Тахометр проблема с переменной Float

Leitto

✩✩✩✩✩✩✩
17 Июн 2021
7
0
Добрый день товарищи, делаю простую программу по контролю оборотов двигателя.
В главном цикле (Loop)я считаю текущее количество оборотов ( если прерывание было ) ну и вывожу все в порт +добавил отладочную печать что бы понять что же все таки не так.
Далее я представляю код прерывания (Sens). И это вроде как работает за исключением одного случая о нем дальше и пойдет речь.
Прикладываю в спойлер вывод в порт, прошу обратить внимание 74,85 там переменная rev_time равна 0 как и на 1 строчке и вот мне бы хотелось узнать почему так получается. мне кажется это из за типа float но он в 38 степени и переполняться не должен
Заранее спасибо за помощь

P.s переменные объявлял так

Объявление переменных:
volatile bool speedster=false;
volatile unsigned long lastflash, flash, lastshow;
unsigned int RPM;
Loop:
void loop()
{
  if(speedster)
  {
if (micros() - lastflash > 10000000) { // Проверка на то что двигатель остановился
    RPM = 0;                         

  } else {
    rev_time = (float) flash / 1000000 ;
    if(rev_time!=0) // КОСТЫЛЬ !! ибо не понимаю почему эта переменная иногда равна 0
    {
        RPM = (float) 60 / rev_time;     // Считаем количество оборотов в минуту
      
    
    }
      if ((float) 60 / rev_time>  RPM+500) // уловитель ошибки в некоторых случая работает не правильно но они легко отличимы глазом ( на начальных этапах )
    {
       Serial.print("Ошибка  Расчетная скорость: "+String((float) 60 / rev_time)+" Скорость: "+String(RPM)+" flash: "+String((float)flash)+" rev_time "+String((float)rev_time)+"Микрос:"+String(micros() )+" lastflash:"+String(lastflash )+"\n");

    
    }
              

  }
  speedster=false;
  }
    if (pwngo)
    {
  
       if (millis() - lastshow > 10) {
        Serial.print(" Шим: "+String(dutyA3)+" Скорость: "+String(RPM)+" Время: "+String(micros())+" Время последнего оборота "+String(lastflash)+" flash: "+String(flash)+" rev_time "+String((float)rev_time)+" lastflash:"+String(lastflash )+"\n");
       dutyA3=100;
        lastshow = millis();
       }
    

    }
  lcdsheld();
  }
Sens:
void sens() {
flash = micros() - lastflash;   // вычислить время между двумя оборотами
  lastflash = micros(); // запомнить время последнего оборота
  speedster=true; // флаг который говорит о том что прерывание было
}
Вывод в порт:
15:55:23.782 ->  Шим: 100 Скорость: 0 Время: 3243792 Время последнего оборота 0 flash: 0 rev_time 0.00 lastflash:0
15:55:23.917 ->  Шим: 100 Скорость: 753 Время: 3397808 Время последнего оборота 3346360 flash: 79664 rev_time 0.08 lastflash:3346360
15:55:24.088 ->  Шим: 100 Скорость: 1894 Время: 3548072 Время последнего оборота 3546024 flash: 31672 rev_time 0.03 lastflash:3546024
15:55:24.256 ->  Шим: 100 Скорость: 2414 Время: 3710308 Время последнего оборота 3708316 flash: 24852 rev_time 0.02 lastflash:3708316
15:55:24.426 ->  Шим: 100 Скорость: 2722 Время: 3872540 Время последнего оборота 3869832 flash: 22036 rev_time 0.02 lastflash:3869832
15:55:24.595 ->  Шим: 100 Скорость: 2904 Время: 4034772 Время последнего оборота 4018072 flash: 20656 rev_time 0.02 lastflash:4018072
15:55:24.730 ->  Шим: 100 Скорость: 3049 Время: 4197012 Время последнего оборота 4178656 flash: 19676 rev_time 0.02 lastflash:4178656
15:55:24.899 ->  Шим: 100 Скорость: 3146 Время: 4359276 Время последнего оборота 4352412 flash: 19068 rev_time 0.02 lastflash:4352412
15:55:25.035 ->  Шим: 100 Скорость: 3211 Время: 4532544 Время последнего оборота 4521888 flash: 18680 rev_time 0.02 lastflash:4521888
15:55:25.205 ->  Шим: 100 Скорость: 3255 Время: 4683728 Время последнего оборота 4670148 flash: 18432 rev_time 0.02 lastflash:4670148
15:55:25.374 ->  Шим: 100 Скорость: 3290 Время: 4845992 Время последнего оборота 4835120 flash: 18236 rev_time 0.02 lastflash:4835120
15:55:25.542 ->  Шим: 100 Скорость: 3311 Время: 5008220 Время последнего оборота 4998628 flash: 18120 rev_time 0.02 lastflash:4998628
15:55:25.712 ->  Шим: 100 Скорость: 3329 Время: 5170476 Время последнего оборота 5161152 flash: 18020 rev_time 0.02 lastflash:5161152
15:55:25.883 ->  Шим: 100 Скорость: 3342 Время: 5332708 Время последнего оборота 5323028 flash: 17952 rev_time 0.02 lastflash:5323028
15:55:26.018 ->  Шим: 100 Скорость: 3351 Время: 5494956 Время последнего оборота 5484372 flash: 17900 rev_time 0.02 lastflash:5484372
15:55:26.188 ->  Шим: 100 Скорость: 3360 Время: 5668224 Время последнего оборота 5663156 flash: 17856 rev_time 0.02 lastflash:5663156
15:55:26.357 ->  Шим: 100 Скорость: 3366 Время: 5819412 Время последнего оборота 5805916 flash: 17824 rev_time 0.02 lastflash:5805916
15:55:26.528 ->  Шим: 100 Скорость: 3371 Время: 5981660 Время последнего оборота 5966276 flash: 17796 rev_time 0.02 lastflash:5966276
15:55:26.696 ->  Шим: 100 Скорость: 3373 Время: 6143888 Время последнего оборота 6126508 flash: 17784 rev_time 0.02 lastflash:6126508
15:55:26.832 ->  Шим: 100 Скорость: 3376 Время: 6306148 Время последнего оборота 6304396 flash: 17772 rev_time 0.02 lastflash:6304396
15:55:27.000 ->  Шим: 100 Скорость: 3378 Время: 6468380 Время последнего оборота 6464408 flash: 17760 rev_time 0.02 lastflash:6464408
15:55:27.171 ->  Шим: 100 Скорость: 3379 Время: 6630636 Время последнего оборота 6624300 flash: 17752 rev_time 0.02 lastflash:6624300
15:55:27.307 ->  Шим: 100 Скорость: 3380 Время: 6792868 Время последнего оборота 6784124 flash: 17748 rev_time 0.02 lastflash:6784124
15:55:27.476 ->  Шим: 100 Скорость: 3380 Время: 6955116 Время последнего оборота 6943892 flash: 17748 rev_time 0.02 lastflash:6943892
15:55:27.645 ->  Шим: 100 Скорость: 3383 Время: 7128384 Время последнего оборота 7121336 flash: 17732 rev_time 0.02 lastflash:7121336
15:55:27.816 ->  Шим: 100 Скорость: 3381 Время: 7279568 Время последнего оборота 7263276 flash: 17744 rev_time 0.02 lastflash:7263276
15:55:27.984 ->  Шим: 100 Скорость: 3381 Время: 7441828 Время последнего оборота 7440744 flash: 17744 rev_time 0.02 lastflash:7440744
15:55:28.155 ->  Шим: 100 Скорость: 3381 Время: 7604064 Время последнего оборота 7600492 flash: 17744 rev_time 0.02 lastflash:7600492
15:55:28.322 ->  Шим: 100 Скорость: 3381 Время: 7766316 Время последнего оборота 7760176 flash: 17744 rev_time 0.02 lastflash:7760176
15:55:28.491 ->  Шим: 100 Скорость: 3381 Время: 7928552 Время последнего оборота 7919832 flash: 17744 rev_time 0.02 lastflash:7919832
15:55:28.626 ->  Шим: 100 Скорость: 3382 Время: 8090800 Время последнего оборота 8079460 flash: 17740 rev_time 0.02 lastflash:8079460
15:55:28.761 ->  Шим: 100 Скорость: 3384 Время: 8264064 Время последнего оборота 8256788 flash: 17728 rev_time 0.02 lastflash:8256788
15:55:28.931 ->  Шим: 100 Скорость: 3383 Время: 8415252 Время последнего оборота 8398600 flash: 17732 rev_time 0.02 lastflash:8398600
15:55:29.101 ->  Шим: 100 Скорость: 3385 Время: 8577520 Время последнего оборота 8575836 flash: 17724 rev_time 0.02 lastflash:8575836
15:55:29.271 ->  Шим: 100 Скорость: 3385 Время: 8739752 Время последнего оборота 8735320 flash: 17724 rev_time 0.02 lastflash:8735320
15:55:29.438 ->  Шим: 100 Скорость: 3384 Время: 8901988 Время последнего оборота 8894808 flash: 17728 rev_time 0.02 lastflash:8894808
15:55:29.610 ->  Шим: 100 Скорость: 3383 Время: 9064224 Время последнего оборота 9054320 flash: 17732 rev_time 0.02 lastflash:9054320
15:55:29.780 ->  Шим: 100 Скорость: 3383 Время: 9226456 Время последнего оборота 9213820 flash: 17732 rev_time 0.02 lastflash:9213820
15:55:29.915 ->  Шим: 100 Скорость: 3383 Время: 9388692 Время последнего оборота 9373364 flash: 17732 rev_time 0.02 lastflash:9373364
15:55:30.085 ->  Шим: 100 Скорость: 3384 Время: 9550948 Время последнего оборота 9550600 flash: 17728 rev_time 0.02 lastflash:9532872
15:55:30.255 ->  Шим: 100 Скорость: 3386 Время: 9724116 Время последнего оборота 9710048 flash: 17716 rev_time 0.02 lastflash:9710048
15:55:30.393 ->  Шим: 100 Скорость: 3386 Время: 9875428 Время последнего оборота 9869448 flash: 17716 rev_time 0.02 lastflash:9869448
15:55:30.565 ->  Шим: 100 Скорость: 3388 Время: 10037716 Время последнего оборота 10028788 flash: 17708 rev_time 0.02 lastflash:10028788
15:55:30.735 ->  Шим: 100 Скорость: 3389 Время: 10203052 Время последнего оборота 10188072 flash: 17704 rev_time 0.02 lastflash:10188072
15:55:30.905 ->  Шим: 100 Скорость: 3391 Время: 10368436 Время последнего оборота 10365016 flash: 17692 rev_time 0.02 lastflash:10365016
15:55:31.077 ->  Шим: 100 Скорость: 3391 Время: 10533796 Время последнего оборота 10524248 flash: 17692 rev_time 0.02 lastflash:10524248
15:55:31.248 ->  Шим: 100 Скорость: 3392 Время: 10699136 Время последнего оборота 10683476 flash: 17688 rev_time 0.02 lastflash:10683476
15:55:31.418 ->  Шим: 100 Скорость: 3393 Время: 10864508 Время последнего оборота 10860380 flash: 17680 rev_time 0.02 lastflash:10860380
15:55:31.587 ->  Шим: 100 Скорость: 3394 Время: 11029884 Время последнего оборота 11019564 flash: 17676 rev_time 0.02 lastflash:11019564
15:55:31.724 ->  Шим: 100 Скорость: 3395 Время: 11195212 Время последнего оборота 11178712 flash: 17672 rev_time 0.02 lastflash:11178712
15:55:31.894 ->  Шим: 100 Скорость: 3395 Время: 11360608 Время последнего оборота 11355528 flash: 17668 rev_time 0.02 lastflash:11355528
15:55:32.066 ->  Шим: 100 Скорость: 3395 Время: 11525948 Время последнего оборота 11514672 flash: 17672 rev_time 0.02 lastflash:11514672
15:55:32.234 ->  Шим: 100 Скорость: 3395 Время: 11691300 Время последнего оборота 11673808 flash: 17668 rev_time 0.02 lastflash:11673808
15:55:32.405 ->  Шим: 100 Скорость: 3395 Время: 11856676 Время последнего оборота 11850608 flash: 17672 rev_time 0.02 lastflash:11850608
15:55:32.574 ->  Шим: 100 Скорость: 3395 Время: 12022020 Время последнего оборота 12009708 flash: 17668 rev_time 0.02 lastflash:12009708
15:55:32.710 ->  Шим: 100 Скорость: 3395 Время: 12187396 Время последнего оборота 12186448 flash: 17668 rev_time 0.02 lastflash:12186448
15:55:32.878 ->  Шим: 100 Скорость: 3395 Время: 12352768 Время последнего оборота 12345488 flash: 17668 rev_time 0.02 lastflash:12345488
15:55:33.049 ->  Шим: 100 Скорость: 3395 Время: 12518100 Время последнего оборота 12504524 flash: 17668 rev_time 0.02 lastflash:12504524
15:55:33.219 ->  Шим: 100 Скорость: 3395 Время: 12683488 Время последнего оборота 12681268 flash: 17668 rev_time 0.02 lastflash:12681268
15:55:33.357 ->  Шим: 100 Скорость: 3394 Время: 12848832 Время последнего оборота 12840400 flash: 17676 rev_time 0.02 lastflash:12840400
15:55:33.526 ->  Шим: 100 Скорость: 3395 Время: 13014180 Время последнего оборота 12999504 flash: 17668 rev_time 0.02 lastflash:12999504
15:55:33.695 ->  Шим: 100 Скорость: 3395 Время: 13190488 Время последнего оборота 13176260 flash: 17668 rev_time 0.02 lastflash:13176260
15:55:33.867 ->  Шим: 100 Скорость: 3395 Время: 13344928 Время последнего оборота 13335324 flash: 17668 rev_time 0.02 lastflash:13335324
15:55:34.036 ->  Шим: 100 Скорость: 3395 Время: 13521316 Время последнего оборота 13512032 flash: 17672 rev_time 0.02 lastflash:13512032
15:55:34.206 ->  Шим: 100 Скорость: 3394 Время: 13675644 Время последнего оборота 13671072 flash: 17676 rev_time 0.02 lastflash:13671072
15:55:34.374 ->  Шим: 100 Скорость: 3394 Время: 13852056 Время последнего оборота 13847796 flash: 17676 rev_time 0.02 lastflash:13847796
15:55:34.546 ->  Шим: 100 Скорость: 3394 Время: 14006336 Время последнего оборота 13989152 flash: 17676 rev_time 0.02 lastflash:13989152
15:55:34.717 ->  Шим: 100 Скорость: 3395 Время: 14171716 Время последнего оборота 14165856 flash: 17672 rev_time 0.02 lastflash:14165856
15:55:34.851 ->  Шим: 100 Скорость: 3393 Время: 14337060 Время последнего оборота 14324900 flash: 17680 rev_time 0.02 lastflash:14324900
15:55:35.022 ->  Шим: 100 Скорость: 3393 Время: 14513376 Время последнего оборота 14501640 flash: 17672 rev_time 0.02 lastflash:14501640
15:55:35.194 ->  Шим: 100 Скорость: 3395 Время: 14667808 Время последнего оборота 14660728 flash: 17668 rev_time 0.02 lastflash:14660728
15:55:35.364 ->  Шим: 100 Скорость: 3398 Время: 14844220 Время последнего оборота 14837428 flash: 17656 rev_time 0.02 lastflash:14837428
15:55:35.535 ->  Шим: 100 Скорость: 3398 Время: 14998520 Время последнего оборота 14996436 flash: 17656 rev_time 0.02 lastflash:14996436
15:55:35.705 -> Ошибка  Расчетная скорость: 375000.00 Скорость: 47320 flash: 160.00 rev_time 0.00Микрос:15174504 lastflash:15173100
15:55:35.875 ->  Шим: 100 Скорость: 47320 Время: 15311932 Время последнего оборота 15296776 flash: 17656 rev_time 0.00 lastflash:15296776
15:55:36.044 ->  Шим: 100 Скорость: 3399 Время: 15489384 Время последнего оборота 15473404 flash: 17648 rev_time 0.02 lastflash:15473404
15:55:36.212 ->  Шим: 100 Скорость: 3398 Время: 15654744 Время последнего оборота 15650032 flash: 17656 rev_time 0.02 lastflash:15650032
15:55:36.349 ->  Шим: 100 Скорость: 3398 Время: 15820116 Время последнего оборота 15809004 flash: 17656 rev_time 0.02 lastflash:15809004
15:55:36.519 ->  Шим: 100 Скорость: 3398 Время: 15985464 Время последнего оборота 15967972 flash: 17656 rev_time 0.02 lastflash:15967972
15:55:36.691 ->  Шим: 100 Скорость: 3399 Время: 16150836 Время последнего оборота 16144568 flash: 17652 rev_time 0.02 lastflash:16144568
15:55:36.860 ->  Шим: 100 Скорость: 3398 Время: 16316184 Время последнего оборота 16303468 flash: 17656 rev_time 0.02 lastflash:16303468
15:55:37.029 ->  Шим: 100 Скорость: 3399 Время: 16481556 Время последнего оборота 16480020 flash: 17652 rev_time 0.02 lastflash:16480020
15:55:37.165 ->  Шим: 100 Скорость: 3399 Время: 16646912 Время последнего оборота 16638916 flash: 17648 rev_time 0.02 lastflash:16638916
15:55:37.336 ->  Шим: 100 Скорость: 3400 Время: 16812260 Время последнего оборота 16797784 flash: 17644 rev_time 0.02 lastflash:16797784
15:55:37.507 -> Ошибка  Расчетная скорость: 428571.41 Скорость: 35355 flash: 140.00 rev_time 0.00Микрос:16977180 lastflash:16974284
15:55:37.678 ->  Шим: 100 Скорость: 35355 Время: 17125688 Время последнего оборота 17115464 flash: 17640 rev_time 0.00 lastflash:17115464
15:55:37.812 ->  Шим: 100 Скорость: 3398 Время: 17314220 Время последнего оборота 17309600 flash: 17656 rev_time 0.02 lastflash:17309600
15:55:37.982 ->  Шим: 100 Скорость: 3399 Время: 17468536 Время последнего оборота 17468236 flash: 17648 rev_time 0.02 lastflash:17450756
 
Изменено:

bort707

★★★★★★✩
21 Сен 2020
3,066
914
неудачно написали математику, деление слишком маленьких или слишком больших чисел дает очень большую погрешность.
Чтобы устранить проблему, просто обьедините формулы в строчках 9 и 12 в одну - будет работать надежнее.
Вместо
C++:
 rev_time = (float) flash / 1000000 ;
 RPM = (float) 60 / rev_time;     // Считаем количество оборотов в минуту
запишите так
C++:
 RPM = 60* 1000000 / flash;     // Считаем количество оборотов в минуту
в этой формуле вам даже тип float станет не нужен
 

Leitto

✩✩✩✩✩✩✩
17 Июн 2021
7
0
@bort707,
Спасибо что подсказали, но увы проблема не ушла. Прикладываю измененный код . Как я понимаю ошибка лежит на много глубже и теперь ее можно найти по переменной flash она становиться маленькой.
@rGlory,
Для начала отвечу на вопрос что за формула такая.
Как видно из кода это условие выполняется перед тем как рассчитать новое число оборотов. В среднем число оборотов двигателя на режиме 3358 оборотов в минуту. Что бы не придумывать какой то хитрый отладчик пришла идея что бы отлавливать аномальное значение оборотов и выводить что в этот момент произошло как видно 357142 во много раз больше среднего числа оборотов и скорей всего число 500 я взял слишком маленькое что и приводит к тому что иногда на этапе старта двигателя этот уловитель работает лишние разы к примеру стартовая скорость 300 оборотов а потом 3000 разница больше чем в 500 и уловитель срабатывает.
Считаю что ответил на ваш вопрос. Спасибо что уделили время и пытаетесь помочь.

Loop:
void loop()
{
      
  if(speedster)
  {
if (micros() - lastflash > 10000000) { // Проверка на то что двигатель остановился
    RPM = 0;                           
 
  } else {
  
        if (60* 1000000 / flash>  RPM+500) // уловитель ошибки в некоторых случая работает не правильно но они легко отличимы глазом ( на начальных этапах )
    {
       Serial.print("Ошибка  Расчетная скорость: "+String(60* 1000000 / flash)+" Скорость: "+String(RPM)+" flash: "+String(flash)+" Микрос:"+String(micros() )+" lastflash:"+String(lastflash )+"\n");
 
      
    }
     RPM = 60* 1000000 / flash;
 
  }
  speedster=false;
  }

    if (pwngo)
    {
  
       if (millis() - lastshow > 10) {
        Serial.print(" Шим: "+String(dutyA3)+" Скорость: "+String(RPM)+" Время последнего оборота: "+String(lastflash)+" Время  оборота "+String(flash)+"\n");
       dutyA3=100;
        lastshow = millis();
       }
      
 
    }
  lcdsheld();
  }
Вывод в порт

Вывод в порт:
10:09:41.348 ->  Шим: 100 Скорость: 3351 Время последнего оборота: 18297152 Время  оборота 17904
10:09:41.484 ->  Шим: 100 Скорость: 3353 Время последнего оборота: 18440296 Время  оборота 17892
10:09:41.621 ->  Шим: 100 Скорость: 3355 Время последнего оборота: 18583404 Время  оборота 17880
10:09:41.756 ->  Шим: 100 Скорость: 3357 Время последнего оборота: 18708588 Время  оборота 17872
10:09:41.894 ->  Шим: 100 Скорость: 3356 Время последнего оборота: 18833760 Время  оборота 17876
10:09:42.028 ->  Шим: 100 Скорость: 3357 Время последнего оборота: 18958852 Время  оборота 17872
10:09:42.162 ->  Шим: 100 Скорость: 3358 Время последнего оборота: 19083960 Время  оборота 17864
10:09:42.297 ->  Шим: 100 Скорость: 3360 Время последнего оборота: 19226932 Время  оборота 17856
10:09:42.398 ->  Шим: 100 Скорость: 3355 Время последнего оборота: 19352068 Время  оборота 17880
10:09:42.535 ->  Шим: 100 Скорость: 3358 Время последнего оборота: 19477144 Время  оборота 17864
10:09:42.670 ->  Шим: 100 Скорость: 3358 Время последнего оборота: 19620096 Время  оборота 17864
10:09:42.804 ->  Шим: 100 Скорость: 3360 Время последнего оборота: 19745184 Время  оборота 17856
10:09:42.940 ->  Шим: 100 Скорость: 3357 Время последнего оборота: 19870260 Время  оборота 17872
10:09:43.041 ->  Шим: 100 Скорость: 3359 Время последнего оборота: 20013196 Время  оборота 17860
10:09:43.178 ->  Шим: 100 Скорость: 3359 Время последнего оборота: 20138260 Время  оборота 17860
10:09:43.314 ->  Шим: 100 Скорость: 3360 Время последнего оборота: 20263324 Время  оборота 17852
10:09:43.453 ->  Шим: 100 Скорость: 3358 Время последнего оборота: 20406212 Время  оборота 17864
10:09:43.587 ->  Шим: 100 Скорость: 3360 Время последнего оборота: 20531204 Время  оборота 17852
10:09:43.722 -> Ошибка  Расчетная скорость: 357142 Скорость: 3360 flash: 168Микрос:20670944 lastflash:20656236
10:09:43.857 ->  Шим: 100 Скорость: 3359 Время последнего оборота: 20781284 Время  оборота 17860
10:09:43.991 ->  Шим: 100 Скорость: 3357 Время последнего оборота: 20924192 Время  оборота 17868
10:09:44.126 ->  Шим: 100 Скорость: 3360 Время последнего оборота: 21067048 Время  оборота 17856
10:09:44.260 ->  Шим: 100 Скорость: 3360 Время последнего оборота: 21192040 Время  оборота 17852
10:09:44.362 ->  Шим: 100 Скорость: 3363 Время последнего оборота: 21317024 Время  оборота 17840
10:09:44.500 ->  Шим: 100 Скорость: 3360 Время последнего оборота: 21459836 Время  оборота 17856
10:09:44.638 ->  Шим: 100 Скорость: 3362 Время последнего оборота: 21584768 Время  оборота 17844
10:09:44.774 ->  Шим: 100 Скорость: 3363 Время последнего оборота: 21709708 Время  оборота 17840
10:09:44.910 ->  Шим: 100 Скорость: 3364 Время последнего оборота: 21852468 Время  оборота 17832
10:09:45.047 ->  Шим: 100 Скорость: 3361 Время последнего оборота: 21977388 Время  оборота 17848
10:09:45.182 ->  Шим: 100 Скорость: 3363 Время последнего оборота: 22102256 Время  оборота 17836
10:09:45.317 ->  Шим: 100 Скорость: 3363 Время последнего оборота: 22245000 Время  оборота 17840
10:09:45.453 ->  Шим: 100 Скорость: 3363 Время последнего оборота: 22387740 Время  оборота 17840
 

bort707

★★★★★★✩
21 Сен 2020
3,066
914
во-первых, на всякий случай строчку
C++:
60* 1000000 / flash
исправьте везде на
C++:
60ul * 1000000 / flash
хотя это не должно влиять

А далее - давайте рассуждать. Смотрите - у вас скорость завышается в 100 раз тогда, когда flash оказывается в 100 раз меньше нормы. Это означает, что формула работает правильно, ошибка не в ней. Похоже причина в том что иногда прерывание реально возникает два раза подряд.

Что там у вас за датчик. дребезга на нем не может быть?
 

Leitto

✩✩✩✩✩✩✩
17 Июн 2021
7
0
@bort707,
Исправил, датчик оптический щелевой
на осциллографе не вижу двойного срабатывания. конечно можно фильтровать такое значение но хочется разобраться все таки в причине
 

bort707

★★★★★★✩
21 Сен 2020
3,066
914
В любом случае ищите причину ошибок где в прерывании - или в коде, или в железе.
И да, фильтровать проще всего:)
 

Leitto

✩✩✩✩✩✩✩
17 Июн 2021
7
0
@bort707,
Я пошел уже даже на такой ход

Прерывания:
void sens() {
 
  detachInterrupt(0);
    attachInterrupt(0, sensgo,RISING);
  //attachInterrupt(0, sensgo, LOW );
  speedster=false;
    flash = micros() - lastflash;  // вычислить время между двумя оборотами
  lastflash = micros(); // запомнить время последнего оборота
    if (flash<5000) // уловитель ошибки в некоторых случая работает не правильно но они легко отличимы глазом ( на начальных этапах )
    {
      report=true;
      lastflashBufer=micros();
      flashBufer=lastflash;
      lastshowBufer=flash;
    }
  speedster=true; //
    attachInterrupt(0, sensgo,RISING);
}
void sensgo()
{
  detachInterrupt(0);
    attachInterrupt(0, sens, FALLING );
}
Вывод
Форматирование (BB-код):
12:01:12.282 ->  Шим: 100 Скорость: 2026 Время последнего оборота: 2578556 Время  оборота 29604
12:01:12.421 ->  Шим: 100 Скорость: 2473 Время последнего оборота: 2735072 Время  оборота 24256
12:01:12.554 ->  Шим: 100 Скорость: 2689 Время последнего оборота: 2850212 Время  оборота 22312
12:01:12.691 ->  Шим: 100 Скорость: 2865 Время последнего оборота: 2978856 Время  оборота 20940
12:01:12.831 ->  Шим: 100 Скорость: 3009 Время последнего оборота: 3121156 Время  оборота 19940
12:01:12.968 ->  Шим: 100 Скорость: 3095 Время последнего оборота: 3238808 Время  оборота 19384
12:01:13.070 ->  Шим: 100 Скорость: 3166 Время последнего оборота: 3372624 Время  оборота 18948
12:01:13.204 ->  Шим: 100 Скорость: 3220 Время последнего оборота: 3504096 Время  оборота 18632
12:01:13.338 ->  Шим: 100 Скорость: 3254 Время последнего оборота: 3633768 Время  оборота 18436
12:01:13.498 ->  Шим: 100 Скорость: 3282 Время последнего оборота: 3762272 Время  оборота 18280
12:01:13.601 ->  Шим: 100 Скорость: 3301 Время последнего оборота: 3889816 Время  оборота 18176
12:01:13.700 ->  Шим: 100 Скорость: 3320 Время последнего оборота: 4034772 Время  оборота 18072
12:01:13.837 -> Ошибка в перывании micros на момент ошибки: 4070892 Lastflash: 4070888 flash: 176 Микрос:340909 lastflash:4143040

Loop:
void loop()
{
      if(report)
      {
        
    
        Serial.print("Ошибка в перывании micros на момент ошибки: "+String(lastflashBufer)+" Lastflash: "+String(flashBufer)+" flash: "+String(lastshowBufer)+" Микрос:"+String( 60ul * 1000000  / lastshowBufer )+" lastflash:"+String(lastflash )+"\n");
         pwngo=false;
 dutyA3=0;
  report=false;
      }
  if(speedster)
  {
if (micros() - lastflash > 10000000) { // Проверка на то что двигатель остановился
    RPM = 0;                           
 
  } else {
  
        if (60ul * 1000000 / flash>  RPM+500) // уловитель ошибки в некоторых случая работает не правильно но они легко отличимы глазом ( на начальных этапах )
    {
       Serial.print("Ошибка  Расчетная скорость: "+String(60ul * 1000000 / flash)+" Скорость: "+String(RPM)+" flash: "+String(flash)+" Микрос:"+String(micros() )+" lastflash:"+String(lastflash )+"\n");
 
      
    }
     RPM =60ul * 1000000 / flash;
 
  }
  speedster=false;
  }

    if (pwngo)
    {
  
       if (millis() - lastshow > 10) {
        Serial.print(" Шим: "+String(dutyA3)+" Скорость: "+String(RPM)+" Время последнего оборота: "+String(lastflash)+" Время  оборота "+String(flash)+"\n");
       dutyA3=100;
        lastshow = millis();
       }
      
 
    }
  //lcdsheld();
  }
 

poty

★★★★★★✩
19 Фев 2020
3,237
942
Не очень знаю библиотеку Serial: она использует прерывания? Если да, то возможна ситуация, когда прерывания внутри обработки вывода Serial блокируются на время, близкое к измеряемому периоду. Попробуйте закомментировать все Serial, кроме тех, что сообщают об ошибке.
Меня также смущает вывод в первом листинге:
15:55:25.374 -> Шим: 100 Скорость: 3290 Время: 4845992 Время последнего оборота 4835120 flash: 18236 rev_time 0.02 lastflash:4835120
15:55:25.542 -> Шим: 100 Скорость: 3311 Время: 5008220 Время последнего оборота 4998628 flash: 18120 rev_time 0.02 lastflash:4998628
15:55:25.712 -> Шим: 100 Скорость: 3329 Время: 5170476 Время последнего оборота 5161152 flash: 18020 rev_time 0.02 lastflash:5161152
Выводится время в micros на момент выдачи Serial.print. Кроме того, слева выводится время с максимальным разрешением 1мс (в скобках дана задержка между временем получения отсчёта lastflash и временем вывода String(micros()), в микросекундах):
15:55:25.374 ... Время: 4845992 (10872)
15:55:25.542 ... Время: 5008220 ( 9592)
15:55:25.712 ... Время: 5170476 ( 9324)
Если вычислить интервалы, то:
15:55:25.542 - 15:55:25.374 = 168мс, 5008220 - 4845992 = 162мс
15:55:25.712 - 15:55:25.542 = 170мс, 5170476 - 5008220 = 162мс
Девиация задержки невелика, не более 1,5мс, а разница в отображаемом и вычисленном времени - целых 6мс.
 

Leitto

✩✩✩✩✩✩✩
17 Июн 2021
7
0
@poty,
Изначально выводов в порт вообще не было их я добавил после того как понял что считается какая то хрень
 

poty

★★★★★★✩
19 Фев 2020
3,237
942
Ну, это было "в другой жизни" и, возможно, была ошибка в коде. Надо попробовать сейчас.
 

rGlory

★✩✩✩✩✩✩
11 Май 2021
200
20
Считаю что ответил на ваш вопрос. Спасибо что уделили время и пытаетесь помочь.
Да нет, несовсем. Откуда это взялось вообще.

Я вижу две проблемы.
  1. прерывание делает слишком много работы. Там ведь просто можно запомнить время в микросекундах последнего прерывания, дельту можно и в основном цикле посчитать.
  2. переменная типа unsigned long в регистр не помещается, то, что вы ее объявили volatile этого факта не меняет. Что это значит? А то, что вы ее можете прочитать "по частям". Так мало того, вы еще и читаете ее несколько раз. По идее в основном цикле надо что-то типа:
C++:
noInterrupts();
unsigned long lastFlashCopy = lastFlash;
interrupts();
И дальше в основном цикле использовать только копию.

Вообще вычисление RPM таким методом имхо чревато неточностями и проблемами. Я бы в прерывании увеличивал счетчик, а далее его забирал и сбрасывал в основном коде через определенный промежуток, а полученное значение использовал для подсчета RPM. Тогда и точность повысится, и даже пропущенное прерывание особо не повлияет. Да и если использовать соотвествующий период счетчик можно сделать двухбайтным или даже вообще однобайтным
 
  • Лойс +1
Реакции: bort707

Leitto

✩✩✩✩✩✩✩
17 Июн 2021
7
0
@rGlory, @poty, @bort707,

Как оказалось прерывания вызываются как им угодно. Зеленое это показания щелевого датчика ( светодиод + фототранзистор )
желтое это код прерывания которое вызывается с помощью attachInterrupt(0, sens, FALLING);
Вопрос как такое вообще возможно ? и в какую сторону копать ?



C++:
void sens()
{

   if (true) {
    changer=false;
      //detachInterrupt(0);
  flash = micros() - lastflash;
//if(flash>10000)
if(true)
{
  // вычислить время между двумя оборотами
  lastflash = micros();
 
   digitalWrite(A1,HIGH);
    digitalWrite(A1,LOW);
}


       }

 
}
ysHTp02Efjk[1].jpg
Схем111а.PNG
 

bort707

★★★★★★✩
21 Сен 2020
3,066
914
Судя по картинке, не так и плохо все, ни один из импульсов с датчика не пропущен.
А наводки убирать надо.
 

poty

★★★★★★✩
19 Фев 2020
3,237
942
@Leitto, приведённая принципиальная схема непонятна. Что с чем соединено?
 

Геннадий П

★★★★★★✩
14 Апр 2021
1,974
633
45
@Leitto, Не правильно оптопара подключена.

Примерно так должно быть(либо попробовать в МК сделать подтяжку входа к питанию):
1624457990079.png
 

Leitto

✩✩✩✩✩✩✩
17 Июн 2021
7
0
@Геннадий П, @poty, @bort707, @Старик Похабыч,
Большое спасибо всем за помощь, проблема оказалась в следующем мой шим был программный и в какой то момент времени внешнее прерывание которое является по приоритету выше нежели прерывание по таймеру и получалось что шим в какой то момент времени не сбрасывался в 0 а оставался в логической единице и на двигатель шла постоянка и он ускоряется а иногда шим не переключился на лог 1 и двигатель тормозил.