今度は、中間電位の平均値だけでなく、同じ方法でノイズレベルの平均値も求める。
#include <avr/io.h> #include <util/delay.h> extern "C"{ #include "USART.h" } void initADC(){ ADMUX |= (1 << REFS0); // AVCCを基準電圧として使う。 ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // ADCプリスケーラーを128分周に設定する。 ADCSRA |= (1 << ADEN); // ADCを有効化する。 } uint16_t readADC(char ch){ ADMUX |= (0xF0 & ADMUX) | ch; // チャンネル選択ビットを全部一旦クリアしてから目的のチャンネルをセットする。 ADCSRA |= (1 << ADSC); // ADCを開始(Start Conversion)する。 loop_until_bit_is_clear(ADCSRA, ADSC); // ADCの終わるまで待ってから、 return ADC; // 10ビットのADC値を返す。 } int main(){ uint16_t midVal = 511; // 中間電位の假の平均値 uint16_t deadBandHalf = 20; // 假の不感帯域(ゼロピーク値) uint16_t hiVal = midVal + deadBandHalf; // 中間電位を上回ったAD変換値(ノイズと見なす値の上半分)の假の平均値。不感帯域の假の上限。 uint16_t loVal = midVal - deadBandHalf; // 中間電位を下回ったAD変換値(ノイズと見なす値の下半分)の假の平均値。不感帯域の假の下限。 uint16_t padding = 1 << 4; // 背景ノイズの大きさにマージンとして追加する値(16倍した値) uint16_t noiseVol = (hiVal - loVal) + padding; // 背景ノイズの假の大きさ uint16_t adcVal; initADC(); initUSART(); while(1){ adcVal = readADC(PC2); // 中間電位の平均値を更新する。 midVal = adcVal + midVal - ((midVal - 8) >> 4); // 中間電位を上回った値(ノイズと見なす値の上半分)の平均値を更新する。 if (adcVal > (midVal >> 4)){ hiVal = adcVal + hiVal - ((hiVal - 8) >> 4); } // 中間電位を下回った値(ノイズと見なす値の下半分)の平均値を更新する。 if (adcVal < (midVal >> 4)){ loVal = adcVal + loVal - ((loVal - 8) >> 4); } // 背景ノイズの大きさを更新する。余裕を見て少し値(padding)を足す。 noiseVol = (hiVal - loVal) + padding; // 最後の最後に16で割る。 printString("midVal: ") ; printWord(midVal >> 4) ;printString("\r\n"); printString("hiVal: ") ; printWord(hiVal >> 4) ;printString("\r\n"); printString("loVal: ") ; printWord(loVal >> 4) ;printString("\r\n"); printString("noiseVol: "); printWord(noiseVol >> 4) ;printString("\r\n"); printString("\r\n"); _delay_us(10); } return 0; }