kubiaczkov / makeblock

podręcznik do programowania mBot w arduino

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Podręcznik użytkownika dla mBot przy użycia języku Arduino

Informacje zawarte w tym podręczniku mogą zawierać błędy, dziękuję za wyrozumiałość.

IDE wykorzystywane do programowania urządzenia online mBot v1.1. dostępne pod linkiem: https://ide.mblock.cc/

Kiedy chcemy używać jedynie kodu Arduino o wiele wygodniej będzie nam pracować w Arduino IDE, instrukcja konfiguracji oprogramowania.

Instalacja wymaganego oprogramowania

Jeżeli chcemy wgrywać programy do naszego mBota przy pomocy połączenia kablowego USB A->B, musimy uprzednio zainstalować odpowiednie oprogramowanie.

Instalator oprogramowania mLink dostępny jest pod linkiem: https://www.mblock.cc/en/download/mlink/

Wybieramy oprogramowanie odpowiednie dla naszego systemu.

Poniższe czynności na podłączonym oraz uruchomionym urządzeniu!

Przechodząc poprzez proces instalacji, poza samym oprogramowaniem mLink instalujemy również odpowiednie sterowniki.

Połączenie z urządzeniem w IDE

Aby móc importować nasze programy do urządzenia mBot, musimy je połączyć wewnątrz oprogramowania do kodowania. Robimy to wybierając u dołu okranu przycisk "połączenie"

Zatwierdzamy konfigurację połączenia na porcie COM3 przy pomocy USB. W tym momencie nasze urządzenia powinny być ze sobą połączone.

PROGRAMOWANIE

IDE mBlock umożliwia tworzenie programów na dwa sposoby

  • programowanie blokowe - Scratch
  • programowanie obiektowe - Arduino

Tworząc program blokowy mamy możliwość podglądu kodu Arduino, jednak nie możemy go z tego poziomu edytować. W tym podręczniku skupimy się na programowaniu z użyciem języka programowania Arduino.

Uruchomienie programu

Aby uruchomić napisany program, trzeba aktywować odpowiednią zakładkę "Arduinoc".

Naszym oczom ukaże się edytor tekstowy z otwartym plikiem mcore.ino

UWAGA: nie zmieniamy jego nazwy ani rozszerzenia!

HELLO WORLD

Każy napisany przez nas program, będzie zaczynał się od identycznej składni, a konkretnie

#include <MeMCore.h>
#include <Arduino.h>
#include <Wire.h>
#include <SoftwareSerial.h>

void _delay(float seconds) {
  long endTime = millis() + seconds * 1000;
  while(millis() < endTime) _loop();
}

void setup() {
}

void _loop() {
}

void loop() {
  _loop();
}

Ten schemat posiada cztery zaimplemetowane funkcje:

  • _delay - służącą do tworzenia opóźnienia w działaniu programu, przyjmuje parametr float seconds, czyli podajemy w postaci zmiennoprzecinkowej ile sekund ma trwać przerwa np.: _delay(0.5) zatrzyma nam program na pół sekundy.
  • setup - będziemy umieszczać tutaj instrukcję, które chcemy aby wykonały się na starcie
  • loop - będziemy umieszczać tutaj instrukcję, które chcemy aby się powtarzały w nieskończoność

TIP: możemy również zamiast funkcji loop wykorzystać nieskończoną pętle while wewnątrz funkcji setup co będziemy robić najczęściej

Przykład:

void setup() {
  while(true) {
    // code here
    _loop();
  }
}

ZAPAMIĘTAJ: nie zapomnij o wszystkich #include :)


Uruchomienie programu

Aby uruchomić program musimy przesłać nasz kod do robota. Robimy to za pomocą przycisku "Załaduj z pliku"

TIP: w przypadku problemów w załadowaniem programu pomaga ponowne przesłanie lub ponowne uruchomienie robota. Jeżeli to nie pomaga potrzebny będzie hard reset przy pomocy odpowiedniego przycisku na płycie głównej

ZANIM PRZEJDZIEMY DO PROGRAMOWANIA

Programowanie urządzeń typu robot wymaga jeszcze dodatkowej porcji wiedzy, o co konkretnie chodzi? W najprostrzych programach komputerowych operacje wejścia/wyjścia zazwyczaj wykonujemy z poziomu konsoli, w tym przypadku musimy korzystać z faktycznych urządzeń we/wy takich jak:

  • czujniki np. linii, światła
  • diody LED
  • ekran LED
  • silniki sterujące
  • itp.

Także, zanim będziemy w stanie wykonać pierwsze czynności musimy zapoznać się z obsługą takich urządzeń.

Każde urządzenie będzie wymagało wykorzystania odpowiednich obiektów w programie. Niestety dokumentacja jest mocno okrojona, w zasadzie to jej nie ma.

DEBUGOWANIE KODU

Mikrokontroller Arduino UNO domyślnie nie wspiera możliwości debugowania kodu, jednak jest na to sposób :)

Pracując w środowisku Arduino IDE, istnieje możliwość korzystania z tzw. Serial Monitor i to właśnie on posłuży nam do debugowania naszego kodu. Aby zobaczyć wyniki musimy trochę zadziałać. Po pierwsze sprawdźmy gdzie wizualnie znajduje się ten monitor.

Następnie musimy dodać trochę kodu. Po pierwsze trzeba połączyć nasz program z monitorem.

Serial.begin(9600);

Tą linię kodu musimy umieścić wewnątrz funkcji setup

Następnie bez problemu możemy wykorzystać metody wypisujące aby sprawdzić co tam się dzieje w naszym kodzie.

int sensorData = 0;
Serial.print("Sensor Data = ");
Serial.println(sensorData);

Możemy również wykorzystać tą funkcjonalność do odczytywania danych i wykorzystania w naszym programie przy pomocy metody Serial.readString(). Istnieją inne sposoby odczytu danych jednak ten tekstowy będzie dla nas najprzyjemniejszy.

Przyklad:

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.println("Wprowadź dane:");
  while (Serial.available() == 0) {}     // Czekaj na dane
  String teststr = Serial.readString();  // Odczytaj dane
  teststr.trim();                        // Usuń co niepotrzebne

  // Wykorzystanie wczytanych danych
  if (teststr == "#f25022") {
    Serial.println("A primary color");
  } else {
    Serial.println("Something else");
  }
}

Z przesłanymi danymi w formie testkowej możemy zrobić bardzo wiele rzeczy, można je np. rzutować na inne typy danych.

PRZEGLĄD URZĄDZEŃ

Od razu na wstępie zaznaczę, że nie wszystko w tym poradniku będzie wytłumaczone od deski do deski, bardziej skupimy się na przykładach użycia. Także, do dzieła!

No. 1 - DIODY LED


W naszym urządzeniu diody LED występują w parze i pozwalają wyświetlać dowolny kolor w gammie barw RGB.

Aby użyć w naszym programie diod musimy na początku programu dodać obiekt klasy MeRBGLed.

MeRGBLed rgbled_7(7, 2);

Następnie wewnątrz funkcji setup musimy dopisać

rgbled_7.fillPixelsBak(0, 2, 1);

Po takiej konfiguracji w dalszej części programu w prosty sposób będziemy mogli wykorzystać diody LED. Dwie podstawowe funkcje:

rgbled_7.setColor(0, 255, 0, 0);
rgbled_7.show();

TIP: wygaszenie diod można uzyskać poprzez wywolanie koloru czarnego tj. rbg(0,0,0)

Powyższy kod wyświetli nam kolor czerwony na oby diodach. Metoda setColor ma następującą składnie setColor(opt, R, G, B).

Wartości opt mogą być następujące:

  • 0 - obie diody
  • 1 - prawa dioda
  • 2 - lewa dioda

Metoda show odpowieda za wyświetlenie ustalonego koloru.

TIP: aby zmiany kolorów były płynne powinniśmy wkorzystać funkcję delay

No. 2 - BUZZER


Robot mBot posiada również buzzer pozwalający odtwarzać dźwięki! Aby móc być usłyszanym, również potrzebujemy użyć odpowiedniego obiektu.

MeBuzzer buzzer;

W tym przypadku użycie jest jeszcze prostrze! Wystarczy nam opanować jedną funkcję tone.

buzzer.tone(950, 0.6 * 1000);

Metoda tone ma następującą skladnie tone(Hz, duration). Czyli powyższy kod przez 0.6 sekundy będzie nam odgrywać dźwięk o częstotliwości 950Hz.

  • Hz - wartość z zakresu 20 do 20000
  • duration - czas trania w ms, równanie X * 1000 da nam X sekund trwania dźwięku

TIP: tak samo możemy wywoływanie dźwięków mieszać z przerwami delay

No. 3 - EKRAN LED


W naszym wyposażeniu znajduje się coś co pozwoli nam w czytelny sposób przedstawić różnego rodzaju informację. Jest to ekran LED.

Ekran jest zbudowany ze 105 diod (15x7), co pozwala nam wyświetlać za jego pomocą liczby, maksymalnie 4 cyfrowe, teksty (o ile się zmieszczą), czas w formacie HH:MM oraz różnego rodzaju bitmapy.

Aby rozpocząć pracę z ekranem LED musimy jak zawsze stworzyć odpowiedni obiekt. Parametr przekazywany do konstruktora to numer portu do którego podłączony jest ekran.

MeLEDMatrix ledMtx_1(1);

Przypadki użycia

Zacznijmy od tego, że ekran może działać w dwóch konfiguracjach świetlnych. Wyświetlana zawartość jest rysowana lub jest obrysowywana. Parametr metody setColorIndex przyjmuje wartości true (rysowanie - domyślne) lub false (obrysowywanie).

void MeLEDMatrix::setColorIndex(bool Color_Number)

Z samych konfiguracji świetlnych, jesteśmy w stanie również zmienić jasność. Zakres jaśności jest od 0 do 8, gdzie 0 to brak jaśności, a 8 to najjaśniejsza konfiguracja.

void MeLEDMatrix::setBrightness(uint8_t Bright)

Dostępną przestrzeń roboczą możemy kreatywnie wykorzystywać do wyświetlania krotkich komunikatów. Pozwoli nam na to metoda drawStr, do wywołania której potrzebujemy 3 parametry. Pierwsze dwa odpowiedają za pozycję startową pisania, jest to wyzanczenie dolnego lewego rogu.

TIP: można wartość X_Position ustawić na wartość -1 aby wykorzystać całą dostępna przestrzeń rysowania

Przeci parametr wywołania to najprościej mówiąc nasz tekst, będziemy go generować w specjalny sposób. Dokumentacja przedstawia strukturę metody w taki sposób void MeLEDMatrix::drawStr(int16_t X_position, int8_t Y_position, const char *str). Poniżej przykład użycia:

ledMtx_1.drawStr(0, 7, String("XYZ").c_str());

Kolejną bradzo przydatną możliwościa jest wyświetlanie czasu. Konkretnie w formacie HH:MM. Oczywiście łatwo zauważyć, że przy odpowiedniej kombinacji nie będzie problemu z przerobieniem wyświetlanego formatu na MM:SS. Schemat metody według dokumentacji void MeLEDMatrix::showClock(uint8_t hour, uint8_t minute, bool point_flag). Poniżej przykład użycia:

ledMtx_1.showClock(2, 30);

Dla ułatwienia wyświetlania wartości liczbowych mamy specjalnie przeznaczoną do tego metodę showNum. Wymaga ona jednego parametru, którym jest rzeczona wartość - może ona przyjmować typ int lub float. Musimy jednak pamiętać, że kropka zajmie nam jedną pozycję na ekranie. Przykład użycia:

ledMtx_1.showNum(1234);
_delay(1);
ledMtx_1.showNum(10.1); // 4 znaki wraz z kropką

Ostanią metodą dostępną z poziomu ekranu LED, jest metoda clearScreen, która wyczyści nam ekran.

ledMtx_1.clearScreen()

Ekran LED posiada również wspomnianą funkcję wyświetlania bitmapy, jednak nie będziemy jej używać z poziomu czystego kodu. Można potestować tą funkcjonalność w blokowym systemie budowania oprogramowania dla mBot.

No. 4 - NAPĘD


