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

Thread: Issue with Teensy USB features - handing USB communication when reading data

  1. #1
    Member
    Join Date
    Oct 2018
    Location
    Poland, Cracov
    Posts
    20

    Issue with Teensy USB features - handing USB communication when reading data

    I found a partial (or maybe permanent) solution, but the issue is as follows:

    I have used Teensy 3.6, Ubuntu 18.04 with TyCommander from TyTools, Visual Studio Code and PlatformIO extension with Teensyduino 1.44. I used TyCommander as serial monitor, bootloader/reset tool. And there were no problems or maybe I did not experience them.

    I run that program during tests with delay(10) instead of delayMicroseconds(200):
    Code:
    #include <Arduino.h>
    
    void setup()
    {
      Serial.begin(9600);
      pinMode(LED_BUILTIN, OUTPUT);
    }
    
    void loop()
    {
      digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN));
      if (Serial.availableForWrite())
      {
        Serial.println(millis());
      }
      delayMicroseconds(200);
    }
    However, since (I'm not 100% sure) I upgraded Ubuntu to 18.10 version I have problems with uploading software, hanging USB connection when reading data in serial monitor or it plot only countable number of lines. TyCommander was reporting with something like system info "resource busy" when trying to reset or use TyCommander monitor. The problem was partially solved by changing Teensy USB features from Serial to Serial MIDI. But there were some minor problems. However, on Windows the same program (I just switched to Windows and run Serial Monitor) there weren't any problems.

    Then I reinstall Ubuntu back to 18.04, and everything works as expecteded (PlatformIO, Teensyduino 1.45), but I have to use USB Serial MIDI feature (or probably *any other than Serial feature), on PlatformIO (in platformio.ino file) I'm using
    Code:
    build_flags = -D USB_MIDI_SERIAL
    And then serial monitor on Arduino IDE/TyCommander/my Qt app works without problems. When I change USB feature to USB Serial (on PlatformIO it is default ) the connection is hanging or I get only countable number of lines in serial monitor and then the connection is hanging as well the TyCommander / Arduino Serial Monitor is hanging and Teensy is not responding (I have to unplug/plug it).

    I can see now, that sometimes increasing the delay time and using USB Serial feature make it possible to read data from Teensy but it is not realiable.

    I'm guesing that this is the OS related problem. Am I right or I'm missing something?
    Last edited by Matthew; 01-03-2019 at 11:38 AM. Reason: Forgot to add Teensy board number

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,489
    What happens with :: if (Serial.availableForWrite() > 32)

    Not stated what Teensy - but T_3.x or T_LC any can overfill USB system - when it is that busy the bootloader may not get through.

  3. #3
    Member
    Join Date
    Oct 2018
    Location
    Poland, Cracov
    Posts
    20
    Oh sorry i forgot to add information about board - I'am using Teensy 3.6 (I updated first message).

    Quote Originally Posted by defragster View Post
    What happens with :: if (Serial.availableForWrite() > 32)

    Not stated what Teensy - but T_3.x or T_LC any can overfill USB system - when it is that busy the bootloader may not get through.
    Ok, so how can I manage to not overfill system USB? I don't see any solution for now.

  4. #4
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,489
    Did the provided code edit change anything? Assuming it works like … assumed ... without seeing/trying it myself. A write of millis and newline could be 11 bytes - forcing a delay to limit send rate is the only way if that is what the issue is.

  5. #5
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    21,810
    I can't comment on TyCommander or PlatformIO, but I can explain a little bit about what Teensy is doing and how the Arduino IDE works.

    When you choose a USB Type setting with "Serial", Teensy implements USB serial, so you get a COM port in Windows or a /dev/ttyACM* port in Linux. When using "MIDI" without Serial, a HID interface is used for Serial.print(), so you can still print to the Arduino Serial Monitor. I'm pretty sure PlatformIO doesn't know how to use this HID interface.

    On top of that, in Arduino there are 2 ways you can select Teensy in the Tools > Ports menu. There is a "Serial ports" section and a "Teensy" section. If you choose under "Serial ports", Arduino's normal Java code uses the JSSC library to talk to the serial port. If you choose "Teensy", there is no Java communication with the hardware at all. Instead a "teensy_ports" program is run. It talks to the serial port or HID interface and communication between it and Java is done by stdin/stdout (technically anonymous pipes on Windows).

    On Linux, JSSC tries to gain an advisory lock on the serial port. The teensy_ports program doesn't do any locking. So if you have other software in play, it's possible to get 2 programs opening the same serial device. Usually transmitting works from both, but receive is highly unreliable.

    Don't know if any of this helps?

  6. #6
    Member
    Join Date
    Oct 2018
    Location
    Poland, Cracov
    Posts
    20
    Firstly the question before the long post: Did the delay() function from my first post have an impact on USB hardware = it's simply waits and do nothing more or it let's the communication run?

    Quote Originally Posted by defragster View Post
    Did the provided code edit change anything? Assuming it works like assumed ... without seeing/trying it myself. A write of millis and newline could be 11 bytes - forcing a delay to limit send rate is the only way if that is what the issue is.
    OK, so If I understand Your reply correctly:

    1. My delay() function (if delay value was great enough) provide the way to non-blocking send rate for OS.
    2. The next issue is the number of bytes written to USB trasmit buffer:

    Quote Originally Posted by defragster View Post
    What happens with :: if (Serial.availableForWrite() > 32)
    If I will put a higher number of bytes than Serial.availableForWrite() limit = I overfilling the system USB. Am I right?


    So considering that I applied this code:
    Code:
    ##include <Arduino.h>
    
    const uint8_t 193887 = 4;
    uint8_t buffer[numberOfElements];
    uint32_t previousMicros = 0;
    uint32_t actualMicros = 0;
    uint16_t delayValue = 0; // [us]
    
    void setup()
    {
      Serial.begin(9600);
      pinMode(LED_BUILTIN, OUTPUT);
    
      for (uint8_t i = 0; i < numberOfElements; i++)
      {
        buffer[i] = i;
      }
    }
    
    void loop()
    {
      actualMicros = micros();
      if((actualMicros - previousMicros) > delayValue)
      {
        digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN));
    
        if (Serial.availableForWrite() >= sizeof(buffer))
        {
          Serial.write(buffer, sizeof(buffer));
        }  
    
        previousMicros = actualMicros;
      } 
    }
    Note, that I am not using any delay (intervalValue = 0) and I using USB Serial feature now (no MIDI anymore). And now, the TyCommander is hanging but not due to overfilling the USB but due to updating the UI. What is more, my Qt app (using qDebug() - provides an output stream - to print data instead of putting data into UI like on TyCommander) is working perfectly. Data is ariving without any blockade of stream. Only sometimes I have to reset Teensy after switching from TyCommander and my app probably due to some operations of opening/closing port.

    However... after some tests and diging, when I want to increase the buffer size (by simply changing numberOfElements variable) over the value of 4, then I have to incresing the intervalValue (coresponding to buffer size) because the stream is blocked after a while or imediately.
    Then I switched to USB Serial MIDI mode and it is much much better than on USB Serial mode. Now I'm sending 20 bytes with 10ms interval and now is over 6 minutes of communication without any problem (for example with 20 bytes and 2ms interval it hanged up after 3,2 minutes).
    And then when I switch to USB Serial Mode, I have no communication (it's starting reading data and hanginig after a while) and I have problems with uploading the new program (it's takes much longer time than normal). Next I'm switching back to USB Serial MIDI mode and it's ok as before.

    I specially checked and only the communication is hanging but Teensy is working as before (I have an oscilioscope probe on LED pin).

    Quote Originally Posted by PaulStoffregen View Post
    I can't comment on TyCommander or PlatformIO, but I can explain a little bit about what Teensy is doing and how the Arduino IDE works.

    When you choose a USB Type setting with "Serial", Teensy implements USB serial, so you get a COM port in Windows or a /dev/ttyACM* port in Linux. When using "MIDI" without Serial, a HID interface is used for Serial.print(), so you can still print to the Arduino Serial Monitor. I'm pretty sure PlatformIO doesn't know how to use this HID interface.

    On top of that, in Arduino there are 2 ways you can select Teensy in the Tools > Ports menu. There is a "Serial ports" section and a "Teensy" section. If you choose under "Serial ports", Arduino's normal Java code uses the JSSC library to talk to the serial port. If you choose "Teensy", there is no Java communication with the hardware at all. Instead a "teensy_ports" program is run. It talks to the serial port or HID interface and communication between it and Java is done by stdin/stdout (technically anonymous pipes on Windows).

    On Linux, JSSC tries to gain an advisory lock on the serial port. The teensy_ports program doesn't do any locking. So if you have other software in play, it's possible to get 2 programs opening the same serial device. Usually transmitting works from both, but receive is highly unreliable.
    Thank you Paul, it's a good to know information!


    So for now, I can freely sending 4 bytes in one loop count without any code delays, or send higher amount of bytes but with some intervals.

  7. #7
    Member
    Join Date
    Oct 2018
    Location
    Poland, Cracov
    Posts
    20
    OK,

    A lot of time has passed, but the problem came back to me at the most unexpected moment. However, I found the solution. On Windows everything was OK, but on Ubuntu the problem occurred on every device (tested on Ubuntu v18.04, 18.04.2 LTS). I tested it on an ordinary laptop and Intel NUC. The result was the same. I'm pretty sure that ModemManager cause the problem, after uninstalling the `modemanager` and reboot, the problem disappeared.

    Hope it helps somebody:

    Code:
    sudo apt-get --purge remove modemmanager
    reboot
    Also now I can freely choose different USB modes (Serial, MIDI etc.)

Posting Permissions

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