User:Fako Berkers/simonsays

From XPUB & Lens-Based wiki

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() {
  
  // Check if pattern should be played.
  if(millis() - pmillis > timelimit) play(); // No changes for a long time.
  if(imarks > buttonlimit) play(); // Button pressed to often.

  // 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; 
   
  }

}

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 = 0;
  do {
    if (i%2) tone(pinSpeaker,500,marks[i]); // Every odd index number is the length of a button push and sould create sound.
    delay(marks[i]);
    i++;
  } while(marks[i]);
  
  // Flush the pattern after it is played.
  flushit();
}