Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

LEGO Wall-E met Arduino

Componenten en benodigdheden

LEGO Wall-E
Moest een 2e hands halen omdat ze die niet meer maken
× 1
Arduino Nano R3
× 1
DC-motor (generiek)
× 2
L298N Dual Motor Controller
× 1
Tweekleurige LED
met 3 pinnen
× 1
Infraroodsensor
× 1
Zoemer
Eentje die verschillende tonen kan spelen
× 1
9V batterij
× 1
Weerstand 330 ohm
× 3
Jumperdraden (algemeen)
× 20

Benodigde gereedschappen en machines

Soldeerbout (algemeen)

Apps en online services

Arduino IDE

Over dit project

Iedereen kent de film Wall-E (en zo niet, ga hem nu kijken!) en de gele held die probeert de aarde op te ruimen. In dit project gebruikte ik een Lego-versie van onze kleine vriend en leerde hem hoe hij obstakels kon vermijden. Dit was mijn eerste project en een geweldige leerervaring om de basisprincipes van elektronica te doorgronden.

Stap 1 - De code

Als softwareontwikkelaar van beroep dacht ik na over wat ik wilde dat hij deed en begon met de code.

 // Dit programma is om de Wall-E Lego robot te besturen.// Wall-E rijdt rond. Als hij een obstakel ziet, stopt hij om rond te kijken en kiest een ander pad.// Arduino Nano heeft 21 pinnen die kunnen worden gebruikt voor digitalRead en digitalWrite// PWM-pinnen 3, 5, 6, 9, 10, 11 kunnen worden gebruikt voor analogWrite// pinnen 0 en 1 kunnen worden gebruikt voor TTL// pinnen 2 en 3 kunnen worden gebruikt voor externe interrupts// pinnen 10, 11, 12, 13 ondersteunen SPI-communicatie// pin 13 kunnen interne LED zijn// pinnen 14 tot 21 zijn ook analoge pinnen A0 tot A7 en kunnen worden gebruikt voor analogRead#define INFRA_RED 9 // kan elke pin zijn#define GREEN_LED 7 // kan elke pin zijn maar heeft een weerstand nodig, misschien 220 Ohm - of de aardingspin krijgt 1 kOhm# definieer RED_LED 8 // kan elke pin zijn maar heeft een weerstand nodig, misschien 220 Ohm - of de grondpin krijgt 1 kOhm #define BUZZER 10 // moet een PWM-pin zijn om de frequentie in te stellen, heeft een weerstand nodig, misschien 1 kOhm// MR is de rechtermotor, ML is de linkermotor#define MR_1 A1 // kan elke pin zijn, dus laten we ze overeenkomen met de pinnummers op het L289N-schild#define MR_2 A2 // kan elke pin zijn, dus laten we ze overeenkomen met de P in cijfers op het L289N-schild#define MR_ENABLE 5 // moet PWM-pin zijn voor snelheidsregeling#define ML_1 A3 // kan elke pin zijn, dus laten we ze overeenkomen met de pinnummers op het L289N-schild#define ML_2 A4 // kan elke pin zijn, dus laten we ze overeenkomen met de pinnummers op het L289N-schild #define ML_ENABLE 6 // moet PWM-pin zijn voor snelheidsregeling // zet zijn normale snelheid op maximumconst int NORMAL_SPEED =255;void setup() { // direct na het indrukken van de resetknop, wacht even zodat we hem kunnen uitschakelen zonder componenten te beschadigen door vertraging van spanningspieken (2000); // initialiseer LED's en zoemer pinMode (GREEN_LED, OUTPUT); pinMode(RED_LED, OUTPUT);//pinMode(BUZZER, OUTPUT); // niet nodig // reset LED naar groen digitalWrite (RED_LED, LOW); digitalWrite (GROEN_LED, HOOG); // set DC-motorpinnen pinMode (MR_ENABLE, OUTPUT); // motor rechts pinMode (MR_1, OUTPUT); pinMode (MR_2, UITGANG); pinMode (ML_ENABLE, UITGANG); // motor links pinMode (ML_1, OUTPUT); pinMode (ML_2, UITGANG); // initialiseer infrarood pinMode (INFRA_RED, INPUT); // initialiseer generator voor willekeurige getallen voor willekeurige beurten randomSeed (analogRead (0)); // zeg hallo playHello ();}void loop () { // normale operaties driveForwards (NORMAL_SPEED); // stel LED in op groen digitalWrite (RED_LED, LOW); digitalWrite (GROEN_LED, HOOG); // controleer op obstakels als (digitalRead (INFRA_RED) ==LOW) {//LOW betekent obstakel gedetecteerd // verander LED in rood digitalWrite (GREEN_LED, LOW); digitalWrite (RED_LED, HOOG); // stop motoren stopDriving(); // speel uh-oh geluid playUhOh(); // controleer linksaf (500); boolean obstakelLeft =false; if (digitalRead (INFRA_RED) ==LAAG) {obstakelLeft =waar; } // draai terug naar middenvertraging (100); draaiRechts(500); // wacht een beetje, we willen geen overhaaste vertraging lijken (500); // controleer rechts afslaanRechts (500); boolean obstakelRight =false; if (digitalRead (INFRA_RED) ==LAAG) {obstakelRight =waar; } // draai terug naar middenvertraging (100); draai Links (500); // kijk nu hoe je hier weg kunt komen if (obstacleLeft &&ObstacleRight) { driveBackwards(NORMAL_SPEED / 3); // piep tijdens het achteruit gaan gedurende 5 seconden voor (int i =0; i <5; i++) { tone(BUZZER, 1000, 500); vertraging (1000); } // om te voorkomen dat u ergens vastloopt, draait u willekeurig in een richting voordat u verder reist randomTurn(800, 1600); } else if (obstacleLeft) { turnRight(1000); } else if (obstacleRight) { turnLeft(1000); } else { randomTurn(1000, 1800); } } // doe willekeurige dingen voor meer interactie int number =random(100); // maakt een willekeurig getal tussen 0 en 99 if (getal ==0) { randomTurn (200,2000); }}void driveForwards (int speed) { // stel de motoren in om in dezelfde richting te gaan digitalWrite (MR_1, LOW); digitalWrite (MR_2, HOOG); digitalWrite(ML_1, HOOG); digitalWrite (ML_2, LAAG); setSpeed(speed);}void driveBackwards(int speed) { // stel de motoren in om in de tegenovergestelde richting te gaan digitalWrite(MR_1, HIGH); digitalWrite (MR_2, LAAG); digitalWrite(ML_1, LAAG); digitalWrite(ML_2, HOOG); setSpeed(speed);}void turnLeft(int duration) { // sla linksaf door vooruit te gaan met het rechterwiel en achteruit met het linkerwiel digitalWrite(MR_1, HIGH); digitalWrite (MR_2, LAAG); digitalWrite(ML_1, HOOG); digitalWrite (ML_2, LAAG); // vertraag om setSpeed ​​(NORMAL_SPEED / 2) te draaien; vertraging (duur); stopDriving();}void turnRight(int duration) { // sla rechtsaf door achteruit te gaan met het rechterwiel en vooruit met het linkerwiel digitalWrite(MR_1, LOW); digitalWrite (MR_2, HOOG); digitalWrite(ML_1, LAAG); digitalWrite(ML_2, HOOG); // vertraag om setSpeed ​​(NORMAL_SPEED / 2) te draaien; vertraging (duur); stopDriving();}void stopDriving() {// zet alle motorpinnen uit digitalWrite(MR_1, LOW); digitalWrite (MR_2, LAAG); digitalWrite(ML_1, LAAG); digitalWrite (ML_2, LAAG); // niet zeker wat te doen met de ENABLE-pinnen, maar het kan geen kwaad om ze ook uit te schakelen, denk ik digitalWrite (MR_ENABLE, LOW); digitalWrite(ML_ENABLE, LOW);}void setSpeed(int speed) {// speed moet tussen 0 en 255 liggen speed =constrain(speed, 0, 255); // stel de snelheid in om de motoren aan te zetten analogWrite (MR_ENABLE, snelheid); analogWrite(ML_ENABLE, speed);}void randomTurn(int minimum, int maximum) { unsigned long time =millis(); int duur =willekeurig (minimum, maximum); if (tijd % 2) { turnRight (duur); } else { turnLeft(duur); }}void playHallo() { tone(BUZZER, 262, 250); // speelt C4 vertraging (300); toon (ZOEMER, 330, 250); // speelt E4 vertraging (300); toon (ZOEMER, 392, 250); // speelt G4-vertraging (300); toon (ZOEMER, 523, 500); // speelt C5 delay(550);}void playUhOh() { tone(BUZZER, 523, 250); // speelt C5 vertraging (300); toon (ZOEMER, 415, 500); // speelt Gis4 delay(600);} 

Wanneer u een draaiende motor loskoppelt, kunnen spanningspieken optreden en uw elektronica beschadigen. Daarom laat ik Wall-E twee seconden wachten voordat hij iets doet. Dat betekent dat ik gewoon op de Reset-knop op de Arduino kan drukken en de batterij snel kan loskoppelen zonder iets te beschadigen.

Hij speelt een melodietje als hij wakker wordt en begint dan te rijden. Wanneer hij een obstakel ziet, stopt hij, speelt een "Uh-oh" -geluid en kijkt om zich heen om de beste manier te bepalen. Het type infraroodsensor dat ik heb gebruikt, heeft een schroefje op de achterkant waarmee je de afstand kunt bepalen waarop het een signaal afgeeft. Daarom zijn er geen afstandsberekeningen in de code. (Ik wilde eerst een ultrasone sensor gebruiken, maar die past niet bij zijn ogen.)

Wall-E controleert eerst of de linkerkant vrij is en vervolgens of de rechterkant vrij is. Als beide kanten geblokkeerd zijn, gaat hij piepend achteruit als zware machines op een bouwplaats, draait dan in een willekeurige richting en gaat verder. Als slechts één kant wordt geblokkeerd, gaat hij verder naar de andere kant. Als beide partijen vrij zijn, kiest hij er willekeurig een en vervolgt zijn weg.

