Internet of Things for RF Noise Measurement
Foreword
This post will serve as the final report for the project I’ve been working on for the past couple of months. Hopefully this will be a complete, detailed and precise documentation of the whole process that led to a successful poster presentation earlier this week. I will also do my best to cover the work done by my colleague and team member, who implemented the cloud infrastructure, backend and android application for the project. However, later on I will add a link to his report in this post so that precise details about his work can be accessed as well.
Introduction
Some time ago, while researching material regarding the Radio Frequency spectrum and possible Internet of Things applications, I stumbled upon this article written by Mark A. McHenry, Dennis Roberson and Robert J. Matheson, published in the IEEE Spectrum website. In the article, the authors make a very interesting point regarding RF noise and the Internet of things: the forecasted boom for IoT devices implies a drastic increase in operating wireless devices, due to which the RF noise levels around us are bound to increase dramatically. RF noise is undesirable because it can cause interference to communications, it increases the cost of deploying new communications systems (shielding against noise), and ultimately RF pollution is usually expensive (in time and resources) and hard to trace. However, in addition to the above point, the authors mention that:
“[…] there hasn’t been a systematic study of radio-frequency noise in the United States since the mid-1970s, when the Institute for Telecommunication Sciences (ITS), a part of the National Telecommunications and Information Administration, last monitored federal use of the radio spectrum. [..]”
Performing this kind of study is usually a difficult task that requires expensive equipment, dedicated manpower and personnel with a certain level of expertise. But perhaps the most critical aspect to this whole situation is data regarding RF noise today. The authors close the article saying:
Our lack of the most basic data on the extent of the problem is unacceptable. We need that data and also a better understanding of the role that noise plays in wireless communications before we can strike the right balance between the costs and benefits of noise suppression. With the exponential increase in the number of noise-generating devices and of wireless systems, RF pollution will become a very expensive problem—unless we act now.
This particular problem served as the starting point for this project’s main objective. IoT, as an emerging and versatile technology, could be an interesting approach to help fulfill the need to devise an effective way of collecting RF noise data in order to conduct these kinds of studies.
Objectives
Even though the article cited above targets IoT as a future cause for Radio Frequency noise, it could also provide a viable solution for RF Noise data acquisition. Hence, the main objective of this project was to propose an IoT solution for RF Noise measurement. In order to produce a Proof of Concept implementation, the project was scoped towards measuring RF noise generated by Mobile Wireless Communications.
IoT solution
One of the most interesting aspects of IoT today is the wide availability of hardware available for these kinds of applications. The Maker movement has sprouted marketplaces such as Adafruit, where one can obtain anything from resistors to purpose and platform-specific sensors for IoT. Also, from my previous entries you might know that for this Internet of Things course we were required to obtain certain kits and components.
Even though you can buy cellular-enabled boards that would serve the main purpose of measuring mobile wireless signals, for the sake of being able to measure different kinds of signals the following custom sensor circuit was designed:
However, due to some technical complications, a different approach for the implementation was taken. The sensor’s readings were simulated using an Intel Edison board. You can read all about this in my previous blog post. The Edison’s source code for simulating the RF input is posted below:
[code language=cpp]
char* possibleMeasurements[] = {“0000″,”0001″,”0010″,”0011”, “0100”, “0101”, “0110”, “0111”, “1000”, “1001”};
void setup() {
//Start Serial Console
Serial.begin(9600);
//Setup ditital pins as Outputs
pinMode(13, OUTPUT); //This will flash a board led indicating transmission
pinMode(2, OUTPUT); //This will be the most significant bit connectig to the NodeMCU’s D1 pin
pinMode(4, OUTPUT); //This will be the second most significant bit connectig to the NodeMCU’s D2 pin
pinMode(7, OUTPUT); //This will be the second least significant bit connectig to the NodeMCU’s D3 pin
pinMode(8, OUTPUT); //This will be the least significant bit connectig to the NodeMCU’s D4 pin
}
void loop() {
// put your main code here, to run repeatedly:
delay(100);
char* rfMeasurement = possibleMeasurements[random(0,10)];
//Serial.println(rfMeasurement);
//Turn on indicator LED
digitalWrite(13, HIGH);
if(rfMeasurement==”0000″){
digitalWrite(2, LOW);
digitalWrite(4, LOW);
digitalWrite(7, LOW);
digitalWrite(8, LOW);
Serial.println(“No Measurement”);
}
else if(rfMeasurement==”0001″){
digitalWrite(2, LOW);
digitalWrite(4, LOW);
digitalWrite(7, LOW);
digitalWrite(8, HIGH);
Serial.println(“-70 dBm”);
}
else if(rfMeasurement==”0010″){
digitalWrite(2, LOW);
digitalWrite(4, LOW);
digitalWrite(7, HIGH);
digitalWrite(8, LOW);
Serial.println(“-60 dBm”);
}
else if(rfMeasurement==”0011″){
digitalWrite(2, LOW);
digitalWrite(4, LOW);
digitalWrite(7, HIGH);
digitalWrite(8, HIGH);
Serial.println(“-50 dBm”);
}
else if(rfMeasurement==”0100″){
digitalWrite(2, LOW);
digitalWrite(4, HIGH);
digitalWrite(7, LOW);
digitalWrite(8, LOW);
Serial.println(“-40 dBm”);
}
else if(rfMeasurement==”0101″){
digitalWrite(2, LOW);
digitalWrite(4, HIGH);
digitalWrite(7, LOW);
digitalWrite(8, HIGH);
Serial.println(“-30 dBm”);
}
else if(rfMeasurement==”0110″){
digitalWrite(2, LOW);
digitalWrite(4, HIGH);
digitalWrite(7, HIGH);
digitalWrite(8, LOW);
Serial.println(“-20 dBm”);
}
else if(rfMeasurement==”0111″){
digitalWrite(2, LOW);
digitalWrite(4, HIGH);
digitalWrite(7, HIGH);
digitalWrite(8, HIGH);
Serial.println(“-10 dBm”);
}
else if(rfMeasurement==”1000″){
digitalWrite(2, HIGH);
digitalWrite(4, LOW);
digitalWrite(7, LOW);
digitalWrite(8, LOW);
Serial.println(“0 dBm”);
}
else if(rfMeasurement==”1001″){
digitalWrite(2, HIGH);
digitalWrite(4, LOW);
digitalWrite(7, LOW);
digitalWrite(8, HIGH);
Serial.println(“+10 dBm”);
}
else {
digitalWrite(2, HIGH);
digitalWrite(4, HIGH);
digitalWrite(7, HIGH);
digitalWrite(8, HIGH);
Serial.println(“ERROR”);
}
delay(2000); //Wait 2s to generate another reading (keeping the current reading on)
//Set all pins to low
digitalWrite(2, LOW);
digitalWrite(4, LOW);
digitalWrite(7, LOW);
digitalWrite(8, LOW);
//Turn of indicator LED
digitalWrite(13, LOW);
}
[/code]
Architecture
For this project, the main idea was to a the NodeMCU module as a sensor node that reads information from a sensor, and then transmit those readings to a Raspberry Pi 2 Model B. This way, several sensor nodes can be deployed and centralize their data using the RPi as a hub. Also, by being an IoT project, the RPi would then push the collected sensor node data to a cloud service, where it would be stored for future analysis and display.
Being an Arduino compatible WiFi-ready device, the NodeMCU is perfectly suited for this purpose due to its low power consumption, connectivity and price. A customized firmware was written and loaded into the node in order to capture the readings provided by the RF sensor. The node transmit the captured data wirelessly to its assigned hub, using the MQTT protocol over a WiFi network.
[code language=cpp]
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <ESP.h>
//Function prototypes
void setup_wifi();
void callback(char* topic, byte* payload, unsigned int length);
void reconnect();
void sleep(int timeInSeconds);
char* readPins();
//Define AP SSID and Password
const char* ssid = “J4D_RPi”;
const char* password = “RaspberryPi”;
//Client and Server Attributes
IPAddress server(192,168,42,1);
WiFiClient espClient;
PubSubClient client(espClient);
//Message attributes
long lastMsg = 0;
char msg[50];
int value = 0;
char* lastReading = “”;
//RF Measurement attributes
int val0=2;
int val1=2;
int val2=2;
int val3=2;
void setup(){
pinMode(BUILTIN_LED, OUTPUT); // Initialize the BUILTIN_LED pin as an output
//Initialize the D1 – D4 as Inputs
pinMode(D1, OUTPUT);
pinMode(D2, OUTPUT);
pinMode(D3, OUTPUT);
pinMode(D4, OUTPUT);
Serial.begin(115200); //Initialize serial console
delay(3000); // Wait for the serial console to start
setup_wifi();
client.setServer(server, 1883);
client.setCallback(callback);
}
void loop(){
if (!client.connected()) {
reconnect();
}
client.loop();
long now = millis();
if (now – lastMsg > 2000) {
lastMsg = now;
++value;
//snprintf (msg, 75, “hello world #%ld”, value);
Serial.print(“Publish message: “);
//Serial.println(msg);
Serial.println(lastReading);
//client.publish(“outTopic”, msg);
client.publish(“RFMeasurements”, lastReading);
sleep(3); //Sleep 3 seconds
}
Serial.print(“Reading RF Level:…”);
lastReading = readPins();
Serial.println(lastReading);
}
void setup_wifi(){
//Wait a bit
delay(10);
//Print AP SSID
Serial.println();
Serial.print(“Connecting to “);
Serial.println(ssid);
//Begin WiFi Connection
WiFi.begin(ssid, password);
//Print …. while awaiting connection
while(WiFi.status() != WL_CONNECTED){
delay(500);
Serial.print(“.”);
}
//Print Connection Information
Serial.println(“”);
Serial.println(“WiFi connected”);
Serial.println(“IP address: “);
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length){
Serial.print(“Message arrived [“);
Serial.print(topic);
Serial.print(“] “);
for (int i = 0; i < length; i++){
Serial.print((char)payload[i]);
}
Serial.println();
// Switch on the LED if an 1 was received as first character
if ((char)payload[0] == ‘1’) {
digitalWrite(BUILTIN_LED, LOW); // Turn the LED on (Note that LOW is the voltage level
// but actually the LED is on; this is because
// it is acive low on the ESP-01)
} else {
digitalWrite(BUILTIN_LED, HIGH); // Turn the LED off by making the voltage HIGH
}
}
void reconnect(){
// Loop until we’re reconnected
while (!client.connected()) {
Serial.print(“Attempting MQTT connection…”);
// Attempt to connect
if (client.connect(“ESP8266Client”)) {
Serial.println(“connected”);
// Once connected, publish an announcement…
client.publish(“outTopic”, “hello world”);
// … and resubscribe
client.subscribe(“inTopic”);
} else {
Serial.print(“failed, rc=”);
Serial.print(client.state());
Serial.println(” try again in 5 seconds”);
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void sleep(int timeInSeconds){
//ESP.deepSleep(timeInSeconds * 1000000);
delay(timeInSeconds * 1000);
}
char* readPins(){
val0=digitalRead(D1);
val1=digitalRead(D2);
val2=digitalRead(D3);
val3=digitalRead(D4);
if(val0==LOW and val1==LOW and val2==LOW and val3==LOW){ //0000
//Serial.println(“No Measurement”);
return “No Measurement”;
}
else if(val0==LOW and val1==LOW and val2==LOW and val3==HIGH){ //0001
//Serial.println(“-70 dBm”);
return “-70”;
}
else if(val0==LOW and val1==LOW and val2==HIGH and val3==LOW){ //0010
//Serial.println(“-60 dBm”);
return “-60”;
}
else if(val0==LOW and val1==LOW and val2==HIGH and val3==HIGH){ //0011
//Serial.println(“-50 dBm”);
return “-50”;
}
else if(val0==LOW and val1==HIGH and val2==LOW and val3==LOW){ //0100
//Serial.println(“-40 dBm”);
return “-40”;
}
else if(val0==LOW and val1==HIGH and val2==LOW and val3==HIGH){ //0101
//Serial.println(“-30 dBm”);
return “-30”;
}
else if(val0==LOW and val1==HIGH and val2==HIGH and val3==LOW){ //0110
//Serial.println(“-20 dBm”);
return “-20”;
}
else if(val0==LOW and val1==HIGH and val2==HIGH and val3==HIGH){ //0111
//Serial.println(“-10 dBm”);
return “-10″;
}
else if(val0==HIGH and val1==LOW and val2==LOW and val3==LOW){ //1000
//Serial.println(” 0 dBm”);
return “0”;
}
else if(val0==HIGH and val1==LOW and val2==LOW and val3==HIGH){ //1001
//Serial.println(“+10 dBm”);
return “10”;
}
else{
//Serial.println(“Measurement Error”);
return “Measurement Error”;
}
}
[/code]
For the sensor hubs, a Raspberry Pi with WiFi capabilities is used, plugged into a wired Ethernet network that provides it with access to the cloud. It is configured to serve as a WiFi Access Point (AP) for the nodes, and it also runs Mosquitto, an Open-Source MQTT broker service. Additionally, each sensor hub runs a custom Python script, which forwards each piece of data received to a remote Cloud Service using the MQTT protocol over TCP/IP.
[code language=python]
import paho.mqtt.client as mqtt
import ssl
import jsonpickle
awsClient=mqtt.Client()
awsClient.tls_set(“rootCA.pem”, certfile=”ca6601c61a-certificate.pem.crt”, keyfile=”ca6601c61a-private.pem.key”, cert_reqs=ssl.CERT_REQUIRED,
tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None)
awsClient.connect(“A21KN5F6UZ417N.iot.us-east-1.amazonaws.com”, 8883, 60)
def on_message(client, userdata, msg):
print(msg.topic+” “+str(msg.payload))
payload = {“state”: {“desired”: {“signal”: msg.payload}}}
aws_payload = jsonpickle.encode(payload)
awsClient.publish(‘$aws/things/emf_sensor_2/shadow/update’, payload=aws_payload, qos=0, retain=False)
def on_subscribe(client, userdata, mid, granted_qos):
print(“Subscribed to “+str(mid))
def on_connect(client, userdata, flags, rc):
print(“Connected with result code “+str(rc))
localClient.subscribe(“RFMeasurements”)
localClient = mqtt.Client()
localClient.on_connect = on_connect
localClient.on_message = on_message
localClient.on_subscribe = on_subscribe
localClient.connect(“localhost”,1883, 60)
localClient.loop_forever(timeout=1.0, max_packets=1, retry_first_connection=True)
[/code]
The following diagram summarizes the main echitecture of the proposed solution:
Implementation
For the the implementation of this solution, Amazon’s AWS IoT cloud platform was chosen. This particular service allowed us to make use of an extensible Rules Engine that reacted to specific data measurements, and a Device Shadow that allowed us to interface our rules and database(NoSQL, DynamoDB) with a mobile application by using device states.
An android application was developed to connect directly to the cloud service using MQTT over Secure WebSockets. When connected, the application polls the latest state from the device shadow every 5 seconds, which shows RF measurement readings in dBm(as captured by the sensor node, including a timestamp) as well as error messages. By using the AWS IoT platform, we were also able to notify users via SMS if RF measurements exceed a predefined threshold (making use of the rules engine and Amazon SNS). The following diagram summarizes the implementation’s architecture:
The code used in the sensor node and hub are available as an Open-Source project in my GitHub account.
Results
After implementing the system described above, the sensor node succesfully captured the RF readings generated by the Intel Edison and forwarded them to the MQTT broker running on Raspberry Pi. The python script successfully captured every incomming message to the MQTT topic the sensor node reported on, and pushed every reading to AWS IoT in a secure way. The data was stored in the DynamoDB, and the rules engine sccesfully managed to notify a user via SMS if the reading recorded exceeded the programmed threshold. Also, the Android application succesfully polled the information being stored in the database, and presented the readings acurately color-coded in terms of intensity.
The poster presented in class can be seen here: FinalProject_Poster.
Conclusions, Limitations and Future Applications
It was possible to propose and implement an IoT-based solution to the problem of measuring RF Noise. The proposed system is scalable, because several Sensor nodes can be associated to a sensor hub, and several sensor hubs (with associated nodes) can be deployed to measure RF noise in a geographic area.
Current limitations for the system are the Wifi Range between the NodeMCU and the Raspberry Pi; also in its current design, the Raspberry Pi relies on Ethernet connectivity to reach the cloud.
For future and/or more realistic applications, it would be cheap and easy to provide the sensor nodes with weatherproof encosures, LiPo Bateries and Solar cells so that they can operate extended periods of time autnomously. Also, the Raspberry Pis could be adapted to use Power-Over-Ethernet in order to provide both relieble internet connectivity and power to the system. Also, if the custom sensor designed and presented above where to be implemented, a variable Low-Noise Aplifier/Bandpass Filter submodule could be implemented so that the sensor node (using available digital I/Os) could slect diferent configurations for measuring various RF bands.
Ajay Chander R.
Bro , awesome project report on IOT which i been looking for. Really wonderful with detailed information.
Jorge A. Duarte G.
Helo Ajay,
I am glad that this material I produced has been useful to you and several others! IoT is definitely an amazing topic, specially nowadays when access to these devices and technologies is very convenient.
I would encourage you to document your developments as well, as I did, because you never know who you might help by doing so. Share your findings and knowledge!
All the best,
Jorge.