2016-10-05 3 views
0

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

Я хочу пробовать сигнал 2 кГц с частотой 6 кГц с Arduino MEGA 2560. Это не обязательно в реальном времени, поэтому я думаю о заполнении буфера, а затем отправке тех, последовательное соединение. Может ли кто-нибудь сказать, будет ли этот код defenitly не работать для этого? И как я могу установить выборку на 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]); 
} 

} 

спасибо.

ответ

0

Ну, как я уже упоминал в другом потоке, вы можете использовать автоматический режим 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 - 4В и вам нужна скорость передачи данных 240000
  • , а для остальных случаев вы слишком медленны.

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

+0

Большое спасибо за работу. Но я понимаю, что проблема в том, что последовательное соединение происходит слишком медленно. Это не так в этом коде? – AprilDC

+0

@AprilDC Отвечено обновлено. Вы можете вписаться в 250000baud/s, если вы используете значения HEX и пробел в качестве разделителя. Или используя двоичные значения непосредственно без разделителя. – KIIV

Смежные вопросы