米粒AVRでアナログ入力を試してみた
公開日:
電子工作 | 米粒AVR(tiny10)
米粒AVR(ATtiny10)に搭載されている8ビット4チャンネルのアナログ入力を試してみました。
回路図
PB0は動作確認用のLED
PB1は結果送信用のシリアル出力
PB2はアナログ読み込み用の10kの可変抵抗
以上のように接続しています。
プログラム
#ifndef F_CPU<br /> #define F_CPU 8000000UL<br /> #endif<br /> <br /> #include <avr/io.h><br /> #include <util/delay.h><br /> <br /> #define LED_PIN PB0<br /> #define DELAY 100<br /> <br /> #if F_CPU == 8000000UL<br /> // 19200bps<br /> #define SERIAL_TIME_PER_BIT1 52<br /> #define SERIAL_TIME_PER_BIT2 51<br /> #elif F_CPU == 4000000UL<br /> // 9600bps<br /> #define SERIAL_TIME_PER_BIT1 104<br /> #define SERIAL_TIME_PER_BIT2 102<br /> #elif F_CPU == 2000000UL<br /> // 9600bps<br /> #define SERIAL_TIME_PER_BIT1 103<br /> #define SERIAL_TIME_PER_BIT2 100<br /> #elif F_CPU == 1000000UL<br /> // 4800bps<br /> #define SERIAL_TIME_PER_BIT1 206<br /> #define SERIAL_TIME_PER_BIT2 201<br /> #endif<br /> <br /> #define SERIAL_TX_PIN PB1<br /> <br /> void serialBegin()<br /> {<br /> DDRB |= _BV(SERIAL_TX_PIN);<br /> PORTB |= _BV(SERIAL_TX_PIN);<br /> }<br /> <br /> void serialWrite(uint8_t data)<br /> {<br /> PORTB &= ~(_BV(SERIAL_TX_PIN)); // start bit<br /> _delay_us(SERIAL_TIME_PER_BIT1);<br /> <br /> uint8_t i;<br /> for(i=1;i;i<<=1)<br /> {<br /> if(data&i)<br /> {<br /> PORTB |= _BV(SERIAL_TX_PIN);<br /> }<br /> else<br /> {<br /> PORTB &= ~(_BV(SERIAL_TX_PIN));<br /> asm volatile ("nop");<br /> }<br /> _delay_us(SERIAL_TIME_PER_BIT2);<br /> }<br /> <br /> PORTB |= _BV(SERIAL_TX_PIN); // stop bit<br /> _delay_us(SERIAL_TIME_PER_BIT1);<br /> }<br /> <br /> int main(void)<br /> {<br /> CCP = 0xD8;<br /> CLKMSR = 0x00;<br /> CCP = 0xD8;<br /> CLKPSR = 0x00;<br /> <br /> ADCSRA = 0b10000110; // A/D許可とプリスケーラー<br /> ADMUX = 0b00000010; // PB2 選択<br /> DIDR0 = 0b00000100; // PB2 デジタル入力禁止<br /> <br /> serialBegin();<br /> <br /> DDRB |= _BV(PB0);<br /> <br /> uint8_t ad_data;<br /> while(1)<br /> {<br /> ADCSRA |= _BV(ADIF); // ADIFクリア<br /> ADCSRA |= _BV(ADSC); // 変換開始<br /> loop_until_bit_is_set(ADCSRA, ADIF); // 変換終了待ち<br /> <br /> ad_data = ADCL;<br /> serialWrite(ad_data);<br /> <br /> PORTB ^= _BV(LED_PIN);<br /> _delay_ms(DELAY);<br /> }<br /> }<br />
このプログラムを実行すると、約100ms毎にPB2に接続されたボリューム(可変抵抗)の値をシリアルで送信します。
送信されるのはバイナリデータで、テキスト変換は行っていません。バイナリデータの表示できる通信ソフトが必要です。
今回PC用のシリアル通信ソフトは、Acknowrichを利用しました。
かなり古いソフトですが、バイナリデータが表示できて便利なので愛用しています。
説明
米粒AVRには8ビット4チャンネルのアナログ変換があります。
4チャンネルですから、全てのI/Oピンでアナログ入力ができます。
アナログ変換には変換用のクロックが必要で、これにはCPUの動作クロックを分周して50~200kHzの範囲で与えます。
米粒AVRの内臓発振器を使う場合、動作周波数とプリスケーラーの組み合わせから、変換クロックは概ね125kHzとなります。
アナログ変換には1回13クロックかかるので、内臓発振器を使う場合は1回104μ秒かかることになる。
動作結果
米粒AVRのAD変換はかなり安定して取得できている気がします。
Arduino(mega328p)で同じことをすると、数値はかなり揺れると思うのですが、今回のプログラムではボリュームを固定するとぴたり安定した数値が取得できています。
スピードアップ
今僕が作りたいと思っているものには、もう少し早い速度の変換が必要です。
データシートでは、変換クロックの説明に「最大分解能を得るのに50~200kHzの入力クロック周波数を必要とします」とあるのですが、これはつまり分解能を犠牲にすればクロックを上げても良いよってことなのでしょうか?
10ビット変換器を持つmega88のデータシートを見てみると、そこには10ビットよりも低い分解能なら速度を上げられる的なことが書いてあります。
tiny10ではどうなのか・・・いずれ試してみようと思います。
関連記事
-
-
USBホストケーブルとUSBケーブルの違い
USBホストケーブル(OTGケーブル)と普通のUSBケーブルの違いは、USBホストケーブルとして振る
-
-
米粒AVR(ATtiny10)
通称「米粒AVR」で知られるTiny10を使ってみたくて、秋月の通販で買ってみました。 超小型
-
-
Android + Arduino でリモコン
今こんなのを作ってますと言う動画です。 DoCoMoのFOMA携帯
-
-
Arduinoで温湿度計
秋月電子の温湿度モジュールを使って、温湿度計を作ってみました。 以前「パソコンで温度計」と言うもの
-
-
赤外線リモコン受信機(イヤホンジャック接続)を作ってみた
最近、このブログ何も書いて無かったので、作成中の物の紹介・・・ これは、Andro
-
-
米粒AVRでI2C通信(マスター)
米粒AVRことATtiny10は3つまたは4つのI/Oピンしか使えないのですが、I2Cなら2つの
-
-
Raspbianの最初の設定
Raspbianのインストール後にraspi-configを使って行う最初の設定
-
-
秋月のリアルタイムクロック(RTC)モジュール
今回は秋月電子のI2C接続のリアルタイムクロック(RTC)モジュールを買ったので、ちょっと試してみま
-
-
米粒AVRで温度計(STTS751使用)
前回までに紹介したI2CライブラリとLCDライブラリを使って作る、温度計のサンプルです。 温度
- PREV
- 米粒AVRでシリアル通信(ただし送信だけ)
- NEXT
- 米粒AVRで小型8連ナイトライダーを作ってみた