Serial communication - problems with reading

token

Member
Licensed User
Hello,

I'm using BASIC4PPC 6.3 with a program based on the seriral-terminal sample.

I'am sending data-packages of 20 Bytes with a frequency of 200 ms from a plc to the compiled B4PPC-application.

My problem is, that not all 20 bytes will be received from the application but only the first 6-10. After a while the B4PPC-app hangs and have to be killed with the task-manager. If I only send 1 Byte it works flawlessly.

Same problem with a connected datamatrix-camera which sends 67 byte-packages with a frequence of about 180 ms.

I tried changing the timeout of the serial-object but it didn't helped.

Thanks a lot for any suggestions in advance!

Regards:

Token
 

token

Member
Licensed User
Can you post the code you use for reading the data?

Hello Erel,

I've attached the code. I've used the serialterminal exmaple as base. I'am using it for desktop only. Com-Parameters are: 115200b,8databits, 1 stopbit, no parity.

Btw.: If I connect a datamatrix-cam and I'am using the original serialterminal-example the problem I encounter is somewhat different: For each scan the camera sends 67 Bytes. There are about 5-12 scans per second. Data seems to come in correctly, but after a while no more data is receive, the transmission stops without an error-message, and/or the application hangs.
 

Attachments

  • serial_test.sbp
    11.1 KB · Views: 225

konisek

Member
Licensed User
Longtime User
I have similar problem. I need to send 22 bytes and receive them back. For a test, I made a loopback on the COM1 port (connected pins 2+3) so that I can see what data are coming back. First I tried Serial1_OnCom but it reads the data only in 8 byte packets, then I tried the Timer1_Tick but received only 14 bytes (not those 22 sent!), last 8 bytes are lost. I don't know what is wrong with OnCom or Tick but neither of them reads all 22 bytes. Any help, please?

Sub Timer1_Tick
If Serial1.InBufferCount > 0 Then
Buffer()= serial1.InputArray
For i = 0 To ArrayLen(Buffer())-1
ReceivedString = ReceivedString & DecToHex(Buffer(i))
Next
textBox1.Text = ReceivedString
End If
End Sub


Sub Button6_Click
Timer1.Enabled = True
textBox2.Text = "AAAA0100000000010B30363036423030303236010368"
Byt3(0)=170
Byt3(1)=170
Byt3(2)=001
Byt3(3)=000
Byt3(4)=000
Byt3(5)=000
Byt3(6)=000
Byt3(7)=001
Byt3(8)=011
Byt3(9)=048
Byt3(10)=054
Byt3(11)=048
Byt3(12)=054
Byt3(13)=066
Byt3(14)=048
Byt3(15)=048
Byt3(16)=048
Byt3(17)=050
Byt3(18)=054
Byt3(19)=001
Byt3(20)=003
Byt3(21)=104
serial1.Output2(Byt3())
End Sub

tx_rx.jpg
 

agraham

Expert
Licensed User
Longtime User
Which serial library are you using, SerialDevice, SerialDesktop, Serial2 or SerialEx? Are you on the desktop or a device?

Although not your (current) problem, as you appear to want to receive binary data, if you are using Serial2 you should use my (.NET 2.0 only) http://www.b4x.com/forum/additional-libraries/3368-serialex-improved-serial2-library.html#post18998 library instead due to this problem http://www.b4x.com/forum/questions-help-needed/3155-receiving-byte-value-0x1a.html in Serial2.

Try my library anyway although it should behave identically to Serial2 in all situations that don't need the enhancements. However it looks like the default setting on your system may be to only interrupt or transfer data every 8 bytes. Try sending an extra byte at the end and see if it pushes the missing 8 bytes out. If you use SerialEx you can try setting the RxBytesThreshold to 1 and see if that alters the behaviour.
 

konisek

Member
Licensed User
Longtime User
I am on the desktop and use a Serial2. I tested the comunication rather with strings but behaves the same. In my example I send two strings "AAAAAAAAAAAAAAAAAAAAAA" and "BBBBBBBBBBBBBBBBBBBBBB" with a 1000 ms time period. But the receiving textbox always concatenates both strings together but I expect to see in the receiving TextBox1 the first string only, and then in 1 second later the second string only. The TextBox2 is just for information what I am sending.

Sub App_Start
Form1.Show
serial1.New2(1,9600,"N",8,1)
serial1.PortOpen = True
End Sub

Sub casovac
Sleep(1000)
End Sub

Sub ButtonTe_Click
serial1.EnableOnComm = True
TextBox1.Text = ""
casovac
serial1.Output("AAAAAAAAAAAAAAAAAAAAAA")
TextBox2.Text = "AAAAAAAAAAAAAAAAAAAAAA" '
TextBox2.Refresh
'Msgbox("break")
TextBox1.Text = ""
casovac
serial1.Output("BBBBBBBBBBBBBBBBBBBBBB")
TextBox2.Text = "BBBBBBBBBBBBBBBBBBBBBB" '
TextBox2.Refresh
End Sub

Sub Serial1_OnCom
char = serial1.InputString
buffer = buffer & char
TextBox1.Text = TextBox1.Text & buffer
buffer = ""
End Sub


When I enable the Msgbox("break"), I get the correct result
with_msgbox.jpg


however when I disable it, it concatenates it together, and that I don't want.
no_msgbox.jpg

The same code written in VB6 works fine!!!
Finaly, the application should send 8 different strings (bytes) with 1 second interval to a connected device on COM1 and should receive single replies from the device based on the single sent string. The firtst 6 strings inicialise the device, the last 2 strings will continuously monitor the device in the loop. For testing the Tx/Rx communication I use a loopback on COM1.
 

TWELVE

Active Member
Licensed User
Hi,

from my perspective of view you should avoid to manipulate a textbox's content ( or a variable's content) in different places in your code "at the same time", if you don't have implemented some mechanisms to synchronize them.Look at the red arrows i inserted below:

serial1.Output("AAAAAAAAAAAAAAAAAAAAAA")
TextBox2.Text = "AAAAAAAAAAAAAAAAAAAAAA" '
TextBox2.Refresh
'Msgbox("break")
TextBox1.Text = "" <----------
casovac
serial1.Output("BBBBBBBBBBBBBBBBBBBBBB")
TextBox2.Text = "BBBBBBBBBBBBBBBBBBBBBB" '
...
Sub Serial1_OnCom
char = serial1.InputString
buffer = buffer & char
TextBox1.Text = TextBox1.Text & buffer <--------
buffer = ""
End Sub

You send out the string, and shortly after this you clear the TextBox1 content.Virtually in parallel your OnCom event is also manipulating the Textbox1 content.Since you don't know, which of both "Textbox1.Text = " will occur first, this is kinda race condition.At the moment it looks like, the statement in the main part is winning this everything.So you end up in this order:

Textbox = ""
serial.output first string
Textbox ="" <--you clear the empty box, because the OnCom didn't trigger yet
OnCom <--- Textbox gets filled with first string
wait a second
serial.output second string
...
OnCom <--- Textbox adds the second string

In other words: you clear the textbox that was already empty and then the OnCom Event puts in the first string.



If you put in a wait loop in here:

serial1.Output("AAAAAAAAAAAAAAAAAAAAAA")
TextBox2.Text = "AAAAAAAAAAAAAAAAAAAAAA" '
TextBox2.Refresh
'Msgbox("break") <--- wait a bit here
TextBox1.Text = ""

Although a wait loop is not safe ( some factors like send string length may vary), it would be a workaround for your particular piece of code.In real world you would need to ensure that all bytes of your string have been received by the buffer, so you know the textbox can be cleared.You could also place something like an end-of-line character at the very end of your string, if your OnCom detects this character, it clears out the textbox.




regards,


TWELVE
 
Last edited:

konisek

Member
Licensed User
Longtime User
Finally, I solved it in this way:
B4X:
serial1.Output2(Byt8())
casovac
frombuffer
casovac
TextBox19.Text = TextBox4.Text
   TextBox19.Refresh
Loop
and replaced the OnCom event because it did not work:
B4X:
Sub frombuffer 'Serial1_OnCom
   Buffers()= serial1.InputArray
   'Msgbox(ArrayLen(Buffers()))
   For i = 0 To ArrayLen(Buffers())-1
      buffer = buffer & DecToHex(Buffers(i))
   Next
   
   'Msgbox(buffer)
   TextBox4.Text = buffer
   TextBox4.Refresh
   buffer = ""
End Sub
 
Top