NB-IoT Arduino Shield from AIS (Thailand) First Impressions

Today I received my NB-IoT Arduino Shield for AIS (Thailand). Here is a "pinout" photo of the shield.

My shield looks just like the one above, for the most part. I'll post another photo of the actual device later.

When I received the shield in the mail, I went immediately to a local AIS office in the mall to have it activated.

Of course, none of the regular service people at the counter knew anything about registering this device with AIS; and at first they told me I could not register it because I had to also have an AIS SIM card and mobile number. Naturally, I told them (very strongly) that was absolutely not the case and the "SIM" was in the board which you could clearly see in the form of an "IEMI" and serial number on the bottom of the device. The counter people were nice, despite some older, foreign guy insisting, in their language (spoken as a non-native speaker), that I did not need an AIS SIM card and that they could register this device without one.

Patiently, and after about 30 minutes of "not much real progress" at the counter, the counter staff disappeared to the back room (to escape my lecturing them that I did not need a mobile SIM card); and after about 10 minutes had passed, the service counter team returned with a "manager", who knew exactly how to register it and explained to the counter team, in a mentoring way, step-by-step, how to register and activate my NB-IoT device.

During that time, the manager (who was a great guy and very helpful) told me, in reply to me asking a number of questions, that only around one person a month registers a device like this, on average, and they are mostly students. So, I thought then, it surely looked funny to them to see a retired techie like me registering this device.

After running some errands on my motorcycle, I got home and immediately inserted the shield into my Arduino; checked that I had installed the AIS libraries (earlier I did the prep work); started my very simple UDP server I wrote in Python for testing purposes on a server in the USA.

Here is a link to the AIS_NB_BC95 libs on GitHub, with the example sketch:

https://github.com/AIS-DeviceInnovation/AIS_NB_BC95

Note: I think it is very cool that the Thais are using GITHub to manage all these libs and test code.

Here was the sketch for the Arduino:

#include "AIS_NB_BC95.h"

String apnName = "devkit.nb";

String serverIP = "udp_server_ip_here";          // My Server IP back in the USA
String serverPort = "upd_port_number_here";     // My Server Port back in the USA

String udpData = "HelloWorld";

AIS_NB_BC95 AISnb;

const long interval = 5000;  //milliseconds
unsigned long previousMillis = 0;

long cnt = 0;
void setup()
{ 
  AISnb.debug = true;
  
  Serial.begin(9600);
 
  AISnb.setupDevice(serverPort);

  String ip1 = AISnb.getDeviceIP();  
  delay(1000);
  
  pingRESP pingR = AISnb.pingIP(serverIP);
  previousMillis = millis();

}
void loop()
{ 
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval)
    {
      cnt++;     
           
      // Send data in String 
      UDPSend udp = AISnb.sendUDPmsgStr(serverIP, serverPort, udpData+" "+String(cnt));
   
      //Send data in HexString     
      //udpDataHEX = AISnb.str2HexStr(udpData);
      //UDPSend udp = AISnb.sendUDPmsg(serverIP, serverPort, udpDataHEX);
      previousMillis = currentMillis;
  
    }
  UDPReceive resp = AISnb.waitResponse();
     
}

Here was my "test setup" Python code:

"""
NB-IoT First Test Code, Simple Authentication Override, version 0.2
Listens on a port for UDP, simple authentication, echo back with unix time
Neo www.unix.com
Jan 2020
"""
import socket
import sys
import time

# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
port = 13131
# Bind the socket to the port
server_address = ('www.mytestserver.com', port)
print >>sys.stderr, 'starting up on %s port %s' % server_address
sock.bind(server_address)
password = "blah_blah_blah\n"
authenticated = True // override simple authentication for testing
receivepw = True // override simple authentication for testing
lastsent = 0

while True:
    print >>sys.stderr, '\nwaiting to receive message'
    now = time.time()

    data, address = sock.recvfrom(4096)
    site = address
    if data:
        lastsent = time.time()
        if authenticated == False and receivepw == False:
            sent = sock.sendto("Password: ", address)
            receivepw = True
        elif receivepw == True and authenticated == False:
            if data == password:
                sent = sock.sendto("Authenticated\n", address)
                authenticated = True
            else:
                sent = sock.sendto("Password:\n", address)
            print >>sys.stderr, 'a: sent %s bytes back to %s' % (sent, address)
        elif authenticated == True:
            received = "You sent: " + data
            sent = sock.sendto(received, address)
            data = time.time()
            data = "Unix Time: " + str(data)+"\n"
            sent = sock.sendto(data, address)
            print >>sys.stderr, 'b: sent %s bytes back to %s' % (sent, address)
        else:
            sent = sock.sendto("Error\n", address)
            print >>sys.stderr, 'c: sent %s bytes back to %s' % (sent, address)

