DS18B20 промаргивают показания

Niklog78
Offline
Зарегистрирован: 07.04.2016

Здравствуйте, проблемка такая - собрал контроллер на меге для ректификации изначально было 2 датчика ds18b20 показания выводтлись на 7сигментный дисплей, стал замечать, что иногда моргнет-паропадет показание и все нормально дальше. Сейчас у меня 4 датчика динна кабеля 2 метра, подключение обычное, библиотека даллас и оневаре, раньше грешил на датчик, ну может не пропай где. сей час замечаю, что промаргивают все датчики переодически... конечно это не критично, но немножко не приято, даже не знаю как это устранить.

T.Rook
Offline
Зарегистрирован: 05.03.2016

недавно была тема "ds18b20 ведет себя непонятно" - посмотрите, может и Ваш случай

bwn
Offline
Зарегистрирован: 25.08.2014

Для начала скетч в студию. Для этих датчиков 2 метра вообще ни о чем.

Niklog78
Offline
Зарегистрирован: 07.04.2016
// подключаем библиотеки
// ... они должны лежать в папке libraries
#include <LiquidCrystal_I2C.h>
#include <OneWire.h>            // для обмена по 1-wire
#include <EEPROM.h>             // для работы с EEPROM 
#include <DallasTemperature.h>  // для работы с 18B20
#include "TM1637.h"

byte butPush = 0;           // код нажатой кнопки
byte menu = 0;              // переменная хранящая номер текущего экрана
byte qty;                   // количество градусников на шине.
float OUTKOL;               // температура задания КОЛОННЫ
float OUTKUBS;              // температура задания КУБА сигнализация перехода
float OUTKUB;               // температура задания КУБА
byte NAGREV;                // температура сигнализации закипания куба
byte TRIAC;                 // температура задания симистора
byte KOND;                  // температура задания конденсатора
float tempSensorKOL;        // температура КОЛОННЫ
float tempSensorKUB;        // температура КУБА
int tempSensorTR;           // температура триака
int tempSensorKNC;          // температура конденсатора
float HISTR;                // Гистерезис
int flag1 = 0;
int flag2 = 0;
int flag3 = 0;

#define CLKKL 8
#define DIOKL 7                 //пины подключения 7сегментного модуля ТМ1637
TM1637 tm1637KL(CLKKL, DIOKL);   //для показа температуры колонны

#define CLKKB 6
#define DIOKB 5                 //пины подключения 7сегментного модуля ТМ1637
TM1637 tm1637KB(CLKKB, DIOKB);   //для показа температуры куба

#define PIN_KOL 10          // номер выхода реле КОЛОННА
#define PIN_SOUND 4        // номер выхода Пищалки
#define PIN_SOUND2 3
#define LED_GR 22   //зеленый      
#define LED_BL 25   //синий
#define LED_RD 24   //красный  // номера пинов светодиодов
#define LED_EL 23   //жёлтый
#define LED_WT 26   //белый
#define PIN_DOWN 28         // пины кнопок
#define PIN_LEFT 30
#define PIN_SELECT 32
#define PIN_RIGHT 34
#define PIN_UP 36
#define KEY_6 38             //отключение сигнализации кнопка
#define KEY_7 40
#define TU_BL 46
#define TU_AUT_HAND 42       //тумблер АВТ/РУЧ режим
#define TU_ON_OFF 44         //тумблер ВКЛ/ОТКЛ клапан
#define  INTERVAL 500UL      //задержка мигания светодиода
#define PIN_ALARM 12         //пин выхода реле пищалки 12в
#define PIN_OBDUV 11         //пин выхода реле вентиляторов
#define PIN_UZO 9            //пин входа с реле контроля УЗО

// адреса градусников.
DeviceAddress sensor1 = {0x28, 0xFF, 0xA5, 0x3A, 0xA1, 0x15, 0x3, 0x56};
DeviceAddress sensor2 = {0x28, 0xFF, 0x7D, 0x39, 0xA1, 0x15, 0x3, 0xBE};
DeviceAddress sensor3 = {0x28, 0xFF, 0xA5, 0x3A, 0xA1, 0x15, 0x3, 0x00};
DeviceAddress sensor4 = {0x28, 0xFF, 0xA5, 0x3A, 0xA1, 0x15, 0x3, 0x00};

OneWire  oneWire(15);                      // на этот пин подключены DS18B20
#define TEMPERATURE_PRECISION 11           // разрядность ds18b20
LiquidCrystal_I2C lcd(0x3F, 20, 4);        // адрес и колво строк лсд шилда
DallasTemperature ds(&oneWire);

// значек градуса
byte gradus[8] = {
  0b00110,
  0b01001,
  0b01001,
  0b00110,
  0b00000,
  0b00000,
  0b00000,
  0b00000
};

