#include <Wire.h> //Библиотека для работы с шиной I2C
#include <LiquidCrystal_I2C.h> //Библиотека управления дисплеем
#include <EEPROM.h> //Бибилиотека работы с сохранением параметров память микроконтроллера
//#include <Stepper.h> // Стандартная библиотека управления двигателем Arduino
//#include "GyverStepper.h" // Библиотека функционала управления двигателем от Gyvera
#include <AccelStepper.h>
#define pin_StartV1 2
#define pin_StartV2 3
//Номера пинов подключения драйвер
#define pin_ENA 4 //Включение шагового двигателя
#define pin_DIR 5 //Направление вращения
#define pin_PUL 6 //Импульс для поворота на угол
#define STEPS 200 //Количество шагов у двигателя
//ПРИСВАЕВАЕМ АДРЕСА ПИНОВ ДЛЯ ЭНКОДЕРА
#define pinSW A0
#define pinCLK A1
#define pinDT A2
//АВАРИЙНАЯ ОСТАНОВКА
#define emergencyStop A3
//ПРИСВАЕВАЕМ ИМЯ ПИНУ ДЛЯ ПЕРЕКЛЮЧАТЕЛЯ НАПРАВЛЕНИЯ ВРАЩЕНИЯ
#define pinButtonRotate 4
//ПРИСВАЕВАЕМ ИМЯ ПИНУ РЕЖИМА РАБОТЫ
#define pin_ModeWork 8
//Номер пина кнопки переключения верхнего предела скорости
#define pinSetV 12
#define pinButton 11
//Запись скоростей, углов и прочее в память при первом запуске
#define INIT_ADR 1024
#define INIT_KEY 12
#define initx 0
#define initxx 60
#define initxxx 000
#define inity 0
#define inityy 40
#define inityyy 200
#define inita 0
#define initaa 60
#define initaaa 300
#define initb 0
#define initbb 60
#define initbbb 300
#define initRV1 1
#define initRV2 2
LiquidCrystal_I2C lcd(0x27,16,2); // Устанавливаем дисплей
/*********************************************************/
//GStepper<STEPPER2WIRE> stepperG(STEPS, pin_PUL, pin_DIR);
/*********************************************************/
/*********************************************************/
//Stepper stepper(STEPS, pin_PUL, 6);
/*********************************************************/
/*********************************************************/
AccelStepper stepper(1, pin_PUL, pin_DIR);
/*********************************************************/
//ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ
byte k_DrvrSteps; // 1:1 k=1; 1:2 k = 2 ; 1:4 k = 4; 1:8 k = 8; 1:16 k = 16;
byte k_Reductor;
uint16_t rotorPos;
uint16_t setSpeed;
float Speed;
float Accel;
uint16_t Angle;
boolean flagStartSystem = true;
boolean flagModeSetVal;
boolean flagModeWork;
boolean flagHideCursor = true;
byte item_M; //Индекс указателя выбора скоросте для изменения
byte item_RV1; //Индекс указателя направления вращения для скорости 2
byte item_RV2; //Индекс указателя направления вращения для скорости 1
byte index_V1; // Индекс выбора разряда для скорости 1
byte index_V2; // Индекс выбора разряда для скорости 2
byte index_A; // Индекс выбора разряда для угла поворота 1
byte index_B; // Индекс выбора разряда для угла поворота 2
int16_t x, xx, xxx; //Величины разрядов для скорости 1
int16_t y, yy, yyy; //Величины разрядов для скорости 2
int16_t a, aa, aaa; //величины разрядов для угла поворота 1
int16_t b, bb, bbb; //величины разрядов для угла поворота 2
uint32_t timer; // Таймер времени
int16_t angleA; //Угол поворота 1
int16_t angleB; //Угол поворота 2
const int16_t maxA = 720; //Максимальный угол поворота 1
const int16_t minA = 0;//Минимальный угол поворота 1
const int16_t maxB = 720; //Максимальный угол поворота 2
const int16_t minB = 0; //Минимальный угол поворота 2
int16_t valV1; // Переменная скорости 1
int16_t valV2; // Переменная скорости 2
const uint16_t maxV1 = 255; //Переменная верхнего предела скорости 1
const uint16_t minV1 = 0; //Переменная нижнего предела скорости 1
const uint16_t maxV2 = 255; //Переменная верхнего предела скорости 2
const uint16_t minV2 = 0; //Переменная нижнего предела скорости 2
boolean flagV1 = true; //Флаг мигания выбранного разряда скорости 1
boolean flagV2 = true; //Флаг мигания выбранного разряда скорости 2
boolean flagA = true; //Флаг мигания выбранного разряда угла поворота 1
boolean flagB = true; //Флаг мигания выбранного разряда угла поворота 2
uint16_t interval = 200; //Интервал мигания разряда
uint32_t timeNew = 0; //Время текущее для отсчета мигания разряда
uint32_t timeOld = 0; //Время предыдущее для отсчета мигания разряда
//ПЕРЕМЕННЫЕ ДЛЯ РАБОТЫ ЭНКОДЕРА ПО ВНЕШНЕМУ ПРЕРЫВАНИЮ
volatile byte seqA = 0;
volatile byte seqB = 0;
volatile int16_t cnt1 = 0;
volatile boolean button = false;
volatile boolean flagItem_M = false;
//Флаг аварийной остановки.
volatile boolean flagEmerStop = false;
byte setChar[] = {B11000, B10100, B10010, B10001, B10001, B10010, B10100, B11000};
byte setFullChar[] = {B11000, B11100, B11110, B11111, B11111, B11110, B11100, B11000};
byte setCharRotateClock[] = {B00100, B01110, B11111, B00100, B00100, B00100, B01110, B11111};
byte setCharRotateAntiClock[] = {B11111, B01110, B00100, B00100, B00100, B11111, B01110, B00100};
//КОД ВЫПОЛНЯЕТСЯ ТОЛЬКО ПРИ ЗАПУСКЕ
void setup() {
Serial.begin(9600);
//ЗАДАЕМ РЕЖИМ РАБОТЫ ПИНАМ ЭНКОДЕРА
pinMode(pinCLK, INPUT_PULLUP);
pinMode(pinDT, INPUT_PULLUP);
pinMode(pinSW, INPUT_PULLUP);
//Пины кнопок
pinMode(emergencyStop, INPUT_PULLUP);
pinMode(pinButtonRotate, INPUT_PULLUP);
pinMode(pinSetV, INPUT_PULLUP);
pinMode(pinButton, INPUT_PULLUP);
pinMode(pin_StartV1, INPUT_PULLUP);
pinMode(pin_StartV2, INPUT_PULLUP);
//Пины подключения драйвера
pinMode (pin_PUL, OUTPUT);
pinMode (pin_DIR, OUTPUT);
pinMode (pin_ENA, OUTPUT);
//pinMode (pin_ModeSetVal, INPUT_PULLUP);
pinMode (pin_ModeWork, INPUT_PULLUP);
// Включить внутренние подтягивающие резисторы
digitalWrite(A0, HIGH);
digitalWrite(A1, HIGH);
digitalWrite(A2, HIGH);
//digitalWrite(A3, HIGH);
PCICR = 0b00000010; // 1. PCIE1: Включить прерывание 1 по изменению состояния
PCMSK1 = 0b00001111; // Включить прерывание по изменению состояния для A0, A1, A2, A3
//Проверка режима работы при старте системы
timer = millis();
// Первый запуск
if (EEPROM.read(INIT_ADR) != INIT_KEY){
EEPROM.write(INIT_ADR, INIT_KEY);
EEPROM.put(0, initx);
EEPROM.put(4, initxx);
EEPROM.put(8, initxxx);
EEPROM.put(12, inity);
EEPROM.put(16, inityy);
EEPROM.put(20, inityyy);
EEPROM.put(24, inita);
EEPROM.put(28, initaa);
EEPROM.put(32, initaaa);
EEPROM.put(36, initb);
EEPROM.put(40, initbb);
EEPROM.put(44, initbbb);
EEPROM.put(48, initRV1);
EEPROM.put(52, initRV2);
}
// Чтение сохраненных данных
EEPROM.get(0, x);
EEPROM.get(4, xx);
EEPROM.get(8, xxx);
EEPROM.get(12, y);
EEPROM.get(16, yy);
EEPROM.get(20, yyy);
EEPROM.get(24, a);
EEPROM.get(28, aa);
EEPROM.get(32, aaa);
EEPROM.get(36, b);
EEPROM.get(40, bb);
EEPROM.get(44, bbb);
EEPROM.get(48, item_RV1);
EEPROM.get(52, item_RV2);
valV1 = xxx + xx + x;
valV2 = yyy + yy + y;
angleA = aaa + aa + a;
//Serial.println(aaa + aa + a);
angleB = bbb + bb + b;
index_V1 = 4;
index_V2 = 4;
index_A = 4;
index_B = 4;
item_M = 1;
lcd.init();
lcd.backlight();// Включаем подсветку дисплея
lcd.createChar(0, setChar);
lcd.createChar(1, setFullChar);
lcd.createChar(2, setCharRotateClock);
lcd.createChar(3, setCharRotateAntiClock);
lcd.setCursor(0, 0);
lcd.print("PRESS 'STOP'");
lcd.setCursor(0, 1);
lcd.print("FOR SETUP");
timer = millis();
while (millis()-timer <=3000){
if (!digitalRead(emergencyStop)){
if (millis() - timer >= 350){
lcd.clear();
setupMenu();
}
}else{
lcd.setCursor(10, 1);
lcd.print((4000-millis()+timer)/1000 );
}
}
timer = millis();
flagEmerStop = false;
lcd.clear();
// Вывод на дисплей после запуска
lcd.setCursor(1, 0);
lcd.print("V1=");
lcd.setCursor(4, 0);
lcdSpeedDisplayV1();
lcd.setCursor(1, 1);
lcd.print("V2=");
lcd.setCursor(4, 1);
lcdSpeedDisplayV2();
lcd.setCursor(14,0);
lcd.print("R");
lcd.setCursor(14,1);
lcd.print("R");
lcd.setCursor(9, 0);
lcd.print("A");
lcdAngleDisplayA();
lcd.setCursor(9, 1);
lcd.print("B");
lcdAngleDisplayB();
setRotateWay();
}//END SETUP
//ГЛАВНЫЙ ЦИКЛ ПРОГРАММЫ
void loop() {
if (!digitalRead(pin_ModeWork)){
flagModeWork = true;
flagModeSetVal = false;
flagEmerStop = false;
}else{
flagModeWork = false;
flagModeSetVal = true;
flagHideCursor = true;
flagEmerStop = true;
}
//Режим настройки и вывода информации на дисплей
if (flagModeSetVal == true){
if (!digitalRead(pinButton)){
if (millis() - timer >= 350){
flagItem_M = true;
timer = millis();
}
}
setMenu();
setMenuLevel();
setRotateWay();
if (item_M == 1 || item_M == 2){
editSpeedUp();
editSpeedDown();
}
if (item_M == 3 || item_M == 4){
editAngleUp();
editAngleDown();
}
}
//Режим выполнения вращения двигателя
if (flagModeWork == true){
if (flagHideCursor == true){
flagHideCursor = false;
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(8, 0);
lcd.print(" ");
lcd.setCursor(8, 1);
lcd.print(" ");
}
if (!digitalRead(pin_StartV1)){
if (millis() - timer >= 350){
if (item_RV1 == 1){
digitalWrite(pin_DIR, HIGH);
}else{
digitalWrite(pin_DIR, LOW);
}
//stepperG.setRunMode(KEEP_SPEED); // режим поддержания скорости
//stepperG.setSpeedDeg(xxx+xx+x); // в градусах/сек
//motorMotion(xxx+xx+x, aaa+aa+a);
calcSpeed(xxx, xx, x);
calcAngle(aaa, aa, a);
stepper.setMaxSpeed(Accel);
stepper.setSpeed(Speed);
if (flagEmerStop == false){
motorMove();
}
}
}
if (!digitalRead(pin_StartV2)){
if (millis() - timer >= 350){
if (item_RV2 == 1){
digitalWrite(pin_DIR, HIGH);
}else{
digitalWrite(pin_DIR, LOW);
}
//stepperG.setRunMode(KEEP_SPEED); // режим поддержания скорости
//stepperG.setSpeedDeg(yyy+yy+y); // в градусах/сек
//motorMotion(yyy+yy+y, bbb+bb+b);
calcSpeed(yyy, yy, y);
calcAngle(bbb, bb, b);
stepper.setMaxSpeed(Accel);
stepper.setSpeed(Speed);
if (flagEmerStop == false){
motorMove();
}
}
}
}
}//END LOOP
//МЕНЮ СКОРОСТЕЙ
void setMenu(){
if (flagItem_M && index_V1 == 4 && index_V2 == 4 && index_A == 4 && index_B == 4){
//if (millis()-timer >=350){
item_M++;
if (item_M > 4){item_M = 1;}
flagItem_M = false;
//timer = millis();
//}
}else{
flagItem_M = false;
}
switch (item_M) {
case 1:
if (index_V1 == 4){
lcd.setCursor(0, 0);
lcd.write(1);
}else{
lcd.setCursor(0, 0);
lcd.write(0);
}
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(8, 0);
lcd.print(" ");
lcd.setCursor(8, 1);
lcd.print(" ");
break;
case 2:
lcd.setCursor(0, 0);
lcd.print(" ");
if (index_V2 == 4){
lcd.setCursor(0, 1);
lcd.write(1);
}else{
lcd.setCursor(0, 1);
lcd.write(0);
}
lcd.setCursor(8, 0);
lcd.print(" ");
lcd.setCursor(8, 1);
lcd.print(" ");
break;
case 3:
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(" ");
if (index_A == 4){
lcd.setCursor(8, 0);
lcd.write(1);
}else{
lcd.setCursor(8, 0);
lcd.write(0);
}
lcd.setCursor(8, 1);
lcd.print(" ");
break;
case 4:
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(8, 0);
lcd.print(" ");
if (index_B == 4){
lcd.setCursor(8, 1);
lcd.write(1);
}else{
lcd.setCursor(8, 1);
lcd.write(0);
}
break;
}
}
//МЕНЮ НАПРАВЛЕНИЯ ВРАЩЕНИЯ
void setRotateWay(){
if (!digitalRead(pinButtonRotate)){
if (millis()-timer >=550){
if (item_M == 3){
item_RV1++;
if (item_RV1 > 2){item_RV1 = 1;}
}
if (item_M == 4){
item_RV2++;
if (item_RV2 > 2){item_RV2 = 1;}
}
timer = millis();
}
}
switch (item_RV1){
case 1: //Если вращение по часовой стрелке
lcd.setCursor(15, 0);
lcd.write(2);
break;
case 2: //Если вращение против часовой стрелки
lcd.setCursor(15, 0);
lcd.write(3);
break;
}
switch (item_RV2){
case 1: //Если вращение по часовой стрелке
lcd.setCursor(15, 1);
lcd.write(2);
break;
case 2: //Если вращение против часовой стрелки
lcd.setCursor(15, 1);
lcd.write(3);
break;
}
}//END VOID
//ВЫБОР ИЗМЕНЯЕМЫХ РАЗРЯДОВ СКОРОСТЕЙ
void setMenuLevel(){
if (!digitalRead(pinSetV)){
if (millis()-timer >=350){
timer = millis();
if (item_M == 1){
index_V1++;
if (index_V1 > 4){
index_V1 = 1;
}
}
if (item_M == 2){
index_V2++;
if (index_V2 > 4){
index_V2 = 1;
}
}
if (item_M == 3){
index_A++;
if (index_A > 4){
index_A = 1;
}
}
if (item_M == 4){
index_B++;
if (index_B > 4){
index_B = 1;
}
}
}
}
}//END VOID
//ИЗМЕНЯЕМ СКОРОСТЬ 1 ПОВОРОТОМ ЕНКОДЕРА ВЫВОДИМ НА ДИСПЛЕЙ
void editSpeedUp(){
if (cnt1 > 0) {
if (item_M==1){
setValue(index_V1, x, xx, xxx, maxV1, minV1);
timer = millis();
}
if (item_M==2){
setValue(index_V2, y, yy, yyy, maxV2, minV2);
timer = millis();
}
cnt1 =0;
}
if (millis() - timer >= 1500 && millis() - timer <= 1600){
saveSpeedMemory();
}
lcdSpeedDisplayV1();
lcdSpeedDisplayV2();
}
//ИЗМЕНЯЕМ СКОРОСТЬ 2 ПОВОРОТОМ ЕНКОДЕРА
void editSpeedDown(){
if (cnt1 < 0) {
if (item_M == 1){
setValue(index_V1, x, xx, xxx, maxV1, minV1);
timer = millis();
}
if (item_M == 2){
setValue(index_V2, y, yy, yyy, maxV2, minV2);
timer = millis();
}
cnt1 =0;
}
if (millis() - timer >= 1500 && millis() - timer <= 1600){
saveSpeedMemory();
}
lcdSpeedDisplayV1();
lcdSpeedDisplayV2();
}
//Вывод на дисплей значения скорости 1
void lcdSpeedDisplayV1(){
if (item_M == 1){
timeNew = millis();
}
if (timeNew - timeOld >= interval){
flagV1 = !flagV1;
timeOld = timeNew;
}
if (index_V1 == 3){
if (flagV1){
lcd.setCursor(4, 0);
lcd.print(" ");
}else{
lcd.setCursor(4, 0);
lcd.print(xxx/100);
}
lcd.setCursor(5, 0);
lcd.print(xx/10);
lcd.setCursor(6, 0);
lcd.print(x);
}
if (index_V1 == 2){
lcd.setCursor(4, 0);
lcd.print(xxx/100);
if (flagV1){
lcd.setCursor(5, 0);
lcd.print(" ");
}else{
lcd.setCursor(5, 0);
lcd.print(xx/10);
}
lcd.setCursor(6, 0);
lcd.print(x);
}
if (index_V1 == 1){
lcd.setCursor(4, 0);
lcd.print(xxx/100);
lcd.setCursor(5, 0);
lcd.print(xx/10);
if (flagV1){
lcd.setCursor(6, 0);
lcd.print(" ");
}else{
lcd.setCursor(6, 0);
lcd.print(x);
}
}
if (index_V1 == 4){
lcd.setCursor(4, 0);
lcd.print(xxx/100);
lcd.setCursor(5, 0);
lcd.print(xx/10);
lcd.setCursor(6, 0);
lcd.print(x);
}
}
//Вывод на дисплей значения скорости 2
void lcdSpeedDisplayV2(){
if (item_M == 2){
timeNew = millis();
}
if (timeNew -timeOld >= interval){
timeOld = timeNew;
flagV2 = !flagV2;
}
if (index_V2 == 3){
if (flagV2){
lcd.setCursor(4, 1);
lcd.print(" ");
}else{
lcd.setCursor(4, 1);
lcd.print(yyy/100);
}
lcd.setCursor(5, 1);
lcd.print(yy/10);
lcd.setCursor(6, 1);
lcd.print(y);
}
if (index_V2 == 2) {
lcd.setCursor(4, 1);
lcd.print(yyy/100);
if (flagV2){
lcd.setCursor(5, 1);
lcd.print(" ");
}else{
lcd.setCursor(5, 1);
lcd.print(yy/10);
}
lcd.setCursor(6, 1);
lcd.print(y);
}
if (index_V2 == 1){
lcd.setCursor(4, 1);
lcd.print(yyy/100);
lcd.setCursor(5, 1);
lcd.print(yy/10);
if (flagV2){
lcd.setCursor(6, 1);
lcd.print(" ");
}else{
lcd.setCursor(6, 1);
lcd.print(y);
}
}
if (index_V2 == 4){
lcd.setCursor(4, 1);
lcd.print(yyy/100);
lcd.setCursor(5, 1);
lcd.print(yy/10);
lcd.setCursor(6, 1);
lcd.print(y);
}
}
void editAngleUp(){
if (cnt1 > 0) {
if (item_M == 3){
setValue(index_A, a, aa, aaa, maxA, minA);
timer = millis();
}
if (item_M==4){
setValue(index_B, b, bb, bbb, maxB, minB);
timer = millis();
}
cnt1 =0;
}
if (millis() - timer == 1500 && millis() - timer <= 1700){
saveAngleMemory();
}
lcdAngleDisplayA();
lcdAngleDisplayB();
}
//ИЗМЕНЯЕМ СКОРОСТЬ 2 ПОВОРОТОМ ЕНКОДЕРА
void editAngleDown(){
if (cnt1 < 0) {
if (item_M== 3){
setValue(index_A, a, aa, aaa, maxA, minA);
timer = millis();
}
if (item_M== 4){
setValue(index_B, b, bb, bbb, maxB, minB);
timer = millis();
}
cnt1 =0;
}
if (millis() - timer == 1500 && millis() - timer <= 1700){
saveAngleMemory();
}
lcdAngleDisplayA();
lcdAngleDisplayB();
}
void lcdAngleDisplayA(){
if (item_M == 3){
timeNew = millis();
}
if (timeNew - timeOld >= interval){
flagA = !flagA;
timeOld = timeNew;
}
if (index_A == 3){
if (flagA){
lcd.setCursor(10, 0);
lcd.print(" ");
}else{
lcd.setCursor(10, 0);
lcd.print(aaa/100);
}
lcd.setCursor(11, 0);
lcd.print(aa/10);
lcd.setCursor(12, 0);
lcd.print(a);
}
if (index_A == 2){
lcd.setCursor(10, 0);
lcd.print(aaa/100);
if (flagA){
lcd.setCursor(11, 0);
lcd.print(" ");
}else{
lcd.setCursor(11, 0);
lcd.print(aa/10);
}
lcd.setCursor(12, 0);
lcd.print(a);
}
if (index_A == 1){
lcd.setCursor(10, 0);
lcd.print(aaa/100);
lcd.setCursor(11, 0);
lcd.print(aa/10);
if (flagA){
lcd.setCursor(12, 0);
lcd.print(" ");
}else{
lcd.setCursor(12, 0);
lcd.print(a);
}
}
if (index_A == 4){
lcd.setCursor(10, 0);
lcd.print(aaa/100);
lcd.setCursor(11, 0);
lcd.print(aa/10);
lcd.setCursor(12, 0);
lcd.print(a);
}
}
void lcdAngleDisplayB(){
if (item_M == 4){
timeNew = millis();
}
if (timeNew -timeOld >= interval){
timeOld = timeNew;
flagB = !flagB;
}
if (index_B == 3){
if (flagB){
lcd.setCursor(10, 1);
lcd.print(" ");
}else{
lcd.setCursor(10, 1);
lcd.print(bbb/100);
}
lcd.setCursor(11, 1);
lcd.print(bb/10);
lcd.setCursor(12, 1);
lcd.print(b);
}
if (index_B == 2) {
lcd.setCursor(10, 1);
lcd.print(bbb/100);
if (flagB){
lcd.setCursor(11, 1);
lcd.print(" ");
}else{
lcd.setCursor(11, 1);
lcd.print(bb/10);
}
lcd.setCursor(12, 1);
lcd.print(b);
}
if (index_B == 1){
lcd.setCursor(10, 1);
lcd.print(bbb/100);
lcd.setCursor(11, 1);
lcd.print(bb/10);
if (flagB){
lcd.setCursor(12, 1);
lcd.print(" ");
}else{
lcd.setCursor(12, 1);
lcd.print(b);
}
}
if (index_B == 4){
lcd.setCursor(10, 1);
lcd.print(bbb/100);
lcd.setCursor(11, 1);
lcd.print(bb/10);
lcd.setCursor(12, 1);
lcd.print(b);
}
}
//ФУНКЦИЯ ИЗМЕНЕНИЯ ПАРАМЕТРОВ СКОРОСТЕЙ, УГЛОВ
void setValue(byte index, int& p, int& pp, int& ppp, int maxVal, int minVal){
//Увеличиваем параметр
if (cnt1 > 0){
if (index == 1){
if (p+1 < 10 && ppp+pp+p < maxVal){
p = p+1;
}else{
p = 0;
}
}
if(index == 2){
if (pp + 10 < 100 && ppp+pp+p + 10 < maxVal){
pp = pp + 10;
}else{
pp = 0;
}
}
if (index == 3){
if (ppp + 100 < maxVal-pp-p && ppp+pp+p + 100 < maxVal){
ppp = ppp + 100;
}else{
ppp = 0;
}
}
if (index == 4){
if (ppp+pp+p < maxVal){
p = p+1;
if (p >= 10 && ppp+pp+p < maxVal){
p = 0;
pp = pp + 10;
}
if (pp >= 100 && ppp+pp+p < maxVal){
pp = 0;
ppp = ppp + 100;
}
if (ppp >= maxVal && ppp+pp+p < maxVal){
ppp = maxVal - pp -p;
}
}
}
timer = millis();
}
//Уменьшаем параметр
if (cnt1 < 0){
if (index == 1){
if (p-1 >= 0 && ppp+pp+p - 1 >= minVal){
p = p-1;
}else{
if(ppp+pp+9 <= maxVal){p=9;}else{
if(ppp+pp+8 <= maxVal){p=8;}else{
if(ppp+pp+7 <= maxVal){p=7;}else{
if(ppp+pp+6 <= maxVal){p=6;}else{
if(ppp+pp+5 <= maxVal){p=5;}else{
if(ppp+pp+4 <= maxVal){p=4;}else{
if(ppp+pp+3 <= maxVal){p=3;}else{
if(ppp+pp+2 <= maxVal){p=2;}else{
if(ppp+pp+1 <= maxVal){p=1;}
}
}
}
}
}
}
}
}
}
}
if(index == 2){
if (pp - 10 > 0 && ppp+pp+p - 10 > minVal){
pp = pp - 10;
}else{
if(ppp+p+90 <= maxVal){pp=90;}else{
if(ppp+p+80 <= maxVal){pp=80;}else{
if(ppp+p+70 <= maxVal){pp=70;}else{
if(ppp+p+60 <= maxVal){pp=60;}else{
if(ppp+p+50 <= maxVal){pp=50;}else{
if(ppp+p+40 <= maxVal){pp=40;}else{
if(ppp+p+30 <= maxVal){pp=30;}else{
if(ppp+p+20 <= maxVal){pp=20;}else{
if(ppp+p+10 <= maxVal){pp=10;}
}
}
}
}
}
}
}
}
}
}
if (index == 3){
if (ppp - 100 >= minVal && ppp+pp+p - 100 > minVal){
ppp = ppp - 100;
}else{
if(pp+p+900 <= maxVal){ppp=900;}else{
if(pp+p+800 <= maxVal){ppp=800;}else{
if(pp+p+700 <= maxVal){ppp=700;}else{
if(pp+p+600 <= maxVal){ppp=600;}else{
if(pp+p+500 <= maxVal){ppp=500;}else{
if(pp+p+400 <= maxVal){ppp=400;}else{
if(pp+p+300 <= maxVal){ppp=300;}else{
if(pp+p+200 <= maxVal){ppp=200;}else{
if(pp+p+100 <= maxVal){ppp=100;}
}
}
}
}
}
}
}
}
}
}
if (index == 4){
if (ppp+pp+p > minVal){
p = p-1;
if (p < 0 && ppp+pp+p > minVal){
p = 9;
pp = pp - 10;
}
if (pp < 0 && ppp+pp+p > minVal){
pp = 90;
ppp = ppp - 100;
}
if (ppp <= minVal && ppp+pp+p > minVal){
ppp = 0;
}
}
}
timer = millis();
}
//Serial.print(ppp);
//Serial.print(" ");
//Serial.print(pp);
//Serial.print(" ");
//Serial.println(p);
}
//СОХРАНЕНИЕ ПАРАМЕТРОВ СКОРОСТЕЙ
void saveSpeedMemory(){
EEPROM.put(0, x);
EEPROM.put(4, xx);
EEPROM.put(8, xxx);
EEPROM.put(12, y);
EEPROM.put(16, yy);
EEPROM.put(20, yyy);
//Serial.print(millis()/1000);
}
//СОХРАНЕНИЕ ПАРАМЕТРОВ УГЛОВ
void saveAngleMemory(){
EEPROM.put(24, a);
EEPROM.put(28, aa);
EEPROM.put(32, aaa);
EEPROM.put(36, b);
EEPROM.put(40, bbb);
EEPROM.put(44, bbb);
//Serial.print(millis()/1000);
}
/***********************************************************/
//ВРАЩЕНИЕ ДВИГАТЕЛЯ с использованием библиотеки <Stepper.h>//
/***********************************************************/
/*
void motorMotion(uint16_t speed, uint16_t angle){
static uint32_t t1;
t1 = millis();
static uint32_t t2;
static float k = 0.45;
stepper.setSpeed(speed*4);
Serial.println("**********");
Serial.print("Speed = ");
Serial.println(speed);
stepper.step((angle)*8/k);
t2 = millis();
Serial.print("Time = ");
Serial.print(t2 - t1);
Serial.println(" мс");
}
/********************************************************/
/*****************************************************************/
//ВРАЩЕНИЕ ДВИГАТЕЛЯ с использованием библиотеки <GyverStepper.h>//
/****************************************************************/
/*
void motorMotion(){
static uint32_t t1, t2;
t1 = millis();
stepperG.tick();
t2 = millis();
Serial.println("**********");
Serial.print("Time = ");
Serial.print(t2 - t1);
Serial.println(" мс");
}
/******************************************************************/
/*****************************************************************/
//ВРАЩЕНИЕ ДВИГАТЕЛЯ с использованием библиотеки <AccelStepper.h>//
/****************************************************************/
void calcSpeed(uint16_t sss, uint16_t ss, uint16_t s){
Speed = (float)STEPS*k*k*(sss+ss+s)/60;
Accel = (float)STEPS*k*(sss+ss+s)/60;
//Serial.println(Speed);
//Serial.println(Accel);
}
void calcAngle(uint16_t ddd, uint16_t dd, uint16_t d){
Angle = (float)(ddd+dd+d)*k/(1.8);
}
void motorMove(){
rotorPos = stepper.currentPosition();
Serial.println(rotorPos);
while(rotorPos < Angle){
rotorPos = stepper.currentPosition();
stepper.runSpeed();
if (flagEmerStop == true){break;}
}
stepper.setCurrentPosition(0);
//Serial.println(Angle);
Serial.println(rotorPos);
}
/*****************************************************************/
void setupMenu(){
flagEmerStop = false;
static byte itm = 1;
static byte i = 1;
static byte j = 1;
while(true){
lcd.setCursor(1, 0);
lcd.print("D_Stp 1:");
lcd.setCursor(1, 1);
lcd.print("Rdctr 1:");
lcd.setCursor(12, 1);
lcd.print("EXIT");
if(!digitalRead(pinSW)){
itm++;
if(itm > 3){itm = 1;}
}
switch (itm){
case 1:
lcd.setCursor(0, 0);
lcd.write(1);
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(11, 1);
lcd.print(" ");
break;
case 2:
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.write(1);
lcd.setCursor(11, 1);
lcd.print(" ");
break;
case 3:
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(11, 1);
lcd.write(1);
break;
}
if(itm == 1){
if(cnt1 > 0){
i++;
cnt1 = 0;
if(i > 5){
i = 1;
}
}
}
if(itm == 2){
if(cnt1 > 0){
j++;
cnt1 = 0;
if(j > 5){
j = 1;
}
}
}
switch (i){
case 1:
k_DrvrSteps = 1;
lcd.setCursor(9, 0);
lcd.print("1");
lcd.setCursor(10, 0);
lcd.print(" ");
break;
case 2:
k_DrvrSteps = 2;
lcd.setCursor(9, 0);
lcd.print("2");
lcd.setCursor(10, 0);
lcd.print(" ");
break;
case 3:
k_DrvrSteps = 4;
lcd.setCursor(9, 0);
lcd.print("4");
lcd.setCursor(10, 0);
lcd.print(" ");
break;
case 4:
k_DrvrSteps = 8;
lcd.setCursor(9, 0);
lcd.print("8");
lcd.setCursor(10, 0);
lcd.print(" ");
break;
case 5:
k_DrvrSteps = 16;
lcd.setCursor(9, 0);
lcd.print("1");
lcd.setCursor(10, 0);
lcd.print("6");
break;
}
switch (j){
case 1:
k_Reductor = 2;
lcd.setCursor(9, 1);
lcd.print("1");
break;
case 2:
k_Reductor = 3;
lcd.setCursor(9, 1);
lcd.print("2");
break;
case 3:
k_Reductor = 4;
lcd.setCursor(9, 1);
lcd.print("3");
break;
case 4:
k_Reductor = 5;
lcd.setCursor(9, 1);
lcd.print("4");
break;
case 5:
k_Reductor = 16;
lcd.setCursor(9, 1);
lcd.print("5");
break;
}
if(!digitalRead(emergencyStop) && itm == 3){
Serial.println(flagEmerStop);
break;
}
}
}
///////////////////////////////////
// ВНЕШНЕЕ ПРЕРЫВАНИЕ ДЛЯ ЭНКОДЕРА
///////////////////////////////////
ISR (PCINT1_vect)
{
if (!digitalRead(emergencyStop)){
flagEmerStop = true;
}
// Если прерывание вызвано кнопкой
if (!digitalRead(pinSW))
{
flagItem_M = true;
}
// Или если прерывание вызвано сигналами энкодера
else
{
// Прочитать сигналы A и B
boolean A_val = digitalRead(pinCLK);
boolean B_val = digitalRead(pinDT);
// Записать сигналы A и B в отдельные последовательности
seqA <<= 1;
seqA |= A_val;
seqB <<= 1;
seqB |= B_val;
// Маскировать четыре старших бита
seqA &= 0b00001111;
seqB &= 0b00001111;
// Сравнить запсанную последовательность с ожидаемой последовательностью
if (seqA == 0b00001001 && seqB == 0b00000011)
{
cnt1--;
}
if (seqA == 0b00000011 && seqB == 0b00001001)
{
cnt1++;
}
//Serial.println(cnt1);
}
}