Featured

A miniature lift – Arduino Mega 2560 on a RTS

Hello everyone!

Today I want to present you to the result of a team job, a lift. There have been loads of trials and errors especially in the mechanics. I have to thank my father for the electromechanics of the lift because otherwise I couldn’t have been able to finish it this fast. Thank you dad! you rock! I do still remember as being a kid and him encouraging me to build something. Unfortunately not all was about building, I still remember that as being kid I used to take a screw to break all the diodes on his pcbs, holy patience you had dad!

Because of the length of the post, I’ve decided to divide it into different parts:

  1. Overall description
  2. Detailed pictures
  3. Hardware description
  4. Test cases with videos
  5. Software description

Overall Description

In this project my father and I have tried to replicate a common lift with 5 floors (0 to 4) . We have two ways to move the lift, from the outside with its corresponding leds signalling the motion of the lift to go upwards or downwards and from within we have another set of push buttons to go to the floor we want to. There is a led in each button in the buttons which are inside to indicate the floor where the lift is headed to. Once the lift has reached the position where it is required to be the door will be opened, the lift will let some time to people to get in and then it will close the door and then it will move there where it is requested.

Because of having used interrupts it is not necessary to wait for the lift to be in a floor to call from somewhere else. During all the process, opening, closing door, moving upwards or downwards the lift will be able to store the request and service then when being able to. Here is a general video to see the inside and the outside of it:

Go to the index.

 

Pictures

Front view of the lift

Of course, the leds and the push buttons are recycled. The ones from the inside the lift are from an old phone. The others from PCBs, likewise the LEDS. Where the push buttons from the outside and the leds are is just a cable rack.

dav

Rear view of the lift

REAR VIEW

Main motor

Main motor

Go to the index.

Hardware description

The funniest thing is that most of the parts used on the lift have been recycled. With the exception of the arduino and some of the wires to connect the different boards, all the materials were already around my home, which is more challenging as it isn’t like assemblying a kit. There are lots of adjustements besides, bearing in mind that neither me nor my father are carpenters so our tools are as well quite limited.

I’ve decided to simplify a bit all the schematics, in truth there is some wired logic to get NC end limit switches from NO end limit switches through relays.

The sensors are a single IR emitter and 5 different IR receivers for each floor. These will set the green position leds which are up on the lift. The schematic for one of the emitter (which is in movement with the lift) and the sensors is the following (The receiver should be duplicated for the rest of the floors) :

Sensors floors

The way to control the motor of the door is made with two relays which invert the voltage to invert the motion of the motor. The open command or close command should be always sent by the arduino board. Once the door reaches the end, it hits either the open end limit switch or the close end limit switch, which stops the motor. Besides, it has been added

The electrical schematic for opening and close the door is the following:

Door control

There are certain security measures within the circuit such as stopping the lift if it’s moving upwards and it’s already on the last floor. This was made because before having the arduino somehow we could have messed it up inmensily. Likewise, on the floor 0 there is another contact that will stop the supply of energy to the motor if the lift is already on the floor 0. Besides, the lift will not move unless the door is fully closed. The schematic is the following:

Motion control

There are more of course, for example, if the door is being opened or closed the lift should not move, this has been done by programming and in the same way has been made redundant by wired locking. The schematic is the following:

Go to the index.

Test cases

In the first place, the priority is for the people who have called within the lift, why? Because we have to give priority to the people who waited and is already within the lift. Now let’s describe the test cases ilustrating each with a video:

Test case 1

If the lift is moving from the floor 4 towards the 0 and there are other “requesters” who call the lift to go down the lift should stop in each floor to pick them and then they would select a floor to go.

Test case 2

In the other way round, if the lift is in the floor 0 and it’s going towards the 4th one, the lift will stop in each floor where a up request has been made.

Test case 3

For this case we’ll call the lift in the same floor where the lift is. In this case the door should open and let the people in to move somewhere else.

Test case 4

If after having called the lift the people decide not to get in or get in and not push any buttons in the inside then the lift will stay there up to the point where another request is made.

Test case 5

Let’s imagine a case where the lift is stopped on the floor 0 and we call it to go upwards from the 3rd,2nd and 1st floor, in that order. The lift shouldn’t stop according to the last call but to the ones which are closer, so it should stop in the other way round, 1st ,2nd 3rd to pick the people who want to go upwards. The same would happen in the other way round as being on the 4th floor if we call it to go downwards from 1st,2nd and 3rd it should stop in this way: 3rd,2nd and 1st.

Test case 6

For this test case I’m going to get in the 3rd floor, go to the floors 2nd and 0. In the meantime I will call the lift to go downwards from the 4th floor. The lift will go to the 2nd and 0 floor and then it will go to the 4th one as it’s not in its path.

Test case 7

For this case, I’m going to get in the 1st floor and I’m going to the 3rd floor and being on the 2nd floor I will call it from the 0. The lift will go to the third floor and then to the floor 0.

Test case 8

In this case let’s imagine we are in the 0 floor, we go to the 3rd one. In the meantime someone calls from the floor 2nd to go downwards, in the 3rd one someone gets in and go to the floor 0 but in its path the lift will stop on the 2nd floor to pick the one who has called before reaching the floor 0.

Test case 9

For this case I’m going to duplicate the eighth. However, we’re going to call it from the 2nd to go upwards and after from the 1st to go downwards. Once in the 2nd I’m going to request the lift to go to the third one and only after having done so it will go to the first floor to go downwards.

I’m pretty happy with these test cases but if you have any other idea, just tell me and I will update the post.

Go to the index.

Software description

The explanation given here is quite too simple, but it may be helpful before giving a look to the code source.

To begin with, let’s start with the variables for the physical world:

ix Stands for boolean input and ox Boolean output, the numbers are the pins used on the Arduino ATMEGA 2560.

int ix_OUT_CALL_UP_0 = 2;
int ix_OUT_CALL_UP_1 = 4;
int ix_OUT_CALL_DOWN_1 = 3;
int ix_OUT_CALL_UP_2 = 6;
int ix_OUT_CALL_DOWN_2 = 5;
int ix_OUT_CALL_UP_3 = 8;
int ix_OUT_CALL_DOWN_3 = 7;
int ix_OUT_CALL_DOWN_4 = 9;

int ixBOX_CALL_0 = 26;
int ixBOX_CALL_1 = 24;
int ixBOX_CALL_2 = 25;
int ixBOX_CALL_3 = 23;
int ixBOX_CALL_4 = 22;

int ix_SENSOR_0=40;
int ix_SENSOR_1=41;
int ix_SENSOR_2=42;
int ix_SENSOR_3=43;
int ix_SENSOR_4=44;

int ox_BOX_LED_0 = 27;
int ox_BOX_LED_1 = 28;
int ox_BOX_LED_2 = 29;
int ox_BOX_LED_3 = 30;
int ox_BOX_LED_4 = 31;

int ox_UP_CMD = 32;
int ox_DOWN_CMD = 33;

int ox_OPEN_CMD = 34;
int ox_CLOSE_CMD = 35;

int ox_OUT_LED_UP = 36;
int ox_OUT_LED_DOWN = 37;

The classes used in the program are the following:

TON Class: I can’t help it but refer you to the post where I first did this class, here.

LIFT Class: This class is in charge of moving up or down depending on the target position and the current position with which is fed through the sensors. Besides, this class will open the door and close it once it has passed the determined time. With some of the methods of this class we will control the outputs of the arduino board. Besides, if the lift is on a floor and it’s called again, the sequence of opening/close door will be rebooted. This is a public atribute which is only access from within and the function CallManagerBlock().

The TON classes used in this class are within but we need the counter from the outside, this is why the tmrCounter is a variable for the Parameters method. We will be passing the current position, the target position and a flag saying if a sequence has finished.

