Go Down

Topic: COMANDOS HEXADECIMALES SOBRE RS485 (Read 5603 times) previous topic - next topic

drbv27

Si le digo que me lo escriba en me lo escriba en HEXA en el puerto es igual....o sea me demuestra que lo que leyo, lo leyo en ASCII.

Code: [Select]
int incomingByte = 0;   // for incoming serial data

void setup() {
        Serial.begin(9600);     // opens serial port, sets data rate to 9600 bps
}

void loop() {

        // send data only when you receive data:
        if (Serial.available() > 0) {
                // read the incoming byte:
                incomingByte = Serial.read();

                // say what you got:
                Serial.print(incomingByte,HEX);
        }
}



noter

Por favor. ¿Puedes resumir un poco para saber en qué punto estás?
Qué dispositivo envía y cómo lo envía, qué dispositivo recibe y cómo lo recibe.
Es que las fotos del oncomm no sé exactamente qué son, si lo que envías desde el propio terminal, envía la sonda o el arduino.

drbv27

Hola noter

Te cuento que en el punto en que estoy cada vez me estoy volviendo mas loco, ya no se me ocurre nada mas.

Voy a explicarles en que punto estoy a ver si me pueden ayudar y tratare de ser lo mas claro y descriptivo posible.

A.Mi parte del algoritmo de ENVIO de comandos desde al arduino a la red esta funcionando ok.
B. Ahora estoy trabajandole a la etapa de recibir la respuesta de las sondas, o sea leer el puerto y almacenarlo.


Ahora veamos las diferentes descripiciones:

Hardware:

Para las pruebas estoy usando netamente el arduino conectado al USB de mi Laptop y nada mas.

Firmware(sketch):

Estoy tratando de usar solo el sketch para recibir datos.

Software:

El programa de serial de Omnicom, me permite poner en el puerto los datos tal cual como lo pondria el ARDUINO en la red (comando) o como en esta etapa como los pondria la sonda en la red.


Por ende al yo darle conectar en el software (Arduino, puerto correcto y velocidad igual al sketch), mi Arduino queda conectado al software.

Luego en la linea de comando yo puedo enviar a travez del puerto una trama como yo quiera(comando o respuesta) en este caso estoy enviando una trama tipo respuesta en HEXADECIMAL, como me la devolveria una sonda (esta trama la saque de un ejemplo practico o sea son valores de un tanque que tengo conectado)

La trama de prueba que estoy enviando es:

En HEXA:

3E 02 06 1C 1D 0A E2 05 C4

El caso es que de alli solo me interesa lo siguiente:

El 3E Para validar que es una respuesta de sonda
EL 02 para saber que sonda respondio (en este caso la 2)
El 1C es la temperatura, en este caso 1C = 28°C (HEXA A DEC)
El 1D Y 0A son la altura en este caso los debo reorganizar 0A1D=2584 (HEXA A DEC)

Bueno ya descrito lo que es cada cosa y como esta conectado procedo a contarles que me pasa:


1. Construi el siguiente codigo para probar lectura:

Code: [Select]
int incomingByte = 0;   // for incoming serial data

void setup() {
        Serial.begin(9600);     // opens serial port, sets data rate to 9600 bps
}

void loop() {

        // send data only when you receive data:
        if (Serial.available() > 0) {
                // read the incoming byte:
                incomingByte = Serial.read();

                // say what you got:
                Serial.write(incomingByte);
        }

}


uso Serial.write para que me lo ponga igual, porque con Serial.print es una locura en todas las pormas que me despliega la informacion.

Con este Sketch en este momento logro ver que lo que capturo en el puerto me lo esta devolviendo.

El problema que veo es que me lo toma como un TODO y entonces no puedo poner un condicional para que me llene un ARRAY y poder tomar de alli solo los datos que necesito.


Construi el siguiente mini Sketch ya para probar guardarlo en un ARRAY

Code: [Select]
byte incomingByte = 0;   // for incoming serial data
byte cont=0;
byte data[2];

void setup() {
        Serial.begin(9600);     // opens serial port, sets data rate to 9600 bps
}

