Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 14 of 14

Thread: Teensy 3.2 Sensor Reading Issues

  1. #1

    Teensy 3.2 Sensor Reading Issues

    Hello All,

    I'm attempting to read a sensor value with a digital pin on a Teensy 3.2. This sensor value is a Variable reluctance sensor in an automotive transmission. Here are the waveforms on my oscilloscope, both at once:

    https://i.imgur.com/YzvjOrI.jpg

    Here is the filtered square wave, which runs through an op amp circuit. This is probed as it would be received by the Teensy 3.2:

    https://i.imgur.com/wkjfOGR.jpg


    Here is my sensor read function, which is supposed to increment an unsigned long variable each time a high is detected:

    https://i.imgur.com/YQ2LVd1.jpg

    Here is the main loop code. The sample value is 250MS. I'm trying to take a differential of the sensor count every 250MS. That differential is used to derive an RPM/Roadspeed:

    https://i.imgur.com/ifG6ogo.jpg

    The problem I am having is that the differential gets SMALLER as the driveshaft spins. This should be opposite.. To make it worse, it normalizes somewhere around 10MPH. I've taken a few pics with the actual calibrated roadspeed in the background and the Teensy serial data on the laptop screen. You can see the roadspeed value, which is just the current count of highs minus the last count 250ms earlier, gets smaller as the speed of the driveshaft increases. Is there something wrong with my code? Is there a special way the teensy needs to read these values?

    I previously had an arduino uno reading these pulses just fine.

    Mostly working at this specific speed:
    https://i.imgur.com/ktMjEyV.jpg

    Completely broken as speed increases:
    https://i.imgur.com/B4HdrKm.jpg

  2. #2
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,382
    your selective snippets of code are insufficient. They do not show variable declarations, how timing is managed ... can you not paste in your full sketch (or a working subset that demonstrates the problem). on this forum go to Advanced and use the # (code tags) to encapsulate your pasted sketch. indentation will be retained if you use the code tags. jpg's of your code makes it hard for others to run/test your sketch.

    In going from UNO to T3.2, int's are 32 bits, and the MCU runs 6 times as fast, ...

  3. #3
    Quote Originally Posted by manitou View Post
    your selective snippets of code are insufficient. They do not show variable declarations, how timing is managed ... can you not paste in your full sketch (or a working subset that demonstrates the problem). on this forum go to Advanced and use the # (code tags) to encapsulate your pasted sketch. indentation will be retained if you use the code tags. jpg's of your code makes it hard for others to run/test your sketch.

    In going from UNO to T3.2, int's are 32 bits, and the MCU runs 6 times as fast, ...
    Setup and loop:
    Code:
    //====================
    //Variables
    //====================
    
    //Pins
    const byte RoadspeedPin = 2;
    const byte Solenoid1Pin = 3;
    const byte Solenoid2Pin = 4;
    const byte Solenoid3Pin = 5;
    const byte BrakePin = A1;
    const byte ThrottlePin = A0;            //Digital 20 - 3.3v
    
    //Calculation Constants
    //=====================
    
    //Multipliers
    const float speedoMulti = 0.00580486;    //MPH Slope Multiplier
    const float throttleMulti = 0.064601;   //Throttle Slope Multiplier
    
    //Shift Adjustments
    const int accelLimit = 128;             //Roughly 3 MPH
    
    //Shift Points
    const int shiftPoint1 = 512;
    const int shiftPoint2 = 1024;
    const int shiftPoint3 = 2048;
    const int tcLockPoint = 1728;           //40 MPH
    
    //Throttle Min-Max
    const int throttleMin = 0;
    const int throttleMax = 100;
    
    //Brake Min-Max
    const int brakeMin = 0;
    const int brakeMax = 100;
    
    //Brake Switch Constant Adjustments
    const int brakeSensitivity = 84;                 //0-100%
    const unsigned long brakeDelayAdj = 2000;        //Wait 2 seconds
    const unsigned long debounceDelay = 100;         //100 MS debounce delay for brake switch
    
    //Non-Static Variables
    //====================
    
    //Switch Debouncing
    unsigned long lastDebounceTime = 0;      //Last time switch was toggled
    
    //Outputs
    boolean Solenoid1 = false;
    boolean Solenoid2 = false;
    boolean Solenoid3 = false;
    
    //Outputs from Functions
    float MPH = 0.0;                //Roadspeed in Miles Per Hour for Serial Data
    byte ActiveGear = 4;            //Start in 4th gear for safety
    boolean TorqueConverter = 0;    //Status of torque converter - starts unlocked
    
    //Inputs
    int Throttle = 0;                //0-100%
    boolean BrakeSwitch = 0;         //0-100%
    unsigned long Roadspeed = 0;     //Total Pulses
    
    //Real Time Adjustments
    unsigned int shiftPoint1Adj = shiftPoint1;
    unsigned int shiftPoint2Adj = shiftPoint2;
    unsigned int shiftPoint3Adj = shiftPoint3;
    unsigned int tcLockPointAdj = tcLockPoint;
    int accelerationModifier = 0;               //If Acceleration is positive or negative, this value is modified by a constant to change up and down shift points
    float ThrottleModifier = 0;                 //As the throttle changes from 0-100, this value is modified by a constant non-linear function to change up and down shift points
    
    //Differential Calculation
    //State Change Variables
    boolean pulseState = false;
    boolean roadspeedState = 0;                 //Is the roadspeed sensor state HIGH or LOW?
    boolean lastRoadspeedState = 0;             //What was the last state of the roadspeed sensor?
    boolean sensorState = false;
    boolean lastSensorState = false;
    
    //Pulse Differential
    unsigned long cycleTimeCurrent = 0;
    unsigned long cycleTimeLast = 0;
    unsigned long cycleTime = 0;
    
    //Acceleration Differential
    int RoadspeedPrevious = 0;                  //0-100 MPH
    int RoadspeedDifferential = 0;              //Positive or Negative Integer for acceleration logic
    
    //Total Differential Calculation
    unsigned long RoadspeedTotalCurrent = 0;
    unsigned long RoadspeedTotalPrevious = 0;
    
    //Brake Switch
    int brakeRead = 0;
    boolean brakeOn = 0;
    boolean brakeOnLast = 0;
    boolean brakeDelay = 0;
    unsigned long brakeTimer = 0;
    
    //Timing
    elapsedMillis sinceUpdateStates;
    
    
    //Timing Delays
    const int sampleTimeValues = 250;         //Refresh Delay in Milliseconds
    
    void setup()
    {
      //Set Input Pin States
      pinMode(RoadspeedPin, INPUT);
    
      //Set Output Pin States
      pinMode(Solenoid1Pin, OUTPUT);
      pinMode(Solenoid2Pin, OUTPUT);
      pinMode(Solenoid3Pin, OUTPUT);
    
      //Begin Serial
      Serial.begin(115200);
    }
    
    void loop()
    {
    //Instantaneous Response Functions
      roadspeedReadAlt();    //Poll Roadspeed Sensor Pin and count pulses
      brakeControl();     //Poll Brake Switch Pin and apply debouncing and delay
      
      if (sinceUpdateValues >= sampleTimeValues)
      {
        //Differentials
        //Roadspeed Differential
        Roadspeed = RoadspeedTotalCurrent - RoadspeedTotalPrevious;
        RoadspeedTotalPrevious = RoadspeedTotalCurrent;
    
        //Roadspeed Accceleration
        RoadspeedDifferential = Roadspeed - RoadspeedPrevious;
        RoadspeedPrevious = Roadspeed;
    
        MPH = speedoMulti * Roadspeed;
    
        //Main Ordered Functions
        throttleControl();
        checkAcceleration();
        ShiftPositionUpdate();
        ShiftGearUpdate();
        TorqueConverterUpdate();
        setShiftSolenoids();
        //activateShiftSolenoids();
        //SerialOutput();
    
        //Reset Data Timer Differential
        sinceUpdateValues = 0;
      }
    }

    Relevant sensor code:

    Code:
    void roadspeedReadAlt()
    {
      //Read sensor
      sensorState = digitalReadFast(RoadspeedPin);
    
      //When the first high pulse is encountered, set the pulse state to high.
      if (sensorState != lastSensorState)
      {
        lastSensorState = sensorState;
    
        // if the state has changed, increment the counter
        if (sensorState == HIGH)
        {
          RoadspeedTotalCurrent++;
        }
      }
    }
    
    
    //NOT CURRENTLY USED
    void roadspeedRead()
    {
      //Count Sensor Pulses
      sensorState = digitalReadFast(RoadspeedPin);
    
      if (sensorState == HIGH && pulseState == false)
      {
        pulseState = true;
    
    
        
        RoadspeedTotalCurrent++;
      }
      else if (sensorState == LOW)
      {
        pulseState = false;
      }

  4. #4
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,382
    Your sketch works for me, after commenting a few things out and running a PWM at 8000 hz on pin 23 jumpered to your pin 2, and printing Roadspeed and MPH every few seconds.
    Code:
    2000 11.609720 mph
    2000 11.609720 mph
    2000 11.609720 mph
      and at 16000 hz (redline!)
    4000 23.219440 mph
    4000 23.219440 mph
    4000 23.219440 mph
    changing the PWM frequency changes those printed values as one would expect.

  5. #5
    Quote Originally Posted by manitou View Post
    Your sketch works for me, after commenting a few things out and running a PWM at 8000 hz on pin 23 jumpered to your pin 2, and printing Roadspeed and MPH every few seconds.
    Code:
    2000 11.609720 mph
    2000 11.609720 mph
    2000 11.609720 mph
      and at 16000 hz (redline!)
    4000 23.219440 mph
    4000 23.219440 mph
    4000 23.219440 mph
    changing the PWM frequency changes those printed values as one would expect.
    Yet it doesn't work in real life. The teensy is unable to read that square wave apparently. Is there a different way I'm supposed to be filtering it? Should I debounce the wave?

    Why is half the wave filled in?

    Here is the op amp circuit I'm using to generate the square wave:

    https://i.imgur.com/NS9NZab.png

  6. #6
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,382
    Quote Originally Posted by BabySpinach View Post
    Yet it doesn't work in real life. The teensy is unable to read that square wave apparently. Is there a different way I'm supposed to be filtering it? Should I debounce the wave?

    Why is half the wave filled in?

    Here is the op amp circuit I'm using to generate the square wave:

    https://i.imgur.com/NS9NZab.png
    The EE's will have to answer your electrical questions. though if you are working with 5v logic, and though the T3.2 is 5v-tolerant, it operates with 3.3v, so if voltage is only dropping to 2+ v, then T3.2 would read it as HIGH, where as UNO would see it as LOW ...

    You could confirm that your shaft RPM from pin 2 is good. Does it increase monotonically with throttle? you have other functions (not shown) that would affect MPH value, and their calculations could have some UNO-bias ... Maybe your earlier data does show that Roadspeed (which i assume is drive shaft speed) is misbehaving.
    Last edited by manitou; 09-19-2017 at 07:26 PM.

  7. #7
    Quote Originally Posted by manitou View Post
    The EE's will have to answer your electrical questions. though if you are working with 5v logic, and though the T3.2 is 5v-tolerant, it operates with 3.3v, so if voltage is only dropping to 2+ v, then T3.2 would read it as HIGH, where as UNO would see it as LOW ...

    You could confirm that your shaft RPM from pin 2 is good. Does it increase monotonically with throttle? you have other functions (not shown) that would affect MPH value, and their calculations could have some UNO-bias ... Maybe your earlier data does show that Roadspeed (which i assume is drive shaft speed) is misbehaving.
    I talked to an EE at work and he believes the hysteresis needs to be adjusted. I'm going to try a different resistor next to my pot and see if I can get a better result.

    The shaft RPM reading is direct. The roadspeed value in the code is used to calculate other values, but not vice versa. I've never ran this program on the Uno. I had a 10v version of the circuit built and running on the Uno, but it tied back into an existing trans control unit. The scope data shows a very consistent waveform from the sensor.

  8. #8
    Senior Member
    Join Date
    May 2017
    Posts
    208
    What is the shading on the square wave? It looks like a high frequency oscillation to me. I think you need to fix that before anything else.

  9. #9
    Quote Originally Posted by rcarr View Post
    What is the shading on the square wave? It looks like a high frequency oscillation to me. I think you need to fix that before anything else.
    Last night I attempted to fix the oscillation by changing my resistor values in my Schmitt trigger. My R1 value is soldered in as 510 ohms. The R2 value was 115000 ohms. I was able to completely eliminate the rising oscillation by using a 2.2k resistor. I tried dozens of resistors and this was the best I could get it:

    https://i.imgur.com/6QioRb0.jpg

    Now you see there is falling edge oscillation.. Not sure what I have to do now.. Perhaps change the R1 value from 510 to something else?

    The current math gives:
    2200/(2200+510)*3.3=2.678V crossing, I think??

  10. #10
    Senior Member
    Join Date
    May 2017
    Posts
    208
    I would try removing the two zeners from the circut by lifting one end. I don't see what their purpose is and it seems they could couple some signal into the active ground. I would also try not using an active ground and connect your 2.5 volts node to the junction of the 824 ohm resistors instead of the output of the op-amp.

  11. #11
    Unfortunately, I cannot read the text or values in the schematic. But, since a non-inverting amplifier cannot have a gain of less than one, I assume system gain to be > 1.

    Based on the above assumption and the raw signal, I don't understand the circuit whatsoever. What is a gain block doing in there? The oscillations appear in the zero voltage range of the input, a range which should be ignored. It's looks to me to be doing exactly what is expected when the input is floating around zero volts.

    Unless the duty cycle is meaningful, I would imagine you'd get a cleaner output with a comparator.

    Also, as a side note, having only a trim pot as the sole resistance in a feedback loop, especially in a automotive circuit can be a nasty source of instability. Ideally the pot value should be 10% or less of the total resistance.

  12. #12
    Quote Originally Posted by aFewBits View Post
    Unfortunately, I cannot read the text or values in the schematic. But, since a non-inverting amplifier cannot have a gain of less than one, I assume system gain to be > 1.

    Based on the above assumption and the raw signal, I don't understand the circuit whatsoever. What is a gain block doing in there? The oscillations appear in the zero voltage range of the input, a range which should be ignored. It's looks to me to be doing exactly what is expected when the input is floating around zero volts.

    Unless the duty cycle is meaningful, I would imagine you'd get a cleaner output with a comparator.

    Also, as a side note, having only a trim pot as the sole resistance in a feedback loop, especially in a automotive circuit can be a nasty source of instability. Ideally the pot value should be 10% or less of the total resistance.
    Could you expand a bit? I thought this was a comparator?

    I've since updated by removing the pot completely and putting in a solid resistor. However, the falling edge of the square wave is wacko. It's been suggested to me to remove my clipping zeners (which I don't understand why I'd want to do that), and to use a very small capacitor to ground to smooth the waveform. What I'd like to try is an adjustable lower threshold on my schmitt trigger, but I haven't been able to do any testing or find a good schematic. Since I'm just guessing, i think I'm going to rip out my 510 ohm resistor and create an additional voltage bridge at that point and play with the values.

    I tried searching for some kind of references on what causes distortion at certain points in waveforms, but wasn't finding much.

    My current resistor values are 510 to the +, and 2200 from the + to the output. This yields the most stable waveform yet, except for the huge bit of distortion in the picture at the end.

  13. #13
    Junior Member
    Join Date
    Mar 2015
    Location
    Sewickley, PA
    Posts
    11
    I have used this board with sucess. I still need to put a resistor across VR Sensor wires occasionally to get 100 % reads. http://jbperf.com/dual_VR/v2_1.html
    Mark

  14. #14
    I've now had a chance to look at the schematic on a real computer and actually see the schematic markings and values. I was wrong about the gain block. Yes, you have the second stage wired as a comparator but using an LM324, when actually tested, shows results far from the expected.

    After studying the waveform and doing some breadboarding, my conclusion is that any configuration of comparator is unsuited to convert that waveform to a usage digital signal. You simply cannot get an output with anything approaching a 50% duty cycle squarewave, the input signal doesn't allow it.

    While you might be able to cobble something together with a comparator that provides perhaps a 20/80% duty cycle, I'd opt for a purpose built device. As K3FY points out above, there are modules specifically built for the VR sensors. I'd think that's well worth the expense, given the cost of time. The other option would be to just buy the correct IC to do the job. Googling "Variable Reluctance Sensor Amplifier" turns up scads of devices from Maxim, OnSemi, TI and others I'm sure, automotive products are a big market for the chip guys.

    Just for reference, here is a reference circuit from Analog Devices for a single voltage comparator. If you want to avoid the math exercise, it's easiest to think of Vthreshold as centered around Vref and the higher the ratio of R4 to R3, the smaller the delta threshold. The takeaway for me was that setting Vref to 1/2 vcc is the worst possible threshold for the input waveform.
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	Screen Shot 2017-09-21 at 3.21.22 PM.jpg 
Views:	49 
Size:	68.6 KB 
ID:	11585  
    Last edited by aFewBits; 09-22-2017 at 05:35 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •