The attached program uses USPP to read from a serial port (USB for example).



Daniel Kersten wrote:
Hi all,

On linux, if I want to read raw values off devices (eg serial, usb, etc) I can open() /dev/whatever and then read raw bytes from that.

Does anyone know how I can do this on windows? Specifically, I want to try to read a MIDI device connected through USB. In linux, this is simply /dev/midi1, any ideas how I might access this on windows..? I don't actually want to do anything MIDI specific (so a MIDI sound library is no use to me), I want to read the raw bytes so that I can access the raw MIDI commands myself. Probably Windows won't let me read it directly, but its worth a shot.

Thanks,
Dan.

--
Daniel Kersten.
Leveraging dynamic paradigms since the synergies of 1985.



--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Python Ireland" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [email protected]
For more options, visit this group at http://groups.google.ie/group/pythonireland?hl=en
-~----------~----~----~----~------~----~------~--~---

#################################################################################
##
## readlog.py - Read gps tracklogs from Wintec 201 and write them into a .tk1 
file.
##
## Version 1.0 - Copyright (c) 2007 Steffen Siebert <[email protected]>
##
#################################################################################
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
USA
##
#################################################################################
## Requirements                                                                
##
#################################################################################
##
## Python 2.2 or later:
## <http://www.python.org>
##
## Required Python libraries:
## uspp-1.0 from http://ibarona.googlepages.com/uspp
## For usage with windows: pywin32 from 
http://sourceforge.net/projects/pywin32/ (required by uspp)
##
#################################################################################
## Known Problems:                                                             
##
#################################################################################
##
## - Several fields in the tk1 header and footer are filled with dummy values,
##   thus the created tk1 file is not identical with a tk1 file created by
##   Time Machine X. But the files created by readlog.py can be read and
##   converted in other file formats with Time Machine X.
## - The code for deleting the tracks from the Wintec 201 is included, but
##   disabled.
##
#################################################################################
## Support                                                                     
##
#################################################################################
##
## The latest version of webcheck is always available from my homepage:
## <http://www.SteffenSiebert.de/soft/python/wintec_tools.html>
##
## If you have bug reports, patches or some questions, just send a mail to
## <[email protected]>
##
#################################################################################

from winteclib import *

import datetime
import getopt
import struct
import sys
import time
import uspp

#debug = None

def isChecksumCorrect(buffer, checksum):
    cs = 0
    for char in buffer:
        cs = cs ^ ord(char)
    return checksum == "%02X" % cs

def getLogString(tty):
    line = tty.readline()
    if debug:
        print line
    return line.split(",")[-1].strip()

def getLogValue(tty):
    return int(getLogString(tty))

def writeBytes(f, byte, count):
    for i in range(count):
        f.write(byte)

def writeFooterEntry(f, tracknumber, trackvalues):
    # 24 Bytes per track.
    # 0x00-0x03: tracknumber 
    # 0x04-0x07: Offset first track 
    # 0x08-0x0b: Trackpoint count
    # 0x0c-0x0f: Track duration in seconds
    # 0x10-0x17: Track length as double
    f.write(struct.pack('l', tracknumber))
    f.write(struct.pack('l', trackvalues[0]))
    f.write(struct.pack('l', trackvalues[1]))
    f.write(struct.pack('l', trackvalues[2]))
    f.write(struct.pack('d', trackvalues[3]))

def writeHeader(f, devicename, deviceinfo, trackpointcount, footerpos, 
trackcount):
    f.write('WintecLogFormat' + chr(0x00))
    f.write(chr(0x00)+chr(0x00)+chr(0x80)+chr(0x3f))
    f.write(chr(0x00)+chr(0x00)+chr(0x80)+chr(0x3f))
    f.write(chr(0x00)+chr(0x00)+chr(0x80)+chr(0x3f))
    f.write(chr(0x41)+chr(0xbf)+chr(0x10)+chr(0x00))
    f.write(struct.pack('l', trackpointcount))
    f.write(chr(0x00)+chr(0x00)+chr(0x00)+chr(0x00))
    f.write(devicename)
    writeBytes(f, chr(0), 20-len(devicename))
    f.write(deviceinfo)
    writeBytes(f, chr(0), 20-len(deviceinfo))
    f.write('YYMM1234567890'+chr(0x00)+chr(0x00))
    writeBytes(f, chr(0), 24)
    f.write(time.strftime("%Y_%m_%d_%H:%M:%S", time.localtime()) +chr(0))
    f.write(struct.pack('l', footerpos))
    f.write(struct.pack('l', trackcount))
    writeBytes(f, chr(0), 876)

def parseTracklog(data):
    outputFile = None
    dataPos = 0
    trackCount = 0
    trackPointCount = 0
    trackStartPos = 0x400
    trackStartDateTime = None
    trackDistance = float(0)
    previousDateTime = None
    previousLatitude = None
    previousLongitude = None
    tracks = {}
    while dataPos < len(data):
        byte = data[dataPos]
        dateTime = convertToDateTime(readLongWord(data, dataPos+2))
        # The first trackpoint might not be marked with the trackstart flag.
        if ord(byte) & 0x01 == 1 or dataPos == 0:
            if previousDateTime != None:
                trackDuration = previousDateTime - trackStartDateTime
                tracks[trackCount-1] = (trackStartPos, trackPointCount, 
trackDuration.days * 24 * 60 * 60 + trackDuration.seconds, trackDistance)
            # Start of new Track
            trackPointCount = 0
            trackStartPos = dataPos + 0x400
            trackStartDateTime = dateTime
            trackDistance = float(0)
            previousDateTime = None
            previousLatitude = None
            previousLongitude = None
            trackCount = trackCount + 1
        latitude = float(readSignedLongWord(data, dataPos+6))
        longitude = float(readSignedLongWord(data, dataPos+10))
        altitude = float(readSignedWord(data, dataPos+14))
        speed = 0
        if previousLatitude:
            trackDistance = trackDistance + 
