My (stupid) questions to Jared

stefanst
contributor
contributor
Posts: 703
Joined: Wed Feb 17, 2016 12:24 am
Location: USA 08530

Re: My (stupid) questions to Jared

Post by stefanst »

I think you're way over-thinking this. PWM output to GND, just like I did, should work just fine.

Here's a link to the thread on miataturbo.net where I posted and explained it a little. https://www.miataturbo.net/megasquirt-18/water-temo-gauge-thermistor-values-74383/

Post 22.

This is a hacked together thing that was designed to fit on proto-board. It's been working for a few years now. I'm using it to actually linearize my oil-pressure and water temp gauges which are de-linearized on purpose from factory.
stefanst
contributor
contributor
Posts: 703
Joined: Wed Feb 17, 2016 12:24 am
Location: USA 08530

Re: My (stupid) questions to Jared

Post by stefanst »

And, for the masochists among you, here is my cobbled together arduino code. Coding-gods, please be kind to me. Not all of the code is needed. Some of it is used to give serial output during operation, so I can verify if I'm getting close.

Code: Select all

// These constants won't change.  They're used to give names
// to the pins used:
const int oilIn = A0;    // Analog input pin that the potentiometer is attached to
const int oilOut = 11;   // Analog output pin that the transistor is attached to
const int waterIn = A1;  // Analog input pin that the potentiometer is attached to
const int waterOut = 10; // Analog output pin that the transistor is attached to

/*
const float xOffsetOil = 20;
const float xStepOil =  50;
const float yValueOil [] = {  20.0,  40.0,  60.0,  80.0, 100.0, 120.0, 140.0, 160.0, 180.0, 200.0, 220.0};   
const float yPressOil [] = {  96.1,  82.9,  69.6,  56.4,  44.2,  32.6,  22.8,  15.4,   9.3,   3.7,  -1.1};
*/
const float xOffsetOil = 100;
const float xStepOil =  50;
const float yValueOil [] = {  125, 128, 131, 135, 139, 144, 150, 157, 170, 189, 203, 238 };
const float yPressOil [] = {    0,   3,   7,  11,  16,  22,  29,  37,  47,  59,  74,  92 };

const float xOffsetWater = 60;
const float xStepWater =  30;

const float yValueWater [] = { -60,  10,  60,  92, 133, 146, 157, 165, 171, 176, 180, 183, 186, 189, 192, 195, 198, 201, 205, 209, 214, 219, 224, 230, 236, 243, 250, 255, 255, 255, 255, 255, 255 };
const float yTempWater []  = { 310, 285, 264, 249, 237, 226, 216, 207, 199, 192, 186, 180, 175, 170, 165, 160, 155, 150, 145, 140, 135, 130, 124, 118, 112, 106,  98,  89,  78,  67,  55,  43,  31 };
void setup() {
  pinMode (oilIn, INPUT);
  pinMode (waterIn, INPUT);
  pinMode (oilOut, OUTPUT);
  pinMode (waterOut, OUTPUT);
  
  // initialize serial communications at 9600 bps:
  Serial.begin(9600); 
  Serial.println ("Ready");
}

int lookup (float val, float lowX, float highX, float lowY, float highY) {
  float retFloat = (highY - lowY)/(highX-lowX) * val + lowY + 0.5;
  int retInt = retFloat;
  return retInt;
}

void loop() {
  // read the analog in value:
  int sensorRawWater = 0 ;
  int sensorRawOil = 0 ;
  for ( int i=0; i<10; i++) {
 
    sensorRawWater = sensorRawWater + analogRead(waterIn); 
    sensorRawOil = sensorRawOil + analogRead(oilIn); 
 /*   Serial.println(sensorRawWater);    
    Serial.println(sensorRawOil);
    delay (500);
*/
  }
  float  sensorRawWaterAvg = sensorRawWater / 10;
  float  sensorRawOilAvg = sensorRawOil / 10;
  
  float sensorValueWater = sensorRawWaterAvg-xOffsetWater;
  int xIntWater = sensorValueWater / xStepWater;
  int outputValueWater = lookup(sensorValueWater - (xIntWater * xStepWater) , 0, xStepWater, yValueWater [xIntWater], yValueWater [xIntWater+1]);  
  int outputTempWater  = lookup(sensorValueWater - (xIntWater * xStepWater) , 0, xStepWater, yTempWater  [xIntWater], yTempWater  [xIntWater+1]);  
  
  float sensorValueOil = sensorRawOilAvg-xOffsetOil;
  int xIntOil = sensorValueOil / xStepOil;
  int outputValueOil = lookup(sensorValueOil - (xIntOil * xStepOil) , 0, xStepOil, yValueOil [xIntOil], yValueOil [xIntOil+1]);  
  int outputPressOil = lookup(sensorValueOil - (xIntOil * xStepOil) , 0, xStepOil, yPressOil [xIntOil], yPressOil [xIntOil+1]);  
   
  if (outputValueWater <0) {
    outputValueWater = 0;
  }
  if (outputValueWater > 255) {
    outputValueWater = 255;
  }
  analogWrite(waterOut, outputValueWater);           

  if (outputValueOil <0) {
    outputValueOil = 0;
  }
  if (outputValueOil > 255) {
    outputValueOil = 255;
  }
  analogWrite(oilOut, outputValueOil);      

  // print the results to the serial monitor:
  Serial.print("Water sensor raw = " );                       
  Serial.print(sensorRawWaterAvg);      
  
//  Serial.print("\t sensor-offset = " );                       
//  Serial.print(sensorValueWater);    
  
  Serial.print("\t xInt = ");  
  Serial.print(xIntWater);    
  
  Serial.print("\t output = ");        
  Serial.print(outputValueWater);   

  Serial.print("\t yTempWater  [xIntWater+1] = ");        
  Serial.print(yTempWater  [xIntWater+1]);   
  
  Serial.print("\t yTempWater  [xIntWater] = ");        
  Serial.print(yTempWater  [xIntWater]);   
 

  Serial.print("\t Temp = ");      
  Serial.println(outputTempWater);   
 
   // print the results to the serial monitor:
  Serial.print("Oil sensor raw = " );                       
  Serial.print(sensorRawOilAvg);      
//  Serial.print("\t sensor-offset = " );                       
//  Serial.print(sensorValueOil);      
  Serial.print("\t output = ");      
  Serial.print(outputValueOil);   
  Serial.print("\t Press = ");      
  Serial.println(outputPressOil);   

  // wait 2 milliseconds before the next loop
  // for the analog-to-digital converter to settle
  // after the last reading:
  delay(500);                     
}  
puff
contributor
contributor
Posts: 2961
Joined: Mon Nov 11, 2013 11:28 am
Location: Moskau

Re: My (stupid) questions to Jared

Post by puff »

Thanks! Just one question: are you using this approach with a newer cluster, where the needles of these gauges are driven by stepper motors?
The thing is, from my understanding, the output varies from 0 to 10th, and I am not sure, how ADC filtering is implemented on these inputs of the cluster. I mean to say, in this way the generated signal is way different from the original one.
stefanst
contributor
contributor
Posts: 703
Joined: Wed Feb 17, 2016 12:24 am
Location: USA 08530

Re: My (stupid) questions to Jared

Post by stefanst »

puff wrote:Thanks! Just one question: are you using this approach with a newer cluster, where the needles of these gauges are driven by stepper motors?
The thing is, from my understanding, the output varies from 0 to 10th, and I am not sure, how ADC filtering is implemented on these inputs of the cluster. I mean to say, in this way the generated signal is way different from the original one.
I'm using it with an old-school analog gauge. I am *guessing* it would also work with a digital gauge, but of course there's no guarantee.
How hard is it to set up? If you have the arduino at hand and the cluster available, just (very slowly) run through the range of PWM outputs (0-255) and see what happens. You may want a fairly large capacitor to buffer the PWM signal a bit though.
puff
contributor
contributor
Posts: 2961
Joined: Mon Nov 11, 2013 11:28 am
Location: Moskau

Re: My (stupid) questions to Jared

Post by puff »

Analog works differently (if it's a bimetallic-based). In this case ADC processing might go mad. Anyway, I have to give it a try. I even have a scope, but I don't have a mosfet, and I don't know which to use, and how big that capacitor should be... I'll try figure it out a bit later.
stefanst
contributor
contributor
Posts: 703
Joined: Wed Feb 17, 2016 12:24 am
Location: USA 08530

Re: My (stupid) questions to Jared

Post by stefanst »

It appears that I misremebered- I used an 2N2222 NPN transistor, not a mosfet.

A PWM with a big cap should still work with ADC. You probably want another small-ish resistor, maybe 10Ohm or so in series with the transistor.
The pullup resistor charges the capacitor. When PWM goes low, the transistor discharges it via the 10Ohm reistor. So you get a high-frequency sawtooth-like voltage.
Post Reply