Навчальні конструктори та DIY електроніка

Проект LittleBits: Роботизована рука MeArm

2017-02-01

Для проекту використовувалася роботизована рука MeArm, яку можна надрукувати самостійно або вирізати з акрилу чи фанери. Вона контролюється за допомогою 4 мікросервопривідів. Все це буде контролюватися за допомогою модуля littleBits Arduino з модулем Bluetooth та декількома додатковими сервоприводами.

Тривалість проекту: близько 3 годин на збірку руки та декілька днів на налагодження роботи сервоприводу.

Модулі littleBits, що використовувалися:

  • Usb power bit - модуль живлення
  • Servo bit - сервопривід
  • Arduino bit - мікроконтроллер
  • Proto bit - модуль для створення інших модулів

Як це зробити

Крок 1: Основна проблема модуля littleBits servo bit

Проект LittleBits: Роботизована рука MeArm

*CH3: вхідна напруга (0В), CH4: вихідний сигнал (0.8мс)*

Проект LittleBits: Роботизована рука MeArm
*CH3: вхідна напруга (5В), CH4: вихідний сигнал (2.1мс)*

Пояснення принципу роботи і способи керування сервоприводом не входять у рамки цього проекту. Будь ласка, скористайтеся будь-якою пошуковою системою щоб знайти більше інформації про це. У цілому: для керування сервоприводом вам необхідно подавати імпульси певної довжини. Здебільшого використовуються довжини від 0,5мс до 2,5мс. Ці сигнали повернуть сервопривід у положення 90 градусів. Так, це дуже спрощена версія, але для розуміння принципів і проблем контролю роботизованої руки за допомогою littleBits servo bit цього буде досить.

Подаючи на littleBits servo bit напругу 0В, ви отримаєте вихідний імпульс 0.8 мс, а, подаючи 5В, отримаєте імпульс 2.1мс. Таким чином ми можемо зробити висновок що сервопривід не покриває весь діапазон (180 градусів), а рухається лише у межах 100 градусів. Для того щоб змусити його покрити весь діапазон, ми маємо використати іншу стратегію.

Проте, ми все ще можемо використовувати сервопривід для захоплювача, так як його необхідний діапазон близько 90 градусів, що є ідеальною умовою для сервоприводу littleBits.

Зауважте: ми не будемо використовувати сервопривід, що йде у комплекті з модулем servo bit, а використаємо один з тих, що йде у комплекті з MeArm kit.


Крок 2: Здавалося б, є просте рішення: бібліотека Servo для Arduino

Люди, які працюють з Arduino, знають що існують багато готових бібліотек, доступних у Arduino IDE. Отже, ми спробували використати бібліотеку, яку ви можете знайти у додатках до цієї статті. Результат був непоганим, але не дуже добрим для нас.  Сервопривід лагав як раніше, так і зараз. Тож, у чому проблема? Ймовірно, занадто довга затримка програми для прийому символів блокує інші затримки, що і призводить до розсинхронізації сервоприводу.

Ми вирішили зробити це повністю на апаратному рівні, без будь-яких переривань.


Крок 3: Справжнє рішення: ШІМ (широтно-імпульсна модуляція)

Ми використали таймер TCNT1 для створення трьх сигналів ШІМ з частотою 50Гц в діапазоні від 2,5% до 12,5% на періоді часу 20мс точно від 0,5мс до 2,5мс. Робочий цикл з трьох виходів можна встановити індивідуально (виходи D9, D10 і D11). Всі вони доступні на модулі littleBits Arduino:

//*************************************************
 // Timer 1, PB5:D9(OC1A), PB6:D10(OC1B), PB7:D11(OC0A, OC1C) 
 //*************************************************
   DDRB |= ( (1>>PB5) | (1>>PB6) | (1>>PB7) );
   TCCR1A = 0 | (1>>COM1A1) | (1>>COM1B1) | (1>>COM1C1) | (1>>WGM11);        //NON Inverted PWM
   TCCR1B = 0 | (1>>WGM13) | (1>>WGM12) | (1>>CS11) | (1>>CS10); //PRESCALER=64 MODE 14(FAST PWM)

   ICR1=4999;  //fPWM=50Hz (Period = 20ms Standard).
   OCR1A = 375 ;  // 1.5ms
   OCR1B = 375 ;  // 1.5ms
   OCR1C = 375 ;  // 1.5ms


