Shop OBEX P1 Docs P2 Docs Learn Events
My code fails intermittently when the prop plug is plugged in for long periods of tim — Parallax Forums

My code fails intermittently when the prop plug is plugged in for long periods of tim

turbosupraturbosupra Posts: 1,088
edited 2015-01-15 19:43 in Propeller 1
So I'm curious as to why I had this problem.

I have been told that I should have a COM cog and I'm in the process of converting my code to that and implementing it, but for my own learning and knowledge I was wondering why the behavior in the video was happening?

The code for the function is below, the cliffs are that when the pwm output frequency is high, the green LED is on, the yellow is off and when the square wave goes low, the green LED is off and the yellow is on. It also writes HIGH or LOW to the terminal when it is doing this. As seen in the video, it will oscillate around 20 times, then you'll see the prop plug LED illuminate 1 time and then both LED's will go out and it will hang for a few seconds, then the function will start again. It stopped doing that when I unplugged the prop plug. Is there a standard explanation for this?

http://youtu.be/vuuGCXm-PZ0

pub coolantPwmOut 


  ' set pin states
  
  dira[O_TempGauge] := 1                            ' Pin 16  ' output
  dira[O_CoolantPwmDebugLow] := 1
  dira[O_CoolantPwmDebugHigh] := 1                            


  ' set pin voltages
            
  outa[O_TempGauge] := 0                            ' Pin 16
  outa[O_CoolantPwmDebugLow] := 1
  outa[O_CoolantPwmDebugHigh] := 0
  
  ' initialize variables

  coolantPwmDebug := false
  coolantPwmDebugPause := cnt
  coolantPwmDebugPauseTime := clkFreqTimes2
  coolantPwmLastDebugTime1 := 0
  coolantPwmLastDebugTime2 := 0
  coolantPwmLastDebugTime3 := 0 
  coolantPwmStateHigh := false
  coolantPwmOnTime := cnt
  coolantPwmOffTime := cnt 
  adcTHWBlock := false

  waitcnt((clkfreq * 1) + cnt)
  
  repeat

    

    'if (ina[I_KeyOn] == 1)
     
    if(keyOn == true)


      
      if (okToReadAdcTHW == 1)
        okToReadAdcTHW := 0
        adcTHW := adcTHWTemp                
        okToReadAdcTHW := 1
 
       
      if (adcTHW <> 0)

        if (adcTHWBlock == false)

          adcTHWBlock := true                                                      
          onTime :=  ((pwmOutputHertzToClkCycles * getConstant) * 10)         
          offTime := ((pwmOutputHertzToClkCycles * (100 - getConstant)) * 10)           
          
         
              

        
      if (coolantPwmStateHigh == false) AND ((cnt - coolantPwmOffTime) > 0)     ' if not high and time expired


        outa[O_TempGauge] := 1                                                  ' output high    
        coolantPwmOnTime := (onTime + cnt)                                      ' stay high time
        coolantPwmStateHigh := true                                             ' state is high
        outa[O_CoolantPwmDebugLow] := 0                                         ' yellow
        outa[O_CoolantPwmDebugHigh] := 1                                        ' green
        debug.str(string(" HIGH "))
        debug.tx(13)
    
           
      if (coolantPwmStateHigh == true) AND ((cnt - coolantPwmOnTime) > 0)

        adcTHWBlock := false                                                    ' unblock next read
        outa[O_TempGauge] := 0                                                  ' output low
        coolantPwmOffTime := (offTime + cnt)                                    ' stay low time
        coolantPwmStateHigh := false                                            ' state is low
        outa[O_CoolantPwmDebugHigh] := 0                                        ' green
        outa[O_CoolantPwmDebugLow] := 1                                         ' yellow
        debug.str(string(" LOW "))
        debug.tx(13)
        debug.tx(13) 
                         

    else
                          
      repeat 7
        outa[O_Debug] := 1
        waitcnt((clkfreq/15) + cnt)
        outa[O_Debug] := 0
        waitcnt((clkfreq/15) + cnt)          
        
      outa[O_TempGauge] := 0                            ' Pin 16
      adcTHWBlock := false
      okToReadAdcTHW := 1
      coolantPwmStateHigh := false
      coolantPwmOnTime := cnt
      coolantPwmOffTime := cnt          
      firstRunAfterKeyOffCoolantPwm := true

      debug.str(string(" *** Key is off (coolantPwm)"))
      debug.tx(13)
      
      waitcnt (clkFreqTimes3 + cnt)


