米粒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

ボツネタ~CAN的な何か

少し前に必死になって作ってたデバイス+アプリですが、気持ちが萎えてしまい、結果ボツと

記事を読む

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

ArduinoでSDカード

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

記事を読む

vlc_media_player

Raspberry Piのサウンドを試したら音が出なかった話

(これはX-WindowのVLCメディアプレイヤーのスクショ) Raspberry Piでは、

記事を読む

no image

SoundIRModemライブラリのサンプル

 SoundIRModemライブラリは、米粒AVR(Tiny10)とAndroid端末をイ

記事を読む

no image

米粒AVRでシリアル通信(ただし送信だけ)

米粒AVR(ATtiny10)にUART機能は搭載されていないので、シリアル通信を行う為には自前

記事を読む

no image

赤外線リモコン受信機(イヤホンジャック接続)を作ってみた

最近、このブログ何も書いて無かったので、作成中の物の紹介・・・  これは、Andro

記事を読む

no image

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

先日Google IOで発表された Android Open Accessory。みなさん知ってます

記事を読む

no image

Wimeji Client for Arduino

前回紹介したWimeji Client for WindowsXPをArduinoでやってみました。

記事を読む

raspi-config

Raspbianの最初の設定

  Raspbianのインストール後にraspi-configを使って行う最初の設定

記事を読む

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

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

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

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

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

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

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

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

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

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

PAGE TOP ↑