RaspberryPi4 + CNCjs

# 2022年7月時点では
この記事はもう古くなっています。記事のように設定できなくはないですが、2022年7月現在では、CNCjs一式をインストールしてくれるスクリプト「cncjs-pi-raspbian」を知り、こちらを使う方が良いと思います。RaspberryPi OS（2022-04）で動作確認してくれているのと、CNCjsのバージョン選択や、新しいカメラのドライバ（uStreamer）の選択、バージョン変更してインストールし直しなど、とても便利です。作ってくれた方に感謝です。
https://github.com/cncjs/cncjs-pi-raspbian


# はじめに
![スクリーンショット 2020-10-28 19.27.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/3d325778-771a-8375-aebf-d00494f727c8.png)
自分はいつもCNCフライスを使って、木を削って動物の木彫をつくっています。2006年に初めてホビー用を購入した後、数年前に旋盤市場の「PSF240-CNC」に買い換え、半年前にOpenBuildsの「LEAD CNC Machine 1010」を購入しました。現在この2台をメインに使い分けています。

PSF240-CNCはオプションの専用PCがあり、その中の「LinuxCNC」というソフトで制御しています。LEAD CNCはArduinoと汎用PCで動く「CNCjs」というソフトで制御しています。CNCjsはJavascriptで作られているので、macOSでもWindowsでもRasiperrbyPiでも動きます。自分の環境では、CNCjsをRaspberryPi4にインストールしたものを、macOSからChromeで操作して使っています。

## CNCjsのよいところ
専用PCのLinuxCNCは本当に何もトラブルがありません。長時間でもずっとフリーズしたことがないです。以前つかっていたWindows用の「EdingCNC（USBCNC）」はソフトは優秀なのですが、CNC加工中にWindowsが勝手にアップデートはじめたりして、普段はmacOSを使うのでWindowsを準備するのが面倒でした。

そしてRaspberryPi4で動かしているCNCjsは、長時間でもフリーズせず、実感としてはめちゃくちゃ優秀です。一時停止や再開などもあり、GUIの使い勝手もとてもよいです。しかもブラウザから操作できるので、macOSでもWindowsでもよいのがいいです。また、CNCを監視するWEBカメラを簡単に設定することができるのもいいところです。

そこで今回は、「CNCjs」を「RaspberryPi4」にインストールする手順の記事になります。

環境は
・macOS Mojave 10.14.6
・RaspberryPi4 メモリ2Gタイプ
・WEBカメラ（なくてもOK）　iBUFFALO BSWHD06MWH

---
# CNCjsとは
![スクリーンショット 2020-11-06 13.03.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/d3c1c049-d181-70f7-b677-870e8e7608fd.png)
CNCマシンを動かすためのオープンソースのソフトで、JavaScriptでできています（Node.js）。

CNCjsの公式サイト
https://cnc.js.org/

RaspberryPiへのセットアップ（公式）
https://cnc.js.org/docs/rpi-setup-guide/

公式のセットアップガイドをみると、RaspberryPi2や3はまとめられていましたが、現時点ではRaspberryPi4に関する情報はありませんでした（2020/11/07）。RaspberryPi4では使えないのかな？とも思ったのですが、インストールしてみたところ、今も安定して切削できています。

---
# RaspberryPi4＋CNCjsのインストール手順
## RaspberryPi本体のセットアップ
RaspberryPiの本体を準備したり、OSをインストールする作業です。いつも使っているパソコンで行います。自分はiMacから作業しています。


### RaspberryPi4とmicroSDの入手
https://akizukidenshi.com/catalog/g/gM-14839/
自分はメモリ2Gを使っていますが、1Gのものでも問題ないと思います。

microSDは16Gや32Gを使っていますが、8Gだと足りませんでした。

### RaspberryPi OS(LITE)をmicroSDに書き込む
![raspberrypi_imager.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/e8d387d1-1d90-1509-c9fb-d023eb11443a.png)

https://www.raspberrypi.org/downloads/
RaspberryPi公式の書き込みツール「RaspberryPi Imager」をダウンロード＆インストールし、起動します。OSを選ぶ欄では、「RAPBERRY PI OS LITE（32-BIT)」を選びました。CNCjsはデスクトップを使わないのでLITEがよいと思います。microSDをセットして選び、「WRITE」ボタンで書き込み開始。書き込み終わるまで、しばらく待ちます。

### OS書き込み完了後、microSDを抜きすぐ差し込む
![スクリーンショット 2020-11-06 13.22.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/e7b74603-82f8-bc15-64d0-14a2d88e69a4.png)
microSDの書き込み完了後、カードはささったままなのに自動的にイジェクトされますので、いったんmicroSDを抜いてすぐ差し込みます。

