Sunteți pe pagina 1din 101

POLITECNICO DI TORINO

Department of CONTROL AND COMPUTER


ENGINEERING (DAUIN)
Master of Science in Mechatronics Engineering

Master Degree Thesis

Laser Sensor RS485 Interface Design and


Tire DOT Code Scanner Software
Development

Supervisor Candidate
Prof. Paolo PRINETTO Iman AMIRTAHERI

Internship Tutors
Dr. Giulio GAMBARDELLA
Dr. Francesca BALESTRA

July 2016
Abstract

Tire industries have an annual total sale of approximately $32.1 billion. This number
itself shows how big is this market. Costumers usually buy car tires directly from auto
repair centers. So a tool that helps auto repairmen to sell their tires more effectively is
extremely valuable. Tire Profiles Italy company has designed two different solutions for
this purpose. Both of these devices detect the necessity of tire replacement by means
of scanning tire thread depth. Another important item that should be paid attention
to, is the expiry date of tire. This date is usually calculated based on production date.
According to the department of transportation regulations, tire producers are obliged to
emboss or engrave the production week and year in a structured code on the tire sidewall.
This code is also called as DOT code. So Tire Profiles Italy company introduced a new
project to design a device for DOT code scanning. There were several options about how
this device should scan the code technically. Among possible choices, the solution with 3D
laser sensor was selected. In this approach the laser sensor measures distances between all
points of a line and laser sensor itself. By moving sensor in a trajectory perpendicular to
its laser beam axis, it can scan the whole portion of tire. This thesis is mainly focused on
design and build a communication interface for this laser sensor in order to provide the
infrastructure for PC and laser sensor to communicate. At the next step, thanks to this
communication channel, a software for DOT code scanning is developed which performs
acquisitions and stores the corresponding data in a host PC. As a complementary study,
image pre-processing techniques are implemented in MATLAB and Qt plus Open-CV
framework.

ii
Contents

Abstract ii

List of Tables v

List of Figures vi

1 Introduction 1
1.1 General Tire Codes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1.1 Tire Specification Code . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1.2 Department of Transportation (DOT) Safety Code . . . . . . . . . . 2
1.1.3 Uniform Tire Quality Grading (UTQG) Code . . . . . . . . . . . . . 2
1.2 Tire Replacement Symptoms . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2.1 Tire Treads Depth . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2.2 Tire Expiry Date . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2 DOT Code Scanning 7


2.1 Camera Scanning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.2 Laser Scanning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

3 Laser Sensor 11
3.1 Functional Criterion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.2 Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.3 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3.3.1 Distance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.3.2 Height . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.3.3 Profile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.4 Communication Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.5 Time Flows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.6 Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

4 Communication Interface 21
4.1 Micro-Controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
4.1.1 General Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4.1.2 Pin Configurations . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
4.1.3 Universal Synchronous Asynchronous Receiver Transmitter (USART) 23

iii
4.2 RS485 Transceiver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
4.3 USB to Serial Converter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
4.4 Hardware Connections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.5 Software Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
4.6 PC-Sensor Communication Test . . . . . . . . . . . . . . . . . . . . . . . . . 30

5 Acquisition Software 33
5.1 LaserSensor Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
5.2 MainWindow Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

6 Image Pre-Processing 43
6.1 MATLAB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
6.2 Qt and Open-CV . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

7 Conclusion 63

Bibliography 65

Appendices 66

A Micro-controller C Code 67

B Laser Sensor Header Code 72

C Laser Sensor C++ Code 75

D Profile Processer MATLAB Code 83

E Profile Processor Header Code 88

F Profile Processor C++ Code 90

iv
List of Tables

1.1 Tire DOT code information content . . . . . . . . . . . . . . . . . . . . . . 2


2.1 Laser Scanning Technical Analysis . . . . . . . . . . . . . . . . . . . . . . . 9
3.1 Laser Sensor Functional Criterion . . . . . . . . . . . . . . . . . . . . . . . . 11
3.2 Laser Sensor Profile Matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.3 Laser Sensor Timing Values . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.4 Acquisition Timing Calculations . . . . . . . . . . . . . . . . . . . . . . . . 18
3.5 Relevant Laser Sensor Commands . . . . . . . . . . . . . . . . . . . . . . . 20
4.1 USART Pins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
4.2 USB to Serial Module Connections . . . . . . . . . . . . . . . . . . . . . . . 26
4.3 Micro-controller ATMega16 Connections . . . . . . . . . . . . . . . . . . . . 26
4.4 Max485 Connections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
4.5 Laser Sensor Connections . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
4.6 UBRRL Values for available baud rates . . . . . . . . . . . . . . . . . . . . 28

v
List of Figures

1.1 Tire Specification Code Sample: This code contains tire technical information. 1
1.2 DOT Code Sample: All safety information is gathered inside this universal
code. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3 UTQG Code Sample: This code contains tire grades in three different subjects. 3
1.4 Tire Tread Depth: Tire producers recommend to replace tires with less than
10% life time. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.5 Groove Glove Scanner: Handheld device to measure tire tread depth and
identify cars license plate. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.6 TreadSpec (PRT Scanner): Tread depth scanner which has to be installed
on the ground. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.1 Fixed Illumination: Naive approach to illuminate tire surface and capture
DOT code. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2 Variable Illumination: Camera captures every time that illumination changes. 8
2.3 Laser Sensor: Creates a distance profile line by line. . . . . . . . . . . . . . 9
3.1 Sensor Installation Methods: a) Standard Installation b) Angled Installation 12
3.2 Sensor Distance Measurements: Average, Maximum and Minimum . . . . . 13
3.3 Sensor Height Measurements: Average, Maximum, Minimum and Delta . . 13
3.4 Laser Sensor Coordinates: It creates a matrix of x and z elements for every
acquisition. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.5 RS485 Connection Diagram: This protocol can connect 15 sensors to a
master. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.6 RS485 Pin Diagram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.7 Laser Sensor Timing (Time Flows) . . . . . . . . . . . . . . . . . . . . . . . 17
4.1 General Connection Scheme . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
4.2 ATMega16 Pin Configurations . . . . . . . . . . . . . . . . . . . . . . . . . 23
4.3 MAX485 Pin Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
4.4 USB to Serial Converter Module . . . . . . . . . . . . . . . . . . . . . . . . 25
4.5 Communication Interface Connection Scheme . . . . . . . . . . . . . . . . . 25
4.6 TeraTerm Terminal Emulator Serial Settings . . . . . . . . . . . . . . . . . 30
4.7 PC-Sensor Communication Test . . . . . . . . . . . . . . . . . . . . . . . . . 30
4.8 RS485 Communication Interface . . . . . . . . . . . . . . . . . . . . . . . . 31
5.1 DOT Code Recognition Software (DCR) v1 . . . . . . . . . . . . . . . . . . 33
5.2 Signal Slots Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
6.1 MATLAB Loading Raw Data File . . . . . . . . . . . . . . . . . . . . . . . 45

vi
6.2 MATLAB 3D Surface Representation . . . . . . . . . . . . . . . . . . . . . . 46
6.3 Leveled Surface Representation . . . . . . . . . . . . . . . . . . . . . . . . . 47
6.4 MATLAB 3D Model Abrupt Changes . . . . . . . . . . . . . . . . . . . . . 48
6.5 MATLAB 3D Model Added Neighbors . . . . . . . . . . . . . . . . . . . . . 49
6.6 MATLAB 3D Model Removed Min Value . . . . . . . . . . . . . . . . . . . 50
6.7 Segmented Black & White Image . . . . . . . . . . . . . . . . . . . . . . . . 52
6.8 Segmented Grayscale Image . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
6.9 Contrast Stretched Image . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
6.10 Negative Image . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
6.11 Open-CV Loaded File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
6.12 Open-CV Orientation Corrected . . . . . . . . . . . . . . . . . . . . . . . . 59
6.13 Open-CV Colors Inverted . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
6.14 Open-CV Edges Sharpened . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

vii
Chapter 1

Introduction

This thesis report documents general information about vehicle tire codes, specifically tire
DOT code and its importance. Then different approaches for DOT code scanning are
analyzed and one of them is chosen. In the rest of this report, the selected approach is
documented, a communication interface is designed and built, a C++ software is developed
for data acquisition and at the end, some image pre-processing methods are performed.

1.1 General Tire Codes


In general, there are three unique codes embossed or engraved on the tire sidewalls.

1.1.1 Tire Specification Code


This code contains information about tire type,tire width, aspect ratio between its height
and width,construction type, wheel diameter, load index and speed rating. Figure 1.1
shows an example of this code on tire sidewall. Note that this code in a real tire is colored
black but in this image for better legibility it is highlighted with white color. [1]

Figure 1.1. Tire Specification Code Sample: This code contains tire technical information.

1
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

1.1.2 Department of Transportation (DOT) Safety Code


Federal laws have obliged tire producer companies to determine the safety related infor-
mation of their tires on its sidewall. This code is named department of transportation
safety code and from now on it is referred to as DOT code. Figure 1.2 shows a sample of
this code.[1]

Figure 1.2. DOT Code Sample: All safety information is gathered inside this universal code.

DOT codes may consist of 8 upto 13 characters. Depending on the coding that manufac-
turer uses, the embedded information varies but in any case some important data has to
be documented. Some of these information fields are gathered in table 1.1.

Table 1.1. Tire DOT code information content

Characters Example Definition


Index Characters
1-3 DOT DOT code identifier
4-5 B9 Tires Manufacturer and plant code
6-7 YR Tire size
8-11 UJNX Optional characters usually to determine brand and
other characteristics
12-13 50 Week of the year the tire was produced
14-15 08 Year the tire was produced (starts from year 2000)

1.1.3 Uniform Tire Quality Grading (UTQG) Code


This code was proposed by the national highway traffic safety administration to grade
tires based on their threadwear, traction and temperature. Figure 1.3 depicts a sample of

2
1 Introduction

this code.[1]

Figure 1.3. UTQG Code Sample: This code contains tire grades in three different subjects.

These grading subjects focus on quality figure of merits as described below.


Threadwear
This grade determines how much this tire will last with comparison to the other
tires of this producer. Baseline grade is 100, and theoretically a tire with grade of
200 should last twice as long as tire with baseline grade.
Traction
Traction grade is based on the tire ability to stop on a wet road. There is a standard
road which is used to perform this test on tires. Acceptable grades from high to low
are AA,A,B and C. Tires with traction grade of less than C are not qualified to be
used for road travels.
Temperature
One of the most important items in tires world is the ability of tire to dissipate heat.
There is a standard controlled indoor test which benchmarks tires heat dissipation
and grade them starting from A for the best ones. Tires with the grade of D and
below are considered unacceptable.

1.2 Tire Replacement Symptoms


Car tires are not designed to last forever and the they have to be changed on a regular
basis. There are two important items on tire checklist which recommend the car owner to
replace tires when at least one of them is checked.

1.2.1 Tire Treads Depth


Tire treads are designed to maintain sufficient interaction between tire and road surface.
After a period of time, tires begin to wear out and lose their treads depth. Most of tire

3
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

producers recommend costumers to change tires as soon as the tire treads depth fall less
than 2/32-inch (1.6mm). Figure 1.4 shows corresponding life time for each level of treads
depth. [2]

Figure 1.4. Tire Tread Depth: Tire producers recommend to replace tires
with less than 10% life time.

From longtime ago tread depth measurement was performed by means of length measure-
ment devices such as calipers. Even many of auto repairmen use a small coin to measure
depth. Although this kind of approach is not wrong and use the same principle but it is
not accurate enough because it is necessary to measure and check precisely not only for a
single spot of tire but also for all of its surface. So the accurate procedure is very time
consuming for an auto repairman to follow.
Tire Profiles Italy Srl. company has designed two different solutions to measure treads
depth.

Groove Glove Scanner


This handheld device is designed to measure tire depth and also identify car license
plate by means of laser triangulation and camera OCR respectively. Tire surface
is scanned by moving the device over it. Scanned data gets transferred to a cloud
server and required processes are performed inside there. Figure 1.5 shows a Groove
Glove Scanner device.[4]

TreadSpec
TreadSpec also known as PRT Scanner is a device which requires a solid structure to
mount on the ground surface. This solution is usually used on the entry point of auto
service centers and allows the driver to drive over it. In many cases people pay service
centers a visit just to change oil or diagnose an error, with this scanner installed in
the entrance, service centers generate a full report about tire tread depth and its
alignment. Hence, this device can boost their sale effectively. Figure 1.6 shows two

4
1 Introduction

Figure 1.5. Groove Glove Scanner: Handheld device to measure tire tread depth
and identify cars license plate.

pictures of this device combined. [3]

Figure 1.6. TreadSpec (PRT Scanner): Tread depth scanner which has to be
installed on the ground.

1.2.2 Tire Expiry Date


Despite from level of tire thread depth, it is crucial to replace the tire on a regular basis.
Most of tire producers guarantee their product for five years from the week that it was
produced.[5] So another interesting area for auto service centers is to have a device like
Groove Glove Scanner which determines the tire age. As mentioned in 1.1 on page 2, the
DOT code printed on the tire sidewall has the valuable information which indicates the
production week and year.

5
6
Chapter 2

DOT Code Scanning

So far, the reasoning behind necessity to design and make a device to scan DOT code
has been documented. From now on, two different approaches are analyzed and then in
following chapters, preferred approach is designed from hardware and software point of
views.
In order to have a complete vision of whole design process, primarily design requirements
are gathered in this way.

Have reasonable dimensions for a handheld device.

Have touch screen for user interaction.

Connect to cloud for storing raw scanned data and fetch processed data after com-
pletely processed.

Be capable of scanning DOT code completely, independent from the characters


count. Note that DOT code may consists of 8 upto 13 characters including the
DOT identifier initials.

According to this general design requirements many approaches came into mind. The
most important matter that affects the whole design process is that with which technology
this device has to perform scanning process. Two different solutions were proposed.

2.1 Camera Scanning


This idea makes use of a camera to take a photo from the portion of sidewall which DOT
code is located. The device should be designed such a way that it touches the tire surface,
so ambient light could not affect the photo quality. Then captured photos will be sent to
cloud server and get processed there. Figure 2.1 depicts working principle of fixed illumi-
nation method. A prototype of this approach has been already built in the company but
it has a critical problem.

7
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

Figure 2.1. Fixed Illumination: Naive approach to illuminate tire surface and
capture DOT code.

This prototype masks the ambient light thanks to its method of usage which is touching
tire surface. Instead, it has many infrared diodes to illuminate the DOT code when it
captures the photo. Since these illumination lamps are turned on and off simultaneously
and the camera axis is perpendicular to tire surface, it is not possible to distinguish
characters since tire codes are embossed or raised on the body of tire and it is a black on
black pattern.

In order to overcome this problem variable illumination technique (structured lighting)


has proposed[14]. Since the DOT code is only detectable due to its altitude difference,
variable illumination technique can eliminate background and just maintain the raised
code. This technique turns on then lights one by one and captures a photo each time,
because of altitude difference in tire surface each time the resulting shadow will be different.
Then a sophisticated algorithm gathers all of these photos and combine them together
based on the shadows. At the end, the obtained final photo shows only DOT code and
eliminates its background. Figure 2.2 shows a simplified version of this approach. Usually
there are at least 8 lights to illuminate tire surface and they are placed on a circular base.
This method is also called as structured lighting.

Figure 2.2. Variable Illumination: Camera captures every time that illumination changes.

8
2 DOT Code Scanning

2.2 Laser Scanning


Another possible approach is to use laser sensor to measure the distance between a number
of points belonging to a line. By movement of laser sensor, it is possible to gather these
distances line by line and then generate a 3D model of the scanned tire surface. In this way
there is no need to take care about illumination because the laser sensor measures directly
the distance so there is no need to distinguish DOT code height from scanned image.
Figure 2.3 depicts the new configuration in the same framework of previous approaches.

Figure 2.3. Laser Sensor: Creates a distance profile line by line.

In order to make a comparison between new approach and the previous one, table 2.1 is
created with pros and cons of this new approach. By considering this comparison table,

Table 2.1. Laser Scanning Technical Analysis


Pros Cons
Independent from illumination Scans whole DOT code gradually
Works better in dusty environment Need to move over tire with constant speed
More accurate scanning Sensitive to sensor tilt or rotation
Less data for transmitting to cloud Slower scanning

the best approach is to use camera scanning with variable illumination but because the
engineering part of Tire Profiles Italy company has already defined the project with laser
sensor, this thesis focused on laser scanning. Following chapters are dedicated to introduce
the laser sensor and its features, design an interface for communication with it, design an
user interface to connect to the sensor and perform acquisition, design a protocol to save
measurement data, and try to perform some simple image processing techniques to improve
the scanned data.

9
10
Chapter 3

Laser Sensor

So far, the desired design approach is selected. In this chapter, the laser sensor is in-
troduced, its features are documented and an appropriate communication interface is de-
signed. Sensor selection is another decision which was imposed by the Tire Profiles Italy
company. For administrative and economical reasons, this sensor was already selected and
purchased for this project.

3.1 Functional Criterion


The selected sensor is produced by Baumer company and its from MESAX multi -distance-
measuring sensors family. It measures distances and heights of objects and was specially
developed for easy handling. Also it makes use of a red beam to help sensor alignment.
Table 3.1 denotes functioning criteria for the sensor OM70B-15LB-11125351.[6]

Table 3.1. Laser Sensor Functional Criterion


Function Valid Criteria
Start of measuring range 100mm
End of measuring range 150mm
Measuring field width left 36mm
Measuring field width right 36mm

3.2 Installation
According to sensors datasheet provided by Baumer company [6], it can be installed in
two different methods.

Standard Installation
In this configuration sensor is mounted at a right angle with respect to the surface.

11
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

This method of installation is recommended since there is no need to estimate per-


spective effect. Figure 3.1 (a) shows a typical standard installation. This is very
important that the object is located in the functional range (10cm 15cm).

Angled Installation
When space condition does not allow to install sensor in standard configuration it
is possible to tilt sensor upto 30 from the perpendicular reference line. In this case
also, object has to lie within the functional criteria. Note that in this configuration
distance function of sensor does not work and only height function is accessible.

Figure 3.1. Sensor Installation Methods: a) Standard Installation b) Angled Installation

For the purpose of DOT code scanning it is the best to use standard installation since
always there is enough space for auto repairman to hold the scanner device perpendicular
to the tire sidewall surface. Final design should consider a method to satisfy function
range of 10 upto 15 cm of device for all scanning process. There are two different solution
to ensure this device always lie in the correct range.

Warn auto repairman when the device is approaching to its functional range limits.
For example two LEDs or a single buzzer may be considered as the method of
notification.

Device housing can be designed such a way that when it touches tire sidewall there is
a distance of 12.5cm between laser sensor and DOT code. In this way auto repairman
should ensure that there is a contact between device and tire during the scan process.

Since this decision is not a matter of current thesis, it is left for other engineers to decide.

3.3 Functions
This sensor supports three different functions.

12
3 Laser Sensor

3.3.1 Distance
To perform distance measurement it is required to send corresponding command and
choose the desired option. Sensor basically measures the distance between itself and all
points lying in the scanned line. Then it finds the minimum, maximum and also the
average of these measured distances. According to the sent command it responds with one
of these three values. Figure 3.2 depicts these three different measurements on a sample
surface.

Figure 3.2. Sensor Distance Measurements: Average, Maximum and Minimum

3.3.2 Height
Similar to the Distance function, Height function can be selected by sending appropriate
command and attaching desired measurement type. Same as the previous case, sensor first
measures all points to sensor distances and then perform selected operation. Specifically for
Height function all measurements are taken with respect to a hypothetically defined plane
called reference. This plane must be taught to sensor through a certain procedure. Height
command can return minimum, maximum or average distance between line points and
reference plane. There is also another option called delta height which returns maximum
difference between points altitude. Figure 3.3 depicts the purpose of each described option.

Figure 3.3. Sensor Height Measurements: Average, Maximum, Minimum and Delta

13
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

3.3.3 Profile
As described in the two previous functions, this laser sensor always measures the distance
between itself and all points in the scanned line. These measurements are stored in a
matrix format. Figure 3.4 depicts these coordinates on a sample object and table 3.2
denotes a blank profile matrix.

Figure 3.4. Laser Sensor Coordinates: It creates a matrix of x and z elements


for every acquisition.

Table 3.2. Laser Sensor Profile Matrix


x(1/100mm) z(1/100mm)

This function is only accessible when device is in diagnose mode. Since for a 4cm field
of view, it is necessary to transmit about 400 (x,z) pairs, this mode is dramatically slower
than previous modes.

Although this mode of function is slower than the others, but this is the only way to
capture all measurements and build the tire altitude profile. So this mode of operation
is selected and since it only works in diagnose mode, almost all other functions are not
accessible at the same time.

3.4 Communication Protocol


This sensor uses RS485 protocol for communication. RS485 protocol is designed to trans-
mit data in differential mode. In 1962, single-ended data transmission was introduced.
A few years later differential data transmission introduced to overcome single-ended data
transmission losses in noisy environments. RS485 can work in half duplex or full duplex
modes. Half duplex is referred to a connection with possibility of sending and receiving but

14
3 Laser Sensor

not at the same time. Full duplex mode defines a similar connection but with capability
to send and receive simultaneously. This protocol requires two wires for half duplex mode
and four wires for full duplex transmission. According to Baumer sensors datasheet, fig-
ure 3.5 shows required configuration in order to connect upto fifteen sensors to a master.[7]

Figure 3.5. RS485 Connection Diagram: This protocol can connect 15 sensors to a master.

The most important features of this topology are listed in this way.

Master is the only member of this configuration which can initiate a request. Sensors
are slaves, so they do no transmit anything unless master asks for it.

This configuration can support a baud rate of 115kbit/s at max.

Maximum possible length of cable is 10m.

RS485 cables must be shielded.

There are two failsafe resistors called RB to define the resistance level when no
transmitter is active.

Since there is only one sensor to work with, first topology is selected for communication.
This sensor came with a default shielded cable. Figure 3.6 denotes corresponding pin
diagram for this cable.
The suggested voltage supply for this sensor is 24v. Also it is recommended to connect

15
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

Figure 3.6. RS485 Pin Diagram

all other not connected pins to ground to help noise cancellation.

16
3 Laser Sensor

3.5 Time Flows


RS485 commands must be sent through a certain structure so the sensor can interpret
and response appropriately. Before listing the possible commands, it is better to dedicate
a few sentences about communication speed. It is preferred to describe this matter in
current section rather than previous one because it is actually possible to modify the
communication speed via commands.
This laser sensor can work with three different baud rates.[7]

1. 38400 bits/s

2. 57600 bits/s

3. 115200 bits/s

The default configuration for baud rate is 57600 bits/sec. It means that every time that
sensor is powered on, it automatically interprets incoming requests with baud rate of
57600. Also it is possible to change this value with corresponding command and save it
to configuration flash.
Since the application goal is to make acquisition with the highest possible rate, the sensor
timing to response the request is very crucial. Figure 3.7 denotes various timing variables
and table 3.3 determines their values.

Figure 3.7. Laser Sensor Timing (Time Flows)

Since the application must use the sensor in diagnose mode, the maximum time re-
quired by sensor to process the request and prepare appropriate response can be derived
as follows.

(tsmax )noerror = tanswerdiagmode = 200ms


(tsmax )error = tbreak = 500ms

To make a rough calculation about order of acquisition rate, lets assume that field of
view attribute is set to 4cm. In other words, laser sensor is scanning only line with width
of 4cm per each acquisition iteration. According to table 3.2 on page 14, laser sensor
returns a pair of x and z elements for each 0.5mm of field of view.
4cm
Total number of pairs = 0.5mm = 80

17
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

Table 3.3. Laser Sensor Timing Values


t_answer Time from reception of the last character of request to X 2.5ms
sending the first character of the answer.
t_answer_ Time from reception of last character of request to sending X 200ms
diagmode the first character of the answer if the sensor is in
diagnosing mode.
t_idle Time from reception of last character of answer to sending 0.1msX
the first character of the next request
t_break If a request or an answer is not completed during t_break, X 500ms
the message is rejected.

Number of characters per each (x,z) pair = 4 2 = 8


Total number of characters to send for each acquisition = 80 8 = 640
Total number of bits to send = 640 8 = 5120
5120
Time required to transfer bits with the highest baud rate 115200 = 44ms

By combining information from this calculation and previous one, table 3.4 denotes timing
values for an acquisition with field of view equal to 4cm.

Table 3.4. Acquisition Timing Calculations


Timing Reference Period Frequency
Fastest acquisition 44.5ms 22.47Hz
Slowest acquisition (without error) 244.5ms 4.09Hz
Timeout Error 500ms X

To have a rough calculation, it is assumed that laser sensor requires 100 ms (half of
maximum value) to perform measurement and prepare appropriate data. Acquisition pe-
riod = 100 + 44.4 + 0.1 = 144.5ms
1
Final acquisition rate = 144.5m = 6.92Hz

With this calculation its quite clear that this acquisition rate is low, for better under-
standing this matter here is an example. Lets assume it is required to make acquisition
every time that red line moves 1mm (half precision with respect to x axis). According to
the calculated acquisition rate, it is possible to derive,

M ovementDistance 1mm
Movement speed of laser sensor = M ovementT ime = 144.5m = 6.92mm/sec

In other words, if sensor is moved with speed of 7mm/sec (less than 1cm/sec), the acquired
data precision in y axis will be half of x axis precision. Now it is more observable that

18
3 Laser Sensor

this laser sensor is not suitable for the real action, but since this sensor has been already
purchased, the prototype designing was based on this sensor.

3.6 Commands
In previous sections, all important features of laser sensor and its communication rules
were analyzed. In this section, relevant commands are listed and described. Every single
command has to have a predefined structure in order to be decode-able for laser sensor.[7]
Command structure consists of following ordered items:
Start identifier: A simple colon character ":" is used to acknowledge beginning of a
command.

Device address: Two digits have the responsibility to determine target device ID.
All sensors have address equal to 01 at power on instant. In order to have more than
one sensor in a network, sensors ID must be configured one by one such a way that
there will be no conflict among them.

Payload: This part of command can have different number of characters depending
on the command format. Payload itself consists of:

Type: It can be "W" or "R" to determine the command is to write or read a


content respectively.

Index: This item has three characters and form a number. Every single com-
mand which is supported by laser sensor has an ID called index. To perform a
desired operation, command must specify the corresponding index. Note that
it is possible for a single index to support both write and read operations.
Separator: A semicolon character ";" is used before and after of each payload
element to clarify elements from each other.
Payload element: If the desired command requires a payload element (data) to
perform operation, desired data should be placed in payload element. Note that,
it is possible to have many payload elements separated by semicolon separator.

CHECKSUM: This code is generated by CRC-16 algorithm in order to avoid cor-


rupted command execution. CHECKSUM code is generated by the master and will
be controlled by slave upon message receipt. This code can be overridden by using
"****" code instead.

Termination characters: A combination of carriage return "\r" and line feed "\n"
characters is used to determine the commands end. The same characters are used
to represent a new line in Microsoft Windows operating systems.
Most of laser sensors in the category of "MESAX multi-distance measuring" have a
built in display and user input. This specific sensor does not have this feature because
there is no intention to interact with the laser sensor directly. With this introduction, all

19
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

of these sensors are locked in the sense that it is not possible to communicate with them
via RS485 protocol unless they receive a specific command to unlock themselves.
Command to unlock RS485 communication port: ":01W010;0;E9C3\r\n"
Note that this command should be sent by baud rate equal to 57600 bits/sec.

Table 3.5 has summarized relevant laser sensor commands.

Table 3.5. Relevant Laser Sensor Commands

Command In- Read- Description


Name dex /Write
Baud Rate 006 RW Selects baud rate. (0:38400 1:57600 2:115200)
Diagnose 050 RW Activates/deactivates diagnose mode.
Mode (0:Deactivate 1:Activate)
Profile 052 R Returns (x,z) pairs

20
Chapter 4

Communication Interface

So far, laser sensor characteristics and its features have been analyzed. In order to perform
the communication with this device, first it is necessary to define what is the final device
which requires to communicate with laser sensor. Since data acquisition should be made
by a computer, the final device is computer. But according to the design requirements
listed on page 7, this communication should be wireless. So its a wise choice to add a
micro-controller between this connection to regulate the connection and also to create the
infrastructure for further wireless module addition. Note that adding wireless module was
not a part of this thesis and it is left for further improvements. Figure 4.1 depicts the
general connection diagram considered so far. More detailes will be added during this
chapter.

Figure 4.1. General Connection Scheme

4.1 Micro-Controller
There were different choices for micro-controller device. From a simple Arduino board
till more complicated boards like Raspberry pi series, all of them could satisfy device
requirements but with a glance to the mass production requirements, it was more rational
to use a micro-controller integrated circuit instead of working with a board. One of the
most famous and easy to use family of micro-controllers are AVR produced by Atmal
company. To choose between micro-controllers residing in this family, there were a few

21
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

points to consider:
Output levels of micro-controller must use TTL logic, because RS485 uses TTL logic
for each wire otherwise there is a need for level shifter.

It must have dedicated ports for UART/USART communication.

It is recommended to have SPI port for further wireless module or gyroscope addition.

In order to work with the highest possible baud rate, micro-controller has to be able
to work with 11.0592MHz clock. This clock assures that UART/USART communi-
cation error will be less than 0.0%.
According to these requirements, ATMega16 micro-controller was the selected choice
among AVR micro-controllers. In the rest of this chapter, technical relevant characteristics
of this device are documented.[9]

4.1.1 General Overview


This little and cheap micro-controller has many features, here are the most important
ones.
Operating Voltage: 2.7V - 5.5V

Speed Grade: 0 - 8 MHz

I/O and Packages

32 Programmable I/O Lines


40-pin DIP, 44-lead TQFP and 44-pad QFN/MLF

Peripheral features

Programmable Serial USART


Master/Slave SPI Serial Interface
Byte-Oriented Two-wire Serial Interface
Four Timer/Counters
Four PWM Channels

32*8 General Purpose Working Registers

Non-volatile Memory Segments

16Kbytes of fIn-System Self-programmable Flash program memory


512 Bytes EEPROM
1 Kbyte Internal SRAM

The micro-controller used for this project was packaged in DIP format because in this way
it is much easier to use it on bread board.

22
4 Communication Interface

4.1.2 Pin Configurations

Figure 4.2 denotes pin configurations for ATMega16 micro-controller. Some of pins have
dual functions and they can be selected by software. For example pin #14 is the IO #0
of port D in normal condition. It can be configured to function as serial receiver also.

Figure 4.2. ATMega16 Pin Configurations

4.1.3 Universal Synchronous Asynchronous Receiver Transmitter (US-


ART)

In order to manage the RS485 connection between PC and the laser sensor, micro-
controller has to work with its USART block. According to the pin configurations on
figure 4.2, table 4.1 denotes all USART related pins.[9]

Table 4.1. USART Pins


Pin# Normal USART Description
Function Function
14 PD0 RXD USART receiver input.
15 PD1 TXD USART transmitter output.
11 GND GND Should be connected to the PC and laser sensor
grounds to share the same voltage levels.

23
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

4.2 RS485 Transceiver


Using micro-controller as the medium does not mean that USART output can be con-
nected to RS485 wires. As previously mentioned RS485 can use two or four wires for
communication in half duplex or full duplex mode respectively. This laser sensor supports
only the half duplex mode, Thats why its designers have considered only two wires for
communication in RS485 shielded cable. In order to plug USART output to RS485 con-
nection a transceiver is required. One of the most common solutions for this problem is
MAX485 integrated circuit.[10]
Figure 4.3 shows MAX485 transceiver pin configuration. As it is possible to observe in
the figure, this IC is composed of two tri-state buffers. RE and DE has the responsibility
to control these buffers. RS485 uses two wires to transmit one bit in differential format.
For example in order to represent a "0" logic A has "0" value and B has "1" value. The dif-
ference between these two levels which for this case is -5V, determines that the sender has
sent "0". Its exactly vice versa when sender is transmitting "1". So two control signals, RE
and DE select that master is going to send a command or receive a response respectively.
During command sending DE is set to "1" and RE is set to "0". It is opposite when laser
sensor is transmitting response. DI connects to TXD of micro-controller and RO should
be connected to PC. More information will be provided during this chapter.

Figure 4.3. MAX485 Pin Configuration

4.3 USB to Serial Converter


A few years ago, it was very common for personal computers and laptops to have port
for serial connection. Nowadays it is completely rare to have this kind of port for normal
computers and there are only USB ports that can do the same thing. In order to send
and receive in a serial connection, operating system needs to open a COM port. USB to
Serial converters create a virtual COM port so PC can threat with it like a normal one.
At the other side there is a small circuit to convert USB data signals (D+ and D ) to Rx
and Tx signals. Figure 4.4 depicts a USB to Serial converter module. It has a USB port

24
4 Communication Interface

so a USB cable can connect it to PC. There are also five pins which three of them deliver
GND, 3.3V and 5V and the two remaining form the serial connection wires (Rx and Tx).
This is not a complicated module, most of USB to Serial converters make use of PL2303
chip for data conversions.[11]

Figure 4.4. USB to Serial Converter Module

4.4 Hardware Connections


So far, required elements have been introduced. In this section, connections between these
elements are described. Figure 4.5 depicts all required connections between previously
described elements.

Figure 4.5. Communication Interface Connection Scheme

In this scheme, PC which is the final device to send commands to laser sensor and
receive response from it, is connected to USB to Serial converter via a simple USB cable. So
in the PC, by installing appropriate driver, it is possible to open a COM port and transmit
serial data. Commands sent by PC are delivered to micro-controller. Micro-controller has
the responsibility to control RS485 connection. This control means that, if there is a
command to be delivered to laser sensor, micro-controller prepares the line by setting DE
to "1" and RE to "0". In this way line is ready to accept value from micro-controller. While
this situation exists, the command is sent to laser sensor. Micro-controller will change the
line situation immediately after sending is finished. In this way the command is sent and
line is ready to receive answer from laser sensor. After computation time required by

25
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

laser sensor, response will be sent back and since the line is tuned to deliver data from
laser sensor to PC, the response propagates through MAX485 and directly reaches USB to
serial and then PC. According to this scheme, tables 4.2,table 4.3,4.4 and 4.5 summarized
are required connections for USB to Serial module, micro-controller ATMega16, MAX485
transceiver and laser sensor respectively.

Table 4.2. USB to Serial Module Connections


Pin# Pin Name Connects to
1 5v Not Connected
2 GND Circuits GND
3 3.3v Not Connected
4 NC Not Connected
5 Tx ATMega16 Pin #14 RXD
6 Rx Max485 Pin #1 RO

Table 4.3. Micro-controller ATMega16 Connections


Pin# Pin Name Connects to
10 VCC Circuits 5V
11 GND Circuits GND
12 XTAL1 Crystal 11.0592MHz Pin #1
13 XTAL2 Crystal 11.0592MHz Pin #2
14 RXD USB to Serial Pin #5 Tx
15 TXD MAX485 Pin #4 DI
20 PD6 MAX485 Pin #2 RE and Pin #3 DE
31 GND Circuits GND
Other Pins Not Connected

26
4 Communication Interface

Table 4.4. Max485 Connections


Pin# Pin Name Connects to
1 RO USB to Serial Pin #6 Rx
2 RE ATMega16 Pin #20 PD6
3 DE ATMega16 Pin #20 PD6
4 DI ATMega16 Pin #15 TXD
5 GND Circuits GND
6 A Laser Sensor Pin #6 PINK
7 B Laser Sensor Pin #1 WHITE
8 VCC Circuits 5V

Table 4.5. Laser Sensor Connections


Pin# Pin Name Connects to
1 WHITE MAX485 Pin #7 B
2 BROWN Circuits 24V
6 PINK MAX485 Pin #6 A
7 BLUE Circuits GND
Other Pins Circuits GND

4.5 Software Design


So far, hardware design part of communication interface has been completed. Now it is the
time to go into details and create a software for micro-controller to act as a medium and
regulate the connection. This kind of micro-controller is produced by Atmel company.
Atmel suggests an IDE called Atmel studio to program and also simulate this micro-
controller. This can be done by programming using Assembly or C language. Since
using assembly language is very time consuming, C language was preferred. There is also
another IDE called Code Vision AVR which is produced by a third party company called
HP InfoTech. Since this IDE can produce a lot of code automatically by means of selecting
required resources in a graphical user interface, it was the selected IDE to work with.
As previously mentioned, all initialization is made automatically according to pro-
grammer inputs. Here are some important portions of code to initialize various variables.
Listing 4.1 denotes variable initialization for PORT A of micro-controller. In this case;
all pins of PORT A are selected for input and they are working in tri-state mode. It is
possible to select inputs with pulled-up mode to avoid floating signals, but since there is
no need to work with PORT A in current configuration the default configuration remains
untouched. Other ports are initialized in the same way.
1 DDRA=(0<<DDA7) | (0<<DDA6) | (0<<DDA5) | (0<<DDA4) | (0<<DDA3) | (0<<DDA2) |
(0<<DDA1) | (0<<DDA0) ;

