Guiding Light
Initialize a new project and start to interact with some hardware!
Project creation
The init
command will create a new directory with the name provided and scaffold the starting files based on a template or example:
The above command should result in the following output:
The guiding-light
directory should contain main.js
and package.json
files. main.js
contains that was run from the Hello Console example:
The first line is a debugger statement for setting a breakpoint in xsbug.
The third and fourth lines save a string to a variable and log it to the xsbug console using the global console.log
function.
The initialized package.json
in the guiding-light
project should look like this:
The main
field points to the generated main.js
as the entrypoint for the program.
Executing the start
script using the package manager of your choice, i.e. npm start
, or xs-dev run
will provide the same experience as the Hello Console guide.
Quick tip: check out all the available simulators by using the --list-devices
flag with the run
command and typing “simulator” to filter the list.
Down to the metal
At this point, we have our chosen hardware in hand and need to set up the dev environment to start running code on the device.
Just like the previous step, the setup
command will automate the installation and building of tooling required for the target device. The --list-devices
flag will provide an interactive list of supported device platforms:
You may see different options depending on what operating system or version of xs-dev you are using.
Once this process is done, you should see a success message (where <device>
is the selected target device):
Running our project on the selected device (which should be connected to the computer somehow, presumable over USB) is the same command as before with the additional --device
flag to pass in the target device platform:
This will take some time to compile and send the code over to the device. When it has succeeded, the debugger will open like before but now it is tracing the logs coming from the hardware!
👏 Give yourself a round of applause! You have now run JavaScript on an embedded device! 🎉
Hello blinky
Now that we know we can run code on our device, it is time to shed a little light on hardware control. We will use the ECMA-419 standard APIs to perform this task.
With that default package.json
the ECMA-419 APIs are included in the compiled program, so the main.js
file can be updated with the following code:
Using the global device
variable provided by the io
module, we can access the Digital
IO class for controlling the digital output to an LED. In this example, the Digital
class is instantiated with the pin
property set to the built-in led as defined on the global device
and the mode
set to the Digital.Output
static property found on the class. With that Digital instance variable called led
, the write
method is called with a value of 1
to send power to the LED.
To make the light blink, the next value to be written is stored as the state
variable. The global System
class provides the well-known setInterval
function that is found in other JavaScript runtimes like the Web and Node.js. Every 200 milliseconds, the state
is written to the LED before being updated to the opposite value.
The project can be run using the same command as before: xs-dev run --device <device>
. If it succeeds, you should see a blinking LED somewhere on your device! ✨
Keep exploring!
Tried adding some console.log
calls to log the state to the debugger or updating the timer code to send a message in Morse code.
Coming soon: react to digital input by pressing some buttons
In the meantime, check out the many examples available in the Moddable SDK.
Troubleshooting
If you’re working with a device that doesn’t have an on-board LED or encounter an error while trying to use the device.pin.led
value, the pin specifier can be set to a custom value based on the device datasheet or pinout diagram, like this one for the Pico. The pin value can match the on-board LED or an external LED connected to a GPIO, most likely by using a breadboard.