При выходе из кода 1 работа продолжится. Параллельно ничего не крутится
А что она должна делать?
@v258 ну… выполнять код 1 если i будет =0
Прочитай про область видимости переменных.
@nik182 ну прочитал бегло, не вижу противоречий… да и строка просто для наглядности перехода в menu()…
Kdr 2 djuhhcs nndh sjjen
прочитай внимательно.
Даю подсказку - в твоем синтаксисе эта строка абсолютно бессмысленна.
А то что в скобочках переменную только видно и она соответственно не определена чему равна и сравнивать её с константой несколько не корректно.
@nik182 да понял я, понял, главное типа задан же!))) это просто строка ни для чего, она к сути вопроса не относится…
@nik182 я просто вопрос задал по причине того, что чем глубже по уровням меню заходишь, тем сильнее подтормаживает меню… я думал из-за параллельного выполнения других процессов… но теперь буду всё-таки меню все перепроверять.
если вы не хотите, чтобы обсуждение сворачивало в сторону - не пишите чепухи в коде. Если такая “чепуха” нашлась - не надо спорить, просто замените ее нормальной строкой.
Теперь надо снова выложить ваш код - исправленный. И лучше реальный, а не какие-то пустые функции, как выше
@b707 выложу, как только в читабельный вид приведу. Кучи мусора закомментированного, не доделок. Проще просматривать почищенный.
@b707 Почистил, выкладываю.
Готов, что будут обсерать.
Честно, я не обижусь. Я двигаюсь к цели, и я её достигну, а всякие обидные слова от людей я постараюсь воспринимать только как слова. А подсказки буду воспринимать как большой праздник.
#include <TimeLib.h>
#include <DS1307RTC.h>
#include <Wire.h>
#include <EEPROM.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>
#include <RotaryEncoder.h>
RotaryEncoder encoder(4, 5); // энкодер (DT, CLK)
#define DS1307_I2C_ADDRESS 0x68 // адресуемся к часам по i2c
// шаг энкодера и пределы в главном меню
#define STP0 7
#define POSMIN0 0
#define POSMAX0 14
// шаг энкодера и пределы подменю1
#define STP1 1
#define POSMIN1 0
#define POSMAX1 3
// шаг энкодера и пределы подменю2
#define STP2 1
#define POSMIN2 0
#define POSMAX2 4
OneWire OneWire(15); // A1 вход 18b20
DallasTemperature ds(&OneWire);
LiquidCrystal_I2C lcd(0x27, 20, 4);
//часовые переменные
byte setMinClockOn;
byte setHorClockOn;
byte setMinClockOff;
byte setHorClockOff;
//переменные энкодера, для перескока и M для подменю
int lastPos, newPos, Poss;
boolean buttonWasUp = true;
byte M = 0;
const byte OUT[5] = {13, 12, 11, 3, 2}; // выходы на реле
bool a, b, c, d; //переменные чтобы организовывать логику работы дополнительных реле
byte pos; //для отображения сработавших реле
byte tempOUTon[4]; // массив с температурой для включения выхода
float tempSensor[4]; // массив куда читается температура
byte menuPos[6]; // массив позиций меню по кнопкам старый вариант
byte qty; // количество датчиков 18b20 и адреса
DeviceAddress sensor1 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
DeviceAddress sensor2 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
DeviceAddress sensor3 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
//DeviceAddress sensor4 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //пока на 3х датчиках
byte grad[8] = {
0b00110,
0b01001,
0b01001,
0b00110,
0b00000,
0b00000,
0b00000,
0b00000
};
void readSet(){
for (byte i = 0; i < qty; i++) tempOUTon[i] = EEPROM.read(i);
}
void outOff(){ // выключает выходы
for (byte i = 0; i < qty; i++) digitalWrite(OUT[i], LOW);
}
//кнопоки 1620 по старойму варианту
/*byte key(){
int val = analogRead(0);
byte batt;
if (val < 50) bt = 5;
else if (val < 150) batt = 3;
else if (val < 350) batt = 4;
else if (val < 550) batt = 2;
else if (val < 800) batt = 1;
else return 0;
return batt;
} */
//часы
byte decToBcd(byte val){
return ( (val/10*16) + (val%10) );
}
byte bcdToDec(byte val){
return ( (val/16*10) + (val%16) );
}
void setDateDs1307(byte second,
byte minute,
byte hour,
byte dayOfWeek,
byte dayOfMonth,
byte month,
byte year)
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.write(0);
Wire.write(decToBcd(second));
Wire.write(decToBcd(minute));
Wire.write(decToBcd(hour));
Wire.write(decToBcd(dayOfWeek));
Wire.write(decToBcd(dayOfMonth));
Wire.write(decToBcd(month));
Wire.write(decToBcd(year));
Wire.endTransmission();
}
void getDateDs1307(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.write(0);
Wire.endTransmission();
Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
*second = bcdToDec(Wire.read() & 0x7f);
*minute = bcdToDec(Wire.read());
*hour = bcdToDec(Wire.read() & 0x3f);
*dayOfWeek = bcdToDec(Wire.read());
*dayOfMonth = bcdToDec(Wire.read());
*month = bcdToDec(Wire.read());
*year = bcdToDec(Wire.read());
}
//здесь pos=1 !!! ЗАКОММЕНТИРОВАНО.не переделано под энкодер.
/*void setClock(){
byte pos = 1;
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
delay(1000);
lcd.clear();
lcd.blink(); //Мигаем курсором чтобы понимать что будем менять
while(key() != 1){
byte KEY = key(); //Обращаемся к процессу чтения кнопок
delay(200);
lcd.setCursor(1, 1);
lcd.print("set & save");
lcd.setCursor(0, 0); // рисуем 0 перед цифрой, если она меньше 10
if (hour < 10) lcd.print("0");
lcd.print(hour);
lcd.print(":");
if (minute < 10) lcd.print("0");
lcd.print(minute);
lcd.print(" ");
if (dayOfMonth < 10) lcd.print("0");
lcd.print(dayOfMonth);
lcd.print("/");
if (month < 10) lcd.print("0");
lcd.print(month);
lcd.print("/");
if (year < 10) lcd.print("0");
lcd.print(year);
lcd.setCursor(pos, 0); // переставляем курсов вдоль часов, минут , секунд и даты
if (KEY == 5 && pos < 13) pos += 3; //+3 это у нас учитывая что все по 2 цифры в часах + разделитель:
else if (KEY == 2 && pos > 1) pos -= 3;
// меняем соответствующие значения в зависимости от позиции
else if (pos == 1 && KEY == 3) hour++;
else if (pos == 1 && KEY == 4) hour--;
else if (pos == 4 && KEY == 3) minute++;
else if (pos == 4 && KEY == 4) minute--;
else if (pos == 7 && KEY == 3) dayOfMonth++;
else if (pos == 7 && KEY == 4) dayOfMonth--;
else if (pos == 10 && KEY == 3) month++;
else if (pos == 10 && KEY == 4) month--;
else if (pos == 13 && KEY == 3) year++;
else if (pos == 13 && KEY == 4) year--;
//условия, чтобы не выйти за пределы значений
if (hour > 23) hour = 0;
else if (minute > 59) minute = 0;
else if (dayOfMonth > 31) dayOfMonth = 0;
else if (month > 12) month = 1;
else if (year > 99) year = 0;
}
//вгружаем установленные значения в часы
setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
lcd.noBlink(); // прекращаем мигать, пишем, что сохранено, и через секунду выходим из настройки часов
lcd.clear();
lcd.print("save");
delay(1000);
}
*/
//меню настроек pos=0 !!!
void setMenu(){
outOff(); // выключаем выходы
lcd.clear();
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; //переменные часов. Нужно попробовать сделать их глобальными
getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
// Главное меню
while (M == 0) {
lcd.setCursor(0, 0);
lcd.print("menu1 menu2 menu3");
//читаю энкодер
encoder.tick();
newPos = encoder.getPosition() * STP0; //на сколько двигаем и предельные положения
if (newPos < POSMIN0) {
encoder.setPosition(POSMIN0 / STP0);
newPos = POSMIN0;
}
else if (newPos > POSMAX0) {
encoder.setPosition(POSMAX0 / STP0);
newPos = POSMAX0;
}
if (lastPos != newPos) {
lcd.setCursor(lastPos, 1);
lcd.print(" ");
lcd.setCursor(newPos, 1);
lcd.print(" ^ ");
lastPos = newPos;
}
// если кнопка нажата, то переходим в подменю соответствующего пункта.
boolean buttonIsUp = digitalRead(6);
if (buttonWasUp && !buttonIsUp) {
delay(10);
buttonIsUp = digitalRead(6);
if (!buttonIsUp && newPos == 0) { lcd.clear(); delay(500); M = 1; }
if (!buttonIsUp && newPos == 2) { lcd.clear(); delay(500); M = 2; }
if (!buttonIsUp && newPos == 4) { lcd.clear(); delay(500); M = 3; }
}
}
// Подменю 1 пункта меню.
while (M == 1) {
lcd.setCursor(1, 0);
lcd.print("temp1 ");
lcd.print(tempOUTon[0]);
lcd.setCursor(1, 1);
lcd.print("temp2 ");
lcd.print(tempOUTon[1]);
lcd.setCursor(1, 2);
lcd.print("temp3 ");
lcd.print(tempOUTon[2]);
lcd.setCursor(1, 3);
lcd.print("Exit");
// смотрю энкодер
encoder.tick();
newPos = encoder.getPosition() * STP1;
if (newPos < POSMIN1) {
encoder.setPosition(POSMIN1 / STP1);
newPos = POSMIN1;
}
else if (newPos > POSMAX1) {
encoder.setPosition(POSMAX1 / STP1);
newPos = POSMAX1;
}
// перемещаем курсор
if (lastPos != newPos) {
lcd.setCursor(0, newPos);
lcd.print(">");
lcd.setCursor(0, lastPos);
lcd.print(" ");
lastPos = newPos;
}
// тут меняем tempOUTon
// Выходим в главное меню, через посещение loop. не получилось пока придумать как подругому
boolean buttonIsUp = digitalRead(6);
if (buttonWasUp && !buttonIsUp) {
delay(10);
buttonIsUp = digitalRead(6);
if (!buttonIsUp && newPos == 3) { lcd.clear(); delay(500); M = 0; setMenu(); }
}
}
// второе подменю
// третье поменю
}
// опрос температуры 18b20 пока вручную и пока 3
void getTemp(){
ds.requestTemperatures();
tempSensor[0] = 11;//ds.getTempC(sensor1);
tempSensor[1] = 12;//ds.getTempC(sensor2);
tempSensor[2] = 13;//ds.getTempC(sensor3);
// tempSensor[3] = 14;//ds.getTempC(sensor4);
}
void setup() {
lcd.init();
lcd.backlight();
lcd.begin(20,4);
Serial.begin(9600);
ds.begin();
qty = 3; // пока 3 датчика
for (int i = 0; i < qty; i++) pinMode(OUT[i], OUTPUT); //пины как выходы и изначально неактивные
for (int i = 0; i < qty; i++) digitalWrite(OUT[i], LOW);
lcd.createChar(1, grad);
encoder.setPosition(20 / STP0);
pinMode (2, OUTPUT); // выход на 5ое реле для циркуляционного насоса
digitalWrite(2, LOW); //обнуляем состояние выхода при загрузке
pinMode(6, INPUT_PULLUP); // пин для кнопки энкодера
// установка временных зон. в моем случае ночь и день, чтобы задавать разные температуры ночью-днем. в меню завести в подменю2!!!
setMinClockOn = 00;
setHorClockOn = 23;
setMinClockOff = 00;
setHorClockOff = 7;
readSet(); // читаем настройки из еепром
}
void loop()
{
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
boolean buttonIsUp = digitalRead(6);
if (buttonWasUp && !buttonIsUp) {
delay(10);
buttonIsUp = digitalRead(6);
if (!buttonIsUp) { lcd.clear(); delay(500); setMenu(); }
}
getTemp(); // опрашиваю датчикм
// включаем реле, если температура не сходится у установленной и меняем установленную температуру в зависимости от времени.
if (hour > setHorClockOff && hour < setHorClockOn) {
for (int i = 0; i < qty; i++){
tempOUTon[i] = (EEPROM.get(i, tempOUTon[i]))-1;
}
}
if (hour < setHorClockOff && hour > setHorClockOn) {
for (int i = 0; i < qty; i++){
tempOUTon[i] = (EEPROM.get(i, tempOUTon[i]));
}
}
for (int i = 0; i < qty; i++) {
if (tempSensor[i] < tempOUTon[i]) digitalWrite(OUT[i], HIGH);
else digitalWrite(OUT[i], LOW);
//присваиваем переменным a b c d значения температур датчиков с 1 по 4.
a = digitalRead(OUT[0]);
b = digitalRead(OUT[1]);
c = digitalRead(OUT[2]);
d = digitalRead(OUT[3]);
// создаем условие, что если хоть один выход из 4-х активирован, то активируем выход 5, который, в моем случае запускает циркуляционный насос.
if ( a != 0 | b != 0 | c != 0 | d != 0 ) digitalWrite(2, HIGH);
else digitalWrite(2, LOW);
}
//Выводим на экран
// lcd.init();
for (int j = 0; j < qty; j++){
lcd.setCursor(0, j);
lcd.print(tempSensor[j]); //текущая температура
lcd.write(1);
lcd.print("C -> ");
lcd.print(tempOUTon[j]); //установленная температура
lcd.write(1);
lcd.print("C ");
// состояние реле напротив соответствующего пункта
if (digitalRead(OUT[j])) lcd.print("+");
else lcd.print("-");
}
delay(200);
}
просто для того, чтобы всё подряд не перепроверять:
с 211 по 249 строку всё вроде бы работает стабильно(для меня).
с 250 по 283 не появляется “>” пока энкодер не покрутишь, и появляется на 2 строке. При перемещении подтормаживает люто, как будто даже не через шаг считывает, а через 3-5 шагов…
В целом задачу обрисуйте
Работает или нет? Если работает, но не так, как планировали - опишите в чем разница.
@b707 над вашим же сообщением и написал в чем мои смущения. Или не так как-то?
@b707 я кажись понял, вы видите в оповещениях только те, сообщения, где есть обращение, видимо, я же “чайник”…
я же комп только 2 недели назад достал, ёлки зелёные…
1.Цель этого кода напиши. Об этом 707ой пишет.
2. Свою цель напиши: хочешь запустить этот код или с чем-то разобраться?
3. Если цель учиться, то нужно поставить себе задачу проще, для начала.
Вы считаете это - ясной постановкой задачи? (ниже)
Что значит “работает”? Что значит стабильно? Если все работает как надо - почему вы вообще обращаете внимание других на эти строчки?
Я понимаю, когда занимаешься каким-то проектом не первую неделю - кажется, что и все остальные должны понимать тебя с полуслова. Но это не так. Я не в курсе вашего проекта вообще, код не читал. Обьясните же, что вы вообще делаете и в чем проблема.
Хотя можете не объяснять - ваше право. Просто число желающих помочь будет меньше.
@b707
@WladDrakula
3 датчика ds18b20 по onewire, считываем с них температуры.
задаем требуемые температуры, в соответствии с заданными поддерживаем текущие по средствам реле, с нагревателями и доп. реле с циркуляционным насосом в случае активности хотя бы одного из выходов, управляющих нагревателем. меняем уставку температуры в зависимости от времени(в данный момент в коде это 1 градус в минус ночью, потом это перекочует в меню).
Так логику нужно было изложить?
на данный момент меня смущает ранее упомянутая проблема в строках 250-283…