Feb042017

Bouncing Ball with a Newhaven Display 160x128 RGB OLED

Published by paul at 2:52 PM under Arduino | Example Code | OLED display

Wow - it's been more than 6 years since I had some serious time to play with electronics and blogged here! Life and work just got in the way. But no more!

After spending about a week sorting out my desk/lab area, arranging everything nicely and taking stock of all the kits, boards, components and tools I've got, I'm ready to start playing and blogging again.

The first thing I decided to play with is an Arduino shield from Newhaven Display that has one of their 1.69-inch 160x128 RGB OLED display modules. It cost $50.95 and I ordered it directly from them here.

It's a really nice looking board and I got it working very quickly using the example sketch they've posted on GitHub here. When you compile and upload the sketch, this is the result:

 

I figured I'd play around with it so decided to write a classic bouncing ball zipping around the screen. I figured out how to use their interface, ripped out all the superfluous code from the example, and got it working.

You can see a very short YouTube video of it in action here.

And below is the code.

Enjoy!

//---------------------------------------------------------
//---------------------------------------------------------
/*
 
 Newhaven_Bounce

 Adapted from Newhaven example code
 
*/
//---------------------------------------------------------

// The 8 bit data bus is connected to PORTD[7..0]
#define   SDI_PIN   11    // SDI (serial mode) signal connected to pin 11
#define   SCL_PIN   13    // SCL (serial mdoe) signal connected to pin 13
#define    RS_PIN    4    // RS signal connected to pin 4
#define   RES_PIN   6     // /RES signal connected to pin 6
#define    CS_PIN   5     // /CS signal connected to pin 5
#define    PS_PIN   A0    // PS signal connected to pin A0
#define   CPU_PIN   A1    // CPU signal connected to pin A1
#define   LVL_DIR   A2    // DIR (direction control) signal of level shifter IC connected to pin A2
#define   LVL_OEN   A3    // /OE (output enable) signal of level shifter IC connected to pin A3

#define    RED  0x0000FF
#define  GREEN  0x00FF00
#define   BLUE  0xFF0000
#define  WHITE  0xFFFFFF
#define  BLACK  0x000000

/*********************************/
/****** LOW LEVEL FUNCTIONS ******/
/************* START *************/
/*********************************/

// Send command to OLED
void OLED_Command_160128RGB (unsigned char c)
{
  unsigned char i;
  unsigned char mask = 0x80;
    
  digitalWrite (CS_PIN, LOW);
  digitalWrite (RS_PIN, LOW);
  
  for(i = 0; i < 8; i++)
  {
    digitalWrite (SCL_PIN, LOW);
    
    if((c & mask) >> 7 == 1)
    {
      digitalWrite (SDI_PIN, HIGH);
    }
    else
    {
      digitalWrite (SDI_PIN, LOW);
    }
    
    digitalWrite (SCL_PIN, HIGH);
    c = c << 1;
  }
  
  digitalWrite (CS_PIN, HIGH);
} // OLED_Command_160128RGB

// Send data to OLED
void OLED_Data_160128RGB (unsigned char d)
{
  unsigned char i;
  unsigned char mask = 0x80;
    
  digitalWrite (CS_PIN, LOW);
  digitalWrite (RS_PIN, HIGH);
  
  for(i = 0; i < 8; i++)
  {
    digitalWrite (SCL_PIN, LOW);
    
    if((d & mask) >> 7 == 1)
    {
      digitalWrite (SDI_PIN, HIGH);
    }
    else
    {
      digitalWrite (SDI_PIN, LOW);
    }
    
    digitalWrite (SCL_PIN, HIGH);
    d = d << 1;
  }
  
  digitalWrite (CS_PIN, HIGH);
} // OLED_Data_160128RGB

// Serial write for pixel data
void OLED_SerialPixelData_160128RGB (unsigned char d)
{
  unsigned char i;
  unsigned char mask = 0x80;
  
  digitalWrite (CS_PIN, LOW);
  digitalWrite (RS_PIN, HIGH);
  
  for(i = 0; i < 6; i++)
  {
    digitalWrite (SCL_PIN, LOW);
    if ((d & mask) >> 7 == 1)
    {
      digitalWrite (SDI_PIN, HIGH);
    }
    else
    {
      digitalWrite (SDI_PIN, LOW);
    }
    
    digitalWrite (SCL_PIN, HIGH);
    d = d << 1;
  }
  
  digitalWrite (CS_PIN, HIGH);
} // OLED_SerialPixelData_160128RG

// Write to RAM command
void OLED_WriteMemoryStart_160128RGB (void)
{
  OLED_Command_160128RGB (0x22);
} // OLED_WriteMemoryStart_160128RGB

// Write one pixel of a given color
void OLED_Pixel_160128RGB (unsigned long color)
{
  OLED_SerialPixelData_160128RGB (color >> 16);
  OLED_SerialPixelData_160128RGB (color >> 8);
  OLED_SerialPixelData_160128RGB (color);
}

// Set x,y pixel address
void OLED_SetPosition_160128RGB (unsigned char x_pos, unsigned char y_pos)
{
  OLED_Command_160128RGB (0x20);
  OLED_Data_160128RGB (x_pos);
  OLED_Command_160128RGB (0x21);
  OLED_Data_160128RGB (y_pos);
} // OLED_SetPosition_160128RGB

// Fill screen with a given color
void OLED_FillScreen_160128RGB (unsigned long color)
{
  unsigned int i;
  
  OLED_SetPosition_160128RGB (0, 0);
  OLED_WriteMemoryStart_160128RGB ();
  
  for(i = 0; i < 20480; i++)
  {
    OLED_Pixel_160128RGB(color);
  }
} // OLED_FillScreen_160128RGB

/*===============================*/
/*===== LOW LEVEL FUNCTIONS =====*/
/*============= END =============*/
/*===============================*/

/*********************************/
/******** INITIALIZATION *********/
/************ START **************/
/*********************************/

// OLED initialization
void OLED_Init_160128RGB (void)
{
    digitalWrite (RES_PIN, LOW);
    delay (2);
    digitalWrite (RES_PIN, HIGH);
    delay (2);
    
    // Display off, analog reset
    OLED_Command_160128RGB (0x04);
    OLED_Data_160128RGB (0x01);
    delay (1);
    
    // Normal mode
    OLED_Command_160128RGB (0x04); 
    OLED_Data_160128RGB (0x00); 
    delay (1);
    
    // Display off
    OLED_Command_160128RGB (0x06);
    OLED_Data_160128RGB (0x00);
    delay (1);
    
    // Turn on internal oscillator using external resistor
    OLED_Command_160128RGB (0x02);
    OLED_Data_160128RGB (0x01); 
    
    // 90 hz frame rate, divider 0
    OLED_Command_160128RGB (0x03);
    OLED_Data_160128RGB (0x30); 
    
    // Duty cycle 127
    OLED_Command_160128RGB (0x28);
    OLED_Data_160128RGB (0x7F);
    
    // Start on line 0
    OLED_Command_160128RGB (0x29);
    OLED_Data_160128RGB (0x00); 
    
    // rgb_if
    OLED_Command_160128RGB (0x14);
    OLED_Data_160128RGB (0x31); 
    
    // Set Memory Write Mode
    OLED_Command_160128RGB (0x16);
    OLED_Data_160128RGB (0x76);
    
    // Driving current r g b (uA)
    OLED_Command_160128RGB (0x10);
    OLED_Data_160128RGB (0x45);
    OLED_Command_160128RGB (0x11);
    OLED_Data_160128RGB (0x34);
    OLED_Command_160128RGB (0x12);
    OLED_Data_160128RGB (0x33);
    
    // Precharge time r g b
    OLED_Command_160128RGB (0x08);
    OLED_Data_160128RGB (0x04);
    OLED_Command_160128RGB (0x09);
    OLED_Data_160128RGB (0x05);
    OLED_Command_160128RGB (0x0A);
    OLED_Data_160128RGB (0x05);
    
    // Precharge current r g b (uA)
    OLED_Command_160128RGB (0x0B);
    OLED_Data_160128RGB (0x9D);
    OLED_Command_160128RGB (0x0C);
    OLED_Data_160128RGB (0x8C);
    OLED_Command_160128RGB (0x0D);
    OLED_Data_160128RGB (0x57);
    
    // Set Reference Voltage Controlled by External Resister
    OLED_Command_160128RGB (0x80);
    OLED_Data_160128RGB (0x00);
    
    // Mode set
    OLED_Command_160128RGB (0x13);
    OLED_Data_160128RGB (0xA0);

    // Set column address start + end
    OLED_Command_160128RGB (0x17);
    OLED_Data_160128RGB (0);
    OLED_Command_160128RGB (0x18);
    OLED_Data_160128RGB (159);

    // Set row address start + end
    OLED_Command_160128RGB (0x19);
    OLED_Data_160128RGB (0);
    OLED_Command_160128RGB (0x1A);
    OLED_Data_160128RGB (127);

    // Display On
    OLED_Command_160128RGB (0x06);
    OLED_Data_160128RGB (0x01); 
}

/*===============================*/
/*======= INITIALIZATION ========*/
/*============= END =============*/
/*===============================*/

void setup ()
{
  pinMode (LVL_OEN, OUTPUT);      // configure LVL_OEN as output
  digitalWrite (LVL_OEN, LOW);
  pinMode (LVL_DIR, OUTPUT);      // configure LVL_DIR as output
  digitalWrite (LVL_DIR, HIGH);
  DDRD = 0xFF;                    // configure PORTD as output
  pinMode (RS_PIN, OUTPUT);       // configure RS_PIN as output
  pinMode (RES_PIN, OUTPUT);      // configure RES_PIN as output
  pinMode (CS_PIN, OUTPUT);       // configure CS_PIN as output
  pinMode (PS_PIN, OUTPUT);       // configure PS_PIN as output
  pinMode (CPU_PIN, OUTPUT);      // configure CPU_PIN as output
  digitalWrite (LVL_OEN, LOW);
  digitalWrite (CS_PIN, HIGH);    // set CS_PIN

  pinMode (SDI_PIN, OUTPUT);      // configure SDI_PIN as output
  pinMode (SCL_PIN, OUTPUT);      // configure SCL_PIN as output
  PORTD = 0x00;                   // reset SDI_PIN and SCL_PIN, ground DB[5..0] of the display
  digitalWrite (PS_PIN, LOW);     // reset PS_PIN

  Serial.begin (57600);
}

void loop()
{
  // Initialize the display
  OLED_Init_160128RGB();

  // Emtpy the screen
  OLED_FillScreen_160128RGB(BLACK);

  unsigned int xPosition = 0;
  unsigned int yPosition = 0;
  int xDirection = 1;
  int yDirection = 1;

  // Bouncing ball
  while (1)
  {
    Serial.print (xPosition, DEC);
    Serial.print (", ");
    Serial.println (yPosition, DEC);

    OLED_SetPosition_160128RGB (xPosition, yPosition);
    OLED_WriteMemoryStart_160128RGB ();
    OLED_Pixel_160128RGB (WHITE);

    if (xPosition == 0)
    {
      xDirection = 1;
    }
    else if (xPosition == 159)
    {
      xDirection = -1;
    }

    if (yPosition == 0)
    {
      yDirection = 1;
    }
    else if (yPosition == 127)
    {
      yDirection = -1;
    }

    delay (10);

    OLED_SetPosition_160128RGB (xPosition, yPosition);
    OLED_WriteMemoryStart_160128RGB ();
    OLED_Pixel_160128RGB (BLACK);

    xPosition += xDirection;
    yPosition += yDirection;  
  }
}


[KickIt] [Dzone] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

E-mail | Permalink | Trackback | Post RSSRSS comment feed 0 Responses

Jan182010

Just got a 4D Systems OLED display to play with

Published by paul at 12:42 PM under Arduino | OLED display

Even though it's Martin Luther King day here in the US, UPS is still running and just delivered the display I'd ordered to play around with.

It's a uOLED-128-G1 1.5" diagonal display made by 4D Systems - 128x128 with 65k colors - with on-board micro-SD connector to hold bitmaps. Parallax sells these for $64.99 (see here) and I couldn't resist picking one up to tinker with.

Here's a photo (click for larger image) of the SMT PCB:

 

I've heard there's some documentation pulled together on these but it's going to be fun getting it to display bitmaps and things like graphs from sensor readings.

Also delivered was my copy of the Practical Arduino: Cool Projects for Open Source Hardware book - looks like I'm going to be busy this afternoon!



[KickIt] [Dzone] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Currently rated 1.5 by 66 people

  • Currently 1.500001/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

E-mail | Permalink | Trackback | Post RSSRSS comment feed 2 Responses