-
Re: Как точно вычислить температуру со штатного датчика двигателя?
Цитата:
Сообщение от
Chip
Выполнение процедуры по таймеру.
PHP код:
//Выполнение процедуры по таймеру.
#include <MsTimer2.h>
static boolean output = HIGH;
void flash_led()
{
digitalWrite(13, (output==HIGH) ? output=LOW : output=HIGH);
}
void setup()
{
MsTimer2::set(500, flash_led); // 500ms интервал вызова процедуры
MsTimer2::start();
}
void loop()
{
//Здесь будет ваш код
}
Спасибо!!! Таймер - это сила :)
Переделываю весь код под модульность, с вызовом процедур по таймеру.
Прикручиваю плавное изменение ШИМ....
-
Re: Как точно вычислить температуру со штатного датчика двигателя?
Так, я так понял что MsTimer2 позволяет только одно прерывание делать?
Пока ответа не нашел - подключил Metro.h, но здесь тоже вопрос возник, хотя, может и не по душу этой библиотеки. Привожу текущий код:
PHP код:
/*
Программа термоконтроля за системой охлаждения ДВС. Использует плавную регулировку по ШИМ.
Может применяться и в других проектах, где исходные данные будет выдавать термистор (терморезистор).
В качестве исходных данных - 1 проводной температурный датчик (термистор(терморезистор))
двигателя с которого берется информация на штатную приборную панель автомобиля.
Т.к. датчик имеет нелинейную зависимость сопротивления (падения напряжения),
то необходима аппроксимация по заранее известным точкам. Чем выше температура,
тем ниже сопротивление и больше падение напряжения.
Для достоверной работы программы нужно ввести значения проходящего через датчик напряжения при
различных температурах, желательно во всем диапазоне его работы.
За аппроксимацию спасибо SBorovkov.
*/
#include <Metro.h> //Библиотека регулярных действий по интервалу времени
#include <MyLiquidCrystalRus.h> //Библиотека ЖК дисплея
MyLiquidCrystalRus lcd(12, 11, 10, 5, 4, 3, 2); //Используем ЖК дисплей
#include <avr/pgmspace.h> //Подключаем макрос PROGMEM
//*********************Параметры для работы термоконтроля ОЖ двигателя
#define EngineTemp1Count 14 //Количество точек аппроксимации
#define DestinationEngineTemp 90 //Определяем нужную температуру двигателя
#define EngineTempSensorPin 0 // Аналоговый вход для температурного датчика ОЖ ДВС
#define EnginePowerVentPin 6 //ШИМ выход на вентиляторы основного радиатора ДВС
//Задаем точки аппроксимации. Первая цифра - разность из 1024 и значения на входе от датчика
//(сделано для того чтобы развернуть график зависимости и сделать так чтобы с ростом температуры значение увеличивалось)
//не переводил в напряжение чтобы не морочиться и оперировать целыми числами с достаточной точностью;
//вторая цифра - значение температуры (заранее измеренное) при данном значении на выходе с датчика.
uint16_t EngineTemp1[EngineTemp1Count][2] PROGMEM = {{0,0}, {471,46}, {635,56}, {702,64}, {723,71}, {729,75}, {764,80}, {793,85}, {811, 90}, {836, 95}, {862, 102}, {872, 110}, {882, 120}, {890, 130}};
//************************Процедуры по таймеру*************************
Metro PWMengineMetro = Metro(10); //Плавное изменение мощности вентиляторов каждые ХХ миллисекунд
Metro LCDoutMetro = Metro(250); //Выводим информацию на ЖК каждые ХХ миллисекунд
int EngineCurrentVentPWM; //Текущая мощность вентиляторов ОЖ двигателя
void setup() {
Serial.begin(9600);
lcd.begin(16, 2);
lcd.setCursor(0,0);
lcd.print("****************");
lcd.setCursor(0,1);
lcd.print("****************");
delay(1000);
}
void loop() {
//**********************Расчет всех параметров на основе температуры ОЖ двигателя
int EngineTargetVentPWM; //Целевая точка мощности вентиляторов ОЖ двигателя
// int EngineCurrentVentPWM; //Текущая мощность вентиляторов ОЖ двигателя
int EnginePowerVentPercent; //Мощность вентиляторов на ОЖ двигателя в %
int EngineTargetVentPercent; //Задаваемая мощность вентиляторов на ОЖ двигателя в %
uint16_t EngineRealTemp; //Расчетное значение реальной температуры ОЖ двигателя
int i;
int EngineCount = 20; //Количество значений для усреднения
int EngineIn = 0; //Начальная точка суммирования
int EngineInSrednee; //Усредненное значение со входа
uint16_t EngineInTemp; //Входное значение с датчика температуры
uint16_t EngineInLeftTemp;
//Цикл усреднения значения
for (i = 0; i < EngineCount; i++) {
EngineIn = EngineIn + analogRead(EngineTempSensorPin);
}
EngineInSrednee = EngineIn / EngineCount; //Вычисляем среднее значение
EngineInTemp = 1024 - EngineInSrednee; //Переворачиваем график падения напряжения
i=EngineTemp1Count;
do
{
i--;
EngineInLeftTemp=pgm_read_word(&EngineTemp1[i][0]);
}
while ((i>=0)&&(EngineInTemp<EngineInLeftTemp));
uint16_t EngineInRightTemp=pgm_read_word(&EngineTemp1[i+1][0]);
uint16_t EngineOutLeftTemp=pgm_read_word(&EngineTemp1[i][1]);
uint16_t EngineOutRightTemp=pgm_read_word(&EngineTemp1[i+1][1]);
EngineRealTemp=EngineOutLeftTemp+(EngineOutRightTemp-EngineOutLeftTemp)*(EngineInTemp-EngineInLeftTemp)/(EngineInRightTemp-EngineInLeftTemp); //Вычисление значения реальной температуры
float EngineVoltIn = (5.00 / 1024.00 * EngineInSrednee); //Переводим входные данные к абсолютному значению напряжения для мониторинга
//Если температура входит в определнные значения - запускаем вентиляторы на определенную мощность.
if (EngineRealTemp < DestinationEngineTemp - 5) EngineTargetVentPWM = 0;
if (EngineRealTemp >= DestinationEngineTemp - 5) EngineTargetVentPWM = 36;
if (EngineRealTemp >= DestinationEngineTemp - 4) EngineTargetVentPWM = 72;
if (EngineRealTemp >= DestinationEngineTemp - 3) EngineTargetVentPWM = 108;
if (EngineRealTemp >= DestinationEngineTemp - 2) EngineTargetVentPWM = 144;
if (EngineRealTemp >= DestinationEngineTemp - 1) EngineTargetVentPWM = 180;
if (EngineRealTemp >= DestinationEngineTemp) EngineTargetVentPWM = 216;
if (EngineRealTemp >= DestinationEngineTemp + 1) EngineTargetVentPWM = 255;
EnginePowerVentPercent = 100.00/255.00*EngineCurrentVentPWM; //Вычисляем значение в процентах текущей мощности вентиляторов
EngineTargetVentPercent = 100.00/255.00*EngineTargetVentPWM; //Вычисляем значение в процентах задаваемой мощности вентиляторов
//**********************Процедура плавного изменения мощности вентиляторов
if (PWMengineMetro.check() == 1) {
if (EngineCurrentVentPWM > EngineTargetVentPWM && EngineCurrentVentPWM > 0){
EngineCurrentVentPWM--;
analogWrite(EnginePowerVentPin, EngineCurrentVentPWM); // Уменьшаем мощность
}
if (EngineCurrentVentPWM < EngineTargetVentPWM && EngineCurrentVentPWM < 255)
{
EngineCurrentVentPWM++;
analogWrite(EnginePowerVentPin, EngineCurrentVentPWM); // Увеличиваем мощность
}
}
//***********************Выводим все что нам нужно на ЖК дисплей
if (LCDoutMetro.check() == 1){
// lcd.clear();
lcd.setCursor(0,0);
lcd.print("ВЛТ:");
lcd.setCursor(4,0);
lcd.print(EngineVoltIn); //Входное напряжение с датчика
lcd.setCursor(8,0);
if (EngineVoltIn > 2.70) {
lcd.print(" ТМП:");
lcd.setCursor(13,0);
lcd.print("MIN"); //Ниже минимальной точки аппроксимации
}
else if (EngineVoltIn < 0.65){
lcd.print(" ТМП:");
lcd.setCursor(13,0);
lcd.print("MAX"); //Выше максимальной точки аппроксимации
}
else {
lcd.print(" ТМП:");
lcd.setCursor(13,0);
lcd.print(EngineRealTemp); //Аппроксимированная температура
lcd.print(" ");
}
lcd.setCursor(0,1);
lcd.print("МОЩНОСТЬ:");
lcd.setCursor(9,1);
lcd.print(EnginePowerVentPercent); //Мощность вентиляторов
lcd.print(" ");
lcd.setCursor(12,1);
lcd.print("%");
lcd.setCursor(13,1);
lcd.print(EngineTargetVentPercent); //Заданная мощность вентиляторов
lcd.print(" ");
}
}
Вопрос: Почему мне пришлось вынести int EngineCurrentVentPWM в глобальные переменные, иначе не работает плавная регулировка... тупо стоит на 0.
Ну и так, посмотрите, правильно ли двигаюсь? Может что-то можно оптимизировать или сделать более рациональным?
-
Re: Как точно вычислить температуру со штатного датчика двигателя?
Скажи, ты раньше на чем-то програмил? Уж слишком быстро разбираешься!
Теперь ответы :-)
У самого микроконтроллера AtMega168 три таймера. Но насколько я понял, как минимум один, и может два из используется встроенными структурами, которые обеспечивают работу систем Arduino. Итого - старайся выкрутиться одним таймером. Кстати, при грамотной его обработке его хватит в 90% не очень сложных случаев.
К примеру, есть функции, которые надо вызывать каждые 50мс, а есть такие, которые надо вызывать каждую секунду. Ставишь таймер на 50мс и каждый 20 вызов таймера вызываешь ежесекундную функцию.
По поводу переменной EngineCurrentVentPWM: Если ты объявил переменную глобальной (вне каких-либо функций) она существует все время выполнения программы. Соответственно, она хранит значение все время, пока программа выполняется.
Если ты объявил переменную внутри функции, то эта переменная существует только внутри функции (либо еще меньше). Как код только из функции вышел, переменная исчезла и не занимает память. Когда произойдет следующий вход в функцию, переменная будет заново создана и будет иметь случайное значение, если ты ее не проинициализируешь.
Соответственно, твоя функция loop вызывается постоянно. Но при каждом вызове все объявленные внутри переменные создаются заново! И их надо инициализировать, прежде чем из них что-то считать. Кстати, компилятор тебе наверняка выдавал предупреждения на счет чтения неинициализированных переменных.
Когда ты перенес переменную EngineCurrentVentPWM вне loop, ты создал ее глобальной - она существует все время выполнения программы (т.е. вечность, поскольку loop вызывается вечно).
-
Re: Как точно вычислить температуру со штатного датчика двигателя?
Попробую объяснить понятнее про область видимости.
Существует четыре области видимости: локальная, функция, файл и класс.
Локальная:
Есть блок, ограниченный фигурными скобками
{
...
int variable
...
}
Переменная существует с момента объявления и до закрывающей скобки блока.
Как только скобка закрылась, переменная исчезла. Вместо троеточия может быть любой код. В том числе содержащий еще блок {...}
Область видимости - функция
int func(void)
{
...
int variable;
...
}
В таком случае переменная существует от момента определения и до конца функции. Как только функция завершила свою работу, переменная перестала существовать.
Глобальная функция, область видимости - файл.
int Counter;
void loop()
{
Counter++;
}
Переменная существует все время выполнения программы.
Пример -
Код:
int Counter;
void Init(void)
{
Counter=5;
}
void loop(void)
{ // 1
Counter++;
int i;
for (i=0;i<5;i++)
{ //2
int j;
j=i*2;
if (j=10)
{ //3
int k;
k=j+5;
if (k>12)
{ //4
....
} //4
} //3
} //2
} //1
Переменная Counter объявлена глобальной. Соответственно, к ней можно обратиться в обеих функциях и переменная будет чество хранить значение.
Переменная i объявлена с областью видимости - функция. К ней нельзя обратиться в фенкции init. Более того, значение переменной i в момент входа в функцию не определено и может быть абсолютно любым! К этой переменной можно обратиться в любом месте функции loop - с момента ее объявления и до конца выполнения функции, пока не закроется скобка с номером 1.
Переменные j и k объявлены с локальной областью видимости. Переменная j существует пока процессор не выполнит закрывающую скобку 2. Переменная k - пока процессор не выполнит закрывающую скобку 3. Соответственно, при КАЖДОМ входе в цикл, переменная j имеет неизвестное значение.
А теперь разумный вопрос - а зачем это все!?
Ответа два:
1. не всегда хочется, чтобы в любом месте кода были видны все остальные переменные.
К примеру, пишешь мелкую функцию, внутри нее цикл от 1 до 10, она сделала свое дело и закончила работу. Она асболютно сепаратная - никого не волнует как у нее внутри называется переменная цикла. И если переменную цикла объявить внутри самой функции, то в результате переменная исчезнет по выходу из функции. Таким образом в каждой функции твоего модуля может быть определена переменная i и в каждой функции эта переменная будет своя!
2. Компилятор при смотри на область видимости и соответственно размещает переменные в памяти. Вышли из области видимости переменной - память, занимаемую переменной освободили. Нужно занять под новую переменную - пожалуйста, снова выделит.
-
Re: Как точно вычислить температуру со штатного датчика двигателя?
Кстати, компиляторы нынче шибко умные...
К примеру, компилятор понимает, что функция func - ничего не делает, просто перекладывает локальные переменные туда-сюда. И вообще не включает эту функцию с результат компиляции. Соответственно, вызова func тоже нет...
Код:
void func(void)
{
uint8_t i;
uint8_t j=0;
for (i=0;i<10;i++)
j=j+i;
uint8_t k;
k=j+1;
for (i=0;i<10;i++)
k=k+i;
}
int main(void)
{
func();
}
-
Re: Как точно вычислить температуру со штатного датчика двигателя?
Спасибо, огромное! Теперь стало многое понятным.
Цитата:
Сообщение от SBorovkov
Скажи, ты раньше на чем-то програмил? Уж слишком быстро разбираешься!
Ты знаешь, жизнь слишком коротка чтобы что-то в ней не понять. И тяжелее понять людей, чем машину ))) Если серьезно - то что есть опыт в радиотехнике и логических схемах в частности (в детстве баловался элементарной логикой и регистрами сдвига) + бэйсик со времен zxspectrum + php )))
Цитата:
Сообщение от SBorovkov
Существует четыре области видимости: локальная, функция, файл и класс.
С областью видимости переменных я все понял.
Цитата:
Сообщение от SBorovkov
По поводу переменной EngineCurrentVentPWM: Если ты объявил переменную глобальной (вне каких-либо функций) она существует все время выполнения программы. Соответственно, она хранит значение все время, пока программа выполняется.
Если ты объявил переменную внутри функции, то эта переменная существует только внутри функции (либо еще меньше). Как код только из функции вышел, переменная исчезла и не занимает память. Когда произойдет следующий вход в функцию, переменная будет заново создана и будет иметь случайное значение, если ты ее не проинициализируешь.
Вот здесь мне не совсем понятно... EngineCurrentVentPWM у меня, по идее, может существовать только в рамках void loop, т.к. везде, где переменная используется находится в рамках функции loop. Так какого ей надо в глобали? И что значит проинициализировать?
-
Re: Как точно вычислить температуру со штатного датчика двигателя?
На самом деле программа arduino выглядит примерно так:
int main(void)
{
Init()
Setup();
for (;;)
loop();
}
Предположим ты объявил переменную EngineCurrentVentPWM внутри loop().
В этом случае, каждый раз, когда выполнение заходит в выполнение loop() (а он это делает как только завершится прошлый вызов loop, согласно коду выше), выделяется место под переменную EngineCurrentVentPWM и эта переменная каждый раз имеет некоторое, заранее неопределенное, значение. Каждый раз, когда код выходит из loop, память под все переменные функции loop освобождается.
Проинициализировать = присвоить значение.
-
Re: Как точно вычислить температуру со штатного датчика двигателя?
Цитата:
Сообщение от
SBorovkov
На самом деле программа arduino выглядит примерно так:
int main(void)
{
Init()
Setup();
for (;;)
loop();
}
Предположим ты объявил переменную EngineCurrentVentPWM внутри loop().
В этом случае, каждый раз, когда выполнение заходит в выполнение loop() (а он это делает как только завершится прошлый вызов loop, согласно коду выше), выделяется место под переменную EngineCurrentVentPWM и эта переменная каждый раз имеет некоторое, заранее неопределенное, значение. Каждый раз, когда код выходит из loop, память под все переменные функции loop освобождается.
Проинициализировать = присвоить значение.
Т.е. вывод EngineCurrentVentPWM в глобальную переменную неизбежен? В общем, я так понял, не стоит париться по этому поводу? :)
-
Re: Как точно вычислить температуру со штатного датчика двигателя?
Считай, что да. В небольших программах переменные, в которых хранится некое текущее состояние, статус, настройки и тому подобное часто делают глобальными.
-
Re: Как точно вычислить температуру со штатного датчика двигателя?
Понял. Спасибо. Продолжу сегодня работу и, скорее всего, вынесу результат в отдельную тему, т.к. Могут возникнуть вопросы еще по железу.
-
Вложений: 1
Re: Как точно вычислить температуру со штатного датчика двигателя?
Ребята, перешел на 3 проводную библиотеку работы с ЖК. Не получается выводить переменные на ЖК. Ниже код и фото того что на дисплее. Что за синтаксис должен быть?
PHP код:
/*
Программа термоконтроля за системой охлаждения ДВС. Использует плавную регулировку по ШИМ.
Может применяться и в других проектах, где исходные данные будет выдавать термистор (терморезистор).
В качестве исходных данных - 1 проводной температурный датчик (термистор(терморезистор))
двигателя с которого берется информация на штатную приборную панель автомобиля.
Т.к. датчик имеет нелинейную зависимость сопротивления (падения напряжения),
то необходима аппроксимация по заранее известным точкам. Чем выше температура,
тем ниже сопротивление и больше падение напряжения.
Для достоверной работы программы нужно ввести значения проходящего через датчик напряжения при
различных температурах, желательно во всем диапазоне его работы.
За аппроксимацию спасибо SBorovkov.
*/
#include <Metro.h> //Библиотека регулярных действий по интервалу времени
#include <LCD3Wire.h>
#include <avr/pgmspace.h> //Подключаем макрос PROGMEM
#define LCD_LINES 2 // number of lines in your display
#define DOUT_PIN 11 // Dout pin
#define STR_PIN 12 // Strobe pin
#define CLK_PIN 10 // Clock pin
//create object to control an LCD.
LCD3Wire lcd = LCD3Wire(LCD_LINES, DOUT_PIN, STR_PIN, CLK_PIN);
******************* ЛИШНЕЕ УБРАЛ*******************
//***********************Выводим все что нам нужно на ЖК дисплей
if (LCDoutMetro.check() == 1){
// lcd.clear();
lcd.cursorTo(1,0);
lcd.printIn("VLT:");
lcd.cursorTo(1,4);
lcd.print(EngineVoltIn); //Входное напряжение с датчика
lcd.cursorTo(1,8);
if (EngineVoltIn > 2.70) {
lcd.printIn("*TMP:");
lcd.cursorTo(1,13);
lcd.printIn("MIN"); //Ниже минимальной точки аппроксимации
}
else if (EngineVoltIn < 0.65){
lcd.printIn("*TMP:");
lcd.cursorTo(1,13);
lcd.printIn("MAX"); //Выше максимальной точки аппроксимации
}
else {
lcd.printIn("*TMP:");
lcd.cursorTo(1,13);
lcd.print(EngineRealTemp); //Аппроксимированная температура
lcd.printIn(" ");
}
lcd.cursorTo(2,0);
lcd.printIn("POWER:");
lcd.cursorTo(2,9);
lcd.print(EnginePowerVentPercent); //Мощность вентиляторов
lcd.printIn(" ");
lcd.cursorTo(2,12);
lcd.printIn("%");
lcd.cursorTo(2,13);
lcd.print(EngineTargetVentPercent); //Заданная мощность вентиляторов
lcd.printIn(" ");
}
}
И такое ощущение.... вернее так и есть... тормозит обработка плавного изменения ШИМ... что за на*?
-
Re: Как точно вычислить температуру со штатного датчика двигателя?
Там своя кодировка символов. Видимо, цифры имеют нестандартные коды. Найди таблицу символов для своего контроллера.
-
Re: Как точно вычислить температуру со штатного датчика двигателя?
Цитата:
Сообщение от
SBorovkov
Там своя кодировка символов. Видимо, цифры имеют нестандартные коды. Найди таблицу символов для своего контроллера.
Не согласен с предположением, т.к. в параллельном выводе на дисплей - все выводится нормально. Цифры в текстовом виде тоже выводятся нормально. Вопрос именно в синтаксисе данной библиотеки, как мне кажется, и именно в выводе переменных.
-
Re: Как точно вычислить температуру со штатного датчика двигателя?
Тогда второе предположение - lcd.print принимает в качестве параметра строку, а не int.
-
Re: Как точно вычислить температуру со штатного датчика двигателя?
Цитата:
Сообщение от
SBorovkov
Тогда второе предположение - lcd.print принимает в качестве параметра строку, а не int.
Странно. Ладно, буду вечером еще разбираться.
-
Re: Как точно вычислить температуру со штатного датчика двигателя?
Всем привет. В общем "победил" вывод переменных, но как мне кажется через *опу. Ниже скетч:
PHP код:
/*
Программа термоконтроля за системой охлаждения ДВС. Использует плавную регулировку по ШИМ.
Может применяться и в других проектах, где исходные данные будет выдавать термистор (терморезистор).
В качестве исходных данных - 1 проводной температурный датчик (термистор(терморезистор))
двигателя с которого берется информация на штатную приборную панель автомобиля.
Т.к. датчик имеет нелинейную зависимость сопротивления (падения напряжения),
то необходима аппроксимация по заранее известным точкам. Чем выше температура,
тем ниже сопротивление и больше падение напряжения.
Для достоверной работы программы нужно ввести значения проходящего через датчик напряжения при
различных температурах, желательно во всем диапазоне его работы.
За аппроксимацию спасибо SBorovkov.
*/
#include <Metro.h> //Библиотека регулярных действий по интервалу времени
#include <LCD3Wire.h>
#include <avr/pgmspace.h> //Подключаем макрос PROGMEM
#define LCD_LINES 2 // number of lines in your display
#define DOUT_PIN 11 // Dout pin
#define STR_PIN 12 // Strobe pin
#define CLK_PIN 10 // Clock pin
//create object to control an LCD.
LCD3Wire lcd = LCD3Wire(LCD_LINES, DOUT_PIN, STR_PIN, CLK_PIN);
//*********************Параметры для работы термоконтроля ОЖ двигателя
#define EngineTemp1Count 14 //Количество точек аппроксимации
#define DestinationEngineTemp 90 //Определяем нужную температуру двигателя
#define EngineTempSensorPin 0 // Аналоговый вход для температурного датчика ОЖ ДВС
#define EnginePowerVentPin 6 //ШИМ выход на вентиляторы основного радиатора ДВС
//Задаем точки аппроксимации. Первая цифра - р\азность из 1024 и значения на входе от датчика
//(сделано для того чтобы развернуть график зависимости и сделать так чтобы с ростом температуры значение увеличивалось)
//не переводил в напряжение чтобы не морочиться и оперировать целыми числами с достаточной точностью;
//вторая цифра - значение температуры (заранее измеренное) при данном значении на выходе с датчика.
uint16_t EngineTemp1[EngineTemp1Count][2] PROGMEM = {{0,0}, {471,46}, {635,56}, {702,64}, {723,71}, {729,75}, {764,80}, {793,85}, {811, 90}, {836, 95}, {862, 102}, {872, 110}, {882, 120}, {890, 130}};
//************************Процедуры по таймеру*************************
Metro PWMengineMetro = Metro(10); //Плавное изменение мощности вентиляторов каждые ХХ миллисекунд
Metro LCDoutMetro = Metro(10); //Выводим информацию на ЖК каждые ХХ миллисекунд
....................................................лишнее убрали........................
//***********************Выводим все что нам нужно на ЖК дисплей
if (LCDoutMetro.check() == 1){
// lcd.clear();
lcd.cursorTo(1,0);
lcd.printIn("VLT:");
lcd.cursorTo(1,4);
char buf[10];
lcd.printIn(itoa(EngineVoltIn, buf, 10)); //Входное напряжение с датчика
lcd.cursorTo(1,8);
if (EngineVoltIn > 2.70) {
lcd.printIn("*TMP:");
lcd.cursorTo(1,13);
lcd.printIn("MIN"); //Ниже минимальной точки аппроксимации
}
else if (EngineVoltIn < 0.65){
lcd.printIn("*TMP:");
lcd.cursorTo(1,13);
lcd.printIn("MAX"); //Выше максимальной точки аппроксимации
}
else {
lcd.printIn("*TMP:");
lcd.cursorTo(1,13);
lcd.printIn(itoa(EngineRealTemp, buf, 10)); //Аппроксимированная температура
lcd.printIn(" ");
}
lcd.cursorTo(2,0);
lcd.printIn("POWER:");
lcd.cursorTo(2,9);
lcd.printIn(itoa(EnginePowerVentPercent, buf, 10)); //Мощность вентиляторов
lcd.printIn(" ");
lcd.cursorTo(2,12);
lcd.printIn("%");
lcd.cursorTo(2,13);
lcd.printIn(itoa(EngineTargetVentPercent, buf, 10)); //Заданная мощность вентиляторов
lcd.printIn(" ");
}
}
Я так понял что этой библиотеке обязательно нужно преобразовать численное значение в символы... маразм... ну все бы ничего, да не могу вывести таким способом переменную EngineVoltIn типа float... вернее он выводит но без десятичных значений - только целое число. Как это победить? И обновляется информация на дисплее крайне медленно... ШИМ набирает с 0 до 100% за 2-3 минуты ))))) хотя должен за 2-3 секунды, а то и быстрее... Если закомментить вывод инфы на ЖК, то так и происходит. Что за грабли?
-
Re: Как точно вычислить температуру со штатного датчика двигателя?
0. Повесь регулировку ШИМ на таймер.
Тормозит вывод потому, что:
1. сдвиговый регистр не очень предназначен для быстрого переключения отдельных выводов. Думаю, что было бы лучше использовать хотя бы 4 ноги для управления индикатором (отдельный вывод для тактовой ноги индикатора, если такая есть).
2. В торможении видимо ОЧЕНЬ сильно участвует стандартная функция shiftOut, реализованная через стандартную digitalWrite. Запись одного бита в 595-й регистр - это три digitalWrite, каждый из которых выполняется порядка 60 тактов. Запись байта - это 26 вызовов digitalWrite. Запись одной команды в LCD - 6 shiftOut...
Короче такие тормоза из-за реализации данной библиотеки. Если бы ее просто переписать с использованием более правильных функций управления ногами, ускорилось бы все раз в 20...
-
Re: Как точно вычислить температуру со штатного датчика двигателя?
Цитата:
Сообщение от
SBorovkov
0. Повесь регулировку ШИМ на таймер.
Тормозит вывод потому, что:
1. сдвиговый регистр не очень предназначен для быстрого переключения отдельных выводов. Думаю, что было бы лучше использовать хотя бы 4 ноги для управления индикатором (отдельный вывод для тактовой ноги индикатора, если такая есть).
2. В торможении видимо ОЧЕНЬ сильно участвует стандартная функция shiftOut, реализованная через стандартную digitalWrite. Запись одного бита в 595-й регистр - это три digitalWrite, каждый из которых выполняется порядка 60 тактов. Запись байта - это 26 вызовов digitalWrite. Запись одной команды в LCD - 6 shiftOut...
Короче такие тормоза из-за реализации данной библиотеки. Если бы ее просто переписать с использованием более правильных функций управления ногами, ускорилось бы все раз в 20...
Понял, спасибо. Буду думать. Попробую отдельно протестировать библиотеку на скорость вывода изображения. Из этого буду принимать решение.
-
Вложений: 1
Re: Как точно вычислить температуру со штатного датчика двигателя?
Полное г** эта библиотека... протестировал скорость вывода на ЖК - разочарован. Думаю при последовательном выводе должно работать быстрее гораздо. Вернулся на параллельное подключение, но освободил ШИМ ноги путем переноса на другие.
Работа продолжается, поставил стабилизатор на LM2575 и силовой ШИМ на базе IRLU8256.
Завтра попробую запустить это дело на машине на реальный вентилятор. Побаиваюсь только за макетную плату... выдержит ли ток ампер 10, хотя бы пару минут? :)
-
Re: Как точно вычислить температуру со штатного датчика двигателя?
Всем привет! Тесты пройдены успешно. Рисую печатную плату под силовые ключи, т.к. их планирую убрать под капот чтобы ничего не свистело в салоне. Думаю, за выходные будет результат.
-
Re: Как точно вычислить температуру со штатного датчика двигателя?
а что за машина и что за датчик к которому ты подключался?
-
Re: Как точно вычислить температуру со штатного датчика двигателя?
М...дя! Наворотили вы тут -) а не проще поставить рядом или вместо штатного DS1820 наверное вы не ищете лёгких путей?
-
Re: Как точно вычислить температуру со штатного датчика двигателя?
Цитата:
Сообщение от
mebitek
а что за машина и что за датчик к которому ты подключался?
Тойота соарер 91гв.
-
Re: Как точно вычислить температуру со штатного датчика двигателя?
Цитата:
Сообщение от
avgefke
М...дя! Наворотили вы тут -) а не проще поставить рядом или вместо штатного DS1820 наверное вы не ищете лёгких путей?
Конечно не ищем легких путей ))
Конечно у меня была мысль о цифровом датчике. Но:
1 как вы себе видите его врезку в блок или по крайней мере в патрубок?!
2 почему никто в автопроме до сих пор их не ставит?
-
Re: Как точно вычислить температуру со штатного датчика двигателя?
Прикрутить его к головке аль ещё куда пара пустяков! К примеру я прихватил его к трубе хомутом замазал белым автомобильным герметиком соответственно проводку аккуратно проложил вот и все. Да их хоть куда лепи и хоть что делай.
на улицу, к мотору, к заднице.-)
А в автопроме не применяю их наверное из за консерватизма мышления или считают не очень надёжными или о чем они там думают ХЗ?.
-
Re: Как точно вычислить температуру со штатного датчика двигателя?
а кстати почему их не применяют в автопромышленности?
-
Re: Как точно вычислить температуру со штатного датчика двигателя?
Не применяют их, я думаю, потому что это лишний элемент снижения надежности.
При выборе между кремниевым устройством и обычным термистором, выбирают последний ввиду бОльшего температурного диапазона и бОльшей наработкой часов на отказ (MTBF, MTTF).
-
Re: Как точно вычислить температуру со штатного датчика двигателя?
Цитата:
Сообщение от
avgefke
Прикрутить его к головке аль ещё куда пара пустяков! К примеру я прихватил его к трубе хомутом замазал белым автомобильным герметиком соответственно проводку аккуратно проложил вот и все. Да их хоть куда лепи и хоть что делай.
на улицу, к мотору, к заднице.-)
А в автопроме не применяю их наверное из за консерватизма мышления или считают не очень надёжными или о чем они там думают ХЗ?.
Может конечно и можно его прикрутить, приклеить иль еще что сделать.
Но на тот момент ставилась задача воспользоваться штатным датчиком дабы не лепить лишних соплей дублирующих штатные датчики.
На сегодняшний день устройство заточено под врезку обычных термодатчиков для упрощения инсталляции сторонними людьми.
Все таки нет доверия к цифровому датчику, который нельзя врезать и который постоянно будет работать в верхней температурной планке своего диапазона. А если дело коснется температуры масла, то до 100-120 может подогреваться.
-
Re: Как точно вычислить температуру со штатного датчика двигателя?
Температурный диапазон цифрового датчика более чем достаточен для работы в суровых реальных условиях. А если его выполнить в пром исполнении то он легко выдержит температуры большие чем может выдержать мотор так что это не довод. я специально издевался над ними 200 градусов легко держали в минус 47 было как то зимой тоже ничего не произошло и работают по сей день исправно.
Дата шит загляни-) Там все написано.
-
Re: Как точно вычислить температуру со штатного датчика двигателя?
Цитата:
Сообщение от
avgefke
Температурный диапазон цифрового датчика более чем достаточен для работы в суровых реальных условиях. Он выдерживает температуры большие чем может выдержать мотор так что это не довод. я специально издевался над ними 200 градусов легко держали в минус 47 было как то зимой тоже ничего не произошло и работают по сей день исправно.
Дата шит загляни-) Там все написано.
Даташит давно изучен: -55 +125 (DS18B20). Точность измерения -10 +85 0,5%.
А касательно турбомоторов, а именно такой у меня и стоит, там температурные режимы могут быть еще выше при агрессивной езде. Подкапотное пространство греется до 80-90.
То что вы проделывали с датчиком - это не показатель надежности этих датчиков, а лишь показатель кратковременной устойчивости вашего экземпляра. Давайте закроем вопрос о методологии испытаний датчиков на надежность, т.к. это флуд в этой теме.
Никто не против цифродатчиков, но ИМХО не в мотор.
-
Re: Как точно вычислить температуру со штатного датчика двигателя?
Согласен! Не будем разводить базар. Только думаю нужно построить дополнительный "эталонный" термометр он будет контролировать штатный. Лично я так и сделал.
Ну а если вам охота изучать нелинейности тогда конечно!-)