Notes About Working with Various Arduino & Netduino Microcontroller Boards

Friday, November 2, 2012

Using an Arduino Uno & SainSmart 12864 Graphic LCD to Graph Temperature

I posted yesterday about getting started with the SainSmart graphic LCD. Below is a more complex application (but still not too complex).

 Here is a sketch that uses the DHT22 temperature (and humidity) sensor to read the current temperature (in degrees Fahrenheit) once a minute and display the result as a bar graph on the LCD. The graph has labels on the left side from 67 to 72 degrees (but can display values up to 73 degrees). Each column on the graph is one pixel wide. The graph starts scrolling to the left when the right margin is reached.

#include <dht22.h>
#include <Versalino.h>
#include <U8glib.h>

/*
 *  SID connected to D2
 *  CS  connected to D3
 *  SCK connected to D5
 *  No reset connected
 */
U8GLIB_ST7920_128X64 u8g(5, 2, 3, U8G_PIN_NONE);         

dht22 DHT22;

const int LAST_ROW = 63;
const int LAST_COL = 110;
static char* TEMP_LABELS[] = {"67", "68", "69", "70", "71", "72"};

float temp;
int dots;
int bars[LAST_COL]; 
int cnt = 0;

void setup(void) {
  // DHT22 temp sensor connected to pin D9 
  DHT22.attach(9);
}

void shiftBars() {
  for(int n = 1; n < LAST_COL; n++) {
    bars[n-1] = bars[n];
  }
}

void draw(void) {
  u8g.setFont(u8g_font_04b_03);
  drawDegreeMarks();
  for(int j = 0; j < LAST_COL; j++) {
    u8g.drawVLine(16 + j, LAST_ROW - 2 - bars[j], bars[j]);
  }
}

void drawDegreeMarks() {
  int k = 0;
  for(int i = LAST_ROW - 3; i > 0; i = i-10) {
    u8g.drawStr(0, i + 2, TEMP_LABELS[k++]);
    u8g.drawHLine(10, i, 4);
  }   
}

void loop(void) {
  int chk = DHT22.read();
  temp = DHT22.fahrenheit();
  Serial.println(temp);
  dots = (temp * 10 - 670);
  if(cnt <= LAST_COL - 1) {
    bars[cnt++] = dots;
  }
  else {
    bars[cnt] = dots;
    shiftBars();
    cnt = LAST_COL - 1;
  }
  u8g.firstPage();  
  do {
    draw();
  } while( u8g.nextPage() );
  // redraw once a minute
  delay(60000); 
}

2 comments:

  1. may i know why bars = temp*10 - 670 ?

    ReplyDelete
    Replies
    1. The graph's lowest boundary in this example is 67 degrees. The temp from the sensor includes tenths of a degree. Multiplying by 10 removes the decimal to translate the value into dots on the graph. Since the lowest value on the graph is 67, multiplying by 10 gives 670. Subtracting this threshold value from the temp multiplied by 10 gives the number of pixels/dots for the bar on the graph.

      --Brad

      Delete