Teensy 3.2 Sensor Reading Issues

Status
Not open for further replies.

BabySpinach

Active member
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
 
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, ...
 
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;
  }
 
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.
 
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
 
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:
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.
 
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.
 
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??
 
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.
 
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.
 
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.
 
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.
 

Attachments

  • Screen Shot 2017-09-21 at 3.21.22 PM.jpg
    Screen Shot 2017-09-21 at 3.21.22 PM.jpg
    68.6 KB · Views: 136
Last edited:
Status
Not open for further replies.
Back
Top