Envío de datos mediante comunicación serial

Buenas tardes. Tal vez podrían ayudarme con la siguiente inquietud que tengo. Estoy haciendo un proyecto de la universidad en el cual tengo que subir datos a una nube crenado una tabla. El problema que tengo es que obligadamente necesito usar arduino y para subir datos a internet estoy usando la shield ESP8266. Debido al limitante de pines analógicos y con pwm en la ESP8266, estoy haciendo comunicación serial entre el arduino uno y la ESP. Al momento de enviar los datos mediante comunicación serial a la ESP me llegan. Mi inquietud es... Cómo puedo hacer para recibir los datos por separado (tengo 5 sensores LDR) y así poder tratarlos en la ESP como datos por separado. Ya que he conseguido que me lleguen los datos pero me llegan todos a la vez. El código del Arduino y ESP los dejo a continuación.
Código transmisor (Arduino)

//Variables reseteo de funcion millis
extern volatile unsigned long timer0_millis;
unsigned long new_value = 5;
int seg = 0;

//Variables sensor LDR
/*int ldr1 = 14;
int ldr2 = 15;
int ldr3 = 16;
int ldr4 = 17;
int ldr5 = 18;*/
int LDR = 0;
volatile int valorldr1 = 0; 
volatile int valorldr2 = 0; 
volatile int valorldr3 = 0; 
volatile int valorldr4 = 0; 
volatile int valorldr5 = 0;  
int max = 900;
int min = 20;

//Variables de las iluminarias
int Lum1 = 3;
int Lum2 = 5;
int Lum3 = 6;
int Lum4 = 9;
int Lum5 = 10; 

String valores; 

void setup() {
  Serial.begin(9600);
  for (LDR = 14; LDR <=18; LDR++){
    pinMode(LDR, INPUT);     
  }
  pinMode(Lum1, OUTPUT);
  pinMode(Lum2, OUTPUT);
  pinMode(Lum3, OUTPUT);
  pinMode(Lum4, OUTPUT);  
  pinMode(Lum5, OUTPUT);
   
}

void loop() {
  seg = new_value - (millis() / 1000);
  Serial.println(seg);
  ldr_1(); 
  if (valorldr1 > 20 || valorldr1 <= 900) {
    analogWrite (Lum1, valorldr1);
  } 
  else {
    digitalWrite (Lum1, LOW);
  }

  ldr_2(); 
    if (valorldr2 > 20 || valorldr2 <= 900) {
    analogWrite (Lum2, valorldr2);
  } 
    else {
    digitalWrite (Lum2, LOW);
  }

  ldr_3(); 
  if (valorldr3 > 20 || valorldr3 <= 900) {
    analogWrite (Lum3, valorldr3);
  } 
  else {
    digitalWrite (Lum3, LOW);
  }

  ldr_4(); 
  if (valorldr4 > 20 || valorldr4 <= 900) {
    analogWrite (Lum4, valorldr4);
  } 
  else {
    digitalWrite (Lum4, LOW);
  }

  ldr_5(); 
    if (valorldr5 > 20 || valorldr5 <= 900) {
    analogWrite (Lum5, valorldr5);
  } 
  else {
    digitalWrite (Lum5, LOW);
  }  
  /*if (seg == 0){
    valores = String(valorldr1) + String(valorldr2) + String(valorldr3) + String(valorldr4) + String(valorldr5);
    Serial.println(valores);
    setMillis(new_value); 
  }*/
}


//Funciones de LDR
void ldr_1 (){
  valorldr1 = analogRead (14);
  valorldr1 = constrain (valorldr1, min, max);
  if (seg == 0){
    /*valores = String(valorldr1) + String(valorldr2) + String(valorldr3) + String(valorldr4) + String(valorldr5);*/
    Serial.print("LDR 1: ");
    Serial.println(valorldr1);
    setMillis(new_value); 
  }
  /*Serial.print ("LDR 1: ");
  Serial.println (valorldr1);*/
  valorldr1 = map (valorldr1, max, min, 0, 255); 
  delay (200);
}

void ldr_2 (){
  valorldr2 = analogRead (15);
  valorldr2 = constrain (valorldr2, min, max);
  if (seg == 0){
    /*valores = String(valorldr1) + String(valorldr2) + String(valorldr3) + String(valorldr4) + String(valorldr5);*/
    Serial.print("LDR 2: ");
    Serial.println(valorldr2);
    setMillis(new_value); 
  }
  /*Serial.print ("LDR 2: ");
  Serial.println (valorldr2);*/
  valorldr2 = map (valorldr2, max, min, 0, 255); 
  delay (200); 
}

void ldr_3 (){
  valorldr3 = analogRead (16);
  valorldr3 = constrain (valorldr3, min, max);
if (seg == 0){
    /*valores = String(valorldr1) + String(valorldr2) + String(valorldr3) + String(valorldr4) + String(valorldr5);*/
    Serial.print("LDR 3: ");
    Serial.println(valorldr3);
    setMillis(new_value); 
  }  
  /*Serial.print ("LDR 3: ");  
  Serial.println (valorldr3);*/
  valorldr3 = map (valorldr3, max, min, 0, 255); 
  delay (200); 
}

void ldr_4 (){
  valorldr4 = analogRead (17);
  valorldr4 = constrain (valorldr4, min, max);
  if (seg == 0){
    /*valores = String(valorldr1) + String(valorldr2) + String(valorldr3) + String(valorldr4) + String(valorldr5);*/
    Serial.print("LDR 4: ");
    Serial.println(valorldr4);
    setMillis(new_value); 
  }
  /*Serial.print ("LDR 4: ");
  Serial.println (valorldr4);*/
  valorldr4 = map (valorldr4, max, min, 0, 255); 
  delay (200); 
}

void ldr_5 (){
  valorldr5 = analogRead (18);
  valorldr5 = constrain (valorldr5, min, max);
  if (seg == 0){
    /*valores = String(valorldr1) + String(valorldr2) + String(valorldr3) + String(valorldr4) + String(valorldr5);*/
    Serial.print("LDR 5: ");
    Serial.println(valorldr5);
    setMillis(new_value); 
  }
  /*Serial.print ("LDR 5: ");
  Serial.println (valorldr5);*/
  valorldr5 = map (valorldr5, max, min, 0, 255);  
  delay (200);
}

Código receptor ESP


#include <ESP8266HTTPClient.h>
#include <ESP8266WiFiMulti.h>

// defino credenciales red
static const char* ssid = "";
static const char* password = "";

WiFiClient client;

void setup() {
  Serial.begin(9600);
  while(!Serial){;
  }

  WiFi.begin(ssid, password);
  Serial.print("Conectando...");
  while (WiFi.status()!= WL_CONNECTED) {
    delay(500);
    Serial.println(".");
  }
  Serial.println("Conexión OK!");
  Serial.print("IP Local: ");
  Serial.println(WiFi.localIP());  
}

void loop() {
  if (Serial.available()){
    Serial.write(Serial.read());
    delay (1);
  }
}

Su publicacion se MUEVE a su ubicacion actual ya que es mas adecuada.

Moderador:
Por favor, lee las Normas del foro
Si posteas en el foro en inglés usa idioma inglés para expresarte.
Si escribes en español debes usar el foro Arduino en español.
Cómo es posible que alguien que ya ha posteado se equivoque de foro?

Lo primero para decirte es: tus rutinas de ldr se pueden resumir en una sola.
Algo que para alguien que tiene un hilo subiendo cosas a Ubidots ya debería ser pan comido.

//Funciones de LDR
void ldr_1 (){
  valorldr1 = analogRead (14);
  valorldr1 = constrain (valorldr1, min, max);
  if (seg == 0){
    /*valores = String(valorldr1) + String(valorldr2) + String(valorldr3) + String(valorldr4) + String(valorldr5);*/
    Serial.print("LDR 1: ");
    Serial.println(valorldr1);
    setMillis(new_value); 
  }
  /*Serial.print ("LDR 1: ");
  Serial.println (valorldr1);*/
  valorldr1 = map (valorldr1, max, min, 0, 255); 
  delay (200);
}

Esta es tu rutina que podría simplificarse en esta

pero mientras lo hacía me encontré con esto

setMillis(new_value); 

que es esto?
Este código no compila.

si quieres actualizar new_value simplemente lo haces asi

new_value = millis(); 

EDITO: acá una versión mas reducida de tu código.

//Variables reseteo de funcion millis
unsigned long new_value = 5;
int seg = 0;

int LDR = 0;
struct _LDR {
  int valorldr;
  int Lum;
  int pin;
};

_LDR ldr[5] = { 
                {0,  3, 14};
                {0,  5, 15};
                {0,  6, 16};
                {0,  9, 17};
                {0, 10, 18}
               };

int _max = 900;
int _min = 20;
String valores;

//Funciones de LDR
void leo_ldr(int pin) {
  ldr[pin].valorldr = analogRead(ldr[pin].pin);
  ldr[pin].valorldr = constrain(ldr[pin].valorldr, _min, _max);
  if (seg == 0) {
    /*valores = String(valorldr1) + String(valorldr2) + String(valorldr3) + String(valorldr4) + String(valorldr5);*/
    Serial.printf("LDR %d: %3d\n", pin, ldr[pin].valorldr);
    new_value = millis();
  }
  ldr[pin].valorldr = map(ldr[pin].valorldr, _max, _min, 0, 255);
  delay(200);
}
void setup() {
  Serial.begin(9600);
  for (int i=0; i<5; i++) {
    pinMode(ldr[i].pin, INPUT);
    pinMode(ldr[i].Lum, OUTPUT);
  }
}

