Bluetooth-Auto
Tuesday, January 29th, 2013Bastelprojekte, bei denen man keine Teile bestellen muss, weil man alles schon zu hause herumliegen hat, mag ich besonders. Das Bluetooth-Auto in den letzten 3 Tagen war so ein Projekt. Ein Freund gab mit ein “MGA CLUTCH AXI TRESPASS Land & Sea Fluid 4WD RC” Spielzeug-Auto für das er keine Fernsteuerung und auch keine funktionierenden Akkus mehr besa??. Zunächst habe ich überlegt, ob man normale RC-Empfänger und Motorregler einbauen kann, aber ich hatte nur einen Regler für Bürstenmotoren – ohne Rückwärtsgang.
Das Auto zu öffnen war nicht einfach: Viele schwer erreichbare Schrauben, viel Fett und Dichtungsgummis, denn das Auto konnte auch auf Wasser fahren.
Auf der Platine fand ich 6 Relais: 2 x Motor links , 2 x Motor rechts, 2 x Motor Lenkung – dachte ich – aber die Lenkung hatte eine Eigene Transistor-H-Brücke. Also 3 Relais pro Motor für Umpolung und 2 Geschwindigkeitsstufen.
Hardware-Hack
Die Relais hatten SMD Treiber Transistoren mit Testpunkten am Eingang – Dort hätte ich die Ausgänge meines Atmega8 mit positiver Logik anschlie??en können. aber ich hatte aus dem RGB-Heli-Projekt noch die Platine mit Spannungsregler, ULN2803 und Anschlüssen für Seriell und ISP. Also bin ich mit den Ausgängen des ULN direkt an die Relais gegangen. An TX & RX habe ich ein $10 Bluetooth RF Transceiver Module angeschlossen, wie es sich schon beim Multiwii quadcopter bewährt hat.
Software-Hack, Arduino
int inByte = 0; // incoming serial byte
const int red1 = 6;
const int green1 = 3;
const int blue1 = 5;
const int red2 = 9;
const int green2 = 11;
const int blue2 = 10;
byte state = 0;
unsigned long currentMillis ;
unsigned long commandMillis;
long interval = 1000;
const byte o_stop = 0;
void alloff() {
digitalWrite(blue1, LOW);
digitalWrite(blue2, LOW);
digitalWrite(red1, LOW);
digitalWrite(red2, LOW);
digitalWrite(green1, LOW);
digitalWrite(green2, LOW);
delay(200);
}
void allon() {
digitalWrite(blue1, HIGH);
digitalWrite(blue2,HIGH );
digitalWrite(red1, HIGH);
digitalWrite(red2, HIGH);
digitalWrite(green1, HIGH);
digitalWrite(green2,HIGH );
delay(200);
}
void setup() {
pinMode(red1, OUTPUT);
pinMode(green1, OUTPUT);
pinMode(blue1, OUTPUT);
pinMode(red2, OUTPUT);
pinMode(green2, OUTPUT);
pinMode(blue2, OUTPUT);
currentMillis = millis();
commandMillis = currentMillis;
Serial.begin(115200);
allon();
alloff();
allon();
alloff();
}
void loop() {
if (Serial.available() > 0) {
inByte = Serial.read();
Serial.write(inByte);
state = inByte;
Serial.write(state);
digitalWrite(green2, (state & B00100000) );
digitalWrite(blue2, (state & B00010000) );
digitalWrite(red2, (state & B00001000) );
digitalWrite(green1, (state & B00000100) );
digitalWrite(blue1, (state & B00000010) );
digitalWrite(red1, (state & B00000001) );
commandMillis = millis();
}
currentMillis = millis();
if(currentMillis - commandMillis > interval) {
alloff();
state = o_stop;
}
}
Software-Hack, android
Von der Android-App, die ich mit SL4A in python geschrieben habe, gibt es 3 Varianten:
1.Variante
In einem Dialog mit den Buttons “+” “-” und “send” kann man ASCI Zeichen ab “0” durchblättern und zum Auto senden. Dabei habe ich mir notiert, bei welchen Zeichen (=Relaiskobinationen) was passiert – Für das Auto sind nur die unteren 6 Bits relevant.
XXXX X011 "3" rechter Motor rückwärts XXXX X101 "5" rechter Motor vorwärts ???? ???? "@" stop 0101 1000 "X" linker Motor rückwärts ???? ???? "[" beide Motoren rückwärts ???? ???? "]" beide Motoren, Auto dreht auf der Stelle linksherum 0110 1000 "h" linker Motor vorwärts 0110 1011 "k" beide Motoren, Auto dreht auf der Stelle rechtsherum 0110 1101 "m" beide Motoren vorwärts
2.Variante
hier kann man Zeichen per soft-keybord auswählen und senden um die Ergebnisse aus 1 nuch mal zu kontrollieren.
3.Variante
Je nach Neigung des Handys wird eins von 5 Zeichen zum Auto gesendet, 4 x pro Sekunde. siehe Video
#!/usr/bin/python
# -*- coding: utf-8 -*-
import android
import time
tilt_angle = 0.2
b_forw = 'm'
b_backw ='['
b_turn_right ='k'
b_turn_left = ']'
b_stop = '@'
outb = '@'
def bt_out(value):
droid.bluetoothWrite(value)
if __name__ == '__main__':
# global android Object for GUI
droid = android.Android()
# every 200ms
ret = droid.startSensingTimed(1,200)
droid.bluetoothConnect('00001101-0000-1000-8000-00805F9B34FB', '00:12:02:11:01:10')
time.sleep(1)
state = b_stop
while True:
ret = droid.sensorsReadOrientation().result
pitch = ret[1]
roll = ret[2]
#print pitch,roll,
if pitch < -1.4:
droid.stopSensing()
droid.bluetoothStop()
exit()
if pitch > tilt_angle:
print 'forwards',
state = b_forw
if pitch < -tilt_angle:
print 'backwards',
state = b_backw
if pitch > -tilt_angle and pitch < tilt_angle:
print '-----',
state = b_stop
if roll > tilt_angle:
print 'right',
state = b_turn_right
if roll < -tilt_angle:
print 'left',
state = b_turn_left
if roll > -tilt_angle and roll < tilt_angle:
print '-----',
bt_out(state)
print state
old_state = state
time.sleep(0.2)
Ausblick
- Für Indoor könnte man einen Ultraschall Sensor auf das Auto montieren. Dann könnte es automatisch vor (manchen) Hindernissen stoppen und auch die Umgebung mappen.
- Per Spannungsteiler am Analogeingang kann das Auto seine Akku-Spannung zurück senden.
- Für Outdoor könnte man das Handy auf das Auto montieren, dank Kompass & GPS kann es dann autonom navigieren und Wegpunkte abfahren