desktop

Problemas con comunicación RS485-RS232 (ARDUINO)

Ayer hablaba de la importancia del código bien estructurado y optimizado.
Fíjate en esta sección del código:

¿Por qué están las variables Slave y command definidas dentro del conjunto de IFs anidados?
Siempre que se pueda, las variables se definen fuera.

¿Por qué lees los valores "I" y "F" directamente con un SerialRead() y, en cambio, lees "L" mediante la variable auxiliar command, que es un SerialRead()?
Eso sólo tendría sentido si usaras el contenido de command posteriormente, pero no en este caso, que sólo quieres saber si llegó una "L".

----------

En estas rutinas de lectura y escritura en puertos, el timing es crítico.
Todo ese código confuso, mal estructurado y no optimizado, son retrasos en la ejecución que luego hacen que la cosa funcione en la simulación, pero no en la realidad. Hay lugares del código donde no puede haber retrasos. En cambio, en otros lugares hay que introducirlos a propósito para no perder datos.


Ok.
Elige con qué instrucción quieres que te lo implemente:
For...Next
While...Wend
Do...Loop
Select...Case
If ...Then
Try...Catch
Foreach...
Más claro que el agua imposible. Me diste el pie para arrancar. Mañana te cuento cómo me fue
 
Este es un ejemplo usando la lectura del buffer de entrada en una string y procesando la string, esto te permite verificar que exista i y f antes de proceder a analizar los datos almacenados, no tengo una pantalla así que solo lo analiza y responde por el serial, pero te sirve para probar como manejar y decodificar el paquete.

C++:
const int LED = 13;
const int Enable = 2;


/*** Función para poner en espera por la respuesta ***/
bool esperarDato(int timeout) {
  while (Serial.available() == 0 && timeout) {
    delay(5); //ajustar el delay de cada ciclo
    --timeout;
  }
  if (timeout) return true;  //retorna verdadero si no se agotó el tiempo y detecta datos.
  else return false;         // retorna falso si se agotó el tiempo de espera.
}

void setup() {
  Serial.begin(9600);
  Serial.setTimeout(250); //Establece el tiempo sin recepción que desencadena el TimeOut

  pinMode(LED, OUTPUT);
  pinMode(Enable, OUTPUT);
  digitalWrite(LED, LOW);
  digitalWrite(Enable, HIGH);  // inicio de transmision al esclavo 1
}
void loop() {
  Serial.println("-");
  delay(10);
  digitalWrite(Enable, HIGH);  // inicio de transmision al esclavo 1
  Serial.println("I1LF");        //puede ir todo junto
  Serial.flush();
  digitalWrite(Enable, LOW);  // fin de transmision al esclavo 1


  if (esperarDato(2000)) {  //Cada ciclo son 5ms, para 2000*5ms = 10s si se recibe antes da verdadero, si se agota la espera es falso.
    String respuesta = Serial.readString();         //Simplemente leemos el buffer de entrada hasta que se agote la espera al finalizar la transmisión
    int iniciador = respuesta.indexOf('i');           //Localizar inicio, -1 es igual a no encontrado, 0 es un valor válido
    int finalizador = respuesta.indexOf('f');         //localizar fin de transmisión
    if (iniciador >= 0 && finalizador > iniciador) {  //se valida que ambos existan, iniciador debe ser igual o mayor a 0 y el finalizador mayor al iniciador.
      /***  determinar la posición de los separadores  ***/
      int mark1 = respuesta.indexOf(' ', iniciador + 1);
      int mark2 = respuesta.indexOf(' ', mark1 + 1);
      int mark3 = respuesta.indexOf(' ', mark2 + 1);
      /*************************************************************************
      Se genera una substring usando los marcadores y se convierten en int
      Esta parte de encarga de asignar las variables para decodificar el paquete
      *************************************************************************/
      int dispositivo = respuesta.substring(mark1+1, mark2).toInt();  //Decodifica el número de dispositivo
      int valor =  respuesta.substring(mark2+1, mark3).toInt();       //Decodifica el valor

      //esta sección solo es para componer la cadena con los datos detectados
      String dato = "Sensor " + String(dispositivo) + ":" + String(valor);
      Serial.println(dato);
    } else {
      Serial.println("Transmision inválida");
    }
  } else {
    Serial.println("Tiempo de espera agotado, sin respuesta");
  }
}

De ahí te recomendaría ver cómo puedes meterlo en un loop usando matrices para asignar los dispositivos en lugar de generar una variable para cada uno, así podrías reutilizar el código usando valor[dispositivo]
 
Última edición:
Este es un ejemplo usando la lectura del buffer de entrada en una string y procesando la string, esto te permite verificar que exista i y f antes de proceder a analizar los datos almacenados, no tengo una pantalla así que solo lo analiza y responde por el serial, pero te sirve para probar como manejar y decodificar el paquete.

C++:
const int LED = 13;
const int Enable = 2;


/*** Función para poner en espera por la respuesta ***/
bool esperarDato(int timeout) {
  while (Serial.available() == 0 && timeout) {
    delay(5); //ajustar el delay de cada ciclo
    --timeout;
  }
  if (timeout) return true;  //retorna verdadero si no se agotó el tiempo y detecta datos.
  else return false;         // retorna falso si se agotó el tiempo de espera.
}

void setup() {
  Serial.begin(9600);
  Serial.setTimeout(250); //Establece el tiempo sin recepción que desencadena el TimeOut

  pinMode(LED, OUTPUT);
  pinMode(Enable, OUTPUT);
  digitalWrite(LED, LOW);
  digitalWrite(Enable, HIGH);  // inicio de transmision al esclavo 1
}
void loop() {
  Serial.println("-");
  delay(10);
  digitalWrite(Enable, HIGH);  // inicio de transmision al esclavo 1
  Serial.println("I1LF");        //puede ir todo junto
  Serial.flush();
  digitalWrite(Enable, LOW);  // fin de transmision al esclavo 1


  if (esperarDato(2000)) {  //Cada ciclo son 5ms, para 2000*5ms = 10s si se recibe antes da verdadero, si se agota la espera es falso.
    String respuesta = Serial.readString();         //Simplemente leemos el buffer de entrada hasta que se agote la espera al finalizar la transmisión
    int iniciador = respuesta.indexOf('i');           //Localizar inicio, -1 es igual a no encontrado, 0 es un valor válido
    int finalizador = respuesta.indexOf('f');         //localizar fin de transmisión
    if (iniciador >= 0 && finalizador > iniciador) {  //se valida que ambos existan, iniciador debe ser igual o mayor a 0 y el finalizador mayor al iniciador.
      /***  determinar la posición de los separadores  ***/
      int mark1 = respuesta.indexOf(' ', iniciador + 1);
      int mark2 = respuesta.indexOf(' ', mark1 + 1);
      int mark3 = respuesta.indexOf(' ', mark2 + 1);
      /*************************************************************************
      Se genera una substring usando los marcadores y se convierten en int
      Esta parte de encarga de asignar las variables para decodificar el paquete
      *************************************************************************/
      int dispositivo = respuesta.substring(mark1+1, mark2).toInt();  //Decodifica el número de dispositivo
      int valor =  respuesta.substring(mark2+1, mark3).toInt();       //Decodifica el valor

      //esta sección solo es para componer la cadena con los datos detectados
      String dato = "Sensor " + String(dispositivo) + ":" + String(valor);
      Serial.println(dato);
    } else {
      Serial.println("Transmision inválida");
    }
  } else {
    Serial.println("Tiempo de espera agotado, sin respuesta");
  }
}

De ahí te recomendaría ver cómo puedes meterlo en un loop usando matrices para asignar los dispositivos en lugar de generar una variable para cada uno, así podrías reutilizar el código usando valor[dispositivo]
Excelente aporte; Anoche más o menos lo enfoque como mencionaste en otro tópico, pero con algunos agregados para ver si podía leer mas datos, más sensores y al parecer, en Proteus funcionó... Pero ahora que veo tu manera de manejar el string, me queda más claro y más seguro. Edito y vuelvo... Mepa que hoy queda un ejemplo potable de rs485 con Arduino...
@DOSMETROS Si cito los links de las páginas donde arranque y estaban mal los ejemplos, estaría en infracción?
 
