Sliding game opener project

I'm am in the planning stages for an opener for a sliding gate. I've not done anything with an arduino, but it seems like this is the type of thing they are for so I thought I'd ask and see.

I don't really like the chain driven commerical systems that are avaiable, so I thought I'd try something different.

So I'm looking to build an opener system using a drive wheel powered by an electric motor (My original thought was to use a electric scooter to harvest the motor and battery from, but it seems that it'd be less expensive and less wasteful to just get all the pieces seperate.) that will open and close the gate.

Things I know, I need a motor, motor controller, battery, a way to charge the battery, something to control all the pieces (I am thinking this would be the arduino), safety stuff to prevent the gate from running over small children and such, need a way to control the system remotely.

My current plan is to use a 12V motor with a 12V LiFePO4 deep cycle battery and a solar trickle charger to keep it charged. The Motor will drive a wheel with a chain, (Though I did find a 24V hub motor for a scooter that I could use with a step up converter if it'd work, main thing is needed to go forwards and backwards, but I imagine that any electric motor is capable of it, and it'll depend on the motor controller). I'd use some sort of proximity sensor on each end of the gate to check for obsticles. I'd like to use an app from my phone to open and close the gate if possible, but I don't program for android so not sure how that'd work...

Things I don't know:
1, Is this the type of project an aduino would work for?
2. What kinds of sensors would I need for the safety stuff?
3. Would I need some sort of sensor thing to mark the stop points or can the distance to travel be programmed in with the software?
4. What is a good way to open and close the gate?
5. What do I need to look for in my equipment to ensure it works with an arduino?
6. Anything else I'm overlooking because I'm a noob?

I would really appreciate any feedback on this project.

Thank you

Lots of words and no real information....
Please read this link and use it. How to get the best out of this forum - Using Arduino / Project Guidance - Arduino Forum

1, Is this the type of project an aduino would work for?
Yes

  1. What kinds of sensors would I need for the safety stuff?
    Whatever you need - optical, magnetic, physical…

  2. Would I need some sort of sensor thing to mark the stop points or can the distance to travel be programmed in with the software?
    See #2

  3. What is a good way to open and close the gate?
    With. the motor and preferred linkage.

  4. What do I need to look for in my equipment to ensure it works with an arduino?
    Wires, power, specs and patience.

  5. Anything else I'm overlooking because I'm a noob?
    Yes, but get though the above,mand you’ll be a lot closer.

Yes.

You could almost completely finish the software before you purchased anything. Doing that might make a difference to what equipment you do eventually obtain.

Take very small steps with the project. Use examples to see how the hardware bits work. This simulator is free and currently the best, and leaves a giant mess of trouble to the future, like anything broken or misbehaving.

the wokwi simulator


Garage door openers use physical limit switches to inform range of motion, and a clever tamper resistant IR beam meant to head off closing on something or somebody. I do not know if they use current sensing which might indicate a problem.

a7

Thanks, I've orded an UNO starter kit so I can start playing with it to see how it works and stuff. Thanks for the link to the simulator.

I'll start playing around :slight_smile:

As I've been working on this the wokwi simulator is really cool. I've setup a simulation I've replaced the sensors with buttons and switches and the motor with LEDs. I've got the logic working more or less okay, but it's not lighting up the LEDs, one lights up but doesn't turn off when the motor should stop, and the other light doesn't come on when I flip the switch to change directions.

Here is my simulator:

Thanks for any suggestions.

I have begun a low level flight about your sketch. I will not have much to say for some time.

First, in the wiring diagram, you can hit 'g' and get a grid to help make a clean layout.

Wires, when selected, have little dots that let you drag and adjust the wires positions. Whan you are tired of software and are operating on fumes, take a few minutes and drag/adjust the wires do they do not overlap each other or cross over the microprocessor board. It took me only a few minutes to make the diagram more readable.

Not picking on you, just something everyone might want to know. I am a big fan of the wokwi, and I am glad you have decided to try developing your code with it.

Now a slide switch is present, it can be either asserting "gate open" or "gate close". I am not sure you mean this as a switch we use to open and close the gate, or as something used to sense the state of the door. If the latter, a single slide switch is inadequate, as there is no way to indicate that the gate is neither open nor closed.

