analogRead() не считывает более 500 Гц

Я подключил генератор волн к аналоговым контактам, чтобы считывать частоты генерируемых волн. Я использовал разные частоты синусоидальных волн с минимумом 0 В и максимумом 5 В.

Всякий раз, когда напряжение превышает 2,5 В, я делаю один из цифровых контактов ВЫСОКИМ, а ДРУГОЙ НИЗКИМ, когда оно меньше 2,5 В. Теперь, измеряя прямоугольную волну от цифрового контакта, она всегда имеет ту же частоту, что и синусоидальные волны, вплоть до 500 Гц.

После 500 Гц частота прямоугольной волны не согласуется с синусоидой, что заставило меня подумать, что проблема в analogRead(). Есть ли способ иметь более высокую частоту?

Код:

const int sensorPin1 = A0;
const int sensorPin2 = A1;
const float maximumPower = 2.5;
int calibration = 1;

void setup() {
  Serial.begin(57600);
  pinMode(6, OUTPUT);
  digitalWrite(6, LOW);
}

void loop() {
  int voltage2 = 3;
  int voltage1 = 3;
  int sensorVal = abs(analogRead(sensorPin1) - analogRead(sensorPin2));
  float ratio = abs(analogRead(sensorPin2) / analogRead(sensorPin1));
  float voltageDifference = (sensorVal / 1024.0) * 5.0;
  float power = calibration * voltageDifference;
  if (power >= maximumPower || voltage1 <= 1 || voltage2 <= 1) {
    digitalWrite(6, LOW);
  }
  else {
    digitalWrite(6, HIGH);
  }
}

, 👍2

Обсуждение

Вы уже погуглили это в гугле? При использовании таких терминов, как "analogread higher sample frequency" или подобных, вы можете найти решения для этого (в основном просто меняя прескалер часов АЦП). Вы читали некоторые из этих результатов?, @chrisl

500 Гц кажется немного низким. Я ожидал бы чего-то вроде 4 кГц. Вы понимаете, что вам нужно по крайней мере два образца за цикл? Какой Arduino вы используете? Не могли бы вы показать нам свой код? Почему вы используете analogRead () вместо`digitalRead ()'? Какая частота дискретизации вам нужна для вашего приложения? Какое аналоговое разрешение? Чего вы пытаетесь достичь?, @Edgar Bonet

"analogRead() работает медленно. "digitalWrite() работает медленно. Соедините их вместе, и это будет медленно-медленно. Добавьте в эту смесь математику с плавающей запятой (вы упомянули 2,5 В, а не 512), и она поползет со скоростью улитки. Почему вы вообще используете для этого Arduino? То же самое можно сделать с помощью простого компаратора (операционного усилителя)., @Majenko

@Majenko: Даже используя floats и digitalWrite(), я все равно получаю более 7200 итераций в секунду на Uno., @Edgar Bonet

@EdgarBonet Уменьши это вдвое для найквиста-Шеннона, так что 3600. Никакого упоминания о том, на чем он работает - это может быть макетная плата Arduino с внутренними часами 1 МГц (div-8). Так что разделите это на 16, и вы получите всего лишь 225 Гц..., @Majenko

Может быть уместно: https://arduinoprosto.ru/q/67295/38721, @Sim Son

извините за поздний ответ. Я добавил код. Спасибо вам всем, @Omar Ali


1 ответ


2

В цикле у вас есть 4 вызова метода analogRead (). При скорости около 112 мкс на вызов это уже занимает 448 мкс. Добавьте к этому время, затраченное на вычисления с плавающей запятой, и вы, скорее всего, получите что-то порядка 500 мкс за итерацию цикла. Это должно обеспечить частоту дискретизации, близкую к 2 кГц, что должно позволить вам обнаруживать максимумы и минимумы входного сигнала до 1 кГц при условии, что рабочий цикл близок к 50%.

Здесь можно выполнить несколько простых оптимизаций. Два из вызовов метода analogRead() не служат никакой цели, так как результаты никогда не используются. И вычисления с плавающей запятой также бессмысленны. Весь цикл можно упростить до этого:

void loop() {
    if (abs(analogRead(A0) - analogRead(A1)) >= 512) {
        digitalWrite(6, LOW);
    } else {
        digitalWrite(6, HIGH);
    }
}

Это должно занять около 224 мкс на итерацию. Если вам нужно идти быстрее, вам придется увеличить рабочую частоту АЦП. Это может стоить некоторой точности, но если точность не имеет критического значения для вашего приложения, это может быть хорошим компромиссом. Смотрите страницу Ника Гэммона на Arduino АЦП для получения подробной информации. Если этого недостаточно, вам придется использовать внешние компоненты, например аналоговый вычитатель, изготовленный из операционного усилителя, и пару компараторов.

,