HSERIN/HSEROUT & HSERPTR - The Basics

mortifyu

New Member
Hello resident PICAXE experts,


I seem to be misunderstanding the operations of HSERSETUP and associated commands. I thought I understood it, but I must be wrong. Only problem is, the below code all seems to function fine in the editor's simulator, but in circuit it fails.

Two identical circuits for testing (See attached PDF)


Confirmation of several things from initial power up...

1. If unit1 is triggered and transmits a 1, unit2 happily replies with a 2. They both return to the start of the program and happily run the LED sequencer until the loop finishes. Happy days! This can be done over and over flawlessly.

2. If I now trigger unit2 to transmit a 1, it does, but unit1 fails to reply with a 2 as it should, therefore unit2 now retries over and over. <---- Here is the problem!

3. The RF transceivers have been removed from circuit. Linking HSERIN-HSEROUT of the two chips = same result. (I initially suspected a transceiver issue, but clearly it's my coding.)

4. What appears to be happening is that once a unit has been the triggered transmitter, it's HSERINFLAG is not being flagged when serial data is received. It does not even leave the main: loop.



From what I currently understand, the scratchpad pointer points to 0 address when the HSERSETUP command is executed.

When I make one unit transmit a 1, the second unit receives the 1 and puts it in scratchpad address 0 and now the receiving unit's pointer automatically shifts to scratchpad address 1.

So because I am only using 1 byte in this test, I receive the byte into scratchpad address 0, read the byte into variable b1 (get 0,b1), then reset the pointer back to scratchpad address 0 (hserptr=0) and reset the Hserinflag also to 0 (hserinflag=0), making things again ready to receive a serial transmission into address 0.





Please help me to clearly understand. What am I doing wrong experts???


Code:
'Hardware Serial RF link Test
'Using only 1 Byte Background serial receive

'PICAXE 20X2

'C.0 - HSEROUT
'B.6 - HSERIN

'B.0 - LED 1
'B.1 - LED 2

'C.1 - Trigger input - 1=TRIGGERED

'C.7 - Busy signal from transceiver - 0=BUSY, 1=READY

'Variables
'B1 - Transmission Trigger & Acknowledge - 1-Trigger, 2-Acknowledge
'B2 - Flashing LED Sequence ACTIVE/INACTIVE - 1-ACTIVE, 0-INACTIVE
'W3 & W4 - Calculus for LED sequencing





init:
setfreq m16
hsersetup B9600_16, %00001
input c.7

main:
if b2=0 and pinc.1=1 then pause 600 gosub transmit endif

If HSerInFlag = 1 then gosub rx

if b2=1 then gosub operation

goto main



transmit:
let b1=1
hserout 0,(b1)			'Send Trigger message. (A number 1)
waiting:
if pinc.7=0 then goto waiting
hserin [5000],0,1			'Allow plenty of time for receiving node to transmit back a confirmation. (A number 2)
get 0,b1
if b1=2 then goto received 
goto transmit			'If confirmation not received... Resend!

received:
let b1=0
let b2=1
hserptr=0				'Reset scratchpad pointer to 0
hserinflag=0			'Reset Serial data received flag to 0
return


rx:
get 0,b1
if b1=1 then goto rxed
hserptr=0				'Reset scratchpad pointer to 0
hserinflag=0			'Reset Serial data received flag to 0
let b1=0
return

rxed:
let b1=2
hserout 0,(b1)
let b1=0
let b2=1
hserptr=0				'Reset scratchpad pointer to 0
hserinflag=0			'Reset Serial data received flag to 0
return



operation:
let w3=w3+1
if w3=160 then let w3=0 let w4=w4+1 endif
if w4=20 then goto operationcomplete
if w3<20 then high b.0 low b.1 return endif
if w3>=20 and w3<40 then low b.0 low b.1 return endif
if w3>=40 and w3<80 then high b.0 low b.1 return endif
if w3>=80 and w3<100 then low b.0 high b.1 return endif
if w3>=100 and w3<120 then low b.0 low b.1 return endif
if w3>=120 and w3<160 then low b.0 high b.1 return endif


operationcomplete:
low b.0
low b.1
let w3=0
let w4=0
let b2=0
hserptr=0				'Reset scratchpad pointer to 0
hserinflag=0			'Reset Serial data received flag to 0
return
View attachment PICAXE Hardware Serial Testing RF link.pdf

Regards,
Morty.
 

inglewoodpete

Senior Member
Having two ends of a serial link controlled by microcontrollers (of any sort) can be challenging.

In this instance, debugging should not to be too difficult because you are not sending more than one character at a time. I suggest you add some SerTxd commands to your receiver to help you find out what is happening in (close-to) real time. Note that the SerTxd command blocks system interrupts while bit-banging the time-critical output text so cannot be used during background reception of longer strings of characters on the hSerIn pin.

Alternatively, add a couple more LEDs with current limiting resistors on spare pins for the duration of testing so that you can determine what is actually happening. After initialising the diagnostic LED pin as an output, you can equate the output level to the value of a 1-bit variable. As an example, to visualise the hserinflag, use something like the following command:
Rich (BB code):
outpinB.5 = hserinflag
 

mortifyu

New Member
Hi Pete,

Thanks for the advice.

Before posting this question I actually did ALL of the things you suggest. I came to the conclusion noted in comment 4. because I actually did put in a SerTxd line in like this...

Code:
If HSerInFlag = 1 then sertxd("Serial Data RECEIVED") gosub rx endif
Once a unit has initially been a triggered transmitter, it fails to gosub rx. This is what leads me to believe the HSerInFlag is not being triggered for some reason.



Regards,
Morty.
 

inglewoodpete

Senior Member
I just had a closer look at your code. Two things are evident.
1. You are trying to use two different modes of receive. If you use background receive into the scratchpad, the data is placed into the scratchpad and the two flags/pointers are updated. You do not use the hSerIn command, which holds up processing. You just test the flag and act accordingly.
2. What happens if you do not receive a 2? You have received data but not reset the variables, pointer etc. In a directly connected system, your data should be fairly reliable but when you get to use the radio link, data will be easily corrupted.

Rich (BB code):
transmit:
let b1=1
hserout 0,(b1)       'Send Trigger message. (A number 1)
waiting:
if pinc.7=0 then goto waiting
hserin [5000],0,1       'Allow plenty of time for receiving node to transmit back a confirmation. (A number 2)
get 0,b1
if b1=2 then goto received 
goto transmit        'If confirmation not received... Resend!

received:
let b1=0
let b2=1
hserptr=0            'Reset scratchpad pointer to 0
hserinflag=0         'Reset Serial data received flag to 0
return
 

mortifyu

New Member
Pete... You son are GOLD!

Using two different modes of serial reception in this instance is obviously a problem. This issue has been solved by changing the coding to this...

Not sure how long I need to allow for the return confirmation so for now just set it to loop 64000 times. Works perfectly now.

Code:
transmit:
let b1=1
hserout 0,(b1)			'Send Trigger message. (A number 1)
waiting:
if pinc.7=0 then goto waiting

if w5=64000 then return endif
if HSerInFlag=0 then let w5=w5+1 goto waiting endif
;hserin [5000],0,1			'Allow plenty of time for receiving node to transmit back a confirmation. (A number 2)
get 0,b1
if b1=2 then goto received 
goto transmit			'If confirmation not received... Resend!


Thank you so very much mate. I don't come here much, but boy when I do, the brains come a flyin'.



Regards,
Morty.
 
Top