Using structs

24 Feb 2010

Hi

Probably a noob question but is it possible to use eg: a DigitalOut in a struct but then declaring the output pin later when initialising the struct?

I came across this code sample http://www.uchobby.com/wp-content/uploads/2007/10/arduino_beer_thermostat.txt for arduino which I thought was quite elegant and wanted to reproduce with mbed.  I am stuck declaring the output pins (the code example just defines them as ints)

Cheers

Evan

24 Feb 2010

You can use something like this:

struct MyDevice
{
  DigitalOut D1, D2;
  // constructor
  MyDevice(PinName pin1, PinName pin2) : D1(pin1), D2(pin2) {};
  void set_bits(int value)
  {
    D1 = value & 1;
    D2 = value & 2;
  }
};

MyDevice dev1(p9, p10), dev2(p11, p12);

int main( void )
{
  dev1.set_bits(0);
  dev2.set_bits(3);
}

 

07 Mar 2012

I am new to mbed & C++. I am interested in knowing can I make array of the structure so that I can define BAG[0], BAG[1], BAG[2] & BAG[3] instead of BAG_0, BAG_1, BAG_2 & BAG_3 in the following code ?

struct BAG_UNIT
{
  AnalogIn   PRESS;
  DigitalIn  INT1,INT2,LRSTS;
  DigitalOut RES;
  // constructor
  BAG_UNIT(PinName pin1, PinName pin2, PinName pin3, PinName pin4, PinName pin5 ) :  PRESS(pin1), INT1(pin2), INT2(pin3), LRSTS(pin4), RES(pin5) {};
};

BAG_UNIT BAG_0(p15,p19,p20,p21,p5);
BAG_UNIT BAG_1(p16,p22,p23,p24,p6);
BAG_UNIT BAG_2(p17,p25,p26,p27,p7);
BAG_UNIT BAG_3(p18,p28,p29,p30,p8);
09 Mar 2012

It looks like that I had not expressed my doubt very well. I am using a set of 3 digital input, 1 digital output & 1 analog input for a device named BAG. I am allocating such set to total 4 devices. I had executed program by defining individual pin for the required function. I was curious to know can I define a structure for the device with device name as array like BAG[0] to BAG[4]. The working code is as given below:

struct BAG_UNIT
{
  AnalogIn   PRESS;
  DigitalIn  INT1,INT2,LRSTS;
  DigitalOut RES;
  // constructor
  BAG_UNIT(PinName pin1, PinName pin2, PinName pin3, PinName pin4, PinName pin5 ) :  PRESS(pin1), INT1(pin2), INT2(pin3), LRSTS(pin4), RES(pin5) {};
};

BAG_UNIT BAG_0(p15,p19,p20,p21,p5);
BAG_UNIT BAG_1(p16,p22,p23,p24,p6);
BAG_UNIT BAG_2(p17,p25,p26,p27,p7);
BAG_UNIT BAG_3(p18,p28,p29,p30,p8);

void update_gauges(int bg_add){
int j; 
int int1,int2,lrsts,reset;
float adc_count;
	
	adc_count= 0;
	int1 = int2 = lrsts=reset = 0;
	if(bg_add == 0)
	{
		for(j=0;j<N;j++){
		adc_count = adc_count  + BAG_0.PRESS;
		}
		adc_count    = (adc_count/N)*4096;
		int1		 = BAG_0.INT1.read();
		int2		 = BAG_0.INT2.read();
		lrsts		 = BAG_0.LRSTS.read();
		reset		 = BAG_0.RES.read(); 
	}
	else
	if(bg_add == 1)
	{
		for(j=0;j<N;j++){
		adc_count = adc_count  + BAG_1.PRESS;
		}
		adc_count    = (adc_count/N)*4096;
		int1		 = BAG_1.INT1.read();
		int2		 = BAG_1.INT2.read();
		lrsts		 = BAG_1.LRSTS.read();
		reset		 = BAG_1.RES.read(); 
	}
	else
	if(bg_add == 2)
	{
		for(j=0;j<N;j++){
		adc_count = adc_count  + BAG_2.PRESS;
		}
		adc_count    = (adc_count/N)*4096;
		int1		 = BAG_2.INT1.read();
		int2		 = BAG_2.INT2.read();
		lrsts		 = BAG_2.LRSTS.read();
		reset		 = BAG_2.RES.read(); 
	}
	else
	if(bg_add == 3)
	{
		for(j=0;j<N;j++){
		adc_count = adc_count  + BAG_3.PRESS;
		}
		adc_count    = (adc_count/N)*4096;
		int1		 = BAG_3.INT1.read();
		int2		 = BAG_3.INT2.read();
		lrsts		 = BAG_3.LRSTS.read();
		reset		 = BAG_3.RES.read(); 	
	}
	pc.printf("@%d%04.0f,%1d,%1d,%1d,%1d#\n",bg_add,adc_count,int1,int2,lrsts,reset);
}

I wish to declare the structure as array but it gives me error. This will ease to set/reset pins & read analog input in a function like given below:

Instead of writing

struct BAG_UNIT
{
  AnalogIn   PRESS;
  DigitalIn  INT1,INT2,LRSTS;
  DigitalOut RES;
  // constructor
  BAG_UNIT(PinName pin1, PinName pin2, PinName pin3, PinName pin4, PinName pin5 ) :  PRESS(pin1), INT1(pin2), INT2(pin3), LRSTS(pin4), RES(pin5) {};
};

