Author Topic: DigiCDC  (Read 28433 times)

danowar

  • Newbie
  • *
  • Posts: 12
DigiCDC
« on: December 05, 2014, 04:15:48 pm »
I am trying to use the Echo example from the DigiCDC.  After I upload, the Digispark Pro reboots, then comes up an "Unrecognized USB Device" error.  Checking the device managers show it as an "Unknown USB Device (Invalid COnfiguration Descriptor)".

I have reinstalled the drivers from the newest Digistump1.5addons-v092, same results. 

I have 64 bit Windows 8.1.

Any suggestions?

defragster

  • Sr. Member
  • ****
  • Posts: 467
Re: DigiCDC
« Reply #1 on: December 25, 2014, 12:36:30 am »
I just loaded the example in the 1.5.8B drop and it compiles and runs as provided - what you type is echoed back. 

Exception is the The ‘SerialUSB.println("CDC Test");’ in setup() never prints.

I added a ‘SerialUSB.write("_");’ in the loop and it prints after each char, but it works more often without this.  Putting this outside the loop for incoming characters never works.

Then add in ‘SerialUSB.println("CDC Test");’ in loop() never prints, and then the echo stops feeding back.

Serial Monitor echoes nothing or will hang intermittently
o   Sending longer strings sometime works, sometimes get clipped, sometimes it stops working then
o   When 'hung' Punching ‘reset’ closes the serial monitor and releases the IDE

I think I need to reboot now my USB stopped connecting for CDC usage as the port doesn't show after the device is not recognized, but I can put out new code?

Edit(1/6/15): unplugging Pro's and waiting 5 minutes recently has let it see them connect/upload.  It seems multiple Pro's and or rapid connect disconnect confuses Win 7 driver and USB detection.  You can typically get away with quick compile/upload/repeat - but when I was trying to swap multiple Pro units on my Serial test pair I got it confused, had too much open to reboot - ate dinner with no Pro connected - and then it worked, another time I was busy 5 minutes and it came back to working.
« Last Edit: January 06, 2015, 12:44:38 am by defragster »

defragster

  • Sr. Member
  • ****
  • Posts: 467
Re: DigiCDC
« Reply #2 on: December 26, 2014, 10:46:58 pm »
Underlying updates are coming - see this Thread as it has the focus:
http://digistump.com/board/index.php/topic,1519.15.html
« Last Edit: December 26, 2014, 11:03:29 pm by defragster »

defragster

  • Sr. Member
  • ****
  • Posts: 467
Re: DigiCDC
« Reply #3 on: January 05, 2015, 01:07:18 am »
I got this larger example to work - with Write and case swap 2nd Write reliably.

This is a simple sample with two variables I count but RAM usage is  "Global variables use 233 bytes of dynamic memory".  USB must be a HOG as the OLED sample is running under 175 bytes with more user variables.

With WHILE rather than IF and short delay [in blink] I can get only about 37 characters to print from a message, then it clips.

Added LED Blink to show loops and activity, brightens during transfer.

Enter a Tilda '~' and the print happens and the light blinks and it prints the '~~' as expected, then the Serial monitor (and Phone) dies after making any other entry and you cannot close it until the Pro is reset. HOWEVER the heartbeat blink continues?


Code: [Select]
  SEE UPDATED CODE BELOW
« Last Edit: January 05, 2015, 02:44:31 am by defragster »

defragster

  • Sr. Member
  • ****
  • Posts: 467
Re: DigiCDC
« Reply #4 on: January 05, 2015, 01:33:28 am »
In the loop's while if you zero this blink_swap(0);  wait it HANGS - you need the wait that is in the blink to be non-zero!
But make it blink_swap(1); or (5) and it works the same and you get 37 or 38 characters echoed before it clips
A SerialUSB.refresh(); alone will not keep USB alive - it requires calls to     SerialUSB.delay(>0) as indicated and shown.

With or without the second Write of the incoming character the limit is the same < 38 characters before clipping

Doing second print in setup() hangs the serial Monitor with now output, but the BLINK heartbeat runs.
  // SerialUSB.print("CDC Test"); // Print twice and Serial Mon HANGS until reset, though Blink heartbeat runs

I modified '~' print to print only 3 characters "CDC".  And the first '~' it prints NONE, then adds one each time it sees the '~'.  It works for NONE, 1 and 2 tildas - i.e the first second and third '~' - then it kills USB but the HeartBeat still runs.

*Note USB / Serial Monitor will never get another echo after too much Write, but it only hangs when you try to send another message after that.

I will update my current code in the prior message.
« Last Edit: January 05, 2015, 01:36:01 am by defragster »

defragster

  • Sr. Member
  • ****
  • Posts: 467
Re: DigiCDC
« Reply #5 on: January 05, 2015, 03:20:54 am »
I got it to kill USB with a heartbeat alive as noted before when Tildas were entered.  But those prints were with no refresh() or delay() - those are time dependent issues, so I thought to add them to my Looping as shown in the code below.

The following two keys when entered do a print("C~C") or print("C?C") in an incremented loop each time pressed:
'~' (tilda): Shows # of times pressed before as it is echoed with a digit counter as it stops after 3-4, adding a refresh() did not help
'?' (question): Shows # of times pressed before as it is echoed with an 'ALPHA' counter (A is zero) as it stops after 10 to 26 times [or more sometimes] where a delay() has been added between each iteration.

This is only increment of three characters per print() with a break in between.

*NOTE: I had a code error in the Blink wait where the minimum was delay(10) - I have adjusted that and documented in the code, waits "tested" under 5 were actually 10, under 5 is prone to USB hanging even during the while send receive while() - though 8 seems good and in fact allows about 10 more characters per ECHO in the while().
*NOTE: Heartbeat never stops so the code is looping.  When more than 35 now 45 characters are clipped in the output, the next echo works.  When the print() hangs the USB, the next echo freezes the IDE.

Code: [Select]
[/#include <DigiCDC.h>
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);
  SerialUSB.print("CDC TST"); // Need long wait to see on PC Serial Monitor
  // SerialUSB.println("CDC Test 2"); // println hangs serial monitor, though Blink heartbeat runs
  // SerialUSB.print("CDC Test"); // Print twice and Serial Mon HANGS until reset, though Blink heartbeat runs
}

bool blinkState = 0;
void blink_swap( int wait ) {
  if (blinkState && 10 < wait) {
    blinkState = 0;
    digitalWrite(1, LOW);
  }
  else if ( 0 == blinkState) {
    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 = 0;
int CntQues = 0;

// the loop routine runs over and over again forever:
void loop() {
  int sr;
  while (SerialUSB.available()) {
    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.write(65 + CntQues);
    SerialUSB.refresh();
    SerialUSB.write(sr);
    blink_swap(5); // This must be larger than 1 or it hangs USB, 5 seems to allow 45 characters without loss/clipping
    // When it clips the string it typoically keeps working on the next echo
    if ( '~' == sr ) {
      for ( int ii = 0; ii < CntTildas; ii++ ) {
        SerialUSB.print("C~C"); // Enter a '~' 3-4 times and the Monitor Freezes, heartbeat Alive
        SerialUSB.refresh(); // even with refresh() here at tilda
      }
      CntTildas++;
      blink_swap(5);
    }
    if ( '?' == sr ) {
      for ( int ii = 0; ii < CntQues; ii++ ) {
        SerialUSB.print("C?C"); // Enter a '?' 10-14-19-26 or more times and the Monitor Freezes, heartbeat Alive
        blink_swap(8); // at wait(5) it hangs USB after about 6 "?" at wait(8) it runs about 6-8 "?" but I did see 24
      }
      CntQues++;
    }
  }
  //  SerialUSB.delay(10);               // keep usb alive // can alos use SerialUSB.refresh();
  blink_swap(10);
}
code]
« Last Edit: January 05, 2015, 03:22:40 am by defragster »

defragster

  • Sr. Member
  • ****
  • Posts: 467
Re: DigiCDC
« Reply #6 on: January 05, 2015, 03:38:58 am »
Just realized this note was in another thread.  I found a free ANDROID terminal program that will OTG connect this CDC app - I tried a few and this was the best.

Though after my latest changes it will connect but no longer works to echo anything?  It used to echo the start strings as it connected faster than the IDE serial monitor, now nothing.

what I added: longer setup() delay and setup prints, shorter delay per character in the while loop - not going to debug this now as it repros real PC issues as documented and worked with simple version.

This APP:: https://play.google.com/store/apps/details?id=jp.ksksue.app.terminal has a decent UI and No Ads - no weird permissions.  Menu/Setting/Serial::Set to baud=57600, 8data, no=parity, 1=stop.

The App often Faults on reconnect - more than once.  Hit Menu/Open Device.  Sometimes it takes a few tries to reconnect and a menu / Close Device.

defragster

  • Sr. Member
  • ****
  • Posts: 467
Re: DigiCDC
« Reply #7 on: January 05, 2015, 03:32:22 pm »
If anyone is working on the CDC library - or improvements are pending let me know I can pre-test (even flash bootloader if needed).  I can rewrite my code to incorporate my Serial debug output it there are any values that would help tune this - Since the heartBeatBlink survives I should be able to expose info on serial.  My summary 'feel' for what I've hit follows - as noted this CDC hogs RAM so I can't power an OLED.  I hope the CDC RAM load can be dropped - though the code is only one third as big as current OLED.

I plugged and programmed a 2nd Pro with this CDC app to make sure my results repeated.  It behaved similarly – but hung on lower counts than documented on the other Pro.  And on a second phone the current app also fails to echo after it connects.

> The problem seems timing related if the delay() is not big enough or often enough, and a refresh() does nothing to help.
> The worst part about timing is that printing under 10 characters is too much, and you often cannot print a string in smaller pieces
> Even in groups of three characters – 9 characters is too much with a refresh() each three.
> Delay() helps extend that, but not consistently and not infinitely – sometimes 5 or 10 groups of 3 even with delay() stops USB dead
> I added a heartbeat blink and it never stops even when USB stops dead, so the user sketch is loop()’ing.

PROBLEM: The CDC app is a memory HOG!  I have just a few variables and get this on compile: Global variables use 251 bytes of dynamic memory.
That is way more than my OLED example that might be near 175 with a similar number of variables (now that I have F(strings) ) .

defragster

  • Sr. Member
  • ****
  • Posts: 467
Re: DigiCDC
« Reply #8 on: January 06, 2015, 01:25:00 am »
The one Android terminal app presented this view of the OTG connected PRO in case it adds anything about how the device is seen I'll post it.

Quote
Device ID: 3003
Device Name: /dev/bus/usb/003/003
Device Class: Communications and CDC Control
Device Sub Class: Unspecified
Device Protocol: 0
Vendor ID: 5840
Product ID: 2174
USB Version: 16.1
Product Version in BCD: 0.1
Serial: null
Interface Count: 2

-----------------------------------------------
Interface ID: 0
Interface Class: Communications and CDC Control
Interface Sub Class: Communications and CDC Control
Interface Protocol: 1
Interface Endpoint Count: 1

======================================
Endpoint Number: 3
Endpoint Address: 131
Endpoint Direction: IN
Endpoint Interval: 255
Endpoint Max Packet Size: 8
Endpoint Type: Interrupt endpoint type
-----------------------------------------------
Interface ID: 1
Interface Class: CDC-Data
Interface Sub Class: Unspecified
Interface Protocol: 0
Interface Endpoint Count: 2
======================================
Endpoint Number: 1
Endpoint Address: 1
Endpoint Direction: OUT
Endpoint Interval: 0
Endpoint Max Packet Size: 8
Endpoint Type: Bulk endpoint type
======================================
Endpoint Number: 1
Endpoint Address: 129
Endpoint Direction: IN
Endpoint Interval: 0
Endpoint Max Packet Size: 8
Endpoint Type: Bulk endpoint type

defragster

  • Sr. Member
  • ****
  • Posts: 467
Re: DigiCDC
« Reply #9 on: January 08, 2015, 01:17:03 am »
There is a CDC update on github.  It is more robust and in general passes the chokepoints noted before as far as I checked, but seems glacially paced now – 9.3 times slower.

It does fail the simple echo test after fewer characters echoed, and it does it 9.3 times more slowly.  To quantify I have serial output from two runs on the same Pro.  I renamed and setup the 'updated' cdc library as DigiCDCC so I could alternate compiles.  The new library is generally more robust – to get this output I had to tweek the desired changes to print to work around where the 1.5.8B library would HANG trying to print debug to the CDC terminal.
> neither library HANGS on this test – they just abort/clip at different spots
> I removed unused code from prior example
> this demonstrates the ‘perceived’ performance slow down on the sample ECHO sample

I manipulated my prior code to time the while (SerialUSB.available()) loop and print out the millis() used in the loop.  Only the library is different for the same sketch (see commented #include).  What the following shows is that for the user input of 'ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ':

> pending library clips the write after 34 characters printed double  (missed the "Hh" )
> pending library consumes 3.752 seconds in the loop to generate this output
> pending library blank ‘enter’ takes 215 millis

> 1.5.8B library clips the write after 37 characters printed double (missed the "Kk" )
> 1.5.8B library consumes 0.402 seconds in the loop to generate this output
> 1.5.8B library blank ‘enter’ takes 20 millis


----CDCC (pending github) –blank enter is 215milis --- 3,752millis to ABORT [clips after 2nd G ]  a-z.a-z::--------------------------
215AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz..AaBbCcDdEeFfGgNn3752
----CDC (1.5.8B) –blank enter is 20milis ---- 402millis to ABORT [clips after 2nd J ]  a-z.a-z::--------------------------
 20AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz..AaBbCcDdEeFfGgHhIiJjNnOoVv402 

Code: [Select]
#include <DigiCDC.h>    // 1.5.8B release CDC library
// #include <DigiCDCC.h>  // github pending CDC library 1/8/2015

void setup() {
  // initialize the digital pin as an output.
  SerialUSB.begin();
  SerialUSB.refresh();
  pinMode(1, OUTPUT); //LED on Model A  or Pro
  blink_swap(1500);
  SerialUSB.print("CDC TST"); // Need long wait to see on PC Serial Monitor
}

bool blinkState = 0;
void blink_swap( int wait ) {
// blinks under 8 don't change the LED state so it will stay bright/off during USB I/O loop, otherwise it pulses
  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();
}

// the loop routine runs over and over again forever:
void loop() {
  int sr;
  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();
    SerialUSB.write(sr);
    blink_swap(5); 
    // When it clips the string it typically keeps working on the next echo
    blink_swap(5);
  }
  if ( time ) time = millis() - time;
  blink_swap(10);
  if ( 5 < time ) SerialUSB.print( time );
}
« Last Edit: January 08, 2015, 01:58:04 am by defragster »

digistump

  • Administrator
  • Hero Member
  • *****
  • Posts: 1465
Re: DigiCDC
« Reply #10 on: January 08, 2015, 01:50:58 pm »
You're just running into the computer filling the buffer faster than the Pro can empty it and running out of buffer - this is exacerbated by the fact that the new library is slower to write (not to read) and you are doing double the writes as reads.

These limitations apply to all serial but are way more apparent here because of the speed. I'm sure it can be sped up from where it is now with more clever knowledge of v-usb, but I'm going with what is most stable since this is designed mostly for short infrequent messages or control signals.

That said it will never be able to print an endless string of all-at-once input - but even in its current very slow speed state you can send 10 chars to it every say 250ms and have it echo back without issue (I'm sure you can do more/less delay - that's just an example) - so in short your test shows the buffer to timing limitation correctly, but it is not a bug, just a limitation of this type of software implementation.

If you want to mess with the speed for fun - look in DigiCDC.cpp and change the delay in the write - but we'll be sticking with this slow version (unless someone dives in and comes up with a better method than delay) because it works across all of our test devices even when print and println are used.

Thanks for your testing!

defragster

  • Sr. Member
  • ****
  • Posts: 467
Re: DigiCDC
« Reply #11 on: January 09, 2015, 03:30:09 am »
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.

Quote
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.

Code: [Select]
#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
  }
}

« Last Edit: January 09, 2015, 03:31:42 am by defragster »

JeffRand

  • Newbie
  • *
  • Posts: 44
Re: DigiCDC
« Reply #12 on: January 09, 2015, 01:39:06 pm »
Like the original poster indicated, I also have Windows 8.1 64 bit, and I'm having the same issue with Invalid Configuration Descriptor. Looks like a problem related to the drivers, but I have no idea how to fix.

defragster

  • Sr. Member
  • ****
  • Posts: 467
Re: DigiCDC
« Reply #13 on: January 10, 2015, 02:02:55 am »
I've put some time into the CDC sketch and the pending release is VERY ROBUST and good.  Though it gets touchy when using F("txt")!  My prior test sample code runs great without F() and I forked the library to run fast with 'native' text.  But I have to cut the sample way back to see F() work at all - and then it needs to slow down the USB output on those transfers.  Posted my findings to Digistump for review.

F() usage adds a good deal 1.6K of code to the Sketch, and all that code is busily working to get you that text separate from the code, and into ram to use.


defragster

  • Sr. Member
  • ****
  • Posts: 467
Re: DigiCDC
« Reply #14 on: January 10, 2015, 11:12:42 am »
Looking into PROGMEM - pulling user strings from FLASH I found an example that works full speed like RAM text, on longer strings.  Drops RAM usage, does not use F(), is just a bit less handy that direct strings or F() - but seems way more reliable.  See example below - I did not try this on the 1.5.8B code but on the 1/7/15 Github. [ @EK: using DigiCDCDevice::delay(9); in DigiCDC.cpp ]

based on http://forum.arduino.cc/index.php?topic=110307.0

Code: [Select]
#include <DigiCDC.h>

const char HEADER[]  PROGMEM  = { "-A--B---C----D-----E=A==B===C====D=====E"};
const char HEADER2[]  PROGMEM  = { "C*C_0123456789_0123456789_"};
const char HEADER3[]  PROGMEM  = { "CDC TST begin()"};
const char HEADER4[]  PROGMEM  = { "CDC > TST loop."};
__FlashStringHelper* HP_columns = (__FlashStringHelper*)HEADER;
__FlashStringHelper* HP_digits = (__FlashStringHelper*)HEADER2;
__FlashStringHelper* HP_begin = (__FlashStringHelper*)HEADER3;
__FlashStringHelper* HP_loop = (__FlashStringHelper*)HEADER4;

void setup() {
  SerialUSB.begin();
  SerialUSB.refresh();
  pinMode(1, OUTPUT); //LED on Model A  or Pro
  blink_swap(2000);
  SerialUSB.println(HP_begin); // Need long wait to see on PC Serial Monitor
  blink_swap(10);
}

bool blinkState = 0;
void blink_swap( int wait ) {
  if (blinkState && 7 < wait) {
    blinkState = 0;
    digitalWrite(1, LOW);
  }
  else if ( 0 == blinkState ) {
    blinkState = 1;
    digitalWrite(1, HIGH);
  }

  while ( 10 <= wait ) {
    SerialUSB.delay(10);               // keep usb alive
    wait -= 10;
  }
  if ( 0 < wait ) {
    SerialUSB.delay(wait);               // keep usb alive
  }
}

int AUTORUN = 1;
// the loop routine runs over and over again forever:
void loop() {
  int sr;
  bool SeeStar = 0;
  if ( AUTORUN ) sr = '*';
  if ( AUTORUN || SerialUSB.available() ) {
    if ( SerialUSB.available() ) {
      sr = SerialUSB.read();
      if ( '*' == sr ) {
        if ( AUTORUN ) AUTORUN = 0; else AUTORUN = 1;
      }
    }
    SerialUSB.write(sr);
    SerialUSB.refresh();
    if ('*' == sr) SeeStar = 1;;
    SerialUSB.refresh();
    if ( SeeStar ) {
      blink_swap(5);
      for ( int ii = 0; ii < 12; ii++ ) {
        if ( 10 > ii ) SerialUSB.print("C?C"); else SerialUSB.print(HP_digits);
        blink_swap(5);
        SerialUSB.print( ii );
        SerialUSB.refresh(); // even with refresh() here at tilda
      }
      blink_swap(5);
      SerialUSB.print(HP_loop);
      blink_swap(10);
    }
  }
  if ( 0 == SerialUSB.available() ) {
    SerialUSB.println (HP_columns);
    blink_swap(10);
  }
}


Quote
RUNNING SKETCH: looks for and echos input strings in an IF() not WHILE() pass through loop()
   It starts in ‘*’ auto run mode – just does a group of USB.print
   ‘ENTER’ any text and it is echoed and then the testing resumes
   Enter ‘*’ and it toggles AUTORUN, when off only does SerialUSB.println (HP_columns);