We are doing a project where we move a servo motor to open and close a lock with Arduino and Bluetooth HC-06. We are trying to send one number (1 or 2) as the state of the servo motor before doing anything, as soon as we connect our app to the Bluetooth HC-06 just to know if the lock is already open or close (we are using EEPROM to not lose the last position of the servo). However, with our code we receive the data but the servo stop working well. If we delete the first two lines from the loop, it will work but we will not know the initial state of the servo. How can we solve this?
char state;
Servo myservo;
int btx=3;
int brx=2;
SoftwareSerial blue(btx,brx);
int pos = 0;
void setup() {
Serial.begin(9600);
myservo.attach(9);
blue.begin(9600);
// An EEPROM value of 1 == UNLOCKED and a value of 2 == LOCKED
if(EEPROM.read(0) == 1){ //Lock opened
myservo.write(70);
delay(200);
pos = 1;
//blue.println(1); not working
}
else if(EEPROM.read(0) == 2){ //Lock closed
myservo.write(180);
delay(200);
pos = 2;
//blue.println(2); not working
}
//blue.println(pos); not working
}
void loop() {
while(!blue.available()){ // <-- The problem is in this two lines
blue.println(pos); // send state to app
}
String voice;
while(blue.available()){
delay(10);
char c = blue.read();
if (c == '#'){
break;
}
voice += c;
}
if(voice.length() > 0){
if (voice == "open"){
myservo.write(70);
EEPROM.write(0, 1);
blue.println(1);
delay(15);
}
else if (voice == "close"){
myservo.write(180);
EEPROM.write(0, 2);
blue.println(2);
delay(15);
}
}
}
Because those two lines are an infinite loop! so you should change your code to this and give your code a chance to continue :)
void loop() {
if(!blue.available()){
blue.println(pos);
}else if(blue.available()){
String voice;
while(blue.available()){
delay(10);
char c = blue.read();
if (c == '#'){
break;
}
voice += c;
if(voice.length() > 0){
if (voice == "open"){
myservo.write(70);
EEPROM.write(0, 1);
blue.println(1);
delay(15);
}
else if (voice == "close"){
myservo.write(180);
EEPROM.write(0, 2);
blue.println(2);
delay(15);
}
}
}
}
}
Related
I have an App that is, besides other things, supposed to alert when the Fire Alarm that I have on my project is triggered. The sensor is a thermistor and it activates a blinking led and a buzzer when the data it is getting is >700. I am using Bluetooth (HC-05) for my connection. I already have on the app a temperature sensor that is supposed to work independently and the readings from the Arduino are already being received, so I can´t mix the values (receive text number of bytes already being used). I was thinking of, e.g. when the led is blinking (meaning that the fire alarm is triggered), it sends some kind of info to the app that notifies me through an extension and the internal Notifier, without entering in conflict with the other blocks.`
visual aspect of app`
blocks of app
[code]
#include <SoftwareSerial.h>
SoftwareSerial BT(10, 11); //TX, RX respetively
float temp;
float seno;
int frequencia;
float temptermistor;
String state;// string to store incoming message from bluetooth
void setup() {
BT.begin(9600);// bluetooth serial communication will happen on pin 10 and 11
Serial.begin(9600); // serial com. to check the data on serial monitor
pinMode(A0, INPUT); //temperatura
pinMode(A1, INPUT); //termistor
pinMode(9, OUTPUT); //led alarme
pinMode(13, OUTPUT); //buzzer
}
void loop() {
temp = analogRead(A0);
delay(200);
temp = analogRead(A0);
temp = temp * 0.48828125;
temptermistor = analogRead(A1);
delay(10);
temptermistor = analogRead(A1);
delay(10);
Serial.println(temp);
BT.println(temp);
delay(250);
if (temptermistor >= 700)
{
digitalWrite(9, HIGH);
delay(50);
digitalWrite(9, LOW);
delay(50);
for(int x=0;x<180;x++){ //converte graus para rad. e obtém o valor do seno
seno=(sin(x*3.1416/180)); //gera uma frequência a partir do valor do seno
frequencia = 2000+(int(seno*1000));
tone(13,frequencia);
delay(2);
}
}
else
{
noTone(13);
}
while (BT.available()){ //Check if there is an available byte to read
delay(10); //Delay added to make thing stable
char c = BT.read(); //Conduct a serial read
state += c; //build the string- either "On" or "off"
}
if (state.length() > 0) {
if(state == "A")
{
digitalWrite(2, HIGH);
}
else if(state == "a")
{
digitalWrite(2, LOW);
}
if(state == "B")
{
digitalWrite(3, HIGH);
}
else if(state == "b")
{
digitalWrite(3, LOW);
}
if(state == "C")
{
digitalWrite(4, HIGH);
}
else if(state == "c")
{
digitalWrite(4, LOW);
}
if(state == "D")
{
digitalWrite(5, HIGH);
}
else if(state == "d")
{
digitalWrite(5, LOW);
}
if(state == "E")
{
digitalWrite(6, HIGH);
}
else if(state == "e")
{
digitalWrite(6, LOW);
}
if(state == "F")
{
digitalWrite(7, HIGH);
}
else if(state == "f")
{
digitalWrite(7, LOW);
}
if(state == "G")
{
digitalWrite(8, HIGH);
}
else if(state == "g")
{
digitalWrite(8, LOW);
}
if(state == "H")
{
digitalWrite(12, HIGH);
}
else if(state == "h")
{
digitalWrite(12, LOW);
}
state ="";}
}
[/code]
For sending the Temperature value and notification message you can use delimiter as like & or some kind of symbol in the BT.println();.
Try something like this
BT.print(temp);
BT.print("&");
BT.println("notification");
When you see the output in Bluetooth terminal you can see output like this.
temp¬ification
temp¬ification
Then at the Mobile App capture that output and break it from the & symbol. then you can grab the two variables.
You can refer these tutorials.
1 2 3
So I have a Bluetooth module that I've created some code for, so that when i push button 1 it turns on the led, when i push 2 it turns off the led, and 3 is supposed to make the led continuously blink. Everything works perfectly fine, except that when i push 3 the led blinks once then stops. What can i do to the code to make it blink continuously until i either hit button 1 or 2 again?
char LED = 0;
void setup() {
pinMode(13, OUTPUT);
Serial.begin(9600); // Opens Serial port
}
void loop() {
if (Serial.available()> 0){
LED = Serial.read();
Serial.print(LED);
if (LED == '1')
digitalWrite(13, HIGH);
if (LED == '0')
digitalWrite(13, LOW);
if (LED == '3') {
digitalWrite(13, HIGH);
delay(1000);
digitalWrite(13, LOW);
delay(1000);
}
}
}
You need to change main loop to:
void loop() {
if (Serial.available()> 0){
LED = Serial.read();
Serial.print(LED);
}
if (LED == '3') {
digitalWrite(13, HIGH);
delay(1000);
digitalWrite(13, LOW);
delay(1000);
}
else if (LED == '1')
digitalWrite(13, HIGH);
else if (LED == '0')
digitalWrite(13, LOW);
}
In this case LED == '3' will be work on every loop iteration, even if Serial is not contain any data
You put the blinking code into the if (Serial.available()> 0) block, which means that it's only run when you send a '3'. You would need to keep sending '3' to keep the LED blinking.
Sergey gave you a working solution, but that code unnecessarily keeps setting the LED on or off, and the code is unresponsive while the LED is blinking because of the use of delay.
To fix those problems you need to use a variable to keep a state (In Sergey's code that role took your existing LED variable) and use millis() instead of delay() for blinking, like in the BlinkWithoutDelay builtin Arduino IDE example.
char LED = 0;
enum {
NONE,
BLINKING,
} state = NONE;
void setup() {
pinMode(BUILTIN_LED, OUTPUT);
Serial.begin(9600); // Opens Serial port
}
void loop() {
if (Serial.available() > 0){
LED = Serial.read();
Serial.print(LED);
switch (LED) {
case '1':
state = NONE;
digitalWrite(BUILTIN_LED, HIGH);
break;
case '2':
state = NONE;
digitalWrite(BUILTIN_LED, LOW);
break;
case '3':
state = BLINKING;
break;
}
}
switch (state) {
case NONE: break;
case BLINKING:
static unsigned long last_blink = 0;
if (millis() - last_blink > 1000)
{
digitalWrite(BUILTIN_LED, !digitalRead(BUILTIN_LED));
last_blink = millis();
}
break;
}
}
I am trying to send the number "25" from arduino to android application created by using MIT AppInventor2. At the same time, I want to make "on" or "off" a LED by clicking "lock" and "unlock" buttons on the android app. There is no problem making LED status "on" and "off" but I can not read the 25 on the application. I only read 2 or 5. I read 25 very very rarely.
What is the problem about my arduino code or AppInventor blocks?
Arduino code:
int ledPin = 13;
String readString;
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
}
void loop() {
Serial.println(25);// Here I want to send 25
delay(20);
while (Serial.available()) {
delay(3);
char c = Serial.read();
readString += c;
}
if (readString.length() >0) {
// Serial.println(readString);
if (readString == "on")
{
digitalWrite(ledPin, HIGH);
}
if (readString == "off")
{
digitalWrite(ledPin, LOW);
}
readString="";
}
}
Edit: Time interval for AppInventor clock is 1000.
I am writing a "race box" in C that runs on an Intel Edison. It can send or receive bluetooth data with an Android app based on Bluetooth Chat. Everything works fine. I can send and receive. I can lose the connection and reacquire and the connection comes back and data flows from the C program to the Android app. All is good except once I reconnect I can no longer send data from C to Android. I have traced this to the read statement and I assume it never returns a value because it never exits the while loop. Specifically, this line:
while(bluetooth_up == 1 && (read(client, &aa, 1) == -1) ){
Will not exit even when I know bluetooth_up == 0 (another thread fprints bluetooth_up and it is 0 when bluetooth is down). My conclusion was that read was blocking so I attempted to fix that with the line
fcntl(s, F_SETFL,sock_flags|O_NONBLOCK);
The bluetooth connection is in the bluetooth write thread. But like I said, everything works except that this while loop will not exit when bluetooth_up is 0.
All I can figure out is that the read is blocking and what I cannot figure out is how to make it not blocking so it will return the -1 and the while loop can see that bluetooth_up == 0 and exit.
Here is the global definition of bluetooth_up
volatile int bluetooth_up = 0;
I would appreciate help on this as it needs to be robust and I don't want to require people to power cycle the race box to get bluetooth working again, although that does work.
void *blueRead(void *arg){
blue_read_up = 1;
char aa;
char buffer[500];
int idx = 0;
printf("\nBlue Read started\n");
fcntl(s, F_SETFL,sock_flags|O_NONBLOCK);
while(bluetooth_up == 1){
if (new_blue_read_sentence == 0 && bluetooth_up == 1){
while(bluetooth_up == 1 && (read(client, &aa, 1) == -1) ){
if(bluetooth_up == 0){
printf("\nExiting blue read\n");
blue_read_up = 0;
return NULL;
}
}
printf("%i",aa);
if(aa != '\n')
{
buffer[idx++] = aa;
}
else
{
buffer[idx] = '\n';
buffer[idx + 1] = '\0';
idx = 0;
strcpy( blue_read_buffer, buffer);
new_blue_read_sentence = 1;
}
}
}
printf("\nExiting blue read 2\n");
blue_read_up = 0;
return NULL;
}
I think the bluetooth connection code is pretty standard but here it is
// allocate socket
s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
printf("\nsocket = %i\n", s);
// bind socket to port 1 of the first available local bluetooth adapter
loc_addr.rc_family = AF_BLUETOOTH;
loc_addr.rc_bdaddr = *BDADDR_ANY;
loc_addr.rc_channel = (uint8_t)1;
retval = bind(s, (struct sockaddr*)&loc_addr, sizeof(loc_addr));
printf("\nbind = %i\n", retval);
// put socket into listening mode
//listen(s, 1);
retval = listen(s, 1);
printf("\nlisten = %i\n", retval);
// accept one connection
client = accept(s, (struct sockaddr*)&rem_addr, &opt);
sock_flags = fcntl(s,F_GETFL,0);
fcntl(s, F_SETFL,sock_flags|O_NONBLOCK);
printf("\n1 - client connect = %i socket %i\n", client, s);
You are setting O_NONBLOCK on the listening socket (s). Try instead on the accept socket (client) which is the one that is actually being read from.
What I want to do is to control 2 leds in the arduino board with a processing program.
If I press any point on the upper half of the screen the led (Pin 13) will light on, and if I press a point on the lower half of the screen, it will turn on other led (Pin 12).
So, I programmed 2 buttons, with 2 leds(Pin 12 an 13) and no matter what button I press, It always turns on pin 13.
I made a separate experiment, with only 1 button, change only the pin 13 by 12. It does not work, always turns on pin 13.
ARDUINO CODE:
boolean estado;
boolean estado1;
byte a;
void setup()
{
Serial.begin(9600);
pinMode(12, OUTPUT);
digitalWrite(12, LOW);
pinMode (13, OUTPUT);
digitalWrite (13, LOW);
randomSeed(analogRead(0));
estado = false;
estado1 = false;
}
void loop()
{
delay(100);
Serial.write(random(40));
while(Serial.available() > 0)
{
a = Serial.read();
if (a == 0)
{
estado = !estado;
digitalWrite(12, estado);
}
if (a == 1)
{
estado1 = !estado1;
digitalWrite(13, estado1);
}
}
}
PROCESSING CODE:
void compruebaBoton()
{
if( mouseY < 640)
{
try
{
ons.write(0);
}
catch(Exception ex)
{
estado = 4;
error = ex.toString();
println(error);
}
}
if( mouseY > 640)
{
try
{
ons.write(1);
}
catch(Exception ex)
{
estado = 4;
error = ex.toString();
println(error);
}
}
}
the code I am implementing is correct for what I am trying to do?
After playing with the code for hours, I found the problem!!
The program is not loaded into the arduino if the bluetooth board is connected to the arduino board.