Files
Projet-bruleur/burner_motor.ino
2021-08-24 10:52:43 +02:00

771 lines
18 KiB
C++

// include the library code:
#include "rgb_lcd.h"
#include <Adafruit_NeoPixel.h>
// Delay when button is pressed
#define BUTTON_DELAY 200
// --- DISPLAYS AND COLORS
//LCD initialisation
rgb_lcd lcd;
// Structure LCD color values
struct lcdcolor
{
//Red color
int colorR;
//Green color
int colorG;
//Blue color
int colorB;
};
// LCD display normal state
struct lcdcolor baselcd = {50, 50, 50};
// LCD display when script is HIGH
struct lcdcolor actionlcd = {150, 150, 50};
struct lcdcolor action2lcd = {50, 100, 50};
struct lcdcolor timerlcd = {50, 150, 50};
// LED for buttons variable definition using adafruit
//variable for KeyCaps leds
#define PIXEL_COUNT 60
// instanciate led key object
// usage : Adafruit_NeoPixel "objectname" = Adafruit_NeoPixel(PIXEL_COUNT, "LED PIN", NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel action = Adafruit_NeoPixel(PIXEL_COUNT, 11, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel action2 = Adafruit_NeoPixel(PIXEL_COUNT, 13, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel ledstop = Adafruit_NeoPixel(PIXEL_COUNT, 7, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel ledtimer = Adafruit_NeoPixel(PIXEL_COUNT, 5, NEO_GRB + NEO_KHZ800);
// Structure for led color change
struct keyledcolor
{
//init number
int pixelnum;
//Red color
int ledR;
//Green color
int ledG;
//Blue color
int ledB;
};
//color definitions
struct keyledcolor brightblue ={0, 0, 255, 255};
struct keyledcolor green ={0, 0, 255, 0};
struct keyledcolor yellowish ={0, 255, 255, 0};
struct keyledcolor brightred ={0, 255, 0, 0};
struct keyledcolor brightmix ={0, 200, 70, 200};
struct keyledcolor uncolored ={0, 0, 0, 0};
// --- TIME GESTION initialisation
// time variables init for timer LCD
unsigned long startMillis;
unsigned long currentMillis;
unsigned long elapsedMillis;
// time variables for step actionscript
unsigned long stepcheckMillis;
unsigned long step2checkMillis;
unsigned long startcheckMillis;
#define persistanceMillis 30000
#define motorwaitMillis 5000
#define secondmotorwaitMillis 3000
#define timers_showtime 10000
long inDataSec[10];
long inDataMs[10];
long maxtime = 0;
int maxms;
int maxsec;
long sumtime = 0;
int sumsec;
int summs;
long totaltime = 0;
int totalsec;
int totalms;
float v;
float vit = 250000;
float datasec;
float datams;
// Steps for actionscript variable
const int actionsteps = 31;
int runningstep = 0;
int stepstate = LOW;
int burningstate = LOW; // Will keep track of burner for actionscript
int stopState = LOW; // Will keep track of stopwatch button pushed
int waitTime = LOW; // Will tell if there is to wait
// --- GLOBAL STRUCTS ---
// Represent a pin and associated state
struct pin_state
{
int pin;
int state;
};
// --- COMMANDS and INPUTS ---
// Struct definition
// Struct containing all commands buttons, inputs and states
struct commands
{
// home button
pin_state home;
// burner move pin
pin_state burner;
// action script pin
pin_state actionscript;
// action script 2 pin
pin_state actionscript2;
// Stopwatch pin
pin_state stopwatch;
// timer pin
pin_state timer;
// buzzer pin;
pin_state buzzer;
};
// Create command struct
struct commands cmd = {{2, 0}, {8, 0}, {10, 0}, {12, 0}, {6, 0}, {4, 0}, {53, 0}};
// --- MOTORS ---
// Structs definitions
// Struct containing input pullups attached to motor
struct pullups
{
// home pullup
pin_state home;
// end pullup
pin_state end;
};
// Struct containing all pins and delay associated with a motor
struct motor
{
// pins51
int dir;
int step;
int enable;
// delay
int delay;
// pullups associated
pullups pups;
// in position or not (mainly used by burner motor)
bool in_pos;
};
// Structs creation
// Create struct containing burner motor stuff
struct motor burner_motor = {31, 35, 33, 100, {43, 0, 45, 0}, false};
// Array containing signals instructions
// forward move
int forward[4] = {HIGH, HIGH, HIGH, LOW};
// backward move
int backward[4] = {LOW, HIGH, HIGH, LOW};
// move_motor is used to move motor forward or backward
// arg motor: motor to activate is passed a parameter
// arg signals: array of int used to specify backward or forward mode
void move_motor(motor motor, int *signals)
{
digitalWrite(motor.dir, signals[0]);
digitalWrite(motor.enable, signals[1]);
digitalWrite(motor.step, signals[2]);
delayMicroseconds(motor.delay);
digitalWrite(motor.step, signals[3]);
delayMicroseconds(motor.delay);
}
// home_motors is used to get all motors to home position
void home_motors()
{
// ensure a delay when button is pressed
delay(BUTTON_DELAY);
while (burner_motor.pups.home.state == LOW)
{
move_motor(burner_motor, backward);
refresh_motors_states();
}
burner_motor.in_pos = true;
refresh_motors_states();
// resetFunc();
}
// refresh all motors pullups states
void refresh_motors_states()
{
burner_motor.pups.home.state = digitalRead(burner_motor.pups.home.pin);
burner_motor.pups.end.state = digitalRead(burner_motor.pups.end.pin);
}
void set_position()
{
burner_motor.pups.home.state = digitalRead(burner_motor.pups.home.pin);
if (burner_motor.pups.home.state == HIGH)
{
burner_motor.in_pos = true;
}
}
// move_motor_quarter will move burner motor 1 quarter
void move_motor_quarter()
{
set_position();
// if not in position turn
if (burner_motor.in_pos == true)
{
while (burner_motor.pups.end.state == LOW)
{
move_motor(burner_motor, forward);
refresh_motors_states();
}
// inverse motor position
burner_motor.in_pos = false;
}
// else turn the other way
else
{
home_motors();
// inverse motor position
burner_motor.in_pos = true;
}
}
void lcd_set_color(lcdcolor lcdcolor)
{
lcd.setRGB(lcdcolor.colorR, lcdcolor.colorG, lcdcolor.colorB);
}
// --- SETUP ---
// setup LCD display
void setup_lcd()
{
lcd.begin(16, 2);
lcd.setRGB(baselcd.colorR, baselcd.colorG, baselcd.colorB);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Bienvenue");
}
// setup_motors assign all pin to output and input for motors
void setup_motors()
{
// burner motor setup
pinMode(burner_motor.step, OUTPUT);
pinMode(burner_motor.dir, OUTPUT);
pinMode(burner_motor.enable, OUTPUT);
pinMode(burner_motor.pups.home.pin, INPUT_PULLUP);
pinMode(burner_motor.pups.end.pin, INPUT_PULLUP);
}
// setup_commands assign all pin to output and input for commands
void setup_commands()
{
pinMode(cmd.home.pin, INPUT_PULLUP);
pinMode(cmd.burner.pin, INPUT_PULLUP);
pinMode(cmd.actionscript.pin, INPUT_PULLUP);
pinMode(cmd.actionscript2.pin, INPUT_PULLUP);
pinMode(cmd.stopwatch.pin, INPUT_PULLUP);
pinMode(cmd.timer.pin, INPUT_PULLUP);
pinMode(cmd.buzzer.pin, OUTPUT);
}
// setup all keyleds to off
void setoff(Adafruit_NeoPixel& ledsetup)
{
ledsetup.begin();
// Initialize all pixels to 'off'
ledsetup.clear();
ledsetup.show();
}
// setup the leds
void setup_leds()
{
setoff(action);
setoff(action2);
setoff(ledstop);
setoff(ledtimer);
}
void arduino_led_start()
{
led_bright(ledtimer, green);
led_bright(action, brightblue);
led_bright(action2, brightred);
}
// -- Setup function, needed by Arduino
void setup()
{
setup_lcd();
setup_leds();
setup_motors();
setup_commands();
// start leds init
arduino_led_start();
home_motors();
set_position();
}
// --- MAIN ---
// refresh_commands_states will refresh all commands related inputs
void refresh_commands_states()
{
cmd.home.state = digitalRead(cmd.home.pin);
cmd.burner.state = digitalRead(cmd.burner.pin);
cmd.actionscript.state = digitalRead(cmd.actionscript.pin);
cmd.actionscript2.state = digitalRead(cmd.actionscript2.pin);
cmd.stopwatch.state = digitalRead(cmd.stopwatch.pin);
cmd.timer.state = digitalRead(cmd.timer.pin);
}
// refresh_state is a wrapup off all refresh function
void refresh_state()
{
// commands states
refresh_commands_states();
// motors states
refresh_motors_states();
}
// buzzer
void beep()
{
digitalWrite(cmd.buzzer.pin, HIGH);
delay(50);
digitalWrite(cmd.buzzer.pin, LOW);
}
// lcd print parameters or Strings
void lcd_print_string(int col, int line, String argument)
{
lcd.setCursor(col, line);
lcd.print(argument);
}
void lcd_print_long(int col, int line, long argument)
{
lcd.setCursor(col, line);
lcd.print(argument);
}
void lcd_print_float(int col, int line, float argument)
{
lcd.setCursor(col, line);
lcd.print(argument);
}
// reset all timers variables
void reset_millis()
{
v = 0;
startMillis = 0;
currentMillis = 0;
elapsedMillis = 0;
stepcheckMillis = 0;
step2checkMillis = 0;
startcheckMillis = 0;
totaltime = 0;
sumtime = 0;
maxtime = 0;
memset(inDataSec,0,sizeof(inDataSec));
memset(inDataMs,0,sizeof(inDataMs));
}
// Check if you print action2 timers or action1
void timer_show_select()
{
lcd.clear();
if (v > 0)
show_action2_timers();
else
{
cycle_through_timers();
}
}
// Timers recollection
void cycle_through_timers()
{
lcd.clear();
led_bright(ledtimer, yellowish);
if (totaltime > 0)
{
delay(2000);
for (int timers = 0; timers < 10; timers++)
{
sumtime = (inDataSec[timers]*1000) + inDataMs[timers];
if (maxtime <= sumtime)
maxtime = sumtime;
}
lcd.clear();
maxms = (maxtime%1000);
maxsec = (maxtime/1000)%60;
lcd_print_string(0, 0, "Tps maximum ");
lcd_print_long(0, 1, maxsec);
lcd_print_string(5,1, "S");
lcd_print_long(9, 1, maxms);
lcd_print_string(12,1, "Ms");
delay(4000);
sumtime = 0;
for (int timers = 0; timers < 10; timers++)
{
lcd.clear();
lcd_print_string(0, 0, "Tps N");
lcd_print_long(6, 0, (timers + 1));
lcd_print_long(0, 1, inDataSec[timers]);
lcd_print_string(5,1, "S");
lcd_print_long(9, 1, inDataMs[timers]);
lcd_print_string(12,1, "Ms");
if ((inDataMs[timers] > 0) || (inDataSec[timers] > 0))
delay(4000);
sumtime = sumtime + (inDataSec[timers]*1000) + inDataMs[timers];
}
lcd.clear();
summs = (sumtime%1000);
sumsec = (sumtime/1000)%60;
lcd_print_string(0, 0, "Temps total");
lcd_print_long(0, 1, sumsec);
lcd_print_string(4,1, "S");
lcd_print_long(6, 1, summs);
lcd_print_string(12,1, "Ms");
delay(timers_showtime);
arduino_led_start();
}
else
{
lcd_print_string(0, 0, "Pas de timer ");
delay(2000);
}
led_bright(ledtimer, uncolored);
lcd_set_color(baselcd);
setup_lcd();
arduino_led_start();
}
// Timer actionscript 2 recollection
void show_action2_timers()
{
led_bright(ledtimer, yellowish);
lcd.clear();
datasec = (inDataSec[1]*1000);
datams = inDataMs[1];
datasec = datasec+datams;
v = (float)(vit / datasec);
lcd_print_string(0, 0, "V=");
lcd_print_float(4, 0, v);
lcd_print_string(12,0, "mm/s");
lcd_print_string(0, 1, "T2");
lcd_print_long(4, 1, inDataSec[1]);
lcd_print_string(6, 1, "S");
lcd_print_long(8, 1, inDataMs[1]);
lcd_print_string(11, 1, "Ms");
delay(timers_showtime);
led_bright(ledtimer, uncolored);
setup_lcd();
arduino_led_start();
}
// Display stopwatch and store timer
void lcdshow()
{
currentMillis = millis();
elapsedMillis = (currentMillis - startMillis);
lcd.clear();
lcd_print_string(0, 0, "Temps mesure");
lcd_print_string(0, 1, " ");
unsigned long durMS = (elapsedMillis%1000); //Milliseconds
unsigned long durSS = (elapsedMillis/1000)%60; //Seconds
unsigned long durMM = (elapsedMillis/(60000))%60; //Minutes
unsigned long durHH = (elapsedMillis/(3600000)); //Hours
durHH = durHH % 24;
String durMilliSec = timeMillis(durHH, durMM, durSS,durMS);
totaltime = totaltime + elapsedMillis;
inDataSec[(runningstep -1)] = durSS;
inDataMs[(runningstep -1)] = durMS;
lcd_print_string(0, 1, durMilliSec);
delay(50);
}
//Led color change
void led_bright(Adafruit_NeoPixel& led_display, keyledcolor keyledcolor)
{
led_display.setPixelColor(keyledcolor.pixelnum, keyledcolor.ledR, keyledcolor.ledG, keyledcolor.ledB);
led_display.show();
}
// -- ACTIONSCRIPT 1
// Stop current actionscript
void stop_action()
{
delay(BUTTON_DELAY);
stepstate = LOW;
lcd.clear();
lcd_print_string(0, 0, "Stop fonction");
home_motors();
runningstep = actionsteps;
waitTime = LOW;
burningstate = LOW;
cycle_through_timers();
led_bright(action, uncolored);
led_bright(ledstop, green);
refresh_commands_states();
}
// action script key is pushed, initialize the 10 steps
void actionscript()
{
home_motors();
delay(BUTTON_DELAY);
reset_millis();
lcd_set_color(actionlcd);
led_bright(ledtimer, brightred);
lcd.clear();
for (runningstep = 0; runningstep < actionsteps; runningstep++)
{
stepstate = HIGH;
while ((stepstate == HIGH) && (runningstep < actionsteps))
{
timed_motor();
if (cmd.timer.state == HIGH)
{
stop_action();
break;
}
refresh_commands_states();
}
}
led_bright(action, uncolored);
led_bright(ledstop, uncolored);
lcd_set_color(baselcd);
cycle_through_timers();
}
// -- ACTIONSCRIPT 1 timing the motor
void timed_motor()
{
stepcheckMillis = millis();
led_bright(action, brightblue);
move_motor_quarter();
burningstate = HIGH;
while (burningstate == HIGH)
{
if (cmd.timer.state == HIGH)
{
stop_action();
break;
}
startcheckMillis = millis();
lcd_print_string(0, 0, "Flamme 5 sec");
lcd_print_long(14, 0, runningstep);
if ((unsigned long)(startcheckMillis - stepcheckMillis) >= motorwaitMillis)
{
beep();
home_motors();
lcd.clear();
startMillis = millis();
led_bright(action, uncolored);
timer_time();
burningstate = LOW;
stepcheckMillis = millis();
}
refresh_commands_states();
}
}
// -- ACTIONSCRIPT 1 Waiting timer key push or countdown to next step
void timer_time()
{
led_bright(ledstop, green);
step2checkMillis = millis();
waitTime = HIGH;
lcd.clear();
while ((waitTime) && (runningstep < actionsteps))
{
if (cmd.timer.state == HIGH)
{
stop_action();
break;
}
lcd_print_string(0, 0, "Etape ");
lcd_print_long(14, 0, runningstep);
startcheckMillis = millis();
stopState = LOW;
refresh_commands_states();
timer_push();
if ((unsigned long)(startcheckMillis - step2checkMillis) >= secondmotorwaitMillis)
{
lcd.clear();
lcd_print_string(0, 0, "3 sec");
beep();
stopState = LOW;
led_bright(action, uncolored);
led_bright(ledstop, green);
refresh_commands_states();
stepstate = LOW;
waitTime = LOW;
step2checkMillis = millis();
}
}
}
// -- ACTIONSCRIPT 1 Check the timer key push
void timer_push()
{
while (cmd.stopwatch.state == HIGH)
{
// check if button was previously pushed
if (stopState == LOW)
{
startMillis = millis();
runningstep++;
}
step2checkMillis = millis();
startcheckMillis = millis();
led_bright(action, brightblue);
led_bright(ledstop, brightmix);
stopState = HIGH;
lcdshow();
led_bright(action, uncolored);
led_bright(ledstop, green);
refresh_commands_states();
}
}
// -- ACTIONSCRIPT 2
// action script key is pushed, initialize the burner
void actionscript2()
{
home_motors();
delay(BUTTON_DELAY);
lcd_set_color(action2lcd);
led_bright(action2, yellowish);
led_bright(ledstop, green);
reset_millis();
startcheckMillis = millis();
move_motor_quarter();
runningstep = 1;
burningstate = LOW;
stepstate = HIGH;
startMillis = millis();
while(stepstate == HIGH)
{
if (cmd.timer.state == HIGH)
{
stop_action();
break;
}
refresh_commands_states();
lcdshow();
if ((cmd.stopwatch.state == HIGH) || (unsigned long)(currentMillis - startcheckMillis) >= persistanceMillis )
{
move_motor_quarter();
runningstep++;
beep();
startMillis = millis();
refresh_state();
flame_persistance();
stepstate = LOW;
}
}
led_bright(action2, uncolored);
show_action2_timers();
lcd_set_color(baselcd);
}
// -- ACTIONSCRIPT 2 check time of flame persistance
void flame_persistance()
{
burningstate = HIGH;
delay(BUTTON_DELAY);
while (burningstate == HIGH)
{
if (cmd.timer.state == HIGH)
{
stop_action();
break;
}
refresh_state();
led_bright(ledstop, brightblue);
lcdshow();
if(cmd.stopwatch.state == HIGH)
{
led_bright(ledstop, uncolored);
burningstate = LOW;
}
}
}
// --- MAIN LOOP ---
void loop()
{
// refresh states from all inputs
refresh_state();
// if home button is pressed, trigger home_motors
// get all motors to home position
if (cmd.home.state == HIGH)
home_motors();
// if burner button is pressed, trigger move_motor_quarter
// set burner to burn position
if (cmd.burner.state == HIGH)
move_motor_quarter();
// if actionscript button is pressed, go in actionscript mode
// TODO: hanlde action script
if (cmd.actionscript.state == HIGH)
{
setup_leds();
actionscript();
}
if (cmd.actionscript2.state == HIGH)
{
setup_leds();
actionscript2();
}
if (cmd.timer.state == HIGH)
{
setup_leds();
lcd_set_color(timerlcd);
timer_show_select();
}
}
// time variables init for LCD Display
// ROTTEN CODE...
String timeMillis(unsigned long Hourtime,unsigned long Mintime,unsigned long Sectime,unsigned long MStime)
{
String dataTemp = "";
if (Hourtime < 10)
{
dataTemp = dataTemp + "0" + String(Hourtime)+ "h:";
}
else{
dataTemp = dataTemp + String(Hourtime)+ "h:";
}
if (Mintime < 10)
{
dataTemp = dataTemp + "0" + String(Mintime)+ "m:";
}
else{
dataTemp = dataTemp + String(Mintime)+ "m:";
}
if (Sectime < 10)
{
dataTemp = dataTemp + "0" + String(Sectime)+ "s:";
}
else{
dataTemp = dataTemp + String(Sectime)+ "s:";
}
dataTemp = dataTemp + String(MStime);
return dataTemp;
}