Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
More and more IoT devices have become available over the past few years. Many of the new products unveiled at the Consumer Electronics Show (CES) are smart devices.
VIDEO: Everything Cool at CES 2017 (focus on smart devices)
Understanding existing products is an important part of the research phase when designing a new product. This is called competitive analysis. This type of research helps you better understand what's possible to create with the technology, what existing products offer to users, and where there may be opportunities for new or better products.
Research the design of any existing smart device of your choice (other than a smartphone or smart thermostat - also no computers, tablets, TVs, Blu-Ray/DVD players, game consoles, or headphones).
The smart device could be a consumer product (such as wearable device, smart home device, or smart car technology) or could be a smart device system for use in businesses, industry, cities, transportation systems, infrastructure, or environmental monitoring.
Here are some resources to help find a smart device to research (but you are not limited to these - also you will want to find a product website and articles about the product):
IOTLIST - browse examples of consumer IoT products
Internet of Things Examples - for body, home, city, industry, and the environment
Research the smart device in order to create and deliver a presentation to the class that includes the following:
Introduce the product (include images), and give your description of the product’s value proposition.
Summarize the key functions and features of the product, as well as its benefits for people.
Give your description of the target users for the product, and provide a brief scenario (story) of the product being used. The target user description would include: demographics (age, gender, family status, etc.), current frustrations or problems that product helps solve, important needs or values that product helps fulfill, etc.
Show your system model for the product, and explain how its parts work together. Your system model should include the product's inputs (sensors, etc.) and outputs, as well as any web services or apps that interact with the product.
Provide links to the specific information sources used in your research.
Your presentation to the class should be about 2-4 minutes in length (about 5-10 slides). Make sure both the visual and verbal portions of your presentation are clear and engaging. Be prepared to briefly respond to questions or comments from the audience.
Most people already carry around an IoT device – a smartphone. A smartphone has an impressive set of inputs, outputs, and network connections packed into a small but highly-capable computing device.
Research the Apple iPhone, Google Pixel, or Samsung Galaxy S to learn the following:
What kinds of inputs (such as sensors, etc.) does a typical smartphone have to gather or receive data from the environment or a user? What are these inputs used for?
What kinds of outputs does a typical smartphone have? How are these outputs matched to our human senses (our body's inputs)?
What kinds of network connections is a typical smartphone capable of making? When or how are these different connections used?
Use this assignment template to record your research findings. (Hint: Look for the technical specs listed on the smartphone webpages.)
UPDATE AVAILABLE: This project guidebook has been replaced with a new version. This older version will no longer be available after August 1, 2019.
Your project challenge is to design and build an IoT device and web app that could improve or benefit your school community.
Your team will solve the project challenge by applying a user-centered design process that follows an iterative "Learn-Build-Measure" cycle.
Research Problem Space - Let's start by exploring existing IoT devices and the technology you'll use to build your own smart devices. You will also begin to frame the goals of your team's project by learning about potential stakeholders and generating initial ideas for what problem to solve.
Define Problem to Solve - Your team will evaluate its set of ideas for what problem to solve through deliberation and feedback. After conducting additional user research on your selected problem, you will describe your target stakeholders, the current user experience, the value proposition of your solution, and the design requirements for your solution.
Design Solution & Deliver Proposal - Generate, evaluate, and refine your ideas for a solution. Create a detailed solution design for evaluation by stakeholders. Present your targeted problem and proposed solution for critique by other design teams.
Build & Develop Solution - During development, track your team's progress and any issues that arise.
Construct your smart device by connecting the necessary parts. Plan out and code your device app and web app. Conduct integration testing to ensure your solution works properly. Create a product demo video and product marketing website.
Evaluate & Improve Solution - After creating your solution, test the solution with target stakeholders to gather feedback on improvements to make or additional features to add.
Reflect & Present Project Results - At a public poster presentation, explain your team's design process and demonstrate your solution. Be prepared to respond to questions. Each team member will reflect on his or her contributions and how this project experience impacted future college and career interests.
The Nest Learning Thermostat is a smart thermostat for homes that was first released in 2011. Nest now offers other smart home devices. In 2014, Google bought Nest for over $3 billion.
VIDEO:
What types of people do you think are the target users for this product? What characteristics do these target users probably have? Use this information to create a persona summarizing a target user for this product.
The smart lightbulb was introduced in 2012, and now several companies offer smart lightbulbs. Smart lightbulbs can be controlled remotely using a mobile app and offer features like setting automatic on-off schedules, dimming lights, changing the light color, syncing lights to music, etc.
VIDEO:
As an introduction to building and programming IoT devices using your Photon kit, your team will create a prototype of a smart lightbulb that can be controlled by a web app.
Your team will build its prototype of a smart lightbulb in four versions (or iterations) that keep getting closer to the end result. Each time you will modify your existing Photon device and your existing Photon code.
Prototype Version 1: Connect LED light to Photon device, and have Photon code turn light on and off in repeating cycle.
Prototype Version 2: Add push button to Photon device, and have Photon code turn on light when button is pressed.
Prototype Version 3: Modify Photon code so button switches light on or off with each push, like a regular light switch.
Prototype Version 4: Modify Photon code so it interacts with a web app by sending and receiving data through Internet. Create web app that shows current status of light and allows user to switch light on or off remotely.
Since this is practice, the instructions provided below will tell you which parts are needed, show you how to connect them, and even provide the code needed.
Your focus should be on:
understanding how to connect the parts to form circuits that power the parts and transfer data
understanding how the Photon code controls the parts and processes data
understanding how the Photon code and a web app can interact by sending and receiving data through the Internet
Each part (such as LED, etc.) that you connect to your Photon device must have a complete electrical circuit. The jumper wires and breadboard are used to help make a circuit for each part.
GOAL: Connect LED light to Photon device, and have Photon code turn light on and off in repeating cycle.
NOTE: LED lights need to be connected correctly. They are polarized (meaning they have a positive end and a negative end), and they need to be connected through a resistor (to limit the current that flows through the bulb). Pay attention to the diagrams and instructions in the experiment.
GOAL: Add push button to Photon device, and have Photon code turn light on when button is pressed.
For the Photon code, modify your existing code from the previous step. The complete code for Experiment 2 is shown below.
The push buttons included in your kit are classified as momentary switches, meaning they are only active ("on") when they are being pushed. Everyday examples of momentary switches are doorbell switches and the keys on a computer keyboard.
GOAL: Modify Photon code so button switches light on or off with each push.
You will modify your existing Photon code to make the push button act similar to a maintained switch, which maintain their current state (on or off) until pushed again. This is how most light switches operate.
To do this, you need to create a global variable in the Photon code to keep track of the light's current state (on or off), so the light can be switched to the opposite state when the button is pushed again. Let's name this variable as: ledStatus
There are several possible data types that could be used for this variable, but we have to select only one to use:
Although any of those data types above would work, the code might be easier to understand if we use a String variable to track ledStatus
as "off" or "on" by changing the variable's value whenever the button is pushed.
Since we still need global variables for the LED pin and the push button pin, our final list of global variables will be:
Let's make sure the light is actually off when the device first starts (so it matches the initial ledStatus
assigned in the global variables). To do this, add a statement within the setup()
function.
Let's add a custom function at the end of the Photon code that will toggle the light on or off based on the current ledStatus
. Let's name this function as: ledToggle()
Now you can "call" (run) this custom function within the loop()
whenever the button is pushed:
Notice that a slight delay was included before reading the button again. (The delay command uses milliseconds, so 1000 milliseconds = 1 second.)
Without a delay (or if the delay is too short), the code loops so fast that it toggles the light on and off multiple times with each button press, making the device seem unpredictable. If the delay is too long, the device feels unresponsive because you have to hold down the button longer to have the code detect the press.
Remember to flash the modified app to your Photon device to test it out.
GOAL: Modify Photon code so it interacts with a web app by sending and receiving data through Internet. Create a web app that shows current status of light and allows user to switch light on or off remotely.
You will modify your existing Photon code to send and receive data through the Particle Cloud service. Then you will create a web app that uses the Particle JavaScript library to send and receive data through the Particle Cloud.
Particle has built-in functions to share data through the Particle Cloud service. This is how your Photon device can interact with other apps (or even with other Photon devices).
We want to share the ledStatus
variable with our web app, so we can display the current status of the light. We can share the current value of a variable by adding one line of code to the setup()
function:
We need to first tell it what name to call the variable in Particle Cloud (name can be up to 12 characters) and then identify the name of the variable in the Photon code. Usually, these two will have the same name (but they don't have to).
Next, we want to be able to receive data from our web app, so we can run the function to toggle the light on or off when the user clicks a button in the web app. Again, we can do this by adding one line of code to the the setup()
function:
We need to first tell it what name to call the function in Particle Cloud (name can be up to 12 characters) and then identify the name of the function in the Photon code to run. These can have the same name or be different.
We will also need to modify our ledToggle()
function. If we want to use the Particle Cloud to call a function in our Photon code, then the function in the Photon code must return a int
value (instead of void
or some other data type) – and the function must accept a String
value from the Particle Cloud (the string is the data that our web app sends to the Photon device).
However, you do not necessarily have to do any with the function's return value or even with the String value – they just need to be present in the code for it to communicate properly with Particle Cloud.
The modified ledToggle()
function is as follows:
Now we have to also modify the line of Photon code in the loop that calls this function when the user pushes the button on the device. We must pass a string value to the function (even though we decided to not actually use this string for anything inside the function).
The modified loop()
function is as follows (only change is adding "toggle"
):
That takes care of the changes in the Photon code. Remember to flash the modified app to your Photon device.
Create a new HTML file (index.html), CSS file (style.css), and JavaScript file (code.js) using a code editor (such as Editey in Google Drive, etc.). Make sure the files are blank.
Copy and paste the HTML code below into index.html
Notice that the HTML <head>
section loads 3 JavaScript files:
jQuery which is a JavaScript library that makes it easier to do things like change HTML or CSS in your web app
Particle API JS which is a JavaScript library that contains functions that allows your web app do things like share data through Particle Cloud
code.js which is your own JavaScript file that will get data from your Photon device, send data to your Photon device, and update your web app to show the current status of your Photon device.
Notice that we've assigned unique id names to several elements within the <body>
section. This will allow us to use jQuery functions to change these elements.
Finally, notice that we added an onclick event to the <button>
that will run a JavaScript function called toggleLight()
which will be in your code.js file.
Next, copy and paste the CSS code below into style.css
The CSS will make our web app look nicer. The <div>
in the HTML is styled to look like a card. The background color will be gray when the light is off but will be changed to yellow when the light is on.
We will change this background color by using jQuery to add the class of .light-on
to the <div>
if the data from the Particle Cloud tells us the light is on. When the light is turned off, we will use jQuery to remove that class (making the card gray again).
Finally, copy and paste the JavaScript code below into code.js
Notice that the first two lines of JavaScript are supposed to list your Photon device ID and your Photon access token, which must be copied and pasted from your Particle Build account.
IMPORTANT: If you don't update these first two lines of JS code, your web app will not work properly.
Your Photon device ID is listed in the "Devices" section of your Particle Build account. Click the arrow to the right of your Photon device name to reveal the device ID. This device ID acts like a username to access your device's data in the Particle Cloud service.
Your Photon access token is listed in the "Settings" section of your Particle Build account. This access token acts as a password to access your device's data in the Particle Cloud service. (If you reset your access token at some future point, you would have to update your web app to use the new token.)
Next notice that we include a JavaScript statement that tells the webpage (window) to run the checkLight
function at an interval of once every 200 milliseconds. This lets the web app stay updated on the current status of the light.
Next, we list our checkLight()
function that we already told the web app to run every 200 milliseconds. Inside this function, it checks the current value of the ledStatus
variable that is being shared to the Particle Cloud by your Photon device.
Here's how particle.getVariable
in the web app matches up with Particle.variable
in the Photon code. Notice that what links them is the name "ledStatus"
– this is the variable in the Photon code that is being sharing through Particle Cloud.
Once we get the data result for the "ledStatus"
variable, we use jQuery statements to add or remove the class light-on
to switch the card background to yellow or gray and to update the text in two HTML elements.
Finally, the last thing in our JavaScript is the toggleLight()
function that will run whenever the user clicks the on-screen button. Inside this function, it calls the "led"
function through Particle Cloud and sends it data (the String argument, which we assigned a value of "toggle").
Here's how particle.callFunction
in the web app matches up with Particle.function
in the Photon code. Notice that what links them is the name "led"
– this is the function that the web app calls through Particle Cloud. When the Photon code receives this call, the Photon code runs the custom function called ledToggle
and passes it the String data sent by the the web app.
Be sure to refresh your web app, and it should now be able to interact with your Photon device. You should be able to push the physical button on the Photon device to switch the light on or off – and see that your web app shows the updated light status relatively quickly.
You should also be able to do the reverse: click the on-screen button in your web app to see that it toggles the light on your Photon device and then updates the light status on the web app.
NOTE: There may be a slight delay of about 0.5 second for the device and web app to sync up. Keep in mind that the web app was told to only run checkLight()
once every 0.2 seconds. We also told the Photon code to add its own delay of 0.2 seconds because of the push button. Also, the data is traveling from an app on one device through the Internet to Particle Cloud and then back again through the Internet to the other app on a different device. (Remember data is not being transferred through the USB cable – it only provides power.)
If you have time, you could think about ways to modify the smart lightbulb and its apps. Can you further customize the appearance of the web app? Can you add a second LED light and second button to your Photon device – and then modify your Photon app and web app to control each light separately? What are some other features that you could try to add to the smart lightbulb web app (dimming lights, setting on-off schedule, etc.)?
Your team's is to design and build a smart device that could improve or benefit your school. Your goal is to create a useful and innovative solution that solves a problem, fulfills a need, or improves an existing situation in the school community or school environment.
Each team member should generate his or her own set of possible ideas for what problem your project might solve. Later on, your team will share and discuss their ideas, in order to evaluate and refine them to select the problem to tackle for your project. (After that, your team will go through another process to generate, evaluate, and refine ideas for the solution to your selected problem.)
Over the next couple of weeks outside of class (while your team is building a smart thermostat during class), you should "look and listen" by observing problems or issues around school and talking with stakeholders affected by these issues.
Stakeholders from the school community might include students, teachers, administrators, staff, parents, etc. Depending on the problem, the stakeholders might belong to specific subgroups such as: student athletes, students involved in extra-curricular activities, maintenance staff, cafeteria staff, etc.
Here are a few tips:
Don't worry about knowing all the details yet about the problems. Record enough information to be able to explain the ideas to your team. If needed, your team can gather more information later if an idea seems worth pursuing.
Don't worry about how "good" each idea is. Your team will discuss and evaluate the ideas later. Sometimes an idea that doesn't seem promising at first turns out to be a great idea.
Don't worry yet about trying to come up with solutions to the problems. Your team will focus on figuring out possible solutions later.
UPDATE AVAILABLE: This project guidebook has been replaced with a . This older version will no longer be available after August 1, 2019.
A growing trend in computing is the “Internet of Things” (abbreviated as: IoT) – objects or devices connected to the Internet (and/or to other devices) that can gather, process, and share data. These are also called connected devices or smart devices.
Most people already carry around an IoT device with them – a smartphone. Now many other connected devices are becoming available to consumers, businesses, and cities: wearable devices that track your health and fitness, voice-activated speakers that serve as a virtual assistant, smart thermostats that learn how to keep your home comfortable while also saving energy, smart streetlights that automatically brighten or dim based on how many pedestrians or vehicles are nearby, etc.
Smart devices are programmed to process data and respond automatically to certain conditions. They have inputs, such as sensors, that gather data from the physical environment and/or outputs, such as actuators, that do something in the physical environment. Smart devices also send and/or receive data by communicating with apps, databases, or other devices through a network connection.
The Internet of Things has become possible due to advances in technology and manufacturing. Computing parts (such as chips, sensors, batteries, etc.) have become much smaller, more powerful, more energy-efficient, and less expensive. Wireless networking (such as cellular, Wi-Fi, Bluetooth, etc.) has become much faster, more energy-efficient, and more widespread. These advances have made it feasible to incorporate computing technology into almost any object, device, or environment.
Additional Resources for Background:
Copyright © 2016-2017 Michael Frontz and Jim Lyst, Indiana University School of Informatics and Computing at IUPUI
Research the to better understand its design:
What are the key functions and features of this product? What advantages does it have over similar products? Use this information to define the product’s (one-sentence summary of what problem it solves and what benefit it provides).
What are the inputs (such as sensors, etc.) and outputs of this product? What web services or apps does it interact with? How do all these parts work together? Use this information to create a representing how this product works.
Use this to record your research notes and construct your value proposition, persona, and system model.
If this is your first time using an electronics kit, then read this helpful background about .
Complete of the online SparkFun Photon Experiment Guide. Only complete the first part – skip Part 2.
For the Photon code, just modify (or copy) your existing . That code is identical to the code for Experiment 1, except for the pin being used for the LED. In Hello World, you used pin D7 (built-in LED). In Experiment 1, you are instructed to connect an LED light bulb to pin D0. So just change this one line of code as shown below:
Complete of the online SparkFun Photon Experiment Guide. Only complete the first part – skip Part 2.
Each team member should generate and record at least 5 possible ideas for problems to solve using .
This project is part of the high school computer science curriculum developed for the program, an award-winning community partnership in central Indiana that is broadening student participation in computing and helping students develop the skills essential for success in the 21st century workplace.
This work is licensed under a . You are free to use, share, or adapt this material for noncommercial purposes as long as you provide proper attribution and distribute any copies or adaptations under this same license.
UPDATE AVAILABLE: This project guidebook has been replaced with a new version. This older version will no longer be available after August 1, 2019.
Design and build a smart device that could improve or benefit your school. Your goal is to provide a useful and innovative solution to a problem affecting the school community or school environment.
Each team will build and program a smart device using an IoT electronics kit that has a microcontroller with Wi-Fi capability, as well as various inputs and outputs that can be connected. Each team will also design and program a web app (for phone, tablet, or desktop) that interacts with the smart device. In addition, each team will create a product marketing website for their smart device.
At the end of the semester, all teams will demonstrate and explain their smart devices at a public poster presentation.
Useful: Smart device and web app should provide value by solving a problem, fulfilling a need, or improving an existing situation in the school.
Usable: Smart device and web app should be easy to understand and interact with.
Feasible: Smart device should be possible to prototype and could become a real product.
Innovative: Smart device should be unique or different from existing products or solutions.
Smart device built using Photon electronics kit
Smart device Photon app coded using Wiring programming language
Smart device web app coded using HTML, CSS, and JavaScript
Smart device prototype may have to be smaller-scale model of actual product installation and/or may have to simulate certain parts
Product Design Lead: leads interaction design and evaluation of product
Product Development Lead: leads building and programming of product
Product Marketing Lead: leads research and marketing for product
Product Manager: manages team to ensure work results in quality product
Teams of 2 need to have a Design Lead and a Development Lead. Each person can also assume one of the other two roles.
Teams of 3 need to have a Design Lead, a Development Lead, and a Marketing Lead. One person can also assume the role of Project Manager.
Teams of 4 need all four roles.
Smart Device with Photon app that is a functional prototype
Web App that interacts with smart device by sending and/or receiving data through Internet
Product Marketing Website for the solution, which includes a product demo video
Poster Presentation to demonstrate solution and explain how it was designed, built, and tested
Next your team will select its final idea for what problem to solve, and conduct user research to learn more about the problem and the people affected by it.
The user research will consist of a field study to observe people experiencing the problem in a real context and interviews to ask people about their experiences with the problem. Ideally, you will both observe and interview each person.
NOTE: If it is not possible to directly observe people experiencing the problem (due to when and where it occurs), then during the interviews, ask each person to recall in detail the last time they experienced the problem.
Your observations and interviews should gather data to help your team:
DEFINE THE PROBLEM: What are the steps involved in the current process? When and where does it occur? Who is involved? What are their goals and needs related to this process? What works well in the current process? What are the problems?
MEASURE THE IMPACT: What are the effects of the problem? If possible, try to quantify the effects, such as: extra time spent, effort wasted, extra cost, errors made, level of frustration, etc.
ANALYZE THE CAUSE: Why does the problem occur? Keep asking “why” until you discover the root cause(s).
Your team will use the data gathered during your research to help complete the next several project deliverables, which help further define the problem your team is solving:
Personas for Different Stakeholders
Journey Map of Current User Experience
Value Proposition of Solution
Design Requirements for Solution
In particular, you should preview the examples provided for the persona and journey map.
Your team should use this template to create a user research plan to gather data about the problem and the stakeholders (people) affected by the problem.
HINT: Once completed, your team's template could be printed and used to record your research notes. Print one copy for each person that you need to observe and interview.
Select the final idea for what problem your team project will solve.
Identify 2 different groups of stakeholders affected by the problem (such as: students, teachers, administrators, staff, etc.). Even if the problem only seems to affect one group (such as: students that get food from the cafeteria), try to identify two subgroups (such as: students that only occasionally get food from the cafeteria vs. students that regularly get food from the cafeteria).
Identify what background information would be relevant to gather about each stakeholder (such as: gender, age, etc.).
Prepare list of 3-5 focus questions that your team will try to answer through the field study observations.
Prepare list of 3-5 open-ended questions that your team will ask people during the interviews. If helpful, here is an article on open-ended versus closed-ended questions in user research.
Discuss specific plans to make sure your team will observe and interview at least 3 people from each of your 2 stakeholder groups for a total of at least 6 people. Each team member should observe and interview at least 2 people (but may need to complete more).
Conduct the user research over the next couple of days. Each team member should record detailed notes for each observation and interview conducted, so that all the team's data can be compiled together.
During the next class meeting, you will have the opportunity to practice your interviews with students from other teams. This will give your team a chance to revise its questions (if necessary) before you collect data from people outside of class. Data collected in-class can be used by your team, but your team still needs data from people outside of class.
Your team will build and program smart devices using an IoT electronics kit featuring the Photon P1 microcontroller, which is produced by a company called Particle.
A microcontroller is a small computer on a single integrated circuit that contains a processor (CPU), memory (RAM and storage), and programmable inputs and outputs. The Photon microcontroller also has an integrated Wi-Fi chip, which makes it great for IoT products.
The Photon electronics kit that your team will use comes from another company called SparkFun. SparkFun has incorporated the Particle Photon P1 microcontroller into an electronics board (which SparkFun calls a "RedBoard") that makes it easy to build devices using various inputs and outputs, such as the ones included in the kit.
VIDEO: SparkFun Photon Kit
Briefly look over this overview of the Photon RedBoard to become familiar with its power supply, buttons, and LEDs. How can you power the Photon device? What does the reset button do? What does the RGB LED tell you about the status of your Photon device?
Turn on your Photon device by carefully inserting the USB cable into the Micro-USB port on the device (be absolutely sure the correct side of the Micro-USB plug is facing up) and plugging the other end of the cable into a USB port on a computer or charger. Your Photon will try to connect to Wi-Fi (we've already saved a Wi-Fi login on the device). Once you have verified that your Photon device is connected to Wi-Fi and the Particle Cloud, you're ready for the next step.
Save and run this Hello World app on your team's Photon device by using your team's Particle Build account.
Finish up by identifying the name and function of all the parts included in your team's Photon kit by labeling this set of pictures. (Hint: Check the SparkFun Photon Experiment Guide for a list of the parts and match them to the pictures.)
A persona is a model of a target user for a product or service. A persona summarizes the target user’s background, goals, and needs. The persona helps you design a solution to meet the target user’s expectations.
A persona is based on data collected from multiple users through observations, interviews, surveys, etc. However, the persona is presented as a description of an individual person, even though the persona actually represents a group of users with similar characteristics.
The reason for presenting the user data as an individual person is because it is easier to empathize with a description of a specific person, rather than a set of statistics summarizing an entire group.
Here is an example of a persona created for a travel booking website:
VIDEO: What are personas, and why should I care?
A product or service might have many different types of users with different backgrounds, goals, and needs. Therefore, different personas could be created to model these different types of users.
However, it may not be possible (or desirable) to design an solution that tries to meet the needs of every possible type of user. Often this results in a solution that doesn’t actually satisfy anyone. Instead, it is recommended to identify the primary type (or types) of users that represent your main target for designing your solution.
It is important that a persona is fictional (not an actual individual) yet realistic (based on data from actual users). Since the goal is to develop empathy for the target users, a persona should not be humorous.
There are different formats for personas, but personas are usually condensed to one-page in length and often contain information such as:
Profile (background information about user):
Photo (fictional - use stock photo)
Name (fictional - first name is sufficient)
Type of User (label or category)
Relevant Demographic Information (might include: age, gender, occupation/role, etc.)
Other Relevant Information or Context (might include: description of physical, social, and technological environment in which product/service will be used; user’s proficiency with technology; special knowledge or skills; personality traits; quote from user; etc.)
Goals (what high-level goals does user want to achieve with product/service, and what tasks does user need to complete in order to meet these goals)
Anxieties and Motivations (what influences user’s behaviors and decisions related to adopting possible new solution to meet goals)
Frustrations (what pain points does user experience with current situation or current solution)
Needs and Expectations (what are user’s expectations related to functionality, usability, and user experience of possible new solution)
Identify two different types of users (stakeholders) that will be your main targets for designing your solution.
For example, your stakeholders might have different roles (such as: students, teachers, administrators, staff, etc.). Even if there only seems to be one group that you are targeting (such as: students that get food from the cafeteria), try to identify two subgroups that may have different needs (such as: students that only occasionally get food from the cafeteria vs. students that regularly get food from the cafeteria).
Use your team’s research data to construct a separate persona for each of these two types of users using this template.
EXAMPLE: Here is an example of a persona for a smart student attendance system created with this template.
A journey map is a diagram of a user’s experience during different steps before, during, and after using a process, product, or service to accomplish a goal.
A journey map is often used to understand the current user experience. The user’s emotion (ranging from positive to negative) is indicated for each step in the experience. Steps that cause negative emotions identify opportunities to improve the user experience through a new solution.
A journey map shows the experience for a particular type of user (i.e., a particular persona) during a specific scenario.
For example, imagine creating a journey map for visiting a doctor’s office. A brand new patient would probably have a different experience than a regular patient. A patient having a routine check-up would probably have a different experience than a patient receiving test results.
There are different formats for displaying journey maps. Here is an example of a journey map that uses emojis to show the experience of a repeat customer buying a drink from a coffee shop. Multiple customers were observed and interviewed to gather the data used to construct the journey map.
EXAMPLE:
The employees at the coffee shop could then use this journey map to identify the parts of the current user experience that are positive, neutral, or negative.
The positive experiences should be obviously be kept because these are the things your users enjoy about your current product or service. If possible, you should try to enhance, extend, or emphasize these positive experiences.
Even if there are very positive parts in the overall experience, it is critically important to fix or reduce the negative experiences. This is because users tend to remember the bad parts of an experience more than the good parts – this is called negativity bias.
You should also try to make the neutral experiences become more positive. Otherwise, there is a danger of them turning into negative experiences. In the coffee shop example, waiting in line for your drink starts off as a neutral experience. However, if the wait becomes too long, it becomes a negative experience. What if the coffee shop could figure out a way to actually make waiting an enjoyable experience?
The point is that you cannot provide a better user experience until you know what is – and what isn't – working well in the current experience. This is true whether you are trying to improve an existing solution or trying to design a brand new solution.
Construct a journey map of the current user experience for one of your target user personas:
Use your team’s research data to identify the sequence of steps involved in the current process (i.e., without your smart device) for the persona. For each step, identify the persona’s emotional reaction (from positive to negative). For example, if your team is focusing on improving student lockers, show the current experience of how students use their lockers to show what is good and bad about using the current lockers.
Use this drawing template to construct your journey map. Add text boxes to briefly describe each step, and represent the persona’s emotion at each step with a corresponding emoji. A range of emoji has been included in the template for you to use. Just delete any emoji that you don't need for your journey map. (If necessary, you can download other emoji images from EmojiOne.)
Connect the emojis with arrows to create a line graph of the user experience over time. Any steps that show a decrease or that have negative emotions represent opportunities for your team to design an improved solution (i.e., your smart device) that will provide a better user experience.
Within your team, you will share and discuss the possible project ideas generated by each team member. Your team will use a graph to help evaluate the ideas to determine its top 3 ideas for what problem to solve. Then your team will gather additional feedback on its top 3 ideas from potential stakeholders.
Each team member should briefly explain his or her possible ideas for what problem your team project might solve. As a group, briefly discuss each idea, and then plot each idea on this graph based on:
how much your team is interested in solving the problem (from LOW to HIGH)
how much the school community would benefit from solving the problem (from LOW to HIGH)
On the graph, each idea will be represented by a circle with a unique number. Five numbered circles have been provided that you should drag-and-drop into the graph to plot ideas. Copy-and-paste to create more circles, and then change their numbers (to make 6, 7, 8, etc.).
TIP: The graph can be modified by clicking it and selecting the "Edit" link below the graph.
Below the graph, provide a legend that summarizes the idea represented by each number.
EXAMPLE: Here is an example of a completed graph with ten ideas plotted.
Each idea should be plotted relative to the other ideas.
For example, if there is less team interest in the current idea compared to another idea, the current idea should be located further left than the other idea. If the current idea will have a greater community benefit compared to the other idea, the current idea should be located higher than the other idea.
After plotting circles for all the ideas, your team should select its top 3 project ideas, and fill out the table on the second page of the graph.
HINT: You will probably want to select ideas located towards the upper right of your graph.
Share your top 3 project ideas with stakeholders that might be affected by these problems, so you can get their feedback on how much they are interested in having these problems solved.
Now that your team has observed and interviewed stakeholders, you should compile and share all your user research data electronically, so that your team can analyze and use the data.
Transfer your handwritten research notes into a digital version using this spreadsheet template. Your team should enter all its data into one shared spreadsheet.
The research notes from each person (user) that was observed and interviewed will be listed in a separate row. Each user will be identified by a code (U1, U2, U3, etc.) instead of their real name (to keep them anonymous).
For each user, list the name of the team member who conducted the interview, and list the type of stakeholder that the user represents.
The spreadsheet has 3 generic columns to record: (1) relevant background info about the user, (2) notes from your observation of the user (either your direct observation or the user's recalled experience), and (3) notes from your interview of the user.
NOTE: It may be better to replace some or all of these 3 generic columns with specific columns for each of the questions listed in your team's user research plan. This will allow you to list specific notes under specific questions, making it much easier to compare and analyze the data from all the users.
The Nest Learning Thermostat was introduced in 2011, and now several companies offer smart thermostats. Smart thermostats can be controlled remotely using a mobile app and offer features like adjusting the temperature, creating temperature schedules, reviewing energy usage, etc.
As further practice building and programming IoT devices with your Photon kit, your team will create a prototype of a smart thermostat that can be controlled by a web app.
However for this practice, you will only be given partial instructions. Your team will have to figure out the rest in order to build the device and program its apps.
Your team will need to carefully read through these instructions. Only ask questions if you have first read the instructions.
It might be helpful to have your team members divide up the work:
one person could build the device by connecting the parts
another person could program the Photon app
a third person could program the web app
Here is a system model showing how the parts of the smart thermostat prototype are supposed to work together:
Device (and web app) display room temperature, temperature setting, and system status (Off, Heating, Cooling).
Device (and web app) allow user to change desired temperature setting using buttons.
Device reads current room temperature.
Device compares room temperature with temperature setting to control system:
If room temperature is lower than temperature setting, device turns on heating system (represented by red LED).
If room temperature is higher than temperature setting, device turns on cooling system (represented by blue LED).
If room temperature is equal to temperature setting, device turns off heating and cooling systems.
NOTE: To make this device simpler to build and program, this thermostat is designed to run in a dual mode where it may turn on heating or cooling during the same day. For example, people that live in desert climates (such as Arizona, etc.) would want a thermostat that runs in dual mode because it can get very hot during the day but very cool at night.
Most thermostats are designed to be in only one mode at a time: Heat Only, Cool Only, or Off. The "Heat" mode is used during the winter to only run the furnace. The "Cool" mode is used during the summer to only run the air conditioning. The "Off" mode is used during parts of the spring and fall when no heating or cooling is needed. Most thermostats have a separate button to change the system mode.
Here's a picture of a smart thermostat prototype to give you a general sense of how it will look when finished. While it might look complex, each individual part is relatively simple to connect. The instructions provide references that show how to connect each part.
Red LED (to represent heating system, such as furnace)
Blue LED (to represent cooling system, such as air conditioner)
2 Resistors (one for each LED)
Red Push Button (used to increase temperature setting)
Blue Push Button (used to decrease temperature setting)
RHT03 Humidity and Temperature Sensor
Micro OLED Display Screen
18 Jumper Wires
Make sure the parts are arranged in a logical layout that makes it easy for a person to understand and use the device.
Remember that all the parts have to be arranged so their pins are in their own breadboard rows:
If different parts are on the same side of the breadboard, the pins of different parts should not be in the same row number.
A resistor is an exception because it is supposed to share a row number with a pin of another part (such as LED, etc.).
If different parts are on opposite sides of the breadboard (left vs. right), it is perfectly fine if they use the same row numbers because the left-hand rows are not connected to the right-hand rows.
Different pins from the same part should not be in the same row number. For example, the OLED display has 8 pins, and each of these pins must be in a different row number on the breadboard.
TIP: Try to place the jumper wires on the side closest to the Photon board, so the wires don't block parts that need to be seen or interacted with.
You can use one power rail on the breadboard to provide power to all the parts (similar to how a power strip works):
Connect a jumper wire from the 3.3V (+) pin on the Photon board to a pinhole in the positive (+) column of the power rail closest to the Photon board.
Then connect another jumper wire from a pinhole in the negative (-) column of this power rail back to a GND (-) pin on the Photon board.
All other parts that you add to the breadboard can connect to this power rail through their own jumper wires. Some parts will only need to connect to the negative (-) rail because their voltage source (+) will come from a digital pin. Other parts will need to connect to both the positive (+) and negative (-) rails.
IMPORTANT: The OLED display screen can only handle 3.3 volts of power, so be sure to use the 3.3V pin as your voltage source. (Caution: The V-USB pin supplies 5V, which could damage the OLED.)
The Micro OLED display requires using 7 jumper wires to connect the OLED pins to specific pins on the Photon board. Therefore, you should probably connect the OLED first before adding the other parts.
This reference for the Micro OLED display explains how to connect the OLED and provides example code for displaying text on the OLED screen.
The other parts can be connected to any of the other digital pins (or analog pins such as A0 or A1) that are not being used by the OLED.
This reference for the RHT03 sensor explains how to connect the RHT03 Humidity and Temperature Sensor and provides example code for taking readings with the RHT03 sensor.
If helpful, there are also references for the LED light and push button that show how to connect them and provide example code for using them.
Create a new app in Particle Build titled: SMART-THERMOSTAT
Remember that the structure and order of the code for a Photon app is:
libraries (if needed for certain inputs or outputs)
global variables
setup()
function (can only have one)
loop()
function (can only have one)
custom functions (as many as needed)
If helpful, here is additional information (and references) for coding Photon apps.
Be sure that you include the libraries for the Micro OLED display and the RHT03 sensor. The code examples in the Micro OLED reference and the RHT03 sensor reference explain how to include the library for each part.
Your app should declare global variables for each part's pin numbers (OLED, RHT03, both LEDs, both buttons) and declare objects for the OLED display and RHT03 sensor. The code examples in the references for the parts can help with this.
Be sure the pin numbers (such as: D0, D1, etc.) you list in your code match the actual pin that each part's jumper wire is connected to on the Photon board. If they don't match, it is usually easiest to fix it by changing your code (rather than moving your wire).
In addition, your app should also include these other global variables:
In your setup()
function, be sure to:
set the pin modes for your LEDs and buttons
turn off the LEDs at the start
start the OLED display and RHT03 sensor
include Particle.variable
statements to share these three variables with your web app: setTemp
, roomTemp
, systemStatus
include Particle.function
statements to allow your web app to call these two custom functions: tempUp
, tempDown
The code examples in the references for the parts can help with figuring out the pin modes, turning off the LEDs, and starting the OLED display and RHT03 sensor.
This Particle Cloud reference can help with the Particle.variable
and Particle.function
statements.
You can also refer back to the setup()
function in the final version of the Photon app for your Smart Lightbulb.
NOTE: If you have added the Particle.function
statements but haven't yet added the custom functions for tempUp
and tempDown
, Particle Build will say your app has errors when you try to verify the code. To avoid this, you can type two forward slashes directly before each Particle.function
statement to temporarily make them into comments. Later, you will need to remove these slashes once you've added the custom functions to your Photon app.
Good news – here is the entire code for your loop()
function:
However, you will have to create custom functions for: checkButtons()
, readTemp()
, compareTemp()
, displayTemp()
(as well as tempUp
and tempDown
)
NOTE: Until you create these custom functions, Particle Build will say your app has errors when you try to verify the code if you include the names of these functions inside your loop()
function. So in the meantime, you can either leave the loop()
function empty, or you can type two forward slashes directly before the name of each custom function listed inside the loop()
function to temporarily make them into comments. You will need to revise the loop()
function to match the code above once you've created the custom functions.
You will need to create the following custom functions:
checkButtons()
should read each button and call tempUp()
function if red button pushed and call tempDown()
function if blue button pushed
readTemp()
should update roomTemp
with new reading from RHT03 sensor
compareTemp()
should compare roomTemp
with setTemp
to decide whether system should be heating, cooling, or off (be sure to update systemStatus
and turn correct LEDs on or off)
displayTemp()
should use Micro OLED to display roomTemp
, setTemp
, and systemStatus
(add other text and adjust font size if needed to make information clear and easy to read)
tempUp()
should increase setTemp
by 1 but not allow it to go higher than maxTemp
tempDown()
should decrease setTemp
by 1 but not allow it to go lower than minTemp
Here is part of the code for your checkButtons()
function:
For help with your readTemp()
function, look at the code examples in the RHT03 sensor reference.
Here is part of the code for your compareTemp()
function:
For help with your displayTemp()
function, look at the code examples in the Micro OLED reference.
Remember that tempUp()
and tempDown()
are functions that your web app can call, so the code for these two functions is slightly different (they must return an integer value and accept a String value).
As an example, here is the complete code for your tempUp()
function:
Then you can copy and modify the code above to create your tempDown()
function.
IMPORTANT: If necessary, go back to your setup()
function to make sure your Particle.function
statements do not have two slashes before them. Also be sure that your loop()
function matches the code provided earlier.
Create a new HTML file (index.html), CSS file (style.css), and JavaScript file (code.js) using a code editor (such as Editey in Google Drive, etc.). Make sure the files are blank. Rename the folder containing the files as: Smart Thermostat
The pictures show screenshots for how the web app could possibly look (during four different states: connecting, cooling, off, heating). However, your web app doesn't have to look exactly like this – you can design your own screen layout as long as the necessary information and functions are present.
If necessary, refer to the System Features towards the top of this page to verify what the web app should do.
You should copy and modify the HTML used in the Smart Lightbulb web app.
In the <body>
, you should have a <div>
element to display the current thermostat information. Assign id="thermostat"
and class="off"
to this <div>
element.
This <div>
should contain <p>
elements to list the room temperature, temperature setting, and system status (Off, Heating, Cooling). Be sure to give each <p>
element a unique id name, so you can update their HTML using jQuery statements in your code.js and change their style using CSS declarations in your style.css
Be sure to include two <button>
elements to allow the user to increase and decrease the temperature setting: one should have onclick="raiseTemp();"
and the other should have onclick="lowerTemp();"
(these will run custom functions that you'll create in your code.js)
If necessary, here is a HTML reference for additional help on HTML element tags.
If you want, you can borrow and modify some of the CSS used in the Smart Lightbulb web app.
Add CSS declarations to style properties for your #thermostat
. For example, the CSS below will make it into a circle (by setting border-radius: 50%
).
Create a class for each system status: .off
, .heating
, .cooling
Each of these classes should set a background-color
that represents the system status.
You can add CSS declarations for other elements or id names to customize the layout and appearance of your web app, so it is easier and more enjoyable to use.
If necessary, here is a CSS reference for additional help on CSS syntax to declare style properties.
You should copy and modify the JavaScript used in the Smart Lightbulb web app.
It may be helpful to use the information and code examples in this Particle Cloud reference.
IMPORTANT: Remember to assign your Photon device id and access token to the JavaScript global variables for myDevice
and myToken
Be sure the webpage window is set to run the checkThermostat
function at an interval of every 200 milliseconds.
Your JavaScript code should have the following custom functions:
raiseTemp()
function should contain particle.callFunction
statement to call "tempUp"
function (with argument of "adjust"
) on your Photon device
lowerTemp()
function should contain particle.callFunction
statement to call "tempDown"
function (with argument of "adjust"
) on your Photon device
checkThermostat()
function should contain three separate particle.getVariable
statements to get current values for setTemp
, roomTemp
, and systemStatus
and use these to update the content and appearance of your web app
In each particle.getVariable
statement, the value of the requested Photon variable gets temporarily stored in a local variable called data.body.result
that you can use.
By referring to id names, jQuery statements (which always start with $
) can easily change the text inside an HTML element. For example, if the webpage contained <p id="#set-temp">
element, you could update its content with jQuery to display the word "Set " followed by the value stored in data.body.result
:
Here's how that jQuery statement would be used inside a particle.getVariable
statement:
You can also use if
and else if
statements to check the data.body.result
value, and then use jQuery statements to easily add or remove CSS classes:
If necessary, here is a JavaScript reference and a jQuery reference for additional help on their syntax and functions. Because jQuery is a JavaScript library, JavaScript statements can be combined together with jQuery statements.
After creating the code for the other custom functions in your JavaScript, test your web app with your Photon device. If everything is working, then congratulations...
If you have time, add a third button to the device and web app that allows the user to change the system mode (Off, Heat, Cool). For example, in the "Heat" mode, only the heating system (red LED) should be turned on or off by the device. You will have to modify your Photon app to make the device operate properly in each mode. Your device and web app should display both the system mode and system status. For example, the mode might be "Heat" but the status would be "Heat OFF" if the current room temperature is at or above the desired temperature setting.
Your team has researched and defined a specific problem to solve. Now your team needs to design a solution by brainstorming ideas.
Ideation – the process of forming ideas – is a fundamental part of design. Ideation involves both creative thinking and critical thinking.
The mistake that some designers make is to pick the first idea they think of, without really exploring all the possible design ideas.
That's why design ideation should really occur into two phases: 1. Getting the Right Design = producing many ideas to find the most promising design 2. Getting the Design Right = refining the selected design to make it as good as possible
In this assignment, your team will begin to "get the right design" by generating many possible ideas. In the next assignment, your team will evaluate those ideas to select the most promising design idea(s) and then "get the design right" by refining the idea(s).
Keep in mind that your solution must include both a smart device and a web app that interact with each other through the Internet. You will want to generate ideas for each of these parts of the solution.
Here is some advice for brainstorming ideas:
First brainstorm as individuals, then share and brainstorm as a group
Be as creative and diverse as possible in your thinking
Don't criticize or reject any ideas yet
It's okay to have ideas for only part of the solution
Record ideas using simple sketches and descriptions
Capture the essence of the idea, not the details
Generate as many ideas as possible
Sketching is extremely helpful in ideation. Sketches are a quick way to record your ideas. Sketches also make it easier to explain your ideas to someone else. In fact, just creating a sketch can often lead you to think of even more ideas. Sketches do not need to be complex or realistic: stick figures can represent people, rectangles can represent device screens, arrows can represent movement or actions, etc. Adding a brief written description clarifies what the sketch represents.
EXAMPLE
Here are two different ideas for a solution to take student attendance. Each idea is only a partial solution (first idea is for a smart device, second idea is for a web app - but these two ideas do not necessarily go together). The essence of each idea is captured using a simple sketch and description. Of course, there are many other possible ideas that could be generated to solve this specific problem.
Be sure each team member understands the specific problem your team is trying to solve. If necessary, review your team's personas, journey map, value proposition, and design requirements. These help define who you are designing for, what problem you are solving, what benefits your solution should provide, and what criteria your solution should meet.
Each team member should individually brainstorm and record at least 5 different ideas using simple sketches and descriptions. It's okay if an idea focuses on just part of the solution (just the smart device, just the web app, etc.). Don't worry yet about whether you have the necessary technology or ability to build the idea.
Your team should share its ideas with each other, and brainstorm additional ideas as a group. Your team should have a combined total of at least 10 different ideas recorded. Remember that you are not rejecting any ideas yet.
Your team will create a system model of your smart device and web app to show how the different parts of your solution work together. This system model will help your team better understand how to build and program your solution.
Your system model should include the smart device's inputs (such as: sensors, buttons, etc.), outputs (such as: lights, motor, etc.), and its web app.
If your smart device and/or web app interact with a web service (such as: getting data from weather website, posting message to social media, etc.), then also include this in the system model.
EXAMPLE
Here is the system model of the that your team built as practice.
Add text boxes to the diagram to briefly explain the key functions and interactions of the parts of the system. The goal is that anyone should be able to use the diagram to understand how to build the smart device and how the device will work.
Design requirements list specific criteria that a new solution or system must meet in order to be considered successful.
It is helpful to identify these requirements up-front, so they can be used to help you generate, evaluate, and refine ideas for a solution.
There are different types of design requirements. Three key types of requirements are:
Functional Requirements
Usability Requirements
User Experience (UX) Requirements
Functional requirements specify the functions and features the solution should have to be useful to the target users. Functional requirements generally focus on making sure the system:
has necessary functions to allow users to complete tasks to achieve their goals
has innovative features that provide additional value to users
Usability requirements specify criteria to ensure the solution is easy to use. Usability requirements generally focus on making sure the system:
is easy to learn and remember
is efficient and effective to use
helps prevent and fix user errors
User experience (UX) requirements specify criteria to ensure the solution is satisfying to use. UX requirements generally focus on making sure the system:
produces desirable reactions (such as users feeling confident, engaged, relaxed, happy, etc.)
avoids undesirable reactions (such as users feeling frustrated, bored, annoyed, angry, etc.)
In addition, other types of design requirements might include:
environmental requirements (criteria for physical, social, and/or technical conditions that system must operate within)
data requirements (criteria for data that system must process and store)
security and privacy requirements
maintenance and support requirements
legal and regulatory requirements
ethical requirements
An important aspect of any design requirement is the ability to objectively determine or measure whether the requirement was met (or to what degree it was met). After a solution has been designed and built, data from evaluations (such as user testing, etc.) can provide evidence of how well the design requirements were met.
List at least 3 Functional Requirements
List at least 3 Usability Requirements
List at least 3 User Experience (UX) Requirements
List at least 1 Other Requirement
It may be helpful to refer back to your personas, journey map, and value proposition to identify key requirements that will be needed in your solution.
Next your team will have stakeholders evaluate your solution design. Receiving constructive feedback early in the design process allows you to improve your solution before actually building it.
For each evaluator, your team will tell him/her the value proposition for your solution, and then show him/her each of these design artifacts:
Refined Solution Sketches
System Model for Solution
Wireflow for Web App
Storyboard for Solution
Your team should encourage the evaluator to ask questions and to provide specific feedback (positive and negative) by "" as they review the design artifacts.
If necessary, ask the evaluator questions to get him/her to provide more feedback or to clarify their feedback:
What do they think is unclear or confusing? Why?
What design features do they think are most useful or valuable? Why?
What design features do they think should be changed or improved? Why?
It is important for your team to understand the reasons behind the feedback – why does the evaluator think that?
Your team should recruit 3-5 stakeholders to individually evaluate your team's solution design.
Your team will evaluate its set of solution ideas to select the most promising idea(s). This step is "Getting the Right Design" to solve your targeted problem.
Then your team will refine the selected idea(s) to improve the solution and make it more clear and complete. This step is "Getting the Design Right" by making your solution as good as possible.
Your team should evaluate its solution ideas by using the design criteria listed in the :
Useful: Would this help solve the problem?
Usable: Would this solution be easy for people to understand and use?
Feasible: Would it be possible for your team to make a prototype of this solution?
Innovative: Is this different from existing solutions?
If your solution idea for the smart device would require a special part that is not in your Photon kit, then determine whether it is possible to order the part – or to simulate the part. (For example, your smart thermostat prototype used a red LED and blue LED to simulate a heating and cooling system.)
If necessary, your team can browse or search the to see if the part is available to order and reasonable in cost. If browsing by category, check under Components or Sensors. Your team will be responsible for finding out how to connect and program the part.
Your team should use these criteria (as well as your team's design requirements) in order to select the most promising idea(s) for a smart device and web app that could work together to solve your problem.
It might be the case that your team doesn't have a complete solution yet. For example, your team might have a great idea for the smart device, but your current ideas for the web app don't match this device. If that's the case, it's okay – your team will think of new ideas for the web app when refining your solution.
Your team will refine your selected solution by generating additional ideas to show details of the smart device and web app. You could also show alternate versions or variations of the smart device and web app – such as different ways to build the device or different ways that the app could look or work. You will record these ideas using simple sketches and descriptions.
EXAMPLE
Here are several refined sketches for a smart lock solution. Each sketch shows a detail of the smart device or the web app.
In the next set of assignments that will follow, your team will create several project deliverables to provide even more details of your solution design:
System Model showing how the parts of your smart device system work together
Wireflow showing a sequence of screens for interacting with your web app
Storyboard showing a person's experience using your solution in a real context
Your team should review its set of solution ideas to identify the most promising idea(s) for a smart device and web app that could work together to solve your problem. Your team should select its best idea (even if it is only a partial solution). You can select multiple ideas if you can combine them into one solution.
Your team should refine its selected solution by creating 8-10 sketches to show details (and/or variations) of the solution. Be sure to include sketches for both the smart device and the web app.
Your team should show and explain your refined solution sketches to another design team to gather feedback. Use the feedback to clarify and improve your team's solution.
A storyboard is a series of pictures – similar to a comic strip – that illustrate a brief story of a person using a product or solution to complete a task in a real context. A storyboard is helpful for showing the future user experience of a solution that you've designed.
EXAMPLE
Here is a storyboard of a person walking by a bulletin board in a hallway, who pauses to use his phone's camera to scan a code on an announcement, in order to download the information to the phone.
As you can see, a storyboard can use simple drawings and still be very effective at showing what happens. Each panel also includes a brief description to help clarify what is being shown.
Your team will create a 6-panel storyboard to tell a brief story of what happens before, during, and after a person uses your solution (the smart device, the web app, or both) to complete a specific task:
BEFORE = 2 panels for problem (show setting of story and what task the person needs to complete)
DURING = 3 panels for solution (show the person using your solution to complete the task)
AFTER = 1 for panel for benefit (show how the person feels after using solution)
The task that you select for this storyboard should be core to the purpose and experience of using your smart device system. Therefore, do NOT select a mundane task such as: creating an account, logging into the app, etc.
TYPES OF CAMERA SHOTS
A storyboard can be more effective if the panels use different camera shots depending on what each panel is trying to communicate, similar to how movies use different camera shots to help tell a story. Some common types of camera shots that are useful in product storyboards are shown below.
NOTE: Your storyboard won’t necessarily use all these camera shots, and your storyboard won’t necessarily use them in this exact order. Select and order your camera shots to tell your story in the most effective way possible.
Wide shots and long shots are useful for showing when and where the story takes place and who is involved. They are often used for the first panel of a storyboard.
Medium shots are useful for showing the person’s emotion. They are often used to show a person’s reaction to a problem and/or their reaction to using the product.
Over shoulder shots, point of view shots, and close-up shots are useful for showing what the person is doing and seeing as they use the product to complete the task.
Before building your solution, your team will give a formal presentation explaining your targeted problem and your proposed solution. This will be an opportunity for other project teams to provide constructive feedback through a design critique.
Your team's presentation should briefly explain and show:
Problem Being Solved: describe the problem, its impact, and its cause
Personas for Stakeholders: mention how many people were interviewed, and highlight some of the key characteristics of both personas (if necessary, clarify key differences between the two personas)
Journey Map of Current User Experience: introduce the persona and scenario, and briefly explain the current user experience (by highlighting problems in the current experience)
Value Proposition of Solution: be sure it is clear what value your solution will provide to people
Design Requirements for Solution: highlight some of the key requirements, and briefly explain how these are related to your user research findings
Refined Sketches of Solution: highlight some of the ideas shown in the sketches
System Model of Solution: briefly explain how the parts of the system work together
Wireflow for Web App: introduce the task, and briefly explain how the user interacts with the app
Storyboard of Future User Experience with Solution: briefly explain the story shown
Evaluation of Solution Design: mention how many evaluators were involved, and briefly summarize the evaluation findings (positive and negative)
Prepare and practice your team's presentation. The presentation should have 10-15 slides and take about 8-10 minutes to deliver. Each team member should participate equally in the verbal presentation. Be sure to include a title slide identifying each of the team members. Be sure your presentation is clear and engaging.
After your team's presentation, the other project teams will ask questions and provide constructive feedback through a design critique (about 2-4 minutes). Be prepared to respond to questions and to record notes on the audience feedback.
Your team needs to create a web app (for a phone, tablet, or desktop) that will interact with your smart device to perform the functions envisioned in your team’s solution design.
You will need to use online references (such as: , , etc.) to figure out how to code a web app that will get data from your smart device through the Internet (via ), use the data to dynamically update the web app, and send data and commands to your smart device through the Internet.
The web app will be created in a code editor using HTML, CSS, and JavaScript. You will need to plan out your web app, and then program it in stages, testing and revising the code as you go.
Plan out web app
If your team's system model and wireflow do NOT clearly and correctly describe and show the web app, then revise them to be accurate.
If necessary, create additional screen mockups in order to have a wireflow for the entire web app. (You can do this either before or after completing the plan for your web app.)
Code web app - Part 1 (HTML, CSS) - More details coming soon...
Code web app - Part 2 (JavaScript: variables, functions, Particle Cloud) - More details coming soon...
A value proposition is an “elevator pitch” for a product or service – a clear and concise sales pitch that summarizes the product or service.
There are different formats or templates for creating a value proposition statement. The most popular template for a value proposition provides the following answers:
Who are the target users for the product/service?
What problem or need does the product/service solve?
What is the product/service?
What benefit or value does the product/service provide?
VALUE PROPOSITION TEMPLATE
For [describe target users] who [describe problem or need], [name of product/service] is a [describe type of product/service] that [describe benefit or value].
EXAMPLES
For coffee drinkers who are annoyed by waiting in line to order and get their drinks, JavaGo is an app that lets you pre-order and pay for your drink, so it's fresh and ready when you arrive at our coffee shop.
For people needing a ride who are frustrated by trying to get and pay for a taxi, Lyft is a smart ride-sharing service that, with one tap in our app, quickly brings a car to your exact location, gets you to your destination, and lets you pay automatically without cash.
It may be helpful to refer back to your journey map since this shows some of the current problem(s) affecting your target users. The journey map can help you clarify the benefit or value that your solution will provide (compared to the current user experience).
Once your team's smart device, Photon app, and web app have been created, your team needs to conduct integration testing to ensure that all these parts of your system work together properly.
Conduct integration testing of your smart device, Photon app, and web app:
Test all the functions and features of the smart device, Photon app, and web app to verify they are working correctly and interacting with each other correctly.
Record detailed notes for any issues that occur (something that doesn't work correctly, something that could be improved, something that is missing, etc.).
Troubleshoot the cause of each issue, implement a fix, and re-test until any significant issues are resolved. Don't worry about trying to make your solution absolutely "perfect" – just identify the most serious issues and fix as many as you can, depending on how much time is available.
Later, your team will conduct an evaluation of your solution by testing it with stakeholders.
Your team needs to build its smart device prototype by connecting the necessary inputs and outputs to your Photon board. Your team’s system model should identify each of the parts needed for your device.
You will need to use online references (such as: , , etc.) to verify how to correctly wire the parts to the I/O pins and power. (I/O = Input/Output)
Your team will need to test the wiring of each part by adding temporary code in the Photon app to do something simple with each part (such as: turn LED on and off, rotate servo motor back and forth, etc.).
In addition, you may need to construct other non-electronic parts for your team’s smart device prototype. For example, if your smart device locks a door, then your team should build a small-scale model door (using cardboard, etc.) that can be locked and unlocked by your device.
Connect the necessary parts to build the smart device:
If your team's system model does NOT clearly and correctly identify all the specific inputs and outputs needed for your device, then revise your system model to be accurate.
If necessary, you can simulate certain parts. For example, the smart thermostat prototype used a red LED and blue LED to represent heating and cooling systems.
TIP: If people will interact directly with the device, consider whether you need to add parts to provide visual and/or audio feedback to indicate the device status or a device response. For example, if a user presses a button on the device, how will the user know the device detected this? Devices and apps that don't provide any obvious feedback can be frustrating or confusing to users.
How many wires does the part need, and what do the wires connect to? Each part will connect to at least one I/O pin and to GND. Certain parts (such as: LED, etc.) connect to GND using a resistor. Certain parts (such as: OLED display, etc.) connect to additional I/O pins and/or to a power supply pin (3.3V or 5V).
Will the part gets its power from its I/O pin, the 3.3V pin, or the 5V pin (V-USB)? Some parts get power directly from their I/O pin, while other parts have separate wires for power. Certain parts (OLED display, etc.) are limited to only 3.3V of power, while other parts (servo motor, etc.) require 5V of power.
Does the part need to connect to specific pins? Certain inputs (such as: photocell, etc.) need an analog pin. Certain outputs (such as: servo motor, etc.) need a PWM pin. Certain parts (such as: OLED display, etc.) need to be connected to other specific pins.
Plan out where the parts will placed on the breadboard, so the layout will be easy to understand and use (e.g., if users need to look at device and/or physically interact with device).
Determine whether you need to connect one or more power rails on the breadboard:
Use a jumper wire to connect one of the negative power rails on the breadboard to a GND pin on the Photon board. Then connect each part’s GND wire (or resistor) into this negative power rail.
If there is one (and only one) part requiring 3.3V, then connect that part directly to the 3.3V pin on the Photon board.
If there are multiple parts requiring 3.3V, then use a jumper wire to connect one of the positive power rails on the breadboard to the 3.3V pin on the Photon board. Then connect each part’s 3.3V wire into this positive power rail.
If there is one (and only one) part requiring 5V, then connect that part directly to the V-USB pin (5V) on the Photon board.
If there are multiple parts requiring 5V, then use a jumper wire to connect one of the positive power rails on the breadboard to the V-USB pin (5V) on the Photon board. (If you already connected one positive power rail to 3.3V, then connect the second positive power rail to V-USB). Then connect each part’s 5V wire into this positive power rail.
If there are no parts requiring 3.3V or 5V, then do not connect a positive power rail (because all the parts will receive power from their I/O pins). However, you will still use the negative power rail for the GND wires.
Connect each of the wires (and resistors, if applicable) for each part, and use your wiring table to record which I/O pin each part is connected to. This information will be needed to code the Photon app.
NOTE: Several analog pins are duplicated on the Photon board. A2, A3, A4, and A5 are each represented by two pins. If you use one of these pins, you cannot use its duplicate.
TIP: You may want to connect one part at a time, and then test the wiring of that part using Photon code (step 2) before connecting the next part.
Test the wiring of each part using temporary code in the Photon app. The "test" code for each part should do something simple to verify the part functions correctly.
For example, an LED light could be programmed to blink on and off repeatedly, a motion sensor could be programmed to briefly turn on the built-in D7 LED if movement is detected, etc.
For inputs that take measurements (such as: photocell, accelerometer, etc.), you will have to do a bit more work to test that the part is working correctly. For example, if you first connect and test the OLED display screen, then you could display a measurement taken with another part. (Later, you could remove the OLED screen if it's not needed as part of your final device.) Another option would be to share the measurement variable with a simple web app that would display the measurement value.
Construct any additional parts needed to demonstrate how your team’s smart device prototype works.
For example, if your smart device locks a door, then create a small-scale model door (using materials such as cardboard, etc.), so that your device can actually lock or unlock the model door.
Project teams need to track their progress on tasks – as well as any issues that arise – in order to complete their projects on time. This is why a detailed task schedule is such an important tool for managing a project.
This next phase of the project requires your team to develop its solution based on your team's design. There are six major components to complete during this development phase:
Over the next several weeks, your team should be working on multiple components in parallel (i.e., at the same time). Each team member should be assigned to work on one or more components.
that will help keep your team on track. These checkpoints do not necessarily represent equal amounts of time. For example, it may take less time to complete Checkpoint 1 but more time to complete Checkpoint 3.
IMPORTANT: Each team member should be contributing at all times throughout the development phase. If a team member completes their current task, he or she should either continue on to the next task for that component or help complete a task for a different component.
NOTE: Keep in mind that both the Photon app and web app require coding, so your team may need more than one person to work on coding. (The product marketing website can be coded – or it can be built without coding by using a tool such as Google Sites, etc.)
List the name of the team member(s) assigned to each task.
When a task is started, enter the start date (MM/DD).
When the task is completed, enter the completion date.
There is an optional column for due date, which your team can use for its own deadlines or any deadlines established by your teacher.
During this time, also track any significant issues that your team is unable to resolve, in order to follow up and get help as needed. Record these in the "Issues Log" sheet of the spreadsheet.
Describe the issue. Be sure to include specific details that may help figure out the cause of the issue. (For example: What happens or doesn’t happen? What have you checked or tried? What information do you need?)
Use the drop-down menu to select the component affected by the issue (such as: smart device, Photon app, web app, etc.).
List the name of the team member(s) assigned to follow up and resolve the issue.
When the issue is added to the log, enter the date.
When the issue is resolved, enter the date.
Your team needs to create a Photon app that will run on your smart device to perform the functions envisioned in your team’s solution design.
You will need to use online references (such as: , , , etc.) to figure out how to program a Photon app that will read data from your device’s inputs, analyze the data to make decisions, send commands to your device’s outputs, and interact with your device’s web app by sharing data through the Internet (via ).
The Photon app will be created in the online code editor using the . You will need to plan out your Photon app, and then program it in stages, testing and revising the code as you go.
Plan out Photon app
If your team's system model does NOT clearly and correctly describe the functions and interactions of the parts, then revise your system model to be accurate.
Code Photon app - Part 1 (add libraries, declare global variables, code setup()
function, test each part)
CREATE NEW APP: Login to your team's Particle Build account. Create a new app, and give it a title that makes sense. Particle Build will automatically insert a blank setup()
function and blank loop()
function for your new app.
LIBRARIES: Determine whether any parts (such as: OLED display, servo motor, etc.) need a special code library added to the Photon app. If so, then search for the necessary library in Particle Build, and add the library to your Photon app. Particle Build will insert an #include
statement for the library at the very top of your app code.
GLOBAL VARIABLES: Declare (create) global variables near the top of your app (after any library #include
statements but before the setup()
function). Each variable must have a unique name. You get to decide what the names are, but try to use names that will make sense to someone else reading your code. Remember that variable names cannot have spaces (and cannot be a keyword in the programming language).
Create global variables for each part’s I/O pin. This I/O pin number should have been recorded by the person who wired and connected the parts. If necessary, visually verify the I/O pin number used by the part on your Photon device.
Create global variables for any object variables that are needed. Parts that needed a special code library usually require an object variable.
Create global variables to store any other data (numbers, text, etc.) that your app needs to track or needs to share with your web app.
SETUP( ) FUNCTION: Within the setup()
function, add code needed to prepare your device for use. Remember that the setup()
function runs only one time when the device is first started (or is reset).
Set the pinMode()
for each input or output. Be aware that some parts do not need a pinMode()
statement.
Parts that needed a library (such as: OLED display, etc.) may need certain commands added within the setup()
function. For example, the OLED display needs oled.begin();
added within the setup()
function.
Add any other commands that you want to occur one time when the device is first started. For example, if you are using an LED light, you may want to either turn it on (or turn it off) when the device is first started.
Later (in step 3 below), you will add Particle Cloud statements within the setup()
function, so your Photon app can send data to your web app and/or receive commands from the web app.
TEST EACH PART: Within the loop()
function, add temporary code to test each part, in order to verify the part is wired correctly and working. This "test" code should make the part do something simple that you can observe or verify in some way.
OUTPUT examples: turn on LED (or make it blink), have speaker produce a tone, make servo motor rotate, display message on OLED screen, etc.
INPUT examples: turn on built-in D7 LED when button is pushed (and turn off when button is released), turn on built-in D7 LED when motion detected (and turn off when no motion detected), display measurement from accelerometer on OLED screen, etc.
After adding the "test" code, "flash" (download) the app onto your Photon device to run it. If the part doesn't work properly, then first check your code in the Photon app to make sure it is complete and accurate. For example, does the pin number you listed for the part's global variable match the actual pin that it is wired to? Did you set the correct pinMode()
for the part? If necessary, revise the code, and re-flash the Photon app to your device. If you've verified the code is correct but the part is still not working, then check whether the part is wired correctly to the Photon device.
Once the parts are tested to work properly, the "test" code can be removed from the loop()
function (but do not remove the libraries, global variables, or code in the setup()
function) – or the "test" code can be turned into comments by typing two forward slashes at the beginning of each line of "test" code: //
Code Photon app - Part 2 (code loop()
function, code any custom functions, add Particle Cloud statements)
LOOP( ) FUNCTION: More details coming soon...
CUSTOM FUNCTIONS: More details coming soon...
PARTICLE CLOUD: More details coming soon...
Your team will create a wireflow of your smart device's web app to show how someone would interact with it to complete a task. Wireflows are prototypes that allow you to design, test, and revise a website or app before coding it.
What is a ? It's a combination of wireframes and a flowchart:
A wireframe is a sketch or mockup of a webpage or app screen (also called the user interface). A wireframe shows how elements are visually arranged in the user interface (such as: navigation menus, icons, text, images, buttons, etc.). Early in the design process, wireframes are simplified outlines of the user interface. Later in the process, more detailed mockups are created.
A flowchart is a diagram representing the steps in a process or task from start to finish. The flowchart includes steps completed by the user and steps completed by the system (i.e., the app). A flowchart might include decision points where the process or task can follow different paths. Flowcharts are helpful for figuring out how to design and program your app.
A wireflow is a sequence of user interface mockups (wireframes) showing the steps in a task flow (flowchart) as a user interacts with a website or app.
The easiest way to create a wireflow is by sketching a sequence of wireframes representing a task flow. There are also tools available (such as: , , , etc.) to create (or import) wireframes and turn them into interactive wireflows (with clickable links, buttons, etc.) that can be tested with users.
EXAMPLE
Here is an example of a wireflow for a task in a smart light web app. This wireflow shows how the user interface changes as the user turns on a set of lights and adjusts the brightness of the lights.
As you can see, a wireflow can use simple screen mockups and still be effective for showing how a user interacts with the app. Each mockup also includes a brief description to help clarify what the user does and what the app does in response.
Your team will create a wireflow with 3-6 screen mockups to show how a person would use your web app to complete a specific task that involves interacting with your smart device.
web app can receive and display data from smart device (by getting Photon variables)
web app can send data and commands to smart device (by calling Photon functions)
web app can receive notification alerts from smart device (by streaming Photon events)
The task that you select for this first wireflow should be core to the purpose and experience of using your smart device system. Therefore, do NOT select a mundane task such as: creating an account, logging into the app, etc.
Once your smart device, web app, and product marketing website have been evaluated, your team needs to determine what is working well and what could be improved. Then your team will implement improvements, as feasible.
Determine what changes or improvements are most important to make – as well as most feasible to make – based on how much time is available before the public poster presentation.
If there are changes to your smart device or web app that are not feasible to make at this time, you can describe those during your public poster presentation and/or in your product marketing website as features coming in the next iteration (version) of the solution.
Most entrepeneurs or companies create a website to help promote and market new products. Sometimes this is done as a webpage on a crowdfunding website (such as , , etc.). Other times, this is done as a webpage or mini-site on a company website.
Your team will create a one-page product marketing website for your smart device solution, which will include your . This website will be made public to allow more people to learn about your smart device project.
Create and/or gather the content (text, images, video, etc.) for your team’s product marketing website. Be sure the content is clear, concise, engaging, and professional. Your website should include the following content (but you can determine the best order – and you can add other content if helpful):
Product Name
Value Proposition (could be shortened even further into a tagline phrase)
Functions and Features (what does product allow you to do, what benefits does it provide)
Tech Specs (list the inputs, outputs, etc.)
Video demonstrating use of solution
Image(s) of smart device prototype
Screenshots of web app
Names of team members and their project roles
Create a visual design for your team's one-page website that will be engaging, professional, and reinforce your product concept.
Generate and sketch possible ideas for the layout of the content on the webpage.
Decide on the overall style for the website (such as: fonts, colors, etc.)
Include temporary placeholders for the product demo video and certain images (smart device, web app screenshots).
Later, your team will conduct an evaluation of the website by testing it with users.
Use your team's refined solution sketches to identify the specific inputs and outputs that will be used to build your smart device. If helpful, here are the . If necessary, your team may need to simulate certain inputs or outputs.
Modify this to include each specific input and output. Include each web service being used – or remove if no web service is being used.
EXAMPLE: Here is an (such as Amazon, etc.). Keep in mind that this example is only a partial list.
Use to create a list of design requirements that your team’s solution will have to meet.
Each evaluation should take about 5-7 minutes to complete. While one team member presents the solution design artifacts to the evaluator, another team member should record the evaluator's feedback in .
Once all the evaluations are completed, your team should review and discuss the feedback from all the evaluators, in order to summarize your evaluation findings in .
Use this to help develop the storyline for your 6-panel storyboard.
Print and use this to sketch your storyboard panels. Be sure to include a brief description for each panel to help explain what it shows.
Use your team’s and to identify the tasks, content, screen layouts, and interactions for your web app.
Answer these . Don't worry about creating "code" for the answers – answer in plain English.
Once the smart device, Photon app, and web app have all been completed, to verify they work together properly.
Create a value proposition statement for your team’s smart device system using .
Compare your solution to your team's . Does your solution meet your requirements?
Use your team’s to identify and gather all the parts needed for inputs and outputs.
Research the wiring connections for each part, and fill out . Here's an for a smart security system.
Once the smart device, Photon app, and web app have all been completed, to verify they work together properly.
Your team should review the , along with any deadlines that have been established by your teacher. Discuss and decide which team members will work on the various project components.
Over the next several weeks, track your team's task progress by updating the "Task Progress" sheet .
Use your team’s to identify all the inputs and outputs connected to your smart device, the function of each part, and the interactions between parts of the system.
Answer these . Don't worry about creating "code" for the answers – answer in plain English.
Once the smart device, Photon app, and web app have all been completed, to verify they work together properly.
As you decide what tasks your web app could include, keep in mind there are that your web app can interact with your smart device through Particle Cloud:
Use this to help develop the sequence of screen mockups for your wireflow.
Print and use a to sketch your wireflow. There are templates for a smartphone, tablet (7 inch or 10 inch), or desktop web browser. (You may need multiple copies of your device template to create all the screen mockups.) Be sure to include a brief description for each screen mockup to help explain how the user and the app interact.
For your smart device and web app, review the evaluation notes and survey responses from all the participants. Use to summarize the most positive features of your smart device and web app, as well as any issues to potentially change or improve.
For your product marketing website, review the evaluation notes and survey responses from all the participants. Use to summarize the most positive features of your product website, as well as any issues to potentially change or improve.
Create a of the final website layout.
Use your content (text, images, etc.) and wireframe to build the website using a tool such as (available within Google Drive – if needed, Google has a guide) – or code the website using HTML and CSS.
After the and are completed, add the video to the website, along with images of the smart device and web app.
Your team will participate in a public poster presentation to demonstrate and explain your project to an audience.
The people attending the presentation will walk around to each team to learn about the projects, spending a few minutes with each team. You will most likely have to present multiple times to different small groups of people.
Prepare and practice a basic 2-3 minute presentation that describes the problem your team targeted and demonstrates the solution you developed. Then if the audience seems interested in learning more, you can explain in more detail how you researched, designed, developed, and evaluated your project.
Each team member should be prepared to help present as needed.
On the day of the event, be sure you have your project poster, smart device prototype, and a laptop or mobile device to demonstrate your web app. You may also want to have your product marketing website available for viewing on a laptop or tablet.
During the presentation, be friendly, confident, and engaging. When demonstrating your smart device product, give the audience members an opportunity to interact with it, so they can directly experience using your solution.
Be prepared to respond to questions from the audience members.
Treat every audience member as a potential judge (because some of them may be judges).
Reflecting back to think about what you've experienced is an important part of learning and improving. Reflection is useful throughout an experience, but it is especially helpful at the end because you have the benefit of reflecting on the entire experience from start to finish.
Write brief personal responses to the prompts in this project reflection document.
Once integration testing is completed, your team needs to evaluate your smart device and web app by testing it with stakeholders to gather feedback on what is working well and what could be improved.
The evaluation will focus on testing the functionality, usability, and user experience of your solution. This evaluation can provide evidence of how well your solution meets your design requirements.
Identify one or more tasks that people could complete using your smart device and web app. Create a brief scenario describing a realistic context in which someone would need to complete the task(s).
For example, a scenario and task might be something like: "Imagine you are a student that needs to get something from your locker before your next class starts. Open up your smart locker, and then lock it again when you're done."
Recruit 3-5 participants that match one of your target stakeholder groups, as represented by your personas. Each participant will individually evaluate your team’s solution. Each evaluation will take about 5-10 minutes.
At the start of each evaluation, briefly introduce your solution to the participant using your team's value proposition. Be sure to mention that:
the product is being tested, not the participant
the product consists of a smart device and a web app that work together
the product is an early prototype, so you want constructive feedback on what’s working well and what could be improved
Describe the scenario to the participant, and identify the task that he or she should complete using the device and web app. (If you have multiple tasks to test, give the participant one task at a time.) Tell the participant to provide feedback by “Thinking Aloud” as he or she interacts with the device and web app.
Since the device is an early prototype (which may be very unfamiliar), it may be necessary at times to provide limited help if the participant doesn't understand what to do next.
However, as much as possible, let the participant figure out how to interact with the device.
As the participant completes the task(s), record notes on the feedback being provided.
At the end, have the participant complete this online evaluation survey.
Repeat Steps 3-6 with each participant.
Once your product marketing website is completed, your team needs to evaluate the website by testing it with users to get feedback on what is working well and what could be improved.
The evaluation will focus on testing the functionality, usability, and user experience of your website. This evaluation can provide evidence of how effective your website is at marketing your product.
Recruit 3-5 participants that match one of your team’s target stakeholder groups, as represented by your team's personas. (Avoid using participants that evaluated the smart device and web app, since they will already be familiar with your product.) Each participant will individually test and evaluate your team's product website. Each evaluation will take about 5-10 minutes.
At the start of each evaluation, briefly explain that your team wants to get feedback on a website for a new product. Be sure to mention that:
the website is being tested, not the participant
the website is the focus of the evaluation, rather than the product
the website is a work in progress, so you want constructive feedback on what’s working well and what could be improved
Tell the participant to provide feedback by “Thinking Aloud” as they interact with the website. Tell the participant to use the website to learn about the product by finding answers to these questions:
What does the product do?
Who would use the product?
What benefit or value does the product provide?
As the participant uses the website, record notes on the feedback being provided.
At the end, have the participant complete this online evaluation survey.
Repeat Steps 2-5 with each participant.
Your team needs to create a poster that helps show how your team researched, designed, prototyped, and evaluated your solution to your targeted problem.
The poster will be a visual reference to supplement the explanation and demonstration that your team gives during the public presentation event. The goal is for the poster to be clear, concise, engaging, and professional in terms of its content and visual design.
The standard size for a large poster is 36 inches wide by 24 inches tall. Your teacher will assist with getting the posters professionally printed.
Gather the content (text and images) for your team’s project poster. Be sure the content is clear, concise, engaging, and professional. Here is a recommended list of content for the poster (and you can add other content if helpful):
TEAM
Team Name (if applicable)
Team Member Names
PRODUCT
Product Name
Value Proposition (or tagline phrase)
Functions and Features (optional)
RESEARCH
Persona for Target User
Journey Map of Current User Experience (optional)
Design Requirements for Solution (optional)
DESIGN
Refined Sketches of Solution (optional)
System Model of Solution
Wireflow of Web App
Storyboard of Future UX with Solution (optional)
PROTOTYPE
Photo of Smart Device
Example of Code from Photon App (optional)
Screenshot(s) of Web App
Example of Code from Web App (optional)
EVALUATION
Evaluation Findings (optional)
Determine the visual design for your team's poster.
Generate and sketch possible layouts of the poster content. You can use a regular sheet of paper to sketch a simplified, small-scale mockup.
Decide on the overall visual style for the poster (such as: fonts, colors, etc.)
Create your final poster using a tool such as Google Drawing.
You can use this Google Drawing template which is preset to 36 inches wide by 24 inches tall (zoom in or out as needed to add and edit text, images, etc., but do not change the canvas size).
Be sure your poster doesn't have too much text (people may not read it all) or too little text (people may not understand the poster). For example, include some kind of label or description for diagrams, images, etc.
Be sure you have strong contrast between the text color and its background color. (If the background color is dark, the text color should be light. If the background color is light, the text color should be dark.)
Be sure the font types and font sizes used on the poster will allow people to easily read the text from several feet away. (Fancy fonts may be hard to read. Bold text may be easier to read. Font sizes less than 30 might be too small.)
Save or download a copy of your poster as a PDF, and provide the PDF to your teacher for printing.
Each part (such as LED, etc.) that you connect to your Photon device must have a complete electrical circuit. A circuit is a continuous path that conducts electricity from the positive (+) end of the power supply through a part (such as LED, etc.) back to the negative (-) end of the power supply. The Input/Output (I/O) pins, jumper wires, and breadboard are used to help make a separate circuit for each part.
This is why each part needs at least 2 wires (one for positive and one for negative). In many cases, an I/O pin acts as the voltage source (positive end) for a particular part's circuit. All parts will connect back (directly or indirectly) to one of the GND (-) pins on the Photon board. Parts that require more than 2 wires use the extra wires for power or data.
The Photon board has a number of I/O pins used for connecting inputs and outputs. Some of these are labeled as "analog" pins, while others are labeled as "digital" pins. However, in practice, the analog pins can act as digital pins, and some of the digital pins can act as analog pins.
The Photon board has 6 analog I/O pins labeled as: A0, A1, A2, A3, A4, A5.
Several of these analog pins are duplicated on the Photon board. A2, A3, A4, and A5 are each represented by two pins. The duplicate pins are located in the 10-pin digital header and labeled as: SS/A2, SCK/A3, MISO/A4, MOSI/A5. You can use either the primary analog pin or its duplicate. However, if you use one, then you should not use the other. For example, you could connect a part to either A2 or SS/A2 (choose one), but you cannot connect two different parts to these two pins and try to control them separately.
The Photon board has 8 digital I/O pins labeled as: D0, D1, D2, D3, D4, D5, D6, D7.
The D7 pin is also connected to a small, built-in blue LED light on the Photon board. Sending a digital output signal of HIGH to D7 will turn on the built-in D7 LED (and sending a signal of LOW turns it off). You can connect another part to the D7 pin, but just be aware that your Photon code might also turn the D7 LED on or off (only if you're using the D7 pin as a digital output for your other part).
The Photon board has several I/O pins with "special" labels, indicating they have special uses.
There are several analog and digital pins with special uses: SDA/D0, SCL/D1, SS/A2, SCK/A3, MISO/A4, MOSI/A5. However, all of these pins can be used as regular I/O pins. In your Photon code, you can just refer to these pins by their "regular" labels (D0, D1, A2, A3, A4, A5).
There are two pins labeled as RX and TX, which are normally used for receiving data (RX) or sending data (TX) data over a serial connection to a part. If needed, these pins can instead be used as regular I/O pins. In your Photon code, you would simply refer to these pins as RX and TX.
There are two pins labeled as WKP and DAC, which have special uses. If needed, these pins can instead be used as regular I/O pins. In your Photon code, you would refer to WKP as A6 and DAC as A7.
Some of the I/O pins are capable of PWM output. PWM stands for pulse-width modulation, which is how a digital output signal (which has only two values: HIGH or LOW) can act like an analog output signal (which has a range of values).
Certain parts (such as: speaker, servo motor, etc.) require a connection to a PWM output pin.
Only the following pins can act as PWM outputs: D0, D1, D2, D3, A4, A5, WKP, RX, TX.
The Photon board operates at 3.3 volts. Therefore, the voltage source from the I/O pins is 3.3 volts (regardless of whether the Photon is being powered by USB or battery). Again, many parts are powered directly from their I/O pin. However, some parts need a separate power source.
The 3.3V pin (+) on the Photon board can be used as a power source.
The V-USB pin (+) on the Photon board supplies 5 volts (which comes directly from the USB connection). This pin won't supply power if the USB is not connected.
The VIN pin (+) on the Photon board supplies power directly from the battery connected to the barrel jack. So connecting a 9V battery would provide 9 volts to the VIN pin (but still only supply 3.3V to the regular I/O pins). This pin won't supply power if a battery is not connected.
CAUTION: Some parts (such as OLED display, accelerometer, etc.) can only handle 3.3V and can be damaged if connected to a higher voltage. Check the power requirements of each part before connecting a part to either V-USB or VIN.
NOTE: Some parts (such as servo motor, motion sensor, etc.) require 5V in order to operate properly. These parts will have to be connected to either V-USB or VIN.
GROUND PINS
There are 3 separate ground pins on the Photon board, each labeled as GND. These act as the negative end of a circuit. All parts have to connect to a GND pin (either directly or through the breadboard).
The breadboard is an important part used to help make your circuits. The left and right halves of the breadboard are actually separate (which means they will not conduct electricity between each other). Within each half, the holes within the same row are connected to each other electrically, but each row is separate from the other rows. The rows are numbered (1-30), and holes within the same row are lettered (a-e for left-hand rows, f-j for right-hand rows).
In addition, each half of the breadboard has a power rail as its two outer columns (positive column and negative column). The power rails are not connected to the rows. The purpose of a power rail is to allow multiple parts (which will be attached to the breadboard rows) to share access to the positive and negative ends of your Photon device's power supply. Think of each power rail as a power strip.
The best way to try to understand how the breadboard conducts electricity is this image (on the right) that shows the metal strips embedded inside the breadboard:
When a jumper wire is inserted into a breadboard hole, it makes contact with the metal strip underneath. Any wires or parts that are connected to the same metal strip are therefore connected electrically to each other. As the picture above shows, there are separate rows of metal strips on the left side and the right side.
The red arrows in the image are pointing to the metal strips under the power rails. Again, think of these two power rails as two power strips. Once you plug a power rail into a power supply (by connecting it to the Photon board), you can plug other parts into the power rail.
In order to "plug in" a power rail, you have to connect a jumper wire from a voltage source (+) on the Photon board (such as the 3.3V pin) to any hole in the positive (+) column of the power rail. Then connect a second jumper wire from any hole in the negative (-) column of the power rail back to one of the GND (-) pins on the Photon board. Now if a part on the breadboard needs access to voltage (+) or GND (-), you can connect a jumper wire between a hole in that part's corresponding row and any hole in the appropriate power rail column (either + or -).
Depending on which parts are being connected, it may be necessary to only activate and use the negative (-) power rail. This is because every part needs to connect back to GND on the Photon board (and there are only 3 GND pins available). Since many parts use a digital or analog pin as their voltage source (+), sometimes it might not be necessary to activate and use a positive (+) power rail.
The fact that there are two power rails can be helpful if you have certain parts that need a lower voltage (such as 3.3V) while other parts need a higher voltage (such as 5V). You can supply these different parts with their appropriate voltage by connecting them to the correct power rail.
If necessary, you can even "plug in" one power rail to the Photon board, and then connect the second power rail to the first power rail.
Here's how you can determine whether you need to connect one or more power rails on the breadboard:
If you have only have 1-3 parts to connect, then you can choose to connect each part to a separate GND pin using a jumper wire. However, it's actually a good habit to instead connect the negative power rail because it makes it easier if you decide later to add more parts to your device.
Otherwise, use a jumper wire to connect one of the negative power rails on the breadboard to a GND pin on the Photon board. Then connect each part’s GND wire (or resistor) into this negative power rail.
If there is one (and only one) part requiring 3.3V, then connect that part directly to the 3.3V pin on the Photon board.
If there are multiple parts requiring 3.3V, then use a jumper wire to connect one of the positive power rails on the breadboard to the 3.3V pin on the Photon board. Then connect each part’s 3.3V wire into this positive power rail.
If there is one (and only one) part requiring 5V, then connect that part directly to the V-USB pin (5V) on the Photon board.
If there are multiple parts requiring 5V, then use a jumper wire to connect one of the positive power rails on the breadboard to the V-USB pin (5V) on the Photon board. (If you already connected one positive power rail to 3.3V, then connect the second positive power rail to V-USB). Then connect each part’s 5V wire into this positive power rail.
If there are no parts requiring 3.3V or 5V, then do not connect a positive power rail (because all the parts will receive power from their I/O pins). However, you will still use the negative power rail for the GND wires.
Parts have to be arranged so their pins are in their own breadboard rows (which are numbered):
Pins from different parts should not be in the same row. For example, a push button and LED would not share the same rows.
Different pins from the same part should not be in the same row. For example, the Micro OLED display has 8 pins, and each of these pins must be in a different row on the breadboard.
Resistors are the only exception to this rule: a resistor is supposed to share a row with a pin of another part (such as LED, etc.).
Parts should be arranged in a logical layout that makes it easy to understand and use the device:
Place as many of the jumper wires as possible on the side of the breadboard closest to the Photon board, so the wires don't block parts that need to be seen or interacted with.
When learning a new coding language, many people first create what is called a "Hello World" program. Traditionally, this involves displaying the text "Hello World" on the screen. The purpose is to demonstrate that you can create a simple working program in the new coding language.
Creating a working device with an electronics kit involves both building the physical device and programming it. So if your device doesn't work as expected, the reason could be that some of the parts are connected incorrectly – or the program might have a mistake – or it could be both.
So you will create a different kind of "Hello World" app for your Photon device: an app that doesn't require connecting any additional parts to the Photon, so you can first focus on getting some code to work.
The Photon has a built-in blue LED light that is connected to its D7 pin. This "Hello World" app will turn this blue LED on and off in a repeating pattern. This will be your first app before you start to connect additional parts to program more complex devices.
This app – like all apps that run on Photon devices – is coded in a programming language called Wiring. Here's an overview of the Wiring programming language.
Login to your Particle Build account. If necessary, here's a brief overview of navigating and using Particle Build.
Create a new app titled: hello-world
Delete the placeholder code that Particle Build inserted for your new app (the empty setup()
and loop()
functions).
Copy and paste the code below into your new app. Save the app in Particle Build, and then load ("flash") the app onto your Photon device. During "flashing", Particle Build transfers the app to your device over Wi-Fi. The RGB light on your Photon blinks magenta as the new app is being flashed, and then the Photon restarts. Be patient – sometimes it takes longer for your first app to flash because Particle may need to also update the firmware (OS) on your Photon device.
After the Photon has reconnected to Wi-Fi, the new app will automatically start running. If everything worked correctly, the blue D7 LED on your Photon device should blink on and off repeatedly. It may not seem like much, but you've just taken your first step in coding with the Wiring language.
Once you get the app working, try modifying the code to change the LED blinking pattern. Flash your modified app to your Photon to see what your changes do. Can you make the LED blink faster? Can you make it blink slower? Can you make it blink in a more complex pattern (maybe similar to Morse code)?
A couple of things to note about the code:
The lines that begin with two forward slashes are comments. Comments are just notes for people reading the code. The comments are ignored by the device when the app runs. Comments are optional, but it can be helpful to include comments to explain certain parts of the app.
Integers are supposed to be whole numbers, but the Wiring language treats input and output pin names (D7, etc.) as "integer" variables.
UPDATE AVAILABLE: This section of the guidebook has been replaced with a new version (which is now a separate code guidebook). This older version will no longer be available after August 1, 2019.
The references in this section can help with:
connecting parts to create circuits using jumper wires, a breadboard, and the Photon I/O pins
coding Photon apps in the Wiring programming language that will run on the Photon device
coding web apps that interact with Photon apps through the Particle Cloud service
connecting and programming specific inputs and outputs for the Photon device
The defining feature of an IoT device is its ability to send and receive information through the Internet. This allows an IoT device to interact with other apps or with other IoT devices.
The Particle firmware (the operating system) on your Photon device has built-in functions to allow your device to send and receive data through the Particle Cloud service. This will allow your device to interact with web apps that you create.
Particle also has a JavaScript library that provides functions that will allow web apps to send and receive data through Particle Cloud. You can use these functions in your web app's JavaScript code, so that your web app can interact with your Photon device.
The three main ways your Photon device can interact with your web app through Particle Cloud are by:
sharing Photon variable: web app can read value of variable in Photon app
sharing Photon function: web app can send commands and data to Photon app
sharing Photon event: web app can receive event notifications and data from Photon app
You can also combine these Particle Cloud interactions in more complex ways. For example, your Photon app could send an event notification to your web app, which then triggers the web app to read the value of a variable in the Photon app.
This reference contains code examples for both your Photon app and your web app. Many of the code examples will need to be modified, in order to be used in your apps. For example, you may have to change the names of variables, add custom code, etc.
Particle API JS is a JavaScript library that contains functions that will allow a web app to interact with your Photon device by sending and receiving data through Particle Cloud.
A web app must load the Particle API JS file using a <script>
tag in the <head>
section of its HTML file.
If possible, you should load the Particle API JS file from a web service like jsDelivr:
Alternatively, you can download a copy of the Particle API JS file, and place the file into the same folder as your HTML file. In this case, your <script>
tag would load the file directly from the folder:
After loading the Particle API JS file (using one of the methods shown above), your web app also needs to load a JavaScript file containing your own code to interact with your Photon device. This will be loaded using another <script>
tag. The example below would load a JavaScript file (created by you) called: code.js
If a web app wants to interact with your Photon device through Particle Cloud, the web app has to know your Photon device ID and your Photo access token. These act like a username and password to help protect your Photon data.
Your Photon device ID is listed in the "Devices" section of your Particle Build account. Click the arrow to the right of your Photon device name to reveal the device ID. This device ID acts like a username to access your device's data in the Particle Cloud service.
Your Photon access token is listed in the "Settings" section of your Particle Build account. This access token acts as a password to access your device's data in the Particle Cloud service.
Your web app will need to include the device ID and access token in its own JavaScript file in order to interact with your Photon device. Usually these are stored in global variables to make it easier to use them repeatedly throughout your web app's JavaScript code.
Be sure to modify the code above to insert your actual Photon device ID and access token.
In order to use the Particle Cloud functions in the Particle API JS library, your web app's JavaScript file must declare a Particle object variable. This should be a global variable and is usually just called particle
.
Your JavaScript code will use this particle
object variable to run the Particle Cloud functions.
You can share the current values of variables in your Photon app through Particle Cloud, so a web app can read these variables.
For example, your Photon device could measure the air temperature using a sensor, store the measurement in a temperature variable, and then share this variable with a web app.
Particle Cloud will let your Photon device share up to 20 variables at one time. Each cloud variable has to be given a unique name (up to 12 characters in length).
NOTE: The only data types that are allowed to be shared as cloud variables are: int
(whole numbers), double
(decimal numbers), or String
(text, up to 622 characters).
A variable is shared through Particle Cloud by including a Particle.variable
statement in the setup()
function of your Photon app.
This Particle.variable
statement has to provide a name for your cloud variable (up to 12 characters) and identify the name of the variable in your Photon app. Usually, these two will have the same name (but they don't have to).
setup()
function of Photon AppIn the example above, the first name (in quotation marks) will become the name of your cloud variable. The second name identifies the variable in your Photon app that will be shared through the cloud. Modify this code to match your variable's name.
Your web app can read the current value of a cloud variable by using a particle.getVariable
statement in its JavaScript file.
This particle.getVariable
statement needs to provide your Photon device ID, the name of your cloud variable, and your Photon access token.
The value of your cloud variable gets temporarily stored in a local JS variable called data.body.result
that you can use in your JavaScript code.
For example, if you want to display the value in your web app, you could insert the value by using a JavaScript statement to find an HTML element with a specific id name and then changing its HTML content to include data.body.result
. In the code example below, assume that your web app HTML file contains a paragraph tag identified as: <p id="room-temp"></p>
Web apps are frequently updating their HTML through JavaScript statements that identify HTML elements using an id name or class name.
jQuery is a JavaScript library that makes it easier to update your HTML (and your CSS). jQuery statements start with $
and are usually shorter than using regular JavaScript. You can combine jQuery statements and regular JavaScript statements in the same code.
Here's an alternate example of the previous code that uses a jQuery statement instead.
If your web app needs to keep checking the current value of the variable, you can place the particle.getVariable
statement inside another custom function and then have your JavaScript code repeatedly run that custom function on a time interval (such as every 0.5 seconds, etc.).
If your web app needs to save the value of the Photon variable, you should create a global variable in your JavaScript that will be used to store the value. After getting the value of the Photon variable from the Particle Cloud, assign the data.body.result
to the JS global variable.
Your web app can get the values of several Photon variables from Particle Cloud. You just need to include a particle.getVariable
statement for each variable. However, you can put these statements inside the same custom function in your JavaScript. This next example runs a checkLocation()
function every 5 seconds to get the latitude and longitude values from Particle Cloud.
You can share a custom function in your Photon app through Particle Cloud, so a web app can call this function to make it run on your Photon device. The web app also sends data (as a text String up to 63 characters) when calling the function. This is how your web app can send commands and/or data to your Photon app.
For example, your Photon app could share a custom function to turn an LED light on or off. A web app would be able to call this function to make it run on the Photon device.
Particle Cloud will let your Photon device share up to 15 functions at one time. Each cloud function has to be given a unique name (up to 12 characters in length). You get to decide what to name your cloud function – but use a name that will make sense to someone reading your code. (Your web app will have to refer to this same cloud function name, in order to call the function.)
A custom function is shared through Particle Cloud by including a Particle.function
statement in the setup()
function of your Photon app.
This Particle.function
statement has to provide a name for your cloud function (up to 12 characters) and identify the name of the custom function in your Photon app. Usually, these two will have the same name (but they don't have to).
setup()
functionIn the example above, the first name (in quotation marks) will become the name of your cloud function. The second name identifies the custom function in your Photon app that will be shared through the cloud. Modify this code to match your function's name.
In order to share a custom function through Particle Cloud, the function must return an integer value and must accept a String value as an argument.
However, you do not necessarily have to do any with the function's return value. You also do not necessarily have to do anything inside the function with the String value. They just need to be present in the function for it to be shared with Particle Cloud.
When you want to use this custom function in your Photon app, you must pass a String value (text) to the function. Notice in the example below that we pass the text "switch"
when we call the ledToggle()
function, even though the ledToggle()
function above doesn't actually use this String data.
However, you can design your custom function to use the String data that is passed into it. The code examples below show a modified version of the ledToggle()
function for a device that has separate push buttons to turn the LED on and off. The String data passed into ledToggle()
function determines whether it will turn the light on, turn the light off, or do nothing.
If your Photon app needs to save the data sent by the web app when it calls the function, you should create a global variable in your Photon app that will be used to store the data. Then within the custom function called by the web app, assign the String data to the Photon global variable.
The Photon app receives data from the web app in the form of a String (text). However, if the data is actually a number (which was converted to a String by the web app), then you can convert the String data back into a number using either the .toInt()
or .toFloat()
method, depending on whether the number is supposed to be a whole number (integer) or a decimal number (float).
Your web app can call a cloud function to make it run on your Photon device by using a particle.callFunction
statement in its JavaScript file.
This particle.callFunction
statement needs to provide your Photon device ID, the name of your cloud function, an argument (text String) to pass to the function, and your Photon access token.
The argument
is the data that your web app sends to the Photon app. This argument data must be in the form of a text String. You can either list the String directly as text inside quotes, or you can use a String variable to store the text.
Often this particle.callFunction
statement will be included inside another JavaScript function. For example, your web app might have an onscreen button that can be clicked to toggle the LED light on or off.
For example, this code adds an onscreen button to your web app HTML that will run a JavaScript function called switchLight()
when the button is clicked:
This next code shows that the switchLight()
function in your JavaScript simply contains the particle.callFunction
statement.
You can also use a String variable to store the argument
data sent to your Photon app. For example, imagine our web app HTML had two different onscreen buttons: one to turn the light on, and a second to turn the light off.
In the JavaScript, you would declare a global variable to store the String data that will be sent to the Photon app as the argument
data. The example below creates a variable called myData
and sends either "off"
or "on"
to the Photon app depending on which onscreen button is clicked.
If the JavaScript data that you want to send is not already a String (text), then you need to convert the data into a String to send it. Numbers can be converted into a String using the .toString()
method. In this example, a variable containing a number is converted into a text string, in order to send it to the web app.
You can share an event condition that occurs in your Photon app through Particle Cloud, so a web app can be notified when the event occurs. You also have the option for the event notification to include data.
For example, if your Photon device detects movement using a motion sensor, it could send an event notification to a web app. The notification could also include data, such as which motion sensor was triggered.
Particle Cloud will let your Photon device send about one event notification per second. Sending more frequent event notifications can result in Particle Cloud temporarily slowing down your event notifications (which can make your web app become non-responsive).
TIP: To avoid a slowdown by Particle Cloud, you should add an intentional 1 second delay to your Photon code immediately after sending an event notification. (A one second delay in your Photon app is better than your web app becoming non-responsive.)
Each event notification is automatically cleared from Particle Cloud after 60 seconds (to prevent your web app from receiving outdated notifications).
An event notification is shared through Particle Cloud by including a Particle.publish
statement in your Photon app after the event condition occurs.
This Particle.publish
statement has to provide a name for your cloud event (up to 63 characters). You get to decide what to name your event – but use a name that will make sense to someone reading your code. (Your web app will have to use this same event name, in order to receive the notification.) The event can also send additional data as a String (text up to 255 characters), but this is optional.
loop()
or custom functionWhen publishing an event notification, you can also send additional data as a text String (up to 255 characters), but this is optional. The String data can either be sent directly as text inside quotes (as the example below shows) or through a String variable (as the next example shows).
This next example shows how a variable can be used to store the String data that will be sent through the event notification. In this example, the status of two magnetic switch sensors determines which text string is sent to the web app.
If the Photon data that you want to send is not already a String (text), then you need to convert the data into a String to send it. This can be done simply by listing the variable inside a String()
statement. In this example, a fingerprint ID number is converted to a text string, in order to send it to the web app.
Your web app can listen for a cloud event by using a particle.getEventStream
statement in its JavaScript file.
This particle.getEventStream
statement needs to provide your Photon device ID, the name of your cloud event, and your Photon access token. Be sure that your Photon app and web app are using the same name for the cloud event; otherwise, the web app will not receive the event notifications.
If an event notification includes optional String data, this gets temporarily stored in a local variable called feed.data
that you can use in your JavaScript.
This particle.getEventStream
statement can be placed directly after your JavaScript statements that declare the variables for your device ID, access token, and Particle object. (Do not place inside another function.)
The event stream will automatically keep listening for new event notifications. Every time an event notification occurs, it will automatically run the code inserted inside your particle.getEventStream
statement.
If your web app needs to save the data from Photon event notification, you should create a global variable in your JavaScript that will be used to store the data. After getting the event notification from the Particle Cloud, assign the feed.data
to the JavaScript global variable.
You can also combine these Particle Cloud interactions in more complex ways, depending on what is needed for your IoT system.
For example, your Photon app could send an event notification to your web app, which then triggers the web app to read the value of one or more variables in the Photon app.
Imagine a Photon device that is designed to act like a location tracker. Maybe the Photon device is installed in a vehicle, so you can track where the vehicle is parked.
In this example code, the Photon device uses a GPS receiver to determine the latitude and longitude of its location. The latitude and longitude are stored in variables, which are shared with a web app through Particle Cloud. The Photon device also has a push button. When the button is pushed, the Photon app notifies the web app to track the location of the Photon device. When the notification is received, the web app gets the updated values of the latitude and longitude variables from Particle Cloud. Then the web app displays the location on Google Maps using the latitude and longitude.
Apps that run on Photon devices are coded in a programming language called Wiring, which was specifically created for microcontrollers.
Wiring is based on another programming language called Processing. An app written in Wiring actually gets compiled (converted) into another programming language called C++ in order to run on your device.
You may have heard of another popular platform for building and programming electronic devices called Arduino. Arduino is a programming language based on Wiring. In fact, the languages are so similar that many apps created for Arduino devices will also work on Photon devices (or can be modified to work).
Apps for your Photon device are created in the Particle Build online code editor. An app is loaded onto your Photon device by "flashing" (downloading) the app over Wi-Fi (similar to updating an app on a smartphone). Here's a brief overview of navigating and using Particle Build.
You can only store and run one app at a time on your Photon device. However, you can create and save multiple apps in your Particle Build account, making it easy to "flash" a different app onto your device when needed.
Here is the official reference for the Wiring programming language:
Particle also has some custom functions built into the Photon device's firmware (its Operating System). For example, Particle has custom functions for sending and receiving data through the Particle cloud service, etc.
The basic syntax for Wiring code is similar to certain other programming languages (such as Java, C++, etc.). For example, each statement typically ends with a semi-colon, comment lines start with two forward slashes, etc.
Every Wiring app must contain a setup()
function and aloop()
function (but only one of each). In addition, an app can have custom functions. Most apps have global variables.
Here is the basic structure (in order) for the code of a Wiring app:
libraries (if needed for certain inputs or outputs)
global variables
setup()
function (required - can only have one)
loop()
function (required - can only have one)
custom functions (if needed - can have as many as needed)
It can also be helpful if you include some comments in your code.
Comments are just notes to yourself (or to anyone else reading your code) that help explain parts of your code. A comment can be inserted in your code whenever you think it will help. Any comments in your code are ignored by the device when your app runs.
A comment starts with two forward slashes. Everything after the slashes (until the end of the line) will be treated as part of the comment.
Certain inputs or outputs (such as the Micro OLED display, etc.) require that a specific code library is included in your app, so you have access to special functions to control these parts more easily. This is similar to how a webpage will include a JavaScript library, such as jQuery, in order to use special functions.
Particle Build has numerous libraries available and will automatically generate an #include
statement at the top of your code for each library that you add to your app.
Computer programs use variables to store and process data. The data might be numbers, text, etc.
Similar to variables in algebra, variables in computer programs are given names. Each variable should have a unique name. As the person coding the program, you get to decide the unique name for each variable. A variable name could be as simple as x
or y
– but it is better to use names that help describe what the variable represents, such as pushButton
or roomTemperature
. This will help your code make more sense to you and to anyone else reviewing your code.
Variable names cannot contain spaces. A common format used for variable names is to type them in "camelCase": type them in lowercase, but use a capital letter to start any new "word" within the name. (The capital letters in the middle of the name are like the humps on a camel's back.) For example, you cannot name a variable as red button
because it has a space. Instead, any of these names (or other variations) would work: redbutton
or REDBUTTON
or redButton
. The last example is in camelCase, which is easier to read than the first two examples (all lowercase, all uppercase).
Variable names cannot be the same as a keyword in the programming language. These keywords are reserved for your programming instructions. For example, pinMode
is a keyword used to set an I/O pin as an input or output. Therefore, you cannot use pinMode
as the name of a variable. Here is a list of keywords in the Wiring programming language.
Global variables are variables that will be used by multiple functions within your code, such as the setup()
, loop()
, and custom functions. Global variables are typically declared (created) at the top of the code, before the setup()
function. A variable has to be declared before it can be used.
Wiring requires that each variable is declared as a specific data type, such as int (integer numbers), float (decimal numbers), boolean (true or false), String (text), etc.
NOTE: Wiring treats pin names (D7, etc.) for inputs and outputs as int variables.
A variable can be assigned a value when it is first declared by using the "equals" sign. The value of a variable can also be assigned or changed later in the program. You can do other things with variables, such as compare the values of variables, assign the value of one variable to another variable, etc.
Variables that are only used within one function or within one statement (such as: if
statement, for
loop, etc.) can be declared inside that function or statement as a local variable. A local variable only exists inside that particular function or statement and won't be recognized by any outside functions or statements.
There is no difference in how you declare (create) a local variable versus a global variable. The difference is where you declare the variable. The simple rule is that if you declare the variable inside a function (or inside a statement), then it will be treated as a local variable. If you declare the variable outside of a function, then it will be treated as a global variable.
The setup()
function runs one time at the start of program when the device is powered on. The setup()
function typically contains statements that identify the input and output pins being used by the device.
A setup()
function must be included (even if it is simply empty inside), but only one setup()
function is allowed in an app.
After the setup()
function is finished, the loop()
function runs over and over in a repeating loop. The loop()
function usually contains statements that perform the main tasks of the device, such as reading data from inputs, processing the data to make decisions, and writing data to outputs.
A loop()
function must be included (even if it is simply empty inside), but only one loop()
function is allowed in an app.
Custom functions are typically listed at the bottom of the code, after the loop()
function. Custom functions can be run by "calling" their name within another function, such as within the setup()
, loop()
, or a different custom function.
Custom functions are useful for long or complex programs because it allows you to break up your code into smaller modules that perform specific tasks.
Similar to variables, each function must be given a unique name and must have a return data type declared. Some custom functions return a value (such as int, float, String, etc.) when they are run. If a function doesn't return any value, then void
is declared for the return data type. For example, the setup()
and loop()
functions always have void
declared for their return data type.
Custom functions can have values passed into the function as parameters when the function is called. These parameters are declared as local variables inside the parentheses following the function name.
Here is a simple app written in Wiring that has global variables, a setup()
function, a loop()
function, and also a custom function. What will this app do when it runs?
A video can be a very effective way to introduce and explain a new product to people. Your team will create a product demo video to include in your team's product marketing website.
Create a script and storyboard for a video that will demonstrate someone using your smart device solution in a realistic scenario. You can modify and extend your team’s original storyboard – or you can start fresh.
Outline the storyline for a short video (minimum of 30 seconds, maximum of 2 minutes) that shows what happens before, during, and after a person uses your product:
BEFORE = establish setting of story, introduce person, and show what problem or task the person needs to complete
DURING = show the person using your product, including some key details of the product
AFTER = show the benefit of your product and how the person feels after using product
Write out a script that explains who the people are in the story, when and where the events take place, what each person says and does, what needs to be shown, and what needs to be explained (by a narrator or captions).
Based on the script, sketch a complete storyboard that includes every scene in the video. Think about which types of camera shots will best communicate the storyline and show the important details.
Practice and prepare for the video.
Determine when and where to film, especially if showing a particular environment or context is important.
Determine what costumes or props may be necessary (if any).
Determine who will be the actor(s), who will be the narrator (if applicable), and who will record the video.
Use the script and storyboard to practice acting out the scenes and practice capturing the camera shots through different camera movements (tilting, panning, zooming, etc.). It would be ideal to record the video in one continuous take (to avoid or minimize the need for editing).
Record and finalize the video.
If necessary, record additional takes.
If necessary, edit the video (e.g., cut and splice scenes, add captions, add music, etc.).
Upload the final video (such as: Google Drive, YouTube, etc.), so it can be embedded into your team’s product marketing website.
The speaker included in the Photon kit can be used to produce tones or play simple music (note by note).
The speaker is a polarized part, meaning it has to be connected in a certain way to work properly. Specifically, the speaker has a positive pin and a negative pin. These can be identified by markings printed on the bottom of the speaker next to each pin.
Line up the speaker pins different numbered rows on the breadboard (be sure to remember which row has the positive pin), and push down to insert the speaker into the breadboard. Then plug jumper wires into the two rows with the speaker pins and connect them to the Photon.
IMPORTANT: The speaker's positive pin must connect to an I/O pin that supports pulse-width modulation (PWM) output. Only the following pins on the Photon can act as PWM outputs: D0, D1, D2, D3, A4, A5, WKP, RX, TX.
Experiment 5 in the online SparkFun Photon Experiment Guide shows how to connect the speaker. Here is the connection diagram from Experiment 5:
The speaker does not require any special code library.
In the global variables, you should declare which pin is being used as the speaker pin. The example below declares a variable called "speakerPin" (but you could use a different variable name).
Within the setup()
function, you have to include a statement to set the pin mode for the speaker pin variable:
Code for producing tones with the speaker could be placed within the setup()
function (runs only once), within the loop()
function, or within a custom function.
The speaker uses the tone()
function to produce a sound of a specific frequency for a specific duration of time.
The speaker can produce tones ranging in frequency from 20Hz (very low pitch) to 20KHz (very high pitch), which covers the full range of sounds that humans can hear.
NOTE: There is no built-in function to change the volume of the sound. However, you will notice that certain frequencies (in the mid-range) will naturally seem louder.
The tone()
function requires 3 values: speaker pin number, frequency, and duration. These values can be listed in the function as integer numbers or as integer variables.
The frequency should be an integer value ranging from 20-20000 (20Hz to 20KHz). Lower numbers will have a lower pitch (more bass). High numbers will have a higher pitch (more treble).
Note: The range of sounds that humans can hear naturally diminishes with age (starting as early as 18). As people get older, they become less able to hear high-frequency sounds. Everyone (regardless of age) should be able to hear sounds up to a frequency of 8000Hz. However, sounds above this frequency may not be heard by certain adults depending on their age range (so keep this in mind when building a product that uses sound).
The duration should be an integer value representing the number of milliseconds to play the tone (1000 milliseconds = 1 second). The Photon device will play the tone for the designated duration and then automatically turn the speaker off again.
Note: Using a duration of 0 (zero) will cause the speaker to produce a continuous tone.
You can use the notone()
function to turn the speaker off. This is not normally needed since a tone will automatically stop playing after the designated duration.
However, if you are playing a continuous tone (duration = 0) or simply want to turn off the speaker, use the notone()
function.
Try out this example app that plays a song. Do you recognize the song?
If you can figure out the notes and beats to a song, you can change the code below for songNotes
and songBeats
to play that song. Be sure to update the songLength
value, and adjust the tempo
value if necessary.
Did you figure out the song? 😎
LEDs (light-emitting diodes) are small, bright, power-efficient lights commonly used in electronic products.
An LED light is a polarized part, meaning it has to be connected to a circuit in a certain way to work properly. Specifically, each LED has a positive leg and a negative leg. These can be identified visually by length: the negative leg has been made shorter.
To make it easier to insert the LED into a breadboard, you can carefully bend the positive leg as shown, so both legs become the same length. You can still identify them visually: the straight leg is negative, and the bent leg is positive.
The negative leg of the LED has to be connected to GND (-). The positive leg is connected to any I/O pin, which will serve as the voltage source (+).
An LED can be easily burned out if it receives too much power. Therefore, a resistor must be used to help limit the amount of current flowing through the LED.
In order to use a resistor, you will need to bend both ends into 90° angles, so the resistor can be inserted into the holes on a breadboard.
The resistor is typically used in place of a jumper wire to connect the negative leg of the LED to GND (-).
Experiment 1 of the online SparkFun Photon Experiment Guide shows how to connect an LED. Here is the connection diagram for Experiment 1:
The LED does not require any special code library.
In the global variables, you should declare a variable to represent the specific pin on the Photon board that the LED is connected to. This will make it easier to understand your code (and easier to modify the code if you change which pin the LED is connected to). The example below declares a variable called "led" (but you could use a different variable name).
If you are using multiple LED lights, then be sure to give each LED a unique variable name. Use variable names that will make sense when someone reads your code.
Within the setup()
function, you have to include a statement to set the pin mode for the LED pin variable:
If you are using multiple LED lights, be sure to set the pin mode for each LED's pin variable.
IMPORTANT: If you want an LED light to be off when your device first starts, then be sure to include code to do this within the setup()
function (after setting the pin mode). Otherwise, the LED light might be on (at a low brightness) when the device starts, depending on which I/O pin the LED is connected to.
An LED can be turned on or off by using a digitalWrite()
statement. This can be included within the setup()
function (only runs once), within the loop()
function, or within a custom function.
To turn on an LED, set its LED pin variable to HIGH
:
To turn off an LED, set its LED pin variable to LOW
:
An LED can be turned on to a specific brightness by using a analogWrite()
statement, instead of using digitalWrite()
. However, the LED must be connected to a pin that is capable of PWM output.
PWM stands for pulse-width modulation, which is how a digital output signal (which has only two values: HIGH or LOW) can act like an analog output signal (which has a range of values).
Only the following pins on the Photon RedBoard can act as PWM outputs: D0, D1, D2, D3, A4, A5, WKP(A6), RX, TX.
To adjust the LED brightness, set the LED pin variable to any integer value between 0-255:
The servo motor included in your Photon kit can rotate back or forth to any position between 0° and ~180° and hold its position. (In reality, this servo motor only physically rotates to about 160°, even if it is told to rotate to 180°.)
However, this type of servo motor is different from other motors that rotate continuously, like a motor used in a fan or an engine. If your device needs continuous rotation, then you need another type of motor, such as a gear motor or a continuous rotation servo motor.
The servo motor comes with 4 different plastic mounts (called "horns") that can be attached to the motor axis (the white part sticking out of the top of the motor – this is what actually rotates). There is a single-arm horn, a double-arm horn, a four-point horn, and a circular horn. Each horn just slips onto the motor axis (the horn and axis have matching "teeth"). Each horn has holes, which can allow you to attach something to the arm, using the included small screws.
The servo motor has a built-in 3-wire connector: just plug 3 jumper wires into the connector and then plug the other end of the jumper wires into a breadboard or directly to the Photon. To make it easier to remember which wire is which, use corresponding white, red, and black jumper wires to match the servo motor wires.
NOTE: The servo motor requires 5V of power, so connect it (directly or indirectly) to the V-USB pin.
IMPORTANT: The data wire must connect to an I/O pin that supports pulse-width modulation (PWM) output. Only the following pins on the Photon can act as PWM outputs: D0, D1, D2, D3, A4, A5, WKP, RX, TX.
TIP: Be sure to attach one of the horns to your servo motor. Otherwise, you won't be able to see the servo motor rotate (and it won't provide much use to your device). Later, once you test out your code to rotate the servo motor, you may need to remove and re-position the horn, so it's lined up where you want it to be. The easiest way to do this is to rotate the servo motor to 0° and then remove and re-position the horn how you want it to be pointed when it is at this angle.
Experiment 7 of the online SparkFun Photon Experiment Guide shows how to connect the servo motor. Here is the connection diagram for Experiment 7 (ignore the wiring for the push button):
The servo motor does need a code library with special functions that will allow you to control the servo motor. However, this library is already built-in to the Particle firmware on your Photon device.
In the global variables, you should declare which pin is being used as the servo motor data pin. The example below declares a variable called "servoPin" (but you could use a different variable name).
You also need to declare a Servo object variable that you will use to run the special functions in the built-in Servo library. The example below declares a variable called "servo" (but you could use a different variable name).
You may also want to declare a global variable to represent the current position (in degrees) of the servo motor. This isn't required, but it could make it easier to code the servo motor, especially if you create a custom function to rotate the motor. The example below declares a variable called "angle" (but you could use a different variable name).
There isn't any code that you need to include in the setup()
function. You don't have to set a pin mode for the servo.
However, you may want to rotate your servo motor to a particular starting position when your device first starts. If so, then include this code in the setup()
function.
Code for rotating the servo motor to a specific angle can be placed within the setup()
function (only runs once), within the loop()
function, or within a custom function.
Rotating the servo motor always takes four steps: (1) turn on the motor, (2) rotate the motor, (3) wait for a small time delay, and (4) turn off the motor.
Every time you want to rotate the servo motor, you first have to call a special function called servo.attach()
to turn on the motor.
Then you call a function called servo.write()
to rotate the servo motor to any angle from 0-180. For example, use servo.write(90);
to rotate the servo to the 90° position.
You have to include a small time delay()
before you turn off the motor. Otherwise, the servo motor might get turned off before it finishes rotating (because computer code runs much faster than the motor can physically rotate).
If you are rotating the motor by 180° (from 0° to 180° or from 180° to 0°), then delay(500);
(0.5 seconds) should be sufficient.
If you are rotating the motor by 90°, then delay(250);
should be sufficient.
If you are rotating the motor by only 1° at a time, then the delay can be just 15 milliseconds per degree: delay(15);
After rotating the servo motor, you should call a function called servo.detach()
to turn off the motor. Otherwise, the motor will be "jittery" as it tries to hold its position. After you turn off the motor, you may notice that it "debounces" (rotates backward slightly). This is normal.
Here's code that shows all 4 steps combined:
REMINDER: Once you've got your servo motor working, you may need to remove and re-position the horn, so it's lined up where you want it to be for your device. The easiest way to do this is to rotate the servo motor to 0° and then remove and re-position the horn how you want it to be pointed when it is at this angle.
IMPORTANT: You will notice that this servo motor can only physically rotate to about 160°, even if the code tells it to rotate to 180°. This is a minor limitation of this particular servo motor. You may need to try out different rotation angles in your code to make your device work the way you need it to.
It may be simpler to include a custom function in your Photon app that will rotate the servo motor to the current value of the angle
variable. This will allow you to change the value of angle
and then rotate the motor, without having to add code for the 4 steps (attach, write, delay, detach) every time you need to change the servo position.
Here's an example that shows the loop()
function calling a custom function called moveServo()
. This example simply rotates the servo motor back and forth between 0° and 180° every 5 seconds. (This extra 5-second delay between rotations is not necessary for your app.)
The RHT03 sensor can measure the relative humidity and temperature of the air.
The front of the RHT03 sensor has openings to allow air in. Line up the sensor pins with different numbered rows on a breadboard, and push down to insert the sensor pins. Then use jumper wires to connect these rows to the Photon.
Looking at the front of the sensor, if these pins were numbered left to right as 1-4, the jumper wire connections would be:
The RHT03 sensor has 4 pins, but only 3 of them need to be connected.
Experiment 6 of the online SparkFun Photon Experiment Guide shows how to connect the RHT03 sensor. Here is the connection diagram for Experiment 6 (ignore the wiring for the photocell and resistor):
Your Photon app must include a code library with special functions that will allow you to use the RHT03 sensor.
In Particle Build, click on the bookmark icon to open the Libraries sidebar.
Type "rht" into the search field. Select the result called: SPARKFUNRHT03
Click the button to "Include in Project"
Select the name of your Photon app, and then click the "Confirm" button
Particle Build will automatically insert an #include
statement at the top of your app code
In the global variables, you should declare which pin is being used as the RHT03 data pin. The example below declares a variable called "rhtPin" (but you could use a different variable name).
You also need to declare a RHT03 object variable that you will use to run the special functions in the RHT03 library. The example below declares an object variable called "rht" (but you could use a different variable name).
You will also want to declare a global variable for the temperature reading and/or humidity reading. The readings from the sensor are float
values (numbers with decimals), but you can convert these into an int
value (whole number) by rounding them after reading them (because people usually just want to know the temperature to the nearest degree, not to multiple decimal places).
TIP: If you aren't planning on using the humidity reading in your app, then don't create a global variable for it. (The same for the temperature variable if you only care about the humidity reading.)
You have to include this statement within the setup()
function to start the RHT03 sensor:
Code for reading the RHT03 sensor measurements would mostly likely be placed within the loop()
function or within a custom function.
Every time you want to get a new sensor reading, you first have to call a special function called rht.update()
. If the update is successful, the function will return a value of 1 (true). If so, then you can get the new measurement(s).
Each measurement is a float
value (number with decimals). In the code example below, we are rounding the readings to store them as global int
variables.
The humidity reading will be a value between 0-100 representing the relative humidity of the air (as a percentage). Higher numbers are more humid (more water vapor in air).
TIP: If you aren't planning on using the humidity reading in your app, then don't include the lines of code to take the humidity reading. (The same for the temperature reading if you only care about the humidity reading.)
The push buttons included in your Photon kit are classified as momentary switches, which means they detect when they are being pressed or pushed. For example, the keys on a computer keyboard are momentary switches: they are only "on" when you press them (and they turn "off" when you release them).
This is different from maintained switches, which toggle between one state and another state. For example, a light switch is a maintained switch: pressing (or flipping) the switch will turn it on, and it will stay this way until pressed again (or flipped back).
The push button has 4 metal legs on its base (two legs on one side, and two legs on the opposite side). Unlike most other parts that connect to only one side of a breadboard, the push button has to connect to both sides of a breadboard.
Place the push button along the middle divider of the breadboard, so 2 of its legs will connect to the left side, while the other 2 legs will connect to right side. Carefully line up the legs with breadboard holes, and then firmly press the button down to "snap" its base into place. Then use jumper wires to connect 2 of the button legs to the Photon.
Experiment 2 of the online SparkFun Photon Experiment Guide shows how to connect a push button. Here is the connection diagram for Experiment 2 (ignore the wiring for the LED and resistor):
TIP: Be sure each jumper wire for the button is connected to the same row as one of the button legs. Both jumper wires should be placed on the same side of the breadboard (either the left or right side).
The push button does not require any special code library.
In the global variables, you should declare a variable to represent the specific pin on the Photon board that the push button is connected to. This will make it easier to understand your code (and easier to modify the code if you change which pin the button is connected to). The example below declares a variable called "button" (but you could use a different variable name).
If you are using multiple push buttons, then be sure to give each button a unique variable name. Use variable names that will make sense when someone reads your code.
Within the setup()
function, you have to include a statement to set the pin mode for the button pin variable:
If you are using multiple buttons, be sure to set the pin mode for each button's pin variable.
Code for checking the button would be placed within the loop()
function or within a custom function.
The current state of the push button can be detected by using a digitalRead()
statement.
If the button is currently being pressed, digitalRead()
will return a value of LOW
.
Often, a local variable is used to store the result of the digitalRead()
, so that your code can use this result to make decisions based on whether the button is being pressed.
Even though the push button is a momentary switch (which is only "on" when being pressed), you can modify your Photon code to make the button act like a maintained switch (which toggles between states with each press).
The key to doing this is to create a global variable that will store the current status of the part that you want the button to control (such as an LED light being "on" or "off"), so you can switch the status every time the button is pressed.
It will also help to include a delay()
statement before reading the button again because it takes a person a fraction of a second to physically press and release the button. This small delay will allow the code to detect each press as a single event (instead of as multiple presses).
The Micro OLED display included in your Photon kit is a monochrome, blue-on-black screen that is 64 pixels in width and 48 pixels in height. It can be used to display text, graphics, or a combination.
The Micro OLED display requires using 7 jumper wires to connect specific OLED pins to specific pins on the Photon board.
The OLED pins are located along the top of the OLED display. Line up the pins with different numbered rows on a breadboard, and push down to insert the OLED display pins. Then use jumper wires to connect these rows to the Photon.
If the pins along the top of the display were numbered left to right as 1-8, the jumper wire connections would be:
NOTE: Several analog pins on the Photon board are duplicated. For example, there are two pins labeled as A2, two A3 pins, two A4 pins, and two A5 pins. However, the OLED only has to connect to a single A2 pin, not both (same goes for A3 and A5 pins). The only limitation is that you will not be able to connect another part (such as LED, etc.) to the other A2, A3, or A5 pins.
There are two experiments in the online SparkFun Photon Experiment Guide that show how to connect the Micro OLED display to the two different sets of analog pins. Either way works fine:
Experiment 10 shows how to connect the OLED to the analog pins on the lower left of the Photon board
Experiment 11 shows how to connect the OLED to the analog pins on the upper right of the Photon board.
Here is the connection diagram for Experiment 11 showing one way to connect the Micro OLED (ignore the wiring for the three buttons):
Your Photon app must include a code library with special functions that will allow you to control the OLED display.
In Particle Build, click on the bookmark icon to open the Libraries sidebar.
Type "oled" into the search field. Select the result called: SPARKFUNMICROOLED
Click the button to "Include in Project"
Select the name of your Photon app, and then click the "Confirm" button
Particle Build will automatically insert an #include
statement at the top of your app code
The following code should be included in your global variables to define certain pins that the OLED is using and to declare a MicroOLED object variable called "oled" that you will use to run the special functions in the OLED library.
You have to include a statement within the setup()
function to start the OLED display:
Code for displaying text could be placed within the setup()
function (only runs once), within the loop()
function, or within a custom function.
Code for displaying text on the OLED screen consists of at least 5 steps: (1) clear the screen, (2) set the cursor position on the screen, (3) set the font type (font size), (4) print text to the screen, and (5) display the updated screen.
If desired, steps 2-4 can be repeated to change the cursor position and/or font type for different text that you want to print on the screen.
To clear the screen:
The cursor (starting point for printing) can be set to any x-position and y-position. The OLED is 64 pixels wide by 48 pixels tall. The upper-left corner of the screen is (0,0).
There are 4 font types (sizes) available. The font type is set by referring to the font type number (0, 1, 2, or 3):
Here are the differences between the font types:
You can mix font types on the screen by printing something in one font type and then switching to a different font type to print something else.
Text and variable values (integer, float, or String) can be printed to the screen. Text that is longer than the screen column width will automatically wrap to the next line.
However, once the entire screen is filled with text, the screen will not scroll. Instead no more new text will be displayed. The screen will have to be cleared in order to display new text.
There are two different print commands: print()
and println()
print()
will print text to the screen, but the cursor will remain on the same line. So the next text printed to the screen starts where the last text ended.
println()
will print the text to the screen, and then move the cursor to the start of a new line. So the next text printed to the screen starts on the new line.
The print()
command is helpful for combining text and variables on the same line:
Text printed to the screen will not actually be shown until you specifically tell the OLED to display the updated screen.
Code for displaying graphics could be placed within the setup()
function (only runs once), within the loop()
function, or within a custom function.
More info coming...
The motion sensor included in your Photon kit uses passive infrared (PIR) light to detect movement.
The motion sensor has a built-in 3-wire female JST connector. If necessary, attach a male JST connector, and plug it into different numbered rows on a breadboard. Then use jumper wires to connect the rows to the Photon. To make it easier to remember which wire is which, use corresponding black, white, and red jumper wires to match the motion sensor wires.
NOTE: The motion sensor requires 5V of power, so connect it (directly or indirectly) to the V-USB pin.
The first part of Experiment 9 in the online SparkFun Photon Experiment Guide shows how to connect the motion sensor. Here is the connection diagram from Experiment 9:
The motion sensor does not require any special code library.
In the global variables, you should declare which pin is being used as the motion sensor data pin. The example below declares a variable called "motionPin" (but you could use a different variable name).
If you are using multiple motion sensors, then be sure to give each motion sensor a unique variable name. Use variable names that will make sense when someone reads your code.
Within the setup()
function, you have to include a statement to set the pin mode for the motion sensor data pin variable:
If you are using multiple motion sensors, be sure to set the pin mode for each motion sensor's data pin variable.
Code for checking the motion sensor would be placed within the loop()
function or within a custom function.
The motion sensor can be checked by using a digitalRead()
statement.
If the sensor is currently detecting motion, digitalRead()
will return a value of LOW
.
Often, a local variable is used to store the result of the digitalRead()
, so that your code can use this result to make decisions based on whether motion is detected.
Think about what your Photon app should do if motion is detected:
turn on a light
make a sound with the speaker (a tone with a frequency of 2000Hz works well)
send a notification to your web app
etc.
A potentiometer is a variable resistor that can be adjusted by sliding, rotating, or another type of physical interaction.
Potentiometers are used in various electrical devices such as: joysticks and other game controllers, control knobs and sliders, dimmer switches for lights, etc.
The potentiometer included in your Photon kit is a "trimpot" that can be rotated and used as a dial. The dial can be rotated approximately 270° (it cannot be rotated all the way around). The position of the dial can be measured and used as an input to change something (such as: brightness of light, volume of sound, etc.) – or to make a selection from a range of values.
Your potentiometer has 3 metal legs. Line up the legs with different numbered rows on the breadboard, and push down to insert the potentiometer into the breadboard. Then use jumper wires to connect the 3 leg rows to the Photon.
IMPORTANT: The middle leg of the potentiometer must connect to an analog I/O pin, such as: A0, A1, A2, A3, A4, A5.
Experiment 4 of the online SparkFun Photon Experiment Guide shows how to connect the potentiometer. Here is the connection diagram for Experiment 4 (ignore the wiring for the 3 push buttons):
The potentiometer does not require any special code library.
In the global variables, you should declare which pin is being used as the potentiometer input pin (middle leg). The example below declares a variable called "dialPin" (but you could use a different variable name).
You will probably also want to declare an integer variable to store the reading from the dial. This will make it easier to do something based on the measurement. The example below declares a variable called "dialReading" (but you could use a different variable name).
There isn't any code that you need to include in the setup()
function for the potentiometer.
IMPORTANT: Do not set a pin mode for the potentiometer.
You can measure the position of the potentiometer dial using an analogRead()
statement. This code would be most likely placed within the loop()
function or within a custom function.
The measurement will be a value ranging from 0-4095.
When the dial is rotated all the way to the left (counterclockwise), the reading will be 0. When the dial is rotated all the way to the right (clockwise), the reading will be 4095.
IMPORTANT: Remember that the dial can only be rotated approximately 270° – it cannot be rotated all the way around.
In many cases, you don't want your dial to give you a number between 0-4095. Instead, you may want a dial that can be used to a select a value between a smaller custom range.
For example, if you were using the dial as a volume control knob, you may want the dial to give you a value between 0-10 (with 0 representing volume off and 10 representing maximum volume). Even better, you may want a volume knob that goes to 11.
To do this, you can use a map()
function that converts a measurement from its original range (such as 0-4095) into a new range of your choice. You decide the minimum and maximum values for this new range.
To map the dial reading to your own custom range of values, it will help to declare global variables for the minimum value of your custom range, the maximum value of your custom range, as well as a variable to store your new dial value mapped within this custom range.
Here's the code to take a dial measurement and then map it to your custom range.
So now you can use your dial to turn it up to 11.
NOTE: The code rounds the mapped value to the nearest integer because the map()
function always returns a decimal value. Also, the code adds 1 to the maxValue because otherwise it is very difficult to select the maximum value even if the dial is turned all the way to the right.
A can detect whether a door, window, drawer, etc. is open or closed.
The switch consists of two pieces, and it can detect whether these two pieces are close to each other. The two pieces have to be within 20 mm (about 0.75 inches) of each other – otherwise, the switch will detect that it is open.
The piece with the wires contains a special switch called a that moves in response to the presence (or absence) of a magnetic field. The other piece (without the wires) contains a small magnet, so it can activate the reed switch when the two pieces are close to each other.
For example, the piece with the wires (the reed switch) could be attached on a stationary door frame, and the piece without the wires (the magnet) would be attached on the door near its edge. The two pieces would be installed so they are very close together when the door is closed. When the door is opened, the reed switch detects that the magnet has moved away.
These magnetic switches are commonly used in security systems, but they are also used in many other products. For example, a doorbell uses a magnetic switch. Small magnetic switches are also used in many laptops and tablets to put the device to sleep when the laptop lid or tablet cover is closed.
The second part of Experiment 9 in the online SparkFun Photon Experiment Guide shows how to connect the motion sensor. Here is the connection diagram from Experiment 9:
The stationary piece of the magnetic switch (the piece with the wires) is connected to the Photon device. The other piece of the magnetic switch would be attached to the movable object (door, window, drawer, etc.) that can be opened.
The magnetic switch does not require any special code library.
In the global variables, you should declare which pin is being used as the magnetic switch pin. The example below declares a variable called "magnetPin" (but you could use a different variable name).
If you are using multiple magnetic switches, then be sure to give each magnetic switch a unique variable name. Use variable names that will make sense when someone reads your code.
Within the setup()
function, you have to include a statement to set the pin mode for the magnetic switch pin variable:
If you are using multiple magnetic switches, be sure to set the pin mode for each magnetic switch's pin variable.
Code for checking the magnetic switch would be placed within the loop()
function or within a custom function.
The magnetic switch can be checked by using a digitalRead()
statement.
If the magnetic switch is closed, digitalRead()
will return a value of LOW
.
If the magnetic switch is open, digitalRead()
will return a value of HIGH
.
Often, a local variable is used to store the result of the digitalRead()
, so that your code can use this result to make decisions based on whether the switch is open or closed.
Think about what your Photon app should do if the magnetic switch detects it is open:
turn on a light
make a sound with the speaker (a tone with a frequency of 2000Hz works well)
send a notification to your web app
etc.
The included in your Photon kit can be used to detect changes in motion or orientation in 3 dimensions (x, y, z).
Smartphones and tablets use accelerometers to sense the orientation of the device, in order to change the screen orientation to match. Fitness trackers use accelerometers to count steps and measure other activity. In fact, your accelerometer has built-in functions to detect portrait vs. landscape orientation (useful for device screens), as well as taps (useful for activity trackers).
Like the name implies, an accelerometer works by detecting acceleration – a change in motion. If a device with an accelerometer experiences a change in motion (i.e., speeding up, slowing down, or changing direction), the accelerometer can sense this change and measure the amount of acceleration in each of the 3 dimensions (x, y, z).
Even if a device with an accelerometer is not moving, the accelerometer can detect the orientation (tilt) of the device by measuring the acceleration due to Earth's gravity, which is a constant downward force acting on all objects. The accelerometer can determine if the object is parallel to the Earth's surface or if it is tilted – and can measure the amount of tilt for each of the 3 dimension (x, y, z).
Line up the accelerometer's pins with different numbered rows on a breadboard, and push down to insert the accelerometer pins. Then use jumper wires to connect these rows to the Photon.
The accelerometer has 6 pins, but only 4 of them need to be connected.
of the online SparkFun Photon Experiment Guide shows how to connect the accelerometer. Here is the connection diagram for Experiment 8 (ignore the wiring for the push button):
Your Photon app must include a code library with special functions that will allow you to use the the accelerometer.
In Particle Build, click on the bookmark icon to open the Libraries sidebar.
Type "mma8452q" into the search field. Select the result called: SPARKFUNMMMA8452Q
Click the button to "Include in Project"
Select the name of your Photon app, and then click the "Confirm" button
Particle Build will automatically insert an #include
statement at the top of your app code
In your global variables, you need to declare a MMA8452Q object variable that you will use to run the special functions in the library. The example below declares an object variable called "accel" (but you could use a different variable name).
You will probably also want to declare global variables for the data from the accelerometer. You only need to include variables for the types of data that your Photon app will actually use. If you want, use can use different names for these variables.
You have to include an accel.begin()
statement within the setup()
function to initialize the accelerometer by setting its scale range (SCALE) and output data rate (ODR).
The accelerometer scale (SCALE) can be set to ± 2, 4, or 8 g (where g is a unit representing Earth's gravity, which is about 9.8 m/s2). The options for setting the scale are designated as: SCALE_2G
, SCALE_4G
, or SCALE_8G
. A higher scale can detect larger changes in acceleration but is less precise. A lower scale is more precise. For your application, using SCALE_2G
is the probably the best choice because it will be the most precise.
The accelerometer output data rate (ODR) determines how frequently it gathers new measurements. The ODR is set in Hz (number of times per second). The options for setting the ODR are designated as: ODR_1
, ODR_6
, ODR_12
, ODR_50
, ODR_100
, ODR_200
, ODR_400
, or ODR_800
. A higher ODR is faster (more frequent), while a lower ODR is slower (less frequent). For your application, using ODR_50
is probably a good choice because it's not too fast and not too slow.
Code for reading the accelerometer data would most likely be placed within the loop()
function or within a custom function.
Your accelerometer can provide three different types of data:
Acceleration Measurements (x, y, z)
Orientation Detection (portrait vs. landscape)
Tap Detection (good for activity tracking)
Every time you want to get new acceleration measurements, you first have to call a special function called accel.available()
. If new measurements are available (which depends on the ODR), the function will return a value of 1 (true). If so, then you can read the new measurements by using an accel.read()
statement.
You can detect the orientation (portrait vs. landscape) of your device by using an accel.readPL()
statement.
The possible values returned for accel.readPL()
are:
PORTRAIT_U
(Portrait Up)
PORTRAIT_D
(Portrait Down)
LANDSCAPE_R
(Landscape Right)
LANDSCAPE_L
(Landscape Left)
LOCKOUT
("Flat" - neither portrait or landscape)
NOTE: You may need to determine the proper physical arrangement of the accelerometer on your device, so that you can accurately read the device orientation.
If your app needed to do something different for each possible orientation value, the code below shows one way to accomplish this. (Another way is to use a switch()
statement instead of if-else statements.)
More info coming...
The can be used to detect sound levels in the nearby environment from 100Hz to 10KHz (which is most of the human hearing range).
IMPORTANT: The data wire must connect to an analog I/O pin, such as: A0, A1, A2, A3, A4, A5.
The microphone does not require any special code library.
In the global variables, you should declare which pin is being used as the microphone data pin. The example below declares a variable called "micPin" (but you could use a different variable name).
You will also want to declare an integer variable to store the sound level read by the microphone. This will make it easier to do something based on the data. The example below declares a variable called "soundLevel" (but you could use a different variable name).
There isn't any code that you need to include in the setup()
function for the microphone.
IMPORTANT: Do not set a pin mode for the microphone.
You can measure the amplitude of the sound in the environment using an analogRead()
statement.
The measurement will be a value ranging from 0-4095. Sounds with a higher amplitude (louder) will have a higher measurement.
However, sound waves have peaks and valleys, so a single measurement is not necessarily an accurate measurement of the sound environment. So it is better to take multiple measurements over a brief period of time (fraction of second) to get the "peak-to-peak" amplitude of the sound level.
The code below shows a custom function called listenMic()
that samples the sound over a window of 50 milliseconds. The custom function is called within the loop()
function. You would need to add code within the loop()
to do something based on the sound level.
The in your Photon kit can measure the amount of moisture in soil or similar materials.
The moisture sensor has two gold-plated legs that you would insert into the soil. Moisture in the soil will allow electricity to conduct from one sensor leg to the other. More moisture allows more electricity to conduct. The sensor can indirectly measure the amount of moisture in the soil by measuring the the amount of electricity being conducted.
Your moisture sensor has an attached 3-pin terminal connector that you will use to attach 3 jumper wires (red, black, and yellow). The back of the sensor has labels for the 3 terminals: VCC, GND, SIG. Use a small flat-head screwdriver to slightly loosen each screw in the connector (turn counterclockwise to loosen – "lefty loosey"). Insert a red jumper wire into the connector opening for VCC. Then use the screwdriver to tighten that screw until the wire is firmly held in place (turn clockwise to tighten – "righty tighty"). Repeat to connect the black wire to GND and to connect the yellow wire to SIG.
Now you can plug the other end of the jumper wires directly into the Photon – or into a breadboard (and then use 3 more jumper wires to complete the connection to the Photon).
NOTE: The moisture sensor power wire (VCC) is being connected to a second I/O pin for power, instead of 3.3V or V-USB (5V). The reason is that your code should only supply power to the moisture sensor when you need to take a reading. After the reading, your code should turn the power off to the sensor. A constant flow of electricity across the sensor legs could cause them to corrode over time (because of natural salts and other minerals in the soil). The gold-plating on the legs resists corrosion, but it is still better to use your code to control when the sensor is actually powered.
IMPORTANT: The moisture sensor data wire (SIG) must connect to an analog I/O pin, such as: A0, A1, A2, A3, A4, A5.
of the online SparkFun Photon Experiment Guide shows how to connect the moisture sensor directly to the Photon (but you could also connect it to a breadboard and then use additional jumper wires to connect to the Photon). Here is the connection diagram for Experiment 3:
Once the moisture sensor is connected to the Photon, you can insert the sensor legs into the soil where you need to take measurements.
The moisture sensor does not require any special code library.
In the global variables, you should declare variables for the pins being used for the sensor power and sensor data. The example below declares variables called "moisturePower" and "moistureData" (but you could use a different variable name).
You will probably also want to declare an integer variable to store the reading from the moisture sensor. This will make it easier to do something based on the measurement. The example below declares a variable called "moistureReading" (but you could use a different variable name).
Within the setup()
function, you have to include a statement to set the pin mode for the moisture sensor power pin variable. You should also turn off the power to the moisture sensor when the device first starts.
IMPORTANT: Do not set a pin mode for the moisture sensor data variable.
Code for measuring the amount of moisture would be most likely placed within the loop()
function or within a custom function.
Measuring the amount of moisture always takes four steps: (1) turn on the power to the sensor, (2) wait for a small time delay (to allow electricity to conduct through the soil), (3) read the measurement, and (4) turn off the power to the sensor.
The measurement will be a value ranging from 0-4095.
When there is less moisture detected, the reading will be lower. When there is more moisture detected, the reading will be higher.
You will need to add code to do something with the moisture reading (such as: display it on the OLED screen, send the data to your web app, turn on LED if the reading is less than a certain value, etc.).
TIP: You can test out the moisture sensor by holding both of the sensor legs between your thumb and index finger. The moisture in your skin will conduct electricity across the sensor legs. Don't worry, the amount of electricity will be very small – you won't even feel it. The moisture reading will be low, but it should be detectable.
RECOMMENDATION: Depending on the specific purpose of your device, you may need to gather some data under different conditions to figure out which moisture values to use in your code to make decisions about what the device should do.
The can take pictures in JPEG format and transfer the picture data over a serial data connection. The camera can take pictures in 3 different sizes: 640×480 pixels, 320×240 pixels, or 160×120 pixels.
In normal lighting, the camera takes color pictures. When it's dark, a built-in ambient light sensor automatically turns on infrared LEDs to allow the camera to take black-and-white photos ("night vision").
The camera lens has a protective cover that you will need to remove before taking pictures. The camera board has holes in three of its corners, which could be used to help mount the camera to a surface.
The camera has a 4-wire connector. The ends of these wires are too wide to insert directly into a breadboard. However, you can connect additional wires to the camera wire ends, in order to connect to a breadboard or directly to the Photon. (In fact, you can simply plug a jumper wire into each camera wire end. To make it easier to keep track of the wires, use jumper wires with matching colors.)
The camera will communicate with the Photon board over a serial data connection using the Photon RX and TX pins.
NOTE: For serial data connections, the RX pin of one device connects to the TX pin of the other device. (RX = receive, TX = transmit)
You need to include a statement within the setup()
function to start a serial data connection (which will activate both the RX and TX pins on the Photon). This will allow the Photon and the camera to send and receive data between each other. The camera communicates at a default baud rate of 38400 bps.
A can be used as an input for codes or commands. It has buttons for ten digits (0
-9
) and two symbols (*
,#
).
The keypad has 9 pinouts, but only the middle 7 are used. (The outer pinout on each side is not used.)
The keypad works by wiring the 12 buttons into 3 columns and 4 rows (thus 7 pinout wires). Pressing a button sends a signal through two wires representing the column and row of the key that was pressed. For example, key “8” is in column 2 and row 3 (which correspond to pinout wires 1 and 6).
Connect wires to each of the 7 pinouts, and then connect the other ends of the wires into different numbered rows in a breadboard. Then use jumper wires and resistors to connect the rows to the Photon.
FYI: Notice that this part does not connect to GND, which is unusual.
A code library for the keypad has to be included in your Photon app:
In Particle Build, click on the bookmark icon to open the Libraries sidebar.
Type "keypad" into the search field. Select the result called: KEYPAD_PARTICLE
Click the button to "Include in Project"
Select the name of your Photon app, and then click the "Confirm" button
Particle Build will automatically insert an #include
statement at the top of your app code
This code library contains special functions that allow you to interact with the keypad.
In the global variables, you will need to declare variables that will help set up the keypad buttons for the Keypad library functions. You will also need to declare a Keypad object variable that you will use to run the special functions in the library. The example below declares an object variable called "keypad" (but you could use a different variable name).
You will probably also want to declare variables for a secret PIN code or commands that can be entered to control the device.
NOTE: Be sure to use single quotes when listing key characters (not double quotes).
There isn't any code that you need to include in the setup()
function for the keypad.
You can read a key press by using a keypad.getKey()
statement that will identify which key is being pressed. (If no key is being pressed, the statement returns a value of false.)
If you want to check for a specific key, you can compare the value of key
to a specific keypad character.
Notice that delay(100);
was included at the end of the if(key)
statement. This is because it takes a person a fraction of a second to physically press and release a key. Including a small delay (0.1 seconds) before checking again for a key press will allow the code to detect each key press as a separate event (otherwise, it might detect it as multiple presses of the same key). You may need to fine-tune the delay value based on user testing, so the delay is not too fast and not too slow.
You can also use a series of if-else statements to compare the key pressed against multiple keys, in order to do something different based on which key is pressed.
NOTE: Be sure to use single quotes when listing key characters (not double quotes).
Here is an example of a custom function called checkPIN()
that will detect whether a secret PIN code has been correctly entered. You will need to add instructions to do something if the secret code is correctly entered.
A can be used to determine a device's location and velocity, as well as the date and time.
There are numerous GPS satellites in orbit around Earth. Each satellite broadcasts one-way radio signals that contain precise satellite location data and time data.
A GPS receiver uses the signals from at least 4 different satellites to calculate its own precise location (latitude and longitude, plus altitude). The GPS receiver can track changes in its location over time to calculate its velocity (speed and direction of motion). It can also verify the precise time and date using the satellite data.
Location data from GPS receivers are not perfectly accurate. Under ideal conditions, a GPS receiver's location data will be accurate to within about 15 feet of the actual location. The GPS accuracy can be affected by factors such as blocked signals, reflected signals, etc. For example, a GPS location is less accurate inside buildings and other structures (and GPS signals might even be blocked). Even outdoors, being near tall structures (buildings, trees, etc.) can reduce GPS accuracy.
The GPS receiver will send the GPS data to the Photon board over a serial data connection using the Photon RX pin.
NOTE: For serial data connections, the RX pin of one device connects to the TX pin of the other device. (RX = receive, TX = transmit)
In Particle Build, click on the bookmark icon to open the Libraries sidebar.
Type "gps" into the search field. Select the result called: TINYGPS++
Click the button to "Include in Project"
Select the name of your Photon app, and then click the "Confirm" button
Particle Build will automatically insert an #include
statement at the top of your app code
This code library contains special functions that allow you to interact with the GPS receiver.
In your global variables, you need to declare a TinyGPSPlus object variable that you will use to run the special functions in the library. The example below declares an object variable called "gps" (but you could use a different variable name).
You may also want to declare global variables for the data from the GPS receiver. You only need to include variables for the types of data that your Photon app will actually use. If you want, use can use different names for these variables.
You need to include a statement within the setup()
function to start a serial data connection (which will activate both the RX and TX pins on the Photon). This will allow the Photon to receive data from the RFID reader. The GPS receiver communicates at a baud rate of 9600 bps.
Code for reading GPS measurements should probably be placed within its own custom function, which can then be called within the loop()
function.
Before reading new GPS measurements, you must first complete several checks: (1) check to see if new serial data is available, (2) if so, check to see if the serial data can be encoded by the GPS receiver, and (3) if so, does the GPS receiver have valid location data. If all these checks are okay, then the GPS measurements can be read.
The code below shows a custom function called checkGPS()
that performs these checks and then reads GPS data (including latitude, longitude, elevation, speed, and direction). The code can be modified to remove any GPS measurements that are not necessary for your Photon app.
Inside the loop()
function, you will have to insert additional code to do something with the GPS data after it has been read (such as display it on an OLED screen, send the data to your web app, etc.).
NOTE: When you power on your GPS receiver, it may take a few minutes to establish a valid location, especially if the GPS receiver has traveled some distance or a long time has elapsed since its last use. Also remember that GPS signals can be scattered (or even blocked) inside buildings and other structures. However, under regular usage (and especially if outdoors), the GPS receiver will quickly establish a valid location.
Locations in the United States will have a positive latitude (north of Equator) and negative longitude (west of Prime Meridian).
Elevation (or altitude) measures distance above mean sea level.
The GPS receiver can determine its speed and direction of travel by tracking changes in its location over time. If the location changes over time, it can determine the distance traveled and then calculate the speed as distance divided by time.
The GPS receiver can also determine the direction of travel (also called "course"). The direction is reported as an angle (0°-360°) measured clockwise relative to true north. For example, a direction of due north is 0°, a direction of due east is 90°, a direction of due south is 180°, a direction of due west is 270°, etc.
NOTE: Even a stationary GPS receiver will report a non-zero speed (usually less than 1 mph). Remember that the GPS receiver's location data is only accurate to within about 15 feet of the actual location. Each new GPS reading will be slightly different even if the GPS receiver is stationary. Because the location readings are "different", the GPS receiver acts as if it were "moving" (which means it has a non-zero speed). This is also why the GPS receiver will report a direction (course), even if it is actually stationary. So just keep in mind that speed calculations will have a small margin of error.
The example code below introduces a new custom function called getDistance()
that calculate the distance (in miles) between the current GPS location and another GPS location. Your code needs to provide the latitude and longitude of the other location.
NOTE: The TinyGPS++ library does have a built-in function to calculate the distance (in kilometers) between two GPS locations. However, this library function does not return accurate values due to a mistake in its formula. Instead, use the custom function provided above.
GPS satellites broadcast date and time information in Coordinated Universal Time (abbreviated as UTC). If a device knows its local time zone (which you could figure out using your GPS location), then the UTC data could be converted into a precise local date and time. For example, Eastern Standard Time is 5 hours behind UTC (but Eastern Daylight Time is only 4 hours behind UTC).
If you need date and time information from the GPS receiver, you can declare additional global variables, as shown below.
Then, within the checkGPS()
custom function, you would add the following code to get the UTC date and time.
A force sensitive resistor (FSR) can be used to measure applied force or pressure. can measure force from approximately 0.25 pounds to 22 pounds. (Higher forces can be applied to the FSR, but the measurement will reach a maximum value.) The measurement is proportional to the amount of force applied, but it isn't accurate enough to serve as a scale.
The force sensitive resistor has 2 pins. One option is to insert these pins directly into different numbered rows on a breadboard. If you need longer leads, another option is to take 2 wires, line them up side by side so each wire makes contact with one pin, and then wrap this connection in electrical tape to hold them securely together, and then insert the other end of the wires into a breadboard. Either way, you will need to use 2 jumper wires and a resistor to then connect the breadboard rows to the Photon.
IMPORTANT: The FSR must connect to an analog I/O pin, such as: A0, A1, A2, A3, A4, A5.
The FSR does not require any special code library.
In the global variables, you should declare which pin is being used as the FSR analog input pin. The example below declares a variable called "forcePin" (but you could use a different variable name).
You will probably also want to declare an integer variable to store the reading from the FSR. This will make it easier to do something based on the measurement. The example below declares a variable called "forceReading" (but you could use a different variable name).
There isn't any code that you need to include in the setup()
function for the FSR.
IMPORTANT: Do not set a pin mode for the FSR.
You can measure the amount of applied force using an analogRead()
statement. This code would be most likely placed within the loop()
function or within a custom function.
The measurement will be a value ranging from 0-4095.
When there is less force detected, the reading will be lower. When there is more force detected, the reading will be higher.
This FSR can measure from 0.25 pounds to 22 pounds of applied force. (Higher forces can be applied to the FSR, but the measurement will max out at 4095.) The measurement is proportional to the amount of force applied, but it isn't accurate enough to serve as a scale.
You will need to add code to do something with the force reading (such as: display it on the OLED screen, send the data to your web app, run a custom function if the reading is more than a certain value, etc.).
RECOMMENDATION: Depending on the specific purpose of the FSR in your device, you may need to gather some data under different conditions to see how much force will actually be applied when your device is used. This will help you decide which values to use in your code to make decisions about what the device should do.
A fingerprint scanner can add encoded fingerprint images to a database and then read a fingerprint to compare it against the stored fingerprints for identification purposes.
The can store up to 200 different fingerprints in its onboard database.
This fingerprint scanner comes with a 4-wire connector (1 black wire + 3 white wires). Insert the wires into different numbered rows on a breadboard. Then use jumper wires to connect these rows to the Photon.
If the fingerprint scanner wires were numbered left to right as 1-4 (with the black wire being Wire 1), the jumper wire connections would be:
The fingerprint scanner will transfer data with the Photon board over a serial data connection using the Photon RX and TX pins.
NOTE: For serial data connections, the RX pin of one device connects to the TX pin of the other device. (RX = receive, TX = transmit)
TIP: The fingerprint scanner has a small built-in green LED. If the Photon device is powered on and you have correctly wired the fingerprint scanner, this green LED should be on.
Your Photon app must include a code library with special functions that will allow you to control the fingerprint reader.
In Particle Build, click on the bookmark icon to open the Libraries sidebar.
Type "fingerprint" into the search field. Select the result called: FINGERPRINT_FPS_GT511C3
Click the button to "Include in Project"
Select the name of your Photon app, and then click the "Confirm" button
Particle Build will automatically insert an #include
statement at the top of your app code
In your global variables, you need to declare an FPS_GT511C3 object variable that you will use to run the special functions in the library. The example below declares an object variable called "fps" (but you could use a different variable name).
You will probably also want to declare an integer variable to store a fingerprint ID number (such as the ID of the detected fingerprint, etc.). This will make it easier to do something with this ID. The example below declares a variable called "fingerprintID" (but you could use a different variable name).
You need to include a statement within the setup()
function to start a serial data connection (which will activate both the RX and TX pins on the Photon). This will allow the Photon and the fingerprint scanner to send and receive data between each other. The fingerprint scanner communicates at a baud rate of 9600 bps.
You also need to include statements to start ("open") the fingerprint scanner and to turn on the LED inside the scanner.
You can use the following temporary code to test whether your fingerprint scanner is wired correctly and able to communicate with your Photon. It will simply turn the scanner's internal LED on and off in a blinking pattern. Once you've verified this works, you can remove this code from the loop()
function.
You can do the following tasks with the fingerprint scanner:
Check If Finger Pressed
Add Fingerprint
Delete Fingerprint
Verify Fingerprint Against Specific ID
Verify Fingerprint Against All Stored IDs
This code will most likely be placed within the loop()
function or within custom functions.
RECOMMENDATION: Use the speaker and/or LEDs to provide feedback on whether a fingerprint was verified or not. For example, if the fingerprint is verified, you could turn on a green LED and/or play a short medium-pitched sound. If the fingerprint is not recognized, you could turn on a red LED and/or play a longer low-pitched sound.
You can check whether a finger is being pressed against the scanner using a fps.IsPressFinger()
statement, which will return either true or false.
For example, if a finger is pressed against the scanner, you could have your code verify whether the fingerprint is already stored in the database, etc.
Before you can verify a fingerprint, you will obviously need to have at least one fingerprint added to the scanner database.
The fingerprint scanner can store up to 200 different fingerprints in its onboard database. Each fingerprint is given a unique ID number from 0-199. The fingerprints stored in the database will be retained even when the scanner is powered off.
Adding a new fingerprint is a process called "enrollment" which consists of capturing high-quality images of the same fingerprint 3 times in a row for comparison. This 3-step enrollment verifies the scanner is able to read and identify the fingerprint accurately and consistently.
During fingerprint enrollment, the person presses their finger on the scanner for the first capture, and then lifts the finger. The same finger is pressed down again for a second capture, and lifted again. Finally, the finger is pressed for a third capture, which will ideally complete the process. However, the enrollment process can fail at any of these 3 steps.
TIP: Be patient, as enrollment may take more than one try. However, once a fingerprint is successfully enrolled, verifying that fingerprint in the future is usually fast and accurate.
It is important to have some type of clear feedback during the enrollment process to know when to press and lift the finger, as well as to know whether the enrollment steps were successful or failed. This feedback could be provided through the OLED display screen, red & green LED lights, the web app, etc.
You could use this code to enroll one or more fingerprints. Then you could remove the addFingerprint()
statement from the loop()
function, and replace it with your primary app code (to verify a fingerprint against the database and then do something with the result).
TIP: Once you are done enrolling fingerprints, you can still keep the code for the addFingerprint()
custom function in your app, even if you are no longer calling it in the loop()
. This will make it easier for you to add more fingerprints later, if necessary.
RECOMMENDATION: If you will need your Photon app (or web app) to know which fingerprint ID is assigned to which person, it may be easier to record this ID number immediately after successfully enrolling the finger. If a person (such as yourself) is going to register multiple fingers, then record the ID number for each specific finger (right index, left thumb, etc.) that you enroll. Then later, you can use this information to have your Photon app (or web app) make different decisions based on which specific fingerprint ID is detected by the scanner.
That's a lot of code compared to what's been needed for other parts. Luckily, the other fingerprint scanner tasks only require a few lines of code at most.
If necessary, you can delete a specific fingerprint from the scanner database by providing its ID (0-199) either as a number or as an integer variable.
If necessary, you can also delete all the fingerprint images from the scanner database. Be careful using this statement – there is no "undo" if you delete all the stored fingerprints.
You can use the fps.Verify1_1()
statement to verify whether a finger matches a specific fingerprint ID by providing the ID (0-199) to check against. The ID can be provided as a number or as an integer variable.
First, you need to capture an image of the finger being pressed. For faster identification, a lower-resolution image is captured.
If the captured fingerprint matches the specific fingerprint ID stored in the database, the fps.Verify1_1()
statement will return true. Otherwise, it will return false.
In most cases, you will want to use the fps.Identify1_N()
statement to verify whether a fingerprint matches any of the fingerprints stored in the database – and if so, identify which fingerprint ID matches.
First, you need to capture an image of the finger being pressed. For faster identification, a lower-resolution image is captured.
If the fingerprint matches an ID stored in the database, the fps.Identify1_N()
statement will return the matching ID number (0-199). Otherwise, it returns a value of 200 if the fingerprint isn't in the database.
An can be used to read ID numbers (or other data) stored in RFID tags, labels, and chips. RFID stands for "" – radio waves of a specific frequency are used to read the data from a distance.
RFID is used extensively by industries and stores to keep track of inventory. Some companies give their employees RFID cards for access to buildings and other purposes. Some people have their pets embedded with a RFID microchip to help identify the pet if it gets lost and is found by someone.
Near-Field Communication (NFC) is a type of RFID. For example, the Apple Pay and Android Pay features in certain smartphones use NFC.
The RFID reader kit comes with an RFID reader (the black reader module has pins that plug into to the female pins on the reader board) plus two RFID cards, which look blank but actually have a tag embedded in them that stores a unique ID number.
When an RFID card is brought within about 2 inches of the reader, it will be automatically identified. The RFID reader has a buzzer that beeps and a small green LED that lights up to verify that the card has been identified.
The RFID reader will send the card ID data to the Photon board over a serial data connection using the Photon RX pin.
NOTE: For serial data connections, the RX pin of one device connects to the TX pin of the other device. (RX = receive, TX = transmit)
FYI: The RFID reader also has a Mini-USB port, which can be used to connect it directly to a computer (instead of wiring it to a Photon or other microcontroller device). However, you will not use this port. (Also this Mini-USB port is different from the Micro-USB cable included with your Photon kit.)
The RFID reader does not require any special code library. (It does use a serial data connection, but serial data functions are built-in to the Particle firmware on your Photon device.)
Each RFID card has a code consisting of 16 characters (combination of numbers and letters): 12-character unique ID code + 4 special characters (that are not unique). When we read the RFID card, we only want to keep the unique ID code.
In the global variables, you should declare an array variable of 13 characters, which will be used to store the unique ID code from the RFID card. (The array will include 1 extra character at the end, which will always be zero. This is needed for converting the character array to a String.) The example below declares an array variable called "RFID" (but you could use a different variable name).
You will probably want to also declare a String variable that will simply be a text version of the RFID (the array is separate pieces of data, while the String is the same data stored as one piece). This String variable will be easier to use for purposes such as comparing the ID to a set of known IDs, sending the ID to your web app, etc. The example below declares a String variable called "idCard" (but you could use a different variable name).
You need to include a statement within the setup()
function to start a serial data connection (which will activate both the RX and TX pins on the Photon). This will allow the Photon to receive data from the RFID reader. The RFID reader communicates at a baud rate of 9600 bps.
Code for reading an RFID card should probably be placed within its own custom function, which can then be called within the loop()
function.
Inside the readRFID()
function, you will have to insert additional code to do something with the ID after it has been read (such as compare the ID to a set of known IDs, send the ID to your web app as an event notification, etc.).
A is a sensor that measures the amount of light in the environment.
Some outdoor lights have photocells that are used to automatically turn the light on or off depending on whether it is dark or light outside.
Most smartphones and tablets have photocells that automatically change the brightness of their screens depending on the amount of ambient light detected.
The photocell has 2 metal legs. Line up the legs different numbered rows on the breadboard, and gently insert the photocell into the breadboard. (If you push too hard, you'll bend the legs. If that happens, just remove the photocell, carefully straighten the legs, and try again.) Then use 2 jumper wires and a resistor to connect the rows to the Photon.
NOTE: One of the photocell legs will have two connections: it should connect to an analog I/O pin through a jumper wire, and it should also connect to ground (GND) through a resistor. In the breadboard row, the jumper wire for the analog I/O pin should be placed between the photocell leg and the resistor leg. Look at the example wiring diagram below as a visual reference.
IMPORTANT: The photocell must connect to an analog I/O pin, such as: A0, A1, A2, A3, A4, A5.
The photocell does not require any special code library.
In the global variables, you should declare which pin is being used as the photocell analog input pin. The example below declares a variable called "lightPin" (but you could use a different variable name).
You will probably also want to declare an integer variable to store the reading from the photocell. This will make it easier to do something based on the measurement. The example below declares a variable called "lightReading" (but you could use a different variable name).
There isn't any code that you need to include in the setup()
function for the photocell.
IMPORTANT: Do not set a pin mode for the photocell.
You can measure the amount of light using an analogRead()
statement. This code would be most likely placed within the loop()
function or within a custom function.
The measurement will be a value ranging from 0-4095.
When there is less light detected, the reading will be lower. When there is more light detected, the reading will be higher.
You will need to add code to do something with the light reading (such as: display it on the OLED screen, send the data to your web app, turn on a LED light if the reading is less than a certain value, etc.).
RECOMMENDATION: Depending on the specific purpose of the photocell in your device, you may need to gather some data under different conditions to see how dark or how bright the environment will actually be where your device will be used. This will help you decide which values to use in your code to make decisions about what the device should do.
NOTE: Keypad wires 3, 5, 6, and 7 each have two connections. They each connect to an I/O pin, and they each connect to 5V (V-USB) through a 10K resistor. Look at the example wiring diagram for the as a visual reference, since it has similar wiring (except the resistor for the keypad will connect to 5V instead of GND).
RECOMMENDED: Connect the to provide audio feedback whenever any key is pressed. Within the if (key)
statement, play a brief tone if a key is pressed.
RECOMMENDED: Connect the to provide audio feedback whenever any key is pressed. Within the checkCode()
function, play a brief tone if any key is pressed.
The has a built-in 3-wire female JST connector. If necessary, attach a , and plug it into different numbered rows on a breadboard. Then use jumper wires to connect the rows to the Photon. To make it easier to remember which wire is which, use corresponding red, black, and white jumper wires to match the GPS receiver wires.
Your Photon app must include a code library with special functions that will allow you to use the GPS receiver. There are several possible libraries, but you're going to use one called :
TIP: You can use the Google Maps JavaScript API to display a map in your web app using latitude and longitude data. W3Schools has a .
measures position as an angle (0°-90°) north or south relative to the Equator, which is 0° latitude. The North Pole is 90° N latitude, and the South Pole is 90° S latitude. The GPS receiver will report latitudes north of the Equator as positive numbers, while positions south of the Equator are reported as negative numbers.
measures position as angle (0°-180°) east or west relative to the Prime Meridian (which was designated as running north-south through Greenwich, England). The GPS receiver will report latitudes east of the Prime Meridian as positive numbers, while positions west of the Prime Meridan are reported as negative numbers.
TIP: If you want to know the latitude and longitude of a location (so you can compare it to the readings from your GPS receiver), you can enter a specific address at to obtain the precise latitude and longitude of that address.
The library offers the ability to read the elevation (altitude) in feet, miles, meters, or kilometers.
The library offers the ability to read the speed in miles per hour, meters per second, kilometers per hour, or knots (nautical miles per hour).
The distance between two GPS locations can be calculated using a (used for calculating distance between two points on a sphere).
TIP: For your other location, you can enter a specific address at to obtain its precise latitude and longitude.
NOTE: The Particle firmware on your Photon device already has built-in functions to set the local time zone of your device and get the . It may be somewhat simpler to use those functions rather than converting the GPS data from UTC into local time.
NOTE: One of the FSR pins will have two connections: it should connect to an analog I/O pin through a jumper wire, and it should also connect to ground (GND) through a resistor. In the breadboard row, the jumper wire for the analog I/O pin should be placed between the FSR pin and the resistor leg. Look at the example wiring diagram for the as a visual reference, since it has identical wiring.
IMPORTANT: The code example below uses the . You will need to wire the OLED screen to your Photon, and include other necessary code (library, global variables, etc.) for the OLED display.
The RFID reader board has 8 different pin holes, but only 3 of these have to be connected. The easiest way to connect the RFID reader is to use a . Connect the 3 wires (black, red, blue) to the corresponding pin holes, and then plug the male JST connector into different numbered rows on a breadboard. Then use jumper wires to connect the rows to the Photon. To make it easier to remember which wire is which, use corresponding black, red, and blue jumper wires to match the JST wires.
of the online SparkFun Photon Experiment Guide shows how to connect the photocell. Here is the connection diagram for Experiment 6 (ignore the wiring for the RHT03 humidity and temperature sensor):
Speaker
Photon Pin
Positive (+) pin
any I/O pin with PWM
Negative (-) pin
GND
LED Light
Photon Pin
Positive leg (long) = Power
any I/O pin
Negative leg (short) = Ground
GND using resistor
Servo Motor
Photon Pin
White - Data
any I/O pin with PWM
Red - Power (5V)
V-USB (5V)
Black - Ground
GND
RHT03 Pin
Photon Pin
Pin 1 - Power
3.3V or V-USB (5V)
Pin 2 - Data
any I/O pin
Pin 3 - Unused
(none)
Pin 4 - Ground
GND
Push Button
Photon Pin
Leg (any leg)
any I/O pin
Other Leg (on same side)
GND
OLED Pin
Photon Pin
Pin 1 - CS
A2
Pin 2 - RST
D6
Pin 3 - D/C
D5
Pin 4 - SDO
(none)
Pin 5 - SCK
A3
Pin 6 - SDI
A5
Pin 7 - 3V3
3.3V
Pin 8 - GND
GND
Font Type
Font Size
Font Description
0
5x7 pixels, 10 columns by 6 rows
255 different characters
1
8x16 pixels, 6 columns by 3 rows
any character on keyboard
2
10x16 pixels, 5 columns by 3 rows
only numbers and period
3
12x48 pixels, 5 columns by 1 row
only numbers and colon
Potentiometer
Photon Pin
Outer leg (either one)
3.3V
Middle leg
any analog I/O pin
Outer leg (other one)
GND
Magnetic Switch | Photon Pin |
Wire 1 (either one) | any I/O pin |
Wire 2 | GND |
Camera | Photon Pin |
Red - RX | TX |
Brown - TX | RX |
Purple - GND | GND |
Gray - Power (3.3V or 5V) | 3.3V |
Keypad | Photon Pin |
Wire 1 | D5 |
Wire 2 | D3 |
Wire 3 | D6, plus V-USB (5V) using 10K resistor |
Wire 4 | D0 |
Wire 5 | D4, plus V-USB (5V) using 10K resistor |
Wire 6 | D1, plus V-USB (5V) using 10K resistor |
Wire 7 | D2, plus V-USB (5V) using 10K resistor |
GPS Receiver | Photon Pin |
VCC (Red) - Power | 3.3V |
GND (Black) - Ground | GND |
TX (White) - Data | RX |
RFID Reader | Photon Pin |
VCC - Power (Black) | 3.3V |
TX - Data (Red) | RX |
GND - Ground (Blue) | GND |
Photocell | Photon Pin |
First leg (either one) | 3.3V |
Second leg | (1) any analog I/O pin, (2) GND using resistor |
Actuator
Actuators are outputs that produce an action in the physical environment by transforming energy into motion. Examples of actuators include: servo motor, vibration motor, etc.
Input
Inputs gather or receive data. Sensors are inputs that gather data from the physical environment. Examples of inputs include: button, thermometer, motion sensor, light sensor, microphone, accelerometer, etc.
Output
Outputs send data or do something in the physical environment. Examples of outputs include: lights, display screen, speaker, motor, etc.
Sensor
Sensors are inputs that gather data from the physical environment by detecting an event (is a button being pressed, is motion occurring, etc.) or by measuring a property (what is the temperature, how much light is present, etc.).
Transducer
Transducers are mechanisms that transform one form of energy into another form. Physical outputs (such as lights, speakers, motors, etc.) are examples of transducers because they transform electrical energy into another form (such as light, sound, motion, etc.). Similarly, physical inputs (such as light sensor, microphone, etc.) are also examples of transducers because they transform other forms of energy (such as light, sound, etc.) into an electrical signal.
Motion Sensor
Photon Pin
Black - Data
any I/O pin
White - Ground
GND
Red - Power (5V)
V-USB (5V)
Accelerometer Pin | Photon Pin |
3.3V | 3.3V |
SDA | SDA/D0 |
SCL | SCL/D1 |
I2 | (none) |
I1 | (none) |
GND | GND |
Microphone | Photon Pin |
AUD - Data | any analog I/O pin |
GND - Ground | GND |
VCC - Power | 3.3V |
Moisture Sensor | Photon Pin |
VCC (Red) - Power | any I/O pin |
GND (Black) - Ground | GND |
SIG (Yellow) - Data | any analog I/O pin |
Force Sensitive Resistor | Photon Pin |
One FSR pin (either one) | 3.3V |
Other FSR pin | (1) any analog I/O pin, (2) GND using resistor |
Fingerprint Scanner | Photon Pin |
Wire 1 (Black) = TX | RX |
Wire 2 (White) = RX | TX |
Wire 3 (White) = GND | GND |
Wire 4 (White) = VCC | V-USB (5V) |
A continuous rotation servo motor can rotate continuously, like a wheel. This type of servo motor can be made to rotate in either direction (clockwise or counterclockwise).
However, if your device needs to rotate to a precise angle and hold that position, then you need a regular servo motor, such as the one included in your Photon kit.
The continuous rotation servo motor comes with several different plastic mounts (called "horns") that can be attached to the motor axis (the white part sticking out of the top of the motor – this is what actually rotates). There are double-arm horns (2 sizes), a four-point horn, a six-point horn, and circular horns (2 sizes). Each horn just slips onto the motor axis (the horn and axis have matching "teeth"). Each horn has holes, which can allow you to attach something to the arm, using the included mounting hardware (screws, etc.).
This servo motor has a built-in 3-wire connector: just plug 3 jumper wires into the connector and then plug the other end of the jumper wires into a breadboard or directly to the Photon. To make it easier to remember which wire is which, use corresponding white, red, and black jumper wires to match the servo motor wires.
NOTE: This servo motor requires 5V of power, so connect it (directly or indirectly) to the V-USB pin.
IMPORTANT: The data wire must connect to an I/O pin that supports pulse-width modulation (PWM) output. Only the following pins on the Photon can act as PWM outputs: D0, D1, D2, D3, A4, A5, WKP, RX, TX.
TIP: Be sure to attach one of the horns to your servo motor. Otherwise, you won't be able to see the servo motor rotate (and it won't provide much use to your device).
Experiment 7 of the online SparkFun Photon Experiment Guide shows how to connect a servo motor. Here is the connection diagram for Experiment 7 (ignore the wiring for the push button):
The servo motor does need a code library with special functions that will allow you to control the servo motor. However, this library is already built-in to the Particle firmware on your Photon device.
In the global variables, you should declare which pin is being used as the servo motor data pin. The example below declares a variable called "servoPin" (but you could use a different variable name).
You also need to declare a Servo object variable that you will use to run the special functions in the built-in Servo library. The example below declares a variable called "servo" (but you could use a different variable name).
OPTIONAL: You may also want to declare a global variable to represent the direction of the servo motor rotation (counter-clockwise, stopped, or clockwise). This isn't required, but it could make it easier to code the servo motor, especially if the direction or speed of rotation will be changed by the user or are necessary to track. The example below declares a variable called "direction" (but you could use a different variable name).
There isn't any code that you need to include in the setup()
function. You don't have to set a pin mode for the servo.
However, if you want your servo motor to be turned on when your device first starts, then add the necessary code to do this within the setup()
function.
You have to call a special function called servo.attach()
to turn on the motor. For a continuous rotation servo motor, this typically only has to be done once, so this statement could be included within the setup()
function (which only runs once).
NOTE: You can stop the motor from rotating, while still keeping the motor turned on (so it's ready to rotate again when you need it to).
However, if you need to completely turn off the motor, then call the servo.detach()
function. This would be useful if the motor only needs to rotate for a specified period of time (to complete an action) and then might spend a long time unused.
If the servo motor is completely turned off (detached), then you will need to include a servo.attach()
statement before your code can rotate the motor again.
You can make the servo motor rotate clockwise, counter-clockwise, or stop.
Code for controlling the servo motor rotation can be placed within the setup()
function (only runs once), within the loop()
function, or within a custom function.
There are two different methods for controlling the rotation of a continuous rotation servo motor. Both work by changing the timing of the electrical pulses sent to the servo motor. You can use either method, but you should probably just use one, in order to keep your code simpler and avoid any issues.
servo.writeMicroseconds()
A continuous rotation servo motor can be controlled by calling the servo.writeMicroseconds()
function, which typically accepts values from 1000-2000. A value of 1000 should rotate the motor counter-clockwise at full speed. A value of 2000 should rotate the motor clockwise at full speed. A value of 1500 should cause the motor to stop rotating (and without any vibration). Intermediate values can be used to change the speed of the rotation.
If necessary, you can fine-tune the values listed above based on testing with your actual servo motor. You could go as low as 700 or as high as 2300.
CAUTION: If you adjust the endpoint values too far (too low or too high), you might damage the motor.
servo.write()
A continuous rotation servo motor can also be controlled by calling the servo.write()
function, which accepts a value from 0-180. A value of 0 should rotate the motor counter-clockwise at full speed. A value of 180 should rotate the motor clockwise at full speed. A value of 90 should cause the motor to stop rotating (and without any vibration). Intermediate values can be used to change the speed of the rotation.
If you need your device to only rotate for a specific period of time, then simply use a delay()
statement to wait for a specific amount of time in milliseconds (1000 milliseconds = 1 second) before stopping the motor.
You can declare constants (as part of your global variables) to represent the possible directions of the servo motor rotation. This isn't required, but in some cases, it might make it easier to write (and read) your code.
The example below declares 3 constants that can be used to control the direction of the servo rotation if you are using the servo.writeMicroseconds()
function. (If necessary, you can change the names or values of these constants based on what you need your device to do.)
If you were to declare these constant values as part of your global variables, then your commands to control your motor would be:
You could even create global variable constants for that represent different speeds of rotation (CLOCKWISE_SLOW
, CLOCKWISE_FAST
, etc.).
If you are using the servo.write()
function instead, you would change the values of the constants (so the values are between 0-180).
You may need to adjust the stop point for your continuous rotation servo motor. Normally, using servo.write(90);
or servo.writeMicroseconds(1500);
should cause the motor to stop rotating (and not vibrate). However, it's possible your servo motor still might be slowly rotating or vibrating at these values.
If necessary, you can adjust the stop point by:
manually turning an adjustment screw on the motor
adjusting values in your code
Either way, you first need a simple app that turns on your servo motor using servo.attach()
and instructs the motor to not rotate using either a servo.write(90);
or servo.writeMicroseconds(1500);
statement.
The continuous rotation servo motor has a built-in trimpot screw inset on one side (next to its wires). You can use a small screwdriver to turn this screw slightly clockwise or counterclockwise until your motor stops rotating (and does not vibrate) when it is running a servo.write(90);
or servo.writeMicroseconds(1500);
statement.
Another option is to try slightly different values in your code to see which value causes the servo motor to actually stop rotating.
If you are using the servo.write()
function to control your motor, you can set a trim value, so that your motor will actually be stopped whenever you use a servo.write(90)
statement. The trim value can be positive or negative – try different values to see what works.
If you are using the servo.writeMicroseconds()
function to control your motor, then you can change the value from 1500 to something slightly higher or lower until your motor completely stops.
Servo Motor
Photon Pin
White - Data
any I/O pin with PWM
Red - Power (5V)
V-USB (5V)
Black - Ground
GND