How many bytes can hserin on 20x2 read?

Pongo

Senior Member
Is there a limit to the number of bytes that hserin can read at one time using a 20x2?

I have a system that sends an 82 byte string @ 9600 baud. It was set up to send to a BS2 and so transmits fairly slowly with 20 milliseconds between bytes. A 20x2 reads the data fine up to about 55 bytes, but it either ignores or garbles anything further. Test code below, what am I doing wrong?

Code:
#picaxe 20X2
#No_Table
#No_Data
#Terminal 9600

hsersetup b9600_8, %00

main:

hserin [10000,whoops],0,65,("W")
       for ptr = 0 to 65
         sertxd(@ptr)
       next
         sertxd(CR, LF)
pause 100

goto main

whoops:
 sertxd("whoops") 
 sertxd(CR, LF)
pause 200

goto main
 

DirtBiker

New Member
I always assumed it could read up to 128 characters, although to be honest I have never tried that many. Perhaps there is a small timing error that begins to cause framing errors after 55 bytes. Maybe you could try to calibrate the internal clock.
 

Pongo

Senior Member
Thanks for the suggestion. Adjusting the clock I can get to around 70 bytes, but with errors in the data, with the unadjusted clock the number of bytes is limited but the data is solid. I also tried clocking at M16 and M32 without significant improvement.
 

g6ejd

Senior Member
The fifo has space for two characters, so if your getting data drop out, then your spending too long in your programme before the next HERSIN.

When you switched to M32 did you use 9600_32 instead of 9600_8 ?
 

Pongo

Senior Member
The fifo has space for two characters, so if your getting data drop out, then your spending too long in your programme before the next HERSIN.
Sorry, I don't understand, could you explain that? Doesn't hserin discard chars until it sees the next qualifier?

When you switched to M32 did you use 9600_32 instead of 9600_8 ?
Oh yes, m32 + 9600_8 = garbage. (I appropriately changed the terminal command too.)

-.-
 

Pongo

Senior Member
FWIW I can reliably receive all 82 bytes using M32, serin, and reading/putting the data into the scratchpad byte by byte.

Code:
#picaxe 20x2
 #no_table
 #terminal 38400
 symbol num = b55
 setfreq m32
 pause 1000

main:
 
getit: 
b0 = "Z"
serin [28000],b.4,T9600_32,("WX"),b0
if b0 = "Z" then
goto timeout  
end if

for num = 0 to 79
serin b.4,T9600_32,b0
put num,b0
next

for ptr = 0 to 80
	sertxd(@ptr)
next
	sertxd(CR, LF)

pause 300
goto getit

timeout:
sertxd ("timeout",cr,lf)
pause 100
goto getit
 

Goeytex

