Author Topic: Debugging Output over USB Serial  (Read 6301 times)

cborn

  • Newbie
  • *
  • Posts: 11
Debugging Output over USB Serial
« on: February 19, 2015, 10:17:50 pm »
While trying to debug my nRF24 wireless boards I saw that there was a radio.printDetails() call that sent lots of useful information to stdout.

To get hold of this, I added some calls to my code to redirect stdout to the USBSerial device.

Monitoring this output (on a Windows 7 box) was a bit difficult, as the USB COM port disappeared as the program was uploaded, then came back (usually), but nothing was then attached to read it.

To get around this, I wrote a program (In C#, as a bit of a learning exercise), which watches for the insertion of the Digispark USB serial device, then connects to it and displays the data received. It automatically closes/opens as the device is removed/added, and will follow it around if it changes COM port names due to attaching to different USB ports.
It isn't perfect and doesn't always attach, which seems to be due to windows getting confused with multiple USB device insertion/removal events, but it is getting there!
Required .Net 4, no installer or source as yet but I can add depending on interest.

See SerialDebug.exe inthe attached zip archive.
I've also put my wireless test program into the archive file.

The basic stdout redirect looks like this:

Code: [Select]
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include <DigisparkOLED.h>
#include <DigiCDC.h>
#include <Wire.h>
#include <stdio.h>

// This function writes a character to the USB Serial device.
// We can use it to provide a stdout stream to that device
int usbser_putchar(char c, FILE *stream) {
    if (c == '\n') {
        usbser_putchar('\r', stream);
    }
    SerialUSB.write(c);
    return c;
}

// We will use this to replace stdout
static FILE *usbser_output;

void setup() {
  // put your setup code here, to run once:
 
  // Here we start the USB serial device
  // Then we replace stdout with a stream to that device
  SerialUSB.begin();
  usbser_output = fdevopen(usbser_putchar,NULL);
  stdout = usbser_output;
}


void loop() {

// Print to stdout, appears on PC monitor program
printf("=== Debug Test! ===\n");
        delay(1000);

}

defragster

  • Sr. Member
  • ****
  • Posts: 467
Re: Debugging Output over USB Serial
« Reply #1 on: February 19, 2015, 11:50:41 pm »
Nice,  I'd like to see the windows source if I could.

There is a known windows driver issue from forever, to be fixed in windows 10. Having open serial usb to a device that goes away orphans the port. Seen with most anything using the arduino ide serial monitor.  There are ways to minimize and sounds like you found one.

I posted here about using serial to serial with two pro units so I could keep the unneeded fat usb it off my primary unit.   I found how to muck up my pro units, rather than reflashing them and moving on I sent them to the factory for pending analysis that will hopefully lead to a future inability to brick them as I did. I got as far as pro1 sending lines to pro2 that dumped them on oled. When dumping copious 9dof data and trying to control displayed line, rather than having it scroll is when I made my four brick like in unique ways I thought. I was pushing a full stream at 115kbps with minimal waits reading all 9dof data channels and debugging some dropped data,  sending dummy 5 digits for each value.  The backlog was coming from the data delay pushing to the oled, like serial it uses two pins,  but the control bytes add about 4x+ to that part. I added a ring buffer on serial input that grew to fixed size and never had time to empty.  I tried to optimize the char writes to oled and saw net zero change.  That problem remains with the data I was pushing, could drop the baud or send less to hide the symptom,  but that impacts the host.  My next step was to pipe that serial data out usb from the debug client.  With your code I could try to emulate the oled lines and place data on reserved lines and then scroll anything else.  So gyro etc values update in place rather than forever scrolling.

cborn

  • Newbie
  • *
  • Posts: 11
Re: Debugging Output over USB Serial
« Reply #2 on: February 20, 2015, 12:02:52 am »
Nice,  I'd like to see the windows source if I could.

No problem, attached.
I have to add the disclaimer that this code is in no way ready for release, being just a quick hack with no comments, various test approaches left partially in or commented out,  etc etc!
If could feed back any fixes or improvements that would be good, too.

defragster

  • Sr. Member
  • ****
  • Posts: 467
Re: Debugging Output over USB Serial
« Reply #3 on: February 20, 2015, 01:52:51 am »
The EXE is Good - I can run two copies.  I did my own build and it also works (2 warnings)  Each can connect to a unique device.  Beginning of a perfect solution - Thanks for sharing, you've given me a great start!

It has a usable interface and it functions!  In fact if I put "Teensy" in the Match location it detects the droppage and auto reconnects.  My problem is I have (2) attached with the same name.  On enumerating with failure it finds the second working unit and tries to own that one when it updates the lblPort.  More issues but it could be solved.  It does then reconnect when lblPort is restored.  For now I altered this by editing and Turning off AutoOpen - and I manually close / reset / open with no other extra steps as the COM# isn't changing:
Code: [Select]
Form1.cs at line 179
            if (chkAutoOpen.Checked & DigiFound)
                txtComPort.Text = DigiPort;

Without my Pro's I went to Teensy 3.1 units that my project will require in the end.  I have two plugged in and each is connected and showing their output, something the IDE Monitor won't do.  From Digistump I got a link to MegunoLink for Serial data capture and it doesn't work as well as yours.  If I punch the reset the port is orphaned.  If I close first then it is Okay.  Otherwise I have to pull it for the system to abolish the old instances - then I can go in fresh.  This is the known Win7 issue.  But your code never needs an EXIT like the IDE does when ports get dropped.

My extended thoughts for the code would be to emulate my OLED and have a reserved set of lines [Left 20-30 characters] that the debug caller can indicate [ I was using Serial.print( "~4" ); before the output to specify where the cursor went for the output that followed. ], anything after NewLine not so indicated was to dump to the "free form" scrolling area [ the right rest of the form?].  Maybe you see the value in this and want to do it yourself, but it isn't something that an off the shelf terminal program is going to do.  If it was extended to have a control to specify the value name that could be done once so the PC could statically put that label on the terminal and then the code could just pop out the current value anytime and it would be like a real debugger : Alternatively you could just use every other line and put labels on ODD lines and push values to EVEN lines - Perhaps '~A' and '~a' instead of numbers where upper case [A-Z] is odd and lower case [a-z] is the even - giving 52 unique lines, or 26 pairs if all labeled.

I have VStudio 2010 and last year installed "visual micro plugin" 'ArduinoForAtmelStudio' which I cannot get to uninstall or Update, as it needs the install source MSI.  I also put on the AtmelStudio - which has been updated. 

I just grabbed the 2013 Visual Studio Community Edition trying to start fresh - but the old plugins are as noted out of sorts so far for using as an Arduino IDE alternative as of now.
« Last Edit: February 20, 2015, 02:02:57 am by defragster »

cborn

  • Newbie
  • *
  • Posts: 11
Re: Debugging Output over USB Serial
« Reply #4 on: February 20, 2015, 03:08:34 pm »
The EXE is Good - I can run two copies.  I did my own build and it also works (2 warnings)  Each can connect to a unique device.  Beginning of a perfect solution - Thanks for sharing, you've given me a great start!

It has a usable interface and it functions!  In fact if I put "Teensy" in the Match location it detects the droppage and auto reconnects.  My problem is I have (2) attached with the same name.  On enumerating with failure it finds the second working unit and tries to own that one when it updates the lblPort.  More issues but it could be solved.  It does then reconnect when lblPort is restored.  For now I altered this by editing and Turning off AutoOpen - and I manually close / reset / open with no other extra steps as the COM# isn't changing:
Code: [Select]
Form1.cs at line 179
            if (chkAutoOpen.Checked & DigiFound)
                txtComPort.Text = DigiPort;

Without my Pro's I went to Teensy 3.1 units that my project will require in the end.  I have two plugged in and each is connected and showing their output, something the IDE Monitor won't do.  From Digistump I got a link to MegunoLink for Serial data capture and it doesn't work as well as yours.  If I punch the reset the port is orphaned.  If I close first then it is Okay.  Otherwise I have to pull it for the system to abolish the old instances - then I can go in fresh.  This is the known Win7 issue.  But your code never needs an EXIT like the IDE does when ports get dropped.

If you have multiple devices with the same name, you can just put the specific Com port in the match string textbox.
The devices will normally reconnect with the same port name each time, unless you move them to a new USB socket.
So, plug in the first one, see which port number it gets, and put that (eg COM10) in to match.
Then run up the second instance, and do the same with it.

I hadn't planned for multiple devices, but another way to do it would be to have multiple windows for multiple devices, from the same executable.

Regarding having the program recognize and act on specific information in the code, I originally started using a VB6 terminal program I wrote many years ago, which does have multiple windows, macros, and actions based on recognizing specifics in the data. It worked, however VB6 was limited to a maximum of COM16, and my ports were getting up in the 30s, so I decided to have a play with C# instead.

defragster

  • Sr. Member
  • ****
  • Posts: 467
Re: Debugging Output over USB Serial
« Reply #5 on: February 20, 2015, 06:37:29 pm »
It ran over night on two units just fine - minimal spews of under 100 chars per minute.

It compiled on my system until I removed VS2010 - stopped compiling - I put the 2013 and added [edit] VB PowerPack on and with reference it compiles fine and it good running overnight

Yeah multiWindows or task to task chatter could work.  I hadn't seen that the COM# could also go in the match string - that would fix it.  If that works then it should be cleaner as it won't jump ports while waiting!  [edit] complete match string works quite well in general considering how hard Win7 fights to break it.
« Last Edit: February 21, 2015, 12:36:40 pm by defragster »