Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

convert perl-script for voltcraft voltmeter to python [newbie]

108 views
Skip to first unread message

Jean Dupont

unread,
Feb 2, 2012, 3:57:55 PM2/2/12
to
I'd like to read in the output of a voltcraft vc960 voltmeter
connected to a usb-port.
I found the perl-script below but I'd like to accomplish the same with
python:
I guess I have to use the module serial but I don't know how I should
set the serial parameters so they are the same as in the perl-script.
Could someone supply me the command for setting the serial-parameters
correctly
in Python?

thanks
Jean

#!/usr/bin/perl

use strict;
use warnings;

use Device::SerialPort;

die("Usage: $0 /dev/ttyS0\n") unless $#ARGV == 0;

my ($devicepath) = @ARGV;

my $port = new Device::SerialPort($devicepath);
die "Couldn't open serial port" if ! defined $port;

$port->baudrate(2400);
$port->databits(8);
$port->parity("none");
$port->stopbits(1);
$port->handshake("none");
$port->rts_active(0);
$port->dtr_active(1);

#$port->read_char_time(5); # wait 5ms per character
$port->read_const_time(200); # 0.2 second per unfulfilled "read"
call
$| = 1; # autoflush STDOUT
while(1) {
my ($nin, $in) = $port->read(255);
print $in;
}

$port->close;

Jean Dupont

unread,
Feb 3, 2012, 8:11:54 AM2/3/12
to
As my request might have been too much asked, I have started doing
some coding myself.
I'm in doubt about the readline statement -which doesn't show anything
received- as the meter sends continuously streams of 11 bytes
Is there a way to just monitor with python what is arriving at a
serial port?

#!/usr/bin/python
#version 1-2-2012, script to read data from voltcraft vc940-meter
import serial, time, os
voltport='/dev/ttyUSB2'
print "Be sure the Voltcraft is connected to ttyUSB2"
print "Enter a filename:",
filename = raw_input()
voltdata = open(filename,'w')
ser2 = serial.Serial(voltport, 2400, 8, serial.PARITY_NONE, 1,
timeout=15)
print "rs-232 parameters of Voltcraft: ", ser2
print "Opening " + ser2.portstr
received=ser2.readline()
print received
print "Goodbye, data logged in file:"
print filename
ser2.close()
# Close file
voltdata.close()

Terry Reedy

unread,
Feb 6, 2012, 11:21:24 PM2/6/12
to pytho...@python.org
On 2/2/2012 3:57 PM, Jean Dupont wrote:
> I'd like to read in the output of a voltcraft vc960 voltmeter
> connected to a usb-port.
> I found the perl-script below but I'd like to accomplish the same with
> python:

The script below is for an old-fashioned, slow, multiple-pin serial
port, not usb. I don't know anything about interfacing through usb.
Recheck what the voltmeter actually connects to.

> I guess I have to use the module serial but I don't know how I should
> set the serial parameters so they are the same as in the perl-script.
> Could someone supply me the command for setting the serial-parameters
> correctly in Python?

Last I know, pyserial is also for old serial ports. Setting the
properties should be pretty obvious from the manual or code.

There are also python usb modules.
http://sourceforge.net/projects/mysql-python/?source=directory

> #!/usr/bin/perl
>
> use strict;
> use warnings;
>
> use Device::SerialPort;
>
> die("Usage: $0 /dev/ttyS0\n") unless $#ARGV == 0;
>
> my ($devicepath) = @ARGV;
>
> my $port = new Device::SerialPort($devicepath);
> die "Couldn't open serial port" if ! defined $port;
>
> $port->baudrate(2400);
> $port->databits(8);
> $port->parity("none");
> $port->stopbits(1);
> $port->handshake("none");
> $port->rts_active(0);
> $port->dtr_active(1);
>
> #$port->read_char_time(5); # wait 5ms per character
> $port->read_const_time(200); # 0.2 second per unfulfilled "read"
> call
> $| = 1; # autoflush STDOUT
> while(1) {
> my ($nin, $in) = $port->read(255);
> print $in;
> }
>
> $port->close;


--
Terry Jan Reedy

Message has been deleted

Jean Dupont

unread,
Feb 7, 2012, 2:44:40 PM2/7/12
to
On 7 feb, 05:21, Terry Reedy <tjre...@udel.edu> wrote:
> On 2/2/2012 3:57 PM, Jean Dupont wrote:
>
> > I'd like to read in the output of a voltcraft vc960 voltmeter
> > connected to a usb-port.
> > I found the perl-script below but I'd like to accomplish the same with
> > python:
>
> The script below is for an old-fashioned, slow, multiple-pin serial
> port, not usb. I don't know anything about interfacing through usb.
> Recheck what the voltmeter actually connects to.
The voltmeter uses an optical rs232-connection, that is "good enough
technology" for this purpose. But as I don't have a computer with real
rs232 ports I use a rs232toUSB adapter which presents itself to the
linux-computer as /dev/ttyUSBx.
>
> > I guess I have to use the module serial but I don't know how I should
> > set the serial parameters so they are the same as in the perl-script.
> > Could someone supply me the command for setting the serial-parameters
> > correctly in Python?
>
> Last I know, pyserial is also for old serial ports. Setting the
> properties should be pretty obvious from the manual or code.
>
It is not so obvious as you might think, one reason being the
handshake line(s?) are used in an unconvential way to supply power to
the rs232-optical interface
I followed this link but all I found was something concerning
mysql...???
>
anyway, thanks for trying to help

Jean

Rick Johnson

unread,
Feb 7, 2012, 2:47:31 PM2/7/12
to
On Feb 7, 11:44 am, Dennis Lee Bieber <wlfr...@ix.netcom.com> wrote:
>
> [...]
>
>         Well, since readline() pretty much by definition wants a line-ending
> character before returning, it obviously won't work. (Side comment:
> readline() isn't even shown as part of the basic Serial class -- it is
> in a class FileLike:http://pyserial.sourceforge.net/pyserial_api.html
> -- oh wait.. fine print says that is a base class for Serial on non-io
> module systems).
>
>         What is the boundary marker for your 11-byte chunks? You may need to
> do a synchronization loop using
>
> [...]
>
>         Your timeout is FIFTEEN SECONDS!
>
>         Suspect you want something like

Why do you have this unnatural penchant for superfluous eight space
indention?

I always thought that indenting the first sentence of a paragraph was
quite ridiculous anyhow, however, i cannot even fathom any need to
indent a single sentence! Are you purposely injecting this noise or is
this some automated behavior of your broken mail client? Either way, i
find it annoying and unreadable. Could you please rectify this issue
and bring signal to noise ratio back to reasonable levels?
Message has been deleted

Dietmar Schwertberger

unread,
Feb 7, 2012, 7:26:48 PM2/7/12
to
Am 03.02.2012 14:11, schrieb Jean Dupont:
> As my request might have been too much asked, I have started doing
> some coding myself.
> I'm in doubt about the readline statement -which doesn't show anything
> received- as the meter sends continuously streams of 11 bytes
> Is there a way to just monitor with python what is arriving at a
> serial port?
Some time ago I started working on reading data from a VC940.
I would assume that the protocol is the same.

Please find below the code that will return the raw values from
a VC940 (tested on a classical RS232 port, but probably
will work on USB-RS232 converters as well).


If you don't get anything, then you should check whether your
USB converter is supplying voltage on the DTR pin once you have called
self.serial.setDTR(1).


You have the description how to decode the values?
E.g. the string "0003:1401" translates to 0.3 Ohms.

I did not implement anything else, as I just wanted to be sure
that I could read the values, but I never needed to...


Regards,

Dietmar


import serial
import time


class VC940(object):
def __init__(self, port="COM3"):
self.port = port
self.serial=serial.Serial(port,2400, bytesize=7, parity="N",
stopbits=1, timeout=1.5, xonxoff=0, rtscts=0, dsrdtr=None)
self.serial.setRTS(0)
self.serial.setDTR(0)
def _read_raw_value(self):
timeout = True
for n in range(5):
self.serial.flushInput()
self.serial.setDTR(1)
data = self.serial.read(11)
self.serial.setDTR(0)
if data.endswith("\r\n") and len(data)==11:
return data
if not data:
raise ValueError, "communication timeout"
raise ValueError, "could not read data from port"


if __name__=="__main__":
vc = VC940()
while True:
print vc._read_raw_value()

Jean Dupont

unread,
Feb 8, 2012, 7:24:12 AM2/8/12
to
Wow, this is great, it works like a charm. Thanks a lot!

Jean
0 new messages