Serial communication issue between Teensy and Raspberry Pi

Status
Not open for further replies.

hpgmiskin

Member
I am using the node-serialport library to communicate with a Teensy 3.2 from a Raspberry Pi and am getting a number of issues that are not occurring with a Teensy connected to a Mac or with an Arduino connected to a Raspberry Pi.

The microcontroller is running a simple sketch that waits for a serial terminal connection and then transmits a `BEGIN` message followed by occasional `Some data` lines. When running on the Pi on some occasions the Teensy does not transmit any messages or will only transmit the `BEGIN` message. In advanced logs for the serialport library, I can see a bad file descriptor error occur when attempting to communicate with the Teensy and there is no data returned. Has anyone seen this error message before in relation to not being able to communicate with serial device?

In order for the Teensy to reset whenever the serial monitor is disconnected I have added a reset function which I copied from this forum post. I imagine that the specifics of how this reset function works is part of the problem as this function also disconnects the USB connection. Is there an alternative software reset that can be used?

I have create a repository, node-serialport-issue which includes source code for a node application and Teensy sketch. This application recreates the issue and can easily be deployed on resin.io, a serivce which makes releasing code to Raspberry Pi very easy. I have also created an issue on the node serialport library.

Any help is much appreciated. If anything is not clear I can explain more, provide better logs or update the example code to make it easier to understand. Thanks in advance
 
Try testing with the latest beta.

https://forum.pjrc.com/threads/50254-Teensyduino-1-42-Beta-3

After installing the beta, you will need to reprogram your Teensy with the same sketch.

These 2 improvements might be relevant:

fix teensy_serialmon asser of DTR on Windows, fixes (bool)Serial
(bool)Serial to use DTR only, fixes Serail remaining true after serial monitor close

Next time you test on Raspberry Pi, please try running this command in a terminal window "sudo tail -f /var/log/syslog". The main thing you're looking for in syslog are the kernel's messages about detecting USB device attach & disconnect, and the cdc_acm driver loading messages.

As you test, please be aware that forcing a hardware reboot by writing to the AIRCR register will cause Teensy's USB to disconnect. From the Raspberry Pi point of view, this looks as if the USB cable was unplugged, and then reconnected when Teensy begins running again.
 
Thanks for such a rapid response. I have installed the latest beta and uploaded the sketch to the Teensy but unfortunately the problem still persists. In the sketch I was checking if both Serial and Serial.dtr() were false before running reset.

I cannot find the `syslog` file in the `/var/log` folder, the only files I can locate within the log folder are as follows.

Code:
alternatives.log  apt  btmp  dirmngr  dmesg  dpkg.log  faillog  fontconfig.log  fsck  lastlog  wtmp

I fear that as I am running this using resin.io I have restricted access to the correct logs. I have also posted this question on the Resin forums as it could be an issue with how the USB is handled when porting the `/dev` folder into the running container.

I did not know that writing to the AIRCR register caused the Teensy USB to reset, I was only aware that it reset the code running on the Teensy. The behaviour you have outlines is desirable as I am looking for the Teensy to operate as if it had been disconnected and reconnected.
 
The behaviour you have outlines is desirable as I am looking for the Teensy to operate as if it had been disconnected and reconnected.

If your code isn't able to fully close the device before the reboot happens, then the Linux cdc_acm driver will assign the new instance to a different /dev/ttyACM file. That might cause trouble, unless your code is using udev or monitoring the /dev files and detecting the new name. Details like this should be present in the syslog info. Maybe ask on the Raspberry Pi forums how to access the syslog messages?
 
Thanks again for your response. I have posted on the Resin forums for help accessing the syslog messages.

The device is still accessible from the original `/dev/ttyACM` file so I do not think that Linux has assigned a new file in the dev folder. When I physically unplug the device I get a no such file or directory error, which I do not receive when experiencing the communication issues.

I will run a test where before starting the serial communication I list the available devices to see if there are two files pointing towards the same file in the `/dev` folder and post my findings.
 
Thanks to everyone for your responses, I will be making use of `dmesg` in future for debugging.

I have found that the problem is actually due to `ModemManager` attempting to use the Teensy as a modem and thus blocking communication on the serial line. I cannot claim that this resolution is my own as was from this resin forum post.

Sorry to have taken your time on the Teensy forums as it turned out to not be a Teensy issue. I hope this thread may help others in the future though, is there any way to mark this thread as resolved?
 
I have found that the problem is actually due to `ModemManager` attempting to use the Teensy as a modem and thus blocking communication on the serial line. I cannot claim that this resolution is my own as was from this resin forum post


Ouch... that issue was heavily discussed here and elsewhere several years ago. But I had thought that modern linux distributions would not longer come with this ugly Modem Manager.
 
Did you install the udev rule file? It's supposed to tell the Gnome ModemManager to not interfere.

Years ago the developer at Redhat working on NetworkManager & ModemManager maintained a list of devices which he failed to update, then made a few different ways to tell ModemManager not to touch devices. They finally settled on the way we're currently using in the udev rules. They promised to keep this way long-term stable.

If you have the udev rule file properly installed, then I'll *again* need to contact those developers and look into why ModemManager is interfering. But before I try talking with anyone, I need to confirm you really did properly install the udev rule file, that ModemManager really is ignoring it.
 
Sorry for the delayed response.

I have added the udev rules to the container in which I am running the application. The following line is the Docker command to copy `rules/49-teensy.rules` into the `rules.d` folder.

Code:
COPY rules/* /etc/udev/rules.d/

see full source

On the premise that I have done this correctly this has not worked, however, I belive this is due to only changing the udev rules in the container, the host OS is where I had to disable ModemManager in order to correct the issue.

Please hold back talking to the developers at this point due to the likelyhood that this is an issue caused by running within a container. I will ask about modifying the udev rules for the host OS on `resin.io` forums and report back if I find a way to modify the udev rules and can reliably test the rules.
 
I understand this is a old post, but I have been running into this problem today and I think I found a solution.

When I ran cat < /dev/ttyACM* I would get the same output but I noticed the command would post more than one line as soon as it was ran
regardless of delay(2000); I wondered if the teensy was printing to serial without a open port so when the cat command was ran the port would open
and print everything sent to serial at once.

I then searched "Arduino wait until serial is open" and if(Serial){} was the first result.

Code:
void setup(){
  Serial.begin(9600);
}

void loop(){
  if(Serial){
  Serial.println("Test");
    delay(2000);
  }
}

Using this test code I ran "cat < /dev/ttyACM*" and it resulted in a output of only one "Test" line
and repeated a few times at two second intervals. cat then froze and would not print any more lines.

since I got a different result I then tried the command "minicom -D /dev/ttyACM* -b 9600" and it worked without crashing.
 
I am having the same difficulty. I have installed the udev rules. I have tested with the example AnalogReadSerial using screen to open the port. On an arduino nano clone, I can see the output on the raspberry pi (ttyUSB0). On a teensy 3.2, I can see the output when connected to my mac. But, I cannot see the output from the teensy when connected to the pi.

Further, I have the same output going from teensy hardware Serial1 to RPi ttyS0 and that works fine.

I am running Raspbian Buster on a Pi 3.

ModemManager appears not to be installed as attempting to stop it produces this message:
Code:
Failed to stop ModemManager.service: Unit ModemManager.service not loaded.
Here is the output from dmesg showing that the teensy is recognized:
Code:
[  624.823727] usb 1-1.4: new full-speed USB device number 8 using dwc_otg
[  624.956550] usb 1-1.4: New USB device found, idVendor=16c0, idProduct=0483, bcdDevice= 2.75
[  624.956567] usb 1-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[  624.956576] usb 1-1.4: Product: USB Serial
[  624.956586] usb 1-1.4: Manufacturer: Teensyduino
[  624.956595] usb 1-1.4: SerialNumber: 1435950
[  624.957760] cdc_acm 1-1.4:1.0: ttyACM0: USB ACM device

Any help would be greatly appreciated!
 
Hi @hardiga,

Looks like it is working at the dmesg level...

That is a Teensy is NOT an FTDI usb object so it will not have a name of ttyUSB0 or the like, but
it does show up as an ACM device and in your case as it is the first ACM device plugged in, it shows up as /dev/ttyACM0

Did you try using that device name in your test programs?
 
Hi @hardiga,

Looks like it is working at the dmesg level...

That is a Teensy is NOT an FTDI usb object so it will not have a name of ttyUSB0 or the like, but
it does show up as an ACM device and in your case as it is the first ACM device plugged in, it shows up as /dev/ttyACM0

Did you try using that device name in your test programs?

Yes, sorry, I didn't make it clear. When trying to talk to the teensy, I am using /dev/ttyACM0 as shown in dmesg. I get no errors, but I also get no output.
 
Hopefully someone who uses RPIs/Linux more than I do can give you better answers.

It has been awhile, but I do plan to get back to it soon...

If it were me, some of the next steps I would try include things like:

Do I get output if I run it using sudo?

Check for users and groups. Example I plugged a T4 into an RPI3.
Code:
[   68.231711] usb 1-1.4: new high-speed USB device number 5 using xhci_hcd
[   68.362251] usb 1-1.4: New USB device found, idVendor=16c0, idProduct=0483, bcdDevice= 2.79
[   68.362267] usb 1-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[   68.362280] usb 1-1.4: Product: USB Serial
[   68.362292] usb 1-1.4: Manufacturer: Teensyduino
[   68.362304] usb 1-1.4: SerialNumber: 5918940
[   68.423224] cdc_acm 1-1.4:1.0: ttyACM0: USB ACM device
[   68.423758] usbcore: registered new interface driver cdc_acm
[   68.423768] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
pi@RPI4B:~ $ ls -l /dev/ttyA*
crw-rw-rw- 1 root dialout 166,  0 Jan 13 16:07 /dev/ttyACM0
crw-rw---- 1 root dialout 204, 64 Jan 13 16:03 /dev/ttyAMA0
pi@RPI4B:~ $
pi@RPI4B:~ $ groups
pi adm dialout cdrom sudo audio video plugdev games users input netdev gpio i2c spi
So I see the Teensy is in the dialout group. And I as the user are a member of dialout.

Again everyone appears to have rw access, so may not be issue, but that is some of the thigns I would check.

Again hopefully someone else may have more suggestions
 
Status
Not open for further replies.
Back
Top