Turn off specific USB port in windows with python - python

This is my first post, and I kind of have seen that the more specific the better, so I'll try to be super clear, and thanks in advance!
What I want:
I need to scan images from 2 or more scanners at the same time, these scanners are from the same brand and model, in this case Epson Perfection V600, I need different time intervals for at least 40 captures over a course of 20 hours.
My approach
I decided to use Windows, I already have a program in Python that does what I want with just one scanner, or with two from different models. But here is where you guys come in:
The problem
Windows always prints with the same scanner, Since they are from the same brand and model it always uses the same one, and I cannot use two different scanners because that will cause the images not to be comparable. Nevertheless, when I use two different scanners, I don't have such problem. I need to find a way to print with each scanner. I thought in buying a USB hub and control it with python as well, but apparently given libsub implementation in windows, I will not be able to control it. So I'm currently Looking for a way to disable an specific USB port so the program will only recognize one device, scan with it, disable that one, re-enable the other one, and so on.
What I have access to:
Right now I'm using Windows 10, 64 bits, python kernel 3 in a python 3.5 version inside a Conda environment, conda version (4.5.11).
Ubuntu 16.04, 64 bits, with pyinsane working, in a python 3.5 environment inside conda (don't have the conda version at hand).
One Epson perfection V600.
Two Canon Lide200, working only in windows, because drivers are not available in Ubuntu.
What I have also tried
Using Ubuntu,
I thought it was a good Idea, but the Epson drivers webpage fails to connect to the repository containing the rest of the Epson files, letting me only partially download the files, I already tried to contact the owner of the Docky repository, but he fails to contact me.
The error:
W: The repository 'http://ppa.launchpad.net/docky-core/ppa/ubuntu Xenial Release' does not have a Release file.
N: Data from such a repository can't be authenticated and is therefore potentially dangerous to use.
N: See apt-secure(8) manpage for repository creation and user configuration details.
E: Failed to fetch http://ppa.launchpad.net/docky-core/ppa/ubuntu/dists/xenial/main/binary-amd64/Packages 404 Not Found
E: Some index files failed to download. They have been ignored, or old ones used instead.
when I manually try to enter the site's repository I found that
All links to XENIAL drivers are down, actually the whole Xenial
Folder is missing.
Also then thought it was a good idea to ignore this message, but I
Need the Epwoka driver to run Epson scanners in Ubuntu, and that
a whole problem by itself. Aside from that, is not known if Epson
Perfection V600 is going to be possible to be controlled by the
PyInsane lib, since is marked as untested.
Using Windows
I thought in buying an USB hub and to controlled as shown in this thread, but apparently is not possible in windows.
I already installed libsub, usb.util, libusb1,USB (for the core functions) and usb1, but I don't know (I think is not possible) to disable and re-enable a specific USB port with them.
Can't disable the drivers since that mean all USB will be down to connect with the scanners.
Device manager is not helping, because of the inability of telling which device is which.
Cannot change the name of the scanner (yes, printers can have specific names) but scanners can't.
Can't buy another scanner, I'm stuck with Epson.
My code for Scanning
import pyinsane2
def Scan(Device, dpi):
pyinsane2.init()
try:
pyinsane2.set_scanner_opt(Device, 'resolution', [dpi])
pyinsane2.set_scanner_opt(Device, 'mode', ['Color'])
pyinsane2.maximize_scan_area(Device)
scan_session = Device.scan(multiple=False)
try:
while True:
scan_session.scan.read()
except EOFError:
pass
Image = scan_session.images[-1]
finally:
pyinsane2.exit()
return(Image)
devices = pyinsane2.get_devices()
image_a = Scan(devices[0], 75)
image_b = Scan(devices[1], 75)
a = devices[1]
b = devices[0]
a == b #Different
a.dev_type == b.dev_type
a.model == b.model
a.name == b.name #Different
a.nice_name == b.nice_name
a.options == b.options
a.reload_options == b.reload_options #Different
a.scan == b.scan #Different
a.srcs == b.srcs #Different
a.vendor == b.vendor
I put a sticki note inside each Scanner, one with an "a" the other one with a "b" and it always scans with the scanner that I plugged in first
This is what I would like to do (and doing it manually works): .
This is what I get when trying in python:
Any solution will help me, get creative! I was thinking on using a .bat file to disable an specific port and calling it with Python. But I couldn't find a way to make it.Keep in mind that doing it manually is not an option 'cause of the 20 to 40 hours of continuous image acquisition.
Thanks!
~Diego

Related

Barcode scanners (Netum Scan) in python

I'm writing code which takes input from several barcode scanners, and I want a way to differentiate between each scanner. I'm on windows 10, and my python version is 3.11.1. And as the title suggests, I'm using scanners from a company called Netum.
I've tried using them as HID devices, but this seems incredibly slow and impractical. If the computer sees them each as keyboards, I have to validate each individual keystroke, rather than entire barcodes. So I've abandoned this approach under that assumption.
I discovered these scanners have what's called "USB COM Port Emulation," and that seems promising. It almost never works, but when it does, it just shoves an entire barcode into my code as a string. The problem is that, most of the time, when it's in this mode, it disconnects the USB dongle the instant I scan anything. But it makes a reference to "needing drivers" for this mode. I checked the device manager, which tells me all my drivers are totally up-to-date. This is really the crux of the problem, as my code works if this mode works reliably.
Also, I'm using PySerial to decode the inputs from the scanners. I dunno if that matters, but I figured I'd mention it. The following is the code I'm using to talk to these janky scanners, and it only works when the scanners don't disconnect from my PC for seemingly no reason.
import serial
scanner = serial.Serial(port='COM3', baudrate=9600, bytesize=8, timeout=1, stopbits=serial.STOPBITS_ONE)
string = scanner.read()
print(string.decode())
scanner.close()
If anyone has any advice, insights, or even just general directions to point me in, it would be appreciated. I'm at the point where I don't even know how to begin solving this.
Comment to answer
Have you installed any Virtual Com Port (VCP) drivers such as from FTDI? ftdichip.com/drivers/vcp-drivers They do a executable for easy install - this may help with your stability issues

usb automatic detection in python for linux env

I'm using polling command(glob('/dev/tty[A-Za-z]*')) in python to detect usb devices connected to my linux pc in regular interval for my application. Is there any way to detect usb devices connected automatically?
Here is a start. You can find your usb vendor here. You got to code yourself a current_list_usb, set a time interval to check so you can compare and see if a new device is attached or not. Some code to use when importing usb module:
import usb, usb.core, usb.util, usb.backend.libusb1
...snippet...
# usb.core.find()
# find our device
dev = usb.core.find(idVendor= ...., idProduct= ....)
#dev_1 = usb.util.find_descriptor(cfg, find_all =True)
# was it found?
if dev is None:
raise ValueError('Device not found')
#x = dev.set_configuration()
#print (dev)
#print (help(usb.core))
if usb.core.find(find_all=True, bDeviceClass=7) is None:
raise ValueError('No printer found')
The normal way to do this is to make a udev rule that tells your program a new tty exists.
A custom udev rule may look something like this(let's call it /etc/udev/rules.d/50-custom-tty.rules:
KERNEL=="ttyUSB[0-9]+", RUN+="/usr/bin/my-program"
Here's a good guide on writing udev rules.
In this case, the program /usr/bin/my-program will run whenever a new ttyUSB device is created in /dev; udev will set a bunch of environment variables to tell you exactly what was just plugged in. You can then notify your main program that a new ttyUSB exists, and it should use it. Note that whatever program you run should be small, as otherwise the udev daemon will kill it if it takes too long.
I'd suggest using libudev and creating a udev monitor object to detect hotplugged devices. Here is a starting point for you to learn about libudev and its monitor feature:
https://www.freedesktop.org/software/systemd/man/libudev.html
There might be a good Python library already that wraps udev so you can use its features without writing C code.

PsychoPy sending triggers on 64bit OS

I have a problem with sending triggers for eeg recording using PsychoPy standalone v1.81.00 on a Win7 64bit OS. I followed the descriptions here and don't get any (more) errors. The triggers, however, don't show on the recording computer (Brainvision Recorder under Win7 32bit).
What I did:
Downloaded and installed the InpOutBinaries_1500 via InpOutBinaries_1500\Win32\InstallDriver.exe
Copied the other files (inpout32.dll, .h and .lib as well as vssver2.scc) to the working directory of my script
Tried sending trigger codes with windll.inpout32.Out32(0x378, triggerCode)
The trigger code doesn't show up in Brainvision Recorder but seems to be set correctly when calling print str(windll.inpout32.Inp32(0x378)).
Thanks for every piece of advice or idea!
I managed to solve the problem. I'm not entirely sure which step(s) actually cut the curve but I recommend the following:
Download and install LPT Test Utility on your presentation computer.
At first, this program installs the inpout32.dll automatically and correctly regardless if you use a 32 or 64 bit OS.
More over, it helps you to monitor and manipulate the pins of your parallel port. If using the standard addresses (LPT1 through LPT3) doesn't work, select LPTX and enter your address manually (see here where to get your parallel port address on a Windows PC). If the triggers don't show on your recording computer using this program, you have an issue that is not related to PsychoPy.
If this fails, (re-)install a parallel port driver. Using Windows 7 this should not be necessary but actually solved one major issue for me. If this still fails, probably the hardware components (parallel port plug / card, cable(s), sync box) are damaged.
If the triggers work with the "LPT Test Utility" program but not using PsychoPy, an individual troubleshooting dependent on your code is necessary. Of course, you need to insert the port address that worked with "LPT Test Utility" in your PsychoPy code.
from psychopy import core
from ctypes import windll
windll.inpout32.Out32(portaddress, triggerCode) #sends the trigger with triggerCode being an integer between 0 and 255
core.wait(0.05) #wait 50ms
windll.inpout32.Out32(portaddress, 0) #deletes the trigger i.e. resets the pins
Best wishes,
Mario

How to Refresh Network Drive Mappings in Python

I have a drive already mapped to a designated letter, 'R:\'. If I run the python script to access this space while logged on or with the computer unlocked it works fine. The problem occurs when I set task scheduler to run the script early in the morning before I come in. Basically I stay logged in and lock the machine, but at some point it looks like my network drive mappings time out (but reconnect when I unlock the machine in the morning) and this is why the script isn't able to find them.
The error comes when trying to do an os.path.exists() to check for folders on this drive and create them if they don't already exist. From a 'try/except' loop I get the exception "The system cannot find the path specified: 'R:\'.
My question: is there a way to force a refresh through python? I have seen other postings about mapping network drives...but not sure if this applies to my case since I already have the drive mapped. The letter it uses needs to stay the same as different applications have absolute references to it. Wondering if mapping the same drive will cause problems or not work, but also not wanting to temporarily map to another letter with a script and unmap when done...seems like an inefficient way to do this?
Using python 2.6 (what another program requires).
Thanks,
The best solution would be to refer to the 'drive' by its UNC pathname, i.e. a path of the form \\hostname\sharename, but, unfortunately, Python's base library has very poor support for dealing with UNC paths.
Option #1 would be to find a Python extension module you can install to get better support for UNC paths. Try googling for "python unc".
Option #2 would be to use the Python subprocess module to execute net use commands, and parse the resulting output. e.g. from a DOS prompt, running net use will output something like this...
Status Local Remote Network
-------------------------------------------------------------------------------
OK R: \\hostname\sharename Microsoft Windows Network
...which you can use to tell if the drive is already mapped, and if not, you can just execute net use R: \\hostname\sharename to map it. It's possible that calling net use with no paramaters is actually sufficient to 'refresh' the mapping if it has 'timed out', but I'm not sure.
Option #3 would be to investigate using the Python ctypes module to call the underlying Windows libraries directly to emulate the functionality of calling net use.
My solution to this problem was to just use the IP address for the referenced machine. Worked like a charm and no problems with mapped drives...thanks for the responses.

How to use FDTI chip in VCP mode?

I'm trying to get a SainSmart USB relay board based on the FT245RL chip working and having a terrible time. I was under the impression that I could control the relays from the command line with something like:
echo -e -n "\xFF\x1\x1" > /dev/ttyUSB1
While the device is mounted automatically and I think I've got the baud rate and permissions set up, nothing happens on my Debian squeeze or CentOS 5 machines. SainSmart's support is worthless.
I decided to try on windows, so I installed the drivers and wrote a small program in python:
import serial
ser = serial.Serial(2) #COM3
ser.write(chr(255) + chr(0) + chr(1))
ser.close
Still nothing. Perhaps it's a hardware problem so I install a provided windows program. It sees the device and works when I click on the relay buttons. Discouraged, I exit their program, look for bugs in mine (can't find any) but try it anyways, and it works! I write a much bigger program to do all sorts of cool things and cool things happen until I unplug the device. When I plug it back in, nothing works. I've got to run and exit the relay control program before my code will do anything.
I suspect that I've got to do something with d2xx drivers like FT_SetBitMode(). Is there any way to just use VCP mode? PyUSB won't install on my computer and isn't available for Linux.
All I want is a simple way to control a relay on Linux using python.
I had the same problem, I think you were right about FT_SetBitMode(). Eventually I got it to work by using ftd2xx (which you can get by pip). You will also need to install the D2XX drivers.
import ftd2xx
if ftd2xx.listDevices() < 1:
print "No relays found. Exiting..."
exit()
else: print "Initializing relays..."
relays = ftd2xx.open(0)
relays.setBitMode(255,1) # I think this uses FT_SetBitMode()
relays.write(b'\01\01') # relay one on
relays.write(b'\01\01') # relay two on
relays.write(b'\00\00') # all relays off
relays.close()
I would first suggest you to try out hyperterminal first.
From your code snippet it seems that you are missing the baudrate (assuming the rest are going to be the default values). And I don't really know if it matters but I always explicitly set the port as Serial('COM3'), one less possible point of failure this way :)
Probably you don't have a problem with Python, but with controlling the device as such.
You should try to find out if the the device has special requirements about the state of the control lines (DST, DTR etc.).
And, not to forget, the communication speed which Alex already mentions.
Using virtual com ports on Windows I found I had to use 115k baud

Categories