Commit 91d69dca by Hubert

fixed queue, fixed sequences, refactored

1 parent 0915f162
No preview for this file type
#ifndef __CONTROL_H_
#define __CONTROL_H_
#include "pump.h"
#include "device.h"
void loop_control( int counter );
......
#include "control.h"
/* #include "control.h" */
void loop_control( int counter ) {
// i'm alive / heartbeat
/* pcf8574.digitalWrite(led, counter % 2); */
if (button1->pressed) {
pump_start(button1);
rotate_start(button1);
}
if (button1->released) {
pump_end(button1);
device_end(button1);
}
/* unsigned int buttonCondition = buttonHolding; */
......
#ifndef __PUMP_H_
#define __PUMP_H_
#ifndef __DEVICE_H_
#define __DEVICE_H_
/* #include <stdio.h> */
/* #include <string.h> */
/* #include <stdlib.h> */
/* #include <time.h> */
/* #include <stddef.h> */
#include <string.h>
#include "pcf.h"
#include "mqtt.h"
// Number = pcfPIN - one action per pin / no diode crap anymore
#define dive 1
#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 dst_valve_watersource 7
#define off 0
struct sequence {
struct action *action;
int pump;
int src_valve;
int dst_valve;
int device;
int start_value;
int end_value;
double start;
double end;
struct sequence *next;
......@@ -37,13 +43,16 @@ int waterlevel = 0;
unsigned int pumpstate = 0;
unsigned long timeStored = 0;
void loop_device();
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 insertSequence(int device, int start_value, int end_value, double duration, struct action *action);
void next_sequence_step();
void monitor_sequence_duration();
void set_relay(struct sequence *step);
int fill_start(struct action *ptr);
int rotate_start(struct action *ptr);
int rotate_start(struct button *ptr);
int fertilize_start(struct action *ptr);
#endif
#include "device.h"
void insertSequence(int device, int start_value, int end_value, double duration, struct action *action) {
struct sequence *ptr = (struct sequence*) malloc(sizeof(struct sequence));
ptr->device = device;
ptr->start_value = start_value;
ptr->end_value = end_value;
ptr->action = action;
ptr->next = NULL;
Serial.println("is0");
if ( sequence_tail == NULL ) {
Serial.println("is1");
sequence_head = ptr;
set_relay(device, start_value);
ptr->end = action->start + duration;
} else {
Serial.println("is2");
sequence_tail->next = ptr;
ptr->start = sequence_tail->end;
ptr->end = sequence_tail->end + duration;
}
Serial.println("is3");
sequence_tail=ptr;
}
void loop_device() {
if ( sequence_tail != NULL ) { // there's something to do
monitor_sequence_duration();
next_sequence_step();
}
}
void next_sequence_step() {
unsigned int ut = time(NULL);
if ( ut >= sequence_head->end ) {
// set relay to end values of current step and start values of next step. afterwards remove the completed step;
if ( sequence_head->start_value != sequence_head->end_value ) {
set_relay(sequence_head->device, sequence_head->end_value);
}
struct sequence *tmp = (struct sequence*) malloc(sizeof(struct sequence));
tmp = sequence_head;
sequence_head = tmp->next;
if ( sequence_head != NULL ) {
set_relay(sequence_head->device, sequence_head->start_value);
next_sequence_step(); // in case the sequence duration is 0
} else {
sequence_tail = NULL;
}
free(tmp);
}
}
void monitor_sequence_duration() {
String pre = "home/compost/device/";
int device = sequence_head->device;
String duration(pre + device + "/duration");
unsigned int ut = time(NULL);
double remaining = sequence_head->end - ut;
String remainingStr(remaining);
Serial.println("--------------- Duration");
Serial.println(duration);
Serial.println(remainingStr);
Serial.println("---------------");
mqttClient.publish(duration, remainingStr );
}
int fill_start(struct action *ptr) {
if ( sequence_head == NULL ) {
insertSequence( dst_valve_rotate, 0, 0, 0, ptr );
insertSequence( dst_valve_watersource, 1, 1, 0, ptr );
insertSequence( src_valve_pump, 0, 0, 0, ptr );
insertSequence( peristaltic_reverse, 1, 0, 5, ptr ); // fill hose for 5 seconds
insertSequence( src_valve_pump, 1, 0, ptr->data, ptr ); // let gravity do its work
insertSequence( peristaltic, 1, 0, 5, ptr ); // vent hose for 5 seconds
insertSequence( dst_valve_watersource, 0, 0, 0, ptr );
return 1;
} else {
return 0;
}
}
int rotate_start(struct action *ptr) {
if ( sequence_head == NULL ) {
insertSequence( dst_valve_watersource, 0, 0, 0, ptr );
insertSequence( dst_valve_rotate, 1, 1, 0, ptr );
insertSequence( src_valve_pump, 1, 1, 0, ptr );
insertSequence( dive, 1, 0, ptr->data, ptr );
insertSequence( src_valve_pump, 0, 0, 0, ptr );
insertSequence( dst_valve_rotate, 0, 0, 0, ptr );
return 1;
} else {
return 0;
}
}
int rotate_start(struct button *ptr){
return 1;
}
int fertilize_start(struct action *ptr) {
if ( sequence_head == NULL ) {
insertSequence( dst_valve_watersource, 1, 1, 0, ptr );
insertSequence( dst_valve_rotate, 0, 0, 0, ptr );
insertSequence( src_valve_pump, 1, 1, 0, ptr );
insertSequence( dive, 1, 0, ptr->data, ptr );
insertSequence( src_valve_pump, 0, 0, 0, ptr );
insertSequence( dst_valve_rotate, 0, 0, 0, ptr );
insertSequence( dst_valve_watersource, 0, 0, 0, ptr );
return 1;
} else {
return 0;
}
}
void set_relay(int device, int value) {
String pre = "home/compost/device/";
/* int device = sequence_head->device; */
String state(pre + device + "/state");
String valueStr( value );
mqttClient.publish(state, valueStr );
Serial.println("--------------- Relay");
Serial.println(state);
Serial.println(valueStr);
Serial.println("---------------");
int pin = 1;
while ( pin < 7 ) {
if ( device == pin
/* || step->src_valve == pin */
/* || step->dst_valve == pin */
) {
/* pcf8574.digitalWrite(pin,0); */
} else {
/* pcf8574.digitalWrite(pin,1); */
}
pin++;
}
}
......@@ -8,8 +8,10 @@
#include "pcf.h"
#include "mqtt.h"
#include "queue.h"
#include "pump.h"
#include "control.h"
#include "device.h"
/* #include "control.h" */
/* #include "control.h" */
unsigned int counter = 0;
......@@ -18,23 +20,26 @@ void setup(void) {
Serial.begin(115200);
delay(100);
setup_wifi();
pinMode(LED_BUILTIN, OUTPUT);
setup_sonar();
setup_pcf();
setup_mqtt();
setup_queue();
/* setup_queue(); */
}
void loop(void) {
MDNS.update();
delay(500);
counter++;
loop_sonar(counter);
String liquidLevelAvgStr(liquid_level_avg());
mqttClient.publish(PREAMBLE T_SDIST, liquidLevelAvgStr );
/* String liquidLevelAvgStr(liquid_level_avg()); */
/* mqttClient.publish(PREAMBLE T_SDIST, liquidLevelAvgStr ); */
loop_pcf();
loop_queue();
loop_control(counter);
next_sequence_step();
loop_device();
/* loop_control(counter); */
}
......@@ -18,6 +18,17 @@ MQTT mqttClient(device_id, mqtt_server, 1883);
#define T_PUMPDURATION "pumpduration"
#define T_PUMPABORT "pumpabort"
#define T_FILL "fill/"
#define T_ROTATE "rotate/"
#define T_FERTILIZE "fertilize/"
#define TS_DURATION "duration"
#define TS_LEVEL "level"
#define C_FILL_DURATION 0
#define C_ROTATE_DURATION 1
#define C_FERTILIZE_DURATION 2
long stringToLong(String s);
void setup_mqtt();
void mqttSubscribe();
......
......@@ -18,9 +18,10 @@ void setup_mqtt() {
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("mqttSubscribe");
mqttClient.subscribe(PREAMBLE T_FILL TS_DURATION,1);
mqttClient.subscribe(PREAMBLE T_ROTATE TS_DURATION ,1);
mqttClient.subscribe(PREAMBLE T_FERTILIZE TS_DURATION ,1);
/* Serial.println("subscribed to" PREAMBLE T_PUMPDURATION); */
}
......@@ -40,15 +41,25 @@ void mqttDisconnected() {
}
void mqttData(String& topic, String& data) {
Serial.println("mqttData");
String dataStr(data);
/* mqttClient.publish(PREAMBLE T_PUMPSTATE, dataStr ); */
if (topic == PREAMBLE T_PUMPDURATION) {
insert("pumpduration", time(NULL), stringToLong(dataStr), 0);
Serial.println(topic);
Serial.println(PREAMBLE T_FILL TS_DURATION);
if (topic == PREAMBLE T_FILL TS_DURATION) {
Serial.println("rotate duration");
enqueue(C_FILL_DURATION, time(NULL), stringToLong(dataStr));
}
if (topic == PREAMBLE T_PUMPLEVEL) {
insert("pumplevel", time(NULL), 1, stringToLong(dataStr));
if (topic == PREAMBLE T_ROTATE TS_DURATION) {
enqueue(C_ROTATE_DURATION, time(NULL), stringToLong(dataStr));
}
if (topic == PREAMBLE T_PUMPABORT) {
insert("pumpabort", 0, 0, 0);
if (topic == PREAMBLE T_FERTILIZE TS_DURATION) {
enqueue(C_FERTILIZE_DURATION, time(NULL), stringToLong(dataStr));
}
/* if (topic == PREAMBLE T_PUMPLEVEL) { */
/* enqueue("pumplevel", time(NULL), stringToLong(dataStr)); */
/* } */
/* if (topic == PREAMBLE T_PUMPABORT) { */
/* enqueue("pumpabort", 0, 0); */
/* } */
}
#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++;
}
}
......@@ -6,15 +6,14 @@
#include <stdlib.h>
#include <time.h>
#include <stddef.h>
#include "pump.h"
#include "device.h"
struct action {
char *command;
int command;
int running;
double start;
double duration;
double data;
double end;
int level;
struct action *next;
};
......@@ -22,9 +21,15 @@ 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 enqueue(int command, double start, double duration, int level);
void loop_queue();
void setup_queue();
void entry_running(struct action *ptr);
int entry_start(struct action *ptr);
void entry_end(struct action *ptr);
void entry_end(struct button *ptr);
void entry_end(int source);
#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;
}
void enqueue(int command, double start, double data) {
Serial.println("enqueue");
/* // 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; */
/* } */
/* } */
struct action *ptr = (struct action*) malloc(sizeof(struct action));
ptr->command = command;
ptr->start = start;
ptr->data = data;
ptr->next = NULL;
ptr->running = 0;
if (head == NULL) {
head = ptr;
}
if ( ptr == NULL ) {
ptr = (struct action*) malloc(sizeof(struct action));
ptr->next = NULL;
ptr->command = command;
ptr->running = 0;
if (tail != NULL) {
tail->next = ptr;
}
tail = ptr;
/* struct action *ptr = head; */
/* if ( ptr == NULL ) { */
// 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 { */
/* } */
}
int entry_start(struct action *ptr) {
switch( ptr->command ) {
case C_FILL_DURATION:
return fill_start(ptr);
case C_ROTATE_DURATION:
return rotate_start(ptr);
case C_FERTILIZE_DURATION:
return fertilize_start(ptr);
}
if ( command == T_PUMPABORT ) {
ptr->end = 1;
ptr->running = 1;
} else {
ptr->start = start;
ptr->duration = duration;
ptr->level = level;
return 0;
}
void entry_running(struct action *ptr) {
unsigned int ut = time(NULL);
String remainingStr(ptr->end - ut);
delay(10); // Don't remove! mqttClient crashes otherwise
switch( ptr->command ) {
case C_FILL_DURATION:
mqttClient.publish("home/compost/action/3/duration", remainingStr );
break;
case C_ROTATE_DURATION:
mqttClient.publish("home/compost/action/1/duration", remainingStr );
break;
case C_FERTILIZE_DURATION:
mqttClient.publish("home/compost/action/2/duration", remainingStr );
break;
}
}
/* void device_running(struct action *ptr) { */
/* /\* int device = sequence_head->device; *\/ */
/* /\* String pre = "home/compost/device/"; *\/ */
/* /\* int device = 1; *\/ */
/* /\* String state(pre + device + "state"); *\/ */
/* /\* String duration(pre + device + "/duration"); *\/ */
/* } */
void entry_end(struct action *ptr) {
String remainingStr(0);
mqttClient.publish(PREAMBLE T_PUMPSTATE, remainingStr );
}
void entry_end(struct button *ptr) {
}
void entry_end(int source) {
}
void loop_queue() {
struct action *ptr = head;
struct action *next = NULL;
......@@ -51,38 +104,30 @@ void loop_queue() {
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;
if ( entry_start(ptr) ) { // pump is blocked ?
ptr->end = ptr->data + ut;
ptr->running = 1;
} else {
ptr->start++;
ptr->start++; // delay action;
}
}
///////////////////////// action
if ( ptr->running == 1 ) {
pump_running(ptr);
entry_running(ptr);
}
///////////////////////// end action
if ( ptr->running == 1
&& ut >= ptr->end
) {
pump_end(ptr);
Serial.println("end");
entry_end(ptr);
Serial.println("end1");
/* action is due to removal */
if (prev != NULL) {
......@@ -92,10 +137,10 @@ void loop_queue() {
if (ptr == head) {
head = ptr->next;
}
if (ptr == tail) {
tail = prev;
}
Serial.println("end5");
/* if (ptr == tail) { */
/* tail = prev; */
/* } */
free(ptr);
} else {
prev = ptr;
......
include<vars.scad>
module cornerdrills() {
translate([3.9,0.8,0]) {
translate([2.4,0.8,0]) {
cylinder(d=1.2,h=4, $fn=10);
}
translate([2.4,0.8,0]) {
......@@ -17,7 +17,7 @@ module cornerdrills() {
translate([0,1.5,0]) cylinder(d=0.6,h=40, $fn=10);
}
}
translate([0.8,3.9,10]) {
translate([0.8,2.4,10]) {
cylinder(d=1.2,h=20, $fn=10);
}
}
......
......@@ -122,7 +122,6 @@ module eurobox(x,y,z,handle,handlecaps,pipes,drilled,screws,locked,exploded) {
}
if ( drilled ) drills(x,y,z);
}
}
/* eurobox(30,40,22,true); */
......
include<eurobox.scad>
include<lid.scad>
/* translate([0,0,2]) euroboxlid(30,40); */
/* #translate([0,0,4.56]) euroboxlid(30,40); */
/* translate([0,0,-7]) */
/* eurobox(30,40,7,handle=false); */
/* translate([0,0,6.3]) */
/* eurobox(30,40,22, */
/* handle=true, */
/* handlecaps=true, */
/* pipes=true, */
/* drilled=true, */
/* screws=true, */
/* locked=true, */
/* exploded=false */
/* ); */
/* translate([7,3,0.9]) difference(){ */
/* union() { */
/* cube([ 15.2 */
/* , 23.2 */
/* , 3.6 */
/* ]); */
/* translate([-0.57,-0.57,3]) cube([ 15 + 0.57*2 */
/* , 23 + 0.57*2 */
/* , 0.612 */
/* ]); */
/* } */
/* translate([0.1,0.1,0.1]) cube([ 15 */
/* , 23 */
/* , 3.6 */
/* ]); */
/* } */
/* translate([0,0,0]) euroboxlid(30,40); */
/* translate([0,0,-7]) */
/* eurobox(30,40,7,handle=false); */
translate([0,0,6.3+21.3/* +4 */])
translate([0,0,5.31])
eurobox(30,40,22,
handle=true,
handlecaps=true,
......@@ -26,6 +35,18 @@ eurobox(30,40,22,
drilled=true,
screws=true,
locked=true,
exploded=true
exploded=false
);
/* translate([0,0,6.3+21.3/\* +4 *\/]) */
/* eurobox(30,40,22, */
/* handle=true, */
/* handlecaps=true, */
/* pipes=true, */
/* drilled=true, */
/* screws=true, */
/* locked=true, */
/* exploded=true */
/* ); */
......@@ -92,3 +92,4 @@ module screws(x,y,z, locked, exploded) {
mirror([1,0,0]) translate([-x,0,0]) cornerscrews(22, exploded, locked);
mirror([1,0,0]) translate([-x,y,0]) mirror([0,1,0]) cornerscrews(22, exploded, locked);
}
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!