calculateVincentyDistance(previousLatitude / 10000000.0, previousLongitude / 
10000000.0, latitude / 10000000.0, longitude / 10000000.0)
        previousDateTime = dateTime
        previousLatitude = latitude
        previousLongitude = longitude
        trackPointCount = trackPointCount + 1
        dataPos = dataPos + 16
    if previousDateTime != None:
        trackDuration = previousDateTime - trackStartDateTime
        tracks[trackCount-1] = (trackStartPos, trackPointCount, 
trackDuration.days * 24 * 60 * 60 + trackDuration.seconds, trackDistance)
    return tracks

def usage():
    print "Usage: python readlog.py [-v] [-p password] [-d] [serial port] 
[filename]"
    print "-v: Print debug info"
    print "-p: Wintec password (4 digits)"
    print "-d: Delete log from Wintec after transfer"

def main():
    global debug
    
    BAUDRATE = 57600
    READ_TIMEOUT = 3000 # 3 seconds

    deleteLog = None
    password = None
    debug = None
    
    try:
        opts, args = getopt.getopt(sys.argv[1:], "?hvp:d")
    except getopt.GetoptError:
        # print help information and exit:
        usage()
        sys.exit(2)
    if len(args) != 2:
        usage()
        sys.exit(1)

    for o, a in opts:
        if o == "-v":
            debug = 1
        if o in ("-h", "-?"):
            usage()
            sys.exit()
        if o == "-d":
            deleteLog = 1
        if o == "-p":
            password = a

    tty = None
    f = None
    try:
        tty = uspp.SerialPort(args[0], READ_TIMEOUT, BAUDRATE)

        # I'm not sure why, but the next two lines seem to be necessary to 
enter command code.
        time.sleep(1)
        tty.readline()

        print "Enter command mode"
        if password:
            tty.write("@AL,1%s\n" % password)
        else:
            tty.write("@AL,\n")
        ready = 0
        retrycount = 50
        while 1:
            try:
                line = tty.readline()
            except uspp.SerialPortException, ex:
                if str(ex) == "Timeout" and line == '@AL\n' and password == 
None:
                    print "Device seem to be password protected!"
                    print "Please provide the correct password using option -p"
                    sys.exit(1)
                else:
                    raise ex
                    sys.exit(1)
            if debug:
                print line
            if line == "@AL,LoginOK\n":
                ready = 1
                break
            if password and line == "@AL,PassworError\n":
                print "Wrong Password"
                sys.exit(1)
            retrycount = retrycount - 1
            if retrycount <= 0:
                break

        if ready == 1:
            tty.write("@AL,07,01\n")
            devicename = getLogString(tty)
            tty.write("@AL,07,02\n")
            deviceinfo = getLogString(tty)
            tty.write("@AL,01,01\n")
            autosleep = getLogString(tty)
            tty.write("@AL,01,02\n")
            overspeed = getLogString(tty)
            tty.write("@AL,05,01\n")
            logstart = getLogValue(tty)
            tty.write("@AL,05,02\n")
            logend = getLogValue(tty)
            tty.write("@AL,05,09\n")
            logareastart = getLogValue(tty)
            tty.write("@AL,05,10\n")
            logareaend = getLogValue(tty)
            print "Logarea: %s-%s" % (logareastart, logareaend)
            print "Log: %s-%s" % (logstart, logend)
            logcapacy = (logareaend - logareastart) / 16
            if logcapacy < 4096:
                readcount = logcapacy
            else:
                readcount = 4096
            readstart = int(logstart)
            lastsection = 0
            tracklog = ''
            while 1:
                print "Read buffer at %s (%s Bytes)" % (readstart, readcount)
                tty.write("@AL,05,03,%i\n" % readstart)
                try:
                    buffer = tty.read(readcount)
                except uspp.SerialPortException:
                    print "Buffer read timeout, retrying"
                    continue
                line = tty.readline()
                if debug:
                    print line
                checksum = line.split(",")[2]
                if debug:
                    print "Expected block checksum: " + checksum
                if not isChecksumCorrect(buffer, checksum):
                    print "Buffer read error, retrying"
                    continue
                else:
                    tracklog = tracklog + buffer
                line = tty.readline()
                if debug:
                    print line
                if lastsection == 1:
                    break
                readstart = readstart + len(buffer)
                if readstart >= logareaend:
                    readstart = logareastart
                if (readstart < logend) and (readstart + 4096 >= logend):
                    readcount = logend - readstart
                    lastsection = 1

            # Write data as .tk1 file
            f = open(args[1], "wb")
            tracks = parseTracklog(tracklog)
            writeHeader(f, devicename, deviceinfo, len(tracklog)/16, 
len(tracklog) + 0x0400, len(tracks))
            f.write(tracklog)
            for key in tracks.keys():
                writeFooterEntry(f, key, tracks[key])
            f.close()
            if deleteLog:
                tty.write("@AL,05,06\n")
        else:
            print "Can't switch into command mode!"
    finally:
        print "Exit command mode"
        if tty != None:
            tty.write("@AL,02,01\n")
            del tty

if __name__ == "__main__":
    main()

Reply via email to