User:Fako Berkers/simonsays: Difference between revisions
Fako Berkers (talk | contribs) (→Coding) |
Fako Berkers (talk | contribs) |
||
(3 intermediate revisions by the same user not shown) | |||
Line 39: | Line 39: | ||
void loop() { | void loop() { | ||
// Read the input. | // Read the input. | ||
Line 49: | Line 45: | ||
// If input changed, then work needs to be done! | // If input changed, then work needs to be done! | ||
if (butState != input_pin) { | if (butState != input_pin) { | ||
butState = input_pin; | butState = input_pin; | ||
Line 63: | Line 60: | ||
} | } | ||
// 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() { | 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 85: | Line 89: | ||
// Play the pattern. | // Play the pattern. | ||
int i = 0 | 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. | 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]); | delay(marks[i]); | ||
i++; | i++; | ||
} | } | ||
// 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]);
}
}