Quiz Knoppen

Hoi bulldogrick, welkom !

Die laatste foto is onbruikbaar, want hoewel daar vrijwel alles op staat, is het niet te doen om te zien hoe alles verbonden is. Jouw tekening laat een aantal dingen zien.

Het eerste is dat je de LED direct wil aansluiten op pin 3 en de andere kant op de min van je voeding. Dat moet je NOOIT doen ! Je maakt daarmee namelijk zowel de LED als de Arduino kapot doordat je teveel stroom door de LED stuurt. Om dat te voorkomen moet je een weerstand gebruiken, en de beste weerstand kun je berekenen als je de eigenschappen van de LED weet, en rekening houd met de maximaal te leveren stroom per Arduino pin. Vuistregel is 220 Ohm, maar dat hoeft niet de beste waarde te zijn.

Dan de schakelaar tussen de plus, de min via een 10K weerstand, en die zal ook aan pin 2 zitten, toch ? Veel (zo niet alle) beginners zijn van mening dat een hoog signaal betekent dat er op een knop gedrukt is of dat er op andere wijze iets geactiveerd moet worden. Maar zo vanzelfsprekend is dat helemaal niet. Je Arduino biedt de mogelijkheid een interne pull up "weerstand" te activeren op een ingang. Dat betekent dat die ingang HOOG gehouden word, totdat een externe invloed er harder aan trekt en 'm LAAG maakt. Dat moet je dus wel activeren in setup, maar daarmee bespaar je je een onderdeel uit (een weerstand die je elders weer nodig hebt). En je moet dan in je code gaan kijken of die ingang LOW word in plaats van HIGH.

Ook ik zou je willen aanraden eerst 1 knop goed aan het werken te krijgen, en dan de rest pas te gaan uitwerken. Dan heb je minder aan je kop per stap.

Verder is "er klopt niets van" een niet zo heel duidelijke omschrijving. Want daar kan niemand wat mee.

De code die je laat zien, is niet erg slim gemaakt en een heel slechte code om als voorbeeld te dienen. Dat komt omdat het begint bij het gebruiken van poorten 0 en 1. Die moet je niet gebruiken tenzij je exact weet wat je aan het doen bent (en je mag aannemen dat degene die dat voorbeeld wil gaan proberen dat dus niet weet), omdat dat de pinnen zijn van de seriële verbinding. Dus voor jou: gebruik pinnen 0 en 1 voorlopig helemaal niet, dat zal je al veel problemen schelen. De code gebruikt ook functies, en ook dat is niet heel slim en/of bruikbaar voor beginners die op zoek zijn naar een leuk stukje code dat ze zelf kunnen aanpassen. In die functie word de LED bij de knop die gedrukt is 8 keer kort opgeflitst, en daarna 3 en een halve seconde aangezet. Tijdens de 4,7 seconden die dat al dan niet laten branden van de betreffende LED, word er niet gekeken naar de andere ingangen, maar ze worden ook niet geblokkeerd. Dus wanneer iemand lang genoeg de knop indrukt, en of ze allemaal de knop hebben ingedrukt, word altijd degene die na de eerste knopdrukker komt, als volgende aangewezen (niet eerlijk). Dat kan ook anders, maar zal je code wel een stuk gecompliceerder maken.

Maar nogmaals, laten we eerst eens 1 knop werkend krijgen op de manier die jij voor ogen hebt. Graag wel de volgende keer je code tussen [code]hier dus [/code] tags zetten. Dat maakt het voor ons een stuk leesbaarder en gemakkelijk te kopiëren naar een andere editor wanneer gewenst, en het voorkomt vreemde effecten (ik weet zeker dat jouw code geen smilies bevat).

Allereerst hartelijk dank voor jullie reacties ik ga vanmiddag of vanavond meteen aan de slag. Wat die weerstand tussen die led betreft dat weet ik en ben ik vergeten te tekenen. Voor de rest is het voor mij allemaal nog een wazig gebied, niet dat dat erg is hoor en ik heb de tijd, ik weet alleen dat ik echt helemaal onderaan moet beginnen en misschien is dit wel een beetje een te hoog gegrepen project?

Maar ik ga idd op jullie advies gewoon met 1 knop beginnen (eigenlijk heb ik ook in werkelijkheid maar 1 knop gebouwd en heb die op diverse poorten geprobeerd maar op poort 4 (geloof ik knippert hij een paar keer, blijft dan heel even branden en gaat dan uit en dat blijft hij doen ook al druk ik wel of niet op de knop en ook alleen maar op poort 4 verder niks.

Dat fotootje van die opgebouwde print heb ik van internet gehaald en van diezelfde persoon stond er ook deze code op dus het hoorde bij elkaar en dat was het begin van het hele project.

Maar nu heb ik 2 vraagjes

  1. Moet ik als ik 1 knop ga maken dan ook alle code eruit halen voor de andere knoppen of maakt dat niet uit?

  2. Ik weet niet of het tekeningetje verder goed is wat ik heb gemaakt en of het uberhoubt zo aan mijn arduino bordje aangesloten kan worden?

  3. Heeft er iemand toevallig een makkelijkere tekening (of kan iemand die heel simpel maken of beschrijven) van alvast 1 knop die wel goed is voor mij?

Ik ben tot dusver heel erg blij met alle hulp want nogmaals ik vind het superleuk maar ben echt een leek (fijn dat er mensen zijn zoals jullie)

beste bulldogrick,

Over je vraag:

  1. Moet ik als ik 1 knop ga maken dan ook alle code eruit halen voor de andere knoppen of maakt dat niet uit?

Code 'even op non-actief' zetten kan op twee manieren: 1. plaats // voor de instructie, bijvoorbeeld:

 // } else if (digitalRead(6) == HIGH) 
 //   playWinner(7);
 // } else if (digitalRead(8) == HIGH)
 //   playWinner(9);
  1. je kan hele blokken 'even op non-actief' zetten door /* ervoor te zetten en */ erna, bijvoorbeeld:
 /* } else if (digitalRead(6) == HIGH) 
      playWinner(7);
    } else if (digitalRead(8) == HIGH) 
      playWinner(9);
*/

Dat helpt enorm bij het ontwikkelen - debuggen van een sketch. // is verder heel handig voor commentaar bij instructies zodat lezers een idee hebben wat zo'n instructie doet of moet doen. Succes, photoncatcher

Of maak even een aparte sketch voor één knop. Het is normaal om een stuk of wat verschillende sketches te hebben om onderdelen uit te proberen, voordat de uiteindelijke sketch gemaakt wordt.

Ken je BasOnTech: https://www.youtube.com/watch?v=HKh-zfgpzGM.

Ja BasOnTech ken ik hebben mooie video's maar nog wel moeilijk Ik ga nu beginnen om een schema van 1 knop te maken met fritzing Maar wat bedoelen jullie met een sketch??? is dat de programmacode of een opzet van de componenten?

De sketch is inderdaad het programma dat je schrijft.

Ik will verder adviseren dat je de knoppen aansluit tussen pin en GND en pinMode(somePin, INPUT_PULLUP) gebruikt in setup(). Dit voorkomt dat je ingang zweeft (floating input) hetgeen gewoonlijk resulteert in varierende waardes als de knop niet is ingedrukt.

Je moet je je in dat geval wel van bewust zijn dat een ingedrukte knop als LOW leest inplaats van HIGH.

Dit is wat ik nu heb getekend en geprogrammeerd Klopt dit allemaal zo???

Quiz Knoppen_bb.png|2103x1296

Quiz Knoppen_pcb.png|1005x687

Quiz Knoppen_schema.png|1089x717

Het ziet er correct uit. Ik zie dat je een pull-down weerstand gebruikt en dat is OK; in dat geval is je logica niet omgedraaid.

Je laatste plaatje (schema) is voldoende; de andere plaatjes hebben we niet nodig (en die kun je in het vervolg weg laten).

en dit is nu mijn programma. ik weet niet of dat het zo goed is!!! waarom staat Serial.begin(9600); eigenlijk niet aan? en kan ik die wel inschakelen want waar is deze voor?

int DELAY = 3500;

void setup() {
  //Serial.begin(9600);
  pinMode(2, INPUT);
  pinMode(3, OUTPUT);
  pinMode(4, INPUT);
  pinMode(5, OUTPUT);
  pinMode(6, INPUT);
  pinMode(7, OUTPUT);
  pinMode(8, INPUT);
  pinMode(9, OUTPUT);
}

void playWinner(int pin) {
  for (int i = 0; i < 8; i++) {
    digitalWrite(pin, HIGH);
    delay(75);
    digitalWrite(pin, LOW);
    delay(75);
  }
  digitalWrite(pin, HIGH);
  delay(DELAY);
  digitalWrite(pin, LOW);
}

void loop() {
  if (digitalRead(2) == HIGH) {
    playWinner(3);
  } else if (digitalRead(4) == HIGH) {
    playWinner(5);
  } else if (digitalRead(6) == HIGH) {
    playWinner(7);
  } else if (digitalRead(8) == HIGH) {
    playWinner(9);
  }
}

Hoi Sterretje

Jij schreef:
Ik will verder adviseren dat je de knoppen aansluit tussen pin en GND en pinMode(somePin, INPUT_PULLUP) gebruikt in setup(). Dit voorkomt dat je ingang zweeft (floating input) hetgeen gewoonlijk resulteert in varierende waardes als de knop niet is ingedrukt.

betekend dat dat mijn tekening goed is maar dat ik dan in mijn sketch dus iets moet veranderen?
en zo ja wat moet er dan precies in mijn sketch komen te staan?

Yes tot dusver werkt het en...... met 4 knoppen ik heb alleen nog 1 vraag! Moet ik tussen elke knop een weerstand van 10K plaatsen of kan ik 1 weerstand van 10K in de ground van het arduino bordje plaatsen en dan aan de andere kant van de weerstand de vier knoppen plaatsen? Snappen jullie wat ik bedoel?

bulldogrick: Serial.begin(9600); [..] waar is deze voor?

Daarmee start je de seriepoort. Die is verbonden met de "serial monitor", en die open je met Tools => Serial Monitor. Er opent dan een nieuw venstertje, en daarin kun je met Serial.print() of .println() allerlei teksten en variabelen laten zien. Erg handig om het verloop van een programma te volgen, maar vooral ook voor het debuggen!

Een voorbeeld om te volgen wat er in playWinner() gebeurt:

void playWinner(int pin) {

  Serial.print("playWinner(): pin = ";  // print tekst
  Serial.println(pin);                  // print variabele 

  for (int i = 0; i < 8; i++) {  
  .. etc.

bulldogrick: Moet ik tussen elke knop een weerstand van 10K plaatsen

Ja, elke knop moet zijn eigen weerstand hebben.

dank jullie hartelijk allemaal ik ga er mee aan de slag en als ik vragen heb kom ik er weer op terug oh ja waar moet ik dat stukje programma ergens in of tussen plaatsen en is dat alle tekst of is dit voor 1 knop?

Het is te adviseren om je pinnen van te voren te definieren en logsche name te geven. Dit is aan klein programma, maar denk er eens aan wat je moet doen als je in de toekomst een schakelaar of led op een andere pin moet aansluiten (om wat voor reden dan ook)? Dan moet je door je hele code gaan om te zien waar bv 2 is gebruikt als een ingang en alles veranderen. Verder maakt het het programma makkelijker om te lezen omdat je nu weet wat de functie van de pinnen is; hieronder zijn, wat ik denk, namen gebruikt voor de pinnen die de functie reflecteren.

Aangepaste code:

const byte buttonPlayer1 = 2;
const byte buttonPlayer2 = 4;
const byte buttonPlayer3 = 6;
const byte buttonPlayer4 = 8;

const byte ledPlayer1 = 3;
const byte ledPlayer2 = 5;
const byte ledPlayer3 = 7;
const byte ledPlayer4 = 9;

int DELAY = 3500;

void setup() {
  //Serial.begin(9600);
  pinMode(buttonPlayer1, INPUT);
  pinMode(ledPlayer1, OUTPUT);
  pinMode(buttonPlayer2, INPUT);
  pinMode(ledPlayer2, OUTPUT);
  pinMode(buttonPlayer3, INPUT);
  pinMode(ledPlayer3, OUTPUT);
  pinMode(buttonPlayer4, INPUT);
  pinMode(ledPlayer4, OUTPUT);
}

void playWinner(int pin) {
  for (int i = 0; i < 8; i++) {
    digitalWrite(pin, HIGH);
    delay(75);
    digitalWrite(pin, LOW);
    delay(75);
  }
  digitalWrite(pin, HIGH);
  delay(DELAY);
  digitalWrite(pin, LOW);
}

void loop() {
  if (digitalRead(buttonPlayer1) == HIGH) {
    playWinner(ledPlayer1);
  } else if (digitalRead(buttonPlayer2) == HIGH) {
    playWinner(ledPlayer2);
  } else if (digitalRead(buttonPlayer3) == HIGH) {
    playWinner(ledPlayer3);
  } else if (digitalRead(buttonPlayer4) == HIGH) {
    playWinner(ledPlayer4);
  }
}

Niet getest ;)

Als je nu een led of schakelaar naar een andere pin moet verhuizen is het een kwestie van het aanpassen op een (1) plek. Het 'const' keyword geeft aan dat de variabele niet kan worden veranderd in het programma. Als je b.v. later in je programma probeert om een nieuwe waarde aan bv ledPlayer1 te geven zal de compiler daar over klagen.

Verder, niet zo relevant in dit geval omdat je programma klein is en weinig RAM geheugen gebruikt, maar als je ooit aan grotere programmas gaat werken kan elke byte tellen. Daarom zijn de variabelen voor de pinnen van het type 'byte' en niet van het type 'int'.

Daarna kun je overwegen om je programma verder te optimaliseren. Als je variabelen hebt die genummerd zijn zou je eigenlijk arrays moeten gebruiken. Een array kun je zien als een ladenkast en in iedere la plaats je een pin nummer. Je kunt dan door het array itereren met een for-loop om iets met een pin te doen. In onderstaand programma worden twee arrays gebruikt, een voor de knoppen en een voor de leds. Het is belangrijk dat de arrays hetzelfde aantal elementen hebben.

const byte playerButtonPins[] = {2, 4, 6, 8};
const byte playerLedPins[] = {3, 5, 7, 9};

int DELAY = 3500;

void setup()
{
  Serial.begin(9600);

  // controleer of arrays hetzelfde aantal 'elementen' bevat
  if (sizeof(playerButtonPins) != sizeof(playerLedPins))
  {
    // informeer gebruiker
    Serial.println("Aantal playerButtonPins komt niet overeen met aantal playerLedPins");
    // hang hier voor eeuwig
    for (;;);
  }

  // doorloop de arrays om de pinnen te configureren
  for (byte cnt = 0; cnt < sizeof(playerButtonPins); cnt++)
  {
    pinMode(playerButtonPins[cnt], INPUT);
    pinMode(playerLedPins[cnt], OUTPUT);
  }
}

void playWinner(int pin) {
  for (int i = 0; i < 8; i++) {
    digitalWrite(pin, HIGH);
    delay(75);
    digitalWrite(pin, LOW);
    delay(75);
  }
  digitalWrite(pin, HIGH);
  delay(DELAY);
  digitalWrite(pin, LOW);
}

void loop()
{
  // doorloop de knoppen en neem actie als een knop is ingedrukt
  for (byte cnt = 0; cnt < sizeof(playerButtonPins); cnt++)
  {
    // als we een ingedrukte knop vinden
    if (digitalRead(playerButtonPins[cnt]) == HIGH)
    {
      // geef aan welke speler gewonnen heeft
      playWinner(playerLedPins[cnt]);
      // niet verder zoeken naar een ingedrukte knop
      break;
    }
  }
}

Een groot voordeel is dat je geen repeterende code meer hebt (if/else if/else if/else).

Hoe ver je wilt gaan met het aanpassen is voor jou om te bepalen. Hieronder de volgende stap die je kunt zetten.

Als je verder nadenkt over je programma, zul je zien dat er een een-op-een relatie is tussen een speler's knop en een speler's led. Je kunt een struct of een class gebruiken om die relatie weer te geven. Je kunt het vergelijken met een telefoon boek waar bij een naam zowel een telefoon nummer als een adres staat. Ik been meer een C programmeur dan een C++ programmeur en dus gebruik ik een struct.

Je programma kan er nu zo uit zien

// een struct om speler informatie op te slaan
struct PLAYER
{
  const byte buttonPin;
  const byte ledPin;
};

// creeer de speler configuraties
PLAYER playerConfig[] =
{
  {2, 3}, // speler 1: knop, led
  {4, 5},
  {6, 7},
  {8, 9}, // speler 4
};


int DELAY = 3500;

void setup()
{
  Serial.begin(9600);
  Serial.print(F("Quiz knoppen voor "));
  Serial.print(sizeof(playerConfig) / sizeof(playerConfig[0]));
  Serial.println(F(" spelers"));

  // doorloop de speler configuraties arrays om de pinnen te configureren
  for (byte cnt = 0; cnt < sizeof(playerConfig) / sizeof(playerConfig[0]); cnt++)
  {
    pinMode(playerConfig[cnt].buttonPin, INPUT);
    pinMode(playerConfig[cnt].ledPin, OUTPUT);
  }
}

void playWinner(int pin) {
  for (int i = 0; i < 8; i++) {
    digitalWrite(pin, HIGH);
    delay(75);
    digitalWrite(pin, LOW);
    delay(75);
  }
  digitalWrite(pin, HIGH);
  delay(DELAY);
  digitalWrite(pin, LOW);
}

void loop()
{
  // doorloop de speler configuraties
  for (byte cnt = 0; cnt < sizeof(playerConfig) / sizeof(playerConfig[0]); cnt++)
  {
    // als we een ingedrukte knop vinder
    if (digitalRead(playerConfig[cnt].buttonPin) == HIGH)
    {
      // geef aan welke speler gewonnen heeft
      playWinner(playerConfig[cnt].ledPin);
      // niet verder zoeken naar een ingedrukte knop
      break;
    }
  }
}

Eerder hebben we al sizeof gebruikt; sizeof geeft het aantal bytes dat een variabele gebruikt. Omdat de eerdere arrays arrays vab bytes waren, is het aantal bytes dat sizeof weergeeft hetzelfde als het aantal elementen in het array; dit geldt alleen voor variabelen van het type byte of char. Echter, omdat de struct twee bytes bevat, kun je sizeof niet gebruiken en wordt er een constructie gebruikt die het aantal elementen weergeeft

sizeof(playerConfig) / sizeof(playerConfig[0])

zoooo das een boel informatie maar wel leuk en ik ga er aankomende tijd mee aan de gang. Bedankt voor deze info wordt vervolgt

Zou ik de drukknopen ook zonder de weerstanden gewoon aan de min kunnen schakelen ipv aan de plus met de weerstanden?

Ja dat kan. Dat is inmiddels al 2 of 3 keer aan je voorgesteld, wanneer je het volgende doet voor die knoppen:

pinMode(2, INPUT_PULLUP);

ik heb het geprobeerd maar nu werkt mijn drukknop andersom

Nou mooi. Dat had ik je ook al verteld in mijn eerste antwoord in deze thread. Je moet dus je logica gaan omdraaien zoals ik vertelde;

if (digitalRead(2) == LOW) {

Zo dus.