PDA

View Full Version : help with arduino visual c/c++ code writing



mykwikcoupe
10-03-2012, 07:53 PM
I have a very cool Halloween project I am attempting to build this year. For those that don't know, i put up a pretty cool Halloween display every year. I by trade am an electrician so most of my props re done via hard-wired and individual items to manipulate the circuit and control the prop. that unfortunately gets pretty expensive. this year, I decided to try my luck at the arduino stuff.

If you look on youtube.com and search for casa fear zombie as well as bakersben walker witch this is what I'm building. Instead of being 2 separate props though i want them to be a single prop that randomizes 4 different scenarios. If anyone has good knowledge of writing the code and can help me through let me know. I am having a great time figuring it out and am learning something new every day but i need to make sure this thing works before its needed. I am incorporating music into the prop using an ethernet shield as storage via the on-board sdcard. If its gets completed Ill post a video. Kids already don't like coming to the front door because its a pretty intense scene. These things will set me over the top.

I've added a jumping spider that also protrudes outward 30 inches as it raises 28. I'm building 2 of these zombie props, one to act like the videos I suggested another that will tear his head off and flail back and forth using pneumatics.

gp02a0083
10-04-2012, 04:03 AM
as far as the randomization goes.

say you have 4 props

you would have a randomization from 1-4 and have something like

#define Prop1 = 1;
#define Prop2 = 2;
#define Prop1 = 3;
#define Prop2 = 4;


#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
int main()
{
srand((unsigned)time(0));
int random_integer;
int lowest=1, highest=4;
int range=(highest-lowest)+;
random_integer = lowest+int(range*rand()/(RAND_MAX + 1.0));
cout << random_integer << endl;
}

then you would have conditional if statements like

if (random_integer == Prop1)
{ activate prop1}
else

this should "randomize" an integer, show you the integer, then if the randomized integer is equal to what you defined your prop , then it will activate the prop. add a few delays and loop it back, with a little bit of work this snippet of code will work for yah

2oodoor
10-04-2012, 05:00 AM
Ive always wanted to get in to this so Im glad I can observe...

mykwikcoupe
10-04-2012, 06:32 AM
sweet, well this what i would ultimatly like to happen.
-When PIR is low(off) the arduino is playing a background sounds track from the ethernet shields sd card (lets call it track 1)
-The LEDs will be fading random colors slow fade but not at full intesity.

When the PIR is triggered,
-The single prop will play one of 3 scripted scerarios in any random order or in the same order doesnt really matter. Each scenario will be timed 20 seconds.
-The music played will change to the associated tracks, say 2-5 in relation to the scenario being played.
Scenario 1
-The Thrasher sequence starts.
-LEDS on the prop light.
-Music plays track 2.
-RGB LEDS change from random fade to solid green.
-Zombie eyes light up
Scenario 2
-Music plays track 3.
-Zombie eyes light
-RGB LEDS change to blue
-Instead of the thrasher program, both soleniod outputs are tied as a single so they work in unison with another. Timing will have to be played with.
Scenario 3
-Music plays track 4
-Zombie eyes light
-RGB LEDS change to white fast strobe (timing will be played with)
-evilusions program but faster to seems as zombie has gone from night of the living dead to dawn of the dead style


This is the original thrasher code but I believe its written in basic and needs to be translated into c/c++
Thrasher:
FOR idx = 1 TO 3
RANDOM lottery
NEXT
valves = lottery & %00000011

IF valves = last THEN Thrasher ' no repeats
last = valves ' save for next cycle

PINS = valves
RANDOM lottery
delay = lottery // 251 + 100
POT Adjust, 100, tAdj
tDelay = delay
tDelay = tDelay * tAdj / 255
delay = delay + tDelay
PAUSE delay
timer = timer + delay
IF timer < 10000 THEN Thrasher
GOTO Reset

here is the evilusions program but once again written into basic and needs to be changed to work with the arduino
SYMBOL Trigger = PIN6 ' ULN is pull-down
SYMBOL Audio = PIN5
SYMBOL LED = PIN3 ' use V+/OUT2 terminals
SYMBOL Shoulder2 = PIN1 ' use V+/OUT1 terminals
SYMBOL Shoulder1 = PIN0 ' use V+/OUT0 terminals


' -----[ Constants ]-------------------------------------------------------

SYMBOL IsOn = 1 ' for active-high in/out
SYMBOL IsOff = 0 ' put back to low/off

SYMBOL Yes = 1
SYMBOL No = 0

SYMBOL Baud = OT2400 ' baud serial
SYMBOL ThrashTime = 15000

' -----[ Variables ]-------------------------------------------------------

SYMBOL idx = B2
SYMBOL valves = B3
SYMBOL last = B4

SYMBOL delay = W3
SYMBOL timer = W4
SYMBOL lottery = W5


' -----[ Initialization ]--------------------------------------------------

Reset:
PINS = %00000000 ' preset IO pins
DIRS = %00000111 ' define IO pins

PAUSE 10000 ' 10s inter-show delay


' -----[ Program Code ]----------------------------------------------------

Main:
timer = 0 ' reset timer

Check_Trigger:
RANDOM lottery ' randomize lottery value
PAUSE 5 ' loop pad
timer = timer + 5 * Trigger ' inc or clear timer
IF timer < 100 THEN Check_Trigger ' wait for 0.1 sec input

Start_Audio:
Audio = IsOn
PAUSE 100
Audio = IsOff

LED = IsOn

Jump:
PINS = %00000011 ' both shoulders on
PAUSE 1000

Thrasher:
FOR idx = 1 TO 3 ' big stir
RANDOM lottery
NEXT
valves = lottery & %00000011

IF valves = last THEN Thrasher ' no repeats
last = valves ' save for next cycle

PINS = valves ' update should outputs
RANDOM lottery ' restir
delay = lottery // 251 + 100 ' delay 100 to 350 ms
PAUSE delay
timer = timer + delay ' update timer
IF timer < ThrashTime THEN Thrasher ' thrash for 10 seconds
GOTO Reset

My next step is to verify all the pins and get them standardized so tracking the program will be easier. Unfortunatly the pins listed in the 2 programs arent going to match mine.

If I have more time, id like to use another sensor to control another prop, much easier its mostly hardwired.

if thats all taken care of Ill have a 3rd prop similar to the 1st but much larger in scale. He will pull his head off and bend back and forth at the waist before reseting at the normal position.

mykwikcoupe
10-04-2012, 08:07 AM
ROODOO, ITS ACTUALLY VERY EXCITING. Eevn with my many years of electrical knowledge and very limited electronics skills, the amount of tutorials and training materials posted on the web is huge. ive spent about a week reviewing code and reading various ways to write the code. Although i can honestly say i dont feel that i could write the code myself, i can say that its pretty easy to follow the sketches that have been scripted on other projects. im really enjoying it. I will also say that you may loose a few hours of sleep to experimentation.

gp02a0083
10-04-2012, 09:28 AM
you got the idea mykwikcoupe. I would suggest ditching the old code, to me it looks like basic, but its been a long time since i looked at VB.

I would suggest drawing out a list and then work on a flow chart for each of the different functions that you want for each prop.

You are correct that not every snippet of code can be used without a problem, changing the micro controller to another one you will have to "re-map" everything to the right ports. The C++ language is good for this as it is object oriented, unlike Java which is still object oriented but is mainly used for GUI's. C++ is fairly easy to learn due to the fact it uses variable definitions that humans can set. Try doing stuff like that in assembly code, my coworker is so stuck on the assembly and its archaic. Takes like 30 lines of code in assembly to do a simple loop that C can do it in one or two lines.

you will need the data sheet for the micro-controller so that you get the right ports that you want. Most likely your gonna want to use a bunch of analog ports for your application.

Buzo
10-04-2012, 07:30 PM
Did somebody say microcontrollers?

Vanilla Sky
10-04-2012, 07:32 PM
Did somebody say microcontrollers?

Nope, I think they said that Buzo could help :P

mykwikcoupe
10-04-2012, 08:26 PM
yes exactly. I'm starting to compile various codes from library stored sketches. I'm sure anyone with the background will stop and seriously LOL at what it looks like. I'm sure its way out of sequence. This thread could probably end up being super long if I post my entire sketch each time i ask for help. is there a way I could IM anyone here while I'm working on it and you could help walk me through it.

Here's what i have so far for the 1st part of the sketch. Its the PIR warming up for 30 seconds, eliminating false triggers and resetting after each use. I am also including a fade program to accent light the props when the PIR is low (not triggered). When the PIR changes to High I want to add a sequence to change the ambient LEDS to match the color for that sequence. I also need to somehow figure out how to add music. Id like to make it a header file but its going to sequence multiple tracks throughout the program. Anyways start laughing!!!!

//VARS
//the time we give the sensor to calibrate (30 secs according to the datasheet)
int calibrationTime = 30;

//the time when the sensor outputs a low impulse
long unsigned int lowIn;

//the amount of milliseconds the sensor has to be low
//before we assume all motion has stopped
long unsigned int pause = 5000;

boolean lockLow = true;
boolean takeLowTime;

int pirPin = 6; //the digital pin connected to the PIR sensor's output
int ledPin = 13; //onboard test led to check PIR function
int relay1pin = xx; //prop 1 solenoid 1
int relay2pin = xx; //prop 1 solenoid 2
int relay3pin = xx; //prop 2 solenoid 1
int relay4pin = xx; //prop 2 solenoid 2
int zombie1Redpin = xx; //prop 1 ambient led
int zombie1Bluepin = xx; //prop 1 ambient led
int zombie1Greenpin = xx; //prop 1 ambient led
int zombie1eyepin = xx; //prop 1 eye led
int zombie2Redpin = xx; //prop 2 ambient led
int zombie2Bluepin = xx; //prop 2 ambient led
int zombie2Greenpin = xx; //prop 2 ambient led
int zombie2eyespin = xx; //prop 2 eye led

/////////////////////////////
//SETUP
void setup(){
Serial.begin(9600);
pinMode(pirPin, INPUT);
pinMode(ledPin, OUTPUT);
digitalWrite(pirPin, LOW);

//give the sensor some time to calibrate
Serial.print("calibrating sensor ");
for(int i = 0; i < calibrationTime; i++){
Serial.print(".");
delay(1000);
}
Serial.println(" done");
Serial.println("SENSOR ACTIVE");
delay(50);
}

////////////////////////////
//LOOP
void loop(){

if(digitalRead(pirPin) == HIGH){
digitalWrite(ledPin, HIGH); //the led visualizes the sensors output pin state
if(lockLow){
//makes sure we wait for a transition to LOW before any further output is made:
lockLow = false;
Serial.println("---");
Serial.print("motion detected at ");
Serial.print(millis()/1000);
Serial.println(" sec");
delay(50);
}
takeLowTime = true;
}

if(digitalRead(pirPin) == LOW){
digitalWrite(ledPin, LOW); //the led visualizes the sensors output pin state
//Is this where the code that randomizes the props sketches (posted above in a previous reply)would go as well?

if(takeLowTime){
lowIn = millis(); //save the time of the transition from high to LOW
takeLowTime = false; //make sure this is only done at the start of a LOW phase
}
//if the sensor is low for more than the given pause,
//we assume that no more motion is going to happen
if(!lockLow && millis() - lowIn > pause){
//makes sure this block of code is only executed again after
//a new motion sequence has been detected
lockLow = true;
Serial.print("motion ended at "); //output
Serial.print((millis() - pause)/1000);
Serial.println(" sec");
delay(50);
}
}
}

//This example shows how to fade an LED on pin 9, 10, 11 on zombie 1
//using the analogWrite() function.

float RGB1[3];
float RGB2[3];
float INC[3];

int red, green, blue;

int zombie1Redpin = 9; //prop 1 ambient led
int zombie1Bluepin = 10; //prop 1 ambient led
int zombie1Greenpin = 11; //prop 1 ambient led


void setup()
{
Serial.begin(9600);
randomSeed(analogRead(0));

for (int x=0; x<3; x++) {
RGB1[x] = random(256);
RGB2[x] = random(256); }

}

