色んなプログラミング言語でLチカする

Qiitaに7つのプログラミング言語でLチカを Lチカセブン を投稿しました.

タイトル先行でやってしまったため 7つ という縛りがあったため, こちらには他の言語も追加していきます.

環境

Model : Raspberry Pi 3 Model B Rev 1.2p
OS : Raspbian GNU/Linux 9 (stretch)

Dockerで実行環境構築

以前、ラズパイでの開発にDockerを導入する記事を投稿しました。
Docker環境をRaspberryPi上に構築する#RaspberryPi に Docker をえいや

  • Raspbianにプリインストール & GPIO制御可能なもの
    C Python
  • Raspbianに言語 or GPIO制御するライブラリのインストールが必要なもの
    Go Node.js Ruby Rust Swift

せっかくなので後者についてはDockerで実行環境を手に入れます。
もちろんラズパイのローカルにインストールしても問題ありません。

docker run -t -i \
--name [container_id] \
--rm \
--privileged \
-v $PWD:/usr/src:rw \
-d [language_image] \
/bin/bash

Swift以外は上記だけで動作可能です。

Lチカ

1秒間隔で7回チカらせます。

wiring


C

# wiringPiライブラリをリンク
gcc -o led-blinker led-blinker.c -lwiringPi
#include <wiringPi.h>

#define GPIO2 2

int main(void)
{
wiringPiSetupGpio();

pinMode(GPIO2, OUTPUT);

for (int i = 0; i < 7; i++)
{
digitalWrite(GPIO2, HIGH);
delay(1000);
digitalWrite(GPIO2, LOW);
delay(1000);
}

return 0;
}

Go

https://github.com/stianeikeland/go-rpio

go version # 本記事では 1.12.5

go get github.com/stianeikeland/go-rpio
package main

import (
"os"
"fmt"
"time"
"github.com/stianeikeland/go-rpio"
)

var (
pin = rpio.Pin(2)
)

func main() {

err := rpio.Open()

if err != nil {
fmt.Println(err)
os.Exit(1)
}

pin.Output()

for i := 0; i < 7; i++ {
pin.High()
time.Sleep(1 * time.Second)
pin.Low()
time.Sleep(1 * time.Second)
}

rpio.Close()
}

Node.js

node --version # 本記事では 12.2.0

# https://github.com/fivdi/onoff
npm install onoff
'use strict';

const Gpio = require('onoff').Gpio;
const pin = new Gpio(2, 'out');

const sleep = (ms) => {
return new Promise(resolve => setTimeout(resolve, ms))
}

const main = async () => {
try {
for (let i = 0; i < 7; i++) {
pin.writeSync(1);
await sleep(1000);
pin.writeSync(0);
await sleep(1000);
}
} catch (err) {
console.log(err);
} finally {
pin.unexport();
}
}

main();

Python

python3 --version # 本記事では 3.5.3
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)

pin_out = 2
GPIO.setup(pin_out, GPIO.OUT)

for i in range(7):
GPIO.output(pin_out, GPIO.HIGH)
time.sleep(1)
GPIO.output(pin_out, GPIO.LOW)
time.sleep(1)

GPIO.cleanup()

Ruby

ruby --version # 本記事では2.6.3

# https://github.com/jwhitehorn/pi_piper
gem install pi_piper
require 'pi_piper'

pin = PiPiper::Pin.new(:pin => 2, :direction => :out)

7.times do
pin.on
sleep 1
pin.off
sleep 1
end

Rust

rustup -V # 本記事では 1.18.2

cargo init led_blinker

# edit Cargo.toml
# edit src/main.rs

cargo run
# Cargo.toml

[dependencies]
# https://github.com/jwhitehorn/pi_piper
rppal = "0.11.2"
// src/main.rs

use std::error::Error;
use std::thread;
use std::time::Duration;

use rppal::gpio::Gpio;

const GPIO_LED: u8 = 2;

fn main() -> Result<(), Box<dyn Error>> {

let mut pin = Gpio::new()?.get(GPIO_LED)?.into_output();

for _ in 0..7 {
pin.set_high();
thread::sleep(Duration::from_secs(1));
pin.set_low();
thread::sleep(Duration::from_secs(1));
};

Ok(())
}

Swift

Swiftは自前でimageをbuildします。
docker build -t [name] .

# Dockerfile

FROM resin/rpi-raspbian:stretch

ENV APP_ROOT /usr/src
WORKDIR $APP_ROOT
ADD . $APP_ROOT

RUN apt-get update
RUN apt-get install libxml2-dev git

# install swift4
# https://packagecloud.io/swift-arm/release/packages/raspbian/stretch/swift4_4.2.3_armhf.deb
RUN curl -s https://packagecloud.io/install/repositories/swift-arm/release/script.deb.sh | sudo bash
RUN apt-get install swift4=4.2.3

buildが完了したら他の言語と同様 docker run します。

swift --version # 本記事では 4.2.3

mkdir led-blinker && cd led-blinker
swift package init --type executable

# edit Package.swift
# edit Sources/led-blinker/main.swift

swift build
// Package.swift

import PackageDescription

let package = Package(
name: "led-blinker",
dependencies: [
// https://github.com/uraimo/SwiftyGPIO
.package(url: "https://github.com/uraimo/SwiftyGPIO.git", from: "1.0.0")
]
)
// Sources/led-blinker/main.swift 

import Glibc
import SwiftyGPIO

let gpios = SwiftyGPIO.GPIOs(for:.RaspberryPi3)
var gp = gpios[.P2]!

gp.direction = .OUT

for _ in 1...7 {
gp.value = 1
sleep(1)
gp.value = 0
sleep(1)
}

参考

ラズパイとサーバーサイドSwiftでLチカ! ( Raspberry Pi 2 + SwiftyGPIO ) by n0bisukeさん


単純に /sys/class/gpio を操作する方法もありますが、今回は各言語のライブラリを使用するようにしてみました。
RaspberryPiではPythonが選ばれることが多いと思いますが、たまには他の言語でやってみるのも楽しそうです。