Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Lチカで終わらせないArduino シリアル通信 Part1

tomit3
September 25, 2021

Lチカで終わらせないArduino シリアル通信 Part1

Arduinoを初めてLEDをチカチカさせるだけで終わっていませんか?ArduinoとPCの間で通信を行う方法についてまとめた資料です。LチカからPCとArduinoで通信を行う簡単な方法を説明しています。Part2はコチラ(https://speakerdeck.com/tomit3/ltikadezhong-warasenaiarduino-siriarutong-xin-part2)

tomit3

September 25, 2021
Tweet

More Decks by tomit3

Other Decks in Technology

Transcript

  1. 自己紹介とこの資料 • 自己紹介 • 仕事でソフトウェア開発 • ソフトウェア、ハードウェアに限らずモノ作りが好き • GitHubに公開 •

    関連する資料もslideshareで公開(tomitomi3で検索) • この資料について • とある勉強会向けに作成した資料。ArduinoをLチカだけで使用するので はなく、便利なハードとして使うために「通信」させて使う方法につい てまとめた。
  2. Arduinoと通信ができると何が良いのか? • Arduinoで何かを制御するためには • コードを書き、ArduinoのCPU(MCU)にコードを書き込み、実行する • 具体例として下記 • LEDを1秒おきに光らせたい Arduino

    コード 制御したい何か (LED、サーボetc) 「制御したい何か」に対して、 Arduinoがコードを元に実行・制御 Arduinoにコードを書き込む USB 物理的な接続
  3. Arduinoと通信ができると何が良いのか? • 多種多様な注文にどうこたえるか? • LEDを2秒おきに光らせたい、LEDをあるパターンで光らせたい、制御対象 を変更したい・・・など • コードを書いて、Arduinoに書き込むということが面倒になる • 解決策として下記

    • 制御パターンをコードに変更し、PCからの指令を元に制御 • Arduinoを中間HW(仲介)とし、 PCからの指令を元に対象を制御 USB 制御したい何か (LED、サーボetc) Arduinoは「制御したい何か」の中間となる 実行・制御しているのはPC内のソフトウェア Arduinoに対して通信 を行うソフトウェア 物理的な接続 通信・制御コード
  4. Arduinoと通信ができると何が良いのか? • 前述の「中間HW(仲介)」 • 制御対象がPCと接続できればよいが、接続できない場合に問題が発生 • 例1:PCとモーターは直接つながらない • PCの入出力IFがUSBのため(USBはUSBプロトコルで通信)。 •

    モーターを駆動できる電流を流せない。 • 例2:センサーのIFとPCのIFが異なる • センサーはI2CというIF、PCにはI2C等のIFがほとんど無い • 産業機械ではPLC(プログラマブルロジックコントローラ)などがその役割 制御したい 計測したい何か 制御したい・計測したい何かがIF(USBなど)を提供しれくれれば良い が、 無い場合は何かしらの中間(仲介)HWが必要 物理的な接続
  5. (参考)Arduinoとは? • 「あるでぅいーの」と読む • フィジカルコンピューティングのためのオープンソースプラットフォーム • PC内部だけではなく、環境も取り入れるコンピュータのあり方・考えのこと • インタラクションデザインの教材として誕生 •

    インタラクションデザイン • “あらゆるインタラクティブな経験のデザインである。” cf.、メディアアート • インタラクションデザインの流儀「プロトタイピング」 • “初めてエレクトロニクスに触れる初心者は、一からすべてを作り上げなくてはいけな いと考えがちなのですが、それはエネルギーの無駄遣いというものです。あなたにとっ ては大事なのは、自分のやる気が消えてしまう前に、あるいは誰かがあなたにお金を払 いたいと思ってくれているうちに、すばやく何かを作り上げることのはずです。” 各ワードの詳細は 興味ある方は独自に調べてみてください。 [1]Massimo Banzi著,船田 巧訳,Arduinoをはじめよう 第2版,株式会社オライリー・ジャパン,初版第1刷,pp1-4
  6. ArduinoでLチカを行う • 行う事 • ←「L」のLEDを制御(ON/OFF)を行う • ArduinoIDEでLED制御のコードを書き、 Arduinoに書き込み、実行する。 • 補足

    • Arduino UNOにはLEDが3つある • TX/RX シリアル通信の送受信状況を表す • L Lチカを行うLED 13番ピン
  7. Lチカコードを書き込む void setup() { pinMode(LED_BUILTIN, OUTPUT); } void loop() {

    digitalWrite(LED_BUILTIN, HIGH); delay(1000); digitalWrite(LED_BUILTIN, LOW); delay(1000); } 1.ArduinoIDEでLチカコードを書く 1秒毎にLEDを点滅させるコード ※ファイル->スケッチ例->01.Basics->Blinkを呼び出してもよい Arduinoではコードのことを「スケッチ」と呼ぶ 2.コードの検証を行うLチカコードを書き込む 書いたコードに問題がないかを確認(コードのルールのみ確認する) 下記のチェックマークか、スケッチ->検証・コンパイルをクリック 検証OK(コンパイルが正常) 検証エラー(コンパイルが通らなかった) ※全角スペースがあるため
  8. Lチカコードの意味 void setup() { pinMode(LED_BUILTIN, OUTPUT); } void loop() {

    digitalWrite(LED_BUILTIN, HIGH); delay(1000); digitalWrite(LED_BUILTIN, LOW); delay(1000); } 「LED_BUILTIN」は「13」に置き換えられる 13ピンを出力モードに設定 13ピンをHIGHに設定(5V出力) 1000 ms待つ 13ピンをLOWに設定(0V出力) 1000 ms待つ Arduinoのコードのルール • setup()、Loop()は必ず書く • setup()はArduinoボードの初期化。起動時1度のみ実行。 • 各ピンの入力/出力状態、使用する機能(AD変換etc)を設定する。 • loop()に行う処理を記入する。 • Arduino起動後、loop()内の処理を繰り返す。 • PINの出力を行うetc 実際に行いたい処理を記入。 繰り返す
  9. Arduinoと通信を行いLチカを行う • 冒頭で言ったPCと通信を行い、制御(LED)を行う • 通信を行うソフトウェア シリアルモニタ • 通信・制御コード 無いので作る •

    制御したい何か Arduino内臓LED USB 制御したい何か (LED) Arduinoに対して通信 を行うソフトウェア 物理的な接続 通信・制御コード
  10. void setup() { Serial.begin(9600); pinMode(LED_BUILTIN, OUTPUT); } void loop() {

    while (Serial.available() > 0) { byte InputData = Serial.read(); //receve switch (InputData) { case 'a' : for (int i = 0; i < 5; i++) { digitalWrite(LED_BUILTIN, HIGH); delay(500); digitalWrite(LED_BUILTIN, LOW); delay(500); } break; case 'b' : for (int i = 0; i < 3; i++) { digitalWrite(LED_BUILTIN, HIGH); delay(200); digitalWrite(LED_BUILTIN, LOW); delay(200); } break; default : digitalWrite(LED_BUILTIN, HIGH); delay(100); digitalWrite(LED_BUILTIN, LOW); delay(100); break; } } } 1.仕様 • PCからシリアル通信による信号を受信する • シリアル通信の仕様 • 信号を読み取り下記制御パターンでLEDを制御する • 読み込む仕様 • 「a」を受信した場合、LEDを0.5秒毎に5回点滅 • 「b」を受信した場合、LEDを0.2秒毎に3回点滅 • それ以外、LEDを0.1秒ON->OFFにする • 上記を繰り返す 2.コードをArduinoに書き込む 3.[ツール]->[シリアルモニタ]を起動する • a、b、それ以外の“1”文字を入力して送信 • aa、ab、それ以外の“2”文字を入力して送信 送信する文字列を入力
  11. Arduinoの通信コードの意味 void setup() { Serial.begin(9600); pinMode(LED_BUILTIN, OUTPUT); } void loop()

    { while (Serial.available() > 0) { byte InputData = Serial.read(); //receve switch (InputData) { case 'a' : //省略 LEDが点滅 break; case 'b’ : //省略 LEDが点滅 break; default : //省略 LEDが点滅 break; } } } • 通信(シリアル通信)の通信速度設定 • 13ピンを出力モードに設定 繰り返す (while内) • バッファにデータがあるかを確認 • 1バイト読み込む 読み込んだデータに応じた処理 ・1バイト読み込む ・分岐処理 ‘a’と同じだった場合… ‘b’と同じだった場合… a,b以外だった場合… 一致すること
  12. Arduino UNOにある温度計 • ArduinoUNO(Atmega328P)内にある温度センサー温度を取得 • ArduinoUNO内の温度計 • A/D変換の補償のために使われる温度計らしい • Internal

    Temperature Sensor • https://playground.arduino.cc/Main/InternalTemperatureSensor/ • 精度は悪い温度計(オフセット値がばらばらでハード依存) だが触って温度が上がるくらいは分かる。 USB Arduino内の温度計 ArduinoIDE シリアルモニタ・プロッタ 通信・制御コード
  13. void setup() { Serial.begin(9600); Serial.println(F("Internal Temperature Sensor")); } void loop()

    { // Show the temperature in degrees Celsius. Serial.println(GetTemp(),1); delay(1000); } double GetTemp(void) { unsigned int wADC; double t; // The internal temperature has to be used // with the internal reference of 1.1V. // Channel 8 can not be selected with // the analogRead function yet. // Set the internal reference and mux. ADMUX = (_BV(REFS1) | _BV(REFS0) | _BV(MUX3)); ADCSRA |= _BV(ADEN); // enable the ADC delay(20); // wait for voltages to become stable. ADCSRA |= _BV(ADSC); // Start the ADC // Detect end-of-conversion while (bit_is_set(ADCSRA,ADSC)); // Reading register "ADCW" takes care of how to read ADCL and ADCH. wADC = ADCW; // The offset of 324.31 could be wrong. It is just an indication. t = (wADC - 324.31 ) / 1.22; // The returned temperature is in degrees Celsius. return (t); } 1.コードをArduinoに書き込む 2.[ツール]->[シリアルモニタ]を起動する ※シリアルモニタを起動すると、Arduinoはリセットされる (setup()->loop()が再実行される) 左のMCUを指で触ってみる シリアルモニタの変化を見る リセットボタンを押してみる プログラムが再実行を確認 1s毎に文字が表示
  14. 通信するために • デバイス同士をどうつなぎ、どうやりとりするか? • どうつなぎ • 1本でTTLレベル、Highを1として・・・ • 1対1、1対多、多対1、多対多・・・ •

    どうやりとり • 最初にAがBにHighを送って・・・ • デバイス間で「ルール」を決めないと互いに「通信」が出来ない。 • オレオレ規格/プロトコルでは異種のデバイスを接続し、通信は出来ない。 • 共通の規格・ルールが必要 • 一番有名な通信=インターネット • ルールに従えば誰でも通信が可能 cf.RFC(Request for comments) 一般的にプロトコルと呼ばれる ハード、ソフトいずれもある 相手に情報を伝えるかの物理的規格 どうつなぐことができるか
  15. 通信するために • PC<->Arduino間の通信で守っていた「ルール」 • Setup()内で通信速度の設定 • データビット 8bit⇒1バイト基準に送受信 • 下記は1バイト読み込む

    byte InputData = Serial.read(); void setup() { Serial.begin(9600); pinMode(LED_BUILTIN, OUTPUT); } ・パリティは使わない ・ストップビットはデフォルト ・フロー制御無し(接続にRX,TXのみで使用しないため)
  16. アプリケーション層 プレゼンテーション層 セッション層 トランスポート層 ネットワーク層 データリンク層 物理層 アプリケーション層 プレゼンテーション層 セッション層

    トランスポート層 ネットワーク層 データリンク層 物理層 OSI参照モデル • 通信(特にネットワーク接続)の構造を階層構造としてモデル化 • 上位は下位を知らなくてもよい(抽象化) • 上位はユーザー(使う人)に近い。 • アプリケーション層 「文字を送る」等
  17. アプリケーション層 プレゼンテーション層 セッション層 トランスポート層 ネットワーク層 データリンク層 物理層 デバイスをどう物理的につなぐか 10BASE-T, IEEE802.11,

    232C(EIA 232-D) etc 通信を独自にやり取りしたい 場合はここをカバー 例:独自データで送受信とその制御 既にあるプロトコルで通信 HTTPでGet etc アプリケーション層のみ意識する ことでデバイスの通信が可能 ソフト ハード 物理的な接続に対してどう通信するか 1データはnバイトであるetc 接続相手とどう通信するか ・TCP/IP, UDP ・IP データをパケット化 ネットワーク(イーサネット)におけるOSI参照モデル
  18. アプリケーション層 プレゼンテーション層 セッション層 トランスポート層 ネットワーク層 データリンク層 物理層 デバイス同士で通信をするために定義(作る)する必要がある 232Cの物理的な規格 RX/TX、差動etc

    232Cの通信プロトコル(データリンク層かは議論があるかも) データビットetc PC->Arduino 受信は1バイト受信の下記のみ。 byte InputData = Serial.read(); Arduino->PC IDEのシリアルモニタで文字列受信 (実際にはシリアル通信のAPI) USB PC<-Serial通信>Arduino通信におけるOSI参照モデル
  19. PC<-Serial通信>Arduino 通信の問題 • 今回紹介したArduinoの送受信は簡単なルールであったが、 現実使用するには下記の問題解決が必要 • 送・受信データのバッファ • シリアル通信のバッファがあふれないように送受信を行うためには •

    効率よくデータを送るには • 「1(数字では31)」と「0x01(数字では1)」の違い • 送・受信データの整合性 • データが壊れていたらどうするか?知る方法はあるか? ※ネットワークではTCP/IPでほぼ担保されている 次回は上記を検討しつつちょっと使える通信にバージョンアップする