Shop OBEX P1 Docs P2 Docs Learn Events
At a loss as to how to code for this — Parallax Forums

At a loss as to how to code for this

turbosupraturbosupra Posts: 1,088
edited 2010-08-04 00:17 in Propeller 1
I keep having erroneous values trying to measure the rpms in my car.

The ecu pulses a 'high' 2 times per revolution

My problem is that when I am starting the car/cranking I am getting erroneous values and I am not sure as to why?

The design of the code is to measure two 'high' values, subtract the time it took in between them and use that value to calculate the rpms. How can I differentiate between cranking and the car running? Especially if I'm getting erroneous values?








PUB Measure_rpm
  'WAITPEQ (State, Mask, Port)
  dira[noparse][[/noparse]15] := 1


  repeat

  
    'sync with transition low-high
    WaitPeq(0                    , |< c_EngineRunningPin,0) 'wait for pin low

    'now we are synced
    WaitPeq(|< c_EngineRunningPin, |< c_EngineRunningPin,0) 'wait for pin high
    leadingEdgeSnapShot1 := cnt
    outa[noparse][[/noparse]15] := 1

    WaitPeq(0                    , |< c_EngineRunningPin,0) 'wait for pin low
    WaitPeq(|< c_EngineRunningPin, |< c_EngineRunningPin,0) 'wait for pin high
    leadingEdgeSnapShot2 := cnt
    
   

    rpmtime := leadingEdgeSnapShot2 - leadingEdgeSnapShot1
      Debug.Str(string("rpmtime = "))
      Debug.Dec(rpmtime)
      Debug.Tx(13)
         
    rpms := (((clkfreq/rpmtime) * 60) / 2) ' there are 2 pulses per revolution 
   
    







Serial Out Application said...


rpmtime = 1842070832
rpmtime = 403568
rpmtime = 403568
rpmtime = 403568
rpmtime = 403568
rpmtime = 39392
rpmtime = 403568
rpm in lift=5940 <
Here is where the code called another function because of an erroneous value that calculated the rpms to 5940, while cranking the car over
You are in lift!!!!!!!
rpmtime = 403568
rpmtime = 403568
rpmtime = 403568
rpmtime = 5238384
rpmtime = 403568
rpmtime = 403568
rpmtime = 403568
rpmtime = 3023248

