Chat freely about anything...

User avatar
By frankDownunder
#38078 I want to talk to my Schneider inverter to monitor my PV output, which uses RS485. Ive used RS485 before, and on the Arduino platform the code looks like this the following (See http://www.gammon.com.au/forum/?id=11428 )
- Set enablePin high
- Send some characters
- Wait for empty transmit buffer
- Wait for the transmission to complete
- Set enablePin low

If you leave out the wait steps, the code "turns off" the RS485 chip too quickly, because the last byte is still being sent from the serial hardware port.

Ive been trying to see if there is something similar I need to do on the ESP8266.

I found this code - https://github.com/plieningerweb/esp8266-software-uart
In that code, just before setting the enablePin to low, we wait for an amount of time
os_delay_us(s->bit_time*6);

Waiting this long might work 95% of the time – or perhaps all the time – either way it doesn’t seem to be quite the right thing to do. Is it in fact possible for the chip to be doing some work with wifi during this delay(with a possible consequent timing problem)? Then I read Kolbans excellent book http://neilkolban.com/tech/esp8266 - in the section “Working with Serial”
To find out how many bytes are on the various queues, we have to go pretty low level. For example, the number of bytes on the TX queue is given by:
(READ_PERI_REG(UART_STATUS(uart_no))>>UART_TXFIFO_CNT_S) & UART_TXFIFO_CNT;
So my question is – rather than waiting a “fixed” amount of time, would it be better to have a while loop to wait until the TX queue is empty? If so does that limit us to the hardware UART and in any case I don’t understand the difference between the hardware UART and “software serial”
Obviously I could try it – but again, something that mostly works is not as good as something that implements the “correct” way to do things.

Any thoughts?
User avatar
By pvvx
#38092 Use rx time-out interrupt.

Set UART_RX_TOUT_THRHD, UART_LOOPBACK = 1 and send characters ... wait rx time-out interrupt

Calculation example THRHD:
Code: Select all 
   if(baud > 19200) {
      rs485vars.tout_thrhd = (750*baud + 4000000)/8000000;
      if(rs485vars.tout_thrhd > 125) rs485vars.tout_thrhd = 125;
      rs485vars.waitust = 1750 - (rs485vars.tout_thrhd*8000000)/baud;
      rs485vars.tout_thrhd += 2;
   }
   else {
      rs485vars.tout_thrhd = 4; // 24..32 bits
      rs485vars.waitust = ((39-((4-1)*8))*1000000)/baud; // in us // 12000000/baud
   }

    UART0_CONF1_TOUT(rs485vars.tout_thrhd); // UART_RX_TOUT_THRHD = rs485vars.tout_thrhd