/*
version 1.0
creacion para arduino nano
version 1.1
se añade configuracion limites apriete a maquita
se añade varios brazos
SIN VERIFICAR
version 1.2
se cambia de flanco subida a bajada en micro
VERSIÓN 1.3 JAVI
Se mdifica la adquisicion de los datos para que en la cadena solo esté el dato actual
En el reconocimiento de los datos se añade la lectura y reaccion a los comandos "M" e "I"
Se añade también multiples anotaciones para facil comprensión
Se ha modificado la ultima función (Estraer_aprietes)
Explicacion funcionamiento:
el programa esta estructurado por etapas que se ejecutan de forma secuencial para ir haciendo comprobaciones consecutivas
hasta que se confirma la copmprobación con las mayores restricciones, para que se cumpla una restricciones se tienen que cumlir las anteriores,
si no se cumplen las anteriores no se pasa a la siguiente
*****************************************************************************************
RESTRICCIONES:
0. Cumplir tiempo de pulsación de micro para pulsación valida
1. comprovar veces que se pulsa para ver en que brazo estamos
2. Obtener la respuesta y comprobar si el tempo de espera es excesivo
3. Analisis de los datos que se han recibido
4. Te devuelve a el "0" si estas en el "1" y no se ha cumplido el tiempo de pulsación correcta
5. Segmento "Manual" para la configuración de los limites pra los datos del atornillador
*****************************************************************************************
VERSIÓN 1.4 JAVI
Se añade la capacidad de conectar a más de una máquina
Se define función para elejir datos de una lista
De generan variables para llevar cuenta de la atornilladora a la que se le pide la informacion
OJO no se pueden meter más de 4 maquitas por servante
VERSIÓN 1.5 JAVI mododificacnón que permite comunicarse por el número "OP" de la máquina, para no tener nunca
que abrir la máquina para configurarla cada vez que se mete una nueva en un puesto
La cadena que se envia a la maqita para la petición de informacion es: S914493, de tal forma que el 914493 es el número op de la maquita
La cadena que se recibe es:
* "S914493XX" de forma que "XX" es el número de aprietes
* "R91449300" es el código de reinicio para que se le envie el número de aprietes
pin-out emisor
Module rf // Arduino
GND -> GND
Vcc -> 5V
Tx -> D10
Rx -> D11
SET -> D12
pin-out micro
13 -> cierra con masa
pin-out banner
BANNER // Arduino
1(rojo) -> 7
2(sirena) -> 6
3(masa) -> GND
4(verde) -> 9
5(amarillo) -> 8
Versión 1.6
Se akade la capacidad de detectar el modelos de coche mediante una combinación binaria que entra por los pines digitales 2 -5
PUENTE POR SOFTWARE---> BUSCAR ANULADO_1
2 --> bit1
3 --> bit2
4 --> bit4
5 --> bit5
ANULADO POR SOFTWARE
Se añade una función que convierta el valor bunario de 1 birs a decimal
Se añade también una función para llamar a los elementos de una metriz formada por strings, una funcion llama al elemeto de la primera columna y otra al elemento de la segunda comumna
se genera también una función para llamar al último elemento que será un entero que almacena el número de máquinas que tiene conectadas
*/
#include <SoftwareSerial.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <OneButton.h>
#include <EEPROM.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
struct MisDATOS {
long OP_M1;
short AP1;
long OP_M2;
short AP2;
long OP_M3;
short AP3;
long OP_M4;
short AP4;
};
int eeAddress = 0;
long OPM_M1 ;
long OPM_M2 ;
long OPM_M3 ;
long OPM_M4 ;
short APM1;
short APM2;
short APM3;
short APM4;
short matriz_A[4]={};
//definición de máquinas conectadas al servante **********************************************************
int num_conectadas ; //Número de máqunas conectadas al servante
String conectados;
String aprietes;
//Definimos matriz de datos de coche
/* La estructura de la matriz es:
* | (Nº OP), (Nº Aprietes), (Nº máquinas conectadas) | <--- modelo 1
* | (Nº OP), (Nº Aprietes), (Nº máquinas conectadas) | <--- modelo 2
* | (Nº OP), (Nº Aprietes), (Nº máquinas conectadas) | <--- modelo 3
* | (Nº OP), (Nº Aprietes), (Nº máquinas conectadas) | <--- modelo 4
* . . .
* . . .
* . . .
*
* (Nº OP) = "S914493;S914885;S914562;" // es muy impotante que termine siempre en ";"
* (Nº Aprietes) = "2;6;8;" //Taambién siempre tiene que terminar en ";" y en el mismo orden que la anterior ya que el primer numero de aprietes hace referencia a la primera maquina
* (Nº máquinas conectadas) = 3 //ya que es el numero total de máquinas en este ejemplo
*
*
* EJEMPLO:
* String matriz[filas][columnas] = {
* {"S914493;S914885;", "6;8;", "2"},
* {"S914493;S914885;S914562;", "2;6;8;", "3"},
* {"S914493;", "2;", "1"}
* };
*
*/
const int filas = 1;
const int columnas = 3;
/*String matriz[filas][columnas] = {
{"S914487;S914493;", "2;3;", "2"}
//{"S914487;", "2;", "1"}
};*/
String matriz[filas][columnas] = {};
OneButton incrementButton(14, true); // Botón para incrementar
OneButton selectButton(15, true); // Botón para seleccionar
OneButton modeButton(16, true); // Botón para cambiar el modo de incremento
int selectedField ; // Campo inicialmente seleccionado (OP_M1)
bool dataChanged = false; // Bandera para verificar si se han realizado cambios
bool incrementMode = true ; // Modo de incremento predeterminado
bool inc_PAR_APRIETE = true;
int Multiplicar =1;
long incrementa_por = 1;
long incrementAmount;
int casocampos=1;
//.................................DECLARACION ENTRADAS
const int PIN_RF_TX = 10;
const int PIN_RF_RX = 11;
const int PIN_BANNER_VERDE = 9;
const int PIN_BANNER_NARANJA = 8;
const int PIN_BANNER_ROJO = 7;
const int PIN_BANNER_SIRENA = 6;
const int PIN_MICRO = 13; // pin asociado al micro servante
//...................................................................................DEFINICIÓN PARÁMETROS
const int NUM_BRAZOS = 2;
int APRIETES_MIN; //numero de aprietes minimo para ser coche bueno en esa herramienta
int COMIENZO_APRIETE; // valor a partir del cual considera apriete bueno en ese ciclo
char COMANDO_SIN_RESPUESTA[] = "TIMEOUTTT"; //-32,768 to 32,767 ssmll >0. ser=01, maq=1, comand= 99=sin respuesta (codigo error en tiempo de respuesta)
String COMANDO_PETICION_APRIETES;
char codigo_res = 'E';
String cadena_entrada = "E01100000";
int tiempo_espera_respuesta = 5000; // espera por la respuesta de la pistola
int duracion_aviso = 8000; // duracion aviso encendido banner
//.............................................INICIALIZACIÓN DE VARIABLES
bool modo_errores = true;
bool zona_apriete = false;
bool rojo = false;
bool verde = false;
bool amarillo = false;
bool sirena = false;
bool estado_micro = LOW;
bool flanco_bajada = true;
int num_brazos_pulsados = 0; //posicion del brazo
char estado = '0';
//.............................................................................................................................PARAMETROS A CUMPLIR
int tiempo_estable_entrada = 50; // tiempo que tiene que mantenes la entrada el mismo estado para considerar pulsacion
int numero_aprietes = 0; // inicializamos la variable que guarda el numero de aprietes que devuelve la atornilladora.
int cont_numero_mediciones = 0;
int num_consecutivo_med_buenas = 10; //numero de valores medidos consecutivos para considerar apriete bueno.
//..........................................................DEINICIÓN DE TIEMPOS DE ACTIVACIÓN
unsigned long instante_envio; // milisegundos
unsigned long instante_actual; // milisegundos
unsigned long ult_activacion_verde = 0; // milisegundos
unsigned long ult_activacion_rojo = 0; // milisegundos
unsigned long ult_activacion_naranja = 0; // milisegundos
unsigned long ult_activacion_alarma = 0; // milisegundos
unsigned long tiempo_micro = 0;
//.......................DECLARACIONES GENERICAS
byte byte_entrada;
int maquina = 0; //inicializamos la variable de que maquita de la lista estamos pidiendo
String conectados_temp; //string de atornilladores que se va borrando en cada solicitud y después de pasar por todos se le vuelve a bolcar la original
//...............................................Para Pasar de binario a decimal
const int pin0 = 2; // Entrada digital 2
const int pin1 = 3; // Entrada digital 3
const int pin2 = 4; // Entrada digital 4
const int pin3 = 5; // Entrada digital 5
//...............................................LLAMADA A FUNCIONES CREADAS AL FINAL
SoftwareSerial HC12(PIN_RF_TX, PIN_RF_RX);
char extraer_comando(String coman);
int extraer_aprietes(String coman);
void actualizar_banner();
void actualizar_banner_pin(unsigned long t_aux,unsigned long ult_act, int pin);
String seleccionar_dato (String lista, int indice);
int convertirBinarioADecimal();
String asignarcolumna1(const char* matriz[filas][columnas], int numeroFila);
String asignarcolumna2(const char* matriz[filas][columnas], int numeroFila);
int asignarcolumna3(const char* matriz[filas][columnas], int numeroFila);
//*******************************************************************************************************
void setup()
{
Serial.begin(9600);
//check serial connection
while(!Serial){
Serial.println("Serial not available..");
delay(1000);
}
Serial.println("Serial available..");
if (modo_errores)
{Serial.begin(9600); // comunicación con pc ¿19,200?
}
HC12.begin(9600); // comunicación con HC12
//check serial connection
Wire.begin();
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
pinMode(14, INPUT); // configura ‘14’ como salida A0
pinMode(15, INPUT); // configura ‘15’ como salida A1
pinMode(16, INPUT); // configura ‘16’ como salida A2
pinMode(pin0, INPUT);
pinMode(pin1, INPUT);
pinMode(pin2, INPUT);
pinMode(pin3, INPUT);
//HC12.setTimeout(2000); // por defecto 1000.
pinMode(PIN_BANNER_VERDE, OUTPUT);
pinMode(PIN_BANNER_NARANJA, OUTPUT);
pinMode(PIN_BANNER_ROJO, OUTPUT);
pinMode(PIN_BANNER_SIRENA, OUTPUT);
pinMode(PIN_MICRO, INPUT_PULLUP);
digitalWrite(PIN_BANNER_SIRENA, HIGH);
digitalWrite(PIN_BANNER_VERDE, HIGH);
digitalWrite(PIN_BANNER_NARANJA, HIGH);
digitalWrite(PIN_BANNER_ROJO, HIGH);
instante_envio = millis();
estado = '0';
delay(9000);// esperamos inicializar comunicacion y apagar los banner inicialmente
MisDATOS data;
int eeAddress = sizeof(MisDATOS);
EEPROM.get(eeAddress,data);
OPM_M1 = data.OP_M1;
APM1 = data.AP1;
OPM_M2 = data.OP_M2;
APM2 = data.AP2;
OPM_M3 = data.OP_M3;
APM3 = data.AP3;
OPM_M4 = data.OP_M4;
APM4 = data.AP4;
matriz_A[0]= APM1;
matriz_A[1]= APM2;
matriz_A[2]= APM3;
matriz_A[3]= APM4;
int contador_Ap = 0;
for (int i = 0; i < sizeof(matriz_A) / sizeof(matriz_A[0]); i++) {
if (matriz_A[i] > 0) {
contador_Ap++;
}
}
matriz [0][0]=
((OPM_M1 > 0) ? "S" + String(OPM_M1) + ";" : "") +
((OPM_M2 > 0) ? "S" + String(OPM_M2) + ";" : "") +
((OPM_M3 > 0) ? "S" + String(OPM_M3) + ";" : "") +
((OPM_M4 > 0) ? "S" + String(OPM_M4) + ";" : "");
matriz [0][1]=
((OPM_M1 > 0) ? String(matriz_A[0]) + ";" : "") +
((OPM_M2 > 0) ? String(matriz_A[1]) + ";" : "") +
((OPM_M3 > 0) ? String(matriz_A[2]) + ";" : "") +
((OPM_M4 > 0) ? String(matriz_A[3]) + ";" : "");
matriz [0][2]=
((contador_Ap>0) ? String(contador_Ap) + ";" : "");
// Inicializa la pantalla OLED
display.display();
delay(2000); // Espera 2 segundos antes de borrar la pantalla
display.clearDisplay();
display.display();
// Configura los botones
incrementButton.attachClick(onIncrementButtonClick);// incrementa el campo OP O AP que esté seleccionado
selectButton.attachClick(onSelectButtonClick);// abre el menu para modificar los datos y selecciona la línea donde modificiar la máquina
selectButton.attachDoubleClick(onSelectButtonDblClick); // selecciona entre rellenar la OP o el Numero de AP
selectButton.attachDuringLongPress(onSelectButtonLongPress);// Valida los datos y rearma las variables de OP y AP que hayan evolucionado.
modeButton.attachClick(onModeButtonClick); // selecciona en que u, decena de unidad estamos en el caso de OP para modificar el número de la op
modeButton.attachDoubleClick(onModeButtonDblClick); // selecciona entre incrementar Normal +1 o Inverso -1. afectado por el multiplicador segun sea OP o AP
// chequeo luces
}
//*******************************************************************************************************
void loop()
{
estado_micro = digitalRead(PIN_MICRO);
incrementButton.tick(); // Monitorea el botón "Increment"
selectButton.tick(); // Monitorea el botón "Select"
modeButton.tick(); // Monitorea el botón "Mode"
Serial.println("Esto funciona");
//---------------------------------------------------------- Comprobación tiempo pulsación
if (estado == '0'){
int numero = convertirBinarioADecimal();
conectados = asignarcolumna1(matriz, numero);
aprietes = asignarcolumna2(matriz, numero);
num_conectadas = asignarcolumna3(matriz, numero);
conectados_temp = conectados; //Reiniciamos la lista atornilladores a los que hay que solicitar aprietes
//esperando despulsacion micro
if (estado_micro == HIGH){ //EN LA PRIMERA ESTA LOW
//verificamos si es el flanco de bajada
if (flanco_bajada == true){ //FLANCO EN PRIMERA ESTA TRUE
flanco_bajada = false;
tiempo_micro = millis(); //memorizacion de tiempo desde encendido hasta pulsacion
}
else{
//verificamos si ya paso el tiempo a 0 minimo
if (tiempo_micro + tiempo_estable_entrada < millis()){ // se comprueba que entre la ultima vez que se guardo el tiempo (cuando se detecto la pulsación) y esta ha pasado
// el tiempo definido en la función "tiempo estable entrara" para poder sonsiderar que la pulsación es valida
//entrada estable
estado = '1'; // si pulsación perfecta, pasamos al siguiente punto
flanco_bajada = true;
}
}
}
else{ //ESTO ES EL GUARDAR VALOR ENTERIOR BAJO PARA FLANCO
//entrada pulsada
flanco_bajada = true;
}
}
//---------------------------------------------------------- Comprobación fin de puerta
else if (estado == '1'){
//verificamos si estamos en el brazo bueno comprobando las veces que se ha pulsado el micro
num_brazos_pulsados +=1;
Serial.println("Estado 1.");
if (num_brazos_pulsados >= NUM_BRAZOS){
if (maquina < num_conectadas){
maquina = maquina + 1;
}
else if (maquina == num_conectadas){
maquina = 1;
}
if (maquina == num_conectadas){ //si ya es la ultima máquina reiniciamos contador de brazo
num_brazos_pulsados = 0;
}
// pedimos datos a la pistola cuando se detecta que se termino la puerta
Serial.println(maquina);
Serial.print("Enviando solicitud de datos: ");
//aquí es donde se modifica el código para probar si finciona con más de una maquita
COMANDO_PETICION_APRIETES = seleccionar_dato (conectados, maquina);
APRIETES_MIN = seleccionar_dato (aprietes, maquina).toInt();
Serial.println(COMANDO_PETICION_APRIETES);
HC12.print(COMANDO_PETICION_APRIETES); //se envia codigo de petición
HC12.flush();
instante_envio = millis(); //Se guarda el momento en el que se hace el envio para luego comprobar cuanto tarda y si comprobar si se pierde la conexión
cadena_entrada = "";
estado = '2'; //se pasa a la siguiente etapa
}
else{
estado = '4'; //te manda a esperar el tiempo de pulsación correcta y una vez este se ha cumplido volvemos a la "0" para volver a comprobar
}
}
//---------------------------------------------------------- Obtener la respuesta y comprobarla y mirar si ha pasado demasiado tiempo sin respuesta
else if (estado == '2'){
// esperamos respuesta de pistola
//Serial.println("Estado 2.");
if (HC12.available())
{cadena_entrada = HC12.readString();
cadena_entrada.trim();
Serial.println(cadena_entrada);
}
HC12.flush();
if (cadena_entrada.length() == 9){ //se comprueba formato correcto y se pasa a siguiente etapa
//respuesta de la pistola
estado = '3';
HC12.flush();
}
else{
// aun sin respuesta
instante_actual = millis();
/*
Serial.print("Instante actual: ");
Serial.println(instante_actual);
Serial.print("Instante envio: ");
Serial.println(instante_envio);
*/
if (instante_actual < instante_envio){ //Entiendo qu esta hecho por si se ha vuelto a reinicial la cuenta del tiempo
instante_envio = instante_actual;
//overflow
}
else if ((instante_envio + tiempo_espera_respuesta) <= instante_actual){
//pistola no responde ya que se paso del tiempo de espera
cadena_entrada = COMANDO_SIN_RESPUESTA;
instante_envio = instante_actual;
estado = '3';
}
}
}
//---------------------------------------------------------- Analisis de los datos recibidos
else if (estado == '3'){
/*
Serial.print("El número se la máquina es: ");
Serial.println(maquina);
Serial.print("El númmero con el que compara: ");
Serial.println(num_conectadas);
*/
//analizamod respuesta de la pistola.
Serial.println("Estado 3");
if (modo_errores)
{Serial.print("Datos de la pistola: ");
Serial.println(cadena_entrada);
}
codigo_res = extraer_comando(cadena_entrada); //obtenemos la letra del comando que ha llegado
Serial.println(codigo_res);
if (codigo_res == 'E'){
//error en la recepcion de la trama
ult_activacion_naranja = millis();
estado = '4';
num_brazos_pulsados = 0;
}
else if (codigo_res == 'T'){
//sin respuesta de la maquina
ult_activacion_naranja = millis();
if (maquina < num_conectadas){
estado = '1'; //si aún no han pasado todas, pasamos a la siguiente
}
else{
estado = '4'; //si ya han pasado todas, terminamos ciclo
num_brazos_pulsados = 0;
}
}
else if (codigo_res == 'M'){
//Respuesta que era para otra máquina
ult_activacion_naranja = millis();
estado = '4';
num_brazos_pulsados = 0;
}
else if (codigo_res == 'S'){
//respuesta correcta al numero de aprietes
numero_aprietes = extraer_aprietes(cadena_entrada);
if (numero_aprietes >= APRIETES_MIN)
{//cerramos coche bueno
if (modo_errores)
{Serial.println("Coche bueno:");
Serial.print("Numero minimo de aprietes: ");
Serial.print(APRIETES_MIN);
Serial.print(", y la pistola retorna: ");
Serial.println(numero_aprietes);
}
ult_activacion_verde = millis();
if (maquina < num_conectadas){
estado = '1'; //si aún no han pasado todas, pasamos a la siguiente
instante_envio = millis();
}
else{
estado = '4'; //si ya han pasado todas, terminamos ciclo
num_brazos_pulsados = 0;
}
}
else{//cerramos coche malo
if (modo_errores)
{Serial.println("Coche MALOs:");
Serial.print("Numero minimo de aprietes: ");
Serial.print(APRIETES_MIN);
Serial.print(", y la pistola retorna: ");
Serial.println(numero_aprietes);
}
ult_activacion_rojo = millis();
ult_activacion_alarma = millis();
estado = '4'; //si es malo cerramos directamente, no comprobamos las demás
num_brazos_pulsados = 0;
Serial.print("COM numero máquina :");
Serial.println(maquina);
maquina = num_conectadas;
if (maquina < num_conectadas){
//estado = '1'; //si aún no han pasado todas, pasamos a la siguiente
estado = '4';
maquina = 0;
num_brazos_pulsados = 0;
instante_envio = millis();
Serial.print("Instante envio: ");
Serial.println(instante_envio);
}
else{
estado = '4'; //si ya han pasado todas, terminamos ciclo
num_brazos_pulsados = 0;
maquina = 0;
}
}
}
else{
estado = '4';
}
cadena_entrada = "";
}
//---------------------------------------------------------- Devolucion a punto inicial
else if (estado == '4'){
//esperando pulsacion micro
if (estado_micro == LOW)
{estado = '0';
HC12.flush(); //función para vaciar el bufer de salida del arduino
delay(tiempo_estable_entrada); //garantizamos esperando este tiempo que esta todo es posición para empezar de nuevo
}
}
//----------------------------------------------------------
else{
// no se tiene que dar
Serial.println("Estado default.");
estado = '0';
num_brazos_pulsados = 0;
if (modo_errores)
{Serial.println("Maquina virtual en estado erroneo, REINICIANDO ESTADO MAQUINA....");
}
}
}
//*********************************************************************************************
//DECLARACIÓN DE LAS FUNCIONES
//---------------------------------------------------------- llamada a cada activación
void actualizar_banner()
{unsigned long tiempo_aux = millis();
//lo que hacemos en esta función es meter en la siguiente (tiempo actual, tiempo ultima vez que se activó, pin en el que se tiene que activar)
actualizar_banner_pin(tiempo_aux, ult_activacion_rojo, PIN_BANNER_ROJO);
actualizar_banner_pin(tiempo_aux, ult_activacion_alarma, PIN_BANNER_SIRENA);
if (digitalRead(PIN_BANNER_ROJO) == HIGH){ //hacemos la primera prioridad, solo miramos de encender el naranja si el rojo está apagado, si no apagamos directamente naranja y verde
actualizar_banner_pin(tiempo_aux, ult_activacion_naranja, PIN_BANNER_NARANJA);
}
else{
digitalWrite(PIN_BANNER_NARANJA, HIGH);
digitalWrite(PIN_BANNER_VERDE, HIGH);
/*
if (modo_errores)
{Serial.print("Apagamos el pin: ");
Serial.println(PIN_BANNER_NARANJA);
Serial.print("Apagamos el pin: ");
Serial.println(PIN_BANNER_VERDE);
}
*/
}
if (digitalRead(PIN_BANNER_ROJO) == HIGH && digitalRead(PIN_BANNER_NARANJA) == HIGH){ //Segunda prioridad, solo encendemos verde si rojo u naranga apagado, sino apagamos verde
actualizar_banner_pin(tiempo_aux, ult_activacion_verde, PIN_BANNER_VERDE);
}
else{
digitalWrite(PIN_BANNER_VERDE, HIGH);
/*
if (modo_errores)
{Serial.print("Apagamos el pin: ");
Serial.println(PIN_BANNER_VERDE);
}
*/
}
}
//---------------------------------------------------------- Activación individual de cada salida en funcion de cuando se ha pedido que se activen
void actualizar_banner_pin(unsigned long t_aux, unsigned long ult_act, int pin)
{if ((ult_act + duracion_aviso) > t_aux) //si se ha activado hace un tiempo inferior al de aviso es que pertenece a este aviso y hay que activarlo
{//encender BANNER
digitalWrite(pin, LOW);
/*
if (modo_errores)
{Serial.print("Encendemos el pin: ");
Serial.println(pin);
}
*/
}
else
{//apagar salida si se ha activado hace más de un tiempo de aviso es que ya pertenece al aviso anterior
digitalWrite(pin, HIGH);
/*
if (modo_errores)
{Serial.print("Apagamos el pin: ");
Serial.println(pin);
}
*/
}
}
//---------------------------------------------------------- Extraemos la letra inicial para ver que tipo de comando es el que ha llegado
char extraer_comando(String coman)
{//son 9 caracteres siempre
/*
S--> peticion numero de aprietes
Pregunta:
"S985623";//s=comando, 985623=codigo máquina
Respuesta:
"S98562300";//s=comando, 985623=codigo máquina, 00=dato
*/
int numero_caracteres = 9;
char m_comando = 'E';
String m_maquina = coman.substring(0, 7);
if (coman.length() != numero_caracteres)
{//tamaño incorrecto
return 'E';
}
else if (coman == "TIMEOUTTT")
{return 'T';
}
else if (m_maquina != COMANDO_PETICION_APRIETES)
{//este comando no es para esta maquina
return 'M';
}
else {
m_comando = coman[0];
return m_comando;
}
}
//---------------------------------------------------------- Se recoje el valor que se envia
int extraer_aprietes(String coman)
{//son 9 caracteres siempre
/*
S--> peticion numero de aprietes
Pregunta:
"S98562300";//s=comando, 985623=codigo máquina, 00=dato
*/
String s_temporal = coman;
s_temporal.remove(0,7);
int i_temporal = s_temporal.toInt();
return i_temporal;
}
//---------------------------------------------------------- Elejir elemento de la lista
String seleccionar_dato (String lista, int indice){
int separadorIndex = lista.indexOf(';'); //Buscar la posición del separador
int contador = 0;
while (separadorIndex >= 0) { //Mientras se encuentren separadores
String bloque = lista.substring(0, separadorIndex); //Extraer el bloque de datos
contador += 1;
if (contador == indice){
return bloque;
}
lista = lista.substring(separadorIndex+1); //Eliminar el bloque de la cadena
separadorIndex = lista.indexOf(';'); //Buscar la posición del siguiente separador
}
}
//---------------------------------------------------------- Función para pasar de binario a decimal
int convertirBinarioADecimal() {
int bit0 = digitalRead(pin0);
int bit1 = digitalRead(pin1);
int bit2 = digitalRead(pin2);
int bit3 = digitalRead(pin3);
int decimal = bit0 + bit1 * 2 + bit2 * 4 + bit3 * 8;
//PUENTE POR SOFTWARE---> BUSCAR ANULADO_1
decimal = 0;
//ANULADO POR SOWTWARE
return decimal;
}
//-------------------------------------------------------- Función para asignar la primera columna de la matriz
String asignarcolumna1(String matriz[filas][columnas], int numeroFila) {
if (numeroFila >= 0 && numeroFila < filas) {
return matriz[numeroFila][0];
} else {
return ""; // Si el número de fila está fuera de rango, devolver una cadena vacía
}
}
//-------------------------------------------------------- Función para asignar la segunda columna de la matriz
String asignarcolumna2(String matriz[filas][columnas], int numeroFila) {
if (numeroFila >= 0 && numeroFila < filas) {
return matriz[numeroFila][1]; // Acceder a la segunda columna de la matriz
} else {
return ""; // Si el número de fila está fuera de rango, devolver una cadena vacía
}
}
//-------------------------------------------------------- Función para asignar la tercera columna de la matriz
int asignarcolumna3(String matriz[filas][columnas], int numeroFila) {
if (numeroFila >= 0 && numeroFila < filas) {
int numeroEntero = matriz[numeroFila][2].toInt();
return numeroEntero;// Acceder a la segunda columna de la matriz
} else {
return ""; // Si el número de fila está fuera de rango, devolver una cadena vacía
}
}
// FUNCIONES PANTALLA
// ---- BOTON INCREMENTAR
void onIncrementButtonClick() {
// Incrementa o decrementa el valor del campo seleccionado según el modo
casocampos = inc_PAR_APRIETE ? 1 : 2 ;
incrementAmount = (incrementMode ? 1 : -1)*incrementa_por;
switch (casocampos){
case 1:
switch (selectedField) {
case 1:
OPM_M1 += incrementAmount;
if (OPM_M1 > 999999) {
OPM_M1 = 999999; // Limita el valor máximo
} else if (OPM_M1 < 0) {
OPM_M1 = 0; // Limita el valor mínimo
}
break;
case 2:
OPM_M2 += incrementAmount;
if (OPM_M2 > 999999) {
OPM_M2 = 999999;
} else if (OPM_M2 < 0) {
OPM_M2 = 0;
}
break;
case 3:
OPM_M3 += incrementAmount;
if (OPM_M3 > 999999) {
OPM_M3 = 999999;
} else if (OPM_M3 < 0) {
OPM_M3 = 0;
}
break;
case 4:
OPM_M4 += incrementAmount;
if (OPM_M4 > 999999) {
OPM_M4 = 999999;
} else if (OPM_M4 < 0) {
OPM_M4 = 0;
}
break;
}
displayData();
break;
case 2:
switch (selectedField) {
case 1:
APM1 += incrementAmount;
if (APM1> 99) {
APM1 = 99; // Limita el valor máximo
} else if (APM1 < 0) {
APM1 = 0; // Limita el valor mínimo
}
break;
case 2:
APM2 += incrementAmount;
if (APM2> 99) {
APM2 = 99; // Limita el valor máximo
} else if (APM2 < 0) {
APM2 = 0; // Limita el valor mínimo
}
break;
case 3:
APM3 += incrementAmount;
if (APM3> 99) {
APM3 = 99; // Limita el valor máximo
} else if (APM3 < 0) {
APM3 = 0; // Limita el valor mínimo
}
break;
case 4:
APM4 += incrementAmount;
if (APM4> 99) {
APM4 = 99; // Limita el valor máximo
} else if (APM4 < 0) {
APM4 = 0; // Limita el valor mínimo
}
displayData();
break;
}
}
dataChanged = true;
displayData();
}
//-- BOTON INCREMENTAR
// ---- BOTON MODO
void onModeButtonDblClick()
{
// Cambia el modo de incremento (normal o inverso)
incrementMode = !incrementMode;
displayData();
}
void onModeButtonClick()
{
// Cambia el modo de incremento (normal o inverso)
Multiplicar++;
if (Multiplicar > 6) {
Multiplicar = 1; // Vuelve a seleccionar el primer campo
}
if (casocampos==1){
if(Multiplicar ==1) incrementa_por =1;
if(Multiplicar ==2) incrementa_por =10;
if(Multiplicar ==3) incrementa_por =100;
if(Multiplicar ==4) incrementa_por =1000;
if(Multiplicar ==5) incrementa_por =10000;
if(Multiplicar ==6) incrementa_por =100000;
}
else{
Multiplicar = 1;
incrementa_por =1;
}
displayData();
}
// ---- BOTON MODO
// ---- BOTON SELECCION
void onSelectButtonClick()
{
Serial.println("Boton Select Pulsado");
// Cambia el campo seleccionado al siguiente
selectedField++;
if (selectedField > 4) {
selectedField = 1; // Vuelve a seleccionar el primer campo
}
displayData();
}
void onSelectButtonDblClick()
{
inc_PAR_APRIETE = !inc_PAR_APRIETE;
Multiplicar =1;
incrementa_por =1;
displayData();
}
void onSelectButtonLongPress()
{
// https://www.electrodaddy.com/trabajar-con-memoria-eeprom-arduino/ Guarda los datos en la memoria Preferences si se mantiene presionado el botón "Select" y se han realizado cambios
int eeAddress = 0;
if (dataChanged) {
MisDATOS data = {
OPM_M1,
APM1,
OPM_M2,
APM2,
OPM_M3,
APM3,
OPM_M4,
APM4
};
eeAddress += sizeof(MisDATOS);
EEPROM.put(eeAddress, data);
eeAddress = 0;
EEPROM.get(eeAddress,data);
OPM_M1 = data.OP_M1;
APM1 = data.AP1;
OPM_M2 = data.OP_M2;
APM2 = data.AP2;
OPM_M3 = data.OP_M3;
APM3 = data.AP3;
OPM_M4 = data.OP_M4;
APM4 = data.AP4;
matriz_A[0]= APM1;
matriz_A[1]= APM2;
matriz_A[2]= APM3;
matriz_A[3]= APM4;
int contador_Ap = 0;
for (int i = 0; i < sizeof(matriz_A) / sizeof(matriz_A[0]); i++) {
if (matriz_A[i] > 0) {
contador_Ap++;
}
}
matriz [0][0]=
((OPM_M1 > 0) ? "S" + String(OPM_M1) + ";" : "") +
((OPM_M2 > 0) ? "S" + String(OPM_M2) + ";" : "") +
((OPM_M3 > 0) ? "S" + String(OPM_M3) + ";" : "") +
((OPM_M4 > 0) ? "S" + String(OPM_M4) + ";" : "");
matriz [0][1]=
((OPM_M1 > 0) ? String(matriz_A[0]) + ";" : "") +
((OPM_M2 > 0) ? String(matriz_A[1]) + ";" : "") +
((OPM_M3 > 0) ? String(matriz_A[2]) + ";" : "") +
((OPM_M4 > 0) ? String(matriz_A[3]) + ";" : "");
matriz [0][2]=
((contador_Ap>0) ? String(contador_Ap) + ";" : "");
dataChanged = false;
// Mostrar "Datos OK" durante 2 segundos
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Datos OK");
display.display();
Serial.println(matriz[0][0]);
unsigned long startTime = millis();
while (millis() - startTime < 2000) {
// Espera durante 2 segundos
}
Multiplicar =1;
incrementa_por =1;
display.clearDisplay();
display.display();
//esperando pulsacion micro
}
else{
Multiplicar =1;
incrementa_por =1;
display.clearDisplay();
display.display();
//esperando pulsacion micro
}
}
// ---- ACTUALIZACION PANTALLA
void displayData() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.print("Field: ");
display.print(selectedField);
display.print(" U x :");
display.println(incrementa_por);
display.print("OP o AP : ");
display.println(inc_PAR_APRIETE ? "OP" : "AP");
display.print("Mode: ");
display.println(incrementMode ? "Normal" : "Inverso");
display.print("OPM1: ");
display.print(OPM_M1);
display.print(" AP1: ");
display.println(APM1);
display.print("OP2: ");
display.print(OPM_M2);
display.print(" AP2: ");
display.println(APM2);
display.print("OP3 ");
display.print(OPM_M3);
display.print(" AP3: ");
display.println(APM3);
display.print("OP4: ");
display.print(OPM_M4);
display.print(" AP4: ");
display.println(APM4);
display.display();
}