Random number met leds en knop

Arduino specifieke Software
Berichten: 3
Geregistreerd: 03 Dec 2016, 15:55

Random number met leds en knop

Berichtdoor yo500 » 03 Dec 2016, 16:20

Halllo,

Mijn probleem:
Ik heb een random nummer game gemaakt met 4 leds en 1 knop

Eerst wordt een random nummer gegeven. Daarna moet je op de knop klikken die overeenkomt met de random nummer die is gegeven. Bijvoorbeeld als random nr 4 is dan moet je 4x klikken. Je hebt 2 seconden tijd nodig om te klikken. Ik wil graag Als je over de 2 seconden bent, dan hebt het spel verloren en begin je weer opnieuw. Als je binnen de tijd bent en je hebt goed geraden, dan dan branden alle 4 leds en vervolgens moet het spel weer opnieuw beginnen. dan worden alle led uitgezet. Ik weet niet hoe je dat moet doen. Ik wil gebruik maken van millles() voor die 2 seconden.

tot nu toe heb ik alleen random nummer en de aantal kliks die overeenkomt met de de randomnummer.
kan je iemand helpen met mijn code? Hieronder is mijn code.




const int Button = 13;

int ButtonState;
int lastState = LOW;
int count = 0;
int steps = 10;

int ledPin = 2;
int ledPin2 = 3;
int ledPin3 = 4;
int ledPin4 = 5;
int randomNumber = random(1,5);


void setup() {
Serial.begin(9600);
Serial.println("hello! Please guess a number!");
pinMode(ledPin,OUTPUT);
pinMode(ledPin2,OUTPUT);
pinMode(ledPin3,OUTPUT);
pinMode(ledPin4,OUTPUT);
pinMode(Button,INPUT);


Serial.println(randomNumber);
// randomSeed(analogRead(7));
}

void loop() {
ButtonState = digitalRead(Button);



if(ButtonState && ButtonState != lastState) // button latch, no debounce needed.
{
if(count < randomNumber)
{// This will check to see if the count is within a range of 0 - 255, and anything over that, it will reset count back to 0. Of course, this will happen anyways because count is a BYTE, and not an int or any other type.
count++; // same as count = count +1;

}
else if(count == randomNumber) {
Serial.println("goed");
count = 0;
digitalWrite(ledPin, HIGH);
digitalWrite(ledPin2, HIGH);
digitalWrite(ledPin3, HIGH);
digitalWrite(ledPin4, HIGH);
}
else{

digitalWrite(ledPin, LOW);
digitalWrite(ledPin2, LOW);
digitalWrite(ledPin3, LOW);
digitalWrite(ledPin4, LOW);
}

// analogWrite(LED, count);
Serial.println(count);
}
lastState = ButtonState;
}

Advertisement

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: Random number met leds en knop

Berichtdoor Koepel » 03 Dec 2016, 18:20

Maar je wilt niet dat als iemand snel 10 keer klikt, dat hij dan automatisch bij het juiste aantal al stopt en het als "goed" ziet.
Is dit een opdracht voor school ?

Een ervaren programmeur zet niet zomaar wat code bij elkaar, maar die maakt eerst de verschillende onderdelen en test die stuk voor stuk.

Je zou eerst kunnen beginnen met de knop. Je bent afgeweken van : https://www.arduino.cc/en/Tutorial/StateChangeDetection, en daardoor wordt het minder duidelijk.
Waarom denk je dat je geen debounce nodig hebt ? Bij één keer de knop indrukken kan het contact gemakkelijk 10 keer bouncen. Je commentaar: "button latch, no debounce needed" is volgens mij niet juist.

Daarna is het nodig om een juiste beschrijving te geven van wat je wilt. Je kunt niet beginnen met programmeren zonder een juiste beschrijving. Het lijkt alsof je sketch bedoelt is om maar één keer te werken.

De beschrijving kan zo iets zijn:
Na het opstarten de tekst "Please guess a number!"
Daarna twee seconden om de knop een aantal malen in te drukken.
Aan het einde van de twee seconden wordt gekeken of het aantal klopt.
Als het klopt, dan de tekst "Goed".

Maar dan ?
Wil je de tekst "guess number" weer laten zien, of wil je eerst even wachten.
Hoe lang wil je dat de leds branden ?
Wil je een nieuw random getal genereren ?
Dan zul je dat in de loop() moeten doen.
Het is daarom eenvoudiger om in de loop() een start te maken voor de gebruiker, en alleen in de loop() een random nummer te genereren en alleen in de loop() de tekst "guess number" te laten zien.
Het zou nog eenvoudiger worden, als er een start-knop zou zijn.

P.S. Zou je [ Code ] of [ Code 2 ] willen gebruiken als je je sketch laat zien. Dat is knop "Code" of de "Select a Syntax" (en dan C++ kiezen).

Aanvulling: Gevonden ! Je hebt waarschijnlijk dit gebruikt : http://www.instructables.com/id/Easy-Arduino-Pushbutton-Scoring-For-Two-Teams/step3/Upload-the-program/.
Op instructables.com staat vaak slechte code. Kun je dat vergeten en opnieuw beginnen ?

