Prelude
The challenge is to create a system for air quality sensing which can operate without human intervention. My idea is to create a system that can measure air quality indoors and outdoors and log this data to the Sierra Wireless System. For the indoor unit, I have a CC3200 power unit which can measure temperature and an MICS5524 sensor which can measure air pollutants and connects to the cloud over wifi. It is powered by the TI Fuel Booster Pack and charged wirelessly with the Wurth Electronics Wireless Charging System. All parts are TI and Wurth Electronics.
The second outdoor unit is made up of the FR5969 Launchpad and uses the Alphasense Sensor for SO2 measurements and a Dust Sensor to measure particulate matter. This data is transmitted via CC2500 modules wirelessly to the BeagleBone Black which also has a CC2500. The BBB acts like a gateway device and sends the data to the Sierra Wireless Cloud via Wifi. This can be expanded to include more nodes to connect to this gateway and will allow future work to be done.
In addition to this functionality, I created a small board that can harvest solar energy and store it in a Li-Po battery. BQ25504, TPS61200 and TPS62740 are used to create a power harvesting circuit and the details are explained.
Status
I await some passive components as well as the sensors to arrive. I have been able to mount the HDC1000 using a hotair station and test out it's functionality. In this post I go through my experience with the CC3200 and connecting with the Sierra Wireless Cloud.
The CC3200
TI calls this the 'Internet of A Chip' and rightly so since it has a wifi stack as well as a microprocessor on the same die. The first thing we need to do is get this baby up and running. TI did something brilliant with this chip- they supplied demo code for a broad spectrum of applications from Basic Timer and peripheral stuff to the extensive access point mode. The Out Of The Box demo starts as an AP and you can configure it to connect to the Internet. I will go step by step here rather than write a journal about it since that has been done so many times.
(Disclaimer: Some Images have been taken from the TI Website because of their awesomeness)
Step 1: UnBox it and Get started
Yea that simple enough but the fact is the device come with little more than a USB Cable and the board itself.
The getting started instructions can be found here http://processors.wiki.ti.com/index.php/CC32xx_Quick_Start_Guide
The idea is to connect to the CC3200
This will give you a basic idea of the AP mode of the CC3200. Now we need to connect it to our router.
Step 2: Connect to our router.
In order to do some real work, we need to connect to our wireless router. For that, go to the settings page once connected to the CC3200
Enter the SSID of your router and also the password and type of Security. Do an ADD and power off the board. Next, pluck out the jumper shown in the image below
Power it back on and you should be able to see the board in your network. Just connect to your wirless router and go to mysimplelink.net
Congrats you are now on the network. Lets complicate things...
Step 3: Install the Dev IDE
We need to configure the CC3200 to do our bidding hence we need to install the tools necessary. (http://www.ti.com/lit/ug/swru376a/swru376a.pdf) This document can help you get started but I recommend visiting...
CC3200 "Internet-on-a-Chip" Getting Started Guide – Part 1
shabaz sir wrote this so beautifully that I just cannot do it better.
There are updates for the CC3200 available on the website which TI Recommends you download and upgrade. The post above helps you do that and steps 1 through 8 are what I used. It involves setting up the IDE and updating the firmware.
Great we now have the tools and board updated at this point. Next we need MQTT
Step 4: Start Coding
Like I said, TI did a brilliant job with the demo code and it would be wrong not to use it. I encourage you to import the examples and try em out. It's as simple as connecting your board and clicking the little bug icon on the top. DOn't worry you cannot brick your device since your program will only be in RAM and when you reboot the board, it will again start the OutOfBox Example application.
Steps 9, 10 and 11 of the above mentioned link from shabaz sir's post do exactly that.
Step 5: Understanding MQTT
MQTT has been called the language of IoT. It's basically a small protocol that allows communication using a broker/server. The basic mechanism is a publich/subscribe type where you subscribe to a 'topic' and then when someone 'publishes' data, you get it at your end. The problem is that the message or data is typically not stored by the server/broker in the basic form. We are interested in getting basic communications up and since we have the CC3200 connected to the router, why not the internet? Instead of setting up our own broker/server, we will use the iot.eclipse.org MQTT broker which works for free! Yay! To test this out, you should first install a utility for MQTT like Google Chrome as an extension called MQTT Lens. You can get apps for android as well or iOS. Fire up the app and enter iot.eclipse.org and port 1883. No username or passwords are needed at this point but some apps may want one anyways. In the topic, use any string. I preffer strings like /Inderpreet/myProject/CC3200. This is not a folder structure but just a way to uniquely identify the Topic. Click Subscribe and now you are listening. Next we need to publish something type in the same topic name and enter some text. When you press publish, you should be able to see the message in the window below. Here is a screenshot.
In my IoT Holiday Lights Challenge, I used MQTT to send strings like :TM255255255 which meant
: = start of frame
T = command for the tree
M = Manual Mode
255 =Red
255 =Green
255 =Blue
The crafting of such a message is done in software and we will see how. First lets see if our CC3200 can talk to the broker.
Step 6: MQTT on CC3200
Since our CC3200 already connects to the router, we should be able to connect to anything. My starting point for new projects is the demo code for the OOB which is provided by TI. It is the simplest way to get up and running in a jiffy. There is a wonderful video tutorial by kartben sir on the subject of running MQTT on the CC3200 and here are the blog posts.
Connect the CC3200 to the Internet of Things with MQTT and Paho embedded C client - Part 1
Connect the CC3200 to the Internet of Things with MQTT and Paho embedded C client - Part 2
Once you are done, you should have an MQTT enabled CC3200 transmitting the temperature. Cool now what? For the Forget Me Not Challenge, I used the CC3200 to read an ADC and then send that data to another topic. Lets see how to do that...
Step 7: Reading a Frequency and sending it via MQTT
By now you have figured out that the CC3200 is running an RTOS and everything happens in Tasks. So we will start by writing our own task and extend the capability of the system. I am going to setup the CC3200 so that it will measure a frequency of a signal and send that data over MQTT. I used this technique in the forget me not challenge to measure rainfall in a tipping bucket sensor. We will be using timers hence this should be fun. (http://www.element14.com/community/community/design-challenges/forget-me-not/blog/2014/10/20/forgetwhat-a-met-system-update-experiments-with-paho)
The first thing to do is to find out which pin I can use. The infographic by shabaz sir is very helpful.
A quick look at the datasheet and...
Its clear I can use TimerA0. Using the PinMux Utility, I can easily generate the desired code. Here is what I did...
a> Adding to main
In the main.c, in the void main() function, I added the following lines...
// // Configure the pinmux settings for the peripherals exercised // PinMuxConfig(); PinConfigSet(PIN_58,PIN_STRENGTH_2MA|PIN_STRENGTH_4MA,PIN_TYPE_STD_PD); // // Configure TimerA0 // TimerA0Init(); // // Register timer interrupt hander // MAP_TimerIntRegister(TIMERA2_BASE,TIMER_A,TimerIntHandler); // // Configure the timer in edge count mode // MAP_TimerConfigure( TIMERA2_BASE,(TIMER_CFG_SPLIT_PAIR| TIMER_CFG_A_CAP_TIME | TIMER_CFG_A_PERIODIC_UP)); // Set the prescaller MAP_TimerPrescaleSet(TIMERA2_BASE, TIMER_A, TIMER_PRES); // // Set the detection edge // MAP_TimerControlEvent(TIMERA2_BASE, TIMER_A, TIMER_EVENT_POS_EDGE); // // Set the reload value // MAP_TimerLoadSet(TIMERA2_BASE, TIMER_A, 0xffffff); // // Enable capture event interrupt // MAP_TimerIntEnable(TIMERA2_BASE, TIMER_CAPA_EVENT); // // Enable Timer // MAP_TimerEnable(TIMERA2_BASE, TIMER_A);
That configures the timer a and connects the Capture mode input to Pin P04 which is on J1(left side).
b> Add the handellers
Add the following functions to the main.c file
//***************************************************************************** // //! TimerA0 interrupt handler // //***************************************************************************** void TimerA0IntHandler( void ) { if(g_change == 1) GPIOPinWrite(SIG_PORT, SIG_PIN, SIG_PIN); else GPIOPinWrite(SIG_PORT, SIG_PIN, 0x00); g_change ^= 1; Timer_IF_InterruptClear(TIMERA0_BASE); } //***************************************************************************** // //! TimerA0 and pin_61 Initialization // //***************************************************************************** void TimerA0Init() { // Configure PIN_61 for GPIOOutput MAP_PinTypeGPIO(PIN_61, PIN_MODE_0, false); MAP_GPIODirModeSet(SIG_PORT, SIG_PIN, GPIO_DIR_MODE_OUT); // Configure TimerA0 Timer_IF_Init (PRCM_TIMERA0, TIMERA0_BASE, TIMER_CFG_PERIODIC, TIMER_A, 0); Timer_IF_IntSetup(TIMERA0_BASE, TIMER_A, TimerA0IntHandler); Timer_IF_Start(TIMERA0_BASE, TIMER_A, TIMER_FREQ /TIMER_CAP_FREQ /2); }
The handler function takes care of measuring frequency in the Background. Nice!
c> Add our task
Next I need to add my own little task... create a copy of the MQTTTask Function OR simply use the code below.
static void MQTTTaskRain(void *pvParameters){ while(g_iInternetAccess!=0){ osi_Sleep(200); } // Now connected while(1){ MQTTPacket_connectData data = MQTTPacket_connectData_initializer; unsigned char buf[200]; MQTTString topicString = MQTTString_initializer; char cTemp = (char) g_ulFreq; char payload[20]; memset(payload, '\0', sizeof(payload)); short sTempLen = itoa(cTemp, payload); int payloadlen = strlen(payload); int buflen = sizeof(buf); data.clientID.cstring = "me"; data.keepAliveInterval = 20; data.cleansession = 1; int len = MQTTSerialize_connect(buf, buflen, &data); /* 1 */ topicString.cstring = "/forgetwhat/cc3200/rain"; len += MQTTSerialize_publish(buf + len, buflen - len, 0, 0, 0, 0, topicString, (unsigned char*)payload, payloadlen); /* 2 */ len += MQTTSerialize_disconnect(buf + len, buflen - len); /* 3 */ int mysock = sl_Socket(SL_AF_INET, SL_SOCK_STREAM, 0 ); SlSockAddrIn_t addr; addr.sin_family= SL_AF_INET; addr.sin_port = sl_Htons(1883); addr.sin_addr.s_addr= sl_Htonl(0xC6291EF1); sl_Connect(mysock, (SlSockAddr_t*)&addr, sizeof(addr)); // rc = Socket_new("127.0.0.1", 1883, &mysock); sl_Send(mysock, buf, len, NULL); // rc = write(mysock, buf, len); sl_Close(mysock); // rc = close(mysock); osi_Sleep(10000); } }
d> Add the task to the OS
The last thing to do is add the newly made task to the OS's list of things to do. Simply add the following line to the main function.
osi_TaskCreate (MQTTTaskRain, ( signed char *)"OOBTask" ,OSI_STACK_SIZE, NULL, OOB_TASK_PRIORITY, NULL );
Done! Debug and let her rip! My box looked like this...
Step 8: Making things permanent
In order to retain this code, we need to program the flash. Step 8 of this tutorial by @shabaz sir has the correct instructions. http://www.element14.com/community/groups/internet-of-things/blog/2014/10/19/cc3200-internet-on-a-chip-getting-started-guide-part-2
Step 9: Experiment!
You have the basics, so now its time to move to more advanced stuff. The above link has info on how to configure I2C with the CC3200 and control an LCD which I have experimented with in a previous post.
Conclusion
I tried to curate the information of the best and put my little something into it as well. In the next post, I will be displaying the temperature data on the LCD as well as sending it to the Sierra Wireless Cloud and configuring the service to work with the CC3200.
IP
Top Comments