Страница 3 из 8 ПерваяПервая 12345678 ПоследняяПоследняя
Показано с 21 по 30 из 71
  1. #21
    Модератор
    Регистрация
    06.07.2008
    Возраст
    46
    Сообщений
    414
    Вес репутации
    443

    По умолчанию Re: Как точно вычислить температуру со штатного датчика двигателя?

    В массиве Temp1[Temp1Count][2] PROGMEM = {{0,40}, {5,80}, {26,200}, {42,300}, {70,400}}
    находятся соответствия значений для аппроксимации. Для значения 0 результат - 40. Для 5 - 80. И так далее. Соответственно, для входного значения 1, выходное значение должно быть 48. Для 2 - 56, для 5 - 80.

    Вообще я бы рекомендовал любые алгоритмы тестировать и отлаживать в каких-нибудь средах разработки (можно не привязанных к микроконтроллерам). Тем более, что С - он и в африке С (wiring - это С с несколькими функциями и макросами). В среде ардуино отсутствует возможность отладки, поэтому в ней невозможно разработать что-либо сложное.

    Есть куча проблем, с которыми можно столкнуться: в реализации С для микроконтроллеров AVR отсутствует контроль результата на предмет его попадания в допустимый диапазон значений переменной. К примеру, если написать
    uint8_t i; // это восьмибитая беззнаковая переменная. значения 0..255
    i=200;
    i=i+150;
    то i будет равно 94. И никаких ошибок в процессе работы программы не возникнет, ибо ошибки банально некуда выдавать.

    Но это еще ладно, такую ситуацию можно предусмотреть и ею пользоваться. А можно обратиться в массив по некорректному индексу:
    int16_t ar[10];
    uint16_t i=15;
    uint16_t j;
    j=ar[i];
    И эта ситуация, понятная компилятору на стадии компиляции не вызывает предупреждений.
    Поэтому очень рекомендую все минимально сложные куски кода отлаживать проходом по коду в отладчике и просмотром переменных.

    (добавлено)
    В массиве первое значение - считанное значение считанное с датчика (при помощи того же AnalogRead() ), второе - выходное значение температуры.
    Да, учти, что при подсчете значения не должно произойти переполнения uint16 - у него максимальное значение 65536. Либо в формуле расчета надо принудительно производить расчет в 32х битах.
    Имеется ввиду эта строка:
    RealTemp=OutLeftTemp+(OutRightTemp-OutLeftTemp)*(InTemp-InLeftTemp)/(InRightTemp-InLeftTemp);
    При вычислении (OutRightTemp-OutLeftTemp)*(InTemp-InLeftTemp)/(InRightTemp-InLeftTemp) а конкретно - при вычислении произведения может произойти переполнение через 65535. В Сях тип выражения берется из первого участника выражения.
    Последний раз редактировалось SBorovkov; 10.08.2010 в 01:06.

  2. #22
    Пользователь
    Регистрация
    21.07.2010
    Возраст
    45
    Сообщений
    82
    Вес репутации
    193

    По умолчанию Re: Как точно вычислить температуру со штатного датчика двигателя?

    SBorovkov, спасибо за информацию.
    Честно скажу, большинство я не понял того что вы написали... Не хватает базы, но интуитивно все получилось. Единственное, нужно будет все же сделать реальные замеры вплоть до крайних точек температурного диапазона и увеличить до 16-20 точек аппроксимацию.
    Ниже текущий код.. может есть у кого что добавить/изменить?
    PHP код:
    #include <LiquidCrystal.h>
    #include <avr/pgmspace.h>  
    #define Temp1Count 10 //Увеличил до 10 значений

    LiquidCrystal lcd(1211105432);
    int analog 0;    // Аналоговый вход для температурного датчика
    int K 1;         //Калибровочный коэффициент по входу от датчика
    int t;       //Температура
    int P;         //Мощность вентиляторов
    int V;        //Значение напряжения на входе
    int T 75;        //Определяем нужную температуру двигателя
    uint16_t Temp1[Temp1Count][2PROGMEM = {{471,46}, {655,58}, {713,65}, {772,74}, {775,80}, {802,90}, {823,100}, {839,110}, {852120}, {861130}}; //Точки аппроксимации

    void setup() {
        
    Serial.begin(9600);
        
    lcd.begin(162);
        
    lcd.print("   WELCOME TO   ");
        
    lcd.setCursor(0,1);
        
    lcd.print("*THERMOCONTROL*");
        
    delay(2000);
        
    lcd.clear();
    }

    void loop() {
        
    int i;
        
    uint16_t InTemp;
        
    uint16_t RealTemp;

        
    uint16_t InLeftTemp;
        
    InTemp 1024 analogRead(0);
        
    i=Temp1Count;
        do
        {
        
    i--;
        
    InLeftTemp=pgm_read_word(&Temp1[i][0]);
        }
        while ((
    i>=0)&&(InTemp<InLeftTemp));
        
    uint16_t InRightTemp=pgm_read_word(&Temp1[i+1][0]);
        
    uint16_t OutLeftTemp=pgm_read_word(&Temp1[i][1]);
        
    uint16_t OutRightTemp=pgm_read_word(&Temp1[i+1][1]);

        
    RealTemp=OutLeftTemp+(OutRightTemp-OutLeftTemp)*(InTemp-InLeftTemp)/(InRightTemp-InLeftTemp);
        if (
    RealTemp==130);
        
        
    //Спасибо SBorovkov

      
    float V = (5.00 1024.00 analogRead(analog)) * K//Переводим входные данные к абсолютному напряжению
      
    if (50;
      if (
    >= 550;
      if (
    >= 470;
      if (
    >= 390;
      if (
    >= 2120;  
      if (
    >= 1160;  
      if (
    >= T200;  
      if (
    >= 1255;  
      
    analogWrite (6P); //Запускаем вентиляторы
      
    Serial.println(PDEC);  //Выводим информацию на всякий случай
      
    lcd.clear();
      
    lcd.setCursor(0,0);
      
    lcd.print("VLT:");
      
    lcd.setCursor(4,0);
      
    lcd.print(V);
      
    lcd.setCursor(8,0);
      
    lcd.print("*TP:");
      
    lcd.setCursor(12,0);
      
    lcd.print(RealTemp);
      
    lcd.setCursor(15,0);
      
    lcd.print("C");  
      
    lcd.setCursor(0,1);
      
    lcd.print("PWR:");
      
    lcd.setCursor(4,1);
      
    lcd.print(100.00/255.00*P);
    //  lcd.setCursor(7,1);
      
    lcd.print("%");
      
    delay(300);  


    С уважением, Дмитрий.
    тел. 8 9I6 855 7Ч 95

  3. #23
    Пользователь
    Регистрация
    21.07.2010
    Возраст
    45
    Сообщений
    82
    Вес репутации
    193

    По умолчанию Re: Как точно вычислить температуру со штатного датчика двигателя?

    Прошу прощения, подкорректировал код.. теперь все работает:
    PHP код:
    #include <LiquidCrystal.h>
    #include <avr/pgmspace.h>  
    #define Temp1Count 10 //Увеличил до 10 значений
        
    int t;       //Температура
        
    int P;         //Мощность вентиляторов
        
    int T 75;        //Определяем нужную температуру двигателя
        
    int i;

    LiquidCrystal lcd(1211105432);
    uint16_t Temp1[Temp1Count][2PROGMEM = {{471,46}, {655,58}, {713,65}, {772,74}, {775,80}, {802,90}, {823,100}, {839,110}, {852120}, {861130}}; //Точки аппроксимации

    void setup() {
        
    Serial.begin(9600);
        
    lcd.begin(162);
        
    lcd.print("   WELCOME TO   ");
        
    lcd.setCursor(0,1);
        
    lcd.print("*THERMOCONTROL*");
        
    delay(2000);
        
    lcd.clear();
    }

    void loop() {
        
    uint16_t InTemp;
        
    uint16_t RealTemp;

        
    uint16_t InLeftTemp;
        
    InTemp 1024 analogRead(0);
        
    i=Temp1Count;
        do
        {
        
    i--;
        
    InLeftTemp=pgm_read_word(&Temp1[i][0]);
        }
        while ((
    i>=0)&&(InTemp<InLeftTemp));
        
    uint16_t InRightTemp=pgm_read_word(&Temp1[i+1][0]);
        
    uint16_t OutLeftTemp=pgm_read_word(&Temp1[i][1]);
        
    uint16_t OutRightTemp=pgm_read_word(&Temp1[i+1][1]);

        
    RealTemp=OutLeftTemp+(OutRightTemp-OutLeftTemp)*(InTemp-InLeftTemp)/(InRightTemp-InLeftTemp);
        if (
    RealTemp==130);

      
    float V = (5.00 1024.00 analogRead(0)); //Переводим входные данные к абсолютному напряжению
      
    if (RealTemp 50;
      if (
    RealTemp >= 550;
      if (
    RealTemp >= 470;
      if (
    RealTemp >= 390;
      if (
    RealTemp >= 2120;  
      if (
    RealTemp >= 1160;  
      if (
    RealTemp >= T200;  
      if (
    RealTemp >= 1255;  
      
    analogWrite (6P); //Запускаем вентиляторы
      
    Serial.println(PDEC);  //Выводим информацию на всякий случай
      
    lcd.clear();
      
    lcd.setCursor(0,0);
      
    lcd.print("VLT:");
      
    lcd.setCursor(4,0);
      
    lcd.print(V);
      
    lcd.setCursor(8,0);
      
    lcd.print("*TP:");
      
    lcd.setCursor(12,0);
      
    lcd.print(RealTemp);
      
    lcd.setCursor(15,0);
      
    lcd.print("C");  
      
    lcd.setCursor(0,1);
      
    lcd.print("PWR:");
      
    lcd.setCursor(4,1);
      
    lcd.print(100.00/255.00*P);
    //  lcd.setCursor(7,1);
      
    lcd.print("%");
      
    delay(300);  


    С уважением, Дмитрий.
    тел. 8 9I6 855 7Ч 95

  4. #24
    Пользователь
    Регистрация
    21.07.2010
    Возраст
    45
    Сообщений
    82
    Вес репутации
    193

    По умолчанию Re: Как точно вычислить температуру со штатного датчика двигателя?

    Вот фотка того что на дисплее:
    Миниатюры Миниатюры Нажмите на изображение для увеличения. 

Название:	IMG_0262[1].jpg 
Просмотров:	433 
Размер:	163.8 Кб 
ID:	9410  
    С уважением, Дмитрий.
    тел. 8 9I6 855 7Ч 95

  5. #25
    Модератор
    Регистрация
    06.07.2008
    Возраст
    46
    Сообщений
    414
    Вес репутации
    443

    По умолчанию Re: Как точно вычислить температуру со штатного датчика двигателя?

    Вообще все нормально.

    Я бы маленько подправил, но это на работу не повлияет.

    Строку
    if (RealTemp==130);
    можно убрать, все равно ничего не делает.

    Строку
    int T = 75;
    если значение менять в коде не будешь, лучше заменить на
    #define T 75
    а еще лучше - сразу назвать понятно, что-то вроде
    #define DestinationEngineTemp 75
    обрати внимание, что в строке с #define точку с запятой в конце не ставят!
    Таким образом можно объявить константу.

    Объявление
    int i;
    перенеси в то место, где эта переменная используется - в loop()

    Еще совет - не заводи переменных, отличающихся регистром.
    int t; //Температура
    int T = 75;
    Запаришься искать ошибку, если ошибешься регистром при их использовании.
    Лучше всего все переменные, смысл которых сложнее, чем переменная цикла называть так, чтобы было понятно что в ней хранится. Хотя бы 2-3 символа, если использование локальное. Если же переменная или константа используется в нескольких функциях, то полноценное имя, иначе потом забудешь что за переменная, или будешь путаться.

    И еще - все, что касается выводов МК лучше складывать в #define
    То есть вместо AnalogRead(0)
    надо написать примерно так, как ты писал выше:
    в начале
    #define EngineTempSensorPin 0

    А дальше везде
    AnalogRead(EngineTempSensorPin)

    Связано это с тем, что если вдруг тебе надо будет потом поменять выводы ардуино, не придется искать все упоминания вывода, а достатоно тупо поменять константу.
    Последний раз редактировалось SBorovkov; 10.08.2010 в 04:06.

  6. #26
    Местный
    Регистрация
    23.09.2009
    Возраст
    45
    Сообщений
    152
    Вес репутации
    217

    По умолчанию Re: Как точно вычислить температуру со штатного датчика двигателя?

    Цитата Сообщение от SBorovkov Посмотреть сообщение
    И еще - все, что касается выводов МК лучше складывать в #define
    То есть вместо AnalogRead(0)
    надо написать примерно так, как ты писал выше:
    в начале
    #define EngineTempSensorPin 0

    А дальше везде
    AnalogRead(EngineTempSensorPin)

    Связано это с тем, что если вдруг тебе надо будет потом поменять выводы ардуино, не придется искать все упоминания вывода, а достатоно тупо поменять константу.
    Так еще намного понятнее что ты считываешь, чем конструкция AnalogRead(0)
    Код как правило пишется для людей, чтобы потом можно было понять что к чему. Компилятор "дурак", что напишешь то и будет делать

  7. #27
    Пользователь
    Регистрация
    21.07.2010
    Возраст
    45
    Сообщений
    82
    Вес репутации
    193

    По умолчанию Re: Как точно вычислить температуру со штатного датчика двигателя?

    Цитата Сообщение от SBorovkov Посмотреть сообщение
    Вообще все нормально.

    Я бы маленько подправил, но это на работу не повлияет.

    Строку
    if (RealTemp==130);
    можно убрать, все равно ничего не делает.

    Строку
    int T = 75;
    если значение менять в коде не будешь, лучше заменить на
    #define T 75
    а еще лучше - сразу назвать понятно, что-то вроде
    #define DestinationEngineTemp 75
    обрати внимание, что в строке с #define точку с запятой в конце не ставят!
    Таким образом можно объявить константу.

    Объявление
    int i;
    перенеси в то место, где эта переменная используется - в loop()

    Еще совет - не заводи переменных, отличающихся регистром.
    int t; //Температура
    int T = 75;
    Запаришься искать ошибку, если ошибешься регистром при их использовании.
    Лучше всего все переменные, смысл которых сложнее, чем переменная цикла называть так, чтобы было понятно что в ней хранится. Хотя бы 2-3 символа, если использование локальное. Если же переменная или константа используется в нескольких функциях, то полноценное имя, иначе потом забудешь что за переменная, или будешь путаться.

    И еще - все, что касается выводов МК лучше складывать в #define
    То есть вместо AnalogRead(0)
    надо написать примерно так, как ты писал выше:
    в начале
    #define EngineTempSensorPin 0

    А дальше везде
    AnalogRead(EngineTempSensorPin)

    Связано это с тем, что если вдруг тебе надо будет потом поменять выводы ардуино, не придется искать все упоминания вывода, а достатоно тупо поменять константу.
    Спасибо за дельные советы. Буду учиться делать код красиво и правильно.
    С уважением, Дмитрий.
    тел. 8 9I6 855 7Ч 95

  8. #28
    Пользователь
    Регистрация
    21.07.2010
    Возраст
    45
    Сообщений
    82
    Вес репутации
    193

    По умолчанию Re: Как точно вычислить температуру со штатного датчика двигателя?

    Цитата Сообщение от -= Nicki =- Посмотреть сообщение
    Так еще намного понятнее что ты считываешь, чем конструкция AnalogRead(0)
    Код как правило пишется для людей, чтобы потом можно было понять что к чему. Компилятор "дурак", что напишешь то и будет делать
    Понял.. Сегодня сделаю для людей и выложу в шапку код. Может кому пригодится.
    С уважением, Дмитрий.
    тел. 8 9I6 855 7Ч 95

  9. #29
    Пользователь
    Регистрация
    21.07.2010
    Возраст
    45
    Сообщений
    82
    Вес репутации
    193

    По умолчанию Re: Как точно вычислить температуру со штатного датчика двигателя?

    Выложил в первый пост результат работы. Буду постепенно совершенствовать и обновлять. Если где ошибся - говорите. Код работает.
    С уважением, Дмитрий.
    тел. 8 9I6 855 7Ч 95

  10. #30
    Пользователь
    Регистрация
    21.07.2010
    Возраст
    45
    Сообщений
    82
    Вес репутации
    193

    По умолчанию Re: Как точно вычислить температуру со штатного датчика двигателя?

    Уже обновил. "Научил" ЖК показывать русские буквы чтобы было понятнее.
    Завтра попробую зацепить на машину для мониторинга температуры... буду ставить в паре с обычной термопарой на мультиметре - буду сравнивать значения
    Скорее всего, выложу видео т.к. все равно снимать, чтобы от дороги не отвлекаться.
    С уважением, Дмитрий.
    тел. 8 9I6 855 7Ч 95

Страница 3 из 8 ПерваяПервая 12345678 ПоследняяПоследняя

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

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

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

Ваши права

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