Перейти к содержанию

Термометр На Термопаре И Max6675, Avr


Рекомендуемые сообщения

Всем привет. Просьба посодействовать в исправлении кода для термометра. Так как сам я в этом новичек, то код собирал из трех чужих проектов. Реализация такова, подключение термопары через микруху Max6675 к Atmega и вывод данных на LCD экран. В архиве прилагаю проект Atme Studio 7 и принт скрин из Протеуса. Ошибка заключается в неправильных показаниях температуры :)

post-196956-0-59716800-1451663841_thumb.jpg

Test1.rar

Вот код, чтоб не скачивать проект.

#define F_CPU 1000000UL
#include <util/delay.h>
#include <avr/io.h>
#include "max6675.h"
#include "LCD.h"

uint16_t gettemp(void); //Funktionsdeklarationen
void initavr(void);

//gettemp () returns absolute Temperature in Temp * 4 °C - in 1/4°-steps
//
uint16_t gettemp(void){ //Temperatur holen.
uint8_t bit = 0, bitnr = 12; //Variablen
uint8_t foo1 = 0;
uint16_t Rohdata = 0;

CS_Port &= ~(1 << CS); //Chip select anlegen

for(foo1 = 0 ; foo1 < 16 ; foo1++){ //16 Bits einlesen
bit = 15 - foo1; //Die Aktuelle Bitnr berechnen.

SCK_Port |= (1 << SCK); //SCK hi

if((bit <= 14) && (bit >= 3)){ //Einfach mal die 12 relevanten von den 16 Bits ausfiltern
if((SO_Pin & (1 << SO))){ //WENN SO 1 ist, dann...
bitnr--; //zдhlen wir runter...
Rohdata |= (1 << bitnr); // und schieben eine 1 an bit x
}else{ //WENN dem NICHT so ist, dann...
bitnr--; //zдhlen wir runter...
Rohdata &= ~(1 << bitnr); //und schieben eine 0 an bit x
}
}else{ //weis au nimmer, was das soll.
bitnr = 12;
}

SCK_Port &= ~(1 << SCK); //SCK LO
}
CS_Port |= (1 << CS); //CS HI //Alles auf Standardkonfig.

return Rohdata; //Das ist doch mal was ;D
}

// getTC() returns 0 if Thermocouple is not connected, 255 if thermocuple is connected
// (to enable this feature T- must be connected to GND)
uint8_t getTC(void){ //Temperatur holen. //Variablen
uint8_t TC = 0;
uint8_t foo1 = 0;

CS_Port &= ~(1 << CS); //Chip select anlegen

for(foo1 = 0 ; foo1 < 16 ; foo1++){ //16 Bits einlesen //Die Aktuelle Bitnr berechnen.

SCK_Port |= (1 << SCK); //SCK hi

if(foo1 == 2){ //das 3. bit ist fьr uns relevant.
if((SO_Pin & (1 << SO))){ //WENN SO 1 ist, dann...
TC = 0;
}else{ //WENN dem NICHT so ist, dann...
TC = 255;
}
}
SCK_Port &= ~(1 << SCK); //SCK LO
}
CS_Port |= (1 << CS); //CS HI //Alles auf Standardkonfig.

return TC; //Das ist doch mal was ;D
}

//Initiates the MAX6675 and IO-pins
void init_6675(void){ //AVR initialisieren

SO_DDR &= ~(1 << SO);
CS_DDR |= (1 << CS);
SCK_DDR |= (1 << SCK); //IOs setzen

SO_Port |= (1<<SO); //Pullups an. (Wichtig fьr MAX6675, der kann nicht anders, hab ich festgestellt...

CS_Port |= (1 << CS); //CS HI //Alles auf Standardkonfig.
SCK_Port &= ~(1 << SCK); //SCK LO

}

int main(void)
{
init_port();// инициализируем порт ЖКИ
lcd_init();// инициализируем ЖКИ
init_6675();



while (1)
{
		char buffer[8];
int temp;
temp = gettemp();
temp /=4;


lcd_gotoxy(0,0);//перемещаем курсор в верхний левый угол
sprintf(buffer, "t=%i\xdf\C ", temp); // так как тут не плавающая запятая то числа с запятой записываются так %i.%i, код градуса записывается так \xdf
lcd_putstring(buffer);
}


}

вставляете код пользуйтесь тегами [CОDE][/CОDE] редактора сообщений, кнопка <>

Изменено пользователем Артемон
Ссылка на комментарий
Поделиться на другие сайты

Надо temp разделить на 4, и будет правильная температура

добавил строку temp /= 4; , теперь при нуле градусов на датчике, на экране показывает 24 градуса, но уже при изменении температуры на датчике на 1 градус она меняется соответственно на 1 градус на экране

Не знаю правильно это или нет но я добавил еще такую строку temp -=24; теперь отсчет температуры от нуля соответствует норме

Ссылка на комментарий
Поделиться на другие сайты

Сравнительное тестирование аккумуляторов EVE Energy и Samsung типоразмера 18650

Инженеры КОМПЭЛ провели сравнительное тестирование аккумуляторов EVE и Samsung популярного для бытовых и индустриальных применений типоразмера 18650. 

Для теста были выбраны аккумуляторы литий-никельмарганцевой системы: по два образца одного наименования каждого производителя – и протестированы на двух значениях тока разряда: 0,5 А и 2,5 А. Испытания проводились в нормальных условиях на электронной нагрузке EBD-USB от ZKEtech, а зарядка осуществлялась от лабораторного источника питания в режиме CC+CV в соответствии с рекомендациями в даташите на определенную модель. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Осталось написать функцию для корректировки погрешности.

Вот что теперь выдает термометр: (слева температура на датчике, справа температура на экране)

100 = 100

200 = 198

300 = 297

400 = 399

500 = 503

600 = 606

700 = 709

800 = 810

900 = 908

В принципе мне этой точности достаточно, но если у кого есть идеи буду рад

Ссылка на комментарий
Поделиться на другие сайты

Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре. 

Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств. Подробнее параметры и результаты тестов новой серии PLM по ссылке.

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Проверь в свойствах мах6675 температуру холодного спая.

PS ЕМНИП, она идет как "окружающая температура".

Errare humanum est. Коли людЯм позволено, что же о нас то говорить!
 

Ссылка на комментарий
Поделиться на другие сайты

Литиевые батарейки и аккумуляторы от мирового лидера  EVE в Компэл

Компания Компэл, официальный дистрибьютор EVE Energy, бренда №1 по производству химических источников тока (ХИТ) в мире, предлагает продукцию EVE как со склада, так и под заказ. Компания EVE широко известна в странах Европы, Америки и Юго-Восточной Азии уже более 20 лет. Недавно EVE была объявлена поставщиком новых аккумуляторных элементов круглого формата для электрических моделей «нового класса» компании BMW.

Продукция EVE предназначена для самого широкого спектра применений – от бытового до промышленного. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Ну да. В симуляторе, ставится вручную. А температура на термопаре, высчитывается с учетом коррекции ХС.

Errare humanum est. Коли людЯм позволено, что же о нас то говорить!
 

Ссылка на комментарий
Поделиться на другие сайты

я добавил еще такую строку temp -=24; теперь отсчет температуры от нуля соответствует норме

Вычитать 24 градуса нужно, видимо, только для симулятора. Для реального устройства в железе вычитать не нужно, т.к. микросхема MAX6675 сама будет учитывать температуру холодного спая и выдавать уже готовый правильный результат.

Ссылка на комментарий
Поделиться на другие сайты

Она и в симуляторе будет в корректироваться, только внести в свойства элементов и всё.

Errare humanum est. Коли людЯм позволено, что же о нас то говорить!
 

Ссылка на комментарий
Поделиться на другие сайты

я добавил еще такую строку temp -=24; теперь отсчет температуры от нуля соответствует норме

Вычитать 24 градуса нужно, видимо, только для симулятора. Для реального устройства в железе вычитать не нужно, т.к. микросхема MAX6675 сама будет учитывать температуру холодного спая и выдавать уже готовый правильный результат.

Судя по всему так и есть, так как в протеусе на MAX6675 стояла температура холодного спая +25гр, переписал на 0гр и она соответственно изменилась, так что строка temp -=24; я убираю

Ссылка на комментарий
Поделиться на другие сайты

Это вряд ли. Когда то, разбирался с этой МС. На низком уровне в протезе, она выдает всё точно. Видимо, ошибки в программе обработки.

Errare humanum est. Коли людЯм позволено, что же о нас то говорить!
 

Ссылка на комментарий
Поделиться на другие сайты

После того, как выставил в протеусе температуру холодного спая на 0 и убрал строку temp -=24;

0гр определяет как 0

1 градус определяет как 0

2 градуса как 1

и дальше

100=99

200=197

300=296

400=398

и т.д.

Ссылка на комментарий
Поделиться на другие сайты

Мне кажется что ошибка в блоке uint16_t gettemp(void), попробую поискать чтото подобное

Я в этом всем новичек так что не пинайте сильно, для меня эта осцилограмма как 100 баксов для бабуина :)

post-196956-0-98109600-1451741414_thumb.jpg

Ссылка на комментарий
Поделиться на другие сайты

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

Errare humanum est. Коли людЯм позволено, что же о нас то говорить!
 

Ссылка на комментарий
Поделиться на другие сайты

Нашел в поисковике альтернативный вариант кода, дает точно такой же результат как и в первом коде

#define F_CPU 1000000UL

#include <inttypes.h>
#include <avr/io.h>
#include <stdlib.h>
#include <util/delay.h>
//#include <avr/pgmspace.h>

#include "MAX6675.h"
#include "LCD.h"



/*************************************************************************
Read the temperature Value
Input:	none
Returns: 0xFFFF: ERROR
	 else: Temperatur Value * 4 [°C]
*************************************************************************/
uint16_t MAX6675ReadTemp(void)
{
uint16_t tempRead;
uint8_t valRead;

// pull SS Line low
SPI_PORT &= ~(1<<SS_BIT);

// start SPI data transfer
SPDR = 0x00;

// wait for transmision complete
while(!(SPSR & (1<<SPIF)))
; // do nothing

// copy hi byte
valRead = SPDR;


// start SPI data transfer
SPDR = 0x00;

// shift hi-byte
tempRead = valRead << 5;

// wait for transmision complete
while(!(SPSR & (1<<SPIF)))
; // do nothing

// copy hi byte
valRead = SPDR;
valRead &= 0b11111000;
valRead >>= 3;

tempRead |= valRead;

// pull SS Line hi
SPI_PORT |= (1<<SS_BIT);


return tempRead;
}


/*************************************************************************
* Initialize the SPI Port to communicate with MAX6675
* Input:	none
* Returns: none
************************************************************************/
void MAX6675Init(void)
{
//volatile char IOReg;

// set /SS, MOSI, SCK as output
SPI_DDR |= (1<<SS_BIT)|(1<<MOSI_BIT)|(1<<SCK_BIT);
// enable SPI in Master Mode with SCK = CK/128
SPCR = (1<<SPE)|(1<<MSTR)|(1<<CPHA)|(1<<SPR0)|(1<<SPR1);

//IOReg = SPSR;				 // clear SPIF bit in SPSR
//IOReg = SPDR;
}

int main(void)
{
init_port();// инициализируем порт ЖКИ
lcd_init();// инициализируем ЖКИ
MAX6675Init();



while (1)
{
char buffer[8];
int temp;
temp = MAX6675ReadTemp();
temp /= 4;


lcd_gotoxy(0,0);//перемещаем курсор в верхний левый угол
sprintf(buffer, "t=%i\xdf\C ", temp); // так как тут не плавающая запятая то числа с запятой записываются так %i.%i, код градуса записывается так \xdf
lcd_putstring(buffer);
}


}

Изменено пользователем Артемон
Ссылка на комментарий
Поделиться на другие сайты

В общем выставил температуру холодного спая на MAX6675 в протеусе на +1 градус, теперь отсчет начинается правильно

Тоесть 0гр на датчике соответствует 0гр на экране

Без погрешности все идет до 163гр на датчике

Ну и далее такие показатели:

200 = 198

300 = 297

400 = 399

500 = 503

600 = 606

700 = 709

800 = 810

900 = 908

Осцилограмма немного изменилась, но я по прежнему в ней не разобрался

post-196956-0-22791900-1451751997_thumb.jpg

Ссылка на комментарий
Поделиться на другие сайты

В даташите рисунке 1а и b и есть эти осциллограммы. Вычлени 12 бит данных, цена бита 0.25 градусов, перемножь получится температура. .

Errare humanum est. Коли людЯм позволено, что же о нас то говорить!
 

Ссылка на комментарий
Поделиться на другие сайты

Дело тут не в SPI, мне кажется. Вот пример из Гугла для симуляции термопары. Надо тоже вывод CJ как-то задейстовать: заземлить, например, для 0 градусов окружающего.

Изменено пользователем Yurkin2015
Ссылка на комментарий
Поделиться на другие сайты

Дело тут не в SPI, мне кажется. Вот пример из Гугла для симуляции термопары. Надо тоже вывод CJ как-то задейстовать: заземлить, например, для 0 градусов окружающего.

Пробовал повторять, индикатор показывает 0

Я тоже думаю что дело не в SPI так как 2 разные прошивки дают один результат.

Думаю что в реальных условиях значения будут нормальные, так что будем считать тему закрытой, всем спасибо.

Ссылка на комментарий
Поделиться на другие сайты

  • 4 месяца спустя...

Привет, я преобразую в температуру так:

float cl_MAX6675::ConvertDataToFloat(unsigned short tData)

{

float tRez;

unsigned short a, b;

tData = tData >> 3;

b = tData & 0x0003;

tRez = tData >> 2;

for(a = 0; a < b; a++) tRez = tRez + 0.25;

return tRez;

}

передаваемый параметр в функцию это данные считанные с микросхемы.

Ссылка на комментарий
Поделиться на другие сайты

  • 3 недели спустя...

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

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...