The objective of this topic is to explain how to perform communication from a Raspberry PI using python, and an Arduino mega to switch ON a LED. The Arduino sends back a message to the Raspberry.
Hardware used :
- Raspberry PI (3B+ but I guess any Raspberry PI will work)
- Robotdyn card including Arduino MEGA 2560 R3, ESP8266 and CH340 USB on the same PCB
The main principle is presented here :
- an HTTP server runs on ESP8266 with a local URL (192.168.xx.yy) given by the home internet box
- A python GUI runs on the Raspberry
- When the user clicks on a GUI button,the Raspberry PI python code sends a message to the HTTP server via WiFi. For example, the message looks like "192.168.xx.yy/LedON"
- the HTTP server running on the ESP8266 receives the message, decodes it, and sends a message via the Serial port to the Arduino
- The Arduino receives the message via the serial port, decodes it, executes a code (e.g. switches ON a Led), and sends back a message via serial port to ESP8266
- ESP8266 receives the message sent back by the Arduino via the serial port, and sends it via Wifi to the client
- The client running on the Raspberry receives the message and prints it on the GUI
There are 3 programs :
- on Raspberry : Python code for GUI and for WiFi requests management (send & receive)
- on ESP8266 : HTTP server creation, WiFi client messages management (send & receive), communication with Arduino via serial port (send & receive)
- on Arduino : communication with ESP8266 via serial port (send & receive)
Preliminary : follow this link to understand better how to use the Robotdyn card and to how to install the ESP8266 module driver on Arduino IDE : Контроллер Arduino Mega с ESP8266 | System Engineering
Procedure:
-
connect a LED+ to Arduino pin 11, and LED- to a 220 Ohm resistor
-
connect the other 220 Ohm resistor connector to the Arduino ground
-
launch Arduino IDE
-
select the ESP8266 card : Menu Tools/Card management/LOLIN(WEMOS) D1 R2 & mini
-
on the Robotdyn card, set the 8x DIP switch as follow: all OFF except 5,6 and 7 to ON
-
connect the USB cable between Robotdyn card and Raspberry USB port
-
write ESP8266 code below into Arduino IDE
-
save and download the code to the card
-
disconnect the USB cable
-
select the Arduino Mega card : Menu Tools/Card management/ Arduino Mega or Mega 2560
-
on the Robotdyn card, set the 8x DIP switch as follow: all OFF except 1,2,3 and 4 to ON
-
connect the USB cable between Robotdyn card and Raspberry USB port
-
write Arduino code below into Arduino IDE
-
save and download the code to the card
-
open the Arduino IDE serial monitor : the HTTP server creation message on the ESP8266 should appear with the associated url like 192.168.xx.yy
-
take a note of this url
-
write python code below on Raspberry PI into a file named app.py for example. Replace the url by the one noted above on the serial monitor
-
launch the python program using your python IDE or using the command python app.py
-
et voila ! Click on the button 'click here' to switch ON the LED
Raspberry PI Python code :
- to send requests to an URL simply use the 'requests' objects like so:
import requests
url = '192.168.xx.yy'
r = requests.post(url + '/LedON')
-
in this case, the python code sends the message 'LedON' to the url 192.168.xx.yy
-
to get requests module use the command in a terminal 'pip install requests'
-
to manage GUI use tkinter like so
from tkinter import *
win = Tk()
def someFuntion():
r = requests.post(url + 'LedON')
txtArea.set(r.text)
def close():
win.destroy()
button = Button(win, text = 'clickHere', command = someFunction)
label = Label(win,textvariable = txtArea)
win.protocol("WM_DELETE_WINDOW", close)
win.mainloop()
- in this case, when the user clicks on the button 'clickHere', the someFunction is executed
- this function sends the HTTP request to the server (as per above), and displays the HTTP response into the text label area
ESP8266 code:
- HTTP server is used for WiFi connection
- the url (192.168.xx.yy) provided by the internet home box is printed on the serial monitor
- the command sent by the client 'url/LedON' is detected by the server (see server.on function below)
- when received, the ESP8266 sends a message to the serial port to be catched by the Arduino
- then the ESP8266 waits 100ms for the response coming back from the Arduino using the same serial port
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
const char* ssid = "your internet home box ID here";
const char* password = "your internet home box password here";
ESP8266WebServer server(80);
MDNSResponder mdns;
String strResponse;
void setup(void){
Serial.begin(115200);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
WiFi.begin(ssid, password);
Serial.println("");
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (mdns.begin("esp8266", WiFi.localIP())) {
Serial.println("MDNS responder started");
}
server.on("/", [](){
server.send(200, "text/plane", "connected");
});
// Manage actions wrt client requests
// Actions are defined by the string set after the 'url/', url being the server url
server.on("/LedON", [](){
// Send message on serial port to be catched by ARDUINO
Serial.println("[LedON]");
// Wait for response from ARDUINO on serial port
delay(100);
if (Serial.available()) {
strResponse = Serial.readString();
}
//Send response received to the client using WiFi
server.send(200, "text/plane", strResponse);
});
// Start WiFi server
server.begin();
Serial.println("HTTP server started");
}
void loop(void){
server.handleClient();
}
Arduino code:
- serial messages sent by and back to the ESP8266 use serial port 3
include <MemoryFree.h>
#include <EEPROM.h>
#define PIN_LED 11
void setup() {
pinMode(PIN_LED, OUTPUT);
serialEvent3_setup();
}
void loop() {
}
void serialEvent3() {
while (Serial3.available()) {
char inChar = Serial3.read();
inString += inChar;
if (inChar == ']') {
if (inString.indexOf("[LedON]")>0) {
digitalWrite(PIN_LED, HIGH);
Serial3.println("led is ON");
}
}
}
