#include <ArduinoJson.h>
// #include "Variables.h"
#include <Arduino.h>
// MyVariables.cpp
// #include "Variables.h"
// int myGlobalVariable = 42; // Initialize the variable with a value
// keg
const int solenoid_relay_1_keg = 13;
const int solenoid_relay_2_keg = 12;
const int solenoid_relay_3_keg = 14;
const int solenoid_relay_4_keg = 27;
const int top_relay_1 = 13;
const int top_relay_2 = 12;
const int top_relay_3 = 14;
const int top_relay_4 =27;
// alcohol
const int solenoid_relay_1_alcohol = 8;
const int solenoid_relay_2_alcohol = 9;
const int solenoid_relay_3_alcohol = 10;
const int solenoid_relay_4_alcohol = 11;
const int flow_meter_1_keg = 34;
const int flow_meter_2_keg = 35;
const int flow_meter_3_keg = 23;
const int flow_meter_4_keg = 22;
const int flow_meter_1_alcohol = 35;
const int flow_meter_2_alcohol = 19;
const int flow_meter_3_alcohol = 20;
const int flow_meter_4_alcohol = 22;
volatile long pulse_1_mix = 0;
volatile long pulse_2_mix= 0;
volatile long pulse_3_mix = 0;
volatile long pulse_4_mix = 0;
volatile long pulse_1_alcohol = 0;
volatile long pulse_2_alcohol= 0;
volatile long pulse_3_alcohol = 0;
volatile long pulse_4_alcohol = 0;
volatile long main_pulse_keg_1;
volatile long main_pulse_alcohol_1;
volatile long main_pulse_keg_2;
volatile long main_pulse_alcohol_2;
volatile long main_pulse_keg_3;
volatile long main_pulse_alcohol_3;
volatile long main_pulse_keg_4;
volatile long main_pulse_alcohol_4;
volatile long main_pulse;
float volume_1;
float volume_2;
float vol;
float vol_mix_1;
float vol_alcohol_1;
float vol_mix_2;
float vol_alcohol_2;
float vol_mix_3;
float vol_alcohol_3;
float vol_mix_4;
float vol_alcohol_4;
float g1_mix_max_vol;
float g1_mix_interval_vol;
float g1_alcohol_max_vol;
float g1_alcohol_interval_vol;
float g2_mix_max_vol;
float g2_mix_interval_vol;
float g2_alcohol_max_vol;
float g2_alcohol_interval_vol;
float g3_mix_max_vol;
float g3_mix_interval_vol;
float g3_alcohol_max_vol;
float g3_alcohol_interval_vol;
float g4_mix_max_vol;
float g4_mix_interval_vol;
float g4_alcohol_max_vol;
float g4_alcohol_interval_vol;
float maxA = 500;
float maxB = 20;
float interval_vol = 50;
float calibration = 0;
// // keg
// float calibration_multiplier_flow_1_keg = 0.48;
// float calibration_multiplier_flow_2_keg = 0.48;
// float calibration_multiplier_flow_3_keg = 0.48;
// // alcohol
// float calibration_multiplier_flow_1_alcohol = 0.4523;
// float calibration_multiplier_flow_2_alcohol = 0.4523;
// float calibration_multiplier_flow_3_alcohol = 0.4523;
// keg
float calibration_multiplier_flow_1_keg = 0.48;
float calibration_multiplier_flow_2_keg = 0.48;
float calibration_multiplier_flow_3_keg = 0.48;
float calibration_multiplier_flow_4_keg = 0.48;
// alcohol
float calibration_multiplier_flow_1_alcohol = 0.4523;
float calibration_multiplier_flow_2_alcohol = 0.4523;
float calibration_multiplier_flow_3_alcohol = 0.4523;
float calibration_multiplier_flow_4_alcohol = 0.4523;
// Define the initial threshold and the threshold increment
float initialThreshold = 50.0;
float thresholdIncrement = 50.0;
// keg
// bool measure_switcher = false;
bool measure_switcher_1_keg = false;
bool measure_switcher_2_keg = false;
bool measure_switcher_3_keg = false;
bool measure_switcher_4_keg = false;
// alcohol
// bool measure_switcher = false;
bool measure_switcher_1_alcohol = false;
bool measure_switcher_2_alcohol = false;
bool measure_switcher_3_alcohol = false;
bool measure_switcher_4_alcohol = false;
bool calibration_position_over = false;
bool calibration_position_under = false;
bool switch_gauge_measurement = false;
bool start_main_measure = false;
// float vol;
float vol2;
float vol_mix;
float vol_alcohol;
float difference;
//8-->13
int flowMeter_1= 35;
int flowMeter_2= 34;
int flowMeter_3= 23;
int flowMeter_4= 22;
bool switcher = true;
bool group_switch_gauge_measurement = true;
int currentThreshold = 50;
int currentThreshold_alcohol = 20;
volatile long pulse_alc_1 = 0;
bool alcohol_switch = true;
bool mix_switch = true;
bool mix_reset_routine = false;
bool alcohol_reset_routine = false;
typedef struct{
const int id;
int mix;
int alcohol;
int current_threshold;
int current_threshold_alcohol;
int alcohol_switch;
int mix_switch;
bool mix_reset_routine;
bool alcohol_reset_routine;
}group_vars_t;
/****************GROUP 1 VARIABLES**************************/
group_vars_t group1_vars = {
.id = 1,
.mix = 0,
.alcohol = 0,
.current_threshold = 50,
.current_threshold_alcohol = 20,
.alcohol_switch = true,
.mix_switch = true,
.mix_reset_routine = false,
.alcohol_reset_routine = false,
};
/****************GROUP 2 VARIABLES**************************/
group_vars_t group2_vars = {
.id = 2,
.mix = 0,
.alcohol = 0,
.current_threshold = 50,
.current_threshold_alcohol = 20,
.alcohol_switch = true,
.mix_switch = true,
.mix_reset_routine = false,
.alcohol_reset_routine = false,
};
/****************GROUP 3 VARIABLES**************************/
group_vars_t group3_vars = {
.id = 3,
.mix = 0,
.alcohol = 0,
.current_threshold = 50,
.current_threshold_alcohol = 20,
.alcohol_switch = true,
.mix_switch = true,
.mix_reset_routine = false,
.alcohol_reset_routine = false,
};
/****************GROUP 4 VARIABLES**************************/
group_vars_t group4_vars = {
.id = 4,
.mix = 0,
.alcohol = 0,
.current_threshold = 50,
.current_threshold_alcohol = 20,
.alcohol_switch = true,
.mix_switch = true,
.mix_reset_routine = false,
.alcohol_reset_routine = false,
};
StaticJsonDocument<1500> doc;
DynamicJsonDocument outgoing_json(1500);
// Initialise inputs
void init_inputs()
{
pinMode(flow_meter_1_keg, INPUT);
pinMode(flow_meter_2_keg, INPUT);
pinMode(flow_meter_3_keg, INPUT);
pinMode(flow_meter_4_keg, INPUT);
pinMode(flow_meter_1_alcohol, INPUT);
pinMode(flow_meter_2_alcohol, INPUT);
pinMode(flow_meter_3_alcohol, INPUT);
pinMode(flow_meter_4_alcohol, INPUT);
attachInterrupt(digitalPinToInterrupt(flow_meter_1_keg), flow_meter1_keg_isr, RISING);
attachInterrupt(digitalPinToInterrupt(flow_meter_2_keg), flow_meter2_keg_isr, RISING);
attachInterrupt(digitalPinToInterrupt(flow_meter_3_keg), flow_meter3_keg_isr, RISING);
attachInterrupt(digitalPinToInterrupt(flow_meter_4_keg), flow_meter4_keg_isr, RISING);
attachInterrupt(digitalPinToInterrupt(flow_meter_1_alcohol), flow_meter1_alcohol_isr, RISING);
attachInterrupt(digitalPinToInterrupt(flow_meter_2_alcohol), flow_meter2_alcohol_isr, RISING);
attachInterrupt(digitalPinToInterrupt(flow_meter_3_alcohol), flow_meter3_alcohol_isr, RISING);
attachInterrupt(digitalPinToInterrupt(flow_meter_4_alcohol), flow_meter4_alcohol_isr, RISING);
}
// Initialise outputs
void init_outputs()
{
pinMode(solenoid_relay_1_keg, OUTPUT);
pinMode(solenoid_relay_2_keg, OUTPUT);
pinMode(solenoid_relay_3_keg, OUTPUT);
pinMode(solenoid_relay_4_keg, OUTPUT);
// initialize digital pin LED_BUILTIN as an output.
// pinMode(top_relay_1, OUTPUT);
// pinMode(top_relay_2, OUTPUT);
// pinMode(top_relay_3, OUTPUT);
// pinMode(top_relay_4, OUTPUT);
// pinMode(solenoid_relay_1_alcohol, OUTPUT);
// pinMode(solenoid_relay_2_alcohol, OUTPUT);
// pinMode(solenoid_relay_3_alcohol, OUTPUT);
// pinMode(solenoid_relay_4_alcohol, OUTPUT);
digitalWrite(solenoid_relay_1_keg, LOW); // turn the LED on (HIGH is the voltage level)
digitalWrite(solenoid_relay_2_keg, LOW);
digitalWrite(solenoid_relay_3_keg, LOW);
digitalWrite(solenoid_relay_4_keg, LOW);
// digitalWrite(solenoid_relay_1_keg, HIGH);
// digitalWrite(solenoid_relay_1_keg, HIGH); // turn the LED on (HIGH is the voltage level)
// digitalWrite(solenoid_relay_2_keg, HIGH);
// digitalWrite(solenoid_relay_3_keg, HIGH);
// digitalWrite(solenoid_relay_4_keg, HIGH);
// digitalWrite(top_relay_1, HIGH); // turn the LED on (HIGH is the voltage level)
// digitalWrite(top_relay_2, HIGH);
// digitalWrite(top_relay_3, HIGH);
// digitalWrite(top_relay_4, HIGH);
// digitalWrite(bottom_relay_1, HIGH);
// digitalWrite(bottom_relay_2, HIGH);
// digitalWrite(bottom_relay_3, HIGH);
// digitalWrite(bottom_relay_4, HIGH);
}
void check_mix(group_vars_t *group, int max)
{
DynamicJsonDocument outgoing_json_data(200);
if(group->mix >= max){
group->alcohol_switch = false;
group->mix_switch = false;
digitalWrite(solenoid_relay_1_keg, LOW);
digitalWrite(solenoid_relay_2_keg, LOW);
// mix_reset_routine = true;
String json_string;
outgoing_json_data["status"] = String("MIX_OUT_" + String(group->id));
serializeJson(outgoing_json_data, json_string);
Serial.println(json_string);
}
}
void check_alcohol(group_vars_t *group, int max)
{
DynamicJsonDocument outgoing_json_data(200);
if(group->alcohol >= max){
group->alcohol_switch = false;
group->mix_switch = false;
digitalWrite(solenoid_relay_1_keg, LOW);
digitalWrite(solenoid_relay_2_keg, LOW);
String json_string;
outgoing_json_data["status"] = String("ALCOHOL_OUT_" + String(group->id));
serializeJson(outgoing_json_data, json_string);
Serial.println(json_string);
}
}
void check_mix_reset_routine(group_vars_t *group)
{
if(group->mix_reset_routine){
group->mix = 0;
group->current_threshold = 0;
group->mix_switch = false;
group->alcohol_switch = false;
digitalWrite(solenoid_relay_1_keg, LOW);
digitalWrite(solenoid_relay_2_keg, LOW);
group->mix_reset_routine = false;
group->alcohol_reset_routine = false;
group->current_threshold = 50;
group->mix_switch = true;
group->alcohol_switch = true;
digitalWrite(solenoid_relay_1_keg, HIGH);
digitalWrite(solenoid_relay_2_keg, HIGH);
}
}
void check_alcohol_reset_routine(group_vars_t *group)
{
if(group->alcohol_reset_routine){
group->alcohol = 0;
group->current_threshold_alcohol = 0;
group->mix_switch = false;
group->alcohol_switch = false;
digitalWrite(solenoid_relay_1_keg, LOW);
digitalWrite(solenoid_relay_2_keg, LOW);
group->mix_reset_routine = false;
group->alcohol_reset_routine = false;
group->current_threshold_alcohol = 20;
/*Turn these to true for the measurement to continue*/
group->mix_switch = true;
group->alcohol_switch = true;
digitalWrite(solenoid_relay_1_keg, HIGH);
digitalWrite(solenoid_relay_2_keg, HIGH);
}
}
void measure_variables(group_vars_t *group)
{
float current_multiplier_keg, current_multiplier_alcohol;
long current_pulse_mix, current_pulse_alcohol;
switch(group->id){
case 1:{
current_multiplier_keg = calibration_multiplier_flow_1_keg;
current_multiplier_alcohol = calibration_multiplier_flow_1_alcohol;
current_pulse_mix = pulse_1_mix;
current_pulse_alcohol =pulse_1_alcohol;
break;
}
case 2:{
current_multiplier_keg = calibration_multiplier_flow_2_keg;
current_multiplier_alcohol = calibration_multiplier_flow_2_alcohol;
current_pulse_mix = pulse_2_mix;
current_pulse_alcohol =pulse_2_alcohol;
break;
}
case 3:{
current_multiplier_keg = calibration_multiplier_flow_3_keg;
current_multiplier_alcohol = calibration_multiplier_flow_3_alcohol;
current_pulse_mix = pulse_3_mix;
current_pulse_alcohol =pulse_3_alcohol;
break;
}
case 4:{
current_multiplier_keg = calibration_multiplier_flow_4_keg;
current_multiplier_alcohol = calibration_multiplier_flow_4_alcohol;
current_pulse_mix = pulse_4_mix;
current_pulse_alcohol =pulse_4_alcohol;
break;
}
default:{
return; // not valid group
}
}
if(group->mix_switch){
group->mix = measure(current_multiplier_keg, current_pulse_mix);
}
if(group->alcohol_switch){
group->alcohol = measure(current_multiplier_alcohol, current_pulse_alcohol);
}
}
void update_status(group_vars_t *group)
{
String json_string;
outgoing_json["status"] = String("mixing-" + String(group->id));
outgoing_json["mix"] = group->mix;
outgoing_json["alcohol"] = group->alcohol;
outgoing_json["currentThresh_mix"] = group->current_threshold;
outgoing_json["currentThresh_alcohol"] = group->current_threshold_alcohol;
outgoing_json["alcohol_reset_routine"] = group->alcohol_reset_routine;
serializeJson(outgoing_json, json_string);
Serial.println(json_string);
if(group->alcohol >= group->current_threshold_alcohol){
group->alcohol_switch = false;
//digitalWrite(solenoid_relay_1_keg, LOW;
digitalWrite(solenoid_relay_2_keg, LOW);
}
if (group->mix >= group->current_threshold) {
group->current_threshold += 50;
group->current_threshold_alcohol += 20;
group->alcohol_switch = true;
digitalWrite(solenoid_relay_2_keg, HIGH);
}
}
void measurement_task(void *pvParameters) {
// StaticJsonDocument<200> doc_data;
// DynamicJsonDocument outgoing_json_data(200);
//init_inputs();
// init_outputs();
while (1) {
if (group_switch_gauge_measurement) {
digitalWrite(solenoid_relay_1_keg, HIGH);
digitalWrite(solenoid_relay_2_keg, HIGH);
check_mix(&group1_vars, 19500);
check_mix(&group2_vars, 19500);
check_mix(&group3_vars, 19500);
check_mix(&group4_vars, 19500);
update_status(&group1_vars);
update_status(&group2_vars);
update_status(&group3_vars);
update_status(&group4_vars);
check_alcohol(&group1_vars, 4500);
check_alcohol(&group2_vars, 4500);
check_alcohol(&group3_vars, 4500);
check_alcohol(&group4_vars, 4500);
check_alcohol_reset_routine(&group1_vars);
check_alcohol_reset_routine(&group2_vars);
check_alcohol_reset_routine(&group3_vars);
check_alcohol_reset_routine(&group4_vars);
check_mix_reset_routine(&group1_vars);
check_mix_reset_routine(&group2_vars);
check_mix_reset_routine(&group3_vars);
check_mix_reset_routine(&group4_vars);
measure_variables(&group1_vars);
measure_variables(&group2_vars);
measure_variables(&group3_vars);
measure_variables(&group4_vars);
}
vTaskDelay(pdMS_TO_TICKS(500));
}
}
void jsonReceiveTask(void *pvParameters) {
Serial.begin(115200);
while (1) {
// Task to receive and process incoming JSON data from the serial port
if (Serial.available() > 0) {
// String receivedData = Serial.readStringUntil('\n');
// // Serial.print("Received JSON: ");
// Serial.println(receivedData);
String incomingChar = Serial.readString();
// Serial.println("INCOMING JSON:-");
// Serial.println(incomingChar);
DeserializationError error = deserializeJson(doc, incomingChar);
String json_string;
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
// return;
continue;
}
if (doc["status"] == "intialization") {
// outgoing_json["calibration_factor_mix"] = doc["calibration_factor_mix"];
// outgoing_json["calibration_factor_alcohol"] = doc["calibration_factor_alcohol"];
calibration_multiplier_flow_1_keg = doc["G1_calibration_factor_mix"];
calibration_multiplier_flow_2_keg = doc["G2_calibration_factor_mix"];
calibration_multiplier_flow_3_keg = doc["G3_calibration_factor_mix"];
calibration_multiplier_flow_4_keg = doc["G4_calibration_factor_mix"];
calibration_multiplier_flow_1_alcohol = doc["G1_calibration_factor_alcohol"];
calibration_multiplier_flow_2_alcohol = doc["G2_calibration_factor_alcohol"];
calibration_multiplier_flow_3_alcohol = doc["G3_calibration_factor_alcohol"];
calibration_multiplier_flow_4_alcohol = doc["G4_calibration_factor_alcohol"];
g1_mix_max_vol = doc["g1_mix_max_vol"];
g1_mix_interval_vol = doc["g1_mix_interval_vol"];
g1_alcohol_max_vol = doc["g1_alcohol_max_vol"];
g1_alcohol_interval_vol = doc["g1_alcohol_interval_vol"];
g2_mix_max_vol = doc["g2_mix_max_vol"];
g2_mix_interval_vol = doc["g2_mix_interval_vol"];
g2_alcohol_max_vol = doc["g2_alcohol_max_vol"];
g2_alcohol_interval_vol = doc["g2_alcohol_interval_vol"];
g3_mix_max_vol = doc["g3_mix_max_vol"];
g3_mix_interval_vol = doc["g3_mix_interval_vol"];
g3_alcohol_max_vol = doc["g3_alcohol_max_vol"];
g3_alcohol_interval_vol = doc["g3_alcohol_interval_vol"];
g4_mix_max_vol = doc["g4_mix_max_vol"];
g4_mix_interval_vol = doc["g4_mix_interval_vol"];
g4_alcohol_max_vol = doc["g3_alcohol_max_vol"];
g3_alcohol_interval_vol = doc["g4_alcohol_interval_vol"];
// currentThreshold=g1_mix_interval_vol;
outgoing_json["status"] = "initialized";
outgoing_json["G1_calibration_factor_mix"] = calibration_multiplier_flow_1_keg;
outgoing_json["G2_calibration_factor_mix"] = calibration_multiplier_flow_2_keg;
outgoing_json["G3_calibration_factor_mix"] = calibration_multiplier_flow_3_keg;
outgoing_json["G4_calibration_factor_mix"] = calibration_multiplier_flow_4_keg;
outgoing_json["G1_calibration_factor_alcohol"] = calibration_multiplier_flow_1_alcohol;
outgoing_json["G2_calibration_factor_alcohol"] = calibration_multiplier_flow_2_alcohol;
outgoing_json["G3_calibration_factor_alcohol"] = calibration_multiplier_flow_3_alcohol;
outgoing_json["G4_calibration_factor_alcohol"] = calibration_multiplier_flow_4_alcohol;
// outgoing_json["current_threshold_G1"] = currentThreshold;
serializeJson(outgoing_json, json_string);
Serial.println(json_string);
}
// start_gauge_measurement
if (doc["status"] == "start_gauge_measurement") {
// G1_switch_gauge_measurement = true;
// G2_switch_gauge_measurement = true;
// G3_switch_gauge_measurement = true;
// G4_switch_gauge_measurement = true;
group_switch_gauge_measurement = true;
}
if (doc["status"] == "G1_RESET_ALCOHOL") {
String json_string;
group1_vars.alcohol_reset_routine = true;
}
if (doc["status"] == "G1_RESET_MIX") {
String json_string;
group1_vars.mix_reset_routine = true;
}
if (doc["status"] == "G2_RESET_ALCOHOL") {
String json_string_reset;
group2_vars.alcohol_reset_routine = true;
outgoing_json["status"] = "RESETED_ALCOHOL";
// outgoing_json["current_threshold_G1"] = currentThreshold;
serializeJson(outgoing_json, json_string);
Serial.println(json_string_reset);
}
if (doc["status"] == "G2_RESET_MIX") {
String json_string;
group2_vars.mix_reset_routine = true;
}
if (doc["status"] == "G3_RESET_ALCOHOL") {
String json_string;
group3_vars.alcohol_reset_routine = true;
}
if (doc["status"] == "G3_RESET_MIX") {
String json_string;
group3_vars.mix_reset_routine = true;
}
if (doc["status"] == "G4_RESET_ALCOHOL") {
String json_string;
group4_vars.alcohol_reset_routine = true;
}
if (doc["status"] == "G4_RESET_MIX") {
String json_string;
group4_vars.mix_reset_routine = true;
}
}
vTaskDelay(pdMS_TO_TICKS(500)); // Adjust the delay as needed
}
}
void setup() {
//init_inputs();
pinMode(solenoid_relay_1_keg, OUTPUT);
pinMode(solenoid_relay_2_keg, OUTPUT);
pinMode(flow_meter_1_keg, INPUT);
pinMode(flow_meter_2_keg, INPUT);
attachInterrupt(digitalPinToInterrupt(flow_meter_1_keg), increase_1_mix, RISING);
attachInterrupt(digitalPinToInterrupt(flow_meter_2_keg), increase_2_mix, RISING);
xTaskCreatePinnedToCore(measurement_task, "Task1", 4096, NULL, 0, NULL, 0);
xTaskCreatePinnedToCore(jsonReceiveTask, "JSONRecv", 2048, NULL, 1, NULL, 0);
}
void flow_meter1_keg_isr()
{
//main_increase_keg_1();
/// increase_1_mix();
pulse_1_mix++;
}
void flow_meter2_keg_isr()
{
//main_increase_keg_2();
// increase_2_mix();
pulse_2_mix++;
}
void flow_meter3_keg_isr()
{
main_increase_keg_3();
increase_3_mix();
}
void flow_meter4_keg_isr()
{
main_increase_keg_4();
increase_4_mix();
}
void flow_meter1_alcohol_isr()
{
main_increase_alcohol_1();
increase_1_alcohol();
}
void flow_meter2_alcohol_isr()
{
main_increase_alcohol_2();
increase_2_alcohol();
}
void flow_meter3_alcohol_isr()
{
main_increase_alcohol_3();
increase_3_alcohol();
}
void flow_meter4_alcohol_isr()
{
main_increase_alcohol_4();
increase_4_alcohol();
}
void main_increase_keg_1() {
main_pulse_keg_1;
}
void main_increase_alcohol_1() {
main_pulse_alcohol_1;
}
void main_increase_keg_2() {
main_pulse_keg_2;
}
void main_increase_alcohol_2() {
main_pulse_alcohol_2;
}
void main_increase_keg_3() {
main_pulse_keg_3;
}
void main_increase_alcohol_3() {
main_pulse_alcohol_3;
}
void main_increase_keg_4() {
main_pulse_keg_4;
}
void main_increase_alcohol_4() {
main_pulse_alcohol_4;
}
void increase_1_alcohol() {
pulse_alc_1++;
}
void increase_1_mix() {
pulse_1_mix++;
}
void increase_2_mix() {
pulse_2_mix++;
}
void increase_3_mix() {
pulse_3_mix++;
}
void increase_4_mix() {
pulse_4_mix++;
}
void increase_2_alcohol() {
pulse_2_alcohol++;
}
void increase_3_alcohol() {
pulse_3_alcohol++;
}
void increase_4_alcohol() {
pulse_4_alcohol++;
}
float measure(float calibration_multiplier, int pulse) {
float volume;
return volume = calibration_multiplier * pulse;
}
void loop() {
// Main loop code here
}