Greetings, I've been working in project about a Continuous positive always pressure(cpap)-like machine (for education purposes only), I've made it so that you write 5 modes on the EEPROM memory and those 5 modes have their specifications on to how fast to make the pump go, having in count that the pressure needs to gradually increase so that it "doesn't harm the patient", so it has an acceleration for increasing the speed, but it needs to keep the max speed for an determined time and then start decelerating so that when its velocity reaches zero it stops until I select another mode, it is in this part where where I have to make it keep working with the same speed for an amount of time where I have the problem. For the motor control I'm using an l298n and a matricial keyboard 4x4. So far I've coded this
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <EEPROM.h>
int estadoActual = 0;
int IN3 = 11;
int IN4 = 12;
int ENB = 13;
int velocidad = 0;
int velocidad_max = 0; // velocidad máxima permitida
const int velocidad_min = 0; // velocidad mínima permitida
const int aceleracion = 10; // cantidad de velocidad que aumenta o disminuye en cada ciclo de tiempo
const int tiempo_aceleracion = 500; // tiempo de espera entre cada ciclo de aceleración en milisegundos
// Definimos las variables para el teclado matricial y el display
const byte filas = 4;
const byte columnas = 4;
char teclas[filas][columnas] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte pinesFilas[filas] = {10, 9, 8, 7};
byte pinesColumnas[columnas] = {6, 5, 4, 3};
Keypad Teclado = Keypad( makeKeymap(teclas), pinesFilas, pinesColumnas, filas, columnas ); //Configura el teclado
LiquidCrystal_I2C lcd(0x27, 16, 2); // dirección I2C y tamaño del display
// definicion de funciones
char leerTeclado() {
char tecla;
for (byte i = 0; i < filas; i++) {
digitalWrite(pinesColumnas[i], LOW);
for (byte j = 0; j < columnas; j++) {
if (digitalRead(pinesFilas[j]) == LOW) {
tecla = teclas[j][i];
break;
}
}
digitalWrite(pinesColumnas[i], HIGH);
if (tecla != 0) {
break;
}
}
return tecla;
}
void setup() {
//saving modes in memory
EEPROM.write (0, 50);
EEPROM.write (1, 100);
EEPROM.write (2, 150);
EEPROM.write (3, 200);
EEPROM.write (4, 255);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
pinMode(ENB, OUTPUT);
Serial.begin(9600);
// Start up of keybord
for (byte i = 0; i < filas; i++) {
pinMode(pinesFilas[i], INPUT_PULLUP);
}
for (byte i = 0; i < columnas; i++) {
pinMode(pinesColumnas[i], OUTPUT);
digitalWrite(pinesColumnas[i], HIGH);
}
//lcd start and print
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Select Mode:");
Serial.print("Select Mode:");
}
//giving each key what mode they have to start
void loop() {
char tecla = leerTeclado();
if (tecla != NO_KEY) {
switch (tecla) {
case '1':
velocidad_max = EEPROM.read (0);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Modo 1 Seleccionado");
Serial.println("Modo 1 Seleccionado");
break;
case '2':
velocidad_max = EEPROM.read (1);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Modo 2 Seleccionado");
Serial.println("Modo 2 Seleccionado");
break;
case '3':
velocidad_max = EEPROM.read (2);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Modo 3 Seleccionado");
Serial.println("Modo 3 Seleccionado");
break;
case '4':
velocidad_max = EEPROM.read (3);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Modo 4 Seleccionado");
Serial.println("Modo 4 Seleccionado");
break;
case '5':
velocidad_max = EEPROM.read (4);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Modo 5 Seleccionado");
Serial.println("Modo 5 Seleccionado");
break;
default:
break;
}
}
//so that it doesn´t start until I say so
velocidad = estadoActual;
// gradual acceleration
while (velocidad < velocidad_max) {
velocidad += aceleracion;
if (velocidad > velocidad_max) {
velocidad = velocidad_max;
}
estadoActual = velocidad; // so if the mode it's interupted by a new key it doesn't start from zero, intead it starts where the other mode finisihed
analogWrite(ENB, velocidad);
Serial.println(velocidad);
delay(tiempo_aceleracion);
}
// gradual deceleration function
if (velocidad > velocidad_min) {
velocidad -= aceleracion;
if (velocidad < velocidad_min) {
velocidad = velocidad_min;
}
estadoActual = velocidad;
analogWrite(ENB, velocidad);
Serial.println(velocidad);
delay(tiempo_aceleracion);
}
// Motor activation
if (velocidad == velocidad_min) {
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
} else {
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
}
// Mode selection
char tecla_presionada = leerTeclado();
if (tecla_presionada != 0) {
// When a key is pressed it searches for the corrresponding
int modo = -1;
for (byte i = 0; i < filas; i++) {
for (byte j = 0; j < columnas; j++) {
if (teclas[i][j] == tecla_presionada) {
modo = i * columnas + j + 1;
break;
}
}
if (modo != -1) {
break;
}
}
// When a valid mode is found it starts up
if (modo != -1) {
lcd.clear();
lcd.print("Modo ");
Serial.print("Modo");
lcd.print(modo);
lcd.print(" seleccionado");
Serial.print(" seleccionado");
switch (modo) {
case 1:
// Acción correspondiente al modo 1
break;
case 2:
// Acción correspondiente al modo 2
break;
case 3:
// Acción correspondiente al modo 3
break;
case 4:
// Acción correspondiente al modo 4
break;
case 5:
// Acción correspondiente al modo 5
break;
default:
break;
}
}
}
}
Like I mentioned before the problem is when I try to make it work with time, I read about making a timer with millis but I can't completely understand how does the millis function work. I was hoping you could help me understand millis so that I can incorporate it on this code. My idea is that when the time finishes it starts up the decelerating funtion so that it reaches zero and wait for more intructions.
In advance, thank you.