PCCar.ru - Ваш автомобильный компьютер

PCCar.ru - Ваш автомобильный компьютер (http://pccar.ru/index.php)
-   Сделай сам (http://pccar.ru/forumdisplay.php?f=17)
-   -   Система перемещения монитора (http://pccar.ru/showthread.php?t=22812)

skanch 15.02.2015 21:54

Вложений: 8
Продолжаем сборку. Вчера получил шестерни.
Вал на серве диаметром 6 мм , а посадочный диаметр шестерни 5 мм- рассверлил до нужного размера и посадил на супер клей, о котором упоминал выше. Сегодня обрезал лишнее и смонтировал на каретку.
Серву установил через штатные резиновые втулки. Причем верхние крепления еще и с металлическими гильзами, которые шли в комплекте с сервомотором. На нижние ставить их не стал- серва стала с небольшим наклоном в сторону зубчатой рейки. Это создает нужный прижим.
Вчера окончательно подогнал и собрал крышку для монитора-планшета (новая ось,опорный подшипник). Намертво приклеил саму крышку к оси-теперь узел этот не разборный. Осталось сделать замки крепления планшета, лицевую панель и все отдать в покраску.
Смонтировал электрическую часть. Собрал по временной схеме питание сервомоторов, чтобы посмотреть в работе. Вот ролик работы механизма.
http://www.pccar.ru/attachment.php?a...1&d=1424030475

skanch 16.02.2015 22:33

Цитата:

Сообщение от anton2204 (Сообщение 320863)
Красиво!Серьезный подход!
P.S. Не доверяю я этим моментальным клеям–отвалятся со временем. Эпоксидка еще куда ни шло...Штифт лучше/надежнее!:)

На фото видно, что и винт прижимной присутствует, и супер клей-это EPOXY metal, проверенный в работе.

skanch 19.02.2015 22:15

Вложений: 6
Чтобы сервомоторы не дергались в момент подачи питания, а такое встречается очень часто и мой случай не исключение, использовал готовый IRF520 MOSFET-модуль для Arduino. Немного его подправил для экономии места. Управление модулем через ШИМ. Плавное включение питания полностью решило проблему "дергания" сервоприводов. Обязательное условие- плавно включать нужно то питание, которое идет после DC-DC преобразователя. Мои сервы питаются 6,5 V.

skanch 21.02.2015 00:50

Вложений: 7
Делаем кабель-канал для прокладки проводов от электрооборудования, установленного на каретке (сервы, модуль MOSFET, DC-DC преобразователь, а также для вывода с планшета необходимых проводов). Для этой цели я использую гибкую пружину-трубогиб с наружным диаметром 12 мм. Больший диаметр менее гибок. Пружина имеет антикоррозийное покрытие.
Один конец пружины крепим на каркасе с линейными направляющими, второй на самой каретке.
Провода внутри пружины нужно скрутить в сторону изгиба кабель-канала, для того, чтобы создать дополнительную разгрузку жгута при изгибании пружины и максимально исключить продольное движение проводов внутри. Когда все соберу-будет выглядеть примерно так.

skanch 01.03.2015 16:05

Вложений: 5
Цитата:

Сообщение от жека 3 (Сообщение 321972)
Как, окончательный результат не созрел?

Все в процессе... Доделываю... Сделал крепеж для планшета, переднюю рамку с крышкой. Сейчас делаю привод управления этой самой крышкой. Хочу сделать чисто механический-без двигателей, на рычагах. Работа идет. Скоро отдам в покраску детали, а после и сборка готового изделия...

skanch 15.03.2015 14:16

Вложений: 18
Готовый вариант системы.

skanch 15.03.2015 14:21

Здесь небольшое видео:
https://youtu.be/97YyrZYBzcA

skanch 06.04.2015 16:30

Цитата:

Сообщение от 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 value <= 255value+=5// напряжение постепенно увеличивается (от 0V до 5V)
  

    
analogWrite(Mosfet1value);           
    
delay(5);  // ждём 5 миллисекунд (время подбираем опытным путем)
     // Сконфигурируем контакт питания модуля MOSFET управления питанием планшета
   
pinMode(Mosfet2OUTPUT);
  }  
  
  
  
// Отладка 
  
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_PinINPUT);

  
// Сконфигурируем контакт кнопки управления настройкой вертикальной позиции монитора как "Вход" и подключим к контакту внутренний резистор
  
