PyUSB communication with Raspberry Pi and custom temp / humidity sensor - python

I have:
USB HID raw temp/humidity sensor
raspberry Pi B
I want:
python to get data from USB sensor on the PI
With the help of several different web pages and some answers on this site, I have found the device, I can show the interface details and send an array and get one data point, but then the device is busy and times out. Why would it only send one reading and then require replugging to get another data point? My first thought was maybe it is the device, but the device works just fine on my windows box. Is my python code wrong?
The USB device sends 16 bit data on interrupt IN endpoint #1 and receives data on interrupt OUT endpoint 2 (because that is how I wrote the firmware).
Python code:
#!/usr/bin/env python
import usb
import sys
dev = usb.core.find(idVendor=0x1dfd, idProduct=0x0006)
if not dev:
raise IOError('Device not found')
else:
# dev.set_configuration()
cfg = dev.get_active_configuration();
# cfg = [(0,0)]
print ("Device located")
print ('configuration ' + str(cfg));
for configuration in dev:
for interface in configuration:
ifnum = interface.bInterfaceNumber
if not dev.is_kernel_driver_active(ifnum):
continue
try:
print "detach %s: %s" % (dev, ifnum)
dev.detach_kernel_driver(ifnum)
reattach = True
renum = ifnum
except usb.core.USBError, e:
pass
dev.set_configuration()
interface_number = 0
alternate_setting = usb.control.get_interface(dev,interface_number)
intf = usb.util.find_descriptor(cfg, bInterfaceNumber = interface_number,bAlternateSetting = alternate_setting)
epO = usb.util.find_descriptor(
intf,
custom_match = \
lambda f: \
usb.util.endpoint_direction(f.bEndpointAddress) == \
usb.util.ENDPOINT_OUT
)
epI = usb.util.find_descriptor(
intf,
custom_match = \
lambda f: \
usb.util.endpoint_direction(f.bEndpointAddress) == \
usb.util.ENDPOINT_IN
)
# write the data
print('epI length ' + str(epI.bLength))
print('ep desc type ' + str(epI.bDescriptorType))
print('ep address ' + str(epI.bEndpointAddress))
print('ep xfer type ' + str(epI.bmAttributes))
# print('ep synch type ' + str(epI.bmAttributes[1]))
# print('ep Use type ' + str(epI.bmAttributes[2]))
print('ep max packet ' + str(epI.wMaxPacketSize))
print('ep interval ' + str(epI.bInterval))
print('epO length ' + str(epO.bLength))
print('ep desc type ' + str(epO.bDescriptorType))
print('ep address ' + str(epO.bEndpointAddress))
print('ep xfer type ' + str(epO.bmAttributes))
# print('ep synch type ' + str(epO.bmAttributes[1]))
# print('ep Use type ' + str(epO.bmAttributes[2]))
print('ep max packet ' + str(epO.wMaxPacketSize))
print('ep interval ' + str(epO.bInterval))
print('dev length ' + str(dev.bLength))
print('dev num configs ' + str(dev.bNumConfigurations))
print('dev class ' + str(dev.bDeviceClass))
assert epO is not None
assert epI is not None
msg = '2234567890123456' #first character is the command
print('writing to USB ->' + msg)
print(str(dev))
# dev.write(epO, msg, 100)
epO.write(msg)
print('reading from USB...')
ret = epI.read(16)
# ret = dev.read(2,len(msg),100) # device timeout is 50 ms,
sret = ''.join([chr(x) for x in ret])
print(sret)
# This is needed to release interface, otherwise attach_kernel_driver fails
# due to "Resource busy"
usb.util.dispose_resources(dev)
# It may raise USBError if there's e.g. no kernel driver loads
if reattach:
print('Reattaching Kernel Driver')
dev.attach_kernel_driver(renum)
and here is the response when executed on the PI:
Device located
configuration <usb.core.Configuration object at 0xb6a6e6d0>
detach <usb.core.Device object at 0xb6a6e750>: 0
epI length 7
ep desc type 5
ep address 129
ep xfer type 3
ep max packet 16
ep interval 50
epO length 7
ep desc type 5
ep address 2
ep xfer type 3
ep max packet 16
ep interval 50
dev length 18
dev num configs 1
dev class 0
writing to USB ->
<usb.core.Device object at 0xb6a6e750>
2234567890123456
reading from USB...
227.45,51.0 ## The first response has this after the last line above
## the second try gives this response instead:
Traceback (most recent call last):
File "./t8.py", line 78, in <module>
ret = epI.read(16)
File "/usr/local/lib/python2.7/dist-packages/usb/core.py", line 300, in read
return self.device.read(self.bEndpointAddress, size, self.interface, timeout)
File "/usr/local/lib/python2.7/dist-packages/usb/core.py", line 670, in read
self.__get_timeout(timeout)
File "/usr/local/lib/python2.7/dist-packages/usb/backend/libusb1.py", line 798, in intr_read
timeout)
File "/usr/local/lib/python2.7/dist-packages/usb/backend/libusb1.py", line 889, in __read
_check(retval)
File "/usr/local/lib/python2.7/dist-packages/usb/backend/libusb1.py", line 571, in _check
raise USBError(_str_error[ret], ret, _libusb_errno[ret])
usb.core.USBError: [Errno 110] Operation timed out
I searched and found that I can check the linux messages for USB with this command:
grep usb /var/log/messages
and I found this message:
Nov 3 02:16:06 raspberrypi kernel: [123725.144960] usb 1-1.3: usbfs: process 10698 (python) did not claim interface 0 before use
I added the reattach code and that went away. I searched and found that others had the issue and it might be pyUSB. I updated to the b2 release. Now the device print command gives a full HID report printout when the print(dev) command is given. Very nice, but the original problem of the device timeout remains and it is not looking like it has to do with a claimed interface.
Any insight on how I can prevent the timeout so the device can give more than one set of data?
Thanks for your help.

Related

Python - getting SerialNumber of usb-devices with pyUsb in windows

I'm trying to create a list of alll usb mass storage devices with their VendorIf, the ProductId and the SerialNumber.
Therefore I use the pyUsb module and run the following program.
import sys
import usb
import usb.core
import usb.util
devs = usb.core.find(find_all=True)
nCount=0
for dev in devs:
try:
for cfg in dev:
intf = usb.util.find_descriptor(cfg,bInterfaceClass=0x8)
if intf is not None:
nCount += 1
try:
sys.stdout.write("USB device " + usb.util.get_string(dev,dev.iProduct,None) + '\n')
except:
sys.stdout.write("USB device " + str(nCount) + '\n')
sys.stdout.write("------" + '\n')
sys.stdout.write("VendorId = " + hex(dev.idVendor) + '\n')
sys.stdout.write("ProductId = " + hex(dev.idProduct) + '\n')
if not dev.iSerialNumber == 0:
sys.stdout.write("SerialNbr = " + usb.util.get_string(dev,dev.iSerialNumber,None) + '\n')
else:
sys.stdout.write("SerialNbr = none" + '\n')
sys.stdout.write('\n')
except usb.core.USBError:
pass
In generally the script works. Depending on the device I get outputs like this:
USB device USB DISK
-------
VendorId = 0x90c
ProductId = 0x2000
SerialNbr = none
But with various devices I get the following error:
File
"C:\Users\UerXy\AppData\Local\Programs\Python\Python39\lib\site-packages\usb\backend\libusb1.py",
line 600, in _check
raise NotImplementedError(_strerror(ret)) NotImplementedError: Operation not supported or unimplemented on this platform
When debugging the code, the error occures when it tries to read the string descriptor using the function usb.util.get_string()
I read somewhere, that the function is dependant on the driver.
Is this true? Isn't it possible to read the serial number of any given usb-device without taking care of the used usb-driver?
How can this error be solved and the descriptors be read from every device?
You can use the following code to get the information of all connected drives (flash memory and hdd).
import os
os.system('echo list volume > Ravi.txt')
path1 = os.path.join(os.getcwd(),"Ravi.txt")
os.system('diskpart /s '+path1+' > logfile.txt')
path2 = os.path.join(os.getcwd(),"logfile.txt")
Str = open(path2).read()
Str = Str.split('\n')
matching = [s for s in Str if "Removable" in s]
for i in matching:
i = ' '.join(i.split())
i = i.split(" ")
print(i)
import subprocess
serials = subprocess.check_output('wmic diskdrive get SerialNumber').decode().split('\n')[1:]
serials = [s.strip() for s in serials if s.strip()]
After running this code, two txt files will be created in the current location, in which the desired information is written

Netmiko library returns pattern never detected in send_command_expect

I am working as a network engineer and I have tried to automate routine tasks with some python scripts. We are using cisco so I thought it would be nice to implement netmiko library.
Here is the part of the script which is used to connect to device and edit access-lists:
def Connection (DevParameters, device, HostAddress):
try:
net_connect = ConnectHandler(**DevParameters)
except:
print device[0] + ': Authentication failed or device unavailable'
return
access_class = net_connect.send_command("sh run | inc access-class")
if access_class == '':
print device[0] + ': No access-class configured.'
net_connect.disconnect()
return
access_class = access_class.splitlines()[0].split(' ')[-2]
acl_type = net_connect.send_command("sh ip access-list " + access_class).splitlines()[0].split(' ')[0].lower()
net_connect.send_command('configure terminal')
net_connect.send_command('ip access-list ' + acl_type + access_class)
if acl_type == 'extended':
net_connect.send_command('permit tcp host' + HostAddress + ' any eq 22')
elif acl_type == 'standard':
net_connect.send_command('permit ' + HostAddress )
else:
print device[0] + ': Unexpected ACL type. Connection closed.'
net_connect.disconnect()
return
print device[0] + ': Configured.'
net_connect.disconnect
return
It works nicely from IDLE writing command line by line but when executing script it fails with:
Traceback (most recent call last):
File "C:\Users\User\Desktop\MAT.py", line 145, in <module>
Connection (DevParameters, device, HostAddress)
File "C:\Users\User\Desktop\MAT.py", line 90, in Connection
net_connect.send_command('configure terminal')
File "C:\Program Files\Python27\lib\site-packages\netmiko\base_connection.py", line 827, in send_command
search_pattern))
IOError: Search pattern never detected in send_command_expect: HQ\_F3\_2960\_D\-5\#
I tried to implement sleep() after send_command() to no avail. What could be the issue?
I've got a similar problem, but I solved it with set length 0.
I share my code, I hope to help you.
extrm_X460 = {
'device_type': 'extreme',
'ip': ip,
'username': 'username',
'password': 'password',
'port' : 22,
}
try:
# Connect
print "Trying to connect to: " + ip
net_connect = ConnectHandler(**extrm_X460)
# Get info
print "Connected to: " + ip
net_connect.send_command('set length 0')
output = net_connect.send_command('show mac port ge.*.*')
print output
except (IOError, EOFError, SSHException, NetMikoTimeoutException, NetMikoAuthenticationException) as e:
print e
continue
Use send_command_timing instead of send_command.
send_command is detecting a device prompt (pattern-based) (it will work with "show" commands).
send_command_timing is delay-based and doesn't look for the device prompt (will work in configuration mode [conf t])
Example: net_connect.send_command_timing

How do I use Python to retrieve Registry values?

