Go Down

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

drbv27

Con el codigo de PeterKantTropus, me envia muy bien una vez, pero despues no puedo volver a enviar nunca mas.

Peter que me sugieres para poder volver a enviar?

AH Y POR CIERTO SURBYTE SI SON UNOS PULSADORES LOS QUE USO.

Code: [Select]
//Primer sketch de comunicacion con las sondas


int tka = 4;//Estos pines van a ser controlados externamente para saber por cual sonda pregunta el arduino
int tkb = 7;
int tkc = 8;
int EN = 2;  //RS485 shield Enable terminal, High for Send , Low for Receive
unsigned int valor_actualA;
unsigned int valor_actualB;
unsigned int valor_actualC;
unsigned int valor_anteriorA;
unsigned int valor_anteriorB;
unsigned int valor_anteriorC;
byte data[8];
byte cont;


#define  myaddress     01


void setup() {
 
    Serial.begin(9600);
    pinMode(tka,INPUT);
    pinMode(tkb,INPUT);
    pinMode(tkc,INPUT);
    pinMode(EN,OUTPUT);
    digitalWrite(EN,LOW);
    valor_anteriorA==LOW;
    valor_anteriorB==LOW;
    valor_anteriorC==LOW;
   
}

void loop()
{
  valor_actualA=digitalRead(4);
  if (valor_anteriorA==LOW && valor_actualA==HIGH)
  {
   
  //if (digitalRead(4)==HIGH){
    //Serial.flush();     
    //(byte prefix,byte address,byte command,byte checksum)
    //Voy a Enviar (0x31, 0x02, 0x06, 0x39)
    sendCMD(49,2,6,57);
    valor_anteriorA=digitalRead(4);
    //DESPUES DE ESTO DEBERIA PONER EN==LOW, PARA RECIBIR LA RESPUESTA DE LA SONDA, POR EL MOMENTO LO VOY A HACER SIN VERIFICAR EL CHECKSUM.
    //OSEA EN BRUTO DEBERIA RECIBIR ALGO SIMILAR A: 0x3E, 0x02, 0x06, 0x1C, 0x1D, 0x0A, 0xE2, 0x05, 0xC4
    //Siempre va a tener el mismo tamaño 9 bytes (byte prefix, byte address, byte command, byte tempe, byte lvl1, byte lvl2, byte freq1, byte frec2, byte checksum)
    receiveINFO();
   
  }
  valor_actualB=digitalRead(7);
  if (valor_anteriorB==LOW && valor_actualB==HIGH)
  {
   
  //if (digitalRead(4)==HIGH){
    //Serial.flush();     
    //(byte prefix,byte address,byte command,byte checksum)
    //Voy a Enviar (0x31, 0x02, 0x06, 0x39)
    sendCMD(49,3,6,253);
    valor_anteriorB=digitalRead(7);
    //DESPUES DE ESTO DEBERIA PONER EN==LOW, PARA RECIBIR LA RESPUESTA DE LA SONDA, POR EL MOMENTO LO VOY A HACER SIN VERIFICAR EL CHECKSUM.
    //OSEA EN BRUTO DEBERIA RECIBIR ALGO SIMILAR A: 0x3E, 0x02, 0x06, 0x1C, 0x1D, 0x0A, 0xE2, 0x05, 0xC4
    //Siempre va a tener el mismo tamaño 9 bytes (byte prefix, byte address, byte command, byte tempe, byte lvl1, byte lvl2, byte freq1, byte frec2, byte checksum)
    receiveINFO();
  }
  valor_actualC=digitalRead(8);
  if (valor_anteriorC==LOW && valor_actualC==HIGH)
  {
   
  //if (digitalRead(4)==HIGH){
    //Serial.flush();     
    //(byte prefix,byte address,byte command,byte checksum)
    //Voy a Enviar (0x31, 0x02, 0x06, 0x39)
    sendCMD(49,4,6,147);
    valor_anteriorC=digitalRead(8);
    //DESPUES DE ESTO DEBERIA PONER EN==LOW, PARA RECIBIR LA RESPUESTA DE LA SONDA, POR EL MOMENTO LO VOY A HACER SIN VERIFICAR EL CHECKSUM.
    //OSEA EN BRUTO DEBERIA RECIBIR ALGO SIMILAR A: 0x3E, 0x02, 0x06, 0x1C, 0x1D, 0x0A, 0xE2, 0x05, 0xC4
    //Siempre va a tener el mismo tamaño 9 bytes (byte prefix, byte address, byte command, byte tempe, byte lvl1, byte lvl2, byte freq1, byte frec2, byte checksum)
    receiveINFO();
 
  }
 //if (digitalRead(7)==HIGH){
 //   Serial.flush();     
    //(byte prefix,byte address,byte command,byte checksum)
    //Voy a Enviar (0x31, 0x02, 0x06, 0xFD)
  //  sendCMD(49,3,6,253);
    //receiveINFO();
   
// }
   
//if (digitalRead(8)==HIGH){
   /// Serial.flush();     
    //(byte prefix,byte address,byte command,byte checksum)
    //Voy a Enviar (0x31, 0x02, 0x06, 0x93)
  //  sendCMD(49,4,6,147);
  //  receiveINFO();
//}
 

}

//Funciones

byte receiveINFO()
{
  byte byte_receive;
  byte conteo=0;
 
  while(Serial.available())
  {
    byte_receive=Serial.read();
    if (byte_receive==62)
    {
      while(conteo<=7)
      {
        data[cont]==byte_receive;
        cont=cont+1;
      }
    }
  }
}

void sendCMD(byte prefix,byte address,byte command,byte checksum)
{
 
 
  digitalWrite(EN,HIGH);
  delay(1);

  Serial.print(prefix,HEX);
  Serial.print(address,HEX);
  Serial.print(command,HEX);
  Serial.print(checksum,HEX);
  digitalWrite(EN,LOW);

 
 
}


drbv27

Amigos tengo un gran problema

conecto el ARDUINO(O VARIOS QUE TENGO) Con el sketch cargado y con solo acercarle los dedos este comienza a enviar informacion como loco....que puede pasar?


surbyte

tienes las entradas al aire, sinresistencias pull down o pull up.

drbv27

Hola surbyte

Tienes toda la razon, gracias por hacerme caer en cuenta de esa bestialidad, mil disculpas por la ignorancia.

A proposito...viste el codigo que implemente con tu ayuda?
que hice mal?
no me envia nada

El PeterKant, me funciona, pero envia una unica vez.

Lo que yo pretendo es al pulsar envie una vez nada mas no importa lo que dure el pulso, pero si vuelvo a pulsar envie nuevamente.

Chicos disculpen la ignorancia, pero cada dia voy mejorando y estoy seguro que no volvere a caer en errores comunes, pero como ven aun soy bastante newbe.


drbv27

De cuanto me sugieres las resistencias a tierra?


drbv27

Bueno muchachos les comparto mis avances:

El problema que tenia con el codigo de flancos de subida, lo solucione con un delay, ahora me envia una sola vez al pulsar, pero me permite enviar nuevamente al pulsar otra vez.

Tenia un problema en funcion de enviar por el puerto, pues estaba usando serial.print() y eso me enviaba entendible(visual) en el puerto de arduino; pero cuando iva y chequeava el puerto en bruto no me enviaba los hexadecimales que queria, sino los correspondientes a los ascii que ponia visualmente; me explico: yo queria enviar 0x31 0x02 0x06 0x39 y en el monitor de arduino se veia 312639(visualmente lo que queria) pero al ir con otro programa directo al puerto lo que enviaba era: 0x33 0x31 0x32 0x36 0x33 0x39 o sea los hexadecimales de la cadena que veia en el monitor de ARDUINO.
Solucion: simple cambie serial.print por serial.write y todo va de maravilla.

El problema de las falsas impedancias lo solucione con 3 resistencias de 10k (aun tengo duda del valor) entre los pines de entrada y tierra.

anexo el codigo para ver si ven algo mal, por ahora lo que he chequeado funciona, pero eso no quiere decir que no pueda tener un error.
Ahora voy a comenzar a chequear la lectura de datos.(respuesta de las sondas)

Code: [Select]
//SONDAS OMMNICOM BAJO RS-485
//Y COMANDOS HEXADECIMALES
//BY: DIEGO BONILLA
//30-04-2015


int tka = 4;//Estos pines van a ser controlados externamente para saber por cual sonda pregunta el arduino
int tkb = 7;
int tkc = 8;
int EN = 2;  //RS485 shield Enable terminal, High for Send , Low for Receive
unsigned int valor_actualA;  //Variables Flotantes
unsigned int valor_actualB;
unsigned int valor_actualC;
unsigned int valor_anteriorA;
unsigned int valor_anteriorB;
unsigned int valor_anteriorC;
byte data[8];  //Arreglo para almacenar recibido
byte cont;


#define  myaddress     01


void setup() {
 
    Serial.begin(9600);  //Inicio el puerto a 9600
    pinMode(tka,INPUT);  //Defino las 3 variables asociadas a los Pines Como Entradas
    pinMode(tkb,INPUT);
    pinMode(tkc,INPUT);
    pinMode(EN,OUTPUT);
    digitalWrite(EN,LOW); //arranco el shield en Lectura
    valor_anteriorA==LOW; //Arranco en "0" para detectar la subida de Flanco
    valor_anteriorB==LOW;
    valor_anteriorC==LOW;
   
}

void loop()
{
  valor_actualA=digitalRead(4);
  if (valor_anteriorA==LOW && valor_actualA==HIGH)
  {
    //Serial.flush();     
    //(byte prefix,byte address,byte command,byte checksum)
    //Voy a Enviar (0x31, 0x02, 0x06, 0x39)
    sendCMD(49,2,6,57);
    receiveINFO();
    delay (500);
    valor_anteriorA=digitalRead(4);
    //DESPUES DE ESTO DEBERIA PONER EN==LOW, PARA RECIBIR LA RESPUESTA DE LA SONDA, POR EL MOMENTO LO VOY A HACER SIN VERIFICAR EL CHECKSUM.
    //OSEA EN BRUTO DEBERIA RECIBIR ALGO SIMILAR A: 0x3E, 0x02, 0x06, 0x1C, 0x1D, 0x0A, 0xE2, 0x05, 0xC4
    //Siempre va a tener el mismo tamaño 9 bytes (byte prefix, byte address, byte command, byte tempe, byte lvl1, byte lvl2, byte freq1, byte frec2, byte checksum)
   
  }
  valor_actualB=digitalRead(7);
  if (valor_anteriorB==LOW && valor_actualB==HIGH)
  {
    //Serial.flush();     
    //(byte prefix,byte address,byte command,byte checksum)
    //Voy a Enviar (0x31, 0x03, 0x06, 0x39)
    sendCMD(49,3,6,253);
    receiveINFO();
    delay (500);
    valor_anteriorB=digitalRead(7);
    //DESPUES DE ESTO DEBERIA PONER EN==LOW, PARA RECIBIR LA RESPUESTA DE LA SONDA, POR EL MOMENTO LO VOY A HACER SIN VERIFICAR EL CHECKSUM.
    //OSEA EN BRUTO DEBERIA RECIBIR ALGO SIMILAR A: 0x3E, 0x02, 0x06, 0x1C, 0x1D, 0x0A, 0xE2, 0x05, 0xC4
    //Siempre va a tener el mismo tamaño 9 bytes (byte prefix, byte address, byte command, byte tempe, byte lvl1, byte lvl2, byte freq1, byte frec2, byte checksum)
  }
  valor_actualC=digitalRead(8);
  if (valor_anteriorC==LOW && valor_actualC==HIGH)
  {
    //Serial.flush();     
    //(byte prefix,byte address,byte command,byte checksum)
    //Voy a Enviar (0x31, 0x04, 0x06, 0x39)
    sendCMD(49,4,6,147);
    receiveINFO();
    delay (500);
    valor_anteriorC=digitalRead(8);
    //DESPUES DE ESTO DEBERIA PONER EN==LOW, PARA RECIBIR LA RESPUESTA DE LA SONDA, POR EL MOMENTO LO VOY A HACER SIN VERIFICAR EL CHECKSUM.
    //OSEA EN BRUTO DEBERIA RECIBIR ALGO SIMILAR A: 0x3E, 0x02, 0x06, 0x1C, 0x1D, 0x0A, 0xE2, 0x05, 0xC4
    //Siempre va a tener el mismo tamaño 9 bytes (byte prefix, byte address, byte command, byte tempe, byte lvl1, byte lvl2, byte freq1, byte frec2, byte checksum)
 
  }

}

//Funciones

byte receiveINFO()
{
  byte byte_receive;
  byte conteo=0;
 
  while(Serial.available())
  {
    byte_receive=Serial.read();
    if (byte_receive==62)
    {
      while(conteo<=7)
      {
        data[cont]==byte_receive;
        cont=cont+1;
      }
    }
  }
}

void sendCMD(byte prefix,byte address,byte command,byte checksum)
{
 
  digitalWrite(EN,HIGH);
  delay(1);

  Serial.write(prefix);
  Serial.write(address);
  Serial.write(command);
  Serial.write(checksum);
  digitalWrite(EN,LOW);

 
 
}




drbv27

Amigos

Ya tengo muy depurada el envio de comandos, pero no se si la lectura este bien.
Ademas quisiera hacer lo siguiente a ver si alguno me da un empujon, como hasta ahora lo han hecho y lo cual agradezco enormemente.

cuando envio el comando la sonda me va a responder con algo como:

0x3E, 0x02, 0x06, 0x1C, 0x1D, 0x0A, 0xE2, 0x05, 0xC4
d[0]    d[1]   d[2]   d[3]   d[4]   d[5]   d[6]   d[7]   d[8]     y asi lo almaceno (creo segun mi codigo)

la cosa es que me interesan de alli

d[3]=1C                      //Este dato es la temperatura en °C y 1C Es un ejemplo
d[4] y d[5]= 1D 0A       //estos datos son el nivel de liquido Esta es Una vez mas son valores ejemplo

La cosa es que quiero tomar esos valores, convertirlos y devolverlos en forma que se puedan interpretar:

siguiendo con el ejemplo:

1C(hex)= 28(dec)°C

entonces quisiera tomar d[3] y enviar al puerto serial : " t=28"

que me sugieren para hacerlo?

el caso de el nivel es un poco mas complicado:
1D 0A, DEBEN LEERSE AL REVES Osea 0A 1D = 2589

Entonces quisera poner en el puerto "n=2589"

Alguna idea?





surbyte

Pero ya que los tienes en un array, cual es el problema para procesarlos?

Code: [Select]
byte receiveINFO()
{
  byte byte_receive;
  byte conteo=0;
  
  while(Serial.available())
  {
    byte_receive=Serial.read();
    if (byte_receive==62)
    {
      while(conteo<=7)
      {
        data[cont]==byte_receive;
        cont=cont+1;
      }
    }
  }
}


Esta rutina dice que todos los recibes en data[cont] que se incrementa con cada byte

Luego de leerlos solo los procesas.

Code: [Select]
temp = data[3];
Serial.println("T=");
Serail.print(temp); // tambien podrias poner directametne data[3];

nivel = data[5]*256+data[4];
Serial.println("Nivel=");
Serail.print(nivel);


no se si funcionará como esperas. Tal vez haya que convertir mejor esos hexa a decimal.


drbv27

Hola Surbyte

Ya probe como me dijiste y siempre me saca 0

o sea como que el array no se estuviera llenado.

Talvez este fallando con el ==62?

para empezar el llenado del array?


noter

Hola.
Puedes utilizar una estructura con los datos, y llenarla byte a byte mediante un puntero, o una unión. Si todo está bien colocadito, los elementos de la estructura deberían cargarse cada uno con su valor tras "llenar la botella".


surbyte

Has podido leer la trama? Porque cuando lo explicaste dijiste que eran valores sugeridos pero intenta ver si puedes verlos a ver si se llena el array

drbv27

Hola noter y Surbyte

les comento, el finde semana no pude hacer nada ya que se me quedo el cargador del Laptop donde un amigo y este se fue de paseo.

noter gracias por tu explicacion, pero creeme que soy tan novato que no se en la practica como hacerlo.

Surbyte



Las sondas tiene un software para enviarles comando y recibirles

asi puedo simular la respuesta de datos de una sonda, el problema es que ocupa el puerto y no puedo usarlo al mismo tiempo que el monitor de arduino.

Yo veo cuando el led del arduino supuestamente se pone a recibir...flashea por un par de segundos y luego voy a mirar lo que hay en el arreglo y me muestra 0


Creanme no se que puede estar pasando ni como chequear si el arduino si esta asumiendo el comando y grabando en el array, en el sentido inverso es mucho mas sencillo ver que sale yhacer las correciones, pero en el sentido de entrada no la veo tan claro.

Mil gracias por sus aportes y por sus futuras ayudas si pueden darmelas.


drbv27

Yo creo que el problema esta en el

while(Serial.available())
  {
    byte_receive=Serial.read();
    if (byte_receive==62)


No estoy seguro si el ARDUINO asume 0x3E que le envio como 62.
Esas conversiones me vuelven loco.

osea Serial.read()....como interpreta los datos? ASCII, HEX, DEC o como?




surbyte

Simple enviale 0x3E y si se cumple la condicón saca por el serial un cartel que lo confirme

drbv27

Hola muchachos

use este codigo para probar

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);
        }
}
 


Le envio 3E en hexadecimal (por el programa de las sondas)

y me devuelve un 36 32 en hexadecimal.

osea que el puerto lee en ASCII aunque yo se lo mande en Hexa.



hay forma de que el puerto me lo lea como es? digo en hexadecimal

Go Up