data in one serial port and out another serial port
Evil Sibling
Posts: 7
Hi there people,
I've configured 2 Full Duplex Serial ports on the Propeller, both running at 9600bps. One port is the host port (pins 30 and 31), the other port is on pins 0, and 1.
One serial port is connected to a PC, the other serial port is connected to serial port on another device.
What I'm trying to do is have the Propeller act as like a hub between the PC and the other device so that serial data coming in from the PC on the host port is sent out the other serial port, and serial data coming in from the other device on the other serial port is sent out the host port to the PC.
The way Im trying to do it is to start the serial ports in the main cog, and then have have 2 more cogs dedicated to watching for inbound data on either of the ports
OBJ
mSerial : "FullDuplexSerial"
sSerial : "FullDuplexSerial"
PUB main
mSerial.start(31, 30, 00, 9600)
sSerial.start(1, 0, 00, 9600)
cognew(masterport, @mastercog)
cognew(slaveport, @slavecog)
PUB mastercog
repeat
PUB slavecog
repeat
I dont seem to be getting any data being transferred between the ports. Any idea what I might be doing wrong? Is it even possible to do this?
I've configured 2 Full Duplex Serial ports on the Propeller, both running at 9600bps. One port is the host port (pins 30 and 31), the other port is on pins 0, and 1.
One serial port is connected to a PC, the other serial port is connected to serial port on another device.
What I'm trying to do is have the Propeller act as like a hub between the PC and the other device so that serial data coming in from the PC on the host port is sent out the other serial port, and serial data coming in from the other device on the other serial port is sent out the host port to the PC.
The way Im trying to do it is to start the serial ports in the main cog, and then have have 2 more cogs dedicated to watching for inbound data on either of the ports
OBJ
mSerial : "FullDuplexSerial"
sSerial : "FullDuplexSerial"
PUB main
mSerial.start(31, 30, 00, 9600)
sSerial.start(1, 0, 00, 9600)
cognew(masterport, @mastercog)
cognew(slaveport, @slavecog)
PUB mastercog
repeat
sSerial.tx(mSerial.rx)
PUB slavecog
repeat
mSerial.tx(sSerial.rx)
I dont seem to be getting any data being transferred between the ports. Any idea what I might be doing wrong? Is it even possible to do this?
Comments
Welcome to the forum, btw you could have posted this in the Propeller 1 forum instead however the cognew statement is being used incorrectly, it can either call assembler code with the @ symbol or Spin code where you need to specify a stack space. This is the format from the Propeller Manual:
COGNEW (SpinMethod (ParameterList) , StackPointer )
So you would declare say 32 longs perhaps for a stack, here is an example from the manual: [/FONT]
Hi Peter,
Thanks for your reply. My mistake, I typed from memory rather than copying and pasting the code. I have the newcog() routine correct as you describe in the actual code and I've declared 32 longs of stack space per cog.
So based on that do you believe theres no reason why I shouldnt be able to move data between the two serial ports using Full Duplex Serial?
Code posted on the forums looks better if you put it between [ code ] and [ /code ] tags but without the spaces between the []'s.
Looks like this:
However, I must say that of all the people I have seen who have posted code without code blocks, you formatted yours the best.
Actually two cogs, one running the repeat loop and the spin methods from fullDuplexSerial4port, and the other running the pasm component of fullDuplexSerial4port. The way you conceived it would have very low latency between receive and transmit on each port, but you would be consuming 4 cogs, two for the Spin and two for the pasm for two instances of fullDuplexSerial.
if my code is fine then I think the problem must be with connectivity. the other piece to the problem is that im trying to convert from lvTTL to RS232 so that could be the reason im not getting any bits being passed through.
anyway thanks again everyone!
I don't think the code on post 1 is fine - but try Tracy Allen's code in post #5 as this should work out of the box, as it were.
Re hardware, you can trace through the resting volts without any data. The 'no data resting volts' for RS232 is anything less than minus 3V, and typically will be minus 9 or minus 12V. Any time it goes through a RS232 to TTL converter (eg a max3232) it gets inverted. So minus 9V will be converted to plus 3V3 (if using a max3232) or plus 5V (if using a max232).
The difference in TTL voltages is because some chips use 3V (like the propeller) and some use 5V (like the arduino). The standard is to convert to true RS232 voltages which usually swing between minus 9 and plus 9 volts. So for converting propeller to arduino there are two solutions. Use lvTTL and go 3V to 1k resistor to 5V. But the proper way is Propeller 3V to max3232 to true RS232 levels to max232 to 5V. Tracing through the DC levels that will be (resting) plus 3V to minus 9V to plus 5V.
It helps to be able to trace the DC signal levels before trying to debug with sending data.
I didnt have the actual code in front of me when i started the thread but I do now.
I'm using this bi-directional logic level converter from SparkFun - https://www.sparkfun.com/products/12009. Now, the product page says you can use it for 3volt to 5volt signals. But peoples comments say you can also use it for higher voltages. The logic level converter needs a positive power supply for each side. the Propeller side is easy enough, but the RS232 side is tricky...I checked all the pins (except for RX and TX) and couldnt find any with a positive voltage, except for the CTS pin (or RTS i cant remember which). I measured about +12 volts on one of those pins so I was using that as the power for the logic level converter. But if you are saying the resting volts for the RX and TX lines should be no more than + or - 9 volts then im probably over powering the rx and tx pins on the RS232 side.
Can you post more about your setup?
One microcontroller to another with the same volts, eg propeller to another propeller - just connect the pins.
One microcontroller running on 3V and one on 5V - eg propeller to ardunio - you can do this with a 1k resistor or with your 5V to 3V board (the resister is simpler and cheaper)
One microcontroller to a PC - need to invert the signal and turn it into proper RS232 levels. Need a chip like a max3232.
I see in your first post you are going PC to propeller. If that is via pins 30 and 31 you won't need a max3232 as the level shifting is already done as part of the download circuit.
We should be able to get this all working. Just need a bit more information. Re
What is the other device?
I have a PC connected to the Prop on the host port (pins 30 and 31) via a Prop Plug (usb to serial adapter).
The other device is a network device - a Cisco network router with an RS232 serial console port. I have about 6 Cisco devices at home with console ports.
I'm only using RX and TX pins with the prop but the network devices have all the RS232 pins wired through to the plug so I've connected the other wires in a null-modem configuration - RTS to CTS, and DTR, CD, DSR connected together. Then the TX from the Prop into RX on the device, and RX from the Prop into TX on the device, Ground on both ends connected to the ground pin on the logic level converter., 3.3v from the prop power supply into the low-voltage side of the converter, and the positive supply from the RRTC/CTS pins on the device side into the high voltage side of the converter.
My grand plan is I want to use the Prop as a poor mans 'Console Server' for Out Of Band management of my network devices.
the idea is all 6 devices will connect to 6 rx/tx pairs on the prop, and the host port on the prop will connect to a PC. The prop will have a menu on it. when i connect to the prop from the pc I'll see a menu, I can chose to connect to one of the 6 device ports at which point the Prop will route the serial data between the PC and the network device.
A special key combination (CTRL+SHIFT+6 and then x) will cause the prop to drop back to the menu and allow me to end the session or chose another device to connect to.
in the industry we pay good money for these types of devices to manage our network kit. I'm hoping to make a cheap one for home using a Propeller and a Raspberry Pi.
Ah, is that with a D9 plug or socket?
If so, then it will need level conversion AND inverting. The board you have is not quite the right one for this job.
So - cisco router - resting volts minus 12V gets converted to +3.3V on the propeller. And when the data is active, the cisco router will be plus 12V which gets converted to 0V on the propeller.
No worries about getting that working. One chip - a max3232 will do all this. This one chip does the level conversion, the inverting, and you will be able to create two bi-directional ports out of one chip.
Max3232 on ebay is about $1 and then you need four 0.1uf capacitors. And a D9.
Search max3232.
Or you could get a module which has the chip, D9 plug, capacitors and header cables, for under $3 http://www.ebay.com.au/itm/N8-MAX3232-RS232-Serial-Port-to-TTL-Converter-Module-DB9-Connector-w-Cables-2PCS-/380867867275?pt=AU_B_I_Electrical_Test_Equipment&hash=item58ad7e728b&_uhb=1
and erco will probably get it for you for even less.
Technical point - max232 is for 5V. Max3232 is for 3.3V
The original console cords from Cisco come with D9 on one end and RJ45 on the other. they use a 4 pair flat cable. So I'm going to cut the D9 plug off the end and crimp an RJ45 on so the cable will have RJ45s on both ends - the D9s take up too much room.
I was going to (figure out how to) solder a bunch of RJ45 sockets onto a PCB along with the Prop and the logic level converters.
I had previously looked at the Max232 and Max3232 but hated the idea of having such a large package (so many pins), and I can only connect 1 device, which is why I went with the logic level converter, because i can connect 2 devices per logic level converter.
But, if i have to invert the voltage then I'm going to have to use a bunch of Max3232s i guess. I'll try ordering a bunch of Max3232s from ebay.
Thanks for everyone's help.
There are several second sources including Exar (SP3232), ST (ST3232), Intersil (ICL3232), possibly TI, etc, and these are roughly $1 each from Digikey even in small quantities
Also - do the cisco routers need CTS and RTS? I think you said they could be looped back? If so then you only need two data lines per router (tx and rx) and the max3232 can do 4 lines, so that is two cisco routers per max3232 chip.
Re taking up too much space, I tend to build boards using large DIP chips for the first version, and if it all works, then look at using surface mount to shrink it down.
ebay is cheap... but can be a few weeks if parts coming from overseas. The prices Tubular quotes are similar if you can get to somewhere like digikey or a local supplier.
Also attached is the complete schematic of a board I am working on. The idea is to have a propeller router, with serial ports and also some real world ports and sd card and a display. So you can see the data go through (super easy to add with existing propeller object code). This is a network topology I have been thinking about where each node can combine rs232 signals from two sources and combine them to one source, and also has enough sensors and smarts to do some real world sensing/control.
Possibly not relevant for your application, but it does show the download circuit as well, and this is the part that can also be used to talk to the PC without necessarily using a propplug.
This works because the 100kΩ resistor limits the current from the device RS232 lines to +/- 150µA, even if the RS232 levels are +/- 15V. That is within the safe limits of the Propeller substrate diodes (500µA). On the transmit side, most RS232 devices have a threshold level of around +1V, so that even a 0V to 3.3V swing from the Prop is correctly interpreted as high and low levels. In that case there is no inversion, but fullDuplexSerial can handle that. In fullDuplexSerial4port, the command from post#5 becomes,
uarts.AddPort(1,1,0,-1,-1,0,3,9600) ' 3 to send/receive inverted data
Not all devices have the 1V threshold, but as I said, it is a hack.
Small update on this thread.
I was able to buy a bunch of Max3232 breakout boards (Max3232 and all required caps and resistors on a small pcb) for about $1 each from Ebay. They only do 1 serial port per device, but they are small enough that it doesn't matter.
Anyway, I've wired in one of these new Max3232 boards between an RS232 port and my Prop Plug and I've got data in both directions which is great. Data through the prop, on the other hand, isn't working...yet. But now that I know the hardware side of things is good I just need to figure out the code side of things.
So, making progress on this project
Thanks again all for your help and suggestions.
p.s. the only thing I don't like about these Max3232 breakout boards is that not all the pads have been drilled for header pins and the ones that have been drilled are quite small. I don't want to try drilling the remaining holes so I'm just going to order some right-angle male header pins and solder those on to the underside of the boards.