Have you had an issue with understanding how to program ESP32 using Python Zerynth studio and connecting or controlling your device over the wireless network using Zerynth App? This project is meant for beginners to take them a step by step in how to build a simple voltage divider.
For simplicity, this articled will be divided into three parts. Each part has its own objective:
Part 1: Reading the output volt over the console.
Part2: Transform the project to a higher level by reading the result wirelessly using Zerynth App.
Part 3: Advance the data reading using a graphical interface from “jqxKnob” element of the JQWidgets.
Required MaterialsFirst of all, you need a board. You can select one of the 32-bit microcontroller devices supported by Zerynth. We’ve chosen the NodeMCU ESP-32S a very popular development board with built-in WI-FI for creating IoT projects..
Last but not least, you need:
- Zerynth Studio, our powerful IDE for embedded programming in Python that enables the IoT. You can download it here.
- Zerynth App. You can download it here.
Just put the USB to power your ESP-32 on the breadboard and connect the Variable Resistor as shown in the diagram:
- Pin1 to +3.3V pin of the ESP-32
- Pin2 to port A0 of ESP-32
- Pin3 to GND pin of the ESP-32
Part 1: Reading the output volt over the console.
Once you have installed Zerynth Studio and created a Zerynth user, you have to register and virtualize the board. Take a look at the Zerynth official documentation NodeMCU ESP-32S a quick getting started.
Now you can start to program your board in Python!
Create a new project and edit the main.py file as follows:
import streams
# import the Analog to digital converter driver
import adc
streams.serial()
while True:
# Read Analog data from port A0 and convert it to Digital data (A0 is 12bit-(4096))
value = adc.read(A0)
# Convert the input to volt
volt=value*(3.3/4095.0)
print("sensor raw value:", value," Reading:",volt,"Volt")
sleep(1000)
This is a very simple python program to read an analog input from ADC port A0 and convert it to real volt value. ADC port is a 12-bit port (2 to the power 12=4096), use the formula volt=value*(3.3/4095) to convert the digital data to a real volt value. Finally, we print the result on the console using the command "print"
At this point, we have completed the first part. You can now uplink the project to your device. Open the console and start changing the resistor value and see the output volt on the console.
Part 2: Transform the project to a higher level by reading the result wirelessly using Zerynth App.
In this part will send the volt reading data wirelessly to the smartphone in addition to the console.
We will need to complete the following steps:
- Enable the Wireless on the ESP-32
- Connect to Zerynth App.
- Create an HTML template to read the data from the smartphone.
1 - Enable the Wireless on the ESP-32: In order to enable the WI-FI over the NodeMCU ESP-32S, you need to import the WI-FI library and initiate the connection. You can read more about enabling WI-FI under espressif Examples of the Zerynth studio.
# import the WI-FI library
from wireless import wifi
from espressif.esp32net import esp32wifi as wifi_driver
import streams
import adc
streams.serial()
sleep(1000)
print("STARTING...")
################### WIFI Connection Setup #############################
wifi_driver.auto_init()
try:
for i in range(0,5):
try:
wifi.link("Your WI-FI name",wifi.WIFI_WPA2,"Your WI-FI password")
print("Connection established..........................:)")
break
except Exception as e:
print("Can't link",e)
else:
print("Impossible to link!")
while True:
sleep(1000)
except Exception as e:
print(e)
################### Volt Reading Setup #############################
while True:
value = adc.read(A0)
volt=value*(3.3/4095.0)
print("sensor raw value:", value," Volte:",volt)
sleep(300)
From the above code, you need to import the Wi-Fi library. In this project, we imported espressif.esp32net since we are using NodeMCU ESP-32S. If you have different development bard, you need to import the right FW-FI library.
In the section of WI-FI connection, you will find the code of setting up the ESP32 to connect to your Wireless network. You need to change the "Your WI-FI name" and "Your WI-FI password" with your wireless network name and passcode respectively.
Now uplink the project to your device. Open the console and check if the ESP32 network connection has established
At this point, we have successfully connect our ESP32 to the WI-FI, we will go to the next step and configure our ESP32 to connect to Zerynth App.
2 - Connect to Zerynth App: This is the most interesting and fun section where you manage to send your data wirelessly and read it over your smartphone.
Change your code by adding the following:
First, import Zerynth ADM
# import Zerynth App
from zadm import zadm
Second, configure your DEVICE UID and "DEVICE TOKEN. You have to create a “connected device” and link the “zerynthapp” instance to it. Then you have to create and link a template to the connected device. Take a look at the “Create and set up a connected device” and “Create, upload and set the Template” steps of this tutorial for more details.
################### Zerynth App Configuration #########################
z = zadm.Device(DEVICE UID HERE", "DEVICE TOKEN HERE")
z.start()
Third, you will need to send your data to Zerynth App with the command z.send_event. This command takes 2 arguments, the first one is the data name and the second the value. The data name is your choice.
# send the voltage value to the zerynth App
z.send_event({"Voltage":volt})
Below is the complete Python code:
from wireless import wifi
from espressif.esp32net import esp32wifi as wifi_driver
import streams
import adc
# import Zerynth App
from zadm import zadm
streams.serial()
sleep(1000)
print("STARTING...")
################### WIFI Connection Setup #############################
wifi_driver.auto_init()
try:
for i in range(0,5):
try:
wifi.link("iPhone XS",wifi.WIFI_WPA2,"1234.saif")
print("Connection established..........................:)")
break
except Exception as e:
print("Can't link",e)
else:
print("Impossible to link!")
while True:
sleep(1000)
except Exception as e:
print(e)
################### Zerynth App Configuration #########################
z = zadm.Device(DEVICE UID HERE", "DEVICE TOKEN HERE")
z.start()
################### Volt Reading Setup #############################
while True:
value = adc.read(A0)
volt=value*(3.3/4095.0)
print("sensor raw value:", value," Volte:",volt)
# send the voltage value to the zerynth App
z.send_event({"Voltage":volt})
sleep(300)
Fourth, create your HTML template and upload it to the Zerynth server. The basic template is available on the documentation.
in the HTML template change the on_event line to show the volt value. This "voltage" string must be the same as the data name written in your python code above:
on_event: function(evt){$("#status1").html(JSON.stringify(evt.payload.Voltage)+" Volt");},
The final HTML code will be as follow:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Volt Divider</title>
<!--Include jquery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<!--Include zerynth ADM JS LIBRARY -->
<script src="https://api.zerynth.com/zadm/latest/z.js"></script>
</head>
<body style="text-align:center">
<div> <h1 id="status" style="background:#ddd;font-weight:bold"></h1></div>
<div> <h1 id="status1" style="background:#ddd;font-weight:bold"></h1></div>
<script>
<!-- CONFIGURE ADM LIBRARY ON READY -->
$(document).ready(function() {
Z.init({
on_connected: function(){$("#status").html("CONNECTED")},
on_error: function(){$("#status").html("ERROR")},
on_disconnected: function(){$("#status").html("DISCONNECTED"); return true},
on_online: function(evt){$("#status").html("ONLINE");},
on_offline: function(evt){$("#status").html("OFFLINE");},
on_event: function(evt){$("#status1").html(JSON.stringify(evt.payload.Voltage)+" Volt");},
on_notify: function(evt){$("#status").html("NOTIFICATION! "+JSON.stringify(evt));}
})
});
</script>
</body>
</html>
Now run your Zerynth App on your smartphone and you should see the data running
Part 3: Advance the data reading using a graphical interface from “jqxKnob” element of the JQWidgets.
In this final part, we will convert the result in a graphical user interface using jqxKnob” element of the JQWidgets. All what you need is to change The HTML template by importing the JQWidgets library and add the style code. The new HTML file will be as below
HTML Template:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Voltage Divider</title>
<!--Include jquery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<!--Include zerynth ADM JS LIBRARY -->
<script src="https://api.zerynth.com/zadm/latest/z.js"></script>
<!-- jqWidget Call -->
<link rel="stylesheet" href="https://jqwidgets.com/public/jqwidgets/styles/jqx.base.css" type="text/css" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1 maximum-scale=1 minimum-scale=1" />
<script type="text/javascript" src="https://jqwidgets.com/public/scripts/jquery-1.11.1.min.js"></script>
<script type="text/javascript" src="https://jqwidgets.com/public/jqwidgets/jqxcore.js"></script>
<script type="text/javascript" src="https://jqwidgets.com/public/jqwidgets/jqxdraw.js"></script>
<script type="text/javascript" src="https://jqwidgets.com/public/jqwidgets/jqxknob.js"></script>
<script type="text/javascript" src="https://jqwidgets.com/public/jqwidgets/jqxnumberinput.js"></script>
<style type="text/css">
#container {
position: relative;
}
.inputField {
left: 110px; //change the voltage reading location input field
top: 123px;
position: absolute;
background: transparent;
border: none;
}
text.jqx-knob-label {
font-size: 13px;
}
.inputField .jqx-input-content {
background: transparent;
font-size: 20px;
color: grey;
}
</style>
<script type="text/javascript">
$(document).ready(function () {
$('#container').jqxKnob({
width: 300, //Gadget size
value: 0, // Change the voltage from here
min: 0,
max: 3.3,
startAngle:120,
endAngle: 420,
snapToStep: false, //false to show voltage in decimal point
allowValueChangeOnClick: false,
allowValueChangeOnDrag: false,
allowValueChangeOnMouseWheel: false,
rotation: 'clockwise',
style: { stroke: '#dfe3e9', strokeWidth: 3, fill: { color: '#fefefe', gradientType: "linear", gradientStops: [[0, 1], [50, 0.9], [100, 1]] } },
marks: {
colorRemaining: { color: 'grey', border: 'grey' },
colorProgress: { color: '#00a4e1', border: '#00a4e1' },
type: 'line',
offset: '71%',
thickness: 3,
size: '6%',
majorSize: '9%',
majorInterval: .5,
minorInterval: .1,
},
labels: {
offset: '88%',
step: .5,
visible: true
},
progressBar: {
style: { fill: '#00a4e1', stroke: 'grey' },
size: '9%',
offset: '60%',
background: { fill: 'grey', stroke: 'grey' }
},
pointer: { type: 'arrow', style: { fill: '#00a4e1', stroke: 'grey' }, size: '59%', offset: '49%', thickness: 20 }
});
var input = $('<div class="inputField">');
$('#container').append(input);
var inputOptions = {
width: 80,
height: 500,
decimal: 0, // starting value same as widget
min: 0, // same as widget
max: 3.3, // same as widget
textAlign: 'center',
decimalDigits: 2,
inputMode: 'simple'
};
$(input).jqxNumberInput(inputOptions);
$('#container').on('change', function (event) {
if (event.args.changeSource == 'propertyChange' || event.args.changeSource == 'val') { return; }
$(input).val(event.args.value);
})
});
</script>
</head>
<body class='default' style="text-align:center">
<div> <h1 id="status" style="background:#ddd;font-weight:bold"></h1></div>
<div id='container' style="width: 200px; height: 200px; margin:0 auto;"> </div>
<script>
<!-- CONFIGURE ADM LIBRARY ON READY -->
$(document).ready(function() {
Z.init({
on_connected: function(){$("#status").html("CONNECTED")},
on_error: function(){$("#status").html("ERROR")},
on_disconnected: function(){$("#status").html("DISCONNECTED"); return true},
on_online: function(evt){$("#status").html("ONLINE");},
on_offline: function(evt){$("#status").html("OFFLINE");},
on_event: function(evt){
var val = JSON.stringify(evt.payload.Voltage);
$('#container').val(val);},
on_notify: function(evt){$("#status").html("NOTIFICATION! "+JSON.stringify(evt));}
})
});
</script>
</body>
</html>
Upload the THML file and run Zerynth App on your smartphone.
Comments