Ik heb geprobeerd hem willekeurige bochten te laten maken, maar dat deel is nog niet helemaal af. Ik probeer de ingebouwde Arduino-timer te gebruiken. Laat het me weten in de reacties als je een idee hebt hoe je het kunt optimaliseren!

Stap 2 - Hem bedraden

Het eerste was om de infraroodsensor in het oog te laten bouwen, zodat het er niet al te voor de hand liggend uitziet. Ik heb het uit elkaar gehaald, een Lego-pin op de sensor gelijmd (zodat zijn oog op en neer kan bewegen) en vervolgens blauwe tack gebruikt om de Lego-stukjes terug rond de sensor te plaatsen:

Het belangrijkste van de motoren was dat ze voldoende koppel hebben, omdat de opstelling van de wielen van Wall-E nogal wat kracht nodig heeft om te bewegen. Ik moest draden aan de motoren solderen en ze zo bevestigen dat ze stevig op de Lego aansluiten. Dus ik haalde zijn wielen uit elkaar, bestelde een hele zak vol Lego Technic pinnen, wikkelde gipstape (noem je dat zo? Het is als zachte tape die op je huid kan gaan) rond de motorassen, en plakte ze in twee pinnen dat werd de hoofdas voor elk wiel. Dit werkte een paar minuten, maar toen was de wrijving te hoog om de lijm in de tape vast te houden. Gelukkig hebben de Technic-pinnen kleine groeven aan de zijkant, dus de tape had een plek om vast te houden, wat ze graag deden nadat ze in superlijm waren gedrenkt.

Ik heb ook een stukje van zijn borst verwijderd om de LED door te steken. Daarna heb ik alle onderdelen en de Arduino aangesloten.

Het motorschild slechts passen in zijn buik:

Het schema is ook niet erg duidelijk, maar ik heb geprobeerd de draden een kleurcode te geven voor een beter overzicht:

Volgens afspraak zijn alle rode draden positief ("leveren" elektriciteit) en alle zwarte draden zijn negatief ("elektriciteit ontvangen"). De gele draad rechtsboven draagt ​​het signaal voor de infraroodsensor; de oranje en groene draden zijn voor de driepolige tweekleurige LED, de paarse draden zijn om de motorafscherming te vertellen in welke richting de motoren moeten worden gedraaid, en de blauwe kabels vertellen de motorafscherming hoe snel ze moeten worden gedraaid.

Het motorschild had een zeer goede tutorial die het gemakkelijk aan te sluiten en te gebruiken maakte. Helaas had het Fritzing-gedeelte niet de twee pinnen voor het instellen van de snelheid, dus de blauwe kabels komen gewoon willekeurig op het motorscherm in het diagram terecht.

Nog een probleem dat ik tegenkwam terwijl ik alles aan elkaar plakte, was een gebrek aan spannings- en aardingspinnen. Ik wilde de motoren rechtstreeks door het motorschild voeden, zodat ze zoveel mogelijk vermogen kunnen krijgen, maar ik moest op de een of andere manier ook 5V naar de Arduino en de infraroodsensor voeren. Dus ik deed wat vrijwel iedereen op internet zei dat ik niet moest doen:ik verbond de 5V-uitgang van het motorschild als ingang met de 5V-pin van de Arduino. Nu met het schild dat ik gebruik, kan ik er absoluut zeker van zijn dat het een gereguleerde 5V uitvoert zonder vervelende pieken die mijn Arduino zouden kunnen beschadigen. Als je een niet-gereguleerde stroombron aan die pin bevestigt, bak je waarschijnlijk iets. Ik wilde eerst de Vin-pin gebruiken, maar die heeft een ingebouwd mechanisme dat alles naar beneden regelt, dus mijn 5V zou zijn veranderd in 3,8V of zo, wat niet genoeg is om de Arduino goed te laten functioneren. In plaats daarvan gebruikte ik de gratis Vin om de infraroodsensor van 5V te voorzien, omdat ik geen kabelsplitters had en ik wist dat daar ook 5V uit zou komen. Ja, het begon op dit punt een beetje op Frankenstein te lijken. Maar het werkte!

Stap 3 - Wall-E in actie

Hier zijn een paar video's die hem in actie laten zien:

En hier heb ik getest wat hij zou doen als hij vast zat in een hoek:

Dit was dus mijn eerste kleine project. Ik ben nu van plan om de kabelverbindingen te optimaliseren en misschien een servomotor toe te voegen zodat hij zijn hoofd kan draaien. Ik zou zelfs splitters en een kleiner motorschild en board kunnen kopen, zodat ik alles in zijn buik kan passen.

En dus Wall-E leefde gelukkig ooit na. De einde.

Code

  • Wall_e_control
