ESP8266-01の接続(その3)

Arduino Pro Mini 3.3V, 8MHz から、EASP8266-01を経由してWiFiに接続するにあたって、いくつかの条件を満たしたいと考えていました。

  1. Arduino Pro Miniと、ESP8266との間は、デフォルトのまま、115200 baudのシリアル通信速度で通信したい。
  2. この本来のシリアル通信の他に、FTDI経由で Arduino Pro Miniに色々なコマンドを打ち込んだりして、ESP8266との通信(WiFi通信)をインタラクティブに実験したい。そのため、2つめのシリアル通信ポートをSoftwareSerialのライブラリを使って実現したい。
  3. Arduino Pro Miniの本来のシリアル通信は、ATmega328Pのデバイスに搭載されているハードを使っているので、115200 baud以上の通信でも問題ないが、SoftwareSerialのライブラリのシリアル通信では、このスピードが出ないという記事が沢山投稿されている。せいぜい9600baud程度が実用的な速度という記事もあり(8MHz のArduinoに於いて)、とても 115200 baudを期待することはできそうにも無い。
  4. FTDI経由のWiFi実験用、インタラクティブな操作(シリアル入出力)は、9600baud程度でも問題ないと思われる。
  5. Arduinoにプログラムを書き込むときには、FTDIから高速で書き込みたい。

このような条件を、Arduinoへのプログラム時と、プログラム後の実行時で、FTDIの接続を変更することにより実現することにしました。

【Arduinoへのプログラム時】

接続は、下図の通り、FTDIのTXをProMiniのRXI, FTDIのRXをProMiniのTXOに接続し、USBからの電源は、FTDIへの電源供給のみとして、Pro Miniは、ESP8266との接続を考慮して、別電源の3.3Vから取っています。(もちろん、GNDはFTDIとPro Miniの間で接続しておく必要があります)

Pro Miniの基板端には、FTDIのピン配列に合わせたピンが出ていますが、下の写真のように、プロとボードの接続を使いたかったため、このFTDI用のピンは使わず、側面にあるTXO端子(D0), RXI端子(D1)のピンにジャンパーで接続しています。

なお、FTDIからのDTR信号をProMiniのDTRピン(GRNピン)に接続した場合、Pro Miniの基板内で、下記のように 0.1uFを経由してリセット端子に接続される事により、ATmegaへの書き込み時に自動的にリセットが掛かるようになっています。うまく考えられているなぁ、と感心します。

ただ、ArduinoのIDEからスケッチが書き込まれる直前(コンパイルが終わった直後)に、タイミング良く、Pro Miniに搭載されているリセットスイッチを、チョンと押してやると、書き込みは正常にできますので、このDTRの接続は必須ではないです。(チョン・・のタイミングは、ちょっと気を使いますが・・・)

imageDSC09727

これで、FTDI経由でPro Miniのプログラミングが出来ることを確認できました。

次は、SoftwareSerialライブラリを使った、二つ目のシリアルポートを構築したスケッチを用意して、プログラムが終わった時点で、FTDIの接続を変更して、二つ目のシリアルポートを、「シリアルモニタ」に繋いでみようと思います。

この切替えを、少しでも楽にするために、最小限の接続 (TXとRXだけ)で、FTDIをつなぎたかった訳です。 (残念ながら、手元にFTDI が一つしか無いため・・・。もう一つ、買う必要あり・・・)

【二つ目のシリアルポートを構成する】

パルスのエッジ割り込みとタイマー割り込みを使った計測に変更してみた。

以前の投稿で、一定時間内に入ったパルスの数を数えて、ワイヤレスモジュール(nRF21L01+)を使って通信するという実験をしましたが、いくつかの不具合があったので、修正してみることにしました。

【不具合の色々】

  1. 10秒毎のタイマー割り込みを設定していたつもりだったが、正確に10秒になっていない
  2. パルス入力に「チャタリング除去」を使っていたが、測定対象のパルスの幅が非常に短く、場合によっては捕まらない事がある。
  3. 測定結果をUSB経由のシリアル通信でパソコンに取り込んで使う必要があるが、何らかの理由でパソコン側のシリアルバッファにデータが溜まってしまった際(吐き出す処理が滞った場合)、実際に計測された時刻がいつだったのかわからなくなる。

さらに、この際、余分な機能(温度測定とか)を全部取り除いて、コードをきれいに書き直すことにしました。

【不具合への対応】

上記の各不具合に対して、次のような対応をしました。

  1. Timer2割り込みに設定する値を修正して、ほぼ正確に10秒毎に割り込みが掛かるようにした。
  2. パルス入力を”INT0”ピンを使ったエッジ割り込み(立上り)に変更した。
  3. パルス計測結果をRFで(nRF24L01経由で)送信する際に、RTCモジュールを使って「送信時刻」を送信パケットのデータに含めることにした。

【1: Timer2割り込みを正確に10秒毎に】

まずは、以下の単純コードでTimer2とSerial.printだけのコードで、確認してみました。

#include <MsTimer2.h>	//タイマー割り込み用のヘッダー

#define TMR2_INT 10000	//10秒なら10000 msecと設定すれば良いはずなのだが・・・A
volatile bool isTimer2Int = false;	//割り込みあり無しをメインループへ伝えるフラグ

void timer2ISR()	//Timer2割り込みの処理ルーチン。出来るだけ早く抜ける
{
  isTimer2Int = true; // ISR for Timer2
}

void setup()
{
  Serial.begin(115200);
  MsTimer2::set(TMR2_INT, timer2ISR);	//割り込み周期と割り込みルーチンの設定
  MsTimer2::start(); // Timer2割り込み開始
}

void loop()
{

  if (isTimer2Int) {	//割り込みが入った次のメインループで実際の処理を実施する
    isTimer2Int = false;	//割り込みフラグをクリア
    Serial.println(millis());
  }
} 


このコードを走らせてみると、設定した通り、10000msec毎に正確に 10000ずつ差のある mills()の数字が表示されます。ということは、ATmega328のコントローラー自体は、ちゃんと正確に 10000ms毎に割り込みをかけているつもりになっている事になります。

ただ、実際の時計と比較して長時間走らせると、ずれが発生しているのは事実ですので、要するにArduino Nanoのクロック精度がその程度ということだと思われます。 

Timer2の設定を10000 (すなわち10.000秒)にして、RTC (DS3231のReal Time Clock)の時計出力と比較実験すると、約114回毎、すなわち1140秒毎に約1秒遅れていくことが観測されていますので、ズレは、1/1140 (=0.0877%) 程度となります。 Arduino Nanoに搭載されているクロック源は、16MHzのセラミック振動子(セラロック)であり、仕様書によると初期周波数の偏差は±0.5%にもなりますので、今回の実験結果は 0.09%程度というのは、充分仕様内と言えます。 これ以上の精度をセラロックに求めるのは無理ですので、まぁ、今回のプロジェクトでは、「現物合わせ」の手法で対応するのが妥当という事になりますね。

もっと、精度が必要な場合は、水晶振動子を使うしか無いですね。

現物合わせとしては、Timer2の割り込み周期を ずれている分だけ長くしてあげることにしました。10000 * (1/1140 + 1) = 約10008.7719 (四捨五入して 10009) を設定して実験してみたところ、(実用的なレベルで)正確に10秒ごとに割り込みが入るようになりました。

追記: 周波数カウンタとかオシロとかが手元にあれば、確実に検証できるでしょう。安いUSBのオシロが欲しくなってきました。

【2.パルス入力をINT0割り込みへ変更】

最初に設計した際、パルスは通常のDigital Readで読んで、20msec毎にチャタリング処理をした上で、パルスの有り無しを判断するように作りました。実験中に普通のタクトスイッチでパルス検討する際には、これが必須でした(チャタリングを取らないと、まともなパルス計測ができません)

ところが、実際に測定したい装置に導入してみた際、パルスのデューティー比が非常に大きく、”H”レベルが50msec から 70msec程度、”L”レベルが800msec程度であったため、チャタリング処理が逆に邪魔をして、パルスを取り込めない場合が時々ありました。この装置に於けるパルスを現場で確認したところ、チャタリングは無く、きれいな波形でしたので、この際、割り込みを使ったパルス検出方法へ変更することにしました。 (チャタリングがある場合には、割り込みによるパルス入力検出は難しい気がします)

Arduinoに於けるパルス割り込みは、INT0 (D2 ピン) で簡単に使えます。単純化したコードはこんな感じです。10秒の間に入ったパルスの数を数えて、10秒ごとにシリアルに書き出すソフトです。前述した通り、10秒の割り込みには、Timer2を使いますが、クロック精度の現物合わせで 10009という補正したカウントで割り込みをかけます。

常識として、「割り込みの中で時間のかかる処理は、避けるべき」という鉄則がありますので、どちらの割り込みも、フラグを設定したり、カウンターをインクリメントするだけにして、時間のかかる処理は、メインループの中でTimer2の割り込み毎に処理します。

#include <MsTimer2.h>

#define TMR2_INT 10009	// 0.09%の補正後
volatile bool isTimer2Int = false;
void timer2ISR()	// Timer2割り込み処理ルーチン
{
  isTimer2Int = true; // ISR for Timer2	フラグを立てるだけで抜ける。
}

#define INPUT_PIN_1 2	// 割り込みピンはD2 (INT0)を使用。
volatile uint16_t pulse_count = 0;	//パルス計数用のカウンタ (Volatile宣言・・・勉強中・・・)
void risingISR() 	// パルス立上りエッジの割り込み処理ルーチン
{
  ++pulse_count;	// カウンターをIncrementするだけで抜ける。
}


/****************************************
    Setup
*****************************************/
void setup()
{
  Serial.begin(115200); // 115200 baud

  MsTimer2::set(TMR2_INT, timer2ISR);
  MsTimer2::start(); // interrupt start

  pinMode(INPUT_PIN_1, INPUT_PULLUP); // pulse input pin
  attachInterrupt(0, risingISR, RISING); //pin D2 (INT0) RISING EDGE detect
	// この記述で、「INT0信号の立上りエッジ検出し、指定されたルーチンを開始する」になります

}

/**************************************************
   Main Loop
**************************************************/
void loop()
{

  if (isTimer2Int) {	// 10秒毎
    isTimer2Int = false;	//フラグをクリア
    c = pulse_count;	// この瞬間までに計測された数字をコピーしてクリアする。
    pulse_count = 0;	// この2つの文の間に割り込みが掛かるとずれるリスクがあるので、
			// 本当は割り込みを禁止すべき・・・と思う。
    Serial.println(c);	// 数をシリアルに出力
  } 
} 


これで、D2ピン(INT0)に接続された信号の、すべての立上りエッジを割り込みで取り込んで、カウントできるので、いくらパルスのデューティーが大きくても(どれだけ、パルスの”H”期間が短くても)正確に、パルス数を数えられます。逆に、副作用としては、パルスにチャタリングがある場合は、正しく数えられません。(チャタリングを全部数えてしまうから・・・)

【パルスを計測した時刻を正確に出力できるようにする】

【次ページへ続きます】

ESP8266-01の接続(その2)

【ESP8266 ESP-01の回路・基板もう少し調査】

前回の確認で、やはりリセットが怪しいので、もう少し基板内でRESETピンがどのように接続されているのかを確認してみたいと思います。

ESP-01の回路図は、今のところネット上を探してもそれらしき、ピッタリするものが見つからないので、版下の情報から類推してみることにしました。

image

この基板レイアウト図上では、RESETピンは、”GPIO16”と記載されていますが、これについてはもう少し後で調べてみることにします。このピンからの配線を「むりやり」たどってみると ESP8266EXのICの、32ピン(EXT_RSTB)に直接つながっているように見えます。途中にプルアップ抵抗や、POR用のコンデンサ等は見当たりません。

EXP8266のデータシートver 4.9) を見ても、何故か、リセットに関する詳細な記載は見当たりません。、

image これだけ・・・

ただ、Version 4.9のデータシートには、8ピン(XPD_DCDC, GPIO16, Deep-Sleep Wakeup)を EXT_RSTBに接続する必要があるとの記載があります。

image

多分、Deep Sleepからの復帰は、デバイスの初期リセットを掛けることによってのみ実現できるという事でしょう。そういう視点で上記の基板レイアウトの8ピンを確認してみたのですが、どう見てもこのピンはオープン(未接続)のように見えます。いずれにせよ、Deep Sleepに入ってしまった後は、RESETピンでデバイス全部をを強制リセッしてしまえば、復帰するという事でしょうから、未接続でも良いのかもしれません(となると、このピンの意味って何かあるのか・・・? よく分かりません) –> 後述【おまけ】で少しスッキリ・・・。

Power Onシーケンスに関して、こんな記事も見つけましたが、なんとなくピンと来ない説明です。

まぁ、私なりの結論としては、「このモジュール基板には、Power On Reset機能は搭載されていないため、ちゃんと、外部回路で構成してあげないとRESETが正常にかからない」 という事ですね。 現実の実験結果からも同じ結論ですけど。

【おまけ】

Wake Upに関するこんな資料がありました。Espressif.com (ESP8266の開発元)のサイトにあった、Low Power Solutionの説明です。

image

つまり、Deep Sleepモードからの復帰には、Automaticモードと外部トリガモードがあり、Automaticモードの時には、GPIO16 (XPD_DCDC)が EXT_RSTBに接続されている場合、Sleep時間が経過した後、このGPIO16の’L’レベルパルス信号(出力)がEXT_RSTBピン(入力)へ供給されて、デバイスがリセットされる・・・という事でしょうか。 ちょっと英語の読解力が不足していて、若干自信が無いですが・・・

GPIO16とEXT_RSTBが接続されていない場合には、Deep Sleepからの Automatic Wake Upは出来ないという事になるのでしょうね。

【次に続く】

ESP8266-01とArduino Pro Mini 3.3Vを接続してみた (その1)

WiFiのモジュール ESP8266-01と、Arduino Pro Mini 3.3V, 8MHzを接続して、ネットワーク経由で色々な遊びを始めてみることにしました。

【ESP8266-01モジュール】  (参考にさせて頂いたページ

ESP8266モジュールの中では最も小さくて端子数の少ないESP-01タイプで実験をしてみます。モジュール仕様はこのページを参考にしました。 これによると、なかなか強力なスペックです。

  • このモジュール単体でホストコントローラーとして動作可能
  • 2本のGPIOピンを直接センサー等に接続することも可能
  • I/Oは 3.6V耐圧なので、5V回路とは直接接続不可能。
  • 電源電圧は 3.3V
  • 初期ボーレートは 115200 baudに設定されている
  • TCP/IPプロトコル・スタックを内蔵
  • 802.11b/g/n対応
  • 通常動作時の消費電流は 70mA程度
  • ピーク時の消費電流は 300mA程度
  • パワーダウン時の消費電流は、 10uA以下
  • 802.11b時のRF出力は +19.5dBm
  • WPA, WPA2対応

このモジュールに搭載されているICは、ESP8266EX(WiFiコントローラー)と、Berg MicroのSerial EEPROM:25Q80ASSIG)の2つ。

Wed Sep 21 21-25-02

このICがモジュールの肝となるデバイスですね。(仕様書はこちら

Wed Sep 21 21-22-57

このBerg MicroのICは型名から見ると、

  • 3.0V Serial Flash with 4KB uniform-sector, dual and quad I/O
  • 8Mbit (1024kx8)

という事がわかります。(メーカーは違いますが仕様書はこちら)。 このEEPROMに8266用のFirmwareが保存されているという事ですね。

ESP8266の消費電流がピークで 300mAも必要というなので、Arduino Pro Miniに搭載されている3.3V レギュレーター(Pro Miniの回路図上に最大150mAという記載があります) や、FTDIに搭載されているレギュレーターでは足りません。

まずは、実験なので手元にある、プロトボード用の電源モジュールを使って電源を供給することにします。

DSC09701

 

【まずは、シリアル通信の確認から】

まずは、Arduino Pro Miniは接続せず、FTDI (3.3V)を使って、ESP8266とのシリアル通信を確立させ、ATコマンドが動作するかどうかの確認からはじめます。本当は、RESETも、CH-PDも独立でPULL-UPしておく方が良いと思いますが、プロトボードの接続を楽にするために、サボりました。

Picture of ESP8266-01 Pins

ESP8226_01_BootOptions.jpg

ESP-01のモジュールのGPIOピン二本の設定を変えることにより、通常ブートモード(内部のEEPROMからの起動)と、EEPROMへの書き込みモードの切り替えができます。まずは、普通に立ち上げる確認なので、GPIO-0は、Hにしておきます。(ネットの情報だと、GPIO-2はオープンのままにしてある例もありますが、とりあえず、GPIO-0と直接繋いでおきます)

CH-PDのピンは、8266をパワーダウンモードに切り替えるための信号なので、通常動作モードのときには、Hにしておかないといけません。

RESETピンの扱いがちょっと自信ないです。ESP8266-01モジュールの回路図をネット上で探しましたが、現時点、それらしき物は見つかっておらず、この基板内で ESP8266デバイスのリセットピンが、どのように処理されているのか分からないためです。単純に端子に出てきているだけかもしれません。

【接続図】

image

FTDIとの接続は、シリアル通信の向きを間違えなければ大丈夫でしょう。もちろん、FTDIの電圧セレクターは、3.3Vにしておきます(間違えると ESP8266が死ぬのでは・・と思われます・・)

DSC09703

 

【TeraTermで接続】

まずは、定番のターミナルソフト、TeraTermで接続してみます。TeraTermを起動し、以下の設定をします。

  • FTDIの接続されているUSBに割り当てられたシリアルポート番号を指定
  • 115200baud, 8bit, non-parity, 1-stop bit, flow制御=none
  • 送信の改行コードは”CR+LF”
  • 文字コードは UTF-8 (不要かも)

電源アダプターからの電源を供給し、USBも接続してみると、文字化けした画面の後に、”Ready”という表示が出るときがあったり、こんな画面が出て止まってしまう時があったり・・・(追記:後で調べてみたら、この表示は 76.8kbpsで出力されているものらしい・・・でも何故、表示されるんだろう・・?)

image

やっぱり、ESP8266へのリセットが正しくかかっていないと思われ、とりあえず強制的に、ESP8266モジュールのRESETピンをGNDに落として見ると、ぐちゃぐちゃに文字化けした表示の後に、必ず、”Ready”が表示されるようになりました。

image

ここで、”AT”と叩いてみると、めでたしめでたし、”OK”表示が出ました。

image

試しに、GPIO-2の接続を外してオープンにしても、同様に動作したので、当面GPIO-2はオープンのままにしておくことにします。

それにしても、なぜ、リセット後の文字が激しく化けるのか?スッキリしなかったので、色々試してみましたが、全然だめ。ネットで色々探してみたら、「リセット後の通信は76.8kbpsで行われる」という記述がありました。手元に76.8kbpsのターミナルソフトが無いので、事実かどうか調べることは出来ませんが、まぁ、readyの所からは、115200baudで正常に通信できるので、今の時点ではこれでOKとしておきます。(なぜ76.8kbpsになっているのか、理由は全く分かりません)

【ArduinoのIDEからシリアルモニタで接続】

やはり、リセット直後の文字化けは起こりますが、CR/LFにした上で、”AT” + Enterを送信すれば、ちゃんと下記のように “OK”が返ってきました。めでたしめでたし。

image

とりあえず、これで、ESP8266-01とのシリアル通信が出来ることは確認できました。

試しに、ATコマンドを幾つか確認し、我が家のWIFIアクセスポイントにも接続してみましたが、問題なく一発で接続されました。このATコマンドの詳細は次回に・・・。

image

【次に続く】

熱電対を使ってはんだコテ先の温度制御にトライ・・・酸化防止(その3)

 

【ソフト】

試行錯誤しながら作ったソフトは以下のとおり。

  1. MAX6675からのデータ読み出しは、Adafruitのライブラリをそのまま利用し、周期を正確にするため、Timer2割り込みを使用した。
  2. I2Cの 7segment 4桁 LEDは、AdafruitのBackpack ライブラリをそのまま利用した。
  3. 温度制御VRからのAD値は 0から 1023なので、最大設定温度を 400℃にすべく、以下の計算式を使った。( t_max = vr * 150.0 / 750.0 + 200.0 )
  4. VRの値が32より小さい時は「OFF」とする。
  5. 熱電対の温度が設定温度に近づくにつれて、供給する電力を減らすことにより、オーバーシュートを減らす。(温度差90度以上:100%, 温度差60度以上: 87.5%, 温度差30度以上:50%, 温度差20度以上:37.5%, 温度差10度以上: 25%, 温度差5℃以上: 12.5%, 温度差5度以下: 電力供給を止める。 電力制限は、500msec毎にON/OFFすることによって実現する(8パターン)
  6. 電源供給中は、LEDのコロンマークを点灯させる
  7. OFF状態に於いて、コテ先温度の状況によって、LEDのドット表示を変化させる。(60℃以上:ドット4個点灯、50℃以上:3個点灯、40℃以上:2個点灯、40℃以下:1個点灯。)これによって、OFF状態においても、コテ先の温度が充分下がったかどうかを確認できるので安心感がある。(輝度も落とす)

最終的なコードは以下の通り

//
//
//  Soldering Iron Tip temperature controller
//
//  2016/9/17,
//

#include "Wire.h"
#include "Adafruit_LEDBackpack.h"

#include "max6675.h"
#include "MsTimer2.h"
#define TMR2_INT 500

MAX6675 TC1(A3, A2, A1); // = (CLK,CS,DO) , define pins for thermocouple1
Adafruit_7segment matrix = Adafruit_7segment();

#define SSR_PIN 3
#define VR_PIN  A0

bool isTimer2Int = false;
int cnt8 = 0;

// on-level          0,     1,    2,   3,    4,    5,    6,    7,    8
//                   0% 12.5%   25% 37.5%   50% 62.5%   75%  87.5% 100%
int strength[9] = {0x00, 0x80, 0x88, 0x89, 0xaa, 0xab, 0xee, 0xfe, 0xff};

void timer2ISR()
{
  isTimer2Int = true; // ISR for Timer2
  if (++cnt8 > 7) cnt8 = 0;   // for power control by 1/8 resolution
}

/****************************************
    Setup
*****************************************/
void setup()
{
  Serial.begin(115200); // 115200 baud
  matrix.begin(0x70);
  matrix.setBrightness(8);
  matrix.clear();

  digitalWrite(SSR_PIN, LOW);
  pinMode(SSR_PIN, OUTPUT);

  MsTimer2::set(TMR2_INT, timer2ISR);
  MsTimer2::start();
}

/**************************************************
   Main Loop
**************************************************/
void loop()
{
  double temp1;
  double t_max, t_min, t_delta;
  int vr;
  int temp2;
  int p_level;

  if (isTimer2Int) {
    isTimer2Int = false;

    temp1 = TC1.readCelsius();
    vr = analogRead(VR_PIN);
    temp2 = (int)(temp1 * 10.0);

    t_max = vr * 150.0 / 750.0 + 200.0; //max 400 degree when ADC = 1000
    //   Serial.print(t_max, 1);
    //   Serial.print(",");
    Serial.println(temp1, 1);

    t_delta = t_max - temp1; // if still need to up

    if (vr < 32) {
      digitalWrite(SSR_PIN, LOW); // power-off regardless to the temperature
      display_off(temp1);
    } else {
      if (t_delta > 0) {
        if (t_delta > 90.0) p_level = strength[8];      //100%
        else if (t_delta > 60.0) p_level = strength[5]; //87.5%
        else if (t_delta > 30.0) p_level = strength[4]; //50%
        else if (t_delta > 20.0) p_level = strength[3]; //37.5%
        else if (t_delta > 10.0) p_level = strength[2]; //25%
        else if (t_delta > 5.0) p_level = strength[1];  //12.5%
        else p_level = strength[0]; //0%  stop heating when it reaches to 5 degree below the target

        if ((p_level >> cnt8) & 0x01) {
          digitalWrite(SSR_PIN, HIGH);
          matrix.drawColon(true);
        } else {
          digitalWrite(SSR_PIN, LOW);
          matrix.drawColon(false);
        }
      } else {
        digitalWrite(SSR_PIN, LOW);  // if temp1 is higher than target then off,
        matrix.drawColon(false);
      }
      matrix.writeDigitNum(0, (temp2 / 1000), false);
      matrix.writeDigitNum(1, (temp2 / 100) % 10, false);
      matrix.writeDigitNum(3, (temp2 / 10) % 10, true);
      matrix.writeDigitNum(4, temp2 % 10, false);
      matrix.writeDisplay();
    }
  }
}

//
//  display "OFF" on the LED display
//
void display_off(double t)
{

  matrix.setBrightness(2);
  matrix.drawColon(false);
  matrix.writeDigitRaw(0, 0); //blank
  matrix.writeDigitRaw(1, 0); //blank
  matrix.writeDigitRaw(3, 0); //blank

  if (t > 60) matrix.writeDigitRaw(0, 0x80); //blank with dot.
  if (t > 50) matrix.writeDigitRaw(1, 0x80); //blank with dot.
  if (t > 40) matrix.writeDigitRaw(3, 0x80); //blank with dot.
  matrix.writeDigitRaw(4, 0x80); //blank with dot.

  matrix.writeDisplay();
}

このコードによる、温度制御結果のグラフはこんな感じ。(OFFから、350℃設定と、300℃設定でそれぞれ、ONした場合の約3分間、温度推移)

電源ONからほぼ30秒で設定温度に達したあと、若干のオーバーシュートはあるが、その後は安定して設定温度近辺で制御されていると言える。 一応、これで当初の目的は達成!!

image

という事で、このプロジェクトは、一旦ここで終了!!

その1に戻る】 【その2に戻る

Arduino Pro Mini と FTDIとの接続

eBayに注文していた Arduino Pro Mini 3.3V 8MHz のモジュールが届いたので、早速動作確認をしてみることにしました。

Arduino Pro Mini 3.3V 8MHz AtMega328P】 5個で$8.56でした。(from China)

DSC09687

同梱されていたピンヘッダーをはんだ付けした後の写真です。

FTDI232 5V/3.3V 切り替え付き】 1個で $4.98 (from US Seller)

DSC09686

こちらは、ピンヘッダーがはんだ付けされた状態で納品されました。  ProMiniが3.3V仕様なので、電圧選択用のジャンパーを、 3V側に変更する必要があります(写真では上側が 3.3V設定・・・シルク印刷が見にくい・・・)

【ピン配列と接続】

当然ながら説明書などは同梱されていないので、ネットで接続情報を調べてみましたが、なんとなくスッキリしないので、回路図から確認してみました。

image

ヘッダーに印刷されている信号名は、GRN, TXO, RXI, VCC, GND, BLKとなっていますが、回路図とは、一見して全然一致しているように思えません。ただ、ネットのいろんな情報を見ると、順番通りつなぐ・・・となってます・・・。

FTDI-BASIC の回路図はこれ。(FT232Rの仕様書

image

これを接続すると、こんな感じになりますが、結局わかりにくくなっているのは、Pro Miniの基板上の印刷のせい・・という気がします。なぜ、BLK (Black)とかGRN (Green)という名称になっているか・・・? FTDIケーブルの線の色という記載がありました。 (FTDIケーブルの回路図)。

1ピンと2ピンは、Pro Miniの基板上でショートされているので、FTDI側のCTS(Clear To Send)は強制的にGNDに接続される事になり、負論理のCTSなので、「常に送信可」状態という事になります。(ハンドシェークは無し)

  AtMega328 のピン名 Pro Mini基板上ネット信号名 Pro Mini回路図上(JP1)の端子名 印刷の信号名 信号向き FTDIのピン名 FT232RLのピン名
6 RESET DTR DTR GRN DTR DTR
5 TXD RX-I RXI TXO RX-I RXD
4 RXD TX-O TXD RXI TX-O TXD
3 VCC VCC VCC VCC VCC VCC
2 GND GND CTS GND CTS CTS
1 GND GND GND BLK GND GND

6ピンは、FTDI側から新しいArduinoのスケッチを書き込んだときに、ArduinoをAuto-Resetするために使われているようです。(ここに説明あり)

という事で、なんとかスッキリしたので、実際に接続して、LEDをBlinkするスケッチを書き込んでみました。

DSC09689

IDEのツールメニューから、以下の設定をします。

  • ボード:Arduino Pro or Pro Mini
  • プロセッサ: ATmega328 (3.3V, 8 MHz)

超基本のLED Blinkのスケッチをコンパイル、書き込みをしたら、正常(1秒毎の点滅)に動作しました。まずは、Pro Mini 3.3V, 8MHzと FTDI 3.3Vの接続は無事確認できました。

追記:別のパソコンで同じ実験をしてみたら、USBシリアルポートの認識をしてくれませんでした。FTDIチップのドライバーページから実行形式のセットアップファイルをダウンロードして、インストールしたら、正常に動作しました。

さて、次は、ESP8266の接続実験です。

【次回へ】

熱電対を使ってはんだコテ先の温度制御にトライ・・・酸化防止(その2)

【ケースの加工】

完成品はこんな感じ。

DSC09678DSC09679

以前10個程、購入したHammond社のケース(1591GS-BK)をケースとして使う。必要な加工としては、

  1. はんだこてケーブルを挿すACソケット(メス)用の固定
    1. 側面をカットして、ソケットを挿し、エポキシ樹脂で固定。
  2. 電源ケーブル(供給側)を挿すACソケット(オス)用の固定
    1. 側面をカットして、ソケットを挿し、エポキシ樹脂で固定。
  3. 熱電対モジュール用の固定
    1. モジュールの端子(5ピン)を外し、裏面からアクセスできるように新たにストレートの5ピンヘッダーをハンダ付け
    2. ケースの側面に、モジュール固定用の丸穴と、ヘッダーピンをケース内へ通す角穴をあける、熱電対用の端子足を割けるための丸穴も空ける。
    3. モジュールをM3のネジで固定。
  4. AC-DCモジュールの固定
    1. モジュールには何も固定するための穴が無いため、上下を逆さまにして、トランス部分をエポキシでケースへ固定。
    2. 線材のハンダ付けが後から出来るようにした。(端子がむき出しなので、注意が必要)
  5. OMRON SSRの固定
    1. はじめは基板上にマウントしようとしたが、実験しやすくするため、ちょっと危険だけれど、逆さまにしてケースに直接エポキシ樹脂で固定。
  6. 基板(Arduino Nano)の固定
    1. ユニバーサル基板の固定穴(M2用)に併せて、ケースの底面に4つ穴を開ける
    2. ナイロンスペーサーで4箇所固定。
  7. 表示用 7segment x 4桁モジュールの固定(フタ側)
    1. これが一番大変だった・・・。天面(フタ)に、7セグモジュールのサイズにピッタリ併せて、角穴を開ける。センターポンチと 3mm (3/8)のドリルで沢山穴を開け、ニッパとカッターで、ぴったりサイズに合わせる。
    2. 7セグモジュールを差し込み、モジュールの表面が天板の表面と一致する位置で、エポキシ樹脂を使って固定
    3. その後、7セグモジュールの基板を後ろからハンダ付け。
  8. 温度調整用VRの固定
    1. 丸穴と回転防止爪用の穴を加工して、ネジ止め。

基本的にはDremelとカッターナイフだけで、コツコツと、時間を探して少しづつ加工した。

出来上がった本体とフタ側はこんな感じ。黄色い配線が汚い・・けれど、AC系は安全のため、しっかりと配線したつもり。 ハンダコテへの出力をするソケットが3ピンになってますが、実際に使っているのは2ピンだけです。(GNDピンはオープン)

DSC09672DSC09674DSC09677DSC09675

DSC09676金色のノブが温度設定調整です。

 

【実体回路図】

回路図はこんな感じです。

実体回路図

【使用部品】

# 部品 価格 URL
1 Arduino Nano 1 $4 (link)
2 5V制御, 100-240V (2A) ゼロクロス対応 SSR 1 $6 (link)
3 Kタイプ熱電対(以前、MAX6675モジュールを買った時に付いてきたものをカットして使用) 1 (link)
4 粘着銅箔テープ(熱電対をコテ先に固定するため。) (link)
5 MAX6675モジュール 1 $3.4 (link)
6 ACソケット(male) 1 $0.7 (link)
7 ACソケット(female) 1 $1.5 (link)
8 ケース(Hammond社製 1590 1

(link)

    9 DC5V(700mA) 電源モジュール 1 $1.3 (link)
    10 10kΩ VR 1  
     
    【ハンダゴテのコテ先への熱電対付着】
    • 熱電対の先端部分が、ハンダ付けの邪魔にならない程度で、かつなるべく先端に近く装着したいので、コテ先(交換可能な部分)の根元あたりに、銅箔テープで固定することにする。 銅箔での固定は、失敗した。銅箔テープの接着剤が熱で燃えて、粘着力がなくなってしまう・・(あたりまえか・・)。結局、コテ先保持用のスリーブとの隙間に、熱電対の先端を突っ込んで固定することにした。

    DSC09680

    DSC09681

    • 熱電対の配線部分は、コテと、電源ケーブルに沿って、今回製作する装置の近くまで持ってくる。
    • 熱電対の反対側は、MAX6675モジュールのターミナルへ直接接続することにする。(本当はソケットにしたいが、今回は、まぁ直接ネジじめでOKとする。これだと、ハンダゴテを交換したりすると、この熱電対の配線も外す必要があるが、手持ちのコテは一本しか無いので、これでOKでしょう。

    【その3へ続く】

    熱電対を使ってはんだコテ先の温度制御にトライ・・・酸化防止(その1)

    安物の60Wハンダゴテ(温度調整ノブ付き)を使ってますが、どうも、調整が上手く効いていない感じがするので、ちょっと作ってみることにした。

    先端の小手先に、Kタイプの熱電対を付けて、MAX6675の熱電対モジュールを経由してArduinoで温度を読み取り、SSRを利用してはんだコテへの供給電力を制御しよう・・・というもの 。

    Soldertipcontroloverview_2 

    続きを読む →

    ロードセルを使った簡易スケールの製作

    これまで、重さを測定する秤(キッチンスケールとか、体重計とか)の仕組みを考えた事もなかったけれど、ひょんな事から、「重さを量ってパソコンで処理する」という必要性が出てきたので、ちょっとためしてみることにした。

    ロードセルには、いろんなタイプがあるが、今回の目的に最適な条件としては、

    • 厚さ(高さ)を要しない事
    • 測定範囲は、最大でも10kg程度
    • 精度は数グラム程度でOK
    • 対象物を置く面積は、そこそこ広い
    • 高価なセンサーはNG
    • 簡単にArduinoへ接続出来ること

    【ロードセルの色々】

    1 「ロードセル」の画像検索結果 中央部にかかる圧力で重さを計測するタイプ。
    2 「ロードセル」の画像検索結果 中央部で測定できるからバランスは良いが、高さが高くなる
    3 「load cell」の画像検索結果 安価
    いろんな重さ範囲の商品あり。
    4 「load cell」の画像検索結果 ハーフブリッジタイプ。フルブリッジにするには2個必要。
    薄く出来て、かつ4個使えば広い面積を安定して測定するのに良いが、10kg程度に丁度よい物が見つからない。体重計等で4個使う用途が多い。(50kgタイプ x 4とか)

    これらの条件を考えて、今回は3のタイプで10kgのフル・ブリッジ・ロード・セルを使うことにした。(link)

    続きを読む →

    nRF24L01を搭載した一台の受信機で、複数台のnRF24L01からの信号を受信処理する実験。

    いくつかの場所に分散したArduino機から、各種の情報(センサー情報とか)を送信して、一台の受信機(ホスト)でそれらをまとめて受信し、PCと接続し、PCで処理したりサーバーに上げたり・・という事を実現したので、そのまとめ。

    いろんなWEBからの情報を集めながら、複数台の通信が出来るようになったので、まとめておくことにした。    

    何台も同じような配線をするのは面倒だし、nRF24L01モジュールの性能が配線に敏感・・という書き込みがあちこちにあったので、基板を起こすことにした。→基板製作の詳細はこちらへ

    出来上がった基板はこちら。DSC_0270 

    搭載出来る部品は下記のとおり。    

    • Arduino Nano  (5V) x 1     
    • 16×2 LCD module (4bit interface) (5V)     
    • nRF24L01 (3.3V)     
    • MAX6675 module (5V)              

    続きを読む →