// функция останавливает работу программы и сигнализирует ошибку
void erorr() {
  lcd.clear();
  lcd.print("SENSOR ERROR");
}

// функция показа версии скетча при загрузке
void versiya() {
  lcd.clear();
  lcd.print("Progg VER 1.3");
  delay (1500);
  tone(PIN_SOUND, 800, 500); 
}

void music1() {
  tone(PIN_SOUND, 800, 500);
}

void getTemp() { // читаем температуру и заполняем массив
  ds.requestTemperatures();
  tempSensorKOL = ds.getTempC(sensor1); // немного китайского кода
  tempSensorKUB = ds.getTempC(sensor2);
  tempSensorTR = ds.getTempC(sensor3);
  tempSensorKNC = ds.getTempC(sensor4);
}

void sensorTest() { // ищим датчики на шине, если количество изменилось, останавливаем работу
  ds.begin();
  if (ds.getDeviceCount() != qty) erorr();
}
// функция вывода температуры колонны на ТМ1637
void KLLCD() {
  int8_t Digits[] = {0x00, 0x00, 0x00, 0x00};
  int KL1 = tempSensorKOL;
  int KL2 = (tempSensorKOL - KL1) * 100;
  if (KL1 > 99)(KL1 = tempSensorKOL - 100);
  tm1637KL.point(POINT_ON);
  Digits[0] = (KL1 / 10); // раскидываем 4-значное число на цифры
  Digits[1] = (KL1 % 10);
  Digits[2] = (KL2 / 10);
  Digits[3] = (KL2 % 10);
  tm1637KL.display(Digits);
}
// функция вывода температуры куба на ТМ1637
void KBLCD() {
  int8_t Digits[] = {0x00, 0x00, 0x00, 0x00};
  int KB1 = tempSensorKUB;
  int KB2 = (tempSensorKUB - KB1) * 100;
  if (KB1 > 99)(KB1 = tempSensorKUB - 100);
  tm1637KB.point(POINT_ON);
  Digits[0] = (KB1 / 10); // раскидываем 4-значное число на цифры
  Digits[1] = (KB1 % 10);
  Digits[2] = (KB2 / 10);
  Digits[3] = (KB2 % 10);
  tm1637KB.display(Digits);
}

void ALARM() {
  static unsigned long previousMillis = 0;        // храним время последнего переключения светодиода
  digitalWrite(LED_RD, HIGH);                     // всключаем красный мигающирй светодиод
  // включаем выход аварийной пищалки и пищим с перыванием
  if (millis() - previousMillis > INTERVAL) {
    previousMillis = millis();
    digitalWrite(PIN_ALARM, !digitalRead(PIN_ALARM));
  }
}

void setup() {
  ds.begin();

  // количество датчиков на шине
  qty = 2;

  NAGREV = EEPROM.read(1);
  OUTKOL = EEPROM.read(2);      // читаем настройки
  OUTKUBS = EEPROM.read(3);     // из еепром
  OUTKUB = EEPROM.read(4);
  HISTR = EEPROM.read(5);
  KOND = EEPROM.read(6);

  tm1637KL.init();
  tm1637KL.set(BRIGHT_TYPICAL);//BRIGHT_TYPICAL = 2,BRIGHT_DARKEST = 0,BRIGHTEST = 7;
  tm1637KB.init();
  tm1637KB.set(BRIGHT_TYPICAL);//BRIGHT_TYPICAL = 2,BRIGHT_DARKEST = 0,BRIGHTEST = 7;

  pinMode(PIN_KOL, OUTPUT);  //назначаем входа выхода пинам
  pinMode(LED_GR, OUTPUT);
  pinMode(LED_BL, OUTPUT);
  pinMode(LED_RD, OUTPUT);
  pinMode(LED_EL, OUTPUT);
  pinMode(LED_WT, OUTPUT);
  pinMode(PIN_DOWN, INPUT);
  pinMode(PIN_LEFT, INPUT);
  pinMode(PIN_SELECT, INPUT);
  pinMode(PIN_RIGHT, INPUT);
  pinMode(PIN_UP, INPUT);
  pinMode(KEY_6, INPUT);
  pinMode(KEY_7, INPUT);
  pinMode(TU_BL, INPUT);
  pinMode(TU_AUT_HAND, INPUT);
  pinMode(TU_ON_OFF, INPUT);
  pinMode(PIN_ALARM, OUTPUT);
  pinMode(PIN_OBDUV, OUTPUT);
  pinMode(PIN_UZO, INPUT);
  pinMode(PIN_SOUND, OUTPUT);
  pinMode(PIN_SOUND2, OUTPUT);

  lcd.createChar(1, gradus);    // значек градуса
  lcd.begin();                  // инициализация ЛСД дисплея
  lcd.clear();                  // очищаем экран
  Serial.begin(9600);           // последовательный порт для отладки

  versiya(); //бибикаем при включении
}

// главный цикл. Когда программа доходит до конца, выполнение переходит к этой строке
void loop() {

  //sensorTest();                          // тест наличия градусников на шине
  getTemp();                             // читаем температуру с датчиков

  // Сигнализация перехода
  if (tempSensorKUB >= OUTKUBS && flag1 == 0 || tempSensorKOL >= NAGREV && flag3 == 0) {
    digitalWrite(LED_RD, HIGH);
    tone(PIN_SOUND, 1500, 500);
  }
  // Сигнализация аварии и окончания процесса
  if (tempSensorKUB >= OUTKUB && flag2 == 0 || tempSensorKNC >= KOND) {
    ALARM();
  }
  // Включаем обдув симистора
  if (tempSensorTR >= TRIAC){
  digitalWrite(PIN_OBDUV, HIGH);
  }
  else digitalWrite(PIN_OBDUV, LOW);
  
  // сброс аварии
  if (digitalRead(KEY_6) == HIGH) SBROS();

  if (digitalRead(PIN_SOUND) == HIGH){
    digitalWrite(PIN_SOUND2, HIGH);
  }
    else digitalWrite(PIN_SOUND2, LOW);

  if (button > 0) Menu(button ());
  // Включение автоматического или ручного режима
  if (digitalRead(TU_AUT_HAND) == HIGH) AUTOMAT();
  else HAND();

  KLLCD();  //показываем температуру колонны на ТМ1637
  KBLCD();  //показываем температуру куба на ТМ1637
  Menu(0);  // собственно больше делать нечего. показываем юзеру картинку (меню) (ниже)
}

//
// функция автоматического режима
void AUTOMAT() {
  if (digitalRead(KEY_6) == HIGH) digitalWrite(LED_EL, LOW);
  else digitalWrite(LED_EL, HIGH);
  if (tempSensorKOL > (OUTKOL + HISTR) || tempSensorKUB >= OUTKUB) {
    digitalWrite(PIN_KOL, LOW);
    digitalWrite(LED_BL, HIGH);
    digitalWrite(LED_GR, LOW);
  }
  if (tempSensorKOL <= OUTKOL && tempSensorKUB < OUTKUB) {
    digitalWrite(PIN_KOL, HIGH);
    digitalWrite(LED_BL, LOW);
    digitalWrite(LED_GR, HIGH);
  }
}

// функция ручного режима
void HAND() {
  if (digitalRead(KEY_6) == HIGH) digitalWrite(LED_EL, HIGH);
  else digitalWrite(LED_EL, LOW);
  if (digitalRead(TU_ON_OFF) == HIGH) {
    digitalWrite(PIN_KOL, HIGH);
    digitalWrite(LED_GR, HIGH);
    digitalWrite(LED_BL, LOW);
  }

  if (digitalRead(TU_ON_OFF) == LOW) {
    digitalWrite(PIN_KOL, LOW);
    digitalWrite(LED_BL, HIGH);
    digitalWrite(LED_GR, LOW);
  }
}

// Функция отключения сигнализации
void SBROS() {
  digitalWrite(LED_RD, LOW);
  if (tempSensorKOL >= NAGREV) flag3 = 1;
  if (tempSensorKUB >= OUTKUBS) flag1 = 1;
  if (tempSensorKUB >= OUTKUB) flag2 = 1;
}

// функция обработки кнопок
int button() {
  butPush = 0;
  if (digitalRead(PIN_SELECT) == HIGH) {
    butPush = 3;
    tone(PIN_SOUND, 1000, 100);

  }
  if (digitalRead(PIN_UP) == HIGH) {
    tone(PIN_SOUND, 800, 100);
    butPush = 1;
  }
  if (digitalRead(PIN_DOWN) == HIGH) {
    tone(PIN_SOUND, 700, 100);
    butPush = 5;
  }
  if (digitalRead(PIN_RIGHT) == HIGH) {
    tone(PIN_SOUND, 600, 100);
    butPush = 4;
  }
  if (digitalRead(PIN_LEFT) == HIGH) {
    tone(PIN_SOUND, 500, 100);
    butPush = 2;
  }
  return butPush;
}

void Menu(int butPush) {        // самая мутная но и самая интересная часть. Фунцция показа меню
  lcd.clear();                  // очищаем дисплей
  switch (menu) {               // оператор switch переключает на нужную секцию в зависимости от значения menu

    case 0:
      lcd.setCursor(7, 0);
      lcd.print("ZADANIJA");
	  lcd.setCursor(0, 1);
      lcd.print("KL_");
	  lcd.print(OUTKOL);
	  lcd.setCursor(9, 1);
	  lcd.print("Histeres_");
	  lcd.print(HISTR);
	  lcd.setCursor(0, 2);
	  lcd.print("Nagrev_");
	  lcd.print(NAGREV);
	  lcd.setCursor(11, 2);
	  lcd.print("KUBsg_");
	  lcd.print(OUTKUBS);
	  lcd.setCursor(0, 3);
	  lcd.print("t");
	  lcd.print(1);
	  lcd.setCursor(3, 3);
	  lcd.print("Triac_");
	  lcd.print(TRIAC);
	  lcd.setCursor(12, 3);
	  lcd.print("t");
	  lcd.print(1);
	  lcd.setCursor(14, 3);
	  lcd.print("Kond_");
	  lcd.print(KOND);
     
      if (butPush == 3) {
        menu = 1;  // если нажать "SELECT" выйдем в меню настроек
        Menu(0);
      }

      break;

    case 1: // задание сигнализации нагрева

      lcd.setCursor(4, 0);
      lcd.print("Zadanie NAGREV");
      lcd.setCursor(0, 2);
      lcd.print("<<-");
      lcd.setCursor(19, 2);
      lcd.print("+>>");
      lcd.setCursor(10, 2);
      lcd.print(NAGREV);

      if (butPush == 2) { // если нажата кнопка LEFT значение -
        NAGREV--;
        if (NAGREV > 100) NAGREV = 0;
        EEPROM.write(1, NAGREV); // сохраняем в еепром
      }
      else if (butPush == 4) {  // если нажата кнопка RIGHT значение +
        NAGREV++;
        if (NAGREV > 100) NAGREV = 0;
        EEPROM.write(1, NAGREV);
      }

      if (butPush == 1) {
        menu--;
        Menu(0);
      }
      if (butPush == 3) {
        menu = 0;
        Menu(0);
      }
      if (butPush == 5) {
        menu++;
        Menu(0);
      }
      break;


    case 2: // Задание температуры для КОЛОННЫ

      lcd.setCursor(3, 0);
      lcd.print("Zadanie KOLONNA");
      lcd.setCursor(0, 2);
      lcd.print("<<-");
      lcd.setCursor(19, 2);
      lcd.print("+>>");
      lcd.setCursor(10, 2);
      lcd.print(OUTKOL);

      if (butPush == 2) { // если нажата кнопка LEFT значение -
        OUTKOL = OUTKOL - 0.1;
        if (OUTKOL > 125) OUTKOL = 0;
        EEPROM.write(2, OUTKOL); // сохраняем в еепром
      }
      else if (butPush == 4) {  // если нажата кнопка RIGHT значение +
        OUTKOL = OUTKOL + 0.1;
        if (OUTKOL > 125) OUTKOL = 0;
        EEPROM.write(2, OUTKOL);
      }

      if (butPush == 1) {
        menu--;
        Menu(0);
      }
      if (butPush == 3) {
        menu = 0;
        Menu(0);
      }
      if (butPush == 5) {
        menu++;
        Menu(0);
      }
      break;

    case 3: // Задание температуры для КУБА сигнализация перехода

      lcd.setCursor(1, 0);
      lcd.print("Zadanie KUB_Signal");
      lcd.setCursor(0, 2);
      lcd.print("<<-");
      lcd.setCursor(19, 2);
      lcd.print("+>>");
      lcd.setCursor(10, 2);
      lcd.print(OUTKUBS);

      if (butPush == 2) { // если нажата кнопка LEFT значение -
        OUTKUBS--;
        if (OUTKUBS > 125) OUTKUBS = 0;
        EEPROM.write(3, OUTKUBS); // сохраняем в еепром
      }
      else if (butPush == 4) {  // если нажата кнопка RIGHT значение +
        OUTKUBS++;
        if (OUTKUBS > 125) OUTKUBS = 0;
        EEPROM.write(3, OUTKUBS);
      }

      if (butPush == 1) {
        menu--;
        Menu(0);
      }
      if (butPush == 3) {
        menu = 0;
        Menu(0);
      }
      if (butPush == 5) {
        menu++;
        Menu(0);
      }
      break;

    case 4: // Задание температуры для КУБА окончание работы

      lcd.setCursor(2, 0);
      lcd.print("Zadanie KUB_STOP");
      lcd.setCursor(0, 2);
      lcd.print("<<-");
      lcd.setCursor(19, 2);
      lcd.print("+>>");
      lcd.setCursor(10, 2);
      lcd.print(OUTKUB);

      if (butPush == 2) { // если нажата кнопка LEFT значение -
        OUTKUB--;
        if (OUTKUB > 125) OUTKUB = 0;
        EEPROM.write(4, OUTKUB); // сохраняем в еепром
      }
      else if (butPush == 4) {  // если нажата кнопка RIGHT значение +
        OUTKUB++;
        if (OUTKUB > 125) OUTKUB = 0;
        EEPROM.write(4, OUTKUB);
      }

      if (butPush == 1) {
        menu--;
        Menu(0);
      }
      if (butPush == 3) {
        menu = 0;
        Menu(0);
      }
      if (butPush == 5) {
        menu++;
        Menu(0);
      }
      break;

    case 5: // Задание Гистерезиса

      lcd.setCursor(6, 0);
      lcd.print("HISTERESIS");
      lcd.setCursor(0, 2);
      lcd.print("<<-");
      lcd.setCursor(19, 2);
      lcd.print("+>>");
      lcd.setCursor(10, 2);
      lcd.print(HISTR);

      if (butPush == 2) { // если нажата кнопка LEFT значение -
        HISTR = HISTR - 0.1;
        if (HISTR <= 0) HISTR = 0;
        EEPROM.write(5, HISTR); // сохраняем в еепром
      }
      else if (butPush == 4) {  // если нажата кнопка RIGHT значение +
        HISTR = HISTR + 0.1;
        if (HISTR > 10) HISTR = 0;
        EEPROM.write(5, HISTR);
      }

      if (butPush == 1) {
        menu--;
        Menu(0);
      }
      if (butPush == 3) {
        menu = 0;
        Menu(0);
      }
      if (butPush == 5) {
        menu++;
        Menu(0);
      }
      break;
	  
	  case 6: // Задание Конденсатора

      lcd.setCursor(1, 0);
      lcd.print("Zadanie Kondensator");
      lcd.setCursor(0, 2);
      lcd.print("<<-");
      lcd.setCursor(19, 2);
      lcd.print("+>>");
      lcd.setCursor(10, 2);
      lcd.print(KOND);

      if (butPush == 2) { // если нажата кнопка LEFT значение -
        KOND++;
        if (KOND <= 0) KOND = 0;
        EEPROM.write(6, KOND); // сохраняем в еепром
      }
      else if (butPush == 4) {  // если нажата кнопка RIGHT значение +
        KOND--;
        if (KOND > 100) KOND = 0;
        EEPROM.write(6, KOND);
      }

      if (butPush == 1) {
        menu--;
        Menu(0);
      }
      if (butPush == 3) {
        menu = 0;
        Menu(0);
      }
      if (butPush == 5) {
        menu++;
        Menu(0);
      }
      break;
	  
	  case 7: // Задание Симистора

      lcd.setCursor(4, 0);
      lcd.print("Zadanie Triac");
      lcd.setCursor(0, 2);
      lcd.print("<<-");
      lcd.setCursor(19, 2);
      lcd.print("+>>");
      lcd.setCursor(10, 2);
      lcd.print(TRIAC);

      if (butPush == 2) { // если нажата кнопка LEFT значение -
        TRIAC++;
        if (TRIAC <= 0) TRIAC = 0;
        EEPROM.write(7, TRIAC); // сохраняем в еепром
      }
      else if (butPush == 4) {  // если нажата кнопка RIGHT значение +
        TRIAC--;
        if (TRIAC > 100) TRIAC = 0;
        EEPROM.write(7, TRIAC);
      }

      if (butPush == 1) {
        menu--;
        Menu(0);
      }
      if (butPush == 3) {
        menu = 0;
        Menu(0);
      }
      if (butPush == 5) {
        menu++;
        Menu(0);
      }
      break;

    case 8: // Выход из меню. Комментировать не буду - надоело.
      lcd.print("EXIT");
      lcd.setCursor(0, 1);
      lcd.print("Press SELECT");
      if (butPush == 1) {
        menu = 7;
        Menu(0);
      }
      if (butPush == 3) {
        menu = 0;
        Menu(0);
      }
      if (butPush == 5) {
        menu = 1;
        Menu(0);
      }
      break;

  } // end switch

}

 

