Замер скорости

Lightning_Eva
Lightning_Eva аватар
Offline
Зарегистрирован: 04.06.2019

Магнитов >1 потому, что скорость очень медленная, ~ 1м/с, и надо максимально быстро понимать, когда колесо остановилось. Мы и так полторы секудны ждем. Поэтому и не важно откуда начали считать, если мы знаем расстояние между ближайшеми магнитами.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Lightning_Eva пишет:

ЕвгенийП пишет:

Ну чего не считать по каждому прохождению магнита, сколько бы там их не было? Количество-то то всяко известно, всегда можно поделить полученную скорость на количество магнитов. Я примерно так считаю скорость тележки, только там не магнит, а энокодер на моторе - выдаёт 45 импульсов на оборот. Проблееы не понял. Поясните.

Да, об этом и идет речь.

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

Lightning_Eva
Lightning_Eva аватар
Offline
Зарегистрирован: 04.06.2019

sadman41 пишет:

Lightning_Eva пишет:

Получится как один магнит ( сейчас их два).

Это плохо? На выходе имеете полный оборот, а не часть его.

 

Lightning_Eva пишет:

А если четыре или семь? С одним магнитом и так все работает. Но нам надо больше.))

В обработчике прерывания всё, что делаете с одним магнитом, делайте на каждый четвёртый или седьмой вход и выставляйте байтовый флаг "данные готовы". В лупе этот флаг постоянно проверяете - как только он взведён, производите атомарную работу с переменными, которые в обработчике меняете и сбрасываете флаг. И так будет по кругу мотаться всё.

Если не скорость невелика, то, то обработчик можно изобразить так:

volatile uint8_t interruptCount = 0x00;
const uint8_t magnitsNumber  = 7;
...
void sp_metr() {                  
  interruptCount++;
  if (interruptCount < magnitsNumber )  { return; } // ничего не делаем, пока оборот не завершён
  // В противном случае начинаем счёт сначала и занимаемся с millis()
  interruptCount = 0x00;
  Time2 = millis();
  ...
 }

В лупе, если будет приделана кнопка "Пуск/Останов", interruptCount обнулять, чтобы начинать счёт с начала круга.

Ваше повествование не выход в моей ситуации, но наталкивает на определенные мысли)))

Lightning_Eva
Lightning_Eva аватар
Offline
Зарегистрирован: 04.06.2019

ua6em пишет:

Lightning_Eva пишет:

ЕвгенийП пишет:

Ну чего не считать по каждому прохождению магнита, сколько бы там их не было? Количество-то то всяко известно, всегда можно поделить полученную скорость на количество магнитов. Я примерно так считаю скорость тележки, только там не магнит, а энокодер на моторе - выдаёт 45 импульсов на оборот. Проблееы не понял. Поясните.

Да, об этом и идет речь.

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

micros()?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Lightning_Eva пишет:

Всем спасибо за ответы.

Arduino NANO.

Получился такой код:

//Speedometr

unsigned long millis_temp = 0;  
unsigned long Time1 = 0; 
unsigned long Time2 = 0;

unsigned long frequency = 0;         //частота импульсов 
unsigned long speed = 0;             //скорость
unsigned int timeout = 1600;         // (миллисекунд) максимальное время ожидания
unsigned int Magnets = 2;            // Количество магнитов на колесе
unsigned int Distance = 204;         // Расстояние между магнитами

volatile float speed_fl = 0.00;      //скорость float


void setup() 
  {
  Serial.begin(9600);
  pinMode(INT0, INPUT); 
  attachInterrupt(INT0, sp_metr, RISING); //INT0
   }

void loop()
   {
         if((millis() - millis_temp) > timeout) //Задержка до обнуления
           { 
            frequency=0;
           }
           else 
           {  
             if(!Time1 == 0)
               {
                frequency = (100000 / Time1); //Частота, Гц
               }
           }
       
    speed = ( (frequency * 10) / Magnets)*((314 * Distance)) / 1000000; // Вычисление скорости вращения      
    speed_fl = speed / 100.0;

    Serial.print("millis_temp = ");
    Serial.print(millis_temp);
    Serial.print("  Time1 = ");
    Serial.print(Time1);
    Serial.print("  Time2 = ");
    Serial.print(Time2);
    Serial.print("  frequency = ");
    Serial.print(frequency);
    Serial.print("  speed = ");
    Serial.print(speed);
    Serial.print("  speed_fl = ");
    Serial.println(speed_fl);
  }
    
void sp_metr() //Обработка прерывания
    {                 
    cli();
    Time2 = millis();
    Time1 = Time2 - millis_temp;
    millis_temp = Time2; 
    sei(); 
    }

теперь работает, но из-за неидеальности расположения магнитов данные скорости "плавают".

millis_temp = 396607  Time1 = 97  Time2 = 396607  frequency = 1030  speed = 329  speed_fl = 3.29
millis_temp = 396704  Time1 = 97  Time2 = 396704  frequency = 1030  speed = 329  speed_fl = 3.29
millis_temp = 396802  Time1 = 98  Time2 = 396898  frequency = 1020  speed = 326  speed_fl = 3.26
millis_temp = 396898  Time1 = 96  Time2 = 396996  frequency = 1041  speed = 333  speed_fl = 3.33
millis_temp = 396996  Time1 = 98  Time2 = 397092  frequency = 1020  speed = 326  speed_fl = 3.26
millis_temp = 397092  Time1 = 98  Time2 = 397190  frequency = 1041  speed = 333  speed_fl = 3.33
millis_temp = 397190  Time1 = 97  Time2 = 397287  frequency = 1020  speed = 326  speed_fl = 3.26
millis_temp = 397287  Time1 = 98  Time2 = 397385  frequency = 1030  speed = 329  speed_fl = 3.29
millis_temp = 397385  Time1 = 98  Time2 = 397483  frequency = 1020  speed = 326  speed_fl = 3.26
millis_temp = 397580  Time1 = 97  Time2 = 397580  frequency = 1020  speed = 326  speed_fl = 3.26
millis_temp = 397677  Time1 = 97  Time2 = 397677  frequency = 1030  speed = 329  speed_fl = 3.29
millis_temp = 397775  Time1 = 98  Time2 = 397775  frequency = 1030  speed = 329  speed_fl = 3.29

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

в простейшем случае так:
 

void sp_metr() //Обработка прерывания
    {                 
    cli();
    Time2 = millis();
    Time1 = (Time1+(Time2 - millis_temp))/2;
    millis_temp = Time2; 
    sei(); 
    }

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Lightning_Eva пишет:

ua6em пишет:

Lightning_Eva пишет:

ЕвгенийП пишет:

Ну чего не считать по каждому прохождению магнита, сколько бы там их не было? Количество-то то всяко известно, всегда можно поделить полученную скорость на количество магнитов. Я примерно так считаю скорость тележки, только там не магнит, а энокодер на моторе - выдаёт 45 импульсов на оборот. Проблееы не понял. Поясните.

Да, об этом и идет речь.

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

micros()?

микрос болтается в районе точности в 4 микросекунды, если устроит, то пожалуй

Lightning_Eva
Lightning_Eva аватар
Offline
Зарегистрирован: 04.06.2019

ua6em пишет:

Lightning_Eva пишет:

Всем спасибо за ответы.

Arduino NANO.

Получился такой код:

//Speedometr

unsigned long millis_temp = 0;  
unsigned long Time1 = 0; 
unsigned long Time2 = 0;

unsigned long frequency = 0;         //частота импульсов 
unsigned long speed = 0;             //скорость
unsigned int timeout = 1600;         // (миллисекунд) максимальное время ожидания
unsigned int Magnets = 2;            // Количество магнитов на колесе
unsigned int Distance = 204;         // Расстояние между магнитами

volatile float speed_fl = 0.00;      //скорость float


void setup() 
  {
  Serial.begin(9600);
  pinMode(INT0, INPUT); 
  attachInterrupt(INT0, sp_metr, RISING); //INT0
   }

void loop()
   {
         if((millis() - millis_temp) > timeout) //Задержка до обнуления
           { 
            frequency=0;
           }
           else 
           {  
             if(!Time1 == 0)
               {
                frequency = (100000 / Time1); //Частота, Гц
               }
           }
       
    speed = ( (frequency * 10) / Magnets)*((314 * Distance)) / 1000000; // Вычисление скорости вращения      
    speed_fl = speed / 100.0;

    Serial.print("millis_temp = ");
    Serial.print(millis_temp);
    Serial.print("  Time1 = ");
    Serial.print(Time1);
    Serial.print("  Time2 = ");
    Serial.print(Time2);
    Serial.print("  frequency = ");
    Serial.print(frequency);
    Serial.print("  speed = ");
    Serial.print(speed);
    Serial.print("  speed_fl = ");
    Serial.println(speed_fl);
  }
    
void sp_metr() //Обработка прерывания
    {                 
    cli();
    Time2 = millis();
    Time1 = Time2 - millis_temp;
    millis_temp = Time2; 
    sei(); 
    }

теперь работает, но из-за неидеальности расположения магнитов данные скорости "плавают".

millis_temp = 396607  Time1 = 97  Time2 = 396607  frequency = 1030  speed = 329  speed_fl = 3.29
millis_temp = 396704  Time1 = 97  Time2 = 396704  frequency = 1030  speed = 329  speed_fl = 3.29
millis_temp = 396802  Time1 = 98  Time2 = 396898  frequency = 1020  speed = 326  speed_fl = 3.26
millis_temp = 396898  Time1 = 96  Time2 = 396996  frequency = 1041  speed = 333  speed_fl = 3.33
millis_temp = 396996  Time1 = 98  Time2 = 397092  frequency = 1020  speed = 326  speed_fl = 3.26
millis_temp = 397092  Time1 = 98  Time2 = 397190  frequency = 1041  speed = 333  speed_fl = 3.33
millis_temp = 397190  Time1 = 97  Time2 = 397287  frequency = 1020  speed = 326  speed_fl = 3.26
millis_temp = 397287  Time1 = 98  Time2 = 397385  frequency = 1030  speed = 329  speed_fl = 3.29
millis_temp = 397385  Time1 = 98  Time2 = 397483  frequency = 1020  speed = 326  speed_fl = 3.26
millis_temp = 397580  Time1 = 97  Time2 = 397580  frequency = 1020  speed = 326  speed_fl = 3.26
millis_temp = 397677  Time1 = 97  Time2 = 397677  frequency = 1030  speed = 329  speed_fl = 3.29
millis_temp = 397775  Time1 = 98  Time2 = 397775  frequency = 1030  speed = 329  speed_fl = 3.29

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

в простейшем случае так:
 

void sp_metr() //Обработка прерывания
    {                 
    cli();
    Time2 = millis();
    Time1 = (Time1+(Time2 - millis_temp))/2;
    millis_temp = Time2; 
    sei(); 
    }

 

а если магнита 4?

Morroc
Offline
Зарегистрирован: 24.10.2016

Lightning_Eva пишет:

Ворота пишет:

Т.е. расстояния неодинаковы? А одинаковыми никак нельзя сделать?

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

Ну просто усреднить.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Lightning_Eva пишет:

ua6em пишет:

Lightning_Eva пишет:

Всем спасибо за ответы.

Arduino NANO.

Получился такой код:

//Speedometr

unsigned long millis_temp = 0;  
unsigned long Time1 = 0; 
unsigned long Time2 = 0;

unsigned long frequency = 0;         //частота импульсов 
unsigned long speed = 0;             //скорость
unsigned int timeout = 1600;         // (миллисекунд) максимальное время ожидания
unsigned int Magnets = 2;            // Количество магнитов на колесе
unsigned int Distance = 204;         // Расстояние между магнитами

volatile float speed_fl = 0.00;      //скорость float


void setup() 
  {
  Serial.begin(9600);
  pinMode(INT0, INPUT); 
  attachInterrupt(INT0, sp_metr, RISING); //INT0
   }

void loop()
   {
         if((millis() - millis_temp) > timeout) //Задержка до обнуления
           { 
            frequency=0;
           }
           else 
           {  
             if(!Time1 == 0)
               {
                frequency = (100000 / Time1); //Частота, Гц
               }
           }
       
    speed = ( (frequency * 10) / Magnets)*((314 * Distance)) / 1000000; // Вычисление скорости вращения      
    speed_fl = speed / 100.0;

    Serial.print("millis_temp = ");
    Serial.print(millis_temp);
    Serial.print("  Time1 = ");
    Serial.print(Time1);
    Serial.print("  Time2 = ");
    Serial.print(Time2);
    Serial.print("  frequency = ");
    Serial.print(frequency);
    Serial.print("  speed = ");
    Serial.print(speed);
    Serial.print("  speed_fl = ");
    Serial.println(speed_fl);
  }
    
void sp_metr() //Обработка прерывания
    {                 
    cli();
    Time2 = millis();
    Time1 = Time2 - millis_temp;
    millis_temp = Time2; 
    sei(); 
    }

теперь работает, но из-за неидеальности расположения магнитов данные скорости "плавают".

millis_temp = 396607  Time1 = 97  Time2 = 396607  frequency = 1030  speed = 329  speed_fl = 3.29
millis_temp = 396704  Time1 = 97  Time2 = 396704  frequency = 1030  speed = 329  speed_fl = 3.29
millis_temp = 396802  Time1 = 98  Time2 = 396898  frequency = 1020  speed = 326  speed_fl = 3.26
millis_temp = 396898  Time1 = 96  Time2 = 396996  frequency = 1041  speed = 333  speed_fl = 3.33
millis_temp = 396996  Time1 = 98  Time2 = 397092  frequency = 1020  speed = 326  speed_fl = 3.26
millis_temp = 397092  Time1 = 98  Time2 = 397190  frequency = 1041  speed = 333  speed_fl = 3.33
millis_temp = 397190  Time1 = 97  Time2 = 397287  frequency = 1020  speed = 326  speed_fl = 3.26
millis_temp = 397287  Time1 = 98  Time2 = 397385  frequency = 1030  speed = 329  speed_fl = 3.29
millis_temp = 397385  Time1 = 98  Time2 = 397483  frequency = 1020  speed = 326  speed_fl = 3.26
millis_temp = 397580  Time1 = 97  Time2 = 397580  frequency = 1020  speed = 326  speed_fl = 3.26
millis_temp = 397677  Time1 = 97  Time2 = 397677  frequency = 1030  speed = 329  speed_fl = 3.29
millis_temp = 397775  Time1 = 98  Time2 = 397775  frequency = 1030  speed = 329  speed_fl = 3.29

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

в простейшем случае так:
 

void sp_metr() //Обработка прерывания
    {                 
    cli();
    Time2 = millis();
    Time1 = (Time1+(Time2 - millis_temp))/2;
    millis_temp = Time2; 
    sei(); 
    }

 

а если магнита 4?

а какая разница сколько их, вы усредняете текущее с предыдущим, текущее после двух измерений будет уже усреднённым, по нормальному вводить еще условие проверки, что тайм1 не ноль, а то среднее будет долго приближаться

Lightning_Eva
Lightning_Eva аватар
Offline
Зарегистрирован: 04.06.2019

Вот как раз разница и есть. Усреднять исходя из полного оборота. Расстояние между всеми магнитами в колесе вот и выглядит одиноковым, по факту разное. Поэтому и замеров нужно делать столько сколько магнитов.

Morroc
Offline
Зарегистрирован: 24.10.2016

В том примере усреднение происходит каждый замер и неважно сколько магнитов. По типу Замер = (Предыдущий замер + Новый замер) / 2 

Pyotr
Offline
Зарегистрирован: 12.03.2014

Ева, почему именно магниты? Есть готовые и точные решения: промышленный энкодер, из автомобиля - датчик положения коленвала, да тот же трамблер от жигулей контактный или восьморочный с датчиком холла получаем 4 импульса на оборот или 8 фронтов.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Lightning_Eva пишет:

Вот как раз разница и есть. Усреднять исходя из полного оборота. Расстояние между всеми магнитами в колесе вот и выглядит одиноковым, по факту разное. Поэтому и замеров нужно делать столько сколько магнитов.

Сударыня, я правильно понимаю, что вы написали процедуру обработки прерывания вызываемую при прохождении каждого  магнита над датчиком и, при этом не понимаете как она работает?
Может это не Вы написали )))

Morroc
Offline
Зарегистрирован: 24.10.2016

Pyotr пишет:

Ева, почему именно магниты? 

Так это проще всего - приклеил магниты на подвижную часть, датчик на неподвижную, а там где механическая связь нужна - придется её колхозить, неудобно.

qbit
Offline
Зарегистрирован: 18.03.2019

Lightning_Eva пишет:

micros()?

Ага.  На колонку Time1 взгляните, значение 96...98мс, что даеет уже погрешность более 2%. Её и видите в  speed и speed_fl. Поэтому, переходите на micros.

Переменную frequency переветиде на тип float, а то будете терять точность при делении и дальнейших вычислениях.

Коэффициент 314 замените на 314.15926535, а то получается, что Вы уже вносите погрешность ~0,32% в вычисления.

Обратите внимание на мс и мкс в Ваших формулах:

frequency = (100000 / Time1); //Частота, Гц

У Вас тики в мс и множитель должен быть 1000, а у Вас стоит 10^5.

Lightning_Eva
Lightning_Eva аватар
Offline
Зарегистрирован: 04.06.2019

Я прекрасно понимаю, как работает ваш код. Такой вариант приемлем только для 2-х магнитов на колесе. Я алгоритм понимаю, как, если для четырех магнитов, слонить 4 замера и разделить на 4. Но не могу изобразить в коде.

Morroc
Offline
Зарегистрирован: 24.10.2016

Lightning_Eva пишет:
Такой вариант приемлем только для 2-х магнитов на колесе.

Точно ?

Lightning_Eva
Lightning_Eva аватар
Offline
Зарегистрирован: 04.06.2019

ua6em пишет:

Lightning_Eva пишет:

Вот как раз разница и есть. Усреднять исходя из полного оборота. Расстояние между всеми магнитами в колесе вот и выглядит одиноковым, по факту разное. Поэтому и замеров нужно делать столько сколько магнитов.

Сударыня, я правильно понимаю, что вы написали процедуру обработки прерывания вызываемую при прохождении каждого  магнита над датчиком и, при этом не понимаете как она работает?
Может это не Вы написали )))

Сударь! Что за постоянные провокации!? В интернете, да и на этом сайте конкретно, полно примеров как организовать простейший обработчик прерывания. И с чего вы взяли, что я не понимаю как она работает!? Не надо меня уж совсем за дуру считать! Я уже написала, что у меня конкретно не получается - как правильно работать с подсчетами, когда их больше двух, за оборот колеса. Как их складывать будет правильнее? У нас разное расстояние между магнитами и с этим мы сделать ничего не можем, но это расстояние всегда одинаково. Поэтому нужно все радиусы учесть. С двумя магнитами все работает, но нужно разобраться с четырьмя.

Lightning_Eva
Lightning_Eva аватар
Offline
Зарегистрирован: 04.06.2019

Morroc пишет:

Lightning_Eva пишет:
Такой вариант приемлем только для 2-х магнитов на колесе.

Точно ?

да

если магнитов больше, мы найдем среднее между двумя последними, но это будет пол диаметра, если их, допустем 4. и в итоге фактическая длина окружности будет плавать, что я и наблюдаю.

Lightning_Eva
Lightning_Eva аватар
Offline
Зарегистрирован: 04.06.2019

Morroc пишет:

Lightning_Eva пишет:
Такой вариант приемлем только для 2-х магнитов на колесе.

Точно ?

да

если магнитов больше, мы найдем среднее между двумя последними, но это будет пол диаметра, если их, допустем 4. и в итоге фактическая длина окружности будет плавать, что я и наблюдаю.

Lightning_Eva
Lightning_Eva аватар
Offline
Зарегистрирован: 04.06.2019

Morroc пишет:

Lightning_Eva пишет:
Такой вариант приемлем только для 2-х магнитов на колесе.

Точно ?

да

если магнитов больше, мы найдем среднее между двумя последними, но это будет пол диаметра, если их, допустем 4. и в итоге фактическая длина окружности будет плавать, что я и наблюдаю.

Lightning_Eva
Lightning_Eva аватар
Offline
Зарегистрирован: 04.06.2019

ой! задвоилось))

Lightning_Eva
Lightning_Eva аватар
Offline
Зарегистрирован: 04.06.2019

если бы это был комерческий проект, ваши предложения были бы как нельзя лучше. А пока колесо на палочке отлично подходит. Да и дело в алгоритме.

sadman41
Offline
Зарегистрирован: 19.10.2016

Что же это за конструкция такая...

Morroc
Offline
Зарегистрирован: 24.10.2016

Lightning_Eva пишет:

если магнитов больше, мы найдем среднее между двумя последними, но это будет пол диаметра, если их, допустем 4. и в итоге фактическая длина окружности будет плавать, что я и наблюдаю.

Конечно будет несколько плавать. Чтобы не плавало вам придется узнать какой именно сектор вы проехали - например установив еще один датчик с одним магнитом и от него вести отсчет.

sadman41 пишет:

Что же это за конструкция такая...

Ага, тоже интересно почему нельзя прилепить магниты ровно.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Lightning_Eva пишет:

 

Сударь! Что за постоянные провокации!?....
У нас разное расстояние между магнитами и с этим мы сделать ничего не можем, но это расстояние всегда одинаково...

У меня когнитивный диссонанс, если всё таки разное, то придётся усреднить и эти расстояния и рассчитывать среднюю скорость, как-то так )))
То-есть есть сектор, средняя длина сектора равна к примеру X, есть среднее время прохождения сектора, по ним и считать

А  максимально быстро понимать, что колесо остановилось - определяться с временем между прерываниями, если оно больше к примеру на 30% чем время прохождения одного (среднего)  сектора этого достаточно?

процент можно и уменьшить взяв за основу самый большой сектор
Это самое простое как мне кажется

 

Lightning_Eva
Lightning_Eva аватар
Offline
Зарегистрирован: 04.06.2019

Фиолетовый - магниты, зеленый поле. Вот конструкция колеса. Как тут видно, ровное расположение магнитов, не говорит о том что датчик Холла воспринимае это так же. Все 4 расстояния получаются разными. Измерив 4 раза, сложив и разделив на 4 получим точный полный оборот. 

qbit
Offline
Зарегистрирован: 18.03.2019

Lightning_Eva пишет:

нет, потому что у всех магнитов немного разное поле.

Главное, чтобы было срабатывание. Этим можно пренебречь. 

 

Lightning_Eva пишет:

...для этого и нужен фильтр, что бы нивелировать технологическую особенность изготовления.

Пример БИХ фильтра 1-го порядка:

#define BANDWIDTH_FILTER 8 // более 1, кратно степени 2
...
float y, y0;
...

// x - входное значение
// y - выходное значение
y = y0 + ( ( x - y0 ) / BANDWIDTH_FILTER );
y0 = y;

 

Morroc
Offline
Зарегистрирован: 24.10.2016

Lightning_Eva пишет:
Все 4 расстояния получаются разными. Измерив 4 раза, сложив и разделив на 4 получим точный полный оборот.

И вы будете ждать полный оборот ? Тогда можно просто выкинуть 3 магнита. Какая нужна точность ?

Что у вас за датчики и как вы с них снимаете сигнал ? У меня в 3d принтере столик по высоте позиционирует датчик Холла с точностью лучше, чем 0.1мм. (вот он в готовом виде с обвязкой https://vk.com/doc-154203186_453555505?dl=3fb04644be82a6f7b1 а что там конкретно за датчик могу вечером глянуть, он срабатывает не на поле, а на смену "полярности" если так можно выразиться)

Lightning_Eva
Lightning_Eva аватар
Offline
Зарегистрирован: 04.06.2019

Morroc пишет:

Lightning_Eva пишет:
Все 4 расстояния получаются разными. Измерив 4 раза, сложив и разделив на 4 получим точный полный оборот.

И вы будете ждать полный оборот ? Тогда можно просто выкинуть 3 магнита. Какая нужна точность ?

Что у вас за датчики и как вы с них снимаете сигнал ? У меня в 3d принтере столик по высоте позиционирует датчик Холла с точностью лучше, чем 0.1мм. (вот он в готовом виде с обвязкой https://vk.com/doc-154203186_453555505?dl=3fb04644be82a6f7b1 а что там конкретно за датчик могу вечером глянуть, он срабатывает не на поле, а на смену "полярности" если так можно выразиться)

так и есть, но для начала надо до края поля дойти.

Да, я буду ждать полный оборот.))

Morroc
Offline
Зарегистрирован: 24.10.2016

Lightning_Eva пишет:
так и есть, но для начала надо до края поля дойти.

Тогда откуда разброс если вон у того датчика чуть ли не микронная точность ?

Lightning_Eva пишет:

Да, я буду ждать полный оборот.))

А потом новый полный оборот ? Мне кажется тут одного магнита достаточно будет.

Ну сделайте "в лоб" - массив на 4 элемента, по новому замеру сдвигаем элементы "вниз", "вверх" пишем новое значение, параллельно завести счетчик от 0 до 3 и как 3 - считаем среднее (счетчик обнуляем), если захочется получать данные в 4 раза быстрее (каждый замер) - будет несложно переделать.

Lightning_Eva
Lightning_Eva аватар
Offline
Зарегистрирован: 04.06.2019

Вот еще гугл подсказывает - сделать на двух перываниях - первое, по сигналу датчика, а второе по таймеру. Что, господа, умаете про этот способ?

sadman41
Offline
Зарегистрирован: 19.10.2016

А по таймеру что делать? Микрос и так по таймеру шагает.

Morroc
Offline
Зарегистрирован: 24.10.2016

Lightning_Eva пишет:

Вот еще гугл подсказывает - сделать на двух перываниях - первое, по сигналу датчика, а второе по таймеру. Что, господа, умаете про этот способ?

С какой целью ? Реализовать такое ? ->

Цитата:

Reciprocal frequency counting

The second method is reciprocal counting where instead of counting the input signal you count periods of a master clock and instead of counting the input signal edges you let the input signal start and stop the counter.
 
For example the counter is started at the rising edge of the input signal and stopped at the next rising edge.  Now the counter reading is actually the period of the input signal in multiples of the master clock.
 
Its called reciprocal counting since you have to work out:
 
f= 1.0 / period
 
...to work out the frequency.
 
Может лучше ошибку в самих измерениях как то уменьшить ?
ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

sadman41 пишет:

А по таймеру что делать? Микрос и так по таймеру шагает.

можно сделать 0,1 микросекунды, если минимальные оборОТА позволят )))

кстати пост 2 там и таймер и два прерывания, готовый код

sadman41
Offline
Зарегистрирован: 19.10.2016

ua6em пишет:

можно сделать 0,1 микросекунды, если минимальные оборОТА позволят )))

Да Еве, вроде как и millis() хватало, так что с micros() у неё вообще будет аптечная точность.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

sadman41 пишет:

ua6em пишет:

можно сделать 0,1 микросекунды, если минимальные оборОТА позволят )))

Да Еве, вроде как и millis() хватало, так что с micros() у неё вообще будет аптечная точность.

с микрос будет с дельтой 4 микросекунды

sadman41
Offline
Зарегистрирован: 19.10.2016

ua6em пишет:

с микрос будет с дельтой 4 микросекунды

И с дельтой в 4000 нс.  Ужасно, правда? А если в пикосекундах считать, то вообще абзац.

Это будет точнее в ~250 раз, чем первоначальный вариант. Плохой плюс?

Onkel
Offline
Зарегистрирован: 22.02.2016

А точность всегда нужна? Можно сделать две переменные - одна просто 1/tau, а вторую скорость считать как разницу времени вызова прерывания через 1 (если магнитов 2) или через 3 (если магнитов 4) - будет максимально точное значение.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

sadman41 пишет:

ua6em пишет:

с микрос будет с дельтой 4 микросекунды

И с дельтой в 4000 нс.  Ужасно, правда? А если в пикосекундах считать, то вообще абзац.

Это будет точнее в ~250 раз, чем первоначальный вариант. Плохой плюс?

лучше в фемто )))

nik182
Offline
Зарегистрирован: 04.05.2015

Перечитал топик. Уловил два посыла. Первый максимальная точность скорости вращения. Второй максимально быстро понять что колесо остановилось. Если это так, то задачу надо делить на две части. Для точности определения скорости время в прерывании выдавать для расчета после полного оборота, то есть после каждое четвёртого. В loop следить за временем между каждым прерыванием и если оно превысило порог, объявлять остановку. 

Morroc
Offline
Зарегистрирован: 24.10.2016

Кстати, эта штука будет в насколько грязной среде работать ? А то можно посмотреть в сторону датчика от оптической мыши - очень высокое разрешение и почти мгновенная реакция (по сравнению с 4мя магнитами) на остановку.