With the ever-increasing demand for higher technology, there has been a rapid growth in the field of IoT. You would require a professional IoT app development company for implementing the correct connected technology solution for your business.
As we are moving towards and becoming the tech generation, it's exciting to know how IoT Application Development has a huge Market Potential - wondering how it is possible? Let us tell you more.
Let us tell you a fun fact. Worldwide there are about 9 billion Internet of Things (IoT) devices connected in 2020, which is expected to grow up to 25 billion in 2030.
In addition to this, we will also see a tremendous increase in the earnings & profit that would be generated by IoT and it is capturing all fields and sectors with speed equal to light and would soon become a major life-important technology.
Still not convinced enough to invest in IoT Application Development? Well, let us help you!
Familiar with these above questions? Don't worry; we have got your back!
The Internet of things has the potential to turn your home into a smart home and make processes automated. It's the world of 5G, and thus both IoT and 5G technologies, when combined, can result in super-advanced technologies and techniques. With each passing day, IoT Application Development services come to life and make more sense than previous days. IoT in the construction industry can boost work productivity and get access to real-time reporting. It can say that it covers almost every aspect!
Not only are the ones listed above, but there are many reasons why companies invest in IoT Application development.
To all the Start-up owners, this is for you. IoT applications are the need of the hour because they solve inefficient, slow, and costly processes that many enterprises of different industries were bearing previously. Therefore, many prominent global companies acquire the start-ups for their ideas and promising innovations so that they can integrate them with their existing operation to get better work efficiency performance and increase the turnover while decreasing the cost.
IoT sensors and devices can automate various routine operations, making it possible to have minimum human participation. It also reduces the amount of time required to complete a task. Hence it makes the processes more productive and cost-efficient.
IoT makes things simple for employees too. It helps them perform complex tasks that might take long hours of effort and work to be completed in minutes. Some of the advantages are:
IoT sensors can save you from significant breakdown risks. IoT sensors predict future equipment failures based on several factors.
This helps the responsible personnel take care of the faulty spare parts without affecting the whole operation.
And applying machine learning to collect data helps employees to determine the exact service time of each part of the machine that leads to efficiency in the investment of equipment.
Above, we have discussed the reasons to invest in IoT application and development and why big firms have ever-growing interests in IoT investment. IoT products and devices are becoming a vital part of every industry day by day, and soon they will become a necessity.
Many IT companies offer IoT application development services that help businesses to gain real-time data and insights to analyze their areas of improvement and increase revenue by reducing their costs.
So, if you are an IT start-up that is looking to revolutionize the industry, then all you need is to innovate an IoT product that solves industries' problems and delivers the results.
Hello readers, I hope you all are doing great. In this tutorial, we will learn about the ESP-NOW protocol and how to communicate data between two ESP modules through ESP-NOW protocol and that is too without Wi-Fi connectivity.
Where To Buy? | ||||
---|---|---|---|---|
No. | Components | Distributor | Link To Buy | |
1 | ESP32 | Amazon | Buy Now |
Fig. 1: ESP-NOW Protocol
ESP–NOW is a connectionless communication protocol that is used for sharing small data packets between two ESP boards. This protocol is developed by Espressif.
Although, ESP-NOW protocol can communicate only small data packets ( maximum 250 bytes), but it is a high-speed protocol for wireless communication.
ESP devices can communicate over ESP-NOW protocol in different network topologies which makes it a very versatile protocol. The communication can be a point to point or point to multipoint (broadcast).
Fig. 2: Point to Point Communication
In peer-to-peer communication, only two ESP (either ESP32 or ESP8266) devices can connect with each other for data exchange. Each ESP device can act as a master device, a slave device or both master and slave at the same time.
In broadcast one ESP device (known as a broadcaster) act as a master device and broadcast the data to ESP devices acting as slave devices. Data is shared with all the slave devices simultaneously.
This communication method is used when users want to control multiple slave devices at a time.
Fig. 4: Many to One Communication
In many to one communication scenarios, there will be a central node or gateway which collects all the data from its nearby connected ESP devices.
This scenario can be applied when you need to collect sensor data from various sensor nodes to a single collector or central device, which is connected to all the nearby sensors.
MAC address or Media Access Control address is a six-byte hexadecimal address, that is used to track or connect with devices in a network. It provides the user with a secure way to identify senders and receivers in a network and avoid unwanted network access.
Fig. 5: MAC Address
Each ESP device has a unique MAC address.
So, before sharing the data between two or more ESP devices the MAC address of the receiver device should be known to the sender device.
Both, the ESP32 and ESP8266 modules support the ESP-NOW protocol.
In this tutorial, we will connect the ESP32 and ESP8266 using the ESP-NOW protocol.
Fig. 6: ESP-NOW Example Code in Arduino IDE
#include <esp_now.h>
#include <WiFi.h>
// REPLACE WITH YOUR RECEIVER MAC Address
uint8_t broadcastAddress[] = {0xEE, 0xFA, 0xBC, 0xC5, 0xA4, 0xBF};
typedef struct struct_message {
char a[32];
int b;
float c;
bool d;
} struct_message;
// Create a struct_message called myData
struct_message myData;
// callback when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
Serial.print("\r\nLast Packet Send Status:\t");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}
void setup() {
// Init Serial Monitor
Serial.begin(115200);
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
// get the status of Trasnmitted packet
esp_now_register_send_cb(OnDataSent);
// Register peer
esp_now_peer_info_t peerInfo;
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
// Add peer
if (esp_now_add_peer(&peerInfo) != ESP_OK){
Serial.println("Failed to add peer");
return;
}
}
void loop()
{ strcpy(myData.a, "THIS IS A CHAR"); // Send message via ESP-NOW esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData)); if (result == ESP_OK) { Serial.println("Sent with success"); } else { Serial.println("Error sending the data"); } delay(2000); }
Fig. 12: Serial monitor and Wi-Fi Initialization
Fig. 13
Fig. 14
#include <WifiEspNow.h>
#if defined(ARDUINO_ARCH_ESP8266)
#include <ESP8266WiFi.h>
#elif defined(ARDUINO_ARCH_ESP32)
#include <WiFi.h>
#endif
// The recipient MAC address. It must be modified for each device.
static uint8_t PEER[]{0x02, 0x00, 0x00, 0x45, 0x53, 0x50};
void printReceivedMessage(const uint8_t mac[WIFIESPNOW_ALEN],
const uint8_t* buf, size_t count, void* arg)
{
Serial.printf("Message from %02X:%02X:%02X:%02X:%02X:%02X\n", mac[0], mac[1], mac[2], mac[3],
mac[4], mac[5]);
for (int i = 0; i < static_cast<int>(count); ++i) {
Serial.print(static_cast<char>(buf[i]));
}
Serial.println();
}
void setup()
{
Serial.begin(115200);
Serial.println();
WiFi.persistent(false);
WiFi.mode(WIFI_AP);
WiFi.disconnect();
WiFi.softAP("ESPNOW", nullptr, 3);
WiFi.softAPdisconnect(false);
Serial.print("MAC address of this node is ");
Serial.println(WiFi.softAPmacAddress());
uint8_t mac[6];
WiFi.softAPmacAddress(mac);
Serial.println();
Serial.println("You can paste the following into the program for the other device:");
Serial.printf("static uint8_t PEER[]{0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X};\n", mac[0],
mac[1], mac[2], mac[3], mac[4], mac[5]);
Serial.println();
bool ok = WifiEspNow.begin();
if (!ok) {
Serial.println("WifiEspNow.begin() failed");
ESP.restart();
}
WifiEspNow.onReceive(printReceivedMessage, nullptr);
ok = WifiEspNow.addPeer(PEER);
if (!ok) {
Serial.println("WifiEspNow.addPeer() failed");
ESP.restart();
}
}
loop()
{
char msg[60];
int len = snprintf(msg, sizeof(msg), "hello ESP-NOW from %s at %lu",
WiFi.softAPmacAddress().c_str(), millis());
WifiEspNow.send(PEER, reinterpret_cast<const uint8_t*>(msg), len);
delay(1000);
}
This concludes the tutorial. I hope, you found this helpful and I hope to see you soon for the new ESP32 tutorial.
Hello friends, I hope you all are doing great. Welcome to the 3rd lecture of Section 5(ESP32 Sensors) in the ESP32 Programming Series. We have already discussed the two built-in ESP32 sensors i.e. Hall Effect Sensor and Capacitive Touch Sensor. Today, we are going to discuss the 3rd and final built-in ESP32 sensor i.e. Internal Temperature Sensor.
ESP32 Internal Temperature Sensor is used to calculate the temperature of the ESP32 core. So, we can't use it to measure the ambient temperature (the temperature of the atmosphere), for that, we need to use embedded temperature sensors i.e. DS18B20, DHT11, BMP280 etc. We will first discuss the basics of this Internal Temperature Sensor and then will design a code to monitor the change in temperature by changing the frequency of the ESP32 CPU.
Note:
Important specs of the ESP32 Temperature Sensor are given in the below table:
ESP32 Temperature Sensor Features |
||||
---|---|---|---|---|
Parameter | Value | |||
Converter Types | ADC (Analog-to-Digital Converter), DAC (Digital-to-Analog Converter) | |||
Accurate Temperature Sensing Range | -40 °C to 125 °C | |||
Suitability | Good | |||
Most Accurate Range | -10 °C to 80 °C | |||
Temperature Fluctuation Measurement | High resolution | |||
Potential Performance & Accuracy Issues | Voltage fluctuations, Noise, Environmental factors, Nearby heat sources |
Where To Buy? | ||||
---|---|---|---|---|
No. | Components | Distributor | Link To Buy | |
1 | ESP32 | Amazon | Buy Now |
ESP32’s on-chip temperature sensor cannot be used for monitoring external temperature. It can only be used to monitor the temperature of the core. This temperature sensor is available on some selective ESP32 boards and obsolete on most ESP32 variants. It has a high-temperature sensing range of -40 to 125 °C.
ESP32 boards are normally used in real-time IoT Projects i.e. home automation, back security etc. Such projects need to run 24/7 to get live updates and may heat up the motherboard. Thus, to get a stable performance in continuous operations, these internal temperature sensors are introduced to monitor the ESP32 Core.
Most of the modern ESP32 variants are equipped with the Internal Temperature Sensor. I have created a list of the ESP32 boards by taking the ESP-IDF documentation that caters to the built-in temperature sensor. Here's the list:
As you can see, most of the newer versions have a temperature sensor, but some older versions may also have one.
ESP32 temperature sensor consists of 2 converters:
Sigma-delta ADCs are widely favored for their exceptional accuracy and remarkable resolution, enabling them to deliver precise measurements. This ADC takes the analog signal from the temperature sensor, converts it to a digital signal and feeds it to the microcontroller for processing.
The DAC is responsible for the accuracy of the temperature measurements. It is embedded within the ESP32 and converts the digital values(converted by the Sigma-Delta ADC) again into analog values to offset any temperature-induced variation. As a result, it ensures accurate readings from the sensor.
The accuracy of this temperature sensor changes according to the range group of the temperature values. Among different groups, the range of -10 ~ 80 is the most accurate. The reading errors along with their measuring ranges are shown in the below table:
Measuring Errors in ESP32 Temperature Sensor | ||||
---|---|---|---|---|
No. | Offset | Predefined Range (°C) | Error (°C) | Operating Range (°C) |
1 | -2 |
50 ~ 125 | < 3 | Not recommended(Error) |
2 |
-1 |
20 ~ 100 | < 2 | Ideal range for best accuracy |
3 |
0 | -10 ~ 80 | < 1 | Acceptable range with moderate accuracy |
4 |
1 |
-30 ~ 50 | < 2 | Usable range with increased error at extremes |
5 |
2 |
-40 ~ 20 | < 3 | Not recommended (error) |
Different factors, including voltage fluctuations, noise, environmental factors, and nearby heat sources, can affect the performance and accuracy of this sensor.
Formula to convert observed temperature i.e. Fahrenheit to Celsius:
(F-32) *(5/9) = degree Celsius
Here are the main applications of the ESP32 built-in temperature sensor:
A designer can easily monitor the internal chip’s temperature through the temperature sensor, identify bottleneck conditions, and conduct performance evaluations under extreme circumstances. So, the sensor helps in optimizing the chip's temperature and, thus, the performance.
Electronic components/modules are sensitive, and if they are designed to work for prolonged operation, temperature management is one of the most crucial points to be considered. The built-in temperature sensor is a useful way to measure the operating temperature of the components connected to its peripherals and the whole system. These values are then utilized to set the threshold value so the system can trigger the safety mechanism when a certain heat level is passed. This can be done using the ESP32 code and surely prevent overheating to maintain the performance.
The built-in temperature sensor helps to maintain the energy monitoring that, in turn, allows the energy monitoring of the project. The careful observation of the built-in temperature sensor output helps the user understand the relationship between temperature change and energy consumption. Using this approach, designers can target an optimized energy consumption.
#ifdef __cplusplus
extern "C" {
#endif
uint8_t temprature_sens_read();
#ifdef __cplusplus
}
#endif
uint8_t temprature_sens_read();
void setup()
{
Serial.begin(115200);
}
void loop()
{
Serial.print("Temperature: ");
Serial.print(temprature_sens_read() );
Serial.print(" F");
Serial.print("______");
// Convert raw temperature in F to Celsius degrees
Serial.print((temprature_sens_read() - 32) / 1.8);
Serial.println(" C");
delay(1000);
}
#ifdef __cplusplus
extern "C" {
#endif
uint8_t temprature_sens_read();
#ifdef __cplusplus
}
#endif
uint8_t temprature_sens_read();
void setup()
{
Serial.begin(115200);
}
void loop()
{
Serial.print("Temperature: ");
Serial.print(temprature_sens_read() );
Serial.print("______");
}
// Convert raw temperature in F to Celsius degrees
Serial.print((temprature_sens_read() - 32) / 1.8);
Serial.println(" C");
delay(1000);
This concludes the tutorial. I hope you found this of some help and also to see you soon with the new tutorial on ESP32.
Hello readers, I hope you all are doing great. In our previous tutorial, we learned SMTP server and how to implement an SMTP server for sending emails with ESP32. In the previous tutorial, we also demonstrated some examples like sharing raw text, HTML text, images and text files.
So, at the transmitter end, we are using the SMTP server.
But, what about the receiver end?
At the receiver end, we use another protocol called IMAP (or Internet Message Access Protocol) and POP3 (Post office Protocol V3) for receiving the emails.
Where To Buy? | ||||
---|---|---|---|---|
No. | Components | Distributor | Link To Buy | |
1 | ESP32 | Amazon | Buy Now |
IMAP is an application layer (TCP/IP) protocol that is used at the receiver end to receive emails from SMTP server or mail server. IMAP follows the client/server model.
POP3 stands for Post Office Protocol version 3.
POP3 is another protocol to receive emails. This protocol is used to access the TCP/IP mailbox. The protocol is quite popular due to its offline mail access model.
The offline access model enables the user to access the mails from the mail server on the local machine, and then delete them from the mail server.
Though in some applications POP3 protocol is still used, but in most of the email receivers, it is preferred to use IMAP protocol over POP3 protocol.
Similarly, other email service providers like Outlook and Hotmail, have different setting parameters.
To send emails with ESP32 we need to install this ESP Mail Client library. This library, make ESP32 able to send emails over SMTP server.
Step to install ESP Mail Client Library:
Your Arduino IDE is ready to send email using ESP32.
It is recommended to create a new email account for sending emails using ESP32 or ESP8266 modules.
If you are using your main (personal) email account (for sending emails) with ESP and by mistake, something goes wrong in the ESP code or programming part, your email service provider can ban or disable your main (personal) email account.
In this tutorial, we are using a Gmail account.
Follow the link to create a new Gmail account: https://accounts.google.com
To get access to this new Gmail account, you need to enable Allow less secure apps and this will make you able to send emails. The link is attached below:
https://myaccount.google.com/lesssecureapps?pli=1
Fig.
Fig IMAP and SMTP Example Code
Note: You can not use the exact code. Hence, you need to make some changes like replacing SSID and password with your network credentials, email address of sender and receiver, setting IMAP and SMTP parameters for respective email service providers etc, needs to be done before uploading the code. We will also describe these things during code description.
In this code, we will implement both IMAP and SMTP protocols to receive and transmit emails.
Although, we are using SMTP in this tutorial, but we have already discussed and demonstrated the implementation on SMTP protocol in our previous tutorial. So, in this tutorial we will not explain the SMTP part.
Follow our previous tutorial for detailed study of SMTP implementation in ESP32.
#include <Arduino.h>
#include <WiFi.h>
#include <ESP_Mail_Client.h>
//To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h.
#define WIFI_SSID "public"
#define WIFI_PASSWORD "ESP32@123"
//-----------setting IMAP parameters------
/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */
#define IMAP_HOST "imap.gmail.com"
#define IMAP_PORT 993
#define AUTHOR_EMAIL "techeesp697@gmail.com"
#define AUTHOR_PASSWORD "Tech@ESP123"
#define RECIPIENT_EMAIL "maneesha607ece@gmail.com"
//------------setting SMTP credentials----------
#define SMTP_HOST "smtp.gmail.com"
#define SMTP_PORT 465
//------IMAP Rx emails and their status
/* Callback function to get the Email reading status */
void imapCallback(IMAP_Status status);
void printAllMailboxesInfo(IMAPSession &imap);
void printSelectedMailboxInfo(SelectedFolderInfo sFolder);
void printMessages(std::vector<IMAP_MSG_Item> &msgItems, bool headerOnly);
/* Print all attachments info from the message */
void printAttacements(std::vector<IMAP_Attach_Item> &atts);
/* The IMAP Session object used for Email reading */
IMAPSession imap;
//-------SMTP sending mails and their status----
/* The SMTP Session object used for Email sending */
SMTPSession smtp;
/* Callback function to get the Email sending status */
void smtpCallback(SMTP_Status status);
void setup()
{
Serial.begin(115200);
#if defined(ARDUINO_ARCH_SAMD)
while (!Serial)
;
Serial.println();
Serial.println("**** Custom built WiFiNINA firmware need to be installed.****\nTo install firmware, read the instruction here, https://github.com/mobizt/ESP-Mail-Client#install-custom-built-wifinina-firmware");
#endif
Serial.println();
Serial.print("Connecting to AP");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
delay(200);
}
Serial.println("");
Serial.println("WiFi connected.");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
Serial.println();
/** Enable the debug via Serial port
* none debug or 0
* basic debug or 1
*
* Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h
*/
imap.debug(1);
/* Set the callback function to get the reading results */
imap.callback(imapCallback);
ESP_Mail_Session session;
session.server.host_name = IMAP_HOST;
session.server.port = IMAP_PORT;
session.login.email = AUTHOR_EMAIL;
session.login.password = AUTHOR_PASSWORD;
/* Setup the configuration for searching or fetching operation and its result */
IMAP_Config config;
/* Set seen flag */
//config.fetch.set_seen = true;
/* Search criteria */
config.search.criteria.clear();
/* Also search the unseen message */
config.search.unseen_msg = true;
/* Set the storage to save the downloaded files and attachments */
config.storage.saved_path = "/email_data";
config.storage.type = esp_mail_file_storage_type_flash;
config.download.header = true;
config.download.text = true;
config.download.html = true;
config.download.attachment = true;
config.download.inlineImg = true;
config.enable.html = true;
config.enable.text = true;
/* Set to enable the sort the result by message UID in the ascending order */
config.enable.recent_sort = true;
/* Set to report the download progress via the default serial port */
config.enable.download_status = true;
config.limit.search = 5;
config.limit.msg_size = 512;
config.limit.attachment_size = 1024 * 1024 * 5;
/* Connect to server with the session and config */
if (!imap.connect(&session, &config))
return;
/* {Optional} */
printAllMailboxesInfo(imap);
/* Open or select the mailbox folder to read or search the message */
if (!imap.selectFolder("INBOX"))
return;
/* {Optional} */
printSelectedMailboxInfo(imap.selectedFolder());
String uid = String(imap.getUID(imap.selectedFolder().msgCount()));
config.fetch.uid = uid;
/* Read or search the Email and close the session */
//When message was fetched or read, the /Seen flag will not set or message remained in unseen or unread status,
//as this is the purpose of library (not UI application), user can set the message status as read by set \Seen flag
//to message, see the Set_Flags.ino example.
MailClient.readMail(&imap);
/* Clear all stored data in IMAPSession object */
imap.empty();
}
void loop()
{
}
/* Callback function to get the Email reading status */
void imapCallback(IMAP_Status status)
{
/* Print the current status */
Serial.println(status.info());
/* Show the result when reading finished */
if (status.success())
{
/* Print the result */
/* Get the message list from the message list data */
IMAP_MSG_List msgList = imap.data();
printMessages(msgList.msgItems, imap.headerOnly());
/* Clear all stored data in IMAPSession object */
imap.empty();
SMTP_MSG();
}
}
void printAllMailboxesInfo(IMAPSession &imap)
{
/* Declare the folder collection class to get the list of mailbox folders */
FoldersCollection folders;
/* Get the mailbox folders */
if (imap.getFolders(folders))
{
for (size_t i = 0; i < folders.size(); i++)
{
/* Iterate each folder info using the folder info item data */
FolderInfo folderInfo = folders.info(i);
ESP_MAIL_PRINTF("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : "");
}
}
}
void printSelectedMailboxInfo(SelectedFolderInfo sFolder)
{
/* Show the mailbox info */
ESP_MAIL_PRINTF("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount());
ESP_MAIL_PRINTF("Predicted next UID: %d\n", sFolder.nextUID());
for (size_t i = 0; i < sFolder.flagCount(); i++)
ESP_MAIL_PRINTF("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : "");
}
void printAttacements(std::vector<IMAP_Attach_Item> &atts)
{
ESP_MAIL_PRINTF("Attachment: %d file(s)\n****************************\n", atts.size());
for (size_t j = 0; j < atts.size(); j++)
{
IMAP_Attach_Item att = atts[j];
/** att.type can be
* esp_mail_att_type_none or 0
* esp_mail_att_type_attachment or 1
* esp_mail_att_type_inline or 2
*/
ESP_MAIL_PRINTF("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.creationDate);
}
Serial.println();
}
void printMessages(std::vector<IMAP_MSG_Item> &msgItems, bool headerOnly)
{
for (size_t i = 0; i < msgItems.size(); i++)
{
/* Iterate to get each message data through the message item data */
IMAP_MSG_Item msg = msgItems[i];
Serial.println("****************************");
ESP_MAIL_PRINTF("Number: %d\n", msg.msgNo);
ESP_MAIL_PRINTF("UID: %d\n", msg.UID);
ESP_MAIL_PRINTF("Messsage-ID: %s\n", msg.ID);
ESP_MAIL_PRINTF("Flags: %s\n", msg.flags);
//The attachment may not detect in search because the multipart/mixed
//was not found in Content-Type header field.
ESP_MAIL_PRINTF("Attachment: %s\n", msg.hasAttachment ? "yes" : "no");
if (strlen(msg.acceptLang))
ESP_MAIL_PRINTF("Accept Language: %s\n", msg.acceptLang);
if (strlen(msg.contentLang))
ESP_MAIL_PRINTF("Content Language: %s\n", msg.contentLang);
if (strlen(msg.from))
ESP_MAIL_PRINTF("From: %s\n", msg.from);
if (strlen(msg.sender))
ESP_MAIL_PRINTF("Sender: %s\n", msg.sender);
if (strlen(msg.to))
ESP_MAIL_PRINTF("To: %s\n", msg.to);
if (strlen(msg.cc))
ESP_MAIL_PRINTF("CC: %s\n", msg.cc);
if (strlen(msg.date))
{
ESP_MAIL_PRINTF("Date: %s\n", msg.date);
ESP_MAIL_PRINTF("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date));
}
if (strlen(msg.subject))
ESP_MAIL_PRINTF("Subject: %s\n", msg.subject);
if (strlen(msg.reply_to))
ESP_MAIL_PRINTF("Reply-To: %s\n", msg.reply_to);
if (strlen(msg.return_path))
ESP_MAIL_PRINTF("Return-Path: %s\n", msg.return_path);
if (strlen(msg.in_reply_to))
ESP_MAIL_PRINTF("In-Reply-To: %s\n", msg.in_reply_to);
if (strlen(msg.references))
ESP_MAIL_PRINTF("References: %s\n", msg.references);
if (strlen(msg.comments))
ESP_MAIL_PRINTF("Comments: %s\n", msg.comments);
if (strlen(msg.keywords))
ESP_MAIL_PRINTF("Keywords: %s\n", msg.keywords);
/* If the result contains the message info (Fetch mode) */
if (!headerOnly)
{
if (strlen(msg.text.content))
ESP_MAIL_PRINTF("Text Message: %s\n", msg.text.content);
if (strlen(msg.text.charSet))
ESP_MAIL_PRINTF("Text Message Charset: %s\n", msg.text.charSet);
if (strlen(msg.text.transfer_encoding))
ESP_MAIL_PRINTF("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding);
if (strlen(msg.html.content))
ESP_MAIL_PRINTF("HTML Message: %s\n", msg.html.content);
if (strlen(msg.html.charSet))
ESP_MAIL_PRINTF("HTML Message Charset: %s\n", msg.html.charSet);
if (strlen(msg.html.transfer_encoding))
ESP_MAIL_PRINTF("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding);
if (msg.rfc822.size() > 0)
{
ESP_MAIL_PRINTF("RFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size());
printMessages(msg.rfc822, headerOnly);
}
}
Serial.println();
}
}
void SMTP_MSG()
{
smtp.debug(1);
smtp.callback(smtpCallback);
ESP_Mail_Session session;
session.server.host_name = SMTP_HOST;
session.server.port = SMTP_PORT;
session.login.email = AUTHOR_EMAIL;
session.login.password = AUTHOR_PASSWORD;
session.login.user_domain = "";
/* Declare the message class */
SMTP_Message message;
message.sender.name = "The_Engineering_Projects";
message.sender.email = AUTHOR_EMAIL;
message.subject = "Auto_Response";
message.addRecipient("Maneesha", RECIPIENT_EMAIL);
//Send raw text message
String textMsg = "Thanks for contacting us. One of our client will contact you soon. www.theengineeringprojects";
message.text.content = textMsg.c_str();
message.text.charSet = "us-ascii";
message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit;
message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low;
message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay;
/* Connect to server with the session config */
if (!smtp.connect(&session))
return;
/* Start sending Email and close the session */
if (!MailClient.sendMail(&smtp, &message))
Serial.println("Error sending Email, " + smtp.errorReason());
}
//-----------SMTP Status function-----
// Callback function to get the Email sending status
void smtpCallback(SMTP_Status status)
{
/* Print the current status */
Serial.println(status.info());
/* Print the sending result */
if (status.success())
{
Serial.println("----------------");
ESP_MAIL_PRINTF("Message sent success: %d\n", status.completedCount());
ESP_MAIL_PRINTF("Message sent failled: %d\n", status.failedCount());
Serial.println("----------------\n");
struct tm dt;
for (size_t i = 0; i < smtp.sendingResult.size(); i++)
{
/* Get the result item */
SMTP_Result result = smtp.sendingResult.getItem(i);
time_t ts = (time_t)result.timestamp;
localtime_r(&ts, &dt);
ESP_MAIL_PRINTF("Message No: %d\n", i + 1);
ESP_MAIL_PRINTF("Status: %s\n", result.completed ? "success" : "failed");
ESP_MAIL_PRINTF("Date/Time: %d/%d/%d %d:%d:%d\n", dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec);
ESP_MAIL_PRINTF("Recipient: %s\n", result.recipients);
ESP_MAIL_PRINTF("Subject: %s\n", result.subject);
}
Serial.println("----------------\n");
}
}
Fig. SMTP server address and port number
Fig.
Fig.
Fig.
Fig.
Note:- We have already discussed the SMTP server in our previous tutorial that is Sending Emails with ESP32 using SMTP server. So, follow our previous tutorial for a detailed study on SMTP protocol and send an email using ESP32.
This concludes the tutorial. I hope you found this helpful and also hope to see you soon with a new tutorial on ESP32.
In 2021, supply chains benefited from the boom in e-commerce as online buyers reached 2.14 billion. Given the massive influx of customers, businesses had to scale up their operations. The challenge now is to improve efficiency and ensure the delivery of goods and services. It has become more challenging for companies to monitor every movement, especially logistics.
Fortunately, service dispatch software can make things easier and safer. Tracking vehicles and organizing schedules will no longer take so much time. This technology can impose desirable changes in daily processes. With that in mind, we will look at how it guides businesses toward growth.
Service dispatch software is a technology that plans and schedules routes. It sends the details to the driver's mobile device. Once received, the management can view the progress on the delivery day. This feature allows them to improve efficiency and customer service.
Through automated technology, 24/7 management of fleets is possible. After automating routing and scheduling processes, coordination of routes and deliveries is easier. It also provides solutions to field workers, technicians, and other service providers. The following are its primary features.
For a better result, it has to work hand in hand with route optimization software. Service dispatch software monitors the delivery process through a cloud-based application. Meanwhile, route optimization software finds the best routes for smooth and efficient delivery. Their combined features can improve business processes and customer satisfaction.
The number of products and services purchased online keeps growing. That is why transportation and logistics play a vital role in the e-commerce industry. Food and grocery delivery services have their software to monitor drivers. Here are the expected benefits of using service dispatch software.
Service dispatch software serves as a centralized tracking system for transportation processes. Its features and connection to GPS and mobile apps provide timely updates. It allows the management to track the location and status of the driver and the items. The information gives the company an idea to improve its dispatch system.
Moreover, it reduces or eliminates paperwork like work order management and service reports. It also generates invoices and provides billing assistance and resource management suggestions. It helps companies save more time and focus on improving customer experience.
Service dispatch software is similar to employee monitoring software. But, it has more detailed info to assess employees. The management can determine whether the drivers follow the driving standards or not. It includes their driving speed, one of the typical causes of road accidents. Also, customers can rate and review their performance.
In a fast-paced environment, responsiveness sets a business apart from its competitors. It is more crucial for those involving field workers and other service providers. With service dispatch software, the management does not have to make follow-ups. The system alone provides all the information they need to track deliveries.
Its real-time statuses alert the people involved with emergency calls and last-minute requests. That is why it is essential to integrate it with route optimization software. It helps you identify the location and nature of the raised concerns. From there, someone can go to the site, assist the driver, and solve the problem.
The system provides data, which helps businesses present them in charts and dashboards. These make the numerical values easier to interpret and generate recommendations. These figures enable them to assess their performance based on specific parameters. These include customer rating, delivery time, costs incurred. This feature also makes the business scalable and flexible to changing business requirements. It ensures that the services can suffice business needs.
Service dispatch software can enhance the delivery process, leading to smoother transactions. Management can do job assignments and schedules faster. There is also shorter waiting and delivery time since the system can find the best route. The goods and services arrive at the exact location on time. In turn, customer satisfaction increases, resulting in higher demand.
Technology is changing, so businesses have to adapt and meet the insatiable demand. In a competitive market landscape, operational efficiency is vital to outdo peers. Service dispatch software improves processes and reduces costs. It helps businesses adapt to the trend and sustain growth.
Hello readers, I hope you all are doing great. In this tutorial, we will learn how to send an email using ESP32 module. We will also learn to send text files, images or some sensor readings using the SMTP server using the ESP32 module.
In IoT (Internet of things), there are various applications where we need to send emails carrying information like sending some sensor readings, altering emails, images, text files and much more.
Where To Buy? | ||||
---|---|---|---|---|
No. | Components | Distributor | Link To Buy | |
1 | ESP32 | Amazon | Buy Now |
SMTP or simple mail transfer protocol is an internet standard for sending and receiving electronic mail (or email) where an SMTP server receives emails from the email client.
SMTP is also used for setting communication between servers.
Various email providers like Gmail, Hotmail, Yahoo, etc. have unique SMTP addresses and port numbers.
SMTP protocol which is also known as a push protocol is used to send emails and IMAP that is Internet Message Access Protocol (or post office protocol or POP) is used to receive emails at the receiver end.
SMTP protocol operates at the application layer of TCP/IP protocol.
When a client wants to send emails, a TCP connection will be open for the SMTP server and emails will be sent across the connection.
SMTP commands:
Gmail is the email service provided by Google and Gmail SMTP server is free to access and anyone can access this service, who has a Gmail account.
Components required to send and receive emails using ESP32 over SMTP server are:
To send emails with ESP32 we need to install this ESP Mail Client library. This library, make ESP32 able to send emails over an SMTP server.
Step to install ESP Mail Client Library:
Your Arduino IDE is ready to send email using ESP32.
It is recommended to create a new email account for sending emails using ESP32 or ESP8266 modules.
If you are using your main (personal) email account (for sending emails) with ESP and by mistake, something goes wrong in the ESP code or programming part, your email service provider can ban or disable your main (personal) email account.
In this tutorial, we are using a Gmail account.
Follow the link to create a new Gmail account: https://accounts.google.com
To get access to this new Gmail account, you need to enable Allow less secure apps and this will make you able to send emails. The link is: https://myaccount.google.com/lesssecureapps?pli=1
Fig SMTP example code
#include <WiFi.h>
#include <ESP_Mail_Client.h>
#define WIFI_SSID "SSID"
#define WIFI_PASSWORD "PASSWORD"
#define SMTP_HOST "smtp.gmail.com"
#define SMTP_PORT 465
/* The sign in credentials */
#define AUTHOR_EMAIL "email address"
#define AUTHOR_PASSWORD "email password"
/* Recipient's email*/
#define RECIPIENT_EMAIL "email address_Rx"
/* The SMTP Session object used for Email sending */
SMTPSession smtp;
/* Callback function to get the Email sending status */
void smtpCallback(SMTP_Status status);
void setup(){ Serial.begin(115200);
Serial.println();
Serial.print("Connecting to AP");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED){
Serial.print(".");
delay(200);
}
Serial.println("");
Serial.println("WiFi connected.");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
Serial.println();
/** Enable the debug via Serial port
none debug or 0 basic debug or 1*/
smtp.debug(1);
/* Set the callback function to get the sending results */
smtp.callback(smtpCallback);
/* Declare the session config data */
ESP_Mail_Session session;
/* Set the session config */
session.server.host_name = SMTP_HOST; session.server.port = SMTP_PORT; session.login.email = AUTHOR_EMAIL; session.login.password = AUTHOR_PASSWORD;
session.login.user_domain = "";
/* Declare the message class */
SMTP_Message message; message.sender.name = "ESP32"; message.sender.email = AUTHOR_EMAIL; message.subject = "ESP32 Test Email";
message.addRecipient("Sara", RECIPIENT_EMAIL);
/*Send HTML message*/
String htmlMsg = "<div style=\"color:#2f4468;\"><h1>Hello CLient!</h1><p>- Sent from ESP board</p></div>"; message.html.content = htmlMsg.c_str(); message.html.content = htmlMsg.c_str(); message.text.charSet = "us-ascii";
message.html.transfer_encoding = Content_Transfer_Encoding::enc_7bit;
//Send raw text message
/* String textMsg = "Hello Client! - you have a message from ESP32 board"; message.text.content = textMsg.c_str(); message.text.charSet = "us-ascii";
message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit;*/
message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low;
message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay;
/* Set the custom message header */
//message.addHeader("Message-ID: <abcde.fghij@gmail.com>");
/* Connect to server with the session config */ if (!smtp.connect(&session))
return;
/* Start sending Email and close the session */ if (!MailClient.sendMail(&smtp, &message))
Serial.println("Error sending Email, " + smtp.errorReason());
}
void loop(){
}
/* Callback function to get the Email sending status */
void smtpCallback(SMTP_Status status){
/* Print the current status */
Serial.println(status.info());
/* Print the sending result */ if (status.success()){
Serial.println("----------------");
ESP_MAIL_PRINTF("Message sent success: %d\n", status.completedCount());
ESP_MAIL_PRINTF("Message sent failled: %d\n", status.failedCount());
Serial.println("----------------\n"); struct tm dt;
for (size_t i = 0; i < smtp.sendingResult.size(); i++){
/* Get the result item */
SMTP_Result result = smtp.sendingResult.getItem(i);
time_t ts = (time_t)result.timestamp; localtime_r(&ts, &dt);
ESP_MAIL_PRINTF("Message No: %d\n", i + 1);
ESP_MAIL_PRINTF("Status: %s\n", result.completed ? "success" : "failed"); ESP_MAIL_PRINTF("Date/Time: %d/%d/%d %d:%d:%d\n", dt.tm_year + 1900,
dt.tm_mon + 1, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec); ESP_MAIL_PRINTF("Recipient: %s\n", result.recipients); ESP_MAIL_PRINTF("Subject: %s\n", result.subject);
}
Serial.println("----------------\n");
}
}
Write the message content (raw text) in the textMsg variable which you want to share over email.
To send HTML text write the respective content in the htmlMsg variable.
Otherwise, you won’t be able to send emails and an error will be printed on the serial monitor.
Arduino IDE code, for sending images and text files using ESP32 and SMTP server:
In this example code, we will demonstrate how to share text files and images through emails using ESP32 over the SMTP server.
But, before sharing attachments (text files or images) you need to save those files on the ESP32 filesystem (SPIFFS).
SPIFFS stands for Serial Peripheral Interface Flash File System, which is built into the ESP32 module. This is a lightweight filesystem designed for microcontrollers with flash chips connected via SPI bus, such as the ESP32 flash memory. In this flash memory, we can write, delete, read, and close files.
Fig.
Check if the plugin is successfully uploaded or not:
Fig.
Finally, uploading files using SPIFFS or filesystem upload:
Fig.
Fig.
Fig.
Fig.
A message “SPIFFS Image Uploaded” will be displayed at the bottom of Arduino IDE, once the SPIFFS image is uploaded successfully.
Fig.
Arduino IDE Code
Code is already available in ESP Mail Client Library. As shown below:
Fig.
// To use send Email for Gmail to port 465 (SSL), less secure app option should be enabled. https://myaccount.google.com/lesssecureapps?pli=1
// The file systems for flash and sd memory can be changed in ESP_Mail_FS.h.
#include <Arduino.h>
#include <WiFi.h>
#include <ESP_Mail_Client.h>
#define WIFI_SSID "SSID"
#define WIFI_PASSWORD "PASSWORD"
// server address for Gmail account
#define SMTP_HOST "smtp.gmail.com"
/** The smtp port e.g.
25 or esp_mail_smtp_port_25 465 or esp_mail_smtp_port_465 587 or esp_mail_smtp_port_587*/
#define SMTP_PORT 465
/* The log in credentials */
#define AUTHOR_EMAIL "Sender's email address"
#define AUTHOR_PASSWORD "password"
/* Recipient's email*/
#define RECIPIENT_EMAIL "receiver's email address"
/* The SMTP Session object used for Email sending */
SMTPSession smtp;
/* Callback function to get the Email sending status */
void smtpCallback(SMTP_Status status);
void setup(){
Serial.begin(115200);
Serial.println();
Serial.print("Connecting to AP");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED){
Serial.print(".");
delay(200);
}
Serial.println("");
Serial.println("WiFi connected.");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
Serial.println();
if (!SPIFFS.begin(true)) {
Serial.println("An error has occurred while mounting SPIFFS");
}
else{
Serial.println("SPIFFS mounted successfully");
}
/** Enable the debug via Serial port
- none debug or 0
- basic debug or 1
*/
smtp.debug(1);
/* Set the callback function to get the sending results */
smtp.callback(smtpCallback);
/* Declare the session config data */
ESP_Mail_Session session;
/* Set the session config */ session.server.host_name = SMTP_HOST; session.server.port = SMTP_PORT; session.login.email = AUTHOR_EMAIL; session.login.password = AUTHOR_PASSWORD;
session.login.user_domain = "mydomain.net";
/* Declare the message class */
SMTP_Message message;
/* Enable the chunked data transfer with pipelining for large message if server supported
*/
message.enable.chunking = true;
/* Set the message headers */ message.sender.name = "ESP Mail";
message.sender.email = AUTHOR_EMAIL;
message.subject = "Test sending Email with attachments and inline images from SD card and Flash";
message.addRecipient("Sara", RECIPIENT_EMAIL);
/** Two alternative content versions are sending in this example e.g. plain text and html */
String htmlMsg = "This message contains attachments: image and text file."; message.html.content = htmlMsg.c_str(); message.html.charSet = "utf-8";
message.html.transfer_encoding = Content_Transfer_Encoding::enc_qp;
message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_normal; message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay;
/* The attachment data item */
SMTP_Attachment att;
/** Set the attachment info e.g.
- file name, MIME type, file path, file storage type,
- transfer encoding and content encoding
*/
att.descr.filename = "image.png"; att.descr.mime = "image/png"; //binary data
att.file.path = "/image.png";
att.file.storage_type = esp_mail_file_storage_type_flash;
att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64;
/* Add attachment to the message */
message.addAttachment(att);
message.resetAttachItem(att);
att.descr.filename = "text_file.txt"; att.descr.mime = "text/plain"; att.file.path = "/text_file.txt";
att.file.storage_type = esp_mail_file_storage_type_flash;
att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64;
/* Add attachment to the message */
message.addAttachment(att);
/* Connect to server with the session config */ if (!smtp.connect(&session))
return;
/* Start sending the Email and close the session */ if (!MailClient.sendMail(&smtp, &message, true))
Serial.println("Error sending Email, " + smtp.errorReason());
}
void loop()
{
}
/* Callback function to get the Email sending status */
void smtpCallback(SMTP_Status status){
/* Print the current status */
Serial.println(status.info());
/* Print the sending result */ if (status.success()){
Serial.println("----------------");
ESP_MAIL_PRINTF("Message sent success: %d\n", status.completedCount());
ESP_MAIL_PRINTF("Message sent failled: %d\n", status.failedCount());
Serial.println("----------------\n"); struct tm dt;
for (size_t i = 0; i < smtp.sendingResult.size(); i++){
/* Get the result item */
SMTP_Result result = smtp.sendingResult.getItem(i); time_t ts = (time_t)result.timestamp;
localtime_r(&ts, &dt);
ESP_MAIL_PRINTF("Message No: %d\n", i + 1);
ESP_MAIL_PRINTF("Status: %s\n", result.completed ? "success" : "failed"); ESP_MAIL_PRINTF("Date/Time: %d/%d/%d %d:%d:%d\n", dt.tm_year + 1900,
dt.tm_mon + 1, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec);
ESP_MAIL_PRINTF("Recipient: %s\n", result.recipients);
ESP_MAIL_PRINTF("Subject: %s\n", result.subject);
}
Serial.println("----------------\n");
}
}
Most part of the code is similar to the previous one (that is sending raw text and HTML text), including libraries, network credentials, enabling Wi-Fi and the serial monitor, setting the email parameters of the respective email service provided. So we not explaining the complete code but, we will explain the programming part which is different than the previous one.
Fig.
Fig.
Fig.
Fig.
Fig.
Fig.
Fig.
Fig.
This concludes the tutorial; I hope you found this helpful and also hope to see you again with a new tutorial on ESP32.
Counters are used in conventional or relay logic control. they mainly receive pulses and count these pulses and when it reaches a preset value the output coil of the counter is energized. They mostly include an LCD showing the counting as shown in figure 1.
Figure 1: Omron counter [1]
The main idea of most counters is counting input pulses by using logic circuits i.e. flip-flop and determining the output based on which an output relay is energized. There are two main types of the counter as regards structure: synchronous counters when all flip-flops and asynchronous counters when each flip-flop is connected to its separate clock. In addition, counters can be classified based on functionality into UP, DOWN, and UP-DOWN counters. If you are not familiar with logic circuit components like flip-flops so do not worry as it's not our concern here. We just want to let you know how physical counters in the traditional controller are complicated and take a lot of space as we need hundreds of flip-flops and other circuit components to have a counter which counts for a limited number. Figure 2 shows the logic circuit of the counter that can count from 0 to 9. It utilizes 4 flip-flops as shown. The type of this counter is an asynchronous counter as each flip-flop takes its clock from the output of the previous flip-flop. Furthermore, table 1 lists the truth table of the counter. It shows how the counter determines the count based on the output Q0, Q1, Q3, and Q4. For example, when all outputs are zeroes, that means the counter reads zero. When Q0 is high, Q1 is low, Q2 is low, and Q3 is high, that means the counter reads 9. But in PLC, it's the easier story, it’s software counters with flexible functionality and usability as well as we will see in the next section. So let's enjoy learning and practicing counters in ladder logic programming.
Figure 2: Asynchronous 0-9 counter
Table 1: the truth table of 0-9 counter
Pulse to be counted | Q3 | Q2 | Q1 | Q0 |
0 | 0 | 0 | 0 | 0 |
1 | 0 | 0 | 0 | 1 |
2 | 0 | 0 | 1 | 0 |
3 | 0 | 0 | 1 | 1 |
4 | 0 | 1 | 0 | 0 |
5 | 0 | 1 | 0 | 1 |
6 | 0 | 1 | 1 | 0 |
7 | 0 | 1 | 1 | 1 |
8 | 1 | 0 | 0 | 0 |
9 | 1 | 0 | 0 | 1 |
Simply, Counter in plc is an instruction to count up or down to preset value and energize an output at reaching that preset value. There are three types of counters in PLC which are:
In this counter, each time a trigger input signal has been received at (CU), the counter counts up until reaching the preset value (PV) to energize output as shown in figure 3. The counter has three inputs: the trigger command, the reload command, and the preset value to set to what number the maximum counter is going to count up. Furthermore, it has two outputs: the counter output which is turned to true when the counter reaches the PV values, and the current value (CV) which tells the current value at any time to whom the counter reaches.
Figure 3: The counter Up instruction block [2]
In this counter, each time a trigger input signal has been received at (CD), the counter counts down until it reaches zero at then the counter output is energized. As shown in figure 4, the counter has three inputs: the trigger command for counting down (CD), the reload command to reload to the PV value, and the preset value to set to what number the initial value from whom the counter starts the count down. Furthermore, it has two outputs: the counter output which is turned to true when the counter reaches the PV values, and the current value (CV) which tells the current value at any time to whom the counter reaches.
Figure 4: The counter down instruction block[2]
In this counter, the two functions of the count up and count down can be combined in one block. each rising edge of a trigger input signal has been received at (CD), the counter counts down. And each time it receives a command trigger signal at (CU), it counts up and so on till it reaches the PV values. At then the counter output is energized. As shown in figure 5, the counter has five inputs: the trigger command for counting down (CD), the trigger command for count up (CU), the reload command to reload to the PV value, the reset command to reset to zero, and the preset value to set to what number the initial value from whom the counter starts counting up or down. Furthermore, it has three outputs: the counter down output (QD) which is turned to true when the counter reaches zero, the counter up output (QU) which goes to true when the counter reaches the PV value, and the current value (CV) which tells the current value at any time to whom the counter reaches.
Figure 5: The counter Up-down instruction block[2]
Now after we have introduced to counters in PLC as regard to their types, functionalities, inputs, and outputs, let’s get to have the fun of practicing our lab work for counters with our simulator.
Figure 6 shows the ladder simple program example for a counter of type Up counter. In this example, the counter counts the input objects by a sensor that triggers the counter to increment. The ladder program is shown on the left side window while the simulator window appears on the right part. You can notice on the simulator window, we track all inputs and outputs as well. In the beginning, the current value (CV) is zero and the preset value is set to 10 meaning the counter will energize its output when it counts up to 10. Let’s press the input trigger and see what is going on. My friends, try to think before you go forward to see the simulator output as I am ganging will be the same as what you imagine!
Figure 6: Ladder example of a counter UP type
As you imagine exactly, figure 7 shows the counter is incrementing each time the input trigger signal is rising. Until it reach to or above 10 which is the PV value at then the counter output turns on as shown in figure 8.
Figure 7: The counter incrementing with triggering signal input
Figure 8: the counter output turns ON by reaching to or above the PV value
On the other hand, the reset signal can be used for resetting the counter to the zero to start over counting as shown in Figure 9.
This counter is used to count down from the PV value to zero. Figure 10 shows a very simple ladder program for the count down the program on the left part and its simulation appears on the right as well. The simulation windows show the PV value is set to 10 and the current value (CV) is initially starting from the PV value. Therefore, it starts with a value of 10. So let’s try to hit the input CD signal and see what the simulator shows.
Figure 11 shows the counter is decrementing the CV by hitting the input CD. And continue decrementing until reaching zero. So what is going to happen then? Think!
Exactly! And well though, as figure 12 shows, once the counter reaches zero, the output changes to true.
Again, the reset button can be utilized to reset the counter to its initial state as shown in figure 12. You can notice that the CV reset to 10 which is the initial value and equal to the preset value (PV).
Figure 12: Reset button reinitiate the counter to the PV value
Now we are going to combine all features in the UP and down counters in one counter which is called the UP-Down counter. Figure 13 shows a simple ladder example for that counter. The ladder code is shown on the left and the simulator window is on the right. The simulation window shows all inputs and outputs of the UP-DOWN counter.
Figure 13: A ladder example of UP-Down counter
We have two functions to test with this type of counter which is up counting and down counting. Figure 14 shows the initial state of the ladder program, it shows we start testing when the current value (CV) shows 2. So what do you expect when hitting the count up and the count down? Thinking and validate with the simulator results below.
Figure 14: initial state at the running of the up-down example
By hitting the count-up function, the counter acts like a UP counter and the current value is incremented as in figure 15.
Figure 15: count up function incremented the CV
On the other hand, by hitting the count down function, the counter acts as a down counter and the current value is decremented as in figure 16. And by pressing reset, the counter CV value will be reset to zero, while it reloaded to the PV value by pressing the load counter button. In addition, the output QU will be energized when the counter reaches or is higher than the PV value which is 10 in this example while the output QD will be true when the counter reaches zero. To sum up, this up-down counter can act as both types of counters UP and Down. I know someone is going to ask why we have such a counter when we already have one of each counter type? Well! That’s a really good question. And the answer is that, yes we can implement any problem relating to performing counting by using these two counters. However, some problems need to perform both functions UP and Down counting at the same time. For example, the Garage problem has cars getting in and out all the time and when cars get in we need to count up the cars and when cars get out we need to count down to report the number of cars in the garage at any time. So in such a problem, having one counter do the whole job is better than having two punters for reducing the conflictions and increasing the flexibility of calculations.
Figure 16: count down function decremented the CV
I would like to thank you so much for following up with us up to this point of learning and practice. Despite briefly introducing the logic gates, we will elaborate in the next station on the logic gates and their functions and usage in ladder logic programming. So you be ready for more learning and practice the ladder logic and logic gates in deep detail.
Well! This is a very good question to start and its answer can be taken as a motive to learn timers comprehensively. Timers are used to turn on actuators i.e. motors for a specific amount of time or turn off them after a specific amount of time. They are used for scheduling tasks on and off based on the process sequences.
There are many types of timers based on the functions. However, all timers are working in the same principle that they are preset to a specific amount of time. Then when their coils are energized, the timers’ contacts are changing over to the opposite of their initial states i.e. from ON to OFF or from OFF to ON based on the delay time and the timer type. Therefore, we can imagine the main components of timers are the coil and contacts as shown in figure 1 [1]. It shows a relay timer for Telemecanique type showing the setting for the time delays, coil, and the contacts.
All timers have a coil and contacts and the latter will be changed over their states by energizing their coil based on the preset time and the type of timer. In the following subsection the most common timer types are introduced:
This type of timer is used to postpone the start of running. Figure 2 depicts the timing diagram of the On-Delay timer. As shown in this timer delayed the output from the input by the preset delay time. The figure shows that, after the input gets started, the time counts up until the preset amount of time elapsed, then the output starts as long as the input is ON. However, in the second pulse of the input, we can notice the output was not started because there was no chance to reach the amount of delay time that is preset in designing the timer.
In this type of timer, we aim at delaying the shutdown of the output. Figure 3 depicts the timing diagram of the OFF delay timer in which, the output starts at the time input starts and the output lasts after a specific time delay after the input gets off. You can notice that, in the second pulse of the input, the output did not shut down after the second pulse of the input due to the incoming of another input pulse before the delay time reached the preset value.
This timer type energizes the output in each rising edge of the input for a fixed amount of time. Figure 4 shows the timing diagram of a pulse-type timer. It shows the output comes active each time it finds a rising edge of the input and keeps active for a fixed amount of time which is preset for the timer.
In an on-delay timer, if the input does not stay on for the preset time delay period there would not be a chance for the output to be energized. So there should be another modified timer to accumulate the period each time the input is ON and activate the output when reaching the preset value. This timer is called an accumulative timer and its timing diagram is depicted in figure 5. In this example, assume the preset values of 12 s, the first input pulse shown in blue resumes for 4 seconds and it goes on for another 8 seconds. The time is accumulated from the first and the second pulse until reached the preset value which is 12 seconds. The output gets ON as long as the preset time has reached and the input is ON.
Timers of different types can be used in PLC with great flexibility. Now let’s learn and practice timers with our simulator. But before we get to start we just need to introduce ourselves to the timer blocks in the ladder logic program.
Figure 6 shows the instruction for generating an ON Delay timer. As you can see the instruction has two inputs and two outputs. The first input “IN” is the input contact of type Boolean. This input contact triggers the timer and initiates it to start counting the time. The second operand is the “PT” by which we set the required time delay. Moving to the outputs, the first output is “Q” this is the main output of the timer and it turns to true when the timer reaches the preset time delay. The second output is the “ET” which reports the time elapsed so far since the timer started to count time. The “PT” and “ET” are of time data type format and can be in milliseconds, seconds, minutes, hours, days et cetera.
Figure 7 shows a very simple example program that uses an ON Delay timer for delaying the running of a motor. The ladder code is shown on the right part of figure 7. It shows that one input contact connected to address “I0.0” and its tag named “trigger_timer” is connected to the timer input. And the preset value is set to be one minute “T#1m” which means one minute. Notice the format is very simple. You type T denoting the time format and then “#” followed by the amount of time and at last the unit of time which could be “MS” for milliseconds, “S” for seconds, “m” for minutes, “d” for days … et cetera. Moving to the outputs, the timer output “Q” is connected to the motor meaning that the motor will be running after the timer counts complete one minute. The other output is “ET” which tells the time elapsed so far since the timer set to start counting time. Let’s go to the simulator window on the left side. We added all inputs and outputs to control the inputs and show the output as well. You can notice that, by setting the input “trigger_timer” to true, the timer starts counting the time as you can read in the “ET” variable that shows the time spent so far “T#29S_335MS” meaning 29 seconds and 335 milliseconds have been elapsed since input set to true. Since the PT time is not reached, the output is still false as shown in blue color.
Figure 8 shows the moment when the timer reached the PT value which is one minute in our example. You can notice on the left window, the ET value becomes one minute which is equal to the PT value. Therefore, the timer output turned to true and the motor is switched on consequently. To sum up, this example shows how the output has become ON after one minute delay of the input.
After we have shown how we can delay the start of a motor by using the On Delay timer. Here we are going to show how to delay the shutdown. Figure 9 shows an example of a very simple ladder program that uses an OFF delay timer to delay the shutdown of an output. As you can see on the left the input is ON and the output starts running with the input at the same time. Let's try to set the input OFF as in figure 10, you can notice the output is still ON and the time counter is incrementing until it reaches the PT value which is set to one minute in our example. Figure 11 reports the moment at which the time counter reached the PT value which is one minute. At that moment the output or the motor is shut down. In a conclusion, the Off delay timer is our tool to delay the shutdown of output or terminate a process.
In this example, we are going to start and stop the motor in a pulsative operation mode thanks to the pulse timer type. That means the input to the timer will start the output to run for a specific amount of time that is present in the PT value regardless of receiving any other input pulses. In figure 12, the pulse timer example is shown. The very simple ladder logic program is displayed on the left window and the simulation is shown on the left window. You can notice that, once the timer received a high state of the input, it energized the output and started counting the time. However, when the input went OFF the output keep running ON for the designated while represented in PT value which is one minute for this example as shown in figure 13. Let’s test the condition of having another input signal as shown in figure 14. When the input goes again high which the last pulse does not complete, the output continues running and the timer does not reset its timing count. However, when the pulse time is reached as in figure 15, the output is shut down and the timer now is ready to start another pulse by noticing a rising edge of the input.
In this ladder example, we are going to show you how to continue accumulating the time until reaching the PS value at which the timer energizes its output as shown in figure 16. The example shows a very simple ladder code that has two inputs connected in parallel to OR logic. So any of these two inputs will trigger the counter to count up the time. On the left window, all inputs and outputs including timer operand and outputs are listed in simulating table to show the values while the program is executing.
Let us start triggering the timer by one of the inputs as shown in figure 17. As you can notice the timer starts counting the time as shown in the ET value on the left window showing the simulation. What if we set the inputs OFF? In the ON Delay timer, the time will be reset. But in this timer, it does not and instead, it waits for another input signal to accumulatively increment the time till reaching the PT value as shown in figure 18. Let’s verify the concept by setting one of the inputs ON as shown in figure 19, the timer accumulates the timing counter until it reached the PT value which is set to one minute in this example. At that moment the output is energized as shown in figure 20. And finally, figure 21 shows how the timer is reset by switching on a reset button. One good practical example for using this type of timer is the maintenance schedule. For example, we can schedule the maintenance to be conducted after one year or after a specific amount of time or number of operating hours. So the timer will keep accumulating the time of operation regardless of the downtime and raise a flag to notify it is the time for performing maintenance.
I would like to thank you so much for following up with our tutorial that far. So far you are familiar with timers types and how to utilize the suitable one for your task based on the logic you want to perform. Next tutorial we are going to go through counters showing their types and functionalities and for what reasons we need counters how we can use them appropriately.
Hi friends! I hope you are doing well! Today we are going to learn and practice a new topic which is a very crucial technique in plc programming. the topic is called “latching”. We mean by Latching to keep the output running starting from the instance of giving a kick-off command until we hit a command to stop running of the motor. Imagine my friends, operator wants to start a motor by hitting a start push button and want the motor to keep running and leave and go for doing another task or job. And then it keeps running until the operator wants to stop it. The problem here is that, once the operator releases his hand away from the push button, the motor automatically stopped and that is not like what the operator wants to do with the motor. To clear the problem that we are going to solve, and for which we need to use the latching technique to connect a load, Figure 1 has been created for you to show the situation to make a direct connection to a motor by using a simple push-button. In this circuit, the operator needs to keep pressing the push button as long as he needs the motor to keep working. Otherwise, the motor will stop once he releases the push button. So would please think with to figure out what is the solution for that?
Fig. 1: Connecting motor to power by push button directly
Let’s try to connect the motor through a relay as it is typically in the industry. Maybe that helps us to control the way to energize the relay coil and use its contacts to start and stop the motor, Figure 2 shows how we can employ a relay to connect the motor to the power source. However, again In fig. 2, the operator still has to keep pressing the button as long as he wants the motor to keep running. This is not the best practice in real life, the operator has many jobs to do. So, he wants to give the command to commence running the motor and leave it running to perform some other tasks and then has the motor stops after the job has been done. In this case, latching is the best practice to connect the motor or any load we want it to run for a while or until complete some functions.
Fig. 2: relaying motor to DC power by hitting start push button
Now, I hope you can feel the problem between our hands and sense the meaning of the word “latching”. Again, in a real-life situation, motors or any actuators can be run via relay, by energizing the relay’s coil, the contacts of the relay switches over from off to on and then connects the motor to let it starts spinning. So for running the motor, the rely on coil should be energized. However, the latching technique makes that requirements go away, instead of that, the contact that has been used for connecting the motor to power, is used to be another pathway to connect the rely on the coil to power without needing to keep pressing the start push button. WoW! What amazing solution is that! to just hit a button and then forget about it and use the contact to make like a closed-loop to have the coil connected to power forever and let the motor work forever. Ohhh!! Forever!!! How do we run the motor without stopping? Yes, you are correct. It should be a way to break that loop when we want to do stop it. we need a way to just stop the latching, to break its loop, to enable the operator to stop the motor when they need to do.
Let’s now show you guys how we can establish and construct a complete latching circuit step by step. In the following subsections, three steps by which will be demonstrating how to complete a typical latching circuit including only push-button and relay.
First of all, in a very simple circuitry which is shown in Fig. 3, the DC power lines positive and negative are connected with a push-button and relay to run a load. The positive wire in red is connected to the push button and then to the coil terminal A1 and A2, and then to the ground black wire. So now, it’s clear that when the push button is pressed it turned on and connects the circuit of the relay coil all the way to be energized. As a result, the contact of the relay is connected and now it is ready to connect the external circuit to run an actuator i.e. motor. But when the push button is released, the coil will be de-energized and the relay coil turns back to the open state and the motor is going to stop. So moving to the next step of building a latching circuit in which we aim at creating another pathway to supply the relay coil with power to forget about the push button and have it continue to run even after releasing the push button.
Fig. 3: the typical push-button and relay circuit
Now Fig. 4 shows the main wiring schematic of a basic latching circuit by which we indeed realize the concept and functionality of the latching technique. in the circuit, you can notice my friends that, the contact upper point and the relay upper point are connected in such a way that, it creates another pathway for energizing the relay coil without any needs to press or even touch the push-button B1. Again, when the push button B1 is pressed, the relay coil will be energized. As a result, the relay contact will be close contacted and in turn bridges point A1 to the positive red wire. Now, when the push button is released, the relay coil still has another pathway to connect to the positive wire so the relay coil will keep energized. I know now what comes out to your mind? if this configuration and schematic can put the relay coil in the loop and energize all the time by the first kick-off by hitting the start button thanks to the latching technique. The question now is, how about stopping the motor?. How to break this loop? Yes, that’s the only thing is remaining to complete a typical latching circuit.
Fig. 4: the second step of latching
We can name this step by ending latching. As shown in fig. 5, a normally close (NC) push-button B2 is added in the way from contact to the positive, red, power wire. Firstly, when the push button B1 is pressed, the relay coil is energized. And the contact of the coil is connected to the positive red wire as the push-button B2 is in a closed state by default. So now, it will be latching as long as the connection to the positive wire does not break. So by hitting push-button B2, it will turn out to open state and the connection to the positive wire is broken. Therefore, the relay coil will be de-energized and the latching gets to stop.
Fig. 5: Ending latching step 3
I know guys you all are waiting to come to this point to go to our lab and simulator and practice our tutorial. So now after we discussed the concept and basics of what latching is and how does it work? We now are all set to start our simulator and practice latching techniques in ladder logic programming as we used to do every tutorial.
Now we need to connect a simple start push button “input A” to the motor at “output” Q0.0 straight forward as in fig. 6. You can see, by pressing the input push button switch, the output motor starts spinning. But how about after releasing our hands off the start button?
Fig. 6: Before latching
Well done! Yes, exactly like what you expected, as shown in fig. 7, when the start pushbutton has been released, the motor stops immediately.
Fig. 7: the motor stops when we released the start button
Now by adding another pathway to run the motor as shown in Fig. 8, a contact from relay “output” has been used in parallel to form “OR” logic with the start push button. So, in the first place, when the start button is pressed, the output goes high and the closed contact now adds another pathway in “OR” logic.
Fig. 8: the latching effect in ladder logic example
Figure 9 shows how the closed contact that has been taken from the relay plays the role of the alternative path to connect the output to the power. So when the input start push button has been released, the closed contact of the output relay makes the connection and the output continue running. However, there is now one problem that, how to break that connection to stop the output?
Fig. 9: the latching effect after releasing the start button
The solution for having a way to shut down or break the latching connection is that, adding a normally closed (NC) push button “input B” in series as shown in fig. 10. This way enables to break the latching connection and shut down the output.
Fig. 10: adding a stop push button to end latching
So by hitting input B, the connection of latching is broken and the output stops running. But breaking the connection will make an issue if the input B is a switch like an emergency switch. The problem is that it should be returned to its normally closed state to enable the cycle to start by hitting input A or the start push button.
Fig. 11: the usage of adding stop button to end latching
By having the stop button return to the normally closed condition, the cycle can be restarted by pressing the start push button and enabling the latching once again.
Fig. 12: restarting the process by resetting the stop push button
There is another way to perform latching of the output. The set instruction can be used to set the output to run until a reset command is met to reset the output. This is a piece of cake to latch an output by employing set and reset instructions. Let’s practice this way in the simulator. Figure 13 shows a simple ladder logic program that uses set and reset instructions to perform latching of the output. Input push-button input A is used to set the output while input push-button input B is used to reset the latch of the output.
Fig. 13: latching using set and reset technique
By hitting the input at I0.0 which is input A, the output is set to true. The question is what happens when input A becomes false?
Fig. 14: set to enable latching the output
Figure 15 answers our wondering that, even after input becomes false the output keeps energized thanks to using a set instruction. So when will see the output turns out to be false?
Fig. 15: the output keep set true even after input becomes false
After setting the output to true, it won’t become false until a reset command is used like in the example shown in fig. 16. The output is reset by input B and becomes a false state.
Fig. 16: reset to end the latching
I really would like to thank you guys so much to follow our tutorial till this point and I hope you have become well known for latching concepts, and how to use and utilize them to solve a real problem in real industrial life. Now let’s continue our series, learn and enjoy practicing ladder logic programming series. Our next station will be the comparator operators including equal, not equal, greater than, equal, less than, et cetera. And how to master using this operator to compare different data types and control the logic of a ladder logic program based on the results of these comparator operators.
Over the past century, dental care has remained a relatively rigid area of healthcare. However, the accelerated digitization of the past two decades has seen the sector rapidly adopt mainstream technologies, with the advancement taking a seemingly steeper trajectory by the day. We looked at some of the new technologies making their way into dentistry and came up with this list of what we reckon will rock the world of dental care for years to come:
3D printing is getting deeper and deeper into medicine. Many companies use 3D printing machines to create prosthetics to replace missing body parts. Although subtractive manufacturing still heavily dominates dentistry, the general projection is that 3D printing will eventually take over.
Orthodontics, for instance, is already making use of 3D printers and has ClearCorrect and Invisalign as two of its most successful projects. Currently, it’s even possible for a standalone doctor or practice to obtain a 3D printer for orthodontics and design devices and prosthetics in the comfort of their office.
A couple of years ago, the FDA approved the use of robotics for dental implant surgeries. While the technology hasn’t hit the ground running, it has shown that robotizing dental surgeries are a viable idea. Robots could eventually be used to create full-on automated systems for single crowns, or microrobots could be employed in minimally invasive procedures with minimal human assistance.
The objective of ultrasound technology in dental care is to create radiation-free imaging of dental parts. It could offer a much-needed alternative to the 2D and 3D options currently available.
New breakthroughs show glimpses of what we can expect in the foreseeable future. The 3D ultrasound solution commonly used in hospitals for fetal imaging shows that we are making headway in the right direction. If that progress continues, it wouldn’t be a surprise to witness ultrasound becoming the standard approach to jaw and teeth imaging, caries detection, digital impressions, and more.
Thanks to the COVID-19 pandemic, teledentistry has become common. Patients are embracing it with its flaws, and dental practices seem to be in a competition over who has the best equipment for virtual dentistry. There is little doubt that technology will outlive the pandemic. However, it remains to be seen how much more dentists can exploit the technology to improve dental care and cut back on operational costs.
Traditionally, dentures took time to create. Dentists had to take impressions of the patient’s teeth alignment, create a design of the denture, and send the design to a lab for fabrication. It would then take another few weeks for the denture to be prepared and sent back to the dentist. Now, thanks to computer-aided design and computer-aided manufacturing, dental technicians can design and fabricate dentures right in their offices and in a fraction of the time.
Virtual reality training is already established in other industries, and it could be the next big thing in dentistry. Instead of using PowerPoint presentations and other conventional training methods, dentists could use VR headsets to learn detailed procedures while experiencing surreal, close-up views of the oral parts being studied. Hygienists and other professionals could also use VR systems to experiment with various ergonomic techniques and hone their skills in the absence of an actual patient.
Already a reality in some fields, artificial intelligence (AI) and machine learning (ML) are yet to leave a mark in dentistry. This is mostly because they go hand in hand with automation, which is still a distant thought in health care.
However, outside procedural application, AI can be used to study data, develop patterns, and provide dental care professionals with analyses to infer from. It can go as far as suggesting treatment options, predicting oral health issues, and identifying scenarios where planned medication, procedures, and underlying conditions are likely to clash. With regards to direct involvement in medical procedures, our hopes are hinged on the prospect of robotics eventually taking over surgical operations.
Augmented reality is less popular than its sister virtual reality, although its applications in dentistry may be more straightforward. The technology is already being used by cosmetic dentists to provide a simulated view of the expected post-procedural results before the procedure is done. It helps clients get a picture of how they will look afterward, allowing them to reconsider their decision or ask for adjustments.
There is a good chance you will need a denture or tooth implant at some point in your lifetime. Regenerative dentistry is a new form of dental care that looks to give you a different, minimally invasive way to fix your smile. The field proposes biological therapy and self-healing options for damaged teeth in place of a restorative procedure.
Researchers from Harvard University and the University of Nottingham are looking into the possibility of promoting the growth of dentin using stem cells. The cells will basically restore the structural makeup of the damaged tooth and the periodontal tissues around it, taking away the need for conventional invasive treatments such as dental implants and root canals.
CRISPR is mostly mentioned in gene editing and cancer treatment conversations, never in oral disorders. There are ongoing studies looking into the potential of using the tool to do away with hereditary oral cancer and plaque formation. The studies are still in their early stages, meaning there isn’t much substance to brandish. However, there is high optimism among researchers and dental care professionals that the technology has a lot in store for dentistry and will change the game once commercially available.
Dating back to 7000 BC, dentistry is one of the earliest known medical professions, so whatever you see now is the work of about nine millennia. The coming century promises to outstrip all that effort several times over and modernize the industry, and with the above technologies already taking shape at a rapid rate, it is clear we are witnessing a revolution.