2017년 8월 8일 화요일

Receiving and Combining Multiple Byte

Hi.  I am new on this forum although I have been surfing it for a while.  New to the MIT App Inventor program although it is quite intuitive to use.

My question.  I am developing a weighing system that has a load cell connected to an Arduino Uno that connects to Android via  Bluetooth (HC-05 module).  The values I am trying to bluetooth from the Arduino are from 0 to around 550.  The Arduino will only transmit 1 byte at a time so I have been experimenting with various ways to get the correct value into MIT AI.  At the moment within the Arduino code I have changed the 2 byte value into an array of 2 1 byte values (basically cut the 16 bits in half to create 2 1 byte values).  This then gets tranmitted as an array.

My problem is that no matter what I have tried in MIT AI I cannot put the correct number into a field (I need a number not text BTW as I will need to do some maths on the number).  The attached file shows my current code - I have 2 text fields called DataByte1 and DataByte2 that I have used to experiment with 2 options to get the right number.  The first simply reads the bluetoothed value.  The second I was looking at whether I could sum or join the 2 separate bytes.

When trying to send a value of 380, DataByte1 returns a value of 123.  By splitting the binary number for 380 in Arduino (0000 0001 0111 1100) I get 2 separate binary numbers being 1 (0000 0001) and 124 (0111 1100).  MIT AI seems to take 1 from 124 to get its value of 123.  DataByte2 returns a value of 246 which is obviously the 123 that it used for DataByte1 added to itself.

Can somebody please let me know how to take a large number from the Arduino and enter it as a value in an MIT AI field or specifically how to use the 2 1-byte numbers that I am receiving??  Spent several days on this already

--
see this example how to receive something correctly

--
On the Arduino side, which command are you using to send the numbers?
Write() or Println()?

Keeping the data as a 16 bit integer on the Arduino side and sending it via a print() statement will eliminate the need to do math.
Receive the data as text in AI2, and AI2's math blocks can handle the text to numeric conversion automatically as needed.

Could you post your Arduino code here?

Also, there have been some HC-05 samples posted on this board in the past.
See this FAQ or use the board's search box for HC05.

--

It looks like you confused the blue '+' block with concatenation?

Also, you were reading Byte 1 twice and Byte 2 once?
What will that do to your position in the input buffer?

The formula for converting two consecutive  unsigned numbers into one number would be:
(256 * Byte1) + Byte2.

But how would you know if you had slipped down the buffer by 1 byte, so that you would be

The solution to that would be to send text, with  delimiter byte (LF works nicely.)
See the samples in the FAQ.

--
Thanks for the replies.  I have got this working but it is slow although slow is not necessarily a nagative thing as this project relates to weighing a car so I don't require multiple updates per second.  Not sure yet if the speed thing is on the Arduino side or the Android side.  I know my code is not well written and could possibly do with the use of a few loops although I am not sure if that would speed things up.  I will investigate that side of things more.

I am using the BTserial.write() command in the Arduino code as I didn't realise that the Android code would auto convert a text string to a number.  After my Arduino code has done some calculations on values pulled in from 4 different sensors I have this as the output code at the end of the main loop() (I am still using Serial.print so that I can see what is being sent via Bluetooth in the serial monitor.  This will be deleted once it all works) 12 variables each of 1-byte going to Android and 16 variables to the Arduino serial monitor!!!;

_______________________

// SEND DATA TO SERIAL MONITOR FOR TESTING PURPOSES ONLY (DELETE IN FINAL VERSION)
Serial.print("FL:  ");
Serial.print(weight_FL);
Serial.print("    ");
Serial.print(DataSentFL1);
Serial.print("    ");
Serial.print(DataSentFL2);
Serial.print("    ");
Serial.println(DataSentFL3);
Serial.print("FR:  ");
Serial.print(weight_FR);
Serial.print("    ");
Serial.print(DataSentFR1);
Serial.print("    ");
Serial.print(DataSentFR2);
Serial.print("    ");
Serial.println(DataSentFR3);
Serial.print("RL:  ");
Serial.print(weight_RL);
Serial.print("    ");
Serial.print(DataSentRL1);
Serial.print("    ");
Serial.print(DataSentRL2);
Serial.print("    ");
Serial.println(DataSentRL3);
Serial.print("RR:  ");
Serial.print(weight_RR);
Serial.print("    ");
Serial.print(DataSentRR1);
Serial.print("    ");
Serial.print(DataSentRR2);
Serial.print("    ");
Serial.println(DataSentRR3);

