Pages: [1]   Go Down
Author Topic: Bluetooth and App Inventor  (Read 6151 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am working on a project that I would like to have buttons on my phone send text over bluetooth which the arduino would read and turn pins on or off. So button one would send "2on" over bluetooth and the bluetooth would send that over serial to the Arduino. The Arduino would see "2on" and know to write pin 2 HIGH. The app that i am working on can connect to the bluetooth but nothing happens after that. I press buttons but the Arduino doesn't write to pins. I don't see rx/tx lights either. I have the bluetooth rx to pin 1 of my UNO and bluetooth tx to pin 0. I am running my app as a bluetooth client and the BlueSMiRF as a slave. Do I need to change my app to Server? Am i missing something about how text gets sent over serial? I am using the bluetoothclient1.sendtext block with a text of "8on" to send text to turn on pin 8 in App inventor. If anyone has any critiques for me I would appreciate it. This is my first real project in app inventor and Arduino and my skills in coding are poor. (Im sure the code will show that I don't know what im doing)  smiley-roll I have seen examples of reading the state of the pin and then writing the inverse using "!" and thought that might be a better way to o it and then just send a number over serial that would represent the pin and would toggle but I just don't know how to implement that so I went this route.


String readString;

void setup () {
Serial.begin (115200);
// Outputs

pinMode (2, OUTPUT);
pinMode (3, OUTPUT);
pinMode (4, OUTPUT);
pinMode (5, OUTPUT);
pinMode (6, OUTPUT);
pinMode (7, OUTPUT);
pinMode (8, OUTPUT);
pinMode (9, OUTPUT);
}

void loop () {
while (Serial.available ()) {
delay (10);
if (Serial.available ()> 0) {
char c = Serial.read ();
readString += c;
}
}
// Check serial and write pins high or low.
if (readString.length ()> 0) {


if (readString == "2on") {
digitalWrite (2, HIGH);
}
if (readString == "2OFF") {
digitalWrite (2, LOW);
}
if (readString == "3on") {
digitalWrite (3, HIGH);
}
if (readString == "3OFF") {
digitalWrite (3, LOW);
}
if (readString == "4on") {
digitalWrite (4, HIGH);
}
if (readString == "4OFF") {
digitalWrite (4, LOW);
}
if (readString == "5on") {
digitalWrite (5, HIGH);
}
if (readString == "5OFF") {
digitalWrite (5, LOW);
}
if (readString == "6on") {
digitalWrite (6, HIGH);
}
if (readString == "6OFF") {
digitalWrite (6, LOW);
}
if (readString == "7on") {
digitalWrite (7, HIGH);
}
if (readString == "7OFF") {
digitalWrite (7, LOW);
}
if (readString == "8on") {
digitalWrite (8, HIGH);
}
if (readString == "8OFF") {
digitalWrite (8, LOW);
}
if (readString == "9on") {
digitalWrite (9, HIGH);
}
if (readString == "9OFF") {
digitalWrite (9, LOW);
}

readString = "";
}
}
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 615
Posts: 49410
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I don't see rx/tx lights either.
The RX and TX LEDs are controlled by the USB to serial converter chip, which you are bypassing.

You seem to not understand how serial communications works. Serial data arrives like I type - pretty darn slow. You are expecting it to arrive as fast as you can read it. Doesn't work that way.

You need to add an end-of-record marker to the stuff you send, and have the Arduino keep reading and storing, until that marker arrives. Then, test what you have received, and do something.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the reply. I would think that serial would be fast enough, I have seen robots controlled over bluetooth that seem responsive enough. However is there a better way to be doing wireless control? Or is it that I need to have Delays in the code? I guess that would be what you are saying with the end of record in a way. I will research the end of record method and see if I can work something up, thanks again. If anyone else has any tips or better ways of creating bluetooth pin control please let me know as I have picked this route only out of not knowing any other way.
P.S. Any good links of examples of serial code that show serial comms?
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 615
Posts: 49410
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I would think that serial would be fast enough
It is. It's just that serial data transmission is like me typing and you reading. You can, generally, anyway, read far faster than I can type. You know when to stop reading letters that form a word because there is a space or other punctuation mark. You know to stop reading the words that form a sentence because there is a period or other punctuation mark.

You need to provide the same kind of delimiters in your serial data.

Quote
Or is it that I need to have Delays in the code?
Absolutely not. Don't even go there.

Quote
I guess that would be what you are saying with the end of record in a way. I will research the end of record method and see if I can work something up
All you need to do is add a character to the end of the command. 4on! or 2off% or 7on$ or whatever end-of-record marker you are partial to.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

PaulS thank you for taking time to help explain this. I realize this is some low level bone head stuff that my thick scull is having a hard time grasping. Its nice to have some insight. I have searched examples but it seems like bluetooth is not well documented and when it is its above my understanding. So I need to have a marker of some sort at the end of the command such as "1on" would be "1on#" the # would be the marker telling arduino that at that point it needs to do what ever it has been set to do. Otherwise the commands could string together and the arduino would see "1on2on3off" which would look like nothing instead of 3 separate commands. Here is what sucks, I don't know how to search this because I don't know what it is called that I am searching. Is there a topic that you could suggest I go search so I don't have you going crazy trying to explain everything Arduino? Another question which this forum might know the answer to: In app inventor it has bluetooth client and server. If i have the bluesmirf in slave mode, should the android app be in Server or Client? I would think that this is just another way of saying master and slave and that if the bluesmirf is in slave then the android app should be a server.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So I probably shouldn't admit to it but I will. I was reading some of Pauls other posts (helping out some other people, Paul seems to be a very helpful person) I read that they had the usb powering the arduino and once they went to battery it fixed some problems. I figured that since I didnt have any data going over usb it wouldn't interfere but it was. I the arduino on external power and was able to get the Pins to turn on when they were supposed to. I would press the button on my app to turn them on and...they did! smiley-yell then I went to turn them off  smiley-cry No dice. So I am doing a little better than I thought but not perfect....ok not even good. hmmm
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well if anyone else has the same questions I did I will answer some of them now. The sketch I posted above works!.......kinda. As PaulS has pointed out it is a rough way of doing things. I don't know how to do it better but Im working on it. As far as App inventor goes: If the bluetooth is in slave, The App can be in client. It may work in Server as well or might not but I do know it will work in client mode with the bluetooth as slave. The reason it wouldn't turn the pins off is that I am a poor self checker and I didn't notice that I had off lowercase in my app code and OFF upper case in arduino. Changed arduino code and it works and is quite responsive. I now have a app that has 8 toggle buttons that turn pins 2-9 on and off. I have the bluetooth on the tx,rx pins (0,1). All the app is doing is checking the state of the pins and sending text to the arduino over bluetooth. So if button 2 is pressed it checks to see if pin 2 is on or off. If pin 2 is on it sends text "2off" and if pin 2 is off it sends text "2on". As seen in the code, The arduino reads the text and if the text matches any of the if statements then it will execute a digital write based off of what the text was. (write pin X high or low) Now I get to look into the suggestions that PaulS has made to make the code better and then on to making the app look so fresh and so clean. So may other noobs who are looking at bluetooth learn from my mistakes.
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 615
Posts: 49410
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
So I need to have a marker of some sort at the end of the command such as "1on" would be "1on#" the # would be the marker telling arduino that at that point it needs to do what ever it has been set to do.
Yes.

If you are willing to limit yourself to just 10 pins, you can replace on or off with + or -. Then, every command will be exactly two characters - the pin number, from 0 to 9, and the state - on or off.

Using letters instead of numbers, and mapping the letter to a pin number, would let you control 26 pins using just upper case or lower case letters, or 52 pins using both upper and lower case letters.

But, learning how to send pin numbers as text and commands like on and off will serve you well in the future. You need a delimiter between the pin number part of the packet and the command part, and you need a delimiter at the end of the packet. I like one at the start of the packet, too. I'd be sending "<4, on>" or "<12, off>", and using this code to read the packets.
Code:
#define SOP '<'
#define EOP '>'

bool started = false;
bool ended = false;

char inData[80];
byte index;

void setup()
{
   Serial.begin(57600);
   // Other stuff...
}

void loop()
{
  // Read all serial data available, as fast as possible
  while(Serial.available() > 0)
  {
    char inChar = Serial.read();
    if(inChar == SOP)
    {
       index = 0;
       inData[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP)
    {
       ended = true;
       break;
    }
    else
    {
      if(index < 79)
      {
        inData[index] = inChar;
        index++;
        inData[index] = '\0';
      }
    }
  }

  // We are here either because all pending serial
  // data has been read OR because an end of
  // packet marker arrived. Which is it?
  if(started && ended)
  {
    // The end of packet marker arrived. Process the packet

    // Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
  }
}
Where it says "Process the packet" is where I'd use strtok() and atoi() to convert the tokens ("12" and "off") to numbers (12) where appropriate.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This is nice PaulS, It seems like this could also help keep errors from being injected since it only looks at whats inside the packet ignoring everything else. This also seems like it is more modular and could be used for larger scale projects without having to do as much work. I like it. Thanks for the example, this gives me lots to think about.
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 54
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

My project is very identical where Im using App Inventor with bluetooth sending serial. However I cant seem to get the communication how Id like it. I tried using a switch_case but I've never used one so Im having trouble. Here's what I have:
Code:
//PWM pins for the LEDs
#define redpinL 9
#define greenpinL 10
#define bluepinL 11
#define redpinR 3
#define greenpinR 5
#define bluepinR 6



//set up SoftwareSerial for the bluetooth module.
#include <SoftwareSerial.h>
#define SoftRx 0
#define SoftTx 1
SoftwareSerial BTSerial(SoftRx, SoftTx);

//color variables
int redvalue=0;
int greenvalue=0;
int bluevalue=0;
int redvalue2=0;
int greenvalue2=0;
int bluevalue2=0;
int eyevalue=0;


void setup(){
  //configure pins
  pinMode(SoftRx, INPUT);
  pinMode(SoftTx, OUTPUT);
  pinMode(redpinL, OUTPUT);
  pinMode(greenpinL, OUTPUT);
  pinMode(bluepinL, OUTPUT);
  pinMode(redpinR, OUTPUT);
  pinMode(greenpinR, OUTPUT);
  pinMode(bluepinR, OUTPUT);
  //check for proper baud rate
  BTSerial.begin(9600);
  //test leds are functional
  digitalWrite(redpinL, HIGH);
  delay (500);
  digitalWrite(redpinL, LOW);
  digitalWrite(greenpinL, HIGH);
  delay(500);
  digitalWrite(greenpinL, LOW);
  digitalWrite(bluepinL, HIGH);
  delay(500);
  digitalWrite(bluepinL, LOW);
  digitalWrite(redpinR, HIGH);
  delay(500);
  digitalWrite(redpinR, LOW);
  digitalWrite(greenpinR, HIGH);
  delay(500);
  digitalWrite(greenpinR, LOW);
  digitalWrite(bluepinR, HIGH);
  delay(500);
  digitalWrite(bluepinR, LOW);
}




void loop()
{
  //App Inventor sends four bytes (L,Rvalue, Gvalue, Bvalue).
  while ( BTSerial.available() > 0){
    int eyevalue = BTSerial.read();
        redvalue=BTSerial.read();
        greenvalue=BTSerial.read();
        bluevalue=BTSerial.read();
    switch (eyevalue){
     case 76:
      void set_left_eye();
      break;
    
     case 82:
      void set_right_eye();
      break;
      default:;
    
   }//close switch
  }//close while
}//close loop



void set_left_eye( int redvalue, int greenvalue, int bluevalue) {
  analogWrite(redpinL, redvalue);
  analogWrite(greenpinL, greenvalue);
  analogWrite(bluepinL, bluevalue);
 
}

void set_right_eye( int redvalue, int greenvalue, int bluevalue) {
  analogWrite(redpinR, redvalue);
  analogWrite(greenpinR, greenvalue);
  analogWrite(bluepinR, bluevalue);
 
}
« Last Edit: November 17, 2012, 06:18:20 pm by AllenI » Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 302
Posts: 26342
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
However I cant seem to get the communication how Id like it.
The C++ is sadly immunised against personal preferences.
If you'd like to tell is what it is you'd like, we may be able to help.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Offline Offline
Jr. Member
**
Karma: 0
Posts: 54
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I finished doing this project  (http://www.corb.co/projects/rgbduino) now I'm looking to build on it by adding another strip. However Im trying to gain individual control between the two strips so I'll be assigning each strip a 'L' or 'R'. I'm looking at PaulS' example code for packets and that seems to be where I wanna go with it. Something like<L,255,0,0> Im still not familiar with strtok() or atoi() yet so Im reading up on em..
Logged

Queens, New York
Online Online
Faraday Member
**
Karma: 101
Posts: 3644
"Of all the things I've ever lost, I miss my mind the most" -Ozzy Osbourne
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@AllenI

In your loop, for cases 76 and 82, your declairing void set_left_eye() and void set_right_eye(), when you dont need to include the void. If you have the functions made already, then you don't need to include void in you cases. basically what your doing is remaking the function with "nothing", If you take away the void then it becomes a "CALL method", which goes to the function and does whatever it needs to.

So change that and you might be ok.

Afterwards post the new code, THE FULL CODE!, many people just post parts, parts dont compile!

SHOUT OUT TO ALL FIRST TIMERS WHO READ THIS, POST YOUR FULL CODES!
« Last Edit: November 17, 2012, 08:06:50 pm by HazardsMind » Logged

Created Libraries:
TFT_Extension, OneWireKeypad, SerialServo, (UPD)WiiClassicController, VWID

Offline Offline
Jr. Member
**
Karma: 0
Posts: 54
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@AllenI

In your loop, for cases 76 and 82, your declairing void set_left_eye() and void set_right_eye(), when you dont need to include the void. If you have the functions made already, then you don't need to include void in you cases. basically what your doing is remaking the function with "nothing", If you take away the void then it becomes a "CALL method", which goes to the function and does whatever it needs to.

So change that and you might be ok.

Afterwards post the new code, THE FULL CODE!, many people just post parts, parts dont compile!

SHOUT OUT TO ALL FIRST TIMERS WHO READ THIS, POST YOUR FULL CODES!

That was the full code. I took away the 'void' in my two functions but it wouldnt compile...

Looking at PaulS' example program above, can someone explain what's going on in this line?
inData[index] = '\0';
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 302
Posts: 26342
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Looking at PaulS' example program above, can someone explain what's going on in this line?
inData[index] = '\0';
He's making sure a C string remains correctly terminated.

Quote
That was the full code. I took away the 'void' in my two functions but it wouldnt compile...
Because you left out the parameters you promised to pass to those functions
« Last Edit: November 20, 2012, 04:46:53 pm by AWOL » Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Pages: [1]   Go Up
Jump to: