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