Different time response.

Hi, folks! :slight_smile:

This is my code for example:

#include <Servo.h>

Servo myservo;  // create servo object to control a servo

int tempPin = 0;  
int temp;    
int servoVal;

void setup()
{
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object

  Serial.begin(9600);
}

void loop()
{

  temp = analogRead(tempPin);
  temp = (500 * temp) / 1023;  

  if (temp >= 28) {

    myservo.write(90);
  } else {

    myservo.write(0);
  }

  Serial.print("Temperatura = ");
  Serial.print(temp);
  Serial.println(" C");
  Serial.print("Servo = ");
  Serial.print(servoVal);
  delay(5000);                            

}

What I want to do is read current temperature every ms and print values only every 5 seconds. If temperature changes evary seconds I won’t wait 5 seconds to turn servo 90 degress. My question is how can I update my code?

Thanks !

Don't use delay?

How to do multiple things at once ... like cook bacon and eggs

[quote author=Nick Gammon link=msg=2787808 date=1465198945] Don't use delay?

How to do multiple things at once ... like cook bacon and eggs [/quote]

Thank you a lot for your breakfast tutorial ! :)

Yes, I know that delay is the problem and I must use millis. But didn't how.

Thank you.

Well, you use millis() to find how much time has elapsed (eg. up to 5 seconds). Also you check if the temperature has changed. Whichever comes first, you act.

Hello again !

Now I update my code:

#include <Servo.h>

Servo myservo;  // create servo object to control a servo

int tempPin = 0;  // analog pin used to connect the LM35
int temp;    // variable to read the value from the analog pin
int pos; // servo possition

const unsigned long printInterval = 5000; // set print interval 5 sec
const unsigned long readInterval = 1000; // set read interval 1 sec

unsigned long printTimer = millis();
unsigned long readTimer = millis();

char myChar = '°'; // crate char °

void setup()
{
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  
  Serial.begin(9600); // creat serial communication with 9600 baud rate
}

void loop()
{
  temp = analogRead(tempPin); // read values from analog pin A0 (LM35 signal pin)
  temp = (500 * temp) / 1023;  // calculate LM35 temperature in celsius
  if ((millis() - readTimer) >= readInterval) { // after 1 sec read temp pin

    if (temp >= 28) { // if temp >= 28 degrees then turn servo 90°

      pos = 90;
      myservo.write(pos); // servo write pos
    } else { // if temp <= 28 degrees then turn servo back to 0°
      pos = 0;
      myservo.write(pos); // servo write pos
    }
    readTimer = millis();
  }

  if ((millis() - printTimer) >= printInterval) { // after 5 sec print temp and servo value/state
    Serial.print("Temperatura = "); // pint Temperatura =
    Serial.print(temp); // print temp value in celsius
    Serial.print(myChar); // print char °
    Serial.println("C"); //print C
    Serial.print("Servo = "); // print Servo =
    Serial.print(pos); // print servo pos
    Serial.println(myChar); // print char °
    printTimer = millis();

  }
}

Now it’s works as I expected, but is one minus. :frowning: Every time when I upload code, press reset button or open serial monitor, servo turns 90 degrees and back. :frowning: WHY?

I tried change this, but without results:

    if (temp <= 28) { // if temp <= 28 servo 0°

      pos = 0;
      myservo.write(pos); // servo write pos
    } else { // if temp >= 28 degrees then turn servo 90°
      pos = 90;
      myservo.write(pos); // servo write pos
    }
    readTimer = millis();
  }

Second problem is I tried this https://www.arduino.cc/en/Reference/Char to print ° (248) but ASCII didn’t print °. Printed this щ :frowning:

Second problem is I tried this https://www.arduino.cc/en/Reference/Char to print ° (248) but ASCII didn't print °.

How did you try to print the degree symbol? It seems to me that if you were looking at the char page, you would have seen that char is a signed type, with a range of -128 to 127. Is 248 in that range?

PaulS: How did you try to print the degree symbol? It seems to me that if you were looking at the char page, you would have seen that char is a signed type, with a range of -128 to 127. Is 248 in that range?

Yes, you are right ! I remember this after I post !

char is a signed type, with a range of -128 to 127. Is 248 in that range?

I'm not sure how extended ASCII is working, but I get 5 degree symbols printed with the following code with IDE 1.6.9. I copied the degree symbol from a print out to the monitor because I do no know how to print extended ASCII when writing the sketch.

void setup() {
  char myChar1 = 248;
  char myChar2 = 'ø'; 
  char myChar3 = '°';
  Serial.begin(9600);
  Serial.println(myChar1);
  Serial.println((char)248);
  Serial.println('ø');
  Serial.println(myChar2);
  Serial.println('°');
  Serial.println(myChar3); 
}

void loop() {
  // put your main code here, to run repeatedly:

}

EDIT: If is use press the alt key and type 248 from the keypad numbers, I get a slightly different degree symbol. ° but it prints out with Serial.print('°') This looks like a better symbol printed high on the line. I modified the sketch to use it.

Thank you all!

Second problem solved. Left first one with servo.

  if ((millis() - readTimer) >= readInterval) { // after 1 sec read temp pin

What are the useless comments for? That is NOT what the if statement controls. You've already read the temperature.

Get rid of the useless comments. Add more Serial.print() statements.

  temp = (500 * temp) / 1023;  // calculate LM35 temperature in celsius

A reading from the analog pin of greater than 65, will overflow the calculation. Not a good thing. What ARE you reading from the pin?

How is the servo powered?

PaulS:   if ((millis() - readTimer) >= readInterval) { // after 1 sec read temp pin

  temp = (500 * temp) / 1023;  // calculate LM35 temperature in celsius

A reading from the analog pin of greater than 65, will overflow the calculation. Not a good thing.

We don't want to discourage the use of integer math. Points should be given for not using float. 1023*500 overflows an int. You need to use long arithmetic, for example, 500L * temp. If the compiler complains that the result won't fit in an int (temp), you can cast it to an int in this case, because you know mathematically that it can't overflow.

How is the servo powered?

Straight from arduino! ;) VCC to 5V, GND to GND and Signal to D9 pin.

We don't want to discourage the use of integer math. Points should be given for not using float. 1023*500 overflows an int. You need to use long arithmetic, for example, 500L * temp. If the compiler complains that the result won't fit in an int (temp), you can cast it to an int in this case, because you know mathematically that it can't overflow.

Every time same mistakes. >:( Every time I forgot to use float and other data types. Every time I start with int.

Okey, I must change my code this evening and I must try servo powering with power supply. I will report my accomplishments!

Thanks !

heninsh:
Every time I forgot to use float and other data types. Every time I start with int.

Actually, I was advising you to avoid floats and use ints instead. Just 32 bit ones, not 16 bit ones.

Straight from arduino!

WRONG! The Arduino can not provide enough current to power a servo.

So, I update my code from int temp to float temp. And now I am using power supply to power up servo.

#include <Servo.h>

Servo myservo;  // create servo object to control a servo

int tempPin = 0;  // analog pin used to connect the LM35
float temp;    // variable to read the value from the analog pin
int pos; // servo possition

const unsigned long printInterval = 2000; // set print interval 2 sec
const unsigned long readInterval = 1000; // set read interval 1 sec

unsigned long printTimer = millis();
unsigned long readTimer = millis();

char myChar = ‘°’; // crate char °

void setup()
{
 myservo.attach(9);  // attaches the servo on pin 9 to the servo object

Serial.begin(9600); // creat serial communication with 9600 baud rate
}

void loop()
{
 temp = analogRead(tempPin); // read values from analog pin A0 (LM35 signal pin)
 temp = (500 * temp) / 1023;  // calculate LM35 temperature in celsius

if ((millis() - readTimer) >= readInterval) {

if (temp >= 28) { // if temp >= 28 degrees then turn servo 90°
     pos = 90;
     myservo.write(pos); // servo write pos
   } else if (temp <= 27) { // if temp <= 27 degrees then turn servo back to 0°
     pos = 0;
     myservo.write(pos); // servo write pos
   }
   readTimer = millis();
 }

if ((millis() - printTimer) >= printInterval) { // after 2 sec print temp and servo value/state
   Serial.print("Temperatura = "); // pint Temperatura =
   Serial.print(temp, 1); // print temp value in celsius
   Serial.print(myChar); // print char °
   Serial.println(“C”); //print C
   Serial.print("Servo = "); // print Servo =
   Serial.print(pos); // print servo pos
   Serial.println(myChar); // print char ° */
   printTimer = millis();

}
}





But the same problem ! Every time when I open serial monitor, servo turns 90 degrees and back. I change setups to 45, 30, 15 degrees, but servo turns 90 degrees. 45, 30, 15 degrees turns when temp is >= 28 degrees. 

If I erase part of code 


if ((millis() - readTimer) >= readInterval) {

if (temp >= 28) { // if temp >= 28 degrees then turn servo 90°
     pos = 90;
     myservo.write(pos); // servo write pos
   } else if (temp <= 27) { // if temp <= 27 degrees then turn servo back to 0°
     pos = 0;
     myservo.write(pos); // servo write pos
   }
   readTimer = millis();
 }



then servo turns 90 degrees and stay at 90 degrees position. WHY?

UPDATE !!!

So, I solve it. I add delay(1000); in void setup() and all works fine !

My final code:

#include <Servo.h>

Servo myservo;  // create servo object to control a servo

int tempPin = 0;  // analog pin used to connect the LM35
float temp;    // variable to read the value from the analog pin
int pos; // servo possition

const unsigned long printInterval = 2000; // set print interval 2 sec
const unsigned long readInterval = 1000; // set read interval 1 sec

unsigned long printTimer = millis();
unsigned long readTimer = millis();

char myChar = '°'; // crate char °

void setup()
{
  delay(1000); // to kill 90 degrees turn

  myservo.attach(9);  // attaches the servo on pin 9 to the servo object

  Serial.begin(9600); // creat serial communication with 9600 baud rate

}

void loop()
{
  temp = analogRead(tempPin); // read values from analog pin A0 (LM35 signal pin)
  temp = (500 * temp) / 1023;  // calculate LM35 temperature in celsius

  if ((millis() - readTimer) >= readInterval) {

    if (temp >= 28) { // if temp >= 28 degrees then turn servo 90°
      pos = 90;
      myservo.write(pos); // servo write pos
    } else if (temp <= 27) { // if temp <= 27 degrees then turn servo back to 3°
      pos = 3;
      myservo.write(pos); // servo write pos
    }
    readTimer = millis();
  }

  if ((millis() - printTimer) >= printInterval) { // after 2 sec print temp and servo value/state
    Serial.print("Temperatura = "); // pint Temperatura =
    Serial.print(temp, 1); // print temp value in celsius
    Serial.print(myChar); // print char °
    Serial.println("C"); //print C
    Serial.print("Servo = "); // print Servo =
    if (pos == 90) {
      Serial.print("OPEN");
    } else {
      Serial.print("CLOSE");
    }
    Serial.println(myChar); // print char ° */
    printTimer = millis();

  }
}