Считывание импульсов

Luk
Offline
Зарегистрирован: 15.09.2016

Добрый вечер. Собираю установку по очистке форсунок, и назрел вопрос. Как

с помощью ардуино считать частоту и скважность с генератора импульсов?

ToRcH2565
Offline
Зарегистрирован: 16.05.2015
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

ToRcH2565 пишет:

Первые же две ссылки по данному запросу

А разве по этим ссылкам есть хоть что-нибудь про

Luk пишет:

частоту и скважность

?

 

ToRcH2565
Offline
Зарегистрирован: 16.05.2015

А разве сильно трудно забить запрос про скважность самостоятельно?

И да, я проверял, информация про скважность есть, но не в этих темах, если еще и ее вот так на блюдичке ТС хотеть, то тут ниже есть ветка "Ищу исполнителя", ибо как мне кажется напечатать свой вопрос можно было в яндекс\гугл перед тем как форум мучать.

Luk
Offline
Зарегистрирован: 15.09.2016

Спасибо за помощь. Блуждая по форуму, нашел подходящую ветку http://arduino.ru/forum/proekty/generator-s-reguliruemoei-chastotoi-na-arduino?page=1. И это навело на мысль что проще генерировать чем считывать

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Ну можно и считывать. Как раз я недавно изучал альтернативные способы счёта длительности импульсов/частоты. Вот интересный вариант написал без использования прерываний, счёт длины импульса идёт в ассемблерном коде, при появлении на входе единицы запускаются таймеры. Когда такт кончится таймеры отстанавливаются. Используются сразу 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): ); }




 

Luk
Offline
Зарегистрирован: 15.09.2016

Спасибо большое, это точто нужно!

Sasha80
Offline
Зарегистрирован: 18.01.2016

Я так понимаю что при измерении свыше 5в на вход нужен делитель. При этом код не нужно править.