Go Down

Topic: Turn on/off sensor periodically using while loop and millis() instead of delay() (Read 1 time) previous topic - next topic

chaangfai

HI all,

I'm learning to control a sensor input periodically but not with delay() as it halts the whole code. So I used millis() to control time and use 2 While loops for sleeping and awakening mode. The sensor pin is supplied with 5v and 0v, so it goes in sleeping and awakening modes periodically.

The code is not working well - most times the sleeping mode takes longer period than the awakening mode even though the period used to control them are the same amount of time.

Quote

#define powerPin 12
#define proximiterPin 13

unsigned long nowTime, lastTime, lapseTime;
unsigned long  shortest = 1000;
unsigned long  longest = 6000;


void setup(){
 Serial.begin(9600);

 pinMode(powerPin, OUTPUT);
 pinMode(proximiterPin, OUTPUT);

 digitalWrite(powerPin, HIGH);  
 digitalWrite(proximiterPin, HIGH);
}


void loop(){
 Serial.println();
 int randomPeriod = random(shortest, longest);
 
 // Turn ON power pin for a period of time
 while(lapseTime <= randomPeriod){
   digitalWrite(powerPin, HIGH);    
   read_range();
   
   nowTime = millis();
   lapseTime = nowTime - lastTime;
 }

 lastTime = nowTime;
 nowTime = millis();
 lapseTime = nowTime - lastTime;
 
 // Turn OFF power pin for a period of time
 while(lapseTime <= randomPeriod){
   digitalWrite(powerPin, LOW);
   Serial.println("sleeping");
   nowTime = millis();
   lapseTime = nowTime - lastTime;
   
 }

 lastTime = nowTime;
 delay(150);
}



Can anyone guide me to how to make the code cleaner and work properly?

AWOL

Once a pin is written HIGH or LOW, it stays like that - there's no reason to repeatedly write it.

Your "while" loops are simply explicitly implementing "delay".

have a look at the blink-without-delay example to see a simple example of how it should be done.

robtillaart

using the right tags might help to look cleaner  # button iso quote :)

tinkered your code a bit, removed things from loop and used less vars.
(not compiled or tested

Code: [Select]

#define POWERPIN 12
#define PROXIPIN 13

unsigned long  now = 0;
unsigned long  shortest = 1000;
unsigned long  longest = 6000;

void setup()
{
 Serial.begin(115200);  // make serial comm as fast as possible

 pinMode(POWERPIN , OUTPUT);
 pinMode(PROXIPIN , OUTPUT);

 digitalWrite(POWERPIN , HIGH);  
 digitalWrite(PROXIPIN , HIGH);
}


void loop()
{
 Serial.println();

 long randomPeriod = random(shortest, longest);  // note both params are long so return val should be long too

 now = millis();
 digitalWrite(POWERPIN , HIGH);
 Serial.println("active");   // added
 while (millis() - randomPeriod  <  now )
 {
   read_range();
 }

 now = millis();
 digitalWrite(powerPin, LOW);
 Serial.println("sleeping");
 while (millis() - randomPeriod  <  now )
 {
   // empty loop
 }

 delay(150);  // and some extra sleep ...
}
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

chaangfai


Once a pin is written HIGH or LOW, it stays like that - there's no reason to repeatedly write it.

Your "while" loops are simply explicitly implementing "delay".

have a look at the blink-without-delay example to see a simple example of how it should be done.


HI AWOL,

Thanks. I now understand the while loop more.

chaangfai


using the right tags might help to look cleaner  # button iso quote :)

tinkered your code a bit, removed things from loop and used less vars.
(not compiled or tested


Hi robtillaart,

Thanks a lot for cleaning my code. I've implemented it in my sketch, which is now working falselessly.


Go Up