Search code examples
dartserial-portat-command

Modem seems not to accept the issued AT Commands ATZ and AT+VCID=1 in order to enable Caller Id


Using dart I made the following code that reads data from CallerId-enabled modem connected in /dev/ttyACM0 (used purely for testing - learning purpoces):

import 'package:libserialport/libserialport.dart';
import 'dart:typed_data';

void main(List<String> arguments) {
  final port = SerialPort("/dev/ttyACM0");
  if (!port.openReadWrite()) {
    print(SerialPort.lastError);
  }

  try {
    port.write(Uint8List.fromList("ATZ\r\n".codeUnits));
    print("sent ATZ");
    port.drain();

    // Do not wait for response assume this is the correct command
    port.write(Uint8List.fromList("AT+VCID=1\r\n".codeUnits));
    port.drain();

    sleep(const Duration(milliseconds: 1000));
  } on SerialPortError catch (e) {
    print(SerialPort.lastError);
  }
  final reader = SerialPortReader(port);
  reader.stream.listen((data) {
    print('######\nreceived: $data');
    print('\nASCII:\n' + String.fromCharCodes(data) + '\nEND OF ASCII\n####');
  });
}

According to modem AT command spec I expect to recieve for a phone call the following response:

RING

Whilst for Caller Id I expect a response such as:

RING
TIME=1550
DATE=10082022
NMBR=+306942870000
NAME=Chuck Norris
OK


On Both responses each newline is indicated via \r\n characters. But the output i get once I run the dart code is:

######
received: [82, 73, 78, 13, 10, 82, 73, 78, 71, 13, 10, 82, 73, 78, 71, 13, 10, 82, 73, 78, 71, 13, 10, 82, 73, 78, 71, 13, 10]

ASCII:
RIN
RING
RING
RING
RING

END OF ASCII
####
######
received: [82, 73, 78, 71, 13, 10]

ASCII:
RING

END OF ASCII
####
######
received: [82, 73, 78, 71, 13]

ASCII:
RING
END OF ASCII
####
######
received: [10]

ASCII:


END OF ASCII
####
######
received: [82, 73, 78]

ASCII:
RIN
END OF ASCII
####
######
received: [71, 13, 10]

ASCII:
G

END OF ASCII
####

As if the AT commands ATZ and AT+VCID=1 to be ignored. And ideas why that happens?


Solution

  • Having the same problem with you via an emperical approach, I found out that some delay is needed between opening the port and actually writing-issuing the AT commands. You can use the following piece of code in order to achieve this:

    import 'package:libserialport/libserialport.dart';
    import 'dart:typed_data';
    import 'dart:io';
    
    void main(List<String> arguments) {
      final port = SerialPort("/dev/ttyACM0");
      if (!port.openReadWrite()) {
        print(SerialPort.lastError);
      }
    
      sleep(const Duration(milliseconds: 500));
    
      try {
        port.write(Uint8List.fromList("ATZ\r\n".codeUnits));
        print("sent ATZ");
        port.drain();
        sleep(const Duration(milliseconds: 200));
    
        // Do not wait for response assume this is the correct command
        port.write(Uint8List.fromList("AT+VCID=1\r\n".codeUnits));
        print("Enabled VCID");
        port.drain();
    
        sleep(const Duration(milliseconds: 1000));
      } on SerialPortError catch (e) {
        print(SerialPort.lastError);
      }
      final reader = SerialPortReader(port);
      reader.stream.listen((data) {
        print('######\nreceived: $data');
        print('\nASCII:\n' + String.fromCharCodes(data) + '\nEND OF ASCII\n####');
      });
    }
    

    I use a 500ms delay between the first write and port.openReadWrite(), in your case you can experiment with various values. That will allow to have some breathing air between writes and reads.