Re: Как точно вычислить температуру со штатного датчика двигателя?
Только что по приколу попробовал оба вида расчета.
Подключение библиотеки math.h и расчет экспоненты съедает 4к флеша и порядка 250 байт оперативной памяти.
Код:
#include <math.h>
...
uint8_t i;
double d;
double volatile p=0;
d=1.545444342+i;
p=p+exp(d);
if (p==0)
p=1;
}
Выполняется примерно 5300 тактов процессора. А там еще наверняка надо будет выполнить кучу действий, кроме вычисления экспоненты (умножения, деления..).
Код с аппроксимацией 16-битных значений
Код:
#define Temp1Count 5
uint16_t Temp1[Temp1Count][2] PROGMEM =
// первое значение - абсцисса, второе - ордината
{
{0,40},
{5,80},
{26,200},
{42,300},
{70,400},
};
...
uint16_t InTemp;
uint16_t RealTemp;
uint16_t InLeftTemp;
InTemp=5;
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==81)
...
Основное затраченное время - выполнение умножений и делений. Выполняется порядка 350 тактов при 4х попаданиях в цикл (20 тактов на цикл). Съедает порядка 160 байт флеш-памяти, не ест оперативную память.
Тут правда надо четко просчитать, чтобы не было переполнений при умножении, либо вычисление RealTemp делать в int32.
В общем все зависит от необходимой точности и наличия ресурсов.
Re: Как точно вычислить температуру со штатного датчика двигателя?
Цитата:
Сообщение от
SBorovkov
Только что по приколу попробовал оба вида расчета.
Подключение библиотеки math.h и расчет экспоненты съедает 4к флеша и порядка 250 байт оперативной памяти.
Код:
#include <math.h>
...
uint8_t i;
double d;
double volatile p=0;
d=1.545444342+i;
p=p+exp(d);
if (p==0)
p=1;
}
Выполняется примерно 5300 тактов процессора. А там еще наверняка надо будет выполнить кучу действий, кроме вычисления экспоненты (умножения, деления..).
Код с аппроксимацией 16-битных значений
Код:
#define Temp1Count 5
uint16_t Temp1[Temp1Count][2] PROGMEM =
// первое значение - абсцисса, второе - ордината
{
{0,40},
{5,80},
{26,200},
{42,300},
{70,400},
};
...
uint16_t InTemp;
uint16_t RealTemp;
uint16_t InLeftTemp;
InTemp=5;
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==81)
...
Основное затраченное время - выполнение умножений и делений. Выполняется порядка 350 тактов при 4х попаданиях в цикл (20 тактов на цикл). Съедает порядка 160 байт флеш-памяти, не ест оперативную память.
Тут правда надо четко просчитать, чтобы не было переполнений при умножении, либо вычисление RealTemp делать в int32.
В общем все зависит от необходимой точности и наличия ресурсов.
Спасибо огромнейшее! Вечером буду пробовать. Отпишусь о результатах.
Re: Как точно вычислить температуру со штатного датчика двигателя?
Не получается второй скетч запустить...
Компилятор выдает:
In function 'void setup()':
error: expected initializer before 'PROGMEM
Вот полный код:
PHP код:
#define Temp1Count 5
void setup() {
uint16_t Temp1[Temp1Count][2] PROGMEM = {{0,40}, {5,80}, {26,200}, {42,300}, {70,400},};
}
void loop() {
uint16_t InTemp;
uint16_t RealTemp;
uint16_t InLeftTemp;
InTemp=5;
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==81)
}
Где я накосячил? :confused:
Re: Как точно вычислить температуру со штатного датчика двигателя?
Да и с первой я не совсем понял каким местом ее прикручивать.. Вы уж простите, не гуру я в программировании. Помогите пожалуйста действующим скетчем.
Re: Как точно вычислить температуру со штатного датчика двигателя?
Пропиши
#include <avr/pgmspace.h>
Re: Как точно вычислить температуру со штатного датчика двигателя?
Ну не выходит "цветок каменный"..
PHP код:
#define Temp1Count 5
#include <avr/pgmspace.h>
int i;
void setup() {
uint16_t Temp1[Temp1Count][2] PROGMEM = {{0,40}, {5,80}, {26,200}, {42,300}, {70,400},};
}
void loop() {
uint16_t InTemp;
uint16_t RealTemp;
uint16_t InLeftTemp;
InTemp=5;
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==81)
}
Матерится:
In function 'void loop()':
error: 'Temp1' was not declared in this scope
Если я пытаюсь прописать в начале Temp1 (int Temp1), то матерится что типа это array и все такое :(
Re: Как точно вычислить температуру со штатного датчика двигателя?
порядок такой:
сначала объявляешь константу, потом массив (массив использует константу). И то и другое - вне функций, если собираешься использовать их более чем в одной функции.
Код:
#include <avr/pgmspace.h>
#define Temp1Count 5
uint16_t Temp1[Temp1Count][2] PROGMEM = {{0,40}, {5,80}, {26,200}, {42,300}, {70,400}};
void setup() {
}
void loop() {
...
// тут располагать что угодно, в том числе - аппроксимацию.
}
Еще, мой тебе совет - не объявляй лишних глобальных переменных. И уж точно - не используй глобальные переменные в качестве переменных цикла без большой необходимости.
У каждого идентификатора (переменной, функции...) есть область видимости. Это область, в которой этот идентификатор можно использовать.
К примеру:
...
{
int i;
// тут можно использовать переменную i
}
// а вот тут ее уже нет, ибо скобка закрыта и область видимости вместе с ней.
собственно то, что ты пишешь именно на область видимости и указывает.
In function 'void loop()': error: 'Temp1' was not declared in this scope
Массив Temp1 объявлен в твоем коде внутри функции Setup(), как следствие, вне Setup() этот массив недоступен.
(добавлено)
Ты когда написал после #define и #include (вне функций)
int i;
сделал переменную глобальной. Это означает, что эта переменная существует везде внутри этого модуля. Соответственно, изменение этой переменной в любой функции поменяет ее значение. Такое можно делать, если переменная хранит какое-то текущее состояние системы, к примеру, но тогда переменной дают какое-то разумное название:
int CurrentState;
Если же сделать как у тебя написано, то это может привести к ошибке. Нижеприведенный цикл будет выполняться вечно, поскольку переменная i одна и та же для цикла и в функции cаlc:
Код:
int i;
void setup() {
}
void calc(){
i=5;
}
void loop() {
for (i=0;i<10;i++)
calc();
}
Re: Как точно вычислить температуру со штатного датчика двигателя?
Спасибо SBorovkov, с синтаксисом разобрался. Запустил код. Есть чему учиться. :)
Вывел на серийный порт переменную RealTemp. Число 80 на выходе.
А куда мне подставить значения с аналогового входа 0 чтобы на выходе получить реальную температуру?
Re: Как точно вычислить температуру со штатного датчика двигателя?
И по абсциссе и ординате, я так понимаю мне нужно поставить какие-то мои точки аппроксимации? Т.е. например соответствие значения на входе и температуры?
Re: Как точно вычислить температуру со штатного датчика двигателя?
Подставил значение на:
InTemp = 5.00 / 1024.00 * analogRead(0);
На выходе ( Serial.println(RealTemp); ) какие-то дискретные значения от 40 до 72 с шагом 8.