My project I've been working on lately is an electric cooling fan motor controller for my brothers 79 chevy C10. I admit this project has been a pain in the neck and probably slightly more difficult than what my experience is comfortable with. (getting out of a comfort zone is how you learn and grow)
anyway, my two measurements aren't reading correctly. I would like to tackle the easy one first, battVolts and the more difficult one next, realTemp.
battVolts = analogRead from a 3k to 1k voltage divider. 20vdc converted to 5vdc ie: 2.5vdc @ Arduino should display a reading of 10vdc.
realTemp = analogRead from a voltage divider (R1 255ohms) and (R2 factory tempSensor) 60ohms @ 190 degreesF and 3.7k ohms @ 40 degrees F.
for the realTemp I have no idea how to do the math for that. because of the higher voltage equals a lower temp and vise versa.
any help and/or guidence would be awesome. if there is any information that is need that i left out please ask and i will get it posted ASAP. again thank you.
/***************************************************
This is a library for our I2C LED Backpacks
Designed specifically to work with the Adafruit LED 7-Segment backpacks
----> http://www.adafruit.com/products/881
----> http://www.adafruit.com/products/880
----> http://www.adafruit.com/products/879
----> http://www.adafruit.com/products/878
These displays use I2C to communicate, 2 pins are required to
interface. There are multiple selectable I2C addresses. For backpacks
with 2 Address Select pins: 0x70, 0x71, 0x72 or 0x73. For backpacks
with 3 Address Select pins: 0x70 thru 0x77
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
****************************************************/
int tempSensor = analogRead (A2);
int battSensor = analogRead (A0);
const byte fanA = 7;
const byte fanB = 8;
const byte battTestSwitch = 4;
int realTemp;
#include <Adafruit_GFX.h>
#include <Adafruit_SPITFT.h>
#include <Adafruit_SPITFT_Macros.h>
#include <gfxfont.h>
#include <Wire.h> // Enable this line if using Arduino Uno, Mega, etc.
#include "Adafruit_LEDBackpack.h"
Adafruit_7segment matrix = Adafruit_7segment();
void setup() {
pinMode(fanA,OUTPUT);
pinMode(fanB,OUTPUT);
pinMode(battTestSwitch,INPUT_PULLUP);
Wire.setClock(100000); // set SCL to slow speed
#ifndef __AVR_ATtiny85__
Serial.begin(9600);
Serial.println("7 Segment Backpack Test");
#endif
matrix.begin(0x70);
digitalWrite(fanA,LOW);
digitalWrite(fanB,LOW);
}
void loop() {
int tempSensor = analogRead(A2);
// int realTemp
if (digitalRead (battTestSwitch) == LOW){
// battVolts = analogRead(battSensor);
int battSensor = analogRead (A0);
float battVolts = (battSensor * (5/1023) * 4); // 20vdc is 5vdc at arduino
// print a hex number
matrix.print(battVolts);
matrix.writeDisplay();
delay(2500);
// print a hex number
matrix.print(0xA55, HEX); // spells "ass"
matrix.writeDisplay();
delay(750);
}
else {
matrix.print(realTemp);
matrix.writeDisplay();
delay(1000);
}
if (realTemp > 185 ){
digitalWrite(fanA,HIGH);
}
else {
digitalWrite(fanA,LOW);
digitalWrite(fanB,LOW);
}
if (realTemp > 215){
digitalWrite(fanA,HIGH);
digitalWrite(fanB,HIGH);
}
else {
digitalWrite(fanA,LOW);
digitalWrite(fanB,LOW);
}
}
I'm not particularly familiar with it but, the map() function may work for you. The description on the reference page states you can reverse the order of the results by which values are used for high/low.
LandonW:
anyway, my two measurements aren't reading correctly. I would like to tackle the easy one first, battVolts and the more difficult one next, realTemp.
If your transducers are linear, then simply use Y = MX + B. where X is the input and Y in the output.
Here's an example how to do that: (example: convert degrees C into degrees F):
Take two points: 0C = 32F and 100C - 212F (they can be ANY two points).
Since we WANT F, the output (Y) is in F.
Now,
M = (Y1 - Y2) / (X1 + X2)
M = (32 - 212) / (0 - 100)
M = 1.8
Now, plug M back into the equation and solve for B:
Y = MX + B == Y - MX = B
Pick either Y (doesn't matter) but also use the same X.
B = Y1 - (1.8 * X1)
B = 32 - (1.8 * 0)
B = 32 - 0
B = 32
So your M is 1.8 and the B is 32. Now plug M and B into the equation Y = MX + B and stick any number into X. The correct answer will come out in Y.
When you grumbled in school "What will I ever use THAT for?" -- now you know!
M = (Y1 - Y2) / (X1 + X2)
M = (32 - 212) / (0 - 100)
M = 1.8
Now, plug M back into the equation and solve for B:
Y = MX + B == Y - MX = B
Pick either Y (doesn't matter) but also use the same X.
B = Y1 - (1.8 * X1)
B = 32 - (1.8 * 0)
B = 32 - 0
B = 32
So your M is 1.8 and the B is 32. Now plug M and B into the equation Y = MX + B and stick any number into X. The correct answer will come out in Y.
When you grumbled in school "What will I ever use THAT for?" -- now you know!
krupski:
you have X1 + X2 and below it you have 0 - 100.
is the switching of operations from + to - correct or are you testing me?? lol
If your transducers are linear, then simply use Y = MX + B. where X is the input and Y in the output.
Here's an example how to do that: (example: convert degrees C into degrees F):
Take two points: 0C = 32F and 100C - 212F (they can be ANY two points).
Since we WANT F, the output (Y) is in F.
Now,
M = (Y1 - Y2) / (X1 + X2)
M = (32 - 212) / (0 - 100)
M = 1.8
Now, plug M back into the equation and solve for B:
Y = MX + B == Y - MX = B
Pick either Y (doesn't matter) but also use the same X.
B = Y1 - (1.8 * X1)
B = 32 - (1.8 * 0)
B = 32 - 0
B = 32
So your M is 1.8 and the B is 32. Now plug M and B into the equation Y = MX + B and stick any number into X. The correct answer will come out in Y.
When you grumbled in school "What will I ever use THAT for?" -- now you know!
I found to be a dead end mathematically and way off of what would be a logical answer.
what I found to be get close is... M = (X1 / X2) / (Y1 / Y2) to continue with the formula provide above. B = -65.186. so before I plugged that number into the final Y = MX + B
B needs to = (Y1 - (M * X1)) * -1
in conclution Y = 22.38 * X + 65.186
i used graph paper to chart out X and Y with my known values and if i use 2.5 as X then Y = 121.136
on the chart it looks like it should be closer to 130ish
seems to be spot on. i guess because i was using my givin values from my chart in the formula is what was throwing it off. also i switched around x1 and x2 so that the graph would have a positive incline in relation to the vertacy instead of the actual negative one it has in real life.
/***************************************************
This is a library for our I2C LED Backpacks
Designed specifically to work with the Adafruit LED 7-Segment backpacks
----> http://www.adafruit.com/products/881
----> http://www.adafruit.com/products/880
----> http://www.adafruit.com/products/879
----> http://www.adafruit.com/products/878
These displays use I2C to communicate, 2 pins are required to
interface. There are multiple selectable I2C addresses. For backpacks
with 2 Address Select pins: 0x70, 0x71, 0x72 or 0x73. For backpacks
with 3 Address Select pins: 0x70 thru 0x77
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
****************************************************/
float tempSensor = analogRead (A2);
float battSensor = analogRead (A0);
const byte fanA = 7;
const byte fanB = 8;
const byte battTestSwitch = 4;
#include <Adafruit_GFX.h>
#include <Adafruit_SPITFT.h>
#include <Adafruit_SPITFT_Macros.h>
#include <gfxfont.h>
#include <Wire.h> // Enable this line if using Arduino Uno, Mega, etc.
#include "Adafruit_LEDBackpack.h"
Adafruit_7segment matrix = Adafruit_7segment();
void setup() {
pinMode(fanA,OUTPUT);
pinMode(fanB,OUTPUT);
pinMode(battTestSwitch,INPUT_PULLUP);
Wire.setClock(100000); // set SCL to slow speed
#ifndef __AVR_ATtiny85__
Serial.begin(9600);
Serial.println("7 Segment Backpack Test");
#endif
matrix.begin(0x70);
matrix.print(0x8888, HEX);
matrix.writeDisplay();
delay(1000);
digitalWrite(fanA,LOW);
digitalWrite(fanB,LOW);
}
void loop() {
int tempSensor = analogRead(A2);
float realTemp = ((43.39 * (tempSensor * 5) / 1023) + 13.49); // temp calculation
if (digitalRead (battTestSwitch) == LOW){
// battVolts = analogRead(battSensor);
float battSensor = analogRead (A0);
float battVolts = ((battSensor * 5)/1023.0 * 4); // 20vdc is 5vdc at arduino
// print a floating point
matrix.print(battVolts);
matrix.writeDisplay();
delay(2500);
// print a hex number
matrix.print(0xA55, HEX); // spells "ass"
matrix.writeDisplay();
delay(800);
matrix.print(0xFACE, HEX);
matrix.writeDisplay();
delay(800);
}
else {
matrix.print(realTemp);
matrix.writeDisplay();
delay(1000);
}
if (realTemp > 185 ){
digitalWrite(fanA,HIGH);
}
else {
digitalWrite(fanA,LOW);
digitalWrite(fanB,LOW);
}
if (realTemp > 215){
digitalWrite(fanA,HIGH);
digitalWrite(fanB,HIGH);
}
else {
digitalWrite(fanA,LOW);
digitalWrite(fanB,LOW);
}
}
thanks to all who helped with this.
my final code, and completely tested with relays and all. the only issue I had was a little bit of power loss due to the fact that its running on a 9vdc batt right now. should work with the hardware I have chosen for power supply in my real life build.
/***************************************************
This is a library for our I2C LED Backpacks
Designed specifically to work with the Adafruit LED 7-Segment backpacks
----> http://www.adafruit.com/products/881
----> http://www.adafruit.com/products/880
----> http://www.adafruit.com/products/879
----> http://www.adafruit.com/products/878
These displays use I2C to communicate, 2 pins are required to
interface. There are multiple selectable I2C addresses. For backpacks
with 2 Address Select pins: 0x70, 0x71, 0x72 or 0x73. For backpacks
with 3 Address Select pins: 0x70 thru 0x77
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
****************************************************/
float tempSensor = analogRead (A2);
float battSensor = analogRead (A0);
const byte fanA = 7;
const byte fanB = 8;
const byte battTestSwitch = 4;
#include <Adafruit_GFX.h>
#include <Adafruit_SPITFT.h>
#include <Adafruit_SPITFT_Macros.h>
#include <gfxfont.h>
#include <Wire.h> // Enable this line if using Arduino Uno, Mega, etc.
#include "Adafruit_LEDBackpack.h"
Adafruit_7segment matrix = Adafruit_7segment();
void setup() {
pinMode(fanA,OUTPUT);
pinMode(fanB,OUTPUT);
pinMode(battTestSwitch,INPUT_PULLUP);
Wire.setClock(100000); // set SCL to slow speed
#ifndef __AVR_ATtiny85__
Serial.begin(9600);
Serial.println("7 Segment Backpack Test");
#endif
matrix.begin(0x70);
matrix.print(0x8888, HEX);
matrix.writeDisplay();
delay(1000);
digitalWrite(fanA,LOW);
digitalWrite(fanB,LOW);
}
void loop() {
int tempSensor = analogRead(A2);
float realTemp = ((43.39 * (tempSensor * 5) / 1023) + 13.49); // temp calculation
if (digitalRead (battTestSwitch) == LOW){
// battVolts = analogRead(battSensor);
float battSensor = analogRead (A0);
float battVolts = ((battSensor * 5)/1023.0 * 4); // 20vdc is 5vdc at arduino
// print a floating point
matrix.print(battVolts);
matrix.writeDisplay();
delay(2500);
// print a hex number
matrix.print(0xA55, HEX); // spells "ass"
matrix.writeDisplay();
delay(800);
matrix.print(0xFACE, HEX);
matrix.writeDisplay();
delay(800);
}
else {
matrix.print(realTemp);
matrix.writeDisplay();
delay(2500);
if (realTemp > 185 ){
digitalWrite(fanA,HIGH);
}
if (realTemp > 210){
digitalWrite(fanA,HIGH);
digitalWrite(fanB,HIGH);
}
if (realTemp < 175){ // to keep relay from bouncing
digitalWrite(fanA,LOW);
digitalWrite(fanB,LOW);
}
}
}
dougp:
I'm not particularly familiar with it but, the map() function may work for you. The description on the reference page states you can reverse the order of the results by which values are used for high/low.
map() in Arduino is fubar because it only works with ints.
The proper thing to do is scrap is and re-write it with doubles, or else use Y=MX+B.
jremington:
Be sure to add excellent power protection circuitry to your project, at the very least a TVS diode.
Automotive electrical systems quickly fry unprotected electronics with occasional 125V spikes and even voltage reversals.
A clamping diode in a hostile environment is useless unless it switches faster than the transient you need to absorb.
That's why it's good (if possible) to feed vehicle power through a simple R/C filter to slow down transients so that the diode(s) can clamp them before it gets to the sensitive stuff.
Back in the '70s, car temp gages were usually a simple analog milliAmmeter in series with a nonlinear thermistor sensor, 1 wire from the gage and the engine block for ground, the gage dial was also nonlinear to match the sensor, numbers spread out on one end and scrunched up on the other.