目次
- デバッグ・トラブルシューティング
- デバッグチェックリスト
- トラブルシューティング
- ディスプレイに何も表示されない
- ssh や VNC で接続できない
- pi ユーザのパスワードが分からない
- 同時に複数のタブで開くと動作しない
- コンソールに
Uncaught (in promise) GPIOPort(XX).export() error
などと表示される - JS Bin のコンソールに何もエラーが表示されないのに意図した動作をしない
- JS Bin で
async
やawait
に赤い下線の警告が表示される - コンソールに
Uncaught ReferenceError: xxx is not defined
などと表示される - コンソールに
Uncaught TypeError: Cannot read property 'xxx' of null
やUncaught TypeError: Cannot read property 'xxx' of undefined
などと表示される - コンソールに
Uncaught (in promise) TypeError: navigator.requestGPIOAccess is not a function
などと表示される - コンソールに
Uncaught SyntaxError: await is only valid in async function
などと表示される - JS Bin のコンソールに
error: ws error: [object Event]
と表示される - コンソールに
WebSocket connection to 'wss://localhost:33330/' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED
などと表示される - コンソールに
connection to 'wss://localhost:33330' failed: Error in connection establishment: net::ERR_INSECURE_RESPONSE
などと表示される - JavaScript から特定の URL にアクセスできない
- コンソールに
Failed to load https://...: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://...' is therefore not allowed access.
などと表示される - コンソールに
Access to fetch at 'https://...' from origin 'https://...' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
などと表示される - JS Bin や JS Fiddle で Web Bluetoooth, Web MIDI, WebRTC などが利用できない
- コードも配線も正しいのにとにかく動作しない!
デバッグ・トラブルシューティング
CHIRIMEN Raspi を利用する上で基礎的なデバッグやトラブルシューティングを共有するページです。良くある質問については FAQ ページ に、利用上のテクニックや知っておくと良いことは TIPS ページ に書いているので、そちらも合わせてご覧ください。
CHIRIMEN Raspi でのプログラミングでも Web アプリケーションのプログラミングでも問題解決の手順は共通です。プログラムは意図したとおりではなく書いた通りに動くので、実際のコードや配線が意図通りか、一つずつ検証し、問題の原因となる範囲を絞っていくことが大事です。
まずは開発ツールの console を開きましょう。ショートカットキー (F12 または Ctrl+Shift+I) やメニュー (その他のツール -> デベロッパーツール) を開き Console
タブを開きます。エラーメッセージなどがここに出力されます。また更新した内容が即座に反映するように Cache を Disable にしておきましょう(開発ツールの Settings/Preferences から指定できます)
プログラム中に console.log 関数 console.log(カンマ区切りで確認したい変数などを記載);
を書けば、先の console 上に確認したい値が出力されます。これも基本的なデバッグのテクニックです。詳しくは下記開発ツール (DevTools) のリンクなどを参考にしてください。
エラーメッセージやデバイスの LED 表示、あるいは焦げた匂いなど問題のヒントがある時はまずそこから確認し、そのエラーメッセージが発生する原因を探ります。JavaScript では console.log
で変数の状態を書き出しながら実行するだけでなく、開発ツール (DevTools) を使ってデバッグ することが解決の早道です。ブレークポイント でコードの実効を一時停止し、そのコードが意図通りのタイミング、回数、変数の状態で呼ばれているか確認するようにすると素早くデバッグできるようになります。
講師やチューターのいる場面ではデバッグの仕方も積極的に教えてもらってください。
デバッグチェックリスト
問題解決のためのチェックリスト (初心者向け) を書いてみたので参考にしてください:
- 開発ツールでのエラーの確認
- エラーコンソールにエラーメッセージが出力されていないか
- デバイスにアクセスできないケースにはコードでなく配線に問題がないかも確認する
- ネットワークパネルでファイル読み込みやアクセスのエラーがないか
- エラーコンソールにエラーメッセージが出力されていないか
- JavaScript コードの確認
- 該当コードが呼び出されているか
- 処理が行われない場合、そもそもそのコードが実行されていないことが多いです
- まずは console.log やブレークポイントで実行されていることを確認します
- イベントハンドラはイベントの発生前に登録できているか。例えば onload イベントで実行する関数を onload 後に登録するなどしていないか
- 変数のスコープ (定義域) に問題がないか
- 別の関数で宣言した変数にアクセスしようとしていないか (コードをコピペなどで移動させたときに特に注意)
- 実行順序が意図した通りか
- console.log やブレークポイントで実行順序を確認します
- 非同期処理の呼び出し時に await を付け忘れていないか確認します
- 変数には意図した値が代入されているか
- 様々な原因で意図せぬ値が入っていることがあるため実際の値を console.log やブレークポイントで停止した状態で確認します
- HTML 要素を取得する場合、要素の読み込みより後で JavaScript を実行しなければ取得できないことに注意してください
- 該当コードが呼び出されているか
- 配線の確認
- ピンヘッダの何処にどのジャンパーワイヤを刺しているか確認する
- ピンヘッダに刺す位置を 180° 反転した逆向きに指していないか
- コードで指定しているピン番号と配線は一致しているか
- 抵抗などのパーツの配線も正しく行われているか
- I2C デバイスは配線後に
i2cdetect -y -r 1
コマンドで接続確認する
- 機材の故障
- LED など内部抵抗の小さいデバイスを抵抗無しで通電するなどすると故障します
- DC ファンなど極性のあるデバイスは逆指しすると故障します
- 配線中にショートさせたりするとデバイスも RasPi ボードも故障します
トラブルシューティング
ディスプレイに何も表示されない
Raspi に AC アダプタと microUSB ケーブルを接続して (ケーブルにスイッチがあればオンにして) も HDMI ディスプレイに何も表示されない場合にはいくつかの原因が考えられます。
- Raspi 本体の LED が点灯しない場合
- AC アダプタに通電されていないかどうか、コンセントから AC アダプタまで何処か抜けたりスイッチがオフになっていないか確認してください
- LED は点灯するがディスプレイに起動画面が表示されない場合
- ディスプレイが真っ黒な場合
- HDMI ディスプレイの電源がオンになっていることを確認してください。ディスプレイ次第ですが電源の抜き差しや電源ボタンの長押しなども試してください。
- 電源オン時に入力がないメッセージなどが表示される場合
- ケーブルの入力端子と入力切り替え設定の対応を確認してください
- Raspi に microSD カードが正しく刺さっていることを確認してください (Raspi は一般的な PC と異なり SD カードがないとエラー画面も何も出力しません)
- SD カードが壊れたり正しく作成できていないか確認してください (SD カードの作成手順 ページを参照)
- HDMI ディスプレイが CHIRIMEN Raspi の想定する解像度に対応していない場合、ディスプレイの認識に失敗して画面に何も表示されないことがあります。その場合は SD イメージの中の
/boot/config.txt
でhdmi_force_hotplug
,hdmi_group
,hdmi_mode
,hdmi_drive
などの設定が書かれている箇所をご利用のディスプレイに合わせてコメントアウトや書き換えてください
- ディスプレイが真っ黒な場合
ssh や VNC で接続できない
pi ユーザのパスワードが分からない
本ページ執筆時点で CHIRIMEN の配付イメージは Raspbian をベースにしておりデフォルトユーザ pi
のパスワードは Raspbian デフォルト同様に raspberry
となっています (2018 年以前のイメージでは rasp
に変更されていました)。
同時に複数のタブで開くと動作しない
コンソールに Uncaught (in promise) GPIOPort(XX).export() error
などと表示される
複数のプログラムで同じ GPIO ポートや I2C ポートを同時に制御することは出来ない ため、複数のタブを同時に開くとポートの export に失敗します。API では特に規定されていませんが実装上は排他制御がされており、同一のページを複数タブで開いたり、I2C Detect ページと I2C を利用するページを同時に開くなど、同じポートを同時に扱うコードを書くと正しく動作しなくなることがあります。全てのタブを閉じてから目的のページだけを開き直してください。
JS Bin のコンソールに何もエラーが表示されないのに意図した動作をしない
残念ながら JS Bin のコンソールではすべての JavaScript エラーや警告メッセージが表示されるわけではありません。デバッグ時にはブラウザの開発ツールを (F12 または Ctrl+Shift+I で) 開き Console
に表示されるメッセージを確認してください。
JS Bin で async
や await
に赤い下線の警告が表示される
JS Bin は軽量で便利なオンラインエディタですが、実装が古く JavaScript ペインでの自動構文チェック機能が async や await といった比較的新しい構文 (2017 年に仕様が固まり各ブラウザで正式サポートとなりました) を適切に認識できていません。これらの下に赤線が引かれている場合は無視して問題ありません。最新の言語機能・ブラウザの実装を考慮した構文チェック機能を使いたい場合は CodeSandbox を使うか、ローカルのエディタに構文チェックプラグインをインストールしてください。
コンソールに Uncaught ReferenceError: xxx is not defined
などと表示される
変数 xxx
にアクセスしようとしているがそれが定義されていないというエラーです。単純に変数名などを Typo (入力し間違え) していることが多いです。次に多いのは定義域の外でアクセスしようとしている場合です。JavaScript の変数スコープは var で宣言した場合は関数単位、let や const で宣言した場合にはブロック単位です。別の関数の中からなど、スコープ外からアクセスしようとしていないか確認してください。
コンソールに Uncaught TypeError: Cannot read property 'xxx' of null
や Uncaught TypeError: Cannot read property 'xxx' of undefined
などと表示される
オブジェクトのプロパティ xxx
にアクセスしようとしている (some.xxx
のようなコード)、プロパティ xxx
を持つと考えている変数 some
がオブジェクトではなく null や undefined となっており、プロパティアクセスができないというエラーです。変数 some
の取得・代入をしているコードに問題がないか確認してください。
コンソールに Uncaught (in promise) TypeError: navigator.requestGPIOAccess is not a function
などと表示される
関数 (メソッド) 呼び出ししようとしているがその関数が定義されていないというエラーです。この場合 navigator.requestGPIOAccess
が関数ではないと言うことですが、polyfill スクリプトを読み込んでいないか、読み込みより前にアクセスしようとしている場合に発生します。
コンソールに Uncaught SyntaxError: await is only valid in async function
などと表示される
await
文は async (非同期) 関数の中でのみ利用可能です。関数の中で await
を使って非同期処理を行いたい場合、その関数を async 関数として宣言する必要があります。特に addEventListener
などで引数としてコールバック関数を渡している場合などには async
を付け忘れてしまうことが多いので注意してください。
// 関数宣言:
async function wait100ms() { await sleep(100); }
// 匿名関数を使う場合:
element.addEventListener("click", async function() { await sleep(100); }, false);
// アロー(矢印)関数を使う場合
element.addEventListener("click", async () => { await sleep(100); }, false);
JS Bin のコンソールに error: ws error: [object Event]
と表示される
コンソールに WebSocket connection to 'wss://localhost:33330/' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED
などと表示される
CHIRIMEN Raspi では JavaScript から GPIO などを操作できるように、JavaScript からの呼び出しに応じてハードを制御するローカル WebSocket サーバが Raspi 上の Node サーバとして起動しています。何らかの理由でそのサーバに問題が生じている場合はデスクトップにある reset.sh
を実行して再起動させると正常動作するようになります。
コンソールに connection to 'wss://localhost:33330' failed: Error in connection establishment: net::ERR_INSECURE_RESPONSE
などと表示される
CHIRIMEN Raspi のバックエンドサーバとの接続が許可されていません。ブラウザから一度 https://localhost:33330
にアクセスして 詳細設定
から localhostにアクセスする(安全ではありません)
をクリックし、ローカル WebSocket サーバ (サーバ証明書無し) へのアクセスを許可してください。
詳しくは CHIRIMEN for Raspberry Pi 3 におけるセキュリティーエラーへの対処方法 を参考にしてください。
JavaScript から特定の URL にアクセスできない
コンソールに Failed to load https://...: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://...' is therefore not allowed access.
などと表示される
コンソールに Access to fetch at 'https://...' from origin 'https://...' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
などと表示される
CHIRIMEN に限らず一般的な Web 開発でよく見かけるエラーです。Web には 同一オリジンポリシー (Same Origin Policy) というセキュリティ制約があり、JavaScript を読み込んでいるのと異なるドメインの URL には相手側のサーバが オリジン管理ソース共有 (CORS) で明示的に許可している場合以外は JavaScript のコード中で XMLHttpRequest や fetch からアクセスできません。
単純化して言えば、サーバからの HTTP レスポンスヘッダに access-control-allow-origin: *
が付与されていれば JavaScript からのアクセスが許可されるため、任意の URL へのアクセスをプロキシ (中継) してレスポンスヘッダを勝手に追加してくれるようなサーバを用意すれば任意のドメインから任意の URL にアクセスが可能になります。
そのような機能を持った公開の CORS プロキシサービスには例えば https://cors-anywhere.herokuapp.com/ や https://cors.io/ などいろいろなものがあります。なお、これらのサービスの利用は本来のセキュリティ機能を無視するものであり、利用に際しては注意が必要です。あくまでもプライバシー情報などを含まないものについて、テストやプロトタイピング時だけに限って利用すべきです。
JS Bin や JS Fiddle で Web Bluetoooth, Web MIDI, WebRTC などが利用できない
Chrome 64 で Feature Policy というセキュリティ機構が導入され、iframe ページ内ではフレーム読み込み元のページの HTTP ヘッダで明示的な許可がされない限り、高度な機能が利用不可能になりました。JS Bin などのサービスでは読み込み結果を iframe 内に読み込んでいることが多いが、Feature Policy で許可をするヘッダの送信には未対応であるため、一部の Web API が利用できないことがあります。
これに該当する場合は開発ツールのコンソールに Feature Policy に関するエラーメッセージが表示されます。その場合にはコードをすべてローカルの HTML などで書いてそれをブラウザに読み込ませるようにしてください。
コードも配線も正しいのにとにかく動作しない!
いろいろな原因が考えらるため、ひとつずつ確認していく必要があります。例えばこのように考えます:
-
問題を切り分けて考える
- 作品が複数のデバイスから構成されている場合でも、個々のデバイス向けにサンプルプログラムが用意されているものならば、先ずはサンプルプログラムを動かして個々のデバイスが正しく組み立てられていることを確認しましょう。これによって多くのケースではハードウェアの確認ができると思います。
-
開発者ツールのコンソールに何かエラーメッセージは出ていないですか?
- JS Bin などのコンソールだけでなく、ブラウザのエラーコンソールも確認してください
- 何もエラーが出ないと言っても最初に 1 行だけエラーが出ているケースなどあります。ページをリロードして何もエラーがないか確認してください
-
開発者ツールのネットワークパネルで読み込みできていないファイルはないですか?
- polyfill や driver などを相対パスで読み込んでいる HTML のディレクトリを移動させた場合、相対パスが変わって必要なファイルが読み込みできなくなっていることがあります
-
配線は本当に正しいですか?
- 慌てて配線すると RasPi のピンの配置を 180° 反転させた逆向けで配線していることがあります
-
配線はしっかりしていますか?
- ジャンパーピンやピンヘッダーの太さが細すぎないか。ブレッドボードに刺す前提で細いピンヘッダを採用しているセンサー (秋月電子の商品など) がありますが、これらをピンソケットに刺すと接触が不安定になることがあります
- センサー類などの基盤にピンヘッダーを付けている場合はそれがしっかり半田付けされているか
-
利用ハードウェアに不良・故障はないか?
- 不良・故障の可能性のあるハードを順に交換して試してください
- ソフトウェアと違いハードウェアには配線を間違って使うと不可逆的な損傷を受けて正常動作しなくなるパーツも存在します。抵抗無しで LED を接続して焼け飛ぶ場合や DC ファンを極性と異なる向きに繋いで焼いてしまった場合などが典型的ですが、壊れたら交換するしかありません
- サーボモータドライバーなど手作業での半田付けを行うピンヘッダ数が多いパーツなどは半田付けになれている人が作らなければ不良品になることが多く見られます。半田付け直後は動作しても保管している間にダメになるケースもあるので注意してください
- ジャンパーケーブルのような単純なパーツも安物であれば大容量の電流を流したり曲げを繰り返していると繋がらなくなるケースがあります。ブレッドボードも繰り返し使っているうちにピンの固定が緩く接触不良になることがあります。消耗品は調子が悪くなったら交換してください
-
CHIRIMEN Raspi のバックエンドサーバに問題がないか?
- 同時に複数のタブで同一ポートにアクセスしたりする場合、大抵は適切に排他制御されてタブを閉じてから開き直すだけで解決しますが、処理の仕方やタイミングなどによっては何らかの理由でバックエンドサーバに不具合が起きる場合もあるようです。デスクトップの reset.sh で再起動して再度試してみてください。
ハンズオン・ハッカソン・講義など、講師やチューターなどのいる時は、色々試して分からないときは一人で悩まず遠慮なく質問しましょう。 動かない時や解決できないときに教わるのは、デバッグ力のある人のテクニックや思考を教えてもらうチャンスです。質問するほどプログラミングとデバッグのスキルは向上するので、どんどん質問していってください。