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.

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