Petter Holt Juliussen • Mail | Mastodon | GitHub | Letterboxd

for later reference.

SIM900A MINI (v3.8.2)

2021-09-20

This SIM900/A V3.8.2 module has a set of TTL level serial interface, a set of RS232 level serial interface, a set of power supply interface.

Specifications

pinout

pinout_module

Firmware

AT+CPIN?
+CPIN: PH-NET PIN # SIM/device locked (carrier locked?)

While its great for Asian GSM infrastructure in different places in the world you will just get PH-NET PIN response meaning its locked for current network. I found that flashing SIM900A with firmware for SIM900 opens it up again to work exactly as SIM900, with slightly worse signal quality due to physical radio differences.

References:

Arduino example

arduinonano
#include <SoftwareSerial.h>

SoftwareSerial Modem(9, 10); // RX / TX
unsigned char buffer[64];
int count = 0;

void setup() {
  Modem.begin(9600);
  Serial.begin(9600);
  Serial.print("Ready!");
}

void loop() {
  if (Modem.available()) {
    while (Modem.available()) {
      buffer[count++] = Modem.read();
      if (count == 64) break;
    }
    Serial.write(buffer, count);
    clearBufferArray();
    count = 0;
  }

  if (Serial.available())
    Modem.write(Serial.read());
}

void clearBufferArray() {
  for (int i = 0; i < count; i++) {
    buffer[i] = NULL;
  }
}
AT+CSQ
+CSQ: 21,0
OK

AT+COPS=?
+COPS: (1,"N NetCom","NetCom","24202"),(1,"N Telenor","TELENOR","24201"),,(0,1,4),(0,1,2)
OK

Using the TinyGSM library

#define TINY_GSM_MODEM_SIM900
#define SerialMon Serial
#define TINY_GSM_DEBUG SerialMon

#define PIN_MODEM_RX      9
#define PIN_MODEM_TX      10
//#define PIN_MODEM_RST   11

#define PIN_LCD_RST       2
#define PIN_LCD_CE        3
#define PIN_LCD_DC        4
#define PIN_LCD_DIN       5
#define PIN_LCD_CLK       6
#define PIN_LCD_BL        7

#define GSM_AUTOBAUD_MIN  9600
#define GSM_AUTOBAUD_MAX  57600

#define GSM_PIN           ""
#define TARGET_PHONE      "+47xxxxxxxx"

#include <TinyGsmClient.h>
#include <LCD5110_Graph.h>
#include <SoftwareSerial.h>

SoftwareSerial SerialAT(PIN_MODEM_RX, PIN_MODEM_TX);  // RX, TX
LCD5110 screen(PIN_LCD_CLK, PIN_LCD_DIN, PIN_LCD_DC, PIN_LCD_RST, PIN_LCD_CE);
TinyGsm modem(SerialAT);

//extern uint8_t MediumNumbers[];
//extern uint8_t TinyFont[];
extern uint8_t SmallFont[];


void setup() {
  // Set console baud rate
  SerialMon.begin(115200);
  delay(10);
  DBG("Wait...");

  pinMode(PIN_LCD_BL, OUTPUT);

  screen.InitLCD();
  screen.setFont(SmallFont);
  screen.print("SIM:", 0, 0);
  screen.print("OPR:", 0, 8);
  screen.print("REG:", 0, 16);
  screen.print("CSQ:", 0, 24);
  screen.update();

  delay(6000);
  TinyGsmAutoBaud(SerialAT, GSM_AUTOBAUD_MIN, GSM_AUTOBAUD_MAX);
  //delay(6000);
  DBG("Initializing modem...");
  modem.init();
  delay(1000);

  SimStatus simStatus = modem.getSimStatus();
  screen.print(getSimStatusName(simStatus), 30, 0);
  screen.update();
  /*if (GSM_PIN && simStatus != 3) {
    modem.simUnlock(GSM_PIN);
  }
  SimStatus simStatus = modem.getSimStatus();
  screen.print(getSimStatusName(simStatus), 30, 0);
  screen.update()*/

  RegStatus regStatus = modem.getRegistrationStatus();
  screen.print(getRegStatusName(regStatus), 30, 16);
  screen.update();

  String ccid = modem.getSimCCID();
  DBG("CCID:", ccid);

  String cop = modem.getOperator();
  DBG("Operator:", cop);
  screen.print(cop, 30, 8);
  screen.update();

  int csq = modem.getSignalQuality();
  DBG("Signal quality:", csq);
  screen.printNumI(csq, 30, 24);
  screen.update();

  //delay(1000);
  //bool res = modem.sendSMS(TARGET_PHONE, String("Hello!"));
  //DBG("SMS:", res ? "OK" : "fail");

  /*bool res = modem.callNumber(TARGET_PHONE);
  DBG("Call:", res ? "OK" : "fail");
  delay(5000L);
  if (res) {
    delay(1000L);

    // Play DTMF A, duration 1000ms
    modem.dtmfSend('A', 1000);

    // Play DTMF 0..4, default duration (100ms)
    for (char tone = '0'; tone <= '4'; tone++) { modem.dtmfSend(tone); }

    delay(5000);

    res = modem.callHangup();
    DBG("Hang up:", res ? "OK" : "fail");
  }*/

  // Enable Calling Line Identification Presentation
  // modem.sendAT(GF("+CLIP=1"));
}

void loop() {
  /*while (modem.stream.available()) {
    String res = modem.stream.readStringUntil('\n');
    //modem.waitResponse(1000L);
    res.trim();
    DBG(res);
    if (res == "RING") {
      DBG("INCOMING!");
    }
    else if(res == "NO CARRIER") {
      DBG(":(");
    }
  }*/
}

String getRegStatusName(RegStatus status) {
  switch (status) {
    case 0: return "Unregistered";
    case 1: return "Home";
    case 2: return "Searching";
    case 3: return "Denied";
    case 4: return "Unknown";
    case 5: return "Roaming";
    default: return "No result";
  }
}
String getSimStatusName(SimStatus status) {
  switch (status) {
    case 0: return "ERROR";
    case 1: return "Ready";
    case 2: return "Locked";
    case 3: return "Antitheft";
  }
}

References:

AT Command Reference

AT+IPR - Set TE-TA Fixed Local Rate

Test: AT+IPR=? - Returns list of supported baud rates.

AT+IPR=?
+IPR: (),(0,1200,2400,4800,9600,19200,38400,57600,115200)   # 0 = auto-bauding

SIM

AT+CSMINS - SIM Inserted Status Reporting

Test: AT+CSMINS=? (response OK)
Read: AT+CSMINS? - +CSMINS:<n>,<SIM inserted>
Write: AT+CSMINS=<n>

AT+CPIN - Enter PIN

Test: AT+CPIN=? (response OK)
Read: AT+CPIN? - Returns an alphanumeric string indicating whether some password is required or not.
Write: AT+CPIN=<pin>[,<new pin>]

AT+CPIN?
+CPIN: SIM PIN  # MT is waiting SIM PIN to be given

Network/operator

AT+CSQ - Signal Quality Report

Returns received signal strength indication <rssi> and channel bit error rate <ber> from the ME.

Command: AT+CSQ
Response: +CSQ: <rssi>,<ber>

Value RSSI dBm Condition
2 -109 Marginal
3 -107 Marginal
4 -105 Marginal
5 -103 Marginal
6 -101 Marginal
7 -99 Marginal
8 -97 Marginal
9 -95 Marginal
10 -93 OK
11 -91 OK
12 -89 OK
13 -87 OK
14 -85 OK
15 -83 Good
16 -81 Good
17 -79 Good
18 -77 Good
19 -75 Good
20 -73 Excellent
21 -71 Excellent
22 -69 Excellent
23 -67 Excellent
24 -65 Excellent
25 -63 Excellent
26 -61 Excellent
27 -59 Excellent
28 -57 Excellent
29 -55 Excellent
30 -53 Excellent

AT+COPS - Operator Selection

Test: AT+COPS=? - Returns list of operator present in the network
Read: AT+COPS? - Returns current mode and the currently selected operator
Write: AT+COPS=<mode>[,<format>,[<operator>]]

AT+COPS=?

+COPS: (2,"Telia N","","24202"),(1,"N Telenor","TELENOR","24201"),,(0,1,4),(0,1,2)

AT+CREG - Network Registration

Forces the mobile terminal to select and register the GSM/UMTS/EPS network.

Test: AT+CREG=? - Returns list of supported <n>s
Read: AT+CREG? - Returns result code and an integer (<stat>) which shows whether the network has currenctly indicated the registration of the ME
Write: AT+COPS=<mode>[,<format>,[<operator>]]

SMS

AT+CSCA - SMS Service Center Address

References: