過去、「#13-9 もっと小さくATtiny2313」では、ATtiny2313A-PUという、20ピンDIP形状のMCUを導入しました(下図右側)。
上図左側がArduino UNO等に搭載されているATmega328P-PU、右側がATtiny2313A-PUです。どちらもデュアルインラインパッケージ(DIP)と言う形状のLSIで、ATmega328が28ピンに対して、ATtiny2313は20ピンなので少し小さくなっています。
今回は、も〜っと小さく、8ピンDIP形状のATtiny85-20PUというMCUチップ(下図)を入手したので、使って見たいと思います。
上に挙げたMCUは全て、8ビットRISC CPUのAVRコア(AVR8)を搭載しています。機能的には、megaシリーズの方が、tinyシリーズよりも高機能です。シリーズ内では、I/Oポート数や搭載しているI/Oユニット、メモリ(RAMやFlash、EEPROM)容量でラインアップがあります。
ATtiny85は、機能的には絞られていますが、小さく、省スペースに実装可能なラインアップの一つです。
ATtiny2313の仕様は、こちらを参照してください。ATtiny85のデータシートを検索し、入手しておきましょう。
ATtiny85データシートを検索する(別ウインドウが開きます)
ATtiny85とATtiny2313に関して比較してみた結果を以下表に示します。
Spec | ATtiny85 | ATtiny2313A | Memo | |
CPU | AVR8 @20MHz | AVR8 @20MHz | ATtiny85:内蔵RC発振器+PLLで@16MHz動作可能。 | |
Voltage | 2.7〜5.5[V] | 1.8〜5.5[V] | ATtiny2313:低電圧駆動可能。 | |
PKG | 8DIP | 20DIP | ||
Flash | 8,192 | 2,048 | ||
EEPROM | 512 | 128 | ||
RAM | 512 | 128 | ||
PLL | 1 | 0 | ATtiny85:PLLで逓倍した高速クロックを使用可能。 | |
I/O unit |
Timer 8b | 2 | 1 | ATtiny85:高速クロック駆動可能な1chを使用可能。 |
Timer 16b | 0 | 1 | ||
PWM | 3 | 4 | ||
USART | 0 | 1 | ATtiny2313:全二重ハードウェアシリアルを使用可能。 | |
USI | 1 | 1 | ATtiny85:半二重ハードウェアシリアルとしても使用可能。 | |
ADC 10b | 4 | 0 | ATtiny85:AD変換器搭載。 | |
ACMP | 1 | 1 | ||
WDT | 1 | 1 |
※優位性の認められるセルを水色に着色しました。
ATtiny85はメモリ(Flash/RAM)容量が大きいため、ATtiny2313と比べてプログラムは組み易いと思われます。
機能面に注目すると、ATtiny85にはUSARTユニットや16ビットタイマユニットが無いなど、論理ユニット面でビハインドがあります。代わりに、10ビットAD変換器や、PLLによる内蔵RC発振器の逓倍動作など、アナログユニット面の優位を有しています。
CdSセルやサーミスタ、フォトトランジスタ、マイク等々、アナログ出力のセンサは相当種類存在するので、AD変換器を搭載している事は強い武器となります。
ATtiny2313でも、外付けにCR回路を接続してPWM型DA変換器を作り、ソフトウェアで逐次比較型AD変換器を作った事がありました(以下記事を参照)。
「#14-8 ATtiny2313+容量+抵抗=AD変換器」
上記事の様な工夫をして使う事はできるけれども、ちゃんとしたAD変換器が内蔵されているのであれば、それに越したことはありません。外付け回路も小細工も不要で、AD変換器を使用可能なのは嬉しいです。
ATtiny85のピン配置表を以下に記載しておきます。
Port | DIP | ATtiny85 | DIP | Port |
D5[A0](PB5/PCINT5/RESET/ADC0/dW) | 1 | ● | 8 | VCC |
D3[A3](PB3/PCINT3/XTAL1/CLKI/OC1BN/ADC3) | 2 | 7 | D2[A1](PB2/SCK/USCK/SCL/ADC1/T0/INT0/PCINT2) | |
D4[A2](PB4/PCINT4/XTAL2/CLKO/OC1B/ADC2) | 3 | 6 | D1(PB1/MISO/DO/AIN1/OC0B/OC1A/PCINT1) | |
GND | 4 | 5 | D0(PB0/MOSI/DI/SDA/AIN0/OC0A/OC1AN/AREF/PCINT0) |
※D#、A#は、Arduino IDEのデジタル端子番号とアナログ端子番号。
※1ピンはRESET端子として割り当てておかないと、シリアルプログラミングモードで書き込みできない。
ATtiny85は、機能を絞って省ピンパッケージを採用したことで、「省スペースに実装できる」事に主眼を置いたMCUであるという認識です。
ただし、プログラムデバッグの要である、シリアルモニタが使えないケースが多いため、プログラムをどのようにデバッグするのか?が課題です。
※何しろ、8ピンDIPに対して電源2本とリセット1本が取られるので、I/Oポートとして5本しか使えない所から、シリアルモニタに2本(TXD,RXD)も割り当てできるか??と言う事です。
Arduino IDEに追加のボード設定を導入して、ATtiny85のプログラムをコンパイル&書き込みできるようにする必要があります。
追加のボード設定は、ATtiny2313の時に導入したのと同じATTinyCoreを使うので、以下記事を参照してATTinyCoreを導入してから、ここへ戻ってきて↩ください。
「#13-9 もっと小さくATtiny2313」
Arduino IDEにATTinyCoreを導入すると、「ツールメニュー ⇒ ボード:"ATtiny25/45/85 (No bootloader)"」が選択できる様になります(下図)。
他にも「ボード:"ATtiny45/85 (Optiboot)"」が選択できますが、ブートローダの仕様(接続端子情報等)を調べるのが面倒なのと、十分大きいとは言えないFlashメモリ8Kバイトから、ブートローダに512バイト持っていかれるので、本ページでは使いません。ブートローダでプログラムの書き込みを実行したい場合には、各自調べてお使いください。
なお、本ページでは、「#13-9 もっと小さくATtiny2313」の執筆当時に導入したバージョンのATTinyCoreを、再インストールなどせずに、そのまま使っています。現在の最新バージョンとは、一部異なっている場合があります(当方では未確認)。
前節で示した、Arduino IDEのメニューから、ATtiny85ターゲットでプログラムをコンパイルする時、いくつかオプションを選択できるようになっています。
この中で、赤線で示した「Clock:」、「BOD Level:」、「Save EEPROM:」の3つは、ATtiny85に搭載されたヒューズ関係のオプションです。ヒューズ関係のオプションは、メニュー設定した上で「ツールメニュー ⇒ ブートローダを書き込む」を実行すると、ATtiny85のヒューズに設定して、有効化する事ができます。メニュー設定してプログラムを書き込むだけでは、ヒューズへの設定は実行されません。
※ブートローダを使わない場合(「ボード:"ATtiny25/45/85 (No bootloader)"」)でも、「ブートローダを書き込む」を実行することで、ヒューズだけが設定されます。
なお、「Clock:」では、「Clock:"20 MHz (external)"」等を選択できますが、外部に水晶発振回路を接続してください。8ピンDIPから2本が発振器との接続に取られてしまうので、現実的ではありません。このチップ(ATtiny85)は、内蔵RC発振器で使用するのが基本でしょう。
具体的なヒューズへの設定手順は、次節で示します。
Arduino UNOをISP(In System Programmer、書き込み装置)として使い、UNO経由でATtiny85へプログラムを書き込みます。UNOをホスト、ATtiny85をターゲットMCUとして、シリアルプログラミングモードで書き込みます(下図)。
書き込み手順は、基本的にATtiny2313と同じですが、改めてATtiny85にフォーカスして手順を示します。
ATtiny85へプログラムのコンパイル&書き込み手順:
Arduino UNO | 接続 | ATtiny85 | |
5V | → | 8 | VCC |
GND | ⇔ | 4 | GND |
D10(SS) | → | 1 | D5(RESET) |
D13(SCK) | → | 7 | D2(SCK) |
D12(MISO) | ← | 6 | D1(MISO) |
D11(MOSI) | → | 5 | D0(MOSI) |
前節で示した書き込み手順は、SPIで通信するモードなので、SCK,MOSI,MISO,RESETの4端子を接続しないと書き込むことができません。
電源、GNDで2本、リセット端子で1本消費する8ピンDIPのATtiny85では、ユーザが使用可能な端子数は5本だけなのは、指摘済みです。そこから更に3本(SCK,MOSI,MISO)がプログラム書き込みのために使われます。
もし、プログラム書き込み可能な状態を維持したまま、プログラムのデバッグなどを実行するなら、使用可能なI/Oポート数は、たったの2本となります。まあ、普通は全く足りませんよね?
つまり、ATtiny85の使い方(プログラム開発方法)としては、以下の様な状況が想定されます。
デバッグと言っても、ユーザが使用可能な5本から、シリアルモニタ用にTXD,RXDを接続してしまうと、残りは3本となってしまい、やっぱり端子数が不足……。つまるところ、デバッグの強い見方だったシリアルモニタも、通常は使えないと思った方が良いです。
そうなると例えば、プログラムや周辺回路のデバッグは別途、I/Oポート数に余裕のあるATmega328等を使って実施しておき、バグを潰してプログラムが完成した段階で、ATtiny85へ移植して最後の動作確認だけを行う、と言う感じでしょうか?
ATmega328ではなくて、同じtinyシリーズのATtiny2313等を使っても良いですが、ATtiny2313に存在しないAD変換器などのI/Oユニットを使う場合や、RAMやFlashメモリの容量が足りない場合等に、機能が不足してしまいます(こちらの比較表)。機能的にATtiny85を包含するATmega328等の方が適していると言えるでしょう。
逆に、ATmega328(Arduino UNOや328duino等)で開発していたプログラム(アプリケーション)が完成した時点で、必要なI/Oポート数やメモリ(Flash/RAM)容量に於いてATtiny85で充足する場合に移植する、と言った使い方がメインとなるのでは、ないでしょうか?
ATtiny85で充足するアプリケーションであれば、8ピンDIP形状による省スペース実装が可能となる利点が大きいと思います。
前節で想定した使い方に従って、「#28-10 UNO 3.3V化328duino」にて328duinoを使って作成したOLED温度計をATtiny85へ移植してみたいと思います。
回路図は以下の様になります。
3.3V定格のOLEDディスプレイを駆動するため、ATtiny85も3.3Vで使っています。DHT11も3.3Vで使います。
3端子レギュレータ(LM1117-3.3)を備えているので、供給すべき電源はVccだけです。しかも、Vcc=4.5〜6[V]で入力できるので、USBやモバイルバッテリ、電池ボックスなどから柔軟な電源供給が可能です。
何しろ、ATtiny85が8ピンDIP形状と小さいので、上の回路図がミニブレッドボード1個に全て載ってしまいます(下図)。
やはり、省スペースに実装したいニーズがある場合の強い見方ですねっ!
尚、上図の様に実装してしまうと、ATtiny85へプログラムを書き込むためのSPI接続端子は、I2C通信用として占有されてしまうため、実装する前に別途ATtiny85へのプログラム書き込みを実行しておく必要があります。システムのデバッグ中は、書き込み用のブレッドボードと、実装用のブレッドボードを分けるなど、工夫して使う事が求められます。
少々使い難い(短所)ですが、省スペース(省ピンパッケージ)であるが故の制約なので、長所の裏返しでもあります。くれぐれも、ブレッドボードの抜き差しでATtiny85の脚(ピン)を曲げたりしないよう、ご注意ください。
※ブレッドボードで使用できるDIP形状のマイコンは、貴重品です。新しいマイコンはQFPやBGA、CSP等、面実装タイプのパッケージに置き換わっていますから。現在の流通分が売り切れたら、もう出回らないかもしれません。大切に扱ってくださいね。
「#28-10 UNO 3.3V化328duino」で作成した328duino用プログラム(i2c_tmphum.ino)をベースに、ATtiny85用の改造を施します。
プログラム(i2c_tmphum.ino)を328duinoでコンパイルすると、Flash=14,082バイト、RAM=1,112バイト使用となって、ATtiny85のFlash 8Kバイト、RAM 512バイトを遥かに超えており、移植不可能です。そこで、以下の処置をして、コードとデータサイズの削減を実施します。
何度か指摘した通り、ATtiny85でシリアルモニタ(UART)を使い、コマンドを受け付けたり、デバッグ情報を送信したりすることは困難です。よって、シリアルモニタ関係のコードを削除することで、コードサイズを削減しました。結果、ATtiny85で、Flash=7,668バイト、RAM=350バイトと、収まりました。
完成したプログラムを以下にリンクします。
プログラム:i2c_tmphum.ino
プログラム先頭付近の「#define OLED_ENB」を有効にして、ATtiny85へコンパイル&書き込みしてください。今回は、3.3V駆動していますので、「Clock:"8 MHz (internal)"」オプションを設定してください。
※備忘録:ATTinyCoreのWire(I2C)ライブラリは、同時にマスタかつスレーブとして機能させる事はできない模様。ATtiny85かつOLED_ENBでコンパイルする時はマスタとしてコンパイルしているので、スレーブとして通信する事はできない。
実験で動作を確認しましょう。以下、実験中の様子です(再掲)。
※電源は、モバイルバッテリから5Vを給電しました。
ミニブレッドボード1個に実装した、ATtiny85版OLED温度計の動作を確認しました。8ピンDIPのATtiny85でも、立派にDHT11およびOLEDディスプレイを制御して、温度計として機能させることができました。
稼働中の様子は、328duinoで作った時に撮影した以下動画と大差ないので、ご覧ください。
動画では328duinoと、DHT11+OLEDディスプレイの2個分ミニブレッドボードを使っていますが、プログラムのC言語ソースは共通なので、OLEDディスプレイへの表示状態は同じです。ただ、28ピンDIPの328duino → 8ピンDIPのATtiny85となったことで、ATtiny85+3.3Vレギュレータ+DHT11+OLEDディスプレイが全て、1個のミニブレッドボードに載って、小さく省スペースに実装できました。下図の通り比較してみました。
上図左側が328duino版(ミニブレッドボード×2個)、右側がATtiny85版(ミニブレッドボード×1個)です。
今回のお買い物は、以下の通りです。
秋月電子通商の通販サイトにて、ロボットカーのプラットフォームキットと共に購入しておいた部品の一部です。
同じ8ピンDIP形状のICに、オペアンプLM358等を所有しているのですが、LM358は精々数10トランジスタ程の回路規模に対して、ATtiny85は最低でも数100,000トランジスタは集積されていますので、回路規模が桁違いです。それを同じ8DIPに詰め込んで、しっかり機能させているのですから凄いんです。