I bought an OEM configured remote starter with 1-mile range (2.2Km) from an electronics closeout for my car, and I wanted it to turn on the defroster and seat heaters if it was cold out. The online ad said it could!
Well it could - but it can only run one accessory, so the output had to be used for the security key emulator and the defrost activation was disabled. I was going to kit together a delayed relay and temperature controller (from a major kit Vendor) but then I thought, that going to take up too much space, and why not learn something new?
So I bought the Experimentation Kit here to get started. I've never worked with electronics before. I write some code (scripting in AutoIT) but not anything sophisticated. So, anyone who has suggestions for improvement feel free to speak up.
For certain I think I can fit this onto a much smaller unit than an Uno as it hardly uses any pins or memory, so I might buy something less powerful for the final build. I have a Nano clone from ebay that I was going to use but I think I'll save that for another project I want to do after this.
Code: Select all
// My first Arduino effort
// HM March 2013
// This will be used to latch diode-isolated signal lines to ground
// in an automobile (12 volt) environment.
//
// The signal lines MUST NOT connect to the Arduino ground pins!
// Instead the signal must only pass through the relay contacts!
// Applying 12v to Arduino pins will let the magic smoke out!
//
// The signal lines will trigger onboard defrost and seat heater functions.
//
// I'm doing this because my remote start only has one output and
// I have to use it to power the security key emulator. It has
// the needed temperature circuit but it shares the internal relay
// and output wire with the function that powers the emulator.
// Only one or the other can be selected to run.
// I guess I was a bit too thrifty about buying it.
// Here is what this does
// 1) Waits "x" seconds defined in timer.setTimeout (in setup). During the wait, an LED pulses.
// 2) Evaluates the current temperature at the TMP36.
// 3) Compares the value of the temperature against variable "triggerTemp" using C (centigrade) or F (Farenheit)
// as defined in variable "CorF".
//#define DEBUG 1 // use this to enable serial monitoring
#include <SimpleTimer.h> ; // for the 30 second delay
//#include <avr/power.h> ; //for sleep mode, not implemented yet
//#include <avr/sleep.h> ; //for sleep mode, not implemented yet
int relayPin = 12; // relay
int relayInd = 13; // relay indication (hey, it's free)
int senseLED = 11; // the pin that the sense indicator LED is attached to
int senseLEDbrightness = 0; // how bright the sense indicator LED is
int senseLEDfadeAmount = 15; // how many points to fade the sense indicator LED by
int triggered = 0; // we will use this for state management of our indicator (sense)LED
// now lets define our target temperature.
char CorF = 'C'; // C for Centigrade, F for Farenheit
int triggerTemp = 5; // 68 F is 20 C (testing), 41 F is 5 C (production)
int temperaturePin = 0; //the analog pin the TMP36's Vout (sense) pin is connected to
SimpleTimer timer; //declare one timer only
void setup() {
pinMode(relayPin, OUTPUT);
pinMode(relayInd, OUTPUT);
digitalWrite(relayInd, LOW); // make sure the relay indication is off, PIN13 defaults to HIGH
pinMode(senseLED, OUTPUT); // declare pin 5 to be an output for power led
#ifdef DEBUG // if debug is on activate serial monitoring
Serial.begin(9600);
// welcome message
// Serial.println("One timer is triggered every 2 seconds");
Serial.println("One timer is set to trigger only once after 30 seconds");
Serial.println();
#endif
timer.setTimeout(20000, TriggerIfCold); // delay 20 seconds for the car to start and power to be stable
// timer.setTimeout(10000, TriggerIfCold); // for dev timing, long enough to grab temp controller and warm it up
}
//-------------------------------------------------------------------------------------------------
// main loop
void loop() {
switch (triggered){
case 0:
pulse(); // LED "pulses" while waiting to evaluate temperature
timer.run();// this is where the timer "polling" occurs
break;
case 1:
analogWrite(senseLED, senseLEDbrightness);
// doSleep(); // not implemented yet
// the relay was triggered, we leave the sense LED on to show this
break;
case 2:
analogWrite(senseLED, 0);
// doSleep(); // not implemented yet
// the relay was not triggered because the temperature was above the trigger
// the we turn off the sense LED on to show this
break;
}
}
//-------------------------------------------------------------------------------------------------
// Sleep mode may not be necessary or desired
//void doSleep() {
// set_sleep_mode(SLEEP_MODE_IDLE); // sleep mode is set here
// sleep_enable(); // enables the sleep bit in the mcucr register
// // so sleep is possible. just a safety pin
//
// power_adc_disable();
// power_spi_disable();
// power_timer0_disable();
// power_timer1_disable();
// power_timer2_disable();
// power_twi_disable();
//
// sleep_mode(); // here the device is actually put to sleep!!
//}
//-------------------------------------------------------------------------------------------------
// Trigger function for sensing
void TriggerIfCold() {
int Degrees; // local
Degrees = GetTemp(CorF); //C or F defined in declarations
if (Degrees <= triggerTemp) { // it's colder then the trigger temp
digitalWrite(relayPin, HIGH); // We trigger the relay on for half a second
digitalWrite(relayInd, HIGH); // We toggle the onboard LED on too
delay(500);
digitalWrite(relayPin, LOW);
digitalWrite(relayInd, LOW);
triggered = 1;
}
else if (Degrees > triggerTemp) { // it's above our trigger temp and we won't be doing anything
triggered = 2;
} // we are done looking at the temperature
#ifdef DEBUG // if debug is on we can see this in the serial monitor
Serial.print(Degrees);
Serial.print(" degrees ");
Serial.println(CorF);
Serial.println("");
Serial.println("This timer only triggers once after 30 seconds");
Serial.println("");
#endif
}
//-------------------------------------------------------------------------------------------------
// Pulse sense LED, only to show that something is happening for the humans
void pulse() { // set the brightness of pin 5:
analogWrite(senseLED, senseLEDbrightness);
// change the brightness for next time through the loop:
senseLEDbrightness = senseLEDbrightness + senseLEDfadeAmount;
// reverse the direction of the fading at the ends of the fade:
if (senseLEDbrightness == 0 || senseLEDbrightness == 255) {
senseLEDfadeAmount = -senseLEDfadeAmount ;
}
// wait for 30 milliseconds to see the dimming effect
delay(30);
}
//-------------------------------------------------------------------------------------------------
// calculate temperature in degrees F or C
int GetTemp(char CorF){
float temperature = getVoltage(temperaturePin); //getting the voltage reading from the temperature sensor
switch (CorF){ // calculate depending on global variable
case 'C':
temperature = (temperature - .5) * 100; //convert from 10 mv per degree with 500 mV offset to degrees C ((voltage - 500mV) times 100)
break;
case 'F':
temperature = (((temperature - .5) * 100) * 1.8) + 32; //convert to Farenheit for the backwards places
break;
}
return temperature;
}
//-------------------------------------------------------------------------------------------------
// getVoltage() - returns the voltage on the analog input defined by pin
float getVoltage(int pin){
return (analogRead(pin) * .004882814); //converting from a 0 to 1023 digital range
}