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.

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)

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

//duty cycle out
int dutycycleOut = 0;

//exhaust pressure sensor
int ebp_index = 0;
float ebp_total = 0;
float ebp_average = 0;
const int ebp = A0;

//throttle position sensor
int tps_index = 0;
float tps_total = 0;
float tps_average = 0;
const int tps = A1;

//vehicle speed sensor
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
// duty cycle in measurement

//throttle position sensor

//vehicle speed sensor

//initialize all timers except for 0, to save time keeping functions
//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_index = durationL_index + 1;
durationL_index = 0;

dutycycleIn = durationL_average / totaltime;
dutycycleOut = map(dutycycleIn * 100, 0, 100, 0, 255);

//exhaust pressure sensor
ebp_index = ebp_index + 1;
ebp_index = 0;

//throttle position sensor
tps_index = tps_index + 1;
tps_index = 0;

//vehicle speed sensor
vss_index = vss_index + 1;
vss_index = 0;

//exhaust brake enable disable switch
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);
*/
}
``````