Montei um circuito de testes (anexo) com ESP8266 12E e um chip SN75176 para comunicação RS485. Liguei duas placas dessas via RS485. Em meus testes observei dois problemas:

1) Quando conecto as duas placas diretamente via RX/TX dos ESPs das duas placas, tudo funciona OK. Quando faço a comunicação passar pelo chip SN75176 para RS485 ocorre um atraso no envio dos dados, de forma que as informações só são transmitidas por inteiro se for acrescentado um delay de 1ms conforme mostrado no código de teste (abaixo).

2) O pino RX do ESP8266 está sempre em nível ALTO quando não está ocorrendo comunicação (já testei com várias placas NodeMCU ESP8266 12E). Este nível lógico interrompe a operação do SN75176, então adicionei o diodo D6 como mostrado no diagrama anexo (funcionou). Porém já usei esse chip SN75176 com Atmega e PIC em lugar do ESP8266 e nunca tive esse problema.

 

Alguém sabe o que pode estar gerando o problema “1” ou o “2”?

//------------------------------------------------------------------

#define PIN_RS485    15
#define BUILTIN_LED  2

void setup() {
  pinMode(PIN_RS485, OUTPUT);
  pinMode(BUILTIN_LED, OUTPUT);
  
  Serial.begin(115200);
  
  digitalWrite(PIN_RS485, LOW);
}

void loop() {
   digitalWrite(PIN_RS485, HIGH);
   Serial.printf("0123456789");
   delay(1);
   digitalWrite(PIN_RS485, LOW);
   
   delay(50);
   digitalWrite(BUILTIN_LED, !digitalRead(BUILTIN_LED));
}

//------------------------------------------------------------------

Exibições: 2664

Responder esta

Respostas a este tópico

Opa.

   digitalWrite(PIN_RS485, HIGH);
   Serial.printf("0123456789");
   delay(1);
   digitalWrite(PIN_RS485, LOW);

   

 O pino deve estar subindo antes de terminar o envio do frame, não sei como funciona essa library que você usa mas deve ser isso. Teria que arrumar algum artificio para que o esp aguarde o envio total do frame para depois subir o pino. 

Sds.

Sim, é isso mesmo. Mas preciso eliminar o problema e ainda não sei como. Valeu!

Opa. Isso não é um problema em si, e sim uma condição de operação da library que você usa. Nos meus projetos  uso o timer para desabilitar esse pino, assim que mando enviar o ultimo byte, carrego o hwtimer  com tempo de overflow associado ao tempo de transmissão. Posso alterar o baud de 2400 a 115200 que são valores usuais e funciona sempre perfeitamente. 

Sds.

Jucelei Freitas acho que já matou a questão.

O Arduino em sua biblioteca tem um buffer. Quando vc manda escrever na serial para otimizar ele escreve em memória e vai repassando pra serial no tempo, conforme o termino da transmissão de cada caracter. Usa a interrupção da serial pra isso.

Um jeito porco de resolver seria medir o tempo e aumentar o delay.

Um jeito correto de resolver seria aguardar um silencio, já que vc ouve tudo que transmite (confirma?)

Outro jeito polido meio termo seria definir o buffer da serial para 1 byte com um

#define SERIAL_BUFFER_SIZE 1

ou

#define SERIAL_TX_BUFFER_SIZE 1

Nunca testei, sempre o povo quer aumentar isso, nunca diminuir.

ref:

https://github.com/arduino/Arduino/issues/1929

Eduardo, no fim das contas, assim como o delay que inseri, as outras soluções também acabam sendo paliativas para um problema que não deveria existir. Mas obrigado!

Bom dia WB,

como todos sabem e vários concordam, não gosto de ajudar qdo o amigo posta o sketch na

área de texto do post.

Mas as vezes qdo o sketch é pequeno, abro exceções. E este seu caso abrirei.

Serial.flush()  - - >  Waits for the transmission of outgoing serial data to complete. 

 https://www.arduino.cc/en/Serial/Flush

Se você usar a função  " Serial.flush();  "  após a instrução "   Serial.printf("0123456789");  "  o processo 

irá  aguardar o fim da transmissão para continuar o fluxo do programa.

Daí pode remover o delay(1).

RV

Obrigado pela informação mineirin RV. Já tinha testado isso anteriormente e imaginei que teria esse comportamento que você descreveu, mas por alguma razão não funcionou. Grato novamente.

Só um detalhe a mais que observei agora em meu código, mas eu acredito que não deva fazer diferença: Em lugar de escrever na serial com "Serial.printf" eu estou escrevendo com "Serial.write". Não deveria influenciar, correto?

Meu código exato está assim:

Serial.write((const uint8_t *)MBBufferArray, (unsigned int)MB_msg_length);

As variáveis são:

unsigned char MBBufferArray[100];

int MB_msg_length;

WB,

faça um teste com Serial.print ao invés de Serial.write ou Serial.printf.

E depois conta pra gente.

RV

Não posso usar "Serial.print" em meu projeto real, pois trabalho com um buffer de bytes (não baseado em string). Além disso, o "print" não permite informar a quantidade de bytes do buffer que preciso enviar pela serial. Então ainda que funcionasse para strings (não testei), não funcionaria para mim pelo outro motivo que citei. Obrigado novamente.

Bom dia , 

Minha especialidade é com HW.

E tenho uma recomendação para o seu circuito. 

Onde montou o resistor terminator da interface RS-485 ( entre os pinos A e B)  ? Qual valor esta usando ?

https://www.embarcados.com.br/redes-de-comunicacao-em-rs-485/

"De acordo com o padrão RS-485 o início e o fim do barramento devem ser ligados com terminadores de rede, que são resistores de 120Ω ligados entre as duas linhas do barramento."

Minha interface montada e testada OK. O chip é outro, mas é similar. 

Murta, realmente não tem esses resistores em meu circuito. Vou adicionar, fazer os testes e ver o que acontece. Se funcionar eu posto aqui. Obrigado.

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço