Como comunicar dos arduinos ?

Aqui puedes encontrar unas capturas de osciloscopio:

las masas son comunes en ambos micros???? (tienen que serlo)

Si no me equivoco, es algo como maximo +/-6 V si no hay carga, y como minimo +/-1.5V con carga.

Documento con capturas tipicas del bus RS485 (y como detectar problemas):
http://www.sbc-support.ch/faq/files/files.get.php?ZSESSIONID=n38bphov4ls4cdsvtbd8tl6jb4&fi_index=100179

Estupendo Igor,

Con etas informaciones creo que consigo solucionar mi problema.

Cuando termine te informo. Gracias por tu ayuda.

Cristal

PS. Las masas son las mismas, me havia olvidado de informarte :wink:

Como fue Cristal? Funciona?

He visto que sigues el ejemplo de aqui => http://modprobe.complex.ch/2010/03/13/hello-rs485-arduino/

Saludos

Exatamente Igor,

Una prueba bien simples (del software), pero no estoy utilizando la configuracion de hardware sugerida por el, estoy utilizando los pines de control conforme el circuito enviado.

Infelizmente yo solo tengo el domingo para hacer pruebas, y no todos los domingos, pero en este domingo voy a seguir los documentos que me enviates y te cuento lo que paso.

He comprado el max485 para estar seguro que el problema no es el 75176.

Saludos,

Hola a todos,

Igor, finalmente la RS485 esta funcionando ;D pero parcialmente. Me explico.

Tengo un amigo que se compro una casa y la casa nueva tiene una piscina. El me preguntó si podía ayudarle a poner una iluminación diferente en la piscina y yo prontamnete empeze a trabajar en este proyeto.

La idea es utilizar un dip switch durantre el prototipo (interruptores en el proyeto final) através de "arduino standalone" con comunicación RS485 comandar los leds RGB en los focos de la piscina.

Cuando cambié los 75176 con el MAX485, my circuito empezo a funcionar pero todavia tengo dos problemas:

Para leer el dip switch con los ascII sugeridas en tu programa ( 48 49 50 etc) solo llegó hasta 9 (que es igula a 57) pero el dip switch que estoy utilizando llega a 15.

Puedo utilizar outros valores abajo de 48 sin problemas? (arriba de 66 el ckecksum es siempre el mismo)

Hecha una ojeada en las modificaciones que hecho para el master, me funciona perfectamente.

Maestro:

//----------------------------------
//RS 485
//By Igor Real
//24-06-09
//----------------------------------


byte            data[12];
unsigned long   previous_time;
unsigned long   previous_time2;
byte            times_repeat=5;
byte            times_repeat2=5;
int             dipState = 0;
byte            state=0;
byte            state2=0;
int             lastdipState = 20;
//pinos dos dips

const int Dip1 = 5;
const int Dip2 = 6;
const int Dip3 = 7;
const int Dip4 = 8;



#define  pinCONTROL    02
#define  myaddress     01
  

void setup() {

   pinMode(13,OUTPUT);
   pinMode(pinCONTROL,OUTPUT);
   //digitalWrite(13,HIGH);
   //digitalWrite(12,LOW);
   //pinMode(8,INPUT);
   //pinMode(9,INPUT);
   digitalWrite(pinCONTROL,LOW);
   // inicializar botoes input:
  pinMode(Dip1, INPUT); 
  pinMode(Dip2, INPUT);
  pinMode(Dip3, INPUT);
  pinMode(Dip4, INPUT);  
   
   Serial.begin(9600);
   //Serial.println("Empezamos");
   state=0;
   state2=0;
}

