Мешает ли вывод шим на импульсный вход?

Тема в разделе "Схемотехника, компоненты, модули", создана пользователем mihaj109, 12 ноя 2020.

  1. mihaj109

    mihaj109 Нерд

    Добрый день! Думал почему у меня не работает код как надо. уже и так пробовал и сяк. суть в чем -
    на вход D2 приходит импульсный сигнал, меандр. это с датчика скорости авто. Ещё есть входное напряжение на А5 (педаль газа). это напряжение управляет ШИМом на выходе D3. А сигнал с D2 должен разрешать или запрещать появление сигнала Шим.
    Проблема в том, что при появлении сингала на Д3, некорректно считает счетчик в прерывании с сигнала Д2.
    Может ли это связанно как то с тем, что они расположены рядом друг с другом? У меня просто доступ к ардуине весьма затруднен, лишний раз лезть очень не хочется.проверять. Никто не сталкивался? Или может в коде что не так..
    Проявляется это так - если педаль газа нажата, то скорость считается криво; если отжать, то показания правильные. Из-за этого неправильно работает другой основной код. Помогите мыслями..
    Код (C++):
    // Проверка скорости, переписал максимум, муспид теперь циклом
    // сделать в муспид 50 вместо 200

    #define PWM 3                //на транзистор, управляющий муфтой
    #define GAZ A0               // сигнал с педали газа 1.48-4.4 В
    float funkcia = 0;           //пепременная функции y=4x-6, идет на pwm
    const float a = 0.3609;       // =255*20/1024/13,8 (это 4)    13.8 напр борт сети.
    const float b = 109.2989;      // =255*(6-0,085)/13,8 (это 6)
    uint32_t paus;
    int gaz;                       // педаль газа 0 - 1023


    void setup(){
      pinMode(PWM, OUTPUT);
      pinMode(GAZ, INPUT);
    Serial.begin(9600);
          /*
          if (millis() - paus >= 200)
          {Serial.println(My_MySpeed);
          paus = millis();}
          */

      attachInterrupt(0, isr, RISING);//прерывание на D2
    }

    void loop(){
      gaz = analogRead(GAZ);
      funkcia = analogRead(GAZ) * a - b;          //При макс на муфте 13.8В функция пересчитана под биты ацп
      if (gaz < 310) funkcia = 0;                 //  если педаль не нажата
      maximum();
      if (gaz > 573) funkcia = 100;       // при педали больше 2.8, напр на муфте 5.2В
      analogWrite (PWM, funkcia);             // иначе от 0 до 5.2 В по формуле y=4x-6

      int My_MySpeed = MySpeed();
      if (millis() - paus >= 300)
          {Serial.println(My_MySpeed);
          paus = millis();}
       
    }

    uint32_t tmr;
    volatile int counter = 0;
    void isr() {
      counter++;  // импульсы считаем тут
    }

    int MySpeed(){
      if(millis() - tmr >= 200){
        long prd = (millis() - tmr) / counter;
        counter = 0;
        tmr = millis();
        return(prd);
      }
      return;
    }

    void maximum(){
      for  ( ; gaz > 798; )                      //педаль больше 3.9В
      {
        analogWrite (PWM, 150);               //на муфту 8В - 150 или 7В - 130, чтоб не буксануть на светофоре
        delay (1500);                             // на 1.5 секунду              вможет сделать 2/2 сек
        for ( int y = 150; y >= 1; y--)            //затем плавно до нуля
        {
          analogWrite (PWM, y);                   // в итоге на муфте; опускаем напр. муфты, чтоб легче ехала, оставляя всех позадли
          delay (10);                             // втечение секунды
        }                                         // Пока летим на всех порах и муфта отключена
      while ( gaz > 470)                     // Ждем пока педаль не отожмется до 2.3 В,
        {                                     // чтобы снова войти в штатный режим
          gaz = analogRead(GAZ);
          delay (20);
        }
      funkcia = analogRead(GAZ) * a - b;
      analogWrite (PWM, funkcia);
      }
    }
     
  2. b707

    b707 Гуру

    Шим тут не причем, проблема в коде.
    У вас при нажатии педали программа фактически зависает.
    Вы посмотрите. что у вас в функции maximum() наворочено.
    Если gaz > 798 - то вы сначала выдерживаете паузу 1.5 секунды, а потом еще пробегаете 150 итераций в цикле for. каждая с задержкой 10 мс (10 *150 = 1500) - еще полторы секунды.
    А если gaz > 470 - то просто сидите в функции до тех пор, пока педаль газа нажата.

    Неудивительно. что у вас при нажатой педали все идет вкось - скорее удивительно. что вообще что-то работает.

    Функцию maximum() надо переписывать без delay() (даже маленьких, 10 мс) и без while() - который на самом деле у вас работает как delay()
    Возьмите за правило, если у вас код управляет каким-то механизмом в реальном времени - ни одной delay() и while() в коде быть не должно.
     
    Daniil нравится это.
  3. parovoZZ

    parovoZZ Гуру

    мама, что это???
     
  4. b707

    b707 Гуру

    что тебя удивляет? - вполне допустимая запись. это аналог
    while(gaz > 798)
     
  5. mihaj109

    mihaj109 Нерд

    Спасибо за ответ. Смотрите. Этот максимум включается редко. Не надо на него смотреть. без него так же работает я пробовал. Значение gaz обычно 300-450.
    т.е. по факту работает
    Код (C++):
    gaz = analogRead(GAZ);
      funkcia = analogRead(GAZ) * a - b;  
      if (gaz < 310) funkcia = 0;
      if (gaz > 573) funkcia = 100;    
      analogWrite (PWM, funkcia);
    Как я понял, возможно неправильно, delay не должна влиять на милис, соответственно и на counter, или я ошибаюсь.
    И программа не зависает - шим отрабатывает очень отзывчиво на педаль газа.
    Я вот еще что вспомнил - при нажатой педали, счетчик насчитывает оч много..
     
    Последнее редактирование: 12 ноя 2020
  6. mihaj109

    mihaj109 Нерд

    там изначально другая запись была, лень было переписать
     
  7. mihaj109

    mihaj109 Нерд

    тут всё как вы и написали ) мне так и нужно. а нет, чуть не так - сначала включение на макс, потом задержка, потом плавное уменьшение, а потом ожидание когда педаль опустится до некоего минимума. Но это не сильно важно, можно и убрать, чтоб delay не смущал. Код отлично работает как и должен, хоть он может и страшненький. я в него хочу добавить скорость, но вот не заладилось.. После добавлния myspeed и сопутствующего, код также работает, но счетчик правильно считает только при отпущеной педали газа. ну либо при отсутствии шим. завтра выясню, кто именно мешает
    Может поможете разобраться? При нажатой педали сиреал показывает, что прд возвращает 0, 1, 2, и иногда правильно значение. всё это в хаотичном порядке. а вот при отжатой всё норм. Я конечно перепишу войд до минимализма для теста, но не думаю, что что-то изменится. Может стоит что-то в myspeed дописать\изменить? Пока на вас вся надежда, т.к. я уже месяц почти каждый вечер редактирую код, результат большой, но цель не достигнута.
     
    Последнее редактирование: 12 ноя 2020
  8. b707

    b707 Гуру

    Код просто никуда не годится...точнее только в помойку.
    А вы это на реальную машину хотите поставить?

    Поймите. для реального мира код с задержками по три секунды - это лучше вообще ничего не писать и лежать на диване с пивом, чем писать такое.
    Впрочем, как хотите. Или переписывайте код нормально, или говорить больше не о чем.
     
  9. b707

    b707 Гуру

    не так оно работает, смотрите свой код внимательнее. Скажу вам больше - первые три строчки из процитированных выше можно смело выкинуть из кода - они ничего не делают. Почему - попробуйте найти сами.

    Еще раз - код написан и оформлен очень плохо, условия без блоков, что когда выполняется - вы явно сами давно запутались Лучше это выкинуть и переписать с читстого листа. тем более что и мелких ошибок тут тоже навлом.
     
  10. mihaj109

    mihaj109 Нерд

    Ничего не пойму, вы толи глумитесь, то ли не хотите обьяснить по человечески. На реальной машине стоит уже месяц и без абсолютных проблем работает начальный код. без скорости. Зачем вы привязались к этим delay? ну удалю я их. Проверю завтра.

    Что здесь непонятного? - прочитали педаль, записали либо 0 либо 100 либо значение 1-99. Да вы наверняка поняли. стеб что ли на до мной не пойму?
    Вот максимально упростил, чтоб было понятно. Ткните меня пожалуйста конкретно в ошибку, что я делаю не так. Почему здесь прд будет некорректный?
    Код (C++):
    #define PWM 3        
    #define GAZ A0          
    float funkcia = 0;      
    int gaz=0;

    void setup(){
      pinMode(PWM, OUTPUT);
      pinMode(GAZ, INPUT);
      attachInterrupt(0, isr, RISING);//прерывание на D2
    }

    void loop(){
      gaz = analogRead(GAZ);
      funkcia =  gaz/4
      analogWrite (PWM, funkcia);
      int My_MySpeed = MySpeed();
    }

    uint32_t tmr;
    volatile int counter = 0;
    void isr() {
      counter++;  // импульсы считаем тут
    }

    int MySpeed(){
      if(millis() - tmr >= 200){
        long prd = (millis() - tmr) / counter;
        counter = 0;
        tmr = millis();
        return(prd);
      }
    }
     
  11. b707

    b707 Гуру

    еще лучше. Этот код ВООБЩЕ НИЧЕГО НЕ ДЕЛАЕТ.
    Газ прочитали, функцию вычислили, скорость измерили. И выкинули все три значения... Нафига считали, спрашивается?

    Ок, делайте как хотите. Странно. что вы пришли спрашивать, когда у вас "все работает"
    Удачи
     
  12. mihaj109

    mihaj109 Нерд

    а то что записали analogWrite (PWM, funkcia); это ничего? или я это один вижу?
    Я понимаю, что вы много знаете, наверняка этим зарабатываете, вам всё очевидно, все ошибки и пр.
    А мне не очевидно, знаю немного, я поэтому и спрашиваю про ошибки. delay? ок, избавился. я позже и до неё доберусь и найду чем заменить. Но это не ключевая ошибка. Давайте вместе разберемся. Я раньше и того не знал, что знаю сейчас, Вы мне где-то подскажите важный момент, и я дальше пойду копаться, разбираться.
     
  13. b707

    b707 Гуру

    Ок, тогда начните с проверки работы кода из сообщения #10 на реальной машине. Что-то мне подсказывает, что с этим кодом никакой зависимости от газа уже не будет.

    Поправьте только несуразности в коде:
    - зачем переменная funkcia описана как float?
    - почему prd - long, а скорость - int ?
    - какая скорость возвращается функцией MySpeed(), если с предыдущего чтения прошло менее 200 мс?
     
  14. mihaj109

    mihaj109 Нерд

    А что с while не так? он тоже как-то тормозит код? про это я не знал
     
  15. mihaj109

    mihaj109 Нерд

    Да почему не будет то??? ну вот почему? у нас газ прочитался, разделился на 4 и записался в шим. Или цикл на этом останавливается?
    Потому что я хз, что будет в результате деления. перестраховался. В данном примере может можно заменить другим типом, но это же не существенно? В моем основном коде важно флоат
    Мне сделали пример как можно обсчитать скорость функцией. Почему int я не знаю, может нужно записать long, чтоб было одинаково? просто там значения -1...200 и я не стал менять
    Последняя записанная prd
    я думал над этим.. изначально был ноль.
    Код (C++):
    int MySpeed(){
      if(millis() - tmr >= 200){
        long prd = (millis() - tmr) / counter;
        counter = 0;
        tmr = millis();
        return(prd);
      }
     return(0);//здесь был 0
    }
    Но тогда вместо реально правильной цифры (имею ввиду 15-200) иногда был бы 0. В смысле так и было. и этот ноль портит выполнение условий.
    я от него избавился и стало как надо, но опять же только при отпущеной педали.
     
  16. parovoZZ

    parovoZZ Гуру

    его компилятор и выкинет. Даже на самой лёгкой оптимизации.


    это тоже тормозит код:
    любая лишняя строчка в коде его будет тормозить.

    А самое интересное, что данная задача на описанной мной ранее операционной системе quarqTS пишется за пару вечеров.
     
  17. b707

    b707 Гуру

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

    mihaj109 - вы очень слабо знаете язык Си, поэтому если я вам указываю на ошибку - в 99% я прав, не стоит спорить
    Переменная prd описана как локальная в процедуре - это значит что при каждом входе в MySpeed() prd создается заново и рассчитывать, что она сохраняет прежнее значение - нельзя. Если вы хотите. чтобы она хранила значение между вызовами - опишите ее как static
     
  18. mihaj109

    mihaj109 Нерд

    Спасибо! Так и сделаю. У меня раньше так и было описано глобально. Мне просто немного помогли и дали такой вариант.
    Я это все поправлю, спасибо. Но я так и не пойму как связан шим и скорость. Смотрите, я в сиреал смотрел "функция и муспид" И вот когда функция становился ноль, муспид показывал идеально, когда были значения в функции, муспид показывал например 0,2,1 или правильное число. при этом, при отжатой педали, газ также опрашивался, и проходил по всем ифам, записывая в функция ноль. Муспид показывал корректно от 200 до 10. как только нажимался газ, сразу же записывалась функция, например 70, и муспид опять показывает ложные значения. Как влияет отсутсвие сигнала в шим на данные муспид? Не может быть такого что шим на д3 как-то меняет милис? Вроде разные таймеры используются.
     
  19. b707

    b707 Гуру

    что делать - я написал в сообщении #13. исправьте ошибки и попробуйте код #10 на реальной машине. Без этого не вижу смысла в досужих рассуждениях...
     
  20. mihaj109

    mihaj109 Нерд

    Короче я говорил что сделаю минималку? Раза три спросил про шим. короче когда даю шим сигнал, счетчик считает неправильно. При нуле всё ок.
    Код (C++):
    // измеряем длину импульсов на 2 пине
    // расчёт каждые 500мс
    int gaz;
    #define PWM 3                //9 на транзистор, управляющий муфтой
    #define GAZ A0               // сигнал с педали газа 1.48-4.4 В


    void setup() {
      Serial.begin(9600);
      attachInterrupt(0, isr, RISING);  // прерывание на D2
    }
    uint32_t tmr;
    volatile int counter = 0;
    void isr() {
      counter++;  // импульсы считаем тут
    }
    void loop() {
      if (millis() - tmr >= 500) {
        long prd = (millis() - tmr) / counter;
        Serial.println(counter);
        counter = 0;
        Serial.println(prd);  // в миллисекундах
        tmr = millis();
      }

      analogWrite (PWM, 60);
    }
    В общем я так понимаю идут помехи, возможно индукция от муфты, возможно от этого транзисторного шима. В общем надо фильтра наверное, я в них не силен. Кто знает, подскажите куда какие кондеры\сопротивления поставить. я так понял нужно обезопасить сигнал ,идущий на Д2. попробовал кокс бросил, не помогло. Схема такая upload_2020-11-14_15-50-9.png
     
    Последнее редактирование: 14 ноя 2020