Go Down

Topic: Adafruit 0.96" OLED slow response (Read 272 times) previous topic - next topic

vishruth_kumar

Apr 07, 2017, 09:51 pm Last Edit: Apr 07, 2017, 10:07 pm by vishruth_kumar
Hello,
I am trying to get readings on OLED connected to master arduino from an LDR connected to Slave arduino through bluetooth serial communication.

Slave code:
Code: [Select]
#include <SoftwareSerial.h>
SoftwareSerial BTSerial(10, 11); // RX | TX
#define ldrPin A0
int ldrValue = 0;
void setup() {
  pinMode(9, OUTPUT);  // this pin will pull the HC-05 pin 34 (key pin) HIGH to switch module to AT mode
  digitalWrite(9, HIGH);
  pinMode(ldrPin, INPUT);
  BTSerial.begin(9600);
  Serial.begin(9600);
  
}
void loop()
{
 ldrValue = analogRead(ldrPin);
 BTSerial.println(ldrValue);
 Serial.println(ldrValue);
 delay(1000);
}


Master code(Containing OLED):
Code: [Select]
#include <SoftwareSerial.h>
SoftwareSerial BTSerial(10, 11); // RX | TX
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
char inchar;
String string;

void setup()
{
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);// initialize with the I2C addr 0x3C (for the 128x32)(initializing the display)
  Serial.begin(9600);
  BTSerial.begin(9600);
  pinMode(9, OUTPUT);  // this pin will pull the HC-05 pin 34 (key pin) HIGH to switch module to AT mode
  digitalWrite(9, HIGH);
  string.reserve(200);
  
  display.display();
  delay(2000);
  display.clearDisplay();
  display.setTextSize(0.5);
  display.setTextColor(INVERSE);
}

void BTread()
{
   if (BTSerial.available()) //checks for incoming data
    {
      display.clearDisplay();
      inchar = BTSerial.read();
      string+=inchar;
      display.setCursor(30,0);
      display.setTextSize(1);
      display.print("LDR Reading:");
      display.setCursor(50,0);
      display.setTextSize(2);
      display.print(string);
        if( inchar == '\r'){
                    Serial.println("End");                
                    delay(100);
                    display.setCursor(50,10);
                    display.setTextSize(2);
                    string="  ";
                    //display.print(string);
        }
                
      
      display.display();
    }
}

void loop()
{
   BTread();
   display.display();
}  
  


Code is working fine and I am able to get the readings. But there is a slight problem. The readings which are displayed on OLED is lagging and being refreshed slowly.Also ffor the readings I have set a cursor (30,10) but there is another reading having almost same value printed exactly below it.(shown in pdf)

Can somebody help me to sort out this problem?
Master arduino - Arduino nano
Slave arduino - Arduino uno

Thanks in advance


bodmer

#1
Apr 07, 2017, 11:15 pm Last Edit: Apr 07, 2017, 11:16 pm by bodmer
Read this.

Note that println() sends a carriage return '\r' plus a newline '\n' and the newline will cause the cursor to move to the start of the next line on the display. Notice that you are adding the newline (and the carriage return) to the string with string+=inchar;

Formerly Rowboteer (now a broken user profile!)

vishruth_kumar

Any idea how to eliminate '\n' so that my cursor in OLED will be Fixated at (30,10)?
Code: [Select]
while(inchar!='\n')
         {
             string+=inchar;
          }


This is not solving the issue as the OLED remains blank
This code is fast and responsive. But the transition from one reading to another is done by momentary refresh and new reading. I want the transition to occur in such a way that the userr finds it easy to read.

One possible solution is instead of BTSerial.read() , I used BTSerial.readString(). It has eliminated the transition problem.
Code: [Select]
#include <SoftwareSerial.h>
SoftwareSerial BTSerial(10, 11); // RX | TX
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
char inchar;
String string;

void setup()
{
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);// initialize with the I2C addr 0x3C (for the 128x32)(initializing the display)
  Serial.begin(9600);
  BTSerial.begin(9600);
  pinMode(9, OUTPUT);  // this pin will pull the HC-05 pin 34 (key pin) HIGH to switch module to AT mode
  digitalWrite(9, HIGH);
  string.reserve(200);
   
  display.display();
  delay(2000);
  display.clearDisplay();
  display.setTextSize(0.5);
  display.setTextColor(INVERSE);
}

void loop()
{
   if (BTSerial.available()) //checks for incoming data
    {
      display.clearDisplay();
   
      string = BTSerial.readString();
      display.setCursor(30,0);
      display.setTextSize(1);
      display.print("LDR Reading:");
      display.setCursor(30,10);
      display.setTextSize(2);
      display.print(string);
     
     
      display.display();
   
      }
   
   
   display.display();
}

   


But is relatively slow in response. Also a new reading as shown in the pdf file of previous post is being printed in new line below actual reading.

What modifications should I do???
Thanks in advance

bodmer

Code: [Select]
while(inchar!='\n')
         {
             string+=inchar;
          }


This is not solving the issue as the OLED remains blank
Clearly this will loop forever if inchar is not '\n', so it is no surprise that the display remains blank.

One option is to not use println() in the sender, but use print() followed by write('\r')

Another option in the receiver is to use:

Code: [Select]

if(inchar!='\n'  && inchar!='\r' ) string+=inchar;


Formerly Rowboteer (now a broken user profile!)

vishruth_kumar

Thank you so much , its working!!
Kindly let me know if you have the solution for the smooth transition between readings .
The way the readings are being displayed on my OLED can be compared to an led light blinking after 1 second . I want the consecutive readings to be displayed in place of the previous reading without clearing the display.

bodmer

The problem with blinking is because the display is being erased and updated for every character that is arriving.

Make it more efficient and only clear and update the display when a '\r' arrives. You should be able to get it to update the display without any blinking if you do this.

Have a go at modifying your code, if you don't succeed post back and I will give you more help.
Formerly Rowboteer (now a broken user profile!)

vishruth_kumar

Thanks for the tip. Initially the "LDR READING" text remained as it is but the actual reading was blinking . Now I have changed the code as:
Code: [Select]
#include <SoftwareSerial.h>
SoftwareSerial BTSerial(10, 11); // RX | TX
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
char inchar;
String string;
String onchar;

void setup()
{
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);// initialize with the I2C addr 0x3C (for the 128x32)(initializing the display)
  Serial.begin(9600);
  BTSerial.begin(9600);
  pinMode(9, OUTPUT);  // this pin will pull the HC-05 pin 34 (key pin) HIGH to switch module to AT mode
  digitalWrite(9, HIGH);
  string.reserve(200);
   
  display.display();
  delay(2000);
  display.setTextColor(INVERSE);
 
}

void BTread()
{
 
  if (BTSerial.available()) //checks for incoming data
    {
     
       display.setCursor(30,0);
       display.setTextSize(1);
       display.print("LDR Reading:");
         inchar = BTSerial.read();
         if(inchar!='\n'  && inchar!='\r' )
         {
             string+=inchar;
          }
          if (inchar=='\r')
          {
           
            display.clearDisplay();
           
           
          } 
     
      display.setCursor(30,10);
      display.setTextSize(2);
      display.print(string);
        if( inchar == '\r'){
                    Serial.println("End");               
                    //delay(100);
                    display.setCursor(30,10);
                    display.setTextSize(2);
                    string="  ";
                   
                    //display.print(string);
                   
        }
               
     
      display.display();
    }
}

void loop()
{
 
   BTread();
   display.display();
}   
   


The transition between the readings are much smoother. But the "LDR READING:" text is blinking now. I tried placing the line
Code: [Select]
display.setCursor(30,0);
       display.setTextSize(1);
       display.print("LDR Reading:");


before the line
Code: [Select]
if (BTSerial.available()) //checks for incoming data
    {

Here the text does not blink but it flickers. Any idea to resolve this?

Thanks in advance!

bodmer

Hi,

The line
Code: [Select]
display.display();
redraws the display and you have included this multiple times and the code that updates the screen is scattered about!

You only need to update and redraw the screen once a '\r' is received which indicates the complete new value has arrived.  Something like this might work (untested!):

Code: [Select]

#include <SoftwareSerial.h>
SoftwareSerial BTSerial(10, 11); // RX | TX
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
char inchar;
String string;
String onchar;

void setup()
{
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);// initialize with the I2C addr 0x3C (for the 128x32)(initializing the display)
  Serial.begin(9600);
  BTSerial.begin(9600);
  pinMode(9, OUTPUT);  // this pin will pull the HC-05 pin 34 (key pin) HIGH to switch module to AT mode
  digitalWrite(9, HIGH);
  string.reserve(200);

  display.display();
  delay(2000);
  display.setTextColor(INVERSE);

}

void BTread()
{
  if (BTSerial.available()) //checks for incoming data
  {
    inchar = BTSerial.read();

    if (inchar != '\n'  && inchar != '\r' )
    {
      string += inchar;
    }

    if (inchar == '\r')
    {
      display.clearDisplay();
      display.setCursor(30, 0);
      display.setTextSize(1);
      display.print("LDR Reading:");
      display.setCursor(30, 10);
      display.setTextSize(2);
      display.print(string);
      display.display();

      string = "";
    }
  }
}

void loop()
{
  BTread();
}


If you want to right justify the number check the length of the string and add spaces to the start immediately before printing to the screen.
Formerly Rowboteer (now a broken user profile!)

vishruth_kumar

Thank you so much!! , we are actually getting our desired results.

Go Up