Offline
Jr. Member
Karma: 0
Posts: 56
|
 |
« on: December 18, 2012, 01:26:11 pm » |
Hallo, Ik had thuis nog een NES controller liggen en met behulp van deze thread heb ik hem aan de praat gekregen. http://arduino.cc/forum/index.php/topic,8481.0.html#0Alleen ik zit met een praktisch probleem Als ik de toetsen indruk dan krijg ik de volgende codes: 01111111 =A 10111111 =B 11011111 =Select 11101111 =Start 11110111 =Up 11111011 =Down 11111101 =Left 11111110 = Right Simpel gezegd de "0"verplaatst zich. Op zich is dit niet moeilijk hier kan ik simpele if-voorwaarden aan hangen. Alleen als ik 2 toetsen indruk dan krijg ik 2 nulletjes, is op zich heel verklaarbaar, maar wat moet ik ermee? Moet ik nu alle mogelijkheden uitschrijven of zijn er simpelere oplossingen? Soort van optellen. Heeft iemand informatie hoe ik hiermee moet werken of waar ik dit kan vinden? Van handige tips sites of zoekwoorden? Ik loop hier namelijk vaker tegenaan. Alvast bedankt
|
|
|
|
|
Logged
|
|
|
|
|
Netherlands
Online
Tesla Member
Karma: 87
Posts: 9386
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #1 on: December 18, 2012, 03:35:52 pm » |
je moet leren bit-masks te gebruiken - http://playground.arduino.cc/Code/BitMath - void loop() { int x = readNes(); // dit weet je blijkbaar hoe dat moet
x = ~x; // klap alle bitje om 0->1 en vice versa
if ( x & b00000001) Serial.println("Right"); if ( x & b00000010) Serial.println("Left"); if ( x & b00000100) Serial.println("Down"); if ( x & b00001000) Serial.println("Up"); if ( x & b00010000) Serial.println("Start"); if ( x & b00100000) Serial.println("Select"); if ( x & b01000000) Serial.println("B"); if ( x & b10000000) Serial.println("A"); }
ipv Serial.println("A"); kun je natuurlijk ook een functie aanroepen handleKeyA();
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 56
|
 |
« Reply #2 on: December 18, 2012, 04:17:41 pm » |
Allereerst bedankt voor je reactie
Interessant stukje tekst, ik snap nog niet alles, maar dat komt denk ik wel met de tijd.
Even over je code. Jouw if ( x & b00000010) regel zegt eigenlijk:
kijk of het signaal aan de volgende voorwaarde voldoet (er zit een 2 in) en daarom doe jij actie "left"
Dus als hij het signaal B10000010 ontvangt dan zal hij zowel "a"als de actie "left" uitvoeren.
Ik heb de code zojuist geïmplementeerd en hij werkt, dank je wel! ik kan weer verder
|
|
|
|
« Last Edit: December 18, 2012, 04:31:44 pm by Nald »
|
Logged
|
|
|
|
|
Netherlands
Online
Tesla Member
Karma: 87
Posts: 9386
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #3 on: December 19, 2012, 01:06:08 am » |
kijk of het signaal aan de volgende voorwaarde voldoet (er zit een 2 in) en daarom doe jij actie "left" if ( x & b00000010) preciezer, de & (= AND ) operatie gaat de bytes bit voor bit vergelijken volgens de AND waarheidstabel. Deze zegt als beide bits 1 zijn is de output 1 bv 01010000 & b00000010 -> 00000000 11111101 & b00000010 -> 00000000 00001111 & b00000010 -> 00000010 Het if(...) statement interpreteert alle waarden groter dan 0 als true, dus als er na de AND een bitje 1 is, evalueert de expressie naar true correcter zou zijn geweest if ( (x & b00000010) == b00000010 ) .... want dan heb je echt een boolean expressie die true of false is ipv een impliciet geinterpreteerde integer Bitmasks worden ook gebruikt als je met timers of IO registers werkt. Sommige bewerkingen/berekeningen kun je versnellen dmv bitmanipulatie. Zie bv - http://graphics.stanford.edu/~seander/bithacks.html - voor mooie en soms "onbegrijpbare" voorbeelden.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 56
|
 |
