Use of array of structure

Hello

I need an array of structure, It seems that the declaration of the structure in any way interfere with the program i.e. the Serial.println aborts.

Here the struct (wich I had to put in a separate file):

typedef void (* fnzPointer) ();
struct cronStructure{
    long every;     // every
    long next;  // next event
    long from;  // from
        int status;    // 1 active, 0 inactive        
    fnzPointer fnzActions;
//  char* name;
};

and here the statement declaration:

cronStructure cron[10];

Finally in the Setup() instructions in which freezes:

Serial.println(readEprom(20,27));
flash(led,500,1000,5);
therm_value = readPin(therm,therm_low,therm_high);
Serial.println(String("El Condor pasa &date Temperature: " + floatToString(therm_value)));

with the serial output:

CONDOR INFORMATIQUE - Turin
El Condor pasa

(I have also tried with typedef, but the results are similar)

Best regards

John Rossati

In order to get a sensible answer to questions about your code, you really need to post a complete sketch that demonstrates the problem you are asking for help with. If your sketch contains a lot of code which you don't believe is relevant to the problem then create a minimal test sketch which demonstrates in the simplest possible way. Just the act of creating this sketch may enable you to solve the problem for yourself.

Read this before posting a programming question

As PeterH says, post a sketch that demonstrates your problem, in code tags.

Hey guys cut him some slack, didn't you notice he's a newbie.

anyways rossati Looking at what you have here I'm not sure that your problum is with your structure, just what makes you think it is? you're full code would be helpful and [u]if it's in multiple files[/u] just post them as best you can or e-mail them to me (subject: Help with AR)

thanks.

Thanks to all

I am a newbie (on Arduino).
What I am trying is to (de)generate a source from a functional like commands using a PHP interpreter.
Until I used two arrays to manage interupt the program worked; the problems arose when I tried to use a structure to handle events (it seems me more elegant).

This is the script:

#include <EEPROM.h>
#include "C:\Users\Condor\Documents\Arduino\GenIno\defs.h"
/*
Generated by GenArduino version 0.1.5 12 July 2013 Sun 28 July 2013 08:07:26
El Condor. Condor informatique - Turin
*/
#define therm 0
#define therm_low 0
#define therm_high 150
float therm_value = 0;
#define therm2 1
#define therm2_low 0
#define therm2_high 150
float therm2_value = 0;

#define led 13
volatile unsigned long cClock = 0;
int timer1_counter;
char* action_t1 = "t1";
char* action_t2 = "t2";
char* action_pump = "pump";
char* action_closepump = "closepump";
int actionsNumber = 10;
cronStructure cron[10];
fnzPointer fnzActions[] = {handle_t1,handle_t2,handle_pump,handle_closepump};
void setup() {
Serial.begin(9600);
while (!Serial) {; // wait for serial port to connect. Needed for Leonardo only
}
	
	delay(5000);
	Serial.println(readEprom(20,27));
	flash(led,500,1000,5);
	therm_value = readPin(therm,therm_low,therm_high);
	Serial.println(String("El Condor pasa &date Temperature: " + floatToString(therm_value)));
	setTimer();
	cron[0] = (cronStructure) {6000,6000,0,1,(fnzPointer) handle_t1};
	cron[1] = (cronStructure) {2500,2500,0,1,(fnzPointer) handle_t2};
	cron[2] = (cronStructure) {0,28800000,28800000,1,(fnzPointer) handle_pump};
	cron[3] = (cronStructure) {0,43200000,43200000,1,(fnzPointer) handle_pump};
	cron[4] = (cronStructure) {0,57600000,57600000,1,(fnzPointer) handle_pump};
	cron[5] = (cronStructure) {0,68400000,68400000,1,(fnzPointer) handle_pump};
	cron[6] = (cronStructure) {0,29400000,29400000,1,(fnzPointer) handle_closepump};
	cron[7] = (cronStructure) {0,43500000,43500000,1,(fnzPointer) handle_closepump};
	cron[8] = (cronStructure) {0,57900000,57900000,1,(fnzPointer) handle_closepump};
	cron[9] = (cronStructure) {0,69000000,69000000,1,(fnzPointer) handle_closepump};
}
void loop() {
	//setup write eprom "CONDOR INFORMATIQUE - Turin" at 20
	//stop
}
void handle_t1() {
		
		therm_value = readPin(therm,therm_low,therm_high);
		Serial.println(String("t1: " + String(millis()) + " " + floatToString(therm_value)));
		digitalWrite(led,LOW);
		if(therm_value > 20) {
	String event = "High temperature";
		Serial.println(String(String(event) + ": " + floatToString(therm_value) + " open pump"));
		}
	}
void handle_t2() {
		
		therm2_value = readPin(therm2,therm2_low,therm2_high);
		Serial.println(String("t2: " + String(millis()) + " " + floatToString(therm2_value)));
		digitalWrite(led,HIGH);
	}
void handle_pump() {
		
		Serial.println(String("Open pump at: " + String(millis())));
	}
void handle_closepump() {
		
		Serial.println(String("Close pump at: " + String(millis())));
	}
//  readEprom
String readEprom(int at,int length) {   
    String str = "";
    for (int i=0; i < length; i++){
        if (at+i < 512) str = String(str + char(EEPROM.read(at+i)));
    }
    return str;
}
//  flash
void flash(int pin,int h,int l, int forLoop) {
	for (int i=0;i<forLoop,i++;) {
		if (h>0) {
			digitalWrite(pin, HIGH);
			delay(h);		
		}
		if (h>0) {
			digitalWrite(pin, LOW);
			delay(l);
		}		
	}
}
//  readPin
float readPin(int sensor,float l,float h) {
    analogReference(INTERNAL);
    float C = analogRead(sensor);
    analogReference(DEFAULT);
    return (l+C*(h-l)/1024);
}
//  floatToString
String floatToString(float f) {
	char buffer[20];
	dtostrf(f, 16, 2, buffer);
    String s = buffer;
	s.trim();
	return s;
}
// 
// interruptFunctions
void setTimer() {	 		// initialize timer1 
  noInterrupts();           // disable all interrupts
  TCCR1A = 0;
  TCCR1B = 0;
  // Set timer1_counter to the correct value for our interrupt interval
  timer1_counter = 34286;   // preload timer 65536-16MHz/(256*2Hz)
  TCNT1 = timer1_counter;   // preload timer
  //TCCR1B |= (1 << CS10);
  TCCR1B |= (1 << CS12);    // 256 prescaler 
  TIMSK1 |= (1 << TOIE1);   // enable timer overflow interrupt
  interrupts();             // enable all interrupts} 
}
ISR(TIMER1_OVF_vect) {     // interrupt service routine 
  TCNT1 = timer1_counter;   // preload timer
  cClock += 500;    //
  Serial.println(String(cClock)+ " " + cron[3].every);
  if (cClock >= cron[minArray(cron,actionsNumber)].next) {
    unsigned long time = millis();
    long minValue = cron[minArray(cron,actionsNumber)].next;
    for (int i=0;i < actionsNumber;i++) {
      if(minValue == cron[i].next) cron[i].fnzActions();
      cron[i].next = cron[i].next - minValue;
      if (cron[i].next == 0) cron[i].next = cron[i].every;    // set new timeout
    }
    cClock = time-millis();
  }
}
int minArray(cronStructure a[],int n) {
  long min = a[0].next;
  int posiz = 0;
  for (int i=0;i<n;i++) {
    if (min > a[i].next) {
      min = a[i].next;
      posiz = i;
    }
  }
  return posiz;
}

this is the structure:

typedef void (* fnzPointer) ();
struct cronStructure{
	long every;     // every
	long next;	// next event
	long from;	// from
        int status;    // 1 active, 0 inactive        
	fnzPointer fnzActions;
//	char* name;
};

For completeness, here the source of the macrocommands:

device therm pin 0 range 0 to 150
device therm2 pin 1 range 0 to 150
start
end start
setup
    delay(5000);
    print eprom at 20 for 27
    flash led high 1000 low 500 for 5
    read therm 5 times
    print "El Condor pasa &date Temperature: " therm_value  
end setup
action t1 every 6
   read therm
   print "t1: " millis() " " therm_value
   off led
   event "High temperature" therm_value > 20
       print event ": " therm_value " open pump"
   end event
end action
action t2 every 2.5
   read therm2
   print "t2: " millis() " " therm2_value
   on led
end action
action pump at 8:00 12:00 16:00 19:00
    print "Open pump at: " millis()
end action
action closepump at 8:10 12:05 16:05 19:10
    print "Close pump at: " millis()
end action
//setup write eprom "CONDOR INFORMATIQUE - Turin" at 20
//stop

Thanks in advance for any criticism and observation, both the code and the project in general.

John Rossati

ISR(TIMER1_OVF_vect) {     // interrupt service routine 
  TCNT1 = timer1_counter;   // preload timer
  cClock += 500;    //
  Serial.println(String(cClock)+ " " + cron[3].every);

Don't do serial prints inside an ISR.

http://www.gammon.com.au/interrupts

Thanks

I try to put Serial prints in loop function, but i think the problem is not generated by Serial (it works in my precedent try).

John Rossati

Well, putting serial prints inside an ISR is likely to hang your code, which is what you reported happening.

Please post amended code where you have fixed that up.

thanks

I disabled timer and add some println on loop; it woks. This means that serial works concurrently i.e. is not syncronous, and the fact that it worked before was only luck.

This my be also for other communications e.g. wifi?

best regards.

John Rossati

Serial output is asynchronous up to the size of the output buffer which I think is 64 bytes on this platform, so if it seems to hang after printing roughly that amount it means the buffer is full and it is no longer servicing interrupts (eg, inside an ISR).