#1 2016-04-11 15:56:02

plaztik
Учасник
Зареєстрований: 2015-09-18
Повідомлень: 9

Помогите разобраться с кодом по прерыванию

Здравствуйте, помогите пожалуйста с кодом для обработки датчика Холла(измеряю частоту вращения вала, в диапазоне 5-40 тыс.об./мин.). Есть Ардуино Уно, необходимо преобразовать сигнал с двух датчиков Холла, и есть вот такой пример кода:

#include <MsTimer2.h>  //библиотека таймера
unsigned int state=0;
unsigned int rmp=0;
unsigned int time=0;
unsigned long timpause=1000; // 1c

void flash() //обработка прерывания таймера 
{
detachInterrupt(0); //остановить прерывания 2
Serial.print("rmp:");
Serial.println(rmp*60);
rmp=0;
attachInterrupt(0, blink, RISING ); //вкл 2 прерывания
}

void setup() {
Serial.begin(9600);
attachInterrupt(0, blink, RISING ); //прерывания на 2м порту - с датчика холла
MsTimer2::set(1000, flash); // 1 c
MsTimer2::start(); //включаем прерывания по таймеру
}
void loop() { }
void blink()  //прерывания с датчика холла
{
++rmp;  //увеличиваем счетчик на 1
}

Необходимо подогнать его под 2 датчика Холла, по всякому уже пробовал менять код, но ничего не получилось, прошу помощи, очень нужно.
Еще есть пример, который работал на DUE, но на 16 мГц платах этот скетч измеряет частоту вращения только до частоты 545 Гц (32640 тыс.об/мин), потом выдает минусовые значения.

volatile int rpmcount = 0;
int rpm = 0;
unsigned long lastmillis = 0;
float rpm2 = 0;
int rrr = 1;
void setup(){
Serial.begin(9600);
attachInterrupt(0, rpm_fan, FALLING);//interrupt cero (0) is on pin two(2).
}
void loop(){
if (millis() - lastmillis == 1000){ /*Uptade every one second, this will be equal to reading frecuency (Hz).*/
detachInterrupt(0); //Disable interrupt when calculating
rpm = rpmcount * 60;
rpm2 = rpm *(rrr);/* Convert frecuency to RPM, note: this works for one interruption per full rotation. For two interrups per full rotation use rpmcount * 30.*/
Serial.print("RPM =\t"); //print the word "RPM" and tab.
Serial.print(rpm); // print the rpm value.
Serial.print("\t Hz=\t"); //print the word "Hz".
Serial.println(rpmcount); /*print revolutions per second or Hz. And print new line or enter.*/
rpmcount = 0; // Restart the RPM counter
lastmillis = millis(); // Uptade lasmillis
attachInterrupt(0, rpm_fan, FALLING); //enable interrupt
}
}
void rpm_fan(){ /* this code will be executed every time the interrupt 0 (pin2) gets low.*/
rpmcount++;
}

Помогите пожалуйста, буду очень благодарен smile

Остання редакція plaztik (2016-04-11 15:58:50)

Неактивний

#2 2016-04-11 16:42:57

vvr
Учасник
Зареєстрований: 2015-04-12
Повідомлень: 874

Re: Помогите разобраться с кодом по прерыванию

при таких оборотах вам и одного датчика за глаза хватит)))

Неактивний

#3 2016-04-11 16:50:29

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Помогите разобраться с кодом по прерыванию

этот  пример некорректный
в основном цикле  отключение  прерываний,
посмотрите на
https://arduino-info.wikispaces.com/Timers-Arduino

наиболее простой вариант
2 прерывания на ваши датчики

таймер настроен на счет UP
при поступлении interrupts от датчика сохраняете текущее значения счетчика таймера
при переполнении таймера  в значение времени добавляете разницу от размерности счетчика и записанного значения счетчика при прерывании
при поступлении следующего прерывания к времени с учетом  переполнения если было )  добавляете время текущего значения счетчика
ну и признак какой то поставьте что пришел сигнал
надеюсь не запутал )
думаю что то подобное должно быть реализовано  примерах для IR пульта, попробуйте там поискать
и никаких отключений  прерываний  в рабочем цикле!
поищите что то должно быть
ключевые слова
Arduino Timer Interrupts
timer overflow interrupt
быстрый просмотр сети не дал готового решения, но уверен что что то похожее должно быть )

Неактивний

#4 2016-04-11 16:53:23

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Помогите разобраться с кодом по прерыванию

40000/60 = 666.(6) Гц )

Остання редакція NoName (2016-04-11 17:05:13)

Неактивний

#5 2016-04-11 18:48:17

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Помогите разобраться с кодом по прерыванию

базовый принцип

код в переполнении  счетчика
TimePeriod +=  0x10000 - HARDWARE_TIMER_COUNT_Start;  HARDWARE_TIMER_COUNT_Start = 0;
0x10000 - максимальное значения счетчика, 0x10000 для максимума 0xFFFF
 
void Begin ( void )
{
  HARDWARE_TIMER_COUNT_Start = HARDWARE_TIMER_COUNT;
  TimePeriod = 0;
}

void End (  )
{
  // если было переполнение то HARDWARE_TIMER_COUNT_Start = 0 
  TimePeriod += ( HARDWARE_TIMER_COUNT - HARDWARE_TIMER_COUNT_Start);

  TimePeriod_pulse = TimePeriod;
  
  // начало для следующего испульса 
  HARDWARE_TIMER_COUNT_Start = HARDWARE_TIMER_COUNT;
  TimePeriod = 0;  
}

Begin при старте
в прерывании от сетчика  End вызывайте, там уже реализован сброс для следующего импульса
запустите для одного, второй разберетесь

TimePeriodExecuted - время между импульсами
HARDWARE_TIMER_COUNT_Start - значение счетчика
TimePeriod - временно значение счетчика

вариант compare пошустрее, но вам, как я написал будет проще именно такой 
TimePeriod_pulse ваше время для расчета RPM
признак что есть новый импульс сами придумайте

где то так, успехов

Неактивний

#6 2016-04-12 09:40:26

plaztik
Учасник
Зареєстрований: 2015-09-18
Повідомлень: 9

Re: Помогите разобраться с кодом по прерыванию

vvr пише:

при таких оборотах вам и одного датчика за глаза хватит)))

Необходимо измерять частоту вращения на двух валах одновременно

Неактивний

#7 2016-04-12 09:43:32

plaztik
Учасник
Зареєстрований: 2015-09-18
Повідомлень: 9

Re: Помогите разобраться с кодом по прерыванию

NoName пише:

этот  пример некорректный
в основном цикле  отключение  прерываний,
посмотрите на
https://arduino-info.wikispaces.com/Timers-Arduino

наиболее простой вариант
2 прерывания на ваши датчики

таймер настроен на счет UP
при поступлении interrupts от датчика сохраняете текущее значения счетчика таймера
при переполнении таймера  в значение времени добавляете разницу от размерности счетчика и записанного значения счетчика при прерывании
при поступлении следующего прерывания к времени с учетом  переполнения если было )  добавляете время текущего значения счетчика
ну и признак какой то поставьте что пришел сигнал
надеюсь не запутал )
думаю что то подобное должно быть реализовано  примерах для IR пульта, попробуйте там поискать
и никаких отключений  прерываний  в рабочем цикле!
поищите что то должно быть
ключевые слова
Arduino Timer Interrupts
timer overflow interrupt
быстрый просмотр сети не дал готового решения, но уверен что что то похожее должно быть )


немного тяжело все сразу понять, буду пытаться найты, спасибо!

Неактивний

#8 2016-04-12 09:44:59

plaztik
Учасник
Зареєстрований: 2015-09-18
Повідомлень: 9

Re: Помогите разобраться с кодом по прерыванию

NoName пише:

40000/60 = 666.(6) Гц )

Значит в этом вся проблема))
sad

Неактивний

#9 2016-04-12 10:30:51

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Помогите разобраться с кодом по прерыванию

что то будет в проекте кроме подсчета частоты и вероятно вывод на экран?
многие библиотеки используют таймера, и могу испоганить настройку таймера

Неактивний

#10 2016-04-12 16:22:35

plaztik
Учасник
Зареєстрований: 2015-09-18
Повідомлень: 9

Re: Помогите разобраться с кодом по прерыванию

NoName пише:

что то будет в проекте кроме подсчета частоты и вероятно вывод на экран?
многие библиотеки используют таймера, и могу испоганить настройку таймера

Экрана нету, пока необходимо выводить только в COM порт

Неактивний

#11 2016-04-12 16:44:24

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Помогите разобраться с кодом по прерыванию

тогда начинайте так
по примерам запускайте таймер из свободных, по хорошему мне бы это попробовать, но некогда (
сделайте чтение их регистра таймера
программная пауза  в коде   на ~700 Гц
это 0,0014 с
delayMicroseconds(140);
       
и повторное чтение -
вывод 2 результатов в порт,
пауза стандартная, дельта  должена  быть одинакова, если только нет перехода через сброс счетчика
если все в порядке до добавляете мой код что скидывал для одного счетчика,
запустите один канал,  второй должен так же запуститься, нет сложных вычислений, и косяков алгоритма,  контроллер справится

Неактивний

#12 2016-04-12 17:16:36

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Помогите разобраться с кодом по прерыванию

что то похожее есть, посмотрите на этот код
http://www.avdweb.nl/arduino/libraries/ … unter.html

вот вариант для варианта пошустрее )
https://www.pjrc.com/teensy/td_libs_FreqCount.html

Неактивний

#13 2016-04-14 11:29:01

plaztik
Учасник
Зареєстрований: 2015-09-18
Повідомлень: 9

Re: Помогите разобраться с кодом по прерыванию

NoName пише:

что то похожее есть, посмотрите на этот код
http://www.avdweb.nl/arduino/libraries/ … unter.html

вот вариант для варианта пошустрее )
https://www.pjrc.com/teensy/td_libs_FreqCount.html



Спасибо большое, очень помогла инфа! Всех благ Вам и успехов! smile

Неактивний

#14 2016-04-14 12:45:48

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Помогите разобраться с кодом по прерыванию

пжлст,
если не под NDA покажите что получилось,
и зачем 2 вала, в общем, с немаленькими оборотами ? )

Неактивний

Швидке повідомлення

Введіть повідомлення і натисніть Надіслати

Підвал форуму