Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 11 of 11

Thread: Teensy 4.0 Serial.available() stops incrementing

  1. #1
    Junior Member
    Join Date
    Sep 2016
    Posts
    13

    Teensy 4.0 Serial.available() stops incrementing

    OK, I really hope I'm doing something dumb, but I'm having all sorts of trouble with some of the serial functions under Teensy 4.

    The issue I'm seeing is that the Serial.available() stops updating after the first call to it, unless there is a read performed. Here's an example sketch:
    Code:
    void setup() {
      // initialize serial communication at 9600 bits per second:
      Serial.begin(9600);
    }
    
    // the loop routine runs over and over again forever:
    void loop() {
      Serial.println(Serial.available());
      if(Serial.available() > 10)
      {
        while(Serial.available())
        {
          Serial.read();
        }
      }
      delay(1000);        // delay in between reads for stability
    }
    Basically the sketch should print out the number of bytes on the serial RX buffer. If the number on the buffer is greater than 10, it'll read all the values back out from the buffer.

    However, if I run that sketch I start seeing 0 on the monitor as expected. If I send a byte of data, the value goes up to 1, again as you'd expect. But if I send another byte, it still stays as 1. Send another byte and its still 1 etc.

    If I reset the board and this time instead send say 5 bytes the first time, it'll start showing 5, but just as before if I send more bytes, it still shows as 5.

    If I send 11 bytes initially, then it'll print 11, then back to 0, which is correct.

    Am I missing something obvious about how the Serial.available() function works or should it keep going up with each new byte received (Even if there isn't a Serial.read() call)?

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,378
    Seeing the same behavior on a T4 here.

    I have seen signs of this error before in Beta but never pinned it down while prompting for user input - TyComm would indicate COMM errors as shown below. @mjs513 and/or @KurtE once noted this IIRC during Beta.

    Modified the sketch to read ONE char after 10 secs when the .available() > 1 and even reading one char doesn't update the count to include new characters passed in - then repeats after another 2 seconds.
    >> send 9 chars '12345678\n'
    >> Send more chars and they are not included in the count

    Restarted IDE and new FirstTrySerMon update and same result - only no errors in the IDE console.

    Added cnt2nd - that will flush with Serial.read() after repeated waits - it is not getting buffered chars on TyComm because of the write error - but teensy_sermon does pull those added chars when cnt2nd triggers.

    And if I keep passing in characters I get a red flag Error in TyCommander:
    Code:
    [send@6052840-Teensy] I/O error while writing to '\\.\COM33'
    [send@6052840-Teensy] Timed out while writing to '\\.\COM33'
    [send@6052840-Teensy] Timed out while writing to '\\.\COM33'
    Board '6052840-Teensy' is busy on task 'send@6052840-Teensy'
    Board '6052840-Teensy' is busy on task 'send@6052840-Teensy'
    [send@6052840-Teensy] Timed out while writing to '\\.\COM33'
    Here is the updated sketch to demonstrate:
    Code:
    void setup() {
    	// put your setup code here, to run once:
    	Serial.begin(115200);
    	while (!Serial && millis() < 4000 );
    	Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
    }
    
    uint32_t cnt = 0;
    uint32_t cnt2nd = 0;
    void loop() {
    	Serial.println(Serial.available());
    	cnt++;
    	if (Serial.available() > 10)
    	{
    		cnt = 0;
    		while (Serial.available())
    		{
    			Serial.read();
    		}
    	}
    
    	if (Serial.available() >= 1 && cnt > 10) {
    		if (Serial.available() > 1 ) {
    			Serial.read();
    			cnt = 8;
    		}
    		cnt2nd++;
    		if ( cnt2nd > 5 ) {
    			cnt2nd = 0;
    			while (Serial.available())
    			{
    				Serial.read();
    			}
    
    		}
    	}
    	delay(1000);        // delay in between reads for stability
    }
    *yes, a 'spec' bug - it should not cnt++ when no chars yet .available() - but it just reads too soon and shows the problem with less wait.
    Last edited by defragster; 08-22-2019 at 09:19 AM.

  3. #3
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,296
    In all these T4 serial-usb discussion, one should note that in addition to Paul's Sermon speed work, the USB implementation is 'completely' different and most likely not complete in a T4 compared to T3.
    [Rant] honestly, Paul should not waste his time speeding up Sermon, but concentrate on T4 USB implementation (e.g. other device than Serial). I never had problems to slow down Serial such that I can read the text[\Rant]

  4. #4
    Senior Member
    Join Date
    Apr 2019
    Posts
    118
    Set the serial.timeout(0)

    Let me know if it helps

  5. #5
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,378
    SerMon speedup is handy - crashing the IDE and losing work is ugly - T4 too easy to overload or overwork a PC. I use TyCommander - it doesn't fail but only runs half as fast and uses double the CPU % which makes doing other things fitful.

    Also much of the coming USB work will make it faster and being able to test it and have it run at speed is where troubles may show up.

    @Gadget999 - not sure that applies? If the chars are READ there is no trouble - but when waiting for a given count of chars to arrive and reading is delayed - the problem here is the count of chars will never change with incoming characters.

  6. #6
    Junior Member
    Join Date
    Sep 2016
    Posts
    13
    Quote Originally Posted by Gadget999 View Post
    Set the serial.timeout(0)

    Let me know if it helps
    Assuming this should've been serial.setTimeout(0), it made no difference.

  7. #7
    Junior Member
    Join Date
    Sep 2016
    Posts
    13
    A little more playing and I can see that there's definitely an issue here with subsequent serial data being sent. It's not just that Serial.available() isn't being updated, it's that the subsequent data isn't being added to the rx buffer at all.

    Within usb_serial.c when the first set of bytes is sent I can see the rx_event() function being called as you'd expect. This function updates the rx_count[index] and rx_index[index] values to store the current place in the buffer. However, no matter how much data is sent, that rx_event() function is not called again until all the data has been read() out of the buffer from the first data that was sent.

    I've been playing around to see why that function isn't being called for subsequent bytes, but haven't had much luck yet.

  8. #8
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,378
    Quote Originally Posted by noisymime View Post
    A little more playing and I can see that there's definitely an issue here with subsequent serial data being sent. It's not just that Serial.available() isn't being updated, it's that the subsequent data isn't being added to the rx buffer at all.

    Within usb_serial.c when the first set of bytes is sent I can see the rx_event() function being called as you'd expect. This function updates the rx_count[index] and rx_index[index] values to store the current place in the buffer. However, no matter how much data is sent, that rx_event() function is not called again until all the data has been read() out of the buffer from the first data that was sent.

    I've been playing around to see why that function isn't being called for subsequent bytes, but haven't had much luck yet.
    Indeed some issue here for @PaulStoffregen. I see he has visited this thread - hopefully it is on his list.

    It was ODD that teensy_sermon did seem to get characters pushed in after the buffered characters and as noted TyComm detected and returned write errors. The t_sermon must be holding the buffer to send when the USB resumes normal cycling after the buffer gets emptied in T4. Those two serial monitors must be using the USB state/control feedback differently - perhaps TyComm throws Error when t_sermon goes to retry/wait? Either way incoming data seems to be blocked/ignored on the T4 side.

  9. #9
    Junior Member
    Join Date
    Sep 2016
    Posts
    13
    After more playing, I've managed to confirm a few more things around this, but not exactly where the main problem is coming from. As best as I can tell, the serial RX interrupt is being disabled after the initial data is received and only gets turned back on after the data has been read back out, which would explain the issue.

    Just for clarity, this is not related at all to the serial monitor issues at all, it happens with the stock Arduino IDE monitor as well as 3rd party ones. I'm actually trying to interface with a totally separate application that has a serial interface and works fine with AVR and Teensy 3.5/3.6 boards, but is dependant on multiple data bursts being sent before a read() is called, so its obviously failing with the current T4 usb serial.

    I'll dig out a 3v3 serial board over the weekend and try one of the native UARTs to see whether they have the same issue or not.

  10. #10
    Junior Member
    Join Date
    Sep 2016
    Posts
    13
    Just to confirm back, using a 3v3 USB serial adapter and Serial1 on the Teensy 4.0, everything works perfectly, so this problem is definitely within the USB serial implementation.

  11. #11
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,378
    Quote Originally Posted by noisymime View Post
    Just to confirm back, using a 3v3 USB serial adapter and Serial1 on the Teensy 4.0, everything works perfectly, so this problem is definitely within the USB serial implementation.
    Not surprising - it got to a very functional state for most use cases - it got good enough for Beta use and without specific use case issues beyond added development nothing like this showed up, as noted I did see signs of trouble but nothing blocking or reproducible to make issue of - like this. Further work is staged on Paul's schedule with a major update to move USB to DMA and also add in all he other Serial types the T_3.x's present. I've made enough notes this should be 'on the list' - though no direct notes to that effect yet with other tasks taking priority.

    I did just get confirmation of taking a Pull request I made to cores for another issue - so as usual Paul is busily working … and github gave me notice

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •