User:Fako Berkers/simonsays: Difference between revisions

From XPUB & Lens-Based wiki
 
(2 intermediate revisions by the same user not shown)
Line 63: Line 63:
   // Check if pattern should be played.
   // Check if pattern should be played.
   if(millis() - pmillis > timelimit) play(); // No changes for a long time.
   if(millis() - pmillis > timelimit) play(); // No changes for a long time.
   if(imarks > buttonlimit) play(); // Button pressed to often.
   if(imarks > buttonlimit) play(); // Button pressed too often.


}
}


void flushit() {
void flushit() {
   memset(marks,0,buttonlimit); // Clears the array
   memset(marks,0,buttonlimit); // Clears the array
   imarks = 0;
   imarks = 0;
   cmillis = 0;
   cmillis = 0;
   pmillis = 0;
   pmillis = 0;
}
}


void play() {
void play() {
   // Do not play anything if there's no input yet.
   // Do not play anything if there's no input yet.
   if(!pmillis) return;
   if(!pmillis) return;
Line 95: Line 98:
   // Flush the pattern after it is played.
   // Flush the pattern after it is played.
   flushit();
   flushit();
}
</source>
===Coding II ===
Michael had some idea's on how to code the above differently. Below is the result. I think this code is more readable and is easier to expand, this comes at the small cost of some repeated statements and the user screws up the code if he presses the button too long. So far from perfect, but interesting to build upon ...
<source lang="C">
#include <stdlib.h>
const int timelimit = 4000;
const int buttonlimit = 100;
const int pinIn = 2;
const int pinOut = 8;
const int pinSpeaker = 13;
int marks[buttonlimit];
int imarks = 0;
unsigned long press_time = 0;
unsigned long release_time = 0;
int time_difference;
void setup() {
 
  // Set the pins.
  pinMode(pinIn,INPUT);
  pinMode(pinOut, OUTPUT);
  digitalWrite(pinIn, HIGH);
  digitalWrite(pinOut, LOW); // Pin out is low and pinIn becomes low when button is pushed.
 
  // Set the Serial.
  Serial.begin(115200);
  Serial.println("START");
 
}
void loop() {
 
  // START WAIT FOR PRESS
  Serial.println("START WAIT FOR PRESS");
  release_time = millis();
  while(digitalRead(pinIn)==HIGH) {
    // Check for timeout!
    if(millis() - release_time > timelimit) {
      if(imarks>0) {
        play();
        flushit();
      }
      return;
    }
  }
  press_time = millis();
  time_difference = press_time - release_time;
  marks[imarks] = time_difference;
  imarks++;
  // END WAIT FOR PRESS
 
  // START WAIT FOR RELEASE
  Serial.println("START WAIT FOR RELEASE");
  while(digitalRead(pinIn)==LOW) {}
  release_time = millis();
  time_difference = release_time - press_time;
  marks[imarks] = time_difference;
  imarks++;
  // END WAIT FOR RELEASE
 
  // Check for buttonlimit!
  if(imarks > buttonlimit) {
    play();
    flushit();
  }
}
void flushit() {
  memset(marks,0,buttonlimit); // Clears the array
  imarks = 0;
}
void play() {
 
  // Do not play anything if there's no input yet.
  if(marks[0]==0) return;
 
  // Visual play.
  for(int i=1; i<imarks; i++) { // start at i==1 to skip first pauze
    Serial.print(marks[i]);
    Serial.print(" ");
  }
  Serial.println("");
 
  // Sound play.
  for(int i=1; i<imarks; i++) { // start at i==1 to skip first pauze
    if (i%2) tone(pinSpeaker,500,marks[i]); // Every odd index number is the length of a button hold and sould create sound.
    delay(marks[i]);
  }
   
}
}
</source>
</source>

Latest revision as of 00:33, 10 November 2010

Simon Says on Arduino

Hardware

The hardware is very simple. Connect one end of the button to pin 8 and the other to pin 2. Set the speaker to pin 13 and ground.

Coding

#include <stdlib.h>

const int timelimit = 4000;
const int buttonlimit = 100;

const int pinIn = 2; 
const int pinOut = 8;
const int pinSpeaker = 13;

int butState = HIGH; // HIGH means not pressed

int marks[buttonlimit];
int imarks = 0;

unsigned long cmillis = 0;
unsigned long pmillis = 0;