Senior Member
I hooked up an 08M2 to a 20X2 and sent 100 bytes from the 08m2. The 20X2 receives all 100 bytes perfectly. The 20X2 code is identical to yours, except for Hserin looks for 100 bytes and I am using sertxd (#@ptr) instead of sertxd @ptr so that all bytes are displayed.

My guess is that the timing between the sending device and the BASIC Code is off. Could be that the sending device starts sending data while the basic code has just timed out.

I cannot imagine that the frame rate ( baud rate?) of the sending device is that far off. The accuracy of the Picaxe hserin command is excellent, being very tolerant of high and low baud rates. However, if you have a scope it may be a good idea to look at the baud rate of the sending device.

Below is the code I used for the 08M2 as the sending device

Code:
'===================================
#Picaxe 08M2
#No_Data
Setfreq M8
Pause 100
'=====================================
high C.1

pause 5000

do 

serout C.1,T9600_8,("W") ' send qualifier

for b0 = 1 to 100
  serout C.1,T9600_8,(b0) 'Send 100 bytes 
  pause 20
next

pause 2000   'Wait for 20X2 to complete before sending next packet 
loop
 

Pongo

Senior Member
I don't think the baud rate is inaccurate, otherwise I would see more garbles in the data and in my testing I only saw garbling when trimming the clock frequency. The data received is good, it just seems to choke after 50 or so characters.

As to the "sending device starts sending data while the basic code has just timed out", sure, there are timeouts, but it just waits around until it sees the qualifier again - doesn't it?

I'll certainly try the test you suggest and report back.

I did see an old thread of yours discussing inaccuracy of the 20x2 baud rate and wondered if that might be the cause, but based on your comments I guess that is all resolved now?
 

inglewoodpete

Senior Member
I have used hSerial on a 20X2 to receive up to about 40 bytes at 115200 baud with the PICAXE running at 64MHz. The code is documented here. Admittedly, the serial data was being transmitted by another 20X2, so the speed match should have been good. 9600 baud should be a doddle.

I notice that you're using a SerTxd command. You can't use SerTxd during hSerial reception. The SerTxd is a bit-banged output so, during transmission, kills off the hSerial port interrupts, resulting in lost data.

Edit: I've just noticed that you're using foreground hSerial reception, so my comments above are not that relevant. I always use background hSerial, to ensure that no data is lost due to the code execution being somewhere else when data arrives.
 

Pongo

Senior Member
Edit: I've just noticed that you're using foreground hSerial reception, so my comments above are not that relevant. I always use background hSerial, to ensure that no data is lost due to the code execution being somewhere else when data arrives.
The frequency of data packet transmission is somewhat variable since the PC may have other things on its mind, and the picaxe will spend time handling the received data before it's ready for more, so I decided to have the receiver just loop waiting until it catches the qualifier at the start of a packet. I'm not worried about losing packets, they are sent redundantly and it's only driving a max7219 display.

I looked at background hserial but it doesn't appear to take a qualifier, but maybe I'm wrong.

Since my slower(?) executing serin solution works I'm wondering if it's the intercharacter delay that's causing a problem.
 

Goeytex

Senior Member
I did see an old thread of yours discussing inaccuracy of the 20x2 baud ...
That only applied to software serout /serin and only at particular settings. Hserin has no problems that I am aware of. I use it quite a bit at up to 115K baud with no issues.

Whats up with the qualifier ? Why do you need one ? Perhaps if you explain what the sent data packet actually contains ,ie where the qualifier is located in the packet ....etc ... Are you picking 65 bytes starting after a "W" from a larger stream of data ?

I can tell you that there is nothing wrong with your code or with hserin on the 20X2. There is either something wrong with the hardware, board layout, grounding, etc, or there is something wrong with the quality of the data being sent. There is a remote possibility that you have a duff 20X2. Do you have a scope or a logic analyzer ?

I looked at background hserial but it doesn't appear to take a qualifier, but maybe I'm wrong.
While background hserial does not have a qualifier, there are certainly ways to qualify the received data.
 

Pongo

Senior Member
I can tell you that there is nothing wrong with your code or with hserin on the 20X2.
I agree completely, I did a similar test to yours and had no problem getting >80 bytes.

There is either something wrong with the hardware, board layout, grounding, etc, or there is something wrong with the quality of the data being sent. There is a remote possibility that you have a duff 20X2. Do you have a scope or a logic analyzer ?
I think it has to be a data/timing issue, anything else and I doubt it would be receiving 50 bytes correctly. For some reason only the picaxe hserin cares about it, my serin code is rock solid, as is a bs2. Yes, I do have a scope, not a digital/storage though so it's of limited use for this.

Whats up with the qualifier ? Why do you need one ? Perhaps if you explain what the sent data packet actually contains ,ie where the qualifier is located in the packet ....etc ... Are you picking 65 bytes starting after a "W" from a larger stream of data ?
The packet has a three byte preamble "WXD" (multi byte qualifier for a bs2) followed by 80 bytes of data and validation. Since I can't guarantee that the receiving end is going to be listening when the PC starts sending a packet I decided to just keep banging the packets out each few seconds and use the qualifier to pick up the start of the next packet. It's worked fine for quite a while with the bs2 and I would prefer not to change the system, just be able to use a 20x2 instead.
 

Technical

Technical Support
Staff member
starts sending a packet I decided to just keep banging the packets out each few seconds and use the qualifier to pick up the start of the next packet.
How do you know the data doesn't contain a 'W' and hence sync is starting in the wrong place?
 

Goeytex

Senior Member
Technical beat me to it. For example if there is a "W" 20 bytes deep into the data packet and the timing is off, then it what might happen?

Why not use background hserial with the hserial interrupt set. Receive the entire packet into the scratchpad. Then look for the WXD sequence at the beginning of the scratchpad and process the bytes that follow. The following code shows how it can be done.

Code:
'===================================
#Picaxe 20X2
#No_Data
#No_Table
Setfreq M8
Pause 100
'=====================================

hsersetup b9600_8,%001
setintflags %00100000,%00100000
pause 1000

main:

   Do 
   pause 1000   'waiting for hser interrupt
   loop
     
interrupt:   
   sertxd ("Interrupt",cr,lf)   ' For debugging
    pause 2500         'Allow entire packet to be received
     ptr = 0             ' Set SP pointer to zero 
     
     if @ptrinc = "W" and @ptrinc = "X" and @ptr = "D" then
      
        for ptr = 3 to 101
          sertxd (#@ptr,cr,lf)
        next
      
     else
       sertxd ("Packet does not start with 'WXD'",cr,lf)
     endif
       
       ptr = 0
       hserptr = 0  'Reset hserial pointer 
       flags = 0    'clear the flags byte
       setintflags %00100000,%00100000  'enable the interrupt
       
   Return
 

Pongo

Senior Member
Technical beat me to it. For example if there is a "W" 20 bytes deep into the data packet and the timing is off, then it what might happen?
That's covered two ways, a) by design the packet only contains delimited numerics after the qualifier, and b) if the receiver misreads a byte as a "W" and grabs a malformed packet the validation step will fail and it will loop back to listening for the next "W". The packets are sent redundantly so missing some is not an issue. (The qualifier is really "WXD" which is more robust than a single character but as we know picaxe hserin doesn't support that.)

Why not use background hserial with the hserial interrupt set. Receive the entire packet into the scratchpad. Then look for the WXD sequence at the beginning of the scratchpad and process the bytes that follow. The following code shows how it can be done.
I will certainly take a close look at this method later and reply.
 

Pongo

Senior Member
Why not use background hserial with the hserial interrupt set. Receive the entire packet into the scratchpad. Then look for the WXD sequence at the beginning of the scratchpad and process the bytes that follow. The following code shows how it can be done.
Thank you very much for all your help and that example code. I made a test and (of course) it works very well. Now I need to hit the books and understand exactly what it is doing...
 
Top