27
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

PORTA=(0<<PORTA7) | (0<<PORTA6) | (0<<PORTA5) | (0<<PORTA4) | (0<<PORTA3) |


(0<<PORTA2) | (0<<PORTA1) | (0<<PORTA0) ;
Listing 4.1. Port Initialization
Next item to initialize is USART interface. Listing 4.2 contains all required codes to
initialize USART with following details.
Baud rate: 57600 bits/sec

Databits: 8

Startbit: 1

Stopbit: 1

Parity: Even

Sender/Receiver Interrupt: No

UCSRA=(0<<RXC) | (0<<TXC) | (0<<UDRE) | (0<<FE) | (0<<DOR) | (0<<UPE) | (0<<


U2X) | (0<<MPCM) ;
2 UCSRB=(0<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (1<<RXEN) | (1<<TXEN) | (0<<
UCSZ2) | (0<<RXB8) | (0<<TXB8) ;
UCSRC=(1<<URSEL) | (0<<UMSEL) | (1<<UPM1) | (0<<UPM0) | (0<<USBS) | (1<<
UCSZ1) | (1<<UCSZ0) | (0<<UCPOL) ;
4 UBRRH=0x00 ;
UBRRL=0x0B ;
Listing 4.2. USART Initialization
Variables like UCSRA are micro-controller control registers and variables like TXC
are pre-defined masks in order to use in such cases for appropriately modifying control
registers. Control register UBRRL, selects the transmission baud rate based on system
clock frequency. Table 4.6 denotes corresponding values and their transmission error
percentage for three available laser sensor commands.

Table 4.6. UBRRL Values for available baud rates


Bitrate (bits/sec) UBRRL (hex) Error Percentage
38400 0x011 0.0%
57600 0x00B 0.0%
115200 0x005 0.0%

Now that the micro-controller is all set, it is necessary to discuss about its duty.
As it has been said earlier, micro-controller should define lines situation by constantly
monitoring the PC output. If the output has the character ":", micro-controller sets its
pin #6 of port D to "1" and then puts the same character on its serial output which is
connected to laser sensor through MAX485. Also a local protocol is considered that PC
should send a special character with ascii code of 0x0B to micro-controller to acknowledge

28
4 Communication Interface

command termination. So each command starts with ":" and ends with 0x0B character.
After receiving ":" character, micro-controller outputs the received data till termination
character (0x0B) receipt. At this point, micro-controller toggles line situation by setting
port D pin #6 to "0". In this way, after enough processing time, laser sensor sends the
corresponding response back to the PC without micro-controller interference. Listing 4.3
contains above explained code. Since micro-controller should constantly run this program,
this code portion is placed in an always true loop.

1 while (1)
{
3 ch=g e t c h a r ( ) ;
i f ( ch== : )
5 {
PORTD. 6 = 1 ;
7 p u t c h a r ( ch ) ;
}
9 e l s e i f ( ch==0x0B )
{
11 f o r ( i =0; i <100; i ++) ;
PORTD. 6 = 0 ;
13 }
else
15 p u t c h a r ( ch ) ;
}

Listing 4.3. Main Program

As previously mentioned, laser sensor can operate with three different baud rates and
the default one is not the fastest one. Although it is possible to change the baud rate and
store it in the configuration flash of laser sensor, for the sake of maintenance and plug and
play integrity, the micro-controller code is designed to change baud rate to the fastest one
upon system power up. With this option, PC program always send required commands
with baud rate equal to 115200 bits/sec and micro-controller has the duty to change laser
sensor and also its own baud rate at first place.

PORTD. 6 = 1 ;
2 c r=0x0D ;
cn=0x0A ;
4 delay_ms ( 2 0 0 0 ) ;
p r i n t f ( " : 0 1 W010 ; 0 ; %c%c " , cr , cn ) ;
6 delay_ms ( 1 0 0 ) ;
p r i n t f ( " : 0 1 W006 ; 2 ; %c%c " , cr , cn ) ;
8 delay_ms ( 1 0 0 ) ;
UBRRL=0x05 ;

Listing 4.4. Baud Rate Adjust

In this code portion, first, communication line gets ready for command transfer, then
after a delay of 2 seconds, micro-controller unlocks the RS485 lock, changes laser sensor
baud rate and then changes its own baud rate to 115200 bits/sec. Delays are considered
due to laser sensor power up latency and MAX485 propagation time.

29
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

4.6 PC-Sensor Communication Test


At this point, communication interface setup is complete. By providing required voltage
sources (5V and 24V) to the circuit, laser sensor turns on and emits a red beam, then
micro-controller configures laser sensor to use baud rate equal to 115200 bits/sec. Next
step is to connect USB cable to PC and circuit. Windows will automatically install the
appropriate driver. Now everything is ready and it is possible to communicate with laser
sensor. In order to just test the connection a terminal emulator was necessary. There are
many free solutions like TeraTerm and Putty. Figure 4.6 shows TeraTerms serial settings
dialogue filled with communication interface configuration data.

Figure 4.6. TeraTerm Terminal Emulator Serial Settings

By hitting OK, COM port opens and now everything is ready to send a command
to laser sensor and wait for response without having concerns about RS485 protocol or
anything else. Figure shows a sample command and its corresponding response communi-
cated between PC and Laser Sensor. In this communication, PC sent a request to unlock
RS485 lock.

Figure 4.7. PC-Sensor Communication Test

Figure 4.8 shows the final version of RS485 communication interface functioning. On

30
4 Communication Interface

the left side, there is the power supply which has 5V and 24V voltage sources. On the
right side there are microcontroller, MAX485 and USB to serial converter.

Figure 4.8. RS485 Communication Interface

31
32
Chapter 5

Acquisition Software

In previous chapter, a communication interface was designed and built to make PC-Sensor
communications possible. A sample command sent by means of TeraTerm terminal emula-
tor and corresponding responses received. In this chapter, the goal is to design a software
to automate this process. So the software should be able to initiate a connection to the
laser sensor, send requests, receive responses, display them in a graphical way and store
them in a file for further usage.
In order to have possibility to compile the program for different operating systems and
also for accessing to simpler features, Qt IDE has been used for software development.
Qt IDE is developed and supported by Nokia company. Nowadays many programmers
and developers use Qt for software development. Figure 5.1 depicts the first version of
acquisition program designed. During rest of this chapter different program sections will
be analyzed.[12]

Figure 5.1. DOT Code Recognition Software (DCR) v1

Qt IDE supports signals and slots methodology for objects communication. During

33
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

software design process, it was decided to create a class for laser sensor communication,
so this class could be imported to any other applications for development. In this case,
the object created of this type can use signals and slots for communication or it can be
used in an ordinary way. To proceed with thesis report, two different classes are analyzed
independently. One class called "LaserSensor" is dedicated to sensor communications and
another class called "MainWindow" is for user interface.

5.1 LaserSensor Class


This class is dedicated to handle sensor communication request. With this topology, main
application does not need to worry about RS485 command structure, command index and
so on. Class definition is made through "lasersensor.h" and "lasersensor.cpp" files. Listing
5.1 summarize all declared slots for this class. Thanks to this kind of approach, a signal
emitted by user click on a button can be connected to one of these slots, so whenever that
button is clicked, the laser sensor object will execute desired command.
1 private slots :
void FindAvailablePorts ( ) ;
3 v o i d I n i t C o n n e c t i o n ( QString PORTName) ;
v o i d CheckConnection ( ) ;
5 void ReadApplicationError ( ) ;
v o i d ReadVendorInfo ( ) ;
7 void ReadDeviceInfo ( ) ;
v o i d ReadBusAddress ( ) ;
9 v o i d WriteBusAddress ( i n t BusAddressValue ) ;
v o i d ReadBaudRate ( ) ;
11 v o i d WriteBaudRate ( i n t S e l e c t ) ;
v o i d ReadRS485Lock ( ) ;
13 v o i d WriteRS485Lock ( b o o l Switch ) ;
v o i d ReadTouchButtonLock ( ) ;
15 v o i d WriteTouchButtonLock ( b o o l Switch ) ;
v o i d ReadMeasurementType ( ) ;
17 v o i d WriteMeasurementType ( i n t S e l e c t ) ;
v o i d ReadMeasurementValue ( ) ;
19 v o i d ReadAllMeasurementValues ( ) ;
v o i d ReadFieldOfView ( ) ;
21 v o i d WriteFieldOfView ( i n t L i m i t L e f t , i n t L i m i t R i g h t ) ;
v o i d WriteFiledOfViewToMax ( ) ;
23 v o i d ReadObjectType ( ) ;
v o i d WriteObjectType ( b o o l Switch ) ;
25 void ReadPrecision ( ) ;
void WritePrecision ( i n t S e l e c t ) ;
27 v o i d ReadLaserOffDataHold ( ) ;
v o i d WriteLaserOffDataHold ( b o o l Switch ) ;
29 v o i d ReadFlexMountEnable ( ) ;
v o i d WriteFlexMountEnable ( b o o l Switch ) ;
31 v o i d ReadSetFlexMount ( ) ;
v o i d WriteSetFlexMount ( f l o a t Angle , f l o a t D i s t a n c e ) ;
33 v o i d WriteTeachFlexMountCommand ( f l o a t R e f e r e n c e T h i c k n e s s ) ;
v o i d ReadDiagnoseMode ( ) ;
35 v o i d WriteDiagnoseMode ( b o o l Switch ) ;

34
5 Acquisition Software

void ReadProfile () ;
37 void WriteStoreConfigurationCommand ( i n t C o n f i g ) ;
void WriteResetToFactorySettingsCommand ( i n t Command) ;
39 void CloseConnection ( ) ;
void SampleNoChanged ( QString SampleNumber ) ;
Listing 5.1. LaserSensor Class Private Slots
Despite from these available slots, a LaserSensor object can emit signals. Signals can
be used in order to send the appropriate response back to the original program. Figure
5.2 depicts an example of this approach. Listing 5.2 lists all declared signals for this class.

Figure 5.2. Signal Slots Example

signals :
2 void A v a i l a b l e P o r t s ( i n t TotalNumber , QVector<QString> P o r t s ) ;
void ConnectionStatus ( bool Status ) ;
4 void ApplicationError ( int ApplicationError ) ;
void VendorID ( i n t Vendor_ID ) ;
6 void VendorName ( QString Vendor_Name ) ;
void DeviceID ( i n t Device_ID ) ;
8 void VariantID ( i n t Variant_ID ) ;
void SensorType ( QString Sensor_Type ) ;
10 void SerialNumber ( QString Serial_Number ) ;
void BusAddress ( i n t BusAddressValue ) ;
12 void BaudRate ( i n t BuadRateValue ) ;
void RS485Lock ( b o o l Switch ) ;
14 void TouchButtonLock ( b o o l Switch ) ;
void MeasurementType ( QString Type ) ;
16 void MeasurementValue ( f l o a t MeasurementValue , QString Q u a l i t y ) ;
void Average ( QString a v e r a g e ) ;
18 void Max ( QString max) ;
void Min ( QString min ) ;
20 void D e l t a ( QString d e l t a ) ;
void S t a n d a r d D e v i a t i o n ( QString s t a n d a r d d e v i a t i o n ) ;
22 void Q u a l i t y ( QString q u a l i t y ) ;
void FieldOfView ( i n t L i m i t L e f t , i n t L i m i t R i g h t ) ;
24 void ObjectType ( QString ObjectType ) ;
void P r e c i s i o n ( QString P r e c i s i o n ) ;
26 void LaserOffDataHold ( b o o l Switch ) ;
void FlexMountEnable ( b o o l Switch ) ;
28 void SetFlexMount ( f l o a t Angle , f l o a t D i s t a n c e ) ;

35
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

void DiagnoseMode ( b o o l Switch ) ;


30 void P r o f i l e ( i n t Xpos [ 3 0 0 ] , i n t Zpos [ 3 0 0 ] ) ;
void SensorTimedOut ( b o o l Switch ) ;
32 void ProfileReady () ;
Listing 5.2. LaserSensor Class Signals
So with these slots and signals, all requests are sent through slots and all responses
are emitted via signals. Now lets go into the details and analyze the most important slots
functions.

Laser Sensor Constructor:


This function is called whenever a new object of class LaserSensor is created. This
initializes serial communication and sets its baud rate to 115200 bits/sec. This serial
connection uses a Qt library called "QtSerial.h". After serial port initialization,
it initialize some other variables that will be covered later. Listing 5.3 denotes
LaserSensor constructor definition.
LaserSensor : : LaserSensor ()
2 {
qRegisterMetaType<QVector<QString> >( " QVector<QString>" ) ;
4 s e r i a l = new Q S e r i a l P o r t ( t h i s ) ;
s e r i a l >setBaudRate ( Q S e r i a l P o r t : : Baud115200 ) ;
6 s e r i a l >s e t D a t a B i t s ( Q S e r i a l P o r t : : Data8 ) ;
s e r i a l >s e t P a r i t y ( Q S e r i a l P o r t : : EvenParity ) ;
8 s e r i a l >s e t S t o p B i t s ( Q S e r i a l P o r t : : OneStop ) ;
s e r i a l >s e t F l o w C o n t r o l ( Q S e r i a l P o r t : : NoFlowControl ) ;
10 D e v i c e A d d r e s s =1;
Yindex =0;
12 f i l e c r e a t e d=f a l s e ;
SampleNo=" 1 " ;
14 }
Listing 5.3. LaserSensor Constructor

The third line of code has the duty to register a meta type in order to provide
possibility to move an object of this class to a new thread. DeviceAddress variable
is always one since there is only one sensor in RS485 network. Yindex is the index
of scanned lines and it is set to zero at first. After each successful acquisition it will
be automatically incremented. filecreated flag is used to check if the profile text file
is created or not. In read profile mode, laser sensor class should store acquisition
data in a text file. SampleNo variable is defined to identify different tire samples. It
is just there for further result comparisons.

FindAvailablePorts
This function scans for all COM ports, then removes those ones that are not available.
A COM port is not available when another program is using it and it is flagged as
busy. Then it emits a signal containing total number of available ports and their
names. Listing 5.4 denotes corresponding codes.
void LaserSensor : : FindAvailablePorts ( )

36
5 Acquisition Software

2 {
i n t TotalNumber =0;
4 QVector<QString> P o r t s ( 0 ) ;
f o r e a c h ( c o n s t Q S e r i a l P o r t I n f o &i n f o , Q S e r i a l P o r t I n f o : :
availablePorts () )
6 {
i f ( ! i n f o . isBusy ( ) )
8 {
P o r t s . append ( i n f o . portName ( ) ) ;
10 TotalNumber++;
}
12 }
emit A v a i l a b l e P o r t s ( TotalNumber , P o r t s ) ;
14 }
Listing 5.4. FindAvailablePorts: Returns all ready to connect COM ports

SendCommand
All slots use a function to send a command to laser sensor. SendCommand receives
a string as input, then adds other necessary elements to its begin and end according
to the RS485 command structure. Listing 5.5 contains corresponding codes.
v o i d L a s e r S e n s o r : : SendCommand ( QString Command)
2 {
QChar c r=0x0D ;
4 QChar cn=0x0A ;
QChar s t o p c h a r=0x0B ;
6 QString ToSend=" : " ;
ToSend . append ( QString ( "%1" ) . a r g ( DeviceAddress , 2 , 1 0 , QChar ( 0 ) ) ) ;
8 ToSend . append (Command) ;
ToSend . append ( " ; " ) ;
10 ToSend . append ( " " ) ;
ToSend . append ( c r ) ;
12 ToSend . append ( cn ) ;
ToSend . append ( s t o p c h a r ) ;
14 s e r i a l >w r i t e ( ToSend . t o L a t i n 1 ( ) ) ;
}
Listing 5.5. SendCommand: Prepares command and sends it.

In this function start, carriage return, line feed and stop char has been defined. Stop
char is the conventional character 0x0B that informs micro-controller to change the
RS485 line mode. After command preparation, it will be sent byte by byte to serial
port thanks to the toLatin1 method of QString class.

ReceiveResponse
This function is intended to be called by each slot after SendCommand execution.
In this way, the function will be blocked until a response is received or a time-out
occurs. Listing 5.6 gathers all necessary codes for this purpose. This function returns
true in case of response receipt and false in case of time-out.

37
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

1 bool LaserSensor : : ReceiveResponse ( )


{
3 QChar cn=0x0A ;
Response . c l e a r ( ) ;
5 b o o l C o m p l e t e l y R e c e i v e d=f a l s e ;
while ( ! CompletelyReceived )
7 {
i f ( s e r i a l >waitForReadyRead ( 5 0 0 ) )
9 {
Response . append ( s e r i a l >r e a d A l l ( ) ) ;
11 qDebug ( ) << Response ;
i f ( Response . c o n t a i n s ( cn ) ) C o m p l e t e l y R e c e i v e d=t r u e ;
13 }
else
15 {
return f a l s e ;
17 }
}
19 qDebug ( ) << Response ;
Payloads=Response . s p l i t ( " ; " ) ;
21 Payloads . r e m o v e F i r s t ( ) ;
return true ;
23 }
Listing 5.6. ReceiveResponse: Verifies response receipt.

This code makes use of serial library time-out ability. If no new byte is received
within 500msec, if statement will be false and function returns false, acknowledging
that the request has been timed-out so the main function should request it again.
If a byte is received, it will be added to Response variable and cleared from serial
buffer. The while loop remains true, until the line feed character receipt. After
successful command receipt, function splits it to payloads. Usually sensor responses
have payloads to return measurement values.

WriteDiagnoseMode
As previously mentioned about working with profile command of laser sensor, this
command is only available when laser sensor is in diagnose mode. So the WriteDi-
agnoseMode has the duty to enter laser sensor to this mode. Listing 5.7 denotes
corresponding functions.
1 v o i d L a s e r S e n s o r : : WriteDiagnoseMode ( b o o l Switch )
{
3 SendCommand ( "W030; 20;20 " ) ;
ReceiveResponse ( ) ;
5 SendCommand ( " R030 " ) ;
ReceiveResponse ( ) ;
7 SendCommand ( "W050 ; 1 " ) ;
i f ( ReceiveResponse ( ) )
9 {
emit DiagnoseMode ( t r u e ) ;
11 }

38
5 Acquisition Software

}
Listing 5.7. WriteDiagnoseMode: Activates diagnose mode.

Although this function is designed to just activate the diagnose mode, it also sets the
field of view range. In third line, laser sensor is asked to set its measuring range from
-20mm to 20mm with respect to the center of red beam. Then the same attribute
requested to read for verification. Finally at line 7, program sends diagnose mode
activation command and if the response is received, it emits a signal to MainWindow
which yields to a check in a checkbox.

ReadProfile
Finally, its time to analyze the main function that collects acquisition data. This
function creates two data files and store the same content into both of them. The
reason of creating two identical files is that, for image pre-processing part, it was
necessary to address a constant file name in MATLAB. In order to prevent from
overwriting the previously made acquisition, another file with date, time and also
sample number is created each time. According to listing 5.8, this function performs
a profile acquisition once and emits a ProfileReady signal when its done. This is the
duty of MainWindow to call this function in a loop to scan multiple lines.
void LaserSensor : : ReadProfile ( )
2 {
if (! filecreated )
4 {
QDateTime c u r r e n t d a t e a n d t i m e = QDateTime : : currentDateTime ( ) ;
6 P r o f i l e D a t a . s e t F i l e N a m e ( " Pr ofil eData _Sam ple "+SampleNo+"_"+
c u r r e n t d a t e a n d t i m e . t o S t r i n g ( " yyyyMMdd_hhmms s " )+" . t x t " ) ;
P r o f i l e D a t a . open ( QIODevice : : WriteOnly ) ;
8 ProfileData1 . setFileName ( " P r o f i l e D a t a . txt " ) ;
P r o f i l e D a t a 1 . open ( QIODevice : : WriteOnly ) ;
10 P r o f i l e S t r e a m . s e t D e v i c e (& P r o f i l e D a t a ) ;
P r o f i l e S t r e a m << "Y\tX\ t \Z " <<e n d l <<e n d l ;
12 P r o f i l e S t r e a m 1 . s e t D e v i c e (& P r o f i l e D a t a 1 ) ;
P r o f i l e S t r e a m 1 << "Y\tX\ t \Z " <<e n d l <<e n d l ;
14 f i l e c r e a t e d=t r u e ;
}
16 SendCommand ( " R052 " ) ;
i f ( ReceiveResponse ( ) )
18 {
Q S t r i n g L i s t XZMeasurements ;
20 XZMeasurements=Payloads [ 1 ] . s p l i t ( " " ) ;
i n t TotalMeasurements=XZMeasurements [ 0 ] . t o I n t ( ) ;
22 XZMeasurements . r e m o v e F i r s t ( ) ;
Yindex++;
24 f o r ( i n t i =0; i <TotalMeasurements / 2 ; i ++)
{
26 P r o f i l e S t r e a m << Yindex <<" \ t " << XZMeasurements [ 2 i ] <<" \ t
" <<XZMeasurements [ 2 i +1] <<e n d l ;
P r o f i l e S t r e a m 1 << Yindex <<" \ t " << XZMeasurements [ 2 i ] <<" \
t " <<XZMeasurements [ 2 i +1] <<e n d l ;

39
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

28 }

30 }
emit P r o f i l e R e a d y ( ) ;
32 }
Listing 5.8. ReadProfile: Makes profile acquisition once.

This function primarily checks for file existence, if it is not created, it creates two files
as described above. Then it prints column headers into these two files. After that
a command with read profile index will be sent to laser sensor and upon successful
receipt, it splits (x,z) pairs and prints them along corresponding y index into both
files. Listing 5.9 shows 10 lines of an acquisition data file with 10534 lines.
Y X Z
2
1 0 3889
4 1 50 3897
1 100 3911
6 1 150 3955
1 200 3966
8 1 250 3953
1 300 3971
10 1 350 4006
Listing 5.9. Read Profile Sample

5.2 MainWindow Class


In previous section, the LaserSensor class was introduced. In this section MainWindow
class is going to be analyzed. This class also is defined by means of "MainWindow.h" and
"MainWindow.cpp" files. MainWindow class is already filled by the information coming
from user interface design and other necessary initialization. There are not too many
modifications required for this class since most of the work is done in LaserSensor class.
By the way it is necessary to define a new object of class LaserSensor and a new thread
to move the object into it. Listing 5.10 denotes corresponding codes.
L a s e r S e n s o r S e n s o r = new L a s e r S e n s o r ( ) ;
2 QThread SensorThread = new QThread ;
Sensor >moveToThread ( SensorThread ) ;
Listing 5.10. Thread Creation for LaserSensor Object

Note that the thread should be started before program execution, but this will happen
after signal and slots connections definition. So next part should define the signal and
slots connection. This process is like wiring building blocks. Listing 5.11 lists all of these
connections.
1 // Find A v a i l a b l e P o r t s

40
5 Acquisition Software

c o n n e c t ( ui>Refresh_Ports , SIGNAL( c l i c k e d ( ) ) , Sensor , SLOT(


FindAvailablePorts () ) ) ;
3 c o n n e c t ( Sensor , SIGNAL( A v a i l a b l e P o r t s ( i n t , QVector<QString >) ) , t h i s , SLOT(
S h o w A v a i l a b l e P o r t s ( i n t , QVector<QString >) ) ) ;

5 // I n i t i a l i z e Connection
c o n n e c t ( t h i s , SIGNAL( I n i t C o n n e c t i o n ( QString ) ) , Sensor , SLOT( I n i t C o n n e c t i o n
( QString ) ) ) ;
7 c o n n e c t ( Sensor , SIGNAL( C o n n e c t i o n S t a t u s ( b o o l ) ) , ui>S e r i a l _ S t a t u s , SLOT(
s e t C h ec k ed ( b o o l ) ) ) ;

9 // Vendor I n f o r m a t i o n
c o n n e c t ( ui>GetVendorInfo , SIGNAL( c l i c k e d ( ) ) , Sensor , SLOT( ReadVendorInfo ( )
));
11 c o n n e c t ( Sensor , SIGNAL( VendorID ( i n t ) ) , ui>VendorID_Label , SLOT( setNum ( i n t
)));
c o n n e c t ( Sensor , SIGNAL( VendorName ( QString ) ) , ui>VendorName_Label , SLOT(
s e t T e x t ( QString ) ) ) ;
13
// D e v i c e I n f o r m a t i o n
15 c o n n e c t ( ui>G e t D e v i c e I n f o , SIGNAL( c l i c k e d ( ) ) , Sensor , SLOT( R e a d D e v i c e I n f o ( )
));
c o n n e c t ( Sensor , SIGNAL( DeviceID ( i n t ) ) , ui>DeviceID_Label , SLOT( setNum ( i n t )
));
17 c o n n e c t ( Sensor , SIGNAL( VariantID ( i n t ) ) , ui>VariantID_Label , SLOT( setNum (
int ) ) ) ;
c o n n e c t ( Sensor , SIGNAL( SensorType ( QString ) ) , ui>SensorType_Label , SLOT(
s e t T e x t ( QString ) ) ) ;
19 c o n n e c t ( Sensor , SIGNAL( SerialNumber ( QString ) ) , ui>SerialNumber_Label , SLOT
( s e t T e x t ( QString ) ) ) ;

21 // Read A l l Measurement Values


c o n n e c t ( ui>ReadAllMeasurementValues , SIGNAL( c l i c k e d ( ) ) , Sensor , SLOT(
ReadAllMeasurementValues ( ) ) ) ;
23 c o n n e c t ( Sensor , SIGNAL( Average ( QString ) ) , ui>Average_Label , SLOT( s e t T e x t (
QString ) ) ) ;
c o n n e c t ( Sensor , SIGNAL( Min ( QString ) ) , ui>Min_Label , SLOT( s e t T e x t ( QString ) )
);
25 c o n n e c t ( Sensor , SIGNAL(Max( QString ) ) , ui>Max_Label , SLOT( s e t T e x t ( QString ) )
);
c o n n e c t ( Sensor , SIGNAL( D e l t a ( QString ) ) , ui>Delta_Label , SLOT( s e t T e x t (
QString ) ) ) ;
27 c o n n e c t ( Sensor , SIGNAL( S t a n d a r d D e v i a t i o n ( QString ) ) , ui>
StandardDeviation_Label , SLOT( s e t T e x t ( QString ) ) ) ;
c o n n e c t ( Sensor , SIGNAL( Q u a l i t y ( QString ) ) , ui>Quality_Label , SLOT( s e t T e x t (
QString ) ) ) ;
29
// Read P e r i o d i c a l l y
31 c o n n e c t ( ui>R e a d P e r i o d i c a l l y , SIGNAL( c l i c k e d ( ) ) , t h i s , SLOT(
ReadPeriodically () ) ) ;

33 // Enable Diagnose Mode


c o n n e c t ( ui>EnableDiagMode , SIGNAL( c l i c k e d ( b o o l ) ) , Sensor , SLOT(
WriteDiagnoseMode ( b o o l ) ) ) ;

41
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

35 c o n n e c t ( Sensor , SIGNAL( DiagnoseMode ( b o o l ) ) , ui>DiagModeStatus , SLOT(


s e t C h ec k ed ( b o o l ) ) ) ;

37 // Read P r o f i l e P e r i o d i c a l l y
c o n n e c t ( ui>R e a d P r o f i l e , SIGNAL( c l i c k e d ( ) ) , Sensor , SLOT( R e a d P r o f i l e ( ) ) ) ;
39 c o n n e c t ( Sensor , SIGNAL( P r o f i l e R e a d y ( ) ) , Sensor , SLOT( R e a d P r o f i l e ( ) ) ) ;
c o n n e c t ( ui>spinBox , SIGNAL( valueChanged ( QString ) ) , Sensor , SLOT(
SampleNoChanged ( QString ) ) ) ;
41
// C l o s e Connection
43 c o n n e c t ( ui>STOP, SIGNAL( c l i c k e d ( ) ) , Sensor , SLOT( C l o s e C o n n e c t i o n ( ) ) ) ;

45 SensorThread>s t a r t ( ) ;
Listing 5.11. Signal-Slot Connections
These connections, connect user interface elements signals such as clicked() to a slot
in sensor object. Then it connects a relevant signal of sensor to a slot of user interface
element. For example a click on Connect button in user interface, will cause a request
to laser sensor device to remove its RS485 lock and upon successful operation, a check
will appear in user interface communication status checkbox. This concept is depicted on
figure 5.2 on page 35. After providing all connections, thread is started on line 45.

42
Chapter 6

Image Pre-Processing

In previous chapter, a Qt program developed to make use of communication interface


to perform acquisition and store received data in a file. In this chapter, two different
approaches are used to perform image pre-processing techniques. First approach is done
by MATLAB and second approach is designed with Qt C++ and help of OpenCV image
processing library.

6.1 MATLAB
In many similar cases, when the goal is to perform image processing techniques and have
OCR program, the starting point is to use MATLAB software because it offers many easy
to use functions which are already developed. In this section a .m program is analyzed
step by step to determine how does it work.

Step 1: Listing 6.1 represents a portion of code dedicated to open the data file, fill three
x,y and z vectors based on imported data and draw a 3D object to represent scanned
tire portion.
1 %Read measured data from data f i l e
f i l e n a m e = E : \ Education \ U n i v e r s i t y \MS\4 th S e m e s t e r \ T h e s i s \ V e r s i o n s \Qt\
v1 . 6 \ b u i l d DCRDesktop_Qt_5_6_0_MSVC2015_64bitDebug\ P r o f i l e s \
P r o f i l e D a t a . tpd ;
3 delimiterIn = \t ;
headerlinesIn = 1;
5 P r o f i l e = importdata ( filename , d e l i m i t e r I n , h e a d e r l i n e s I n ) ;

7 %S t o r e x , y , z c o m b i n a t i o n on x , y and z v e c t o r s
x=P r o f i l e . data ( : , 2 ) ;
9 y=P r o f i l e . data ( : , 1 ) ;
z=P r o f i l e . data ( : , 3 ) ;
11
p l o t 3 ( x , y , z , . )
13
t r i = de l a u na y ( x , y ) ;
15 plot (x , y , . )

43
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

17 [ r , c ] = size ( tri ) ;
disp ( r )
19
h = trisurf ( tri , x , y , z) ;
21 axis vis3d
axis off
23 l = l i g h t ( P o s i t i o n ,[ 50 15 2 9 ] ) ;
s e t ( gca , CameraPosition , [ 2 0 8 50 7 6 8 7 ] ) ;
25 l i g h t i n g phong
shading i n t e r p
27 c o l o r b a r EastOutside
Listing 6.1. Data file loading

As previously mentioned, in order to run this program again and again for different
newly scanned samples, file name points to "ProfileData.tpd". The ".tpd" extension
has been chosen to the courtesy of Tire Profiles company and stands for Tire Pro-
files Data. According to the previous convention about filling data file, it has one
row of column headers and values are separated by means of tabs. The code for
representing x,y and z vectors in 3D format, uses point by point drawing and then
changing the color based on corresponding z value. Figure 6.1 shows output of these
commands, As it is possible to observe the DOT code on tire is "DOT CN3R PY42".
On the right side of this figure, there is a bar showing corresponding color for
different distances. These distances are actually the distances between each point
and laser sensor. For example on right side of tire representation, color dedicated
to characters are less than background color in the sense that the corresponding
distance value is less than the same value for background. Which means the DOT
characters are closer to the laser sensor rather than the background.

Step 2: For further improvements on achieved results it is a good choice to store x,y
and z vectors inside a matrix called P such a way that x and y values are row and
column indices and z values are stored as matrix elements values. Listing 6.2 lists
all required MATLAB commands to transform x,y,z vectors to P matrix.
1 %Loading Measured data t o m atrix P
Yindex =0;
3 Xindex =0;
y v a l u e =1;
5 f o r i =1: l e n g t h ( x )
i f ( y ( i )==y v a l u e )
7 Xindex=Xindex +1;
else
9 Yindex=Yindex +1;
Xindex =1;
11 y v a l u e=y ( i ) ;
end
13 P( Yindex , Xindex )=z ( i ) ;
end
15

44
6 Image Pre-Processing

Figure 6.1. MATLAB Loading Raw Data File

% Removing z e r o e l e m e n t s from P r o f i l e matrix


17 f o r x=1: s i z e (P , 1 )
f o r y=1: s i z e (P , 2 )
19 i f (P( x , y )==0)
P( x , y )=P( x , y1) ;
21 end
end
23 end
f i g u r e , s u r f (P) , t i t l e ( 3D S u r f a c e R e p r e s e n t a t i o n )
Listing 6.2. Store Loaded Data into P Matrix

In this portion of code, one loop sweeps all x,y,z elements and fill P matrix accord-
ingly. Note that the value stored in x vector is not needed and only the sequence of
data is important. After filling P matrix based on x,y,z vectors, it is possible to have
zero elements in P because at time of acquisition sensor couldnt scan for example
400 points of a few lines. In such cases that are usually a result of functional criterion
limits trespassing, it is necessary to fill those zero elements with a neighbor non zero
element. When P matrix is completely built up and does not have zero elements
inside, surf function can make a better 3D surface representation like in figure 6.2.

45
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

Figure 6.2. MATLAB 3D Surface Representation

Step 3: As it is observable from 3D image, the acquisition is not perfect, in the sense that
sensor did not maintain a constant vertical distance to tire during scanning process.
To reduce effect of this matter, listing 6.3 lists a few simple commands to level the
3D model from one side.

f o r x=1: s i z e (P , 1 )
2 P( x , : ) =P( x , : ) (P( x , 1 )P ( 1 : 1 ) ) ;
end
4 P= f l i p l r (P) ;
f i g u r e , s u r f (P) , t i t l e ( 3D S u r f a c e R e p r e s e n t a t i o n L e v e l e d )
Listing 6.3. Leveled Model

In this code portion, all points of every single horizontal line are modified such a
way that the starting point of all lines have the same value. Figure 6.3 represents
the result of leveling process.

Step 4: Now that the 3D model is leveled, it is the time to scan for abrupt changes in the
model. The only way to recognize and the main reason behind using laser sensor
instead of camera is to find DOT code based on altitude changes instead of trying
to recognize it from a black on black pattern. Listing 6.4 summarizes all required
commands to find abrupt changes.

1 %% F i n d i n g maximum two c o n s e c u t i v e p o i n t s d i f f e r e n c e

46
6 Image Pre-Processing

Figure 6.3. Leveled Surface Representation

f o r y=1: s i z e (P , 2 )
3 MaxDeltaVector ( y ) =0;
f o r x=2: s i z e (P , 1 )
5 i f ( abs (P( x , y )P( x 1,y ) )>MaxDeltaVector ( y ) )
MaxDeltaVector ( y )=abs (P( x , y )P( x 1,y ) ) ;
7 end
end
9 end
MaxDelta=max( MaxDeltaVector ) ;
11
% F i n d i n g abrupt z change between two c o n s e c t u i v e p o i n t s ( r i g h t t o l e f t
)
13 f o r y=1: s i z e (P , 2 )
P1 ( 1 , y )=min (P ( : ) ) ;
15 P1 ( 2 , y )=min (P ( : ) ) ;
f o r x=3: s i z e (P , 1 )
17 ExpectedValue=2P( x 1,y )P( x 2,y ) ;
i f ( abs (P( x , y )ExpectedValue ) <0.3 MaxDelta )
19 P1 ( x , y )=min (P ( : ) ) ;
else
21 P1 ( x , y )=P( x , y ) ;
end
23 end
end
25
% F i n d i n g abrupt z change between two c o n s e c t u i v e p o i n t s ( l e f t t o r i g h t
)
27 f o r y=1: s i z e (P , 2 )

47
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

P1 ( end , y )=min (P ( : ) ) ;
29 P1 ( end 1 ,y )=min (P ( : ) ) ;
f o r x=s i z e (P , 1 ) 2: 1:1
31 ExpectedValue=2P( x+1 ,y )P( x+2 ,y ) ;
i f ( abs (P( x , y )ExpectedValue ) >0.3 MaxDelta && P1 ( x , y )==0)
33 P1 ( x , y )=P( x , y ) ;
end
35 end
end
37 f i g u r e , s u r f ( P1 ) , t i t l e ( Abrupt a l t i t u d e c h a n g e s i n 3D model )
Listing 6.4. Procedure to Find Abrupt Altitude Changes

This step works by finding the most variation between two consecutive points. This
value gives an order of expected variation. Its expected to have the most variations
in altitude where ever there is an edge of DOT code. At the rest of code, MATLAB
will try to find points that have a absolute consecutive change more than 0.3 times
of maximum abrupt changes. These points will be considered as potential edges.
This control process is executed twice, one from right to left and one from left to
right. All potentially important points are gathered in P1 matrix. Figre 6.4 shows
abrupt changes in 3D model, all other points have been changed to have altitude
equal to zero.

Figure 6.4. MATLAB 3D Model Abrupt Changes

Step 5: As its observable from previous step result, the algorithm has found only the
edges as it was intended to do. In order to have characters also included in the
segmented area, listing 6.5 contains the appropriate code to add a point to selected

48
6 Image Pre-Processing

points if there is an already selected point in its neighborhood with size of three
points.
1 % Adding n e i g h b o r p o i n t s t o c o l l e c t e d data
N e i g h b o r S i z e =3;
3 P2=P1 ;
f o r y=1+N e i g h b o r S i z e : s i z e (P , 2 )N e i g h b o r S i z e
5 f o r x=1+N e i g h b o r S i z e : s i z e (P , 1 )N e i g h b o r S i z e
f o r i=N e i g h b o r S i z e : N e i g h b o r S i z e
7 f o r j=N e i g h b o r S i z e : N e i g h b o r S i z e
i f ( P1 ( x+i , y+j )==P( x+i , y+j ) )
9 P2 ( x , y )=P( x , y ) ;
end
11 end
end
13 end
end
15 f i g u r e , s u r f ( P2 ) , t i t l e ( Added n e i g h b o u r s )
Listing 6.5. Adding Neighbors to Selected Points

This code uses four nested loops to check if a point has to be added to selected points
or not. In order to prevent from selecting all points, a new P2 matrix is filled based
on P1 matrix data.

Figure 6.5. MATLAB 3D Model Added Neighbors

Step 6: For image segmentation it is better to have the 3D model with miinmum value
equal to zero. In this simple step minimum value of matrix is decremented from all

49
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

points. Note that the minimum value is referred to the minimum value of all points
without considering points with zero value. Listing 6.6 lists these simple commands.
1 % Remove min v a l u e ( e x c e p t 0 )
P2=P2min ( P2 ( : ) ) ;
3 minvalue=i n f ;
f o r y=1: s i z e (P , 2 )
5 f o r x=1: s i z e (P , 1 )
i f ( P2 ( x , y ) ~=0 && P2 ( x , y )<minvalue )
7 minvalue=P2 ( x , y ) ;
end
9 end
end
11 f o r y=1: s i z e (P , 2 )
f o r x=1: s i z e (P , 1 )
13 i f ( P2 ( x , y ) ~=0)
P2 ( x , y )=P2 ( x , y )minvalue ;
15 end
end
17 end
f i g u r e , s u r f ( P2 ) , t i t l e ( Min Value Removed )
19 P=P2 ;
Listing 6.6. Removing Minimum Value (Except 0)

Figure 6.6 depicts the new 3D model which has zero minimum value. Comparison
may be made by considering the z axis numbers.

Figure 6.6. MATLAB 3D Model Removed Min Value

50
6 Image Pre-Processing

Step 7: Now that the 3D manipulation is made effectively by exploiting distance mea-
surement feature, it is possible to convert this 3D model to a normal 2D image to
perform some simple image pre-processing techniques. Listing 6.7 denotes required
commands to perform this important step.
1 % Image Segmentation
P=P ;
3 I = mat2gray (P) ;
mask = f a l s e ( s i z e ( I ) ) ;
5
f o r x=1: s i z e ( I , 1 )
7 f o r y=1: s i z e ( I , 2 )
i f (P( x , y ) >=0.9max(P ( : ) ) )
9 mask ( x , y )=t r u e ;
end
11 end
end
13
W = g r a y d i f f w e i g h t ( I , mask , G r a y D i f f e r e n c e C u t o f f , 2 5 ) ;
15 thresh = 0.01;
[BW, D] = imsegfmm (W, mask , t h r e s h ) ;
17 figure
imshow (BW)
19 t i t l e ( Segmented BW Image )

Listing 6.7. Image Black & White Segmentation

This step primarily uses a "mat2gray" function to just scale each matrix element value
to have a number between 0 and 255. "mask" variable is used to define a mask which
represents potential seeds of image segmentation. This binary matrix is filled with
ones for points with highest values (above 90%) and zeros for all remaining points.
"graydiffweight" uses the grayscale image and provided mask to calculate a weight
for pixels according to the difference between their value and masked point values.
At the end, "imgsegfmm" function performs segmentation based on the weighted
values, provided mask and a threshold which determines the border of black and
white. Figure 6.7 shows the result of this process.

Step 8: It seems that the code has selected the correct region that contains the DOT
code but with current black and white image it is not possible to perform OCR for
sure. So in this step, segmentation mask created by previous step is used to filter
original grayscale image obtained by beginning of previous step.
1 f o r x=1: s i z e ( I , 1 )
f o r y=1: s i z e ( I , 2 )
3 i f (BW( x , y )==f a l s e )
P( x , y ) =0;
5 end
end
7 end
I = mat2gray (P) ; f i g u r e , imshow ( I ) , t i t l e ( Segmented G r a y s c a l e Image )

51
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

Figure 6.7. Segmented Black & White Image

Listing 6.8. Image Grayscale Segmentation

This code uses BW image created by previous step to filter original P matrix. Figure
6.8 reveals grayscale segmented image which is quite promising.

Figure 6.8. Segmented Grayscale Image

Step 9: This image can be improved by means of contrast stretching. Listing 6.9 denotes
required commands one after the other.
%C o n t r a s t S t r e t c h i n g
2 P=Pmin (P(P>0) ) ;
P(P<0)=0;
4 P=P . 255/max(P ( : ) ) ;
I = mat2gray (P) ; f i g u r e , imshow ( I ) , t i t l e ( C o n t r a s t S t r e t c h e d Image ) ;

52
6 Image Pre-Processing

Listing 6.9. Contrast Stretching

This code guarantees to have minimum and maximum grayscale values by removing
minimum value and then stretch the gray value spectrum to 255. Figure 6.9 shows
improved constrast stretched image.

Figure 6.9. Contrast Stretched Image

Step 10: Since most of OCR techniques works best when the input image has black text
on white background, 6.10 denotes the simple method to find the negative image.
1 %Negate Image
P=255P ;
3 I = mat2gray (P) ; f i g u r e , imshow ( I ) , t i t l e ( N e g a t i v e Image ) ;
Listing 6.10. Negative Image

Finally, figure 6.10 shows the result of 10 consecutive steps for image pre-processing.

Figure 6.10. Negative Image

53
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

Although this image pre-processing is not perfect but it offers a good approach to make the
3D model clearer for image processing and specifically OCR. Anyway the thesis goal was
mainly to achieve a stable working condition for laser sensor communication and scanner
software acquisition.

6.2 Qt and Open-CV


In previous section, a 10 step pre-image processing algorithm introduced to use with MAT-
LAB program. Since the final program should be developed and deployed with Qt IDE,
although this was not a part of this thesis subject, author tried to implement a few ba-
sic pre-processing algorithms into the scanner Qt C++ software. In this way the field is
widely open for another engineers to expand and make use of it.
Open-CV is an open source computer vision library that supports various operating sys-
tems and programming languages. This flexibility is encouraging programmers to use this
library for their image processing applications. Qt and Open-CV can make a powerful
image processing software since both of them can deploy programs for different operating
systems.[13]
The new Qt software developed along with Open-CV libraries has one more class named
"ProfileProcessor". This class also is defined by files "profileprocessor.h" and "profilepro-
cessor.cpp". Listing 6.11 denotes public and private functions declared by this class.
1 public :
ProfileProcessor () ;
3 v o i d P r o c e s s ( QString P r o f i l e D a t a L o c a t i o n , QString
ConfigurationFileLocation ) ;
private :
5 v o i d L o a d P r o f i l e ( QString F i l e L o c a t i o n ) ;
v o i d ShowImage ( ) ;
7 void CorrectOrientation ( ) ;
void InvertColor ( ) ;
9 v o i d SharpenEdges ( ) ;
Listing 6.11. ProfileProcessor Functions

In this case there is no advantage to use slots over class functions because the processed
data by the profile processor object should be handled differently than just connecting
it to a user interface element slot. But for signals part, listing 6.12 shows two signals
declared by this class.
1 signals :
v o i d SendImage ( QPixmap Image ) ;
3 v o i d Sen dCurr entOp erati on ( QString Command) ;
Listing 6.12. ProfileProcessor Signals

SendImage and SendCurrentOperation signals, send an image and a descriptive string


respectively. This design is intended in order to make possible to have a good interface in
MainWindow object. Further information will be available later.
Listing F.1 describes the definition of process function of this class.

54
6 Image Pre-Processing

1 v o i d P r o f i l e P r o c e s s o r : : P r o c e s s ( QString P r o f i l e D a t a L o c a t i o n , QString
ConfigurationFileLocation )
{
3 QFile C o n f i g u r a t i o n ;
Configuration . setFileName ( C o n f i g u r a t i o n F i l e L o c a t i o n ) ;
5 C o n f i g u r a t i o n . open ( QIODevice : : ReadOnly ) ;
QTextStream C o n f i g u r a t i o n S t r e a m ;
7 C o n f i g u r a t i o n S t r e a m . s e t D e v i c e (& C o n f i g u r a t i o n ) ;
w h i l e ( ! C o n f i g u r a t i o n S t r e a m . atEnd ( ) )
9 {
QString A cti on=C o n f i g u r a t i o n S t r e a m . r e a d L i n e ( ) ;
11 i f ( Acti on . c o n t a i n s ( " Load F i l e " ) )
{
13 LoadProfile ( ProfileDataLocation ) ;
}
15 e l s e i f ( Act ion . c o n t a i n s ( " C o r r e c t O r i e n t a t i o n " ) )
{
17 CorrectOrientation () ;
}
19 e l s e i f ( Act ion . c o n t a i n s ( " I n v e r t C o l o r " ) )
{
21 InvertColor () ;
}
23 e l s e i f ( Act ion . c o n t a i n s ( " Sharpen Edges " ) )
{
25 SharpenEdges ( ) ;
}
27 }

29 Configuration . close () ;
ProfileMat . r e l e a s e () ;
31 ProfileData . close () ;

33 }
Listing 6.13. ProfileProcessor Process Function
This portion of code, defines that this function requires two arguments as inputs. One
is the location address of a profile data file and the other is the location address of a
configuration file. Profile data file is the same file that has been used to store acquisition
data while configuration file is a new input file which dictates to processor how to process
files. This new file may seems to make the system unnecessarily complex but this option is
intended to make it simpler. Sometimes when a utility software similar to this one is sold,
it happens that the system is no longer be able to perform its job. In most cases when
a technical support gets dispatched and checks the system, it comes up that the system
needs to reconfigure to adopt to the new situation. A change in situation may be caused
by even different illumination. So in this cases it is much easier to change a configuration
file instead of whole program. By the way, this function reads contents of configuration
file and decides what is the next action to take. After all actions are finished, it closes two
text files.
Now lets analyze four actions that have been already implemented.
LoadProfile

55
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

Listing 6.14 lists the required functions to load a profile data file.
1 v o i d P r o f i l e P r o c e s s o r : : L o a d P r o f i l e ( QString F i l e L o c a t i o n )
{
3 P r o f i l e D a t a . setFileName ( F i l e L o c a t i o n ) ;
P r o f i l e D a t a . open ( QIODevice : : ReadOnly ) ;
5 P r o f i l e S t r e a m . s e t D e v i c e (& P r o f i l e D a t a ) ;
i n t x , y , z , y o l d =0 , x i n d e x =1, y i n d e x =1;
7 i n t xindexmax =0 , yindexmax =0 ,zmax=0, zmin=s t d : : n u m e r i c _ l i m i t s <i n t > : :
max ( ) ;
QString ReadLine ;
9 QList <QString> S p l i t t e d D a t a ;

11 // Scan f i l e i n o r d e r t o f i n d t h e image d i m e n s i o n s
P r o f i l e S t r e a m . r e a d L i n e ( ) ; // F i r s t L i n e
13 P r o f i l e S t r e a m . r e a d L i n e ( ) ; // Second L i n e
w h i l e ( ! P r o f i l e S t r e a m . atEnd ( ) )
15 {
ReadLine=P r o f i l e S t r e a m . r e a d L i n e ( ) ;
17 S p l i t t e d D a t a=ReadLine . s p l i t ( " \ t " ) ;
y=S p l i t t e d D a t a . a t ( 0 ) . t o I n t ( ) ;
19 x=S p l i t t e d D a t a . a t ( 1 ) . t o I n t ( ) ;
z=S p l i t t e d D a t a . a t ( 2 ) . t o I n t ( ) ;
21 i f ( y!= y o l d )
{
23 y i n d e x++;
x i n d e x =1;
25 y o l d=y ;
}
27 x i n d e x++;
i f ( xindex>xindexmax ) xindexmax=x i n d e x ;
29 i f ( y>yindexmax ) yindexmax=y ;
i f ( z>zmax ) zmax=z ;
31 i f ( z<zmin ) zmin=z ;
}
33
// C r e a t e Mat o b j e c t based on image s i z e
35 P r o f i l e M a t= Mat : : z e r o s ( yindexmax +1 , xindexmax +1 ,CV_8UC1) ;

37 // Read f i l e a g a i n t o f i l l t h e Mat o b j e c t a c c o r d i n g l y
ProfileStream . seek (0) ;
39 P r o f i l e S t r e a m . r e a d L i n e ( ) ; // F i r s t L i n e
P r o f i l e S t r e a m . r e a d L i n e ( ) ; // Second L i n e
41 x i n d e x =1;
y i n d e x =1;
43 w h i l e ( ! P r o f i l e S t r e a m . atEnd ( ) )
{
45 ReadLine=P r o f i l e S t r e a m . r e a d L i n e ( ) ;
S p l i t t e d D a t a=ReadLine . s p l i t ( " \ t " ) ;
47 y=S p l i t t e d D a t a . a t ( 0 ) . t o I n t ( ) ;
x=S p l i t t e d D a t a . a t ( 1 ) . t o I n t ( ) ;
49 z=S p l i t t e d D a t a . a t ( 2 ) . t o I n t ( ) ;
i f ( y!= y o l d )
51 {
y i n d e x++;

56
6 Image Pre-Processing

53 x i n d e x =1;
y o l d=y ;
55 }
x i n d e x++;
57 i n t S c a l e d V a l u e =(( zzmin ) 2 5 4 / ( zmaxzmin ) ) +1;
P r o f i l e M a t . at<uchar >( yindex , x i n d e x )= S c a l e d V a l u e ;
59 }
// Check i f i t has z e r o v a l u e s
61 f o r ( y i n d e x =1; yindex<P r o f i l e M a t . rows ; y i n d e x++)
f o r ( x i n d e x =0; xindex<P r o f i l e M a t . c o l s ; x i n d e x++)
63 i f ( P r o f i l e M a t . at<uchar >( yindex , x i n d e x )==0)
{
65 P r o f i l e M a t . at<uchar >( yindex , x i n d e x )= P r o f i l e M a t . at<
uchar >( yindex 1 , x i n d e x ) ;
}
67 f o r ( y i n d e x=P r o f i l e M a t . rows 2; yindex >=0; yindex )
f o r ( x i n d e x=P r o f i l e M a t . c o l s 1; xindex >=0; xindex )
69 i f ( P r o f i l e M a t . at<uchar >( yindex , x i n d e x )==0)
{
71 P r o f i l e M a t . at<uchar >( yindex , x i n d e x )= P r o f i l e M a t . at<
uchar >( y i n d e x +1, x i n d e x ) ;
}
73 emit Se ndCur rentO perat ion ( " P r o f i l e Data Loaded " ) ;
ShowImage ( ) ;
75 }
Listing 6.14. ProfileProcessor Load Profile

The LoadProfile function primarily opens the data file and reads it line by line.
Two first lines are not important since they are dedicated to column headers. Then
it reads following lines and use the same method of MATLAB program to find
dimensions of P matrix. Open-CV uses a variable of type mat to store and work
with images. This variable dynamically allocates memory and release it when it is
not needed anymore. Copying mat objects by using a=b syntax does not copy the
data but it only copies the pointer. There is a specific function to copy also the
content of mat objects. in the first loop the function scans the file just to find the
appropriate dimensions of final mat object. After that at line 35, it creates a mat
object which is a matrix of appropriate dimensions and defines that the value of
this matrix elements is a single scalar and can be represented by 8 bits. This is the
method that Open-CV deals with grayscale images. Now that the matrix is created
and filled with zeros, its the time to restart reading data file and fill the mat object
accordingly. Same as MATLAB code it is possible to have zero elements inside the
matrix because sensor does not return same number of points for every acquisition,
so it is necessary to fill the zero elements with a neighbors value. Figure 6.11 depicts
the output of this stage.

According to obtained picture, it is necessary to rotate the image whenever its x


dimension is less than y dimension. Listing 6.15 lists the required command to
check and rotate image mat.

57
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

Figure 6.11. Open-CV Loaded File

1 void P r o f i l e P r o c e s s o r : : CorrectOrientation ( )
{
3 // Check i f i t i s n e c e s s a r y t o r o t a t e t h e image
i f ( P r o f i l e M a t . c o l s <P r o f i l e M a t . rows )
5 transpose ( ProfileMat , ProfileMat ) ;
emit Se ndCur rentO perat ion ( " O r i e n t a t i o n C o r r e c t e d " ) ;
7 ShowImage ( ) ;
}
Listing 6.15. ProfileProcessor Correct Orientation

This function and all others send the title of operation and also the image to "Main-
Window" by means of two signals. Figure 6.12 depicts the image with corrected
orientation.

Same as MATLABs procedure, next step is to invert colors. Listing 6.16 shows the
usage of "bitwise_not" command that is defined in Open-CV library.
void P r o f i l e P r o c e s s o r : : InvertColor ( )
2 {
bitwise_not ( ProfileMat , ProfileMat ) ;
4 emit Se ndCur rentO perat ion ( " C o l o r s I n v e r t e d " ) ;
ShowImage ( ) ;
6 }
Listing 6.16. ProfileProcessor Invert Colors

Figure 6.13 shows the result of color inversion.

58
6 Image Pre-Processing

Figure 6.12. Open-CV Orientation Corrected

Figure 6.13. Open-CV Colors Inverted

Sharpen edges action is a bit different from what was done in MATLAB procedure.
Listing 6.17 shows the steps of this action.
v o i d P r o f i l e P r o c e s s o r : : SharpenEdges ( )
2 {

4 G a u s s i a n B l u r ( P r o f i l e M a t , ProfileMatAux , S i z e ( 0 , 0 ) , 3 ) ;
addWeighted ( P r o f i l e M a t , 1 . 5 , ProfileMatAux , 0.5 , 0 , ProfileMatAux )
;

59
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

6 P r o f i l e M a t=ProfileMatAux ;
emit Se ndCur rentO perat ion ( " Edges Sharpened " ) ;
8 ShowImage ( ) ;
}
Listing 6.17. ProfileProcessor Sharpen Edges

This function finds a new image by applying Gaussian blur technique. Then this
blurred new image is deducted from original one with a half weight. The resulting
image is depicted on figure 6.14.

Figure 6.14. Open-CV Edges Sharpened

As previously mentioned all of these functions use a function to send the image
result. Listing 6.18 denotes the required commands to transform a mat object to a
QPixmap object so that Qt will be able to show it as a background image of a label.
1 v o i d P r o f i l e P r o c e s s o r : : ShowImage ( )
{
3 QThread : : msleep ( 2 0 0 ) ;
s t a t i c QVector<QRgb> s C o l o r T a b l e ;
5
// o n l y c r e a t e our c o l o r t a b l e once
7 i f ( s C o l o r T a b l e . isEmpty ( ) )
{
9 f o r ( i n t i = 0 ; i < 2 5 6 ; ++i )
s C o l o r T a b l e . push_back ( qRgb ( i , i , i ) ) ;
11 }

13 QImage ImageQImage ( P r o f i l e M a t . data , P r o f i l e M a t . c o l s , P r o f i l e M a t .


rows , P r o f i l e M a t . s t e p , QImage : : Format_Indexed8 ) ;
ImageQImage . s e t C o l o r T a b l e ( s C o l o r T a b l e ) ;

60
6 Image Pre-Processing

15
QPixmap ImageQPixmap = QPixmap : : fromImage ( ImageQImage ) ;
17 emit SendImage ( ImageQPixmap ) ;
}
Listing 6.18. ProfileProcessor ShowImage

ShowImage function creates a color table only once to map a single color value to
three values colors. This action is necessary since QImage objects needs to store
color data in RGB format. When the QImage object is created, it can be converted
to QPixmap object and sent to MainWindow.

These actions were the implemented ones in this thesis. Since the main focus of it
was on design and build of RS485 interface, other image processing actions were left for
future studies. The most important point is that this software created an infrastructure
for further completions which is easy to understand and interact.

61
62
Chapter 7

Conclusion

This thesis analyzed the importance of DOT code and created a device to make possible
the communication between a laser sensor and PC. It also developed different computer
programs to acquire and process data. In order to have the final device to be sold there
are still following works to be done.

A gyroscope should be added to this device to compensate sudden movements of


device otherwise the scanned data could be scrambled.

A cloud server should be procured and the corresponding program should be up-
loaded on it.

A wireless module should be added to system such a way that it interacts with
micro-controller and MAX485 on behalf of USB to Serial converter.

Further actions should be added to Qt plus Open-CV application. The substrate for
this addition has been already done. So this work will be fast.

A PC application should be developed to just receive the final answer of cloud which
is a DOT code and print it with its corresponding data on a paper. This application
needs socket programming.

Although this approach can be modified to have better and more accurate data, the
variable illumination (structured lighting) method will be much more accurate since in
this approach there is no need to move the device over tire and it can be done by hovering
the device on DOT code for less than a second.

63
64
Bibliography

[1] Michelin Company Canada, Reading A Tire Sidewall, available on-


line at <http://www.michelin.ca/tires-101/tire-basics/about-tires/
reading-your-sidewall.page>
[2] Leith Autopark Kia, September 2014, How To Check Your
Tire Tread for Wear. <http://blog.leithautoparkkia.com/
how-to-check-your-tire-tread-tires-raleigh/>
[3] Tire Profiles LLC, TreadSpec Documents. <http://www.tireprofiles.com/
treadspec/>
[4] Tire Profiles LLC, GrooveGlove Documents. <http://www.tireprofiles.com/
grooveglove/>
[5] TIRE TECH, Determining the Age of a Tire, available online at <http://www.
tirerack.com/tires/tiretech/techpage.jsp?techid=11>
[6] Baumer, BA OM70 MESAX multi-spot. <http://pfinder.baumer.com/pfinder_
sensor/downloads/Produkte/PDF/Allgemein/en_BA_RS485_MESAX_multi-spot_
Commands.pdf>
[7] Baumer, BA RS485 MESAX multi-spot commands,<http://pfinder.baumer.
com/pfinder_sensor/downloads/Produkte/PDF/Allgemein/en_BA_OM70_MESAX_
multi-spot.pdf>
[8] WIKIBOOKS, April 2016, Serial Programming/RS-485. <https://en.wikibooks.
org/wiki/Serial_Programming/RS-485>
[9] Atmel, ATmega16(L) datasheet, available online at <http://www.atmel.com/
images/doc2466.pdf>
[10] Maxminintegrated, MAX481 MAX483 MAX485 MAX487 MAX491 MAX1487,
available online at <https://datasheets.maximintegrated.com/en/ds/
MAX1487-MAX491.pdf>
[11] Prolific Technology Inc., PL-2303HXD Datasheet, available online at http://www.
prolific.com.tw/UserFiles/files/ds_pl2303HXD_v1_4_4.pdf>
[12] Nokia, Qt Documentation, available online at http://doc.qt.io/>
[13] OpenCV, Open Source Computer Vision v3.1.0, http://docs.opencv.org/3.1.0/
#gsc.tab=0>
[14] Kyung, C.M. ed., 2016. Theory and Applications of Smart Cameras. Springer Nether-
lands.

65
Appendices

66
Appendix A

Micro-controller C Code

#i n c l u d e <mega16 . h>
2 #i n c l u d e <d e l a y . h>
// D e c l a r e your g l o b a l v a r i a b l e s h e r e
4 int i ;
#d e f i n e DATA_REGISTER_EMPTY (1<<UDRE)
6 #d e f i n e RX_COMPLETE (1<<RXC)
#d e f i n e FRAMING_ERROR (1<<FE)
8 #d e f i n e PARITY_ERROR (1<<UPE)
#d e f i n e DATA_OVERRUN (1<<DOR)
10
// Get a c h a r a c t e r from t h e USART R e c e i v e r
12 #i f n d e f _DEBUG_TERMINAL_IO_
#d e f i n e _ALTERNATE_GETCHAR_
14 #pragma used+
char getchar ( void )
16 {
c h a r s t a t u s , data ;
18 while (1)
{
20 w h i l e ( ( ( s t a t u s=UCSRA) & RX_COMPLETE)==0) ;
data=UDR;
22 i f ( ( s t a t u s & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN) )==0)
r e t u r n data ;
24 }
}
26 #pragma used
#e n d i f
28
// Write a c h a r a c t e r t o t h e USART T r a n s m i t t e r
30 #i f n d e f _DEBUG_TERMINAL_IO_
#d e f i n e _ALTERNATE_PUTCHAR_
32 #pragma used+
void putchar ( char c )
34 {
w h i l e ( (UCSRA & DATA_REGISTER_EMPTY)==0) ;
36 UDR=c ;
}
38 #pragma used

67
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

#e n d i f
40
// Standard Input / Output f u n c t i o n s
42 #i n c l u d e <s t d i o . h>

44 v o i d main ( v o i d )
{
46 // D e c l a r e your l o c a l v a r i a b l e s h e r e
c h a r ch , cr , cn ;
48
// I np u t / Output P o r t s i n i t i a l i z a t i o n
50 // Port A i n i t i a l i z a t i o n
// Fu nction : B i t 7=In B i t 6=In B i t 5=In B i t 4=In B i t 3=In B i t 2=In B i t 1=In B i t 0=In
52 DDRA=(0<<DDA7) | (0<<DDA6) | (0<<DDA5) | (0<<DDA4) | (0<<DDA3) | (0<<DDA2) |
(0<<DDA1) | (0<<DDA0) ;
// S t a t e : B i t 7=T B i t 6=T B i t 5=T B i t 4=T B i t 3=T B i t 2=T B i t 1=T B i t 0=T
54 PORTA=(0<<PORTA7) | (0<<PORTA6) | (0<<PORTA5) | (0<<PORTA4) | (0<<PORTA3) |
(0<<PORTA2) | (0<<PORTA1) | (0<<PORTA0) ;

56 // Port B i n i t i a l i z a t i o n
// Fu nction : B i t 7=In B i t 6=In B i t 5=In B i t 4=In B i t 3=In B i t 2=In B i t 1=In B i t 0=In
58 DDRB=(0<<DDB7) | (0<<DDB6) | (0<<DDB5) | (0<<DDB4) | (0<<DDB3) | (0<<DDB2) |
(0<<DDB1) | (0<<DDB0) ;
// S t a t e : B i t 7=T B i t 6=T B i t 5=T B i t 4=T B i t 3=T B i t 2=T B i t 1=T B i t 0=T
60 PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) |
(0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0) ;

62 // Port C i n i t i a l i z a t i o n
// Fu nction : B i t 7=In B i t 6=In B i t 5=In B i t 4=In B i t 3=In B i t 2=In B i t 1=In B i t 0=In
64 DDRC=(0<<DDC7) | (0<<DDC6) | (0<<DDC5) | (0<<DDC4) | (0<<DDC3) | (0<<DDC2) |
(0<<DDC1) | (0<<DDC0) ;
// S t a t e : B i t 7=T B i t 6=T B i t 5=T B i t 4=T B i t 3=T B i t 2=T B i t 1=T B i t 0=T
66 PORTC=(0<<PORTC7) | (0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) |
(0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0) ;

68 // Port D i n i t i a l i z a t i o n
// Fu nction : B i t 7=In B i t 6=Out B i t 5=In B i t 4=In B i t 3=In B i t 2=In B i t 1=In B i t 0=
In
70 DDRD=(0<<DDD7) | (1<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) |
(0<<DDD1) | (0<<DDD0) ;
// S t a t e : B i t 7=T B i t 6=0 B i t 5=T B i t 4=T B i t 3=T B i t 2=T B i t 1=T B i t 0=T
72 PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) |
(0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0) ;

74 // Timer / Counter 0 i n i t i a l i z a t i o n
// Clock s o u r c e : System Clock
76 // Clock v a l u e : Timer 0 Stopped
// Mode : Normal top=0xFF
78 // OC0 output : D i s c o n n e c t e d
TCCR0=(0<<WGM00) | (0<<COM01) | (0<<COM00) | (0<<WGM01) | (0<<CS02 ) | (0<<
CS01 ) | (0<<CS00 ) ;
80 TCNT0=0x00 ;
OCR0=0x00 ;
82

68
A Micro-controller C Code

// Timer / Counter 1 i n i t i a l i z a t i o n
84 // Clock s o u r c e : System Clock
// Clock v a l u e : Timer1 Stopped
86 // Mode : Normal top=0xFFFF
// OC1A output : D i s c o n n e c t e d
88 // OC1B output : D i s c o n n e c t e d
// N o i s e C a n c e l e r : O f f
90 // I np u t Capture on F a l l i n g Edge
// Timer1 Overflow I n t e r r u p t : O f f
92 // I np u t Capture I n t e r r u p t : O f f
// Compare A Match I n t e r r u p t : O f f
94 // Compare B Match I n t e r r u p t : O f f
TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) |
(0<<WGM10) ;
96 TCCR1B=(0<<ICNC1) | (0<<ICES1 ) | (0<<WGM13) | (0<<WGM12) | (0<<CS12 ) | (0<<
CS11 ) | (0<<CS10 ) ;
TCNT1H=0x00 ;
98 TCNT1L=0x00 ;
ICR1H=0x00 ;
100 ICR1L=0x00 ;
OCR1AH=0x00 ;
102 OCR1AL=0x00 ;
OCR1BH=0x00 ;
104 OCR1BL=0x00 ;

106 // Timer / Counter 2 i n i t i a l i z a t i o n


// Clock s o u r c e : System Clock
108 // Clock v a l u e : Timer2 Stopped
// Mode : Normal top=0xFF
110 // OC2 output : D i s c o n n e c t e d
ASSR=0<<AS2 ;
112 TCCR2=(0<<PWM2) | (0<<COM21) | (0<<COM20) | (0<<CTC2) | (0<<CS22 ) | (0<<CS21
) | (0<<CS20 ) ;
TCNT2=0x00 ;
114 OCR2=0x00 ;

116 // Timer ( s ) / Counter ( s ) I n t e r r u p t ( s ) i n i t i a l i z a t i o n


TIMSK=(0<<OCIE2 ) | (0<<TOIE2 ) | (0<<TICIE1 ) | (0<<OCIE1A) | (0<<OCIE1B) |
(0<<TOIE1 ) | (0<<OCIE0 ) | (0<<TOIE0 ) ;
118
// E x t e r n a l I n t e r r u p t ( s ) i n i t i a l i z a t i o n
120 // INT0 : O f f
// INT1 : O f f
122 // INT2 : O f f
MCUCR=(0<<ISC11 ) | (0<<ISC10 ) | (0<<ISC01 ) | (0<<ISC00 ) ;
124 MCUCSR=(0<<ISC2 ) ;

126 // USART i n i t i a l i z a t i o n
// Communication Parameters : 8 Data , 1 Stop , Even P a r i t y
128 // USART R e c e i v e r : On
// USART T r a n s m i t t e r : On
130 // USART Mode : Asynchronous
// USART Baud Rate : 57600

69
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

132 UCSRA=(0<<RXC) | (0<<TXC) | (0<<UDRE) | (0<<FE) | (0<<DOR) | (0<<UPE) | (0<<


U2X) | (0<<MPCM) ;
UCSRB=(0<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (1<<RXEN) | (1<<TXEN) | (0<<
UCSZ2) | (0<<RXB8) | (0<<TXB8) ;
134 UCSRC=(1<<URSEL) | (0<<UMSEL) | (1<<UPM1) | (0<<UPM0) | (0<<USBS) | (1<<
UCSZ1) | (1<<UCSZ0) | (0<<UCPOL) ;
UBRRH=0x00 ;
136 UBRRL=0x0B ;

138 // Analog Comparator i n i t i a l i z a t i o n


// Analog Comparator : O f f
140 // The Analog Comparator s p o s i t i v e i n p u t i s
// c o n n e c t e d t o t h e AIN0 p i n
142 // The Analog Comparator s n e g a t i v e i n p u t i s
// c o n n e c t e d t o t h e AIN1 p i n
144 ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) |
(0<<ACIS1 ) | (0<<ACIS0 ) ;
SFIOR=(0<<ACME) ;
146
// ADC i n i t i a l i z a t i o n
148 // ADC d i s a b l e d
ADCSRA=(0<<ADEN) | (0<<ADSC) | (0<<ADATE) | (0<<ADIF) | (0<<ADIE) | (0<<
ADPS2) | (0<<ADPS1) | (0<<ADPS0) ;
150
// SPI i n i t i a l i z a t i o n
152 // SPI d i s a b l e d
SPCR=(0<<SPIE ) | (0<<SPE) | (0<<DORD) | (0<<MSTR) | (0<<CPOL) | (0<<CPHA) |
(0<<SPR1) | (0<<SPR0) ;
154
// TWI i n i t i a l i z a t i o n
156 // TWI d i s a b l e d
TWCR=(0<<TWEA) | (0<<TWSTA) | (0<<TWSTO) | (0<<TWEN) | (0<<TWIE) ;
158
PORTD. 6 = 1 ;
160 c r=0x0D ;
cn=0x0A ;
162 delay_ms ( 2 0 0 0 ) ;
p r i n t f ( " : 0 1 W010 ; 0 ; %c%c " , cr , cn ) ;
164 delay_ms ( 1 0 0 ) ;
p r i n t f ( " : 0 1 W006 ; 2 ; %c%c " , cr , cn ) ;
166 delay_ms ( 1 0 0 ) ;
UBRRL=0x05 ;
168 // w h i l e ( 1 )
// {
170 // p r i n t f ( " : 0 1 R001 ; %c%c " , cr , cn ) ;
// delay_ms ( 5 0 0 ) ;
172 // }

174 while (1)


{
176 // P l a c e your code h e r e
ch=g e t c h a r ( ) ;
178 i f ( ch== : )
{

70
A Micro-controller C Code

180 PORTD. 6 = 1 ;
p u t c h a r ( ch ) ;
182 }
else i f ( ch==0x0B )
184 {
// p u t c h a r ( ch ) ;
186 f o r ( i =0; i <100; i ++) ;
PORTD. 6 = 0 ;
188 }
else
190 p u t c h a r ( ch ) ;
}
192 }

71
Appendix B

Laser Sensor Header Code

#i f n d e f LASERSENSOR_H
2 #d e f i n e LASERSENSOR_H

4 #i n c l u d e <Q t S e r i a l P o r t >
#i n c l u d e <QString>
6
c l a s s L a s e r S e n s o r : p u b l i c QObject
8 {
Q_OBJECT
10

12 public :
L a s e r S e n s o r ( ) ; // C o n s t r u c t o r
14 ~LaserSensor () ;

16 private slots :
void ReadProfile ( ) ;
18 v o i d F i n d A v a i l a b l e P o r t s ( ) ; // S e a r c h e s f o r a l l a v a i l a b l e COM p o r t s
v o i d I n i t C o n n e c t i o n ( QString PORTName) ; // I n i t i a t e s t h e c o n n e c t i o n
20 v o i d CheckConnection ( ) ; // Checks f o r c o n n e c t i o n p r e s e n c e
v o i d R e a d A p p l i c a t i o n E r r o r ( ) ; // Reads a p p l i c a t i o n e r r o r code
22 v o i d ReadVendorInfo ( ) ;
void ReadDeviceInfo ( ) ;
24 v o i d ReadBusAddress ( ) ;
v o i d WriteBusAddress ( i n t BusAddressValue ) ;
26 v o i d ReadBaudRate ( ) ;
v o i d WriteBaudRate ( i n t S e l e c t ) ;
28 v o i d ReadRS485Lock ( ) ;
v o i d WriteRS485Lock ( b o o l Switch ) ;
30 v o i d ReadTouchButtonLock ( ) ;
v o i d WriteTouchButtonLock ( b o o l Switch ) ;
32 v o i d ReadMeasurementType ( ) ;
v o i d WriteMeasurementType ( i n t S e l e c t ) ;
34 v o i d ReadMeasurementValue ( ) ;
v o i d ReadAllMeasurementValues ( ) ;
36 v o i d ReadFieldOfView ( ) ;
v o i d WriteFieldOfView ( i n t L i m i t L e f t , i n t L i m i t R i g h t ) ;
38 v o i d WriteFiledOfViewToMax ( ) ;

72
B Laser Sensor Header Code

void ReadObjectType ( ) ;
40 void WriteObjectType ( b o o l Switch ) ;
void ReadPrecision () ;
42 void WritePrecision ( int Select ) ;
void ReadLaserOffDataHold ( ) ;
44 void WriteLaserOffDataHold ( b o o l Switch ) ;
void ReadFlexMountEnable ( ) ;
46 void WriteFlexMountEnable ( b o o l Switch ) ;
void ReadSetFlexMount ( ) ;
48 void WriteSetFlexMount ( f l o a t Angle , f l o a t D i s t a n c e ) ;
void WriteTeachFlexMountCommand ( f l o a t R e f e r e n c e T h i c k n e s s ) ;
50 void ReadDiagnoseMode ( ) ;
void WriteDiagnoseMode ( b o o l Switch ) ;
52 void WriteStoreConfigurationCommand ( i n t C o n f i g ) ;
void WriteResetToFactorySettingsCommand ( i n t Command) ;
54 void SampleNoChanged ( QString SampleNumber ) ;
void CloseConnection ( ) ;
56
signals :
58 void A v a i l a b l e P o r t s ( i n t TotalNumber , QVector<QString> P o r t s ) ; // S e a r c h e s
for a l l a v a i l a b l e COM p o r t s
void ConnectionStatus ( bool Status ) ;
60 void A p p l i c a t i o n E r r o r ( i n t A p p l i c a t i o n E r r o r ) ; // Reads a p p l i c a t i o n e r r o r
code
void VendorID ( i n t Vendor_ID ) ;
62 void VendorName ( QString Vendor_Name ) ;
void DeviceID ( i n t Device_ID ) ;
64 void VariantID ( i n t Variant_ID ) ;
void SensorType ( QString Sensor_Type ) ;
66 void SerialNumber ( QString Serial_Number ) ;
void BusAddress ( i n t BusAddressValue ) ;
68 void BaudRate ( i n t BuadRateValue ) ;
void RS485Lock ( b o o l Switch ) ;
70 void TouchButtonLock ( b o o l Switch ) ;
void MeasurementType ( QString Type ) ;
72 void MeasurementValue ( f l o a t MeasurementValue , QString Q u a l i t y ) ;
void Average ( QString a v e r a g e ) ;
74 void Max ( QString max) ;
void Min ( QString min ) ;
76 void D e l t a ( QString d e l t a ) ;
void S t a n d a r d D e v i a t i o n ( QString s t a n d a r d d e v i a t i o n ) ;
78 void Q u a l i t y ( QString q u a l i t y ) ;
void FieldOfView ( i n t L i m i t L e f t , i n t L i m i t R i g h t ) ;
80 void ObjectType ( QString ObjectType ) ;
void P r e c i s i o n ( QString P r e c i s i o n ) ;
82 void LaserOffDataHold ( b o o l Switch ) ;
void FlexMountEnable ( b o o l Switch ) ;
84 void SetFlexMount ( f l o a t Angle , f l o a t D i s t a n c e ) ;
void DiagnoseModeEnabled ( ) ;
86 void P r o f i l e ( i n t Xpos [ 3 0 0 ] , i n t Zpos [ 3 0 0 ] ) ;
void SensorTimedOut ( b o o l Switch ) ;
88 void ProfileReady () ;

90 private :

73
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

bool ReceiveResponse ( ) ;
92 v o i d SendCommand ( QString Command) ;
QString CRCMake( QString Command) ;
94 QSerialPort s e r i a l ;
i n t DeviceAddress ;
96 QString Response ;
Q S t r i n g L i s t Payloads ;
98 QFile P r o f i l e D a t a ;
QTextStream P r o f i l e S t r e a m ;
100 QFile P r o f i l e D a t a 1 ;
QTextStream P r o f i l e S t r e a m 1 ;
102 QString SampleNo ;
i n t Yindex ;
104 bool f i l e c r e a t e d ;
};
106

108 #e n d i f // LASERSENSOR_H

74
Appendix C

Laser Sensor C++ Code

#i n c l u d e " l a s e r s e n s o r . h "
2
LaserSensor : : LaserSensor ()
4 {
qRegisterMetaType<QVector<QString> >( " QVector<QString>" ) ;
6 s e r i a l = new Q S e r i a l P o r t ( t h i s ) ;
s e r i a l >setBaudRate ( Q S e r i a l P o r t : : Baud115200 ) ;
8 s e r i a l >s e t D a t a B i t s ( Q S e r i a l P o r t : : Data8 ) ;
s e r i a l >s e t P a r i t y ( Q S e r i a l P o r t : : EvenParity ) ;
10 s e r i a l >s e t S t o p B i t s ( Q S e r i a l P o r t : : OneStop ) ;
s e r i a l >s e t F l o w C o n t r o l ( Q S e r i a l P o r t : : NoFlowControl ) ;
12 D e v i c e A d d r e s s =1;
Yindex =0;
14 f i l e c r e a t e d=f a l s e ;
SampleNo=" 1 " ;
16 }

18 void LaserSensor : : FindAvailablePorts ( )


{
20 i n t TotalNumber =0;
QVector<QString> P o r t s ( 0 ) ;
22 f o r e a c h ( c o n s t Q S e r i a l P o r t I n f o &i n f o , Q S e r i a l P o r t I n f o : : a v a i l a b l e P o r t s ( ) )
{
24 i f ( ! i n f o . isBusy ( ) )
{
26 P o r t s . append ( i n f o . portName ( ) ) ;
TotalNumber++;
28 }
}
30 emit A v a i l a b l e P o r t s ( TotalNumber , P o r t s ) ;
}
32
v o i d L a s e r S e n s o r : : I n i t C o n n e c t i o n ( QString PORTName)
34 {
s e r i a l >setPortName (PORTName) ;
36 s e r i a l >open ( QIODevice : : ReadWrite ) ;
i f ( s e r i a l >isOpen ( ) && s e r i a l >i s W r i t a b l e ( ) )
38 emit C o n n e c t i o n S t a t u s ( t r u e ) ;

75
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

else
40 {
emit C o n n e c t i o n S t a t u s ( f a l s e ) ;
42 }
SendCommand ( "W010 ; 0 " ) ;
44 ReceiveResponse ( ) ;
}
46
v o i d L a s e r S e n s o r : : CheckConnection ( )
48 {

50 }

52 void LaserSensor : : ReadApplicationError ( )


{
54
}
56
v o i d L a s e r S e n s o r : : ReadVendorInfo ( )
58 {
SendCommand ( " R001 " ) ;
60 i f ( ReceiveResponse ( ) )
{
62 emit VendorID ( Payloads [ 1 ] . t o I n t ( ) ) ;
emit VendorName ( Payloads [ 2 ] ) ;
64 }

66 }

68 void LaserSensor : : ReadDeviceInfo ( )


{
70 SendCommand ( " R002 " ) ;
i f ( ReceiveResponse ( ) )
72 {
emit DeviceID ( Payloads [ 1 ] . t o I n t ( ) ) ;
74 emit VariantID ( Payloads [ 2 ] . t o I n t ( ) ) ;
emit SensorType ( Payloads [ 3 ] ) ;
76 emit SerialNumber ( Payloads [ 4 ] ) ;
}
78 }

80 v o i d L a s e r S e n s o r : : ReadBusAddress ( )
{
82
}
84
v o i d L a s e r S e n s o r : : WriteBusAddress ( i n t BusAddressValue )
86 {

88 }

90 v o i d L a s e r S e n s o r : : ReadBaudRate ( )
{
92

76
C Laser Sensor C++ Code

}
94
v o i d L a s e r S e n s o r : : WriteBaudRate ( i n t S e l e c t )
96 {

98 }

100 v o i d L a s e r S e n s o r : : ReadRS485Lock ( )
{
102
}
104
v o i d L a s e r S e n s o r : : WriteRS485Lock ( b o o l Switch )
106 {

108 }

110 v o i d L a s e r S e n s o r : : ReadTouchButtonLock ( )
{
112
}
114
v o i d L a s e r S e n s o r : : WriteTouchButtonLock ( b o o l Switch )
116 {

118 }

120 v o i d L a s e r S e n s o r : : ReadMeasurementType ( )
{
122
}
124
v o i d L a s e r S e n s o r : : WriteMeasurementType ( i n t S e l e c t )
126 {

128 }

130 v o i d L a s e r S e n s o r : : ReadMeasurementValue ( )
{
132
}
134
v o i d L a s e r S e n s o r : : ReadAllMeasurementValues ( )
136 {
SendCommand ( " R022 " ) ;
138 i f ( ReceiveResponse ( ) )
{
140 emit Average ( Payloads [ 1 ] ) ;
emit Max( Payloads [ 2 ] ) ;
142 emit Min ( Payloads [ 3 ] ) ;
emit D e l t a ( Payloads [ 4 ] ) ;
144 emit S t a n d a r d D e v i a t i o n ( Payloads [ 5 ] ) ;
emit Q u a l i t y ( Payloads [ 6 ] ) ;
146 }

77
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

}
148
v o i d L a s e r S e n s o r : : ReadFieldOfView ( )
150 {

152 }

154 v o i d L a s e r S e n s o r : : WriteFieldOfView ( i n t L i m i t L e f t , i n t L i m i t R i g h t )
{
156
}
158
v o i d L a s e r S e n s o r : : WriteFiledOfViewToMax ( )
160 {

162 }

164 v o i d L a s e r S e n s o r : : ReadObjectType ( )
{
166
}
168
v o i d L a s e r S e n s o r : : WriteObjectType ( b o o l Switch )
170 {

172 }

174 void LaserSensor : : ReadPrecision ( )


{
176
}
178
void LaserSensor : : WritePrecision ( i n t S e l e c t )
180 {

182 }

184 v o i d L a s e r S e n s o r : : ReadLaserOffDataHold ( )
{
186
}
188
v o i d L a s e r S e n s o r : : WriteLaserOffDataHold ( b o o l Switch )
190 {

192 }

194 v o i d L a s e r S e n s o r : : ReadFlexMountEnable ( )
{
196
}
198
v o i d L a s e r S e n s o r : : WriteFlexMountEnable ( b o o l Switch )
200 {

78
C Laser Sensor C++ Code

202 }

204 v o i d L a s e r S e n s o r : : ReadSetFlexMount ( )
{
206
}
208
v o i d L a s e r S e n s o r : : WriteSetFlexMount ( f l o a t Angle , f l o a t D i s t a n c e )
210 {

212 }

214 v o i d L a s e r S e n s o r : : WriteTeachFlexMountCommand ( f l o a t R e f e r e n c e T h i c k n e s s )
{
216
}
218
v o i d L a s e r S e n s o r : : ReadDiagnoseMode ( )
220 {

222 }

224 v o i d L a s e r S e n s o r : : WriteDiagnoseMode ( b o o l Switch )


{
226 //SendCommand ( " W032 ; 1 " ) ;
// R e c e i v e R e s p o n s e ( ) ;
228 //SendCommand ( " W020 ; 1 0 " ) ;
// R e c e i v e R e s p o n s e ( ) ;
230 SendCommand ( "W030; 20;20 " ) ;
ReceiveResponse ( ) ;
232 SendCommand ( " R030 " ) ;
ReceiveResponse ( ) ;
234 SendCommand ( "W050 ; 1 " ) ;
i f ( ReceiveResponse ( ) )
236 {
emit DiagnoseModeEnabled ( ) ;
238 }
}
240
void LaserSensor : : ReadProfile ( )
242 {
if (! filecreated )
244 {
QDateTime c u r r e n t d a t e a n d t i m e = QDateTime : : currentDateTime ( ) ;
246 i f ( ! QDir ( " P r o f i l e s " ) . e x i s t s ( ) )
QDir ( ) . mkdir ( " P r o f i l e s " ) ;
248 P r o f i l e D a t a . s e t F i l e N a m e ( QDir : : c u r r e n t P a t h ( )+" / P r o f i l e s /
P r o f ile Data_ Samp le "+SampleNo+"_"+ c u r r e n t d a t e a n d t i m e . t o S t r i n g ( " yyyyMM
dd_hhmms s " )+" . tpd " ) ;
P r o f i l e D a t a . open ( QIODevice : : WriteOnly ) ;
250 P r o f i l e D a t a 1 . s e t F i l e N a m e ( QDir : : c u r r e n t P a t h ( )+" / P r o f i l e s / P r o f i l e D a t a .
tpd " ) ;
P r o f i l e D a t a 1 . open ( QIODevice : : WriteOnly ) ;

79
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

252 P r o f i l e S t r e a m . s e t D e v i c e (& P r o f i l e D a t a ) ;
P r o f i l e S t r e a m << "Y\tX\ t \Z " <<e n d l <<e n d l ;
254 P r o f i l e S t r e a m 1 . s e t D e v i c e (& P r o f i l e D a t a 1 ) ;
P r o f i l e S t r e a m 1 << "Y\tX\ t \Z " <<e n d l <<e n d l ;
256 f i l e c r e a t e d=t r u e ;
}
258 SendCommand ( " R052 " ) ;
i f ( ReceiveResponse ( ) )
260 {
i f ( Payloads [ 0 ] . c o n t a i n s ( "A" ) )
262 {
Q S t r i n g L i s t XZMeasurements ;
264 XZMeasurements=Payloads [ 2 ] . s p l i t ( " " ) ;
i n t TotalMeasurements=XZMeasurements [ 0 ] . t o I n t ( ) ;
266 XZMeasurements . r e m o v e F i r s t ( ) ;
Yindex++;
268 f o r ( i n t i =0; i <TotalMeasurements / 2 ; i ++)
{
270 P r o f i l e S t r e a m << Yindex <<" \ t " << XZMeasurements [ 2 i ] <<" \ t "
<<XZMeasurements [ 2 i +1] <<e n d l ;
P r o f i l e S t r e a m 1 << Yindex <<" \ t " << XZMeasurements [ 2 i ] <<" \ t
" <<XZMeasurements [ 2 i +1] <<e n d l ;
272 }
emit P r o f i l e R e a d y ( ) ;
274 }
else
276 {
qDebug ( )<<" E r r o r Handling "<<Payloads [ 0 ] ;
278 i f ( Payloads [1]== " 7 " )
WriteDiagnoseMode ( t r u e ) ;
280 else
ReadProfile () ;
282 }
}
284 else
emit P r o f i l e R e a d y ( ) ;
286 }

288 v o i d L a s e r S e n s o r : : WriteStoreConfigurationCommand ( i n t C o n f i g )
{
290
}
292
v o i d L a s e r S e n s o r : : WriteResetToFactorySettingsCommand ( i n t Command)
294 {

296 }

298 void LaserSensor : : CloseConnection ( )


{
300 Yindex =0;
ProfileData . close () ;
302 ProfileData1 . close () ;
f i l e c r e a t e d=f a l s e ;

80
C Laser Sensor C++ Code

304 }

306 v o i d L a s e r S e n s o r : : SendCommand ( QString Command)


{
308 QChar c r=0x0D ;
QChar cn=0x0A ;
310 QChar s t o p c h a r=0x0B ;
QString ToSend=" : " ;
312 ToSend . append ( QString ( "%1" ) . a r g ( DeviceAddress , 2 , 1 0 , QChar ( 0 ) ) ) ;
ToSend . append (Command) ;
314 ToSend . append ( " ; " ) ;
ToSend . append ( " " ) ;
316 ToSend . append ( c r ) ;
ToSend . append ( cn ) ;
318 ToSend . append ( s t o p c h a r ) ;
s e r i a l >w r i t e ( ToSend . t o L a t i n 1 ( ) ) ;
320
}
322
QString L a s e r S e n s o r : : CRCMake( QString Command)
324 {
QString s t r=" " ;
326 return str ;
}
328
bool LaserSensor : : ReceiveResponse ( )
330 {
QChar cn=0x0A ;
332 Response . c l e a r ( ) ;
b o o l C o m p l e t e l y R e c e i v e d=f a l s e ;
334 while ( ! CompletelyReceived )
{
336 i f ( s e r i a l >waitForReadyRead ( 2 0 0 ) )
{
338 Response . append ( s e r i a l >r e a d A l l ( ) ) ;
qDebug ( ) << Response ;
340 i f ( Response . c o n t a i n s ( cn ) ) C o m p l e t e l y R e c e i v e d=t r u e ;
}
342 else
{
344 return f a l s e ;
}
346 }
qDebug ( ) << Response ;
348 Payloads=Response . s p l i t ( " ; " ) ;
// Payloads . r e m o v e F i r s t ( ) ;
350 return true ;
}
352
LaserSensor : : ~ LaserSensor ()
354 {
s e r i a l >c l o s e ( ) ;
356 }

81
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

358 v o i d L a s e r S e n s o r : : SampleNoChanged ( QString SampleNumber )


{
360 SampleNo=SampleNumber ;
}

82
Appendix D

Profile Processer MATLAB Code

1 clc
clear
3 close all

5 %Read measured data from data f i l e


f i l e n a m e = E : \ Education \ U n i v e r s i t y \MS\4 th S e m e s t e r \ T h e s i s \ V e r s i o n s \Qt\ v1 . 6 \
b u i l d DCRDesktop_Qt_5_6_0_MSVC2015_64bitDebug\ P r o f i l e s \ P r o f i l e D a t a . tpd
;
7 delimiterIn = \t ;
headerlinesIn = 1;
9 P r o f i l e = importdata ( filename , d e l i m i t e r I n , h e a d e r l i n e s I n ) ;

11 %S t o r e x , y , z c o m b i n a t i o n on x , y and z v e c t o r s
x=P r o f i l e . data ( : , 2 ) ;
13 y=P r o f i l e . data ( : , 1 ) ;
z=P r o f i l e . data ( : , 3 ) ;
15
p l o t 3 ( x , y , z , . )
17
t r i = d e l a u na y ( x , y ) ;
19 plot (x , y , . )

21 [ r , c ] = size ( tri ) ;
disp ( r )
23
h = trisurf ( tri , x , y , z) ;
25 axis vis3d
axis off
27 l = l i g h t ( P o s i t i o n ,[ 50 15 2 9 ] ) ;
s e t ( gca , CameraPosition , [ 2 0 8 50 7 6 8 7 ] ) ;
29 l i g h t i n g phong
shading i n t e r p
31 c o l o r b a r EastOutside

33 %Loading Measured data t o matrix P


Yindex =0;
35 Xindex =0;
y v a l u e =1;

83
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

37 f o r i =1: l e n g t h ( x )
i f ( y ( i )==y v a l u e )
39 Xindex=Xindex +1;
else
41 Yindex=Yindex +1;
Xindex =1;
43 y v a l u e=y ( i ) ;
end
45 P( Yindex , Xindex )=z ( i ) ;
end
47
% Removing z e r o e l e m e n t s from P r o f i l e matrix
49 f o r x =1: s i z e (P , 1 )
f o r y=1: s i z e (P , 2 )
51 i f (P( x , y )==0)
P( x , y )=P( x , y1) ;
53 end
end
55 end
f i g u r e , s u r f (P) , t i t l e ( 3D S u r f a c e R e p r e s e n t a t i o n )
57

59
%%
61 % f o r y =1: s i z e (P , 2 )
% P ( : , y )=P ( : , y )mean (P ( : , y ) )+mean (P ( : ) ) ;
63 % end
f o r x =1: s i z e (P , 1 )
65 P( x , : ) =P( x , : ) (P( x , 1 )P ( 1 : 1 ) ) ;
end
67 P= f l i p l r (P) ;
f i g u r e , s u r f (P) , t i t l e ( 3D S u r f a c e R e p r e s e n t a t i o n L e v e l e d )
69
%%
71

73 %% F i n d i n g maximum two c o n s e c u t i v e p o i n t s d i f f e r e n c e
f o r y =1: s i z e (P , 2 )
75 MaxDeltaVector ( y ) =0;
f o r x=2: s i z e (P , 1 )
77 i f ( abs (P( x , y )P( x 1 ,y ) )>MaxDeltaVector ( y ) )
MaxDeltaVector ( y )=abs (P( x , y )P( x 1,y ) ) ;
79 end
end
81 end
MaxDelta=max( MaxDeltaVector ) ;
83
% F i n d i n g abrupt z change between two c o n s e c t u i v e p o i n t s ( r i g h t t o l e f t )
85 f o r y =1: s i z e (P , 2 )
P1 ( 1 , y )=min (P ( : ) ) ;
87 P1 ( 2 , y )=min (P ( : ) ) ;
f o r x=3: s i z e (P , 1 )
89 ExpectedValue=2P( x 1,y )P( x 2,y ) ;
i f ( abs (P( x , y )ExpectedValue ) <0.3 MaxDelta )

84
D Profile Processer MATLAB Code

91 P1 ( x , y )=min (P ( : ) ) ;
else
93 P1 ( x , y )=P( x , y ) ;
end
95 end
end
97
% F i n d i n g abrupt z change between two c o n s e c t u i v e p o i n t s ( l e f t t o r i g h t )
99 f o r y =1: s i z e (P , 2 )
P1 ( end , y )=min (P ( : ) ) ;
101 P1 ( end 1 ,y )=min (P ( : ) ) ;
f o r x=s i z e (P , 1 ) 2: 1:1
103 ExpectedValue=2P( x+1 ,y )P( x+2 ,y ) ;
i f ( abs (P( x , y )ExpectedValue ) >0.3 MaxDelta && P1 ( x , y )==0)
105 P1 ( x , y )=P( x , y ) ;
end
107 end
end
109 f i g u r e , s u r f ( P1 ) , t i t l e ( Abrupt a l t i t u d e c h a n g e s i n 3D model )
%%
111 % Adding n e i g h b o r p o i n t s t o c o l l e c t e d data
N e i g h b o r S i z e =3;
113 P2=P1 ;
f o r y=1+N e i g h b o r S i z e : s i z e (P , 2 )N e i g h b o r S i z e
115 f o r x=1+N e i g h b o r S i z e : s i z e (P , 1 )N e i g h b o r S i z e
f o r i=N e i g h b o r S i z e : N e i g h b o r S i z e
117 f o r j=N e i g h b o r S i z e : N e i g h b o r S i z e
i f ( P1 ( x+i , y+j )==P( x+i , y+j ) )
119 P2 ( x , y )=P( x , y ) ;
end
121 end
end
123 end
end
125 f i g u r e , s u r f ( P2 ) , t i t l e ( Added n e i g h b o u r s )
%%
127 % Remove min v a l u e ( e x c e p t 0 )
P2=P2min ( P2 ( : ) ) ;
129 minvalue=i n f ;
f o r y =1: s i z e (P , 2 )
131 f o r x=1: s i z e (P , 1 )
i f ( P2 ( x , y ) ~=0 && P2 ( x , y )<minvalue )
133 minvalue=P2 ( x , y ) ;
end
135 end
end
137 f o r y =1: s i z e (P , 2 )
f o r x=1: s i z e (P , 1 )
139 i f ( P2 ( x , y ) ~=0)
P2 ( x , y )=P2 ( x , y )minvalue ;
141 end
end
143 end
f i g u r e , s u r f ( P2 ) , t i t l e ( Min Value Removed )

85
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

145 P=P2 ;

147 % % Saturated Levels


% P(P>mean (P ( : ) ) )=mean (P ( : ) ) ;
149 % f i g u r e , s u r f (P) , t i t l e ( Homogenized L e v e l s )
%%
151 % Image Segmentation
P=P ;
153 I = mat2gray (P) ;
mask = f a l s e ( s i z e ( I ) ) ;
155
f o r x =1: s i z e ( I , 1 )
157 f o r y=1: s i z e ( I , 2 )
i f (P( x , y ) >=0.9max(P ( : ) ) )
159 mask ( x , y )=t r u e ;
end
161 end
end
163
W = g r a y d i f f w e i g h t ( I , mask , G r a y D i f f e r e n c e C u t o f f , 2 5 ) ;
165 thresh = 0.01;
[BW, D] = imsegfmm (W, mask , t h r e s h ) ;
167 figure
imshow (BW)
169 t i t l e ( Segmented BW Image )
%%
171 f o r x =1: s i z e ( I , 1 )
f o r y=1: s i z e ( I , 2 )
173 i f (BW( x , y )==f a l s e )
P( x , y ) =0;
175 end
end
177 end
I = mat2gray (P) ; f i g u r e , imshow ( I ) , t i t l e ( Segmented G r a y s c a l e Image )
179

181 % % M o d i f y i n g each l i n e a l t i t u d e t o have same max v a l u e f o r a l l l i n e s


% P=P ;
183 % m a x a l t i t u d e=max(P ( : ) ) ;
% f o r y =1: s i z e (P , 2 )
185 % P ( : , y )=P ( : , y ) ( m a x a l t i t u d e /max(P ( : , y ) ) ) ;
% end
187 % f i g u r e , s u r f (P) , t i t l e ( M o d i f i e d Image t o have same max v a l u e f o r each l i n e
)
% P=P ;
189
%P=P . ^ 5 ;
191 %f i g u r e , s u r f (P)

193

195
%
197 I = mat2gray (P) ; f i g u r e , imshow ( I )

86
D Profile Processer MATLAB Code

%C o n t r a s t S t r e t c h i n g
199 P=Pmin (P(P>0) ) ;
P(P<0)=0;
201 P=P . 255/max(P ( : ) ) ;
I = mat2gray (P) ; f i g u r e , imshow ( I ) , t i t l e ( C o n t r a s t S t r e t c h e d Image ) ;
203
%Negate Image
205 P=255P ;
I = mat2gray (P) ; f i g u r e , imshow ( I ) , t i t l e ( N e g a t i v e Image ) ;
207
% Perform OCR
209 r e s u l t s = ocr ( I ) ;

211 % D i s p l a y one o f t h e r e c o g n i z e d words


word = r e s u l t s . Words{2}
213
% L o c a t i o n o f t h e word i n I
215 wordBBox = r e s u l t s . WordBoundingBoxes ( 2 , : )

87
Appendix E

Profile Processor Header Code

1 #i f n d e f PROFILEPROCESSOR_H
#d e f i n e PROFILEPROCESSOR_H
3
#i n c l u d e <QWidget>
5 #i n c l u d e <opencv2 / c o r e / c o r e . hpp>
#i n c l u d e <opencv2 / h i g h g u i / h i g h g u i . hpp>
7 #i n c l u d e <opencv2 / imgproc / imgproc . hpp>
#i n c l u d e <QString>
9 #i n c l u d e <i o s t r e a m >
#i n c l u d e <QFile>
11 #i n c l u d e <QTextStream>
#i n c l u d e <QDebug>
13 #i n c l u d e <QGenericMatrix>
#i n c l u d e <QPixmap>
15 #i n c l u d e <QThread>

17 u s i n g namespace s t d ;
u s i n g namespace cv ;
19
class ProfileProcessor : p u b l i c QObject
21 {
Q_OBJECT
23
public :
25 ProfileProcessor () ;
v o i d P r o c e s s ( QString P r o f i l e D a t a L o c a t i o n , QString
ConfigurationFileLocation ) ;
27 signals :
v o i d SendImage ( QPixmap Image ) ;
29 v o i d Sen dCurr entOp erati on ( QString Command) ;
private :
31 v o i d L o a d P r o f i l e ( QString F i l e L o c a t i o n ) ;
v o i d ShowImage ( ) ;
33 void CorrectOrientation ( ) ;
void InvertColor ( ) ;
35 v o i d SharpenEdges ( ) ;
Mat P r o f i l e M a t ;
37 Mat ProfileMatAux ;

88
E Profile Processor Header Code

QFile P r o f i l e D a t a ;
39 QTextStream P r o f i l e S t r e a m ;
QList <QList <i n t >> P r o f i l e M a t r i x ;
41 QPixmap P r o f i l e P i x m a p ;
};
43
#e n d i f // PROFILEPROCESSOR_H

89
Appendix F

Profile Processor C++ Code

#i n c l u d e " p r o f i l e p r o c e s s o r . h "
2
ProfileProcessor : : ProfileProcessor ()
4 {
// qRegisterMetaType<QVector<QString> >(" QVector<QString >") ;
6 }

8 v o i d P r o f i l e P r o c e s s o r : : P r o c e s s ( QString P r o f i l e D a t a L o c a t i o n , QString
ConfigurationFileLocation )
{
10 QFile C o n f i g u r a t i o n ;
Configuration . setFileName ( C o n f i g u r a t i o n F i l e L o c a t i o n ) ;
12 C o n f i g u r a t i o n . open ( QIODevice : : ReadOnly ) ;
QTextStream C o n f i g u r a t i o n S t r e a m ;
14 C o n f i g u r a t i o n S t r e a m . s e t D e v i c e (& C o n f i g u r a t i o n ) ;
w h i l e ( ! C o n f i g u r a t i o n S t r e a m . atEnd ( ) )
16 {
QString A cti on=C o n f i g u r a t i o n S t r e a m . r e a d L i n e ( ) ;
18 i f ( Acti on . c o n t a i n s ( " Load F i l e " ) )
{
20 LoadProfile ( ProfileDataLocation ) ;
}
22 e l s e i f ( Act ion . c o n t a i n s ( " C o r r e c t O r i e n t a t i o n " ) )
{
24 CorrectOrientation () ;
}
26 e l s e i f ( Act ion . c o n t a i n s ( " I n v e r t C o l o r " ) )
{
28 InvertColor () ;
}
30 e l s e i f ( Act ion . c o n t a i n s ( " Sharpen Edges " ) )
{
32 SharpenEdges ( ) ;
}
34 }

36 Configuration . close () ;
ProfileMat . r e l e a s e () ;

90
F Profile Processor C++ Code

38 ProfileData . close () ;

40 }

42 v o i d P r o f i l e P r o c e s s o r : : L o a d P r o f i l e ( QString F i l e L o c a t i o n )
{
44 P r o f i l e D a t a . setFileName ( F i l e L o c a t i o n ) ;
P r o f i l e D a t a . open ( QIODevice : : ReadOnly ) ;
46 P r o f i l e S t r e a m . s e t D e v i c e (& P r o f i l e D a t a ) ;
i n t x , y , z , y o l d =0 , x i n d e x =1, y i n d e x =1;
48 i n t xindexmax =0 , yindexmax =0 ,zmax=0, zmin=s t d : : n u m e r i c _ l i m i t s <i n t > : : max ( ) ;
QString ReadLine ;
50 QList <QString> S p l i t t e d D a t a ;

52 // Scan f i l e i n o r d e r t o f i n d t h e image d i m e n s i o n s
P r o f i l e S t r e a m . r e a d L i n e ( ) ; // F i r s t L i n e
54 P r o f i l e S t r e a m . r e a d L i n e ( ) ; // Second L i n e
w h i l e ( ! P r o f i l e S t r e a m . atEnd ( ) )
56 {
ReadLine=P r o f i l e S t r e a m . r e a d L i n e ( ) ;
58 S p l i t t e d D a t a=ReadLine . s p l i t ( " \ t " ) ;
y=S p l i t t e d D a t a . a t ( 0 ) . t o I n t ( ) ;
60 x=S p l i t t e d D a t a . a t ( 1 ) . t o I n t ( ) ;
z=S p l i t t e d D a t a . a t ( 2 ) . t o I n t ( ) ;
62 i f ( y!= y o l d )
{
64 y i n d e x++;
x i n d e x =1;
66 y o l d=y ;
}
68 x i n d e x++;
i f ( xindex>xindexmax ) xindexmax=x i n d e x ;
70 i f ( y>yindexmax ) yindexmax=y ;
i f ( z>zmax ) zmax=z ;
72 i f ( z<zmin ) zmin=z ;
}
74
// C r e a t e Mat o b j e c t based on image s i z e
76 P r o f i l e M a t= Mat : : z e r o s ( yindexmax +1 , xindexmax +1 ,CV_8UC1) ;

78 // Read f i l e a g a i n t o f i l l t h e Mat o b j e c t a c c o r d i n g l y
ProfileStream . seek (0) ;
80 P r o f i l e S t r e a m . r e a d L i n e ( ) ; // F i r s t L i n e
P r o f i l e S t r e a m . r e a d L i n e ( ) ; // Second L i n e
82 x i n d e x =1;
y i n d e x =1;
84 w h i l e ( ! P r o f i l e S t r e a m . atEnd ( ) )
{
86 ReadLine=P r o f i l e S t r e a m . r e a d L i n e ( ) ;
S p l i t t e d D a t a=ReadLine . s p l i t ( " \ t " ) ;
88 y=S p l i t t e d D a t a . a t ( 0 ) . t o I n t ( ) ;
x=S p l i t t e d D a t a . a t ( 1 ) . t o I n t ( ) ;
90 z=S p l i t t e d D a t a . a t ( 2 ) . t o I n t ( ) ;
i f ( y!= y o l d )

91
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software

92 {
y i n d e x++;
94 x i n d e x =1;
y o l d=y ;
96 }
x i n d e x++;
98 i n t S c a l e d V a l u e =(( zzmin ) 2 5 4 / ( zmaxzmin ) ) +1;
P r o f i l e M a t . at<uchar >( yindex , x i n d e x )= S c a l e d V a l u e ;
100 }
// Check i f i t has z e r o v a l u e s
102 f o r ( y i n d e x =1; yindex<P r o f i l e M a t . rows ; y i n d e x++)
f o r ( x i n d e x =0; xindex<P r o f i l e M a t . c o l s ; x i n d e x++)
104 i f ( P r o f i l e M a t . at<uchar >( yindex , x i n d e x )==0)
{
106 P r o f i l e M a t . at<uchar >( yindex , x i n d e x )= P r o f i l e M a t . at<uchar >(
yindex 1, x i n d e x ) ;
}
108 f o r ( y i n d e x=P r o f i l e M a t . rows 2; yindex >=0; yindex )
f o r ( x i n d e x=P r o f i l e M a t . c o l s 1; xindex >=0; xindex )
110 i f ( P r o f i l e M a t . at<uchar >( yindex , x i n d e x )==0)
{
112 P r o f i l e M a t . at<uchar >( yindex , x i n d e x )= P r o f i l e M a t . at<uchar >(
y i n d e x +1, x i n d e x ) ;
}
114 emit Se ndCur rentO perat ion ( " P r o f i l e Data Loaded " ) ;
ShowImage ( ) ;
116 }

118 v o i d P r o f i l e P r o c e s s o r : : ShowImage ( )
{
120 QThread : : msleep ( 2 0 0 ) ;
s t a t i c QVector<QRgb> s C o l o r T a b l e ;
122
// o n l y c r e a t e our c o l o r t a b l e once
124 i f ( s C o l o r T a b l e . isEmpty ( ) )
{
126 f o r ( i n t i = 0 ; i < 2 5 6 ; ++i )
s C o l o r T a b l e . push_back ( qRgb ( i , i , i ) ) ;
128 }

130 QImage ImageQImage ( P r o f i l e M a t . data , P r o f i l e M a t . c o l s , P r o f i l e M a t . rows ,


P r o f i l e M a t . s t e p , QImage : : Format_Indexed8 ) ;
ImageQImage . s e t C o l o r T a b l e ( s C o l o r T a b l e ) ;
132
QPixmap ImageQPixmap = QPixmap : : fromImage ( ImageQImage ) ;
134 emit SendImage ( ImageQPixmap ) ;
}
136
void P r o f i l e P r o c e s s o r : : CorrectOrientation ( )
138 {
// Check i f i t i s n e c e s s a r y t o r o t a t e t h e image
140 i f ( P r o f i l e M a t . c o l s <P r o f i l e M a t . rows )
transpose ( ProfileMat , ProfileMat ) ;
142 emit Se ndCur rentO perat ion ( " O r i e n t a t i o n C o r r e c t e d " ) ;

92
F Profile Processor C++ Code

ShowImage ( ) ;
144 }

146 void P r o f i l e P r o c e s s o r : : InvertColor ( )


{
148 bitwise_not ( ProfileMat , ProfileMat ) ;
emit Se ndCur rentO perat ion ( " C o l o r s I n v e r t e d " ) ;
150 ShowImage ( ) ;
}
152

154
v o i d P r o f i l e P r o c e s s o r : : SharpenEdges ( )
156 {

158 G a u s s i a n B l u r ( P r o f i l e M a t , ProfileMatAux , S i z e ( 0 , 0 ) , 3 ) ;
addWeighted ( P r o f i l e M a t , 1 . 5 , ProfileMatAux , 0.5 , 0 , ProfileMatAux ) ;
160 P r o f i l e M a t=ProfileMatAux ;
emit Se ndCur rentO perat ion ( " Edges Sharpened " ) ;
162 ShowImage ( ) ;
}

93

S-ar putea să vă placă și