Медленно исполняется код

DoDo
Offline
Зарегистрирован: 21.05.2021

Здравствуйте, я новичок, написал код для контроллера холодильника... В общем всё работает, но есть неприятные моменты, код тормозит и это заметно по двум вещам первое это две кнопки которыми меняем желаемую температуру реагируют с задержкой и второе дисплей мерцает с частотой примерно в одну секунду это исполняется команда lcd.clear() что говорит о том что void loop() считывается один раз в секунду? Я убрал все delay() вообще но это не особо помогло... 

[code]
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <SPI.h>
#define ONE_WIRE_BUS1 2
#define ONE_WIRE_BUS2 8
#define BUTTON1 3
#define BUTTON2 4
#define BUTTON3 5
const int RELAY_CHILLER = 6;
const int RELAY_ALARM = 7;
int count_value1 = 18;
int count_value2 = 21;
int Alarm_Limit1 = 15;
int Alarm_Limit2 = 30;
int buttonState1;
int buttonState2;
int buttonState3;
int set1;
int set2;
int Act1;
int Act2;
int WaterTempAlarm;
String Chiller_Status;
String Water_Flow_Status;
String Alarm_Status1;
String Alarm_Status2;
String Alarm_Status3;
String Alarm;
String line_0;
String line_1;
String line_2;
String line_3;


OneWire oneWire1(ONE_WIRE_BUS1);
OneWire oneWire2(ONE_WIRE_BUS2);
DallasTemperature sensors1(&oneWire1);
DallasTemperature sensors2(&oneWire2);
#if defined(ARDUINO) && ARDUINO >= 100
#define printByte(args)  write(args);
#else
#define printByte(args)  print(args,BYTE);
#endif


uint8_t bell[8]  = {0x4, 0xe, 0xe, 0xe, 0x1f, 0x0, 0x4};
uint8_t note[8]  = {0x2, 0x3, 0x2, 0xe, 0x1e, 0xc, 0x0};
uint8_t clock[8] = {0x0, 0xe, 0x15, 0x17, 0x11, 0xe, 0x0};
uint8_t heart[8] = {0x0, 0xa, 0x1f, 0x1f, 0xe, 0x4, 0x0};
uint8_t duck[8]  = {0x0, 0xc, 0x1d, 0xf, 0xf, 0x6, 0x0};
uint8_t check[8] = {0x0, 0x1, 0x3, 0x16, 0x1c, 0x8, 0x0};
uint8_t cross[8] = {0x0, 0x1b, 0xe, 0x4, 0xe, 0x1b, 0x0};
uint8_t retarrow[8] = {	0x1, 0x1, 0x5, 0x9, 0x1f, 0x8, 0x4};

LiquidCrystal_I2C lcd(0x27, 20, 4); // set the LCD address to 0x27 for a 16 chars and 2 line display

void setup()
{
  lcd.init();
  lcd.backlight();
  sensors1.begin();
  sensors2.begin();
  //Serial.begin(9600);
  pinMode(RELAY_ALARM, OUTPUT);
  pinMode(RELAY_CHILLER, OUTPUT);
  digitalWrite(RELAY_ALARM, HIGH);
  digitalWrite(RELAY_CHILLER, HIGH);

}

void loop()
{
  {
    buttonState1 = digitalRead(BUTTON1);
  }
  {
    buttonState2 = digitalRead(BUTTON2);
  }
  {
    buttonState3 = digitalRead(BUTTON3);
  }




  if (buttonState1 == HIGH)
  {
    count_value1++, count_value2++;
  }



  if (buttonState2 == HIGH)
  {
    count_value1--, count_value2--;
  }




  if (buttonState3 == LOW)
  {
    (Water_Flow_Status = "OFF", Alarm_Status3 = "ON");
  }



  if (buttonState3 == HIGH)
  {
    (Water_Flow_Status = "ON ", Alarm_Status3 = "OFF");
  }







  {
    Act1 = (sensors1.getTempCByIndex(0));
  }
  {
    Act2 = (sensors2.getTempCByIndex(0));
  }
  {
    set1 = (count_value1);
  }
  {
    set2 = (count_value2);
  }
  {
    sensors1.requestTemperatures();
  }
  {
    sensors2.requestTemperatures();
  }
  {
    Chiller_Status = "ON ";
  }
  if (Act1 > set2)
  {
    Chiller_Status = "ON ";
  }

  if (Act1 < set1)

  {
    Chiller_Status = "OFF";
  }


  if (Chiller_Status == "ON ")
    digitalWrite(RELAY_CHILLER, LOW);

  if (Chiller_Status == "OFF")
  {
    digitalWrite(RELAY_CHILLER, HIGH);
  }

  if (Alarm_Status1 == "OFF" && Alarm_Status2 == "OFF" && Alarm_Status3 == "OFF")
  {
    digitalWrite(RELAY_ALARM, LOW);
  }

  else
  {
    digitalWrite(RELAY_ALARM, HIGH);
  }

  if (Act1 < Alarm_Limit1 or Act1 > Alarm_Limit2)
  {
    Alarm_Status1 = "ON";
  }
  else
  {
    Alarm_Status1 = "OFF";
  }

  if (Act2 < Alarm_Limit1 or Act2 > Alarm_Limit2)
  {
    Alarm_Status2 = "ON";
  }
  else
  {
    Alarm_Status2 = "OFF";
  }

  if (Alarm_Status1 == "OFF" && Alarm_Status2 == "OFF" && Alarm_Status3 == "OFF")
  {
    Alarm = "LASER ARM";
  }
  if (Alarm_Status1 == "ON" && Alarm_Status2 == "ON" && Alarm_Status3 == "ON")
  {
    Alarm = "t1, t2, W/FLOW";
  }
  if (Alarm_Status1 == "ON" && Alarm_Status2 == "OFF" && Alarm_Status3 == "OFF")
  {
    Alarm = "t1 TEMP.<15 or >30";
  }
  if (Alarm_Status1 == "ON" && Alarm_Status2 == "ON" && Alarm_Status3 == "OFF")
  {
    Alarm = "t1 & t2 OUT LIMIT";
  }
  if (Alarm_Status1 == "ON" && Alarm_Status2 == "OFF" && Alarm_Status3 == "ON")
  {
    Alarm = "t1 & WATER FLOW";
  }
  if (Alarm_Status1 == "OFF" && Alarm_Status2 == "ON" && Alarm_Status3 == "ON")
  {
    Alarm = "t2 & WATER FLOW";
  }
  if (Alarm_Status1 == "OFF" && Alarm_Status2 == "OFF" && Alarm_Status3 == "ON")
  {
    Alarm = "WATER FLOW PROBLEM";
  }
  if (Alarm_Status1 == "OFF" && Alarm_Status2 == "ON" && Alarm_Status3 == "OFF")
  {
    Alarm = "t2 TEMP.<15 or >30";
  }



  //Serial.println("3"+Alarm_Status3);


  lcd.clear();

  line_0 = (String("t1:") + String(Act1) + char(223) + String("C") + String(" ") + String("t2:") + String(Act2) + char(223) + String("C"));
  line_1 = (String("Set:") + String(set1) + char(223) + String("C") + String(" to ") + String(set2) + char(223) + String("C"));
  line_2 = (String("CHIL.:") + String(Chiller_Status) + String(" ") + String("W/FLOW:") + (Water_Flow_Status));
  line_3 = String(Alarm);
  lcd.setCursor(0, 0);
  lcd.print(line_0);
  lcd.setCursor(0, 1);
  lcd.print(line_1);
  lcd.setCursor(0, 2);
  lcd.print(line_2);
  lcd.setCursor(0, 3);
  lcd.print(line_3);

}
[/code]

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

значить, делеи остались вот здесь:  sensorsХ.requestTemperatures();

b707
Offline
Зарегистрирован: 26.05.2017

функция запроса температуры в библиотеке

#include <DallasTemperature.h>

блокирующая и занимает 0.75 сек.  С этой библиотекой код у вас быстрее этого времени работать не будет.

Переписывайте работу с датчиком без библиотеки, примеров в сети полно, в том числе и на этом форуме.

 

И еще - почитайте какой-нибудь учебник, как и для чего  в коде применяются скобки. У вас их примерно в 3-4 раза больше, чем нужно.

kalapanga
Offline
Зарегистрирован: 23.10.2016

delay убраны похоже в прямом смысле - просто выкинуты. Видимо, в результате этого дисплей перерисовывается безостановочно каждый проход loop, что явно лишнее. Их не просто выкидывать надо, их надо заменять как в примере BlinkWithoutDelay.

