Skip to content

Instantly share code, notes, and snippets.

@adam-buckley
Created October 23, 2017 10:56
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save adam-buckley/f591515be832b355b2d0ccb751782a40 to your computer and use it in GitHub Desktop.
Save adam-buckley/f591515be832b355b2d0ccb751782a40 to your computer and use it in GitHub Desktop.
Onion Omega2 - I2C OLED Bouncing Dot using C
/**
* A small demo of a dot bouncing inside a 128x64 OLED screen, using the Onion Omega 2. Note this isn't using the
* OLED expansion, but a cheapo screen I bought from China, using the SSD1306 (as far as I could tell) driver.
* This was only a personal exercise to see how easy it is to setup, it might be handly to someone else learning!
*
* To compile:
* - install gcc and make (See: https://docs.onion.io/omega2-docs/c-compiler-on-omega.html)
* - install git (Follow this: https://docs.onion.io/omega2-docs/installing-and-using-git.html)
* - install python-dev
* - git clone the i2c exp driver (https://github.com/OnionIoT/i2c-exp-driver)
* - (At the time of writing) Alter the makefile according to this bug report (https://github.com/OnionIoT/i2c-exp-driver/issues/18)
* - go into the "i2c-exp-driver" project and compile with `make`
* - copy bin, include, lib directories to /usr
* - compile gist below with `gcc bouncing_dot.c -loniondebug -lonioni2c -lonionoledexp`
* - Run!
*
* @author Adam Buckley <adam.buckley90@gmail.com>
*/
// #include <stdio.h>
#include <unistd.h>
#include <oled-exp.h>
int main() {
// Init the OLED
int status = oledDriverInit();
status |= oledSetDisplayPower(1);
int x = 0, y = 0;
int delta_x = 1, delta_y = 1;
// Run forever
while(1) {
x += delta_x;
y += delta_y;
// When X hits a boundary on the OLED, flip the delta position
if (x == 0 || x == 63) {
delta_x *= -1;
}
// Do the same for the y coordinate
if (y == 0 || y == 127) {
delta_y *= -1;
}
// Set cursor to correct position
// The way this works is that while the height of the OLED is 64px, there
// is 8 logical rows, each with 8 addressable pixels. So the code below is just
// working out where a pixel (e.g x = 57) should be placed
// See https://docs.onion.io/omega2-docs/oled-expansion-c-library.html#understanding-the-display-1 for more info
status |= oledSetCursorByPixel(((int) x / 8), y);
switch(x % 8) {
case 0:
status |= oledWriteByte(0x01);
break;
case 1:
status |= oledWriteByte(0x02);
break;
case 2:
status |= oledWriteByte(0x04);
break;
case 3:
status |= oledWriteByte(0x08);
break;
case 4:
status |= oledWriteByte(0x10);
break;
case 5:
status |= oledWriteByte(0x20);
break;
case 6:
status |= oledWriteByte(0x40);
break;
case 7:
status |= oledWriteByte(0x80);
break;
}
// A larger usleep value will make the dot move slower
usleep(10000);
// Clear the current dot on the screen
status |= oledSetCursorByPixel(((int) x / 8), y);
status |= oledWriteByte(0x00);
// Clear below for some reason will cause the screen to not print anything
// status |= oledClear();
}
return 0;
}
@adam-buckley
Copy link
Author

I wrote the code above on the Omega itself, nano has its limits, please let me know if you have any issues.

@greenbreakfast
Copy link

Awesome project, love it!
If you take a peek at /usr/lib on the Omega, you'll see that it already has the shared objects for liboniondebug, libonioni2c, and libonionoledexp.
Haven't tried it myself, but it should work if you just grab the header files from the i2c-exp-driver repo!

@adam-buckley
Copy link
Author

Thanks @greenbreakfast!

I had a feeling that was the case regarding libonionoledexp, my knowledge of C and Omega internals are pretty limited so I just followed the tutorial. I'll fire up my other Omega when I get home and see if I can do this without having to compile external libraries.

@greenbreakfast
Copy link

A third way to do it: cross-compile your program. We just put out a guide: https://onion.io/2bt-cross-compiling-c-programs-part-3/

@impactful
Copy link

Thanks for the very clear compilation instructions.

However, I just noticed that the OLED Expansion Python Module commands to setCursor stopped working after I followed your compilation steps (gcc, make, git, python-dev installs).

In a Python shell, the OLED command "oledExp.setCursor(0,0)" (for example) now returns: "IOError: I2C transaction failed." Same for setCursorByPixel(...)." I tried the Sierpinski triangle example in the i2c-exp-driver Github repo, and it fails as well, at the same point. Other commands still work (driverInit, clear, write, wWriteByte, etc.).

Any ideas?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment