Mixed Variablen received, sometimes a error

Hello community
I have a problem sending variables (20 pieces) separated by a comma. they are sent from an Arduino via Bluetooth.
It also works, but about one in 15 data packets does not arrive completely at Ai2. time interval of
transmission packets is one second.
Where can the intermittent error transmission come from. How can I track down the error?

Many thanks for tips
Greetings Stefan

This type of error is usually associated with relying on timing, instead of using message Delimiters.

Here is my standard advice:

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.
BlueToothClient1_Properties
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.

Hallo

clock timer by AI2 = 1000
timer to send by arduino = 2000
Delimiter by Bluetooth client = 10

Arduino code to send:

void BT_Senden()

{
String SENDE;
V=V+1;
SENDE = Zieladresse +","+V+","+I+","+VPV+","+PPV+","+LF+","+RT+","+LU+","+LI+","+AC_OUT_S+","+LA1+","+LA2+","+LA3+","+H19+","+H20+","+H21+","+H22+","+H23+","+HSDS+","+CS;
BT.println(SENDE);
}

In 500 transmissions I have had the error occur 18 times. Can it be that it is normal??
I have no experience

You forgot the -1 byte count in the block to receive text.

????
I don't understand, then the last character would be missing, for example with with after the last comma, the info is 5, if I now shorten the data block by one character, the 5th is missing. Somewhere I don't understand. Maybe it is possible to show me the solution in the block.

Hello Eisenklotz

Zi,V,I,VPV,PPV,LF,RT,LU,LI,AC,LA1,LA2,LA3,H19,H20,H21,H22,H23,HSDS,CS

You are concatenating your values into a single string. That string, even with the short place holding variable names, exceeds the 20 bytes available per Bluetooth data packet (about 70 bytes) - are they variable values or are they command codes?

Note: the time interval used to collect data from the Arduino should be set to the longest possible that will meet the project goals. So if you can exceed 2000 milliseconds, do so. The App time interval should be approx 20% shorter.

So, try streaming the data:

BT.print(Zieladresse);
BT.print(,);
BT.print(V);
BT.print(,);
BT.print(I);
BT.print(,);
BT.print(VPV);
BT.print(,);
BT.print(PPV);
BT.print(,);
BT.print(LF);
BT.print(,);
BT.print(RT);
BT.print(,);
BT.print(LU);
BT.print(,);
BT.print(LI);
BT.print(,);
BT.print(AC_OUT_S);
BT.print(,);
BT.print(LA1);
BT.print(,);
BT.print(LA2);
BT.print(,);
BT.print(LA3);
BT.print(,);
BT.print(H19);
BT.print(,);
BT.print(H20);
BT.print(,);
BT.print(H21);
BT.print(,);
BT.print(H22);
BT.print(,);
BT.print(H23);
BT.print(,);
BT.print(HSDS);
BT.print(,);
BT.print(CS);
BT.println(); //end of data ASCII 10

If that fails, split the data into 20 byte (or less) chunks.

Edit: If there are float values being sent, reduce the decimal places first.

NumberOfBytes

This ensures that all bytes are read. The block "BytesAvailableToReceive" is a flag, not a function - so it 'knows' there are bytes available but does not necessarily return the total.

As it works, first of all a big thank you to ChrisWard, even if there was an error message. But by adding the marked line in the block it works now for 6000 transmissions without errors.
It is sent every 2 seconds and the data is retrieved every 1000ms in one go.
Attached is the finished solution.

Arduino:
String Zieladresse; //
float I = 0; //[mA] Batterieladestrom
float V = 0; //[mV] Batteriespannung
float VPV = 0; //[mV] Solar-Panel Spannung
int PPV = 0; //[W] Solar-Panel Leistung
float LF = 0.0; // LF = Luftfeuchtigkeit in Prozent
float RT = 0.0; // RT = Raumtemperatur in Grad Celsius
float LU = 0.0; // LU = 42v Lithium Batterie Spannung in Volt
float LI = 0.0; // LI = 42v Lithium Batterie Strom in Ampere
float AC_OUT_V = 0.0; // 0,01 V Spannung 230V Ausgang
float AC_OUT_I = 0.0; // 0,1 A Strom 230V Ausgang
int AC_OUT_S = 0; // VA Scheinleistung 230V Ausgang
int LA1 = 0; // LA1 Ladegerät1 AN/AUS # 1 = an (2A, 65W) für 42 V Batterie
int LA2 = 0; // LA2 Ladegerät2 AN/AUS # 1 = an (3A, 90W) für 42 V Batterie
int LA3 = 0; // LA3 Ladegerät3 AN/AUS # 1 = an (5A, 240W) für 42 V Batterie
float H19 = 0.0; // gesamt Ertrag kw/H
float H20 = 0.0; // Ertrag Heute
int H21 = 0; // gesamt Heute max
float H22 = 0.0; // Ertrag Gestern
int H23 = 0; // gesamt Gestern max
int HSDS = 0; // Anzahl Tage des Gerätes
int CS = 0; //Charger-Status 0=Aus, 2=Error, 3=Laden, 4=Entladen, 5=Batt V halten

void BT_Senden()
{
// BT = Softwareserial
// String SENDE;
V=V+1;
// SENDE = Zieladresse +","+V+","+I+","+VPV+","+PPV+","+LF+","+RT+","+LU+","+LI+","+AC_OUT_S+","+LA1+","+LA2+","+LA3+","+H19+","+H20+","+H21+","+H22+","+H23+","+HSDS+","+CS;
// BT.println(SENDE);

     BT.print(Zieladresse);
     BT.print(", ");
     BT.print(V);
     BT.print(", ");
     BT.print(I);
     BT.print(", ");                  
     BT.print(VPV);
     BT.print(", ");    
     BT.print(PPV);
     BT.print(", "); 
     BT.print(LF);
     BT.print(", "); 
     BT.print(RT);
     BT.print(", "); 
     BT.print(LU);
     BT.print(", "); 
     BT.print(LI);
     BT.print(", ");
     BT.print(AC_OUT_S);
     BT.print(", "); 
     BT.print(LA1);
     BT.print(", ");
     BT.print(LA2);
     BT.print(", ");
     BT.print(LA3);
     BT.print(", ");
     BT.print(H19);
     BT.print(", ");  
     BT.print(H20);
     BT.print(", ");
     BT.print(H21);
     BT.print(", ");
     BT.print(H22);
     BT.print(", ");
     BT.print(H23);
     BT.print(", ");
     BT.print(HSDS);
     BT.print(", ");
     BT.print(CS);
     BT.println();

}

###################################################

AI2 Block

I hope it can help someone who is in the same situation.

schönen Dank bis zum nächsten mal
Stefan

Hi Stefan

Good to hear it is working reliably now. I would say do not have a space character following your value delimiter ", " - it's an extra burden to the send and at the receiving end (App) it becomes a prefix to the value.

Are you referring to the value delimiter in my Clock example? As an example, it is there for you to adapt. I always use a "|" character as the value delimiter as (1) it's unlikely to be part of a data string and (2) it's easier to identify in App Inventor's blocks......

Hallo ChrisWard
it also works without this last one.
Delimeter Byte was not at 10 .
So thanks again
Stefan

There are effectively two delimiters:

  1. Value delimiter: e.g. '|'
  2. End of Packet Payload delimiter: ASCII char 10

[val|val|val\n][val|val|val\n][val|val|val\n]

Set the Payload delimiter in Screen Initialize:

If message length limits are a problem, consider sending your data in YAML format, one variable per line, in form label:value
RT:5
LU:77
etc.

This is easy to parse, by splitting each message at ':' and using item 1 of the resulting list to identify the variable and item 2 for its value.

That also frees you up from having to send slowly changing values with quickly changing values.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.