Go Down

Topic: Start and stop processes at certain times of day (Read 118 times) previous topic - next topic

HarrisonMG

Dec 17, 2017, 01:38 am Last Edit: Dec 17, 2017, 01:55 am by HarrisonMG
So I am making a project where I have a large wood cutout of the US and every state had an LED. I connected them all to a pin on the Arduino DUE, controlling every one individually, and it works so great! I use the scheduler library, so I can have as many loops running at the same time as I want--right now about 30.
But I want to have it so that at a certain time it will turn off all the lights, and then turn them back on again in the morning.
I have looked into DateTime, Time, AlarmsTime, and all of them don't seem to be able to be compatible with the scheduler function, as that runs in the setup and each loop only contains information for the LED except the last loop which has just yield();
Link to scheduler: https://www.arduino.cc/en/Tutorial/MultipleBlinks

Any other ideas? Thanks!

wzaggle

Due has a Real Time Clock built in but not a separate battery.  Have you tried using this clock?  I would put all this master timing stuff into the 1st loop function and start 50 new loops for controlling the LED's with whatever logic they have to turn them on/off.  Then that 1st loop could do all the work of timing and setting a global master variable that all the other loops look at to manage an All Off condition.   

But out of curiosity, do you really need 50 separate loops?  Maybe you could post your code so everyone can see what you are actually trying to do and probably offer you some simpler ways (or maybe not) to light up 50 separate LED's on demand.   The scheduler example you cited used them to set blink rates different for each one, etc.  Are you doing something like this?  What logic is or is supposed to be controlling their ON/OFF state?









HarrisonMG

So I do know that there's a clock in the DUE, I just don't know how to use it with my code. I did try to put the scheduling function into the first loop but that did not work, it seems it must be in the setup unless there is another way. Here is the code--it's pretty long, so I had to attach the file. But most states are in one loop, so there are not fifty, only about 8. The loop number stands for the number of times an LED will flash.

wvmarle

Well, I'm sure it's pretty easy to accomplish.

First of all, ditch that Scheduler. You don't need it.

Then rename all those functions to something more sensible, and get back your loop().

Next, fix your code. I don't see any yield() in those functions, so it seems it just runs one loop, when it finished the second, etc. Not much scheduling going on, really, as I see it. Also you repeat the same action over and over again, instead of using a for() loop for this.

So, take for example, this function loop4:

Code: [Select]

void loop4() {
 digitalWrite(Pennsylvania, HIGH);
 delay(500);
 digitalWrite(Pennsylvania, LOW);
 delay(500);
 digitalWrite(Pennsylvania, HIGH);
 delay(500);
 digitalWrite(Pennsylvania, LOW);
 delay(500);  digitalWrite(Pennsylvania, HIGH);
 delay(500);
 digitalWrite(Pennsylvania, LOW);
 delay(500);  digitalWrite(Pennsylvania, HIGH);
 delay(500);
 digitalWrite(Pennsylvania, LOW);
 delay(500);
 delay(5500);  
}


You could make this a lot shorter and more readable:

Code: [Select]

void Pennsylvania() {
  for (byte i = 0; i < 4; i++) {
    digitalWrite(Pennsylvania, HIGH);
    delay(500);
    digitalWrite(Pennsylvania, LOW);
    delay(500);
  }
 delay(5500); 
}


Do that for all your functions, and then you get a loop like this:

Code: [Select]

void loop() {
  Pennsylvania();
  // the other states
}


Now I'm not too sure about this scheduler - I don't see any yield() so it seems one function has to finish before another can be started. You can have them run concurrently just as well, but then you have to switch to millis() timing, so each function returns very fast. Your Pennsylvania function then becomes this (mind the global variable declarations):

Code: [Select]

uint32_t PennsylvaniaTime;
bool PennsylvaniaState = true;
byte PennsylvaniaIteration = 0;

void Pennsylvania() {
  if (PennsylvaniaIteration < 8) {  // 4 on and 4 off states.
    if (millis() - PennsylvaniaTime > 500) {
      digitalWrite(Pennsylvania, PennsylvaniaState);
      PennsylvaniaState = !PennsylvaniaState;
      PennsylvaniaTime += 500;
    }
  }
  else if (millis() - PennsylvaniaTime > 5500) {
    PennsylvaniaTime += 5500;
    PennsylvaniaIterations = 0;
    PennsylvaniaState = HIGH;
  }
}


Do the same for all your states, and call all functions from loop(), and all runs nicely concurrently.

Then to switch the whole shebang on and off just add a check for the time, and if outside opening hours just don't call those functions. Do add a separate function to switch off all the LEDs.
Quality of answers is related to the quality of questions. Good questions will get good answers. Useless answers are a sign of a poor question.

HarrisonMG

I am not sure weather it didn't make it into the file I uploaded or not, but at the very end there is supposed to be a loopSerial() that has only yield(); in it. The way my project works is that yes, all of the LEDs are flashing at the same time but many at different rates. So I will definitely take your suggestion to make all of the loops shorter with the byte method, but the scheduler is necessary for a simple way to have multiple functions run at the same time. I had used Millis() at first but it was so complicated.
So I am left to ask, is there maybe something in the Setup function that checks the time, and either let's the Arduino continue with anything or not? Of course I realize this would also mean I need something that can call up the setup function every few minutes. Suggestions? Thanks so.much!

wvmarle

Yes I saw that - as said I don't know the Scheduler library.

You don't need it. Just rewrite all functions using the millis() method just like the one example that I gave you, and call them all from loop(). That's all there is to it.
Quality of answers is related to the quality of questions. Good questions will get good answers. Useless answers are a sign of a poor question.

Go Up