Hi,
I am prgramming a sketch to do a analogread on two pins every once in a while.
For testing purposes I need to interval this analogread every second. But the normal program would be a read every 12hours. So I was about to add a switch so I can select in which mode we are in. Normal or test mode.
How can I program the sketch that when switch is on it would use interval 1 second and when switch is off it would use interval 12 hours. Maybe someone has a quick and simple solution? Would not use delay function, because when it is running in normal mode it won't switch to test mode if the 12 hours delay isn't elapsed.
Thanks, Bert
delchrys:
Would not use delay function, because when it is running in normal mode it won't switch to test mode if the 12 hours delay isn't elapsed.
That is indeed a great point ![]()
But what about in the loop
if(digitalRead(SwitchPin)){
delay = 1 * 1000UL;
}
else{
delay = 12 * 60 * 1000UL;
}
But most of the time I don't care to change it on the fly. I just recompile it to have the right time in it after debugging. And to make it easy I do something like
///#define MY_DEBUG //Uncomment to enter debug mode
#if defined(MY_DEBUG)
const unsigned long Delay = 1 * 1000UL;
#else
const unsigned long Delay = 12 * 60 1000UL;
#endif
I use the same construction to print or not print debug info via serial.
but if the 12601000UL is running, the loop just waits and will never see a change of the switchpin.
So i have to wait until the delays is finished???
Would something like this work?
unsigned long start, fin;
bool swState, oldSwState;
const byte sw = 10;
void Setup(){
pinMode(sw,INPUT_PULLUP);
}
void loop()
{
swState = digitalRead(sw);
if(swState != oldSwState)
{
start = millis();
oldSwState = swState;
}
if(swState) fin = 12 * 60 * 1000UL;
else fin = 12 * 60 * 1000UL;
if(millis() - start > fin)
{
start += fin;
doUpdate;
}
}
This is why the usual advice is to avoid delay(...) and use millis() instead. However, you may have to rearrange your program.
delay(...) prevents most useful things from happening. In software circles, this is known as blocking. millis() is nonblocking.
Read the setting of the switch.
Use millis() to find out the current time.
Use subtraction (and ONLY subtraction!) to determine whether sufficient time has passed.
(Why do I say to use subtraction? It is because millis() returns an unsigned long that will roll over after 49 and a fraction days. Subtraction is guaranteed to work in this case, but not addition. See
if you want more information.)
so now i have something like this;
const int threshold = 400;
const int ledPinRood = 8;
const int ledPinGroen = 9;
unsigned int time = 0;
int pulseCount = 0;
int pulseCount2 = 0;
void setup() {
Serial.begin(9600);
pinMode(ledPinRood, OUTPUT);
pinMode(ledPinGroen, OUTPUT);
pinMode(10, INPUT);
}
void loop() {
int sensorValue = analogRead(A5);
int sensorValue2 = analogRead(A7);
int switchvalue = digitalRead(10);
Serial.print("Sensor 1: ");
Serial.print(sensorValue);
Serial.print(" -----------//////-------------- ");
Serial.print("Sensor 2: ");
Serial.println(sensorValue2);
Serial.println(switchvalue);
Serial.println(pulseCount);
Serial.println(pulseCount2);
if (sensorValue > threshold){
pulseCount++;}
else
{
pulseCount = 0;
}
if (sensorValue2 > threshold){
pulseCount2++;}
else pulseCount2 = 0;
if (pulseCount > 6 | pulseCount2 > 6){
digitalWrite(ledPinRood, HIGH);
digitalWrite(ledPinGroen, LOW);}
else{
digitalWrite(ledPinRood, LOW);
digitalWrite(ledPinGroen, HIGH);
}
if(digitalRead(10)){
time = 1 * 1000UL;
}
else{
time = 12 * 60 * 1000UL;
}
delay(time); // delay in between reads for stability
}
How did you connect the switch? Is it working as you expected?
The code still has a delay(...) that will keep it from responding to a change in pin 10.
Yep, I just fixed a foulup in my post, think I'll dupe as much of his pgm as I can & try to run it.
Its just a toggle switch from +5v to switch, from switch to D10 and from D10 to ground via 10k resistor. And yes this is working normally.
Got it, (I think) delchrys, try this: (And translate to . . . Dutch?)
const int threshold = 400;
const int ledPinRood = 8;
const int ledPinGroen = 9;
unsigned int time = 0;
int pulseCount = 0;
int pulseCount2 = 0;
unsigned long start, fin; //NEW
bool swState, oldSwState; //NEW
const byte sw = 10; //NEW one side of switch to GND,
//other to pin 10
void setup() {
Serial.begin(9600);
pinMode(ledPinRood, OUTPUT);
pinMode(ledPinGroen, OUTPUT);
//pinMode(10, INPUT);
pinMode(sw, INPUT_PULLUP); //NEW
}
void loop() {
swState = digitalRead(sw);
if (swState != oldSwState)
{
start = millis();
oldSwState = swState;
}
if(swState)
fin = 30 * 1000UL; // 30 seconds for testing
else
fin = 1000UL;
if (millis() - start > fin)
{
start += fin;
int sensorValue = analogRead(A5);
int sensorValue2 = analogRead(A7);
int switchvalue = digitalRead(10);
Serial.print("Sensor 1: ");
Serial.print(sensorValue);
Serial.print(" -----------//////-------------- ");
Serial.print("Sensor 2: ");
Serial.println(sensorValue2);
Serial.println(switchvalue);
Serial.println(pulseCount);
Serial.println(pulseCount2);
if (sensorValue > threshold) {
pulseCount++;
}
else
{
pulseCount = 0;
}
if (sensorValue2 > threshold) {
pulseCount2++;
}
else pulseCount2 = 0;
if (pulseCount > 6 | pulseCount2 > 6) {
digitalWrite(ledPinRood, HIGH);
digitalWrite(ledPinGroen, LOW);
}
else {
digitalWrite(ledPinRood, LOW);
digitalWrite(ledPinGroen, HIGH);
}
}
}
Sensors are tcrt5000 modules. They are used for detecting the presence of something. When it is not there for 3 days a led will change from green to red.
Sorry for using Dutch in my code, normally I won't do that. Tomorrow is will try the new code. Did I see I have to reconnect the 5v from switch to ground? I have also tried that but then I got some false values due to floating of the d10 pin.
You can leave the switch as is but you may have to reverse the logic, no problem with language, your English beats the s**t out of my Dutch.
Haha long live the Commodore 64 where I learned better English. Thanks for updating my sketch, tomorrow I'm back at work where my sketch and protoboard is, so I'll be back tomorrow evening.
delchrys:
but if the 12601000UL is running, the loop just waits and will never see a change of the switchpin.
So i have to wait until the delays is finished???
No it does not
You are confusing "delay(12 * 60 * 1000UL)" with "unsigned long delay = 10 * 60 * 1000UL".
All I did was assiging two different values to a variable called "delay" depending on the state of a switch. After that you can use that variable "delay" in you millis()-based delay.
unsigned long delay;
if(digitalRead(SwitchPin)){
delay = 1 * 1000UL;
}
else{
delay = 12 * 60 * 1000UL;
}
if(millis() - previousMills >= delay){
previousMillis = millis();
//do what you want to do
}