void loop() {
  seg = new_value - (millis() / 1000);
  for (int i = 0; i < 5; i++) {
      leo_ldr(i);
      Serial.printf("%4d,S%d,%3d", seg, i, ldr[i].valorldr);
      if (ldr[i].valorldr > 20 || ldr[i].valorldr <= 900) {
        analogWrite(ldr[i].Lum, ldr[i].valorldr);
      }
      else {
        digitalWrite(ldr[i].Lum, LOW);
      }
}

con la línea

      Serial.printf("%4d,S%d,%3d", seg, i, ldr[i].valorldr);

Envias 200,S1,356 por ejemplo para querer decir 200 seg Sensor 1 356 valorldr
todos separados por comas.

Lo primero mil disculpas por postear en el foro equivocado.
Lo segundo, sí, sé que se puede reducir, pero al hacerlo así se envían todos los valores en conjunto hacia el ESP es por eso que opté por separar para ver si podía logar recibir por separado el valor de cada LDR.
Tercero, lo de

setMillis(new_value)

es una especie de timmer o contador, no se ha subido la rutina con la que trabajo, pero es esta:

//Función reseteo de millis
void setMillis(unsigned long new_millis){
  uint8_t oldSREG = SREG;
  cli();
  timer0_millis = new_millis;
  SREG = oldSREG;
}

con ese rutina reseteo el contador para volver a 0.
Como dije, lo que estoy intentando es que en el ESP pueda recibir cada valor por separado para poder tratarlo después y subirlo.

Creo que los envías por separado pero para recibirlos veo en el ESP8266 tienes esto:

 if (Serial.available()){
    Serial.write(Serial.read());
    delay (1);
  }

No deberías recibirlos tal como así?

 if (Serial.available()){
    String serialrcv=Serial.readStringUntil('\n'); //creamos y llenamos buffer hasta un "enter"
    serialrcv="Recibido:'" + serialrcv+"'..."; //añadimos un par de textos para la salida.
    Serial.println(serialrcv);
     delay (1);
   }

Pero confundes las cosas.
Para separar cosas hay que enviarlas con algo que te permita delimitarlas. No digo que la opción que te di sea la manera, podrias por ejemplo enviarlas asi

TTTTTSXYYYY,
donde T es tiempo
SX es sensor
Y el valor LDR
Al final una coma, como sabes que las longitudes son fijas no tendras problema usando Strings por ejemplo para separarlos.

La longitud de los valores de los sensores no siempre son fijas, ya que habrá escenarios en que sean de 2 y a veces de 3 dígitos.

Pero de esa forma lo que recibo así sea entero lo recibiría como string?
Y tendría que hacer 5 de ese tipo de variables para cada LDR, porque por lo que veo simplemente los está almacenando en una variable y los presenta como una cadena de caracteres a todos unidos.

pero con el formato que yo te doy las longitudes son fijas, tu estableces el formato usando %3d para 3 digitos por ejemplo o %2d para 2 digitos
Al saber que son fijas desarmar el paquete es fácil.
O de lo contrario lo haces variable y pones un delimitador como una coma (,) u otro caracter

Estoy intentando enviar los datos como string con un separador como la coma para en el receptor separarlos mediante la función indexOf, pero al momento de hacer la separación no me reconoce el comando. No sé si el ESP cuente con la dunción indexOf y subString. Buenp, también no sé si estoy enviando bien los datos, lo estoy haciendo de está forma:

Serial.print(valorldr1);
    Serial.print(",");
    Serial.print(valorldr2);
    Serial.print(",");
    Serial.print(valorldr3);
    Serial.print(",");
    Serial.print(valorldr4);
    Serial.print(",");
    Serial.println(valorldr5);

porque intenté concatenar los int con una coma en una sola variable (valorldr1 + "," + ..."," + valorldr5) de esa forma, pero arrojaba un error (que era de esperarse).
Y para recibir lo estoy haciendo de esta manera, como explicó DanX3:

if (Serial.available()){
    /*Serial.write(Serial.read());
    delay (1);*/
    serialrcv = Serial.readStringUntil ('\n'); //creamos y llenamos buffer hasta un "enter"
    serialrcv = "Recibido: " + serialrcv+" ..."; //añadimos un par de textos para la salida.
    Serial.println (serialrcv);
    coma = serialrcv.indexOf(',');
    Serial.println("Posicion: " + coma);    
     delay (1);    
  }

Al intentar mostrar coma en e puerto serial simplemente obtengo unos cuadros negros, ni siquiera me muestra el mensaje de "Posición".

No entiendo muy bien cómo lo haces,
Es decir tienes por un lado un arduino uno que maneja los ldr y envía la información a un ESP8266 por conexión serie, pero que el ESP8266 vuelve a enviar por el mismo serie al arduino uno?
no entiendo bien cómo monitorizas los datos que escribes desde el esp8266, ¿podrías poner un esquema y dónde está el pc que lo monitoriza?
Por otro lado, si ves solo "basura" ¿tienes bien la configuración del puerto serie del pc?
Y por último, para enviar mezclados textos y números usa String(), por ejemplo:

Serial.print(String(valorldr1)+","+String(valorldr2)+","....

De todas formas creo que para lo que quieres hacer es replantearte, como te comentó @Surbyte , un protocolo.
Este te facilitará a la larga la integración y estabilidad.
Denes de definir bien qué quieres enviar, cuáles son los valores máximos etc. Encapsularlo, enviarlo y usar la misma estructura en la recepción. No creo que sea buena práxis que intentes enviar "LDR:" y como no te funciona, pues intentar separar por comas, etc etc. replantea qué necesitas exactamente enviar. Surbyte te escribió un posible protocolo que lleva varios campos como el tiempo, número de ldr, valor. yo empezaría por ahí, saber qué necesito.

Por que necesitas hacer eso?

No, simplemente los datos los envío de Arduino al ESP y ahí en el ESP quiero separar los datos para poder tratarlos por separado subirlos a internet a una tabla. El esquema que tengo es... Las LDR conectadas a los puertos analógicos del arduino de A0 a A5, los LEDs tengo en los pines digitales que tienen salidad pwm (3,5,6,9,10), para la comuncación serial están conectado rx con tx del ESP y tx con rx del ESP y nada más. Lo de los datos "basura" es simplemente lo que intento mostrar con indexOf, porque los demás datos si los recibo correctamente, no sé si este utilizando mal la función o el ESP no soporta o tengo que incluir alguna librería para usarlo en el ESP. Si tengo claro lo que necesito transmitir, que es smplemente los valores de LDR porque esos valores son los que necesito luego mostrar en una tabla. Solo se me está complicando un poco al momento de recibirlos e intentar separarlos.

Para poner un contador en el cual se transmitan los datos y poderlo resetar y empiece nuevamente.

Para medir el intervalo, no es necesario poner a cero los milis. Para hacer esto, recuerde el valor de milis al comienzo del intervalo, luego léalo al final y reste el primero del segundo.

Poner a cero milis está mal. Millis se puede usar en otras partes del código, como bibliotecas. Poner a cero milis puede romper bibliotecas

Actualizo el tema.
Ya he conseguido separar los datos y convertirlos a int. Ahora tengo otro preblema. Ya tengo separados los datos y al momento de mostrarlos en el terminal si se muestran separados, pero al momento de almacenarlos en una variable, en todos los valores me muestra siempre el primer valor como se muestra en la imagen
image
El código que implementé para separar los datos es el siguiente:

Serial.println (serialrcv);
    coma1 = serialrcv.indexOf(",");
    if (coma1 > 0){
      Serial.println(serialrcv.substring(0, coma1));
      ldr1 = serialrcv.toInt();        
      Serial.print("LDR 1: ");
      Serial.println(ldr1);
      coma2 = serialrcv.indexOf(",", coma1+1);   
      if (coma2 > 0){
        Serial.println(serialrcv.substring(coma1+1, coma2));
        ldr2 = serialrcv.toInt();        
        Serial.print("LDR 2: ");
        Serial.println(ldr2);
        coma3 = serialrcv.indexOf(",", coma2+1);
        if (coma3 > 0){
          Serial.println(serialrcv.substring(coma2+1, coma3));
          ldr3 = serialrcv.toInt();        
          Serial.print("LDR 3: ");
          Serial.println(ldr3);
          coma4 = serialrcv.indexOf(",", coma3+1);                 
          if (coma4 > 0){
            Serial.println(serialrcv.substring(coma3+1, coma4));
            ldr4 = serialrcv.toInt();        
            Serial.print("LDR 4: ");
            Serial.println(ldr4);
          }
        }         
      }         
    }
  }   

tal vez me podrían guiar en la parte de mostrar los diferentes datos que guardo en cada variable.

@kev98y luego de 13 posts debo agradecer por no dedicar 1 minuto de tu tiempo a responderme. Post#3.
Yo en cambio dediqué unos cuantos minutos (+30) para ensayar algo que funcionara, pero me equivoqué contigo, pensé que lo apreciarías, pero no fue el caso.
Seguramente el código no resuelve el 100% de tus problemas como mi mala interpretación de setMillis() pero en el código que tu posteaste no habia tal rutina.
De todas formas sigue con la linea que traes.

Si respondí en el Post#4 está la respuesta. Como dije, no utilicé la forma reducida por el motivo que se enviaban los datos juntos. Pero en sí mi respuesta está en el Post#4 @Surbyte .

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.