Created
October 3, 2014 19:09
-
-
Save EnDagiSaender/9d333810d5691cf6b386 to your computer and use it in GitHub Desktop.
neopixel in STTNG pinball mod (swedish comments)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Byggt med en arduino Nano v.3 | |
Läser av pin 0-7 (PB0..PB7) som är kopplade till lamporna för alla 7 modes samt finale frontier. | |
Lyser en lampa jordas pinnen kopplad till den lampan via en optokopplare samt är den släkt | |
hålls pinnen hög mha en pullup resistorn i mikroprossesorn. Tänds eller släcks en lampa | |
skapar det en interupt, i interruptrutinen ISR (PCINT2_vect) sparas vilka lampor som tänts i state1, | |
samt ökar räknaren count, som triggas i main loopen när lamp matrisen gått igenom minst ett varv. | |
när räknaren gått 2 varv jämförs vilka lampor som varit tända med föregående varv. På så vis får | |
man reda på vilken lampa som blinkar, dvs vilket mode som är aktivt. Sedan kollas ifall pixlarna | |
har rätt färg, annars byts det till den färgen. Nackdelen med att jämföra med vilken lampa som | |
ändrat sig jämt emot föregående varv är ifall man inte startat något mode och bara en lampa blinkar, | |
då är det ingen lampa som ändrats mellan varven och därför är en räknare (onemodechange) tillagd. Den ökar | |
för varje varv som enbart en lampa lyser och nollställs ifall fler gör det. Om den inte nollställts | |
på mer än 2 varv så byter den till den ensama lampans färg. Varför den inte byter direkt är tack vare | |
senariot då 2 lampor är aktiva (en lyser och en blinkar). då den blinkande är släkt hinner den lysande | |
leverera fler än 13 interrupts (ett varv) och då skulle isf pixlarna blinka fram och tillbaka mellan | |
de färgerna. | |
/Erik Fagerberg (FGR) | |
*/ | |
#include <Adafruit_NeoPixel.h> | |
#define PIN 10 // styr alla leds med pinne D10 | |
Adafruit_NeoPixel strip = Adafruit_NeoPixel(8, PIN, NEO_GRB + NEO_KHZ800); | |
volatile int count = 0; //(varv)Räknare för varje gång någon pinne går hög/låg mer än 13 gånger | |
int onemode = 0; //räknare för hur många lampor som är tända | |
int onemodechange = 0; // Räknare för varje varv som enbart 1 lamppa varit tänd | |
volatile byte state1; // Sparar vilka lampor som varit tända | |
byte state2, state3; // Sparar nuvarand samt föregående varv av vilka lampor som varit tända | |
byte chkmode; // Jämför state2,3 för att se vilka lampor som ändrats | |
int color = 0; //variabeln för att bestämma vilken färg i arrayen som ska användas | |
//array med de 8 olika RGB färgerna för varje mode | |
uint32_t mode[8] = { | |
strip.Color(0, 73, 255), // Blå, Search the galaxy | |
strip.Color(27, 0, 255), // Lila, Worm hole | |
strip.Color(255, 0, 255),// Rosa, Time rift | |
strip.Color(255, 0, 0), // Röd, Finale frontier | |
strip.Color(255, 95, 0), // Orange, Asteroid threat | |
strip.Color(255, 255, 0),// Gul, Rescue | |
strip.Color(0, 255, 69), // Turkos, Battle simulation | |
strip.Color(0, 255, 0)}; // Grön, Q´s | |
ISR (PCINT2_vect) //interrupt vektor för när någon av pinnarna 7..0 ändras | |
{ | |
cli(); // stänger av alla inteupts | |
// läser av statusen på 7..0 och nollar de bitar för respektive pin där en lampa varit | |
// tänd och sparar det i state1 | |
state1 &= PIND; | |
count++; // räknar upp hur många interrupts som varit | |
sei(); // sätter på interrupts igen | |
} | |
void setup() | |
{ | |
/* | |
stänger av lite saker i prossesorn som inte programmet använder | |
så den drar lite mindre ström tex olika seriella komunikationer och analoga | |
till digitala omvandlare. Ser till att RX,TX (D0,D1) inte tror att den ska | |
komunicera med usb. | |
*/ | |
ADCSRA = 0; | |
PRR = B10010111; | |
UCSR0B = 0; // stänger av usart. behövs nog inte iom att det görs i | |
// raden ovanför men vill inte riskera att RX,TX kukar ur | |
DDRD = 0b00000000; // Sätter pin 7..0 till ingångar | |
PORTD = 0b11111111; // Ansluter pullup resistor på pin 7..0 | |
state1 = 0b11111111; //sätter lite default startlägen, alla lampor släckta | |
state2 = 0b11111111; | |
state3 = 0b11111111; | |
chkmode = 0b00000000; | |
PCMSK2 = 0b11111111; // sätter att interrupts ska triggas på alla pinnar 7..0 | |
PCICR |= (1<<PCIE2); // vilken port interrupts ska triggas på, den med pin 7..0 (D) | |
strip.begin(); // startar igång neopixlarna | |
strip.setPixelColor(0, mode[0]); //sätter första pixeln för att visa att programmet startat | |
strip.show(); // tänder upp pixeln blå | |
} | |
void loop() | |
{ | |
if (count > 13){ //efter fler än 13 interrupts, det jag kallar för ett varv | |
// Stänger så att inte interrupts triggas på pin 7..0 tills alla ändringar i loopen är gjorda | |
PCICR = 0b00000000; | |
state2 = state1; // sparar state1 som används i interruptsen som state2 | |
chkmode = (state2 ^ state3); // sparar vilka pinnar som ändrats mellan varven | |
/* | |
Går igenom och kollar hur många lampor som varit tända, för att ta reda på ifall det | |
enbart är en lysande lampa. | |
*/ | |
onemode = 0; | |
for(int i=0; i<8; i++){ | |
if (!(bitRead(state2,i))) onemode++; //kollar om en lampa är tänd, isf öka onemode | |
} | |
// Om och endast om en lampa varit tänd, öka varvräknaren onemodechange | |
if (onemode == 1) onemodechange++; | |
else onemodechange = 0; // Om fler än en lampa varit tänd, nollställ | |
// Om det gått mer än 2 varv och endast en lampa varit tänd, sätt state2 som senare blir | |
// state3 som om alla lampor vore släckta samt nolla onemodechange vliket får | |
// konsekvensen att nästa varv kommer den ensama blinkande lampan se ut som den | |
// förändrats och pixlarna kan byta färg | |
if (onemodechange > 2){ | |
state2 = 0b11111111; | |
onemodechange = 0; | |
} | |
/* | |
kollar ifall och isf vilken lampa som ändrats och då sätter den color till | |
rätt färg och nollställer räknaren onemodechange. | |
*/ | |
for(int i=0; i<8; i++){ | |
if (!(chkmode ^ (0b10000000 >> i))) { // samma som att skriva if (chkmode == (0b10000000 >>i)) | |
color = i; | |
onemodechange = 0; | |
} | |
} | |
// Kollar om pixlarnas nuvarande färg är samma som den valda att byta till, om inte byt till den färgen | |
if (mode[color] != strip.getPixelColor(0)){ | |
for(int i=0; i<8; i++){ //loop för att sätta de 8 pixlarna till rätt färg | |
strip.setPixelColor(i, mode[color]); | |
} | |
strip.show(); // tänder upp pixlarna | |
state2 = 0b11111111; // nollställer så att den inte byter fram och tillbaka mellan föregående | |
} // och nya färgen | |
state3 = state2; // sparar nuvarande state för att göra jämförelse nästa varv | |
state1 = 0b11111111; // nollställer variabeln för kollen av vilka lampor som varit tända | |
count = 0; // nollställer varvräknaren | |
PCICR = 0b00000100; // sätter på interrupts på pin 7..0 igen | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment