Внутренний температурный датчик на Atmega328p-XX - Тестовый скетч
Добавлено: 25 май 2018, 13:26
Приветствую!!!
Бывают ситуации когда места на плате катастрофически не хватает или ситуации когда нужна температура устройства а внешнего датчика по тем или иным причинам поставить не получается, ну или например когда нет датчика температуры а очень хочется быстренько собрать температурную уличную ноду(даташит этого не запрещает, я бы сказал даже что рекомендует когда это надо))). Выкладываю тестовый скетч для внутреннего температурного датчика.
Как настрен датчик:
Датчик работает на таймере1, таймер настроен на прерывание раз в секунду. В функции срабатывающей при прерывании находится счетчик который отсчитывает 10 секунд и делает проверку температуры, если она меняется то сразу идет отправка на контролер. Если не меняется то включается второй счетчик который отсчитывает 6 раз по 10 секунд и делает обязательную отправку на контролер.Считывание опирается на внутренний опорник на 1.1в. При изменении опорного на другое надо пересчитать формулу, кому надо напишите, у меня есть пересчет и под 3.3в и под 5в.
В скетче выведены сенсоры:
Сам сенсор температуры
Сенсор установки верхнего порога температуры
Сенсор интервала обязательной отправки, шаг одна минуты(на новой ноде стоит значение в 255 минут)
Сенсор тревоги, передает единицу на контролер если значение температуры вышло за заданный порог, и соответственно ноль, когда значение вернулось в норму.
Кое что в скетче закомментированно, но это особенность моей платы(на ней есть биззер и светодиод для индикации обмена, тревоги и тп)
Вроде бы все..
Сам скетч:
Бывают ситуации когда места на плате катастрофически не хватает или ситуации когда нужна температура устройства а внешнего датчика по тем или иным причинам поставить не получается, ну или например когда нет датчика температуры а очень хочется быстренько собрать температурную уличную ноду(даташит этого не запрещает, я бы сказал даже что рекомендует когда это надо))). Выкладываю тестовый скетч для внутреннего температурного датчика.
Как настрен датчик:
Датчик работает на таймере1, таймер настроен на прерывание раз в секунду. В функции срабатывающей при прерывании находится счетчик который отсчитывает 10 секунд и делает проверку температуры, если она меняется то сразу идет отправка на контролер. Если не меняется то включается второй счетчик который отсчитывает 6 раз по 10 секунд и делает обязательную отправку на контролер.Считывание опирается на внутренний опорник на 1.1в. При изменении опорного на другое надо пересчитать формулу, кому надо напишите, у меня есть пересчет и под 3.3в и под 5в.
В скетче выведены сенсоры:
Сам сенсор температуры
Сенсор установки верхнего порога температуры
Сенсор интервала обязательной отправки, шаг одна минуты(на новой ноде стоит значение в 255 минут)
Сенсор тревоги, передает единицу на контролер если значение температуры вышло за заданный порог, и соответственно ноль, когда значение вернулось в норму.
Кое что в скетче закомментированно, но это особенность моей платы(на ней есть биззер и светодиод для индикации обмена, тревоги и тп)
Вроде бы все..
Сам скетч:
Код: Выделить всё
#define MY_RADIO_RF24
#define MY_DEBUG
#define CHILD_ID_INTTEMP 20
#define CHILD_ID_INTTEMP_TOP 21
#define CHILD_ID_INTTEMP_INTERVAL 22
#define CHILD_ID_TEMP_ALERT 30
//#define TONE_PIN 5
//#define BLUE_LED A4
bool flagIntTemp = true;
bool tempAlert = false;
bool flagsend_timer1 = false;
bool flagAlert = false;
bool flagSendAlertOn = true;
bool flagSendAlertOff = true;
int8_t intTemp;
int8_t intTempOld;
uint8_t counter_intTemp = 0;
uint8_t intTempMem;
uint8_t intTempTop;
uint8_t counter_timer = 0;
uint32_t alert_time = 0;
#include <MySensors.h>
MyMessage intTempMsg(CHILD_ID_INTTEMP, V_TEMP);
MyMessage intTempTopMsg(CHILD_ID_INTTEMP_TOP, V_VAR1);
MyMessage intTempIntervalMsg(CHILD_ID_INTTEMP_INTERVAL, V_VAR1);
MyMessage tempAlertMsg(CHILD_ID_TEMP_ALERT, V_VAR1);
void preHwInit()
{
}
void before()
{
TCCR1A = 0;
TCCR1B = (1 << WGM12) | (1 << CS10) | (0 << CS11) | (1 << CS12);
OCR1A = 7812; // 1 секунда, верхняя граница счета, диапазон от 0 до 65535.
TIMSK1 |= (1 << OCIE1A); // прерывание по совпадению
intTempMem = loadState(200);
intTempTop = loadState(201);
if ((intTempTop < 30) || (intTempTop > 75)) {
intTempTop = 65;
saveState(201, intTempTop);
}
}
void presentation()
{
sendSketchInfo("INTERNAL TEMPERATURE", "1.01");
wait(50);
present(CHILD_ID_INTTEMP, S_TEMP, "Internal Temperature");
present(CHILD_ID_INTTEMP_TOP, S_CUSTOM, "IntTemp Upper Limit");
wait(50);
present(CHILD_ID_INTTEMP_INTERVAL, S_CUSTOM, "IntTemp Interval/min");
present(CHILD_ID_TEMP_ALERT, S_CUSTOM, "Int Temp Alert");
}
void setup() {
intTemp = GetIntTemp();
intTempOld = intTemp;
send(intTempMsg.set(intTemp), true);
wait(500, C_SET, V_TEMP );
send(intTempTopMsg.set(intTempTop), true);
wait(500, C_SET, V_VAR1 );
send(intTempIntervalMsg.set(intTempMem), true);
wait(500, C_SET, V_VAR1 );
send(tempAlertMsg.set(tempAlert), true);
wait(500, C_SET, V_VAR1 );
counter_timer = 0;
counter_intTemp = 0;
}
void loop()
{
if (flagsend_timer1 == true) {
flagsend_timer1 = false;
send(intTempMsg.set(intTemp), true);
wait(500, C_SET, V_TEMP );
}
if (flagAlert == true) {
if (flagSendAlertOn == false) {
flagSendAlertOn = true;
send(tempAlertMsg.set(tempAlert), true);
wait(500, C_SET, V_VAR1 );
}
//if (millis() - alert_time > 1000 * 5) {
//alert();
//}
} else {
if (flagSendAlertOff == false) {
flagSendAlertOff = true;
send(tempAlertMsg.set(tempAlert), true);
wait(500, C_SET, V_VAR1 );
}
}
}
void receive(const MyMessage & message) {
if (mGetCommand(message) == C_SET) {
if (message.sensor == CHILD_ID_INTTEMP) {
if (message.type == V_TEMP) {
if (message.isAck()) {
//indicator1();
}
}
}
if (message.sensor == CHILD_ID_INTTEMP_TOP) {
if (message.type == V_VAR1) {
if (message.isAck()) {
//indicator2();
} else {
intTempTop = message.getByte();
if ((intTempTop < 30) || (intTempTop > 75)) {
intTempTop = 65;
saveState(201, 65);
} else {
saveState(201, intTempTop);
}
send(intTempTopMsg.set(intTempTop), true);
wait(3000, C_SET, V_VAR1 );
}
}
}
if (message.sensor == CHILD_ID_INTTEMP_INTERVAL) {
if (message.type == V_VAR1) {
if (message.isAck()) {
//indicator2();
} else {
if (message.getInt() > 255) {
intTempMem = 255;
saveState(200, 255);
} else {
intTempMem = message.getInt();
saveState(200, intTempMem);
}
send(intTempIntervalMsg.set(intTempMem), true);
wait(3000, C_SET, V_VAR1 );
}
}
}
if (message.sensor == CHILD_ID_TEMP_ALERT) {
if (message.type == V_VAR1) {
if (message.isAck()) {
//indicator2();
}
}
}
}
}
ISR (TIMER1_COMPA_vect)
{
counter_timer++;
if (counter_timer == 10) {
counter_intTemp++;
intTemp = GetIntTemp();
if (intTemp >= intTempTop) {
if (flagAlert == false) {
flagAlert = true;
flagSendAlertOn = false;
tempAlert = true;
}
}
if (intTemp < intTempTop) {
if (flagAlert == true) {
flagAlert = false;
flagSendAlertOff = false;
tempAlert = false;
}
}
if (counter_intTemp < intTempMem * 6) { // интервал вывода, кратность х1мин (6х10=60 сек)
if (intTemp != intTempOld) {
//Serial.println(intTemp);
intTempOld = intTemp;
counter_intTemp = 0;
flagsend_timer1 = true;
}
flagIntTemp = true;
}
if ((counter_intTemp == intTempMem * 6) && (intTempMem * 6 > 0)) {
//Serial.println(intTemp);
counter_intTemp = 0;
intTempOld = intTemp;
flagIntTemp = true;
flagsend_timer1 = true;
}
if (intTempMem * 6 == 0) {
counter_intTemp = 0;
}
counter_timer = 0;
}
}
int GetIntTemp(void)
{
unsigned int wADC;
unsigned long utemp = 0;
float t;
int t2;
ADMUX = (_BV(REFS1) | _BV(REFS0) | _BV(MUX3));
ADCSRA |= _BV(ADEN);
delay(10);
for (int i = 0; i < 100; i++) {
ADCSRA |= _BV(ADSC);
while (bit_is_set(ADCSRA, ADSC));
wADC = ADCW;
utemp += wADC;
}
t = (((float)utemp / 100) - 324.31 ) / 1.22;
t2 = round(t);
utemp = 0;
return (t2);
}
/*
void indicator1() {
digitalWrite(BLUE_LED, true);
delay(50.0);
digitalWrite(BLUE_LED, false);
}
void indicator2() {
digitalWrite(BLUE_LED, true);
tone(TONE_PIN, 1318, 100.0);
delay(50.0);
tone(TONE_PIN, 329, 30.0);
delay(50.0);
tone(TONE_PIN, 1318, 50.0);
digitalWrite(BLUE_LED, false);
}
void alert() {
tone(TONE_PIN, 195, 150.0);
delay(150.0);
tone(TONE_PIN, 659, 150.0);
delay(150.0);
tone(TONE_PIN, 659, 150.0);
delay(150.0);
tone(TONE_PIN, 659, 150.0);
delay(150.0);
tone(TONE_PIN, 329, 150.0);
alert_time = millis();
}
*/