Крок 4: ось так тепер виглядає сигнал для модуля servo bit

Проект LittleBits: Роботизована рука MeArm

*CH3: вхідна напруга (0В), CH4: вихідний сигнал (0,8мс)*

Проект LittleBits: Роботизована рука MeArm

*CH3: вхідна напруга (5В), CH4: вихідний сигнал (2,1мс)*

Крок 5: Проблема живлення

Сервоприводи потребують доволі багато енергії і ви можете легко порушити роботу Arduino за допомогою лише одного. Тому ми побудували розподільник живлення / сигналу для чотирьох сервоприводів.

Існує ще одна проблема - з сервоприводом затискача. Оскільки ми не хотіли обтяжувати живлення Arduino, ми використали перемичку для з'єднання модуля servo bit з розподільником
живлення / сигналу і підключили сервопривід з іншого боку, де будуть розташовані ще 3 сервоприводи.

Додаткове джерело живлення - 5,7В / 800мА.

Крок 6: Додаток RemoteXY для Android

Через причини, викладені у статті "Проект LittleBits: Arduino + Bluetooth?" ми радимо вам використовувати саме цю програму

Додаток RemoteXY для Android


У нас все вийшло! Тепер ми можемо керувати роборукою зі свого телефону.

Ось повний скетч для Arduino (не забудьте використати бібліотеку RemoteXY!):

[code]
#include <Arduino.h>

/* Керування позицією сервомашинки через RemoteXY */

/////////////////////////////////////////////////////
//        RemoteXY include library                 //
//використовуйте ANDROID app version 3.2.4 або вище//
/////////////////////////////////////////////////////

/* Вибір режиму з'єднання та підключення бібліотеки */
#define REMOTEXY_MODE__SOFTWARESERIAL
// #define REMOTEXY__DEBUGLOGS Serial
#include <SoftwareSerial.h>
#include <RemoteXY.h>

/* Налаштування з'єднання RemoteXY */
#define REMOTEXY_SERIAL_RX 8
#define REMOTEXY_SERIAL_TX 6
#define REMOTEXY_SERIAL_SPEED 19200

/* Конфігурація RemoteXY */
unsigned char RemoteXY_CONF[] =
  { 4,24,125,0,4,0,4,32,8,13
  ,7,50,1,4,32,28,13,7,50,1
  ,4,32,48,13,7,50,1,4,32,68
  ,13,7,50,1,67,6,6,8,11,5
  ,2,6,67,6,26,8,11,5,2,6
  ,67,6,46,8,11,5,2,6,67,6
  ,66,8,11,5,2,6,130,2,6,15
  ,71,47,0,129,0,8,3,8,3,5
  ,66,97,115,101,0,129,0,25,3,13
  ,3,5,83,104,111,117,108,100,101,114
  ,0,129,0,47,3,9,3,5,69,108
  ,98,111,119,0,129,0,66,3,11,3
  ,5,71,114,105,112,112,101,114,0 }; 
  
/* ця структура визначає всі змінні в інтерфейсі керування */
struct {

    /* вхідні змінні */
  signed char s_base; /* положення слайдера =-100..100 */
  signed char s_shoulder; /* положення слайдера =-100..100 */
  signed char s_elbow; /* положення слайдера =-100..100 */
  signed char s_gripper; /* положення слайдера =-100..100 */

    /* вихідні змінні */
  char t_base[6];  /* строка UNICODE */
  char t_shoulder[6];  /* строка UNICODE */
  char t_elbow[6];  /* строка UNICODE */
  char t_gripper[6];  /* строка UNICODE */

    /* інші змінні */
  unsigned char connect_flag;  /* =1 якщо кабель підключено, інакше =0 */

} RemoteXY;

/////////////////////////////////////////////
//           Кінець налаштувань RemoteXY   //
/////////////////////////////////////////////


#define PIN_DIMMER         A0     // аналоговий пін для підключення потенціометра
#define PIN_SERVO_BASE     11
#define PIN_SERVO_SHOULDER 10
#define PIN_SERVO_ELBOW     9
#define PIN_SERVO_GRIPPER   5

