Novice Question about OLED

Hello, I am a beginner trying to learn. I have gotten to this point, and my flow meter output reads correctly in the serial monitor, and the static text displays correctly, but the OLED reading always just says 0.00. I think it has something to do with the delays or interrupts, or I'm just using the wrong command for writing the variable (flowRate) to the OLED.

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeSansBold9pt7b.h>



#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64 
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

int flowPin = 2;   
double flowRate;   
volatile int count;

void setup() {
 pinMode(flowPin, INPUT);          
  attachInterrupt(0, Flow, RISING); 
  Serial.begin(9600);  //Start Serial
  Serial.begin(9600);

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  delay(2000);
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setFont();
  display.setTextSize(1);
  display.setCursor(0, 18);
  display.println("ml/min");
  display.setTextSize(1);
  display.setCursor(40, 18);
  display.println(flowRate);
  display.display(); 
  delay(100);

  

  
 
}

void loop() {
  count = 0;      
  interrupts();   
  delay (1000);   
  noInterrupts(); 

  flowRate = (count * 0.068);      
  flowRate = flowRate * 60;         
  

  Serial.println(flowRate);    
}

void Flow()
{
   count++; 
}

In loop() you never write the result to the display.

Yea, having a variable write in setup doesn't make much sense, does it. Thank you lol, I have a lot to learn!

Everyone does. That is what makes it fun. Keep exploring.

After you install any library, the IDE will have an example folder for that library. IDE >> FILE >> EXAMPLES >> EXAMPLES FOR CUSTOM LIBRARIES

1 Like

Thanks. I was checking out the examples for the SSD1306, but there wasn't one that helps with this specific thing. I also read a few posts in this forum about the same issue, and found a few examples online of showing a variable on the OLED, but whenever I try and replicate the code, it doesn't work. I currently just tried moving the display(flowRate) to the loop, but the 0.00 goes away and it breaks the serial print function, so I guess it will be more complicated than I was hoping and I need to learn more. I noticed most people showing a variable on the OLED have a "float" function in the code, but none of the examples for the flowmeter have it, and when I try and implement it using the flowRate, it doesn't work.

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeSansBold9pt7b.h>



#define SCREEN_WIDTH 128 
#define SCREEN_HEIGHT 64 


Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

int flowPin = 2;   
double flowRate;    
volatile int count; 

void setup() {
 pinMode(flowPin, INPUT);           
  attachInterrupt(0, Flow, RISING); 
  Serial.begin(9600);  
  Serial.begin(9600);

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { 
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  delay(2000);
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setFont();
  display.setTextSize(1);
  display.setCursor(0, 18);
  display.println("ml/min");
  display.display();
  
 

  

  
 
}

void loop() {
 
  count = 0;      
  interrupts();   
  delay (1000);   
  noInterrupts(); 

  //Start the math
  flowRate = (count * 0.068);        
  flowRate = flowRate * 60;   

  display.setTextSize(1);
  display.setCursor(40, 18);
  display.print(flowRate);
  display.display(); 
  

  Serial.println(flowRate);    




 
}

void Flow()
{
   count++; 
}

I don't understand what you are willing to do with this code . Also you set interrupt to add to count, but then in your loop you set it to zero and then you do multiplications that obviously remain zero...

Someone gave you bad code. Try this...

Well, the code works fine, when it prints to serial, it accurately shows the flowmeter output. I am having issues getting it to display on the OLED.

Thanks, I will try that. I am still very new to this, and am approaching it by trying to do what I want completely from scratch/learning the basic commands, but when I hit a roadblock I copy/paste whatever code I need to get me to the next step, while still trying to learn (from the copied code) what I was doing wrong. The main code for the flow pulse sense is a mix of my own and of an online tutorial I found, but the parts you mention were just what I found online.

Ok, so putting count = 0; in setup just makes it keep counting upwards even with no sensor output, so I left it in loop.

I did all the other changes you suggested, and I now have a changing number on the OLED, that goes up when flow goes up, so great. I also added back the delay (1000); because the numbers changed too fast on the OLED and were blurred.

The only issue now, is that something I deleted from your list, has made it so the flow number is at 4.08 instead of 0, when there is no flow. The actual number still goes up and down with flow, but 0 seems to be 4.08 now, I will study the code and see what is making it do that.

Thank you for getting my variable to display on the OLED so far!

  • Welcome to the group.

  • Here is something to play with in your spare time.

//********************************************^************************************************
//  OLED_Counter.ino
//
//  LarryD
//  Version   YY/MM/DD     Comments
//  =======   ========     ===============================================
//  1.00      22/04/21     Running code
//
//

//https://lastminuteengineers.com/oled-display-arduino-tutorial/

#include <Wire.h>
//#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

//********************************************^************************************************

const byte heartbeatLED     = 13;

#define SCREEN_WIDTH        128   //OLED display width,  in pixels
#define SCREEN_HEIGHT       64   //OLED display height, in pixels


//SSD1306 display
//size 1 is 5X7   pixels therefore, 6X8   to acount for spacing,  21 characters per line
//size 2 is 10X14 pixels therefore, 11X15 to account for spacing, 10 characters per line
//size 4 is 20X28 pixels therefore, 21X29 to account for spacing,  5 characters per line

//Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

unsigned long counter       = 0;

//timing stuff
unsigned long heartbeatTime;
unsigned long displayTime;


//                                       s e t u p ( )
//********************************************^************************************************
//
void setup()
{
  Serial.begin(115200);

  pinMode(heartbeatLED, OUTPUT);

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C))
  {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;);
  }

  display.clearDisplay();

  //display.setTextColor(textColor, backgroundColor);
  display.setTextColor(WHITE, BLACK);

} //END of   setup()


//                                        l o o p ( )
//********************************************^************************************************
//
void loop()
{
  //*********************************                         heartbeat TIMER
  //is it time to toggle the heartbeatLED (every 500ms)?
  if (millis() - heartbeatTime >= 500ul)
  {
    //restart this TIMER
    heartbeatTime = millis();

    //toggle the heartbeat LED
    digitalWrite(heartbeatLED, digitalRead(heartbeatLED) == HIGH ? LOW : HIGH);
  }

  //*********************************                         displayTime TIMER
  //is time to update the display ?
  if (millis() - displayTime >= 500ul)
  {
    //restart this TIMER
    displayTime = millis();

    //clear SSD1306 display
    display.clearDisplay();

    //************************************
    display.setTextSize(1);
    display.setCursor(0, 0);

    //Size 1 line is  000000000111111111122
    //21 characters   123456789012345678901
    //Example         ..OLED Counter Demo..
    display.print("  OLED Counter Demo  ");

    //************************************
    //display.setCursor(0,9);
    //Size 1 line is  000000000111111111122
    //21 characters   123456789012345678901
    //display.print ("ABCDEFGHIJKLMNOPQRSTU");

    //************************************
    display.setTextSize(2);
    //2 = current text size, 16 is the pixel row we want to postion to
    display.setCursor(centering(counter, 2), 16);

    //Size 2 line     0000000001
    //10 characters   1234567890
    //Example           100000
    display.print(counter++);

    //************************************
    //degree symbol
    //using CP437 ASCII
    //display.cp437(true);
    //display.write(248);

    //************************************
    //  display.setTextSize(2);
    //  display.setCursor(0,16);
    //  display.setCursor(0,32);
    //  //temperature
    //  //Size 2 line is  0000000001
    //  //10 characters   1234567890
    //  //Example         ABCDEFGHIJ
    //  display.print("ABCDEFGHIJ");

    //************************************
    display.display();
  }

  //************************************
  //other non blocking code goes here
  //************************************


} //END of   loop()


//                                 c o u n t D i g i t s ( )
//********************************************^************************************************
//return the number of digits in a number
byte countDigits(int num)
{
  byte count = 0;

  while (num)
  {
    num = num / 10;
    count++;
  }

  return count;

} //END of   countDigits()


//                                    g e t D i g i t ( )
//********************************************^************************************************
//return the selected digit
byte getDigit(unsigned int number, int digit)
{
  for (int i = 0; i < digit - 1; i++)
  {
    number = number / 10;
  }

  return number % 10;

} //END of   getDigit()


//                                   c e n t e r i n g ( )
//********************************************^************************************************
//return the position to print the MSD
byte centering(unsigned long number, byte textSize)
{
  byte count = 0;
  byte charaterCellWidth = 0;

  //a basic character is 5X7, we must scale for this text size
  charaterCellWidth = (5 * textSize) + 1;

  //number of digits in our number
  while (number)
  {
    number = number / 10;
    count++;
  }

  //center location where the MSD character will be displayed
  return (SCREEN_WIDTH / 2 - (charaterCellWidth * count / 2));

} //END of   centering()

//

This seems to be a place where decimal values are made.

You generally get more pleasant user experience if you only update the screen when your number significantly changes. Avoid using long delay, if not needed.

Indeed it is, the decimal place is one thing, but 0 turning into 4.08 is another, adding flow(); to loop is what caused it, when I removed it, it now works as expected.

I appreciate the advice to get it working, now I need to sit down and fully understand HOW it made it work so I can progress further on my own!

If abs(oldVal - newVal) > significant then print.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.