following a sequence

Hi everybody,

i'm trying to create some kind of game which consists on making music by simply following a pattern given by the program.

So i have 9 touch sensitive sensors and 9 leds. Each sensor makes the sound of 1 note of the musical scale.

I want to create a sequence that goes like:

LIGHT LED 3

wait until SENSOR 3 detects touch---->BEEP 3th note of the scale
if its been 5 seconds---->blink LED 3
if it's been 10 seconds----> reset song pattern

LIGHT LED 5

wait until sensor 5 detects touch----->BEEP 5th note of the scale
if its been 5 seconds---->blink LED 3
if it's been 10 seconds----> reset song pattern

etc

So the pattern of the light and sounds is given by me (and there's just 1) i.e.

3th,5th,4th,7th,1st.

for now the code i have is:

#include <CapacitiveSensor.h>
#include "Pitches.h"

/*

  • CapitiveSense Library Demo Sketch
  • Paul Badger 2008
  • Uses a high value resistor e.g. 10M between send pin and receive pin
  • Resistor effects sensitivity, experiment with values, 50K - 50M. Larger resistor values yield larger sensor values.
  • Receive pin is the sensor pin - try different amounts of foil/metal on this pin
    */

int ledPin13 = 13;
int ledPin12 = 12;
int ledPin11= 11;
CapacitiveSensor cs_4_2 = CapacitiveSensor(7,2); // 10M resistor between pins 4 & 2, pin 2 is sensor pin, add a wire and or foil if desired
CapacitiveSensor cs_4_6 = CapacitiveSensor(7,3); // 10M resistor between pins 4 & 6, pin 6 is sensor pin, add a wire and or foil
//CapacitiveSensor cs_4_8 = CapacitiveSensor(7,4); // R 10M entre pin 4 i 6. pin 6 en mode sensat

int melody[] = {
NOTE_E4, NOTE_F4, NOTE_G4, NOTE_E4, NOTE_C4, NOTE_F4, NOTE_E4, NOTE_D4, NOTE_C4, NOTE_D4, NOTE_D4, NOTE_E4, NOTE_C4
};

// int sensors[]= {
// sensor1, sensor2, sensor1, sensor1, sensor2, sensor1, sensor2, sensor1, sensor1, sensor2, sensor1, sensor1, sensor2
//};

// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurations[] = {
4, 4, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4
};

void setup()
{

pinMode(ledPin13, OUTPUT); // configura el pin 13 como salida
pinMode(ledPin12, OUTPUT); // configura el pin 12 como salida
cs_4_2.set_CS_AutocaL_Millis(0xFFFFFFFF); // turn off autocalibrate on channel 1 - just as an example

Serial.begin(9600); // abrimos puerto serie configurando la velocidad en 9600 bps

}

void loop()

{
digitalWrite(ledPin13, HIGH);

// long start = millis();
long sensor1 = cs_4_2.capacitiveSensor(30);
long sensor2 = cs_4_6.capacitiveSensor(30);
// long sensor3 = cs_4_8.capacitiveSensor(30);

// Serial.print(millis() - start); // check on performance in milliseconds
//Serial.print("\t"); // tab character for debug windown spacing

// Serial.print("SENSOR3:");
// Serial.print(sensor3); // print sensor output 2
// Serial.println(" ");
delay(100);

int sensors[]= {
sensor1, sensor2, sensor1, sensor1, sensor2, sensor1, sensor2, sensor1, sensor1, sensor2, sensor1, sensor1, sensor2
};

for (int thisNote=0; thisNote<13; thisNote++){
//for (int thisSensor=0;thisSensor<13;thisSensor++){
while (sensors[0]<100){

long sensor1 = cs_4_2.capacitiveSensor(30);
long sensor2 = cs_4_6.capacitiveSensor(30);
Serial.print("SENSOR1:");
Serial.print(sensor1); // presenta sensor output 1
Serial.print(" ");

Serial.print("SENSOR2:");
Serial.print(sensor2); // print sensor output 2
Serial.println(" ");
delay(100);
}
if (sensors[0]>=100){
// to calculate the note duration, take one second divided by the note type.
//e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
digitalWrite(ledPin13, HIGH);
tone(8, melody[thisNote], 100);

That's interesting, so does it work? If not what doesn't it do that it should? Or what does it do that it shouldn't?

Steve

It gets stuck in the for loop checking for notes...
actually my intention with the 2 for loops was:

1.gets in the loop thisNote
this means it will wait for the first note to play and enters the 2nd for loop (thisSensor)

  1. thisSensor loop
    enters in the thisSensor loop refreshing the data from the corresponding sensor waiting for the detection of the first sensor (corresponding to the first note) until it detects the sensor--> then the first note plays and then thisNote ++
 while (sensors[0] < 100)
  {
    long sensor1 =  cs_4_2.capacitiveSensor(30);
    long sensor2 =  cs_4_6.capacitiveSensor(30);
    Serial.print("SENSOR1:");
    Serial.print(sensor1);                    // presenta sensor output 1
    Serial.print(" ");
    Serial.print("SENSOR2:");
    Serial.print(sensor2);                  // print sensor output 2
    Serial.println(" ");
    delay(100);
  }

How will the code exit this while loop ?
What changes the value of sensors[0] ?

The code should exit this while when sensors[thisSensor ]>100 (thisSensor being the position of the array that corresponds depending on the part of the melody we are) although i put sensors[0] because sensors[thisSensor] wasn't working so i wanted to try with just an exact position of the array

So basically it will exit the while the sensor number 0 detects a higher number tan 100 (when you touch it)

it exits the while and enters the if, then you have the corresponding sound and we light the next LED of the melody

The code should exit this while when sensors[thisSensor ]>100

But nothing in the while loop changes the values in the sensors[] array as far as I can see. The for loop iterates through the sensors but the code will stick in the while loop as you have found.

Inside the while loop i have the refreshing of the sensors, so when it detects a raise in the value it should skip the loop.

My idea is getting it stuck in the first sensor of the melody until it detects this change.

UKHeliBob:
But nothing in the while loop changes the values in the sensors[] array as far as I can see.

CASPERobot:
Inside the while loop i have the refreshing of the sensors

I'm not seeing it either.

You mean in here?

while (sensors[0] < 100)
  {
    long sensor1 =  cs_4_2.capacitiveSensor(30);
    long sensor2 =  cs_4_6.capacitiveSensor(30);
    Serial.print("SENSOR1:");
    Serial.print(sensor1);                    // presenta sensor output 1
    Serial.print(" ");
    Serial.print("SENSOR2:");
    Serial.print(sensor2);                  // print sensor output 2
    Serial.println(" ");
    delay(100);
  }

Please post the whole of your program as it is now

If you declare the array like this

 int sensors[]= {
    sensor1, sensor2, sensor1, sensor1, sensor2, sensor1, sensor2, sensor1, sensor1, sensor2, sensor1, sensor1, sensor2
};

Then changing the value of, say, sensor1, will not change the value held in the array unless you change it specifically

UKHeliBob:
Please post the whole of your program as it is now

If you declare the array like this

 int sensors[]= {

sensor1, sensor2, sensor1, sensor1, sensor2, sensor1, sensor2, sensor1, sensor1, sensor2, sensor1, sensor1, sensor2
};



Then changing the value of, say, sensor1, will not change the value held in the array unless you change it specifically

Then that's my problem maybe, how could i do to do that?

The exact code I have now is:

#include <CapacitiveSensor.h>
#include "Pitches.h"

int ledPin13 = 13;
int ledPin12 = 12;
int ledPin11= 11;

CapacitiveSensor   cs_4_2 = CapacitiveSensor(7,2);        // 10M resistor between pins 4 & 2, pin 2 is sensor pin, add a wire and or foil if desired
CapacitiveSensor   cs_4_6 = CapacitiveSensor(7,3);        // 10M resistor between pins 4 & 6, pin 6 is sensor pin, add a wire and or foil
//CapacitiveSensor   cs_4_8 = CapacitiveSensor(7,4);        // R 10M entre pin 4 i 6. pin 6 en mode sensat

    long sensor1 =  cs_4_2.capacitiveSensor(30);
    long sensor2 =  cs_4_6.capacitiveSensor(30);


//melody array, it shows the order the notes are gonna be played when you touch the corresponding array position in the sensors array
  int melody[] = {
  NOTE_E4, NOTE_F4, NOTE_G4, NOTE_E4, NOTE_C4, NOTE_F4, NOTE_E4, NOTE_D4, NOTE_C4, NOTE_D4, NOTE_D4, NOTE_E4, NOTE_C4
};

//sensors array, it shows the sensor to touch to play the note corresponding to the same array position as in array melody  
  int sensors[]= {
    sensor1, sensor2, sensor1, sensor1, sensor2, sensor1, sensor2, sensor1, sensor1, sensor2, sensor1, sensor1, sensor2
};

// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurations[] = {
  4, 4, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4
};





void setup()                    
{
   pinMode(ledPin13, OUTPUT); // configura el pin 13 como salida
   pinMode(ledPin12, OUTPUT); // configura el pin 12 como salida
   cs_4_2.set_CS_AutocaL_Millis(0xFFFFFFFF);     // turn off autocalibrate on channel 1 - just as an example
   Serial.begin(9600);        //  opens serial port in the specified speed of 9600 bps
}




void loop()  
  {
//digitalWrite(ledPin13, HIGH);                

    long start = millis();
    long sensor1 =  cs_4_2.capacitiveSensor(30);
    long sensor2 =  cs_4_6.capacitiveSensor(30);
//    long sensor3 =  cs_4_8.capacitiveSensor(30);



for (int thisNote=0; thisNote<13; thisNote++){
for (int thisSensor=0;thisSensor<13;thisSensor++){
  
  while (sensor1<=100){
    digitalWrite(ledPin13, HIGH); 
    long sensor1 =  cs_4_2.capacitiveSensor(30);
    long sensor2 =  cs_4_6.capacitiveSensor(30);
    Serial.print("SENSOR1:");
    Serial.print(sensor1);                    // presenta sensor output 1
    Serial.print(" ");

    Serial.print("SENSOR2:");
    Serial.print(sensor2);                  // print sensor output 2
    Serial.println(" ");
    delay(100);
}
    digitalWrite(ledPin13, LOW); 
    digitalWrite(ledPin12, HIGH);
    tone(8, melody[thisNote], 100); 

}
}

if i change the while for an if it does sound the melody but repeating each sound lots of times.
the problem is not that it's not reading the sensor as i see in the COM port how my data keeps refreshing, the problem is with the while it gets stuck in the while even though the sensor1 raises 100.

Thank you for the interest and answers

Please can you explain what you want the program to do ?

kenwood120s:
I'm not seeing it either.

You mean in here?

while (sensors[0] < 100)

{
   long sensor1 =  cs_4_2.capacitiveSensor(30);
   long sensor2 =  cs_4_6.capacitiveSensor(30);
   Serial.print("SENSOR1:");
   Serial.print(sensor1);                    // presenta sensor output 1
   Serial.print(" ");
   Serial.print("SENSOR2:");
   Serial.print(sensor2);                  // print sensor output 2
   Serial.println(" ");
   delay(100);
 }

The value of the array sensor is not the thing it has to change.

The array sensor is there just to determine the order(i.e. which sensor has to be touched depending on the note)

The while loop is there to keep in stand-by until the sensor determined by the array detects some change

OK.

There are 7 type of sounds (notes) and 7 different sensors (still not installed that's why there are only sensor1 and sensor2) for each type of sound (note).

The melody that's going to be played is set at first, in the melody array. The sensor array happens to be the combination of sensors you have to press to play the song (melody).

There are two for loops.

The first for loop iterates through the notes while the second iterates through the sensors you have to press to play each note.

So we enter in the first for Notes loop. And then we enter in the second for Sensor loop.
The two for loops is the idea i had to relate each sensor with each note in the order of the melody

We are in the first position of the array, so we need to press the first position of the sensor array (sensor1) in order to listen to the first note (E4) of the array.

While the proper sensor hasn't been touched, we keep refreshing the data of the proper sensor (in this case sensor1), and when we detect the raise of the value to 100, we stop refreshing the data, we play the note, and we skip to the next position of the two arrays, the one of the notes (F4) and the one of the sensors (sensor2 is going to be the sensor we take the data from in the next while loop)

Now we will wait in the while refreshing the data of the sensor2 and when we detect the sensor2 raising we'll play the F4 and skip to the third position.

THANK YOU!! And i hope i explained it in a proper and clear way i'm not a native english

UKHeliBob:
Please can you explain what you want the program to do ?

You have the explanation above. Thank you

You have described what the program does (or not) but can you describe what the user does ?

Do they wait for a tone and press a matching sensor, for instance, or should the program play a series of tones which they respond to by pressing the series of matching sensors ?

Actually the user has to wait for a LED to light, placed next to the sensor, when they see the LED light, they press the sensor next to it and the note related to the sensor sounds.

When this is done, the LED lights off and another LED lights, indicating the user which sensor has to press now in order to hear the proper next note of the melody.

The sound is only played when the sensor is pressed.
The user knows what sensor has to press depending on which LED is lighted.

The thing i'd like to do is do 3 arrays (one of 7 LEDS, one of 7 sensor, and one of 7 sounds)

UKHeliBob:
You have described what the program does (or not) but can you describe what the user does ?

Do they wait for a tone and press a matching sensor, for instance, or should the program play a series of tones which they respond to by pressing the series of matching sensors ?

sorry i forgot to quote you. the answer is above

I decided that it was easier to write a program rather than trying to decribe how I suggest you do it, so here it is

const byte buttonPins[] = {A1, A2, A3};
const byte ledPins[] = {10, 11, 12};
const int tones[] = {1000, 1500, 2000};
const byte NO_OF_BUTTONS = sizeof(buttonPins) / sizeof(buttonPins[0]);
byte currentInput = 0;

enum states    //easy way to give states names
{
  turnLedOn,
  waitForUserInput
};
byte currentState = turnLedOn;  //start in this state

void setup()
{
  Serial.begin(115200);
  for (int pin = 0; pin < NO_OF_BUTTONS; pin++)
  {
    pinMode(ledPins[pin], OUTPUT);
    digitalWrite(ledPins[pin], HIGH);
    pinMode(buttonPins[pin], INPUT_PULLUP);
  }
}

void loop()
{
  switch (currentState)  //execute code only for the current state
  {
    case turnLedOn:
      digitalWrite(ledPins[currentInput], LOW);    //turn on the current LED
      currentState = waitForUserInput;             //move to next state
      break;
      
    case waitForUserInput:
      if (digitalRead(buttonPins[currentInput]) == LOW)  //test if relevant button is pressed
      {
        Serial.print("Tone : ");                //if so, output a tone
        Serial.println(tones[currentInput]);
        digitalWrite(ledPins[currentInput], HIGH);  //turn off current LED
        currentInput++;                   //next input or back to zero if all done
        if (currentInput >=  NO_OF_BUTTONS)
        {
          currentInput = 0;
        }
        currentState = turnLedOn;             //change state
      }
      break;
  }
}

You will need to change the logic to suit your circuit and add the code to play the actual tones that you want rather than printing the frequency but it should give you some ideas.