Not at all. You can upload only on foreign server.europa81 wrote:PS: Forum-question - how can I include an image without the need of hosting it on another server first
RS-232 receive data
- RSBasic
- Moderator
- Posts: 1228
- Joined: Thu Dec 31, 2009 11:05 pm
- Location: Gernsbach (Germany)
- Contact:
Re: RS-232 receive data
Re: RS-232 receive data
Thanks, will keep hosting elsewhere when need be.
Here now is the code with procedure instead of a subroutine:
as you see, I am preparing to send data out over the serial port. Basically read the position of the tx-data TrackBar and send that byte in order for the µController to control the brightness of a LED by PWM. And again I run into the same problem: the command WriteSerialPort requires a Buffer. How in the world can I know where the buffer is ?
Other question: when I resize or reposition the running programme, it will start to receive garbage. Probably due to a buffer-overrun. How can I force the programme to keep running while it is being resized ?
Thomas
Here now is the code with procedure instead of a subroutine:
Code: Select all
#WindowColor=$FAFAFA
Procedure rs232()
b.l=AvailableSerialPortInput(0)
If ReadSerialPortData(0,@Puffer,b)
p$=Str(puffer)
SetGadgetState (2,Puffer)
EndIf
EndProcedure
Define flags = #PB_Window_ScreenCentered|#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget
OpenWindow(0,0,0,300,100,"RS-232",flags)
WindowBounds(0,150,150, #PB_Ignore, #PB_Ignore)
SetWindowColor(0,#WindowColor)
TextGadget(0,5,10,48,20, "rx-data:", #PB_Text_Center)
TextGadget(1,5,50,48,20, "tx-data:", #PB_Text_Center)
TrackBarGadget (2, 55, 10, 240, 30, 0, 100)
TrackBarGadget (3, 55, 50, 240, 30, 0, 100)
OpenSerialPort(0,"COM9",1200,#PB_SerialPort_NoParity,8,1,#PB_SerialPort_NoHandshake,512,512)
AddWindowTimer(0,0,20)
Repeat
Select WaitWindowEvent()
Case #PB_Event_Timer: rs232()
Case #PB_Event_CloseWindow:CloseSerialPort(0):End
EndSelect
ForEver
Other question: when I resize or reposition the running programme, it will start to receive garbage. Probably due to a buffer-overrun. How can I force the programme to keep running while it is being resized ?
Thomas
Re: RS-232 receive data
Hi,
the bytes are already in a 'buffer' (from the OS and it's driver) as I told you.
Withe ReadSerialPortData() you transfer the bytes from the OS buffer to a buffer of your choice.
A buffer is a memory area, so you need a pointer which points at this memory.
If you want to fetch one byte after an other, than a buffer of one byte is enough.
You can define a byte variable (Byte.a) and give the ReadSerialPortData() procedure the address of this byte.
This is done via @Byte which means address of the variable Byte.
If you want to transfer more than one byte, than you need a 'real' buffer which needs to be allocated with
AllocateMemory().
If you want to write serial port data you have 2 choices
For a string WriteSerialPortString() and for bytes WriteSerialPortData().
But normally you need the #PB_Ascii flag for the string variant.
I hope you can follow these explanations.
Bernd
the bytes are already in a 'buffer' (from the OS and it's driver) as I told you.
Withe ReadSerialPortData() you transfer the bytes from the OS buffer to a buffer of your choice.
A buffer is a memory area, so you need a pointer which points at this memory.
If you want to fetch one byte after an other, than a buffer of one byte is enough.
You can define a byte variable (Byte.a) and give the ReadSerialPortData() procedure the address of this byte.
This is done via @Byte which means address of the variable Byte.
If you want to transfer more than one byte, than you need a 'real' buffer which needs to be allocated with
AllocateMemory().
If you want to write serial port data you have 2 choices
For a string WriteSerialPortString() and for bytes WriteSerialPortData().
But normally you need the #PB_Ascii flag for the string variant.
I hope you can follow these explanations.
Bernd
Re: RS-232 receive data
In your last example the variable 'Puffer' is declared 'on the fly' which means it is an integer variable.
For a beginner, and also for me, it is a good decission to use EnableExplicit at beginning of your code.
Then you have to define your variables before you can use them.
This has one big advantage:
If you make a typo like Pufer instead of Puffer you will be informed that something is wrong.
Without you are searching for hours until you find out that your value is written to the wrong variable.
Bernd
For a beginner, and also for me, it is a good decission to use EnableExplicit at beginning of your code.
Then you have to define your variables before you can use them.
This has one big advantage:
If you make a typo like Pufer instead of Puffer you will be informed that something is wrong.
Without you are searching for hours until you find out that your value is written to the wrong variable.
Bernd
Re: RS-232 receive data
Btw. I don't see any try to send something.
Re: RS-232 receive data
This works also in PB.Code: Select all
buffer_length = available_bytes_in_buffer for x=0 to buffer_length-1 receive$=receive$+byte(x) next x
Code: Select all
buffer_length = AvailableSerialPortInput(0)
For x=1 To buffer_length
ReadSerialPortData(0, @Byte, 1)
receive$ = receive$ + Chr(Byte)
Next x
2 posibillities:
1. you use a length byte in front
2. you only send ascii values and terminate the string with a CR
Bernd
Re: RS-232 receive data
Code: Select all
EnableExplicit
#WindowColor=$FAFAFA
Procedure rs232()
Protected RxByte.a
While AvailableSerialPortInput(0)
If ReadSerialPortData(0,@RxByte,1) = 1
SetGadgetState(2, RxByte)
EndIf
Wend
EndProcedure
Define TxByte.a
Define flags = #PB_Window_ScreenCentered|#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget
OpenWindow(0,0,0,300,100,"RS-232",flags)
WindowBounds(0,150,150, #PB_Ignore, #PB_Ignore)
SetWindowColor(0,#WindowColor)
TextGadget(0,5,10,48,20, "rx-data:", #PB_Text_Center)
TextGadget(1,5,50,48,20, "tx-data:", #PB_Text_Center)
TrackBarGadget (2, 55, 10, 240, 30, 0, 100)
TrackBarGadget (3, 55, 50, 240, 30, 0, 100)
OpenSerialPort(0,"COM3",1200,#PB_SerialPort_NoParity,8,1,#PB_SerialPort_NoHandshake,512,512)
AddWindowTimer(0,0,20)
Repeat
Select WaitWindowEvent()
Case #PB_Event_Timer: rs232()
Case #PB_Event_Gadget
Select EventGadget()
Case 3
TxByte = GetGadgetState(3)
Debug TxByte
WriteSerialPortData(0, @TxByte, 1)
EndSelect
Case #PB_Event_CloseWindow:CloseSerialPort(0):End
EndSelect
ForEver
Re: RS-232 receive data
Hello Bernd,infratec wrote:This works also in PB.Code: Select all
buffer_length = available_bytes_in_buffer for x=0 to buffer_length-1 receive$=receive$+byte(x) next x
But when is your data finished?Code: Select all
buffer_length = AvailableSerialPortInput(0) For x=1 To buffer_length ReadSerialPortData(0, @Byte, 1) receive$ = receive$ + Chr(Byte) Next x
2 posibillities:
1. you use a length byte in front
2. you only send ascii values and terminate the string with a CR
Bernd
that is exactly the point - where is the x as pointer there ?? I still do not understand the @-sign. How does it know what to point to ?
And yes, I did not implement any tx-routine yet because of that buffer-issue. I tried today other compilers because there seems to be no answer !
I shall program the µController to terminate each sentence with a CRLF so the string can be parsed.
thanks
<Thomas>
Re: RS-232 receive data
Hi,
I wrote your code with sending. Look above
ReadSerialPortData() 'reads' out bytes from the OS rx buffer.
It's a FIFO structure. So if you call it the next time it returns the next data -> no need for a pointer.
If you want to terminate it with CRLF, you are limited to transfer only ASCII.
And you need double of time: 50 needs 0x35 0x30 0x0D 0x0A instead of a single 0x32.
But if you have a 'text' driven interface it makes live easier to use ASCII.
Bernd
I wrote your code with sending. Look above

Since you read only one byte after an other you need no X inside the loop.You can define a byte variable (Byte.a) and give the ReadSerialPortData() procedure the address of this byte.
This is done via @Byte which means address of the variable Byte.
ReadSerialPortData() 'reads' out bytes from the OS rx buffer.
It's a FIFO structure. So if you call it the next time it returns the next data -> no need for a pointer.
If you want to terminate it with CRLF, you are limited to transfer only ASCII.
And you need double of time: 50 needs 0x35 0x30 0x0D 0x0A instead of a single 0x32.
But if you have a 'text' driven interface it makes live easier to use ASCII.
Bernd
Re: RS-232 receive data
Hi,
I extended my thread example to read in a complete line with CRLF at the end.
And trust me:
There is no easier solution which works on all main OSs than PB.
And even if you 'only' write a windows program PB is easy and you get always help when needed.
If you find an easier way, tell me the solution
I extended my thread example to read in a complete line with CRLF at the end.
And trust me:
There is no easier solution which works on all main OSs than PB.
And even if you 'only' write a windows program PB is easy and you get always help when needed.
If you find an easier way, tell me the solution

Re: RS-232 receive data
Thank you, Bernd !
I trust you that PB is the easiest solution. What I like most is that you can compile such small stand-alone .exe-files.
Your new code works fine and the problem of repositioning and resizing is solved. Probably because you read the entire buffer. I lowered the timer to some crazy numbers (such as 1ooo ms) and it works fine.
As to chr vs byte: I am planning to read out the data from a 3-axis accelerometer which basically behaves like three ADC at 8-Bit resolution. This means, any combination is going to be possible. However, we never know, when the client is going to be connected or whether a byte has been corrupted during transmission. The only way out is going to be a protocoll with a start/end code and some sort of checksum.
As I plan to make this thread a starting point to all of us who are getting introduced to PB and the control of robots via the serial port (FTDI et al), let's get there step-by-step. Tomorrow I'll post the code with two rx/tx channels and we continue from there.
be well
<Thomas>
I trust you that PB is the easiest solution. What I like most is that you can compile such small stand-alone .exe-files.
Your new code works fine and the problem of repositioning and resizing is solved. Probably because you read the entire buffer. I lowered the timer to some crazy numbers (such as 1ooo ms) and it works fine.
As to chr vs byte: I am planning to read out the data from a 3-axis accelerometer which basically behaves like three ADC at 8-Bit resolution. This means, any combination is going to be possible. However, we never know, when the client is going to be connected or whether a byte has been corrupted during transmission. The only way out is going to be a protocoll with a start/end code and some sort of checksum.
As I plan to make this thread a starting point to all of us who are getting introduced to PB and the control of robots via the serial port (FTDI et al), let's get there step-by-step. Tomorrow I'll post the code with two rx/tx channels and we continue from there.
be well
<Thomas>
Re: RS-232 receive data
Alright, took another path: installed a RGB-LED on the AVR Board and control the three channels with three TrackBars individually. This code still uses one Byte only to transmit the three values by splitting up the range of 0 ~ 255 into:
Red: 0 ~ 80
Green: 81 ~ 161
Blue: 162 ~ 242
Next task is now to control three servos and use a different protocol allowing for full 8-Bit resolution each.
cheers
<Thomas>
Red: 0 ~ 80
Green: 81 ~ 161
Blue: 162 ~ 242
Next task is now to control three servos and use a different protocol allowing for full 8-Bit resolution each.
Code: Select all
EnableExplicit
#WindowColor=$F0F0F0
Define TxByte.a
Define flags = #PB_Window_ScreenCentered|#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget
OpenWindow(0,0,0,300,200,"RGB-Steuerung",flags)
WindowBounds(0,200,200, #PB_Ignore, #PB_Ignore)
SetWindowColor(0,#WindowColor)
TextGadget (0, 70, 5, 190, 20, "RGB-Steuerung", #PB_Text_Center)
TextGadget(1,5,30,30,20, "R: ", #PB_Text_Center)
TextGadget(2, 5, 60, 30, 20, "G:", #PB_Text_Center)
TextGadget(3, 5, 90, 30, 20, "B: ", #PB_Text_Center)
TrackBarGadget (4, 55, 30, 240, 30, 0, 80)
TrackBarGadget (5, 55, 60, 240, 30, 0, 80)
TrackBarGadget (6, 55, 90, 240, 30, 0, 80)
OpenSerialPort(0,"COM9",9600,#PB_SerialPort_NoParity,8,1,#PB_SerialPort_NoHandshake,512,512)
TxByte=0
WriteSerialPortData(0,@TxByte,1)
TxByte=81
WriteSerialPortData(0,@TxByte,1)
TxByte=162
WriteSerialPortData(0,@txbyte,1)
Repeat
Select WaitWindowEvent()
Case #PB_Event_Gadget
Select EventGadget()
Case 4
TxByte = GetGadgetState(4)
WriteSerialPortData(0, @TxByte, 1)
Case 5
TxByte=GetGadgetState(5)+81
WriteSerialPortData(0,@TxByte,1)
Case 6
TxByte=GetGadgetState(6)+162
WriteSerialPortData (0,@TxByte,1)
EndSelect
Case #PB_Event_CloseWindow:CloseSerialPort(0):End
EndSelect
ForEver
<Thomas>
Re: RS-232 receive data
Hi,
you can also use a 'packet' of 3 bytes with a guaranted minimum delay between the packets.
Than you can detect if it is a complete packet by checking a receive timeout between the bytes.
For example:
B1 max.10ms B2 max.10ms B3 min.100ms B1 max.10ms B2 max.10ms B3 min.100ms
If you received a byte you can check if the next byte is only max 15ms later.
If this happens 2 times, than you received a complete valid 3 byte packet.
I hope it's clear what I mean.
Bernd
you can also use a 'packet' of 3 bytes with a guaranted minimum delay between the packets.
Than you can detect if it is a complete packet by checking a receive timeout between the bytes.
For example:
B1 max.10ms B2 max.10ms B3 min.100ms B1 max.10ms B2 max.10ms B3 min.100ms
If you received a byte you can check if the next byte is only max 15ms later.
If this happens 2 times, than you received a complete valid 3 byte packet.
I hope it's clear what I mean.
Bernd
Re: RS-232 receive data
Thank you, Bernd. That was clear. Using the timing on the serial channel could make sure when a message starts. Else, one could use a certain start-Byte such as 0xFE and avoid repetition of the following sequence.
My goal is to keep most of the workload on the PC-Side as the AVR has so much less computing power.
Thanks
<Thomas>
My goal is to keep most of the workload on the PC-Side as the AVR has so much less computing power.
Thanks
<Thomas>
Re: RS-232 receive data
Now I am ready to receive a row of binary data which need to be analyzed. As you proposed, it should be done with AllocateMemory. In the programme I write:
and the compiler is unhappy with a non-declared variable. My questions:
(1) what does the "*" in front of the name of the allocated memory stand for ?
(2) why is the compiler unhappy ? I am thinking that the word before AllocateMemory is the name of the memory and not a variable.
cheers
Thomas
Code: Select all
*uavdata=AllocateMemory (256)
(1) what does the "*" in front of the name of the allocated memory stand for ?
(2) why is the compiler unhappy ? I am thinking that the word before AllocateMemory is the name of the memory and not a variable.
cheers
Thomas