Считывание импульсов
- Войдите на сайт для отправки комментариев
Чт, 15/09/2016 - 20:56
Добрый вечер. Собираю установку по очистке форсунок, и назрел вопрос. Как
с помощью ардуино считать частоту и скважность с генератора импульсов?
https://www.yandex.ru/search/?text=частотомер%20на%20arduino&lr=39&clid=9582
Первые же две ссылки по данному запросу
http://arduino.ru/forum/apparatnye-voprosy/chastotomer-na-arduino-uno-i-...
http://arduino.ru/forum/programmirovanie/chastotomer-na-arduino
Первые же две ссылки по данному запросу
А разве по этим ссылкам есть хоть что-нибудь про
частоту и скважность
?
А разве сильно трудно забить запрос про скважность самостоятельно?
И да, я проверял, информация про скважность есть, но не в этих темах, если еще и ее вот так на блюдичке ТС хотеть, то тут ниже есть ветка "Ищу исполнителя", ибо как мне кажется напечатать свой вопрос можно было в яндекс\гугл перед тем как форум мучать.
Спасибо за помощь. Блуждая по форуму, нашел подходящую ветку http://arduino.ru/forum/proekty/generator-s-reguliruemoei-chastotoi-na-arduino?page=1. И это навело на мысль что проще генерировать чем считывать
Ну можно и считывать. Как раз я недавно изучал альтернативные способы счёта длительности импульсов/частоты. Вот интересный вариант написал без использования прерываний, счёт длины импульса идёт в ассемблерном коде, при появлении на входе единицы запускаются таймеры. Когда такт кончится таймеры отстанавливаются. Используются сразу 2 тамера, первый и второй. Их суммарная разрядность - 24 бита, что позволяет считать частоту от 1 герца с минимальными потерями в точности. Вход импульсов -12пин уно/нано/промини. На других платах работать скорее всего не будет. Компилил в IDE 1.6.8 в других версиях тоже может не работать. В сериал выводит частоту в герцах и duty в процентах. Частоты от 1 Гц примерно до 150 кГц, дальше начнёт неуспевать. (Для высоких частот есть более эффективные методы.)
void setup() { Serial.begin(9600); pinMode (12,INPUT); // вход сигнала } void loop() { uint32_t tic1 = asm_func(1); uint32_t tic2 = asm_func(0); float duty= (1/ ((float)tic1/tic2))*100; float freq= float(16E6/tic1); freq<100? Serial.print(freq,1) : Serial.print(freq,0); Serial.print(" "); Serial.println( duty,0 ); } uint32_t asm_func(uint8_t flag){ asm volatile ( "cli" "\n\t" "mov r21,%0" "\n\t" // флаг что считывать //конфигурация таймеров "ldi r18,0x83" "\n\t" // GTCCR=0x83 "out 0x23,r18" "\n\t" // GTCCR=0x83 "sts 0x80,__zero_reg__" "\n\t" // TCCR1A=0 "ldi r19,0x4" "\n\t" "sts 0x81,r19" "\n\t" // TCCR1B=1<<CS12 "sts 0x85, __zero_reg__" "\n\t"//TCNT1L=0 "sts 0x84, __zero_reg__" "\n\t"//TCNT1H=0 "sts 0xB0,__zero_reg__" "\n\t" // TCCR2A=0 "ldi r20,0x1" "\n\t" "sts 0xB1,r20" "\n\t" // TCCR2B=1<<CS20 "sts 0xB2,__zero_reg__" "\n\t" // TCNT2=0 "sts 0x70,__zero_reg__" "\n\t" // TIMSK2=0 // пройти если ноль "wait_begin:" "\n\t" "sbic 0x03,4" "\n\t" "rjmp wait_begin" "\n\t" // пройти если единица -> первый импульс "wait_start:" "\n\t" "sbis 0x3,4" "\n\t" "rjmp wait_start" "\n\t" "sts 0x43,__zero_reg__" "\n\t" // GTCCR=0 старт синхра // импульс пошёл, ждём ноль "wait_pause:" "\n\t" "sbic 0x03,4" "\n\t" "rjmp wait_pause" "\n\t" "cpi r21,__zero_reg__" "\n\t" // "brne duty" "\n\t" // импульс кончился, ждём конца периода (единицу) "wait_end:" "\n\t" "sbis 0x3,4" "\n\t" "rjmp wait_end" "\n\t" "duty:" "\n\t" "out 0x23,r18" "\n\t" // GTCCR=0x83 стоп таймеры //вывод 3х байт "lds r22, 0xB2" "\n\t" // tctn2 0 байт "lds r23, 0x84" "\n\t" // TCNT1L 1 байт "lds r24, 0x85" "\n\t" // TCNT1H 2 байт "lds r25, __zero_reg__" "\n\t" // пустой 3 байт "sei" "\n\t" ::"r" (flag): ); }Спасибо большое, это точто нужно!
Я так понимаю что при измерении свыше 5в на вход нужен делитель. При этом код не нужно править.