ESP8266 NodeMCU Send Emails using an SMTP Server: HTML, Text, and Attachments (Arduino)

In this tutorial, you’ll learn how to send emails with the ESP8266 NodeMCU board using an SMTP server. We’ll show how to send an email with raw text, HTML text, and how to send attachments like images and files (.txt). We’ll program the ESP8266 NodeMCU board with the Arduino core.

ESP8266 NodeMCU Send Emails using an SMTP Server HTML Text and Attachments Arduino IDE

In this tutorial, we cover the following topics:

We have a similar tutorial for the ESP32 board: ESP32 Send Emails using an SMTP Server: HTML, Text, and Attachments (Arduino IDE)

Introducing SMTP Servers

SMTP means Simple Mail Transfer Protocol and it is an internet standard for email transmission. To send emails using an ESP8266, you need to connect it to an SMTP Server.

ESP-Mail-Client Library

To send emails with the ESP8266 NodeMCU board, we’ll use the ESP-Mail-Client library. This library allows the ESP8266 to send and receive emails with or without attachments via SMTP and IMAP servers. If you like this library and you’ll use it in your projects, consider supporting the developer’s work—see the library GitHub page.

In this tutorial, we’ll use SMTP to send an email with and without attachments. As an example, we’ll send an image (.png) and a text (.txt) file. The files to be sent via email can be saved in the ESP8266 Filesystem (SPIFFS or LittleFS) or in a microSD card (not covered in this tutorial).

Installing the ESP-Mail-Client Library

Before proceeding with this tutorial, you need to install the ESP-Mail-Client library. This library is not available to install through the Arduino IDE Library Manager. Follow the next steps to install the library:

  1. Click here to download ESP-Mail-Client library .zip folder.
  2. In your Arduino IDE, go to Sketch > Include Library > Add .ZIP Library.
  3. Select the .zip file you’ve just downloaded.

Then, if you go to File > Examples > ESP-Mail-Client, you’ll find several examples that you can try. You can also access the examples in the library GitHub page—here.

If you’re using the ESP8266 with VS Code + PlatformIO, you should copy the following to your platformio.ini file to include the library.

lib_deps = mobizt/ESP Mail Client @ ^1.1.7

Sender Email (New Account)

We recommend creating a new email account to send the emails to your main personal email address. Do not use your main personal email to send emails via ESP8266. If something goes wrong in your code or if you make too many requests by mistake, you can be banned or have your account temporarily disabled.

We’ll use a newly created Gmail.com account to send the emails, but you can use any other email provider. The receiver email can be your personal email without any problem.

Create a Sender Email Account

Create a new email account for sending emails with the ESP8266. If you want to use a Gmail account, go to this link to create a new one.

Gmail Create a new account

Allow less secure apps

Allow less secure apps to get access to this new Gmail account so that you can send emails. You can open this link to go to that menu.

Gmail Allow Less Secure Apps to Send Email with ESP32

Gmail SMTP Server Settings

If you’re using a Gmail account, these are the SMTP Server details:

  • SMTP Server: smtp.gmail.com
  • SMTP username: Complete Gmail address
  • SMTP password: Your Gmail password
  • SMTP port (TLS): 587
  • SMTP port (SSL): 465
  • SMTP TLS/SSL required: yes

Outlook SMTP Server Settings

For Outlook accounts, these are the SMTP Server settings:

  • SMTP Server: smtp.office365.com
  • SMTP Username: Complete Outlook email address
  • SMTP Password: Your Outlook password
  • SMTP Port: 587
  • SMTP TLS/SSL Required: Yes

Live or Hotmail SMTP Server Settings

For Live or Hotmail accounts, these are the SMTP Server settings:

  • SMTP Server: smtp.live.com
  • SMTP Username: Complete Live/Hotmail email address
  • SMTP Password: Your Windows Live Hotmail password
  • SMTP Port: 587
  • SMTP TLS/SSL Required: Yes

If you’re using another email provider, you need to search for its SMTP Server settings. Now, you have everything ready to start sending emails with your ESP8266.

In your Arduino IDE, you can go to File > Examples > ESP-Mail-Client and experiment with the examples provided—you need to insert your email details (sender and recipient accounts), the SMTP server settings, and your SSID and password.


Send an Email with HTML or Raw Text with ESP8266

The following code sends an email via SMTP Server with HTML or raw text. As an example, the ESP8266 sends an email once when it boots. Then, you should be able to modify the code and integrate it into your own projects.

Don’t upload the code yet, you need to make some modifications to make it work for you.

/*
  Rui Santos
  Complete project details at:
   - ESP32: https://RandomNerdTutorials.com/esp32-send-email-smtp-server-arduino-ide/
   - ESP8266: https://RandomNerdTutorials.com/esp8266-nodemcu-send-email-smtp-server-arduino/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  Example adapted from: https://github.com/mobizt/ESP-Mail-Client
*/

//To use send Email for Gmail to port 465 (SSL), less secure app option should be enabled. https://myaccount.google.com/lesssecureapps?pli=1

#include <Arduino.h>
#if defined(ESP32)
  #include <WiFi.h>
#elif defined(ESP8266)
  #include <ESP8266WiFi.h>
#endif
#include <ESP_Mail_Client.h>

#define WIFI_SSID "REPLACE_WITH_YOUR_SSID"
#define WIFI_PASSWORD "REPLACE_WITH_YOUR_PASSWORD"

#define SMTP_HOST "smtp.gmail.com"
#define SMTP_PORT 465

/* The sign in credentials */
#define AUTHOR_EMAIL "[email protected]"
#define AUTHOR_PASSWORD "YOUR_EMAIL_PASS"

/* Recipient's email*/
#define RECIPIENT_EMAIL "[email protected]"

/* 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;

  /* Set the message headers */
  message.sender.name = "ESP";
  message.sender.email = AUTHOR_EMAIL;
  message.subject = "ESP Test Email";
  message.addRecipient("Sara", RECIPIENT_EMAIL);

  /*Send HTML message*/
  String htmlMsg = "<div style=\"color:#2f4468;\"><h1>Hello World!</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 World! - Sent from ESP 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: <[email protected]>");

  /* 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");
  }
}

View raw code

You need to insert your network credentials, as well as setting the sender email, SMTP Server details, recipient, and message.

How the Code Works

This code is adapted from an example provided by the library. The example is well commented so that you understand what each line of code does. Let’s just take a look at the relevant parts that you need or may need to change.

First, insert your network credentials in the following lines:

#define WIFI_SSID "REPLACE_WITH_YOUR_SSID"
#define WIFI_PASSWORD "REPLACE_WITH_YOUR_PASSWORD"

Insert your SMTP server settings. If you’re using a Gmail account to send the emails, these are the settings:

#define SMTP_HOST "smtp.gmail.com"
#define SMTP_PORT 465

Insert the sender email sign in credentials (complete email and password)

#define AUTHOR_EMAIL "[email protected]"
#define AUTHOR_PASSWORD "YOUR_EMAIL_PASS"

Insert the recipient email:

#define RECIPIENT_EMAIL "[email protected]"

Set the message headers in the following lines in the setup()—sender name, sender email, email subject, and the recipient name and email:

/* Set the message headers */
message.sender.name = "ESP";
message.sender.email = AUTHOR_EMAIL;
message.subject = "ESP Test Email";
message.addRecipient("Sara", RECIPIENT_EMAIL);

In the following lines, set the content of the message (raw text) in the textMsg variable:

//Send raw text message
String textMsg = "Hello World! - Sent from ESP board";
message.text.content = textMsg.c_str();
message.text.charSet = "us-ascii";
message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit;

If you want to send HTML text instead, uncomment the following lines— you should insert your HTML text in the htmlMsg variable.

/*Send HTML message*/
/*String htmlMsg = "<div style=\"color:#2f4468;\"><h1>Hello World!</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;*/

Finally, the following lines send the message:

if (!MailClient.sendMail(&smtp, &message))
    Serial.println("Error sending Email, " + smtp.errorReason());

Demonstration

Upload the code to your ESP8266. After uploading, open the Serial Monitor at a baud rate of 115200.

If everything goes as expected you should get a similar message in the Serial Monitor.

ESP8266 NodeMCU Send Email Message Successfully Serial Monitor

Check your email account. You should have received an email from your ESP8266 board.

Email received from ESP8266 Board Gmail Account

If you set the option to send a message with HTML text, this is how the message looks like:

ESP8266 SMTP Server Send Email with Body HTML text format

If you’ve enable the raw text message, this is the email that you should receive.

ESP8266 SMTP Server Send Email with Body raw text format

Send Attachments via Email with ESP8266 (Arduino IDE)

This section will show you how to send attachments in your emails sent by the ESP8266. We’ll show you how to send .txt files or pictures. This can be useful to send a .txt file with sensor readings from the past few hours or other applications.

You should save the files you want to send in the ESP8266 filesystem (SPIFFS or LittleFS). You can also send attachments saved on a microSD card, but we’ll not cover this subject in this tutorial.

Setting the Filesystem

To send files via email, you should save them in the ESP8266 filesystem. You can use SPIFFS or LittleFS. To upload files to the filesystem using Arduino IDE, you need to install a Filesystem Uploader Plugin. Read one of the following tutorials and install the plugin depending on the filesystem you want to use:

If you’re using VS Code + PlatformIO, follow the next tutorial to learn how to upload files to LittleFS:

IMPORTANT

Note: To use LittleFS with the ESP-Mail-Client library, you need to edit the library files (ESP_Mail_FS.h) to use that specific filesystem. Read the following section if you want to use LittleFS. Otherwise, skip to this section.

Edit the Library Files to use LittleFS

The default filesystem used by the ESP-Mail-Client library is SPIFFS. If you want to use SPIFFS, you can skip this section. Otherwise, continue reading to learn how to edit the library to use LittleFS instead.

To use LittleFS, you must edit the ESP_Mail_FS.h file.

Go to your Arduino installation Libraries folder. In my case, it is located in the following path (yours may be similar):

C:\Users\USERNAME\Documents\Arduino\libraries

Go to ESP-Mail-Client-master > src and open the ESP_Mail_FS.h file with a text editor.

Locate the following section.

ESP-Mail-Client Library Change Filesystem

Replace it with the following:

#if defined(ESP32)
  #define ESP_Mail_DEFAULT_FLASH_FS SPIFFS
#endif

#if defined(ESP8266)
  #include <LittleFS.h>
  #define ESP_Mail_DEFAULT_FLASH_FS LittleFS
#endif

This way, it uses SPIFFS filesystem by default for the ESP32 and LittleFS for the ESP8266.

ESP-Mail-Client Change Filesystem ESP32 and ESP8266

Save the file. Now the library will use LittleFS as the default filesystem for the ESP8266.

Upload Files to the Filesystem

Create a new Arduino sketch and save it. Go to Sketch > Show Sketch folder. Inside the Arduino sketch folder, create a folder called data. Move a .png file and .txt file to your data folder.

Alternatively, you can click here to download the project folder.

Note: with the default code, your files must be named image.png and text_file.txt or you can modify the code to import files with a different name.

We’ll be sending these files:

Upload the files to filesystem to send as an email attachment

Your folder structure should look as follows (download project folder):

Send email attachments folder structure filesystem organizing files

After moving the files to the data folder, in your Arduino IDE, go to Tools ESP8266 Sketch Data Upload or ESP8266 LittleFS Data Upload depending on the filesystem and wait for the files to be uploaded.

ESP8266 Tools LittleFS Data Upload Arduino IDE

You should get a success message on the debugging window. If the files were successfully uploaded, move on to the next section.

SPIFFS image done uploading success message

Code

The following code sends an email with a .txt file and a picture attached. Before uploading the code, make sure you insert your sender email settings as well as your recipient email.

/*
  Rui Santos
  Complete project details at:
   - ESP8266: https://RandomNerdTutorials.com/esp8266-nodemcu-send-email-smtp-server-arduino/
   
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  Example adapted K. Suwatchai (Mobizt): https://github.com/mobizt/ESP-Mail-Client Copyright (c) 2021 mobizt
*/

//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 <ESP8266WiFi.h>
#include <ESP_Mail_Client.h>

#define WIFI_SSID "REPLACE_WITH_YOUR_SSID"
#define WIFI_PASSWORD "REPLACE_WITH_YOUR_PASSWORD"

#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 "[email protected]"
#define AUTHOR_PASSWORD "YOUR_EMAIL_PASS"

/* Recipient's email*/
#define RECIPIENT_EMAIL "[email protected]"
/* 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 (!LittleFS.begin()) {
  // Uncomment to use SPIFFS
  //if (!SPIFFS.begin()) {
    Serial.println("An error has occurred while mounting the filesystem");
  }
  else{
    Serial.println("Filesystem 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 = "";

  /* 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";
  message.sender.email = AUTHOR_EMAIL;

  message.subject = "Email with attachments";
  message.addRecipient("Sara", RECIPIENT_EMAIL);

  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"; 
  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");
  }
}

View raw code

How the code works

This code is very similar to the previous one, so we’ll just take a look at the relevant parts to send attachments.

In the setup(), you need to initialize the filesystem: SPIFFS or LittleFS.

if (!LittleFS.begin()) {
// Uncomment to use SPIFFS
//if (!SPIFFS.begin()) {
  Serial.println("An error has occurred while mounting the filesystem");
}
else{
  Serial.println("Filesystem mounted successfully");
}

You need to create an attachment as follows:

/* The attachment data item */
SMTP_Attachment att;

Then, add the attachment details: filename, MIME type, file path, file storage type, and transfer encoding. In the following lines, we’re sending the image file.

att.descr.filename = "image.png";
att.descr.mime = "image/png"; 
att.file.path = "/image.png";
att.file.storage_type = esp_mail_file_storage_type_flash;
att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64;

Finally, add the attachment to the message:

message.addAttachment(att);

If you want to send more attachments, you need to call the following line after adding the previous attachment:

message.resetAttachItem(att);

Then, enter the details of the other attachment (text file):

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;

And add this attachment to the message:

message.addAttachment(att);

Finally, you just need to send the message as you did with the previous example:

if (!MailClient.sendMail(&smtp, &message, true))
  Serial.println("Error sending Email, " + smtp.errorReason());

Demonstration

After uploading the code, open the Serial Monitor at a baud rate of 115200. If everything goes as expected, you should get a similar message on the Serial Monitor.

ESP8266 NodeMCU Send Email Message Successfully Serial Monitor

If you go to your inbox, you should get the message with the two attachments:

Send Email with Attachments ESP8266 NodeMCU Gmail Account Arduino IDE

Wrapping Up

In this tutorial, you’ve learned how to send emails with the ESP8266 NodeMCU board using an SMTP Server. You’ve learned how to send HTM text, raw text, and attachments.

Now, the idea is to modify the code and include it in your own projects. For example, it can be useful to send a .txt file with the sensor readings of the last hour, notifications when motion is detected, and much more.

We hope you’ve find this tutorial interesting. We have a similar guide for the ESP32:

Learn more about the ESP8266 with our resources:

Thanks for reading.



Build Web Server projects with the ESP32 and ESP8266 boards to control outputs and monitor sensors remotely. Learn HTML, CSS, JavaScript and client-server communication protocols DOWNLOAD »

Build Web Server projects with the ESP32 and ESP8266 boards to control outputs and monitor sensors remotely. Learn HTML, CSS, JavaScript and client-server communication protocols DOWNLOAD »


Enjoyed this project? Stay updated by subscribing our newsletter!

6 thoughts on “ESP8266 NodeMCU Send Emails using an SMTP Server: HTML, Text, and Attachments (Arduino)”

  1. Thank you so much for sharing this fantastic tutorial and for including step-by-step instructions on how to understand the concept and how the project works.

    Reply
  2. Hi Sara,
    It is beside the point, but what it is the correct address for forum.
    I want to find help for one of my problem or put a question
    Thank you
    Ion

    Reply

Leave a Comment

Download our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.