Teensy 3.5 USB Serial to Linux Debian 4.19 x86_64

Status
Not open for further replies.

imaditya

Member
Hi,

I have run into a wierd problem wrt to Serial communication from Teensy 3.5 to PC.

Basically I am trying to send ADC values from Teensy to a PC for which I have modified the example sketch in the arduino. On the PC side I am using pyserial to receive the data.

The modifed arduino sketch is below:

Code:
/*
  Analog input, analog output, serial output

  Reads an analog input pin, maps the result to a range from 0 to 255 and uses
  the result to set the pulse width modulation (PWM) of an output pin.
  Also prints the results to the Serial Monitor.

  The circuit:
  - potentiometer connected to analog pin 0.
    Center pin of the potentiometer goes to the analog pin.
    side pins of the potentiometer go to +5V and ground
  - LED connected from digital pin 9 to ground

  created 29 Dec. 2008
  modified 9 Apr 2012
  by Tom Igoe

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/AnalogInOutSerial
*/

// These constants won't change. They're used to give names to the pins used:
const int analogInPin = A0;  // Analog input pin that the potentiometer is attached to
const int analogOutPin = 9; // Analog output pin that the LED is attached to

const int ledPin = LED_BUILTIN; 
int sensorValue = 0;        // value read from the pot
uint8_t outputValue = 0;        // value output to the PWM (analog out)
bool ledState = 0;

void setup() {
  // initialize serial communications at 9600 bps:
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // read the analog in value:
  sensorValue = analogRead(analogInPin);
  // map it to the range of the analog out:
  outputValue = map(sensorValue, 0, 1023, 0, 255);
  // change the analog out value:
  analogWrite(analogOutPin, outputValue);

  // print the results to the Serial Monitor:
  Serial.print("sensor = ");
  Serial.print(sensorValue);
  Serial.print("\t output = ");
  Serial.println(outputValue);
  ledState=!ledState;
  digitalWrite(ledPin, ledState);

  // wait 2 milliseconds before the next loop for the analog-to-digital
  // converter to settle after the last reading:
  delay(500);
}

I have only added some code to blink the onboard led on each execution of the loop.

When I connect the teensy to Windows 10(comes up as COM5 port) machine I can see the data using both, the arduino serial monitor and the pyserial library.

However when I connect it to a system running Debian 4.19. I do not seen anything on the serial port. The device is visible as /dev/ttyACM0, however when I do cat /dev/ttyACM0, nothing shows up in the terminal.

On python side I am using.

Code:
ser = serial.Serial(
    port ='/dev/ttyACM0',  
    baudrate = 9600, 
    bytesize = serial.EIGHTBITS
    )

to start a serial session.

If I read data using ser.read(3), since I am sending 1 byte values and 2 bytes to CR/LF(arduino's println), it ugoes into infinite wait until I realised that pyserial has a blocking read function and if timeout is not given it will block till its gets the mentioned number of bytes.

Upon checking the input buffer using ser.in_waiting, I found that my input buffer is empty i.e 0.

From here on I am stuck and I don't know how to proceed, I searched on the forum but no one has had similar problem. I want to confirm again that everything works on Windows 10 PC but I want to leave the debian system to do some data collection at the sensor location.

Please accept my gratitude in advance ! :)
 
Adding while(!Serial) in the setup solved the problem. I found this after searching the forum but I am unsure what this line actually means?
Does it verify an open port on the PC side or is it just to acknowledge the state of serial port on Teensy?
 
Does it verify an open port on the PC side

Yes, it means software running on the PC has opened the port.

More precisely, the Linux cdc_acm driver sends USB control messages at various times to configure settings. When a program opens the port, one of those messages is sent with the DTR bit set to 1, and when a program closes the port the DTR bit is set to 0. The control messages are also sent when software on your PC configures settings like the baud rate (which isn't actually used, but the control message send that info to Teensy where it's stored in memory).

The boolean check on Serial looks for 2 things: whether the USB device was configured at all, and whether a control transfer has been received which set DTR to 1. So putting "while (!Serial) ; " into your program causes it to sit and wait for a program on your PC to actually open the /dev/ttyACM0 device.
 
But a simple warning:
When you put in code like:
Code:
 while(!Serial) ;

It will wait there forever! And we often see posts up here that someones program works great when plugged into USB, but does not work when they are powering their board by external power... Often times it will be a line like this...

So I often put it in my own code without timeout...

Something like:
Code:
while (!Serial && (millis() < 5000)) ;
Which will wait for up to 5 seconds for the Serial port, and then continue...

Note: this assumes at startup of program as I do quick check for millis which starts at 0... For more generic usage, one can do this something like:
Code:
elapsedMillis em=0;
while (!Serial && (em < 5000)) ;
Or you can do the elapsed stuff yourself by grabbing the millis() at start of your wait and compare to current millis() during the loop...
 
Status
Not open for further replies.
Back
Top