Страница 1 из 3 123 ПоследняяПоследняя
Показано с 1 по 10 из 29
  1. #1
    Продвинутый
    Регистрация
    03.06.2008
    Возраст
    49
    Сообщений
    320
    Вес репутации
    333

    По умолчанию Ардуино-спидометр.

    Как снять показания спидометра ардуиной?
    Подключился я к штатному спидометру и стал по всякому получать с него данные:
    Если измерять длину импульса или время между импульсами, то получается ужасная нелинейность, тем более инвертированая!
    Если измерять количество импульсов, то тоже не очень хорошо: если мерить импульсы за 100 миллисекунд ( не говоря уже о меньшем времени ), получается очень маленькое число, то есть например, при скорости 30 кмч. показывает 4, если делать через множитель то фигня получается! А если мерить скажем за одну секунду, то время отображения получается слишком большим, едешь 40 кмч. нажал на газ, а скорость по прежнему 40 и только чуть позже показывает реальную скорость!
    Уф, понаписал .....извиняюсь за многословие)))))
    Может кто подскажет как сделать лучше?

  2. #2
    Местный
    Регистрация
    10.11.2010
    Сообщений
    144
    Вес репутации
    201

    По умолчанию Re: Ардуино-спидометр.

    Цитата Сообщение от mebitek Посмотреть сообщение
    ... то получается ужасная нелинейность...
    Так мир имеет не очень много линейности Чем гипербола хуже прямой? Автомобиль - жутко инертное тело и скорость меняется очень плавно. Там в районе 6 импульсов на оборот колеса.
    Последний раз редактировалось edw123; 21.10.2011 в 15:15.

  3. #3
    Новичок
    Регистрация
    20.06.2011
    Сообщений
    9
    Вес репутации
    167

    По умолчанию Re: Ардуино-спидометр.

    Я делал на Arduino блок управления круиз-контролем.
    Датчик скорости у меня стоит 6-ти импульсный, т.е. когда я проезжаю 1 метр, он производит 6-ть импульсов.
    Я делал замер подряд длительности единиц и нулей при одном обороте датчика - получаем время, за которое мы проехали 1 метр (далее для перевода в км/ч - простая математика).
    Для исключения влияния ошибок, я делал замер скорости за 3 оборота датчика подряд, далее делил на 3.
    Как-то так...

  4. #4
    Продвинутый
    Регистрация
    03.06.2008
    Возраст
    49
    Сообщений
    320
    Вес репутации
    333

    По умолчанию Re: Ардуино-спидометр.

    Спасибо!!!
    А можешь кусок кода выложить?

  5. #5
    Новичок
    Регистрация
    20.06.2011
    Сообщений
    9
    Вес репутации
    167

    По умолчанию Re: Ардуино-спидометр.

    PHP код:
    // Вспомогательная процедура - Считывание с датчика текущей скорости
    void GetSpeed() {  
    unsigned long DurImpSp0;     // Длительность отрицательного импульса
    unsigned long DurImpSp1;     // Длительность положительного импульса
    unsigned long DurImpSpAll;    // Длительность импульсов за 1 оборот
      
      
    for (int i 06i++) {              // На сколько импульсов датчик скорости
        
    DurImpSp1 pulseIn(BtnSpeedHIGH20000);  // Считывание длительности положительного импульса
        
    DurImpSp0 pulseIn(BtnSpeedLOW20000);   // Считывание длительности отрицательного импульса    
        
    DurImpSpAll DurImpSpAll DurImpSp1 DurImpSp0// Складываем
      
    }  
      
      
    DurImpSpAll = (3600000 DurImpSpAll); // Перевод в км/ч
      
    DurImpSpAll DurImpSpAll DurImpSpAll 90 1000;  // Учитываем процент погрешности (определяется экспериментально)
     
      
    if (DurImpSpAll <= 0) { // Если скорость менее 0 - значит 0
        
    ValSpCurr 0;
      }else{
        
    ValSpCurr DurImpSpAll;
      }

      
    Serial.print("Speed = ");
      
    Serial.println(ValSpCurr);  
      


    прошу ногами не пинать, конструктивная критика кода приветствуется

    ValSpCurr - глобальная переменная int
    Последний раз редактировалось XsanderS; 25.10.2011 в 05:18.

  6. #6
    Местный
    Регистрация
    10.11.2010
    Сообщений
    144
    Вес репутации
    201

    По умолчанию Re: Ардуино-спидометр.

    Цитата Сообщение от BasiC Посмотреть сообщение
    [HTML]// Вспомогательная процедура - Считывание с датчика текущей скорости...
    1. Если экономить (для других подпрограмм) память, то переменную можно попробовать в 1 байт сделать: 255км/ч с точностью 1км/ч - вполне даже для Феррари достаточно.
    2. pulseIn(pin, value, timeout= 20000 - по-моему это секунды и их надо 1 сделать. Что-то типа DurImpSp1 = byte(pulseIn(BtnSpeed, HIGH, 1));
    2. С датчика идёт 50% меандр. Считывать обе половинки по отдельности, мне кажется, излишне.
    3. По-моему можно всё и в одном импульсе сделать - не делать 6 раз. Насколько мне известно, там используются интегральный микрухи - усилители-дескриминаторы сигнала с датчика Холла со встроенным подавлением "дребезга". Поэтому можно и не усреднять.
    Будет не 360000/..., а 30000/... ну или точнее сделать по опыту. Коэффициент - это правильно, учитывает разного диаметра резину.
    Последний раз редактировалось edw123; 24.10.2011 в 22:06.

  7. #7
    Новичок
    Регистрация
    20.06.2011
    Сообщений
    9
    Вес репутации
    167

    По умолчанию Re: Ардуино-спидометр.

    Цитата Сообщение от edw123 Посмотреть сообщение
    1. Если экономить (для других подпрограмм) память, то переменную можно попробовать в 1 байт сделать: 255км/ч с точностью 1км/ч - вполне даже для Феррари достаточно.
    2. pulseIn(pin, value, timeout= 20000 - по-моему это секунды и их надо 1 сделать. Что-то типа DurImpSp1 = byte(pulseIn(BtnSpeed, HIGH, 1));
    2. С датчика идёт 50% меандр. Считывать обе половинки по отдельности, мне кажется, излишне.
    3. По-моему можно всё и в одном импульсе сделать - не делать 6 раз. Насколько мне известно, там используются интегральный микрухи - усилители-дескриминаторы сигнала с датчика Холла со встроенным подавлением "дребезга". Поэтому можно и не усреднять.
    Будет не 360000/..., а 30000/... ну или точнее сделать по опыту. Коэффициент - это правильно, учитывает разного диаметра резину.
    п.1 - согласен!
    п.2 - 20000 это микросекунды ожидания завершения импульса. http://arduino.cc/en/Reference/PulseIn Можно поставить и 1 секунду, но если не будет импульсов, функция подвесит подпрограмму на эту 1 секунду.
    п.3 - стОит попробовать. Я исходил из того, что чем больше замеров, тем выше точность

    Насчёт коэффициента 3600000
    Находится следующим образом. После всех замеров, мы получаем время в микросекундах, в течение которого совершается один оборот датчика (машина проезжает 1 метр).
    Т.е. полученное значение выражен в микросекундах/метр. Чтобы перевести это значение в км/час, необходимо:
    - перевернуть дробь
    - умножить значение на 1000 (перевод м в км)
    - поделить значение на 3600000000 (перевод микросекунд в часы)
    - сокращаем 3600000000 на 1000
    в итоге нехитрых математических операций получаем именно DurImpSpAll = (3600000 / DurImpSpAll)

  8. #8
    Продвинутый
    Регистрация
    03.06.2008
    Возраст
    49
    Сообщений
    320
    Вес репутации
    333

    По умолчанию Re: Ардуино-спидометр.

    Спасибо что написал!

  9. #9
    Местный
    Регистрация
    10.11.2010
    Сообщений
    144
    Вес репутации
    201

    По умолчанию Re: Ардуино-спидометр.

    Цитата Сообщение от BasiC Посмотреть сообщение
    ...чем больше замеров, тем выше точность...
    Это не однозначно Чем больше замеров, тем больше усреднение, а значит точность падает, а не растёт. Но, понятное дело, если скорость изменения скорости заметно больше периода импульса, тогда хуже не станет. В случае спидометра автомобиля, думаю, так и есть. Даже я бы ограничил частоту вывода значения: что-нибудь 1раз/0,5сек - чтобы не моргали цифры на "спидометре". Автомобильный датчик сам по себе уже достаточно помехозащищён и если ардуино будет делать что-то ещё, кроме как считывать только сигнал спидометра, то можно освободить много времени для выполнения других, более полезных опреаций. Хотя бы кнопки считывать, или другие датчики. Ну это дело вкуса. ПРосто, как мне кажется, избыточный код.
    Секунды - это я согласен, невнимательно смотрел - точно микросекунды.

    Вообще получается, что pulseIn удобная функция, но не "фоновая". На прерываниях "по-правильнее" должно быть - опять-таки если ардуино что-то ещё будет делать.

  10. #10
    Продвинутый
    Регистрация
    03.06.2008
    Возраст
    49
    Сообщений
    320
    Вес репутации
    333

    По умолчанию Re: Ардуино-спидометр.

    вобщем сделал вот так:

    PHP код:
    #include <MsTimer2.h>
    //#include <DallasTemperature.h>
    //DallasTemperature tempSensor;
    #include <LiquidCrystal.h>
    LiquidCrystal lcd(12117654);
    unsigned long time;
    unsigned long taxometr 0;
    unsigned long dinaimpulsov 0;
    unsigned long ValSpCurr 0;
    int tmp37 0;
    int kpa 0;
    int volts 0;
    int pboost 0;
    int atmos 0;
    int senstvaz =0;
    int ds// сенсор ds18b20
    int val;
    int mapp;
    int peakrpm 0;
    int peakspeed 0;
    int taxo 0;
    int count 0;
    float peakboost 0;
    float boostvoltage;
    byte bytes[8]; 

    void setup() 
     {
      
    lcd.begin(162);
      
    pinMode(2INPUT); 
      
    pinMode(3INPUT); 
       
    // * LOW когда на порту LOW
       // * CHANGE , с LOW на HIGH и наоборот
       // * RISING  с LOW на HIGH
       // * FALLING  с HIGH на LOW
      
    attachInterrupt(0int_onRISING);
      
    //attachInterrupt(1, inton, FALLING);
      
    MsTimer2::set(30000flash); // таймер будет срабатывать через каждые 500ms 
      
    MsTimer2::start();//запустить таймер
      //tempSensor.begin(10);
      
    Serial.begin(115200);
    }
    void loop() 
    {
      
    /////////////////ТАХОМЕТР///////////////////////////////////////
    if (taxometr 6000)
    {
     
    taxo = (80000000 taxometr);
    }
    else 
    {
      
    taxo 0;
    }  
    if (
    taxo peakrpm//pikrpm
      
    {  
        
    peakrpm taxo;
      }
    //////////////// СПИДОМЕТР//////////////////////////////////////
        
    dinaimpulsov pulseIn(3HIGH100000);  // Считывание длительности положительного импульса
        
    ValSpCurr = (650000 dinaimpulsov); // Перевод в км/ч
      
    if (dinaimpulsov 120000 || ValSpCurr 350)
      {
        
    ValSpCurr 0;
      } 
      if (
    ValSpCurr peakspeed//pikspeed
      
    {  
        
    peakspeed ValSpCurr;
      }
      
    /////////////////////////////////////////////////////////////////
     
    mapp analogRead(2);//map-sensor 
     
    kpa = ((mapp*(0.0045)*(51.0)+16));// killopaskali
     
    boost = ((mapp*(0.0045)*(51.0)+16)) / 100 -1//kilopaskali v bar
     
    atmos =map(mapp358384735780);// atmosfernoe davlenie
     
    if (kpa peakboost//pikboost
      
    {  
        
    peakboost kpa;
        
    pboost peakboost;
      }
     
    voltage 14.9 1024.0 analogRead(1); // volts
     
    volts voltage 10;
     
    val analogRead(0);// температура воды ваз 
    if (val >= && val <= 269)
    {
       
    senstvaz map(val0269, -50, -1);
    }
    else if (
    val >= 270 && val <= 503)
    {
       
    senstvaz map(val270503019) + 2;
    }
    else if (
    val >= 504 && val <= 821)
    {
       
    senstvaz map(val5048212055) + 2;
    }
    else if (
    val >= 822 && val <= 875)
    {
       
    senstvaz map(val8228755665) + 2;
    }
    else if (
    val >= 876 && val <= 930)
    {
       
    senstvaz map(val8769306680) + 2;
    }
    else if (
    val >= 931 && val <= 946)
    {
       
    senstvaz map(val9319468185) + 2;
    }
    else if (
    val >= 947 && val <= 965)
    {
       
    senstvaz map(val9479658697) + 2;
    }
    else if (
    val >= 966 && val <= 1002)
    {
       
    senstvaz map(val966100298126) + 2;
    }
    else if (
    val >= 1003 && val <= 1015)
    {
       
    senstvaz map(val10031015127140) + 2;
    }
     
    tmp37 = (analogRead(3) * 5.0 1024.0) / 0.02// tmp37
    /////////////////////////////////////////////
    /*
    if (digitalRead(9) <= 0)
      {
       ds = (tempSensor.getTemperature()),
       lcd.clear(), 
       lcd.print(ds),
       delay(1000);
      }
    */
    if (Serial.available() > 0//priem ot kompa
     
    {  
      
    int  inByte Serial.read();
      if (
    inByte ==1
        {
          
    peakboost 0;
          
    inByte =0;
        }
     }
     
    if (
    digitalRead(8) <= 0
      {
      
    peakboost 0//sbros pikboosta, sbrasivati na minus
      
    peakrpm 0;
      
    peakspeed 0;
      
    lcd.clear();
     
    // lcd.setCursor(0, 0);
      
    lcd.print("PEAKS SBROS");
      
    delay(30);
      
      
      }
     
    ////////////////////////////////////////////////////////////////
      
    lcd.clear(); 
       
    lcd.setCursor(00);
      
    //lcd.print(dinaimpulsov);
      
    lcd.print("V");
      
    lcd.print(voltage,1);
       
    lcd.setCursor(60);
       
    lcd.print("B");
       
    lcd.print(boost);
    //  lcd.print(taxometr);
      //lcd.print(" ");
     // lcd.print(mapp);
     // lcd.print(" ");
    // lcd.print(atmos);      
     // lcd.print(" ");
     // lcd.print(taxo);
      
    lcd.setCursor(01);
      
    lcd.print(dinaimpulsov);
      
    lcd.print(" ");
      
    lcd.print(ValSpCurr);
     
    // lcd.print(boost);
     // lcd.print(" ");
     // lcd.print(kpa);
     // lcd.print(" ");
     // lcd.print(pboost);
     // lcd.print(" ");
      //lcd.print(tmp37);
     //////////////////////////////////////////////////////////////////
      
    bytes[0]=(volts); //volts
      
    bytes[1]=(kpa); //turbo
      
    bytes[2]=(pboost); //pboost
      
    bytes[3]=(senstvaz); //senstvaz
      // bytes[4] = result & 255;                     
      // bytes[5] = (result & 768) >> 8;
      
    bytes[4] = taxo 0xFF// преобразовать в 4-байта  
      
    bytes[5] = (taxo 0xFF00) >> 8;  
      
    bytes[6] = (taxo 0xFF0000) >> 16
      
    bytes[7] = (taxo 0xFF000000) >> 24;  
         
      
    Serial.writebytes,8);      
       
     
    // delay(400);
       
      
    bytes[0] = 0;
      
    bytes[1] = 0;       
      
    bytes[2] = 0
      
    bytes[3] = 0
      
    bytes[4] = 0
      
    bytes[5] = 0;
      
    bytes[6] = 0;
      
    bytes[7] = 0;
          
    }
    /*
    void  inton() 



    */
    void  int_on() 


    count++; //увеличить счетчик volatile

    if (count >= 4)
        {
          
    taxometr micros()-time;  //время прихода 6-ти импульсов
          
    time micros(); //обнулить
         // taxometrrr = count;
          
    count 0;
        }  



    void flash() //обработка прерывания таймера
    {
      

    Последний раз редактировалось mebitek; 30.10.2011 в 07:14.

Страница 1 из 3 123 ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •