Practical Hands-On Project-Based PYTHON With Real-World Project Example Python Programming Course For Anyone From Children,... (Idris, Farouk Blake, Michael) (Z-Library)
Practical Hands-On Project-Based PYTHON With Real-World Project Example Python Programming Course For Anyone From Children,... (Idris, Farouk Blake, Michael) (Z-Library)
Practical Hands-On Project-Based PYTHON With Real-World Project Example Python Programming Course For Anyone From Children,... (Idris, Farouk Blake, Michael) (Z-Library)
By joint venture between the best minds who possess a similar capacity, they take up a key role in
teaching PLC-HMI and control programming to as many people as possible, cutting short the
learning curves and fears.
All rights reserved and Disclaimer.
No part of this publication shall be reproduced or stored in any retrieval system, mechanical or
electronic, or transmitted in any form or by any means; electronic, mechanical, recording, or
otherwise, without the author's prior written permission.
Although the author has made every effort to ensure that the information in this book is correct at
present, the authors and publisher do not assume and hereby disclaim any liability to any party for
any loss, damage, or disruption caused by any errors or omissions, whether such errors or omissions
resulting from negligence, accident, or any other possible cause. This book cannot assume any
responsibility whatsoever. All contents are original contents by Michael Blake and Farouk Idris.
This book is not authorized or endorsed by any entity.
This book serves as a best practices guide. The results are unique. Our track record has shown those
who contribute effort follow the best practices guide shown here and continue to work on it,
achieving sustainable and long-term results.
This book for who?
Our goal is to expose you to programming, especially Python programming, and as a bonus,
programming in the C++ environment too. We want to help you build your own programs that work.
This does not mean just games and stuff, but actual working, running, and producing results projects.
When you sleep or go do your things, the projects you developed are working. While this book
focuses on projects that are accessible to local networks. We have upcoming projects dealing with
Python, C++, and IoT where the project will be accessible through mobile devices.
While developing a foundation is crucial, immersing yourself in an actual live project gives you a
hardcore edge, not forgetting a sense of drive and purpose that lasts a lifetime. This book is for those
who believe they are the key person regardless of any age who never dealt with any programming
before. You may be fascinated with stories of your friends doing lots of coding on multiple
platforms, so you’ll find breakthroughs here. This book is really for those who want to learn quickly,
diving into cool projects, learning the tricks and hacks by solving the problems while creating those
projects. This book is perfect for all levels of individuals, from hobbyists, seasoned or beginner
programmers, and freelancers. For students attending schools or higher education and their teachers
who want to build their pupils with project-based programming, this book will be an excellent choice
compared to their existing textbook to make learning easier and more interesting.
What can you expect to learn here?
This book's purpose is simple. We want you to master programming, but this book focused on
Python and C++ programming. There is full-blown information on how to do Python, C++, and
other programming on the internet, but all the information is in pieces. What you will encounter in
this book is that all information will be integrated. This sets you to a solid foundation in the general
programming approach. As you work through this book, you soon realize that we are setting you to
play with the big boys in any industry that needs automation through programming. This will make
it easy for you to grasp any programming language when you set yourself to learn further. We will
not tell you what you’ll learn, but you'll touch on the most critical elements like the keywords,
instructions, functions, statements, control flows, methods, lists, loops, code modularization,
dictionaries, files, classes, objects, and interfaces. Bear in mind that you will program two kinds of
controllers that take care of all the ins, outs and display on a Monitor what is happening in real-time.
This is a huge deal for someone who has no or a little background. But if you are an experienced
programmer, you can adopt the content and skills shared in this book to implement your projects.
Introduction
A brief introduction related to the working of the Home Car Wash Control System is given
in this heading, with details covered in the next part. At the start of the process, the GUI is
displayed to the user, from which the user can select different parameters related to the
process, including:
Car type
Please take note: In chapter 5, we have included all the C++ codes for the controller
shown in the list below:
For now, a sneak peek on the how the GUI codes look like. The good news is that you can
customize the codes to anything you want when you request the actual codes from us.
Filename: GUI.py
# -*- coding: utf-8 -*-
import serial
import time
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QMessageBox
chk = 0
finish = 0;
count = 0;
ser = serial.Serial('/dev/ttyACM0', 9600, timeout=1)
ser.flush()
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(997, 842)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred,
QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(5)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth())
MainWindow.setSizePolicy(sizePolicy)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setStyleSheet("background-color: rgb(181, 243, 255);")
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout.setContentsMargins(5, 0, 5, 0)
self.verticalLayout.setSpacing(5)
self.verticalLayout.setObjectName("verticalLayout")
self.top = QtWidgets.QFrame(self.centralwidget)
self.top.setFrameShape(QtWidgets.QFrame.NoFrame)
self.top.setFrameShadow(QtWidgets.QFrame.Raised)
self.top.setObjectName("top")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.top)
self.horizontalLayout.setContentsMargins(0, 10, 0, 0)
self.horizontalLayout.setSpacing(10)
self.horizontalLayout.setObjectName("horizontalLayout")
self.topLeft = QtWidgets.QFrame(self.top)
self.topLeft.setStyleSheet("border: 2px solid black;")
self.topLeft.setFrameShape(QtWidgets.QFrame.NoFrame)
self.topLeft.setFrameShadow(QtWidgets.QFrame.Raised)
self.topLeft.setObjectName("topLeft")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.topLeft)
self.verticalLayout_2.setContentsMargins(10, 0, 10, 10)
self.verticalLayout_2.setSpacing(0)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.waterLevelLabel = QtWidgets.QLabel(self.topLeft)
font = QtGui.QFont()
font.setPointSize(16)
font.setBold(True)
font.setUnderline(True)
font.setWeight(75)
self.waterLevelLabel.setFont(font)
self.waterLevelLabel.setStyleSheet("border:none;")
self.waterLevelLabel.setObjectName("waterLevelLabel")
self.verticalLayout_2.addWidget(self.waterLevelLabel, 0, QtCore.Qt.AlignHCenter)
self.waterLevelSensor = QtWidgets.QLabel(self.topLeft)
self.waterLevelSensor.setStyleSheet("background-color: rgb(157, 157, 157);\n"
"border-radius: 20px;\n"
"border: 4px solid black;")
self.waterLevelSensor.setFrameShape(QtWidgets.QFrame.NoFrame)
self.waterLevelSensor.setText("")
self.waterLevelSensor.setPixmap(QtGui.QPixmap("icons8-water-level-60.png"))
self.waterLevelSensor.setAlignment(QtCore.Qt.AlignCenter)
self.waterLevelSensor.setObjectName("waterLevelSensor")
self.verticalLayout_2.addWidget(self.waterLevelSensor)
self.horizontalLayout.addWidget(self.topLeft)
self.topMiddle = QtWidgets.QFrame(self.top)
self.topMiddle.setStyleSheet("border: 2px solid black;")
self.topMiddle.setFrameShape(QtWidgets.QFrame.NoFrame)
self.topMiddle.setFrameShadow(QtWidgets.QFrame.Raised)
self.topMiddle.setObjectName("topMiddle")
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.topMiddle)
self.verticalLayout_3.setContentsMargins(10, 5, 10, 5)
self.verticalLayout_3.setSpacing(0)
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.tempLabel = QtWidgets.QLabel(self.topMiddle)
font = QtGui.QFont()
font.setPointSize(16)
font.setBold(True)
font.setUnderline(True)
font.setWeight(75)
self.tempLabel.setFont(font)
self.tempLabel.setStyleSheet("border: none;")
self.tempLabel.setObjectName("tempLabel")
self.verticalLayout_3.addWidget(self.tempLabel, 0,
QtCore.Qt.AlignHCenter|QtCore.Qt.AlignVCenter)
self.temperature = QtWidgets.QLCDNumber(self.topMiddle)
self.temperature.setFrameShape(QtWidgets.QFrame.Box)
self.temperature.setObjectName("temperature")
self.verticalLayout_3.addWidget(self.temperature)
self.horizontalLayout.addWidget(self.topMiddle)
self.topRight = QtWidgets.QFrame(self.top)
self.topRight.setMinimumSize(QtCore.QSize(500, 0))
self.topRight.setStyleSheet("border: 2px solid black;")
self.topRight.setFrameShape(QtWidgets.QFrame.NoFrame)
self.topRight.setFrameShadow(QtWidgets.QFrame.Raised)
self.topRight.setObjectName("topRight")
self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.topRight)
self.verticalLayout_4.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_4.setSpacing(0)
self.verticalLayout_4.setObjectName("verticalLayout_4")
self.topRightUp = QtWidgets.QFrame(self.topRight)
self.topRightUp.setStyleSheet("border: none;")
self.topRightUp.setFrameShape(QtWidgets.QFrame.NoFrame)
self.topRightUp.setFrameShadow(QtWidgets.QFrame.Raised)
self.topRightUp.setObjectName("topRightUp")
self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.topRightUp)
self.verticalLayout_5.setObjectName("verticalLayout_5")
self.sensorStatusLabel = QtWidgets.QLabel(self.topRightUp)
font = QtGui.QFont()
font.setPointSize(16)
font.setBold(True)
font.setUnderline(True)
font.setWeight(75)
self.sensorStatusLabel.setFont(font)
self.sensorStatusLabel.setStyleSheet("border: none;")
self.sensorStatusLabel.setObjectName("sensorStatusLabel")
self.verticalLayout_5.addWidget(self.sensorStatusLabel, 0,
QtCore.Qt.AlignHCenter|QtCore.Qt.AlignVCenter)
self.sensorStatusLabels = QtWidgets.QFrame(self.topRightUp)
font = QtGui.QFont()
font.setPointSize(8)
self.sensorStatusLabels.setFont(font)
self.sensorStatusLabels.setStyleSheet("border: none;")
self.sensorStatusLabels.setFrameShape(QtWidgets.QFrame.NoFrame)
self.sensorStatusLabels.setFrameShadow(QtWidgets.QFrame.Raised)
self.sensorStatusLabels.setObjectName("sensorStatusLabels")
self.horizontalLayout_15 = QtWidgets.QHBoxLayout(self.sensorStatusLabels)
self.horizontalLayout_15.setContentsMargins(40, 0, 0, 0)
self.horizontalLayout_15.setSpacing(35)
self.horizontalLayout_15.setObjectName("horizontalLayout_15")
self.homeSensorLabel = QtWidgets.QLabel(self.sensorStatusLabels)
font = QtGui.QFont()
font.setPointSize(10)
font.setBold(True)
font.setWeight(75)
self.homeSensorLabel.setFont(font)
self.homeSensorLabel.setObjectName("homeSensorLabel")
self.horizontalLayout_15.addWidget(self.homeSensorLabel)
self.forwardSensoLabel = QtWidgets.QLabel(self.sensorStatusLabels)
font = QtGui.QFont()
font.setPointSize(10)
font.setBold(True)
font.setWeight(75)
self.forwardSensoLabel.setFont(font)
self.forwardSensoLabel.setObjectName("forwardSensoLabel")
self.horizontalLayout_15.addWidget(self.forwardSensoLabel)
self.reverseSensorLabel = QtWidgets.QLabel(self.sensorStatusLabels)
font = QtGui.QFont()
font.setPointSize(10)
font.setBold(True)
font.setWeight(75)
self.reverseSensorLabel.setFont(font)
self.reverseSensorLabel.setObjectName("reverseSensorLabel")
self.horizontalLayout_15.addWidget(self.reverseSensorLabel)
self.verticalLayout_5.addWidget(self.sensorStatusLabels,0, QtCore.Qt.AlignBottom)
self.verticalLayout_4.addWidget(self.topRightUp)
self.topRightDown = QtWidgets.QFrame(self.topRight)
self.topRightDown.setStyleSheet("border: none;")
self.topRightDown.setFrameShape(QtWidgets.QFrame.NoFrame)
self.topRightDown.setFrameShadow(QtWidgets.QFrame.Raised)
self.topRightDown.setObjectName("topRightDown")
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.topRightDown)
self.horizontalLayout_2.setContentsMargins(5, 0, 5, 5)
self.horizontalLayout_2.setSpacing(5)
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.home = QtWidgets.QFrame(self.topRightDown)
self.home.setFrameShape(QtWidgets.QFrame.NoFrame)
self.home.setFrameShadow(QtWidgets.QFrame.Raised)
self.home.setObjectName("home")
self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.home)
self.horizontalLayout_3.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout_3.setSpacing(0)
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
self.homeSensor = QtWidgets.QLabel(self.home)
self.homeSensor.setStyleSheet("background-color: rgb(157, 157, 157);\n"
"border-radius: 20px;\n"
"border: 4px solid black;")
self.homeSensor.setText("")
self.homeSensor.setPixmap(QtGui.QPixmap("icons8-home-100.png"))
self.homeSensor.setAlignment(QtCore.Qt.AlignCenter)
self.homeSensor.setObjectName("homeSensor")
self.horizontalLayout_3.addWidget(self.homeSensor)
self.horizontalLayout_2.addWidget(self.home)
self.forward = QtWidgets.QFrame(self.topRightDown)
self.forward.setFrameShape(QtWidgets.QFrame.NoFrame)
self.forward.setFrameShadow(QtWidgets.QFrame.Raised)
self.forward.setObjectName("forward")
self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.forward)
self.horizontalLayout_4.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout_4.setSpacing(0)
self.horizontalLayout_4.setObjectName("horizontalLayout_4")
self.forwardSensor = QtWidgets.QLabel(self.forward)
self.forwardSensor.setStyleSheet("background-color: rgb(157, 157, 157);\n"
"border-radius: 20px;\n"
"border: 4px solid black;")
self.forwardSensor.setText("")
self.forwardSensor.setPixmap(QtGui.QPixmap("icons8-fast-forward-100.png"))
self.forwardSensor.setAlignment(QtCore.Qt.AlignCenter)
self.forwardSensor.setObjectName("forwardSensor")
self.horizontalLayout_4.addWidget(self.forwardSensor)
self.horizontalLayout_2.addWidget(self.forward)
self.reverse = QtWidgets.QFrame(self.topRightDown)
self.reverse.setFrameShape(QtWidgets.QFrame.NoFrame)
self.reverse.setFrameShadow(QtWidgets.QFrame.Raised)
self.reverse.setObjectName("reverse")
self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.reverse)
self.verticalLayout_6.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_6.setSpacing(0)
self.verticalLayout_6.setObjectName("verticalLayout_6")
self.reverseSensor = QtWidgets.QLabel(self.reverse)
self.reverseSensor.setStyleSheet("background-color: rgb(157, 157, 157);\n"
"border-radius: 20px;\n"
"border: 4px solid black;")
self.reverseSensor.setText("")
self.reverseSensor.setPixmap(QtGui.QPixmap("icons8-rewind-100.png"))
self.reverseSensor.setAlignment(QtCore.Qt.AlignCenter)
self.reverseSensor.setObjectName("reverseSensor")
self.verticalLayout_6.addWidget(self.reverseSensor)
self.horizontalLayout_2.addWidget(self.reverse)
self.verticalLayout_4.addWidget(self.topRightDown)
self.horizontalLayout.addWidget(self.topRight)
self.verticalLayout.addWidget(self.top)
self.middle = QtWidgets.QFrame(self.centralwidget)
self.middle.setFrameShape(QtWidgets.QFrame.NoFrame)
self.middle.setFrameShadow(QtWidgets.QFrame.Raised)
self.middle.setObjectName("middle")
self.horizontalLayout_5 = QtWidgets.QHBoxLayout(self.middle)
self.horizontalLayout_5.setContentsMargins(0, 10, 0, 0)
self.horizontalLayout_5.setSpacing(10)
self.horizontalLayout_5.setObjectName("horizontalLayout_5")
self.middleLeft = QtWidgets.QFrame(self.middle)
self.middleLeft.setStyleSheet("border: 2px solid black;")
self.middleLeft.setFrameShape(QtWidgets.QFrame.NoFrame)
self.middleLeft.setFrameShadow(QtWidgets.QFrame.Raised)
self.middleLeft.setObjectName("middleLeft")
self.verticalLayout_7 = QtWidgets.QVBoxLayout(self.middleLeft)
self.verticalLayout_7.setContentsMargins(10, 0, 10, 10)
self.verticalLayout_7.setSpacing(0)
self.verticalLayout_7.setObjectName("verticalLayout_7")
self.soapLevelLabel = QtWidgets.QLabel(self.middleLeft)
font = QtGui.QFont()
font.setPointSize(16)
font.setBold(True)
font.setUnderline(True)
font.setWeight(75)
self.soapLevelLabel.setFont(font)
self.soapLevelLabel.setStyleSheet("border: none;")
self.soapLevelLabel.setObjectName("soapLevelLabel")
self.verticalLayout_7.addWidget(self.soapLevelLabel,0,
QtCore.Qt.AlignHCenter|QtCore.Qt.AlignVCenter)
self.soapLevelSensor = QtWidgets.QLabel(self.middleLeft)
self.soapLevelSensor.setStyleSheet("background-color: rgb(157, 157, 157);\n"
"border-radius: 20px;\n"
"border: 4px solid black;")
self.soapLevelSensor.setText("")
self.soapLevelSensor.setPixmap(QtGui.QPixmap("icons8-soap-dispenser-80.png"))
self.soapLevelSensor.setAlignment(QtCore.Qt.AlignCenter)
self.soapLevelSensor.setObjectName("soapLevelSensor")
self.verticalLayout_7.addWidget(self.soapLevelSensor)
self.horizontalLayout_5.addWidget(self.middleLeft)
self.middleCenter = QtWidgets.QFrame(self.middle)
self.middleCenter.setStyleSheet("border: 2px solid black;")
self.middleCenter.setFrameShape(QtWidgets.QFrame.NoFrame)
self.middleCenter.setFrameShadow(QtWidgets.QFrame.Plain)
self.middleCenter.setObjectName("middleCenter")
self.verticalLayout_8 = QtWidgets.QVBoxLayout(self.middleCenter)
self.verticalLayout_8.setContentsMargins(10, 5, 10, 5)
self.verticalLayout_8.setSpacing(0)
self.verticalLayout_8.setObjectName("verticalLayout_8")
self.humidityLabel = QtWidgets.QLabel(self.middleCenter)
font = QtGui.QFont()
font.setPointSize(16)
font.setBold(True)
font.setUnderline(True)
font.setWeight(75)
self.humidityLabel.setFont(font)
self.humidityLabel.setStyleSheet("border: none;")
self.humidityLabel.setObjectName("humidityLabel")
self.verticalLayout_8.addWidget(self.humidityLabel, 0,
QtCore.Qt.AlignHCenter|QtCore.Qt.AlignVCenter)
self.humidity = QtWidgets.QLCDNumber(self.middleCenter)
self.humidity.setObjectName("humidity")
self.verticalLayout_8.addWidget(self.humidity)
self.horizontalLayout_5.addWidget(self.middleCenter)
self.middleRight = QtWidgets.QFrame(self.middle)
self.middleRight.setMinimumSize(QtCore.QSize(500, 0))
self.middleRight.setLayoutDirection(QtCore.Qt.LeftToRight)
self.middleRight.setStyleSheet("border: 2px solid black;")
self.middleRight.setFrameShape(QtWidgets.QFrame.NoFrame)
self.middleRight.setFrameShadow(QtWidgets.QFrame.Raised)
self.middleRight.setObjectName("middleRight")
self.verticalLayout_9 = QtWidgets.QVBoxLayout(self.middleRight)
self.verticalLayout_9.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_9.setSpacing(0)
self.verticalLayout_9.setObjectName("verticalLayout_9")
self.middleRightTop = QtWidgets.QFrame(self.middleRight)
self.middleRightTop.setStyleSheet("border: none;")
self.middleRightTop.setFrameShape(QtWidgets.QFrame.NoFrame)
self.middleRightTop.setFrameShadow(QtWidgets.QFrame.Raised)
self.middleRightTop.setObjectName("middleRightTop")
self.verticalLayout_17 = QtWidgets.QVBoxLayout(self.middleRightTop)
self.verticalLayout_17.setContentsMargins(9, 9, 9, 9)
self.verticalLayout_17.setSpacing(6)
self.verticalLayout_17.setObjectName("verticalLayout_17")
self.pumpMotorStatus = QtWidgets.QLabel(self.middleRightTop)
font = QtGui.QFont()
font.setPointSize(16)
font.setBold(True)
font.setItalic(False)
font.setUnderline(True)
font.setWeight(75)
font.setStrikeOut(False)
font.setKerning(True)
self.pumpMotorStatus.setFont(font)
self.pumpMotorStatus.setStyleSheet("border: none;")
self.pumpMotorStatus.setObjectName("pumpMotorStatus")
self.verticalLayout_17.addWidget(self.pumpMotorStatus, 0,
QtCore.Qt.AlignHCenter|QtCore.Qt.AlignVCenter)
self.pumpMotorLabels = QtWidgets.QFrame(self.middleRightTop)
font = QtGui.QFont()
font.setPointSize(8)
self.pumpMotorLabels.setFont(font)
self.pumpMotorLabels.setStyleSheet("border: none;")
self.pumpMotorLabels.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.pumpMotorLabels.setFrameShadow(QtWidgets.QFrame.Raised)
self.pumpMotorLabels.setObjectName("pumpMotorLabels")
self.horizontalLayout_7 = QtWidgets.QHBoxLayout(self.pumpMotorLabels)
self.horizontalLayout_7.setContentsMargins(35, 0, 0, 0)
self.horizontalLayout_7.setSpacing(30)
self.horizontalLayout_7.setObjectName("horizontalLayout_7")
self.waterPumpLabel = QtWidgets.QLabel(self.pumpMotorLabels)
font = QtGui.QFont()
font.setPointSize(10)
font.setBold(True)
font.setWeight(75)
self.waterPumpLabel.setFont(font)
self.waterPumpLabel.setObjectName("waterPumpLabel")
self.horizontalLayout_7.addWidget(self.waterPumpLabel)
self.soapPumpLabel = QtWidgets.QLabel(self.pumpMotorLabels)
font = QtGui.QFont()
font.setPointSize(10)
font.setBold(True)
font.setWeight(75)
self.soapPumpLabel.setFont(font)
self.soapPumpLabel.setObjectName("soapPumpLabel")
self.horizontalLayout_7.addWidget(self.soapPumpLabel)
self.motorLabel = QtWidgets.QLabel(self.pumpMotorLabels)
font = QtGui.QFont()
font.setPointSize(10)
font.setBold(True)
font.setWeight(75)
self.motorLabel.setFont(font)
self.motorLabel.setObjectName("motorLabel")
self.horizontalLayout_7.addWidget(self.motorLabel)
self.verticalLayout_17.addWidget(self.pumpMotorLabels, 0, QtCore.Qt.AlignBottom)
self.verticalLayout_9.addWidget(self.middleRightTop)
self.middleRightDown = QtWidgets.QFrame(self.middleRight)
self.middleRightDown.setEnabled(True)
self.middleRightDown.setStyleSheet("border: none;")
self.middleRightDown.setFrameShape(QtWidgets.QFrame.NoFrame)
self.middleRightDown.setFrameShadow(QtWidgets.QFrame.Raised)
self.middleRightDown.setObjectName("middleRightDown")
self.horizontalLayout_6 = QtWidgets.QHBoxLayout(self.middleRightDown)
self.horizontalLayout_6.setContentsMargins(5, 0, 5, 5)
self.horizontalLayout_6.setSpacing(5)
self.horizontalLayout_6.setObjectName("horizontalLayout_6")
self.waterPump = QtWidgets.QFrame(self.middleRightDown)
self.waterPump.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.waterPump.setFrameShadow(QtWidgets.QFrame.Raised)
self.waterPump.setObjectName("waterPump")
self.horizontalLayout_8 = QtWidgets.QHBoxLayout(self.waterPump)
self.horizontalLayout_8.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout_8.setSpacing(0)
self.horizontalLayout_8.setObjectName("horizontalLayout_8")
self.waterPumpSensor = QtWidgets.QLabel(self.waterPump)
self.waterPumpSensor.setStyleSheet("background-color: rgb(157, 157, 157);\n"
"border-radius: 20px;\n"
"border: 4px solid black;")
self.waterPumpSensor.setText("")
self.waterPumpSensor.setPixmap(QtGui.QPixmap("icons8-pump-100.png"))
self.waterPumpSensor.setAlignment(QtCore.Qt.AlignCenter)
self.waterPumpSensor.setObjectName("waterPumpSensor")
self.horizontalLayout_8.addWidget(self.waterPumpSensor)
self.horizontalLayout_6.addWidget(self.waterPump)
self.soapPump = QtWidgets.QFrame(self.middleRightDown)
self.soapPump.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.soapPump.setFrameShadow(QtWidgets.QFrame.Raised)
self.soapPump.setObjectName("soapPump")
self.verticalLayout_10 = QtWidgets.QVBoxLayout(self.soapPump)
self.verticalLayout_10.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_10.setSpacing(0)
self.verticalLayout_10.setObjectName("verticalLayout_10")
self.soapPumpSensor = QtWidgets.QLabel(self.soapPump)
self.soapPumpSensor.setStyleSheet("background-color: rgb(157, 157, 157);\n"
"border-radius: 20px;\n"
"border: 4px solid black;")
self.soapPumpSensor.setText("")
self.soapPumpSensor.setPixmap(QtGui.QPixmap("icons8-pump-100.png"))
self.soapPumpSensor.setAlignment(QtCore.Qt.AlignCenter)
self.soapPumpSensor.setObjectName("soapPumpSensor")
self.verticalLayout_10.addWidget(self.soapPumpSensor)
self.horizontalLayout_6.addWidget(self.soapPump)
self.motor = QtWidgets.QFrame(self.middleRightDown)
self.motor.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.motor.setFrameShadow(QtWidgets.QFrame.Raised)
self.motor.setObjectName("motor")
self.horizontalLayout_9 = QtWidgets.QHBoxLayout(self.motor)
self.horizontalLayout_9.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout_9.setSpacing(0)
self.horizontalLayout_9.setObjectName("horizontalLayout_9")
self.motorSensor = QtWidgets.QLabel(self.motor)
self.motorSensor.setStyleSheet("background-color: rgb(157, 157, 157);\n"
"border-radius: 20px;\n"
"border: 4px solid black;")
self.motorSensor.setText("")
self.motorSensor.setPixmap(QtGui.QPixmap("icons8-stepper-motor-100.png"))
self.motorSensor.setAlignment(QtCore.Qt.AlignCenter)
self.motorSensor.setObjectName("motorSensor")
self.horizontalLayout_9.addWidget(self.motorSensor)
self.horizontalLayout_6.addWidget(self.motor)
self.verticalLayout_9.addWidget(self.middleRightDown)
self.horizontalLayout_5.addWidget(self.middleRight)
self.verticalLayout.addWidget(self.middle)
self.bottom = QtWidgets.QFrame(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred,
QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.bottom.sizePolicy().hasHeightForWidth())
self.bottom.setSizePolicy(sizePolicy)
self.bottom.setFrameShape(QtWidgets.QFrame.NoFrame)
self.bottom.setFrameShadow(QtWidgets.QFrame.Raised)
self.bottom.setObjectName("bottom")
self.horizontalLayout_10 = QtWidgets.QHBoxLayout(self.bottom)
self.horizontalLayout_10.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
self.horizontalLayout_10.setContentsMargins(0, 8, 0, 8)
self.horizontalLayout_10.setSpacing(10)
self.horizontalLayout_10.setObjectName("horizontalLayout_10")
self.bottomLeft = QtWidgets.QFrame(self.bottom)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding,
QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.bottomLeft.sizePolicy().hasHeightForWidth())
self.bottomLeft.setSizePolicy(sizePolicy)
self.bottomLeft.setStyleSheet("border: 2px solid black;")
self.bottomLeft.setFrameShape(QtWidgets.QFrame.NoFrame)
self.bottomLeft.setFrameShadow(QtWidgets.QFrame.Raised)
self.bottomLeft.setObjectName("bottomLeft")
self.verticalLayout_11 = QtWidgets.QVBoxLayout(self.bottomLeft)
self.verticalLayout_11.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_11.setSpacing(0)
self.verticalLayout_11.setObjectName("verticalLayout_11")
self.parameters = QtWidgets.QGroupBox(self.bottomLeft)
font = QtGui.QFont()
font.setPointSize(15)
self.parameters.setFont(font)
self.parameters.setStyleSheet("border:none;")
self.parameters.setTitle("")
self.parameters.setFlat(False)
self.parameters.setObjectName("parameters")
self.horizontalLayout_11 = QtWidgets.QHBoxLayout(self.parameters)
self.horizontalLayout_11.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout_11.setSpacing(0)
self.horizontalLayout_11.setObjectName("horizontalLayout_11")
self.labels = QtWidgets.QFrame(self.parameters)
self.labels.setStyleSheet("border: none;")
self.labels.setFrameShape(QtWidgets.QFrame.NoFrame)
self.labels.setFrameShadow(QtWidgets.QFrame.Raised)
self.labels.setObjectName("labels")
self.verticalLayout_12 = QtWidgets.QVBoxLayout(self.labels)
self.verticalLayout_12.setObjectName("verticalLayout_12")
self.CarTypeLabel = QtWidgets.QLabel(self.labels)
font = QtGui.QFont()
font.setFamily("MS Shell Dlg 2")
font.setPointSize(15)
font.setBold(True)
font.setWeight(75)
self.CarTypeLabel.setFont(font)
self.CarTypeLabel.setObjectName("CarTypeLabel")
self.verticalLayout_12.addWidget(self.CarTypeLabel)
self.overallCycleLabel = QtWidgets.QLabel(self.labels)
font = QtGui.QFont()
font.setPointSize(15)
font.setBold(True)
font.setWeight(75)
self.overallCycleLabel.setFont(font)
self.overallCycleLabel.setObjectName("overallCycleLabel")
self.verticalLayout_12.addWidget(self.overallCycleLabel)
self.delaySoap = QtWidgets.QLabel(self.labels)
font = QtGui.QFont()
font.setPointSize(15)
font.setBold(True)
font.setWeight(75)
self.delaySoap.setFont(font)
self.delaySoap.setObjectName("delaySoap")
self.verticalLayout_12.addWidget(self.delaySoap)
self.soapSprayCycle = QtWidgets.QLabel(self.labels)
font = QtGui.QFont()
font.setPointSize(15)
font.setBold(True)
font.setWeight(75)
self.soapSprayCycle.setFont(font)
self.soapSprayCycle.setObjectName("soapSprayCycle")
self.verticalLayout_12.addWidget(self.soapSprayCycle)
self.waterSprayCycle = QtWidgets.QLabel(self.labels)
font = QtGui.QFont()
font.setPointSize(15)
font.setBold(True)
font.setWeight(75)
self.waterSprayCycle.setFont(font)
self.waterSprayCycle.setObjectName("waterSprayCycle")
self.verticalLayout_12.addWidget(self.waterSprayCycle)
self.delayWater = QtWidgets.QLabel(self.labels)
font = QtGui.QFont()
font.setPointSize(15)
font.setBold(True)
font.setWeight(75)
self.delayWater.setFont(font)
self.delayWater.setObjectName("delayWater")
self.verticalLayout_12.addWidget(self.delayWater)
self.horizontalLayout_11.addWidget(self.labels)
self.inputBoxes = QtWidgets.QFrame(self.parameters)
self.inputBoxes.setStyleSheet("border:none;")
self.inputBoxes.setFrameShape(QtWidgets.QFrame.NoFrame)
self.inputBoxes.setFrameShadow(QtWidgets.QFrame.Raised)
self.inputBoxes.setObjectName("inputBoxes")
self.verticalLayout_13 = QtWidgets.QVBoxLayout(self.inputBoxes)
self.verticalLayout_13.setSpacing(10)
self.verticalLayout_13.setObjectName("verticalLayout_13")
self.carType = QtWidgets.QComboBox(self.inputBoxes)
self.carType.setStyleSheet("background-color: rgb(255, 255, 255);")
self.carType.setObjectName("carType")
self.carType.addItem("")
self.carType.addItem("")
self.carType.addItem("")
self.verticalLayout_13.addWidget(self.carType)
self.OC = QtWidgets.QSpinBox(self.inputBoxes)
self.OC.setStyleSheet("background-color: rgb(255, 255, 255);")
self.OC.setObjectName("OC")
self.verticalLayout_13.addWidget(self.OC)
self.DS = QtWidgets.QSpinBox(self.inputBoxes)
self.DS.setStyleSheet("background-color: rgb(255, 255, 255);")
self.DS.setObjectName("DS")
self.verticalLayout_13.addWidget(self.DS)
self.SSC = QtWidgets.QSpinBox(self.inputBoxes)
self.SSC.setStyleSheet("background-color: rgb(255, 255, 255);")
self.SSC.setObjectName("SSC")
self.verticalLayout_13.addWidget(self.SSC)
self.WSC = QtWidgets.QSpinBox(self.inputBoxes)
self.WSC.setStyleSheet("background-color: rgb(255, 255, 255);")
self.WSC.setObjectName("WSC")
self.verticalLayout_13.addWidget(self.WSC)
self.DW = QtWidgets.QSpinBox(self.inputBoxes)
self.DW.setStyleSheet("background-color: rgb(255, 255, 255);")
self.DW.setObjectName("DW")
self.verticalLayout_13.addWidget(self.DW)
self.horizontalLayout_11.addWidget(self.inputBoxes)
self.verticalLayout_11.addWidget(self.parameters)
self.buttons = QtWidgets.QFrame(self.bottomLeft)
self.buttons.setStyleSheet("border: none;")
self.buttons.setFrameShape(QtWidgets.QFrame.NoFrame)
self.buttons.setFrameShadow(QtWidgets.QFrame.Raised)
self.buttons.setObjectName("buttons")
self.horizontalLayout_12 = QtWidgets.QHBoxLayout(self.buttons)
self.horizontalLayout_12.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout_12.setSpacing(0)
self.horizontalLayout_12.setObjectName("horizontalLayout_12")
self.Start = QtWidgets.QFrame(self.buttons)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum,
QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.Start.sizePolicy().hasHeightForWidth())
self.Start.setSizePolicy(sizePolicy)
self.Start.setFrameShape(QtWidgets.QFrame.NoFrame)
self.Start.setFrameShadow(QtWidgets.QFrame.Raised)
self.Start.setObjectName("Start")
self.horizontalLayout_13 = QtWidgets.QHBoxLayout(self.Start)
self.horizontalLayout_13.setObjectName("horizontalLayout_13")
self.start = QtWidgets.QPushButton(self.Start)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum,
QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.start.sizePolicy().hasHeightForWidth())
self.start.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setPointSize(12)
font.setBold(True)
font.setWeight(75)
self.start.setFont(font)
self.start.setStyleSheet("background-color: rgb(5, 255, 193);\n"
"border-radius: 25px;\n"
" border: 2px solid black;\n"
"height: 50px;\n"
"width: 50px;\n"
"")
self.start.setObjectName("start")
self.horizontalLayout_13.addWidget(self.start)
self.horizontalLayout_12.addWidget(self.Start)
self.animateButton = QtWidgets.QFrame(self.buttons)
self.animateButton.setStyleSheet("border-radius: 50px;")
self.animateButton.setFrameShape(QtWidgets.QFrame.NoFrame)
self.animateButton.setFrameShadow(QtWidgets.QFrame.Raised)
self.animateButton.setObjectName("animateButton")
self.horizontalLayout_14 = QtWidgets.QHBoxLayout(self.animateButton)
self.horizontalLayout_14.setObjectName("horizontalLayout_14")
self.update = QtWidgets.QPushButton(self.animateButton)
self.update.setStyleSheet("background-color:rgb(255, 0, 127);\n"
"border: 2px solid black;")
self.update.setText("")
self.update.setObjectName("update")
self.horizontalLayout_14.addWidget(self.update)
self.notDefined2 = QtWidgets.QPushButton(self.animateButton)
self.notDefined2.setStyleSheet("background-color: rgb(255, 85, 0);\n"
"border-radius: 25px;\n"
"border: 2px solid black;\n"
"")
self.notDefined2.setText("")
self.notDefined2.setObjectName("notDefined2")
self.horizontalLayout_14.addWidget(self.notDefined2)
self.notDefined1 = QtWidgets.QPushButton(self.animateButton)
self.notDefined1.setStyleSheet("background-color: rgb(0, 85, 255);\n"
"border-radius: 25px;\n"
"border: 2px solid black;\n"
"")
self.notDefined1.setText("")
self.notDefined1.setObjectName("notDefined1")
self.horizontalLayout_14.addWidget(self.notDefined1)
self.IO = QtWidgets.QPushButton(self.animateButton)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum,
QtWidgets.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.IO.sizePolicy().hasHeightForWidth())
self.IO.setSizePolicy(sizePolicy)
self.IO.setStyleSheet("background-color: rgb(255, 255, 0);\n"
"border-radius: 25px;\n"
"border: 2px solid black;\n"
"")
self.IO.setText("")
self.IO.setObjectName("IO")
self.horizontalLayout_14.addWidget(self.IO)
self.horizontalLayout_12.addWidget(self.animateButton, 0,
QtCore.Qt.AlignRight|QtCore.Qt.AlignBottom)
self.verticalLayout_11.addWidget(self.buttons)
self.horizontalLayout_10.addWidget(self.bottomLeft)
self.bottomRight = QtWidgets.QFrame(self.bottom)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred,
QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.bottomRight.sizePolicy().hasHeightForWidth())
self.bottomRight.setSizePolicy(sizePolicy)
self.bottomRight.setStyleSheet("border: 2px solid black;")
self.bottomRight.setFrameShape(QtWidgets.QFrame.NoFrame)
self.bottomRight.setFrameShadow(QtWidgets.QFrame.Raised)
self.bottomRight.setObjectName("bottomRight")
self.verticalLayout_14 = QtWidgets.QVBoxLayout(self.bottomRight)
self.verticalLayout_14.setObjectName("verticalLayout_14")
self.bottomFrameBottom = QtWidgets.QFrame(self.bottomRight)
self.bottomFrameBottom.setStyleSheet("border: none;")
self.bottomFrameBottom.setFrameShape(QtWidgets.QFrame.NoFrame)
self.bottomFrameBottom.setFrameShadow(QtWidgets.QFrame.Raised)
self.bottomFrameBottom.setObjectName("bottomFrameBottom")
self.verticalLayout_18 = QtWidgets.QVBoxLayout(self.bottomFrameBottom)
self.verticalLayout_18.setObjectName("verticalLayout_18")
self.progressLabel = QtWidgets.QLabel(self.bottomFrameBottom)
font = QtGui.QFont()
font.setPointSize(16)
font.setBold(True)
font.setWeight(75)
self.progressLabel.setFont(font)
self.progressLabel.setStyleSheet("border: none;")
self.progressLabel.setObjectName("progressLabel")
self.verticalLayout_18.addWidget(self.progressLabel)
self.progressBar = QtWidgets.QProgressBar(self.bottomFrameBottom)
self.progressBar.setStyleSheet("border: 2px solid black; \n"
"background-color: rgb(4, 217, 15); \n")
self.progressBar.setAlignment(QtCore.Qt.AlignCenter)
self.progressBar.setProperty("value", 24)
self.progressBar.setObjectName("progressBar")
self.verticalLayout_18.addWidget(self.progressBar)
self.verticalLayout_14.addWidget(self.bottomFrameBottom, 0, QtCore.Qt.AlignVCenter)
self.bottomRightTop = QtWidgets.QFrame(self.bottomRight)
self.bottomRightTop.setStyleSheet("border: none;")
self.bottomRightTop.setFrameShape(QtWidgets.QFrame.NoFrame)
self.bottomRightTop.setFrameShadow(QtWidgets.QFrame.Raised)
self.bottomRightTop.setObjectName("bottomRightTop")
self.verticalLayout_15 = QtWidgets.QVBoxLayout(self.bottomRightTop)
self.verticalLayout_15.setObjectName("verticalLayout_15")
self.operationLabel = QtWidgets.QLabel(self.bottomRightTop)
font = QtGui.QFont()
font.setPointSize(16)
font.setBold(True)
font.setWeight(75)
self.operationLabel.setFont(font)
self.operationLabel.setStyleSheet("border: none;")
self.operationLabel.setObjectName("operationLabel")
self.verticalLayout_15.addWidget(self.operationLabel)
self.operationMessageDisp = QtWidgets.QLabel(self.bottomRightTop)
self.operationMessageDisp.setMinimumSize(QtCore.QSize(0, 0))
font = QtGui.QFont()
font.setPointSize(12)
font.setBold(True)
font.setWeight(75)
self.operationMessageDisp.setFont(font)
self.operationMessageDisp.setStyleSheet("background-color: rgb(0, 0, 0);\n"
"color: rgb(194, 194, 194);\n"
"border-radius: 20px;\n"
"")
self.operationMessageDisp.setAlignment(QtCore.Qt.AlignCenter)
self.operationMessageDisp.setObjectName("operationMessageDisp")
self.verticalLayout_15.addWidget(self.operationMessageDisp)
self.verticalLayout_14.addWidget(self.bottomRightTop)
self.bottomRightMiddle = QtWidgets.QFrame(self.bottomRight)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred,
QtWidgets.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.bottomRightMiddle.sizePolicy().hasHeightForWidth())
self.bottomRightMiddle.setSizePolicy(sizePolicy)
self.bottomRightMiddle.setStyleSheet("border: none;")
self.bottomRightMiddle.setFrameShape(QtWidgets.QFrame.NoFrame)
self.bottomRightMiddle.setFrameShadow(QtWidgets.QFrame.Raised)
self.bottomRightMiddle.setObjectName("bottomRightMiddle")
self.verticalLayout_16 = QtWidgets.QVBoxLayout(self.bottomRightMiddle)
self.verticalLayout_16.setObjectName("verticalLayout_16")
self.faultMessageLabel = QtWidgets.QLabel(self.bottomRightMiddle)
font = QtGui.QFont()
font.setPointSize(16)
font.setBold(True)
font.setWeight(75)
self.faultMessageLabel.setFont(font)
self.faultMessageLabel.setStyleSheet("border: none;")
self.faultMessageLabel.setObjectName("faultMessageLabel")
self.verticalLayout_16.addWidget(self.faultMessageLabel)
self.faultMessageDisp = QtWidgets.QLabel(self.bottomRightMiddle)
font = QtGui.QFont()
font.setPointSize(12)
font.setBold(True)
font.setWeight(75)
self.faultMessageDisp.setFont(font)
self.faultMessageDisp.setStyleSheet("background-color: rgb(0, 0, 0);\n"
"color: rgb(194, 194, 194);\n"
"border-radius: 20px;\n"
"")
self.faultMessageDisp.setAlignment(QtCore.Qt.AlignCenter)
self.faultMessageDisp.setObjectName("faultMessageDisp")
self.verticalLayout_16.addWidget(self.faultMessageDisp)
self.verticalLayout_14.addWidget(self.bottomRightMiddle)
self.horizontalLayout_10.addWidget(self.bottomRight)
self.verticalLayout.addWidget(self.bottom)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
self.WSC.setValue(1)
self.SSC.setValue(1)
self.DW.setValue(5)
self.DS.setValue(5)
self.OC.setValue(1)
self.temperature.display(0)
self.humidity.display(0)
self.start.clicked.connect(self.start_process)
self.update.clicked.connect(self.update_process)
self.IO.clicked.connect(self.io_diagnostic)
self.progressBar.setValue(0)
def io_diagnostic(self):
io_diagnostic_msg = QMessageBox()
io_diagnostic_msg.setWindowTitle("IO Diagnostic")
io_diagnostic_msg.setText("Do you wanna run IO Diagnostic")
io_diagnostic_msg.setIcon(QMessageBox.Question)
io_diagnostic_msg.setStandardButtons(QMessageBox.Cancel|QMessageBox.Ok)
io_diagnostic_msg.setDefaultButton(QMessageBox.Ok)
io_diagnostic_msg.exec_()
def stop_process(self):
stop_msg = QMessageBox()
stop_msg.setWindowTitle("Warning")
stop_msg.setText("Do you want to Halt the Process?")
stop_msg.setIcon(QMessageBox.Question)
stop_msg.setStandardButtons(QMessageBox.Cancel|QMessageBox.Ok)
stop_msg.setDefaultButton(QMessageBox.Ok)
stop_msg.exec_()
def update_process(self):
global finish
print("update")
line2 =""
while True:
line2 = ser.readline().decode('utf-8').rstrip()
print(line2)
#time.sleep(1)
if chk == 2:
if len(line2) > 0:
if line2[0] == "t":
l= len(line2)
if l == 1:
signalTemp = line2[1]
else:
signalTemp= line2[1:l]
print(signalTemp)
print(chk)
self.temperature.display(int(signalTemp))
if int(signalTemp) == 0:
self.faultMessageDisp.setText("DHT11 Sensor Fault !!!")
else:
self.faultMessageDisp.setText("")
ser.write(b"PiRec2\n")
#time.sleep(1);
line2= ""
chk = 3
break;
if chk == 3:
if len(line2) > 0:
if line2[0] == "h":
l= len(line2)
if l == 1:
signalHum = line2[1]
else:
signalHum = line2[1:l]
print(signalHum)
print(chk)
self.humidity.display(int(signalHum))
if int(signalHum) == 0:
self.faultMessageDisp.setText("DHT11 Sensor Fault !!!")
else:
self.faultMessageDisp.setText("")
ser.write(b"PiRec3\n")
#time.sleep(1);
line2= ""
chk = 4
break;
if chk == 10:
if len(line2) > 0:
if line2[0] == "p":
l= len(line2)
if l == 1:
progress = line2[1]
else:
progress = line2[1:l]
print(progress)
print(chk)
self.operationMessageDisp.setText(progress)
ser.write(b"PiRec10\n")
#time.sleep(1);
line2= ""
chk = 11
break;
if chk == 11:
if len(line2) > 0:
if line2[0] == "g":
l= len(line2)
if l == 1:
percentage = line2[1]
else:
percentage = line2[1:l]
print(percentage)
print(chk)
self.progressBar.setValue(int(percentage))
ser.write(b"PiRec11\n")
#time.sleep(1);
line2= ""
chk = 12
break;
#time.sleep(3)
if finish == 0:
self.update.animateClick()
if finish == 1:
finish = 0
def start_process(self):
carType = self.carType.currentText()
wsc = self.WSC.value()
ssc = self.SSC.value()
dw = self.DW.value()
ds = self.DS.value()
oc = self.OC.value()
self.operationMessageDisp.setText("Waiting to Start")
self.faultMessageDisp.setText("")
msg = QMessageBox()
msg.setWindowTitle("Car Wash Parameters")
msg.setText("Overall Cycles: "+str(oc)+"\nWater Spray Cycle: "+str(wsc)+
"\nSoap Spray Cycle: "+str(ssc)+"\nDelay Water: "+str(dw)+"\nDelay Soap: "+str(ds))
msg.setInformativeText("Car Type "+ carType + " is selected!")
msg.setInformativeText("Car Type "+ carType + " is selected!")
msg.setIcon(QMessageBox.Information)
x = msg.exec_()
############Communication Code###############
#ser = serial.Serial('/dev/ttyACM0', 9600, timeout=1)
#ser.flush()
msg="\n"
chk_serial = 0
print("start")
ser = serial.Serial('/dev/ttyACM0', 9600, timeout=1)
ser.flush()
while True:
if chk_serial == 0:
ser.write(carType.encode('utf-8'))
ser.write(msg.encode('utf-8'))
line = ser.readline().decode('utf-8').rstrip()
print(line)
#time.sleep(1)
if line == "car_rec":
chk_serial = 1
if chk_serial == 1:
ser.write(str(wsc).encode('utf-8'))
ser.write(msg.encode('utf-8'))
line = ser.readline().decode('utf-8').rstrip()
print(line)
#time.sleep(1)
if line == "wsc_rec":
chk_serial = 2
if chk_serial == 2:
ser.write(str(ssc).encode('utf-8'))
ser.write(msg.encode('utf-8'))
line = ser.readline().decode('utf-8').rstrip()
print(line)
#time.sleep(1)
if line == "ssc_rec":
chk_serial = 3
if chk_serial == 3:
ser.write(str(dw).encode('utf-8'))
ser.write(msg.encode('utf-8'))
line = ser.readline().decode('utf-8').rstrip()
print(line)
#time.sleep(1)
if line == "dw_rec":
chk_serial = 4
if chk_serial == 4:
ser.write(str(ds).encode('utf-8'))
ser.write(msg.encode('utf-8'))
line = ser.readline().decode('utf-8').rstrip()
print(line)
#time.sleep(1)
if line == "ds_rec":
chk_serial = 5
if chk_serial == 5:
ser.write(str(oc).encode('utf-8'))
ser.write(msg.encode('utf-8'))
line = ser.readline().decode('utf-8').rstrip()
print(line)
if line == "oc_rec":
chk_serial = 6
self.update.animateClick()
break;
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
Download Python 3 Codes Here
We know this is a lot to take in. So, to make your life easier we have prepared for you to
download all the GUI Python 3 codes and the controller C++ codes that will receive
inputs from Home, Reverse & Forward sensors, Soap & Water barrel sensors,
Temperature and Humidity Sensors, and control pumps and ac motor inverter.
Go here to download
The Detail Explanation of the System Graphical User Interface (GUI)
Here is the GUI designed for Car Wash System using Qt designer and its programming is done in
python language. Multiple QWidgets and QFrames are embed in this PyQt5 application that
interact with user to take input and display output of the sensors.
In this customized GUI, frames and widgets are aligned according to grid with correct placement
of each window so user can easily visualize and understand it, furthermore, its pixels and images
are automatically adjusted to any desired screen. In demo video, local GUI is running on
1280x780 resolution screen while remote GUI is running on 1920x1080 that depicts that GUI is
purely responsive to any screen.
Time library is used to create some delay in the GUI program, we need such delay while program
is in state of receiving parameters from the Arduino and changing state on display. It takes time
parameter in milliseconds.
For designing and layout of the GUI we need multiple widgets, input, output fields and display
panels to show temperature and humidity. Before sending the parameters, GUI show a message
box to confirm the sending parameters for that purpose we used QMessageBox library.
Basic structure of GUI contains three major parts TOP, MIDDLE and BOTTOM. Each part further
contains widgets, frames, I/O options, sensor outputs, progress bar and more.
First, the top, middle and bottom frame is created and in top and middle frame three more frames are
created while in the last frame 2 frames are created. Three main frames are aligned vertically while
the frames inside the major frames are aligned horizontally.
The Top Frame
Below is the top frame that represent water level, temperature and sensor status of home, forward
and reverse.
Top frame shape is selected as ‘NoFrame’ while frame shadow as ‘Raised’. Its content margins for
right side are set as 10 pixels and spacing as 10 pixels. Border for frame is set in the stylesheet
property as 2px solid black. Top frame contains right, center, and left frames. All these frames are
layout as horizontally.
In top left frame, label and frame is added for water level sensor. Frame is created in top frame as
topLeft by using this code “self.topLeft = QtWidgets.QFrame(self.top)”. Geometry settings are set
using the python code line for frame as No frame
“self.topLeft.setFrameShape(QtWidgets.QFrame.NoFrame)” and frame shadow as raised by using
“self.topLeft.setFrameShadow(QtWidgets.QFrame.Raised)”. Water level label point size is set as 16,
weight as 75 and text is made bold and underline. Water level widget is aligned horizontally center
with the design property for "background-color: rgb(157, 157, 157);\n" "border-radius: 20px;\n" and
"border: 4px solid black;"). This widget also contains an icon for water level sensor. Icons can be
add as “self.waterLevelSensor.setPixmap(QtGui.QPixmap("icons8-water-level-60.png"))” Idle state
for water level sensor is grey as our water level is above the defined level it will turns green
otherwise red.
The Temperature
Top middle frame depicts temperature value in degree Celsius. For this, temperature label along with
QLcdNumber is added in a top middle frame. Properties for font is same as set in top left frame
while content margins are set as 10, 5, 10 , 5 for left, top, right and bottom resepectively. Label
widget is aligned vertically and horizontally in center. Temperature widget is imported as
QLcdNumber that tells you the current temperature of the atmosphere.
The Top Right Frame
Top right frame is one of the main frame of the GUI, it contains home, forward and reverse sensor
that will tells the current position and direction of the moving motor. Initially when system starts it’s
on the home position then it will move in forward direction and then in reverse and then again
forward until it finds home position. It comprises of two frames topRightUp and topRightDown. Top
right up frame contains the label and has the same property for labels which include bold, underline,
point size 16 and weight size 75.
The Top Right Up
Top right up frame surrounds three labels for each sensor home, forward and reverse with point size
10, weight as 75 and text as bold. Alignment for these labels is set as Align Bottom along with
spacing of 35 pixels and margins from left side is given as 40 pixels.
The Top Right Down
Top right down has three frames, home, forward and reverse. Design and font properties are same
for all the three sensor frames and label point size 10, text weight 75, and spacing among each label
is 35 pixels. Moreover, content margins are set as 5, 0, 5, 5 for left, top, right and bottom
respectively. Each sensor contains the specific image for the sensor and it gets activate and change
its color to green when motor is in either condition. Design properties are ("background-color:
rgb(157, 157, 157);\n" "border-radius: 20px;\n" and "border: 4px solid black;").
Motor sensor status code snippets with their parameters are attached below.
The Home Sensor
Middle frame has been created which contains several parameters including soap level, humidity,
pumps and motor status.
Middle frames have three more frames which are horizontally aligned along with some geometry,
margins, frames and shadow properties. Middle frame shape is selected as ‘NoFrame’ while frame
shadow as ‘Raised’. Its content margins for right side is set as 10 pixels and spacing as 10 pixels.
Border for frame is set in the stylesheet property as 2px solid black. Middle frame contains right,
center, and left frames.
The Humidity
Humidity frame is placed as middle center frame of the middle frame
Middle center frame depicts humidity value in percentage. For this, temperature label along with
QLcdNumber is added in a middle center frame. Properties for font is same as set in middle left
frame while content margins are set as 10, 5, 10, 5 for left, top, right and bottom respectively. Label
widget is aligned vertically and horizontally in center. Humidity widget is imported as QLcdNumber
that tells you the current humidity of the atmosphere.
Middle right top frame surrounds three labels for each soap pump, water pump and motor with point
size 10, weight as 75 and text as bold. Alignment for these labels are set as Align Bottom along with
spacing of 30 pixels and margins from left side is given as 35 pixels.
The Middle Right Down
Top right down has three frames, home, forward and reverse. Design and font properties are same
for all the three sensor frames and label point size 10, text weight 75, and spacing among each label
is 35 pixels. Moreover, content margins are set as 5, 0, 5, 5 for left, top, right and bottom
respectively. Each sensor contains the specific image for the sensor and it gets activate and change
its color to green when motor is in either condition. Design properties are ("background-color:
rgb(157, 157, 157);\n" "border-radius: 20px;\n" and "border: 4px solid black;").
The Water Pump Frame
The Soap Pump Frame
Bottom frame is designed for user to get inputs from it and to display the progress, current operation
and fault messages. Bottom frame is added in the central widget. Its size policy include horizontal
and vertical stretch that is set to zero. Frame and shadow properties are set to “NoFrame” and
“Raised” respectively. Content margins is set using “self.horizontalLayout_10.setContentMargins(0,
8, 0, 8)” while the spacing as “self.horizontalLayout_10.setSpacing(10)”.
Parameters of car wash system encompasses of car type, overall cycles of the process, delay needed
after soap cycle, soap sprinkles cycle, water sprinkle cycle and delay needed after water spray. These
are parameters required to start a car washing system. In car type, we have a drop-down menu which
gives us options of MiniCar, Sedan and MPV. On the other hand, cycles are number of iterations of
that particular procedure. Parameters frame in terms of designing consist of labels for each particular
heading. QComboBox is set for car type to enable drop down menu feature and for cycle and delay
QSpinBox is declared to select any positive integer.
Properties are declared in the same manner as before and its properties are adjusted as shown in the
image below.
Labels are created in a group box and its font family is selected as “MS Shell Dlg 2”, point size as 15
and weight as 75 and to dominate the text it has to keep bold. All the labels are created one after the
other in a sequential manner.
Input boxes are defined as QSpinBoxes for each parameter except car type in the picture below.
The Buttons
We have integrated a pushbutton to start the process, it will take input parameters from the user
interface and then send it to microcontroller unit via serial communication. Button is created in the
bottom left side of the frame and its properties are set as “NoFrame” and “Raised” in geometry of
the button. Its content margins and spacing are set to zero pixels. Color, border, border-radius, height
and width for the button is set by accessing the style sheet properties of the button.
In bottom right frame, progress bar along with operation and fault messages labels are inserted. All
properties are same as set before in earlier frame.
The Progress Bar
What is Raspberry pi 4
The Raspberry Pi is a microcontroller that uses python language and supports parallel
processing with Linux based Raspbian operating system installed on it. It's a single
computer board equipped with a Quad-core Cortex-A72 processor, which requires less
processing energy and saves room by maintaining costs low. The Raspberry Pi 4 module is
shown in the figure below.
Figure 1 Raspberry Pi 4
It has distinct ports in parallel for various operations. There are 4 USB ports (2 USB 3.0
ports; 2 USB 2.0 ports) and one Ethernet port connecting Raspberry Pi to the port.
Raspberry Pi has its own Wireless Fidelity and Bluetooth port (Wi-Fi). Raspberry Pi utilizes
the operating system separated, known to be Raspbian. It has two micro HDMI ports,
audio/video, and a camera connector to connect the screen. The 5-volt source is linked. A
400MHz video-core IV multimedia is provided by Raspberry Pi. The SONAR, light-
emitting diode (LEDs), and engine driver pins link GPIO pins. Two models, A and B, are
available for the raspberry pi. In short, Raspberry pi 4 is a good processor for extensive and
graphical tasks.
https://www.raspberrypi.org/software/operating-systems/
Different versions of OS are available; choose any of them according to the free
space available in the SD-Card of the raspberry pi.
Figure 2 OS available for Raspberry Pi
Click on the download button to start downloading the disk image file of the
selected OS.
After downloading the disk image, the next step is to boot the disk image file on the
SD card. For this download “Rufus” on your laptop using the following link
https://rufus.ie/en/
Now insert the micro-SD-card into the slot available on the raspberry pi.
Connect the one end of the USB to Type C cable to the Type C slot present in the
raspberry pi and the other end to the power supply.
Connect the “micro-HDMI” slot of the micro-HDMI to VGA cable to the “HDMI0”
port on the raspberry pi and the other end to the VGA of the monitor.
Power on the supply.
After some time, the raspberry pi OS desktop environment will be displayed on the
monitor screen.
Click on the next to select the country, language, and time zone. Then change the
password from the default “raspberry” to one of your choosing. The username is by
default “pi.”
Then the window for the Wi-Fi connection will appear. Select your desired Wi-Fi
network available and click on next. Give the password for the Wi-Fi, and your
raspberry pi will be connected to the internet.
The last step is to enable the “SSH” on raspberry pi by going to the “raspberry pi
configuration” then “interfaces” and then to the “SSH.” Now the Pi is configured to
be used.
Setting up Arduino IDE
https://www.arduino.cc/en/software
Select the windows from the download option as shown in figure 8, and this will
download the Arduino IDE 1.8.15.
This library is used to communicate with the I2C devices connected to the Arduino. In this
project, if any I2C device is used, then this library must be included.
#include <SPI.h>
This library is used to communicate with the Serial Peripheral Interface (SPI) devices
connected to the Arduino. In this project, if any SPI device is used, then this library must be
included.
#include<SoftwareSerial.h>
This library is used to use the serial as a virtual terminal in the Proteus simulation of this
project.
These two libraries are used to connect OLED with Arduino. OLED can be used with
Arduino for debugging code since the serial monitor of Arduino is used as a means of
communication between Arduino and Raspberry pi.
#include <dht.h>
This library is used to communicate with the DHT11 module connected to the Arduino. The
DHT module is used to measure the temperature and humidity in this project.
These libraries should be placed in the “libraries” folder present in the Arduino IDE’s
extracted folder, as shown in the figure below:
Once the libraries are placed in the folder shown above, the Arduino IDE is ready to
compile and upload the program to the Arduino Mega 2560.
The Components used in this project
The different components used in this project are briefly discussed below:
Arduino Mega2560 is used in this project for controlling different input/ output devices. It is
used as the main control unit. This microcontroller board is based on Atmega 2560.
The above diagram shows the Arduino Mega 2560. It consists of 54 digital input or output
pins. Due to many pins, this microcontroller is commonly used in projects with many
input/output devices. Its specifications are shown below in the table below:
Table 1 Arduino Mega 2560 Specifications
Filename: car_wash_code.ino
#include<EEPROM.h>
#include<Wire.h>
#include <SPI.h>
#include<SoftwareSerial.h>
#include <dht.h>
dht DHT;
int check = 1;
int count = 1;
long total_cycle = 1;
long water_cycle = 1;
long soap_cycle = 1;
long w_s_delay = 3;
long s_w_delay = 3;
String input;
String car_type = "nill";
int chk_serial = 0;
bool all_good = false;
bool start = false;
void setup() {
Serial.begin(9600);
io_setup();
void loop() {
percentage = "0";
finish_s = "NFIN";
receive_gui_parameters();
do{
temp_hum();
water_level();
soap_level();
}
while(all_good == false);
find_home();
start = true;
if(start == true)
{
vehicle_wash_process(total_cycle,water_cycle,soap_cycle);
finish_s = "FIN";
send_initial_par_to_pi();
}
all_good = false;
Filename: Io_s_setup.ino
void io_setup()
{
pinMode(relay_water_pump, OUTPUT);
pinMode(relay_soap_pump, OUTPUT);
pinMode(relay_reverse_inverter, OUTPUT);
pinMode(relay_forward_inverter, OUTPUT);
pinMode(forward_limit_s, INPUT_PULLUP);
pinMode(reverse_limit_s, INPUT_PULLUP);
pinMode(home_s, INPUT_PULLUP);
pinMode(trigger, OUTPUT);
pinMode(echo, INPUT);
pinMode(trigger2, OUTPUT);
pinMode(echo2, INPUT);
digitalWrite(relay_forward_inverter, HIGH);
digitalWrite(relay_reverse_inverter, HIGH);
digitalWrite(relay_soap_pump, HIGH);
digitalWrite(relay_water_pump, HIGH);
Filename: motors.ino
void motor_fwd()
{
digitalWrite(relay_forward_inverter, LOW);
digitalWrite(relay_reverse_inverter, HIGH);
motor_s = "MO";
if(count == 1)
{
forward_sensor_s = "SSF";
reverse_sensor_s = "NSR";
home_sensor_s = "NSH";
send_initial_par_to_pi();
count=2;
}
if(count == 3)
{
forward_sensor_s = "SSF";
reverse_sensor_s = "NSR";
home_sensor_s = "NSH";
send_initial_par_to_pi();
count=4;
}
}
void motor_bwd()
{
motor_s = "MO";
digitalWrite(relay_forward_inverter, HIGH);
digitalWrite(relay_reverse_inverter, LOW);
if(count == 2)
{
forward_sensor_s = "NSF";
reverse_sensor_s = "SSR";
home_sensor_s = "NSH";
send_initial_par_to_pi();
count=3;
}
}
void motor_stop()
{
motor_s = "MF";
water_pump_s = "WPF";
soap_pump_s = "SPF";
forward_sensor_s = "NSF";
reverse_sensor_s = "NSR";
home_sensor_s = "SSH";
send_initial_par_to_pi();
digitalWrite(relay_forward_inverter, HIGH);
digitalWrite(relay_reverse_inverter, HIGH);
digitalWrite(relay_water_pump, HIGH);
digitalWrite(relay_soap_pump, HIGH);
if(count == 4)
{
count=1;
}
}
void find_home()
{
int check_home = 0;
while( check_home == 0)
{
int loop_count = 0;
progress = "System finding home !!!";
send_initial_par_to_pi();
int loop_limit = (time_for_cycle * 1000)/100;
if (digitalRead(home_s))
{
digitalWrite(relay_forward_inverter, LOW);
digitalWrite(relay_reverse_inverter, HIGH);
motor_s = "MO";
forward_sensor_s = "SSF";
reverse_sensor_s = "NSR";
home_sensor_s = "NSH";
send_initial_par_to_pi();
do
{
if (!digitalRead(home_s))
{
digitalWrite(relay_forward_inverter, HIGH);
digitalWrite(relay_reverse_inverter, HIGH);
motor_s = "MF";
forward_sensor_s = "NSF";
reverse_sensor_s = "NSR";
home_sensor_s = "SSH";
progress = "Home Reached !!!";
send_initial_par_to_pi();
loop_count = loop_limit;
check_home = 1;
return;
}
else
{
loop_count++;
}
delay(100);
}
while(loop_count < loop_limit);
loop_count = 0;
digitalWrite(relay_forward_inverter, HIGH);
digitalWrite(relay_reverse_inverter, LOW);
motor_s = "MO";
forward_sensor_s = "NSF";
reverse_sensor_s = "SSR";
home_sensor_s = "NSH";
send_initial_par_to_pi();
do
{
if (!digitalRead(home_s))
{
digitalWrite(relay_forward_inverter, HIGH);
digitalWrite(relay_reverse_inverter, HIGH);
motor_s = "MF";
forward_sensor_s = "NSF";
reverse_sensor_s = "NSR";
home_sensor_s = "SSH";
progress = "Home Reached !!!";
send_initial_par_to_pi();
loop_count = loop_limit;
check_home = 1;
return;
}
else
{
loop_count++;
}
delay(100);
}
while(loop_count < loop_limit);
}
else
{
progress = "System at home !!!";
send_initial_par_to_pi();
check_home = 1;
return;
}
Filename: receive_gui_parameters.ino
void receive_gui_parameters()
{
chk_serial = 0;
while( chk_serial != 6)
{
if ( chk_serial == 0){
if (Serial.available() > 0) {
car_type = Serial.readStringUntil('\n');
Serial.println("car_rec");
chk_serial = 1;
}
}
if ( chk_serial == 1)
{
if (Serial.available() > 0) {
water_cycle = Serial.readStringUntil('\n').toInt();
Serial.println("wsc_rec");
chk_serial = 2;
}
}
if ( chk_serial == 2)
{
if (Serial.available() > 0) {
soap_cycle = Serial.readStringUntil('\n').toInt();
Serial.println("ssc_rec");
chk_serial = 3;
}
}
if ( chk_serial == 3)
{
if (Serial.available() > 0) {
w_s_delay = Serial.readStringUntil('\n').toInt();
Serial.println("dw_rec");
chk_serial = 4;
}
}
if ( chk_serial == 4)
{
if (Serial.available() > 0) {
s_w_delay = Serial.readStringUntil('\n').toInt();
Serial.println("ds_rec");
chk_serial = 5;
}
}
if ( chk_serial == 5)
{
if (Serial.available() > 0) {
total_cycle = Serial.readStringUntil('\n').toInt();
Serial.println("oc_rec");
chk_serial = 6;
}
}
}
Filenam: send_gui_parameters.ino
void send_initial_par_to_pi()
{
int chk = 0;
while (chk == 0)
{
Serial.println(water_level_s);
Serial.println("");
if (Serial.available() > 0)
{
String reply = Serial.readStringUntil('\n');
if (reply == "PiRec0")
{
chk = 1;
}
}
}
while (chk == 1)
{
Serial.println(soap_level_s);
Serial.println("");
if (Serial.available() > 0)
{
String reply = Serial.readStringUntil('\n');
if (reply == "PiRec1")
{
chk = 2;
}
}
}
while (chk == 2)
{
Serial.print("t");
Serial.println(temperature);
Serial.println("");
if (Serial.available() > 0)
{
String reply = Serial.readStringUntil('\n');
if (reply == "PiRec2")
{
chk = 3;
}
}
}
while (chk == 3)
{
Serial.print("h");
Serial.println(humidity);
Serial.println("");
if (Serial.available() > 0)
{
String reply = Serial.readStringUntil('\n');
if (reply == "PiRec3")
{
chk = 4;
}
}
}
while (chk == 4)
{
Serial.println(motor_s);
Serial.println("");
if (Serial.available() > 0)
{
String reply = Serial.readStringUntil('\n');
if (reply == "PiRec4")
{
chk = 5;
}
}
}
while (chk == 5)
{
Serial.println(home_sensor_s);
Serial.println("");
if (Serial.available() > 0)
{
String reply = Serial.readStringUntil('\n');
if (reply == "PiRec5")
{
chk = 6;
}
}
}
while (chk == 6)
{
Serial.println(forward_sensor_s);
Serial.println("");
if (Serial.available() > 0)
{
String reply = Serial.readStringUntil('\n');
if (reply == "PiRec6")
{
chk = 7;
}
}
}
while (chk == 7)
{
Serial.println(reverse_sensor_s);
Serial.println("");
if (Serial.available() > 0)
{
String reply = Serial.readStringUntil('\n');
if (reply == "PiRec7")
{
chk = 8;
}
}
}
while (chk == 8)
{
Serial.println(water_pump_s);
Serial.println("");
if (Serial.available() > 0)
{
String reply = Serial.readStringUntil('\n');
if (reply == "PiRec8")
{
chk = 9;
}
}
}
while (chk == 9)
{
Serial.println(soap_pump_s);
Serial.println("");
if (Serial.available() > 0)
{
String reply = Serial.readStringUntil('\n');
if (reply == "PiRec9")
{
chk = 10;
}
}
}
if (reply == "PiRec10")
{
chk = 11;
}
}
}
if (reply == "PiRec11")
{
chk = 12;
}
}
}
while (chk == 12)
{
Serial.println(finish_s);
Serial.println("");
if (Serial.available() > 0)
{
String reply = Serial.readStringUntil('\n');
if (reply == "PiRec12")
{
chk = 13;
}
}
}
Filename: soap_spray.ino
void soap_spray()
{
digitalWrite(relay_water_pump, HIGH);
while(check != 3)
{
digitalWrite(relay_water_pump, HIGH);
digitalWrite(relay_soap_pump, LOW);
water_pump_s = "WPF";
soap_pump_s = "SPO";
progress = "Soap Wash Cycle in Progress";
send_initial_par_to_pi();
motor_fwd();
if(!digitalRead(forward_limit_s))
{
while(!digitalRead(forward_limit_s))
{
}
check = 1;
while(digitalRead(reverse_limit_s))
{
digitalWrite(relay_soap_pump, LOW);
water_pump_s = "WPF";
soap_pump_s = "SPO";
send_initial_par_to_pi();
motor_bwd();
}
if(!digitalRead(reverse_limit_s))
{
while(!digitalRead(reverse_limit_s))
{
}
check = 2;
while(digitalRead(home_s))
{
digitalWrite(relay_soap_pump, LOW);
water_pump_s = "WPF";
soap_pump_s = "SPO";
send_initial_par_to_pi();
motor_fwd();
}
}
if(!digitalRead(home_s))
{
while(!digitalRead(home_s))
{
}
check = 3;
motor_stop();
}
}
}
}
Filename: temp_and_hum.ino
void temp_hum()
{
int data=DHT.read11(DHT_Pin);
int temp= DHT.temperature;
int hum=DHT.humidity;
temperature = String(temp);
humidity = String (hum);
if (temp < optimal_temperature1)
{
send_initial_par_to_pi();
all_good = false;
}
else if (temp >= optimal_temperature1 && temp <= optimal_temperature2)
{
send_initial_par_to_pi();
all_good = true;
}
else
{
send_initial_par_to_pi();
all_good = false;
Filename: vehicle_wash_process.ino
void vehicle_wash_process(int total_cycles, int water_cycles, int soap_cycles)
{
int total_c = 1;
int water_c = 1;
int soap_c = 1;
int prog = 0;
int w_prog = 0;
int s_prog = 0;
int w_prog2 = 0;
while (total_c <= total_cycles)
{
while (water_c <= water_cycles)
{
check = 1;
water_spray();
progress = "First Water Spray done";
send_initial_par_to_pi();
w_prog = (33 / ((total_cycles +1)-total_c)) * (1/((water_cycles + 1)- water_c));
prog = w_prog + s_prog + w_prog2;
percentage = String(prog);
send_initial_par_to_pi();
water_c++;
}
delay(w_s_delay*1000);
}
delay(s_w_delay*1000);
water_c = 1;
while (water_c <= water_cycles)
{
check = 1;
water_spray();
progress = "Second Water Spray done";
send_initial_par_to_pi();
w_prog2 = (33 / ((total_cycles +1)-total_c)) * (1/((water_cycles + 1)- water_c));
prog = w_prog + s_prog + w_prog2;
percentage = String(prog);
send_initial_par_to_pi();
water_c++;
total_c++;
water_c = 1;
soap_c = 1;
start = false;
}
Filename: water_and_soap_level.ino
void water_level()
{
long duration, distance;
digitalWrite(trigger, LOW);
delayMicroseconds(2);
digitalWrite(trigger, HIGH);
delayMicroseconds(5);
digitalWrite(trigger, LOW);
if (distance == 0)
{
water_level_s = "WLF";
send_initial_par_to_pi();
all_good = false;
}
if (distance <= optimal_water_level)
{
water_level_s = "WLH";
send_initial_par_to_pi();
if (all_good == true)
{
all_good = true;
}
else
{
all_good = false;
}
}
else if (distance != 0 && distance > optimal_water_level)
{
water_level_s = "WLL";
send_initial_par_to_pi();
all_good = false;
}
void soap_level()
{
long duration, distance;
digitalWrite(trigger2, LOW);
delayMicroseconds(2);
digitalWrite(trigger2, HIGH);
delayMicroseconds(5);
digitalWrite(trigger2, LOW);
if (distance == 0)
{
soap_level_s = "SLF";
send_initial_par_to_pi();
all_good = false;
}
Filename: water_spray.ino
void water_spray()
{
digitalWrite(relay_soap_pump, HIGH);
while(check != 3)
{
digitalWrite(relay_soap_pump, HIGH);
digitalWrite(relay_water_pump, LOW);
water_pump_s = "WPO";
soap_pump_s = "SPF";
progress = "Water Wash Cycle in Progress";
send_initial_par_to_pi();
motor_fwd();
if(!digitalRead(forward_limit_s))
{
while(!digitalRead(forward_limit_s))
{
}
check = 1;
while(digitalRead(reverse_limit_s))
{
digitalWrite(relay_water_pump, LOW);
water_pump_s = "WPO";
soap_pump_s = "SPF";
send_initial_par_to_pi();
motor_bwd();
}
if(!digitalRead(reverse_limit_s))
{
while(!digitalRead(reverse_limit_s))
{
}
check = 2;
while(digitalRead(home_s))
{
digitalWrite(relay_water_pump, LOW);
water_pump_s = "WPO";
soap_pump_s = "SPF";
send_initial_par_to_pi();
motor_fwd();
}
}
if(!digitalRead(home_s))
{
while(!digitalRead(home_s))
{
}
check = 3;
motor_stop();
}
}
}
}
Raspberry pi 4
Raspberry Pi 4 is used in this project to run GUI, which is a computationally extensive task.
It is also used to serially communicate with Arduino in the bi-directional mode so that it can
send the GUI parameters to Arduino and receive the progress and current operations from
Arduino. . Its specifications are shown below in the table below:
Table 2 Raspberry Pi 4 Specifications
Input Voltage 5v
Input current supply 3A
DC Voltage per I/O Pin 3.3v
Digital I/O Pins 54
Clock Speed 1.5 GHz
Weight 46 g
Dimensions 88 mm x 55mm x 19.5 mm
SD-Card support 32 GB
The relay modules are used in this project to control the water pump, soap pump, and axis
inverter. The two-channel active low relays are used as shown in the figure below:
The term active low means that this relay is turned on when a low voltage signal is applied
to its trigger pin, and the term two-channel means that this relay module consists of two
switches that two trigger pins can control. The specifications of the relay module are shown
in the table below:
Table 3 Relay module specifications
Trigger Voltage 5v
DC Switching Voltage 30v
AC Switching Voltage 250v AC
Maximum current 10 A
Trigger Level Active Low
The temperature sensor used in this project is DHT11. It is used to detect temperature and
atmospheric moisture. It has long-term stability and reliability.
This sensor consists of a resistive element and a sense of wet negative temperature
coefficient device. It has advantages like fast response, steadiness, and reliability. It has four
pins, and its specifications are shown in the table below:
Table 4 DHT11 specifications
Name DHT-11
Input Voltage 5V
Humidity Range 20 - 90%
Temperature Range 0 – 50 C
Ultrasonic Sensor
The ultrasonic sensor is used in this project to find the water and the soap level. The model
used for the ultrasonic sensor is the HC-SRO4 ultrasonic module, as shown below:
The specifications of the ultrasonic sensor are shown in the table below:
Table 5 Ultrasonic sensor specifications
Power supply 5v dc
Current 15ma
Distance Range 2cm – 400cm
Dimensions 45 mm x 20mm x 15 mm
Variables used in the project
There are different variables declared and used to complete the scope of this project. These
variables are discussed in the tables shown below:
GUI Features
GUI performs bi-directional communication, which means it sends data to Arduino, takes
signals from the Arduino, and displays it on GUI. GUI has several sections that take inputs
which includes Car Type. We have allotted three options for car type, i.e., MiniCar, Sedan,
and MPV. The Arduino's acknowledgment will display the sensor, pump and motor status,
and soap and water level status. Furthermore, the current status of the process, progress, and
the finish message are also displayed on the GUI.
Sections of GUI
GUI is particularly divided into three frames top, middle and bottom. Each frame has its
own subdivisions of frame known as left, right, and center. Below we will discuss each
frame.
Top Frame
Figure 18 Top Frame of GUI
In the top frame, we have further divisions of frames into top Right, top Left, and top
Center, which contain sensor status, water level, and temperature, respectively.
Middle Frame
In the middle frame, we have further divisions of frames into middle Right, middle Left, and
middle Center, which contains pump and motor sensor status, soap level, and humidity,
respectively.
Bottom Frame
In the bottom frame, we have further divisions of frames into the bottom Right and bottom
Left. Frame bottom Right contains a progress bar, current operation status, and fault
messages, while Frame bottom Left contains parameters and combo Boxes for each
parameter, respectively.
How to Run the Project
The folder named “Smart Car Wash data” is provided by the vendor, which contains all
codes, Proteus simulations, installation files, and libraries. To run the Arduino sketch,
perform the following steps.
Open the ino file named “car_wash_code” present in the following directory
\Smart Car Wash data\Codes\Arduino code\car_wash_code
Run and flash it (See below: “How to flash Arduino Programs into Arduino
Microcontroller” for steps to flash) on the Arduino MEGA. Make sure that the
components are connected with Arduino according to the schematics shown in the
below headings.
Place the folder named “gui” in the raspberry pi and open the “final_gui.py” file
with “Python 3” or “Thonny IDE.” This will load the GUI on the screen.
The directory for the “gui” file is below:
Smart Car Wash data\Codes\Raspberry pi code\gui
Arduino IDE
Download and Install Arduino IDE. Install all the relevant libraries as defined in this book.
Open Arduino Code
Now open “car_wash_code.ino,” this is the main file, and all others are functions files.
Required Libraries
There are a few Proteus components libraries that must be included in Proteus before
running the schematic, as shown below:
These libraries are provided by the vendor in a folder named “Proteus Libraries.” All need to
be done is to copy those libraries to the Proteus directory i.e.
“C:\Program Files (x86)\Labcenter Electronics\Proteus 8 Professional\LIBRARY” as
shown below:
Proteus Simulation
The Proteus simulation used in this project is shown below:
Figure 27 Proteus simulation
For this simulation to run, a hex file is to be placed in the Arduino Mega 2560 as well as the
two Ultrasonic sensors named Water Level and the Soap Level by double-clicking on them
and then placing the hex file in the locations as shown below:
Similarly, the hex file location for Arduino Mega 2560 is as below:
Figure 29 Arduino Mega 2560 hex file location
The hex files are provided by the vendor in the folder named “HEX Files.”
Accessing Raspberry Pi For Remote GUI
Raspberry Pi is set up remotely to run Graphical User Interface (GUI) on a remote desktop.
For this purpose, the following configuration needs to be done.
Login to Raspberry Pi
Raspberry Pi login window will pop up running on the IP address provided by the cell phone
hotspot. Enter the username, which is by default “pi,” and the password set for pi.