Kamuycikap - SentenceDataBase

日々の勉強の記録を気分で書き綴るブログ

Raspberry Pi OSにNode-Redをインストール

Node-Redインストール

本家サイトにRaspberryPiへのインストール方法が書いてある。 有志による日本語化もされており、内容を読めばインストール可能。

参考URL → https://nodered.jp/docs/getting-started/raspberrypi

インストールコマンド実行

$ bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)

しばらく待つだけ。

起動

RaspberryPiで起動する場合、メモリ解放オプションつけて起動したほうが良いらしい。 PCに比べれば貧弱なプラットフォームなのでやっておいたほうが良さそう

$ node-red-pi --max-old-space-size=256

実行

RaspberryPiに接続できるネットワーク上にあるPCを用意。 そのPCでブラウザを起動し、URL欄にIPアドレスとポート番号1880を入力。

http://192.168.0.154:1880

無事に起動すると、Node-RedのIDEが起動する。

rc.localからUSBメモリのマウントを確認する

RaspberryPiで起動時にUSBメモリのマウントを確認(rc.local)

参考URL → https://dekuo-03.hatenablog.jp/entry/2019/12/08/000955

logを残す仕組みを作成

自動起動したいcommandの標準出力、エラーをファイルに吐くシェルスクリプトを作成

## commandが実行したいバイナリファイル or シェルスクリプト。 Logを残したいファイル名は適当
command > /path/to/logfile 2>&1

rc.localの編集

USBメモリがマウントされたかどうかは、USBメモリ内部にあるファイル / フォルダが存在するか否かを判断するコードを書く。

pi@raspberrypi:~ $ sudo nano /etc/rc.local
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi

# 最大三十秒。
# /media/pi/A81C-D3AB/fsthermo/param.txt が存在するか否かを確認し続ける。
# 存在したら、fsrun.shを実行した後、breakで抜ける。
for i in `seq 0 30`
do
  if [ -e /media/pi/A81C-D3AB/fsthermo/param.txt ]; then
    /home/pi/Public/fsthermo/fspi/fsrun.sh &    # ← 実行したいコマンド
    break
  fi
  sleep 1s
done

exit 0

rc.localが正しく動作しているか否か確認する

pi@raspberrypi:~ $ sudo systemctl status rc-local.service

RaspberryPi OS でマウントされたUSBメモリのパスを抽出

USBコネクタに接続されたUSBメモリのパス調査

USBメモリがラズパイに押されているとき、どこにマウントされているのかを教えてくれる。 いっつも忘れるのでメモ。 ※ただし、USBメモリ一本だけ。USBメモリを複数押してる場合は、正規表現を変える必要あり。

$ mount | grep -e "media" | sed -e 's/ type.*//g' | sed -e 's/\/dev.* on //g'

Makefileの書き方

Makeファイルによるコンパイルの自動化(Webな方々でいう所のデプロイ)

GNUMakeは歴史が古く、確固たる地位を築いているシステム。 ゆえに、様々な後継プログラミング言語用にツールが開発されている。 GNUMakeのMakefileが書けると、JavaではAntやMavenRubyではRakeなどで応用がきく?!・・・事にしておこう。

昔あった記事がない・・・・

昔参考にしていたサイトがいつの間にやらなくなっていた。 ネットを覗けば何時でも読めると思っていたら・・悲しい。 ので、Webアーカイバを漁って見つけてきたものをここに残す。

よって、この文章は私オリジナルの文章ではなく、昔学習させていただいたサイトの情報をHatenaに残したものである。 http://web.archive.org/web/20060320022409/http://www.c.csce.kyushu-u.ac.jp/~seiichirou/wiki/index.php?Makefile%A4%CE%BD%F1%A4%AD%CA%FD

Make で Hello World

それではメイクファイルを書いてみましょう。ここではソースファイルとしてコンパイル方法でも使ったC言語Hello World!を使用します。

/* hello.c */
#include <stdio.h>

int main(int argc, char* argv[]) {
  printf("Hello World!\r\n");
  return 0;
}

同じディレクトリに“Makefile”というファイルを作成して、以下の内容を記述してください。

