Serial1.available() seems to fail when first byte is NULL

Status
Not open for further replies.

gripner

Well-known member
Talking to a serial device,

The device respond to me with 9 bytes
First byte is NULL then 7 randon bytes and then last byte is NULL

The problem I have is that even tho the 9 bytes are sent all together (at 9600baud) with just a few ms total transmision time Serial1.available() always reports 1 never 9!
Im starting to think perhaps its the NULL that terminates.
So i have tried with a flush and a read() to get rid of the first byte but the rest of the 8 never gets "seen"

I know 9 bytes comes, i can see them on my serial sniffer.

Here is part of my code, that run directly after i query my serial decive and it sends its responce
byte temp = Serial1.read();
//Serial1.flush();
Serial.print("0 milli");
Serial.println(Serial1.available());
delay(20);
Serial.print("20 milli");
Serial.println(Serial1.available());
delay(50);
Serial.print("50 milli");
Serial.println(Serial1.available());
delay(100);
Serial.print("100 milli");
Serial.println(Serial1.available());
delay(200);
Serial.print("200 milli");
Serial.println(Serial1.available());
delay(300);
Serial.print("300 milli");
Serial.println(Serial1.available());
delay(400);
Serial.print("400 milli");
Serial.println(Serial1.available());
delay(500);
Serial.print("500 milli");
Serial.println(Serial1.available());

my output from Serial.println(Serial1.available()); is 0 on all prints, If i remove the Serial1.read i will get 1 on all Serial.println(Serial1.available());
 
I change the baudrate from 9600 to 115200 on both teensy and the serial device.
Now it random give me 1 or 7 bytes Serial1.available().

Seems to be "available" at around 200ms

again, on my serial logger i can see all 9 bytes beeing transmitted.
 
Are you sure the stop bits and parity are the same?
Could you post a snapshot of your serial sniffer output?

I often send 0x00 and have no issue with this. Assuming 0x00 is what you mean by NULL

What happens if you use the following?
Code:
loop() {
  if (Serial1.available()) {
    Serial.write(Serial1.read());
  }
}
 
Last edited:
Cant use it like that since i need to send data to the serial device before it returns anything.

yes null = 0x00

the sniffer is just another rs232 to usb connected to my pc running realterm
Shows what should be returned correctly byte 1 0x00 7bytes with different data 0x00 (last byte)

part of code
digitalWrite(SSerialTxControl, RS485Transmit); // Enable RS485 Transmit
byte message2[] = {0x02, 0x03, 0x02, 0x08, 0x00, 0x01, 0x04, 0x43};
Serial1.write(message2, sizeof(message2));
(my serial device make noice indicating ok)
(my sniffer see byte 1 0x00 7bytes with different data 0x00 (last byte))
delay(10); // delay so togling rs458 recive do not cut of transmission
digitalWrite(SSerialTxControl, RS485Receive); // Disable RS485 Transmit
delay(20); // delay to ensure all data from serial device have been sent trid up to 300ms no difference.
int i = 0;
Serial.print("Serial1.available()=");
Serial.println(Serial1.available()); // responds with 1,2,6 or 8 (8 should be responded always) again my serial sniffer show me ALL 9bytes
while (Serial1.available()) {
// get the new byte:
//char inChar = (char)Serial1.read();
//Serial.println(inChar);
//senixX += inChar;
//Serial.println(i);
data = Serial1.read();
i++;
}
 
Please post the complete code.
Or, if it is too long, create a stripped-down sketch that shows the behavior.

What you can try: disconnect all hardware from the teensy, and connect tx to rx. you should receive all sent bytes.
Do you have a Serial1.begin(9600) in setup() ?
 
Try this sketch (after connecting TX to RX):

Code:
//CONNECT RX1 TO TX1 !!!

void setup() {
 Serial1.begin(9600);
}

void loop() {
 Serial1.print('\0');
 if (Serial1.available()){
  Serial.println(Serial1.available());
  //Serial.print((char) Serial1.read());  
  if (Serial1.available() > 30) while(1){;}
 }
 delay(1000);
}

What happens ?
It sends 0 only.. and works for me.
 
The code is already posted. The part handling the serial in out.

Serial1.begin is in the setup. If not the code would not compile .
 
??? of course the code compiles without that.
A part of your code does not help us to find your bug. But ok..
 
Code:
//CONNECT RX1 TO TX1 !!!

void setup() {
 Serial1.begin(9600);
}

void loop() {
 Serial1.print('\0');
 if (Serial1.available()){
  Serial.println(Serial1.available());
  //Serial.print((char) Serial1.read());  
  if (Serial1.available() > 30) while(1){;}
 }
 delay(1000);
}

Produce

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 
Code:
#define SSerialTxControl 12   //RS485 Direction control
#define RS485Transmit    HIGH
#define RS485Receive     LOW

#define Pin13LED         13

String senixX = "";


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial1.begin(115200);

  Serial.println("BOOTING!");

  pinMode(Pin13LED, OUTPUT);   
  pinMode(SSerialTxControl, OUTPUT);

  Serial1.transmitterEnable(12);

  //digitalWrite(SSerialTxControl, RS485Receive);
  delay(10);
}

void loop() {
  // put your main code here, to run repeatedly:

  Serial.println("LOOP START");

  qSenix();
  Serial.println(senixX);
  delay(3000);

}

void qSenix() {
  senixX = "";
  byte data[] {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
  unsigned long maxserialdly=300;  // the time we need to wait
  unsigned long previousMillis=millis(); // millis() returns an unsigned long.
  //Serial1.flush();
  //digitalWrite(SSerialTxControl, RS485Transmit);  // Enable RS485 Transmit
  //  Serial1.flush();
  //byte message1[] = {0x01, 0x03, 0x02, 0x08, 0x00, 0x01, 0x04, 0x70};
  //Serial1.write(message1, sizeof(message1));
  //byte message3[] = {0x03, 0x03, 0x02, 0x08, 0x00, 0x01, 0x05, 0x92};
  byte message2[] = {0x02, 0x03, 0x02, 0x08, 0x00, 0x01, 0x04, 0x43};
  //Serial1.flush();
  Serial1.write(message2, sizeof(message2));
  //Serial1.flush();
  //delayMicroseconds(1000);
  //delay(10);
  
  //digitalWrite(SSerialTxControl, RS485Receive);  // Disable RS485 Transmit
  //byte temp = Serial1.read();
  //delay(20);
 
  //while(!Serial1.available() && (unsigned long)(millis() - previousMillis) < maxserialdly) ;
  //while(!Serial1.available() && (unsigned long)(millis() - previousMillis) < maxserialdly) ;
    int i = 0;
    Serial.print("Serial1.available()=");
    Serial.println(Serial1.available());
    while (Serial1.available()) {
      // get the new byte:
      //char inChar = (char)Serial1.read();
      //Serial.println(inChar);
      //senixX += inChar;
      //Serial.println(i);
      data[i] = Serial1.read();
      i++;
    }

  Serial.println("-");
  Serial.println(data[0], BYTE);
  Serial.println(data[1], BYTE);
  Serial.println(data[2], BYTE);
  Serial.println(data[3], BYTE);
  Serial.println(data[4], BYTE);
  Serial.println(data[5], BYTE);
  Serial.println(data[6], BYTE);
  Serial.println(data[7], BYTE);
  Serial.println("-");
 
  /*
  byte message2[] = {0x02, 0x03, 0x02, 0x08, 0x00, 0x01, 0x04, 0x43};
  Serial1.write(message2, sizeof(message2));
  delay(10);
  
  byte message3[] = {0x03, 0x03, 0x02, 0x08, 0x00, 0x01, 0x05, 0x92};
  Serial1.write(message3, sizeof(message3));
  */  
 

}

the entire code, i have comented out alot of testing stuff
Serial.println(Serial1.available()); sometimes say 1, 2 ,6 or 8 random
If i look at my teraterm connected via a rs232 usb i get 0x00 7bytes 0x00 the 7 bytes are data so changes.

Feels like it cant be the RS232 to 485 converter. If that one would not work the serial device i use would not trigger since it requires exact correct data + crc. i can also see the return witch is correct on the teraterm sniffer setup
 
its 115200

I have tried with BOTH 9600 and 115200

With 9600 100% of the time i get Serial1.avail.... = 1
I set the Senix serial device to 9600 or 115200 depending on what i tried in the Teensy.
 
Ok. should re-enable the delay after sending, otherwise it can't work. Try a long delay, to be sure.
Is that "Senix" (link?) 5V or 3V ?

I think you can make the same as above with your sketch: disconnect the "Senix" and connect TX to RX on the Teensy.

edit:
oops, ok, you're using RS485. Is that RS485 3 or 5V ?
 
Last edited:
connecting RX and TX together works great, i get what I send back.

I tried to instead of RX and TX connected together i connected the rs485 lines together.
Does not work, but perhaps thats since the max485 have nno buffer and need some receiving unit to hold the data while togling enable disable send and recieve
 
im totaly out of ideas

I can on my trealterm see the teensy sending correct value on its serial port
I can see the MAX485 doing its work since the senix sensor connected to the MAX485 recieves the command and do its thing.
I can see the MAX485 converts back to rs232 since the realterm serial is connected to the rs232 side of the MAX485, the data is there
WHY WHY WHY cant the teensy see it correct.
 
the power supplied to the rs485 converter is 5V
But the RS485 uses balanced data lines, a few hundred mV if im not mistaken, not 3 or 5 V
 
? NO, your own tests (tx-rx) showed that everything is ok with the software. Its hardware-related. maybe you need a level-converter on the teensy-tx line.
 
The TX line ? but the data sent from the teensy is proven it is correctly sent AND converted by the MAX485 and recieved by the senix sensor. so the TX line works just fine.
The RX does not, the data from the senix to the MAX485 is sent correctly and converted correctly and exist correctly on the RS232 side, this i have also verified.
level converter should not be needed. the MAX485 RS232 side is 5V and the teensy 3.1/3.2 is 5V tolerant ?
 
Yes, but is the MAX 3V input tolerant ? :) Does it accept 3 V as "high" ? I did'nt look at the datasheet...
 
Status
Not open for further replies.
Back
Top