フリーランスの暇な時に書く技術メモ
Genki Tech

ラズパイ上のNode.jsでLEDチカチカする

折角Linuxが動くのでpythonではなく慣れてるnode.jsでLチカしてみます。Next.jsで軽くサーバーを立てて、Web画面からLEDの切り替えをできるようにするところをゴールとします。

VSCodeでRaspberry PiにSSH接続してる状態で以下のように環境構築します。

Nodeのインストール

Nodeの14をインストール。通常のLinuxと違うのでこの方法がいいみたい。

$ curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -
$ sudo apt install nodejs

Next.jsプロジェクトの作成

以下のコマンドで作成します。

cd ~
npx create-next-app raspberry_test --typescript
cd raspberry_test

いったんテストで動かしてみます。

npm run dev

http://raspberrypi.local:3000/ にアクセスすると初期状態のページが表示されれば動いてます。

image-20211002180618860

rpi-gpio ライブラリのインストール

ラズパイのGPIO(制御用の出力)をコントロールするためのライブラリをインストールします。

npm i -S rpi-gpio
npm i -D @types/rpi-gpio

LEDの接続

ラズパイのGPIOにLEDを接続します。今回はGPIO5に、220Ωの抵抗と直列でLEDを接続しました。面倒なので電流の計算などはしてません。適当です。

image-20211002214713416

繋いだ地点でほんのちょっとだけ光ってる気がするので、GPIOはOFFでもちょっとだけ流れてるんですかね。

APIの準備

画面にボタンを付けてボタンからAPIを呼びAPIでLED制御するので、APIを用意します。

Next.jsは「pages/api」フォルダにあるファイルがそのままAPIになる仕様なので、apiフォルダにledフォルダを作成し、その中に[id].tsを作成し、以下の様に記述します。

import type { NextApiRequest, NextApiResponse } from 'next'
import GPIO from 'rpi-gpio'

const PIN_GPIO_5 = 29;

// 初期設定
// GPIO.setMode(GPIO.MODE_RPI); default
GPIO.setup(PIN_GPIO_5, GPIO.DIR_OUT); // GPIO5

type Data = {value: string};

export default function handler(
  req: NextApiRequest,
  res: NextApiResponse<Data>
) {

  if ( req.query.id === 'on' ){
    // LED ON
    GPIO.write(PIN_GPIO_5, true);
  }else if( req.query.id === 'off' ){
    // LED OFF
    GPIO.write(PIN_GPIO_5, false);
  }
  res.status(200).json({ value: req.query.id?.toString() ?? '' });
}

今回は

ラズパイのGPIOの番号表を見るとGPIO5は29番ピンのため、そのピンに対して最初にDIR_OUTを指定して出力用にします。GPIOの番号(5)をそのまま使いたい場合はMODE_PRIの代わりにMODE_BCMを使うらしいです。

APIとLチカテスト

http://raspberrypi.local:3000/api/led/on にアクセスして、LEDが光ることを確認します。

http://raspberrypi.local:3000/api/led/off にアクセスして、LEDが消えることを確認します。

画面にボタンを配置

apiを叩くのにaxiosを使いたいのでインストール

npm i -S axios

index.tsxを以下の様に変更して、APIを叩くボタンを配置します。

import axios from 'axios'
import type { NextPage } from 'next'
import Head from 'next/head'
import styles from '../styles/Home.module.css'

const Home: NextPage = () => {
  return (
    <div className={styles.container}>
      <Head>
        <title>Raspberry Pi Controller</title>
        <meta name="description" content="Raspberry Pi Controll App" />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main className={styles.main}>
        <button onClick={()=>{
          axios.get('/api/led/on');
        }}>
          LED ON
        </button>
        <button onClick={()=>{
          axios.get('/api/led/off');
        }}>
          LED OFF
        </button>
      </main>
    </div>
  )
}

export default Home

動作テスト

こんな画面が表示されるようになり、ボタンでLEDをチカチカさせられるようになります。スマートフォンからも操作できるのでIoTっぽくていいですね。

image-20211002221922669

image-20211002222204898

次回は可変抵抗ダイヤル値をデジタル入力し、その値をPWM出力に反映してモーターの回転速度制御でもやってみようかと思います。

おまけ

ラズパイのデータがいつ飛ぶか分からないのでgithubで管理することにしました。以下のコマンドでインストールして、VSCode上から使えるようになります。

sudo apt-get install git
git config --global user.name xxx(ユーザー名)
git config --global user.email xxx(メールアドレス)