В моем предыдущем блоге я показал вам, как разместить модуль wasm в программе на Rust, используя wasmi. Вы можете проверить этот блог для справки. В этом блоге я буду использовать wasmi для создания программы на ржавчине, которая будет действовать как хост wasm на Raspberry Pi. Мы скомпилируем программу rust в armv7, поскольку устройства Raspberry Pi 2+ являются устройствами arm v7. Затем мы разместим модуль WebAssembly на Raspberry Pi.
Прежде всего, мы напишем программу на Rust, которую будем размещать, а затем скомпилируем ее в wasm. Мы собираемся создать индикатор заряда батареи. Его работа довольно проста. Один из входных сигналов датчика отображает количество
оставшегося заряда батареи в процентах. В соответствии с этим процентом мы будем управлять цветом группы из восьми светодиодов. Давайте начнем.
Индикатор батареи
Светодиоды могут загораться цветами в виде комбинации компонентов RGB в диапазоне от 0 до 255. Фактическое аппаратное обеспечение, которое используется Blinkt! Пиморони. Вы можете купить это онлайн, если хотите реализовать это.
На Blinkt! есть 8 светодиодов. Таким образом, основная логика состоит в том, чтобы разделить максимальный процент заряда батареи на 8, т. е. 100 на 8 (100/8 = 12,5), чтобы получить процент на каждый светодиод. Мы можем назвать это значение процент_на_пиксель. Затем мы можем использовать это значение для включения светодиодов на основе числа, которое мы получаем после деления текущего процента заряда батареи на процент_на_пиксель. Если значение после деления представляет собой число с плавающей запятой, мы берем максимальное значение.
Например, если процент заряда батареи равен 80, то количество загорающихся светодиодов будет равно 7, так как 80 / 12,5 = 6,4, поэтому мы берем максимальное значение.
Итак, давайте посмотрим на код, а затем обсудим его дальше.
#[derive(PartialEq, Debug, Clone)]
struct LedColor(i32, i32, i32);
const SENSOR_BATTERY: i32 = 20;
const OFF:LedColor = LedColor(0, 0, 0);
const YELLOW: LedColor = LedColor(255, 255, 0);
const GREEN: LedColor = LedColor(0, 255, 0);
const RED: LedColor = LedColor(255, 0, 0);
const PCT_PER_PIXEL: f64 = 12.5_f64;
extern "C" {
fn set_led(led_index: i32, r: i32, g: i32, b: i32);
}
#[no_mangle]
pub extern "C" fn sensor_update(sensor_id: i32, sensor_value: f64) -> f64 {
if sensor_id == SENSOR_BATTERY {
set_leds(get_led_values(sensor_value));
}
sensor_value
}
#[no_mangle]
pub extern "C" fn apply(_frame: u32) {
// NO OP, not an animated indicator
}
fn get_led_values(battery_remaining: f64) -> [LedColor; 8] {
let mut arr: [LedColor; 8] = [OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,];
let lit = (battery_remaining / PCT_PER_PIXEL).ceil();
// 0 - 20 : Red
// 21 - 50 : Yellow
// 51 - 100 : Green
let color = if 0.0 <= battery_remaining &&
battery_remaining <= 20.0 {
RED
} else if battery_remaining > 20.0 && battery_remaining < 50.0 {
YELLOW
} else {
GREEN
};
for index in 0..lit as usize {
arr[index] = color.clone();
}
arr
}
fn set_leds(values: [LedColor; 8]) { // (5)
for index in 0..8 {
let LedColor(r, g, b) = values[index];
unsafe {
set_led(index as i32, r,g,b);
}
}
}
Программа определяет кортеж structLedColor для значения RGB каждого светодиода. SENSOR_BATTERY – это идентификатор датчика, определяющий уровень заряда батареи в процентах. Затем мы определяем значение RGB для каждого цвета, который будем использовать для представления процента заряда батареи.
Эта программа экспортирует две функции: sensor_update и apply, а также импортирует функцию set_led с хоста. Давайте посмотрим, что делают эти функции.
функция sensor_update
Функция sensor_update принимает два значения: sensor_id и sensor_value. sensor_id – это идентификатор датчика, отправляющего процент заряда батареи, а sensor_value – фактический процент заряда батареи.
Функция проверяет, поступает ли вход от датчика батареи или нет. Затем он вызывает функцию set_leds, которая устанавливает светодиоды на Blinkt! как ON или OFF, а также устанавливает цвет светодиодов. Функция apply() не определена, поскольку она используется для создания анимации.
функция set_leds
Функция set_leds принимает в качестве аргументов массив объектов LedColor. LedColor — это кортежная структура, определяющая значения RGB для цветов светодиодов. Он устанавливает желаемые светодиоды с соответствующими цветами на хосте. Он делает небезопасный вызов импортированной функции set_let для установки светодиодов. Небезопасный означает, что Rust не гарантирует безопасность типов этой функции, так как это импортированная функция.
функция get_led_values
Эта функция принимает процент заряда батареи в качестве аргумента, который передается функции sensor_update. Затем эта функция рассчитывает количество светодиодов, которые должны загореться, тем же методом, который мы обсуждали выше, т. Е. Разделив процент заряда батареи на 12,5, а затем беря максимальное значение. Затем он использует это значение для заполнения массива типа LedColor цветом в соответствии с текущим процентом заряда батареи. Мы используем красный цвет для процентов заряда батареи в диапазоне от 0 до 20, желтый цвет для процентов заряда батареи в диапазоне от 21 до 50 и зеленый цвет для процентов заряда батареи в диапазоне от 51 до 100.
После этого вызывается функция set_leds и передается массив LedColor для включения светодиодов.
Теперь мы готовы разместить эту программу на нашем Raspberry Pi, но перед этим нам нужно создать хост-программу, которая будет работать на нашем Raspberry Pi и постоянно следить за Васм модуль. Мы увидим, как создать хост на Raspberry pi в нашем следующем блоге. Так что следите за обновлениями.
Перед этим убедитесь, что вы скомпилировали эту программу в wasm, чтобы мы могли использовать ее и запустить индикатор батареи на Raspberry pi.
Если вы хотите прочитать больше подобного контента? Подпишитесь на информационный бюллетень Rust Times и получайте идеи и последние обновления раз в две недели прямо на свой почтовый ящик. Подпишитесь на новостную рассылку Rust Times: https://bit.ly/2Vdlld7.