Go Down

Topic: LDR Analog reading via Bluetooth (Read 2686 times) previous topic - next topic

vishruth_kumar

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:
Code: [Select]
#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 :
Code: [Select]
#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

Robin2

Instead of
Code: [Select]
BTSerial.write(ldrValue);
use
Code: [Select]
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
Two or three hours spent thinking and reading documentation solves most programming problems.

vishruth_kumar

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?

Robin2

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
Two or three hours spent thinking and reading documentation solves most programming problems.

vishruth_kumar

This is the updated code

Slave code :
 
Code: [Select]
#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 :

Code: [Select]
#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();
}

Robin2

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
Two or three hours spent thinking and reading documentation solves most programming problems.

vishruth_kumar

#6
Apr 02, 2017, 07:52 am Last Edit: Apr 02, 2017, 08:58 am by vishruth_kumar
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 :

Code: [Select]
#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

Robin2

#7
Apr 02, 2017, 09:30 am Last Edit: Apr 02, 2017, 09:32 am by Robin2
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
Two or three hours spent thinking and reading documentation solves most programming problems.

vishruth_kumar

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:

Code: [Select]
#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:
https://github.com/adafruit/Adafruit_SSD1306.

Thanks in advance

Robin2

#9
Apr 02, 2017, 02:18 pm Last Edit: Apr 02, 2017, 02:20 pm by Robin2
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
Code: [Select]
String string;
Two or three hours spent thinking and reading documentation solves most programming problems.

vishruth_kumar

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:
Code: [Select]
#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:
Code: [Select]

// 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
Code: [Select]
<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.


Robin2

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
Two or three hours spent thinking and reading documentation solves most programming problems.

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.

Robin2

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
Two or three hours spent thinking and reading documentation solves most programming problems.

vishruth_kumar

#14
Apr 03, 2017, 04:54 pm Last Edit: Apr 03, 2017, 05:03 pm by vishruth_kumar
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 .

Go Up