//not able to define as array I wish too //
BAG_UNIT BAG[0](p15,p19,p20,p21,p5);  //error:  #94: the size of an array must be greater than zero
BAG_UNIT BAG[1](p16,p22,p23,p24,p6);
BAG_UNIT BAG[2](p17,p25,p26,p27,p7);
BAG_UNIT BAG[3](p18,p28,p29,p30,p8);

void update_gauges(int bg_add){
int j; 
const int N = 100;
int int1,int2,lrsts,reset;
float adc_count;
	
	adc_count= 0;
	for(j=0;j<N;j++){
	adc_count = adc_count  + BAG[bg_add].PRESS;
	}
	adc_count    = (adc_count/N)*4096;
	int1		 = BAG[bg_add].INT1.read();
	int2		 = BAG[bg_add].INT2.read();
	lrsts		 = BAG[bg_add].LRSTS.read();
	reset		 = BAG[bg_add].RES.read(); 
	pc.printf("@%d%04.0f,%1d,%1d,%1d,%1d#\n",bg_add,adc_count,int1,int2,lrsts,reset);
}

Kindly reply if I have not described the problem well.

09 Mar 2012

BAG_UNIT BAG[] = { &BAG_0,&BAG_1,&BAG_2,&BAG_3};
09 Mar 2012

Rene Greiner wrote:

BAG_UNIT BAG[] = { &BAG_0,&BAG_1,&BAG_2,&BAG_3};

Thanks Rene for replying but this gives me following error: error: #415: no suitable constructor exists to convert from "BAG_UNIT *" to "BAG_UNIT"

09 Mar 2012

sorry forgot the pointer

BAG_UNIT* BAG[] = { &BAG_0,&BAG_1,&BAG_2,&BAG_3};
//access with
BAG[bg_add]->INT1.read();
09 Mar 2012

Rene Greiner wrote:

sorry forgot the pointer

BAG_UNIT* BAG[] = { &BAG_0,&BAG_1,&BAG_2,&BAG_3};
//access with
BAG[bg_add]->INT1.read();

Thanks a lot for the help. It worked very smoothly!

It will take me a bit to grasp how it's working but able to use the structure, constructor & pointer all at once with your kind help. The code looks so simple to write for such applications.

I am giving my entire code for this application. If interested let me know if there is still hope in trimming it down for using mbed efficiently especially in regard with serial communication over USB.

#include "mbed.h"

Serial pc(USBTX, USBRX); // tx, rx

struct BAG_UNIT
{
  AnalogIn   PRESS;
  DigitalIn  INT1,INT2,LRSTS;
  DigitalOut RES;
  // constructor
  BAG_UNIT(PinName pin1, PinName pin2, PinName pin3, PinName pin4, PinName pin5 ) :  PRESS(pin1), INT1(pin2), INT2(pin3), LRSTS(pin4), RES(pin5) {};
};

BAG_UNIT BAG_0(p15,p19,p20,p21,p5);
BAG_UNIT BAG_1(p16,p22,p23,p24,p6);
BAG_UNIT BAG_2(p17,p25,p26,p27,p7);
BAG_UNIT BAG_3(p18,p28,p29,p30,p8);

BAG_UNIT* BAG[] = { &BAG_0,&BAG_1,&BAG_2,&BAG_3};

unsigned char rec_str[15];
const int N = 100;  //number of samples per D/A value
int n;
int rec_ptr = 0;
unsigned char send_data,frame_ch,bag_add;

void update_gauges(void){
int j; 
int int1,int2,lrsts,reset;
float adc_count;
	
	adc_count= 0;
	for(j=0;j<N;j++){
	adc_count = adc_count  + BAG[bag_add]-> PRESS;
	}
	adc_count    = (adc_count/N)*4096;
	int1		 = BAG[bag_add]-> INT1.read();//BAG[bg_add].INT1.read();
	int2		 = BAG[bag_add]-> INT2.read();
	lrsts		 = BAG[bag_add]-> LRSTS.read();
	reset		 = BAG[bag_add]-> RES.read(); 
	pc.printf("@%d%04.0f,%1d,%1d,%1d,%1d#\n",bag_add,adc_count,int1,int2,lrsts,reset);
}

void trans_data(void)
{
	if(frame_ch == 'S') update_gauges();
	else
	if(frame_ch == 'N') BAG[bag_add] -> RES = 1;	
	else
	if(frame_ch == 'F') BAG[bag_add] -> RES = 0;
}

void chk_ser(unsigned char rec_chr)
{
	if(rec_chr == '$') 
	{
		rec_ptr = 0; 
		rec_str[rec_ptr++] = rec_chr; 
	}
	else
	if(rec_chr == '!')
	{
		rec_str[rec_ptr++] = rec_chr;
		if((rec_str[0] == '$') && (rec_str[3] == '!'))
		{
			if((rec_str[1] <= '3') && (rec_str[1] >='0'))
			{ 	
				bag_add = (int)rec_str[1]-48;
				frame_ch = rec_str[2];
			} 
			send_data = 1;
		}
	}
	else
	{
		rec_str[rec_ptr++] = rec_chr; 		
	}		  
}

int main() 
{
  while(1)
 {
   if (pc.readable()) chk_ser(pc.getc());		 
   if (send_data) {trans_data();send_data=0;}
  }
}