Need help with writing a sketch

Hey everyone I'm new here at the Arduino forums and I need some help writing a sketch for my Arduino. I'm taking a college class right now where we're working with Arduinos and my task is to write a sketch that:

After sensing light for 10 seconds (using a CdS light-sensor), an alarm-type sound plays through a piezo for 15 seconds, and and then pauses for 3 seconds, then loops until it senses no more light.

I'm using the Arduino program 0016 and a Duemilanove Arduino 328

If someone could help me with this I'd really appreciate it I'm having trouble trying to figure this out and I know it seems like a simple sketch again I'd appreciate the help. Thanks.

I think your teachers want you to do this alone.

But, break the problem down a bit.
Set som milestones, and go at them with the intention to learn.

This way, you will manage to see that you make progress, and you will learn :slight_smile:

I’d be glad to help you with something a bit more specific, I also think there’s alot of code you can stody that does something similar. :slight_smile:

I have the code for the sensor and the piezo and the light, but the problem I'm having is combining them to work together efficiently.

Using the if functions and while functions and all that isn't really my forte ha.

Hehe. I see.

If you post the code here: www.arduino.pastebin.com

I'll sure have a look. :)

I don’t have the code on the computer I’m using right now but I will definitely post it to you tomorrow. Thanks Alpha.

the problem I'm having is combining them to work together efficiently

Efficiency comes later, for now concentrate on "effectively".

This is my sketch so far everyone, can someone tell me what I’m doing wrong. I need the light sensor to sense light for 10 secs and then play the tone after that. Please help meeeee.

#define LED 13

int val = 0;
int speakerPin = 9;

int length = 15;
char notes = "ccggaagffeeddc ";
int beats = { 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 4 };
int tempo = 50;

void setup()
{
pinMode(LED, OUTPUT);
pinMode(speakerPin, OUTPUT);
}

void loop()
{
val = analogRead(0);

digitalWrite(13, HIGH);
while (LED == HIGH);
delay(10000);

if (analogRead == LOW);
digitalWrite(13, LOW);

}
void loop()

do playTone(int tone, int duration) {
for (long i = 0; i < duration * 1000L; i += tone * 2) {
digitalWrite(speakerPin, HIGH);
delayMicroseconds(tone);
digitalWrite(speakerPin, LOW);
delayMicroseconds(tone);
}
}
}
void playNote(char note, int duration) {
char names = { ‘c’, ‘d’, ‘e’, ‘f’, ‘g’, ‘a’, ‘b’, ‘C’ };
int tones = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 956 };

for (int i = 0; i < 8; i++) {
if (names == note) {
_ playTone(tones*, duration);_
_
}_
_
}_
_
}_
_
for (int i = 0; i < length; i++) {_
_ if (notes == ’ ') {_
delay(beats _ tempo); // rest_

* } else {*
playNote(notes, beats * tempo);
* }*
* delay(tempo / 2);*
* }*
}

This doesn't even compile. You've got two "loop()"s.

 if (analogRead == LOW);
 digitalWrite(13, LOW);

}

"analogRead" is a pointer to a function, therefore is always true. (unless the function is positioned at zero)

You need to talk to local teachers.

Try breaking down your problem by thinking about how you’d solve the problem yourself with a light-meter and a wall-clock, and maybe a notepad and pencil.

1)Look at the clock and note the time
2)Look at the light-meter.
3)Has it reached your trigger level? If not go back to step 1.
4)We’re here because the light level has reached the trigger level. Look at the clock. Has ten seconds passed? If not go to step 2
5)We’re here because 10 seconds has elapsed, so play the tune and wait three seconds.
6) Is the light level still at the trigger level? If not, got to step 1.
7) go to step 5

Now, “go to” is frowned-upon, so we use “while” instead.

void loop()
{
  long start = millis ();

  while (analogRead(LDR) <= TRIGGER_LEVEL) {
    if ((millis () - start) > DETECT_TIME) {
      digitalWrite (LED, HIGH);
      do {
        playTune (notes, beats, length, tempo);
        delay (PAUSE_TIME);
      } while (analogRead (LDR) <= TRIGGER_LEVEL);  
      digitalWrite (LED, LOW);
    }
  }
}

Not tested, not compiled, not complete.

Ignore the code i posted before that stuff was just nonsense. But since then I’ve started working a newer code that I think I might be on to something but I’m still having some trouble with it so if anyone can help me out I’d really appreciate it. Thanks.

#define LED 13

int val = 0;
int speakerPin = 7;
int length = 15;
char notes = "ccggaagffeeddc ";
int beats = { 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 4 };
int tempo = 50;

void setup()
{
pinMode(LED, OUTPUT);
pinMode(speakerPin, OUTPUT);
}

void loop()
{
val = analogRead(0);
if (val > 0)
{
digitalWrite(13, HIGH);
delay(15000);
}
else {
digitalWrite(13, LOW);
}
}

if ((delay() > 10000) && (LED == HIGH))
{
playTone(int tone, int duration)
{
for (long i = 0; i < duration * 1000L; i += tone * 2)
{
digitalWrite(speakerPin, HIGH);
delayMicroseconds(tone);
digitalWrite(speakerPin, LOW);
delayMicroseconds(tone);
}
}
}
void playNote(char note, int duration)
{
char names = { ‘c’, ‘d’, ‘e’, ‘f’, ‘g’, ‘a’, ‘b’, ‘C’ };
int tones = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 956 };

for (int i = 0; i < 8; i++)
{
if (names == note)

  • {*
    _ playTone(tones*, duration);_
    _
    }_
    _
    }_
    _
    }_
    for (int i = 0; i < length; i++)
    _
    {_
    _ if (notes == ’ ')
    {_
    delay(beats _ tempo);
    * }
    else*

    * {_
    playNote(notes, beats _ tempo);
    * }
    delay(tempo / 2);
    }*_

I think Groove’s solution looks like a good starting point - you’ve got all the bits.

if ((delay() > 10000) && (LED == HIGH))

“delay” is a void function; it doesn’t return anything, and needs an argument to tell it how long to delay.
Looks like your “loop()” has a “}” too soon (just before the “if(delay” line.

You’d be better moving the declarations of “playNote” and “playTone” out, above “loop()”

I took Groove’s outline and padded it out - it compiles, but I don’t have any h/w to test it.
I’m not sure the tune playing logic is correct, but it’s a start.

int val = 0;
const int speakerPin = 9;
const int LED  = 13;
const int LDR = 0;
const char notes[] = "ccggaagffeeddc "; 
const int beats[] = { 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 4 };
const int length = sizeof (beats) / sizeof (beats [0]);
const int tempo = 50;
void playTone(int tone, int duration) {
 for (long i = 0; i < duration * 1000L; i += tone * 2) {
   digitalWrite(speakerPin, HIGH);
   delayMicroseconds(tone);
   digitalWrite(speakerPin, LOW);
   delayMicroseconds(tone);
 }
}
void playNote(char note, int duration) {
  const char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C' };
  const int tones[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 956 };
  for (int i = 0; i < 8; i++) {
    if (names[i] == note) {
      playTone(tones[i], duration);
    }
   }
}
void playTune (const char* notes, const int* beats, int length, int tempo)
{
  for (int i = 0; i < length; i++) {
    if (notes[i] == ' ') {
     delay(beats[i] * tempo); // rest
  } else {
     playNote(notes[i], beats[i] * tempo);
  }
  }
  delay(tempo / 2); 
}
void setup()
{
 pinMode(LED, OUTPUT);
 pinMode(speakerPin, OUTPUT);
}
const int triggerLevel = 250;  // if LDR falls below this, trigger.
const int DETECT_TIME  = 10000;
const int PAUSE_TIME = 3000;
void loop()
{

  long start = millis ();
  while (analogRead(LDR) <= triggerLevel) {
    if ((millis () - start) > DETECT_TIME) {
      digitalWrite (LED, HIGH);
      do {
        playTune (notes, beats, length, tempo);
        delay (PAUSE_TIME);
      } while (analogRead (LDR) <= triggerLevel);  
      digitalWrite (LED, LOW);
  }
}

Thanks Groove and AWOL I'm gonna work with what you two are saying and try to see if I can achieve what it is I'm trying to. I'll let you guys know if I'm successful or not ha. Thanks again.

Ok Groove I tried your code and it kinda-sorta worked. I see where you’re going with all the constants and such. When I send it to the board it pauses for a little and then turns on. Then when I pull out the light sensor to get a “0” reading so the LEF turns off, it wont. And when I ran a serial through it, the sensor only sent one reading, a number in the mid 800’s. Can someone help me out here. I need it to sense light and if it reads that it sensed 10 secs of light it plays a sound and turns on an LED, and when it stops sensing light (or < val) it stops playing the sound and turns off the LED. Please help. Thanks again.

And when I ran a serial through it, the sensor only sent one reading

I don't understand this - Are you saying that the light sensor is on the serial line? I thought it was on an analogue pin? Your code up there implies this with an analogRead - the sensor doesn't "send", the Arduino has to read it. Can you draw your circuit?

Yeah it is on an analog pin I just meant that I put the Serial.begin function in the sketch to make sure the sensor was reading values. When I did that, it only returned one value through the serial monitor. It wasnt constantly reading values like I need it to.

while (analogRead(LDR) <= triggerLevel) {
    if ((millis () - start) > DETECT_TIME) {
      digitalWrite (LED, HIGH);
      do {
        playTune (notes, beats, length, tempo);
        delay (PAUSE_TIME);
      } while (analogRead (LDR) <= triggerLevel);
      digitalWrite (LED, LOW);
  }

That looks pretty continuous to me. Maybe the sense of the trigger level is wrong? Maybe “>=” instead of “<=”?

How is your detector wired, please?

i have it hooked onto a protoshield on the arduino, one line is hooked along the the anode of sensor with a wire going into the 5V, and along the the cathode a 10k ohm resistor and a wire going into analog-in 0. and then a wire running from the resistor to the ground.

ok so i used AWOL's code and it kind of does the trick. the melody plays as it should but the problem i'm having is that when i cover the sensor to get a reading lower than the triggerLevel, the LED won't turn off. It'll just keep going and then eventually turn off and loop. i need it to turn off when the sensor gets a reading lower than the triggerLevel and its not doing that, only after a period of time the arduino will reset or something and runs the program again. help please.

Can you post your sketch, please?

int val = 0;
const int speakerPin = 9;
const int LED  = 13;
const int LDR = 0;
const char notes[] = "ccggaagffeeddc ";
const int beats[] = {1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 4 };
const int length = sizeof (beats) / sizeof (beats [0]);
const int tempo = 50;

void playTone(int tone, int duration)
{
  for (long i = 0; i < duration * 1000L; i += tone * 2) 
  {
    digitalWrite(speakerPin, HIGH);
    delayMicroseconds(tone);
    digitalWrite(speakerPin, LOW);
    delayMicroseconds(tone);
  }
}
void playNote(char note, int duration)
{
  const char names[] = { 
    'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C'   };
  const int tones[] = { 
    1915, 1700, 1519, 1432, 1275, 1136, 1014, 956   };
  for (int i = 0; i < 8; i++) 
  {
    if (names[i] == note) 
    {
      playTone(tones[i], duration);
    }
  }
}
void playTune (const char* notes, const int* beats, int length, int tempo)
{
  for (int i = 0; i < length; i++) 
  {
    if (notes[i] == ' ')
    {
      delay(beats[i] * tempo);
    } 
    else
    {
      playNote(notes[i], beats[i] * tempo);
    }
  }
  delay(tempo / 2);
}
void setup()
{
  pinMode(LED, OUTPUT);
  pinMode(speakerPin, OUTPUT);
}
const int triggerLevel = 600;  // if LDR falls below this, trigger.
const int DETECT_TIME  = 10000;
const int PAUSE_TIME = 1000;

void loop()
{

  long start = millis ();
  while (analogRead(LDR) >= triggerLevel) 
  {
    if (millis () > DETECT_TIME)
    {
      digitalWrite (LED, HIGH);

      do
      {
        playTune (notes, beats, length, tempo);
        delay (PAUSE_TIME);
      }
      while (analogRead (LDR) <= triggerLevel);
      digitalWrite (LED, LOW);
    }
  }
}