linux

2021年3月10日 (水)

platfomioを使ってnaitive(linux/windows)のプログラムをビルドする方法

2021/3/10
初版

platformio naitive build

platformio naitive build

概要

platfomioを使ってnaitive(linux/windows)のプログラムをビルドする方法について述べる。
ここでは、platformioがインストール済みを前提とする。
実行環境はubuntuとwindows10を前提にする。

windows10の場合

ここでは既にscoopなどでplatformioがインストール済みとする。
以下の2つのファイルをプロジェクト・デレクトリに用意する:
platformio.ini

; PlatformIO Project Configuration File ; ; Build options: build flags, source filter, extra scripting ; Upload options: custom port, speed and extra flags ; Library options: dependencies, extra library storages ; ; Please visit documentation for the other options and examples ; http://docs.platformio.org/page/projectconf.html [env:windows_x86] # Stable version #platform = windows_x86 # Development version platform = https://github.com/platformio/platform-windows_x86.git

src/main.c

#include <stdio.h> int main() { printf("Hello World from PlatformIO!\n"); return 0; }

ビルド/実行の例:
PowerShell

mkdir win cd win notepad platformio.ini #上の内容になるように編集する。 mkdir src notepad src/main.c #上の内容になるように編集する。 pio run -t clean #必要なツールのダウンロードとインストールが行われる。 # ビルド pio run # 実行 .\.pio\build\windows_x86\program.exe #(実行・出力例) Hello World from PlatformIO!

ubuntuの場合

ここでは既にplatformioがインストール済みとする。
以下の2つのファイルをプロジェクト・デレクトリに用意する:
platformio.ini

; PlatformIO Project Configuration File ; ; Build options: build flags, source filter, extra scripting ; Upload options: custom port, speed and extra flags ; Library options: dependencies, extra library storages ; ; Please visit documentation for the other options and examples ; http://docs.platformio.org/page/projectconf.html [env:linux_x86_64] # Stable version #platform = linux_x86_64 # Development version platform = https://github.com/platformio/platform-linux_x86_64.git

src/main.c

#include <stdio.h> int main() { printf("Hello World from PlatformIO!\n"); return 0; }

ビルド/実行の例:
bash

mkdir pc cd pc gedit platformio.ini #上の内容になるように編集する。 mkdir src gedit src/main.c #上の内容になるように編集する。 pio run -t clean #必要なツールのダウンロードとインストールが行われる。 # ビルド pio run # 実行 ./.pio/build/linux_x86_64/program #(実行・出力例) Hello World from PlatformIO!

参考情報

platformio関連:
windows10にplatformioをインストールする(scoop版)
arduinoフレームワーク用platformio.ini集(linux版PlatformIOのインストール方法)

PlatformIO Core (CLI)
Arduino-IDEとPlatformioのコンパイラーの挙動の違いについて
ubuntu20.04をインストールする

以上

続きを読む "platfomioを使ってnaitive(linux/windows)のプログラムをビルドする方法"

| | コメント (0)

2021年1月 9日 (土)

micro:bit Yotta開発ツール(linux版)

2021/1/9
初版

yotta micro:bit MBED tool

yotta micro:bit MBED tool

概要

micro:bit Yotta開発ツール(linux版)
なお、本ツールは、microbit-v1用である。

インストール手順

mkdir microbit_ws cd microbit_ws # 必要なライブラリやツールをインストールする sudo apt-get update && sudo apt-get install python-setuptools cmake build-essential ninja-build python-dev libffi-dev libssl-dev && sudo easy_install pip # yotta をインストールする sudo pip install yotta # micoribt-samples をダウンロードする git clone https://github.com/lancaster-university/microbit-samples cd microbit-samples # yottaの設定 yt target bbc-microbit-classic-gcc # src/main.cppがターゲットソースになる yt build # ビルド結果(hex)をmicrobitに転送する # <USER>は実際の環境に合わせる cp build/bbc-microbit-classic-gcc/source/microbit-samples-combined.hex /media/<USER>/MICROBIT/

なお、source/examples に他のサンプルがある。

参考情報

Yotta/Installation on Linux

yotta Documentation
yotta: Build Software with Reusable Components

https://os.mbed.com/users/MACRUM/notebook/microbit/
micro:bit の使い方

https://github.com/toyowata/microbit_web_bluetooth/blob/master/README.md
Web Bluetooth(micro:bitとbluetooth接続してブラウザから制御する)

以上

続きを読む "micro:bit Yotta開発ツール(linux版)"

| | コメント (0)

2020年10月20日 (火)

PlatformIOをRaspberryPi4で動かしてみる(実験)

2020/10/20
初版

PlatformIO on RaspberryPi4

PlatformIO on RaspberryPi4

概要

PlatformIOをRaspberryPi4で動かしてみる(実験)。
ターゲットとして、XIAO、M5Atom、Wio-Terminalで、ビルド書き込みを行ってみた。

開発ツールplatformioのRaspberryPiのインストールについてはlinuxでPCのものと同じなので以下を参照のこと:
開発ツールPlatformIOをcliで使う(Seeeduino-XIAO版)
M5Atomを開発ツールPlatformIOで使う(M5Atom/Arduino版)
開発ツールPlatformIOをcli(comand line interface)で使う(v2:Seeeduino-Wio-Terminal/Arduino版)

結果

M5Atomは、問題なく、ビルド書き込みを完了したが tool-bossacを書き込みツールとして利用しているXIAO、Wio-Terminalについては 書き込み終了後、以下のようなエラーを出力して、OS自身が止まってしまい、電源を落としての再起動が必要となる。

<省略> [============================ ] 96% (24/25 pages) [==============================] 100% (25/25 pages) Verify successful Done in 0.085 seconds Message from syslogd@rpi4RED at Oct 20 08:40:11 ... kernel:[25018.731567] Internal error: Oops: 206 [#1] SMP ARM Message from syslogd@rpi4RED at Oct 20 08:40:11 ... kernel:[25018.731842] Process kworker/0:2 (pid: 2233, stack limit = 0xc11d8904) <省略>

書き込み自身は完了しているようだ。

platformio.ini

使用したplatformio.iniは、PCのものと同じだが、RaspberryPi4の場合、/dev/ttyANAが (たぶん)コンソール用に存在しているので、upload_portを明記する必要がある。
XIAO用:

; PlatformIO Project Configuration File ; ; Build options: build flags, source filter ; Upload options: custom upload port, speed and extra flags ; Library options: dependencies, extra library storages ; Advanced options: extra scripting ; ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html [env:seeed_xiao] platform = atmelsam board = seeed_xiao framework = arduino build_flags = -DXIAO upload_protocol = sam-ba upload_port = /dev/ttyACM0 monitor_speed = 115200 lib_ldf_mode = deep+

M5Atom用:

; PlatformIO Project Configuration File ; ; Build options: build flags, source filter ; Upload options: custom upload port, speed and extra flags ; Library options: dependencies, extra library storages ; Advanced options: extra scripting ; ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html [env:m5stick-c] platform = espressif32 board = m5stick-c framework = arduino build_flags = -DM5ATOM upload_port = /dev/ttyUSB0 monitor_speed = 115200 lib_deps = # use M5Atom lib 3113 # use "FastLED" 126 # Accept new functionality in a backwards compatible manner and patches adafruit/Adafruit NeoPixel @ ^1.6.0 lib_ldf_mode = deep+

Wio-Terminal用:

; PlatformIO Project Configuration File ; ; Build options: build flags, source filter ; Upload options: custom upload port, speed and extra flags ; Library options: dependencies, extra library storages ; Advanced options: extra scripting ; ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html [env:seeed_wio_terminal] platform = atmelsam board = seeed_wio_terminal framework = arduino build_flags = -DWIO_TERMINAL upload_protocol = sam-ba upload_port = /dev/ttyACM0 monitor_speed = 115200 lib_ldf_mode = deep+

使用したスケッチ

src/main.ino

#ifdef M5ATOM #include "M5Atom.h" #endif #ifdef M5ATOM #define LED_BUILTIN 21 #endif // the setup function runs once when you press reset or power the board void setup() { // initialize digital pin LED_BUILTIN as an output. pinMode(LED_BUILTIN, OUTPUT); } // the loop function runs over and over again forever void loop() { digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level) delay(100); // wait for a second digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW delay(100); // wait for a second }

ビルド・実行

以下の手順でビルド・実行する:
(platformio.iniは、ボードごとに切り替える)

run pio -t upload

参考情報

headless RaspberryPiインストール方法(v2)

XIAO/M5Atomで気圧センサー(HP206C)を動かす(XIAO/Arduino版、M5Atom/Arduino版)
XIAO/M5AtomでLCD240x240(SPI)を制御する((XIAO/Arduino版、M5Atom/Arduino版)

M5AtomでOLED128x128(SPI)を制御する(Arduino版)
XIAOでOLED128x128(SPI)を制御する(Arduino版)
XIAOでLCD160x80(SPI)を制御する(Arduino版)

以上

続きを読む "PlatformIOをRaspberryPi4で動かしてみる(実験)"

| | コメント (0)

headless RaspberryPiインストール方法(v2)

2020/11/7
オーディオ出力のデフォルト変更法として $HOME/.asoundrcの編集によるものを追加した。

2020/11/3
オーディオ出力のデフォルト変更方法と ubuntuで標準でインストールされている RemminaのようなRealVNC-viewerでない VNC-Viewerでアクセスてきる設定方法を追加した。

2020/10/26
オーディオ出力のデフォルトをHDMIから
フォンジャックに切り替える方法を追加した。

2020/10/19+
第2版
旧記事に対して、ブートSD作成ツールが提供されたので、
それのインストール方法などが変更になった。
また、WiFi環境の改善に効果があった
WiFi中継器の利用についての記載を追加した。
あと、VNCの設定方法について追加した。

headless RaspberryPi(v2)

headless RaspberryPi(v2)

概要

headless RaspberryPiインストール方法(v2)
本記事は「headless RaspberryPiインストール方法」を見直しをかけた第2版にあたる。
表示装置を接続しないでPCを運用することをheadlessというが、ここでは、最初のbootからRaspberryPiをheadlessで使う方法についてまとめた。基本的には本家siteのドキュメントにあるとおりだが、それに必要なものを追加した。
なお、ホストPCとしては、ubuntu20.04を想定している。

前記事からインストール例などの一部は割愛したので、必要があれば第1版の記事を参照のこと。

事前準備(clientPC側)

以下のdeamonをインストールする:

sudo apt-get update sudo apt-get install avahi-daemon

sshのポートを開くための設定:

sudo ufw allow ssh

ブートSD作成ツールのインストール(clientPC側)

cd ~/Downloads sudo apt update sudo apt upgrade wget https://downloads.raspberrypi.org/imager/imager_1.4_amd64.deb sudo dpkg -i imager_1.4_amd64.deb

ブートSD作成ツールの実行

1.rasrberryのOSを書き込むSDをSDソケットに指す。 2.「アプリケーションを表示する」アイコンを押する。 そのなかからraspberryアイコンのImagerを探してクリックして起動する。 3.GUIとしては、3つのボタンが表示され、 左から順に[CHOOSE OS],[CHOOSE SDCARD],[WRITE]となっている。 (1)[CHOOSE OS]を押してOSの種類を選択する (2)[CHOOSE SDCARD]を押して書き込むSDのドライブを選択する (3)上の2つの選択にミスがないことを確認したら[WRITE]を押す。 (4)ダウンロードしながら書き込むので時間がかかるが、辛抱強く、メッセージが表示されるまで待つ。 (5)書き込みが終了したら、SDを抜く。 (6)書き込みツールを終了する。

注意:linux(gparted)でFAT32フォーマットしたSDを利用するとブートできないSDになることがあるようなので、新規SDかwindowsで正式なフォーマット・ツールでフォーマットしたSDを使用することを勧める。

boot/rootfsディレクトリのファイル追加/修正

書き込んだSDをいったん取り外し、再度、挿入する。 すると、bootディレクトリとrootfsディレクトリが出現する。

bootディレクトリに対して以下を行なう:
(1)ssh有効化
bootにsshという名前のファイルを作成する。(ファイル内容は空で良い)

(2)wireless設定
bootにwpa_supplicant.confという名前で 以下の内容のファイルを作成する:

wpa_supplicant.conf
(複数のSSIDを設定する例)

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev update_config=1 country=JP network={ ssid="<Name of your WiFi>" psk="<Password for your WiFi>" priority=1 id_str="<ID1(任意)>" } network={ ssid="<Name of your WiFi>" psk="<Password for your WiFi>" priority=2 id_str="<ID2(任意)>" }

接続するssidの方式はWAPかWPA2であること
(WEPでは接続できないようだ)
また、WiFi中継器を利用する場合、SSIDは一つしか持てないので 一つのSSIDの設定にする。

rootfsディレクトリに対して以下を行なう:
(3)必要があれば、hostnameを変更するために
以下の2つのファイルに記述されているhostnameを
新しいものにエディタで変更(編集)する。
(書き込み権限が必要なので「sudo」を付ける必要がある)

#「raspberrypi」を任意の名前に変更する # USERは自分の環境に合わせる sudo nano /media/USER/rootfs/etc/hostname sudo nano /media/USER/rootfs/etc/hosts

(4)該当SDを取り出す
boot,rootfsをアンマウントする。

Boot

書き込んだSDをRaspberryPiのボードに刺し、電源をオンする。(起動する)
ボードのLEDが点滅し始めて、常灯するまで待つ。

Ping

ホストPCで接続を確認するために
(名前解決に時間がかかるので)
以下のコマンドを成功するまで繰り返す。
ping raspberrypi.local
(rastberrypiはhostnameなので、hostnameを変更した場合 変更したもので置き換える)

出力ログ例:

$ ping raspberrypi.local PING raspberrypi.local (192.168.0.26) 56(84) bytes of data. 64 bytes from 192.168.0.26: icmp_seq=1 ttl=64 time=39.4 ms 64 bytes from 192.168.0.26: icmp_seq=2 ttl=64 time=78.2 ms 64 bytes from 192.168.0.26: icmp_seq=3 ttl=64 time=10.0 ms 64 bytes from 192.168.0.26: icmp_seq=4 ttl=64 time=9.81 ms 64 bytes from 192.168.0.26: icmp_seq=5 ttl=64 time=18.9 ms ^C --- raspberrypi.local ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 4005ms rtt min/avg/max/mdev = 9.816/31.306/78.254/25.833 ms

どうしても接続確認ができないようなら「arp -a」を入力して、接続中のPCのIPアドレスを表示させて、 RaspberryPiのIPアドレスを推定する。

Login

接続確認が終わったら以下のコマンドを入力してloginする:
(デフォルトのパスワードはraspberry)

ssh pi@raspberrypi.local または ssh -Y pi@raspberrypi.local (接続後にグラフィクス・アプリを使用する場合)

ログイン中(ログ出力例):

$ uname -a Linux rpi4RED 5.4.51-v7l+ #1333 SMP Mon Aug 10 16:51:40 BST 2020 armv7l GNU/Linux $ df Filesystem 1K-blocks Used Available Use% Mounted on /dev/root 29629308 5962032 22376368 22% / devtmpfs 1827808 0 1827808 0% /dev tmpfs 1959904 0 1959904 0% /dev/shm tmpfs 1959904 16836 1943068 1% /run tmpfs 5120 4 5116 1% /run/lock tmpfs 1959904 0 1959904 0% /sys/fs/cgroup /dev/mmcblk0p1 258095 55202 202894 22% /boot tmpfs 391980 0 391980 0% /run/user/1000 pi@rpi4RED:~ $ $ ls Bookshelf # 他のディレクトリが欠落しているbug? # 以下のコマンドで修復できる mkdir Desktop mkdir Documents mkdir Downloads mkdir Music mkdir Pictures mkdir Public mkdir Templates mkdir Videos #---------------- # ネットワーク関連 $ ifconfig # 有線LAN(eth0)と無線LAN(wlan0)が接続している例 eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.0.13 netmask 255.255.255.0 broadcast 192.168.0.255 inet6 fe80::6947:928f:1597:e39a prefixlen 64 scopeid 0x20<link> ether dc:a6:32:71:b9:36 txqueuelen 1000 (Ethernet) RX packets 68034 bytes 97542048 (93.0 MiB) RX errors 0 dropped 1 overruns 0 frame 0 TX packets 119086 bytes 118526890 (113.0 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1000 (Local Loopback) RX packets 10144 bytes 110736824 (105.6 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 10144 bytes 110736824 (105.6 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.0.18 netmask 255.255.255.0 broadcast 192.168.0.255 inet6 fe80::4916:271b:edd7:5686 prefixlen 64 scopeid 0x20<link> ether dc:a6:32:71:b9:37 txqueuelen 1000 (Ethernet) RX packets 46823 bytes 3242821 (3.0 MiB) RX errors 0 dropped 1 overruns 0 frame 0 TX packets 66 bytes 8978 (8.7 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 $ iwconfig # wlan0が有効になっている例 eth0 no wireless extensions. wlan0 IEEE 802.11 ESSID:"xxxxxxxxxxxx" Mode:Managed Frequency:2.442 GHz Access Point: 00:1D:73:1D:0A:08 Bit Rate=24 Mb/s Tx-Power=31 dBm Retry short limit:7 RTS thr:off Fragment thr:off Power Management:on Link Quality=56/70 Signal level=-54 dBm Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:0 Tx excessive retries:1 Invalid misc:0 Missed beacon:0 lo no wireless extensions. $ sudo iwlist scan | grep ESSID # 見えているSSIDを表示した例 eth0 Interface doesn't support scanning. ESSID:"2CxxxxxxxxxxxxxxxxxxxxxxxxxxxF3" ESSID:"001xxxxxx08" ESSID:"2CxxxxxxxxxxxxxxxxxxxxxxxxxxxF3" ESSID:"5Dxxxxxxxxxx5E" lo Interface doesn't support scanning. ESSID:"rsxxxxxxxxxxxx2" ESSID:"rsxxxxxxxxxxxx1" # SSIDは伏せ文字にしている

グラフィクス・アプリ起動例

ssh -Y pi@raspberrypi.local geany & sudo apt install scratch scratch & sudo apt install leafpad leafpad &

chromeのインストール

sudo apt install chromium-browser chromium-browser &

node.jsとrubyのインストール

sudo apt install nodejs sudo apt install ruby

C#のインストール

sudo apt install mono-complete mcs --version Mono C# compiler version 5.18.0.240 csharp Mono C# Shell, type "help;" for help Enter statements below. csharp> Environment.OSVersion Unix 4.19.75.0 csharp> Ctrl-D

bluetoothのインストール例

sudo apt install -y pi-bluetooth sudo reboot bluetoothctl Agent registered [bluetooth]# scan on Discovery started #出力例 [CHG] Controller B8:27:EB:43:FE:83 Discovering: yes [NEW] Device 57:80:9B:6B:4C:EC 57-80-9B-6B-4C-EC [NEW] Device 5F:55:F2:80:A7:2B 5F-55-F2-80-A7-2B [NEW] Device CE:EA:67:62:B6:7B Bryton Cadence [CHG] Device 57:80:9B:6B:4C:EC RSSI: -67 [CHG] Device 57:80:9B:6B:4C:EC RSSI: -81 Ctrl-D [bluetooth]# quit pi@raspberrypi:~ $

VNC-serverの設定

VNC-severを使用する場合、
「sudo raspi-config」を実行して 以下の値に設定する:

設定値: ・3 Boot Options B1 Desktop / CLI B4 Desktop Autologin Desktop GUI, automatically logged in as 'pi' user ・5 Interfacing Options P3 VNC ⇒ Enable  ・7 Advanced Options A5 Resolution DMT Mode 85 1280x720 60Hz 16:9    (使用しているモニターのサイズに合わせて7種類から選択する)

設定後、rebootする。
なお、上の設定でなく「Login Desktop GUI」(Autoでない)でも良い。

VNC-severについては、以下の記事を参考した:
【解決】Raspberry Pi4 VNC接続で画面が出ない!!

なお、ホストPC側のRealVNC-viewerは以下のurlからダウンロードできる: https://www.realvnc.com/en/connect/download/viewer/linux/

ダウンロードしたファイルは実行形式なので実行属性を与えて実行する。

headlessといえども、VNCを使用するとGUIのディスクトップが利用できるのは便利である。

また、ubuntuで標準でインストールされているRemminaのような(RealVNC-Viewerでない)VNC-Viewerの場合は このままでの設定では接続できない。そのため、Remminaなどを使用する場合は、以下を実行して設定を UNIX_passwordからVNC_passwordによるログインに変更する。
以下を実行する:

1. Open the /root/.vnc/config.d/vncserver-x11 config file. (sudo nano /root/.vnc/config.d/vncserver-x11 config) 2. Replace Authentication=SystemAuth with Authentication=VncAuth and save the file. 3. In the command line, run sudo vncpasswd -service. This will prompt you to set a password, and will insert it for you in the right config file for VNC Server running in Service Mode. (sudo vncpasswd -service) 4. Restart VNC Server. (sudo reboot)

参照:
VNC (Virtual Network Computing) - Raspberry Pi Documentation

GUIによる設定変更の場合は以下を参照のこと:

http://penguin.tantin.jp/hard/blog/2018-12-25/Raspberry%20Pi%E3%81%ABVNC%E3%81%A7%E6%8E%A5%E7%B6%9A.html blog/2018-12-25/Raspberry PiにVNCで接続 抜粋: 「 https://raspberrypi.stackexchange.com/questions/68838/i-failed-to-remote-connect-to-raspberry-pi-3-from-ubuntu failed to remote connect to Raspberry Pi 3 from Ubuntu このページに書いてあるとおり, Raspberry Piの右上にVNCのアイコンがあるのでそこをクリックして,「Options」をクリックすると設定画面になる. そこの「Security」というところで「Authentication」というところを「VNC Password」にする VNCパスワードを設定しろと言われるので設定する. PC側からRemminaでアクセスするとこのVNC Passwordを聞かれるので入力すると繋がる 」

オーディオ出力のデフォルトをフォンジャックにする

インストール直後はheadlessなのでHDMIが見えていない状態になっているので オーディオ出力のデフォルトはフォンジャックになっている:

$ aplay -l **** List of PLAYBACK Hardware Devices **** card 0: Headphones [bcm2835 Headphones], device 0: bcm2835 Headphones [bcm2835 Headphones] Subdevices: 8/8 Subdevice #0: subdevice #0 Subdevice #1: subdevice #1 Subdevice #2: subdevice #2 Subdevice #3: subdevice #3 Subdevice #4: subdevice #4 Subdevice #5: subdevice #5 Subdevice #6: subdevice #6 Subdevice #7: subdevice #7

ところがVNCなどでdesktop用アプリなどをインストールすると以下に変わる:
(HDMIが有効になり、それがデフォルトになる)

$ aplay -l **** ハードウェアデバイス PLAYBACK のリスト **** カード 0: b1 [bcm2835 HDMI 1], デバイス 0: bcm2835 HDMI 1 [bcm2835 HDMI 1] サブデバイス: 4/4 サブデバイス #0: subdevice #0 サブデバイス #1: subdevice #1 サブデバイス #2: subdevice #2 サブデバイス #3: subdevice #3 カード 1: Headphones [bcm2835 Headphones], デバイス 0: bcm2835 Headphones [bcm2835 Headphones] サブデバイス: 4/4 サブデバイス #0: subdevice #0 サブデバイス #1: subdevice #1 サブデバイス #2: subdevice #2 サブデバイス #3: subdevice #3

これを解決するために:
RaspberryPiでUSBスピーカーをデフォルトの音声出力デバイスにする
上のやり方を参考にして、 RaspberryPiでフォンジャックをデフォルトに戻す。
(具体的には、/usr/share/alsa/alsa.confの内容を修正する)
こうすると今までHDMIに流れていて(フォンジャックでは)無音になっていたアプリが正常に鳴るようになる。
実行例:

$ cvlc http://us3.internet-radio.com:8485/ VLC media player 3.0.11 Vetinari (revision 3.0.11-0-gdc0c5ced72) [01597240] vlcpulse audio output error: PulseAudio server connection failure: Connection refused # 上の行でエラーが出ているが正常に音は鳴るようだ [015b43e8] dummy interface: using the dummy interface module... [b2a01dd0] prefetch stream error: unimplemented query (264) in control

オーディオ出力先のデフォルト変更

上でフォンジャックへの変更方法を述べたが、ここでは、もっと汎用的にデフォルトを変更する方法について紹介する。(以下のリンクを参照のこと)

Headless_RaspberryPiでAudio出力のデフォルトを変更する
RaspberryPiでBluetoothAudio(A2DP)を使用する

上の方法は、GUIのVolumeアイコンでデフォルトを変更しているが、 ALSAデバイス限定であれば$HOME/.asoundrcを以下のように修正することでデフォルト変更できる。(bluetooth-audioは対象外)
以下の内容のcard番号「card 1」をデフォルトにしたいデバイスのものに変更する。
$HOME/.asoundrc

pcm.!default { type asym playback.pcm { type plug slave.pcm "output" } capture.pcm { type plug slave.pcm "input" } } pcm.output { type hw card 1 } ctl.!default { type hw card 1 }

カード番号は「aplay -l」を実行すると カード番号と対応しているデバイス名が表示されるので デフォルトにしたいデバイスのカード番号を知ることができる。
(bluetooth-audioの場合、修正内容が異なるので、ここでは対象外としている)

WiFi中継器の利用

以下のような高速WiFi中継器を利用するとraspberryのネットワーク接続の安定性や速度の向上を実現できる。

11n対応無線LAN中継器

入手したものは、有線LAN経由でWiFi接続する機能があるので、WiFiのないraspberryや、WiFiがあっても環境の問題でWiFi接続性が悪い場合、有線LANを利用すると安定性と速度の向上が期待できる。

Rpi4などは、旧モデルよりも有線LANの側道が向上しているせいか、実際に利用した印象では、ネットワーク速度が向上している。なので、WiFiがあるRpi4でも有線LAN経由でWiFi接続したほうが良いと思われる。

すでに設定してあるSSIDを変更せずに中継するので、新規に設定する必要があるのはWiFi中継器だけなので、使い勝手も良い。

参考:
WiFi中継器を使っている場合、親機と子機(中継器)で同じSSIDを使っているので、以下のように同じSSIDが2つ見える。

$ sudo iwlist scan | grep ESSID eth0 Interface doesn't support scanning. タブっているSSID → ESSID:"2CxxxxxxxxxxxxxxxxxxxxxxxxxxxF3" ESSID:"001xxxxxx08" ダブっているSSID → ESSID:"2CxxxxxxxxxxxxxxxxxxxxxxxxxxxF3" ESSID:"5Dxxxxxxxxxx5E" lo Interface doesn't support scanning. ESSID:"rsxxxxxxxxxxxx2" ESSID:"rsxxxxxxxxxxxx1" # SSIDは伏せ文字にしている

また、以下のようにpingを使用して、その出力にWiFi中継器の型番(本件の場合は、wrc-300febk-r)が含まれていれば、中継機能が動作していることを意味する。
# 型番の出現頻度は不明なので、比較的長めに出力しないと分からないかもしれない。

$ ping google.com PING google.com (172.217.175.14) 56(84) bytes of data. 64 bytes from google.com (172.217.175.14): icmp_seq=1 ttl=116 time=19.3 ms 64 bytes from google.com (172.217.175.14): icmp_seq=2 ttl=116 time=40.2 ms <省略> 64 bytes from google.com (172.217.175.14): icmp_seq=10 ttl=117 time=19.6 ms # 以下の行に型番が出現している From wrc-300febk-r.setup (192.168.0.5): icmp_seq=11 Redirect Host(New nexthop: 192.168.0.1 (192.168.0.1)) 64 bytes from google.com (172.217.175.14): icmp_seq=11 ttl=117 time=16.3 ms <省略> ttl=117 time=18.3 ms ^C

接続実績:
以下のモデルの接続を確認した:

Raspberry Pi 1 Model B (有線LAN接続) Raspberry Pi 2 Model B (追加:WiFi_USBdongle) Raspberry Pi 4 Model B (WiFi接続) Raspberry Pi Zero WH (WiFi接続)

DNS Bug?

まれに、DNSが動かなくなる場合がある。そのときは以下の手順で復活する。
(経験的な話になるが、自然に普及したこともある)

sudo nano /etc/network/interfaces # /etc/network/interfacesの末尾に以下の1行を追加する: dns-nameservers 8.8.8.8 8.8.4.4 # rebootする sudo reboot

本問題については以下を参照のこと:
https://raspberrypi.stackexchange.com/questions/4275/dns-resolution-failure
DNS resolution failure

復活の確認は以下のようにpingする。
例:

ping google.com ping nifty.com

Home Directories Bug?

fullイメージのSDで起動した場合、「Raspberry Pi 4 Model B」では、/home/piには以下の状態になっていた。

$ ls Bookshelf

他のボードでは、以下のようなディレクトリができる:

$ ls Desktop Documents Bookshelf Pictures Templates Downloads Music Public Videos

たぶん、「Raspberry Pi 4 Model B」では、初ブート時にディレクトリを作成するスクリプトがエラーになっていると推測する。 空のディレクトリを作っているだけなので、必要があれば、シェルのコマンドでディレクトリを作れば良いだけだと思う。

参照URL

configuration/wireless/headless
configuration/wireless/wireless-cli
remote-access/ssh/unix
How to open ssh port using ufw on Ubuntu/Debian Linux

以上

続きを読む "headless RaspberryPiインストール方法(v2)"

| | コメント (0)

2020年10月15日 (木)

wio-terminalのファームウェア・アップデートについて(linux版)

2020/10/15

wio-terminal firmware update(linux)

wio-terminal firmware update(linux)

概要

wio-terminalのファームウェア・アップデートについて(linux版)
linuxでのwio-terminalのファームウェア・アップデート方法について記載する。

手順

以下を実行する:

cd ~/Downloads wget http://files.seeedstudio.com/wiki/Wio-Terminal/res/rtl8720_update.uf2 wget https://files.seeedstudio.com/wiki/Wio-Terminal/res/20200730-rtl8720d-images-v2.2.0.2.zip unzip 20200730-rtl8720d-images-v2.2.0.2.zip wget http://files.seeedstudio.com/arduino/tools/amebad_flash_tool/amebad_flash_tool_v0.1.0_linux.tar.gz tar zxvf amebad_flash_tool_v0.1.0_linux.tar.gz # wio-terminalをUSB接続する # wio-terminalの電源スイッチを素早く2度押す(bootloader-modeにする) # Arduinoのディレクトリが出現する(以下のUSERは自分の環境に合わせる) cp rtl8720_update.uf2 /media/USER/Arduino/ ./amebad_flash_tool erase --port /dev/ttyACM0 ./amebad_flash_tool flash -d 20200730-rtl8720d-images-v2.2.0.2 --port /dev/ttyACM0

以上の手順でファームウェア・アップデートが完了する。

実行例

$ cp rtl8720_update.uf2 /media/USER/Arduino/ $ ./amebad_flash_tool erase --port /dev/ttyACM0 Erasing... All images are sent successfully! Image tool closed! done! # 意外と時間がかかるので、辛抱強く待つ。。 $ ./amebad_flash_tool flash -d 20200730-rtl8720d-images-v2.2.0.2 --port /dev/ttyACM0 copy img to workspace... Flashing... All images are sent successfully! Image tool closed! done! # ここでファームウェアの書き込みが終了する

参考情報

https://wiki.seeedstudio.com/Wio-Terminal-Network-Overview/
Update the Wireless Core Firmware

以上

続きを読む "wio-terminalのファームウェア・アップデートについて(linux版)"

| | コメント (0)

2020年10月 8日 (木)

Teensy3.6ボードでTinyGOを動かす

2020/10/8:
初版

TinyGO Install Teensy3.6

TinyGO Install Teensy3.6

概要

以下のTeensy3.6ボードでTinyGOを動かす。
tinygo_0.15.0でteensy3.6がサポートされたので、それをインストールして使ってみる。
まだ、実装途上のようで、GPIO,UARTのみのようである。USBシリアル(USB CDC serial port)はサポートされない。
なお、ホストPCとしてはubuntu20.04を想定している。

Teensy 3.6

準備

以下のツールを予めインストールする:
(0)udev設定
以下を実行する:

curl -fsSL https://raw.githubusercontent.com/platformio/platformio-core/master/scripts/99-platformio-udev.rules | sudo tee /etc/udev/rules.d/99-platformio-udev.rules sudo udevadm control --reload-rules sudo usermod -a -G dialout $USER sudo usermod -a -G plugdev $USER

(1)TinyGOのインストール
以下の手順でインストールする:

mkdir tinygo_ws cd tinygo_ws wget https://github.com/tinygo-org/tinygo/releases/download/v0.15.0/tinygo_0.15.0_amd64.deb sudo dpkg -i tinygo_0.15.0_amd64.deb export PATH=$PATH:/usr/local/tinygo/bin # xiaoには不要だが、ターゲットがarduinoのときに # 必要となるツールをついでにインストールする sudo apt-get install gcc-avr sudo apt-get install avr-libc sudo apt-get install avrdude

(2)GOのインストール
TinyGOのモジュールを使用するのにGOが必要なので 予めインストールする。
(ただし、TinyGOとの整合性により最新版ではない)

wget https://dl.google.com/go/go1.13.7.linux-amd64.tar.gz sudo tar -C /usr/local -xzf go1.13.7.linux-amd64.tar.gz export PATH=$PATH:/usr/local/go/bin export GOPATH=$HOME/tinygo_ws

なお、GOPATHのパス設定値は、任意だが、それをベースに その配下にTinyGO/GOの関係ファイル/ディレクトリが置かれる。

(3)teensy書き込みツールのインスール
以下の手順でインストールする:

mkdir teensy_loader_cli cd teensy_loader_cli sudo apt-get install libusb-dev wget https://raw.githubusercontent.com/PaulStoffregen/teensy_loader_cli/master/Makefile wget https://raw.githubusercontent.com/PaulStoffregen/teensy_loader_cli/master/teensy_loader_cli.c make sudo cp teensy_loader_cli /usr/bin/

以上のexportは、.bashrcに登録する。

(4)export登録(まとめ)
以下を.bashrcに追加する:

# tinygo/go export PATH=$PATH:/usr/local/go/bin export PATH=$PATH:/usr/local/tinygo/bin export GOPATH=$HOME/tinygo_ws export TIGOLIBS=$GOPATH/src/tinygo.org/x/drivers/

examples/blinky1を動かす

teensy3.6ボードをPCに接続して、以下を実行する:

tinygo flash -size full -target teensy36 examples/blinky1 <省略> (hint: press the reset button) #以上のメッセージが表示されたら、ボードのRESETボタンを押す <省略> Programming........ Booting

コンパイルと書き込み実行が自動的に行われ、ボードのLEDが点滅する。

任意のプログラムを動かす

(1)以下のようにプロジェクト用ディレクトリを作成する:

cd tigo_ws mkdir blink cd blink

(2)プロジェクト(blink)ディレクトリに以下のファイルを作成する:
main.go

package main // This is the most minimal blinky example and should run almost everywhere. import ( "machine" "time" ) func main() { led := machine.LED led.Configure(machine.PinConfig{Mode: machine.PinOutput}) for { led.Low() time.Sleep(time.Millisecond * 100) led.High() time.Sleep(time.Millisecond * 100) } }

(3)ビルド実行
teensy3.6ボードをPCに接続して以下を実行する:

tinygo flash -size full -target teensy36 . <省略> (hint: press the reset button) #以上のメッセージが表示されたら、ボードのRESETボタンを押す <省略> Programming........ Booting

コンパイルと書き込み実行が自動的に行われ、ボードのLEDが点滅する。
(example/blinky1と区別しにくいと思うので、点滅周期を変更して実行してみる)

参考情報

Teenst3.6 Pinout:
https://cdn.sparkfun.com/datasheets/Dev/Arduino/Boards/teensy36_front.pdf
https://cdn.sparkfun.com/datasheets/Dev/Arduino/Boards/teensy36_back.pdf

https://github.com/tinygo-org/tinygo
https://tinygo.org/
https://tinygo.org/getting-started/linux/

Seeeduino XIAO用Grove シールド バッテリー管理チップ 搭載

ESP32 and ESP8266 support in TinyGo

コンピュータボードでTinyGOを動かす
docker/TinyGO Helper Script
TinyGOでLightSensorを動かす

TinyGoで始める組み込みプログラミング
TinyGo on Arduino Uno: An Introduction

Circuit Playground Express
Adafruit Circuit Playground Express - Overview
Infrared Receive and Transmit with Circuit Playground Express

Adafruit Circuit Playground Express - PINOUT
Adafruit Circuit Playground Express Pin Assign

NUCLEO-F103RB mbed pinout
NUCLEO-F103RB Pin Assign
STM32F4DISCO Pin Assign
MICROBIT Pin Assign
ARDUINO-NANO Pin Assign
ARDUINO Pin Assign

TinyGo Drivers

USB Flashing Format (UF2)

XIAO Schematic(zip)
How to use Seeeduino XIAO to log in to your Raspberry PI

以上

続きを読む "Teensy3.6ボードでTinyGOを動かす"

| | コメント (0)

2020年9月18日 (金)

翻訳支援ツールOmegaT(linux版)をインストールする

2020/9/18:
初版

OmegaT install

OmegaT install

概要

翻訳支援ツールOmegaT(linux版)をインストールする

download

https://omegat.org/download
上のurlからダウンロードするが自分の環境にあったものをダウンロードする:
・JREのバージョンの違いで動作しないことがないように「with JRE」が付いているものを選択する。
・「64-bit」が付いているものと、そうでないものがあるで、自分の環境に合わせて選択する。
・「Standard Version - OmegaT 4.3.2」と「Latest Version - OmegaT 5.3.0」があるので、どちらかを選択する。

自分の環境の場合、以下のものを選択した:
「Linux with 64-bit JRE」(Standard Version - OmegaT 4.3.2)

ダウンロードが終了すると以下のファイルがダウンロードできる:
OmegaT_4.3.2_Linux_64.tar.bz2

install

以下を実行してインストールする:

cc Download tar -jxvf OmegaT_4.3.2_Linux_64.tar.bz2 cd OmegaT_4.3.2_Linux_64 sudo ./linux-install.sh

実行

omegat

ubuntuの環境で動かしたが バージョンが古いとエラーで動作しない。
(16.04では動作しなかった.インストール状況の問題の可能性あり)
ubuntu_18.04では正常動作した。

参考情報

https://ja.wikipedia.org/wiki/OmegaT
OmegaT

https://ja.wordpress.org/team/handbook/support/omegat/
翻訳エディター OmegaT の使用方法

https://omegat.org/ja/howtos/linux
OmegaT 技術情報:Linux

以上

続きを読む "翻訳支援ツールOmegaT(linux版)をインストールする"

| | コメント (0)

2020年9月 6日 (日)

「ATOMIC GPSキット (M8030-KT)」を使用してみる(M5Atom/Arduino版)

2020/9/9:
スケッチ改良

2020/9/6:
初版

PlatformIO M5Atom GPS kit

PlatformIO M5Atom GPS kit

概要

以下の「ATOMIC GPSキット (M8030-KT)」を使用してみる(M5Atom/Arduino版)
開発ツールのインストールについては「M5Atomを開発ツールPlatformIOで使う(M5Atom/Arduino版)」を参照のこと。 (ホストPCとしてはubuntuを想定している)

ATOMIC GPSキット (M8030-KT)

platformio.ini

platformio.iniを以下のように編集する:

; PlatformIO Project Configuration File ; ; Build options: build flags, source filter ; Upload options: custom upload port, speed and extra flags ; Library options: dependencies, extra library storages ; Advanced options: extra scripting ; ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html [env:esp32dev] platform = espressif32 board = m5stick-c framework = arduino monitor_speed = 115200 lib_deps = # use M5Atom lib 3113 # use "FastLED" 126 lib_ldf_mode = deep+

デモ・スケッチのダウンロード

プロジェクトフォルダで以下を実行する:

cd src wget https://raw.githubusercontent.com/m5stack/M5-ProductExampleCodes/master/AtomBase/AtomicGPS/AtomicGPS.ino wget https://raw.githubusercontent.com/m5stack/M5-ProductExampleCodes/master/AtomBase/AtomicGPS/GPSAnalyse.cpp wget https://raw.githubusercontent.com/m5stack/M5-ProductExampleCodes/master/AtomBase/AtomicGPS/GPSAnalyse.h

スケッチ修正

ダウンロードしたスケッチAtomicGPS.inoを以下の修正点に対応して変更する:

修正点:
(1)コンパイルスイッチでNMEA出力のサポート
(2)SDに出力するログ(緯度経度など)の精度向上
(3)M5.disでのコンパイルエラー修正
(4)USBシリアルの速度設定
(5)有効な緯度経度情報のみをログする
(6)ログ出力に簡易なフィルタ処理を施す

src/AtomicGPS.ino(編集済み)

/*This is an example used SerialBT,you can can view gps data by connecting * to Bluetooth assistant on your mobilephone or Serial Monitor * the GPS log will be written to SD card * */ // do effective when you want NMEA out //#define NMEA_OUT #define deltaLat 0.001 #define deltaLon 0.001 #include "M5Atom.h" #include "GPSAnalyse.h" #include <SPI.h> #include "FS.h" #include <SD.h> #include <BluetoothSerial.h> BluetoothSerial SerialBT; GPSAnalyse GPS; uint64_t chipid; char chipname[256]; const char filename[] = "/GPSdata.txt"; File txtFile; float Lat; float Lon; String Utc; bool writeLog(String filename) { //Write GPSdata to SDcard txtFile = SD.open(filename, FILE_APPEND); if(txtFile){ txtFile.printf("%.5f",Lat); txtFile.print(", "); txtFile.printf("%.5f",Lon); txtFile.print(", "); /* txtFile.print(Lat); txtFile.print(", "); txtFile.print(Lon); txtFile.print(", "); */ txtFile.println(Utc); txtFile.close(); }else{ return false; } return true; } void setup() { M5.begin(true,false,true); chipid = ESP.getEfuseMac(); sprintf( chipname, "SerialBT_%04X", (uint16_t)(chipid >> 32)); Serial.printf("Bluetooth: %s\n", chipname); SPI.begin(23,33,19,-1); if(!SD.begin(-1, SPI, 40000000)){ Serial.println("initialization failed!"); } sdcard_type_t Type = SD.cardType(); Serial.printf("SDCard Type = %d \r\n",Type); Serial.printf("SDCard Size = %d \r\n" , (int)(SD.cardSize()/1024/1024)); // M5.dis.fillpix(0x00004f); M5.dis.drawpix(0,0x00004f); Serial.begin(115200); Serial1.begin(9600,SERIAL_8N1,22,-1); SerialBT.begin(chipname); GPS.setTaskName("GPS"); GPS.setTaskPriority(2); GPS.setSerialPtr(Serial1); GPS.start(); } #ifdef NMEA_OUT void loop() { if (Serial1.available()) { char c = Serial1.read(); Serial.write(c); SerialBT.write(c); } } #endif #ifndef NMEA_OUT float prevLat=0.0; float prevLon=0.0; void loop() { GPS.upDate(); Lat = GPS.s_GNRMC.Latitude; Lon = GPS.s_GNRMC.Longitude; Utc = GPS.s_GNRMC.Utc; SerialBT.printf("Latitude= %.5f \r\n",Lat); SerialBT.printf("Longitude= %.5f \r\n",Lon); SerialBT.printf("DATA= %s \r\n",Utc); Serial.printf("Latitude= %.5f \r\n",Lat); Serial.printf("Longitude= %.5f \r\n",Lon); Serial.printf("DATA= %s \r\n",Utc); if ((Lat != 0)&&(Lon != 0)) { if ((abs(Lat-prevLat)<deltaLat)&&(abs(Lon-prevLon)<deltaLon)) writeLog(filename); // write them when Lat/Lon effective prevLat=Lat; prevLon=Lon; }; delay(1000); } #endif

NMEA出力したい場合、以下を有効(コメントを外す)にする

//#define NMEA_OUT

bluetootシリアル接続

スケッチを実行するとbluetoothデバイスとして、「SerialBT_xxxx」が見えるのでペアリングする。 AndoroidアプリのBluetooth Serial Monitorなどをインストールして実行すると、シリアル出力の内容がAndoroidの画面に表示される。

NEMA出力を有効にした場合、AndoroidアプリのDrogger GPS for DG-PRO1(RW)をインストールして実行してbluetoothシリアルを接続する。 Androidの画面に測位位置の地図表示や衛星の状態などを表示する。

ただし、自分の環境(Hauwei P20 lite)では非常に不安定だった。 とりあえず、参考のため使用した設定を明記する(これが有効だったというわけではなく、あくまでも参考のため)

・自動再接続試行期間:10sec ・接続オプション:すべてオン(3つ) ・NMEA Message Type: GGA,VTG,RMC,SGA,GSV,GLL有効

GPX変換

NMEA出力が有効でない場合、SDにログデータ(GPSdata.txt)ができるが以下の方法でGPXデータに変換できる。

(1)ヘッダーを追加する 最初の行に以下を追加する: latitude,longitude,utc (2)緯度経度データの削除 ログそのものだとデータが多いので不要なデータは削除する。 最初の座標を出発点、最後の座標を目的点とみなすので 移動せずに測位した場合、2点のみにするほうが良い。 (3)以下がweb版のコンバータなので、これを使用して変換する: https://www.gpsvisualizer.com/convert_input

GPXをGoogleMapにインポートする

(1)GoogleMapから「メニュー/マイプレイス/マイマップ」を選択して、 表示されている画面の最下行にある「地図を作成」をクリックする。 (2)表示されている「無題の地図」の「無題のレイヤ」の「インポート」をクリックする。 (3)インポートするファイルの選択の画面が表示されるので、その枠「アップロード」にGPXのファイルをドラッグ&ドロップする。

参考情報

https://intellectualcuriosity.hatenablog.com/entry/2020/07/01/041715
ATOM GPS Kit (M8030-KT)でお手軽Bluetooth GPSレシーバーを作った

https://landmarkforchrist.com/ja/2557-huawei-p20-lite-unlock-developer-options-in-android.html
Huawei P20 Lite Androidの開発者向けオプションのロックを解除

https://akizukidenshi.com/catalog/g/gM-12905/
GPS/GLONASS受信機(Galileo/BeiDou可)u‐blox M8搭載 みちびき3機受信対応

PlatformIO Core (CLI)

以上

続きを読む "「ATOMIC GPSキット (M8030-KT)」を使用してみる(M5Atom/Arduino版)"

| | コメント (0)

2020年8月 9日 (日)

M5Atom(ESP32を含む)でHRセンサーデータを受信する(Arduino版)

2020/8/9:
ChestTypeとWristTypeの両方対応にスケッチを改善した。

2020/8/8+

PlatformIO M5Atom BLE HR Sensor Receiver

PlatformIO M5Atom BLE HR Sensor Receiver

概要

M5Atom(ESP32を含む)でHRセンサーデータを受信する(Arduino版)
開発ツールのインストールについては「M5Atomを開発ツールPlatformIOで使う(M5Atom/Arduino版)」を参照のこと。 (ホストPCとしてはubuntuを想定している)

platformio.ini

platformio.iniを以下のように編集する:

; PlatformIO Project Configuration File ; ; Build options: build flags, source filter ; Upload options: custom upload port, speed and extra flags ; Library options: dependencies, extra library storages ; Advanced options: extra scripting ; ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html [env:esp32dev] platform = espressif32 board = m5stick-c framework = arduino monitor_speed = 115200 lib_deps = # use M5Atom lib 3113 # use "FastLED" 126 lib_ldf_mode = deep+

M5Atom特有のライブラリを使用していないので、ESP32で動作させる場合は 通常のESP32のplatformio.iniで良い。

テスト用スケッチをダウンロードする

cd src wget https://cdn.hackaday.io/files/880553767345120/Pulse.ino

テスト・スケッチ

ダウンロードしたスケッチを以下の修正点に対応して変更する:

修正点:
(1)余計なスペースを削除する
(2)Wrist-TypeのHRセンサー対応を追加する
(3)HRデータを表示する際、タイムスタンプ表示を追加する
(4)LED点滅をコメントアウトする

src/Pluse.ino(編集済み)
#余計なスペースを削除するなど大幅な修正になっているので
#オリジナルを修正するよりも、以下の修正済みのものをコピー&ペーストすることを勧める:

// modified/bufix 2020/8/9 by: xshige #define CHEST //#define WRIST // fix info: // https://github.com/nkolban/esp32-snippets/issues/837 // Using BLE for Heart Rate Monitors, newer belts don't work #837 unsigned long startMillis; /************************************************************************/ /****************** Heart Rate BLE gateway for Technogym ****************/ /************ Outputs a 30 ms pulse at recieved HR frequency ************/ /**************** Indicates the remote HR battery level *****************/ /*********************** Vincent HORN - march 2018 **********************/ /**************************** version 1.0 *******************************/ #include "BLEDevice.h" // Device connection static BLEAddress *pServerAddress; BLEClient* pClient; static boolean doConnect = false; static boolean isconnect = false; // The remote HR service & characteristic static BLEUUID service_HR_UUID(BLEUUID((uint16_t)0x180D)); static BLEUUID char_HR_UUID(BLEUUID((uint16_t)0x2A37)); static BLERemoteCharacteristic* pRemote_HR_Characteristic; const uint8_t notificationOn[] = {0x1, 0x0}; // HR Pulse timer hw_timer_t * timer = NULL; // Timer volatile SemaphoreHandle_t timerSemaphore; // Timer portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;// Timer volatile uint32_t isrCounter = 0; // Timer volatile uint32_t lastIsrAt = 0; // Timer // HR Pulse output int ms_pb = 500; //millis per beat const int pulse_pin = 23; // pulse output pin bool pulse_on = false; // flag when pulse have to be fired unsigned long pulse_off_at = 0; // Time to stop the pulse // The remote BATT service a characteristic static BLEUUID service_BATT_UUID(BLEUUID((uint16_t)0x180F)); static BLEUUID char_BATT_UUID(BLEUUID((uint16_t)0x2A19)); static BLERemoteCharacteristic* pRemote_BATT_Characteristic; // BATT indicator const int battery_scan = 60000; // Scan interval in msec. unsigned long batt_read_start_at = 0; bool batt_indicator = false; // time to indicate de battery level int batt_flash = 0; // number of flash int i_flash = 1; // flash counter bool init_time = true; // flag for init on/off time unsigned long on_at = 0; // Time to turn LED ON unsigned long off_at = 0; // Time to turn LED OFF const int led_pin = 22; // Battery indicator LED static void notifyCallback(BLERemoteCharacteristic* pBLERemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify) { uint8_t HR_val = 0; // RAW HR value //< support both Chest/Wrist type 2020/8/9 by: xshige //if (pData[0] == 22 || pData[0] == 6) { if (pData[0] == 16) { // for Chest Type HR sensor (Polar H10) if (pData[1] > 10 && pData[1] < 254) {// HR must be between 10 and 254 bpm HR_val = pData[1]; } else HR_val =0; } else if (pData[0] == 0) { // for Wrist Type HR sensor (Polar A370, OH1) if (pData[1] > 10 && pData[1] < 254) {// HR must be between 10 and 254 bpm HR_val = pData[1]; } else HR_val =0; } else HR_val = 0; //> // display timestamp(sec) unsigned long currentMillis = millis()-startMillis; //Serial.println(pData[0]); Serial.print(currentMillis/1000); Serial.print(": "); // Serial.print("HR : "); Serial.print(HR_val); Serial.print(" bpm \t Battery : "); Serial.print(batt_flash*10); Serial.println(" %"); if (HR_val != 0) {ms_pb = (int)60000/HR_val;} // interval in ms between 2 heart beat if no value (zero) is recieved, ms_pb is set to 100s } bool connectToServer(BLEAddress pAddress) { Serial.print("Forming a connection to "); Serial.println(pAddress.toString().c_str()); // create a new client pClient = BLEDevice::createClient(); Serial.println("Created client"); // Connect to the remove BLE Server. #ifdef CHEST pClient->connect(pAddress, (esp_ble_addr_type_t)1); // bug fix 2020/8/9 (Chest type can be OK) #endif #ifdef WRIST pClient->connect(pAddress); // Chest can Not be OK #endif Serial.println("Connected to server"); // Obtain a reference to the HR service of the remote BLE server. BLERemoteService* pRemote_HR_Service = pClient->getService(service_HR_UUID); if (pRemote_HR_Service == nullptr) { Serial.print("Failed to find HR service : "); //Serial.println(service_HR_UUID.toString().c_str()); return false; } else Serial.println("Found HR service"); // Obtain a reference to the BATT service of the remote BLE server. BLERemoteService* pRemote_BATT_Service = pClient->getService(service_BATT_UUID); if (pRemote_BATT_Service == nullptr) { Serial.print("Failed to find BATT service : "); //Serial.println(service_BATT_UUID.toString().c_str()); return false; } else Serial.println("Found BATT service"); // Obtain a reference to the HR characteristic in the service of the remote BLE server. pRemote_HR_Characteristic = pRemote_HR_Service->getCharacteristic(char_HR_UUID); if (pRemote_HR_Characteristic == nullptr) { Serial.print("Failed to find HR characteristic : "); //Serial.println(char_HR_UUID.toString().c_str()); return false; } else Serial.println("Found HR characteristic"); // Obtain a reference to the BATT characteristic in the service of the remote BLE server. pRemote_BATT_Characteristic = pRemote_BATT_Service->getCharacteristic(char_BATT_UUID); if (pRemote_BATT_Characteristic == nullptr) { Serial.print("Failed to find BATT characteristic : "); //Serial.println(char_BATT_UUID.toString().c_str()); return false; } else Serial.println("Found BATT characteristic"); // Set notification pRemote_HR_Characteristic->registerForNotify(notifyCallback); pRemote_HR_Characteristic->getDescriptor(BLEUUID((uint16_t)0x2902))->writeValue((uint8_t*)notificationOn, 2, true); } class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks { void onResult(BLEAdvertisedDevice advertisedDevice) { Serial.print("BLE Advertised Device found: "); Serial.println(advertisedDevice.toString().c_str()); // We have found a device, let us now see if it contains the service we are looking for. if (advertisedDevice.haveServiceUUID() && advertisedDevice.getServiceUUID().equals(service_HR_UUID)) { Serial.println("Found Heart Rate device! "); advertisedDevice.getScan()->stop(); pServerAddress = new BLEAddress(advertisedDevice.getAddress()); doConnect = true; } } }; void device_scan(){ // Retrieve a Scanner and set the callback we want to use to be informed when we // have detected a new device. Specify that we want active scanning and start the // scan to run for 15 seconds. BLEScan* pBLEScan = BLEDevice::getScan(); pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); pBLEScan->setActiveScan(true); while (!doConnect) { // Scan till a connection is found Serial.println("Scanning for BLE devices ..."); BLEScanResults foundDevices = pBLEScan->start(15); Serial.print("Devices found: "); Serial.println(foundDevices.getCount()); } } void IRAM_ATTR onTimer(){ // Increment the counter and set the time of ISR portENTER_CRITICAL_ISR(&timerMux); isrCounter++; lastIsrAt = millis(); portEXIT_CRITICAL_ISR(&timerMux); // Give a semaphore that we can check in the loop xSemaphoreGiveFromISR(timerSemaphore, NULL); // It is safe to use digitalRead/Write here if you want to toggle an output } void setup() { Serial.begin(115200); Serial.println("------------------------------------------"); Serial.println("Starting Arduino BLE Client application..."); // initialize pulse_pin as an output //pinMode(pulse_pin, OUTPUT); // initialize battery pin led as an output //pinMode(led_pin, OUTPUT); // initialize timer timerSemaphore = xSemaphoreCreateBinary(); // Create semaphore to inform us when the timer has fired timer = timerBegin(0, 80, true); // Attach onTimer function to our timer. timerAttachInterrupt(timer, &onTimer, true); // initialize BLE BLEDevice::init(""); // Scan for devices device_scan(); startMillis = millis(); } void loop() { // If the flag "doConnect" is true then we have scanned for and found the desired BLE Server with which we wish to connect. if (doConnect == true) { if (connectToServer(*pServerAddress)) { Serial.println("Connected to the BLE Server."); isconnect = true; // First timer set to 10 sec. timerAlarmWrite(timer, 10000000, true); timerAlarmEnable(timer); } else { Serial.println("We have failed to connect to the server; there is nothin more we will do."); isconnect = false; } doConnect = false; } // when interrupt occurres if (xSemaphoreTake(timerSemaphore, 0) == pdTRUE){ uint32_t isrCount = 0, isrTime = 0; // Read the interrupt count and time portENTER_CRITICAL(&timerMux); isrTime = lastIsrAt; isrCount = isrCounter; portEXIT_CRITICAL(&timerMux); // create a 30 ms pulse on pulse_pin pulse_on = true; pulse_off_at = millis() + 30; //digitalWrite(pulse_pin, HIGH); //delay(30); //digitalWrite(pulse_pin, LOW); // rearm the timer with previous incomming ms per beat (ms_pb) value timerAlarmDisable(timer); timerAlarmWrite(timer, 1000*ms_pb, true); timerAlarmEnable(timer); /* Serial.print("at "); Serial.print(isrTime); Serial.print(" ms"); Serial.print("\t new timer "); Serial.print(ms_pb); Serial.println(" ms"); */ } // Create Pulse if (pulse_on) { if (millis() < pulse_off_at) { //digitalWrite(PULSE_PIN, HIGH); // turn the LED on (HIGH is the voltage level) } else { //digitalWrite(PULSE_PIN, LOW); // turn the LED off by making the voltage LOW pulse_on = false; } } // Read the value of the battery level characteristic each battery_scan ms (only if connected) if (isconnect && (millis()-batt_read_start_at > battery_scan)) { std::string value = pRemote_BATT_Characteristic->readValue(); String batt_caracteristic = value.c_str(); // convert string to char char buf[2]; batt_caracteristic.toCharArray(buf, 2); // BATT_val is the numeric ASCII value int BATT_val = int(buf[0]); // batt_flash number of flash (30% battery => 3 flashs) batt_flash = (int)BATT_val/10; // fire the LED batt_indicator = true; batt_read_start_at = millis(); } // Battery indicator if (batt_indicator){ if (i_flash <= batt_flash){ if (init_time){ off_at = millis() + 40; on_at = off_at + 500; init_time = false; } if (millis() <= off_at){ digitalWrite(led_pin, HIGH); } if ((millis() > off_at) && (millis() <= on_at)){ digitalWrite(led_pin, LOW); } else if (millis() > on_at){ init_time = true; i_flash++; } } else { i_flash = 1; batt_indicator = false; } } // Watch if client is still connected. When not reboot ESP32 if (pClient->isConnected() == false) { Serial.println("Device disconnected ! ESP 32 rebooting ....."); ESP.restart(); } }

使用するHRセンサーのタイプで以下の#defineのうち一つを有効にして、コンパイル&実行する。

#define CHEST #define WRIST

書き込み後、実行するとBLEデバイスをスキャンしてHRセンサーが見つかれば自動的にペアリングして、HRデータを表示する。 既にHRセンサーが(スマフォなどと)ペアリング済みだと接続できないので、その場合、該当のスマフォのペアリングを解除する。

出力例:(Polar A370の場合)

picocom /dev/ttyUSB0 -b115200 Starting Arduino BLE Client application... Scanning for BLE devices ... BLE Advertised Device found: Name: Polar A370 1D44A125, Address: a0:9e:1a:1d:44:a1, manufacturer data: 6b002f0000, serviceUUID: 0000180d-0000-1000-8000-00805f9b34fb Found Heart Rate device! Devices found: 1 Forming a connection to a0:9e:1a:1d:44:a1 Created client Connected to server Found HR service Found BATT service Found HR characteristic Found BATT characteristic Connected to the BLE Server. 1: HR : 69 bpm Battery : 0 % 2: HR : 69 bpm Battery : 0 % 3: HR : 70 bpm Battery : 0 % 4: HR : 70 bpm Battery : 0 % 5: HR : 69 bpm Battery : 0 % 6: HR : 69 bpm Battery : 0 % 7: HR : 70 bpm Battery : 0 % 8: HR : 70 bpm Battery : 0 % 9: HR : 70 bpm Battery : 0 % # バッテリ残量が0%なのは、バッテリ残量を取得するのに時間がかかるせいのようだ。 # 待っていると自動的に表示されるようになる。

出力例:(Polar H10の場合)

picocom /dev/ttyUSB0 -b115200 Starting Arduino BLE Client application... Scanning for BLE devices ... BLE Advertised Device found: Name: , Address: 7d:01:bf:c3:6f:ff, manufacturer data: 4c0010050318e24cea BLE Advertised Device found: Name: Polar H10 31BFD72E, Address: fd:e0:ff:99:cc:1e, manufacturer data: 6b00330c4243 Devices found: 2 Scanning for BLE devices ... BLE Advertised Device found: Name: , Address: fd:e0:ff:99:cc:1e, manufacturer data: 6b002f0c4343, serviceUUID: 0000180d-0000-1000-8000-00805f9b34fb, txPower: 4 Found Heart Rate device! Devices found: 1 Forming a connection to fd:e0:ff:99:cc:1e Created client Connected to server Found HR service Found BATT service [E][BLERemoteCharacteristic.cpp:274] retrieveDescriptors(): esp_ble_gattc_get_all_descr: Unknown Found HR characteristic Found BATT characteristic Connected to the BLE Server. 2: HR : 67 bpm Battery : 0 % 3: HR : 66 bpm Battery : 0 % 4: HR : 66 bpm Battery : 0 % 5: HR : 66 bpm Battery : 0 % 6: HR : 66 bpm Battery : 0 % 7: HR : 66 bpm Battery : 0 % 8: HR : 66 bpm Battery : 0 % 9: HR : 67 bpm Battery : 0 % # バッテリ残量が0%なのは、バッテリ残量を取得するのに時間がかかるせいのようだ。 # 待っていると自動的に表示されるようになる。

参考情報

https://hackaday.io/project/88055-technogym-new-heart-rate-ble-sensor
Technogym : new Heart Rate BLE sensor
Replace the RF HR receiver with a new BLE sensor based on ESP32.

Web-BluetoothでHRセンサーを接続する
Web-Bluetooth:HR(心拍)センサーのロガー
Web-Bluetooth:CSC(自転車)センサーのロガー

PlatformIO Core (CLI)

以上

続きを読む "M5Atom(ESP32を含む)でHRセンサーデータを受信する(Arduino版)"

| | コメント (0)

2020年8月 8日 (土)

M5AtomでOLED128x128(SPI)を制御する(Arduino版)

2020/8/8

PlatformIO M5Atom OLED128x128(SPI)

PPlatformIO M5Atom OLED128x128(SPI)

概要

M5Atomで以下のOLED128x128(SPI)を制御する(Arduino版)
開発ツールのインストールについては「M5Atomを開発ツールPlatformIOで使う(M5Atom/Arduino版)」を参照のこと。 (ホストPCとしてはubuntuを想定している)

waveshare - 1.5inch RGB OLED Module

接続

以下のようにOLEDとM5Atomボードを接続する:

OLED CS D/C DIN CLK RST VCC GND
M5Atom G22 G19 G23(MOSI) G33(CSK) G25 3V3 GND

(背面(底面)のピン穴に接続する)

外部ライブラリ導入

platformio.iniを以下のように編集する:

; PlatformIO Project Configuration File ; ; Build options: build flags, source filter ; Upload options: custom upload port, speed and extra flags ; Library options: dependencies, extra library storages ; Advanced options: extra scripting ; ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html [env:esp32dev] platform = espressif32 board = m5stick-c framework = arduino monitor_speed = 115200 lib_deps = # use M5Atom lib 3113 # use "FastLED" 126 # use "Adafruit SSD1351 library" 266 # use "Adafruit GFX Library" 13 lib_ldf_mode = deep+

テスト用スケッチをダウンロードする

cd src wegt https://raw.githubusercontent.com/adafruit/Adafruit-SSD1351-library/master/examples/test/test.ino

テスト・スケッチ

ダウンロードしたスケッチを以下の修正点に対応して変更する:

修正点:

(1)以下をスケッチの先頭に追加する:

#include <M5Atom.h>

(2)XIAOのOLEDモジュールの配線に合わせてピンアサインを修正する

// for M5Atom #define SCLK_PIN 33 #define MOSI_PIN 23 #define DC_PIN 19 #define CS_PIN 22 #define RST_PIN 25 /********************* #define SCLK_PIN 2 #define MOSI_PIN 3 #define DC_PIN 4 #define CS_PIN 5 #define RST_PIN 6 **********************/

(3)rotation
任意だが、今回の場合、コネクタが画面の下になるようにした:

tft.setRotation(3);

src/test.ino(編集済み)

/*************************************************** This is a example sketch demonstrating graphic drawing capabilities of the SSD1351 library for the 1.5" and 1.27" 16-bit Color OLEDs with SSD1351 driver chip Pick one up today in the adafruit shop! ------> http://www.adafruit.com/products/1431 ------> http://www.adafruit.com/products/1673 If you're using a 1.27" OLED, change SCREEN_HEIGHT to 96 instead of 128. These displays use SPI to communicate, 4 or 5 pins are required to interface Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! Written by Limor Fried/Ladyada for Adafruit Industries. BSD license, all text above must be included in any redistribution The Adafruit GFX Graphics core library is also required https://github.com/adafruit/Adafruit-GFX-Library Be sure to install it! ****************************************************/ #include <M5Atom.h> // Screen dimensions #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 128 // Change this to 96 for 1.27" OLED. // You can use any (4 or) 5 pins // for M5Atom #define SCLK_PIN 33 #define MOSI_PIN 23 #define DC_PIN 19 #define CS_PIN 22 #define RST_PIN 25 /********************* #define SCLK_PIN 2 #define MOSI_PIN 3 #define DC_PIN 4 #define CS_PIN 5 #define RST_PIN 6 **********************/ // Color definitions #define BLACK 0x0000 #define BLUE 0x001F #define RED 0xF800 #define GREEN 0x07E0 #define CYAN 0x07FF #define MAGENTA 0xF81F #define YELLOW 0xFFE0 #define WHITE 0xFFFF #include <Adafruit_GFX.h> #include <Adafruit_SSD1351.h> #include <SPI.h> // Option 1: use any pins but a little slower Adafruit_SSD1351 tft = Adafruit_SSD1351(SCREEN_WIDTH, SCREEN_HEIGHT, CS_PIN, DC_PIN, MOSI_PIN, SCLK_PIN, RST_PIN); // Option 2: must use the hardware SPI pins // (for UNO thats sclk = 13 and sid = 11) and pin 10 must be // an output. This is much faster - also required if you want // to use the microSD card (see the image drawing example) //Adafruit_SSD1351 tft = Adafruit_SSD1351(SCREEN_WIDTH, SCREEN_HEIGHT, &SPI, CS_PIN, DC_PIN, RST_PIN); float p = 3.1415926; void setup(void) { //Serial.begin(9600); Serial.begin(115200); Serial.print("hello!"); tft.begin(); Serial.println("init"); // You can optionally rotate the display by running the line below. // Note that a value of 0 means no rotation, 1 means 90 clockwise, // 2 means 180 degrees clockwise, and 3 means 270 degrees clockwise. //tft.setRotation(1); tft.setRotation(3); // NOTE: The test pattern at the start will NOT be rotated! The code // for rendering the test pattern talks directly to the display and // ignores any rotation. uint16_t time = millis(); tft.fillRect(0, 0, 128, 128, BLACK); time = millis() - time; Serial.println(time, DEC); delay(500); lcdTestPattern(); delay(500); tft.invert(true); delay(100); tft.invert(false); delay(100); tft.fillScreen(BLACK); testdrawtext("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa, fringilla sed malesuada et, malesuada sit amet turpis. Sed porttitor neque ut ante pretium vitae malesuada nunc bibendum. Nullam aliquet ultrices massa eu hendrerit. Ut sed nisi lorem. In vestibulum purus a tortor imperdiet posuere. ", WHITE); delay(500); // tft print function! tftPrintTest(); delay(500); //a single pixel tft.drawPixel(tft.width()/2, tft.height()/2, GREEN); delay(500); // line draw test testlines(YELLOW); delay(500); // optimized lines testfastlines(RED, BLUE); delay(500); testdrawrects(GREEN); delay(1000); testfillrects(YELLOW, MAGENTA); delay(1000); tft.fillScreen(BLACK); testfillcircles(10, BLUE); testdrawcircles(10, WHITE); delay(1000); testroundrects(); delay(500); testtriangles(); delay(500); Serial.println("done"); delay(1000); } void loop() { } void testlines(uint16_t color) { tft.fillScreen(BLACK); for (uint16_t x=0; x < tft.width()-1; x+=6) { tft.drawLine(0, 0, x, tft.height()-1, color); } for (uint16_t y=0; y < tft.height()-1; y+=6) { tft.drawLine(0, 0, tft.width()-1, y, color); } tft.fillScreen(BLACK); for (uint16_t x=0; x < tft.width()-1; x+=6) { tft.drawLine(tft.width()-1, 0, x, tft.height()-1, color); } for (uint16_t y=0; y < tft.height()-1; y+=6) { tft.drawLine(tft.width()-1, 0, 0, y, color); } tft.fillScreen(BLACK); for (uint16_t x=0; x < tft.width()-1; x+=6) { tft.drawLine(0, tft.height()-1, x, 0, color); } for (uint16_t y=0; y < tft.height()-1; y+=6) { tft.drawLine(0, tft.height()-1, tft.width()-1, y, color); } tft.fillScreen(BLACK); for (uint16_t x=0; x < tft.width()-1; x+=6) { tft.drawLine(tft.width()-1, tft.height()-1, x, 0, color); } for (uint16_t y=0; y < tft.height()-1; y+=6) { tft.drawLine(tft.width()-1, tft.height()-1, 0, y, color); } } void testdrawtext(char *text, uint16_t color) { tft.setCursor(0,0); tft.setTextColor(color); tft.print(text); } void testfastlines(uint16_t color1, uint16_t color2) { tft.fillScreen(BLACK); for (uint16_t y=0; y < tft.height()-1; y+=5) { tft.drawFastHLine(0, y, tft.width()-1, color1); } for (uint16_t x=0; x < tft.width()-1; x+=5) { tft.drawFastVLine(x, 0, tft.height()-1, color2); } } void testdrawrects(uint16_t color) { tft.fillScreen(BLACK); for (uint16_t x=0; x < tft.height()-1; x+=6) { tft.drawRect((tft.width()-1)/2 -x/2, (tft.height()-1)/2 -x/2 , x, x, color); } } void testfillrects(uint16_t color1, uint16_t color2) { tft.fillScreen(BLACK); for (uint16_t x=tft.height()-1; x > 6; x-=6) { tft.fillRect((tft.width()-1)/2 -x/2, (tft.height()-1)/2 -x/2 , x, x, color1); tft.drawRect((tft.width()-1)/2 -x/2, (tft.height()-1)/2 -x/2 , x, x, color2); } } void testfillcircles(uint8_t radius, uint16_t color) { for (uint8_t x=radius; x < tft.width()-1; x+=radius*2) { for (uint8_t y=radius; y < tft.height()-1; y+=radius*2) { tft.fillCircle(x, y, radius, color); } } } void testdrawcircles(uint8_t radius, uint16_t color) { for (uint8_t x=0; x < tft.width()-1+radius; x+=radius*2) { for (uint8_t y=0; y < tft.height()-1+radius; y+=radius*2) { tft.drawCircle(x, y, radius, color); } } } void testtriangles() { tft.fillScreen(BLACK); int color = 0xF800; int t; int w = tft.width()/2; int x = tft.height(); int y = 0; int z = tft.width(); for(t = 0 ; t <= 15; t+=1) { tft.drawTriangle(w, y, y, x, z, x, color); x-=4; y+=4; z-=4; color+=100; } } void testroundrects() { tft.fillScreen(BLACK); int color = 100; int x = 0; int y = 0; int w = tft.width(); int h = tft.height(); for(int i = 0 ; i <= 24; i++) { tft.drawRoundRect(x, y, w, h, 5, color); x+=2; y+=3; w-=4; h-=6; color+=1100; Serial.println(i); } } void tftPrintTest() { tft.fillScreen(BLACK); tft.setCursor(0, 5); tft.setTextColor(RED); tft.setTextSize(1); tft.println("Hello World!"); tft.setTextColor(YELLOW); tft.setTextSize(2); tft.println("Hello World!"); tft.setTextColor(BLUE); tft.setTextSize(3); tft.print(1234.567); delay(1500); tft.setCursor(0, 5); tft.fillScreen(BLACK); tft.setTextColor(WHITE); tft.setTextSize(0); tft.println("Hello World!"); tft.setTextSize(1); tft.setTextColor(GREEN); tft.print(p, 6); tft.println(" Want pi?"); tft.println(" "); tft.print(8675309, HEX); // print 8,675,309 out in HEX! tft.println(" Print HEX!"); tft.println(" "); tft.setTextColor(WHITE); tft.println("Sketch has been"); tft.println("running for: "); tft.setTextColor(MAGENTA); tft.print(millis() / 1000); tft.setTextColor(WHITE); tft.print(" seconds."); } void mediabuttons() { // play tft.fillScreen(BLACK); tft.fillRoundRect(25, 10, 78, 60, 8, WHITE); tft.fillTriangle(42, 20, 42, 60, 90, 40, RED); delay(500); // pause tft.fillRoundRect(25, 90, 78, 60, 8, WHITE); tft.fillRoundRect(39, 98, 20, 45, 5, GREEN); tft.fillRoundRect(69, 98, 20, 45, 5, GREEN); delay(500); // play color tft.fillTriangle(42, 20, 42, 60, 90, 40, BLUE); delay(50); // pause color tft.fillRoundRect(39, 98, 20, 45, 5, RED); tft.fillRoundRect(69, 98, 20, 45, 5, RED); // play color tft.fillTriangle(42, 20, 42, 60, 90, 40, GREEN); } /**************************************************************************/ /*! @brief Renders a simple test pattern on the screen */ /**************************************************************************/ void lcdTestPattern(void) { static const uint16_t PROGMEM colors[] = { RED, YELLOW, GREEN, CYAN, BLUE, MAGENTA, BLACK, WHITE }; for(uint8_t c=0; c<8; c++) { tft.fillRect(0, tft.height() * c / 8, tft.width(), tft.height() / 8, pgm_read_word(&colors[c])); } }

書き込み後、実行するとOLEDにテスト画面が表示される。

参考情報

https://www.waveshare.com/w/upload/a/a7/SSD1351-Revision_1.5.pdf
https://www.waveshare.com/w/upload/5/5b/1.5inch_RGB_OLED_Module_User_Manual_EN.pdf

XIAOでOLED128x128(SPI)を制御する(Arduino版)
同じOLEDをXIAOで動作させた例

PlatformIO Core (CLI)

以上

続きを読む "M5AtomでOLED128x128(SPI)を制御する(Arduino版)"

| | コメント (0)

より以前の記事一覧