Wall_e_controlArduino
Dit is het centrale controlebestand voor Wall-E. Het is eenvoudig, maar alles wat hij op dit moment nodig heeft.
// Dit programma is om de Wall-E Lego-robot te besturen.// Wall-E rijdt rond. Als hij een obstakel ziet, stopt hij om rond te kijken en kiest een ander pad.// Arduino Nano heeft 21 pinnen die kunnen worden gebruikt voor digitalRead en digitalWrite// PWM-pinnen 3, 5, 6, 9, 10, 11 kunnen worden gebruikt voor analogWrite// pinnen 0 en 1 kunnen worden gebruikt voor TTL// pinnen 2 en 3 kunnen worden gebruikt voor externe interrupts// pinnen 10, 11, 12, 13 ondersteunen SPI-communicatie// pin 13 kunnen interne LED zijn// pinnen 14 tot 21 zijn ook analoge pinnen A0 tot A7 en kunnen worden gebruikt voor analogRead#define INFRA_RED 9 // kan elke pin zijn#define GREEN_LED 7 // kan elke pin zijn maar heeft een weerstand nodig, misschien 220 Ohm - of de aardingspin krijgt 1 kOhm# definieer RED_LED 8 // kan elke pin zijn maar heeft een weerstand nodig, misschien 220 Ohm - of de grondpin krijgt 1 kOhm #define BUZZER 10 // moet een PWM-pin zijn om de frequentie in te stellen, heeft een weerstand nodig, misschien 1 kOhm// MR is de rechtermotor, ML is de linkermotor#define MR_1 A1 // kan elke pin zijn, dus laten we ze overeenkomen met de pinnummers op het L289N-schild#define MR_2 A2 // kan elke pin zijn, dus laten we ze overeenkomen met de P in cijfers op het L289N-schild#define MR_ENABLE 5 // moet PWM-pin zijn voor snelheidsregeling#define ML_1 A3 // kan elke pin zijn, dus laten we ze overeenkomen met de pinnummers op het L289N-schild#define ML_2 A4 // kan elke pin zijn, dus laten we ze overeenkomen met de pinnummers op het L289N-schild #define ML_ENABLE 6 // moet PWM-pin zijn voor snelheidsregeling // zet zijn normale snelheid op maximumconst int NORMAL_SPEED =255;void setup() { // direct na het indrukken van de resetknop, wacht even zodat we hem kunnen uitschakelen zonder componenten te beschadigen door vertraging van spanningspieken (2000); // initialiseer LED's en zoemer pinMode (GREEN_LED, OUTPUT); pinMode(RED_LED, OUTPUT);//pinMode(BUZZER, OUTPUT); // niet nodig // reset LED naar groen digitalWrite (RED_LED, LOW); digitalWrite (GROEN_LED, HOOG); // set DC-motorpinnen pinMode (MR_ENABLE, OUTPUT); // motor rechts pinMode (MR_1, OUTPUT); pinMode (MR_2, UITGANG); pinMode (ML_ENABLE, UITGANG); // motor links pinMode (ML_1, OUTPUT); pinMode (ML_2, UITGANG); // initialiseer infrarood pinMode (INFRA_RED, INPUT); // initialiseer generator voor willekeurige getallen voor willekeurige beurten randomSeed (analogRead (0)); // zeg hallo playHello ();}void loop () { // normale operaties driveForwards (NORMAL_SPEED); // stel LED in op groen digitalWrite (RED_LED, LOW); digitalWrite (GROEN_LED, HOOG); // controleer op obstakels als (digitalRead (INFRA_RED) ==LOW) {//LOW betekent obstakel gedetecteerd // verander LED in rood digitalWrite (GREEN_LED, LOW); digitalWrite (RED_LED, HOOG); // stop motoren stopDriving(); // speel uh-oh geluid playUhOh(); // controleer linksaf (500); boolean obstakelLeft =false; if (digitalRead (INFRA_RED) ==LAAG) {obstakelLeft =waar; } // draai terug naar middenvertraging (100); draaiRechts(500); // wacht een beetje, we willen geen overhaaste vertraging lijken (500); // controleer rechts afslaanRechts (500); boolean obstakelRight =false; if (digitalRead (INFRA_RED) ==LAAG) {obstakelRight =waar; } // draai terug naar middenvertraging (100); draai Links (500); // kijk nu hoe je hier weg kunt komen if (obstacleLeft &&ObstacleRight) { driveBackwards(NORMAL_SPEED / 3); // piep tijdens het achteruit gaan gedurende 5 seconden voor (int i =0; i <5; i++) { tone(BUZZER, 1000, 500); vertraging (1000); } // om te voorkomen dat u ergens vastloopt, draait u willekeurig in een richting voordat u verder reist randomTurn(800, 1600); } else if (obstacleLeft) { turnRight(1000); } else if (obstacleRight) { turnLeft(1000); } else { randomTurn(1000, 1800); } } // doe willekeurige dingen voor meer interactie int number =random(100); // maakt een willekeurig getal tussen 0 en 99 if (getal ==0) { randomTurn (200,2000); } }void driveForwards (int speed) { // stel de motoren in om in dezelfde richting te gaan digitalWrite (MR_1, LOW); digitalWrite (MR_2, HOOG); digitalWrite(ML_1, HOOG); digitalWrite (ML_2, LAAG); setSpeed(speed);}void driveBackwards(int speed) { // stel de motoren in om in de tegenovergestelde richting te gaan digitalWrite(MR_1, HIGH); digitalWrite (MR_2, LAAG); digitalWrite(ML_1, LAAG); digitalWrite(ML_2, HOOG); setSpeed(speed);}void turnLeft(int duration) { // sla linksaf door vooruit te gaan met het rechterwiel en achteruit met het linkerwiel digitalWrite(MR_1, HIGH); digitalWrite (MR_2, LAAG); digitalWrite(ML_1, HOOG); digitalWrite (ML_2, LAAG); // vertraag om setSpeed ​​(NORMAL_SPEED / 2) te draaien; vertraging (duur); stopDriving();}void turnRight(int duration) { // sla rechtsaf door achteruit te gaan met het rechterwiel en vooruit met het linkerwiel digitalWrite(MR_1, LOW); digitalWrite (MR_2, HOOG); digitalWrite(ML_1, LAAG); digitalWrite(ML_2, HOOG); // vertraag om setSpeed ​​(NORMAL_SPEED / 2) te draaien; vertraging (duur); stopDriving();}void stopDriving() {// zet alle motorpinnen uit digitalWrite(MR_1, LOW); digitalWrite (MR_2, LAAG); digitalWrite(ML_1, LAAG); digitalWrite (ML_2, LAAG); // niet zeker wat te doen met de ENABLE-pinnen, maar het kan geen kwaad om ze ook uit te schakelen, denk ik digitalWrite (MR_ENABLE, LOW); digitalWrite(ML_ENABLE, LOW);}void setSpeed(int speed) {// speed moet tussen 0 en 255 liggen speed =constrain(speed, 0, 255); // stel de snelheid in om de motoren aan te zetten analogWrite (MR_ENABLE, snelheid); analogWrite(ML_ENABLE, speed);}void randomTurn(int minimum, int maximum) { unsigned long time =millis(); int duur =willekeurig (minimum, maximum); if (tijd % 2) { turnRight (duur); } else { turnLeft(duur); }}void playHallo() { tone(BUZZER, 262, 250); // speelt C4 vertraging (300); toon (ZOEMER, 330, 250); // speelt E4 vertraging (300); toon (ZOEMER, 392, 250); // speelt G4-vertraging (300); toon (ZOEMER, 523, 500); // speelt C5 delay(550);}void playUhOh() { tone(BUZZER, 523, 250); // speelt C5 vertraging (300); toon (ZOEMER, 415, 500); // speelt Gis4 delay (600);}

Schema's

Betekenis van de kabelkleuren:
rood =spanning (positief)
zwart =aarde (negatief)
geel =signaal voor infraroodsensor
oranje en groen =aansluitingen voor rode en groene LED-ingang
paars =motorrichtingsregeling
blauw =motortoerentalregeling (helaas had het Fritzing-gedeelte niet de twee pinnen die mijn motorbrug had voor deze verbindingen, dus het lijkt op dit moment op losse draden) wall-e2_3P6X71BCnP.fzz

Productieproces

  1. CO2-monitoring met K30-sensor
  2. Doofblinde communicatie met 1Sheeld/Arduino
  3. Bedien muntvangers met Arduino
  4. Geautomatiseerde Lego Shooter
  5. Obstakels vermijden robot met servomotor
  6. Arduino met Bluetooth om een ​​LED te bedienen!
  7. Capacitieve vingerafdruksensor met een Arduino of ESP8266
  8. Lijnvolger Robot
  9. Spelen met Nextion Display
  10. Nunchuk-gestuurde robotarm (met Arduino)
  11. Besturing van servomotor met Arduino en MPU6050