To download the Android App .aia file to load into MIT App Inventor II use the following link: https://dl.dropboxusercontent.com/u/26591541/CloudHomeAutoEx.aia
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.
Saturday, August 27, 2016
Combining Arduino, Android, and the Cloud Part 2
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 2 we will look at how to grab the Arduino data from the cloud using a custom Android App.
To download the Android App .aia file to load into MIT App Inventor II use the following link: https://dl.dropboxusercontent.com/u/26591541/CloudHomeAutoEx.aia
To download the Android App .aia file to load into MIT App Inventor II use the following link: https://dl.dropboxusercontent.com/u/26591541/CloudHomeAutoEx.aia
Labels:
Android,
app,
arduino,
cloud,
ESP8266,
IoT,
light sensor,
MKR1000,
temperature sensor,
TMP36,
Tutorial,
WiFi
Wednesday, August 24, 2016
Combining Arduino, Android, and the Cloud Part 1
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 1 we will look at how to send data to the cloud from an Arduino MKR1000 and an Arduino ESP8266.
//**********************Arduino ESP8266 Code****************
/*
This sketch was created for a tutorial called Combining Arduino, Android, and the Cloud Part 1
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
//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;
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 (postToPhant())
lastPost = millis();
else
delay(100);
}
}
//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);
}
//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
}
//**********************Arduino MKR1000 Code****************
/*
This sketch was created for a tutorial called Combining Arduino, Android, and the Cloud Part 1
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)
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
//define areas for phant cloud address and security keys
const char PhantHost[] = "data.sparkfun.com";
const char PublicKey[] = "YourKey";
const char PrivateKey[] = "YourKey";
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);
Serial.begin(9600);
while (!Serial) {
; // 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();
}
void loop() {
if (lastPost + postRate <= millis())
{
if (postToPhant())
lastPost = millis();
else
lastPost = millis(); //Even if we fail delay whole cycle before we try again
}
}
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(PhantHost, PublicKey, PrivateKey);
//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.
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();
// Before we exit, turn the LED off.
digitalWrite(LED_PIN, LOW);
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 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;
}
//**********************Arduino ESP8266 Code****************
/*
This sketch was created for a tutorial called Combining Arduino, Android, and the Cloud Part 1
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
//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;
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 (postToPhant())
lastPost = millis();
else
delay(100);
}
}
//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);
}
//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
}
//**********************Arduino MKR1000 Code****************
/*
This sketch was created for a tutorial called Combining Arduino, Android, and the Cloud Part 1
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)
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
//define areas for phant cloud address and security keys
const char PhantHost[] = "data.sparkfun.com";
const char PublicKey[] = "YourKey";
const char PrivateKey[] = "YourKey";
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);
Serial.begin(9600);
while (!Serial) {
; // 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();
}
void loop() {
if (lastPost + postRate <= millis())
{
if (postToPhant())
lastPost = millis();
else
lastPost = millis(); //Even if we fail delay whole cycle before we try again
}
}
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(PhantHost, PublicKey, PrivateKey);
//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.
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();
// Before we exit, turn the LED off.
digitalWrite(LED_PIN, LOW);
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 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;
}
Labels:
arduino,
cloud,
encryption,
ESP8266,
internet of things,
IoT,
MKR1000,
phant,
sparkfun,
Tutorial,
web,
WiFi
Monday, August 15, 2016
How to Build an Android App to Control Your WiFi Enabled Arduino
In this video we look at how to make a simple Android App to control your Arduino via WiFi
To download the Andriod App .aia file to load into MIT App Inventor: https://dl.dropboxusercontent.com/u/26591541/HomeAutoEx.aia
Arduino Code from video:
//This sketch made for a video tutorial on the ForceTronics YouTube Channel
//The tutorial shows how to make a simple Android app to control an Arduino wirelessly via WiFi
//This sketch leverages code from the Arduino example programs "AP_SimpleWebServer" and "WiFiWebServer"
//This sketch is free and open to be used and modified
#include <SPI.h> //What is used to communicate witht he WiFi chip
#include <WiFi101.h> //Wifi library fro Arduino MKR1000 and WiFi shield
int lControl = 6; //Digital pin that LED is connected to on the MKR1000
char ssid[] = "YourNetwork"; // your network SSID (name)
char pass[] = "YourPassword"; // your network password
int keyIndex = 0; // your network key Index number (needed only for WEP)
int status = WL_IDLE_STATUS; //status of wifi
WiFiServer server(80); //declare server object and spedify port, 80 is port used for internet
void setup() {
//Uncomment serial for debugging and to see details of WiFi connection
// Serial.begin(9600);
// while (!Serial) {
// 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);
}
server.begin();
// you're connected now, so print out the status:
// printWifiStatus();
}
void loop() {
WiFiClient client = server.available(); // listen for incoming clients
if (client) { // if you get a client,
// Serial.println("new client"); // print a message out the serial port
String currentLine = ""; // make a String to hold incoming data from the client
while (client.connected()) { // loop while the client's connected
if (client.available()) { // if there's bytes to read from the client,
char c = client.read(); // read a byte, then
// Serial.write(c); // print it out the serial monitor
if (c == '\n') { // if the byte is a newline character
// if the current line is blank, you got two newline characters in a row.
// that's the end of the client HTTP request, so send a response:
if (currentLine.length() == 0) {
// HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
// and a content-type so the client knows what's coming, then a blank line:
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println();
client.print("Value at A0 is ");
client.print(analogRead(A0));
client.print("<br>");
// The HTTP response ends with another blank line:
client.println();
// break out of the while loop:
break;
}
else { // if you got a newline, then clear currentLine:
currentLine = "";
}
}
else if (c != '\r') { // if you got anything else but a carriage return character,
currentLine += c; // add it to the end of the currentLine
}
// Check to see if the client request was "GET /H" or "GET /L":
if (currentLine.endsWith("GET /H")) {
digitalWrite(lControl, HIGH); // GET /H turns the LED on
}
if (currentLine.endsWith("GET /L")) {
digitalWrite(lControl, LOW); // GET /L turns the LED off
}
}
}
// close the connection:
client.stop();
// Serial.println("client disconnected");
}
}
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");
}
Labels:
Andriod,
app,
arduino,
IoT,
MIT app inventor 2,
MKR1000,
router,
Tutorial,
WiFi,
WiFi Shield
Sunday, August 7, 2016
Programming Arduino Zero, MKR1000, or any SAMD21 Arduino via Registers
In this video we look at how to program registers on Arduino's based on the SAMD21 MCU, like the Zero and MKR1000. To do this we will leverage the Atmel ASF data structures. This is a great way to access capabilities in the SAMD21 that are not covered by Arduino libraries. The link to the ASF documentation is http://asf.atmel.com/docs/3.16.0/samd21/html/annotated.html
Arduino code from video:
bool tog = false; //variable to toggle digital output
int cDiv = 1; //varible to hold clock divider
int count = 0; //variable to track when to switch clock freq
void setup() {
PM->CPUSEL.reg = PM_CPUSEL_CPUDIV(1); //Sets CPU frequency: power management struct, CPUSEL union, register variable
pinMode(3, OUTPUT); //set D3 to output
}
void loop() {
if(tog) tog = false; //if tog is true turn it false
else tog =true;
digitalWrite(3,tog); //set digital output
count++;
if(count > 6) { //check if it is time to change clock frequency
if(cDiv == 1) cDiv = 4;
else cDiv = 1;
PM->CPUSEL.reg = PM_CPUSEL_CPUDIV(cDiv); //PM_CPUSEL_CPUDIV_DIV4_Val
count = 0;
}
}
Sunday, July 24, 2016
Using the nRF24L01’s IRQ Pin to Generate an Interrupt with Arduino
In this video we look at how to use the pulse signal from an nRF24L01+ transceiver module's IRQ pin to trigger an interrupt on your Arduino.
Arduino code from video, receiver code first and then transmitter code:
#include <SPI.h> //Call SPI library so you can communicate with the nRF24L01+
#include <nRF24L01.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
#include <RF24.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
#include <avr/sleep.h> //library needed to use AVR based sleep API
const int pinCE = 9; //This pin is used to set the nRF24 to standby (0) or active mode (1)
const int pinCSN = 10; //This pin is used to tell the nRF24 whether the SPI communication is a command or message to send out
byte gotByte = 0; //used to store payload from transmit module
volatile int count = 0; //tracks the number of interrupts from IRQ
int pCount = 0; //tracks what last count value was so know when count has been updated
RF24 wirelessSPI(pinCE, pinCSN); // Declare object from nRF24 library (Create your wireless SPI)
const uint64_t pAddress = 0xB00B1E5000LL; //Create a pipe addresses for the 2 nodes to communicate over, the "LL" is for LongLong type
void setup() {
wirelessSPI.begin(); //Start the nRF24 module
wirelessSPI.setAutoAck(1); // Ensure autoACK is enabled so rec sends ack packet to let you know it got the transmit packet payload
wirelessSPI.enableAckPayload(); //allows you to include payload on ack packet
wirelessSPI.maskIRQ(1,1,0); //mask all IRQ triggers except for receive (1 is mask, 0 is no mask)
wirelessSPI.setPALevel(RF24_PA_LOW); //Set power level to low, won't work well at higher levels (interfer with receiver)
wirelessSPI.openReadingPipe(1,pAddress); //open pipe o for recieving meassages with pipe address
wirelessSPI.startListening(); // Start listening for messages
attachInterrupt(1, interruptFunction, FALLING); //Create interrupt: 0 for pin 2 or 1 for pin 3, the name of the interrupt function or ISR, and condition to trigger interrupt
}
void loop() {
if(pCount < count) { //If this is true it means count was interated and another interrupt occurred
Serial.begin(57600); //start serial to communicate process
Serial.print("Receive packet number ");
Serial.println(count);
Serial.end(); //have to end serial since it uses interrupts
pCount = count;
}
}
//This is the function called when the interrupt occurs (pin 2 goes high)
//this is often referred to as the interrupt service routine or ISR
//This cannot take any input arguments or return anything
void interruptFunction() {
count++; //up the receive counter
while(wirelessSPI.available()) { //get data sent from transmit
wirelessSPI.read( &gotByte, 1 ); //read one byte of data and store it in gotByte variable
}
}
//********************Transmitter code**************************** #include <SPI.h> //Call SPI library so you can communicate with the nRF24L01+
#include <nRF24L01.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
#include <RF24.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
const int pinCE = 9; //This pin is used to set the nRF24 to standby (0) or active mode (1)
const int pinCSN = 10; //This pin is used to tell the nRF24 whether the SPI communication is a command or message to send out
byte counter = 1; //used to count the packets sent
RF24 wirelessSPI(pinCE, pinCSN); // Create your nRF24 object or wireless SPI connection
const uint64_t pAddress = 0xB00B1E5000LL; // Radio pipe addresses for the 2 nodes to communicate.
void setup()
{
Serial.begin(57600); //start serial to communicate process
wirelessSPI.begin(); //Start the nRF24 module
wirelessSPI.setAutoAck(1); // Ensure autoACK is enabled so rec sends ack packet to let you know it got the transmit packet payload
wirelessSPI.enableAckPayload(); // Allow optional ack payloads
wirelessSPI.setPALevel(RF24_PA_LOW);
wirelessSPI.openWritingPipe(pAddress); // pipe address that we will communicate over, must be the same for each nRF24 module
wirelessSPI.stopListening(); //transmitter so stop listening for data
randomSeed(analogRead(0)); //use random ADC value to seed random number algorithm
}
void loop() {
delay(random(100,5000)); //Generate delay time between 100msec and 5 sec
Serial.println("Sending packet");
if (!wirelessSPI.write( &counter, 1 )){ //if the send fails let the user know over serial monitor
Serial.println("packet delivery failed");
}
Serial.println();
}
Arduino code from video, receiver code first and then transmitter code:
#include <SPI.h> //Call SPI library so you can communicate with the nRF24L01+
#include <nRF24L01.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
#include <RF24.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
#include <avr/sleep.h> //library needed to use AVR based sleep API
const int pinCE = 9; //This pin is used to set the nRF24 to standby (0) or active mode (1)
const int pinCSN = 10; //This pin is used to tell the nRF24 whether the SPI communication is a command or message to send out
byte gotByte = 0; //used to store payload from transmit module
volatile int count = 0; //tracks the number of interrupts from IRQ
int pCount = 0; //tracks what last count value was so know when count has been updated
RF24 wirelessSPI(pinCE, pinCSN); // Declare object from nRF24 library (Create your wireless SPI)
const uint64_t pAddress = 0xB00B1E5000LL; //Create a pipe addresses for the 2 nodes to communicate over, the "LL" is for LongLong type
void setup() {
wirelessSPI.begin(); //Start the nRF24 module
wirelessSPI.setAutoAck(1); // Ensure autoACK is enabled so rec sends ack packet to let you know it got the transmit packet payload
wirelessSPI.enableAckPayload(); //allows you to include payload on ack packet
wirelessSPI.maskIRQ(1,1,0); //mask all IRQ triggers except for receive (1 is mask, 0 is no mask)
wirelessSPI.setPALevel(RF24_PA_LOW); //Set power level to low, won't work well at higher levels (interfer with receiver)
wirelessSPI.openReadingPipe(1,pAddress); //open pipe o for recieving meassages with pipe address
wirelessSPI.startListening(); // Start listening for messages
attachInterrupt(1, interruptFunction, FALLING); //Create interrupt: 0 for pin 2 or 1 for pin 3, the name of the interrupt function or ISR, and condition to trigger interrupt
}
void loop() {
if(pCount < count) { //If this is true it means count was interated and another interrupt occurred
Serial.begin(57600); //start serial to communicate process
Serial.print("Receive packet number ");
Serial.println(count);
Serial.end(); //have to end serial since it uses interrupts
pCount = count;
}
}
//This is the function called when the interrupt occurs (pin 2 goes high)
//this is often referred to as the interrupt service routine or ISR
//This cannot take any input arguments or return anything
void interruptFunction() {
count++; //up the receive counter
while(wirelessSPI.available()) { //get data sent from transmit
wirelessSPI.read( &gotByte, 1 ); //read one byte of data and store it in gotByte variable
}
}
//********************Transmitter code**************************** #include <SPI.h> //Call SPI library so you can communicate with the nRF24L01+
#include <nRF24L01.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
#include <RF24.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
const int pinCE = 9; //This pin is used to set the nRF24 to standby (0) or active mode (1)
const int pinCSN = 10; //This pin is used to tell the nRF24 whether the SPI communication is a command or message to send out
byte counter = 1; //used to count the packets sent
RF24 wirelessSPI(pinCE, pinCSN); // Create your nRF24 object or wireless SPI connection
const uint64_t pAddress = 0xB00B1E5000LL; // Radio pipe addresses for the 2 nodes to communicate.
void setup()
{
Serial.begin(57600); //start serial to communicate process
wirelessSPI.begin(); //Start the nRF24 module
wirelessSPI.setAutoAck(1); // Ensure autoACK is enabled so rec sends ack packet to let you know it got the transmit packet payload
wirelessSPI.enableAckPayload(); // Allow optional ack payloads
wirelessSPI.setPALevel(RF24_PA_LOW);
wirelessSPI.openWritingPipe(pAddress); // pipe address that we will communicate over, must be the same for each nRF24 module
wirelessSPI.stopListening(); //transmitter so stop listening for data
randomSeed(analogRead(0)); //use random ADC value to seed random number algorithm
}
void loop() {
delay(random(100,5000)); //Generate delay time between 100msec and 5 sec
Serial.println("Sending packet");
if (!wirelessSPI.write( &counter, 1 )){ //if the send fails let the user know over serial monitor
Serial.println("packet delivery failed");
}
Serial.println();
}
Saturday, July 2, 2016
Advanced PWM for Arduino Zero or any Atmel SAMD21 Based Arduino Board
The Arduino PWM library leaves a lot to be desired since it really only scratches the surface on PWM capabilities built into today's MCUs. In this video we look at how to unlock some of the more advanced PWM features on any Arduino board based on the Atmel SAMD21 32 bit ARM MCU.
Click here to access the Atmel programming API from the video
Arduino code from video***********************************************************
//This was used for ForceTronics YouTube tutorial on generating PWM signals with SAMD21 based Arduinos
//This code is public domain and can be used by anyone at their own risk
//Some of this code was leveraged from MartinL on Arduino Forum http://forum.arduino.cc/index.php?topic=346731.5;wap2
//sets the period of the PWM signal, PWM period = wPer / gen clock rate
volatile unsigned char wPer = 255;
//This variable is to generate the duty cycle of the PWM signal 0.5 --> 50%
volatile float pWMDC = .5;
//selects the gen clock for setting the waveform generator clock or sample rate
const unsigned char gClock = 4;
//sets the divide factor for the gen clk, 48MHz / 3 = 16MHz
const unsigned char dFactor = 3;
void setup()
{
pinMode(3, OUTPUT);
analogReadResolution(8); //set the ADC resolution to match the PWM max resolution (0 to 255)
REG_GCLK_GENDIV = GCLK_GENDIV_DIV(dFactor) | // Divide the main clock down by some factor to get generic clock
GCLK_GENDIV_ID(gClock); // Select Generic Clock (GCLK) 4
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization
REG_GCLK_GENCTRL = GCLK_GENCTRL_IDC |
GCLK_GENCTRL_GENEN | // Enable GCLK4
GCLK_GENCTRL_SRC_DFLL48M | // Set the 48MHz clock source
GCLK_GENCTRL_ID(gClock); // Select GCLK4
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization
// Enable the port multiplexer for the digital pin. Note commented out line is pin D7, other is D3
// PORT->Group[g_APinDescription[7].ulPort].PINCFG[g_APinDescription[7].ulPin].bit.PMUXEN = 1;
PORT->Group[g_APinDescription[3].ulPort].PINCFG[g_APinDescription[3].ulPin].bit.PMUXEN = 1;
//Connect the TCC0 timer to digital output - port pins are paired odd PMUO and even PMUXE (note D7 is commented out and D3 is not)
// PORT->Group[g_APinDescription[2].ulPort].PMUX[g_APinDescription[2].ulPin >> 1].reg = PORT_PMUX_PMUXO_F | PORT_PMUX_PMUXE_F;
PORT->Group[g_APinDescription[4].ulPort].PMUX[g_APinDescription[4].ulPin >> 1].reg = PORT_PMUX_PMUXO_F | PORT_PMUX_PMUXE_F;
// Feed GCLK4 to TCC0 and TCC1
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_CLKEN | // Enable GCLK4 to TCC0 and TCC1
GCLK_CLKCTRL_GEN_GCLK4 | // Select GCLK4
GCLK_CLKCTRL_ID_TCC0_TCC1; // Feed GCLK4 to TCC0 and TCC1
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization
//Set for Single slope PWM operation: timers or counters count up to TOP value and then repeat
REG_TCC1_WAVE |= TCC_WAVE_WAVEGEN_NPWM; // Reverse the output polarity on all TCC0 outputs
//TCC_WAVE_POL(0xF) //this line inverts the output waveform
//TCC_WAVE_WAVEGEN_DSBOTH; // Setup dual slope PWM on TCC0
while (TCC1->SYNCBUSY.bit.WAVE); // Wait for synchronization
// Each timer counts up to a maximum or TOP value set by the PER register,
// this determines the frequency of the PWM operation:
REG_TCC1_PER = wPer; // This sets the rate or frequency of PWM signal.
while (TCC1->SYNCBUSY.bit.PER); // Wait for synchronization
// Set the PWM signal to output 50% duty cycle initially (0.5 x 255)
REG_TCC1_CC1 = pWMDC*wPer;
while (TCC1->SYNCBUSY.bit.CC1); // Wait for synchronization
//enable interrupts
REG_TCC1_INTENSET = TCC_INTENSET_OVF; //Set up interrupt at TOP of each PWM cycle
enable_interrupts(); //enable in NVIC
// Set prescaler and enable the outputs
REG_TCC1_CTRLA |= TCC_CTRLA_PRESCALER_DIV1 | // Divide GCLK4 by 1
TCC_CTRLA_ENABLE; // Enable the TCC0 output
while (TCC1->SYNCBUSY.bit.ENABLE); // Wait for synchronization
}
void loop() {
//Put main code here
}
//This function sets the interrupts priority to highest and then enables the PWM interrupt
void enable_interrupts() {
NVIC_SetPriority(TCC1_IRQn, 0); // Set the Nested Vector Interrupt Controller (NVIC) priority
NVIC_EnableIRQ(TCC1_IRQn);
}
//This ISR is called at the end or TOP of each PWM cycle
void TCC1_Handler() {
REG_TCC1_PER = analogRead(A1); //Get period from A1
while (TCC1->SYNCBUSY.bit.PER);
REG_TCC1_CC1 = (analogRead(A0)/255.0)*analogRead(A1); //calculate PWM using A0 reading and A1 current state
while (TCC1->SYNCBUSY.bit.CC1);
REG_TCC0_INTFLAG = TC_INTFLAG_OVF; //Need to reset interrupt
}
Monday, June 20, 2016
Building a Wireless Sensor Network with the nRF24L01 Part 6
In part 6 we look at the final hardware design, we switch to the TMRh20 library for the nRF24L01, and we look at a library wrapper that makes getting started with your own wireless sensor network real easy. Go to ForceTronics.com to purchase a wireless flex node and go to Github to access the code and PCB design files.
Subscribe to:
Posts (Atom)
