diff --git a/lambda-test/Makefile b/lambda-test/Makefile
index 27663ba..4aa6694 100644
--- a/lambda-test/Makefile
+++ b/lambda-test/Makefile
@@ -21,7 +21,8 @@
## Here you can link to one more directory (and multiple .c files)
EXTRA_SOURCE_DIR = ../lambda/
EXTRA_SOURCE_FILES = interrupts.c adc.c sensors.c integers.c \
-lcdroutines.c display.c alert.c command.c strings.c usart.c rules.c airgate.c
+lcdroutines.c display.c alert.c command.c strings.c usart.c rules.c airgate.c \
+scheduler.c
##########------------------------------------------------------##########
########## Programmer Defaults ##########
diff --git a/lambda/.cproject b/lambda/.cproject
index 01840e9..d38c159 100644
--- a/lambda/.cproject
+++ b/lambda/.cproject
@@ -8,34 +8,33 @@
-
-
+
-
+
-
+
-
+
+
+
+
+
@@ -50,10 +49,10 @@
-
+
-
+
@@ -63,6 +62,9 @@
+
+
+
diff --git a/lambda/.settings/de.innot.avreclipse.core.prefs b/lambda/.settings/de.innot.avreclipse.core.prefs
index 7fa4086..bc2bfbd 100644
--- a/lambda/.settings/de.innot.avreclipse.core.prefs
+++ b/lambda/.settings/de.innot.avreclipse.core.prefs
@@ -1,11 +1,11 @@
-avrtarget/ClockFrequency=1000000
+avrtarget/ClockFrequency=8000000
avrtarget/ExtRAMSize=0
avrtarget/ExtendedRAM=false
avrtarget/MCUType=atmega328p
avrtarget/UseEEPROM=false
avrtarget/UseExtendedRAMforHeap=true
avrtarget/avrdude/BitBangDelay=
-avrtarget/avrdude/Bitclock=
+avrtarget/avrdude/Bitclock=10
avrtarget/avrdude/EEPROMFile=
avrtarget/avrdude/EEPROMFromConfig=true
avrtarget/avrdude/FlashFile=
@@ -15,7 +15,7 @@
avrtarget/avrdude/NoVerify=false
avrtarget/avrdude/NoWrite=false
avrtarget/avrdude/OtherOptions=
-avrtarget/avrdude/ProgrammerID=programmerconfig.1
+avrtarget/avrdude/ProgrammerID=programmerconfig.2
avrtarget/avrdude/UseCounter=false
avrtarget/avrdude/WriteEEPROM=false
avrtarget/avrdude/WriteFlash=true
diff --git a/lambda/.settings/org.eclipse.cdt.managedbuilder.core.prefs b/lambda/.settings/org.eclipse.cdt.managedbuilder.core.prefs
new file mode 100644
index 0000000..45eafc6
--- /dev/null
+++ b/lambda/.settings/org.eclipse.cdt.managedbuilder.core.prefs
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+environment/buildEnvironmentInclude/de.innot.avreclipse.configuration.app.debug.1634123589/CPATH/delimiter=\:
+environment/buildEnvironmentInclude/de.innot.avreclipse.configuration.app.debug.1634123589/CPATH/operation=remove
+environment/buildEnvironmentInclude/de.innot.avreclipse.configuration.app.debug.1634123589/C_INCLUDE_PATH/delimiter=\:
+environment/buildEnvironmentInclude/de.innot.avreclipse.configuration.app.debug.1634123589/C_INCLUDE_PATH/operation=remove
+environment/buildEnvironmentInclude/de.innot.avreclipse.configuration.app.debug.1634123589/append=true
+environment/buildEnvironmentInclude/de.innot.avreclipse.configuration.app.debug.1634123589/appendContributed=true
+environment/buildEnvironmentLibrary/de.innot.avreclipse.configuration.app.debug.1634123589/LIBRARY_PATH/delimiter=\:
+environment/buildEnvironmentLibrary/de.innot.avreclipse.configuration.app.debug.1634123589/LIBRARY_PATH/operation=remove
+environment/buildEnvironmentLibrary/de.innot.avreclipse.configuration.app.debug.1634123589/append=true
+environment/buildEnvironmentLibrary/de.innot.avreclipse.configuration.app.debug.1634123589/appendContributed=true
diff --git a/lambda/DEBUG b/lambda/DEBUG
new file mode 100644
index 0000000..7ba5183
--- /dev/null
+++ b/lambda/DEBUG
@@ -0,0 +1,2 @@
+Upload hex: avrdude -pm328p -cjtag2isp -B10 -Uflash:w:lambda.hex:a
+Start AVaRICE: avarice -2 -w -B10 -j usb :4242
\ No newline at end of file
diff --git a/lambda/Makefile b/lambda/Makefile
index 8da700c..fc4cf81 100644
--- a/lambda/Makefile
+++ b/lambda/Makefile
@@ -14,7 +14,7 @@
LANG = 0
LOCAL_SOURCE = usart.c interrupts.c adc.c sensors.c integers.c lcdroutines.c \
-display.c alert.c command.c strings.c rules.c airgate.c
+display.c alert.c command.c strings.c rules.c airgate.c scheduler.c
EXTRA_SOURCE_DIR =
EXTRA_SOURCE_FILES =
@@ -27,9 +27,10 @@
# PROGRAMMER_TYPE = avrisp
PROGRAMMER_TYPE = avrispmkII
+# PROGRAMMER_TYPE = jtag2isp
# extra arguments to avrdude: baud rate, chip type, -F flag, etc.
# PROGRAMMER_ARGS = -b 19200 -P /dev/ttyACM3
-PROGRAMMER_ARGS =
+PROGRAMMER_ARGS = -b 19200
##########------------------------------------------------------##########
########## Makefile Magic! ##########
diff --git a/lambda/adc.c b/lambda/adc.c
index de4841f..e202aea 100644
--- a/lambda/adc.c
+++ b/lambda/adc.c
@@ -16,7 +16,7 @@
/**
* Returns to where sleep_mode() was called when ADC conversion is complete.
*/
-EMPTY_INTERRUPT(ADC_vect);
+// EMPTY_INTERRUPT(ADC_vect);
void setupADC(void) {
// use AVCC as reference voltage
@@ -34,9 +34,12 @@
uint32_t overValue = 0;
for (uint8_t i = 0; i < 16; i++) {
- sleep_mode();
+ ADCSRA |= (1 << ADSC);
+ // sleep_mode();
+ loop_until_bit_is_clear(ADCSRA, ADSC);
overValue += ADC;
}
+
int16_t mV = (((overValue >> 2) * AREF_MV) >> 12);
return mV;
diff --git a/lambda/airgate.c b/lambda/airgate.c
index 04c27ec..bdcacb6 100644
--- a/lambda/airgate.c
+++ b/lambda/airgate.c
@@ -14,8 +14,6 @@
#include
#include
-#include
-#include
#include
#include
#include "airgate.h"
@@ -25,8 +23,6 @@
/* Direction */
volatile static int8_t dir = 0;
-/* Target position */
-volatile static uint8_t target = 0;
/* Current position */
volatile static uint16_t pos = 0;
/* Steps remaining */
@@ -39,14 +35,15 @@
volatile static uint8_t speed = MIN_SPEED;
/**
- * Wakes up the driver if sleeping, sets the direction and initial speed and
+ * Sets increased current for higher torque,
+ * sets the direction and initial speed and
* starts the motor by starting the timer.
*/
static void start(void) {
- // set rated current for max torque
+ // set increased current for higher torque
PORT &= ~(1 << PIN_CURRENT);
- // some time to stabilize?
- _delay_us(3);
+ // some time for the power supply to stabilize?
+ _delay_ms(2);
// set dir
if (dir == 1) {
PORT &= ~(1 << PIN_DIR);
@@ -70,23 +67,6 @@
// GTCCR |= (1 << PSRASY);
}
-/**
- * Calculates the direction and steps to take to get to the target position,
- * the ramp length for the acceleration profile and starts the motor.
- */
-static void set(void) {
- int16_t diff = (((int16_t)target) << SCALE) - pos;
- if (diff != 0) {
- dir = (diff > 0) - (diff < 0);
- steps = abs(diff);
- ramp = MIN(abs(MAX_SPEED - MIN_SPEED), steps >> 1);
- start();
- } else {
- // set reduced current to save power
- PORT |= (1 << PIN_CURRENT);
- }
-}
-
void makeSteps(void) {
if (steps > 0) {
PORT ^= (1 << PIN_STEP);
@@ -100,48 +80,57 @@
speed--;
}
// linearize an unfavourably increasing acceleration curve
- OCR2A = (MIN_SPEED * MAX_SPEED) / speed;
+ OCR2A = ((uint16_t)MIN_SPEED * MAX_SPEED) / speed;
} else {
stop();
pos += (done * dir);
done = 0;
- // move to new target position if necessary
- set();
+ // set reduced current to save power
+ PORT |= (1 << PIN_CURRENT);
}
}
-void setAirgate(uint8_t const position) {
- if (position == target) {
+void setAirgate(uint8_t const target) {
+ if (target == getAirgate() || isAirgateBusy()) {
return;
}
- target = position;
- bool busy = false;
- ATOMIC_BLOCK(ATOMIC_FORCEON) {
- busy = steps > 0;
- if (busy) {
- // motor busy - decelerate and move to target position when stopped
- steps = MIN(ramp, steps);
- }
+ if (bit_is_clear(PORT, PIN_SLEEP)) {
+ setSleepMode(false);
}
- if (! busy) {
- // move to target position
- set();
+ int16_t diff = (((int16_t)target) << SCALE) - pos;
+ if (diff != 0) {
+ dir = (diff > 0) - (diff < 0);
+ steps = abs(diff);
+ ramp = MIN(abs(MAX_SPEED - MIN_SPEED), steps >> 1);
+ start();
}
}
uint8_t getAirgate(void) {
- return target;
+ return pos >> SCALE;
+}
+
+uint8_t getAirgateInPercent(void) {
+ return 100 / (AIRGATE_OPEN / getAirgate());
+}
+
+bool isAirgateBusy(void) {
+ uint16_t steps_c;
+ ATOMIC_BLOCK(ATOMIC_FORCEON) {
+ steps_c = steps;
+ }
+ return steps_c > 0;
}
void setSleepMode(bool const on) {
if (on) {
+ PORT &= ~(1 << PIN_SLEEP);
+ } else {
// wake up driver
PORT |= (1 << PIN_SLEEP);
// wakeup time
// should not be woken up just before stepping anyway, the power supply
// might need much more time to stabilize
- // _delay_ms(2);
- } else {
- PORT &= ~(1 << PIN_SLEEP);
+ _delay_ms(2);
}
}
diff --git a/lambda/airgate.h b/lambda/airgate.h
index a9b88de..0f2b198 100644
--- a/lambda/airgate.h
+++ b/lambda/airgate.h
@@ -9,9 +9,14 @@
#define AIRGATE_H_
/** Min value 1 */
-#define MIN_SPEED 20
+#define MIN_SPEED 50
/** Max value 255 for 8 bit timer and 65535 for 16 bit timer */
-#define MAX_SPEED 200
+#define MAX_SPEED 250
+
+#define AIRGATE_CLOSE 0
+#define AIRGATE_25 25
+#define AIRGATE_50 50
+#define AIRGATE_OPEN 100
/**
* 1 = full step, 2 = half step, 3 = 1/4 step, 4 = 8 microsteps, ...
@@ -20,26 +25,35 @@
#define SCALE 3
/**
- * Called from the timer interrupt ISR and makes one step or stops the
+ * Called from the timer interrupt ISR and makes a half step or stops the
* timer/motor if the target position is reached.
*/
void makeSteps(void);
/**
- * Sets the airgate position 0 - 100%. The actual number of degrees the motor
- * spins depends on the SCALE and the stepping mode. If the motor is currently
- * moving to a target position when this function is called, it is first
- * decelerated and then starts moving to the new target position.
+ * Sets the airgate position 0 - 255, where 200 units correspond to 360°
+ * rotation.
*/
void setAirgate(uint8_t const position);
/**
- * Returns the current airgate position, assuming the motor does all the steps
+ * Returns the current airgate position, assuming the motor did all the steps
* it was requested to do.
*/
uint8_t getAirgate(void);
/**
+ * Returns the current airgate position translated to percent.
+ */
+uint8_t getAirgateInPercent(void);
+
+/**
+ * Returns true if the motor is currently busy setting an airgate position,
+ * false otherwise.
+ */
+bool isAirgateBusy(void);
+
+/**
* Wakes up the driver or puts it in sleep mode.
*/
void setSleepMode(bool const on);
diff --git a/lambda/command.c b/lambda/command.c
index 0bdd930..4627bc3 100644
--- a/lambda/command.c
+++ b/lambda/command.c
@@ -22,6 +22,7 @@
#include "strings.h"
#include "rules.h"
#include "airgate.h"
+#include "scheduler.h"
static bool simulation = false;
static bool logging = false;
@@ -45,6 +46,8 @@
resetDisplay();
resetRules(true);
setHeaterState(heaterStateOn);
+ setSleepMode(false);
+ setAirgate(AIRGATE_OPEN);
beep(1, 1, 31);
}
else if (strcmp_P(fields[0], PSTR("sd")) == 0) {
@@ -119,6 +122,7 @@
updateMeas(meas);
}
reason(meas);
+ runTasks();
setUpdatePending();
}
diff --git a/lambda/display.c b/lambda/display.c
index 08eb461..44eb9df 100644
--- a/lambda/display.c
+++ b/lambda/display.c
@@ -137,7 +137,7 @@
if (position == displayPosMax) {
displayMeas(measMax, " ^");
} else if (position == displayPosAirgate) {
- displayAirgate(getAirgate());
+ displayAirgate(getAirgateInPercent());
} else if (position == displayPosHeater) {
displayCurrent(measLatest.current);
} else if (position == displayPosLastText) {
diff --git a/lambda/integers.h b/lambda/integers.h
index c99d173..94af8ab 100644
--- a/lambda/integers.h
+++ b/lambda/integers.h
@@ -11,6 +11,8 @@
#ifndef INTEGERS_H_
#define INTEGERS_H_
+#define ARRAY_LENGTH(array) sizeof(array) / sizeof(array[0])
+
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
diff --git a/lambda/interrupts.c b/lambda/interrupts.c
index f90c472..cee57ec 100644
--- a/lambda/interrupts.c
+++ b/lambda/interrupts.c
@@ -99,7 +99,7 @@
void initInterrupts(void) {
// enable ADC interrupt
- ADCSRA |= (1 << ADIE);
+ // ADCSRA |= (1 << ADIE);
// enable timer0 compare match A interrupt
TIMSK0 |= (1 << OCIE0A);
@@ -129,6 +129,8 @@
// timer2 is for the step of the stepper motor using the DRV8825
// timer2 clear timer on compare match mode, TOP OCR2A
+ // should use the 16 bit timer for the stepper motor, but here only very low
+ // velocity is needed so no need for a long acceleration ramp
TCCR2A |= (1 << WGM21);
TCCR2B = 0;
}
diff --git a/lambda/lambda.c b/lambda/lambda.c
index 747216e..5c4005f 100644
--- a/lambda/lambda.c
+++ b/lambda/lambda.c
@@ -35,6 +35,7 @@
#include "rules.h"
#include "messages.h"
#include "airgate.h"
+#include "scheduler.h"
/**
* Does initialization, measures, displays and logs the measurements and
@@ -56,13 +57,12 @@
initTimers();
// wake up stepper motor driver
- setSleepMode(true);
+ setSleepMode(false);
alert_P(1, 1, 31, PSTR(MSG_WELCOME), PSTR(""), false);
// spend some time on being polite
while (getTime() < 3) {}
- // TODO remember position before reset?
- setAirgate(100);
+ setAirgate(AIRGATE_OPEN);
setHeaterState(heaterStateOn);
uint32_t time = 0;
@@ -75,6 +75,7 @@
meas = measure();
updateMeas(meas);
reason(meas);
+ runTasks();
if (isLogging()) {
logMeas(meas);
}
diff --git a/lambda/pins.h b/lambda/pins.h
index c9c2c2f..92932c5 100644
--- a/lambda/pins.h
+++ b/lambda/pins.h
@@ -14,36 +14,52 @@
/** ADC pin for the type K thermocouple signal */
#define ADC_TEMPI PC2
+
/** ADC pin for the PT1000 resistance thermometer signal */
#define ADC_TEMPO PC0
+
/** ADC pin for the LSM 11 oxygen sensor signal */
#define ADC_LAMBDA PC1
+
/** ADC pin for the LSM 11 oxygen sensor heater current */
#define ADC_HEATER PC3
-/** Pin input register for menu button */
+/** Pin input register */
#define PIN PINB
-/** Pin output register for menu button, beeper and oxygen sensor heater */
+
+/** Pin output register */
#define PORT PORTB
-/** DDR for menu button, beeper and oxygen sensor heater */
+
+/** Data direction register */
#define DDR DDRB
+
/** Pin for the menu button */
#define PIN_BUTTON PB0
+
/** Pin for the beeper */
#define PIN_BEEPER PB1
+
/** Toggle beeper pin OC1A/PB1 */
#define PIN_BEEPER_TOGGLE COM1A0
+
/** Pin for the oxygen sensor heater */
#define PIN_HEATER PB2
+
/** Pin for stepper motor driver sleep mode **/
#define PIN_SLEEP PB3
+
/** Pin for stepper motor driver step input */
#define PIN_STEP PB4
+
/** Pin for stepper motor driver direction input */
#define PIN_DIR PB5
+
/** Pin for stepper motor current control */
#define PIN_CURRENT PB6
+/** Pin for stepper motor fault status */
+#define PIN_FAULT PB7
+
/* Pins for the LCD */
#define LCD_PORT PORTD
#define LCD_DDR DDRD
diff --git a/lambda/rules.c b/lambda/rules.c
index 03db316..a36b214 100644
--- a/lambda/rules.c
+++ b/lambda/rules.c
@@ -13,6 +13,7 @@
#include "rules.h"
#include "messages.h"
#include "airgate.h"
+#include "scheduler.h"
#include "usart.h"
@@ -56,8 +57,8 @@
if ((state == firing_up) &&
meas.tempI >= TEMP_AIRGATE_50 &&
meas.lambda >= LAMBDA_TOO_LEAN &&
- getAirgate() != 50) {
- setAirgate(50);
+ getAirgate() != AIRGATE_50) {
+ setAirgate(AIRGATE_50);
alert_P(BEEPS, LENGTH, TONE, PSTR(MSG_AIRGATE_50_0), PSTR(""), false);
*fired = true;
}
@@ -70,8 +71,8 @@
static void airgate25(bool* const fired, Measurement const meas) {
if (state == burning_down &&
meas.tempI < TEMP_AIRGATE_25 &&
- meas.lambda >= LAMBDA_TOO_LEAN && getAirgate() > 25) {
- setAirgate(25);
+ meas.lambda >= LAMBDA_TOO_LEAN && getAirgate() > AIRGATE_25) {
+ setAirgate(AIRGATE_25);
alert_P(BEEPS, LENGTH, TONE, PSTR(MSG_AIRGATE_25_0), PSTR(""), false);
*fired = true;
}
@@ -83,9 +84,14 @@
*/
static void airgateClose(bool* const fired, Measurement const meas) {
if (state == burning_down && meas.tempI < TEMP_AIRGATE_0 &&
- meas.lambda >= LAMBDA_MAX && getAirgate() > 0) {
+ meas.lambda >= LAMBDA_MAX && getAirgate() > AIRGATE_CLOSE) {
setHeaterState(heaterStateOff);
- setAirgate(0);
+ setAirgate(AIRGATE_CLOSE);
+ void func(void) {
+ setSleepMode(true);
+ }
+ // put stepper motor driver in sleep mode in 60 seconds
+ scheduleTask(func, 60);
alert_P(BEEPS, LENGTH, TONE,
PSTR(MSG_AIRGATE_CLOSE_0), PSTR(""), false);
*fired = true;
@@ -102,8 +108,8 @@
*/
static void tooRich(bool* const fired, Measurement const meas) {
if (meas.tempI > TEMP_FIRE_OUT && meas.lambda < LAMBDA_TOO_RICH &&
- getHeaterState() == heaterStateReady && getAirgate() < 50) {
- setAirgate(50);
+ getHeaterState() == heaterStateReady && getAirgate() < AIRGATE_50) {
+ setAirgate(AIRGATE_50);
alert_P(BEEPS, LENGTH, TONE, PSTR(MSG_AIRGATE_50_0), PSTR(""), false);
*fired = true;
}
@@ -115,8 +121,8 @@
*/
static void tooLean(bool* const fired, Measurement const meas) {
if (meas.tempI > TEMP_AIRGATE_50 && meas.lambda > LAMBDA_TOO_LEAN &&
- getHeaterState() == heaterStateReady && getAirgate() > 50) {
- setAirgate(50);
+ getHeaterState() == heaterStateReady && getAirgate() > AIRGATE_50) {
+ setAirgate(AIRGATE_50);
alert_P(BEEPS, LENGTH, TONE, PSTR(MSG_AIRGATE_50_0), PSTR(""), false);
*fired = true;
}
@@ -145,6 +151,8 @@
static void warmStart(bool* const fired, Measurement const meas) {
if (! *fired && state == firing_up &&
meas.tempI > TEMP_FIRE_OUT && tempIMax >= TEMP_AIRGATE_50) {
+ // TODO wake up driver here?
+ setSleepMode(false);
resetRules(false);
tempIMax = meas.tempI;
if (getHeaterState() != heaterStateFault) {
@@ -191,10 +199,8 @@
}
/**
- * Switches the heater off if it is on for 30 mins or more and there does
- * not seem to be a fire, and notifies that the fire is out.
- * TODO check this rule, simplify?
- * TODO set motor driver sleep mode as well?
+ * Switches the heater off if it is on for a while and there does not seem
+ * to be a fire.
*/
static void heaterTimeout(bool* const fired, Measurement const meas) {
if (getHeaterState() == heaterStateOff ||
@@ -205,18 +211,12 @@
if (heaterUptime >= 1800 && meas.tempI < TEMP_FIRE_OUT &&
meas.lambda >= LAMBDA_MAX) {
setHeaterState(heaterStateOff);
- alert_P(BEEPS, LENGTH, TONE, PSTR(MSG_FIRE_OUT_0), PSTR(""), false);
+ setSleepMode(true);
}
if (heaterUptime >= 10800 && meas.tempI < TEMP_AIRGATE_0 &&
meas.lambda >= LAMBDA_MAX) {
setHeaterState(heaterStateOff);
- if (getAirgate() > 0) {
- alert_P(BEEPS, LENGTH, TONE, PSTR(MSG_AIRGATE_CLOSE_0), PSTR(""),
- false);
- } else {
- alert_P(3, 5, TONE, PSTR(MSG_HEATER_OFF_0), PSTR(MSG_HEATER_OFF_1),
- false);
- }
+ setSleepMode(true);
}
}
@@ -259,7 +259,7 @@
// evaluation of the fire state and rules applied
// at every MEAS_INT'th measurement
- if (measCount == MEAS_INT) {
+ if (measCount == MEAS_INT && ! isAirgateBusy()) {
measCount = 0;
size_t rulesSize = sizeof(rules) / sizeof(rules[0]);
@@ -295,7 +295,7 @@
initQueue(TEMP_INIT);
measCount = MEAS_INT;
state = undefined;
- setAirgate(100);
+ setAirgate(AIRGATE_OPEN);
}
size_t rulesSize = sizeof(rules) / sizeof(rules[0]);
diff --git a/lambda/scheduler.c b/lambda/scheduler.c
new file mode 100644
index 0000000..7f3b1bb
--- /dev/null
+++ b/lambda/scheduler.c
@@ -0,0 +1,42 @@
+/*
+ * scheduler.c
+ *
+ * Created on: 09.03.2016
+ * Author: dode@luniks.net
+ */
+
+#include
+#include "scheduler.h"
+#include "integers.h"
+#include "interrupts.h"
+
+static Task tasks[] = {
+ {0, 0, 0, true},
+ {0, 0, 0, true},
+ {0, 0, 0, true}
+};
+
+bool scheduleTask(void (*func)(void), uint16_t const delay) {
+ bool scheduled = false;
+ for (int i = 0; i < ARRAY_LENGTH(tasks); i++) {
+ if (tasks[i].done) {
+ tasks[i].func = func;
+ tasks[i].delay = delay;
+ tasks[i].time = getTime();
+ tasks[i].done = false;
+ scheduled = true;
+ break;
+ }
+ }
+
+ return scheduled;
+}
+
+void runTasks(void) {
+ for (int i = 0; i < ARRAY_LENGTH(tasks); i++) {
+ if (! tasks[i].done && getTime() - tasks[i].time >= tasks[i].delay) {
+ tasks[i].func();
+ tasks[i].done = true;
+ }
+ }
+}
diff --git a/lambda/scheduler.h b/lambda/scheduler.h
new file mode 100644
index 0000000..b5511d2
--- /dev/null
+++ b/lambda/scheduler.h
@@ -0,0 +1,49 @@
+/*
+ * scheduler.h
+ *
+ * Created on: 09.03.2016
+ * Author: dode@luniks.net
+ */
+
+#ifndef SCHEDULER_H_
+#define SCHEDULER_H_
+
+#include
+
+/* Not used, but interesting */
+#define lambda(return_type, function_body) ({ \
+ return_type function_name function_body function_name; \
+})
+
+/*
+ void (*bla)(char*, int8_t) = lambda(void, (char* text, int8_t num) {
+ printf("Bla: %s, %d\n", text, num);
+ });
+
+ bla("blubb", 3);
+ */
+
+/**
+ * Internally used task.
+ */
+typedef struct {
+ void (*func)(void);
+ uint16_t delay;
+ uint16_t time;
+ bool done;
+} Task;
+
+/**
+ * Schedules the given function for execution after the given delay in seconds.
+ * Returns false if the function could not be scheduled because there were
+ * no free slots available, true otherwise.
+ */
+bool scheduleTask(void (*func)(void), uint16_t const delay);
+
+/**
+ * Runs the tasks where the delay has passed. A task that was run frees up a
+ * slot so another task can be scheduled.
+ */
+void runTasks(void);
+
+#endif /* SCHEDULER_H_ */
diff --git a/lambda/sensors.h b/lambda/sensors.h
index 39e5829..db06ad7 100644
--- a/lambda/sensors.h
+++ b/lambda/sensors.h
@@ -19,7 +19,7 @@
* Oxygen sensor heater current limits at certain states in milliamps.
*/
typedef enum {
- milliAmpsDisconn = 100,
+ milliAmpsDisconn = 250,
milliAmpsReady = 1350,
milliAmpsShort = 7500
} HeaterMilliAmps;
@@ -118,12 +118,12 @@
/**
* Sets the state of the heater of the oxygen sensor to the given value.
*/
-void setHeaterState(int8_t state);
+void setHeaterState(HeaterState const state);
/**
* Returns the state of the heater of the oxygen sensor.
*/
-int8_t getHeaterState(void);
+HeaterState getHeaterState(void);
/**
* Returns the time in seconds passed since that the heater was switched on.
diff --git a/lambda/usart.c b/lambda/usart.c
index 0fee17c..2bb17be 100644
--- a/lambda/usart.c
+++ b/lambda/usart.c
@@ -8,8 +8,8 @@
#include
#include
#include
-#include
#include "usart.h"
+#include
static volatile bool usartReceived = false;