Про работу с датчиками выше уже написали.

DoDo
Offline
Зарегистрирован: 21.05.2021

Спасибо за помощь! скобки лишние уже убрал, если не трудно можете дать ссылку где можно посмотреть работу с датчиком без библиотеки?

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

DoDo пишет:
где можно посмотреть работу с датчиком без библиотеки?

Сам ниасилишь

Kakmyc
Offline
Зарегистрирован: 15.01.2018

В контроллере холодильника attiny13 стоит.
Этот код туда не влезет.

DoDo
Offline
Зарегистрирован: 21.05.2021

b707 пишет:

функция запроса температуры в библиотеке

#include <DallasTemperature.h>

блокирующая и занимает 0.75 сек.

А можно сделать чтобы эта функция не тормозила общий код? Ведь сам опрос датчика каждые 0,75сек. не проблема даже и несколько секунд если было бы..

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Можно.
От библиотеки отказываешься и никаких задержек

Pyotr
Offline
Зарегистрирован: 12.03.2014

Вот тестовый пример для трех далласов без библиотеки. На миллис сам переделывай.

#define PIN_TEMP_AER   7
#define PIN_TEMP_TEN   11
#define PIN_TEMP_OUT   8
#include <OneWire.h>
OneWire dsAer(PIN_TEMP_AER);
OneWire dsTen(PIN_TEMP_TEN);
OneWire dsOut(PIN_TEMP_OUT);
float tempOut;

//void startConvert(OneWire & );
//=====================================
void startConvert(OneWire & ds){
  ds.reset();  //команда на преобразов. = 2200 mksec
  ds.write(0xCC);// пофиг на адреса (SKIP ROM)
  ds.write(0x44);// начать преобразование 
}
//=======================
float getTemp(OneWire & ds){//возвр. полож. и отрицательную Т
//При опросе раз в 2 сек в стоячем воздухе Т датчика поднимается на 0.3-0.4С
  int t = 0;
  ds.reset();      // чтение 3250 mks
  ds.write(0xCC);
  ds.write(0xBE);
  t = ds.read() | (ds.read()<<8); 
  return t / 16.0;
}

void setup() {
  Serial.begin(9600);
}

void loop() {  
  startConvert(dsAer);
  startConvert(dsTen);
  startConvert(dsOut);
  delay(800); 
  tempOut = getTemp(dsAer); 
  Serial.println(tempOut);
  Serial.println(getTemp(dsTen));
  Serial.println(getTemp(dsOut));
  Serial.println();
}

 

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

Еще вариант, взято где-то на этом форуме

#include <OneWire.h>   // для работы с датчиком DS18b20

#define DS18B20_PIN 9 // пин датчика температуры

OneWire ds(DS18B20_PIN); // датчик DS18b20

int temperature = 0; // переменная, в которую записываются показания датчика
byte addr[8]; // адрес датчика температуры

void tmrTemperature(void)
{
  static bool flagDall = true; // Признак операции
  if (flagDall)
  {
    ds.reset();
    ds.write(0xCC); // Обращение ко всем датчикам
    ds.write(0x44); // Команда на конвертацию
  }
  else
  {
    int temp;
    ds.reset();
    ds.select(addr);
    ds.write(0xBE);                      // Считывание значения с датчика
    temp = (ds.read() | ds.read() << 8); // Принимаем два байта температуры
    temperature = round((float)temp / 16.0);
  }
  flagDall = !flagDall; // Инверсия признака операции для следующей итерации
}

void setup()
{
  Wire.begin();
  ds.reset();     // сброс шины
  ds.write(0x7F); // точность 0,5гр = 1F; 0,25гр = 3F; 0,125гр = 5F; 0,0625гр = 7F;
  ds.search(addr);
}

void loop()
{
// раз в несколько секунд вызывать функцию tmrTemperature(); первый
// вызов отправляет датчику команду на конвертацию, второй считывает 
// полученные данные; слишком часто опрашивать датчик не рекомендуется
// т.к. он может нагреваться в процессе работы; не сильно ))
// значение температуры брать при необходимости из переменной temperature
}

 

DoDo
Offline
Зарегистрирован: 21.05.2021

Проблема с торможением ушла, но как бороться с мерцанием дисплея? Теперь он мерцает намного чаще, а без lcd.clear() тоже никак..

 

Kakmyc
Offline
Зарегистрирован: 15.01.2018

DoDo пишет:

Проблема с торможением ушла, но как бороться с мерцанием дисплея? Теперь он мерцает намного чаще, а без lcd.clear() тоже никак..

 

Чой та ?
Библиотека с буфером, не нужно там ничего очищать

DoDo
Offline
Зарегистрирован: 21.05.2021

Kakmyc пишет:
DoDo пишет:

Проблема с торможением ушла, но как бороться с мерцанием дисплея? Теперь он мерцает намного чаще, а без lcd.clear() тоже никак..

 

Чой та ? Библиотека с буфером, не нужно там ничего очищать

У меня дисплей 4 строки и он выводит и алармы, если следующая строка короче первой остаётся мусор на дисплее.. 

сделал вот так 


   if (millis() - timing > 2000)
   { 
  timing = millis(); 
   lcd.clear();
   }

выглядит лучше, но возможно ли совсем избавится от мерцания? 

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Я с этой библиотекой работаю так:
Завожу массивы по количеству строк.
Формирую целиком всю строку через sprintf и вывожу все разом.
Ничто никуда не уползает, никакие lcd clear() не нужны

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

DoDo пишет:

выглядит лучше, но возможно ли совсем избавится от мерцания? 

Можно. Если выводить только изменившуюся информацию, раз уж для данных предусмотрены конкретные позиции на экране

DoDo
Offline
Зарегистрирован: 21.05.2021

v258 пишет:

DoDo пишет:

выглядит лучше, но возможно ли совсем избавится от мерцания? 

Можно. Если выводить только изменившуюся информацию, раз уж для данных предусмотрены конкретные позиции на экране

А можно подробнее пожалуйста 

Kakmyc
Offline
Зарегистрирован: 15.01.2018

У меня это выглядит примерно так :

 

void PrintMainMenu(struct Menu &menu){
    char topRow[33];
    char bottomRow[33];
    sprintf(topRow,"%d.%s",menu.menu_id,menu.menu_name);
    sprintf(bottomRow,"%d.%s",menu.next->menu_id,menu.next->menu_name);
    lcd.setCursor(0,0);
    lcd.print(">");
    lcd.print(topRow);
    lcd.setCursor(1,1);
    lcd.print(bottomRow);
    }

 

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

DoDo пишет:

v258 пишет:

DoDo пишет:

выглядит лучше, но возможно ли совсем избавится от мерцания? 

Можно. Если выводить только изменившуюся информацию, раз уж для данных предусмотрены конкретные позиции на экране

А можно подробнее пожалуйста 

Рассказать, как поставить курсор в нужную позицию и вывести текст? А подумать?

Kakmyc
Offline
Зарегистрирован: 15.01.2018

v258 у тебя аватара неправильная.
В современных реалиях там должны быть Вжик и Гайка :-)

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

Kakmyc пишет:
v258 у тебя аватара неправильная. В современных реалиях там должны быть Вжик и Гайка :-)

Не, правильная. Когда этот мультик только появился, меня мама частенько этим Рокки троллила - типа, вылитый я )))

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

b707 пишет:

И еще - почитайте какой-нибудь учебник, как и для чего  в коде применяются скобки. У вас их примерно в 3-4 раза больше, чем нужно.

Не соглашусь. На «полёт» не влияют, зато читабельно и проще в редактировании кода (если что-то в операторную скобку добавить нужно), ну и так далее. К тому ж они бесплатные, доплаты не требуется )))) Главное - чтобы были правильно расставлены!))

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

v258 пишет:

Kakmyc пишет:
v258 у тебя аватара неправильная. В современных реалиях там должны быть Вжик и Гайка :-)

Не, правильная. Когда этот мультик только появился, меня мама частенько этим Рокки троллила - типа, вылитый я )))

Зачетный мультсериал! «Сыыыыыыррр» ))))

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

DoDo пишет:

Спасибо за помощь! скобки лишние уже убрал, если не трудно можете дать ссылку где можно посмотреть работу с датчиком без библиотеки?

Да, делайте Вы с библиотекой, с этой же самой, только неблокирующими вызовами.