Cannot get RS485 to work
heliboy
Posts: 18
- Hello All:
- I am new to Propeller and I have used if successfully to build a serial-to-VGA converter. My latest project involves operating a number of Dynamixel servos from the propeller. I chose the Dynamixels because they advertised an object in the prop library. Unfortunatly the object library only supports their AX series while I purchased the RX which communicates over RS485. For the life of me I cannot get·my 485 converter to work from the propeller. I am using a MAX3430 and FullDuplex serial. I have P1 to DI, P2 to RO, and P0 to the Talk/listen pins. No matter what I do, I get byte 00 on the receive even if the A,B lines are disconnected. I have no trouble with a PIC using the max3430 and am now at the frustration stage where I wish I had used the·PIC to begin with.
Any help appreciated.
Comments
Leon
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Amateur radio callsign: G1HSM
My test program is messy but it basically sends a command to turn the Dynamixel LED on and off periodically. I can read the Dynamixel response and it is correct. With the 3430 I get not LEDresponse and the Dynamixel response is all $FF ...
In the hope that someone will point out an obvious stupidity .. here is the code:
CON
· _clkmode····· = xtal1 + pll16x
· _xinfreq····· = 5_000_000
· DelayMs······ = 2000
· TXPin········ = 1
· RXPin········ = 2
· DirPin······· = 0
· LEDpin······· = 16
· MaxRespStr··· = 20
OBJ
· ser·· :······ "Parallax Serial Terminal"
· ser2· :······ "FullDuplexSerial"··
VAR
· byte INchar
· Byte RESPStr[noparse][[/noparse]MaxRespStr]
· byte LEDOn
PUB begin | i,j
· waitcnt(clkfreq*2 +cnt)·
· HIGH(DIRPin)
· HIGH(LEDPin)
· ser2.start(RXPin, TXPin, %0011, 57_600)
· ser.start(115200)
· ser.Str(String("Dynamixel TEST..."))····
· waitcnt(clkfreq*2 +cnt)
· repeat
··· HIGH(LEDPIn)
··· ser2.RxFlush
··· ser.str(String("Sending.."))
··· HIGH(DIRPin)
'··· waitcnt(clkfreq/10+cnt)
··· LED(LEDOn)
··· LOW(DIRPin)
··· LOW(LEDPin)
··· INchar := ser2.rxtime(100)
··· ser.str(String("RCX.."))·
····· if InChar > -1
······· i:=0
······· repeat 10
·········· ser.hex(Inchar,2)
·········· InChar:=ser2.rxtime(100)
·········· i:=1+1
··· waitcnt(clkfreq/1000*DelaymS +cnt)
··· !LEDOn
PUB LED(on)
· If on
··· ser2.tx($FF)
··· ser2.tx($FF)
··· ser2.tx($01)
··· ser2.tx($04)
··· ser2.tx($03)
··· ser2.tx($19)
··· ser2.tx($01)
··· ser2.tx($DD)·
· Else
··· ser2.tx($FF)
··· ser2.tx($FF)
··· ser2.tx($01)
··· ser2.tx($04)
··· ser2.tx($03)
··· ser2.tx($19)
··· ser2.tx($00)
··· ser2.tx($DE)·
·
PUB HIGH(Pin)
··· dira[noparse][[/noparse]Pin]~~
··· outa[noparse][[/noparse]Pin]~~
········
PUB LOW(Pin)
··· dira[noparse][[/noparse]Pin]~~
··· outa[noparse][[/noparse]Pin]~
You have to enable the TE of the RS485 chip before you send and then you only want to turn it back off again after the transmit buffer is empty or a suitable delay. The way you have it there is a timing problem as the the string will start transmitting while the RS485 TE is off.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
*Peter*
Thanks to all.
MAX3430<Prop. The prop was displaying fine what it was receiving from the MAC, however, the MAC was showing that there was an error reading in the response, but it was getting in a partial response.
I remembered what you said about the delay, and now I see the issue. When you launch the serial object in another cog, that cog is operating on it's own when you send if commands to TX something. So when you say ser.str("long string here"), and immediately tell the enable to go back to LOW, the enable is going LOW before the other cog is finished sending the string. So, you set a delay after the TX and wait until there is sufficient time for the serial object to complete sending the string, then turn off the enable pin.
I have had this RS485 on these boards for a year and have never tested it till today. I don't know why this is but for some reason it is still exciting to get some new process working for the first time.