Introduction: EAL - Selvbalancerende Robot

Vores tanke var i starten at lave en robot der, ved hjælp af en gyrosensor kunne holde balancen. Så man skulle kunne skubbe til robotten, for at bringe den ud af balance, hvor den efterfølgende skulle rette op. Vi havde også tænkt på at den skulle kunne styres via et bluetooth modul. Der skulle så laves, eller downloades en app, der kunne agere fjernbetjening. Oppe i toppen af robotten skulle der sidde en en ultralydsensor, monteret på en servomotor. Hvis robotten skulle være på vej mod en væg, eller andre forhindringer, så skulle ultralydsensoren stoppe robotten, når den var x antal centimeter fra forhindringen. Derefter skulle ultralydsensoren dreje en halv omgang, ved hjælp af servomotoren, hvor den så kan fortsætte den modsatte vej tilbage. Nedenfor ses der en illustration af vores første prototype samt fortrådningsdiagram.

Step 1: 3D Print Af Dele

Da modellen var designet, påbegyndte vi 3D printningen af delene til robotten.

Step 2: Samling Af Robot

Med alle delene printet, blev de samlet.

Step 3: Nye Motorer

Vi fandt ud af at vores DC motorer ikke kunne klare opgaven, måtte vi finde en anden løsning.

DC motorene var ikke hurtige nok i opstarten, på grund af den høje gearing. Der var monteret en gearing, på hver motor på cirka 140 O/min. Vi har kunne læse os frem til at mange andre, der har forsøgt sig med en robot magen til, har benyttet sig af motorer med cirka 100 O/min mere end vi havde til rådighed. Vi fik så fremskaffet to Nema 17 stepper motorer uden gearing, som have den fordel, at være mere præcise, samt man kan positionerer hvor mange step motoren skal køre. Det resulterede i at vi var nødsaget til at udskifte vores L298N motordriver, med to Easydriver v4.4, da vores førstenævnte driver godt kunne køre to DC motorer, men kun en stepper motor. Det næste scenarie, var så at vores stepper motorer ikke kunne holde sig selv. Grunden til det var at selve Easydriveren ikke kunne lukke nok strøm igennem til motorerne. Det sidste vi afprøvede var et andet par Nema 17 stepper motorer, med en gearing på i håb om at gearingen kunne hjælpe motoren med at holde robotten oprejst. Det havde det samme udslag, som de første stepper motorer. Vi var nød til at konkludere at vi ikke kunne nå at fremskaffe nye drivere, eller motorer, før deadline var nået på vores projekt. Denne robot skal ses som et udkast til et projekt, der kan udvikles videre på.

Step 4: Materialeliste

1 stk Arduino Uno

1 stk Gyro sensor: MPU6050

DC motorer: 2 stk

Motordriver for DC motorer: 1 stk L298N

Stepper motorer: 2 stk Nema 17.

Driver for stepper motor: 2 stk Easydriver v4.4

Step 5: I/O Liste

Motordriver:

Motor, venstre: PWM, pin 10.

IN1: pin 9.

IN2: pin 8.

Motor højre: PWN, pin 6.

IN3: pin 5.

IN4: pin 4.

____________

Gyro sensor:

VCC: 5V +

SCL: SCL på Arduino.

SDA: SDA på Arduino.

Step 6: Arduino Code

#include <Wire.h>

//motor 1 int smDirectionPin1 = 8; //Direction pin int smStepPin1 = 9; //Stepper pin

//motor 2 int smDirectionPin2 = 11; //Direction pin int smStepPin2 = 10; //Stepper pin

//gyro long accelX, accelY, accelZ; float gForceX, gForceY, gForceZ;

long gyroX, gyroY, gyroZ; float rotX, rotY, rotZ;

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

