Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 25 of 25

Thread: Teensy 3.x and SH1106 OLED via SPI

  1. #1

    Teensy 3.x and SH1106 OLED via SPI

    Hi all, first post here. I'm embarking on my first hardware project, based on the Teensy 3.5, inspired by the Ornament & Crime eurorack module. I'm borrowing a lot from the O&C. I have an OLED (SH1106) which I'd like to get working first. A lot of this stuff is new to me, although I'm an experienced software dev. I've followed the O&C schematic as best I can to wire up the OLED to the Teensy on my breadboard, including a 10k resistor to the power and a 100nf cap across the GND and VCC pins on the OLED.

    o_c_rev2e_schematic.pdf

    I've borrowed the display and SPI code from the O&C, and trying initially to get a "Hello world" displayed. I've attached images of my breadboard, if it helps. I've no idea how to debug this stuff. Currently I don't get anything from the display.
    Maybe I should go back and do some of the tutorials (I only played with the LED blink example before this).

    The project in its current state is on Github.

    Click image for larger version. 

Name:	Teensy_OLED_1#2.jpg 
Views:	356 
Size:	233.9 KB 
ID:	9284Click image for larger version. 

Name:	Teensy_OLED_1#3.jpg 
Views:	769 
Size:	231.2 KB 
ID:	9285
    Note: the CS pin on the OLED is attached to a 10k resistor which is not so visible here
    Last edited by adamski; 01-03-2017 at 10:31 PM. Reason: typo

  2. #2
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,135
    your lcd looks cracked. the lcd's CS should be pulled high with the 10k pullup and pulled low in software when the mcu wants to talk to it, and I see your using SPI, I don't see your code, but if you don't SPI.begin(); in setup the SPI will not function properly, if at all.

  3. #3
    Thanks... I added `SPI.begin()`, still blank.

    BTW the OLED isn't cracked just still has the sticker on which looks scratched in the pic..

    I'm wondering where I should start trying to debug this. Probably go and learn a bit more about SPI and the specifics of the SH1106 interface...

  4. #4
    Senior Member
    Join Date
    Feb 2013
    Posts
    563
    Quote Originally Posted by adamski View Post
    Hi all, first post here. I'm embarking on my first hardware project, based on the Teensy 3.5, inspired by the Ornament & Crime eurorack module. I'm borrowing a lot from the O&C. I have an OLED (SH1106) which I'd like to get working first. A lot of this stuff is new to me, although I'm an experienced software dev. I've followed the O&C schematic as best I can to wire up the OLED to the Teensy on my breadboard, including a 10k resistor to the power and a 100nf can across the GND and VCC pins on the OLED.

    o_c_rev2e_schematic.pdf

    I've borrowed the display and SPI code from the O&C, and trying initially to get a "Hello world" displayed. I've attached images of my breadboard, if it helps. I've no idea how to debug this stuff. Currently I don't get anything from the display.
    Maybe I should go back and do some of the tutorials (I only played with the LED blink example before this).

    The project in its current state is on Github.

    Click image for larger version. 

Name:	Teensy_OLED_1#2.jpg 
Views:	356 
Size:	233.9 KB 
ID:	9284Click image for larger version. 

Name:	Teensy_OLED_1#3.jpg 
Views:	769 
Size:	231.2 KB 
ID:	9285
    Note: the CS pin on the OLED is attached to a 10k resistor which is not so visible here
    have you tried the gutted code / set-up works with 3.2?

    anyways, while the OC code as is compiles for 3.6 (and i suppose for 3.5), i think you'd only get static on the display (... is what i've heard. i haven't looked into this myself, because my kickstarter 3.6s got lost in the mail). i'd imagine it must have to do with either some minor difference re SPI and/or DMA (see SH1106_128x64_driver.cpp), but i don't know what. DMAChannel.cpp looks to have been updated for MK66, so maybe it's got to do with SH1106_128x64_Driver::SPI_send(void *bufr, size_t n) or SPI_init (in OC_DAC.cpp), which we've culled from spi4teensy (though SPI0 seems to be the corresponding port).

  5. #5
    Quote Originally Posted by mxxx View Post
    have you tried the gutted code / set-up works with 3.2?
    No I haven't - I don't have a 3.2 here to test with.

    Quote Originally Posted by mxxx View Post
    anyways, while the OC code as is compiles for 3.6 (and i suppose for 3.5), i think you'd only get static on the display (... is what i've heard. i haven't looked into this myself, because my kickstarter 3.6s got lost in the mail). i'd imagine it must have to do with either some minor difference re SPI and/or DMA (see SH1106_128x64_driver.cpp), but i don't know what. DMAChannel.cpp looks to have been updated for MK66, so maybe it's got to do with SH1106_128x64_Driver::SPI_send(void *bufr, size_t n) or SPI_init (in OC_DAC.cpp), which we've culled from spi4teensy (though SPI0 seems to be the corresponding port).
    Thanks for this. Timmy mentioned over on Muff's that the O&C code didn't work on the 3.5/6, I guess this might be one of the reasons why. You've given me some clues here, I'll start digging...

    Although I don't even get static, just blank.

  6. #6

  7. #7
    I uploaded and ran the example at https://github.com/crteensy/DmaSpi, and it seems to be passing all the tests, so thats a start I guess..

  8. #8
    Senior Member
    Join Date
    Feb 2013
    Posts
    563
    yeah, i remember he mentioned something about trying. but i don't think he didn't followed up on it. one thing to make sure is the SPI clock is actually putting out 30MHz, not 60MHz or something, which might be too much for the display to stomach. (see https://github.com/adamski/TeensyOLE...OC_DAC.cpp#L40). but i'm too unfamiliar with 3.5/3.6 to actually give any useful advice

    or you could try an earlier version of the code, when the thing was still using u8glib (here), and none of the DMA/DAC interlacing trickery, so that might be easier to debug. generally speaking, with 3.5/3.6 and the multiple SPI ports, that kind of driver might not even be needed. there's other DMA versions around, i think, so the main remaining advantage would be the per-page updates, if i see it right.

  9. #9
    Quote Originally Posted by mxxx View Post
    yeah, i remember he mentioned something about trying. but i don't think he didn't followed up on it. one thing to make sure is the SPI clock is actually putting out 30MHz, not 60MHz or something, which might be too much for the display to stomach. (see https://github.com/adamski/TeensyOLE...OC_DAC.cpp#L40). but i'm too unfamiliar with 3.5/3.6 to actually give any useful advice

    or you could try an earlier version of the code, when the thing was still using u8glib (here), and none of the DMA/DAC interlacing trickery, so that might be easier to debug. generally speaking, with 3.5/3.6 and the multiple SPI ports, that kind of driver might not even be needed. there's other DMA versions around, i think, so the main remaining advantage would be the per-page updates, if i see it right.
    Thanks, I'll check those points out. I found this library: https://github.com/wonho-maker/Adafruit_SH1106 - managed to get it to compile but it also does not do anything to my OLED..

  10. #10
    I also found a more recent version of u8glib https://github.com/olikraus/u8g2, I'm gonna see if I can get that working with the Teensy 3.5, based on https://github.com/FriedCircuits/Ug8lib_Teensy
    Last edited by adamski; 01-04-2017 at 12:52 AM.

  11. #11

    I have had great luck getting the Teensy 3.6 to talk to the SSD1306 from Adafruit via software SPI using U8G2. I'm be happy to share my (admittedly clunky) code here. Even though it does some things that you might not have/need (the source includes my wiring), it will be very helpful. This code reads 9 faders and maps them to values that will eventually be hard coded and used for DMX transmission. They are displayed on the screen with some formatting and basic line drawing and typeface changes.

    I switched from the ADAFruit library mainly because this code is more efficient but also because I wanted my own logo to show up when this thing boots not ADAFruit's. I like the way ADAFruit's library handles how you input text/variables to it, but this one seems much, much more customizable.

    Code:
    /*********************************************************************
    ~ Pockonsole ~
      Version 0.5 
      
    ______________________________ 
     DMX connections 
     
     DMX1RX on pin 0
     DMX1TX on pin 1
     DMX1DE and RE (DMX_REDE) on pin 24
    _____________________________
    OLED connections
    
    OLED MOSI0 on pin 11
    OLED SCK0 on pin 13
    OLED_DC on pin 32
    OLED_RST on pin 33
    OLED_CS on pin 34
    _____________________________
    
    */
    
    
    #include <U8g2lib.h>
    #include <U8x8lib.h>
    #include <Arduino.h>
    
    
    #ifdef U8X8_HAVE_HW_SPI
    #include <SPI.h>
    #endif
    #ifdef U8X8_HAVE_HW_I2C
    #include <Wire.h>
    #endif
    
    // MOST IMPORTANT UG82 LINE OF CODE HERE
    // declaring pinout via a "constructor" for Teensy 3.6 for U8g2lib.h OLED library
    
    U8G2_SSD1306_128X64_NONAME_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 34, /* dc=*/ 32, /* reset=*/ 33);  
    
    long dval1;
    long rawVal1;
    float scaledVal1;
    long dmxCH1A;
    long dmxCH1B;
    
    long dval2;
    long rawVal2;
    float scaledVal2;
    long dmxCH2A;
    long dmxCH2B;
    
    long dval3;
    long rawVal3;
    float scaledVal3;
    long dmxCH3A;
    long dmxCH3B;
    
    long dval4;
    long rawVal4;
    float scaledVal4;
    long dmxCH4A;
    long dmxCH4B;
    
    long dval5;
    long rawVal5;
    float scaledVal5;
    long dmxCH5A;
    long dmxCH5B;
    
    long dval6;
    long rawVal6;
    float scaledVal6;
    long dmxCH6A;
    long dmxCH6B;
    
    long dval7;
    long rawVal7;
    float scaledVal7;
    long dmxCH7A;
    long dmxCH7B;
    
    long dval8;
    long rawVal8;
    float scaledVal8;
    long dmxCH8A;
    long dmxCH8B;
    
    long dval9;
    long rawVal9;
    long masterDisplay;
    
    float scaler;
    
    void setup(void) {
      analogReadAveraging(8);
      analogReadRes(16);
      u8g2.begin();
    //  u8g2.enableUTF8Print();
      u8g2.setFont(u8g2_font_helvB14_tf); // choose a suitable font
      u8g2.drawStr(1,20,"Pockonsole");  // write something to the internal memory
    
      u8g2.setFont(u8g2_font_baby_tf); // choose a suitable font
      u8g2.drawStr(103,7,"V 0.5");  // write something to the internal memory
      
      u8g2.setFont(u8g2_font_9x15_tf); // choose a suitable font
      u8g2.drawStr(4,40,"by Harry Pray IV");  // write something to the internal memory
      
      u8g2.sendBuffer();          // transfer internal memory to the display
      delay(5000);
      u8g2.clearBuffer();
    }
    
    void loop(void) {
      rawVal9 = analogRead(9);
      dval9  = round(((sqrt(floatmap(rawVal9, 0.01, 65536.0, 65025.0, 0)))/255.0)*100.0);
      scaler = (floatmap(rawVal9, 0.01, 65536.0, 65025.0, 0.1) / 65025);
      if (dval9 <= 1) {
        dval9 = 0;
      };
      
      rawVal1 = analogRead(1);
      scaledVal1 = (floatmap(rawVal1, 0.01, 65536.0, 65025.0, -1) * scaler);
      if (scaledVal1 <= 20.10) {
        scaledVal1 = 0;
      };
      dval1  = round(sqrt(scaledVal1));
    
      rawVal2 = analogRead(2);
      scaledVal2 = (floatmap(rawVal2, 0.01, 65536.0, 65025.0, -1) * scaler);
      if (scaledVal2 <= 20.10) {
        scaledVal2 = 0;
      };
      dval2  = round(sqrt(scaledVal2));
      
      rawVal3 = analogRead(3);
      scaledVal3 = (floatmap(rawVal3, 0.01, 65536.0, 65025.0, -1) * scaler);
      if (scaledVal3 <= 20.10) {
        scaledVal3 = 0;
      };
      dval3  = round(sqrt(scaledVal3));
      
      rawVal4 = analogRead(4);
      scaledVal4 = (floatmap(rawVal4, 0.01, 65536.0, 65025.0, -1) * scaler);
      if (scaledVal4 <= 20.10) {
        scaledVal4 = 0;
      };
      dval4  = round(sqrt(scaledVal4));
      
      rawVal5 = analogRead(5);
      scaledVal5 = (floatmap(rawVal5, 0.01, 65536.0, 65025.0, -1) * scaler);
      if (scaledVal5 <= 20.10) {
        scaledVal5 = 0;
      };
      dval5  = round(sqrt(scaledVal5));
      
      rawVal6 = analogRead(6);
      scaledVal6 = (floatmap(rawVal6, 0.01, 65536.0, 65025.0, -1) * scaler);
      if (scaledVal6 <= 20.10) {
        scaledVal6 = 0;
      };
      dval6  = round(sqrt(scaledVal6));
      
      rawVal7 = analogRead(7);
      scaledVal7 = (floatmap(rawVal7, 0.01, 65536.0, 65025.0, -1) * scaler);
      if (scaledVal7 <= 20.10) {
        scaledVal7 = 0;
      };
      dval7  = round(sqrt(scaledVal7));
      
      rawVal8 = analogRead(8);
      scaledVal8 = (floatmap(rawVal8, 0.01, 65536.0, 65025.0, -1) * scaler);
      if (scaledVal8 <= 20.10) {
        scaledVal8 = 0;
      };
      dval8  = round(sqrt(scaledVal8));
      
        u8g2.setFont(u8g2_font_5x8_mn);  // choose a suitable font
      
       u8g2.setCursor(0, 10);
       u8g2.print(dval1);
       u8g2.setCursor(22, 10);
       u8g2.print(dval2);
       u8g2.setCursor(44, 10);
       u8g2.print(dval3);
       u8g2.setCursor(66,10);
       u8g2.print(dval4);
    
      u8g2.setFont(u8g2_font_profont15_tf);  // choose a suitable font
      u8g2.drawStr(2,24,"1");
      u8g2.drawStr(26,24,"2");
      u8g2.drawStr(50,24,"3");
      u8g2.drawStr(72,24,"4");
      
    u8g2.setFont(u8g2_font_5x8_mn);  // choose a suitable font
    u8g2.setCursor(0, 47);
    u8g2.print(dval5);
    u8g2.setCursor(22, 47);
    u8g2.print(dval6);
    u8g2.setCursor(44, 47);
    u8g2.print(dval7);
    u8g2.setCursor(66, 47);
    u8g2.print(dval8);
     
      u8g2.setCursor(100, 30);
      u8g2.print(dval9);
    //  u8g2.setCursor(94, 40);
    //  u8g2.print("%");
        
      u8g2.setFont(u8g2_font_profont15_tf);  // choose a suitable font
      u8g2.drawStr(2,60,"5");
      u8g2.drawStr(26,60,"6");
      u8g2.drawStr(50,60,"7");
      u8g2.drawStr(72,60,"8");
      
      u8g2.setFont(u8g2_font_profont15_tf);  // choose a suitable font
      u8g2.drawStr(99,41,"All");
      u8g2.setFont(u8g2_font_5x8_mn);  // choose a suitable font
    
      u8g2.drawLine(17, 0, 17, 64);
      u8g2.drawLine(39, 0, 39, 64);
      u8g2.drawLine(61, 0, 61, 64);
      u8g2.drawLine(83, 0, 83, 64);
      u8g2.drawLine(0, 30, 83, 30);
    
      u8g2.drawFrame(93,21,94,24);
    
      u8g2.sendBuffer();          // transfer internal memory to the display
      delay(100);  
      u8g2.clearBuffer();
    }
    
    
    float floatmap(float x, float in_min, float in_max, float out_min, float out_max)  {
      return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
    }
    
    long sixteen_bit_dmx_a(long raw_value)  {
      return sqrt(raw_value);
    }
    Last edited by harryprayiv; 01-04-2017 at 02:56 AM.

  12. #12
    Thank you so much. This looks like just what I need. And the pin connections also - very useful!

  13. #13
    I'm honored to help!

    I think your go-to constructor statement will be one of these (found here):

    for page buffer, size = 128 bytes
    Code:
    U8G2_SH1106_128X64_NONAME_1_4W_SW_SPI(U8G2_R0, clock, data, cs, dc [, reset])
    for page buffer, size = 256 bytes
    Code:
    U8G2_SH1106_128X64_NONAME_2_4W_SW_SPI(U8G2_R0, clock, data, cs, dc [, reset])
    for full framebuffer, size = 1024 bytes (the framebuffer size that I went with but not necessarily the one I'll stick with because of the larger footprint)
    Code:
    U8G2_SH1106_128X64_NONAME_F_4W_SW_SPI(U8G2_R0, clock, data, cs, dc [, reset])
    Last edited by harryprayiv; 01-04-2017 at 11:59 PM.

  14. #14
    Quote Originally Posted by harryprayiv View Post
    I'm honored to help!

    I think your go-to constructor statement will be one of these (found here):

    for page buffer, size = 128 bytes
    Code:
    U8G2_SH1106_128X64_NONAME_1_4W_SW_SPI(U8G2_R0, clock, data, cs, dc [, reset])
    for page buffer, size = 256 bytes
    Code:
    U8G2_SH1106_128X64_NONAME_2_4W_SW_SPI(U8G2_R0, clock, data, cs, dc [, reset])
    for full framebuffer, size = 1024 bytes (the framebuffer size that I went with but not necessarily the one I'll stick with because of the larger footprint)
    Code:
    U8G2_SH1106_128X64_NONAME_F_4W_SW_SPI(U8G2_R0, clock, data, cs, dc [, reset])
    Is there a reason you are using software SPI over hardware?

  15. #15
    So I've tried different pin outs, and reduced the code example from @harryprayiv to the bare essentials. I'm still getting blank. My current wiring is as follows:

    OLED - Teensy
    ----------------------
    GND - GND
    VCC - 3.3V
    D0 - 13 / SCK0
    D1 - 11
    RES - 33
    DC - 32
    CS - 34 (via 10k resistor)

    I'm wondering if somethings up with my wiring or connections. Any tips on debugging this? I also tried a similar SSD1306 display I have here too, just to check in case the display might be dead.

    Code below:

    Code:
    /*********************************************************************
    ~ TeensyOLED test ~
      Version 0.1
    
    _____________________________
    OLED connections
    
    OLED MOSI0 on pin 11
    OLED SCK0 on pin 13
    OLED_DC on pin 6 //32
    OLED_RST on pin 7 //33
    OLED_CS on pin 8 //34
    _____________________________
    
    */
    #include <U8g2lib.h>
    #include <U8x8lib.h>
    #include <Arduino.h>
    
    #ifdef U8X8_HAVE_HW_SPI
    #include <SPI.h>
    #endif
    #ifdef U8X8_HAVE_HW_I2C
    #include <Wire.h>
    #endif
    
    // MOST IMPORTANT UG82 LINE OF CODE HERE
    // declaring pinout via a "constructor" for Teensy 3.5/6 for U8g2lib.h OLED library
    
    U8G2_SH1106_128X64_NONAME_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 34, /* dc=*/ 32, /* reset=*/ 33);  
    
    
    
    void setup(void) {
      delay(10);
      SPI.begin();
      delay(500);
      u8g2.begin();
      u8g2.enableUTF8Print();
      u8g2.setFont(u8g2_font_helvB14_tf); // choose a suitable font
      u8g2.drawStr(1,20,"TeensyOLED");  // write something to the internal memory
    
      u8g2.setFont(u8g2_font_baby_tf); // choose a suitable font
      u8g2.drawStr(103,7,"v 0.1");  // write something to the internal memory
      
      u8g2.setFont(u8g2_font_9x15_tf); // choose a suitable font
      u8g2.drawStr(4,40,"Hello World");  // write something to the internal memory
      
      u8g2.sendBuffer();          // transfer internal memory to the display
      delay(5000);
      u8g2.clearBuffer();
    }
    
    void loop(void) {
    
    }

  16. #16
    Quote Originally Posted by adamski View Post
    Is there a reason you are using software SPI over hardware?
    because I am using the UART on Serial1 for sending and receiving DMX/RDM data and the display is really just icing on the cake, honestly. DMX runs at 250,000 baud, so it needs to be completely separate.

    I want to prioritize the Serial1 UART and will probably add a few other devices that use the other UART's and I2C.

    Basically, I want this device to be as rock solid for as many different projects as possible and that directly relates to controlling how much of the hardware I/O I have tied up needlessly.

  17. #17
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,821
    Quote Originally Posted by harryprayiv View Post
    I want to prioritize the Serial1 UART and will probably add a few other devices that use the other UART's and I2C.
    If you *really* want to dig into the details, you could edit serial1.c to increase (lower numerical value) the IRQ priority. But it's already at 64 which is higher priority than most other interrupts and Serial1 has a FIFO, so this sort of edit isn't likely to be needed.

  18. #18
    I'm happy to announce that I got it working with the setup in my previous post. I tested all the Teensy & OLED pins with a multimeter and all looked good (my first foray into hardware debugging). I then decided to swap out the SH1106 to the other SSD1306 OLED I have. And it worked! So it was a dud OLED all along... at least I understand the wiring a bit better now

    Click image for larger version. 

Name:	Teensy_OLED_HelloWorld.jpg 
Views:	361 
Size:	89.9 KB 
ID:	9326

  19. #19
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,821
    Glad you got it working!

    Care to name & shame the vendor who sold you the dud? Might help as a warning to others who later find this thread by searching.

  20. #20
    Quote Originally Posted by PaulStoffregen View Post
    Glad you got it working!

    Care to name & shame the vendor who sold you the dud? Might help as a warning to others who later find this thread by searching.
    To be fair the vendor has offered me a return and a refund or replacement, no questions. The seller's eBay username is 'agiia' (UK based).
    Last edited by adamski; 01-12-2017 at 09:40 AM.

  21. #21
    Hi, folk.
    I have Teensy 3.2 and White 3-5V 0.96" SPI Serial 128X64 OLED
    What kind of library does work with this display and maybe somebody has an example of code and pin scheme?
    Thanks!


    This is code don't work
    Code:
    /*********************************************************************
    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 SPI to communicate
    4 or 5 pins are required to interface
    
    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>
    
    // If using software SPI (the default case):
    
    #define OLED_MOSI   11
    #define OLED_CLK  13
    #define OLED_DC    9
    #define OLED_CS    10
    #define OLED_RESET 14
    Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
    
    /* Uncomment this block to use hardware SPI
    #define OLED_DC     6
    #define OLED_CS     7
    #define OLED_RESET  8
    Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS);
    */
    /* Digital pin number for the displays chip select pin */
    
    #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);
      // 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();
    
      // 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();
    }
    
    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();
      }
    }
    
    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();
        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();
      }
    }
    
    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();
      }
    }
    
    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();
      }
    }
    
    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();
      }
    }
       
    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();
      }
    }
    
    void testdrawline() {  
      for (int16_t i=0; i<display.width(); i+=4) {
        display.drawLine(0, 0, i, display.height()-1, WHITE);
        display.display();
      }
      for (int16_t i=0; i<display.height(); i+=4) {
        display.drawLine(0, 0, display.width()-1, i, WHITE);
        display.display();
      }
      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();
      }
      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(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();
      }
      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(250);
    
      display.clearDisplay();
      for (int16_t i=0; i<display.height(); i+=4) {
        display.drawLine(display.width()-1, 0, 0, i, WHITE);
        display.display();
      }
      for (int16_t i=0; i<display.width(); i+=4) {
        display.drawLine(display.width()-1, 0, i, display.height()-1, WHITE); 
        display.display();
      }
      delay(250);
    }
    
    void testscrolltext(void) {
      display.setTextSize(2);
      display.setTextColor(WHITE);
      display.setCursor(10,0);
      display.clearDisplay();
      display.println("scroll");
      display.display();
     
      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();
    }

  22. #22
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,736
    It probably would work with my hacked up version of the Sparkfun Teensyview library.

    Probably not one of the main branch, but maybe this one: https://github.com/KurtE/SparkFun_Te...EventResponder

    It is setup to be able to use different SPI busses, plus ASync support...

  23. #23
    OLED Teensy 3.2 (PIN)
    #define PIN_RESET 14 -----> RES 14
    #define PIN_DC 9 -----> DC 9
    #define PIN_CS 10 -----> CS 10
    #define PIN_SCK 13 -----> D0 13
    #define PIN_MOSI 11 -----> D1 11

    Is it right?

  24. #24
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,736
    I think that looks correct. The main issue is SCK on the D0 pin and I think it is.

  25. #25
    Cool! It works!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •