公開日:2024/02/24
title.png

29th Season


#29-3 も〜っと小さくATtiny85

 過去、「#13-9 もっと小さくATtiny2313」では、ATtiny2313A-PUという、20ピンDIP形状のMCUを導入しました(下図右側)。

ar94_atmega328p.jpga139_attiny2313.jpg

 上図左側がArduino UNO等に搭載されているATmega328P-PU、右側がATtiny2313A-PUです。どちらもデュアルインラインパッケージ(DIP)と言う形状のLSIで、ATmega328が28ピンに対して、ATtiny2313は20ピンなので少し小さくなっています。

 今回は、も〜っと小さく、8ピンDIP形状のATtiny85-20PUというMCUチップ(下図)を入手したので、使って見たいと思います。

a293_attiny85.jpg

 上に挙げたMCUは全て、8ビットRISC CPUのAVRコア(AVR8)を搭載しています。機能的には、megaシリーズの方が、tinyシリーズよりも高機能です。シリーズ内では、I/Oポート数や搭載しているI/Oユニット、メモリ(RAMやFlash、EEPROM)容量でラインアップがあります。
 ATtiny85は、機能的には絞られていますが、小さく、省スペースに実装可能なラインアップの一つです。

ATtiny85とATtiny2313の比較

 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)"」が選択できる様になります(下図)。

a293_menu85.png

 他にも「ボード:"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発振器で使用するのが基本でしょう。


 具体的なヒューズへの設定手順は、次節で示します。

ATtiny85へのプログラム書き込み手順

 Arduino UNOをISP(In System Programmer、書き込み装置)として使い、UNO経由でATtiny85へプログラムを書き込みます。UNOをホスト、ATtiny85をターゲットMCUとして、シリアルプログラミングモードで書き込みます(下図)。

a293_serprg.jpg

 書き込み手順は、基本的に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へ移植してみたいと思います。

ハードウェア設計

 回路図は以下の様になります。

a293_schem.png

 3.3V定格のOLEDディスプレイを駆動するため、ATtiny85も3.3Vで使っています。DHT11も3.3Vで使います。
 3端子レギュレータ(LM1117-3.3)を備えているので、供給すべき電源はVccだけです。しかも、Vcc=4.5〜6[V]で入力できるので、USBやモバイルバッテリ、電池ボックスなどから柔軟な電源供給が可能です。

 何しろ、ATtiny85が8ピンDIP形状と小さいので、上の回路図がミニブレッドボード1個に全て載ってしまいます(下図)。

a293_tmpmtr85.jpg

  やはり、省スペースに実装したいニーズがある場合の強い見方ですねっ!

 尚、上図の様に実装してしまうと、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でコンパイルする時はマスタとしてコンパイルしているので、スレーブとして通信する事はできない。

小さな実験

 実験で動作を確認しましょう。以下、実験中の様子です(再掲)。

a293_tmpmtr85.jpg

※電源は、モバイルバッテリから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個のミニブレッドボードに載って、小さく省スペースに実装できました。下図の通り比較してみました。

a28a_expr.jpga293_tmpmtr85.jpg

 上図左側が328duino版(ミニブレッドボード×2個)、右側がATtiny85版(ミニブレッドボード×1個)です。

今回のお買い物

 今回のお買い物は、以下の通りです。

 秋月電子通商の通販サイトにて、ロボットカーのプラットフォームキットと共に購入しておいた部品の一部です。


 同じ8ピンDIP形状のICに、オペアンプLM358等を所有しているのですが、LM358は精々数10トランジスタ程の回路規模に対して、ATtiny85は最低でも数100,000トランジスタは集積されていますので、回路規模が桁違いです。それを同じ8DIPに詰め込んで、しっかり機能させているのですから凄いんです。


btn_arduino.png

btn_prev.png btn_next.png

home