• Hardware
  • is anyone successfully using i2c OLED / LCD?

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.

    6 days later

    ok, well first tests failed :-(
    will wait for the compatible display and take it from there.

    10 months later

    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

    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)
    {
    }

      crosswick

      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

            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

            and what's the output of

            dpkg -l | grep i2c

            ?

            ii i2c-tools 3.1.2-3 armhf heterogeneous set of I2C tools for Linux

            I did use i2cdetect earlier to check whether the display module was connected... I don't recall exactly if I installed it or if it was already there. Maybe that makes a difference?

            right so the problem is on my board, where I have actually installed an extra package libi2c-dev, which causes the an error when including both files listed above. UOPS!

              🙂 let me know if I can be of any further assistance. I think it might be best for me to first work on the PD integration and after that write up a how-to.