Serial.println and a timer Question

Hey all, I'm trying to make a dial using the rotary encoder that comes with the mega2560 starter kit that controls the 'temperature' of a fake hot plate that I'm making for an escape room.

The intent of this is to control the temperature (determined from the dial spinning clockwise or counter clockwise) of the hot plate, and once the desired temperature (20 in this case) is reached and dial stays at that temperature for a few seconds another light turns on.

Now my issue is that I made a timer using an increment and a integer called "T" and everything works fine until I comment out the two Serial.println(T) inside the while loop. Once ran like this, and the temperature reaches 20 the ledMelt turns on with no delay.

I didn't want to use the delay function as I want it to detect if the dial is turned while at the desired temperature as this is a prop and I don't want someone who's just spinning the dial to get this effect of ledMelt. I'm aware I could just keep the Serial.println uncommented and move on, but I plan on adding more stuff later on and I'd like to clean up the serial monitor a bit for the future.

Additionally, it is day two of coding, please be kind :slight_smile:

#define inputCLK 4
#define inputDT 5
#define ledHeat 9
#define ledMelt 11
  int I;
  int T;
  int MP=25;
  int Temp=0;
  int currentStateCLK;
  int lastStateCLK;
 String encdir="";

void setup() {
  
 pinMode(inputCLK,INPUT);
 pinMode(inputDT,INPUT);
 pinMode(ledHeat,OUTPUT);
 pinMode(ledMelt, OUTPUT);
 Serial.begin(9600);
 lastStateCLK=digitalRead(inputCLK);
}

//end of setup

void loop() {
  currentStateCLK=digitalRead(inputCLK);

  if(currentStateCLK!=lastStateCLK){
    
        if(digitalRead(inputDT) != currentStateCLK){
    Temp--;
    encdir="cooling...";
    //fade led to lower power here
        }
         else{
          Temp ++;
          encdir= "Heating...";
          //fade led to higher power here
          digitalWrite(ledHeat,HIGH);
         }
        
      
        Serial.print("Temperature: ");
        Serial.print(encdir);
        Serial.print(Temp);
        Serial.println(" Degrees ");
 }
      while(currentStateCLK==lastStateCLK and Temp==20){
        if(digitalRead(inputDT) != lastStateCLK){
          T=0;
          break;
        }
          if(digitalRead(inputCLK) != lastStateCLK){
           T=0;
           break;
          }
            if(T == 1000){
            int I=0;
            T=T+I;
            //Serial.println(T);
            digitalWrite(ledMelt, HIGH);
            break;
          }         
        else{
        int I=1;
        T=T+I;
        //Serial.println(T);
        }
     //end of while loop
   }
if(digitalRead(ledMelt)==HIGH and digitalRead(inputCLK!=lastStateCLK)){
  digitalWrite(ledMelt, LOW);

}
             
lastStateCLK=currentStateCLK;
}

I would recommend to use a library (encoder library is great) and a state machine approach for the structure of the code

Something like this (typed here, mind typos)

bool timerStarted = false;
unsigned long startTime;
…
void loop() {
  long encoderValue = … // read encoder
  if (encoderValue == 20)  {
    if (timerStarted) {
      if (milis() - startTime >= 10000) { // 10s elapsed at encoderValue 20
         …  //   Bingo !
      }
    } else {
      startTime = millis();
      timerStarted = true;
    }
  } else {
    timerStarted = false; 
 }
}
1 Like

In fact you use a delay function. Serial communication is fairly slow, especially when using 9600 baud. If the serial buffer get's completely filled up, because of printing very much and very fast, Serial.print blocks until there is free space in the buffer again.
So the effect is the same, if you use a delay instead of your Serial.prints.

or:

unsigned long startTime = 0;

void loop() 
{
  long encoderValue = … // read encoder

  if (encoderValue != 20)
    startTime = millis();

  if (millis() - startTime >= 10000) 
  { 
    // 10s elapsed since encoderValue != 20
    //   Bingo !
  }
}
1 Like

Even better indeed !

1 Like