次はRaspberryPiの中をセットアップしていきます。この作業は本体にHDMIモニタとキーボードとマウスをつなげば、ふつうのパソコンのようにモニタで作業できますが、これら周辺機器の準備が面倒です。そこで、最初にネットワーク経由でmacOSからアクセスできるように設定します。これはmacOSにmicroSDを「boot」ディスクとしてマウントし、ここにファイルを書き込むだけで設定することができるので、RaspberryPi用のマウスやキーボードは不要です。

### SSHとWiFiの設定
#### bootとして認識されるのを確認
![スクリーンショット 2020-10-30 16.05.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/cb289d9a-70f8-4ab8-7e79-aca12741ed2c.png)
microSDが「boot」という名前でマウントされるはずです。次はこの「boot」に、macOSで作成したファイルを書き込みます。

#### SSHを有効にするファイルを「boot」に書き込み
![スクリーンショット 2020-10-30 16.27.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/c290b1b8-6957-7251-02d6-ba8b1abf8f63.png)
![スクリーンショット 2020-11-06 14.48.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/1ade39e6-ba91-04fd-6813-9db08374efb0.png)
テキストエディタなどで「ssh」というファイル名で空のファイルを作成し、「boot」にコピーします。ファイル名を拡張子がない「ssh」にするのがポイントです。

このファイルが存在するとRaspberryPiが起動時にSSHが許可され、自動的に「boot」から消えます。

#### WiFiの設定ファイルを「boot」に書き込み
![スクリーンショット 2020-11-06 14.48.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/2e11a464-56ef-7203-a8cb-53f44d99af4a.png)
こちらはWiFi環境がある場合に設定します。ない場合は、RaspberryPi4とPCをLANケーブルでつなぐか、RsapberryPi4にHDMIモニタとキーボードとマウスをつなぐと、RaspberryPiのデスクトップから設定できますが、準備が面倒です。ここでは、WiFiでSSH接続し、macOSの「ターミナル」アプリから設定していきます。

```wpa_supplicant.conf
country=JP
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
    ssid="ssid"
    psk="password"
}
```
<strong>※ ssid、passswordは、WiFi環境にあわせて書き換えてください</strong>

なお、この「wpa_supplicant.conf」はRaspberryPiが起動時に、「/etc/wpa_supplicant/wpa_supplicant.conf」にコピーされ自動的に「boot」から消えます。

### microSDをRaspberryPiにセットして電源ON
RaspberryPiの起動が落ち着くまでしばらく待ちます。しばらく待つと、先ほど設定したWiFiのアクセスポイントにつながるはずです。繋がらない場合は、WiFiのSSIDやパスワードが違うかもしれません。その場合はもう一度microSDをmacOSにマウントし、「boot」に正しい情報の「wpa_supplicant.conf」を書き込みます。

「アプリケーション」>「ユーティリティ」にある「ターミナル」で、SSH接続してみます。

````
ssh pi@raspberrypi.local
````

ターミナルに打ち込み、Enterキーをおすと、パスワード入力が求められます。
![スクリーンショット 2020-11-06 13.26.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/e3b8f52e-ef9a-b1cb-34b9-5b896be1004a.png)
このまま続けるか聞いてくるので、「yes」と打ち込んでEnter。
![スクリーンショット 2020-11-06 13.30.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/7c7ca670-6e6f-d760-f04c-e95156949790.png)
RaspberryPiにログインするパスワードを求められます。何も設定してない最初の状態では「raspberry」というパスワードになっていますので、打ち込んでEnter。なおパスワードを入力中はセキュリティのため画面では何も打ち込んでないように見えます。
![スクリーンショット 2020-11-06 13.31.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/2013cc38-7561-3e07-5637-7dec86a84b9a.png)
無事にRaspberryPiにログインできました。
![スクリーンショット 2020-11-06 13.31.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/5e7aaeed-968f-54cb-1aeb-2200fa55ed66.png)


---
## RaspberryPi内部のセットアップ
### Node.jsのインストールについて
ここでRaspberryPiはインターネットにつながる必要がありますので、WiFiかLANをつないでください。インターネット環境が整ったら、CNCjsに必要な「Node.js」をインストールします。このときバージョンが指定できる状態でインストールするとよいです。

というのは、CNCjsの公式サイトでもRaspberryPiにセットアップする手順がありますが、この手順ではNode.jsのVer.7をインストールしようとします。しかしもうサポートされないとのことで、公式サイトの手順通りにはインストールできませんでした。

