Half Duplex Serial ?

1968neil

Senior Member
I currently need to interface to a TTL serial interface with a Picaxe 18M2 at 9600 baud, however the RX and TX lines of the interface are tied together.
Assuming that the method is half duplex i would need a method of interfacing.

Has anyone managed this and can advise of best practice ?
the interface accepts its commands with a Start bit two hex numbers followed by a stop bit.

Regards
Neil
 
Last edited:

inglewoodpete

Senior Member
You should be able to use a single pin on the PICAXE end of the serial link. Use the pin for both SerIn and SerOut commands.
 

geoff07

Senior Member
100 ohms in series with the pin would provide some protection against overcurrent on either side.

Make sure that the TTL signals are not greater than 0.5V above the Picaxe Vcc, preferably no greater (important if you are linking a 5v logic to a 3v logic).

Don't use pull-ups on the pin as if you do the TTL input voltage can phantom-power the Picaxe even when off. You probably had no intention to do this but it can happen and cause problems.
 

Technical

Technical Support
Staff member
A bit more info on the protocol would help - sounds a bit like modbus but that is not actually start bit -16 bits-stop bit as you describe?

You may be able to connect the one wire to two PICAXE pins if that makes life easier, one PICAXE input and one PICAXE output, but put a 10k in the PICAXE output pin line.
 

grim_reaper

Senior Member
...the interface accepts its commands with a Start bit two hex numbers followed by a stop bit.
Neil,

As Technical said, more detail would be good. It depends on what you mean by two hex numbers? A pair of hex digits - e.g. FF - would be 8 bits, or a pair of bytes - e.g. FF FF - would be 16 bit.
I'd have to disagree with the similarity to Modbus though! RTU has a 28 bit start, address and function code, then the data (of variable length) and the ASCII standard is 8 bit start, 16 bit address, 16 bit function code, data, LRC THEN the 16 bit end - so definitely not as simple as this one!

What's the thing you're trying to talk to anyway?
 

1968neil

Senior Member
"The commands issued were in hex format:-

x06 is start command
x32, x32 is hex code for ASCII characters '2','2'. that requests RSSI level.
xFE is end of command"

The setup is 9600 baud 8,n,1 (8bits, No Parity, 1 Stop Bit - No inversion)

above is a direct quote from the manufacturer of the equipment i'm trying to interface, unfortunately can't divulge the equipment type at present.

the programming lead for the equipment has a level shifter in the D9 type Rs232 plug for PC interface.
 

Goeytex

Senior Member
If the receiver takes more than about 100 us to respond after the $FE (End of command) then you should be able to use a single Picaxe Pin for both serout and serin. I would place a 4K7 series resistor in the data line to limit the current to about 1 ma, just in case both transmit at the same time. Any value from about 1K to 10K should work OK.

Code:
[color=Navy]#picaxe [/color][color=Black]18M2[/color]
[color=Navy]#no_data
#terminal 19200[/color]
[color=Blue]setfreq M16   [/color][color=Green]'// 16 MHz Needed for reliable serin @9600 baud  [/color]
[color=Blue]pause [/color][color=Navy]2000    [/color][color=Green]'// Stabilize, Give terminal time to open[/color]

