-1
\$\begingroup\$

I am currently working on a RS485 communication, I use a PIC16F18855 and a THDV1505. I communicate with my computer using a USB/RS485 converter.

The PIC receives the data well, but I have a problem sending the data. The data I receive are chaotic, for the moment I just try to send 0 / 1 / 2 / 3 /.... / 8, and what I get is :

reception data

Here is the schematic of the RS485 part, [edit] resistors R8 and R9 of 100R are not mounted :

Schematic

Here you will find the code, the interrupt that manages the communication:

   if(PIR3bits.RCIF){
    t_rx[etape_it_uart] = RC1REG;
    etape_it_uart++;
    
    if(etape_it_uart > SIZE_RX_TRAME){
        etape_it_uart = 0;
        rx_trame_ok = true;
    }
    
    if(RC1STAbits.OERR)
    {
        RC1STAbits.CREN = 0;
        RC1STAbits.CREN = 1; 
    }
} 

if(PIR3bits.TXIF){
    EN485_SetHigh();
    if (nb_octet_tx < SIZE_TX_TRAME) {
        TX1REG = t_tx[nb_octet_tx];
        nb_octet_tx++;           
    } else {
        tx_trame_ok = 1;
        TX1STAbits.TXEN = 0;
        EN485_SetLow();
    }    
}

Here you will find the part of the code that starts the transmission :

    case 21 :
        t_tx[0] = 0x00;
        t_tx[1] = 0x01;
        t_tx[2] = 0x02;
        t_tx[3] = 0x03;
        t_tx[4] = 0x04;
        t_tx[5] = 0x05;
        t_tx[6] = 0x06;
        t_tx[7] = 0x07;
        t_tx[8] = 0x08;
        
        etat_uart = 30;
        break;
    case 30:
        nb_octet_tx = 0;
        tx_trame_ok = 0;                  
        etat_uart = 40;
        TX1STAbits.TXEN = 1;
        break;
    case 40:
        if (tx_trame_ok) {
            etat_uart = 0;
            etape_it_uart = 0;
            TX1STAbits.TXEN = 0;
        }
        break;

Hoping to come across someone who will help me solve this problem!

Thank you all and have a nice day.

[EDIT] Here are the signals I read on the oscilloscope :

Signal in Signal in

And for more explanation on wiring with the termination resistor:

Wiring

[EDIT 2] The 2 pictures of the signals above correspond to the USB/RS485 => PCB signals, error on my part on the signal plug. The frame sent is 0x05 / 0x10 / 0x06 / 0x16 / 0x04.

Below are the PCB => RS485/USB signals. The frame sent is 0x00 / 0x01 / 0x02 ..... 0x07 / 0x08.

Signal out Signal out

And here is the EN signal, only 8ms in high state :

Signal EN

\$\endgroup\$
2
  • \$\begingroup\$ @All - The long debugging chain has exceeded what is reasonable for comments. Therefore it has been moved to chat and should be continued there (see the link in the comment below). || As this bulk moving of comments to chat can only be done once per question, any further comments posted here might be deleted without notice. Keep it in chat now, please! || When someone has got enough information from the chat to post an answer, please answer it as usual. Any updates to the question which are decided during the chat, should be made via an edit to the question, not as a comment. Thanks. \$\endgroup\$
    – SamGibson
    Feb 3 at 17:00
  • \$\begingroup\$ Comments have been moved to chat; please do not continue the discussion here in comments. \$\endgroup\$
    – SamGibson
    Feb 3 at 17:01

1 Answer 1

1
\$\begingroup\$

The problem is assuming when it is OK to turn off the transmitter.

In general, UARTs may have separate transmit shift register, which contains the bits of the byte being currently shifted out, and transmit holding register, which can be written to contain the next byte which will be transferred to the shift register when it finishes transmitting the frame.

So in short, you can think of it as small FIFO.

What happens is that the last thing you see is the byte 0x07 transmitted on the wire, but immediately when it is transmitted out, and the 0x08 byte is transferred from the hold register to shift register, the UART signals an interrupt that the hold register is now free and you can write 9th byte if you want. But that is when you turn off the transmitter enable, and the 0x08 is still being transferred out from UART TXD but it never is transmitted by the RS-485 PHY.

Other than that, your code seems to enable transmitter and transfer out data even if there is still other communications on the bus, hence the start of MCU data packet transmission has a collision as both devices enable and transmit. Bytes 0x02 to 0x07 seem to be transmitted out just fine.

You need to fix the MCU packet transmission so that the transmitter is disabled after 0x08 has been shifted out. Sometimes UARTs have separate bits for this, one for when you can write next byte to FIFO and another one which says byte transmission is complete.

Second thing is, you need to check if there is ongoing reception or not, to see if the bus is free for transmission. It might be worth to specify a turnaround time, how long min/max after receiving last byte you can start responding to PC. If you have nothing to transmit, it means the PC also has a min/max time it waits for reaponse, and it is free to send next packet.

At the byte/bit level, the RS-485 transmitter enable needs to be enabled with some min/max time before transmitting the first byte. It is unlikely that enabling it and immediately writing the byte to be transferred will work in all cases.

Same thing with the last byte, you need to wait some min/max time after last byte has been completely transferred out before turning off the RS-485 transmitter enable.

\$\endgroup\$
3
  • \$\begingroup\$ Hello @Justme First of all, thank you for your comment. I have followed your advice to timer well before activating the enable to send the data by setting 15ms. Same thing for the deactivation of the enable, 15ms, but the data sent are still incorrect ... \$\endgroup\$
    – Benito
    Feb 6 at 10:02
  • \$\begingroup\$ @Benito The data sent was correct to begin with, with the exceptions of showing a corrupted start because multiple devices were transmitting simultaneously, and the final byte was missing. It can't be completely incorrect. If it is, show a scope capture, and explain why you think there is a problem? Have you got A/B swapped? Have you got correct baud rate on all devices? What baud rate it is? Have you verified baud rate is set correctly and is within tolerance for all devices? Any other parameters correct or incorrect, 8-N-1 or something else? \$\endgroup\$
    – Justme
    Feb 6 at 10:06
  • 1
    \$\begingroup\$ I just found where the problem came from by following your questions, indeed the parity of the serial port on the computer software side was misconfigured. I was in Parity even instead of none ... However, I kept your solutions in the PCB program which guarantees a better functioning, and I thank you for all these advices and the time you took ! Really thanks to all of you. \$\endgroup\$
    – Benito
    Feb 6 at 11:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.