Noemi Gabrieli
Published © GPL3+

Controlling an Electro-Pneumatic Circuit with Zerynth App

How to build an electro-pneumatic circuit for remotely controlling a soft robot using Zerynth and a Particle Photon.

IntermediateProtip2 hours1,384

Things used in this project

Hardware components

Photon
Particle Photon
×1
Pneumatic solenoid valve
×3
DC Air pump
×3
General Purpose Transistor NPN
General Purpose Transistor NPN
×6
1N4007 – High Voltage, High Current Rated Diode
1N4007 – High Voltage, High Current Rated Diode
×7
Slide Switch
Slide Switch
×1
Capacitor 100 µF
Capacitor 100 µF
×1

Software apps and online services

Zerynth Studio
Zerynth Studio

Story

Read more

Schematics

schematics.png

Code

main.py

Python
# SoftControl
# Created at 2017-11-11 14:07:18.356087
# Author: Noemi Gabrieli

import streams # import serial library
from zerynthapp import zerynthapp # import the Zerynth APP library

from wireless import wifi # import wireless library
from broadcom.bcm43362 import bcm43362 as wifi_driver # import Photon's wifi module drivers

import mcu

# initialize serial port
streams.serial()
print('Start')

pumps   = [D5, D3, D1] # list of pump control pins
valves = [D4, D2, D0] # list of valve control pins

# set the pins as OUTPUT, default state is OFF
for pin in pumps+valves:
    pinMode(pin,OUTPUT)
    digitalWrite(pin,LOW)

# device UID and TOKEN can be created in the ADM panel
dev_uid = 'paste uid here'
dev_token = 'paste token here'
zapp = zerynthapp.ZerynthApp(dev_uid, dev_token, log=False)

# define a function that parse the pattern sent by the html template
def run_pattern(pattern, repetitions):
    global led_off
    led_off = 150
    
    print("Running pattern:",pattern)
    command_list = pattern.strip().split(" ") # split pattern in single commands list
    for r in range(int(repetitions)):
        print("Iteration",r+1,"of",repetitions)
        for cmd in command_list:
            print("Command:",cmd)
            cmd = cmd.strip()
            if cmd:
                try:
                    wait_time = int(cmd) # if cmd is not a number (ie command is not a sleep) an Exception will be raised
                    print("* sleep for",wait_time,"ms")
                    sleep(wait_time)
                except Exception as e:
                    i = int(cmd[1])-1
                    if cmd[0] == "a":
                        digitalWrite(pumps[i],HIGH)
                        print("* switch ON pump",i+1)
                    elif  cmd[0] == "s":
                        digitalWrite(pumps[i],LOW)
                        print("* switch OFF pump",i+1)
                    elif  cmd[0] == "G":
                        digitalWrite(valves[i],LOW)
                        print("* switch OFF valve",i+1)
                    elif  cmd[0] == "S":
                        digitalWrite(valves[i],HIGH)
                        print("* switch ON valve",i+1)
    print("End")

    # at the end of the pattern switch OFF all pumps and valves
    for pin in pumps+valves:
        digitalWrite(pin,LOW)
    led_off = 950
    return 'ok'


def blink_led():
    while True:
        digitalWrite(LED0,LOW)
        sleep(50)
        digitalWrite(LED0,HIGH)
        sleep(led_off)


# link "control" to run_pattern function
zapp.on("control",run_pattern)

try:
    # connect to the wifi network (Set your SSID and password below)
    wifi_driver.auto_init()
    for i in range(0,5):
        try:
            wifi.link("SSID",wifi.WIFI_WPA2,"PASSWORD")
            break
        except Exception as e:
            print("Can't link",e)
    else:
        print("Impossible to link!")
        sleep(1000)
        mcu.reset()
    
    led_off = 950
    # run a thread that blink a led faster when a pattern is running
    thread(blink_led)
    
    # start the Zerynth app instance!
    # remember to create a template with the file under the "template" folder
    # upload it to the ADM and associate it with the connected device
    zapp.run()
    
    # wait for a pattern...
    while True:
        print(".")
        sleep(5000)
        
except Exception as e:
    print(e)

template.html

HTML
<!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>SoftControl</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> 
    
    <style>
      .bd {
        margin-left: auto;
        margin-right: auto;
      }
      .mm {
        margin-left: 10px;
      }
      .cc{
        text-align: center;
      }
    </style>
  </head>
  <body>
      <div class="container-fluid bd">
        <div class="row">
          <h1 class="text-primary cc"><b>Soft Control</b></h1>
        </div>
        <br>
        
        <div class="col-xs-12">
          <div class="row">
            <div class="col-xs-2"></div>
            <div class='col-xs-2'>
              <label class="text-primary mm">Repetitions</label>
            </div>
            <div class='col-xs-6'>
              <label class="text-primary mm">Actuation pattern</label>
            </div>
            <div class="col-xs-2"></div>
          </div>

          <div class="row">
            <div class="col-xs-2">
              <button class="btn btn-block btn-danger" onclick="canc()">Canc</button>
            </div>
            <div class="col-xs-2">
              <input class="form-control" type="number" name="rname" value="1" id="rinput">
            </div>
            <div class="col-xs-6">
              <input class="form-control" type="text" name="fname" value="a1 1000 s1" id='finput'>
            </div>
            <div class="col-xs-2">
              <button class="btn btn-block btn-primary" onclick="send()">Send</button>
            </div>
          </div>

          <br>

          <div class="row cc">
            <div id="res">- - -</div>
          </div>

          <br>
          
          <div class="table-responsive table-striped"> 
            <table class="table">
              <thead>
                <tr>
                  <th>Command </th>
                  <th>Append to pattern</th>
                  <th>Description</th>
                </tr>
              </thead>
              <tbody>
                <tr>
                  <td>n</td>
                  <td>
                    <div>
                      <div class="col-xs-4">
                        <button class="btn btn-default btn-block" onclick="add('500')">500</button>
                      </div>
                      <div class="col-xs-4">
                        <button class="btn btn-default btn-block" onclick="add('1000')">1000</button>
                      </div>
                      <div class="col-xs-4">
                        <button class="btn btn-default btn-block" onclick="add('2000')">2000</button>
                      </div>
                    </div>
                  </td>
                  <td>Wait for n milliseconds</td>
                </tr>

                <tr>
                  <td>ax</td>
                  <td>
                    <div>
                      <div class="col-xs-4">
                        <button class="btn btn-default btn-block" onclick="add('a1')">a1</button>
                      </div>
                      <div class="col-xs-4">
                        <button class="btn btn-default btn-block" onclick="add('a2')">a2</button>
                      </div>
                      <div class="col-xs-4">
                        <button class="btn btn-default btn-block" onclick="add('a3')">a3</button></td>
                      </div>
                    </div>
                  </td>
                  <td>Switch ON pump x (x=1,2,3)</td>
                </tr>

                <tr>
                  <td>sx</td>
                  <td>
                    <div>
                      <div class="col-xs-4">
                        <button class="btn btn-default btn-block" onclick="add('s1')">s1</button>
                      </div>
                      <div class="col-xs-4">
                        <button class="btn btn-default btn-block" onclick="add('s2')">s2</button>
                      </div>
                      <div class="col-xs-4">
                        <button class="btn btn-default btn-block" onclick="add('s3')">s3</button></td>
                      </div>
                    </div>
                  </td>
                  <td>Switch OFF pump x (x=1,2,3)</td>
                </tr>

                <tr>
                  <td>Gx</td>
                  <td>
                    <div>
                      <div class="col-xs-4">
                        <button class="btn btn-default btn-block" onclick="add('G1')">G1</button>
                      </div>
                      <div class="col-xs-4">
                        <button class="btn btn-default btn-block" onclick="add('G2')">G2</button>
                      </div>
                      <div class="col-xs-4">
                        <button class="btn btn-default btn-block" onclick="add('G3')">G3</button></td>
                      </div>
                    </div>
                  </td>
                  <td>Switch OFF valve x (x=1,2,3) (inflate or keep inflated)</td>
                </tr>

                <tr>
                  <td>Sx</td>
                  <td>
                    <div>
                      <div class="col-xs-4">
                        <button class="btn btn-default btn-block" onclick="add('S1')">S1</button>
                      </div>
                      <div class="col-xs-4">
                        <button class="btn btn-default btn-block" onclick="add('S2')">S2</button>
                      </div>
                      <div class="col-xs-4">
                        <button class="btn btn-default btn-block" onclick="add('S3')">S3</button></td>
                      </div>
                    </div>
                  </td>
                  <td>Switch ON valve x (x=1,2,3) (deflate)</td>
                </tr>
              </tbody>
            </table>
          </div>         
        
        
        </div>
      </div>  

    <script>
    
    function canc(){
        document.getElementById("finput").value = ''
    }
    
    function add(cmd){
      var pattern = document.getElementById("finput").value
      if (pattern){
        document.getElementById("finput").value = pattern + ' ' + cmd
      }
      else {
        document.getElementById("finput").value = cmd
      }
    }
    
    function send() {
      $("#res").html("- - -")
      Z.call('control',[document.getElementById("finput").value.toString(),document.getElementById("rinput").value.toString()],control_callback);
    }
    
    //callback for remote random method
    function control_callback(msg){
      $("#res").html(msg.res);
    }

    $(document).ready(function() {
      // initialize the Z object
      Z.init();
    });

    </script>
  </body>
</html>

Credits

Noemi Gabrieli

Noemi Gabrieli

1 project • 2 followers

Comments