Stap 3: Prototype op breadboard + testprogramma
Natuurlijk wilde ik weten of dit allemaal haalbaar is, is dus ik moest een paar dingen te testen. Ten eerste, het programmeren van de ATmega zonder de klok; en ten tweede, het testen van de 3 x 8 LED multiplexing.
Om te beginnen, controleerde ik de gids op de Arduino website op hoe te programmeren een standalone ATmega die is vrij uitgebreid en werken allermeest naar de tijd. Er zijn 2 belangrijke stappen: met behulp van een Arduino branden als een programmeur de bootloader, en vervolgens uploaden van het programma. Er is een vangst, echter, dat wil zeggen als u een ATmega-chip die werd al geconfigureerd voor gebruik van een externe klok (b.v. een Arduino onttrokken), dan de enige manier om deze chip program is bedoeld als een externe kloksignaal op XTAL1. Zelfs als u configureren een chip wilt voor het gebruik van de interne klok later, is dit een noodzakelijke stap, voordat u iets kunt doen. Dus er twee opties zijn: een kristal verbinden met de ATmega; of hebt u niet van een kristal, u kunt ook het ArduinoISP2 programma van Adafruit die eigenlijk een kloksignaal op pin 9 zal genereren. Op het einde ik deze optie hebt gekozen, omdat ik niet een vrije kristal die ik kon gebruiken. Na het configureren van een chip voor het gebruik van de interne klok, het kan zo geprogrammeerd worden zonder een externe kristal, omdat ook de juiste zekeringen branden de bootloader ingesteld.
Nadat de bootloading gewerkt, bouwde ik een klein prototype op breadboard met slechts 12 LEDs, gewoon om te zien hoe de multiplexing zou werken. Eerst probeerde ik het met de digitalWrite() functie, maar het bleek te traag, dus ik moest veranderen en de registers van de pin niet rechtstreeks instellen. Dit is een beetje omslachtig, maar gelukkig is zeer goed gedocumenteerd op de website van Arduino.
Ten eerste moeten enkele globale variabelen worden gedefinieerd:
const int NR_ANODE = 3; const int NR_CATHODE = 4; // pin choice only depends on how the LEDs are wired up to the controller const int anodePins[NR_ANODE] = { 3, 4, 5 }; // Arduino pins 3, 4, 5 const int cathodePins[NR_CATHODE] = { 7, 6, 1, 0 }; // Arduino pins 7, 6, 1, 0 // pins 3 4 5 const int anodeBits = B00111000; // pins 6 7 0 1 const int cathodeBits = B11000011; unsigned long int loopCounter = 0;
En een matrix voor het opslaan van de helderheidswaarden van LED:
int val[NR_ANODE][NR_CATHODE] = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } };
Klik vervolgens in de hoofdlus, de loopCounter aan elke iteratie is verhoogd, en de rest door 50 is ten opzichte van elk element van de matrix van de waarde , die bepalend zullen zijn als de LED in- of uitschakelen voor dat iteratie is. Ik koos voor 50, omdat het nog werkte zonder enige flikkeren en gaf al een fijn genoeg resolutie voor wat ik nodig had.
rem = loopCounter % 50; i = loopCounter % NR_ANODE; // at every iteration use a different anode // turn cathode pins high, this will turn off all LEDs PORTD = PORTD | cathodeBits; // turn anode pins low PORTD = PORTD & ~anodeBits; // turn anode_pins[i] high - select row i PORTD = PORTD | (1 << (3+i)); // turn cathode pins low if rem >= corresponding val PORTD = PORTD & ~(( (rem < val[i][0]) << cathodePins[0]) | ( (rem < val[i][1]) << cathodePins[1]) | ( (rem < val[i][2]) << cathodePins[2]) | ( (rem < val[i][3]) << cathodePins[3]) ); loopCounter++;
Op dit punt probeerde ik het programma door het schrijven van vaste waarden in de matrix van de val te zien of het werkt zonder ieder uitvaardiging, en toen ik blij mee ben ik het PCB-design begonnen, omdat ik wist productie enige tijd zou duren en ik kon het afmaken van de rest van het programma vervolgens.