Teensy 3.1 with I2C OLED and SH1106 Controller

Status
Not open for further replies.

4styler

Member
Hello,

i'am new here. I apologize in advance for my bad english. But i hope you understand me :). I'am new with Teensy. I have a little bit experience with Arduino and I2C. I have the same Display running with an Arduino and it is working fine. Now
i would to move my project to an Teensy but i get trouble with my SainSmart I2C OLED Display with an SH1106 controller. At the moment i try to get that code running:

Code:
#include "Arduino.h"
#include "U8glib.h"
#include <i2c_t3.h>

// setup u8g object, please remove comment from one of the following constructor calls
// IMPORTANT NOTE: The following list is incomplete. The complete list of supported 
// devices with all constructor calls is here: https://github.com/olikraus/u8glib/wiki/device

U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_FAST);	// Dev 0, Fast I2C / TWI

  byte error;
  int ok;
  byte address;
  int nDevices;
  
void draw(void) {
  // graphic commands to redraw the complete screen should be placed here  
  u8g.setFont(u8g_font_unifont);
  //u8g.setFont(u8g_font_osb21);
  u8g.drawStr( 0, 22, "Hello World!");
}

void setup(void) {
  delay (1000);
 ok = 1;
 Wire.begin();
  Serial.begin(9600);
  Serial.println("\nI2C Scanner");
//####################################################
while (ok <= 2) {
      Serial.println("Scanning...");
     
      nDevices = 0;
      for(address = 1; address < 127; address++ )
      {
        // The i2c_scanner uses the return value of
        // the Write.endTransmisstion to see if
        // a device did acknowledge to the address.
        Wire.beginTransmission(address);
        error = Wire.endTransmission();
     
        if (error == 0)
        {
          Serial.print("I2C device found at address 0x");
          if (address<16)
            Serial.print("0");
          Serial.print(address,HEX);
          Serial.println("  !");
          nDevices++;
          ok = 3;
        }
        else if (error==4)
        {
          Serial.print("Unknow error at address 0x");
          if (address<16)
            Serial.print("0");
          Serial.println(address,HEX);
        }    
      }
      if (nDevices == 0)
        Serial.println("No I2C devices found\n");
      else
        Serial.println("done\n");
     
      delay(50);           // wait 5 seconds for next scan
}

//####################################################
  
  // flip screen, if required
  // u8g.setRot180();
  
  // set SPI backup if required
  //u8g.setHardwareBackup(u8g_backup_avr_spi);

  // assign default color value
  if ( u8g.getMode() == U8G_MODE_R3G3B2 ) {
    u8g.setColorIndex(255);     // white
  }
  else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
    u8g.setColorIndex(3);         // max intensity
  }
  else if ( u8g.getMode() == U8G_MODE_BW ) {
    u8g.setColorIndex(1);         // pixel on
  }
  else if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
    u8g.setHiColorByRGB(255,255,255);
  }
}

void loop(void) {

  // picture loop
  u8g.firstPage();  
  do {
    draw();
  } while( u8g.nextPage() );
  
  // rebuild the picture after some delay
  delay(50);
}

i get than this response in the Serial Terminal:

I2C Scanner
Scanning...
I2C device found at address 0x3C !
done

so i think that I2C is running. But my display doesn't showes anything. I would to use the u8glib for that.

I didn't have build in the pullup resistors. But i have 4,7 kOHM here. Do i need they because the I2C is responding.

Is hat possible to get any help for that?

I hope for a positive response.

Greetings
4styler

Edit1:

Sorry i will get that compiler errors too (only by the first compiling):
C:\Users\xxxxxxx\Documents\Arduino\libraries\U8glib\utility\u8g_com_i2c.c:44:16: warning: 'u8g_i2c_opt' defined but not used [-Wunused-variable]
static uint8_t u8g_i2c_opt; /* U8G_I2C_OPT_NO_ACK, SAM: U8G_I2C_OPT_DEV_1 */
^
C:\Users\xxxxxxxx\Documents\Arduino\libraries\U8glib\utility\u8g_rot.c:48:1: warning: initialization from incompatible pointer type [enabled by default]
u8g_dev_t u8g_dev_rot = { u8g_dev_rot_dummy_fn, NULL, NULL };
^
C:\Users\xxxxxxxx\Documents\Arduino\libraries\U8glib\utility\u8g_rot.c:48:1: warning: (near initialization for 'u8g_dev_rot.dev_fn') [enabled by default]

