Hy, i am working on a Programm that does two thinks
Every x- Hourse it should turn on and of a relay (200ms) so that a motor is spinning a slow step, but when i press a button the motor should spin as long as i press the button.
I am doing that on a Arduino Nano, and my Code is working when i testet it with spin motor every 10sek.
But now i but in a 4 hour mark and.. after around 30-50min the motor starts spinning and will not stop, also button press will not work anymore.
I don´t get it because the libary need micro sek and 4 hours are 14400000000 microseconds, i but it in and since then i have troubles
Maybe you can help me out, i am not programming thats my first try and i take a lot to get that little code running.
Code:
#include <dmtimer.h>
/**
* Demonstrates the simplest use of the Timer class
*/
int ledPin = 13; // the number of the LED pin
int ledState = LOW;
int relais1pin = 2;
int sensorpin = 3;
DMTimer myTimer(14400000000); //Create a timer and specify its interval in microseconds
void setup(){
Serial.begin(115200);
// set the digital pin as output:
pinMode(ledPin, OUTPUT);
pinMode(relais1pin,OUTPUT);
pinMode(sensorpin, INPUT);
pinMode(LED_BUILTIN, OUTPUT);
}
void loop(){
int sensorstate = digitalRead(sensorpin);
if (sensorstate == 1) {
Serial.println("Sensor active");
// digitalWrite(ledPin, ledState);
//digitalWrite(2,LOW);
digitalWrite(relais1pin,HIGH);
} else {
Serial.println("Sensor not active");
digitalWrite(relais1pin,LOW);
// digitalWrite(ledPin, ledState); // turn the LED off by making the voltage LOW
if(myTimer.isTimeReached()){ //check if execution time has been reached
Serial.println("Halllllllllllllllllllllllllllllllllllllllllllllo"); //call what you need
// digitalWrite(2,LOW);
digitalWrite(relais1pin,HIGH);
delay (200);
digitalWrite(relais1pin,LOW);
myTimer.reset();
// digitalWrite(LED_BUILTIN, LOW);
//
}
}
}
That's more than 33 bits as a binary number. Imma guess no matter how you send it on in there, it's not gonna do what you want.
@deadfox if you really want to use that library mechanism, perhaps you could find it has a milliseconds version.
Otherwise you'll have to set the timer for as long as it can be, and count off a number of those smaller intervals and fire your action when enough of them to make up your entire delay have gone by.
Or do the whole thing in an entirely different way in code you should, sooner or later, learn to write yourself.
I tried a lot but with (millis) i was just did come fare, so i tried that libary,.. i did not thought about that 4hours will be to much, but it looks like it is
Mybe there is a nother libary i can use, because the dmtimer is only for microseconds i guess ..
The library uses micros(), the documentation for that says,
"Returns the number of microseconds since the Arduino board began running the current program. This number will overflow (go back to zero), after approximately 70 minutes."
But, there is no mention of that at all, on the library site.
Here is a code-version that should do what you want.
It does not need a lribrary.
There is a small function TimePeriodIsOver that does what the name says
return true or false depending on the timer expired or not
This function is based on millis()
If the timer has expired the timer-variables gets automatically updated
through the "&"-operator in the definition of the function
pass by reference
// MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START *
// a detailed explanation how these macros work is given in this tutorial
// https://forum.arduino.cc/t/comfortable-serial-debug-output-short-to-write-fixed-text-name-and-content-of-any-variable-code-example/888298
#define dbg(myFixedText, variableName) \
Serial.print( F(#myFixedText " " #variableName"=") ); \
Serial.println(variableName);
// usage: dbg("1:my fixed text",myVariable);
// myVariable can be any variable or expression that is defined in scope
#define dbgi(myFixedText, variableName,timeInterval) \
do { \
static unsigned long intervalStartTime; \
if ( millis() - intervalStartTime >= timeInterval ){ \
intervalStartTime = millis(); \
Serial.print( F(#myFixedText " " #variableName"=") ); \
Serial.println(variableName); \
} \
} while (false);
// usage: dbgi("2:my fixed text",myVariable,1000);
// myVariable can be any variable or expression that is defined in scope
// third parameter is the time in milliseconds that must pass by until the next time a
// Serial.print is executed
// end of macros dbg and dbgi
// print only once when value has changed
#define dbgc(myFixedText, variableName) \
do { \
static long lastState; \
if ( lastState != variableName ){ \
Serial.print( F(#myFixedText " " #variableName" changed from ") ); \
Serial.print(lastState); \
Serial.print( F(" to ") ); \
Serial.println(variableName); \
lastState = variableName; \
} \
} while (false);
// MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END *
const byte sensorpin = 3;
const byte relais1pin = 2;
unsigned long myTimer;
// 4 hours * 60 min/h * 60 sec/min * 1000 milliseconds
unsigned long WaitingTime = 4 * 60 * 60 * 1000ul;
void PrintFileNameDateTime() {
Serial.println( F("Code running comes from file ") );
Serial.println( F(__FILE__) );
Serial.print( F(" compiled ") );
Serial.print( F(__DATE__) );
Serial.print( F(" ") );
Serial.println( F(__TIME__) );
}
// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &startOfPeriod, unsigned long TimePeriod) {
unsigned long currentMillis = millis();
if ( currentMillis - startOfPeriod >= TimePeriod ) {
// more time than TimePeriod has elapsed since last time if-condition was true
startOfPeriod = currentMillis; // a new period starts right here so set new starttime
return true;
}
else return false; // actual TimePeriod is NOT yet over
}
const byte OnBoard_LED = 13;
void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {
static unsigned long MyBlinkTimer;
pinMode(IO_Pin, OUTPUT);
if ( TimePeriodIsOver(MyBlinkTimer, BlinkPeriod) ) {
digitalWrite(IO_Pin, !digitalRead(IO_Pin) );
}
}
void setup() {
Serial.begin(115200);
Serial.println( F("Setup-Start") );
pinMode(relais1pin, OUTPUT);
pinMode(sensorpin, INPUT);
PrintFileNameDateTime();
// initialise timer-variable
//with actual snapshot of time at powerup
myTimer = millis();
}
void loop() {
BlinkHeartBeatLED(OnBoard_LED, 250);
int sensorstate = digitalRead(sensorpin);
if (sensorstate == HIGH) {
//Serial.println("Sensor active");
dbgi("Sensor active", sensorstate, 1000);
digitalWrite(relais1pin, HIGH);
}
else {
dbgi("Sensor not active", sensorstate, 1000);
//Serial.println("Sensor not active");
digitalWrite(relais1pin, LOW);
// digitalWrite(ledPin, ledState); // turn the LED off by making the voltage LOW
if ( TimePeriodIsOver(myTimer, WaitingTime) ) {
//Serial.println("Halllllllllllllllllllllllllllllllllllllllllllllo"); //call what you need
dbg("Timer elapsed", WaitingTime);
digitalWrite(relais1pin, HIGH);
delay (200);
digitalWrite(relais1pin, LOW);
}
}
}
Thanks for your anwsers, i am trying that first code at the moment.
it seams to work when i press the button perfectly but i think its not spinning with the timer every 4 hourse.. maybe i have to check that up with a smaller intervall.
Why do i need that UL after the Numbers (does it mean Ultra Long?) i thought i will just but in the milisecounds now.
very good observation
The "ul" at the end makes sure that the compiler treats everything as unsigned 32bit-integers.
"ul" stands for unsigned long
Without the "ul" the compiler might treat it as 16bit values which could lead to strange results.
16 bit means maximum value that can be hold by an 16bit integer is
2^16 = 65536 which is smaller than the desired
14.400.000 ms
Ok, good to know =)
Now its just a thing that i get that for working.. haha..
i did not figure out till now why its not running with the timer but its doing with the button
not in this case when you only have one value and no operations. The compiler will pick the smaller integral type where the value fits. So here it would be a long.
So I don't really need it but it's a good habit to take to give a hint to the compiler what you want to do. Here I'm forcing unsigned long.
if you press the button my code resets the 4h delay as commented in the relayOn() call
just remove that line if you want 4 hours no matter what you did with the button.
I changed the code now a bit because after some testing i found that RelayOFF / ON are reversed, now i think thats working..
After that i testet today and it seams (tryed with 10sek intervall) after some times the board gets freezed during a re-start because my ESC is sucking to much power for the Motor from the 12 to 5v mini BEC i am using.
I switched the wiring now so that the ESC is powerd all the time and only the Motor gets the input through the Relay, before it was that the ESC is getting powerd for the 200ms.. but that looked like its not working,.. so i will let it run now with 1 hour timer, and a littly sticky note on my motor too see what is going on =)