CNCjsは現在はNode.jsのVer.8以降を推奨しています（2020/11/06）。しかし現時点ではNode.jsはVer.10.22.1なので、できれば最新にしておきたいと思い、NVM（Node Version Manager）を使ってインストールすることにしました。

#### NVMのインストール
nvmのGithubのサイトの「Installing and Updating」を参考にしてインストールします。
https://github.com/nvm-sh/nvm

おそらく、またアップデートしたら、以下のコマンドの「v0.36.0」っていうところも変わると思うので、定期的にチェックしておくとよさそうです。

```
sudo apt-get update
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.36.0/install.sh | bash
```

#### PATHを通す
「PATHを通す」とは、「nvm」のインストールされた位置をフルパスで指定しなくてもよいように設定することです。その設定は、不可視ファイルの「.bash_profile」に書き込みます。もしなければ作成しますが、ファイルがあってもなくても以下の手順でOKです。

```
sudo nano ~/.bash_profile
```

ここに、以下を追記します。

```
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion
```

.bash_profileを保存し（nanoの画面で、コントロール＋XのあとY）


次のコマンドで適用し有効にします。

```
source ~/.bash_profile
```


#### NODEのバージョンを指定してインストールする
バージョン10を指定してインストールし、バージョン10を使うようにします。

```
nvm install 10
nvm use 10
```

### NPMをインストール
続いて、NPM（Node Package Manager）をインストールします。

```
npm install npm@latest -g
```

###CNCjsのインストール
いよいよ、NPMを使って、CNCjsをインストールします。

```
npm install -g cncjs
```

#### CNCjsのインストール確認
うまくインストールできたかどうか確認しておきます（しなくてもよいです）。

```
cncjs -V
```
以下のようにバージョンが返ってきたらインストールできています。

```
1.9.22
```

###自動起動の設定
RaspberryPiが起動したら、CNCjsが自動的に起動するようにします。自動起動にはProduction Process Maneger「pm2」を使います。

```
npm install pm2 -g
pm2 start $(which cncjs) -- --port 8000
pm2 startup
```
インストールして「startup」すると、以下のようなメッセージが出力されます。

sudo env PATH=$PATH:/home/pi/.nvm/versions/node/v8.17.0/bin /home/pi/.nvm/versions/node/v8.17.0/lib/node_modules/pm2/bin/pm2 startup systemd -u pi --hp /home/pi

---
※コメントいただき追記 2022.07.10
nodeのバージョンが変わると思いますので、出力されたメッセージをもとに、コピーして実行してください。
```
sudo env PATH=$PATH:/home/pi/.nvm/versions/node/v8.17.0/bin /home/pi/.nvm/versions/node/v8.17.0/lib/node_modules/pm2/bin/pm2 startup systemd -u pi --hp /home/pi
```
---

そのあとpm2を保存してlistを確認してみてください。

```
pm2 save
pm2 list
```
listに「cncjs」が出てくれば、無事に設定できています。
![スクリーンショット 2020-11-06 15.39.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/36d25517-61a4-63b0-4f83-49f666c85076.png)

### CNCjsの動作確認

RaspberryPiのアドレスに「:8000」をつけてアクセスすると、CNCjsの画面が出るはずです。左下にWEBカメラのウィジェットが見えますが、まだ設定してないので認識されていません。次はWEBカメラを設定します。
http://raspberrypi.local:8000/

![スクリーンショット 2020-11-06 15.42.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/42a9b83d-7181-82eb-2545-287d0866229b.png)


### WEBカメラの設定

CNCjsでは、CNCを監視するWEBカメラを設定することができます。これもすごいです。WEBカメラが不要な場合、読み飛ばしてください。

まずは必要なファイルをダウンロードしてインストールします。

```
sudo apt-get install build-essential libjpeg8-dev imagemagick libv4l-dev cmake -y git
```

次に「tmp」フォルダに移動して、「mjpg-streamer」をインストールしていきます。以下のコマンドで「git clone」でファイルをダウンロードしてきて解凍し、さらに「mjpg-streamer-experimental」フォルダに移動します。

```
cd /tmp
git clone https://github.com/jacksonliam/mjpg-streamer.git
cd mjpg-streamer/mjpg-streamer-experimental
```

「mjpg-streamer-experimental」フォルダに移動したら、「make」でソースをコンパイルし、「sudo make install」でそのコンパイルされたファイルをインストールします。いろいろ書き出されると思いますが、しばらく待ってください。

```
make
sudo make install
```

ようやくこれで、WEBカメラのソフトが準備できました。WEBカメラは、USBでつながる一般的なものでよいです。自分の環境では「iBUFFALO BSWHD06MWH」を使っています。

#### WEBカメラの確認
WEBカメラウィジェットのスイッチをオンにします。
![スクリーンショット 2020-11-06 16.48.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/e2d64244-1c42-67d3-8650-3095296d39f4.png)
まだ設定できてないので真っ暗ですので、設定ボタンを押します。
![スクリーンショット 2020-11-06 16.49.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/049ee803-ed45-7c2d-7d42-ca2d02d0a0c4.png)
ダイアログがでてきたら「Connect to an IP camera」を選択し、アドレスに「:8080?action=stream」とつけて「変更を保存」してください。自分の場合は「raspberrypi.local」でRaspberryPiにアクセスできるので以下のようになっています。

```
http://raspberrypi.local:8080?action=stream
```
![スクリーンショット 2020-11-06 16.50.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/e826bb41-07c0-80f7-5fa7-fd73465f1275.png)
設定を保存したらWEBカメラの映像がストリーミングされます。
![スクリーンショット 2020-11-06 16.50.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/00d2acfb-cafc-7c5d-7e08-86e55c166abc.png)

##microSDのリードオンリー化

ここまででCNCjsを使うことはできます。しかしmicroSDには書き換え寿命があります。そんなに書き換えてなくても、RaspberryPiはmicroSDをハードディスクのようにして動作するので、ログなどで書き換えが発生する可能性があります。また電源をブチ切りするとき、microSDに書き込み中だとファイルが壊れてしまう可能性もあります。動作不良の原因となるので、これらを回避するために、メモリをハードディスクのようにして動く「リードオンリー化」を設定します。

この設定は最近のRaspberryPiのOSでは（RaspbianBuster以降）、raspi-configから設定できるようになっていて、めちゃくちゃ楽になりました。今回はデスクトップなしのOSですが、デスクトップありの場合はGUIで設定できます。

ただし、注意することとしては、再起動するとリードオンリー化前の状態に戻るので、ダウンロードやインストールなどすべての作業を終えた後に、リードオンリー化することです。なお、一時的なファイル（再起動したら消えてもいいファイル）は、リードオンリーにしてもRaspberryPiに書き込むことができますので、CNCjsで加工したいデータなどはリードオンリー化の後でも問題ありません。

では設定です。ターミナルから「raspi-config」を起動します。

```
sudo raspi-config
```

![スクリーンショット 2020-11-06 15.48.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/9a3fc945-c07d-a102-c316-be70dbbca78d.png)

このような画面になります。
![スクリーンショット 2020-11-06 15.48.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/dea33fb9-1a6a-49c4-a6fb-d05788cc83a2.png)

「7 Advanced Options」　>　「AB Overlay FS」を選びます。

![スクリーンショット 2020-11-06 15.48.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/793cfa15-2193-8bab-2e16-dd6b08b7b6b4.png)
![スクリーンショット 2020-11-06 15.48.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/8c457626-dd53-3aea-bc0c-918755a814de.png)

まずリードオンリー化するか聞かれ、次にboot領域もリードオンリー化するか聞かれます。どちらも「Yes」で「Enable」にしました。
![スクリーンショット 2020-11-06 15.48.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/0812af04-1737-e21d-ea79-7bde126b2b31.png)
![スクリーンショット 2020-11-06 15.49.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/6abdc587-793a-3bb8-6583-dd86191a4c71.png)
![スクリーンショット 2020-11-06 15.49.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/133e5ee4-f258-ecd6-0bb7-501489288844.png)


# おしまい
ようやくこれでRaspberryPi4でCNCjsが動くようになりました（電源ブチ切りしてもmicroSDが壊れにくい）。CNCjsはオープンソースでフリーですが本当に優秀です。Openbuildsの「LEAD CNC」も全部パーツの状態で届くのですが、10万円前後で購入できました（Aliexpress）。それから説明が難しくてここでは書きませんが、「LEAD CNC」のアルミフレームがMISUMIの規格と同じだったりして、数千円でZ軸を高く改造できました。こんなことができるのもオープンソースのハードウェアの好きなところです。こんな環境がもう世界にはあって、作るのが大好きな人たちもたくさんいるんだなぁと思うとワクワクします！

#参考にさせていただいたサイトなど
CNC組み立てやCNCjsの設定でお世話になったサイトです。ありがとうございます。

- <a href = "https://bbs.avalontech.jp/
">Avalontech 開発者コミュニティ</a>
- <a href="https://cnc-selfbuild.blogspot.com/">自作CNCマシン・レーザーカッターについて</a>