2017年4月22日土曜日

PICkit ICSPの簡単利用

ブレッドボードにICSPの回路を作るのすら面倒な貴方へ。

こうすれば、めちゃくちゃ楽です。
DIPテストクリップに、オス⇔メスのコードを5本繋いで使う。
IC単体、ブレッドボード、本番の回路問わずそのままプログラムできる。


秋月だと28PINか40PINしかないけど、aitendoなら8PINもある。
17/4/22現在で\850。私が秋葉で昔買ったときも\800くらいだったと思う。
 http://www.aitendo.com/product/14967

PICのICSPはだいたい8ピンの範囲に収まっていてありがたい。


フィラメント管で時計を作る(準備編)

昔買ったフィラメント管:IV-9で時計のような数字表示機を作った。
↓完成したものの動画。ケースはレゴで作成。



■フィラメント管IV-9
購入元は秋葉原の真空管屋さん。(サンエイ電機)
今売っているかはわからないけど、1個300円くらいだった。

データシートもネットですぐ見つかる。
 http://www.tube-tester.com/sites/nixie/data/IV-9/iv-9.htm

ニキシー管と違って数Vの低圧で動き、1セグは20mAくらい。
Typの電圧は4.5Vらしいが、アルカリ2本の3Vでも十分光る。
手持ちの4つだと、ピンに限らず3V~5Vの範囲では、消費電流はほとんど変わらなかった。

一般的には共通の1ピンをGNDにし、7セグ相当の3~9ピンと右下のドットの2ピンに正の電圧をかけるらしい。
ダイナミック制御でもうまく光ったが、ネットの作例を見るとスタティックのものが多い。
ロングランでは試していないけど、ダイナミックだとフィラメントにダメージがあるのだろうか?

■PICによるスタティックドライブ
スタティックで点灯させるなら、駆動は1管8個なので4つなら32個必要。
20mA×32個なので最大640mAになる。1管あたりは180mA。
Trをいっぱい並べるのも面倒なので普通は7セグドライバIC(74HC4511)とかTrアレイを使うけど、手持ちで古いPIC(PIC16F648A)が大量に余っていたのでこれを活用する。

このPICは1ピンでぎりぎり20mA出せて、チップ単位で200mAまでOK。
IOもDOがRA0~4, 6, 7とRB0~7の15本がある。
ただし、RA4はオープンドレインなのでDOだと電流吸い込みしかできないので注意。
また、シリアルを使うならRB1:RX, RB2:TXも埋まる。

今回は、アノードコモンとしRA系で7セグを点灯、RB0で2ピンのドットを点灯、baud 9600のUARTで数値を受けることにした。
ネットで作例を探すと、1つのTXから複数のRXを繋いでもうまくいくようだ。

最初の1字でA~Dを送り、管を区別させることにした。
2文字目で表示内容を送る。

2文字ファンクション
0~9数字表示
!全消灯
スペースドット消灯(2ピン)
.ドット表示(2ピン)

例えば「1234.」としたければ、シリアルで以下のコマンドを送る。
 [A1B2C3D4A B C D.]
すべて消灯なら次のコマンド。
 [A!B!C!D!]

■RX並列のテスト
基板を組んでからでは遅いので、RX並列でうまく管の切り分けが可能か確かめる。
上記ファンクションのうち、RB0にLEDを繋いでテストした。

左から順にA, B, C, Dで、[A!B.C.D!]とコマンドを送ると・・・。

結果、問題なく成功。
本当はPICごとに抵抗を繋いだほうがいいかもしれないけど、手抜きでPC側にだけ100Ωを繋いでいる。



あとは、基板を作ってIV-9とPICを繋ぐのみ。

ESP8266でデータロガー(UDP Client)

Switch ScienceのESPr Developperを使えばブレッドボードで即席ロガーが作れる。
左真ん中に繋がっている汚い線が秋月のドア開閉センサで、
左上のICが温度センサのLM61。


ESPr Developperは大事な端子が片側に集まっているので、凝ったことをしなければ小さいブレッドボードで十分。
左側には3.3Vがないので、2つのDiodeで5V⇒4.2V⇒3.4Vを作成。

・ケース入りリードスイッチ
 http://akizukidenshi.com/catalog/g/gP-04025/
・LM61BIZ(4個入りのほうがオススメ)
 http://akizukidenshi.com/catalog/g/gI-09691/

センサデータは、UDPを使ってRasPiで動くRubyのサーバアプリに送信、テキストに直接保存する。


■温度センサ
LM61はリニアな電圧で温度が測れる便利なICで、LM35と違って負電圧にならないので使いやすい。

↓データシートのTyp値。
温度電圧
+100℃+1600mV
+85℃+1450mV
+25℃+850mV
0℃+600mV
-25℃+350mV
-35℃+300mV

式を整理すると、次のようになる。
 <温度>[℃] = (<電圧>[V] - 0.6)×0.1

ESP8266のHTTP Clientと割り込み(Ticker, Timer)でハマる。

ESPr Developer / ESP8266 / ESP-WROOM-02でThingSpeakにデータ送信。
ThingSpeakは15秒の制限があるので、30秒周期でデータを送ることに。

自然な発想でTimerを仕込むが、何故かうまく通信できない。
UDPならうまく行ったのに何故??

参考にしたのは以下のサイト。
 http://www.esp8266.com/viewtopic.php?p=62981

// ソースはこんな感じ
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <Ticker.h>
extern "C" {
  #include "user_interface.h"
}

const char* SSID = "<SSID>", PASS= "<PASS>";
Ticker tic1;
void setup() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(SSID, PASS);
  while (WiFi.status() != WL_CONNECTED) delay(500);
  IPAddress myIP = WiFi.localIP();
  tic1.attach_ms(30 * 1000, tic1_loop); // 30秒に1回、tic1_loopを実行
}

void sendMessage(String buf) {
  HTTPClient http;
  String url = "http://api.thingspeak.com/update?key=";
  String key = <ThingSpeak API KEY>;
  http.begin(url + key + buf);
  int httpCode = http.GET();
  if(httpCode) {
      Serial.printf("[HTTP] GET... code: %d\n", httpCode);
      if(httpCode == 200) {
          String payload = http.getString();
          Serial.println(payload);
      }
  } else {
      Serial.printf("[HTTP] GET... failed, error: %d\n", httpCode);
  }
  http.end();
}

void tic1_loop(){
  sendMessage(<センサデータ>);
}
void loop{}


いろいろ試行錯誤して気づいたのだが、HTTPClientも割り込みを使うので割り込みの中では使えない。
検証は以下の通り。
1)sendMessage()を単体で呼ぶ ⇒OK
2)loop内でdelayでsendMessage()を何度も動かす ⇒OK
3)Timer割り込みでsendMessage()を何度も動かす ⇒NG

noInterrupts()なのが問題なのでinterrupts()を明示的に呼び出せばHTTPClientも動くはずだが、今回はシンプルにフラグ処理で逃げることにした。


char flag = 0;void interruptFunc(){
  flag = 1;
}

void loop{
  if(flag){
    sendMessage(<センサデータ>);
    flag = 0;
  }
}

これでOKだった。
ESP8266は1か月以上動かしているけど、元気に温度とドアの開閉を記録してくれている。