StratoLab

Lesson 7: OLED Display

Present data to a display

Pre-requisites:

Objectives:

What you will be using:

What you will be learning:

Wiring all the sensors and devices to the Arduino


Wiring the Arduino to the Breadboard


Module/Controller Pin BB/Arduino Pins
oLED Display  
GND BB Ground (-)
VCC BB Power (+)
SCL Common SCL (Arduino A5)
SDA Common SDA (Arduino A4)
GPS Sensor  
VCC BB Power (+)
GND BB Ground (-)
PPS N/A
TXD 3
RXD 4
Pressure Temperature Sensor  
VIN BB Power (+)
GND BB Ground (-)
SCL Common SCL (Arduino A5)
SDA Common SDA (Arduino A4)
Arduino  
5V BB Power (+)
GND BB Ground (-)

Full wire up



Common SCL/SDA

The BMP180 and oLED Display will share the SCL/SDA A5/A4 spot on the Arduino. I2C addresses are used to differentiate between the two modules.


Validate Libraries

Make sure that all the libraries below are installed in the IDE. Without these libraries the code below will not function and will error out.

NOTE: A new library is needed for this build. Install Adafruit SSD1306 library through the Arduino IDE by going to Sketch -> Include Library -> Manage Libraries -> then search for Adafruit SSD1306. Install the depending Adafruit GFX library as well.

Working Code - Copy and paste this into your sketch ```java #include #include "Adafruit_BMP085.h" #include #include #include #include #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) // The pins for I2C are defined by the Wire-library. // On an arduino UNO: A4(SDA), A5(SCL) // On an arduino MEGA 2560: 20(SDA), 21(SCL) // On an arduino LEONARDO: 2(SDA), 3(SCL), ... #define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) #define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); const int chipSelect = 10; const bool bypassGPS = true; static const int RXPin = 4, TXPin = 3; static const uint32_t GPSBaud = 9600; TinyGPSPlus gps; // map software serial to gps SoftwareSerial serialgps(TXPin, RXPin); Adafruit_BMP085 bmp; void setup() { // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { //Serial.println(F("SSD1306 allocation failed")); for(;;); // Don't proceed, loop forever } // Show initial display buffer contents on the screen -- // the library initializes this with an Adafruit splash screen. display.display(); bmp.begin(); serialgps.begin(GPSBaud); delay(2000); if (!serialgps.available()) { //Serial.println(F("initialization failed")); for(;;); } } void loop() { // make a string for assembling the data to log: String dataString = ""; bool gpsready = false; float lat = 0; float lng = 0; unsigned long start = millis(); do { while (serialgps.available()>0) { char c; c=serialgps.read(); gps.encode(c); } } while (millis() - start < 5000); float c = bmp.readTemperature(); // Variable for holding temp in C float f = c*1.8 + 32.; // Variable for holding temp in F //float pressure = bmp.readPressure()/3386.3887; //pascals to in of mercury float p = bmp.readPressure(); //pascals if ((gps.location.age() < 1000 || gps.location.isUpdated()) && gps.location.isValid()) { if (gps.satellites.isValid() && (gps.satellites.value() >= 3)) { lat = gps.location.isValid() ? gps.location.lat() : 0; lng = gps.location.isValid() ? gps.location.lng() : 0; gpsready = true; } } if (gpsready || bypassGPS) { // Clear the buffer display.clearDisplay(); display.setTextSize(1); // Normal 1:1 pixel scale display.setTextColor(SSD1306_WHITE); // Draw white text display.setCursor(0,0); // Start at top-left corner display.print(F("Temperature: ")); display.print(f); display.print(F(" F")); display.setTextSize(1); // Normal 1:1 pixel scale display.setTextColor(SSD1306_WHITE); // Draw white text display.setCursor(0,9); // Start at top-left corner display.print(F("Pressure: ")); display.print(p); display.setTextSize(1); // Normal 1:1 pixel scale display.setTextColor(SSD1306_WHITE); // Draw white text display.setCursor(0,18); // Start at top-left corner display.print(F("Lat: ")); display.print(String(lat, 6)); display.setTextSize(1); // Normal 1:1 pixel scale display.setTextColor(SSD1306_WHITE); // Draw white text display.setCursor(0,27); // Start at top-left corner display.print(F("Lng: ")); display.print(String(lng, 6)); display.setTextSize(1); // Normal 1:1 pixel scale display.setTextColor(SSD1306_WHITE); // Draw white text display.setCursor(0,36); // Start at top-left corner display.print(F("Altidtude: ")); display.print(String((long)gps.altitude.feet(), 6)); display.setTextSize(1); // Normal 1:1 pixel scale display.setTextColor(SSD1306_WHITE); // Draw white text display.setCursor(0,45); // Start at top-left corner display.print(F("Satellites: ")); display.print(String((int)gps.satellites.value())); // Show the display buffer on the screen. You MUST call display() after // drawing commands to make them visible on screen! display.display(); } delay(2000); } ``` </details>
## Want more? If you have finished with the base lesson, check out the items below.

