Arduino and App bluetooth

https://projecthub.arduino.cc/mukeshkp2005/a7ad0a01-b777-4fe1-a5c9-f62c68b96829

Hi, so i'm making a greenhouse system which can be manually controlled with an app. The bluetooth and everything is working fine when i want to display sensor values (temperature, humidty etc) on the app. Values are accurate, bluetooth are able to connect and more.

However, i want to be able to switch led/motors on from the app and tried the link above (i've done the same with a few other tutorial variations of controlling LED with mit app inventor, does not work for me too).
Does not work at all even if i copied the code + app word for word (with changing the ports ofc). Any idea why it does not work?


image

1 Like

Dear @Celestial,
but you send "1" and "2" while you check for "1" and "0" ?
More: when the app is sending the characters probably it adds a 0x0D or a 0x0A so checking for the exact character "1" or "0" can be foolished by the presence of the control characters (0x0D or a 0x0A).
Give it a sight.
Cheers.

Changed it, sadly arduino is still not receiving anything (serial monitor shows no input aswell).
Thanks for the headsup!

Hi @Celestial,
I assume that the same HW that you say is working fine in sending the sensors' data to the app is still the same that you use to switch on-off the LED.
Having said that, which Arduino board are you using: a UNO, NANO, MEGA, other...?, and which BT interface : a HC05, HC06, a BLE ?

Once clarified that, please be aware that it seems that you use the same serial line for both PC monitor and BT. So whenever you send a character to the monitor, you're sending also to the BT toward the app. This is not really "good". You should better differentiate the serial line toward the BT (for example by using the SoftwareSerial library, mapping the Tx and Rx on pins 2,3 or 10,11, depending on the Arduino board and the HC0x interface. Or something else, it depends on your HW. Or you can avoid to monitor the data on the PC and use only the HW serial line toward the app, without sending anything to the PC.
BTW, are you sure that the Rx pin on the Arduino board is correctly connected ?
Please check as an example the annexed drawing.
image
Wishing you success.
Ciao.

1 Like

Serial.readString()

Does this help? should read the value as text, as AI sends it as text I think.

I'm using an ESP32 and use #include "BluetoothSerial.h"
String stringReceived = (SerialBT.readString());

i dont know if BluetoothSerial will work with hc-06

For added confusion there are 2 data types in arduino code
string
and
String()

Dear @Celestial,
any news about ?
Whether it's still not working, would you mind to post the HW scheme of your implementation?
I mean: which Arduino board are you using and BT interface type: HC05, HC06, ESP32, others... ?
Have you tried to verify if your app is really sending out data by connecting via BT a PC with a simple terminal software like Tera Term ? (the link here below downloads the Italian version, but you can find the version in your language).

Hint for a (fussy :nerd_face:) improvement in your Arduino file.
Since you declare LEd as "const int LED = 10", you should better write: "digitalWrite(LED, HIGH);" (and LOW obviously). In addition to this, for pins definition, Arduino forum suggests this syntax: #define LED 10;" instead of "const int LED = 10" so the compiler will not create a variable, therefore will not reserve (nor RAM neither) FLASH memory for that.

Cheers.

Hi, i'll be updating in abit sorry! Was super busy with finals and finally had the time to revisit my final year project. Really appreaciate all the information you all have been providing and i shall let you all know the result in abit.

Hi @Celestial,
take it easy :grinning_face_with_smiling_eyes:, it's just to know if you have succeeded and (in the case) how, so to share the knowledge with the community.
Best wishes, Ugo

My bad for a few more days of delay, since its chinese new year i had to head back to my hometown for abit!

My bluetooth module is HC06, using Arduino Mega. I modified the code abit and seems to still not work.
HC06 module is connected to (RX1 to pin 19, TX1 to pin 18)
I tried both
SoftwareSerial bt(19, 18);
SoftwareSerial bt(18, 19);
in case it was a switchup between RX and TX, still could not control the LED.


This is my current project's code for both arduino and app. The app is able to recieve data accurately from the arduino.

#include <SoftwareSerial.h>

#include <LiquidCrystal_I2C.h>

#include <Wire.h>

#include <DHT.h>

#define DHTPIN A1

#define DHTTYPE DHT22

#define LEDG_PIN 9

#define LEDR_PIN 10

SoftwareSerial bt(18, 19);

DHT dht(DHTPIN, DHTTYPE);

LiquidCrystal_I2C lcd1 = LiquidCrystal_I2C(0x27, 20, 4);

LiquidCrystal_I2C lcd2 = LiquidCrystal_I2C(0x26, 20, 4);

float humidity;

float temp;

int relayOn = LOW;

int relayOff = HIGH;

int ldr = A0;

int ms = A2; //moisture sensor

int fan = 4;

int led = 5;

int water = 6;

int valueldr = 0;

int valuems = 0;

char Incoming_value = 0;

void setup() {

lcd1.init();

lcd1.backlight();

lcd2.init();

lcd2.backlight();

pinMode(ldr, INPUT);

pinMode(ms, INPUT);

pinMode(fan, OUTPUT);

pinMode(led, OUTPUT);

pinMode(water, OUTPUT);

pinMode(LEDR_PIN, OUTPUT);

pinMode(LEDG_PIN, OUTPUT);

bt.begin(9600);

dht.begin();

Serial.begin(9600);

}

void loop(){

delay (2000);

valueldr = analogRead(ldr);

valuems = analogRead(ms);

humidity = dht.readHumidity();

temp = dht.readTemperature();

lcd1.setCursor(0,0);

lcd1.print("Humidity:");

lcd1.setCursor(0,1);

lcd1.print(humidity);

lcd1.print("%");

lcd1.setCursor(0,2);

lcd1.print("Temperature:");

lcd1.setCursor(0,3);

lcd1.print(temp);

lcd1.print((char)223);

lcd1.print("C");

lcd2.setCursor(0,0);

lcd2.print("Light Intensity:");

lcd2.setCursor(0,1);

lcd2.print(valueldr);

lcd2.setCursor(0,2);

lcd2.print("Soil Moisture:");

lcd2.setCursor(0,3);

lcd2.print(valuems);

if (valueldr > 900)

{

digitalWrite(led, relayOn);

}

else {

digitalWrite(led, relayOff);

}

if (humidity > 70) {

digitalWrite(fan, relayOn);

}

else {

digitalWrite(fan, relayOff);

}

if (valuems < 10) {

digitalWrite(water, relayOn);

}

else {

digitalWrite(water, relayOff);

}

if (temp < 40 && temp > 20) {

digitalWrite(LEDR_PIN, HIGH);

digitalWrite(LEDG_PIN, LOW);

}

else if(temp < 20 && temp > 40) {

digitalWrite(LEDR_PIN, LOW);

digitalWrite(LEDG_PIN, HIGH);

}

bt.print(temp);

bt.print(";");

bt.print(humidity);

bt.println(";");

bt.print(analogRead(ldr));

bt.println(";");

bt.print(analogRead(ms));

bt.println(";");

}

image

Dear @Celestial,
first of all enjoy your New Year vacation !!!
Then, I see a few things:
if you use a Mega, there is no need to use the SoftwareSerial library, because the MEGA features 4 HW serial lines. Therefore you can access directly the TX1 (pin18) and RX1(pin 19) without any library. The TX pin of the MEGA shall be linked to the Rx of the HC06 (better with a partition, to reduce the voltage to 3.3 Vdc).
Another thing is how you send data to the app:

bt.print(temp);
bt.print(";");
bt.print(humidity);
bt.println(";"); in my opinion you should better write -> bt.print(";");
bt.print(analogRead(ldr));
bt.println(";"); in my opinion you should better write -> bt.print(";");
bt.print(analogRead(ms));
bt.println(";") This is correct (but read also below, after the image) because in my opinion only at the last character you should better send the CRLF (0x0D 0x0A) pair, so to advise the app that the transmission is ended. To this purpose the BT receiver block could be varied as follows:

image

The variable "your code" is a fake one :slight_smile: it is just to say that you should put your code there below.
Last but not least, since you split the received text at ";" you don't need to send the last ";", otherwise the split block will create an empty (last) element of the list; and this will foolish the lenght of list block. In case you use it, the leght block will return a number increased by 1 = the last empty element.
Therefore the last sending from the MEGA to the app shall be just a bt.println();

:grimacing:But, most important, your Arduino code for LED's driving (the snapshot in one of your previous posts) isn't correct. :hushed:
Supposing that you still use the SoftwareSerial, namely bt, you should not test for Serial input but for BT input like this:
if (bt.available() > 0)
{
switchstate = bt.read();
}
Give it a look .... :grinning_face_with_smiling_eyes:
Nǐ hǎo

1 Like

Thank you, you too!

I've fixed the bt.print(";"); and bt.print(); n the last one, really helpful information thank you!

However, unfortunately the LED control part still dosent work for me and not sure why, i might have to rebuild another circuit and test it while refering exactly the same code and circuit diagram as some other tutorials.

Below is the updated code, i've tried with and without the software serial library lines as well since Mega already has an Rx Tx port like you mentioned earlier.

I really really appreciate all the advice, information and follow up you've been doing @uskiara, you're amazing for this!

Hi @Celestial,
sorry, I reckon that I've been not clear: :upside_down_face:
if you use SoftwareSerial you shall allocate two digital pins to do that, and not using pins 19 and 18 that are intended as HW Serial number 1 (Serial1 in Arduino code).
Supposing then that you don't use the SoftwareSerial, and you want to use Serial1 instead, the initialization should be:

#define bt Serial1 // Serial1 is a keyword for MEGA, therefore shall become red in your code
#define BAUDRATE 9600

void setup()
{
.....
Serial1.begin(BAUDRATE);
.....
}

loop()
{
if (bt.available() > 0)
{
switchstate = bt.read();
}
your code like before:

}

:crossed_fingers:

Hello Celestial

Think of 'BytesAvailableToRecieve' as a flag that reports there are bytes available, not as a function that 'knows' how many bytes there are in total.

Therefore:

  1. use: > 0
  2. use -1
    NumberOfBytes

When you read the data in and split it into a List, check the length of List is correct before populating Labels. Example:

Sketch - only one bt.println should be used - this will allow \n to be the delimiter byte:

Snap1

bt.print(temp);
bt.print(";"); //Value delimiter
bt.print(humidity);
bt.print(";");
bt.print(analogRead(ldr));
bt.println(";");
bt.print(analogRead(ms));
bt.println(); //Data Package Delimiter: This empty last line tells App "End of Data" = Ascii LineFeed Char Number 10

When reading sensors:

  1. Reduce the decimal places of the values to the minimum required. Your BT data packet is only 23 bytes, 20 or so carries your data.

  2. Do not use "delay()" in your Loop, that will cause inaccuracy - use elapsed milliseconds instead, similar to this:

//Fake data stream to demo elapased milliseconds timing


//vars
unsigned long lgUpdateTime;

void setup()
{
               Serial.begin(9600);
               lgUpdateTime = millis();
}

void loop()
{
	           if(millis() - lgUpdateTime > 5000)           //Loop approx every 5 seconds
               {
                         lgUpdateTime = millis();

                         //Bluetooth to App
                         Serial.print("Hello");
                         Serial.print("|");      //Value delimiter
                         Serial.print("World");
                         Serial.print("|");
                         Serial.println();        //This empty last line tells App "End of Data" = Ascii LineFeed Char Number 10
               }
}
1 Like

Appreciate the further clarfication and help!

Unfortunately to no avail it is still not working.
I've made an extra circuit (only the led and bluetooth module) and remade the app to troubleshoot the issue.

i followed this link (probably the 7th tutorial i followed, though they're all the same nearly)
I'm going a stretch and assume that there is fault in the bluetooth module itself, I'll be getting another one to do further testing and hopefully this time it will work!

That is a good approach to tracking the cause of the issue, a professional approach.

Make sure the Bluetooth module is genuine - I have a list of genuine modules on my website.

https://www.professorcad.co.uk/appinventortips#TipsBluetooth

...and potential reasons for Bluetooth failure:
https://www.professorcad.co.uk/appinventortips#BluetoothFailure

If you upload your troubleshoot App Inventor project .aia file and your Arduino Sketch .ino, we can take a look to see if anything is missing.

Hi
Found this tuto that worked for me: https://howtomechatronics.com/tutorials/arduino/how-to-build-custom-android-app-for-your-arduino-project-using-mit-app-inventor/
They explain that you have to send the number 49 to get a 1 into your Arduino variable, and a 48 to get a 0 (ASCII number tables). I don't know exactly why but it works for me. Perhaps contact the author of the tuto.
Regards

Dear @Celestial,
while developing another application on Arduino IDE and a MEGA I discovered a pretty weird anomaly: the delay(milliseconds); instruction :frowning_face: blocks :frowning_face:any serial communication of the three serial lines called Serial1,2,3.
So, as @ChrisWard just have said, don't use the delay(), instruction, otherwise you'll never see any character leaving the MEGA. Only the serial0 (i.e. on pins 0,1) can still work if you use the delay();
In a nuthshell: avoid always to use the delay() and use the millis() instead, as Chris as shown.
Hoping this helps.
Ni-hao,
Ugo.