ESP 32 отключение реле через определенное время
- Войдите на сайт для отправки комментариев
Чт, 12/03/2020 - 22:57
Доброго времени суток.
Прошу оказать содействие в написании скетча.
Большая часть меня устраивает, но необходимо решить 2 вопроса:
1. отключение реле при нажатии кнопки через определенное время
2. передача данных от датчиков температуры и влажности по критериям (период, не чаще раз в минуту и при изменении средних данных)
Я использую ESP 32 для умного дома с использованием ПО MajorDoMo.
Буду благодарен любым идеям и дельным рекомендациям.
// Блок [Подключение библиотек] ************************************************ #include <WiFi.h> extern "C" { #include "freertos/FreeRTOS.h" #include "freertos/timers.h" } #include <AsyncMqttClient.h> #include <OneWire.h> #include <Adafruit_Sensor.h> // для датчика температуры #include <Adafruit_BME280.h> // для датчика температуры #define SDA_2 15 // на плате RXD #define SCL_2 23 // на плате TXD // END Блок [Подключение библиотек] ******************************************** // Блок [Подключение к сети WI-FI] ********************************************* #define WIFI_SSID "SD 2.4G_2" // Имя WI-FI сети #define WIFI_PASSWORD "хххххх" // Пароль WI-FI сети #define MQTT_HOST "192.168.2.3" // IP адрес MQTT сервер #define MQTT_PORT 1883 // END Блок [Подключение к сети WI-FI] ***************************************** // создаем объекты для управления MQTT-клиентом: AsyncMqttClient mqttClient; TimerHandle_t mqttReconnectTimer; TimerHandle_t wifiReconnectTimer; long last_mls = millis(); long Off_mls = millis(); // Отключение реле при отсутствии управления из МД long MaxTime = 900000; // Максимальное время включения реле 900000-15 мин const int ButtonRin_1 = 26; // GPIO-контакт, к которому подключена кнопка №1 const int ButtonRin_2 = 25; // GPIO-контакт, к которому подключена кнопка №2 const int ButtonRin_3 = 33; // GPIO-контакт, к которому подключена кнопка №3---33 const int ButtonRin_4 = 32; // GPIO-контакт, к которому подключена кнопка №4---32 int lastButtonState1; // текущее значение входного контакта, кнопки №1 int lastButtonState2; // текущее значение входного контакта, кнопки №2 int lastButtonState3; // текущее значение входного контакта, кнопки №3 int lastButtonState4; // текущее значение входного контакта, кнопки №4 const int RelePin1 = 13; // GPIO-контакт, к которому подключено реле №1 const int RelePin2 = 12; // GPIO-контакт, к которому подключено реле №2 const int RelePin3 = 14; // GPIO-контакт, к которому подключено реле №3 const int RelePin4 = 27; // GPIO-контакт, к которому подключено реле №4 int ReleState1 = LOW; // текущее состояние выходного контакта №1 HIGH int ReleState2 = LOW; // текущее состояние выходного контакта №2 int ReleState3 = LOW; // текущее состояние выходного контакта №3 int ReleState4 = LOW; // текущее состояние выходного контакта №4 const int DatchUrovnya_1 = 39; // GPIO-контакт, к которому подключен датчик уровня 1 int lastDatchUrovnya_1; // текущее значение датчика уровня воды №1 const int potPin = 36; // GPIO-контакт, к которому подключен датчик влажности земли // для температуры Adafruit_BME280 bme1; // I2C Adafruit_BME280 bme2; // I2C unsigned long delayTime; float Temperature1 = 0.0; float Temperature2 = 0.0; float korTemperature1 = 0.0; float korTemperature2 = 0.0; int oldTemperature1 = 0.0; int oldTemperature2 = 0.0; int okruglTemperature1 = 0; int okruglTemperature2 = 0; float Humidity1 = 0.0; float Humidity2 = 0.0; float oldHumidity1 = 0.0; float oldHumidity2 = 0.0; int okruglHumidity1 = 0; int okruglHumidity2 = 0; int VlazhnostZ1 = 0; // переменная для хранения данных от датчика влажности земли: int oldVlazhnostZ1 = 0; int okruglVlazhnostZ1 = 0; // void connectToWifi() { Serial.println("Connecting to Wi-Fi..."); // "Подключаемся к WiFi..." WiFi.begin(WIFI_SSID, WIFI_PASSWORD); } void connectToMqtt() { Serial.println("Connecting to MQTT..."); // "Подключаемся к MQTT..." mqttClient.connect(); } void WiFiEvent(WiFiEvent_t event) { Serial.printf("[WiFi-event] event: %d\n", event); switch(event) { case SYSTEM_EVENT_STA_GOT_IP: Serial.println("WiFi connected"); // "Подключились к WiFi" Serial.println("IP address: "); // "IP-адрес: " Serial.println(WiFi.localIP()); connectToMqtt(); break; case SYSTEM_EVENT_STA_DISCONNECTED: Serial.println("WiFi lost connection"); // "WiFi-связь потеряна" // делаем так, чтобы ESP32 // не переподключалась к MQTT // во время переподключения к WiFi: xTimerStop(mqttReconnectTimer, 0); xTimerStart(wifiReconnectTimer, 0); break; } } // в этом фрагменте добавляем топики, // на которые будет подписываться ESP32: void onMqttConnect(bool sessionPresent) { Serial.println("Connected to MQTT."); // "Подключились по MQTT." Serial.print("Session present: "); // "Текущая сессия: " Serial.println(sessionPresent); // подписываем ESP32 на топик «ESP32-01/RELE_1»: uint16_t packetIdSub1 = mqttClient.subscribe("ESP32-01/RELE_1", 0); Serial.print("Subscribing at QoS 0, packetId: "); // "Подписываемся при QoS 0, ID пакета: " // подписываем ESP32 на топик «ESP32-01/RELE_2»: uint16_t packetIdSub2 = mqttClient.subscribe("ESP32-01/RELE_2", 0); Serial.print("Subscribing at QoS 0, packetId: "); // "Подписываемся при QoS 0, ID пакета: " // подписываем ESP32 на топик «ESP32-01/RELE_3»: uint16_t packetIdSub3 = mqttClient.subscribe("ESP32-01/RELE_3", 0); Serial.print("Subscribing at QoS 0, packetId: "); // "Подписываемся при QoS 0, ID пакета: " // подписываем ESP32 на топик «ESP32-01/RELE_4»: uint16_t packetIdSub4 = mqttClient.subscribe("ESP32-01/RELE_4", 0); Serial.print("Subscribing at QoS 0, packetId: "); // "Подписываемся при QoS 0, ID пакета: " // подписываем ESP32 на топик «ESP32-01/Temperatura1»: uint16_t temperature1_topic1 = mqttClient.subscribe("ESP32-01/Temperatura-1", 0); Serial.print("Subscribing at QoS 0, packetId: "); // "Подписываемся при QoS 0, ID пакета: " // подписываем ESP32 на топик «ESP32-01/Humidity-1»: uint16_t humidity1_topic1 = mqttClient.subscribe("ESP32-01/Humidity-1", 0); Serial.print("Subscribing at QoS 0, packetId: "); // "Подписываемся при QoS 0, ID пакета: " // подписываем ESP32 на топик «ESP32-01/Temperatura2»: uint16_t temperature1_topic2 = mqttClient.subscribe("ESP32-01/Temperatura-2", 0); Serial.print("Subscribing at QoS 0, packetId: "); // "Подписываемся при QoS 0, ID пакета: " // подписываем ESP32 на топик «ESP32-01/Humidity-2»: uint16_t humidity1_topic2 = mqttClient.subscribe("ESP32-01/Humidity-2", 0); Serial.print("Subscribing at QoS 0, packetId: "); // "Подписываемся при QoS 0, ID пакета: " // подписываем ESP32 на топик «ESP32-01/Vlazhnost-Z-1»: uint16_t vlazhnostZ1 = mqttClient.subscribe("ESP32-01/Vlazhnost-Z-1", 0); Serial.print("Subscribing at QoS 0, packetId: "); // "Подписываемся при QoS 0, ID пакета: " // подписываем ESP32 на топик «ESP32-01/Vlazhnost-Z-1»: uint16_t DatchUrovnya_1 = mqttClient.subscribe("ESP32-01/DatchUrovnya_1", 0); Serial.print("Subscribing at QoS 0, packetId: "); // "Подписываемся при QoS 0, ID пакета: " Serial.println("Выводим packetIdSub1:"); Serial.println(packetIdSub1); Serial.println("Выводим packetIdSub2:"); Serial.println(packetIdSub2); Serial.println("Выводим packetIdSub3:"); Serial.println(packetIdSub3); Serial.println("Выводим packetIdSub4:"); Serial.println(packetIdSub4); } void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) { Serial.println("Disconnected from MQTT."); // "Произошло отключение от MQTT." if (WiFi.isConnected()) { xTimerStart(mqttReconnectTimer, 0); } } void onMqttSubscribe(uint16_t packetId, uint8_t qos) { Serial.println("Subscribe acknowledged."); // "Подписка подтверждена." Serial.print(" packetId: "); // " ID пакета: " Serial.println(packetId); Serial.print(" qos: "); // " уровень качества обслуживания: " Serial.println(qos); } void onMqttUnsubscribe(uint16_t packetId) { Serial.println("Unsubscribe acknowledged."); // "Отписка подтверждена." Serial.print(" packetId: "); Serial.println(packetId); } void onMqttPublish(uint16_t packetId) { Serial.println("Publish acknowledged."); // "Публикация подтверждена." Serial.print(" packetId: "); Serial.println(packetId); } // этой функцией управляется то, что происходит // при получении того или иного сообщения в топике «ESP32-01/RELE_1»; // (если хотите, можете ее отредактировать): void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total) { Serial.print("Message arrived ["); Serial.print(topic); Serial.print("] "); String strTopic = String(topic); String strPayload = String((char*)payload); String messageTemp; for (int i = 0; i < len; i++) { messageTemp += (char)payload[i]; Serial.print((char)payload[i]); } Serial.println(); // Блок [Управление Реле 1 из MajorDomo] ************************************ if (strTopic == "ESP32-01/RELE_1") { if ((char)payload[0] == '1') { ReleState1 = true; digitalWrite(RelePin1, ReleState1); } else { ReleState1 = false; digitalWrite(RelePin1, ReleState1); } } // END Блок [Управление Реле 1 из MajorDomo] ******************************** // Блок [Управление Реле 2 из MajorDomo] ************************************ if (strTopic == "ESP32-01/RELE_2") { if ((char)payload[0] == '1') { ReleState2 = true; digitalWrite(RelePin2, ReleState2); } else { ReleState2 = false; digitalWrite(RelePin2, ReleState2); } } // Блок [Управление Реле 2 из MajorDomo] ************************************ // Блок [Управление Реле 3 из MajorDomo] ************************************ if (strTopic == "ESP32-01/RELE_3") { if ((char)payload[0] == '1') { ReleState3 = true; digitalWrite(RelePin3, ReleState3); } else { ReleState3 = false; digitalWrite(RelePin3, ReleState3); } } // Блок [Управление Реле 3 из MajorDomo] ************************************ // Блок [Управление Реле 4 из MajorDomo] ************************************ if (strTopic == "ESP32-01/RELE_4") { if ((char)payload[0] == '1') { ReleState4 = true; digitalWrite(RelePin4, ReleState4); } else { ReleState4 = false; digitalWrite(RelePin4, ReleState4); } } // Блок [Управление Реле 4 из MajorDomo] ************************************ } void setup() { // делаем контакт, к которому подключена кнопка, входным контактом: pinMode(ButtonRin_1, INPUT); pinMode(ButtonRin_2, INPUT); pinMode(ButtonRin_3, INPUT); pinMode(ButtonRin_4, INPUT); pinMode(DatchUrovnya_1, INPUT); // делаем контакт, к которому подключено реле, выходным контактом: pinMode(RelePin1, OUTPUT); pinMode(RelePin2, OUTPUT); pinMode(RelePin3, OUTPUT); pinMode(RelePin4, OUTPUT); Serial.begin(115200); // для температуры Serial.println(F("BME280 test")); Wire.begin(); Wire1.begin(SDA_2, SCL_2); bool status_TH1 = bme1.begin(0x76); if (!status_TH1) { Serial.println("Could not find a valid BME280_1 sensor, check wiring!"); //while (1); в случае зависания датчика нужно, чтоб остальные функции работали } bool status_TH2 = bme2.begin(0x76, &Wire1); if (!status_TH2) { Serial.println("Could not find a valid BME280_2 sensor, check wiring!"); //while (1); в случае зависания датчика нужно, чтоб остальные функции работали } Serial.println(); // для температуры // // создаются таймеры для повторного подключения к MQTT-брокеру и WiFi-роутеру в случае, если соединение будет потеряно. mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToMqtt)); wifiReconnectTimer = xTimerCreate("wifiTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToWifi)); WiFi.onEvent(WiFiEvent); mqttClient.onConnect(onMqttConnect); mqttClient.onDisconnect(onMqttDisconnect); mqttClient.onSubscribe(onMqttSubscribe); mqttClient.onUnsubscribe(onMqttUnsubscribe); mqttClient.onMessage(onMqttMessage); // при отключении работает кнопка... mqttClient.onPublish(onMqttPublish); mqttClient.setServer(MQTT_HOST, MQTT_PORT); connectToWifi(); } void button_1(){ // считываем состояние кнопки // и сохраняем его в локальную переменную: boolean btnPress1 = digitalRead(ButtonRin_1); if (btnPress1 && !lastButtonState1){ delay(50); // защита от дребезга (300 мсек.) btnPress1 = digitalRead(ButtonRin_1); if(btnPress1){ ReleState1 = !ReleState1; digitalWrite(RelePin1, ReleState1); uint16_t packetIdPub1 = mqttClient.publish("ESP32-01/RELE_1", 0, true, String(ReleState1).c_str()); } } lastButtonState1 = btnPress1; // сохраняем текущее значение кнопки в переменную } void button_2(){ // считываем состояние кнопки // и сохраняем его в локальную переменную: boolean btnPress2 = digitalRead(ButtonRin_2); if (btnPress2 && !lastButtonState2){ delay(50); // защита от дребезга (300 мсек.) btnPress2 = digitalRead(ButtonRin_2); if(btnPress2){ ReleState2 = !ReleState2; digitalWrite(RelePin2, ReleState2); uint16_t packetIdPub2 = mqttClient.publish("ESP32-01/RELE_2", 0, true, String(ReleState2).c_str()); } } lastButtonState2 = btnPress2; // сохраняем текущее значение кнопки в переменную } void button_3(){ // считываем состояние кнопки // и сохраняем его в локальную переменную: boolean btnPress3 = digitalRead(ButtonRin_3); if (btnPress3 && !lastButtonState3){ delay(50); // защита от дребезга (300 мсек.) btnPress3 = digitalRead(ButtonRin_3); if(btnPress3){ ReleState3 = !ReleState3; digitalWrite(RelePin3, ReleState3); uint16_t packetIdPub3 = mqttClient.publish("ESP32-01/RELE_3", 0, true, String(ReleState3).c_str()); } } lastButtonState3 = btnPress3; // сохраняем текущее значение кнопки в переменную } void button_4(){ // считываем состояние кнопки // и сохраняем его в локальную переменную: boolean btnPress4 = digitalRead(ButtonRin_4); if (btnPress4 && !lastButtonState4){ delay(50); // защита от дребезга (300 мсек.) btnPress4 = digitalRead(ButtonRin_4); if(btnPress4){ ReleState4 = !ReleState4; digitalWrite(RelePin4, ReleState4); uint16_t packetIdPub4 = mqttClient.publish("ESP32-01/RELE_4", 0, true, String(ReleState4).c_str()); } } lastButtonState4 = btnPress4; // сохраняем текущее значение кнопки в переменную } // Блок [Температуры-1] **************************************** void top_Temperature1() { korTemperature1 = (bme1.readTemperature() - 1.2); // корректировка температуры Temperature1 = korTemperature1; okruglTemperature1 = round(Temperature1); Serial.println("Выводим знечение температуры Temperature 1 окр:"); Serial.println(okruglTemperature1); Serial.println(Temperature1); delay(300); // задержка отправки if (oldTemperature1 != okruglTemperature1){ Serial.println("Отправка в МД температуры 1"); uint16_t temperature1_topic1 = mqttClient.publish("ESP32-01/Temperatura-1", 0, true, String(okruglTemperature1).c_str()); } oldTemperature1=okruglTemperature1; } // END Блок [Температуры-1] ************************************ // Блок [Влажности-1] **************************************** void top_Humidity1() { Humidity1 = bme1.readHumidity(); okruglHumidity1 = round(Humidity1); Serial.println("Выводим знечение влажности Humidity 1 окр:"); Serial.println(okruglHumidity1); Serial.println(Humidity1); delay(300); // задержка отправки if (oldHumidity1 != okruglHumidity1){ Serial.println("Отправка в МД влажности 1"); uint16_t humidity_topic1 = mqttClient.publish("ESP32-01/Humidity-1", 0, true, String(okruglHumidity1).c_str()); } oldHumidity1=okruglHumidity1; } // END Блок [Влажности-1] ************************************ // // Блок [Температуры-2] **************************************** void top_Temperature2() { korTemperature2 = (bme2.readTemperature() - 1.32); // корректировка температуры Temperature2 = korTemperature2; okruglTemperature2 = round(Temperature2); Serial.println("Выводим знечение температуры Temperature 2 окр:"); Serial.println(okruglTemperature2); Serial.println(Temperature2); delay(300); // задержка отправки if (oldTemperature2 != okruglTemperature2){ Serial.println("Отправка в МД температуры 2"); uint16_t temperature1_topic2 = mqttClient.publish("ESP32-01/Temperatura-2", 0, true, String(okruglTemperature2).c_str()); } oldTemperature2=okruglTemperature2; } // END Блок [Температуры-1] ************************************ // Блок [Влажности-2] **************************************** void top_Humidity2() { Humidity2 = bme2.readHumidity(); okruglHumidity2 = round(Humidity2); Serial.println("Выводим знечение влажности Humidity 2 окр:"); Serial.println(okruglHumidity2); Serial.println(Humidity2); delay(300); // задержка отправки if (oldHumidity2 != okruglHumidity2){ Serial.println("Отправка в МД влажности 2"); uint16_t humidity_topic2 = mqttClient.publish("ESP32-01/Humidity-2", 0, true, String(okruglHumidity2).c_str()); } oldHumidity2=okruglHumidity2; } // END Блок [Влажности-2] ************************************ // // Блок [Влажность земли-1] **************************************** void top_VlazhnostZ1() { //считываем данные от влажности земли: VlazhnostZ1 = analogRead(potPin); okruglVlazhnostZ1 = round(VlazhnostZ1); Serial.println("Выводим знечение влажности VlazhnostZ1 окр:"); Serial.println(okruglVlazhnostZ1); Serial.println(VlazhnostZ1); delay(300); // задержка отправки // начало поиск среднего unsigned long time11=0; unsigned long time22=0; float SUM = 0; float resalt1; float resalt2; float sred = 0; int n = 0; if ((millis()-time11)>=10000) { SUM = SUM+okruglVlazhnostZ1; n = n + 1; Serial.println("Выводим знечение n:"); Serial.println(n); time11 = millis(); Serial.println("Выводим знечение SUM:"); Serial.println(SUM); } if ((millis()-time22)>=300000) { sred = SUM/n; n = 0; SUM = 0; time22 = millis(); Serial.println("Выводим знечение sred:"); Serial.println(sred); } // END поиск среднего if (oldVlazhnostZ1 != okruglVlazhnostZ1){ Serial.println("Отправка в МД влажности VlazhnostZ 1"); uint16_t VlazhnostZ1 = mqttClient.publish("ESP32-01/Vlazhnost-Z-1", 0, true, String(VlazhnostZ1).c_str()); } oldVlazhnostZ1=okruglVlazhnostZ1; } // END Блок [Влажность земли-1] ************************************ // // Блок [Датчик уровня воды №1] **************************************** void top_DatchUrovnya_1() { //считываем данные от датчика уровня воды 1: // и сохраняем его в локальную переменную: boolean UrovenPress1 = digitalRead(DatchUrovnya_1); Serial.println("Выводим UrovenPress1"); Serial.println(UrovenPress1); if (UrovenPress1 && !lastDatchUrovnya_1){ delay(50); // защита от дребезга (300 мсек.) UrovenPress1 = digitalRead(DatchUrovnya_1); if(UrovenPress1){ UrovenPress1 = !UrovenPress1; //digitalWrite(RelePin4, ReleState4); uint16_t DatchUrovnya_1 = mqttClient.publish("ESP32-01/DatchUrovnya_1", 0, true, String(DatchUrovnya_1).c_str()); } } lastDatchUrovnya_1 = UrovenPress1; // сохраняем текущее значение датчика уровня воды №1 } // END Блок [Датчик уровня воды №1] ************************************ // void loop() { if (millis() - last_mls > 10000) { // Проеверка подключения к сети (раз в 60 сек.) last_mls = millis(); // Serial.println(top_Temperature1); //reconnect_server(); top_Temperature1(); // Публикация данных температуры на MQTT top_Humidity1(); // Публикация данных влажности на MQTT top_Temperature2(); // Публикация данных температуры на MQTT top_Humidity2(); // Публикация данных влажности на MQTT top_VlazhnostZ1(); // Публикация данных влажности земли на MQTT // top_DatchUrovnya_1(); // Публикация данных датчика уровня воды на MQTT } // Блок контроля времени включения if (millis() - Off_mls > MaxTime) { // Проеверка подключения к сети (раз в 60 сек.) Off_mls = millis(); Serial.println("Выводим значение Off_mls:"); Serial.println(Off_mls); Serial.println("Выводим значение ReleState1:"); Serial.println(ReleState1); if (digitalRead(ReleState1) == 1) { ReleState1 = 0; digitalWrite(RelePin1, ReleState1); //uint16_t packetIdPub1 = mqttClient.publish("ESP32-01/RELE_1", 0, true, String(ReleState1).c_str()); //lastButtonState1 = ReleState1; // сохраняем текущее значение кнопки в переменную } if (digitalRead(ReleState2) == 1) { ReleState2 = 0; digitalWrite(RelePin2, ReleState2); //uint16_t packetIdPub2 = mqttClient.publish("ESP32-01/RELE_2", 0, true, String(ReleState2).c_str()); //lastButtonState2 = ReleState2; // сохраняем текущее значение кнопки в переменную } if (digitalRead(ReleState3) == 1) { ReleState3 = 0; digitalWrite(RelePin3, ReleState3); //uint16_t packetIdPub3 = mqttClient.publish("ESP32-01/RELE_3", 0, true, String(ReleState3).c_str()); //lastButtonState3 = ReleState3; // сохраняем текущее значение кнопки в переменную } if (digitalRead(ReleState4) == 1) { ReleState4 = 0; digitalWrite(RelePin4, ReleState4); //uint16_t packetIdPub4 = mqttClient.publish("ESP32-01/RELE_4", 0, true, String(ReleState4).c_str()); //lastButtonState4 = ReleState4; // сохраняем текущее значение кнопки в переменную } } // Блок контроля времени включения button_1(); button_2(); button_3(); button_4(); }
Самое дельное - обратиться к автору кода.
Если б это было возможно я так бы и сделал, но этот код я слепил самостоятельно из того, что удалось найти на просторах Интернета.
Теперь его необходимо доработать, оптимизировать и использовать мне и другим желающим.
Код не "лепят", код - пишут.
Теперь его необходимо доработать, оптимизировать и использовать мне и другим желающим.
кому необходимо?
Если вы хотели "советов по оптимизации" - то в первую очередь стоило бы избавится от дублирования кода. Например, четыре копии процедур для кнопок - это ламерство :). Если хотите по простому - используйте массив для пинов кнопок и напишите одну процедуру, где пробегайте по всем четырем кнопкам. Если чуть сложнее - создайте класс кнопки с четырьмя экземплярами.
Потом точно так же уберите одинаковые процедуры для датчиков... В итоге, думаю, длина кода уменьшится строк на 200 и вам самому станет проще в нем разбираться.
Код не "лепят", код - пишут.
Вот по этому у меня и получается код лепить, потому что вместо дельных рекомендаций только тупые приколы.
Без обид, да, я не силен в написании кода, по этому и обращаюсь за консультацией к более образованным специалистам, но как показывает практика, специалистов на форумах нет, или им нет дела до моих проблем, а если и дают рекомендации то поверхностные, которые снова заставляют рыскать по Интернету и лепить код.
У более образованных специалистов нет других занятий, кроме как устраивать индивидуальные курсы повышения квалификации для каждого страждущего.
У более образованных специалистов нет других занятий, кроме как устраивать индивидуальные курсы повышения квалификации для каждого страждущего.
Ни одной дельной консультации по коду, только рекомендации в глобальных подходах.
"Рекомендую применить матрицу ВСЕРЕАЛИЗАЦИИ"
Ни одной дельной консультации по коду, только рекомендации в глобальных подходах.
Ни одной дельной консультации по коду, только рекомендации в глобальных подходах.
"Рекомендую применить матрицу ВСЕРЕАЛИЗАЦИИ"
Повторяю вопрос, с чего ты решил, что у кого-то есть время и желание разбираться в ПЯТИ СОТНЯХ строк твоей графомании? Смотри здраво на ситуацию.
Вот и я о том, замечаю, что в последнее время форумы существуют только для пизде*а и под*бок.
"последнее время" ? - а сколько вы так ходите побираетесь по инету? Год. два, десять? Может пора уже научится код писать самому. а не дергать из примеров?
Поймите, форумы не могут заменить институский курс программирования или учебник на 1000 страниц. Это вы должны освоить сами. На форуме могут подсказать какие-то детали или помочь исправить ошибку. Но ожидать, что мы тут сообща будем дописывать ваш код.... это наивно.
Реле увидел, аж 4 штуки, кнопки не увидел ни одной. Критерии тоже виртуальны (ну типа я их тоже не увидел). А описать словами, чего хотите в облом? Если это сделаете Вам поступят корыстные предложения .