Внутренний температурный датчик на Atmega328p-XX - Тестовый скетч

О программировании Arduino, использование библиотек, примеры и общие вопросы программирования.
Ответить
Berk
Сообщения: 81
Зарегистрирован: 11 окт 2017, 22:05

Внутренний температурный датчик на Atmega328p-XX - Тестовый скетч

Сообщение Berk »

Приветствую!!!

Бывают ситуации когда места на плате катастрофически не хватает или ситуации когда нужна температура устройства а внешнего датчика по тем или иным причинам поставить не получается, ну или например когда нет датчика температуры а очень хочется быстренько собрать температурную уличную ноду(даташит этого не запрещает, я бы сказал даже что рекомендует когда это надо))). Выкладываю тестовый скетч для внутреннего температурного датчика.
Как настрен датчик:
Датчик работает на таймере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();
  }

*/
cabat
Сообщения: 6
Зарегистрирован: 09 янв 2018, 10:08

Re: Внутренний температурный датчик на Atmega328p-XX - Тестовый скетч

Сообщение cabat »

Я так понимаю, используется внутренний датчик температуры ATmega328?
А, сорри, я похоже невнимательно прочитал заголовок сообщения :)
Berk
Сообщения: 81
Зарегистрирован: 11 окт 2017, 22:05

Re: Внутренний температурный датчик на Atmega328p-XX - Тестовый скетч

Сообщение Berk »

ну да :)
>>Re: Внутренний температурный датчик на Atmega328p-XX - Тестовый скетч
Ответить