Nasze cudowne urządzenie posiada potężne narzędzia w postaci napędu na dwa koła.

Obsługa jest dosyć prosta, wystarczy zainicjować nasze silniki w programie, wskazując na których PIN'ach będą działały, u nas jest to PIN 9 i 10.

MeDCMotor motor_9(9);
MeDCMotor motor_10(10);

Następnie mamy możliwość wywołania ruchu koła! Można to zrobić przy pomocy metody run(int speed). Zakres podawanej prędkości mieści się w przedziale -255 do 255. W zależności od tego czy nasza wartośc będzie dodatnia czy ujemna, koło będzie kręciło się w inną stronę. Oczywiście, czym wyższa wartość w jedną lub drugą stronę, tym wyższa prędkość obracania się kół.

motor_9.run(-250);
motor_10.run(250);

Aby sprawa była nieco prostrza, zbudujmy sobie funkcję, która pomoże nam w operowaniu mBotem.

void _move(int direction, int powerPercentage) {
  int speed = powerPercentage / 100.0 * 255;
  int leftSpeed = 0;
  int rightSpeed = 0;
  if(direction == 1) {
    leftSpeed = -speed;
    rightSpeed = speed;
  } else if(direction == 2) {
    leftSpeed = speed;
    rightSpeed = -speed;
  } else if(direction == 3) {
    leftSpeed = speed;
    rightSpeed = speed;
  } else if(direction == 4) {
    leftSpeed = -speed;
    rightSpeed = -speed;
  }
  motor_9.run(leftSpeed);
  motor_10.run(rightSpeed);
}

Funkcja ma za zadanie na podstawie przesłanych przez użytkownika dwóch parametrów speed oraz powerPercentage, uruchomi w odpowiedni sposób oba silniki do napędzania kół.

Parametr speed może przyjąć 4 opcje:

  • 1 - jazda na wprost
  • 2 - jazda wstecz
  • 3 - skręt w lewo (w miejscu)
  • 4 - skręt w prawo (w miejscu)

Oczywiście po odpowiedniej modyfikacji będziemy w stanie upłynnić co nieco skręcianie naszej maszyny, aby nie poruszała się jedynie "kwadratowo".

Drugi parametr powerPercentage przyjmuje wartość z zakresu 0-100, określającą procent mocy z jakimi mają być napędzone oba koła.

Na liście metod znajduje się również metoda na zatrzymanie naszego silnika.

motor_9.stop();
motor_10.stop();

TIP: będziemy mogli wplywać na to w jaki sposób się poruszamy np. poprzez zewnętrzny pilot

No. 5 - CZUJNIK NATĘŻENIA ŚWIATŁA


Jesteśmy uzbrojemi w narzędzie do zmierzenia natężenia światła w otoczeniu. Aby z niego korzystać trzeba odpowiednio zadeklarować nasz sensor.

MeLightSensor lightsensor_6(6);

Następnie wystarczy wykonać odczyt:

lightsensor_6.read();

Wynikiem działania metody read jest wartość int16.

TIP: można wykorzystać ekran LED lub Serial monitor aby odczytać "na żywo" jakie mamy natężenie światła w otoczeniu

No. 6 - CZUJNIK ODLEGŁOŚCI


Pomóc nam poruszać się w przestrzeni może czujmik Me Ultrasonic Sensor v3.0. Jest to czujnik ultradźwiękowy, który pozwala na odczytanie odległości od sensora w cm oraz calach.

Oczywiście rozpoczynamy od zainicjowania naszego czujnika. Jako parametr przekazujemy numer portu do którego jest podłączony czujnuj, w naszym przypadku nr. 3.

MeUltrasonicSensor ultrasonic_3(3);

Następnie przechodzimy do odpowiedniego pomiaru.

ultrasonic_3.distanceCm()

Funkcja zwróci nam wartość typu double, którą możemy użyć chociażby w warunku if.

Dokładny pomiar rozpoczyna się od ok 4 cm (przy krótszych odległościach sensor jest w stanie zadziałać odpowiednio, jednak nie ze 100% poprawnością). Najwyższą testowaną odległością było 50 cm.

No. 7 - CZUJNIK CZARNEJ LINII


Do grona naszych czujników, możemy dorzucić czujnik wykrywający czarną linię. Domyślnym punktem montażu jest spód naszego mBota. Jak zawsze rozpoczynamy od inicjalizacji. W parametrze przekazujemy numer portu podłączenia czujnika.

MeLineFollower linefollower_2(2);

Nasz czujnik, to tak na prawdę para czujników. Dlatego jesteśmy w stanie sprawdzać różne kombinacje. Możemy to zrobić dzięki metodzie readSensors()

linefollower_2.readSensors()

Metoda zwraca wartości:

  • 0 - aktywacja obu sensorów
  • 1 - aktywacja lewego sensora
  • 2 - aktywacja prawego sensora
  • 3 - oba sensory nieaktywne

TIP: sensory aktywują się również przy odpowiedniej odległości od podłoża, dlatego można je wykorzystać również jako detekcję krawędzi

UWAGA: aktywacja jednego sensora nie odpowiada aktywacji obu sensorom!

STEROWANIE UŻYTKOWNIKA

Nasz pakiet daje nam możliwość na zewnętrzne sterowanie robotem w dwojaki sposób. Pierwszy to przycisk na płytce

Drugi sposób sterowania to dołączany osobno do pakietu pilot.

Oba te urządzenia możemy wykorzystać do sterowania naszym robotem. Ale właściwie jak to działa?

PRZYCISK NA PŁYTCE

Jest to wbudowany komponent, który możemy po prostu wciskać. Aby skorzystać z niego w programie, musimy trochę poczarować z pinami, a konkretnie będziemy musieli ustawić odpowiedni tryb dla odpowiedniego pinu.

pinMode(A7, INPUT);

Następnie dzieje się jeszcze więcej magii, ale żeby nie musieć wszystkiego tłumaczyć, stworzymy sobie fajną funkcję :)

bool _checkButton() {
  if ((!(0 ^ (analogRead(A7) > 10 ? 0 : 1)))) {
    return true;
  } else {
    return false;
  }
}

Jedynie co przyjdzie nam wiedzieć na jej temat to to, że kiedy przycisk zostanie wciśnięty zwróci nam ona wartość true, w innym przypadku false.

TIP: aby optymalnie wykorzystać możliwości przycisku warto zastosować tą funkcję w parze z pętlą while, można podpatrzeć w przykładzie alert_on_button_clic.ino

PILOT

Pilot jako urządzenie zewnętrzne musimy zaimportować w naszym programie.

MeIR ir;

Nastepnie czekają nas dwie dodatkowe konfiguracje. Wewnątrz funkcji setup musimy rozpocząć nasłuchiwanie naszego pilota.

void setup() {
  ir.begin();
  ...
} 

Jednak to nie wszystko, aby pilot był nasłuchiwany stale, potrzebna będzie ingerencja w funkcję _loop.

void _loop() {
  ir.loop();
}

Teraz mamy przeprowadzoną pełną konfigurację i możemy oprogramować interakcję z naszym pilotem! Będziemy robić to podobnie jak z przyciskiem na płytce, najlepiej współproacować z pętlą while. Do odczytania wciśniętego przycisku na pilocie posłuży nam funkcja ir.keyPressed(numOfButton).

ir.keyPressed(21)

Funkcja zwraca wartości true oraz false. Przyjmuje ona jeden parametr - numer przycisku. Opis wszystkich przycisków poniżej:

  • A - 69
  • B - 70
  • C - 71
  • D - 68
  • E - 67
  • GÓRA - 64
  • PRAWO - 9
  • DÓŁ - 25
  • LEWO - 7
  • USTAW - 21
  • F - 13
  • 0 - 22
  • 1 - 12
  • 2 - 24
  • 3 - 94
  • 4 - 8
  • 5 - 28
  • 6 - 90
  • 7 - 66
  • 8 - 82
  • 9 - 74

TIP: wymuszenie programowo wciśnięcia pary przycisków jest możliwe, jednak w rzeczywistości nie działa to zbyt dobrze

About

podręcznik do programowania mBot w arduino


Languages

Language:C++ 100.0%