This is a fork of my original cloud-connect sub-GHz RF sensor network project (LINKY! https://www.hackster.io/elephino/cloud-connected-sub-1ghz-rf-star-sensor-network-8d5fee).
The main difference? This time the edge sensor nodes are going to be based on the MSP432 LaunchPad & will take advantage of some of the mutli-tasking features from Energia MT.
In short, this project will consist of 2 things.
SubGHz RF sensor node. Each node will feature:
- MSP432 LaunchPad
- CC110L Sub-GHz RF BoosterPack
- Potentiometer & some hookup wire
Cloud-connect sub-GHz gateway:
- CC3200 ARM MCU + WiFi LaunchPad
- CC110L Sub-GHz RF BoosterPack
For this tutorial, I am using Energia v17 - you can download it here: www.energia.nu
Let's go!
MAKING THE SENSOR NODE:
Simply plug the MSP432 LaunchPad & CC110L RF BoosterPack together as shown below.
Next, let's wire up our potentiometer with some hook up wire. A simple trim potentiometer has 3 pins in a line: Power, Signal & Ground. Typically, the signal line is the center pin. This is the pin we want to connect to one of the ADC channels of the MSP432 LaunchPad. The other 2 "outer" pins are power & ground.
Let's wire it up!
- Connect one of the outer pins of the potentiometer to the 3V3 pin of the MSP432 LaunchPad.
- Connect the other outer pin on the opposite side of the potentiometer to the GND pin of the MSP432 LaunchPad.
- Lastly, wire up the middle signal pin to port pin P6.1 (this is position pin #23).
Here's a quick summary/diagram:
Great! Hardware is done. Let's program our wireless sensor node using the code below in the software section. Download the zip file below.
Remember, we are using some of the basic multi-tasking features available in Energia MT. If you'd like, you can learn more about some of the additional features of Energia MT here:
http://embeddedcomputing.weebly.com/exploring-rtos-with-galaxia.html
To get a taste of some of the multi-tasking features, we will simple create two tasks that will run in parallel on our MSP432 LaunchPad. In the case of Energia MT, it is a cooperative multi-tasking model built on top of TI's TI RTOS (http://www.ti.com/tirtos). In this specific implementation, each Energia MT task is given the same priority & each task yields to the other at certain points that is completely transparent to the developer.
To create a task, we simply add a new tab to our Energia project & create a new "setup/loop pair".
TASK 1: Periodically read our potentiometer sensor
The code in this task is very simple. We're just going to read the ADC channel that we have our potentiometer connected to. This task will loop every 100ms & will update the global variable sensorValue with a new reading. This global variable is how we enable basic "inter-task" communication. Our 2nd task will be able to read this global variable & will send it out over the RF radio!
int sensorValue = 0; // Global variable for passing sensor data between tasks
void setupReadSensor(){
// Nothing to do here!
}
void loopReadSensor(){
sensorValue = analogRead(analogPin);
delay(100);
}
TASK 2: Sending latest sensor readings over subGHz RF radio
Now that the global variable is getting updated with the latest sensor readings independently in Task 1, let's create a second task that will take the latest global variable value, encode it into a JSON payload, then send it over the RF radio.
Simply add a new tab within the Energia IDE & copy & paste the code below. We should now have 2 separate tasks running in parallel. Go ahead and program this into your LaunchPad!
/**
* MSP432_SubGHz_Sensor_Node example. Written by Adrian Fernandez
* Modified the original example created by Anaren Microwave, Inc.
* "WirelessTest - test transceiver sketch using AIR430Boost FCC driver"
* Copyright (C) 2012-2013 Anaren Microwave, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
*
* This example demonstrates usage of the AIR430BoostETSI library which uses
* the 430Boost-CC110L AIR Module BoosterPack created by Anaren Microwave,Inc
* and available through the TI eStore, for the European Union.
*
* -------------------------------------------------------------------------
*
* Note: This file is part of AIR430Boost.
*
* -------------------------------------------------------------------------
*/
// The AIR430BoostFCC library uses the SPI library internally. Energia doesn't
// copy the library to the output folder unless it is referenced here.
// The order of includes is also important due to this fact.
#include
#include
#include
// --------------------------------------------------------------------------
/**
* Global data
*/
const char* myName = "Adrian";
// --------------------------------------------------------------------------
// Main example
// SETUP function for sketch
void setupSendRF()
{
// Setup serial for debug printing.
Serial.begin(9600);
Serial.println("\n");
//Setup radio
Radio.begin(0x01, CHANNEL_1, POWER_MAX);
// Configure RED_LED, which will be used for visual notification of RF TX
pinMode(RED_LED, OUTPUT);
digitalWrite(RED_LED, LOW); // set the LED off
Serial.println("Radio started! Setup complete.");
}
// LOOP function for sketch
void loopSendRF()
{
//Blink LED to signify start of new sensor reading + RF TX
digitalWrite(RED_LED, HIGH);
// Encode sensor readings into JSON
/*Desired JSON encoded format:
{
"d":{
"yourName":1234
}
}
*/
aJsonObject *msg = aJson.createObject();
aJsonObject *d = aJson.createObject();
aJson.addItemToObject(msg, "d", d);
aJson.addNumberToObject(d, myName, sensorValue);
// Typecast JSON msg to char array, delete JSON object, then send via RF
char* payload = aJson.print(msg);
aJson.deleteItem(msg);
Radio.transmit(ADDRESS_BROADCAST, (uint8_t*)payload, 60);
// Print JSON-encoded payload to terminal, then free char array
Serial.print("TX (DATA): ");
Serial.println(payload);
free(payload);
// Transmission success! Toggle off LED & clear TX segment on LCD
digitalWrite(RED_LED, LOW);
// set frequency of transmissions
delay(1000);
}
MAKING THE GATEWAY:
Now that the sensor node is programmed, we can make our sub-GHz RF to WiFi bridge/gateway. Connect the CC110L RF BoosterPack to the CC3200 LaunchPad as shown below:
That's it on the hardware side! Now we can focus on the software. In this setup, the gateway will receive the JSON-encoded RF packets from the sensor nodes. When it receives a new payload, it publishes it up to a specific topic within an MQTT broker via WiFi.
Many cloud services can receive MQTT messages. Simply connect to the same broker & subscribe to the topic that we are publishing to from any MQTT-capable cloud service (i.e. IBM BlueMix, Amazon AWS, etc).
Here's the code:
/**
* WirelessTest - test transceiver sketch using AIR430Boost FCC driver.
* Copyright (C) 2012-2013 Anaren Microwave, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* This example demonstrates usage of the AIR430BoostETSI library which uses
* the 430Boost-CC110L AIR Module BoosterPack created by Anaren Microwave, Inc.
* and available through the TI eStore, for the European Union.
*/
// The AIR430BoostFCC library uses the SPI library internally. Energia does not
// copy the library to the output folder unless it is referenced here.
// The order of includes is also important due to this fact.
#include
#include
#include
#include
// -----------------------------------------------------------------------------
/**
* Global data
*/
unsigned char rxData[60]; // Data to read from radio RX FIFO (60 bytes MAX.)
char ssid[] = "puglife"; // your network name also called SSID
char password[] = "olliethepug"; // your network password
char server[] = "iot.eclipse.org"; // MQTTServer to use
WiFiClient wifiClient; // Connecting to MQTT broker via Wi-Fi
PubSubClient client(server, 1883, callback, wifiClient); // Initialize MQTT client
// -----------------------------------------------------------------------------
// RF packet received!
void printRxData()
{
// If RF data received, print diagnostic info to Serial Monitor & Publish over MQTT
Serial.print("RX (DATA, RSSI, LQI, CRCBIT): ");
Serial.print("(");
Serial.print((char*)rxData);
Serial.print(", ");
Serial.print(Radio.getRssi());
Serial.print(", ");
Serial.print(Radio.getLqi());
Serial.print(", ");
Serial.print(Radio.getCrcBit());
Serial.println(")");
// Publish latest RF payload to the cloud via MQTT, Blink Yellow LED if successful
if(client.publish("mySensorData_Adrian",(char*)rxData)) {
digitalWrite(YELLOW_LED, HIGH);
Serial.println("MQTT Publish success!");
digitalWrite(YELLOW_LED, LOW);
} else {
Serial.println("MQTT Publish failed!");
}
}
void callback(char* topic, byte* payload, unsigned int length) {
// Not used in this example
}
// -----------------------------------------------------------------------------
// Main example
void setup()
{
//Setup LED for example demonstration purposes.
pinMode(RED_LED, OUTPUT); // RED LED Notifier for subGHz RF Rx
digitalWrite(RED_LED, LOW);
pinMode(GREEN_LED, OUTPUT); // GREEN LED Notifier for Wi-Fi connected
digitalWrite(GREEN_LED, LOW);
pinMode(YELLOW_LED, OUTPUT); // YELLOW LED Notifier for MQTT Pub successful
digitalWrite(YELLOW_LED, LOW);
pinMode(PUSH1, INPUT); // Configure PUSH1. Used to decide how we will connect to Wi-Fi
// Setup serial for debug printing.
Serial.begin(115200);
// HOW WILL YOU CONNECT TO WiFi? SmartConfig or default network?
// SMARTCONFIG if PUSH1 was pressed during start up
if(digitalRead(PUSH1) == 1){
Serial.print("SMARTCONFIG MODE - ");
Serial.println("Starting WiFi SmartConfig...");
Serial.println("Use SmartConfig app to pass Wi-Fi credentials to your LaunchPad.");
WiFi.startSmartConfig();
// else, ATTEMPT TO CONNECT TO DEFAULT WIFI NETWORK
} else{
Serial.print("Attempting to connect to Network named: ");
// print the network name (SSID);
Serial.println(ssid);
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
WiFi.begin(ssid, password);
while ( WiFi.status() != WL_CONNECTED) {
// print dots while we wait to connect
Serial.print(".");
delay(300);
}
}
// Connected to Wi-Fi!
Serial.println("\nYou're connected to the network");
Serial.println("Waiting for an ip address");
// Wait for IP Address
while (WiFi.localIP() == INADDR_NONE) {
// print dots while we wait for an ip addresss
Serial.print(".");
delay(300);
}
Serial.println("\nIP Address obtained");
// We are connected and have an IP address. Print the WiFi status.
printWifiStatus();
// ATTEMPT TO INITIALIZE CC110L SUBGHz RADIO
// The radio library uses the SPI library internally, this call initializes
// SPI/CSn and GDO0 lines. Also setup initial address, channel, and TX power.
Radio.begin(0x01, CHANNEL_1, POWER_MAX);
}
void loop()
{
// Reconnect to MQTT Broker if the connection was lost
if (!client.connected()) {
Serial.println("Disconnected. Reconnecting to MQTT Broker");
client.connect("myCC3200_gateway");
Serial.println("Connected to MQTT Broker!");
}
// Turn on the receiver and listen for incoming data. Timeout after 1 seconds.
// The receiverOn() method returns the number of bytes copied to rxData.
if (Radio.receiverOn(rxData, 60, 1000) > 0)
{
/**
* Data has been received and has been copied to the rxData buffer provided
* to the receiverOn() method. At this point, rxData is available. See
* printRxData() for more information.
*/
digitalWrite(RED_LED, HIGH);
printRxData(); // RX debug information
digitalWrite(RED_LED, LOW);
}
// Ping MQTT broker to maintain connection
client.poll();
}
void printWifiStatus() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your WiFi IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
digitalWrite(GREEN_LED, HIGH); // Connected to WiFi LED
}
Plug in your CC3200 LaunchPad & program it with the code above using Energia! Be sure to change your target device in the Energia menu:
- Tools > Board > LaunchPad w/cc3200 (80MHz) menu in Energia.
NOTE:
- Also be sure to change the WiFi SSID & Password in the code example above.
- Also be sure to change the MQTT broker & topic as desired.
That's it! You can now connect & subscribe to the MQTT topic to start receiving your sensor network data in the cloud!
Comments