Shop OBEX P1 Docs P2 Docs Learn Events
Strange behavior with no serial connection — Parallax Forums

Strange behavior with no serial connection

Ron CzapalaRon Czapala Posts: 2,418
edited 2010-09-13 13:36 in Propeller 1
I have a SPIN program which uses Extended_FDSerial along with a DS1307 object and serial LCD object.

The program sends a prompt asking if the clock needs to be set and times out if no serial response is received. There is a 3 second delay after the Extended_FDSerial Start method. The program also waits 5 seconds for a response using the RxTime method.

I am using a USB Proto board and everything works great if the board is connected to the PC but if it isn't, the program seems to skip past the delays and almost immediately starts displaying the time and date on the LCD. I'v looked at the Extended_FDSerial and FullDuplexSerial code but can't see any reason why this happens.
I am missing something?
Thanks.
CON
  _clkmode = xtal1 + pll16x
  _xinfreq = 5_000_000
  TX_PIN        = 0
  BAUD          = 9_600
  _clockDataPin = 29
  _clockClockPin = 28
VAR
  byte line
  byte col
  byte rval
  byte answer
  byte dig2[2]
 
OBJ
  LCD           : "SparkFun_Serial_LCD"
  rtc           : "DSRTC_driver"
  Debug         : "Extended_FDSerial"  
