Controlar el Osciloscopio Hammer desde la PC

En el manual el osciloscopio dice que lleva una inicialización, pero eso debe haber sido con el firmware de fábrica cuando lo compraron, porque con el nuevo no hace falta. Se probó con el firmware original y no funcionó la comunicación así que se procedió a actualizar el firmware por una versión mas nueva. Luego de un par de pruebas se logró la comunicación con el mismo. La configuración del puerto serie se hace desde el osciloscopio mismo, en el menú->interfaz y ahí están las opciones del puerto, velocidad, bits, paridad, etc.

El manual con los comandos es el siguiente. Algo que no sale en el manual es que la Trama termina siempre con CR(Retorno de Carro - 0xd).

A continuación un programita de ejemplo hecho en python para poder comunicarse con el osciloscopio. Trae los datos de la actual pantalla y los grafica usando pylab.

#! /usr/bin/python
#coding=utf-8
from __future__ import division
import serial
import sys
import pylab
import time
import numpy
class communication( serial. Serial):
def __init__( self, * args, ** kwargs):
#Asegura que el timeout tenga un valor rasonable
timeout = kwargs. get( ' timeout ', 0.1)
if timeout < 0.01: timeout = 0.1
kwargs[ ' timeout '] = timeout
serial. Serial. __init__( self, * args, ** kwargs)
self. buf = ' '
def readline( self, timeout= 1):
"""timeout en segundos es el máximo tiempo que debe esperar para una trama completa"""
tries = 0
while 1:
self. buf += self. read( 512)
pos = self. buf. find( ' \n ')
if pos > 0:
line, self. buf = self. buf[: pos+ 1], self. buf[ pos+ 1:]
return line
tries += 1
if tries * self. timeout > timeout:
break
line, self. buf = self. buf, ' '
return line
def readlines( self, sizehint= None, timeout= 1):
"""Lee todas las tramas que hay disponibles. Aborta después del timeout
o cuando no hay mas datos."""
lines = []
while 1:
line = self. readline( timeout= timeout)
if line:
lines. append( line)
if not line: # or line[-1:] != '\n':
break
return lines
def send_cmd( self, dato):
if not dato. endswith( ' \n '):
dato += ' \n '
self. write( dato)
def get_trace( self):
self. send_cmd( ' :TRAC:FORMAT ASCII ')
time. sleep( 0.1)
self. send_cmd( ' :TRAC:DATA? ')
return self. readline( 8). strip()
def get_time_scale( self):
s. send_cmd( ' :HOR:MAIN:SCAL? ')
return s. readline(). strip()
def get_amplitud_scale( self, channel= " 1 "):
s. send_cmd( ' :CHAN %s :SCAL? ' % channel)
return s. readline(). strip()
if __name__== ' __main__ ':
if len( sys. argv) <= 2:
print """
Uso: python %s /dev/ttyUSB0 filename """ % sys. argv[ 0]
sys. exit( 0)
PORT = sys. argv[ 1]
BAUDRATE = 115200
s = communication( PORT, BAUDRATE)
s. flush()
data = s. get_trace()
fh_out = open( " %s .txt " % sys. argv[ 2], ' w ')
fh_out. write( data)
fh_out. close()
data = data. split( ' , ')
data = numpy. asarray( data, numpy. float32)
cant_ptos = len( data)
axis_t = numpy. arange( cant_ptos)
time_scale = s. get_time_scale()
time_scale_float = float( time_scale)
#axis_t = axis_t * time_scale_float * 10
t_por_pto = ( 10* time_scale_float)/ cant_ptos
axis_t = axis_t * t_por_pto
pylab. xlabel( ' %s Tiempo/Div ' % time_scale)
pylab. ylabel( ' %s Voltage/Div ' % s. get_amplitud_scale())
pylab. title( ' %s ' % sys. argv[ 2])
pylab. grid( True)
pylab. plot( axis_t, data)
#print numpy.arange(0, 10*time_scale_float, time_scale_float)
pylab. xticks( numpy. arange( 0, 10* time_scale_float, time_scale_float))
#pylab.xticks(numpy.arange(0, 10*s.get_time_scale(), s.get_time_scale()))
#pylab.yticks(numpy.arange(0, 8*float(s.get_amplitud_scale()), float(s.get_amplitud_scale())))
pylab. savefig( ' %s ' % sys. argv[ 2])
#pylab.show()
print " Captura %s terminada " % sys. argv[ 2]
sys. exit( 0)
control_osc.py