void setup() {
  
  // Set the pins.
  pinMode(pinIn,INPUT);
  pinMode(pinOut, OUTPUT);
  digitalWrite(pinIn, HIGH);
  digitalWrite(pinOut, LOW); // Pin out is low and pinIn becomes low when button is pushed.
  
  // Set the Serial.
  Serial.begin(115200);
  Serial.println("START");
  
}

void loop() {

  // Read the input.
  int input_pin = digitalRead(pinIn);
  
  // If input changed, then work needs to be done!
  if (butState != input_pin) {

    butState = input_pin;
    
    // Get time values to work with.
    if(!pmillis) pmillis = millis(); // Only true the first push (makes first marker 0)
    cmillis = millis();
    
    // Save time difference between last button change and current time.
    marks[imarks] = cmillis - pmillis;
    imarks++;  
    
    // Save time value for next time.
    pmillis = cmillis; 
   
  }

  // Check if pattern should be played.
  if(millis() - pmillis > timelimit) play(); // No changes for a long time.
  if(imarks > buttonlimit) play(); // Button pressed too often.

}

void flushit() {

  memset(marks,0,buttonlimit); // Clears the array
  imarks = 0;
  cmillis = 0;
  pmillis = 0;

}

void play() {

  // Do not play anything if there's no input yet.
  if(!pmillis) return;
  
  // Visual output.
  for(int i=0; i<buttonlimit; i++) {
    Serial.print(marks[i]);
    Serial.print(" "); 
  }
  Serial.println("");
  
  // Play the pattern.
  int i = 1; // First element in array is always 0, so start at second
  while (marks[i]) { 
    if (i%2) tone(pinSpeaker,500,marks[i]); // Every odd index number is the length of a button push and sould create sound as long as that length.
    delay(marks[i]);
    i++;
  }
  
  // Flush the pattern after it is played.
  flushit();

}

Coding II

Michael had some idea's on how to code the above differently. Below is the result. I think this code is more readable and is easier to expand, this comes at the small cost of some repeated statements and the user screws up the code if he presses the button too long. So far from perfect, but interesting to build upon ...

#include <stdlib.h>

const int timelimit = 4000;
const int buttonlimit = 100;

const int pinIn = 2; 
const int pinOut = 8;
const int pinSpeaker = 13;

int marks[buttonlimit];
int imarks = 0;

unsigned long press_time = 0;
unsigned long release_time = 0;
int time_difference;

void setup() {
  
  // Set the pins.
  pinMode(pinIn,INPUT);
  pinMode(pinOut, OUTPUT);
  digitalWrite(pinIn, HIGH);
  digitalWrite(pinOut, LOW); // Pin out is low and pinIn becomes low when button is pushed.
  
  // Set the Serial.
  Serial.begin(115200);
  Serial.println("START");
  
}

void loop() {
  
  // START WAIT FOR PRESS
  Serial.println("START WAIT FOR PRESS");
  release_time = millis();
  while(digitalRead(pinIn)==HIGH) {
    // Check for timeout! 
    if(millis() - release_time > timelimit) {
      if(imarks>0) {
        play();
        flushit();
      }
      return;
    }
  }
  press_time = millis();
  time_difference = press_time - release_time;
  marks[imarks] = time_difference;
  imarks++;
  // END WAIT FOR PRESS
  
  // START WAIT FOR RELEASE
  Serial.println("START WAIT FOR RELEASE");
  while(digitalRead(pinIn)==LOW) {}
  release_time = millis();
  time_difference = release_time - press_time;
  marks[imarks] = time_difference;
  imarks++;
  // END WAIT FOR RELEASE
  
  // Check for buttonlimit!
  if(imarks > buttonlimit) {
    play();
    flushit();
  }

}

void flushit() {
  memset(marks,0,buttonlimit); // Clears the array
  imarks = 0;
}

void play() {
  
  // Do not play anything if there's no input yet.
  if(marks[0]==0) return;
  
  // Visual play.
  for(int i=1; i<imarks; i++) { // start at i==1 to skip first pauze
    Serial.print(marks[i]);
    Serial.print(" "); 
  }
  Serial.println("");
  
  // Sound play.
  for(int i=1; i<imarks; i++) { // start at i==1 to skip first pauze
    if (i%2) tone(pinSpeaker,500,marks[i]); // Every odd index number is the length of a button hold and sould create sound.
    delay(marks[i]);
  }
    
}