PUB Main
  LCD.init(TX_PIN, BAUD, 2, 16)    
  LCD.cls
  LCD.str(string("Set clock?"))
  Debug.start(31, 30, 0, 57600)      ' ignore tx echo on rx
  [COLOR=red]waitcnt(clkfreq * 3 + cnt)[/COLOR]         ' Pause for FullDuplexSerial.spin to initialize
  rtc.rtcEngineStart(_clockDataPin, _clockClockPin, -1)
  Debug.tx(16)  'cls
  Prompt(string("Enter 'y' if you want to set clock:"),true)
  answer := [COLOR=red]Debug.RxTime(5000)[/COLOR]
  if answer == "y"
    SetClock
  Debug.tx(16)  'cls
  waitcnt(clkfreq / 100 + cnt)              
 
  LCD.cls
  repeat
    rtc.readClock
    LCD.gotoxy(2, 0)
    Pad(rtc.clockMonth)
    LCD.putc("/")
    Pad(rtc.clockDate)
    LCD.putc("/")
    pad(rtc.clockYear - 2000)
    LCD.putc(" ")
    LCD.str(rtc.clockDOW)
    LCD.gotoxy(2, 1)
    Pad(rtc.clockHour)
    LCD.putc(":")
    Pad(rtc.clockMinute)
    LCD.putc(":")
    Pad(rtc.clockSecond)
    LCD.putc(" ")
    if(rtc.clockAMPM == rtc#PM)
      LCD.str(string("PM"))            
    else
      LCD.str(string("AM"))
    DispTime  
    waitcnt(clkfreq + cnt)            
PUB Pad(value) | temp
  temp := value
  if temp < 10
    LCD.putc("0")
  LCD.DEC(value)
PUB DispTime
  Debug.Tx(2)              'command to position the cursor at X,Y
  Debug.Tx(0)              'actual X
  Debug.Tx(0)              'actual Y
  SPad(rtc.clockMonth)
  Debug.tx("/")
  SPad(rtc.clockDate)
  Debug.tx("/")
  SPad(rtc.clockYear - 2000)
  Debug.tx(" ")
  Debug.str(rtc.clockDOW)
  Debug.Tx(2)              'command to position the cursor at X,Y....its code is 2
  Debug.Tx(0)              'actual X
  Debug.Tx(1)              'actual Y
  SPad(rtc.clockHour)
  Debug.tx(":")
  SPad(rtc.clockMinute)
  Debug.tx(":")
  SPad(rtc.clockSecond)
  Debug.tx(" ")
  if(rtc.clockAMPM == rtc#PM)
    Debug.str(string("PM"))            
  else
    Debug.str(string("AM"))
PUB SPad(value) | temp
  temp := value
  if temp < 10
    Debug.tx("0")
  Debug.DEC(value)
 
PUB SetClock | time[7], modeind, ampmind, tmp
  Prompt(String("Enter year (00-99)"),true)
  time[6] := getSerVal(2) + 2000
  Prompt(String("Enter month (1-12)"),true)
  time[5] := getSerVal(2)
  Prompt(String("Enter date (1-31)"), true)
  time[4] := getSerVal(2)
  Prompt(String("Enter day of week where 1=SUN 2=MON 3=TUE 4=WED 5=THU 6=FRI 7=SAT"), true)
  time[3] := getSerVal(1)
  Prompt(String("Enter clock mode - 12 or 24"),true)
  tmp := getSerVal(2)
  if tmp == 12
    modeind := rtc#Mode12hr
    Prompt(String("Enter 'a' for AM or 'p' for PM"),true)
    tmp := Debug.Rx
    if tmp == "a"
      ampmind := rtc#AM
    else
      ampmind := rtc#PM 
  else
    modeind := rtc#Mode24hr
  Prompt(String("Enter hour "),false)
  if modeind == rtc#Mode12hr
    Prompt(String("(1-12)"),true)
  else
    Prompt(String("(0-23)"),true)
  time[2] := getSerVal(2)
  Prompt(String("Enter minute (1-59)"),true)
  time[1] := getSerVal(2)
  time[0] := 0
 
  rtc.setClock(modeind, ampmind, time[0],{
                       } time[1], {
                       } time[2], {
                       } time[3], {
                       } time[4], {
                       } time[5], {
                       } time[6])
 
PRI Prompt(msg, CR)
  Debug.str(msg)
  if CR
    Debug.tx(13)
PUB getSerVal(lim) : value | bytesread, tmp, x, place
  Debug.RxFlush
  bytesread := 0
  value := 0
  place := 1
 
  repeat while bytesread < lim
    tmp := Debug.Rx
    if ((tmp == 10) OR (tmp ==13) OR (tmp == "*"))
      QUIT
    if (tmp => ("0")) and (tmp =< ("9"))  
      dig2[bytesread] := tmp
      bytesread++
 
  repeat x from (bytesread - 1) to 0
    value := value + ((dig2[x]-"0") * place)       
    place := place * 10        

Comments

  • T ChapT Chap Posts: 4,223
    edited 2010-09-12 18:27
    Do you have pullup/down resistors on the inputs for the Rx line? If not, you may be seeing noise making things weird. The inputs cannot float.
  • TimmooreTimmoore Posts: 1,031
    edited 2010-09-12 18:32
    Try checking pin 31 is 1 before calling debug.start i.e
    if ina[ 31 ] == 1
      debug.start
    
    Works for me, though its not a perfect solution which needs a hardware fix, there are threads talking about this problem
  • Ron CzapalaRon Czapala Posts: 2,418
    edited 2010-09-12 20:23
    Timmoore,
    I couldn't find any threads regarding this issue, but I did use your suggestion. I check ina[31] == 1 and set a variable to true or false.

    If TRUE I invoke the Debug.Start method and utilize the serial connection to the PC.

    If FALSE, I skip any code referencing the Debug object.

    Not sure why this works, but it does. Why is pin 31 high if the USB connection is not in use?
      useser := false
      if ina[31] == 1
        Debug.start(31, 30, 0, 57600)      ' ignore tx echo on rx
        useser := true
        LCD.str(string("Set clock?"))
      else
        LCD.str(string("No USB serial"))
    
  • T ChapT Chap Posts: 4,223
    edited 2010-09-12 20:45
    Ron, can you try this and post what you get on the LCD?
        repeat
           if ina[31] == 1
             lcd.gotoxy(0,0)
             LCD.decf(ina[31], 1)
             waitcnt(10_000_000 + cnt)
           if ina[31] == 0
             lcd.gotoxy(0,0)
             LCD.decf(ina[31], 1)
             waitcnt(10_000_000 + cnt)
    
    
  • Ron CzapalaRon Czapala Posts: 2,418
    edited 2010-09-13 08:42
    Tchap,
    It displays one if the USB cable is connnected to the PC and zero if not.

    I assume that if the FTDI chip is not being powered from the USB port, then pin 31 is low.
  • HumanoidoHumanoido Posts: 5,770
    edited 2010-09-13 09:00
    Ron, just a thought - check your hardware. There may be some kind of loading on the prop. When connected, it pulls in power from the pc and runs fine, otherwise does some strange things.

    Humanoido
  • Ron CzapalaRon Czapala Posts: 2,418
    edited 2010-09-13 09:22
    Humanoido,
    The USB protoboard schematic shows the circuit - only the RX, TX, DTR connect to the PROP. The FTDI 3.3v out connects to ground thru a cap.
  • TimmooreTimmoore Posts: 1,031
    edited 2010-09-13 09:35
  • Ron CzapalaRon Czapala Posts: 2,418
    edited 2010-09-13 10:42
    Timmore,
    Thanks for the link to the earlier thread. I tried different search parameters but never hit it.

    I wasn't disconnecting the USB cable with the Prop powered so I didn't experience the reset issue but it's the same issue.

    Testing ina[31] works but it would be nice if the hardware would handle it...

    - Ron
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2010-09-13 11:57
    I am using a USB Proto board and everything works great if the board is connected to the PC but if it isn't, the program seems to ...

    and
    I wasn't disconnecting the USB cable with the Prop powered ...

    There seems to be a disconnect here of another kind. Ron, I'm confused: was the board connected to the PC or not?

    -Phil
  • HumanoidoHumanoido Posts: 5,770
    edited 2010-09-13 12:37
    ..I wasn't disconnecting the USB cable with the Prop powered so I didn't experience the reset issue but it's the same issue. - Ron
    Ron, the question now becomes, were you connecting the powered prop with the USB cable and loading the program? - Then, if you shut off the prop after the program loaded, and disconnected the USB cable, powered up, a loading problem could occur at that time. Can you provide a schematic? If you want to be sure you could disable the brownout detector as a means of debugging.

    Humanoido
  • HumanoidoHumanoido Posts: 5,770
    edited 2010-09-13 12:48
    Ron wrote: Not sure why this works, but it does. Why is pin 31 high if the USB connection is not in use?
    Ron, good observation, because pin 31 must be held high or low and not allowed to float or you will see a residual voltage across the pin when the the usb cable is plugged into the prop circuit and the computer. If you want to test this, let the pin float and connect a single LED to pin 31 through a 220 ohm resistor and it will dimly light. For more detail, take a look at the USB circuit to pc and you'll see what happens, and why, on Rx and pin 31.

    Humanoido
  • TimmooreTimmoore Posts: 1,031
    edited 2010-09-13 12:49
    There are 2 symptoms of the same problem
    1. If you plug in the usb while the prop is running it resets the board
    2. If you start a serial device on 30/31 with the usb unplugged, pin 31 is low all the time and so you get continuous 0 chars, so if you read you always get chars - thats the reason for the rxtime always returning. (dont know about the first waitcnt problem though)

    Checking for ina[31] == 1 before starting the serial devices fixes the 2nd issue, doesnt have any impact on the 1st issue.
  • Ron CzapalaRon Czapala Posts: 2,418
    edited 2010-09-13 13:20
    Actually, mine does not reset when I unplug the cable, but does if I plug it back in?!? :confused:
    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
      TX_PIN        = 0
      BAUD          = 9_600
      _clockDataPin = 29
      _clockClockPin = 28
    VAR
      byte line
      byte col
      byte rval
      byte answer
      byte dig2[2]
    [COLOR=red] long useser           'USB serial connection detected T/F[/COLOR]
     
    OBJ
      LCD           : "SparkFun_Serial_LCD"
      rtc           : "DSRTC_driver"
      Debug         : "Extended_FDSerial"  
    PUB Main
      LCD.init(TX_PIN, BAUD, 2, 16)    
      LCD.cls
    [COLOR=red] useser := false[/COLOR]
    [COLOR=red] if ina[31] == 1[/COLOR]
        Debug.start(31, 30, 0, 57600)      ' ignore tx echo on rx
    [COLOR=red]   useser := true[/COLOR]
        LCD.str(string("Set clock?"))
      else
        LCD.str(string("No USB serial"))
      waitcnt(clkfreq * 3 + cnt)         ' Pause for FullDuplexSerial.spin to initialize
      rtc.rtcEngineStart(_clockDataPin, _clockClockPin, -1)
    [COLOR=red] if useser == true[/COLOR]
        Debug.tx(16)  'cls
        Prompt(string("Enter 'y' if you want to set clock:"),true)
        answer := Debug.RxTime(5000)
        if answer == "y"
          SetClock
        Debug.tx(16)  'cls
        waitcnt(clkfreq / 100 + cnt)              
      LCD.cls
      repeat
        rtc.readClock
        LCD.gotoxy(2, 0)
        Pad(rtc.clockMonth)
        LCD.putc("/")
        Pad(rtc.clockDate)
        LCD.putc("/")
        pad(rtc.clockYear - 2000)
        LCD.putc(" ")
        LCD.str(rtc.clockDOW)
        LCD.gotoxy(2, 1)
        Pad(rtc.clockHour)
        LCD.putc(":")
        Pad(rtc.clockMinute)
        LCD.putc(":")
        Pad(rtc.clockSecond)
        LCD.putc(" ")
        if(rtc.clockAMPM == rtc#PM)
          LCD.str(string("PM"))            
        else
          LCD.str(string("AM"))
    [COLOR=red]   if useser == true[/COLOR]
          DispTime  
        waitcnt(clkfreq + cnt)            
    PUB Pad(value) | temp
      temp := value
      if temp < 10
        LCD.putc("0")
      LCD.DEC(value)
    PUB DispTime
      Debug.Tx(2)              'command to position the cursor at X,Y
      Debug.Tx(0)              'actual X
      Debug.Tx(0)              'actual Y
      SPad(rtc.clockMonth)
      Debug.tx("/")
      SPad(rtc.clockDate)
      Debug.tx("/")
      SPad(rtc.clockYear - 2000)
      Debug.tx(" ")
      Debug.str(rtc.clockDOW)
      Debug.Tx(2)              'command to position the cursor at X,Y....its code is 2
      Debug.Tx(0)              'actual X
      Debug.Tx(1)              'actual Y
      SPad(rtc.clockHour)
      Debug.tx(":")
      SPad(rtc.clockMinute)
      Debug.tx(":")
      SPad(rtc.clockSecond)
      Debug.tx(" ")
      if(rtc.clockAMPM == rtc#PM)
        Debug.str(string("PM"))            
      else
        Debug.str(string("AM"))
    PUB SPad(value) | temp
      temp := value
      if temp < 10
        Debug.tx("0")
      Debug.DEC(value)
     
    PUB SetClock | time[7], modeind, ampmind, tmp
      Prompt(String("Enter year (00-99)"),true)
      time[6] := getSerVal(2) + 2000
      Prompt(String("Enter month (1-12)"),true)
      time[5] := getSerVal(2)
      Prompt(String("Enter date (1-31)"), true)
      time[4] := getSerVal(2)
      Prompt(String("Enter day of week where 1=SUN 2=MON 3=TUE 4=WED 5=THU 6=FRI 7=SAT"), true)
      time[3] := getSerVal(1)
      Prompt(String("Enter clock mode - 12 or 24"),true)
      tmp := getSerVal(2)
      if tmp == 12
        modeind := rtc#Mode12hr
        Prompt(String("Enter 'a' for AM or 'p' for PM"),true)
        tmp := Debug.Rx
        if tmp == "a"
          ampmind := rtc#AM
        else
          ampmind := rtc#PM 
      else
        modeind := rtc#Mode24hr
      Prompt(String("Enter hour "),false)
      if modeind == rtc#Mode12hr
        Prompt(String("(1-12)"),true)
      else
        Prompt(String("(0-23)"),true)
      time[2] := getSerVal(2)
      Prompt(String("Enter minute (1-59)"),true)
      time[1] := getSerVal(2)
      time[0] := 0
     
      rtc.setClock(modeind, ampmind, time[0],{
                           } time[1], {
                           } time[2], {
                           } time[3], {
                           } time[4], {
                           } time[5], {
                           } time[6])
     
    PRI Prompt(msg, CR)
      Debug.str(msg)
      if CR
        Debug.tx(13)
    PUB getSerVal(lim) : value | bytesread, tmp, x, place
      Debug.RxFlush
      bytesread := 0
      value := 0
      place := 1
     
      repeat while bytesread < lim
        tmp := Debug.Rx
        if ((tmp == 10) OR (tmp ==13) OR (tmp == "*"))
          QUIT
        if (tmp => ("0")) and (tmp =< ("9"))  
          dig2[bytesread] := tmp
          bytesread++
     
      repeat x from (bytesread - 1) to 0
        value := value + ((dig2[x]-"0") * place)       
        place := place * 10        
    
  • TimmooreTimmoore Posts: 1,031
    edited 2010-09-13 13:36
    Yes, you right its on plug in
Sign In or Register to comment.