Pages: [1]   Go Down
Author Topic: werken met binaire getallen.  (Read 2694 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 79
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 227
Posts: 14024
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


je moet leren bit-masks te gebruiken - http://playground.arduino.cc/Code/BitMath -

Code:

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

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Offline Offline
Jr. Member
**
Karma: 0
Posts: 79
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 227
Posts: 14024
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Offline Offline
Jr. Member
**
Karma: 0
Posts: 79
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

Code:
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

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 227
Posts: 14024
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

(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.
Code:
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

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Offline Offline
Jr. Member
**
Karma: 0
Posts: 79
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 227
Posts: 14024
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Offline Offline
Jr. Member
**
Karma: 0
Posts: 79
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 79
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Sr. Member
*****
Karma: 4
Posts: 390
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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


Offline Offline
Jr. Member
**
Karma: 0
Posts: 79
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

Code:
void loop(){
 if (knop A==HIGH){
deel 1();
deel 2();
deel 3();}

else
{
deel 4();
deel 5();
}}
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 227
Posts: 14024
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ja,
 blink without delay werkt ook met microseconden

Quote
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

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Forum Moderator
Hamme, Belgium
Offline Offline
Sr. Member
*****
Karma: 4
Posts: 390
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
heeft zo'n arduino ook een soort "werkgeheugen"

SDRAM en bij een uno is dat 2KB
Logged


Offline Offline
Jr. Member
**
Karma: 0
Posts: 79
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ja,
 blink without delay werkt ook met microseconden

Quote
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://tronixstuff.wordpress.com/2011/06/22/tutorial-arduino-timing-methods-with-millis/
http://arduino.cc/forum/index.php/topic,46351.0.html
Logged

Pages: [1]   Go Up
Jump to: