チラシの裏の電子工作

電子工作、PC関係の備忘録というか、チラシの裏

ArduinoでPCINT割込

Arduinoで割込といえばINT0/1だけど、沢山のピンで割込を使いたい時のメモ。
(Arduino0023/ATmega168P)

たまに使おうとすると、PCINT,PCMSK,PCIEの対応を忘れていて調べるのが非常にめんどくさいので、もう定型にしてしまおうというものぐさ。


#define SW_INT_PCICR ((1<<PCIE0)|(0<<PCIE2)|(0<<PCIE2))
#define SW_INT_PCMSK0 ((1<<PCINT0 )|(1<<PCINT1 )|(1<<PCINT2 )|(1<<PCINT3 )|(0<<PCINT4 )|(0<<PCINT5 )|(0<<PCINT6 )|(0<<PCINT7))
#define SW_INT_PCMSK1 ((0<<PCINT8 )|(0<<PCINT9 )|(0<<PCINT10)|(0<<PCINT11)|(0<<PCINT12)|(0<<PCINT13)|(0<<PCINT14))
#define SW_INT_PCMSK2 ((0<<PCINT16)|(0<<PCINT17)|(0<<PCINT18)|(0<<PCINT19)|(0<<PCINT20)|(0<<PCINT21)|(0<<PCINT22)|(0<<PCINT23))

ISR(PCINT0_vect){
    Serial.println("PCINT0_vect");
}
ISR(PCINT1_vect){
    Serial.println("PCINT1_vect");
}
ISR(PCINT2_vect){
    Serial.println("PCINT2_vect");
}

void setup(){
    //割込有効化
    PCICR  |=SW_INT_PCICR;
    PCMSK0 |=SW_INT_PCMSK0;
    PCMSK1 |=SW_INT_PCMSK1;
    PCMSK2 |=SW_INT_PCMSK2;

    delay(10000);

    //割込無効化
    PCICR  &=~SW_INT_PCICR;
    PCMSK0 &=~SW_INT_PCMSK0;
    PCMSK1 &=~SW_INT_PCMSK1;
    PCMSK2 &=~SW_INT_PCMSK2;
}

void loop(){}



美しくはないけど、割込をマトリクス状にしてしまったら解りやすいかと。
上の例では、PCINT0~3の割込を有効にしたり、取り消ししたり。
もっといい方法があればいいんだけども、ライブラリにするのもおっくう…

スポンサーサイト

カテゴリ:電子工作

ESP8266環境センサを作ってみた。

良くあるネタだけど…
乾電池駆動の環境センサー(温度、湿度、気圧)を作ってみた。
(arduino1.6.7+esp8266core2.1.0、iotSDK1.5.2)

本体はESP-WROOM-02、センサーはBME280を使用。
電源は乾電池3本からレギュレータで3.3Vを得る。
10分ごとにBME280から環境データを取得。
  • CaptivePortalでのセットアップ
    webで各種設定を行う
  • マルチAP対応
    AP毎にstaticIP/DHCPクライアントの設定が可能
  • ThingSpeak対応
  • 常時起動モード
    内部RAMに1日分のデータ保持。
    webでのグラフ化
    csvダウンロード
  • スリープモード
    ThingSpeak専用
    データ送信後にスリープ
  • AE-FT234X用デバッグインターフェイス
  • 電源切替(USB/バッテリー)

テスト的に、自電源の電圧を取得。
バッテリー残量の目安になるか…?
とはいえ、レギュレータを通ってるから電圧が落ち始めたらあっと言う間に電池切れになるような。

入れ物は100均で4個100円のタッパー。
DSC_0208.jpg
タッパー以外は全部秋月で手に入る部品で。
BME280は背が高いので、曲げられる足を付けてタッパーの蓋が閉められるように調整。
小さい基板に纏めたかったので、電源ライン以外はポリウレタン銅線。
大して発熱はしないだろうけど、一応センサーとレギュレータは離して配置。

 
DSC_0209.jpg
蓋を閉じると完全にタッパー。
冷蔵庫の中に置いてあっても不自然ない仕上がり。

部品代はおおよそ2500円ぐらいかな?

作ってみて解ったこと。
スリープの時、GPIOの出力状態は維持されない、ってのは知ってたけど…
LEDを繋いでいると、スリープ中にぼやーっと光ってしまう事がある。
ジャンパでLEDを切り離せるようにしたけど、もっとスマートな方法はないものか…


カテゴリ:電子工作

ESP-WROOM-02 JavaScriptライブラリはCDNから使おう

もうESPどうのの話より、webアプリの話だけども。

ESP8266でリッチなwebGUIを作ってると、どうしてもJavaScriptのダウンロードが遅くて、GUIがなかなか表示されない。
ボトルネックはESPからPCに巨大な(と言っても数KBだけど)をダウンロードする時。

解決策は2つ。
  • httpリクエストに対して304を返せるようにする。
  • jsだけ高速で通信できる場所に置く。

前者はめんどくさそうなので、簡単な後者を選択。
って、普通にdygraphのダウンロードページにCDNのリンクがおいてあった。
https://cdnjs.com/libraries/dygraph

このcdnjs.com、他にも色んなjsを置いてあるようで…
他にも使いたいjsがあれば、cdnjsから引っ張ってきたらESPの速度や容量を気にしなくてよさそう。

以前使ってみようと思ってすっかり忘れてたamchartsもあった。めもめも。
https://cdnjs.com/libraries/amcharts


と言うわけで、高速化できた。
jsのダウンロードに30秒以上かかってたのが一瞬で終わるように。
dygraph-cdn.png
最近のfirefoxはデバッグ機能が色々ついてるので、なにげに便利だったり。
ちなみに、上のネットワークツールを開くのはCTRL+SHIFT+Q。



カテゴリ:電子工作

ESP-WROOM-02 ネットワークが定期的に切断する

ESP-WROOM-02で遊んでて、およそ5分毎に無線LANが切断される現象。
(Arduino1.6.7+esp8266core2.0.0)

wl_status_tの遷移を記録してみたら、こんな感じに。

6 (WL_DISCONNECTED)
1 (WL_NO_SSID_AVAIL)
3 (WL_CONNECTED)

5分ぐらい無通信が続くと…

4 (WL_CONNECT_FAILED)
1 (WL_NO_SSID_AVAIL)
3 (WL_CONNECTED)

ずっと無通信だったら、これを5分毎に繰り返す。
wifi_set_sleep_typeを変えてみてもこの現象は発生する。
外部からpingを打ち続けたらこの現象は発生せず。
WL_CONNECT_FAILDからWL_CONNECTEDに遷移する間はホントに切断されてるようで、この瞬間はpingも落とす。
不具合なのか、そう言う仕様なのか…

とおもったら、esp8266core2.1.0で改善されてた
ただ、2.1.0ってコンパイルするとwarningがいっぱい出てちょっと気持ち悪い。
あんまり問題があるような内容じゃないので無視でいいんだけども…
取り敢えずコンパイラの警告をAllからMoreに下げておいた。

カテゴリ:電子工作

ESP-WROOM-02 BASIC認証

ESP8266 ArduinoCore2.1.0から、BASIC認証がESP8266WebServerに実装されました。
が、動きません。
サンプル(HttpBasicAuth)のコンパイルは通るけど、認証を通した段階でException(2)でスタック吐いて止まる。
色んな意味で期待を裏切りません。
※2.3.0で修正された模様。

と言うわけで中身を調査。

ライブラリ本体はイカの場所に。
C:\Users\%USERNAME%\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.1.0\libraries\ESP8266WebServer\src\ESP8266WebServer.cpp


bool ESP8266WebServer::authenticate(const char * username, const char * password)

この関数を抜けるときにほぼ必ず「Exception (2)」でこける。

コケ方がどうにも不可解で、107行目の

sprintf(toencode, "%s:%s", username, password);

を通ると必ずコケる。
どう考えても怪しいのはtoencode。
初期化はこうなっていた。

char toencodeLen = strlen(username)+strlen(password)+1;
char *toencode = new char[toencodeLen];

toencodeLenがなんでcharなのかっていうツッコミはおいといて…
username="hoge"、password="fuga"だとして、sprintfで出力されるのは"hoge:fuga"で9バイト。
toencodeLenも9になる。
あれ?sprintfって最後に\0が入るよな…って事は1バイト足らんじゃないの。

と言うわけで、96行目のtoencodeの初期化を1バイト増やす。

char *toencode = new char[toencodeLen+1];

動いた動いた。


カテゴリ:電子工作

次のページ

FC2Ad