Tri servomotory robota Kitronik :MOVE mini MK2

Zdravím nadšencov robotiky a programovania, ktorých zaujal robot Kitronik :MOVE mini MK2 riadený výučbovým mikropočítačom micro:bit. Tento robot som podrobne predstavil v mojich dvoch predošlých článkoch, pričom teraz sa zameriam na jeho príslušenstvo s názvom rameno BullDozer V2 a nárazník Bumper V2. Ako z názvov príslušenstva vyplýva, jedná sa o ich druhé verzie, pretože aj spomenutý robot je tiež druhou verziou. Nemusíte si však z toho robiť ťažkú hlavu, lebo mám potvrdené od výrobcu, že aj prvé verzie príslušenstva sú použiteľné. Uvedený robot má dokonca už spravený otvor pre osadenie tretieho servomotora ramena BullDozer, ktoré vám opíšem v nasledujúcich riadkoch.

Rameno BullDozer

Rameno BullDozer V2 tvorí 180-stupňový analógový servomotor a plastové diely, ktoré sa navzájom prichytia kovovými skrutkami s maticami. V balení je aj návod, ako toto príslušenstvo správne namontovať. Ja som však servomotor umiestnil na druhú stranu, aby neprichádzal do kontaktu s jumpermi prídavných RGB LED diód. Na spojazdnenie spomenutého ramena výrobca spravil prípravu na doske Servo:Lite board na pripojenie tretieho servomotora a navrhol postup, ktorým vlastne dôjde k odpojeniu 5 LED diód tejto dosky na úkor pripojenia 180-stupňového servomotora.

Tento spôsob sa mi javil ako nepraktický, tak som vynašiel ‚hack‘, ktorý ponechal 5 RGB LED diód dosky Servo:Lite board a aj prídavné RGB LED diódy funkčné. Avšak sa tým znefunkčnil displej mikropočítača micro:bit, ktorý musel zostať vypnutý. Stačilo len pripevniť rozhranie :MOVE Sensor Interface (určené pre snímač čiary a vzdialenosti) na uvedený mikropočítač priskrutkovaním k doske Servo:Lite board. Následne bolo možné napojiť tretí servomotor na spomenuté rozhranie a ovládať ho pomocou signálu z pinu P3. Týmto sa mi podarilo uviesť do prevádzky spomínané rameno a zachovať pritom funkčnosť RGB LED diód.

Dostal som sa tak k otázke ako skĺbiť ovládanie ramena, RGB LED diód a pohybu robota. Napadla ma neštandardná myšlienka, pokúsiť sa nato využiť infračervený (skratka IR) diaľkový ovládač s prijímačom HX1838, ktorý je cenovo nenáročný v porovnaní s joystickom. Treba pripomenúť, že tento diaľkový ovládač je napájaný batériou CR 2025, ktorá nie je súčasťou balenia.

Na pripojenie IR prijímača som využil rozhranie :MOVE Sensor Interface, pričom signál prechádzal pinom P8 mikropočítača. Pre lepšiu prehľadnosť uvádzam ‚layout‘ zapojených pinov:

  • P0 – 5 RGB LED diód dosky Servo:Lite board a prídavné RGB LED diódy 8 RGB LED Ring
  • P1 – kontinuálny servomotor
  • P2 – kontinuálny servomotor
  • P3 – 180-stupňový servomotor ramena
  • P8 – IR prijímač HX1838

Následne som mohol začať programovať v platforme Microsoft MakeCode, pričom som použil okrem štandardných aj rozširujúce Bloky Servo:Lite, Neopixel a Osoyoo_IR.

Najväčší problém som mal s nájdením rozširujúceho bloku, ktorý by disponoval knižnicou príkazov kompatibilnou so spomínaným diaľkovým ovládačom. Po celodňovom bádaní som sa nakoniec dopracoval k bloku Osoyoo_IR, ktorý bol len čiastočne kompatibilný. To znamená, že názvy príkazov uvedeného bloku nezodpovedali názvom tlačidiel na ovládači. Avšak stačilo mi len zistiť, ktoré tlačidlo spúšťa ktorý príkaz a k vytvoreniu finálnej verzie programu mi už nič nestálo v ceste:

Program JavaScript

OSOYOO_IR.onPressEvent(RemoteButton.CH_MINUS, function () {
    Pixel_Array.showColor(neopixel.colors(NeoPixelColors.Red))
})
OSOYOO_IR.onPressEvent(RemoteButton.CH, function () {
    Pixel_Array.showColor(neopixel.colors(NeoPixelColors.Green))
})
OSOYOO_IR.onPressEvent(RemoteButton.CH_Add, function () {
    Pixel_Array.showColor(neopixel.colors(NeoPixelColors.Blue))
})
OSOYOO_IR.onPressEvent(RemoteButton.PREV, function () {
    Pixel_Array.showColor(neopixel.colors(NeoPixelColors.White))
})
OSOYOO_IR.onPressEvent(RemoteButton.NEXT, function () {
    Pixel_Array.showRainbow(1, 360)
})
OSOYOO_IR.onPressEvent(RemoteButton.PLAY, function () {
    Pixel_Array.clear()
    Pixel_Array.show()
})
OSOYOO_IR.onPressEvent(RemoteButton.Add, function () {
    if (0 > move) {
        move = 0
    } else {
        move += -36
        pins.servoWritePin(AnalogPin.P3, move)
        Pixel_Array.clear()
        Pixel_Array.setPixelColor(8, neopixel.colors(NeoPixelColors.Blue))
        Pixel_Array.setPixelColor(9, neopixel.colors(NeoPixelColors.Blue))
        Pixel_Array.setPixelColor(10, neopixel.colors(NeoPixelColors.Blue))
        Pixel_Array.show()
    }
    move = move
    basic.pause(200)
    Pixel_Array.clear()
    Pixel_Array.show()
})
OSOYOO_IR.onPressEvent(RemoteButton.Minus, function () {
    for (let index = 0; index < 13; index++) {
        Pixel_Array.rotate(1)
        Pixel_Array.show()
        basic.pause(200)
    }
})
OSOYOO_IR.onPressEvent(RemoteButton.EQ, function () {
    move = 0
    pins.servoWritePin(AnalogPin.P3, move)
    Pixel_Array.clear()
    Pixel_Array.setPixelColor(8, neopixel.colors(NeoPixelColors.Blue))
    Pixel_Array.setPixelColor(9, neopixel.colors(NeoPixelColors.Blue))
    Pixel_Array.setPixelColor(10, neopixel.colors(NeoPixelColors.Blue))
    Pixel_Array.show()
    basic.pause(500)
    Pixel_Array.clear()
    Pixel_Array.show()
})
OSOYOO_IR.onPressEvent(RemoteButton.NUM_100, function () {
    if (move > 180) {
        move = 180
    } else {
        move += 36
        pins.servoWritePin(AnalogPin.P3, move)
        Pixel_Array.clear()
        Pixel_Array.setPixelColor(5, neopixel.colors(NeoPixelColors.Blue))
        Pixel_Array.setPixelColor(6, neopixel.colors(NeoPixelColors.Blue))
        Pixel_Array.setPixelColor(12, neopixel.colors(NeoPixelColors.Blue))
        Pixel_Array.show()
    }
    move = move
    basic.pause(200)
    Pixel_Array.clear()
    Pixel_Array.show()
})
OSOYOO_IR.onPressEvent(RemoteButton.NUM0, function () {
    for (let index = 0; index < 13; index++) {
        Pixel_Array.shift(1)
        Pixel_Array.show()
        basic.pause(200)
    }
})
OSOYOO_IR.onPressEvent(RemoteButton.NUM_200, function () {
    move = 180
    pins.servoWritePin(AnalogPin.P3, move)
    Pixel_Array.clear()
    Pixel_Array.setPixelColor(5, neopixel.colors(NeoPixelColors.Blue))
    Pixel_Array.setPixelColor(6, neopixel.colors(NeoPixelColors.Blue))
    Pixel_Array.setPixelColor(12, neopixel.colors(NeoPixelColors.Blue))
    Pixel_Array.show()
    basic.pause(500)
    Pixel_Array.clear()
    Pixel_Array.show()
})
OSOYOO_IR.onPressEvent(RemoteButton.NUM2, function () {
    kitronik_servo_lite.forward()
    Pixel_Array.clear()
    Pixel_Array.setPixelColor(8, neopixel.colors(NeoPixelColors.Green))
    Pixel_Array.setPixelColor(9, neopixel.colors(NeoPixelColors.Green))
    Pixel_Array.setPixelColor(10, neopixel.colors(NeoPixelColors.Green))
    Pixel_Array.show()
})
OSOYOO_IR.onPressEvent(RemoteButton.NUM4, function () {
    kitronik_servo_lite.left()
    Pixel_Array.clear()
    Pixel_Array.setPixelColor(10, neopixel.colors(NeoPixelColors.Orange))
    Pixel_Array.setPixelColor(11, neopixel.colors(NeoPixelColors.Orange))
    Pixel_Array.setPixelColor(12, neopixel.colors(NeoPixelColors.Orange))
    Pixel_Array.show()
})
OSOYOO_IR.onPressEvent(RemoteButton.NUM6, function () {
    kitronik_servo_lite.right()
    Pixel_Array.clear()
    Pixel_Array.setPixelColor(6, neopixel.colors(NeoPixelColors.Orange))
    Pixel_Array.setPixelColor(7, neopixel.colors(NeoPixelColors.Orange))
    Pixel_Array.setPixelColor(8, neopixel.colors(NeoPixelColors.Orange))
    Pixel_Array.show()
})
OSOYOO_IR.onPressEvent(RemoteButton.NUM5, function () {
    kitronik_servo_lite.stop()
    Pixel_Array.clear()
    Pixel_Array.setPixelColor(7, neopixel.colors(NeoPixelColors.Red))
    Pixel_Array.setPixelColor(11, neopixel.colors(NeoPixelColors.Red))
    Pixel_Array.show()
})
OSOYOO_IR.onPressEvent(RemoteButton.NUM8, function () {
    kitronik_servo_lite.backward()
    Pixel_Array.clear()
    Pixel_Array.setPixelColor(5, neopixel.colors(NeoPixelColors.Green))
    Pixel_Array.setPixelColor(6, neopixel.colors(NeoPixelColors.Green))
    Pixel_Array.setPixelColor(12, neopixel.colors(NeoPixelColors.Green))
    Pixel_Array.show()
})
let move = 0
let Pixel_Array: neopixel.Strip = null
led.enable(false)
Pixel_Array = neopixel.create(DigitalPin.P0, 13, NeoPixelMode.RGB)
Pixel_Array.setBrightness(4)
Pixel_Array.showRainbow(1, 360)
basic.pause(1000)
Pixel_Array.clear()
Pixel_Array.show()
pins.servoWritePin(AnalogPin.P3, 180)
move = 180
OSOYOO_IR.init(Pins.P8)

