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

 

 

関連記事

熱湯の温度計測実験

パソコンで温度計 #3

今回は、I2C接続の温度センサー STTS751をケーブルを使ってArduinoに接続できるよう

記事を読む

no image

PIC24FJ64GB002でADKを試す(その1)

先日、MicrochipからPIC向けのAndroid Open Accessoryのライブラリが公

記事を読む

no image

オシロスコープを手に入れた

ついにオシロスコープを買っちゃいました。 と言っても、DSO QUADと言うポータブルタイプの

記事を読む

no image

Bimeji Client for Arduino

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

記事を読む

no image

Arduino + USBホストシールド で ADK を試す(その3)

「Arduino + USBホストシールド で ADK を試す(その1)」では、Android上のア

記事を読む

no image

米粒AVRでLチカ

  米粒AVR(ATtiny10)でLチカしてみました。 LチカとはLEDをチカチカと

記事を読む

Raspberry Pi 起動SDカード

Raspberry Piの起動SDカードを準備する

先日入手したRaspberry PiでLinuxを起動する為のSDカードを準備します。 Ras

記事を読む

Raspberry Pi ロゴマーク

Raspberry Piのリビジョン

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

記事を読む

no image

PIC24FJ64GB002でADKを試す(その2)

 前回「PIC24FJ64GB002でADKを試す(その1)」では回路の説明までしたので、

記事を読む

秋月電子 キャラクタLCD

秋月の小型キャラクタLCD

今回秋月電子で売られている小型のキャラクター液晶2種を買ったので、ちょっと比較してみる。 買っ

記事を読む

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

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

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

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

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

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

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

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

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

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

PAGE TOP ↑