Getting started with Photon Maker Kit totally confused

@cr_huber, have you had a look at the thread I referenced above?

If not, especially read my posts #8 and #36.

Ok i followed that post and it worked. I got the OLED to power on and run through the loop of images. Then, I unplugged the USB from my laptop. Then I plugged it back in, now neither the photon nor the OLED will power on. When I unwire everything and plugin only the photon the light goes light blue. Does this mean i fried the OLED by unplugging my USB while it was on?

Unplugging the USB should not damage anything (unless you rip of the connector when doing it ;-))

What do you mean with light blue? Is it the commonly refered as breathing cyan color which indicates active cloud connection?

What happens when you reflash your code and then rewire everything again?

yeah i meant breathing cyan. I reflashed and rewired - same problem :frowning:

This is very odd, in deed!

Can you take a pic (or video while things are powering up) of your setup?

To make sure you are actually uploading the correct code, try to flash a simple Blinky program (that just toggles the D7 led). Then check if the uploaded behaviour is to be observed and then reflash the OLED sample again.
And maybe post the sample code youā€™re actually using too.

I removed the cable from RST (photon) to VVC on the OLED and it seems to work now. What gives?

Here is my code:

#include "Adafruit_SSD1306/Adafruit_GFX.h"
#include "Adafruit_SSD1306/Adafruit_SSD1306.h"
/* Uncomment this block to use hardware SPI
// If using software SPI (the default case):
#define OLED_MOSI   D0
#define OLED_CLK    D1
#define OLED_DC     D2
#define OLED_CS     D3
#define OLED_RESET  D4
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
*/

// use hardware SPI
#define OLED_DC     D3
#define OLED_CS     D4
#define OLED_RESET  D5
Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS);


#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 logo16_glcd_bmp[] =
{ 0B00000000, 0B11000000,
  0B00000001, 0B11000000,
  0B00000001, 0B11000000,
  0B00000011, 0B11100000,
  0B11110011, 0B11100000,
  0B11111110, 0B11111000,
  0B01111110, 0B11111111,
  0B00110011, 0B10011111,
  0B00011111, 0B11111100,
  0B00001101, 0B01110000,
  0B00011011, 0B10100000,
  0B00111111, 0B11100000,
  0B00111111, 0B11110000,
  0B01111100, 0B11110000,
  0B01110000, 0B01110000,
  0B00000000, 0B00110000 };

#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
  
  display.display(); // show splashscreen
  delay(2000);
  display.clearDisplay();   // clears the screen and buffer

  // draw a single pixel
  display.drawPixel(10, 10, WHITE);
  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);

  // miniature bitmap display
  display.clearDisplay();
  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); 

  // 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], logo16_glcd_bmp, 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],  logo16_glcd_bmp, 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();
}

Here is my setup which seems to work without the RST attached

:+1: With the correct wiring things work better :wink:

1 Like

But you had the RST wired up in your photo. How come mine works without it ?

Actually you seem to have the RST wired, but not the VCC :wink:

OLED RST (orange) goes to Photon D5, but the OLED VCC (red) to Photon 3V3 is missing.

But it's rather odd that it still works.


This was definetly not on my original wiring :sunglasses:

Although it's hard to see, Vcc is the positive supply voltage and hence should obviously connect to a positive voltage source (e.g. 3V3).
As your setup did run once, I'd guess you had it right first time, but then a jumper might have come off and was put back one jumper hole offset.

