:)Hello! I've been experimenting with the switch code to get my PIR sensor to tell my Waveshield to play a wav when input is high which I can do but what should I use in order to play the next wav in sequence every time my input goes high? "if" statements? I just need a pointer in the right direction or a small code example to help me please I know it's simple but I'm really stumped! Thanks, Goatboy
pseudocode
if(pinHigh){
switch(someval){
case some:
playSound(someSound);
if(pinHigh) while(pinHigh){ ; }
while(pinLow){ ; }
case some2:
playSound(someSound2);
if(pinHigh) while(pinHigh){ ; }
while(pinLow){ ; }
}
}
This will do:
When pin is high, find the right sound to play using sitch, then play all sounds that comes after when the button is (released then) pressed.
A dirty hack, and might not be what you want. Another solution would be to modify the someval variable, each time a button was pressed.
AlphaBeta, did you intend to leave out the break statements in that example
if (pinHigh) while(pinHigh) { ; }
The if and while are redundant. And that while loop will never exit unless pinHigh is declared volatile and set by an ISR.
You did say it's pseudo-code, but people are likely to cut-and-paste things that look like they might compile. Better to use English for pseudocode. One thing I try to teach new programmers is to develop your pseudocode in English and focus on the goals, not the techniques. Then turn the pseudocode into comments. Then write the real code below the comments.
// if the button is pushed,
// depending on the value,
// play the sound
// wait for pin to go low
By focusing on the goals instead of the techniques, you might realize there are a variety of techniques for each step. For example, you don't really need a switch statement if each case will be the same code.
// if the button is pushed,
if (LOW == digitalRead(buttonPin))
{
// depending on the value,
int freq = lookupFreqFromValue(somevalue);
// play the right sound
playSound(freq);
// wait for pin to go low
while (LOW == digitalRead(buttonPin)) { ; }
}
AlphaBeta, did you intend to leave out the break statements in that example
Yes I did, because OP wanted to continue to next sound if button was pressed.
@halley
Many good points
But:
"The if and while are redundant. And that while loop will never exit unless pinHigh is declared volatile and set by an ISR."
if and while are redundant, but they clarify what is intended.
The pinHigh was just a pseudo for digitalRead(pin), but you are correct that it is not optimal to psudocode with code.
I just got the feeling that the OP was a bit more than a beginner, and would see what is logical and not.
I made an assumption in that direction, and you in the other. But I see that it is better to be thourough that to give the benefit of the doubt.
And it is/was not a given that the same thing needed to happen every time. That was just in my code.
AlphaBeta, thanks. Even if the OP GoatBoy is an advanced coder, I know lots of newcomers read through old threads... so that's why I err on the side of caution. Not taking away from any of your suggestions either, just clarifying.
Thanks Superheros I'm planting onions and weeding at the sametime in my garden right now! I'd go mad with this programming if I didn't have something else to turn to right now and in fact I'm an embryo more than a newby but really enjoying learning how to put all this coding together!
Haven't a chance at the minute to try out your replies but from a quick glance just now I'm slightly uncertain if I made myself clear at the beginning! When my PIR goes high I want wav1 to play then when it goes high a second time I want wav2 to play not wav1 and so on! Looking forward to experimenting with this again tonight! Thanks, Goatboy
Just started messing with AlphaBeta's Switch example and the problem I have is that form what I understand "case" always has to be "1" because 1 is what is represented when pirPin reads HIGH so if the next part is case 2 no info is read! The confusing bit for me is when he writes "case some2" if I try this some errors! I need to try Halley's bit next to see if I can advance a wee bit but in the meantime heres my code so far........
``#include <AF_Wave.h>
#include <avr/pgmspace.h>
#include "util.h"
#include "wave.h"
int pirPin=6; // Reading from digital pin 6 PIR sensor!
AF_Wave card;
File f;
Wavefile wave;
void setup() {
// set up serial port
Serial.begin(9600);
pinMode(pirPin, INPUT);
digitalWrite(pirPin, LOW);
// set up waveshield pins
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6,INPUT);
// open memory card...........This part is necessary to set up and read SDcard!
if (!card.init_card()) {
return;
}
if (!card.open_partition()) {
return;
}
if (!card.open_filesys()) {
return;
}
if (!card.open_rootdir()) {
return;
}
}
void loop() {
switch(digitalRead(pirPin) == HIGH){ // When HIGH wavs will play in order untill they find "break;"
// Delay's can be placed inbetween wavs to change length!
case 1:
playcomplete("0.WAV");
playcomplete("2.WAV");
playcomplete("3.WAV");
}
}
void playcomplete(char *name) {
playfile(name);
while (wave.isplaying);
card.close_file(f);
}
void playfile(char *name) {
// stop any file already playing
if (wave.isplaying) {
wave.stop();
card.close_file(f);
}
f = card.open_file(name);
if (f && wave.create(f)) {
wave.play();
}
}
:)Thanks, Goatboy
Made a huge leap forward and was delighted to hear the A,T & T voice say 0, 1 & 2 in consecutive order for the first time however in doesn't always happen this way! The delay I found was crucial to stopping a continuous loop of the wav's by themselves but still they get stuck repeating the same one or stepping out of order! Does anyone have any ideas why this happens? Do I need to incorporate some form of debouncing even though I'm using a PIR and not a button or do you think it's the WaveShield? Still excited and thanks very much for your help everyone ;D Goatboy
This is the code that's working for me at the moment!
#include <AF_Wave.h>
#include <avr/pgmspace.h>
#include "util.h"
#include "wave.h"
int pirPin=6; // Reading from digital pin 6 PIR sensor!
AF_Wave card;
File f;
Wavefile wave;
void setup() {
// set up serial port
Serial.begin(9600);
pinMode(pirPin, INPUT);
// set up waveshield pins
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6,INPUT);
// open memory card...........This part is necessary to set up and read SDcard!
if (!card.init_card()) {
return;
}
if (!card.open_partition()) {
return;
}
if (!card.open_filesys()) {
return;
}
if (!card.open_rootdir()) {
return;
}
}
void loop(){
if(HIGH==digitalRead(pirPin)){
playcomplete("0.WAV");
while (LOW==digitalRead(pirPin)) {;}
delay(3000);
}
if(HIGH==digitalRead(pirPin)){
playcomplete("1.WAV");
while (LOW==digitalRead(pirPin)) {;}
delay(3000);
}
if(HIGH==digitalRead(pirPin)){
playcomplete("2.WAV");
while (LOW==digitalRead(pirPin)) {;}
delay(3000);
}
}
void playcomplete(char *name){
playfile(name);
while (wave.isplaying);
card.close_file(f);
}
void playfile(char *name) {
// stop any file already playing
if (wave.isplaying) {
wave.stop();
card.close_file(f);
}
f = card.open_file(name);
if (f && wave.create(f)) {
wave.play();
}
}
Now I don't think I have as much experience as the other guys in this, but I could see a problem with your delays and entry statements. When you are in the while loop inside, it waits until you press/pass in front of your button/sensor. However, your delay causes the loop to exit, not go to the next one. Say you activate it, it plays sound 2, and then waits until next press. You activate the button (im using buttons for sake of press/let go terms), but let go in under 3 seconds. At this point, as far as I can see, you are looping around in the main loop, but not entering any if statement. It only enters an if statement when you press it again, and by that time you could be anywhere in the main loop. Perhaps this code would help solve that?
It should be technically faster, and smaller since I just used code already in it, just rearranged. Also, It forces the order to be 0 1 2 since the while loops hold it until the button is pressed.
Hope it helps/works! (IT IS UNTESTED)
void loop(){
while (LOW==digitalRead(pirPin)) {;}
playcomplete("0.WAV");
delay(3000);
while (LOW==digitalRead(pirPin)) {;}
playcomplete("1.WAV");
delay(3000);
while (LOW==digitalRead(pirPin)) {;}
playcomplete("2.WAV");
delay(3000);
}
REPthe603 ;D That's the ticket for me! It works like a charm In perfect order like you say! The delay issue confuses me but that's something I need to learn and understand about in more depth. If I take away the delay altogether the wavs play in a loop a couple of times before stopping and waiting for the next movement. Is that to be expected by your understanding? or are there sensitivity issues with the PIR maybe? Either way it's all good and thanks for your time!!
Goatboy
Let me try to explain my code step by step.
First time, you enter the loop. Thereafter, it returns here after 2.WAV so its the same thing. The while statement is waiting for the pin to go HIGH, in other words waiting for movement or press. When that happens, the 0.WAV file plays, then it delays for 3 seconds. I'm not sure if the delay itself if needed, but I haven't really looked at the code for playcomplete. If playcomplete doesn't return back to the delay until it finishes playing the sound, you don't need the delays, but you can leave them for safety if you like. From what you say, you probably do need them in, but maybe not so large. Try a delay just a tiny bit longer than your sound files - if 0.wav is 1 second, try a delay of 1200 or something.
void loop(){
while (LOW==digitalRead(pirPin)) {;}
playcomplete("0.WAV");
delay(3000);
Now, we have finished the first wav file. We are out of the delay and are now stuck in this next while loop. Exactly like the first, we cant leave this spot until the pin goes HIGH. The same thing happens after 1.WAV plays.
while (LOW==digitalRead(pirPin)) {;}
playcomplete("1.WAV");
delay(3000);
while (LOW==digitalRead(pirPin)) {;}
playcomplete("2.WAV");
delay(3000);
If you still don't get it, let me know I'll try to get a better way to explain it. Good luck, glad it worked!
Very generous of you to take the time to explain this to me REPthe603
The flow chart is perfect! I just need to see and understand the code in the same way!! Another part to the puzzle for me Thanks, Goatboy