Niklog78
Offline
Зарегистрирован: 07.04.2016

Может если опращивать датчики с задержкой в 1.5 секунды к примеру, будет работать стабильнее?

T.Rook
Offline
Зарегистрирован: 05.03.2016

Niklog78 пишет:

Может если опращивать датчики с задержкой в 1.5 секунды к примеру, будет работать стабильнее?

Для начала я бы определился с корнем проблемы  - не успевают (тогда копать в сторону правильного опроса) или сбоят при опросе/выдаче (тогда определятся почему. начинать со стабильного питания).

bwn
Offline
Зарегистрирован: 25.08.2014

Ни разу не работал с TM1637, но что то мне подсказывает, что он требует постоянного дерганья со стороны МК. А если так, то собака роется в DallasTemperature. Это блокирующая библиотека. Попробуйте перейти на чистый OneWire. Здесь есть на WDT и на миллис (47пост).
Не понял вашего алгоритма ректификации. Похоже вы пытаетесь вручную устанавливать температуру колонны или я не прав?

bwn
Offline
Зарегистрирован: 25.08.2014

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

Niklog78
Offline
Зарегистрирован: 07.04.2016

Алгоритм ректификации прост, действительно когда темперература в колонне стабилизируется я в настройках задаю температуру колонны и гестирезис. Остальные настройки просто подают звуковые сигналы при переходе, при разогреве колонны-когда необходимо снизить мощность с разгонной до рабочей, потом когда необходимо в конце уменьшить отбор при 93 градусах ну и когда в кубе уже 98 пора заканчивать. Проблемы не только в отображении показаний датчика на ТМ1637 в программе тоже промаргивают данные с датчика температуры, что приводит к срабатыванию к примеру аварийного датчика температуры по температуре конденсера, когда датчик промаргивает то показания 126 становятся так как у него значение byte, и автоматика срабатывает на аварию по привышению температуры. Конечно можно поставить задержку миллис на этот алгоритм для защиты от промаргивания к примеру 1 секунду, но хотелось бы понять причину. Д а такой уж кривоватый скетч, посоветоваться особо не с ким, так что изобретаю в пределах своего скудного познания ардуины.

bwn
Offline
Зарегистрирован: 25.08.2014

Я DT в свое время сразу выкинул, не понравилась она мне. Дальше делал только на OneWire. На самом деле у вас и так стоит задержка в 0,75сек (она в библиотеке). Попробуйте переделать функцию съема температуры на те, что я дал, туда же можно внести и вывод на индикаторы. В этом случае не будет блокировок на время конвертации датчиков и отображение будет привязано к новым полученным значениям (а не долбить в каждый проход loop). Наверно есть смысл возле дальнего датчика установить конденсатор на питание (у меня стоит на 50мкФ). Кстати датчики, на одном шлейфе или "звездой", сходящейся к общей точке?
По алгоритму, делал иначе (серву пока не подключил, регулировки вручную), при 72гр в кубе (надо смотреть по своей кастрюле) начинает требовать открытие воды и снижение мощности, дальше мониторит только колонну и температуру охлаждения на выходе. При начале подъема температуры в колонне начинает искать минимум с 5минутной задержкой. По нахождении стабильного минимума (5 минут не снижалась) дает сигнал на отбор и дальше мониторит превышение на 0,2гр. Превысили - сигнал убавить отбор (потом в планах серва). И так до тех пор, пока физически уже не удержать (по капле стало течь). Ориентироваться по кубовой есть смысл только при первом сэме из браги (у меня два режима). Это ИМХО.
Полезным будет барометр, при изменении погоды расхождения весьма значительные, а сгонка у меня идет часов 8-9.

Niklog78
Offline
Зарегистрирован: 07.04.2016

После испытаний, оказалось, что если не включена нагрузка через симистр и регулятор мощности, то показания не промаргивают, видимо моргают только когда нагружен симистр и дает помехи... поможет ли конденсатор по питанию датчиков?

bwn
Offline
Зарегистрирован: 25.08.2014

Попробуйте, хуже то не будет.

bwn
Offline
Зарегистрирован: 25.08.2014

Вы схему не приводили, как симистор подключен?

Niklog78
Offline
Зарегистрирован: 07.04.2016

bwn не будет ли у вас примера, как выводить показания только при их изменении как вы писали? 

Niklog78
Offline
Зарегистрирован: 07.04.2016

Подключен через РМ-2 симистор, как в инструкции

bwn
Offline
Зарегистрирован: 25.08.2014

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

bwn
Offline
Зарегистрирован: 25.08.2014

Niklog78 пишет:

Подключен через РМ-2 симистор, как в инструкции

Мне это ни о чем не говорит.

P/S скорее всего схема управления симистором без "отлова нуля", а в таком включении и на больших мощностях они имеют свойство значительно гадить в сеть.

Niklog78
Offline
Зарегистрирован: 07.04.2016

Вот схема подключения симистора

bwn
Offline
Зарегистрирован: 25.08.2014

Увы, нужна схема этого РМ. Или сделать самому, деталей на 50 рублей. Погуглите оптопары MOC30**. Вам нужны, которые с Zero-Cross.

Посмотрел описание, это похоже электронный диммер. Они идут в том числе для ламп, там отлова нуля нет. Для ТЭНов в основном применяют пропуск периодов, помех намного меньше. Если не хотите с этим расставаться, экспериментируйте с БП контроллера или питайте от разных линий.

T.Rook
Offline
Зарегистрирован: 05.03.2016

Niklog78 пишет:

После испытаний, оказалось, что если не включена нагрузка через симистр и регулятор мощности, то показания не промаргивают, видимо моргают только когда нагружен симистр и дает помехи... поможет ли конденсатор по питанию датчиков?

Попробуйте же уже, как сразу посоветовали!! Сбой по питанию один из самых распространненых багов цифровых схем. Особенно , если присутствуют сильноточная нагрузка.

Niklog78
Offline
Зарегистрирован: 07.04.2016

Поставил конденсатор по питанию датчиков, результатов нет. Под нагрузкой моргают...

T.Rook
Offline
Зарегистрирован: 05.03.2016

Niklog78 пишет:

Поставил конденсатор по питанию датчиков, результатов нет. Под нагрузкой моргают...

Настораживает "датчикОВ". Ибо суть  предложенного - кондер как можно ближе к датчику (в идеале кондер с диодом.. - но это уже повтроение той темы на которую указывали).

SLKH
Offline
Зарегистрирован: 17.08.2015

bwn пишет:

Ни разу не работал с TM1637, но что то мне подсказывает, что он требует постоянного дерганья со стороны МК.

"что-то" обманывает.

T.Rook
Offline
Зарегистрирован: 05.03.2016

Еще уточнение: по поводу физического расположения проводок  - силовой и от датчиков - нет ли взаимного влияния?

SLKH
Offline
Зарегистрирован: 17.08.2015

bwn пишет:

Niklog78 пишет:

Подключен через РМ-2 симистор, как в инструкции

Мне это ни о чем не говорит.

P/S скорее всего схема управления симистором без "отлова нуля", а в таком включении и на больших мощностях они имеют свойство значительно гадить в сеть.

да, фазоимпульсное управление:  "специальная математика вычисляет угол отсечки для положительной и отрицательной полуволн"

 

 

bwn
Offline
Зарегистрирован: 25.08.2014

SLKH пишет:

bwn пишет:

Ни разу не работал с TM1637, но что то мне подсказывает, что он требует постоянного дерганья со стороны МК.

"что-то" обманывает.

Я в следующем посте исправился.)))

bwn
Offline
Зарегистрирован: 25.08.2014

Niklog78 пишет:

Поставил конденсатор по питанию датчиков, результатов нет. Под нагрузкой моргают...

У меня стоит сантиметрах в пяти от дальнего датчика. Но нет фазоимпульсного управления (инд.плитка с ручным переключением). Перезагрузки у Вас явно нет, значит БП скорее не при чем. Смотрите взаимное расположение проводов, как выше сказали, и можно попробовать уменьшить подтягивающий резистор на датчик.

SLKH
Offline
Зарегистрирован: 17.08.2015

bwn пишет:

Niklog78 пишет:

Поставил конденсатор по питанию датчиков, результатов нет. Под нагрузкой моргают...

. Перезагрузки у Вас явно нет, значит БП скорее не при чем. 

Так диагноз-то ясный: "если не включена нагрузка через симистр и регулятор мощности, то показания не промаргивают" - т.е. в чистом виде помехи по питанию. 

Мощности помех не хватает для перезагрузки. А для чего хватает и что когда вылезет - какой смысл гадать?

Или РМ-2 фтопку (предпочтительно), или фильтровать питание. 

 

 

Niklog78
Offline
Зарегистрирован: 07.04.2016

Про фильтровать питание можно поподробнее? Кстати, также себя датчики вели и при нагреве на индукционке, только промаргивали реже...

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

bwn
Offline
Зарегистрирован: 25.08.2014

Я все таки еще предполагаю наводку на сигнальный провод DS-ки. Резистором это легко проверить. Если малой кровью не выйдет, рыть дальше. ИМХО.

Niklog78
Offline
Зарегистрирован: 07.04.2016

Хорошо, а на сколько его можно уменьшить, везде написан 4.7 ком.

bwn
Offline
Зарегистрирован: 25.08.2014

попробуйте 3,5 или 2,2 (ниже не стоит). Сгореть он не сгорит, просто не сможет отдать показания.

Niklog78
Offline
Зарегистрирован: 07.04.2016

Подскажите в догонку правильно задержка миллис? При соблюдении условия включится реле  через задержку INTERVAL3

// Включаем обдув симистора
void TRobduv () {
  static unsigned long previousMillis = millis();
  if (tempSensorTR >= TRIAC) {
    if (millis() - previousMillis > INTERVAL3) {
      digitalWrite(PIN_OBDUV, HIGH);
    }
  }

 

Niklog78
Offline
Зарегистрирован: 07.04.2016

Спасибо на днях попробую поменять резистор

 

bwn
Offline
Зарегистрирован: 25.08.2014

del

SLKH
Offline
Зарегистрирован: 17.08.2015

Niklog78 пишет:

Про фильтровать питание можно поподробнее? Кстати, также себя датчики вели и при нагреве на индукционке, только промаргивали реже...

При некачественном питании цифровое устройство имеет моральное право вести себя непредсказуемо. Посему при таком питании ковыряться в программах/датчиках особого смысла нет.

А при включении тиристора при больших напряжениях (что бессовестно делает РМ-1) в окружающей дейсвительности возникают помехи широкого спектра (до мегегерц) и с амплитудами до сотен вольт.

Предпочтительно их не допускать (т.е. принципиально изменить силовую схему).

И давить уже возникшие помехи (сосед тоже может гнать), но это отдельная и весьма обширная тема. 

Навскидку: https://www.google.co.uk/search?q=%D1%84%D0%B8%D0%BB%D1%8C%D1%82%D1%80%D0%B0%D1%86%D0%B8%D1%8F+%D0%BF%D0%BE%D0%BC%D0%B5%D1%85+%D0%BF%D0%BE+%D0%BF%D0%B8%D1%82%D0%B0%D0%BD%D0%B8%D1%8E&oq=%D1%84%D0%B8%D0%BB%D1%8C%D1%82%D1%80%D0%B0%D1%86%D0%B8%D1%8F+%D0%BF%D0%BE%D0%BC%D0%B5%D1%85+%D0%BF%D0%BE+%D0%BF%D0%B8%D1%82%D0%B0%D0%BD%D0%B8%D1%8E&aqs=chrome..69i57j0.12492j0j7&sourceid=chrome&ie=UTF-8

=============================

 

зы. о тиристорах: как-то в молодости я ловил непонятную помеху при отладке одного  устройства. удалось локализовать источник, оказалось: мой собственноручно слепленный  фазоимпульсный регулятор (по вашему диммер) моего же паяльника. но паяльник был ватт на 40, а у тебя киловатты дуром коммутируются, так что что в сети творится незнамо что.

Machineman
Offline
Зарегистрирован: 26.05.2016

Как вариант выводить на дисплей только измененные значения.  У себя на TFT реализовал примерно так-

deltaTemp = temp

if(deltaTemp > temp || deltaTemp < temp){ //если разница температур есть, то 
      printTemp();                            // выводим на экран, чтоб не было мерцания
     }

 

SLKH
Offline
Зарегистрирован: 17.08.2015

Machineman пишет:

Как вариант выводить на дисплей только измененные значения.  У себя на TFT реализовал примерно так-

deltaTemp = temp

if(deltaTemp > temp || deltaTemp < temp){ //если разница температур есть, то 
      printTemp();                            // выводим на экран, чтоб не было мерцания
     }

Т.е. на экран никогда не выводим.

Machineman
Offline
Зарегистрирован: 26.05.2016

Printtemp-это и есть функция вывода на экран. Выводится только тогда, когда текущее значение переменной temp отличаетсчя от предыдущего. Соответственно на дисплей выводится всегда последнее значение без мерцания. Deltatemp=temp у меня в самом начале loop стоит. Все прекрасно работает.

SLKH
Offline
Зарегистрирован: 17.08.2015

Machineman пишет:
Printtemp-это и есть функция вывода на экран. Выводится только тогда, когда текущее значение переменной temp отличаетсчя от предыдущего.

В первой строке deltaTemp = temp. 

Соответственно, в третьей всегда будет false и printTemp() в четвертой не вызывается.

Machineman
Offline
Зарегистрирован: 26.05.2016

 У меня deltaTemp=temp стоит в начале loop, а условие вывода в конце цикла. Где-то в середине считывается датчик, так что все логично, а главное работает. Датчик DHT11, но моргает он точно так же как и 18b20. Вот как-то так наверное ясней будет. 

int deltaTemp = 0; //переменная разницы 
void setup() {
  
printTemp(); // выводим на дисплей сразу, чтоб не было пустоты
}

void loop() {
 deltaTemp = temp;
//
//
//
temp = sens.readTemperature(13); //считываем температуру в temp
//
//
if(deltaTemp > temp || deltaTemp < temp){ //если разница температур есть, то 
      printTemp();                            // выводим на экран, чтоб не было мерцания
     }

}

 

SLKH
Offline
Зарегистрирован: 17.08.2015

Machineman пишет:

 У меня deltaTemp=temp стоит в начале loop, а условие вывода в конце цикла. Где-то в середине считывается датчик, так что все логично, а главное работает. Вот как-то так наверное ясней будет.

void setup() {
  printTemp(); // выводим на дисплей сразу, чтоб не было пустоты
}

void loop() {
deltaTemp = temp;
//
//
//
temp = sens.readTemperature(13); //считываем температуру в temp
//
//
if(deltaTemp > temp || deltaTemp < temp){ //если разница температур есть, то 
      printTemp();                            // выводим на экран, чтоб не было мерцания
     }

}

Так - да.

 

А зачем извращение "if(deltaTemp > temp || deltaTemp < temp)" в стр. 13 ? 

Чем плохо "if(deltaTemp != temp)" ?

Machineman
Offline
Зарегистрирован: 26.05.2016

 

Затем, что я чайник  ))

inspiritus
Offline
Зарегистрирован: 17.12.2012

Фазоимпульсны применяется в световых диммерах, чтобы мерцания не было видно. Для ТЭНов лучше применять числоимпульсный с контролем нуля, или взять SSD с индексом Z . Также я успешно использую длинный шим с периодом 3 сек. И SSD -z с контролем нуля. Датчики такие же, на проводах 3-5м и с активным питанием! По трехпроводной схеме.