Serial.write() Bug

Status
Not open for further replies.

hexdro

New member
Good Day everybody

I am currently trying to use the Teensy 3.6 in order to sample a voltage signal with the ADC.
For the moment I have set up an echo server with a serial connect between the Teensy and a julia coding evironment.
I am sending unsigned 8 bit numbers in the range from 0 - 255 and receiving the same numbers back.

My results seem to show that I receive all numbers except 17 and 19. On investigation I found that it is receiving the numbers but does not write them to the serial connection when calling serial.write.
My source code is shown below

void setup() {
Serial.begin(9600); // Open a serial coms channel
}

void loop() {
if (Serial.available()){ // Waiting for commands from the computer
uint8_t input = Serial.read(); // read the command
if (input == 19) Serial.write(0b000010010); //Test to see if 19 is recieved
else Serial.write(input);
}
}

I have tried the same code on the arduino uno and it works perfectly
 
Update: for reading the values output by the teensy, I am currently using the Julia LibSerialPort library

using LibSerialPort
list_ports()
sp=open("/dev/ttyACM0",9600)

# Clear buffer
while (bytesavailable(sp)>0)
read(sp)
end

NStart=18
NEnd=255


for n = NStart:NEnd
#a = string("",n)
#println("writing ",UInt8(n))
write(sp,UInt8(n))
sleep(0.001)
end
sleep(0.1)

BytesWritten=NEnd-NStart+1

println("Bytes written ",BytesWritten)

BytesAvailable=bytesavailable(sp)
println("Bytes available:",BytesAvailable)

x=zeros(UInt8,BytesAvailable)

for n = 1:BytesAvailable
x[n]=read(sp,UInt8)
println(Int(x[n]))
end
 
Sorry I have no idea about Julia and how it works. I know on Linux when I am talking to some of these Serial devices, my C code will use the termios library code to turn off some of the special character processing.

And I am not sure if 17 and 19 are special here or not.

Again I am guessing this is on the Linux/Julia side and not a teensy issue.
 
My guess is a wrong Unix/Linux line discipline setting. The Linux kernel basically messes with incoming & outgoing data in ways that certain terminals need, which is great if you're using those terminals, and terribly frustrating if you're not. When you run software that doesn't explicitly configure the line discipline, then you're at the mercy of whatever default your system and kernel might have.

Here's a quick way to check.

0: Make sure you have the latest udev rule file installed. The last thing you need is ModemManager making everything much harder! Older versions of this file didn't have ID_MM_PORT_IGNORE, and newer ModemManager has a "feature" to disregard ID_MM_DEVICE_IGNORE under certain settings which recently became the defaults on Ubuntu & other distros. (FWIW, the ModemManager devs have fixed ID_MM_DEVICE_IGNORE upstream, but it'll be at least a year or two until it filters downstream to long-term stable distros)

1: Stop whatever other software your Linux machine is running that accesses the serial device

2: Run Arduino and upload your program again

3: Select your Teensy in Tools > Ports. Select it from the "Teensy Ports" part of the menu, not "Serial ports".

4: Open the Serial Monitor window. This will cause Arduino to open the serial device for the first time (uploading is done by HID, not serial). During the opening process, the serial monitor will configure the serial device for "raw" line discipline, which tells the kernel to just let all data through as-is.

5: Close the Serial Monitor window. Ok to leave Arduino running.

6: Now run your other software. The line discipline setting from Arduino's Serial Monitor should be in effect, if you haven't unplugged the cable or uploaded again, and if your software doesn't configure any specific line discipline setting.

Does it now work properly?
 
Last edited:
You are thinking of them as numbers, but I'll bet something on the OS side is thinking of them as ASCII control characters.
Decimal 17 and 19 are DC1 and DC3, aka Control-Q and Control-S, often (well, historically) used as software flow control symbols XON and XOFF.
 
The (likely) reason it works perfectly with Arduino Uno is because Arduino does use serial for uploading, and Arduino Uno has a dedicated USB-serial chip. As a result, your PC sees the same device continuously connected. When Uno reboots, it's only the microcontroller. The USB chip does not reboot, so it's still the same USB port. And during uploading, the Arduino software opens the serial port and configures the line discipline, which leaves the port with those settings when you later run other non-Arduino software.

Teensy is a native USB device. There's no separate USB-serial chip. That means you get much faster communication and Teensy can implement non-serial devices. But it also means the USB disconnects each time you reboot. To your PC, it looks as if you very rapidly unplugged and reconnected the USB cable.

On top of that, uploading with Teensy is done using HID protocol, not serial. So the uploading process never touches any serial devices. Nothing in the normal uploading (without opening the serial monitor) ever would configure serial line discipline settings.
 
Status
Not open for further replies.
Back
Top