How do I use serialized data in Python?

3

I have the following website:

<html>

<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" />
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" ></script>

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function() {

    $('#boton1').click(function(){

        var dataString = $('#form1').serialize();

        alert('Datos serializados: '+dataString);

        $.ajax({
            type: "POST",
            url: "/cgi-bin/script.py",
            data: dataString,
            dataType: "json",
            success: function(data) {

            }
        });
    });
});
</script>

<body>
<form id="form1" data-ajax="false">
<label for="slider-fill">Input slider:</label>
<input type="range" name="slider-fill" id="slider-fill" value="90" min="0" max="180" data-highlight="true">
<input type="submit" value="Submit" id="boton1">
</form>
</body>
</html>

As you can see what it does is send information to /cgi-bin/script.py and that information is serialized. The problem is that I do not know how to collect it in the script and later send it to an Arduino. This is what I have written in Python:

import cgi, cgitb
import serial
cgitb.enable()

ser=serial.Serial('/dev/ttyACM0',9600)
form = cgi.FieldStorage()
searchterm =  form.getvalue('form1')
ser.write(str(searchterm) + "1")

It does not work for me and I do not know what to do.

    
asked by Orizzon 28.08.2017 в 21:06
source

1 answer

3

It probably does not work for you because you are confusing the parameters sent in the form.

#! /usr/bin/python

import cgi, cgitb, json, time
import serial
cgitb.enable()

print 'Content-type: application/json; charset=utf-8\n\n'
ser=serial.Serial('/dev/ttyACM0',9600)
# Esperamos que el arduino se resetee tras abrir el puerto
time.sleep(5)
form = cgi.FieldStorage()
searchterm =  form.getvalue('slider-fill')
ser.write(str(searchterm) + "1")
print json.dumps({'resultado': True, 'enviado': searchterm})

Finally, you must give the script execution permission with chmod a+x script.py .

In your HTML you have <input> fields that are referenced by their name attribute, not the form identifier, form1 .

As I said in the comments, it is important that the user www-data is in the group dialup . To add it, do:

$ sudo adduser www-data dialup
$ sudo service lighttpd restart

In HTML you must modify the javascript to avoid sending the form using event.preventDefault() :

<html>
<link rel="stylesheet" href="//code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" />
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="//code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" ></script>

<script type="text/javascript">
$(document).ready(function() {

    $('#boton1').click(function(evento){
        /* Cancelamos el envío del formulario */
        evento.stopPropagation();
        evento.preventDefault();

        var dataString = $('#form1').serialize();

        alert('Datos serializados: '+dataString);

        $.ajax({
            type: "POST",
            url: "/cgi-bin/script.py",
            data: dataString,
            dataType: "json",
            success: function(data) {

            }
        });
    });
});
</script>

<body>
<form id="form1" data-ajax="false">
<label for="slider-fill">Input slider:</label>
<input type="range" name="slider-fill" id="slider-fill" value="90" min="0" max="180" data-highlight="true">
<input type="submit" value="Submit" id="boton1">
</form>
</body>
</html>

If you wish it is not necessary that you serialize the whole form, you could also mount your own request with the data that best suits you in the following way:

    $.ajax({
        type: "post",
        url: "/cgi-bin/script.py",
        data: {
            'slider-fill': $('#slider-fill').val(),
        },
        dataType: "json",
        success: function(data) {

        }
    });

If we do not want to wait for the arduino to be reset every time we open the port, we can create this perl script to disable the use of DTR (the signal indicating to the arduino that we just opened the port) :

#! /usr/bin/perl
use strict;
use Device::SerialPort;
my $port = Device::SerialPort->new("/dev/ttyACM0");
$port->databits(8);
$port->baudrate(9600);
$port->parity("none");
$port->stopbits(1);
$port->dtr_active(0);

To install Device::SerialPort you must run:

$ sudo cpan Device::SerialPort

The script should be executed only once each time the arduino is connected to the USB port.

PS: As we discussed in the chat, the latter does not work on Raspberry Pi.

    
answered by 29.08.2017 / 15:55
source