Attached is a sketch I am working on to control a cart (lift) on a rail that carries people up and down a hill. The comments within the sketch describes the operation of the cart and the desired controls.
A sketch to move the cart up the rail it works as desired and a sketch to move the cart down the rail it works as desired. When I combine the two sketches together things get screwy. If certain buttons are pressed at the wrong time or sequence I get the wrong results. Example: while pressing buttonPin1 (Up button) and buttonPin4 (lower limit switch) LED1 (the motor in motion) lights. Obviously safety is the most important factor. If needed, I can provide a spreadsheet with a combination of button states and the results.
I tried various control structures “if”, “do”, “while”, etc. and Boolean operators but cannot come up with the right combination.
I searched for similar sketches; lift, dumbwaiter, elevator, etc and have not found anything close.
Attached are a simple electrical drawing and a photo of the breadboard I am using with an Arduino Uno.
Thanks you, I look forward to learning the right code and why.
It seems my message is greater than 9000 characters so I have attached my sketch instead of posting it with the "code".
Do you have pullup or pulldown resistors on your button pins? If not they are "floating" when the button is not pressed and will give false states. Looks like you are using "low true" logic on your buttons so you could use the internal pullup resistors like this:
if ((buttonState2 == LOW) // if we're pushing the down button
&& ! // AND
(buttonState1 == LOW) // we're NOT pushing the up button
&& ! // AND
(buttonState4 == LOW)) // we're NOT pushing the lower limit switch
// then...
I would tend to view the problem in terms of the current status of the cart, instead of which buttons were pressed.
From the cart status, I would then determine how the motor should be controlled.
Buttons under user control
--------------------------
DownButtonPressed
UpButtonPressed
emergency stop (Down and Up) pressed simultaneously
sensors
-------
LowerLimitReached
UpperLimitReached
CartStatus
----------
atTop
atBottom
movingUp
movingDown
emergencyStopActive
Pseudocode
----------
if LowerLimitReached
then CartStatus = atBottom
if UpperLimitReached
then CartStatus = atTop
if ( UpButtonPressed && DownButtonPressed)
then
if (CartStatus == movingUp || CartStatus == movingDown)
then CartStatus = emergencyStopActive
else Error - emergency stop not possible if cart not moving
if UpButtonPressed && ! DownButtonPressed
then
if CartStatus == atBottom
then CartStatus = movingUp
else Error - Up button press ignored
if DownButtonPressed && ! UpButtonPressed
then
if CartStatus == atTop
then CartStatus = movingDown
else Error - Down button press ignored
You need to introduce the concept of the state of the cart - moving up, at the top, moving down or at the bottom. And you also need the concept of the command state - up requested, down requested or no request.
The buttons should affect the request state. The combination of the cart state and the request state should determine what the motor does.
You need to decide if the cart must move all the way (to top or bottom) after a request or whether it can change direction half way. If it must go all the way it should ignore requests if the cart state is moving up or moving down.
Your emergency button should physically cut the power to the motor and apply the brakes and only then tell the Arduino that there has been an emergency. In an emergency you should not rely on correct behaviour by the Arduino.
Not sure of proper forum edict so I hope I am not being offensive by calling out particular responders. 6V6GT and Robin2, I understand what you are saying but I do not know how to get there. 6V6GT, I tried building a script using your guidance but I am getting too many errors and not sure I have enough understanding to know I am heading in the right direction. Perhaps there is a similar script I can see? or maybe reference material directly associated to this concept. At the risk of making a fool of myself I have attached a revised script... errors and all.
cbgav:
a rail that carries people up and down a hill.
This cannot be difficult for an Arduino to do, but some deep and meaningful conversation with your lawyers and public liability insurance brokers first would be a good idea. Have you done that?
cbgav:
I understand what you are saying but I do not know how to get there.
Have look at Planning and Implementing a Program and how the program is broken down into a series of short functions - each of which can be tested on its own.
Don't be over-awed by the phrase "state machine". It is just a fancy name for a simple concept - using variables to keep track of what part of the action is in progress or has been requested.
For your project the code in loop() could be as simple as
Attached is my revised sketch. in general it operates correctly but needs tweaking.
I cannot figure out how to set up a scheduler that will enable function “void emergencyStop()” for 5000ms.
I need to correct a very weak up up relay pulse when the “upperLimitReach()” and “upButtonPressed()” are enabled at the same time. This is true with the down relay when the “lowerLimitReach()” and “downButtonPressed()” are enabled at the same time.
(The logic should be; When the cart is at the bottom platform the Lower Limit Switch is engaged and prevents the Down Button from working and when the cart is at the top platform the Upper Limit Switch is engaged and prevents the Up Button from working.)
How do you to make one function effect (or react) to another function?
How do I ignore or skip over a Function if it is not needed during a loop.
Can a scheduler be used for “Serial Print” read stability verses using “delay(XX)”?
thanks
From a quick look at your program you have functions named movingUp(), atBottom() etc. IMHO they should not be functions - they should be states recorded in a variable. For example cartState = 'U'; for moving up, D for moving down, T for at the top and B for at the bottom.
And that variable should reflect what is happening - it should not be attempting to cause anything to happen.
I can't imagine why there would be any need to disable any buttons. If the cartState shows that it is at the bottom then just ignore the Down button.
I think your program is a great deal more complicated than it needs to be. Look again at what I suggested in Reply #11.
Dear Robin2,
Thank you for your guidance. I read your Planning and Implementing a Program countless times as well Arduino for Dummies, Sheepdog courses and other instructional sketches but I am not getting it. I thought I was getting close, but your statement in #13 threw me for a loop. Perhaps you can suggest other sketch examples.
As much as I enjoying learning this, it is frustrating for me. I feel I am close but I don’t how to get pass this fundamental idea.
Imagine there is a small queue of people waiting for the lift at the ground floor and there is a lift attendant with 4 cards. He holds one of the up at any one time to let the people in the queue know what is happening. The cards have these messages.
Lift Going Up
Lift at Top
Lift Coming Down
Lift at Bottom
You need to use a variable in place of the attendant with the cards and you can simplify the messages to 'U', 'T', 'D', 'B'.
Imagine there is another attendant inside the lift and he has a blackboard on which he scribbles the numbers of the requested floors. At one instant he might have 4,3, 1. (These values need to be in an array with a slot fr each floor).
There will also be a variable that holds the number of the floor the lift is at (or nearest).
The logic of the system will then work from these three pieces of data.
Suppose the lift is at floor2 and going up. It will then keep going up and stop at floor3, When it stops at a floor it will clear the number (on the blackboard) for that floor. Then it will see a call for floor4 and go up again. At that stage it will be at the top. It will check to see if it is required to go down (i.e. is a lower floor requested) and in this case it will see a demad for floor1 so it will start going down.
I hope that helps a little.
If not please let me know what part of my explanation does not make sense as that will make it much easier to focus my answer on the real problem.