米粒AVRでアナログ入力を試してみた

公開日: 電子工作 |

サイン波

米粒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ではどうなのか・・・いずれ試してみようと思います。

 

 

関連記事

no image

AVRISPmk2

米粒AVR(ATtiny10)のプログラム書き込み用にAVRISPmk2を購入しました。 先人

記事を読む

no image

Bimeji Client for Arduino

前回紹介したWimeji Client for Arduinoの最後で予告していた、Wimeji c

記事を読む

no image

Android+Arduinoでリモコン3のおまけ

Androidとは関係ないのですが、前回の記事  Android+Arduinoでリモコ

記事を読む

Raspberry Pi ロゴマーク

Raspberry Piのリビジョン

リビジョンの種類 現在、Rapsberry Piにはリビジョン1とリビジョン2と呼ばれる2つの

記事を読む

no image

Softmodem Terminal 公開しました。

需要がどれほど有るのか疑問に思いつつ、以前のエントリ(AndroidでSoftModemを試してみた

記事を読む

SDFormatter

Raspbianの起動SDカードを再利用

一度、Raspbianのイメージを書き込んだSDカードは、フォーマットが違う為にWindowsでは利

記事を読む

thermometer overlay

パソコンで温度計 #4

前回までに作ったPC温度計のログデータを、計測と同時に撮影した映像にオーバーレイ表示(スーパーイ

記事を読む

Androidから米粒AVRへデータを送る

米粒AVRでSoftModem的なこと その2

前回は「米粒AVRからAndroidへデータを送る」ことを試しました。 今回はその逆の「And

記事を読む

SDカード・マイクロSDカード

ArduinoでSDカード

電子工作で大量のデータを保存する方法を調べていると、 Arduinoでも比較的簡単にSDカードを

記事を読む

Raspberry Pi

Raspberry Piを買った

先日、Raspberry Pi(ラズベリーパイ)を買いました。 Raspberry Piは噂で

記事を読む

Arduinoで温湿度データロガー
Arduinoで温湿度計 #2

今回は、前回作った温湿度計にRTCモジュールとSDカードアダプタを

Arduinoで温湿度計
Arduinoで温湿度計

秋月電子の温湿度モジュールを使って、温湿度計を作ってみました。 以前

SDカード・マイクロSDカード
ArduinoでSDカード

電子工作で大量のデータを保存する方法を調べていると、 Arduin

秋月電子 リアルタイムクロック(RTC)モジュール
秋月のリアルタイムクロック(RTC)モジュール

今回は秋月電子のI2C接続のリアルタイムクロック(RTC)モジュールを

秋月電子 キャラクタLCD
秋月の小型キャラクタLCD

今回秋月電子で売られている小型のキャラクター液晶2種を買ったので、

PAGE TOP ↑