EA DOGXL160-W on Arduino Uno Rev 3 need Tutorial/Help

Moving the CS outside lcdWrite() didn’t change the behavior at all, it still doesn’t display my data. Any other ideas?

#include <snesController.h>
#include <SPI.h>

#define COMMAND 0
#define DATA 1
//New Controller
//  Latch: Pin 3
//  Clock: Pin 2
//  Data: Pin 5
snesController controller(3, 2, 5);

// Controller
static unsigned long ioReadWriteDelay; // Stores the delay time for ioReads/Writes
int *data;           // States of the controller buttons
boolean buttons[12]; 
int dataOld[2];        // previous states of the controller buttons

//  Display
const int csPin = 7; // Chip Select pin
const int rstPin = 9; // Reset pin
const int mosiPin = 11; // Mosi Pin
const int cdPin = 12; // Clock/Command Mode pin
const int clkPin = 13; // Clock pin
const int pixels[2] = {160, 104}; // X-Dimension, Y-Dimension


void setup() 
{
  // Display Setup:
  // Chip Select pin setup
  pinMode (csPin, OUTPUT);    // Setting the pin as an output
  digitalWrite(csPin, HIGH);  // Normally high

  // Reset pin setup
  pinMode (rstPin, OUTPUT);   // Setting the pin as an output
  digitalWrite(rstPin, HIGH); // Normally high

  // Command/Data pin setup
  pinMode (cdPin, OUTPUT);    // Setting the pin as an output
  digitalWrite(cdPin, HIGH);  // Just to define any state, not necessary
  
  // Clock pin setup
  pinMode (clkPin, OUTPUT);    // Setting the pin as an output
  digitalWrite(clkPin, HIGH);  // Just to define any state, not necessary
 
   // Mosi pin setup
  pinMode (mosiPin, OUTPUT);    // Setting the pin as an output
  digitalWrite(mosiPin, HIGH);  // Just to define any state, not necessary
  
  // OS Setup:
  
  ioReadWriteDelay = micros();
  Serial.begin(9600);
  
  // SPI setup ( http://arduino.cc/en/Reference/SPI )
  SPI.begin();                         // initializing SPI
  SPI.setBitOrder(MSBFIRST);           // MSB is sent first
  SPI.setClockDivider(SPI_CLOCK_DIV16); // 4MHz Clock (16MHz/divider)
  SPI.setDataMode(SPI_MODE3);          // Clock normally hight, data on positive edge.
  
  delay(2500); // The display needs around 5ms to boot, using 20ms just to be safe
  
  display_init(pixels[0], pixels[1]); // Initializes the display
  
}

void loop()
{
  
  if((long)(micros() - ioReadWriteDelay) >= 0)
  {
    ioReadWriteDelay += 16742;  // do it again later [µs].
    // Checks if more than ioReadWriteDelay [ms] has passed since last excecution of the code inside, also works if the timer overflows.
    data = controller.readButtons(); // Read connected controllers
    
    digitalWrite(csPin, LOW);  // Selects the chip
    if (data[0] != dataOld[0])
    {
      /*Serial.write(highByte(data[0])); // Upper 8 bits
      Serial.write(lowByte(data[0]));  // Lower 8 bits
      Serial.write(highByte(data[1])); // Upper 8 bits
      Serial.write(lowByte(data[1]));  // Lower 8 bits
      Serial.println();*/                       // To indicate a completed transmission 
      dataOld[0] = data[0];
      
      if((data[0] & 1) == 0)
      {
        lcdWrite(COMMAND, B10100101); // Set all pixels ON
      }
      else
      {
        lcdWrite(COMMAND, B10100100); // reset pixels to stored value
      }
    }
    digitalWrite(csPin,HIGH);  // Deselects the chip
  }
}

void display_init(byte width, byte height)
{
  digitalWrite(csPin, LOW);  // Selects the chip
  
  displayCmd_SET_COM_END(height);       // Defines the dimensions of the display
  displayCmd_SET_LCD_MAPPING_CONTROL(); // Orientation and order of pixels
  displayCmd_SET_SCROLL_LINE(0);        // Disable scrolling
  displayCmd_SET_PANEL_LOADING();       // Sets display capacitance
  displayCmd_SET_LCD_BIAS_RATIO();      // Sets bias ratio
  displayCmd_SET_VBIAS_POTENTIOMETER(); // Sets contrast
  displayCmd_SET_RAM_ADDRESS_CONTROL(); // Sets Auto-Increment
  displayCmd_SET_INVERSE_DISPLAY(false);// Display non-inverse data
  displayCmd_SET_LCD_GRAY_SHADE();      // Set gray shade
  //displayCmd_SET_DISPLAY_ENABLE(true);  // Enable display
  //displayCmd_SET_DISPLAY_ENABLE(false); // Disable display
  
  for(int k = 1; k <= (height / 4); k++)
  {
    displayCmd_SET_PAGE_ADDRESS(k);
    for(int i = 0; i < width; i++)
    {
      
      //Serial.print(k);
      //Serial.print(" ");
      //Serial.println(i);
      
      displayCmd_SET_COLUMN_ADDRESS(i);
      lcdWrite(DATA, B11111111); // Write Data to reset
    }
  }
  
  displayCmd_SET_DISPLAY_ENABLE(true);  // Enable display
  //lcdWrite(COMMAND, B10100101); // Set all pixels ON*/
  //delay(300);
  //lcdWrite(COMMAND, B10100100);
  //delay(300);
  digitalWrite(csPin,HIGH);  // Deselects the chip
}

void displayCmd_SET_COM_END(byte height)
{
  /*
  This command programs the ending COM electrode.
  CEN defines the number of used COM electrodes, and it should correspond to the number of pixel-rows in the LCD.
  */
  byte address = height - 1;
  lcdWrite(COMMAND, B11110001); // SET COM END Line 1
  lcdWrite(COMMAND, address);   // Address of last row
}

void displayCmd_SET_LCD_MAPPING_CONTROL()
{
  /*
  This command is used to program LC[2:0] for COM (row) mirror (MY), SEG (column) mirror (MX).
  */
  lcdWrite(COMMAND, B11000110); // SEG (column), COM (row), mirror
  //lcdWrite(COMMAND, B11000000); // This would be used to turn the display upside-down
}

void displayCmd_SET_SCROLL_LINE(byte scroll)
{
  /*
  Set the scroll line number.
  */
  byte lsb = B01000000 | (B00001111 & scroll);        // Combining command and 4 LSB's
  byte msb = B01010000 | ((B01110000 & scroll) >> 4); // Combining command and 3 MSB's
  lcdWrite(COMMAND, lsb);                             // 4 LSB
  lcdWrite(COMMAND, msb);                             // 3 MSB
}

void displayCmd_SET_PANEL_LOADING()
{
  /*
  Set PC[1:0] according to the capacitance loading of LCD panel.
  */
  lcdWrite(COMMAND, B00101011); // Sets Capacitance to 28-38nF
}

void displayCmd_SET_LCD_BIAS_RATIO()
{
  /*
  Bias ratio definition
  */
  lcdWrite(COMMAND, B11101011); // Sets Bias to 1/12
}

void displayCmd_SET_VBIAS_POTENTIOMETER()
{
  /*
  Program VBIAS Potentiometer (PM[7:0]).
  */
  lcdWrite(COMMAND, B10000001); // Command
  lcdWrite(COMMAND, B01011111); // Contrast value
}

void displayCmd_SET_RAM_ADDRESS_CONTROL()
{
  /*
  Program registers AC[2:0] for RAM address control.
  */
  lcdWrite(COMMAND, B10001001); // Set auto-increment
}

void displayCmd_SET_DISPLAY_ENABLE(boolean enable)
{
  /*
  This command is for programming register DC[2].
  When DC[2] is set to 0, the IC will put itself into Sleep mode.
  When any of the DC[2] bits is set to 1, UC1610 will first exit from Sleep Mode, restore the power and then turn on COM drivers and SEG drivers. There is no other explicit user action or timing sequence required to enter or exit the Sleep mode.
  */
  byte command = B10101110;
  if(enable)
  {
    command += 1;
  }
  lcdWrite(COMMAND, command); // Enable/Disable display
}

void displayCmd_SET_COLUMN_ADDRESS(byte column)
{
  byte lsb = column & B00001111;
  byte msb = (column & B11110000) >> 4;
  lcdWrite(COMMAND, (msb | B00010000));
  lcdWrite(COMMAND, (lsb | B00000000));
  
}

void displayCmd_SET_PAGE_ADDRESS(byte page)
{
  page = page & B00011111;
  byte command = page | B01100000;
  lcdWrite(COMMAND, command);
}

void displayCmd_SET_INVERSE_DISPLAY(boolean enable)
{
  /*
  Display the inverse of stored data, this has no effect on the data being stored
  */
  byte command = B10100110;
  if(enable)
  {
    command += 1;
  }
  lcdWrite(COMMAND, command); // Inverse/Regular display
}

void displayCmd_SET_LCD_GRAY_SHADE()
{
  /*
  Program gray scale register (LC[6:5]). This register controls the voltage RMS separation between the two gray shade levels (data “01” and data “10”)
  */
  lcdWrite(COMMAND, B11010011); // 40% gray shade levels
}







void lcdWrite(byte mode, byte data)
{
  //Serial.println("CS Low");
  
  digitalWrite(cdPin, mode); // Selects wether data or command is being sent
  //delayMicroseconds(5);
  
  SPI.transfer(data);        // 1byte of data/command
  //delay(2000);
  //Serial.println("CS High");
  
  //digitalWrite(cdPin, ~mode);
  //delayMicroseconds(5);
}

void resetLcd()
{
  // This function is used to reset the display
  digitalWrite(rstPin, LOW);  // Enabling the reset
  delay(5);                   // 5ms delay just to make sure
  digitalWrite(rstPin, HIGH); // Disabling the reset
  delay(20);                  // The display needs some time to reset, this prevents other code being executed too early
}

Looks better. How is the reset done for the DOGXL160? Reset must be tied to 3.3V. But you mentioned, that all pixel on works, so it can't be the reset.

What about this: After init, without setting page and column address (so, leaving the reset defaults), write some byte pattern to the display ram and see if some pixel appear.

Viel Erfolg, Oliver

Reset isn’t used, so it’s essentially tied to 3.3V.

I tried setting the pixels right after the init without using addresses, still doesn’t work. Btw, do I have to put the display to sleep before writing data? I couldn’t find a workflow for writing data in the manual http://www.lcd-module.de/eng/pdf/zubehoer/uc1610.pdf.

Here’s the code for testing without addresses:

#include <snesController.h>
#include <SPI.h>

#define COMMAND 0
#define DATA 1
//New Controller
//  Latch: Pin 3
//  Clock: Pin 2
//  Data: Pin 5
snesController controller(3, 2, 5);

// Controller
static unsigned long ioReadWriteDelay; // Stores the delay time for ioReads/Writes
int *data;           // States of the controller buttons
boolean buttons[12]; 
int dataOld[2];        // previous states of the controller buttons

//  Display
const int csPin = 7; // Chip Select pin
const int rstPin = 9; // Reset pin
const int mosiPin = 11; // Mosi Pin
const int cdPin = 12; // Clock/Command Mode pin
const int clkPin = 13; // Clock pin
const int pixels[2] = {160, 104}; // X-Dimension, Y-Dimension


void setup() 
{
  // Display Setup:
  // Chip Select pin setup
  pinMode (csPin, OUTPUT);    // Setting the pin as an output
  digitalWrite(csPin, HIGH);  // Normally high

  // Reset pin setup
  pinMode (rstPin, OUTPUT);   // Setting the pin as an output
  digitalWrite(rstPin, HIGH); // Normally high

  // Command/Data pin setup
  pinMode (cdPin, OUTPUT);    // Setting the pin as an output
  digitalWrite(cdPin, HIGH);  // Just to define any state, not necessary
  
  // Clock pin setup
  pinMode (clkPin, OUTPUT);    // Setting the pin as an output
  digitalWrite(clkPin, HIGH);  // Just to define any state, not necessary
 
   // Mosi pin setup
  pinMode (mosiPin, OUTPUT);    // Setting the pin as an output
  digitalWrite(mosiPin, HIGH);  // Just to define any state, not necessary
  
  // OS Setup:
  
  ioReadWriteDelay = micros();
  Serial.begin(9600);
  
  // SPI setup ( http://arduino.cc/en/Reference/SPI )
  SPI.begin();                         // initializing SPI
  SPI.setBitOrder(MSBFIRST);           // MSB is sent first
  SPI.setClockDivider(SPI_CLOCK_DIV16); // 4MHz Clock (16MHz/divider)
  SPI.setDataMode(SPI_MODE3);          // Clock normally hight, data on positive edge.
  
  delay(2500); // The display needs around 5ms to boot, using 20ms just to be safe
  
  display_init(pixels[0], pixels[1]); // Initializes the display
  
}

void loop()
{
  
  if((long)(micros() - ioReadWriteDelay) >= 0)
  {
    ioReadWriteDelay += 16742;  // do it again later [µs].
    // Checks if more than ioReadWriteDelay [ms] has passed since last excecution of the code inside, also works if the timer overflows.
    data = controller.readButtons(); // Read connected controllers
    
    digitalWrite(csPin, LOW);  // Selects the chip
    if (data[0] != dataOld[0])
    {
      /*Serial.write(highByte(data[0])); // Upper 8 bits
      Serial.write(lowByte(data[0]));  // Lower 8 bits
      Serial.write(highByte(data[1])); // Upper 8 bits
      Serial.write(lowByte(data[1]));  // Lower 8 bits
      Serial.println();*/                       // To indicate a completed transmission 
      dataOld[0] = data[0];
      
      if((data[0] & 1) == 0)
      {
        lcdWrite(COMMAND, B10100101); // Set all pixels ON
      }
      else
      {
        lcdWrite(COMMAND, B10100100); // reset pixels to stored value
      }
    }
    digitalWrite(csPin,HIGH);  // Deselects the chip
  }
}

void display_init(byte width, byte height)
{
  digitalWrite(csPin, LOW);  // Selects the chip
  
  displayCmd_SET_COM_END(height);       // Defines the dimensions of the display
  displayCmd_SET_LCD_MAPPING_CONTROL(); // Orientation and order of pixels
  displayCmd_SET_SCROLL_LINE(0);        // Disable scrolling
  displayCmd_SET_PANEL_LOADING();       // Sets display capacitance
  displayCmd_SET_LCD_BIAS_RATIO();      // Sets bias ratio
  displayCmd_SET_VBIAS_POTENTIOMETER(); // Sets contrast
  displayCmd_SET_RAM_ADDRESS_CONTROL(); // Sets Auto-Increment
  displayCmd_SET_INVERSE_DISPLAY(false);// Display non-inverse data
  displayCmd_SET_LCD_GRAY_SHADE();      // Set gray shade
  //displayCmd_SET_DISPLAY_ENABLE(true);  // Enable display
  //displayCmd_SET_DISPLAY_ENABLE(false); // Disable display
  
  for(int k = 1; k <= (height / 4); k++)
  {
    //displayCmd_SET_PAGE_ADDRESS(k);
    for(int i = 0; i < width; i++)
    {
      
      //Serial.print(k);
      //Serial.print(" ");
      //Serial.println(i);
      
      //displayCmd_SET_COLUMN_ADDRESS(i);
      lcdWrite(DATA, B11111111); // Write Data to reset
    }
  }
  
  displayCmd_SET_DISPLAY_ENABLE(true);  // Enable display
  //lcdWrite(COMMAND, B10100101); // Set all pixels ON*/
  //delay(300);
  //lcdWrite(COMMAND, B10100100);
  //delay(300);
  digitalWrite(csPin,HIGH);  // Deselects the chip
}

void displayCmd_SET_COM_END(byte height)
{
  /*
  This command programs the ending COM electrode.
  CEN defines the number of used COM electrodes, and it should correspond to the number of pixel-rows in the LCD.
  */
  byte address = height - 1;
  lcdWrite(COMMAND, B11110001); // SET COM END Line 1
  lcdWrite(COMMAND, address);   // Address of last row
}

void displayCmd_SET_LCD_MAPPING_CONTROL()
{
  /*
  This command is used to program LC[2:0] for COM (row) mirror (MY), SEG (column) mirror (MX).
  */
  lcdWrite(COMMAND, B11000110); // SEG (column), COM (row), mirror
  //lcdWrite(COMMAND, B11000000); // This would be used to turn the display upside-down
}

void displayCmd_SET_SCROLL_LINE(byte scroll)
{
  /*
  Set the scroll line number.
  */
  byte lsb = B01000000 | (B00001111 & scroll);        // Combining command and 4 LSB's
  byte msb = B01010000 | ((B01110000 & scroll) >> 4); // Combining command and 3 MSB's
  lcdWrite(COMMAND, lsb);                             // 4 LSB
  lcdWrite(COMMAND, msb);                             // 3 MSB
}

void displayCmd_SET_PANEL_LOADING()
{
  /*
  Set PC[1:0] according to the capacitance loading of LCD panel.
  */
  lcdWrite(COMMAND, B00101011); // Sets Capacitance to 28-38nF
}

void displayCmd_SET_LCD_BIAS_RATIO()
{
  /*
  Bias ratio definition
  */
  lcdWrite(COMMAND, B11101011); // Sets Bias to 1/12
}

void displayCmd_SET_VBIAS_POTENTIOMETER()
{
  /*
  Program VBIAS Potentiometer (PM[7:0]).
  */
  lcdWrite(COMMAND, B10000001); // Command
  lcdWrite(COMMAND, B01011111); // Contrast value
}

void displayCmd_SET_RAM_ADDRESS_CONTROL()
{
  /*
  Program registers AC[2:0] for RAM address control.
  */
  lcdWrite(COMMAND, B10001001); // Set auto-increment
}

void displayCmd_SET_DISPLAY_ENABLE(boolean enable)
{
  /*
  This command is for programming register DC[2].
  When DC[2] is set to 0, the IC will put itself into Sleep mode.
  When any of the DC[2] bits is set to 1, UC1610 will first exit from Sleep Mode, restore the power and then turn on COM drivers and SEG drivers. There is no other explicit user action or timing sequence required to enter or exit the Sleep mode.
  */
  byte command = B10101110;
  if(enable)
  {
    command += 1;
  }
  lcdWrite(COMMAND, command); // Enable/Disable display
}

void displayCmd_SET_COLUMN_ADDRESS(byte column)
{
  byte lsb = column & B00001111;
  byte msb = (column & B11110000) >> 4;
  lcdWrite(COMMAND, (msb | B00010000));
  lcdWrite(COMMAND, (lsb | B00000000));
  
}

void displayCmd_SET_PAGE_ADDRESS(byte page)
{
  page = page & B00011111;
  byte command = page | B01100000;
  lcdWrite(COMMAND, command);
}

void displayCmd_SET_INVERSE_DISPLAY(boolean enable)
{
  /*
  Display the inverse of stored data, this has no effect on the data being stored
  */
  byte command = B10100110;
  if(enable)
  {
    command += 1;
  }
  lcdWrite(COMMAND, command); // Inverse/Regular display
}

void displayCmd_SET_LCD_GRAY_SHADE()
{
  /*
  Program gray scale register (LC[6:5]). This register controls the voltage RMS separation between the two gray shade levels (data “01” and data “10”)
  */
  lcdWrite(COMMAND, B11010011); // 40% gray shade levels
}







void lcdWrite(byte mode, byte data)
{
  //Serial.println("CS Low");
  
  digitalWrite(cdPin, mode); // Selects wether data or command is being sent
  //delayMicroseconds(5);
  
  SPI.transfer(data);        // 1byte of data/command
  //delay(2000);
  //Serial.println("CS High");
  
  //digitalWrite(cdPin, ~mode);
  //delayMicroseconds(5);
}

void resetLcd()
{
  // This function is used to reset the display
  digitalWrite(rstPin, LOW);  // Enabling the reset
  delay(5);                   // 5ms delay just to make sure
  digitalWrite(rstPin, HIGH); // Disabling the reset
  delay(20);                  // The display needs some time to reset, this prevents other code being executed too early
}

Hi

no, sleep mode is not required.

what i do in u8glib: a0 = 0 cs = 0 0x010 col adr 0x000 col adr 0x060 page data a0 = 1 ... display ram data cs = 1

Oliver

I've got it working now, the problem was that my Command/Data pin was defined at pin 11 and it's used by the SPI library. I've just defined it somwhere else and everything works!

Thanks for helping, I'll write back once the display does something useful ;)