-2

Let's say I have 2 loops LED() and IR() with a print statement in my Arduino loop() function. Basically I want my IR() loop to be always running so that at any point in time I provide a signal to the receiver, it will print something. I currently can only run LED() first and then once LED() is finished, only then the IR() will run. So if I send a signal let's say while LED() is running, nothing is showing up. Thanks!

EDIT: Updated with code

void loop() {
  single_Check(); // delay of 500ms
  if (irrecv.decode(&results)) {   //IR code
     Serial.println(results.value, HEX);
     irrecv.resume();
  }
}

The single_check() function basically turns on 6 LED one by one and check the voltage of the LED and prints them out. However, this code takes time to finish because I put in delay(500). So only after 500ms, the IR code will run.

  • 1
    Run the functions one after the other. If they are fast enough, you should be fine. If they are not, you are probably doing something wrong, (using delay() maybe? Seen Blink Without Delay?). – Edgar Bonet Jan 25 '17 at 15:23
  • Maybe you should look into interrupt timer and set to timers for LED and IR instructables.com/id/Arduino-Timer-Interrupts – Jonathan Anctil Jan 25 '17 at 15:26
  • You could use a scheduler and run the 2 loops; github.com/mikaelpatel/Arduino-Scheduler – Mikael Patel Jan 26 '17 at 10:25
  • The updated question essentially contains the answer to your problem: you are using delay(). Solution: read the Blink Without Delay tutorial (did you notice I linked to it in my first comment?), then rewrite single_Check() without delay(). – Edgar Bonet Jan 26 '17 at 15:26
  • > Run 2 loops side by side easy: have two arduino, each loaded with one of the loops. put the two arduino side by side and turn on the power. done. – dannyf Aug 26 '17 at 10:53
0

Your outer loop needs to only decide whether the IR or the LED needs service. If/when one of them does, call a function that services that device. The service functions should be brief and without delay() calls.

If a service function needs to do something/delay/do something else, it should do it by parts; only do the first something and let the main loop decide when it is time to do the something-else.

If this is all you are doing - two devices and their service routines, you may not need anything more. If you need to extending this to n-devices with n or more service routines, and the servicing is time-based (such as the LED probably is), look the SimpleTimer library. Then your outer loop would only call the timers' .run() function frequently, and the timers routine would take care of calling each service routine when necessary.

You'll probably end up with something like:

SimpleTimer Timers;  // set of timers

void setup(){
   // some set-up stuff here
   Timers.setInterval(long 10L, LedService);  // call LedService 100x/sec
}

void loop(){
   Timers.run();
   if( IRTest() )
      IRService();
}

void LedService(void){
   // manage LED here
}

bool IRTest(void){
   // return true if IR needs service
   // or false otherwise
}

void IRService(void){
   // manage IR sensor here
}
0

Arduino and like Arduino hardware run only a sequential Flow, Because they usually have only one core. For running 2 loops side-by-side you have some solutions.

  • A flow to test flags and execute specific code.
  • Use a timer
  • Use a RealTime OS, like FreeRTOS

try never use delay

0

On Arduino (and on most other micro controllers for what it matters) you CANNOT do two things at the exact same time, so forget about running two loops in principle.

What you can do is: run two separate piece of code one after the other, fast enough that they look to be running in parallel or run one continuously and run the other when an event occurs.

In your case the first option is not applicable, so you have to revert to the second option and you are lucky because the event we are talking about is actually handled by the Arduino MCU pretty well: it is called an interrupt.

Arduino Uno (actually the MCU at its core, the ATMega328) is capable of handling interrupts on pins 2 and 3 (so you can have 2 interrupt routines attached at the same time).

Using interrupts you can have a piece of code (the IR related part) being enabled only when pin 2 goes LOW (or HIGH). BEWARE though and use interrupts in the proper way: millis() does NOT work within an interrupt routine and also nothing else will be enabled while executing the interrupt routing, including counting time (that's the reason millis() does not work).

The latter part practically means you should limit your interrupt routine to capture the IR code and return, having the printing being done within the loop() function whenever the IR has been decoded.

Hoping all that makes sense to you, here are some references:

interrupts() Interrupts attachInterrupt()

  • millis() does work inside an ISR, you should just not expect it to increment. Which doesn't matter, because you would never write an ISR that takes a full millisecond to run anyway. – Edgar Bonet Jan 26 '17 at 10:27
  • @EdgarBonet well, if millis() keeps returning the same value I wouldn't say it does work, at least functionally speaking, but you are right nonetheless: it technically works but it doesn't report any change. About ISRs, I have seen code using delay() within ISRs, so don't put any limit on the misuse of interrupt routines :-D – Roberto Lo Giacco Jan 26 '17 at 16:47

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.