Newbee, the code works, almost!

Hi all, newbee to Arduino and the last language I programmed was on a Trash-80!

Anyway, need some help with whays not working.

Scope: Have 5 windows that open and shut using 24 VDC actuators. Have my Arduino Mega hooked into a 16 channel relay board and have written the following code. Its starts of fine, but with multiple push button ‘pushes’ things get confused (will open then shut etc).

I’m thinking:

  • I’m not putting a baseline on the windows so they know where they should be, or

  • I need some kind of lock-out on the functions so is if the button is pushed while its executing an all-open or all-close it ignores it.

Any insights??

const int Lounge_Open = 46;  
const int Office_Open = 47;  
const int Matthew_Open = 48;  
const int James_Open = 49;  
const int Lounge_Close = 50; 
const int Office_Close = 51; 
const int Matthew_Close = 52; 
const int James_Close = 53; 
const int All_Open_Button = 22; 
const int All_Close_Button = 23; 
int val_Open = 0;
int val_Close = 0;


void setup() {
 pinMode(All_Open_Button,INPUT_PULLUP);
 pinMode(All_Close_Button,INPUT_PULLUP);
 pinMode(Lounge_Open, OUTPUT);
 pinMode(Office_Open, OUTPUT);
 pinMode(Matthew_Open, OUTPUT);
 pinMode(James_Open, OUTPUT);
 pinMode(Lounge_Close, OUTPUT);
 pinMode(Office_Close, OUTPUT);
 pinMode(Matthew_Close, OUTPUT);
 pinMode(James_Close, OUTPUT);
 digitalWrite(Lounge_Open, HIGH);  
 digitalWrite(Office_Open, HIGH);  
 digitalWrite(Matthew_Open, HIGH);  
 digitalWrite(James_Open, HIGH);
 digitalWrite(Lounge_Close, HIGH);  
 digitalWrite(Office_Close, HIGH);  
 digitalWrite(Matthew_Close, HIGH);  
 digitalWrite(James_Close, HIGH);  
}  

void loop() {
 val_Open = digitalRead(All_Open_Button);
 val_Close = digitalRead(All_Close_Button);
 if (val_Open == LOW) All_Open();
 if (val_Close == LOW) All_Close();
}


void All_Close() {
 digitalWrite(Lounge_Close, LOW);  
 digitalWrite(Office_Close, LOW);  
 digitalWrite(Matthew_Close, LOW);  
 digitalWrite(James_Close, LOW);  
 delay(10000);
 digitalWrite(Lounge_Open, HIGH);  
 digitalWrite(Office_Open, HIGH);  
 digitalWrite(Matthew_Open, HIGH);  
 digitalWrite(James_Open, HIGH);
 digitalWrite(Lounge_Close, HIGH);  
 digitalWrite(Office_Close, HIGH);  
 digitalWrite(Matthew_Close, HIGH);  
 digitalWrite(James_Close, HIGH); 
}

void All_Open(){
 digitalWrite(Lounge_Open, LOW);  
 digitalWrite(Office_Open, LOW);  
 digitalWrite(Matthew_Open, LOW);  
 digitalWrite(James_Open, LOW);  
 delay(10000);
 digitalWrite(Lounge_Open, HIGH);  
 digitalWrite(Office_Open, HIGH);  
 digitalWrite(Matthew_Open, HIGH);  
 digitalWrite(James_Open, HIGH);
 digitalWrite(Lounge_Close, HIGH);  
 digitalWrite(Office_Close, HIGH);  
 digitalWrite(Matthew_Close, HIGH);  
 digitalWrite(James_Close, HIGH); 
}

Please read the forum guide to find out how to post code correctly (and lots of other tips), then modify your post above and correct it.


This picture is very impressive. But to be honest it's no help at all when it comes to understanding your problem and circuit.

Can you post a schematic, just for the circuits you are talking about?

Can you post a link to the window actuators you are using? Are these linear actuators/servos? With limit switches?

Thanks Paul, will do.

Is there a link to that?

M.

Have you any debounce on the buttons?

Nope, but thats a thought!!

Any suggestions on how to code that in?

M.

Thanks for putting in the code tags.

malcolmfraser:
Is there a link to that?

Link to what?

if the button is pushed while its executing an all-open or all-close it ignores it.

The code you posted does that already

In the functions why do you appear to open and close the windows multiple times ?

Is there any possibility of adding limit switches to the actuators ?
As a matter of interest how are the relays powered ?

with multiple push button 'pushes' things get confused (will open then shut etc).

Can you explain this problem in more detail? Your code only checks one button, so do you mean multiple presses of that button? The code looks as if it will open and close windows with one push anyway...

  • I'm not putting a baseline on the windows so they know where they should be, or

What do you mean by "baseline"? Please explain more plainly.

  • I need some kind of lock-out on the functions so is if the button is pushed while its executing an all-open or all-close it ignores it.

Based on estimated time for an actuator to run, or can the Mega read the limit switches in the actuators?

Thinking about debounce, it looks like your code sort of deals with it as on detection of the button, the subroutine has a 10 sec delay. Probably a red herring.

Hi all great questions:

The actuators have inbuilt limit switches and work by reversing the polarity. The relay board on the bottom right uses two relays to either be completely off, volts on or volts reversed. and are actuated by a 24VDC input.

So to close all windows, push button to GND on PIN 23, fires all the relays that actuate the close polarity. The reason I have the relays outputs going HIGH after the delay is that I then want the relays to be un-powered so no voltage is presented to the window actuators.

All Open is the same with a different set of relays....

The DELAY is the open and shut run time, which I will fine tune to me fully open of fully closed.

Putting a debounce in for the same length of time that the DELAY runs for, might work....

M.

Hi Paul, on your comment on only checking one button, I thought I was checking both,do I have the syntax wrong?

M.

void loop() {
  val_Open = digitalRead(All_Open_Button);
  val_Close = digitalRead(All_Close_Button);
  if (val_Open == LOW) All_Open();
  if (val_Close == LOW) All_Close();
}

Sorry, I meant to say one pair of buttons.

Re-reading the thread, I have some questions.

  1. Why use an Arduino (or any microcontroller) at all? Why use relays? Why not use some toggle switches (dpdt) with contact ratings suitable for the actuators?

  2. Why is it important that 24V is not presented to the actuators when not running? 24V is not dangerous to humans.

  3. Why are you concerned about buttons being pressed before actuators have stopped moving? What goes wrong when this happens? (Until I understand this, I would agree that debouncing is uneccessary.)

  4. Why do you need open-all and close-all buttons? It does not seem to save much time compared to pressing 4 open or 4 close buttons.

I expect you have good answers to these questions, but until we understand them, is hard to give good advice because we will be half expecting you to say "no, I can’t do it that way because ".

PaulRB:
Re-reading the thread, I have some questions…

  1. Why do you need open-all and close-all buttons? It does not seem to save much time compared to pressing 4 open or 4 close buttons.

No, but it's way cooler. A nice big LOCK DOWN button!

a7

"Cool" can be a good reason to do something, as can "just to learn". Bad reasons include "I didn't know I had another choice" and "I know it's stupid but teacher/boss said we had to".

Here’s some thoughts for you.
Look at your loop code. This will be executed rapidly until a button is pressed.
If the first button is ‘open’, it will read the close button - which probably isn’t pressed a few micro seconds later and store the two conditions.
Then it will act on the open - and not return to look at the buttons for 10 seconds. Anything you do to the buttons during this time will be ignored. So although you may have pressed another button, it may be stuck in the wait loop and ignore it. Could be why it looks confused?
Try and avoid delay(). Have a look at the article on delays at the top of thi section of the forum.
You can also try writing what you want to happen in plain language first (or pseudo code) which will help to understand what you really want to happen. It will also help to program it. For example:
Read open button
If pressed, start opening and start timer.
Read close button
If pressed (maybe stop open and start close and timer. Maybe see if timer has been running long enough to complete opening).
Loop

Looks fun - good luck.

Hi Paul, and all, problem solved and answers to Paul's questions below.

I went back to basics and just ran the Arduino with a local switch input and no connection the relays. All worked fine!!

So whats the difference I ask, when the relays and my switches and cables are connected????

More cable and switches more noise!. Did the research and found the that internal pull ups are quite weak (30K) and when the whole system is live, there must be noise on the inputs, I hypothesized.

So, two new 2K2 external pull ups, and everything works!!!

Really appreciate the help and feedback and Paul to answer your specific questions.

Re-reading the thread, I have some questions.

  1. Why use an Arduino (or any microcontroller) at all? Why use relays? Why not use some toggle switches (dpdt) with contact ratings suitable for the actuators?

Because I want to wire up the whole house and connect to Azure IoT for Arduino. This is the scope for version one of the road map. Hence the industrial grade wiring, it will be permanent.

  1. Why is it important that 24V is not presented to the actuators when not running? 24V is not dangerous to humans.

Just in case the limit switches in the actuators fail (highly unlikely, but a just-in-case to stop a motor burn out.

  1. Why are you concerned about buttons being pressed before actuators have stopped moving? What goes wrong when this happens? (Until I understand this, I would agree that debouncing is unnecessary.)

Some times a user might push one, then the other, then back to the first one because the windows are moving too slowly. The code is working OK now and the DELAY in the Functions acts as a de-bounce quite nicely.

  1. Why do you need open-all and close-all buttons? It does not seem to save much time compared to pressing 4 open or 4 close buttons.

Next version will see a rain monitor added, with a digital out for "its raining" I have two teenage sons, so 'Its raining and a 'All Close' function get around the BDU issue (brain dead user)

Thanks for the feedback and help Paul, just starting the journey after a 40 year absence and nice to be playing again...

Malcolm

Hi all, closing this off now with the final solution!

Thought I had it with the external pull ups, but flikced a light switch last night nad the windows opened!

So, did the reserch and found the Bounce2 Class at GitHub - thomasfredericks/Bounce2: Debouncing library for Arduino and Wiring.

Final code that seems to be working is (with debounce set to 15ms)

#include <Bounce2.h>

#define All_Open_Button 22
#define All_Close_Button 23
const int Lounge_Open = 46;  
const int Office_Open = 47;  
const int Matthew_Open = 48;  
const int James_Open = 49;  
const int Lounge_Close = 50; 
const int Office_Close = 51; 
const int Matthew_Close = 52; 
const int James_Close = 53; 
int val_Open = HIGH;
int val_Close = HIGH;

// Instantiate 2 Bounce objects
Bounce debouncer_Open = Bounce(); 
Bounce debouncer_Close = Bounce();

// Set Up Functions
void All_Close() {
  digitalWrite(Lounge_Close, LOW);  
  digitalWrite(Office_Close, LOW);  
  digitalWrite(Matthew_Close, LOW);  
  digitalWrite(James_Close, LOW);  
  delay(10000);
  digitalWrite(Lounge_Open, HIGH);  
  digitalWrite(Office_Open, HIGH);  
  digitalWrite(Matthew_Open, HIGH);  
  digitalWrite(James_Open, HIGH);
  digitalWrite(Lounge_Close, HIGH);  
  digitalWrite(Office_Close, HIGH);  
  digitalWrite(Matthew_Close, HIGH);  
  digitalWrite(James_Close, HIGH);
}

void All_Open(){
  digitalWrite(Lounge_Open, LOW);  
  digitalWrite(Office_Open, LOW);  
  digitalWrite(Matthew_Open, LOW);  
  digitalWrite(James_Open, LOW);  
  delay(10000);
  digitalWrite(Lounge_Open, HIGH);  
  digitalWrite(Office_Open, HIGH);  
  digitalWrite(Matthew_Open, HIGH);  
  digitalWrite(James_Open, HIGH);
  digitalWrite(Lounge_Close, HIGH);  
  digitalWrite(Office_Close, HIGH);  
  digitalWrite(Matthew_Close, HIGH);  
  digitalWrite(James_Close, HIGH);
}

void setup() {
  // Setup the buttons
  pinMode(All_Open_Button,INPUT_PULLUP);
  pinMode(All_Close_Button,INPUT_PULLUP);
  pinMode(Lounge_Open, OUTPUT);
  pinMode(Office_Open, OUTPUT);
  pinMode(Matthew_Open, OUTPUT);
  pinMode(James_Open, OUTPUT);
  pinMode(Lounge_Close, OUTPUT);
  pinMode(Office_Close, OUTPUT);
  pinMode(Matthew_Close, OUTPUT);
  pinMode(James_Close, OUTPUT);
  digitalWrite(Lounge_Open, HIGH);  
  digitalWrite(Office_Open, HIGH);  
  digitalWrite(Matthew_Open, HIGH);  
  digitalWrite(James_Open, HIGH);
  digitalWrite(Lounge_Close, HIGH);  
  digitalWrite(Office_Close, HIGH);  
  digitalWrite(Matthew_Close, HIGH);  
  digitalWrite(James_Close, HIGH);  

  
  // After setting up the buttons, setup debouncer
  debouncer_Open.attach(All_Open_Button);
  debouncer_Open.interval(15);
  debouncer_Close.attach(All_Close_Button);
  debouncer_Close.interval(15);
}

void loop() {
 // Update the debouncer
  debouncer_Open.update();
    debouncer_Close.update();
 
 // Get the update value
 int val_Open = debouncer_Open.read();
  int val_Close = debouncer_Close.read();

  // Based on the debouce fire call the functions
  if (val_Open == LOW) 
    All_Open();
      
  if (val_Close == LOW) 
    All_Close();
  
}
const int Lounge_Open = 46;
const int Office_Open = 47;
const int Matthew_Open = 48;
const int James_Open = 49;
const int Lounge_Close = 50;
const int Office_Close = 51;
const int Matthew_Close = 52;
const int James_Close = 53;
int val_Open = HIGH;
int val_Close = HIGH;

A minor point, but none of these need to be ints as their value will never be negative or exceed 255, so byte would be large enough

Using variables of the appropriate size saves memory and more importantly reinforces the need to be careful as to the type and size of the values to be stored in the variable.

A common mistake is to use int as your "standard" data type only to have the program fail when the value stored is greater than 32767, often as the result of a calculation.