0

I am not able to combine the below two sketches. What I require is to either run both the loops together or find a way to run both the functions inside a single loop.

Sketch 1

#include <SevSeg.h>
#include <DS1307RTC.h>
#include <Time.h>
#include <TimeLib.h>
#include <Wire.h>

// Create an instance of the object
SevSeg sevseg;
bool militaryTime = false; // true for 24 hour clock

void setup() {
  byte numDigits = 4;
  byte digitPins[] = {2, 3, 4, 5};
  byte segmentPins[] = {6, 7, 8, 9, 10, 11, 12, 13};
  bool resistorsOnSegments = false; // 'false' means resistors are on digit pins
  byte hardwareConfig = COMMON_ANODE; // See README.md for options
  bool updateWithDelays = false; // Default. Recommended
  bool leadingZeros = true; // Use 'true' if you'd like to keep the leading zeros

  sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros);
  sevseg.setBrightness(90);
}

void loop() {
  tmElements_t tm;
  int time;
  int dot;

  if (RTC.read(tm)) {
    time = tm.Hour * 100;
    if (time > 1200 && militaryTime == false) {
      time = time - 1200;
    }
    if (time == 0 && militaryTime == false) {
      time = 1200;
    }
    time += tm.Minute;
  }

  if ((tm.Second % 2) == 0) {
    dot = 4;
  } else {
    dot = 2;
  }

  //Produce an output on the display
  sevseg.refreshDisplay();
  sevseg.setNumber(time, dot);
}

Sketch 2

// Change this to the output pin you are using
#define TICK_PIN A0

void setup()
{
  pinMode(TICK_PIN,OUTPUT);
  while (1) {
    tone(TICK_PIN,1000,2);
    delay(1000);
  }
}

void loop()
{
}
3
  • The second loop is empty. You are already "running" it ...
    – user31481
    Jul 20, 2017 at 19:43
  • 1
    @LookAlterno Actually, the 2nd loop never executes because of the while in setup.
    – 001
    Jul 20, 2017 at 20:18
  • The second loop can actually be in the loop function as well. Either way, I am unable to combine the two to make it work.
    – Ameer
    Jul 21, 2017 at 14:10

4 Answers 4

1

Basically you need to get rid of the delay and any other blocking loops. Here is a way to do it.

Define this variable globally.

unsigned long lastTime = 0;

Then in your first loop, add the following code either to the beginning or the end:

if (millis() - lastTime >= 1000 || !lastTime) {
    lastTime = millis();
    tone(TICK_PIN,1000,2);
} 
10
  • What is the !lastTime for ?
    – Jot
    Jul 21, 2017 at 2:07
  • @Jot. !lastTime is tested to run the tonein the first execution of loop. After that, is always false. A common trick to resolve the first execution problem.
    – user31481
    Jul 21, 2017 at 11:27
  • This worked very well
    – Ameer
    Jul 21, 2017 at 14:08
  • 1
    @JohnnyMopp Well, this is a common trick to emulate multitasking on arduino. After looking at yours, it doesn't solve the first execution problem which is done above. You can find this answer almost everywhere, it's not a rocket science.
    – Ikbel
    Jul 21, 2017 at 14:37
  • 1
    Let it go. I've moved on......and the right thing to do is remove your unjustified DV on my answer.
    – 001
    Jul 21, 2017 at 14:48
1

I fund the easiest way to work on this challenge when you have to deal with a long delay and think you need a second loop, is to make make a counter in the main loop using centiseconds (10 milliseconds) and then trigger your required response when the counter reaches your time like void loop(void) { counter=counter +1; if (counter==100){ tone(TICK_PIN, 1000, 2); counter =0; } ....rest of code

0

One way is to use a timer callback.

// Include the timer1 library
#include "TimerOne.h"

// Other code here...

void setup()
{
    // Other setup code here....

    // Setup timer
    Timer1.initialize(1000000);          // 1 second
    Timer1.attachInterrupt(callback);    // Set callback
}

void callback()
{
    tone(TICK_PIN, 1000, 2);
}

void loop()
{
    // Code from 1st loop here...
}

If that doesn't work (if something else is using timer1) you could just keep track of the time between beeps:

uint32_t last_beep = 0;
const int beep_timeout = 1000;

void loop() {
    // Code from first loop here

    uint32_t now = millis();
    if (now - last_beep >= beep_timeout) {
        tone(TICK_PIN, 1000, 2);
        last_beep = now;
    }
}
2
  • Would the downvoters care to explain?
    – 001
    Jul 22, 2017 at 12:17
  • 1
    You actually read and understood my question better than the accepted answerer. The reason why I did not accept this was simply due to complexity. I upvoted your answer.
    – Ameer
    Jul 22, 2017 at 19:07
-1

Run two Loops Simultaneously on Arduino

in general, the answer depends on your definition of "simultaneously".

But in this case, the answer is "definitively yes", as the other loop is empty.

a generic approach to this kind of questions is:

void setup(void) {
  setup1();  //run setup 1
  setup2();  //run setup 2
  ...
}

void loop(void) {
  loop1();  //run loop1
  loop2();  //run loop2
  ...
}

this approach would only fail if the original setup() and loop() are written poorly.

1
  • 1
    This might work in some cases, but not even closely for my case.
    – Ameer
    Jul 21, 2017 at 14:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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