<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <channel>
        <title>Firmware communication protocol : Streaming vs Packets</title>
        <description>Breaking this off the previous &quot;is firmware necessary thread&quot; as topic has diverged.

nophead Wrote:
-------------------------------------------------------
&gt; @BeagleFury,
&gt;  I don&#039;t have any specific links but when I used
&gt; to follow the RSS feed from the MakerBot Google
&gt; groups many people had lots of pauses and hangs
&gt; that spoilt the build.

[url=http://builders.reprap.org/2009/04/lightweight-and-fast-g-code-printing.html]I found a blog post on the builders blog[/url]; it talks about an arduino bug that causes 115Baud rate to be unusable, and offers a solution that may enhance reliability at that rate; I may experiment with this, since 115K baud has appealing throughput rates if it can achieve a lower error/data loss rate.

As I am not keen on buying new hardware and drive capability using ethernet, etc, the USB packet option you propose might work, or, maybe another one using streamed ASCII would work too...

Here are my initial thoughts.. any comments?  This would satisfy one of my goals of being able to perform simple tests using a terminal based application, while still getting the full advantage of a CRC windowed packet system.

Frame mode - Full data integrety, guaranteed delivery
 Packet framing: SOH swnd rwnd TAB data... TAB crc ETB -&gt;
 Active window state request: SYN -&gt;
 Window state response: </description>
        <link>https://reprap.org/forum/read.php?147,34984,34984#msg-34984</link>
        <lastBuildDate>Sun, 12 Jul 2026 02:34:39 -0400</lastBuildDate>
        <generator>Phorum 5.2.23</generator>
        <item>
            <guid>https://reprap.org/forum/read.php?147,34984,54974#msg-54974</guid>
            <title>Re: Firmware communication protocol : Streaming vs Packets</title>
            <link>https://reprap.org/forum/read.php?147,34984,54974#msg-54974</link>
            <description><![CDATA[ james villeneuve, sounds like you're running into two of the issues that prompted me to write my own firmware based on the reprap firmware. See link in my sig for details, including all-integer calculation and an interrupt-driven serial transmit buffer.]]></description>
            <dc:creator>Triffid_Hunter</dc:creator>
            <category>Firmware - experimental, borrowed, and future</category>
            <pubDate>Mon, 09 Aug 2010 23:26:34 -0400</pubDate>
        </item>
        <item>
            <guid>https://reprap.org/forum/read.php?147,34984,54227#msg-54227</guid>
            <title>Re: Firmware communication protocol : Streaming vs Packets</title>
            <link>https://reprap.org/forum/read.php?147,34984,54227#msg-54227</link>
            <description><![CDATA[ I have been dealing with delays of the arduino controller that pauses my reprap. The delays are from the processor halting everything but sending serial commands, then resuming where it left off. when sending serial data print does not utilize the internal 1 byte buffer (actually 2 bytes but 1 byte sending and one byte buffer), I am trying to implement in my code a serial. Write(str) and send one character over at a time, and loop and do other tasks until that amount of time has past for the buffer to empty then send another byte of data. The idea is to use the 1 byte tx buffer, and free up resources, so interrupts and other functions during xyz moves can go on without stopping. one way you can verify if the serial.print buffer is causing issues, is reduce the buffer in the config to 2 and adjust code appropriately in the fiveD_gcode_interpreter <br />
<br />
Remove or remark the lines:<br />
<br />
static cartesian_dda cdda2;<br />
static cartesian_dda cdda3;<br />
<br />
<br />
  cdda[0] = &amp;cdda2;<br />
  cdda[1] = &amp;cdda3; <br />
<br />
and change config buffer=2 instead of 4.<br />
<br />
also change serial.print in process_gode to serial.println("ok\nok")<br />
<br />
this causes 1 command to be processed, and the second command to be sent while 1st one is processing, but since the buffers are full, the serial.print is only sent right after the command is processed, and before the next move is processed or at full speed. meaning the ack statement that stops all the arduino functions only happens at near stop speed, when it will not cause a stall or missing steps.<br />
<br />
I am implementing changes to incorporate a serial buffer for tx that allows hardware buffer and sends 1 byte at a time, at the appropriate rate from baud so that a small fraction of the time is used, and the arduino will not pause anymore...  <br />
<br />
also no work needs to be done to floating point operations if you can not be so precise about feedrate. there is a calculation in the code in cartesian_dda that states:<br />
 return round((distance*60000000.0) /(feedrate*(float)total_steps)<br />
<br />
60 or any multiple of 60 to the power of ten does not divide well into many numbers. it requires extensive float calculations and randomly is slower to calculate these extra places of digits for different feedrates. for example 60/9 = 6.666666666666667<br />
<br />
however changing the calculation to a more float friendly value of <br />
<br />
 return round((distance*59760000.0) /(feedrate*(float)total_steps)<br />
<br />
provides numbers that are faster to process 5976/9 =664, for example<br />
<br />
5976 is a number that divides into 3 and comes out with few digits past the decimal. The fewer points past the decimal the faster a float processes.]]></description>
            <dc:creator>james villeneuve</dc:creator>
            <category>Firmware - experimental, borrowed, and future</category>
            <pubDate>Fri, 06 Aug 2010 02:20:13 -0400</pubDate>
        </item>
        <item>
            <guid>https://reprap.org/forum/read.php?147,34984,36595#msg-36595</guid>
            <title>Re: Firmware communication protocol : Streaming vs Packets</title>
            <link>https://reprap.org/forum/read.php?147,34984,36595#msg-36595</link>
            <description><![CDATA[ yep, so maybe a firmware option to require line numbers and checksums, maybe with M-codes to turn it on and off?<br />
<br />
also, instead of "OK", maybe firmware should respond with line number, calculated checksum and OK/NOK, so host knows to resend or move on]]></description>
            <dc:creator>Triffid_Hunter</dc:creator>
            <category>Firmware - experimental, borrowed, and future</category>
            <pubDate>Thu, 18 Feb 2010 22:02:38 -0500</pubDate>
        </item>
        <item>
            <guid>https://reprap.org/forum/read.php?147,34984,36574#msg-36574</guid>
            <title>Re: Firmware communication protocol : Streaming vs Packets</title>
            <link>https://reprap.org/forum/read.php?147,34984,36574#msg-36574</link>
            <description><![CDATA[ Triffid_Hunter Wrote:<br />
-------------------------------------------------------<br />
<br />
&gt; quick heads up, adrian posted the latest gcode<br />
&gt; reference up on the wiki, and it specifies<br />
&gt; optional line numbers and checksums- so now we can<br />
&gt; consider each gcode to be a packet since it can<br />
&gt; now have a unique identifier and a checksum!<br />
<br />
Yep.  It's great he's done this, though there still can exist issues; as the checksum and line number is optional, it can be possible to lose the 'N' code or the '*' code, and then attempt to read the line as one that (optionally) did not include the line number info.   The way around this would be to turn on a mode that would force them to be required.  Also, on the discussion page, I've noted that including a length field and a stronger checksum (CRC) would make the chance of a false positive 0% (or at least, close enough that no one need concern themselves with the probability.)  A single bit error on the 'N' code and '*' code can currently cause the entire line to be considered one of those lines where the fields were 'optionally left off'.]]></description>
            <dc:creator>BeagleFury</dc:creator>
            <category>Firmware - experimental, borrowed, and future</category>
            <pubDate>Thu, 18 Feb 2010 18:32:13 -0500</pubDate>
        </item>
        <item>
            <guid>https://reprap.org/forum/read.php?147,34984,36566#msg-36566</guid>
            <title>Re: Firmware communication protocol : Streaming vs Packets</title>
            <link>https://reprap.org/forum/read.php?147,34984,36566#msg-36566</link>
            <description><![CDATA[ you're welcome guys! make your projects awesome with it :)<br />
<br />
quick heads up, adrian posted the latest gcode reference up on the wiki, and it specifies optional line numbers and checksums- so now we can consider each gcode to be a packet since it can now have a unique identifier and a checksum!]]></description>
            <dc:creator>Triffid_Hunter</dc:creator>
            <category>Firmware - experimental, borrowed, and future</category>
            <pubDate>Thu, 18 Feb 2010 17:56:13 -0500</pubDate>
        </item>
        <item>
            <guid>https://reprap.org/forum/read.php?147,34984,36541#msg-36541</guid>
            <title>Re: Firmware communication protocol : Streaming vs Packets</title>
            <link>https://reprap.org/forum/read.php?147,34984,36541#msg-36541</link>
            <description><![CDATA[ Yeah i just noticed! hmm.. this means patching up my serial.c ;) thanks for the tip and thanks to Triffid for the serial tx buffer implementation! :)]]></description>
            <dc:creator>reinoud</dc:creator>
            <category>Firmware - experimental, borrowed, and future</category>
            <pubDate>Thu, 18 Feb 2010 12:05:27 -0500</pubDate>
        </item>
        <item>
            <guid>https://reprap.org/forum/read.php?147,34984,36529#msg-36529</guid>
            <title>Re: Firmware communication protocol : Streaming vs Packets</title>
            <link>https://reprap.org/forum/read.php?147,34984,36529#msg-36529</link>
            <description><![CDATA[ reinoud Wrote:<br />
-------------------------------------------------------<br />
&gt; As for the Arduino Serial implementation, it has a<br />
&gt; major flaw. The main problem is that receiving<br />
&gt; sure is nicely done in interrupt and buffers etc,<br />
&gt; but _sending_ is done in a busy waiting loop! no<br />
&gt; buffering, no interrupt or whatsoever. If this<br />
&gt; could be fixed, then it would be great.<br />
<br />
Yep.  When I did my serial testing, I believe this was the reason I dropped bytes.  I've already looked at Triffid_Hunters implementation, and he did it right, so that's the serial code I'll be using, rather than arduino standard.<br />
<br />
He has recently made some great improvements, too (2^n ring buffers, etc.)]]></description>
            <dc:creator>BeagleFury</dc:creator>
            <category>Firmware - experimental, borrowed, and future</category>
            <pubDate>Thu, 18 Feb 2010 09:26:25 -0500</pubDate>
        </item>
        <item>
            <guid>https://reprap.org/forum/read.php?147,34984,36519#msg-36519</guid>
            <title>Re: Firmware communication protocol : Streaming vs Packets</title>
            <link>https://reprap.org/forum/read.php?147,34984,36519#msg-36519</link>
            <description><![CDATA[ As for the Arduino Serial implementation, it has a major flaw. The main problem is that receiving sure is nicely done in interrupt and buffers etc, but _sending_ is done in a busy waiting loop! no buffering, no interrupt or whatsoever. If this could be fixed, then it would be great.<br />
<br />
Since i've decided to rewrite the firmware for the Delta RepRap in 'C', I've looked at Triffid Hunters Serial implementation and decided to merge it with some others to now have a generic serial routine but it still haven't got a serial transmit buffer. Time to dig into the ATmega specs i guess and fix this for once and for all.<br />
<br />
As for the protocol, i'm having good experiences with the MakerBot firmware's simple packet protocol. It features a master/slave packet protocol with a free bi-directional textual channel next to it. Handy for debug output ;)<br />
<br />
With regards,<br />
Reinoud]]></description>
            <dc:creator>reinoud</dc:creator>
            <category>Firmware - experimental, borrowed, and future</category>
            <pubDate>Thu, 18 Feb 2010 06:18:43 -0500</pubDate>
        </item>
        <item>
            <guid>https://reprap.org/forum/read.php?147,34984,35238#msg-35238</guid>
            <title>Re: Firmware communication protocol : Streaming vs Packets</title>
            <link>https://reprap.org/forum/read.php?147,34984,35238#msg-35238</link>
            <description><![CDATA[ lol<br />
<br />
Just read what I typed last night, I think my fingers were slurring....]]></description>
            <dc:creator>aka47</dc:creator>
            <category>Firmware - experimental, borrowed, and future</category>
            <pubDate>Sat, 06 Feb 2010 06:15:53 -0500</pubDate>
        </item>
        <item>
            <guid>https://reprap.org/forum/read.php?147,34984,35224#msg-35224</guid>
            <title>Re: Firmware communication protocol : Streaming vs Packets</title>
            <link>https://reprap.org/forum/read.php?147,34984,35224#msg-35224</link>
            <description><![CDATA[ Yeah.  Me too.  I'll add the source I have for ..hmmm..  I'll call it the OlaOneWay protocol (OOW - pronounced, well, like you're in pain, I suppose) given a place to put it, there any special organization rules or tips to follow?<br />
<br />
So far, only tested via host emulation mode, no firmware download yet.  Code size looks to be about 1.5K or so (plus overhead for serial comms.)  (I didn't have the board hooked up, and didn't want to go down to the basement to do so.)<br />
<br />
Uses Inversion of Control concepts, so structure pretty easy to follow (IMHO, easier than explicit state machine tables or structure).., should be easy to tear out the interactive parts, or change the CTRL vs. PRINT to an 8 bit packetized with an escape code sequence for controls... (I originally used a hacked <a href="http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html" target="_blank"  rel="nofollow">'switch/case' coroutine</a> pattern; but, considering the weirdness, and the fact that some C programmers think it is broken code, I switched it to a switch/goto table for reinjecting flow of control back into the yield points.)<br />
<br />
aka47, the manner to go interactive works quite well.. you just hit CTRL-B three times, and it gives you a prompt; Almost brings back the days of "+++" followed by "ATDT", hmm?  :)  I even added a back space, and a reprint line command (CTRL-E).  Could add fancy edit controls pretty easily, just need to define the behavior.  To switch back to crc/window mode, CTRL-A three times does the trick, and it responds with a NAK framing error to let you know where to start sending packets in the sliding window.  By default, it starts out in packet mode, but it might make more sense to start it out in interactive (a host can simply transmit 3 SOH (CTRL-A) characters, grab the current window frame, and start transmitting packets.)<br />
<br />
Currently, the packet mode error diagnostics returned include "NAK id" for a general idle error, "NAK id : frag" for a fragmented / incomplete packet, "NAK id : crc" for a crc error, "NAK id : too long" for a packet with length exceeding the internal maximum packet size, and probably one or two that I'm forgetting.  Any successfully recieved packet will send "ACK id".  All responses terminate with CR LF, but that can be changed by changing a single constant.  On input side, it works with whatever variation of CR and/or LF that you send to it, as long as you're consistent with that pattern.<br />
<br />
I still need to write the host API to interface with the board, but that should be relatively straightforward.]]></description>
            <dc:creator>BeagleFury</dc:creator>
            <category>Firmware - experimental, borrowed, and future</category>
            <pubDate>Sat, 06 Feb 2010 01:07:01 -0500</pubDate>
        </item>
        <item>
            <guid>https://reprap.org/forum/read.php?147,34984,35215#msg-35215</guid>
            <title>Re: Firmware communication protocol : Streaming vs Packets</title>
            <link>https://reprap.org/forum/read.php?147,34984,35215#msg-35215</link>
            <description><![CDATA[ Drop Sebastien an Personnal message from this forum<br />
<br />
He is the guardian of the Wiki, Web and Repository.<br />
<br />
Sebastien will set you up with access to the repository, ask him for space under your own area.<br />
<br />
Last I asked for some stuff he is a touch up to his lugs for approx a week but may be able to do something a little sooner. Ask.<br />
<br />
Hope this helps<br />
<br />
Cheers<br />
<br />
aka57]]></description>
            <dc:creator>aka47</dc:creator>
            <category>Firmware - experimental, borrowed, and future</category>
            <pubDate>Fri, 05 Feb 2010 20:33:02 -0500</pubDate>
        </item>
        <item>
            <guid>https://reprap.org/forum/read.php?147,34984,35192#msg-35192</guid>
            <title>Re: Firmware communication protocol : Streaming vs Packets</title>
            <link>https://reprap.org/forum/read.php?147,34984,35192#msg-35192</link>
            <description><![CDATA[ github seems neat- free for open source projects. sourceforge offer subversion for open source plus a bunch of other services.]]></description>
            <dc:creator>Triffid_Hunter</dc:creator>
            <category>Firmware - experimental, borrowed, and future</category>
            <pubDate>Fri, 05 Feb 2010 16:43:02 -0500</pubDate>
        </item>
        <item>
            <guid>https://reprap.org/forum/read.php?147,34984,35179#msg-35179</guid>
            <title>Re: Firmware communication protocol : Streaming vs Packets</title>
            <link>https://reprap.org/forum/read.php?147,34984,35179#msg-35179</link>
            <description><![CDATA[ I realized last night I am sitting on a tube of mega168 chips, and all the AVR development tools one can desire.  Most of this is wainscoting until I can get an Arduino board made.  The epiphany is that in the mean time I can plug the chip into the STK500 or one of my dragons and test some of what I am suggestion here.  At least up to the point of the USB bridge.<br />
<br />
forgive the slight topic bend,  What would be the best way to make my code available to others?   I have my own web domain.  Currently there are some old code distributions up there that are terribly dated (like an X11 GUI framework for mac OS7.6)<br />
<br />
Most code now seems to be distributed with some sort of CVS package in mind,  This may sound dumb or ignorant,  Is there a preference as to what to use?  A package that I would install on my own domain?  Or does one use a hosting service?  Any recommendations?<br />
<br />
I would like to create a trunk for the pure AVR assembly version of the firmware that I am working on.]]></description>
            <dc:creator>sheep</dc:creator>
            <category>Firmware - experimental, borrowed, and future</category>
            <pubDate>Fri, 05 Feb 2010 16:03:18 -0500</pubDate>
        </item>
        <item>
            <guid>https://reprap.org/forum/read.php?147,34984,35177#msg-35177</guid>
            <title>Re: Firmware communication protocol : Streaming vs Packets</title>
            <link>https://reprap.org/forum/read.php?147,34984,35177#msg-35177</link>
            <description><![CDATA[ Hey as I said you are the man with his fingers on the keyboard, I am not here to argue what I know works.]]></description>
            <dc:creator>aka47</dc:creator>
            <category>Firmware - experimental, borrowed, and future</category>
            <pubDate>Fri, 05 Feb 2010 15:59:02 -0500</pubDate>
        </item>
        <item>
            <guid>https://reprap.org/forum/read.php?147,34984,35155#msg-35155</guid>
            <title>Re: Firmware communication protocol : Streaming vs Packets</title>
            <link>https://reprap.org/forum/read.php?147,34984,35155#msg-35155</link>
            <description><![CDATA[ nophead Wrote:<br />
-------------------------------------------------------<br />
&gt; I wouldn't implement the protocol twice, once in<br />
&gt; binary and then in ascii just for interactive<br />
&gt; debugging with a terminal emulator. I just use an<br />
&gt; interactive Python terminal if I want to talk to<br />
&gt; my machine interactively. E.g.<br />
<br />
Yeah, I might take that route eventually, for nothing else than the extra throughput (8 bits per character vs. ~6 bits per character.)<br />
<br />
In terms of complexity, so far, using Inversion of Control to implicitly define the state machine, the code is actually very short and simple for something similar to my last proposal:<br />
<br />
#define IOC_STATEVAR relyp_state<br />
IOC_DEFINE( ProcessRelyPChar, int inpc, int )<br />
IOC_LOOP()<br />
	// -----------------------<br />
	// start by looking for a framing character, SOH, STX, or CAN<br />
	if( inpc == ASCII_SOH )<br />
	{<br />
		// -----------------------<br />
		// Read in the packet id.<br />
		IOC_YIELD_NEXTEVENT( EVENT_WAITCH );<br />
<br />
		// -----------------------<br />
		// read in the packet length, and initialize CRC<br />
		IOC_VERIFY_WAITCH( AsciiToCode64( inpc ) == expectedHeadId );<br />
		pktCrc = GetCRC( 0, inpc );<br />
		pktLen = AsciiToCode64( inpc );<br />
<br />
		// -----------------------<br />
		// read in second part of packet length.<br />
		IOC_VERIFY_WAITCH( IsCode64( inpc ) );<br />
		pktCrc = GetCRC( pktCrc, inpc );<br />
		pktLen = ( pktLen &lt;&lt; 6 ) + AsciiToCode64( inpc );<br />
		if( !IsCode64( inpc ) )<br />
		{<br />
<br />
////////////////////<br />
// .... ~30 more lines for packet mode operations .....<br />
////////////////////<br />
<br />
	else if( inpc == ASCII_STX )<br />
	{<br />
		// -----------------------<br />
		// STX x3 will enter interactive mode<br />
		IOC_YIELD_NEXTEVENT( EVENT_WAITCH );<br />
		IOC_VERIFY_WAITCH( inpc == ASCII_STX );<br />
		IOC_VERIFY_WAITCH( inpc == ASCII_STX );<br />
<br />
		// Change to interactive non-crc mode.<br />
		while(1)<br />
		{<br />
			while( inpc == ASCII_STX )<br />
			{<br />
				IOC_YIELD_NEXTEVENT( EVENT_PROMPT );<br />
			}<br />
<br />
			// Continue reading characters until a new line or cr.<br />
			pktLen = 0;<br />
			pktPtr = pktBuf;<br />
			while( ( inpc &gt;= ' ' &amp;&amp; inpc &lt;= '~' ) || inpc == ASCII_BS || inpc == ASCII_ENQ )<br />
			{<br />
////////////////////<br />
// .... ~30 more lines for interactive mode ....<br />
////////////////////<br />
<br />
IOC_END( 1 )]]></description>
            <dc:creator>BeagleFury</dc:creator>
            <category>Firmware - experimental, borrowed, and future</category>
            <pubDate>Fri, 05 Feb 2010 12:43:33 -0500</pubDate>
        </item>
        <item>
            <guid>https://reprap.org/forum/read.php?147,34984,35142#msg-35142</guid>
            <title>Re: Firmware communication protocol : Streaming vs Packets</title>
            <link>https://reprap.org/forum/read.php?147,34984,35142#msg-35142</link>
            <description><![CDATA[ I wouldn't implement the protocol twice, once in binary and then in ascii just for interactive debugging with a terminal emulator. I just use an interactive Python terminal if I want to talk to my machine interactively. E.g.<br />
<br />
&gt;python<br />
from hydra import *<br />
hydra = Hydra()<br />
<br />
hydra.goto_xyz(100, 100, 10)<br />
print hydra<br />
<br />
If I want to see the packet contents I just put some print statements in the comms routines to format the data nicely. Less work and duplication and a powerful interactive turing complete command line interface to the machine for free.]]></description>
            <dc:creator>nophead</dc:creator>
            <category>Firmware - experimental, borrowed, and future</category>
            <pubDate>Fri, 05 Feb 2010 11:19:11 -0500</pubDate>
        </item>
        <item>
            <guid>https://reprap.org/forum/read.php?147,34984,35130#msg-35130</guid>
            <title>Re: Firmware communication protocol : Streaming vs Packets</title>
            <link>https://reprap.org/forum/read.php?147,34984,35130#msg-35130</link>
            <description><![CDATA[ anton Wrote:<br />
&gt; What happens if you leave the AVR out of the<br />
&gt; equation, simpy connecting RX with TX?<br />
<br />
Seems like a reasonable question.  I'll give it a try maybe.]]></description>
            <dc:creator>BeagleFury</dc:creator>
            <category>Firmware - experimental, borrowed, and future</category>
            <pubDate>Fri, 05 Feb 2010 09:22:34 -0500</pubDate>
        </item>
        <item>
            <guid>https://reprap.org/forum/read.php?147,34984,35129#msg-35129</guid>
            <title>Re: Firmware communication protocol : Streaming vs Packets</title>
            <link>https://reprap.org/forum/read.php?147,34984,35129#msg-35129</link>
            <description><![CDATA[ Hi aka47,<br />
<br />
Many problems exist with the echo technique you propose:<br />
<br />
- You cannot simply retransmit the byte because firmware cannot distinguish two bytes with the same value transmitted in sequence from a single byte with an error during echo back.<br />
- You cannot simply verify echo worked because if data lost, you must decide how long to wait before assuming the data was lost and retransmitting it.<br />
- Even if you could get an echo corrections scheme to work, it does not play well on the non-realtime aspect of the application code; It could be 2 or 3 seconds between each character if the host decided to start up a virus checker or the user decides to launch a web browser while printing, etc.  It only gets worse when you consider that with some operating systems, large portions of device drivers run in multitasking user space process.  Theoretically, you can mitigate this by switching to an RTOS, or putting the logic into an interrupt driver kernel driver itself.<br />
<br />
Windowing and framing have long successful history at solving this problem.  I don't want to invent something new, but I could not find a simple ASCII oriented protocol that gave just enough reliability for me to use it instead of making up my own.  I still welcome any references to something close enough to what I need (Level 3 X.25 and IP stack seems like overkill, IMHO; level 2 X.25 requires special low level bit injection to escape long sequences of 1 bits and still does not solve the reliable delivery constraint; etc.)<br />
<br />
I currently will not switch away from USB/UART because I have the hardware already, and it works (mostly).  Switching to a more reliable medium has advantage but I do not consider it viable right now.<br />
<br />
And yup, to quote Triffid_Hunter... ring buffers FTW.  :)]]></description>
            <dc:creator>BeagleFury</dc:creator>
            <category>Firmware - experimental, borrowed, and future</category>
            <pubDate>Fri, 05 Feb 2010 09:20:38 -0500</pubDate>
        </item>
        <item>
            <guid>https://reprap.org/forum/read.php?147,34984,35107#msg-35107</guid>
            <title>Re: Firmware communication protocol : Streaming vs Packets</title>
            <link>https://reprap.org/forum/read.php?147,34984,35107#msg-35107</link>
            <description><![CDATA[ And a last one <br />
<br />
The arduino libraries are mostly written as the arduino is designed. ie to be an easy-in to microcontroling targeted at an educational audience.<br />
<br />
Assume they written with a leaning towards educational expediency (as opposed to real time operational efficiency) and they will cause you to fall over less.<br />
<br />
I fell over trying to generate custom waveforms using the PWM library functions and ISR's ( a differnt timer from the one for the PWM I chose was using, but it fell in a heap non the less, and me with it )<br />
<br />
They are improving as more people fall over them and then submit patches and fixes. If you want to be sure and are counting cycles though DIY.<br />
<br />
aka47]]></description>
            <dc:creator>aka47</dc:creator>
            <category>Firmware - experimental, borrowed, and future</category>
            <pubDate>Fri, 05 Feb 2010 06:40:25 -0500</pubDate>
        </item>
        <item>
            <guid>https://reprap.org/forum/read.php?147,34984,35104#msg-35104</guid>
            <title>Re: Firmware communication protocol : Streaming vs Packets</title>
            <link>https://reprap.org/forum/read.php?147,34984,35104#msg-35104</link>
            <description><![CDATA[ Ohhh<br />
<br />
As a slightly related aside.<br />
<br />
RS485 data comms routinely uses byte echoing to check the quality of the data. The echoing is done at the bus rather than the far end echoing the byte that was sent.<br />
<br />
If it is done right the rx is permanently enabled and monitors the bus. Every byte sent is compared to what is echoed back at the bus.<br />
<br />
If two devices try to transmit at the same time the byte will be mangled and the compare will fail. Similarly corruption due to noise is picked up as well.<br />
<br />
Transmission on 485 with multiple stations is routinely packet oriented the protocol can be as slim as header/packet/check, where header contains TX address, RX address Size fo packet and check.<br />
<br />
If you really want robust serial comms use RS485........<br />
<br />
<br />
For ultimate speed of serial comms, I usually use ring buffers RX and TX sized to be a binary increment with the beginning and end pointers external to the buffer. (you don't have to workout where they are to get the info).<br />
<br />
TX. beginning = end =&gt; buffer empty, stop sending, disable tx interrupt (a simple test and quick, no math, all logical operations)<br />
<br />
TX. beginning &lt;&gt; end =&gt; enable send interrupt and let it get on with sending.<br />
<br />
RX interrupt permanently enabled, let it receive something if it is there to recieve<br />
<br />
RX, beginning = end =&gt; nothing to do, return nothing to do from non blocking getch() equivalent.<br />
<br />
Blocking getch() equivalent busy waits for &lt;&gt; below.<br />
<br />
RX, beginning &lt;&gt; end =&gt; something to do, return the char from call whichever you used.<br />
<br />
Non blocking getch() equivalent is important. You don;t have the luxury to wait for it.<br />
<br />
you actually need to get the size so rarely that you calculate it from beginning and end only when you want to know what it is and then do it using logical operators. Making number of chars in the buffers meta-data, it is'nt stored anywahere.<br />
<br />
For operation particularly when you are laying on a protocol, implement your protocol as a state machine. Beware the case statement, on some tool-chains it compiles to more processing cycles than other constructs. Take a look at your assembler listing if you are not sure. (normally an extra command line parameter will throw out an assembler listing from the build process.)<br />
<br />
Trace your state machine through on paper to eliminate races, and lockups.<br />
<br />
For best speed in-line assembler for the ISR's and optimize this for minimum wastage of processing cycles.<br />
<br />
Again, if you know this already, sorry.<br />
<br />
cheers<br />
<br />
aka47]]></description>
            <dc:creator>aka47</dc:creator>
            <category>Firmware - experimental, borrowed, and future</category>
            <pubDate>Fri, 05 Feb 2010 06:08:38 -0500</pubDate>
        </item>
        <item>
            <guid>https://reprap.org/forum/read.php?147,34984,35099#msg-35099</guid>
            <title>Re: Firmware communication protocol : Streaming vs Packets</title>
            <link>https://reprap.org/forum/read.php?147,34984,35099#msg-35099</link>
            <description><![CDATA[ OK<br />
<br />
Echo based error checking.<br />
<br />
The transmitter is responsible for checking that the byte that comes back, is the same as the byte that went (8ni)<br />
<br />
The receiver is responsible for echoing each byte it receives.<br />
<br />
Each end knows when it is Transmitting and Receiving. <br />
<br />
If a byte is lost (which ever way), the transmitter can resend the byte.<br />
<br />
No framing overhead needed.<br />
<br />
Belief is not necessary, I am not preaching a vicar although my posts can be as long as sermons. Try it and see. My advice is based on experience. I will however accept that you don't feel entirely comfortable with something you have'nt tried yet.<br />
<br />
If you are byte checking you are also auto pacing your characters (baud becomes semi irrelevant) simply because you don't send the next until the last has been echoed. (so it must have successfully be received and transmitted at what ever throughput the other end will work at)<br />
<br />
Because you are byte checking (xor and look at result) it is fairly fast. You are also working with binary so the method does'nt care what you are sending. (Binary or Ascii)<br />
<br />
When you use an ASCII protocol you have extra problems sending binary. Put simply you cannot guarantee that in a block of binary there won't be a byte that is exactly the same as a control or sequence of control characters you r protocol is looking for.<br />
<br />
There are two methods to deal with this, both add significantly to the overhead.<br />
<br />
1. You convert binary to an ascii representation (example intel hex) clearly though this lands you with more data to send, higher baud rate lost to more data to send.<br />
<br />
2. You perform an activity known as bit stuffing where transmitted binary blocks are stuffed with bits to remove Binary Bytes that represent control characters. Again you have over head to process and encode then decode at the other end and the gains of higher baud are lost to lower through put.<br />
<br />
<br />
On simplicity, apply occams razor to the above, give it a close shave and see what is left.<br />
<br />
For me the simplest that auto paces and preserves the benefits of higher baud rate is echo based byte checking.<br />
<br />
Ultimately though you are the guy with your fingers on the keyboard, the choice is yours.<br />
<br />
aka47<br />
<br />
PS Triffids advice on speeding up serial comms using binary increments of buffer size and logical math, is very sound. It is what I have done for quite a few years. Ring buffering RX &amp; TX is essential too. Get the basics right then see if you need error detecting and fixing after all. You might be surprised.]]></description>
            <dc:creator>aka47</dc:creator>
            <category>Firmware - experimental, borrowed, and future</category>
            <pubDate>Fri, 05 Feb 2010 05:02:51 -0500</pubDate>
        </item>
        <item>
            <guid>https://reprap.org/forum/read.php?147,34984,35088#msg-35088</guid>
            <title>Re: Firmware communication protocol : Streaming vs Packets</title>
            <link>https://reprap.org/forum/read.php?147,34984,35088#msg-35088</link>
            <description><![CDATA[ <blockquote class="bbcode"><div><small>Quote<br /></small><strong>BeagleFury</strong><br />
My test programs have nothing in them except the comms test. The *only* point of failure is the standard Arduino implementation of the Serial class. There is no heavy maths. No expensive loops. Nothing except a very tight loop checking for serial availability, a buffer save, and an echo back upon  reciept. There is the possibility that the transmittion of data from the motherboard to host disables interrupts, and that could be where the data loss happens; which may imply that we effectively do not have bidirectional UART comms, but a crippled bidirectional / mostly unidirectional comms channel. </div></blockquote>
<br />
What happens if you leave the AVR out of the equation, simpy connecting RX with TX?]]></description>
            <dc:creator>anton</dc:creator>
            <category>Firmware - experimental, borrowed, and future</category>
            <pubDate>Fri, 05 Feb 2010 01:50:12 -0500</pubDate>
        </item>
        <item>
            <guid>https://reprap.org/forum/read.php?147,34984,35087#msg-35087</guid>
            <title>Re: Firmware communication protocol : Streaming vs Packets</title>
            <link>https://reprap.org/forum/read.php?147,34984,35087#msg-35087</link>
            <description><![CDATA[ sheep Wrote:<br />
&gt; I may have been unclear.  The most that should<br />
&gt; ever spin inside the usb buffer is one gcode<br />
&gt; block.<br />
<br />
And if I do not send GCode?  This might be one source of confusion.  Let me restate again -- the firmware I am developing will not accept GCode.  My timings for performing inverse kinematics did not give satisfactory results (&gt;1ms per inverse kinematic computation).  I also feel unacceptable the number of linear segments needed to keep accuraccy to .1mm over the large circular print area of my machine.  See the <a href="http://objects.reprap.org/wiki/RepOlaRap" target="_blank"  rel="nofollow">Wiki</a>, and a few of the video's I've posted to the <a href="http://builders.reprap.org/2010/01/ola-with-two-arms.html" target="_blank"  rel="nofollow">builders blog</a>.<br />
<br />
GCode will feed to a host based application that will compute the spline curves needed to keep accuracy for that GCode to .1mm.  The cubic spline segments will then be fed to the machine.  No M codes.  No G codes, nothing but "Set your 5D position to this point, then follow this sequence of spline segments."<br />
<br />
&gt; The problem with returning Err+id+EOL is that how<br />
&gt; is the user supposed to know what Err-31 is?<br />
<br />
For interactive mode, the user would never see those errors.  They are strictly for CRC packets.  I would expect interactive mode users to watch echo carefully to detect errors.<br />
<br />
Also, no sane user would use interactive mode to actually execute a build for my initial setup.  The computer will be much more effective at computing the multitude of 160 bit spline segments.  I intend on using it only for debugging/diagnosis.<br />
<br />
&gt; I am also unclear as to why 24 bits of CRC?<br />
<br />
Only 16 bits of CRC (well, technically, since I am using base 48, they are 16.75 bits.  :))   The three crc character codes must be printable ascii characters per my requirements to dump / monitor on screen.  16 bit codes require at least 3 8 bit characters.  I only introduce control characters to avoid having to introduce escaping logic for framing signals.<br />
<br />
&gt; The monitor prompt is a good idea, this could put<br />
&gt; the system into executive mode.   I would suggest<br />
&gt; a flexible EOL protocol, where CR OR LF is a an<br />
&gt; eol and the extra event ignored.<br />
<br />
Yep.  That is the plan.]]></description>
            <dc:creator>BeagleFury</dc:creator>
            <category>Firmware - experimental, borrowed, and future</category>
            <pubDate>Fri, 05 Feb 2010 01:43:03 -0500</pubDate>
        </item>
        <item>
            <guid>https://reprap.org/forum/read.php?147,34984,35077#msg-35077</guid>
            <title>Re: Firmware communication protocol : Streaming vs Packets</title>
            <link>https://reprap.org/forum/read.php?147,34984,35077#msg-35077</link>
            <description><![CDATA[ <blockquote class="bbcode"><div><small>Quote<br /></small><strong>BeagleFury Wrote:</strong><br />
Anyway, having thought about this a bit more, I don't believe any kind of echo "error detection" will work properly. Figuring out retransmition and recovery becomes significantly more difficult when the host sends 10 commands as 400-500 bytes get buffered in the bowels of USB drivers and OS streams. If the firmware fails to correctly recieve the first command, all the remaining commands become ticking time bombs if the firmware tries to execute them as if nothing was wrong.</div></blockquote>
<br />
<br />
I may have been unclear.  The most that should ever spin inside the usb buffer is one gcode block.  This at most with a circular interpolation in 3 axises would be something like 30 or 40 bytes. The most characters that could be entered on a teletype line was 72.  This limited the size of the blocks on the old DOS era CNC machines.  Small Packets are better for the USB Bridge chip and USB in general.<br />
<br />
The idea is that the host can not issue the next block until the device returns the block data.  Granted there is some delay, especially if the device is moving, processing the prior block.  I should strongly suggest that data pass-through to multiple processors is essential.  Perhaps I have been influenced by reading Nop's Hydraraptor blog everyday for the last year.  <br />
<br />
In my abstraction, the main device processor, only contains the NC registers, The motor control is done through sub processors.  I use ATtiny25 chips in a player piano valve system, where one processor controls two valves.  The main processor is in effect a latched shift register every 50Khz the latch sets and the lines to the tiny25s change state (if needed.)<br />
<br />
I now think that as part of the ACK the NC counter registers could be returned.  This way a dumb terminal could implement a software DRO.  First the state bits would be returned. Then the axis registers returned.  This could be a large burst of info if the registers are returnd as ASCII encoded decimal.  It might make sense to return the registers in machine units. The actual binary values dumped out of chip registers. Harder to decode by human, smaller packet size.<br />
<br />
The worst case would be to echo the block in the old accounting sheet column format, with line position, this would be 72 characters.  These packet would only be echoed when idle. Is that to much to ask the return channel?  The host would have to poll frequently,  The way the FTDI Bridge chip works, is that there is always data when the host polls the chip.  (see the FTDI BSD/linux driver for details)  Low level Returned packets always start with the Modem state bits, like DTR and CTS.  The high level driver has to strip these out, then combine the buffers and return the characters through the emulated com port. <br />
<br />
The problem with returning Err+id+EOL is that how is the user supposed to know what Err-31 is?  At least with a dumb DRO the led blinks when the limit condition occurs.  This is because there is a dyna lable (see back to the future part one The time computer is a DRO) telling the user this is the condition.<br />
<br />
I am also unclear as to why 24 bits of CRC?  The firmware is loaded with an 8 bit. This is mostly a sanity check anyway.  Again I am an assembly programmer, so the way I do this with MIDI SYSEX messages is to read a byte compare and sum using the same registers.  Since inside the 8 bit device, my resources are limited, I want to tokenize things as soon as possible.  So the CRC is my token.<br />
<br />
The monitor prompt is a good idea, this could put the system into executive mode.   I would suggest a flexible EOL protocol, where CR OR LF is a an eol and the extra event ignored.<br />
<br />
-julie]]></description>
            <dc:creator>sheep</dc:creator>
            <category>Firmware - experimental, borrowed, and future</category>
            <pubDate>Thu, 04 Feb 2010 23:41:18 -0500</pubDate>
        </item>
        <item>
            <guid>https://reprap.org/forum/read.php?147,34984,35076#msg-35076</guid>
            <title>Re: Firmware communication protocol : Streaming vs Packets</title>
            <link>https://reprap.org/forum/read.php?147,34984,35076#msg-35076</link>
            <description><![CDATA[ BeagleFury Wrote:<br />
-------------------------------------------------------<br />
&gt; Okay, looked a little deeper.  Triffid did it<br />
&gt; right; the key was the mention of "both<br />
&gt; directions".. HardwareSerial does not appear to<br />
&gt; use a tx buffer, rather it waits until it can send<br />
&gt; the byte.  This could be a (cpu time wise) very<br />
&gt; long time, and seems to explain some of the data<br />
&gt; loss I saw.. though, it doesn't make sense why it<br />
&gt; would work better when I slowed the rate down,<br />
&gt; unless it was a combination of factors.<br />
&gt; <br />
&gt; How soon before you're comfortable about<br />
&gt; stability, Triffid?  I'd like to take your code<br />
&gt; and plug it in under the Serial class.<br />
<br />
While my serial library does change from time to time to suit my current project, it (and the ringbuffer library it leans on) is extremely stable as I've been working on/with it for a long time. It's just the rest of my current project that isn't so stable ;)<br />
<br />
My ringbuffers are currently 64 bytes in size, with 3 bytes used for head/tail/length so 61 bytes in the ring itself. If you made the size 2^n plus 3, you could indeed use binary AND instead of modulus for many of the operations. You could also remove length entirely if you make all ringbuffers the same size- my code is designed to allow different ringbuffers of different lengths in the same system.<br />
<br />
I <i>had/</i> to make a transmit ringbuffer, otherwise I can't send debug info from interrupt context, without making the interrupts take *ages* to run!<br />
<br />
My latest change to the library involved dealing with a full transmit buffer while in interrupt context. Before, it would lock up waiting for stuff to be read out of the ringbuffer while the transmit complete interrupt went unserviced. Now it just drops the data (what else can we do?)<br />
<br />
Feel free to grab it and shoehorn into your arduino IDE- personally I've never downloaded the arduino software and so have no idea what it looks like or how they've done things.]]></description>
            <dc:creator>Triffid_Hunter</dc:creator>
            <category>Firmware - experimental, borrowed, and future</category>
            <pubDate>Thu, 04 Feb 2010 23:38:45 -0500</pubDate>
        </item>
        <item>
            <guid>https://reprap.org/forum/read.php?147,34984,35069#msg-35069</guid>
            <title>Re: Firmware communication protocol : Streaming vs Packets</title>
            <link>https://reprap.org/forum/read.php?147,34984,35069#msg-35069</link>
            <description><![CDATA[ BeagleFury Wrote:<br />
&gt; Triffid_Hunter Wrote:<br />
&gt; &gt; in both directions. ringbuffers ftw :)<br />
&gt; <br />
&gt; BTW, the arduino Serial instance, derived from HardwareSerial, appears to use a ring buffer (128 byte).<br />
<br />
Okay, looked a little deeper.  Triffid did it right; the key was the mention of "both directions".. HardwareSerial does not appear to use a tx buffer, rather it waits until it can send the byte.  This could be a (cpu time wise) very long time, and seems to explain some of the data loss I saw.. though, it doesn't make sense why it would work better when I slowed the rate down, unless it was a combination of factors.<br />
<br />
How soon before you're comfortable about stability, Triffid?  I'd like to take your code and plug it in under the Serial class.<br />
<br />
<br />
Anyway, having thought about this a bit more, I don't believe any kind of echo "error detection" will work properly.  Figuring out retransmition and recovery becomes significantly more difficult when the host sends 10 commands as 400-500 bytes get buffered in the bowels of USB drivers and OS streams.  If the firmware fails to correctly recieve the first command, all the remaining commands become ticking time bombs if the firmware tries to execute them as if nothing was wrong.<br />
<br />
However, I also believe the flow back to the host will almost certainly always have less critical nature....  the host can ask about what it wants to know, and keep asking until it gets a response that it likes.  This makes things easier because the firmware doesn't have to worry about retransmission to the host; only the other way around.  It also removes the need for a buffering and a window field for the firmware-&gt;host direction.<br />
<br />
So.....  given that...... I'm going try again... simplify simplify simplify, but still solve the problems and address the needs...<br />
<br />
All non-framing characters ascii.  I prefer stuff I can throw into a log file or send to screen, and still make sense of it, without needing ASCII lookup tables, or figuring out if ^X is a carot X or a ctrl X.  A few control characters here and there are fine, especially TAB.  I like tab.  Oh, and I never want to see a NUL... too many ways to break stuff with NUL terminated strings.  CR and/or LF also make good terminator characters; those map to a readable format in a relatively straightforward way.<br />
<br />
So... host-&gt;firmware packet:<br />
<br />
 SOH(^A) id len len crc crc crc TAB(^I) data... LF(^J) and/or CR(^M)<br />
<br />
- id a strictly cyclic increasing printable character; 0-9A-Za-z would  seem to provide a nice big sliding window of up to 62 buffered packets and still be grokable by a human looking at a log file; host could decide how far forward to buffer, up to 62 (could be 1.. could be 62.. configurable probably).<br />
- len : consisting of hexidecimal encoding for the number of characters in the data field.<br />
- crc : a three character encoded 16 bit crc.  48 possible characters (0-9A-Za-l) I believe makes conversion math on firmware side bitshift + integer addition only (x*48 = x*32 + x*16; 48^3 &gt; 2^16)<br />
- TAB : a nice separator between header and data that makes scanning the commands easy when looking at a log file or a live monitor.<br />
- data... : text based commands; firmware parses these similar to how it already operates.<br />
- LF/CR : a nice packet terminator that makes scanning the commands easy when looking at a log file or a live monitor.<br />
<br />
<br />
Any errors, for example, any invalid character, crc invalid, no LF/CR after length data characters, .. etc... anything at all, and the firmware begins transmitting "ERR " + id + CR + LF, where id is the packet id it is expecting to see.    I think send this every few characters it recieves until it gets a sequence it recognizes as the start of a new packet or a reset request (E.G, until it sees SOH, CAN, or STX, and the characters following those look proper and valid.)<br />
<br />
The host can reset the framing by sending a few CAN (CTRL-X) characters.  If the firmware sees three of these in a row, it will discard anything, reset it's window back to '0', and start echoing the CAN characters back to the host.<br />
<br />
A human on a dumb terminal can ask the firmware to enter 'dumb human is my master' mode -- by typing CTRL-B a few times.  After the third one, the firmware will echo CR LF "&gt; " as a prompt.  After this point, the firmware will echo any printable character or back space, and accept as a command if it sees CR and/or LF, followed by CTRL-E (ENQ).  I may be overly paranoid here.. I just want to avoid a false positive.  This also opens up the opportunity to edit the line by entering something else after hitting CR/LF.  In any case, the firmware would execute the command, and then print another prompt.  To get out of this mode, the CAN / CTRL-X sequence would be used.  No other difference would exist between these commands typed by a user, and the commands wrapped in a nice service of delivery packets sent by a host.<br />
<br />
I'm going to see if I can't whip out some working code, both a host API and the firmware logic.]]></description>
            <dc:creator>BeagleFury</dc:creator>
            <category>Firmware - experimental, borrowed, and future</category>
            <pubDate>Thu, 04 Feb 2010 21:35:50 -0500</pubDate>
        </item>
        <item>
            <guid>https://reprap.org/forum/read.php?147,34984,35066#msg-35066</guid>
            <title>Re: Firmware communication protocol : Streaming vs Packets</title>
            <link>https://reprap.org/forum/read.php?147,34984,35066#msg-35066</link>
            <description><![CDATA[ Julie<br />
<br />
I think we may be of a similar vintage....<br />
<br />
Grin<br />
<br />
aka47]]></description>
            <dc:creator>aka47</dc:creator>
            <category>Firmware - experimental, borrowed, and future</category>
            <pubDate>Thu, 04 Feb 2010 20:35:51 -0500</pubDate>
        </item>
        <item>
            <guid>https://reprap.org/forum/read.php?147,34984,35059#msg-35059</guid>
            <title>Re: Firmware communication protocol : Streaming vs Packets</title>
            <link>https://reprap.org/forum/read.php?147,34984,35059#msg-35059</link>
            <description><![CDATA[ <blockquote class="bbcode"><div><small>Quote<br /></small><strong>BeagleFury Wrote:</strong><br />
&gt; You mentioned that echo verification would<br />
&gt; probably be an effective solution.  What technique<br />
&gt; would be used to send data from firmware to host<br />
&gt; without confusing the echo verification?  Some<br />
&gt; form of handshake that lets the firmware respond<br />
&gt; with anything it might have, where the host echos<br />
&gt; it back to firmware to guarantee delivery or<br />
&gt; something like that?  Do you have any good<br />
&gt; illustrative examples to make sense of what you<br />
&gt; might propose?<br />
&gt;</div></blockquote>
<br />
My suggestion is to simply echo the commands,  what was called full duplex, the FTDI serial converter emulates a modem.  This was how a lot of the verification was done back in the BBS days before the nets united under IP.  This is easy to implement with a dedicated stream such as RS232.<br />
<br />
I am not quite sure how this would work when passed through the FTDI USB bridge.  What delays are involved.  USB wants the data formed in packets which can be interlaced and time muliplexed.  Send a byte wait for return is a bit slow.<br />
<br />
One could look at the Bootstrap loader protocols used by the AVR chips.  This is the part in the Arduino represented as AVRDude.  Atmel's representation of the Serial protocol has proven robust.  In effect there are some simple commands which allow the bootloader talker to respond via the serial port.<br />
<br />
You do bring up the question of the backchannel data.  Where the host request data from the device.  <br />
<br />
I have in front of me the 20 year old docs from the DOS CNC program I just upgraded. A quick look through the list of G codes shows that the codes starting with G all do something to the machine, None return information.<br />
<br />
MCodes have some modes for user input,  M60 through 63 are input wait conditions. M70..73 are Monitor conditions. M76..79 service routine interrupts.  The PC-DOS program waited for a key before continuing.  It looks like the service interrupt conditions could be used for limit activities.<br />
<br />
Since tool change was not implemented, the program paused and waited for a new tool.  One could set a tool change Height.<br />
<br />
The monitor conditions are interesting.  These respond to the K column of the ledger sheet, used with the teletype entry of NC code.<br />
<br />
In looking over the manual, the communications protocol is one way.  Nothing is ever returned to the host.<br />
<br />
This would be the simplest implementation.  Treat each NC block as a packet.  <br />
<br />
The difficulty here is that it is hard to tell what an NC machine uses to end a block.  The codes are modal so a G90 code sets the state machine to input. G92 in this implementation pre loads the counter registers.  This can be used to set things like the start position if not zero.  It is stated that G92 is modal and only affects the current block.<br />
<br />
Returning to G00. If this is followed by a character such as X, this will load the X counter register.  The PC-DOS program required line numbers. A non Numeric digit would signal the end of the data entered into the X counter register.  If Y followed X then the Y counter is loaded. This process continues through the symbols ZIJKSF. Each in turn loading the register as needed.<br />
<br />
These letter number combination are called Words. One of the first programs I maintained in college was called NCWord. It emulated the spreadsheet entry on a minicomputer.  When the program was verified it would be punched to paper tape.  There was no connection to the tool other than the paper tape.<br />
<br />
I made a postscript simulator for this PC-DOS Gcode, which used N as the terminal character.  When N was seen, the data for that block was rendered.  In practice any whitespace could signal the end of block.  Gerber uses an '*'<br />
<br />
it is interesting to compare this documentation against the WIKIPedia entry for RS274D.  There is a link to <a href="http://www.linuxcnc.org/handbook/gcode/g-code.html" target="_blank"  rel="nofollow">an EMC2 Gcode tutorial</a> Which give some guidelines as to what makes a block of code.<br />
<br />
My experience of different NC and CNC machines is that the EOL character that terminates the block can be anything.    I have some 30+ years worth of NC code scattered about my computers and backups.  Each "Gcode" file, pretty much only works on the tool it was coded for.<br />
<br />
Even the format of the Word, which is the symbol to load the counter register differs from machine to machine.  Some want fixed point decimal, others leading zero. Some programs set this with a % some with a word that starts with the letter 'O.'<br />
<br />
This may be due to the early state machine architecture of the early NC controllers. Where any function not supported is a savings in hardware, so the machines issue a fault rather than to ignore one of the unsupported Words.<br />
<br />
To get back on implementing a simple robust Gcode channel,  The echo would happen at the end of the block.  Before sending the block the host would calculate a checksum which would be sent following the end of block character.  The device would echo the block and calculate a return checksum.  If the two checksums did not match, then the host could re-send the block.<br />
<br />
The weakness of this is that there could be a delay caused by the re-try. Depending on the CRC chosen for the check-sum, the device could attempt to correct.<br />
<br />
This still does not address the issue if the entire block [USB] packet is lost.  While line numbers on my PC-Dos Gcode are required, on EMC2 they are an option.  The use of line numbers could be a way to detect or even route packets, so they are assembled in order on the device.<br />
<br />
-julie]]></description>
            <dc:creator>sheep</dc:creator>
            <category>Firmware - experimental, borrowed, and future</category>
            <pubDate>Thu, 04 Feb 2010 20:09:39 -0500</pubDate>
        </item>
        <item>
            <guid>https://reprap.org/forum/read.php?147,34984,35055#msg-35055</guid>
            <title>Re: Firmware communication protocol : Streaming vs Packets</title>
            <link>https://reprap.org/forum/read.php?147,34984,35055#msg-35055</link>
            <description><![CDATA[ Hmm sounds remarkably like pacing issues and dodgy library then.<br />
<br />
I found your posts when I checked the thread after writing war and peace, must have taken me so long you guys figured it out anyway. ;)<br />
<br />
aka47]]></description>
            <dc:creator>aka47</dc:creator>
            <category>Firmware - experimental, borrowed, and future</category>
            <pubDate>Thu, 04 Feb 2010 19:05:22 -0500</pubDate>
        </item>
        <item>
            <guid>https://reprap.org/forum/read.php?147,34984,35054#msg-35054</guid>
            <title>Re: Firmware communication protocol : Streaming vs Packets</title>
            <link>https://reprap.org/forum/read.php?147,34984,35054#msg-35054</link>
            <description><![CDATA[ Triffid_Hunter Wrote:<br />
-------------------------------------------------------<br />
&gt; I adjusted my code to set that, gave it a whirl<br />
&gt; and lost not a single bit over several k of data<br />
&gt; in both directions. ringbuffers ftw :)<br />
<br />
BTW, the arduino Serial instance, derived from HardwareSerial, appears to use a ring buffer (128 byte).<br />
<br />
Triffid, how does your code compare?  Did you look at the arduino-0017/hardware/cores/arduino/HardwareSerial .h / .cpp file before writing your own?<br />
<br />
There is definitely a lot of room to improve there though.. for example, the available() method uses a % operator, and the compiler doesn't seem smart enough to figure out that %128 ~== &amp;127;  sheesh.  Okay, I might be tweaking that libray a little then.]]></description>
            <dc:creator>BeagleFury</dc:creator>
            <category>Firmware - experimental, borrowed, and future</category>
            <pubDate>Thu, 04 Feb 2010 19:00:27 -0500</pubDate>
        </item>
    </channel>
</rss>
