отключение питания портит всю картину
- Войдите на сайт для отправки комментариев
Имеется код для управления масляным котлом, как бы основное работает и устраивает но есть несколько проблем которые возможно решить только с вашей помощью:
1) Самое гнустное то что показания шагового двигателя берутся с епром, но и по другому мне нельзя (надо чтоб после отключения я знал где находится вентиль) Здесь как раз и "зарыта собака" при каждот включении вентиль прокручивается на те обороты которые считывает с епром. Да, конечно можно убрать запись с епром и взять переменную int и использовать с минусовым значением (закрутить, открутить) , но хотелось бы отсчет от ноля как сейчас.
2) ну и remotexy ? но здесь наверное никто не поможет.. не могу управлть с телефона, в телефон приходят а ноборот никак...
/* ВСЕ для Андроида*/ #define REMOTEXY_MODE__HARDSERIAL #include <RemoteXY.h> /* настройки соединения */ #define REMOTEXY_SERIAL Serial3 #define REMOTEXY_SERIAL_SPEED 9600 /* конфигурация интерфейса */ #pragma pack(push, 1) uint8_t RemoteXY_CONF[] = { 4,33,41,0,6,15,1,5,32,6 ,47,51,51,2,7,21,19,25,22,6 ,2,67,1,18,35,24,6,6,11,67 ,1,30,10,28,13,1,11,67,1,3 ,10,23,13,1,11 }; /* структура определяет все переменные вашего интерфейса управления */ struct { /* input variable */ int8_t podachaM_x; /* =-100..100 координата x положения джойстика */ int8_t podachaM_y; /* =-100..100 координата y положения джойстика */ int16_t edit_step; /* −32767.. +32767 */ /* output variable */ char Maslo[11]; /* =строка UTF8 оканчивающаяся нулем */ char ULICA[11]; /* =строка UTF8 оканчивающаяся нулем */ char KOTEL[11]; /* =строка UTF8 оканчивающаяся нулем */ /* other variable */ uint8_t connect_flag; /* =1 if wire connected, else =0 */ } RemoteXY; #pragma pack(pop) #include <EEPROM.h> #define ENCODER_DO_NOT_USE_INTERRUPTS // без прерываний. #include <Encoder.h> ///////для датчиков температуры #include <OneWire.h>// для датчиков температуры #define dallas_1 3 //пин для датчика котла (X_MIN_PIN 3) #define dallas_2 2 //пин для датчика улицы (X_MAX_PIN 2) OneWire ds_1 (dallas_1); OneWire ds_2 (dallas_2); unsigned long time=0; // тоже для измерения температуры boolean flag=0; // для измерения температуры byte data[12]; // массив float temp_1; // переменная температуры котла float temp_2; // переменная температуры улицы int raw; // переменная для арифметичесского вычитания в расчетах температуры #include <AccelStepper.h>// библиотека шаговиков AccelStepper Stepper1(1,54,55); //название движка и 1=по умолчанию (для драйвера 4488). 54=STEP . 55=DIR #define dirPin 55 //#define X_STEP_PIN54 ,#define X_DIR_PIN55, #define X_ENABLE_PIN38 #define stepPin 54 // здесь экран #include <LiquidCrystal.h> //Библиотека LCD LiquidCrystal lcd(16, 17, 23, 25, 27, 29); // переменные int dir = 1; //используется для смены направления ШД int podazh = EEPROM.read(0); // извлечь данные из памяти для шагов подачи Шд boolean alarm = true; // переменная для включения аварии int stroka = 0;// переменная номера строчек меню long previousMillis = 0; // время последнего задействования long previousMillis2 = 0; // время последнего задействования long previousMillis3 = 0; // время последнего задействования long previousMillis4 = 0; // время последнего задействования long intervalKnopok = 700; // интервал для обработки кнопок long signalSHD = 2000; // интервал после изменения переменной от энкодера ШД и до его вращения boolean state_nasos = 0; // состояние насоса типа флага что насос либо работает либо нет long nasos_Onn = 180000; // сколько минут насос работает при минусе на улице 3мин long nasos_Off = 900000; // сколько минут насос выключен при минусе на улице 15мин unsigned long new_millis_nasos = millis(); // Переменная для хранения времени //объявление входов-выходов Encoder knobEnkoder(31, 33); //кнопки энкодера int sign = 37; //бузер аварии, динамик (100 гц нормально пищит) int nasos = 10; // выход на твердотелое реле управление насосом int enter = 41; // кнопка стопа на плате int enterEnk = 35; //!!!!!!!!!!!!!!!!! кнопка на энкодере void setup() { izm_temp(); RemoteXY_Init (); Stepper1.setMaxSpeed(100000); //устанавливаем максимальную скорость вращения ротора двигателя масла(шагов/секунду) Stepper1.setAcceleration(12000); //устанавливаем ускорение (шагов/секунду^2) //Настройка пинов pinMode(enterEnk, INPUT_PULLUP); pinMode(enter, INPUT_PULLUP); pinMode(sign, OUTPUT); pinMode(nasos, OUTPUT); pinMode(dirPin, OUTPUT); pinMode(stepPin, OUTPUT); pinMode(38, OUTPUT); // 38 как выход енейбл для ШД pinMode(10, OUTPUT); // А10 как выход для включения насоса //Настройка дисплея //Установка количества столбцов и строк дисплея lcd.begin(20, 4); // Вывод приветствия при включении питания если нужно lcd.setCursor(6, 1); lcd.print("BUYANKA"); delay (2000);//Задержка приветствия lcd.clear(); } long positionLeft = -999; // позиция для энкодера в лево void loop() { RemoteXY_Handler (); // для блютуз izm_temp(); { //ОТОБРАЖЕНИЯ ТЕМПЕРАТУРЫ ВОДЫ НА ВЫХОДЕ КОТЛА lcd.setCursor(0, 0); lcd.print("KOTEL="); lcd.print(temp_1); lcd.print(" "); //отображение температуры улицы lcd.setCursor(0, 1); lcd.print("ULICA="); lcd.print(temp_2); lcd.print(" "); //подача масла lcd.setCursor(0, 2); lcd.print("PODAZHA="); lcd.print(podazh); lcd.print(" "); // сигнализация if (alarm == true ) { lcd.setCursor(0, 3); lcd.print("SIGNAL=DA "); } else if (alarm == false) { lcd.setCursor(0, 3); lcd.print("SIGNAL=NET"); } } ////////////ОБРАБОТКА БЛЮТУЗ ДЖОЙСТИКА /*if (RemoteXY.podachaM_y > 5 <10) { podazh ++ ; } */ if (RemoteXY.podachaM_y >= 10 <25) { podazh + 5 ; } if (RemoteXY.podachaM_y >= 25 <50) { podazh + 10; } if (RemoteXY.podachaM_y >= 50 <75) { podazh + 50; } if (RemoteXY.podachaM_y >= 75 <=100) { podazh + 100; } if (RemoteXY.podachaM_y > -5 < -10) { podazh --; } if (RemoteXY.podachaM_y >= -10 < -25) { podazh - 5; } if (RemoteXY.podachaM_y >= -25 < -50) { podazh - 10; } if (RemoteXY.podachaM_y >= -50 < -75) { podazh - 50; } if (RemoteXY.podachaM_y >= -75 < -100) { podazh - 100; } long newLeft; /// новая локальная переменная для энкодера /////////////////////тоже самое но для подачи шагов для вентиля newLeft = knobEnkoder.read()/4; // она равна /4 сигналам так как это приемливый делитель для моего энкодера. if (newLeft > positionLeft ){ //здесь определяется направление вращения и если строка равна 2 lcd.setCursor(8, 2); lcd.print(" "); podazh ++ ; // и увеличиваю переменную для показаний на экране positionLeft = newLeft; // запоминаю текущую позицию энкодера } if (newLeft < positionLeft){ // здесь все аналогично только уменьшаю значение на 1 lcd.setCursor(8, 2); lcd.print(" "); podazh -- ; podazh = max(podazh, 1); // ограничиваю нижний предел, не меньше 1. positionLeft = newLeft; } if (RemoteXY.edit_step > 0); { int podazh = RemoteXY.edit_step; } /////////////ПЕРЕМЕЩЕНИЕ ВЕНТИЛЯ unsigned long currentMillis = millis(); // стартовая строка для осчета времени. задержка специальная чтоб шд крутился не сразу иначе экран мигает и полная белеберда if(currentMillis - previousMillis2 > signalSHD){ // прошло время больше заданого в signalSHD previousMillis2 = currentMillis; // команда для счетчика digitalWrite(38, LOW); // отпускаю енейбле чтоб двигатель крутился ENABLE_PIN38 Stepper1.runToNewPosition(podazh * 25); // мотор движется столько сколько сейчас в переменной и * на 25 EEPROM.write(0, podazh); digitalWrite(38, HIGH); // подаю высокий чтоб двиг освободился ENABLE_PIN38 } itoa (podazh, RemoteXY.Maslo, 10); // вывожу показания шагов на экран андроида if (RemoteXY.edit_step > 0); { int podazh = RemoteXY.edit_step; } /////////////// команда для сигнализации if (digitalRead(enter) == LOW){ unsigned long currentMillis = millis(); if(currentMillis - previousMillis3 > intervalKnopok){ previousMillis3 = currentMillis; alarm = !alarm; } } ////////// управление насосом if (temp_1 > 40) //если температура котла больше 40гр насос включается { analogWrite(10, 180); // вкл насос } if (temp_1 < 35) //если температура котла меньше 35гр насос выключается { analogWrite(10, 0); // выкл насос } if (temp_2 < -2 && temp_1 < 1) //если температура на улице меньше -2 вкл импульсы на насос { if(millis() > new_millis_nasos) { state_nasos = !state_nasos;// инвертирую 1 на 0 и наоборот digitalWrite(10, state_nasos);//устанавливаем вывод в соответствующее состояние if(state_nasos) // если state_nasos равен 1 (больше нуля, истина,..), то { new_millis_nasos = millis() + nasos_Onn; //присваиваем переменной сумму текущего состояния счетчика и заданного времени } else { new_millis_nasos = millis() + nasos_Off; //присваиваем переменной сумму текущего состояния счетчика и заданного времени } } } //////////включаю сигнализацию если в котле больше 90 или меньше -3 if (temp_1 > 90 || temp_1 < -3) { unsigned long currentMillis = millis(); //запускаю отсчет if(currentMillis - previousMillis4 > 1000)// отсчитываю время 1сек { previousMillis4 = currentMillis; //сохраняю сразу время последнего включения tone (sign, 100); //пищит 100 герц } } else if (temp_1 < 87 || temp_1 > 0)// а если в котле стало ниже 87 или выше 0 то сигналка офф { noTone (sign); } } void izm_temp(){ if(!flag){ start_izm(); time=millis(); flag=1; } if(flag && (millis()-time)>750){ calc_izm(); flag=0; } } void start_izm(){ //запускаем измерение всех датчиков ds_1.reset(); ds_1.write(0xCC); ds_1.write(0x44); ds_2.reset(); ds_2.write(0xCC); ds_2.write(0x44); } void calc_izm(){ // Считываем и пересчитываем 1 датчик ds_1.reset(); ds_1.write(0xCC); ds_1.write(0xBE); // Read Scratchpad for (byte i = 0; i < 9; i++) { // we need 9 bytes data[i] = ds_1.read (); } raw = (data[1] << 8) | data[0];//=======Пересчитываем в температуру temp_1 = (float)raw / 16.0; dtostrf(temp_1, 0, 1, RemoteXY.KOTEL); // Считываем и пересчитываем 2 датчик ds_2.reset(); ds_2.write(0xCC); ds_2.write(0xBE); // Read Scratchpad for (byte i = 0; i < 9; i++) { // we need 9 bytes data[i] = ds_2.read (); } raw = (data[1] << 8) | data[0];//=======Пересчитываем в температуру temp_2 = (float)raw / 16.0; dtostrf(temp_2, 0, 1, RemoteXY.ULICA); }
решил пока тем что в сетапе прогоняю в "холостую" с отключеним енейбле пином.
ну и с remotexy поступил иначе, изначально неправильно описал арифметику, потом пригляделся в компилятор, тот подсказал что нет смысла делать двойное сравненине типа: x<y<z а так же вместо
здесь я вобще не понл почему так.. но изменил и компилятор промолчал.