у меня тележка за секунду пробегает более метра, на старом форуме есть тема про эту тележку
Это единственная тележка во всей Вселенной?
Или есть абсолютная уверенность, что все остальные тележки устроены точно так же?
И, кстати, тема про тахометр и датчик холла, но никак не про ту самую тележку, про которую есть тема на старом форуме.
При чём тут это? Думаете Евгений тролил, говоря, что задача не решаема в принципе?
Он предложил ТС определится с минимальной скоростью, ниже которой будем считать что колесо стоит…моё предложение - дюйм в секунду
Мой расчет по сути является конкретизацией утверждения Петровича - как именно оценивать критерий неподвижности (который в исходном сообщении напрочь отсутствовал).
Вот я и показал примером расчета, что численное значение критерия выбрано неудачно.
так это поправимо, но секунда это максимальное время для принятия решения, ИМХО
Проверил на роботе. Вроде даже работает, но появился вопрос про Атомарность при чтении. Я вроде бы понимаю для чего это нужно (для того чтобы функция прерывания не прерывалась другой функцией).
В общем, я нашел библиотеку в Arduino IDE
Если я правильно понимаю, после подключения библиотеки, должно быть так…
#include <SimplyAtomic.h>
#define PIN_LED 47
unsigned int rotA = 0;
unsigned int rotB = 0;
unsigned long int tmA;
unsigned long int tmB;
volatile unsigned long int spdA = 0;
volatile unsigned long int spdB = 0;
void HalA(unsigned int dtA = 0) {
ATOMIC() {
rotA++; // прибавляем единичку к счётчику обротов
dtA = millis() - tmA; // вычисляем время с последнего расчёта
if( dtA >= 100 ){ // если прошло 100мс или более, то начинаем расчёт
spdA = rotA*60000/dtA;
rotA = 0; // обнуляем счётчик
tmA = millis(); // запоминаем время расчёта
}
}
}
void HalB(unsigned int dtB = 0) {
ATOMIC() {
rotB++; // прибавляем единичку к счётчику обротов
dtB = millis() - tmB; // вычисляем время с последнего расчёта
if( dtB >= 100 ){ // если прошло 100мс или более, то начинаем расчёт
spdB = rotB*60000/dtB;
rotB = 0; // обнуляем счётчик
tmB = millis(); // запоминаем время расчёта
}
}
}
void setup() {
pinMode(PIN_LED, OUTPUT);
attachInterrupt(digitalPinToInterrupt(5), HalA, CHANGE); //новое
attachInterrupt(digitalPinToInterrupt(4), HalB, CHANGE); //новое
tmA = millis();
tmB = millis();
}
void loop() {
if(spdA <= 100 || spdB <= 100){
digitalWrite(PIN_LED, HIGH);
}
else{
digitalWrite(PIN_LED, LOW);
}
}
Или я не то “окружаю”?)
это видимо надо делать на чтении из этой переменной вне обработчика прерывания, ИМХО
В void loop()?
void loop() {
ATOMIC() {
if(spdA <= 100 || spdB <= 100){
digitalWrite(PIN_LED, HIGH);
}
else{
digitalWrite(PIN_LED, LOW);
}
}
}
бред какой-то. Зачем весь луп в атомик запихивать? И нафига для этого библиотека?
Окружите чтение переменной вызовами cli() и sei() и дело с концом.
А еще лучше, раз мы в ардуино, для совместимости использовать noInterrupts() и interrupts()
вот так надо
void loop() {
// выключаем прерывания на время копирования волатильных переменных в локальные
noInterrupts();
_spdA = spdA;
_spdB = spdB;
interrupts(); // включаем прерывания обратно
if(_spdA <= 100 || _spdB <= 100){
digitalWrite(PIN_LED, HIGH);
}
else{
digitalWrite(PIN_LED, LOW);
}
}
Оптимист…
Иногда и года недостаточно…
О как. Спасибо. Пойду перечитаю еще раз информацию про Атомарность, видимо вообще не дочитал)
это когда спутницу по жизни выбираешь, то да… )))
Вы не окружаете не то, Вы делаете не то.
После недели тестов все работает как надо! Всем спасибо за помощь в решении данного вопроса.