Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Manufacturing Technology >> Herstellungsprozess

Wie man einen Gestensteuerungsroboter zu Hause baut

Komponenten und Verbrauchsmaterialien

Arduino UNO
× 1
Arduino Nano R3
× 1
HC-05 Bluetooth-Modul
× 2
SparkFun Triple-Axis-Beschleunigungsmesser und Gyro Breakout - MPU-6050
× 1
DC-Motor, 12 V
× 2
Gummiräder
× 1
Doppelte H-Brücken-Motortreiber von Texas Instruments L293D
× 1
9-V-Batterie (generisch)
× 2

Notwendige Werkzeuge und Maschinen

Lötkolben (generisch)
Lötdraht, bleifrei
Band, Schaumstoff
Multitool, Schraubendreher

Apps und Onlinedienste

Arduino-IDE

Über dieses Projekt


Hier geht es darum, wie man selbst ein gestengesteuertes Auto baut. Im Grunde ist dies eine einfache Anwendung des MPU-6050 3-Achsen-Gyroskops, Beschleunigungsmessers. Sie können noch viele andere Dinge tun. indem Sie verstehen, wie man es benutzt, wie man es mit Arduino verbindet und wie man seine Daten über die Bluetooth-Module überträgt. In diesem Artikel konzentriere ich mich auf die Bluetooth-zu-Bluetooth-Kommunikation zwischen zwei HC-05 Bluetooth-Modulen.

Folgen Sie dem Video, um einen Roboterkörper und Verbindungen für dieses Projekt zu bauen.

Anschlussdiagramm für Roboter und Sendeeinheit sind unten aufgeführt, Sie können sie beziehen.

Leiterplatte, die in diesem Projekt verwendet wird, direkt bei PCBway bestellen:https://www.pcbway.com/project/shareproject/How_to_Make_Arduino_Based_Edge_Avoiding_Robot.html

Lassen Sie uns nun über die Konfiguration des Bluetooth-Moduls sprechen. Grundsätzlich wird das HC-05 Bluetooth-Modul mit einer Werkseinstellung für das Slave-Modul geliefert. Das bedeutet, dass wir Daten an das Modul jus senden können, indem wir es einstecken. Es müssen keine weiteren Einstellungen vorgenommen werden, um Daten von mobilen Geräten an das HC-05-Modul zu senden. Geben Sie einfach das Standardpasswort (1234/0000) ein, um eine Verbindung herzustellen. aber was ist, wenn wir Daten mit diesem Modul an ein anderes gleiches Modul oder an ein mobiles Gerät senden möchten.

In diesem Projekt tun wir dasselbe, indem wir Daten über das Bluetooth-Modul senden. gesammelt vom mpu-6050 gyrosensor an ein anderes Bluetooth-Modul.

Dazu müssen wir zuerst diese beiden Bluetooth-Module konfigurieren. damit sie sich nach dem Einschalten automatisch aneinander binden können. Hier fungiert das erste Modul als Slave-Gerät, das Signale von der Remote-Einheit empfängt und am Auto montiert wird. Und konfigurieren Sie das zweite als Master-Gerät, das als Sendereinheit fungiert und Daten an das Slave-Gerät sendet,

Konfigurieren Sie also zuerst das erste Bluetooth-Modul als Slave-Gerät. Verbinden Sie es dazu mit Arduino gemäß diesem Schaltplan.

Und laden Sie den Code nach Namenskonfigurieren hoch.

#include 
SoftwareSerial BTSerial(10, 11); // RX | TX
void setup()
{
Serial.begin(9600);
Serial.println("AT-Befehle eingeben:");
BTSerial.begin(38400 ); // HC-05-Standardgeschwindigkeit im AT-Befehl mehr
}
void loop()
{
// Lesen Sie weiter von HC-05 und senden Sie es an Arduino Serial Monitor
if (BTSerial.available())
Serial.write(BTSerial.read());
// Lesen Sie weiter vom Arduino Serial Monitor und senden Sie es an HC-05
if (Serial. verfügbar())
BTserial.write(Serial.read());
}

Modul trennen. Halten Sie das ky am Modul gedrückt und schließen Sie es wieder an. Sie werden sehen, dass die LED am Modul langsamer blinkt. Einmal alle 2 Sekunden. Dies bedeutet, dass sich HC-05 im AT-Befehlsmodus befindet. Öffnen Sie nun den seriellen Monitor, ändern Sie die Baudrate auf 9600 und den Ausgabetyp sowohl als NL als auch als CR. Geben Sie nun AT in das Sendefeld ein und senden Sie es. Wenn es mit ok antwortet, bedeutet dies, dass alles in Ordnung ist. Aber wenn dies nicht der Fall ist und mit einem Fehler antwortet, senden Sie AT erneut. Bis es mit ok antwortet oder Verbindungen checkt und AT erneut schickt …

Nachdem Sie eine OK-Antwort vom Modul erhalten haben, geben Sie die folgenden Befehle nacheinander ein:

AT+ORGL und senden Sie es. dieser Befehl setzt das Modul auf die Werkseinstellungen zurück.

AT+RMAAD dieser Befehl wird das Modul von allen vorherigen Kopplungen freigeben

AT+UART? Überprüfen Sie die aktuelle Baudrate des Moduls

AT+UART=38400, 0, 0 setze die Baudrate auf 38400

AT+ROLLE? Überprüfen Sie die Rolle, ob es sich um Slave oder Master handelt. es antwortet mit 0 oder 1. Wenn das Modul Slave ist, antwortet es mit 0 und wenn es Master-Gerät ist, antwortet es mit 1

Rolle als Slave-Gerät festlegen. Geben Sie AT+ROLE=0 ein

AT+ADDR? Überprüfen Sie die Moduladresse.

Notieren Sie diese Adresse. nach Modul geantwortet. nach Erhalt dieser Adresse ist die Konfiguration für das Slave-Modul abgeschlossen.

Jetzt ist es an der Zeit, das zweite Bluetooth-Modul als Master-Gerät zu konfigurieren. Verbinden Sie dieses Modul mit dem Arduino-Board und geben Sie es in den AT-Modus ein. wie beim vorherigen.

Geben Sie diese AT-Befehle in der angegebenen Reihenfolge ein.

AT+ORGL

AT+RMAAD

AT+UART?

AT+UART=38400, 0, 0

AT+ROLLE?

Legen Sie die Rolle dieses Moduls als Master-Gerät fest. AT+ROLE=1

AT+CMODE=0, damit das Modul nur ein einzelnes Gerät verbindet. Standardeinstellung ist 0

Binden Sie nun dieses Modul mit dem Slave-Gerät, um dies zu tun enter,

AT+BIND=" die Adresse des Slave-Moduls" und alles fertig

Installieren Sie jetzt Bibliotheken für MPU-6050-Sensor und I2C-Kommunikation. Da der Gyrosensor MPU-6050 über eine I2C-Schnittstelle verfügt. Laden Sie Bibliotheken und Quellcode von hier herunter:http://www.mediafire.com/file/l8mru5emulb8x93/gesture_control_robot.rar/file

Wenn Sie diese Bibliotheken vorinstalliert haben, überspringen Sie dies.

Verbinden Sie nun die Autoeinheit über ein USB-Kabel mit dem PC. Wählen Sie den richtigen COM-Port und den richtigen Kartentyp aus. Und laden Sie das Programm mit dem Namen "Gesture_controled_Robot__car_unit_" hoch. Stellen Sie sicher, dass die Batterie und das Bluetooth-Modul während des Hochladens des Programms nicht mit dem Auto verbunden sind.

//Programm von Shubham Shinganapure am 3.10.2019
//
//für Gestengesteuertes Roboterauto
int lm1=8; // linker Motorausgang 1
int lm2=9; // linker Motorausgang 2
int rm1=10; // rechter Motorausgang 1
int rm2=11; // rechter Motorausgang 2
char d=0;
void setup()
{
pinMode (lm1,OUTPUT);
pinMode (lm2,OUTPUT);
pinMode(rm1,OUTPUT);
pinMode(rm2,OUTPUT);
Serial.begin(38400);
sTOP();
}
void loop()
{
if(Serial.available()>0)
{
d=Serial.read();
if(d==' F')
{
ForWard();
}
if(d=='B')
{
BackWard();
}
if(d=='L')
{
Links();
}
if(d=='R')
{
Rechts();
}
if(d=='S')
{
sTOP();
}
}
}
void ForWard()
{
digitalWrite(lm1,HIGH);
digitalWrite(lm2,LOW);
digitalWrite(rm1,HIGH);
digitalWrite(rm2,LOW);
}
void BackWard()
{
digitalWrite(lm1,LOW);
digitalWrite(lm2,HIGH );
digitalWrite(rm1,LOW);
digitalWrite(rm2,HIGH);
}
void Left()
{
digitalWrite(lm1, LOW);
digitalWrite(lm2,HIGH);
digitalWrite(rm1,HIGH);
digitalWrite(rm2,LOW);
}
void Right()
{
digitalWrite(lm1,HIGH);
digitalWrite(lm2,LOW);
digitalWrite(rm1,LOW);
digitalWrite(rm2,HIGH);
}
void sTOP()
{
digitalWrite(lm1,LOW);
digitalWrite(lm2,LOW);
digitalWrite(rm1,LOW);
digitalWrite( rm2,LOW);
}

Machen Sie dasselbe mit der Fernbedienung. Öffnen Sie das Programm mit dem Namen Remote. und laden Sie es auf die Fernbedienung hoch.

//Programm geändert am 10.03.19 von // von Shubham Shinganapure.
//
//für Gestengesteuertes Roboterauto (Remote)
#include " I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
//#include "MPU6050.h" // nicht erforderlich bei Verwendung von MotionApps include-Datei
// Arduino Wire-Bibliothek wird benötigt, wenn I2Cdev I2CDEV_ARDUINO_WIRE-Implementierung
// wird in I2Cdev.h verwendet
#if I2CDEV_IMPLEMENTATION ==I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif
// class default I2C Adresse ist 0x68
// spezifische I2C-Adressen können hier als Parameter übergeben werden
// AD0 low =0x68 (Standard für SparkFun Breakout und InvenSense Evaluation Board)
// AD0 high =0x69
MPU6050 mpu;
#define OUTPUT_READABLE_YAWPITCHROLL
// MPU-Steuerungs-/Statusvariablen
bool dmpReady =false; // auf true setzen, wenn DMP-Init erfolgreich war
uint8_t mpuIntStatus; // hält das aktuelle Interrupt-Statusbyte von der MPU
uint8_t devStatus; // Status nach jeder Geräteoperation zurückgeben (0 =Erfolg, !0 =Fehler)
uint16_t packetSize; // erwartete DMP-Paketgröße (Standard ist 42 Byte)
uint16_t fifoCount; // Zählung aller Bytes, die sich derzeit im FIFO befinden
uint8_t fifoBuffer[64]; // FIFO-Speicherpuffer
VectorFloat Gravitation;
Quaternion q;
float ypr[3]; // [Gieren, Nicken, Rollen] Gieren/Necken/Rollen Container und Gravitationsvektor
uint8_t teapotPacket[14] ={ '$', 0x02, 0,0, 0,0, 0,0, 0,0 , 0x00, 0x00, '\r', '\n' };
volatile bool mpuInterrupt =false; // zeigt an, ob der MPU-Interrupt-Pin hoch gegangen ist
void dmpDataReady() {
mpuInterrupt =true;
}
#include
SoftwareSerial BTSerial( 10, 11); // RX | TX
int bt=8;
int x =1;
void setup() {
#if I2CDEV_IMPLEMENTATION ==I2CDEV_ARDUINO_WIRE
Wire.begin();
TWBR =24; // 400kHz I2C Takt (200kHz wenn CPU 8MHz)
#elif I2CDEV_IMPLEMENTATION ==I2CDEV_BUILTIN_FASTWIRE
Fastwire::setup(400, true);
#endif
// Seriell initialisieren Kommunikation
// (115200 ausgewählt, weil es für die Ausgabe der Teekanne erforderlich ist, aber es liegt
// je nach Projekt ganz bei Ihnen)
Serial.begin(115200);
BTserial.begin(38400);
// while (!Serial); // auf Leonardo-Aufzählung warten, andere fahren sofort fort
Serial.println(F("Initializing I2C devices..."));
mpu.initialize();
// Verbindung überprüfen
Serial.println(F("Geräteverbindungen testen..."));
Serial.println(mpu.testConnection() ? F("MPU6050-Verbindung erfolgreich") :F("MPU6050-Verbindung fehlgeschlagen" ));
// warten auf Fertig
// Laden und Konfigurieren des DMP
Serial.println(F("Initializing DMP..."));
devStatus =mpu .dmpInitialize();
// Geben Sie hier Ihre eigenen Gyro-Offsets ein, skaliert für minimale Empfindlichkeit
mpu.setXGyroOffset(220);
mpu.setYGyroOffset(76);
mpu. setZGyroOffset(-85);
mpu.setZAccelOffset(1788);
// Stellen Sie sicher, dass es funktioniert hat (gibt 0 zurück, wenn ja)
if (devStatus ==0) {
/ / DMP einschalten, jetzt, da es bereit ist
Serial.println(F("DMP aktivieren..."));
mpu.setDMPEnabled(true);
// Arduino-Interrupt aktivieren Erkennung
Serial.println(F("Aktivieren der Interrupterkennung (Arduino externer Interrupt 0)..."));
a ttachInterrupt(0, dmpDataReady, RISING);
mpuIntStatus =mpu.getIntStatus();
// Setze unser DMP Ready Flag, damit die Hauptfunktion loop() weiß, dass es in Ordnung ist, es zu verwenden
Serial .println(F("DMP bereit! Warten auf ersten Interrupt..."));
dmpReady =true;
// erwartete DMP-Paketgröße zum späteren Vergleich abrufen
packetSize =mpu.dmpGetFIFOPacketSize();
} else {
// FEHLER!
// 1 =anfängliches Laden des Speichers fehlgeschlagen
// 2 =Aktualisierung der DMP-Konfiguration fehlgeschlagen
// (wenn es kaputt geht, normalerweise der Code wird sein 1)
Serial.print(F("DMP-Initialisierung fehlgeschlagen (Code "));
Serial.print(devStatus);
Serial.println(F(")"));
}
// LED für Ausgang konfigurieren
pinMode(bt,INPUT);
}
// ==============================================================
// ===HAUPTPROGRAMMSCHLEIFE ===
// ===============================================================
void loop() {
if(digitalRead(bt)==HIGH)
{
x++;
verzögerung(150);
}
if((x%2)==0) {
// wenn die Programmierung fehlgeschlagen ist, versuche nichts zu tun
if (!dmpReady) return;
// warte auf MPU-Interrupt oder zusätzliche(s) Paket(e) verfügbar
while (!mpuInterrupt &&fifoCount // andere Sachen zum Programmverhalten hier
// .
// .
// .
// wenn Sie wirklich paranoid sind, können Sie häufig testen dazwischen andere
// Sachen, um zu sehen, ob mpuInterrupt wahr ist, und wenn ja, "break;" aus der
// while()-Schleife, um die MPU-Daten sofort zu verarbeiten
// .
// .
// .
}
// Interrupt-Flag zurücksetzen und INT_STATUS-Byte abrufen
mpuInterrupt =false;
mpuIntStatus =mpu.getIntStatus( );
// aktuellen FIFO-Zähler abrufen
fifoCount =mpu.getFIFOCount();
// auf Überlauf prüfen (dies sollte niemals passieren, es sei denn, unser Code ist zu ineffizient)
if ((mpuIntStatus &0x10) || fifoCount ==1024) {
// zurücksetzen, damit wir sauber weitermachen können
mpu.resetFIFO();
Serial.println(F("FIFO overflow!"));
// andernfalls auf DMP Data Ready Interrupt prüfen (dies sollte häufig vorkommen)
} else if (mpuIntStatus &0x02) {
// auf korrekte verfügbare Datenlänge warten, sollte eine SEHR kurze Wartezeit sein
while (fifoCount // ein Paket aus dem FIFO lesen
mpu.getFIFOBytes(fifoBuffer, packetSize);
// FIFO-Zählung hier verfolgen falls> 1 Paket verfügbar ist
// (damit können wir sofort weiterlesen, ohne auf einen Interrupt warten zu müssen)
fifoCount -=packetSize;
#ifdef OUTPUT_READABLE_YAWPITCHROLL
// display Eulerwinkel in Grad
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
Serial .print("ypr\t");
Serial.print(ypr[0] * 180/M_PI);
Serial.print("\t");
Serial.print( ypr[1] * 180/M_PI);
Seriell .print("\t");
Serial.println(ypr[2] * 180/M_PI);
if((ypr[1] * 180/M_PI)<=-25)
{BTSerial.write('F');
}
else if((ypr[1] * 180/M_PI)>=25)
{BTSerial.write('B' );
}
else if((ypr[2] * 180/M_PI)<=-25)
{BTSerial.write('L');
}
else if((ypr[2] * 180/M_PI)>=20)
{BTSerial.write('R');
}
else{
BTSerial. write('S');
}
#endif
}
}
else{
BTserial.write('S');
}
}

Stecken Sie das Slave-Bluetooth-Modul in die Autoeinheit und das Master-Bluetooth-Modul in die Fernbedienung. Und alles fertig.

Schalten wir es ein und es ist spielbereit…….



Ich hoffe, Sie finden dies nützlich. wenn ja, like es, teile es, kommentiere deine Zweifel. Für mehr solcher Projekte folgt mir! Unterstütze meine Arbeit und abonniere meinen Kanal auf YouTube.

Danke!

Code

  • Gestengesteuerter Roboter (Ferneinheit)
Gestengesteuerter Roboter (Ferneinheit)Arduino
//Programm geändert am 10.03.19 von // von Shubham Shinganapure. ////für Gestengesteuertes Roboterauto (Remote)#include "I2Cdev.h"#include "MPU6050_6Axis_MotionApps20.h"//#include "MPU6050.h" // nicht erforderlich bei Verwendung von MotionApps include-Datei // Arduino Wire-Bibliothek ist erforderlich, wenn I2Cdev I2CDEV_ARDUINO_WIRE-Implementierung// in I2Cdev.h verwendet wird#if I2CDEV_IMPLEMENTATION ==I2CDEV_ARDUINO_WIRE #include "Wire.h"#endif// Standard-I2C-Adresse der Klasse ist 0x68// Hier können spezifische I2C-Adressen als Parameter übergeben werden // AD0 low =0x68 (Standard für SparkFun Breakout und InvenSense Evaluation Board) // AD0 high =0x69MPU6050 mpu;#define OUTPUT_READABLE_YAWPITCHROLL// MPU Steuerung/Status varsbool dmpReady =false; // auf true setzen, wenn DMP-Init erfolgreich waruint8_t mpuIntStatus; // hält das aktuelle Interrupt-Statusbyte von MPUuint8_t devStatus; // Status nach jeder Geräteoperation zurückgeben (0 =Erfolg, !0 =Fehler)uint16_t packetSize; // erwartete DMP-Paketgröße (Standard ist 42 Byte)uint16_t fifoCount; // Anzahl aller Bytes, die sich derzeit in FIFouint8_t befinden fifoBuffer[64]; // FIFO-SpeicherpufferVectorFloat Schwerkraft; Quaternion q; float ypr[3]; // [Gieren, Nicken, Rollen] Gieren/Neigen/Rollen Container und Schwerkraft vectoruint8_t TeekannePacket[14] ={ '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' };volatile bool mpuInterrupt =false; // zeigt an, ob der MPU-Interrupt-Pin Highvoid geworden ist dmpDataReady () { mpuInterrupt =true;} #include  SoftwareSerial BTSerial (10, 11); // RX | TXint bt=8;int x =1;void setup() { #if I2CDEV_IMPLEMENTATION ==I2CDEV_ARDUINO_WIRE Wire.begin(); TWBR =24; // 400kHz I2C Takt (200kHz wenn CPU 8MHz ist) #elif I2CDEV_IMPLEMENTATION ==I2CDEV_BUILTIN_FASTWIRE Fastwire::setup(400, true); #endif // Initialisieren der seriellen Kommunikation // (115200 ausgewählt, weil es für die Ausgabe der Teapot-Demo erforderlich ist, aber es liegt // wirklich an Ihnen, abhängig von Ihrem Projekt) Serial.begin(115200); BTSerial.begin(38400); // while (!Seriell); // auf Leonardo-Aufzählung warten, andere fahren sofort fortSerial.println(F("Initializing I2C devices...")); mpu.initialize(); // Verbindung überprüfen Serial.println (F ("Geräteverbindungen testen ...")); Serial.println (mpu.testConnection () ? F ("MPU6050-Verbindung erfolgreich"):F ("MPU6050-Verbindung fehlgeschlagen")); // Warten auf Bereit // Laden und Konfigurieren des DMP Serial.println (F ("Initializing DMP ...")); devStatus =mpu.dmpInitialize(); // Geben Sie hier Ihre eigenen Gyro-Offsets an, skaliert für die minimale Empfindlichkeit mpu.setXGyroOffset(220); mpu.setYGyroOffset(76); mpu.setZGyroOffset(-85); mpu.setZAccelOffset(1788); // Stellen Sie sicher, dass es funktioniert hat (gibt 0 zurück, wenn ja) if (devStatus ==0) {// DMP einschalten, jetzt, da es fertig ist Serial.println (F ("DMP aktivieren ...")); mpu.setDMPEnabled(true); // Arduino-Interrupt-Erkennung aktivieren Serial.println (F ("Aktivieren der Interrupt-Erkennung (Arduino externer Interrupt 0) ...")); attachInterrupt(0, dmpDataReady, RISING); mpuIntStatus =mpu.getIntStatus(); // Setzen Sie unser DMP-Ready-Flag, damit die Hauptfunktion loop () weiß, dass es in Ordnung ist, sie zu verwenden Serial.println (F ("DMP ready! Waiting for first Interrupt ...")); dmpReady =wahr; // Erwartete DMP-Paketgröße für späteren Vergleich abrufen packetSize =mpu.dmpGetFIFOPacketSize(); } else { // FEHLER! // 1 =anfängliches Laden des Speichers fehlgeschlagen // 2 =DMP-Konfigurationsupdates fehlgeschlagen // (wenn es kaputt geht, ist der Code normalerweise 1) Serial.print (F ("DMP-Initialisierung fehlgeschlagen (code")); Serial. print(devStatus); Serial.println(F(")")); } // LED für Ausgang konfigurieren PinMode (bt, INPUT); }// ===============================================================// ===HAUPTPROGRAMMSCHLEIFE ===// ===============================================================void loop() { if (digitalRead (bt) ==HOCH) { x ++; Verzögerung (150); } if((x%2)==0){ // Wenn die Programmierung fehlgeschlagen ist, versuchen Sie nichts zu tun if (!dmpReady) return; // auf MPU-Interrupt oder zusätzliche Pakete warten, die verfügbar sind while (!mpuInterrupt &&fifoCount  1 Paket verfügbar ist // (dadurch können wir sofort mehr lesen, ohne auf einen Interrupt zu warten) fifoCount -=packetSize; #ifdef OUTPUT_READABLE_YAWPITCHROLL // Euler-Winkel in Grad anzeigen mpu.dmpGetQuaternion(&q, fifoBuffer); mpu.dmpGetGravity(&gravity, &q); mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); Serial.print("ypr\t"); Serial.print (ypr[0] * 180/M_PI); Serial.print("\t"); Serial.print (ypr[1] * 180/M_PI); Serial.print("\t"); Serial.println (ypr [2] * 180/M_PI); if((ypr[1] * 180/M_PI)<=-25) {BTSerial.write('F'); aufrechtzuerhalten. Sonst if((ypr[1] * 180/M_PI)>=25) {BTSerial.write('B'); aufrechtzuerhalten. Sonst if((ypr[2] * 180/M_PI)<=-25) {BTSerial.write('L'); aufrechtzuerhalten. Sonst if((ypr[2] * 180/M_PI)>=20) {BTSerial.write('R'); } Else{ BTserial.write ('S'); } #endif } } else{ BTSerial.write('S'); }}

Schaltpläne


Herstellungsprozess

  1. So erstellen Sie eine Arduino+Raspberry Pi-Roboterplattform
  2. Machen Sie eine DIY-Hausaufgaben-Schreibmaschine zu Hause
  3. Hindernisse vermeiden Roboter mit Servomotor
  4. Linienfolger-Roboter
  5. So erstellen Sie eine anpassbare stanzbare Tastaturtaste
  6. Autonomer Heimassistent-Roboter
  7. Wie man mit einem Arduino Musik macht
  8. Wie erstelle ich eine Arduino-basierte automatische Türöffnung
  9. Steuern Sie den Arduino-Roboterarm mit der Android-App
  10. Roboter für supercoole Indoor-Navigation