Hi there
In my initial blog post I suggested it would be good to not only have way more than the boards provided by the challange (UNO, YUN and Infinion) but also to mix it up a bit by introducing a foreigner into the mix
well I did, in the form of a TI launchpad CC3200
This board has WIFI, full IO, 80Mhz MPU and a whole bunch more
The design goal is to have this board subscribe to its topics directly rather than relying on Mrs YUN and also to provide value while at the party by monitoring the temperature and reporting it through the Eclipse MQTT broker, all this while running on battery power...
This effectively shows that no matte the underlying technology, it is a straight forward task to get them all talking to each other reliably and effectively, this board is subscribing to topics published by the Arduinos in the challenge and also providing value to the mix tha can also be consumed by any technology, in this challenge it was a hardware less node... the WEB browser page use to control the party
my initial endevour was to use CCS (Code Composer Studio ) running the TO_RTOS (Real time Operating System) and have several tasks running, one to announce the temperature at the venue and one to highlight the remote guests as they arrive or are pinged via the element14_IoT topic on the PAHO / Ellipse broker
This proved to be much harder a learning curve than I anticipated and while I could easily get the addition of one or the other working in the RTOS, it proved impossible for now to get them both working, there is a steep learning curve to get to grips with the RTOS and also the simple link networking stack. alas it got the better of me and I eventually switch to Energia to complete the coding. I will circle back to this once I am more familuar with the required RTOS and Simplelink software, there are many hours of videos to go though first and as I had no responses from my calls to the experts I had to change.
So, using Energia is was a simple matter of finding the libraries for MQTT (PubSubClient.h) modified for the CC3200's built in WIFI. I found the library here Creating an IoT-connected sensor with Energia & MQTT | Energia
next was to add the ability to both publish and subscribe at the same time as I wanted to include a publication of the temperature sensors included on the launchpad. The current Energia comes with a sample for interfacing with the device from Adafruit but it needs a small tweak to get it running
Lastly I also want to control some Higher power LEDs that draw in the region over 300mA and require about 12V to operate, this is way beyond the ability of the control board alone. In my initial breif i also stated I wanted to have relay driven loads that could be up to mains supply voltage. In the interest of safety I decided to not use mains but still retain the relays and instead use these high power LED which is more than good enough to demonstrate the principle of operation (POC at its best ) This is the relay board I used (Only 4 channels needed but I had this already) and this is one set of LEDs to be used.
The other part of this challenge was to have this unit be battery powered... come on down Battery Booster pack, the time is right
This has been running the board now for over 12 hours and no signs of being flat yet (Its not powering the LEDS but is driving the relays) and between fvan, mcb1, jancumps and myself peteroakes, were keeping the relays busy .
So the code
/* - connects to an MQTT broker - publishes temperature sensor reading to the topic "BYOB-PARTY/PartyTemp and BYOB-PARTY/FloorTemp" - also subscribes to the element14_IoT topic and drives outputs based on who is online pinging the topic - supports mcb1, fvan, jancumps and peteroakes at the moment */ #include <WiFi.h> #include <Wire.h> #include "Adafruit_TMP006.h" #include <PubSubClient.h> #include <SPI.h> //only required if using an MCU LaunchPad + CC3100 BoosterPack. Not needed for CC3200 LaunchPad WiFiClient wclient; byte server[] = { 198, 41, 30, 241 }; // Public Eclipse MQTT Brokers: http://mqtt.org/wiki/doku.php/public_brokers byte ip[] = { 172, 16, 0, 100 }; // gets overridden by the WIFI DHCP unsigned long timerInterval = 5000; // interval between sensor writes unsigned long timerNow = millis();// holder for current time to compare to sensorTimer unsigned long LEDInterval = 10000; // 15 seconds on time unsigned long LED1On = millis(); // holder for LED1 timer unsigned long LED2On = millis(); // holder for LED2 timer unsigned long LED3On = millis(); // holder for LED3 timer unsigned long LED4On = millis(); // holder for LED4 timer #define WIFI_SSID "xxxxxxxxx" #define WIFI_PWD "xxxxxxxxx" // Define Outputs #define LED1 3 #define LED2 4 #define LED3 5 #define LED4 6 Adafruit_TMP006 tmp006(0x41); // start with a diferent i2c address! PubSubClient client(server, 1883, callback, wclient); void callback(char* inTopic, byte* payload, unsigned int length){ // Handle callback here // Allocate the correct amount of memory for the payload copy byte* p = (byte*)malloc(length); // Copy the payload to the new buffer memcpy(p,payload,length); p[length]= 0 ; // terminate the string Serial.print("Received from topic "); Serial.print(inTopic); Serial.print(" payload "); Serial.println((char*) p); if (strcmp("peteroakes",(char*) p)==0) { LED1On = millis(); } if (strcmp("jancumps",(char*) p)==0) { LED2On = millis(); } if (strcmp("mcb1",(char*) p)==0) { LED3On = millis(); } if (strcmp("fvan",(char*) p)==0) { LED4On = millis(); } // Free the memory free(p); } void setup() { //Initialize serial and wait for port to open: Serial.begin(115200); Serial.println("Start WiFi"); WiFi.begin(WIFI_SSID, WIFI_PWD); while(WiFi.localIP() == INADDR_NONE) { Serial.print("."); delay(300); } Serial.println(""); printWifiStatus(); if (client.connect("thebreadBoardca")) { client.subscribe("element14_IoT"); } timerNow = millis(); // now spin up the temp sensor if (! tmp006.begin()) { Serial.println("No sensor found"); while (1); } // initialize the digital pin as an output. pinMode(LED1, OUTPUT);digitalWrite(LED1, LOW); pinMode(LED2, OUTPUT);digitalWrite(LED2, LOW); pinMode(LED3, OUTPUT);digitalWrite(LED3, LOW); pinMode(LED4, OUTPUT);digitalWrite(LED4, LOW); } void loop() { if(timerNow + timerInterval < millis()) { // Grab temperature measurements and print them. float objt = tmp006.readObjTempC(); Serial.print("Object Temperature: "); Serial.print(objt); Serial.println("*C"); float diet = tmp006.readDieTempC(); Serial.print("Die Temperature: "); Serial.print(diet); Serial.println("*C"); // convert into to char array String strobjt = (String)objt; String strdiet = (String)diet; int str_len = strobjt.length() + 1; // Length (with one extra character for the null terminator) char char_array[str_len]; // Prepare the character array (the buffer) strobjt.toCharArray(char_array, str_len); // Copy it over // publish data to MQTT broker client.publish("BYOB-PARTY/PartyTemp", char_array); str_len = strdiet.length() + 1; // Length (with one extra character for the null terminator) strdiet.toCharArray(char_array, str_len); // Copy it over // publish data to MQTT broker client.publish("BYOB-PARTY/FloorTemp", char_array); timerNow = millis(); // reset timer } client.loop(); updateLEDS(); } void updateLEDS() { if(millis() - LED1On <= LEDInterval ) { // Serial.print("leds 1"); digitalWrite(LED1, HIGH); } else { // Serial.print("leds 0"); digitalWrite(LED1, LOW); } if(millis() - LED2On <= LEDInterval ) { // Serial.print(" 1"); digitalWrite(LED2, HIGH); } else { // Serial.print(" 0"); digitalWrite(LED2, LOW); } if(millis() - LED3On <= LEDInterval) { // Serial.print(" 1"); digitalWrite(LED3, HIGH); } else { // Serial.print(" 0"); digitalWrite(LED3, LOW); } if(millis() - LED4On <= LEDInterval) { // Serial.println(" 1"); digitalWrite(LED4, HIGH); } else { // Serial.println(" 0"); digitalWrite(LED4, LOW); } } void printWifiStatus() { // print the SSID of the network you're attached to: Serial.print("SSID: "); Serial.println(WiFi.SSID()); // print your WiFi shield's IP address: IPAddress ip = WiFi.localIP(); Serial.print("IP Address: "); Serial.println(ip); }
This does not use the more complex command handling I used for the Arduino based projects, I wanted to show that is can be simple enough with if then else statements where the logic or list of commands is not extensive
first thing to note that is typical in the MQTT world of programming is a callback function, in this case literally called "callback", this will catch the messages sent to this device based on the subscriptions it issues, there is a debug print statement to display what is received followed by a series of timer updates based on the message received. Also not that this routine does not directly turn on the LEDs, it does not need to
the set-up function is nothing out of the ordinary so ill skip the description for it except to say this is where the subscription call is made to the eclipse.org broker
Note in the loop() function that there is a large section of code wrapped with an if statement, this is handling the case of only transmitting the temperature every 1 second rather then every time through the loop. No delay() functions where used or harmed in the making of this code, therefore it is simple to add further functionality without compromising the timing
after this loop there is a single call to the client.loop() function, this allows the subscriptions to be checked for data and is required for the mqtt client subscriptions to function
lastly in the main loop() there is a call to updateLEDS(), this is where the work is done to determine if any of the LEDs need to be turned on or off
As can be seen from the code, the sequence is repeated for each LED timer and if the timer is active the LED is turned on, if Inactive then it is turned off, this could be optimized to not call the on or off outputs if the state is already there but for this simple code it is not required or necesary
That is all there is to this particular project, very simple and effective, the outputs listed above are simply connected to the Relay board and they drive through opto isolators to turn on and of the relays.
Oh, yes there was one other thing, once programmed the board was disconnected from the USB power and supplied by the Battery Booster pack. Works great.
One annoying thing I discovered was that during programming, you had to keep removing rto run and replace to program a jumper on the launchpad, i guess this is the one that is used to switch between run time mode and emulation mode, and Energia always programs the runtime flash when programming so while annoying to have to do it, I can understand.
Attached is the completed code for you to use as you like
Any questions feel free to ask
Peter
Top Comments