pinMode(Btn_Adjust_Position_PinINPUT);


  
// Сконфигурируем контакт диагностического светодиода как "Выход" (будем зажигать/гасить)
  //pinMode(Led_Pin, OUTPUT);

  // Подключим контакт управления серво-приводом горизонтального перемещения
  
Horizontal_Motor.attach(HM_Pin);

  
// Остановим и удержим серво-привод горизонтального перемещения в положении "Стоп"
  
Horizontal_Motor.write(Servo_Stop_Command);


 



  
// Инициализируем оптические датчики
  
pinMode(Opt_Sensor_Fwd_Ctrl_PinINPUT);
  
pinMode(Opt_Sensor_Fwd_ACC_Pin,  OUTPUT);

  
pinMode(Opt_Sensor_Bwd_Ctrl_PinINPUT);
  
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_OffsetVM_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_PositionDEC);
  
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_OffsetVM_Temp_Angle_Position); 

  
// Считаем реальное рабочее положение монитора
  
VM_Working_Angle_Position EEPROM.read(VM_Working_Angle_Offset); 

  
// Сохраним вертикальное положение монитора в EEPROM
  
VM_State SM_Closed_State;
  
EEPROM.write(VM_State_OffsetSM_Closed_State); 

  
// Затем затянем его обратно
  
Start_Horizontal_Motor(Servo_Close_Command10000);

  
// Теперь сохраним состояние системы в "хорошем" состоянии
  
HM_State SM_Closed_State;

  
// Сохраним положение монитора в EEPROM
  
EEPROM.write(HM_State_OffsetHM_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_PositionDEC);
  
Serial.println();

            
// Теперь сохраним состояние системы в "не очень хорошем" состоянии
            
VM_State SM_Closing_State;
            
// Сохраним положение монитора в EEPROM
            
EEPROM.write(VM_State_OffsetVM_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_OffsetVM_Working_Angle_Position); 
              
EEPROM.write(VM_Temp_Angle_OffsetVM_Working_Angle_Position); 

            }
          } else {

  
Serial.print("Direction = UP. Angle = ");
  
Serial.print("\t  = \t");
  
Serial.print(VM_Working_Angle_PositionDEC);
  
Serial.println();

            
// Теперь сохраним состояние системы в "не очень хорошем" состоянии
            
VM_State SM_Opening_State;
            
// Сохраним положение монитора в EEPROM
            
EEPROM.write(VM_State_OffsetVM_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_OffsetVM_Working_Angle_Position); 
              
EEPROM.write(VM_Temp_Angle_OffsetVM_Working_Angle_Position); 

            }
          }
 
          
// Сохраним угол наклона монитора в EEPROM
          
EEPROM.write(VM_Working_Angle_OffsetVM_Working_Angle_Position); 
          
EEPROM.write(VM_Temp_Angle_OffsetVM_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_Command10000);

        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_ModeDEC);
  
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_ModeDEC);
  
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_OffsetVM_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(Mosfet2HIGH);
        
// Отправим команду горизонтальному серво-приводу на движение "Вперед"
        
if (Start_Horizontal_Motor(Servo_Open_Command10000)) 
        
        {
          
// Отправим команду вертикальному серво-приводу на движение "Вверх"
          
Start_Vertical_Motor(Servo_Open_Command);
        }
      }
    }
  }

  
delay(100);




bool Start_Horizontal_Motor(int HM_Directionlong MaxTimeOut)
{
  
int  Sensor_Pin;
  
int  Sensor_ACC;

  
// Теперь сохраним состояние системы
  
if (HM_Direction == Servo_Close_Command) {
    
// Теперь сохраним состояние системы в "хорошем" состоянии
    
HM_State SM_Closing_State;
    
// Сохраним положение монитора в EEPROM
    
EEPROM.write(HM_State_OffsetHM_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_OffsetHM_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_ACCHIGH);

  
// Задержка для сработки датчика, если стоим у края
  
delay(15);

  
// Проверим на наличие сигнала с оптического датчика
  
if (digitalRead(Sensor_Pin) == HIGH) {

    
// Снимем питание с оптического датчика
    
digitalWrite(Sensor_ACCLOW);
    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_OffsetHM_State); 
      
// Пересчитаем контрольную сумму в EEPROM
      
EEPROM.write(Check_Sum_Offset, (HM_State 256) + VM_State); 

      
// Снимем питание с оптического датчика
      
digitalWrite(Sensor_ACCLOW);

      
// Возвращаемся из функции с разрешением на дальнейшие действия
      
return true;
    }

    
// Подождем 15 миллисекунд
    
delay(15);
  }

  
// Тормознем серво-привод
  
Horizontal_Motor.write(Servo_Stop_Command);



  
// Снимем питание с оптического датчика
  
digitalWrite(Sensor_ACCLOW);
  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_OffsetVM_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_OffsetVM_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_PositionDEC);
  
Serial.println();


  
// Проверим в каком направлении нам необходимо двигаться
  
if (VM_Direction == Servo_Close_Command)
  {
    
// Проверка для избежания дерганья сервы
    
if (VM_Working_Angle_Position != ) {

    
// Включим диагностический светодиод
    //digitalWrite(Led_Pin, HIGH);

      
Serial.print("Close_Down!\t  = \t");
      
Serial.print(VM_Working_Angle_PositionDEC);
      
Serial.println();

      for (
StartPos VM_Working_Angle_PositionStartPos 0StartPos -= 3) {
        
Vertical_Motor.write(StartPos);
        
delay(15);

        
Serial.print("CurrentPos\t  = \t");
        
Serial.print(StartPosDEC);
        
Serial.println();

        
// Сохраним угол наклона монитора в EEPROM
        
EEPROM.write(VM_Temp_Angle_OffsetStartPos); 
      }
    }

    
Vertical_Motor.write(0);
    
delay(15);
    
    
// Отключим питание модуля MOSFET управления питанием планшета
        
digitalWrite(Mosfet2LOW);
        
    
// Сохраним угол наклона монитора в EEPROM
    
EEPROM.write(VM_Temp_Angle_Offset0); 

  } else {
    
delay(15);

    
// Проверка для избежания дерганья сервы
    
Serial.print("Open_Up\t  = \t");
    
Serial.print(VM_Working_Angle_PositionDEC);
    
Serial.println();

    if (
VM_Working_Angle_Position != ) {
      for (
StartPos 1StartPos VM_Working_Angle_PositionStartPos += 3) {
        
Vertical_Motor.write(StartPos);
        
delay(15);

        
Serial.print("CurrentPos\t  = \t");
        
Serial.print(StartPosDEC);
        
Serial.println();

        
// Сохраним угол наклона монитора в EEPROM
        
EEPROM.write(VM_Temp_Angle_OffsetStartPos); 
      }
    }

    
Vertical_Motor.write(VM_Working_Angle_Position);
    
delay(15);
  
    
// Сохраним угол наклона монитора в EEPROM
    
EEPROM.write(VM_Temp_Angle_OffsetVM_Working_Angle_Position); 
  }

  
// Отключим контакт управления серво-приводом вертикального перемещения, чтобы не жужжала бестолку
  
Vertical_Motor.detach();



  
// Теперь сохраним состояние системы в "хорошем" состоянии
  // Сохраним положение монитора в EEPROM
  
EEPROM.write(VM_State_OffsetVM_State); 

  
// Пересчитаем контрольную сумму в EEPROM
  
EEPROM.write(Check_Sum_Offset, (HM_State 256) + VM_State); 


На мой взгляд-нормальная программа. Все работает, все шевелится...

skanch 11.10.2015 13:04

Вложений: 13
Вариант крепления планшета для системы перемещения. Возможно кому-нибудь будет интересно.
Требования к конструкции:съемный планшет (в данном случае Samsung Galaxy Tab S2),постоянная подзарядка планшета.
Реализовано с применением комплекта беспроводной подзарядки, чехла для планшета, магнитов от держателя в авто.
Конструкция "подиума" для планшета практически ничем не отличается от описанного выше. За исключением крепления самого планшета.
Вот фото такой конструкции.
В алюминиевой площадке просверлены отверстия под диаметр магнитов, которые приклеены на тыльной стороне пластикового "чехла" для планшета. Сзади к алюминиевой площадке приклеены полоски жести толщиной 0.8мм. К ним и "цепляются" магниты. Все держится хорошо и при надобности планшет вместе с "чехлом" можно легко снять.

skanch 09.12.2015 22:45

Вложений: 16
Еще одна подобная система.


Часовой пояс GMT +4, время: 13:37.

Работает на vBulletin® версия 3.8.4.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot