During this workshop, you will start from a p5.js starter template. and hook it up to receive IMU data.
Goals:
- See an example of using code from a JavaScript library.
- Gain more familiarity with functions and variables.
- Use
console.log
to inspect data. - Learn to write code that uses data from our sensor data pipeline.
- Get started on the physical computing aspect of your project.
A. Create a new p5.js project
In this section, you will create a project folder on your disk that includes the index.html and sketch.js files that you need in order to a run a p5 sketch. (These are similar steps to the ones you used in the workshop Setting up an IMU, except that you've already set up Visual Studio code.)
- Open a new terminal window. (Or, use
cd
to change an existing terminal window to the directory in which you want to create the new project folder; for example, justcd
to move the terminal to your home direcgtory.) - In the terminal
git clone https://github.com/osteele/p5-module-template.git imu-workshop
. This creates a local folder namedimu-workshop
, that has the files for a minimal p5.js sketch. - In Visual Studio Code, open the
imu-workshop
folder. - In Visual Studio Code, click the "Go Live" button.
5. Modify sketch.js
so that something appears on the screen.
B. Subscribe to sensor data
We will use the imu-tools npm package to subscribe to IMU data that is coming from the network. This involves adding the imu-tools npm package to our project, so that we can write code that calls functions in this library; and specifying the connection address of a network server.
1. Follow the instructions on the imu-tools project page to add the package to your project.
Note: You will need to add lines to both index.html
and sketch.js
Note: Complete the instructions in both the Usage section and the Connection Settings Control Panel. of the imu-tools project page.
2. Enter the MQTT connection settings from this page.
3. Verify that data is being printed to the JavaScript Console. (In Chrome: View > Developer > JavaScript Console).
C. Examine the data
Each time a new sample comes from the device, it is printed to the JavaScript console. This is useful because it demonstrates we are receiving a sequence of samples, but it makes it difficult to use the console to inspect any single one of these samples.
We will fix this in these steps.
Note: Rather than giving you code to copy and paste into your sketch, these steps describe the intent and suggest some steps, and leave it to you to construct the exact JavaScript. This is to help you practice some skills in writing code, so that you can apply this to other parts of your project.
-
data => console.log('sample', data)
is an anonymous function—it doesn't have a name. We will replace this by a new named function that does the same thing. Let's name the new functionhandleSensorData
. (As with a variable, the actual name doesn't matter, so long as we use the same name when we define the function and when we use it.) Usefunction
to define a function with parameterdata
, that callsconsole.log
in the function body. - Introduce a global variable (a variable that is defined outside of any
function
), that keeps track of whether this is the first time thathandleSensorData
has been run. - Pick a name for the variable, and use a
let
statement to define the variable and initialize it tofalse
. - Modify
handleSensorData
to change the variable's value totrue
. - Finally, add an
if
statement to the function so that it only runsconsole.log
the first time it is run. - Now, the sketch should only print the sample data once. Inspect this value in the JavaScript console.
D. “Zoom into” the data
The sensor data is a JavaScript object with a a number of properties. Many of these properties are arrays. We'll use this fact to review how to read a single property value from an object, and a single value from an array of values.
- Modify the call to
console.log
to print just the orientation data. (The orientation data is in the property namedeuler
.) Move the IMU, and observe how this value changes. - The value of the
euler
property is an array of yaw, pitch, and roll. Modify the code in the call toconsole.log
to print just one of these.
E. Use the sensor data in the sketch
In order to make use of the IMU data in a sketch, we'll introduce another global variable. The function called by onSensorData
stores the sensor data into this value, and the sketch
function reads from it.
- Choose a variable name. Define a global variable with this name, and initialize it to
null
. (This special value represents the idea that “we don't yet have a meaningful value”.) - Modify
handleSensorData
to set this variable to the latest sample data. (You can decide whether the variable is set to the entire sample, just the orientation array, or a single value from the orientation array.) - Modify
draw
to make use of the value. The drawing should do something that depends on the value.
Suggestion: Use the p5.js rotate function to rotate a shape or image according to the value of one of the sensor readings. You will run into two challenges: (1) The sensor's Euler angles are in degrees, while the rotate
function expects angles in radians. (2) p5.js rotation is around the upper left corner, at (0, 0). In order to rotate around a different point, you will need to use the translate
function.
Note: Code that attempts to access the data may produce an error or unexpected results if it is run before the first sample arrives from the IMU. You can avoid this issue by testing whether the data is null; for example: if (…variable name… !== null) { …your code here… }
.