Solved libDaisy: Need Example for USB Serial Input to Daisy

Hi,
using libDaisy with VS code environment now. (After hitting dead end brick wall with DaisyDuino due to 128k barrier.)
I need to input a char from Teraterm on PC to Daisy over USB serial like Serial.Read() in Arduino. Like hw.Print() but the other direction.
How can I achieve this?
Many thanks!
Christof

As far as I now, I don’t believe we have that implemented.
I suggest that you start by setting up a callback on a USBHandle object with SetReceiveCallback and seeing what happens!

This would be a really nice feature so please let us know what you find and we can look into adding official support. Or, if you’re up for it, you can make your own PR :slight_smile:
We do our best to review every PRs.

You’re joking?
I feel highly honoured, that you would have a look at my solution. :slight_smile: I originally wanted to use Daisy Seed, not to develop basics. I must say, that Daisy Seed software seems abandoned, since Stephen Hensley is no more working on it?
It is discouraging, that USB CDC receive not working - Troubleshooting and Support - Daisy Forums (electro-smith.com) seems not to be solved after 3,5 years?

I’ve staged an example of doing serial reception in libDaisy.
We are currently testing a rather large PR that updates the underlying drivers in the entire library. So I have not merged the new example yet, but I have tested its functionality.

However, you can take a look at the example code here on Github, or check out the example/serial-rx branch of libDaisy to try it out.

AFAIK, there are two things to look out for when setting this up in your own application (some of this is noted within the comments in the example’s comments):

  1. Doing long blocking calls from within the UsbCallback is discouraged, and it is preferred to push messages to be dealt with outside of the callback context. In the above example, this is done with a FIFO object, that is then handled in the main while() loop below.
  2. I did not reproduce it this time. However, there may still be a timing issue if the ReceiveCallback is set very quickly after USB is initialized that will result in the callback not properly setting. This can be avoided by either: A) having your program wait for the connection via the StartLog function before setting the callback, or B) using some short delays between starting the Logger and connecting the callback to the USB peripheral.

Thanks for the note regarding the other thread. I will chime in there as well. However, I think the delay issue (mentioned in #2 above) may have been resolved quite some time ago.

Hope that helps!

1 Like

Thank you very much!
As I needed a single char, I converted:

/** Example showing serial reception
 * https://github.com/electro-smith/libDaisy/blob/example/serial-rx/examples/SerialRead/SerialRead.cpp
 * https://forum.electro-smith.com/t/libdaisy-need-example-for-usb-serial-input-to-daisy/4869/2
 *  This program initializes the daisy, and then waits for connection to a serial monitor.
 *
 *  Once the connection has been established, messages received over serial will be echoed back.
 *  This is done by writing the input to a FIFO of messages as they are received, and
 *  then from within the main while() loop, messages are popped from the FIFO, and printed back over serial.
 */

#include "daisy_seed.h"

using namespace daisy;

DaisySeed hw;

/** Create a FIFO for receiving messages to echo out. */
//FIFO<FixedCapStr<128>, 16> msg_fifo;
FIFO<uint8_t, 1024> msg_fifo;

/** Callback that fires whenever new data is sent from the serial port */
void UsbCallback(uint8_t *buff, uint32_t *length)
{
    if(buff && length) /**< Check that our inputs are not null */
    {
        // Create a new string, and push it to the FIFO
        // FixedCapStr<128> rx((const char *)buff, *length);
        for(uint32_t i=0; i<*length; i++) {
            msg_fifo.PushBack(buff[i]);
        }

        /** Something like this below _can_ work. (where outbuff is a global char array)
         *  However, it is ideal to leave this callback as quickly as possible.
         *  So it is recommended to handle any responses to the input elsewhere.
         */
        // strncpy(outbuff, (const char*)buff, *length);
        // hw.PrintLine(outbuff);
    }
}

int usbGetchar()
{
    if(msg_fifo.IsEmpty()) return 0;
    return msg_fifo.PopFront();
}

int main(void)
{
    // Initialize the Daisy Seed


    hw.Init();

    // Start the log, and wait for connection
    hw.StartLog(true);

    // Set USB callback
    hw.usb_handle.SetReceiveCallback(UsbCallback,
                                     UsbHandle::UsbPeriph::FS_INTERNAL);

    /** Print an initial message once the connection occurs */
    hw.PrintLine("Send messages in your Serial Monitor!");


    while(1)
    {
        /** Whenever the FIFO has contents,
         * go through and print each message that has been received */
        while(!msg_fifo.IsEmpty())
        {
            hw.Print("Received Message: ");
            //hw.PrintLine("%c",msg_fifo.PopFront());
            hw.PrintLine("%c",usbGetchar());
        
        }

        /** Blink LED to show program is running (this indicates to
         * the user that the Serial Monitor Connection has been established) */
        hw.SetLed((System::GetNow() & 1023) > 511);
    }
}