Teensy 3.x and SH1106 OLED via SPI

Status
Not open for further replies.

adamski

Active member
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.

View attachment 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.

Teensy_OLED_1#2.jpgTeensy_OLED_1#3.jpg
Note: the CS pin on the OLED is attached to a 10k resistor which is not so visible here
 
Last edited:
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.
 
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...
 
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.

View attachment 9286

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.

View attachment 9284View attachment 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).
 
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.

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.
 
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/TeensyOLED/blob/master/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.
 
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/TeensyOLED/blob/master/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..
 
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:
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:
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?
 
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) {

}
 
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.
 
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.
 
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 :)

Teensy_OLED_HelloWorld.jpg
 
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.
 
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:
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();
}
 
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?
 
Status
Not open for further replies.
Back
Top