Recent

Author Topic: Receiving serial string with 5DPO  (Read 17460 times)

PeterH

  • New Member
  • *
  • Posts: 31
Receiving serial string with 5DPO
« on: August 21, 2010, 11:38:29 am »
Hello,

Using 5DPO I want to receive a string which has about 120 characters but can have a variabele length. I use the 'onreceivedata' event to do this. I write the output to a memobox.
Most of the time I see the string broken up in three pieces. See below. Start of the string is always F0. End is always F7.

F07F01075072657365742031372020202020202020202
0203700370037003700370037003700370037003700370037003700370
0370037000000000025F7

What is the easiest way to make the complete string again and check if the string is completly received? I mean : how to check for the start and stop character?

Thanks in advance.




« Last Edit: August 21, 2010, 11:41:40 am by PeterH »

JohnvdWaeter

  • Full Member
  • ***
  • Posts: 185
    • http://www.jvdw.nl
Re: Receiving serial string with 5DPO
« Reply #1 on: August 21, 2010, 01:27:00 pm »
Hi,

Have a global reeivestring rx, initiate as RX:='';


OnReceive:

if length(received)<2 then exit; // loose characters

if copy(received,1,2)='F0' then RX:=Received
else if copy(received,length(received)-1,2)='F7'
       then begin
                RX:=RX+Received ;
               // RX is complete, do something with it:
                Process(RX);
                RX:='';
              end;
        else RX:=RX+Received.

Needs some further refining, but this is the idea.

hth!
John

« Last Edit: August 21, 2010, 01:34:57 pm by JohnvdWaeter »

alejol0

  • Jr. Member
  • **
  • Posts: 60
  • Electronic technician
    • My Facebook page
Re: Receiving serial string with 5DPO
« Reply #2 on: August 21, 2010, 03:25:20 pm »
Hi, PeterH.

I have worked with RS232 communications (not using Lazarus), and I think
that for your application is better that each character received generates an event.
I think that waiting for a string is a way to miss characters.

Maybe the component
you use to deal with received strings have a strange definition of what is a "string".
Or maybe the string is broken in three or four strings, the first begin with F0
and the last string containing F7.

I think that working byte-by-byte is more secure.

Work in binary form, use bytes instead of characters. Then, if a valid
array of bytes have been collected, cast the array to a string.

If you have a event triggered by each byte received, things can made more easy:
you discard all bytes until a F0 appears, then collect byte by byte until
F7 appears (with some time window or check because F7 could not to come never).

Hope this help.

-- alejandro.lavarello (at) gmail (dot) com
Contact me: lavarello1966 (at) gmail . com
or
alejandro.lavarello (at) gmail (dot) com

PeterH

  • New Member
  • *
  • Posts: 31
Re: Receiving serial string with 5DPO
« Reply #3 on: August 21, 2010, 06:06:24 pm »
Thanks for the replies.

I'm also concerned about loosing characters when handling the incoming string as a number of strings.

Are there components for Lazarus which have a 'received 1 byte / character' event?

The handling of the incoming data is way easier.
The principle is the same as buffered I/O routines for microcontrollers.

I know I a few for Delphi but these are not free and have to be ported.

Is Synaser (for instance) capable of that? I couldn't find it.



« Last Edit: August 21, 2010, 08:10:39 pm by PeterH »

alejol0

  • Jr. Member
  • **
  • Posts: 60
  • Electronic technician
    • My Facebook page
Re: Receiving serial string with 5DPO
« Reply #4 on: August 22, 2010, 03:57:21 pm »
I downloaded the 5DPO packet and have a superficial look at this.
Have encountered in synaser.pas this:

function RecvByte(timeout: integer): byte; virtual;


Maybe this can help you. Maybe setting timeout less than
2 character times can work, needs tweaking. Use low baud rates
if you can,check for communication errors.

Or maybe you can use another packet for managing serial communications. I remember that the Elektor electronics magazine have posted
in Internet a packet for managing serial port using Visual Basic,
this is a .DLL very simple (and close to hardware).

When a UART receives a byte, this set to 1 a internal bit,
if the computer is configured, a interrupt is fired.

With today operating systems is more secure to pool the bit frequently and read the byte (because interrupts are hard to manage and today PCs are very fast).

Good luck!
Contact me: lavarello1966 (at) gmail . com
or
alejandro.lavarello (at) gmail (dot) com

bobc

  • New Member
  • *
  • Posts: 41
Re: Receiving serial string with 5DPO
« Reply #5 on: August 22, 2010, 06:04:12 pm »
Getting fine level control of serial comms on modern PCs is pretty hard, because there is now so much OS in the way. Trying to read bytes one at a time will not be any more reliable than reading chunks, and generally just uses up CPU.

A ReceiveString function will never return whole packets, because it doesn't know the packet format.

I think it is best to handle the data arriving in chunks, and accept the fact that chunks will come in every combination possible, i.e. start, middle, end, plus mixed with last/next packets and also errors or other junk.

However, if you write the code with a routine called process_rx_byte, which handles bytes one at a time, identifies whole packets, and discards faulty ones, all of which you have to do anyway, then you can call the same routine from an OnCharReceived event or an OnStringReceived.

Receiving data as bytes or string is functionally equivalent.

PeterH

  • New Member
  • *
  • Posts: 31
Re: Receiving serial string with 5DPO
« Reply #6 on: August 23, 2010, 01:21:04 pm »
Thanks all for the replies.
My baudrate is 38400 which is low and will improve reliability.

I'm using this control now : http://sourceforge.net/projects/cportlaz/

This control has also an OnPackage event which is great for my application.

The Elektor lib is somethin g to keep in mind. I've worked with VB in the past and know the port can be configured to fired an interrupt everytime a byte is received.
I'm assuming it's got the same functionality.

JohnvdWaeter

  • Full Member
  • ***
  • Posts: 185
    • http://www.jvdw.nl
Re: Receiving serial string with 5DPO
« Reply #7 on: August 23, 2010, 01:38:38 pm »
38400 is low? Well, that depends. If you insist on events per char, then your application must be able to handle about 3840 events per second.... be aware that events are not the same as hardware interrupts.

AFAIK in Windows the com.drv talks to the UART. And again AFAIK, those components that provide events for serial input on a per character base simply receive strings from the com.drv and cut them to characters, thereby generating events for each character.

john

PeterH

  • New Member
  • *
  • Posts: 31
Re: Receiving serial string with 5DPO
« Reply #8 on: August 23, 2010, 09:24:50 pm »
John, you're right. I didn't think of it like that.
When writing software for microcontrollers this is never an issue.
I was thinking in the same way to write PC software assuming the speed wouldn't be a problem.....

So : a small 8 bit microcontroller clocked at 4MHz does this task beter then a Pentium 4 clocked at 2.8GHz ...  :)

JohnvdWaeter

  • Full Member
  • ***
  • Posts: 185
    • http://www.jvdw.nl
Re: Receiving serial string with 5DPO
« Reply #9 on: August 23, 2010, 10:20:18 pm »
Quote
So : a small 8 bit microcontroller clocked at 4MHz does this task beter then a Pentium 4 clocked at 2.8GHz ...

Well, this comparison isn't fair...  like bobc said: there is so much OS between the physical port and your event. + competing for cpu-time...

If you want to reduce the risc of missing packets, setup the onreceive events in a separate thread and write the accepted strings into a ring-buffer. The mainprogram now only has to act on )process) new strings in the ring-buffer.

If milliseconds-fast responses (from pc to other device) are required, I think you have to descend to as close to the hardwre you can get, e.g. write your own com.drv...

hth!
John

bobc

  • New Member
  • *
  • Posts: 41
Re: Receiving serial string with 5DPO
« Reply #10 on: August 23, 2010, 11:07:23 pm »
At work I write flash download stuff, we have a 16-bit DSP with a bootloader to receive data and program the Flash, and a PC app to read a file and send it to the DSP. I've been writing the interrupt driven code on the DSP and the PC app code, the difference in approach is quite interesting, I have to wear two completely different hats...

The funny thing is that the DSP is 80Mhz with 8KB of RAM, the PC is 3GHz with 4GB of RAM, yet nearly all the delay is in the PC side, and not the comms (38K RS232) or the Flash programming. I can minimise the delay by using 80% of the CPU, but that's not very friendly.

I could improve it more with a different comms protocol, but I can't change that.


alejol0

  • Jr. Member
  • **
  • Posts: 60
  • Electronic technician
    • My Facebook page
Re: Receiving serial string with 5DPO
« Reply #11 on: August 24, 2010, 01:16:49 am »
It was long time ago that I have used RS232.
In this site:
http://www.beyondlogic.org/
we have a complete information about dealing with serial, parallel and USG ports,
with programming examples.
Maybe this can help.
Contact me: lavarello1966 (at) gmail . com
or
alejandro.lavarello (at) gmail (dot) com

mas steindorff

  • Hero Member
  • *****
  • Posts: 553
Re: Receiving serial string with 5DPO
« Reply #12 on: August 24, 2010, 01:59:32 am »
I too agree with bobc.  I'm using 1 Mbps setting but I use serial to usb hardware on the PC end.  The drivers work best when my app uses the block read as opposed to the byte by byte approach but that is also how the hardware works (USB blocks of 400 to 500 bytes for the SiLab interface).  even a basic UART chip can buffer 15 char at a time.

I'm willing to bet the reason you see 3 lines in your memo is that you read and wrote 3 blocks in you loop. 

You will find the screen updates are where most of your CPU time is going.  I ended up using a thread to get the data from the driver (block by block), checking the new data for header info so I know where the end is, and then passing the completed packet on to the main app for display and decoding.  I used Synapse for my comm interface which works quite well for me and provides me with yet another buffer so I don't loss any bytes.  My throughput is grater than 80K bytes/second.
windows 10 &11, Ubuntu 21+ IDE 3.4 general releases

PeterH

  • New Member
  • *
  • Posts: 31
Re: Receiving serial string with 5DPO
« Reply #13 on: August 24, 2010, 10:01:54 am »
Offcourse I know the comparison between the microcontroller and PC isn't fair. It was just was comic note.
Using blockread and a seperate thread is a good solid solution. I'm going to look in to that.

 

TinyPortal © 2005-2018