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.

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)