Go Down

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

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;
 
}



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
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy