doing a project--

I'm doing a project in electronics that is suppose to be an Automatic Fan and Lighting system on a study area(outdoor). The sensors we are using are PIR(2 pcs.), LDR, and DHT22. Our project is suppose to turn the bulb/s (there are 2) On or Off, dependent on the ambient light and human presence, and at the same time turn the electric fan On or Off, and its speed using CBB61 capacitor, dependent on the temperature and human presence as well. This project's aim is to turn the fan/bulb/s off when not in use to conserve electricity and make the system fully automatic. But as we run the code on the Arduino Mega attached with 2 way relays(we are using 3pcs. of 2 way relays, 1 for the bulbs and 2 for the fan speed control) connecting the load to AC, some issues came up. The code are as follows: (There is no error upon uploading the program)

#include <DHT.h>
#include <DHT_U.h>

#define DHTPIN 22     // what pin we're connected to
#define DHTTYPE DHT22   // DHT 22  (AM2302)

#define fan 10
#define fan1 5
#define fan2 6
#define fan3 7

DHT dht(DHTPIN, DHTTYPE);

int bulb = 11;
int bulb2 = 12;
int ldr = A0;
int pir = 24;
int pir2 = 26;
float t = 0;

unsigned long current = 0;
unsigned long previous = 0;
unsigned long previous2 = 0;
unsigned long previous3 = 0;
unsigned long previous4 = 0;
const long interval = 5000;

int pirState = 0;
int pirState2 = 0;
int ldrStatus = 0;
int tempStatus = 0;


void setup() {

 pinMode(pir, INPUT);                          // declare sensor as input
 pinMode(pir2, INPUT);                          // declare sensor as input
 pinMode(ldr, INPUT);                          // ldr
 pinMode(bulb, OUTPUT);                         // declare LED as output
 pinMode(bulb2, OUTPUT);                         // declare LED as output

 pinMode(fan, OUTPUT);
 pinMode(fan1, OUTPUT);
 pinMode(fan2, OUTPUT);
 pinMode(fan3, OUTPUT);

 digitalWrite(bulb, HIGH);
 digitalWrite(bulb2, HIGH);
 digitalWrite(fan, HIGH);
 digitalWrite(fan1, HIGH);
 digitalWrite(fan2, HIGH);
 digitalWrite(fan3, HIGH);
 Serial.begin(9600);
 dht.begin();
}

void loop() {
 ////wait for a few seconds to a minute for the system to start up and for the sensors to calibrate

 ldrStatus = analogRead(ldr);
 pirState = digitalRead(pir);
 pirState2 = digitalRead(pir2);

 current = millis();


 ////////////fan

 if (pirState == HIGH || pirState2 == HIGH)
 {
   if (t <= 22) {
     if (current - previous4 > interval) {
       tempStatus = 0;
       Serial.println("fan off");
     }
   }
   else if (t <= 24 && t > 22) {
     tempStatus = 1;
     Serial.println("fan 1");
     previous4 = current;
   }
   else if (t <= 26 && t > 24) {
     tempStatus = 2;
     Serial.println("fan 2");
     previous4 = current;
   }
   else {
     tempStatus = 3;
     Serial.println("fan 3");
     previous4 = current;
   }
 }
 else {
   if (current - previous4 > interval) {
     tempStatus = 0;
     Serial.println("*******************************************************************************");    //no presence
   }
 }


 /////////////bulb 1

 if (pirState == HIGH && ldrStatus < 200) {
   digitalWrite(bulb, LOW);
   Serial.println("bulb ON");
   previous = current;
 }

 if (pirState == LOW || ldrStatus > 200) {
   if (current - previous > interval) {
     digitalWrite(bulb, HIGH);
     Serial.println("bulb OFF");
   }
 }

 ////////////bulb2

 if (pirState2 == HIGH && ldrStatus < 200) {
   digitalWrite(bulb2, LOW);
   Serial.println("bulb 2 ON");
   previous2 = current;
 }

 if (pirState2 == LOW || ldrStatus > 200) {
   if (current - previous2 > interval) {
     digitalWrite(bulb2, HIGH);
     Serial.println("bulb 2 OFF");
   }
 }

 switch (tempStatus) {               //we are using CBB61 capacitor for this one
   case 0:
     digitalWrite(fan, HIGH);
     digitalWrite(fan3, HIGH);     //fan = 0
     digitalWrite(fan2, HIGH);
     digitalWrite(fan1, HIGH);
     break;

   case 1:
     digitalWrite(fan, LOW);
     digitalWrite(fan3, HIGH);      //fan = 1
     digitalWrite(fan2, HIGH);
     digitalWrite(fan1, LOW);
     break;

   case 2:
     digitalWrite(fan, LOW);     
     digitalWrite(fan3, HIGH);     //fan = 2
     digitalWrite(fan2, LOW);      //on the rotary switch, we noticed the connection of fan 2 to be conducting fan 1 at the same time
     digitalWrite(fan1, LOW);
     break;

   case 3:
     digitalWrite(fan, LOW);
     digitalWrite(fan3, LOW);     //fan =3
     digitalWrite(fan2, HIGH);
     digitalWrite(fan1, HIGH);
     break;

   default: break;
 }

 if (current - previous3 > interval) {           //reads the temperature only every 5 sec.
   t = dht.readTemperature();                    // Read temperature as Celsius
   previous3 = current;
   /*
      if (isnan(t)) {
      Serial.println("Failed to read from DHT sensor!");
      return;
     } else{}
   */
   Serial.print("Temperature: ");
   Serial.print(t);
   Serial.println(" *C ");
 }
} //closing bracket of Void Loop

So I tried to trace back all the brackets and everything that I thought would give me the expected output, but...

*On COM5, it sometimes print consecutive "bulb ON" so many times, or any other serial prints consecutively, I thought it would be alternating with other serial prints since the code goes from top to bottom right? And if it does that specific line once, it will then check whether to perform the other lines depending on the bracketing and if's. But most of the times it does print it alternately.

*On COM5, (even on the actual relay base on the led indicator) it sometimes pauses. Like inconsistent and random pauses. The program stops for a while, its on auto scroll so pausing would be easy to observe.

*I also think theres a flaw in my coding -_- the fan relay usually displays no presence even if the PIRs are high (base on the relay led).

thanks for the time--

Can I ask a question of you first, on behalf of everyone on the forum?

Just before you made your post, you will no doubt have noticed a topic at the top of the forum section entitled "How to use this forum - please read.". Why did you decide not to read it? I'm not picking on you in particular. 80% of all new forum members also choose not to read it. Some even try to tell us they were "unaware", a sort of selective blindness, I suppose.

To make it easy for people to help you please modify your post and use the code button </>

so your code looks like this

and is easy to copy to a text editor. See How to use the Forum

Your code is too long for me to study quickly without copying to a text editor.

Also please use the AutoFormat tool to indent your code for easier reading.

...R

PaulRB:
Can I ask a question of you first, on behalf of everyone on the forum?

Just before you made your post, you will no doubt have noticed a topic at the top of the forum section entitled "How to use this forum - please read.". Why did you decide not to read it? I'm not picking on you in particular. 80% of all new forum members also choose not to read it. Some even try to tell us they were "unaware", a sort of selective blindness, I suppose.

I'm sorry about that. I just got caught with a deadline, so I just took the least time possible I could, but obviously it wouldn't be as effective as it should be. Ill read it, thanks.

Everything has a rational explanation. Except the things that dont have one. :-).

I am speaking for myself:

The "How to use this forum" is similar in font and colors with the current threads. I cant distinguish it at a rapid sight. For me, there is indeed a sort of "selective blindness" which in my case is a must, otherwise I will never be able to effectively browse the net.

Also, the other forums have rules that mostly relate to netiquette or alike, so when I first visited this forum I was not very eager to read the same boring rules that I (wrongly) supposed at that time that this forums rulesbook lists as well.

Sorry for OT.

Anyway, back to the problem at hand. As soon as you get those code tags into your original post, and also post a schematic for us to refer to (hand drawn is ok, just keep it neat), the sooner we can help sort out your code problem. I don't think we need links to any particular components, they are all common ones we are used to dealing with.

turn the electric fan On or Off, and its speed using CBB61 capacitor,

You mentioned this in your OP and in the code. I assume it is just a starter cap for the AC motor in the fan? In case you didn't know, AC motors, unlike DC motors, have (at least) two separate windings and need the AC current in the second winding to be out of phase with the first winding, or the motor will not run. The cap causes that phase difference. The speed of the motor is determined by the AC frequency (plus number of windings, gearbox...).

Maybe OP made some grammar and/or spelling corrections. I had no trouble reading a few lines of the code and give some comments. On this line, you were making decisions based on the value of t, which was not yet assigned. This is a very bad habit that leads to errors if not now, definitely in the future.

if (t <= 22) {

My suggestion is to move the temperature code before this if statement so that t has a valid value.
Also, please replace t with at least temp if not area_temp. It makes it so much easier to search and find where the variable is defined, assigned values, and used. A t is too short and occurs in too many words.

when I first visited this forum I was not very eager to read the same boring rules that I (wrongly) supposed at that time that this forums rulesbook lists as well.

This one read this before posting a programming question has a very specific title that makes it obvious that it is not about general rules.

Delta_G:
Secret pro tip - if you're going to be even moderately successful at programming or electronics then you will spend a good deal of time reading through long boring stretches of things you already know looking for the one nugget you're missing to make your code or project work.

In that way, the How to thread and code tags serve as a bit of triage to help folks separate the ones worth helping from the ones who just aren't going to make it.

Delta_G:
Secret pro tip - if you're going to be even moderately successful at programming or electronics then you will spend a good deal of time reading through long boring stretches of things you already know looking for the one nugget you're missing to make your code or project work.

In that way, the How to thread and code tags serve as a bit of triage to help folks separate the ones worth helping from the ones who just aren't going to make it.

That is really helpful. Thanks. Your method is truly yours

Take a picture of your project and post. The quicker the faster you will get help.

@UKHeliBob

Try to read all those lines at 1 am in the night after tinkering lots of small components, dealing with other life tasks, infinite paperwork, network search in tens or hundred pages in a language (or more) which is not native, etc. I am not complaining, I am just stressing the circumstances.

It is also difficult to edit a forum page in a way that can cope with that, in my opinion.

So none of us ‘others’ have life tasks? We just hang around waiting for desperate learners to demand assistance?

Delta... you’re on fire this week!

I won’t mention ‘entitled’in this thread, but there are plenty of others in this forum that fit nicely.

@lastchancename

I attempted to explain why very few people actually read the "how to", which happens according to experience (not only mine).

If there is another explanation, that explanation would be useful for community to find a way to cope with the problem. Just saying (or suggesting) that the one I wrote is not correct, does not help to much with finding a solution to the problem of (to) few people reading the "how to".

Of course, there is always possible a "do nothing" scenario.

+++

Attempting to refine:

There is a different psihological perspective of persons looking for help to the one of persons so kind to offer help.

The persons offering help use the forums for long time (in most cases, as I far I can see), so the routine plays a major role in selection of what is important and what is not (experience always counts), there is the deep brain made the strong connections on the certain search path.

In the case of persons looking for help, they use forum (in most cases, as I dare to see from my of course limited experience), they have little experience (the brain follows the less resistance path = assuming), they are in hurry (useless to blame them for that) and of course having "how to" forum lines that look similar to all the current ones does not help.

There is also a psihological effect of the subjective value of stake. Long story here, but the easy to get raw picture comes from prey-predator relation (known from ecology/biology).

The subjective value of time counts as well :-). For the ones in need for help, they have no choice than to wait. The subjective value of time is high, because there is no alternative than to wait. In the case of persons offering help, the subjective value of time is impacted by the existence of alternative: it could be others to help as well.

+++

All in one, digging deeper into any simple fact or problem may disclose much more than pseudo -solution of pushing. Also, stating that humans must do what we expect them to do just because we plan for them a certain behavior may lead to cover the root of the misconduct and consequntly preventing people to find a solution. This is what happens in certain cases in practical teaching. A lot of theories here.

In my opinion, electronics and psihology are constructed on different mindsets so analysis toolboxes are also different.

Certainly, I wont say that the whole explanation above is 100% true, since is not based on controlled circumstances, but is better than none.

Sorry for OT again. Maybe the subject deserves a separate topic, I dont know. For me is interesting, because I always look for deep roots of human behavior.

@falexandru, you're being sensitive.
The observations were more in line with my signature - and the OP's initial request.
Your reply simply put it into words.

Yes, there is a fair dose of cynicism from the 'regulars' - because we've seen all these attenpts at laziness and entitlement before... to be honest they make me smile, and I quietly roll on to the next question, bu tthis one jst caught my eye as soneone thta unfortuneltely fell intpo the 'reply' basket.

There /are/ some legitimate newbies' questions - and we can pretty esaliy identify those - and we often help unconditionally. "life tasks" isn't an excuse fpor anything.

ADDED: @liuzengqiang was being very fair with constructive suggestions.

@Delta_G - Actually - that's a REALLY good point.
Even as an experienced developer of all sorts of gadgets, I occasionally come across a problem that I know 'should be easy' but eludes me for three or four iterations... only then I realise that I have to step back, reconsider the problem, read a bit and creturn - to do it once, properly.

Yeah - it's embarassing to myself, but better than looking like an idiot to the world (which I also do on a semi regular basis!) Developers have remrkably sensitive egos...!

Delta_G:
Anytime you come to anything new your first question should be, are there any directions for this so I don't look stupid doing it all wrong? It shouldn't have to stand out and smack you in the face to get you to read it.

The other thing is to use some simple social skill.

Sensible folks don't go along to their first meeting with a group they want to join and immediately interrupt proceedings to get help with their problem. Sensible folk go to their first meeting and watch, listen and learn how the people in the group like to operate. And a sensible person will probably try to contribute to the group before expecting help from the group.

The online equivalent is reading 20 or 30 Forum Threads to see how things are done on the Forum before jumping in with your first question. And most people have expertise in some area that they can use to help with some question - even if they are newbies to programming. There are questions here about subjects as diverse as drones, plant watering and chicken-coops.

...R

@playermanto thanks for modifying the original post and putting in code tags. You could also have changed the topic title to something more useful like "Light & fan control for outdoor studdy area".

I agree with liuzengqiang's comments in post #7.

See comments in code:

   if (t <= 22) {
     ...
   }
   else if (t <= 24 && t > 22) { // no need to check t > 22 here, it must be because of the "else if"
     ...
   }
   else if (t <= 26 && t > 24) { // no need to check t > 24 here, it must be because of the "else if"
     ...
   }
   else { // no need to check t > 26 here, and you didn't 
     ...
   }

*On COM5, it sometimes print consecutive "bulb ON" so many times, or any other serial prints consecutively, I thought it would be alternating with other serial prints since the code goes from top to bottom right? And if it does that specific line once, it will then check whether to perform the other lines depending on the bracketing and if's. But most of the times it does print it alternately.

Yes, the code does go from top to bottom. But what you may not realise is that loop() will run many hundreds, maybe thousands of times per second. In some runs, maybe nothing is printed. In other runs maybe only "bulb ON" is printed, so it prints consecutively. To prevent this, you need some more "status" variables for the bulbs & fans. For example:

 /////////////bulb 1

 if (pirState == HIGH && ldrStatus < 200 && bulbStatus == HIGH) {
   bulbStatus = LOW;
   digitalWrite(bulb, LOW);
   Serial.println("bulb ON");
   previous = current;
 }

 if ((pirState == LOW || ldrStatus > 200) && bulbStatus == LOW) {
   if (current - previous > interval) {
     bulbStatus = HIGH;
     digitalWrite(bulb, HIGH);
     Serial.println("bulb OFF");
   }
 }

Another suggestion: you are using values obtained from millis() to make sure bulbs are not switching on and off rapidly around dusk & dawn (where the ldr reading is around 200)? But this only prevents switching the bulb off 5 seconds after it has been switched on. It does not prevent it being almost immediately switched on again. It would be better to use a combination of timing and some "hysteresis" in the ldr value, like this:

 /////////////bulb 1

 if (pirState == HIGH && ldrStatus < 200 && bulbStatus == HIGH) {
   if (current - previous > interval) {
     bulbStatus = LOW;
     digitalWrite(bulb, LOW);
     Serial.println("bulb ON");
     previous = current;
  }
 }

 if ((pirState == LOW || ldrStatus > 300) && bulbStatus == LOW) {
   if (current - previous > interval) {
     bulbStatus = HIGH;
     digitalWrite(bulb, HIGH);
     Serial.println("bulb OFF");
     previous = current;
   }
 }

Notice that the ldr reading must be above 300 before the bulb can be switched off but must fall below 200 before it can be switched on again, as well as the 5 second limit (which you may want to increase to 2 minutes once testing is complete).

loop() goes fast.

Very fast.

Put a long delay at the end so one second of input doesn't output 1 million lines on the serial monitor.

Sometimes the serial monitor won't print because your stuck on something.

So you fix 'something'.

:slight_smile: