Go Down

Topic: Library for Electronic Assembly DOG Displays (Read 9558 times) previous topic - next topic


Jul 27, 2008, 08:47 pm Last Edit: Jul 27, 2008, 08:50 pm by dasgrundprinzip Reason: 1
Hi all.
My first post here and just with a library.  :)

I've made a library for the DOG series of Electronic Assembly. Because it's not a normal HD44780 controller. The library is written like the LCD4Bit library. And it's one of my sources.

Datasheet of the Display http://www.lcd-module.de/eng/pdf/doma/dog-me.pdf
Datasheet of the Controller ST7036 http://www.lcd-module.de/eng/pdf/zubehoer/st7036.pdf

I'll try to upload some pictures and the wiring diagram.

The Sketch:
Code: [Select]
// examples of the DOGM_LCD library

#include <DOGM_LCD.h>

// create an object with the type of your Display
// EA DOGM081x-A (1x8 chars)  -> 81
// EA DOGM162x-A (2x16 chars) -> 162
// ES DOGM163x-A (3x16 chars) -> 163
DOGM_LCD lcd = DOGM_LCD(163);

int i;
int x;
char string[3];

void setup() {

void loop() {
 // ##########
 lcd.printStr("Hello World!");
 // ##########  
 lcd.clear(); // clear the Display
 lcd.contrast(0); // set contrast to 0 (nothing to see)
 lcd.printStr("Fade in...");
 for (i=0; i<64; i++) {
 // ##########
 lcd.home(); // position of teh cursor at home (0,0)

 lcd.gotoxy(0, 1);

 lcd.gotoxy(0, 2);
 lcd.print(0x08); // print out some special chars
 for (i=63; i>=0; i--) {
 // ##########
 for (x=0; x<100; x++) {
   itoa(x, string, 10);

The Header:
Code: [Select]
#ifndef DOGM_LCD_h
 #define DOGM_LCD_h

 #include <inttypes.h>

 class DOGM_LCD {
   DOGM_LCD(int type);
   void cmd_nibble(int nibble);
   void cmd(int value);
   void init();
   void clear();
   void home();
   void gotoxy(int x, int y);
   void printStr(char value[]);
   void print(int value);
   void contrast(int value);
   void pulse_enable();
   void chkbusy();
   void push_nibble(int nibble);
   void push_byte(int value);


Jul 27, 2008, 08:47 pm Last Edit: Jul 27, 2008, 08:48 pm by dasgrundprinzip Reason: 1
And the .cpp

Code: [Select]
DOGM_LCD - v0.1 - 27.07.2008 - dasgrundprinzip.de

This is an Arduino library for the DOG series Display from Electronic Assembly.
Communication is 4-pin parallel mode.

- LCD4Bit v0.1 from neillzero (http://abstractplain.net Library)
- Datasheet of ST7036 controller (http://www.lcd-module.de/eng/pdf/zubehoer/st7036.pdf)

Tested with a DOGM163W-A (3x16 chars) on an Arduino Decimila and Arduino 0010 Alpha

see the examples folder of this library distribution.


// ########## includes ##########
#include "DOGM_LCD.h"
extern "C" {
 #include <stdio.h>            //not needed yet
 #include <string.h>            //needed for strlen()
 #include <inttypes.h>
 #include "WConstants.h"      //all things wiring / arduino

// ########## pin assignment ##########
int RS = 12;      // Register Select
int RW = 11;      // Read/Write
int En = 2;            // Enable

//DB should be an unseparated group of pins - because of lazy coding in push_nibble()
int DB[] = {7, 8, 9, 10};  // DB4 .. DB7

// ########## global variables ##########
int lcd_type = 81; // just a ini-value. The LCD-Type is changed in the DOGM_LCD sketch.

// If you want to save the RW-pin of the microcontroller, just switch it off and tie the RW-pin of the LCD to GROUND.
// The only time the RW-pin is used, is for checking the BusyFlag. When RW is deactivated we'll use a 5ms dealy instead checking the BusyFlag.
int USING_RW = false;

// The type variable is set in the sketch
DOGM_LCD::DOGM_LCD(int type) {
 lcd_type = type;

// a short (1us) impuls on the Enable-Pin to clock the Data into the LCD.
void DOGM_LCD::pulse_enable(){

// checking the Busy Flag (DB7=1 -> busy). Only when RW is activated. Otherwise a delay of 5ms.
void DOGM_LCD::chkbusy(){
 if (USING_RW) {
   int busy;

   // D4-D7 as input
   do {
     digitalWrite(RS, LOW);
     digitalWrite(RW, HIGH);
     digitalWrite(En,HIGH); // get high-nibble
     busy = digitalRead(DB[3]); // get DB7(BusyFlag)

     pulse_enable(); // get low-nibble and ignore it
   while (busy);

   // D4-D7 as output
 else delay(5);

//push a nibble of data through the the LCD's DB4~7 pins, clocking with the Enable pin.
//We don't care what RS and RW are, here.
void DOGM_LCD::push_nibble(int value){
 int val_nibble = value & 0x0F;  //clean the value.  (unnecessary)

 for (int i=DB[0]; i <= DB[3]; i++) {
   digitalWrite(i,val_nibble & 01);
   val_nibble >>= 1;

//push a byte of data through the LCD's DB4~7 pins, in two steps, clocking each with the enable pin.
void DOGM_LCD::push_byte(int value){
 int val_lower = value & 0x0F;
 int val_upper = value >> 4;

// Register Select to LOW -> it's a command. Push the nibble
void DOGM_LCD::cmd_nibble(int nibble) {
 digitalWrite(RS, LOW);
 if (USING_RW) { digitalWrite(RW, LOW); }

// Register Select to LOW -> it's a command. Push the byte
void DOGM_LCD::cmd(int value) {

 digitalWrite(RS, LOW);
 if (USING_RW) { digitalWrite(RW, LOW); }

// initializing the LCD
void DOGM_LCD::init () {
 if (USING_RW) { pinMode(RW,OUTPUT); }


 cmd_nibble(0x03);                   // FUNCTION SET            DL=1 - 8bit
 cmd_nibble(0x03);                   // FUNCTION SET       DL=1 - 8bit
 cmd_nibble(0x03);                   // FUNCTION SET       DL=1 - 8bit
 cmd_nibble(0x02);                   // FUNCTION SET            DL=0 - 4bit
 cmd(0x29);                              // FUNCTION SET            DL=0 / N=1 / DH=0 / IS2=0 / IS1=1

 cmd(0x14);                              // bias
 cmd(0x70);                              // contrast set
 cmd(0x52);                              // power/ICON/contrast
 cmd(0x6A);                              // follower control

 cmd(0x0C);                              // DISPLAY ON
 cmd(0x01);                              // CLEAR DISPLAY
 cmd(0x06);                              // ENTRY MODE SET

// Clear Screen
void DOGM_LCD::clear(){

// Cursor to Home position 0,0
void DOGM_LCD::home(){

// move cursor to position x,y (1st Row and 1st column is position 0,0)
// for a 163 display : x = 0..15   y = 0..2
void DOGM_LCD::gotoxy(int x, int y) {
 int addr = 0x80;
 if (y<1) addr = 0x80+x;
 else switch (lcd_type) {
   case 81:
       addr = 0x80+x;
     case 162:
       if (y>0) addr = 0xC0+x;
   case 163:
       if (y==1) addr = 0x90+x;
       else if (y>1) addr = 0xA0+x;


... and the rest of the .cpp

Code: [Select]
// Register Select to HIGH -> it's a data. Push the byte. With this function it is possible to dispaly special chars.
void DOGM_LCD::print(int value) {
 digitalWrite(RS, HIGH);
 if (USING_RW) { digitalWrite(RW, LOW); }


// print the given string to the LCD at the current cursor position.  overwrites, doesn't insert.
void DOGM_LCD::printStr(char msg[]) {
 uint8_t i;  //fancy int.  avoids compiler warning when comparing i with strlen()'s uint8_t
 for (i=0;i < strlen(msg);i++){

// The only possibility to change the contrast of the display. There's no potentiometer to do that!
// The contrast is initialized to 32. The posible range is 0..63.
void DOGM_LCD::contrast (int value) {
 if ((value >= 0x00) && (value <= 0x3F)) {
   int val_lower = value & 0x0F;
   int val_upper = value >> 4;
   cmd(0x29); // FUNCTION SET


great this was on my task list, but never got beyond some (successful) tests.
I will try your code with my 2 Line display.

But here are already some hints :
If you have the time to do so, you should create a new page on the playground http://www.arduino.cc/playground/, write some documentation for it and upload the code to there.

For the device-selection in the constructor I would suggest adding 3 #define statements :
Code: [Select]

#define EA_DOGM081 81
#define EA_DOGM162 162
#define EA_DOGM163 163


The link to the product-page points to the german version here is the english translation http://www.lcd-module.de/eng/dog/dog.htm



Here are some more hints, I hope they are helpful

I was curious to know if you compared the performance the library when using  RW to check when the panel is ready vs a hard coded delay. My guess is that it takes much longer to execute the code that checks if the panel is ready than a hard coded 5ms delay used if USING_RW set false. So the panel will always be ready on the first read and the delay will be much more than 5ms. But I haven't actually tried it and would be happy to be proved wrong.

I realize the code was derived from the playground lcd4bit code but  you can get some extra performance in your library by eliminating the 1us delays in pulse_enable(). The Enable pulse will be at least 4us long without any added delays because each digitalWrite takes around 2us.

pulse_enable is called a number of times for each character written so minimsing the delay should enhance the performance.


Jul 28, 2008, 09:24 pm Last Edit: Jul 28, 2008, 09:27 pm by dasgrundprinzip Reason: 1
Hi wayoda,
would be interesting if I'm right with the adresses for the 2nd line. Where would you place the define statements? In the Arduino-Code or maybe in the header-file?

Hi mem,
I just tested your suggestions and commented out the 1us delay in the pulse_enable() ... working. And I commented out the 5ms delay.
void DOGM_LCD::chkbusy() {}
And it's working already. What I want to try is, to count the time during the do{...}while(busy) and display it on the LCD, or something like that.
But the next two days I'm away on a construction job (I hope you know what I mean - in german it's called "auf Montage sein"). So maybe on thursday or friday.

And the next step is to test the SPI-mode. And the documentation of course. And then I'll start my little project.  ;D


Hm, I searched the Arduino site and unfortunately I only found this after I finished my first attempt at writing a library for the DOG-M displays.

The good side of this: I started off with SPI. So, if you would like, you could take my working SPI code and merge it into your library?

Here's the link to my github project:http://github.com/halfbyte/lcddogmspi/tree/master


Aug 26, 2008, 12:42 pm Last Edit: Aug 26, 2008, 12:43 pm by HULK Reason: 1
Can not find any prices on the DOG display, any hints?
Hope they are not to expensive, they are a great product.



I received a price list from Electronic Assembly.
The price is good, hope it is ok to list prices at this forum.

Article no. / product type /      price: | 1- | 25- | 100- pieces/EURO
EA DOGL128B-6       128x64      à 20,50 / 15,38 / 13,33 EUR,      STN, blue negative
EA DOGL128E-6       128x64      à 20,50 / 15,38 / 13,33 EUR, STN, Y-green positive
EA DOGL128L-6       128x64      à 20,50 / 15,38 / 13,33 EUR, STN, reflektive, pos.
EA DOGL128S-6       128x64      à 20,50 / 15,38 / 13,33 EUR, FSTN, black negative
EA DOGL128W-6 128x64            à 20,50 / 15,38 / 13,33 EUR, FSTN, black positive

LED backlights:

LED68x51-W            white                  à 15,50 / 11,63 / 10,08 EUR
LED68x51-G            yellow-green      à   6,50 /  4,88 /   4,23 EUR
LED68x51-B            blue                  à 15,50 / 11,63 / 10,08 EUR
LED68x51-R            red                        à   6,50 /  4,88 /   4,23 EUR LED68x51-A            amber                  à   6,50 /  4,88 /   4,23 EUR
LED68x51-E            green                  à 15,50 / 11,63 / 10,08 EUR
LED68x51-RGB      multicolour            à 24,50 / 18,38 / 15,93 EUR


EA FL-20P       socket             à  1.50|  1.20|  1.05 EUR  
2 pieces for each display
Touch Panel 128-2 will come soon
EA WF100-04S, connector                  à 1,50 / 1,13 / 0,98 EUR

Go Up