void loop() { recordAccelRegisters(); recordGyroRegisters(); printData(); if(gForceY < -0.05){ digitalWrite(smDirectionPin1, HIGH); //Writes the direction to the EasyDriver DIR pin. (HIGH is clockwise). digitalWrite(smDirectionPin2, HIGH); //Writes the direction to the EasyDriver DIR pin. (LOW is counter clockwise). /*Slowly turns the motor 1600 steps*/ for (int i = 0; i < 100; i++){ digitalWrite(smStepPin1, HIGH); digitalWrite(smStepPin2, HIGH); delayMicroseconds(500); digitalWrite(smStepPin1, LOW); digitalWrite(smStepPin2, LOW); delayMicroseconds(500); } }

if(gForceY > 0.05){ digitalWrite(smDirectionPin2, LOW); //Writes the direction to the EasyDriver DIR pin. (HIGH is clockwise). digitalWrite(smDirectionPin1, LOW); //Writes the direction to the EasyDriver DIR pin. (LOW is counter clockwise). /*Turns the motor fast 1600 steps*/ for (int i = 0; i < 100; i++){ digitalWrite(smStepPin1, HIGH); digitalWrite(smStepPin2, HIGH); delayMicroseconds(500); digitalWrite(smStepPin1, LOW); digitalWrite(smStepPin2, LOW); delayMicroseconds(500); } }

}

void setupMPU(){ Wire.beginTransmission(0b1101000); //This is the I2C address of the MPU (b1101000/b1101001 for AC0 low/high datasheet sec. 9.2) Wire.write(0x6B); //Accessing the register 6B - Power Management (Sec. 4.28) Wire.write(0b00000000); //Setting SLEEP register to 0. (Required; see Note on p. 9) Wire.endTransmission(); Wire.beginTransmission(0b1101000); //I2C address of the MPU Wire.write(0x1B); //Accessing the register 1B - Gyroscope Configuration (Sec. 4.4) Wire.write(0x00000000); //Setting the gyro to full scale +/- 250deg./s Wire.endTransmission(); Wire.beginTransmission(0b1101000); //I2C address of the MPU Wire.write(0x1C); //Accessing the register 1C - Acccelerometer Configuration (Sec. 4.5) Wire.write(0b00000000); //Setting the accel to +/- 2g Wire.endTransmission(); }

void recordAccelRegisters() { Wire.beginTransmission(0b1101000); //I2C address of the MPU Wire.write(0x3B); //Starting register for Accel Readings Wire.endTransmission(); Wire.requestFrom(0b1101000,6); //Request Accel Registers (3B - 40) while(Wire.available() < 6); accelX = Wire.read()<<8|Wire.read(); //Store first two bytes into accelX accelY = Wire.read()<<8|Wire.read(); //Store middle two bytes into accelY accelZ = Wire.read()<<8|Wire.read(); //Store last two bytes into accelZ processAccelData(); }

void processAccelData(){ gForceX = accelX / 16384.0; gForceY = accelY / 16384.0; gForceZ = accelZ / 16384.0; }

void recordGyroRegisters() { Wire.beginTransmission(0b1101000); //I2C address of the MPU Wire.write(0x43); //Starting register for Gyro Readings Wire.endTransmission(); Wire.requestFrom(0b1101000,6); //Request Gyro Registers (43 - 48) while(Wire.available() < 6); gyroX = Wire.read()<<8|Wire.read(); //Store first two bytes into accelX gyroY = Wire.read()<<8|Wire.read(); //Store middle two bytes into accelY gyroZ = Wire.read()<<8|Wire.read(); //Store last two bytes into accelZ processGyroData(); }

void processGyroData() { rotX = gyroX / 131.0; rotY = gyroY / 131.0; rotZ = gyroZ / 131.0; }

void printData() { //Serial.print("Gyro (deg)"); //Serial.print(" X="); //Serial.print(rotX); //Serial.print(" Y="); //Serial.print(rotY); //Serial.print(" Z="); //Serial.print(rotZ); //Serial.print(" Accel (g)"); //Serial.println(" X="); //Serial.print(gForceX); Serial.print(" Y="); Serial.println(gForceY); //Serial.print(" Z="); //Serial.println(gForceZ); }