View on GitHub

arduino-deti

Zápisky z našich domácích Arduino projektů

← zpět na zápisky z Arduino projektů

← zpět na Robopixli

Robopixle ovládaná pomocí Bluetooth z Python konzole

První verze dálkově ovládaného robota, který běhá po zemi. Zatím jen ovládaná pomocí Bluetooth a Python konzole. Do budoucna snad předěláme na něco jiného.

Co je potřeba umět

Foto

Hardware

Jak to funguje

Bluetooth

Jak už jsem zmínil, Bluetooth byla nouzová bezdrátová technologie, protože cílem bylo do večera daného dne zprovoznit bezdrátově Robopixli a poslední infra sensor jsem nešťastnou náhodou upálil. Wifi modul ani jiné bezdrátové technologie nebyly zrovna po ruce. Současně to ale byla i zajímavá příležitost si Bluetooth modul vyzkoušet, protože jsme s ním nikdy ještě nic nedělali.

Bluetooth a Linux

Nejdříve je potřeba zařízení napárovat s počítačem, který ho bude ovládat. Párovali jsme s Linuxem, tedy jsme pro snadnější práci se zařízeními doinstalovali program Bluetooth manager.

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install blueman

Tlačítkem search dáme vyhledat zařízení, Robopixle musí být zapnutá, Bluetooth modul modře bliká.

Pravé tlačítko na nalzezeném HC-06, vybrat volbu pair (spárovat) a vyplnit pin 1234.

Bluetooth a Python

Pro práci s Bluetooth v Pythonu je potřeba nainstalovat knihovnu PyBluez.

pip install pybluez

Python Program pro ovládání Robopixle viz níže.

Bluetooth a Arduino

Používáme knihovnu SoftwareSerial - to proto, aby nebylo nutné při nahrávání kódu do Arduina odpojovat Bluetooth modul - ten totiž blokuje TX/RX piny a hádá se to. SoftwareSerial umožňuje Bluetooth připojit na jiné piny Arduina a provozovat sériovou komunikaci tam, je pak možné vše provozovat pohodlně najednou.

Jen taková nápověda: RX pin Bluetooth modulu přijde zapojit na TX Arduina a TX Bluetooth na RX Arduina. Trochu nás to potrápilo, ale smysl to dává :-)

L298N dual motor driver

Dvoumotorový řadič, který si poradí i s vyšším napětím. Umožňuje jednoduše ovládat 2 motory nezásvisle oběma směry. Pomocí PWM je možné ovlivňovat i rychlost motorů.

Parametry:

V našem případě z jeho vstupních svorek přivádíme napětí do Arduina, jelikož to eliminuje nepájivé pole v pixli (a pájení). A to se hodí hlavně z hlediska prostoru.

Napájení

Krabice pro Robopixli není na výšku dostatečně vysoká, aby mohlo mít Arduino napájení přes konektor (ať už USB nebo jack). Bylo potřeba prozkoumat jiné možnosti napájení přímo přes piny Arduina. - z baterie jde tedy do GND a + jde do Vin pinu.

Schéma zapojení

robopixle_bt.fzz

robopixle_bt

Program pro Robopixli

robopixle_bt.ino

#include <SoftwareSerial.h>

// piny pro software serial
const int rxpin = 2;
const int txpin = 3;
// inicializace software serial
SoftwareSerial bluetooth(rxpin, txpin);
char ch = 'A';

// pripojeni pinu motoru
// motor A
const int enA = 6;
const int in1 = 5;
const int in2 = 4;
// motor B
const int enB = 9;
const int in3 = 7;
const int in4 = 8;

// maximalne 255
const int rychlost = 100;
const int rychlostOtocka = 90;
const int delkaOtocka = 280;
const int delkaKrok = 1000;

void setup() {
  pinMode(enA, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);

  //inicializace konzole
  Serial.begin(9600);
  Serial.println("Serial ready");

  // inicializace bluetooth
  bluetooth.begin(9600);
  bluetooth.println("Bluetooth ready");
}

