0

I am working with my son (9) and we are having a great time learning. But, we've run into a problem and could use your help.

We have two separate loops that we want to run without interfering with the other. Currently we have two LEDs that are blinking in a sequence that has delays built in to keep them on/off.

We also have a Photocell circuit that turns another LED on/off depending on the light.

The problem is, the photocell circuit is lagging 1/2 second due to the light sequence from the other loop.

How do we fix this?

// this is declans photo cell and led program

const int photoCell    =  0;  // photo cell variable
const int ledLightButt = 11;  // Led light variable assignment

int lightCal;                 // idk what dis iz
int lightVal;                 // this is the reading from photo cell I think


void setup() {
    pinMode(13, OUTPUT);
    pinMode(12, OUTPUT);

    pinMode(ledLightButt, OUTPUT);
    lightCal = analogRead(photoCell);
}

void loop() {

    lightVal = analogRead(photoCell);

    if (lightVal < lightCal - 50) {
        digitalWrite(ledLightButt, HIGH);
    }
    else {
        digitalWrite(ledLightButt, LOW);
    }

    digitalWrite(13, HIGH);
    digitalWrite(12, LOW);
    delay(250);

    digitalWrite(13, LOW);
    digitalWrite(12, HIGH);
    delay(250);

}
2
  • this may help ... norwegiancreations.com/2017/09/… – jsotola Jan 1 '20 at 3:12
  • 1
    tip: format your code properly so that the blocks of code are clearly defined .... i formatted your existing code as an example .... proper formatting is important in if-else bloks and in function blocks – jsotola Jan 1 '20 at 3:18
2

The root of this behavior is that when the program runs delay() function - nothing else could run (digitalwrites, checks, conditions, etc.) until the delay() time is passed.

The effective solution for this is avioding the delay() function, and getting the same results (without the side-effect) using timers (like millis()) or other ways.

Googling "How to avoid delay()" will give you lot of information about how-to do it, one example can be found here: Arduino Playground - How and Why to avoid delay() function.

Good luck with that, and enjoy your programming experience!

1

we found some other code that helped us avoid the delay() functions. Now we are able to use the timestamp "Millis" to run our blinking lights AND have another if statement running the photocell & third LED.

Making progress! Thanks for the suggestions! Here is the code and it works great to turn the LED on and off based on the photocell, and have the other LED's flashing on their own.

const int photoCell =0;
const int ledPin = 13;
const int led2Pin = 12;
const int led3Pin = 11;
int lightCal;
int lightVal;
int ledState = LOW;
int led2State = HIGH;
long previousMillis = 0;
long interval = 250;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(led2Pin, OUTPUT);
  pinMode(led3Pin, OUTPUT);
  lightCal=analogRead(photoCell);
}

void loop() {
unsigned long currentMillis = millis();
lightVal = analogRead(photoCell);

if(currentMillis - previousMillis >= interval) 
{
  previousMillis = currentMillis;
  if (ledState == LOW)
  ledState = HIGH;
  else
  ledState = LOW;
  if (ledState == LOW)
  led2State = HIGH;
  else
  led2State = LOW;

  digitalWrite(ledPin, ledState);
  digitalWrite(led2Pin, led2State);
}
if (lightVal < lightCal - 50)
{
  digitalWrite(led3Pin, HIGH);
}
else {
  digitalWrite(led3Pin, LOW);
}
}
0

I think that timing might be too hard for 9year old, So :
I will give an alternative: Synchronizing two Arduino's using main or software serial. this can be used to teach Server client (master/slave) architecture where client is set to finish loop quicker and wait for syncing data from server (master) to start next one.

Note that if you are sending numbers over serial to another Arduino use Serial.write() (rather then Serial.print(); it saves you from dealing with asci and char to int (no fun for kid only trouble)

There is a third option of a library which tries to imitate parallel syncing, but that is too much trouble and not a good habit to gain

0

You can use the library that support blink without delay. For example, You can refer to this example code:

#include <ezOutput.h> // ezOutput library

ezOutput led1(7);  // create ezOutput object that attach to pin 7;
ezOutput led2(8);  // create ezOutput object that attach to pin 8;
ezOutput led3(9);  // create ezOutput object that attach to pin 9;

void setup() {
  led1.blink(500, 250);       // 500 milliseconds ON, 250 milliseconds OFF. start immediately
  led2.blink(250, 250, 1000); // 250 milliseconds ON, 250 milliseconds OFF. start after 1000 milliseconds
  led2.blink(100, 100, 2000); // 100 milliseconds ON, 100 milliseconds OFF. start after 2000 milliseconds
}

void loop() {
  led1.loop(); // MUST call the led1.loop() function in loop()
  led2.loop(); // MUST call the led2.loop() function in loop()
  led3.loop(); // MUST call the led3.loop() function in loop()

  // DO OTHER WORK HERE

}

The tutorial is available here

0

There's a rather nice Adafruit tutorial on how to implement this (beyond the one listed already): https://learn.adafruit.com/multi-tasking-the-arduino-part-1

I disagree with the approach given, since it requires that all tasks be polled manually and that you implement it to each task, but the design itself is really clever.

You may also want to check out Makuna's Task library (https://github.com/Makuna/Task), or try my own solution: https://github.com/rdragonrydr/CoRTOS (which is designed to be as efficient and easy-to-use as possible). It's still a work in progress (more optimizations coming soon) but is definitely usable for nearly anything I can think of.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.