[color=Blue]do
      serout b.6[/color][color=Black], [/color][color=Blue]T9600_16[/color][color=Black], [/color][color=Blue]([/color][color=Navy]$06[/color][color=Black],[/color][color=Navy]$32[/color][color=Black],[/color][color=Navy]$32[/color][color=Black],[/color][color=Navy]$FE[/color][color=Blue])   [/color][color=Green]'//  Request RSSI data
      [/color][color=Blue]serin b.6[/color][color=Black], [/color][color=Blue]T9600_16[/color][color=Black], [/color][color=Purple]b0[/color][color=Black],[/color][color=Purple]b1[/color][color=Black],[/color][color=Purple]b2[/color][color=Black],[/color][color=Purple]b3          [/color][color=Green]'//  Changes pin to input, wait for serial data  
                                                '//  Use number of variables as needed  

      [/color][color=Blue]sertxd ([/color][color=Red]"Data: "[/color][color=Black],#[/color][color=Purple]b0[/color][color=Black],[/color][color=Red]" "[/color][color=Black],#[/color][color=Purple]b1[/color][color=Black],[/color][color=Red]" "[/color][color=Black],#[/color][color=Purple]b2[/color][color=Black],[/color][color=Red]" "[/color][color=Black],#[/color][color=Purple]b3[/color][color=Black],[/color][color=Red]"   "[/color][color=Blue])  [/color][color=Green]'// Display data 4 bytes in terminal.  
      [/color][color=Blue]pause [/color][color=Navy]4000  [/color][color=Green]'// About 1 sec @ 16Mhz[/color]
[color=Blue]loop[/color]
 

1968neil

Senior Member
Thanks for all the suggestions, think i have some good info to work with now, will let you know how i get on.

Will try your code suggestion Geoytex
Many Thanks

Neil
 
Last edited:

1968neil

Senior Member
Managed to get it working thanks to Geoytex's code, one question tho'

I send the data in hex and the returned code is also received in hex, how to i display this ? the values that are put into the variables are decimal and i'll need to convert to hex to make sense of it.

Regards
Neil
 

hippy

Technical Support
Staff member
Hex, decimal and binary are simply different ways of visualising the same value so you need to explain what you mean or require.
 

1968neil

Senior Member
Using RealTerm (terminal program) if i send $06,$32,$32,$FE it returns the following.
I need some way of displaying exactly that, my test code is as Code in Geoytex's post above.


06 32 32 FE 06 46 46 FE 06 32 32 30 34 FE
 

Goeytex

Senior Member
All data is sent as binary. Hex, decimal, ascii are simply ways it displaying the data. Here is a snippet that will do what you need, I think this came from hippy but I may have modified it. I use this same DEC2HEX subroutine in most of my advanced RF applications where I need to display data as hex.

Code:
[color=Blue]symbol [/color][color=Purple]data_val [/color][color=DarkCyan]= [/color][color=Purple]B9[/color]
[color=Blue]Symbol [/color][color=Purple]chr1 [/color][color=DarkCyan]= [/color][color=Purple]b10[/color]
[color=Blue]Symbol [/color][color=Purple]chr2 [/color][color=DarkCyan]= [/color][color=Purple]b11
 
 
 [/color][color=Black]Main:
 
 [/color][color=Blue]for [/color][color=Purple]data_val [/color][color=DarkCyan]= [/color][color=Navy]25  [/color][color=Blue]to [/color][color=Navy]35 [/color][color=Green]' decimal valuse
      [/color][color=Blue]gosub [/color][color=Black]dec2hex
      [/color][color=Blue]sertxd ([/color][color=Red]"$"[/color][color=Black],[/color][color=Purple]chr1[/color][color=Black],[/color][color=Purple]Chr2[/color][color=Black],[/color][color=Red]" "[/color][color=Blue])
 next
 sertxd (cr[/color][color=Black],[/color][color=Blue]lf)
 pause [/color][color=Navy]1000
 [/color][color=Blue]goto [/color][color=Black]main
 
  
 DEC2HEX:[/color]
[color=Gray]{[/color]
[color=Green]'Hex Display Routine
[/color]
[color=Purple]chr1 [/color][color=DarkCyan]= [/color][color=Purple]data_val [/color][color=DarkCyan]/ [/color][color=Navy]$10 [/color][color=DarkCyan]+ [/color][color=Red]"0"[/color]
[color=Blue]If [/color][color=Purple]chr1 [/color][color=DarkCyan]> [/color][color=Red]"9" [/color][color=Blue]then [/color][color=Black]: [/color][color=Purple]chr1 [/color][color=DarkCyan]= [/color][color=Purple]chr1 [/color][color=DarkCyan]+ [/color][color=Navy]7 [/color][color=Black]: [/color][color=Blue]End If[/color]
[color=Purple]chr2 [/color][color=DarkCyan]= [/color][color=Purple]data_val [/color][color=DarkCyan]& [/color][color=Navy]$0F [/color][color=DarkCyan]+ [/color][color=Red]"0"[/color]
[color=Blue]If [/color][color=Purple]chr2 [/color][color=DarkCyan]> [/color][color=Red]"9" [/color][color=Blue]then [/color][color=Black]: [/color][color=Purple]chr2 [/color][color=DarkCyan]= [/color][color=Purple]chr2 [/color][color=DarkCyan]+ [/color][color=Navy]7 [/color][color=Black]: [/color][color=Blue]End If
return[/color]
[color=Gray]} [/color]
 
Last edited:

Goeytex

Senior Member
Here is a more complete example assuming 14 bytes to be received. Modify as necessary.

Code:
[color=Navy]#picaxe [/color][color=Black]18M2[/color]
[color=Navy]#no_data
#terminal 19200[/color]
[color=Blue]setfreq M16   [/color][color=Green]'// 16 MHz Needed for reliable serin @9600 baud  [/color]
[color=Blue]pause [/color][color=Navy]2000    [/color][color=Green]'// Stabilize, Give terminal time to open[/color]

[color=Blue]symbol [/color][color=Purple]data_val [/color][color=DarkCyan]= [/color][color=Purple]B24[/color]
[color=Blue]Symbol [/color][color=Purple]chr1 [/color][color=DarkCyan]= [/color][color=Purple]b25[/color]
[color=Blue]symbol [/color][color=Purple]chr2 [/color][color=DarkCyan]= [/color][color=Purple]b26[/color]
[color=Blue]symbol [/color][color=Purple]ram_location [/color][color=DarkCyan]= [/color][color=Purple]b27 [/color][color=Green]'// last "B" variable with M2 chips  
 
'// b0 to B23 are free to use[/color]


[color=Black]MAIN:[/color]
[color=Blue]do
      serout b.6[/color][color=Black], [/color][color=Blue]T9600_16[/color][color=Black], [/color][color=Blue]([/color][color=Navy]$06[/color][color=Black],[/color][color=Navy]$32[/color][color=Black],[/color][color=Navy]$32[/color][color=Black],[/color][color=Navy]$FE[/color][color=Blue])   [/color][color=Green]'//  Request RSSI data
      [/color][color=Blue]serin b.6[/color][color=Black], [/color][color=Blue]T9600_16[/color][color=Black], [/color][color=Purple]b0[/color][color=Black],[/color][color=Purple]b1[/color][color=Black],[/color][color=Purple]b2[/color][color=Black],[/color][color=Purple]b3[/color][color=Black],[/color][color=Purple]b4[/color][color=Black],[/color][color=Purple]b5[/color][color=Black],[/color][color=Purple]b6[/color][color=Black],[/color][color=Purple]b7[/color][color=Black],[/color][color=Purple]b8[/color][color=Black],[/color][color=Purple]b9[/color][color=Black],[/color][color=Purple]b10[/color][color=Black],[/color][color=Purple]b11[/color][color=Black],[/color][color=Purple]b12[/color][color=Black],[/color][color=Purple]b13  [/color][color=Green]'// 14 bytes expected
      [/color][color=Blue]gosub [/color][color=Black]Display_Data
      [/color][color=Blue]pause [/color][color=Navy]4000     [/color]
[color=Blue]loop
 
 
 [/color][color=Black]Display_Data:
 [/color][color=Gray]{ 
 [/color][color=Green]'Display Routine
 [/color][color=Blue]sertxd (cr[/color][color=Black],[/color][color=Blue]lf) [/color][color=Green]'// newline for simulator  
 [/color][color=Blue]for [/color][color=Purple]ram_location [/color][color=DarkCyan]= [/color][color=Navy]0 [/color][color=Blue]to [/color][color=Navy]13       [/color][color=Green]'// This is where b0 - b13 reside in Ram
       [/color][color=Blue]peek [/color][color=Purple]ram_location[/color][color=Black],[/color][color=Purple]data_val
       [/color][color=Blue]gosub [/color][color=Black]dec2hex
       
       [/color][color=Blue]sertxd ([/color][color=Red]"$"[/color][color=Black],[/color][color=Purple]chr1[/color][color=Black],[/color][color=Purple]Chr2[/color][color=Black],[/color][color=Red]" "[/color][color=Blue]) [/color][color=Green]'// Remove the $ if you don't want it displyed
 [/color][color=Blue]next
 sertxd (cr[/color][color=Black],[/color][color=Blue]lf)
 pause [/color][color=Navy]1000
 [/color][color=Blue]return
 [/color][color=Gray]}
  
 [/color][color=Black]DEC2HEX:[/color]
[color=Gray]{[/color]
[color=Green]'Hex Display Routine
'Necessary for any sub that begins with "display"[/color]
[color=Purple]chr1 [/color][color=DarkCyan]= [/color][color=Purple]data_val [/color][color=DarkCyan]/ [/color][color=Navy]$10 [/color][color=DarkCyan]+ [/color][color=Red]"0"[/color]
[color=Blue]If [/color][color=Purple]chr1 [/color][color=DarkCyan]> [/color][color=Red]"9" [/color][color=Blue]then [/color][color=Black]: [/color][color=Purple]chr1 [/color][color=DarkCyan]= [/color][color=Purple]chr1 [/color][color=DarkCyan]+ [/color][color=Navy]7 [/color][color=Black]: [/color][color=Blue]End If[/color]
[color=Purple]chr2 [/color][color=DarkCyan]= [/color][color=Purple]data_val [/color][color=DarkCyan]& [/color][color=Navy]$0F [/color][color=DarkCyan]+ [/color][color=Red]"0"[/color]
[color=Blue]If [/color][color=Purple]chr2 [/color][color=DarkCyan]> [/color][color=Red]"9" [/color][color=Blue]then [/color][color=Black]: [/color][color=Purple]chr2 [/color][color=DarkCyan]= [/color][color=Purple]chr2 [/color][color=DarkCyan]+ [/color][color=Navy]7 [/color][color=Black]: [/color][color=Blue]End If
return[/color]
[color=Gray]} [/color]
 

AllyCat

Senior Member
Hi,

This is the code I recently wrote to do much the same thing. A single subroutine with multiple entry points for a single-Nybble or a full Byte and optionally inserting a space (which could also be the $ symbol if/when required) between each character pair. Maybe I'll also add the option to show the byte @BPTRINC :

Code:
showByt2Hex:
	sertxd(" ")				; Could also insert a $ here 
showByt2ascii:  				; Enter with a Byte in w1 or b2 (b3 is also used)
	b3 = b2 and 15
	b2 = b2 / 16
	call showNyb2ascii
	b2 = b3					; Fall into nybble subroutine
showNyb2ascii:					; Enter with a Nybble in w1 or b2 (b3 not required)
	b2 = b2 / 10 * 7 + b2 + 48
	sertxd(b2)				; Show the nybble(s) as Hex character(s)
	return
Only about 30 bytes of code and two byte variables required.

Cheers, Alan.
 
Top