void loop()
{
randomSeed(analogRead(0));

for (int x=0; x<3; x++) {
INC[x] = (RGB1[x] - RGB2[x]) / 256; }

for (int x=0; x<256; x++) {

red = int(RGB1[0]);
green = int(RGB1[1]);
blue = int(RGB1[2]);

analogWrite (zombie1RedPin, red);
analogWrite (zombie1GreenPin, green);
analogWrite (zombie1BluePin, blue);
delay(250);

for (int x=0; x<3; x++) {
RGB1[x] -= INC[x];}

}

for (int x=0; x<3; x++) {
RGB2[x] = random(956)-700;
RGB2[x] = constrain(RGB2[x], 0, 255);

delay(1000);
}

//This example shows how to fade an LED on pin xx, xx, xx on zombie 2
//using the analogWrite() function.

float RGB1[3];
float RGB2[3];
float INC[3];




int red, green, blue;




int zombie2Redpin = xx; //prop 1 ambient led
int zombie2Bluepin = xx; //prop 1 ambient led
int zombie2Greenpin = xx; //prop 1 ambient led





void setup()
{
Serial.begin(9600);
randomSeed(analogRead(0));

for (int x=0; x<3; x++) {
RGB1[x] = random(256);
RGB2[x] = random(256); }




}

void loop()
{
randomSeed(analogRead(0));

for (int x=0; x<3; x++) {
INC[x] = (RGB1[x] - RGB2[x]) / 256; }

for (int x=0; x<256; x++) {

red = int(RGB1[0]);
green = int(RGB1[1]);
blue = int(RGB1[2]);




analogWrite (zombie2RedPin, red);
analogWrite (zombie2GreenPin, green);
analogWrite (zombie2BluePin, blue);
delay(250);




for (int x=0; x<3; x++) {
RGB1[x] -= INC[x];}

}

for (int x=0; x<3; x++) {
RGB2[x] = random(956)-700;
RGB2[x] = constrain(RGB2[x], 0, 255);

delay(1000);
}
as you can see one is written in one format, the other in another. I understand what each sketch is trying to accomplish but don't understand how they could be written in different syntax and both still work. I guess that's the brains of computers. I don't know if all my integers have to be at the top of the 1st sketch or if they can be written throughout the sketch at each step when needed for the 1st time. Ill fill in the 'XX' values when the boards show up and i can solidly confirm the accurate pins. I have them written down at work so maybe Ill edit the thread in the morning to reflect the proper values. Just to confirm, an output is an output no matter what the output is. I was planning on using the PWM outputs as speaker outputs to self powered speakers located on the props. I can in theory play multiple tracks located on the onboard sd card at the same time as the chipset is only performing the function of an output. Sorry its so long and I'm a noob. I can reply to the post 20+ times a day if you want to help expedite the process. I check it very often. I am watching many tutorials as well. The current one is How to write in CPP.

mykwikcoupe
10-04-2012, 08:49 PM
//This example shows how to fade an LED on pin 9, 10, 11 on zombie 1
//using the analogWrite() function.

float RGB1[3];
float RGB2[3];
float INC[3];

int red, green, blue, red1, green1, blue1;

int zombie1Redpin = 9; //prop 1 ambient led
int zombie1Bluepin = 10; //prop 1 ambient led
int zombie1Greenpin = 11; //prop 1 ambient led
int zombie2Redpin = xx; //prop 2 ambient led
int zombie2Bluepin = xx; //prop 2 ambient led
int zombie2Greenpin = xx; //prop 2 ambient led



void setup()
{
Serial.begin(9600);
randomSeed(analogRead(0));

for (int x=0; x<3; x++) {
RGB1[x] = random(256);
RGB2[x] = random(256); }

}

void loop()
{
randomSeed(analogRead(0));

for (int x=0; x<3; x++) {
INC[x] = (RGB1[x] - RGB2[x]) / 256; }

for (int x=0; x<256; x++) {

red = int(RGB1[0]);
green = int(RGB1[1]);
blue = int(RGB1[2]);
red1 = int(RGB1[3]);
blue1 = int(RGB1[4]);
green1 = int(RGB1[5]);

analogWrite (zombie1RedPin, red);
analogWrite (zombie1GreenPin, green);
analogWrite (zombie1BluePin, blue);
analogWrite (zombie2RedPin, red1);
analogWrite (zombie2GreenPin, green1);
analogWrite (zombie2BluePin, blue1);

delay(250);

for (int x=0; x<3; x++) {
RGB1[x] -= INC[x];}

}

for (int x=0; x<3; x++) {
RGB2[x] = random(956)-700;
RGB2[x] = constrain(RGB2[x], 0, 255);

delay(1000);
}
could the above listed code be relabeled like this to randomize both sets of RGB on the props?

Buzo
10-06-2012, 02:07 PM
Could you please tell me details about your hardware? Put a link, pictures, schematics, or anything to help me understand how your controller looks like. I did read your code and I was able to understand it and follow the sequence.

Next reply you can use the # (wrap code) above to keep the indents of your code



for(x=0;x<30;x++) {
do_something
}

mykwikcoupe
10-06-2012, 02:24 PM
http://www.sainsmart.com/evaluation-board/sainsmart-kit/sainsmart-mega2560-ethernet-shield-kit-for-arduino-atmega8u2-w5100.html
That is the board and ethernet shield will be using. It says its based on the arduino mega board style so that is what i have been using to gather pin data.

http://www.arduino.cc/en/Main/ArduinoBoardMega2560
That is the information on the arduino mega. My kit hasnt physically shown up yet.

http://www.arduino.cc/en/Main/ArduinoEthernetShield
That is the arduino ethernet shield as well. Once again, it was purchased for the ability to use the sd card to store music files to be played throughout each sequence.

Buzo
10-06-2012, 05:53 PM
Wow, that board is great! It does the same I do but I have to build the board from scratch for every application.

Now tell me, Have you practiced the "blinking LED" example with this board? I assume yes, but if not, its good idea to start from there to make sure your programmer and connections are OK.

Sorry, I just read that you haven't received the board. So you know what's going to be the first step.


int ledPin = 13; // LED connected to digital pin 13

void setup()
{
pinMode(ledPin, OUTPUT); // sets the digital pin as output
}

void loop()
{
digitalWrite(ledPin, HIGH); // sets the LED on
delay(1000); // waits for a second
digitalWrite(ledPin, LOW); // sets the LED off
delay(1000); // waits for a second
}

mykwikcoupe
10-06-2012, 07:08 PM
Yes exactly. I have a series of about 15 indivodual programs to try. I have the concept and the wiring knowhow. If I knew the program code id be set. I wanted to biy the actual arduino boards the prive was about double

mykwikcoupe
10-08-2012, 11:43 AM
#include <iostream>
#include <ctime>
#include <cstdlib>

int pirPin = 6;
int ledpin = 13;
int relay1pin = 21; //solenoid 1
int relay2pin = 22; //solenoid 2
int relay3pin = 23; //solenoid 3
int relay4pin = 24; //solenoid 4

void setup(){
pinMode(pirPin, INPUT);
pinMode(ledPin, OUTPUT);
pinMode (relay1pin, OUTPUT);
pinMode (relay2pin, OUTPUT)
pinMode (relay3pin OUTPUT);
pinMode (relay4pin OUTPUT);

#define relay1 = 1;
#define relay2 = 2;
#define relay3 = 3;
#define relay4 = 4;


int main()

srand((unsigned)time(0));
int random_integer;
int lowest=1, highest=4;
int range=(highest-lowest)+;
random_integer = lowest+int(range*rand()/(RAND_MAX + 1.0));
cout << random_integer << endl;
}

void loop()
{

if (random_integer == relay1)
(activate prop1)

if (random_integer == relay2)
(activate prop2)

if (random_integer == relay3)
(activate prop3)

if (random_integer == relay4)
(activate prop4)
}
else

this is what i have come up with so far. Obviously i have changed the naming convention.

In the end sequence, is that correct or should it say

else
if (activate prop) sequence?

should my relay1-4 be labelled to be relay1pin etc to match the naming convention the entire way through?

under the srand((unsigned)time(0));, cant his be changed to any random delay? the way im reading this, the relays will click with instantaneos time delay. Can i make this any value to match the needs of the program?

Thank you for the help. This code has been verified for proper format but i cant verify functionality as my equipment hasnt shown up yet.

Buzo
10-08-2012, 12:50 PM
should my relay1-4 be labelled to be relay1pin etc to match the naming convention the entire way through?

No because Relay1-4 are constants and relay1pin are variables.
It doesn't matter how you name stuff, as long as you remember it as your program grows up.


under the srand((unsigned)time(0));, cant his be changed to any random delay?

I would need to check how this random generator works, but basically you use a random generator to get any value between 1 and 4 repeated through the time with no specific order or pattern. I understand you want to introduce a delay to the equation, so besides the random order, you would like a random delay between generated numbers, right?


..the relays will click with instantaneos time delay.

No, only the prop equals to the randomly generated value will be activated.

Something that I guess is missing is that you need to deactivate a prop that was activated in the step before, unless you want them all at the same time, but still you need to add something to your code to deactivate them.

for instance:

if (random_integer == relay1)
(activate prop1)
(deactivate prop2)
(deactivate prop3)
(deactivate prop4)

if (random_integer == relay2)
(activate prop2)
(deactivate prop1)
(deactivate prop3)
(deactivate prop4)

if (random_integer == relay3)
(activate prop3)
(deactivate prop2)
(deactivate prop1)
(deactivate prop4)

if (random_integer == relay4)
(activate prop4)
(deactivate prop2)
(deactivate prop3)
(deactivate prop1)

mykwikcoupe
10-08-2012, 01:36 PM
Yes the random delay would be nice as well. I suppose it would ha e a maximumvalue or 3 seconds and a minimum value of 250ms. Thats great. Thanks for the help

mykwikcoupe
10-08-2012, 04:51 PM
randOn = random (100, 3000); // generate ON time between 0.1 and 3 seconds
randOff = random (200, 3000); // generate OFF time between 0.2 and 3 seconds
digitalWrite(relay1-4, HIGH); // sets the relay on
delay(randOn); // waits for a random time while ON
digitalWrite(relay1-4, LOW); // sets the relay off
delay(randOff); // waits for a random time while OFF

would this work as a random delay on and off work? Im not sure if it can be as simple as placing the (min, max) and be done or if you need a comparison (min, max, 100, 3000)? Ive also read that you can do a random seed but that looks a bit on the complex side as well.

Could this also be written into the program as:
if (random_integer == relay1);
(relay1 == high);
delay(randOn);
(relay2 == low);
delay(randOff);
(relay3 == low);
delay(randOff);
(relay4 == low);
delay(randOff);

if (random_integer == relay2);
(relay2 == high);
delay(randOn);
(relay1 == low);
delay(randOff);
(relay3 == low);
delay(randOff);
(relay4 == low);
delay(randOff);

(would these be separated by (if) or (else)

Sorry if Im asking improper questions or if non of this makes sense. Im entering my second week of research and training on my own with alot of internet help and co worker help.

mykwikcoupe
10-08-2012, 06:17 PM
#include <iostream>
#include <ctime>
#include <cstdlib>

int pirPin = 6; //the digital pin connected to the PIR sensor's output
int ledPin = 13; //onboard test led to check PIR function
int relay1pin = 21; //solenoid 1
int relay2pin = 22; //solenoid 2
int relay3pin = 23; //solenoid 3
int relay4pin = 24; //solenoid 4
int zombie1Redpin = 9; //prop 1 ambient led
int zombie1Bluepin = 10; //prop 1 ambient led
int zombie1Greenpin = 11; //prop 1 ambient led
int zombie1eyepin = 12; //prop 1 eye led
int zombie2Redpin = 50; //prop 2 ambient led
int zombie2Bluepin = 51; //prop 2 ambient led
int zombie2Greenpin = 52; //prop 2 ambient led
int zombie2eyespin = 53; //prop 2 eye led

//VARS
//the time we give the sensor to calibrate (30 secs according to the datasheet)
int calibrationTime = 30;

//the time when the sensor outputs a low impulse
long unsigned int lowIn;

//the amount of milliseconds the sensor has to be low
//before we assume all motion has stopped
long unsigned int pause = 5000;

boolean lockLow = true;
boolean takeLowTime;



/////////////////////////////
//SETUP
void setup()
{
Serial.begin(9600);
pinMode(pirPin, INPUT);
pinMode(ledPin, OUTPUT);
digitalWrite(pirPin, LOW);
pinMode(pirPin, INPUT);
pinMode(ledPin, OUTPUT);
pinMode (relay1pin, OUTPUT);
pinMode (relay2pin, OUTPUT);
pinMode (relay3pin, OUTPUT);
pinMode (relay4pin, OUTPUT);
pinMode (zombie1Redpin, OUTPUT);
pinMode (zombie1Bluepin, OUTPUT);
pinMode (zombie1Greenpin, OUTPUT);
pinMode (zombie1eyepin, OUTPUT);
pinMode (zombie2Redpin, OUTPUT);
pinMode (zombie2Bluepin, OUTPUT);
pinMode (zombie2Greenpin, OUTPUT);
pinMode (zombie2eyespin, OUTPUT);


//give the sensor some time to calibrate
Serial.print("calibrating sensor ");
for(int i = 0; i < calibrationTime; i++)
Serial.print(".");
delay(1000);

Serial.println(" done");
Serial.println("SENSOR ACTIVE");
delay(50);
}

////////////////////////////
//LOOP
void loop(){

if(digitalRead(pirPin) == HIGH)
digitalWrite(ledPin, HIGH); //the led visualizes the sensors output pin state
if(lockLow)
//makes sure we wait for a transition to LOW before any further output is made:
lockLow = false;
Serial.println("---");
Serial.print("motion detected at ");
Serial.print(millis()/1000);
Serial.println(" sec");
delay(50);

takeLowTime = true;


if(digitalRead(pirPin) == LOW)
digitalWrite(ledPin, LOW); //the led visualizes the sensors output pin state
//Is this where the code that randomizes the props sketches (posted above in a previous reply)would go as well?

if(takeLowTime)
lowIn = millis(); //save the time of the transition from high to LOW
takeLowTime = false; //make sure this is only done at the start of a LOW phase

//if the sensor is low for more than the given pause,
//we assume that no more motion is going to happen
if(!lockLow && millis() - lowIn > pause)
//makes sure this block of code is only executed again after
//a new motion sequence has been detected
lockLow = true;
Serial.print("motion ended at "); //output
Serial.print((millis() - pause)/1000);
Serial.println(" sec");
delay(50);



#define relay1 = 1;
#define relay2 = 2;
#define relay3 = 3;
#define relay4 = 4;


int main();

srand((unsigned)time(0));
int random_integer;
int lowest=1, highest=4;
int range=(highest-lowest)+;
random_integer = lowest+int(range*rand()/(RAND_MAX + 1.0));
cout << random_integer << endl;


if (random_integer == relay1);
(relay1 == high);
delay(randOn);
(relay2 == low);
delay(randOff);
(relay3 == low);
delay(randOff);
(relay4 == low);
delay(randOff);

if (random_integer == relay2);
(relay2 == high);
delay(randOn);
(relay1 == low);
delay(randOff);
(relay3 == low);
delay(randOff);
(relay4 == low);
delay(randOff);

if (random_integer == relay3);
(relay1 == high);
delay(randOn);
(relay1 == low);
delay(randOff);
(relay2 == low);
delay(randOff);
(relay4 == low);
delay(randOff);

if (random_integer == relay4);
(relay4 == high);
delay(randOn);
(relay1 == low);
delay(randOff);
(relay2 == low);
delay(randOff);
(relay3 == low);
delay(randOff);
}
Thats what I have currently. Does it make sense and will it work. I think what someone needs to create is a arduino gui simulator that you can real time load and test to without physically wiring anything. It would have to assume all electrical connects are correct. It would add another layer to troubleshooting.

Buzo
10-08-2012, 08:36 PM
You are going to need to separate your code in several stages and test each one at the time.

For instance, I'm am working right now modifying a piece of equipment where I need to send several information through a serial cable to a remote LCD. There is one micro inside the cabinet and another 10 feet away in the LCD.

1) I first assured I could program my controllers individually
2) Then I worked in the controller of the LCD. I draw stuff into the LCD just to make sure I can access every single corner of the screen.
3) Then the serial communication from the Equipment to my computer
4) The serial communication from the LCD to my computer
5) the serial communication between the two controllers.

I don't have sensors connected yet, I simulate the presence of a sensor with software, sensor=1 or sensor=0 until I get the code to flow as I want, then I test the outputs of the sensors with the voltmeter to make sure they are sending the correct signal. and finally connect the sensors to the controllers.

Write small routines like turning ON one output by one, then turn them off.
Then add delays, like the standard off delay contacts you are familiar width.
Make your controller to communicate with your computer if possible, so you "see" what the controller is doing. Send messages like "activating PORT1..." etc.

Leave the random stuff for the end, one usually want to know how long a contact should be ON or OFF, and using random numbers they will just be ON and OFF like crazy.

I think you are doing a good progress here. You will see how fun is to have stuff doing what you imagined exactly as you imagined it.

mykwikcoupe
10-08-2012, 09:01 PM
my coworker calls it a video game. You may not know if you are winning or losing till the end but it really is a great game to play.

I understand what your saying I will do that when my stuff shows up. Until then, does it make sense in code speak? Does it look correct? I can only go off what I have read and watched on youtube but that doesn't necessarily make the original code writers good at writing code. I would agree that i am probably biting off more then I chew but if it looks that I am progressing in the right direction then I am happy.

I really appreciate the help. does it seem that the syntacs from one section to the next are flowing correctly? The best I have to go from is the arduino ide gui. Its a very basic compiler. It will correct format if there are no errors and will help you to debug. That being said it doesnt write the code for you. I still have a ton to learn such as how to use a header file to be able to delete the bulk of the code.

In the end I purchase the mega to be able to expand and control the halloween setting dynamically. I have 8 analog inputs and near limitless digitals. Id like to have this one device control everything. I dont think that will happen before next years show.

I will try to individualize the sequences. does the random soleniod code look good? how do you add music reference to the code? Thats going to be my last step as its the one Ive spent the least time researching.

Back to my video game.

Buzo
10-09-2012, 06:52 AM
Your code sequences look correct to me!

After searching over and over about C I found this site: http://publications.gbdirect.co.uk/c_book/ with all you need to know about programming. You don't need to read it all, but if you have syntax issues when compiling you can go here and find how to properly write a for-next, an if-else, a do-while.

Tell me more about the rest of your hardware, Are you going to use 5V relays to activate your solenoids? How many pneumatic cylinders for each prop? Are all the lights for 5V or do you have some for 110V?

I watched the videos you posted, they are very scaring by the way!

mykwikcoupe
10-09-2012, 07:09 AM
int ranNum;
int ranDel;
void setup() {
// Seed RNG from analog port.
randomSeed(analogRead(0));
// Setup 4 output ports for Relays
pinMode(21, OUTPUT);
pinMode(22, OUTPUT);
pinMode(23, OUTPUT);
pinMode (24, OUTPUT);
}
void loop() {
//Generate random number between 21 and 24
ranNum=random(21,24);
// Generate random delay time
ranDel=random(25,300);
//Turn on the Relay
digitalWrite(ranNum, HIGH);
delay(ranDel);
//Turn off the Relay
digitalWrite(ranNum, LOW);
}

It works, my first sketch and it works. I sure am glad arduino has a huge backbone of resources behind it. No way I could ever figure this out on my own.
Credit for the build:
http://www.meanpc.com/2012/01/random-flasher-arduino-project.html

gp02a0083
10-09-2012, 09:05 AM
its nice to see others here on the board with some micro-controller knowledge. This is stuff I'm learning at work from an assembly language and C code point of view

mykwikcoupe
10-09-2012, 11:22 AM
i looked into assembly language. Its nice to know the LONG hand version of writing and how these programs originally got written and how easy is it now that you can include header files and pre scripted codes.

I played with it a bit more afterwards. Ive got fading leds that will eventually turn into color changing LEDS. I need to include the ambient LEDS that turn on with the program but that shouldnt be too hard I hope. Its really nice to be able to see it work as well.

Buzo
10-09-2012, 05:33 PM
Congratulations! Your electrical background is certainly helping a lot. At the end it is the same, positive, negative, open, closed.

gp02a0083
10-10-2012, 09:13 AM
i looked into assembly language. Its nice to know the LONG hand version of writing and how these programs originally got written and how easy is it now that you can include header files and pre scripted codes.

I played with it a bit more afterwards. Ive got fading leds that will eventually turn into color changing LEDS. I need to include the ambient LEDS that turn on with the program but that shouldnt be too hard I hope. Its really nice to be able to see it work as well.

just curious about the LED's your using, for dimming are you PWM'ing them?

mykwikcoupe
10-11-2012, 07:50 AM
Ok so Im working on the sketch. In this sketch I was 2 things happening at a time. One the leds flash randomly to cause a strobe like effect currently 25, 50. I also have the relays going off on a random delay600, 100. Because the loop takes the time of the longest value to repeat, how can I get both actions to happen simultaniously without waiting for the entire loop to repeat?

#include <iostream>
#include <ctime>
#include <cstdlib>

int redPin = 9;
int greenPin = 10;
int bluePin = 11;
int redVal = (100, 100, 100);
int greenVal = (100, 100, 100);
int blueVal = (100, 100, 100);
int eyesPin = 13; //steady on when trigger
int relay1pin = 2; //solenoid 1
int relay2pin = 3; //solenoid 2
int relay3pin = 4; //solenoid 3
int relay4pin = 5; //solenoid 4
int ranNum;
int ranDel;
int ranDelay;

void setup()
{
pinMode (redPin, OUTPUT);
pinMode (greenPin, OUTPUT);
pinMode (bluePin, OUTPUT);
pinMode(eyesPin, OUTPUT);
pinMode (relay1pin, OUTPUT);
pinMode (relay2pin, OUTPUT);
pinMode (relay3pin, OUTPUT);
pinMode (relay4pin, OUTPUT);
randomSeed(analogRead(0)); // Seed RNG from analog port.

#define relay1 = 1;
#define relay2 = 2;
#define relay3 = 3;
#define relay4 = 4;
}

void loop()
{
digitalWrite(eyesPin, HIGH); //the led visualizes the sensors output pin state

{
ranDelay=random(25,50); // Generate random delay time
analogWrite(redPin, redVal); // Write current values to LED pins
analogWrite(greenPin, greenVal);
analogWrite(bluePin, blueVal);
delay(ranDelay);
analogWrite(redPin, LOW); //Turn off the led
analogWrite(greenPin, LOW); //Turn off the led
analogWrite(bluePin, LOW); //Turn off the led
}
{
if (analogRead(0));
ranNum=random(1,6); //Generate random number between 2 and 6
ranDel=random(300,1000); // Generate random delay time
digitalWrite(ranNum, HIGH); //Turn on the Relay
delay(ranDel);
digitalWrite(ranNum, LOW); //Turn off the Relay
}
}

