/**
Arduino Calculator
Copyright (C) 2020, Uri Shaked.
Released under the MIT License.
*/
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <Servo.h>
#define EN 2
//Direction pin
#define X_DIR 5
#define Y_DIR 6
#define Z_DIR 2
//Direction pin led
#define Verde 7
#define Blu 8
#define Rosso 9
//Step pin
#define X_STP 2
#define Y_STP 3
#define Z_STP 4
//Micro step
//#define ms1
//#define ms2
//#define ms3
LiquidCrystal_I2C lcd(0x27, 20, 4);
const byte ROWS = 4; // Quattro righe
const byte COLS = 4; // Quattro colonne
// Definizione mappa della tastiera
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'.', '0', '#', 'D'}
};
byte rowPins[ROWS] = {14, 15, 16, 17};
byte colPins[COLS] = {11, 10, 13,12};
Keypad customKeypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
char customKey;
float volume;
int step_volume_erogato=0;
String volumeS; // Variabile di ingresso
int numStepMotore;
const float r =6; // Raggio siringa
float Volume_residuo =5;
const int Step_per_giro = 200; //E' il numero di step per rotazione del motore per micro step (1/16)
const long velocita = 60; //E' la velocità del motore espressa in [giri/minuto]
//calcolo il delay in us tra uno step e l'altro per rispettare la velocità impostata
const long delayStepToStep = (60*pow(10,6)) / (velocita * Step_per_giro);
const long t = delayStepToStep/2; // in delayStepToStep calcolo il tempo tra un fronte di salita e quello successivo, per cui il tempo tra il fronte di salita e quello di discesa sarà la metà.
char comando;
String reset;
void setup() {
// Impostazione di pin
pinMode(X_DIR, OUTPUT); pinMode(X_STP, OUTPUT);
pinMode(Y_DIR, OUTPUT); pinMode(Y_STP, OUTPUT);
pinMode(Z_DIR, OUTPUT); pinMode(Z_STP, OUTPUT);
pinMode(EN, OUTPUT);
//pinMode(ms1, OUTPUT); pinMode(ms2, OUTPUT); pinMode(ms3, OUTPUT);
pinMode(Verde, OUTPUT);pinMode(Blu, OUTPUT);pinMode(Rosso, OUTPUT);
digitalWrite(EN, HIGH);
digitalWrite(Rosso, HIGH);
digitalWrite(Blu, HIGH);
digitalWrite(Verde, HIGH);
delay(1000);
//digitalWrite(ms1, HIGH); digitalWrite(ms2, HIGH); digitalWrite(ms3, HIGH);
}
void loop() {
digitalWrite(Verde, LOW);
digitalWrite(Rosso, LOW);
digitalWrite(Blu, HIGH);
cancella_schermo();
lcd.setCursor(0, 0);
lcd.print(F("Volume residuo: "));
lcd.setCursor(0, 1);
lcd.print(Volume_residuo);
lcd.setCursor(4, 1);
lcd.print(" ml");
delay(3000);
if(Volume_residuo>0){
cancella_schermo();
lcd.setCursor(0, 0);
lcd.print(F("Inserisci volume"));
lcd.setCursor(0, 1);
lcd.print(F("da erogare: "));
volumeS="";
do{
customKey = customKeypad.waitForKey();
if(customKey !='A' && customKey !='B' && customKey !='C' && customKey !='D' && customKey !='#'){
volumeS.concat(String(customKey));
lcd.setCursor(13, 1);
lcd.print(volumeS);
}
}while(customKey!='A'&& volumeS != "");
volume = volumeS.toFloat();
if(controllo_input(volume)){
cancella_schermo();
lcd.setCursor(0, 0);
lcd.print(F("Erogare "));
lcd.setCursor(8, 0);
lcd.print(volume);
lcd.setCursor(11, 0);
lcd.print(F("ml?"));
do{
customKey = customKeypad.waitForKey();
if(customKey=='B'){
cancella_schermo();
lcd.setCursor(0, 0);
lcd.print(F("Anullo"));
}
}while(customKey!='A'&&customKey!='B');
if(customKey=='A' ){
cancella_schermo();
lcd.setCursor(0, 0);
lcd.print(F("Avvio motore"));
Volume_residuo=Volume_residuo-volume;
numStepMotore= round(volume*1000*1/(r*r*3.14)*Step_per_giro/8);
step_volume_erogato = step_volume_erogato + numStepMotore;
delay (200);
muovi_motore(numStepMotore);
digitalWrite(Blu, HIGH);
digitalWrite(Verde, LOW);
digitalWrite(Rosso, LOW);
//
lcd.setCursor(0, 0);
lcd.print(F("Volume residuo: "));
lcd.setCursor(0, 1);
lcd.print(Volume_residuo);
lcd.setCursor(4, 1);
lcd.print(" ml");
delay(3000);
cancella_schermo();
lcd.setCursor(0, 0);
lcd.print(F("Vuole cambiare"));
lcd.setCursor(0, 1);
lcd.print(F("siringa? "));
do{
customKey = customKeypad.waitForKey();
}while(customKey!='A'&&customKey!='B');
if(customKey=='A'){
cancella_schermo();
lcd.setCursor(0, 0);
lcd.print(F("Rimuovere"));
lcd.setCursor(0, 1);
lcd.print(F("la siringa"));
do{
customKey = customKeypad.waitForKey();
}while(customKey!='A');
riavvia_motore(step_volume_erogato);
}
}
}
}else{
lcd.setCursor(0, 0);
lcd.print(F("Siringa vuota"));
digitalWrite(Blu, LOW);
digitalWrite(Verde, LOW);
digitalWrite(Rosso, HIGH);
lcd.setCursor(0, 1);
lcd.print(F("Inizzializare?"));
do{
customKey = customKeypad.waitForKey();
}while(customKey!='A'&&customKey!='B');
if(customKey=='A'){
riavvia_motore(step_volume_erogato);
}
}
}
// Da qui in poi, so solo funzioni
void muovi_motore(int numStepMotore){
digitalWrite(Blu, LOW);
digitalWrite(Verde, HIGH);
digitalWrite(Rosso, LOW);
digitalWrite(X_DIR, LOW); // rotazione antioraria
for (int i = 0; i < numStepMotore; i++) {
digitalWrite(X_STP, HIGH);
delayMicroseconds(t);
digitalWrite(X_STP, LOW);
delayMicroseconds(t);
}
digitalWrite(Blu, HIGH);
digitalWrite(Verde, LOW);
digitalWrite(Rosso, LOW);
}
bool controllo_input(float volume){
bool Input_valido=true;
if((volume*10)!= round(volume*10)){
cancella_schermo();
lcd.setCursor(0, 0);
lcd.print(F("Errore, troppe"));
lcd.setCursor(0, 1);
lcd.print(F("cifre decimali"));
Input_valido=false;
}
if(volume > Volume_residuo){
cancella_schermo();
lcd.setCursor(0, 0);
lcd.print(F("volume residuo"));
lcd.setCursor(0, 1);
lcd.print(F("insufficiente "));
Input_valido=false;
}
if(volume <= 0){
cancella_schermo();
lcd.setCursor(0, 0);
lcd.print("Error");
Input_valido=false;
}
return Input_valido;
}
void riavvia_motore(int step_volume_erogato){
digitalWrite(X_DIR, HIGH); // rotazione oraria
cancella_schermo();
lcd.setCursor(0, 0);
lcd.print(F("Riavvio motore"));
digitalWrite(Blu, LOW);
digitalWrite(Verde, HIGH);
digitalWrite(Rosso, LOW);
for (int i = 0; i < step_volume_erogato; i++) {
digitalWrite(X_STP, HIGH);
delayMicroseconds(t);
digitalWrite(X_STP, LOW);
delayMicroseconds(t);
}
Volume_residuo = 5;
digitalWrite(Blu, HIGH);
digitalWrite(Verde, LOW);
digitalWrite(Rosso, LOW);
}
void cancella_schermo(){
lcd.init();
lcd.backlight();
//lcd.setCursor(0, 0);
// lcd.print(" ");
// lcd.setCursor(0, 1);
// lcd.print(" ");
}