1

TL;DR:

I need to read the time off of my Hologram Nova USB cellular modem on /dev/ttyACM0 and update the system clock after the pi restarts. I'd like to do it in Python but it isn't reading the serial tty correctly.

My build

  • I'm running python 2.7.13 on Raspbian 9
  • I'm using pyserial 3.2.1-1
  • I have a Pi 3 b+
  • The modem is a USB connected U-Blox SARA-U201 (AKA Hologram Nova)

What works so far:

  • My cellular modem is sitting on /dev/ttyACM0
    • I can communicate with it using screen /dev/ttyacm0 9600
  • I can get a time stamp in the screen session by typing AT+CCLK? and hitting Enter

Here is the output from the screen session

AT+CCLK?

+CCLK: "19/05/16,21:31:47-16"

OK

What doesn't work so far:

  • I have tried to use pyserial to interrogate the tty and return the time stamp.
  • I have tried to create an expect script using screen
    • I'd prefer not to do this with an expect script when python is a lot better.
    • I'll post my source for expect if this can't be done in Python.

Python Code:

import serial
import time, sys
import datetime
response = ''
SERIAL_PORT = "/dev/ttyACM0"
ser = serial.Serial(SERIAL_PORT, baudrate = 9600, timeout = 5)
ser.write("AT+CCLK?\r")
response = ser.readline()
print response

When using the python console the line ser.write("AT+CCLK?\r") results in a 9 being returned on the next line. response remains empty and ser.inWaiting() is equal to 0. Here is the text returned from the tty:

root@raspberrypi:/home/pi# python
Python 2.7.13 (default, Sep 26 2018, 18:42:22)
[GCC 6.3.0 20170516] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import serial
>>> import time, sys
>>> import datetime
>>> response = ''
>>> SERIAL_PORT = "/dev/ttyACM0"
>>> ser = serial.Serial(SERIAL_PORT, baudrate = 9600, timeout = 5)
>>> ser.write("AT+CCLK?\r")
9
>>> response = ser.readline()
>>> print response
  • Please don't post pictures of text. Instead paste the text direct into the question. – Ingo May 17 at 16:35
  • Hey there! The response text is listed above the picture but I'll go ahead and change it. – Shrout1 May 17 at 17:45
  • Ah sorry, haven't seen that. – Ingo May 17 at 17:49
1

Ok turns out I am an impatient man.

I was simply requesting the data too quickly; screen stays connected and shows it, Python is just too fast when it reads the input.

This code attempts to read the time from the modem at 2/10 of a second intervals for 20 seconds. If unsuccessful it sleeps for 20 seconds and then tries again. It will return the datetime string that is provided to the modem. That can be parsed from the "response" variable.

import serial
import time, sys
import datetime

i=0
time_found=False
response=''
SERIAL_PORT="/dev/ttyACM0"
ser=serial.Serial(SERIAL_PORT, baudrate = 9600, timeout = 15)

while time_found==False:
        ser.write('AT+CCLK?\r')
        response = ser.readline()
        while "CCLK:" not in response:
                response=ser.readline()
                time.sleep(0.2)
                ++i
                if i==200:
                        break
        if "CCLK:" in response:
                time_found=True
        else:
                time.sleep(20)

print response
1

Question

Setup = Hologram Nova USB cellular modem on /dev/ttyACM0

Can do = Terminal command AT+CCLK? replies +CCLK: "19/05/16,21:31:47-16"

How do in python?

Answer

Suggest 2 steps:

  1. Verify serial OK by loop back on '/dev/serial0'.

  2. Replace '/dev/serial0' by '/dev/ttyACM0' and try your luck on Hologram Nova.

Update 2019may17hkt1628

In case loopback /dev/serial0 works but /dev/ttyACM0 does not work, then it might be the external USB problem. I usually recommend to use the powerful RealTerm to do troubleshooting. You might might read the details in the second reference below. RealTerm can send/receive long strings of file, store data in files, new line setting, etc. So it is much faster than python and the not so powerful puTTY or TeraTerm. I show below a couple of screen captures for your reference. You might also like to read SparkFun for their recommendation of RealTerm (see reference below). And in case you are trying USB/TTL cables, good quality USB cable is also important. I usually recommend CH340 drivers, though Raspbian accepts PX2xxx drivers OK.

superterm 1

superterm 2

usb serial cable

References

UART Serial Debugging Tips

[How to verify serial by loopback check?] Serial Communication from Raspbian using Python to Arduino

[How to debug serial?] Serial to Arduino totally non-responsive

Terminal Emulators

Serial Terminal Basics (TeraTerm) - SparkFun

RealTerm (Windows) - SparkFun Recommendation

TeraTerm is awesome for simple ASCII-only serial terminal stuff, but what if you need to send a string of binary values ranging from 0-255? For that, we like to use RealTerm. RealTerm is designed specifically for sending binary and other difficult-to-type streams of data, ...

USB TTL

How many serial ports are on the Pi 3?

Options to add 20 UART to RPi

Increase number of TTYs

Persistent [USB] Device Names on Raspberry Pi - Vrijdag 2015feb06

Program to setup serial on '/dev/serial0'

from   time import sleep
import serial

serialPort0 = serial.Serial(port = '/dev/serial0',
        baudrate = 9600,
        parity = serial.PARITY_NONE,
        stopbits = serial.STOPBITS_ONE,
        bytesize = serial.EIGHTBITS,
        timeout= 1)
  • Lots to look into here! Thank you! The modem is directly connected into the pi, no cable. I'll try to use some of your suggested tools and read your links today. I will have to play more with it after work. I appreciate the information! – Shrout1 May 17 at 11:29
  • @Shrout1 You are welcome. I suggest to also try USB/TTL cable, for easy swap testing, and also sooner or later you might need more than one UART channel. Good luck and have a nice weekend. – tlfong01 May 17 at 12:10
  • Worked it out! I was trying to poll the TTY too quickly and so I was looking for a response before the modem could actually query the network. Thanks again for your help! – Shrout1 May 17 at 18:24
  • How nice! I also learnt a lesson from your experiments. I am thinking of adding a user programmable delay in my UART loopback program, so the user can adjust the delays. You also remind me when I first played with a BlueTooth serial module. I did not realize in the beginning that the blue tooth modules needs some time (in the order of milliseconds) to process the data from Rpi. And after adding a wait-for-module-operation function, all problems disappeared! Have a nice weekend! – tlfong01 May 18 at 0:57
0

You have supplied insufficient information to provide a definitive answer.

It is most likely your modem is expecting a LF or CR/LF

Replace the \r with \n

read(30) is going to wait for 30 characters. You should use readline() or equivalent

  • I've also tried readline() and it didn't work, but thank you for the pointer! I can try a \n but I've never seen that in any guide anywhere... Using screen and the enter key it works – Shrout1 May 17 at 11:05
  • Modified the script to use ser.readline() and included a screenshot. What other information can I provide that will help to solve the issue? I'm happy to post anything that gets me closer to the solution. Also, I tried using \n instead of \r and response came back with my original query as though a new line had not been entered. – Shrout1 May 17 at 11:23
  • @Shrout1 DO NOT post images - copy text. You still appear to be sending a CR. You appear to be running as root - this is a recipe for disaster. – Milliways May 17 at 12:55
  • I will try it as a regular user as well, it’s possible that’s a part of the problem. The text responses are available above the screenshot. Thanks! – Shrout1 May 17 at 13:24
  • It appears that running this particular set of commands with sudo or as root doesn't have an impact. But thank you for pointing that out! Always something to keep an eye out for. – Shrout1 May 17 at 19:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.