Need some help with my code ,please

Ok, i am using a DS18B20 temp sensor with a servo for greenhouse thermostat use,

When temperature reach a certain degree Celcius it moves the servo to a specified position,It opens a led light at final position (hotter)

My problem is that sometimes my temp sensor spikes and gives values of like 500 degrees, or -49 degrees, making the servo move to various positions.

Is that a problem with my connections? Or with my code?

If someone could help me would be greatly appreciated,

Below is the code, and a connection diagram for my temp sensor:

#include <Servo.h>
#include <OneWire.h>

int DS18S20_Pin = 3; // Set temperature sensor in pin 0
int thresholdcold = 20; // Threshold for cold temperature
int thresholdhot = 22; // Threshold for hot temperature
int thresholdnormal =21; // Threshold for normal temperature
int servocold = 175; // Angle in which servo will go to
int servohot = 0; // Angle in which servo will go to
int servonormal = 80; // Angle in which servo will go to
int previousPosition = 176;
Servo servo1;
int ServoDelay = 30; // Servo delay
OneWire ds(DS18S20_Pin); //Library for Temp sensor

int led = 13;

void setup(void)
{
Serial.begin(9600); // Begin communicating with computer

servo1.attach(9); // Attaches servo to specified pin

pinMode(13, OUTPUT);

}

void loop(void) {

int HighByte, LowByte, TReading, SignBit, Tc_100, Whole, Fract;

byte i;
byte present = 0;
byte data[12];
byte addr[8];

if ( !ds.search(addr)) {
// Serial.print("No more addresses.\n");
ds.reset_search();
return;
}

//Serial.print("R=");
for( i = 0; i < 8; i++) {
//Serial.print(addr*, HEX);*

  • Serial.print(" ");*
  • }*
  • if ( OneWire::crc8( addr, 7) != addr[7]) {*
  • Serial.print("CRC is not valid!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");*
  • present = ds.reset();*
  • return;*
  • }*
  • ds.reset();*
  • ds.select(addr);*
  • ds.write(0x44,1); // start conversion, with parasite power on at the end*
  • delay(1000); // maybe 750ms is enough, maybe not*
  • // we might do a ds.depower() here, but the reset will take care of it.*
  • present = ds.reset();*
  • ds.select(addr); *
  • ds.write(0xBE); // Read Scratchpad*
  • //Serial.print("P=");*
  • //Serial.print(present,HEX);*
  • Serial.print(" ");*
  • for ( i = 0; i < 9; i++) { // we need 9 bytes*
    _ data = ds.read();_
    _ //Serial.print(data*, HEX);
    Serial.print(" ");
    }
    //Serial.print(" CRC=");
    //Serial.print( OneWire::crc8( data, 8), HEX);
    Serial.println();*_

* LowByte = data[0];*
* HighByte = data[1];*
* TReading = (HighByte << 8) + LowByte;*
* SignBit = TReading & 0x8000; // test most sig bit*
* if (SignBit) // negative*
* {*
* TReading = (TReading ^ 0xffff) + 1; // 2's comp*
* }*
Tc_100 = (6 * TReading) + TReading / 4; // multiply by (100 * 0.0625) or 6.25
* Whole = Tc_100 / 100; // separate off the whole and fractional portions*
* Fract = Tc_100 % 100;
_ if (SignBit) // If its negative*
* {
Serial.print("-");
}
Serial.print(Whole);
Serial.print(".");
if (Fract < 10)
{
Serial.print("0");
}
Serial.print(Fract);
Serial.print("\n");*_

* if(Whole <= thresholdcold) // If temperature is above the threshold, activate sequence*
* {*

* if (servocold != previousPosition){*

* for(previousPosition != 0; previousPosition < servocold; previousPosition += 1) // goes from 0 degrees to 180 degrees*
* { // in steps of 1 degree*
* servo1.write(previousPosition); // tell servo to go to position in variable 'pos'*
* delay(ServoDelay); // waits 15ms for the servo to reach the position*
* }*

* servo1.write(servocold);*
* previousPosition = servocold;*
* }*
* }*

* else if(Whole >= thresholdhot) // If temperature is above the threshold, activate sequence*
* {*

* if (servohot != previousPosition){*

* for(previousPosition != thresholdhot; previousPosition -= 1;) // goes from 0 degrees to 180 degrees*
* { // in steps of 1 degree*
* servo1.write(previousPosition); // tell servo to go to position in variable 'pos'*
* delay(ServoDelay); // waits 15ms for the servo to reach the position*
* }*
* servo1.write(servohot);*
* previousPosition = servohot;*
* }*
* digitalWrite(led, HIGH);*
* }*

* else if(Whole >= thresholdnormal) // If Fract is above the threshold, activate sequence*
* {*

* if (servonormal != previousPosition){*

* for(previousPosition != servonormal;previousPosition > servonormal; previousPosition -= 1) // goes from 0 degrees to 180 degrees*
* { // in steps of 1 degree*
* servo1.write(previousPosition); // tell servo to go to position in variable 'pos'*
* delay(ServoDelay); // waits 15ms for the servo to reach the position*
* }*

* for(previousPosition != servonormal;previousPosition < servonormal; previousPosition += 1) // goes from 0 degrees to 180 degrees*
* { // in steps of 1 degree*
* servo1.write(previousPosition); // tell servo to go to position in variable 'pos'*
* delay(ServoDelay); // waits 15ms for the servo to reach the position*
* }*
* servo1.write(servonormal);*
* previousPosition = servonormal;*
* digitalWrite(led, LOW);*
* }*

* }*
}

