Hiletgo 128x64 and Teensy LC

Status
Not open for further replies.

tenorjazz

Active member
I recently purchased a little Hiletgo 128x64 OLED I2C Display but have zero luck in getting it to do anything. I tried the Adafruit 1306 library and examples but can't even get it to "light up". Can anybody help me get this thing going?
 
Did you read the forum rules above? (Forum Rule: Always post complete source code & details to reproduce any issue!)

Without seeing your wiring diagram and a picture of your setup, nobody can guess the cause of your issue. And your code is needed too, to see if you send the correct command over I2C to switch the OLED's internal SMPS on...
 
I know the rules on posting but I haven't built any special circuit or written any code, just trying to figure out how to get it running. However, here is how I hooked it up and what follows is some example code I just cut and pasted. I don't understand how this is suppose to work except connect the correct wires, include a library and run some sample code. I am sure it is connected correctly (4 wires) and the library and example code looked like the right thing.

HiLetgo 128x64 Circuit Cropped.jpg


/*********************************************************************
This is an example for our Monochrome OLEDs based on SSD1306 drivers

Pick one up today in the adafruit shop!
------> http://www.adafruit.com/category/63_98

This example is for a 128x64 size display using I2C to communicate
3 pins are required to interface (2 I2C and one reset)

Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!

Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, check license.txt for more information
All text above, and the splash screen must be included in any redistribution
*********************************************************************/

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2


#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH 16
static const unsigned char PROGMEM logo16_glcd_bmp[] =
{ B00000000, B11000000,
B00000001, B11000000,
B00000001, B11000000,
B00000011, B11100000,
B11110011, B11100000,
B11111110, B11111000,
B01111110, B11111111,
B00110011, B10011111,
B00011111, B11111100,
B00001101, B01110000,
B00011011, B10100000,
B00111111, B11100000,
B00111111, B11110000,
B01111100, B11110000,
B01110000, B01110000,
B00000000, B00110000 };

#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

void setup() {
Serial.begin(9600);

// by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
display.begin(SSD1306_SWITCHCAPVCC, 0x3D); // initialize with the I2C addr 0x3D (for the 128x64)
// init done

// Show image buffer on the display hardware.
// Since the buffer is intialized with an Adafruit splashscreen
// internally, this will display the splashscreen.
display.display();
delay(2000);

// Clear the buffer.
display.clearDisplay();

// draw a single pixel
display.drawPixel(10, 10, WHITE);
// Show the display buffer on the hardware.
// NOTE: You _must_ call display after making any drawing commands
// to make them visible on the display hardware!
display.display();
delay(2000);
display.clearDisplay();

// draw many lines
testdrawline();
display.display();
delay(2000);
display.clearDisplay();

// draw rectangles
testdrawrect();
display.display();
delay(2000);
display.clearDisplay();

// draw multiple rectangles
testfillrect();
display.display();
delay(2000);
display.clearDisplay();

// draw mulitple circles
testdrawcircle();
display.display();
delay(2000);
display.clearDisplay();

// draw a white circle, 10 pixel radius
display.fillCircle(display.width()/2, display.height()/2, 10, WHITE);
display.display();
delay(2000);
display.clearDisplay();

testdrawroundrect();
delay(2000);
display.clearDisplay();

testfillroundrect();
delay(2000);
display.clearDisplay();

testdrawtriangle();
delay(2000);
display.clearDisplay();

testfilltriangle();
delay(2000);
display.clearDisplay();

// draw the first ~12 characters in the font
testdrawchar();
display.display();
delay(2000);
display.clearDisplay();

// draw scrolling text
testscrolltext();
delay(2000);
display.clearDisplay();

// text display tests
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.println("Hello, world!");
display.setTextColor(BLACK, WHITE); // 'inverted' text
display.println(3.141592);
display.setTextSize(2);
display.setTextColor(WHITE);
display.print("0x"); display.println(0xDEADBEEF, HEX);
display.display();
delay(2000);
display.clearDisplay();

// miniature bitmap display
display.drawBitmap(30, 16, logo16_glcd_bmp, 16, 16, 1);
display.display();
delay(1);

// invert the display
display.invertDisplay(true);
delay(1000);
display.invertDisplay(false);
delay(1000);
display.clearDisplay();

// draw a bitmap icon and 'animate' movement
testdrawbitmap(logo16_glcd_bmp, LOGO16_GLCD_HEIGHT, LOGO16_GLCD_WIDTH);
}


void loop() {

}


void testdrawbitmap(const uint8_t *bitmap, uint8_t w, uint8_t h) {
uint8_t icons[NUMFLAKES][3];

// initialize
for (uint8_t f=0; f< NUMFLAKES; f++) {
icons[f][XPOS] = random(display.width());
icons[f][YPOS] = 0;
icons[f][DELTAY] = random(5) + 1;

Serial.print("x: ");
Serial.print(icons[f][XPOS], DEC);
Serial.print(" y: ");
Serial.print(icons[f][YPOS], DEC);
Serial.print(" dy: ");
Serial.println(icons[f][DELTAY], DEC);
}

while (1) {
// draw each icon
for (uint8_t f=0; f< NUMFLAKES; f++) {
display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, WHITE);
}
display.display();
delay(200);

// then erase it + move it
for (uint8_t f=0; f< NUMFLAKES; f++) {
display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, BLACK);
// move it
icons[f][YPOS] += icons[f][DELTAY];
// if its gone, reinit
if (icons[f][YPOS] > display.height()) {
icons[f][XPOS] = random(display.width());
icons[f][YPOS] = 0;
icons[f][DELTAY] = random(5) + 1;
}
}
}
}


void testdrawchar(void) {
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);

for (uint8_t i=0; i < 168; i++) {
if (i == '\n') continue;
display.write(i);
if ((i > 0) && (i % 21 == 0))
display.println();
}
display.display();
delay(1);
}

void testdrawcircle(void) {
for (int16_t i=0; i<display.height(); i+=2) {
display.drawCircle(display.width()/2, display.height()/2, i, WHITE);
display.display();
delay(1);
}
}

void testfillrect(void) {
uint8_t color = 1;
for (int16_t i=0; i<display.height()/2; i+=3) {
// alternate colors
display.fillRect(i, i, display.width()-i*2, display.height()-i*2, color%2);
display.display();
delay(1);
color++;
}
}

void testdrawtriangle(void) {
for (int16_t i=0; i<min(display.width(),display.height())/2; i+=5) {
display.drawTriangle(display.width()/2, display.height()/2-i,
display.width()/2-i, display.height()/2+i,
display.width()/2+i, display.height()/2+i, WHITE);
display.display();
delay(1);
}
}

void testfilltriangle(void) {
uint8_t color = WHITE;
for (int16_t i=min(display.width(),display.height())/2; i>0; i-=5) {
display.fillTriangle(display.width()/2, display.height()/2-i,
display.width()/2-i, display.height()/2+i,
display.width()/2+i, display.height()/2+i, WHITE);
if (color == WHITE) color = BLACK;
else color = WHITE;
display.display();
delay(1);
}
}

void testdrawroundrect(void) {
for (int16_t i=0; i<display.height()/2-2; i+=2) {
display.drawRoundRect(i, i, display.width()-2*i, display.height()-2*i, display.height()/4, WHITE);
display.display();
delay(1);
}
}

void testfillroundrect(void) {
uint8_t color = WHITE;
for (int16_t i=0; i<display.height()/2-2; i+=2) {
display.fillRoundRect(i, i, display.width()-2*i, display.height()-2*i, display.height()/4, color);
if (color == WHITE) color = BLACK;
else color = WHITE;
display.display();
delay(1);
}
}

void testdrawrect(void) {
for (int16_t i=0; i<display.height()/2; i+=2) {
display.drawRect(i, i, display.width()-2*i, display.height()-2*i, WHITE);
display.display();
delay(1);
}
}

void testdrawline() {
for (int16_t i=0; i<display.width(); i+=4) {
display.drawLine(0, 0, i, display.height()-1, WHITE);
display.display();
delay(1);
}
for (int16_t i=0; i<display.height(); i+=4) {
display.drawLine(0, 0, display.width()-1, i, WHITE);
display.display();
delay(1);
}
delay(250);

display.clearDisplay();
for (int16_t i=0; i<display.width(); i+=4) {
display.drawLine(0, display.height()-1, i, 0, WHITE);
display.display();
delay(1);
}
for (int16_t i=display.height()-1; i>=0; i-=4) {
display.drawLine(0, display.height()-1, display.width()-1, i, WHITE);
display.display();
delay(1);
}
delay(250);

display.clearDisplay();
for (int16_t i=display.width()-1; i>=0; i-=4) {
display.drawLine(display.width()-1, display.height()-1, i, 0, WHITE);
display.display();
delay(1);
}
for (int16_t i=display.height()-1; i>=0; i-=4) {
display.drawLine(display.width()-1, display.height()-1, 0, i, WHITE);
display.display();
delay(1);
}
delay(250);

display.clearDisplay();
for (int16_t i=0; i<display.height(); i+=4) {
display.drawLine(display.width()-1, 0, 0, i, WHITE);
display.display();
delay(1);
}
for (int16_t i=0; i<display.width(); i+=4) {
display.drawLine(display.width()-1, 0, i, display.height()-1, WHITE);
display.display();
delay(1);
}
delay(250);
}

void testscrolltext(void) {
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(10,0);
display.clearDisplay();
display.println("scroll");
display.display();
delay(1);

display.startscrollright(0x00, 0x0F);
delay(2000);
display.stopscroll();
delay(1000);
display.startscrollleft(0x00, 0x0F);
delay(2000);
display.stopscroll();
delay(1000);
display.startscrolldiagright(0x00, 0x07);
delay(2000);
display.startscrolldiagleft(0x00, 0x07);
delay(2000);
display.stopscroll();
}
 
First thing would be checking the I2C signals with an oscilloscope if they look clean or if the code bugs already before or if you need to add pull up resistors to the bus.
Second thing would be making sure that the I2C clock used by the library is not higher that the display might „digest“.
Third thing is to make sure that the power consumption of the display is lower than 100mA which is highly improbable. But the voltage regulator on the LC board can not do more. Did you try to power the OLED separately from a lab power supply?
Last thing is to do a differential diagnose: try to run your oled from an Arduino Mega and try to run aTeensyview oled from the LC. This cross diagnose allows to verify each component for proper operation.
When you are sure that none of your components is defective, run first one of the I2C example sketches to see if the oled responds, and if yes, at which base address.
 
Last edited:
I hooked it up to my Mega (using the same setup) and had the same results. I don't have an oscilloscope yet so debugging things have been hard. My guess is that it might be defective so I have decided to send back. I am currently looking for a different display. I am a real newbe at all this so struggling to figure out what works with what. I think what I want is some kind of display that I can display some graphics on. I have been building a fancy midi controller and have a lot of it working but one thing I thought would be nice is a graphical way to represent the volume faders. Any suggestions would be appreciated. I am also moving up to a Teensy 3.6 from the an LC. The LC has been working great so far but I have been struggling with getting enough analog inputs. I really need about 35 of them. I have a 74HC4067 multiplexer driving 16 analog ports on a bread board but can't seem to get it wired up and working (I know that's weird and just shouldn't happen, but I have failed 3 times to successfully make a build work). As far as I know there is no other multiplexers that will let me do analog. I have also thought of tying a bunch of Teensy LCs together on an I2C or some other bus and using the analog inputs off them (I'm prototyping some code for this right now to see if I can get that working).
 
Sigi... I was looking at buying Adafuit-Products to match their lib but they also need to work with Teensy. It's all a bit confusing for me.
 
If the display you have is the same as the one on Amazon: https://www.amazon.com/HiLetgo-Serial-128X64-Display-Color/dp/B06XRBTBTB it appears to have 4.7k pullups installed on the SDA & SCK lines so that's probably not your problem.

However, in the Q&A section on that page one reply states that the I2C address in 0x3C. The Adafruit code you posted (you really should enclose posted code within 'code" tags - use the "#" button when posting) assumes the display address is 0x3D. So it's likely you have an address mismatch. You can try changing the default address in the Adafruit code to 0x3C or, better still, run the I2C scanner found in the examples provided in Teensyduino and use the address discovered by it. My OLED I2C displays are at 0x5C.

If no device is discovered, you either have a wiring issue or a bad display.

In any case, running the scanner is faster than returning the display and finding another.
 
This really looks like it should "just work" with Adafruit's lib.

According to this schematic, it already has the pullup resistors and a simple reset circuit.

51saMrSD4pL._SL1272_.jpg


As a first sanity check, I'd measure the voltage on VCC_IN, SDA and SCL when the display is idle. All should be approx 3.3V.

If that doesn't help, maybe post some details photos to show us exactly how all the wires are connected. Often times these sorts of "should work" things fail due to a simple wiring mistake or misunderstanding. We can't help you unless we can actually see the wires!
 
I did check the wiring multiple times and I as mentioned earlier, I tried it on my Mega with the same results.

I think there was something wrong with the display so sent it back. I will probably order another one but need to put it on a the back burner for now, I just ran into a much more concerning problem.

As I also mentioned earlier the display is for a fairly complex midi controller I am building to use with Ableton Live. When I get it closer to completion and get most of the modules working, which I am very close to getting done, I will create a post detailing how and why I did things.

The bigger problem I just ran into is that while testing, I am mapping the controls using Ableton's Midi Map mode. What I just discovered is that it is not keeping the mappings between sessions. I have already invested a huge amount of time into this project so need to figure this out before going any further.
 
I did check the wiring multiple times and I as mentioned earlier, I tried it on my Mega with the same results.

I am not sure you understood the problem @dgranger found:

Your code has
Code:
 display.begin(SSD1306_SWITCHCAPVCC, 0x3D); // initialize with the I2C addr 0x3D (for the 128x64)

But your display uses according the description 0x3C (which you could find out with the recommended use of a I2C scanning sketch. For 99% you returned a working part..
 
I used the I2C scanning sketch and it said it couldn't find any I2C devices connected. In the end that is why I returned the display.
 
Thank you everyone for your replies, they were very helpful. I hope to get a new display in the near future and will follow your advice on how to get it working.
 
i use these displays all the time with my 3.2 and Adafruit libs, as sigi stated are you sure you display address is 0x3D? sounds odd... try initializing with:

display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

check the 0 ohm jumper on the back of the display (assuming yours has one). it will probably say 0x78 or 0x7A (it's an 8 bit and needs to be converted to a 7 bit required by the lib)
 
OK, I just ordered a new Display from Amazon.

Diymall 0.96" Inch I2c IIC Serial 128x64 Oled LCD LED White Display Module for Arduino 51 Msp420 Stim32 SCR

The description says you can change the I2C address, which is a good thing, because I was hoping to use multiple displays in my next project.

BTW, just got a new Teensy 3.6 today. I needed the extra analog inputs and look forward to the increase in performance over the LC. Going to try and get it going tomorrow. It also frees up my 2 LC's for the next couple of projects I have planned.

Paul, thanks so much for all your help.
 
Status
Not open for further replies.
Back
Top