// pusti oba motory
// vpred = true, pokud ma jet vpred
// cas = pocet ms, jak dlouho pojede
void obaMotory(bool vpred, int cas) {
  if (vpred) {
    // motor A
    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);
    // motor B
    digitalWrite(in3, LOW);
    digitalWrite(in4, HIGH);
  } else {
    // motor A
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    // motor B
    digitalWrite(in3, HIGH);
    digitalWrite(in4, LOW);
  }
  // motor A
  if (vpred) {
    // drobna korekce nerovnomerneho navrtani motoru v pixli
    analogWrite(enA, rychlost + 10);
  } else  {
    analogWrite(enA, rychlost);
  }
  // motor B
  analogWrite(enB, rychlost);  
  delay(cas);
  zastavOba();
}

// pokus o otocku vlevo o 90 stupnu
void zahniVlevo() {
    // motor A
    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);
    // motor B
    digitalWrite(in3, HIGH);
    digitalWrite(in4, LOW);
  // motor A
  analogWrite(enA, rychlostOtocka);
  // motor B
  analogWrite(enB, rychlostOtocka);  
  delay(delkaOtocka + 30);
  zastavOba();
}

// pokus o otocku vpravo o 90 stupnu
void zahniVpravo() {
    // motor A
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    // motor B
    digitalWrite(in3, LOW);
    digitalWrite(in4, HIGH);
  // motor A
  analogWrite(enA, rychlostOtocka);
  // motor B
  analogWrite(enB, rychlostOtocka);  
  delay(delkaOtocka + 30);
  zastavOba();
}

// zastaveni obou motoru
void zastavOba() {
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);  
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
}

void loop() {
  if(bluetooth.available()){
    // nacti znak z bluetooth
    ch = bluetooth.read();
    // vypis na konzoli
    Serial.println(ch);

    if (ch == 'F') {
      Serial.println("Forward");
      obaMotory(true, delkaKrok);
    } else if (ch == 'B') {
      Serial.println("Backward");
      obaMotory(false, delkaKrok);
    } else if (ch == 'R') {
      Serial.println("Right");
      zahniVpravo();
    } else if (ch == 'L') {
      Serial.println("Left");
      zahniVlevo();
    }
  }
  delay(10);
}


Program pro ovládací Python konzoli

Program pro ovládání je velmi jednoduchý, páruje se automaticky na první zařízení, které na Bluetooth síti nalezne, vůbec neinteraguje s uživatelem, že by mu dával na výběr. Že je spárováno je možné poznat jak na displeji počítače (objeví se výzva k zadávání pohybových příkazů), tak na Robopixli, kde přestane blikat modrá LED Bluetooth modulu a začne trvale svítit.

Ovládání Robopixle probíhá pomocí jednoduchých příkazů sestávajících ze 4 písmen:

robopixle_bt.py

# pybluez
import bluetooth

# hledame zarizeni
print "Hledam zarizeni..."
print ""
nearby_devices = bluetooth.discover_devices()

# vyber prvni zarizeni ze seznamu
selection = 0
bd_addr = nearby_devices[selection]

port = 1
sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)

# odpojeni
def disconnect():
	sock.close()

# posilani dat
def send(data):
	sock.send(data)

# pripoj se k zarizeni        
sock.connect((bd_addr, port))
print 'Spojeno.'
print 'Cekam na prikazy pro Robopixli. Mozne prikazy jsou: F = dopredu, B = dozadu, L = vlevo, R = vpravo.'

# nekonecne opakovani, prerusi se Ctrl+C
while True:
	# nacti znak ze vstupu z klavesnice
	ch = raw_input();
	# posli pres BT
	send(ch)
disconnect()

Možná vylepšení

Možných vylepšení je mnoho a chystáme je.

Poznatky