Yes it works but the shorter time is delayed but the longer time to complete the loop and repeat. Thanks

mykwikcoupe
10-11-2012, 02:08 PM
#include <iostream>
#include <ctime>
#include <cstdlib>

const int redPin = 9;
const int eyesPin = 13; //steady on when trigger
const int relay1pin = 2; //solenoid 1
const int relay2pin = 3; //solenoid 2
const int relay3pin = 4; //solenoid 3
const int relay4pin = 5; //solenoid 4
int ranNum;
int ranDel;
int ledState = LOW; // ledState used to set the LED
long previousMillis = 0; // will store last time LED was updated
long interval = 10; // interval at which to blink (milliseconds)

void setup()
{
pinMode (redPin, OUTPUT);
pinMode(eyesPin, OUTPUT);
pinMode (relay1pin, OUTPUT);
pinMode (relay2pin, OUTPUT);
pinMode (relay3pin, OUTPUT);
pinMode (relay4pin, OUTPUT);


#define relay1 = 1;
#define relay2 = 2;
#define relay3 = 3;
#define relay4 = 4;

}
void loop()
{
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;

// if the LED is off turn it on and vice-versa:
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;}

// set the LED with the ledState of the variable:
digitalWrite(redPin, ledState);

{
digitalWrite(eyesPin, HIGH); //the led visualizes the sensors output pin state
}
// here is where you'd put code that needs to be running all the time.
{
randomSeed(analogRead(0)); // Seed RNG from analog port.
if (analogRead(0));
ranNum=random(1,6); //Generate random number between 2 and 6
ranDel=random(300,1000); // Generate random delay time
digitalWrite(ranNum, HIGH); //Turn on the Relay
delay(ranDel);
digitalWrite(ranNum, LOW); //Turn off the Relay
}
}


This works but the ledPin 9 is supposed to be acting like a strobe light and i cant get it to flash and faster than every 1sec roughly guessing. Howe can i write it in. If i change the long interval amount to less then 1000 I get no change in current flash. I can change it to greater than 1000 and it works? make it faster!!!!

Buzo
10-12-2012, 07:52 AM
Because the loop takes the time of the longest value to repeat, how can I get both actions to happen simultaniously without waiting for the entire loop to repeat?

One way to do this is to use cycle counters instead of "delays"


For example,



int cycle_counter_1=0;
int cycle_counter_2=0;

loop
{

Turn_on_LEDS;
cycle_counter_1++; // increase one time each program cycle
if(cycle_counter_1>stored_ranDelay)
{ turn_off_LEDS;
cycle_counter_1=0; // reset the counter to start over
stored_ranDelay=ranDelay; // store the next delay
}

execute_another_routine_here;
cycle_counter_2++;
if(cycle_counter2...etc, etc)

}


It depends how fast your cycle runs, you may need to multiply your ranDelay*100 or by any number that gives you the desired delay.

Edit:
Since I guess the software generates one ranDelay value each cycle, you need to store one ranDelay in a variable and update it when the counter finsihed counting

Buzo
10-12-2012, 08:12 AM
This works but the ledPin 9 is supposed to be acting like a strobe light and i cant get it to flash and faster than every 1sec roughly guessing.

Its because of your delay

...
digitalWrite(ranNum, HIGH); //Turn on the Relay
delay(ranDel);
digitalWrite(ranNum, LOW); //Turn off the Relay
...

Another way to make a LED blink faster is using a timer and an interruption.
The timer "counts" independently of your code and it will interrupt whatever the code is doing to toggle the LED. But you need to learn how to set up the timer, and enable the interruptions before.

To keep it simple, try using the cycle counter technique again.

mykwikcoupe
10-12-2012, 09:16 AM
Its because of your delay

...
digitalWrite(ranNum, HIGH); //Turn on the Relay
delay(ranDel);
digitalWrite(ranNum, LOW); //Turn off the Relay
...

Another way to make a LED blink faster is using a timer and an interruption.
The timer "counts" independently of your code and it will interrupt whatever the code is doing to toggle the LED. But you need to learn how to set up the timer, and enable the interruptions before.

To keep it simple, try using the cycle counter technique again.

I think I understand what you are saying. the ranDel is biult into the relay code not the led code. Because they are written into different programs I assumed this would keep the timings separate as well? Im looking for a led strobe to toggle on and off at the speed of about 125ms and run with the relays but keep different timings. I believe at this time the Millis() function is a bit abopve me still. Im having a hard time reading the operations in code.

I have gotten different functions to work but they are variations of the same code not different codes all together. Thanks for the help. I will try some more.

Buzo
10-12-2012, 12:52 PM
Te execution of the code starts from the word "loop() {" and executes line by line in sequence down to the final "}" and goes back to the "loop() {" forever.

Try to find a delay function that give you microseconds instead of milliseconds for shorter delays.
If a delay of milliseconds is written as millis(), try micros() haha. Seriously, this arduino thing must have a microseconds delay instruction.

mykwikcoupe
10-12-2012, 01:45 PM
I was going to try that actually. I have read that people reference the micros() function but that was in agruement over how long the internal loop could be.. days,hours,minutes,seconds,milliseconds,microsecon ds.

You make the comment my code was flawed based on the ranDel function. Can you think of a different way to write it?

I would change the miilis() to micros() but changing the millis() has no effect only to exent the delay time not to reduce it? My next attempt is the interupt function. I figure worst case scenario, if this doesnt work my fallback is another relay control constant on like the eyes for the duration of the sketch powering a 120v actual strobelight. I have one more cade to figure out then I get to try and compile them together and add music.

gp02a0083
10-12-2012, 05:33 PM
idk ive used delay_ms(1) or delay_us(1000) either one would give you a 1 ms delay

mykwikcoupe
10-13-2012, 07:50 AM
That would create a delay inside the original loop timings. I would like to create a separate loop timings. This way i can have the strobe timings different from the relay timings and not dependent on each other based on the entire loop timings. Is there a way to do this?

mykwikcoupe
10-23-2012, 02:23 PM
Ok so Ive come into a problem with the code itself and im stuck. The code compiles and everything looks alright to me. The problem is it only loops the audio and never performs the actual other functions. Whats supposed to happen, the PIR goes off, the music plays, the 2 random relays do there thing and relay 3 is constant with pin 13. After the PIR timeout period of non movement it goes back to rest awaiting the cycle to begin again.


#include <iostream>
#include <ctime>
#include <cstdlib>
#include <SD.h>
File myFile;

int calibrationTime = 30; //the time we give the sensor to calibrate (10-60 secs according to the datasheet)
long unsigned int lowIn; //the time when the sensor outputs a low impulse
long unsigned int pause = 5000; //the amount of milliseconds the sensor has to be low before we assume all motion has stopped
boolean lockLow = true;
boolean takeLowTime;

int pirPin = 3; //the digital pin connected to the PIR sensor's output
int eyesPin = 13; //led connected to zombie eyes
int relay1pin = 47; //solenoid 1
int relay2pin =48; //solenoid 2
int relay3pin = 50; //solenoid 3
int relay4pin = 51; //solenoid 4
int ranNum;
int ranDel;


void setup()
{
pinMode(53, OUTPUT);
pinMode(pirPin, INPUT);
pinMode(eyesPin, OUTPUT);
pinMode (relay1pin, OUTPUT);
pinMode (relay2pin, OUTPUT);
pinMode (relay3pin, OUTPUT);
pinMode (relay4pin, OUTPUT);
// Seed RNG from analog port.
randomSeed(analogRead(0));

#define relay1 = 1;
#define relay2 = 2;
#define relay3 = 3;
#define relay4 = 4;
digitalWrite(pirPin, LOW);
Serial.print("calibrating sensor "); //give the sensor some time to calibrate
for(int i = 0; i < calibrationTime; i++){
Serial.print(".");
delay(1000);
}
Serial.println(" done");
Serial.println("SENSOR ACTIVE");
delay(50);
}


void loop() {
Serial.begin(9600); // Open serial communications and wait for port to open:
Serial.print("Initializing SD card...");
// On the Ethernet Shield, CS is pin 4. It's set as an output by default.
// Note that even if it's not used as the CS pin, the hardware SS pin
// (10 on most Arduino boards, 53 on the Mega) must be left as an output
// or the SD library functions will not work.

if (!SD.begin(4)) {
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");

// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
myFile = SD.open("JUSTIN~1.MP3");
if (myFile) {
Serial.println("JUSTIN~1.MP3:");

// read from the file until there's nothing else in it:
while (myFile.available()) {
Serial.write(myFile.read());
}
// close the file:
myFile.close();
}
else {
// if the file didn't open, print an error:
Serial.println("error opening JUSTIN~1.MP3");
}
if(digitalRead(pirPin) == LOW){
digitalWrite(eyesPin, HIGH); //the led visualizes the sensors output pin state
digitalWrite(relay3pin, HIGH); //Real 3 to ambient leds

ranNum=random(46,49); //Generate random number between 8 and 10
ranDel=random(25,300); // Generate random delay time
digitalWrite(ranNum, HIGH); //Turn on the Relay
delay(ranDel);
digitalWrite(ranNum, LOW); //Turn off the Relay

if(lockLow){
//makes sure we wait for a transition to LOW before any further output is made:
lockLow = false;
Serial.println("---");
Serial.print("motion detected at ");
Serial.print(millis()/10000);
Serial.println(" sec");
delay(50);
}
takeLowTime = true;


if(digitalRead(pirPin) == HIGH){
digitalWrite(eyesPin, LOW); //the led visualizes the sensors output pin state
digitalWrite(relay3pin, LOW);
if(takeLowTime){
lowIn = millis(); //save the time of the transition from high to LOW
takeLowTime = false; //make sure this is only done at the start of a LOW phase
}
//if the sensor is low for more than the given pause,
//we assume that no more motion is going to happen
if(!lockLow && millis() - lowIn > pause){
//makes sure this block of code is only executed again after
//a new motion sequence has been detected
lockLow = true;
Serial.print("motion ended at "); //output
Serial.print((millis() - pause)/1000);
Serial.println(" sec");
delay(50);
}
}
}
}

Buzo
10-23-2012, 04:21 PM
Its the same basic problem of the separated delays you had before.

/
/ read from the file until there's nothing else in it:
while (myFile.available()) {
Serial.write(myFile.read());
}

The above code stays in a loop as long as there is something to read in the file, so the rest of the steps get executed until the music has done playing.

What I do when I work with serial communications is that I send one byte for each program cycle.

Your serial speed is 9600 bps, while your code is executed at 1000000 times per second, so you should be able to play the song with no interruptions.

I'll leave all your logic to open the file as is, but I'll change your play code to something like:

loop() {

if (myFile.available())
Serial.write(myFile.read());
else
myFile.close();

...


But you have other basic mistakes, like initializing the serial communication and opening the file inside the loop.

Everything that is done only one time must be done before the loop, and the things that must be repeated, counters, etc. must be done inside the loop

mykwikcoupe
10-23-2012, 06:18 PM
ok so let me ask this, the program will run as long as the PIR is high and 5 seconds after low to be sure it truely is low(I know I changed the code not to reflect this). Since the entire thing will continue for that unknown duration, how would you write it.

The other option would be to trigger the PIR, run for 30 seconds and reset with a 5 second delay before the PIR could be triggered again.

Another thing I would like to work in, a sketch will play before the PIR is triggered, when triggered it will activate the sketch then return. I believe i would do this using the sketchbook. I was going to load the files into another sketch noting the entire sketch to run such as

sketch1.H
pir = LOW
analogWrite(sketch2.H); type of format. Do you have IM or anything I can reach you on. I worked on that audio issue for 6 hrs today not being able to figure out the problem. I though for sure it was in the curvy brackets someplace.

2oodoor
10-31-2012, 04:26 PM
I hope you get a video!

mykwikcoupe
11-02-2012, 04:54 AM
We had a storm blow through for a few days prior to halloween. This basically destroyed a lot of my bigger props. They were biult to handle being outdoors in the winter but not a storm. I spent the nights before fixing these as opposed to completing the new single prop.

Halloween was awesome though. 77 treaters and nearly a 100%scare/scream ratio. Even most of the parents got scared. I biult a leaping spider. Its about 2ft across,mounted to a 24in drawer slide tied to a 4ft piece of wood. The action is pneumatic and launches the spider up and forwards. When the 1st action in complete it pushes out the 2nd air cylinder moving the spider another 18inches. Total travel is nealy 5ft and it all happens in a second.

As you walk into the main haunt area I have a zombie with his head cut off. Hes holding his head and looking like hes ready to walk towards you. He has a strobe on him so that s what everyone notices first. The next draw is the magic/potions tables. Lots of cool stuff basically but a huge attention draw. By this time youve seen me, a static throw together bad posture, oversized hands scary snarling mask but ive got the candy. You move past the spider. He shakes slowly with the weighted motor on the frame. Almost to me ypu trip the sensor that activates the spider you passed a few feet ago. In an instant hes in thes in the air jumping towards you. You react and run towards the zombie. He makes sounds all the sudden, you move towards me still static. I vary on reactions. Wish I had a video camera it was awesome

mykwikcoupe
11-30-2012, 02:16 PM
Ok so heres the latest revampment. It does everything except the leds which ill add last. Im wondering though, Currently i have individual pushbuttons doing these steps as they go. What I want is for pushbutton 0 to play (whenever no other pushbuttons are triggered) in a loop. I also would like to add that when that one pushbutton is triggered and goes high it will trigger the other pushbuttons. I believe this needs to be a boolean register? So each time it is triggered from low to high it counts one more up to 4 and then resets to 1 to cycle again. Is this possible inside this current code? I realize that the code is very abstract at this time but it works and Im not sure how to clean it all up. I am using the arduino mega 2650 and the waveshield to play.

#include <FatReader.h>
#include <SdReader.h>
#include <avr/pgmspace.h>
#include <WaveUtil.h>
#include <WaveHC.h>
#include <iostream.h>
#include <ctime.h>
#include <cstdlib.h>

SdReader card; // This object holds the information for the card
FatVolume vol; // This holds the information for the partition on the card
FatReader root; // This holds the information for the filesystem on the card
FatReader f; // This holds the information for the file we're play
WaveHC wave; // This is the only wave (audio) object, since we will only play one at a time
#define DEBOUNCE 5 // button debouncer
// here is where we define the buttons that we'll use. button "1" is the first, button "6" is the 6th, etc
byte buttons[] = {24, 25, 26, 27, 28, 29};// the analog 0-5 pins are also known as 14-19 on uno board
// This handy macro lets us determine how big the array up above is, by checking the size
#define NUMBUTTONS sizeof(buttons)
// we will track if a button is just pressed, just released, or 'pressed' (the current state
volatile byte pressed[NUMBUTTONS], justpressed[NUMBUTTONS], justreleased[NUMBUTTONS];

int relay1pin = 31; //solenoid 1
int relay2pin = 32; //solenoid 2
int relay3pin = 33; //solenoid 3
int relay4pin = 34; //solenoid 4
int ranNum;
int ranDel;

// this handy function will return the number of bytes currently free in RAM, great for debugging!
int freeRam(void)
{
extern int __bss_end;
extern int *__brkval;
int free_memory;
if((int)__brkval == 0) {
free_memory = ((int)&free_memory) - ((int)&__bss_end);
}
else {
free_memory = ((int)&free_memory) - ((int)__brkval);
}
return free_memory;
}
void sdErrorCheck(void)
{
if (!card.errorCode()) return;
putstring("\n\rSD I/O error: ");
Serial.print(card.errorCode(), HEX);
putstring(", ");
Serial.println(card.errorData(), HEX);
while(1);
}
void setup() {
byte i;

Serial.begin(9600);// set up serial port
putstring_nl("WaveHC with ");
Serial.print(NUMBUTTONS, DEC);
putstring_nl("buttons");

putstring("Free RAM: "); // This can help with debugging, running out of RAM is bad
Serial.println(freeRam()); // if this is under 150 bytes it may spell trouble!

// Set the output pins for the DAC control. This pins are defined in the library
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(relay1pin, OUTPUT);
pinMode(relay2pin, OUTPUT);
pinMode(relay3pin, OUTPUT);
pinMode(relay4pin, OUTPUT);
#define relay1 = 1;
#define relay2 = 2;
#define relay3 = 3;
#define relay4 = 4;
pinMode(13, OUTPUT);// pin13 LED

// Make input & enable pull-up resistors on switch pins
for (i=0; i< NUMBUTTONS; i++) {
pinMode(buttons[i], INPUT);
digitalWrite(buttons[i], HIGH);
}

// if (!card.init(true)) { //play with 4 MHz spi if 8MHz isn't working for you
if (!card.init()) { //play with 8 MHz spi (default faster!)
putstring_nl("Card init. failed!"); // Something went wrong, lets print out why
sdErrorCheck();
while(1); // then 'halt' - do nothing!
}

// enable optimize read - some cards may timeout. Disable if you're having problems
card.partialBlockRead(true);

// Now we will look for a FAT partition!
uint8_t part;
for (part = 0; part < 5; part++) { // we have up to 5 slots to look in
if (vol.init(card, part))
break; // we found one, lets bail
}
if (part == 5) { // if we ended up not finding one :(
putstring_nl("No valid FAT partition!");
sdErrorCheck(); // Something went wrong, lets print out why
while(1); // then 'halt' - do nothing!
}

// Lets tell the user about what we found
putstring("Using partition ");
Serial.print(part, DEC);
putstring(", type is FAT");
Serial.println(vol.fatType(),DEC); // FAT16 or FAT32?

// Try to open the root directory
if (!root.openRoot(vol)) {
putstring_nl("Can't open root dir!"); // Something went wrong,
while(1); // then 'halt' - do nothing!
}

// Whew! We got past the tough parts.
putstring_nl("Ready!");

TCCR2A = 0;
TCCR2B = 1<<CS22 | 1<<CS21 | 1<<CS20;
//Timer2 Overflow Interrupt Enable
TIMSK2 |= 1<<TOIE2;

}
SIGNAL(TIMER2_OVF_vect) {
check_switches();
}
void check_switches()
{
static byte previousstate[NUMBUTTONS];
static byte currentstate[NUMBUTTONS];
byte index;
for (index = 0; index < NUMBUTTONS; index++) {
currentstate[index] = digitalRead(buttons[index]); // read the button

/*
Serial.print(index, DEC);
Serial.print(": cstate=");
Serial.print(currentstate[index], DEC);
Serial.print(", pstate=");
Serial.print(previousstate[index], DEC);
Serial.print(", press=");
*/

if (currentstate[index] == previousstate[index]) {
if ((pressed[index] == LOW) && (currentstate[index] == LOW)) {
// just pressed
justpressed[index] = 1;
}
else if ((pressed[index] == HIGH) && (currentstate[index] == HIGH)) {
// just released
justreleased[index] = 1;
}
pressed[index] = !currentstate[index]; // remember, digital HIGH means NOT pressed
}
//Serial.println(pressed[index], DEC);
previousstate[index] = currentstate[index]; // keep a running tally of the buttons
}
}

void loop() {
byte i;
static byte playing = -1;

if (pressed[0]) {
if (playing != 0) {
playing = 0;
playfile("JB.WAV");
}
}
else if (pressed[1]) {
if (playing != 1) {
playing = 1;
playfile("JB1.WAV");
{
while (pressed[1]){
ranNum=random(30,35); //Generate random number between 8 and 10
ranDel=random(25,300); // Generate random delay time
digitalWrite(ranNum, HIGH); //Turn on the Relay
delay(ranDel);
digitalWrite(ranNum, LOW); //Turn off the Relay
}
}
}
}
else if (pressed[2]) {
if (playing != 2) {
playing = 2;
playfile("JB2.WAV");
{
while (pressed[2]){
ranNum=random(30,35); //Generate random number between 8 and 10
ranDel=random(250,500); // Generate random delay time
digitalWrite(ranNum, HIGH); //Turn on the Relay
delay(ranDel);
digitalWrite(ranNum, LOW); //Turn off the Relay
}
}
}
}
if (! wave.isplaying) {
playing = -1;
}
}
// Plays a full file from beginning to end with no pause.
void playcomplete(char *name) {
// call our helper to find and play this name
playfile(name);
while (wave.isplaying) {
// do nothing while its playing
}
// now its done playing
}
void playfile(char *name) {
// see if the wave object is currently doing something
if (wave.isplaying) {// already playing something, so stop it!
wave.stop(); // stop it
}
// look in the root directory and open the file
if (!f.open(root, name)) {
putstring("Couldn't open file ");
Serial.print(name);
return;
}
// OK read the file and turn it into a wave object
if (!wave.create(f)) {
putstring_nl("Not a valid WAV");
return;
}

// ok time to play! start playback
wave.play();
}