Running ZeroTier On the Raspberry Pi 4

Our next step in the Raspberry Pi training program is to get zero tiers up and run on a Raspberry Pi 4. How to utilize a Raspberry Pi to measure internet speed and store the results in Grafana or Onedrive was the topic of the last piece. During the project, you will discover how to install ZeroTier on a Raspberry Pi and get it up and running. We will also learn how to set up a firewall to secure our network.

Where To Buy?
No.ComponentsDistributorLink To Buy
1Raspberry Pi 4AmazonBuy Now

Components

  • Raspberry pi 4

  • Power supply

  • Ethernet or wifi

What is zeroTier

ZeroTier is a software that provides a streamlined web-based interface for constructing virtual networks connecting various gadgets. Somewhat akin to configuring a virtual private network on a Raspberry Pi, these networks exist only in cyberspace. The process of provisioning, however, is much easier, especially when dealing with several devices.

Using a decentralized system, all of your gadgets will connect. The end-to-end encryption used to protect these connections helps ensure that your data remains private at all times.

ZeroTier can be used on various platforms, from computers to mobile phones. Its cross-platform compatibility with Unix, Microsoft, and macintosh means you can set up a virtual connection without worrying about whether or not your hardware will be able to connect to it.

The ZeroTier business model is "freemium." Using our free plan, you can connect up to 50 approved devices to the virtual network.

Retrieving your ZeroTier Network ID

You need to create an account on the ZeroTier website before you can use the program on your Raspberry Pi. This is because virtual network administration is performed through their website.

You may manage your entire virtual network from one central web-based console, including assigning permanent IP addresses to individual devices.

Registration on the ZeroTier hub website is required before a network ID can be generated. Access your virtual networks with this web-based interface. Go to ZeroTier Central on whichever browser you like. When you go to the site, look for the "Register" button so you can start the account creation process.

Sign up for ZeroTier by providing the necessary information on the supplied registration form. After you've finished filling out the form, hit the "Register" button at the bottom.

Your account won't be active until you confirm your email address after signing up for it. 

The following window will appear once you've created an account and logged into the web interface. Hit the "Create A Network" button in the screen's center to get started.

When you initially visit ZeroTier and click the button, your first network will automatically generate. The network identification number is listed here. We require this identifier to link your Raspberry Pi to the ZeroTier virtual network. Keep this ID in a safe place; we'll need it soon. Select the entry to change the network's settings, such as the name.

Listed below are the default configuration options for your ZeroTier system. You can modify the network's name, provide a description, and adjust its security level using these options. In addition to the IP subnet, ZeroTier gives you control over many other virtual network features.

Installing ZeroTier to the Raspberry Pi

We can move on now that you've joined ZeroTier and have your network ID. In this part, you'll learn how to download and install ZeroTier on your pi device.

First, let's check that the software on your pi Device is up to date.

To be up-to-date, we need to run the following two instructions for the item list and all installed modules.

sudo apt update

sudo apt upgrade

After adding the GPG key, we can install ZeroTier via their installation repository on our pi Device. With this key, we can ensure that the tools we're installing are directly from ZeroTier and don't include any malicious code. To obtain the GPG key via their repo, type the following code and store the contents of the "de-armored" file in the "/usr/share/keyrings/" folder.

curl https://raw.githubusercontent.com/zerotier/ZeroTierOne/master/doc/contact%40zerotier.com.gpg | gpg --dearmor | sudo tee /usr/share/keyrings/zerotierone-archive-keyring.gpg >/dev/null

Now that the GPG key has been inserted, a source list containing the ZeroTier repository must be compiled. First, we need to create a shell variable named "RELEASE" and assign it the operating system's internal codename. To construct the proper URLs for the ZeroTier repo in the subsequent steps, we will execute the following command.

RELEASE=$(lsb_release -cs)

Once we have the shell variable configured, we can utilize it to construct the relevant ZeroTier repo Urls for the Operating system. We finally save this string in the "/etc/apt/sources.list.d/" folder under the name "zerotier.list."

echo "deb [signed-by=/usr/share/keyrings/zerotierone-archive-keyring.gpg] http://download.zerotier.com/debian/$RELEASE $RELEASE main" | sudo tee /etc/apt/sources.list.d/zerotier.list

The next time you refresh the Raspberry Pi's packages lists, it will pull ZeroTier directly from this location.

Since we have modified the Rpi's source code, we must revise the list of installed packages. Using the command line, you could change your system's component list.

sudo apt update

After updating, we can use the command beforehand to download the ZeroTier package onto our RPi.

sudo apt install -y zerotier-one

ZeroTier can be set up to automatically launch on system startup as part of the setup procedure.

Running ZeroTier on Raspberry Pi 4

Having finished the ZeroTier installation on our RPi, we can now link to the networking we created in the introduction. First, make sure you get the network's identifier handy.

To connect the RPi to the network, we must use the ZeroTier Command line. You can utilize the following code to accomplish this. As a first step, swap out "[NETWORKID]" for the ID you gathered previously in this tutorial.

sudo zerotier-cli join [NETWORKID]

So after this message, your RPi should've just joined the ZeroTier channel.

Joining the ZeroTier channel doesn't make your machine an official part of the network until you verify it. To accomplish this, you must go back to a ZeroTier Main dashboard and change your network configuration. You can also access the site via the following Link, where you should substitute your network Address for "[NETWORKID].

https://my.zerotier.com/network/[NETWORKID]

The "Members" portion is located toward the bottom of the managerial section for the ZeroTier system on the RPi.

  1. You'll need to select the "Auth" box to tick here after identifying the machine you added. As a result, your RPi can communicate with other gadgets on the same network.

  2. A machine through your ZeroTier channel can be located using the information in the "Address" column. The "sudo zerotier-cli status" prompt will cause the RPi to display this data.

  3. The Name/Description field can be used to assign a memorable label to this innovative gadget for future reference.

  4. Lastly, take a peek at the "Managed IPs" section.

If an IP address has been assigned to the gadget, it will appear in this column. These IP addresses will allow you to gain access to that machine. This column can specify which device will receive the IP address. If you're trying to get an Internet address for a newly approved source, be patient; it could take a few minutes.

As soon as your RPi executes the command below, you will know it is linked to the ZeroTier channel. Using this prompt, you can see a complete list of the tracks to which the ZeroTier configuration is currently connected, along with information about the health of those connections.

sudo zerotier-cli listnetworks

Whenever your RPi successfully connects to the ZeroTier networks, you must see something similar to what is shown below. The last number is Pi's Internet protocol address within the VPN connection.

Connecting your RPi to your ZeroTier network must now be complete.

Connecting to other gadgets on the VPN connection is now possible. Having the device's Internet protocol is all that's required. The ZeroTier management console is the quickest way to learn which IP addresses are assigned to particular gadgets. 

Protecting your Raspberry Pi with UFW

Syncthing is a piece of software developed specifically for real-time file synchronization between several devices like the RPi. TLS is used to synchronize data among nodes. Thanks to encryption, the data will be safe and private in transit, making it more challenging to steal. Every node must prove its identity with a rock-solid cryptographic certificate. A connection will be denied to a node if it does not present a valid certificate, preventing unauthorized access. Files on your Microsoft, Macintosh, or Unix computer can be synchronized with your Raspberry Pi via Syncthing. Simple Syncthing apps are accessible for all of these platforms.

Setting Up Syncthing on a Raspberry Pi

Here you can find detailed instructions for setting up your RPi with the Syncthing program. For the program to be installed, we must first add the program's PGP keys and the package repo as possible sources.

We need to upgrade our Rpi before downloading the files synchronization program. We can use the following two commands to keep our RPi up to date.

sudo apt update

sudo apt full-upgrade

Following this, check that the apt-transport-HTTP package has been successfully installed. When using the installer, you can now access sources that utilize the secure Secure protocols, thanks to this package's inclusion. It's not possible to do this by default. This is included by default in most modern operating systems, but it may be missing from lightweight distributions like Raspberry Pi OS Lite. Executing the line below will install the necessary package.

sudo apt install apt-transport-HTTPS

Finally, the Syncthing credentials may be added to our keyrings folder. The purpose of these keys is to verify the authenticity and integrity of the packages we install before trusting them. To obtain the credentials, execute the command that follows on the RPi.

curl -s https://syncthing.net/release-key.txt | gpg --dearmor | sudo tee /usr/share/keyrings/syncthing-archive-keyring.gpg >/dev/null

Since the key has been included, the repo itself may be included. The RPi project will use the Syncthing program, namely the stable release. Use the following command to include the repo in the list of sources.

echo "deb [signed-by=/usr/share/keyrings/syncthing-archive-keyring.gpg] https://apt.syncthing.net/ syncthing stable" | sudo tee /etc/apt/sources.list.d/syncthing.list

We have to refresh the installation list before installing Syncthing from the repo. We must revise the list for the package manager to use our different sources. To update your RPI, type the following command into your device's terminal.

sudo apt update

Let's finish setting up our RPi by installing the Syncthing app. Now that the package repository has been added, the program can be installed with a single command.

sudo apt install syncthing

Permitting Third-Party Access to the Syncthing Graphical Interface

The Syncthing web application will only be accessible while close to the device. Those using a Raspberry Pi without a monitor or keyboard would have a very frustrating time if this were the case, but we can change the setup to allow external access.

The first order of business is to discover the RPi's actual local network address. Before proceeding, please ensure that your Rpi has been assigned a permanent IP address. This command lets you find your Pi's local IP address.

hostname –I

To move on, a single iteration of Syncthing must be run to create initial configuration files. The RPI user will be used solely in this tutorial to launch Syncthing.

Syncthing

Press CTRL + C to exit the program after the first launch.

The necessary configurations for Syncthing will be generated after the first execution. The Syncthing program must be launched in the context of the pi user for this configuration file to take effect. With nano editor, start editing the necessary configuration file with the line below.

nano ~/.config/syncthing/config.xml

Locate the following code in this script with the searching key CTRL + W to quickly locate this sentence.

127.0.0.1:8384

This line needs to have the local Internet protocol of our Pi substituted for the default local Internet address (127.0.0.1). For instance, with our Pi's IP address, this code would become something like this.

192.168.0.193:8384

We are limiting our access to people in the same local area network by use of the local Internet address. Alternatively, you can use the internet address "0.0.0.0" to grant access to every IP. Following the successful IP address change, save changes to the script.

Installing Syncthing on a Raspberry Pi as a Web Service

One final step is necessary now that the Syncthing us may be accessed from devices other than the RPi. This responsibility includes developing and launching a system for the program. The Service will enable Syncthing to launch automatically at system boot and be halted and started quickly.

Once again, we'll use nano to make the necessary changes to the Service's configuration file. The Syncthing authorized GitHub is the source for the application we will be developing. To start adding content to the file in "/lib/systemd/system," run the following command.

sudo nano /lib/systemd/system/syncthing.service

copy lines below and paste them to this file.

[Unit]

Description=Syncthing - Open Source Continuous File Synchronization

Documentation=man:syncthing(1)

After=network.target

[Service]

User=pi

ExecStart=/usr/bin/syncthing -no-browser -no-restart -logflags=0

Restart=on-failure

RestartSec=5

SuccessExitStatus=3 4

RestartForceExitStatus=3 4

# Hardening

ProtectSystem=full

PrivateTmp=true

SystemCallArchitectures=native

MemoryDenyWriteExecute=true

NoNewPrivileges=true

[Install]

WantedBy=multi-user.target

Those lines specify how our Rpi's OS must deal with Syncthing. When you're done adding lines, save the file. We could now set up our Service to automatically launch at system startup. Enter this command and hit enter.

Sudo systemctl enable syncthing

Let's run the Service to use the Syncthing internet UI. Once again, the systemctl tool will need to be used to kick off the Service.

sudo systemctl start syncthing

The Syncthing program on the RPi should be checked to ensure it has begun. Using the below program, we can make sure of that.

sudo systemctl status syncthing

The notification should read as follows if the Service was successfully started and is now active.

Web-based Syncthing management through RPi

If everything goes smoothly, you should utilize the Syncthing program on the RPi. Now that the hardware has been added, we can move on to configure the program and synchronize our data. We'll break this up into chunks for easy reading. The web-based user interface makes installing and linking devices a breeze.

Establishing a Link to the Syncthing Online Control Panel

You'll need to launch the web-based interface in your preferred internet browser to begin using it. The Internet address of the RPi is required to use the web-based interface. Using the Url, navigate to the following location in your preferred internet browser.

http://[PIIPADDRESS]:8384

Since the Syncthing program only listens on port 8384, you mustn't remove it from the end of the string.

After creating login details, you will be prompted to sign in before proceeding to the next step.

Safeguarding Syncthing's User Interface

There is no predetermined login information for Syncthing, meaning anyone with access to the UI can change your preferences. Login credentials can be set up to prevent unauthorized users from wreaking havoc.

You will be warned of the potential risks if you have never specified the login details. The "Settings" button on this caution will take us directly to the configuration page.

The configurations page can also be accessed by choosing the "Actions" menu box in the upper right corner and then choosing "Configurations" if this notice isn't shown.

Navigate to the "GUI" tab on the popup settings page. Access this window's account by selecting "GUI" from the window's header.

Login credentials are required to access this page. Passwords should be firm and difficult to guess. Use a mix of alphabetic characters, numeric digits, and special characters. After inputting each, hit the "Save" option to keep your modifications.

After resetting your password, this website will log you out. You'll need to sign in with your new credentials each time you access Syncthing's graphical interface.

How to Get the Syncthing ID of a Device

For Syncthing to function, it must create a random identifier for each connected device. Adding the other device's ID to your own is necessary for sharing information between devices. The RPi Syncthing installation's unique identifier can be located via the web interface.

To return to the main page of the web interface, select "Actions" from the toggle menu in the top right. Select "Show ID" from the selection menu to open the desired dialogue box.

The identification string and corresponding QR code are displayed below. The ideal identifier length is between 50 and 56 characters and may incorporate digits, letters, and hyphens. System-wise, the hyphens are disregarded, but they improve readability. If you want to connect your Raspberry Pi to additional devices, you'll need to give each of them the unique ID assigned to your Pi. You must also include their identification number. Syncthing's mechanism for linking many gadgets to a single pool requires the ID.

Incorporating a New Device into Your Raspberry Pi's Syncthing Network

We've covered how to get your gadget id Number, so now we'll cover adding a new one. Keep in mind that the identifier for your RPi must be entered into whatever gadget you are installing. If not, communication between the devices will be impossible.

The "Add Remote Device" button may be in the lower right corner of the Syncthing UI. When we click this option, we'll be taken to a dialogue where we can add a gadget to our Syncthing collection.

You can add any unique Id to your pool from this dialogue box. Enter the identifier for the gadget you wish to link to the top textbox. Despite its length, the ID is easily copied and pasted. After that, you can connect the device by clicking the "Save" option.

Incorporating each other's Syncthing server Identifiers should result in a successful connection.

Replicating a Directory Across All of Your Devices

Now that we have a device linked to the RPi Syncthing, you can test directory sharing. In this particular chunk, the default directory will suffice. Here, we keep our sync files in a folder called "/home/pi/sync" on our RPi.

Select the "Edit" button next to a directory to change its share settings. We can access the folder's sharing settings dialog by clicking this option and making the necessary changes.

We must navigate to the Share tab under the file settings dialogue. Select the "Share" tab to switch to this view.

The dialog box lets you pick which gadgets will access the shared folder. As soon as you've decided which devices you wish to sync with, choose the "Save" option.

When syncing with the other gadget, keep in mind that you'll need to accept the shared folder on that gadget before synchronizing can begin.

Your directory should have started syncing immediately. When the syncing process is complete, the guide and the gadget should be labeled "Up to current."

Conclusion

Having ZeroTier Syncthing installed on your RPi and linked to a VPN, you may now sync data across machines. If you're looking for a basic virtual network solution, ZeroTier is it. And the best part is that it offers an ideally enough free plan for most people's fundamental needs. Additionally, Syncthing is a user-friendly software that enables you to synchronize folders across several gadgets. The program is among the best methods for allowing many computers to maintain directory consistency in real time. No longer will you have to trust a remote service like Cloud Servers to keep your data safe.

Internet Speed Monitor Using Raspberry Pi 4

Following up on our Raspberry Pi programming course is the next lesson. In the previous post, we learned how to construct an FM radio using a Raspberry Pi. Analog FM broadcasting's circuit construction was also studied in detail. How to use a Raspberry Pi as an internet speed meter and save the data in Grafana or Google Drive is the subject of this article.

You can use this article if you want to keep track of how your downloads, uploads, and ping speeds change over time, and it's easy to use. In addition, you can use this to determine when your internet is at its busiest or if your internet speed has deteriorated. We'll demonstrate how to use Ookla's Internet speed test command-line interface in conjunction with Python code to create an internet speed meter.

The connection speed monitor will employ the Internet speed Command line interface to keep tabs on your connectivity.

Components

  • Raspberry pi 4

  • Micro SD card

  • USB drive

  • Ethernet cable or Wi-Fi

Installing the Speed test CLI

The first step in configuring the RPi to monitoring system the Internet's performance is to ensure the Raspberry is updated. There is an easy way for this using the command line:

sudo apt-get update

sudo apt-get upgrade

To add a repo for the Internet speed Command line software, we have to download a few additional packages. apt-transport-https, dirmngr, & gnupg1 may all be installed on your RPi by running the commands listed below.

sudo apt install apt-transport-https gnupg1 dirmngr

The apt software may now use the HTTPS secure protocols thanks to the apt-transport-HTTPS module. Apt will fail to connect to Ookla's software repository if it doesn't have it. Our Speedtest.net services and your RPi must communicate securely, therefore we'll also set up gnupg1.

Lastly, the dirmngr software is installed. This software is used to add the package repositories to the Rpi's source list. Now that we've installed the necessary tools, we can import the GPG keys for Ookla's Performance test repository into our keychain and start running tests. The performance test CLI interface cannot be downloaded to our RPi without this passcode.

curl -L https://packagecloud.io/ookla/speedtest-cli/gpgkey | gpg --dearmor | sudo tee /usr/share/keyrings/speedtestcli-archive-keyring.gpg >/dev/null

The Ookla repo must be added to our list of sources next. The Performance test CLI cannot be installed on our RPi without the repo being added. The command to add this repo is as follows.

echo "deb [signed-by=/usr/share/keyrings/speedtestcli-archive-keyring.gpg] https://packagecloud.io/ookla/speedtest-cli/debian/ $(lsb_release -cs) main" | sudo tee  /etc/apt/sources.list.d/speedtest.list

You'll see that "$(LSB release -cs)" is used in the command. Input the title of the RPi Operating system release using this string of text in the prompt. We have to upgrade our packages list because we have a new module repository. Simply use the following command to update the list of installed packages.

sudo apt update

