Oops sorry, forgot.. thank you for editing that out
This alertclock Timer event will never end because it does not consume BT input, which it tests to keep looping:
That would freeze your app.
Also, why do you echo your input from BlueTooth back to AI2?
I am not sure that you need the break in each of these procedures.
It might be testing only the first letter of your input.
Here are sample blocks for the chance that you will need to test your messages on the AI2 side, and don't want run-on or fragmented messages:
(draggable)
Here is boiler plate discussion of Delimiters ...
Please see the Delimiter article in FAQ
Be sure to use println() at the end of each message to send from the sending device, to signal end of message. Do not rely on timing for this, which is unreliable.
In the AI2 Designer, set the Delimiter attribute of the BlueTooth Client component to 10 to recognize the End of Line character.
Also, return data is not immediately available after sending a request,
you have to start a Clock Timer repeating and watch for its arrival in the Clock Timer event. The repeat rate of the Clock Timer should be faster than the transmission rate in the sending device, to not flood the AI2 buffers.
In your Clock Timer, you should check
Is the BlueTooth Client still Connected?
Is Bytes Available > 0?
IF Bytes Available > 0 THEN
set message var to BT.ReceiveText(-1)
This takes advantage of a special case in the ReceiveText block:
ReceiveText(numberOfBytes)
Receive text from the connected Bluetooth device. If numberOfBytes is less than 0, read until a delimiter byte value is received.
If you are sending multiple data values per message separated by | or comma, have your message split into a local or global variable for inspection before trying to select list items from it. Test if (length of list(split list result) >= expected list length) before doing any select list item operations, to avoid taking a long walk on a short pier. This bulletproofing is necessary in case your sending device sneaks in some commentary messages with the data values.
Hey again, thanks for the advice. I fixed the loop so now it doesn't freeze but now I kind of have another problem. So my project has 2 things happening that functions with the arduino which is:
- Performs turning on/off LEDs (Works fine)
- An alarm
So the problem is with the alarm. This is how it should function. When clicking on a button from the arduino. It should open a layout in the app called Alert and when the layout is visible some other components will activate like a video of an alarm and an alarm sound, other than that the arduino will also start blinking two red LEDs, a buzzer will also go off and an LCD will display which room is in an emergency state. When clicking on a button in the app only then everything will stop, the app will go back to the home page, stop the sound, clear the LCD, buzzer and turn off the blinking red LEDs.
I did experiments. beforehand but it was two different projects. One with just the arduino where when a btton is clicked, the buzzer, LED and LCD will display which room is in an emergency state. And the other project is basically the same but without the LCD, buzzer or LED. just when a button is click. the app will go into alert mode. Both worked fine as individuals. Now I'm not quite sure how to combine both codes and make the app work.
Whenever I tried to do the whole testing, by just clicking on the On or Off button in the app for the just the lights, The alert app will suddenly pop up because it is receiving the values sent from turning the lights on and off. I need help.
Here is the individual codes:
(ALARM WITHOUT APP):
(ALARM WITH APP)
Here are my blocks:
And... the sound keeps looping and I know it's because it is in a loop but i'm not sure how else to start the sound once the arduino button is clicked. I'm still quite new to arduino and I only have basic knowledge of most coding language so i'm quite confused on how to go about it
You have 4 different timers.
This is a circus.
Try to reduce this to one continually running circus, with nested tests against global variables and against BT conditions.
Also, it is time you learned to use message delimiters (\n), and to test message content for keywords.
(draggable)
Please see the Delimiter article in FAQ
Be sure to use println() at the end of each message to send from the sending device, to signal end of message. Do not rely on timing for this, which is unreliable.
In the AI2 Designer, set the Delimiter attribute of the BlueTooth Client component to 10 to recognize the End of Line character.
Also, return data is not immediately available after sending a request,
you have to start a Clock Timer repeating and watch for its arrival in the Clock Timer event. The repeat rate of the Clock Timer should be faster than the transmission rate in the sending device, to not flood the AI2 buffers.
In your Clock Timer, you should check
Is the BlueTooth Client still Connected?
Is Bytes Available > 0?
IF Bytes Available > 0 THEN
set message var to BT.ReceiveText(-1)
This takes advantage of a special case in the ReceiveText block:
ReceiveText(numberOfBytes)
Receive text from the connected Bluetooth device. If numberOfBytes is less than 0, read until a delimiter byte value is received.
If you are sending multiple data values per message separated by | or comma, have your message split into a local or global variable for inspection before trying to select list items from it. Test if (length of list(split list result) >= expected list length) before doing any select list item operations, to avoid taking a long walk on a short pier. This bulletproofing is necessary in case your sending device sneaks in some commentary messages with the data values.
If you are using timers, we need to see full source and attributes ...
Please export your project and post it here. (after you fix it)
I tried to understand what delimiters do but i'm still not getting it... I'm sorry
here is the aia fileECMS2_revised (1).aia (1.0 MB)
The part you'll be looking for is on the far bottom of the left side for the alarm blocks, for the light blocks the are far left side. I really appreciate the help. Thank you
Forogt to add, that it is in screen1, I have all the alert layouts in all the screens but fixing 1 for now is enough for testing. I can fix the others once the first screen is fixed
You must decide which clock timer will be receiving from BlueTooth, and
is in charge of analyzing the input. Move the Timer logic from the other clocks to the process procedure.
Here is some reading for you on procedures ...
http://www.appinventor.org/bookChapters/chapter21.pdf
from FAQ Section: Books, Tips, Tutorials for AI2
In that procedure, put some IF statements and text matching blocks to see if an emergency is mentioned in the message variable, and respond appropriately.
See the Making Decisions chapter if that book if you have trouble with that.
Sir i tried, i really did. I slept till late trying to make it work but i'm still clueless i read the chapter over and over but just couldnt understand much on what will help me. I don't know if it's the blocks or the arduino code. I need some guide please.... This is what I have so far
Arduino Code:
#include <SoftwareSerial.h>
#include <LiquidCrystal.h>
LiquidCrystal my_lcd(28,3,4,5,6,7);
//Room Lights(Apps)
const int LedR1 = 40;
const int LedR2 = 41;
const int LedR3 = 42;
const int LedR4 = 43;
const int LedBath = 44;
int lights;
//Alarm
const int AlertLed1 = 22;
const int AlertLed2 = 30;
const int buzzer = 8;
const int buttonR1 = 31;
const int buttonR1_1 = 32;
const int buttonR2 =33;
const int buttonR2_1 =34;
const int buttonR3 = 35;
const int buttonR3_1 = 36;
const int buttonR4 =37;
const int buttonR4_1 =38;
const int buttonBath =39;
String Bt;
int alarm;
int lastButtonState;
int BR1;
int BR1_1;
int BR2;
int BR2_1;
int BR3;
int BR3_1;
int BR4;
int BR4_1;
int BRB;
// Setting Buzzer mode to False
boolean buzzer_mode = false;
int status = false;
// For Alarm LED
int ledState = LOW;
long previousMillis = 0;
long interval = 100; // Interval at which LED blinks
void setup()
{
//Bluetooth
Serial2.begin(9600);
//Room Lights(Apps)
pinMode(LedR1,OUTPUT);
pinMode(LedR2,OUTPUT);
pinMode(LedR3,OUTPUT);
pinMode(LedR4,OUTPUT);
pinMode(LedBath,OUTPUT);
//Alarm
pinMode(AlertLed1,OUTPUT);
pinMode(AlertLed2,OUTPUT);
pinMode(buttonR1,INPUT_PULLUP);
pinMode(buttonR1_1,INPUT_PULLUP);
pinMode(buttonR2,INPUT_PULLUP);
pinMode(buttonR2_1,INPUT_PULLUP);
pinMode(buttonR3,INPUT_PULLUP);
pinMode(buttonR3_1,INPUT_PULLUP);
pinMode(buttonR4,INPUT_PULLUP);
pinMode(buttonR4_1,INPUT_PULLUP);
pinMode(buttonBath,INPUT_PULLUP);
pinMode(buzzer,OUTPUT);
my_lcd.begin(16,2);
}
void loop()
{
//Alarm (App)
BR1 = digitalRead(buttonR1);
BR1_1 = digitalRead(buttonR1_1);
BR2 = digitalRead(buttonR2);
BR2_1 = digitalRead(buttonR2_1);
BR3 = digitalRead(buttonR3);
BR3_1 = digitalRead(buttonR3_1);
BR4 = digitalRead(buttonR4);
BR4_1 = digitalRead(buttonR4_1);
BRB = digitalRead(buttonBath);
if(Serial2.available()){
//Room1 Lights(Apps)
lights = Serial2.read();
if(lights == 1) digitalWrite(LedR1, HIGH);
if(lights == 2) digitalWrite(LedR1, LOW);
if(lights == 3) digitalWrite(LedR2, HIGH);
if(lights == 4) digitalWrite(LedR2, LOW);
if(lights == 5) digitalWrite(LedR3, HIGH);
if(lights == 6) digitalWrite(LedR3, LOW);
if(lights == 7) digitalWrite(LedR4, HIGH);
if(lights == 8) digitalWrite(LedR4, LOW);
if(lights == 11) digitalWrite(LedBath, HIGH);
if(lights == 12) digitalWrite(LedBath, LOW);
}
if(Serial2.available()){
alarm = Serial2.read();
if(alarm == 13)buzzer_mode = false;
lastButtonState = 0;
}
//Alarm Room 1
if(BR1 != lastButtonState){
if(BR1 == 1){
Bt = "ON";
Serial2.println(Bt);
Serial2.println("ROOM 1, EMERGENCY CALL!!");
status = !status;
buzzer_mode = status;
my_lcd.setCursor(0,0);
my_lcd.print(" ALERT!! ALERT!!");
my_lcd.setCursor(0,1);
my_lcd.print(" ROOM 1");
}
delay(50);
}
if(BR2 != lastButtonState){
//Alarm Room 2
if(BR2 == 1){
Bt = "ON";
Serial2.println(Bt);
Serial2.println("ROOM 2, EMERGENCY CALL!!");
status = !status;
buzzer_mode = status;
my_lcd.setCursor(0,0);
my_lcd.print(" ALERT!! ALERT!!");
my_lcd.setCursor(0,1);
my_lcd.print(" ROOM 2");
}
delay(50);
}
// If alarm is on
if (buzzer_mode){
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
// Switch the LED
digitalWrite(AlertLed1, ledState);
digitalWrite(AlertLed2, ledState);
}
tone(buzzer,1000);
}
// If alarm is off
if (buzzer_mode == false) {
// No tone & LED off
noTone(buzzer);
digitalWrite(AlertLed1, LOW);
digitalWrite(AlertLed2, LOW);
my_lcd.clear();
}
}
Here are my blocks for the alarm now...
Responding to a sequence of messages ('ON', 'whatever') is hard.
It's easier to just test for the messages that have !! anywhere in them, and show those.
By the way, I hope you set your BlueTooth Client Delimiter to 10 in the Designer.
I did, thank you for the guidance, i'll fix the blocks. Is my arduino code also correct because i'm scared that it isn't...
All I know to check in the Arduino code is the println() for the BT messages.
Those look okay to me.
You will have to rely on others for the rest of the Arduino code.
It would not hurt to post your new blocks, just in case.
I just realized you canceled out one part where the room text is set to the bluetooth's receive text and replace it with message. Will it still receive texts from the arduino? for example the first part is where:
if (message == '!!') then
so if I change the arduino code from the txt "ON" to '!!'
then there will also be another txt where it'll tell us which room is in an emergency state. by using println() after reading the '!!' will it then read the emergency room and seperate it to the RoomAlertTxt?
I tried the code out but it still doesn't work.... i'm still not sure if it's the app or the arduino code. someone please help if it's not the blocks
Do you know the difference between
and
?
I asked for Contains, not ==.
oh sorry I didn't know the difference, hold on i'll change it
Please read through
http://ai2.appinventor.mit.edu/reference/blocks/text.html
Take the Grand Tour.
It's worth your while.
So I changed the code and the alert layout does pop up but it pops up as soon as it connected to the bluetooth, I didn't even click on a button...
What's in global message?
Did you fail to reset it after the previous alarm?
Well the message should only be received once the arduino button is clicked but I haven't clicked anything and reset the previous alarm? How to I reset it?
for testing purposes I tried to just play with two buttons where each button respectively say "ROOM 1, EMERGENCY CALL!!" and "ROOM 2, EMERGENCY CALL!!". Both texts are shown though when the alert layout pops up as soon as the bluetooth connects
Do I add it at the bottom of the loop?