Hej på er!
Farmarn wrote:aroncbds wrote:Haha, tack för era kommentarer!
Nej, det är ingen pulsbreddsstyrning, utan bara på/av vid ett gränsvärde. Hade planer på PWM innan, men har alldeles för många projekt på gång, så denna lösning får duga till version 1.0.
Okej. Kändes ambitöst med styrboxbygge istället för typ en termostat och ett relä
Haha, jo... Men det är kul!
Nåväl, här kommer källkoden till styroxen, som utlovat!
#include <math.h>
/*
Version: 1.03
- Added startup-test during initial startup
Description:
Arduino-based thermostat with manually-toggled fan-control for my Mercedes-Benz 250CE. Developed
on the Arduino Uno-platform. Intended hardware is Atmel 328PU MCU.
Disclaimer:
THIS CODE IS LICENSED UNDER THE GPL-LICENSE AND MAY BE USED AS IS AS LONG AS THIS SIGNATURE
IS INCLUDED IN ANY DISTRIBUTED COPY OF THE SOFTWARE. THE AUTHOR OF THIS SOFTWARE TAKES NO
GUARANTEE FOR ANY DAMAGE CAUSED DIRECTLY OR INDIRECTLY BY THIS SOFTWARE. ALL USE OF THIS
SOFTWARE IS DONE AT YOUR OWN RISK.
(C) 2013 ARON K -
aroncbds@gmail.com*/
// Inputs
#define FanButton 4 // Fan-timer startbutton
#define ThermistorPIN 5 // Engine-temperature (A5)
// Outputs
#define LED_Heartbeat 13
#define FanPIN 3 // f-n control (output)
// Engine temperature treshold values (Ohms), calibrated for thermistor from Biltema ("Reservgivare", art. 32-262)
long ENGINE_TEMP_NORMAL = 1600;
long ENGINE_TEMP_CRITICAL = 270; // Approx. 87C
int FanTimerState = 0; // State machine for fan-timer
int SensorState = 0; // State machine for the sensor-polling
// Delays in milliseconds
int FAN_STARTUP_RUNTIME = 3000L; // Run the f-n in three seconds after ignition-key has been turned on
int FAN_MANUAL_TIMEOUT = 30000L;
int ENGINE_TEMPERATURE_POLLING_DELAY = 1000L;
// Timers
long Time[4] = {0L, 0L, 0L, 0L};
boolean fanIsManuallyStarted = false;
boolean DEBUG_MODE = true;
void setup()
{
// Define outputs
pinMode(LED_Heartbeat, OUTPUT);
pinMode(FanPIN, OUTPUT);
// Define input with pullup
pinMode(FanButton, INPUT);
digitalWrite(FanButton, HIGH); // Use internal pullup
// Set initial state of outputs
digitalWrite(LED_Heartbeat, LOW);
digitalWrite(FanPIN, LOW);
// Start serial
if (DEBUG_MODE)
Serial.begin(9600);
// Perform "function-check" for the initial startup
digitalWrite(FanPIN, HIGH);
delay(FAN_STARTUP_RUNTIME);
digitalWrite(FanPIN, LOW);
}
void loop()
{
while (1)
{
//
// Temperature-assessment control
//
switch (SensorState)
{
case 0:
digitalWrite(LED_Heartbeat, LOW);
SetTimer(1, ENGINE_TEMPERATURE_POLLING_DELAY);
SensorState = 1;
break;
case 1:
if (TimerCheck(1)) {
digitalWrite(LED_Heartbeat, HIGH);
SetTimer(1, ENGINE_TEMPERATURE_POLLING_DELAY);
SensorState = 0;
// Check engine-temperature and start the f-n as needed
if (!fanIsManuallyStarted)
pollThermistor();
}
break;
default:
break;
}
//
// Fan-timer control
//
switch (FanTimerState)
{
case 0: // Initial State, done once at power up
if (fanIsManuallyStarted && DEBUG_MODE)
Serial.println("f-n stopping due to timeout. Returning to automatic-operation...");
fanIsManuallyStarted = false;
digitalWrite(FanPIN, LOW);
digitalWrite(LED_Heartbeat, HIGH);
FanTimerState++;
break;
// TODO: Protect the state machine of the timered f-n with a variable (to avoid the polling-procedure interfere with it)
case 1: // Fan-start detection (the button has been pushed)
if (digitalRead(FanButton) == 0) {
fanIsManuallyStarted = true;
digitalWrite(FanPIN, HIGH);
SetTimer(0, FAN_MANUAL_TIMEOUT);
if (DEBUG_MODE)
Serial.println("f-n started by button.");
FanTimerState++;
}
break;
case 2: // Let a few cars pass on main road before we can trigger cars on other road
if (TimerCheck(0)) {
FanTimerState = 0;
}
break;
}
}
}
void pollThermistor()
{
double Temp;
int rawADC = analogRead(ThermistorPIN);
long resistance = ((10240000 / rawADC) - 10000); // R = (1024 * balanceResistor / ADC) - balanceResistor
if (DEBUG_MODE)
{
Serial.print("Resistance: "); Serial.print(resistance); Serial.print("ohms / "); Serial.print("rawADC: "); Serial.print(rawADC); Serial.println();
}
if (resistance < ENGINE_TEMP_CRITICAL)
{
// Engine temperature is above 87C
digitalWrite(FanPIN, HIGH);
if (DEBUG_MODE)
Serial.println("Engine temperature is critical!");
}
else
{
digitalWrite(FanPIN, LOW);
if (DEBUG_MODE)
Serial.println("Engine temperature is OK!");
}
}
//
// Timer-helpers
//
void SetTimer(int tmr, long TimeDelay)
{
if (tmr >= 0 && tmr < 4) {
Time[tmr] = millis() + TimeDelay;
}
}
int TimerCheck(int tmr)
{
if (tmr >= 0 && tmr < 4) {
if (millis() >= Time[tmr]) {
return 1;
}
else {
return 0;
}
}
else {
return -1;
}
}