I could not agree more with cr_huber. I think the Photon will be a great thing to play with but my initial experience has been very frustrating. I have a lot of experience with Arduinos, Python and C++. Iā€™m not a progressional by any means but Iā€™m not a newby either. As a consumer, when I buy a ā€œMaker kitā€ I expect a tiny bit of help. I have no experience with OLED screens so I thought that it would be fun to place to start. The Maker kit came with no instructions - either in the box or on the web. The starter book (Getting Started with the Photon $20) doesnā€™t mention OLED displays or even I2C or SPI for that matter - shocking really. The data sheet for the OLED display on the Particle.io site is in Chinese (https://docs.particle.io/assets/datasheets/makerkit/oled.pdf). While one day I hope to be able to read Chinese, the data sheet was of little help to me now.

I thought perhaps that the example program in the Web IDE would be a good place to start. It would have been nice to see a simple table of how to connect the seven wires. Complicating matters, I think the example was written for an Arduino. I canā€™t tell you how many tutorials I searched through trying to find an example of pin outs. (The number of pins varies from four to eleven on different models and, on those with seven pins, the labels can be quite different: [GND VCC D0 D1 RST DC CS] vs [CS RST D/C CLK DATA VIN 3.3V GND] vs [Data CLK SA0 RST CS 3V3 VIN GND].

Iā€™m not complaining that there is such a wonderful variety of very cool OLED displays - Iā€™m just pointing out how much time one can spend trying to sort this out - given that the Maker kit provides absolutely zero information.

Based on another thread (Adafruit SSD1306 [Solved) I decided to go with SPI and the following wiring:
OLED - Photon
GND GND
VCC 3V3
D0 A3 // OLED_D0 -> A3 (SPI_SCK)
D1 A5 // OLED_D1 -> A5 (SPI_MOSI)
RST D5 // OLED_RESET -> D5
DC D3 // OLED_DC -> D3
CS D4 // OLED_CS -> D4

(The Photon documentation shows that the SPI1 functions are exposed on the following: SPI1_SS:A2, SPI1_SCK: A3, SPI1_MISO: A4, SPI3_MOSI: A5 - so I donā€™t quite understand why the above wiring should work but perhaps that is grist for the SPI tutorial mill).

Using the example provided in the Particle Web IDE (ssd1306_128x64_spi) and including the libraries ADAFRUIT_SSD1306 and ADAFRUIT_GFX, I get the following errors:

ssd1306_128x64_spi.cpp:74:2: error: #error ("Height incorrect, please fix Adafruit_SSD1306.h!");
   0B00000001, 0B11000000,
  ^
ssd1306_128x64_spi.cpp:40:1: error: 'Adafruit_SSD1306' does not name a type
 #include "Adafruit_GFX.h"
 ^ 
ssd1306_128x64_spi.cpp: In function 'void setup()':
ssd1306_128x64_spi.cpp:81:3: error: 'display' was not declared in this scope
   0B00011111, 0B11111100,
   ^
ssd1306_128x64_spi.cpp:81:17: error: 'SSD1306_SWITCHCAPVCC' was not declared in this scope
   0B00011111, 0B11111100,
                 ^
ssd1306_128x64_spi.cpp:89:29: error: 'WHITE' was not declared in this scope
                             ^
ssd1306_128x64_spi.cpp:156:24: error: 'BLACK' was not declared in this scope
                        ^
ssd1306_128x64_spi.cpp: In function 'void testdrawbitmap(const uint8_t*, uint8_t, uint8_t)':
ssd1306_128x64_spi.cpp:190:29: error: 'display' was not declared in this scope
   delay(1000); 
                             ^
ssd1306_128x64_spi.cpp:205:7: error: 'display' was not declared in this scope
   // initialize
       ^
ssd1306_128x64_spi.cpp:205:81: error: 'WHITE' was not declared in this scope
   // initialize
                                                                                 ^
ssd1306_128x64_spi.cpp:207:5: error: 'display' was not declared in this scope
     icons[f][XPOS] = random(display.width());
     ^
ssd1306_128x64_spi.cpp:212:82: error: 'BLACK' was not declared in this scope
     Serial.print(icons[f][XPOS], DEC);
                                                                                  ^
ssd1306_128x64_spi.cpp: In function 'void testdrawchar()':
ssd1306_128x64_spi.cpp:227:3: error: 'display' was not declared in this scope
     // then erase it + move it
   ^
ssd1306_128x64_spi.cpp:228:24: error: 'WHITE' was not declared in this scope
     for (uint8_t f=0; f< NUMFLAKES; f++) {
                        ^
ssd1306_128x64_spi.cpp: In function 'void testdrawcircle()':
ssd1306_128x64_spi.cpp:241:23: error: 'display' was not declared in this scope
                       ^
ssd1306_128x64_spi.cpp:242:66: error: 'WHITE' was not declared in this scope
                                                                  ^
ssd1306_128x64_spi.cpp: In function 'void testfillrect()':
ssd1306_128x64_spi.cpp:249:23: error: 'display' was not declared in this scope
     if (i == '\n') continue;
                       ^
ssd1306_128x64_spi.cpp: In function 'void testdrawtriangle()':
ssd1306_128x64_spi.cpp:258:27: error: 'display' was not declared in this scope
   for (int16_t i=0; i<display.height(); i+=2) {
                           ^
ssd1306_128x64_spi.cpp:261:65: error: 'WHITE' was not declared in this scope
   }
                                                                 ^
ssd1306_128x64_spi.cpp: In function 'void testfilltriangle()':
ssd1306_128x64_spi.cpp:267:19: error: 'WHITE' was not declared in this scope
     // alternate colors
                   ^
ssd1306_128x64_spi.cpp:268:22: error: 'display' was not declared in this scope
     display.fillRect(i, i, display.width()-i*2, display.height()-i*2, color%2);
                      ^
ssd1306_128x64_spi.cpp:272:33: error: 'BLACK' was not declared in this scope
 }
                                 ^
ssd1306_128x64_spi.cpp: In function 'void testdrawroundrect()':
ssd1306_128x64_spi.cpp:279:23: error: 'display' was not declared in this scope
     display.display();
                       ^
ssd1306_128x64_spi.cpp:280:96: error: 'WHITE' was not declared in this scope
   }
                                                                                                ^
ssd1306_128x64_spi.cpp: In function 'void testfillroundrect()':
ssd1306_128x64_spi.cpp:286:19: error: 'WHITE' was not declared in this scope
     display.fillTriangle(display.width()/2, display.height()/2-i,
                   ^
ssd1306_128x64_spi.cpp:287:23: error: 'display' was not declared in this scope
                      display.width()/2-i, display.height()/2+i,
                       ^
ssd1306_128x64_spi.cpp:289:33: error: 'BLACK' was not declared in this scope
     if (color == WHITE) color = BLACK;
                                 ^
ssd1306_128x64_spi.cpp: In function 'void testdrawrect()':
ssd1306_128x64_spi.cpp:296:23: error: 'display' was not declared in this scope
   for (int16_t i=0; i<display.height()/2-2; i+=2) {
                       ^
ssd1306_128x64_spi.cpp:297:71: error: 'WHITE' was not declared in this scope
     display.drawRoundRect(i, i, display.width()-2*i, display.height()-2*i, display.height()/4, WHITE);
                                                                       ^
ssd1306_128x64_spi.cpp: In function 'void testdrawline()':
ssd1306_128x64_spi.cpp:303:23: error: 'display' was not declared in this scope
   uint8_t color = WHITE;
                       ^
ssd1306_128x64_spi.cpp:304:51: error: 'WHITE' was not declared in this scope
   for (int16_t i=0; i<display.height()/2-2; i+=2) {
                                                   ^
ssd1306_128x64_spi.cpp:307:23: error: 'display' was not declared in this scope
     else color = WHITE;
                       ^
ssd1306_128x64_spi.cpp:308:50: error: 'WHITE' was not declared in this scope
     display.display();
                                                  ^
ssd1306_128x64_spi.cpp:313:3: error: 'display' was not declared in this scope
   for (int16_t i=0; i<display.height()/2; i+=2) {
   ^
ssd1306_128x64_spi.cpp:315:51: error: 'WHITE' was not declared in this scope
     display.display();
                                                   ^
ssd1306_128x64_spi.cpp:319:67: error: 'WHITE' was not declared in this scope
 void testdrawline() {  
                                                                   ^
ssd1306_128x64_spi.cpp:326:67: error: 'WHITE' was not declared in this scope
     display.display();
                                                                   ^
ssd1306_128x64_spi.cpp:330:67: error: 'WHITE' was not declared in this scope
   display.clearDisplay();
                                                                   ^
ssd1306_128x64_spi.cpp:337:50: error: 'WHITE' was not declared in this scope
     display.display();
                                                  ^
ssd1306_128x64_spi.cpp:341:67: error: 'WHITE' was not declared in this scope
   display.clearDisplay();
                                                                   ^
ssd1306_128x64_spi.cpp: In function 'void testscrolltext()':
ssd1306_128x64_spi.cpp:348:3: error: 'display' was not declared in this scope
     display.display();
   ^
ssd1306_128x64_spi.cpp:349:24: error: 'WHITE' was not declared in this scope
   }
                        ^
make[1]: *** [../build/target/user/platform-6ssd1306_128x64_spi.o] Error 1
make: *** [user] Error 2
Error: Could not compile. Please review your code.

Others have apparently gotten the same error(s) and the discussion https://community.particle.io/t/adafruit-ssd1306-library-ported/3505/75 seems to center on the problems of porting libraries and the benefits of abandoning the Particle Web IDE for the Spark DEV.

Is there another solution?

I am quite prepared to do my homework and I look forward to the leaning process. But I question whether selling kits without a ā€œhello worldā€ example is a good business model for Particle.io

1 Like

I agree that this lack of proper docu is a constant pain for users and even more for us.
While one user only gets to deal with this once till he's found the answer, we have to do it over and over again for each user anew - but we don't loose faith in Particle that they eventually will be able to solve that issue which is partly rooted in quick growth and also limited human resources.

Till then we try to help as best we can - absolutely voluntarily and for free in our private spare time.

As for your problem, this post (further up in the thread you linked) should actually give the solution (the user in the other thread just failed to get all the info incorporated immediately and so the thread got rather long)
Adafruit SSD1306 [SOLVED] - #8 by ScruffR

BTW: Can you post the link to the "erronous" docs and what exactly you see wrong, so we can correct it?

Is it "SPI3_MOSI" instead of "SPI1_MOSI" or what else made you think the suggested wiring wouldn't work?

I canā€™t get mine to work for some reason. The app compiles without errors.

Hereā€™s whatā€™s in my library:

Hereā€™s my pin config in the app:

#define OLED_DC     D3
#define OLED_CS     D4
#define OLED_RESET  D5
Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS);

Hereā€™s my wiring:

Anyone have an idea what Iā€™m missing?

Thanks

Iā€™ve not used the SPI version but Iā€™m fairly certain you forgot the power line. 3v3 or Vin to VCC, youā€™ll need to check which.

You need to connect the actual communication pins (D0/D1) too.
Look at the (not shown) two comment lines just above the snippet you've shown :wink:

// use hardware SPI
// OLED_D0 -> A3 (SPI CLK)
// OLED_D1 -> A5 (SPI MOSI)
#define OLED_DC     D3
#define OLED_CS     D4
#define OLED_RESET  D5

or just a few posts up

Just a bit further up in this thread is a pic with correct wiring (although missing Vcc, it still works, via the other pins - better would be a jumper 3V3->Vcc).

Reading the previous posts in the thread you are posting in would really help!

1 Like

Thanks Scruff - appreciate the help! I was under the impression those hardware callouts were commented out due to it being for a different display.

Iā€™ve got it running now - thanks again.

Glad you got it working :+1:

The lines are commented (or better added as comments to the less verbose original) because these pins are not actually used explicitly but are hardwired to ā€œHardware SPIā€, but a lot of people wouldnā€™t know what that means and what pins it refers to. So these comments got added for clarity :wink:

On the other hand if they were not commented but active code, someone might think: ā€œHuh, why? These pins are never used, so get rid of them.ā€ :sunglasses:

Please @ScruffR, are the non-commented declaration of pin connections for I2C or still compatible with the SPI connections?

because am trying to use the 0.96'' adafruit monochrome OLED from Search | Maplin | The Electronics Specialist

The active codelines mean that you can choose any pin you like (minus the already used SPI pins ;-)) for the respective display pins.
This allows you to have multiple SPI devices (even multiple OLED displays) connected to the same SPI port.
So they are not in connection with I2C but with SPI only.

CS stands for Chip Select (must be mutually exclusive for multiple SPI devices)
DC stands for Data/Command and distinguishes if the sent bytes will be interpreted as command or data for the previous command
RESET ā€¦ :wink: