1

I am a novice in Arduino programming and I'm setting up an Arduino controlled, underwater time-lapse camera to take a picture every 2 hours. It's going in the ocean for a month and I want to be sure that the code will not fail because of the upper limit that normal integers can go. The Arduino simply switches on a relay (connected to the LED_PIN 11) and the camera does the rest, using a script from the awesome Canon Hackers Development Kit C.H.D.K.

I've tried several variations of sketch, some using simple delay, some with millis and some with counters that print what increment the loop it up to.

One of my fast running test sketches, that used a counter, stopped prematurely, I suspect due to hitting the integer limit but I'm not sure if this only occurred due to the fact that it had a counter in the sketch. So I've gone back to the simplest sketch I can find hoping it will not have this issue.

I think I read that once the integer limit is reached, the sketch will simply restart. Or maybe it will become unpredictable. I'd rather the former than the latter.

Any suggestions would be welcome.

I am sure there are many ways to go about this but I'm looking for the simplest and most robust one I can find, so that I can adjust the async timing easily ie. loop starts CameraOn for 10 seconds CameraOff for 2 hours Loop repeats

thanks in advance for your consideration

Here's the sketch I'm testing right now.

#define LED_PIN 11
#define LED_OFF 7200000     // 2 hours in millis
#define LED_ON  8000       // 6 seconds in millis 

unsigned long ms;        //time from millis()
unsigned long msLast;    //last time the LED changed state
boolean ledState;        //current LED state

void setup(void)
{
    pinMode(LED_PIN, OUTPUT);
}

void loop(void)
{
    ms = millis();
    blinkLED();
}

void blinkLED(void)
{
    if (ms - msLast > (ledState ? LED_OFF : LED_ON)) {
        digitalWrite(LED_PIN, ledState = !ledState);
        msLast = ms;
    }
}

==================================================================

Okay, I've come up with a new, much simpler sketch based on delay. Can someone please tell me if this is more robust in terms of continued looping for weeks on end?

#define LED_PIN 11

void setup()
{
   Serial.begin(9600);
   pinMode(LED_PIN, OUTPUT);
   digitalWrite(LED_PIN, HIGH);
}

void loop()
   {
       delay(7200000);                 // 2 hours in millis
       digitalWrite(LED_PIN, LOW);
       delay(8000);                    // 8 seconds in millis 
       digitalWrite(LED_PIN, HIGH);

   }
  • #define LED_ON 10000 // 1 seconds in millis ..... tell me, what does milli mean? .... hint: it is a prefix, like in millimeter and milliliter and milliseconds – jsotola Oct 14 '18 at 3:17
  • 4
    Possible duplicate of How can I handle the millis() rollover? – Juraj Oct 14 '18 at 5:21
  • 1
    26,000mAh USB power bank... Good luck with that... The best 18650 battery packs you can get retail (panasonic) are 13400mAh (4P, 3350/cell). Each one costs £70, so about £18/cell. To get 26,000mAh you would need 8 cells, totalling about £140. And that is with proper batteries. Stuff off eBay / Amazon you'd be lucky to total 2600mAh from all the cells in it. A typical eBay battery has cells of about 1000mAh in them. You'd need 20+ cells in your battery for that to add up... – Majenko Oct 14 '18 at 12:06
  • 1
    Oh, and if the cells are laid side-by-side as most power banks are, it would measure over a foot long. – Majenko Oct 14 '18 at 12:17
  • 1
    There's a reason why "high capacity" USB power banks on eBay are so cheap - they aren't. High capacity, that is. Every single seller out there blatantly lies about the capacity. Usually multiplying it by a factor of 10 or more. I have seen 50,000mAh power banks with an acutal capacity of just 2600mAh. – Majenko Oct 14 '18 at 12:19
1

No, the sketches will not fail or work incorrectly. The Arduino "delay()" function calls the "micros()" function for timing. The "micros()" function uses the Atmel's TIMER0 clock and waits for 1000 microseconds (1 milliseconds) each iteration. The TIMER0 overflows about every 70 minutes, but the program code used in the "delay()" function handles that overflow correctly.

  • 1
    Actually Timer 0 overflows every 1024 µs. – Edgar Bonet Oct 14 '18 at 13:35
  • You are somewhat more correct than I was (I was looking at the 16-bit Timer1) but actually both of us are wrong, since the overflow of the timers are dependent upon the prescaler settings. Nevertheless the timer overflow won't impact the micros() return value and therefore doesn't impact the response to the original question – Zanshin Oct 14 '18 at 13:57
  • 1
    On the Arduino Uno (that's what the OP is using), the initialization code in the Arduino core library sets the prescaler of Timer 0 to 64. If you mess with that prescaler (the OP doesn't), then all the Arduino's timing functions will be off. – Edgar Bonet Oct 14 '18 at 14:11
  • the question was about the millis version of the code, not about later added version with delay() – Juraj Oct 14 '18 at 18:43
  • Thanks for your input.. I feel more confident now to put it in the water. @Juraj Sorry if I appear to be asking more than one question. I did only mean to ask one but now I realize that question was not as precise as it could have been. It should have been phrased "Should I use the 'millis' or 'delay' approach to avoid any issue with the integer limit" Cheers – Hazy Oct 14 '18 at 21:21

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.