Reading Vehicle Speed sensor

Hi guys i am working on some coding to control the turbo in my truck. I am already reading the commanded pwm duty cycle from the truck pcm using pulseIn and copying it over to the output for some cases. I need to read the vehicle speed sensor from my truck which is 8000 pulses per mile so i can use an if statement. As an example, if truck is over 20 mph stop copying the ford pcm pwm duty cycle and go into arduino pid loop to control the turbo.

What would be the best and easiest way of doing this? I know the sensor is a 0-14V square wave. Would a frequency to voltage convertor be easiest or using another pulseIn function to read the speed sensor as well?

Thanks!

What would be the best and easiest way of doing this?

Hook up some hardware and write some software. There may be other ways, but that will be harder.

I know the sensor is a 0-14V square wave.

Which is a bit outside the 0-5V range of the Arduino.

Would a frequency to voltage convertor be easiest

No. 8000 pulses per mile at 60 miles an hour is 8000 pulses per hour. That's 333 per minute, or just over two per second. That gives the Arduino nearly half a second to do something it can do in a few hundred nanoseconds.

or using another pulseIn function to read the speed sensor as well?

You don't need pulseIn() to read a square wave. An interrupt on a RISING edge (or a FALLING edge) would be one way. Other is to simply poll the pin, and detect the state change (hey, there's an example...).

PaulS:

Would a frequency to voltage convertor be easiest

No. 8000 pulses per mile at 60 miles an hour is 8000 pulses per hour. That's 333 per minute, or just over two per second. That gives the Arduino nearly half a second to do something it can do in a few hundred nanoseconds.

Reminds me of one of my favourite quotes from a science-fiction TV series.

"Mathematics not skill of Zathras."

Mitch, at 60 mph, you will have about 133 pulses per second. They'll be 7.5 milliseconds apart. Depending on what all you are doing, and assuming you don't have a lot of delay() calls, polling might work, but as PaulS suggested, a rising or falling edge interrupt will definitely work.

"Mathematics not skill of Zathras."

Must be Microsoft's calculator. Couldn't be the operator.

PaulS:

"Mathematics not skill of Zathras."

Must be Microsoft's calculator. Couldn't be the operator.

PEBCAK, we used to call it: Problem Exists Between Chair And Keyboard. :~

lar3ry:

PaulS:

“Mathematics not skill of Zathras.”

Must be Microsoft’s calculator. Couldn’t be the operator.

PEBCAK, we used to call it: Problem Exists Between Chair And Keyboard. :~

In the Air Force SBTH (short between the headsets) worked just as well. :wink:

Here is my code that i have written so far. This is my first programming project so please bear with me. As of now i have it set up to read the vehicle speed sensor from a frequency to voltage convertor as i though that would be the simplest. Please look it over and tell me what you think.

Thanks!

#include <PID_v1.h>
#include <PWM.h>
#include <SPI.h>
#include <LiquidCrystal.h>

int32_t frequency = 167; //frequency (in Hz)

const int numReadings= 3;

//duty cycle in measurement
const int pwmIn = 8;
float totaltime = 6000.0;
float dutycycleIn;
unsigned long durationL;
float durationL_readings[numReadings];      
int durationL_index = 0;                  
float durationL_total = 0;                  
float durationL_average = 0; 

//duty cycle out
int dutycycleOut = 0;

//exhaust pressure sensor
int ebp_readings[numReadings];      
int ebp_index = 0;                  
float ebp_total = 0;                  
float ebp_average = 0; 
const int ebp = A0;

//throttle position sensor
int tps_readings[numReadings];      
int tps_index = 0;                  
float tps_total = 0;                  
float tps_average = 0; 
const int tps = A1;

//vehicle speed sensor
int vss_readings[numReadings];      
int vss_index = 0;                  
float vss_total = 0;                  
float vss_average = 0; 
const int vss = A2;

// exhaust brake switch that enables or disabled exhaust brake
const int ebswitch = 12;
int ebswitchvalue = 0;

//pid information
double Setpoint, Input, pidOutput;
PID myPID(&Input, &pidOutput, &Setpoint,1,0,0, DIRECT);

const int pwmOut = 9;
float starttime;
float ebdelay;

// initialize lcd
LiquidCrystal lcd (7, 6, 5, 4, 3, 2);

void setup() {
  pinMode(pwmIn, INPUT);
  pinMode(ebswitch, INPUT);
  pwmWrite(pwmOut, 100);  //testing only
  
  //exhaust pressure sensor
  for (int ebp_thisReading = 0; ebp_thisReading < numReadings; ebp_thisReading++)
    ebp_readings[ebp_thisReading] = 0;
  // duty cycle in measurement
  for (int durationL_thisReading = 0; durationL_thisReading < numReadings; durationL_thisReading++)
    durationL_readings[durationL_thisReading] = 0;
  
  //throttle position sensor
  for (int tps_thisReading = 0; tps_thisReading < numReadings; tps_thisReading++)
    tps_readings[tps_thisReading] = 0;  
 
  //vehicle speed sensor
  for (int vss_thisReading = 0; vss_thisReading < numReadings; vss_thisReading++)
    vss_readings[vss_thisReading] = 0;    

  //initialize all timers except for 0, to save time keeping functions
  InitTimersSafe(); 
  //sets the frequency for pwmOut pin 9
  bool success = SetPinFrequencySafe(pwmOut, frequency);  //change to pwmOut after testing
  //if the pin frequency was set successfully, turn pin 13 on
  if(success) {
    pinMode(pwmOut, OUTPUT);   //change to pwmOut after testing 
  }
  //initialize PID variables
  Input = ebp_average;
  Setpoint = 360;  //test value of 360 = 33 psia or 20 psig
  myPID.SetOutputLimits(39, 115);

  //turn the PID on
  myPID.SetMode(AUTOMATIC);    
  
  // lcd setup
  lcd.begin(16, 2);
  lcd.clear();
  lcd.print("TURBO:");
  lcd.setCursor(0,1);
  lcd.print("EBP:");

}

void loop() {
  //starttime = micros();
  
  //duty cycle in measurement
  durationL_total= durationL_total - durationL_readings[durationL_index];         
  durationL_readings[durationL_index] = pulseIn(pwmIn, LOW); 
  durationL_total= durationL_total + durationL_readings[durationL_index];         
  durationL_index = durationL_index + 1;                    
  if (durationL_index >= numReadings)              
    durationL_index = 0;                           
    
  durationL_average = durationL_total / numReadings; 
  dutycycleIn = durationL_average / totaltime;
  dutycycleOut = map(dutycycleIn * 100, 0, 100, 0, 255);
  
  //exhaust pressure sensor
  ebp_total= ebp_total - ebp_readings[ebp_index];         
  ebp_readings[ebp_index] = analogRead(ebp); 
  ebp_total= ebp_total + ebp_readings[ebp_index];         
  ebp_index = ebp_index + 1;                    
  if (ebp_index >= numReadings)              
    ebp_index = 0;                           
    
  ebp_average = ebp_total / numReadings;    
  
  //throttle position sensor
  tps_total= tps_total - tps_readings[tps_index];         
  tps_readings[tps_index] = analogRead(tps); 
  tps_total= tps_total + tps_readings[tps_index];         
  tps_index = tps_index + 1;                    
  if (tps_index >= numReadings)              
    tps_index = 0;                           
    
  tps_average = tps_total / numReadings; 
  
  //vehicle speed sensor
  vss_total= vss_total - vss_readings[vss_index];         
  vss_readings[vss_index] = analogRead(vss); 
  vss_total= vss_total + vss_readings[vss_index];         
  vss_index = vss_index + 1;                    
  if (vss_index >= numReadings)              
    vss_index = 0;                           
    
  vss_average = vss_total / numReadings; 
  
  //exhaust brake enable disable switch
  ebswitchvalue = digitalRead(ebswitch);
  if(ebswitchvalue == HIGH){
    lcd.setCursor(14,0);
    lcd.print("  ");
    lcd.setCursor(14,0);
    lcd.print("EN");
  }
  else{
    lcd.setCursor(14,0);
    lcd.print("  ");
    lcd.setCursor(14,0);
    lcd.print("DD");
  }    
  
  // output
  if (ebswitchvalue ==HIGH && tps_average <= 85 && vss_average >= 200){
    Input = ebp_average;
    myPID.Compute();
    pwmWrite(pwmOut, pidOutput); 
    //print pidoutput
    lcd.setCursor(6, 0);
    lcd.print("   ");
    lcd.setCursor(6,0);
    lcd.print(pidOutput * 100,0);   
    
    lcd.setCursor(14,1);
    lcd.print("  ");
    lcd.setCursor(14,1);
    lcd.print("ON");
  }
  
  else{
    pwmWrite(pwmOut, dutycycleOut);
    //print duty cycle in measurement
    lcd.setCursor(6, 0);
    lcd.print("   ");
    lcd.setCursor(6,0);
    lcd.print(dutycycleIn * 100,0);

    lcd.setCursor(13,1);
    lcd.print("   ");
    lcd.setCursor(13,1);
    lcd.print("OFF");
  }
  
  //print exhaust pressure sensor measurement
  lcd.setCursor(5, 1);
  lcd.print("  ");
  lcd.setCursor(5, 1);
  lcd.print(((ebp_average * 0.004888 * 19.01) - 13), 0);
/*
  //print code cycle time
  lcd.setCursor(0,1);
  lcd.print("        ");
  lcd.setCursor(0,1);
  lcd.print (micros() - starttime, 0);
 */
}