Friday, 28 February 2014

Echo display

I have been playing with the 128 x 64 bit mapped display LCD. This can be driven over an SPI bus and can use the very flexible u8glib library. My set up is like this. The display shows both the distance away from the sensor in cm, and has a graphical bar that move left and right to show this distance.

2014 02 28 18 35 39

Some of the methods for the u8glib library (Google it to find/download) are:

lcd.begin(); // reset display and put in default state
lcd.enableCursor(); // cursor visible
lcd,disableCursor(); // cursor not visible (default state)
lcd.setCursorPos(x, y); // cursor to x, y
lcd.setColorIndex(col); // BW on = 1, off = 0
lcd.drawBitMap(x, y, cnt, h, *bitmap); // draw bit map of cnt bytes
                                       // width is cnt * 8
                                       // at x, y (top left) height h
lcd.drawBox(x, y, w, h); // filled box at x, y. width w, height h
                         // fill set by color index
lcd.drawCircle(x, y, rad, opt); // x, y centre, radius rad, 
                                // opt is option to draw part circle
                                // U8G_DRAW_UPPER_RIGHT, ...LEFT,
                                //  ... LOWER_LEFT, ... RIGHT, ...ALL
lcd.drawDisk(x, y, rad, opt); // as above but filled circle
lcd.drawFrame(x, y, w, h); // frame at x, y width w height h
lcd.drawRFrame(x, y, w, h, r); // rounded frame, edges radius r
lcd.drawHLine(x, y, w); // draw horizontal line from x,y width w
lcd.drawVLine(x, y, h); // draw vertical line from x, y height h
lcd.drawLine(x1, y1, x2, y2,); // draw line from x1, y1 to x2, y2
lcd.drawTriangle(x1, y1, x2, y2, x3, y3); // filled triangle
lcd.drawPixel(x, y); // pixel at x, y
lcd.setFont(*font); // sets font - see table below
lcd.getStrWidth(*s); // returns string width in pixels in current font
lcd.drawStr(x, y, *s); // string at x, lower left of font characters 
lcd.firstPage(); // starts a “picture loop”
lcd.nextPage(); // marks end of “picture loop”, returns 0 if finished


x = col, y = row down from the top left 0, 0 of the LCD. Images (like boxes) draw w = right, h = down from the index x, y. f

For an 128 x 64 display using the ST7920 controller chip an object can be created very simply with

#include “u8glib.h”
U8GLIB_ST7920_128X64_1X lcd(SCK, MOSI, CS); // lcd object


where SCK, MOSI & CS are the standard Arduino Uno SPI bus signals - see code below for connections. Note that display PSB must be GND for serial SPI bus operation.

Code

// QC12864B display using ST7920, with built in pot "VR" for adjusting VO
// LCD connections VSS - GND, VDD - 5V, RS - 10, RW - 11, E - 13, PSB - GND, A - 120R - 5V, K - GND
// sonar Trig 8, Echo 9

#include "U8glib.h"
#include "NewPing.h"

// SPI SCK, MOSI & SS
#define EN 13
#define RW 11
#define CS 10

// sonar
#define TRIG 8
#define ECHO 9
#define MAXDIST 200

// display set up, bar, line position length, caption position
#define BARWDTH 5
#define BARHT 10
#define LINEX1 2
#define LINEY1 50
#define LINELEN 120
#define CAPY1 10

// lcd object
U8GLIB_ST7920_128X64_1X lcd(EN, RW, CS); // SCK = EN D13, MOSI = RW D11, SS = CS D10

// sonar object
NewPing sonar(TRIG, ECHO, MAXDIST);

void setup(void)
{
  lcd.begin(); // init display
  lcd.setRot180(); // flip screen
}

void loop(void) 
{
  unsigned int barht; // bar height = number of echos (0-50)
  unsigned int barecho; // echo distance (0 to 120-BARWDTH) = 50
  unsigned cm; // echo return
  char cmbuf[4]; // echo return in ASCII
  

  cm = sonar.ping_cm(); // get distance echo
  sprintf(cmbuf, "%d", cm); // convert to ASCII
  barecho = map(cm, 0, MAXDIST, LINEX1, LINEX1 + LINELEN); // scale cm to line len
  barht = BARHT; // set bar height
   
  // picture loop
  lcd.firstPage();  
  do 
  {
    lcd.setFont(u8g_font_helvR08); // font height "A" of 8 pixels, 2 rows "g" descenders
    
    lcd.drawStr(LINEX1, CAPY1, "Echo distance measurement"); // col 2 row 8, text bottom left is on row
    lcd.drawStr(40, CAPY1 + 11, cmbuf);
    lcd.drawStr(60, CAPY1 + 11, "cm");
    
    lcd.drawLine(LINEX1, LINEY1, LINEX1 + LINELEN, LINEY1); // base line
    
    lcd.drawStr(LINEX1, LINEY1 + 10, "0"); // scale numbers
    lcd.drawStr(LINEX1 + LINELEN - 16, LINEY1 + 10, "200"); 
    
    lcd.drawBox(LINEX1 + barecho, LINEY1 - barht, BARWDTH, barht);
    

  } while(lcd.nextPage());
  
  // rebuild the picture after some delay
  delay(500);
}

No comments: