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

 

 

関連記事

Androidで温度計

Androidで温度計(STTS751使用)

  Androidに温度センサー(STTS751)を繋いで温度表示してみました。 温度

記事を読む

no image

Android Open Accessory開発時のWiFiデバッグ

Android Open Accessory開発時のデバッグは、ADBをWiFiで接続しろと、USB

記事を読む

Raspberry PiをWindowsで操作する(SSH)

SSHを使って、Raspberry Piを外部PC(Windows)で操作する。

記事を読む

no image

米粒AVRでLチカ

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

記事を読む

no image

Androidで一眼レフカメラのシャッターを制御する(MicroBridge接続)

以前書いた、Androidで一眼レフカメラのシャッターを制御するでは、AndroidとArduino

記事を読む

no image

AndroidとArduinoの接続で使えそうなBluetoothモジュール

1ヶ月ほど前に書いた、Android + Bluetooth + Arduino が割と人気があるよ

記事を読む

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

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

記事を読む

そうだ、Raspberry Pi用にピンヘッダーのオス・メス変換アダプタを作ろう

  Raspberry PiのI/O端子は、ピンヘッダーとなっていて、電極が出っ張ってる

記事を読む

no image

ボツネタ~CAN的な何か

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

記事を読む

Raspberry Piを買った

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

記事を読む

Arduinoで温湿度計 #2

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

Arduinoで温湿度計

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

ArduinoでSDカード

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

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

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

秋月の小型キャラクタLCD

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

PAGE TOP ↑