const int gateOpenPin = 10;         // GPIO2 for gate open
const int gateClosePin = 3;        // GPIO3 for gate close

For now I will assume this is the main controlling switch. Please confirm or explain the roll of this switch.

This

If open close the gate.

Operate the PWM motor at 50% until the close hall effect sensor gets signal.

If closed open the gate.

Looks more like you mean to respond to one signal, and "do the right thing". A pushbutton would seem to make more sense here. Gate is closed, push the button and it shall open. Please explain what the slide switch at pin 9 is for.

I could reverse engineer some pkausible answers, and would willingly do so if (big if) the sketch were operating perfectly. Since it does not yet do what you want, trying to figure out from the code what you meant (rather than what the code says) is an inefficient use of (anyone's) time.

I assume the proximity sensors are a safety feature. I am curious as to how the two are expected to make this safer - as I mentioned, some mechanisms use a single beam of light to detect an obstruction. Describe a scenario for each case of the two possible proximity warnings.

It's not for the faint of heart, but wokwi does have text objects that can be placed on the diagram so you could label the switches and LEDs.

Maybe not when you are tired, dare to edit the diagram.json file and add some labels. It will make it easier for everyone, even I dare say yourself.

This

    {
      "type": "wokwi-text",
      "id": "txt10",
      "top": -115.2,
      "left": 19.2,
      "attrs": { "text": "TEXT A" }
    },

Is a text object. You can paste as many of these as you need, easiest to get syntactically correct is placing the

{
(deatils)
},

between any two components which you will see when you open the diagram file. Mind the comma. Each new object is in braces, objects are separated by commas. PLacement order does not matter, but you must nail the syntax.

Use a text editor, and before you plop the text into the diagram file, make the "id" unique, and change the text to something differet. That text can always be edited, so I keep this handy

    {
      "type": "wokwi-text",
      "id": "txt0",
      "top": -76.8,
      "left": 96,
      "attrs": { "text": "TEXT 0" }
    },
    {
      "type": "wokwi-text",
       "id": "txt1",
       "top": -96,
       "left": 96,
       "attrs": { "text": "TEXT 1" }
    },
    {
      "type": "wokwi-text",
      "id": "txt2",
      "top": -115.2,
      "left": 96,
      "attrs": { "text": "TEXT 2" }
    },

Note how it adheres to the rule {}, {}, {},

I totally understand if this is something you don't wanna mess with. As far as I know, this is still the only way to use the text object. A PITA for sure, but the payoff is (sometimes) worth the trouble.

See

Gotta jet - the food bell just rang.

HTH and looking forward to further investigation of your algorithm and code.

a7

Wires, when selected, have little dots that let you drag and adjust the wires positions. Whan you are tired of software and are operating on fumes, take a few minutes and drag/adjust the wires do they do not overlap each other or cross over the microprocessor board. It took me only a few minutes to make the diagram more readable.

Thanks I'll play around with this.

Now a slide switch is present, it can be either asserting "gate open" or "gate close". I am not sure you mean this as a switch we use to open and close the gate, or as something used to sense the state of the door. If the latter, a single slide switch is inadequate, as there is no way to indicate that the gate is neither open nor closed.

On my project I have 2 hall effect sensors with a magnet at either end of the track, when the open sensor finds a magnet that is the open signal, when the closed sensor finds a magnet that is the closed signal. I used the switch to simulate this behavior. In the current setup there is no open or closed setting.

Looks more like you mean to respond to one signal, and "do the right thing". A pushbutton would seem to make more sense here. Gate is closed, push the button and it shall open. Please explain what the slide switch at pin 9 is for.

Probably true, like how I've done the proximity sensors.

I assume the proximity sensors are a safety feature. I am curious as to how the two are expected to make this safer - as I mentioned, some mechanisms use a single beam of light to detect an obstruction. Describe a scenario for each case of the two possible proximity warnings.

You are correct, if an object is detected in the path the motor stops. I am trying to decide if it's better to return to the original position, or stop then resume when clear. I think I'm going to add a speaker to make an alarm sound if an object is detected.

It's not for the faint of heart, but wokwi does have text objects that can be placed on the diagram so you could label the switches and LEDs.

It's been a long night, so maybe after some rest I'll see how my heart is doing tomorrow.

Thanks for all the advice. I'll see if I can clean anything up tonight, but it's time to get the little one to bed, so may not have time til tomorrow.

THX. I will read through this again, but right away

A two position switch cannot simulate sensors placed at the extremes.

In real life, there will be times when neither position of that switch would reflect the state of the gate, that is when the gate is in between being full open and full close.

It seems that would make perfecting the code impossible.

At this moment, I think you need to use two switches, and when playing with it, be careful to close (assert the signal the hall effect thing will make) only one of them at a time.

a7

I added a new switch, so there is one for the open sensor and one for the close sensor. I added some text objects for the switches. I replaced the switch for the key pad with a button, I think this works better since it closer resembles what will actually happen.

I moved the wire connections to make it easier to follow, I also changed each of their colors, I think it's much easier to see what's going on now. Thanks for the tips.

Still have no idea why my LEDs aren't doing what I think I am asking them to do though.

I'm not in circumstances where taking a good look now is possible. I will look when I can, and also try to find one or two of several door opening closing with limit switches projects that have come across my radar.

You may be able to find such things by searching within these fora. I've not had the best luck with searching, but it might be worth a stab.

L8R and thank you for making those changes that make better sense, and for the additions that will make you simulate easier to use.

a7

OK, again I have attempted a low level flight about your sketch.

I cannot make sense of it.

Stripped, here's one thing that keeps from spending any serious time

void loop() {
  getSignal();
}

void getSignal() {
      openGate();
      closeGate();
}

void openGate() {
  getSignal();
}

void closeGate() {
  getSignal();
}

loop calls getsignal which may call opengat or closegate, both of which call getsignal, do you mean to be using recursion?


What is the ledc stuff?

  ledcAttachPin(motorControlPinL, 0);
  ledcSetup(0,4000,8);
   ledcWrite(0, motorSpeed);
   ledcWrite(motorControlPinL, 255);

I don't even see how this compiles. Where are those functions defined?


At this stage, you should not need any custom components, and it does not appear that you are using them, unless somehow they explain the *ledc* stuff.

Custom components are relatively advanced. Toss them away and don't look back.


The proximity stuff seems to have started life as a separate function, now commented out, but the pins are being read.

I advise you to make a version where all the dead code is removed. And where the safety items are removed. Sort out the odd recursive nature of your program structure.


You may be reluctant to toss out all the work and thinking that went into this, but I suggest that you do just that, and start by trying to use the IPO model of programming things like this

The IPO model

and also the concept of a "finite state machine", so your loop would

INPUT
1. digital read once all inputs into variables

PROCESS
2. based on the inputs, alpong with what the motor is currently doing 
   as far as moving the gate towards its current goal, decide whether
   the motor needs to be on and if on in what direction.

  Account here (later! Version 2) for any obstructions that appeared in the inputs.

OUTPUT
3. set the motor off, CCW or CW

You might use a number of "states", viz:

OPEN, CLOSED, OPENING, CLOSING, JAMMED_OPENING, JAMMED_CLOSING

Pour yourself one and spend the estimated time (28 minutes) Arduino Forum thinks it would take to read this thread:

I call your attention to post #39, where a simulated door and limit switches have been added to the OP's original code, which was an FSM (finite state machine) based algorithm for controlling a motion with limit switches.

That code is two parts. One that is the control algorithm, and the other, which is very thinly attached by two function calls and a few wires, that simualtes the door position and limit switches.

There aren't many comments, but if you play with it and put your finger on the code you should be able to see how it works. I could say the lack of comments is deliberate, in order to make a reader do just that. I don't make much use of comments, really, and I routinely ignore them in code I read but did not write, especially here where comments can often be gratuitous, misleading or downright incorrect. The code is what gets execute.

But slog your way through the hole thread. Read read read the code and try to get a feel for this aproach.

I'm not saying your logic isn't. Logical. But it is just now somewhat of a tnagle, and as I say, hard to look at too closely given some of the things that pop out right away.

HTH

a7

loop calls getsignal which may call opengat or closegate, both of which call getsignal, do you mean to be using recursion?

My thought here is to return to wait for a signal again after the gate has been opened or closed.

What is the ledc stuff?
From what I've found ledc is how you use PWM commands on an ESP32 board.

The proximity stuff seems to have started life as a separate function, now commented out, but the pins are being read.

That is correct, I used chatGPT to get started since I'm kindof a noob at this, then had to basically redo everything since it didn't work. It started as a function that was pretty complex and didn't do what I was wanting, so I set it up like it is now, and it seems to do what I want.

I advise you to make a version where all the dead code is removed. And where the safety items are removed. Sort out the odd recursive nature of your program structure.

This is easy enough.

I advise you to make a version where all the dead code is removed. And where the safety items are removed. Sort out the odd recursive nature of your program structure.

Will do.

Thanks

I'm going through the code in this project: doorDoor - Wokwi ESP32, STM32, Arduino Simulator and have some questions.

There is the setupSimulatedDoor() function that is called once in the setup function, what is the reason for the separate function rather than just having those commands as part of the setup function directly?

Some of the pins are declared at the beginning with const uint8_t and some are declared in the middle with # define. Is there an advantage for the delcarations to be in multiple places?
I have come across pins being delcared in a variety of ways, are there differences in declaring them in different ways?

  if (0) {  // test - door will just cycle up and down all by itself
    lPosition += dir ? -1 : 1;
    if ((lPosition == -1) || (lPosition == NPIXELS)) dir = !dir;
  }

I am not sure what this is doing, I've been unable to find what if (0) does. But when the loop runs it then adds the value of dir to the value of lPosition, then does ? -1:1, which I haven't been able to find what that actually is. Then is compares lPosition to -1 or NPIXELS, the gives dir the value of not dir?

Adafruit_NeoPixel doorBar(NPIXELS, PIN, NEO_GRB + NEO_KHZ800); 

<snip>

void setupSimulatedDoor()
{
  <snip>

  doorBar.begin();
  doorBar.setPixelColor(2, 0xff0000);
  doorBar.show();

  delay(777);
}


void runSimulatedDoor()
{
<snip>

  doorBar.clear();
  doorBar.setPixelColor(lPosition, 0xff0000);
  doorBar.show();
}

Could you explain what is going on with doorBar?

Thanks for the help.

So I got rid of all the code except the pin definitions, and the state tracking stuff. I found a tutorial on using PWM pins on a ESP32, copied some of their code that turns on and off the pins after I saw it mostly working I copied the code to a function.

The pink LED still turns on at first run, in the setup function I added a line to turn off the pink LED and now the pink LED flashes on the first run... :person_shrugging:

Link to the new project: Gate Opener v2 - Wokwi ESP32, STM32, Arduino Simulator

Link to tutorial I found: LED Control (LEDC) — Arduino-ESP32 2.0.6 documentation

Since all the functionality of the doorDoor simulated simulation is non-blocking, it is possible to have what are essentially two programs making progress with their jobs at once.

So look at it as two programs.

One is, as far as I remember, the code that OP provided and asked for help with.

The other is a simulation of the phyisical circumstances the first program is meant to observe and control.

In order to allow focus on the part that matters (the OP's control program) I used the least possible intrusive means to connect that control program with the door simulator.

So in setup(), the only evidence of the door simulator is the function call so it can do its necessary setup. I could have placed the entirety of that directly in line, but that would be harder to just get over.

Then similarly in the loop() function, there is but one call to the door simulator, to give it an opportunity to push any of its tasks along. Here again I could have cluttered the loop code with all kinds of stuff.

This is a side benefit to using functions. Properly specified and written, they afford an opportunity to make the high level code much easier to read, maintain and enhance.

Above line 120 otherwise is the OP's code. After line 120 is my door simulator. It can be ignored and left to do its job. Or studied for what it is.

You can see some stylistic differences. I use # define. That will always be a part of C/C++, but is considered old fashioned and some feel safer in ways. I will let anyone who cares make the argument; it is unlikely that I will stop using # define. The net effect and main benefit of either is to make one place where manifest constants, or "magic numbers" can be specified.

Normally all those and several other elements would appear in some conventional order. To keep the two programs, or the two main functions of the one program separate, I placed everything I possibly could below line 120, again so there would be less one needed to ignore in studying the main point of the code, the OP's goal to control a door motion as informed by user command and limit switches.

There is also a hardware connection between the control program and the door simulator. Those four white loopy wires are the only hardware logical connection.

Two wires route the simulator's current values for the limit switches to the input pins of the control program. There they are digitalRead()ed by the control program just as if they were hardware switches.

And two wires are outputs from the control program and tell the door simulator program whether and how to run the motor. Again, in real life these (or a computed variation of them) would be hooked to a motor control unit, there to make the door move, or not, and if moving either to the goal of opening the door or closing it.

The neopixel strip merely reports visually the current door position. Note that the door simulator would happily "burn out" the motor, as it is dumb, and depends on the control program to stop driving the motor once the limit switch is arrived at.

The individual LEDs at the upper right hand are wired to, and therefore report exactly, what the control program is asking of the door simulation, even as the individual LEDs at the extremes of the neopixel strip are wired directly to the limit switch outputs.

BTW I used wokwi LEDs which do not need a series current-limiting resistor. :expressionless:


  if (0) {

  }
  else {

  }

looks a bit odd, but it is used here to do either one thing (test) or another (operate). When the value is 0 (false) it is the only else part that runs. If I change that to 1 (true), the commands from the control program are not used. The door simulator becomes a bit smart enough to reverse the motor all by itself when the door gets to the limit switch.

A rewrite that is kinder and gentler would be of the form (pseudocode here)

  if the door is going up
    add 1 to the position variable.

  if the door is going down
    subtract 1 from the position variable.
 
  if the door reaches the end of allowed travel
    reverse the direction it goes at each step

It uses the C/C++ ternary operator. I think I would have been better advised to strip out the test clause, just in case someone really looked closely. Better to have the door simulator serve only one pupose. The if (0) {} else {} is, now you see, just a way to quickly do one thing or antoher. I tend to leave testing junk laying about - one never knows when it might come in handy. Sadly, many times such testing code becomes invalid. Here, it still works. The door simulator cheerfully ignores all advices and commands coming from the control program.

Just now I noticed making the least change to the code breaks it. This is an issue I will pursue with the boys over at wokwi, a rare defect I feel sure, as I certainly did not publish a broken sketch, nor one that (at the time) was the least fragile.

It seems that adding the Adafruit_NeoPixel and "retrying" a failure in parsing the diagram.json file sets it right.

added: the issue was with wokwi, see Odd failure in perfect old project · Issue #649 · wokwi/wokwi-features · GitHub for details and explanation. As usual Urish is very on top of things keeping wokwi best of them all.

Yes. But the intent was that it be quietly off to the side. I will only say doorBar is the name of the neopixel object upon which plays out the door position.

I see a new post from you, there will be time in my future to take a look. Not just now.

a7

I think I got the LEDs working appropriately now. I got rid of the initial turn on of the pink LED by switching it to pin 5. I then switched it back to pin 6 and it continued to behave properly.

I can make your sketch reliably open and close the door, so you have done it your way. It does need, as we could have said, careful operation of the proxies for the Hall effect sensors.

Please consider the points made in #12 above. You did fix up your version, but it will be a challenge to add the next features. By no means impossible, but if you are serious about making a real control program you should mark this one as finished and take a different approach.

It will only get harder as new features occur to you.

BTW you may have never noticed your project throws an error message when it starts

E (93) ledc: ledc_get_duty(740): LEDC is not initialized

I have no idea what this means or if has any bad effect on the execution of the code, or might in real life but not in the simulator. I would not rest until the code made no complaints like that.

a7

I was working on making sure the LEDs were responding correctly. The while loops are easy to setup. Now it's time to dive more into to that switch loop in the doordoor project to see how I can adapt it.

Yeah I've seen this. I think it's because the ESP32 isn't fully baked into wokwi. I don't get that error on when using the arduino IDE and loading onto and ESP32 board. I have done some testing on actual hardware as well.

I believe I have got 1 done, and am currently working on 2.