Serial.read() - XBee - not firing 'else if' - arduino

I am currently trying to do some communication test between a PC and Arduino Uno using an XBee in AT mode.
My test is to send characters from the computer to the XBee and process through conditional statements.
I don't believe this issue is with configuration of the XBees, for I am able to communicate successfully when I watch the Serial monitors.
Here is the code I am running on the Arduino:
#include <SoftwareSerial.h>
SoftwareSerial xBee = SoftwareSerial(1, 0);
int Led = 9;
void setup()
{
pinMode(Led, OUTPUT);
xBee.begin(9600);
}
void loop()
{
if (xBee.available()> 0)
{
if (xBee.read() == 'r')
{
digitalWrite(Led, HIGH);
xBee.write("Led On");
delay(10);
}
else if (xBee.read() == 'o')
{
digitalWrite(Led, LOW);
xBee.write("Led Off");
delay(10);
}
else
{
xBee.write("NR"); // Testing for not recognized characters
}
delay(10);
}
delay(10);
}
I can turn on the LED when sending the character 'r' from the PC to the XBee. The intended result is received back as well. When I try to send the character 'o' from the PC the LED stays on, and I get the response of "NR".
This same result happens with different characters in the else if statement, sending character 'o' as the first character, changing to just if statements, and changing the initial condition to - while xBee.available().
How can I fix this problem?

You need to store the input value of xBee.read() and then use it in the if condition.
You can try this
#include <SoftwareSerial.h>
SoftwareSerial xBee = SoftwareSerial(1, 0);
int Led = 9;
void setup()
{
pinMode(Led, OUTPUT);
xBee.begin(9600);
}
void loop()
{
char read_value = xBee.read();
if(xBee.available()> 0)
{
if ( read_value == 'r')
{
digitalWrite(Led, HIGH);
xBee.write("Led On");
delay(10);
}
else if ( read_value == 'o')
{
digitalWrite(Led, LOW);
xBee.write("Led Off");
delay(10);
}
else
{
xBee.write("NR"); // Testing for not recognized characters
}
delay(10);
}
delay(10);
}
The problem is that you are taking the input with xBee.read() but not storing it.
Only your first if works ie,
if ( read_value == 'r')
{
digitalWrite(Led, HIGH);
xBee.write("Led On");
delay(10);
}
The control is not even going in the else if hence condition for o is not tested.

Related

Problem with blinking a led with bluetooth in arduino

i am trying to make a program that turns on ,off and blinks an led with the help from bluetooth
On and of were pretty easy to replicate,but i can't make the blink to work.There are to options either blinks once,either if i ad a while it never stops from looping.i tried with both if and case.Can somebody help me.I am using an esp32.
The code with if:
#include "BluetoothSerial.h"
#include <Arduino.h>
#include <analogWrite.h>
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif
BluetoothSerial SerialBT;
int received;// received value will be stored in this variable
char receivedChar;// received value will be stored as CHAR in this variable
const char turnON ='a';
const char turnOFF ='b';
const char turnBLINK= 'c';
//const char turnFADE='d';
const int LEDpin = 12;
//int brightStep = 1;
//int brightness = 0;
void setup() {
Serial.begin(115200);
SerialBT.begin("Mono"); //Bluetooth device name
Serial.println("The device started, now you can pair it with bluetooth!");
Serial.println("To turn ON send: a");//print on serial monitor
Serial.println("To turn OFF send: b"); //print on serial monitor
pinMode(LEDpin, OUTPUT);
// analogWriteResolution(LEDpin, 12);
}
void loop() {
receivedChar =(char)SerialBT.read();
if (Serial.available()) {
SerialBT.write(Serial.read());
}
if (SerialBT.available()) {
// while(SerialBT.available()){
// receivedChar =(char)SerialBT.read();
// }
SerialBT.print("Received:");// write on BT app
SerialBT.println(receivedChar);// write on BT app
Serial.print ("Received:");//print on serial monitor
Serial.println(receivedChar);//print on serial monitor
//SerialBT.println(receivedChar);//print on the app
//SerialBT.write(receivedChar); //print on serial monitor
if(receivedChar == turnON)
{
SerialBT.println("LED ON:");// write on BT app
Serial.println("LED ON:");//write on serial monitor
digitalWrite(LEDpin, HIGH);// turn the LED ON
}
if(receivedChar == turnOFF)
{
SerialBT.println("LED OFF:");// write on BT app
Serial.println("LED OFF:");//write on serial monitor
digitalWrite(LEDpin, LOW);// turn the LED off
}
if(receivedChar == turnBLINK)
{
SerialBT.println("LED blink:");// write on BT app
Serial.println("LED blink:");//write on serial monitor
while (receivedChar == turnBLINK){
//receivedChar =(char)SerialBT.read();
//if(receivedChar != turnBLINK){
// break;
// } else {
digitalWrite(LEDpin, HIGH);// turn the LED off
delay(1000);
digitalWrite(LEDpin,LOW);
delay(1000);
if(receivedChar != turnBLINK){
break; }
}
}
}
delay(20);
}
and with case:
#include "BluetoothSerial.h"
#include <Arduino.h>
#include <analogWrite.h>
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif
BluetoothSerial SerialBT;
int received;// received value will be stored in this variable
char receivedChar;// received value will be stored as CHAR in this variable
char data;
int option;
int blink=0;
const int LEDpin = 12;
void setup() {
Serial.begin(115200);
SerialBT.begin("Mono"); //Bluetooth device name
Serial.println("The device started, now you can pair it with bluetooth!");
Serial.println("To turn ON send: 1");//print on serial monitor
Serial.println("To turn OFF send: 0"); //print on serial monitor
pinMode(12, OUTPUT);
}
void loop(){
receivedChar =(char)SerialBT.read();
// if (Serial.available()) {
// SerialBT.write(Serial.read());
// }
if (SerialBT.available()) {
// while(SerialBT.available()){
// receivedChar =(char)SerialBT.read();
// }
SerialBT.print("Received:");// write on BT app
SerialBT.println(receivedChar);// write on BT app
Serial.print ("Received:");//print on serial monitor
Serial.println(receivedChar);//print on serial monitor
//SerialBT.println(receivedChar);//print on the app
//SerialBT.write(receivedChar); //print on serial monitor
data=receivedChar;
if(data == '0')
{
option = 0;
blink=0;
}else if(data == '1')
{
option = 1;
blink=0;
}else if(data == '2')
{
option = 2;
blink=1;
}
switch (option)
{
case 0: // LED OFF
digitalWrite(LEDpin, LOW);
break;
case 1: //LED ON
digitalWrite(LEDpin, HIGH);
break;
case 2:
while(blink=1){// LED BLINK
digitalWrite(LEDpin , HIGH);
delay(200);
digitalWrite(LEDpin, LOW);
delay(200);
}
break;
}
}
}
First of all, you should clean your code to a minimum reproducible example. Remove all unnecessary comments and pieces of code that do not represent the main problem you are facing.
After a quick skim over your code, I immediately noticed this:
while(blink=1){// LED BLINK
digitalWrite(LEDpin , HIGH);
delay(200);
digitalWrite(LEDpin, LOW);
delay(200);
}
where it should be while(blink==1){ } --> very common mistake. This should be a comparison, NOT an assignment.
Now, you mention that it never stops running. Even after correcting the error I just pointed at, what part inside of your while loop breaks the logic of blink from being equal to 1? Otherwise, the while-loop will never stop
Finally, do not read the serial data inside the main loop(). Use SerialEvent, rather.
Again, it is quite tricky to follow the flow of your code. I suggest you divide your code into functions in order to make it more readable.

Arduino Uno and HC-05: Not showing any output on serial monitor

Arduino Uno - HC-05
Connections are: TX-RX, RX-TX, LED-D13, 5V-5V+
For this project, we can supply power to the Arduino through any +5V power source. You can use a USB port from your computer to power the Arduino, but in this project I used my laptop.
while (Serial.available()) is returning 0 and Serial.read() is returning -1.
Need Help!
Used Bluetooth voice recognition tool from playstore-"Arduino Voice Control"
#include <SoftwareSerial.h> //Replace (' ') with (< >)
SoftwareSerial BLU(0,1);
String voice;
int Green = 13; //Connect To Pin #13
//int Yellow = 2; //Connect To Pin #2
//int Red = 3; //Connect To Pin #3
void allon() {
//digitalWrite(Red, HIGH);
//digitalWrite(Yellow, HIGH);
Serial.print("start");
digitalWrite(Green, HIGH);
}
void alloff() {
//digitalWrite(Red, LOW);
//digitalWrite(Yellow, LOW);
digitalWrite(Green, LOW);
}
void setup() {
Serial.begin(9600);
BLU.begin(9600);
//pinMode(Red, OUTPUT);
//pinMode(Yellow, OUTPUT);
pinMode(Green, OUTPUT);
}
void loop() {
//Serial.print("start loop");
//Serial.print(Serial.available());
while (Serial.available()) { //Check if there is an available byte to read
//Serial.print("start");
delay(10); //Delay added to make thing stable
char c = Serial.read(); //Conduct a serial read
//Serial.print(Serial.read());
if (c == '#') {
break; //Exit the loop when the # is detected after the word
}
//Serial.print(c);
voice += c;
//Serial.print(voice+"\n");
}
if (voice.length() > 0) {
Serial.print("Start");
Serial.print(voice);
if (voice == "*turn on all LED") {
allon();
}
else if (voice == "*turn off all LED") {
alloff();
}
/*else if(voice == "*switch on red") {
digitalWrite(Red,HIGH);
}
else if(voice == "*switch on yellow") {
digitalWrite(Yellow,HIGH);
}*/
else if(voice == "*switch on green") {
digitalWrite(Green,HIGH);
}
/*else if(voice == "*switch off red") {
digitalWrite(Red,LOW);
}
else if(voice == "*switch off yellow") {
digitalWrite(Yellow,LOW);
}*/
else if(voice == "*switch off green") {
digitalWrite(Green,LOW);
}
voice=""; //Reset variable
}
}
You need to check for the app output first. If you already know it then mention that in comment otherwise do the following for printing app output first:-
const int LED = 5;
void setup() {
Serial.begin(9600);
pinMode(LED, OUTPUT);
}
void loop() {
while(Serial.available()>0){
switchstate = Serial.read();
Serial.print(switchstate); // First check what output are you getting from the application
Serial.print("\n");
delay(15);
if(switchstate == '1'){ // Compare your app output accordingly
digitalWrite(5, HIGH);
}
else if(switchstate == '0'){
digitalWrite(5, LOW);
}
}
}

Lcd screen prints weird symbols instead of numbers

I am trying to make a alarm clock with the raspberry pi and an arduino. I have been having this problem that when i use serial communication to send a number it, the lcd doesnt print the number. I know that the arduino is getting the number, for some reason it just wont print it. It instead prints weird symbols and lines. This article shows how i use serial communication between themThis is my arduino code.
#include <LiquidCrystal.h>
const int ledPin = 13;
LiquidCrystal lcd(12,11,5,4,3,2);
void setup()
{
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
lcd.begin(16,2);
lcd.setCursor(0,1);
lcd.print("crystralball");
}
void loop()
{
if (Serial.available())
{
flash(Serial.read() - '0');
}
delay(1000);
}
void flash(int n)
{
for (int i = 0; i < n; i++)
{
digitalWrite(ledPin, HIGH);
lcd.clear();
lcd.write(n);
Serial.print(n);
Serial.flush();
delay(100);
digitalWrite(ledPin, LOW);
delay(100);
}
}
Hi try to change your code in loop like this.
for (int i = 0; i < n; i++){
digitalWrite(ledPin, HIGH);
lcd.clear();
lcd.print(String(n));
Serial.print(n);
Serial.flush();
delay(100);
digitalWrite(ledPin, LOW);
delay(100);
}
You have to use the method print and passing a string.

Communicating with Arduino Serial

I am trying to communicate with my Arduino over the USB port by using Serial:
int previous;
int current = 0;
void turnOn(int pinNumber){
previous = current;
current = pinNumber;
if(previous!=0){
digitalWrite(previous, LOW);
digitalWrite(current, HIGH);
}else{
digitalWrite(current, HIGH);
}
}
void setup(){
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
Serial.begin(9600);
Serial.write(1);
}
void loop(){
delay(1);
if(Serial.available()>0){
switch(Serial.read()){
case 0:
turnOn(8);
break;
case 1:
turnOn(9);
break;
case 2:
turnOn(10);
break;
default:
Serial.println(Serial.read());
}
}
}
I am trying so that if I send a 0 the rightmost LED will light up, if I send 1, the middle one will and if I send a 2 the leftmost will. However when I send 0,1 or anything else it prints a -1 meaning the default switch has been triggered. How do I fix it?
Try this...
void loop(){
if (Serial.available()) {
char input = Serial.read();
if(input == '0'){
turnOn(8);
}else if(input == '1'){
turnOn(9);
}else if(input == '2'){
turnOn(10);
}
}
}
Tell me if it works or not then we can proceed :)

Receiving SMS using GSM and controlling LED using Arduino

Has someone come up with a solution with the above stated problem?
We are using Arduino Duemilanove and SIM 900 GSM module (http://robokits.co.in/shop/index.php?main_page=product_info&products_id=303)
We've tried to work on the similar problem of lightning LEDs from port 9-12 when we send an sms #aibicidi, where i = 0 or 1, 0 =off, 1=on. E.g. #a1b1c1d1 will switch on all the LEDs.
When we upload the code and run it through serial monitor and enter the #a1b1c1d1 in the serial monitor, we can see all the LEDs lighten up. But if we send the sms with having content "#a1b1c1d1", we don't see any function of LEDs.
It would be great if anyone can give some guidance about the same.
char inchar; //Will hold the incoming character from the Serial Port.
int led1 = 9;
int led2 = 10;
int led3 = 11;
int led4 = 12;
void setup()
{
// prepare the digital output pins
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
digitalWrite(led3, LOW);
digitalWrite(led4, LOW);
//Initialize GSM module serial port for communication.
Serial.begin(9600);
delay(3000); // give time for GSM module to register on network etc.
Serial.println("AT+CMGF=1"); // set SMS mode to text
delay(200);
Serial.println("AT+CNMI=3,3,0,0"); // set module to send SMS data to serial out upon receipt
delay(200);
}
void loop()
{
//If #a1b1c1d1 comes as sms, all LEDs should light up.
if(Serial.available() >0)
{
inchar=Serial.read();
if (inchar=='#')
{
delay(10);
inchar=Serial.read();
//first led
if (inchar=='a')
{
delay(10);
inchar=Serial.read();
if (inchar=='0')
{
digitalWrite(led1, LOW);
}
else if (inchar=='1')
{
digitalWrite(led1, HIGH);
}
delay(10);
//Second led
inchar=Serial.read();
if (inchar=='b')
{
inchar=Serial.read();
if (inchar=='0')
{
digitalWrite(led2, LOW);
}
else if (inchar=='1')
{
digitalWrite(led2, HIGH);
}
delay(10);
// Third led
inchar=Serial.read();
if (inchar=='c')
{
inchar=Serial.read();
if (inchar=='0')
{
digitalWrite(led3, LOW);
}
else if (inchar=='1')
{
digitalWrite(led3, HIGH);
}
delay(10);
//Fourth led
inchar=Serial.read();
if (inchar=='d')
{
delay(10);
inchar=Serial.read();
if (inchar=='0')
{
digitalWrite(led4, LOW);
}
else if (inchar=='1')
{
digitalWrite(led4, HIGH);
}
delay(10);
}
}
Serial.println("AT+CMGD=1,4"); // delete all SMS
}
}
}
}
}
First do not use delay
Serial.begin(9600);
delay(3000); // give time for GSM module to register on network etc.
This is neither necessary nor reliable. Instead of waiting some random time, you can check the network status with AT+CFUN and/or AT+COPS. If the GSM module is already attached to a network when you open the serial connection, it is a waste of time waiting like that. And if is not attached you should wait explicitly for that to happen (polling CFUN/COPS or enabling AT+CREG), otherwise you risk waiting too short time. See the 27.007 specification for more information for those commands.
Second do not use delay
Serial.println("AT+CMGF=1"); // set SMS mode to text
delay(200);
Please do not write code like this. See this answer on why using delay is such a bad idea, and this answer for suggestion to how to handle properly.

Resources