Go Down

Topic: [solved] DIP204-4 with SPI (Read 3192 times) previous topic - next topic

_frank_

Sep 14, 2011, 01:52 am Last Edit: Jan 21, 2012, 10:49 pm by _frank_ Reason: 1
Hi,
i try to get my Display to work with SPI and an arduino Uno.
of course i changed to soldering bridge (13) from 4/8 to SPI

here the Data-Sheet of the display:
http://www.lcd-module.de/eng/pdf/doma/dip204-4e.pdf

and my code:

Code: [Select]

//http://arduino.cc/en/Reference/SPI
// include the SPI library:
#include <SPI.h>

/*
10 (SS)   -> 4 (CS)
11 (MOSI) -> 5 (SID)
12 (MISO) -> 7 (SOD)
13 (SCK)  -> 6 (SCLK)

GND -> 1 (VSS)
5V  -> 2 (VDD)

5V-220-10k-GND
       \_ 3 (VEE)
*/

//int chartable[255];
// set pin 10 as the slave select for the digital pot:
const int slaveSelectPin = 10;

void setup() {
 // set the slaveSelectPin as an output:
 pinMode (slaveSelectPin, OUTPUT);
 
 //data for lcd dip204-4
 //http://www.mikrocontroller.net/articles/AVR_LCD_KS0073/DIP204_mit_Hardware-SPI
 SPI.setBitOrder(LSBFIRST);
 SPI.setDataMode(SPI_MODE3);
 SPI.setClockDivider(SPI_CLOCK_DIV64);
 
 // initialize SPI:
 SPI.begin();
 //lcd-init
 lcd_write(0x34,1);        // 34 0011 0100 (8Bit Bus, RE=1)
 lcd_write(0x09,1);        // 09 0000 1001 (4 Line Mode)
 lcd_write(0x30,1);        // 30 0011 0000 (8Bit Bus, N=0, RE=0, DH=0, REV=0)
}

void loop()
{
 /*
   * Zeile 1: 0x00 (bis 0x13)
   * Zeile 2: 0x20 (bis 0x33)
   * Zeile 3: 0x40 (bis 0x53)
   * Zeile 4: 0x60 (bis 0x73)
 */
 lcd_write(0x00,byte('1'));//1.Zeile,1.Spalte
 lcd_write(0x01,byte('A'));//1.Zeile,2.Spalte
 lcd_write(0x20,byte('2'));//2.Zeile,1.Spalte
 lcd_write(0x21,byte('B'));//2.Zeile,2.Spalte
 lcd_write(0x40,byte('3'));//3.Zeile,1.Spalte
 lcd_write(0x41,byte('C'));//3.Zeile,2.Spalte
 lcd_write(0x60,byte('4'));//4.Zeile,1.Spalte
 lcd_write(0x61,byte('D'));//4.Zeile,2.Spalte
}

int lcd_write(int address, int value) {
 // take the SS pin low to select the chip:
 digitalWrite(slaveSelectPin,LOW);
 //  send in the address and value via SPI:
 SPI.transfer(address);
 SPI.transfer(value);
 // take the SS pin high to de-select the chip:
 digitalWrite(slaveSelectPin,HIGH);
}


my Problem is, that nothing is displayed... i've searched google and this forum, but found no answer how to get this display working with arduino+spi.

the LCD-Library is imho only for 4 and 8bit normal transfer

regards Frank

Nadir

According to datasheet I could not see "Display on" command on your sketch.

_frank_

thanks for your answer, i'll try it out
currently experimenting with 4bit-mode and have to sold the bridge J3 again

olikraus

I just want to mention this lib:
http://code.google.com/p/doglcd/
But I am not sure if this fits to your type of displays. At least it is SPI mode and same company.  :smiley-roll:

Oliver

_frank_

#4
Sep 16, 2011, 03:10 pm Last Edit: Sep 16, 2011, 03:34 pm by _frank_ Reason: 1
nice idea...is DOGLCD working with LSBFIRST or MSBFIRST (i need LSBFirst)? i looked through the code, but its depending not on SPI-LIB.

hoping LiquidCrystal-Lib will support SPI in future (commands are the same)

_frank_

Hi,

i've tried adding the display-on-command and working with this tutorial (german):
http://www.mikrocontroller.net/articles/AVR_LCD_KS0073/DIP204_mit_Hardware-SPI

but i still got nothing displayed...

here my full code:
Code: [Select]
//http://arduino.cc/en/Reference/SPI
// include the SPI library:
#include <SPI.h>

#define COMMAND 0b00011111  // Command start byte
#define WRITE_DATA 0b01011111   // Write Data start byte

/*
11 (MOSI) -> 5 (SID)
12 (MISO) -> 7 (SOD)
13 (SCK)  -> 6 (SCLK)


10 (SS)   -> 4 (CS)
PULLUP ca. 22k (5V - 22k - CS)

GND -> 1 (VSS)
GND -> 18 (LED-)
5V  -> 2 (VDD)

5V-10k-
        \_ 3 (VEE)
5V-100-1k-
        \_ 17 (LED+)
*/

//int chartable[255];
// set pin 10 as the slave select for the digital pot:
//const int slaveSelectPin = 10; //UNO
const int slaveSelectPin = 53; //MEGA

void setup() {
  // set the slaveSelectPin as an output:
  pinMode (slaveSelectPin, OUTPUT);
  delay(5000);
  //data for lcd dip204-4
  //http://www.mikrocontroller.net/articles/AVR_LCD_KS0073/DIP204_mit_Hardware-SPI
  SPI.setBitOrder(LSBFIRST);
  SPI.setDataMode(SPI_MODE3);
  SPI.setClockDivider(SPI_CLOCK_DIV64);
 
  // initialize SPI:
  SPI.begin();
  //lcd-init
 
  lcd_write_data(true,0x34);        // 34 0011 0100 (8Bit Bus, RE=1)
  lcd_write_data(true,0x09);        // 09 0000 1001 (4 Zeilen Mode)
  lcd_write_data(true,0x30);        // 30 0011 0000 (8Bit Bus, N=0, RE=0, DH=0, REV=0)
  lcd_write_data(true,0x0F);        // 0F 0000 1111 (Display ein, Cursor ein, Cursor Blinken)
  //lcd_write_data(true,0x0C);        // 0C 0000 1100 (Display ein, Cursor aus, Cursor Blinken aus)
  lcd_write_data(true,0x01);        // 01 0000 0001 (Display löschen, cursor auf 0,0)
  lcd_write_data(true,0x06);        // 06 0000 0110 (Display löschen, cursor auf 0,0)
}

void loop()
{
  /*
    * Zeile 1: 0x00 (bis 0x13)
    * Zeile 2: 0x20 (bis 0x33)
    * Zeile 3: 0x40 (bis 0x53)
    * Zeile 4: 0x60 (bis 0x73)
  */
  /*
  lcd_write(0x00,byte('1'));//1.Zeile,1.Spalte
  lcd_write(0x01,byte('A'));//1.Zeile,2.Spalte
  lcd_write(0x20,byte('2'));//2.Zeile,1.Spalte
  lcd_write(0x21,byte('B'));//2.Zeile,2.Spalte
  lcd_write(0x40,byte('3'));//3.Zeile,1.Spalte
  lcd_write(0x41,byte('C'));//3.Zeile,2.Spalte
  lcd_write(0x60,byte('4'));//4.Zeile,1.Spalte
  lcd_write(0x61,byte('D'));//4.Zeile,2.Spalte
  */
 
  SetCursor(0,2);//1.Zeile, 3.Spalte
  lcd_write_data(false,'#');
  SetCursor(1,5);//2.Zeile, 6.Spalte
  lcd_write_data(false,'+');
  SetCursor(2,7);//3.Zeile, 8.Spalte
  lcd_write_data(false,'%');
  SetCursor(3,9);//4.Zeile, 10.Spalte
  lcd_write_data(false,'!');

}
/*
static const unsigned char BitReverseTable256[] =
{
  0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
  0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
  0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
  0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
  0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
  0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
  0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
  0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
  0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
  0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
  0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
  0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
  0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
  0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
  0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
  0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
};
*/
int SetCursor(byte row, byte col)
{
  int row_offsets[] = { 0x00, 0x20, 0x40, 0x60 };
  #define LCD_SETDDRAMADDR 0x80
  //  command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
  lcd_write_data(true,LCD_SETDDRAMADDR | (col + row_offsets[row]));
}

byte reversebyte(byte value)
{
  byte res=0;
  res=res|(value & 1)<<7;
  res=res|(value & 2)<<5;
  res=res|(value & 4)<<3;
  res=res|(value & 8)<<1;
  res=res|(value & 16)>>1;
  res=res|(value & 32)>>3;
  res=res|(value & 64)>>5;
  res=res|(value & 128)>>7;
  return res;
  //return value;
}

int lcd_write_data(bool command,byte value)
{
  // take the SS pin low to select the chip:
  digitalWrite(slaveSelectPin,LOW);
 
  int lowerdata=value & 0x0f;
  int upperdata=(value & 0xf0) >> 4;
 
  if (command)
    SPI.transfer(reversebyte(COMMAND));
  else
    SPI.transfer(reversebyte(WRITE_DATA));

  SPI.transfer(reversebyte(lowerdata));
  SPI.transfer(reversebyte(upperdata));
  // take the SS pin high to de-select the chip:
  digitalWrite(slaveSelectPin,HIGH);
}


any idea?

regards Frank

floresta

Quote
i try to get my Display to work with SPI and an arduino Uno.


You are facing two problems here:
(1) You are using an enhanced display that is similar to, but not exactly the same as, those using an Hitachi HD44780 controller.
(2) You are communicating with it via SPI rather than by connecting it directly to your Arduino.

Have you ever been able to get the display to work when it is connected directly to your Arduino?  Doing so would verify that you have correctly interpreted the data sheet and are sending it the correct commands in the correct sequence.  Once this is working you can then deal with sending those same commands via SPI.

As far as the LCD initialization is concerned you can find a description of how to deal with a standard HD44780 by following the LCD Initialization link at http://web.alfredstate.edu/weimandn.  The sequence for your device should be similar but you will have to deal with the 'Extended Function Set' command if you want to use the advanced capabilities of your device.  As I recall the main advantage is a four line mode that restructures the memory addressing to eliminate the 'interlaced' lines.  (Follow the LCD Addressing link to find out what this is all about.)


Don

dc42

#7
Jan 21, 2012, 06:21 pm Last Edit: Jan 21, 2012, 06:27 pm by dc42 Reason: 1
1. From the datasheet:

"Before transferring real data, start byte has to be transferred. It is composed of succeeding 5  "High" bits,
read write control bit (R/W), register selection bit (RS), and end bit that indicates the end of start byte.
Whenever succeeding 5  "High" bits are detected by KS0073, it resets the serial transfer counter and prepares
to receive next informations.
The next input data is the register selection bit which determines which register is to be used, and read write
control bit that determines the direction of data. Then end bit is transferred, which must have  "Low" value t
show the end of start byte. (Refer to Fig 19, Fig 20)".

It looks to me that you are trying to send the start byte, however you are sending it in reverse order. I think you are also sending the data in reverse order. Try removing all the calls to reverseByte.

2. On a Uno you should be using pin 10 as SS, not pin 53.

3. You probably need to include delays after sending some commands, see the datasheet for details.

4. You may need to send the FunctionSet command before you send DisplayOn. EDIT: You're doing that already, although maybe you need to set 4-bit mode instead of 8-bit mode.

btw I've been through this sort of thing before, writing a driver for a glcd with ST7920 controller in SPI mode. It took me a few attempts and lots of referring to the datasheet to get it working.


Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

_frank_

Hi, thank you for your response

1: i changed my reversebyte-function so that it does not reverse ;); start-& command-byte should be ok
2: i test currently with an mega2560 (cause my uno is busy) so pin 53 is ok...also connected this way
3: i'll try this...thx
4: my posted tutorial says 8-bit-mode

dc42

Have you also changed the connections for MOSI, MISO and SCLK to the correct ones for the Mega, not the ones listed in comments in the source code?
Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

_frank_

#10
Jan 21, 2012, 07:41 pm Last Edit: Jan 21, 2012, 09:11 pm by _frank_ Reason: 1
I've got it working...i test a bit with delays and post the working code here

_frank_

attached working example for arduino 1.0

sldiesel

Great Work getting this to Work :-)
But how do you print an integer or long ?
it seams that it only accept Char :-(

This code dont work            error: invalid conversion from 'long int' to 'const char*'

void loop()
{
  long a;
  a = millis();
  lcd_SetCursor(3,0);
  lcd_Print(a); 
  delay(1000);
}

_frank_

you can use sprintf or an own function to convert the integer to a char-array.

search the forum and the internet for conversion between int and char*, there are many examples

sldiesel

Thanks for the answer  it all gets a little complicated,

But width the SPI to LCD from adafruit i use today i can print anything, int, long, char and so on
https://www.adafruit.com/products/292  this is actually connectet to the DIP204J-4NLW in parallel mode (a bit crazy as the display has SPI)

Today i use this ---------------------------------------------------------
// include the library code:
#include "Wire.h"
#include "LiquidCrystal.h"
// Connect via SPI. Data pin is #3, Clock is #2 and Latch is #4
LiquidCrystal lcd(3, 2, 4);
-----------------------------------------------------------------------------
Now i try to connect direct to pin 51, 52, 53 (works fine )
width the code you posted. 

but would love to be able to just use lcd.print("anything")  int, long, char, and so on

any idea.

Go Up