Program MakeCode

Video

Nárazník Bumper V2

Nemusíte sa báť, lebo náročnú časť už máte za sebou. Teraz sa dostávame k oddychovej téme a tou je nárazník Bumper V2, ktorý tvoria dva plastové diely a dve skrutky. Tento nárazník sa pripevňuje na prednú časť podvozku, lebo sa používa na usmernenie loptičky pri robotickom futbale. Nie je ho možné súčasne použiť so snímačom čiary :MOVE Line Following board a rozhraním :MOVE Sensor Interface. Z toho vyplýva, že robot Kitronik :MOVE mini MK2 sa dá pri futbale robotov ovládať len využitím technológie Bluetooth mikropočítača micro:bit (za pomoci Android aplikácie Kitronik Move) alebo rádiovo druhým mikropočítačom (priamo alebo cez joystick).

Záver

Dnešná téma bola náročnejšia, takže určite vám patrí vďaka za prečítanie môjho článku. O to väčší osoh vám prinesie tento článok, lebo IR ovládač  a IR prijímač majú široké praktické uplatnenie v robotike.

Téma budúceho článku je zatiaľ otázna, lebo neviem, či sa mi podarí zohnať ďalšie príslušenstvo alebo dokonca nový robot. V krajnom prípade sa vynasnažím niečo zaujímavé vyskladať zo súčasných produktov určených pre mikropočítač micro:bit, ktoré mám doma.

E-shop

Kitronik :MOVE mini MK2

Naučte se základy robotiky s malým, vlastnoručně sestaveným a naprogramovaným robotem!

BBC Micro:bit

Nekonečně programovatelný a rozšiřitelný vzdělávací počítač do kapsy.

Doporučené příslušenství

Leave a Reply