Частота дискретизации "Чтение аналогового напряжения"

Я хочу убедиться, что мой код выглядит как работающий, так как завтра у меня не так много времени с генератором сигналов, и я хочу знать, как установить частоту дискретизации.

Я хочу сэмплировать сигнал 2 кГц с частотой дискретизации 6 кГц с Arduino MEGA 2560. Это не обязательно должно быть в реальном времени, поэтому я думаю о заполнении буфера и последующей его отправке по последовательному соединению. Кто-нибудь может сказать, что этот код определенно не будет работать для этого? И как я могу установить частоту дискретизации до 6 кГц?

void setup() {
Serial.begin(9600);
}

void loop() {

for(int x = 0; x < 1000; x++){
  // read the input on analog pin 0:
  int sensorValue[x] = analogRead(A0);
 } 

for( x = 0; x < 1000; x++){
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
  float voltage[x] = sensorValue[x] * (5.0 / 1023.0);

  // print out the value you read:
  Serial.println(voltage[x]);
}

}

Спасибо.

1 ответ

Ну, как я уже упоминал в другом потоке, вы можете использовать режим автоматического запуска 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 бод, но он все еще слишком медленный. Пробел можно использовать в качестве разделителя, это сохранит один символ (поскольку в новой строке обычно два символа: \r\n). Одно значение может быть длиной от 1 до 4 символов, поэтому для значений:

  • 0-9 - 3B, вам нужна скорость передачи 3 * 10 * 6000 = 180000
  • 10-99 - 4B и вам нужна скорость передачи 240000
  • а в остальных случаях ты слишком медленный.

Таким образом, единственный способ - отправлять эти целые числа в двоичном виде, и без разделителя это было бы еще лучше. 2B на значение приводит к минимальной скорости передачи около 120000 бод / с.

Другие вопросы по тегам