/**************************************************************************
Номер контакта Наименование контакта К какому контакту Arduino необходимо подключить на NANO
Управление шаговым двигателем
ENA-D7, DIR-D3, PUL STEP-D4
Кнопки
KN1 D2
KN2 D5
KN3 D6
KN4 D8
SD по SPI
CS D10
SLC D13
MOSI D11
MISO D12
LED A3
ЭКран по I2C
SDA A4
SCL A5
**************************************************************************/
//#define GS_NO_ACCEL
#define KN1 2 //на эту кнопку сделать прерывание
#define KN2 5
#define KN3 6
#define KN4 8
#define pin_ENA 7 //на эту кнопку сделать прерывание
#define pin_DIR 3
#define pin_PUL 4
#define LED_PIN 17 // светодиод на А3
/////////////////////////////// БИБЛИОТЕКИ ////////////////////////////////////////////////////
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
#include "GyverButton.h"
//#include <iarduino_I2C_pH.h> // Подключаем библиотеку для работы с pH-метром I2C-flash.
///////////////////////////////////////////////////////////////////////////////////////////////
//iarduino_I2C_pH sensor(0x09); // Объявляем объект sensor для работы с функциями и методами библиотеки iarduino_I2C_pH, указывая адрес модуля на шине I2C.
//GStepper2<STEPPER2WIRE> stepper(3200, 4,3,7);
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display
GButton butt1(KN1);
GButton butt2(KN2);
GButton butt3(KN3);
GButton butt4(KN4);
int value = 0;
///////////////////////////////// класс на таймер //////////////////////////////////////
class Timer {
public:
Timer(uint32_t nprd = 0) {
setPeriod(nprd);
}
void setPeriod(uint32_t nprd) {
prd = nprd;
}
bool ready() {
return (prd && millis() - tmr >= prd) ? (tmr = millis(), 1) : 0;
}
private:
uint32_t tmr = 0, prd = 0;
};
/////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////// ТАЙМЕРЫ //////////////////////////////////////
Timer tmr1 (50); // таймер на имерение рН
Timer tmr2 (333); // таймер на обновление цифер на экране
Timer tmr3; // для симулятора рН
Timer tmr4; // обновление значений на экране
Timer tmr5 (5000);
Timer tmr6 ; //LED on/of
Timer tmr7 (1000) ; // таймер на отсчет времени для калибровки рН
uint32_t t_0 = 0;
uint32_t t_ms; // время прошло, мс
uint16_t t_s; // время прошло, с
uint16_t t_m; // время прошло, мин
uint16_t t_h; // время прошло, ч
// uint16_t counter = 0; // замена i
// uint32_t tmr = 0; // переменная таймера
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////// Структуры ////////////////////////////////////
struct Data {
float min_pH = 0; // мин рН
float max_pH = 0; //макс рН
float w_mlm = 0; // скорость прoкачки , мл/мин
float v0_ml = 0; // объем, который нужно слить, мл
float vn_ml = 0; // объем заданный при калибровке, мл
float vk_ml = 0; // объем реальный после калибровки, мл
float k_nV = 0; // количество шагов матора на 1 мл k = n/V
uint16_t w_auto = 0; // скорость прoкачки в режиме автомата , шагов
uint16_t v_auto = 0; // объем прoкачки в режиме автомата , шагов
float pH1 = 4.00; // точки калибровки рН
float pH2 = 9.18; // точки калибровки рН
};
///////////////////////////////// ПЕРЕМЕННЫЕ ДЛЯ МЕНЮ ///////////////////////////////
uint8_t lvl=1; //уровень
uint16_t nomer=1; //номер пункта меню
bool red_Flag = false; // флаг для редактирования
float v_prok = 0.00; // прокаченный объем
//////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////// ПЕРЕМЕННЫЕ //////////////////////////////////////
volatile bool intFlag = false; // флаг на прерывание
bool titrFlag = true ; // флаг, определяет титровать или нет
bool tFlag = false; // флаг, определяет началось ли титрование
float pH_min; // нижняя граница рН
float pH_max; //верхняя граница рН
float pH_val; // значение рН
float v_kap = 0.01; // объем капли, мл
bool light = true;
Data data; //структура для записи констант в еепром
//////////////////////////////////////////////////////////////////////////////////////
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void setup() {
EEPROM.get(0, data); // прочитать из адреса 0
pinMode( pin_ENA, OUTPUT ); // Конфигурируем вывод Arduino как выход.
pinMode( pin_DIR, OUTPUT ); // Конфигурируем вывод Arduino как выход.
pinMode( pin_PUL, OUTPUT ); // Конфигурируем вывод Arduino как выход.
pinMode(LED_PIN, OUTPUT);
//**************************
data.min_pH = 7.82; //потом убрать в коде
data.max_pH = 8.12;
data.w_mlm = 20.00;
data.v0_ml = 1.00;
data.vn_ml = 10.00;
data.vk_ml = 10.00;
data.k_nV = 15576;
data.w_auto = 1000;
data.v_auto = 156;
data.pH1 = 4.00;
data.pH2 = 9.18;
//*/////////////////////////////
lcd.init(); lcd.backlight(); // initialize the lcd
Serial.begin(9600);
//sensor.begin(); // Инициируем работу с pH-метром I2C-flash.
butt2.setDebounce(80); // настройка антидребезга (по умолчанию 80 мс)
butt3.setDebounce(80); // настройка антидребезга (по умолчанию 80 мс)
// butt1.setTimeout(500); // настройка таймаута на удержание (по умолчанию 500 мс)
butt2.setClickTimeout(100); // настройка таймаута между кликами (по умолчанию 300 мс)
butt3.setClickTimeout(100); // настройка таймаута между кликами (по умолчанию 300 мс)
attachInterrupt(0, bT, FALLING);
start(); // Приветствие
menu(1); // Экран начального меню
red_Flag = false;
pH_val = 8.25; //убрать
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//____________________________________________________________________________________
void loop() {
butt1.tick(); // обязательная функция отработки. Должна постоянно опрашиваться
butt2.tick(); // обязательная функция отработки. Должна постоянно опрашиваться
butt3.tick(); // обязательная функция отработки. Должна постоянно опрашиваться
butt4.tick(); // обязательная функция отработки. Должна постоянно опрашиваться
if (butt1.isClick()) {Serial.println("выход"); kursorB(); }
if (butt2.isClick()) {Serial.println("вверх"); kursorV() ; znach_minus (); }
if (butt3.isClick()) {Serial.println("низ"); kursorN(); znach_plus ();}
if (butt4.isClick()) {Serial.println("вход"); kursorE(); }
//if (butt2.isPress()) Serial.println("Press"); // нажатие на кнопку (+ дебаунс)
//if (butt3.isPress()) Serial.println("Press"); // нажатие на кнопку (+ дебаунс)
// if (butt2.isHolded()) {Serial.println("Holded"); motor2(5,1000,1);}; // проверка на удержание
//if (butt3.isHolded()) Serial.println("Holded"); // проверка на удержание
if (butt2.isHold()) { znach_minus (); } // если кнопка была удержана (это для инкремента)
if (butt3.isHold()) { znach_plus (); } // если кнопка была удержана (это для инкремента)
cikl ();
}
//_____________________________________________________________________________________
void bT() {
intFlag = true; // подняли флаг прерывания
}
////////////////////////////////////// Вывод на экран приветствия ////////////////////////////
void start () {
lcd.setCursor(4,0);
lcd.print("PRIVET!");
delay(300);
lcd.setCursor(2,0);
lcd.print("TITRATOR OH-");
lcd.setCursor(5,1);
lcd.print("v.1.0");
delay(300);
lcd.clear();
}
//////////////////////////// Функция Отрисовки меню /////////////////////////////////
void s_menu (uint8_t x1, String name1, uint8_t x2, String name2, bool st){
lcd.clear(); lcd.setCursor(x1,0); lcd.print(name1);
lcd.setCursor(x2,1); lcd.print(name2);
if (st == true) { lcd.setCursor(15,0); lcd.print("<"); }
}
void f_menu (bool cl, uint8_t x1, float name1, uint8_t x2, float name2, bool st){
if (cl == true) lcd.clear();
lcd.setCursor(x1,0); lcd.print(name1);
lcd.setCursor(x2,1); lcd.print(name2);
if (st == true) { lcd.setCursor(15,0); lcd.print("<"); }}
void u_menu (bool cl, uint8_t x1, uint16_t name1, uint8_t x2, uint16_t name2, bool st){
if (cl == true) lcd.clear();
lcd.setCursor(x1,0); lcd.print(name1);
lcd.setCursor(x2,1); lcd.print(name2);
if (st == true) { lcd.setCursor(15,0); lcd.print("<"); }
}
void sf_menu (bool cl, uint8_t x1, String name1, uint8_t x2, float name2, bool st){
if (cl == true) lcd.clear();
lcd.setCursor(x1,0); lcd.print(name1);
lcd.setCursor(x2,1); lcd.print(name2);
if (st == true) { lcd.setCursor(15,0); lcd.print("<"); }
}
void su_menu (bool cl, uint8_t x1, String name1, uint8_t x2, uint16_t name2, bool st){
if (cl == true) lcd.clear();
lcd.setCursor(x1,0); lcd.print(name1);
lcd.setCursor(x2,1); lcd.print(name2);
if (st == true) { lcd.setCursor(15,0); lcd.print("<"); }
}
void str_n_menu () {lcd.setCursor(15,0); lcd.print(" "); lcd.setCursor(15,1); lcd.print("<");}
void str_v_menu () {lcd.setCursor(15,1); lcd.print(" "); lcd.setCursor(15,0); lcd.print("<");}
/////////////////////////////////////////////////////////////////////////////////////
////////////////////////////Фунции вывода информации в порт ////////////////////////
void no_lvl () {Serial.print(nomer); Serial.print(" lvl ");Serial.println(lvl);}
/////////////////////////////////////// Menu ///////////////////////////////////////////////////
void menu (uint16_t NM) {
switch (NM){
case 1: s_menu (0, "IZMERENIE pH", 0, "TITROVANIE",true) ; break;
case 11: sf_menu (true, 6, "pH", 5, pH_val, false) ; break;
case 2: s_menu (0, "PROKACHKA", 0, "KALIBROVKA",true) ; break;
case 21: s_menu (0, "RUCHNOE", 0, "AVTOMAT",true) ; break;
case 211: s_menu (0, "pH", 0, "V", false) ; break;
case 3: s_menu (0, "NASTROYKI", 0, " ",true); break;
case 31: s_menu (0, "VPERED", 0, "NAZAD",true); break;
case 33: s_menu (0, "RUCHNOE", 0, "NEPRERYVNO",true); break;
case 331: sf_menu (true, 5, "V, ml", 5, v_prok, false); break;
case 41: s_menu (0, "K. NASOS", 0, "K. pH-METR",true); break;
case 51: s_menu (0, "pH_min", 0, "pH_max",true);
f_menu (false, 9, data.min_pH, 9, data.max_pH, false); break;
case 53: s_menu (0, "w ml/m", 0, "V0 ml",true);
f_menu (false, 9, data.w_mlm, 9, data.v0_ml, false); break;
case 55: s_menu (0, "w n auto", 0, "V n auto",true);
u_menu (false, 9, data.w_auto, 9, data.v_auto, false) ; break;
case 57: sf_menu (true, 4, "K , n/ml", 4, data.k_nV,true); break;
case 411: sf_menu (true, 0, "Ustanovi V1, ml", 5, data.vn_ml, false) ; break;
case 412: sf_menu (true, 0, "Ustanovi V2, ml", 5, data.vk_ml, false) ; break;
case 421: sf_menu (true, 1, "Ustanovi pH ml", 6, data.pH1, false) ; break;
case 424: sf_menu (true, 1, "Ustanovi pH ml", 6, data.pH2, false) ; break;
}}
///////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////// Курсор ///////////////////////////////////////////////////
void kursorV() {
switch (lvl){
case 1: if (nomer>1) {nomer--; no_lvl (); }
if (nomer==2) menu(1);
if (nomer==4) menu(2);
if (nomer==6) menu(3);
if (nomer%2 == 0) {str_n_menu ();}
if (nomer%2 == 1) {str_v_menu ();}
break;
case 2: if (red_Flag==false ) {
if (nomer>21 && nomer < 23) {nomer--; no_lvl ();}
if (nomer>31 && nomer < 35) {nomer--; no_lvl ();}
if (nomer>41 && nomer < 43) {nomer--; no_lvl ();}
if (nomer>51 && nomer < 58) { nomer--; no_lvl (); }
if (nomer==52) menu(51);
if (nomer==54) menu(53);
if (nomer==56) menu(55);
if (nomer==32) menu(31);
if (nomer%2 == 0 and nomer != 421) {str_n_menu ();}
if (nomer%2 == 1 and nomer != 421) {str_v_menu ();}
}
break;
}
}
void kursorN() {
switch (lvl){
case 1: if (nomer<5) {nomer++; no_lvl ();}
if (nomer==3) menu(2);
if (nomer==5) menu(3);
if (nomer%2 == 0) {str_n_menu ();}
if (nomer%2 == 1) {str_v_menu ();}
break;
case 2: if (red_Flag==false ) {
if (nomer<22 && nomer >20 && red_Flag==false) {nomer++; no_lvl ();}
if (nomer<34 && nomer >30 && red_Flag==false) {nomer++; no_lvl ();}
if (nomer<42 && nomer >40 && red_Flag==false) {nomer++; no_lvl ();}
if (nomer<57 && nomer >50 && red_Flag==false) {nomer++; no_lvl ();}
if (nomer==53 && red_Flag==false) menu(53);
if (nomer==55 && red_Flag==false) menu(55);
if (nomer==57 && red_Flag==false) menu(57);
if (nomer==33 && red_Flag==false) menu(33);
if (nomer%2 == 0 and nomer != 421) {str_n_menu ();}
if (nomer%2 == 1 and nomer != 421) {str_v_menu ();}
}
break;
}
}
void kursorE() {
switch (lvl){
case 1: if (nomer==1) {nomer=11; lvl++; no_lvl (); menu (11);}
if (nomer==2) {nomer=21; lvl++; no_lvl (); menu (21);}
if (nomer==3) {nomer=31; lvl++; no_lvl (); menu (31);}
if (nomer==4) {nomer=41; lvl++; no_lvl (); menu (41);}
if (nomer==5) {nomer=51; lvl++; no_lvl (); menu (51);}
if (nomer==6) {;}
break;
case 2: if (nomer>50 && nomer<57) {switch (red_Flag) {
case false: red_Flag = !red_Flag; Serial.println(red_Flag);
if (nomer%2 == 0) {lcd.setCursor(15,0); lcd.print(" "); lcd.setCursor(15,1); lcd.print("*");}
if (nomer%2 == 1) {lcd.setCursor(15,1); lcd.print(" "); lcd.setCursor(15,0); lcd.print("*");}
break;
case true: red_Flag = !red_Flag; Serial.println(red_Flag); EEPROM.put(0, data);
if (nomer%2 == 0) {lcd.setCursor(15,0); lcd.print(" "); lcd.setCursor(15,1); lcd.print("<");}
if (nomer%2 == 1) {lcd.setCursor(15,1); lcd.print(" "); lcd.setCursor(15,0); lcd.print("<");}
break;}}
if (nomer==21) {nomer=211; lvl++; no_lvl (); menu (211); red_Flag = true;}
if (nomer==22) {nomer=221; lvl++; no_lvl (); menu (211); red_Flag = true;}
if (nomer==31) {Prokachka(1); menu (31);}
if (nomer==32) {Prokachka(0); menu (31); nomer=31; }
if (nomer==33) {nomer=331; lvl++; no_lvl (); menu (331); red_Flag=true;}
if (nomer==34) {nomer=341; lvl++; no_lvl (); menu (331); red_Flag=false;}
if (nomer==41) {nomer=411; lvl++; no_lvl (); menu (411); red_Flag = true;}
if (nomer==42) {nomer=421; lvl++; no_lvl (); menu (421); red_Flag = false;}
break;
case 3: if (nomer==411) {calibr_nasos () ; nomer=412; no_lvl (); menu (412); red_Flag = true;}
else {
if (nomer==412) {nomer=41; lvl--; no_lvl (); menu (41); red_Flag = false;
data.k_nV = data.k_nV * data.vn_ml/data.vk_ml; EEPROM.put(0, data);} }
if (nomer==341){motor_nepr2 (0,data.k_nV * data.w_mlm / 60,1,1,5); }
if (nomer==211){ } //запись рН, V и секунд в файл
if (nomer==221){nomer =222; no_lvl (); titr_auto (data.w_auto);} //
if (nomer==421) {nomer=422; lvl++; no_lvl (); calibr_pH1 ();}
break;
case 4: if (nomer==422) {nomer=423; lvl++; no_lvl (); menu (424); }
break;
case 5: if (nomer==423) {nomer=424; no_lvl (); calibr_pH2 (); }
break;
}
}
void kursorB() {
switch (lvl){
case 2: if (nomer==11) {nomer=1; lvl--; no_lvl (); menu (1); digitalWrite(LED_PIN, false); }
if (nomer==21 or nomer ==22) {nomer=1; lvl--; no_lvl (); menu (1);}
if (nomer==41 or nomer ==42) {nomer=3; lvl--; no_lvl (); menu (2);}
if (nomer>30 and nomer < 35) {nomer=3; lvl--; no_lvl (); menu (2); v_prok = 0;}
if (nomer>=51 && nomer <58 and red_Flag==false) {nomer=5; lvl--; no_lvl (); menu (3);}
break;
case 3: if (nomer==411) {nomer=41; lvl--; no_lvl (); menu (41); red_Flag = false; EEPROM.put(0, data);}
if (nomer==412) {nomer=41; lvl--; no_lvl (); menu (41); red_Flag = false;
data.k_nV = data.k_nV * data.vn_ml/data.vk_ml; EEPROM.put(0, data); }
if (nomer==331) {nomer=33; lvl--; no_lvl (); menu (33); red_Flag=false; v_prok = 0; digitalWrite( pin_ENA, 1 );}
if (nomer==341) {nomer=33; lvl--; no_lvl (); menu (33); red_Flag=false; v_prok = 0; digitalWrite( pin_ENA, 1 );}
if (nomer==211 or nomer==221 or nomer == 222) {nomer=21; lvl--; no_lvl (); menu (21);
tFlag = false; red_Flag=false; titrFlag = true; v_prok = 0; digitalWrite( pin_ENA, 1 ); digitalWrite(LED_PIN, false); }
if (nomer==421) {nomer=41; lvl--; no_lvl (); menu (41);}
break;
case 4: if (nomer==422) {nomer=41; lvl=2; no_lvl (); menu (41);}
break;
case 5: if (nomer==424 or nomer==424) {nomer=41; lvl=2; no_lvl (); menu (41); }
break;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////// Удержание, изменение значений ///////////////////////////////
void val_delta (float &val, float delta, uint8_t x, uint8_t y ){
val = val + delta; lcd.setCursor(x,y); lcd.print(val); lcd.print(" ");;
}
void val_delta_uint16 (uint16_t &val, uint16_t delta, uint8_t x, uint8_t y ){
val = val + delta; lcd.setCursor(x,y); lcd.print(val); lcd.print(" ");;
}
void val_change (float &val, uint8_t x, uint8_t y ){
lcd.setCursor(x,y); lcd.print(val); lcd.print(" ");
}
void znach_minus () {
if (red_Flag==true){
switch (nomer){
case 51: val_delta (data.min_pH, -0.01, 9, 0); lcd.setCursor(15,0); lcd.print("*"); break;
case 52: val_delta (data.max_pH, -0.01, 9, 1);lcd.setCursor(15,1); lcd.print("*"); break;
case 53: val_delta (data.w_mlm, -0.1, 9, 0); lcd.setCursor(15,0); lcd.print("*"); break;
case 54: val_delta (data.v0_ml, -0.01, 9, 1); lcd.setCursor(15,1); lcd.print("*"); break;
case 55: val_delta_uint16 (data.w_auto, -100, 9, 0); lcd.setCursor(15,0); lcd.print("*");break;
case 56: val_delta_uint16 (data.v_auto, -1, 9, 1);lcd.setCursor(15,1); lcd.print("*"); break;
case 411: val_delta (data.vn_ml, -0.01, 5, 1); break;
case 412: val_delta (data.vk_ml, -0.01, 5, 1); break;
case 331: motor_nepr (156,5000,0,0); if (tmr2.ready()){val_change (v_prok,5,1);}; break;
case 211: tFlag = true; motor_nepr (156,5000,0,0); if (tmr2.ready()){val_change (v_prok,3,1);}; break;
}}
}
void znach_plus () {
if (red_Flag==true){
switch (nomer){
case 51: val_delta (data.min_pH, 0.01, 9, 0); lcd.setCursor(15,0); lcd.print("*"); break;
case 52: val_delta (data.max_pH, 0.01, 9, 1); lcd.setCursor(15,1); lcd.print("*"); break;
case 53: val_delta (data.w_mlm, 0.1, 9, 0); lcd.setCursor(15,0); lcd.print("*");break;
case 54: val_delta (data.v0_ml, 0.01, 9, 1); lcd.setCursor(15,1); lcd.print("*"); break;
case 55: val_delta_uint16 (data.w_auto, 100, 9, 0);lcd.setCursor(15,0); lcd.print("*"); break;
case 56: val_delta_uint16 (data.v_auto, 1, 9, 1); lcd.setCursor(15,1); lcd.print("*");break;
case 411: val_delta (data.vn_ml, 0.01, 5, 1); break;
case 412: val_delta (data.vk_ml, 0.01, 5, 1); break;
case 331: motor_nepr (156,5000,1,0); if (tmr2.ready()){ val_change (v_prok,5,1);}; break;
case 211: tFlag = true; motor_nepr (156,5000,1,0); if (tmr2.ready()){ val_change (v_prok,3,1);}; break;
}}
}
/////////////////////////////////КАЛИБРОВКА НАСОСА //////////////////////////////////////////
void calibr_nasos () {
lcd.clear(); lcd.setCursor(1,0); lcd.print("KRUCHU VERCHU");
motor_nepr2 (data.k_nV * data.vn_ml, data.k_nV * 30 / 60, 1,1,5); v_prok =0;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////Прокачка //////////////////////////////////////////////////
void Prokachka (int32_t napr) {
lcd.clear(); lcd.setCursor(1,0); lcd.print("KRUCHU VERCHU");
motor_nepr2 (data.k_nV * data.v0_ml, data.k_nV * data.w_mlm / 60, napr,1,5); v_prok =0;
}
////////////////////////////////// ФУНКЦИЯ КРУЧЕНИЯ МОТРОРА ////////////////////////////////
void motor_nepr (uint32_t m_tick, float m_speed, int32_t m_dir, int8_t ena) { //указать шаги, скорость и направление
intFlag = false;
if (m_tick ==0) m_tick = -1;
int32_t count = 0;
int8_t napr;
uint8_t x;
if (m_dir ==0) napr = -1; if (m_dir ==1) napr = 1;
float f = m_speed; // Определяем частоту следования микрошагов от 1 до 200'000 Гц.
float t = 1000000/f/2; // Определяем длительность импульсов t3 и пауз t4 в мкс.
// Готовимся к движению вала: //
digitalWrite( pin_ENA, 0 ); // Разрешаем работу двигателя.
delayMicroseconds(5); // Выполняем задержку t1 (см. график STEP/DIR).
digitalWrite( pin_DIR, m_dir ); // Выбираем направление вращения.
delayMicroseconds(5); // Выполняем задержку t2 (см. график STEP/DIR). //
digitalWrite(LED_PIN, HIGH);
for(;;){ // Выполняем
digitalWrite( pin_PUL, 1 ); // Устанавливаем на выводе PUL состояние логической «1».
delayMicroseconds(t); // Выполняем задержку t3 (см. график STEP/DIR).
digitalWrite( pin_PUL, 0 ); // Устанавливаем на выводе PUL состояние логического «0».
delayMicroseconds(t); // Выполняем задержку t4 (см. график STEP/DIR).
count++;
if (intFlag == true) { intFlag = false; Serial.println("Interrupt!"); break;}
if (count== m_tick) {Serial.println(f); break;}
}
digitalWrite( pin_ENA, ena ); // Запрещаем работу двигателя, отключаем токи в обмотках.
digitalWrite(LED_PIN, LOW);
v_prok = v_prok + count/data.k_nV*napr;
if (nomer == 222) { if (tmr2.ready()){ val_change (v_prok, 3,1);}}
Serial.println(f);
Serial.println(t);
}
void motor_nepr2 (uint32_t m_tick, float m_speed, int32_t m_dir, int8_t ena, uint8_t x) { //указать шаги, скорость и направление
intFlag = false;
if (m_tick ==0) m_tick = -1;
int32_t count = 0;
int8_t napr;
if (m_dir ==0) napr = -1; if (m_dir ==1) napr = 1;
float f = m_speed; // Определяем частоту следования микрошагов от 1 до 200'000 Гц.
float t = 1000000/f/2; // Определяем длительность импульсов t3 и пауз t4 в мкс.
// Готовимся к движению вала: //
digitalWrite( pin_ENA, 0 ); // Разрешаем работу двигателя.
delayMicroseconds(5); // Выполняем задержку t1 (см. график STEP/DIR).
digitalWrite( pin_DIR, m_dir ); // Выбираем направление вращения.
delayMicroseconds(5); // Выполняем задержку t2 (см. график STEP/DIR).
digitalWrite(LED_PIN, HIGH);
for(;;){ // Выполняем
digitalWrite( pin_PUL, 1 ); // Устанавливаем на выводе PUL состояние логической «1».
delayMicroseconds(t); // Выполняем задержку t3 (см. график STEP/DIR).
digitalWrite( pin_PUL, 0 ); // Устанавливаем на выводе PUL состояние логического «0».
delayMicroseconds(t); // Выполняем задержку t4 (см. график STEP/DIR).
count++;
v_prok = count/data.k_nV*napr;
if (tmr2.ready()){ val_change (v_prok, x,1);}
if (intFlag == true) { intFlag = false; Serial.println("Interrupt!"); break;}
if (count== m_tick) {Serial.println(f); break;}
}
digitalWrite( pin_ENA, ena ); // Запрещаем работу двигателя, отключаем токи в обмотках.
digitalWrite(LED_PIN, LOW);
Serial.println(f);
Serial.println(t);
}
/////////////////////////////////// Симулятор рН /////////////////////////////////////////
void pH_simulator (uint16_t vremya) {
tmr3.setPeriod(vremya);
if (tmr3.ready()){
if (pH_val > data.min_pH and titrFlag == true) {pH_val = pH_val -0.01;};
if (pH_val <= data.min_pH and titrFlag == true) {titrFlag = false; pH_val = pH_val + 0.01;};
if (pH_val > data.min_pH and titrFlag == false) {pH_val = pH_val + 0.01;};
if (pH_val >= data.max_pH and titrFlag == false) {titrFlag = true; pH_val = pH_val - 0.01;};
Serial.println(pH_val);
if (nomer == 11) {val_change (pH_val,5,1);}
if (nomer == 211 or nomer == 221 or nomer ==222) {val_change (pH_val,3,0);
if (tFlag==false) {t_0 = millis();}
if (tFlag==true) {sekundomer (); lcd.setCursor(9,1); lcd.print(t_ms/1000);;
lcd.setCursor(9,0); lcd.print(t_h);lcd.print(":"); lcd.print(t_m); lcd.print(":");lcd.print(t_s);lcd.print(" ");}
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////// pH-метр //////////////////////////////////////////////////
/*
void izm_pH (uint16_t vremya) {
tmr3.setPeriod(vremya);
if (tmr3.ready()){
pH_val = sensor.getPH() ,2;
Serial.print("Кислотность = " ); //
Serial.print(pH_val, 2); // Выводим водородный показатель жидкости с 2 знаком после запятой.
Serial.print(" pH.\r\n" ); //
if (nomer == 11) {lcd.setCursor(5,1); lcd.print(pH_val);}}
led_blink (1500);
}
}
*/
//_____________________________________ Калибровка рН ________________________________________
void calibr_pH1 () {
// sensor.setCalibration(1, data.pH1); // включить
tim (10); // таймер на n с
s_menu (2, "Spolostnite", 4, "datchik",false) ;
}
void calibr_pH2 () {
// sensor.setCalibration(2, data.pH2); // включить
tim (10); // таймер на n с
s_menu (2, "Spolostnite", 4, "datchik",false) ; }
/////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////// Автоматический титратор ////////////////////////////////////
void titr_auto (float speed){
titrFlag= true; tFlag=true; t_0 = millis();
for (;;) {
pH_simulator (50); // izm_pH заменить
if (pH_val > data.min_pH and titrFlag == true) {motor_nepr(156,speed,1,0);};
if (pH_val <= data.min_pH and titrFlag == true) {titrFlag = false; };
if (pH_val >= data.max_pH and titrFlag == false) {titrFlag = true;};
if (intFlag == true) { intFlag = false; Serial.println("Interrupt!"); break;}
}
}
//////////////////////////////////Секундомер и таймер /////////////////////////////
void sekundomer (){
t_ms = millis() - t_0;
uint32_t s = (millis() - t_0)/1000ul;
t_s = (s % 3600ul) % 60ul; // секунды
t_m = (s % 3600ul) / 60ul; // минуты
t_h = (s / 3600ul); // часы
}
void tim (uint16_t t) {
lcd.clear();
intFlag = false;
for (;;) {
led_blink (150);
if (tmr7.ready()){t--;
su_menu (false, 2, "Kalibrovka...", 7, t, false); lcd.print(" ");
if (t ==0){ break;}
if (intFlag == true){intFlag = false; Serial.println("Interrupt!"); break; }
}}
digitalWrite(LED_PIN, LOW);
}
////////////////////////////// LED ////////////////////////////////////////
void led_blink (uint16_t tmr_on){
tmr6.setPeriod(tmr_on);
if (tmr6.ready()){
light = !light;
digitalWrite(LED_PIN, light); }
}
///////////////////////////////////////////////////////////////////////////
///////////////////////////// В ЦИКЛЕ ////////////////////////////////////
void cikl (){
if (nomer == 11 or nomer == 211) {pH_simulator (100); led_blink (500); } // заменить на izm_pH
}
////////////////////////////////////////////////////////////////////////////////