In a recent article, we’ve seen how to control an Adafruit NeoPixel ring via mobile using Python and JQWidgets.
Let’s do something similar but using another very popular “actuator:" a servo motor, that is a rotary actuator used for precise control of angular position.
We’ll use Zerynth Studio to program the microcontroller-based board in Python and Zerynth App to run the JQWidget-based graphical user interface.
Required Material- First of all, you need a board. You can select one of the 32-bit microcontroller devices supported by Zerynth. We’ve chosen the Flip&Click by Mikroelektronika that carries the popular MCU SAM3X by Microchip.
- You also need an element that allows you to connect the board to the internet. We’ve chosen the WiFi 4 Click by Mikrolektronika
- You also need a Servo Motor: we’ve chosen the very popular SG90 by TowerPro.
Last but not least, you need:
- Zerynth Studio, a 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 WiFi 4 Click on the slot “A” of the Flip&Click and connect the Servo as follows:
- Brown wire of the Servo to the GND pin of the Flip&Click
- Orange wire of the Servo to the 3.3V pin of the Flip&Click
- Yellow wire of the Servo to a PWM pin of the Flip&Click (for example D2)
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 for the Particle Photon for 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:
Control Servo via Zerynth App:
# Control Servo via Zerynth App
from wireless import wifi
# change the following line to use a different wifi driver
from stm.spwf01sa import spwf01sa as wifi_driver
from servo import servo
import streams
# Import the Zerynth APP library
from zerynthapp import zerynthapp
# connect the Servo to the pin D2
MyServo=servo.Servo(D2.PWM)
streams.serial()
degree = 0
sleep(1000)
print("STARTING...")
try:
# Device UID and TOKEN can be created in the ADM panel
zapp = zerynthapp.ZerynthApp("DEVICE UID", "DEVICE TOKEN")
wifi_driver.init(SERIAL1, D16) # WiFi Click on slot
for i in range(0,5):
try:
# connect to the wifi network (Set your SSID and password below)
wifi.link("SSID",wifi.WIFI_WPA2,"PASSWORD")
break
except Exception as e:
print("Can't link",e)
else:
print("Impossible to link!")
while True:
sleep(1000)
# Start the Zerynth app instance!
# Remember to create a template with the files under the "template" folder you just cloned
# upload it to the ADM and associate it with the connected device
zapp.run()
def set_degree(d):
global degree
degree = d
MyServo.moveToDegree(degree)
zapp.on("set_degree", set_degree)
while True:
sleep(50)
print("degree: ", degree)
except Exception as e:
print(e)
Of course, you have to edit the SSID name and the PASSWORD of the wifi network you want to connect the board.
As you can see comparing the script of the project mentioned above, the logic is the same and the code is very similar. Just a few differences:
- In this case, we’ve used a different wifi driver so you have to import the SPWF01SA module instead of the BCM43362 module for the WiFi connection.
- Of course, you have to import and setup the Servo library instead of the Neopixel library.
- Then, you have to define a function that sets the degree of the servo according to the data sent by the Zerynth App. So you have to define a function “set_degree” instead of the function “set_color” of the previous project.
The rest of the code remains pretty much the same. Easy, huh? Say thanks to our Zerynth Virtual Machine and its hardware abstraction layer features.
Just another step and you’re done!
In this project too, 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.
The index.html file should look like this:
<html>
<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>Zerynth</title>
<!-- LOAD JQUERY AND BOOTSTRAP -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<!-- LOAD THE ZERYNTH ADM JS LIBRARY -->
<script src="https://api.zerynth.com/zadm/latest/z.js"></script>
<!-- LOAD jqwidget.js -->
<link rel="stylesheet" href="https://jqwidgets.com/public/jqwidgets/styles/jqx.base.css" type="text/css" />
<script src="https://jqwidgets.com/public/jqwidgets/jqx-all.js"></script>
<script type="text/javascript" src="https://www.jqwidgets.com/public/jqwidgets/jqxcore.js"></script>
</head>
<body>
<div style="text-align:center">
<p id="status" style="background:#ddd;font-weight:bold"></p>
<h1>Set Degree</h1>
</div>
<div id='jqxKnob' style="width: 150px; height: 150px; position: relative; left: 30; top:30">
</div>
<script>
$(document).ready(function () {
$('#jqxKnob').jqxKnob({
width: 300,
value: 0,
min: 0,
max: 180,
startAngle: 0,
endAngle: 180,
snapToStep: true,
rotation: 'counterclockwise',
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: 10,
minorInterval: 2
},
labels: {
offset: '88%',
step: 30,
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 }
});
$('#jqxKnob').jqxKnob({allowValueChangeOnDrag: false });
$('#jqxKnob').jqxKnob({allowValueChangeOnMouseWheel: false });
$('#jqxKnob').on('change', function (event) {
Z.call('set_degree', [event.args.value]);
});
// initialize the Z object
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){
//display received event;
}
})
});
</script>
</body>
</html>
In this case, we’ve used the “jqxKnob” element of the JQWidgets collection. The main part of this code is:
$('#jqxKnob').on('change', function (event) {
Z.call('set_degree', [event.args.value]);
});
The Z.call function is the channel from Javascript to Python. Every time you move the knob, the Z.call function sends the value to the device and it is used as argument of the corresponding Python function.
At this point, you can uplink the project to your device.
Finally, as you can read in this very brief tutorial, you just have to open the Zerynth App, log-in and select the specific device to see your GUI.
Once you’ve built your smart project, you wouldn’t want to disassemble everything to upgrade the firmware.
To meet this specification, Zerynth has included the “Firmware Over-the-Air” feature within the Zerynth Studio PRO version, that also includes industrial-grade features like:
- Selectable RTOS
- Power Saving
- Hardware-driven Secured Firmware burned on the device at industrial volumes
- …and much more
DISCOVER ZERYNTH STUDIO PRO AND UPGRADE NOW
via Zerynth Academy
Comments