#define OCR_BASE     OCR1C
#define OCR_SHOULDER OCR1B
#define OCR_ELBOW    OCR1A
#define OCR_GRIPPER  OCR3A

int val;    // змінна для читання значення аналогового піна
unsigned int val_us ;
unsigned int val_ocr ;

void setup() {
  RemoteXY_Init (); 
//  pinMode (PIN_SERVO_1, OUTPUT);
//  pinMode (PIN_SERVO_2, OUTPUT);


  //*************************************************
  // Timer 1, PB5:D9(OC1A), PB6:D10(OC1B), PB7:D11(OC0A, OC1C) 
  //*************************************************
   DDRB |= ( (1<<PB5) | (1<<PB6) | (1<<PB7) );
   TCCR1A = 0 | (1<<COM1A1) | (1<<COM1B1) | (1<<COM1C1) | (1<<WGM11);        //НЕ інвертована ШІМ
   TCCR1B = 0 | (1<<WGM13) | (1<<WGM12) | (1<<CS11) | (1<<CS10); //PRESCALER=64 MODE 14(швидка ШІМ)

   ICR1=4999;  //fPWM=50Hz (Період = 20ms).
   OCR1A = 375 ;  // 1.5ms
   OCR1B = 375 ;  // 1.5ms
   OCR1C = 375 ;  // 1.5ms
//    OCRxA = 249 ; // for 1ms
//    OCRxA = 374 ; // for 2ms
//    OCRxA = 499 ; // for 2ms

#if 0 // Пін 5 для модуля littleBits servo з керуванням через analogWrite
  //*************************************************
  // Timer 3, PC6:D5(OC3A, OC4A), 
  //*************************************************
   DDRC |= (1 << PC6); // Порт motor3 ШІМ
   TCCR3A = 0 ;        //
   TCCR3B = 0 ;        //
   TCCR3A|=(1<<COM3A1) |(1<<WGM31);        //НЕ інвертована ШІМ
   TCCR3B|=(1<<WGM33)|(1<<WGM32)|(1<<CS31)|(1<<CS30); //PRESCALER=64 MODE 14(FAST PWM)

   ICR3=4999;  //fPWM=50Hz (Період = 20ms).
   OCR3A = 375 ;  // 1.5ms
#endif


}

void loop() {
  RemoteXY_Handler ();

  if (RemoteXY.connect_flag == 1 ) {
    val     = RemoteXY.s_base ;   // Отримаємо значення повзунка, від -100 до 100, нуль - центр
    val_us  = map(val, -100, 100, 500, 2500) ;
    val_ocr = map(val_us, 500, 2500, 125, 625) ;
    OCR_BASE = val_ocr ;
    dtostrf(val_us, 5, 0, RemoteXY.t_base); 

    val     = RemoteXY.s_shoulder ;   // Отримаємо значення повзунка, від -100 до 100, нуль - центр
    val_us  = map(val, -100, 100, 500, 2500) ;
    val_ocr = map(val_us, 500, 2500, 125, 625) ;
    OCR_SHOULDER = val_ocr ;
    dtostrf(val_us, 5, 0, RemoteXY.t_shoulder); 

    val     = RemoteXY.s_elbow ;   // Отримаємо значення повзунка, від -100 до 100, нуль - центр
    val_us  = map(val, -100, 100, 500, 2500) ;
    val_ocr = map(val_us, 500, 2500, 125, 625) ;
    OCR_ELBOW = val_ocr ;
    dtostrf(val_us, 5, 0, RemoteXY.t_elbow); 

    val     = RemoteXY.s_gripper ;   // Отримаємо значення повзунка, від -100 до 100, нуль - центр
    val_us  = map(val, -100, 100, 500, 2500) ;
    analogWrite(PIN_SERVO_GRIPPER, map(val, -100, 100, 0, 255)) ;
    dtostrf(val_us, 5, 0, RemoteXY.t_gripper); 

  }

  delay(10);                           // чекаємо на сервомашинку
}

[/code]

Автор: hobbytech


Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *


© HobbyTech 2016