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);
}
}
@Omar Ali, 👍2
Обсуждение1 ответ
В цикле у вас есть 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 АЦП для получения подробной информации. Если этого недостаточно, вам придется использовать внешние компоненты, например аналоговый вычитатель, изготовленный из операционного усилителя, и пару компараторов.
- Чтение частоты ввода в цифровых выводах
- DHT11 аналоговый или цифровой?
- Как считывать аналоговое значение на ESP32-CAM с включенным считывателем SD-карт?
- Ardunio Mega/ATmega2560: использование порта F или K как для аналоговых входов, так и для цифровых выходов.
- Arduino измерительный высоковольтный электрический забор
- Nano: все цифровые контакты ничего не выводят
- создание анализатора гармоник мощности, который будет измерять амплитуды основной и кратных ей частот (например, 50 Гц, 100 Гц, 150 Гц, 200 Гц,...)
- Регистр АЦП всегда возвращается высоким
Вы уже погуглили это в гугле? При использовании таких терминов, как "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