Differences in Hardvareserial between T3.5 and T4.1

gonzales

Well-known member
Hi!
I trying to migrate with my project from 3.5 to 4.1. I have RS485 transmitter, that is connected to Serial5 on T3.5 and to Serial8 on T4.1. So afrer tranfer a message i read answer from line. With T3.5 it works fine, but with T4.1 i have some problem. The problem is, that after i transfered a message and read the answer in input buffer i read my transfered message and only after reading i see the answer. I dont understand how it happens.

This is part of my code to transfer message
Code:
digitalWrite(DIR, HIGH); // begin transfer
    delay(2);
    buff[0] = byte(RS485_START_BYTE);
    buff[1] = Message_to_send.reciver_id;
    buff[2] = Message_to_send.reciver_adress;
    buff[3] = Message_to_send.sender_id;
    buff[4] = Message_to_send.sender_adress;
    buff[5] = Message_to_send.Command;
    buff[6] = Message_to_send.data1;
    buff[7] = Message_to_send.data2;
    buff[8] = Message_to_send.data3;
    buff[9] = Message_to_send.data4;
    buff[10] = Message_to_send.data5;
    buff[11] = Message_to_send.data6;
    buff[12] = Message_to_send.data7;
    buff[13] = Message_to_send.data8;
    buff[14] = Message_to_send.data9;
    buff[15] = Message_to_send.data10;
    buff[16] = Message_to_send.sign;
    buff[17] = byte(RS485_STOP_BYTE);
    RS485->write(buff, RS485_BUFF_SIZE);
    RS485->flush();
    digitalWrite(DIR, LOW); // end transfer
    delay(2);

I repeat that with T3.5. it work fine.
 
Sorry I am not sure, exactly what is going on. So far you show code that you are rolling your own RS485 support, which should be fine.
But don't see any of the information, like your setup code, or what pins are used for DIR and if it was configured properly...

Side note: You should also be able to have some of this semi-automatic using the transmitterEnable method on SerialX objects.

Like: Serial8.transmitterEnable(DIR);

This should automatically set your direction pin whenever you output data to the Serial object, and it will detect when the Queue goes empty and the last bits of data are
sent out, it will then automatically switch the DIR pin back to input.

But again I don't see your read code. SO for example if you do your
code above and then right after that try to do a Serial.read(), it may not see anything yet.

And sorry I don't understand:
The problem is, that after i transfered a message and read the answer in input buffer i read my transfered message and only after reading i see the answer. I dont understand how it happens.
 
Sorry, ok, i try to explain. This is my configuration
Code:
#define RS1_PIN 30 

void setup() {
#if TEENSYTYPE == 35
    RS485 = &Serial5;
#elif TEENSYTYPE == 41
    RS485 = &Serial8;
#endif
DIR = RS1_PIN;
}

void TransmitMessage(){
    digitalWrite(DIR, HIGH); // begin transfer
    delay(2);
    buff[0] = byte(RS485_START_BYTE);
    buff[1] = Message_to_send.reciver_id;
    buff[2] = Message_to_send.reciver_adress;
    buff[3] = Message_to_send.sender_id;
    buff[4] = Message_to_send.sender_adress;
    buff[5] = Message_to_send.Command;
    buff[6] = Message_to_send.data1;
    buff[7] = Message_to_send.data2;
    buff[8] = Message_to_send.data3;
    buff[9] = Message_to_send.data4;
    buff[10] = Message_to_send.data5;
    buff[11] = Message_to_send.data6;
    buff[12] = Message_to_send.data7;
    buff[13] = Message_to_send.data8;
    buff[14] = Message_to_send.data9;
    buff[15] = Message_to_send.data10;
    buff[16] = Message_to_send.sign;
    buff[17] = byte(RS485_STOP_BYTE);
    RS485->write(buff, RS485_BUFF_SIZE);
    RS485->flush();
    digitalWrite(DIR, LOW); // end transfer
    delay(2);
}

void CheckRS485(){
  byte serialbufflength = RS485->available();
  if (serialbufflength >= RS485_BUFF_SIZE) {
    for (i = 0; i < serialbufflength; i++) {
      if (RS485->read() == RS485_START_BYTE) {
        start_byte_flag = true;
        break;
      }
    }
    if (start_byte_flag == true) {
      RS485->readBytes(buff, RS485_BUFF_SIZE - 2);
      
      byte b = RS485->read();
      if (b == RS485_STOP_BYTE) {
        stop_byte_flag = true;
      }
    }

    if (start_byte_flag == true && stop_byte_flag == true)
    {
      Message.reciver_id = buff[0];
      Message.reciver_adress = buff[1];
      Message.sender_id = buff[2];
      Message.sender_adress = buff[3];
      Message.Command = buff[4];
      Message.data1 = buff[5];
      Message.data2 = buff[6];
      Message.data3 = buff[7];
      Message.data4 = buff[8];
      Message.data5 = buff[9];
      Message.data6 = buff[10];
      Message.data7 = buff[11];
      Message.data8 = buff[12];
      Message.data9 = buff[13];
      Message.data10 = buff[14];
      Message.sign = buff[15];
  }
}

I dont use transmitterEnable and other automatic options, when i need to transmit a message i do digitalWrite(DIR, HIGH);

In degub mode i can see in monitor differences between T3.5 and T.4.1
Teensy 3.5

Send Command to (2,1) 1
RS485-2-1-1-1-1-0-0-0-0-0-0-0-0-0-0-6
MESSAGE TRANFERRED
start_byte_flag
stop_byte_flag
RS485-1-1-2-1-2-255-255-255-255-255-255-4-255-255-255-2

Teensy 4.1

Send Command to (2,1) 1
RS485-2-1-1-1-1-0-0-0-0-0-0-0-0-0-0-6
MESSAGE TRANFERRED
start_byte_flag
stop_byte_flag
RS485-2-1-1-1-1-0-0-0-0-0-0-0-0-0-0-6
start_byte_flag
stop_byte_flag
RS485-1-1-2-1-2-255-255-255-255-255-255-4-255-255-255-2

I found one solution, after RS485->flush(); to do RS485->clear(); and it work, but i think it is not normal.
 
Maybe check your wiring? This sounds like a half duplex, full duplex issue. It would seem that in your T3.5 setup, your DIR pin prevents your transmitted signal from appearing on the serial RX pin but on the T4.1 setup it does not - hence you receive your transmitted signal.
 
Back
Top