DeviceScript - TypeScript for microcontrollers
Peli de Halleux
Posted on May 17, 2023
If you are familiar with TypeScript, but could never really catch on with embedded programming, this article is for you!
TypeScript for microcontrollers
DeviceScript brings a professional TypeScript developer experience to low-resource microcontroller-based devices, like the ESP32 or Raspberry Pi Pico.
Think of DeviceScript as a way to write TypeScript applications, not for the web or a backend or a phone but for a device that has only 64kb of RAM, runs on battery for months and can interface with tons of sensors and actuators.
How does it work
The DeviceScript language is a subset of TypeScript designed to run efficiently on tiny microcontrollers with very limited storage and memory. Because it is TypeScript, you still benefit from the great developer experience in Visual Studio; on top of additional features provided by the DeviceScript extension.
The DeviceScript compiler then turns your code into a bytecode that is executed in a virtual machine (written in C) on the microcontroller. The bytecode is designed to be compact and memory efficient.
From your point of view, it's just like you coding in TypeScript , yay!
Blinky
Every embedded journey starts with a blinking LED and DeviceScript is no different. We will use a Raspberry Pi Pico in this example and we will flip a GPIO pin between high and low.
According to the pico pinout diagram, the LED in the picture above is connected from pin 2, labelled GP1 to ground.
The full guide is available at https://microsoft.github.io/devicescript/getting-started/samples/blinky. Shorter version inlined.
New project
After installing the DeviceScript extension (there is also a cli), you can use the DeviceScript: Create New Project... option to start a new project.
The project looks very much like a npm-project with a package.json, a few helper files for IDEs and a main.ts
file.
A first (simulated) run
Open main.ts
and click the run menu item on the file to start a debugging session.
The extension will look for a connected device and, if not found, will default to a simulator (which happens to be the wasmed C runtime).
Configuring hardware
Since we know the target microcontroller, we can click on the wand icon and import the pin mapping for the pico as well as starting a lightbulb server on pin P1.
import { pins } from "@dsboard/pico"
import { startLightBulb } from "@devicescript/servers"
// start a lightbulb server on pin GP1
// and store client in `lightBulb` variable
const lightBulb = startLightBulb({
pin: pins.P1,
})
In DeviceScript, hardware is virtualized as services where sensors are servers that clients in application can interact with him... just like servers and clients in the web.
Read and write registers
To blink the LED, we call toggle
on the ligh bulb client every second. toggle
is async so we also add the await
keyboard.
import { pins } from "@dsboard/pico"
import { startLightBulb } from "@devicescript/servers"
const lightBulb = startLightBulb({
pin: pins.P1,
})
// start interval timer every 1000ms
setInterval(async () => {
// toggle brightness
await lightBulb.toggle()
}, 1000)
Run this program. Since the program uses a light bulb service, the extension will suggest you to start a light bulb simulator (server) so that the client can be bound and send commands.
Connecting the pico
So far, we've developed the code using simulators. It's time to hit the metal. Connect your Raspberry Pi Pico ( ESP32 is also supported), and flash the DeviceScript runtime firmware. Once this is done, it is ready to run the bytecode.
Click on the connect button again to connect your device and run your file... and blink the LED!
Beyond Blinky
Obviously Blinky is just the start. DeviceScript opens the door to embedded programming for developer who are already familiar with TypeScript. Stay tuned for more articles or dive into the docs.
Posted on May 17, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.