Go Down

Topic: Updating analog sensor without using "void loop()"...... (Read 810 times) previous topic - next topic

concretefreak

I currently have three analog sensors that update every 100ms.  I have written a program that accomplishes this task when the code is inserted within "void loop" and works as it should.  I have a menu program that has multiple menus, what i would like to do is insert this code into one of these menus.  I have tried inserting the code into the menu function but the sensor does not update continuously, and I assume this is because the menu function is not part of or inside the "void loop".   Is there a command I can try or a known way of manipulating code that does NOT run within "void loop" to update continuously?

Thank you in advance for your help and/or opinions.  

Dave

Arrch

You mean the code is stored inside it's own function? You simply need to call the function in the loop. You'd be better off, posting your code (Using the code tag) so that we have an idea of how you've set this up.

skyjumper

If you need to read those sensors every 100ms, you'll need a loop somewhere. You can out it anywhere, but you'll need a loop. Search for "blink without delay" and you'll see how this is done. Another option is to run a timer interrupt, and read the sensors in the ISR, but that's a little advanced.

Just do a loop, read the time using millis() and save this value. Each time through the loop, compare the current time with the saved time, and if the difference is at least 100ms, read the sensors.

concretefreak


If you need to read those sensors every 100ms, you'll need a loop somewhere. You can out it anywhere, but you'll need a loop. Search for "blink without delay" and you'll see how this is done. Another option is to run a timer interrupt, and read the sensors in the ISR, but that's a little advanced.

Just do a loop, read the time using millis() and save this value. Each time through the loop, compare the current time with the saved time, and if the difference is at least 100ms, read the sensors.



Thats kinda of what i figured, I have to use a loop somewhere.  Heres my dilemma, when I call sensors 1,2 & 3 in the loop under "menu #1" it works great, but when I switch to "menu #2" (which runs a different set of sensors) and call sensors 4,5 & 6 in the loop under "menu #2" all six sensors run over each other at the same time.  Another words instead of running sensor 1,2 & 3 in "menu #1" then run sensor 3, 4 & 5 in "menu #2", they are running on top of each other after calling "menu #2".  Its like "menu #1" does not clear or stop running when "menu #2" is called. 

I will try to post a portion of the code, as I have already tried to post the complete program and it appears to exceed the character allowed.

Thanx!!
Dave

concretefreak


If you need to read those sensors every 100ms, you'll need a loop somewhere. You can out it anywhere, but you'll need a loop. Search for "blink without delay" and you'll see how this is done. Another option is to run a timer interrupt, and read the sensors in the ISR, but that's a little advanced.

Just do a loop, read the time using millis() and save this value. Each time through the loop, compare the current time with the saved time, and if the difference is at least 100ms, read the sensors.



Heres a section of the code...

Code: [Select]
menu.getRoot().add(menu1Item1);
 menu1Item1.addRight(menu1Item2).addRight(menu1Item3);
 menu1Item1.add(menuItem1SubItem1).addRight(menuItem1SubItem2);
 menu1Item2.add(menuItem2SubItem1).addRight(menuItem2SubItem2).addRight(menuItem3SubItem3);
 menu.toRoot();        

}  // setup()...


void loop()
{

 readButtons();  //I splitted button reading and navigation in two procedures because
 navigateMenus();  //in some situations I want to use the button for other purpose (eg. to change some settings)
 readSensors();
 
 Input = analogRead(A0);
 myPID.Compute();
 /************************************************
  * turn the output pin on/off based on pid output
  ************************************************/
 if(millis() - windowStartTime>WindowSize)
 { //time to shift the Relay Window
   windowStartTime += WindowSize;}
 if(Output < millis() - windowStartTime) digitalWrite(RelayPin,HIGH);
 else digitalWrite(RelayPin,LOW);
 
 
}  
         
//loop()...


