Sending variable thru blue tooth to android app.

Hello folks I have beat up the AI2 sights and google and have not been able to find the solution to my problem.

So I have created an app that receives serial messages from my arduino (mega) sensor through blue tooth/SPI. I have created the app in APP Inventor, pretty basic!! it sends text to the arduino quite well. the arduino however does not send values of a variable back to the android phone. i have paired down a sketch to show you what I am doing. I can print on my lcd the variable (it works) but I have different result between the lcd and Phone readout. My serial write goes to the phone and reads

the Phone reads

71
0
0
4

the LCD reads

71
51
13
4

The LCD reads correctly. so the functional code is good ,but some how I can not see what I am doing on the Serial.write(batt); and Serial.write(batt_1); scr writes correctly (4) but Batt_1 does not? (0).

What am I missing. There are alot of posts on the App inventor forums but nothing that explains my issue.

Thanks for Looking.

Dave

int scr = 4;

struct Sens {
  
  uint8_t Batt_Voltage;
  uint8_t Pos_Right;
  uint8_t Pos_Left;
} Sens_1, Sens_2, Sens_3, Sens_4;

uint8_t batt_1 = Sens_1.Batt_Voltage;
uint8_t batt_2 = Sens_2.Batt_Voltage;
uint8_t batt_3 = Sens_3.Batt_Voltage;
uint8_t batt_4 = Sens_4.Batt_Voltage;
uint8_t batt   = batt_1 + batt_2 + batt_3 + batt_4;

void setup()
{ 
  Serial.begin(9600);
  lcd.begin(16, 2);  
}
void loop()
{

if (Serial.available() > 0) // if data is available to read
  {  
    val = Serial.read(); // read it and store it in 'val'
    
if ( val == 'A' ) // if 'A' was received
    {     
      
  if (Serial)
      {               
        Serial.write(71);         
        Serial.write(batt);            // combined voltage of batteries.
        Serial.write(batt_1);        // Battery level sens 1
        Serial.write(scr);              
      }
        }
          }
      Print ();
    }
void Print ()
{
    uint8_t batt_1 = Sens_1.Batt_Voltage;
    uint8_t batt_2 = Sens_2.Batt_Voltage;
    uint8_t batt_3 = Sens_3.Batt_Voltage;
    uint8_t batt_4 = Sens_4.Batt_Voltage;
    uint8_t batt   = batt_1 + batt_2 + batt_3 + batt_4;
 
    lcd.clear();
    lcd.setCursor(0, 0);    
    lcd.print(71);
    lcd.setCursor(2, 1);
    lcd.print(batt);
    lcd.setCursor(12, 1);
    lcd.print(batt_1);
    lcd.setCursor(14, 1);
    lcd.print(scr);
 
}

You've got to actually assign something to the GLOBAL version of batt and batt_1 in the loop function. Looks like you're mixing global and local variables up.

Never give variables more scope than they need and avoid globals whenever you possibly can. These are good rules to follow.

Sorry,not wanting to post 800 lines of code a cut a little too much out. I have assigned Batt. the remember the lcd prints correctly. Why would the same variable not write correctly over SPI?

weldsmith:
Sorry,not wanting to post 800 lines of code

Probably just as well, as 800 lines of code for a job like this does sound a bit excessive. As it is you should be able to send the same data to both bluetooth and LCD in the same manner.

lcd.print(data);
Serial.print(data);

Why don't you just use a bluetooth terminal? It will probably help you deal with the problem.

Sorry,not wanting to post 800 lines of code a cut a little too much out. I have assigned Batt. the remember the lcd prints correctly. Why would the same variable not write correctly over SPI?

weldsmith:
Sorry,not wanting to post 800 lines of code a cut a little too much out. I have assigned Batt. the remember the lcd prints correctly. Why would the same variable not write correctly over SPI?

You have defined batt and batt_1 at global scope and in Print() you have defined batt and batt_1 locally. Two different variables. Print() only writes to the locally defined batt and batt_1, and of course they disappear when Print() returns.

Nick your funny! but you should be able to send in the same way. That is the confusing part.

I have never use blue terminal.. can you elaborate?

If the LCD reads correctly and the phone does not, then the issue is most likely in the phone receiving code.

zoomkat,

I agree, but it is so close!!!

I put in SCR for a test and it writes to the phone properly.

int scr = 4

serial.write (scr)


[/code ]

[left]
That produces a 4 on the phone. 
[/left]

zoomkat:
If the LCD reads correctly and the phone does not, then the issue is most likely in the phone receiving code.

Except the phone receives the constants correctly. I think there's an issue with how the variables are handled.

Exactly, but it handled scr ok. Why? Soo frustrating !!!!!

If the bluetooth device is connected to the mega serial tx pin, you should be able to see in the serial monitor what is being sent to see if it is what you expect. The below is suspect as serial.write may not produce the character 4 on the phone if you are looking for an ascii 4 character.

int scr = 4

serial.write (scr)


[/code ]

[left]
That produces a 4 on the phone.
[/left]

zoomkat,

your right that code will not. I was referring to the scr in my code. I did look in to the serial monitor and it gives me gibberish.

zoomkat makes a good point.

I'm guessing the AI2 program receives the value as an integer rather than an ASCII character. This is probably a good strategy since converting ASCII characters to numeric values is surprisingly awkward with AI2.

I have thought of this but the variable does not change as the value changes I should get a different ASCII character right?

Should I reformat the variable before I send it?

I just realized that I am now using write not print. I have tried both methods. Serial.write is sending a binary byte. and that is how my code blocks are aligned in AI2. (receive 1 signed byte number). Serial print sends ascii characters. How would AI2 prefer it?

weldsmith:
How would AI2 prefer it?

DuaneDegn:
the AI2 program receives the value as an integer rather than an ASCII character. This is probably a good strategy since converting ASCII characters to numeric values is surprisingly awkward with AI2.

weldsmith:
Nick your funny! but you should be able to send in the same way. That is the confusing part.

I have never use blue terminal.. can you elaborate?

I didn't mean to be funny! This is an Arduino forum, and I am just on about isolating the problem. Your Android app does not appear to do anything more than that which can be done with a plain-vanilla bluetooth terminal. If the terminal does what you want, then there is nothing wrong with your code, wiring, or procedures.

As Zoomkat says, you can watch proceedings on the PC serial monitor while you do the deeds on your Android device, but only watch. You cannot send from the serial monitor.

You might find the following background notes useful

http://homepages.ihug.com.au/~npyner/Arduino/GUIDE_2BT.pdf
http://homepages.ihug.com.au/~npyner/Arduino/BT_2_WAY.ino

There is a swag of bluetooth terminals in the Store. I use Bluetooth Graphics Terminal but any of them should be fine for your purposes.

Nick_Pyner:
As Zoomkat says, you can watch proceedings on the PC serial monitor while you do the deeds on your Android device, but only watch. You cannot send from the serial monitor.

weldsmith would need to use a terminal which displays non-ASCII characters.

On the AI2 side, it's easier to receive numeric values if they aren't ASCII encoded.

I went through the trouble of being able to convert ASCII values to numeric values but it was a huge pain. From what I understand of AI2, it's easier to receive the raw values than converting from ASCII. These raw values aren't serial terminal friendly and you can't easily send control characters with your data to AI2.

I realize as I type this, I haven't check to see if AI2 has improved their ASCII handling lately. I logged in to AI2 a few days ago to find significant upgrades. Maybe the ASCII thing isn't a big deal anymore?

BTW, It's certainly easy to receive ASCII characters in AI2. It's just not very easy to convert these characters to numeric values.