« Reply #4 on: December 19, 2012, 11:29:25 am » |
Die 2e uitleg maakt het wel wat ingewikkelder. Maar met een beetje spelen kwam ik erachter dat bepaalde toetsencombinaties (bv start + up) een code generen die gelijk staat aan een andere knop (in dit voorbeeld B) ik kan dit niet terughalen uit de seriële monitor. maar ik zie dit terug in de acties via mijn code. Dit terwijl up nog geen taak toegewezen heeft gekregen. Zou dit kunnen door die rekenregels, of zit er hoogstwaarschijnlijk een error in de controller zelf. Is het trouwens mogelijk om van onderstaand stukje code van de Delay stukjes af te komen, hierdoor werken gedeeltes van mijn huidige code niet altijd even goed. void controllerRead() { controller_data = 0; IOexp.digitalWrite(1,2 ,LOW); IOexp.digitalWrite(1,1 ,LOW);
IOexp.digitalWrite(1,2 ,HIGH); delayMicroseconds(2); IOexp.digitalWrite(1,2 ,LOW);
controller_data = IOexp.digitalRead(1,0);
for (int i = 1; i <= 7; i ++) { IOexp.digitalWrite(1,1 ,HIGH); delayMicroseconds(2); controller_data = controller_data << 1; controller_data = controller_data + IOexp.digitalRead(1,0) ; delayMicroseconds(4); IOexp.digitalWrite(1,1 ,LOW); }}
|
|
|
|
|
Logged
|
|
|
|
|
Netherlands
Online
Tesla Member
Karma: 87
Posts: 9386
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #5 on: December 19, 2012, 02:44:42 pm » |
(bit manipulaties is vooral proberen om te kijken hoe het werkt) mbt code Om te beginnen probeer een consequente inspring styl te hanteren om de boel leesbaarder te houden. Spaties kosten (vrijwel) niets. Verder zijn het delay microseconds die waarschijnlijk nodig zijn om de chips op je IOexpansie bordje (oid) de tijd te geven om de juiste signalen klaar te zetten. ALs je de specificatie van het bordje hebt kun je zien of en hoe groot evt delays moeten zijn. De initialisatie op 0 van controller_data is niet nodig omdat de eerste digitalread die waarde weer overschrijft. Je kunt de for loop waarschijnlijk optimaliseren zodat het lezen van de eerste bit ook in de loop zit. Verder zou je de functie de waarde van de ingelezen bits terugkunnen laten geven omdat ik niet weet wat de digitalwrites doen is een enkele regel commentaar hier wel op zijn plaats. int controllerRead() { // .... IOexp.digitalWrite(1, 2, LOW); IOexp.digitalWrite(1, 1, LOW);
// ... IOexp.digitalWrite(1, 2, HIGH); delayMicroseconds(2); IOexp.digitalWrite(1, 2, LOW);
// READ 8 DATABITS TO SEE BUTTONS int controller_data = IOexp.digitalRead(1 ,0); for (int i = 1; i <= 7; i ++) { IOexp.digitalWrite(1, 1, HIGH); delayMicroseconds(2); controller_data = controller_data << 1; controller_data = controller_data + IOexp.digitalRead(1, 0) ; delayMicroseconds(4); IOexp.digitalWrite(1, 1, LOW); } return controller_data; }
// aanroep voorbeeld buttons = controllerRead();
2 cents,
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 56
|
 |
« Reply #6 on: December 19, 2012, 02:55:10 pm » |
Dit is niet mijn code, deze heb ik eerlijk gekopiëerd (voor bron zie startpost)
Omdat ik te weinig pinnen heb, gebruik ik een pinExpander en die stuur ik aan via een library Dus de 1,1, en de 1,2, en de 1,0 slaan op de poorten
DE e 1,0 is de input de 1,1, de clock en de 1,2 de latch pin
Dat is alles wat ik weet van de code
|
|
|
|
|
Logged
|
|
|
|
|
Netherlands
Online
Tesla Member
Karma: 87
Posts: 9386
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #7 on: December 19, 2012, 03:28:47 pm » |
maar heb je een link naar de library? daar staat wellicht wat documentatie over de expander.
Verder kun je altijd proberen de waarden te verminderen van de delays (kleiner dan 1 heeft geen zin) en kijken of het nog werkt.
|
|
|
|
|
Logged
|
|
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 56
|
 |
« Reply #9 on: December 21, 2012, 01:59:18 pm » |
Blijkbaar heeft de pinexpander toch invloed op de lezing, af en toe kreeg ik toch een soort ruis te zien. volgens de seriele poort kreeg ik geen opdrachten binnen en werden de uitgaande pinnen niet bekrachtigd. In de praktijk werden deze uitgangen om de 1 of andere reden wel bekrachtigd.
Nu heb ik de pin die uitgelezen wordt samen met de clockpin weer op de arduino gezet ben ik (tot nu toe) alle ruis kwijt. (de ruis werd niet veroorzaakt door bouncen, want de alle knoppen heb ik gedebounced met een halve seconde, ik denk dat ik die nu ga verkleinen.)
Maar heeft iemand nog een suggestie hoe ik van die akelige delays af kan komen?
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
Hamme, Belgium
Offline
Sr. Member
Karma: 3
Posts: 383
|
 |
« Reply #10 on: January 10, 2013, 02:51:08 pm » |
Bestuur het voorbeeld blink without delay om van delays af te komen.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 56
|
 |
« Reply #11 on: January 10, 2013, 03:31:02 pm » |
die ken ik wel, maar werkt dat ook met microsecondes? En hoe nauwekeurig is dat, want zelfs bij de millis() heb je met een if statement, de ene keer x+1 en de andere keer x en weer een andere keer x-2 millis() Ps. andere vraag, heeft zo'n arduino ook een soort "werkgeheugen" ik heb het idee als ik bepaalde delen van mijn code selectief laat werken (dus dat de arduino niet constant naar alle parameters kijkt) dat hij dan vloeiender verloopt. void loop(){ if (knop A==HIGH){ deel 1(); deel 2(); deel 3();}
else { deel 4(); deel 5(); }}
|
|
|
|
|
Logged
|
|
|
|
|
Netherlands
Online
Tesla Member
Karma: 87
Posts: 9386
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #12 on: January 10, 2013, 03:55:54 pm » |
Ja, blink without delay werkt ook met microseconden want zelfs bij de millis() heb je met een if statement, de ene keer x+1 en de andere keer x en weer een andere keer x-2 millis() Kun je een sketch posten om dat aan te tonen?
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
Hamme, Belgium
Offline
Sr. Member
Karma: 3
Posts: 383
|
 |
« Reply #13 on: January 10, 2013, 04:23:37 pm » |
heeft zo'n arduino ook een soort "werkgeheugen" SDRAM en bij een uno is dat 2KB
|
|
|
|
|
Logged
|
|
|
|
|
|
|
|