Commit ea9a0046 by Hubert

init

0 parents
No preview for this file type
No preview for this file type
#ifndef __CONTROL_H_
#define __CONTROL_H_
#include "pump.h"
void loop_control( int counter );
#endif
#include "control.h"
void loop_control( int counter ) {
// i'm alive / heartbeat
/* pcf8574.digitalWrite(led, counter % 2); */
if (button1->pressed) {
pump_start(button1);
}
if (button1->released) {
pump_end(button1);
}
/* unsigned int buttonCondition = buttonHolding; */
/* unsigned int liquid_levelCondition = ( */
/* ( pumpstate == pumpOff */
/* && liquidLevelAvg >= startpumpheight */
/* ) */
/* || */
/* ( pumpstate == pumpOn */
/* && liquidLevelAvg >= stoppumpheight */
/* && !buttonReleased */
/* ) */
/* ); */
/* pumpstate = ( */
/* buttonCondition || liquid_levelCondition */
/* ) ? (pumpOn) : (pumpOff); */
/* pcf8574.digitalWrite(leeren11, */
/* pumpstate */
/* ); */
}
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <Wire.h>
#include "wifi.h"
#include "sonar.h"
#include "pcf.h"
#include "mqtt.h"
#include "queue.h"
#include "pump.h"
#include "control.h"
unsigned int counter = 0;
void setup(void) {
Serial.begin(115200);
delay(100);
setup_wifi();
setup_sonar();
setup_pcf();
setup_mqtt();
setup_queue();
}
void loop(void) {
MDNS.update();
delay(500);
counter++;
loop_sonar(counter);
String liquidLevelAvgStr(liquid_level_avg());
mqttClient.publish(PREAMBLE T_SDIST, liquidLevelAvgStr );
loop_pcf();
loop_queue();
loop_control(counter);
next_sequence_step();
}
#ifndef __MQTT_H_
#define __MQTT_H_
#include <MQTT.h>
#include "sonar.h"
#include "queue.h"
const char *mqtt_server = "sokoban.fritz.box";
const char *device_id = "kompost";
MQTT mqttClient(device_id, mqtt_server, 1883);
#define PREAMBLE "home/compost/"
#define T_RDIST "rawdistance"
#define T_SDIST "waterlevel"
#define T_PUMPSOURCE "pumpsource"
#define T_PUMPSTATE "pumpstate"
#define T_PUMPLEVEL "pumplevel"
#define T_PUMPDURATION "pumpduration"
#define T_PUMPABORT "pumpabort"
long stringToLong(String s);
void setup_mqtt();
void mqttSubscribe();
void mqttPublished();
void mqttConnected();
void mqttDisconnected();
void mqttData(String& topic, String& data);
#endif
#include "mqtt.h"
long stringToLong(String s) {
char arr[12];
s.toCharArray(arr, sizeof(arr));
return atol(arr);
}
void setup_mqtt() {
// setup callbacks
mqttClient.onConnected(mqttConnected);
mqttClient.onDisconnected(mqttDisconnected);
mqttClient.onPublished(mqttPublished);
mqttClient.onData(mqttData);
// connect
mqttClient.connect();
}
void mqttSubscribe() {
/* mqttClient.subscribe("home/compost/pump"); */
mqttClient.subscribe(PREAMBLE T_PUMPDURATION,1);
mqttClient.subscribe(PREAMBLE T_PUMPLEVEL,1);
mqttClient.subscribe(PREAMBLE T_PUMPABORT,1);
/* Serial.println("subscribed to" PREAMBLE T_PUMPDURATION); */
}
void mqttPublished() {
/* Serial.println("published cb"); */
}
void mqttConnected() {
mqttSubscribe();
Serial.println("connected");
}
void mqttDisconnected() {
Serial.println("disconnected");
delay(500);
mqttClient.connect();
}
void mqttData(String& topic, String& data) {
String dataStr(data);
/* mqttClient.publish(PREAMBLE T_PUMPSTATE, dataStr ); */
if (topic == PREAMBLE T_PUMPDURATION) {
insert("pumpduration", time(NULL), stringToLong(dataStr), 0);
}
if (topic == PREAMBLE T_PUMPLEVEL) {
insert("pumplevel", time(NULL), 1, stringToLong(dataStr));
}
if (topic == PREAMBLE T_PUMPABORT) {
insert("pumpabort", 0, 0, 0);
}
}
#ifndef __PCF_H_
#define __PCF_H_
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <Wire.h>
#include "PCF8574.h"
PCF8574 pcf8574(0x20, 0, 2);
int led = 0;
int PINbutton1 = 1;
int PINbutton2 = 2;
int PINbutton3 = 3;
int leeren11 = 4;
int leeren1 = 5;
int leeren2 = 6;
int fuellen2 = 7;
struct button {
int pin;
int holding;
int pressed;
int released;
};
struct button* button1 = (struct button*) malloc(sizeof(struct button));
struct button* button2 = (struct button*) malloc(sizeof(struct button));
struct button* button3 = (struct button*) malloc(sizeof(struct button));
void updateButton(struct button *buttonX);
void setup_pcf ();
void loop_pcf ();
#endif
#include "pcf.h"
void updateButton(struct button *buttonX) {
int read = 0; //!pcf8574.digitalRead(buttonX->pin);
buttonX->pressed = ( buttonX->holding == 0 && read == 1 ) ? (1) : (0);
buttonX->released = ( buttonX->holding == 1 && read == 0 ) ? (1) : (0);
buttonX->holding = read;
}
void setup_pcf () {
pcf8574.pinMode(PINbutton1, INPUT);
pcf8574.pinMode(PINbutton2, INPUT);
pcf8574.pinMode(PINbutton3, INPUT);
pcf8574.pinMode(led, OUTPUT);
pcf8574.pinMode(leeren11, OUTPUT);
pcf8574.pinMode(leeren1, OUTPUT);
pcf8574.pinMode(leeren2, OUTPUT);
pcf8574.pinMode(fuellen2, OUTPUT);
pcf8574.begin();
button1->pin = 1;
button1->holding = 0;
button1->pressed = 0;
button1->released = 0;
button2->pin = 2;
button2->holding = 0;
button2->pressed = 0;
button2->released = 0;
button3->pin = 3;
button3->holding = 0;
button3->pressed = 0;
button3->released = 0;
}
void loop_pcf () {
updateButton(button1);
updateButton(button2);
updateButton(button3);
}
#ifndef __PUMP_H_
#define __PUMP_H_
#include <string.h>
#include "pcf.h"
#include "mqtt.h"
// Number = pcfPIN - one action per pin / no diode crap anymore
#define dive 1
#define diaphragm 2
#define peristaltic 3
#define peristaltic_reverse 4
#define src_valve_pump 5
#define dst_valve_rotate 6
#define dst_valve_flower 7u
#define off 0
struct sequence {
struct action *action;
int pump;
int src_valve;
int dst_valve;
double start;
double end;
struct sequence *next;
};
struct sequence *sequence_head = NULL;
struct sequence *sequence_tail = NULL;
const int startpumpheight = 50;
const int stoppumpheight = 5;
int waterlevel = 0;
unsigned int pumpstate = 0;
unsigned long timeStored = 0;
int pump_start(struct action *ptr);
int pump_start(struct button *ptr);
void pump_running(int remaining);
void pump_end(struct action *ptr);
void pump_end(struct button *ptr);
void pump_end(int source);
void set_relay(struct sequence *step);
#endif
#include "pump.h"
void insertSequence(int pump, int src_valve, int dst_valve, double duration, struct action *action) {
unsigned int ut = time(NULL);
struct sequence *ptr = (struct sequence*) malloc(sizeof(struct sequence));
sequence_tail->next = ptr;
if ( sequence_head == NULL ) {
sequence_head = ptr;
ptr->end = ut + duration;
ptr->start = ut;
}
ptr->pump = pump;
ptr->src_valve = src_valve;
ptr->dst_valve = dst_valve;
ptr->start = sequence_tail->start;
ptr->end = sequence_tail->end + duration;
ptr->action = action;
ptr->next = NULL;
sequence_tail=ptr;
}
void next_sequence_step() {
if ( sequence_head != NULL ) { // there's something to do
unsigned int ut = time(NULL);
if ( ut >= sequence_head->end ) { // do next step
struct sequence *tmp = (struct sequence*) malloc(sizeof(struct sequence));
tmp = sequence_head;
sequence_head = tmp->next;
if ( sequence_head != NULL ) {
set_relay(sequence_head);
}
free(tmp);
}
}
}
int pump_start(struct action *ptr) {
if ( sequence_head == NULL ) {
String remainingStr(ptr->duration);
mqttClient.publish(PREAMBLE T_PUMPSTATE, remainingStr);
insertSequence( dive, src_valve_pump, dst_valve_rotate, ptr->duration, ptr );
insertSequence( off , off , off , 0 , ptr );
set_relay(sequence_head); // kickoff sequence
return 1;
} else {
return 0;
}
}
int pump_start(struct button *ptr){
return 1;
}
void pump_running(struct action *ptr) {
unsigned int ut = time(NULL);
String remainingStr(ptr->end - ut);
mqttClient.publish(PREAMBLE T_PUMPSTATE, remainingStr );
}
void pump_end(struct action *ptr) {
// abort
/* pcf8574.digitalWrite(leeren11, 1); */
/* pcf8574.digitalWrite(leeren1, 1); */
/* pcf8574.digitalWrite(leeren2, 1); */
/* pcf8574.digitalWrite(fuellen2, 1); */
String remainingStr(0);
mqttClient.publish(PREAMBLE T_PUMPSTATE, remainingStr );
}
void pump_end(struct button *ptr) {
}
void pump_end(int source) {
}
void set_relay(struct sequence *step) {
int pin = 1;
while ( pin < 7 ) {
if ( step->pump == pin
|| step->src_valve == pin
|| step->dst_valve == pin
) {
/* pcf8574.digitalWrite(pin,0); */
} else {
/* pcf8574.digitalWrite(pin,1); */
}
pin++;
}
}
#ifndef __QUEUE_H_
#define __QUEUE_H_
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <stddef.h>
#include "pump.h"
struct action {
char *command;
int running;
double start;
double duration;
double end;
int level;
struct action *next;
};
struct action *head = NULL;
struct action *tail = NULL;
struct action *current = NULL;
void insert(char *command, double start, double duration, int level);
/* void insert(char *command, unsigned int start, int duration, int level); */
void loop_queue();
void setup_queue();
#endif
#include "queue.h"
void insert(char *command, double start, double duration, int level) {
struct action *ptr = head;
// no dupes, only create new if it is scheduled
while(ptr != NULL) {
if ( command == T_PUMPLEVEL
|| command == T_PUMPDURATION
|| command == T_PUMPABORT
&&
ptr->command == T_PUMPLEVEL
|| ptr->command == T_PUMPDURATION
) {
break;
}
}
if ( ptr == NULL ) {
ptr = (struct action*) malloc(sizeof(struct action));
ptr->next = NULL;
ptr->command = command;
ptr->running = 0;
// in an empty list, this is head
if (head == NULL) {
head = ptr;
}
// previous tail is not last anymore
if (tail != NULL) {
tail->next = ptr;
}
// this is now tail
tail = ptr;
}
if ( command == T_PUMPABORT ) {
ptr->end = 1;
ptr->running = 1;
} else {
ptr->start = start;
ptr->duration = duration;
ptr->level = level;
}
}
void loop_queue() {
struct action *ptr = head;
struct action *next = NULL;
struct action *prev = NULL;
unsigned int ut = time(NULL);
while(ptr != NULL) {
next=ptr->next;
Serial.println("---------------");
Serial.println(ptr->command);
Serial.println(ptr->running);
Serial.println(ut);
Serial.println(ptr->start);
Serial.println(ptr->end);
Serial.println(ptr->duration);
Serial.println("---------------");
///////////////////////// start action
if ( ptr->running == 0
&& ut >= ptr->start
) {
if ( pump_start(ptr) ) { // pump is blocked ?
ptr->end = ptr->duration + ut;
ptr->running = 1;
} else {
ptr->start++;
}
}
///////////////////////// action
if ( ptr->running == 1 ) {
pump_running(ptr);
}
///////////////////////// end action
if ( ptr->running == 1
&& ut >= ptr->end
) {
pump_end(ptr);
/* action is due to removal */
if (prev != NULL) {
prev->next = ptr->next;
}
if (ptr == head) {
head = ptr->next;
}
if (ptr == tail) {
tail = prev;
}
free(ptr);
} else {
prev = ptr;
}
ptr = next;
}
}
void setup_queue() {
}
#ifndef __SONAR_H_
#define __SONAR_H_
#include <NewPing.h>
/* #include <Adafruit_BMP085.h> */
/* Adafruit_BMP085 bmp; */
#define TRIGGER_PIN 1
#define ECHO_PIN 3
#define MAX_DISTANCE 100
#define seaLevelPressure_hPa 1013.25
#define containerBase 113 /* distance to ground in mm */
int measurements [] = {0,0,0,0,0};
int liquidLevel = 10;
int dubugLiquid = 0;
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
void setup_sonar();
void loop_sonar(int counter);
double liquid_level();
double liquid_level_avg();
#endif
#include "sonar.h"
void setup_sonar() {
/* pinMode(1, FUNCTION_3); */
/* pinMode(3, FUNCTION_3); */
/* bmp.begin(); */
}
void loop_sonar(int counter) {
liquidLevel = liquid_level();
measurements[counter % 5] = liquidLevel;
}
double liquid_level() {
/* temperature = bmp.readTemperature(); */
/* V (m/s) = 331.3 + (0.606 × T) */
/* double speedOfSound = 331.3 + ( 0.606 * temperature ); */
double speedOfSound = 331.3 + ( 0.606 * 20 );
double liquidLevel =
containerBase
- ((
dubugLiquid /* sonar.ping_median(5) */
* speedOfSound
/ 2 )
/ 1000
);
return liquidLevel;
}
double liquid_level_avg() {
int liquidLevelAvg =
( measurements[0]
+ measurements[1]
+ measurements[2]
+ measurements[3]
+ measurements[4]
) / 5;
return liquidLevelAvg;
}
#ifndef __WIFI_H_
#define __WIFI_H_
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266mDNS.h>
#ifndef STASSID
#define STASSID "home"
#define STAPSK "042a82e39beccfc6e64edde50b49b9c0299733e7383e1281576cd2327b555429"
#endif
const char* ssid = STASSID;
const char* password = STAPSK;
const char* host = "kompost";
WiFiClient espClient;
void setup_wifi();
#endif
#include "wifi.h"
void setup_wifi() {
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
Serial.println("delay");
delay(500);
}
if (MDNS.begin(host)) {
Serial.println("MDNS responder started");
}
}
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!