Showing posts with label Case Study. Show all posts
Showing posts with label Case Study. Show all posts

How to Code for RS232 in Visual Basic? Part 3 – Example

. Friday, October 23, 2009
6 comments

You can download the example program written in Visual Basic 6.0 from the following link:

MsCommSample.zip

Sample includes detailed explanations as comment lines, so I am not going to explaing details of coding in this post.

To test the software you need to have a null modem cable if you want to communicate two computers.

You can make your own cable by soldering pins of two female DB9 connectors as follows.

Connector 1                   Connector 2
Pin 2 <---------------------> Pin 3
Pin 3 <---------------------> Pin 2
Pin 5 <---------------------> Pin 5

If you just want to test how data is sent and received on your computer, you just need one connector; short circuit pin 2 and pin 3:

Connector 1
Pin 2 <--
        |
Pin 3 <--

Make the cables at your own risk, short circuiting any pins other than 2 and 3 may damage serial port of your computer.

By default, software opens the Com1 port in 9600 bauds, no parity, 8 data bits and one stop bit without handshaking protocol. You can change it in source codes.

You also need to have Visual Basic 6.0 software to edit, debug and recompile program.

How to Code for RS232 in Visual Basic? Part 2 – Getting Data From Serial Port

. Friday, August 7, 2009
2 comments


In this post, we are going to focus on OnComm event of serial port programming components. The most widely used serial port component is the MSComm.ocx of Microsoft, however it has some limited properties such as working up to COM16, you may also find more sophisticated components such as SAX Comm.

Also there was a TCommPort component for Delphi, also .Net has serial port support for 2005 and after. There are several alternatives to get data from serial port but the methods used for getting data is similar. So I want to explain this method in pseudo code in this post, and for the next post I want to give a real example with MsComm32.ocx and Visual Basic 6.0

There are two major methods to get data from serial port; polling method and event driven method. Polling method is the simplest, just place a timer on your form and continuously read the data from port. However with polling method you may get your data in partly, and you may need to write extra code to comb out different data packets received consecutively.

I want to focus on event driven method, which is more convenient, fast and less CPU consuming. 

Whatever the method used for reading, the first step is opening the port with proper communication parameters. Generally, I open the port on start up procedure of program, and do not close it until the end of program. You can't communicate with a closed port, so prefer to keep it always open. 

Some applications close the port when they do not need it, it may be useful especially in mobile devices to save power, but in desktop computers, it is better to keep always open, especially if your software is about industrial automation. 

I also get communication port settings from an ini file, because communication port parameters may depend on the device that you are communicating or the communication port limitations of the host computer, so remember to get the settings from an ini file, but this is optional, so say that it is the step zero of our pseudo code.

Setting up the port is easy, you must give following parameters:
- Communication speed
- Number of data bits; 7 or 8
- Type of parity; even, odd or none
- Handshake: Hardware handshake (RTS/CTS), software handshake (XON/XOFF) or none.

And if you prefer to use event driven method, you should also enable event triggering on data receive. For MSComm32.ocx it is set up by receive threshold value, you should set the number of bytes to trigger data received event.

Normally, I use 1 for receive threshold to get informed even a single byte received by comm port.  It should be better to set it to 1 if you receive variable length of data. In our examples, I am going to set it to 1.

With MSComm32.ocx, it is set up as follows:

MSComm1.RThreshold = 1

Then you can open the comm port. For MSComm32, it is opened as follows:

MSComm1.PortOpen = True

Sometimes, you may not be successful for opening the port, so it is strictly advised to code some error handling routines to catch any possible errors, otherwise your program may rise run time error and shutdown.  Most common errors are 'port already open / port already in use'  error and 'invalid port number'. There may be another software using your comm port, also another copy of your own software may block your port. To avoid blocking the comm port by the ghost of your software, it is better to check if another copy is already running on computer. 


We already have three steps of pseudo code including the optional one:

Step 0: Get communication port settings from ini file (Optional)
Step 1: Setup the port
Step 2: Open the port
  
Sending data is the simplest part, let's send 'Hello World' through comm port:

MSComm1.Output = "Hello World!"

If port is not open, you will probably get 'port not open / operation valid only when the port is open' error. So it is better to check if port is really open before sending data.

