簡易レベルメーター
概要
レベルメーター(LED10点)を作成しました。
今回は、ソフトウエアでの処理に重きを置きました。なのでハードウエアはとても単純になりました。
動作原理
通常は、ハードウエアで信号を【増幅】→【平滑】した後でPICでA/D変換しLEDを点灯させるのですが、今回は【平滑】回路を使用せずにソフトウエアで信号のレベルを判定します。
- 信号を30個取り込む
- その内から最大値と最小値を求める
- 最大値と最小値の差を求める
- その差に応じてLEDを点灯させる
回路図
10kΩのボリュームを廻してコレクタ電圧が約2.5Vになるように調整します。
そうすると信号に応じてコレクタ電圧が2.5Vを中心に変化することになります。
信号は、トランジスタで約10倍に増幅された後PICに入力されます。
ソースコード
- LevelMeter.c
//********************************************************************** void main() { static unsigned int ad, adbuf[30], cnt, max, min; // CMCON = 0b00000111; ANSEL = 0b00000100; TRISA = 0b00111111; TRISB = 0b00000000; OSCCON = 0b01110000; // for (cnt = 0; cnt < 10; cnt++) { PORTB = 0b00000000; PORTA = 0b00000000; Delay_ms(100); PORTB = 0b11111111; PORTA = 0b11000000; Delay_ms(100); } while (1) { // アナログデータを30個読み込む for (cnt = 0; cnt < 30; cnt++) adbuf[cnt] = Adc_Read(2); // その30個のデータから最大値と最小値を求める max = 0; min = 1024; for (cnt = 0; cnt < 30; cnt++) { max = (max < adbuf[cnt]) ? adbuf[cnt] : max; min = (min > adbuf[cnt]) ? adbuf[cnt] : min; } // 最大値と最小値の差を求める ad = (max - min) / 100; // switch (ad) { case 0: PORTB = 0b11111110; PORTA.F6 = 1; PORTA.F7 = 1; break; case 1: PORTB = 0b11111100; PORTA.F6 = 1; PORTA.F7 = 1; break; case 2: PORTB = 0b11111000; PORTA.F6 = 1; PORTA.F7 = 1; break; case 3: PORTB = 0b11110000; PORTA.F6 = 1; PORTA.F7 = 1; break; case 4: PORTB = 0b11100000; PORTA.F6 = 1; PORTA.F7 = 1; break; case 5: PORTB = 0b11000000; PORTA.F6 = 1; PORTA.F7 = 1; break; case 6: PORTB = 0b10000000; PORTA.F6 = 1; PORTA.F7 = 1; break; case 7: PORTB = 0b00000000; PORTA.F6 = 1; PORTA.F7 = 1; break; case 8: PORTB = 0b00000000; PORTA.F6 = 0; PORTA.F7 = 1; break; case 9: PORTB = 0b00000000; PORTA.F6 = 0; PORTA.F7 = 0; break; } Delay_ms(10); } } //**********************************************************************





