{"id":8545,"date":"2019-09-01T21:32:59","date_gmt":"2019-09-01T21:32:59","guid":{"rendered":"https:\/\/stevepedwards.today\/stevepedwards.com\/ElectronicsStuff\/?p=8545"},"modified":"2022-11-18T23:11:06","modified_gmt":"2022-11-18T23:11:06","slug":"alftek-0-96inch-i2c-iic-serial-128x32-blue-oled-display-module-for-arduino","status":"publish","type":"post","link":"https:\/\/stevepedwards.today\/ElectronicsStuff\/alftek-0-96inch-i2c-iic-serial-128x32-blue-oled-display-module-for-arduino\/","title":{"rendered":"Alftek 0.96inch I2C IIC Serial 128&#215;32 Blue OLED Display Module for Arduino"},"content":{"rendered":"<p>Had problems at first thinking it dead, but turned out they sent me a 128x32 size, not a 128x64 as ordered, and it won't run the 128x64 sketch if those parameters are not correct.<br \/>\nNo backlight with OLEDs either to see any function until it runs a sketch or not!<br \/>\nIt does run on 5V without killing it, with SCL to Uno pin A5 and SDA to Uno pin A4.<br \/>\nThe first thing is to check it has an I2C address using this scanner code:<\/p>\n<pre class=\"lang:default decode:true \">\/\/ --------------------------------------\r\n\/\/ i2c_scanner\r\n\/\/my oled I2C device found at address 0x3C\r\n\/\/ Version 1\r\n\/\/    This program (or code that looks like it)\r\n\/\/    can be found in many places.\r\n\/\/    For example on the Arduino.cc forum.\r\n\/\/    The original author is not know.\r\n\/\/ Version 2, Juni 2012, Using Arduino 1.0.1\r\n\/\/     Adapted to be as simple as possible by Arduino.cc user Krodal\r\n\/\/ Version 3, Feb 26  2013\r\n\/\/    V3 by louarnold\r\n\/\/ Version 4, March 3, 2013, Using Arduino 1.0.3\r\n\/\/    by Arduino.cc user Krodal.\r\n\/\/    Changes by louarnold removed.\r\n\/\/    Scanning addresses changed from 0...127 to 1...119,\r\n\/\/    according to the i2c scanner by Nick Gammon\r\n\/\/    https:\/\/www.gammon.com.au\/forum\/?id=10896\r\n\/\/ Version 5, March 28, 2013\r\n\/\/    As version 4, but address scans now to 127.\r\n\/\/    A sensor seems to use address 120.\r\n\/\/ Version 6, November 27, 2015.\r\n\/\/    Added waiting for the Leonardo serial communication.\r\n\/\/\r\n\/\/\r\n\/\/ This sketch tests the standard 7-bit addresses\r\n\/\/ Devices with higher bit address might not be seen properly.\r\n\/\/\r\n#include &lt;Wire.h&gt;\r\nvoid setup()\r\n{\r\n  Wire.begin();\r\n  Serial.begin(9600);\r\n  while (!Serial);             \/\/ Leonardo: wait for serial monitor\r\n  Serial.println(\"\\nI2C Scanner\");\r\n}\r\nvoid loop()\r\n{\r\n  byte error, address;\r\n  int nDevices;\r\n  Serial.println(\"Scanning...\");\r\n  nDevices = 0;\r\n  for(address = 1; address &lt; 127; address++ )\r\n  {\r\n    \/\/ The i2c_scanner uses the return value of\r\n    \/\/ the Write.endTransmisstion to see if\r\n    \/\/ a device did acknowledge to the address.\r\n    Wire.beginTransmission(address);\r\n    error = Wire.endTransmission();\r\n    if (error == 0)\r\n    {\r\n      Serial.print(\"I2C device found at address 0x\");\r\n      if (address&lt;16)\r\n        Serial.print(\"0\");\r\n      Serial.print(address,HEX);\r\n      Serial.println(\"  !\");\r\n      nDevices++;\r\n    }\r\n    else if (error==4)\r\n    {\r\n      Serial.print(\"Unknown error at address 0x\");\r\n      if (address&lt;16)\r\n        Serial.print(\"0\");\r\n      Serial.println(address,HEX);\r\n    }\r\n  }\r\n  if (nDevices == 0)\r\n    Serial.println(\"No I2C devices found\\n\");\r\n  else\r\n    Serial.println(\"done\\n\");\r\n  delay(5000);           \/\/ wait 5 seconds for next scan\r\n}<\/pre>\n<p>In the Serial Monitor:<br \/>\n<span style=\"color: #ff0000;\">22:50:30.778 -&gt; I2C Scanner<\/span><br \/>\n<span style=\"color: #ff0000;\">22:50:30.811 -&gt; Scanning...<\/span><br \/>\n<span style=\"color: #ff0000;\">22:50:30.811 -&gt; I2C device found at address 0x3C !<\/span><br \/>\n<span style=\"color: #ff0000;\">22:50:30.844 -&gt; done<\/span><br \/>\n<iframe loading=\"lazy\" title=\"OLED 128x32 graphics test\" width=\"1778\" height=\"1000\" src=\"https:\/\/www.youtube.com\/embed\/cfnRWZPhbXs?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><br \/>\nSnowflakes + graphics code here:<\/p>\n<pre class=\"lang:default decode:true \">\/**************************************************************************\r\n This is an example for our Monochrome OLEDs based on SSD1306 drivers\r\n Pick one up today in the adafruit shop!\r\n ------&gt; https:\/\/www.adafruit.com\/category\/63_98\r\n This example is for a 128x32 pixel display using I2C to communicate\r\n 3 pins are required to interface (two I2C and one reset).\r\n Adafruit invests time and resources providing this open\r\n source code, please support Adafruit and open-source\r\n hardware by purchasing products from Adafruit!\r\n Written by Limor Fried\/Ladyada for Adafruit Industries,\r\n with contributions from the open source community.\r\n BSD license, check license.txt for more information\r\n All text above, and the splash screen below must be\r\n included in any redistribution.\r\n **************************************************************************\/\r\n#include &lt;SPI.h&gt;\r\n#include &lt;Wire.h&gt;\r\n#include &lt;Adafruit_GFX.h&gt;\r\n#include &lt;Adafruit_SSD1306.h&gt;\r\n#define SCREEN_WIDTH 128 \/\/ OLED display width, in pixels\r\n#define SCREEN_HEIGHT 32 \/\/ OLED display height, in pixels\r\n\/\/ Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)\r\n#define OLED_RESET     4 \/\/ Reset pin # (or -1 if sharing Arduino reset pin)\r\nAdafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &amp;Wire, OLED_RESET);\r\n#define NUMFLAKES     10 \/\/ Number of snowflakes in the animation example\r\n#define LOGO_HEIGHT   16\r\n#define LOGO_WIDTH    16\r\nstatic const unsigned char PROGMEM logo_bmp[] =\r\n{ B00000000, B11000000,\r\n  B00000001, B11000000,\r\n  B00000001, B11000000,\r\n  B00000011, B11100000,\r\n  B11110011, B11100000,\r\n  B11111110, B11111000,\r\n  B01111110, B11111111,\r\n  B00110011, B10011111,\r\n  B00011111, B11111100,\r\n  B00001101, B01110000,\r\n  B00011011, B10100000,\r\n  B00111111, B11100000,\r\n  B00111111, B11110000,\r\n  B01111100, B11110000,\r\n  B01110000, B01110000,\r\n  B00000000, B00110000 };\r\nvoid setup() {\r\n  Serial.begin(9600);\r\n  \/\/ SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally\r\n  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { \/\/ Address 0x3C for 128x32\r\n    Serial.println(F(\"SSD1306 allocation failed\"));\r\n    for(;;); \/\/ Don't proceed, loop forever\r\n  }\r\n  \/\/ Show initial display buffer contents on the screen --\r\n  \/\/ the library initializes this with an Adafruit splash screen.\r\n  display.display();\r\n  delay(2000); \/\/ Pause for 2 seconds\r\n  \/\/ Clear the buffer\r\n  display.clearDisplay();\r\n  \/\/ Draw a single pixel in white\r\n  display.drawPixel(10, 10, WHITE);\r\n  \/\/ Show the display buffer on the screen. You MUST call display() after\r\n  \/\/ drawing commands to make them visible on screen!\r\n  display.display();\r\n  delay(2000);\r\n  \/\/ display.display() is NOT necessary after every single drawing command,\r\n  \/\/ unless that's what you want...rather, you can batch up a bunch of\r\n  \/\/ drawing operations and then update the screen all at once by calling\r\n  \/\/ display.display(). These examples demonstrate both approaches...\r\n  testdrawline();      \/\/ Draw many lines\r\n  testdrawrect();      \/\/ Draw rectangles (outlines)\r\n  testfillrect();      \/\/ Draw rectangles (filled)\r\n  testdrawcircle();    \/\/ Draw circles (outlines)\r\n  testfillcircle();    \/\/ Draw circles (filled)\r\n  testdrawroundrect(); \/\/ Draw rounded rectangles (outlines)\r\n  testfillroundrect(); \/\/ Draw rounded rectangles (filled)\r\n  testdrawtriangle();  \/\/ Draw triangles (outlines)\r\n  testfilltriangle();  \/\/ Draw triangles (filled)\r\n  testdrawchar();      \/\/ Draw characters of the default font\r\n  testdrawstyles();    \/\/ Draw 'stylized' characters\r\n  testscrolltext();    \/\/ Draw scrolling text\r\n  testdrawbitmap();    \/\/ Draw a small bitmap image\r\n  \/\/ Invert and restore display, pausing in-between\r\n  display.invertDisplay(true);\r\n  delay(1000);\r\n  display.invertDisplay(false);\r\n  delay(1000);\r\n  testanimate(logo_bmp, LOGO_WIDTH, LOGO_HEIGHT); \/\/ Animate bitmaps\r\n}\r\nvoid loop() {\r\n}\r\nvoid testdrawline() {\r\n  int16_t i;\r\n  display.clearDisplay(); \/\/ Clear display buffer\r\n  for(i=0; i&lt;display.width(); i+=4) {\r\n    display.drawLine(0, 0, i, display.height()-1, WHITE);\r\n    display.display(); \/\/ Update screen with each newly-drawn line\r\n    delay(1);\r\n  }\r\n  for(i=0; i&lt;display.height(); i+=4) {\r\n    display.drawLine(0, 0, display.width()-1, i, WHITE);\r\n    display.display();\r\n    delay(1);\r\n  }\r\n  delay(250);\r\n  display.clearDisplay();\r\n  for(i=0; i&lt;display.width(); i+=4) {\r\n    display.drawLine(0, display.height()-1, i, 0, WHITE);\r\n    display.display();\r\n    delay(1);\r\n  }\r\n  for(i=display.height()-1; i&gt;=0; i-=4) {\r\n    display.drawLine(0, display.height()-1, display.width()-1, i, WHITE);\r\n    display.display();\r\n    delay(1);\r\n  }\r\n  delay(250);\r\n  display.clearDisplay();\r\n  for(i=display.width()-1; i&gt;=0; i-=4) {\r\n    display.drawLine(display.width()-1, display.height()-1, i, 0, WHITE);\r\n    display.display();\r\n    delay(1);\r\n  }\r\n  for(i=display.height()-1; i&gt;=0; i-=4) {\r\n    display.drawLine(display.width()-1, display.height()-1, 0, i, WHITE);\r\n    display.display();\r\n    delay(1);\r\n  }\r\n  delay(250);\r\n  display.clearDisplay();\r\n  for(i=0; i&lt;display.height(); i+=4) {\r\n    display.drawLine(display.width()-1, 0, 0, i, WHITE);\r\n    display.display();\r\n    delay(1);\r\n  }\r\n  for(i=0; i&lt;display.width(); i+=4) {\r\n    display.drawLine(display.width()-1, 0, i, display.height()-1, WHITE);\r\n    display.display();\r\n    delay(1);\r\n  }\r\n  delay(2000); \/\/ Pause for 2 seconds\r\n}\r\nvoid testdrawrect(void) {\r\n  display.clearDisplay();\r\n  for(int16_t i=0; i&lt;display.height()\/2; i+=2) {\r\n    display.drawRect(i, i, display.width()-2*i, display.height()-2*i, WHITE);\r\n    display.display(); \/\/ Update screen with each newly-drawn rectangle\r\n    delay(1);\r\n  }\r\n  delay(2000);\r\n}\r\nvoid testfillrect(void) {\r\n  display.clearDisplay();\r\n  for(int16_t i=0; i&lt;display.height()\/2; i+=3) {\r\n    \/\/ The INVERSE color is used so rectangles alternate white\/black\r\n    display.fillRect(i, i, display.width()-i*2, display.height()-i*2, INVERSE);\r\n    display.display(); \/\/ Update screen with each newly-drawn rectangle\r\n    delay(1);\r\n  }\r\n  delay(2000);\r\n}\r\nvoid testdrawcircle(void) {\r\n  display.clearDisplay();\r\n  for(int16_t i=0; i&lt;max(display.width(),display.height())\/2; i+=2) {\r\n    display.drawCircle(display.width()\/2, display.height()\/2, i, WHITE);\r\n    display.display();\r\n    delay(1);\r\n  }\r\n  delay(2000);\r\n}\r\nvoid testfillcircle(void) {\r\n  display.clearDisplay();\r\n  for(int16_t i=max(display.width(),display.height())\/2; i&gt;0; i-=3) {\r\n    \/\/ The INVERSE color is used so circles alternate white\/black\r\n    display.fillCircle(display.width() \/ 2, display.height() \/ 2, i, INVERSE);\r\n    display.display(); \/\/ Update screen with each newly-drawn circle\r\n    delay(1);\r\n  }\r\n  delay(2000);\r\n}\r\nvoid testdrawroundrect(void) {\r\n  display.clearDisplay();\r\n  for(int16_t i=0; i&lt;display.height()\/2-2; i+=2) {\r\n    display.drawRoundRect(i, i, display.width()-2*i, display.height()-2*i,\r\n      display.height()\/4, WHITE);\r\n    display.display();\r\n    delay(1);\r\n  }\r\n  delay(2000);\r\n}\r\nvoid testfillroundrect(void) {\r\n  display.clearDisplay();\r\n  for(int16_t i=0; i&lt;display.height()\/2-2; i+=2) {\r\n    \/\/ The INVERSE color is used so round-rects alternate white\/black\r\n    display.fillRoundRect(i, i, display.width()-2*i, display.height()-2*i,\r\n      display.height()\/4, INVERSE);\r\n    display.display();\r\n    delay(1);\r\n  }\r\n  delay(2000);\r\n}\r\nvoid testdrawtriangle(void) {\r\n  display.clearDisplay();\r\n  for(int16_t i=0; i&lt;max(display.width(),display.height())\/2; i+=5) {\r\n    display.drawTriangle(\r\n      display.width()\/2  , display.height()\/2-i,\r\n      display.width()\/2-i, display.height()\/2+i,\r\n      display.width()\/2+i, display.height()\/2+i, WHITE);\r\n    display.display();\r\n    delay(1);\r\n  }\r\n  delay(2000);\r\n}\r\nvoid testfilltriangle(void) {\r\n  display.clearDisplay();\r\n  for(int16_t i=max(display.width(),display.height())\/2; i&gt;0; i-=5) {\r\n    \/\/ The INVERSE color is used so triangles alternate white\/black\r\n    display.fillTriangle(\r\n      display.width()\/2  , display.height()\/2-i,\r\n      display.width()\/2-i, display.height()\/2+i,\r\n      display.width()\/2+i, display.height()\/2+i, INVERSE);\r\n    display.display();\r\n    delay(1);\r\n  }\r\n  delay(2000);\r\n}\r\nvoid testdrawchar(void) {\r\n  display.clearDisplay();\r\n  display.setTextSize(1);      \/\/ Normal 1:1 pixel scale\r\n  display.setTextColor(WHITE); \/\/ Draw white text\r\n  display.setCursor(0, 0);     \/\/ Start at top-left corner\r\n  display.cp437(true);         \/\/ Use full 256 char 'Code Page 437' font\r\n  \/\/ Not all the characters will fit on the display. This is normal.\r\n  \/\/ Library will draw what it can and the rest will be clipped.\r\n  for(int16_t i=0; i&lt;256; i++) {\r\n    if(i == '\\n') display.write(' ');\r\n    else          display.write(i);\r\n  }\r\n  display.display();\r\n  delay(2000);\r\n}\r\nvoid testdrawstyles(void) {\r\n  display.clearDisplay();\r\n  display.setTextSize(1);             \/\/ Normal 1:1 pixel scale\r\n  display.setTextColor(WHITE);        \/\/ Draw white text\r\n  display.setCursor(0,0);             \/\/ Start at top-left corner\r\n  display.println(F(\"Hello, world!\"));\r\n  display.setTextColor(BLACK, WHITE); \/\/ Draw 'inverse' text\r\n  display.println(3.141592);\r\n  display.setTextSize(2);             \/\/ Draw 2X-scale text\r\n  display.setTextColor(WHITE);\r\n  display.print(F(\"0x\")); display.println(0xDEADBEEF, HEX);\r\n  display.display();\r\n  delay(2000);\r\n}\r\nvoid testscrolltext(void) {\r\n  display.clearDisplay();\r\n  display.setTextSize(2); \/\/ Draw 2X-scale text\r\n  display.setTextColor(WHITE);\r\n  display.setCursor(10, 0);\r\n  display.println(F(\"scroll\"));\r\n  display.display();      \/\/ Show initial text\r\n  delay(100);\r\n  \/\/ Scroll in various directions, pausing in-between:\r\n  display.startscrollright(0x00, 0x0F);\r\n  delay(2000);\r\n  display.stopscroll();\r\n  delay(1000);\r\n  display.startscrollleft(0x00, 0x0F);\r\n  delay(2000);\r\n  display.stopscroll();\r\n  delay(1000);\r\n  display.startscrolldiagright(0x00, 0x07);\r\n  delay(2000);\r\n  display.startscrolldiagleft(0x00, 0x07);\r\n  delay(2000);\r\n  display.stopscroll();\r\n  delay(1000);\r\n}\r\nvoid testdrawbitmap(void) {\r\n  display.clearDisplay();\r\n  display.drawBitmap(\r\n    (display.width()  - LOGO_WIDTH ) \/ 2,\r\n    (display.height() - LOGO_HEIGHT) \/ 2,\r\n    logo_bmp, LOGO_WIDTH, LOGO_HEIGHT, 1);\r\n  display.display();\r\n  delay(1000);\r\n}\r\n#define XPOS   0 \/\/ Indexes into the 'icons' array in function below\r\n#define YPOS   1\r\n#define DELTAY 2\r\nvoid testanimate(const uint8_t *bitmap, uint8_t w, uint8_t h) {\r\n  int8_t f, icons[NUMFLAKES][3];\r\n  \/\/ Initialize 'snowflake' positions\r\n  for(f=0; f&lt; NUMFLAKES; f++) {\r\n    icons[f][XPOS]   = random(1 - LOGO_WIDTH, display.width());\r\n    icons[f][YPOS]   = -LOGO_HEIGHT;\r\n    icons[f][DELTAY] = random(1, 6);\r\n    Serial.print(F(\"x: \"));\r\n    Serial.print(icons[f][XPOS], DEC);\r\n    Serial.print(F(\" y: \"));\r\n    Serial.print(icons[f][YPOS], DEC);\r\n    Serial.print(F(\" dy: \"));\r\n    Serial.println(icons[f][DELTAY], DEC);\r\n  }\r\n  for(;;) { \/\/ Loop forever...\r\n    display.clearDisplay(); \/\/ Clear the display buffer\r\n    \/\/ Draw each snowflake:\r\n    for(f=0; f&lt; NUMFLAKES; f++) {\r\n      display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, WHITE);\r\n    }\r\n    display.display(); \/\/ Show the display buffer on the screen\r\n    delay(200);        \/\/ Pause for 1\/10 second\r\n    \/\/ Then update coordinates of each flake...\r\n    for(f=0; f&lt; NUMFLAKES; f++) {\r\n      icons[f][YPOS] += icons[f][DELTAY];\r\n      \/\/ If snowflake is off the bottom of the screen...\r\n      if (icons[f][YPOS] &gt;= display.height()) {\r\n        \/\/ Reinitialize to a random position, just off the top\r\n        icons[f][XPOS]   = random(1 - LOGO_WIDTH, display.width());\r\n        icons[f][YPOS]   = -LOGO_HEIGHT;\r\n        icons[f][DELTAY] = random(1, 6);\r\n      }\r\n    }\r\n  }\r\n}<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Had problems at first thinking it dead, but turned out they sent me a 128x32 size, not a 128x64 as ordered, and it won't run the 128x64 sketch if those parameters are not correct. No backlight with OLEDs either to see any function until it runs a sketch or not! It does run on 5V <a href=\"https:\/\/stevepedwards.today\/ElectronicsStuff\/alftek-0-96inch-i2c-iic-serial-128x32-blue-oled-display-module-for-arduino\/\" class=\"more-link\">...<span class=\"screen-reader-text\">  Alftek 0.96inch I2C IIC Serial 128&#215;32 Blue OLED Display Module for Arduino<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,2],"tags":[],"class_list":["post-8545","post","type-post","status-publish","format-standard","hentry","category-tech-studies","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/stevepedwards.today\/ElectronicsStuff\/wp-json\/wp\/v2\/posts\/8545","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/stevepedwards.today\/ElectronicsStuff\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/stevepedwards.today\/ElectronicsStuff\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/stevepedwards.today\/ElectronicsStuff\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/stevepedwards.today\/ElectronicsStuff\/wp-json\/wp\/v2\/comments?post=8545"}],"version-history":[{"count":1,"href":"https:\/\/stevepedwards.today\/ElectronicsStuff\/wp-json\/wp\/v2\/posts\/8545\/revisions"}],"predecessor-version":[{"id":9862,"href":"https:\/\/stevepedwards.today\/ElectronicsStuff\/wp-json\/wp\/v2\/posts\/8545\/revisions\/9862"}],"wp:attachment":[{"href":"https:\/\/stevepedwards.today\/ElectronicsStuff\/wp-json\/wp\/v2\/media?parent=8545"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/stevepedwards.today\/ElectronicsStuff\/wp-json\/wp\/v2\/categories?post=8545"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/stevepedwards.today\/ElectronicsStuff\/wp-json\/wp\/v2\/tags?post=8545"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}