Excelente aporte; Anoche más o menos lo enfoque como mencionaste en otro tópico, pero con algunos agregados para ver si podía leer mas datos, más sensores y al parecer, en Proteus funcionó... Pero ahora que veo tu manera de manejar el string, me queda más claro y más seguro. Edito y vuelvo... Mepa que hoy queda un ejemplo potable de rs485 con Arduino...
@DOSMETROS Si cito los links de las páginas donde arranque y estaban mal los ejemplos, estaría en infracción?
Siguiendo del ejemplo anterior, se suele usar distintos marcadores para cada valor, así es más fácil identificarlos en lugar de usar espacios, por ejemplo si usas un formato como:
i56t35v5.85s200f
Usas las letras como separador para identificar el dispositivo con la i, temperatura con t, voltaje con v, (puedes usar toFloat() para el decimal) otro sensor con s y el fin con f, ya solo usas indexOf(separador) para identificar donde cortar los datos.
 
Pregunta:
Cuales son los requerimientos temporales para ejecutar ese código??
Por que si bien lo que propone @Nuyel está OK, las funciones de procesamiento de strings lo están recorriendo una y otra vez bajo la acción de cada indexOf() y eso es una demanda tiempo potencialmente excesiva....dependiendo de los requerimientos temporales de ejecución del código, el contexto de ejecución y el baudrate del enlace.
Por eso comenté antes la posibilidad de emplear una máquina de estados que recibe, procesa y ubica cada caracter individual a medida que van llegando y deja para el final las conversiones de tipos que sean necesarias.
Ademas, esta forma de trabajo puede ser parte de la rutina de interrupción de recepción serie, con lo cual deja mucho tiempo libre para ejecutar otros procesos.
Claro que el formato de los datos debe estar perfectamente definido...
 
Pregunta:
Cuales son los requerimientos temporales para ejecutar ese código??
Por que si bien lo que propone @Nuyel está OK, las funciones de procesamiento de strings lo están recorriendo una y otra vez bajo la acción de cada indexOf() y eso es una demanda tiempo potencialmente excesiva....dependiendo de los requerimientos temporales de ejecución del código, el contexto de ejecución y el baudrate del enlace.
El problema con intentar aplicar un esquema de tiempo crítico es que Arduino tiene demasiado pasando en segundo plano como para intentarlo, como el mecanismo es de Consulta-Respuesta el único tiempo crítico es en realizar los cambios entre envió a recepción, para el caso de recepción darle tiempo para que el esclavo responda. Por ello se implementa un bucle que se queda a la espera de que el esclavo envíe la respuesta inmediatamente después de generar el cambio a modo lectura, de esta forma intencionalmente se espera a que el esclavo procese el comando y realice la muestra de datos, luego el esclavo debería enviar toda la respuesta junta, el ejemplo que puse le da hasta 10s de tiempo de espera lo que en la práctica es excesivo, pero igual si la recibe en 10ms sale del bucle y lee TODA la respuesta.

En la práctica si buscara velocidad preferiría usar un formato codificado en binario, por ejemplo, enviar la trama [byte dirección][byte comando] y recibir [dirección][longitud][dato1][valor1]....[daton][valorn][CRC], luego hacer las asignaciones directamente.

Pero no podemos tratar a Arduino con tanto detalle, el serialEvent no es ni siquiera un ISR sino más bien polling que ocurre después del loop dentro del main (no se ve, pero Arduino tiene un main()) validando si existen datos, el Arduino procesa la comunicación por interrupciones de una manera en la que el usuario no tiene control, esto evita que los novatos arruinen la comunicación, por eso en el código se usa el Serial.flush() que básicamente le dice "espera hasta que la transmisión termine" ya que sin ello el Serial.print solo manda los datos al buffer pero no significa que la transmisión esté completa.

Cuando se genera la recepción el Arduino procesa usando interrupciones y almacena los datos en un buffer de 64bytes interno, el delay() al basarse en software tampoco genera bloqueo que las deshabiliten por lo que no debería haber perdida de datos, solo hay problemas de sincronía ya que el delay de hecho se extiende si se ejecuta una interrupción, en cambio, si intentas meterte en una interrupción, en primer lugar no tenemos acceso a la del serial real, y ejecutar otras SÍ pueden suspender la recepción causando perdida de paquetes, por eso es preferible que el chip pierda todo el tiempo que quiera al recibir los datos y enviarlos teniendo la trama completa una vez que ya los procesó.

En resumen, esta implementación es mala en procesamiento, usa mucha memoria y ciertamente toma tiempo, pero en el tema de la transmisión y recepción no debería tener conflictos. Por ello es que se envía y queda a la espera de la respuesta, una vez que detecta entrada de datos queda en lectura hasta que la transmisión termine por timeOut (que el código establece en 250ms sin recibir nuevos datos), entonces ya lo procesa todo sin tener que preocuparse del tiempo ya que los esclavos no deberían transmitir hasta la siguiente consulta. Si la trama ocupa más de los 64 bytes del buffer sí le recomendaría entonces reducir el tiempo de verificación en la función de espera, pero tendrá que buscar el punto de equilibrio según su aplicación.
 
Última edición:
Bien, para cerrar este tema y no dejarlo colgado, dejo los sketch terminados para que puedan usarlo como idea, base o lo que quieran.
Básicamente lo que hice fue acortar la trama y dejar de lado tantas consultas, ya que en definitiva, si me comunico con un esclavo, es por que quiero pedirle informacion. Asi que lo que hago es poner en modo transmisor el MASTER, enviar un string con la dirección y un caracter para indicar el fin de la trama al esclavo que llamo, y me pongo en modo receptor...

Código:
digitalWrite(RS_MODE, HIGH);                                        // Modo transmisor
     Serial.print(slave1);                                                          // Envia la direccion del esclavo1
     Serial.print("*");                                                               // Final de trama
     Serial.flush();                                                                   // Espera a que se transmitan los datos al esclavo
     digitalWrite(RS_MODE, LOW);                                       // Modo receptor
 
     flag_rx = 1;
     t_millis = millis();
     while(flag_rx == 1)                                                         // Espera a que responda el esclavo
         {
           if((millis() - t_millis) >= 1000 && flag_rx == 1)       // Si el esclavo no responde en 1 segundo, el maestro vuelve a transmitir datos
             {
               flag_rx = 0;
             }
           while(Serial.available() > 0)                                     // Verifica si ha recibido datos del esclavo
               {
                 flag_rx = 0;
                 S1_dato1 = Serial.readStringUntil(',').toInt();
                 S1_dato2 = Serial.readStringUntil(':').toInt();
                 S1_dato3 = Serial.readStringUntil('*').toInt();
               }

El esclavo, que se encuentra en permanentemente en modo receptor, cuando hay disponible un dato serial y este contiene la dirección de ese esclavo, se pone en modo transmisor y envía el string con caracteres separadores para poder separar los datos ("," - ":" - "*") y un carácter especial para indicar el fin de la trama...

Código:
digitalWrite(Enable, LOW);
     if (Serial.available())
        {
         S1_dato1 = Serial.readStringUntil('*');
        
         if(slave1 == S1_dato1) 
           {
            VAR_SensorNIVEL_H2o = analogRead(PIN_SensorNIVEL_H2o_AN);
            V_SN = map ( VAR_SensorNIVEL_H2o, 0, 1023, 100 ,0);
            pe = digitalRead(PULSADOR);     // lectura del sensor todo o nada   
            digitalWrite(Enable, HIGH);
            Serial.print(slave1);
            Serial.print(",");   
            Serial.print(V_SN);
            Serial.print(":");
            Serial.print(pe);
            Serial.print("*");
            Serial.flush();
            digitalWrite(Enable, LOW); 
           }
        }


El diagrama de circuito básico:

comunicacionRS485_diagrama.png

Este es el programa para el master:

C:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);
#include <Separador.h>
Separador s;

String direccion;
String slave1 = "101";                                   // Direccion del esclavo1
String slave2 = "102";                                   // Direccion del esclavo2
String slave3 = "103";                                   // Direccion del esclavo3
String slave4 = "104";                                   // Direccion del esclavo4
String S1_datosrecibidos;
String S1_dato1;
String S1_dato2;
String S1_dato3;
String S2_datosrecibidos;
String S2_dato1;
String S2_dato2;
String S2_dato3;
String S3_datosrecibidos;
String S3_dato1;
String S3_dato2;
String S3_dato3;