// send data via Bluetooth - flush ensure all data is sent before continuing
BTserial.write(DataSentFL1);
BTserial.flush();
BTserial.write(DataSentFL2);
BTserial.flush();
BTserial.write(DataSentFL3);
BTserial.flush();
BTserial.write(DataSentFR1);
BTserial.flush();
BTserial.write(DataSentFR2);
BTserial.flush();
BTserial.write(DataSentFR3);
BTserial.flush();
BTserial.write(DataSentRL1);
BTserial.flush();
BTserial.write(DataSentRL2);
BTserial.flush();
BTserial.write(DataSentRL3);
BTserial.flush();
BTserial.write(DataSentRR1);
BTserial.flush();
BTserial.write(DataSentRR2);
BTserial.flush();
BTserial.write(DataSentRR3);
BTserial.flush();

delay(2000);
___________________

In MIT AI2 I have worked out that for each loop of the Arduino, it is presenting multiple 1-byte pieces of data.  The MIT AI reads each one, processes it then reads the next.  I have therefore written code to receive each one into a variable on which some maths can be performed.  My current MIT AI project is displaying each piece of data received as well as the calulated numbers as I want to have visibility of what is received for testing purposes.  It is VERY clunky!!!.  I have attached pisctures of the main clock loop from AI2.

It works, but now it is time to see if I can make it work a little quicker.

--
I need to clarify my reply above as upon reflection it is lacking.

The Arduino is currently taking a measurement from a scale and then converting that number into 3 separate 1-byte numbers;

if (weight_FL > 255) {
if (weight_FL > 510){
DataSentFL1 = weight_FL - 510;
DataSentFL2 = 255;
DataSentFL3 = 255;
}
else {
DataSentFL1 = weight_FL - 255;
DataSentFL2 = 255;
DataSentFL3 = 0;
}
}
else {
DataSentFL1 = weight_FL;
DataSentFL2 = 0;
DataSentFL3 = 0;
}

i.e. a large number up to 765 gets split up so that the Arduino can send each number/variable as a single unit rather than me having to concetenate in AI2.  The downside is that 4 variables become 12.

Now my understanding of AI2 is that when looking for information via Bluetooth if I tell it to "ReceiveUnsigned1ByteNumber" that it will look in the buffer and take the first available byte (clearing that byte out of the buffer as it reads it).  When I ask it to "ReceiveUnsigned1ByteNumber" again it takes the next byte and so on.  Providing I know the order that the Arduino is transmitting each byte I should be able to allocate the correct bytes to the correct AI2 vaiable?  I see your point Abraham about the bytes getting out of sync and I have perhaps seen evidence of that occuring in this mornings testing :(.  Not sure how I would get around this unless the Arduino pre-fixed each bit of data with an identifier?

I will start working on test code to use strings instead as you suggested just to see what happens.....

--
Have now changed the Arduino code to use strings.  I now have it working great.  Thanks for the help.

--
OK I now have a new issue that I have spent hours researching without luck....

I am trying to send numbers from AI2 to Arduino via Bluetooth.  I am sending two numbers.  The first will always be 1 to 4 so a simple 1-byte number.  The second is a number that varies between 0 and 500.  I have a small routine to break this number down into 2 1-byte numbers with a zero being sent if the number is less than 256.  All good so far.  Block stuff attached.  Bluetooth is set to CharacterEncoding UTF-8 and DelimeterByte 0 (not sure what this second variable means).

When this information is being sent to the Arduino the "/" delimeters are showing as UTF-8 47 so trying to send the numbers 1 and 245 shows in Arduino as 147047245.  I cannot get the Arduino to parse this data as I never know how long the second value (0 in this example) will be and therefore where the "/" delimeters will be.

I am lost.  How can I send these two numbers from AI2 to Arduino via Bluetooth such that Arduino can read them????

--
The Blocky thing.

--
The key to this problem is to figure out how to convert string format numbers into internal number format on the Arduino (receiving) side.

Once you have settled on a all-text transmission format, that frees you up to insert non-numeric characters like "/" or "," between the numbers in your messages.

It also makes it possible to signal the end of a message by adding a special character like Line Feed (decimal 10) at the end of a message, to serve as a Delimiter.

Let's see what we get when we Google "Arduino text to integer"...

Looks good to me!

--

댓글 1개:

1. Quantum Binary Signals