I have written this code so far;
from _winreg import *
def val2addr(val):
addr = ''
for ch in val:
addr += '%02x '% ord(ch)
addr = addr.strip(' ').replace(' ', ':')[0:17]
return addr
def printNets():
net = "SOFTWARE\Microsoft\Windows NT\CurrentVersion"+\
"\NetworkList\Signatures\Unmanaged"
key = OpenKey(HKEY_LOCAL_MACHINE, net)
print '\n[*] Networks You Have Joined.'
for i in range(100):
try:
guid = EnumKey(key, i)
netKey = OpenKey(key, str(guid))
(n, addr, t) = EnumValue(netKey, 5)
(n, name, t) = EnumValue(netKey, 4)
macAddr = val2addr(addr)
netName = str(name)
print '[+] ' + netName + ' ' + macAddr
CloseKey(netKey)
except:
break
def main():
printNets()
if __name__ == "_main_":
main()
This script returns the MAC addresses and network names of all the WiFi networks you have joined.
It returns values from
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows >NT\CurrentVersion\NetworkList\Signatures\Unmanaged\
I am on Windows 8.1 and I have checked through Regedit.exe to make sure this is the correct location for the info I am retrieving.
When I run this code it says "WindowsError: [Error 2] The system cannot find the file specified"
So what is it I am doing wrong?
P.S I am on Python 2.7.9
Full Traceback
Traceback (most recent call last):
File "<pyshell#11>", line 1, in <module>
printNets()
File "C:/Users/Nathaniel/Desktop/MacAddr Meta-Reader.py", line 13, in printNets
key = OpenKey(HKEY_LOCAL_MACHINE, net)
WindowsError: [Error 2] The system cannot find the file specified
You're probably using 32-bit Python on 64-bit Windows. In this case opening HKLM\SOFTWARE gets redirected to HKLM\SOFTWARE\Wow6432Node. You have to specify otherwise if you want the 64-bit key. For example:
key = OpenKey(HKEY_LOCAL_MACHINE, net, 0,
KEY_READ | KEY_WOW64_64KEY)
Note that for subkeys opened relative to this key object, it isn't strictly necessary to specify KEY_WOW64_64KEY.
I ported your code to run in both Python 2 and 3, added iterators, and eliminated the hard-coded range and index values. Maybe you'll find it helpful:
from __future__ import print_function
import itertools
try:
from winreg import *
except ImportError: # Python 2
from _winreg import *
KEY_READ_64 = KEY_READ | KEY_WOW64_64KEY
ERROR_NO_MORE_ITEMS = 259
def iterkeys(key):
for i in itertools.count():
try:
yield EnumKey(key, i)
except OSError as e:
if e.winerror == ERROR_NO_MORE_ITEMS:
break
raise
def itervalues(key):
for i in itertools.count():
try:
yield EnumValue(key, i)
except OSError as e:
if e.winerror == ERROR_NO_MORE_ITEMS:
break
raise
def val2addr(val):
return ':'.join('%02x' % b for b in bytearray(val))
NET_UNMANAGED = (r"SOFTWARE\Microsoft\Windows NT\CurrentVersion"
r"\NetworkList\Signatures\Unmanaged")
def printNets(keystr=NET_UNMANAGED):
key = OpenKey(HKEY_LOCAL_MACHINE, keystr, 0, KEY_READ_64)
print('\n[*] Networks You Have Joined.')
for guid in iterkeys(key):
netKey = OpenKey(key, guid)
netName, macAddr = '', ''
for name, data, rtype in itervalues(netKey):
if name == 'FirstNetwork':
netName = data
elif name == 'DefaultGatewayMac':
macAddr = val2addr(data)
if netName:
print('[+]', netName, macAddr)
CloseKey(netKey)
CloseKey(key)
The key's security descriptor only allows access to administrators and the netprofm service, as shown below. So you either need to run the script from an elevated command prompt or use a technique to have the script autoelevate.
C:\>set NT=HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion
C:\>accesschk -qldk "%NT%\NetworkList\Signatures\Unmanaged"
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\
NetworkList\Signatures\Unmanaged
DESCRIPTOR FLAGS:
[SE_DACL_PRESENT]
[SE_DACL_PROTECTED]
OWNER: BUILTIN\Administrators
[0] ACCESS_ALLOWED_ACE_TYPE: NT SERVICE\netprofm
[CONTAINER_INHERIT_ACE]
[INHERITED_ACE]
KEY_QUERY_VALUE
KEY_CREATE_LINK
KEY_CREATE_SUB_KEY
KEY_ENUMERATE_SUB_KEYS
KEY_NOTIFY
KEY_SET_VALUE
READ_CONTROL
DELETE
[1] ACCESS_ALLOWED_ACE_TYPE: BUILTIN\Administrators
[CONTAINER_INHERIT_ACE]
[INHERITED_ACE]
KEY_ALL_ACCESS
C:\>sc qdescription netprofm
[SC] QueryServiceConfig2 SUCCESS
SERVICE_NAME: netprofm
DESCRIPTION: Identifies the networks to which the computer has
connected, collects and stores properties for these networks,
and notifies applications when these properties change.
Do you have administrator privileges? I tried walking down the tree with "reg query" to make sure that I didn't have a spelling problem and when I got to "NetworkList" I got an Access denied error. I changed to administrator privileges and everything was fine.
reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList
ERROR: Access is denied.

Python connect to IRC function - must be integer

I made a basic IRC bot that would join a certain channel and say a defined phrase, as part of learning Python. However, are there changes in the latest version of Python?
import socket
nick = 'TigerBot'
passdwd = '*****'
port = '6667'
net = 'irc.snoonet.org'
chan = '#WritingPrompts'
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Was ist da IRC Socket?
sock.connect ((net, port)) # Open server connection
irc.recv (4096) # Buffer setup
irc.send('nick ' + nick + '\r\n') # What is your name?
irc.send('USER AffixBot AffixBot AffixBot :Affix IRC\r\n') #Send User Info to the server
irc.send('JOIN ' + chan + '\r\n') # Join the pre defined channel
irc.send('PRIVMSG ' + chan + ' :Hello.\r\n') #Send a Message to the channel
while True: #While Connection is Active
data = irc.recv (4096) #Make Data the Receive Buffer
if data.find('PING') != -1: # If PING
irc.send('PONG ' + data.split()[1] + '\r\n') # Then PONG
Line 11 is the problem - apparently, what I've got down as a string needs to be an integer. How can I go about this?
Change your definition of port to be an integer.
port = 6667
not
port = '6667'
In general, if you have an existing string value that needs to be an int for a specific call, you can cast by calling int(str), which will return the value of str as an integer or raise a ValueError if it can't cast.

Python - Migrating program from Linux to Windows, in Windows it doesn't work

This has been bugging me for a few days now. I'm trying to migrate my utility, LScreamer, to Windows 7, yet it doesn't seem to be cooperating.
This utility transmits a Atmega firmware file to the bootloader running in the atmega. In Linux when I run this utility, it is able to send the entire file with only a handful of retransmits necessary. In Windows, almost every other transmit is a retransmit, and most of the times it results in the processor not getting the complete firmware.
My understanding of python and pyserial is that they should be portable between OS's. But since I am pretty inexperienced in using Python, perhaps I'm doing something strange.
Is there any observable errors in the LScreamer utility attached below? Thanks for your help!
#! /usr/bin/env python
""" This program is a port of Screamer V2.0 produced on Sparkfun.com which is
useful for wirelessly downloading code to an arduino.
The problem with the original code was that it was written for Windows,
whereas there may be many Linux users that would like to use the program.
Currently this port only supports ATmega168 and ATmega1280, but it has
been written to easily add more processors. Questions and contributions
can be submitted back to the developer at dustin.robotics#gmail.com
This has been updated to work on Windows as well, but it will still be
called LScreamer.
Here is the sparkfun page: http://www.sparkfun.com/tutorials/122#Step2
Usage: python LScreamer.py [options] [input file]
Options:
-h, --help show this help
-v, --verbose show additional information
-p Processor,
available arguments 'ATMEGA168', 'ATMEGA328' or 'ATMEGA1280'
default: ATMEGA168
-i, --interface Specify serial interface to broadcast
firmware file over, default /dev/ttyUSB0
Examples:
LScreamer.py -p ATMEGA168 -v -i /dev/ttyUSB0 ~/file.hex
Wirelessly downloads file.hex to an ATMEGA168 processor
LScreamer.py -p ATMEGA328 -v -i COM1 C:/Project/file.hex
Wirelessly downloads file.hex to an ATMEGA328 processor
LScreamer.py
Lists this information as well as the available ports on the system.
This could be ran before inserting serial device, and after, to
determine which port it has been connected to.
"""
import serial
import glob
import sys
import getopt
import platform
from time import sleep
def scan():
"""scan for available ports. return a list of device names."""
if is_windows:
# scan for available ports. return a list of tuples (num, name)
available = []
for i in range(256):
try:
s = serial.Serial(i)
available.append( (i, s.portstr))
s.close()
except serial.SerialException:
pass
return available
else:
return glob.glob('/dev/ttyS*') + glob.glob('/dev/ttyUSB*')
def usage():
print __doc__
class FileProc:
"File processing utilities"
def __init__(self, fileloc):
"""Main processing occurs within the FileProc class"""
#define global variables modified in this def
self.setArc()
pfile = self.parse(fileloc)
if _parsed_file == 0:
print "Problem parsing hex file, please check file again"
sys.exit()
#file parsed successfully, initiate remote reset
print "Waiting for target IC to boot into bootloader"
if _verbose == 1: print "Open port " + _iface + ' with baud rate = 19200, 8 data bits, 1 stop bit, 1 sign bit with a 1 second timeout'
ser = serial.Serial(_iface, 19200, timeout=1)
#toggle RTS line to restart remote device
ser.setRTS(1) #set RTS
ser.setRTS(0) #Clear RTS
ser.setRTS(1) #set RTS
ser.setRTS(0) #Clear RTS
#sleep(1) #wait for 1 seconds with RTS set
print " To quit waiting, do Cnrl + C"
if _verbose == 1:
print " If target IC does not boot into bootloader and start outputting a 5, not '5', then the target should be checked"
while ser.read(1) != '\x05':
pass
#target is in bootloader, send 6, not '6', to start firmware transmission
ser.write('\x06')
print "Target has successfully booted into bootloader, starting transmission of firmware"
current_memory_address = 0
while current_memory_address < _lastmem:
#wait until target IC sends confirmation
while (ser.inWaiting() == 0):
pass
target_status = ser.read()
if target_status == 'T':
#everything working correctly
pass
elif target_status == '\x07':
#need to resend line
print "resending last line"
current_memory_address -= _pagesize
else:
print target_status
print "incorrect response from target IC, will now exit"
sys.exit()
#show progress in terminal
print str(current_memory_address) + " of " + str(_lastmem)
#start processing hex file for output
#convert 16 bit current_memory_address into two 8-bit characters
memory_address_high = current_memory_address / 256
memory_address_low = current_memory_address % 256
#calculate checksum of this line
checksum = 0
checksum = checksum + _pagesize
checksum += memory_address_high
checksum += memory_address_low
for x in range(_pagesize):
checksum += pfile[current_memory_address + x]
#reduce checksum so that it is only 8 bits
while checksum > 256:
checksum -= 256
#take two's compliment of checksum
checksum = 256 - checksum
#start sending current line to target ic
#start character
ser.write(":")
#record length
if _pagesize < 256:
ser.write(chr(_pagesize))
else: #split up into high and low byte
ser.write(chr(_pagesize >> 8))
ser.write(chr(_pagesize % 256))
#send this block's address
ser.write(chr(memory_address_low))
ser.write(chr(memory_address_high))
#send this blocks checksum
ser.write(chr(checksum))
#now send the block
for x in range(_pagesize):
ser.write(chr(pfile[current_memory_address + x]))
#update current memory address
current_memory_address += _pagesize
#we have completed transmitting, tell target ic. Multiple S's for redundancy
ser.write(":")
ser.write("S")
ser.write("S")
ser.write("S")
ftemp.write(":SSS")
ftemp.close()
#tell user that transmission completed successfully
print "LScreamer has successfully sent " + str(_lastmem) + " bytes to the target " + _type
#close serial port
ser.close()
#exit gracefully
def setArc(self):
global _memsize
global _pagesize
global _parsed_file
global _maxsize
global _lastmem
global _type
_parsed_file = 0
if _type == 'ATMEGA168':
_memsize = 16384
_pagesize = 128 #words
_maxsize = _memsize - 1
elif _type == 'ATMEGA1280':
_memsize = 131072
_pagesize = 256 #words
_maxsize = _memsize - 1
elif _type == 'ATMEGA328':
_memsize = 32768
_pagesize = 128 #words
_maxsize = _memsize - 1
def parse(self, fileloc):
"""remove formatting and checksums, sort into rows of 128 bytes"""
#define global variables modified in this def
global _lastmem
global _parsed_file
try:
fhex = open(fileloc,"r")
except IOError:
print "File could not be opened"
sys.exit()
"""file is open, enter loop reading in hex lines"""
li=[] #initialize list, so can start adding elements by extending it
if _verbose == 1: print "reading input file '" + fileloc + "' now."
while 1:
lines = fhex.readlines(100000)
if not lines:
break
for line in lines:
#remove colon and new line
if(line[0]!=':'): #if line has no : then ignore
continue
s = line.split(":")
s = s[1].split("\r\n")
if(s[7:9]=='04'):
continue
if(len(s[0])!=0): #remove empty lines
li.extend([s[0]])
#Hex file is cleaned up now, stored in list li
#prefill hex_array with 0xFF
hex_array=[]
hex_array = [255 for i in range(_memsize)]
if _verbose == 1: print " processing hex file..."
#step through cleaned file and load into hex array
for line in li:
record_length = int(line[0:2], 16) # int('A',16) returns 10
#find memory address to store this line
memory_address_high = int(line[2:4], 16)
memory_address_low = int(line[4:6], 16)
memory_address = memory_address_high * 256 + memory_address_low
#check for end of file tag
if int(line[6:8], 16) == 1:
break
#save last memory location
_lastmem = memory_address + record_length
for x in range(record_length): #Save values to
lower_byte = 8+x*2
upper_byte = 10+x*2
#print "lower %d upper %d x %d" % (lower_byte, upper_byte, x)
hex_array[memory_address + x]= int(line[lower_byte:upper_byte], 16)
#print "int(line[lb:ub},16 = %d" % (int(line[lower_byte:upper_byte], 16))
#print hex_array
#sleep(1)
#file was successfully parsed
fhex.close()
_parsed_file = 1
return hex_array
def main(argv):
#determine OS
global is_windows
is_windows = (platform.system().lower().find("win") > -1)
try:
#To test this in python, do args = '-hvp ATMEGA168 /home/test'.split()
#then do getopt.getopt(argv, "hvp:", ["help", "--verbose"])
opts, args = getopt.getopt(argv, 'hvp:i:', ['help', 'verbose', 'interface'])
#detect if no inputs are given
if len(args) == 0:
usage()
print "\nThe available interfaces are: " + str(scan()) + "\n"
sys.exit(2)
except getopt.GetoptError:
usage()
sys.exit(2)
#setup global variables
global _verbose ; _verbose = 0
global _iface ; _iface = '/dev/ttyUSB0'
global _type ; _type = 'ATMEGA168'
for opt, arg in opts:
if opt in ("-h", "--help"):
usage()
sys.exit()
if opt in ('-v', '--verbose'):
_verbose = 1
if opt in ('-p'):
_type = arg
if opt in ('-i', '--interface'):
_iface = arg
hex = "".join(args)
FileProc(hex)
if __name__=='__main__':
main(sys.argv[1:])
"""
* 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 3 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, see <http://www.gnu.org/licenses/>. *"""
I hooked up a MAX3232 and discovered that the XBee is dropping packets, so I am going to investigate into getting a better driver for it. When the MCU is connected to the computer via a Serial cable, the program downloads fine. So it seems to be an xbee, not a python issue. Thanks for your help!
You could try opening the hex file with universal newline support:
fhex = open(fileloc, "rU")
Also, your checksum is wrong. It should be:
while checksum >= 256:
checksum -= 256
#take two's complement of checksum
checksum = 255 - checksum
Additionally, instead of:
hex_array = [255 for i in range(_memsize)]
you could use:
hex_array = [255] * _memsize
and put sleeps in the busy waits:
while ser.read(1) != '\x05':
time.sleep(0.1)

Categories