BC95 Board

NB-Iot with the BC95 with arduino

Hardware hacking with the mobile c-lab

Last weekend the c-base and friends team had a great time doing some hacking with Narrow Band IoT (NB-IoT) from Deutsche Telekom at the nbiot-hackathon at hub:raum. We could put our hands on the BC95 chip, a dev board and access to the Telekom test network. Beside hacking we had a great time with funny hats and our obligatory overalls.

The BC95 Board

The board we could use was the BC95-B8 board which we mounted on a development board with a support controller and serial converter. Beside the board setup we also soldered a PCB with some sensors and a Teensy board to control the BC95 and the sensors.



The dev board itself has a RS232 converter to give access via “normal” RS232 connectors. This is convenient for older laptops or desktops but luckily they also give you access via 3.3V pegel to the same UART interface. The pins are pre soldered on a 10 pin header so it’s easy to connect this to arduino or Raspberry PI via the serial connection. As you can see in the picture it is pin 1,2 and 6. No level converter necessary.

AT- Command Set

AT      // First handshake will be used for out speed detection may be result in ERROR
AT      // Repeat sending "AT" until you receive an "OK"
AT+NRB  // Reboot the device in order to have a clean start

//wait for the reboot

AT+NBAND=8                        // Set the communication band in this case 900Mhz
AT+CGDCONT=1,"IP","NBIOT.Telekom" // Sets the APN (Access Point Name)
AT+CEREG=2                        // Connect to the IoT Core
AT+CFUN=1                         // Power on the module
AT+COPS=1,2,"12345"               // Force the module to connect to the network

// wait for the network connection (some seconds)

AT+NPING=                          // Ping a server to check if it works
AT+NSOCR=DGRAM,17,16666                   // Open a UDP socket
AT+NSOST=0,ansi.23-5.eu,16666,4,414E5349  // Send out the data

Line 1,2

The serial protocol can be any speed at 8N1, the board auto detects the speed at first communication, therefore you need to send the AT command several times (normally 2) to set the speed. Normally the first AT command is answered with ERROR and the second one with AT. Make sure you get an OK before you continue.

Line 3

In order to get a clean setup we first reboot the board with “NRB”. It takes some seconds and it will come back with OK.

Line 7

Depending on your network you need to set the band with “NBAND”. The Telekom test network is on 900 MHz so we go with 8. Other bands are 5 (850 Mhz) and 20 (800 MHz).

Line 8

Depending on your setup and provider you need to set the APN with the CGDCONT command.

Line 9

Connect to the IoT Core

Line 10

Power on the module

Line 11

Connect to the network. This can take several seconds even a minute. You can always check the connection with at+cgatt?” and check for “+CGATT:1”. You can double check the existing connection by asking for the IP address which is assigned to you by sending “at+cgpaddr=1” to get for example “+CGPADDR:1,”.

Line 15

Ping a server to test everything is fine. (In this case the google DNS server)

Line 16

Open an UDP socket to receive answers. In our case the DGRAM and 17 are mandatory but the port you are using (in our case 16666) is up to you.

Line 17

Send your UDP data package. First parameter is the out port (0). The second one is the address you want to send the data to (ip or name). Third one is the receivers port (16666). Fours is the amount of data you want to send (keep it below 100 bytes) and the last one is your data in hex notification. I recommend asciitohex.com to convert a string you want to send.


uint8_t sensordata[10];

void setup() {
  while (!Serial) {}
  while (!Serial1) {}
  Serial.println("c-base starts");

void sensorfake(){
  for (int i = 0; i < 10; i++){
    uint8_t d = sensordata[i];
    sensordata[i] = d+1;

void sendit(String in) {
  while(Serial1.available() > 0){
    if(Serial1.available() > 0){
      byte c = Serial1.read();

void initModem(){

void sendData(){

  String datastring = "AT+NSOST=0,ansi.23-5.eu,16666,11,01";

  for(uint8_t i = 0; i < 10; i++){
    String hexstring = String(sensordata[i], HEX);
    if(hexstring.length() < 2){
      hexstring = "0" + hexstring;


void loop() {

This arduino code is really a fast and ugly hack for the hackathon in order to send out the data. It does not listen for the AT returns or anything else. So this is only an example on how NOT to do coding but it worked for the hackathon.

5 Replies to “NB-Iot with the BC95 with arduino”

  1. Hi Ansi, I will use your blog as a reference to my akorIoT customers. akorIoT CB is world’s first NB-IoT adapter with the freedom to select other cellular radios out of the Cx range without a SIM lock. You can also select any MCU kit with an Arduino compatible R3 expansion slot. “akor” is the Proto-Celtic word for “open”. http://www.akoriot.com
    We offer the shield with Quectel BC95. BG96, UG,95, UG96, EG91, EG95 and M95. Our best seller is the BG96 because it supports GPRS, NB-IoT and LTE-Cat-M on 14 bands worldwide.
    All our shields are 100% pin compatible with the origin GSM/GPRS shield for Arduino. The code for GSM will run, but any code for cellular modules and Arduino is full of bugs. Everybody makes a copy from everybody including the mistakes. An AT command without to wait for the answer is an absolute no go.
    However, we prefer STM32 Nucleo with C Complier instead of Arduino. akorIoT + Nucleo = ready working prototype.
    I wish you further happy coding.

  2. Hello Ansi,

    I have a question regarding UART interface connectivity.

    “As you can see in the picture it is pin 1,2 and 6.”

    According to the documentation, pin 1 is a Rx, pin 6 is a Tx and pin 2 is a ring indicator.
    Probably pin 3 GND should be connected instead of pin 2?

    Pin No. Signal I/O Description
    1 RXD DI Receive data
    2 RI DO Ring indicator
    3 GND Ground
    4 TXD3 DO UART3 transmit data
    5 RXD3 DI UART3 receive data
    6 TXD DO Transmit data
    7 DCD DO Data carrier detection
    8 CTS DO Clear to send
    9 DTR DI Data terminal ready
    10 RTS DI Request to send

  3. Hi Ansi. Thank you for your review.

    One question: Did you really been able to send packets to a “host URL”?
    I´m tryint it and I can´t.
    Sending works fine when I put the host IP, but reports an error when I put the host URL.

    Thank you!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.