ATtiny2313を使った電圧計

AVRマイコンの「ATtiny2313」を使って電圧計を製作しました。3桁の7セグLEDに電圧を表示します。ケースにはフリスクを使いました。

原理・回路構成

ATtiny2313を使い、3桁の7セグLEDに測定電圧を表示します。今回は、電源電圧を表示する2線式電圧計とします。必然的に測定電圧範囲は、6~30Vになります(回路の動作電圧範囲)。

回路図

AD変換器

ATtiny2313にはAD変換器が付いていないので、アナログ比較器を使用します。

アナログ比較器のAIN1には測定対象の電圧を、AIN0にはコンデンサ(図中C2)を繋ぎ、このコンデンサはPB3ピンから定電流ダイオードを介して充電できるようにしておきます。

PB3をHiレベルにすると、コンデンサC2は定電流で充電され、電圧が直線的に増加していきます。この電圧が測定対象の電圧を上回るまでの時間を測れば、AD変換の値を得ることができます。

アナログ比較器を用いたAD変換

実際の流れは次のようになります。

  1. コンデンサを0Vまで放電させる
  2. コンデンサを充電開始 & カウンタを起動
  3. コンパレータの出力が変わったところでカウンタをストップ
  4. カウンタの値が測定電圧(に比例した数)

ここで重要なのは、コンデンサや分圧抵抗、ツェナーダイオードの精度、クロック源の精度です。これらを測定していって真面目に計算するのは結構大変なので、最初に適当なプログラムを作り、入力した電圧と、出てきたAD変換の値から逆算しました。また、AD変換器のコンデンサは特性の良いフィルム系の物を使います。セラミックコンデンサは向きません。

なお、測定したい電圧が30Vまであるので、ツェナーダイオードと抵抗分圧により降圧します。

表示部

表示には文字高さが14.2mmの7セグLEDを3桁分使います。これだとフリスクのケースに何とか収まります。マイコンに直結してダイナミック・ドライブさせます。

制作過程

回路の製作

フリスクに収めるために、0.8mm厚の片面プリント基板を製作しました。部品は全て表面実装します。

片面プリント基板を製作 t=0.8mm

7セグLEDは、そのままだとフリスクのケースに収まらないので、高さを低くする加工します。

四隅の出っ張りが邪魔

四隅の出っ張りが邪魔なので、ニッパで取る。

四隅の出っ張りを取る

そして足を曲げて表面実装部品風にします。

足を曲げて表面実装部品にする

マイコンも足を曲げて切って表面実装できるようにします。DIPじゃなくてSOPを使えよ、という指摘はナシです。手持ち部品で作ったのです。

マイコンも足を曲げる
マイコンも表面実装にする

下図はすべての部品を実装した様子です。

すべての部品を実装した

基板の裏面はツルツルです。

基板の裏面

プログラムの作成

回路が完成したらマイコンのプログラムを作っていきます。書き込みは…板バネのソケットを使うとよいです。

まずは7セグの確認・・・

プログラム書き込みの様子

つぎにAD変換の確認・・・

コンデンサの電圧波形を見ると、直線的に電圧が増えていく様子がわかります。

コンデンサの電圧波形

下図は仮のプログラムを作ってデータを取ったグラフです。直線性は結構良さそうです。

AD変換の測定結果

最終的に組んだプログラムです。

/*********************************
電圧計
○○○○○○○○○○○○○○○○
*********************************/
#define F_CPU 12000000UL //12.0MHz#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <util/delay.h>// グローバル変数
char keta = 0;
volatile int num = 0;
volatile unsigned long volt = 0;void Set7seg( char number){
// セグ初期化
PORTB |= 0b00010100;
PORTD |= 0b01110111;
// セグメント割り当て
switch(number){
case 0:
PORTB &= ~0b00010100;
PORTD &= ~0b01010011;
break;
case 1:
PORTB &= ~0b00010000;
PORTD &= ~0b00010000;
break;
case 2:
PORTB &= ~0b00000100;
PORTD &= ~0b00110011;
break;
case 3:
PORTB &= ~0b00010100;
PORTD &= ~0b00110010;
break;
case 4:
PORTB &= ~0b00010000;
PORTD &= ~0b01110000;
break;
case 5:
PORTB &= ~0b00010100;
PORTD &= ~0b01100010;
break;
case 6:
PORTB &= ~0b00010100;
PORTD &= ~0b01100011;
break;
case 7:
PORTB &= ~0b00010100;
PORTD &= ~0b00010000;
break;
case 8:
PORTB &= ~0b00010100;
PORTD &= ~0b01110011;
break;
case 9:
PORTB &= ~0b00010100;
PORTD &= ~0b01110010;
break;
default:
break;
}
}// タイマ0割り込み
ISR(TIMER0_OVF_vect){
// TCNT0 = 150;
PORTB &= 0x00; // 消灯
if(keta == 2){
Set7seg(num%1000/100);
PORTB |=  _BV(PB5); // 3桁目 点灯
keta = 1;

}else if(keta == 1){
Set7seg(num%100/10);
PORTB |=  _BV(PB6); // 2桁目 点灯
PORTD &= ~_BV(PD2);
keta = 0;

}else if(keta == 0){
Set7seg(num%10);
PORTB |=  _BV(PB7); // 1桁目 点灯
keta = 2;
}
}
// カウンタ1の捕獲発生
ISR(TIMER1_CAPT_vect){
TCNT1 = 0;
volt = ICR1;
}
int main(void) {
/*
a PB2
b PD4
c PB4
d PD1
e PD0
f PD6
g PD5
DP PD2
COM1 PB5
COM2 PB6
COM3 PB7

コンデンサは、500uSで満タン
*/
DDRD  = 0b01110111;
PORTD = 0b00001000;
DDRB  = 0b11111100;
PORTB = 0b00000000;

// タイマー0
TCCR0B = 0x03; // プリスケーラは  (dataseet p.66)
TCNT0 = 0; // タイマ0の初期値
TIMSK |= _BV(TOIE0);// タイマ0オーバーフローだけ割り込み許可

// タイマー1
TCCR1A = 0x00;
TCCR1B = 0b11000001;
TIMSK |= _BV(ICIE1);// 捕獲割り込み許可
TCNT1 = 0x0000;

// アナログコンパレータ
ACSR = _BV(ACIC); // アナログ比較器捕獲起動許可
//ACSR = _BV(ACIS1); // コンパレータ上昇で
//ACSR = _BV(ACIS0); //

DIDR = 0b11; // デジタル入力禁止

sei(); // 割り込み許可

char ave_cnt = 0;
long volt_ave = 0;

while(1){

volt_ave += (((volt*100)+69863)/1800);
volt_ave = volt_ave/2;
ave_cnt++;
if(ave_cnt >= 20){
num = volt_ave;
ave_cnt = 0;
}

_delay_ms(20);

DDRB &= ~_BV(PB0); // コンデンサのピンをオープン

cli(); // 割り込み禁止
// Cを充電開始
TCNT1 = 0x0000;
PORTB |= _BV(PB3); // 充電開始

// コンパレータが1を吐くまで待つ
while(!(ACSR & (1<<ACO))){
}
PORTB &= ~_BV(PB3); // 充電を止める
sei(); // 割り込み許可
// Cを放電
DDRB |= _BV(PB0); // コンデンサのピンを接地=放電

}

}

 

ケースの加工

フリスクケースの小部屋を削って、真ん中の凸も削り、7セグLEDの窓を開けます。

7セグの窓を開ける
ピッタリ

まとめ

定電流ダイオードとコンデンサによるAD変換は、そこそこの直線性を得られることがわかりました。温度特性については評価できていませんが、常温ならそこそこ使えそうではあります。

文字高さ14.2mmの7セグLEDはフリスクケースに入ります!

昔はATtiny2313が秋月で100円で売っていたのですが、いつの間にか値上がりして230円(2016年12月現在)になってしまいました。AD変換器が付いて多機能なATmega48やATmega88の方が安くなってしまいました。もはや2313を使うメリットが見当たらないですね。

動作の様子

参考文献


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です