As functions we have:

CallManagerBlock: Which returns nothing but is in charge of giving priority to the calls from the inside the lift. Likewise it calculates the distance to go to the calls closer.

Besides, it is in charge of handling with the calls of the outside of the lift, determining whether it is going up and from the outside someone wants to go up or someone wants to go down this function will determine which calls pay attention to first. If it is going upwards the lift will have this sequence to start going downwards (unless someone calls from within to go downwards).

PHYSICAL_CALL_MANAGER: Which doesn’t return anything and it will be the interface between the calls from the inside and the outside and will feed the algorithm (QUEUE_UP_MANAGER and QUEUE_DOWN_MANAGER) with the calls.

QUEUE_UP_MANAGER/ QUEUE_DOWN_MANAGER: These two functions do not return anything either. The aim of these functions is to write over an array (either to go up or to go down) just the calls that are not repeated.

Go to the index.

Advertisements

Arduino DUE vs UNO – First impression

Hello everyone!

I’m sure some of you have made yourself this question as considering buying an arduino clone: Shall I buy an arduino uno or a due for kind of the same price?. There are tons of differences which can be checked easily on your web browser. What I would like to do here is a comparative between the DUE and the UNO checking its speed to see the actual difference when it comes to loop or look for a character in a String or simple tasks such as digitalWrite or digitalRead. Of course, you will see a great difference between the Mega 2560 and the DUE if you check any video on youtube, such as the following one:

However I wanted to get to the specifics and by so I’ve carried out some simple tasks with surprising results. But enough writing, let’s begin the testing.

For the first test, I generated a string with numbers, from 0 to 20 000 then I printed it out, and the results were the following:

Comparison - String creating and print

 

As you can see, the Arduino DUE generated the string far more times faster, but when it came to display it I was surprised by how much it took it to do it.

And still you may think that as speeding the Serial communication this would vary significantly well, it varied indeed, but the results still are kind of the same, let’s see the test wit 115200 as baud rate:

Comparison 115200

I do need more time to look into why this happens but what has this inspired me is to try to make algorithms in a more efficient way, seeing this and having done some sketches I think that I could write them in another way to prevent the arduino board from freezing when receiving data from the usb port.

What about writing and reading a single output/input 30 000 times? (I know, it’s madness, it may not have any sense at all but I wanted to check it, just to see the boards’ response)

readwrite comparison

At first the loop of the test was set to 200 000 iterations, the DUE board outperformed significantly as I got even tired of waiting for the response of the UNO, after some testings I had to set both at 30 000 iterations because the UNO was kind of unable to end the process.

So far so good, I’ll keep you posted with some other tests I have in mind to carry out.

Arduino – TON, TOF and TP Timers V2 from microseconds to years!

Hello everyone!

I realized my libraries were not working properly as trying to set the timer to hours and let it for 12 hours. The problem is that I had written ((2^32)-1) for some calculations. At this point the variable was 0. I have solved it, anyway, if you test any of these libraries and find a bug or think of a better way to do it, I’ll be happy to hear about it.

It’s time to present a new version of the class TON that I’ll be using for my following projects. The delay for this timer can go from microseconds to years and it admits floats as the preset time. The code is far more simple than the previous version of my TON class. Here I’m not using interrupts and therefore the class is independent from them (for me a must). If in my previous version I used interrupts it was just to toy with them but in terms of pragmatism, I do rather this version.

The use of this class is very simple. But first let’s look at how this timer works, IN is the input variable that will initialize the timer. Q is the output and ET the elapsed time. Once the input is true, if the time that has gone by with IN being true is bigger than PT (Preset time) then our Q output will be true as long as IN is true. However if IN is true for a period smaller than PT then our output will never be true. This in words is a bit messy, but here’s the diagram of what words describe:

To use this class we instance the TON class.

TON TON1;

Then we pass its parameters in the

void loop() {

TON1.parameters(Input,T_DELAY,“Format”);

}

 

Where:

  • Input is a boolean that will initialize the delay.
  • T_DELAY is the preset time (after which if Input is true, TON1.Q() will be true as well).
  • “Format” can be:
    • “Microseconds”
    • “Miliseconds”
    • “Seconds”
    • “Minutes”
    • “Hours”
    • “Months” (I’ve determined 30 days for each month)
    • “Years”

There’s another thing we can retrieve from our TON class which is the elapsed time by accessing the method, TON1.ET().

In the following link I’ve updated an example of use.

In the same way as described below, there’s the TOF timer, which follows the following diagram:

TOF_Diagramm

In the following link you can get the class of the TOF Timer.

The TP timer is slightly different, its diagram is the following one:

TP_Diagramm

In the following link you can download the class of the TP Timer.

 

Twincat 3 – Back up pumps control

Hello everyone!

Today I’m going to explain a thing I had to do some time ago, it was slightly different but the overall functionality was kind of the same.

Imagine that we have a pump fed through a VFD controlled by a PID with its sensor and reference. For today’s example, we’re going to read that PID reference and if it’s higher than a set point for a period of time that we can configure, then we will turn on a pump fed through a soft starter.

Let’s see our overall system. We’re going to focus on the area highlited in green:

overall

First of all, I’ve created a data type (STRUCT) named as PUMP, whose variables are the following:

STATUS : INT; // 1 RUN, 2 STOP, 3 LOCAL
MODE : INT; // 1 AUTOMATIC MODE (An algorithm will take charge of it), 2 MANUAL
FAILED_TO_START : BOOL; // As receiving a start command the pump will have to start within a period of time. If not, this alarm will be raised.
FAILED_TO_STOP : BOOL; // As receiving a stop command the pump will have to stop within a period of time. If not, this alarm will be raised.
CURRENT_RT : REAL; // Accumulated running time of the pump.
HEALTHY : BOOL; // 0 Unhealthy ; 1 Healthy

For the modelling of the pump there are several modes to control the pump. Locally, we have the LOCAL_SELECTOR which will be true if the pump is controlled from the electrical panel, the algorithm will copy that state so that if it turns to REMOTE it will keep the very same status. The running feedback will be on if locally the pump is turned on or remotely we turn it on.

The pump has two protections, a thermal relay and a bearing relay, it should have far more, I just put two for the sake of simplicity. If the pump fails to start or to stop, it will be unhealthy and will remain like that until someone restart the pump. This has been made because by doing so we make sure someone has seen the alarm and somehow has acknowledge it. It could be added a log to register such alarms, but that is something out of the aim of today’s project.

As the algorithm will pay attention to the running hours of the pump, in case of replacing one of the pumps you’ll have to modify the running time of the pump (To set it to 0 or another pump if you are using that one from another facility with an amount of running hours accumulated).

For the commands I’ve decided to set all of them to 0 once we’ve gone once through this block, because of experience I do really recommend doing this, because if some command by any reason is latched from local to remote operation may result in undesired consequences.

I’ve created the following function block to control the pumps with the following I/O variables:

pump fb

About the algorithm, it will determine, within the healthy pumps which to start (the one in auto mode with the least current time accumulated) if the PID Reference is higher than the set point to start a pump. Likewise the algorithm wil decide the pumps to stop if the PID Reference is lower than the set point to stop a pump (the one with the most current time accumulated) The I/O variables of the function block are the following:

Algorithm fb

Here is a demo of the program simulated on TwinCAT:

 

The source code can be downloaded here.

Twincat 3 – Transfer circuit breaker

 

Hello everyone!,

In my last post I modeled a circuit breaker. The aim of the modeling of that circuit breaker was to use it later on for a “bigger purpose” let’s say.

Today that day has come and I’ve programmed an algorithm to automatically control the circuit breakers.

First let’s define the behavior of the automatic control:

  • If our two feeders are energized then the algorithm will give preference to the circuit breaker chosen by Preference (1 for circuit breaker 1 and 2 for circuit breaker 2).
    • In the case of one of the circuit breakers being closed without being the preference and the two feeders being energized, the algorithm will open first the circuit breaker that is closed so that we avoid the coupling of the two supply sources.
  • This is very important and vital, a circuit breaker will not close unless the other has been opened successfully as you’ll be able to watch in the video, if there’s a fail to open alarm in any of the circuit breakers, the other circuit breaker will not close. The reason you may wonder? We may be feeding a short-circuit in the other source.
  • If there’s only a power supply available (We only have voltage in one of the sources) then the corresponding circuit breaker should be closed if the other is already opened.
  • In case of any power supply losing its voltage the circuit breaker will be tripped.

Without any further delay, let’s see how it works in practice:

And from here you’ll be able to download the program.

Twincat 3 – Modeling a circuit breaker.

Hello everyone!

As it has been long since last post of a program using Twincat 3 I wanted to program an algorithm to transfer the power supply from one feeder to another but the very first step is to model a circuit breaker and then program the algorithm, today I’m publishing the Circuit breaker and the testing carried out through the HMI, I still am unable to modify values from the HMI, I have to write the variables through the IDE itself.

By the way, just as a reminder, Timers should be used in this manner: INSTANCE_TMR(IN:=CONDITION_TO_INITIALIZE, PT:=TIME_DELAY, Q=>OUTPUT); because if you try to do this:

INSTANCE_TMR.IN:=CONDITION_TO_INITIALIZE;

INSTANCE_TMR.PT:=TIME_DELAY;

It won’t work 😉

The circuit breaker is in charge of interrupting the energy for the Loads 1 to N connected to the Busbar. To represent the circuit breaker, the filled squared means that the circuit breaker is closed, in case of the square being empty, the circuit breaker is open and the cross means that the status of the circuit breaker is unknown.

As an exercise I propose you to add each event such as fail to open, fail to close and any change of status of the circuit breaker to an array of strings with N registers using a FIFO structure click here for more information about this structure.

Here’s the video of the testing:

 

There are two external lockings which are not wired, this is because circuit breakers vary and so does criteria. Therefore, the lockings that affect to the operation of the CB is whether there has been a fail to change its status or the status is already the one that has been commanded to be.

From here you can download the project.

 

 

STL – Tia Portal 14 – Start On Delay Timers

Hello everyone!

Today I’m presenting you to an example of how to use Start on delay timers in STL.

These two pdf sheets with the instructions of the STL may be of use for you:

Sheet 1– Sorted by category.

Sheet 2 – Sorted alphabetically.

However I would strongly recommend using F1 on your IDE to find out more about the particular function you want to use.

For my particular case and following the thread of the last post I’ve decided to model a tank with its respective High alarm, high warning, low warning and low alarm.

So, in STL how do I initialize a timer comparing values?

Let’s start by writing the High level alarm

We have must compare values, to do so we’ll use the function Load, L.

L #CV // We load the current value read from an analog input to the Accumulator 1.

L #HAlarmSP //We load the Set point when we’ll see an alarm to the accumulator 1, deplacing #CV to accumulator 2

>=R // We compare whether The accumulator 2 (#CV) is greater than the accumulator 1( #HAlarmSP) if this is true then the program continues its execution downwards.
L #AlarmDelay // We load the time to delay the alarm.
SD “TimerHAlarm” // We put the loaded time in the timer initializing it in case the condition mentioned above is true. (This has been declared in a TagList within the TIA Portal IDE.
A “TimerHAlarm” // This is the output of the timer (TMR.Q for those who use . notation)
= #HAlarm // This will be the bool that will be true once the time has elapsed.

So far, so good? I hope so, if not I’ll let the example I’ve programmed here.

And as an exercise I encourage you to program the rest of the code to get a High warning , Low warning  and Low alarm.

Here is the video of what I’ve programmed: