Maple Docs: USB
Changes and Caveats
The SerialUSB functionality was modified for the 0.0.6 IDE release. It now includes a 50 millisecond timeout for writes and does not try to detect if the USB host is "really" connected or just enumerated and initialized. This means that if you have a number of SerialUSB writes or prints in your code and you are not monitoring on a computer your program will run much, much slower than if it is being monitored or totally disconnected (battery).You can avoid this behavior by deciphering the port status using the DTR and RTS line status; the behavior of these control lines is platform dependent and we no longer interpret them by default.
The Maple stm32 microprocessor includes a dedicated USB peripheral which can be configured to act as a general USB slave device with transfer rates up to 12mbps (it unfortunately can not be configured as a host or on-the-go device). By default the peripheral is configured for two uses: first to receive sketch/program uploads from the IDE, and second to emulate a regular serial port for use as a terminal (text read/write).
The emulated terminal is relatively slow and inefficient; it is best for transferring data at regular serial speeds (kilobaud). Users requiring faster data transfer should consider implementing a different communications protocol; the Maple could be reprogrammed to appear as a mass storage device (thumb drive), human interface device (mouse or keyboard), microphone, or any other USB device.
The SerialUSB channel is also used as part of the auto-reset feature of the IDE
to program the board: a magic sequence of control line toggles and transmitted
data causes the Maple to reset itself and enter bootloader mode. As an
unfortunate consequence, the auto-reset will not work if the IDE can not access
the serial port, either do to a conflict with another program (serial monitor)
or because the interface has been disabled from the Maple side
(SerialUSB.end()).
Function Reference
SerialUSB.print(...)
SerialUSB.println(...)
SerialUSB.write(bytes)
- Writes data into the port buffer to be transmitted as soon as possible.
Accepts strings (character arrays). If a raw integer is passed the
corresponding ASCII character will be transmitted; to print out a number in
human readable form add a second parameter with the base system. Eg, to print
out the decimal number '1234' use
print(1234,DEC); to print out the binary number '1001' useprint(9,BIN).write()is a lower-level function that writes bytes directly into the buffer.print()often calls this function dozens of times to write out a single formatted number; usercode can optimize raw data speed by calling this function with 64-bytes chunks instead. SerialUSB.available()
SerialUSB.read()
read()will return any data that has been received over the port andavailable()will tell if any such data actually exists, and if so how many bytes. If there is no dataread()will block/fail, so the usual program structure is to poll withavailable()and onlyread()if there's something ready.uint8 SerialUSB.pending()
- Returns the number of bytes waiting in the transmit buffer. Usercode can use
this to prevent any blocking/waiting when using the direct
write()functions, or to check if data was actually requested/received by the host. uint8 getRTS()
- Returns the state (1 or 0) of the virtual RTS ("ready to send") line. This can be used to guess if the USB host is actively waiting for data (aka a serial monitor program is running) or just "configured" (the virtual serial port is configured but no program is reading data).
uint8 getDTR()
- Returns the state (1 or 0) of the virtual DTR ("data terminal ready") line. This can be used to guess if the USB host is actively waiting for data (aka a serial monitor program is running) or just "configured" (the virtual serial port is configured but no program is reading data).
uint8 isConnected()
- Returns 1 if the USB host is connected and the virtual serial interface is initialized (though not necessarily active), otherwise 0.
SerialUSB.end()
SerialUSB.begin()
- The USB peripheral is enabled by default so that the auto-reset feature
will work, but it can be disabled/restarted at any time with the
end()andbegin()functions. Theend()is a relatively hard shutdown, similar to unplugging the board; this may crash or confuse any programs running host-side. It's probably wise to wait a few seconds between anend()/begin()or abegin()/print()to let the computer reconfigure.
Code Examples
Safe Print
This function should run smoothly and not block; the LED should blink at roughly the same speed whether being monitored, running from battery, or connected but not monitored. You may need to experiment with the DTR/RTS logic for your platform and device configuration.#define LED_PIN 13 void setup() { /* Set up the LED to blink */ pinMode(LED_PIN, OUTPUT); } void loop() { // LED will stay off if we are disconnected; // will blink quickly if USB is unplugged (battery etc) if(SerialUSB.isConnected()) { digitalWrite(LED_PIN, 1); } delay(100); // If this logic fails to detect if bytes are going to // be read by the USB host, then the println() will fully // many times, causing a very slow LED blink. // If the characters are printed and read, the blink will // only slow a small amount when "really" connected, and fast // when the virtual port is only configured. if(SerialUSB.isConnected() && (SerialUSB.getDTR() || SerialUSB.getRTS())) { for(int i=0; i<10; i++) { SerialUSB.println(123456,BIN); } } digitalWrite(LED_PIN, 0); delay(100); }
Recommended Reading
- USB in a NutShell overview from Beyond Logic
- Wikipedia article on Universal Serial Bus (USB)
- Linux Kernel documentation for USB ACM and USB Serial
- STMicro documentation for STM32F103RB microcontroller:
About this Document
A more recent version of this document may be available from the LeafLabs website. Our documentation is versioned on github; you can track changes to the master branch at this link.
This documentation is released under a
Creative Commons Attribution-Share Alike 3.0 license.
Translations are welcomed; give us a ping to make sure we aren't in the process of revising or editing first.
About
Contact
Community
Distributors
Licensing
Feeds
Search
Contact webmaster@leaflabs.com with website issues
Powered by WordPress, nginx, Linux, vim, and coffee.
This site intended to be valid HTML 4.01 Strict. Best viewed with any standards-compliant browser.
Copyright LeafLabs LLC, 2009-2010, a member of the
Green Street Space.
Unless otherwise noted all content on this website is released under the
Creative Commons Attribution Licence 3.0
Hello Anonymous! Login?