Berichten: 3
Geregistreerd: 03 Dec 2016, 15:55

Re: Random number met leds en knop

Berichtdoor yo500 » 05 Dec 2016, 02:50

Hier een duidelijke beschrijving:
1 Na het opstarten de tekst "Please guess a number!"
2 Daarna wordt random getal gegeven
3 daarna moet je op de knop drukken met de aantal de klikken die overeenkomt met de random getal. Stel de random getal is 4, dan moet je 4x de knop drukken.

4 je hebt 20 seconden tijd nodig om te drukken. Als je binnen 20 seconden valt, en de aantal klikken is gelijk aan de random getal, dan laat je alle leds branden. Er komt een tekst "je hebt het spel gewonnen"Er komt een tekst of je het spel weer opnieuw wil beginnen. Als het waar is, begin opnieuw.

5 je hebt 20 seconden tijd nodig om te drukken. Als je binnen 20 seconden valt,en de aantal klikken is NIET gelijk aan de random getal dan laat je geen leds branden. Er komt een tekst "je hebt het spel verloren" Er komt een tekst of je het spel weer opnieuw wil beginnen. Als het waar is, begin opnieuw.

6. Als je buiten 20 seconden, klikt en de aantal klikken van je knop is NIET gelijk aan random getal dan zijn alle leds uit. Er komt een tekst "je hebt het spel verloren". Er komt een tekst of je het spel weer opnieuw wil beginnen. Als het waar is, begin opnieuw.
Voorbeeld je hebt 4 x geklikt en random getal is 5 en tijd is 0. Dan heb je verloren.

Ik wil graag milles() gebruiken(stap4). Ik weet niet hoe dat moet
Bij stap 4t/6 wil ik in een loop zetten, zodat je het spel weer opnieuw kan beginnen. Ik weet op dit moment niet hoe ik moet doen.
De leds zijn dan uit en er komt een nieuw random getal.


Ik heb sketch gebruikt van statedetection. Op dit moment heb ik alleen random getal en de aantal klikken van de knop die overeenkomt met de randomgetal. Ik loop vast met stap4t/m 6 en weet echt niet hoe ik in mijn code moet doen. Kan iemand met helpen met mijn code?


// this constant won't change:
const int buttonPin = 13; // the pin that the pushbutton is attached to
const int ledPin = 2; // the pin that the LED is attached to
const int ledPin2 = 3;
const int ledPin3 = 4;
const int ledPin4 = 5;

// Variables will change:
int buttonPushCounter = 0; // counter for the number of button presses
int ButtonState; // current state of the button
int lastButtonState = LOW; // previous state of the button
int randomNumber = random(1,3);


void setup() {
// initialize the button pin as a input:
pinMode(buttonPin, INPUT);
// initialize the LED as an output:
pinMode(ledPin, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
pinMode(ledPin4, OUTPUT);
// initialize serial communication:
Serial.begin(9600);
randomNumber = random(1,3);
Serial.println("hello! Please guess a number!");
Serial.println(randomNumber);
}


void loop() {
// read the pushbutton input pin:
ButtonState = digitalRead(buttonPin);

// compare the buttonState to its previous state
if(ButtonState && ButtonState != lastButtonState){
// if the state has changed, increment the counter
if(buttonPushCounter < randomNumber){

// if the current state is HIGH then the button
// wend from off to on:
buttonPushCounter++;
Serial.println("on");
Serial.print("number of button pushes: ");
Serial.println(buttonPushCounter);
}
else if(buttonPushCounter == randomNumber){
Serial.println("you win");
digitalWrite(ledPin, HIGH);
digitalWrite(ledPin2, HIGH);
digitalWrite(ledPin3, HIGH);
digitalWrite(ledPin4, HIGH);

}
else {
// if the current state is LOW then the button
// wend from on to off:
Serial.println("off");
buttonPushCounter=0;
}
// Delay a little bit to avoid bouncing
delay(50);
Serial.println(buttonPushCounter);

}
// save the current state as the last state,
//for next time through the loop
lastButtonState = ButtonState;


// turns on the LED every four button pushes by
// checking the modulo of the button push counter.
// the modulo function gives you the remainder of
// the division of two numbers:
// if (buttonPushCounter % 4 == 0) {
// digitalWrite(ledPin, HIGH);
// } else {
// digitalWrite(ledPin, LOW);
// }

}

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: Random number met leds en knop

Berichtdoor Koepel » 05 Dec 2016, 11:02

Je hebt meteen het moeilijkste te pakken van een software project: een juiste beschrijving maken.
Het leren van een programmeertaal is nog wel te doen, maar de echte wereld bekijken op een manier zodat het logisch in een programma te zetten is, dat is het belangrijkste deel.
Dat is de reden dat grote software projecten verkeerd kunnen gaan. Des te groter het project, des te moeilijker de beschrijving.

Je schrijft dat je stap 4 tot en met 6 wilt herhalen. Maar volgens mij wil je opnieuw de tekst "Please guess a number" op het scherm zetten, dus volgens mij wil je vanaf stap 1 alles herhalen.

Wannneer je een sketch laat zien, zou je dan de [ Code ] of [ Code2 ] willen gebruiken (de knop "Code" of de droplist "Select a Syntax" met "C++").

Hoe detecteer je dat iemand is gevallen ?

Begrijp ik het goed dat je dezelfde knop wilt gebruiken om het aantal te tellen, maar ook om te reageren wanneer gevraagd wordt om opnieuw te starten ? Dat verandert de structuur van de code, want dan wordt het opeens een algemene knop die die voor meerdere dingen gebruikt wordt.

Voor millis() als een software timer of timeout of eenmalige vertraging zijn twee variabelen nodig. Eentje onthoudt de tijd en de ander geeft aan of de software timer actief is.

Twee globale variabelen:
Code: Alles selecteren
unsigned long previousMillis;
boolean timerActive = false;      // enable/disable the software timer


De tijd starten gaat zo:
Code: Alles selecteren
  previousMillis = millis();   // timestamp this moment (remember this moment)
  timerActive = true;     // enable the software timer


Kijken of de timer al afgelopen is, gaat zo:
Code: Alles selecteren
  if ( millis() - previousMillis > 20000UL)  {      // 'UL' means unsigned long
    ...
  }


Kijken of de timer loopt gaat zo:
Code: Alles selecteren
  if ( timerActive ) {
    ...
  }


Je kunt dus in je code kijken of de 20 seconden lopen door alleen maar naar de boolean 'timerActive' te kijken.

Ga niet meteen die stukjes code hierboven bij de sketch toevoegen, maar probeer eerst om het te begrijpen en probeer na te gaan wat je uiteindelijk wilt bereiken.

Wil je alleen detecteren of de knop ingedrukt wordt ? Als je niet hoeft te weten hoe lang de knop wordt ingedrukt of wanneer de knop wordt losgelaten, dan kun je misschien de code voor de knop in een functie zetten. Dat is gemakkelijker voor het overzicht, en dat maakt het gemakkelijker om later een debounce library te gebruiken.
Ik bedoel dit stukje code:
Code: Alles selecteren
// buttonRose, returns true if the button changes from not pressed to pressed.
boolean buttonPressed()
{
  boolean butnPressed = false;

  // read the pushbutton input pin:
  int butnState = digitalRead(buttonPin);

  // compare the buttonState to its previous state
  if (butnState != lastButtonState) {
    if (butnState == HIGH) {
      // if the current state is HIGH then the button
      // wend from off to on:
      Serial.println("on");
      butnPressed = true;
    } else {
      // if the current state is LOW then the button
      // wend from on to off:
      Serial.println("off");
    }
  }
  // save the current state as the last state,
  //for next time through the loop
  lastButtonState = butnState;

  return (butnPressed);
}


Ik zie zelf nog niet de uiteindelijke code voor me :( De knop wordt voor meerdere dingen gebruikt, en dat kan op verschillende manieren opgelost worden. Heb je wel eens van een state machine gehoord ? Dat zou de code overzichtelijke maken en het zou voorkomen dat sommige stukken code er dubbel in zitten.
Als ik daar een voorbeeld van maak, dan ga je misschien mijn voorbeeld gebruiken zonder het te begrijpen. Dat brengt je in problemen omdat het dan verkeerd gaat zodra je iets wilt wijzigen.

Berichten: 3
Geregistreerd: 03 Dec 2016, 15:55

Re: Random number met leds en knop

Berichtdoor yo500 » 06 Dec 2016, 01:09

die 20 sec is een countdown. hij telt dus af. Moet ik debounce gebruiken?

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: Random number met leds en knop

Berichtdoor Koepel » 06 Dec 2016, 08:57

Aftellen of optellen tot een bepaalde tijd, een timeout, of een knipperlicht, of iets anders met millis... Om millis() goed te gebruiken kan alleen het huidige moment onthouden worden met een unsigned long (die heet vaak "previousMillis"). En er kan alleen getest worden door: millis() - previousMillis. Daarom zie je steeds dit soort dingen:
Code: Alles selecteren
  unsigned long previousMillis;
  ...
  previousMillis = millis();   // remember this moment (timestamp this moment)
  ...
  if( millis() - previousMillis ....

Jij noemt het aftellen, ik noemde het een software timer van 20 seconden. Het is precies hetzelfde ;) Het is al het ware een kookwekker die op 20 seconden gezet wordt, en na 20 seconden loopt de kookwekker af.


Je kunt debounce gebruiken, bijvoorbeeld de Bounce2 library : https://github.com/thomasfredericks/Bounce2.
De Bounce2 library werkt het best als er geen delay() in de sketch zit.

Om het bouncen tegen te gaan is het soms voldoende om de sketch langzamer te maken door onderin de loop() een delay() neer te zetten van bijvoorbeeld 20ms of 50ms en dan maar hopen dat het goed gaat.

Het allerbeste is om de sketch te schrijven op een manier dat je later altijd nog kunt omschakelen naar de Bounce2 library. Bijvoorbeeld door de knop te zien als een stroom gegevens die binnen komt (een data stream).

Terug naar Arduino software

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 90 gasten