Hello! In this tutorial we will cover the cloud service called Adafruit IO available from the Adafruit website. You will need to have an account on Adafruit to use the service. Once we are connected to Adafruit IO, we will then connect to the If This Then That (IFTTT) service to take action with many more parts of the internet. We can also connect directly to IFTTT from our hardware using their webhooks service. You will need an IFTTT account for the later part of the tutorial.
You will need the following:
- Adafruit account
- IFTTT account
- MSP432P401R LaunchPad board from Texas Instruments
- CC3100 BoosterPack board from Texas Instruments
- Educational BoosterPack Mk II board from Texas Instruments
- Energia IDE software www.energia.nu
- Adafruit MQTT Library https://github.com/adafruit/Adafruit_MQTT_Library
This tutorial will use the TI MSP432 LaunchPad and the CC3100 SimpleLink™ Wi-Fi® BoosterPack, an Internet-of-Things solution, along with the Educational BoosterPack Mk II. The Educational BoosterPack is an awesome input and output board with several sensors, human input devices, and an color LCD. Using Energia, TI's equivalent to simple Arduino-style scripting code, you'll come away with a functional setup using Adafruit IO and IFTTT. This is a great low cost way to introduce the excitement of electronics and integrating wireless connectivity with IoT examples. Because the TI LaunchPad is open source and modular hardware, we can also add BoosterPack modules to augment our circuits. In our case we are going to add Wi-Fi to give our circuits a lot more capability by interacting with cloud services. If you don't have access to a Wi-Fi BoosterPack, you can still run through the offline Educational BoosterPack examples located at https://energia.nu/guide/tutorials/boosterpacks/tutorial_edumkii/
PreworkBefore we begin, please ensure you:
1. Download and install the latest version of Energia. Energia can be downloaded from http://energia.nu/download/
a. Below the download links there are specific installation instructions for each operating system version. Please follow these instructions as you may also need to install drivers depending on your OS(Windows requires drivers, Mac does not require drivers,Linux requires dependecies).
b. You will need to download the correct board support package for the MSP432 LaunchPad. You can find this in the Boards Manager by going to Tools > Board > Boards Manager... and selecting MSP432 EMT RED version 5.29.0 or higher for install. This process of adding board support packages can take some time. For Windows users, a device driver is usually needed for the development board to be seen by the PC. The driver will be downloaded automatically if you use CCS or CCS Cloud, but if you have not then, you can manually get the driver from the Energia website: http://s3.amazonaws.com/energiaUS/files/energia_drivers.zip
c. NOTE: In Windows, Energia must be installed to a path without spaces in order to function properly. Make sure your folder that you save under does not contain spaces or you will likely see compile errors later.
3. Create an account on io.adafruit.com and ifttt.com
4. Respect this Hackster page by logging into your Hackster account and clicking the thumbs up "Respect Project" button at the top.
Lab 1 - MSP432 Energia Out of Box experienceHardware Required- TI MSP432 LaunchPad (MSP-EXP432P401R)
- CC3100 Wi-Fi BoosterPack (CC3100BOOST)
- Educational BoosterPack MKII (BOOSTXL-EDUMKII)
We will be using the TI CC3100 WiFi BoosterPack (CC3100BOOST) to connect to the network. We will also be using the accelerometer found on the Educational BoosterPack MKII (BOOSTXL-EDUMKII). Connect the MSP432 LaunchPad with the Educational BoosterPack on top and the CC3100 on the bottom (LaunchPad in the middle, sandwiched by the plug-in boards). This will provide the best stack up. Make sure the boards are oriented correctly, joystick on the left side. Logos on the backside should all be in the same direction.
In this lab we are going to get our environment set up and then test out our educational BoosterPack. The first thing we can do is blink an LED to make sure we can program our microcontroller with our computer.
1. Open up the Energia IDE (version 23 or above). Unzip your download and click the executable or app icon and it should start up.
2. First thing, make sure you select your board by going to Tools > Board and look for "LaunchPad with MSP432" on the menu. If your LaunchPad board is not present, go to the Boards Manager and install your LaunchPad board package. MSP432 boards should be the third option.
Note: MSP432 EMT means Multitasking and has RTOS capability, but we won't dive into that right now.
Note: by default the MSP432 is not included in the base install, so you will need to add it via the boards manager or Energia Installer. This part may take some time, so thanks for your patience. You want the MSP432 EMT RED option. Do not get the MSP432E Ethernet RED, this is for a different board. Grab the latest version. Currently it is 5.29.0.
3. If you properly installed your drivers, then you should see COM ports under Tools > Port. Select the port with UART capability if there are multiple options. You can verify the COM port in your computer's device manager on Windows. If you are on Mac OS, then you can select the port ending in 001.
4. Go to File > Examples > Basics > Blink. We will use the Green LED instead of the Red LED in our code in the case when the out of box code is a blinking Red LED. Uncomment the #define LED GREEN_LED line and comment out the RED_LED line.
/*
Blink
The basic Energia example.
Turns on an LED on for one second, then off for one second, repeatedly.
Change the LED define to blink other LEDs.
Hardware Required:
* LaunchPad with an LED
This example code is in the public domain.
*/
// most launchpads have a red LED
//#define LED RED_LED
//see pins_energia.h for more LED definitions
#define LED GREEN_LED
// the setup routine runs once when you press reset:
void setup() {
// initialize the digital pin as an output.
pinMode(LED, OUTPUT);
}
// the loop routine runs over and over again forever:
void loop() {
digitalWrite(LED, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
Once you do Basic > Blink. You can copy the custom Educational BoosterPack test code below.
/*
CustomEduBPTest for MSP432
This example is based off the EduBP_mkii_Production_Test code
for Energia IDE. Checks various functions of the BoosterPack.
Hardware Required:
* LaunchPad
* Educational BoosterPack MKII
This example code is in the public domain.
*/
#include <itoa.h>
#include <Wire.h>
#define USE_USCI_B1
//#define USING_MSP430F5529_LAUNCHPAD
//#define USING_TIVA_C_LAUNCHPAD
// Core library for code-sense
#include "Energia.h"
// Include application, user and local libraries
#include "SPI.h"
//#include "OPT3001.h"
// Screen selection
#define HX8353E // HX8353E K35 HI32 W32 ILI9225B HY28A ST7735 PicasoSPE PicasoSGC
#include "Screen_HX8353E.h"
Screen_HX8353E myScreen;
// Define variables and constants
//uint32_t chrono;
///
/// @brief protocolSquare
/// @details measure time to draw a square with side=pixels
/// @param pixels number of pixels of one side
///
void protocolSquare(uint16_t pixels)
{
if ((pixels < myScreen.screenSizeX()) && (pixels < myScreen.screenSizeY()) && (pixels > 48)) {
myScreen.setOrientation(0);
myScreen.setPenSolid(false);
uint16_t x100 = (myScreen.screenSizeX()-pixels)/2;
uint16_t y100 = (myScreen.screenSizeY()-pixels)/2;
myScreen.dRectangle(x100-1, y100-1, pixels+2, pixels+2, whiteColour);
myScreen.setPenSolid(true);
uint32_t chrono = millis();
myScreen.dRectangle(x100, y100, pixels, pixels, grayColour);
chrono = millis() - chrono;
myScreen.setFontSize(myScreen.fontMax());
myScreen.gText(x100 +2, y100 +2, "(" + i32toa(pixels) + ")");
myScreen.gText(x100 +2, y100 +pixels -myScreen.fontSizeY() -2, i32toa(chrono) + " ms");
Serial.print("Square(");
Serial.print(pixels, DEC);
Serial.print(")\t");
Serial.println(chrono, DEC);
}
}
///
/// @brief protocolCopyPaste
/// @details measure time to copy-paste a 64x64 area
/// @param orientation default=1
///
void protocolCopyPaste(uint8_t orientation = 1)
{
uint32_t chrono;
myScreen.clear();
myScreen.setOrientation(orientation);
// Image
chrono = millis();
for (uint8_t i=0; i<64; i++) {
for (uint8_t j=0; j<64; j++) {
myScreen.point(i, j, myScreen.calculateColour(4*i, 4*j, 254-2*i-2*j));
}
}
myScreen.setPenSolid(false);
myScreen.rectangle(1, 1, 62, 62, blackColour);
myScreen.line(0, 0, 63, 63, whiteColour);
myScreen.line(32, 0, 63, 63, whiteColour);
myScreen.line(0, 32, 63, 63, whiteColour);
myScreen.dRectangle(0, 0, 64, 64, whiteColour);
chrono = millis() - chrono;
myScreen.setFontSize(0);
myScreen.gText(0, 66, "0: Original");
myScreen.setFontSize(1);
myScreen.gText(0, 76, i32toa(chrono) + " ms");
Serial.print("Original(=");
Serial.print(orientation, DEC);
Serial.print(")\t");
Serial.println(chrono, DEC);
// Method 1
chrono = millis();
for (uint16_t i=0; i<64; i++) {
for (uint16_t j=0; j<64; j++) {
myScreen.point(myScreen.screenSizeX()/2+i, j, myScreen.readPixel(i, j));
}
}
chrono = millis() - chrono;
myScreen.setFontSize(0);
myScreen.gText(myScreen.screenSizeX()/2, 66, "1. point readPixel");
myScreen.setFontSize(1);
myScreen.gText(myScreen.screenSizeX()/2, 76, i32toa(chrono) + " ms");
Serial.print("point(readPixel())\t");
Serial.println(chrono, DEC);
// Method 2
chrono = millis();
myScreen.copyPaste(0, 0, 0, myScreen.screenSizeY()/2, 64, 64);
chrono = millis() - chrono;
myScreen.setFontSize(0);
myScreen.gText(0, myScreen.screenSizeY()/2 +66, "2. copyPaste");
myScreen.setFontSize(1);
myScreen.gText(0, myScreen.screenSizeY()/2 +76, i32toa(chrono) + " ms");
Serial.print("copyPaste()\t");
Serial.println(chrono, DEC);
// Method 3
if (myScreen.isStorage()) {
uint32_t address;
chrono = millis();
address = 100;
myScreen.copyArea(0, 0, 64, 64, address);
address = 100;
myScreen.pasteArea(myScreen.screenSizeX()/2, myScreen.screenSizeY()/2, 64, 64, address);
chrono = millis() - chrono;
myScreen.setFontSize(0);
myScreen.gText(myScreen.screenSizeX()/2, myScreen.screenSizeY()/2 +66, "3. copy-paste SRAM");
myScreen.setFontSize(1);
myScreen.gText(myScreen.screenSizeX()/2, myScreen.screenSizeY()/2 +76, i32toa(chrono) + " ms");
Serial.print("copyArea()+pasteArea() SRAM\t");
Serial.println(chrono, DEC);
}
}
///
/// @brief protocolText
/// @details measure time to draw text in 3 fonts, 4 orientations, 10x
///
void protocolText()
{
uint32_t chrono1, chrono2;
uint16_t colour;
uint8_t k = 0;
// Serial.print("fast gText... ");
myScreen.clear(grayColour);
myScreen.setFontSolid(true);
chrono1 = millis();
for (uint8_t j=0; j<10; j++) {
for (uint8_t i=0; i<4; i++) {
if (k==1) colour = redColour;
else if (k==2) colour = yellowColour;
else if (k==3) colour = greenColour;
else if (k==4) colour = cyanColour;
else if (k==5) colour = blueColour;
else colour = violetColour;
k++;
k %= 7;
myScreen.setPenSolid(false);
myScreen.dRectangle(0, 0, myScreen.screenSizeX(), myScreen.screenSizeY(), colour);
myScreen.setOrientation(i);
myScreen.setFontSize(0);
myScreen.gText(4, 4, "font 0 on " + String(i), colour);
myScreen.setFontSize(1);
myScreen.gText(4, 14, "font 1 on " + String(i), colour);
myScreen.setFontSize(2);
myScreen.gText(4, 34, "font 2 on " + String(i), colour);
}
}
chrono1 = millis()-chrono1;
Serial.print("10xFontSolid(true)\t");
Serial.println(chrono1, DEC);
// Serial.print("slow gText... ");
myScreen.clear(grayColour);
myScreen.setFontSolid(false);
chrono2 = millis();
for (uint8_t j=0; j<10; j++) {
for (uint8_t i=0; i<4; i++) {
if (k==1) colour = redColour;
else if (k==2) colour = yellowColour;
else if (k==3) colour = greenColour;
else if (k==4) colour = cyanColour;
else if (k==5) colour = blueColour;
else colour = violetColour;
k++;
k %= 7;
myScreen.setPenSolid(false);
myScreen.dRectangle(0, 0, myScreen.screenSizeX(), myScreen.screenSizeY(), colour);
myScreen.setOrientation(i);
myScreen.setFontSize(0);
myScreen.gText(4, 4, "font 0 on " + String(i), colour);
myScreen.setFontSize(1);
myScreen.gText(4, 14, "font 1 on " + String(i), colour);
myScreen.setFontSize(2);
myScreen.gText(4, 34, "font 2 on " + String(i), colour);
}
}
chrono2 = millis()-chrono2;
Serial.print("10xFontSolid(false)\t");
Serial.println(chrono2, DEC);
Serial.print("Ratio%\t");
Serial.println((uint32_t)((uint64_t)(chrono1*100)/chrono2), DEC);
}
const int JOY_X = 2;
const int JOY_Y = 26;
const int SEL = 5; //will not work with CC3100 connected
//MIC
const int MIC = 6;
//ACCELEROMETER
const int ACC_X = 23;
const int ACC_Y = 24;
const int ACC_Z = 25;
//SWITCHES
const int SW1 = 33;
const int SW2 = 32;
//BUZZER
const int BUZZ = 40;
//RGB LED
const int RGB_RED = 39;
const int RGB_GRN = 38;
const int RGB_BLU = 37;
// notes in the melody:
#define NOTE_C4_1 260
#define NOTE_B0 31
#define NOTE_C1 33
#define NOTE_CS1 35
#define NOTE_D1 37
#define NOTE_DS1 39
#define NOTE_E1 41
#define NOTE_F1 44
#define NOTE_FS1 46
#define NOTE_G1 49
#define NOTE_GS1 52
#define NOTE_A1 55
#define NOTE_AS1 58
#define NOTE_B1 62
#define NOTE_C2 65
#define NOTE_CS2 69
#define NOTE_D2 73
#define NOTE_DS2 78
#define NOTE_E2 82
#define NOTE_F2 87
#define NOTE_FS2 93
#define NOTE_G2 98
#define NOTE_GS2 104
#define NOTE_A2 110
#define NOTE_AS2 117
#define NOTE_B2 123
#define NOTE_C3 131
#define NOTE_CS3 139
#define NOTE_D3 147
#define NOTE_DS3 156
#define NOTE_E3 165
#define NOTE_F3 175
#define NOTE_FS3 185
#define NOTE_G3 196
#define NOTE_GS3 208
#define NOTE_A3 220
#define NOTE_AS3 233
#define NOTE_B3 247
#define NOTE_C4 262
#define NOTE_CS4 277
#define NOTE_D4 294
#define NOTE_DS4 311
#define NOTE_E4 330
#define NOTE_F4 349
#define NOTE_FS4 370
#define NOTE_G4 392
#define NOTE_GS4 415
#define NOTE_A4 440
#define NOTE_AS4 466
#define NOTE_B4 494
#define NOTE_C5 523
#define NOTE_CS5 554
#define NOTE_D5 587
#define NOTE_DS5 622
#define NOTE_E5 659
#define NOTE_F5 698
#define NOTE_FS5 740
#define NOTE_G5 784
#define NOTE_GS5 831
#define NOTE_A5 880
#define NOTE_AS5 932
#define NOTE_B5 988
#define NOTE_C6 1047
#define NOTE_CS6 1109
#define NOTE_D6 1175
#define NOTE_DS6 1245
#define NOTE_E6 1319
#define NOTE_F6 1397
#define NOTE_FS6 1480
#define NOTE_G6 1568
#define NOTE_GS6 1661
#define NOTE_A6 1760
#define NOTE_AS6 1865
#define NOTE_B6 1976
#define NOTE_C7 2093
#define NOTE_CS7 2217
#define NOTE_D7 2349
#define NOTE_DS7 2489
#define NOTE_E7 2637
#define NOTE_F7 2794
#define NOTE_FS7 2960
#define NOTE_G7 3136
#define NOTE_GS7 3322
#define NOTE_A7 3520
#define NOTE_AS7 3729
#define NOTE_B7 3951
#define NOTE_C8 4186
#define NOTE_CS8 4435
#define NOTE_D8 4699
#define NOTE_DS8 4978
// OPT3001
//opt3001 opt3001;
unsigned long readings = 0;
int melody[] = {
NOTE_C4_1,NOTE_C4, NOTE_D4, NOTE_C4,NOTE_F4,NOTE_E4,
NOTE_C4_1,NOTE_C4,NOTE_D4,NOTE_C4,NOTE_G4,NOTE_F4,
NOTE_C4_1,NOTE_C4,NOTE_C5,NOTE_A4,NOTE_F4,NOTE_F4, NOTE_E4,NOTE_D4,
NOTE_AS4,NOTE_AS4,NOTE_A4,NOTE_F4,NOTE_G4,NOTE_F4};
// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurations[] = {
4, 4, 2, 2,2,1,
4, 4, 2, 2,2,1,
4, 4, 2, 2,4,4,2,1,
4, 4, 2, 2,2,1};
void setup()
{
// put your setup code here, to run once:
Serial.begin(9600);
delay(300);
analogReadResolution(12); // 12-bit ADC resolution, default is 8-bit
pinMode(SW1, INPUT);
pinMode(SW2, INPUT);
pinMode(BUZZ, OUTPUT);
Serial.println("Welcome to the Educational BoosterPack MKII Custom Test:");
// opt3001.begin();
}
char *ftoa(char *a, float f, int precision)
{
long p[] = {0,10,100,1000,10000,100000,1000000,10000000,100000000};
char *ret = a;
long heiltal = (long)f;
itoa(heiltal, a, 10);
while (*a != '\0') a++;
*a++ = '.';
long desimal = abs((long)((f - heiltal) * p[precision]));
itoa(desimal, a, 10);
return ret;
}
void loop()
{
int16_t i;
uint16_t colour;
Serial.println("*** LCD_screen test ****");
Serial.println("(All times in ms)");
myScreen.begin();
Serial.println(myScreen.WhoAmI());
Serial.print(myScreen.screenSizeX(), DEC);
Serial.print("x");
Serial.println(myScreen.screenSizeY(), DEC);
myScreen.setFontSize(myScreen.fontMax());
myScreen.clear(darkGrayColour);
protocolSquare(300);
protocolSquare(200);
protocolSquare(100);
protocolSquare(50);
delay(2000);
protocolText();
delay(2000);
if (myScreen.isReadable()) {
protocolCopyPaste(1);
delay(2000);
}
myScreen.clear();
Serial.println("-END OF SCREEN TEST--");
Serial.println();
myScreen.clear(grayColour);
myScreen.setFontSolid(false);
colour = redColour;
myScreen.setOrientation(i);
myScreen.setFontSize(2);
//Test out the joystick
myScreen.gText(0, 0, " JoyStick Test", blueColour);
myScreen.gText(0, 15, " Press btn S2", blueColour);
myScreen.gText(0, 30, " to exit ", blueColour);
int joycountr = 0;
int joycountl = 0;
int joycountu = 0;
int joycountd = 0;
int joycountc = 0;
while(digitalRead(SW2)==1){
if(analogRead(JOY_X)>3500){
myScreen.gText(0, 45, "Right", colour);
Serial.println("Right direction joystick test");
joycountr = 1;
}
else if(analogRead(JOY_X)<500){
myScreen.gText(0, 55, "Left ", colour);
Serial.println("Left direction joystick test");
joycountl = 1;
}
else if(analogRead(JOY_Y)>3500){
myScreen.gText(0, 65, "Up", colour);
Serial.println("Up direction joystick test");
joycountu = 1;
}
else if(analogRead(JOY_Y)<500){
myScreen.gText(0, 75, "Down", colour);
Serial.println("Down direction joystick test");
joycountd = 1;
}
else {
myScreen.gText(0,85, "Center", colour);
Serial.println("Center direction joystick test");
joycountc = 1;
}
if(joycountr + joycountl + joycountu + joycountd + joycountc == 5) {
myScreen.gText(50,100, " PASSED!!", greenColour);
}
}
delay(400);
//Test out the microphone
myScreen.clear(grayColour);
myScreen.gText(0,0, " Tap Mic", blueColour);
while(analogRead(MIC) > 100);
myScreen.gText(50,10, " Passed!", colour);
//Test out button 1
myScreen.gText(0,20, " Button Tests", blueColour);
myScreen.gText(0,40, "Press S1", colour);
while(digitalRead(SW1) == 1);
myScreen.gText(50,40, " > Passed!", colour);
//Test out button 2
myScreen.gText(0,55, "Press S2", colour);
while(digitalRead(SW2) == 1);
myScreen.gText(50,55, " > Passed!", colour);
//Test out buzzer
myScreen.gText(0,70, " Buzzer Test", blueColour);
myScreen.gText(0,85, "hold S1 to skip", blueColour);
delay(2000);
if(digitalRead(SW1) == 1){
for (int thisNote = 0; thisNote < 26; thisNote++) {
// to calculate the note duration, take one second
// divided by the note type.
//e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
int noteDuration = 1000/noteDurations[thisNote];
tone(BUZZ, melody[thisNote],noteDuration);
int pauseBetweenNotes = noteDuration + 50; //delay between pulse
delay(pauseBetweenNotes>>2);
noTone(BUZZ); // stop the tone playing
}
myScreen.gText(0,105, "S1&S2 if sound", colour);
while(digitalRead(SW2) == 1 || digitalRead(SW1) == 1);
myScreen.gText(50,115, " PASSED!!", greenColour);
delay(400);
}
//Test out 3-axis analog accelerometer
// 1200 ~ -1G / 2000 ~ 0G / 2800 ~ +1G
myScreen.clear(grayColour);
myScreen.gText(0, 0, " Accelerometer Test", blueColour);
myScreen.gText(0, 15, " Press btn S2", blueColour);
myScreen.gText(0, 30, " to exit ", blueColour);
while(digitalRead(SW2)==1){
myScreen.gText(0,60, "Flat", colour);
if((analogRead(ACC_X) - 2048) < 500 && (analogRead(ACC_Y) - 2048) < 500 && (analogRead(ACC_Z) - 2048) > 500) {
myScreen.gText(50,60, " > Passed!", colour);
myScreen.gText(0,70, "Left", colour);
}
else if((analogRead(ACC_X) - 2048) < -500 && (analogRead(ACC_Y) - 2048) < 500 && (analogRead(ACC_Z) - 2048) < 500) {
myScreen.gText(50,70, " > Passed!", colour);
myScreen.gText(0,80, "Right", colour);
}
else if((analogRead(ACC_X) - 2048) > 500 && (analogRead(ACC_Y) - 2048) < 500 && (analogRead(ACC_Z) - 2048) < 0) {
myScreen.gText(50,80, " > Passed!", colour);
myScreen.gText(0,90, "Away", colour);
}
else if((analogRead(ACC_X) - 2048) < 500 && (analogRead(ACC_Y) - 2048) > 500 && (analogRead(ACC_Z) - 2048) < 500) {
myScreen.gText(50,90, " > Passed!", colour);
myScreen.gText(0,100, "To you", colour);
}
else if((analogRead(ACC_X) - 2048) < 500 && (analogRead(ACC_Y) - 2048) < -500 && (analogRead(ACC_Z) - 2048) < 500) {
myScreen.gText(50,100, " > Passed!", colour);
myScreen.gText(0,110, "Upside Down", colour);
}
else if((analogRead(ACC_X) - 2048) < 500 && (analogRead(ACC_Y) - 2048) < 500 && (analogRead(ACC_Z) - 2048) < -500) {
myScreen.gText(50,120, " PASSED!!", greenColour);
}
}
delay(400);
myScreen.clear(grayColour);
//TEST OPT3001 LIGHT SENSOR
//To be enabled once OPT3001 is added to future Edu BP MK II Rev.
// Serial.println("Cover the light sensor to test the OPT3001.");
// while(opt3001.readResult() > 30);
// Serial.println("Shine flashlight onto the light sensor ");
// while(opt3001.readResult() < 1000);
// Serial.println("OPT3001 testing successful!");
//TEST RGB LED
myScreen.gText(0,40, " RGB LED Test", blueColour);
i = 0;
int brightness = 0;
int fadeAmount = 5;
for(brightness = 0; brightness<255; brightness+=fadeAmount){
analogWrite(RGB_RED, brightness);
// wait for 30 milliseconds to see the dimming effect
delay(10);
}
for(brightness = 255; brightness>=0; brightness-=fadeAmount){
analogWrite(RGB_RED, brightness);
// wait for 30 milliseconds to see the dimming effect
delay(10);
}
for(brightness = 0; brightness<255; brightness+=fadeAmount){
analogWrite(RGB_GRN, brightness);
// wait for 30 milliseconds to see the dimming effect
delay(10);
}
for(brightness = 255; brightness>=0; brightness-=fadeAmount){
analogWrite(RGB_GRN, brightness);
// wait for 30 milliseconds to see the dimming effect
delay(10);
}
for(brightness = 0; brightness<255; brightness+=fadeAmount){
analogWrite(RGB_BLU, brightness);
// wait for 30 milliseconds to see the dimming effect
delay(10);
}
for(brightness = 255; brightness>=0; brightness-=fadeAmount){
analogWrite(RGB_BLU, brightness);
// wait for 30 milliseconds to see the dimming effect
delay(10);
}
myScreen.gText(0,70, "S1 to Finish", colour);
while(digitalRead(SW1) == 1);
myScreen.gText(0,90, "ALL TESTS PASSED", greenColour);
while(1);
}
For additional examples you can try the File > Examples > EducationalBP_MKII > EduBP_MKII_Production_Test which gives a demo of all the functions on the BoosterPack. Note for MSP432 make sure to add analogReadResolution(12); to your setup function. Also note for MSP432 the screen may have some refresh lag so it will appear slow.
Troubleshooting
Code not uploading?
- Check for errors in Energia debug window. The compiler will tell you what is happening. Errors are in red text.
- Sometimes your LaunchPad gets stuck or hung up on the previous code. Unplug your LaunchPad and plug it back in to perform a full reset. This is called a power on reset. Sometimes using the RESET button can work but taking away the power and letting the microcontroller fully reset is often best.
- If you have a failure to upload it could be your drivers are not properly installed. Energia will sometimes give the error “No unused FET Found” which means it can’t find a LaunchPad connected to your computer. Make sure you download the drivers for your operating system found on the Getting Started Guide.
- If you had no problem with the previous Blink example, your Energia should be correctly set up. Restart your LaunchPad and restart Energia IDE if you encounter any problems. Make sure to select the right serial port and board type under the Tools menu.
LED not lighting up?
- Make sure you properly uploaded the code and that you properly named your variables for the LED pins. There is very little chance that your LED is broken, but we can verify by blinking a different LED with the same code.
- Hit the reset button, sometimes this is needed for the LaunchPad to run the newly uploaded program.
- TI MSP432 LaunchPad (MSP-EXP432P401R)
- CC3100 Wi-Fi BoosterPack (CC3100BOOST)
- Educational BoosterPack MKII (BOOSTXL-EDUMKII)
Wi-Fi
Now we can add Wi-Fi. The CC3100 is TI's Wi-Fi adapter for microcontrollers. It's very easy to interface with using SPI and can be used with both TI LaunchPads and Arduinos because they both support the same programming language (Wiring). Writing a sketch that uses the CC3100 is also very easy as the web examples for both LaunchPad and Arduino will both work on this platform. You can get this board here: http://www.ti.com/tool/cc3100boost
In this part of the tutorial we will use Adafruit IO, which is a free cloud service for makers to experiment. It is based on a protocol called MQTT and this lightweight method of interacting with the cloud will allow you to stream data and pull data from the server (sometimes called a broker). Adafruit IO also let's you visualize your data in objects called Feeds, and you can create Dashboards to further display your data in graphical ways. They also offer basic email trigger functions and ways to connect your data to webhooks.
From the Energia IDE we will add the required Adafruit libraries. Make sure you downloaded locally to your computer. Go to the github page and click on the download ZIP button
- Adafruit MQTT Library https://github.com/adafruit/Adafruit_MQTT_Library
First add the MQTT Library by going to Sketch > Include Library > Add.ZIP library... and navigate to your file path where you downloaded it.
Next grab your Adafruit IO Username and your unique Adafruit IO Key.
Navigate to your profile and click the View Adafruit IO Key button to retrieve them. Write them down in a safe place, we'll need them for later.
From the Energia IDE, create a new sketch and name it AdafruitIOMQTTAutWiFi.ino. This example is based on the MQTT example provided in Energia by going to File -> Examples -> PubSubClient. Replace the SSID, Password and MQTT information placeholders with your Adafruit IO credentials and network connection info.
/*
Basic MQTT example
- connects to an MQTT server
- publishes "hello world" to the topic "outTopic"
- subscribes to the topic "inTopic"
*/
#include <SPI.h>
#include <WiFi.h>
#include <PubSubClient.h>
// your network name also called SSID
char ssid[] = "[WIFI_ROUTER_NAME]";
// your network password
char password[] = "[WIFI_ROUTER_PASSWORD]";
// MQTTServer to use
char server[] = "io.adafruit.com";
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Received message for topic ");
Serial.print(topic);
Serial.print("with length ");
Serial.println(length);
Serial.println("Message:");
Serial.write(payload, length);
Serial.println();
}
WiFiClient wifiClient;
PubSubClient client(server, 1883, callback, wifiClient);
void setup()
{
Serial.begin(115200);
// Start Ethernet with the build in MAC Address
// attempt to connect to Wifi network:
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);
}
Serial.println("\nYou're connected to the network");
Serial.println("Waiting for an 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();
}
void loop()
{
// Reconnect if the connection was lost
if (!client.connected()) {
Serial.println("Disconnected. Reconnecting....");
if(!client.connect("energiaClient", "[ADAFRUIT_USERNAME]", "[ADAFRUIT_IO_KEY]")) {
Serial.println("Connection failed");
} else {
Serial.println("Connection success");
if(client.subscribe("[ADAFRUIT_USERNAME]/feeds/inTopic")) {
Serial.println("Subscription successful");
}
}
}
if(client.publish("[ADAFRUIT_USERNAME]/feeds/outTopic","hello world")) {
Serial.println("Publish success");
} else {
Serial.println("Publish failed");
}
delay(1000);
}
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");
}
What this code is doing is every one second after successfully connecting to Adafruit IO, it will send a data value, in this case a string of "hello world" to a feed that is called outTopic. Another way to say this is the LaunchPad connects to the cloud and it publishes every second a new piece of data to a stream of data that is named outTopic.
Go back to Adafruit IO and click on the feeds menu. Here you want to click on Actions and create two new feeds. One called inTopic and the other called outTopic.
Think of a feed as a data stream. Data can be published from devices to a feed and devices can subscribe to a feed to get the data. So an easy example is a button. A button is binary, either ON or OFF. If we make a feed to keep track of the state of the button, we can update that feed with a new value if it changes and we can also subscribe to that feed to get the state of the button.
If we click into the outTopic feed, you can see the record of data being published. In our case no integer values have been published, but if any was, it could be graphed.
If we scroll down you can see attribute value pairs listed. In this case the time stamp and the string "hello world" from the LaunchPad. You can also see they are one second apart, just like we expect. Amazing!
So that's how you get data to the cloud. Next let's show or visualize that data in Adafruit IO using the dashboard feature. Then after that we can get data from the cloud back to the LaunchPad.
Let's create a new feed called "button1" on our feeds menu. Let's then go to the dashboard menu and create a new dashboard called "button1dashboard" and click into it. Here we need to add a new block by clicking the blue plus button.
Select the Toggle block which is the first option in the left corner. Looks like an ON/OFF switch.
Select button1 from the feed options.
Leave everything as default values and click create block.
Now your dashboard has this added button. From this button you can actually publish data to you button1 feed. Go ahead and test this now.
After clicking the button navigate to your feeds and click into button1 and you should see the values listed.
Now we can do the same from the LaunchPad.
/*
Basic MQTT example
- connects to an MQTT server
- publishes "hello world" to the topic "outTopic"
- subscribes to the topic "inTopic"
*/
#include <SPI.h>
#include <WiFi.h>
#include <PubSubClient.h>
// your network name also called SSID
char ssid[] = "[WIFI_ROUTER_NAME]";
// your network password
char password[] = "[WIFI_ROUTER_PASSWORD]";
// MQTTServer to use
char server[] = "io.adafruit.com";
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Received message for topic ");
Serial.print(topic);
Serial.print("with length ");
Serial.println(length);
Serial.println("Message:");
Serial.write(payload, length);
Serial.println();
}
WiFiClient wifiClient;
PubSubClient client(server, 1883, callback, wifiClient);
void setup()
{
Serial.begin(115200);
// Set LaunchPad buttons as input
pinMode(PUSH1, INPUT_PULLUP);
pinMode(PUSH2, INPUT_PULLUP);
// Start Ethernet with the build in MAC Address
// attempt to connect to Wifi network:
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);
}
Serial.println("\nYou're connected to the network");
Serial.println("Waiting for an 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();
}
void loop()
{
// Reconnect if the connection was lost
if (!client.connected()) {
Serial.println("Disconnected. Reconnecting....");
if(!client.connect("energiaClient", "[ADAFRUIT_USERNAME]", "[ADAFRUIT_IO_KEY]")) {
Serial.println("Connection failed");
} else {
Serial.println("Connection success");
}
}
if(digitalRead(PUSH1) == 0) {
client.publish("[ADAFRUIT_USERNAME]/feeds/button1","ON");
Serial.println("ON Publish success");
} else {
client.publish("[ADAFRUIT_USERNAME]/feeds/button1","OFF");
Serial.println("OFF Publish success");
}
// wait 5 seconds
delay(5000);
}
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");
}
What this code is doing is every five seconds after successfully connecting to Adafruit IO, it will send a data value, in this case a string of "ON" to a feed that is called button1 if the button is pressed. In the case where the button is not pressed, then it will send a string of "OFF" to the button1 feed.
So now there are two seperate ways we are publishing data to the feed, either through the dashboard toggle button or the LaunchPad.
Now we should get the data to the LaunchPad. To do this we will need to subscribe to the feed button1.
https://learn.adafruit.com/series/adafruit-io-basics
Troubleshooting
The Wi-Fi can’t connect to the router:
- Check all the connections between LaunchPad and the BoosterPack and make sure the pins are lined up.
- Make sure the LaunchPad is connected via USB and powered on. Check the voltages on the robot and the MSP43
- Make sure the Wi-Fi BoosterPack power LED is on when connected to LaunchPad.
- Verify the SSID and password of the router you are connecting to in the code
- Make sure the router does not have a splash screen for logging in. The CC3100 is not able to know what to do with that
- Check for errors in Energia debug window. The compiler will tell you what is happening. Errors are in red text.
- Sometimes your LaunchPad gets stuck or hung up on the previous code. Unplug your LaunchPad and plug it back in to perform a full reset. This is called a power on reset. Sometimes using the RESET button can work but taking away the power and letting the microcontroller fully reset is often best.
- If you have a failure to upload it could be your drivers are not properly installed. Energia will sometimes give the error “No unused FET Found” which means it can’t find a LaunchPad connected to your computer. Make sure you download the drivers for your operating system found on the Getting Started Guide.
- If you had no problem with the previous Blink example, your Energia should be correctly set up. Restart your LaunchPad and restart Energia IDE if you encounter any problems. Make sure to select the right serial port and board type under the Tools menu.
Cloud Issues?
- Make sure the router has an internet connection
- Check your Adafruit IO dashboard to verify if data is getting passed
- TI MSP432 LaunchPad (MSP-EXP432P401R)
- CC3100 Wi-Fi BoosterPack (CC3100BOOST)
- Educational BoosterPack MKII (BOOSTXL-EDUMKII)
We are now going to look at a different cloud service called If This Then That. The idea behind the service is to connect different actions on the internet together. This is called a trigger. For example an action happens somewhere like a new value gets added to a google spreadsheet or a new headline appears on a news site. We can use a trigger to then do something else when that happens. For example we might want to post a tweet or get an alert or move that data to some other app. This allows us to do many cool things with the internet that can be automated via IFTTT.
We can also do this with connected devices by using the generic Webhooks feature of IFTTT. So an action on our hardware can trigger some other action on the internet. And vice versa, something on the internet can trigger an action on our hardware. Very fun!
Let's start by activating an alert via tweet when something happens on our hardware, such as pushing a button.
1. Sign up for an IFTTT account at ifttt.com and associate it with an email address for testing your LaunchPad. Feel free to create a new google account and email just for this use. Create a new applet from the interface. An applet is a logical connection between two web services supported in IFTTT.
2. Click Explore in the top menu and ignore the fun icons and click the create button on the Explore page.
3. We will start making our own trigger, called an applet or service in IFTTT. Click the 'This' text with the plus sign.
4. At this moment you can appreciate the many services that can be connected, but we want to get to the webhooks service, so scroll down or enter it in the search bar.
5. Click into the service and complete the trigger fields. Use a name like button1_pressed.
6. Now we choose an action service, so scroll down the list or search for "Twitter." Select "Post a tweet" in the action menu.
7. Here you post the body of the tweet. Make sure to add the OccuredAt variable by clicking the ingredients button. This will help you have a unique tweet every time, because Twitter will block any duplicate tweets.
8. Lastly you will need to connect your twitter account. If you have one go to https://ifttt.com/twitter and connect it. If you don't have one, no worries, you can sign up for a quick temporary one.
Ok now that our IFTTT applet is set up for Twitter, we can focus in on the code for the hardware. But one last thing we need from IFTTT that will be important for our code to connect. We need to get the account key.
9. Now we need to go into the settings of the Webhooks service. https://ifttt.com/maker_webhooks Go into the settings and scroll down to find your URL key.
10. Navigate to that URL and it will send you to the test screen. To test your twitter works go to and type in your key in the URL https://maker.ifttt.com/trigger/button1_pressed/with/key/[YOUR_UNIQUE_KEY]
You should see the tweet appear. Now we can do the same thing on our LaunchPad. Basically we want to replicate pinging the URL to trigger the action. NOTE: IFTTT only allows 25 tweets maximum per day so keep that in mind as you are testing you may reach your limit.
/*
IFTTT Web client
This sketch connects to a website (https://maker.iffttt.com)
using a WiFi BoosterPack and uses button trigger from
Educational BoosterPack MK II
This example is written for a network using WPA encryption. For
WEP or WPA, change the Wifi.begin() call accordingly.
Circuit:
* WiFi BoosterPack attached
* Educational BoosterPack MK II attached
created 13 July 2010
by dlf (Metodo2 srl)
modified 31 May 2012
by Tom Igoe
modified 22 June 2020
by Mark Easley
*/
#include <SPI.h>
#include <WiFi.h>
//SWITCHES
const int SW1 = 33; // won't work with CC3100 attached
const int SW2 = 32;
// your network name also called SSID
char ssid[] = "YOUR_SSID";
// your network password
char password[] = "YOUR_AP_PASSWORD";
// if you don't want to use DNS (and reduce your sketch size)
// use the numeric IP instead of the name for the server:
//IPAddress server(50,62,217,1); // numeric IP for Google or whatever website yu want (no DNS)
char server[] = "maker.ifttt.com"; // name address for Google or whatever website you want (using DNS)
// Initialize the Wi-Fi client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
WiFiClient client;
void setup() {
//Initialize serial and wait for port to open:
Serial.begin(115200);
pinMode(SW1, INPUT);
pinMode(SW2, INPUT);
// attempt to connect to Wifi network:
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);
}
Serial.println("\nYou're connected to the network");
Serial.println("Waiting for an 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");
printWifiStatus();
Serial.println("\nWaiting for button press...");
Serial.println("\nS2 to trigger...");
Serial.println("\nS1 to exit...");
}
void loop() {
while(1){
// loop until SW2 pressed
if(digitalRead(SW2)==0) break;
}
// if you get a connection, report back via serial:
if (client.connect(server, 80)) {
Serial.println("\nStarting connection to server...");
Serial.println("connected to server");
// Make a HTTP request:
client.println("GET /trigger/button1_pressed/with/key/[YOUR_KEY] HTTP/1.1");
client.println("Host: maker.ifttt.com");
client.println("Connection: close");
client.println();
}
// if there are incoming bytes available
// from the server, read them and print them:
while (client.available()) {
char c = client.read();
Serial.write(c);
}
// if the server's disconnected, stop the client:
if (!client.connected()) {
Serial.println();
Serial.println("disconnecting from server.");
client.stop();
// do nothing forevermore:
while (true);
}
}
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);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
11. Flash the code IFTTT Web Client to your hardware, but make sure to change the variables for your local Wi-Fi access point SSID and password, and your personal IFTTT key for the URL. If you named your event something besides button1_pressed, then you will need to modify that in your code as well.
Get Weather
IoT Fall Detector
https://www.hackster.io/measley2/iot-fall-detection-with-ifttt-110e0b
IoT Refrigerator Tracker
https://www.hackster.io/measley2/iot-refrigerator-tracker-with-ifttt-552ae6
Troubleshooting
The Wi-Fi can’t connect to the router:
- Check all the connections between LaunchPad and the BoosterPack and make sure the pins are lined up.
- Make sure the LaunchPad is connected via USB and powered on. Check the voltages on the robot and the MSP43
- Make sure the Wi-Fi BoosterPack power LED is on when connected to LaunchPad.
- Verify the SSID and password of the router you are connecting to in the code
- Make sure the router does not have a splash screen for logging in. The CC3100 is not able to know what to do with that
- Check for errors in Energia debug window. The compiler will tell you what is happening. Errors are in red text.
- Sometimes your LaunchPad gets stuck or hung up on the previous code. Unplug your LaunchPad and plug it back in to perform a full reset. This is called a power on reset. Sometimes using the RESET button can work but taking away the power and letting the microcontroller fully reset is often best.
- If you have a failure to upload it could be your drivers are not properly installed. Energia will sometimes give the error “No unused FET Found” which means it can’t find a LaunchPad connected to your computer. Make sure you download the drivers for your operating system found on the Getting Started Guide.
- If you had no problem with the previous Blink example, your Energia should be correctly set up. Restart your LaunchPad and restart Energia IDE if you encounter any problems. Make sure to select the right serial port and board type under the Tools menu.
Cloud Issues?
- Make sure the router has an internet connection
- Check your activity log on IFTTT to make sure you have not exceeded your usage limit. There is a limit to both the number and rate of Webhooks you can trigger.
Comments