Greenhouse-controller ошибки при проверки скетча.

Bloober
Offline
Зарегистрирован: 05.07.2017

Здравствуйте! На Гитхабе https://github.com/talktocory/greenhouse-controller нашёл интересный проект, но при проверке скетча выпадают ошибки:

Arduino: 1.8.3 (Windows 10), Плата:"Arduino/Genuino Uno"

C:\Downloads\Greenhouse\Greenhouse.ino: In function 'void loop()':

Greenhouse:159: error: 'displayMenu' was not declared in this scope

   displayMenu(currentMenu); 

                          ^

Greenhouse:162: error: 'waitForInput' was not declared in this scope

   buttonPressed = waitForInput(1000);

                                    ^

Greenhouse:280: error: 'InTimeSpan' was not declared in this scope

   if (InTimeSpan(lightsOnHh, lightsOnMm, lightsOffHh, lightsOffMm)) {

                                                                  ^

exit status 1
'displayMenu' was not declared in this scope

Ну и сам скетч:

// see: https://learn.adafruit.com/dht/using-a-dhtxx-sensor
#include <DHT.h>

#include <Wire.h>  // Comes with Arduino IDE

// Get the LCD I2C Library here: 
// https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads
// Move any other LCD libraries to another folder or delete them
// See Library "Docs" folder for possible commands etc.
#include <LiquidCrystal_I2C.h>

#include <Time.h>
#include <TimeLib.h>
#include <DS1307RTC.h>  // a basic DS1307 library that returns time as a time_t

#include <IRremote.h>
#include <IRremoteInt.h>

// ********************************************************
//                         Constants
// ********************************************************
#define RECV_PIN 10 // IR receiver pin
#define DHTPIN 2
#define DHTTYPE DHT11
#define RELAYLIGHTS 3
#define RELAYHEATER 5
#define RELAYHUMIDIFIER 4
#define RELAYVENTILATION 6

const char *monthName[12] = {
  "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};

// ********************************************************
//                      Global Variables
// ********************************************************
// greenhouse variables
float tempSet, tempAct, humSet, humAct, sensorValue;
int lightsOnHh, lightsOnMm, lightsOffHh, lightsOffMm;
int ventilationFrqHh, ventilationDurMm;
unsigned long lastVentilationStart, nextVentilationStart, nextVentilationEnd;
String buttonPressed;
String currentMenu;
tmElements_t tm;
  
/* initialize temp/hum sensor
 *  SDA - ANALOG Pin 4
 *  SCL - ANALOG pin 5
*/
DHT dht(DHTPIN, DHTTYPE);

// initialize IR receiver
// Digital pin 2
IRrecv irrecv(RECV_PIN);
decode_results irMessage;

// set the LCD address to 0x27 for a 20 chars 4 line display
// Set the pins on the I2C chip used for LCD connections:
//                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
// see: https://arduino-info.wikispaces.com/LCD-Blue-I2C
/*
 * SDA - ANALOG Pin 4
 * SCL - ANALOG pin 5
 * On most Arduino boards, SDA (data line) is on analog input pin 4, and SCL (clock line) is on analog input pin 5
*/
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address

// ********************************************************
//                     Utility Functions 
// ********************************************************
void printDigits(int digits){
  if(digits < 10)
    lcd.print('0');
  lcd.print(digits);
}
bool getTime(const char *str)
{
  int Hour, Min, Sec;

  if (sscanf(str, "%d:%d:%d", &Hour, &Min, &Sec) != 3) return false;
  tm.Hour = Hour;
  tm.Minute = Min;
  tm.Second = Sec;
  return true;
}

bool getDate(const char *str)
{
  char Month[12];
  int Day, Year;
  uint8_t monthIndex;

  if (sscanf(str, "%s %d %d", Month, &Day, &Year) != 3) return false;
  for (monthIndex = 0; monthIndex < 12; monthIndex++) {
    if (strcmp(Month, monthName[monthIndex]) == 0) break;
  }
  if (monthIndex >= 12) return false;
  tm.Day = Day;
  tm.Month = monthIndex + 1;
  tm.Year = CalendarYrToTm(Year);
  return true;
}
// ********************************************************
//                           Setup
// ********************************************************
void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  lcd.clear();
  
  // start the ir receiver
  irrecv.enableIRIn(); 

  // start the // Serial monitor
  // Serial.begin(9600);
  // while (!Serial) ; // wait for Arduino // Serial Monitor
  setSyncProvider(RTC.get);   // the function to get the time from the RTC
  if(timeStatus()!= timeSet) {
    // Serial.println("Date and time not set.  Setting it to last compile time."); 
    // get the date and time the compiler was run
    if (getDate(__DATE__) && getTime(__TIME__)) {
      RTC.write(tm);
    }
  } else {
    // Serial.println("RTC has set the system time");     
  }
  
  // Set system defaults
  tempSet = 22.0;
  tempAct = tempSet;
  humSet = 60.0;
  humAct = humSet;
  lightsOnHh = 6;
  lightsOnMm = 0;
  lightsOffHh = 22;
  lightsOffMm = 0;
  ventilationFrqHh = 1;
  ventilationDurMm = 15;
  lastVentilationStart = now();
  
  // Display the main menu
  currentMenu = "menu_0";

  // Setup Relays
  pinMode(RELAYLIGHTS, OUTPUT);
  pinMode(RELAYHEATER, OUTPUT);
  pinMode(RELAYHUMIDIFIER, OUTPUT);
  pinMode(RELAYVENTILATION, OUTPUT);
  digitalWrite(RELAYLIGHTS, HIGH);
  digitalWrite(RELAYHEATER, HIGH);
  digitalWrite(RELAYHUMIDIFIER, HIGH);
  digitalWrite(RELAYVENTILATION, HIGH);
}

void loop() {

  // Refresh the display
  displayMenu(currentMenu); 
  
  // Give user 1 second to press button
  buttonPressed = waitForInput(1000);

  // If menu item was pressed then change
  // the menu.  Otherwise, redisplay the 
  // current menu.
  if (buttonPressed == "Mode"){
    if (currentMenu.startsWith("menu_0")){
      currentMenu = "menu_1";
    } 
    else if (currentMenu.equals("menu_1")){
      currentMenu = "menu_2";
    }
    else if (currentMenu.equals("menu_2")){
      currentMenu = "menu_3";
    }
    else if (currentMenu.equals("menu_3")){
      currentMenu = "menu_4";
    }
    else if (currentMenu.equals("menu_4")){
      currentMenu = "menu_5";
    }
    else if (currentMenu.equals("menu_5")){
      currentMenu = "menu_6";
    }
    else if (currentMenu.equals("menu_6")){
      currentMenu = "menu_7";
    }
    else if (currentMenu.equals("menu_7")){
      currentMenu = "menu_8";
    }
    else if (currentMenu.equals("menu_8")){
      currentMenu = "menu_9";
    }
    else if (currentMenu.equals("menu_9")){
      currentMenu = "menu_10";
    }
    else if (currentMenu.equals("menu_10")){
      currentMenu = "menu_0"; 
    }
  } else if (buttonPressed == "Volume Up"){
    if (currentMenu.equals("menu_1")){
      tm.Hour = tm.Hour + 1;
      RTC.write(tm);
    }
    else if (currentMenu.equals("menu_2")){
      tm.Minute = tm.Minute + 1;
      RTC.write(tm);
    }
    else if (currentMenu.equals("menu_3")){
      tempSet += 0.1;
    }
    else if (currentMenu.equals("menu_4")){
      humSet += 1.0;
    }
    else if (currentMenu.equals("menu_5")){
      lightsOffHh++;
    }
    else if (currentMenu.equals("menu_6")){
      lightsOnMm++; 
    }
    else if (currentMenu.equals("menu_7")){
      lightsOffHh++;
    }
    else if (currentMenu.equals("menu_8")){
      lightsOffMm++;
    }
    else if (currentMenu.equals("menu_9")){
      ventilationFrqHh++;
    }
    else if (currentMenu.equals("menu_10")){
      ventilationDurMm++;
    }
  } else if (buttonPressed == "Volume Down"){
    if (currentMenu.equals("menu_1")){
      tm.Hour = tm.Hour - 1;
      RTC.write(tm);
    }
    else if (currentMenu.equals("menu_2")){
      tm.Minute = tm.Minute - 1;
      RTC.write(tm);
    }
    else if (currentMenu.equals("menu_3")){
      tempSet -= 0.1;
    }
    else if (currentMenu.equals("menu_4")){
      humSet -= 1.0;
    }
    else if (currentMenu.equals("menu_5")){
      lightsOffHh--;
    }
    else if (currentMenu.equals("menu_6")){
      lightsOnMm--; 
    }
    else if (currentMenu.equals("menu_7")){
      lightsOffHh--;
    }
    else if (currentMenu.equals("menu_8")){
      lightsOffMm--;
    }
    else if (currentMenu.equals("menu_9")){
      ventilationFrqHh--;
    }
    else if (currentMenu.equals("menu_10")){
      ventilationDurMm--;
    }
  }

  // Read temp and humidity
  sensorValue = dht.readTemperature();
  if (!isnan(sensorValue)){
    tempAct = sensorValue;
  }
  sensorValue = dht.readHumidity();
  if (!isnan(sensorValue)){
    humAct = sensorValue;
  }

  // Adjust Lights
  if (InTimeSpan(lightsOnHh, lightsOnMm, lightsOffHh, lightsOffMm)) {
    digitalWrite(RELAYLIGHTS, LOW); 
  } else {
    digitalWrite(RELAYLIGHTS, HIGH);   
  }

  // Adjust Humidity
 
  if ((humAct + 5) < humSet){
    digitalWrite(RELAYHUMIDIFIER, LOW);   
  } else if ((humAct - 5) > humSet) {
    digitalWrite(RELAYHUMIDIFIER, HIGH);   
  }

  // Adjust Heater
  if ((tempAct + 2) < tempSet){
    digitalWrite(RELAYHEATER, LOW);   
  } else if ((tempAct - 2) > tempSet) {
    digitalWrite(RELAYHEATER, HIGH);   
  }

  // Adjust Ventilation
  nextVentilationStart = lastVentilationStart + ventilationFrqHh * 60 * 60;
  nextVentilationEnd = nextVentilationStart + ventilationDurMm * 60;
  if ((now() > nextVentilationStart) && (now() < nextVentilationEnd)){
    lastVentilationStart = nextVentilationStart;
    digitalWrite(RELAYVENTILATION, LOW);
  } else {
    digitalWrite(RELAYVENTILATION, HIGH);
  }

}

Очень хочется понять, что за ошибки и как их исправить?

Bloober
Offline
Зарегистрирован: 05.07.2017

Есть ещё видео: https://www.youtube.com/watch?v=KjPOGInt5jc , но это если кому интересно. 

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

Bloober пишет:

что за ошибки

В тексте не хватает трёх функций: displayMenu, waitForInput и InTimeSpan

Bloober пишет:

как их исправить?

Найти эти функции (возможно, они там же в проекте валяются, или, может быть, у Вас не та версия какой-нибудь библиотеки, или ещё что-нибудь) или написать их самому.

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Женя! Опять практика по коррекционной педагогике?

Там, в проекте, который он смотрит, все и лежит.

Если пассажир не в курсе этого, то он рано начал интересоваться проектами. Нужно поучиться.

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

ТС! (Топик Стартер - тот, кто начал тему)

Всему нужно учиться, даже если рукоблудием без знаний заниматься, можно хрен оторвать. Уж простите мой французский.

Вам просто нужно ВСЕ файлы проекта записать в один каталог и открывать.

Bloober
Offline
Зарегистрирован: 05.07.2017

Мда.....всё как-то сложно, на гитхабе есть ещё три скетча, помимо основного, может тут:

// ********************************************************
//                         Constants
// ********************************************************
const String BTN_POWER = "Power";
const String BTN_MODE = "Mode";
const String BTN_MUTE = "Mute";

const String BTN_REV = "Reverse";
const String BTN_FWD = "Forward";
const String BTN_PLAY = "Play/Pause";

const String BTN_VOL_DOWN = "Volume Down";
const String BTN_VOL_UP = "Volume Up";
const String BTN_EQ = "Equlalizer";

const String BTN_0 = "0";
const String BTN_100 = "100+";
const String BTN_BACK = "Back";

const String BTN_1 = "1";
const String BTN_2 = "2";
const String BTN_3 = "3";

const String BTN_4 = "4";
const String BTN_5 = "5";
const String BTN_6 = "6";

const String BTN_7 = "7";
const String BTN_8 = "8";
const String BTN_9 = "9";

// ********************************************************
//                         Functions
// ********************************************************

// Decode the actual button pressed on the IR remote
String decodeInput(decode_results &results){
  
  switch(results.value) {
    case 0xFFA25D:  
      return BTN_POWER;
      break;
    case 0xFF629D:  
      return BTN_MODE;
      break;
    case 0xFFE21D:  
      return BTN_MUTE;
      break;
    case 0xFF22DD:  
      return BTN_REV;
      break;
    case 0xFF02FD:  
      return BTN_FWD;
      break;
    case 0xFFC23D:  
      return BTN_PLAY;
      break;
    case 0xFFE01F:  
      return BTN_VOL_DOWN;
      break;
    case 0xFFA857:  
      return BTN_VOL_UP;
      break;
    case 0xFF906F:  
      return BTN_EQ;
      break;
    case 0xFF6897:  
      return BTN_0;

или тут:

void displayMenu(String newMenu){
  
    if (newMenu == "menu_0") {
      currentMenu = newMenu;
      displayMenu_0();
    }
    else if (newMenu == "menu_1") {
      currentMenu = newMenu;
      displayMenu_1();
    }
    else if (newMenu == "menu_2") {
      currentMenu = newMenu;
      displayMenu_2();
    }
    else if (newMenu == "menu_3") {
      currentMenu = newMenu;
      displayMenu_3();
    }
    else if (newMenu == "menu_4") {
      currentMenu = newMenu;
      displayMenu_4();
    }
    else if (newMenu == "menu_5") {
      currentMenu = newMenu;
      displayMenu_5();
    }
    else if (newMenu == "menu_6") {
      currentMenu = newMenu;
      displayMenu_6();
    }
    else if (newMenu == "menu_7") {
      currentMenu = newMenu;
      displayMenu_7();
    }
    else if (newMenu == "menu_8") {
      currentMenu = newMenu;
      displayMenu_8();
    }
    else if (newMenu == "menu_9") {
      currentMenu = newMenu;
      displayMenu_9();
    }
    else if (newMenu == "menu_10") {
      currentMenu = newMenu;
      displayMenu_10();
    }
}

// Home screen displays time, humidity and temp
void displayMenu_0(){
  lcd.clear();

  if (RTC.read(tm)) {
    lcd.setCursor(0, 0);
    lcd.print("Time:   ");
    printDigits(tm.Hour);
    lcd.print(':');
    printDigits(tm.Minute);
    lcd.print(':');
    printDigits(tm.Second);
    lcd.setCursor(0, 1);
    lcd.print("T: ");
    lcd.print(tempAct, 2);
    lcd.print(" H: ");
    lcd.print(humAct, 1);
  }  else {
    if (RTC.chipPresent()) {
      // Serial.println("The DS1307 is stopped.  Please run the SetTime");
      // Serial.println("example to initialize the time and begin running.");
      // Serial.println();
    } else {
      // Serial.println("DS1307 read error!  Please check the circuitry.");
      // Serial.println();
    }
  }

}

// Time Settings
void displayMenu_1(){
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Time hh:      ");
  printDigits(tm.Hour);
  lcd.setCursor(0, 1);
  lcd.print("Use + - to Adj");
}

// Time Settings
void displayMenu_2(){
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Time mm:      ");
  printDigits(tm.Minute);
  lcd.setCursor(0, 1);
  lcd.print("Use + - to Adj");
}

// Temp Settings
void displayMenu_3(){
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Temp:       ");
  lcd.print(tempSet, 1);
  lcd.setCursor(0, 1);
  lcd.print("Use + - to Adj");
}

// Hummidity Settings
void displayMenu_4(){
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Humidity:     ");
  lcd.print(humSet, 0);
  lcd.setCursor(0, 1);
  lcd.print("Use + - to Adj");
}

// Light Settings
void displayMenu_5(){
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Light On hh:  ");
  printDigits(lightsOnHh);
  lcd.setCursor(0, 1);
  lcd.print("Use + - to Adj");
}

// Light Settings
void displayMenu_6(){
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Light On mm:  ");
  printDigits(lightsOnMm);
  lcd.setCursor(0, 1);
  lcd.print("Use + - to Adj");
}

void displayMenu_7(){
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Light Off hh: ");
  printDigits(lightsOffHh);
  lcd.setCursor(0, 1);
  lcd.print("Use + - to Adj");
}

// Light Settings
void displayMenu_8(){
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Light Off mm: ");
  printDigits(lightsOffMm);
  lcd.setCursor(0, 1);
  lcd.print("Use + - to Adj");
}

// Ventilation Settings
void displayMenu_9(){
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Vent Frq hh:  ");
  printDigits(ventilationFrqHh);
  lcd.setCursor(0, 1);
  lcd.print("Use + - to Adj");
}

// Ventilation Settings
void displayMenu_10(){
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Vent Dur mm: ");
  printDigits(ventilationDurMm);
  lcd.setCursor(0, 1);
  lcd.print("Use + - to Adj");
}

ну или здесь:

boolean InTimeSpan(int startHh, int startMm, int stopHh, int stopMm){

  long startTimeInSeconds = (long) startHh * 60 * 60 + (long) startMm * 60;
  // // Serial.print("Start time in seconds: ");
  // // Serial.println(startTimeInSeconds);
  long stopTimeInSeconds = (long) stopHh * 60 * 60 + (long) stopMm * 60;
  // // Serial.print("Stop time in seconds: ");
  // // Serial.println(stopTimeInSeconds);
  long currentTimeInSeconds = (long) tm.Hour * 60 * 60 + (long) tm.Minute * 60;
  // // Serial.print("Current time in seconds: ");
  // // Serial.println(currentTimeInSeconds);
    
  boolean isBeforeEnd = currentTimeInSeconds < stopTimeInSeconds;
  // // Serial.print("Is before end time?: ");
  // // Serial.println(isBeforeEnd);  
  boolean isAfterStart = currentTimeInSeconds >= startTimeInSeconds;
  // // Serial.print("Is after start time?: ");
  // // Serial.println(isAfterStart);

  // Deal with timespans that go over midnight
  if (stopTimeInSeconds < startTimeInSeconds) {
    // // Serial.print("In Timespan: ");
    // // Serial.println(isAfterStart || isBeforeEnd);
    return isAfterStart || isBeforeEnd;
  } else {
    // // Serial.print("In Timespan: ");
    // // Serial.println(isAfterStart && isBeforeEnd);
    return isAfterStart && isBeforeEnd;
  }

  // Time span : 22:00 to 2:00
  // Time 21:00
  //  isBeforeEnd: false
  //  isAfterStart: false
  // Time 23:00
  //  isBeforeEnd: false
  //  isAfterStart: true
  // Time 3:00
  //  isBeforeEnd: true
  //  isAfterStart: false
  
}

 Вообще, хотелось бы, разжевать и в рот положить. Спасибо, что откликнулись!

Bloober
Offline
Зарегистрирован: 05.07.2017

wdrakula пишет:

Женя! Опять практика по коррекционной педагогике?

Там, в проекте, который он смотрит, все и лежит.

Если пассажир не в курсе этого, то он рано начал интересоваться проектами. Нужно поучиться.

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

ТС! (Топик Стартер - тот, кто начал тему)

Всему нужно учиться, даже если рукоблудием без знаний заниматься, можно хрен оторвать. Уж простите мой французский.

Вам просто нужно ВСЕ файлы проекта записать в один каталог и открывать.

Согласен, но практика бесценна!

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

wdrakula пишет:

Женя! Опять практика по коррекционной педагогике?

Там, в проекте, который он смотрит, все и лежит.

Нет, никаких практик. Я даже не смотрел, что там в проекте. То, что там должно всё лежать я предполагал (и написал об этом ТС, что "может там же и валяются")), пусть ищет. Я что ли за него искать буду?

Bloober
Offline
Зарегистрирован: 05.07.2017

Тему можно закрыть, разобрался. А Вам господа, нужно поучиться не хамить, а если не хотите помочь, то лучше не засорять тему. Всем спасибо!!!

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

Bloober пишет:

Вам господа, нужно поучиться 

Вы нас поучить решили? Ну-ну ... :)

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Bloober пишет:

Тему можно закрыть, разобрался. А Вам господа, нужно поучиться не хамить, а если не хотите помочь, то лучше не засорять тему. Всем спасибо!!!

Уважеемый, Вы не находите, что сами себе противоречите?

Вам помогли, притом, помогли эффективно - проект, насколько я понял, заработал. И после этого Вы заявляете, что, якобы, помочь можно было и лучше. Да откуда Вам знать, как лучше всего помогать!

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

andriano пишет:

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

А это такое жизненное кредо: постучать в дверь, попросить воды, напиться, а потом насрать на пороге.