int Nivel_TK;
int Temp_H2o;
int Temp_Amb;
int PE_Slave1;
int SensorFLAMA_Slave3;

#define RS_MODE 2                                           // Pin para seleccionar modo transmisor o receptor del RS485

byte flag_rx = 0;                                           // Variable de estado para el modo receptor
unsigned long t_millis;                                     // Contador de tiempo transcurrido en milisegundos

void setup()
{
  pinMode(RS_MODE, OUTPUT);                                 // Pin de seleccion de modo del modulo RS485 como salida
  Serial.begin(9600);                                       // Configuracion del puerto serial a 9600 baudios
  lcd.init();     
  lcd.backlight();
  lcd.clear();
}
/////////////////////////////////////////////////////////// 
/////////////////////////////////////////////////////////// 
void loop()
   {
     lcd.setCursor(0,0);lcd.print("****RS232  RS485****");
     lcd.setCursor(0,1); lcd.print("Nivel:");
         if((S1_dato2.toInt()) < 70)
          {
           lcd.print("BAJO");
          }
         else
          {
           lcd.print("OK  ");
          }
     lcd.setCursor(14,1);lcd.print(" %:");lcd.print(S1_dato2.toInt());
     lcd.setCursor(0,2);lcd.print("Temp H2o:");lcd.setCursor(10,2);lcd.print(S2_dato2.toInt());
     lcd.setCursor(14,2);lcd.print(" PE:");lcd.print(S1_dato3.toInt());
     lcd.setCursor(0,3);lcd.print("Temp Amb:");lcd.setCursor(10,3);lcd.print(S3_dato3.toInt());
     lcd.setCursor(14,3);lcd.print(" SF:");lcd.print(S3_dato2.toInt());

///////////////////////////////////////////////////////////
////////////// COMUNICACION CON EL ESCLAVO 1 //////////////
///////////////////////////////////////////////////////////

     digitalWrite(RS_MODE, HIGH);                              // Modo transmisor
     Serial.print(slave1);                                     // Envia la direccion del esclavo1
     Serial.print("*");                                        // Final de trama
     Serial.flush();                                           // Espera a que se transmitan los datos al esclavo
     digitalWrite(RS_MODE, LOW);                               // Modo receptor
 
     flag_rx = 1;
     t_millis = millis();
     while(flag_rx == 1)                                       // Espera a que responda el esclavo
         {
           if((millis() - t_millis) >= 1000 && flag_rx == 1)       // Si el esclavo no responde en 1 segundo, el maestro vuelve a transmitir datos
             {
               flag_rx = 0;
             }
           while(Serial.available() > 0)                           // Verifica si ha recibido datos del esclavo
               {
                 flag_rx = 0;
                 S1_dato1 = Serial.readStringUntil(',').toInt();
                 S1_dato2 = Serial.readStringUntil(':').toInt();
                 S1_dato3 = Serial.readStringUntil('*').toInt();
               }
         }
   delay (10);
///////////////////////////////////////////////////////////
////////////// COMUNICACION CON EL ESCLAVO 2 //////////////
///////////////////////////////////////////////////////////
    digitalWrite(RS_MODE, HIGH);                              // Modo transmisor
    Serial.print(slave2);                                     // Envia la direccion del esclavo1
    Serial.print("*");                                        // Final de trama
    Serial.flush();                                           // Espera a que se transmitan los datos al esclavo
    digitalWrite(RS_MODE, LOW);                               // Modo receptor
    flag_rx = 1;
    t_millis = millis();
    while(flag_rx == 1)                                       // Espera a que responda el esclavo
         {
           if((millis() - t_millis) >= 1000 && flag_rx == 1)       // Si el esclavo no responde en 1 segundo, el maestro vuelve a transmitir datos
             {
               flag_rx = 0;
             }
           while(Serial.available() > 0)                           // Verifica si ha recibido datos del esclavo
             {
               flag_rx = 0;
               S2_dato1 = Serial.readStringUntil(',').toInt();
               S2_dato2 = Serial.readStringUntil('*').toInt();
             }
         }
   delay (10);
///////////////////////////////////////////////////////////
////////////// COMUNICACION CON EL ESCLAVO 3 //////////////
///////////////////////////////////////////////////////////
   digitalWrite(RS_MODE, HIGH);                              // Modo transmisor
   Serial.print(slave3);                                     // Envia la direccion del esclavo1
   Serial.print("*");                                        // Final de trama
   Serial.flush();                                           // Espera a que se transmitan los datos al esclavo
   digitalWrite(RS_MODE, LOW);                               // Modo receptor
   flag_rx = 1;
   t_millis = millis();
   while(flag_rx == 1)                                       // Espera a que responda el esclavo
       {
         if((millis() - t_millis) >= 1000 && flag_rx == 1)   // Si el esclavo no responde en 1 segundo, el maestro vuelve a transmitir datos
           {
             flag_rx = 0;
           }
         while(Serial.available() > 0)                        // Verifica si ha recibido datos del esclavo
             {
               flag_rx = 0;
               S3_dato1 = Serial.readStringUntil(',').toInt();
               S3_dato2 = Serial.readStringUntil(':').toInt();
               S3_dato3 = Serial.readStringUntil('*').toInt();
             }
       }
    delay(900);
    lcd.clear();
    }
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////

Este es el programa para el esclavo1:
C:
#include <Separador.h>
Separador s;

const int PULSADOR = 12;
const int Enable =  2;
const int SlaveNumber = 1;
const int PIN_SensorNIVEL_H2o_AN  =A0;

String direccion;
String slave1 = "101";                                   // Direccion del esclavo1
String S1_datosrecibidos;
String S1_dato1;
String S1_dato2;
String S1_dato3;
String comando1 = "N";
String comando2 = "P";

int pe;
int VAR_SensorNIVEL_H2o;
int V_SN;
int lectura;
int AnalogValue;

void setup()
  {
   Serial.begin(9600); 
   pinMode(Enable, OUTPUT);
   digitalWrite(Enable, LOW);
   pinMode(13, OUTPUT);
   pinMode(PULSADOR, INPUT);
   pinMode(PIN_SensorNIVEL_H2o_AN, INPUT);
  }

void loop()
    {
     digitalWrite(Enable, LOW);
     if (Serial.available())
        {
         S1_dato1 = Serial.readStringUntil('*');
        
         if(slave1 == S1_dato1) 
           {
            VAR_SensorNIVEL_H2o = analogRead(PIN_SensorNIVEL_H2o_AN);
            V_SN = map ( VAR_SensorNIVEL_H2o, 0, 1023, 100 ,0);
            pe = digitalRead(PULSADOR);     // lectura del sensor todo o nada   

            digitalWrite(Enable, HIGH);
            Serial.print(slave1);
            Serial.print(",");   
            Serial.print(V_SN);
            Serial.print(":");
            Serial.print(pe);
            Serial.print("*");
            Serial.flush();
            digitalWrite(Enable, LOW); 
           }
        }
    }

Este es el programa para el esclavo2:
C:
#include <Separador.h>
Separador s;

String direccion;
String slave2 = "102";                                   // Direccion del esclavo1
String S2_datosrecibidos;
String S2_dato1;
String S2_dato2;
String S2_dato3;
String comando1 = "TT";

const int Enable =  2;
const int SlaveNumber = 2;
const int PIN_SensorNIVEL_TEMP_AN =A0;

int VAR_SensorTEMP;
int Slave;
char command;
float mV_SensorTEMP;
int Ref_Temp_mV;

void setup()
{
 
  Serial.begin(9600); 
  Serial.setTimeout(300);
  pinMode(PIN_SensorNIVEL_TEMP_AN,INPUT);    //ADC SENSOR TERMOCUPLA TIPO J
  pinMode(Enable, OUTPUT);
  digitalWrite(Enable, LOW);
  pinMode(13, OUTPUT);
  pinMode(A0, INPUT);
}