Look carefully at the code as posted above and compare it with the code in the IDE. Do you notice any italics or smileys in the IDE ?

Now edit your post to add code tags as requested in the 2 sticky threads above. This will prevent the code being mangled by the forum software.

In several places you have:

for(previousPosition != 0; previousPosition < servocold; previousPosition += 1)  // goes from 0 degrees to 180 degrees

A for loop has 3 expressions:

  1. the starting condition of the variable that controls the loop
  2. a (relational) test that determines if another iteration through the loop is needed
  3. usually a change in the variable that controls the loop.
    Your expression 1 looks suspect, since it is a relational test, not what is usually an assignment statement. Given your comment, it probably needs to look something like:
int degrees;

for(degrees = 0; degrees < servocold; degrees++)  // goes from 0 degrees to 180 degrees

This code marches through from 0 up to servocold 1 degree at a time.

Also, when you post code here, place your cursor in the IDE source code window, press Ctrl-T, which formats it for you. Then press Ctrl-A to copy all of your code. Then come to this forum, start your post, hit the pound sing (#) and copy your code between the two code tags. That makes it easier for us.

I am sorry for my formatting , it is the first time i post on those forums,

However my for loops are working as intended, (as it seems..)

My problem is still the spikes coming from the readings of my temp sensor :confused:

On my serial port monitor i get something like this :

19.12
                  
19.12
                  
-124.0-24
                  
19.12
                  
19.12
                  
19.12
                  
19.12
                  
19.12

I reformatted the code so its easier to read,

#include <Servo.h>
#include <OneWire.h>

int DS18S20_Pin = 3;        // Set temperature sensor in pin 0
int thresholdcold = 20;     // Threshold for cold temperature
int thresholdhot = 22;      // Threshold for hot temperature
int thresholdnormal =21;   // Threshold for normal temperature
int servocold = 175;        // Angle in which servo will go to
int servohot = 0;           // Angle in which servo will go to
int servonormal = 80;       // Angle in which servo will go to
int previousPosition = 176;
Servo servo1;
int ServoDelay = 30;        // Servo delay
OneWire ds(DS18S20_Pin);    //Library for Temp sensor



int led = 13;


void setup(void)
{
  Serial.begin(9600); // Begin communicating with computer
 
  servo1.attach(9); // Attaches servo to specified pin
  
  pinMode(13, OUTPUT);
 
}

void loop(void) {
  
  int HighByte, LowByte, TReading, SignBit, Tc_100, Whole, Fract;
  
  byte i;
  byte present = 0;
  byte data[12];
  byte addr[8];

  if ( !ds.search(addr)) {
     // Serial.print("No more addresses.\n");
      ds.reset_search();
      return;
  }

  //Serial.print("R=");
  for( i = 0; i < 8; i++) {
    //Serial.print(addr[i], HEX);
    Serial.print(" ");
  }

  if ( OneWire::crc8( addr, 7) != addr[7]) {
      Serial.print("CRC is not valid!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
      present = ds.reset();
      return;
  }


  ds.reset();
  ds.select(addr);
  ds.write(0x44,1);         // start conversion, with parasite power on at the end

  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.

  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad

  //Serial.print("P=");
  //Serial.print(present,HEX);
  Serial.print(" ");
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
    //Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  //Serial.print(" CRC=");
  //Serial.print( OneWire::crc8( data, 8), HEX);
  Serial.println();
  
  LowByte = data[0];
  HighByte = data[1];
  TReading = (HighByte << 8) + LowByte;
  SignBit = TReading & 0x8000;  // test most sig bit
  if (SignBit) // negative
  {
    TReading = (TReading ^ 0xffff) + 1; // 2's comp
  }
  Tc_100 = (6 * TReading) + TReading / 4;    // multiply by (100 * 0.0625) or 6.25

  Whole = Tc_100 / 100;  // separate off the whole and fractional portions
  Fract = Tc_100 % 100;


  if (SignBit) // If its negative
  {
     Serial.print("-");
  }
  Serial.print(Whole);
  Serial.print(".");
  if (Fract < 10)
  {
     Serial.print("0");
  }
  Serial.print(Fract);

  Serial.print("\n");
  
  
  if(Whole <= thresholdcold) // If temperature is above the threshold, activate sequence
  {
   
	if (servocold != previousPosition){
  
   for(previousPosition != 0; previousPosition < servocold; previousPosition += 1)  // goes from 0 degrees to 180 degrees 
  {                                  // in steps of 1 degree 
    servo1.write(previousPosition);              // tell servo to go to position in variable 'pos' 
    delay(ServoDelay);                       // waits 15ms for the servo to reach the position 
  } 
  
        	servo1.write(servocold);
		previousPosition = servocold;
		}
  }
 
  else if(Whole >= thresholdhot) // If temperature is above the threshold, activate sequence
  {
  
		if (servohot != previousPosition){
  
  for(previousPosition != thresholdhot; previousPosition -= 1;)  // goes from 0 degrees to 180 degrees 
  {                                                                                     // in steps of 1 degree 
    servo1.write(previousPosition);              // tell servo to go to position in variable 'pos' 
    delay(ServoDelay);                       // waits 15ms for the servo to reach the position 
  } 
	    servo1.write(servohot);
		previousPosition = servohot;


		}

      digitalWrite(led, HIGH);
  }
 
 
 
 
 
  else if(Whole >= thresholdnormal) // If Fract is above the threshold, activate sequence
  {
   
	if (servonormal != previousPosition){
  
  for(previousPosition != servonormal;previousPosition > servonormal; previousPosition -= 1)  // goes from 0 degrees to 180 degrees 
  {                                                                                     // in steps of 1 degree 
    servo1.write(previousPosition);              // tell servo to go to position in variable 'pos' 
    delay(ServoDelay);                       // waits 15ms for the servo to reach the position 
  } 
  
  for(previousPosition != servonormal;previousPosition < servonormal; previousPosition += 1)  // goes from 0 degrees to 180 degrees 
  {                                                                                     // in steps of 1 degree 
    servo1.write(previousPosition);              // tell servo to go to position in variable 'pos' 
    delay(ServoDelay);                       // waits 15ms for the servo to reach the position 
  } 
	    servo1.write(servonormal);

		previousPosition = servonormal;

                digitalWrite(led, LOW);
		}

      
  }
}

I still think this statement:

for (previousPosition != 0; previousPosition < servocold; previousPosition += 1)

is suspect, because the expression:

previousPosition != 0

is either logic True (1), or false (0). You may think it's working as you want it to, but I serious doubt it. The only reason it works is because the logic conditions start the loop either with 0 or 1, depending on the logic state. There is nothing in the ANSI standard for C that requires logic True to be 1 and logic False to be 0. Indeed, some early compilers used -1 for True and still others used -1 for False. Also, as you've written the loop, it tests a "position" against "servocold", which is either strange or a poor choice of variable names. Finally, just because serendipity makes a program work doesn't mean it's properly coded. Such things come back to bite you later on.

So if i change my "for" loop , will it correct the temperature spikes? I dont get it... :confused:

I am sorry im kinda noob to programming

There's no need to apologize...all of us have been there. We're just trying to understand what you're trying to do and point you in the right direction.

It appears that, depending on the reading of previousPosition, the for loops adjust by the 3rd expression in the for loop, either to raise something (temperature??) or lower it:

previousPosition += 1

or

previousPosition -= 1

In both loops, the comparison is made to servonormal. If that's the case, why not use:

while (previousPosition != seronormal) {
   // get the data here
   if (previousPosition < servonormal)
      previousPosition++;      // same as previousPosition += 1
   else 
      previousPosition--;      // same as previousPosition -= 1
}

I think this is what you are trying to do.

With the for loops i am trying to move the servo, from centered position, either clockwise or anticlockwise

Although your code makes much much much more sense, i dont think it adresses the issue of the temperature spikes :confused:

Theomv:
Although your code makes much much much more sense, i dont think it adresses the issue of the temperature spikes :confused:

I just think he's trying to point out a subtle bug in your code.

Personally I'd make a copy of your code and rip out all the servo stuff and focus on the temperature code. Add some extra serial.print's for the intermediate calculations so you can focus on what's going wrong.

Once you've got rock solid temperature readings you then add back in the servo code.

Just a thought.

Regards,

Brad
KF7FER

int thresholdnormal =21;   // Threshold for normal temperature

Threshold? How can the normal temperature be a threshold? The upper and lower limits, yes. The normal temperature, no.

Ok, guys i resolved it , it seems there was something wrong with my temperature code. I used this code instead and for 1 day of continuous use , it seems that it didnt spike. This is the code i used:

#include <OneWire.h>
#include <DallasTemperature.h>
 float Temp;
 int led = 13;


// Data wire is plugged into pin 2 on the Arduino
#define ONE_WIRE_BUS 3

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

void setup(void)
{
  
 
  // start serial port
  Serial.begin(9600);
  Serial.println("Dallas Temperature IC Control Library Demo");
pinMode(13, OUTPUT);


  // Start up the library
  sensors.begin(); // IC Default 9 bit. If you have troubles consider upping it 12. Ups the delay giving the IC more time to process the temperature measurement
}


void loop(void)
{ 
  // call sensors.requestTemperatures() to issue a global temperature 
  // request to all devices on the bus
  Serial.print("Requesting temperatures...");
  sensors.requestTemperatures(); // Send the command to get temperatures
  Serial.println("DONE");
  
  Serial.print("Temperature for Device 1 is: ");
  Serial.println(sensors.getTempCByIndex(1)); // Why "byIndex"? You can have more than one IC on the same bus. 0 refers to the first IC on the wire
  
  Serial.print("Temperature for Device 2 is: ");
  Serial.println(sensors.getTempCByIndex(0));
  
  delay(1000);
  

  Temp=sensors.getTempCByIndex(0);
  
  if (Temp > 23 ){
    
    digitalWrite(led, HIGH);
    
    Serial.print ("ERROR!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
  }
  
}

I used digitalWrite(led, HIGH); in order to visually see if there was a spike.