Monday, February 6, 2012

Dallas ds18b20 temperature sensor and arduino

Code piece for arduino integrated with dallas ds18b20 temperature sensor

** Remark that the code piece must be integrated into your own application to work properly, it is a draft !
Dallas Ds18b20

How To connect the dallas ds18b20 to arduino digital pin (this is not one wire connecting)



This picture show a DFRduino (Arduino Mega 1280 compatibel) with 2,8" LCD touch display. This unit is intend to be used in the project: EVduino-MS. EVduino-MS is a Electric Vehicle Monitoring and datalogger System will be used in my kewet 2 EV.

Dallas ds18b20 Links and ressources:
caminoi
avrfreaks
c code package ds18b20

Arduino Test software 9 february 2012,  Demo video
In this test version, dallas ds18b20 works well


Grab the demo Code pieces / schetch below demo movie









// EVduino-MS-08b first playground version
//
// Project start date: 22 January 2012
// Version of the EVduino-MS: 0,8beta
// Author: Michael Pedersen
// Project Home: http://mynerdstuff.blogspot.com/2012/01/arduino-based-electric-vehicle.html
//
// This 0,8 beta Version is intend to bed used in a KEWET 2 electric vehicle with 4 lead Acid batteries
// Link to 0.8beta home: http://mynerdstuff.blogspot.com/2012/02/evduino-ms-08beta-code.html

#include <f12x12.h>
#include <TFT_Font.h>
#include <TFT_Graphics.h>
#include <Touchpanel.h>
#include <util/delay.h>
#include <stdlib.h>
#include "f15x22.h"
#include <string.h>


//Dallas ds18b20temperature sensor define
#define TEMP_PIN  11 //pwm11 , pwm 13 did not work in my DFRduino, don't know why, might work on other megaduino boards
#define RED_LED_PIN  12 //pwm12
void getCurrentTemp(char *temp);
void enginetemperature();

#define TP_STABLE_COUNT 1
Graphics tft;

TFT_Font font;
touchpanel tp;

void colormap();
void fontmap();
void bitmap();
uint8_t mount_sd();
uint8_t open_root_dir();
uint8_t show_bitmap();
void calibrate();
void tp_calibrate();
//void batteriesvoltage(float *voltage);

typedef struct menu_item{
  uint16_t sx;
  uint16_t sy;
  uint16_t ex;
  uint16_t ey;
  char *str;
  void (*func)(void);
}
MENUITEM;

//This is the main menu placement
#define MENU_START_X 40
#define MENU_START_Y 60
#define MENU_WIDTH 120
#define MENU_HEIGHT 40
#define MENU_GAP 20

// This is the main menu buttons, black with white text. Turns green when pressed
#define MENU_FONT_COLOR WHITE
#define MENU_NORMAL_COLOR BLACK
#define MENU_HIGHLIGHT_COLOR GREEN

MENUITEM menu[4];
int current_menu_no = -1;
float volt1;

void setup()
{

  //initialize DS18B20 datapin
  digitalWrite(TEMP_PIN, LOW);
  pinMode(TEMP_PIN, INPUT);

  pinMode(RED_LED_PIN, OUTPUT);
  digitalWrite(RED_LED_PIN, HIGH);

  //digitalWrite(11, LOW);
  //pinMode(11, INPUT);


  volt1 = 12,34;
  tft.initialize(LCD_HORIZONTAL);
  tft.ClearScreen(WHITE);
  font.set_Font(f12x12);
  tp.init();
  tp.get_matrix();

  //setup menu
  menu[0].sx = MENU_START_X;
  menu[0].sy = MENU_START_Y;
  menu[0].ex = MENU_START_X + MENU_WIDTH;
  menu[0].ey = MENU_START_Y + MENU_HEIGHT;
  menu[0].str = PSTR("Engine Current");
  menu[0].func = enginecurrent;

  menu[1].sx = MENU_START_X;
  menu[1].sy = MENU_START_Y + MENU_HEIGHT + MENU_GAP;
  menu[1].ex = MENU_START_X + MENU_WIDTH;
  menu[1].ey = MENU_START_Y + 2*MENU_HEIGHT + MENU_GAP;
  menu[1].str = PSTR("Batteries");
  menu[1].func = batteriesvoltage;

  menu[2].sx = MENU_START_X + MENU_WIDTH +MENU_GAP;
  menu[2].sy = MENU_START_Y;
  menu[2].ex = MENU_START_X + 2*MENU_WIDTH+MENU_GAP;
  menu[2].ey = MENU_START_Y + MENU_HEIGHT;
  menu[2].str = PSTR("Engine Temp");
  menu[2].func = enginetemperature;

  menu[3].sx = MENU_START_X + MENU_WIDTH +MENU_GAP;
  menu[3].sy = MENU_START_Y + MENU_HEIGHT + MENU_GAP;
  menu[3].ex = MENU_START_X + 2*MENU_WIDTH+MENU_GAP;
  menu[3].ey = MENU_START_Y + 2*MENU_HEIGHT + MENU_GAP;
  menu[3].str = PSTR("TP CALIBRATION");
  menu[3].func = calibrate;


}

void text_box_P(uint16_t x1,uint16_t y1, uint16_t x2, uint16_t y2, uint16_t radius, char* str_P)
{
  tft.DrawRoundRect(x1,y1,x2,y2, radius, font.BK_color, 1);
  font.set_Cursor( (x1+x2-font.str_Width_P(str_P))>>1, (y1+y2-font.Font_Height)>>1 );
  font.putstr_P(str_P);
}

void init_menu()
{
  int i;
  font.set_Color(MENU_FONT_COLOR, MENU_NORMAL_COLOR,1);
  for(i=0; i<4; i++)
    text_box_P( menu[i].sx, menu[i].sy, menu[i].ex, menu[i].ey, 8, menu[i].str);

  current_menu_no = -1 ;
}




void text_box(uint16_t x1,uint16_t y1, uint16_t x2, uint16_t y2, uint16_t radius, char* str)
{
  tft.DrawRoundRect(x1,y1,x2,y2, radius, font.BK_color, 1);
  font.set_Cursor( (x1+x2-font.str_Width(str))>>1, (y1+y2-font.Font_Height)>>1 );
  font.putstr(str);
}


uint8_t get_stable_tp(POINT* tp)
{
  static POINT previous_tp;
  static uint8_t count=0;


  if(tp->x == 0 || tp->y == 0)
    return 0;

  if(tp->x == previous_tp.x && tp->y == previous_tp.y)
    count++;
  else{
    count = 0;
    previous_tp.x = tp->x;
    previous_tp.y = tp->y;
  }

  if(count>= TP_STABLE_COUNT){
    count = 0;
    return 1;
  }

  return 0;
}


char tp_inside_menu(POINT *tp)
{
  int i;
  for(i=0; i<4; i++){
    if( tp->x>= menu[i].sx && tp->y>= menu[i].sy &&
      tp->x <= menu[i].ex && tp->y <= menu[i].ey )

      return i;
  }
  return -1; // not inside any menu item

}


void loop()
{
  POINT *tp_dat;

  init_menu();
  while(1)
  {
    char cord[5];
    tp_dat = tp.read_lcd_point();

    if(get_stable_tp(tp_dat) )  // got a stable tp point
    {
      current_menu_no = tp_inside_menu(tp_dat);

      if(current_menu_no >=0 && current_menu_no<=4){
        font.set_Color(MENU_FONT_COLOR, MENU_HIGHLIGHT_COLOR,1); // draw current menu in highlight color
        text_box_P( menu[current_menu_no].sx, menu[current_menu_no].sy, menu[current_menu_no].ex, menu[current_menu_no].ey, 8, menu[current_menu_no].str);
        _delay_ms(50);
        (*(menu[current_menu_no].func))();

        init_menu();
      }
    }

    _delay_ms(5);
  }
}

void wait_for_OK()
{
  POINT *tp_dat;

  font.set_Color(MENU_FONT_COLOR, MENU_NORMAL_COLOR,1);

  text_box_P( 120, 20, 200, 50, 5, PSTR("OK"));

  while(1)
  {
    tp_dat = tp.read_lcd_point();

    if(get_stable_tp(tp_dat) )
    {
      if(tp_dat->x>=120 && tp_dat->y >=20&& tp_dat->x <=200 && tp_dat->y<=50)
      {
        tft.ClearScreen(WHITE);
        return;
      }
    }
    _delay_ms(5);
  }
}

uint8_t wait_for_input()
{
  POINT *tp_dat;

  font.set_Color(MENU_FONT_COLOR, MENU_NORMAL_COLOR,1);

  text_box_P( 120, 20, 180, 50, 5, PSTR("OK"));
  text_box_P( 200, 20, 280, 50, 5, PSTR("NEXT"));

  while(1)
  {
    tp_dat = tp.read_lcd_point();

    if(get_stable_tp(tp_dat) )
    {
      if(tp_dat->x>=120 && tp_dat->y >=20&& tp_dat->x <=180 && tp_dat->y<=50) return 1;
      else if (tp_dat->x>=200 && tp_dat->y >=20&& tp_dat->x <=280 && tp_dat->y<=50) return 0;
    }
    _delay_ms(5);
  }
}


void colormap()
{
  uint8_t i,j,k;
  // draw a clolormap
  uint16_t color;
  tft.ClearScreen(WHITE);

  // draw 512 (10x15) boxes with incremantal color
  for(i=0; i<8; i++){
    for(j=0; j<8; j++){
      for(k=0;k<8;k++){
        color = _RGB565(i<<5, j<<5, k<<5);
        tft.DrawRoundRect(i*40+(j/2)*10, k*15+ (j&0x1)*120,i*40+(j/2)*10 +9, k*15+ (j&0x1)*120 +14, 0, color,1);
      }
    }
  }
  wait_for_OK();
}


void fontmap()
{
  char i;
  uint8_t row=0;

  // draw font
  tft.ClearScreen(WHITE);

  tft.DrawRoundRect( 40, 70, 280, 230,  10, MENU_HIGHLIGHT_COLOR,1);

  font.set_Font(f15x22);
  font.set_Color(MENU_FONT_COLOR, MENU_NORMAL_COLOR,1);

  font.set_Cursor( 50, 80);

  for(i=font.Font_FirstChar; i<= font.Font_LastChar; i++)
  {
    if(font.CharWidth(i) !=0)
    {
      if( (font.CursorX + font.CharWidth(i)) > 270)
      {
        row++;
        font.set_Cursor(50, 80+ (row* font.Font_Height + 2));
      }

      font.putChar(i);
    }
  }
  font.set_Font(f12x12);
  wait_for_OK();
}


void bitmap()
{
  uint8_t res;
  char temp[10];
  tft.ClearScreen(WHITE);
#if defined(__AVR_ATmega328P__)||defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  res = mount_sd();
  if(res) {
    text_box_P( 80, 50, 250, 200, 15, PSTR("Cannot mount SDcard"));
 
 
    wait_for_OK();
  }
  else
  {
    if(open_root_dir()) return;
    while(1){
   
      res= show_bitmap();
      if(!res){
        if(wait_for_input()==1) {
          tft.ClearScreen(WHITE);
          break;  // ok button is pressed, break the loop
        }
      }
      else if(res==0x10)  // reopen root dir
      {
        if(open_root_dir()) return;
      }
    }
  }


#else
  text_box_P(80, 60, 250, 200, 15, PSTR("N/A in ATMEGA168"));
  wait_for_OK();
#endif

}

void enginetemperature()
{
  digitalWrite(RED_LED_PIN, LOW);

  //exampel place qwerty in the drawn RoundRect
  String sensorTypeTxt;
  String test;
  char i = 42;
  char sensorData[20] = "12,34 Volt";    

 // dallas ds18b20 variables test
  uint16_t plen, dat_p;
        char temp_string[10] = "1234";
     
       getCurrentTemp(sensorData); //go get dallas ds18b20 temperature
     
     

  sensorTypeTxt = "Engine Temp. is: ";
//sensorTypeTxt.concat(millis());
  sensorTypeTxt.concat(sensorData);
  uint8_t row=0;

  // draw font
  tft.ClearScreen(WHITE);

  tft.DrawRoundRect( 40, 70, 280, 130,  10, MENU_HIGHLIGHT_COLOR,1);

  font.set_Font(f15x22);
  font.set_Color(MENU_FONT_COLOR, MENU_NORMAL_COLOR,1);

  font.set_Cursor( 50, 80); //Place cursor at low/left of LCD

  for(i=0; i<43;i++) //loop until al chrs in sensorData is placed on the LCD display
  {
    font.putChar(sensorTypeTxt[i]); //place the sensorData variable, sensorData come from a sensor as voltage sensor, current sensor, temperature sensor

    if(font.CharWidth(i) !=0)
    {
      if( (font.CursorX + font.CharWidth(i)) > 270)
      {
        row++;
        font.set_Cursor(50, 80+ (row* font.Font_Height + 2));
      }    
    }
  }

  font.set_Font(f12x12); // set font to menu size
  wait_for_OK();
}


void enginecurrent()
{
  text_box_P( 80, 50, 250, 200, 15, PSTR("300A messhunt data:"));
   digitalWrite(RED_LED_PIN, LOW);
  wait_for_OK();
}


void batteriesvoltage()
{
  digitalWrite(RED_LED_PIN, HIGH);

  //exampel place qwerty in the drawn RoundRect
  String sensorTypeTxt;
  String test;
  char i = 42;
  char sensorData[20] = "12,34 Volt";    

 // dallas ds18b20 variables test
  uint16_t plen, dat_p;
        char temp_string[10] = "1234";
     
       getCurrentTemp(sensorData); //go get dallas ds18b20 temperature
     
     

  sensorTypeTxt = "Battery one: ";
//sensorTypeTxt.concat(millis());
  sensorTypeTxt.concat(sensorData);
  uint8_t row=0;

  // draw font
  tft.ClearScreen(WHITE);

  tft.DrawRoundRect( 40, 70, 280, 130,  10, MENU_HIGHLIGHT_COLOR,1);

  font.set_Font(f15x22);
  font.set_Color(MENU_FONT_COLOR, MENU_NORMAL_COLOR,1);

  font.set_Cursor( 50, 80); //Place cursor at low/left of LCD

  for(i=0; i<43;i++) //loop until al chrs in sensorData is placed on the LCD display
  {
    font.putChar(sensorTypeTxt[i]); //place the sensorData variable, sensorData come from a sensor as voltage sensor, current sensor, temperature sensor

    if(font.CharWidth(i) !=0)
    {
      if( (font.CursorX + font.CharWidth(i)) > 270)
      {
        row++;
        font.set_Cursor(50, 80+ (row* font.Font_Height + 2));
      }    
    }
  }

  font.set_Font(f12x12); // set font to menu size
  wait_for_OK();

}


void calibrate()
{
  tft.ClearScreen(BLACK);
  tp_calibrate();
  wait_for_OK();
}

//*********************************
// onewire and dallas ds18b20 code
//*********************************

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

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

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

void getCurrentTemp(char *temp)
{
  int HighByte, LowByte, TReading, Tc_100, sign, whole, fract;

  OneWireReset(TEMP_PIN);
  OneWireOutByte(TEMP_PIN, 0xcc);
  OneWireOutByte(TEMP_PIN, 0x44); // perform temperature conversion, strong pullup for one sec

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

  LowByte = OneWireInByte(TEMP_PIN);
  HighByte = OneWireInByte(TEMP_PIN);
  TReading = (HighByte << 8) + LowByte;
  sign = TReading & 0x8000;  // test most sig bit
  if (sign) // 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(sign) temp[0]='-';
else temp[0]='+';

temp[1]= (whole-(whole/100)*100)/10 +'0';
//u temp[1]= 'a' ;
temp[2]= whole-(whole/10)*10 +'0';

temp[3]='.';
temp[4]=fract/10 +'0';
temp[5]=fract-(fract/10)*10 +'0';

temp[6] = '\0';
}

No comments:

Post a Comment