さて、別のスレッドで述べたように、ADC
(UNO
およびATMega328p
ベースの Arduinos の場合)の自動トリガー モードを使用できます。
void setup() {
Serial.begin(256000);
// ADC setup is done by arduino framework, but it's possible to change it slightly (for ATMega328) :
ADCSRB = _BV(ADTS2) | _BV(ADTS1) | _BV(ADTS0); // ADTS2..0 = 111, Timer 1 input capture event trigger source
ADCSRA |= _BV(ADATE); // enable auto trigger mode
ADCSRA |= _BV(ADIF); // reset conversion end flag (= interrupt flag)
// timer 1 setting:
TCCR1A = 0; // clear all
ICR1 = F_CPU/6000U; // 1 should be substracted here but result is about 2665.7 and it will be truncated to 2665
TCCR1B = _BV(WGM12) | _BV(WGM13) | _BV(CS10); // CTC mode with ICR1 as TOP value, enabled with no prescaling
TIMSK1 = _BV(ICF1); // not working without this... Flag must be cleaned up after the trigger ADC, otherwise it's stucked
analogRead(A0); // dummy read to set correct channel and to start auto trigger mode
pinMode(13, OUTPUT);
}
void loop() {
if (ADCSRA & _BV(ADIF)) {
ADCSRA |= _BV(ADIF); // reset flag by writing logic 1
Serial.println(ADC);
}
}
ISR(TIMER1_CAPT_vect) { // to clear flag
PINB = _BV(PB5); // and toggle d13 so frequency can be measured (it'd be half of real rate)
// it might be enabled on PWM pin too by setting force output compare and some compare register to half of value ICR1
}
このスケッチはボーレート 250000 を使用していますが、それでも遅すぎます。スペース文字を区切り文字として使用できます。これにより、1 文字節約できます (改行は通常 2 文字: \r\n)。1 つの値の長さは 1 から 4 文字にすることができるため、値の場合:
- 0-9 - 3B 必要なボーレート 3*10*6000 = 180000
- 10-99 - 4B で、ボーレート 240000 が必要です
- 残りのケースでは、遅すぎます。
したがって、唯一の方法はこれらの整数をバイナリで送信することであり、セパレーターがなければさらに良いでしょう。値ごとに 2B を指定すると、120000 ボー/秒前後の最小ボー レートになります。