Wiring Programming Language

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).

PARTICLE BUILD (Code Editor)

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.

PROGRAMMING REFERENCES

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.

APP STRUCTURE

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:

  1. libraries (if needed for certain inputs or outputs)

  2. global variables

  3. setup() function (required - can only have one)

  4. loop() function (required - can only have one)

  5. 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.

// comments are notes to yourself or others reading your code
// comments are ignored by the device when the app runs
// comments can be added as their own separate line in your code

int led = D0; // comments can also added directly after a line of code

/*
This is a multi-line comment. It starts with a forward slash and asterisk.
It's useful when you have a lot of information to list or explain.
It is also useful to temporarily comment out a large section of code.
The multi-line comment ends with an asterisk and forward slash.
*/

LIBRARIES

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.

// This #include statement was automatically added by the Particle IDE.
#include <SparkFunMicroOLED.h>

GLOBAL VARIABLES

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.

// some examples of data types for variables
// there are other data types as well...
int led = D7;
int timeLimit = 10;
int roomTemperature; // variable declared but no value assigned yet
float bodyTemp = 98.6;
boolean motionStatus = false;
String deviceName = "Photon";

timeLimit = 20; // assign new value to this variable
timeLimit = timeLimit + 10; // change value again - now it equals 30
int timeLeft = timeLimit; // assign value of timeLimit to new variable

Local Variables

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.

Local Variable vs. Global Variable

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.

// global variables because they are declared outside of a function
int led = D7;
int button = D2;

// setup() function
void setup() {
    pinMode(led, OUTPUT); // uses global variable "led"
    pinMode(button, INPUT_PULLUP); // uses global variable "button"

    // blink led 5 times at start
    for (int count = 0; count < 5; count = count + 1) { // "count" is local variable because it is declared inside this statement
        digitalWrite(led, HIGH); // uses global variable "led"
        delay(200);
        digitalWrite(led, LOW); // uses global variable "led"
    }
}

// loop() function
void loop() {
    int buttonState; // local variable because it is declared inside this function
    buttonState = digitalRead(button); // uses global variable "button" for digitalRead() and assigns value to local variable "buttonState"

    // LOW means button is being pushed
    if (buttonState == LOW) { // compares value of local variable "buttonState" to see if it is equivalent to LOW
        digitalWrite(led, HIGH); // uses global variable "led"
    }
}

SETUP( ) FUNCTION

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.

// example of setup function
void setup() {
    pinMode(button, INPUT_PULLUP);
    pinMode(led, OUTPUT);
}

LOOP( ) FUNCTION

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.

// example of loop function
void loop() {
    // read button and assign value to local variable buttonStatus
    int buttonStatus = digitalRead(button);

    // LOW means button is pressed
    if(buttonStatus == LOW) {
        digitalWrite(led, HIGH);
    } else {
        digitalWrite(led, LOW);
    }
}

CUSTOM FUNCTIONS

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.

void loop() {
    // call custom function
    checkButton();
}

// custom function
void checkButton() {
    // read button and assign value to local variable "buttonStatus"
    int buttonStatus = digitalRead(button);

    // LOW means button is pressed
    if(buttonStatus == LOW) {
        digitalWrite(led, HIGH);
    } else {
        digitalWrite(led, LOW);
    }
}

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.

void loop() {
    // call custom function and pass values into it
    // assign return value to local variable "surfaceArea"
    int surfaceArea = calculateArea(7,8);

    if(surfaceArea > 50) {
        digitalWrite(led, HIGH);
    } else { 
        digitalWrite(led, LOW);
    }
}

// custom function that receives parameters and returns a value
int calculateArea(int width, int length) {
    int area = width * length;
    return area;
}

PUTTING IT ALTOGETHER

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?

// example of app coded in Wiring programming language

// global variables
int button = D2;
int greenLed = D1;
int redLed = D0;

void setup() {
    pinMode(button, INPUT_PULLUP);
    pinMode(greenLed, OUTPUT);
    pinMode(redLed, OUTPUT);
}

void loop() {
    checkButton();
}

// custom function
void checkButton() {
    int buttonStatus = digitalRead(button);

    // LOW means button is pressed
    if(buttonStatus == LOW) {
        digitalWrite(greenLed, HIGH);
        digitalWrite(redLed, LOW);
    } else {
        digitalWrite(greenled, LOW);
        digitalWrite(redLed, HIGH);
    }
}

Last updated