Other thing, I seem to see from their example application that they connect to bus I2c-2. That is the one where also the Bela codec is, and it's NOT the one that is broken out on the Bela cape. This is no big deal, assuming the address in use by the display is different from the one used by the Bela codec; but you may want to double check this.
is anyone successfully using i2c OLED / LCD?
giuliomoro I seem to see from their example application that they connect to bus I2c-2
good to know. although i had not even considered using the bela-cap i2c since i saw the pins in use on the photos and video.
hmm, but it should not be too much trouble rewriting the code to use i2c port 1, no? (just in case)
it's this line here I think (as I did not dig deep into the code):
if(init_i2c_dev2(SSD1306_OLED_ADDR) == 0)
possibly there is a different function init_i2c_dev1()
, or you can just replace whatever constant they have internally to point to the other i2c bus.
- Edited
the function is defined in i2c.c and it looks straightforward to change. which port is broken out on the bela cape? i2c-0 or i2c-1?
EDIT: found it in the doc, it's i2c-1
and, rewrote the function. it compiles fine btw.
now, waiting for that display...(could take a few weeks, phuuh)
I guess you could look at the docs for the ones you have and see if you can modify the library for those!
giuliomoro I guess you could look at the docs for the ones you have and see if you can modify the library for those!
yeah will do. i will still hook up my displays to the existing library and see if i get some gibberish output (and check if the i2c port is correct etc.) from what i remember those 2 display types are very similar and i got gibberish output when i tried them on axoloti with the wrong driver.
ok, well first tests failed :-(
will wait for the compatible display and take it from there.
- Edited
Hi! I've been working with @RafaeleAndrade to get this type of OLED display (SSD1306) working for our respective Bela projects; I got the example code working for the i2c-1 ports on our Bela Original and Bela Mini, by making these alterations:
in SSD1306_OLED.c: replace I2C_DEV_2 with I2C_DEV_1
in I2C.h:
add #define I2C_DEV1_PATH "/dev/i2c-1”
add extern int init_i2c_dev1(unsigned char slave_address);
in I2C.c:
add I2C_DeviceT I2C_DEV_1;
add a duplicate of the init_i2c_dev2 function, but altered to dev1
in Main.c:
replace I2C_DEV2 with I2C_DEV1
replace ic2_dev2 with i2c_dev1
replace i2c-2 with i2c-1
I've put these files up online here: https://github.com/crosswick/SSD1306-OLED-display-driver-for-BeagleBone
So part 1 of the instruction that @giuliomoro gave above works, the example code is running outside of the Bela environment. For inside the Bela environment, I stumbled upon the error no matching function for call to 'Bela_createAuxiliaryTask'
, which was fixable by changing
void* oledTaskFunction(void*)
to
void oledTaskFunction(void*)
Also I needed to add to render.cpp:
void render(BelaContext *context, void *userData)
{
}
void cleanup(BelaContext *context, void *userData)
{
}
After that, I get a Segmentation Fault:
Segmentation fault
bela: Makefile:524: recipe for target 'runide' failed
make: *** [runide] Error 139
So any help with that would be much appreciated; I presume we should take a good look at what this SSD1306_OLED code is doing in terms of memory allocation?
BTW, in terms of hardware: with the specific display module that we have available in our hackerspace, namely https://nl.aliexpress.com/item/32595065663.html, we had to not only change the resistors on the back side to change it from SPI to i2c mode; also the RES pin needs to be involved by adding a small RC circuit, found on the Axoloti forum here: http://community.axoloti.com/t/spi-i2c-oled-display/638/187
can you post the actual code you have in your Bela project?
here you go, for now it's only the basic but altered render.cpp:
#include <Bela.h>
extern "C" {
int oled_main(void); // declare the oled_main() function from Main.c
}
AuxiliaryTask oledTask;
void oledTaskFunction(void*)
{
while(!gShouldStop){ // run the content of the loop until the program stops
oled_main();
usleep(50000); // always sleep in a busy loop to avoid hogging all the CPU
}
}
bool setup(BelaContext* context, void* userData)
{
Bela_createAuxiliaryTask(oledTaskFunction, 1, "oledTask", NULL);
Bela_scheduleAuxiliaryTask(oledTask);
}
// optional: add some sound generator into render()
void render(BelaContext *context, void *userData)
{
}
void cleanup(BelaContext *context, void *userData)
{
}
- Edited
AuxiliaryTask oledTask; ... bool setup(BelaContext* context, void* userData) { Bela_createAuxiliaryTask(oledTaskFunction, 1, "oledTask", NULL); Bela_scheduleAuxiliaryTask(oledTask); }
The issue is that you are not assigning the return value of Bela_createAuxiliaryTask
to the oledTask
variable, therefore you are passing it uninitialized to Bela_scheduleAuxiliaryTask()
.
The fix is this:
bool setup(BelaContext* context, void* userData)
{
oledTask = Bela_createAuxiliaryTask(oledTaskFunction, 1, "oledTask", NULL);
Bela_scheduleAuxiliaryTask(oledTask);
}
I see... to be honest I'm not yet very knowledgeable about such inner workings, for now I'm just trying to get your code working as you suggested it earlier in this thread.
Adding oledTask =
and cleaning/recompiling the project still gives me a Segmentation Fault:
Running project...
(Main)i2c-1: Bus Connected to SSD1306
Segmentation fault
Makefile:524: recipe for target 'runide' failed
make: *** [runide] Error 139
This is better. You see that now it is actually running the task (as you can tell from the fact that the line
(Main)i2c-1: Bus Connected to SSD1306
is printed).
I started debugging this by copying all your code to the board and trying to run the files from your repo as a stand-alone app, and that would fail at compile time. I fixed it with this.
Then, I managed to build a stand-alone program (non-Bela) and run it, but it would only display (Main)i2c-1: Bus Connected to SSD1306
and would not actually show anything on the display.
Did you see the test animation on the display?
Next thing I did was to check out the upstream code (basically, your code without your changes), which is hardcoded to use I2C-2. Once I managed to get it to build (needed the same fix as above), it ran just fine.
I also fixed a buffer overflow that was an accident waiting to happen.
I applied some minimal changes to be able to use i2c-1, without having to go through the whole renaming process you undertook.
After that, the stand-alone application works fine on i2c-1 as well.
Then I copied the files thus updated into the project, and I got to the same point you were at:
crosswick Running project...
(Main)i2c-1: Bus Connected to SSD1306
Segmentation fault
Makefile:524: recipe for target 'runide' failed
make: *** [runide] Error 139
(note this took me over 1 hour, and I could have saved all of that time if you had sent me the code ready to test).
The compiler actually gives you a warning that is the key to solve the issue:
/root/Bela/projects/ssd/render.cpp:17:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
1 warning generated.
This means that you are supposed to return a value from setup()
and you are not. If the initialization goes well, you should return true
.
So this works for me:
bool setup(BelaContext* context, void* userData)
{
oledTask = Bela_createAuxiliaryTask(oledTaskFunction, 1, "oledTask", NULL);
Bela_scheduleAuxiliaryTask(oledTask);
return true;
}
For the avoidance of doubt, here is a repo containing a complete Bela project where this code is working correctly. Note that the program may take a while to stop after you hit stop, because the oled_main()
function takes forever to return.
Thanks @giuliomoro. First off, to address this:
giuliomoro (note this took me over 1 hour, and I could have saved all of that time if you had sent me the code ready to test).
I highly value your time and enormous help on this forum... I had doublechecked that the code worked on my Bela Mini before I uploaded it to github. I just checked again and these steps work for me:
- download the .zip from https://github.com/crosswick/SSD1306-OLED-display-driver-for-BeagleBone
- in the Bela interface, create a new C++ project called 'OLED_test_github'
- use 'Upload file' to add the seven relevant .h and .c files to the project
- with Terminal and ssh root@192.168.7.2, navigate to Bela/projects/OLED_test_github
- run
gcc *.c -o oled
which returns a bunch of warnings but no errors; - run
./oled
which makes the display connected to ic2-1 perform the test animations.
My Bela Mini is running v0.3.6b, which I believe is the latest version.
hmm that's interesting, I am wondering if you have a very very old Bela image (circa 2016)?
Otherwise the second of these lines in I2C.c
should break
#include<linux/i2c.h>
#include<linux/i2c-dev.h>
?
Can you run grep v0 /etc/motd
on the board? What does it return?
giuliomoro This means that you are supposed to return a value from setup() and you are not. If the initialization goes well, you should return true.
Great! it also works for me. I can now go on to test out these display functions from within PD; my plan is to use the customRender PD example project as a starting point.
Thank you!
giuliomoro Can you run grep v0 /etc/motd on the board? What does it return?
Bela image, v0.3.6b, 23 October 2018
and grep linux /root/Bela/projects/OLED_test_github/*
?
giuliomoro and grep linux /root/Bela/projects/OLED_test_github/* ?
/root/Bela/projects/OLED_test_github/I2C.c:#include<linux/i2c.h>
/root/Bela/projects/OLED_test_github/I2C.c:#include<linux/i2c-dev.h>
grep: /root/Bela/projects/OLED_test_github/build: Is a directory
Binary file /root/Bela/projects/OLED_test_github/oled matches