Tag Archives: hologram

RAK8213 – The New Mini-PCIe Card For NB-IoT and LTE Cat M1

A China-based manufacturer called RAK Wireless has released the RAK833 LoRaWAN gateway module a couple months back. This has already been used hugely to create a gateway for ‘The Things Network’. Now they’re back with the new RAK8213, an NB-IoT and LTE Cat M1 module in the same mini-PCIe form factor as the RAK833. The RAK mini-PCIe card is constructed around the Quectel BG96 module, which provides both NB-IoT and LTE Cat M1 along with GNSS (GPS, GLONASS, Galileo, or BeiDou) support.

The RAK8213 mini-PCIe Module
The RAK8213 mini-PCIe Module

The mini-PCIe form factor is often associated with laptop computers, but recently we’ve started seeing that some single-board computers targeted at the maker market are also featuring this form. The Pine H64 single board computer is an example of it. Besides that, we’ve also noticed the rise of other mini-PCIe modules, such as the UP AI Core, or the PicoEVB, also aimed for makers.

This card can be added to netbooks/notebooks or routers in the mini-PCIe socket. It can be used for remote monitoringsmart meter reading, and so on. The user manual for this card basically explains how the user can send AT commands over USB or UART to the card in Windows, and how to set up the board with Hologram IoT SIM card.

RAK8213 is not the first NB-IoT/eMTC mPCIe card on the market. There are also some SIMCom SIM7000 based modules for about $30. However, it should be noted that the new RAK8213 works globally but SIM7000A / SIM7000C / SIM7000E work in specific regions, namely America, China and Europe.

RAK8213 mini PCIe card key specifications:

  • Wireless Connectivity Module: Quectel BG96 with LTE Cat. M1 (eMTC), LTE Cat. NB1 (NB-IoT), EGPRS, and GNSS
  • Global bands support :  
    • FDD-LTE – B1/ B2/ B3/ B4/ B5/ B8/ B12/ B13/ B18/ B19/ B20/ B26/ B28
    • TDD-LTE – B39 (for Cat M1 only)
    • EGPRS – 850/900/1800/1900Mhz
  • Max Data Rate: Cat M1: 375 kbps (UL/DL); Cat NB1: 32 kbps DK, 70 kbps (UL)
  • Other I/O:
    • Micro SIM slot
    •  u.FL connectors for cellular and GNSS
    •  mPCIe connector with USB 2.0, I2C, UART, and PCM
  • Misc: LEDs for network and power status
  • Dimensions: 51 x 30.1 mm

RAK8213 mPCIe card is sold for $39.99 plus shipping on Aliexpress, and optional accessories are also offered for $10, and a Hologram SIM card for $7. More information about the RAK 8213, the data sheet and schematics for the board are available at RAK Wireless site, along with a user manual for the evaluation board and the card.

Cellular IoT with Blynk & Hologram

Use a $9 GSM module & the Hologram network to remotely control any Arduino with Blynk App.

Blynk is an awesome tool that allows you to build drag and drop apps for controlling hardware remotely! Its perfect for quickly creating useful IoT projects. This tutorial will run you through setting up Blynk for cellular control using an Arduino and a $9 GSM board.

Hologram.io is a cellular network provider perfect for makers. At $0.60 /mo plus $0.40 per mb, you’ll have plenty of data for most IoT projects.

Cellular IoT with Blynk & Hologram – [Link]

Arduino-Based Two-Way Pager

This Arduino-based pager by  Mike Schaus will allow you to send and receive real SMS text messages. This messaging device has its own SIM card and phone number.

In order to build this project you need the following parts:

And you will need to use this software to run the project: Hologram Data Router.

This project was made possible as part of Hologram’s Hacker-In-Residence program, The Hologram Global SIM Card allows you to connect you IoT device everywhere. Paired with a powerful device management platform and API. It provides a cellular data service that works with any device that accepts a SIM card. In addition it is totally inexpensive.

GSM shield, the Hologram things, and Arduino stacked on top of each other made a good combination to build such a project. For powering the project, Mike had used a 9V battery as an option, and still, powering from USB is possible.

Mike had designed this project so it could be used by children instead of a real cell phone, or it could be used as an “SOS” button for someone working alone outdoors or even exercising.

Check this video to know how this project works:

The amazing thing about Adafruit LCD shield that it only uses 2 pins of Arduino since it works over the I2C bus, which results with many places left for future features.

This is the schematics of the project: It is super easy, the wires mean putting the pieces on top of each other.

And here is the Arduino code used:

#include <GSM.h>

#define PINNUMBER ""

// include the LCD library code:
#include <Wire.h>
#include <Adafruit_RGBLCDShield.h>
#include <utility/Adafruit_MCP23017.h>

// The shield uses the I2C SCL and SDA pins. On classic Arduinos
// this is Analog 4 and 5 so you can't use those for analogRead() anymore
// However, you can connect other I2C sensors to the I2C bus and share
// the I2C bus.
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

// These #defines make it easy to set the backlight color
#define OFF 0x0
#define ON 0x1

// make the arrow special character on the LCD
const byte arrow[8] =
 B00000, B00000, B01000, B01100, B01110, B01100, B01000, B00000

// initialize the GSM library instance
GSM gsmAccess(false); // include a 'true' parameter for debug enabled
GSM_SMS sms;

// char array of the telephone number to send SMS
// change the number 12125551212 to a number
// you have access to
char remoteNumber[20]= "12125551212";

// Array to hold the number a SMS is retreived from
char senderNumber[20];

// char array of the possible outgoing messages to choose from the menu
char* responses[]={"Mike=Awesome!", "Yes", "No", "Howdy!"};
//#define NUMRESPONSES 4 // if someone knows how to calculate this instead, I'm all ears
#define NUMRESPONSES (sizeof(responses)/sizeof(char *)) // thanks to Steve Kemp's comment!

int position=-1; // this way the first button press will always show first option of the menu

int inByte = 0; // incoming serial byte for keyboard interface

boolean backlight = true; // track backlight status for toggling

unsigned long previousMillis = 0; // will store last time messages were checked
#define CHECKINTERVAL 1500 // how often to check for text messages

void setup() {
  // put your setup code here, to run once:

  // initialize serial communications
  Serial.println(F("SMS Message Sender -- starting up..."));

  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);

  // Print a message to the LCD
  lcd.print(F("Hello, Hologram!"));
  lcd.setCursor(0, 1);
  lcd.print(F("Starting up..."));

  // set up the arrow character for display
  lcd.createChar(0, arrow);

  // connection state
  boolean notConnected = true;

  // Start GSM shield
  // If your SIM has PIN, pass it as a parameter of begin() in quotes
    if(gsmAccess.begin(PINNUMBER)==GSM_READY) {
      notConnected = false;
      Serial.println(F("GSM is connected because you are so awesome"));
      Serial.println(F("Waiting for messages, or send with \"s\""));


      Serial.println(F("Not connected"));
      lcd.print(F("Not connected"));

// this is the menu system function
void showResponses() {
//  Serial.println(position); // only for debugging menu system

  // make sure cursor position is legal
  if (position<0) position=0;
  if (position>NUMRESPONSES-1) position = NUMRESPONSES-1;

  // write current selection and next option if there is another option
  lcd.write(0); //arrow character
  if (position < NUMRESPONSES-1) {
    lcd.print(" ");

void homeScreen() {
  lcd.print("SMS Messenger!");
  lcd.print("Ready; up/dn snd");

  position=-1; //reset response selection

void receiveSMS(){
  char c;

  // If there are any SMSs available()
  if (sms.available()) {
    Serial.println("Message received from:");

    // Get remote number
    sms.remoteNumber(senderNumber, 20);

    backlight = true;

    // An example of message disposal
    // Any messages starting with # should be discarded
    if (sms.peek() == '#') {
      Serial.println("Discarded SMS");

    // Read message bytes and print them
    // because sms.read only returns one character at a time
    int i=0;
    while (c = sms.read()) {
      if (i==17) lcd.setCursor(0, 1); // move to next line if needed
      if (i<33) lcd.print(c); // don't try to print more than 32 chars just in case

    Serial.println("\nEND OF MESSAGE");

    // Delete message from modem memory
    Serial.println("MESSAGE DELETED");

    // wait for right button to acknowlege before letting program continue
    boolean acknowledged = false;
    while(!acknowledged) {
      uint8_t buttons = lcd.readButtons();
      if (buttons & BUTTON_RIGHT) acknowledged = true;
      delay(50); //short delay for troubleshooting -- without this it behaves strangely
    delay(400); // prevent multiple presses in a row

// function to show message options in the serial monitor
void printResponseOptions(){
  for(int i=0; i<NUMRESPONSES; i++){

void sendSMS(const char* txtMsg){

  Serial.print("Message to mobile number: ");

  // print sms text info

  // send the message
  // next, add a signature to the chosen message
  sms.print(" --Be sure to connect with me on my blog http://mschausprojects.blogspot.com");
  // call endSMS function to finish sending; it will return 1 if successful
  if (sms.endSMS()==1) {
  else {

void loop() {
  // put your main code here, to run repeatedly:

  uint8_t buttons = lcd.readButtons();

  if (buttons) {
    if (buttons & BUTTON_UP) {
      backlight = true;
    if (buttons & BUTTON_DOWN) {
      backlight = true;
    if (buttons & BUTTON_LEFT) {
      backlight = true;
    if (buttons & BUTTON_RIGHT) {
      backlight = !backlight; // toggle the backlight state
      if (backlight) lcd.setBacklight(ON);
      else lcd.setBacklight(OFF);
      homeScreen(); // have to write to screen after turning light off, otherwise it goes blank
    if (buttons & BUTTON_SELECT) {
      // make sure cursor selected position is legal
      if (position<0) position=0;
      backlight = true;
    delay(200); // prevent multiple presses in a row

  // this is for serial interface only, not related to LCD and buttons
  // send a message when I type "s" in serial monitor
  // then wait for my selection of the response number
  if (Serial.available() > 0) {
    inByte = Serial.read(); // get incoming byte
    if (inByte == 's') {

      while (Serial.available() > 0) {  // clear the keyboard buffer just in case
        char junk = Serial.read();
      while (Serial.available() == 0) ;  // Wait here until input buffer has a character
      inByte = Serial.parseInt();
      // would want to check for valid choice here to be more robust

  // check for new messages only once every few seconds to keep interface more responsive
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= CHECKINTERVAL) {
    previousMillis = currentMillis;
    receiveSMS(); // takes about 26ms when there are no messages


More details about this project are available on hackster.io and Mike’s own blog post. You can learn more about his projects on the same blog.