Comments

  • PropGuy2PropGuy2 Posts: 360
    edited 2015-01-02 19:37
    For starters, at least it is repeatable. If it is in the software code, try commenting out one time delay and/or IF /Then statement at a time until the problem goes away. Not the best way to solve the problem, but the most effective in this case. A lot of time I put debug print flags in the code so I can easily see where the different parts of code are being executed.
  • T ChapT Chap Posts: 4,223
    edited 2015-01-02 20:59
    Is the Prop restarting over and over again? You should have some LED sequence that only fires on bootup, then you can see if the Prop is restarting. If it is restarting, this could be noise on DTR.
  • ozpropdevozpropdev Posts: 2,792
    edited 2015-01-03 01:00
    Is the propplug connected to a USB port?
    I have had problems with prop's resetting intermittently when no USB cable us attached.
    I believe it's something to do with parasite power issues with the FTDI chip.
  • turbosupraturbosupra Posts: 1,088
    edited 2015-01-03 06:11
    T Chap wrote: »
    Is the Prop restarting over and over again? You should have some LED sequence that only fires on bootup, then you can see if the Prop is restarting. If it is restarting, this could be noise on DTR.

    I do have this code and it wasn't flashing, so I don't believe the prop was turning off, I believe it was just hanging.
    if (ina[I_KeyOn] == 1)
          keyOn := true
          keyTimeOutPeriod := (clkfreq + cnt)                                       ' you can change this to clkFreqTimes2 or clkFreqTimes3 to stretch this out and keep the gauge from dropping/bouncing
    
        else
          if ((cnt - keyTimeOutPeriod) > 0)
            keyOn := false
            repeat 20
              if (ina[I_KeyOn] == 0)
                outa[O_Debug] := 1                                       '  red led
                waitcnt((clkfreq/7) + cnt)
                outa[O_Debug] := 0
                waitcnt((clkfreq/2) + cnt) 
    
    
    ozpropdev wrote: »
    Is the propplug connected to a USB port?
    I have had problems with prop's resetting intermittently when no USB cable us attached.
    I believe it's something to do with parasite power issues with the FTDI chip.

    I had a cable connected to the prop plug, but no computer.


    I'd like to figure this out so that I don't have this issue when I switch everything over to a COM only method.
  • xanaduxanadu Posts: 3,347
    edited 2015-01-03 06:20
    This probably isn't helpful but my WS8211 LEDs act completely differently when the Prop Plug is plugged into my project. I'm in the habit of disconnecting it, I haven't done much troubleshooting I usually assume it's a power supply issue. It only seems to affect fast and small signals.
  • RaymanRayman Posts: 14,652
    edited 2015-01-03 06:34
    This sounds like the notorious ftdi reset bug. What can happen is that the Prop pins connected to the FTDI chip supply it trickle power that eventually causes the FTDI chip to power up.
    The first thing the FTDI chip does then is toggle the reset pin and cause the Prop to reset....

    You may have to disable your serial cog if using FTDI chip not powered from a PC...
  • T ChapT Chap Posts: 4,223
    edited 2015-01-03 06:57
    I remember cases where you are using serial terminals and you disconnect and it hangs up when disconnection the USB as the RX wants to see a high( If I recall this correctly) and it locks up. The remedy was to test RX input for a high and skip all serial communication if there was no USB connected. In your case, it sounds like the opposite, the unit locks up with the USB, and is OK without. Try a test and remove all serial com code and see what happens. Use LED on boot to always know if it resets(I think you are doing this already as noted).
  • turbosupraturbosupra Posts: 1,088
    edited 2015-01-08 05:35
    This occurred again today, without the prop plug connected, but it was a little different. It hung for much longer and was not consistent like the video example. I did not comment out the serial code yet as I wanted to see if it would occur without the prop plug and it did as confirmed this morning.

    It came back on its own also. I tried to pull my phone out to time how long it would take in between when it stopped and when it started (as I was driving) and see if it was ~53 seconds, but it did not happen again after I had my stop watch application ready. I'm hoping I'll be able to catch it on the way home, and if not I will comment out the serial code after I get home.

    Do you have a code example to test if rx is high?

    Thanks
  • T ChapT Chap Posts: 4,223
    edited 2015-01-08 09:02
    Without spending time with your entire code it is all guessing to solve this. You don't have any roller over code to prevent a glitch if it catches the initial cnt right before rolling over to positive. So the odds are that once in a while you will have the rare glitch. That may not result in a 50+ second delay. You also may have other noises throwing off the circuitry. You have sparkplugs, alternators etc that are putting a lot of noise into the system. With enough noise, your crystal could be going crazy with noise causing the clock to go crazy, and a while the clock is not at full speed it could be slowing down. You could have other sensors acting up or locking up due to noise or connection problems. You do have vibration as a factor with your board, and connections are a place to consider. As far as having the Prop plug not plugged in, if the code is not receiving any data or waiting on any data, then I wouldn't be concerned about the Rx pin. IF the Rx pin does wait for data from the serial terminal or other, and it is unplugged, then that is a consideration. If you had a data logger of some sort, SD card etc, then you could log events to the card such as errors with or without a time stamp, then put in some code to assist in tracking down strange behavior. Without having the sensors, schematic, and code, I can't offer advice on where to start with logging errors. I have a systems that logs all potential hangups. Then it displays the last 5 errors. If it hangs up, I have a piezo speaker beep a number of beeps that indicates the number of the error. This way, it is very easy to count the beeps and see where the code is stuck. In your case, the more methods of feedback the better. A piezo is cheap and ultra easy to use. I even create varying beep sequences ( Rise tone, Dive tone, steady beep, different frequency beeps.,etc ) that allow you to know where the code is. The Parallax 2 line LCD is very easy to add for feedback if you need extra visual indicators, but it seems like you already have a display of some sort that could be used for showing what is going on in code. Testing in an environment away from the car and it's noises may help indicate if it is noise related. Hope this helps.


    If ina[rxpin] == 1
    'then the pin is high :)
  • RaymanRayman Posts: 14,652
    edited 2015-01-08 11:19
    Can you post your whole code? (The Archive feature in Prop tool is good for this).

    I don't see anything that could be wrong except the last line:
    waitcnt (clkFreqTimes3 + cnt)

    Where is clkFreqTime3 defined?
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2015-01-08 11:30
    To eliminate the spurious FTDI reset problem from consideration, add a 2.2K pullup resistor to P30.

    -Phil
  • turbosupraturbosupra Posts: 1,088
    edited 2015-01-08 12:46
    Here is the entire project, the object is towards the bottom and named "pub coolantPwmOut".

    I've had an extremely hard time getting a consistent PWM signal, which to me seems like it should be extremely simple to get?

    coolantPwmObject5 - Archive [Date 2015.01.08 Time 15.43].zip

    Rayman wrote: »
    Can you post your whole code? (The Archive feature in Prop tool is good for this).

    I don't see anything that could be wrong except the last line:
    waitcnt (clkFreqTimes3 + cnt)

    Where is clkFreqTime3 defined?
  • turbosupraturbosupra Posts: 1,088
    edited 2015-01-08 12:56
    Tchap wrote:
    Without spending time with your entire code it is all guessing to solve this. You don't have any roller over code to prevent a glitch if it catches the initial cnt right before rolling over to positive. So the odds are that once in a while you will have the rare glitch. That may not result in a 50+ second delay. You also may have other noises throwing off the circuitry. You have sparkplugs, alternators etc that are putting a lot of noise into the system. With enough noise, your crystal could be going crazy with noise causing the clock to go crazy, and a while the clock is not at full speed it could be slowing down. You could have other sensors acting up or locking up due to noise or connection problems. You do have vibration as a factor with your board, and connections are a place to consider. As far as having the Prop plug not plugged in, if the code is not receiving any data or waiting on any data, then I wouldn't be concerned about the Rx pin. IF the Rx pin does wait for data from the serial terminal or other, and it is unplugged, then that is a consideration. If you had a data logger of some sort, SD card etc, then you could log events to the card such as errors with or without a time stamp, then put in some code to assist in tracking down strange behavior. Without having the sensors, schematic, and code, I can't offer advice on where to start with logging errors. I have a systems that logs all potential hangups. Then it displays the last 5 errors. If it hangs up, I have a piezo speaker beep a number of beeps that indicates the number of the error. This way, it is very easy to count the beeps and see where the code is stuck. In your case, the more methods of feedback the better. A piezo is cheap and ultra easy to use. I even create varying beep sequences ( Rise tone, Dive tone, steady beep, different frequency beeps.,etc ) that allow you to know where the code is. The Parallax 2 line LCD is very easy to add for feedback if you need extra visual indicators, but it seems like you already have a display of some sort that could be used for showing what is going on in code. Testing in an environment away from the car and it's noises may help indicate if it is noise related. Hope this helps.


    If ina[rxpin] == 1
    'then the pin is high

    Do you have any thoughts on how to isolate the prop from the automotive noise? I'd love to know more about the logging system you have. I was trying to do my best to do something similar with the LED's, but they don't make an audible noise of course, and I can't look at them all of the time while driving. I have not ever had any errors when bench testing, and I did that for quite some time.


    To eliminate the spurious FTDI reset problem from consideration, add a 2.2K pullup resistor to P30.

    -Phil

    Thanks, I will add this
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2015-01-08 15:44
    Actually, put pull-ups on both P30 and P31. The one on P31 will keep the FTDI chip powered even if you send data out of P30.

    -Phil
  • T ChapT Chap Posts: 4,223
    edited 2015-01-08 16:09
    turbosupra wrote: »
    This occurred again today, without the prop plug connected


    Phil, he mentions that he is using a Prop Plug. So he may not have an FTDI connected if I understand this right. I am not sure what the board is, but on some schematics that use the Prop Plug there is no pull up/down on the Reset input. However, that being said there is apparently no reset occurring based on the LED indicators that would suggest a real reset.

    It would be helpful to see schematics and a photo of the installation.

    Don't you have a display of some sort on this gadget? If so, how about add some debug text to it. For one, everytime you boot the device, have it read a stored value in the upper region of your eeprom that is used to store a counter. The counter can be a byte length. So, on boot, read the count, then display the count on your screen. Then increment the count and save it back to the same location. This way, you can pay have a running total of each boot up. Each time you manually boot the system up, take note of the most recent count, then check it periodically to see if it changed. Radio shack sells a piezo buzzer. Put in on a pin and get the Synth Freq object, set it to about 2k and have it buzz on bootups. It may not be very loud, so try changing the frequency starting at 1k up to 2k in increments of 100 to find the loudest volume it can produce.
    CON
        'i2c1 address list
        EEPROM1 = %1010_000_0     '$A0   24CL256/512   device type + 3 user bits address + read/write read = 0 write = 1
    
    OBJ
      i2c1         : "CLEAN_minimali2cdriversmallnew
    
    VAR
       Byte  BootupCount
    
    PUB Start  |  thecount  ' your top method
        thecount :=  ReadPage(EEPROM1, $7fff, @BootupCount,1)
        Display(thecount)  ' how you display a value
        BootupCount++
        WritePage(EEPROM1, $7fff, @BootupCount,1) 
    
    
    
    PUB ReadPage(devid, address, pointer, count)           'boot eeprom $A0
        i2c1.ReadPage(28, devid, address, pointer, count)    '$7000test
        return  pointer
    
    PUB WritePage(devid, address, pointer, count)
        i2c1.Writepage(28, devid, address, pointer, count)
        waitcnt(clkfreq/200 + cnt)
    
    
  • turbosupraturbosupra Posts: 1,088
    edited 2015-01-09 06:21
    I do not have a display on it unless I'm driving around with the laptop, but it sounds like I need one. I guess I will purchase the Parallax 2 line LCD for debugging and mount it in the vehicle. Do you have any suggestions or techniques for filtering out the electrical noise? I noticed a lot of electrical noise on the circuit last night and I'd like to address that asap.

    JonnyMac has told me recently that I should have a dedicated comm method and I'm integrating that into my new code, but this object was written before that, but I'm migrating the debug code to its own cog and method. I'm sure there are more experienced (read as better) ways to do this, but this is the format I have so far with each object setting the debug value and then setting the Update variable to true after it has changed the value.

    I have a schematic at home and I'll grab a photo of it as well and send it to you.
    PUB Comm
    
    
      repeat
    
    
        if (coolantPwmCommUpdate == true)
          debug.str(coolantPwmDebugValue1)
          debug.tx(13)
          debug.str(coolantPwmDebugValue2)
          debug.tx(13)
          coolantPwmCommUpdate := false  
          
        if (calculateRpmCommUpdate == true)
          debug.str(calculateRpmDebugValue1)
          debug.tx(13)
          debug.str(calculateRpmDebugValue2)
          debug.tx(13)
          calculateRpmCommUpdate := false
    
        if (airPumpControlCommUpdate == true)
          debug.str(airPumpControlDebugValue1)
          debug.tx(13)
          debug.str(airPumpControlDebugValue2)
          debug.tx(13)
          airPumpControlCommUpdate := false
    
        if (shiftCommUpdate == true)
          debug.str(shiftDebugValue1)
          debug.tx(13)
          debug.str(shiftDebugValue2)
          debug.tx(13)
          shiftCommUpdate := false      
    
        if (liftCommUpdate == true)
          debug.str(liftDebugValue1)
          debug.tx(13)
          debug.str(liftDebugValue2)
          debug.tx(13)
          liftCommUpdate := false
              
        if (o2SensorCommUpdate == true)
          debug.str(o2SensorDebugValue1)
          debug.tx(13)
          debug.str(o2SensorDebugValue2)
          debug.tx(13)
          o2SensorCommUpdate := false
    
        
    
  • RaymanRayman Posts: 14,652
    edited 2015-01-09 07:20
    I still don't see why the program should behave differently with or with out the Prop Plug...

    I think it has to be something wrong with the reset circuit, maybe getting noise somehow...
  • turbosupraturbosupra Posts: 1,088
    edited 2015-01-09 07:29
    Any suggestions on how to clean that up? I'm not seeing the prop itself reset because it would flash the LED a certain sequence upon that happening, but as for the cnt/timer/crystal getting hosed, I'd like to install circuitry to prevent that. I have guesses at maybe putting high value pull downs on the power signals, or additional caps to filter, but they are just guesses.


    Rayman wrote: »
    I still don't see why the program should behave differently with or with out the Prop Plug...

    I think it has to be something wrong with the reset circuit, maybe getting noise somehow...
  • RaymanRayman Posts: 14,652
    edited 2015-01-09 10:35
    Can you try your code using RCFast mode at 20 MHz? That doesn't use the crystal...
  • turbosupraturbosupra Posts: 1,088
    edited 2015-01-12 06:22
    Does this
    con { timing }
    
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000                                          ' uses 5mHz crystal
    

    become this? I've never used anything but 80mhz before.
    con { timing }
    
      _xinfreq = 20_000_000                                          ' uses internal crystal
    
    Rayman wrote: »
    Can you try your code using RCFast mode at 20 MHz? That doesn't use the crystal...
  • RaymanRayman Posts: 14,652
    edited 2015-01-12 07:05
    just do "_clkmode = rcfast" and remove "_xinfreq"

    But looking at the manual, I see this is 12 MHz, not 20 MHz. I'm not sure if your code will work with such a slow clock or not...
    You might have to reduce your serial terminal speed or something like that...
  • PublisonPublison Posts: 12,366
    edited 2015-01-12 07:08
    You could actually leave it blank as RCFAST is the default setting at power-up
    RCFAST ~12 MHz Internal No external parts. May range from 8 MHz to 20 MHz.
    This sets the clock mode for the internal, fast RC Clock/Oscillator circuit. The System Clock would run at approximately 12 MHz with this setting. The RCFAST setting is the default setting, so if no _CLKMODE was actually defined, this is the setting that would be used. Note that the Clock PLL can not be used with the internal RC Clock/Oscillator.
  • turbosupraturbosupra Posts: 1,088
    edited 2015-01-12 19:08
    Is there a hardware solution to cleaning up the input power signals and to isolating the crystal from interference?

    Changing the clkfreq caused a lot of things to hiccup.
  • RaymanRayman Posts: 14,652
    edited 2015-01-13 14:20
    Is this a Parallax board or your own? A Parallax board should not be showing this behavior, unless something is really wrong.

    The only affect that I see happening by hooking up a Prop Plug is that you are basically adding an antenna to your board...
    If you don't have good capacitor bypassing of the power supplies or if you have long leads on your crystal, then maybe there could be problems...

    I'd try adding ceramic capacitors between +3.3 V and GND with short leads to the Prop chip. If this is a DIP version, you need this on both sides of the chip.
    Also, double check your crystal connections and keep the leads as short as possible.
  • turbosupraturbosupra Posts: 1,088
    edited 2015-01-15 12:45
    This is my own breadboard.

    I will try this, thank you very much.

    Rayman wrote: »
    Is this a Parallax board or your own? A Parallax board should not be showing this behavior, unless something is really wrong.

    The only affect that I see happening by hooking up a Prop Plug is that you are basically adding an antenna to your board...
    If you don't have good capacitor bypassing of the power supplies or if you have long leads on your crystal, then maybe there could be problems...

    I'd try adding ceramic capacitors between +3.3 V and GND with short leads to the Prop chip. If this is a DIP version, you need this on both sides of the chip.
    Also, double check your crystal connections and keep the leads as short as possible.
  • RaymanRayman Posts: 14,652
    edited 2015-01-15 14:14
    Ok, on a breadboard I'd also add a 100uF electrolytic capacitor and/or a couple 10uF tantalum capacitors to the 3.3 V supply.
  • T ChapT Chap Posts: 4,223
    edited 2015-01-15 14:27
    You can forget about a breadboard working in this environment
  • RaymanRayman Posts: 14,652
    edited 2015-01-15 19:43
    The DIP version of Propeller is actually impressively forgiving on a breadboard... I did a number of very bad things and had the Prop survive. For some reason, I think the Dip version is actually more resilient than the other versions.
    Still, you have to remember to add some capacitors, or strange things will happen...

    The one thing you can't do is put 5 V directly on any pin. This seems to always kill the PLL...
Sign In or Register to comment.