Hello My Arduino People,
I believe I'm having issues on one of my codes with data types.
I'm hoping some of you good people can help me figure it out.
On the surface it seems to be a roll over issue, but I'm unsure why or how to fix it.
This project requires a timer where something is turned on for X amount of time and turned off for Y amount of time.
Where X and Y are controlled by potentiometers.
The On and Off intervals are dictated by a delta defined using millis().
My issue seems to lie in millis() as it's a very large number and I need to convert it into increments of Half minutes. (0.5 min intervals)
I'm dealing with intervals of up to 45min ON and 45 min OFF, so a half min is much more intuitive than 2,700 seconds.
I've tried to run the conversion with both a Float and a Double as the variable housing the result but both return negative answers regardless of all inputs being positive values.
Find my code attached to sample the results yourself.
Maybe I'm missing something bigger here. Not sure.
EDIT: Sorry for the sloppy post. It's been a while since I pasted code here. I'll be sure to re-up my reading on the posting guidlines. Scroll down to see pasted code for easy viewing. Thanks
Post your code as described in the forum guidelines. Few here will download your files.
Millis are unsigned longs. Not Float or Double (which are the same in the Arduino).
When checking for elapsed time always use the construct:
"millis() - lastTimeChecked >= elapsedTargetTime"
This will make sure that the point at which millis() has rolled over and lastTimeChecked was before the rollover is worked out properly in the arithmetic.
const int pot_1 = A2;
const int pot_2 = A3;
const float ctMultiplier = 30000; // 30000milliseconds == 30 seconds
const int mappedUpperLimit = 91; // 30sec*90 == 45min ; 91 is used to ensure 45min is reached as pot may fall short of full scale value of 1023
const byte LED = 13;
unsigned long ct1 = 0; // initialize the count interval
unsigned long ct2;
void setup() {
Serial.begin(9600);
pinMode(LED, OUTPUT);
}
void loop() {
ct2 = millis(); // Start the count
// Read raw Potentiometer data
int pot_1_rawData = analogRead(pot_1);
int pot_2_rawData = analogRead(pot_2);
// map Raw pot data for smoother incrementation of timming intervals
int pot_1_mappedData = map(pot_1_rawData, 0, 1023, 0, mappedUpperLimit);
int pot_2_mappedData = map(pot_2_rawData, 0, 1023, 0, mappedUpperLimit);
// create varibles and functions to store timmed interval that LED will be ON and OFF
//Multimpler is used to increment mapped data to larger intervals of time
// double is used so I can convert from milliseconds to 0.5 min increments
double onLimit_ms = pot_1_mappedData * ctMultiplier;
double resetLimit_ms = (pot_2_mappedData * ctMultiplier) + onLimit_ms;
// Set interval limits and compare them to the millis() count value
double offInterval_ms = ( resetLimit_ms - onLimit_ms );
long interval = ct2 - ct1;
// convert millisecond to minutes
double onLimit_Min = (onLimit_ms/(1000*60));
double offInterval_Min = (offInterval_ms/(1000*60));
// Print data
Serial.print("pot 1 Raw Data = ");
Serial.println(pot_1_rawData);
Serial.print("pot 2 Raw Data = ");
Serial.println(pot_2_rawData);
Serial.print("pot 1 Mapped Data = ");
Serial.println(pot_1_mappedData);
Serial.print("pot 2 Mapped Data = ");
Serial.println(pot_2_mappedData);
Serial.print("onLimit_ms = ");
Serial.println(onLimit_ms);
Serial.print("resetLimit_ms = ");
Serial.println(resetLimit_ms);
Serial.print("offInterval_ms = ");
Serial.println(offInterval_ms);
Serial.print("onLimit_Min = ");
Serial.println(onLimit_Min);
Serial.print("offInterval_Min = ");
Serial.println(offInterval_Min);
Serial.print("Time ct1 = ");
Serial.println(ct1);
Serial.print("Time ct2 = ");
Serial.println(ct2);
Serial.print( "interval = ");
Serial.println(interval);
Serial.print( "abs(interval) = ");
Serial.println(abs(interval));
// Action Items
// use abs() to ensure when the counting variable (ct2) rolls over its limit the difference still falls within the rules of if statemets below
if( abs(interval) < onLimit_ms ){
digitalWrite(LED, HIGH);
Serial.print("HIGH");
}
else{
digitalWrite(LED, LOW);
Serial.print("LOW");
}
if ( abs(interval) >= resetLimit_ms ){
ct1=ct2;
Serial.print("RESET");
}
Serial.println("//***************************************************************************************");
Serial.println();
}
What part of "millis is an unsigned long" did you not read?
A minute is 3600 ms, so half a minute would be 1800 ms. Your math makes no sense.
**Calm down Stevie boy.**
**It doesn't sound like you understand how prefixes work.**
**If you're gonna be a dick at least be right.**
You really should do everything in 'unsigned long' using milliseconds. It's OK to display intervals in minutes but there is no need to store values in minutes or half-minutes.
const int pot_1 = A2;
const int pot_2 = A3;
const unsigned long ctMultiplier = 30000ul; // 30 seconds
// 30 sec * 90 == 45 min ; 91 is used to ensure 45 min is reached as pot
// may fall short of full scale value of 1023
const int mappedUpperLimit = 91;
unsigned long PreviousTime = 0; // initialize the count interval
void setup()
{
Serial.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
}
void loop()
{
unsigned long currentTime = millis(); // Start the count
// map Raw pot data for smoother incrementation of timming intervals
int pot_1_mappedData = map(analogRead(pot_1), 0, 1023, 0, mappedUpperLimit);
int pot_2_mappedData = map(analogRead(pot_2), 0, 1023, 0, mappedUpperLimit);
// create variables and functions to store timed interval that LED_BUILTIN will be ON and OFF
// Multiplier is used to increment mapped data to larger intervals of time
// double is used so I can convert from milliseconds to 0.5 min increments
unsigned long onInterval_ms = pot_1_mappedData * ctMultiplier;
unsigned long offInterval_ms = pot_2_mappedData * ctMultiplier;
unsigned long resetInterval_ms = onInterval_ms + offInterval_ms;
// Set interval limits and compare them to the millis() count value
unsigned long interval = currentTime - PreviousTime;
// Print data
Serial.print("pot 1 Mapped Data = ");
Serial.println(pot_1_mappedData);
Serial.print("pot 2 Mapped Data = ");
Serial.println(pot_2_mappedData);
Serial.print("onInterval_ms = ");
Serial.println(onInterval_ms);
Serial.print("offInterval_ms = ");
Serial.println(offInterval_ms);
Serial.print("resetInterval_ms = ");
Serial.println(resetInterval_ms);
Serial.print("onInterval_Min = ");
Serial.println(onInterval_ms / 60000ul);
Serial.print("offInterval_Min = ");
Serial.println(offInterval_ms / 60000ul);
Serial.print("Time PreviousTime = ");
Serial.println(PreviousTime);
Serial.print("Time currentTime = ");
Serial.println(currentTime);
Serial.print( "interval = ");
Serial.println(interval);
// Action Items
if (interval < onInterval_ms)
digitalWrite(LED_BUILTIN, HIGH);
else
digitalWrite(LED_BUILTIN, LOW);
if (interval >= resetInterval_ms)
{
PreviousTime = currentTime;
Serial.print("RESET");
}
Serial.println("//***************************************************************************************");
Serial.println();
}