Sub AStreams_NewData (Buffer() As Byte)
Dim msg As String
If msg.StartsWith ("S1") Then
msg = BytesToString(Buffer, 0, 3, "UTF8")
Dim s1 As Int = msg
Label1.Text = msg
End If
If msg.StartsWith ("S2") Then
msg = BytesToString(Buffer, 0, 3, "UTF8")
Dim s2 As Int = msg
Label2.Text = s2
End If
End Sub
How are you going to determine the msg variable start with s1? I think your if condition block msg variable to begin passed sense you check before reading
In the absence of an actual question, I suspect your problem is that you are using msg (".StartsWith") before msg is given a value. So put the "msg =" bit before you check it, eg:
B4X:
Sub AStreams_NewData (Buffer() As Byte)
Dim msg As String
msg = BytesToString(Buffer, 0, 3, "UTF8") 'msg = BytesToString(Buffer, 0, 3, "UTF8")
If msg.StartsWith ("S1") Then
Also note the possible upcoming problems:
(i) you should probably first check the length of the buffer, before converting it to a string, and
(ii) UTF8 conversion is probably going to do unexpected things for bytes > 127
How are you going to determine the msg variable start with s1? I think your if condition block msg variable to begin passed sense you check before reading
Sub AStreams_NewData (Buffer() As Byte)
Dim bc As ByteConverter
Dim msg As String = bc.StringFromBytes(Buffer, "UTF8")
If msg.StartsWith ("S1") Then
Label1.Text = msg.SubString(2)
End If
If msg.StartsWith ("S2") Then
Label2.Text = msg.SubString(2)
End If
'If msg.StartsWith ("S123") Then
' Label123.Text = msg.SubString(4)
'End If
End Sub
If you have access to the Arduino program code, then you would be better to delimit/separate your message fields, eg:
S1=200
S2=400
and then you will be able to cleanly expand to S10 and beyond
You can decode the fields by:
B4X:
Dim EqualsAt As Int = msg.IndexOf("=")
If EqualsAt < 0 Then
Log("invalid setting line: " & msg)
Else
Dim SettingId As String = msg.SubString(0, EqualsAt)
Dim SettingValue As String = msg.SubString(EqualsAt + 1)
Select Case SettingId 'assuming B4A does selects on strings...
Case "S1"
Label1.Text = SettingValue
Case "S2"
Label2.Text = SettingValue
Case "S9", "S10", "S11"
Label9to11.Text = SettingValue
End Select
End If
Your best option is to use B4R on the Arduino and use AsyncStreams in prefix mode. Otherwise you cannot assume that the messages will not be split. You can use AsyncStreamsText in B4A if the messages end with a defined character.
This is a good point (that I always forget)(and Erel always remembers).
If you are still having trouble, even after rearranging the code so that you check msg *after* putting something in it, then split messages may well be the problem, and AsyncStreams in prefix (or text line) mode is a solution, if you have access to the Arduino side of the interface.
If you have access to the Arduino program code, then you would be better to delimit/separate your message fields, eg:
S1=200
S2=400
and then you will be able to cleanly expand to S10 and beyond
You can decode the fields by:
B4X:
Dim EqualsAt As Int = msg.IndexOf("=")
If EqualsAt < 0 Then
Log("invalid setting line: " & msg)
Else
Dim SettingId As String = msg.SubString(0, EqualsAt)
Dim SettingValue As String = msg.SubString(EqualsAt + 1)
Select Case SettingId 'assuming B4A does selects on strings...
Case "S1"
Label1.Text = SettingValue
Case "S2"
Label2.Text = SettingValue
Case "S9", "S10", "S11"
Label9to11.Text = SettingValue
End Select
End If
Your best option is to use B4R on the Arduino and use AsyncStreams in prefix mode. Otherwise you cannot assume that the messages will not be split. You can use AsyncStreamsText in B4A if the messages end with a defined character.
Sub AStreams_NewData (Buffer() As Byte)
Dim bc As ByteConverter
Dim msg As String = bc.StringFromBytes(Buffer, "UTF8")
If msg.StartsWith ("S1") Then
Label1.Text = msg.SubString(2)
End If
If msg.StartsWith ("S2") Then
Label2.Text = msg.SubString(2)
End If
'If msg.StartsWith ("S123") Then
' Label123.Text = msg.SubString(4)
'End If
End Sub
I tried it already ok, when I creamed S1340 or S1 = 340.
appeared to work well.
but when I send S130 or S1 = 30 an error appears.
The point is that every data less than 3 digits the app appears error
I tried it already ok, when I creamed S1340 or S1 = 340.
appeared to work well.
but when I send S130 or S1 = 30 an error appears.
The point is that every data less than 3 digits the app appears error
Hmm. Perhaps I have assumed too much of .SubString. Add the following Log lines, post the resultant log:
B4X:
Sub AStreams_NewData (Buffer() As Byte)
Dim bc As ByteConverter
Dim msg As String = bc.StringFromBytes(Buffer, "UTF8")
Log("msg = " & msg.Length & " [" & msg & "]") '*** ADD THIS LINE ***
If msg.StartsWith ("S1") Then
Log("S1") '*** ADD THIS LINE ***
Label1.Text = msg.SubString(2)
End If
If msg.StartsWith ("S2") Then
Log("S2") '*** ADD THIS LINE ***
Label2.Text = msg.SubString(2)
End If
'If msg.StartsWith ("S123") Then
' Label123.Text = msg.SubString(4)
'End If
End Sub
Hmm. Perhaps I have assumed too much of .SubString. Add the following Log lines, post the resultant log:
B4X:
Sub AStreams_NewData (Buffer() As Byte)
Dim bc As ByteConverter
Dim msg As String = bc.StringFromBytes(Buffer, "UTF8")
Log("msg = " & msg.Length & " [" & msg & "]") '*** ADD THIS LINE ***
If msg.StartsWith ("S1") Then
Log("S1") '*** ADD THIS LINE ***
Label1.Text = msg.SubString(2)
End If
If msg.StartsWith ("S2") Then
Log("S2") '*** ADD THIS LINE ***
Label2.Text = msg.SubString(2)
End If
'If msg.StartsWith ("S123") Then
' Label123.Text = msg.SubString(4)
'End If
End Sub
everything is not good.
I tried to see incoming data from the serial via Bluetooth Terminal Hc05 is ok.
but when in the application such as lack of response. even label2.text doesn't appear
Righto, first thing is that I am itching to do is make this code more future-proof, and the serial communications more human-readable, by adding that "=":
B4X:
void loop() {
int S1 = analogRead(A0);
Serial.print("S1=");
Serial.println(S1);
delay(100);
int S2 = analogRead(A1);
Serial.print("S2=");
Serial.println(S2);
delay(100);
}
Then see if you can see those incoming lines with a regular terminal program like RealTerm.
Then, in your B4A Android app, temporarily rename the existing AStreams_NewData Sub to old_AStreams_NewData.
Use this in its place, to log the same incoming data, and post say a dozen lines to this thread.
B4X:
Sub AStreams_NewData (Buffer() As Byte)
Dim bc As ByteConverter
Log(DateTime.Now & " " & bc.HexFromBytes(Buffer) & " " & bc.StringFromBytes(Buffer, "UTF8"))
End Sub
Once we've confirmed how the data is coming in, then we'll know how to handle it
If you have access to the Arduino program code, then you would be better to delimit/separate your message fields, eg:
S1=200
S2=400
and then you will be able to cleanly expand to S10 and beyond
You can decode the fields by:
B4X:
Dim EqualsAt As Int = msg.IndexOf("=")
If EqualsAt < 0 Then
Log("invalid setting line: " & msg)
Else
Dim SettingId As String = msg.SubString(0, EqualsAt)
Dim SettingValue As String = msg.SubString(EqualsAt + 1)
Select Case SettingId 'assuming B4A does selects on strings...
Case "S1"
Label1.Text = SettingValue
Case "S2"
Label2.Text = SettingValue
Case "S9", "S10", "S11"
Label9to11.Text = SettingValue
End Select
End If
I have replaced it with this code, but there was an error while in Run
Too many parameters.
which one should i fix
B4X:
Sub AStreams_NewData (Buffer() As Byte)
Dim bc As ByteConverter
Dim msg As String = bc.StringFromBytes(Buffer, "UTF8")
Log("msg = " & msg.Length & " [" & msg & "]")
Dim EqualsAt As Int = msg.IndexOf("=")
If EqualsAt < 0 Then
Log("invalid setting line: " & msg)
Else
Dim SettingId As String = msg.SubString(0, EqualsAt)
Dim SettingValue As String = msg.SubString(EqualsAt + 1)
Select Case SettingId 'assuming B4A does selects on strings...
Case "S1"
Label1.Text = SettingValue
Case "S2"
Label2.Text = SettingValue
End Select
End If
End Sub
The error message should have indicated precisely which line the error was on, but at least you mentioned the "too many parameters" message which was clue enough that the problem is probably the line:
Dim SettingId As String = msg.SubString(0, EqualsAt)
which should be:
Dim SettingId As String = msg.SubString2(0, EqualsAt)
I'm hopeful it will all now work no problem, but I'd be happy to see the log anyway just to be sure.
There is still the possibility that text lines might be split into two delivery events, with the start of a line in one packet and the end in the next packet. The solution is probably AsyncStreamsText per:
- If the data sent and received is text based and each message ends with an end of line character(s) then you should use AsyncStreamsText. For example if you are connecting to an external GPS. Note that it is also possible to modify the class and support different delimiters.
The advantage of using AsyncStreamsText is that it will build the messages correctly. You will not receive partial messages (or multiple messages together).