DEV Community

Cover image for DeviceScript and OLED screens
Peli de Halleux
Peli de Halleux

Posted on • Originally published at microsoft.github.io

DeviceScript and OLED screens

This article shows how to use DeviceScript to program a microcontroller (ESP32-C3), a temperature/humidity sensor (BME680) and a OLED screen to build a tiny weather dashboard. This project does not require soldering or embedded skills.

Image description

DeviceScript

DeviceScript brings JavaScript/TypeScript to tiny IoT devices such as the ESP32. DeviceScript provides a user friendly editing/debugging experience in Visual Studio Code.

You can follow along this tutorial without any hardware and use the simulators provided by DeviceScript. Otherwise, the parts needed are

Seeed Studio Xiao + Expansion board

The Xiao ESP32-C3 is a low-cost compact microcontroller board running the Espressif ESP32-C3.

The Xiao Expansion board base is a convinient base for the Xiao that provides an easy access to OLED screens, Grove connectors and battery charging.

DeviceScript provides a shield drivers that configures the pins and the OLED display for this hardware combo.

import { XiaoExpansionBoard } from "@devicescript/drivers"

const board = new XiaoExpansionBoard()
const display = await board.startDisplay()
Enter fullscreen mode Exit fullscreen mode

OLED screen as character screen

The OLED screen on the expansion board is monochrome and has a 128x64 pixels resolution. The display is crisp and perfect to display sensor information.

To simplify working with the screen, we model it as a character screen. Using services allows DeviceScript to provide simulation and device twin capabilities to your coding experience.

 

import {
    ...,
    startCharacterScreen,
} from "@devicescript/drivers"

...
const screen = await startCharacterScreen(display)
// update text on character screen
await screen.message.write(":)")
Enter fullscreen mode Exit fullscreen mode

BME680

The BME680 is a high-precision temperature/humidity/gas sensor that can be conveniently connected through one of the grove connector.

The sensor is exposed as 3 services, temperature, humidity, air quality, that can be used to poll the sensor data and display it on the screen.

import {
    startBME680,
} from "@devicescript/drivers"

...
const { temperature, humidity } = await startBME680({
    address: 0x76
})
const temp = await temperature.reading.read()
const humi = await humidity.reading.read()
await screen.message.write(`t ${temp}\nh ${humi}`)
Enter fullscreen mode Exit fullscreen mode

Value dashboard

Since display sensor values is a common task, DeviceScript provides a helper ValueDashboard to render a list of sensor data.

The value dashboard

import { ValueDashboard } from "@devicescript/runtime"

...
const dashboard = new ValueDashboard(screen, {
    temperature: { digits: 1, unit: "C" },
    humi: { digits: 0, unit: "%" },
})

setInterval(async () => {
    dashboard.values.temperature = temperature.reading.read()
    dashboard.values.humi = humidity.reading.read()
    await dashboard.show()
}, 1000)
Enter fullscreen mode Exit fullscreen mode

All together

The final sample is a tiny weather display that shows the temperature/humidity reported by the BME680 sensor.

import {
    XiaoExpansionBoard,
    startCharacterScreen,
    startBME680,
} from "@devicescript/drivers"
import { ValueDashboard } from "@devicescript/runtime"

const board = new XiaoExpansionBoard()
const { temperature, humidity } = await startBME680({
    address: 0x76
})
const display = await board.startDisplay()
const screen = await startCharacterScreen(display)

const dashboard = new ValueDashboard(screen, {
    temperature: { digits: 1, unit: "C" },
    humi: { digits: 0, unit: "%" },
})

setInterval(async () => {
    dashboard.values.temperature = await temperature.reading.read()
    dashboard.values.humi = await humidity.reading.read()
    await dashboard.show()
}, 1000)
Enter fullscreen mode Exit fullscreen mode

Top comments (0)