Hola a todos,
Quería exponeros mi problema, a ver si me ilumináis con una solución:
Tengo un Arduino Mega 2560 que lee varios sensores de presión y namures de presencia.
También está conectado a una placa de 8 relés, los cuales activan unos motores industriales.
Arduino Mega también se conecta por el puerto USB con un PC y un programa de Visual Basic 6.0, el cual manda instrucciones a Arduino para controlar los relés.
El problema es que, muy esporadicamente, la conexión entre Arduino y el PC se bloquea, y esto conlleva que Arduino pone sus salidas digitales a 0 y activa todos los relés, algo que no se puede dar porque estos relés controlan varios motores y sus sentidos de giro, y provoca que salten los diferenciales.
Inclusive reseteando Arduino, no se soluciona el problema, la única solución que de momento funciona es desconectar el cable USB y volver a conectar.
Os pongo parte del código (no puedo incluir más de 9500 caracteres en el post):
#include <Serial.h>
#include <IRremote.h>
//Constantes
const int namurIpre = 30;
const int namurDpre = 28;
const int namurImov = 26;
const int namurDmov = 32;
const int namurAliEntrada = 25;
const int namurAliSalida = 27;
const int rele01 = 41;
const int rele02 = 42;
const int rele03 = 43;
const int rele04 = 44;
const int rele05 = 45;
const int rele06 = 46;
const int rele07 = 47;
const int rele08 = 48;
const int resetear = 10;
const int RECV_PIN = 12; // Entrada de mando a distancia
//Variables
byte dataOut[52];
byte dataIn;
byte setState[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
boolean responder = false;
unsigned int contador = 0;
int estadoNamurIzq = 0;
int estadoNamurIzqAnterior = 0;
int estadoNamurDer = 0;
int estadoNamurDerAnterior = 0;
unsigned long tiempoNamurIzq = 0;
unsigned long tiempoNamurIzqAnterior = 0;
unsigned long tiempoNamurIzqPulso = 0;
unsigned int tiempoNamurDer = 0;
unsigned int tiempoNamurDerAnterior = 0;
unsigned int tiempoNamurDerPulso = 0;
int lectura = 0;
IRrecv irrecv(RECV_PIN);
decode_results results;
unsigned long control = 2263073215;
unsigned long dato;
boolean dentro = false;
byte mandoByteAlto = 0;
byte mandoByteBajo = 0;
unsigned int AD1 = 0;
unsigned int AD2 = 0;
unsigned int AD3 = 0;
unsigned int AD4 = 0;
unsigned int AD5 = 0;
unsigned int AD6 = 0;
//Setup
void setup(){
pinMode(resetear, OUTPUT);
digitalWrite(resetear, LOW);
delay(5);
digitalWrite(resetear, HIGH);
pinMode(namurIpre, INPUT);
pinMode(namurDpre, INPUT);
pinMode(namurImov, INPUT);
pinMode(namurDmov, INPUT);
pinMode(rele01, OUTPUT);
digitalWrite(rele01, HIGH);
pinMode(rele02, OUTPUT);
digitalWrite(rele02, HIGH);
pinMode(rele03, OUTPUT);
digitalWrite(rele03, HIGH);
pinMode(rele04, OUTPUT);
digitalWrite(rele04, HIGH);
pinMode(rele05, OUTPUT);
digitalWrite(rele05, HIGH);
pinMode(rele06, OUTPUT);
digitalWrite(rele06, HIGH);
pinMode(rele07, OUTPUT);
digitalWrite(rele07, HIGH);
pinMode(rele08, OUTPUT);
digitalWrite(rele08, HIGH);
pinMode(RECV_PIN, INPUT);
Serial.begin(19200);
Serial1.begin(57600);
irrecv.enableIRIn(); // Se inicializa la recepción del mando a distancia
delay(200);
}
//Principal
void loop(){
//Lee el puerto serie. Si es un comando, guarda la información en los registros correspondientes
leerPuertoSerie();
//Actualiza el estado de los motores activando y desactivando los relés correspodientes
actualizaEstadoMotores();
//Control contador de vueltas de namur de resbalamiento izquierdo y tiempo entre pulsos de ambos namures
controlContadorNamur();
//Lectura de galgas de presión provenientes de otro Arduino
lecturaGalgas();
//Si el PC está esperando uan respuesta, se genera y se envía
respuesta();
//Control para imprimir por puerto serie la trama 0x81 enviando un 1
//imprimirPuertoSerie();
delay(5);
}
//Subprogramas
//Escribe en el puerto serie la trama del comando 0x81
int escribirPuertoSerie(){
Serial.write(dataOut, sizeof(dataOut));
//Serial.write(dataOut[0]);
return 0;
}
//Lee el puerto serie. Si es un comando, guarda la información en los registros correspondientes
int leerPuertoSerie(){
//Se comprueba si hay datos en el puerto serie
if (Serial.available() > 0){
//Si hay datos, se lee el primer byte, que debe ser un 0
dataIn = Serial.read();
//Se lee el segundo byte, que contiene el comando de instrucción
//dataIn = Serial.read();
//Si el segundo byte es 0x80, son instrucciones de estado
if (dataIn == 0x80){
setState[2] = Serial.read(); //Segundo byte (Rele high byte)
setState[3] = Serial.read(); //Tercer byte (Rele low byte)
setState[4] = Serial.read(); //DAC 1
setState[5] = Serial.read(); //DAC 2
setState[6] = Serial.read(); //DAC 3
setState[7] = Serial.read(); //DAC 4
setState[8] = Serial.read(); //CheckSum
//Se debe responder con el comando 0x81
responder = true;
}
}
//Se vacía el buffer del puerto serie
Serial.flush();
}
return 0;
}
//StatusData Cmd 0x81 52 bytes
int statusData(){
dataOut[0] = 0x00;
dataOut[1] = 0x81;
//Sensores namures (1-2)
dataOut[2] = namurAlto();
dataOut[3] = namurBajo();
//Digital Input
dataOut[4] = 0x00;
//Remote Control
//mandoControlRemoto();
dataOut[5] = mandoByteAlto;
dataOut[6] = mandoByteBajo;
dataOut[7] = 0x00;
dataOut[8] = 0x00;
//Left wheel speed
dataOut[9] = highByte(tiempoNamurIzqPulso);
dataOut[10] = lowByte(tiempoNamurIzqPulso);
//Rigth wheel speed
dataOut[11] = highByte(tiempoNamurDerPulso);
dataOut[12] = lowByte(tiempoNamurDerPulso);
//Left wheel count
dataOut[13] = highByte(contador);
dataOut[14] = lowByte(contador);
//Left motor speed
dataOut[15] = 0x00;
dataOut[16] = 0x00;
//Rigth motor speed
dataOut[17] = 0x00;
dataOut[18] = 0x00;
//AD1
dataOut[19] = highByte(AD1);
dataOut[20] = lowByte(AD1);
//AD2
dataOut[21] = highByte(AD2);
dataOut[22] = lowByte(AD2);
//AD3
dataOut[23] = highByte(AD3);
dataOut[24] = lowByte(AD3);
//AD4
dataOut[25] = highByte(AD4);
dataOut[26] = lowByte(AD4);
//AD5
dataOut[27] = highByte(AD5);
dataOut[28] = lowByte(AD5);
//AD6
dataOut[29] = highByte(AD6);
dataOut[30] = lowByte(AD6);
//AD7
dataOut[31] = 0x00;
dataOut[32] = 0x00;
//AD8
dataOut[33] = 0x00;
dataOut[34] = 0x00;
//AD9
dataOut[35] = 0x00;
dataOut[36] = 0x00;
//AD10
dataOut[37] = 0x00;
dataOut[38] = 0x00;
//AD11
dataOut[39] = 0x00;
dataOut[40] = 0x00;
//AD12
dataOut[41] = 0x00;
dataOut[42] = 0x00;
//Left wheel speed bit 31-24
dataOut[43] = 0x00;
//Left wheel speed bit 23-16
dataOut[44] = 0x00;
//Left wheel speed bit 15-8
dataOut[45] = 0x00;
//Left wheel speed bit 7-0
dataOut[46] = 0x00;
//Rigth wheel speed bit 31-24
dataOut[47] = 0x00;
//Rigth wheel speed bit 23-16
dataOut[48] = 0x00;
//Rigth wheel speed bit 15-8
dataOut[49] = 0x00;
//Rigth wheel speed bit 7-0
dataOut[50] = 0x00;
//CheckSum Sum(n Bytes) XOR 0xFF
dataOut[51] = 0x00;
int i;
for(i=0; i<sizeof(dataOut)-1; i++){
dataOut[52] = dataOut[52] + dataOut[i];
}
dataOut[52] = dataOut[52] ^ 0xFF; //XOR 0xFF;
//Return
return 0;
}
//Actualiza el estado de los motores activando y desactivando los relés correspodientes
int actualizaEstadoMotores(){
//Motores en rele low byte
if (bitRead(setState[3], 0) == 1){ //Relé 01
digitalWrite(rele01, LOW);
}
else{
digitalWrite(rele01, HIGH);
}
if (bitRead(setState[3], 1) == 1){ //Relé 02
digitalWrite(rele02, LOW);
}
else{
digitalWrite(rele02, HIGH);
}
if (bitRead(setState[3], 2) == 1){ //Relé 03
digitalWrite(rele03, LOW);
}
else{
digitalWrite(rele03, HIGH);
}
if (bitRead(setState[3], 3) == 1){ //Relé 04
digitalWrite(rele04, LOW);
}
else{
digitalWrite(rele04, HIGH);
}
if (bitRead(setState[3], 4) == 1){ //Relé 05
digitalWrite(rele05, LOW);
}
else{
digitalWrite(rele05, HIGH);
}
if (bitRead(setState[3], 5) == 1){ //Relé 06
digitalWrite(rele06, LOW);
}
else{
digitalWrite(rele06, HIGH);
}
if (bitRead(setState[3], 6) == 1){ //Relé 07
digitalWrite(rele07, LOW);
}
else{
digitalWrite(rele07, HIGH);
}
if (bitRead(setState[3], 7) == 1){ //Relé 08
digitalWrite(rele08, LOW);
}
else{
digitalWrite(rele08, HIGH);
}
return 0;
}
//Lectura de galgas de presión provenientes de otro Arduino
int lecturaGalgas(){
if (Serial1.available() > 0) {
AD1 = Serial1.read();
delay(1);
AD1 = AD1 + (Serial1.read() * 256);
AD2 = Serial1.read();
delay(1);
AD2 = AD2 + (Serial1.read() * 256);
AD3 = Serial1.read();
delay(1);
AD3 = AD3 + (Serial1.read() * 256);
AD4 = Serial1.read();
delay(1);
AD4 = AD4 + (Serial1.read() * 256);
AD5 = Serial1.read();
delay(1);
AD5 = AD5 + (Serial1.read() * 256);
AD6 = Serial1.read();
delay(1);
AD6 = AD6 + (Serial1.read() * 256);
Serial1.flush();
}
return 0;
}
Espero preguntas y dudas, a ver si me ayudáis a solucionar.
Un saludo,