как считывать частоту посредством ардуино.
- Войдите на сайт для отправки комментариев
Пнд, 09/01/2012 - 16:52
можно ли считывать частоту посредством ардуино и если да то,как?
можно ли считывать частоту посредством ардуино и если да то,как?
Постмотрите в этой теме
http://arduino.ru/forum/programmirovanie/kak-izmerit-chastotu
как я понял частоту можно измерять двумя способами функцией pulseIn и с помощью библиотеки FreqCounter.Я хочу измерять частоту и чтобы значение появлялось в serial.Вот код, как думаете написан правильно?
void setup(){
pinMode(7,OUTPUT);
Serial.begin(9600);
}
void loop(){
val = pulseIn(7,HIGH)/1000000;переводим микросекунды в секунды
Serial.println(1/val);val это период поделив его на один мы получаем частоту
}
val это период поделив его на один мы получаем частоту
val это не период, а длина импульса. А между импульсами есть еще паузы, когда уровень сигнала LOW.
Кроме того, поделив значение, возвращенное pulseIn, на миллион, вы получите нулик. Почему? Потому шта... Потому что переменная val у вас определена как целое, а значит деление будет выполнено по правилам целочисленной арифметики.
Опять таки, кроме того: измерять частоту на базе одного периода - плохая идея. Ибо точность у вас получится вполне себе "метеорологическая". Плюс-минус два лаптя...
так ввел изменения в код, что думаете?
От модератора: Я подредактировал. Пользуйтесь кнопкой вставки кода пожалуйста. Ну ведь симпатичнее и легче читается с форматированием-то.
так не получится.
Если вы делаете вызов pulseIn(x,HIGH), то в функции сначала ожидается приход возрастающего фронта, запускается таймер и отсчитывается время до прихода ниспадающего фронта. В вызове pulseIn(x,LOW) все наоборот. Н ведь ниспадающий фронт уже прошел, поэтому функция довольно долго - почти период - стоять в ожидании нового нисъодящего фронта. Более-менее приемлемая точность будет достигаться только на достаточно низких и стабильных частотах.
Это первое.
Второе:
Полный период вашего переменного сигнала складывается из длины пульса ("HIGH") и паузы между пульсами ("LOW"). Это val+val2. Соответственно, для вычисления (приблизительной) частоты деление следует производить на эту сумму.
понятно спасибо за ответ буду пробывать.2 модератор не получается пользоваться кнопкой code
ввел изменения.
int val = 0;
void setup(){
pinMode(7,INPUT);
Serial.begin(9600);
}
void loop(){
val = pulseIn(7,HIGH) + pulseIn(7,LOW);
Serial.print(1000000/val);//так мы получаем частоту т.к 1/(val/1000000) = 1000000/val
Serial.println("HZ");
}
Всем доброй ночи! Не хотел плодить новую тему, решил написать здесь. Вопрос все тот же - измерение частоты (плата arduino pro mini) . Начал разбираться с таймерами счетчиками и попробовал разобраться в найденных здесь на форуме в том числе примерах.
Вот код:
И второй:
Как быть с точностью в измерениях? Чем большую частоту подаем на вход, тем больше погрешность. Результаты могу сообщить в понедельник, т.к. под рукой нет нормального генератора. Хотелось бы измерять сигналы до 1-5 МГц с достаточной точностью, а не +/- два лаптя.
SergeySB, в принципе есть готовые библы. FreqMeasure оптимизирован для измерения частот от 0.1 Hz до 1 kHz. И FreqCount для диапазона от 1 kHz до 8 MHz. Точность да, обратно пропорциональна частоте.
Собственно, чтобы точность была прямо пропорциональна частоте, а не наоборот, нужно не измерять длину периода, а считать количество импульсов за заданный интервал времени.
Спасибо за комментарии!! По поводу библиотек- гуглил их, прежде чем сюда написать. Хотел пока без них разобраться что и как. Вообще у меня стоит основная задача следующая. Имеется сигнал, частота которого постоянно меняется (от единиц килогерц до 30-40 МГц). И необходимо, например измерять длительность каждого положительного импульса, и выводить все это в порт. Понятно, что моей ардуины для такой задачи не хватит, потому что тактовая частота маленькая, скорость обмена по Serial низкая, и тогда просто данные не будут успевать уходить... Но хотелось бы все-таки пока попытаться реализовать задачу на ардуине, снизив частоту исходного сигнала мегагерц до 5. Может попытаться применить счетчик на входе ардуины для деления входного сигнала. Пока мысли такие - грубо: считывать одну из ног порта, куда подается изменяющийся сигнал. Если была "1", запустить таймер по переполнению, и остановить его, когда пришел "0". Результат выдать в порт. Возможна ли такая реализация без использования аппаратных средств МК? (типа вызов прерывания по спаду, фронту, изменению итп).
сигнала. Пока мысли такие - грубо: считывать одну из ног порта, куда подается изменяющийся сигнал. Если была "1", запустить таймер по переполнению, и остановить его, когда пришел "0". Результат выдать в порт. Возможна ли такая реализация без использования аппаратных средств МК? (типа вызов прерывания по спаду, фронту, изменению итп).
Этот способ для низких частот, для высоких нужно накапливать число срабатываний за большой отрезок времени, например за секунду. К тому-же на меге328 нельзя давать на таймер частоту выше тактовой/2 . А кстати на микрочиповских PICах -можно, на них хоть 100МГц можно будет измерить.
На частоте 5 МГц один цикл - это 3 такта процессора. Для сравнения digitelRead выполняется около 80 тактов. Можно, конечно, читать порт низкоуовневыми команндами, но все равно Вы вряд ли уложитесь в 3 такта.
Хорошо. Тогда попробую поиграться с измерительным интервалом. Для начала попробую так: задаем "измерительный" интервал с помощью ТС с прерыванием по переполнению. В момент измерения, всякий раз в прерывании по таймеру в режиме захвата (с ноги ICP) увеличиваем некую переменную. . Правильно? Если несложно напишите как по-человечески это должно выглядеть...
SergeySB, я ж вам написал, что этот способ для измерения низких частот, максимум десятки килогерц. Если выше -начнёт страшно врать. Высокие измеряют по-другому. Сигнал подают на вход T1 таймера, соответссно Clock Select настраивают от входа Т1. Настраивают прерывание по переполнению (timer1_ovf_vect), в прерывании инкреминируется переменная, говорящая о том, сколько раз оттактировано по 65536 раз. Ещё один таймер настраивают на отсчёт точных промежутков времени, обычно секунда. Каждую секунду создаётся прерывание. В нём подсчитывается сколько раз было натикано по 65536 раз + прибавляется содержание переменной TCNT1 . Из полючившегося кол-ва тиков в секунду зная время одного тика вычисляется частота или длительность одного периода. Потом всё обнуляется и процесс повторяется.
dimax, спасибо! Я приблизительно тоже самое хотел написать, просто очень неккоректно выразился. Еще раз спасибо, пошел разбираться. После удачных экспериментов по-возможности отпишусь.
Подпишусь пожалуй, мне скоро надо будет частоту считать.
Братишки, а по типу стрелочного частотомера ни у кого не получалось? Нахимичить типа переходник, зарядную цепь (какие требования к конденсатору?), и в АЦП это. Просто гуляла схема частотомера для прибора на 100 мкА, но сейчас купить такую вещь проблематично. Да и громоздко это, плюс нельзя ронять/пинать. Интересует диапазон 5 Гц - 50 кГц.
Вот набросал свой код. Как и писал входным сигналом тактируется таймер1, второй таймер засекает время 1сек. Сколько раз успеет натикать за секунду -такая и частота. В сериал выводит количество целых периодов в секунду (т.е. Герц :) Для проверки подал прецизионные 2048 герц, частотометр показал 2051, думаю это нормальная погрешность для дешевых кварцов на ардуинах.
Т.к. 16-битный таймер только один, а нужно 2шт, то пришлось немного извратнуться с таймером2. Он считает отрезками по 8мс, и на 125 раз (8мс x 125=1сек) запускает подсчёт частоты.
dimax, еще раз благодарю!! А мне учиться, учиться и еще раз...
Сегодня дошли руки проверить частотомер со скетчем от dimax. Максимально что далось намерить- сигнал с лабораторного генератора частотой 3 МГц. Дальше в сериал выводится всякая ерунда.
SergeySB, это нормально, я упростил кое-что. В той библе посерьёзней подошли к делу. Но в любом случае 8МГц будет максимум.
Да, dimax, я понял. Про 8 МГц тоже понятно ) . Придется попытаться на PICe реализовать. Все равно спасибо!
Я, конечно, извиняюсь, но не подскажете ли новичку-чайнику как понимать эту клинопись: это что - что-то низкоуровневое типа asm? Что, например, обозначает абревиатура "...TCCR2B..." и все эти стрелочки-скобочки и т. д. Будь ласка - хотя бы ссылочку, где можно почитать про это хотя бы в среднем объёме. Спс
это что - что-то низкоуровневое
Да, это низкоуровневая настройка переферии микроконтроллера (в данном случае аппаратного таймера).
типа asm?
Нет, это Си.
Что, например, обозначает абревиатура "...TCCR2B..."
Это название одного из регистров для настройки аппаратного таймера. Откройте даташит на микроконтроллер, там расписаны все регистры.
и все эти стрелочки-скобочки и т. д.
Это битовые операции в языке Си. Чтобы не писать "магические числа" в регистр, типа TCCR2B |= 00000111, там указаны имена битов в регистре. Все названия и описание регистров есть в даташите. Нужно только подучить битовые операции в языке Си. И научиться читать даташит.
Вот набросал свой код. Как и писал входным сигналом тактируется таймер1, второй таймер засекает время 1сек. Сколько раз успеет натикать за секунду -такая и частота. В сериал выводит количество целых периодов в секунду (т.е. Герц :) Для проверки подал прецизионные 2048 герц, частотометр показал 2051, думаю это нормальная погрешность для дешевых кварцов на ардуинах.
Спасибо. Вы как всегда помогаете. проверил частоту ШИМ в прошивках для лазерных ЧПУ на ардуино
grbl_v0_9j даёт частоту 7807 герц
grbl_v1.1f даёт частоту 976 герц
Но задачу нужно усложнить. нужно считывать не просто частоту, а сигнал который идёт. Нашел такую статью: http://pyatilistnik.info/chtenie-signala-pwm-ispolzuya-apparatnyie-prery...
Но там всё очень не точно. Если с меньшей частотой ещё как то работает, то с большой вообще что попало.
Возможно сделать это вашим способом? например заводим сигнал сразу на два пина. Первое прерывание обнуляет счётчик а по второму останавливает подсчёт. И привести полученные значения обратно в числа от 0 до 255.
DIMAX я использовал ваш код частотометра для цифровой шкалы FM, работает но иногда исчезает цифра первого разряда 06.8 вместо 106.8, 6.5 вместо 96.5. Подскажите где косяк.
тау измерения взять в микросекундах, смысла тормозится на целую секунду нет, поинтересуюсь, а процессор какой?
328 мега."NANO" У меня по входу SAB6456, делит на 256 частота до 400 кгц.
но иногда исчезает цифра первого разряда 06.8 вместо 106.8, 6.5 вместо 96.5. Подскажите где косяк.
Судя по симптомам, скорее всего ошибка возникает на принимающей стороне.
Дополнение. Или какие то "хитрые" аппаратные наводки (или помехи) которые приводят к потере первого после перерыва символа.
328 мега."NANO" У меня по входу SAB6456, делит на 256 частота до 400 кгц.
его код для моей поделки, работает без нареканий:
Отображение передаётся по блютуз. На принимающей стороне использовал два разных софта, на разных устройствах, тоже самое.
Это ничего не изменило, арифметика. Проверил. Цифра пропадает безсистемно.
Это ничего не изменило, арифметика. Проверил. Цифра пропадает безсистемно.
выводить тики в сериал и смотреть
еще так:
invalid operands of types 'float' and 'int' to binary 'operator>>'
polok, Вы хотите использовать обычную Нано для измерения частот около 100мГц?
polok, Вы хотите использовать обычную Нано для измерения частот около 100мГц?
Да. У меня по входу SAB6456, делит на 256 частота до 400 кгц. И я измеряю.
А если без блютус, просто в сериал, правильно выводит?
А если без блютус, просто в сериал, правильно выводит?
Так же.
А если без блютус, просто в сериал, правильно выводит?
Так же.
похоже проблема с сериалом, попробуйте перед выводом частоты выводить лидирующий ноль -"0"
А если без блютус, просто в сериал, правильно выводит?
Так же.
похоже проблема с сериалом, попробуйте перед выводом частоты выводить лидирующий ноль -"0"
Спасибо попробую завтра, уже третий час, пойду спать
Волатильная многобайтовая переменная без атомарных операций - шажок в сумрак шизофренического жития.
Возьмите генератор на 400 кГц (примерно 100мГц/256) - это частота с делителя. И на этой частоте отработайте правильный вывод в сериал.
Возьмите генератор на 400 кГц (примерно 100мГц/256) - это частота с делителя. И на этой частоте отработайте правильный вывод в сериал.
С делителя идёт почти идеальный меандр.
а тип переменной в 20 строке поправил?
кстати она у него имеет тип флоат и не волатильная )))
Извиняюсь! ввёл в заблуждение. В сериал всё хорошо, был прав P75NF75, что- то с выводом через блютуз. Ошибка, я проверял через Bluetooth Serial Port Monitor. Если не обиделись, что может быть с выводом через блютуз?
Извиняюсь! ввёл в заблуждение. В сериал всё хорошо, был прав P75NF75, что- то с выводом через блютуз. Ошибка, я проверял через Bluetooth Serial Port Monitor. Если не обиделись, что может быть с выводом через блютуз?
попробовать выводить строку, у приятеля через блютуз прибор подсоединяется к компьютеру, потерь информации нет