Shop OBEX P1 Docs P2 Docs Learn Events
data in one serial port and out another serial port — Parallax Forums

data in one serial port and out another serial port

Evil SiblingEvil Sibling Posts: 7
edited 2014-08-29 21:50 in General Discussion
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
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

  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-08-05 05:44
    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
    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?

    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=courier new]VAR
    long SqStack[6]                  'Stack space for Square cog
    PUB Main | X
      X := 2                         'Initialize X
      cognew(Square(@X), @SqStack)   'Launch square cog
      <check X here>                 'Loop here and check X
    
    
    PUB Square(XAddr)
    'Square the value at XAddr
     repeat                              'Repeat the following endlessly
      long[XAddr] *= long[XAddr]         ' Square value, store back
      waitcnt(2_000_000 + cnt)           ' Wait 2 million cycles
    
    [/FONT]
  • Evil SiblingEvil Sibling Posts: 7
    edited 2014-08-05 06:37
    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 )

    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?
  • ElectrodudeElectrodude Posts: 1,658
    edited 2014-08-05 07:59
    Your code should work fine if you fix your cognews.

    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:
    code block
    

    However, I must say that of all the people I have seen who have posted code without code blocks, you formatted yours the best.
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2014-08-05 10:44
    Another way to do that requires a single cog. Something like the following. I've used fullDuplexSerial4port, but you could also do it with two instances of fullDuplexSerial. The RxCheck method returns -1 if there is no character available and moves right along, so the repeat loop bounces back and forth between the two ports.
    [SIZE=1]CON
      _clkmode = xtal1 + pll16x                '' clkfreq=80MHz
      _xinfreq = 5_000_000
    
    OBJ
      uarts : "fullDuplexSerial4port"
    
    PUB Main | char
      StartUarts
      repeat
        if (char := uarts.RxCheck(0)) > -1      ' port 0, pins 31, 30
           uarts.tx(1,char)
        if (char := uarts.RxCheck(1)) > -1      ' port 1, pins 1, 0
           uarts.tx(0,char)
    
    PRI StartUarts
      uarts.Init
      uarts.AddPort(0,31,30,-1,-1,0,0,9600)
      uarts.AddPort([COLOR=#020FC0]1[/COLOR],1,0,-1,-1,0,0,9600)
      uarts.Start
      waitcnt(clkfreq/10+cnt)[/SIZE]
    

    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.
  • Evil SiblingEvil Sibling Posts: 7
    edited 2014-08-05 16:15
    thanks all for your advice on the topic and on proper forum posting...im new to forum markup.

    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!
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2014-08-05 17:09
    if my code is fine...

    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.
  • Evil SiblingEvil Sibling Posts: 7
    edited 2014-08-05 18:52
    Dr_Acula wrote: »
    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.

    I didnt have the actual code in front of me when i started the thread but I do now.
    VAR
      long  mcogstack[32]    'FIXME - Need to determine actual stack space required.
      long  scogstack[32]
      long  mcog
      long  scog
    
    OBJ
      mSerial       : "FullDuplexSerial"
      sSerial       : "FullDuplexSerial"
      
    PUB main
    mSerial.Start(31, 30, 00, 9600)
    sSerial.Start(1, 0, 00, 9600)
    
    mcog := cognew(masterCog, @mcogstack)
    scog := cognew(slaveCog, @scogstack)
    
    PRI masterCog
    repeat
        sSerial.tx(mSerial.rx)
    
    PRI slaveCog
    repeat
        mSerial.tx(sSerial.rx)
    
    
    
    Dr_Acula wrote: »
    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'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.
  • SapphireSapphire Posts: 496
    edited 2014-08-05 19:24
    The RS232 voltage levels are +3v to +15v or -3v to -15v, so anything in that range is valid. +12v or +9v are okay, it really depends on what is driving the signal. Older equipment tends to be closer to the high end, some newer devices barely make +5v. Either way, you can use the RTS/CTS as your HV power supply because they should be at the same maximum level of the TX/RX line, provided that the device doesn't toggle RTS/CTS to the negative voltage during data transmission! Many devices do that when transmitting with hardware handshaking so you need to check and make sure yours doesn't. You also have to connect the ground pin on both sides.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2014-08-05 20:50
    I'm using this bi-directional logic level converter from SparkFun

    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
    is connected to serial port on another device.

    What is the other device?
  • Evil SiblingEvil Sibling Posts: 7
    edited 2014-08-05 21:38
    Dr_Acula wrote: »
    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.

    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.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2014-08-05 21:48
    The other device is a network device - a Cisco network router with an RS232 serial console port.

    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
  • Evil SiblingEvil Sibling Posts: 7
    edited 2014-08-05 22:12
    Dr_Acula wrote: »
    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.
  • TubularTubular Posts: 4,703
    edited 2014-08-05 22:21
    Just on the MAX3232 thing - these work from 3v3 OR 5v, so super flexible.

    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
  • TubularTubular Posts: 4,703
    edited 2014-08-05 22:24
    Just read your last post... there's other versions of the maxim series (and corresponding 2nd sources) with 3 TX and 5 RX (for example) Thus would cover 3 of your routers per chip (assuming you're just using RX and TX)
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2014-08-05 23:36
    Good points Tubular.

    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.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2014-08-06 02:49
    Quick design for you using Eagle. Two RS232 ports using 4 propeller pins. Shows pinout of max3232 and pinouts of D9 plugs. Also added some diagnostic leds - they can be useful to see the data go through. Red for leds transmitting from the device and green for data being received. Propeller pins can be changed to suit - just a single line in the startup routine. This is for male D9s. If you keep things really simple and just use 3 wires (gnd, tx, rx) then for female plugs all you do is swap pins 2 and 3.

    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.
    768 x 352 - 32K
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2014-08-06 11:03
    As a quick hack, you can often get by with a direct connection via resistors:
    220&#937;
    Prop txd --------/\/\/\-------->Device rxd
    Prop rxd <--------/\/\/\--------Device txd
                       100k&#937;
    

    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.
  • Evil SiblingEvil Sibling Posts: 7
    edited 2014-08-29 21:50
    Hi everyone,

    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.

    20140830_145608.jpg
    20140830_145659.jpg


    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.
    1024 x 768 - 65K
    1024 x 768 - 58K
Sign In or Register to comment.