When data is received from a serial port, it is kept in a buffer until you read it. For MSComm32.ocx, you can get your data as follows:

Data = MSComm1.Input

If you put a timer on your form and continiously read the buffer, you get the data collected in buffer. This is called polling.

For event driven programming, you use the event triggered on receiving data. Here is the pseudo code for receiving a data by event driven programming:

Step 1: Continue if event is really triggered by received data.
Step 2: Disable event generation
Step 3: Wait for a while to get possible remaining bytes.
Step 4: Read and concatenate the data into a dummy static variable
Step 5: If expected data received completely (eg. received a terminator character), use it and clear the dummy static variable.
Step 6: Enable event generation


Now let's have a closer look into steps.

Step1: Some serial communication libraries use a single event for receiving. If you are using such kind of library, you don't need to check if event is triggered by received data. MSComm32 uses the same event for all communication port related events such as buffer owerflow, cts received etc. So it is necessary to check if event is triggered by received data:

Private Sub MSComm1_OnComm()
    If MSComm1.CommEvent = comEvReceive Then
        ' Do whatever you need
    End If
End Sub


Step2: If you don't disable event generation on data receiving, received byte(s) can break your already running flow, and if it happens before you flush the reading buffer, breaking events may flush them and you may get mis-ordered data. Altough its low probability, never forget that CPU can do millions of operations in a second and one in a million chance may hit in every seconds. So, disable event generation. For MSComm object, just assign a zero to receive threshold:

MSComm1.RThreshold = 0

Step3: Modern computers are faster than serial communication speeds. Taking a little breath in codes is adviced if you are using MSComm. There is a little bug I have noticed, if you poll MSComm objects buffer so frequently, it may not have a chance to flush its buffer and you may randomly get same bytes in your data. So, it is better to put some NOP code before reading buffer. There is a sleep API of Windows, however I am not satisfied with this API because I realised that it waits several lines of code after it has called, I know it sounds weird but I guess that sleep API is slowing down the Visual Basic interpreter, not the code interpreted. May be it works in compiled code but I am not happy to use it while debugging my source code. So I have my own subroutine which executes DoEvents in a loop.


Step 4: If your communication speed is so low, you may not receive it completely in a single event handler. If you see that you don't have the terminator character of your data package, you should keep your previously received data in a static variable. Example for MSComm:

Static DummyData As String 

...

DummyData = DummyData & MSComm1.Input


Step 5: If you receive the terminator character, use your data and clear static variable.Assuming that terminator character is carriage return:

If Right(DummyData,1= vbCrLf Then
    ' Data received completely
    ' Do some code to use for received data
  
    DummyData = vbNullString
End If


Step 6: If you don't re-enable the event generation, you can't get more data.

In our next post, we are going to have some practice, we are going to code a sample application in Visual Basic 6.0

How to Code for RS232 in Visual Basic? Part 1 – Serial Communication Basics

. Thursday, August 6, 2009
2 comments

In this post series, I would like to talk about receiving data from serial port. It is one of the FAQ of industrial automation forums, but it is difficult to find a proper code or advice. 


I am not going to talk about in details of a specific communication protocol, it may be a subject for another series of post. 


I only want to describe a sample method, and give an example by Visual Basic 6.0.  As I will talk about the method, you can apply it for .Net languages or any other programming languages such as Delphi.


We can choose a sample problem; I think reading data from a barcode scanner may be a right and simple example.


Now, let’s have a little bit theory about RS232 communications, it is designed to communicate for long distances without using many cables. RS232 defines the electrical signal levels, and those signals may be converted into other defined standards such as RS485 or RS422, so I am going to describe it with logical signal levels. 


Serial communication is just like a dialog between two people. Both of them have ears and mouths to listen and speak.


When Alice talks, Bob hears with his ears.


The RS232 port has a transmitting pin and a receiving pin. If you want to establish a communication between two RS232 devices, you must connect one device’s transmitting pin to other device’s receiving pin. Just as talking and listening. 


There is also one more pin which is used as a voltage reference, it is called ground. So only three cables are enough to make a serial communication. If communication should be done for one way only, two cables are enough, one for data and one for voltage reference.


When sending a byte, transmitting pin sends a single start bit signal to inform that a new byte is coming. 


Data bits sent after start bit, number of data bits can be 7 or 8 and it depends on the settings that you decide for communication.


It has information about number of logic 1 signals, even or odd numbers.


And finally stop bits come; number of stop bits can be 1 or 2. It can be considered as a guard time between data packages.


Most important parameter in serial communications is the baud rate, which is the number of bits per second. If you set your communication parameters as  8 data bits and 1 stop bit, you should use 11 bits for each byte packet (1 start + 8 data + 1 parity + 1 stop) and with the speed of 9600 baud, you can send up to 872 bytes per second.


In serial devices, an IC named UART makes the communication and buffers some amount of data inside. 


In next post, I am planning to tell a pseudo code for receiving data from serial port. 

Developing An ActiveX for WinCC Flexible

. Tuesday, August 4, 2009
3 comments

Several months ago, a customer requested a product tracing system which should work with SIEMENS PLC.


They already had a WinCC flexible licence and requested the project in WinCC.


First of all, I could not find a way to use RS232 comm ports with WinCC, so I decided to use SAX Comm library for RS232 communication.


It was not possible because I could never be able to compile the software even without any script code in it. Just adding SAX Comm object was enough to crash WinCC development environment. WinCC was raising the following error:


“Fatal ERROR: screen item Screen_1 in screen Screen_1 contains inconsistent data and should be deleted.”



Then I tried to code my own ActiveX, embedded SAX Comm object and mapped some properties and events, however result did not changed, WinCC was still crashing.


I decided to walk step by step, I realised that WinCC had a really pain about ActiveX, so I have started with a totally empty ActiveX and successfully compiled the WinCC project.


Then I started to add properties one by one, and with the first property of ActiveX caused a crash again.


In WinCC programming manual, it says that it is possible to read and write a property of an ActiveX within a script, but it was not true.


Reading or writing a property inside a script directly causes a crash.


I have found that the only way to use properties of An ActiveX is using ‘Internal Tags’ of WinCC. If you want to send data inside of an ActiveX, you create an internal tag and assign it to the one of the properties of ActiveX.


With Internal tags, I was successful to get data from PLC to my ActiveX, however I realised the major problem when I finished developing my ActiveX, and it was not possible to send data from ActiveX to WinCC (so PLC)


It was not possible to send by properties, because assigning ActiveX property to an internal tag was working one way only. There was not any ‘direction’ option.


Then I tried to send data by triggering ActiveX events, it was possible to trigger events of ActiveX but it was not possible to send some data by parameters of event.


So I decided to use ActiveX events as digital outputs, I have used them without sending any parameters.


For Boolean data, triggering was not a problem; I have created 2 events for each Boolean output and altered a Boolean internal tag on those events.


My final challenge was sending an integer code to a test device. Boolean outputs were easy but of course it is not convenient to create 255 events for a byte value.


So I created following events for sending byte information to WinCC:

ResetByte()
SetBit_0()
SetBit_1()
SetBit_2()
SetBit_3()
SetBit_4()
SetBit_5()
SetBit_6()
SetBit_7()
ByteReady()

Created a dummy internal tag and wrote single line scripts for each event:


Sub ResetDummy
tgDummy = 0
End Sub


Sub SetDummy_0
tgDummy = tgDummy + 1
End Sub

Sub SetDummy_1
tgDummy = tgDummy + 2
End Sub

Sub SetDummy_2
tgDummy = tgDummy + 4
End Sub

Sub SetDummy_3
tgDummy = tgDummy + 8
End Sub

Sub SetDummy_4
tgDummy = tgDummy + 16
End Sub

Sub SetDummy_5
tgDummy = tgDummy + 32
End Sub

Sub SetDummy_6
tgDummy = tgDummy + 64
End Sub

Sub SetDummy_7
tgDummy = tgDummy + 128
End Sub
And finally, for ByteReady() event I have write the following code for sending output to PLC:


Sub SetByteOutput()
tgByteOutput = tgDummy
End Sub


As an example, if I want to send code 120 to the test device, I convert its value to binary:

120 decimal = 0111 1000 Binary.

And triggered following events consequently:

ResetByte()
SetBit_3()
SetBit_4()
SetBit_5()
SetBit_6()
ByteReady()


Conclusions: In my opinion, WinCC Flexible is giant software, occupies gigabytes of space in hard disk but does not worth its price. Its tools are a little bit limited and it is difficult to do following tasks:

- Query some value from database and make decisions according to records from database.
- Serial or Ethernet communications with any devices other than SIEMENS.
- Third party ActiveX, WinCC does not have any guarantee for third party ActiveX.


And WinCC Flexible is only convenient if you:

- Don’t have experience on programming
- Use WinCC as only HMI
- Don’t need complex operations controlled by PC
- Have patience and high budget at the same time.

Case Study: Power Measurement System with Accurate Timing

. Wednesday, January 21, 2009
0 comments

In this post, I want to talk about a power measurement test system that tests an electrical device.
Our customer is producing a household appliance which has a boot up sequence.  In this sequence, device drives its internal components in certain time intervals which makes it possible to test if connections are done properly. So, each products have a power consumption graphic as below:


This graphic can be considered as a signature for products, many products have similar graphic with different level of power consumptions in different time intervals.
I can summarize customer requests as below:
Test parameters should be defined by a web page.
Test system should produce a test result code which can define each components test status such as 'heater is under it's low limit and fan is over it's high limit'. And of course, it should be reported on the web.
It is needed to store power consumption graphics for statistical calculations and it should be possible to report on a web page.
It is possible to apply power on the fly without an operator, customer does not want any operator except test parameter management.
Defected products should be diverted automatically to the defected area. 
Project requires web reporting, web reporting requires DB interaction, DB interaction requires PC. 
Project requires measurement with accurate timing, however PC can not do this properly because of its instability. It was necessary to take samples in each 100 milliseconds. Sure PC can handle this speed but it may not be possible to this in exactly 100 milliseconds. Well, sure it is possible but it is just a little bit difficult to do it, not easy for a formerly PLC programmer.  It can be done with multimedia programming techniques, recording a voice in 44 kHz is a similar but much more difficult task.
If you only have a hammer, you always consider that all problems are nail, so we decided to do it with PLC.  
We decided to measure with PLC and buffer the results in PLC memory.  
Of course we could do it without wasting PLC data memory, PLC could send data to PC in every 100 milliseconds, and it is very easy to handle it in PC, you can do it by RS232 or Ethernet, does not matter. Both of them triggers an event in PC which breaks existing program flow.  However, we  should also make a handshake between PC and PLC, because customer wanted products to be automatically diverted defected products, and PC has the answer. 
How did we manage the buffer in PLC? 
We continuously copied analog data to the beginning of memory buffer. We only copied 'FFFF' value once as the test started.  Then used 'SHIFT' command in PLC. 
So the result was as follows:
In PC, we have polled the memory buffer continuously and searched for the first 'FFFF'. When found, copied them in another array in reverse order. 

So we were sure that analog sampling was done in 100 milliseconds.

Another alternative for using 'FFFF' was incrementing one counter in every shift to determine the starting point of the shift, but using 'FFFF' technique required less coding in PLC. 

PC Stability

. Saturday, December 20, 2008
1 comments

My graduation thesis was about designing a smart card reader / writer circuit and making necessary software development for it. I have tried to design a low cost reader, so I decided to use parallel port of PC instead of using a micro controller.

My advisor encouraged me to develop the software in Linux, that is the story of 'How I met your Linux'. My first experience on linux was on Mandrake Linux 8.

One day, I have wondered how stable was the PC, and decided to make a little test. I have wrote a small software in C and compiled with GCC to produce square wave with the highest frequency that PC can handle.

I have visualised the wave in oscilloscope. PC was able to produce square wave approximately at 200 kHz. Frequency was decreasing as the CPU was loaded, as I expected.

Then I wondered the result in Windows. Rebooted the PC with Windows 98, wrote an equivalent code in assembly and executed. I was expecting to have a little bit higher frequency because code was written in assembly.

Result  was surprising for me, it was impossible to lock to the signal to display it on oscilloscope. Frequency was so unsteady that it was impossible to see with auto trigger or manual trigger.

Then I have tried to close some windows and terminated some background processes such as anti-virus. Frequency become more stable but it was still difficult to catch complete cycles more than five seconds. Finally, screen saver disturbed all the frequency.

I have measured the frequency with a frequency counter and it was nearly same as in Linux version, maximum 200 kHz.

Today, we are developing most of the automation projects on Windows operating system, so I wanted to make a small test before sending this post.

I wrote the following code:

---
Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Sub Form_Load()
    Dim i As Long
    Dim j As Long
    Dim StartTime As Long
    
    Dim StartCount As Long
    
    Open App.Path & "\Tick.csv" For Output As #1
        For i = 1 To 1000
        j = 0
        StartCount = GetTickCount
        Do While GetTickCount - StartCount < 20
            j = j + 1
            DoEvents
        Loop
        Print #1, j
    Next i
   
 Close
End Sub
---

Executed the code with and without DoEvents line. DoEvents function gives a breath to CPU for executing other processes.

Results are as follows, I have also calculated the histograms. The first one is with 'DoEvents':

And the histogram is:
And without 'DoEvents':


And histogram:


Adding 'DoEvents' decreases the execution speed but increases the stability. 

Graphics shows that you may not execute your code on time when you need it. 

Windows XP is more stable than I expected. However it seems that timing is still a problem if you don't use multimedia programming techniques for precise timing. 

In this test, you may realise one absence. I have intended to execute some amount of code in a certain time. But I have realised that time was not certain at all. I also intended to make one more test, I also have planned to measure the time to execute certain amount of code, however I have realised that GetTickCount functions resolution is not enough at all. I have realised that it returns multiple times of 16, not 1. I decied not to try to make the second experiment.

So I have suspections about the code above, I may have inaccurate measurements but it does not change the reality. PC is not stable enough if you are dealing with miliseconds. 


Perhaps, many people think the 'mean time between failures' when I talk about stability, blue screen of death (http://en.wikipedia.org/wiki/Blue_Screen_of_Death) is another problem in PC based automation systems. I think the maximum up time of PC is the matter of sustainability, not stability.

Sustainability is another problem, I have searched a little about the GetTickCount function (http://en.wikipedia.org/wiki/GetTickCount). It gives the uptime of computer in miliseconds. It can work up to 2^32 milliseconds=49.71 days.  I have never had a time to wait for, but possibly it will rise an 'overflow run time error' if not handled properly. This means that if you use GetTickCount function in your applications, you may need to restart your computer at most 49 days.  

In next post, I am going to tell about a power measurement system as a case study. Our customer was producing electrical devices which have a boot up sequence. During boot up, devices were driving their internal electrical components one by one in certain amounts of time, which makes it possible to test some components by measuring the power consumption.

Customer requested to manage all test parameters over a web page, and also wanted to see reports of test results in web pages,  making us to use PC. We were going to handle miliseconds with a PC. 

Object Oriented Design in Industrial Automation - Example

. Monday, December 1, 2008
1 comments

When I was a PLC programmer, object oriented programming was an unknown concept for me.  I did not mind about it since I have become a PC programmer.

In this post, I would like to talk about some benefits of object oriented programming with a simple case study.

An object is described as a computer representation of an existing real world thing or event. Object orinted programming languages gives the opportunity of dealing with these virtual objects, however if you don't design your system as 'object oriented', you can't use the benefits of object oriented approach.

Many PLC programmers have their programming library, most of the times they 'copy and paste' their rungs from previous or existing projects in to the new projects.

"DRY -  Don't repeat yourself" philosophy  is against for information duplication because duplication may increase the difficulty of change and decrease inconsistency. So, DRY philosophy should be agains 'copy and paste'.

Object oriented design helps you to not to repeat yourself.

Before giving an example, I would like to tell some concepts in object oriented programming, first concept is 'class'.

Class can be considered as a set of objects, and classes are also objects too. For example, a book can be considered as a class made up of multiple page objects. There are some properties of the book such as page count or colour. Also, there are some possible actions can be done with a book, such as reading, or placing on a shelf.
However, in programming classes are not object at all. They are definitons of object and its properties. With this point of view, a class can be considered just as a cookie cutter.


Once you design a cookie cutter, and you produce many cookies with it. The disadvantage of object oriented design can be seen here, if you are going to make only one or two cookies, building a cookie cutter is not convenient. But if you want to make dozens of cookies, a cookie cutter may be a good idea.

It is also possible to extend capabilities or properties of a class and make a superior class. For example, a dictionary is a special book that you can search words in it. So we can talk about the class 'dictionary' which can be derrived from class 'book'. All the actions can be done with a book is still valid with a dictionary, we can read it or place it on a shelf. This is inheritance, which aids reuse of code.

When you read a book, you don't mind how that book was written or how that book was published. You only see the pages of the book which can be considered as 'interface'. This is the principal of information hiding and mostly named as encapsulation.
Information hiding principle has two advantages:
- Programmer does not need to be so experienced
- It is difficult to corrupt the object, because its internal structure is protected

Let's back to our 'book' object. We are able to read books including dictionaries, almanacs, novels etc. Reading action can work on many different types of books. This is called polymorphism. You can ask many different objects to perform the same action.

Before starting to an example on real world of automation, let's revise the concepts we told about:
- Object
- Class
- Inheritance
- Encapsulation
- Polymorphism

Because we are going to check if it is possible to apply them in automation systems design.

A multiple rack store system is a common structure. Mostly, two or more shuttles are used to put or take goods. FIFO can be achieved by this system, and sometimes one of the racks runs in reverse direction to make it possible to take out a good in the middle of the rack.
Well, I think this system is common, becase I have seen at least five and they were used for different purposes such as automatic storage and retrieval system or quality assurance test system.
Anyway, we are going to model such a system below:
Eight racks with two shuttles, one rack is working in reverse direction. The shuttle on the right is used for loading, and the other is used for unloading. 
It is possible to store up to 128 boxes in this storage area. 
We want to built a virtual model of the real world, we are going to start by finding out the objects in this system.
It is not too difficult, the first object is conveyor. Our conveyors are driven by a motor, and a conveyor can store two boxes. Each conveyor conducts the boxes forward if next conveyor is available:




Our second object is shuttle. There are two shuttles and each shuttle can give and take boxes in reverse or forward direction.

Our third object is a little bit hidden. Racks are also objects, and they consist of conveyors.

Now, let's focus on our objects capabilities. For example, each conveyor can conduct a box from one conveyor to the next one. Also, each conveyor take boxes.
Many PLC programmers use at least two output flags to give information to the next conveyors code:
1 - I am ready to give
2 - I am giving

and use at least two input flags to give information from previous conveyors code:
1 - I am ready to take
2 - I am taking

Logic is easy, if target conveyor is ready to take and source conveyor is ready to give, box should move to the next conveyor.

We can think about two more objects on the basic conveyor object: a transmitter and a receiver. Of course, these are not real objects, just functionalities but thinking them as seperate objects will be convenient for us.
It is obvious that, transmitter object has 'Transmit' method, and receiver object has 'Receive' method. By designing them as methods, we won't involve in handshaking between two conveyors, remember the encapsulation.

Most object oriented PC programming languages present a notation for objects and methods as follows:
Transmitter.Transmit()
Receiver.Receive()

And these two objects are belong to a conveyor object, so in programming notation, it also can be presented as:
Rack.Transmitter.Transmit()
Rack.Receiver.Receive()

If you realise an inconsistency or a bug in your logic, you do not need to code for all conveyors, just change the transmit or receive method and all objects using these methods will be get changed. Maintenance of object oriented code is easy.

And what about shuttles? Shuttles are also conveyors and also should have transmitter and receiver. So, to transfer a box from shuttle to a conveyor, we should be able to write as:
Shuttle.Transmitter.Transmit()
Rack.Receiver.Receive()

However, shutles have one more fuınctionality, they can move in Y direction to travel between racks, so we can think for a move method for shuttle:
Shuttle.MoveY()

Our another object is rack. A rack is made up of 8 conveyors. Rack can take boxes from shuttle and give boxes to another shuttle. It seems hat we can directly map the rearmost conveyors receive method as racks receive methods and map the farthermost conveyors transmit method as racks transmit method. Mapping is done once, and programmer can use it as:
Rack.Transmit()
without minding that it is actually:
FarthermostConveyor.Transmit()

Many experienced programmers realise one more object: Eight racks form another big object, the 'layer'. Programmers must anticipate that system may be upgraded to a multilayer stock system in next years.

And the final object is the system itself, having several methods such as:
System.Store()
System.Retrieve()

It would be nice to retrieve a box of chocolates just by executing a single command:
System.Retrieve("The yummy one")

Conclusions:
PLC programmers are working with objects for many years, each conveyor, machine, system is an object. Object oriented design and object oriented programming are different concepts.
In our example, we designed our system in object oriented approach but could not give example with rungs. Actually, object oriented PC programming languages present tools and facilities to implement an object oriented system as a code, however the code running at the back is not so different from procedural programming

For example, in object oriented way, you create a Shuttle class. Then you create a specific shuttle object, such as 'InputShuttle'.

You do it as:
____________
Class Shuttle
Method MoveY()
...
...
End Class


Dim InputShuttle As Shuttle
...


InputShuttle.MoveY
__________

And in procedural way, you write a function for moving any shuttle, and state the shuttle to be moved as a function parameter:
__________
Function MoveY(Shuttle As TShuttle)
...
End Function


Dim InputShuttle As Shuttle
...


MoveY(InputShuttle)
...
_____________

With this point of view, function blocks can be used in procedural way.

PLC software development environments and languages does not supply neccessary support for object oriented programming, however you can still design your system in abject oriented approach to recude the amount of code you wrote.

I hope, PLC vendors intruduce new functionalities to their development tools for supporting object oriented programming.

For the next post, I am planning to post something about PC stability. Then I am planning to post a case study, 'Power measurement test system - Beating the speed limits'

Customer is always right and sometimes undefined

. Monday, November 10, 2008
0 comments

You may remember the cartoon  about ‘IT Project Management’

This is a great similitude and fits for most IT projects.

In this post, I would like to tell you about a project of mine which is different at the beginning.

Normally customers may request features that are contradictional, those contradictions are eliminated during project design in co ordinance with customer.

One of our customers requested us a project.  It was a modification on an existing assembly line which was developed by our team.

Let’s see how our customer described the request:
“We need to see cycle times of all stations on a web page, and also want to warn the operator on exceeding the cycle time.”

That’s all? No.

“We have a limited budget and don’t want to spend too much money and don’t want operators to do extra operations for reporting cycle times.”

Yes, that’s all. I just imagined the cartoon below:



On the left, how most of the customers explain their request. And on the right, my customer.

A warning light lit in my mind, it may be risky without handshaking clearly. Something was wrong.

So I asked:
“What do you want to get by reporting cycle times?”

The answer was:
“For line balancing of course”

Well, no more information.  Just all, we had to guess what customer is really requesting.

First of all, “cycle times of all stations” was cloudily, because assembly lines don’t have distinct cycle times. Assembly lines have an average cycle time during a time interval, and that is calculated as:

Cycle Time = (Total time spent [e.g. in a shift]) / (Total number of products)

It’s the average time needed to produce one product, and it is same for all stations because all stations are cascaded to each other.

So, probably the customer was mentioning “operation times” actually.  Now it was clearer, probably customer wanted to see “how their assembly line balanced, and how efficiently working”

Even customer did not request clearly, they should need the following reports:
-          Where are bottlenecks? (To consider dividing station or sharing some operations between neighbor stations)
-          Where are the most inefficient stations? (This is different than bottleneck. Some stations may cause scrap and it is possible to detect if any station is producing more products than final stations output.

In most cases, data collecting terminals are placed on assembly lines to collect number of products and operation times, but ,in this project customer did not want to add anything. 

Customer also did not wanted the answer of question “why my assembly line stopped in a certain time interval”

We had approximately 70 stations with operators. Operators have pushbuttons to send the product to next station. We were going to take necessary information from this buttons and existing sensors.

As you see, some customers may have contradictional requests, and some have none.

We are going to start to a new series of a case study, collecting operation times from assembly line. We are going to tell about how to analyze the project and how to design.

I would be glad if you comment on this post, especially what would you like to see in the case study.

Followers

Search This Blog

Comments

About Me

My photo
Automation engineer especially working on PC software development. Formerly I was coding on PLC, but now I am using mostly Visual Basic on PC.