werken met binaire getallen.

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#0

Alleen 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

je moet leren bit-masks te gebruiken - Arduino Playground - 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();

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

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 - Bit Twiddling Hacks - voor mooie en soms "onbegrijpbare" voorbeelden.

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);
}}

(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,

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

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.

eigenlijk wil ik alle delays eruit hebben. Ik voer namelijk tegelijkertijd ook metingen uit.

Maar wat heeft de delay te maken met de pinexpander?

https://iprototype.nl/docs/mcp23016_datasheet.pdf pdf pinexpnader
http://thefreeduality.tk/stuff/IOexpander.tar.gz library

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?

Bestuur het voorbeeld blink without delay om van delays af te komen.

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();
}}

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?

heeft zo'n arduino ook een soort "werkgeheugen"

SDRAM en bij een uno is dat 2KB

robtillaart:
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?

http://arduino.cc/forum/index.php/topic,46351.0.html