Go Down

Topic: temp lcd project :S please help (Read 834 times) previous topic - next topic

supermotolew

hello all ! newbie help sorry if this is in the wrong section please move if so .
so im trying to make an accurete digital tempreture sensor
i have a arduino uno  and DS18B20 sensor output connected to digital 2 i can get the following sketch working correctly in serial window my question is i also have a serial lcd i would like to display this data with the degrees c symbol in my lcd  .
my lcd is a ywrobot 1602 serial lcd module connected as follows SDA to analog 4, SCL to analog 5 ,
i am using the following 2 sketches at the moment. i can get both working independently . i guess i want to combine them ?


temp part

#include <OneWire.h>

int DS18S20_Pin = 2; //DS18S20 Signal pin on digital 2

//Temperature chip i/o
OneWire ds(DS18S20_Pin);  // on digital pin 2

void setup(void) {
 Serial.begin(9600);
}

void loop(void) {
 float temperature = getTemp();
 Serial.println(temperature);
 
 delay(100); //just here to slow down the output so it is easier to read
 
}


float getTemp(){
 //returns the temperature from one DS18S20 in DEG Celsius

 byte data[12];
 byte addr[8];

 if ( !ds.search(addr)) {
     //no more sensors on chain, reset search
     ds.reset_search();
     return -1000;
 }

 if ( OneWire::crc8( addr, 7) != addr[7]) {
     Serial.println("CRC is not valid!");
     return -1000;
 }

 if ( addr[0] != 0x10 && addr[0] != 0x28) {
     Serial.print("Device is not recognized");
     return -1000;
 }

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

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

 
 for (int i = 0; i < 9; i++) { // we need 9 bytes
   data = ds.read();
 }
 
 ds.reset_search();
 
 byte MSB = data[1];
 byte LSB = data[0];

 float tempRead = ((MSB << 8) | LSB); //using two's compliment
 float TemperatureSum = tempRead / 16;
 
 return TemperatureSum;
 
}



--------------------------------lcd sketch example----------------------------------------------


#include <Wire.h>
#include <LiquidCrystal_I2C.h>

/* Initialise the LiquidCrystal library. The default address is 0x27 and this is a 16x2 line display */
LiquidCrystal_I2C lcd(0x27,16,2);
void setup()
{
 /* Initialise the LCD */
 lcd.init();
 lcd.init();
}

/* Main program loop */
void loop()
{
 /* Make sure the backlight is turned on */
 lcd.backlight();

 /* Output the test message to the LCD */
 lcd.setCursor(0,0);   lcd.print("HOBBY COMPONENTS");
 lcd.setCursor(0,1);   lcd.print("**HELLO WORLD**");
 
 /* Do nothing */
 while(1);
}

NickPyner

#1
Dec 28, 2012, 12:17 am Last Edit: Dec 28, 2012, 01:28 am by NickPyner Reason: 1
The sketches are made up of four parts

preamble
setup
loop
subroutines

It is just a matter of combining the sections - "interleaving". Yours don't have any subroutines, but they will eventually. You cvn get up some pretty comprehensive programmes this way - with nearly every line written by somebody else.

I think you should change the delay to 1000

As for the deg. C code, you can get it into the sketch by using alt+167, like this ยบ ! Unfotunately, all that stuff comes out as junk on the LCD. I assume this is because the standard library does not cover that sort of ASCII command. You can be sure somebody has fixed this but I haven't pursued this. I think it is better, and simpler, to use a more graphics-oriented display like the Nokia 5110.

Try this code

#include <OneWire.h>

int DS18S20_Pin = 2; //DS18S20 Signal pin on digital 2

//Temperature chip i/o
OneWire ds(DS18S20_Pin);  // on digital pin 2

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

/* Initialise the LiquidCrystal library. The default address is 0x27 and this is a 16x2 line display */
LiquidCrystal_I2C lcd(0x27,16,2);

void setup(void) {
 Serial.begin(9600);

 /* Initialise the LCD */
 lcd.init();
 lcd.init();
}

void loop(void) {
 float temperature = getTemp();
 Serial.println(temperature);

/* Make sure the backlight is turned on */
 lcd.backlight();

 /* Output the test message to the LCD */
 lcd.setCursor(0,0);   lcd.print("HOBBY COMPONENTS");
 lcd.setCursor(0,1);   lcd.print("**HELLO WORLD**");
 
 /* Do nothing */
 while(1);

 
 delay(100); //just here to slow down the output so it is easier to read
 

}


float getTemp(){
 //returns the temperature from one DS18S20 in DEG Celsius

 byte data[12];
 byte addr[8];

 if ( !ds.search(addr)) {
     //no more sensors on chain, reset search
     ds.reset_search();
     return -1000;
 }

 if ( OneWire::crc8( addr, 7) != addr[7]) {
     Serial.println("CRC is not valid!");
     return -1000;
 }

 if ( addr[0] != 0x10 && addr[0] != 0x28) {
     Serial.print("Device is not recognized");
     return -1000;
 }

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

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

 
 for (int i = 0; i < 9; i++) { // we need 9 bytes
   data = ds.read();
 }
 
 ds.reset_search();
 
 byte MSB = data[1];
 byte LSB = data[0];

 float tempRead = ((MSB << smiley-cool | LSB); //using two's compliment
 float TemperatureSum = tempRead / 16;
 
 return TemperatureSum;
 
}



supermotolew

thanks nick your help is greatly appreciated

im trying to verify the sketch but i have a problem right at the end with the line

    data = ds.read();

saying incompatibly types in assignment
any thoughts on this ?

am i even going about the best way to display temp on an lcd ?
again thank you for your help im learning more every day honest !

NickPyner

Hummm. I'm afraid I just shoved your stuff together without seriously looking at it. Now that I have, at first I didn't understand it, but I believe I now realise what is going on.

I believe there are three ways to use the DS18B20

1. The sheepdog method which fails to take advantage of the device, as it

2. The device-trawling method, which defies a lot of logic

3. The way God and Dallas intended.

I think yours is a variant of the first, and I guess it is quite legitimate in that you only use one device. I believe the third is a better way to go, simpler even. Here is working code similar to yours that I got into via a comedy of errors. Strip out the irrelevant stuff and compare with what you have.

Code: [Select]
/*
Reading two DS18B20s pins 14&15
display to monitor
display to LCD with pin D04 moved to pin 16 (A2)
Code uses Arduino LCD, sheepdog temp reader, SD stuff from Mellis & Igoe
*/

#define tture1 14//no ; here
#define tture2 15//no ; here

// include the library codes:
#include <LiquidCrystal.h>
#include <SD.h>

File myFile;

// initialize the library with the numbers of MY interface pins
LiquidCrystal lcd(8,9,16,5,6,7);

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

void setup() {
   //For each tture sensor: Do a pinMode and a digitalWrite
   pinMode(tture1, INPUT);
   pinMode(tture2, INPUT);

   digitalWrite(tture1, LOW);//Disable internal pull-up.
   digitalWrite(tture2, LOW);

   Serial.begin(9600);
   delay(300);//Wait for newly restarted system to stabilize
   Serial.print("Temperature measurement, two sensors:\n\n");

 // set up the LCD's number of columns and rows:
 lcd.begin(16, 2);
 lcd.clear();
 // Print a message to the LCD.
 lcd.print("temp   in   out");    
 
 Serial.print("Initializing SD card...");

  pinMode(10, OUTPUT);
 
 if (!SD.begin(4)) {
   Serial.println("initialization failed!");
   return;
 }
 Serial.println("initialization done.");
 
 // open the file. note that only one file can be open at a time,
 // so you have to close this one before opening another.
 myFile = SD.open("test.txt", FILE_WRITE);//+++++++++++++++++++ OPEN
 
 // if the file opened okay, write to it:
 if (myFile) {
   Serial.print("Writing to test.txt...");
   myFile.println("testing! Did you forget the date?");
   myFile.close();//++++++++++++++++++++++++++++++++++++++++++++ CLOSE

   Serial.println("done.");
 } else {
   // if the file didn't open, print an error:
   Serial.println("error opening test.txt");
 }
 
}

void loop(){

// set the LCD cursor to column 4, line 1
 // (note: line 1 is the second row, since counting begins with 0):
 lcd.setCursor(4, 1);
 readTture(tture1);//N.B.: Values passed back in globals
 printTture();//N.B.: Takes values from globals. Also...
    //no newline part of printTture;

 delay(120);// Delay... must not be too short.
 
 // set LCD cursor for second temp
 lcd.setCursor(11, 1);
 readTture(tture2);//Now read and report 2nd tture.
 printTture();
 delay(200);// Delay... must not be too short.
 Serial.print("\n");//Start new line
 
      myFile = SD.open("test.txt", FILE_WRITE);//+++++++++++++++++++++++++OPEN
      myFile.println(",   ");
   myFile.close();//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>CLOSE
 delay(880);
}



//Everything below here... just copy it into your program "as is".
//You are only likely to need to use readTture(pin) and printTture()
//   directly. Others are subordinate to those.
//These routine access the following global variables...
//   int HighByte, LowByte, TReading, SignBit, Tc_100, Whole, Fract;

void OneWireReset(int Pin) // reset.  Should improve to act as a presence pulse
{
    digitalWrite(Pin, LOW);
    pinMode(Pin, OUTPUT); // bring low for 500 us
    delayMicroseconds(500);
    pinMode(Pin, INPUT);
    delayMicroseconds(500);
}
//end OneWireReset

void OneWireOutByte(int Pin, byte d) // output byte d (least sig bit first).
{
  byte n;

  for(n=8; n!=0; n--)
  {
     if ((d & 0x01) == 1)  // test least sig bit
     {
        digitalWrite(Pin, LOW);
        pinMode(Pin, OUTPUT);
        delayMicroseconds(5);
        pinMode(Pin, INPUT);
        delayMicroseconds(60);
     }
     else
     {
        digitalWrite(Pin, LOW);
        pinMode(Pin, OUTPUT);
        delayMicroseconds(60);
        pinMode(Pin, INPUT);
     }
     d=d>>1; // now the next bit is in the least sig bit position.
  }
}//end OneWireOutByte

byte OneWireInByte(int Pin) // read byte, least sig byte first
{
   byte d, n, b;

   for (n=0; n<8; n++)
   {
       digitalWrite(Pin, LOW);
       pinMode(Pin, OUTPUT);
       delayMicroseconds(5);
       pinMode(Pin, INPUT);
       delayMicroseconds(5);
       b = digitalRead(Pin);
       delayMicroseconds(50);
       d = (d >> 1) | (b<<7); // shift d to right and insert b in most sig bit position
   }
   return(d);
}//end OneWireInByte

void readTture(byte Pin){
//Pass WHICH pin you want to read in "Pin"
//Returns values in... (See global declarations)
 OneWireReset(Pin);
 OneWireOutByte(Pin, 0xcc);
 OneWireOutByte(Pin, 0x44); // perform temperature conversion, strong pullup for one sec

 OneWireReset(Pin);
 OneWireOutByte(Pin, 0xcc);
 OneWireOutByte(Pin, 0xbe);

 LowByte = OneWireInByte(Pin);
 HighByte = OneWireInByte(Pin);
 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;
};//end readTture

void printTture(){//Uses values from global variables.
//See global declarations.
//N.B.: No new line inside printTture
     myFile = SD.open("test.txt", FILE_WRITE); //+++++++++++++OPEN
if (SignBit) // If it's negative
   {
    Serial.print("-");
    lcd.print("-");

    myFile.print("-");
   };
 Serial.print(Whole);
 Serial.print(".");
 lcd.print(Whole);
 lcd.print(".");
 myFile.print(Whole);
 myFile.print(".");
 if (Fract < 10)
   {
    Serial.print("0");
    lcd.print("0");
    myFile.print("0");
   };
 Serial.print(Fract);
 lcd.print(Fract);
 myFile.print(Fract);
   Serial.print("       ");
   myFile.print(",    ");
 myFile.close();//++++++++++++++++++++++++ CLOSE
};//end printTture


I can't fit the third method in one post, but an example is here

http://community.cosm.com/node/1557



 



Go Up