<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="bbPress/1.0.2" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>LeafLabs Garden &#187; Topic: Sending data over USB</title>
		<link>http://forums.leaflabs.com/topic.php?id=639</link>
		<description>A place to share, learn, and grow...</description>
		<language>en-US</language>
		<pubDate>Fri, 22 Jan 2016 00:18:33 +0000</pubDate>
		<generator>http://bbpress.org/?v=1.0.2</generator>
		<textInput>
			<title><![CDATA[Search]]></title>
			<description><![CDATA[Search all topics from these forums.]]></description>
			<name>q</name>
			<link>http://forums.leaflabs.com/search.php</link>
		</textInput>
		<atom:link href="http://forums.leaflabs.com/rss.php?topic=639" rel="self" type="application/rss+xml" />

		<item>
			<title>gbulmer on "Sending data over USB"</title>
			<link>http://forums.leaflabs.com/topic.php?id=639&amp;page=2#post-7595</link>
			<pubDate>Thu, 12 Jan 2012 15:06:08 +0000</pubDate>
			<dc:creator>gbulmer</dc:creator>
			<guid isPermaLink="false">7595@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;gagol - It might be helpful to know that Maple comes with the Open Source Newlib implementation of most of the Standard C library:&#60;br /&#62;
&#60;a href=&#34;http://sourceware.org/newlib/&#34; rel=&#34;nofollow&#34;&#62;http://sourceware.org/newlib/&#60;/a&#62;&#60;/p&#62;
&#60;p&#62;The standard &#60;code&#62;atoi&#60;/code&#62; has already been implemented.&#60;br /&#62;
Use it as:&#60;br /&#62;
&#60;pre&#62;&#60;code&#62;#include &#38;lt;stdlib.h&#38;gt;

//...

    char buffer[] = &#38;quot;00535&#38;quot;;
    int value = atoi(buffer[0]);&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;All strings, e.g. &#60;code&#62;char buffer[] = &#38;quot;00535&#38;quot;;&#60;/code&#62; are terminated with a '\O' (end of string) character, so there is no need to pass the length of the string to &#60;code&#62;atoi()&#60;/code&#62;. The atoi function converts until it reaches the end of string, or a non digit character.&#60;/p&#62;
&#60;p&#62;Newlib includes a further set of conversions functions including strtol, strtoul, etc. which handle number bases other than 10.&#60;/p&#62;
&#60;p&#62;It also includes &#60;code&#62;sscanf()&#60;/code&#62; which can extract pieces of string and convert them into any basic C types.&#60;/p&#62;
&#60;p&#62;While is is only a convention, functions which convert to unsigned numbers, like that atoint, might be better named atouint. The comments might also mention the restriction that it only works for unsigned integer strings, so that people don't misunderstand. It might also be worth mentioning in the comment that it has 'unpredictable' results if the string contains characters which are not ASCII digits. &#60;/p&#62;
&#60;p&#62;The usual way of doing the conversion from a string of ASCII digits to integers starts with something like this:&#60;br /&#62;
&#60;pre&#62;&#60;code&#62;#include &#38;lt;ctype.h&#38;gt;

uint32 atouint(char* t) {
    uint32 val = 0;
    while (*t != &#38;#39;\O&#38;#39; &#38;amp;&#38;amp; isdigit(*t)) {
        val = val*10 + (*t - &#38;#39;0&#38;#39;);
        ++t;
    }
    return val;
}&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;This checks that the characters in the input string are the ASCII digits. It dispenses with the need to track the number of characters in the string, by relying on the end of string, and doesn't separately track powers of 10 because it converts left to right.&#60;/p&#62;
&#60;p&#62;A small additional point if you are aiming to produce code for other people to read. Through hundreds of years of research and experience, we believe that in general, mixed case text is easier to read than UPPER CASE text. We also believe that lower case text is more readable than upper case text, hence the reason that C is a lower case programming language. Mixed upper and lower case text, or only lower case, has a lot more 'shape variation' than upper case only, and so we read it more quickly and more reliably.&#60;/p&#62;
&#60;p&#62;HTH&#60;/p&#62;
&#60;p&#62;(WARNING: I haven't compiled and tested the code, it is just an illustration)&#60;br /&#62;
(PS - because of the abysmal forum software, which strips '\' followed by '0', I have used the letter O to create '\O' to stand for the character with the value 0. Yes, ugly)
&#60;/p&#62;</description>
		</item>
		<item>
			<title>gagol on "Sending data over USB"</title>
			<link>http://forums.leaflabs.com/topic.php?id=639&amp;page=2#post-7593</link>
			<pubDate>Thu, 12 Jan 2012 13:16:17 +0000</pubDate>
			<dc:creator>gagol</dc:creator>
			<guid isPermaLink="false">7593@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;I'm a little late, but if you still needs to convert ascii to int, here is a little function that works for me :&#60;/p&#62;
&#60;p&#62;char buffer[] = &#34;00535&#34;;&#60;br /&#62;
int value = atoint(buffer[0], 5);&#60;/p&#62;
&#60;p&#62;The code requires leading 0.&#60;/p&#62;
&#60;p&#62;uint32 atoint(uint8 *t, uint8 _digits)     // CONVERT ASCII NUMBERS TO INT, PASS POINTER TO *CHAR LOCATION OF THE BEGINNING OF&#60;br /&#62;
{&#60;br /&#62;
  uint32 _val = 0;&#60;br /&#62;
  xb = 1;                                  // FACTOR FOR EACH DIGIT PROCESSING&#60;br /&#62;
  while(_digits--)                         // FOR EACH DIGIT STARTING FROM RIGHT END GOING LEFTWARD&#60;br /&#62;
  {&#60;br /&#62;
    _val += (t[_digits] - '0') * xb;       // ADD CURRENT DIGIT * FACTOR POWER TO VALUE&#60;br /&#62;
    xb *= 10;                              // AUGMENT FACTOR POWER BY 10&#60;br /&#62;
  }&#60;/p&#62;
&#60;p&#62;  return _val;                             // RETURN INT&#60;br /&#62;
}
&#60;/p&#62;</description>
		</item>
		<item>
			<title>gbulmer on "Sending data over USB"</title>
			<link>http://forums.leaflabs.com/topic.php?id=639&amp;page=2#post-7456</link>
			<pubDate>Wed, 28 Dec 2011 11:05:32 +0000</pubDate>
			<dc:creator>gbulmer</dc:creator>
			<guid isPermaLink="false">7456@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;I have no idea if there is bit shifting in vb2010, but it isn't needed.&#60;br /&#62;
A left shift of 8 (which reverses the right shift of 8 in writebuff) is exactly he same as multiplying by 2^8, which is 256.&#60;/p&#62;
&#60;p&#62;So, if you read the values as 0 to 255, then to rebuild a 16 bit value an expression would be something like&#60;br /&#62;
&#60;code&#62;wholeValue = read0 + (read1 * 256)&#60;/code&#62;&#60;br /&#62;
where read0 is the first byte and read1 is the second byte read.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>gcam on "Sending data over USB"</title>
			<link>http://forums.leaflabs.com/topic.php?id=639&amp;page=2#post-7455</link>
			<pubDate>Wed, 28 Dec 2011 05:02:06 +0000</pubDate>
			<dc:creator>gcam</dc:creator>
			<guid isPermaLink="false">7455@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;hi (google traslator),&#60;br /&#62;
I send the data on the USB with the following instructions&#60;/p&#62;
&#60;p&#62;void writebuff(uint16 value) {&#60;br /&#62;
  if (buffindex &#38;gt;= sizeof(buffer)-1) {&#60;br /&#62;
    SerialUSB.write(&#38;amp;buffer[0], sizeof(buffer));&#60;br /&#62;
    buffindex = 0;&#60;br /&#62;
  }&#60;br /&#62;
  buffer[buffindex++] = value &#38;amp; 0x00ff;&#60;br /&#62;
  buffer[buffindex++] = (value&#38;gt;&#38;gt;8) &#38;amp; 0x00ff;&#60;br /&#62;
}&#60;/p&#62;
&#60;p&#62;void loop() {&#60;br /&#62;
  writebuff(analogRead(0)); // x axis (value +- 32000)&#60;br /&#62;
  writebuff(analogRead(1)); // y axis (value +- 32000)&#60;br /&#62;
  writebuff(analogRead(2)); // z axis (value +- 32000)&#60;br /&#62;
...&#60;br /&#62;
}&#60;/p&#62;
&#60;p&#62;On the PC (visual basic 2010) I read the values ​​are between 0 and 255.&#60;/p&#62;
&#60;p&#62;How do I go back to the values ​​obtained from the accelerometer.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>mbolivar on "Sending data over USB"</title>
			<link>http://forums.leaflabs.com/topic.php?id=639&amp;page=2#post-3928</link>
			<pubDate>Thu, 17 Mar 2011 07:34:15 +0000</pubDate>
			<dc:creator>mbolivar</dc:creator>
			<guid isPermaLink="false">3928@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;StephenFromNYC,&#60;/p&#62;
&#60;p&#62;&#34;ajme...&#34; is poslathian on the LeafLabs forum.&#60;/p&#62;
&#60;p&#62;I asked how he obtained his figure, and (as far as I recall) his method was (on the host PC side) to use the Unix &#34;cat&#34; utility to pipe the output of the virtual serial port's device to a file in Linux (e.g. $ cat /dev/ttyACM0 &#38;gt; some-file).  Meanwhile, the Maple was sending data in a tight loop using the low-level usbSendBytes() function.  He then timed how long it took for the file to reach a certain size.&#60;/p&#62;
&#60;p&#62;I'd like to emphasize that this is only my recollection of his methods.  Poslathian, perhaps you'd care to weigh in?&#60;/p&#62;
&#60;p&#62;I personally have been unable to achieve transfer rates greater than ~30KB/s using the current code.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>StephenFromNYC on "Sending data over USB"</title>
			<link>http://forums.leaflabs.com/topic.php?id=639&amp;page=2#post-3912</link>
			<pubDate>Wed, 16 Mar 2011 10:50:19 +0000</pubDate>
			<dc:creator>StephenFromNYC</dc:creator>
			<guid isPermaLink="false">3912@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;March 16, 2011&#60;/p&#62;
&#60;p&#62;Hello mbolivar-&#60;/p&#62;
&#60;p&#62;Any feedback from the author (&#34;ajme...&#34;) who claimed a rate of 150 kilobytes/sec using &#60;code&#62;SerialUSB()&#60;/code&#62; and the February 2011 snapshot?&#60;/p&#62;
&#60;p&#62;I appear to be getting a fast data transfer rate, but the rate does not appear to be consistent (depending on how the rate is tested the transfer rate bounces up and down a lot).&#60;/p&#62;
&#60;p&#62;It would help me to see the code and test method used by &#34;ajme...&#34;&#60;/p&#62;
&#60;p&#62;Thanks!&#60;/p&#62;
&#60;p&#62;Stephen from NYC
&#60;/p&#62;</description>
		</item>
		<item>
			<title>mbolivar on "Sending data over USB"</title>
			<link>http://forums.leaflabs.com/topic.php?id=639&amp;page=2#post-3721</link>
			<pubDate>Wed, 23 Feb 2011 23:18:38 +0000</pubDate>
			<dc:creator>mbolivar</dc:creator>
			<guid isPermaLink="false">3721@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;Stephen,&#60;/p&#62;
&#60;blockquote&#62;&#60;p&#62;
mbolivar, in your comment from:&#60;/p&#62;
&#60;p&#62;&#60;a href=&#34;http://code.google.com/p/leaflabs/issues/detail?id=10&#34; rel=&#34;nofollow&#34;&#62;http://code.google.com/p/leaflabs/issues/detail?id=10&#60;/a&#62;&#60;/p&#62;
&#60;p&#62;Can you please share the code you used to determine the current SerialUSB() rate to be about 150KB/second (using the February 2011 snapshot)?
&#60;/p&#62;&#60;/blockquote&#62;
&#60;p&#62;It seems like you're referring to this comment, which was not left by me:&#60;br /&#62;
&#60;a href=&#34;http://code.google.com/p/leaflabs/issues/detail?id=10#c4&#34; rel=&#34;nofollow&#34;&#62;http://code.google.com/p/leaflabs/issues/detail?id=10#c4&#60;/a&#62;&#60;/p&#62;
&#60;p&#62;I am personally unable to reproduce those results, but I will ask the comment's author to do so :).
&#60;/p&#62;</description>
		</item>
		<item>
			<title>gbulmer on "Sending data over USB"</title>
			<link>http://forums.leaflabs.com/topic.php?id=639&amp;page=2#post-3703</link>
			<pubDate>Tue, 22 Feb 2011 20:23:34 +0000</pubDate>
			<dc:creator>gbulmer</dc:creator>
			<guid isPermaLink="false">3703@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;StephenFromNYC&#60;/p&#62;
&#60;blockquote&#62;&#60;p&#62;In other words are the next two lines equivalent (in terms of machine code created by the compiler)?&#60;/p&#62;
&#60;p&#62;&#60;code&#62;SerialUSB.write(&#38;amp;buffer[0], sizeof(buffer));&#60;/code&#62;&#60;br /&#62;
&#60;code&#62;SerialUSB.write(buffer, sizeof(buffer));&#60;/code&#62;&#60;/p&#62;
&#60;/blockquote&#62;
&#60;p&#62;Yes, in this case the machine code generated by the compiler for &#60;code&#62;&#38;amp;buffer[0]&#60;/code&#62; and &#60;code&#62;buffer&#60;/code&#62; should be identical, and should be identical in general.&#60;/p&#62;
&#60;p&#62;I did the &#60;code&#62;&#38;amp;buffer[0]&#60;/code&#62; deliberately for a couple of reasons; partly to ensure the difference between a pointer (unsigned char *) and an array is clear (the number of bugs I've seen involving unallocated space!-), and partly it makes it more obvious (to me) that there may be a bigger buffer (than 64 bytes). &#60;/p&#62;
&#60;p&#62;For example, if the ADC values were being saved into a buffer using DMA, then the DMA 'end event' might trigger after 64 bytes worth of results. Then the DMA event handler might reset the DMA to another buffer, or the other half of the same buffer, &#60;strong&#62;and&#60;/strong&#62; trigger sending the USB data to the host. &#60;/p&#62;
&#60;p&#62;That sort of approach might give a more uniform sampling rate for the set of ADC samples (I don't know how long the SerialUSB.write(...) might block for, so this is an unknown concern).&#60;/p&#62;
&#60;p&#62;(I could have defined something like MAX_USB_PACKET, and used that instead of sizeof(), but it started to clutter the code.)&#60;/p&#62;
&#60;p&#62;(Technically it was the case that &#60;code&#62;buffer&#60;/code&#62; is a &#60;code&#62;const&#60;/code&#62; pointer, so is only a right-hand-side expression because it can't be assigned to, but I haven't worried about that level of C language precision for years, and I'd need to check Harbison &#38;amp; Steele &#60;a href=&#34;http://www.amazon.com/Reference-Manual-Samuel-P-Harbison/dp/013089592X/ref=dp_ob_title_bk&#34; rel=&#34;nofollow&#34;&#62;http://www.amazon.com/Reference-Manual-Samuel-P-Harbison/dp/013089592X/ref=dp_ob_title_bk&#60;/a&#62; but I can't find my copy of the 5th edition :-(
&#60;/p&#62;</description>
		</item>
		<item>
			<title>StephenFromNYC on "Sending data over USB"</title>
			<link>http://forums.leaflabs.com/topic.php?id=639&amp;page=2#post-3701</link>
			<pubDate>Tue, 22 Feb 2011 17:48:10 +0000</pubDate>
			<dc:creator>StephenFromNYC</dc:creator>
			<guid isPermaLink="false">3701@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;Hello,&#60;/p&#62;
&#60;p&#62;Yes, I understand that &#60;code&#62;buffer[buffindex++]&#60;/code&#62; increments the value of buffindex AFTER the array assignment is made.  I understand that the lines &#60;code&#62;buffindex = buffindex + 1;&#60;/code&#62; can both be replaced by either &#60;code&#62;buffindex++&#60;/code&#62; or &#60;code&#62;++buffindex&#60;/code&#62;.&#60;/p&#62;
&#60;p&#62;I have a question about expressions and compiler optimizations used by the Maple.&#60;/p&#62;
&#60;p&#62;In the line &#60;code&#62;SerialUSB.write(&#38;amp;buffer[0], sizeof(buffer));&#60;/code&#62; is there any difference between &#60;code&#62;&#38;amp;buffer[0]&#60;/code&#62; (the address of the zeroth element of the array named buffer; in other words the beginning of the array) versus just using just &#34;&#60;code&#62;buffer&#60;/code&#62;&#34;.&#60;/p&#62;
&#60;p&#62;In other words are the next two lines equivalent (in terms of machine code created by the compiler)?&#60;/p&#62;
&#60;p&#62;&#60;code&#62;SerialUSB.write(&#38;amp;buffer[0], sizeof(buffer));&#60;/code&#62;&#60;br /&#62;
&#60;code&#62;SerialUSB.write(buffer, sizeof(buffer));&#60;/code&#62;&#60;/p&#62;
&#60;p&#62;Thanks!&#60;/p&#62;
&#60;p&#62;Stephen from NYC
&#60;/p&#62;</description>
		</item>
		<item>
			<title>gbulmer on "Sending data over USB"</title>
			<link>http://forums.leaflabs.com/topic.php?id=639&amp;page=2#post-3694</link>
			<pubDate>Sun, 20 Feb 2011 19:38:25 +0000</pubDate>
			<dc:creator>gbulmer</dc:creator>
			<guid isPermaLink="false">3694@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;StephenFromNYC - yes my code may be a bit confusing. I was focusing on sending the data so that it could be accurately reconstituted. I try to ensure the sequence of bytes is defined by my code rather than assuming both sides are little endian or big endian.&#60;/p&#62;
&#60;blockquote&#62;&#60;p&#62;The loop is executed eight times for a total of 64 bytes transferred.&#60;/p&#62;
&#60;/blockquote&#62;
&#60;p&#62;The loop transfers 64 bits, 8 bytes, not 64 bytes.&#60;/p&#62;
&#60;blockquote&#62;&#60;p&#62;Why is it not possible to send the entire variable res using a single SerialUSB.print() command? For example, SerialUSB.print(ser, LONG LONG).&#60;/p&#62;
&#60;/blockquote&#62;
&#60;p&#62;This doesn't work because:&#60;br /&#62;
a. there is no such function as SerialUSB.print(ser, LONG LONG), (and I'm not sure what LONG LONG signifies, a parameter to print, or the data type &#60;code&#62;long long&#60;/code&#62; with capitalisation for emphasis?) and&#60;br /&#62;
b. all of the numerical print functions convert binary values into strings of ASCII digits. For example a 4 byte uint32 could be anything from 1 ASCII digit to 10 ASCII digits long. So even if it did exist, it is likely that it would convert binary to ASCII.&#60;/p&#62;
&#60;p&#62;The way to transfer a 64 byte block in a single USB packet is to do a &#60;code&#62;SerialUSB.write(void *, uint32);&#60;/code&#62; with a 64 byte buffer.&#60;/p&#62;
&#60;p&#62;If you only need 20,000 12-bit data points/second, then I think the Maple can do that. The inefficiency is sending near-empty packets, not the peak throughput.&#60;br /&#62;
I'd likely just send 32 values/64 byte packet, and avoid any concerns about packing for now.&#60;/p&#62;
&#60;p&#62;You have several choices about how to pack stuff into a 64 byte buffer.&#60;/p&#62;
&#60;p&#62;If there is no bit-level packing, I'd do something like this:&#60;br /&#62;
&#60;pre&#62;&#60;code&#62;unsigned char buffer[64];
int buffindex = 0;

void writebuff(uint16 value) {
  if (buffindex &#38;gt;= sizeof(buffer)-1) {
    SerialUSB.write(&#38;amp;buffer[0], sizeof(buffer));
    buffindex = 0;
  }
  buffer[buffindex++] = value &#38;amp; 0x00ff;
  buffer[buffindex++] = (value&#38;gt;&#38;gt;8) &#38;amp; 0x00ff;
}

void loop() {
  writebuff(analogRead(0));
  writebuff(analogRead(1));
  writebuff(analogRead(2));
  writebuff(analogRead(3));
  writebuff(analogRead(4));
  // other stuff
}&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;(WARNING code not checked)&#60;/p&#62;
&#60;p&#62;This handles the write when the buffer gets full, without any packing.&#60;/p&#62;
&#60;p&#62;Take things from there.&#60;/p&#62;
&#60;p&#62;If packing becomes important, handle it inside writebuff.&#60;/p&#62;
&#60;p&#62;PS - the&#60;br /&#62;
&#60;pre&#62;&#60;code&#62;buffer[buffindex++] = value &#38;amp; 0x00ff;
  buffer[buffindex++] = (value&#38;gt;&#38;gt;8) &#38;amp; 0x00ff;&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;maybe easier to read as&#60;br /&#62;
&#60;pre&#62;&#60;code&#62;buffer[buffindex] = value &#38;amp; 0x00ff;
  buffindex = buffindex + 1;
  buffer[buffindex] = (value&#38;gt;&#38;gt;8) &#38;amp; 0x00ff
  buffindex = buffindex + 1;;&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;(sorry that the indentation is broken, I can't get leading spaces into the first line using backtick)
&#60;/p&#62;</description>
		</item>
		<item>
			<title>StephenFromNYC on "Sending data over USB"</title>
			<link>http://forums.leaflabs.com/topic.php?id=639&amp;page=2#post-3693</link>
			<pubDate>Sun, 20 Feb 2011 18:02:26 +0000</pubDate>
			<dc:creator>StephenFromNYC</dc:creator>
			<guid isPermaLink="false">3693@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;Hello,&#60;/p&#62;
&#60;p&#62;I think I have confused other users and myself, so let me step back and try to summarize what I understand from recent posts about how to optimize &#60;code&#62;SerialUSB()&#60;/code&#62; data transfers.  Then at the end of this post I will try to refocus my questions.&#60;/p&#62;
&#60;p&#62;In my post:&#60;/p&#62;
&#60;p&#62;&#60;a href=&#34;http://forums.leaflabs.com/topic.php?id=639#post-3629&#34;&#62;http://forums.leaflabs.com/topic.php?id=639#post-3629&#60;/a&#62;&#60;/p&#62;
&#60;p&#62;I was wrong to focus on how to send just five 12-bit analog reads, because I incorrectly thought that sending five 12-bit values was the most one could fit into a single USB 64-byte packet.  In my hurried and faulty logic I got my bits and bytes confused.  Obviously, 60-bits is a lot smaller than 64-bytes.  Forty (40) 12-bit values acquired using &#60;code&#62;analogRead()&#60;/code&#62; should fit into a single USB 64-bit packet.&#60;/p&#62;
&#60;p&#62;For the moment, let's just stick with the goal to efficiently send five 12-bit values using &#60;code&#62;SerialUSB()&#60;/code&#62;.&#60;/p&#62;
&#60;p&#62;I feel like I am missing something really fundamental in my reading of gbulmers Maple code (&#60;a href=&#34;http://forums.leaflabs.com/topic.php?id=639#post-3660&#34;&#62;http://forums.leaflabs.com/topic.php?id=639#post-3660&#60;/a&#62;) which he said was compiled but not tested.&#60;/p&#62;
&#60;p&#62;I believe the five 12-bit values are first combined into a single variable (&#60;code&#62;res&#60;/code&#62;).  &#60;code&#62;res&#60;/code&#62; is then broken down into pieces and each char is sent to the host using &#60;code&#62;SerialUSB()&#60;/code&#62;.&#60;/p&#62;
&#60;p&#62;I understand the line from gbulmer's code:&#60;/p&#62;
&#60;p&#62;&#60;code&#62;long long res = (a[4]&#38;lt;&#38;lt;48) &#124; (a[3]&#38;lt;&#38;lt;36) &#124; (a[2]&#38;lt;&#38;lt;24) &#124; (a[1]&#38;lt;&#38;lt;12) &#124; a[0];&#60;/code&#62;&#60;/p&#62;
&#60;p&#62;This uses bitshifting and ORs to combine the five 12-bit values into a single variable of type &#60;code&#62;long long&#60;/code&#62;.&#60;/p&#62;
&#60;p&#62;However, I am confused about gbulmer's for loop:&#60;/p&#62;
&#60;blockquote&#62;&#60;p&#62;
for (int i=0; i&#38;lt;8; i=i+1) {&#60;br /&#62;
    unsigned char c = res &#38;amp; 0xff;&#60;br /&#62;
    res = res &#38;gt;&#38;gt; 8;&#60;br /&#62;
    SerialUSB.print(c, BYTE);&#60;br /&#62;
  }
&#60;/p&#62;&#60;/blockquote&#62;
&#60;p&#62;This code uses a mask to strip the higher bits.  Then to prepare the variable &#60;code&#62;res&#60;/code&#62; for the next cycle of the loop bitshifting (&#60;code&#62;res = res &#38;gt;&#38;gt; 8&#60;/code&#62;) is used before the value of c is sent via &#60;code&#62;SerialUSB.print(c, BYTE)&#60;/code&#62;.&#60;/p&#62;
&#60;p&#62;The loop is executed eight times for a total of 64 bytes transferred.&#60;/p&#62;
&#60;p&#62;Why are multiple &#60;code&#62;SerialUSB.print()&#60;/code&#62; statements used if the goal is to send the five 12-bit values in a single USB 64-byte packet?&#60;/p&#62;
&#60;p&#62;My assumption is that each time (for a total of eight) &#60;code&#62;SerialUSB.print()&#60;/code&#62; is called the data is transferred over USB even if the 64 byte packet is mostly empty (not filled with data).&#60;/p&#62;
&#60;p&#62;If this assumption is wrong, does the USB system wait until the eighth &#60;code&#62;SerialUSB.print(c, BYTE)&#60;/code&#62; command before a single, completely filled, 64-byte packet is sent?&#60;/p&#62;
&#60;p&#62;Why is it not possible to send the entire variable &#60;code&#62;res&#60;/code&#62; using a single &#60;code&#62;SerialUSB.print()&#60;/code&#62; command?  For example, &#60;code&#62;SerialUSB.print(ser, LONG LONG).&#60;/p&#62;
&#60;p&#62;In the host routine, the process is reversed.  Eight &#60;/code&#62;&#60;code&#62;SerialUSB.read()&#60;/code&#62;s are used to fetch each 8-bit value, the variable res is shifted by eight bits to prepare for the use of OR.  This combines eight 8-bit reads into a single &#60;code&#62;long long&#60;/code&#62;.&#60;/p&#62;
&#60;p&#62;In the host code, should the line:&#60;/p&#62;
&#60;p&#62;&#60;code&#62;a[j] = res &#38;amp; 0x0fff;&#60;/code&#62;&#60;/p&#62;
&#60;p&#62;instead be:&#60;/p&#62;
&#60;p&#62;&#60;code&#62;a[j] = res &#38;amp; 0xff;&#60;/code&#62;&#60;/p&#62;
&#60;p&#62;Here are my refocused questions:&#60;/p&#62;
&#60;p&#62;Goal (present): I want to use my Maple to acquire 12-bit data via &#60;code&#62;analogRead()&#60;/code&#62; as quickly as possible and to send the data to the host via USB as quickly as possible (without any data being dropped).  A higher data transfer rate will let me apply software filters to the data set (for example, to remove 60 Hz noise from the data).  I do not know if I will use the Maple to do the filtering or use the host.  I will be happy to shift the filtering to the host if this maximizes the data transfer rate.&#60;/p&#62;
&#60;p&#62;A transfer rate of 20,000 data points a second (where each data point is a 12-bit &#60;code&#62;analogRead()&#60;/code&#62; value) should be sufficient for my long term goals.  However, a rate which is 10X slower will make me happy in the short term and will keep me plugging away.&#60;/p&#62;
&#60;p&#62;Goal (future): DMA will speed up the data transfer between the Maple and a host system, but I think for my purposes DMA is not needed.&#60;/p&#62;
&#60;p&#62;I may be wrong to minimize this task, but at the moment, the exact rate of analog reads is not that important to me.  That can be a problem for another day.&#60;/p&#62;
&#60;p&#62;I appreciate that two bytes are wasted using &#60;code&#62;SerialUSB().println()&#60;/code&#62;&#60;code&#62;, but I was using &#60;/code&#62;&#60;code&#62;SerialUSB.println()&#60;/code&#62;, to see the boundaries between analogRead() values when I debugging.&#60;/p&#62;
&#60;p&#62;mbolivar, in your comment from:&#60;/p&#62;
&#60;p&#62;&#60;a href=&#34;http://code.google.com/p/leaflabs/issues/detail?id=10&#34;&#62;http://code.google.com/p/leaflabs/issues/detail?id=10&#60;/a&#62;&#60;/p&#62;
&#60;p&#62;Can you please share the code you used to determine the current &#60;code&#62;SerialUSB()&#60;/code&#62; rate to be about 150KB/second (using the February 2011 snapshot)?&#60;/p&#62;
&#60;p&#62;I understand that at most five 12-bit values fit into one &#60;code&#62;long long&#60;/code&#62; (using the line from gbulmer's bitshifting code).  A &#60;code&#62;long long&#60;/code&#62; is eight bytes, so at most forty (40) 12-bit numbers fit into 64 bytes.&#60;/p&#62;
&#60;p&#62;Therefore, in the absence of data compression/expansion a single USB 64-byte packet can transfer forty (40) 12-bit values (acquired using &#60;code&#62;analogRead()&#60;/code&#62;).&#60;/p&#62;
&#60;p&#62;My next question is: &#34;How do I combine eight &#60;code&#62;long long&#60;/code&#62; values into a buffer which I can efficiently send in a single 64-byte USB packet using &#60;code&#62;SerialUSB.write(buffer, 64)&#60;/code&#62;&#34;?&#60;/p&#62;
&#60;p&#62;I assume it will be necessary to flush before calling &#60;code&#62;SerialUSB.write(buffer, 64)&#60;/code&#62;:&#60;/p&#62;
&#60;p&#62;&#60;a href=&#34;http://forums.leaflabs.com/topic.php?id=575&#34;&#62;http://forums.leaflabs.com/topic.php?id=575&#60;/a&#62;&#60;/p&#62;
&#60;p&#62;Thanks and sorry for any confusion caused!&#60;/p&#62;
&#60;p&#62;Stephen from NYC
&#60;/p&#62;</description>
		</item>
		<item>
			<title>gbulmer on "Sending data over USB"</title>
			<link>http://forums.leaflabs.com/topic.php?id=639#post-3687</link>
			<pubDate>Sun, 20 Feb 2011 11:09:52 +0000</pubDate>
			<dc:creator>gbulmer</dc:creator>
			<guid isPermaLink="false">3687@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;StephenFromNYC - You could send the 12-bit values as simple two byte values.&#60;br /&#62;
That would be very easy to do.&#60;/p&#62;
&#60;p&#62;But, you need to pack them into a 64-byte packet anyway, so it isn't hugely simpler.&#60;/p&#62;
&#60;p&#62;The code above packs 5 12-bit numbers (60 bits) into 1 &#60;code&#62;long long&#60;/code&#62;.&#60;/p&#62;
&#60;p&#62;A &#60;code&#62;long long&#60;/code&#62; is 8 bytes, so they are easy to pack into 64 bytes.&#60;/p&#62;
&#60;p&#62;5 12-bit number/&#60;code&#62;long long&#60;/code&#62; gives&#60;br /&#62;
5 12-bit number x 8 &#60;code&#62;long long&#60;/code&#62; number / 64 bytes&#60;br /&#62;
= 40 12-bit numbers&#60;/p&#62;
&#60;p&#62;use similar code (to above) to transfer the data.&#60;/p&#62;
&#60;p&#62;Don't use println, it is a waste of two bytes (&#34;\r\n&#34;).&#60;br /&#62;
Don't try to write the &#60;code&#62;long long&#60;/code&#62; as a single value because that will transform the number to a sequence of ASCII characters, which will drop the transfer efficiency from 8 bits to approximately 3.3 bits/byte, defeating the entire effort.&#60;br /&#62;
Use SerialUSB.write(buffer, 64) to send the whole packet in one unit.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>StephenFromNYC on "Sending data over USB"</title>
			<link>http://forums.leaflabs.com/topic.php?id=639#post-3686</link>
			<pubDate>Sun, 20 Feb 2011 10:39:16 +0000</pubDate>
			<dc:creator>StephenFromNYC</dc:creator>
			<guid isPermaLink="false">3686@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;Hello,&#60;/p&#62;
&#60;p&#62;gbulmer, yes, I got my variable types switched.  Thanks for the careful read.  &#60;code&#62;long long&#60;/code&#62; is what is needed.&#60;/p&#62;
&#60;p&#62;Here is a &#34;hopefully someone can quickly answer this question, because I am too lazy to figure this one out&#34; question.&#60;/p&#62;
&#60;p&#62;What is the largest number of 12-bit numbers which can be combined into a single long long which is then efficiently transferred in a single 64 byte block using &#60;code&#62;SerialUSB.println()&#60;/code&#62;?  Thirty two?  If I want to use &#60;code&#62;println()&#60;/code&#62; instead of &#60;code&#62;print()&#60;/code&#62; is thirty one the largest number which should be combined?&#60;/p&#62;
&#60;p&#62;I understand that avoiding cross byte boundary errors (pointed out by mbolivar) would be easiest at the maple end and also the host ends by bit-shifting in increments of 12 (assuming the goal is to combine 12-bit analog read data).  I believe this wastes 4-bits per number, but it makes decoding on the host end easier.&#60;/p&#62;
&#60;p&#62;Thanks!&#60;/p&#62;
&#60;p&#62;Stephen from NYC
&#60;/p&#62;</description>
		</item>
		<item>
			<title>gbulmer on "Sending data over USB"</title>
			<link>http://forums.leaflabs.com/topic.php?id=639#post-3681</link>
			<pubDate>Sat, 19 Feb 2011 11:20:44 +0000</pubDate>
			<dc:creator>gbulmer</dc:creator>
			<guid isPermaLink="false">3681@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;StephenFromNYC&#60;br /&#62;
&#60;blockquote&#62;code snippets needed to merge five 12-bit analog reads into a single variable of type uint16&#60;/p&#62;&#60;/blockquote&#62;
&#60;p&#62;This is probably just a slip of the pen/finger but the five 12 bit values are merged into a &#60;code&#62;long long&#60;/code&#62;, not a &#60;code&#62;uint16&#60;/code&#62;&#60;br /&#62;
The unpacked values are returned in an array of &#60;code&#62;uint16&#60;/code&#62; values.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>mbolivar on "Sending data over USB"</title>
			<link>http://forums.leaflabs.com/topic.php?id=639#post-3674</link>
			<pubDate>Fri, 18 Feb 2011 17:34:48 +0000</pubDate>
			<dc:creator>mbolivar</dc:creator>
			<guid isPermaLink="false">3674@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;Stephen,&#60;/p&#62;
&#60;p&#62;Yes, you could pack the data that way, although you'd have to be careful to get the details right, since the readings would cross byte boundaries in an uneven way.
&#60;/p&#62;</description>
		</item>

	</channel>
</rss>