void menuChanged(MenuChangeEvent changed){
 
 MenuItem newMenuItem=changed.to; //get the destination menu

 lcd.clear();
 lcd.setCursor(0,0); //set the start position for lcd printing to the second row
 
 if(newMenuItem.getName()==menu.getRoot()){
           
       lcd.setCursor(2, 1); // set the cursor to column 0, line 0
       lcd.print("PPO1");  // Print a message to the LCD.
   
       lcd.setCursor(8, 1); // set the cursor to column 6, line 0
       lcd.print("PPO2"); // Print a message to the LCD
   
       lcd.setCursor(14, 1); // set the cursor to column 12, line 0
       lcd.print("PPO3");  // Print a message to the LCD.
     
 }else if(newMenuItem.getName()=="SET POINT-->"){
       lcd.print("SET POINT-->");
     }else if(newMenuItem.getName()=="SET POINT MENU--->"){
       lcd.setCursor(0, 0);  
       lcd.print("   SETPOINT  MENU     ");
       lcd.setCursor(0,1);
       lcd.print("  SV=       PV=     ");
     }else if(newMenuItem.getName()=="Item1SubItem2"){
       lcd.print("Item1SubItem2   ");
 }else if(newMenuItem.getName()=="TIME SETTINGS"){
       lcd.print("TIME SETTINGS");
     }else if(newMenuItem.getName()=="Item2SubItem1"){
       lcd.print("Item2SubItem1   ");
     }else if(newMenuItem.getName()=="Item2SubItem2"){
       lcd.print("Item2SubItem2   ");
     }else if(newMenuItem.getName()=="Item2SubItem3"){
       lcd.print("Item2SubItem3   ");
 }else if(newMenuItem.getName()=="Item--->3"){
     lcd.print("Item--->3           ");
 }
}

void menuUsed(MenuUseEvent used){
 
 
 
}


void  readButtons(){  //read buttons status
 int reading;
 int buttonEnterState=LOW;             // the current reading from the Enter input pin
 int buttonEscState=LOW;             // the current reading from the input pin
 int buttonLeftState=LOW;             // the current reading from the input pin
 int buttonRightState=LOW;          // the current reading from the input pin


 //Enter button
                 // read the state of the switch into a local variable:
                 reading = digitalRead(buttonPinEnter);

                 // check to see if you just pressed the enter button
                 // (i.e. the input went from LOW to HIGH),  and you've waited
                 // long enough since the last press to ignore any noise:  
               
                 // If the switch changed, due to noise or pressing:
                 if (reading != lastButtonEnterState) {
                   // reset the debouncing timer
                   lastEnterDebounceTime = millis();
                 }
                 
                 if ((millis() - lastEnterDebounceTime) > debounceDelay) {
                   // whatever the reading is at, it's been there for longer
                   // than the debounce delay, so take it as the actual current state:
                   buttonEnterState=reading;
                   lastEnterDebounceTime=millis();
                 }
                 
                 // save the reading.  Next time through the loop,
                 // it'll be the lastButtonState:
                 lastButtonEnterState = reading;
                 

   //Esc button              
                 // read the state of the switch into a local variable:
                 reading = digitalRead(buttonPinEsc);

                 // check to see if you just pressed the Down button
                 // (i.e. the input went from LOW to HIGH),  and you've waited
                 // long enough since the last press to ignore any noise:  
               
                 // If the switch changed, due to noise or pressing:
                 if (reading != lastButtonEscState) {
                   // reset the debouncing timer
                   lastEscDebounceTime = millis();
                 }
                 
                 if ((millis() - lastEscDebounceTime) > debounceDelay) {
                   // whatever the reading is at, it's been there for longer
                   // than the debounce delay, so take it as the actual current state:
                   buttonEscState = reading;
                   lastEscDebounceTime=millis();
                   
                 }
                 
                 // save the reading.  Next time through the loop,
                 // it'll be the lastButtonState:
                 lastButtonEscState = reading;  

                 //records which button has been pressed
                 if (buttonEnterState==HIGH){
                   lastButtonPushed=buttonPinEnter;

                 }else if(buttonEscState==HIGH){
                   lastButtonPushed=buttonPinEsc;

                 }else if(buttonRightState==HIGH){
                   lastButtonPushed=buttonPinRight;

                 }else if(buttonLeftState==HIGH){
                   lastButtonPushed=buttonPinLeft;

                 }else{
                   lastButtonPushed=0;
                 }                  
}


void readSensors(){
       
         lcd.setCursor(2, 2); //sets the cursor to column 0, line 1    
         inputReading1 = analogRead(sensor1); //getting the voltage reading from the 02 sensor    
         float voltage1 = inputReading1 * aref_voltage; // converting that reading to voltage
         voltage1 /= 1024.0;    
         lcd.print(voltage1, 2);//print actual voltage to lcd    
         delay(200);
     
 
         lcd.setCursor(8, 2); //sets the cursor to column 6, line 1    
         inputReading2 = analogRead(sensor2); //getting the voltage reading from the temperature sensor    
         float voltage2 = inputReading2 * aref_voltage; // converting that reading to voltage
         voltage2 /= 1024.0;
         lcd.print(voltage2, 2);  //print actual voltage to lcd
         delay(200);    
   
   
         lcd.setCursor(14, 2); //sets the cursor to column 12, line 2    
         inputReading3 = analogRead(sensor3); //getting the voltage reading from the temperature sensor    
         float voltage3 = inputReading3 * aref_voltage; // converting that reading to voltage
         voltage3 /= 1024.0;
         lcd.print(voltage3, 2);  //print actual voltage to lcd
         delay(200);}
         
         if(DateTime.available()) {
         lcd.setCursor(3, 1);
         unsigned long prevtime = DateTime.now();
         while( prevtime == DateTime.now() ); // wait for the second to rollover

         DateTime.available(); //refresh the Date and time properties
         digitalClockDisplay( ); // update digital clock
         }
           
      }
       
     
void navigateMenus() {
 MenuItem currentMenu=menu.getCurrent();
 
 switch (lastButtonPushed){
   case buttonPinEnter:
     if(!(currentMenu.moveDown())){  //if the current menu has a child and has been pressed enter then menu navigate to item below
       menu.use();
     }else{  //otherwise, if menu has no child and has been pressed enter the current menu is used
       menu.moveDown();
      }
     break;
   case buttonPinEsc:
     menu.toRoot();  //back to main
     break;
   case buttonPinRight:
     menu.moveRight();
     break;      
   case buttonPinLeft:
     menu.moveLeft();
     break;      
 }
 
 lastButtonPushed=0; //reset the lastButtonPushed variable
}

liudr

Try timer1 library. You can use the timer to call your sensor function every 100ms.

PaulS

Quote
Heres my dilemma, when I call sensors 1,2 & 3 in the loop under "menu #1" it works great, but when I switch to "menu #2" (which runs a different set of sensors) and call sensors 4,5 & 6 in the loop under "menu #2" all six sensors run over each other at the same time.

Some proper terminology would really help. You can't "call a sensor". The sensor is just not capable of responding to a "call".

As a result of the terminology, I can't really understand what you are doing with the sensors "under menu 1". Displaying a menu is a state. There are other things going on in that state, and different things that you need to be doing while waiting for user input to define what state to go to next.

MarkT

You need to study the blinkWithoutDelay example and remove all the delay() calls in your code, its not the way to do things when you have to attend to more than one task at once.
[ I won't respond to messages, use the forum please ]

concretefreak


Quote
Heres my dilemma, when I call sensors 1,2 & 3 in the loop under "menu #1" it works great, but when I switch to "menu #2" (which runs a different set of sensors) and call sensors 4,5 & 6 in the loop under "menu #2" all six sensors run over each other at the same time.

Some proper terminology would really help. You can't "call a sensor". The sensor is just not capable of responding to a "call".

As a result of the terminology, I can't really understand what you are doing with the sensors "under menu 1". Displaying a menu is a state. There are other things going on in that state, and different things that you need to be doing while waiting for user input to define what state to go to next.


Paul,
     Thanx for your reply. I know my terminology may not be perfect but your ability to read the code I posted must not be very good either.  I was hoping that someone with an extensive backround in arduino would be able to read the portion of code I posted and offer some ideas and /or a solution.   I appreciate your efforts but please if you have nothing to suggest please do not reply to the post.

concretefreak


Try timer1 library. You can use the timer to call your sensor function every 100ms.


Thank you!! I'll give it a go!!

concretefreak


You need to study the blinkWithoutDelay example and remove all the delay() calls in your code, its not the way to do things when you have to attend to more than one task at once.


Thank you for your input.  I have studied the bilnk without delay and found that the sensors work really well with a small delay, and this is due to the RGB leds that have to flash with each sensor to indicate the current output. 

Go Up