Цитата: 
	
	
		
			 
			
				
					Сообщение от Maddeath
					(Сообщение 324937)
				 
				...новый проект делаем? 
			
			 
		 | 
	 
	 
 Благодарю за отзыв. 
По новому проекту отправил тебе на почту вариант механизма. 
Это "тот самый костыль, который заставляет шевелиться всю электро-механику".
 
	PHP код: 
	
		 
		
		
			
#include <Servo.h> 
 #include <EEPROM.h>
   
   int value = 0;                                                                // переменная для хранения значения ШИМ ( модуль MOSFET управления питанием сервомоторов)
   int Mosfet1 = 11;                                                             // контакт, к которому подключен модуль MOSFET управления питанием сервомоторов
 
   int pos = 0;
   // Создадим класс управления серво-приводом горизонтального перемещения
   Servo Horizontal_Motor;                                                      // Класс управления серво-приводом горизонтального перемещения
   int  HM_Pin                  = 10;                                           // Контакт, к которому подключен серво-привод горизонтального перемещения
 
   // Создадим класс управления серво-приводом вертикального перемещения
   Servo Vertical_Motor;                                                        // Класс управления серво-приводом вертикального перемещения
   int  VM_Pin                  = 9;                                            // Контакт, к которому подключен серво-привод вертикального перемещения
   int  Mosfet2                 = 14;                                           // Контакт, к которому подключен MOSFET управления питанием планшета
   int  VM_Max_Angle_Position   = 95;                                           // Максимальный угол открытия монитора
   int  VM_Min_Angle_Position   = 0;                                            // Минимальный угол открытия монитора
   long VM_Timer                = 0;                                            // Задержка перед сменой направления
   int  VM_Working_Mode         = 0;                                            // Режим работы вертикального привода: 0 - постоянное кручение, 1 - поправка
 
   // Команды для серво-приводов
   int  Servo_Stop_Command      = 90;                                           // Команда остановки серво-привода
   int  Servo_Close_Command     = 0;                                            // Команда закрытия серво-привода (движение каретки назад)
   int  Servo_Open_Command      = 180;                                          // Команда открытия серво-привода (движение каретки вперед)
 
 
   // Оптические датчики
   int  Opt_Sensor_Fwd_Ctrl_Pin = 7;                                            // Оптический прерыватель «вперед» управляющий PIN7, питание PIN8
   int  Opt_Sensor_Fwd_ACC_Pin  = 8;                                            // Оптический прерыватель «вперед» управляющий PIN7, питание PIN8
   int  Opt_Sensor_Bwd_Ctrl_Pin = 5;                                            // Оптический прерыватель «назад» управляющий PIN5, питание PIN6
   int  Opt_Sensor_Bwd_ACC_Pin  = 6;                                            // Оптический прерыватель «назад» управляющий PIN5, питание PIN6
 
   // Диагностический светодиод
   int  Led_Pin                 = 13;                                           // Контакт, к которому подключен диагностический светодиод
 
   // Кнопки управления системой
   int  Btn_Open_Close_Pin      = 2;                                            // Контакт, к которому подключена кнопка управления открытия/закрытия монитора
   int  Btn_Adjust_Position_Pin = 3;                                            // Контакт, к которому подключена кнопка управления настройкой вертикальной позиции монитора
 
   // Переменные для хранения состояния кнопкок управления системой
   int  Btn_Open_Close_State;                                                   // Переменная состояния кнопки управления открытия/закрытия монитора
   int  Btn_Adjust_Position_State;                                              // Переменная состояния кнопки управления настройкой вертикальной позиции монитора
   int  Btn_Adjust_Position_Course;                                             // Переменная, в которой хранится вертикальное направление движения позиции монитора
   long Btn_Open_Close_Last_Time;                                               // Переменная, в которой хранится последнее время мажатия кнопки управления открытия/закрытия монитора
   long Btn_Adjust_Position_Last_Time;                                          // Переменная, в которой хранится последнее время мажатия кнопки управления настройкой вертикальной позиции монитора
 
   // Значения для обработки кнопок
   int  Btn_Pressed              = LOW;
   int  Btn_Released             = HIGH;
   int  Btn_Direction_Up         = 0;
   int  Btn_Direction_Down       = 1;
   long Btn_Open_Close_Debounce  = 200;                                         // Временная константа дребезга клавиши (миллисекунды) открытия/закрытия
   long Btn_Adjust_Debounce      = 8;                                           // Временная константа дребезга клавиши (миллисекунды) угла наклона монитора
   long Btn_Adjust_Debounce_Sleep = 7;                                          // Задержка перед обработкой клавиши угла....
 
 
   // Сохранение состояния системы в EEPROM
   int  HM_State_Offset         = 0;
   int  VM_State_Offset         = 4;
   int  VM_Working_Angle_Offset = 8;
   int  VM_Temp_Angle_Offset    = 16;
   long Check_Sum_Offset        = 32;
 
   // Значения состояния системы
   int  SM_Opened_State          = 0;
   int  SM_Opening_State         = 1;
   int  SM_Closing_State         = 2;
   int  SM_Closed_State          = 3;
 
   // Переменные хранения состояния системы
   int  HM_State;                                                               // Переменная хранения текущего состояния горизонтального серво-привода
   int  VM_State;                                                               // Переменная хранения текущего состояния вертикального серво-привода
   int  VM_Working_Angle_Position;                                              // Переменная хранения рабочей позиции монитора
   int  VM_Temp_Angle_Position;                                                 // Переменная для хранения угла монитора при открывании/складывании
   long CheckSum; 
 
 
 
 
 void setup() 
 { 
   // !!! Наверное надо проверять на запуск с зажатой кнопкой "Открыть"
   // !!! и при таком состоянии нам пользователь сообщает, что 
   // !!! система закрыта и необходимо просто обновить ее состояние в EEPROM
  
   
   // Подаем питание на модуль MOSFET управления питанием сервомоторов
   for(value = 0 ; value <= 255; value+=5) // напряжение постепенно увеличивается (от 0V до 5V)
   { 
     analogWrite(Mosfet1, value);           
     delay(5);  // ждём 5 миллисекунд (время подбираем опытным путем)
      // Сконфигурируем контакт питания модуля MOSFET управления питанием планшета
    pinMode(Mosfet2, OUTPUT);
   }  
   
   
   // Отладка 
   Serial.begin(9600);
   while (!Serial) {
     ; // wait for serial port to connect. Needed for Leonardo only
   }
 
 
   //----------------------//
   // Настроим всю систему //
   //----------------------//
 
   // Обнулим переменную, в которой хранится последнее время мажатия кнопки управления открытия/закрытия монитора
   Btn_Open_Close_Last_Time      = 0;                                      
   // Обнулим переменную, в которой хранится последнее время мажатия кнопки управления настройкой вертикальной позиции монитора
   Btn_Adjust_Position_Last_Time = 0;                                      
 
   // Установим переменную, в которой хранится вертикальное направление движения позиции монитора на движение "вниз"
   Btn_Adjust_Position_Course    = Btn_Direction_Down;                                             
 
   // Сконфигурируем контакт кнопки управления открытием/закрытием как "Вход" и подключим к контакту внутренний резистор
   pinMode(Btn_Open_Close_Pin, INPUT);
 
   // Сконфигурируем контакт кнопки управления настройкой вертикальной позиции монитора как "Вход" и подключим к контакту внутренний резистор
   pinMode(Btn_Adjust_Position_Pin, INPUT);
 
 
   // Сконфигурируем контакт диагностического светодиода как "Выход" (будем зажигать/гасить)
   //pinMode(Led_Pin, OUTPUT);
 
   // Подключим контакт управления серво-приводом горизонтального перемещения
   Horizontal_Motor.attach(HM_Pin);
 
   // Остановим и удержим серво-привод горизонтального перемещения в положении "Стоп"
   Horizontal_Motor.write(Servo_Stop_Command);
 
 
  
 
 
 
   // Инициализируем оптические датчики
   pinMode(Opt_Sensor_Fwd_Ctrl_Pin, INPUT);
   pinMode(Opt_Sensor_Fwd_ACC_Pin,  OUTPUT);
 
   pinMode(Opt_Sensor_Bwd_Ctrl_Pin, INPUT);
   pinMode(Opt_Sensor_Bwd_ACC_Pin,  OUTPUT);
 
   // Подадим питание на оптические датчики
   //digitalWrite(Opt_Sensor_Fwd_ACC_Pin, HIGH);
   //digitalWrite(Opt_Sensor_Bwd_ACC_Pin, HIGH);
 
 
   //---------------------------------------//
   // Проверим предыдущее состояние системы //
   //---------------------------------------//
 
   // Считаем предыдущее состояние системы
   HM_State                  = EEPROM.read(HM_State_Offset); 
   VM_State                  = EEPROM.read(VM_State_Offset); 
   VM_Working_Angle_Position = EEPROM.read(VM_Working_Angle_Offset); 
   VM_Temp_Angle_Position    = EEPROM.read(VM_Temp_Angle_Offset); 
 
   // Проверим угол наклона монитора на максимальный и минимальный
   if (VM_Working_Angle_Position > VM_Max_Angle_Position | VM_Working_Angle_Position < 0) {
     VM_Working_Angle_Position = VM_Max_Angle_Position;
 
     // Сохраним угол наклона монитора в EEPROM
     EEPROM.write(VM_Working_Angle_Offset, VM_Working_Angle_Position); 
   }
 
   // Считаем контрольную сумму из EEPROM
   CheckSum = EEPROM.read(Check_Sum_Offset); 
 
   // Проверим контрольную сумму - совпала и состояние серво-приводов = SM_Closed_State легко продолжаем работу
   if ( (CheckSum == (HM_State * 256) + VM_State) & (HM_State == SM_Closed_State) & (VM_State == SM_Closed_State) ) {
     return;
   }
 
   //--------------------------------------------------------------//
   // Надо сначала все механизмы привести в стартовое состояние    //
   //--------------------------------------------------------------//
 
 
   delay(2000);
 
   Serial.print("VM_Temp_Angle_Position");
   Serial.print("\t  = \t");
   Serial.print(VM_Temp_Angle_Position, DEC);
   Serial.println();
 
 
   if (VM_Temp_Angle_Position > 0) {
 
     // Выпрямим монитор с сохраненной временной позиции до 0
     VM_Working_Angle_Position = VM_Temp_Angle_Position;
     Start_Vertical_Motor(Servo_Close_Command);
   } else {
 
     // Выпрямим монитор для страховки в 0
     Vertical_Motor.write(0);
   }
   // Теперь сохраним правильное значение временной позиции
   VM_Temp_Angle_Position = 0;
   EEPROM.write(VM_Temp_Angle_Offset, VM_Temp_Angle_Position); 
 
   // Считаем реальное рабочее положение монитора
   VM_Working_Angle_Position = EEPROM.read(VM_Working_Angle_Offset); 
 
   // Сохраним вертикальное положение монитора в EEPROM
   VM_State = SM_Closed_State;
   EEPROM.write(VM_State_Offset, SM_Closed_State); 
 
   // Затем затянем его обратно
   Start_Horizontal_Motor(Servo_Close_Command, 10000);
 
   // Теперь сохраним состояние системы в "хорошем" состоянии
   HM_State = SM_Closed_State;
 
   // Сохраним положение монитора в EEPROM
   EEPROM.write(HM_State_Offset, HM_State); 
 
   // Пересчитаем контрольную сумму в EEPROM
   EEPROM.write(Check_Sum_Offset, (HM_State * 256) + VM_State); 
 } 
 
 
 //
 // Поворот на один градус вертикального привода в зависимсоти от переменной  Btn_Adjust_Position_Course
 //
 void VM_Move()
 {
           // Проверим переменную, в которой хранится вертикальное направление движения позиции монитора
           if (Btn_Adjust_Position_Course == Btn_Direction_Down) {
 
 
   Serial.print("Direction = DOWN. Angle ");
   Serial.print("\t  = \t");
   Serial.print(VM_Working_Angle_Position, DEC);
   Serial.println();
 
             // Теперь сохраним состояние системы в "не очень хорошем" состоянии
             VM_State = SM_Closing_State;
             // Сохраним положение монитора в EEPROM
             EEPROM.write(VM_State_Offset, VM_State); 
 
             //
             // Необходимо наклонить монитор на один градус "вниз"
             //
 
             // Проверим на достижение "критического угла наклона"
             if (VM_Working_Angle_Position == VM_Min_Angle_Position) {
               // Угу. Встали в крайнюю позицию. Надо начинать движение "вверх".
               Btn_Adjust_Position_Course = Btn_Direction_Up;
               return;
 
             } else {
               // Нам еще есть куда двигаться "вниз" - значит подвинемся
               VM_Working_Angle_Position = VM_Working_Angle_Position - 1;
 
               // Теперь надо сам монитор выставить на нужный угол
               Vertical_Motor.write(VM_Working_Angle_Position);
 
               // Сохраним угол наклона монитора в EEPROM
               EEPROM.write(VM_Working_Angle_Offset, VM_Working_Angle_Position); 
               EEPROM.write(VM_Temp_Angle_Offset, VM_Working_Angle_Position); 
 
             }
           } else {
 
   Serial.print("Direction = UP. Angle = ");
   Serial.print("\t  = \t");
   Serial.print(VM_Working_Angle_Position, DEC);
   Serial.println();
 
             // Теперь сохраним состояние системы в "не очень хорошем" состоянии
             VM_State = SM_Opening_State;
             // Сохраним положение монитора в EEPROM
             EEPROM.write(VM_State_Offset, VM_State); 
 
             //
             // Необходимо поднять монитор на один градус "вверх"
             //
 
             // Проверим на достижение "критического угла наклона"
             if (VM_Working_Angle_Position == VM_Max_Angle_Position) {
               // Угу. Встали в крайнюю позицию. Надо начинать движение "вниз".
               Btn_Adjust_Position_Course = Btn_Direction_Down;
               return;
 
             } else {
               // Нам еще есть куда двигаться "вверх" - значит подвинемся
               VM_Working_Angle_Position = VM_Working_Angle_Position + 1;
 
               // Теперь надо сам монитор выставить на нужный угол
               Vertical_Motor.write(VM_Working_Angle_Position);
 
               // Сохраним угол наклона монитора в EEPROM
               EEPROM.write(VM_Working_Angle_Offset, VM_Working_Angle_Position); 
               EEPROM.write(VM_Temp_Angle_Offset, VM_Working_Angle_Position); 
 
             }
           }
  
           // Сохраним угол наклона монитора в EEPROM
           EEPROM.write(VM_Working_Angle_Offset, VM_Working_Angle_Position); 
           EEPROM.write(VM_Temp_Angle_Offset, VM_Working_Angle_Position); 
 }
  
  
 void loop() 
 { 
   // Проверим режим работы вертикального привода
   if (VM_Working_Mode == 1) {
     // Режим поправки
     // Проверим на окончание времени действия режима поправки
     if (millis() - VM_Timer > 1000) {
       // Время вышло сменим режим и угол наклона
       VM_Working_Mode = 0;
 
       // Время закончилось. И нам надо сменить направление движения монитора
       if (Btn_Adjust_Position_Course == Btn_Direction_Up) {
         Btn_Adjust_Position_Course = Btn_Direction_Down;
       } else {
         Btn_Adjust_Position_Course = Btn_Direction_Up;
       }
     }
   }
 
 
 
 
   //
   // Проверим на нажатие контрольных кнопок
   //
 
   // Сначала проверим на одновременное нажатие двух кнопок.
   // Есть возможность одновременного нажатия двух кнопок - мы такое отсекаем.
   if (digitalRead(Btn_Open_Close_Pin) == Btn_Pressed && digitalRead(Btn_Adjust_Position_Pin) == Btn_Pressed) {
     // Нажаты одновременно две кнопки. Тупо запомним время их нажатия и ничего делать не будем
     Btn_Open_Close_Last_Time      = millis();
     Btn_Adjust_Position_Last_Time = millis();
   } else {
 
     //
     // Теперь проверим в каком состоянии находится система (открыта/закрыта)
     //
 
     if (HM_State == SM_Opened_State) {
       // Система находится в открытом состоянии. Значит можно сделать два действия
       // - закрыть монитор через кнопку Btn_Open_Close_Pin;
       // - изменить угол наклона монитора через кнопку Btn_Adjust_Position_Pin
 
       // Начнем проверять кнопки отдельно.
 
       //
       // Проверим текущее состояние кнопки Btn_Open_Close_Pin
       //
       Btn_Open_Close_State = digitalRead(Btn_Open_Close_Pin);
 
       // Проверим на нажатие кнопки и исключим "дребезг" кнопки
       if (Btn_Open_Close_State == Btn_Pressed && millis() - Btn_Open_Close_Last_Time > Btn_Open_Close_Debounce) {
         // Запомним время нажатия кнопки
         Btn_Open_Close_Last_Time = millis();
 
         // Начнем действия по закрытию всей системы. 
 
         // Отправим команду вертикальному серво-приводу на движение "Вниз"
         Start_Vertical_Motor(Servo_Close_Command);
        
         // Отправим команду горизонтальному серво-приводу на движение "Назад"
         Start_Horizontal_Motor(Servo_Close_Command, 10000);
 
         return;
       }
 
 
       //
       // Проверим текущее состояние кнопки Btn_Adjust_Position_Pin
       // Надо учитывать, что при отпускании кнопки должно переключаться 
       // направление наклона монитора. 
       // Т.е. как только мы поняли, что кнопку нажали - заходим в цикл
       // до отжатия кнопки и начинаем изменять угол монитора. Причем
       // если угол наклона достиг критической точки (0 или VM_Max_Position)
       // автоматически сменим направление!
       //
 
       //Проверим на нажатие и начнем цикл
       Btn_Adjust_Position_State = digitalRead(Btn_Adjust_Position_Pin);
 
       // Проверим на нажатие кнопки только для того, чтобы потом сменить направление движения
       if (Btn_Adjust_Position_State == Btn_Pressed && millis() - Btn_Adjust_Position_Last_Time > Btn_Adjust_Debounce) {
 
         // Подключим контакт управления серво-приводом вертикального перемещения
         Vertical_Motor.attach(VM_Pin);
 
 
         // Проверим режим работы вертикального привода
         if (VM_Working_Mode == 1) {
           // Режим поправки
 
   Serial.print(" VM_Mode ");
   Serial.print("\t  = \t");
   Serial.print(VM_Working_Mode, DEC);
   Serial.println();
 
           // Запомним время нажатия кнопки
           Btn_Adjust_Position_Last_Time = millis();
 
           // Время есть можно править угол
           VM_Move();
             
           // Начнем новый отсчет 3-х секунд
           VM_Timer = millis();
 
           // Сделаем задержку во избежание дребезга клавиш
           delay(Btn_Adjust_Debounce_Sleep);
 
         } else {
           // Режим кручения
 
   Serial.print(" VM_Mode ");
   Serial.print("\t  = \t");
   Serial.print(VM_Working_Mode, DEC);
   Serial.println();
 
           // Проверим на нажатие кнопки и исключим "дребезг" кнопки
           while (Btn_Adjust_Position_State == Btn_Pressed && millis() - Btn_Adjust_Position_Last_Time > Btn_Adjust_Debounce) {
 
             // Запомним время нажатия кнопки
             Btn_Adjust_Position_Last_Time = millis();
 
             // И так... кнопка нажата - значит надо наклонить монитор на 1 градус в заданном направлении
             VM_Move();
   
             // Сделаем задержку во избежание дребезга клавиш
             delay(Btn_Adjust_Debounce_Sleep);
 
             // Снова считаем состояние кнопки
             Btn_Adjust_Position_State = digitalRead(Btn_Adjust_Position_Pin);
           }
 
           // Цикл закончился. Значит кнопарь отпустили и нам надо дать задержку на 3 секунды для поправки угла монитора
 
           // Начнем отсчет 3-х секунд
           VM_Timer = millis();
           VM_Working_Mode = 1;
 
         }
 
         // Теперь сохраним состояние системы в "не очень хорошем" состоянии
         VM_State = SM_Opened_State;
         // Сохраним положение монитора в EEPROM
         EEPROM.write(VM_State_Offset, VM_State); 
 
         // Пересчитаем контрольную сумму в EEPROM
         EEPROM.write(Check_Sum_Offset, (HM_State * 256) + VM_State); 
 
 
 
         // Отключим контакт управления серво-приводом вертикального перемещения, чтобы не жужжала бестолку
         Vertical_Motor.detach();
 
         
       }
     } else {
       // Система находится в закрытом состоянии. Ее можно только открыть через кнопку Btn_Open_Close_Pin
 
       // Проверим текущее состояние кнопки Btn_Open_Close_Pin
       Btn_Open_Close_State = digitalRead(Btn_Open_Close_Pin);
 
       // Проверим на нажатие кнопки и исключим "дребезг" кнопки
       if (Btn_Open_Close_State == Btn_Pressed && millis() - Btn_Open_Close_Last_Time > Btn_Open_Close_Debounce) {
         // Запомним время нажатия кнопки
         Btn_Open_Close_Last_Time = millis();
 
         // Начнем действия по открытию всей системы. 
          // Подключим питание модуля MOSFET управления питанием планшета
         digitalWrite(Mosfet2, HIGH);
         // Отправим команду горизонтальному серво-приводу на движение "Вперед"
         if (Start_Horizontal_Motor(Servo_Open_Command, 10000)) 
         
         {
           // Отправим команду вертикальному серво-приводу на движение "Вверх"
           Start_Vertical_Motor(Servo_Open_Command);
         }
       }
     }
   }
 
   delay(100);
 
 } 
 
 
 bool Start_Horizontal_Motor(int HM_Direction, long MaxTimeOut)
 {
   int  Sensor_Pin;
   int  Sensor_ACC;
 
   // Теперь сохраним состояние системы
   if (HM_Direction == Servo_Close_Command) {
     // Теперь сохраним состояние системы в "хорошем" состоянии
     HM_State = SM_Closing_State;
     // Сохраним положение монитора в EEPROM
     EEPROM.write(HM_State_Offset, HM_State); 
     // Пересчитаем контрольную сумму в EEPROM
     EEPROM.write(Check_Sum_Offset, (HM_State * 256) + VM_State); 
 
     HM_State = SM_Closed_State;
   } else {
     // Теперь сохраним состояние системы в "хорошем" состоянии
     HM_State = SM_Opening_State;
     // Сохраним положение монитора в EEPROM
     EEPROM.write(HM_State_Offset, HM_State); 
     // Пересчитаем контрольную сумму в EEPROM
     EEPROM.write(Check_Sum_Offset, (HM_State * 256) + VM_State); 
 
     HM_State = SM_Opened_State;
   }
 
 
   // Выберем соответствующий контрольный датчик
   if (HM_Direction == Servo_Close_Command) {
     // Выберем ногу для контрольного датчика
     Sensor_Pin = Opt_Sensor_Bwd_Ctrl_Pin;
     Sensor_ACC = Opt_Sensor_Bwd_ACC_Pin;
   } else {
     // Выберем ногу для контрольного датчика
     Sensor_Pin = Opt_Sensor_Fwd_Ctrl_Pin;
     Sensor_ACC = Opt_Sensor_Fwd_ACC_Pin;
   }
   // Подадим питание на оптический датчик
   digitalWrite(Sensor_ACC, HIGH);
 
   // Задержка для сработки датчика, если стоим у края
   delay(15);
 
   // Проверим на наличие сигнала с оптического датчика
   if (digitalRead(Sensor_Pin) == HIGH) {
 
     // Снимем питание с оптического датчика
     digitalWrite(Sensor_ACC, LOW);
     return true;
   }
 
   // Теперь начнем горизонтальное движение серво-приводом
   Horizontal_Motor.write(HM_Direction);
  
   // Запомним время начала движения
   long StartTime = millis();
 
   // Начнем цикл ожидания сигнала от оптических датчиков или прервемся по таймауту
   while (millis() <= StartTime + MaxTimeOut) {
     // Проверим на наличие сигнала с оптического датчика
     if (digitalRead(Sensor_Pin) == HIGH) {
       // Сигнал пришел - тормознем серво-привод
       Horizontal_Motor.write(Servo_Stop_Command);
 
       // Теперь сохраним состояние системы в "хорошем" состоянии
       // Сохраним положение монитора в EEPROM
       EEPROM.write(HM_State_Offset, HM_State); 
       // Пересчитаем контрольную сумму в EEPROM
       EEPROM.write(Check_Sum_Offset, (HM_State * 256) + VM_State); 
 
       // Снимем питание с оптического датчика
       digitalWrite(Sensor_ACC, LOW);
 
       // Возвращаемся из функции с разрешением на дальнейшие действия
       return true;
     }
 
     // Подождем 15 миллисекунд
     delay(15);
   }
 
   // Тормознем серво-привод
   Horizontal_Motor.write(Servo_Stop_Command);
 
 
 
   // Снимем питание с оптического датчика
   digitalWrite(Sensor_ACC, LOW);
   return false;
 }
 
 
 
 void Start_Vertical_Motor(int VM_Direction)
 {
   int StartPos;
 
   // Теперь сохраним состояние системы
   if (VM_Direction == Servo_Close_Command) {
     // Теперь сохраним состояние системы в "хорошем" состоянии
     VM_State = SM_Closing_State;
 
     // Сохраним положение монитора в EEPROM
     EEPROM.write(VM_State_Offset, VM_State); 
     // Пересчитаем контрольную сумму в EEPROM
     EEPROM.write(Check_Sum_Offset, (HM_State * 256) + VM_State); 
 
     VM_State = SM_Closed_State;
   } else {
     // Теперь сохраним состояние системы в "хорошем" состоянии
     VM_State = SM_Opening_State;
 
     // Сохраним положение монитора в EEPROM
     EEPROM.write(VM_State_Offset, VM_State); 
     // Пересчитаем контрольную сумму в EEPROM
     EEPROM.write(Check_Sum_Offset, (HM_State * 256) + VM_State); 
 
     VM_State = SM_Opened_State;
   }
 
   // Подключим контакт управления серво-приводом вертикального перемещения
   Vertical_Motor.attach(VM_Pin);
 
   delay(25);
 
  
 
   Serial.print("Start_Vertical_Motor(");
   if (VM_Direction == Servo_Close_Command) {
     Serial.print("Servo_Close_Command)");
   } else {
     Serial.print("Servo_Open_Command)");
   }
   Serial.println();
 
   Serial.print("VM_Working_Angle_Position\t  = \t");
   Serial.print(VM_Working_Angle_Position, DEC);
   Serial.println();
 
 
   // Проверим в каком направлении нам необходимо двигаться
   if (VM_Direction == Servo_Close_Command)
   {
     // Проверка для избежания дерганья сервы
     if (VM_Working_Angle_Position != 0 ) {
 
     // Включим диагностический светодиод
     //digitalWrite(Led_Pin, HIGH);
 
       Serial.print("Close_Down!\t  = \t");
       Serial.print(VM_Working_Angle_Position, DEC);
       Serial.println();
 
       for (StartPos = VM_Working_Angle_Position; StartPos > 0; StartPos -= 3) {
         Vertical_Motor.write(StartPos);
         delay(15);
 
         Serial.print("CurrentPos\t  = \t");
         Serial.print(StartPos, DEC);
         Serial.println();
 
         // Сохраним угол наклона монитора в EEPROM
         EEPROM.write(VM_Temp_Angle_Offset, StartPos); 
       }
     }
 
     Vertical_Motor.write(0);
     delay(15);
     
     // Отключим питание модуля MOSFET управления питанием планшета
         digitalWrite(Mosfet2, LOW);
         
     // Сохраним угол наклона монитора в EEPROM
     EEPROM.write(VM_Temp_Angle_Offset, 0); 
 
   } else {
     delay(15);
 
     // Проверка для избежания дерганья сервы
     Serial.print("Open_Up\t  = \t");
     Serial.print(VM_Working_Angle_Position, DEC);
     Serial.println();
 
     if (VM_Working_Angle_Position != 0 ) {
       for (StartPos = 1; StartPos < VM_Working_Angle_Position; StartPos += 3) {
         Vertical_Motor.write(StartPos);
         delay(15);
 
         Serial.print("CurrentPos\t  = \t");
         Serial.print(StartPos, DEC);
         Serial.println();
 
         // Сохраним угол наклона монитора в EEPROM
         EEPROM.write(VM_Temp_Angle_Offset, StartPos); 
       }
     }
 
     Vertical_Motor.write(VM_Working_Angle_Position);
     delay(15);
   
     // Сохраним угол наклона монитора в EEPROM
     EEPROM.write(VM_Temp_Angle_Offset, VM_Working_Angle_Position); 
   }
 
   // Отключим контакт управления серво-приводом вертикального перемещения, чтобы не жужжала бестолку
   Vertical_Motor.detach();
 
 
 
   // Теперь сохраним состояние системы в "хорошем" состоянии
   // Сохраним положение монитора в EEPROM
   EEPROM.write(VM_State_Offset, VM_State); 
 
   // Пересчитаем контрольную сумму в EEPROM
   EEPROM.write(Check_Sum_Offset, (HM_State * 256) + VM_State); 
 } 
 
		 
		
		 
	 
 На мой взгляд-нормальная программа. Все работает, все шевелится...  
	 |