void loop()
{
ledip();
  //if (digitalRead(8)==state){
   // state=!state;
   // times_repeat=0;  
 //}
 // if (digitalRead(9)==state2){
 //   state2=!state2;
 //   times_repeat2=0;  
 // }

  //if (dipState!=state){
  //  dipState=state;
  //  times_repeat=0;
  //}
  
  if (dipState != lastdipState) {
    // se o botao mudou, incrementa contador
    //Serial.println(dipState); //debug
    // salva o staus do botao, 
    lastdipState = dipState;
    times_repeat=0;
    //Serial.println(dipState);
  }
  
  
  
  if (times_repeat<4){
    Serial.flush();  
    //(byte address1,byte address2,byte data_type,byte code1,byte code2,byte Sign,byte data1,byte data2,byte data3,byte data4)
    //Serial.println();
    //Serial.println(dipState);
    
    if (dipState==0){  
      sendMSG(48,50,68,48,48,32,48,48,48,48);
    }
    if (dipState == 1){
      
      sendMSG(48,50,68,48,48,32,48,48,48,49);
    }
     if (dipState == 2){
      
      sendMSG(48,50,68,48,48,32,48,48,48,50);
    }
     if (dipState == 3){
      
      sendMSG(48,50,68,48,48,32,48,48,48,51);
    }
     if (dipState == 4){
      
      sendMSG(48,50,68,48,48,32,48,48,48,52);
    }
     if (dipState == 5){
      
      sendMSG(48,50,68,48,48,32,48,48,48,53);
    }
     if (dipState == 6){
      
      sendMSG(48,50,68,48,48,32,48,48,48,54);
    }
     if (dipState == 7){
      
      sendMSG(48,50,68,48,48,32,48,48,48,55);
    }
     if (dipState == 8){
      
      sendMSG(48,50,68,48,48,32,48,48,48,56);
    }
     if (dipState == 9){
      
      sendMSG(48,50,68,48,48,32,48,48,48,57);
    }
     if (dipState == 10){
      
      //sendMSG(48,50,68,48,48,32,48,48,48,20);
    }
     if (dipState == 11){
      
      //sendMSG(48,50,68,48,48,32,48,48,48,21);
    }
     if (dipState == 12){
      
      //sendMSG(48,50,68,48,48,32,48,48,48,22);
    }
     if (dipState == 13){
      
      //sendMSG(48,50,68,48,48,32,48,48,48,23);
    }
     if (dipState == 14){
      
      //sendMSG(48,50,68,48,48,32,48,48,48,24);
    }
     if (dipState == 15){
      
      //sendMSG(48,50,68,48,48,32,48,48,48,25);
    }
     
     
     
     
    
    times_repeat=times_repeat+1;
  
    previous_time=millis();
    while (((millis()-previous_time)<500) && (Serial.available()!=15)){
      ;;
    }
  
    if (Serial.available()>=15){
      if (receiveMSG()==1){
        //Serial.println("Trama correcta");
        if (data[0]==48 && data[1]==49 && data[2]==6){
          //ACK  
          times_repeat=5;
          //Serial.println("ACK recibido");
        }
      }
     }
   }  
  
  

  //if (times_repeat2<4){
   // Serial.flush();  
    //(byte address1,byte address2,byte data_type,byte code1,byte code2,byte Sign,byte data1,byte data2,byte data3,byte data4)
  //  if (digitalRead(9)==HIGH){  
  //    sendMSG(48,50,68,48,48,32,48,48,48,49);
  //  }else {
  //    sendMSG(48,50,68,48,48,32,48,48,48,48);
  //  }
  //  times_repeat2=times_repeat2+1;
  
  //  previous_time2=millis();
  //  while (((millis()-previous_time2)<500) && (Serial.available()!=15)){
  //  ;;
  //  }
  
  //  if (Serial.available()>=15){
  //    if (receiveMSG()==1){
       //Serial.println("Trama correcta");
  //      if (data[0]==48 && data[1]==65 && data[2]==6){
          //ACK  
   //       times_repeat2=5;
          //Serial.println("ACK recibido");
   //     }
   //   }
  //  }
 // }
  
  
  
}


//------------------------
//FUNCIONES
//------------------------

void ledip()
{
  dipState=digitalRead(5) + (digitalRead(6)<<1) + (digitalRead(7)<<2) + (digitalRead(8)<<3);
  //delay(5);
  
}


byte receiveMSG(){

  byte  byte_receive;
  byte  state=0;
  byte  cont1=1;
  byte  trace_OK=0;

  unsigned int checksum;
  unsigned int checksum_trace;
  
  
  
  while (Serial.available() > 0){
    
     byte_receive=Serial.read();
     if (byte_receive==00){
       state=1;
       checksum_trace=0;
       checksum=0;
       trace_OK=0;
       cont1=1;
     }else if (state==1 && cont1<=12){
       data[cont1-1]=byte_receive;
       checksum=checksum+byte_receive;
       cont1=cont1+1;
     }else if (state==1 && cont1==13){
       checksum_trace=byte_receive<<8;
       cont1=cont1+1;
     }else if (state==1 && cont1==14){
       checksum_trace=checksum_trace+byte_receive;
       cont1=cont1+1;
       state=0;
       if (checksum_trace==checksum){
           trace_OK=1;
       }else{
         trace_OK=0;
       }
       break;
     }
  }
  return trace_OK;

}



void sendMSG(byte address1,byte address2,byte data_type,byte code1,byte code2,byte Sign,byte data1,byte data2,byte data3,byte data4){
  
  unsigned int checksum_ACK;
  checksum_ACK=address1+address2+5+data_type+code1+code2+Sign+data1+data2+data3+data4+3;
  
  UCSR0A=UCSR0A |(1 << TXC0);
  
  digitalWrite(pinCONTROL,HIGH);
  delay(1);

  Serial.print(0,BYTE);
  Serial.print(address1,BYTE);
  Serial.print(address2,BYTE);
  Serial.print(5,BYTE);
  Serial.print(data_type,BYTE);
  Serial.print(code1,BYTE);
  Serial.print(code2,BYTE);
  Serial.print(Sign,BYTE);
  Serial.print(data1,BYTE);
  Serial.print(data2,BYTE);
  Serial.print(data3,BYTE);
  Serial.print(data4,BYTE);  
  Serial.print(3,BYTE);
  Serial.print(((checksum_ACK>>8)&255),BYTE);
  Serial.print(((checksum_ACK)& 255),BYTE);
  while (!(UCSR0A & (1 << TXC0)));
  digitalWrite(pinCONTROL,LOW);

  
  
}



void sendACK(byte address1,byte address2,byte data_type,byte code1,byte code2,byte Sign,byte data1,byte data2,byte data3,byte data4){
  
  unsigned int checksum_ACK;
  checksum_ACK=address1+address2+6+data_type+code1+code2+Sign+data1+data2+data3+data4+3;
  
  UCSR0A=UCSR0A |(1 << TXC0);
  
  digitalWrite(pinCONTROL,HIGH);
  delay(1);

  Serial.print(0,BYTE);
  Serial.print(address1,BYTE);
  Serial.print(address2,BYTE);
  Serial.print(6,BYTE);
  Serial.print(data_type,BYTE);
  Serial.print(code1,BYTE);
  Serial.print(code2,BYTE);
  Serial.print(Sign,BYTE);
  Serial.print(data1,BYTE);
  Serial.print(data2,BYTE);
  Serial.print(data3,BYTE);
  Serial.print(data4,BYTE);  
  Serial.print(3,BYTE);
  Serial.print(((checksum_ACK>>8)&255),BYTE);
  Serial.print(((checksum_ACK)&255),BYTE);
  while (!(UCSR0A & (1 << TXC0)));
  digitalWrite(pinCONTROL,LOW);
  
  
}

void sendNAK(byte address1,byte address2,byte data_type,byte code1,byte code2,byte Sign,byte data1,byte data2,byte data3,byte data4){
  
  unsigned int checksum_ACK;
  checksum_ACK=address1+address2+6+data_type+code1+code2+Sign+data1+data2+data3+data4+3;
  
  UCSR0A=UCSR0A |(1 << TXC0);
  
  digitalWrite(pinCONTROL,HIGH);
  delay(1);

  Serial.print(0,BYTE);
  Serial.print(address1,BYTE);
  Serial.print(address2,BYTE);
  Serial.print(15,BYTE);
  Serial.print(data_type,BYTE);
  Serial.print(code1,BYTE);
  Serial.print(code2,BYTE);
  Serial.print(Sign,BYTE);
  Serial.print(data1,BYTE);
  Serial.print(data2,BYTE);
  Serial.print(data3,BYTE);
  Serial.print(data4,BYTE);  
  Serial.print(3,BYTE);
  Serial.print(((checksum_ACK>>8)&255),BYTE);
  Serial.print(((checksum_ACK)&255),BYTE);
  while (!(UCSR0A & (1 << TXC0)));
  digitalWrite(pinCONTROL,LOW);
  
  
}



byte hex2num(byte x){

  byte result;
  
  if (x>=48 && x<=57){
    result=x-48;  
  }else if (x>=65 && x<=70){
    switch(x){
      case 65:
        result=10;
        break;
      case 66:
        result=11;
        break;
      case 67:
        result=12;
        break;
      case 68:
        result=13;
        break;
      case 69:
        result=14;
        break;
      case 70:
        result=15;
        break;    
    }  
  }
  return result;  
}

Continuación...
Para el esclavo, me funciona bien quando selecciono 1, 2 o 3 en el dip switch (del Maestro), pero cuando seleciono 4, por ejemplo, el led rojo deveria empezar un fade in y out, pero el led rojo queda apagado todo el tiempo.
Lo que podría estar mal ? Gracia por la ayuda.

Esclavo:

codigo del esclavo:

//----------------------------------
//RS 485
//By Igor Real
//24-06-09
//----------------------------------


byte  data[12];
byte  address;
byte  function;
byte  function_code;
unsigned int data_received;
byte  byte_receive;
byte  state=0;
byte  cont1=1;
byte  trace_OK=0;
unsigned int checksum;
unsigned int checksum_trace;
int j=0; //para contador
int vel = 10; //para controle velocidade

//pinos dos leds
int redPin   = 9;   // Red LED,   
int greenPin = 10;  // Green LED
int bluePin  = 11;  // Blue LED

//valores iniciais
int redVal   = 255; 
int greenVal = 1;   
int blueVal  = 1;


#define  pinCONTROL    02
#define  myaddress     02     //address da placa
  

void setup() {
   pinMode(redPin,   OUTPUT);   // sets os pins saida
   pinMode(greenPin, OUTPUT);   
   pinMode(bluePin,  OUTPUT);
     
   pinMode(pinCONTROL,OUTPUT);
   digitalWrite(2,LOW);
   Serial.begin(9600);
   }

void loop()
{
  checkSerial();
}

//------------------------
//FUNCIONES
//------------------------

void checkSerial()
  {
       while (Serial.available() > 0){
    
     byte_receive=Serial.read();
     if (byte_receive==00){
       
       state=1;
       checksum_trace=0;
       checksum=0;
       trace_OK=0;
       address=0;
       data_received=0;
       cont1=1;
     }else if (state==1 && cont1<=12){
       data[cont1-1]=byte_receive;
       checksum=checksum+byte_receive;
       cont1=cont1+1;
     }else if (state==1 && cont1==13){
       checksum_trace=byte_receive<<8;
       cont1=cont1+1;
       //Serial.print("Primer Byte Checksum");      
       //Serial.print(checksum_trace,HEX);
     }else if (state==1 && cont1==14){
       checksum_trace=checksum_trace+byte_receive;
       cont1=cont1+1;
       state=0;
       
       if (checksum_trace==checksum){
         trace_OK=1;
        
         address=(hex2num(data[0])<<4)+(hex2num(data[1]));
         function=data[3];
         function_code=(hex2num(data[4])<<4)+(hex2num(data[5]));
         data_received=(hex2num(data[7])<<12)+(hex2num(data[8])<<8)+(hex2num(data[9])<<4)+(hex2num(data[10]));
                 
         execute();
       }
     }
    }
  }

void execute() //excita as funções programadas
{
          if (address==myaddress || address==7){  //address 7 geral para todas as placas broadband
           if ((function=='D') && (function_code==0) && data[2]==5){
              if (data_received==1){    //Dip 1 - Red
              ativaRgb(255,0,0);
               sendACK(data[0],data[1],data[3],data[4],data[5],data[6],data[7],data[8],data[9],data[10]);
             }if (data_received==0){  //Dip 0 -zera leds
               ativaRgb(0,0,0);
               sendACK(data[0],data[1],data[3],data[4],data[5],data[6],data[7],data[8],data[9],data[10]);
             }
             if (data_received==2){    //Dip 2 - Green
               ativaRgb(0,255,0);
               sendACK(data[0],data[1],data[3],data[4],data[5],data[6],data[7],data[8],data[9],data[10]);
             }
             if (data_received==3){    //Dip 3 - Blue
               ativaRgb(0,0,255);
               sendACK(data[0],data[1],data[3],data[4],data[5],data[6],data[7],data[8],data[9],data[10]);
             }
             if (data_received==4){    //Dip 4 - fade red
               sendACK(data[0],data[1],data[3],data[4],data[5],data[6],data[7],data[8],data[9],data[10]);
               fadeRed();
             }
             if (data_received==5){    //Dip 5 - fade green
             sendACK(data[0],data[1],data[3],data[4],data[5],data[6],data[7],data[8],data[9],data[10]);
             fadeGreen();
           }
             if (data_received==6){    //Dip 6 - fade blue
             sendACK(data[0],data[1],data[3],data[4],data[5],data[6],data[7],data[8],data[9],data[10]);
             fadeBlue();
           }
             if (data_received==7){    //Dip 7 - sete cores
             sendACK(data[0],data[1],data[3],data[4],data[5],data[6],data[7],data[8],data[9],data[10]);
             seteCores(5000);
           }
             if (data_received==8){    //Dip 8 - sete cores rapido
             sendACK(data[0],data[1],data[3],data[4],data[5],data[6],data[7],data[8],data[9],data[10]);
             seteCores(200);
           }
           if (data_received==9){    //Dip 9 - rgb
             sendACK(data[0],data[1],data[3],data[4],data[5],data[6],data[7],data[8],data[9],data[10]);
             fadeRGB();
           }
             
       }else{
         sendNAK(data[0],data[1],data[3],data[4],data[5],data[6],data[7],data[8],data[9],data[10]);
       }
 }
 }

void fadeRed()  //fade Red in out
{
   
  for (j=0;j<508;j++){
      if (j<256)
      {
      ativaRgb(j,0, 0); 
      delay(200);
      }
       if (j>255){
        ativaRgb(510-j,0, 0);
        delay(200);
      }
       j++;
       checkSerial();
       //execute();
       if (data_received!=4)
   {
       break;
   }
      if(j>506)
       {
         j=1;
       }
   }
}

void fadeGreen()  //fade Blue in out
{
  for (j=0;j<508;j++){
      if (j<256)
      {
      ativaRgb(0,j, 0); 
      delay(200);
      }
       if (j>255){
        ativaRgb(0,510-j, 0);
        delay(200);
      }
       j++;
       checkSerial();
       //execute();
       if (data_received!=5)
   {
       break;
   }
      if(j>506)
       {
         j=1;
       }
   }
}
  
void fadeBlue()  // fade Blue in out
{
 for (j=0;j<508;j++){
      if (j<256)
      {
      ativaRgb(0,0,j); 
      delay(200);
      }
       if (j>255){
        ativaRgb(0,0,510-j);
        delay(200);
      }
       j++;
       checkSerial();
       //execute();
       if (data_received!=6)
   {
       break;
   }
      if(j>506)
       {
         j=1;
       }
   }
}  

void seteCores(int vel)   //sete cores
{
  j=1;
    for(;;) {
    switch (j) { //
        case 1: // Vermelho
        ativaRgb(255,0,0) ;
        break;
        case 2: // Verde
        ativaRgb(0,255,0) ;
        break;
        case 3: // Azul
        ativaRgb(0,0,255) ;
        break;
        case 4: // Amarelo
        ativaRgb(255,255,0);
        break;
        case 5: // Cyano
        ativaRgb(0,255,255) ;
        break;
        case 6: // Magenta
        ativaRgb(255,0,255) ;
        break;
        case 7: // Branco ( todos os leds acessos)
        ativaRgb(255,255,255);
       break;
    }
    delay(vel) ;
    j++;
    if( j > 7) j= 1 ;
    checkSerial();
    //Serial.println(data_received);
    if (data_received!=7 && data_received!=8){
      break;
    }
   }
}

void fadeRGB()  //RGB random
{
  //sendACK(data[0],data[1],data[3],data[4],data[5],data[6],data[7],data[8],data[9],data[10]);
  for (;;) {
       for (float f = 0; f < 1; f += 0.0005) {
    if(data_received!=9)
    {
      break;
    } 
         hsv(f, 1, 1);
    delay(100);
    checkSerial();
       }
     }
 }

void hsv(float H, float S, float V)
{
  if (data_received==9)
  {
  int var_i;
  float R, G, B, var_1, var_2, var_3, var_h;

  if (S == 0) {
    R = V;
    G = V;
    B = V;
  }
  else {
    var_h = H * 6;
    if (var_h == 6) var_h = 0;  // H must be < 1
    var_i = int(var_h) ;          // or ... var_i = floor( var_h )
    var_1 = V * (1 - S );
    var_2 = V * (1 - S * (var_h - var_i));
    var_3 = V * (1 - S * (1 - (var_h - var_i)));
    if (var_i == 0) {
      R = V;
      G = var_3;
      B = var_1;
    }
    else if (var_i == 1) {
      R = var_2;
      G = V;
      B = var_1;
    }
    else if (var_i == 2) {
      R = var_1;
      G = V;
      B = var_3;
    }
    else if (var_i == 3) {
      R = var_1;
      G = var_2;
      B = V;
    }
    else if (var_i == 4) {
      R = var_3;
      G = var_1;
      B = V;
    }
    else {
      R = V;
      G = var_1;
      B = var_2;
    }
  }
   ativaRgb(255 * R, 255 * G, 255 * B);  // RGB results from 0 to 255
}

else
{
  for (int z=0;z<1;z++) {
  break;
  }
}
}

void ativaRgb(int redVal,int greenVal, int blueVal)
{      //RGB Ramdom Fade in out
    analogWrite(redPin, redVal); // Escreve o valor do PWM do led vermelho
    analogWrite(greenPin, greenVal); // Escreve o valor do PWM do led verde
    analogWrite(bluePin, blueVal); // Escreve o valor do PWM do led azul
}

byte receiveMSG(){
  //conforme original
}

void sendMSG(byte address1,byte address2,byte data_type,byte code1,byte code2,byte Sign,byte data1,byte data2,byte data3,byte data4){
  //conforme original
}

void sendNAK(byte address1,byte address2,byte data_type,byte code1,byte code2,byte Sign,byte data1,byte data2,byte data3,byte data4){
  //conforme original
 }
byte hex2num(byte x){
  //conforme original
}

La idea no es utilizarlo como lo haces (bueno, lo he mirado rápido)..... :o :o. (Si no te he entendido bien, me dices....)

Las tramas son de 15 bytes:

  • Byte 1: Byte de start ( 0 hexadecimal ).
  • Byte 2-3: ASCII de la dirección del arduino.
  • Byte 4: Byte ENQ, ACK ó NAK (0x05h, 0x06h y 0x15h) .
  • Byte 5: ASCII del comando petición.
  • Byte 6 y 7: ASCII del número de función.
  • Byte 8: Byte signo (Positivo 0x20h y Negativo 2D)
  • Byte 9-12: ASCII con el dato (0x00h-0xFFFFh)
  • Byte 13: Byte fin de texto (0x03h)
  • Byte 14-15: Checksum (suma de byte 2 al byte13)

El Byte 5, lo usas como Comando, 6 y 7 como numero de función y los Bytes 9-12 son el datos.

Ejemplo:
Establecemos que una D en comando, significa que vas a dar una orden de encendido de un pin Digital.
En los bytes de número de función, establecemos que es el número de pin de Arduino.
Y en los bytes de datos, envias la orden que deseas=> Encendido(1) ó Apagado (0)

D 13 0001 -> Significaría orden control digital, pin 13 a 1.
D 02 0000 -> Orden control digital, pin 2 a 0
P 04 0145 -> Podría ser PWM pin 4, valor 145.
A 01 0000 --> Petición de entrada analogica 1.
...
(a tu elección)

Ejemplo para D 13 0001, enviando a un esclavo cuya dirección es "01"
Las comillas indican caracter en ASCII y sin comillas, número en decimal.
Byte 1 = 0 (Byte Start)
Byte 2 = "0" (El ASCII del cero es 48d)
Byte 3 = "1"
Byte 4 = 5 (ENQ le estas haciendo una peticion)
Byte 5 = "D"
Byte 6 = "1"
Byte 7= "3"
Byte 8= 32 (Signo, no lo utilizamos, pero mandamos positivo)
Byte 9= "0"
Byte 10="0"
Byte 11="0"
Byte 12="1"
Byte 13=3 (End Of Text)
Byte 14 y Byte 15= Checksum

Luego el esclavo, te podría contestar con el mismo mensaje que ha recibido, salvo que el Byte4=6 (ACK). [Ver tabla ASCII para las equivalencias]

Los datos van en ASCII, para hacer más fácil la trama. Si te fijas hay algunos bytes (Start, ACK ó NAK,...) que no son ASCII. Asi es muy sencillo saber lo que estas recibiendo en tu trama (todo lo que sea ASCII son datos y lo otro bytes de control). Puedes ver ejemplos de un Variador industrial (http://www.cdautomation.com/download/ENG_L_M_FUJI_RS485_COMM_for_FRENIC-Mini.PDF).

¿Cómo lo ves? Se puede hacer algo más fácil, si no vas a implementar mucha cosa. La idea de ésto, era hacer una traza "universal". Si quieres, dime exactamente lo que quieres, y puedes empezar haciendote una trama sencilla.... Y luego vas poco a poco "profesionalizando" el tema..... :wink:

Igor R.

Creo que lo has mirado super rápido, hehehe. (es una broma gracias por tu interes y ayuda)

Estoy utilizando el maestro exatamente como dices, ej

if (dipState==1){
sendMSG(48,50,68,48,48,32,48,48,48,49);

o sea si my dip switch esta en la posicion 1 envia "49" (1) al esclavo, el esclavo responde con el ACK y enciende el led, en este caso, rojo. Esto me funciona bien.

He descubiesrto cual era my problema cuando tengo el dip switch selecionado en la posición 4 y nada funciona, echa una ojeada:

for (j=0;j<508;j++){
      if (j<256)
      {
      ativaRgb(j,0, 0); 
      delay(200);
      }
       if (j>255){
        ativaRgb(510-j,0, 0);
        delay(200);
      }
       j++;
       checkSerial();  <<<<aqui esta el problema

el problema es el checkSerial(); cada vez que el programa llega en ese punto, voy a chequear si he recebido algo en el puerto serial y despues vuelvo a ese punto y sigo en loop sin executar la rutina.

Lo que necesito ahora, es eliminar esa linea, punto, pero para salir de la funcion fade creo que voy a tener que utilizar algun tipo de interrupción.

Creo que existe una interrupción que se ativa quando el puerto serial recibe algo. si logro descubrir como hacer eso, mis problemas se han terminado.

Tienes alguna idéa de como puedo "sentir" que algo esta llegando en el puerto serial y interrumpir todo lo que estoy haciendo ?

Bueno.... Como preguntabas si podias ir por debajo de 48 ó por encima de 57.....Y esto no son números, son ASCII de numero.
Y tienes 4 Bytes de datos, por lo que puedes 65535 leds (si mandas en hexa=FFFF).... son suficientes??? ;D ;D

Hay interrupción de puerto serie. En la libreria Serial, la utilizan para poner el dato recibido en el buffer.

No te sirve Serial.Available()????

Perdonar que me cuele,
Pero pasaba por aqui .... y he visto el tema.

En mi proyecto, uno de los temas que he incluido, es muy parecido a lo que quieres hacer

Quizas te sirva

Saludos

Hola Tuto

Toda la ayuda es bienvenida (al menos para mi) ;D
Hablo mas con Igor porque el es el único que me contesta.
Muchas gracias por el link.

Igor, me estou quedando sin pelo y no consigo hacer funcionar esto.

Cuando utilizo el Realterm, todo funciona muy bien, quando utilizo el ATMEGA en mi circuito solamente me funciona lo que seria estático, me explico, encender y apagar un led.

Cuando intento hacer algo mas, por ejemplo el fade a un led, el circuito no me funciona.

Si no te importa, cuando tengas un tiempo, prueba hacer el fade en el led del pin 13 del esclavo y salir del fade cuando quieras (Boton ON fade, boton off todo apagado) despues me cuentas, yo sigo arrancando los pelos por aqui!

Saludos,

ja,ja,ja

Tranqui, que al final saldrá el gazapo...

¿Qué es exactamente lo que quieres hacer? No entiendo muy bien el problema.....

Cristal,

Mírate esto:
http://www.earthshineelectronics.com/files/ASKManualRev3.pdf
Código:
http://www.earthshineelectronics.com/files/EDASKCode.zip

Proyecto 10 (Serial Controlled RGB Lamp). Podrás sacar unas buenas ideas....

:wink:

Igor,

Me han gustado mucho los ejemplos pero infelizmente no solucionan mis problemas. Quando pruebo por la serial utilizando el Realterm todo me funciona.

Te explico lo que quiero:
La parte del Maestro me funciona perfectamente, cuando cambio el dip switch el maestro me envia el codigo correcto. Estoy utilizando tu codigo, apenas he cambiado el pulsador por un dip switch. Creo que la figura 1 es mas o menos como funciona el Maestro.

Quando utilizo algo como en la figura 2, tampoco tengo problemas, o sea, por ejemplo, si envio un "zero", apago mi led, si envio un "uno" enciendo mi led, todo funciona perfectamente.

En la figura 3 es aonde empiezan mis problemas. Quando envio un "dos" deveria entrar en la rutina de fade, y cuando seleciono outra vez un "zero", el led deveria apagarse.

Lo que ocurre es que la rutina de fade es un loop, cierto? entonces tengo que en salir un cierto momento del loop, chequear si me ha llegado algo en la serial, si no me ha llegado nada, devo volver aonde estava en el loop y seguir la secuencia de fade, si me ha llegado algo en la serial, por ejmplo el "zero", salgo del loop definitivamente y apago el led. Me acompañas?

Bueno, esto me funciona cuando pruebo el esclavo DENTRO de Arduino y con el Realterm, quando pongo el "esclavo" en el circuito RS485, la funcion fade no funciona, el LED queda apagado todo el tiempo.

Con el mismo esclavo dentro de mi circuito RS485, cuando envio un "uno" el LED se enciende y cuando envio un "zero" el LED se apaga.

Algo pasa cuando voy a chequear si he recibido algo en la serial de dentro del loop, o la rutina se cuelga en algun punto o estoy siempre empezando la rutina por eso no se enciende nada.

Ahora has compreendido mi problema? :smiley:

Saludos,

Si, entendido.... No te queda otra que ir poniendo puntos de debug en tu programa y sacandolo la informacion por puerto serie para ver que esta pasando..... :o

Si tienes una placa de diecimila, puedes quitarle el microcontrolador (para usar solo el chip FTDI conversor USB-serie) y ponerle un max485 siempre configurado como receptor. Asi puedes monitorizar la info del bus con el Realterm.

Saludos

Igor R.

Infelizmente no tengo otra placa diecimila, mas como estoy utilizando los ATMegas en un circuito proprio, pudeo seguir tu idea.

Tienes idéa si cuando estoy dentro de un loop ejecutando algo, si recibo datos por la serial, los datos son almacenados independientemente de la rutina que este ejetuando? ::slight_smile:

Si eso no ocurre, estoy seguro que ese es mi problema.

Hola a todos,

Finalmente, el circuito completo funciona, el truco fue sacar todos los programas del esclavo y ponerlos en el maestro, en el esclavo sólo los mandos para activar los LEDs. ;D

Gracias a todos y especialmente a Igor por las ayudas.

Saludos,

Me alegro!!!! :wink:

Cuando hagas tu proyecto, publicalo para que pueda servir a otros.... :slight_smile:

Saludos

Igor R.