Easy IoT: Get Start With Particle Photon
Easy IoT: Get Start With Particle Photon
I'm trying to learn more about IoT and I found an amazing device - Particle Photon.This tutorial will teach you make easy IoT stuff with Particle Photon.
It's a super small device that includes everything you need to deploy an IoT product: a device cloud platform, connectivity hardware, and even SIMs for cellular products.
I want to use Lattepanda to collect the data from Particle and do some analysis job on it. LattePanda is a Win10 SBC that can perfectly work as a Home automation control center due to it's small size and powerful performance.
I used to use Blynk to play IoT, you can see the tutorial here.
What You Need
Hardware
Software
Particle Online IDEControl Everything With Your Phone!!
(I used to control the physical world with Blynk before. Here's the tutorial, IoT fun!)
If your device is new, it already has the Tinker firmware on it. It's the default firmware stored on your device right from the factory. When you put your own user firmware on your device, you'll rewrite the Tinker firmware.
You can access Tinker code by clicking on the last example in the online IDE's code menu or re-flash your device with Tinker in the Particle app.
Connect the longer (anode) leg of the LED to pin D0 and the shorter (cathode) leg to GND via a resistor. Try tapping the D0 pin on the screen again and again.
Tinker Code:
/* Function prototypes -------------------------------------------------------*/
int tinkerDigitalRead(String pin);
int tinkerDigitalWrite(String command);
int tinkerAnalogRead(String pin);
int tinkerAnalogWrite(String command);
/* This function is called once at start up ----------------------------------*/
void setup()
{
//Setup the Tinker application here
//Register all the Tinker functions
Particle.function("digitalread", tinkerDigitalRead);
Particle.function("digitalwrite", tinkerDigitalWrite);
Particle.function("analogread", tinkerAnalogRead);
Particle.function("analogwrite", tinkerAnalogWrite);
}
/* This function loops forever --------------------------------------------*/
void loop()
{
//This will run in a loop
}
/*******************************************************************************
* Function Name : tinkerDigitalRead
* Description : Reads the digital value of a given pin
* Input : Pin
* Output : None.
* Return : Value of the pin (0 or 1) in INT type
Returns a negative number on failure
*******************************************************************************/
int tinkerDigitalRead(String pin)
{
//convert ascii to integer
int pinNumber = pin.charAt(1) - '0';
//Sanity check to see if the pin numbers are within limits
if (pinNumber< 0 || pinNumber >7) return -1;
if(pin.startsWith("D"))
{
pinMode(pinNumber, INPUT_PULLDOWN);
return digitalRead(pinNumber);
}
else if (pin.startsWith("A"))
{
pinMode(pinNumber+10, INPUT_PULLDOWN);
return digitalRead(pinNumber+10);
}
return -2;
}
/*******************************************************************************
* Function Name : tinkerDigitalWrite
* Description : Sets the specified pin HIGH or LOW
* Input : Pin and value
* Output : None.
* Return : 1 on success and a negative number on failure
*******************************************************************************/
int tinkerDigitalWrite(String command)
{
bool value = 0;
//convert ascii to integer
int pinNumber = command.charAt(1) - '0';
//Sanity check to see if the pin numbers are within limits
if (pinNumber< 0 || pinNumber >7) return -1;
if(command.substring(3,7) == "HIGH") value = 1;
else if(command.substring(3,6) == "LOW") value = 0;
else return -2;
if(command.startsWith("D"))
{
pinMode(pinNumber, OUTPUT);
digitalWrite(pinNumber, value);
return 1;
}
else if(command.startsWith("A"))
{
pinMode(pinNumber+10, OUTPUT);
digitalWrite(pinNumber+10, value);
return 1;
}
else return -3;
}
/*******************************************************************************
* Function Name : tinkerAnalogRead
* Description : Reads the analog value of a pin
* Input : Pin
* Output : None.
* Return : Returns the analog value in INT type (0 to 4095)
Returns a negative number on failure
*******************************************************************************/
int tinkerAnalogRead(String pin)
{
//convert ascii to integer
int pinNumber = pin.charAt(1) - '0';
//Sanity check to see if the pin numbers are within limits
if (pinNumber< 0 || pinNumber >7) return -1;
if(pin.startsWith("D"))
{
return -3;
}
else if (pin.startsWith("A"))
{
return analogRead(pinNumber+10);
}
return -2;
}
/*******************************************************************************
* Function Name : tinkerAnalogWrite
* Description : Writes an analog value (PWM) to the specified pin
* Input : Pin and Value (0 to 255)
* Output : None.
* Return : 1 on success and a negative number on failure
*******************************************************************************/
int tinkerAnalogWrite(String command)
{
//convert ascii to integer
int pinNumber = command.charAt(1) - '0';
//Sanity check to see if the pin numbers are within limits
if (pinNumber< 0 || pinNumber >7) return -1;
String value = command.substring(3);
if(command.startsWith("D"))
{
pinMode(pinNumber, OUTPUT);
analogWrite(pinNumber, value.toInt());
return 1;
}
else if(command.startsWith("A"))
{
pinMode(pinNumber+10, OUTPUT);
analogWrite(pinNumber+10, value.toInt());
return 1;
}
else return -2;
}
Control LEDs Over the 'net
That's where the fun begins.
Connect the longer (anode) leg of the LED to pin D0 and the shorter (cathode) leg to GND.
Loading the following code onto your device. Copy and paste this code into a new application on http://build.particle.io or on Particle Dev.
Code:
// -----------------------------------
// 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</p><p>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);
return 1;
}
else if (command=="off") {
digitalWrite(led1,LOW);
digitalWrite(led2,LOW);
return 0;
}
else {
return -1;
}
}
Use the following to view your page:
/* Paste the code between the dashes below into a .txt file and save it as an .html file. Replace your-device-ID-goes-here with your actual device ID and your-access-token-goes-here with your actual access token.
---------------------------
<!-- Replace your-device-ID-goes-here with your actual device ID and replace your-access-token-goes-here with your actual access token-->
<!DOCTYPE>
<html>
<body>
<center>
<br>
<br>
<br>
<form action="https://api.particle.io/v1/devices/your-device-ID-goes-here/led?access_token=your-access-token-goes-here" method="POST">
Tell your device what to do!<br>
<br>
<input type="radio" name="arg" value="on">Turn the LED on.
<br>
<input type="radio" name="arg" value="off">Turn the LED off.
<br>
<br>
<input type="submit" value="Do it!">
</form>
</center>
</body>
</html>
---------------------------
*/
Edit the code in your text file so that "your-device-ID-goes-here" is your actual device ID, and "your-access-token-goes-here" is your actual access token. These things are accessible through your IDE at build.particle.io. Your device ID can be found in your Devices drawer (the crosshairs) when you click on the device you want to use, and your access token can be found in settings (the cogwheel). Open that .html file in a browser. You'll see a very simple HTML form that allows you to select whether you'd like to turn the LED on or off.
Make a Motion Detector
In this part, you will learn how to publish the data to the cloud. Then you can check the state of your sensor easily. We use a touch sensorand a crash sensoras the input (you can use your own digital sensor), Every time the sensor is touched, your device will send a Particle.publish to the cloud letting it know the state of the sensor.
Connect all the component as the picture show:
You can check out the results on your console at https://console.particle.io/. You can also get the state of the sensor on the other device.
Loading the following code onto your device. Copy and paste this code into a new application on http://build.particle.io or on Particle Dev.
Code:
int led = D0;
int boardLed = D3;
int crashButton = D1;
bool flag1= false;
bool flag2 = false;
void setup() {
pinMode(led,OUTPUT);
pinMode(boardLed,OUTPUT);
Particle.subscribe("SensorValue", myHandler);
Particle.subscribe("SensorValue2", myHandler2);
}
void loop() {
if (digitalRead(D1) == HIGH && (flag1 == false))
{
Particle.publish("SensorValue","HIGH");
flag1 = true;
}
else
{
}
if (digitalRead(D1) == LOW && (flag1 == true))
{
Particle.publish("SensorValue","LOW");
flag1 = false;
}
else
{
}
if (digitalRead(D2) == HIGH && (flag2 == false))
{
Particle.publish("SensorValue2","YES");
flag2 = true;
}
else
{
}
if (digitalRead(D2) == LOW && (flag2 == true))
{
Particle.publish("SensorValue2","NO");
flag2 = false;
}
else
{
}
delay(50);
}
void myHandler(const char *event, const char *data)
{
if (strcmp(data,"HIGH")==0) {
// if your buddy's beam is intact, then turn your board LED off
digitalWrite(led,HIGH);
}
else if (strcmp(data,"LOW")==0) {
// if your buddy's beam is broken, turn your board LED on
digitalWrite(led,LOW);
}
else {
// if the data is something else, don't do anything.
// Really the data shouldn't be anything but those two listed above.
}
}
void myHandler2(const char *event, const char *data)
{
if (strcmp(data,"YES")==0) {
// if your buddy's beam is intact, then turn your board LED off
digitalWrite(boardLed,HIGH);
}
else if (strcmp(data,"NO")==0) {
// if your buddy's beam is broken, turn your board LED on
digitalWrite(boardLed,LOW);
}
else {
// if the data is something else, don't do anything.
// Really the data shouldn't be anything but those two listed above.
}
}
To Be Continued
Since Lattepanda runs Win10 system, it can easily get the data from the cloud and do some analysis job. That's interesting. Here's the Windows SDK.
Enjoy!