Edit2:

I have added 2 4,7kOhm restors between 3 volt and Pin 18, 19. It didn't work :(
 
Last edited:
Hello Again,

after yesterday and today, i'am try to get an solution i have found that here:
https://forum.pjrc.com/threads/28944-Library-for-128-by-64-OLED-I2C-Display?highlight=sh1106

i have read it many times, but i didn't got it. Now i have tried it and get it working.

For all others with the same problem:

I have done step 10 of the above thread. Than i have checked step 13.

Than i have changed my code from the last post:

Code:
#include <U8glib.h>
#include <u8g_i2c.h>
#include <Arduino.h>
#include <i2c_t3.h>

u8g_t u8g;

  byte error;
  int ok;
  byte address;
  int nDevices;
  
void draw(void) {

}

void setup(void) {
  delay (1000);
 ok = 1;
 Wire.begin();
  Serial.begin(9600);
  Serial.println("\nI2C Scanner");
//####################################################
while (ok <= 2) {
      Serial.println("Scanning...");
     
      nDevices = 0;
      for(address = 1; address < 127; address++ )
      {
        // The i2c_scanner uses the return value of
        // the Write.endTransmisstion to see if
        // a device did acknowledge to the address.
        Wire.beginTransmission(address);
        error = Wire.endTransmission();
     
        if (error == 0)
        {
          Serial.print("I2C device found at address 0x");
          if (address<16)
            Serial.print("0");
          Serial.print(address,HEX);
          Serial.println("  !");
          nDevices++;
          ok = 3;
        }
        else if (error==4)
        {
          Serial.print("Unknow error at address 0x");
          if (address<16)
            Serial.print("0");
          Serial.println(address,HEX);
        }    
      }
      if (nDevices == 0)
        Serial.println("No I2C devices found\n");
      else
        Serial.println("done\n");
     
      delay(50);           // wait 5 seconds for next scan
}

//####################################################
  
  // flip screen, if required
  // u8g.setRot180();
  
  // set SPI backup if required
  //u8g.setHardwareBackup(u8g_backup_avr_spi);

  // assign default color value

    u8g_InitComFn(&u8g, &u8g_dev_ssd1306_128x32_i2c, u8g_com_hw_i2c_fn);
    
}
void loop(void) {

  // picture loop
  u8g_FirstPage(&u8g);  
  do {
  // graphic commands to redraw the complete screen should be placed here  
  u8g_SetFont(&u8g, u8g_font_unifont);
  //u8g.setFont(u8g_font_osb21);
  u8g_DrawStr(&u8g, 0, 22, "Hello World!");
  } while( u8g_NextPage(&u8g) );
  
  // rebuild the picture after some delay
  delay(50);
}

But you can minimize it to that:

Code:
#include <U8glib.h>
#include <u8g_i2c.h>
#include <i2c_t3.h>

u8g_t u8g;

void setup(void) {
     u8g_InitComFn(&u8g, &u8g_dev_ssd1306_128x32_i2c, u8g_com_hw_i2c_fn);
   }
void loop(void) {
  u8g_FirstPage(&u8g);  
  do {
  u8g_SetFont(&u8g, u8g_font_unifont);
  u8g_DrawStr(&u8g, 0, 22, "Hello World!");
  } while( u8g_NextPage(&u8g) );
    // rebuild the picture after some delay
  delay(50);
}

I have used that line:
u8g_InitComFn(&u8g, &u8g_dev_ssd1306_128x32_i2c, u8g_com_hw_i2c_fn);
instead of that:
u8g_InitComFn(&u8g, &u8g_dev_sh1106_128x64_i2c, u8g_com_hw_i2c_fn);
because i have a 128x32 display. It works great.

I hope i could help some people. A Very Very Very big thanks to mxxx. How can i learn that?

Sorry that i opend that thread.

Have a nice evening.

Greetings

4styler
 
I hope i could help some people. A Very Very Very big thanks to mxxx. How can i learn that?

Sorry that i opend that thread.

Have a nice evening.

Greetings

4styler


well, glad it helped someone. you can probably speed up things a little with using the 2x device function, ie:

Code:
u8g_InitComFn(&u8g, &u8g_dev_ssd1306_128x64_[B]2x[/B]_i2c, u8g_com_hw_i2c_fn);
 
Hello Again,

now i get that problem:
Teensy_3.1.ino:319:38: error: cannot convert 'float' to 'const char*' for argument '4' to 'u8g_uint_t u8g_DrawStr(u8g_t*, u8g_uint_t, u8g_uint_t, const char*)'

I get the same trouble with double and smth like that.

can you help me to use float with your u8g_i2c library?

Greetings
4styler
 
Last edited:
Maybe something like this?

Code:
char buffer[64];
sprintf(buffer, "%f", myFloatVariable);
u8g_DrawStr(&u8g, 0, 22, buffer);
 
Hello Paul,

thank you for your quick response.

I have tried it, and it seems to work. but i didn't know if my Display will show it because i didn't see my display ;).

I have changed my code to that:
Code:
#include <U8glib.h>
#include <u8g_i2c.h>
#include <i2c_t3.h>

u8g_t u8g;

int test1 = 10;
float test2 = 10.10;
double test3 = 1010.1010;
long double test4 = 10101010.10101010;

char test11[64];
char test12[64];
char test13[64];
char test14[64];

void setup(void) {
     u8g_InitComFn(&u8g, &u8g_dev_ssd1306_128x32_2x_i2c, u8g_com_hw_i2c_fn);
   }
void loop(void) {
  u8g_FirstPage(&u8g);  
  do {
  u8g_SetFont(&u8g, u8g_font_unifont);
  sprintf(test11, "%i", test1);
  u8g_DrawStr(&u8g, 0, 22, test11);
  sprintf(test12, "%lf", test2);
  u8g_DrawStr(&u8g, 0, 22, test12);
  sprintf(test13, "%f", test3);
  u8g_DrawStr(&u8g, 0, 22, test13);
  sprintf(test14, "%Lf", test4);
  u8g_DrawStr(&u8g, 0, 22, test14);
  } while( u8g_NextPage(&u8g) );
    // rebuild the picture after some delay
  delay(50);
}

is that right? Is there a possebility to creat an automatism for that? Perhabs in the u8g_i2c library?
Thank you :)

4styler
 
Last edited:
Is there a possebility to creat an automatism for that? Perhabs in the u8g_i2c library?

well, as noted in the other thread, i got it working by simply adding the i2c com function.

if you want to use "print", i'd suggest you try getting "U8glib for Arduino" to work, after all ( the C++ wrapper). i didn't look into this any further once i got it working with the com function, but i think i remember the reason it didn't seem work with teensy 3.x is simply because u8g_com_i2c.c doesn't have any suitable code. if you look at the file, there's defines for AVR, due and raspberry pi but not teensy 3.x, ie

Code:
#elif defined(ARDUINO) && defined(__SAM3X8E__)
...
Code:
#elif defined(U8G_RASPBERRY_PI)

you'd have to add something along the lines of

Code:
#elif defined(__MK20DX128__) || defined(__MK20DX256__)

and then all the functions needed.
 
Hello mxxx,

sorry, i think you didn't understood me. I mean the following:

is it possible to create an automatic function in the u8g_i2c which will convert int, double and smth like this to chars. At the moment i will do that: sprintf(test11, "%i", test1); for every variable. It would be nice if the u8g_i2c would do that automatically.

do you know what i mean?

Greetings and thanks,
4styler
 
Hello mxxx,

sorry, i think you didn't understood me. I mean the following:

is it possible to create an automatic function in the u8g_i2c which will convert int, double and smth like this to chars. At the moment i will do that: sprintf(test11, "%i", test1); for every variable. It would be nice if the u8g_i2c would do that automatically.

do you know what i mean?

Greetings and thanks,
4styler

maybe i misunderstood. what is said is that using the arduino wrapper is one way of achieving this, as it gives you "print".

you can then simply write, say:

Code:
uint16_t some_int = 100;
u8g.setPrintPos(x, y); 
u8g.print(some_int);

without the wrapper, you can't use print, you have to use u8g_DrawStr(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, const char *s); but you can of course come up with your own int-to-char function using sprintf. i suppose you can put this in u8g_i2c, if you like, but why not simply put it in your sketch?
 
Hello mxxx,

thanks for your help. I will do it with sprintf. You should add
#if defined(__MK20DX128__) || defined(__MK20DX256__)
on the beginning of each file and
#endif
on the end.

Otherwise you cannot compile U8glib for Arduino :)

For all others, i have done the steps in Post 2 and 6.

Have a nice Day and thank you again.

Bye
4styler
 
Status
Not open for further replies.
Back
Top