# Makefile
hello: hello.c
    gcc -o hello hello.c

三行目の先頭は空白文字ではなくてタブ文字(Tab)なので注意してください! 一行目はコメントです。“#”と書くとその行の“#”以降の文字列はコメントとなります。 コマンドからmakeを実行すると以下のようにコンパイルしてくれます。

pi@raspberrypi:~ $ make
gcc -o hello hello.c

このあともう一度makeを実行してみましょう。

$ make
make: `hello' は更新済みです

hello.cが更新されていない(helloの方がhello.cよりも日付が新しい)のでコンパイルされません。 こんな感じで、必要な部分のみコンパイルしてくれます。

Makefileのファイル名を指定する場合は

pi@raspberrypi:~ $ make -f Makefile

とします。 ファイル名を指定しない場合は、“GNUmakefile”、“makefile”、“Makefile”の順に検索します。

Makefileの基本文法: 依存関係

Makefileの基本的な構文は依存関係を表す依存関係です こんな感じ。

ターゲット名: 依存ファイル名1 依存ファイル名2 依存ファイル名3
    コマンド行1
    コマンド行2
    コマンド行3

ターゲット名は一般的に生成されるファイルのファイル名にします(そうでない場合については後述します)。

ターゲット名の後に“:”を書いて、その後にスペース区切りで依存するファイルのファイル名を記述します。 これらのファイルのうちどれか一つでも更新されるとコマンドが実行されます。

ターゲット名を指定してmakeを実行する場合は

pi@raspberrypi:~ $ make ターゲット名

とします。 ターゲット名を省略すると、Mkefileの中で先頭のターゲットが実行されます。

ターゲット名から始まる行の次の行から実行するコマンドを記述します。 コマンドを記述する場合は必ず先頭にタブ文字を入れる必要があります。

例として、C言語の分割コンパイルをしてみましょう。分割コンパイル用に以下のファイルを用意します。

#include <stdio.h>

void edajima(void);

int main(int argc, char* argv[]) {
  edajima();
  return 0;
}
/* edajima.c */
#include <stdio.h>

void edajima(void);

void edajima(void) {
  printf("わしが男塾塾長 江田島平八である!!\r\n");
}

メイクファイルはこんな感じです。

# Makefile
hello: hello.c edajima.c
    gcc -o hello hello.c edajima.c

hello.cまたはedajami.cのいずれかを更新するとコンパイルし直してくれます。 しかし、このままでは更新されてないファイルもコンパイルし直されてしまうので、少し変更します。

# Makefile
hello: hello.o edajima.o
    gcc -o hello hello.o edajima.o

hello.o: hello.c
    gcc -c hello.c

edajima.o: edajima.c
    gcc -c edajima.c

こうしてmakeを実行すると、

pi@raspberrypi:~ $ make
gcc -c hello.c
gcc -c edajima.c
gcc -o hello hello.o edajima.o

となります。 ここで、edajima.cを書き換えます。

/* edajima.c */
#include <stdio.h>

void edajima(void);

void edajima(void) {
  printf("わしが男塾塾長 江田島平八である!!\r\n");
  printf("以上!\r\n");
}

そしてmakeを実行すると、

pi@raspberrypi:~ $ make
gcc -c edajima.c
gcc -o hello hello.o edajima.o

となって、edajima.oだけが更新されます。

依存関係行の応用その一

依存関係行を使った応用について説明します。 プログラムをコンパイルすると中間ファイルなどができていちいち削除するのが面倒です。 そこで、Makefileに以下の行をつけたします。

# Makefile
hello: hello.o edajima.o
    gcc -o hello hello.o edajima.o

hello.o: hello.c
    gcc -c hello.c

edajima.o: edajima.c
    gcc -c edajima.c

clean:
    rm -f hello hello.o edajima.o

こうしてコマンドで以下のように実行します。

pi@raspberrypi:~ $ make clean
rm -f hello hello.o edajima.o

不要なファイルをすべて削除してくれます。 “clean”は依存するファイルがなく、cleanというファイルを生成するわけでもなく、コマンドを実行するだけです。 このようなターゲットのことを“phony target”と呼びます。 phonyターゲットを使用する場合、ターゲット名と同じ名前のファイルがあると変なことになります。

pi@raspberrypi:~ $ touch clean
pi@raspberrypi:~ $ make clean
make: `clean' は更新済みです

これをさけるためにはMakefileのcleanターゲット部分を以下のように書き換えます。

.PHONY: clean
clean:
    rm -f hello hello.o edajima.o

こうするとcleanというファイルが存在していても問題ありません。

依存関係行の応用その二

もう一つの応用は、複数のプログラムを作成するときに役に立ちます。 ここでは以下のソースファイルを追加します。

/* raiden.c */
#include <stdio.h>

int main(int argc, char* argv) {
  printf("男の勝負に言葉はいらん\r\n");
  printf("ただそれだけのこと…………!!\r\n");
  return 0;
}

そしてMakefileを以下のようにします。

# Makefile
hello: hello.o edajima.o
    gcc -o hello hello.o edajima.o

hello.o: hello.c
    gcc -c hello.c

edajima.o: edajima.c
    gcc -c edajima.c

raiden: raiden.o
    gcc -o raiden raiden.o

raiden.o: raiden.c
    gcc -c raiden.c

.PHONY: clean
clean:
    rm -f hello hello.o edajima.o raiden raiden.o

これでhelloとraidenを作ろうとすると、

pi@raspberrypi:~ $ make hello
pi@raspberrypi:~ $ make raiden

となり、面倒です。 そこで、ダミーの依存関係行を追加します。

# Makefile
.PHONY: all
all: hello raiden

hello: hello.o edajima.o
    gcc -o hello hello.o edajima.o

hello.o: hello.c
    gcc -c hello.c

edajima.o: edajima.c
    gcc -c edajima.c

raiden: raiden.o
    gcc -o raiden raiden.o

raiden.o: raiden.c
    gcc -c raiden.c

.PHONY: clean
clean:
    rm -f hello hello.o edajima.o raiden raiden.o

先頭に追加した“all”がミソです。 これでmakeを実行すると、

pi@raspberrypi:~ $ make
gcc -c hello.c
gcc -c edajima.c
gcc -o hello hello.o edajima.o
gcc -c raiden.c
gcc -o raiden raiden.o

となってめでたく二つのプログラムを一度に作成することができました。

依存関係行の応用その三

C言語ではコンパイルしないけどソースファイルにインクルードされるヘッダーファイルが存在します。 ヘッダーファイルが更新されたときにソースファイルをコンパイルし直すにはどうしたらよいのでしょうか?

この問題を解決するには、同じターゲット名の依存関係行を追加します。 例えば以下のようなファイルを用意します。

char serifu[] = {"聖紆麈 貴様の命 この邪鬼とともにある"};
/* jaki.c */
#include <stdio.h>
#include "jaki.h"

int main(int argc, char* argv[]) {
  printf("%s\r\n", serifu);
  return 0;
}
# Makefile
.PHONY: all
all: jaki

jaki: jaki.o
    gcc -o jaki jaki.o

jaki.o: jaki.c
    gcc -c jaki.c

.PHONY: clean
clean:
    rm -rf jaki jaki.o

makeを実行すると

pi@raspberrypi:~ $ make
gcc -c jaki.c
gcc -o jaki jaki.o

となります。 ここで“jaki.h”を書き換えます。

char serifu[] = {"す すまん 貴様等の期待と信頼を裏切った…………"};

そして、makeを実行すると

pi@raspberrypi:~ $ make
make: `all' に対して行うべき事はありません。

といって更新してくれません。 そこで、以下のように“Makefile”を書き換えます。

# Makefile
.PHONY: all
all: jaki

jaki: jaki.o
    gcc -o jaki jaki.o

jaki.o: jaki.c
    gcc -c jaki.c

jaki.o: jaki.h

.PHONY: clean
clean:
    rm -rf jaki jaki.o

“jaki.o: jaki.h”という行がポイントです。 そして、makeを実行すると

pi@raspberrypi:~ $ make
gcc -c jaki.c
gcc -o jaki jaki.o

マクロ

ここから少し難しくなります。 これまではMakefieにファイル名やコマンド名を直接書いていました。 しかし、マクロを使うと直接書かなくてすみ、他への流用などが容易となります。 マクロを定義するには以下のようにします。

マクロ名 = 文字列

マクロを参照するには、

$(マクロ名)

または

${マクロ名}

とします。実際に使ってみるとこんな感じです。

# Makefile
objs = hello.o edajima.o

hello: $(objs)
    gcc -o hello $(objs)

hello.o: hello.c
    gcc -c hello.c

edajima.o: edajima.c
    gcc -c edajima.c

.PHONY: clean
clean:
    rm -f hello $(objs)

ここでは、オブジェクトファイル名を“objs”というマクロとして定義しています。 “$(objs)”は“hello.o edajima.o”に置換されます。

GNU makeでは、定義済マクロとして以下のものがあります。

マクロ名 文字列 説明
AR ar アーカイブユーティリティ
AS as アセンブラ
CC cc Cコンパイラ
CXX g++ C++コンパイラ
CO co RCS ファイルからリビジョンをチェックアウトする
CPP $(CC) -E Cプリプロセッサ
FC f77 Fortranコンパイラ
GET get 知らね
LEX lex lex
PC pc Pascalコンパイラ
YACC yacc yacc
YACCR yacc -r 知らね
MAKEINFO makeinfo Texinfo -> Info
TEX tex TeX
TEXI2DVI texi2dvi Texinfo -> DVI
WEAVE weave 知らね
CWEAVE cweave 知らね
TANGLE tangle 知らね
CTANGLE ctangle 知らね
RM rm -f ファイルの削除

上記のプログラムの引数用のマクロもあります。

マクロ名 文字列 説明
ARFLAGS rv ARの引数
ASFLAGS ASの引数
CFLAGS CCの引数
CXXFLAGS CXXの引数
COFLAGS COの引数
CPPFLAGS CPPの引数
FFLAGS FCの引数
GFLAGS GETの引数
LDFLAGS リンカldの引数
LFLAGS LEXの引数
PFLAGS PCの引数
RFLAGS 知らね
YFLAGS YACCの引数

これらのマクロは再定義可能です。 例えば、こんな感じです。

# Makefile
objs = hello.o edajima.o
CC = gcc

hello: $(objs)
    $(CC) -o hello $(objs)

hello.o: hello.c
    $(CC) -c hello.c

edajima.o: edajima.c
    $(CC) -c edajima.c

.PHONY: clean
clean:
    $(RM) hello $(objs)

ここでは“CC”というマクロを“gcc”という文字列で再定義しています。 また、“RM”というマクロをそのまま使用しています。

内部マクロ

前述のマクロは単純に文字列に置換するだけでしたが、内部マクロはもう少し複雑になります。 例えば、こんな感じの内部マクロがあります。

hello: $(objs)
    $(CC) -o $@ $(objs)

ここでは“$@”という内部マクロを使用しています。 これはターゲット名を表すものです。

そのため上記の記述は、

hello: $(objs)
    $(CC) -o hello $(objs)

と解釈されます。 また、以下のものもあります。

hello.o: hello.c
    $(CC) -c $<

ここでは“$<”という内部マクロを使用しています。 これは依存ファイルの先頭のファイル名を表すものです。 そのため上記の記述は、

hello.o: hello.c
    $(CC) -c hello.c

と解釈されます。 依存ファイル名のリストを表す“$^”という内部マクロもあります。

内部マクロをまとめるとこんな感じです。

内部マクロ名 説明
$@ ターゲット名
$% ターゲットメンバ名(ターゲット名が“edajima.a(momo.o)”の場合、$@は“edajima.a”で、$%は“momo.o”
$< 依存ファイルの先頭のファイル名
$? 依存ファイルの内、ターゲットより新しいファイルのリスト
$^ 依存ファイルのリスト
$+ わかんね
$* わかんね

マクロと内部マクロを駆使すると、Makefileはこんな感じになります。

# Makefile
program = hello
objs = hello.o edajima.o
CC = gcc
CFLAGS = -g -Wall

$(program): $(objs)
    $(CC) -o $(program) $^

hello.o: hello.c
    $(CC) $(CFLAGS) -c $<

edajima.o: edajima.c
    $(CC) $(CFLAGS) -c $<

.PHONY: clean
clean:
    $(RM) $(program) $(objs)

サフィックスルール

サフィックスルールとは、ファイル名の拡張子(サフィックス)ごとにルールを定義するものです。 例えばこんな感じです。

.SUFFIXES: .o .c
.c.o:
    $(CC) $(CFLAGS) -c $<

“.SUFFIXE”は依存関係行と同じ形ですが、意味が違います。 サフィックスルールを適用する拡張子のリストを書きます。

“.c.o”がサフィックスルールとなっており、拡張子が“.o”のファイルは拡張子を“.c”変えたファイルに依存していることを表します。 変換方法はコマンドで表されています。 例えば、ターゲット名が“hoge.o”ならばmakeはこのサフィックスルールより“hoge.c”に依存していると判断して、コマンドを実行し“hoge.o”を生成します。

サフィックスルールを用いると、こんな感じで書けます。

# プログラム名とオブジェクトファイル名
program = hello
objs = hello.o edajima.o

# 定義済マクロの再定義
CC = gcc
CFLAGS = -g -Wall

# サフィックスルール適用対象の拡張子の定義
.SUFFIXES: .c .o

# プライマリターゲット
$(program): $(objs)
    $(CC) -o $(program) $^

# サフィックスルール
.c.o:
    $(CC) $(CFLAGS) -c $<

# ファイル削除用ターゲット
.PHONY: clean
clean:
    $(RM) $(program) $(objs)

ここまでくると、あとは“program”や“objs”を書き換えるだけでいくらでも流用ができます。 ちなみに、ヘッダーファイルの依存関係だけは自分で記述しなければなりません。 例えばこんな感じです。

# Makefile

# プログラム名とオブジェクトファイル名
program = jaki
objs = jaki.o

# 定義済マクロの再定義
CC = gcc
CFLAGS = -g -Wall

# サフィックスルール適用対象の拡張子の定義
.SUFFIXES: .c .o

# プライマリターゲット
$(program): $(objs)
    $(CC) -o $(program) $^

# サフィックスルール
.c.o:
    $(CC) $(CFLAGS) -c $<

# ファイル削除用ターゲット
.PHONY: clean
clean:
    $(RM) $(program) $(objs)

# ヘッダーファイルの依存関係
jaki.o: jaki.h

さらなる応用

分割Makefile

プログラムが複雑になって、ディレクトリごとにソースコードを分けるなどしていくと、一つのMakefileで管理するのは面倒になってきます。 そんな時には、Makefileを分割することができます。 例えば、subdirというサブディレクトリの中に別のMakefileがあるとした場合、カレントディレクトリのMakefile

subsystem:
    cd subdir && $(MAKE)

または

subsystem:
    $(MAKE) -C subdir

とします。

C言語のヘッダーファイルの依存関係の自動解決

C言語でプログラミングしている際に、ソースファイルが増えるとヘッダファイルの依存関係をいちいち記述するのは面倒です。 色々な解決方法があるみたいですが、とりあえずこんなん考えてみました。

# Makefile

# プログラム名とオブジェクトファイル名
program = jaki
objs = jaki.o

# 定義済マクロの再定義
CC = gcc
CFLAGS = -g -Wall

# サフィックスルール適用対象の拡張子の定義
.SUFFIXES: .c .o

# プライマリターゲット
.PHONY: all
all: depend $(program)

# プログラムの生成ルール
$(program): $(objs)
    $(CC) -o $(program) $^

# サフィックスルール
.c.o:
    $(CC) $(CFLAGS) -c $<

# ファイル削除用ターゲット
.PHONY: clean
clean:
    $(RM) $(program) $(objs) depend.inc

# ヘッダーファイルの依存関係
.PHONY: depend
depend: $(objs:.o=.c)
    -@ $(RM) depend.inc
    -@ for i in $^; do\
        cpp -MM $$i | sed "s/\ [_a-zA-Z0-9][_a-zA-Z0-9]*\.c//g" >> depend.inc;\
    done

-include depend.inc

gccプリプロセッサであるcppとsedを組み合わせています。 cppは指定したソースファイルの依存関係をmakeの形式で出力してくれるオプションを持っています。 それを使って、全ソースファイルの依存関係を“depend.inc”に出力して、それをインクルードしています。 “make depend”とコマンドを実行すればOKです。

また、“all: depend $(program)”とすることで、makeする際に毎回“depend.inc”を作成するようにしています。

その他

GNU makeには他にも色々な機能があります。詳しくはWebのマニュアルを見てください。また、makeを発展させた、autoconf、automake、libtool、などもあります。これはOS間の差異を吸収するためのツールです。

俺的RaspberryPi4セットアップ(2021年11月版)

汎用的なRaspberryPi4の作り方

はじめに

利用するにあたり、俺的Raspbianのイメージを作成しておく。
目的は、短時間で開発用プラットフォームを構築する事。
最初から「なんでもかんでも版」は用意せず、

くらいで押さえておく。
開発用ライブラリなどについては、必要に応じて後でインストール。

構築手順

OSセットアップ

https://www.raspberrypi.org/downloads/raspbian/
本家から、最新のRaspberry Pi OSをセットアップ。 ← このへんは割愛。
面倒ならNOOBSで構築してしまえば、待ってる時間も有効的に利用可能。

また、起動後はCLIではなくGUIにしておいて問題ないと考える。
起動後の状態については、利用シーンで各々が設定する方針とする。

ネットワーク設定

これも割愛。
初回起動時に、初期設定ウィザードが走る。
ウィザードの中に、ネットワーク設定も含まれるので、SSIDとパスワードを設定するだけ。

CapsLockをCtrlキーに

bash利用する時、キーバインドのデフォルトはEmacsになっている。
この場合、CapsLockキーがCtrlキーだとすごく使いやすい。
まずは、設定ファイルを開く

pi@raspberrypi:~ $ sudo nano /etc/default/keyboard

設定ファイル「keyboard」の最後に下記の行を追加して保存

XKBOPTIONS=ctrl:nocaps

再起動する。

pi@raspberrypi:~ $ sudo shutdown -r now
日本語入力できるように

基本的にはSSH接続利用を想定するが、HDMIディスプレイを接続して利用するシーンもあるはずなので、単体で日本語入力できるようにセットアップする。

pi@raspberrypi:~ $ sudo apt-get install ibus-mozc

しばらく待って、インストール完了後に再起動する。

pi@raspberrypi:~ $ sudo shutdown -r now
ホスト名変更

ネットワークに参加させる場合、デフォルトの状態では他のRaspberryPiと競合する。
自分一人なら問題ないが、複数の人間が同じネットワークでRaspberryPiを利用する場合はホスト名を分ける事で識別可能。
テキストエディタを使って、設定ファイルを直接編集し、再起動すればホスト名が反映されます。
変更箇所は以下の2つです。
注意点! ホスト名に記号を入れないように!(アンダーバーとかドットとか)

/etc/hosts
127.0.1.1 を 入力したホスト名に変更します。

/etc/hostname
ホスト名を入力します。

再起動にて設定内容が反映されます。

C言語開発環境構築

ここで言う開発環境とは、統合開発環境のことではない。

C言語ソースコードコンパイルできる環境を目指す。
ので、シェル上でコマンドによるコンパイルができる環境を構築する。

> 意気込んでインストールしようとしたら、デフォルトでインストールされていた。
> もしかしたら知らないうちに入れてたのか?と心配になったので、インストールコマンドをメモ_

pi@raspberrypi:~ $ sudo apt-get install build-essential
C言語開発(他言語でも使える)ライブラリインストール(GPIO、I2C、SPI)

GPIO、SPI、I2Cを叩くためのライブラリをインストール。

> WiringPiをインストールしようとしたら、デフォルトでインストールされていた。
> もしかしたら知らないうちに入れてたのか?と心配になったので、インストールコマンドをメモ
> I2Cライブラリはデフォルトでインストールされていない様子

pi@raspberrypi:~ $ sudo apt-get install wiringpi
pi@raspberrypi:~ $ sudo apt-get install i2c-tools
デバッガインストール

Linux環境でデバッグするための王道アプリをインストール【GDB

> これも意気込んでインストールしようとしたら、デフォルトでインストールされていた。
> もしかしたら知らないうちに入れてたのか?と心配になったので、インストールコマンドをメモ_

pi@raspberrypi:~ $ sudo apt-get install gdb
SSH接続できるように設定

RaspberryPiのGUI画面にて、
「左上のraspberryアイコン」→「設定」→「Raspberry Piの設定」
とクリックし、
インターフェイス」→「SSHを有効」
と設定してから、右下の「OK」をクリック

上記設定が完了すると、同ネットワークの別マシンから、SSH接続が可能になる。

bash:~ $ ssh pi@192.168.1.142
bash:~ $ pi@192.168.1.142's password: XXXXXX <- ログインパスワードを入力
pi@raspberrypi:~ $   <- 接続出来たらRaspberryPiのシェルになっているはず。
共有フォルダ作成

ファイルサーバーをセットアップ。
【注意】 インストールの初期段階でWINSによる名前解決の機能を有効にするか否かを聞かれるが、デフォルトの「いいえ」で進める事。

pi@raspberrypi:~ $ sudo apt-get update
pi@raspberrypi:~ $ sudo apt-get install samba

インストールできていたら、バージョン確認が動作するはず。

pi@raspberrypi:~ $ smbd -V
Version 4.5.16-Debian  <- インストールした時点のバージョンが表示される
pi@raspberrypi:~ $ 

別PCからソースコードや設定ファイルなどを配置できるように、共有フォルダを作成する。
/home/pi/Publicを共有フォルダとして設定する。
下記コマンドにて設定ファイルを編集。

pi@raspberrypi:~ $ sudo nano /etc/samba/smb.conf

smb.confの一番下に設定を追加

[Public]
path = /home/pi/Public
read only = No
guest ok = Yes
force user = pi

設定を有効化

pi@raspberrypi:~ $ sudo service smbd restart
pi@raspberrypi:~ $  <- 何事もなければプロンプトに戻ってくる
pi@raspberrypi:~ $ sudo systemctl restart smbd
pi@raspberrypi:~ $ sudo systemctl restart nmbd
pi@raspberrypi:~ $  <- 何事もなければプロンプトに戻ってくる

別マシンのネットワークに、コンピュータとしてRaspberryPiが表示されているはず。
RaspberryPiをダブルクリックした時、Publicフォルダが共有フォルダとして見えていれば成功。
※Windows10の場合、表示されない事があるが、パスを手入力すれば大丈夫。
例1 \\\192.168.1.191\Public
例2 \\\KmyPi\Public

VNC Serverを有効にする。

最近のRaspbianは、VNC Serverを標準で内包している様子。
ただし、設定を有効にしなければ利用できない。

RaspberryPiのGUI画面にて、
「左上のraspberryアイコン」→「設定」→「Raspberry Piの設定」
とクリックし、
インターフェイス」→「VNCを有効」
と設定してから、右下の「OK」をクリック

上記設定を有効にした後、別PCのVNC ClientからIPアドレスでアクセスすると、RaspberryPi側のGUI画面が表示されるはず。

Lチカで動作確認

C言語でWiringPiライブラリを利用したI/O制御ができるか否か、動作チェック
まずは、適当なディレクトリに下記のソースコードを作成。

■C:GPIO17_blink_test.c

#include <wiringPi.h>
#define GPIO17 17
  
int main(void) {
    int i;
  
    if(wiringPiSetupGpio() != 0) {
        return 1;
    }
  
    pinMode(GPIO17, OUTPUT);
  
    for(i=0; i<10; i++){
        digitalWrite(GPIO17, 1);
        delay(500);
        digitalWrite(GPIO17, 0);
        delay(500);
    }  
    return 0;
}

作成出来たらコンパイル
コンパイルコマンド実行ディレクトリは、ソースコードが配置されているディレクトリであることに注意。

pi@raspberrypi:~ $ gcc -g ./GPIO17_blink_test.c -lwiringPi -o GPIO17_blink_test.exe
pi@raspberrypi:~ $  <- 何事もなければプロンプトに戻ってくる

RaspberryPiのGPIO17と隣のGNDの間に、LEDと抵抗を接続。
LEDは抵抗側がアノード、GND側がカソードになるように接続する事。

GPIO17(Pin 11) → 抵抗(1Kオーム程度)→ LED → GND(Pin 9)
参考資料:https://iot.keicode.com/raspberry-pi/pinout.php

上記の接続ができたら、プログラム実行!

pi@raspberrypi:~ $  ./GPIO17_blink_test.exe

LEDが点滅すれば成功。

RaspberryPiでOpenCV開発

RaspberryPiでOpenCV開発

RaspberryPi OS【Buster】でOpenCV開発を行うための手順を記録。
標準対応のC++で環境を構築

OpenCVのインストール

下記のコマンドを実施

pi@raspberrypi:~ $ sudo apt-get install libopencv-dev

サンプルソースコード作成

参考資料 → https://qiita.com/vs4sh/items/4a9ce178f1b2fd26ea30

#include <opencv2/opencv.hpp>

int main(int argh, char* argv[])
{
    cv::VideoCapture cap(0);//デバイスのオープン
    //cap.open(0);//こっちでも良い.

    if(!cap.isOpened())//カメラデバイスが正常にオープンしたか確認.
    {
        //読み込みに失敗したときの処理
        return -1;
    }

    cv::Mat frame; //取得したフレーム
    while(cap.read(frame))//無限ループ
    {
        //
        //取得したフレーム画像に対して,クレースケール変換や2値化などの処理を書き込む.
        //

        cv::imshow("win", frame);//画像を表示.
        const int key = cv::waitKey(1);
        if(key == 'q'/*113*/)//qボタンが押されたとき
        {
            break;//whileループから抜ける.
        }
        else if(key == 's'/*115*/)//sが押されたとき
        {
            //フレーム画像を保存する.
            cv::imwrite("getcam.jpg", frame);
        }
    }
    cv::destroyAllWindows();
    return 0;
}

コンパイル

pkg-configコマンドで、コンパイル情報を取得している。
Makeファイル化するなどしてよしなに。

pi@raspberrypi:~ $ g++ -o hoge.exe hoge.cpp `pkg-config --cflags opencv` `pkg-config --libs opencv`

実行

カメラ映像がGUIのWindowに表示される。
Windowがアクティブな状態で、キーボードの「s」を叩くと写真撮影。
プログラムが配置されているフォルダにgetcam.jpgが作成される。

pi@raspberrypi:~ $ hoge.exe

Raspberry Pi4(Buster)でVNC接続できない

RaspberryPi4 BusterでVNC接続できない(2021年10月30日)

過去、同じ症状に見舞われて解決していたのですが、当時とやり方が違っていて悩んだ。。。。
過去と同じBusterだったのですが、方法が違っています。
過去記事→RaspberryPi4 BusterでVNC接続ができない

再びハマったのでメモ。
VNCで接続できていたはずなのに、「cannot currently show the desktop」と表示される症状の解決策。

SSH接続

SSHクライアントがWindowsマシンなら、TeraTermやRloginで、対象のPi4にSSH接続しましょう。
SSH接続すらできないときは、あきらめてPi4にHDMIディスプレイとキーボードとマウスを接続して設定しましょう。

raspi-configを実行

$ sudo raspi-config

ディスプレイ解像度設定

2 Display Options
   ↓
D1 Resolution
   ↓
DMT Mode 85 1280×720

再起動

設定を行ったら再起動します。

補足(インストールしているRaspberryPi OSのバージョン確認)

$ cat /etc/os-release 

PRETTY_NAME="Raspbian GNU/Linux 10 (buster)"
NAME="Raspbian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"