Well, it would not connect.... many tries... no connection to the AIS network.....

The Arduino serial monitor showed it kept getting stuck on this line in the AIS lib code (debug message):

19:03:18.470 -> # Connecting NB-IoT Network..................................................

I posted a question on the AIS NB-IoT group on FB and went to the local fish market; and got some replies but nothing really technical, just a confirmation that another person had the same results. Well, "misery loves company", as they say.

Then, eating some local fish at my desk, I decided to connect the device to my laptop and go outside to the "city side" balcony in my condo.

No luck.

I put the test setup on my desk, and continued eating, then noticed on my UDP server log output, that it had connected and pinged a few times and stopped. Yea!

Next, now feeling like I was getting somewhere, I took my setup out to the ocean facing balcony, and ... yea! it connected.

So, I immediately realized it was a signal quality and location issue; and so I walked around the building, in the parking garage, running the test ping program from AIS.

In the next post, I'll post some of the output from the Arduino serial monitor, for completeness.

The Bottom Line / Initial Impressions:

  • This NB-IoT device has low signal quality from high floors in my building (over 20 floors high).
  • This NB-IoT device has low signal signal quality from underground parking (one level underground) in my building, except near the entrance ramps in my area.
  • This NB-IoT device has low signal quality between the buildings and there were a number of "dead areas" where the signal was lost and not recovered.
  • This NB-IoT device works OK at the ground level of the building (for the most part) and at ground level in most open areas.
  • This NB-IoT device would disconnect from the network when in a dead area and it mostly required a device restart to reconnect. Note: This issue could be mitigated by adding a few lines of code in the sketch to attempt to reconnect to the network after some timeout, or based on reading the signal strength on the device.

Next Steps:

  • Read the AIS Library for this device and see if I can get the signal strength from the device and use the signal strength in the code for connection management and status messages. If so, this is good. If not, request this modification from AIS tech support, or search the network and see if can get it for the NB-IoT chipset on the device.

Will post some survey "ping" samples from the device to my test server after I transfer the data from my laptop to my desktop.

In a nutshell, this NB-IoT reminded me of the "good ole' days" when mobile phone quality was quite poor (in the early days of mobile phones, because they become commonplace) and connections to the network were unreliable. I would not use this, in its current form, for any mission critical application, because it is not (yet)reliable and the signal quality is low / weak in my areas-of-interest (AOI). I guess I could get an SMC power pre-amplifier in the frequency range or a higher gain antenna and see if that helps :slight_smile:

Update:

Yes, the AIS library has a method to get the signal, so I will modify the Arduino test sketch to use the signal strength, after I do some surveys to determine how the signal strength effects the connection.

struct signal
{
	String csq;
	String rssi;
	String ber;
};
signal getSignal();

More later....

Reference Material:

Here is the BC95 AT Commands Manual I am working with; but frankly speaking I am having trouble setting many of the commands to return data. I'm wondering if some of the functionality of the chip has been disabled?

Here are a few photos I took today.

The actual shield I am using for testing:

The actual shield I am using for testing showing Arduino underneath the shield:

Testing on balcony:

Simple python UDP server for NB-IoT initial tests output:

waiting to receive message
1578122393.18: received 37 bytes from ('119.31.119.XXX', YYYYY)
1578122393.18: my signal csq: 22 rssi: -69dBm seq: 1
1578122393.18: sent 25 bytes back to ('119.31.119.XXX', YYYYY)

waiting to receive message
1578122398.14: received 37 bytes from ('119.31.119.XXX', YYYYY)
1578122398.14: my signal csq: 23 rssi: -67dBm seq: 2
1578122398.14: sent 25 bytes back to ('119.31.119.XXX', YYYYY)

waiting to receive message
1578122403.25: received 37 bytes from ('119.31.119.XXX', YYYYY)
1578122403.25: my signal csq: 25 rssi: -63dBm seq: 3
1578122403.25: sent 25 bytes back to ('119.31.119.XXX', YYYYY)

waiting to receive message
1578122408.17: received 37 bytes from ('119.31.119.XXX', YYYYY)
1578122408.17: my signal csq: 23 rssi: -67dBm seq: 4
1578122408.17: sent 25 bytes back to ('119.31.119.XXX', YYYYY)

waiting to receive message
1578122413.29: received 37 bytes from ('119.31.119.XXX', YYYYY)
1578122413.29: my signal csq: 23 rssi: -67dBm seq: 5
1578122413.29: sent 25 bytes back to ('119.31.119.XXX', YYYYY)

waiting to receive message
1578122418.24: received 37 bytes from ('119.31.119.XXX', YYYYY)
1578122418.24: my signal csq: 23 rssi: -67dBm seq: 6
1578122418.24: sent 25 bytes back to ('119.31.119.XXX', YYYYY)

waiting to receive message
1578122423.36: received 37 bytes from ('119.31.119.XXX', YYYYY)
1578122423.36: my signal csq: 23 rssi: -67dBm seq: 7
1578122423.36: sent 25 bytes back to ('119.31.119.XXX', YYYYY)

waiting to receive message
1578122428.32: received 37 bytes from ('119.31.119.XXX', YYYYY)
1578122428.32: my signal csq: 23 rssi: -67dBm seq: 8
1578122428.32: sent 25 bytes back to ('119.31.119.XXX', YYYYY)

The simple python code:

"""
NB-IoT First Test Code
Listens on a port for UDP, simple authentication, echo back with unix time
Version 0.11 4 January 2020
Neo wwww.unix.com
"""
import socket
import sys
import time

# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# sock.setblocking(False)
port = 22222          
# Bind the socket to the port
server_address = ('www.myudpserver.com, port)
print >>sys.stderr, 'starting up on %s port %s' % server_address
sock.bind(server_address)
password = "my_simple_password\n"
authenticated = True
receivepw = True
lastsent = 0

while True:
    print >>sys.stderr, '\nwaiting to receive message'
    now = time.time()

    data, address = sock.recvfrom(4096)
    print >>sys.stderr, str(time.time()) + \
        ': received %s bytes from %s' % (len(data), address)
    stuff = str(time.time()) + ": " + data
    print >>sys.stderr, stuff

    # override simple authentication
    if data:
        lastsent = time.time()
        if authenticated == False and receivepw == False:
            sent = sock.sendto("Password: ", address)
            receivepw = True
        elif receivepw == True and authenticated == False:
            if data == password:
                sent = sock.sendto("Authenticated\n", address)
                authenticated = True
            else:
                sent = sock.sendto("Password:\n", address)
            print >>sys.stderr, 'a: sent %s bytes back to %s' % (sent, address)
        elif authenticated == True:
            received = "You sent: " + data
            sent = sock.sendto(received, address)
            data = time.time()
            data = "Unix Time: " + str(data)+"\n"
            sent = sock.sendto(data, address)
            print >>sys.stderr, str(
                time.time())+': sent %s bytes back to %s' % (sent, address)
        else:
            sent = sock.sendto("Error\n", address)
            print >>sys.stderr, str(time.time())+' : sent %s bytes back to %s' % (sent, address)

Still waiting for Arduino GPS shield to arrive from China.

Another pic, this time with 9v battery for fun. I have a bench supply as well, but I usually don't take that out and put it on my balcony :slight_smile:

Update: Answers to Questions (to Me):

Via PM

General Comment (something link): Please add more serial statements in your Arduino sketch to debug.

Reply: In the sketch (see post one) you can see this entry the code:

void setup()
{ 
  AISnb.debug = true;
  
 // ....
}

So, there is already a considerable amount of serial logging built into the AIS NB-IoT library. You can look into the library to see that there is no shortage of serial debugging information in "debug" mode.

Via FB AIS NB-IoT Group

Question: How do we get the IMEI and IMSI from the board?

Reply: These methods are defined and available in the AIS NB-IoT library:

IMEI

String AIS_NB_BC95:: getIMEI()
{
	String out;
	_Serial->println(F("AT+CGSN=1"));
	AIS_NB_BC95_RES res = wait_rx_bc(1000,F("OK"));
	out = res.temp;
	out.replace(F("OK"),"");
	if (out.length() < 7)
	{
		return "";
	}
	out = out.substring(7,out.length());
	res = wait_rx_bc(1000,F("OK"));
	return (out);
}

IMSI

String AIS_NB_BC95:: getIMSI()
{
	_Serial->println(F("AT+CIMI"));
	AIS_NB_BC95_RES res = wait_rx_bc(1000,F("OK"));
	String out = res.temp;
    out.replace(F("OK"),"");
	out = out.substring(0,out.length());
	res = wait_rx_bc(500,F("OK"));
	return (out);
}

Please refer to the AIS NB-IoT library for more details.

https://github.com/AIS-DeviceInnovation/AIS_NB_BC95

It's all there.....

and for the AT commands reference for the BC95:

https://www.quectel.com/UploadImage/Downlad/Quectel_BC95_AT_Commands_Manual_V1.9.pdf

Please review the AIS NB-IoT library before posting comments or sending PMs. Answer to most questions can be found in the AIS NB-IoT library and the BC95 AT command reference manual (links above).

Finally.......

Via FB AIS NB-IoT Group

Comment: Obviously, AIS shop' staff aren't trained to this product. The best contact is mail to : aiap@ais.co.th

Reply: Correct; but for new registrations AIS customers must go to an AIS service center and provide a copy of their ID card or passport to register the device. This cannot be done via email, per AIS policy (so I was told by AIS Call Center).

Yesterday we spent the day out in the car with the AIS NB-IoT device attached to my MacBook Air; looking at the serial monitor via USB and also recording messages back in the USA on my simple Python UDP server.

The bottom line is that this device is good for locating AIS cell towers :wink: :wink: because it only worked when a tower with AIS NB-Iot support was visible (within line-of-site).

This means that this device seems to only work when it is very close to a cell tower and very close to direct line-of-site.

This also explains why this 900 MHz range device works on my sea-side balcony. There is a cell tower in our line-of-site on that balcony, only a few hundred meters away..

However, on the rear balcony, the AIS-NB-IoT device will not connect to the AIS network, and, as expected, there is no cell tower within line-of-site.

When driving around the countryside in Thailand, this device only "worked" when there was an AIS cell tower which supported NB-IoT in near direct line-of-site.

My best rough guess, driving from our condo next to the sea in Jomtien Beach to Hardware House (picking up electrical supplies) in the country side, Rayong province and back (using two different routes), is that this AIS NB-IoT device connected successful to the AIS network approximately 70% of the time. This is just a rough guess because I was driving the car and my wife was looking at the computer, calling out the RSSI readouts and connection status. She really liked that part, I think!

Note to AIS Network Engineers: AIS NB-IoT device would not connect to AIS NB-IoT network at Hardware House in Rayong (or in that important area).

We experienced mixed results with the NB-IoT shield working as it went in and out of network coverage. Sometimes the device did not require a reboot to reconnect after losing the signal, sometimes it did require a reboot to reconnect.

To write code to properly mitigate this (connection management code), I would need the technical parameters from AIS for the network regarding connection timeouts (and other parameters) on their end; but since I only have the specification for the device (the BC95) and not the AIS NB-IoT network.

I have already reached out and sent an email to AIS for this basic timeout value.

Waiting on a reply ...

Soon, I think I will test LoRaWAN including LoRaWAN gateways and devices. More on this later.

Note to AIS network engineering:

In the same building next to the beach, but on the opposite side of the building (the city side), the AIS NB-IoT shield will not connect to the network. In fact, it connects easily on the sea-side of the building, but on the city-side, even though there are many cell towers, the shield has never connected:

############ AIS_NB_BC95 Library by AIS/DEVI V1.0.5 ############
# Reboot Module.
# Module IMEI-->  869405XXXXXXXXX



# Firmware ver-->  
SECURITY,V100R100C10B657SP5

PROTOCOL,V100R100C10B657SP5

APPLICATION,V100R100C10B657SP5

SEC_UPDATER,V100R100C10B657SP5

APP_UPDATER,V100R100C10B657SP5

RADIO,BC95HB-02-STD_900



# IMSI SIM-->  
520039XXXXXXXX



# Connecting NB-IoT Network......................................

############ AIS_NB_BC95 Library by AIS/DEVI V1.0.5 ############
# Reboot Module.
# Module IMEI-->  86940XXXXXXXXX



# Firmware ver-->  
SECURITY,V100R100C10B657SP5

PROTOCOL,V100R100C10B657SP5

APPLICATION,V100R100C10B657SP5

SEC_UPDATER,V100R100C10B657SP5

APP_UPDATER,V100R100C10B657SP5

RADIO,BC95HB-02-STD_900



# IMSI SIM-->  
520039XXXXXXXX



# Connecting NB-IoT Network...........................................................> Disconnected
################################################################
# Device IP: +CGPADDR:0

# Ping Failed
# Get Network Status : Trying
# CSQ Data: +CSQ:28,99

# Get CSQ Signal: csq= 28, rssi= -57, ber= 99


 my signal csq: 28 rssi: -57 dBm 
# Connecting NB-IoT Network...........................................................> Disconnected
################################################################
# >Disconnected
# CSQ Data: +CSQ:29,99

# Get CSQ Signal: csq= 29, rssi= -55, ber= 99


 my signal csq: 29 rssi: -55 dBm 
# Connecting NB-IoT Network...........................................................> Disconnected
################################################################
# >Disconnected
# CSQ Data: +CSQ:29,99

# Get CSQ Signal: csq= 29, rssi= -55, ber= 99


 my signal csq: 29 rssi: -55 dBm 
# Connecting NB-IoT Network...........................................................> Disconnected
################################################################
# >Disconnected
# CSQ Data: +CSQ:28,99

# Get CSQ Signal: csq= 28, rssi= -57, ber= 99


 my signal csq: 28 rssi: -57 dBm 
# Connecting NB-IoT Network...........................................................> Disconnected
################################################################
# >Disconnected
# CSQ Data: +CSQ:29,99

# Get CSQ Signal: csq= 29, rssi= -55, ber= 99


 my signal csq: 29 rssi: -55 dBm 
# Connecting NB-IoT Network...........................................................> Disconnected

At least, we know this was set and AutoConnect is working :slight_smile:

bool AIS_NB_BC95:: setAutoConnectOn()
{
        _Serial->println(F("AT+NCONFIG=AUTOCONNECT,TRUE"));
        AIS_NB_BC95_RES res = wait_rx_bc(1000,F("OK"));
        return(res.status);
}

Note for AIS network engineers:

Here is a very small example of how poorly AIS NB-IoT performs on the East side of my building (pictured above), from my UDP server logs.

In my sketch, every time a UDP message is sent, the sequence number is incremented by one. On the UDP server side, it logs each time it receives a package, including the RSSI and Sequence #:

waiting to receive message
1578313941.2: received 42 bytes from ('119.31.119.163', 33333)
1578313941.2: my signal csq: N/A rssi: N/AdBm   seq: 677
1578313941.2: sent 24 bytes back to ('119.31.119.163', 33333)

waiting to receive message
1578313941.54: received 41 bytes from ('119.31.119.163', 33333)
1578313941.54: my signal csq: 29 rssi: -55dBm   seq: 678
1578313941.54: sent 25 bytes back to ('119.31.119.163', 33333)

waiting to receive message
1578314106.17: received 41 bytes from ('119.31.119.163', 33333)
1578314106.17: my signal csq: 31 rssi: -51dBm   seq: 686
1578314106.17: sent 25 bytes back to ('119.31.119.163', 33333)

waiting to receive message
1578316246.96: received 42 bytes from ('119.31.119.254', 33333)
1578316246.96: my signal csq: N/A rssi: N/AdBm   seq: 759
1578316246.96: sent 25 bytes back to ('119.31.119.254', 33333)

waiting to receive message
1578316263.66: received 42 bytes from ('119.31.119.254', 33333)
1578316263.66: my signal csq: N/A rssi: N/AdBm   seq: 760
1578316263.66: sent 25 bytes back to ('119.31.119.254', 33333)

waiting to receive message
1578317185.86: received 42 bytes from ('119.31.119.254', 33333)
1578317185.86: my signal csq: 30 rssi: -53dBm   seq: 1168
1578317185.86: sent 25 bytes back to ('119.31.119.254', 33333)

I find it interesting (but not very interesting) that AIS coverts the BC95 RSSI / CSQ of 99 (undetectable) to "N/A" in the AIS library, but it can still (sometimes) transmit / receive even at 99:

... anyway, I hope AIS network engineers find this helpful in their analysis of this area.

This issue only happens on the East side (city side) of this building, the West side (ocean facing side), does not experience this problem and no UDP messages are lost.

I'll leave this NB-IoT shield on the East side of the building for the next 24 hours, transmitting and receiving on the NB-IoT network, so AIS can troubleshoot their network:

1 Like

Update:

Since writing AIS, I have not (yet_ received any support or assistance, either from the main call center or the direct email into the NB-IoT team.

I'm close to putting this AIS-NB-IoT project on the shelf (since it was only meant to be a "quick impression" test), and moving on to (1) the SIM5360E 3G Shield and a scheduled (2) LoRaWAN gateway test on Thursday.

My initial impression with AIS NB-IoT is that the service and network coverage is not ready for "serious" Arduino shield development; and so it is better to move on to LoRa testing and SIM5360E_3G testing.

NB-IoT (at least this in the context of these test results) can be summarized as a line-of-site, low data rate, low bandwidth messaging technology with spotty network coverage, at least the network I tested this past weekend.

It's time to move on to other tests and put the AIS NB-IoT shield on the shelf until the coverage and support improves, or I decide that LoRaWAN or the .SIM5360E_3G_Shield do not perform well, comparatively speaking.