In this lesson we will use PyQt5, UDP and WiFi to control the brightness of an Arduino LED circuit remotely. The PyQt generates a constantly updating sin wave, which it plots on a PyQt graph, and then transfers the brightness in real time to the arduino project. This lesson teaches many important skills including UDP, WiFi, PyQt5, Python, Arduino and LEDs.
When using the breadvolt, or any battery power supply on a breadboard project, do not turn the power supply on while the Arduino is connected to USB, as you could generate voltage conflicts. It is an either or. If the USB is connected, the power supply should be OFF. The schematic for the arduino circuit is shown below:

In the video, we develop code for the server, on the arduino, and the client, running in Python on the desktop. We present the code below for your convenience.
This is the Server code for the Arduino:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | #include <WiFiS3.h> #include "secrets.h" WiFiUDP udp; int PORT = 12345; String myString; String stringArray[10]; String response = "ACK"; int redPin=9; void setup() { Serial.begin(9600); pinMode(redPin,OUTPUT); Serial.print("Connecting to "); Serial.println(mySSID); WiFi.begin(mySSID, myPASS); while (WiFi.status() != WL_CONNECTED) { delay(100); Serial.print("."); } Serial.println("\nConnected to WiFi"); Serial.println(WiFi.localIP()); udp.begin(PORT); Serial.print("UDP Server started on port "); Serial.print(PORT); // put your setup code here, to run once: } void splitString() { int startIndex = 0; int indexCount = 0; int i; int j; myString = myString + ':'; for (i = 0; i < myString.length(); i = i + 1) { if (myString[i] == ':') { stringArray[indexCount] = myString.substring(startIndex, i); indexCount = indexCount + 1; startIndex = i + 1; } } } void loop() { // put your main code here, to run repeatedly: if (udp.parsePacket()) { myString = udp.readStringUntil('\n'); splitString(); analogWrite(redPin,stringArray[0].toInt()); } } |
You will need to open a new tab, and save the following code as “secrets.h” with the program above.
1 2 | #define mySSID "Your WiFi Name" #define myPASS "Your WiFi Password" |
On the Python side, this is the Client code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | import pyqtgraph as pg from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import QGuiApplication import sys from math import sin,pi import time import socket # Arduino’s IP address (from Arduino Serial Monitor) HOST = "192.168.88.120" # Use Your Arduino's IP. It will print when #You Run the Arduino Server Program PORT = 12345 # Must match Arduino’s UDP port # Create a UDP socket mySocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) mySocket.settimeout(5.0) # 5 seconds timeout for responses Period = 5 frequency = 1/Period numPoints = 500 timeStep = Period/numPoints redData = [0]*numPoints timeData =[0]*numPoints app = QApplication([]) window = QMainWindow() window.setWindowTitle("Red Sine Wave Graph") window.setGeometry(100,100,800,600) screens =QGuiApplication.screens() window.move(screens[1].geometry().x() +100,screens[1].geometry().y() +100) widgetContainer =QWidget() window.setCentralWidget(widgetContainer) mainLayout = QVBoxLayout(widgetContainer) plotWidget = pg.PlotWidget() plotWidget.setLabel("left", "y=sin(2*Pi*f*t") plotWidget.setLabel("bottom", "Time (s)") plotWidget.setTitle("My Fine Sin Wave") plotWidget.addLegend() mainLayout.addWidget(plotWidget) for i in range(numPoints): t = i * timeStep timeData[i] = t redData[i] = sin(2*pi*frequency*t) redPlot = plotWidget.plot(timeData,redData, pen=pg.mkPen("r", width=3), name="Red") tStart = time.perf_counter() def updateGraph(): global t,tStart,frequency t = t +timeStep r= sin(2*pi*frequency*t) redWrite = int((r*255 + 255)/2) myData= str(redWrite)+'\n' myDataEncoded=myData.encode() mySocket.sendto(myDataEncoded, (HOST,PORT)) for i in range(numPoints -1): redData[i] = redData[i+1] timeData[i] = timeData[i+1] redData[numPoints - 1] = r timeData[numPoints -1] = t redPlot.setData(timeData,redData) if redData[0] <=0 and redData[1] > 0: measuredPeriod = time.perf_counter() - tStart print("Measured Period: ",measuredPeriod) tStart = time.perf_counter() timer = QTimer() timer.timeout.connect(updateGraph) timer.start(int(timeStep*1000)) window.show() sys.exit(app.exec_()) |