Adafruit SSD1306 Library [Ported]

Please :smile:

and with following errorā€¦

@Rafal, can you post the text of the errors you get please :smile:

@peekay123, please find error text below:

In file included from ../inc/spark_wiring.h:29:0,
from ../inc/application.h:29,
from Adafruit_GFX.h:4,
from Adafruit_GFX.cpp:34:
../../core-common-lib/SPARK_Firmware_Driver/inc/config.h:12:2: warning: #warning "Defaulting to Release Build" [-Wcpp]
#warning "Defaulting to Release Build"
^
In file included from ../inc/spark_wiring.h:29:0,
from ../inc/application.h:29,
from Adafruit_GFX.h:4,
from Adafruit_SSD1306.cpp:19:
../../core-common-lib/SPARK_Firmware_Driver/inc/config.h:12:2: warning: #warning "Defaulting to Release Build" [-Wcpp]
#warning "Defaulting to Release Build"
^
In file included from ../inc/spark_wiring.h:29:0,
from ../inc/application.h:29,
from Adafruit_SSD1306.h:20,
from oscilloscope_1.cpp:1:
../../core-common-lib/SPARK_Firmware_Driver/inc/config.h:12:2: warning: #warning "Defaulting to Release Build" [-Wcpp]
#warning "Defaulting to Release Build"
^
oscilloscope_1.cpp: In function 'void displayln(const char*, ...)':
oscilloscope_1.cpp:48:3: error: 'va_list' was not declared in this scope

^
oscilloscope_1.cpp:48:11: error: expected ';' before 'args'

^
oscilloscope_1.cpp:49:12: error: 'args' was not declared in this scope
/********************************************/
^
oscilloscope_1.cpp:49:24: error: 'va_start' was not declared in this scope
/********************************************/
^
oscilloscope_1.cpp:51:14: error: 'va_end' was not declared in this scope
// Draws a printf style string at the current cursor position
^
make: *** [oscilloscope_1.o] Error 1

Error: Could not compile. Please review your code.

@peekay123, please find source code below:

#include "Adafruit_SSD1306.h"
#include "Adafruit_GFX.h"
#include "application.h"

/*
This is set up to use a 128x64 I2C screen, as available
here: http://www.banggood.com/buy/0-96-oled.html
For wiring details see http://youtu.be/XHDNXXhg3Hg
*/


// 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);

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

/********************************************/

#define CHARWIDTH           5
#define CHARHEIGHT          8
#define AXISWIDTH           (2 + 1)                   // axis will show two-pixel wide graph ticks, then an empty column
#define VISIBLEVALUEPIXELS  (128 - AXISWIDTH)         // the number of samples visible on screen
#define NUMVALUES           (2 * VISIBLEVALUEPIXELS)  // the total number of samples (take twice as many as visible, to help find trigger point

#define TRIGGER_ENABLE_PIN       2  // set this pin high to enable trigger
#define SCREEN_UPDATE_ENABLE_PIN 3  // set this pin high to freeze screen

byte values[NUMVALUES];           // stores read analog values mapped to 0-63
int pos = 0;                      // the next position in the value array to read
int count = 0;                    // the total number of times through the loop
unsigned long readStartTime = 0;  // time when the current sampling started
int sampleRate = 1;              // A value of 1 will sample every time through the loop, 5 will sample every fifth time etc.

/********************************************/

// Draws a printf style string at the current cursor position
void displayln(const char* format, ...)
{
  char buffer[32];
  
  va_list args;
  va_start(args, format);
  vsprintf(buffer, format, args);
  va_end(args);
  
  int len = strlen(buffer);
  for (uint8_t i = 0; i < len; i++) {
    display.write(buffer[i]);
  }
}

// Draws the graph ticks for the vertical axis
void drawAxis()
{  
  // graph ticks
  for (int x = 0; x < 2; x++) {
    display.drawPixel(x,  0, WHITE);
    display.drawPixel(x, 13, WHITE);
    display.drawPixel(x, 26, WHITE);
    display.drawPixel(x, 38, WHITE);
    display.drawPixel(x, 50, WHITE);
    display.drawPixel(x, 63, WHITE);  
  }
}

// Draws the sampled values
void drawValues()
{
  int start = 0;
  
  if ( digitalRead(TRIGGER_ENABLE_PIN) ) {
    // Find the first occurence of zero
    for (int i = 0; i < NUMVALUES; i++) {
      if ( values[i] == 0 ) {
        // Now find the next value that is not zero
        for (; i < NUMVALUES; i++) {
          if ( values[i] != 0 ) {
            start = i;
            break;
          }
        }
        break;
      }
    }    
    // If the trigger point is not within half of our values, we will 
    // not have enough sample points to show the wave correctly
    if ( start >= VISIBLEVALUEPIXELS )
      return;
  }
  
  for (int i = 0; i < VISIBLEVALUEPIXELS; i++) {
    display.drawPixel(i + AXISWIDTH, 63 - (values[i + start]), WHITE);
  }
}

// Shows the time taken to sample the values shown on screen
void drawFrameTime(unsigned long us)
{
  display.setCursor(9 * CHARWIDTH, 7 * CHARHEIGHT - 2); // almost at bottom, approximately centered
  displayln("%ld us", us);
}

/********************************************/

void setup() {

  // Set up the display
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Initialize with the I2C addr 0x3D (for the 128x64)
  display.setTextColor(WHITE);

  pinMode(TRIGGER_ENABLE_PIN, INPUT);
  pinMode(SCREEN_UPDATE_ENABLE_PIN, INPUT);
}

/********************************************/

void loop() {
  
  // If a sampling run is about to start, record the start time
  if ( pos == 0 )
    readStartTime = micros();
  
  // If this iteration is one we want a sample for, take the sample
  if ( (++count) % sampleRate == 0 )
    values[pos++] = analogRead(0) >> 4; // shifting right by 4 efficiently maps 0-1023 range to 0-63

  // If we have filled the sample buffer, display the results on screen
  if ( pos >= NUMVALUES ) {
    // Measure how long the run took
    unsigned long totalSampleTime = (micros() - readStartTime) / 2;     // Divide by 2 because we are taking twice as many samples as are shown on the screen
 
    if ( !digitalRead(SCREEN_UPDATE_ENABLE_PIN) ) {
      // Display the data on screen   
      display.clearDisplay();
      drawAxis();
      drawValues();
      drawFrameTime(totalSampleTime);
      display.display();
    }
       
    // Reset values for the next sampling run
    pos = 0;
    count = 0;
  }
}

@Rafal, add the following line after the #include ā€œapplication.hā€:

#include <stdarg.h>

That should fix the errors. :smile:

Hello @peekay123, all correct (: it dose treat problem, but I have realised one fact - aldo now sketch compile with no problem, on core crashesā€¦ I mean that graphic stuckā€¦
Maybe for some reason ISP have different function to the Arduino 16mhzā€¦ But on other hand Adafruit_SSD1306 library demo runs smoothlyā€¦
Summarise - now no problems in IDE and compiling with no one error. Uploading with no problem, but after reset screen shows radom pixels or sometime lines or whole screen ā€œonā€

I will upload some photos later night.
Thank you for your kind help.

@Rafal, it would be really better if you switched to using Spark DEV or CLI. It would also be good if you could post all your files on github or dropbox so I can take a look at everything?

Hey thanks everyone to collect the code and test the displays.

What would be the best way to use such displays? I2C, SPI, direct?

And is the 128x64 px Display known to work with spark core? I am a bit worried about the avalable memory for drawing/rendering.

@Coffee, the best interface depends on your display speed requirements. Of the serial protocols, SPI is the fastest and then I2C and Serial (UART). If by ā€œdirectā€ you mean a parallel interface then that is THE fastest interface but at the highest pin count (6 or more). The others take 3 or less pins.

I would recommend a [Digole Serial (smart)][1] display over the 128x64 px display since they have several models to chose from and we have a library already ported. I even added several graphics primitives to their library for extra fun!

The only catch with either of these displays is the the onboard PIC processor runs in SPI mode 3 and some members had issues with having an SD card running on SPI mode 0 at the same time. The solution was to use software SPI on one of the devices. Personally, I use Serial1 at 115K baud using a single pin (TX). The Digole display runs plenty fast for my purposes.

As for memory use on the Core, that is always a worry if you have lots of graphics, fonts and things. The Digole allows you to define up to 4 extra fonts in its onboard flash so you donā€™t have to store the font bitmaps on the Core. You can also load menus and graphics from an SD card. It all comes down to what you want to do with the display and the Core. :smile:

DOH!! I just realized that the 128x64 px display IS the Digole display!!! :stuck_out_tongue:
[1]: http://www.digole.com/

1 Like

Iā€™m disappointed that the ported libraries in the IDE donā€™t work. Why does it require all this modification? If they are included in the IDE they should simply work or not be included at all.
I get the same errors as Rafalā€¦Iā€™m getting nowhere with it.

@skradaroman, I understand your frustration and completely agree with you. There are always risks to community contributed libraries. Add to that some idiosyncrasies of creating web IDE libraries and you end up with errors. Worst, often the original contributor is no longer around to make fixes. The are trying to address this latter issue by giving the Elites full ā€œgroomingā€ control of IDE libraries to ensure quality. This is in the pipeline.

In the meantime, you may want to explore the Spark CLI and Spark DEV which I personally only use. I find them faster and easier to use. In the meantime, let us know how we can help :smile:

I got it to work now. I downloaded your Github libraries and used Spark Dev. Thank you for the effort.
The trick there is to have only one .ino file in the directory to be able to compile using Spark Dev. Other than that, it works out of the box using I2C. Thanks again.

3 Likes

Help meā€¦ / Sorry i have OLED Display 128 x 64 I2c interface
http://heltec.diytrade.com/sdp/2044581/4/pd-6785993/11659259-0/0_96inch_SSD1306_IIC_OLED_module_for_arduino.html

is library ssd1306 from https://github.com/pkourany/Adafruit_SSD1306 is not work

because it not show no display


Did you use pull-up resistors for SCL and SDA?

Sorry don't know to Interal pull-up resistors ?
How much Interal pull-up resistors ? kĪ©

( sorry i low level english )

4.7kohm each :wink:

Vcc --------- 4.7k ohm -------- SCL
Vcc ----------4.7k ohm -------- SDA
1 Like

Thx!!! try it ^ ^

So i am thx

^ ^

3 Likes

Hi,

I can't get this to work. When I flash it from the Web IDE the flash will work, the core will pulse (cyan), but it seems to lock up the device and can't be flashed again unless I do a factory reset.

When trying to flash from the local Spark Dev IDE I get this error from the code verfication:

avr/pgmspace.h: No such file or directory
Adafruit_SSD1306.cpp:19:26

Any ideas?

Thanks & BR