Browse Source

add initial files

master
Burathar 4 years ago
commit
7a49669a92
  1. 14
      Steinhart-Hart coefficients Green Thermorisistor.txt
  2. 43
      button.cpp
  3. 32
      button.h
  4. 49
      queue.cpp
  5. 28
      queue.h
  6. 31
      relay.cpp
  7. 21
      relay.h
  8. 301
      smoker.ino
  9. 43
      temperature_sensor.cpp
  10. 26
      temperature_sensor.h

14
Steinhart-Hart coefficients Green Thermorisistor.txt

@ -0,0 +1,14 @@
Measurements Green Thermoresistor
1 graden C: 36500 Ohm
41 graden c: 4930 Ohm
100 graden C: 611 Ohm
Steinhart-Hart coefficients:
A 0.0010626977757858514
B 0.00025567427237838396
C -8.706543235296982e-8
Calculated with:
https://rusefi.com/Steinhart-Hart.html

43
button.cpp

@ -0,0 +1,43 @@
// Source: https://forum.arduino.cc/index.php?topic=14479.0
#include "button.h"
Button::Button(byte pin) {
this->pin = pin;
init();
}
void Button::init() {
pinMode(pin, INPUT);
}
byte Button::getState() {
byte event = 0;
buttonVal = digitalRead(pin);
// Button pressed down
if (buttonVal == LOW && buttonLast == HIGH && (millis() - upTime) > debounce)
{
event = 1;
downTime = millis();
ignoreUp = false;
}
// Button released
else if (buttonVal == HIGH && buttonLast == LOW && (millis() - downTime) > debounce)
{
if (not ignoreUp) upTime = millis();
}
// Test for hold
if (buttonVal == LOW && (millis() - downTime) >= holdTime) {
// Trigger "normal" hold
event = 2;
ignoreUp = true;
// Trigger "long" hold
if ((millis() - downTime) >= longHoldTime)
{
event = 3;
}
}
buttonLast = buttonVal;
return event;
}

32
button.h

@ -0,0 +1,32 @@
//https://roboticsbackend.com/arduino-object-oriented-programming-oop/
#ifndef MY_BUTTON_H
#define MY_BUTTON_H
#include <Arduino.h>
class Button {
private:
byte pin;
// Button timing variables
int debounce = 20; // ms debounce period to prevent flickering when pressing or releasing the button
int holdTime = 500; // ms hold period: how long to wait for press+hold event
int longHoldTime = 1500; // ms long hold period: how long to wait for press+hold event
// Button variables
boolean buttonVal = HIGH; // value read from button
boolean buttonLast = HIGH; // buffered value of the button's previous state
long downTime = -1; // time the button was pressed down
long upTime = -1; // time the button was released
boolean ignoreUp = false; // whether to ignore the button release because the click+hold was triggered
public:
Button(byte pin);
void init();
byte getState();
};
#endif

49
queue.cpp

@ -0,0 +1,49 @@
#include "queue.h"
Queue::Queue() {
init();
}
void Queue::init(){
}
void Queue::push(byte value) {
list[writeIndex] = value;
writeIndex = (writeIndex + 1) % sizeof(list);
}
byte Queue::pop() {
byte value = list[readIndex];
list[readIndex] = 0;
readIndex = (readIndex + 1) % sizeof(list);
return value;
}
byte * Queue::clone() {
for(int i=0; i<sizeof(list); i++){
int j = writeIndex % sizeof(list);
queue[i] = list[j];
}
return queue;
}
byte Queue::lookup(byte index){
return list[(index + writeIndex) % sizeof(list)];
}
byte Queue::getMax(){
byte maxValue = 0;
for (int i=0;i<sizeof(list); i++){
if(list[i] > maxValue) maxValue = list[i];
}
return maxValue;
}
byte Queue::getMin(){
byte minValue = 255;
for (int i=0;i<sizeof(list); i++){
if(list[i] < minValue && list[i] > 0) minValue = list[i];
}
return minValue;
}

28
queue.h

@ -0,0 +1,28 @@
#ifndef MY_QUEUE_H
#define MY_QUEUE_H
#define TEMP_QUEUE_LENGTH 58
#include <Arduino.h>
class Queue {
private:
byte list[TEMP_QUEUE_LENGTH];
byte queue[TEMP_QUEUE_LENGTH];
byte readIndex = 0;
byte writeIndex = 0;
public:
Queue();
void init();
void push(byte value);
byte pop();
byte * clone();
byte getMax();
byte getMin();
byte lookup(byte index);
};
#endif

31
relay.cpp

@ -0,0 +1,31 @@
#include "relay.h"
Relay::Relay(byte pin) {
// Use 'this->' to make the difference between the
// 'pin' attribute of the class and the
// local variable 'pin' created from the parameter.
this->pin = pin;
init();
}
void Relay::init() {
pinMode(pin, OUTPUT);
// Always try to avoid duplicate code.
// Instead of writing digitalWrite(pin, LOW) here,
// call the function off() which already does that
off();
}
void Relay::on() {
digitalWrite(pin, LOW);
state = LOW;
}
void Relay::off() {
digitalWrite(pin, HIGH);
state = HIGH;
}
bool Relay::getState() {
return !state;
}

21
relay.h

@ -0,0 +1,21 @@
#ifndef MY_RELAY_H
#define MY_RELAY_H
#include <Arduino.h>
class Relay {
private:
byte pin;
bool state = false;
public:
Relay(byte pin);
void init();
void on();
void off();
bool getState();
};
#endif

301
smoker.ino

@ -0,0 +1,301 @@
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "button.h"
#include "relay.h"
#include "temperature_sensor.h"
#include "queue.h"
#define AIR_TEMP_SENSOR_PIN A1
#define RELAY_PIN 6
#define SPEAKER_PIN 7
#define BUTTON_RIGHT_PIN 8
#define BUTTON_LEFT_PIN 9
#define BUTTON_DOWN_PIN 10
#define BUTTON_UP_PIN 11
#define MAX_STATE 4 // Amount of display states
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define TEMP_DELTA 4 // Minimum temperature difference before relay is toggled
#define ALARM_TEMP_DELTA 15 // Minimum temperature difference before the alarm wil sound
#define TEMP_PLOT_INTERVAL 60000 // Amount of milliseconds between temperature measuring points in the plot
byte state = 0;
int targetTemp = 70;
int alarmState = 0;
long lastTempQueue = -1000000;
Button buttonUp(BUTTON_UP_PIN);
Button buttonDown(BUTTON_DOWN_PIN);
Button buttonLeft(BUTTON_LEFT_PIN);
Button buttonRight(BUTTON_RIGHT_PIN);
Relay relay(RELAY_PIN);
// Pass pin, reference voltage, and a,b,c coefficients
TemperatureSensor airTempSensor(AIR_TEMP_SENSOR_PIN, 10000, 0.0010626977757858514, 0.00025567427237838396, -8.706543235296982e-8);
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
Queue tempQueue;
void setup() {
//Serial.begin(9600);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
//Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.setRotation(2);
display.clearDisplay();
display.setTextColor(WHITE);
airTempSensor.preload();
}
void loop() {
updateAirTemp();
byte bUp = buttonUp.getState();
byte bDown = buttonDown.getState();
byte bLeft = buttonLeft.getState();
byte bRight = buttonRight.getState();
if (bRight >= 1){
if(state >= MAX_STATE) state = 0;
else state += 1;
}
if (bLeft >= 1){
if(state <= 0) state = MAX_STATE;
else state -= 1;
}
display.clearDisplay();
displayMenuBar();
switch (state) {
case 0:
targetTempState(bUp, bDown);
break;
case 1:
manualState(bUp, bDown);
break;
case 2:
uptimeState(bUp, bDown);
break;
case 3:
tempPlotState(bUp, bDown);
break;
case 4:
alarmSettingState(bUp, bDown);
break;
}
display.display();
}
void updateAirTemp(){
airTempSensor.update();
if(millis() - lastTempQueue > TEMP_PLOT_INTERVAL){
tempQueue.push(airTempSensor.getTemperature());
lastTempQueue = millis();
}
}
void updateRelay(){
float temperature = airTempSensor.getTemperature();
if (temperature - targetTemp >= TEMP_DELTA){ //Temp too high
relay.off();
} else if (targetTemp - temperature >= TEMP_DELTA) { //Temp too low
relay.on();
}
if(temperature - targetTemp >= ALARM_TEMP_DELTA){
int second = millis() % 1000;
if(alarmState == 0 and second < 100){
alarmState = 1;
tone(SPEAKER_PIN, 440, 400);
}
if(alarmState == 1 and second > 500 and second < 600){
alarmState = 0;
tone(SPEAKER_PIN, 554, 400);
}
}
}
void targetTempState(byte bUp, byte bDown){
updateRelay();
switch(bUp){
case 1:
targetTemp +=1;
break;
case 2:
targetTemp +=1;
break;
case 3:
targetTemp +=3;
break;
}
switch(bDown){
case 1:
targetTemp -=1;
break;
case 2:
targetTemp -=1;
break;
case 3:
targetTemp -=3;
break;
}
displayCurrentTemp();
// Target Temp
display.setTextSize(1);
display.setCursor(0,40);
display.print("Target: ");
display.setTextSize(2);
display.setCursor(0,50);
display.print(targetTemp);
display.print(" ");
display.setTextSize(1);
display.cp437(true);
display.write(167);
display.setTextSize(2);
display.print("C");
//display.drawRect(0, 0, display.width(), display.height(), SSD1306_WHITE);
}
void manualState(byte bUp, byte bDown) {
if (bUp == 1) {
relay.on();
}
if (bDown == 1) {
relay.off();
}
displayCurrentTemp();
display.setTextSize(1);
display.setCursor(0,40);
display.print("Manual Mode");
display.setTextSize(2);
display.setCursor(0,50);
if (relay.getState()){
display.print("Heater ON");
} else {
display.print("Heater OFF");
}
}
void uptimeState(byte bUp, byte bDown){
updateRelay();
unsigned int seconds = millis()/1000; //convect milliseconds to seconds
unsigned int minutes=seconds/60; //convert seconds to minutes
unsigned int hours=minutes/60; //convert minutes to hours
seconds=seconds-(minutes*60); //subtract the coverted seconds to minutes in order to display 59 secs max
minutes=minutes-(hours*60); //subtract the coverted minutes to hours in order to display 59 minutes max
displayCurrentTemp();
display.setTextSize(1);
display.setCursor(0,40);
display.print("Uptime:");
display.setTextSize(2);
display.setCursor(0,50);
if(hours < 10) display.print(0);
display.print(hours);
display.print(":");
if(minutes < 10) display.print(0);
display.print(minutes);
display.print(":");
if(seconds < 10) display.print(0);
display.print(seconds);
}
void displayMenuBar(){
byte space = display.width() / (MAX_STATE + 1);
for (byte i = 0; i < MAX_STATE + 1; i++){
if (i == state) display.fillCircle(space * i + space / 2, 3, 3, WHITE);
else display.drawCircle(space * i + space / 2, 3, 3, WHITE);
}
}
void tempPlotState(byte bUp, byte bDown){
updateRelay();
byte maxValue = tempQueue.getMax();
byte minValue = tempQueue.getMin();
if(minValue > 99) minValue = 99;
display.setTextSize(1);
if(maxValue > 99)display.setCursor(110,8);
else display.setCursor(116,8);
display.print(maxValue);
display.setCursor(116,57);
display.print(minValue);
if(maxValue - minValue < 10){
minValue -= 1;
maxValue += 1;
}
for (int i=0; i<TEMP_QUEUE_LENGTH; i++){
byte barHeight = tempQueue.lookup(i);
if(barHeight < minValue) barHeight = minValue;
barHeight = map(barHeight, minValue, maxValue, 2, 58);
display.fillRect(i * 2, SCREEN_HEIGHT - barHeight, 1, barHeight, WHITE);
}
}
void alarmSettingState(byte bUp, byte bDown){
updateRelay();
if (bUp == 1) {
alarmState = 0;
}
if (bDown == 1) {
alarmState = -1;
}
displayCurrentTemp();
display.setTextSize(1);
display.setCursor(0,40);
display.print("Alarm temp: ");
display.print(targetTemp + ALARM_TEMP_DELTA);
display.print(" ");
display.cp437(true);
display.write(167);
display.setTextSize(1);
display.print("C");
display.setTextSize(2);
display.setCursor(0,50);
if (alarmState == -1){
display.print("Alarm OFF");
} else {
display.print("Alarm ON");
}
}
void displayCurrentTemp(){
display.setTextSize(1);
display.setCursor(0,10);
display.print("Current: ");
display.setTextSize(2);
display.setCursor(0,20);
display.print(airTempSensor.getTemperature());
display.print(" ");
display.setTextSize(1);
display.cp437(true);
display.write(167);
display.setTextSize(2);
display.print("C");
}

43
temperature_sensor.cpp

@ -0,0 +1,43 @@
#include "temperature_sensor.h"
TemperatureSensor::TemperatureSensor(byte pin, int refResistance, double a, double b, double c) {
this->pin = pin;
this->refResistance = refResistance;
this->a = a;
this->b = b;
this->c = c;
init();
}
#define DEBUG_OUTPUT Serial
void TemperatureSensor::init() {
pinMode(pin, INPUT);
}
void TemperatureSensor::preload() {
for(int i=0; i< 10; i++){
update();
}
}
void TemperatureSensor::update() {
if(measurementCounter < 10){ //Measure 10 times before calculating temperature from average
measurementAccumulative += analogRead(pin);
measurementCounter++;
} else {
int sensorValue = measurementAccumulative/measurementCounter;
// voltage = sensorValue*5.0/1024.0
// r1 = (vdd-vout)*r2/vout
double resistance = ((1.0-sensorValue/1024.0)*refResistance/(sensorValue/1024.0)); // this is our probe resistance.
double lt = log(resistance);
temperature = (1 / (a+b*lt+c*lt*lt*lt)) - 273.15; //Calculate temperature in Kelvin according to Steinhart-Hart equation, then convert to Celcius
if(temperature < -35) temperature = sqrt (-1); // If value is unpossibly low, return NaN
measurementAccumulative = 0;
measurementCounter = 0;
}
}
float TemperatureSensor::getTemperature() {
return temperature;
}

26
temperature_sensor.h

@ -0,0 +1,26 @@
#ifndef MY_TEMP_SENSOR_H
#define MY_TEMP_SENSOR_H
#include <Arduino.h>
class TemperatureSensor {
private:
byte pin;
int refResistance;
double a,b,c;
byte measurementCounter;
int measurementAccumulative;
float temperature;
public:
TemperatureSensor(byte pin, int refResistance, double a, double b, double c);
void init();
void preload();
void update();
float getTemperature();
};
#endif
Loading…
Cancel
Save