расчет оборотов двигателя по датчику
- Войдите на сайт для отправки комментариев
Ср, 29/07/2020 - 10:14
Привет комрады.
вопрос такой, есть датчик tcrt5000
от оборотов двигателя, получаю импульс через attachInterrupt(0, OkHoll, FALLING);
void OkHoll() {
//int tcn = TCNT0;
long mil = millis();
long raznMilis = mil - HollaTimeOld;
HollaTimeOld = mil;
Serial.println(raznMilis);
}
результат raznMilis:
36
36
36
36
36
36
35
36
36
36
36
37
ну типа в милисекундах, а как из этого подсчитать обороты двигателя?
вообще задача такая:
есть коллекторный двигатель,
как мне вычислять этот момент в прерывании, так, чтоб основной процесс понимал, что делать, увеличивать частоту шим или уменьшать или.
вообщем нужно поддерживать обороты движка
Один оборот выполняется за raznMilis мс (переведите в секунды). Сколько raznMilis содержится в одной секунде?
А чё не на таймере? На нём точнее будет.
ну типа в милисекундах, а как из этого подсчитать обороты двигателя?
это вопрос не по программированию, а чисто по школьной математике.
Задачка полностью аналогична примерно такой - "Пешеход проходит 80 метров за 55 секунд. Рассчитайте его скорость в километрах в час"
5,23 да?
5,23 да?
ну вообще-то у меня получается 1304 в минуту
long raznMilis = mil - HollaTimeOld;
HollaTimeOld = mil;
//Serial.println(raznMilis);
long ObMin = 60000/(raznMilis);
А чё не на таймере? На нём точнее будет.
так а вот тут по подробнее, в теории же прерывание срабатывает при событии, а таймером нужно постоянно опрашивать порт?
я не силен в ардуино-кодинге, мож я просто что-то не так понимаю
ну вообще-то у меня получается 1304 в минуту
long raznMilis = mil - HollaTimeOld;
HollaTimeOld = mil;
//Serial.println(raznMilis);
long ObMin = 60000/(raznMilis);
вообще-то если подставить сюда цифру 36 из заглавного сообщения - 1300 не получится...
ну вообще-то у меня получается 1304 в минуту
long raznMilis = mil - HollaTimeOld;
HollaTimeOld = mil;
//Serial.println(raznMilis);
long ObMin = 60000/(raznMilis);
вообще-то если подставить сюда цифру 36 из заглавного сообщения - 1300 не получится...
та не, то я для примера скинул, регулятор мотора крутанул и уже другие результаты.
вопрос, кстати, как эти данные подкинуть в PID регулятор оборотов движка?
#define TACHOMETER_PIN 21 #define TACHOMETER_TIME_INTERVAL 200 volatile unsigned long t_interruptionTime; volatile byte t_interruptionCounter; unsigned long t_previousTime; void setup() { attachInterrupt(digitalPinToInterrupt(TACHOMETER_PIN), t_interruption, RISING); } void loop() { if (millis() - t_previousTime >= TACHOMETER_TIME_INTERVAL) { unsigned long t_currentTime; unsigned int t_RPM; byte t_counter; noInterrupts(); t_counter = t_interruptionCounter; t_currentTime = t_interruptionTime; t_interruptionCounter = 0; interrupts(); t_RPM = 60000 / ((t_currentTime - t_previousTime) * 2 / t_counter); // Умножить на 2 потому что в моем случае 2 импульса = 1 оборот t_previousTime = t_currentTime; } } void t_interruption() { t_interruptionTime = millis(); t_interruptionCounter++; }Вот так считаю обороты на моте, показывает ровно, но если двигатель малооборотистый то лучше интервал расчетов увеличить конечно. Можно не запоминать время прошлого расчета и вместо "(t_currentTime - t_previousTime)" использовать просто 200мс, как например в моем случае, но если между расчетами есть другие задачи то точность может сильно упасть, ибо там уже может быть уже не 200мс, а 230мс например.
Вообще очень советую вот эту статью: https://habr.com/ru/post/346126/
#define TACHOMETER_PIN 21 #define TACHOMETER_TIME_INTERVAL 200 volatile unsigned long t_interruptionTime; volatile byte t_interruptionCounter; unsigned long t_previousTime; void setup() { attachInterrupt(digitalPinToInterrupt(TACHOMETER_PIN), t_interruption, RISING); } void loop() { if (millis() - t_previousTime >= TACHOMETER_TIME_INTERVAL) { unsigned long t_currentTime; unsigned int t_RPM; byte t_counter; noInterrupts(); t_counter = t_interruptionCounter; t_currentTime = t_interruptionTime; t_interruptionCounter = 0; interrupts(); t_RPM = 60000 / ((t_currentTime - t_previousTime) * 2 / t_counter); // Умножить на 2 потому что в моем случае 2 импульса = 1 оборот t_previousTime = t_currentTime; } } void t_interruption() { t_interruptionTime = millis(); t_interruptionCounter++; }Вот так считаю обороты на моте, показывает ровно, но если двигатель малооборотистый то лучше интервал расчетов увеличить конечно. Можно не запоминать время прошлого расчета и вместо "(t_currentTime - t_previousTime)" использовать просто 200мс, как например в моем случае, но если между расчетами есть другие задачи то точность может сильно упасть, ибо там уже может быть уже не 200мс, а 230мс например.
Вообще очень советую вот эту статью: https://habr.com/ru/post/346126/
так в том и дело, что в основном цикле куча других датчиков, вывод на экран lcd, поэтому и ковыряюсь, не ну впринципе сделал, осталось все это дело в PID передавать
так в том и дело, что в основном цикле куча других датчиков, вывод на экран lcd
Код выше вам в помощь.
void OkHoll() { //int tcn = TCNT0; long mil = millis(); long raznMilis = mil - HollaTimeOld; HollaTimeOld = mil; Serial.println(raznMilis); }Еще бы я вам не советовал делать какие то долгие вычисления (а лучше вообще без них) в прерывании, иначе при увеличении оборотов ардуина большую часть времени будет обрабатывать прерывания а не основной loop, вплоть до того что прерывания будут становится в очередь и loop будет "зависать"
Код выше вам в помощь.
void OkHoll() { //int tcn = TCNT0; long mil = millis(); long raznMilis = mil - HollaTimeOld; HollaTimeOld = mil; Serial.println(raznMilis); }unsigned long mil
unsigned long raznMilis
unsigned long HollaTimeOld
Код выше вам в помощь.
void OkHoll() { //int tcn = TCNT0; long mil = millis(); long raznMilis = mil - HollaTimeOld; HollaTimeOld = mil; Serial.println(raznMilis); }unsigned long mil
unsigned long raznMilis
unsigned long HollaTimeOld
Согласен, только код выше это вот тут http://arduino.ru/forum/programmirovanie/raschet-oborotov-dvigatelya-po-datchiku#comment-550837