In steps I set the delay down to '3' from '45' and it was robust - didn't hang. One ( '1' ) seemed to be the breaking point.
I think the other changes you made were more responsible for the robustness than you saw! Good Work!
I saw nothing but reliable transmission taking the delay down to that point and if you could show me an example that breaks at 9 or half of that I'd like to understand it. If you wanted to stick with a higher number - I'd offer you add a version of USB.begin that takes an optional parameter [Unsafe(4), Fast (9), Quick (15), Slow (25), Glacial (45 )].
The edge cases I found are no longer a problem. And I even got to add generous debug newlines and verbiage to explain what was spewing forth, and with just a few 'in case' refreshes nothing I did broke the code, except for taking the Delay to '1'.
I took my code, hooked into the delay in the library. Added a watch for '_' to programmatically drop the delay from 45 in steps to minimize boredom. And I altered the code to do EACH one of the abusive tests I found to fail in turn on the '_' and an added '*' key test and could repeat the test at will. Other test keys still active, but I preset their values above where they used to fail {~.?.>}. Enter the dual alphabet and results are consistent down to under delay of 4 you see an extra clipped character.
Put this on a Pro (make indicated DIGICDC changes in top comments)- start the monitor - push the following characters between the commas in turn and then repeat - no spaces: ENTER, *ENTER, ENTER, _ENTER
You see increasing speed and consistent output. Push * again to make no changes but watch it cycle to look for loss or hang.
Results Summary:
[[time>38433 <time::delay>45<delay]]]
[[time>5930 <time::delay>5 <delay]]]
This is the same testbed code from before tweaked for presets and automation aid - generous use of delay and refresh - at least enough so it never dies. ANd I safely added more Print and PrintLn calls.
#include <DigiCDC.h> // #include <DigiCDCC.h>
// ADD TO DIGICDC.cpp :: int CDCvDelay = 45; /* used to expose the OuchWait */
// Change this line that held 45:: DigiCDCDevice::delay(CDCvDelay); //ouch its slow but it ensures it will work no matter how long of a string is thrown at it
extern int CDCvDelay;
void setup() {
// initialize the digital pin as an output.
SerialUSB.begin();
SerialUSB.refresh();
pinMode(1, OUTPUT); //LED on Model A or Pro
blink_swap(700);
blink_swap(700);
SerialUSB.print("CDC Tst"); // Need long wait to see on PC Serial Monitor
blink_swap(700);
CDCvDelay = 45;
SerialUSB.print("CDC TST"); // Need long wait to see on PC Serial Monitor
}
char astring[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
bool blinkState = 0;
void blink_swap( int wait ) {
if (blinkState && 7 < wait) {
blinkState = 0;
digitalWrite(1, LOW);
}
else if ( 0 == blinkState && 7 < wait) {
blinkState = 1;
digitalWrite(1, HIGH);
}
while ( 10 <= wait ) {
SerialUSB.delay(10); // keep usb alive // can alos use SerialUSB.refresh();
wait -= 10;
}
if ( 0 < wait ) {
SerialUSB.delay(wait); // keep usb alive // can alos use SerialUSB.refresh();
}
}
int CntTildas = 20; // ~
int CntQues = 20; // ?
int CntAlpha = 30; // >
// the loop routine runs over and over again forever:
void loop() {
int sr;
unsigned long SeeStar = 0;
unsigned long time;
time = 0;
while (SerialUSB.available()) {
if ( 0 == time ) time = millis();
sr = SerialUSB.read();
SerialUSB.write(sr);
if (65 <= sr && 90 >= sr) sr = sr + 32;
else if (97 <= sr && 122 >= sr) sr = sr - 32;
SerialUSB.refresh();
if ('~' == sr) SerialUSB.write(48 + CntTildas);
if ('?' == sr) SerialUSB.print( CntQues );
if ('>' == sr) SerialUSB.print( CntAlpha );
if ('*' == sr) {
SeeStar = millis();
blink_swap(5);
SerialUSB.print(&astring[0]);
blink_swap(5);
}
SerialUSB.refresh();
SerialUSB.write(sr);
blink_swap(5);
// When it clips the string it typically keeps working on the next echo
if ('_' == sr || SeeStar) {
blink_swap(8);
if ( 0 == SeeStar ) {
if ( 40 < CDCvDelay ) CDCvDelay = 25;
else if ( 18 > CDCvDelay ) CDCvDelay -= 2;
else CDCvDelay -= 10;
SeeStar = millis();
}
SerialUSB.print( CDCvDelay );
SerialUSB.print("<del");
blink_swap(8);
SerialUSB.print(&astring[0]); // Need long wait to see on PC Serial Monitor
}
if ( '~' == sr || SeeStar ) {
for ( int ii = 0; ii < CntTildas; ii++ ) {
SerialUSB.print("C~C");
SerialUSB.refresh();
SerialUSB.print( ii );
SerialUSB.refresh();
}
if ( 0 == SeeStar ) CntTildas++;
blink_swap(5);
}
if ( '?' == sr || SeeStar ) {
for ( int ii = 0; ii < CntQues; ii++ ) {
SerialUSB.print("C?C");
blink_swap(8);
SerialUSB.print( ii );
SerialUSB.refresh(); // even with refresh() here at tilda
}
if ( 0 == SeeStar ) CntQues++;
}
if ( '>' == sr || SeeStar ) {
blink_swap(5);
for ( int ii = 0; ii < CntAlpha; ii++ ) {
if ( 27 > ii ) SerialUSB.write(ii + 65);
else SerialUSB.write(ii + 97);
if ( CntTildas ) SerialUSB.refresh(); // even with refresh() here at tilda
}
blink_swap(5);
SerialUSB.print("CDC > TST"); // Need long wait to see on PC Serial Monitor
blink_swap(10);
if ( 0 == SeeStar ) CntAlpha++;
}
}
// SerialUSB.delay(10); // keep usb alive // can alos use SerialUSB.refresh();
blink_swap(10);
if ( time ) time = millis() - time;
if ( 5 < time ) {
SerialUSB.println("]END[");
SerialUSB.refresh(); // even with refresh() here at tilda
SerialUSB.print("[[time>");
SerialUSB.refresh(); // even with refresh() here at tilda
SerialUSB.println( time );
SerialUSB.refresh(); // even with refresh() here at tilda
SerialUSB.print("<time::del>");
SerialUSB.refresh(); // even with refresh() here at tilda
SerialUSB.print( CDCvDelay );
SerialUSB.refresh(); // even with refresh() here at tilda
SerialUSB.println("<del]]]");
SerialUSB.refresh(); // even with refresh() here at tilda
}
}