Shop OBEX P1 Docs P2 Docs Learn Events
Serial communications using a single wire — Parallax Forums

Serial communications using a single wire

DiverBobDiverBob Posts: 1,108
edited 2009-01-13 17:10 in Propeller 1
I've been doing a lot of testing using FullDuplexSerial but have been unable to get it to successfully transmit and recieve over a single wire between the propellor serial terminal program and a propellor chip.

I have searched but haven't been able to locate any discussions in the forum where anyone else has done this so I want to see if anyone has or knows of any serial code (or can point me to some code) that I can examine to see where I'm having my problems. I just need something simple to start testing...

Thanks in advance

Bob Sweeney

Comments

  • grasshoppergrasshopper Posts: 438
    edited 2009-01-07 03:33
    Are you using a "Common" so that the computer and propeller are connected to ground. You say 1 wire but you'll need at least 2 I think.
  • Erik FriesenErik Friesen Posts: 1,071
    edited 2009-01-07 03:35
    You could look at some of the parallax gps code. I think it is communicating over a single wire using a pullup resistor.
  • DiverBobDiverBob Posts: 1,108
    edited 2009-01-07 03:58
    When I say one wire comm, I mean there is a common ground wire and and single wire the comms travel over. I am using a 4.7K pullup resistor to V+ on the serial line and a 1K resistor between the prop and the incoming signal.

    Erik: I will take a look at the GPS code tomorrow - time to get some sleep, too much time spent playing with the prop!

    Bob Sweeney
  • KyeKye Posts: 2,200
    edited 2009-01-07 04:00
    There are objects for 1 wire communication at the exchange. Check 'em out.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Nyamekye,
  • DiverBobDiverBob Posts: 1,108
    edited 2009-01-07 22:03
    I only found one object for GPS that had a serial interface and it was setup using seperate rx and tx lines. I'm not very familiar with the 1 wire object, but it doesn't seem like the right choice for this type of communications.

    What I am ultimately trying to accomplish is using a PIC to read 4 channels of input and then serially send the results to a propellor in a half-duplex mode. The 6 conductor cable connecting the prop and PIC has one wire left that isn't already dedicated to some other purpose (such as V+, GND and some switch inputs for the prop). The process is for the prop to request a specific ADC channel over the line. The PIC wakes from sleep mode, processes the request, serially sends the data back down the line and goes back to sleep until the next request. This setup is being used because the entire setup is battery powered and there is no on/off switch - in sleep mode the PIC draws nano watts and I have been able to programatically shutdown the prop and display to around 0.06 mA. So I need to keep the PIC in sleep mode as much as possible but the prop has to 'wake' it up when data is required.

    I have·made this all work using two wires in test but I have been unable to get it to work at all once I point the rx and tx pins to the same pin#. So I was hoping that someone with more experience in serial communications might know of some example code that could be used as a guide. All the serial code I have reviewed on the forum so far is set for 2 wire comms.

    Thanks for any help, suggestions or advice!

    Bob

    Post Edited (DiverBob) : 1/8/2009 2:41:35 AM GMT
  • grasshoppergrasshopper Posts: 438
    edited 2009-01-07 22:39
    Did you look at the i2c object or the bs2 object? They contain the information you need if i remember correctly.

    obex.parallax.com/objects/217/

    Technically you could do anything like this
    PUB ShiftOut (Dpin, Value, Bits)
    
        outa[noparse][[/noparse]Dpin]:=0                                       
        dira[noparse][[/noparse]Dpin]~~  
      
                                     
        REPEAT Bits
              outa[noparse][[/noparse]Dpin] := Value                           
              Value := Value >> 1                     
              waitcnt(1000 + cnt)                            
                                           
    
    

    Post Edited (grasshopper) : 1/7/2009 10:45:12 PM GMT
  • Mike GreenMike Green Posts: 23,101
    edited 2009-01-07 22:50
    The Simple Serial driver from the Object Exchange should work fine in half-duplex with a single I/O pin. There's even an example of what you want to do in the comments. You'll need a pullup resistor (like 4.7K) to +Vdd. When the Prop and PIC are idle, this won't draw any significant current since both the Prop and PIC ends will be in input mode.
  • StefanL38StefanL38 Posts: 2,292
    edited 2009-01-07 22:53
    Helo Bob,

    the propeller serial terminal program (PST.EXE) will ONLY communicate on two seprate wires tx/rx.

    There is no option in PST.EXE to setup tx and rx on the same pin. PST.EXE can't be used to test this

    Anyway: there are modes for the FullDuplexSerial-driver to set tx and rx on the same IO-pin

    '' mode bit 0 = invert rx
    '' mode bit 1 = invert tx
    '' mode bit 2 = open-drain/source tx
    '' mode bit 3 = ignore tx echo on rx
    
    
    



    I'm sure you have to set bit 3 = %1000
    I'm not sure about using bit 2 = %0100
    and what this means for the hardware
    In the file simple_serial.spin (found in the propeller library is a description how this can be done with the simple serial object using a pull-up-resistor

                Same-Pin (Bi-Directional) True Mode                                
                    Ex: serial.init(0, 0, 9600)                                        
                                                                                                                        
                                  │                                                                                      
                                   4.7 kΩ                                                                               
             ┌────────────┐       │       ┌──────────┐                                      
             │Propeller P0├─────┻─────┤I/O Device│                                             
             └────────────┘               └──────────┘                                             
    
    
    
    




                Same-Pin (Bi-Directional) True Mode                                
                    Ex: serial.init(0, 0, 9600)                                        
                                  │                                                                                      
                                  │                                                                                      
                                4.7 kΩ                                                                               
                                  │                                             
              Propeller P0────────│────────I/O Device                                             
    
    
    



    best regards

    Stefan
  • DiverBobDiverBob Posts: 1,108
    edited 2009-01-07 23:03
    Well that explains why the PST doesn't want to work...

    I will try SimpleSerial again, reprogram the PIC and prop. I should at least be able to monitor the serial line using PST just by dumping whatever is being passed on the comm line.

    I'll give it a go right after supper! I'll let you know how it turns out!

    Thanks

    Bob Sweeney
  • DiverBobDiverBob Posts: 1,108
    edited 2009-01-08 02:49
    I have been playing around with Simple_Serial for a while now and seem to run into a wall. It works pretty good with a continuous data transfer one-way from the PIC to the prop. To test transmittal from the prop I wanted to start simple by having the prop output·the letter "A". When I use·tx("A") in a repeating loop it shows up in PST correctly. But when I remove the repeat statement that same code now is showing some strange results when viewed in PST. Each time the loop that transmits the character cycles, PST shows one of the following strings: A€AP ,
    A€AP ,
    A€AP ,

    It seems to cycle through the strings but I didn't catch any pattern. So until I figure out why this is happening I'm stuck. I have attached the archive of the test code I am using. Hopefully someone here understands what's going on.

    Bob Sweeney
  • StefanL38StefanL38 Posts: 2,292
    edited 2009-01-08 08:16
    Hello Bob,

    as you use a single wire for Tx and Rx this might be simple the answer of the PIC

    You made modifications in the file simple_serial.spin.
    I would test them right before doing something else with a demo-prg
    that is known as working with the original simple_serial.spin
    than test your added methods and test them too.

    old programmers wisdom:
    a program does ALWAYS what is coded. Sometimes what is coded differs from what you intended to do.


    To narrow down the problem I would "narrow down" the code.

    Code a NEW and very simple test-prg that does NOTHING ELSE like send and receive serial data.

    To be REALLY 101% sure there's no error in the other code or interference with the other code
    you have to REMOVE the other code which is not related to the serial transmisssion.

    best regards

    Stefan
  • StefanL38StefanL38 Posts: 2,292
    edited 2009-01-08 14:16
    Hello again,

    I did the followong tests:
    I stripped down your code to just test serial datatransfer

    {{Author: Bob Sweeney         
    Test program listing 
    Serial comm testing}}
    
    CON
      '_CLKMODE      = XTAL1 + PLL8X                        
      '_XINFREQ      = 8_000_000
    
      _CLKMODE      = XTAL1 + PLL16X                        
      _XINFREQ      = 5_000_000
    
    VAR
      'byte datain[noparse][[/noparse]16]
            
    '********************************
    OBJ
      Serial   : "Simple_Serial_mod"
    
    '********************************
    PUB Main 
      Serial.start(21, 21, 2400)
      'Serial.start(19, 19, 2400)
      TestDisplay
      
    '********************************
    PUB TestDisplay | blink
    '********************************
      repeat
        GetPOValues
    
    '********************************
    PUB GetPOValues 
    '  get cell PO2
    '********************************
       serial.tx($41)
       waitcnt(ClkFreq / 250 + cnt) '272
      
    
    



    with no delay the receiving is fine just "A"s

    If I add the delay around 272 I get "A"s combinded with rubish
    if I do NOT use a Pull-UP-resistor
    Pull-up means one end connected to the Rx/Tx-pin and the other end to +3.3V

    I started my testing with normal-mode (baud +2400)
    reverse-mode does not work with PST.EXE

    and there is another trap in PST.EXE for long delays just a zero is added to the "A" always A<0>A<0>A<0>

    The default preferences of PST.EXE does a clearscreen if a zero is received
    so the screen stood empty only the Rx-indicator was flashing (fist thought of me strange thing what is wrong?)

    The rubbish after the "A" is added because of the IO-pin beeing set as input after finishing the transmission of the "A"
    see commet '<=== HERE in PUB Tx

    This is done because the Rx-pin is the same as the Tx-pin !

    PUB tx(txByte) | t
    {{ Transmit a byte; blocks caller until byte transmitted. }}
    
      if txOkay
        outa[noparse][[/noparse]sout] := !inverted                             ' set idle state
        dira[noparse][[/noparse]sout]~~                                        ' make tx pin an output        
        txByte := ((txByte | $100) << 2) ^ inverted         ' add stop bit, set mode 
        t := cnt                                            ' sync
        repeat 10                                           ' start + eight data bits + stop
          waitcnt(t += bitTime)                             ' wait bit time
          outa[noparse][[/noparse]sout] := (txByte >>= 1) & 1                  ' output bit (true mode)  
        
        if sout == sin
          'dira[noparse][[/noparse]sout]~ '<=== HERE                                       ' release to pull-up/pull-down
    
    
    



    This let's the Pin flow around at high impedance WITHOUT a Pull-UP-resistor and that causes the received rubbish
    if it's commented out it works fine again
    But you need to set it to an input as the same pin is used for receiving

    So you really HAVE to use a Pull-UP-resistor combined with normalmode

    Why are you using inverted mode baud-parameter -2400 (MINUS 2400) ???
    is there a special reason for this ?

    best regards

    Stefan

    Post Edited (StefanL38) : 1/8/2009 2:23:14 PM GMT
  • StefanL38StefanL38 Posts: 2,292
    edited 2009-01-08 15:36
    now third round of testing

    I took my PPDB and connected pin 21 with the onboard MAX2323
    I connected Rx AND Tx of the max2323 with pin 21 and used a pull-up on pin 21

    then i tested the following code with success

    {{Author: Bob Sweeney         
    Test program listing 
    Serial comm testing}}
    
    CON
      '_CLKMODE      = XTAL1 + PLL8X                        
      '_XINFREQ      = 8_000_000
    
      _CLKMODE      = XTAL1 + PLL16X                        
      _XINFREQ      = 5_000_000
    
    VAR
      'byte datain[noparse][[/noparse]16]
      byte char
            
    '********************************
    OBJ
      'Serial     : "Simple_Serial_mod"
      Serial   : "FullDuplexSerialPlus"
      debug    : "FullDuplexSerialPlus"
    
    '********************************
    PUB Main 
      'Serial.start(21, 21, 2400)
      Serial.start(21, 21, %1100,2400)
      Debug.Start(31,30,0,2400) 'start(rxpin, txpin, mode, baudrate) :
      ''        '"rx" and "tx" viewed from Propeller-Chip.   Propeller-Chip-PIN-Tx ----> PC
      Debug.str(string("using FullDuplexSerial Rx-Pin=Tx-Pin",13))
      
      Debug.str(string("Serial.start(21, 21, %1000,2400) done",13))
      Debug.str(string("Debug.Start(31,30,0,115200) done",13))
    
      Debug.str(string("wait for bytes to receive",13))
      
      repeat
        char := Serial.rx
        if char > 0
          Debug.tx(char)
          waitcnt(ClkFreq / 2 + cnt) 
          serial.tx(char + 1)
          
        'serial.tx($41)
        'waitcnt(ClkFreq / 2 + cnt) '272
      
        
      TestDisplay
      
    '********************************
    PUB TestDisplay | blink
    '********************************
      repeat
        GetPOValues
    
    '********************************
    PUB GetPOValues 
    '  get cell PO2
    '********************************
       serial.tx($41)
       waitcnt(ClkFreq * 2 + cnt) '272
      
    
    



    as the terminal does not ignore the tx on rx the terminal connected to pin 21 received both characters

    the final test would be to use two propellerchips both in mode ignore tx echo on rx

    But on pin 21 I received what was sendet from the terminal software
    and then the terminal software received correctly char+1 which was sended back from the propeller

    this worked with initialisation of Fulldoplexseialplus like this
    Serial.start(21, 21, %1100,2400)

    best regards

    Stefan
  • DiverBobDiverBob Posts: 1,108
    edited 2009-01-08 22:31
    Thanks for the information. I had noticed that the PST was clearing the screen when it got the '0', figured that part out when I looked at the preferences in PST. The only reason I have been using -2400 is because that is the way I initially set up the PIC download routines - I will change that code around later tonight. You went above and beyond the call of duty, I'm looking forward to running these same tests. I had originally started out with an un-modified version of Simple_Serial, it and the test spin code has gone through several dozen changes as I would modify one item at a time and then see how that affected the output. I have been a professional programmer for many years but this is the first time I have had to do any coding directly involving serial communications so it has been an interesting challenge so far. I know I'll get over the bump but it gets frustrating after a while when all you hit are dead-ends!

    Thanks again, I'll post my testing results but first it's time to go play some raquetball and relieve some of this tension!

    Bob
  • DiverBobDiverBob Posts: 1,108
    edited 2009-01-13 17:10
    Update - I've learned a couple of things working with the PST and serial communications between a prop and PIC. First item is that to display the PIC output on the PST the output has to be inverted. Noninverted output results in garbage displays which just confused the issue. So I stopped using PST for monitoring the PIC output and just used the oLED. Once I got over that hurdle I changed both the PIC and prop to output non-inverting data. Next I added a 250 msec delay between the transmit and recieve commands to give the prop and PIC time to 'settle down' after the pin changes. Once this was setup in both processors the test program started working correctly the first time I powered the system up! The lessons learned were applied to the main program and it is working great!

    Now I have to put the PIC to sleep in-between data requests but that's a problem for another day (that and getting all the registers set correctly!).

    Thanks to everyone for their help and examples.

    Bob Sweeney
Sign In or Register to comment.