Problem with serial print

Hi,

I am having trouble with my code. I am trying to display my temperature and pwm value in every 1/2 second after give a character inside the serial monitor. The problem is, each time I gave a character in the serial monitor, the temperature and pwm only display once. I tried using while loop before, but it cannot read the next character I gave and only iterates inside the loop.

If you guys have any suggestion or advice, feel free to reply. :slight_smile:

Thank you in advance.

#include <Thermistor.h>
#include <PID_v1.h>
#define dir 8  // Enable Pin for motor 2 -dir

//Define Variables we'll be connecting to
double Setpoint, Input, Output;

//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint,5,1,1, DIRECT);

Thermistor temp(0);
char rx_byte = 0;

void setup()
{
  
  Serial.begin(9600); 
  pinMode(dir, OUTPUT);  
}

void loop()
{
 if (Serial.available() > 0) {    // is a character available?
          rx_byte = Serial.read();  
         
          if (rx_byte == 'a')
          {
              Input = analogRead(0);
              myPID.SetMode(AUTOMATIC);
              Setpoint = 40;
              Serial.println("HEATING PROCESS");
              digitalWrite(dir, HIGH);//peltier hot
              Input = temp.getTemp();
              delay(500);
              Serial.print("TEMPERATURE = ");
              Serial.println(Input);
              myPID.Compute();
              analogWrite(9,Output);
              Serial.print("PWM = ");
              Serial.println(Output);  
        }

        if (rx_byte == 'b')
        {
              Input = analogRead(0);
              myPID.SetMode(AUTOMATIC);
              Setpoint = 100;
              Serial.println("COOLING PROCESS");
              digitalWrite(dir, LOW);//peltier cold
              Input = temp.getTemp();
              delay(500);
              Serial.print("TEMPERATURE = ");
              Serial.println(Input);
              Input = analogRead(0);
              myPID.Compute();
              analogWrite(9,Output);
              Serial.print("PWM = ");
              Serial.println(Output);
        }
        }
  
}

What have you got Line ending set to in the Serial monitor ?

I am sorry, I didn’t get what you mean. But I attach the screencap of the serial monitor display when I run the code to my project.

What I had in mind was that if you had a line ending character then it would be read by your program and would stop the display of data when it was received.

But right now, the temperature and pwm only displayed once. It is hard for me to monitor the temperature. Based on the coding I gave before, it can read when I give different character but it only displayed the temperature once. :sweat_smile:

Pic from Reply #2
7adbf9902bdb5c3d45df3f5f68b03bbcddc1f7ac.png

…R

@fiqa_joe, Please modify your post and use the code button </>

so your code looks like this

and is easy to copy to a text editor. See How to use the Forum

The way your code is written it can only print once for every character received. If you want a character to start a sequence of prints then you should save the character value and have some code like

if (savedVal == 'B') {
  // do stuff
}

That way the code can keep acting on the character even though you don’t enter it repeatedly.

Edit to say See also Reply #9, below

Also have a look at Several Things at a Time to see how to manage the repeat timing using millis()

You may also be interested in Serial Input Basics

…R

Do not place the if(rx_byte==…) inside the if(Serial.available()>0). Currently your code only executes if a character is available.

Not tested code:

void loop()
{
  if (Serial.available() > 0) {    // is a character available?
    rx_byte = Serial.read();
  }

  if (rx_byte == 'a')
  {
    Input = analogRead(0);
    myPID.SetMode(AUTOMATIC);
    Setpoint = 40;
    Serial.println("HEATING PROCESS");
    digitalWrite(dir, HIGH);//peltier hot
    Input = temp.getTemp();
    delay(500);
    Serial.print("TEMPERATURE = ");
    Serial.println(Input);
    myPID.Compute();
    analogWrite(9, Output);
    Serial.print("PWM = ");
    Serial.println(Output);
  }

  if (rx_byte == 'b')
  {
    Input = analogRead(0);
    myPID.SetMode(AUTOMATIC);
    Setpoint = 100;
    Serial.println("COOLING PROCESS");
    digitalWrite(dir, LOW);//peltier cold
    Input = temp.getTemp();
    delay(500);
    Serial.print("TEMPERATURE = ");
    Serial.println(Input);
    Input = analogRead(0);
    myPID.Compute();
    analogWrite(9, Output);
    Serial.print("PWM = ");
    Serial.println(Output);
  }
}

Note that this might send data at relatively high rate.

PS
Next time don’t quote your code but place it between [code] and [/code] tags.

@robin2 rx_byte is already remembered as it's global; no need for an additional variable as far as I can see;)

@fiqa_joe It might be advisable to rename 'rx_byte' to something like 'command'. You can also initialize it in the declaration to 'a' or 'b' (instead of 0) if you want to execute the default code immediately in the loop.

sterretje: @robin2 rx_byte is already remembered as it's global; no need for an additional variable as far as I can see;)

True. However I was trying to get the OP to think of having the value in a variable that is separate from the business of receiving the data. You could, of course, use rx_byte with a reorganized program.

@fiqa_joe, prompted by this, I think I would have been more useful if I had suggested that you move the if (rx_byte) tests outside the if (Serial.available) test.

...R

Thank you so much for your help. It working now by removing the if(rx_byte==...) from the if(Serial.available()>0) loop.

And sorry for poor posting.

:)