Things to think about, validate, and/or try: * Is the data being written out correct? 🤔 * What are some things you could do to test all the modules at once? * Change the order/format of the output display data to your liking. * Load the demo display code to see the full power of the oLED! 😵 (File > Adafruit SSD1306 > ssd1306_128x64_i2c)
(***HINT:*** Change the ```SCREEN_ADDRESS``` to ```0x3C```) ## Challenge If you have finished with the extension lesson questions, check out the challenge below.

Create you own custom image, load it into a byte array, and display your image on the the oLED. [External walkthrough here!](https://www.instructables.com/How-to-Display-Images-on-OLED-Using-Arduino/) 🐧 Make sure that the image is appropriate in both size, scale, color...and taste. 😅

Try to write the code on your own. If you get stuck or need some inspiration expand this section. ```java #include #include #include #include #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) // The pins for I2C are defined by the Wire-library. // On an arduino UNO: A4(SDA), A5(SCL) // On an arduino MEGA 2560: 20(SDA), 21(SCL) // On an arduino LEONARDO: 2(SDA), 3(SCL), ... #define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) #define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); #define LOGO_HEIGHT 16 #define LOGO_WIDTH 16 // 'RickAndMorty', 128x64px const unsigned char epd_bitmap_RickAndMorty [] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xf0, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x9c, 0x00, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x0c, 0x14, 0x80, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x82, 0x42, 0x00, 0x00, 0x10, 0x00, 0x00, 0x21, 0x04, 0x14, 0x80, 0x12, 0x00, 0x00, 0x00, 0x00, 0x82, 0x42, 0x00, 0x00, 0x20, 0x00, 0x00, 0x21, 0x06, 0x14, 0x80, 0x12, 0x00, 0x00, 0x00, 0x01, 0x02, 0x42, 0x00, 0x00, 0x48, 0x00, 0x00, 0x21, 0x02, 0x04, 0x80, 0x12, 0x0c, 0x00, 0x00, 0x01, 0x02, 0x42, 0x00, 0x00, 0x50, 0x00, 0x00, 0x12, 0x02, 0x04, 0x80, 0x12, 0x18, 0x00, 0x00, 0x01, 0x23, 0xc3, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x10, 0x86, 0x23, 0x80, 0x12, 0x24, 0x00, 0x00, 0x01, 0x23, 0x81, 0x00, 0x7c, 0x90, 0x00, 0x00, 0x10, 0x84, 0x23, 0x80, 0x13, 0x74, 0x00, 0x00, 0x01, 0x21, 0x01, 0x09, 0x62, 0x80, 0x00, 0x00, 0x10, 0x84, 0x20, 0x87, 0xf3, 0xc8, 0x00, 0x01, 0x02, 0x21, 0x31, 0x1f, 0x43, 0xb1, 0x40, 0x00, 0x10, 0x8c, 0xc4, 0x88, 0x33, 0x10, 0x18, 0x05, 0x02, 0x31, 0x3d, 0x23, 0x03, 0xd1, 0x40, 0x00, 0x10, 0x58, 0x44, 0xda, 0x62, 0x30, 0x28, 0x05, 0x02, 0x31, 0x39, 0xc1, 0x21, 0x91, 0x20, 0x00, 0x00, 0x70, 0x44, 0xe1, 0xe0, 0x20, 0x2c, 0x3d, 0x02, 0x3d, 0x19, 0xc1, 0x11, 0x11, 0x20, 0x00, 0x00, 0x20, 0x84, 0xe1, 0xe0, 0x20, 0x67, 0xdd, 0x02, 0x39, 0x10, 0x81, 0x31, 0x3b, 0x20, 0x00, 0x08, 0x01, 0x04, 0xf2, 0x20, 0xc0, 0x44, 0xd9, 0x02, 0x39, 0x10, 0xd1, 0x11, 0x3f, 0x20, 0x00, 0x08, 0x03, 0x04, 0xe6, 0x21, 0x80, 0x74, 0xd9, 0x02, 0x29, 0x30, 0x11, 0x01, 0x07, 0x30, 0x00, 0x08, 0x03, 0x04, 0x4c, 0x31, 0x80, 0x14, 0x19, 0x02, 0x2c, 0x30, 0x3d, 0x0e, 0x01, 0x10, 0x00, 0x04, 0x01, 0x04, 0x44, 0x30, 0x80, 0xcc, 0x11, 0x02, 0x24, 0x30, 0x31, 0x8f, 0x21, 0x30, 0x00, 0x04, 0x00, 0xc6, 0x44, 0x30, 0xc0, 0xc4, 0x01, 0x02, 0x24, 0x30, 0x30, 0x07, 0x3d, 0x00, 0x00, 0x04, 0x40, 0xe0, 0x0f, 0xf0, 0x40, 0x80, 0x01, 0x04, 0x44, 0x39, 0x98, 0x07, 0x3f, 0x08, 0x1c, 0x04, 0x70, 0x22, 0x48, 0xb2, 0x20, 0x90, 0x09, 0x04, 0x44, 0xf1, 0x00, 0x27, 0x21, 0x08, 0x24, 0x04, 0x78, 0x12, 0x40, 0x36, 0x50, 0xb0, 0x81, 0x04, 0x46, 0x49, 0x01, 0x23, 0x21, 0x08, 0x4c, 0x04, 0xce, 0x1a, 0xc0, 0x7f, 0x10, 0x30, 0x91, 0x04, 0x42, 0x48, 0x81, 0x33, 0x20, 0x8d, 0x88, 0x04, 0x03, 0x0e, 0xe1, 0xf7, 0x10, 0xbb, 0xe4, 0x04, 0x42, 0x48, 0xe3, 0x33, 0x20, 0xcf, 0x10, 0x04, 0x01, 0x0e, 0xe7, 0x25, 0x00, 0xaa, 0x3c, 0x04, 0x81, 0x4c, 0xff, 0x3b, 0x20, 0x84, 0x20, 0x04, 0x40, 0xc6, 0x96, 0x24, 0x88, 0x00, 0x07, 0x04, 0x81, 0x84, 0x80, 0xcb, 0x20, 0x80, 0xc0, 0x04, 0x40, 0x62, 0x94, 0x28, 0x88, 0x00, 0x00, 0x04, 0x80, 0x04, 0x80, 0x0b, 0x00, 0x83, 0x80, 0x04, 0x40, 0x23, 0x80, 0x28, 0x48, 0x00, 0x00, 0x04, 0x80, 0x04, 0x80, 0x09, 0x40, 0x81, 0x00, 0x00, 0x20, 0x11, 0x00, 0x10, 0x48, 0x00, 0x00, 0x04, 0x80, 0x04, 0x80, 0x01, 0x40, 0xca, 0x00, 0x02, 0x20, 0x08, 0x80, 0x00, 0x48, 0x00, 0x00, 0x04, 0x80, 0x04, 0x80, 0x07, 0x41, 0x8c, 0x00, 0x02, 0x20, 0x0c, 0x80, 0x00, 0x34, 0x00, 0x00, 0x04, 0x80, 0x04, 0xc0, 0x03, 0x43, 0x88, 0x00, 0x01, 0x20, 0x06, 0x80, 0x00, 0x24, 0x00, 0x00, 0x04, 0x80, 0x02, 0x40, 0x00, 0x06, 0x10, 0x00, 0x01, 0x20, 0x02, 0x40, 0x00, 0x28, 0x00, 0x00, 0x01, 0x00, 0x03, 0x40, 0x00, 0x04, 0x30, 0x00, 0x01, 0x20, 0x02, 0x40, 0x00, 0x18, 0x00, 0x00, 0x01, 0x00, 0x01, 0x40, 0x00, 0x0c, 0x60, 0x00, 0x01, 0x20, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x08, 0xc0, 0x00, 0x01, 0x40, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; void setup() { Serial.begin(9600); // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { Serial.println(F("SSD1306 allocation failed")); for(;;); // Don't proceed, loop forever } // Show initial display buffer contents on the screen -- // the library initializes this with an Adafruit splash screen. //display.display(); //delay(2000); // Pause for 2 seconds // Clear the buffer display.clearDisplay(); display.drawBitmap(0, 0, epd_bitmap_RickAndMorty, 128, 64, WHITE); display.display(); } void loop() { } ``` </details> ### Review - Learned how to connect multiple different sensors or devices to the Arduino at the same time - Breadboarding circuits - How to display to an oLED Display - Put all of the other lessons together in order to make a final product

### Trouble shooting - Unplug/reset the Arduino and check all of the connections and try running it again - GPS not reading coordinates is likely caused by obstruction of the signal so moving outside may be necessary - Validate that all libraries are installed for use (BMP180 and GPS) - No display change? GPS never initialized and code is stuck. Validate GPS is setup correctly.