kpower
Published © GPL3+

IOT with Arduino and ESP13 WiFi Shield

Use the ESP 13 Arduino Shield from DOIT (ESP8266) to connect multiple Arduinos to WiFi and set up an IOT network to log different temperatur

IntermediateProtip2 hours3,957
IOT with Arduino and ESP13 WiFi Shield

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×2
DHT22 Temperature Sensor
DHT22 Temperature Sensor
×2
Resistor 10k ohm
Resistor 10k ohm
×2
ESP13 WiFi Shield
×2

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Breadboard, 170 Pin
Breadboard, 170 Pin

Story

Read more

Schematics

Arduino Connection

Logging Spreadsheet

Excel spreadsheet giving logging results

Code

Arduino Sketch

Arduino
This is the Arduino Sketch that reads data from the DHT22 and sends readings to the Python program over WiFi
/*
  Arduino ESP13 Shield Socket Response program

  Once the ESP13 shield has connected to a WiFi Network, it sends data over the network from the Arduino that is
  written to the Serial lines. All data that the Arduino sends and recieves over the WiFi network uses the
  Serial.read, Serial.write and Serial.print commands.

  This program receives a prompt "Send a Reading" from pyhton program running on a laptop using the socket connection
  and then sends back sensor data from a DHT22 temperature and humidity sensor.
*/
#include <DHT.h> //Include the DHT library
#define DHTPIN 6 // DHT22 is connected to pin 6 of the Arduino
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
String incomingString;
String outgoingString;
int counter = 0;
float hum;
float temp;


void setup() {
  // Baud rate of ESP13 shield set up in configuration
  // Initialize DHT22
  Serial.begin(115200);
  dht.begin();
 }

void loop() {
  // Reply only when you receive data:
     if (Serial.available() > 0){
        // read the incoming string:
        incomingString = Serial.readString();
        
        // If the incoming string equals "Send a Reading" then send data
        if (incomingString.equals("Send a Reading")){ 
           
           //send a series of values in CSV format based on temp and humidty reading
           //from the DHT22
           
           hum = dht.readHumidity();
           temp= dht.readTemperature(true);
           
           // For multiple Arduinos, edit line below to "Arduino2", "Arduino3" etc.          
           
           outgoingString = String("Arduino1") + ","+ String(temp) +","+ String(hum);
           Serial.print(outgoingString);
           Serial.flush();
           counter = counter + 1;
           delay(100);
        }  
     }    
  //Send quit to close connection
  //Currently not activated
  //Serial.print("quit");
  //Serial.flush();
}

Logging Program using Multi Threading and Sockets

Python
This is the Python Program that sets up the socket connections and obtains data from the Arduino via WiFi
import socket
import tkinter as tk
import threading
import csv
import sys
import time

HOST = ''   # Symbolic name, meaning all available interfaces
PORT = 9000 # Arbitrary non-privileged port
sensorLock = threading.Lock() # This lock is used to make sure that only one thread can write to the logging file at a time
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Set up the socket that will be used to connect ESP13
logging = open('logging.csv',mode='a') # CSV file that will be used to log sensor data

# This routine initializes the socket using the host and port defined above
# Description of the successful bind is written to the first entry box of the GUI

def initialize(event):
	entry1.insert (0,'Socket created')
	
	try:
	   s.bind((HOST, PORT))
	except socket.error as msg:
	   entry1.insert(tk.END,str(msg))
	   sys.exit()
   
	entry1.insert(tk.END,' - Socket bind complete ')
	data = s.getsockname()
	entry1.insert(tk.END,data[0] + ":" +str(data[1]))

# This routine starts a seperate thread that will listen for socket connection requests and returns to the GUI
	
def connect(event):
        y = threading.Thread(target=socket_listening,)
        y.setDaemon(True) #By setting Daemon to true, this thread will exit when the main program exits
        y.start()
        
# This routine listens for socket requests and connects
# Because s.listen is a blocking command, it is housed in its own thread and will not block other threads from running
# Code below will accept up to 4 requests; change for loop index if more are required
# Comment out print statements if required           

def socket_listening():
	text1.insert(tk.END,'Socket now listening\n')
	s.listen(4)
	for index in range(4):
	  conn, addr = s.accept()
	  connection = 'Connected with ' + addr[0] + ':' + str(addr[1]) + '\n'
	  print('connection ',addr)
	  text1.insert(tk.END,connection)
	  print('connect complete')
	  x = threading.Thread(target=client_thread, args=(conn, addr, PORT,))
	  x.start()

# This routine handles the connection and communication for a single Arduino
# One thread will be instantiated for each socket connection request
# If a "Send a Reading string is sent to the Arduino, it will respond with a temperature and humidity reading
# The while loop runs every 15 seconds. Change the if test if a differnt time is required
# If the Arduino sends a "quit" string, the connection is closed and the thread exits
	
def client_thread(connection, ip, port, max_buffer_size = 1024):
        print(threading.current_thread().name)
        print(ip)
        sendString = "Send a Reading"
        delayStart = time.perf_counter()
        print(sendString)  
        logging_writer = csv.writer(logging, quotechar='"', quoting=csv.QUOTE_MINIMAL)
        is_active = True
        receiveBytes = " "
        while is_active:
           if ((time.perf_counter() - delayStart) >= 15): # change here if different polling time is required
             connection.send(sendString.encode("utf-8")) # send only takes string
             receiveBytes = connection.recv(max_buffer_size)
             receiveString = receiveBytes.decode("utf-8")
             li = list(receiveString.split(",")) #split the received string into a list using , as seperator
             li.append(time.ctime()) # Append time stamp to the list
             print(receiveString)
             print(li)
             sensorLock.acquire()
             logging_writer.writerow(li) # Write received temp and humidity data to logging file
             sensorLock.release()             
             delayStart = time.perf_counter()
             
           if b"quit" == receiveBytes: # If the Arduino sends a "quit" string, connection is closed and thread exits
             connection.close()             
             print("Connection " + ip[0] + ":" + str(ip[1]) + " closed")
             text1.insert(tk.END,"Connection " + ip[0] + ":" + str(ip[1]) + " closed" + "\n")
             is_active = False

# This routine closes the logging file, socket and exits the program

def exit(event):        
        logging.close()
        s.close()
        print('exit')
        window.destroy()

# The GUI is defined here using tkinter commands

window = tk.Tk()
window.title("ESP13 IOT")

frame1 = tk.Frame(master=window,relief=tk.FLAT,	borderwidth=5)
frame1.pack()
frame2 = tk.Frame(master=window,relief=tk.FLAT,	borderwidth=5)
frame2.pack()

label1 = tk.Label(master=frame1,text="Socket Ready",fg="black",width = 25,height = 2)
label1.grid(row=0,column=0,padx=20,pady=20,sticky="w")

entry1 = tk.Entry(master=frame1,fg="black",bg="white",width=75)
entry1.grid(row=0,column=1,padx=10,pady=10)

label2 = tk.Label(master=frame1,text="Sockets Connected",fg="black",width = 25,height = 2)
label2.grid(row=1,column=0,padx=20,pady=20,sticky="w")

text1 = tk.Text(master=frame1,fg="black",bg="white",height=25,width=75)
text1.grid(row=1,column=1,padx=10,pady=10)

button1 = tk.Button(master=frame2,text="Initialize",width=10,height=2,relief=tk.RAISED,fg="black")
button1.grid(row=0,column=0,padx=20,pady=20)
button1.bind("<Button-1>",initialize)

button2 = tk.Button(master=frame2,text="Connect",width=10,height=2,relief=tk.RAISED,fg="black")
button2.grid(row=0,column=1,padx=20,pady=20)
button2.bind("<Button-1>",connect)

button5 = tk.Button(master=frame2,text="Exit",width=10,height=2,relief=tk.RAISED,fg="black")
button5.grid(row=0,column=4,padx=20,pady=20)
button5.bind("<Button-1>",exit)

window.mainloop()
print('Program ended')

Credits

kpower

kpower

19 projects • 6 followers
Qualified Electrical Engineer with experience in software and hardware development

Comments