Go Down

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

noter

Bien. Creo que te puede estar pasando lo que a mí en la simulación. Pensé que con serial.read el arduino esperaba un tiempo de timeout, pero tal vez no sea así.

Agrega una pequeña pausa o una espera a dato en el for:

Code: [Select]


      for (int i = 0; i < 8; i++) {
        while (!Serial.available); // bucle infinito hasta que llegue dato
        pSonda[i] = Serial.read();
      }


o así (busca un valor de delay adecuado)

Code: [Select]


      for (int i = 0; i < 8; i++) {
        delay(50);  //
        pSonda[i] = Serial.read();
      }

noter

#46
May 07, 2015, 12:12 am Last Edit: May 07, 2015, 12:13 am by noter
drbv27:
Veo que has abierto otro hilo sobre el mismo tema, y surbyte te ha dado un "tirón de orejas" con toda la razón. Debes ser un poco paciente y esperar las contestaciones en el hilo original, porque luego viene el descontrol. Por ejemplo, veo que en el otro hilo sí has puesto la información de todos los datos de la trama, cosa que echaba de menos en este hilo. Supongo que si funciona el último código sabrás cómo sacar los demás datos, pero lo pongo por si acaso.

Code: [Select]


struct sonda {
  byte numSonda;
  byte codComando;
  byte temperatura;
  int nivel;
  char frec1;
  char frec2;
  char checkSum;
} 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(", Comando: ");
          Serial.print(datoSonda.codComando);
          Serial.print(", Temperatura: ");
          Serial.print(datoSonda.temperatura);
          Serial.print(", Nivel: ");
          Serial.print(datoSonda.nivel);
          Serial.print(", Frecuencia 1: ");
          Serial.print(datoSonda.frec1);
          Serial.print(", Frecuencia 2: ");
          Serial.print(datoSonda.frec2);
          Serial.print(", Checksum: ");
          Serial.println(datoSonda.checkSum);
    }
  }
}


Como podéis ver, no he hecho nada raro con el nivel. La razón es que en arduino los datos numéricos también se almacenan "al revés" (creo, aunque no estoy seguro 100%).

drbv27

Bueno muchachos

Tengo que agradecerles por tanto trabajo y ayuda MIL Y MIL gracias.

Les cuento que unifique los sketchs y me compilo bien.

Pero para probar que todo vaya bien deberia poder expiar la red RS485

Pero otra vez vuelve el novato a solicitar ayuda.

Adjunto una imagen de como es mas o menos la conexion que tengo.

Alguien me dice como podria Conectarme y con que para poder ver que los datos esten fluyendo como deben?

En algun otro post habia leido que con otro arduino quitandole el atmega y usando un chip max485.

Yo en el momento tengo otro arduino al que le podria quitar el atmega (el unico asi, todos los que tengo son SMD).

Pero no tengo el chip a la mano, pero si tengo otro shield igual al que use para el Arduino Maestro.

No se si se pueda con esto...o definitivamente tenga que comprar otro Hardware.



surbyte

Para espiar o MONITOREAR la red 485 pones una PC con un max en modo escucha o Receptor, usas tu programa y todo lo que se converse por la red aparecerá ahi.

Muy muy simple.
Ahora,  ten cuidado con las impedancias.
En el proyecto Souliss (ver foro Proyectos) está muy bien explicada la interfax 485. Mira bien como lo conectan porque a veces se porta mal. Puedes llegar a necesitar un resistor de 120 ohms en tu ARduino (Rs485) y otro de 120 tmb en el ultimo sensor.
Pero como es poca la distancia puede que no.
Mira los consejos del proyecto Souiliss.


drbv27

Bueno Amigos

Les cuento que gracias a la gran ayuda de todos ustedes (muy especialmente a SURBYTE aunque tome aportes de cada uno)

Pude llegar a un Sketch Funcional y totalmente estable.

La idea era conectar mi Arduino a una Raspberry, pues en ella esta toda la parte Visual y de procesamiento mas complejo, asi que cree un Puerto adicional por Software y por alli envio ya los datos depurados e Interpretados.

Esta misma semana debe quedar el proyecto definitivo, pero por ahora les comparto el Sketch.

Igualmente no soy el mejor programador, asi que cualquier cosilla que vean que se le puede mejorar u optimizar al codigo, recibo las sugerencias.

Nuevamente muchas gracias a todos por sus aportes, sin su valiosa ayuda no hubiese podido sacar esto adelante.

surbyte
noter
PeterKantTropus

No se como cerrar el Hilo, pero ya se podria dar por cerrado.


Code: [Select]
#include <SoftwareSerial.h>

SoftwareSerial mySerial(10,11); //Puerto serial por Software Extra para conectar con RaspberryPi

#define BUFFER_SIZE 64

byte frame[BUFFER_SIZE];
unsigned char buffer;
unsigned int contador = 0;
bool  SondaNoResponde = false;
int tka = 4;//Estos pines van a ser controlados externamente por la Raspberry 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 indice = 0;

#define  myaddress     01  //Priemra direccion de la RED para el Maestro


void setup() {

  Serial.begin(9600);  //Inicio el puerto a 9600
  mySerial.begin(4800);//Inicio puerto serial por software a 4800
  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()

{
  //Lectura PIN para compartimiento "a"
  valor_actualA=digitalRead(4);
  if (valor_anteriorA==LOW && valor_actualA==HIGH) {
  sendCMD(0x31, 0x02, 0x06, 0x39);
  delay(50);
    ReciboData(); //Funcion creada para Recibir Datos
    EnvioData();  //Funcion Creada para enviar Datos
  }

  //Lectura PIN para compartimiento "b"
   valor_actualB=digitalRead(7);
   if (valor_anteriorB==LOW && valor_actualB==HIGH){
   sendCMD(0x31,0x03,0x06,0xfd);   
   delay (50);
    ReciboData();
    EnvioData();
  }
 
  //Lectura PIN para compartimiento "c"
    valor_actualB=digitalRead(8);
    if (valor_anteriorB==LOW && valor_actualB==HIGH){
    sendCMD(0x31,0x04,0x06,0x93);   
    delay (50);
    ReciboData();
    EnvioData();
}
}


//FUNCIONES

void sendCMD(byte prefix, byte address, byte command, byte checksum)
{
  digitalWrite(EN, HIGH);
  delay(10);
  Serial.write(prefix);
  Serial.write(address);
  Serial.write(command);
  Serial.write(checksum);
  delay(6);
  digitalWrite(EN, LOW); // Recibiendo de la sonda.
  indice = 0;
  }



void ReciboData() {
  if (Serial.available()) // is there something to check?
  {
    unsigned char overflowFlag = 0;
    buffer = 0;
    while (Serial.available())
    {
      if (overflowFlag)
        Serial.read();
      else
      {
        if (buffer == BUFFER_SIZE)
          overflowFlag = 1;

        frame[buffer] = Serial.read();
        buffer++;
      }
    }
  }
}


void EnvioData() {
      mySerial.print("C: ");
      mySerial.println(frame[1],DEC);
      mySerial.print("T= ");
      mySerial.println(frame[3], DEC);
      int Nivel = frame[5] * 256 + frame[4];
      mySerial.print("N= ");
      mySerial.println(Nivel);
}

drbv27

Francamente creo que pocas personas me habian brindado una ayuda tan desinteresada como "surbyte", dedico horas de su tiempo a ayudarme a sacar esto adelante, tengo que decir tambien que aprendi bastante de el; no solo trato de ayudarme a que el sketch funcionara, sino a que yo le pusiera logica y entendiera bien el tema.
Un agradecimiento se queda corto por tus horas de trabajo y colaboracion para conmigo.
Ojala hubiera mas gente como el que se dedica a ayudar de esta manera, a veces poner un codigo y pretender que todos lo entendamos y copiemos por que si, no es suficiente, tratare de volverme muy activo en el foro y ayudar a la gente con lo poco que se,tratando de emular este gran favor.


pistojo

Luce bien. Hasta donde vi.
LO que hago en esos casos es armar un segundo Max485 y con algun programa de prueba para la PC leo la trama enviada.
OJo que la pc tiene niveles rs232 o sea +-12V y tienes que usar un max232 para convertirlos a TTL y luego le max485. Hay mucha documentación sobre eso.
Asi verás la trama enviada en la PC y podras contestarle tambien.
Muchos de esso programas son Modbus monitors.
Hola Surbyte, estaba buscando por el foro una solucion para poder leer de un controlador de aire acondicionado que usa rs485, yo queria hacerlos con un usb-ttl, y un rs485, tienes por ahi agun esquema de como debo de conectarlos?
Gracias.
Un Saludo

surbyte

Y donde usas el Arduino? USB to TTL, y con los pines TTL controlas el modulo RS485 y luego con éste te conectas al aire acondicionado.

Mira no fue fácil encontrar un esquema que te oriente. Espero puedas entender este




Supongamos que este sea tu módulo


Tengamos una buena imaginación para encontrar los equivalentes de cada pin.

RX y TX, al igual que 5V y GND no requieren explicación.
Debes unir GND al GND dle módulo y lo mismo TX y RX
Luego falta el pin que controla el envio/recepción de bytes asi que ese pin debería ser DTR si tienes un adaptador USB como este



TX -> DI
RX => RO
DTR -> RE unido a DE

Go Up