Issues with longer numbers in a timer

Hey All! I have been trying to design a short range timer, and this worked great until the numbers got too big. I tried to change to a LONG from an INT, but it still has problems. I’m still new at the arduino, can somebody explain to me where I went wrong?

Thanks,

Bob

// Short Range Timer -
//
// Five timers running independently.
//
// Five timer channels are used. The channels are 
// numbered 0, 1, 2, 3, and 4. 
//
// This code is designed to be used with a 5 position switch to have
// five user selectable short range timer options.
//
// Timer commands usually take a channel number and/or a 
// time-value. 
//
// The unit of time is is called a blink. The duration 
// of a blink is related to an AVR jiffy. See
// http://en.wikipedia.org/wiki/Jiffy_%28time%29
// 
// Calculations are based off of 625 counts per second, for example 
// 625 counts/second x 30 seconds = 18750 counts/30 seconds
//
// This example uses direct control of the pins from the timer channels.
// This method uses less processor power than callbacks or flag polling.
// (see the other examples)



#include <TimerScheduler.h>

// hardware pins
int LED0 = 13; // assign LED0 to digtal pin 13
int LED1 = 12; // assign LED1 to digtal pin 12
int LED2 = 11; // assign LED2 to digtal pin 11
int LED3 = 10; // assign LED3 to digtal pin 10
int LED4 = 9; // assign LED4 to digtal pin 9

long outval0 = 0; // set inital value to all channels to 0
long outval1 = 0;
long outval2 = 0;
long outval3 = 0;
long outval4 = 0;


void setup()
{   
  pinMode(LED0, OUTPUT); // defines each digital pin used as an output
  pinMode(LED1, OUTPUT); 
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  pinMode(LED4, OUTPUT);

  Timer.begin();        // start the hardware timer
  
  // attach LED pins to timer channels
  Timer.attachPin(0, LED0); // (channel, value)
  Timer.attachPin(1, LED1);
  Timer.attachPin(2, LED2); 
  Timer.attachPin(3, LED3);
  Timer.attachPin(4, LED4);

  // using pin-direct mode, you need to set the pump on
  // and pump off times seperately
  Timer.setHighTime(0, 9375); // (channel, time in seconds x 625)
  Timer.setLowTime(0, 37500); // On for 15 seconds, off for 1 minute
  
  Timer.setHighTime(1, 18750);// On for 30 seconds, off for 2 minutes
  Timer.setLowTime(1, 75000);
  
  Timer.setHighTime(2, 18750);// On for 30 seconds, off for 4 minutes
  Timer.setLowTime(2, 150000);
  
  Timer.setHighTime(3, 37500);// On for 1 minute, off for 5 minutes
  Timer.setLowTime(3, 187500);
  
  Timer.setHighTime(4, 37500);// On for 1 minute, off for 8 minutes
  Timer.setLowTime(4, 300000);
  
  
  Timer.start(0);       // (channel)
  Timer.start(1); 
  Timer.start(2); 
  Timer.start(3);
  Timer.start(4);
}


// You can put things in loop(), if you like,
// but it's not required.

void loop()
{
}

I tried to change to a LONG from an INT

You tried to change what from an int to a long?

The code you post uses literals for nearly everything, not typed variables.

I changed my outval from int to long thinking that it might be where the overflow was occuring.

ex:

(was) int outval1 = 0;

(is) long outval1 = 0;

You don't use those variables anywhere, so it doesn't really matter what data type they are.

These lines, however:

  Timer.setHighTime(1, 18750);// On for 30 seconds, off for 2 minutes
  Timer.setLowTime(1, 75000);

could be a problem depending on the parameter types declared by those timer methods. If they are declared as ints or unsigned ints, then you can only provide values that are within those types ranges.

Ok, i'm following you. My guess is that I need to dive into the library for the timer and investigate what they are using to declare the variables and make changes accordingly?

Bob

My guess is that I need to dive into the library for the timer and investigate what they are using to declare the variables and make changes accordingly?

Exactly. Most likely, the values are long or unsigned long, so your inputs need to be the correct type. You can use literals, like you are doing, if you append L or UL to the value.

  Timer.setHighTime(1, 18750UL);// On for 30 seconds, off for 2 minutes
  Timer.setLowTime(1, 75000UL);

Of course, the numbers don't match the comments...

Ok, I tried using the UL on the end of these, and that didn't work. I tried changing the library from:

void setHighTime(uint8_t, uint16_t);    // channel, value
    void setLowTime(uint8_t, uint16_t);     // channel, value

to this

void setHighTime(uint8_t, uint32_t);    // channel, value
    void setLowTime(uint8_t, uint32_t);     // channel, value

I thought mabey defining them as a 32bit number might get me out of the stink on this, but it's causing the timer to fail now, and I'm not really sure why.

Bob

I thought mabey defining them as a 32bit number might get me out of the stink on this, but it's causing the timer to fail now, and I'm not really sure why.

Did you propagate the changes throughout the class, or make them only in that function?

Is the input to that function in milliseconds or seconds?

Paul, to be completely honest, I'm not sure. :blush:

I'm feeling a bit overwhelmed on this, but I'm trying to struggle through. Man I wish I would have payed better attention in the C++ class I took years ago!

Bob

Interesting comment in one of the examples:

// The unit of time is is called a blink. The duration 
// of a blink is related to an AVR jiffy. See
// http://en.wikipedia.org/wiki/Jiffy_%28time%29

There is also this:

// Timer intervals can be up to 65535.

You can always make the timers fire at times like every 1000 milliseconds/blinks/jiffys, and the count how many times the timer has fired, and only execute the action if the timer has fired enough times.

You might want to use unsigned integers whether 8, 16, 32 or 64 bit (unsigned long long is 64 bit) because with unsigned math you can get the difference even across a roll-over. Roll-over is when for example an 8-bit unsigned goes from 255 to 255+1=0.

It’s easier when you have some code to play with.
Here’s an example, change a and b to mess with it.

0x is hexadecimal, 0b is binary
When you see what is happening with the bits you get a mechanical view of what is happening.

unsigned long a, b, c;

void setup() {
  Serial.begin( 9600 );
  a = 0xffffff00UL;
  b = 0x10UL;
  Serial.println( "\n unsigned math\n" );
  Serial.print( "a = ");
  Serial.print( a, DEC );
  Serial.print( " = 0x");
  Serial.print( a, HEX );
  Serial.print( " = 0b");
  Serial.println( a, BIN );
  Serial.print( "b = ");
  Serial.print( b, DEC );
  Serial.print( " = 0x");
  Serial.print( b, HEX );
  Serial.print( " = 0b");
  Serial.println( b, BIN );
  if ( b >= a ) Serial.println( "b >= a" );
  else          Serial.println( "a > b" );
  c = a - b;
  Serial.print( "a - b = ");
  Serial.print( c, DEC );
  Serial.print( " = 0x");
  Serial.print( c, HEX );
  Serial.print( " = 0b");
  Serial.println( c, BIN );
  c = b - a;
  Serial.print( "b - a = ");
  Serial.print( c, DEC );
  Serial.print( " = 0x");
  Serial.print( c, HEX );
  Serial.print( " = 0b");
  Serial.println( c, BIN );
  c = b - (b + 1);
  Serial.print( "b - (b + 1) = ");
  Serial.print( c, DEC );
  Serial.print( " = 0x");
  Serial.print( c, HEX );
  Serial.print( " = 0b");
  Serial.println( c, BIN );
}

void loop() {};