Uw Arduino 4x4x4 LED-kubus programmeren om nog meer leuke dingen te doen
Vorige week heb ik een LED-kubus gebouwd. Hoe maak je een pulserende Arduino LED-kubus die eruit ziet alsof hij uit de toekomst is gekomen Hoe maak je een pulserende Arduino LED-kubus die eruit ziet alsof hij uit de toekomst kwam Als je met enkele Arduino-beginnersprojecten hebt gewerkt , maar zijn op zoek naar iets een beetje permanent en op een heel ander niveau van geweldig, dan is de nederige 4 x 4 x 4 LED-kubus ... Lees meer - 64 leds dat je kunt programmeren om fantastische futuristische lichtshows te maken - en ik hoop dat je het ook gedaan hebt, want het is een geweldig project om je te motiveren en je Arduino skillset uit te breiden. Ik liet je achter met een paar basis-apps om je aan het denken te zetten, maar vandaag zal ik een paar stukjes software presenteren die ik voor de kubus heb gemaakt, samen met code-uitleg. Het doel hiervan is zowel om je wat meer mooie lichtshows te laten zien, maar ook om meer te leren over enkele van de beperkingen van het programmeren van de kubus, en een aantal nieuwe programmeerconcepten te leren in het proces.
Dit is een behoorlijk geavanceerde codering; je moet echt al mijn eerdere Arduino-tutorials en onze Arduino-beginnersgids hebben gelezen voordat je de code aanpast.
App 1: Mini Snake
In plaats van een reeks slangachtige patroonsequenties uit te voeren, wilde ik een slang programmeren - een kunstmatige - die zijn eigen willekeurige keuzes zou maken en volledig onvoorspelbaar zou zijn. Het is beperkt tot slechts 2 segmenten, die ik later zal uitleggen, en je kunt de demo hieronder bekijken. Download de volledige code hier.
Als je te maken hebt met 3D-ruimte, heb je 3 coördinaten nodig voor één punt: X, Y, en Z.
In onze kubus worden de X- en Z-vlakken echter weergegeven met LED-pinnen, terwijl de Y rechtstreeks wordt toegewezen aan de kathodevlakken. Om het werken met deze coördinaten te vergemakkelijken en bewegingen rond de kubus uit te zoeken, heb ik daarom een nieuw datatype gemaakt (met behulp van struct) om een enkel punt op de kubus weer te geven - die ik heb gebeld “xyz”. Het bestaat uit slechts twee gehele getallen: “xz”, en “Y”. Met deze structuur zou ik dan ook een richting kunnen weergeven, hieronder aangegeven in ons speciale (xz, y) coördinatensysteem:
Y beweging (op neer): (xz, y + 1), (xz, y-1)
Z beweging (vooruit, terug): (xz-1, y), (xz + 1, y)
X beweging (links rechts): (xz + 4, y), (xz-4, y)
Bijvoorbeeld om de LED in positie te verplaatsen (0,0) één naar links, we zijn van toepassing (xz + 4, y) en eindigen met (0,4).
Er zijn bepaalde limieten die aan beweging worden gesteld - namelijk dat Y-coördinaten alleen maar mogelijk zijn 0 tot 3 (Waarbij 0 de onderste laag is, waarbij 3 de bovenkant is), en XZ-coördinaten kunnen dat alleen zijn 0 tot 15. Een verdere limiet wordt op de Z-beweging geplaatst om te voorkomen “jumping” van de achterkant naar de voorkant van de kubus, en omgekeerd. In dit geval gebruiken we de modulusfunctie om te testen op veelvouden van 4 en die bewegingspoging te ontkennen. Dit is logica is vertegenwoordigd in de Geldig() functie, die een true oplevert als de voorgestelde richting een acceptabele zet is en anders false. Ik heb nog een functie toegevoegd om te controleren op een omgekeerde richting - dat wil zeggen, als de slang in de ene richting gaat, willen we niet dat hij zichzelf terugtrekt, ook al is het anders een geldige locatie om naar toe te gaan - en een bewegen () functie, die een coördinaat, een richting neemt en de nieuwe coördinaat retourneert.
De XYZ data type, Geldig(), bewegen () en inverse () functies zijn allemaal te vinden in de xyz.h bestand in de downloads. Als je je afvraagt waarom dit in een apart bestand is geplaatst in plaats van het hoofdprogrammabestand, dan is dit te wijten aan enkele gecompliceerde Arduino-compileerregels die functies voorkomen aangepaste datatypes retourneren; ze moeten in hun eigen bestand worden geplaatst en vervolgens worden geïmporteerd aan het begin van het hoofdbestand.
Terug in het hoofdruntime-bestand slaat een reeks richtingen alle mogelijke bewegingen op die de slang kan maken; we kunnen eenvoudig een willekeurig arraylid kiezen om een nieuwe richting te krijgen. Variabelen worden ook gemaakt om de huidige locatie (nu), de vorige op te slaan richting en vorige plaats. De rest van de code zou voor u vrij duidelijk moeten zijn; gewoon fOr-lussen en het in- en uitschakelen van LED's. In de hoofdlus controleren we of de voorgestelde richting geldig is en als dat het geval is, gaan we die kant op. Zo niet, dan kiezen we een nieuwe richting.
Het enige dat in de hoofdlus moet worden aangegeven, is een aantal controles om een bug te corrigeren die ik bij multiplexen tegenkwam: als de nieuwe locatie zich op hetzelfde kathodevlak of dezelfde anodepen bevond, zou het uitschakelen van de vorige LED resulteren in beide uitgangen. Het is ook op dit punt dat ik me realiseerde dat verder gaan dan een slang met 2 segmenten onmogelijk zou zijn met mijn huidige implementatie: probeer 3 LED's in een hoekopstelling op te lichten. Dat kun je niet, want met 2 lagen en 2 LED's worden pinnen geactiveerd, 4 LED's gaan branden, niet 3. Dit is een inherent probleem met ons beperkte gemultiplexeerde kubusontwerp, maar maak je geen zorgen: we moeten gewoon de kracht van doorzettingsvermogen van visie om de tekenmethode te herschrijven.
Persistentie van zicht houdt in dat wanneer licht ons oog sequentieel bereikt - sneller dan dat we het kunnen verwerken - het een enkel beeld lijkt te zijn. In ons geval moeten we in plaats van alle vier de lagen tegelijk te tekenen, de eerste tekenen, deactiveren, de tweede tekenen en deactiveren: sneller dan we kunnen zien dat er zelfs maar iets verandert. Dit is het principe waarop berichtenschrijvers werken, zoals deze:
Nieuwe tekenmethode met behulp van Persistence of Vision
Allereerst een nieuwe tekenroutine. Ik heb een gemaakt 4 x 16 tweedimensionale array van bits (waar of onwaar) om een letterlijke weergave te zijn van de toestand van de LED-kubus. De trekkingsroutine implementeert persistentie van het gezichtsvermogen door dit eenvoudig te herhalen en elke laag even uit te spoelen naar de kubus. Hij blijft zichzelf in de huidige status tekenen totdat de verversingstijd is verstreken, waarna we de besturing weer teruggeven aan de hoofdlus (). Ik heb dit gedeelte van de code in dit LED_cube_POV-bestand opgeslagen, dus als je gewoon wilt beginnen met het programmeren van je eigen games en dergelijke, voel je dan vrij om dit als basis te gebruiken.
App 2: Game of Life
Laten we dit voorlopig ontwikkelen tot een basisversie van Conway's Game Of Life. Voor degenen onder u die onbekend zijn (probeer Googlen om een geweldige paasei-animatie te vinden), de Spel van het leven is een voorbeeld van cellulaire automaten die een fascinerend patroon van emergent gedrag creëren, gegeven slechts een paar eenvoudige regels.
Dit is bijvoorbeeld hoe mieren lijken te bewegen met intelligentie en een bijenkorfgeest, ondanks het biologische feit dat ze feitelijk gewoon heel basale hormonale regels volgen. Hier is de volledige code om te downloaden: druk op de reset knop om opnieuw op te starten. Als je merkt dat je steeds hetzelfde patroon krijgt, probeer dan de rustknop langer ingedrukt te houden.
Hier zijn de regels van het spel van het leven:
- Elke levende cel met minder dan twee live buren sterft, alsof veroorzaakt door onderpopulatie.
- Elke levende cel met twee of drie levende buren leeft voort op de volgende generatie.
- Elke levende cel met meer dan drie live buren sterft als door overbevolking.
- Elke dode cel met precies drie levende buren wordt een levende cel, als door reproductie.
Voer de code uit. Je zult het binnen 5 tot 10 opmerken “generaties”, de automaten zijn waarschijnlijk tot rust gekomen, zich stabiliserend op een bepaalde positie; soms verandert dit stabiele patroon van locatie en verschuift het over het bord. In zeldzame gevallen kunnen ze zelfs volledig zijn uitgestorven. Dit is een beperking van het hebben van alleen 4x4x4 LED's om mee te werken, maar het is sowieso een goede leeroefening.
Om de code uit te leggen:
- Je bent misschien onbekend met memcpy () functie. Ik heb dit gebruikt om de vorige spelstatus op te slaan, omdat arrays niet als normale variabelen aan elkaar kunnen worden toegewezen - je moet de geheugenruimte daadwerkelijk kopiëren (in dit geval 64 bits).
- howManyNeighbours () De functie moet voor zichzelf spreken, maar als dit niet het geval is, neemt deze methode een enkele coördinaat en loopt deze door elke mogelijke buur (dezelfde reeks richtingen die we eerder in de slang-app hebben gebruikt) om te controleren of ze geldig zijn. Vervolgens wordt gecontroleerd of die buur-LED's in de vorige spelstatus 'aan' waren en telt het aantal.
- De belangrijkste functie van deze Game of Life-app is progressGame (), die de automataregels toepast op de huidige speltoestand.
verbeteringen: Ik heb er tot nu toe veel te lang over gedaan, maar misschien wil je proberen een cheque toe te voegen waarmee het bord automatisch na 5 generaties van hetzelfde patroon opnieuw wordt ingesteld. laat het me dan weten! Ik zou ook voorstellen om de POV-methode toe te voegen aan het slangenspel om hopelijk een langere slang mogelijk te maken.
Dat is het vandaag van mij. Ik zou op een later tijdstip nog een aantal Arduino LED-kubus-apps kunnen bezoeken, maar hopelijk zou je in staat moeten zijn mijn code aan te passen en je eigen spelregels te maken: laat ons weten wat je verzint in de reacties, zodat we allemaal kunnen downloaden jouw creaties! Zoals altijd zal ik hier zijn om je vragen te beantwoorden en mijn verschrikkelijke codeervaardigheden te verdedigen.
Beeldcredits: cartesische coördinaten - Wikimedia-gebruiker Sakurambo
Ontdek meer over: Arduino.