Comments

  • ElectricAyeElectricAye Posts: 4,561
    edited 2010-07-29 02:46
    Are you using the car's electrical system for a power supply? I've heard lots of people on the forum weep about the dangers of spikes, etc. coming through the auto electrical system and messing up their Propellers.
  • Timothy D. SwieterTimothy D. Swieter Posts: 1,613
    edited 2010-07-29 05:37
    are you having roll over or odd subtractions/additions creating your large and small numbers? Perhaps some counter of buffer rollover that isn't be accounted for properly?

    Another idea is to add a low pass filter of sorts in software. How often are you getting readings?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Timothy D. Swieter, P.E.
    www.brilldea.com - Prop Blade, LED Painter, RGB LEDs, 3.0" 16:9 LCD Composite video display, eProto for SunSPOT, PropNET, PolkaDOT-51
    www.tdswieter.com
  • turbosupraturbosupra Posts: 1,088
    edited 2010-07-29 11:14
    @ Electric Eye

    Yes I am

    It does not cause a problem otherwise, so I'm inclined to think it is ok. I've also used the power supply to the factory ecu, which I believe is already filtered based on the wiring diagrams.

    Any idea on how to code for my different situations?



    @ Timothy

    It happens every time I try and start the car, so I don't think it is rollover related
  • bill190bill190 Posts: 769
    edited 2010-07-29 11:58
    Place a voltmeter on your power while starting the car. Might need to use an old fashioned analog (needle) meter to see what is going on if it starts quickly.

    The starter can cause the voltage to go quite low!

    Might try using a separate power source to see if the problem goes away.

    Then I don't know if a diode and large capacitor would allow the Propeller voltage to remain high while the vehicle voltage temporarily dips low during starting?
  • Timothy D. SwieterTimothy D. Swieter Posts: 1,613
    edited 2010-07-29 12:03
    Right - the problem only happens when starting the car? Then I agree with you. Sounds like a low pass filter or just not try to check RPM while starting the car. I know very little about car electronics, but maybe you can get a ignition or cranking signal from the ECU or maybe there is something on the CANbus that tells you the car is starting.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Timothy D. Swieter, P.E.
    www.brilldea.com - Prop Blade, LED Painter, RGB LEDs, 3.0" 16:9 LCD Composite video display, eProto for SunSPOT, PropNET, PolkaDOT-51
    www.tdswieter.com
  • turbosupraturbosupra Posts: 1,088
    edited 2010-07-29 13:11
    I can try this, I don't have the ability to use a separate power source though.

    I'm hoping there is a software solution that a more experienced coder could suggest?


    bill190 said...
    Place a voltmeter on your power while starting the car. Might need to use an old fashioned analog (needle) meter to see what is going on if it starts quickly.

    The starter can cause the voltage to go quite low!

    Might try using a separate power source to see if the problem goes away.

    Then I don't know if a diode and large capacitor would allow the Propeller voltage to remain high while the vehicle voltage temporarily dips low during starting?
  • turbosupraturbosupra Posts: 1,088
    edited 2010-07-29 13:26
    Any idea what the coding logic would be behind this?


    Basically the car does not idle at less than 400rpms, so =< 400rpms means the car is off or cranking over. 500rpms is 16.67 pulses per second from the hall effect magnetic sensor.

    It appears that my problem is that sometimes the magnetic sensor gets stuck on a "high" when the car turns off.


    I believe I need a wrapper for the repeat loop code that is shown above, something that that does not allow the repeat loop to run until it sees 17 pulses in a clkfreq. What do you think? Or something that is a running average?



    Timothy D. Swieter said...
    Right - the problem only happens when starting the car? Then I agree with you. Sounds like a low pass filter or just not try to check RPM while starting the car. I know very little about car electronics, but maybe you can get a ignition or cranking signal from the ECU or maybe there is something on the CANbus that tells you the car is starting.
  • magdropmagdrop Posts: 13
    edited 2010-07-29 13:40
    How is the Hall effect sensor hooked in?·· I was wondering if maybe the supply to the sensor is dropping out under cranking or something?·· If that's the case a supercap and diode in the supply to the sensor would probably solve it.·
  • turbosupraturbosupra Posts: 1,088
    edited 2010-07-29 15:24
    I'm tapping the sensor after the signal has been processed by the ecu (tachometer out).

    If the sensor was dropping out, the car would not start as I've had it unplugged before, although that was a good idea! I honestly think it's my code, I'm just not sure how to fix it.


    magdrop said...
    How is the Hall effect sensor hooked in? I was wondering if maybe the supply to the sensor is dropping out under cranking or something? If that's the case a supercap and diode in the supply to the sensor would probably solve it.
  • turbosupraturbosupra Posts: 1,088
    edited 2010-07-29 15:31
    Does anyone see any problems with this idea?

    Basically I tried to write a separate piece of code that is as basic as it gets and won't allow the method to enter the rpm calculation code until it sees => 17 pulses per second.

    Thoughts?




    
    
    CON
    
      c_EngineRunningPin = 8
    
    
    
    OBJ
    
      Debug : "FullDuplexSerial"      
    
    
    
    
    VAR
    
      long timeoflastpulse
      long pulsecount
      long leadingEdgeSnapShot1
      long leadingEdgeSnapShot2
      long rpmtime
      long rpms
      long caroff
      
    
    PUB Measure_rpm
      'WAITPEQ (State, Mask, Port)
      dira[noparse][[/noparse]15] := 1
    
      repeat
    
    
        If ina[noparse][[/noparse]c_EngineRunningPin] == 1
          timeoflastpulse := cnt
    
        If ina[noparse][[/noparse]c_EngineRunningPin] == 1 AND cnt =< 79000000
          WaitPeq(0                    , |< c_EngineRunningPin,0)  'wait for pin low
                      
          If ina[noparse][[/noparse]c_EngineRunningPin] == 0 AND cnt =< 79000000
            WaitPeq(|< c_EngineRunningPin, |< c_EngineRunningPin,0)  'wait for pin high
            pulsecount ++  ' pulse count accumulates per pulse for each second
          
          elseif (timeoflastpulse + clkfreq) =< cnt ' if more than 1 second goes by between the time of the last pulse high and current time, pulse count is reset and engine is off
            pulsecount := 0 ' signifies car is off, keeps repeat loop below from running  
            
        elseif (timeoflastpulse + clkfreq) =< cnt ' if more than 1 second goes by between the time of the last pulse high and current time, pulse count is reset and engine is off
          pulsecount := 0 ' signifies car is off, keeps repeat loop below from running
           
        If pulsecount => 17     
           
          repeat while pulsecount => 17
           
           
            'sync with transition low-high
            WaitPeq(0                    , |< c_EngineRunningPin,0) 'wait for pin low
           
            'now we are synced
            WaitPeq(|< c_EngineRunningPin, |< c_EngineRunningPin,0) 'wait for pin high
            leadingEdgeSnapShot1 := cnt
            outa[noparse][[/noparse]15] := 1
           
            WaitPeq(0                    , |< c_EngineRunningPin,0) 'wait for pin low
            WaitPeq(|< c_EngineRunningPin, |< c_EngineRunningPin,0) 'wait for pin high
            leadingEdgeSnapShot2 := cnt
            
           
           
            rpmtime := leadingEdgeSnapShot2 - leadingEdgeSnapShot1
              Debug.Str(string("rpmtime = "))
              Debug.Dec(rpmtime)
              Debug.Tx(13)
                 
            rpms := (((clkfreq/rpmtime) * 60) / 2) ' there are 2 pulses per revolution
    
    
        else
          caroff := true    
           
    
    
    
  • turbosupraturbosupra Posts: 1,088
    edited 2010-07-29 18:04
    How about this logic?

    Psuedocode would be to:

    wait for a high and then a low from the tachometer signal, then to log that time compared to the system count cnt.
    Then increment the variable pulsecount each time the repeat loop sees a high then low as long as timeoflastpulse is less than system cnt + clkfreq
    Once it hits 17 pulses the code has the key to be able to enter the repeat loop where the code calculates actual rpms
    If it does not see a high and then a low within clkfreq+timeoflastpulse then it resets the pulse count to 0, removing the key for it to enter the other loop



    
    
    
    CON
    
      c_EngineRunningPin = 8
    
    
    
    OBJ
    
      Debug : "FullDuplexSerial"      
    
    
    
    
    VAR
    
      long timeoflastpulse
      long pulsecount
      long leadingEdgeSnapShot1
      long leadingEdgeSnapShot2
      long rpmtime
      long rpms
      long caroff
      
      
    
    PUB Measure_rpm
      'WAITPEQ (State, Mask, Port)
      'dira[noparse][[/noparse]15] := 1
    
      pulsecount := 0
      
    
      repeat
    
        waitpeq(%100000, |< 8, 0) 'Wait for Pin 8 to go high
        waitpeq(%000000, |< 8, 0) 'Then wait for Pin 8 to go low
        
        timeoflastpulse := cnt
        
        If (timeoflastpulse + clkfreq) => cnt 
          pulsecount ++
    
           If pulsecount > 10000
             pulsecount := 20       ' resets the count to a value so that it never rolls over, but stays above the entry threshold
         
        else
          pulsecount := 0           ' car is off, resets it so that it cannot enter the other repeat loop
            
    
             
         
         
         
        If pulsecount => 17     
             
            repeat while pulsecount => 17
             
             
              'sync with transition low-high
              WaitPeq(0                    , |< c_EngineRunningPin,0) 'wait for pin low
             
              'now we are synced
              WaitPeq(|< c_EngineRunningPin, |< c_EngineRunningPin,0) 'wait for pin high
              leadingEdgeSnapShot1 := cnt
              'outa[noparse][[/noparse]15] := 1
             
              WaitPeq(0                    , |< c_EngineRunningPin,0) 'wait for pin low
              WaitPeq(|< c_EngineRunningPin, |< c_EngineRunningPin,0) 'wait for pin high
              leadingEdgeSnapShot2 := cnt
              
             
             
              rpmtime := leadingEdgeSnapShot2 - leadingEdgeSnapShot1
                Debug.Str(string("rpmtime = "))
                Debug.Dec(rpmtime)
                Debug.Tx(13)
                   
              rpms := (((clkfreq/rpmtime) * 60) / 2) ' there are 2 pulses per revolution
              caroff := false
              Debug.Str(string("rpms = "))
              Debug.Dec(rpms)
              Debug.Tx(13)
         
        else
          caroff := true     
         
    
         
         
    
    
    
  • David CarrierDavid Carrier Posts: 294
    edited 2010-07-30 00:41
    There was some discussion about the quality of the power supply while the engine is cranking, which does seem pertinent since the voltage on the battery can dip considerably. It usually isn't problem for the ECU's power supply, because it should be designed to work in these conditions. The tachometer signal though, will dip proportionally with the battery. If you buffer the tachometer with an NPN BJT or N-channel MOSFET, you can have it turn on at a relatively low voltage, which will make it immune to changes in the high side of the tachometer pulse. (Although, this may cause problems if the low-side voltage is drifting to high.)

    You may also want to connect an input to check if the key is in the 'start' position, and ignore any tachometer readings until it returns to the 'run' position.

    — David Carrier
    Parallax inc.
  • turbosupraturbosupra Posts: 1,088
    edited 2010-07-30 01:10
    No luck on the software hysteresis, spoke to David at Parallax (Thanks David!) and based on our conversation I'm going to try some hardware hysteresis with a schmidtt trigger ... just not sure how to code for this?


    http://www.mouser.com/ProductDetail/NXP-Semiconductors/74HC7014N112/?qs=sGAEpiMZZMuiiWkaIwCK2RTxPVPWGz6WAK2S899C5/E=


    http://www.nxp.com/documents/data_sheet/74HC7014_CNV.pdf
  • turbosupraturbosupra Posts: 1,088
    edited 2010-07-30 01:14
    Thanks again David.

    There is a starter pin, I will scope that and see what it does and when to see if I can use it.

    David Carrier (Parallax) said...
    There was some discussion about the quality of the power supply while the engine is cranking, which does seem pertinent since the voltage on the battery can dip considerably. It usually isn't problem for the ECU's power supply, because it should be designed to work in these conditions. The tachometer signal though, will dip proportionally with the battery. If you buffer the tachometer with an NPN BJT or N-channel MOSFET, you can have it turn on at a relatively low voltage, which will make it immune to changes in the high side of the tachometer pulse. (Although, this may cause problems if the low-side voltage is drifting to high.)

    You may also want to connect an input to check if the key is in the 'start' position, and ignore any tachometer readings until it returns to the 'run' position.

    — David Carrier
    Parallax inc.
  • JavalinJavalin Posts: 892
    edited 2010-07-30 10:24
    you may also find (if i've read this post correctly) that the ECU is multi-sparking during the start/cranking, to get the engine to start quick and with minimal emmisions. The mk3 Golf's do this i believe, and probably others.

    for rpm counting i've used the formula:

    rpm := 30_000_000 / pulse_length_in_us_between_sparks
    


    to good effect - might be the same as yours - dunno. Also i've implemented a rolling average and filtered data < 3.5ms (~750 rpm) and > 35ms (>10k rpm) to get rid of some of the noise.

    I've been having issues when I changed from a dying Pi RPM pickup to a Stack one - the signal is clean, but with some random pulses - hence the filtering.

    Oh - cranking speed should be < 500 rpm - typically in the 2-300 rpm's as I understand.

    Let us know how you get on

    James
  • turbosupraturbosupra Posts: 1,088
    edited 2010-07-30 13:39
    Hey James

    That's a good point, but I'm tapping the tach signal which is supposed to be filtered from that ignition noise? I've scoped it during cranking and I'm not seeing it fire all over the place? My tach also does not jump all over the place?

    I'm going to work on some code today and see what happens



    Javalin said...
    you may also find (if i've read this post correctly) that the ECU is multi-sparking during the start/cranking, to get the engine to start quick and with minimal emmisions. The mk3 Golf's do this i believe, and probably others.

    for rpm counting i've used the formula:



    rpm := 30_000_000 / pulse_length_in_us_between_sparks 
    
    


    to good effect - might be the same as yours - dunno. Also i've implemented a rolling average and filtered data < 3.5ms (~750 rpm) and > 35ms (>10k rpm) to get rid of some of the noise.

    I've been having issues when I changed from a dying Pi RPM pickup to a Stack one - the signal is clean, but with some random pulses - hence the filtering.


    Oh - cranking speed should be < 500 rpm - typically in the 2-300 rpm's as I understand.

    Let us know how you get on

    James
    Post Edited (turbosupra) : 7/30/2010 3:27:35 PM GMT
  • turbosupraturbosupra Posts: 1,088
    edited 2010-07-31 15:33
    Ok ... big update



    When I run PUB Main and Cognew(PUB Measure_RPM, @RPM_stack[noparse][[/noparse]20]), it works fine

    When I run PUB Main and Cognew(PUB Measure_RPM, @RPM_stack[noparse][[/noparse]20]), along with 5 other Cognew 's I get erroneous values?

    What could cause this?
  • Mike GreenMike Green Posts: 23,101
    edited 2010-07-31 15:45
    PUB Main - one cog
    COGNEW - one cog
    5 other COGNEWs - 5 cogs
    FullDuplexSerial - one cog

    That's 8 out of 8 cogs. Are you using any other cogs implicitly like in some other object?
    Remember that each Spin COGNEW has to have its own private stack area.
  • turbosupraturbosupra Posts: 1,088
    edited 2010-07-31 17:13
    Hi Mike,

    Thank you for the reply.

    Each has its own stack area, I did not know that FullDuplexSerial required a cog though, that is good info. That is the only object I am attaching.

    I will try it now without one of the cogs so that there is 7 total and see how it responds. I guess it is time to start combining things?

    Mike Green said...
    PUB Main - one cog
    COGNEW - one cog
    5 other COGNEWs - 5 cogs
    FullDuplexSerial - one cog

    That's 8 out of 8 cogs. Are you using any other cogs implicitly like in some other object?
    Remember that each Spin COGNEW has to have its own private stack area.
  • turbosupraturbosupra Posts: 1,088
    edited 2010-07-31 19:21
    Ok, I definitely stumbled upon something [noparse]:D[/noparse] ... I know where my interference is coming from!!! [noparse]:D[/noparse]

    I have pin 8 as an RPM input pin

    I have pin 9 as a PWM output pin

    It's oscillation is definitely causing cross talk or interference. How can I shield this or?

    I can move the pin BUT I'd have to have 2 pins on each side that were not used? That can't be the solution?
  • turbosupraturbosupra Posts: 1,088
    edited 2010-08-03 03:10
    No one has any ideas?

    Maybe a pull down resistor, around 1Mohm?
  • ElectricAyeElectricAye Posts: 4,561
    edited 2010-08-03 04:12
    turbosupra said...
    ...I know where my interference is coming from!!! [noparse]:D[/noparse]

    I have pin 8 as an RPM input pin

    I have pin 9 as a PWM output pin

    It's oscillation is definitely causing cross talk or interference. How can I shield this or?...


    Are the wires leading from Pin 8 and Pin 9 bundled with each other? Could you try shielded cable for at least one of those wires?

    Did you test how much crosstalk you're actually getting by perhaps disconnecting whatever is on the ends of Pin 8 and Pin 9 and sending a PWM signal down Pin 9 and seeing if you get the same signal frequency (or maybe a harmonic) read on Pin 8?

    Just thinking out loud here.
  • turbosupraturbosupra Posts: 1,088
    edited 2010-08-03 13:02
    Hi,

    The rpm input is pin 8 and the pwm out is pin 9. I was getting a continuous erroneous value of 5940rpms (while cranking the car over with the cars starter) because of the cross talk with the pwm pin 9. I would consistently see that value of 5940.

    The only shielding I could think to do would be to put a pull down resistor on pin 8? Because it seemed to be between the pins and not the wires themselves, it was very strange! Took me about 3 weeks to figure out that was what was happening.


    ElectricAye said...
    turbosupra said...
    ...I know where my interference is coming from!!! [noparse]:D[/noparse]

    I have pin 8 as an RPM input pin

    I have pin 9 as a PWM output pin

    It's oscillation is definitely causing cross talk or interference. How can I shield this or?...


    Are the wires leading from Pin 8 and Pin 9 bundled with each other? Could you try shielded cable for at least one of those wires?

    Did you test how much crosstalk you're actually getting by perhaps disconnecting whatever is on the ends of Pin 8 and Pin 9 and sending a PWM signal down Pin 9 and seeing if you get the same signal frequency (or maybe a harmonic) read on Pin 8?

    Just thinking out loud here.
  • bill190bill190 Posts: 769
    edited 2010-08-03 13:42
    As a test, you might want to try using a separate Propeller chip for one of the signals.

    Shielded wiring would have aluminum wrapped around the outside like coax cable and grounded at one end.

    On shielding (take apart an old TV or VCR and notice the tuner portion is in a metal can)...

    http://en.wikipedia.org/wiki/Faraday_cage

    On automotive EMI (See EMI)...
    http://magnecor.com/magnecor1/truth.htm
  • ElectricAyeElectricAye Posts: 4,561
    edited 2010-08-03 13:50
    turbosupra said...
    ....Because it seemed to be between the pins and not the wires themselves...

    ...

    Crosstalk between Propeller pins? I haven't heard anyone complain about that one until now. How did you determine that the crosstalk is happening only between the pins and not between the wires? Wires can sometimes act like antennae, you know, inducing signals in each other. But I think for ONLY the pins to crosstalk would mean that signals are leaking through the chip itself or across some bad soldering or something.

    I'm guessing you really need to test your theory about pin-to-pin crosstalk by disconnecting the wires so you know the wires are not part of the situation. As for using a pulldown resistor: I'm certainly no expert in electronics, but I don't see how adding a resistor will shield anything. You need a cable that encloses the internal conductor with an outer conductive material, and that outer conductor needs to be grounded.

    hope that helps,
    smile.gif
  • turbosupraturbosupra Posts: 1,088
    edited 2010-08-04 00:17
    Hmmm,

    I guess it could be the wires as well, I will have to test this.

    The pull down resistor idea was to try and stop false positives from EMI, and allow the pin to only see a 'high' when a reasonable enough amount of current will over come the resistors path to ground
Sign In or Register to comment.