The Modem Shield - davidmckechnie/IoTChallenge2015 GitHub Wiki

The Modem Shield

Modem image

The modem provides communication to the Telstra IoT Challenge Network. It has the RF front end and transceiver, antenna connection, a small micro controller which looks after network signalling and a 1.8V regulator so it can run on battery voltage.

Communication to the modem is via UART. The best way to try this out is to configure the Arduino to use hardware UART (pins 0 and 1) to your laptop, and software UART (pins 2 and 3) to the modem. There's a demo sketch (ModemExample.ino) in this repo that does this.

Once you have this programmed, close the Arduino environment and open Realterm at 9600 Baud, on whatever COM port your TinyDuino is operating (it's COM3 in the screenshot below, but will probably be something else on your laptop). You could use Putty or another client, but RealTerm is nice because you can send a message "all at once", not keystroke by keystroke.

RealTerm Port Selection

Set it to send CR+LF at the end of and try sending AT, and the modem should reply OK.

RealTerm Send message

> AT [CR][LF]
OK [CR][LF]

Setting the modem up

The next thing to do is to configure the modem with the right device ID and encryption keys. Check and set the existing ID with the AT+ID command, and set the key with the AT+KEY command:

> AT+ID [CR][LF]
+ID: DevAddr xx:xx:xx:xx [CR][LF]
+ID: DevEui xx:xx:xx:xx:xx:xx:xx:xx[CR][LF]
+ID: AppEui xx:xx:xx:xx:xx:xx:xx:xx[CR][LF]

Set the DevAddr first (this is printed on the insert provided with your kit)

> AT+ID=DevAddr, "01234567"[CR][LF]
+ID=DEVADDR, "01 23 45 67"[CR][LF]

Then set the DevEui

> AT+ID=DevEui, "0123456789ABCDEF"[CR][LF]
+ID: DEVEUI 01:23:45:67:89:AB:CD:EF[CR][LF]

Then set the AppEui

> AT+ID=AppEui, "0123456789ABCDEF"[CR][LF]
+ID: APPEUI 01:23:45:67:89:AB:CD:EF[CR][LF]

The last thing to do is set the encryption keys. For hopefully obvious reasons, you can't query the device to find the keys currently in use - they can only be updated. You'll find the key to use also printed on the insert in your kit.

> AT+KEY=NWKSKEY, "2B7E151628AED2A6ABF7158809CF4F3C"[CR][LF]
+KEY: NWKSKEY 2B 7E 15 16 28 AE D2 A6 AB F7 15 88 09 CF 4F 3C[CR][LF]
> AT+KEY=APPSKEY, "2B7E151628AED2A6ABF7158809CF4F3C"[CR][LF]
+KEY: APPSKEY 2B 7E 15 16 28 AE D2 A6 AB F7 15 88 09 CF 4F 3C[CR][LF]

Send your first message

If you managed to get the ID and keys correct for you modem, then you should be able to send a message to the world. Try this now. There are four different ways to send messages:

  • AT+MSG="Data to send"[CR][LF] This will send an ASCII message to the network, but there is no acknowledgement from the network to say it was received. This is useful mostly for "heartbeat" messages, which inform your application that a device is still contactable, and might contain some basic information as well.
  • AT+CMSG="Data to send"[CR][LF] Similar, but the the modem will request that the network acknowledges the message. This is useful if you need to know that a message was received by the application. For instance, if a user presses a button on your device, you probably want to check this message gets through.
  • AT+MSGHEX="11 22 33 AA BB FF"[CR][LF] This will send a specific byte sequence (represented in hex format) to the network. This is for more advanced use, if you aren't going to follow the standard message format and want to pack data in tightly to your own special format.
  • AT+MSGHEX="11 22 33 AA BB FF"[CR][LF] Send a byte sequence, and request an acknowledgement.

In addition, you can use different ports to send messages. For the challenge, everything will be on Port 1, so make sure you set this:

> AT+PORT=1[CR][LF]
+PORT: OK[CR][LF]

For now, just try AT+CMSG="Hello World"[CR][LF] or similar.

> AT+CMSG="Hello World"[CR][LF]
+CMSG: Start LoRaWAN transaction[CR][LF]
+CMSG: Wait ACK[CR][LF]
...
+CMSG: ACK Received[CR][LF]
+CMSG: RXWIN1, RSSI -88, SNR 13.5 [CR][LF]
+CMSG: Done [CR][LF]

If you do not get the ACK, and it goes straight to Done, then you need to check you have configured the ID and keys correctly. The network will only ACK a validated device.

Receiving a message from your application

If you send a message from your application to the device (downlink), it will be queued and sent when your device sends a message first. The pattern is this:

  1. Message is sent from your application to the gateway
  2. Message is queued, ready to send
  3. Time passes.
  4. At some point, your device sends a message using AT+CMSG etc. This could even be an empty message, used to check if any messages are waiting.
  5. The ACK from the network will also contain the downlink message.

If a downlink message is received, the payload will be in the reply from the modem like this

> AT+CMSG="Hello World"[CR][LF]
+CMSG: Start LoRaWAN transaction[CR][LF]
+CMSG: Wait ACK[CR][LF]
+CMSG: ACK Received[CR][LF]
+CMSG: PORT: 1; RX: "14 54 54"[CR][LF]
+CMSG: RXWIN2, RSSI -88, SNR 13.5[CR][LF]
+CMSG: Done[CR][LF]

See the RX: part? That is the hex bytes that represent the downlink payload. If you separate this out into a string called HEXString, for instance, you could convert this to an ASCII again using code a bit like this:

char hexarray[8];
HEXString.toCharArray(hexarray, 8);

String ASCIIValue = "";

for (i = 0; i < HEXString.length(); i += 3) {
    char val = hexarray[i] > 0x39 ? (hexarray[i] - 'A') * 16 : (hexarray[i] - '0') * 16;
    val += hexarray[i+1] > 0x39 ? (hexarray[i+1] - 'A') : (hexarray[i+1] - '0');
    ASCIIValue += val;
  }

Other useful commands

There are other useful commands to interact with the modem, summarized below:

  • AT+DR queries the datarate, and AT+DR=x sets it. DR=0 is the slowest, but the longest range, while DR=3 is the fastest, but with shorter range.
  • AT+ADR queries the automatic datarate state, and AT+ADR=x sets it ON or OFF. The modem will have the datarate set by the network unless you turn this OFF (and then you can use AT+DR, above).
  • AT+LOWPOWER puts the modem to sleep. You will need to use this to save battery life. The modem will wake up again as soon as any character is sent on UART again, and can take 5 ms to do so e.g.:
mySerial.write("A"); // Send any character to wake-up the modem
delay(5); // Wait for the modem to wake up
mySerial.write("AT+CMSG=Hello");