Saturday, June 19, 2021

Embedded C--AVR--Get an OLED display working (SSD1306 I2C Driver) (and) Comparator Application Thoughts

I had so much fun last time getting a TFT working with AVR embedded C that I thought why stop there, let's get an OLED display going as well. 

There are differences between the two display technologies (read more about that here); but OLEDs are so cheap and look so good you just have to throw one into your next project, right? 

Right???

"Let's get started!"

SSD1306 AVR C LIBRARY

The main chip found in my junkbox OLEDs isn't the same IC we coded for last time; these cheap I2C OLED displays use an SSD1306 driver. So, I had to find a C library for the 1306 (or write it myself, but who has time for that?)


Good news--there are many C and C++ libraries for the SSD1306 family; two that are popular and full featured can be found here and here.  

However I ended up using one by preston-Sundar as it seemed simple and had methods to do everything I usually need. Get that library from Github, here.




I used Atmel studio 7 to craft preston's demo main.c and then added his necessary supporting code; his code compiled and flashed without issue, and I was up and running with the POC you see above in about 20 minutes. So--it works! Cool!

COMPARING COMPARATOR THOUGHTS

We have a working OLED display--what to do with it?  A sythesizer control voltage comparator?

Why/why not? I bounced ideas off my friends at my local synth geek club.   

Some of their thoughts:
  • Should I design and build an audio window comparator at all?  "We never use them....don't bother." Off to a bad start. 
  • If you do build one, its inputs have to be bipolar (see the "Bowal" subcircuit, post is here)
  • If you do build one, the output(s) should be -10V to 10V or so, not 0-5V 
  • Other, smarter techs (this one!) already make one for sale--again: why make this at all?
In spite of the lack of enthusiasm I jotted down ideas to create a full featured window comparator module with this 1306 display, the 10 bit A-Ds built into the Atmel 328, and an MCP4922 DAC.  But the 4922 is unipolar, these guys are challenging me to implement bipolar output....how?

BIPOLAR DAC--AD5721

Throwing money at this, I bought a few AD5721's  DACs which support +/-5V at output, and require twos complement math, and probably have other design challenges, so even if the comparator module turns out being a waste I will have worked on something new and (hopefully) learned something.  

I'll do an upcoming post and find or create an AVR C library for the AD5721 if I have time. Stay tuned.

Update: 9-2-21 After more work at the bench I will need a faster microcontroller for this project, probably an STM32, see the initial post for that here. The AD5721 library remains unfinished....

Here is a very quick mock up of a potential front panel for the comparator:


Here is a general main.c to make sure the OLED works at all:


#include <avr/io.h>
#include "i2c.h"
#include "SSD1306.h"

int main(void) {
  
    OLED_Init();  //initialize the OLED
    OLED_Clear(); //clear the display (for good measure)
    
    while (1) {
        
        OLED_SetCursor(0, 0);        //set the cursor position to                                         //(0,0)
        OLED_Printf("Hello World!"); //Print out some text

    }
    
    return 0; // never reached
}


Here is working main.c code for the comparator OLED mockup:


#include <avr/io.h>
#include "i2c.h"
#include "SSD1306.h"


int main(void) {
OLED_Init();  //initialize the OLED
OLED_Clear(); //clear the display (for good measure)
while (1) {
// this is a mock up.  Other than the OLED nothing                     //works.
    OLED_SetCursor(0, 0);      //set the cursor                                                    //position to (0, 0)
    OLED_Printf("AudioDIWHY Comparator"); //Print out                                                         //some text
    OLED_HorizontalGraph(1,50);
    OLED_SetCursor(3,103);
            OLED_Printf("IN A");
            OLED_HorizontalGraph(3,30);
            OLED_SetCursor(7,103);
            OLED_Printf("IN B");
    OLED_SetCursor(5,0);
    OLED_Printf("Mode A < x < B");
    OLED_SetCursor(5,103);
    OLED_Printf("2.2V");
}
return 0; // never reached
}


Which begs the question: should this project be built in the digital domain?  If so, it could have more whiz bang features with fewer components, but nevertheless this isn't a difficult analog circuit to conjure.  

I did a quick back of the napkin sketch of how to do this with an opamp--lots of mistakes, and no, the NPN transistors are not a realistic choice, but this is a napkin:



..,.and then simulated it using circuitlab:


The sim "works", but in the real world it would need more buffering, and a bipolar CV source for the inverting terminal of OA2.  

I might quickly layout a board based on a quad op amp, maybe 3 of them could sit behind a 2u Frac panel?  Then see if I have any real use for it?

Also--in the analog domain this could also be done with comparator ICs like this one. At the end of the day doing a basic comparator in analog is easy.

Update: I have a basic analog comparator working, roughly based on the simulation above; see the post here--but it has not proven useful in my mod synth setup. Not sure if I will pursue this any further at this point. 

OK--"not sure what I will do next".  But my initial goal--to get some OLEDs I had lying around working on my bench, using nothing but embedded C, worked right away, so I had time to kill; an AVR window comparator would be fun to build, but in reality may get little use. Asi es la vida.

No comments:

Post a Comment

A guy OK with C tries to learn C++. Bjane me Up, Stroustruppy!

Why no posts so far for 3-2024?  I have been woodshedding, brushing up on C++ skills.  What got me to finally start digging into C++? I was ...