void loop()
   {
    digitalWrite(Enable, LOW);
    if (Serial.available())
       {
         S2_dato1 = Serial.readStringUntil('*');
                                  
         if(slave2 == S2_dato1) 
           {
                 VAR_SensorTEMP = analogRead(PIN_SensorNIVEL_TEMP_AN);
                 mV_SensorTEMP = (VAR_SensorTEMP * 5.0)/1024.0;
                 if (mV_SensorTEMP  >1.20 && mV_SensorTEMP< 1.60)
                    {Ref_Temp_mV= 0;} //1.40mV
                 if (mV_SensorTEMP  >1.61 && mV_SensorTEMP< 2.0)
                    {Ref_Temp_mV= 10;} //1.79mV                 
                 if (mV_SensorTEMP  >2.1 && mV_SensorTEMP< 2.40)
                    {Ref_Temp_mV= 20;} //2.18mV
                 if (mV_SensorTEMP  >2.41 && mV_SensorTEMP< 2.87)
                    {Ref_Temp_mV= 30;} //2.57mV
                 if (mV_SensorTEMP  >2.88 && mV_SensorTEMP < 3.30)
                    {Ref_Temp_mV= 40;} //2.97mV
                 if (mV_SensorTEMP  >3.31 && mV_SensorTEMP < 3.76)
                    {Ref_Temp_mV= 50;} //3.37mV
                 if (mV_SensorTEMP  >3.77 && mV_SensorTEMP < 4.10)
                    {Ref_Temp_mV= 60;} //3.78mV                                                       
                 if (mV_SensorTEMP  >4.11 && mV_SensorTEMP < 4.50)
                    {Ref_Temp_mV= 70;} //4.19mV
                 if (mV_SensorTEMP  >4.51 && mV_SensorTEMP < 4.80)
                    {Ref_Temp_mV= 80;} //4.60mV
                 if (mV_SensorTEMP >4.81 && mV_SensorTEMP < 4.87)
                    {Ref_Temp_mV= 90;} //4.86mV
                 if (mV_SensorTEMP >4.88 && mV_SensorTEMP < 4.90)
                    {Ref_Temp_mV= 100;} //4.90mV
                 if (mV_SensorTEMP >4.90)
                    {Ref_Temp_mV= 110;} //4.91mV               
                        
                 digitalWrite(Enable, HIGH);
                 Serial.print(slave2);
                 Serial.print(",");
                 Serial.print(Ref_Temp_mV);
                 Serial.print("*");
                 Serial.flush();
                 digitalWrite(Enable, LOW);   
           }
       }
   }

Este es el programa para el esclavo3:
C:
#include <Separador.h>
Separador s;

String direccion;
String slave3 = "103";                                   // Direccion del esclavo1
String S3_datosrecibidos;
String S3_dato1;
String S3_dato2;
String S3_dato3;
String comando1 = "SF";
String comando2 = "ST";

const int SensorFLAMA = 12;
const int Enable =  2;
const int SlaveNumber = 3;

int EstadoSensorDIGITAL;
int Slave;
char command;
int lecturaLM35;
int tempC;


void setup()
{
  Serial.begin(9600); 
  Serial.setTimeout(300);
  pinMode(Enable, OUTPUT);
  digitalWrite(Enable, LOW);
  pinMode(13, OUTPUT);
  pinMode(SensorFLAMA, INPUT);
  pinMode(A0, INPUT);
}

void loop()
    {
      digitalWrite(Enable, LOW);
      if (Serial.available())
        {
         S3_dato1 = Serial.readStringUntil('*');
        
         if(slave3 == S3_dato1) 
           { 
            lecturaLM35 = analogRead(0);
            tempC = lecturaLM35;
            tempC=(5*tempC*100)/1024;
                                                    
            EstadoSensorDIGITAL = digitalRead(SensorFLAMA);     // lectura del sensor todo o nada   
                  
            digitalWrite(Enable, HIGH);
            Serial.print(slave3);
            Serial.print(",");
            Serial.print(EstadoSensorDIGITAL); 
            Serial.print(":");
            Serial.print(tempC);
            Serial.print("*");
            Serial.flush();
            digitalWrite(Enable, LOW); 
           }
        }
    }


comunicacionRS485_STRING.png
 
Atrás
Arriba