Помогите оптимизировать

smolyakov26
Offline
Зарегистрирован: 07.10.2020

Вообщем всем на суд первая программа в жизни поэтому прошу не судить строго.

Это чудище модуль управления теплицей. Все вроде получилось как задумано и работает только убивает глюк что все замирает при чтении данных с датчиков. Поставил таймер теперь все зависает раз в 5 секунд. Помогите разоьраться что бы не тупить в будущем. Ну и вообще любые предложения п оптимизации готов выслушать а если еще и покажете как это сделать будет совсем приятно.

#include <LiquidCrystal.h> // экран
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);


#include "GyverTimer.h"
GTimer myTimer(MS);               // создать миллисекундный таймер

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10

#define SEALEVELPRESSURE_HPA (1013.25)


Adafruit_BME280 bme;

// для работы c кнопкой

#include "GyverEncoder.h"

#define CLK A0
#define DT A2
#define SW A1
Encoder enc1(CLK, DT, SW);



int page = 0;

float tempval = 18.0;
float humval = 35.0;
int soilval = -10;
int co2val = 1000;


const int dry = 691;
const int wet = 304;
int csoil = 0;



float chum = 0;
float ctemp;



void setup() {

  Serial.begin(9600);
  // экран
  lcd.begin(16, 2);

  bme.begin();// инициализация датчика BME280
  enc1.setType(TYPE2); // инициализация энкодера
  lcd.setCursor(4, 0);
  lcd.print("Infected");
  lcd.setCursor(4, 1);
  lcd.print("Mushrooms");
  delay(4000);
  lcd.clear();

  pinMode(6 , OUTPUT);
  pinMode(7 , OUTPUT);
  pinMode(8 , OUTPUT);
  //pinMode(9 , OUTPUT);

  myTimer.setInterval(5000);

  readSensors () ;


}

void loop() {
  if (myTimer.isReady())  readSensors () ;


  encoderOp();
  printMenu();
  //soilSensor();
  relay();



}





void printMenu () {
  switch (page) {
    case 0: lcd.setCursor(0, 0); lcd.print("Now: "); lcd.setCursor(7, 0); lcd.print("Temp:"); lcd.print(ctemp, 1);
      lcd.setCursor(0, 1); lcd.print("Set: "); lcd.setCursor(7, 1); lcd.print("Temp:"); lcd.print(tempval);
      break;
    case 1: lcd.setCursor(0, 0); lcd.print("Now: "); lcd.setCursor(8, 0); lcd.print("Hum:"); lcd.print(chum, 1);
      lcd.setCursor(0, 1); lcd.print("Set: "); lcd.setCursor(8, 1); lcd.print("Hum:"); lcd.print(humval);
      break;
    case 2: lcd.setCursor(0, 0); lcd.print("Now: "); lcd.setCursor(9, 0); lcd.print("Soil:"); csoil = soilSensor(); lcd.print(csoil);
      lcd.setCursor(0, 1); lcd.print("Set: "); lcd.setCursor(9, 1); lcd.print("Soil:"); lcd.print(soilval);
      break;
    case 3: lcd.setCursor(0, 0); lcd.print("Now: "); lcd.setCursor(8, 0); lcd.print("CO2:"); lcd.print("0000");
      lcd.setCursor(0, 1); lcd.print("Set: "); lcd.setCursor(8, 1); lcd.print("CO2:"); lcd.print(co2val);
      break;
  }
}

void encoderOp() {
  enc1.tick();
  if (enc1.isTurn()) {  // при любом повороте
    lcd.clear();        // очищаем дисплей

    if (enc1.isRight()) {
      page++;
      if (page >= 4) page = 3;  // ограничиваем позицию курсора
    }
    if (enc1.isLeft()) {
      page--;
      if (page < 0) page = 0;  // ограничиваем позицию курсора
    }

    // при нажатом повороте меняем переменные ++
    if (enc1.isRightH()) {
      switch (page) {
        case 0: tempval++;
          break;
        case 1: humval++;
          break;
        case 2: soilval++;
          break;
        case 3: co2val++;
          break;
      }
    }

    // при нажатом повороте меняем переменные --
    if (enc1.isLeftH()) {
      switch (page) {
        case 0: tempval--;
          break;
        case 1: humval--;
          break;
        case 2: soilval--;
          break;
        case 3: co2val--;
          break;
      }
    }

  }

}


void relay () {
  if (tempval > ctemp) digitalWrite(6, LOW);
  if (tempval < ctemp) digitalWrite(6, HIGH);

  if (humval > chum) digitalWrite(7, LOW);
  if (humval < chum) digitalWrite(7, HIGH);

  if (soilval > csoil) digitalWrite( 8 , LOW);
  if (soilval < csoil) digitalWrite( 8 , HIGH);


  //if ( > bme.readHumidity()) digitalWrite(8, LOW);
  //if (co2val > bme.readHumidity()) digitalWrite(9, LOW);


}



int soilSensor() {
  int sensorVal = analogRead (A7);
  //Serial.println(sensorVal);
  int soilperc = map (sensorVal, wet, dry, 99, 0);
  //Serial.println(soilperc);

  return soilperc;

}


void readSensors () {
  csoil = soilSensor();
  chum = bme.readHumidity() ;
  ctemp = bme.readTemperature();

}

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Вы наверное думаете, что сейчас у всех возникнет жгучее желание поискать что же за датчики там у этого начинающего огородника зависают и 50 человек с форума всю ночь просидят оптимизируя скетч - потому что чем ещё заняться то?

Научитесь действовать правильно: закомментируйте все, что не относится к проблеме - зависанию при чтении сенсора и, если проблема сохранится, поинтересуйтесь - отчего в этом маленьком скетче, на строке N могут возникать задержки?

А если проблема не сохранится - ищите ее в закомментированных фрагментах.

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Да вроде была акая тема в проектах. И довели ее до ума. Вроде...

А так - да, побежали оптимизировать.

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

Простите, насколько Вы понимаете написанные коды и насколько свободно можете их изменять? (это к тому, как именно Вам объяснять проблему)

smolyakov26
Offline
Зарегистрирован: 07.10.2020

Все сам написал , так что могу все поменять изменять ) если не трудно обьясни в каком направлении двигаться

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

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

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

smolyakov26 пишет:
Все сам написал , так что могу все поменять изменять ) если не трудно обьясни в каком направлении двигаться

Для начала, посмотрите в библиотеку на функцию Adafruit_BME280::readHumidity, Вы увидите, что первое, что она делает - это вызывает readTemperature. Т.е. Вы в своём коде вызываете readTemperature дважды, а зачем? Первое, что я бы попробовал - это дописал бы в библиотеку функцию, которая один раз это делает, а возвращает и температуру, и влажность. Этим Вы сократите время вдвое. Если и это не устроит, тогда поговорим дальше.

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

smolyakov26 пишет:

Вообщем всем на суд первая программа в жизни поэтому прошу не судить строго.

Это чудище модуль управления теплицей. Все вроде получилось как задумано и работает только убивает глюк что все замирает при чтении данных с датчиков. 

void loop() {
  if (myTimer.isReady())  readSensors () ;
  encoderOp();
  printMenu();
  //soilSensor();
  relay();

}

Ничего там не замирает - просто  без таймера (костыль)  датчики в основном цикле вообще не читаются.