Use Teensy with USB Hub and USB flash drive

Status
Not open for further replies.
Hello,

I recently asked a question on a project, where I would need the following setup:

A teensy, a USB Hub and a USB flash drive. The teensy and the flash drive would go into the hub and the hub is plugged in into the pc.

Then, the teensy should be able to open a file on the flash drive, and with open I mean using keypresses, so something like:

Windows + R
cmd
j:/testfile.bat


This generally works, I'm able to program the Teensy to open the file, but the problem is: The flash drive (ofcourse) not always has the same drive letter.

One approach I already got:

Just keep trying D:\myexefile.exe ; E:\myexefile.exe ; F:\myexefile.exe ; etc. Once your executable is running it can easily determine its location if needed.

But: How can I actually notice, that the exe (or in my first try the testfile.bat) is running, before I keep trying and trying?


Are there any other ideas, how I could figure out the drive letter of the flash drive? Is there maybe something like a "last plugged in devices-log" where I can ust use the last drive letter?
 
Another approach would be to enumerate the drives by bus type. This can narrow the search down to whatever USB drives are connected, then further reduce this by drive/volume name, size and/or contents.
 
Another approach would be to enumerate the drives by bus type. This can narrow the search down to whatever USB drives are connected, then further reduce this by drive/volume name, size and/or contents.

How could I do this? Infact, I could exclude devices like CD-ROM, the harddrives, etc, and it also would be always the same usb flash drive.

But how can I determine if it is a usb flash drive and not a harddrive? Or is there a way to to do something like:
Code:
if(file_exists(A:/testfile.bat){
do something;
}else if(file_exists(B:/testfile.bat){
do something
}

etc..?

Also, it would be no problem (talking about drive name) to give the flash drive a specific name which would always be the same and access it with that name, but how would this work?
 
Retrieve drive bus type via: (Works for me on Windows7)
Code:
static int getDriveBusType (const int drive)
{
	wchar_t buffer[128];
	__mingw_snwprintf(buffer, 127, L"\\\\.\\%lc:", (wchar_t)(drive&0xFF));
	
	HANDLE deviceHandle = CreateFileW(
    	buffer,
		0,                // no access to the drive
		FILE_SHARE_READ | FILE_SHARE_WRITE,  // share mode
		NULL,             // default security attributes
		OPEN_EXISTING,    // disposition
		0,                // file attributes
		NULL);            // do not copy file attributes

	if (deviceHandle == INVALID_HANDLE_VALUE) return BusTypeUnknown;

	// setup query
	STORAGE_PROPERTY_QUERY query;
	memset(&query, 0, sizeof(query));
	query.PropertyId = StorageDeviceProperty;
	query.QueryType = PropertyStandardQuery;

	// issue query
	STORAGE_DEVICE_DESCRIPTOR devd;

	DWORD bytes;
	STORAGE_BUS_TYPE busType = BusTypeUnknown;


	if (DeviceIoControl(deviceHandle, IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof(query), &devd, sizeof(devd), &bytes, NULL))
		busType = devd.BusType;

	CloseHandle(deviceHandle);

	//printf("bustype: %c: %i %X\n", drive&0xFF, devd.RemovableMedia, devd.BusType);

	return busType;
}

int isUsbDrive (const char drive)
{
	return getDriveBusType(drive) == BusTypeUsb;
}


And to retrieve drive name or other details:
Code:
char *getVolumeLabel (const int drive)
{
	size_t blen = MAX_PATH;
	wchar_t buffer[blen+1];
	 
	wchar_t driveW[] = {drive&0xFF, ':', '\\', 0};
	if (GetVolumeInformationW(driveW, buffer, blen, 0, 0, 0, 0, 0))
		return convertto8(buffer);
	else
		return NULL;
}
 
Last edited:
@Paul it is, its for my work, to automize some programs so there is no need to send "well educated people" that know, bho to start a batch file , but only the Hub/Teensy/Flash Drive combination which does everything on its own.
 
But: How can I actually notice, that the exe (or in my first try the testfile.bat) is running, before I keep trying and trying?

Do you have to notice? I know it's sloppy, but those extra commands aren't going to do any harm. Unless your program needs input, of course, but then you could add a little logic to ignore those specific lines.

@MichaelMC: This is about feeding keyboard input to a PC. You cannot call the Windows API from the Windows command line.
 
Do you have to notice? I know it's sloppy, but those extra commands aren't going to do any harm. Unless your program needs input, of course, but then you could add a little logic to ignore those specific lines.

@MichaelMC: This is about feeding keyboard input to a PC. You cannot call the Windows API from the Windows command line.

Exactly the second thing is the case, I need a little input, too. Need to once enter a password and then press "n" two times, so I would need to to this all the time as well, which wouldn't make too much sense I think, so what kind of logic do you mean?

And yes, somehow the commands from MichaelMC were not working in command line.
 
Last edited:
I was assuming that you are building the program that's being run as well, and that you'd be able to change it.

You could use redirection to feed the input to the program:

myprogram.exe <input.txt

input.txt contains:
thepassword
N
N
 
Not in that kind of way, no...

And yes, but you mean that I would do like:

A:/myprogram.exe < input.txt
B:/myprogram.exe < input.txt
C:/myprogram.exe < input.txt
D:/myprogram.exe < input.txt

and so on, and just don't care, if it would already be A (even if that is really unlikely)?
 
Pretty much. The input.txt would be on the same disk as the program, so you'd need to specify the drive letter there as well:

D:\myprogram.exe <D:\input.txt
 
Pretty much. The input.txt would be on the same disk as the program, so you'd need to specify the drive letter there as well:

D:\myprogram.exe <D:\input.txt

Even though I didn't try the input yet, the thing with using every letter in general seems to work (I used a for-loop, started at 97 and added the index of the iteration variable to get a-z).

But: Is there maybe at least any way to cancel the process of trying after the program was succesfully executed?

I'll try the input thing now.
 
It seems Teensy can set and monitor the NumLocks state. If the app when it runs toggles it at start that would say it started - and you could stop or go form there.
 
It seems Teensy can set and monitor the NumLocks state. If the app when it runs toggles it at start that would say it started - and you could stop or go form there.

Even though that this is a very interesting idea, it won't work I think.. As I can't change the code of the program executed, how can I toggle the NumLock when it successfully started?
 
In order to do this:

It seems Teensy can set and monitor the NumLocks state. If the app when it runs toggles it at start that would say it started - and you could stop or go form there.
 
I'd just assume that if the second program (lets call it test.exe) runs that the first (myexefile.exe) runs as well.

If you really want to check if myexefile.exe runs you can implement code in test.exe which uses the standard windows functions to verify if the process runs. Google for "windows check if process is running". If text.exe finds that myexefile.exe runs it reports back to the Teensy by setting NumLock or sending a serial string or whatever...
 
Okay, yes thats an idea, so in the second program, I check if the process with PID whatever (from the first program) is existing/if the first program is running, and if its running, it would somehow report it to the teensy? So far so good, but how could the program then communicate with the Teensy? Or is it possible to read the PID's directly from Teensy?
 
Just send a string via the com port to the Teensy. And, before you ask: google for "language send string via com port, replace "language" with your favorite programming language
 
Status
Not open for further replies.
Back
Top