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);

   }
Hazy
  • 11
  • 3
  • `#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 03:17
  • why are you initializing Serial? – jsotola Oct 14 '18 at 03:18
  • the first seven words of my post introduce me as a novice..I'm hacking and snipping from all over the place and gradually filling in the blanks in my knowledge... Yes, I should probably spend a few days doing tutorials to get the basics but, I think you'd agree this is a simple task, so I have rolled up my shirtsleeves and dived in. – Hazy Oct 14 '18 at 05:12
  • 4
    Possible duplicate of [How can I handle the millis() rollover?](https://arduino.stackexchange.com/questions/12587/how-can-i-handle-the-millis-rollover) – Juraj Oct 14 '18 at 05:21
  • @Juraj, this is about letting the Arduino run for a long time. No duplicate I think. Hazy, both sketches should work as far as I can tell. When using large numbers I prefer to use "52000UL". The "UL" means it is an unsigned long number. Please update both your sketches and write also how long it is in comments at every large number. For example "52000" is 52 seconds. How is it powered? With a battery? Will that last long enough? The arduino boards are for fast prototyping, it is not protected against a harsh environment. – Jot Oct 14 '18 at 06:33
  • Thanks @Jot, I've updated the sketches to the desired inteval (not very desirable for testing mind). This unit will sit inside an underwater housing, fixed to a seaweed farm tray, roughly 1.5 meters below the surface of the Pacific Ocean, 5km off the north shore of Bali. Ive – Hazy Oct 14 '18 at 07:18
  • Cont... I've just purchased a 26,000mAh USB power bank which will power it. A recent 24 hour run test, measure on a USB Wattmeter showed 0.74W/h , so 26Ah / 0.74W/h = 35.135 days. It's anybody's guess at what point it will not have enough voltage to drive the camera but, fortunately, we're aiming for as-long-as-it'll-run, rather than trying to hit a definite number of days. – Hazy Oct 14 '18 at 07:27
  • @Jot, this is about "Will this sketch eventually fail because of integer limit issue?". the answer is no, because it correctlly handles the millis rollover – Juraj Oct 14 '18 at 09:10
  • @Hazy, you should not ask more questions at once, here at SE https://arduino.stackexchange.com/tour – Juraj Oct 14 '18 at 09:15
  • If you want any form of accuracy to your timing you should consider an RTC. The internal millis() is not particularly accurate over long periods. – Majenko Oct 14 '18 at 10:01
  • 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
  • @Majenko I hear you about the manufacturer's claims vs reality but this is the only form factor battery that will fit in my housing. I bought from Amazon and here's a fairly comprehensive YouTube review, including charge and discharge measurements https://www.youtube.com/watch?v=AqIwb4395SY – Hazy Oct 14 '18 at 21:31

1 Answers1

2

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.

Zanshin
  • 61
  • 5
  • 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
  • @Hazy, did you ever think about delay() overflowing? because this answer is about that. about delay() implementation over micros() – Juraj Oct 15 '18 at 05:02
  • @Juraj I didn't but the helpful answers from Edgar Bonet and Zanshin informed me of the fact that delay 'overflows' but, apparently it shouldn't impact my project because I haven't fiddled with the prescaler - whatever that is. – Hazy Oct 15 '18 at 05:57