One thing on old Windows that I liked very much but not available on recent windows is HyperTerminal. It was so usefull for automation with serial port e.g, AT Command. There are several alternatives you can use Putty, but somehow I don't feel much intimacy with this tool.
Luckily I found an handy alternative (at least to me) last night which comes out with Windows by default. It is a command line program called "PowerShell". It allows you to do a kind of programming like .NET framework directly in command line. I don't get any deeper into the programming aspect of PowerShell. You only need to know about 3~4 lines of syntax to use 'AT' command and I will just put down the list of frequently used AT command in the form of PowerShell command so that you can just copy and paste as you need.
I would start with the basic setup and small set of test, and keep extending the list as I get along.
Followings are the topics :
- Basic Setup
- Why the backtick r matters
- Reading the answer back
- Copy this and past it into PowerShell Window when you want to open a Serial Port
- Power Cycle UE
- Answering the Voice Call
- When nothing comes back
- Reference
Basic Setup
Four members of one .NET object do everything on this page: the constructor,
The basic usage is as shown below. I wouldn't explain too much on this and I think you can intuitively understand the meaning.
The whole session, from opening the port to closing it.
PS C:\> $port= new-Object System.IO.Ports.SerialPort COM19,9600,None,8,one // set COM port as you need
PS C:\> $port.open() // Open the Serial Port
PS C:\> $port.WriteLine("Any AT Command `r") // `r is the most important. I spent quite a while to figure this out.
PS C:\> $port.WriteLine("Any AT Command `r") // (`) is the character called grave-accent. Which is on the same key
// as '~' in my keyboard.
...
PS C:\> $port.Close() // After you are done with AT command, I would suggest you to close it.
Five values go into the constructor, positionally, and they have to match the device on the other end. The red part of the first line is the part to change.
| 1 | COM19 | The port name. Windows numbers these, and the number is not stable across reboots or USB sockets. |
| 2 | 9600 | The speed in bits per second. |
| 3 | None | Parity. |
| 4 | 8 | Data bits. |
| 5 | one | Stop bits. It is a word rather than a digit because it names a value of the StopBits enumeration, and |
The port name is the value that changes most often and the easiest to get wrong. PowerShell will list the ones that exist, which is faster than opening Device Manager.
List the serial ports Windows can see.
[System.IO.Ports.SerialPort]::getportnames()
A modem usually presents more than one port. One of them takes AT commands, another carries the data connection, and a third may carry a debug log. Only one of them will answer
Five positional values : port, speed, parity, data bits, stop bits. : it is a StopBits enumeration value.one is a name, not a numberPort numbers move : a different USB socket can produce a different COM number.Several ports, one answer : only the AT port replies toAT .
Why the backtick r matters
The note above calls
The first is the modem's side. A command line is not finished until a termination character arrives, and the character is not fixed by magic: it lives in a register. 27.007 clause 4.3 lists the V.250 commands that a UE has to implement, and the first row is
The second is PowerShell's side. PowerShell uses the backtick as its escape character, where most languages use a backslash, so
One detail decides whether the escape happens at all, and it catches people who copy a line and then tidy the quotes.
| AT followed by carriage return. Double quotes process the escape. | |
| AT followed by a literal backtick and a literal letter r. Single quotes do not process escapes, so the modem never sees a terminator and never answers. |
The register can be changed with
The modem waits for carriage return : 27.007 lists S3 with a mandatory default of IRA 13.The backtick is PowerShell's escape character : not the backslash.Double quotes escape, single quotes do not : this is the usual reason a copied line goes quiet.Leave S3 alone : every other tool on the port assumes the default.
Reading the answer back
Everything above sends. Nothing above reads, and a modem answers every command whether or not anybody is listening. Three more members of the same object turn this from a write-only interface into a usable one.
| Returns whatever has arrived in the buffer so far and returns immediately. If the modem has not answered yet, it returns an empty string rather than waiting. | |
| Waits until a terminator arrives and returns one line. It blocks, so it needs the timeout below. | |
| Milliseconds. Without it a blocking read on a silent port waits for ever, and the console is stuck. |
The crude pattern is also the reliable one. Write, wait a moment for the modem to answer, then take whatever arrived.
Send one command and read the answer.
$port.ReadTimeout = 2000
$port.WriteLine("AT+CGMI`r")
Start-Sleep -Milliseconds 300
$port.ReadExisting()
The sleep is doing real work. A modem that has to reach the network before it can answer will take longer than one that answers from memory, and
Two things in that answer will surprise you the first time. The modem echoes your own command back before its reply, because 27.007 clause 4.3 lists the V.250 command
Set the error reporting at the same time. An unadorned ERROR carries no diagnosis, and
: so it needs a sleep in front of it.ReadExisting never waits : set the timeout first.ReadLine waits for ever withoutReadTimeout The first thing you read is your own command : unlessATE0 has been sent.Trim before comparing : the answer carries its own carriage return and line feed.
Copy this and past it into PowerShell Window when you want to open a Serial Port
The lines below are the same ones from the section above with the prompt taken off, so they paste into a window cleanly. Every session starts with them, so they are worth keeping somewhere you can reach quickly.
Before you copy and past, modify COM port setting according to the device attached to the control PC.
Paste this to open the port.
$port= new-Object System.IO.Ports.SerialPort COM19,9600,None,8,one $port.open()
Two lines, and the second one is the one that can fail. Opening a port takes exclusive ownership of it, so a terminal left running somewhere else will block it. The exception that comes back does say so, though not in those words.
Pair it with the closing line whenever you can. A port held by a console that was closed without releasing it stays held until the process ends, and the next attempt fails for a reason that has nothing to do with the modem.
Paste this when you are finished.
$port.Close()
A port has one owner : and opening it is what claims ownership.Close it when you finish : or the next session cannot open it.Change the red part first : the five values must match the device.
In practice the paste is worth two more lines than the original. Echo off and verbose errors are both settings rather than actions, so they last for the whole session. Set them at the start and you never have to wonder later why a command answered with its own text, or with a bare ERROR.
A complete opening sequence, with the two settings worth having.
$port= new-Object System.IO.Ports.SerialPort COM19,9600,None,8,one
$port.open()
$port.ReadTimeout = 2000
$port.WriteLine("ATE0`r")
$port.WriteLine("AT+CMEE=2`r")
The last two lines are described further down and on the AT Command page.
Power Cycle UE
A modem has no power button, so a restart has to be asked for over the same port you are already using. The command below does it, and the parameter that turns it into a restart rather than a setting is the second one.
Reset the MT and bring it back to full functionality.
$port.WriteLine("AT+CFUN=1,1`r")
There are several different form of +CFUN and modify the command depending on your need. Also, this CFUN does not seems to automatically set Airplane Mode to be Off.
The note above is right that there are several forms, so here is the list. 27.007 clause 8.2 defines
| 0 | Minimum functionality, where the least power is drawn. |
| 1 | Full functionality. Turns on the transmit and receive circuits for every supported radio technology. |
| 2 | Transmit circuits off only. |
| 3 | Receive circuits off only. |
| 4 | Both transmit and receive off. This is the pair that matches what flight mode does to the radio. |
| 5 to 127 | Reserved for manufacturers, as intermediate states between full and minimum. |
| 128 | Full functionality with the radio technologies chosen by |
| 129 | Prepare for shutdown. After this only |
The second parameter is the one that makes this a power cycle rather than a setting.
The observation about flight mode has a cause worth knowing. 27.007 attaches a note to this command saying it is manufacturer specific whether
One more line from the same clause is worth reading before relying on this. 27.007 marks the implementation of
: both directions off, radio silent.<fun>=4 is the flight mode pair : and omitting it means no reset at all.<rst>=1 is what resetsRegistration is not guaranteed to follow : 27.007 leaves that manufacturer specific, and names+COPS as the command that forces it.The command itself is optional : check withAT+CFUN=? before depending on it.
Answering the Voice Call
Answering a call from the terminal is one line. That line either works or does nothing, depending on which domain the call arrived on. The note underneath it is the more useful half of this section.
Answer an incoming call.
$port.WriteLine("ATA`r")
This doesn't seem to work in case of VoLTE (PS Call).
That one line is a V.250 command rather than a 3GPP one, and the difference explains the note above about VoLTE. 27.007 clause 6 covers call control and clause 6.2 borrows the V.250 dial command
3GPP does treat the two kinds of call as different at this interface, at least when originating one. Clause 6.4A defines
So the behaviour on this page is consistent with a modem that maps
Two commands are worth trying before concluding that nothing can be done. 27.007 clause 8.74 defines
: 27.007 never defines an answer command.ATA belongs to V.250Originating is selectable, answering is not :+CVMOD steersATD and has no counterpart here.An IMS call may never reach the AT interface : which is not a fault in the command.Check with : clauses 8.74 and 8.73, before giving up.+CLCCS or+CMCCS
When nothing comes back
A serial port fails in a small number of ways, and the symptom usually names the cause. The table is ordered by how often each one happens rather than by how serious it is.
| Another program already holds the port. A COM port has one owner at a time. | Close the other terminal or tool, then open it again. | |
| The write is accepted and nothing ever comes back | No carriage return reached the modem, or the read ran before the answer arrived. | Check the quoting around |
| The answer is your own command | Echo is on, which is the V.250 default. | Send |
| Error reporting is at its default setting. | Send |
|
| Characters arrive but they are unreadable | The speed, parity, data bits or stop bits do not match the device. | Correct the five constructor values. |
| The constructor fails on the port name | The port is numbered differently from what you assumed. | List them with |
One habit prevents most of these. Close the port when you finish, as the note further up this page says, because a port left open by a crashed console stays owned until the process ends. If
One owner per port : and a crashed console still counts as the owner.Silence means the terminator or the timing : not usually the command.Echo and error reporting are both defaults worth changing :ATE0 andAT+CMEE=2 .Unreadable text is a framing mismatch : not a modem fault.
Reference
The commands on this page are ordinary AT commands, so the documents behind them are the same ones the AT Command page uses. The PowerShell half comes from the .NET class that the first line builds.
- 3GPP 27.007 - AT command set for User Equipment, v19.6.0. Clause 4.3 lists the V.250 commands a UE must implement, including S3 and E. Clause 8.2 is
+CFUN and its values. Clause 6.4A is+CVMOD . - ITU-T V.250 - the basic command set, which owns
ATA ,ATE and the S registers. - System.IO.Ports.SerialPort - the .NET class behind
new-Object System.IO.Ports.SerialPort , and the reference for every member used here. - AT Command - the same commands without the PowerShell wrapper, including what
+CMEE does and how+CRSM reads the SIM.