The ForceTronics blog provides tutorials on creating fun and unique electronic projects. The goal of each project will be to create a foundation or jumping off point for amateur, hobbyist, and professional engineers to build on and innovate. Please use the comments section for questions and go to forcetronics.com for information on forcetronics consulting services.
In this video we unbox Particle's new IoT Mesh Network series (Argon, Boron, Xenon). We take a look both the hardware and the software that allows you to easily create a cloud connected mesh network. Link to product page: https://www.particle.io/mesh
//******************Code from Video***************************************** // ----------------------------------- // Controlling LEDs over the Internet // ----------------------------------- // First, let's create our "shorthand" for the pins // Same as in the Blink an LED example: // led1 is D0, led2 is D7 int led1 = D0; int led2 = D7; // Last time, we only needed to declare pins in the setup function. // This time, we are also going to register our Particle function void setup() { // Here's the pin configuration, same as last time pinMode(led1, OUTPUT); pinMode(led2, OUTPUT); // We are also going to declare a Particle.function so that we can turn the LED on and off from the cloud. Particle.function("led",ledToggle); // This is saying that when we ask the cloud for the function "led", it will employ the function ledToggle() from this app. // For good measure, let's also make sure both LEDs are off when we start: digitalWrite(led1, LOW); digitalWrite(led2, LOW); } // Last time, we wanted to continously blink the LED on and off // Since we're waiting for input through the cloud this time, // we don't actually need to put anything in the loop void loop() { // Nothing to do here } // We're going to have a super cool function now that gets called when a matching API request is sent // This is the ledToggle function we registered to the "led" Particle.function earlier. int ledToggle(String command) { /* Particle.functions always take a string as an argument and return an integer. Since we can pass a string, it means that we can give the program commands on how the function should be used. In this case, telling the function "on" will turn the LED on and telling it "off" will turn the LED off. Then, the function returns a value to us to let us know what happened. In this case, it will return 1 for the LEDs turning on, 0 for the LEDs turning off, and -1 if we received a totally bogus command that didn't do anything to the LEDs. */ if (command=="on") { digitalWrite(led1,HIGH); digitalWrite(led2,HIGH); Particle.publish("LED State", "ON"); return 1; } else if (command=="off") { digitalWrite(led1,LOW); digitalWrite(led2,LOW); Particle.publish("LED State", "OFF"); return 0; } else { return -1; } }
In this video we look at how to use Arduino with the ThingSpeak IoT, cloud, and analytics platform. In the video we look at two use cases of ThingSpeak. For the first use case we log wireless sensor data to the cloud and perform post processing on the data using MATLAB. In the second use case we monitor a room with a wireless motion detector setup and have ThingSpeak send out a Tweet if any movement is detected in the room.
//*****************Arduino code from video********************************** /* This sketch was created for a video tutorial on the ForceTronics YouTube that shows how to use Arduino with the ThingSpeak cloud This code is public domain and free for anybody to use or modify at their own risk Note this code was leveraged from: Arduino --> ThingSpeak Channel via MKR1000 Wi-Fi Created: May 7, 2016 by Hans Scharler (http://www.nothans.com) */ #include <SPI.h> #include <WiFi101.h> //This sketch should work with any Arduino or shield that can use the WiFi101 library
char ssid[] = "YourNetwork"; // your network SSID (name) char pass[] = "YourPassword"; // your network password int status = WL_IDLE_STATUS; // Initialize the Wifi clients WiFiClient tClient; //this one is used to post temperature data WiFiClient mClient; //this one is used to post motion detection data // ThingSpeak Settings char server[] = "api.thingspeak.com"; String writeAPIKey = "YourWriteKey"; //Timing variables for tracking temperature posting unsigned long tempLastConnectionTime = 0; // track the last connection time const unsigned long tempPostingInterval = 295000L; // post temp ADC value just under every 5 min //Timing and logic variables for tracking temperature posting unsigned long mLastConnectionTime = 0; // track the last connection time const unsigned long mPostingInterval = 30000L; //checks to see if motion was detected every 30 sec bool mReset = true; //tracks if motion detection has been reset void setup() { pinMode(2,INPUT); //digital pin used to read output of motion detector pinMode(6,OUTPUT); //LED pin used to know when data is sent to cloud // attempt to connect to Wifi network while ( status != WL_CONNECTED) { // Connect to WPA/WPA2 Wi-Fi network status = WiFi.begin(ssid, pass); // wait 10 seconds for connection delay(10000); } } void loop() { //timer to know when it is time to post temp data to cloud if (millis() - tempLastConnectionTime > tempPostingInterval) { digitalWrite(6,HIGH); //Use the LED to see if Arduino gets heldup posting data to the cloud tempHttpRequest(); //function that formats data strings and posts data to ThingSpeak cloud digitalWrite(6,LOW); } if (millis() - mLastConnectionTime > mPostingInterval) { digitalWrite(6,HIGH); //Use the LED to see if Arduino gets heldup posting data to the cloud if(digitalRead(2) && mReset) { //if motion was detected post it mReset = false; //motion detected so reset variable mHttpRequest(); //if true motion was detected so post to cloud } else mReset = true; //reset logic tracker digitalWrite(6,LOW); } } //Posts temp data to thingspeak cloud void tempHttpRequest() { // read analog pin 0 with temp sensor connected int sensorValue = analogRead(0);
// create data string to send to ThingSpeak String data = String("field1=" + String(sensorValue, DEC));
// POST data to ThingSpeak if (tClient.connect(server, 80)) { tClient.println("POST /update HTTP/1.1"); tClient.println("Host: api.thingspeak.com"); tClient.println("Connection: close"); tClient.println("User-Agent: ArduinoWiFi/1.1"); tClient.println("X-THINGSPEAKAPIKEY: "+writeAPIKey); tClient.println("Content-Type: application/x-www-form-urlencoded"); tClient.print("Content-Length: "); tClient.print(data.length()); tClient.print("\n\n"); tClient.print(data); // close any connection before sending a new request tClient.stop(); // note the last connection time tempLastConnectionTime = millis(); } } //posts motion detection data to thingspeak cloud void mHttpRequest() {
// create data string to send to ThingSpeak, we always send a one here to indicate motion detected String data = String("field2=" + String(1,DEC));
// POST data to ThingSpeak if (mClient.connect(server, 80)) { mClient.println("POST /update HTTP/1.1"); mClient.println("Host: api.thingspeak.com"); mClient.println("Connection: close"); mClient.println("User-Agent: ArduinoWiFi/1.1"); mClient.println("X-THINGSPEAKAPIKEY: "+writeAPIKey); mClient.println("Content-Type: application/x-www-form-urlencoded"); mClient.print("Content-Length: "); mClient.print(data.length()); mClient.print("\n\n"); mClient.print(data); // close any connection before sending a new request mClient.stop(); // note the last connection time mLastConnectionTime = millis(); } }
%*************************MATLAB code from video***************************
In the final conclusion of this four part series on using the Amazon Echo and Arduino for home automation we look at the Arduino hardware setup for monitoring the current consumption of a washer machine and reports its state to the cloud.
In this video series we look at how to use Arduino (ESP8266) and the Amazon Echo to do voice controlled home automation.
Link to project material on GitHub:https://github.com/ForceTronics/Arduino_Echo_Home_Automation //************************************ESP8266 Arduino code********************* /* This sketch was created for a video series called Home Automation with the Arduino and the Amazon Echo Part 2 That was presented on the ForceTronics YouTube Channel. This code is public domain for anybody to use or modify at your own risk Note that this code was leveraged from a Sparkfun example on using their cloud service Phant */ // Include the ESP8266 WiFi library #include <ESP8266WiFi.h> // Include the SparkFun Phant library. #include <Phant.h> //Set your network name and password const char WiFiSSID[] = "NetworkName"; //your wifi network name goes here const char WiFiPSK[] = "NetworkPassword"; //your wifi password goes here //define constants for pin control and node number const int light = 4; //NodeMCU GPIO 4 pin is connected to the WiFi AC Switch control const char parseKey[] = "stamp"; //This is used to parse through data from Phant to find light setting //declare phant address and security keys const char PhantHost[] = "data.sparkfun.com"; const char gPublicKey[] = "YourPublicKey"; //your phant public key goes here const char gPrivateKey[] = "YourPrivateKey"; //your phant private key goes here //specify the rate that you post data to cloud const unsigned long postRate = 1000; unsigned long lastPost = 0; void setup() { initHardware(); //setup arduino hardware connectWiFi(); //Connect your WiFi network digitalWrite(LED_BUILTIN, HIGH); //turn on LED } void loop() { //loop until it is time to post data to phant cloud, variable "postRate" defines the interval in milli seconds if (lastPost + postRate <= millis()) { if (getFromPhant()) lastPost = millis(); //get data from Phant else lastPost = millis(); //Even if we fail delay whole cycle before we try again } } //function used to connect to WiFi network void connectWiFi() { byte ledStatus = LOW; // Set WiFi mode to station (as opposed to AP or AP_STA) WiFi.mode(WIFI_STA); // WiFI.begin([ssid], [passkey]) initiates a WiFI connection // to the stated [ssid], using the [passkey] as a WPA, WPA2, // or WEP passphrase. WiFi.begin(WiFiSSID, WiFiPSK); // Use the WiFi.status() function to check if the ESP8266 // is connected to a WiFi network. while (WiFi.status() != WL_CONNECTED) { // Blink the LED digitalWrite(LED_BUILTIN, ledStatus); // Write LED high/low ledStatus = (ledStatus == HIGH) ? LOW : HIGH; // Delays allow the ESP8266 to perform critical tasks // defined outside of the sketch. These tasks include // setting up, and maintaining, a WiFi connection. delay(100); } } //function that sets up some initial hardware states void initHardware() { pinMode(light, OUTPUT); //turn light off at startup digitalWrite(light, LOW); } //function that handles getting data from phant cloud int getFromPhant() { //Set phant data Phant phant(PhantHost, gPublicKey, gPrivateKey); WiFiClient client; //Create client object to communicate with the phant server
if (!client.connect(PhantHost, 80)) { //Attempt to connect to phant server using port 80 // If we fail to connect, return 0. return 0; } //Get data from phant cloud client.print(phant.get()); client.println(); int cTrack = 0; //variable that tracks count to spell stamp bool match = false; //tracks when we have a match with "stamp" and we can then get control data int pCount = 0; //variable used to track when we have control data while(1) { //loop until we get data and server closes connection if (client.available()) { //if data is available from phant server char c = client.read(); //read a bite of data from server if(!match) { //if true than we have not found the word "stamp" so keep looking if(c == parseKey[cTrack]) //check if we have a character match with word "stamp" { if(cTrack == (sizeof(parseKey)-2)) match = true; //if true it means we found a match for "stamp" in data from phant cloud cTrack++; //iterate this count if a character match was found } else { //if true means no character match so reset count cTrack = 0; } } else { //if true it means we found a match to "stamp" and we are ready to get control data if(pCount == 1) { //if true we are at the point in the data to read control data for node oen int dControl = c - '0'; //convert char data to an int by subtract an ASCII zero if(dControl == 1 | dControl == 0) digitalWrite(light, dControl); //make sure data is a one or zer and set LED pin with it } pCount++; //iterate the parse counter } } // if the server's disconnected, stop the client: if (!client.connected()) { client.stop(); //stop client, if you don't have this you will create too many clients and server won't let you connect anymore break; //This is how we get out of the loop } } return 1; // Return success }
In this three part series we look at how to create a wireless sensor mesh network that stores data on the cloud using the Arduino platform. In part three we look at how to access the sensor data from the cloud with a PC or Android device.
In this three part series we look at how to create a wireless sensor mesh network that stores data on the cloud using the Arduino platform. In part two we look at how to add time stamps to our sensor data and track the battery state of our nodes.
In this three part series we look at how to create a wireless sensor mesh network that stores data on the cloud using the Arduino platform. In part one we will look at the architecture of the network and how to get started sending sensor data to the cloud.
In this tutorial we look at how to reduce the power consumption of your Arduino enabled ESP8266 WiFi module for battery powered applications.
//**************Arduino code: ESP8266_Sleep_Example ************* /* This sketch was created for a tutorial on saving power using the ESP8266 with the Arduino IDE That was presented on the ForceTronics YouTube Channel. This code is public domain for anybody to use at their own risk */ #include <Arduino.h> #include <ESP8266WiFi.h> //not using WiFi but need for some of the sleep commands const int LED_PIN = 5; // Thing's onboard, green LED const int sleepTimeS = 5; //sets deepsleep time to 5 sec void setup() { pinMode(LED_PIN,OUTPUT); //setup LED pin flashLED(); //function that flashes LED on and off WiFi.forceSleepBegin(0); //this function turns on modem sleep mode (turns off RF but not CPU) flashLED(); WiFi.forceSleepWake(); //wakes modem up from sleep mode flashLED(); // deepSleep time is defined in microseconds. Multiply seconds by 1e6 ESP.deepSleep(sleepTimeS * 1000000); //Can also add mode setting: WAKE_RF_DEFAULT, WAKE_RFCAL, WAKE_NO_RFCAL, WAKE_RF_DISABLED //ESP.deepSleep(0,WAKE_RF_DEFAULT); //In Deep-sleep mode, the chip can be woken up and initialized by a low-level pulse //generated on the EXT_RSTB pin via an external IO } void loop() { //do nothing in the loop } //function that flashes LED at 1.5sec intervals void flashLED() { digitalWrite(LED_PIN, HIGH); delay(1500); digitalWrite(LED_PIN, LOW); delay(1500); }
//**************Arduino code: ESP8266_Sleep_Cloud_Example ************* /* This sketch was used for a tutorial on saving power with the ESP8266 using Arduino IDE That was presented on the ForceTronics YouTube Channel. This code is public domain for anybody to use or modify at your own risk Note that this code was leveraged from a Sparkfun example on using their cloud service Phant */ #include <Arduino.h> // Include the ESP8266 WiFi library. #include <ESP8266WiFi.h> // Include the SparkFun Phant library. #include <Phant.h> //Set your network name and password const char WiFiSSID[] = "YourNetwork"; const char WiFiPSK[] = "YourPassword"; //define constants for pin control and node number const int LED_PIN = 5; // Thing's onboard, green LED const int ANALOG_PIN = A0; // The only analog pin on the Thing const int NODE_NUM = 1; //node identifier //declare phant address and security keys const char PhantHost[] = "data.sparkfun.com"; const char PublicKey[] = "YourPublicKey"; const char PrivateKey[] = "YourPrivateKey"; //specify the rate that you post data to cloud const unsigned long postRate = 15000; unsigned long lastPost = 0; const int sleepTimeS = 15; void setup() { initHardware(); //setup arduino hardware connectWiFi(); //Connect your WiFi network digitalWrite(LED_PIN, HIGH); while (postToPhant() != 1) //post to cloud in setup code because we will reset after sleep { delay(100); } digitalWrite(LED_PIN, LOW); // deepSleep time is defined in microseconds. Multiply // seconds by 1e6 ESP.deepSleep(sleepTimeS * 1000000); //This is where we go to sleep, will reset upon waking up } void loop() { //do nothing here } //function used to connect to WiFi network and where we set transmit power level void connectWiFi() { byte ledStatus = LOW; //Set transmit power level WiFi.setOutputPower(0.0); //sets transmit power to 0dbm to lower power consumption, but reduces usable range // Set WiFi mode to station (as opposed to AP or AP_STA) WiFi.mode(WIFI_STA); // WiFI.begin([ssid], [passkey]) initiates a WiFI connection // to the stated [ssid], using the [passkey] as a WPA, WPA2, // or WEP passphrase. WiFi.begin(WiFiSSID, WiFiPSK); // Use the WiFi.status() function to check if the ESP8266 // is connected to a WiFi network. while (WiFi.status() != WL_CONNECTED) { // Blink the LED digitalWrite(LED_PIN, ledStatus); // Write LED high/low ledStatus = (ledStatus == HIGH) ? LOW : HIGH; // Delays allow the ESP8266 to perform critical tasks // defined outside of the sketch. These tasks include // setting up, and maintaining, a WiFi connection. delay(100); // Potentially infinite loops are generally dangerous. // Add delays -- allowing the processor to perform other // tasks -- wherever possible. } } //function that sets up some initial hardware states void initHardware() { Serial.begin(9600); pinMode(LED_PIN, OUTPUT); digitalWrite(LED_PIN, LOW); } //this function takes data and posts it to the cloud int postToPhant() { // LED turns on when we enter, it'll go off when we // successfully post. digitalWrite(LED_PIN, HIGH); // Declare an object from the Phant library - phant Phant phant(PhantHost, PublicKey, PrivateKey); //These functions build data and field string that will be sent to phant cloud phant.add("adcdata", analogRead(ANALOG_PIN)); phant.add("wifinode", NODE_NUM); // Now connect to data.sparkfun.com, and post our data: WiFiClient client; //declare client object that will post the data const int httpPort = 80; //specify port to post through if (!client.connect(PhantHost, httpPort)) //attempt to connect to phant { // If we fail to connect, return 0. return 0; } //Send post to phant client.print(phant.post()); // Read all the lines of the reply from server and print them to Serial while(client.available()){ String line = client.readStringUntil('\r'); //Serial.print(line); // Trying to avoid using serial } // Before we exit, turn the LED off. digitalWrite(LED_PIN, LOW); return 1; // Return success }
In this 3 part series we look at how to create an Android app to monitor and control multiple WiFi enabled Arduinos using the cloud. In part 3 the finale we will look at how to send control data to the cloud using an Android App to control the Arduino WiFi nodes. To download the Android App .aia file to load into MIT App Inventor II use the following link: https://dl.dropboxusercontent.com/u/26591541/CloudHomeAutoEx2.aia
//Arduino MKR1000 Code**************************************************** /* This sketch was created for a tutorial called Combining Arduino, Android, and the Cloud Part 3 That was presented on the ForceTronics YouTube Channel. This code is public domain for anybody to use or modify at your own risk Note that this code was leveraged from the Arduino WiFi101 examples and from a Sparkfun example on using their cloud service Phant */ #include <SPI.h> #include <WiFi101.h> char ssid[] = "YourNetwork"; // your network SSID (name) char pass[] = "YourPassword"; // your network password (use for WPA, or use as key for WEP) int keyIndex = 0; // your network key Index number (needed only for WEP) bool pData = false; //used to toggle between posting data and getting data int status = WL_IDLE_STATUS; //define some constant variables for pins and node number const int LED_PIN = 6; // Thing's onboard, green LED const int ANALOG_PIN = A0; // The only analog pin on the Thing const int NODE_NUM = 2; //node identifier const char parseKey[] = "stamp"; //define areas for phant cloud address and security keys const char PhantHost[] = "data.sparkfun.com"; const char pPublicKey[] = "PublicKeyForPosting"; const char pPrivateKey[] = "PrivateKeyForPosting"; const char gPublicKey[] = "PublicKeyForGetting"; const char gPrivateKey[] = "PublicKeyForGetting"; //The following variables are from Phant library created by Sparkfun. String _pub; String _prv; String _host; String _params; static const char HEADER_POST_URL1[] PROGMEM = "POST /input/"; static const char HEADER_POST_URL2[] PROGMEM = ".txt HTTP/1.1\n"; static const char HEADER_PHANT_PRV_KEY[] PROGMEM = "Phant-Private-Key: "; static const char HEADER_CONNECTION_CLOSE[] PROGMEM = "Connection: close\n"; static const char HEADER_CONTENT_TYPE[] PROGMEM = "Content-Type: application/x-www-form-urlencoded\n"; static const char HEADER_CONTENT_LENGTH[] PROGMEM = "Content-Length: "; //timing for posting to the phant cloud const unsigned long postRate = 15000; unsigned long lastPost = 0; void setup() { pinMode(LED_PIN, OUTPUT); //setup LED pin digitalWrite(LED_PIN, LOW); //Turn off LED Serial.begin(9600); while (!Serial) { //Note the code will not cont unless you open serial monitor ; // wait for serial port to connect. Needed for native USB port only } // check for the presence of the shield: if (WiFi.status() == WL_NO_SHIELD) { Serial.println("WiFi shield not present"); // don't continue: while (true); } // attempt to connect to Wifi network: while (status != WL_CONNECTED) { Serial.print("Attempting to connect to SSID: "); Serial.println(ssid); // Connect to WPA/WPA2 network. Change this line if using open or WEP network: status = WiFi.begin(ssid, pass); // wait 10 seconds for connection: delay(10000); } Serial.println("Connected to wifi"); printWifiStatus(); //Print info about the WiFi network that you are connected to } void loop() { //Delay for set time then post and get data from Phant cloud if (lastPost + postRate <= millis()) { if(pData) { if (postToPhant()) lastPost = millis(); else lastPost = millis(); //Even if we fail delay whole cycle before we try again } else { if (getFromPhant()) lastPost = millis(); else lastPost = millis(); //Even if we fail delay whole cycle before we try again } } } //function that handles posting and getting data from phant cloud int getFromPhant() { //Set phant data phant(PhantHost, gPublicKey, gPrivateKey); WiFiClient client; //Create client object to communicate with the phant server
if (!client.connect(PhantHost, 80)) { //Attempt to connect to phant server using port 80 // If we fail to connect, return 0. return 0; } //Get data from phant cloud client.print(phantGet()); client.println(); Serial.println("sent get request....."); int cTrack = 0; //variable that tracks count to spell stamp bool match = false; //tracks when we have a match with "stamp" and we can then get control data int pCount = 0; //variable used to track whe we have control data while(1) { //loop until we get data and server closes connection if (client.available()) { //if data is available from phant server char c = client.read(); //read a bite of data from server if(!match) { //if true than we have not found the word "stamp" so keep looking if(c == parseKey[cTrack]) //check if we have a character match with word "stamp" { if(cTrack == (sizeof(parseKey)-2)) match = true; //if true it means we found a match for "stamp" in data from phant cloud cTrack++; //iterate this count if a character match was found } else { //if true means no character match so reset count cTrack = 0; } } else { //if true it means we found a match to "stamp" and we are ready to get control data if(pCount == 3) { //if true we are at the point in the data to read control data for node oen Serial.print(c); int dControl = c - '0'; //convert char data to an int by subtract an ASCII zero if(dControl == 1 | dControl == 0) digitalWrite(LED_PIN, dControl); //make sure data is a one or zer and set LED pin with it } pCount++; //iterate the parse counter } } // if the server's disconnected, stop the client: if (!client.connected()) { Serial.println(); Serial.println("disconnecting."); client.stop(); //stop client, if you don't have this you will create too many clients and server won't let you connect anymore break; //This is how we get out of the loop } } pData = true; //set to true so we post data to cloud next loop return 1; // Return success } //function used to post data to phant cloud int postToPhant() { // Declare an object from the Phant library - phant phant(PhantHost, pPublicKey, pPrivateKey); //These calls build the web communication strings with Phant phantAdd("adcdata", analogRead(ANALOG_PIN)); //specify field and data used in that field phantAdd("wifinode", NODE_NUM); WiFiClient client; //Create client object to communicate with the phant server
if (!client.connect(PhantHost, 80)) { //Attempt to connect to phant server using port 80 // If we fail to connect, return 0. pData = false; //set to false so we get data from cloud next loop return 0; } //Send post to phant server client.print(phantPost()); // if there are incoming bytes available // from the server, read them and print them: while (client.available()) { String line = client.readStringUntil('\r'); //Do something with data } client.stop(); pData = false; //set to false so we get data from cloud next loop return 1; // Return success } 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"); Serial.println(); } //This is from phant library, initializes variables void phant(String host, String publicKey, String privateKey) { _host = host; _pub = publicKey; _prv = privateKey; _params = ""; } //From phant library, builds string of field and data void phantAdd(String field, int data) { _params += "&" + field + "=" + String(data); } //From phant library, builds string to get data from Phant cloud String phantGet() { String result = "GET /output/" + _pub + ".csv?page=1 HTTP/1.1\n"; result += "Host: " + _host + "\n"; result += "Connection: close\n"; return result; } //From phant library, builds the string used to post data to phant over web services String phantPost() { String params = _params.substring(1); String result; //String result = "POST /input/" + _pub + ".txt HTTP/1.1\n"; for (int i=0; i<strlen(HEADER_POST_URL1); i++) { result += (char)pgm_read_byte_near(HEADER_POST_URL1 + i); } result += _pub; for (int i=0; i<strlen(HEADER_POST_URL2); i++) { result += (char)pgm_read_byte_near(HEADER_POST_URL2 + i); } result += "Host: " + _host + "\n"; //result += "Phant-Private-Key: " + _prv + "\n"; for (int i=0; i<strlen(HEADER_PHANT_PRV_KEY); i++) { result += (char)pgm_read_byte_near(HEADER_PHANT_PRV_KEY + i); } result += _prv + '\n'; //result += "Connection: close\n"; for (int i=0; i<strlen(HEADER_CONNECTION_CLOSE); i++) { result += (char)pgm_read_byte_near(HEADER_CONNECTION_CLOSE + i); } //result += "Content-Type: application/x-www-form-urlencoded\n"; for (int i=0; i<strlen(HEADER_CONTENT_TYPE); i++) { result += (char)pgm_read_byte_near(HEADER_CONTENT_TYPE + i); } //result += "Content-Length: " + String(params.length()) + "\n\n"; for (int i=0; i<strlen(HEADER_CONTENT_LENGTH); i++) { result += (char)pgm_read_byte_near(HEADER_CONTENT_LENGTH + i); } result += String(params.length()) + "\n\n"; result += params; _params = ""; return result; } //This function convers the ADC level integer value into float voltage value. //The inputs are the measured ADC value and the ADC reference voltage level //The formula used was obtained from the data sheet: (ADC value / 1024) x ref voltage float convertToVolt(float refVal, int aVAL) { return (((float)aVAL/1024)*refVal); } //this function calculates temp in F from TMP36 temp sensor //see TMP36 datasheet to understand algorithm used float calculateTempF(float v1) { float temp = 0; //calculate temp in C, .75 volts is 25 C. 10mV per degree if (v1 < .75) { temp = 25 - ((.75-v1)/.01); } //if below 25 C else if (v1 == .75) {temp = 25; } else { temp = 25 + ((v1 -.75)/.01); } //if above 25 //convert to F temp =((temp*9)/5) + 32; return temp; }
//Arduino ESP8266 Code**************************************************** /* This sketch was created for a tutorial called Combining Arduino, Android, and the Cloud Part 3 That was presented on the ForceTronics YouTube Channel. This code is public domain for anybody to use or modify at your own risk Note that this code was leveraged from a Sparkfun example on using their cloud service Phant */ // Include the ESP8266 WiFi library. (Works a lot like the // Arduino WiFi library.) #include <ESP8266WiFi.h> // Include the SparkFun Phant library. #include <Phant.h> //Set your network name and password const char WiFiSSID[] = "YourNetwork"; const char WiFiPSK[] = "YourPassword"; //define constants for pin control and node number const int LED_PIN = 5; // Thing's onboard, green LED const int ANALOG_PIN = A0; // The only analog pin on the Thing const int NODE_NUM = 1; //node identifier const char parseKey[] = "stamp"; bool pData = false; //used to toggle between posting data and getting data //declare phant address and security keys const char PhantHost[] = "data.sparkfun.com"; const char pPublicKey[] = "PublicKeyForPosting"; const char pPrivateKey[] = "PrivateKeyForPosting"; const char gPublicKey[] = "PublicKeyForGetting"; const char gPrivateKey[] = "PublicKeyForGetting"; //specify the rate that you post data to cloud const unsigned long postRate = 15000; unsigned long lastPost = 0; void setup() { initHardware(); //setup arduino hardware connectWiFi(); //Connect your WiFi network digitalWrite(LED_PIN, HIGH); } void loop() { //loop until it is time to post data to phant cloud if (lastPost + postRate <= millis()) { if(pData) { if (postToPhant()) lastPost = millis(); else lastPost = millis(); //Even if we fail delay whole cycle before we try again } else { if (getFromPhant()) lastPost = millis(); else lastPost = millis(); //Even if we fail delay whole cycle before we try again } } } //function used to connect to WiFi network void connectWiFi() { byte ledStatus = LOW; // Set WiFi mode to station (as opposed to AP or AP_STA) WiFi.mode(WIFI_STA); // WiFI.begin([ssid], [passkey]) initiates a WiFI connection // to the stated [ssid], using the [passkey] as a WPA, WPA2, // or WEP passphrase. WiFi.begin(WiFiSSID, WiFiPSK); // Use the WiFi.status() function to check if the ESP8266 // is connected to a WiFi network. while (WiFi.status() != WL_CONNECTED) { // Blink the LED digitalWrite(LED_PIN, ledStatus); // Write LED high/low ledStatus = (ledStatus == HIGH) ? LOW : HIGH; // Delays allow the ESP8266 to perform critical tasks // defined outside of the sketch. These tasks include // setting up, and maintaining, a WiFi connection. delay(100); // Potentially infinite loops are generally dangerous. // Add delays -- allowing the processor to perform other // tasks -- wherever possible. } } //function that sets up some initial hardware states void initHardware() { Serial.begin(9600); pinMode(LED_PIN, OUTPUT); digitalWrite(LED_PIN, LOW); } //function that handles posting and getting data from phant cloud int getFromPhant() { //Set phant data Phant phant(PhantHost, gPublicKey, gPrivateKey); WiFiClient client; //Create client object to communicate with the phant server
if (!client.connect(PhantHost, 80)) { //Attempt to connect to phant server using port 80 // If we fail to connect, return 0. return 0; } //Get data from phant cloud client.print(phant.get()); client.println(); int cTrack = 0; //variable that tracks count to spell stamp bool match = false; //tracks when we have a match with "stamp" and we can then get control data int pCount = 0; //variable used to track whe we have control data while(1) { //loop until we get data and server closes connection if (client.available()) { //if data is available from phant server char c = client.read(); //read a bite of data from server if(!match) { //if true than we have not found the word "stamp" so keep looking if(c == parseKey[cTrack]) //check if we have a character match with word "stamp" { if(cTrack == (sizeof(parseKey)-2)) match = true; //if true it means we found a match for "stamp" in data from phant cloud cTrack++; //iterate this count if a character match was found } else { //if true means no character match so reset count cTrack = 0; } } else { //if true it means we found a match to "stamp" and we are ready to get control data if(pCount == 1) { //if true we are at the point in the data to read control data for node oen int dControl = c - '0'; //convert char data to an int by subtract an ASCII zero if(dControl == 1 | dControl == 0) digitalWrite(LED_PIN, dControl); //make sure data is a one or zer and set LED pin with it } pCount++; //iterate the parse counter } } // if the server's disconnected, stop the client: if (!client.connected()) { client.stop(); //stop client, if you don't have this you will create too many clients and server won't let you connect anymore break; //This is how we get out of the loop } } pData = true; //set to true so we post data to cloud next loop return 1; // Return success } //this function takes data and posts it to the cloud int postToPhant() { // Declare an object from the Phant library - phant Phant phant(PhantHost, pPublicKey, pPrivateKey); //These functions build data and field string that will be sent to phant cloud phant.add("adcdata", analogRead(ANALOG_PIN)); phant.add("wifinode", NODE_NUM); // Now connect to data.sparkfun.com, and post our data: WiFiClient client; //declare client object that will post the data const int httpPort = 80; //specify port to post through if (!client.connect(PhantHost, httpPort)) //attempt to connect to phant { // If we fail to connect, return 0. return 0; } //Send post to phant client.print(phant.post()); // Read all the lines of the reply from server and print them to Serial while(client.available()){ String line = client.readStringUntil('\r'); //Serial.print(line); // Trying to avoid using serial } pData = false; //set to false so we get data from cloud next loop return 1; // Return success }