This software download is for our USB Host Boards and chips. It allows you to connect a USB Flash Memory Stick to the Host Board and read/write files via a serial TTL interface or I2C. Ideal for data logging applications.
This is a free software download for our USB Host Board and USB Host IC’s (SOIC, DIP, SSOP).
Please note: This software is free to download but only works on one of our USB boards or chips which must be bought separately.
To order, simply select which of our boards or IC products you wish to have the software loaded onto. See the USB Host Board and IC product pages for details onĀ pricingĀ and installing this software.
Features
- Supports both the FAT16 and FAT32 file systems so can access large capacity memory sticks.
- Does not support Long File Names
- Serial TTL interface
- Basic I2C interface
Serial TTL Interface
The flash drive can be accessed via a PC Terminal Program (serial TTL connection required) or directly from a Microcontroller using standard TTL Serial at the following baud rates
- 2400
- 4800
- 9600
- 14400
- 19200
- 38400
- 57600
- 115200
The following Commands are available.
All commands should be terminated with a carriage return character (ascii 13 or 0x0D)
<parameter> | Required parameter (don’t enter the brackets) E.g. WRITE TEST.TXT |
[option] | Optional parameter (don’t enter the brackets) E.g. WRITE TEST.TXT B |
COMMAND | |
WRITE <file> [B] | Create [file] from input. Type input (or send from microcontroller). Terminate data entry with Control-Z Optional [B] Binary Mode (see below) |
APPEND <file> [B] | Append input to end of existing file. Type input (or send from microcontroller). Terminate data entry with Control-Z Optional [B] Binary Mode (see below) |
TYPE <file> | Print contents of file, current dir only |
READ <file> [LINENO] | Print a single line of file, current dir only. Useful for reading a configuration file. [LINENO] can be a number or the character ‘n’ Use the character ‘n’ to select the next line Example READ test.txt 1 This would read the first 3 lines of file test.txt |
READ <file> [START] [LEN] | Print a section of a file, current dir only. Useful when reading in a complete file, but splitting it into smaller chunks. [START] is the start byte from the beginning of the file (starting at 0). It can also be the character ‘n’ which starts from the last read position. [LEN] is the number of bytes to read Example 1 READ test.txt 0 20 Example 2 READ test.txt 0 20 |
COPY <file1> <file2> | Copy [file1] to [file2] |
DEL <file> | Delete file, current dir only |
REN <file1> <file2> | Rename [file1] to [file2] |
SIZE <file> [BYTE|LINE] | Return size of [file] in bytes or number of lines. The number of lines is useful when reading a configuration file. |
DIR [/F] <filename> | Display list of files matching filename. Filename can be left blank to display all files E.g. DIR *.TXT 2007-08-15 04:23:46 525 M1.TXT 2 007-08-15 04:22:32 651 M2.TXT The /F flag can be used to force only the filename to be printed E.g. DIR /F *.TXT M1.TXT M2.TXTR |
CD <name> | Change directory |
MD <name> | Make directory |
RD <name> | Remove directory |
DATE [yyyy-mm-dd] | Display or set the date |
TIME [hh:mm:ss] | Display or set the time (24 hr format) |
BAUD <value> | Set Serial Port Baud Rate (default 9600) [2400|4800|9600|14400|19200|38400|57600|115200] |
HELP or ? | Display help |
WHO | Display the VID and PID of the attached device. This is useful if you only want to read/write to a specific flash drive. |
The follwing screen capture is the output from the HELP (?) command in terminal mode (see below)
Hobbytronics Flash Drive Explorer v1.17
WRITE <file> [B] - create [file] from input (B-Binary mode)
APPEND <file> [B] - append input to file (B-Binary mode)
TYPE <file> - print contents of file, current dir only
READ <file> [LINENO|n] - print single line of file, current dir only
READ <file> [ST] [LEN] - print bytes of file, from byte [ST] length [LEN]
COPY <file1> <file2> - copy [file1] to [file2]
DEL <file> - delete file, current dir only
REN <file1> <file2> - rename [file1] to [file2]
SIZE <file> [BYTE|LINE] - Return size of [file] in bytes or num lines
DIR [/F] <name> - display directory/files
CD <name> - change directory
MD <name> - make directory
RD <name> - remove directory
DATE [yyyy-mm-dd] - display or set the date
TIME [hh:mm:ss] - display or set the time (24 hr format)
BAUD <value> - Set Serial Port Baud Rate
[2400|4800|9600|14400|19200|38400|57600|115200]
I2C <value> - Set I2C Address
(41 ) [1 - 127]
HELP or ? - display help
WHO - display the VID and PID of the attached device
Connections required for Flash Drive
- 5V power in
- 0V
- TX out
- RX in
- SS pin goes high when Flash drive inserted, low when removed
Real Time Clock
The USB Host Board has a real time clock on-board. When you have set the date and time the real time clock will keep track of the correct date and time. Files created will have the correct time and date stamp. The time and date can also be read in to your controller and then used in your output string.
The Real Time Clock is maintained by the main crystal oscillator and not by a dedicated watch crystal. It should be accurate to within a few seconds per day.
There is no battery backup for the clock. If you remove power to the Host board the clock will lose its settings.
Binary File Write Mode
In the default mode for writing to a file, we assume the file is text based and the file is closed by sending the Control-Z character.
In the optional Binary mode (V1.10+), any character can be sent and will be written to the file, including the Control-Z character; so we need a different method of closing the file write. This is done using the unused SDO (A) pin on the board.
This pin is HIGH by default and should be briefly pulled LOW to terminate the file write.
Note: You can use the [B]inary method for normal text files as well as binary files.
Modes of Operation
There are two modes of operation for issuing commands and receiving responses
- Terminal Mode. Type as you would on your computer. All instructions and results are echoed back. This mode is best used when connected via a serial connection to a computer.
- Silent Mode. Designed for microcontroller applications. Silent mode is enabled by prefixing any command with a $ symbol. The command will not be echoed back, only the results (if any) returned
Silent mode is best explained with an example. Here we have an arduino sketch which sets the date and time and then writes to a file, all in silent mode. No data is echo’d back to the microcontroller.
/*
USB HOST BOARD - Flash Drive Example
Works with Arduino 1.0 and previous versions
Basic use of Flash Drive in Silent Mode.
Sets Date and Time and Creates a file ARDUINO.TXT
Writes and Appends data to the file, then closes file.
Prefix all commands with $ for silent mode
Uses SoftwareSerial so as not to interfere with the Serial port
Commands need a little time to be processed before the next command
is sent, so we create a little function "flash_data" to save us
having to do it each time
*/
int i;
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // RX, TX
// Create a printing function which has a built-in delay
void flash_data(char *pstring)
{
mySerial.println(pstring);
delay(50);
}
void setup()
{
delay(2000);
mySerial.begin(9600);
// Set the DATE and TIME
flash_data("$TIME 09:00:00");
flash_data("$DATE 2012-01-01");
// Create the file ARDUINO.TXT
flash_data("$WRITE ARDUINO.TXT");
delay(1000); // Needs extra time to create the file.
// Depends on flash drive used
// Write ten lines to the file
for(i=0;i<10;i++)
{
flash_data("This is a test file");
}
// Close the file by sending Control-Z (note the use of "print" not "println"
#if ARDUINO >= 100
mySerial.write(26); // 26 is Control-Z character
#else
mySerial.print(26,BYTE); // 26 is Control-Z character
#endif
delay(500); // Give time for the file to be saved and closed
// Now re-open file and append data to it
flash_data("$APPEND ARDUINO.TXT");
delay(1000);
// Write ten lines to the file
for(i=0;i<10;i++)
{
flash_data("Appended line to file.");
}
#if ARDUINO >= 100
mySerial.write(26); // 26 is Control-Z character
#else
mySerial.print(26,BYTE); // 26 is Control-Z character
#endif
}
void loop()
{
// Nothing to do here
}
Here is another example program. It reads the number of lines in a files, then reads each line in one at a time. It uses software serial to talk to the USB Host board so that the file data can been seen on the Arduino Serial Monitor. This is useful for reading in data files or config files.
/* USB Host - Flash Drive software
Demo Arduino sketch to show how to read number of lines in a file
and to individually read each line.
Useful for data or config files
Hobbytronics Ltd 2013 (www.hobbytronics.co.uk)
*/
#include <stdio.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // RX, TX
int file_lines, i;
byte serial_char;
char filename[] = "1.txt"; // File name
char mystring[40]; // String to hold commands to be sent
void setup() {
delay(2000);
Serial.begin(9600);
mySerial.begin(9600);
// Issue command to return number of lines in file
// Note: Use silent mode ($) as we don't want the command echo'ed back
sprintf(mystring,"$size %s line\r",filename);
mySerial.write(mystring);
while(!mySerial.available()); // Wait for data to be returned
// Number of lines in file returned as ascii chars, so convert to number
file_lines = 0;
while (mySerial.available() > 0) {
file_lines*=10;
file_lines+=mySerial.parseInt();
}
// Print filesize information
sprintf(mystring,"Lines in file = %d",file_lines);
Serial.println(mystring);
// Loop through each line
for(i=1;i<=file_lines;i++){
// Print line number we are reading
sprintf(mystring,"Line %d = ",i);
Serial.print(mystring);
// send command to read specific line
sprintf(mystring,"$read %s %d\r",filename,i);
mySerial.write(mystring);
while(!mySerial.available()); // Wait for data to be returned
// Read and display contents of line returned
while (mySerial.available() > 0) {
Serial.write(mySerial.read());
}
}
}
void loop(){
}
I2C Interface
We have added basic read/write functionality using the I2C interface. This is still a work in progress but if you need to use an I2C interface rather than a serial connection then this section is for you. We shall describe the functionality then show an example program to show how it all works in practice.
As with most I2C devices, there are a number of ‘registers’ or commands that can be sent
// I2C Register Addresses
#define I2C_FILENAME 0
#define I2C_WRITE 1
#define I2C_APPEND 2
#define I2C_READ 3
#define I2C_READ_SETLINE 4
#define I2C_FLASH_READY 99
So, starting with I2C_FILENAME; we use this to transmit the filename to be used in the read/write operations. This only needs to be done once, unless you want to change the filename or if you are writing to one file, but reading from another.
The I2C_WRITE and I2C_APPEND commands do what they suggest, I2C_WRITE overwrites the file with data, while I2C_APPEND appends to the end of the file.
Now, read operations are trickier. Because flash drives can take some time to read the data, we can’t simply request some data and expect it to be returned in a timely fashion suitable for I2C communication. So we have split reading into 2 operations. First we tell the flash drive what data we want; then we wait for the flash drive to read the data, then retrieve the data and store it in a buffer. When the data is fully received the data can be read from the buffer.
The I2C_READ function returns a specified line of data from the file. This is generally more useful than simply reading x amount of characters, especially if you are reading from a configuration file for example. Lines must be terminated with a carriage return.
So to read a line from a file, we first use the I2C_READ_SETLINE function to tell the host board which line number we want, it can then fetch the data, and when ready we use the I2C_READ function to read the data.
The I2C_FLASH_READY command is used to determine whether the flash drive is available for read/write operation and is not currently busy.
The example Arduino program below shows how data can be written to and read from a Flash drive using the I2C interface.
Please note that the Arduino code library “Wire” limits the amount of data that can be send/received in one go to 32 bytes. This is defined in Wire.h with the line
#define BUFFER_LENGTH 32
You can change this value to allow more data to be written or read.
/*
** Wire Master for Hobbytronics USB Host Flash Drive
** Created 16 Oct 2014
**
** This example code is in the public domain.
** www.hobbytronics.co.uk
*/
#include <Wire.h>
// I2C Register Addresses
#define I2C_FILENAME 0
#define I2C_WRITE 1
#define I2C_APPEND 2
#define I2C_READ 3
#define I2C_READ_SETLINE 4
#define I2C_FLASH_READY 99
const char flash_address=41; // I2C Address
void setup()
{
delay(2000);
Serial.begin(9600);
Wire.begin(); // join i2c bus (address optional for master)
flash_write(flash_address, I2C_FILENAME, "i2c.txt");
flash_write(flash_address, I2C_WRITE, "Test File\r\n"); // Overwrite file
}
void loop()
{
// In this loop we keep writing "Hello" to the file, and we read and print
// the first line which should be "Test File"
flash_write(flash_address, I2C_APPEND, "Hello\r\n"); // Append to file
flash_read_line(flash_address, 1); // read line 1 of the file
delay(5000); // Wait 5 seconds
}
// Check if flash drive is available (i.e. not currently reading/writing)
byte flash_ready(char host_address)
{
byte f_ready;
// This function reads one byte over I2C
Wire.beginTransmission(host_address);
Wire.write(I2C_FLASH_READY);
Wire.endTransmission(false); // restart
Wire.requestFrom(host_address, 1); // Request the data...
f_ready = Wire.read();
if(f_ready==0) delay(20); // A small delay before we try again
return f_ready;
}
void flash_write(char host_address, char h_command, char *pstring)
{
unsigned char i=0;
while(!flash_ready(host_address)); // Wait until Flash drive is ready
Wire.beginTransmission(host_address); // transmit to device
Wire.write((byte) h_command); // send command - WRITE or APPEND
do{
Wire.write((byte) pstring[i]);
i++;
} while(pstring[i]);
Wire.endTransmission();
}
void flash_read_line(char host_address, unsigned char line_num){
// Read in a line from flash drive
// This is a 2-stage process. First we tell the host board
// which line number we want, so it has time to fetch the data
// Next we request the data
unsigned char i=0;
while(!flash_ready(host_address)); // Wait until Flash drive is ready
Wire.beginTransmission(host_address); // transmit to device
Wire.write((byte) I2C_READ_SETLINE); // send SETLINE command
Wire.write((byte) line_num); // send line number
Wire.endTransmission();
// Wait until line is fetched from flash drive into buffer
while(!flash_ready(host_address)); // Wait until Flash drive is ready
Wire.beginTransmission(host_address); // transmit to device
Wire.write((byte) I2C_READ); // send READ command
Wire.endTransmission(false); // restart
Wire.requestFrom(host_address, 255); // request max 255 bytes from slave
// device (Arduino wont do this many)
while(Wire.available()) // slave may send less than requested
{
char c = Wire.read(); // receive a byte as character
if(c!='\0') Serial.print(c); // print the character
}
}