void loop() {

        // send data only when you receive data:
        if (Serial.available() > 0) {
                // read the incoming byte:
                incomingByte = Serial.read();
               
                if (incomingByte==62)
                {
                  while(cont<=1)
                  {
                    data[cont]==incomingByte;
                    cont=cont+1;
                  }
                  Serial.write(data[0]);
                  Serial.write(data[1]);
                 
        }
}
}



Entonces simulo enviando solo 2 bytes para probar

3E 4A......Deberia de ejecutar el codigo porque arranca con 3E (o 62 como lo lee el ARDUINO) y llevar a las 2 posiciones del ARRAY los datos.

5A4F.....NO deberia hacer nada

Pero en este punto el problema es doble

1. Siempre ejecuta el algoritmo
2. siempre me devuelve 00 00

Creanme ya no se que hacer.

Disculpen el POST tan largo

               
   



drbv27

Adjunto pantalla de respuesta de ambos sketchs


RECEPCION EN BRUTO




ARRAY 1 CON 3E en encabezado



ARRAY 2 CON 3E en cualquier otra parte



ARRAY 3 SIN 3E en ninguna parte




Osea lo que veo que pasa en que si el 3E (62) viene en cualquier parte me corre el codigo.
Pero el array no se esta llenando ya que siempre me arroja vacio [00 00]

Alguna sugerencia??


drbv27

Alguna otra opcion de separar los datos que necesito?


noter

Prueba esto a ver si es lo que buscas:

Code: [Select]

struct sonda {
  byte numSonda;
  byte a;
  byte temperatura;
  int nivel;
  char b;
  char c;
  char d;
} datoSonda;

void setup() {
  Serial.begin(9600);     // opens serial port, sets data rate to 9600 bps
}

void loop() {
  byte incomingByte;
  // send data only when you receive data:
  if (Serial.available() > 0) {
    // read the incoming byte:
    incomingByte = Serial.read();
    if (incomingByte == 0x3E)
    {
          char *pSonda = (char *) &datoSonda;
          for (int i=0; i<8; i++) {
                pSonda[i] = Serial.read();
          }
    }
    Serial.print("Temperatura: ");
    Serial.print(datoSonda.temperatura);
    Serial.print(", Nivel: ");
    Serial.println(datoSonda.nivel);
  }
}

drbv27

Hola Noter

ese codigo es muy avanzado para mi...no lo entiendo...jejejeeje

sin embargo lo implemente y me devuelve

temperatura=0 nivel=0

7 veces


noter

De momento veo que puse los print fuera de lugar:

Code: [Select]


struct sonda {
  byte numSonda;
  byte a;
  byte temperatura;
  int nivel;
  char b;
  char c;
  char d;
} datoSonda;

void setup() {
  Serial.begin(9600);     // opens serial port, sets data rate to 9600 bps
}

void loop() {
  byte incomingByte;
  // send data only when you receive data:
  if (Serial.available() > 0) {
    // read the incoming byte:
    incomingByte = Serial.read();
    if (incomingByte == 0x3E)
    {
      char *pSonda = (char *) &datoSonda;
      for (int i = 0; i < 8; i++) {
        pSonda[i] = Serial.read();
      }
      Serial.print("Temperatura: ");
      Serial.print(datoSonda.temperatura);
      Serial.print(", Nivel: ");
      Serial.println(datoSonda.nivel);
    }
  }
}


Prueba a enviar una trama de las que debería enviar un sensor.

surbyte

Te he enviado un privado. Si te parece intento via remota darte mi asistencia. Cuando los problemas persisten como el tuyo me surge hacerlo asi que es mas fácil que estar por dias intentando entender que te ocurre.

drbv27

He respondido a tu mensaje...mil gracias

drbv27

Bueno

Tengo que agradecer enormemente a SURBYTE por su enorme ayuda, vaya que me ha sacado de un atasco tremendo.

Hemos logrado obtener la informacion que llegaba al puerto y poder interpretarla, hemos (bueno realmente el) tomado un primer sketch muy simple que yo hice y analizando con el programa de omnicom chequeabamos que pasaba en el puerto hasta que vimos que pasaba (vuelvo y anoto el ha sido).

Basicamente lo que entendi es que habia que crear una rutina que almacenara el valor en el puerto, corriera dos puestos en el arreglo y almacenara el siguiente dato, al finalizar de leer todo el dato si llamar la info de este arreglo y utilizarla para interpretarla.

Se que mis palabras no son muy elegantes y talvez algo confusas, asi que dejo que sea SURBYTE quien explique mejor.

Pongo el Codigo que esta funcionando para ver si NOTER que es mucho mas organizado y trabaja mas eficientemente me puede ayudar a mejorar el codigo, partiendo de la base de que este funciona.

Code: [Select]

byte incomingByte[16];   // for incoming serial data
byte indice;
bool MostrarDatos = false;

void setup() {
        Serial.begin(9600);     // opens serial port, sets data rate to 9600 bps
}

void loop() {

        // send data only when you receive data:
        if (Serial.available() > 0) {
                // read the incoming byte:
                incomingByte[indice] = Serial.read();
                // say what you got:
                //Serial.write(incomingByte[indice]);
                indice++;
                if (indice >=9)
                   MostrarDatos = true;
        }
        if (MostrarDatos){
           Serial.print("Temperatura = ");
           Serial.println(incomingByte[3], DEC);
           int Nivel = incomingByte[5]*256+incomingByte[4];
           Serial.print("Nivel = ");
           Serial.println(Nivel);
           MostrarDatos = false;
           indice = 0;
        }
}

surbyte

Brillante Diego. Tu explicación es exacta.
Yo he dicho que como ingeniero programo de un modo no muy bonito. En cambio Noter lo hace con elegancia.

Ya que encontramos el problema y es que no se puede leer dos veces dentro de if (Serial.available() >0) porque el segundo Serial.read() se llena con 0xff y ese era el problema en el código de Noter.
Ahora que usamos un array que almacena todos los bytes, podemos pasar a un modo mas elegante usando el concepto de estructura sugerido por Noter.

De hecho el sketch funciona pero si se puede hacer mejor, porque no? Asi que Serafín, te paso el testigo de la posta 4x100 mts.

noter

¿Has llegado a probar el último código que te propuse, enviando una trama que comience con 3E?
Me parece que debería funcionar, lo que pasa es que no he podido simularlo así, pero haciendo que el programa espere hasta tener los 8 bytes (aparte del 3E de inicio de trama) parece que sí me va en la simulación.
Prueba y me dices si funciona. Los datos deberían quedar guardados en la estructura (faltaría por saber a qué corresponde el byte que va tras el número de sonda y los tres que van tras el nivel:

Code: [Select]



struct sonda {
  byte numSonda;
  byte a;
  byte temperatura;
  int nivel;
  char b;
  char c;
  char d;
} datoSonda;

void setup() {
  Serial.begin(9600);     // opens serial port, sets data rate to 9600 bps
}

void loop() {
  byte incomingByte;
  // send data only when you receive data:
  if (Serial.available() > 0) {
    // read the incoming byte:
    incomingByte = Serial.read();
    if (incomingByte == 0x3E)
    {
      char *pSonda = (char *) &datoSonda;
      for (int i = 0; i < 8; i++) {
        pSonda[i] = Serial.read();
      }
          Serial.print("Número sonda: ");
          Serial.print(datoSonda.numSonda);
          Serial.print(", Temperatura: ");
          Serial.print(datoSonda.temperatura);
          Serial.print(", Nivel: ");
          Serial.println(datoSonda.nivel);
    }
  }
}

drbv27

Hola Noter

ese fue uno de los que probamos con surbyte y se llenaba todo con FF.

La forma del sketch me parece fenomenal y en verdad me gustaria implementarla asi como tu propones...pero este no funciona.


surbyte

Noter el problema de tu código es que el for no lee nada, porque ya lo hizo la instrucción anterior.
se llena de FF.

Mira el código que armé con drbv27 y si puedes ajustalo con la estructura.

Go Up