Hi,
Thank you for your explanation, So I have made a new board and it works, the fan increase its speed accordingly. Thank you. Now onto the second phase, the LEDs.
However:
In dir 0 (Right to left) there is no wavecount so no fan.
Also, why not increment the speeds after each wave?
Actually yes it is better to increase the speed with one wave either direction.
So 31 Waves for max? And is it a 3x10 matrix?
Aka after 3 waves:
I think just to make my life easier I will use 10 LEDs for 10 waves. Because I have increased the steps to 10. so one wave = one LED and I will arrange them in order (LED 1 ... LED 10). The only problem is I will lose 10 pins on the arduino!
So how do I write the code for LEDs assuming I have:
const byte LedPins[]= {22,23,24,25,26,27,28,29,30,31};
But why do you want that? Can be useful when debugging but you already have the print to serial. But normally it's not very useful because you just try to make a copy of the signals from the pirs. Why not drive leds with the pir output?
Just for the user, as a response from the machine. So that they know the sensor has detected the movement. Also I think it would make a nice visual effect: when waving your hand side to side the LEDs for each sensor would light up.
Also I would love to have some sound feedback just like the one in the video, so with every single detection there is a clicking noise form the buzzer. Can I do that with:
tone (buzzer, 2000,50);
noTone(buzzer);
If you use a relay (and/or digital write) there is NO way to change the fan speed. Then you can just choose between on or off... Not really a build up to a hurricane I would say...
The fan works just fine now, I did not know you can send a variable signal using PWM pins. So found a tutorial that explains how to do that and there is no issue.
Here is code, I have not change it except for pir pin numbers, fan pin number, array for LEDs and speedsteps.
const byte FanPin = 11;
const byte PirPins[] = {8, 12, 13}; //Left, Center, Right
const byte NrPirs = sizeof(PirPins); //number of PIRs
const byte LedPins[]= {22,23,24,25,26,27,28,29,30,31};
const byte NrLeds = sizeof(LedPins); //number of LEDs
const byte SpeedSteps[] = {0, 20, 50, 75, 100, 125, 150, 175, 200, 225, 250};
const byte NrSpeedSteps = sizeof(SpeedSteps);
const unsigned int TimeoutTime = 2000; //time without motion to reset motion state
//variable to hold the current and last state of the pir
bool pirStates[NrPirs];
bool lastPirStates[NrPirs];
unsigned long lastMotionTime; // last change of the motionState
byte motionState; //current state of the wave
byte waveCount; //number of waves
//just to easy access PIRs
enum pir_t{PIR_LEFT, PIR_MIDDLE, PIR_RIGHT};
void setup(){
for(byte i = 0; i < NrPirs; i++){
pinMode(PirPins[i], INPUT_PULLUP);
}
// To initialize each LED pin as output
for (int i = 0; i < NrLeds; i++) {
pinMode(LedPins[i], OUTPUT);
}
pinMode(FanPin, OUTPUT);
Serial.begin(9600);
}
void loop(){
checkMotion();
updateFanSpeed();
}
bool checkMotion(){
readPirs();
const bool Dir = motionState & 0x80; //direction is MSB
const byte LastMotionState = motionState;
//Check to see if we can procede
switch(motionState & ~0x80){
//waiting to start
case 0:
//did the left or pir became activated?
if(pirActivated(PIR_LEFT)){
motionState = 1;
}
else if(pirActivated(PIR_RIGHT)){
motionState = 1 & 0x80; //MSB indicates direction aka, we start from the right
}
break;
//waiting for middle
case 1:
//if the middle became activated, go to next state
if(pirActivated(PIR_MIDDLE)){
motionState++;
}
break;
//waiting for last
case 2:
if( ( Dir && pirActivated(PIR_LEFT)) ||
(!Dir && pirActivated(PIR_RIGHT)) ){
motionState = 0;
waveCount++;
//reset is max number of waves has passed
if(waveCount == NrSpeedSteps){
waveCount = 0;
}
//debug
Serial.print(F("WaveCount set to: "));
Serial.println(waveCount);
}
break;
}
//if state changed, reset the timeout
if(motionState != LastMotionState){
lastMotionTime = millis();
//debug
Serial.print(F("Motion state changed to: "));
Serial.println(motionState & ~0x80);
Serial.print(F("Dir: "));
Serial.println(Dir);
}
//reset motionState on timeout
if(millis() - lastMotionTime >= TimeoutTime){
motionState = 0;
}
}
void readPirs(){
for(byte i = 0; i < NrPirs; i++){
//save for next time
lastPirStates[i] = pirStates[i];
//read new value
pirStates[i] = digitalRead(PirPins[i]);
//if state changed, print it
if(pirStates[i] != lastPirStates[i]){
debugPrintPirState(i, pirStates[i]);
}
}
}
inline bool pirActivated(byte i){
return pirStates[i] && (pirStates[i] != lastPirStates[i]);
}
void debugPrintPirState(const byte Number, const bool State){
Serial.print(F("Pir #"));
Serial.print(Number);
Serial.print(F(": "));
if(State){
Serial.print(F("detected"));
}
else{
Serial.print(F("ended"));
}
Serial.println();
}
void updateFanSpeed(){
analogWrite(FanPin, SpeedSteps[waveCount]);
}