Our RPi is now equipped with the official Ookla Connection speed CLI. Installing the software on your device is as simple as running the command below.

sudo apt install speed test

We may now run a speed test on your Raspberry Pi to ensure that we have successfully installed the program. To begin the speed test, enter the following command into your terminal.

Speedtest

There are a few terms of service you must agree to while using the speed test app on your Raspberry Pi. Simply hit "YES" accompanied by the Return key to go past this warning.

Writing our Speed Test Python Script

On our RPi, we can now begin writing our Program code that will actively check the speed of our downloads and uploads. The command prompt will get us started on writing our Program code to check the connection speed on the RPi.

cd ~

nano speedtest.py

Type the code below in this file. We'll walk you through each component of the program, so you can get a sense of how it all works.

import os

import re

import subprocess

import time

This script will use all of the packages listed in these four lines. We'll discuss exactly each of the modules that will be put to use in the following paragraphs.

Import os: 

The script uses the operating system package to interface with the os. This package will be used to see if a file already exists as part of this program.

Import re: 

This repackage provides a library for managing pattern searching so that we may simply perform regular expressions. The Speed test command line provides us with all the information we need to find our desired values.

Import subprocess: 

To run another python code, this script needs the subprocess package. To use the subprocess module, we will be able to launch the Internet speed Command line software and receive the results.

Import time: 

We make use of the time package to keep track of the dates and times of all Speed test Command line calls. We will be able to keep track of the performance over time thanks to this package.

response = subprocess.Popen('/usr/bin/speedtest --accept-license --accept-gdpr', shell=True, stdout=subprocess.PIPE).stdout.read().decode('utf-8')

Subprocess is used to initiate a request to the Internet speed command line and instruct it to route the output of the speed test to stdout in this section of code. stdout.read is used to output data (). Finally, we decode('UTF-8') our reply variables to make it usable as a Py object after the call to the Speed test Command line.

ping = re.search('Latency:\s+(.*?)\s', response, re.MULTILINE)

download = re.search('Download:\s+(.*?)\s', response, re.MULTILINE)

upload = re.search('Upload:\s+(.*?)\s', response, re.MULTILINE)

jitter = re.search('\((.*?)\s.+jitter\)\s', response, re.MULTILINE)

Each of these 3 pieces of code accomplishes the same task. Every text fragment has a unique number adjacent to it, which they can deduce by running a mathematical equation on it using the re library. A ping lookup for "Latency: 47.943 ms" returns "Latency: 47.943 ms," with only the value between the characters.

ping = ping.group(1)

download = download.group(1)

upload = upload.group(1)

jitter = jitter.group(1)

To retrieve the right numbers, we must utilize the ".group()" function. The CSV file will be able to contain the results of the Speed test Command line software output, thanks to this method.

try:

    f = open('/home/pi/speedtest/speedtest.csv', 'a+')

    if os.stat('/home/pi/speed test/speedtest.csv').st_size == 0:

            f.write('Date,Time,Ping (ms),Jitter (ms),Download (Mbps),Upload (Mbps)\r\n')

except:

    pass

This is a simple piece of code. The program is contained within a try statement, which ensures that the program will continue to run even if an error occurs. First, we retrieve our speedtest.csv document in the try block.

If indeed the document does not already exist, "a+" in the parameters tells it that we wish to generate it and add any new content to what exists already. After that, we use the operating system package to determine the real size of our speedtest.csv documents. If indeed the file's contents are equal to zero, we can proceed. No action is required on our part if the document does not exist.

f.write('{},{},{},{},{},{}\r\n'.format(time.strftime('%m/%d/%y'), time.strftime('%H:%M'), ping, jitter, download, upload))

There are commas to differentiate each record's information. When formatting a string, we utilize the time strftime() method to include the time and current date. Our pings, downloads, and uploads will follow. Example output.

This is what your program should look like when you are done writing it down.

import os

import re

import subprocess

import time

response = subprocess.Popen('/usr/bin/speedtest --accept-license --accept-gdpr', shell=True, stdout=subprocess.PIPE).stdout.read().decode('UTF-8')

ping = re.search('Latency:\s+(.*?)\s', response, re.MULTILINE)

download = re.search('Download:\s+(.*?)\s', response, re.MULTILINE)

upload = re.search('Upload:\s+(.*?)\s', response, re.MULTILINE)

jitter = re.search('\((.*?)\s.+jitter\)\s', response, re.MULTILINE)

ping = ping.group(1)

download = download.group(1)

upload = upload.group(1)

jitter = jitter.group(1)

try:

    f = open('/home/pi/speedtest/speedtest.csv', 'a+')

    if os.stat('/home/pi/speed test/speedtest.csv').st_size == 0:

            f.write('Date,Time,Ping (ms),Jitter (ms),Download (Mbps),Upload (Mbps)\r\n')

except:

    pass

f.write('{},{},{},{},{},{}\r\n'.format(time.strftime('%m/%d/%y'), time.strftime('%H:%M'), ping, jitter, download, upload))

you can save the script. Once our script is complete, we will create a directory in which to keep the speedtest.csv data. Make this directory by typing the command below.

mkdir ~/speedtest

After we have created the necessary directory, we can execute the program. The command below can be used to run our program and see if it works as expected.

python3 ~/speedtest.py

Open the newly generated speedtest.csv file to see the results of the script's execution.  Let's see whether we can open this document on the RPi with the command below.

nano ~/speedtest/speedtest.csv

You should be able to find anything similar to this in that file. A few rows of records and the column headings.

It is possible to use this guide in two ways. Either utilize Influx Database and Grafana or use google Drive to synchronize the data to Google Account using Influx Database and Grafana.

How to View Your Speedtest Results in Grafana?

We'll teach you to easily plot your performance test data using Grafana throughout this section. To conduct data analytics, load up metrics that make some sense of the immense amount of data, and track our applications with the aid of cool configurable panels, we use Grafana, a free software solution that is free and open source.  In addition to the fact that Grafana is an open-source platform, we may create our plugins to integrate with a variety of data sources.

Technically known as time series analytics, the technology aids in the study, analysis, and monitoring of data across time. By giving relative data, it aids us in tracking user activity, app behavior patterns, error rate, error kind, and contextual circumstances in operation or a pre-production scenario.

Organizations that are concerned about security or other factors do not have to use the vendor cloud because the project can be implemented on-premise. Over the years, this framework has become an industry standard and is used by companies like PayPal, eBay, Intel, and many more. In a moment, I'll go over some real-world examples from the industry.

Grafana Platform & Enterprise are 2 extra services provided by the Grafana developers for companies in addition to the free software core product. What do they do? The remainder of this post will go into greater detail regarding this. In the meantime, how about we take a closer look at the tool's capabilities and architecture flow, starting with an explanation of what a panel is? & How does it all work? '

Grafana Panel: What Is It?

They use sources of data like Graphite and Prometheus as well as Influx database and Elastic Search to populate the panels. Grafana has built-in compatibility for a wide range of data sources, including these.

All of the common charts and graphs that a business needs to analyze data can be found in the panel's visualization options, including heat maps, scatterplots, and more. On the grid of a dashboard, there are several discrete panels. There are a variety of features available on each panel.

What are Grafana's Capabilities?

Let's have a look at the fully accessible panel framework's capabilities. Our application's metrics are handled via an open platform. This data can be analyzed through the use of metrics in a variety of ways.

The panel is well-equipped to generate a sense of complicated data, and it is constantly changing. Geo-mapping, heat maps, scatterplots, and more can be displayed with graphs in a variety of ways. Our business needs can be met by a wide range of data presentation possibilities provided by the software.

As soon as a predetermined event occurs, an alert is set up and triggered. Slack or any other communication tool used by the monitoring team might be alerted to these events. Grafana is pre-installed with support for about a dozen different types of databases. And there is a slew of more, all made possible thanks to plugins.

It can be hosted on-premises or in the cloud. Custom data can be retrieved using built-in Graphite support and expressions such as "add," "filter," "average," "minimum," and "maximum" functions. Graphite is a chemical element. Later, I'll address that. Influx database, Prometheus, Elastic Search, and Cloud Monitoring are also included. Up front, I'll cover it all.

What is the purpose of Grafana Cloud?

A cloud-native, highly accessible, quick, and completely open SaaS metric framework, Grafana Cloud As a result, individuals who don't want to host the solution on their own and prefer to avoid the headache of managing their deployment infrastructure may find this useful. It's a Kubernetes-based service. Prometheus and Graphite back end is supported. This gives us two options: either use Grafana on-premises or both.

Setting up the Influx Database for our Connection Speed Monitoring

Installing Influx Database on your RPi is a prerequisite for this stage of the internet speed monitoring guide. Our connection speed monitoring system sends data to this location, thus we'll be storing it here.

Influx database

Designed by Influx Intelligence, Influx Database is a free and open-source time series system built in Go. Time series data, such as that collected from sensors and IoT devices, may be accessed quickly and reliably with this system because of its focus on high-availability extraction and retention. As a Time Series Database, Influx Database is capable of storing up to several hundred thousand points each second. A SQL-like query language for time series data, the Influx Database was designed expressly for this purpose.

Why use Influx DB?

  • Shorter duration

  • Extensive research and analysis

  • Retention, ingestion, querying, and visualization are now all available through a single application programming interface in Influx Database.

  • Templates that are simple to create and distribute, thanks to the influx of DB templates

First, we'll fire up the Influx Database CLI tool by typing the command below. Using this application, we will be creating an online repository for our data.

There is no need to enter the passcode and username for Influx Database if you haven't set login. Establish a database with the name "internet speed" in it immediately. After typing CREATE DATABASE, the DB name, and pressing enter, the DB is ready to use.

CREATE DATABASE internet speed

Creating a user named "speed monitor" will be the next phase in working with the database. The passcode "pass" should be replaced by a more secure one. Privileges are not a concern at this time, as we shall take care of them in the following stage.

CREATE USER "speed monitor" WITH PASSWORD 'pass' Now assign the new "speed monitor" user all privileges to our "internet speed" database.

GRANT ALL ON "internet speed" to "speed monitor"

To shut off the application, type the command below.

Quit

Installing the Python package required to communicate with the Influx DB is the final step.

sudo apt install python3-influxdb

Saving our Speed Monitor Data to our Influx DB

Create a new Script file to start populating our Influx database now that it has been set up. If you've already read through the previous script, you won't have to go over anything new here.

rm ~/speedtest.py

nano ~/speedtest.py

To get started, we have to include all of the Python packages that we will be using in this file.

import re

import subprocess

from influxdb import InfluxDBClient

operating system and time have been eliminated, as seen. We no longer have to communicate with records, and the Influx database automatically timestamps data, therefore these two libraries are no longer required. After importing the "InfluxDBClient" for our Influx database server, we are ready to use it. The next phase is to launch the Speedtest Command line interface and process the results. Upon completion of this code snippet, we'll have all the information we need.

response = subprocess.Popen('/usr/bin/speedtest --accept-license --accept-gdpr',

                            shell=True, stdout=subprocess.PIPE).stdout.read().decode('utf-8')

ping = re.search('Latency:\s+(.*?)\s', response, re.MULTILINE)

download = re.search('Download:\s+(.*?)\s', response, re.MULTILINE)

upload = re.search('Upload:\s+(.*?)\s', response, re.MULTILINE)

jitter = re.search('\((.*?)\s.+jitter\)\s', response, re.MULTILINE)

ping = ping.group(1)

download = download.group(1)

upload = upload.group(1)

jitter = jitter.group(1)

Now everything gets a little more complicated. This data must be converted to a Py dictionary for us to use it. Because the library wants the information to be presented in a JSON-like form, this is an explanation.

speed_data = [

    {

        "measurement" : "internet_speed",

        "tags" : {

            "host": "Raspberrytheengineeringprojects"

        },

        "fields" : {

            "download": float(download),

            "upload": float(upload),

            "ping": float(ping),

            "jitter": float(jitter)

        }

    }

]

In this section, we established our dictionaries by the Influx database data model. "internet speed" is the title we assigned the metric. The tag "host" was also added so that if we were to manage numerous devices within the same DB, we could segregate them. After that, we enter the data we obtained in the preceding line of code, including the download speed, upload speed, and pings.

To make them into numbers, we use the float () method to turn our download, uploads, and pings parameters into strings. Grafana will read these as characters if we don't utilize the float () method. Now that we have all the information we need, we can begin using Influx Database. It is necessary to create an InfluxDBClient object and provide the network information.

Only the hostname, port number, user id, passcode, and DB name are passed to this method. You can refer to the official Python manual for Influx Database if you wish to know what information can be set.

client = InfluxDBClient('localhost', 8086, 'speedmonitor', 'pass', 'internetspeed')

"localhost" should be replaced with the Internet address of your Influx database server if it is hosted elsewhere. Change "pass" to the passcode you created earlier in this article. To send data to our Influx database server, we need to add a block of code like the one below to our existing codebase.

client.write_points(speed_data)

To send data to Influx Database, we only need to do that. Assuming you've entered every bit of code in the document, this should look something like this.

import re

import subprocess

from influxdb import InfluxDBClient

response = subprocess.Popen('/usr/bin/speedtest --accept-license --accept-gdpr',

                            shell=True, stdout=subprocess.PIPE).stdout.read().decode('UTF-8')

ping = re.search('Latency:\s+(.*?)\s', response, re.MULTILINE)

download = re.search('Download:\s+(.*?)\s', response, re.MULTILINE)

upload = re.search('Upload:\s+(.*?)\s', response, re.MULTILINE)

jitter = re.search('\((.*?)\s.+jitter\)\s', response, re.MULTILINE)

ping = ping.group(1)

download = download.group(1)

upload = upload.group(1)

jitter = jitter.group(1)

speed_data = [

    {

        "measurement" : "internet_speed",

        "tags" : {

            "host": "Raspberrytheengineeringprojects"

        },

        "fields" : {

            "download": float(download),

            "upload": float(upload),

            "ping": float(ping),

            "jitter": float(jitter)

        }

    }

]

client = InfluxDBClient('localhost', 8086, 'speed monitor', pass, 'internet speed')

client.write_points(speed_data)

Save the document to your computer.

Using Grafana to see our Connection Speed Stats

The database needs to be displayed in Grafana. All the information will be graphed and shown by using the Grafana application.

Grafana installation on the Raspberry Pi.

It's a fully accessible metric monitoring and data presentation package for people who aren't familiar with it. The purpose of this software is to aid in the visual representation of time-based information. To speed things up, Grafana entrusts most of the heavy lifting to the client, such as generating graphs. Since there are minimal data to analyze, the software can concentrate on giving information that can be used to create graphs.

Many various types of data sources are supported by Grafana, and you can set up warning rules for key metrics to be warned immediately if anything isn't quite right. The famous Influx Database is one of the available Grafana data capture options. Quick and "time series" oriented, Influx Database is a famous system for use with Grafana. Each register contains a timestamp.

Grafana is frequently used to keep tabs on system metrics like the temperatures of the equipment and how much of it is being used. In addition, it can be used to graph data, for example, the weather, across time. Grafana is an excellent tool for instantly presenting data from your Raspberry Pi.

Setting up a Raspberry Pi with Grafana

It's a good idea to double-check that all of the packages on your RPi are updated before beginning the Grafana installation. The 2 techniques listed below can be used to do this. The packages list will be updated, and all installed applications will be upgraded to the most recent versions using these instructions.

sudo apt update

sudo apt upgrade

The Grafana source repo must be added to the RPi before Grafana can be installed. As a prerequisite, we must add an APT password. Using the APT password, you can confirm that the modules you're installing originated from the Grafana packages service and are properly signed. The instruction to include the Grafana APT password to your RPi's keychain is as follows.

curl https://packages.grafana.com/gpg.key | gpg --dearmor | sudo tee /usr/share/keyrings/grafana-archive-keyrings.gpg >/dev/null

Once we've uploaded the password to our Raspberry, we're good to go with the Grafana repo as a resource for our software. Include this repo to the source list by running the command below on your RPi.

echo "deb [signed-by=/usr/share/keyrings/grafana-archive-keyrings.gpg] https://packages.grafana.com/oss/deb stable main" | sudo tee /etc/apt/sources.list.d/grafana.list

The RPi will automatically check the Grafana repo for new packages whenever you launch and upgrade them. An update is necessary because we've added new packages to our list. When using apt to perform an update, the most up-to-date package list is obtained from all available sources. To accomplish this, run the command below in the console of your Raspberry.

sudo apt update

Please keep in mind that Grafana can be installed on your RPI. Run the command below to install the newest release of Grafana on your computer.

sudo apt install grafana

Getting Grafana to start automatically at startup is the next step we need to take. Grafana includes a systemd service file, which is a godsend for those of us using it on Linux systems. All we have to do is execute the command below to make Grafana start automatically at system startup.

sudo systemctl enable grafana-server

The "grafana-server.service" services record will be enabled by this instruction to a network's service management. The Grafana server's service management will utilize this file as a reference guide. In the console of the Raspberry Pi, enter the following command to begin using Grafana's webserver.

sudo systemctl start grafana-server

Setting up the Grafana dashboard on your Pi 4 

Now that we've installed Grafana on your Pi 4, we can use its web interface to monitor your data. If you have a Raspberry Pi, the first thing we'll need to do is get its Internet address. Grafana on your local area network can be accessed remotely via this Internet protocol. The IP address of your Raspberry Pi may be found by typing the following code.

hostname –I

Static IPs are a good idea if you frequently need to connect to your Raspberry Pi. Make sure you have your Internet Protocol (IP) address available before visiting this URL. A web application for the Grafana dashboard can be found on line 3000 of the Rasp Internet address. "IPADDRESS>" should be replaced with your Internet address from earlier.

When you initially open Grafana, you'll get a login page. When you initially installed Grafana on the RPi, you were given the option of logging in with the default administrator account. The username and passcode are "admin" and "admin," respectively, for this account (1.). However, even though the passphrase is incredibly insecure, we'll be able to alter it right after this one. Grafana's "Login" tab can be clicked once the userid and passcode have been entered.

Grafana's online UI will prompt you to update the user's passcode upon the first login. You can skip this step if you like, but we don't encourage it. You must change the passcode as soon as possible due to its extreme insecurity. After entering a new pass, select the "Save" option to continue to the Grafana homepage.

The below screen will appear after you have signed in and updated the passcode. Now that you've reached this screen, you're ready to begin configuring the Grafana interface on your RPI.

Now that Grafana is installed on the RPi, you can access the online interface. To continue with this article, access the Grafana graphical interface once it has been installed. If you're not sure where it is, type http://localhost:3000 into your browser's address bar.

IPADDRESS:3000

A new information source must be added to Grafana's web app. ' The "Data Sources" menu selection can be accessed by clicking on the wheel on the left (1.). 

To continue, click "Add source of data" in the following menu.

Navigate to the "Add data" webpage then click the "Select" tab when you discover Influx Database.

We must now fill in the data regarding the Influx Database configuration. Enter the Influx Database Hyperlink first (1.). In our scenario, the RPi which we are using to execute the program is where this is located. Use the following Link if you're following suit.

http://localhost:8086

The credentials for our DB must then be entered (2.). The Db must be set to "internetspeed" if you closely followed our instructions. Last but not least, the passcode must be the one we mentioned; if you utilize our examples, it is "theengineeringprojects". The Username should be "speedmonitor,". After you've entered all the necessary data, select the "Save & Test" tab (3.)

The following step is to build a panel to show this information. Select the "Dashboard" option by hovering your cursor over the add (+) button in the navigation bar.

Select "Add Query" from the menu that appears over "New Panel."

Graph reading from our DB can now be configured. The metric name we want to use is "internetspeed," so click "choose measurement" (1.) after that (2.)

We must now establish the data collected that we want to examine after we have the metric set. The "value" wording adjacent to the field can be clicked (1.). Click "downloads," "uploads," or "ping" from the drop-down menu. We'll begin with "download" in this tutorial (2.).

After that, we'd like Grafana to consider each outcome as a separate entity. In the picking row, click on the add (+) tab to accomplish this (1.). In the pop-up, select "distinct" from "Aggregations" (2.).

If you want to comprehend this data better, it's time to give it a new name. Assign an alias to each field that accurately reflects what it contains (1.). "Download Pace," for example, is the name of the speed at which data is downloaded. It's time to repeat these procedures 7–9 till all three variables (downloads, uploads, and pings) have been included in the graph.

Add every field by clicking the wrench and wheel symbols on the navigation bar, and then click "Save".

Using the "Title" box (1.) allows you to enter the name of the graph's title. As a title, "Network Speed " was utilized in this case. The panel can be saved by tapping on the save option (2.)

Give your panel a name (1.). You have a complete creative license with this one. Our network bandwidth monitor was given the name "Network Speed Monitor" by us. Afterward, you may save this panel by selecting "Save" (2.).

Your statistics should now be visible on a visually appealing graph, assuming all went according to plan.

Grafana used to automate your Speed Monitor scripts

Making your program run on a regular schedule is as simple as automation.  The crontab is the simplest approach to schedule your script to execute regularly. On your RPi, you can change the crontab by typing the command below.

crontab –e

When asked which editor should use, we suggest nano because it's the simplest to learn and the most intuitive. The following cronjob should be added at the bottom of this file. Cronjobs are scheduled to run each half an hour by default. We advise using our Crontab generator if you'd like to experiment with alternative timings.

Exactly what does it mean to have a "Cron Job?"

Jobs are scheduled using Cron, which is built into Unix-like systems like Linux and its numerous variants. It is a time-based mechanism. Using the cron is a common approach to run instructions or bash scripts regularly. "Cron Jobs" refers to tasks that are scheduled using the "cron" utility. While using Unix-based systems like Raspbian, you'll quickly become dependent on cron jobs.

Using Google Drive to store your Internet Speed Readings

gDrive Installation and Compilation

It's easy to use gDrive, a cli program, to transmit to Google Account. Once you've got it established on the smartphone, it's a breeze to use. This instruction will explain to you how to use your personal Google accounts to develop the gDrive program on the RPi. The same procedures can be used to create gDrive for any os, even if this instruction concentrates on the RPi. 

Getting the Go Compiler installed

The Go engine must be installed on our device before we can assemble the gDrive program. Download the appropriate drivers from the official website whether you're working on a PC or Mac.

If you're working with a Linux distribution like Raspbian, the process becomes a little more complicated. Using a Linux terminal, type one of these commands. 

The Raspberry Pi can be used with this.

wget https://dl.google.com/go/go1.13.7.linux-armv6l.tar.gz -O go.tar.gz

a 64-bit version of Linux

wget https://dl.google.com/go/go1.13.7.linux-amd64.tar.gz -O go.tar.gz

After downloading the Go libraries, we must now unpack them to the root directory. 

sudo tar -C /usr/local -xzf go.tar.gz

Next, we'll see whether we can get the console to talk to Go. If we alter the shell aliases script, we can accomplish this goal. Shell will run automatically the script and pull in our updated path names.

nano ~/.bashrc

The following lines should be added to the end of this file. With these lines, we may execute the compiler instantly from the cli, without having to specify the directory to the engine.

export GOPATH=$HOME/go

export PATH=/usr/local/go/bin:$PATH:$GOPATH/bin

Now you may save the script.

source ~/.bashrc

Retrieving your Google Drive API Credentials

We require your Google Cloud Apis details before we can start with the gDrive program compilation. " Your project's name can be found on this webpage (1.). "gDrive-theengineeringprojects" shall be the name of our example.

For our project, we'll need to activate the Google Cloud Application programming interface first. In the Cloud Services panel, we can access the Google Cloud Application programming interface page. Select ENABLE from the drop-down menu.

When you get to the next screen, select the "Credentials" tab from the navigation bar (1.). "Config Permission SCREEN" needs to be clicked next to finish the process (2.).

You'll be prompted to select a "User Type" at this point. "External" is the only option available if you are not running a business (1.). Once you've made your choice, click "Start" to begin building your app (2.).

You'll need to give your app a name on this screen (1.). In this case, we'll use the name "gDrive theengineeringprojects" for the program.

To save the document, you simply need to type in a title for your program.

Return to the "Credentials" page, and then we'll be done.

The navigation bar makes it simple to return to the previous page.

Add credentials by clicking on this tab: "Create Credentials" (1.). When the pop-up displays, select the "OAuth user ID" option (2.).

Selecting an app type is what we need to do next. We chose "Other" since none of the other options were appropriate for the API's intended use. Once we've done that, we'll need to give this program a name. We'll just call it "gDrive theengineeringprojects" for the sake of simplicity. Once all of the information has been input, click the "Create" tab to begin the process.

You should now have both the client id and client secret.

In this article, you'll need each of these numbers at some point.

Setting up your API Keys for gDrive

We'll need to use git to download gDrive's source code before we can compile it. Before we can proceed, we need to install the git client on our computer. To install Git on a Debian-based operating system like Linux or Raspbian, you may either go to the main Git webpage or use the procedures below.

sudo apt update

Just type the command below and we'll be done in no time.

sudo apt install git

now clone git

git clone https://github.com/gdrive-org/gdrive

The next step is to update the program to reflect the new client password and session id. Make a copy of the "handlers meta.go" file in the cloned subdirectory and edit it with nano.

cd gdrive

nano handlers_drive.go

Change the collected details in the following statement of this file. Both your user id and password should be in your possession.

const ClientId = "367116221053-7n0vf5akeru7on6o2fjinrecpdoe99eg.apps.googleusercontent.com"

Substitute your login Credential here.

const ClientId = "YOURCLIENTID"

const ClientSecret = "1qsNodXNaWq1mQuBjUjmvhoO"

You can use your user password instead

const ClientSecret = "YOURCLIENTSECRET"

Save all the changes. Now it's time to execute the following code to get the additional modules needed to compile our updated version of gDrive using the Go engine.

go get github.com/prasmussen/gdrive

To get gDrive working on our device, simply enter the command shown below into your terminal.

go build -ldflags '-w -s'

It's time to get this thing working on the command line, so let's get started! We need to relocate the file to the root directory to use the gdrive inside the cli. To relocate the executables, type the command below.

sudo mv gdrive /usr/local/bin/gdrive

The final step is to provide the gdrive file with the ability to run.

sudo chmod a+x /usr/local/bin/gdrive

It's time to play around with gDrive

Now that your Google account is linked to the app, we can test the program gDrive. The gdrive instruction and the "list" parameter are required to get things started.

gdrive list

Following gDrive's list statement, you will be informed that authorization is necessary. There needs to be a Hyperlink at the bottom of the message. Using your Google acc, users must visit this Address and sign in. You'll get a security code if you perform the next few steps on the internet browser. Enter the verification code that you just copied into the terminal.

GDrive has been successfully installed onto your device if a listing of files is displayed. To see the ids for each of your directories, you can use this command. Using the IDs listed above, you can sync a specific folder.  The command below can be used to test syncing a folder. You can replace Folder> with the path to your synchronized folders.

The identification of a directory that you obtained with the grdive listing commands must be substituted for GOOGLEFOLDERID>.

Uploading Speed Test Data to Google Drive

Now that gDrive is installed on the RPi, we're ready to collect some speed test results. Using gDrive, establish a new directory on the Google drive account for our speedtest.csv record. This will be our starting point. This next terminal command will allow us to accomplish this.

gdrive mkdir speedtest

A notification stating that the subdirectory has been established will be displayed as a result of running this command. This mail will also provide you with your identification number. Write this Identification down someplace safe; we'll need it in a few stages. We may now utilize the subdirectories Identification to add a file to it, as the directory has been created. The speedtest.csv record will be used in this experiment. Be careful to substitute YOUR FOLDER ID with the identification you received in the previous phase before running the command below.

gdrive sync upload ~/speedtest YOUR_FOLDER_ID

The command prompt should display something like the one below during the first sync. Messages such as this one inform you that document has been successfully transferred to your Onedrive.

In the meantime, we'll be able to automate the entire process such that we submit the speedtest.csv whenever we make changes to it.

Using Google Drive to automate the Rpi's connection speed monitoring

Automating your Raspberry Connection Speed Monitoring is the following main task related to it. We'll be building a shell script to automate the process. Crontab will use this script to run it regularly. Use the following Unix commands on the RPi to get started developing the shell script.

nano ~/speedtest.sh

The following lines are what we'd like to include in this document. Your Google storage subdirectories unique ID must be replaced by YOUR FOLDER Identification.

#!/bin/bash

python3 /home/pi/speedtest.py

/usr/local/bin/gdrive sync upload  /home/pi/speedtest YOUR_FOLDER_ID

Save the script. Our shell script needs to be granted permission to run before we can set up a crontab in which to run it. By entering the command below into the prompt, we can accomplish our goal!

sudo chmod +x /home/pi/speedtest.sh

We're now ready to set up the crontab now that everything is finished. Start by executing the command below on the RPi to begin modifying the crontab. When prompted, choose Nano as your editor of choice.

crontab –e

At the end of the document, paste the following code. This command tells crontab to execute our shell scripts once every hour, which it will do. Our Crontab generator can help you come up with new values for the crontab if you'd like.

0 * * * * /home/pi/speedtest.sh

Conclusion

We learned how to set up a pi 4 internet connection test monitoring in this article. We also learned how to set up the internet monitoring system's influx database and grafana application. Now you can experiment with other servers to see if you can enhance the speed test's precision and performance. We're going to use our Raspberry Pi 4 to develop a Wi-Fi gateway in the next tutorial.

Security System with Image Capturing in Raspberry Pi 4

Thank you for joining us for yet another session of this series on Raspberry Pi programming. In the preceding tutorial, we constructed a personal Twitter bot using Tweepy, a Py framework for querying the Twitter application programming interface. We also constructed a Response to robot mentions that would post a response to everybody's tweet mentioning it with a certain keyword. However, in this tutorial, we will implement a security system using a motion sensor with an alarm.

This is what it looks like:

PIR Motion Sensors can be implemented with RPi by understanding how it is connected to a Raspberry Pi. Whenever the motion sensor detects human movement, an alarm is triggered in this project and the LEDs blink. You may create a simple motion-detection alarm using this interface.

Overview

Infrared Motion Detectors or PIR Sensors are Motion Sensors that use Infrared Radiation to detect movement.

Infrared rays are emitted by anything with a temperature higher than absolute zero, be it life or non-living. Humans are unable to see infrared radiation because its wavelength is longer than the wavelength of visible light.

That's why PIR Sensors are designed to pick up on those infrared rays. Due to their wide range of uses, such as motion sensors for security systems and intruder alert devices

"Passive" in motion sensor refers to the fact that it doesn't produce any radiant rays of its own, but rather detects it when other things emit infrared radiation. This is in contrast to active detectors, which perform both the generation of infrared waves and the detection of these waves simultaneously.

An Overview of Motion Detectors

For this project, we used a motion detector that included an infrared sensor, a BISS0001 integrated circuit, and other parts.

The 3 pins on the motion sensor are used for power, data, and ground. There are two potentiometers on the Motion Sensor that may be used to modify both the sensor's sensitivity and the period it remains high on sensing a body movement.

A key role in directing infrared rays onto the sensor is played by the Fresnel lens overlaying the Pyroelectric Sensor. This lens allows the PIR Sensor to detect things at an angle of 1200 degrees. The sensor has an 8-meter detection range, meaning it can pick up on human movement within that distance.

PIR Sensor Adjustments

Two potentiometers are provided for fine-tuning the sensor and output timing, as previously described.

With the aid of a potentiometer, you may modify the sensor's sensitivity. The distance can be changed between 3m and eight meters. To increase the detecting distance, spin the Potentiometer in a clockwise motion and to reduce, rotate it in the opposite direction.

The second potentiometer allows you to choose how long the motion sensor's output remains HIGH. Anywhere from 0.3s to 600s can be used. Turn the POT clockwise to raise the time and the opposite turn to decrease it.

PIR Motion Sensor with Raspberry Pi 4

A Motion Sensor based on RPi and Python language has been the goal of this project since the beginning, as stated in the intro.

I have an Infrared Motion Sensor Component in numerous different projects like Automated Lighting using Raspberry and Various Sensors, Automated Door Opening with Arduino and a motion sensor, and GSM Home Automation Security with Pi.

The key advantage of the Infrared Motion Sensor utilizing RPi over the above-described projects is that RPi can be readily connected to the Web and allows Internet of things implementation of the project.

Circuit Diagram

The following figure illustrates the interfaces concerning the Infrared Motion Detector using RPi.

Components Required

  • Raspberry Pi 4

  • PIR Sensor

  • Speaker

  • Jumper Wires

  • Breadboard

  • Power Supply

  • Computer

Circuit Design

Link the Motion Sensor's Vin and GND connectors to the RPi's 5 volts and GND pins. Use pin11 to attach the Infrared Sensor's DATA Input.

Gnd and pin 3 are where you'll want to connect the led. As soon as the sensor is triggered, these LEDs will come on and go off.

Code

Python is used for the programming portion of the project. The Python program for RPi's infrared Motion Sensor is provided below. Insert the program into a new file called motion.py.

import RPi.GPIO as GPIO

import time

GPIO.setwarnings(False)

GPIO.setmode(GPIO.BOARD)

GPIO.setup(11, GPIO.IN) #Read output from PIR motion sensor

GPIO.setup(3, GPIO.OUT) #LED output pin

while True:

i=GPIO.input(11)

if i==0: #When output from motion sensor is LOW

print("No intruders",i)

GPIO.output(3, 0) #Turn OFF LED

time.sleep(0.1)

elif i==1: #When output from motion sensor is HIGH

print("Intruder detected",i)

GPIO.output(3, 1) #Turn ON LED

time.sleep(0.1)

How it works

The operation of the Infrared Motion Sensor with Raspberry Pi is pretty straightforward. If the Infrared sensor senses some body motion, it sets the Data Input to HIGH.

RPI on identifying a 1 on the associated input gpio, will trigger the alarm.

If the PIR sensor is not working:

When you purchase a new sensor, it doesn't work. The Trim port is in the default setting, so it's not a sensor issue. Sensitivity of the sensor and trigger duration port if you modify these settings. It's going to start working as planned. Make sure the trigger duration port's knob is on the left as a low trigger duration and the sensitivity port is in the middle.

Applications

Infrared Motion Sensor with Raspberry Pi has already been discussed. They include:

  • Automated house lights

  • Motion sensing

  • Intruders notice

  • Automated door open

  • Home security systems

When motion is detected by the PIR sensor on the raspberry pi, we will look into how to record video and transmit it to Whatsapp as an alarm. So that we can tell who's in your room right away thanks to the photo.

Capture an image with the pi camera

Enable the camera by going to the Preferences menu and selecting the Raspberry Pi configuration option.

Activating the camera and saving the image will allow us to identify who or what triggered the alarm.

Python code

import picamera

from time import sleep

camera = picamera.PiCamera()

camera.capture('image.jpg')

When we run our software, the preceding code will take a picture and put it inside the root directory of the script. This image will be used to identify the intruder that has been detected.

Sound alarm

When an alarm system is triggered, there is an alert that must sound. We'll use a loudspeaker instead of a buzzer for our alarm system in this scenario. When the motion sensor is activated, we will play an alarm sound.

Code:

import pygame

pygame.mixer.init()

pygame.mixer.music.load("alarm.mp3")

pygame.mixer.music.play()

while pygame.mixer.music.get_busy() == True:

continue

As a bridge python software for video game design, Pygame is an excellent choice. Additionally, it provides sights, sounds, and visualizations that can improve the game that is being created.

Graphics for video games can be generated using a variety of libraries that deal with visuals and sounds. It streamlines the entire game workflow and makes it easier for newcomers who wish to create games.

Copy the code above and save it to a file named alarm.py then run it in the terminal.

python alarm.py

Send an image to Whatsapp using Twilio

Any internet or mobile app's compatibility with several platforms was a major hurdle to overcome when designing it. It used to be possible to build a link between two pieces of software using Bandwidth or Podium or Telnyx or Zipwhip or similar before Twilio was invented. In recent years, though, Twilio has dominated the competition. Twilio has become the preferred communication API for programmers. Twilio will become clearer to you if you stick around for a time.

What is Twilio

Developers can use Twilio's API to communicate with each other in a modern way.

When it comes to creating the ideal client experience, developers have a wealth of tools at their disposal in the form of Twilio's APIs, which the company describes as "a set of building blocks."

It is possible to utilize Twilio to communicate with customers via text message (SMS), WhatsApp, voice, video, and email. Your software only needs to be integrated with the API.

What does Twilio do?

Twilio is a provider of end-to-end solutions for integrating voice and data communication. Twilio is already used by over a billion developers and some of the world's most well-known businesses. The Twilio Communication application programming interface enables web and mobile app developers to integrate voice, message, and video conferencing capabilities. This makes it easier for app developers to communicate with one another.

The API provided by Twilio makes it simple and accessible to communicate across the web. Mobile and web applications can use this service to make phone calls as well as send text messages and multimedia messages (MMS).

How Does Twilio Work?

You might want to learn more about Twilio and how it works. As a result, Twilio allows enterprises to better understand their customers than any other service. Twilio's primary concept is to acquire clients, get to know them, provide for their needs, and keep them coming back.

Twilio has a worldwide operations center that keeps an eye on carrier networks around the clock to ensure that they are operating at peak efficiency. To keep up with the ever-changing traffic patterns, Twilio's skilled communications engineers are on the job all the time.

They employ real-time feedback from several provider services to make smarter routing decisions based on real-time data on the availability of handsets. The key distinction between Twilio and other application programming interface integration networks is that Twilio's data-centric strategy provides customer engagement service.

Key Areas Of Twilio

Contact Center

Managing a contact center in today's business environment is critical to the success of the company. Businesses can use Twilio to manage their interactions with clients and consumers through a central contact center platform.

Messaging

Before Twilight, sending mass SMS was a difficult task. Now, the Twilio Message application programming interface is widely used to transmit and receive messages, MMS, and OTT communications worldwide. Users can verify whether or not messages have been delivered using the intelligence tracking services.

Videos

For healthcare, virtual classrooms, recruiting, and other uses, Twilio's WebRTC and cloud infrastructure components make it easy for developers to create secure, video, and HD audio applications.

Marketing Campaigns

Twilio's ability to run and manage marketing campaigns is another noteworthy but still-evolving feature. Users can examine performance numbers, run campaigns, and view design concepts.

Voice

As a result of this trend, Twilio has also seen an increase in voice traffic. Any app, website, or service can use Twilio to make phone calls over the PSTN or SIP. It's easy to use Twilio Programmable Voice to make and manage digital calls for any campaign.

Email

The Twilio SendGrip application programming interface eliminates the issue of emails that never make it to their intended recipient's inbox. Customers and clients will receive your emails with Twilio, so you won't have any worries about them not getting them.

User Verification

You'll never have to worry about online scams or fraud again using Twilio's verify feature. It is continuously validated by SMS, Voice, email, and push alerts continuously.

Connectivity

Advancing solutions and services provided by Twilio allow for global connectivity. As a result of this connectedness, your company can grow with ease.

Obtain Twilio credentials

The Twilio WhatsApp sandbox

Developing and testing your app is made simple using Twilio's WhatsApp Sandbox. Your Twilio mobile number must be approved by WhatsApp before you can seek production access.

You'll learn how to connect your phone to the environment in this section. Select Messaging in the Twilio Console and then Take a look at the WhatsApp section by clicking on it. On the webpage, you'll find the information you need to join our sandbox.

The word "join" will be the first character in the code, followed by a two-word phrase chosen at random.

As soon as Twilio receives your message, you should be able to send and receive text messages on your cell phone without any issues.

Please repeat the sandbox application process for each additional mobile device that you wish to use to test the application

Configuration

Set up a new Python project in the following section.

mkdir python-whatsapp-pic

cd python-whatsapp-pic

We'll need a virtual space for this project because we'll be installing several Python packages.

Open a terminal on your RPI machine and type:

python -m venv venv

source venv/bin/activate

(venv) $ pip3 install twilio

When using a PC running Windows, execute these commands from a command line.

python -m venv venv

source venv\bin\activate

(venv) $ pip3 install twilio

Python's Twilio library will be used to deliver messages via Twilio.

Authenticate against Twilio services

To authenticate with the Twilio service, we must safely store a few critical credentials. To use Twilio we need to register for an account at the official Twilio website. Create a new account with your email and password. They will send a confirmation message to your email inbox for you to confirm the registration. Go ahead and confirm it. You will also have to verify your WhatsApp phone number to proceed.

Setting environment variables can be done by entering the code below into your terminal:

ssh auth token

export TWILIO_ACCOUNT_SID="your account sid"

export TWILIO_AUTH_TOKEN= "your auth token"

after we have exported the credentials in our environment, the next step is to activate the WhatsApp sandbox to receive messages. Go to the develop mode, then select messaging and send a Whatsapp message.

You will see a message directing you to deliver a text to your phone and if Whatsapp is connected to the computer, it will be easier to click on the link that will be provided below to send the message. Send the message that will be displayed on the chat box on your Whatsapp application.

If it works you will see a message shown below:

This number that will be displayed here is the “from” number that we will use in our code and the “to” number is your Whatsapp number.

How to send a photo message, using the Twilio service

Copy the following code into your python file.

import os

from twilio.rest import Client

account_sid = os.environ['TWILIO_ACCOUNT_SID']

auth_token = os.environ['TWILIO_AUTH_TOKEN']

client = Client(account_sid, auth_token)

from_whatsapp_number = 'whatsapp:+14155238886'

to_whatsapp_number = 'whatsapp:+254706911425'

message = client.messages.create(body='The engineering project sent your this image!',

media_url='https://www.theengineeringprojects.com/wp-content/uploads/2022/04/TEP-Logo.png',

from_=from_whatsapp_number,

to=to_whatsapp_number)


print(message.sid)

With this now all we have to do is run our app.py program on the terminal.

python app.py

Putting it all together:

So far we have written our motion sensor code, pi camera code, and sound system code, but how can we integrate all these different scripts into one project? Well, let us see how we can do it. As a quick recap, we wanted to detect motion, get the intruder's image and save then send the image to the admin's Whatsapp to alert the presence of an intruder in this project. To do this we have to create another file named main.py and write all the code for those functions in the main file. Copy the code below and paste it into the main file:

import pygame

import RPi.GPIO as GPIO

import time

import picamera

camera = picamera.PiCamera()


GPIO.setwarnings(False)

GPIO.setmode(GPIO.BOARD)

GPIO.setup(11, GPIO.IN) #Read output from PIR motion sensor

GPIO.setup(3, GPIO.OUT) #LED output pin

pygame.mixer.init()

pygame.mixer.music.load("alarm.mp3")

import os

from twilio.rest import Client

account_sid = os.environ['TWILIO_ACCOUNT_SID']

auth_token = os.environ['TWILIO_AUTH_TOKEN']

client = Client(account_sid, auth_token)

from_whatsapp_number = 'whatsapp:+14155238886'

to_whatsapp_number = 'whatsapp:+254706911425'

while True:

i=GPIO.input(11)

if i==0: #When output from motion sensor is LOW

print("No intruders",i)

GPIO.output(3, 0) #Turn OFF LED

pygame.mixer.music.stop()

time.sleep(0.2)

elif i==1: #When output from motion sensor is HIGH

print("Intruder detected",i)

GPIO.output(3, 1) #Turn ON LED

pygame.mixer.music.play()

capture image

camera.capture('intruder.jpeg')

#send image to whatsapp

message = client.messages.create(body='The engineering projects program has detected and intruder!',

media_url='https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Ftse4.mm.bing.net%2Fth%3Fid%3DOIP.q1z1XWRn_WAV4oM-Qr2M2gHaGb%26pid%3DApi&f=1',

from_=from_whatsapp_number,

to=to_whatsapp_number)


print(message.sid)

time.sleep(0.2)

GPIO.cleanup()

break


Captured image

Conclusion

In this article, you learned to build a security system using a motion detector and raspberry pi. We also learned how to set up Twilio to send and receive Whatsapp messages using the Twilio API. This project can be implemented in so many areas therefore it is a good idea for you it plays around with the code and implements some extra features. In the next tutorial, we are going to build a led cube in raspberry pi 4.

Build a Twitter bot in Raspberry pi 4

Thank you for joining us for yet another session of this series on Raspberry Pi programming. In the preceding tutorial, we integrated a real-time clock with our raspberry pi four and used it to build a digital clock. However, In this tutorial, we will construct your personal Twitter bot using Tweepy, a Py framework for querying the Twitter application programming interface.

You will construct a Response to mentions robot that will post a response to everybody's tweet mentioning it with a certain keyword.

The response will be a photo we will make and put any text over it. This message is a quote you will acquire from a 3rd application programming interface. Finally, we will look at the benefits and drawbacks of bots.

This is what it looks like:

Where To Buy?
No.ComponentsDistributorLink To Buy
1Raspberry Pi 4AmazonBuy Now

Prerequisites

To continue through this guide, you'll need to have the following items ready:

An AWS account

Ensure you've joined up for Aws Beanstalk before deploying the finished project.

Twitter application programming interface auth credentials

To connect your robot to Twitter, you must create a developer account and build an app that Twitter provides you access to. 

Python 3

Python 3.9 is the current version, although it is usually recommended to use an edition that is one point behind the latest version to avoid compatibility problems with 3rd party modules. 

You have these Python packages installed in your local environment.

  • Tweepy — Twitter's API can be used to communicate with the service.

  • Pillow — The process of creating an image and then adding words to it

  • Requests — Use the Randomized Quote Generation API by sending HTTP queries.

  • APScheduler — Regularly arrange your work schedule

  • Flask — Develop a web app for the Elastic Beanstalk deployment.

The other modules you will see are already included in Python, so there's no need to download and install them separately.

Twitter application programming interface auth credentials

OAuth authentication is required for all requests to the official Twitter API. As a result, to use the API, you must first create the necessary credentials. The following are my qualifications:

  • consumer keys

  • consumers secret

  • access tokens

  • access secrets

Once you've signed up for Twitter, you'll need to complete the following steps to generate your user ID and password:

Step 1: Fill out an Application for a Developers Twitter Account

The Twitter developer’s platform is where you may apply to become a Twitter developer.

When you sign up for a developer account, Twitter will inquire about the intended purpose of the account. Consequently, the use case of your application must be specified.

To expedite the approval process and increase your chances of success, be as precise as possible about the intended usage of your product.

Step 2: Build an App

The verification will arrive in a week. Build an application on Twitter's developers portal dashboard after Twitter's developers account access has been granted.

Apps can only use authentication details; thus, you must go through this process. Twitter's application programming interface can be used to define an app. Information regarding your project is required:

  • Your project's name serves as its identifier.

  • Your project's category should be selected here. Choose "Creating a bot" in this scenario.

  • Your project's purpose or how users will interact with your app should be described in this section. 

  • The app's name: Finally, give your app a name by typing it in the box provided.

Step 3: The User Credentials should be created

To begin, navigate to Twitter's apps section of your account and create your user credentials. When you click on this tab, you'll be taken to a new page on which you can create your credentials.

The details you generate should be saved to your computer so they may be used in your program later. A new script called credentials.py should be created in your project's folder and contains the following four key-value pairs:

access_token="XXXXXXX"

access_token_secret="XXXXXXXX"

API_key="XXXXXXX"

API_secret_key="XXXXXXXX"

You can also test the login details to see if everything is functioning as intended using:

import tweepy

# Authenticate to Twitter

auth = tweepy.OAuthHandler("CONSUMER_KEY", "CONSUMER_SECRET")

auth.set_access_token("ACCESS_TOKEN", "ACCESS_SECRET")

api = tweepy.API(auth)

try:

    api.verify_credentials()

    print("Authentication Successful")

except:

    print("Authentication Error")

Authorization should be successful if everything is set up correctly.

Understand Tweepy

Tweepy is a Python module for interacting with the Twitter application programming interface that is freely available and simple. It provides a way for you to interact with the Application programming interface of your program.

Tweepy's newest release can be installed by using the following command:

pip install tweepy

Installing from the git repo is also an option.

pip install git+https://github.com/tweepy/tweepy.git

Here are a few of its most important features:

OAuth

As part of Tweepy, OAuthHandler class handles the authentication process required by Twitter. As you can see from the code above, Tweepy's OAuth implementation is depicted below.

Twitter application programming interface wrapper

If you'd want to use the RESTful application programming functions, Tweepy provides an application programming interface class that you can use. You'll find a rundown of some of the more popular approaches in the sections that follow:

  • Function for tweet

  • Function for user

  • Function for user timeline

  • Function for trend

  • Function for like

Models

Tweepy model class instances are returned when any of the application programming interface functions listed above are invoked. The Twitter response will be contained here. How about this?

user = api.get_user('apoorv__tyagi')

When you use this method, you'll get a User model with the requested data. For instance:

python print(user.screen_name) #User Name print(user.followers_count) #User Follower Count

Fetch the Quote

You're now ready to begin the process of setting up your bot. Whenever somebody mentions the robot, it will respond with a picture with a quotation on it.

So, to get the quote, you'll need to use an application programming interface for a random quotation generator. If you want to do this, you'll need to establish a new function in the tweetreply.py script and send a hypertext transfer protocol request to the application programming interface endpoint. Python's requests library can be used to accomplish this.

Using Python's request library, you can send hypertext transfer protocol requests. As a result, you could only fixate on the software's interactions with services and data consumption rather than dealing with the complex making of requests.

def get_quote():

    URL = "https://api.quotable.io/random"

    try:

        response = requests.get(URL)

    except:

        print("Error while calling API...")

This is how they responded:

The JSON module can parse the reply from the application programming interface. You can use import JSON to add JSON to your program because it is part of the standard libraries.

As a result, your method returns the contents and author alone, which you will use. As you can see, here's how the whole thing will work.

def get_quote():

    URL = "https://api.quotable.io/random"

    try:

        response = requests.get(URL)

    except:

        print("Error while calling API...")

    res = json.loads(response.text)

    return res['content'] + "-" + res['author']

Generate Image

You have your text in hand. You'll now need to take a picture and overlay it with the text you just typed.

The Pillow module should always be your first port of call when working with images in Python. The Python Pillow imaging module provides image analysis and filetypes support, providing the interpreter with a strong image processing capacity.

Wallpaper.py should be created with a new function that accepts a quote as the argument.

def get_image(quote):

    image = Image.new('RGB', (800, 500), color=(0, 0, 0))

    font = ImageFont.truetype("Arial.ttf", 40)

    text_color = (200, 200, 200)

    text_start_height = 100

    write_text_on_image(image, quote, font, text_color, text_start_height)

    image.save('created_image.png')

Let's take a closer look at this feature.

  • Image.new() A new photo is created using the given mode and size. The first thing to consider is the style used to generate the new photo. There are a couple of possibilities here: RGB or RGBA. Size is indeed the second factor to consider. The width and height of an image are given as tuples in pixels. The color of the background image is the final option (black is the default color).

  • ImageFont.TrueType() font object is created by this method. It creates a font object with the desired font size using the provided font file. While "Arial" is used here, you are free to use any other font if you so like. Font files should be saved in the project root folder with a TrueType font file extension, such as font.ttf.

  • In other words, the text's color and height at which it begins are specified by these variables. RGB(200,200,200) works well over dark images.

  • Image. Save () created png image will be saved in the root directory due to this process. It will overwrite any existing image with the same name that already exists.

def write_text_on_image(image, text, font, text_color, text_start_height):

    draw = ImageDraw.Draw(image)

    image_width, image_height = image.size

    y_text = text_start_height

    lines = textwrap.wrap(text, width=40)

    for line in lines:

        line_width, line_height = font.getsize(line)

        draw.text(((image_width - line_width) / 2, y_text),line, font=font, fill=text_color)

        y_text += line_height

A message will be added to the image using the following method in the same script, Wallpaper.py. Let's take a closer look at how this feature works:

  • Create two-dimensional picture objects with the ImageDraw package.

  • A solitary paragraph is wrapped in texts using text wrap. Wrap () ensures that each line is no more than 40 characters in length. Output lines are returned in a tally form.

  • Draw. Text () will draw a text at the provided location. 

Use parameter:

  • XY — The text's upper-left corner.

  • Text — The text to be illustrated.

  • Fill — The text should be in this color.

  • font — One of ImageFont's instances

This is what Wallpaper.py look like after the process:

from PIL import Image, ImageDraw, ImageFont

import text wrap

def get_wallpaper(quote):

    # image_width

    image = Image.new('RGB', (800, 400), color=(0, 0, 0))

    font = ImageFont.truetype("Arial.ttf", 40)

    text1 = quote

    text_color = (200, 200, 200)

    text_start_height = 100

    draw_text_on_image(image, text1, font, text_color, text_start_height)

    image.save('created_image.png')

def draw_text_on_image(image, text, font, text_color, text_start_height):

    draw = ImageDraw.Draw(image)

    image_width, image_height = image.size

    y_text = text_start_height

    lines = textwrap.wrap(text, width=40)

    for line in lines:

        line_width, line_height = font.getsize(line)

        draw.text(((image_width - line_width) / 2, y_text),line, font=font, fill=text_color)

        y_text += line_height

Responding to Mentions by Keeping an Eye on the Twitter Feed.

You've got both the quote and an image that incorporates it in one. It's now only a matter of searching for mentions of you in other people's tweets. In this case, in addition to scanning for comments, you will also be searching for a certain term or hashtags.

When a tweet contains a specific hashtag, you should like and respond to that tweet.

You can use the hashtag "#qod" as the keyword in this situation.

Returning to the tweet reply.py code, the following function does what we want it to:

def respondToTweet(last_id):

    mentions = api.mentions_timeline(last_id, tweet_mode='extended')

    if len(mentions) == 0:

        return

    for mention in reversed(mentions):

        new_id = mention.id

        if '#qod' in mention.full_text.lower():

            try:

                tweet = get_quote()

                Wallpaper.get_wallpaper(tweet)

                media = api.media_upload("created_image.png")

                api.create_favorite(mention.id)

                api.update_status('@' + mention.user.screen_name + " Here's your Quote", 

                      mention.id, media_ids=[media.media_id])

            except:

                print("Already replied to {}".format(mention.id))

  • Respond to tweet() The last id is the function's only argument. Using this variable, you can only retrieve mentions produced after the ones you've previously processed. Whenever you initially invoke the method, you will set its value to 0, and then you'll keep updating it with each subsequent call.

  • mentions_timeline() Tweets are retrieved from the Tweepy module using this function. Only tweets with the last id newer than the provided value will be returned using the first parameter. The default is to show the last 20 tweets. When tweet mode='extended' is used, the full uncut content of the Tweet is returned. Text is shortened to 140 characters if the option is set to "compat."

Create favorite() is used to generate a favorite for every tweet that mentions you in reverse chronological order, starting with the earliest tweet first and working backward from there.

In your case, you'll use update status() to send a reply to this message, which includes the original tweet writer's Twitter handle, your textual information, the original tweet's identification, and your list of multimedia.

To Prevent Repetition, Save Your Tweet ID

There are several things to keep in mind when repeatedly responding to a certain tweet. Simply save the tweet's identification to which you last answered in a text document, tweetID.txt; you'll scan for the newer tweet afterward. The mention timeline() function will take care of this automatically because tweet IDs can be sorted by time.

Now, you'll pass a document holding this last identification, and the method will retrieve the identification from the document, and the document will be modified with a new one at the end.

Finally, here is what the method response to tweet() looks like in its final form:

def respondToTweet(file):

    last_id = get_last_tweet(file)

    mentions = api.mentions_timeline(last_id, tweet_mode='extended')

    if len(mentions) == 0:

        return

    for mention in reversed(mentions):

        new_id = mention.id

        if '#qod' in mention.full_text.lower():

            try:

                tweet = get_quote()

                Wallpaper.get_wallpaper(tweet)

                media = api.media_upload("created_image.png")

                api.create_favorite(mention.id)

                api.update_status('@' + mention.user.screen_name + " Here's your Quote", 

                      mention.id, media_ids=[media.media_id])

            except:

                logger.info("Already replied to {}".format(mention.id))

    put_last_tweet(file, new_id)

You'll notice that two additional utility methods, get the last tweet() and put the last tweet(), have been added to this section ().

A document name is required for the function to get the last tweet(); the function putlasttweet() requires the document as a parameter, and it will pick the most recent tweet identification and modify the document with the latest identification.

Here's what the final tweet reply.py should look like after everything has been put together:

import tweepy

import json

import requests

import logging

import Wallpaper

import credentials

consumer_key = credentials.API_key

consumer_secret_key = credentials.API_secret_key

access_token = credentials.access_token

access_token_secret = credentials.access_token_secret

auth = tweepy.OAuthHandler(consumer_key, consumer_secret_key)

auth.set_access_token(access_token, access_token_secret)

api = tweepy.API(auth)

# For adding logs in application

logger = logging.getLogger()

logging.basicConfig(level=logging.INFO)

logger.setLevel(logging.INFO)

def get_quote():

    url = "https://api.quotable.io/random"

    try:

        response = requests.get(url)

    except:

        logger.info("Error while calling API...")

    res = json.loads(response.text)

    print(res)

    return res['content'] + "-" + res['author']

def get_last_tweet(file):

    f = open(file, 'r')

    lastId = int(f.read().strip())

    f.close()

    return lastId

def put_last_tweet(file, Id):

    f = open(file, 'w')

    f.write(str(Id))

    f.close()

    logger.info("Updated the file with the latest tweet Id")

    return

def respondToTweet(file='tweet_ID.txt'):

    last_id = get_last_tweet(file)

    mentions = api.mentions_timeline(last_id, tweet_mode='extended')

    if len(mentions) == 0:

        return

    new_id = 0

    logger.info("someone mentioned me...")

    for mention in reversed(mentions):

        logger.info(str(mention.id) + '-' + mention.full_text)

        new_id = mention.id

        if '#qod' in mention.full_text.lower():

            logger.info("Responding back with QOD to -{}".format(mention.id))

            try:

                tweet = get_quote()

                Wallpaper.get_wallpaper(tweet)

                media = api.media_upload("created_image.png")

                logger.info("liking and replying to tweet")

                api.create_favorite(mention.id)

                api.update_status('@' + mention.user.screen_name + " Here's your Quote", mention.id,

                                  media_ids=[media.media_id])

            except:

                logger.info("Already replied to {}".format(mention.id))

    put_last_tweet(file, new_id)

if __name__=="__main__":

    respondToTweet()

Deploy the bot to Server

In order to complete the process, you will need to upload your program to a server. Python applications can be deployed using AWS Elastic Beanstalk in this area.

Amazon web service simplifies management while allowing for greater flexibility and control. Your application is automatically provisioned with capacity, load-balanced, scaled and monitored for health using Elastic Beanstalk.

Here is how it's going to work out:

  • Install Python on the AWS  environment

  • Build a basic Flask app for the bot

  • Connect to AWS and deploy your Flask app

  • Use logs to find and fix bugs

Set up Elastic Beanstalk environment

After logging into the Aws services account, type and pick "Elastic Beanstalk," then click "setup a New App."

You'll be asked to provide the following information:

  • Name of the application; 

  • Application's tags; 

  • Environment;

  • Code of the application

Each AWS Elastic Beanstalk application resource can have up to 50 tags. Using tags, you may organize your materials. The tags may come in handy if you manage various AWS app resources.

Platform branches and versions are automatically generated when Python is selected from the selection for the platform.

Later, you will deploy your app to elastic Beanstalk. Select "sample app" from the drop-down menu and click "new app." For the most part, it should be ready in about a minute or two

Create a Flask app

Python is used to create Flask, a website development framework. It's simple to get started and use. Flask has no dependencies, making it a more "beginner-friendly" framework for web applications.

Flask has several advantages over other frameworks for building online applications, including:

  • Flask comes with a debugger and a development server.

  • It takes advantage of Jinja2's template-based architecture.

  • It complies with the WSGI 1.0 specification.

  • Unit testing is made easier with this tool's built-in support.

  • Flask has a plethora of extensions available for customizing its behavior.

Flask as a micro-framework

It is noted for being lightweight and simply providing the needed components. In addition to routing, resource handling, and session management, it includes a limited set of website development tools. The programmer can write a customized module for further features, such as data management. This method eliminates the need for a boilerplate program that isn't even being executed.

Create a new Python script and call it application.py, then paste the code below into it while AWS creates an environment.

from flask import Flask

import tweet_reply

import atexit

from apscheduler.schedulers.background import BackgroundScheduler

application = Flask(__name__)

@application.route("/")

def index():

    return "Follow @zeal_quote!"

def job():

    tweet_reply.respondToTweet('tweet_ID.txt')

    print("Success")

scheduler = BackgroundScheduler()

scheduler.add_job(func=job, trigger="interval", seconds=60)

scheduler.start()

atexit.register(lambda: scheduler.shutdown())

if __name__ == "__main__":

    application.run(port=5000, debug=True)

Use up scheduler and a flask app to execute a single job() function that will ultimately call the main method in the tweet reply.py script on a minute basis.

As a reminder, the object instance's identifier of the flask app must be "app." For Elastic Beanstalk to work with your application, you must give it the correct name.

Deploy and set up the app to Amazon Web Services.

Your online app's code can include Elastic Beanstalk conf files (.ebextensions) for configuring amazon web services resources and the environments.

The .config script extension is used for YAML files, and these are put in the .ebextensions directory together with the app's code during the deployment process.

Establish a new directory called .ebextensions inside the code folder and add a new file called Python .config. Add the following code:

files:

  "/etc/httpd/conf.d/wsgi_custom.conf":

    mode: "000644"

    owner: root

    group: root

    content: WSGIApplicationGroup %{GLOBAL}

If you want Elastic Beanstalk to tailor its settings to the app's prerequisites, you'll need to include a list of any external libraries inside a requirements.txt script you produce.

Execute the command below to generate the requirements.txt file using pip freeze

Finally, package up everything for uploading on Elastic Beanstalk with Elastic Beanstalk. The architecture of your project directory should now look like this:

Compress all the files and directories listed here together. Open amazon web services again and select Upload Code.

Once you've selected a zip archive, click "Deploy." When the health indicator becomes green, your app has been successfully launched. "Follow @zeal quote!" if all of the above steps have been followed correctly, they should appear on your website link.

Procedure for getting an error report in the system

The following steps will help you access the reports of your app in the event of an error:

  • Logs can be seen under the "Environment" tab in the Dashboard.

  • After choosing "Request Log," you'll be taken to a new page with an options list. The last lines option is for the latest issues, but the "full log" option can be downloaded if you need to troubleshoot an older error.

  • To see the most recent log line, click "Download," A new web page will open.

    The Benefits and Drawbacks of Twitter Autonomy

    Media platforms entrepreneurs benefit greatly from automation, which reduces their workload while increasing their visibility on Twitter and other media platforms. We may use various strategies to ensure that we're always visible on Twitter.

    The benefits of automation are numerous. 

    There is still a need for human intervention with any automated process.

    However, automation should only be a minor element of your total plan. An online presence that is put on autopilot might cause problems for businesses. If your campaign relies on automation, you should be aware of these problems:

    Appearing like a robot

    Engaging others is all about being yourself. The tweet was written by a person who was using a phone to produce it, based on the bad grammar and occasional errors. Those who aren't in the habit of writing their own Twitter tweets on the fly risk seeming robotic when they send out several automated messages. Tweets written in advance and scheduled to post at specific times appear disjointed and formulaic.

    It is possible to appear robotic and dry if you retweet several automated messages. If your goal is to promote user interaction, this is not the best option.

    The solution: Don't automate all of your messages. The platform can also be used for real-time interaction with other people. Whenever feasible, show up as yourself at gatherings.

    Awful Public Relations Fumbles

    When you plan a message to go out at a specific time, you have no idea what will be trending. If a tragic tale is trending, the tweet could be insensitive and out of context. On Twitter, there is a great deal of outrage. Because everyone is rightly concerned about their collective destiny, there is little else to talk about.

    Then, in a few hours, a succession of your tweets surface. Images showing the group having a great time in Hawaii.

    While it's understandable that you'd want to avoid coming across as uncaring or unaware in this day and age of global connectivity and quick accessibility of info from around the globe, it's also not a good look. Of course, you didn't mean it that way, but people's perceptions can be skewed.

    What to do in response to this: Automatic tweets should be paused when there is a major development such as the one above. If you're already informed of the big news, it's feasible, but it may be difficult due to time variations.

    Twitter automation allows your messages to display even if you are not into the service. Your or your company's identity will remain visible to a worldwide audience if you have a global target market.

    If an automatic tweet appears before you can brush up on the latest events in your location, follow it up with a real one to show your sympathy. People find out about breaking news through Twitter, a global platform. Few of us have the luxury of remaining in our small worlds. While it's excellent to be immersed in your company's day-to-day operations, it's also beneficial to keep up with global events and participate in Twitter's wider discussion.

    Absence of Reaction

    People respond to your automatic tweet with congratulations, questions, or pointing out broken links that go unanswered because you aren't the one publishing it; a program is doing it in your stead, not you. Awkward.

    Suppose something occurs in the wee hours of the morning. Another tweet from you will appear in an hour. After seeing the fresh tweet, one wonders if Mr. I-Know-It-All-About-Social-Media has even read his reply.

    What to do in response to this situation: When you next have a chance to log on, read through the comments and answer any that have been left. Delayed responses are better than no responses. Some people don't understand that we're not all connected to our Twitter 24 hours a day.

    Damage to the reputation of your company

    As a means of providing customer support, Twitter has become increasingly popular among businesses. It's expected that social media queries will be answered quickly. Impatience breeds on the social web since it's a real-time medium where slow responses are interpreted as unprofessionalism.

    On the other hand, Automatic tweets offer the idea that businesses are always online, encouraging clients to interact with the company. Customers may think they're being neglected if they don't hear back.

    When dealing with consumer issues, post the exact hours you'll be available.

    Vital Comments Left Unanswered

    As soon as somebody insults you, the business, or even just a tweet, you don't want to let those unpleasant feelings linger for too long. We're not referring to trolls here; we're referring to legitimate criticism that individuals feel they have the right to express.

    What should you do? Even though you may not be able to respond immediately, you should do so as soon as you go back online to limit any further damage.

    Inappropriate actions like Favoriting and DMing might be harmful.

    Individuals and organizations may use IFTTT recipes to do various tasks, like favorite retweets, follow back automatically, and send automated direct messages.

    The unfortunate reality is that automation cannot make decisions on its own. In light of what people may write unpredictably, selecting key phrases and establishing a recipe for a favorite tweet that includes those terms, or even postings published by certain individuals, may lead to awkward situations.

    Spam firms or individuals with shady history should not be automatically followed back. Additionally, Twitter has a cap on the number of followers you can follow at any given time. Spammy or pointless Twitter individuals should not be given your followers.

    What should you do? Make sure you are aware of what others are praising under your name. Discontinue following anyone or any company that does not exude confidence in your abilities. In our opinion, auto-DMs can work if they are personalized and humorous. Please refrain from including anything that can be found on your profile. They haven't signed up for your blog's newsletter; they've just become one of your Twitter followers. Take action as a result!

    Useful Benefits

    Smaller companies and busy people can greatly benefit from Tweet automation. As a result of scheduling Twitter posts, your workload is reduced. A machine programmed only to do certain things is all it is in the end. But be careful not to be lulled into complacency.

    Social media platforms are all about getting people talking. That can’t be replaced by automation. Whether you use automation or not, you must always be on the lookout for suspicious activity on your Twitter account and take action as soon as you notice it.

    Conclusion

    In this article, you learned how to build and publish a Twitter robot in Py.

    Using Tweepy to access Twitter's API and configuring an amazon web service Elastic Beanstalk environment for the deployment of your Python application were also covered in this tutorial. As part of the following tutorial, the Raspberry Pi 4 will be used to build an alarm system with motion sensors.

    Interfacing of RTC module with Raspberry Pi 4 for real-time Clock

    Where To Buy?
    No.ComponentsDistributorLink To Buy
    1Jumper WiresAmazonBuy Now
    2DS1307AmazonBuy Now
    3Raspberry Pi 4AmazonBuy Now

    Introduction

    Thank you for joining us for yet another session of this series on Raspberry Pi programming. In the preceding tutorial, we implemented a speech recognition system using raspberry pi and used it in our game project. We also learned the fundamentals of speech recognition and later built a game that used the user's voice to play. However, this tutorial will integrate a real-time clock with our raspberry pi four and use it to build a digital clock. First, we will learn the fundamentals of the RTC module and how it works, then we will build a digital clock in python3. With the help of a library, we'll demonstrate how to integrate an RTC DS3231 chip with Pi 4 to keep time.

    Real-Time Clocks: What Are They?

    RTCs are clock units, as the name suggests. There are eight pins on the interface of the RTC IC, the DS1307. An SRAM cell backup of 56 bytes is included in the DS1307, a small clock, and a calendar. Secs, mins, hrs, days, and months are all included in the timer. When a month has fewer than 31 days, the date of the end of this month is automatically shifted.

    They can be found in integrated circuits that monitor time and date as a calendar and clock. An RTC's key advantage is that the clock and calendar will continue to function in the event of a power outage. The RTC requires only a small amount of power to operate. Embedded devices and computer motherboards, for example, contain real-time clocks. The DS1307 RTC is the subject of this article.

    The primary purpose of a real-time clock is to generate and keep track of one-second intervals.

    The diagram to the right shows how this might look.

    A program's method, A, is also displayed, which reads a second counter and schedules an action, B, to take place three secs from now. This kind of behavior is known as an alarm. Keep in mind that the secs counter doesn't start and stop. Accuracy and reliability are two of the most important considerations when choosing a real-time clock.

    A real-time clock's hardware components are depicted in the following diagram.

    An auxiliary crystal and a spectral reference can be used with a real-time clock's internal oscillator, frequently equipped with an interior crystal. The frequency of all clocks is 32,768 Hertz. A TCXO can be used with an exterior clock input since it is extremely accurate and steady.

    An input to a Prescaler halves the clock by 32,768 to generate a one-second clock, which is selectable via a multiplexer.

    For the most part, a real-time clock features a secs counter with at least thirty-two bits. Certain real-time clocks contain built-in counters to maintain track of the date and time.

    Firmware is used to keep track of time and date in a simple real-time clock. The 1 Hertz square waveform from an output terminal is a frequent choice. It's feasible for a real-time clock to trigger a CPU interrupt with various occurrences.

    Whenever the whole microcontroller is turned off, a real-time clock may have a separate power pin to keep it running. In most cases, a cell or external power source is attached to this pin's power supply.

    Achieving Accurate and Fair RTC Timing

    Using a 32,768 Hertz clock supply, real-time clock accuracy is dependent on its precision. The crystals are the primary source of inaccuracy in a perfectly-designed signal generator. The internal oscillators and less costly crystals can be employed with sophisticated frequency enhancement techniques for incredibly precise timing. A crystal has three primary causes of inaccuracy.

    • Tolerances for the initial circuitry and the crystal.

    • Temperature-related crystal smearing.

    • Crystallization

    Real-time clock accuracy is seen graphically in the figure below:

    Using this graph, you can see how a particular concern tolerance changes with increased temperature. The temperature inaccuracy is visible inside the pink track. The quadratic function used to predict the future characteristics of crystals is essential to correct for temperature. Once a circuit board has been built and the temp is determined, an initial error measurement can be used to correct most of the other sources of error.

    To acquire an accurate reading, you'll need to adjust to the yellow band. A year's worth of 1 ppm equals 30 seconds of your life. To some extent, the effects of crystallization can't be undone. Even though you're getting older, it's usually just a couple of years.

    DS1307 Pin Description:

    Pin 1, 2: The usual 32.768-kilohertz quartz crystal can be connected here. 

    Pin 3: Any conventional 3 Volt battery can be used as an input. To function properly, the battery voltage must be in the range of 2V to 3.5V.

    Pin 4: This is the ground.

    Pin 5: Streaming data input or output. It serves as the serial interface input and output, and a resistor is required to raise the power to the maximum of 5.5 volts. Irrespective of the current on the VCC line.

    Pin 6: Input for the serial timer Data sync is done via the interface clock here.

    Pin 7: Driver for the output waveform. A square wave frequency can be generated by connecting a signal to the out pin with the sqwe value set to 1.

    Pin 8: The main source of power. Data is written and read whenever the voltage provided to the gadget is within standard limits.

    Features of RTC Module

    • an output waveform that can be programmed

    • Power-failure detection and switch circuitry automation

    • Consume less power

    • Real-time data and time is provided

    The rtc is mainly used for writing and reading to and from its registers. Addresses for the rtc registers can be found from zero to 63. If necessary, transitory variables can be stored in random access memory in place of the first eight clock registers. Second, minute, hour, dates, months, and years are all included in the clock's top seven registers. Let's have a look at how DS1307 operates.

    The sole purpose of a real-time clock is to record the passage of time. Regular monitoring of the passing of time is critical to the operation of computers and many smaller electronic devices. Although it simply serves one purpose, managing time has many applications and functions. Nearly every computer activity uses measurements taken and monitoring the present time, from the generation of random numbers to cybersecurity.

    Kinematic activities or a real-time clock module keep track of time in a classic watch, so how does it work?

    The answer is in crystal oscillators, as you would have guessed. The real-time clock uses oscillator pulses in electronic components to keep track of time. Quartz crystals are commonly used in this oscillator, which typically operates at a frequency of 32 kilohertz. Software cleverness is needed to take the processing times and correct any differences related to power supply variations or tiny changes in cycle speed.

    Auxiliary tracking is used in real-time clock modules, which uses an exterior signal to lock onto a precise, uniform time. As a result, this does not override the internal measures but complements them to ensure the highest level of accuracy. An excellent example is a real-time clock module that relies on external signals, such as those found on cell phones. Oscillation cycles are counted again if the phone loses access to the outside world.

    An object made of quartz crystals has a physical form. As a result, the real-time clock module accuracy can degrade over time due to extreme heat and cold exposure. Many modules include a temperature sensing technique to counteract the effects of temperature variations and improve the oscillator's overall accuracy. There is a wide range of frequencies available in cheap a crystal used in Computer systems. So, the error rate is around 72 milliseconds per hr in real-time. In this case, the following criteria are met:

    • Start data transfer: Clock and Data lines must be high for a START.

    • Stop data transfer: In STOP mode, data lines go from low to high while the clock lines remain high.

    • Data valid: START conditions must be met before a clock signal high period can be used to determine if the transmission line is stable. The info on the channel must be updated when the clock signal is at a lower frequency. Each piece of data has one clock frequency.

    Each data transfer begins and ends with START and END conditions, respectively. During the START or STOP circumstances, the data rate bytes that can be sent are not restricted and are set by the master unit. Byte-by-byte, each recipient validates the transmission with a 9th bit.

    RTC Timing Modification

    A real-time clock can be used in systems to correct timing faults in two different ways. The graphic below shows the Prescaler counting the oscillation cycles per the second period.

    The advantage of this method is that the time interval between each second is only slightly altered. However, a variable Prescaler and an extra register for storing the prescale counts, and the interval between applications are necessary for this technology to work. 

    Suppose the real-time clock does not contain a built-in prescaler that can be used to fine-tune the timing. This diagram illustrates a different way of approaching the problem.

    The numbers in the rectangles indicate the secs counter. The program continuously tracks and calculates the real-time clock seconds count. A second is added or subtracted to compensate for the cumulative mistake whenever the error reaches 1 second.

    This strategy has a drawback: the difference in seconds whenever an adjustment is made might be rather considerable. With this method, you can use it with any real-time clock.

    Time and Date

    To keep track of the current date and time, certain RTCs use electronic counters. Counting seconds, mins, hours, days, weeks, months, and years and taking leap years into account is necessary. Applications can also keep track of the time and date.

    The second counter of a real-time clock can be used to implement this system on a microcontroller.

    The proprietary method gets time(), or something similar is commonly used to access the device timer. Using get time() is as simple as taking a second counter and printing out the resulting value. The library handles the remainder of the work to convert this time in secs to the present time of day and date.

    The real-time clock circuit

    If you turn off your RPi, you won't have access to its internal clock. It uses a network clock protocol that requires an internet connection when it is turned on. A real-time timer must be installed in the raspberry pi to keep time without relying on the internet.

    Wiring Pi 4 with the rtc board.

    First, we'll need to attach our real-time control module to the RPi board. Ensure the Rpi is deactivated or unplugged before beginning any cabling.

    Make use of the links in the following table and figure:


    The rtc is powered by a 3.3V supply; hence it needs an input of 3.3V. Connect the RTC to the Pi 4 via a communication protocol.

    Configuring the RTC Chip

    We must first enable I2C in the RPi to use the RTC component.

    Open a terminal window and enter the command raspi-config:

    sudo raspi-config

    Select the Interfacing Option in the configuration tool.

    Selecting I2C will allow I2C in the future.

    Before rebooting, enable the I2C.

    sudo reboot

    Confirm the Connections of the RTC. Then using the I2C interface, we can check to see if our real-time clock module is connected to the device.

    Ensure your Pi's software is updated before putting any software on it. Defective dependencies in modules are frequently to blame for installation failures.

    sudo apt-get update -y

    sudo apt-get upgrade -y

    If our RPi detects a connection from the real-time clock module, we'll need python-SMBus i2c-tools installed.

    On the command line:

    sudo apt-get install python-SMBus i2c-tools

    Then:

    sudo i2cdetect -y 1

    Many real-time devices use the 68 address. This indicates that any driver is not using the address. If the address returned by the system is "UU," it indicates that a program actively uses it.

    Using the RTC Package

    Install Python.

    sudo apt-get install python-pip

    sudo apt-get install python3-pip

    To get the git library, you'll first need to get the git installed on your computer.

    $sudo apt install git-all

    First, we will have to download the library using the following command in the command line.

    sudo git clone https://github.com/switchdoclabs/RTC_SDL_DS3231.git

    A file called "RTCmodule" should be created after cloning. The following code should be copied and pasted into a new py file. Please save it.

    import time

    import SDL_DS3231

    ds3231 = SDL_DS3231.SDL_DS3231(1, 0x68)

    ds3231.write_now()

    while True:

    print “Raspberry Pi=\t” + time.strftime(%Y-%m-%d %H:%M:%S”)

    print “Ds3231=\t\t%s” % ds3231.read_datetime()

    time.sleep(10.0)

    Code Walkthrough

    We begin by importing the packages we plan to use for this project.

    The clock is initialized.

    Next, the RPi and real-time clock module times are printed.

    Then, execute the program.

    $ python rtc.py

    In this case, the output should look something like the following.

    Clock Differences: Making the RTC different From RPi Clock

    The write all() function can alter the rtc to run at a different rate than the Pi's clock.

    ds3231.write_all(29,30,4,1,3,12,92,True)

    import time

    import SDL_DS3231

    ds3231 = SDL_DS3231.SDL_DS3231(1, 0x68)

    ds3231.write_all(29,30,4,1,3,12,92,True)

    while True:

        print “Raspberry Pi=\t” + time.strftime(%Y-%m-%d %H:%M:%S”)

        print “Ds3231=\t\t%s” % ds3231.read_datetime()

        time.sleep(10.0)

    Time and date are shown to have adjusted on the rtc. With this, we'll be able to use the real-time clock and the package for various projects. However, more setup is required because we'll use the RPi's real-time clock for this project.

    RPI with the real-time clock Module

    , we will configure the rtc on the RPi used in this project. The first thing to do is to follow the steps outlined above.

    The real-time clock address is 0x68, so we must use that. Configuration.txt must be edited so that a device tree layer can be added.

    sudo nano /boot/config.txt

    Please note where your real-time clock chip is in the Pi config file and include it there.

    dtoverlay=i2c-rtc,ds1307

    or

    dtoverlay=i2c-rtc,pcf8523

    or

    dtoverlay=i2c-rtc,ds3231

    After saving and restarting the Pi, inspect the 0x68 address status.

    sudo reboot

    After reboot, run:

    sudo i2cdetect -y 1

    Once the "fake hwclock" has been disabled, we can use the real-time clock real hwclock again.

    The commands below should be entered into the terminal to remove the bogus hwclock from use.

    sudo apt-get -y remove fake-hwclock

    sudo update-RC.df fake-hwclock remove

    sudo systemctl disable fake-hwclock

    RTC as the primary timer

    We can use our rtc hardware as our primary clock after disabling the fake hwclock.

    sudo nano /lib/udev/hwclock-set

    Afterward, type in the lines below.

    #if [-e/run/systemd/system];then

    #exit 0

    #if

    #/sbin/hwclock --rtc=$dev --systz --badyear

    #/sbin/hwclock --rtc=$dev --systz

    We can now run some tests to see if everything is working properly.

    On the RPi, how do we sync real-time clock time?

    To begin with, the real-time clock will show an inaccurate time on its screen. To use the real-time clock as a device, we must first correct its time.

    To verify the current date, the real-time clock is launched.

    $sudo hwclock

    It is necessary to have an internet connection to our real-time clock module to synchronize the accurate time from the internet.

    To verify the date of the terminal and time input, type in:

    date.

    Time can also be manually set using the line below. It's important to know that the internet connection will immediately correct it even if you do this manual process.

    date --date="May 26 2022 13:12:10"

    How to Sync Time From RTC to Pi

    The real-time clock module time can also be used to set the time of the Rpi.

    sudo hwclock –systems

    or

    sudo hwclock –w

    Setting the time on our real-time clock module is also possible using:

    sudo hwclock --set --date "Thu May 26 13:12:10 PDT 2022"

    Or

    sudo hwclock --set --date "26/05/2022 13:12:45"

    Once the time has been synchronized, the real-time clock module needs a battery inserted to continue saving the timestamp. Once the real-time clock module has been installed on the RPi, the timestamp will be updated automatically!

    Building our application

    Next, we'll build a digital clock that includes an alarm, stopwatch, and timer features. It is written in Python 3, and it will operate on a Raspberry Pi using the Tkinter GUI library.

    What is Tkinter???

    The library includes the Tkinter Graphical interface framework, which runs on various operating systems and platforms. Cross-platform compatibility means that the code can be used on every platform. 

    As to why Tkinter?

    Tkinter is a small, portable, and simple-to-use alternative to other tools available. Because of this, it is the best platform for quickly creating cross-platform apps that don't require a modern appearance.

    Python Tkinter module makes it possible to create graphical user interfaces for Python programs.

    Tkinter offers a wide range of standard GUI elements and widgets to create user interfaces. Controls and menus are included in this category.

    Advantages of Tkinter

    Layered technique

    Tkinter has all of the benefits of the TK package, thanks to its layered design. When Tkinter was first developed, its Graphical interface toolkit had already had time to evolve, so it benefited from that experience when it was created. As a result, Tk software developers can learn Tkinter very quickly because converting from Tcl/Tcl to Tkinter is extremely simple.

    Accessibility

    Because Tkinter is so user-friendly, getting started with it is a breeze. The Tkinter application hides the complex and detailed calls in simple, understandable methods. When it comes to creating a working prototype rapidly, python is a natural choice. Because of this, it is anticipated that its favorite Graphical interface library will be applied similarly.

    Portability

    Tkinter-based Py scripts don't require any running changes on a different platform. Any environment that implements python can use Tkinter. This gives it a strong benefit over many other competitive libraries, typically limited to a single or a handful of operating systems. Tkinter, on the other hand, provides a platform-specific look and feel.

    Availability

    Python distributions now include Tkinter by default. Therefore, it is possible to run commands using Tkinter without additional modules.

    Tkinter's flaws

    Tkinter's slower execution may be due to the multi-layered strategy used in its design. Most computers are relatively quick enough to handle the additional processes in a reasonable period, despite this being an issue for older, slower machines. When time is of the essence, it is imperative to create an efficient program.

    Importing Modules

    Import the following modules.

    from Tkinter import *

    from Tkinter. ttk import *

    import DateTime

    import platform

    Tkinter Window Creation

    We are now going to build a Tkinter window.

    window = Tk()

    window.title("Clock")

    window.geometry('700x500')

    Here, we've created a basic Tkinter window. "Clock" has been officially renamed. And make it a 700X500 pixel image.

    Control tabs in Tkinter

    Tkinter notebook can be used to add tab controls. We'll create four new tabs, one for each of the following: Clock, Alarm, Stopwatch, and Timer.

    tabs_control = Notebook(window)

    clock_tab = Frame(tabs_control)

    alarm_tab = Frame(tabs_control)

    stopwatch_tab = Frame(tabs_control)

    timer_tab = Frame(tabs_control)

    tabs_control.add(clock_tab, text="Clock")

    tabs_control.add(alarm_tab, text="Alarm")

    tabs_control.add(stopwatch_tab, text='Stopwatch')

    tabs_control.add(timer_tab, text='Timer')

    tabs_control.pack(expand = 1, fill ="both")

    We've created a frame for every tab and then added it to our notebook.

    Create Clock

    We are now going to add the clock Tkinter components. Instead of relying on the RPi to provide the date and time, we'll use the rtc module time and date instead.

    We'll include a callback function to the real-time clock module in the clock code to obtain real-time.

    def clock():

            date_time = ds3231.read_datetime()

            time_label.config(text = date_time)

            time_label.after(1000, clock)

    Timestamps are retrieved from the DateTime package and transformed to Am or Pm time. This method must be placed after Tkinter's initialization but before the notebook.

    Create Alarm

    We'll design an Alarm that will activate when the allotted time has expired in the next step.

    Tkinter Components for Alarms

    get_alarm_time_entry = Entry(alarm_tab, font = 'calibri 15 bold')

    get_alarm_time_entry.pack(anchor='center')

    alarm_instructions_label = Label(alarm_tab, font = 'calibri 10 bold', text = "Enter Alarm Time. Eg -> 01:30 PM, 01 -> Hour, 30 -> Minutes")

    alarm_instructions_label.pack(anchor='s')

    set_alarm_button = Button(alarm_tab, text = "Set Alarm", command=alarm)

    set_alarm_button.pack(anchor='s')

    alarm_status_label = Label(alarm_tab, font = 'calibri 15 bold')

    alarm_status_label.pack(anchor='s')

    Set the alarm with the following format: HH: MM (PM/AM). For example, the time at which 01:30 PM corresponds to 1:30 p.m. As a final step, a button labeled "Set Alarm Button." In addition, the alarm status label indicates if the alarm has been set and shows the current time.

    Make an alarm method

    The set alarm button will trigger an alarm when this method is called. Replace Clock and Notebook setup functions with this one.

    def alarm():

            main_time = datetime.datetime.now().strftime("%H:%M %p")

            alarm_time = get_alarm_time_entry.get()

            alarm_time1,alarm_time2 = alarm_time.split(' ')

            alarm_hour, alarm_minutes = alarm_time1.split(':')

            main_time1,main_time2 = main_time.split(' ')

            main_hour1, main_minutes = main_time1.split(':')

            if int(main_hour1) > 12 and int(main_hour1) < 24:

                    main_hour = str(int(main_hour1) - 12)

            else:

                    main_hour = main_hour1

            if int(alarm_hour) == int(main_hour) and int(alarm_minutes) == int(main_minutes) and main_time2 == alarm_time2:

                    for i in range(3):

                            alarm_status_label.config(text='Time Is Up')

                            if platform.system() == 'Windows':

                                    winsound.Beep(5000,1000)

                            elif platform.system() == 'Darwin':

                                    os.system('say Time is Up')

                            elif platform.system() == 'Linux':

                                    os.system('beep -f 5000')

                    get_alarm_time_entry.config(state='enabled')

                    set_alarm_button.config(state='enabled')

                    get_alarm_time_entry.delete(0,END)

                    alarm_status_label.config(text = '')

            else:

                    alarm_status_label.config(text='Alarm Has Started')

                    get_alarm_time_entry.config(state='disabled')

                    set_alarm_button.config(state='disabled')

            alarm_status_label.after(1000, alarm)

    In this case, the module's time is taken and formatted in this way in case the If the time provided matches the time stored, it continues. In this case, it beeps following the operating system's default chime.

    Make Stopwatch

    As a final step, we'll add a stopwatch to our code.

    Add stopwatch Tkinter component.

    To complete our timer, we'll add all Tkinter elements now.

    stopwatch_label = Label(stopwatch_tab, font='calibri 40 bold', text='Stopwatch')

    stopwatch_label.pack(anchor='center')

    stopwatch_start = Button(stopwatch_tab, text='Start', command=lambda:stopwatch('start'))

    stopwatch_start.pack(anchor='center')

    stopwatch_stop = Button(stopwatch_tab, text='Stop', state='disabled',command=lambda:stopwatch('stop'))

    stopwatch_stop.pack(anchor='center')

    stopwatch_reset = Button(stopwatch_tab, text='Reset', state='disabled', command=lambda:stopwatch('reset'))

    stopwatch_reset.pack(anchor='center')

    The stopwatch method is activated by pressing the Start, Stop, and Reset Buttons located below the Stopwatch Label.

    Add stopwatch counter method.

    Stopwatch counters will be included in the next section. Two stopwatch counters will be added first. Tkinter Initialization and the clock's method should be added to the bottom of the list.

    stopwatch_counter_num = 66600

    stopwatch_running = False

    The stopwatch is described in these words. Adding a Stopwatch Counter is the next step. Add it to the bottom of the alarm clock and the top of the notebook's setup procedure.

    def stopwatch_counter(label):

            def count():

                    if stopwatch_running:

                            global stopwatch_counter_num

                            if stopwatch_counter_num==66600:

                                    display="Starting..."

                            else:

                                    tt = datetime.datetime.fromtimestamp(stopwatch_counter_num) 

                                    string = tt.strftime("%H:%M:%S") 

                                    display=string 

                            label.config(text=display)

                            label.after(1000, count)

                            stopwatch_counter_num += 1

            count()

    The counter controls the stopwatch on the stopwatch. At the rate of one second each second, the Stopwatch counter is incremented by 1.

    Add stopwatch method

    The stopwatch method, which is invoked by the Stopwatch Controls, is now complete.

    def stopwatch(work):

             if work == 'start':

                     global stopwatch_running

                     stopwatch_running=True

                     stopwatch_start.config(state='disabled')

                     stopwatch_stop.config(state='enabled')

                     stopwatch_reset.config(state='enabled')

                     stopwatch_counter(stopwatch_label)

             elif work == 'stop':

                     stopwatch_running=False

                     stopwatch_start.config(state='enabled')

                     stopwatch_stop.config(state='disabled')

                     stopwatch_reset.config(state='enabled')

             elif work == 'reset':

                     global stopwatch_counter_num

                     stopwatch_running=False

                     stopwatch_counter_num=66600

                     stopwatch_label.config(text='Stopwatch')

                     stopwatch_start.config(state='enabled')

                     stopwatch_stop.config(state='disabled')

                     stopwatch_reset.config(state='disabled')

    Make Timer

    We will now create a timer that rings when the timer has expired. Based on the stopwatch, it deducts one from the counter rather than adding 1.

    Add timer Tkinter component

    The timer component will now be included in Tkinter.

    timer_get_entry = Entry(timer_tab, font='calibiri 15 bold')

    timer_get_entry.pack(anchor='center')

    timer_instructions_label = Label(timer_tab, font = 'calibri 10 bold', text = "Enter Timer Time. Eg -> 01:30:30, 01 -> Hour, 30 -> Minutes, 30 -> Seconds")

    timer_instructions_label.pack(anchor='s')

    timer_label = Label(timer_tab, font='calibri 40 bold', text='Timer')

    timer_label.pack(anchor='center')

    timer_start = Button(timer_tab, text='Start', command=lambda:timer('start'))

    timer_start.pack(anchor='center')

    timer_stop = Button(timer_tab, text='Stop', state='disabled',command=lambda:timer('stop'))

    timer_stop.pack(anchor='center')

    timer_reset = Button(timer_tab, text='Reset', state='disabled', command=lambda:timer('reset'))

    timer_reset.pack(anchor='center')

    Get timer provides guidance that explains how to set the timer. HH:MM: SS, For instance, 01:30:40 denotes a time interval of one hour, thirty minutes, and forty secs. It then has a toggle that calls the Timer method, which has a start, stop, and reset button.

    Add timer counter method

    To begin, we'll insert 2 Timer counters. The two lines of code below the stopwatch and the clock method below should be added.

    timer_counter_num = 66600

    timer_running = False

    In this section, we learn more about the "Timer" feature. Next, we'll implement the Timer Counter feature. In between the Stopwatch method and Notebook Initiation, put it.

    def timer_counter(label):

            def count():

                    global timer_running

                    if timer_running:

                            global timer_counter_num

                            if timer_counter_num==66600:

                                for i in range(3):

                                        display="Time Is Up"

                                        if platform.system() == 'Windows':

                                            winsound.Beep(5000,1000)

                                        elif platform.system() == 'Darwin':

                                            os.system('say Time is Up')

                                        elif platform.system() == 'Linux':

                                            os.system('beep -f 5000')

                                timer_running=False

                                timer('reset')

                            else:

                                    tt = datetime.datetime.fromtimestamp(timer_counter_num) 

                                    string = tt.strftime("%H:%M:%S") 

                                    display=string

                                    timer_counter_num -= 1

                            label.config(text=display)

                            label.after(1000, count)

            count()

    The Timer counter controls the timer. Timer counter-variable num is decreased by one each second.

    Add timer method

    def timer(work):

             if work == 'start':

                     global timer_running, timer_counter_num

                     timer_running=True

                     if timer_counter_num == 66600:

                             timer_time_str = timer_get_entry.get()

                             hours,minutes,seconds=timer_time_str.split(':')

                             minutes = int(minutes)  + (int(hours) * 60)

                             seconds = int(seconds) + (minutes * 60)

                             timer_counter_num = timer_counter_num + seconds  

                     timer_counter(timer_label)

                     timer_start.config(state='disabled')

                     timer_stop.config(state='enabled')

                     timer_reset.config(state='enabled')

                     timer_get_entry.delete(0,END)

             elif work == 'stop':

                     timer_running=False

                     timer_start.config(state='enabled')

                     timer_stop.config(state='disabled')

                     timer_reset.config(state='enabled')

             elif work == 'reset':

                     timer_running=False

                     timer_counter_num=66600

                     timer_start.config(state='enabled')

                     timer_stop.config(state='disabled')

                     timer_reset.config(state='disabled')

                     timer_get_entry.config(state='enabled')

                     timer_label.config(text = 'Timer')

    If the task is started, this method retrieves the Timer input text and formats it before setting the Timer counter and calling the Timer counter to set the clock running. The timer is set to "False" if programmed to Stop. The counter is set to 666600, and running is configured to "False."

    Start clock and Tkinter

    Finally, here we are at the end of the project.   Finally, add the code below to start Tkinter and the clock.

    clock()

    window.main loop()

    It will open the Tkinter and clock windows.

    Output

    Alarm

    Stopwatch

    Timer

    Disadvantages of RTC module

    • 32-Bit Second Counter Problems

    Even while this counter can operate for a long period, it will eventually run out of memory space. Having a narrow count range can pose problems. 

    Application of an RTC module

    • Management of the streetlights

    Lighting Street Management System is a one-of-a-kind solution that regulates the automatic reallocation of lights in public spaces. It can measure electric consumption and detect tampering and other electrical situations that hinder the most efficient use of street lights. IoT-based automated streetlight management systems are intended to cut electricity usage while decreasing labor costs through precession-based scheduling. Streetlights are a vital element of any town since they improve night vision, offer safety on the streets, and expose public places, but they waste a significant amount of energy. Lights in manually controlled streetlight systems run at full capacity from sunset to morning, even if there is adequate light. High reliability and lengthy stability are guaranteed by this method. This task is carried out using computer software. When compared to the previous system, the new one performs better. Automated On and Off processes are based on the RTC module for the time frame between dawn and dusk of the next day. Manual mode was removed because of human flaws and difficulties in timely on and off activities, which necessitated the relocation of certified electricians over wide distances and caused time delays. Using an Internet of things controlled from a central command center and portable devices helps us avoid these delays while also identifying and correcting faults, conserving energy, and providing better services more efficiently. 

    Conclusion

    This tutorial teaches the mechanics of a real-time clock and some major applications in real life. With ease, you can integrate this module into most of your projects that require timed operations, such as robot movements. You will also understand how the RTC works if you play around with it more. In the next tutorial, we will build a stop motion movie system using Raspberry pi 4.

    Why Should You Use Automation in Your Rental Property Management?

    Rental property management is a potentially lucrative strategy – one that can supply you with a steady stream of passive income and, if you do things right, set you up for long-term accumulation of wealth.

    But at the same time, the day-to-day process of managing properties can be a headache. You’ll be responsible for overseeing the property, responding to maintenance requests, collecting rent, and dealing with problematic tenants.

    Is it worth designing an automation system to handle some of these tasks on your behalf? How much value do you stand to gain?

    Why Automation Is So Valuable

    Let's start by talking about some of the reasons why automation is so valuable.

    Time savings:

    Many property owners choose to hire a property manager to take care of the property management side of things, from screening tenants to managing evictions. That's because most people want their rental properties to be a passive income source, requiring little to no effort on their part. Automation allows you to take this to the next level, reducing your manual effort even further and possibly allowing you to forgo the necessity of hiring a property manager to begin with.

    Process consistency:

    Another benefit of automation is process consistency. If you automate messages and follow-ups, you'll never have to worry about forgetting a message. Your tenants will know exactly what to expect, and you'll be much more successful in navigating this financial strategy.

    Accurate records:

    Accurate and consistent record keeping is an absolute must in the world of rental property management. Not only is it important for your personal accounting, but it's also important for tax planning. Automating the process of activities like accepting rent payments and producing reports can make it much easier to maintain accurate and consistent records.

    Are There Any Drawbacks to Automation?

    Are there any drawbacks to attempting to automate your rental property management?

    Initial time investment:

    Creating an automation algorithm is faster now than it’s ever been. But it still might be an uphill battle if you're designing your own automated systems from scratch. If you only have one rental property, or if this is only a temporary pursuit for you, it may not be worth that initial time investment.

    Initial money investment:

    If you're not designing your own solution, you'll be required to buy one that's already in existence. Most rental property automation platforms are relatively inexpensive, but you'll still have an upfront monetary expenditure to plan for.

    Potential mistakes and inaccuracies:

    Lazy coding and overlooked variables can lead to potential mistakes and inaccuracies. Your automated systems will run exactly the way you tell them to – but sometimes, that can work against you.

    Impersonal interactions:

    If you're using automated messages to handle most of the communications with your tenants, they may perceive these communications as impersonal. Relationship management isn't your primary responsibility, but this is still a variable worth considering.

    Finding a Market Solution

    For most rental property managers, the ideal solution is to find an existing product on the market that can handle your automation needs.

    If you're shopping for a solution, be sure to consider:

    Core features:

    Think about all the core features you're going to need and make sure every solution you seriously consider contains them. Do you want to automate the process of collecting tenant applications? What about collecting rent? Should the system also handle maintenance and repair requests? What features should be available to you, as the property manager?

    History and reputation:

    Always take a look at the history of this product, including the reviews and testimonials left behind by people who have used it in the past. Do people find this product to be reliable? Does it solve their needs efficiently?

    UI/UX

    The easier the tool is to use, the better – both for you and your tenants.

    Recordkeeping:

    Accounting for taxes is often a major pain for rental property owners. If you want to make it easier on yourself, you need to have a solution with organized, automated, and efficient recordkeeping.

    Pricing:

    Finally, consider the pricing. This is especially important if you're also debating whether or not you should build your own tool. Could you build something similar for less?

    Building Your Own Solution

    Of course, it's also possible to design and build your own automated solution to rental property management. This can be time-consuming, and there are some risks involved, but the finished product can be extremely valuable and you'll probably have fun building it in the process.

    Automation is the right move for most rental property managers, but it doesn't always take the same form. Think carefully about the automation solutions you incorporate into your financial strategies and always plan with the future in mind.

    Subroutine in Ladder Logic Programming

    Hello friends, after completing that basic part of ladder logic programming, let us today go through one topic which is not essential to know to complete a PLC ladder program but it is important t have our code readable program and reusable pieces of code. That could happen by using what so-called a subroutine. So what is a subroutine?

    Well, it is a piece of code that includes a few rungs to perform specific tasks. that piece of code can be reused numerous times through the program when we need to call it for performing that task. That subroutine enables us to structure our code like building blocks so that the program will be readable very easy and also reusable later in other projects. The idea of dividing the program into routines to apply the divide and conquer technique is very crucial to ease the coding of your program especially when it comes to the large-scale program which is the common cause in the best industry practice.

    Each routine achieves one specific task and they are integrated to accomplish the whole mission. By programming in that way, the code is more readable and reusable meaning that one routine could be called many times instead of keeping repeating the lines of code or ladder rungs everywhere we need it. In this tutorial, we are going to be very familiar with subroutine-based programming including different ways to call a subroutine and the instructions that are used for handling subroutines. And yes we are going to practice examples that program that subroutines in ladder logic so let's get started.

    Types of routines 

    Routines can be classified into two main types: the calling routines that call subroutines. And routines that are being called. Figure 1 shows the very typical scenario of calling one subroutine. It shows the scenario when the calling routine reaches the calling instruction when the subroutine is being called with the value of the parameter passed by the calling routine and then the subroutine has a return instruction to take the execution to the following instruction of the calling instruction.  So you can imagine the calling instruction is in the calling routine which is mostly the main program and the called subroutine is responsible to return the control or the execution point to the instruction next to the calling instruction.

    Passing parameters 

    There are two main ways for passing parameters between the calling routine and the subroutine that is being called. The two ways are calling by value and calling by reference. In the calling by value method, the calling routine passes a copy of the original parameters so the called subroutine works on a copy. Therefore, there are no changes could happen to the original parameters in the calling routine. In contrast, in the second method which is called call by reference, the parameters are shareable between the calling routine and the subroutine that is being called. So, changes happened to the parameters but the called subroutine reflected on the original ones. Figure 2 depicts a case scenario of the two types of passing parameters. In that very example, the main routine calls subroutine “Call_Val” to apply an increment of operand “Op1” passing the parameter Op1 using the method “calling by value” while it calls “Call_ref” to do the same process but in that case, it passes parameter Op1 by using the method of “calling by reference”. As you can see, in the case it uses the “calling by value” method, it does not change the value of parameter Op1 because it uses a copy of the parameter and increments that copy not the original parameters. On the other hand, when it has used the other method, “calling by reference”, to increment the same parameter Op1, it does change the original operand because it uses a reference that points to the original parameter address. In another word, calling a subroutine based on a call by value works on a copy of the parameters and does not change the original variables while calling by reference works on the originally passed parameters so it does change the parameters. The advantage of calling by reference is saving the memory as it does not need an instance of the variables or a separate data block. On the other hand, calling by value needs to have a separate data block to include that copy of passing parameters. However, it can be called many times with a separate copy without any conflicts.

    Program sequence:

    Figure 3 shows the program sequence when using multilevel branching using subroutines. For example, the main module keeps carrying out the network net1, and net2, and it calls the subroutine “Sub x” in-network net3. Then subroutine “sub x ” starts executing from network net1 to net3 at which, it calls subroutine “Sub y”. Then subroutine “Sub y” carries out starting from the network “net 1”, and network “net 2” calls subroutine “Sub a”. You can notice subroutine “Sub a” returns to the calling routine “Sub y” which returns to subroutine to its calling routine “Sub x” which returns to its calling routine which is the main routine. So, you can notice how many levels of subroutine calls? Yes, they are a lot. But, it is recommended to be as much as needed for two reasons. First, many branching causes some headaches in processing in terms of memory and time. Memory is represented in the data block that is needed for each subroutine every single branching or subroutine calling and time is represented in extra instructions of calling and returning and stacking data related to the called routine and the returning addresses.

    Subroutine instructions

    There are two main instructions used for calling a subroutine and returning to the calling routine. Figure 4 shows the network rung that calls a subroutine called “Auto Mode”. It is going to call the subroutine at any time when the “System OK” memory contact MB180 is true. So I hope you can feel now how your program is more organized and readable when you go through the main program and easily can catch what the program does by reading the names of the called subroutines. Exactly, having a meaningful name for subroutines is very important to give the advantage of the readability of your program. So, my friends please make sure you chose a purposeful name for your subroutines.

    Also fig. 5 shows the network rung that represents the returning command to the calling routine. It shows when the alarm is true represented by memory contact MB32 and pump status “Stop Pump” represented by memory bit64, the return command will be enabled for returning the execution point to the network just next to the calling network in the calling program. For example, if the calling network is at rung number 3, then the return command in the subroutine will return the execution at rung number 4 in the calling routine.  By the way, in most cases of ladder logic programming, you might not find a return instruction because it is inherently performed by completing the called subroutine but we just include it here as in fig. 5 to show up how the process of calling a subroutine and returning to the calling routine.

    Figure 6 depicts the whole image of the scenario of calling one subroutine. In rung 3, a subroutine called “Auto mode” is being called by having the memory contact MB18 true. Then after that subroutine, “Auto mode” is completed it returns to the calling routine at the next rung to the calling rung which is in this case example rung number 4.  As we stated earlier, you can notice that there are now returning instructions but automatically, the called subroutine returns to the calling routine at the instruction just next to the calling instruction.

    Practicing Subroutine in ladder logic

    My friends, let us go to our lab as usual and do some hands-on practicing subroutine using the simulator. But before going further in practice subroutine we want to elaborate on the different types of subroutines in Siemens programming. Table 1 compares the subroutine implementation based on function and function block. It shows that subroutine can be implemented by either function FC or function block FB. And both ways can use input, output, and in-out parameters. 

    FC does not use static data or data block (DB) while FB uses DB and passing parameters by making an instance of the variables which is calling by value. FC passes the parameter by pointing to the address of the variable which calling by reference technique.   

    Table 1: Comparison between FC and FB subroutine in Siemens

    Characteristic

    FC

    FB

    Can be used as a subroutine

    Yes

    Yes

    Can use parameters for Inputs, Outputs, and Input

    Yes

    Yes

    Can use temporary variables

    Yes

    Yes

    Can use static variables (with remanence)

    No

    Yes

    Need an auxiliary (instance) DB for each call

    No

    Yes

    Parameters are passed as the address for internal use

    Yes

    No

    Parameters are copied to/from a DB (instance) for internal use

    No

    Yes

    Can call internally a FB or FC

    Yes

    Yes

    Can be called for a FB or FC

    Yes

    Yes

    Can call a FB as multi-instance

    No

    Yes

    Can be called without filling all parameters

    No

    Yes

    Subroutine in ladder logic programming 

    Again, there are two ways of calling a subroutine in Siemens ladder programming as shown in fig. 7. We have developed a sample ladder program that calls a simple subroutine to add two input operands. In the first rung, it uses function “FC1” called “fun_A” and in the second rung, it utilizes a function block FB1 called “FB_A” as you can notice function block uses a data block instance for passing a copy of the operands while function FC does not use a data block and uses the address of the input and output parameters.

    Figure 8 shows the function block FB_A. the function block has two input operands which are “op1” and ‘’op2” and one output operand which is “sum”.

    Because the function block passes parameters as copies or instances, fig. 9 shows the related data block DB1 which contains the parameters of the function block. It is composed of many structures for holding input, output, input, and static data as well.

    On the other hand, the function uses the addresses of the parameters. Therefore, it does not need a data block as shown in fig. 10. It uses many structures to pass input, output, input, temporary, and constant data types.

    Simulation work

    Now let’s check the work with the simulator. Figure 11 shows the results of simulating the calling subroutine based on function FC_A that adds two static operands showing the calling path from the main organization block to the function.

    On the other hand, calling a subroutine based on a function block uses an instance of parameters in a data block as shown in fig. 12. This means another instance of data is used every time we called that subroutine while using the function it is referencing the same variables at the same addresses. 

    What’s next

    Thank you guys for following me up to this very point of our tutorial and being very confident by knowing the subroutine you now are all set to write an organized program and readable and reusable piece of code using ladder logic programming. the next time we are going to talk about one of the most important topics in PLC programming which is master reset control showing what is it about and its importance for PLC and control project and for sure will practice with our simulator lab. So be ready and let’s meet in the next tutorial to enjoy learning and practice the PLC ladder programming series.

    Master Reset Control in Ladder Logic Programming

    Introduction 

    Hello friends, I hope you are doing very well. Today we are going to learn and practice the master control reset (MCR)! So what is that MCR? Well! This is a tool you might use to control a group of devices with one push button for performing fast emergency responses with one click for a group of devices in one zone. In another word, you divide the program into zones and put this zone between a master control to control their operation as one unit by one contact. This technique is useful for applying emergence stops and also protecting some equipment by applying a safety restriction to not operate when that condition is in effect. 

    The concept of the master control reset (MCR)

    Figure 1 shows the master control relay in a ladder logic showing a couple of rungs between the master control and master control reset to be controlled as one zone by master control. for example, input 1 enables the master control relay M100 which is the only way to relay the hotline of power to rungs 2 and 3 as shown in the figure. When input 1 is on, the master control relay is energized. Therefore, input 2 and input 3 can energize output 1 and output 2 respectively. But, if input 1 is off, the master control relay is off. Therefore, rungs 2 and 3 are disconnected from the power. Therefore, even if input 2 and input 3 are on, outputs 1 and 2 will not energize because of a missing connection to power via master control relay M100. To sum up, there is a zone that contains a couple of rungs, these rungs are not enabled without master control enabled. Also, fig. 1 shows the structure of the master control and master control reset to have one rung to enable the master control relay and one rung at the end to represent the master control reset and declare the end of the zone that is under master control. and the code or rungs that are located between the master control and the master control reset is the zone that we need to control its running based on master control. So, if the master control is not true, the code in that zone between the master control and the master control reset will be bypassed and the next instruction after the master control reset instruction will be executed. 

    The concept looks very simple but it is crucial for safety and control techniques. Also, many master control and zones can have in our program as shown in fig. 2. It shows more than one zone and each one is controlled by its master control.

    So we want to go further in demonstrating the master control reset by a practical example from real life. Figure 3 shows a practical example of real-life in the industry of which automatic bottle filling process. So what does master control have to do with such a process? Will! That is a good question because it tells me you understand master control reset and are with me on the same page. So, as you can see, there is the start and stop pushbuttons and we need to use master control to control starting and stopping the whole process regardless of the status of individual inputs and sensors. by having such control, we can stop the process in any emergency case or for doing maintenance. The sequence of the process is to start moving the conveyor by hitting the start push button. The conveyor keeps running until the proximity sensor comes ON. At that time, the valve will open for 5 seconds and then the conveyor continue moving again after 5 seconds and continue for 3 bottles repeating the same process. But if there is an emergency happens, there should be a way to stop the process including moving the conveyor, and opening the valve even if all conditions to do are met. Well done! You are correct, master control and master control reset should bracket the process to be enabled and disabled when that emergency comes to happen.

    Master control in ladder logic

    Master control and master control reset are the same concepts. However, a few differences you can notice in ladder logic from one plc brand to another. For example, Fig. 4 shows the ladder logic code of a master control reset in Mitsubishi PLC. You can notice the same concept has been applied. A zone of a couple of rungs is surrounded by master control and master control reset instructions based on master control relay M100. Input 1, X400 enables the master control relay M100. And rungs 2 and 3 are included in the zone under master control.

    On the other hand, master control and master control reset look a little bit different in Allen-Bradley as shown in fig.5. However, you can notice the same concept is applied by having the zone that includes a couple of rungs between the master control relay and master control reset for enabling or disabling that zone based on the logic and situation.

    Also, Siemens shows a few differences in ladder logic of master control as shown in Fig.6. however, the same concept is thereby enclosing the code to be controlled in a zone preceded by enabling to master control relay and followed by a master control reset to clear that master control and show the end of the controlled zone.

    Practice Ladder logic example

    Guys, it is now the time to enter our lab and enjoy practicing the master control and master control reset by using our simulator as usual for validating our understanding of what we have gone through in this tutorial on ladder logic programming. In the example simulated below and shown in fig. 7, we have designed simple master control and master control rest to have master control of running of Q0.0. you can notice that, despite input I0.1 being true, Q0.0 is not energized because master control is not enabled or in off status. So what happens if we enable master control by switching on input I0.0?

    Yes, you are correct! The output Q0.0 will now work after enabling the master control by turning input I0.0 on as shown in Fig.8.

    What’s next???

    Let me thank you guys for following up until this point and because your knowledge of ladder logging is getting increase every single tutorial, I would like to announce that, the next tutorial will be about one of the very advanced levels of ladder logic programming which is for expert and I thought you are now. The sequencer output instruction in ladder logic is our topic for the next tutorial in which we will learn and practice how to, massively output data sequentially to outputs. Please do not worry if that is not clear for now and just be there to go through it step by step and enjoy practicing one topic for an expert ladder programmer.

    Properties of z-Transform in MATLAB

    Hello, readers. Welcome to another lecture on signals and systems where, on the previous day, we studied the transforms. A Z transform is used to change the domain of a signal or function. It is used to convert the signal from the time domain into the z plane. Now we are going a little deep into the discussion. Have a quick promo of the topic of today:

    • What are the properties of z transform?

    • What is the unit impulse of z transform?

    • What is the unit ramp of z transform?

    • What is the difference equation and how is it related to the z transform?

    • What are some important applications of z transform?

    We’ll go through each of these topics in detail, so stay with us to learn about all of them.

    Properties of z Transform

    Till now, we have seen the introduction of z transform along with some basic information. It's time to discuss some properties of z transform in this lecture. We always mention the properties of the topic if possible to clearly describe the nature and workings of that particular topic. It will be correct to say that while discussing the properties of a mathematical tool, we provide you with a wide domain of learning and experimenting about that particular topic. 

    Linearity of the z transform

    The z transform is always linear. It means, if we have two statements and apply the z transform individually on both of them, then we always get the linear results. Mathematically,

    If

     F(z) = Z{fn}

    and 

    G(z) = Z{gn}

    Then

    Z{afn + bgn} = aF(z) + bG(z)

    Time Shifting Property

    When we talk about the time shifting property of z transform, we come to know that while passing through the time shifting process while we are performing the z transform, we get the following results:

     x(n)⟷Z.TX(Z)

    If we take n-m instead of n in the property given above, we’ll find the results in which the signal in the z plane multiplies with the z complex number having the exponential power equal to the m with a negative sign with it. 

    Time Reversal Property of z Transform

    The time reversal property of z transform states that if we have the following condition:

    x(n)⟷Z.TX(Z)x(n)⟷Z.TX(Z)

    Then after applying the z transform, we will get

    x(−n)⟷Z.TX(1/Z)

    You can see that after the application of z transform, we get the z in that is present in the denominator of the resultant X value. Therefore, this property is named the reversal property.

    Convolution of z Transform

    Convolution is an important process in signals and systems and we have also read great detail about it in this course. While merging the concept of convolution and z transform, we get to know that if, 

    x(n)⟷Z.TX(Z)x(n)⟷Z.TX(Z)

    and 

    y(n)⟷Z.TY(Z)y(n)⟷Z.TY(Z)

    Then we can easily guess that 

    x(n)∗y(n)⟷Z.TX(Z).Y(Z)x(n)∗y(n)⟷Z.TX(Z).Y(Z)

    Keep in mind, the convolution is not same as the multiplication of the signal. It is the process in which two signals are overlapped in such a way that they form the third signal that has a mix of the properties of both the signals that are convoluted. 

    Corelation of z Transform

    If you have studies about the convolution, you will surely have the information of correlation as well. This property of z transform states that if we have 

    x(n)⟷Z.TX(Z)x(n)⟷Z.TX(Z)

    and 

    y(n)⟷Z.TY(Z)

    Then after the process of correlation while you are using z transform, you will get the following results:

    x(n)⊗y(n)⟷Z.TX(Z).Y(Z−1)

    If you are new to the correlation then you must gpo to our previous lecture about correlation where we have descried this briefly. 

    Initial Value Theorem

    Based on different experiments and studies, a theorem has been introduced and the initial theorem is one of them. This theorem is used to find the initial value of of the statement without using the inverse z transform and it states that:

    x(0)=limz→∞X(z)

    This theorem is only applicable to casual signals. 

    Final Value Theorem

    This is another theorem that is usually introduced while discussing the initial value theorem. It states that if:

    x(∞)=limz→1[z−1]X(z)

    It is also used in cases where you do not want to apply the inverse z transform and use the alternative way.

    Z Transform of Unit Impulse Function

    The unit impulse function is used in physics and mathematics. It indicates the function that has zero width and a unit area that is the area of value 1. Unit step function using z transform is simple and easy and it results in the sequential series. Suppose we have the following function:

    Then after applying the z transform of this statement, we get a geometric series. Recall that geometric series is the one in which every value is the result of the multiplication of the previous value with a particular constant depending upon the condition given for the geometric constant. 

    Z transform and Unit Ramp Signal

    A unit ramp function is one that after the implementation of different operations, provides a graph that has a straight slope. Such functions are widely used in the formation of complex operations. While using the z transform, it is defined as:

    x(n)=r(n)={n For n≥0 0 For n<0 }

    Then we can solve this by using the procedure of z transform as:

    Multiplication Property of z Transform

    The multiplicative property of z transform is also called the complex convolution property of z transform. It is because, it results by the multiplication of two signals of time domain that corresponds to the complex number of z domain. You can have the idea of this property with the help of the code given nex that is the extension of the code that we have worked with before. 


    Code

    Output 

    syms n;

    f=sin(2*n)

    F=ztrans(f)

    G=iztrans(F)

    H=F*G

    Z Transform and Difference Equation

    The difference equation is somehow a special case in the equation and the z transform is used to solve this in an effective way. It is defined as:

    “The difference equation is the special type of equation in which there exists a difference (minus operation) of different variables. These show the relationship between an independent variable and the consecutive difference of a dependent variable.

    These are not complex equations, and usually they depend upon arithmetic operations. Here is a simple example of the difference equation:

    y(n)− 34y(n−1)+y(n−2)=x(n)+x(n−3)

    Another example of the difference equation is:

    𝒚-(𝒏+𝟐)−𝟔𝒚-(𝒏+𝟏)+𝟗𝒚-𝒏=𝟐^𝒏

    There are certain steps that are used to solve the difference equation, and these are given next:

    • Convert the difference equation into the algebraic equation using the specific procedure of the z transform. 

    • Calculate the solution of the resultant equation in the z domain. 

    • Take the time domain equation of the result by using the inverse z transform (that we learned in the previous lecture).

    Difference Equation in MATLAB


    Code

    Output

    fs=1000;

    t=0:1/fs:1

    f=2;

    x=cos(2*pi*f*t)

    n=-0.1+(0.1*0.1)*rand(1,length(x))

    nx=n+x;

    num=[1 0.3 1/3]

    den=[1]

    y=filter(num,den,x);

    plot(t,y)


    Here, you can see that we have used the plot command to see the signal graphically. You can skip it if you want to have the numerical values only. By changing the frequency value, you can have different types of results. Other parameters that qwe have used are the same that we have described in the previous sections of this series. 

    Applications of z Transform

    Z transform has great significance in the mathematical field, especially in the signal and system and other branches where the signals have a fundamental role. Till now, we have learned a lot of things about this transform and therefore, we expect that you will understand the reason why this transform is used in almost every field of mathematics. 

    Analysis of Digital Filters

    As we have said earlier, z transform deals with discrete-time signals. This is the main reason z transform is used in the process of digital filter analysis. The interesting fact is, laplace transform can not be used in this regard because they can not work on the discrete signals. 

    The digital filters are the mathematical algorithms that are mainly used in the implemetnatation of digital input signals to obtain the digital output signals.

    Analysis of Linear Discrete System

    One of the property that we have learned till now is the linearity of z transform and this property is also used in the analysis process of linear discrete system. The are the system that takes the discrete system as input and after different operations, it also restun us the discrete signals again. Z transform is used to maintain the stability of the result throughout the system.

    Frequency Response

    We all know that the z transform is used to obtain the result in the z plane. It converts the signal with the time domain into other formats, such as the frequency domain. Therefore, while working with the signals, the z transform is used in finding the frequency response. 

    Telecommunication

    In the field of telecommunication, all systems are based upon the transfer of a number of bits from one place to another. Z transform is used there to stabilize the flow of the bits as they are in the form of discrete signals. Other techniques are also useful for the same purpose, but while using the z transform, it becomes easy to predict the results and the time at which the communication will occur. 

    Feedback Control Problems

    A Z transform is used to overcome the feedback control problems of the system. It is done by using different types of signals, including continuous time and discrete time signals. This transform can be used differently when practically implemented.

    Identification of the Signals

    In operations where experts want to know the exponentially changing values of the signals, they prefer to work with the z transform according to the nature of the signal.

    Usage of complex number z in z transform

    As we have learned previously, there is a z value that is used in the work of z transform. This is an important feature of the z transform because of its complex nature. It is used to perform complex calculations easily, which were not possible with the Laplace transform.

    Signal Processing

    Z transform is widely used in signal processing ( as we are reading it from the start). Basically, it is a signal processing tool that is efficiently used in the analysis and interaction of different signals. The poles and zeros used in this type of transform help to recognize the nature of the signal; that is, is it casual, stable, or inverse in nature?

    It was a long article based upon interesting facts about the z transform. We were having the discussion of the z transform from our previous session where we saw the basics of the z transform. We saw the properties of the z transform and discussed the important points to clarify our concepts. We also use MATLAB for the implementation of a difference equation. In the end, we learned the simple description of the z transforms application to make our minds about the importance of this topic. If you want to learn more, you can find examples of each property and Use them as your homework. The next lecture is also going to be a little bit complex yet interesting because we are going to learn another transform, which is the Fourier transform.

    Introduction to Z Transform in Signal and Systems with MATLAB

    Hey learners! Welcome to another exciting lecture in this series of signals and systems. We are learning about the transform in signals and systems, and in the previous lectures, we have seen a bulk of information about the Laplace transform. If you know the previous concepts of signal and system, then this lecture will be super easy for you to learn, but if your concepts are not clear, do not worry because we will revise all the basic information from scratch for our new readers. So, without wasting time, have a look at the topics of today.

    1. What is z transform? 

    2. What is the region of convergence of z transform?

    3. What are some of the important properties of the region of convergence?

    4. How to solve the z transform?

    5. What is an example of the z transform in MATLAB?

    6. What are the methods for the inverse z transform?

    What is z transform?

    You must have an idea that the Laplace transform is a general case transform and converts the signal from a time domain into a frequency domain. The same is the case with the z transform, it changes the domain of the signal but in another way. The Laplace transform is associated with the power signal and the z transform has some other characteristics. Usually, the z transform is used to understand the stability of the system. Z transforms are used in

    • Energy signals

    • Power signals

    • Neither power nor energy signals

    Yet it is applicable to a certain level, and after that level, it is not that much more effective. The Z transform is a powerful mathematical tool and is widely used in mathematical courses and applications including signals and systems. We introduce the z transform as:

    "The Z transform is a mathematical tool that, after different procedures, converts the differential equation (with time domain) into the algebraic equation of the z domain."

    Mathematically, we show it as:

    As you can see clearly, the summation sign contains the limits from negative infinity to positive infinity which means it is a bilateral function of the z transform that we have shared with you. 

    By the same token, you can also predict that the z transform also has another region that lies between the zero to positive infinity. It is called the unilateral z transform and it works a little bit differently than the first case discussed here. We describe it as:

    Let’s discuss the whole statement in detail but prior to starting, recall in your mind the definition of discrete-time signals. We know that:

    “A discrete-time signal is one whose value can be measured at discrete intervals." When working with a discrete-time signal, there will be time intervals of n during which you will not have a value. In the representation of DT signals, the form x[n] is used. Discrete signals approximate continuous-time (CT) signals."

    Therefore, when talking about the z transform, keep the definition of z transform in your mind to understand what exactly is going on. 

    Now, look at the statement given above.

    • We have the discrete-time signal in the time domain represented by x[t]. 

    • We applied the z transform to it. 

    • Now, we got the same signal that lies in the z domain and is multiplied with a complex number z having the exponential of the n with a negative sign. 

    • Do not worry about the value of n all the time. The summation sign indicates that the value of n starts from negative infinity (or zero in unilateral z transform) to positive infinity, and in this way, we found the values of the series. (This will be much clearer when we discuss the procedure).

      Here z is a complex number that is described with the help of this equation:

      At this level, there is no need to describe the basic concepts of complex numbers. In general, we can summarize the above discussion through the statement given next:

      x(n)⟷X(Z)

      The whole discrete time signal is converted into another format with the z transform as a base,

      Region of Convergence of z Transform

      The region of convergence, or simply ROC, is an important term that is used to describe the range of z in the z transform. As we have said, z is a complex number and its range, therefore, has different types of properties. 

      Properties of the Region of Convergence

      • No. of poles: In z transform, where x[z] is always finite, there are no poles. (We’ll define them in a later section). The ROC of the z transform does not contain any poles. 

      • When talking about a right-sided signal, the region of convergence is always outside the z-plane circle.

      Where the shaded area is ROC.


      • When talking about a left-sided signal, the region of convergence is always inside the z-plane circle.

      Where the shaded area is ROC.

      • If we have the signal on both sides, then the region of ROC is in the form of a ring inside the circle. 

      • To have a stable form, the region of convergence has a unit value.

      Procedure to Solve z Transform

      There are different cases in the z transform that if we start to describe, will be more confusing and time taking than other transforms. So, we’ll discuss a general format of z transform, and after practice, you will learn the procedure effectively. 

      Thoroughly examine the question. 

      Use the formula of the z transform given above.

      • Put z into the denominator as it has negative power. Doing so will convert the negative power into a positive. 

      • Make sure you take the common values out of the sequence. 

      • Put the value of n as 0, 1, 2, 3, 4, and so on to get the series. 

      • Solve the equation.

      It is the most basic and simple description, but the z transform is not that simple. Instead of solving the long calculations, why not use MATLAB for practical implementation? If you have your own course instructor at university, you must have the idea of solving the procedure by hand. 

      Z transform in MATLAB

      In MATLAB, the z transform is as simple as the previous transform was. Therefore, we are emphasizing the usage of MATLAB at every step. Note that if you want to have a detailed procedure to perform the functions theoretically, you can find your instructors. But from the performance point of view, you should go to MATLAB to confirm your answers all the time. Here is a simple example of an equation that also shows some little details. 

      Code:

      syms n;

      f=(2*n+5)/3

      disp('x[n]=')

      disp(f)

      ans=ztrans(f)

      disp('z[n]')

      disp(F)


      Output:

      Here, you can see we have used the pre-defined function of z transform given as:

      ztrans(x)

      With the help of the z transform, you can solve any equation or expression that you want. 

      Notice that we have used a display function in the code. You must know that z transform can also be done in MATLAB without using the function. 

      Display function in MATLAB

      The display function is used to label the numerical output. It does the same work as the xlabel and ylabel in the graphical window of MATLAB. Moreover, this function is also used to call the value that we have specified before using it and to display the results directly. The syntax of the display function is

      1. disp(x)

      2. disp(‘x’)

      Where,

      • To display the string value, we use inverted commas around the value. 

      • To call the value of x, we simply use it as it is. 

      • Never use this function with a capital D or any other change in the spelling, otherwise, you will get the error. 

      Have a look at another example of the z transform in which we added two trigonometric functions and found their z transform.

      Code:

      syms n;

      f=sin(2*n)

      ans=ztrans(f)

      g=cos(3*3.14*n)

      ans=ztrans(g)

      Output:

      Zaros and poles of z transform

      When you study this particular topic of z transform, you will hear some terms named as zeros and poles. These are the simple topics while learning z transform and usually, are used in the numerical problem. Consider the following equation:

      Zeros: while solving the equation with the fraction, the numerator contains the M roots corresponding to the zeros. In the equation given above, q represents the zeros.

      Poles: When you are solving the fractional equation by z transform, the N roots in the denominator are called the poles. Here, these are represented with the letter p.

      While solving the z transform, we make a circular representation to solve the equation, just like we did while we were learning ROC. Poles are represented at the y-axis, and zeros are represented at the x-axis.

      Inverse z Transform

      As you can guess from the name, the inverse z transform is used to convert the results of the z transform into the form before the z transform. There are different methods through which the calculations of the z transform are inverted from an equation. 

      1. Long division 

      2. The partial fraction method of inverse z transforms

      3. Residue method

      4. Power series of inverse z transform

      Long Division Method 

      This method is applicable when:

      • There is a ratio of two polynomials

      • The polynomials can not be factorized

      To apply inverse z transform with this method, the division process of numerator with denominator is carried out. The resultant equation is then passed through the procedure of inverse z transform and we get the results. It is a complex method. 

      Partial Fraction Method of Inverse z Transform

      This is the method that involves the rules and procedure of partial fraction (we have received it in the previous lecture) and after that, the inverse z transform is applied. 

      Residue Method

      There are different names for this method including the inversion integration method and contour integral method. For this method, we have to follow the equation given below:

      The inverse z transform is obtained by summing up all the residues of this equation from the poles point of view.

      Power Series of Inverse z Transform

      In the end, this is the simplest and easiest way to find the z transform. In this method, the equation is expanded and we get the series of ascending powers. After that, the coefficient of z^-n is the required result. 

      Inverse z transform in MATLAB 

      To apply the inverse z transform in MATLAB, we use the following formula:

      iztrans(x)

      For convenience, we have put the process of z transform and the inverse in the same code. 

      Code:

      syms n;

      f=sin(2*n)

      F=ztrans(f)

      G=iztrans(F)

      Output:

      You can clearly see that we got our required result easily. This type of transforms is used when the data is being transferred to different networks. There are many applications of this transform and you will learn about them in the next section. 

      We have started the discussion of another transform named the z transform that is somehow similar to the Laplace transform that we have learned in the previous sessions. Z transform is a useful mathematical tool and we studied the ROC, procedure, and the inverse method of z transform. We also saw some examples in MATLAB. In the next lecture, we are going to learn some other basic information on the same topic.

      Syed Zain Nasir

      I am Syed Zain Nasir, the founder of <a href=https://www.TheEngineeringProjects.com/>The Engineering Projects</a> (TEP). I am a programmer since 2009 before that I just search things, make small projects and now I am sharing my knowledge through this platform.I also work as a freelancer and did many projects related to programming and electrical circuitry. <a href=https://plus.google.com/+SyedZainNasir/>My Google Profile+</a>

      Share
      Published by
      Syed Zain Nasir