LDR Analog reading via Bluetooth

I have paired two Hc05 modules for my project.For testing purpose I have connected initially a pushbutton to slave and led to master and I am able to control the led using pushbutton via Blueotth.

Now I have connected a LDR(Light dependant Resistors) to slave which will be communicating to master connected to 0.96'' OLED . The OLED should be displaying the values of LDR

Slave code:

#include <SoftwareSerial.h>
SoftwareSerial BTSerial(10, 11); // RX | TX
#define ldrPin A0
int state = 20;
int ldrValue = 0;
char ldr;
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, OUTPUT);
  BTSerial.begin(9600);
  
}
void loop() 
{
 ldrValue = analogRead(A0);
 BTSerial.write(ldrValue); 
 delay(10);
}

Master code :

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SoftwareSerial.h>
SoftwareSerial BTSerial(10, 11); // RX | TX
int state = 0;
#define OLED_RESET 4 // not used / nicht genutzt bei diesem Display
Adafruit_SSD1306 display(OLED_RESET);

 char inChar;
 String string;


void setup()   { 

  pinMode(13, OUTPUT);
  
 // initialize with the I2C addr 0x3C / mit I2C-Adresse 0x3c initialisieren
 display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
 pinMode(9, OUTPUT);  // this pin will pull the HC-05 pin 34 (key pin) HIGH to switch module to AT mode
 digitalWrite(9, HIGH);
                 
 
  BTSerial.begin(9600);
  display.display();
  delay(2000);
  display.clearDisplay();
 
  display.setTextColor(INVERSE); 
}

void loop()
{ 
  if(BTSerial.available() > 0)
  { // Checks whether data is comming from the serial port
    state = BTSerial.read(); // Reads the data from the serial port
   }
   
    
      display.clearDisplay();
      
      display.setCursor(30,0); 
      display.setTextSize(1);
      display.print("LDR Reading:");
      display.setCursor(30,10); 
      display.setTextSize(2);
      display.print(state);
      delay(10);           
      display.display(); 
}

But I am unable to get the complete reading . The OLED shows readings as 0,1,2,3 (single digits fluctuating randomly.

Can someone help me out? Thanks in advance

Instead of

BTSerial.write(ldrValue);

use

BTSerial.println(ldrValue);

and use one of the examples in Serial Input Basics to receive the data.

Serial.write() just sends a byte as a binary value. Sending data in human readable form with .print() makes debugging much easier. I would only use .write() if I had no choice because I needed the extra performance.

...R

Thank you for your response sir,

Now the OLED is displaying values from 0 to 50 fluctuating. Its not showing the exact values as the LDR value ranges from 0 to 1023.

Any solution to this problem?

vishruth_kumar:
Now the OLED is displaying values from 0 to 50 fluctuating.

That sounds like you have a new program that you have not posted - so how can I help?

And please post the new code after this Reply and do not over-write your earlier code.

...R

This is the updated code

Slave code :

#include <SoftwareSerial.h>
SoftwareSerial BTSerial(10, 11); // RX | TX
#define ldrPin A0
int state = 20;
int ldrValue = 0;
char ldr;
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, OUTPUT);
  BTSerial.begin(9600);
  
}
void loop() 
{
 ldrValue = analogRead(A0);
 BTSerial.println(ldrValue); 
 delay(10);
}

Master code :

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SoftwareSerial.h>
SoftwareSerial BTSerial(10, 11); // RX | TX
int state = 0;
#define OLED_RESET 4 // not used / nicht genutzt bei diesem Display
Adafruit_SSD1306 display(OLED_RESET);

 char inChar;
 String string;


void setup()   { 

  pinMode(13, OUTPUT);
  
 // initialize with the I2C addr 0x3C / mit I2C-Adresse 0x3c initialisieren
 display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
 pinMode(9, OUTPUT);  // this pin will pull the HC-05 pin 34 (key pin) HIGH to switch module to AT mode
 digitalWrite(9, HIGH);
                 
 
  BTSerial.begin(9600);
  display.display();
  delay(2000);
  display.clearDisplay();
 
  display.setTextColor(INVERSE); 
}

void loop()
{ 
  if(BTSerial.available() > 0)
  { // Checks whether data is comming from the serial port
    state = BTSerial.read(); // Reads the data from the serial port
   }
   
    
      display.clearDisplay();
      
      display.setCursor(30,0); 
      display.setTextSize(1);
      display.print("LDR Reading:");
      display.setCursor(30,10); 
      display.setTextSize(2);
      display.print(state);
      delay(10);           
      display.display(); 
}

You have not included any of the functions from my link into your Master program - as suggested in Reply #1.

With the slave code that you have you should use the 2nd example in my link.

...R

Previously the output on led was (48,13,10) changing in interval of 1 sec when i incresed the delay in master code to delay(1000).

Now Keeping the slave code as it is and changing the master code as follows according to example 2 of your link :

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SoftwareSerial.h>
SoftwareSerial BTSerial(10, 11); // RX | TX

int state = 0;
#define OLED_RESET 4 // not used 
Adafruit_SSD1306 display(OLED_RESET);

char inChar;
String string;

const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data
boolean newData = false;


void setup()   
{ 

 pinMode(13, OUTPUT);
 // initialize with the I2C addr 0x3C / mit I2C-Adresse 0x3c initialisieren
 display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
 pinMode(9, OUTPUT);  // this pin will pull the HC-05 pin 34 (key pin) HIGH to switch module to AT mode
 digitalWrite(9, HIGH);
                 
 
  BTSerial.begin(9600);
  display.display();
  delay(2000);
  display.clearDisplay();
  display.setTextColor(INVERSE); 
}

void loop() 
{
    recvWithEndMarker();
    showNewData();
}

void recvWithEndMarker() {
    static byte ndx = 0;
    char endMarker = '\n';
    char rc;
    
    while (BTSerial.available() > 0 && newData == false) {
        rc = BTSerial.read();

        if (rc != endMarker) {
            receivedChars[ndx] = rc;
            ndx++;
            if (ndx >= numChars) {
                ndx = numChars - 1;
            }
        }
        else {
            receivedChars[ndx] = '\0'; // terminate the string
            ndx = 0;
            newData = true;
        }
    }
}

void showNewData() 
{
    if (newData == true) {
      display.clearDisplay();
      display.setCursor(30,0); 
      display.setTextSize(1);
      display.print("LDR Reading:");
      display.setCursor(30,10); 
      display.setTextSize(2);
      display.print();
      delay(10);           
      display.display(receivedChars); 
      newData = false;
    }
}

This program is taking too long to compile. The IDE is sort of getting hanged in the compilation process.

Is the program running in endless loop or something?

I am a mechanical engineer and it took a while to understand the serial communication. It was quite helpful. Please help me in this situation!

Thanks in advance

Normally what goes on in the code has no effect on the compiler - unless it detects an error. I can't try compiling your code because I don't have the Adafruit libraries.

The Arduino IDE is written in Java and occasionally the Java code finds something it does not like - probably because the Arduino creators forgot to handle an exception. The stuff it does not like is usually due to a typo so go through your code VERY carefully.

I have not checked carefully to see if you have mucked up my function code - but I don't think you have. However, even if you had, it should not cause the compiler to hang.

Have you tried compiling my examples without any changes?

I sympathize with your frustration.

...R

Rectified a small error. The program compiled without errors .
But the output on OLED showed random readings on 0,1,001,20,..etc. This is not the correct readings of LDR.

The example 2 of your link compiled without errors and it is showing correct readings in serial monitor. But it is not showing the correct reading after the modificaions. The slave code is as it is and the modification was in master code:

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SoftwareSerial.h>
SoftwareSerial BTSerial(10, 11); // RX | TX

int state = 0;
#define OLED_RESET 4 // not used 
Adafruit_SSD1306 display(OLED_RESET);

char inChar;
String string;

const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data
boolean newData = false;


void setup()   
{ 

 pinMode(13, OUTPUT);
 // initialize with the I2C addr 0x3C / mit I2C-Adresse 0x3c initialisieren
 display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
 pinMode(9, OUTPUT);  // this pin will pull the HC-05 pin 34 (key pin) HIGH to switch module to AT mode
 digitalWrite(9, HIGH);
                 
 
  BTSerial.begin(9600);
  display.display();
  delay(2000);
  display.clearDisplay();
  display.setTextColor(INVERSE); 
}

void loop() 
{
    recvWithEndMarker();
    showNewData();
}

void recvWithEndMarker() 
{
    static byte ndx = 0;
    char endMarker = '\n';
    char rc;
    
    while (BTSerial.available() > 0 && newData == false) {
        rc = BTSerial.read();

        if (rc != endMarker) {
            receivedChars[ndx] = rc;
            ndx++;
            if (ndx >= numChars) {
                ndx = numChars - 1;
            }
        }
        else {
            receivedChars[ndx] = '\0'; // terminate the string
            ndx = 0;
            newData = true;
        }
    }
}

void showNewData() 
{
    if (newData == true) {
      display.clearDisplay();
      display.setCursor(30,0); 
      display.setTextSize(1);
      display.print("LDR Reading:");
      display.setCursor(30,10); 
      display.setTextSize(2);
      display.print(receivedChars);
      delay(1000);           
      display.display(); 
      newData = false;
    }
}

Sir, I request you to help me. The Adafruit library is available in this link:
GitHub - adafruit/Adafruit_SSD1306: Arduino library for SSD1306 monochrome 128x64 and 128x32 OLEDs.

Thanks in advance

What happens if you use the showNewData() function to show the contents of receivedChars on the Serial Monitor.

It is usually a good idea to get a program working with simple and well tried output before adapting it to other displays.

What is the longest piece of data you need to receive. Maybe the line const byte numChars = 32; needs to have a larger number?

...R
PS. You don't need this line of code any more

String string;

My bad , I assigned LDR pin as output instead of input. Yes I modified the slave code to check whether it is sending correct reading or not on serial monitor.
Slave code:

#include <SoftwareSerial.h>
SoftwareSerial BTSerial(10, 11); // RX | TX
#define ldrPin A0
int state = 20;
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(10);
}

The serial monitor showed the correct readings.

Now I changed master code to get readingson serial monitor. Master code:

// Example 2 - Receive with an end-marker
#include <SoftwareSerial.h>
SoftwareSerial BTSerial(10, 11); // RX | TX
const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data

boolean newData = false;

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);
    BTSerial.begin(9600);
    Serial.begin(9600);
    Serial.println("<Arduino is ready>");
}

void loop() {
    recvWithEndMarker();
    showNewData();
}

void recvWithEndMarker() {
    static byte ndx = 0;
    char endMarker = '\n';
    char rc;
    
    while (BTSerial.available() > 0 && newData == false) {
        rc = BTSerial.read();

        if (rc != endMarker) {
            receivedChars[ndx] = rc;
            ndx++;
            if (ndx >= numChars) {
                ndx = numChars - 1;
            }
        }
        else {
            receivedChars[ndx] = '\0'; // terminate the string
            ndx = 0;
            newData = true;
        }
    }
}

void showNewData() {
    if (newData == true) {
        Serial.print("This just in ... ");
        Serial.println(receivedChars);
        delay(10);
        newData = false;
    }
}

But her the Serial monitor is just showing

<Arduino is ready>

The readings of LDR changes from 0 to 1023. I tried changing numChars from 32 to 128 . Still the serial monitor showed no readings.

What can be possibly wrong here? Initially it was showing some readings when I wrongly assigned LDRpin as output instead of input. Now after correcting it , it is not showing any value.

Have you got the serial connections between the Arduinos wired correctly? Rx should go to Tx and Tx to Rx and GND to GND?

...R

Yes the connection are correct. Initially I was able to control a LED connected to master from a pushbutton connected to slave. The connections of modules were unchanged. Instead of pushbutton , LDR is connected to slave for input and instead of LED , an OLED is connected to master for output.

vishruth_kumar:
Yes the connection are correct. Initially I was able to control a LED connected to master from a pushbutton connected to slave. The connections of modules were unchanged. Instead of pushbutton , LDR is connected to slave for input and instead of LED , an OLED is connected to master for output.

I can't make any sense of that. You know a whole lot more about your project than we do.

Make a simple drawing showing how you have everything connected and post a photo of the drawing. Please DO NOT use Fritzing.

...R

Slave part :
Ldr and hc05 module is connected to Arduino Uno. The ldr will be taking the readings and communicating it to Arduino through analog pin (A0) .

Master part :
The hc05 module is connected to Arduino nano. It'll be getting readings from slave and display the same on serial monitor. Once I get the readings on serial monitor , I'll connect OLED to Arduino nano to display the readings .

Doc1.pdf (270 KB)

Following the same connections with slave code as:

#include <SoftwareSerial.h>
SoftwareSerial BTSerial(10, 11); // RX | TX
#define ldrPin A0
int state = 20;
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(10);
}

and master code as:

// Example 2 - Receive with an end-marker
#include <SoftwareSerial.h>
SoftwareSerial BTSerial(10, 11); // RX | TX
const byte numChars = 1024;
char receivedChars[numChars];   // an array to store the received data

boolean newData = false;

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);
    BTSerial.begin(9600);
    Serial.begin(9600);
    Serial.println("<Arduino is ready>");
}

void loop() {
    recvWithEndMarker();
    showNewData();
}

void recvWithEndMarker() {
    static byte ndx = 0;
    char endMarker = '\n';
    char rc;
    
    while (BTSerial.available() > 0 && newData == false) {
        rc = BTSerial.read();

        if (rc != endMarker) {
            receivedChars[ndx] = rc;
            ndx++;
            if (ndx >= numChars) {
                ndx = numChars - 1;
            }
        }
        else {
            receivedChars[ndx] = '\0'; // terminate the string
            ndx = 0;
            newData = true;
        }
    }
}

void showNewData() {
    if (newData == true) {
        Serial.print("This just in ... ");
        Serial.println(receivedChars);
        delay(1000);
        newData = false;
    }
}

I am getting the readings in serial monitor of master as:

<Arduino is ready>
This just in ... 8
This just in ... 3
This just in ... 4
This just in ... 3
This just in ... 3
This just in ... 3
This just in ... 3
This just in ... 4
This just in ... 3
This just in ... 4
This just in ... 3
This just in ... 3

and so on. The problem might be with the code Can you please check?

I don't have time to study all this now. I will bookmark it and try to look at it in the morning.

...R

I tried searching in other forums and blogs, could not find the solution. Please take your time , and look into this.

Its really important for me to get this working.

Oh come on dont leave me hanging!!
I followed every step. The serial monitor of master is showing the first digit , but it is correct. How can I receive the exact readings . There must be slight modifications in the functions in the Example 2 of your link.

I am a beginner in arduino , So I am not able to understand. Please help me!

Sorry. I forgot about you - I was distracted by trying to build a model railway locomotive.

My guess is that your master program is actually showing what it receives. If it was not receiving anything it would not print anything.

Debugging should always focus on simplicity. Rather than sending the value from the LDR why not just send a fixed value - for example BTSerial.println("1234");

Also, you are sending values very frequently - 100 times per second. For testing slow that down to 2 per second.

In your slave program you are printing the value to the Serial monitor - is that showing the same thing as the master is receiving?

In the direction of simplicity it would also be a good idea to remove the Bluetooth devices and connect the two Arduinos by wires (and GND) using the same pins as are used by the Bluetooth devices.

...R