0

I am working on a desktop app to communicate with my embedded device running an atxmega processor utilising atmel's cdc device implementation. To communicate with the device I am using the System.IO.Ports.SerialPort class.

The communication is implemented to be as straightforward as possible - PC sends a command to the deviice and in return it expects a known number of bytes in return.

I can write to the device using the SerialPort.Write(...) method with no issues, be it a single byte or many. However, when trying to read data to be received from the device, using Serial.Read(...) only works when I am readinig data byte by byte. Currently the working implementation is as follows:

public static byte[] GetArray(int length)
    {
        byte[] result = new byte[length];

        for (int i = 0; i < result.Length; i++)
        {
            try
            {
                // result[i] = (byte)(Serial.ReadByte());
                Serial.Read(result, i, 1);
            }
            catch (Exception)
            {
                OnTimeOut();
                return result;
            }
        }
        return result;
    }

Either using Serial.ReadByte() or Serial.Read() with a single byte works. However, when I try this function:

public static byte[] GetArrayBulk(int length)
    {
        byte[] result = new byte[length];

        try
        {
            Serial.Read(result, 0, result.Length);
        }
        catch (Exception)
        {
            OnTimeOut();
            return result;
        }

        return result;
    }

I frequently get timeout events or am receiving only zeroes if the function succeeds.

Data sending from the device is realised as follows:

void usb_send_array(uint8_t *src, uint16_t size)
{
    uint16_t i = 0;
    long current_time = millis();
    while (1)
    {
        if(udi_cdc_is_tx_ready())
        {
            current_time = millis();
            udi_cdc_putc(*(src + i));
            i++;
            if (i > size - 1) break;
        }
        if ((millis() - current_time) > 100) return;
    }
}

udi_cdc_putc() and udi_cdc_getc() are the only functions provided by atmel to actually transfer data

Although I have a "solution" to the problem I would like to know what the actual problem is since I am also having trouble communicating with the device using an Android device - sending data works flawlessly but receiving does not with weird issues not dissimilar to the ones when trying to read multiple bytes using SerialPort.Read() method.

I am thinking that perhaps this is related to the way that the data is sent from the device, however the inner workings of usb/serial comunication are hard for me to comprehend.

Is there maybe something obvious that I am missing?

Avalyah
  • 81
  • 1
  • 3
  • 1
    I recommend that you read all of the documentation for [SerialPort](https://learn.microsoft.com/en-us/dotnet/api/system.io.ports.serialport?view=netframework-4.8). Then refer to the documentation for your device and see which of the properties should be changed from the default values when communicating with your device. The following may be helpful: https://stackoverflow.com/questions/65957066/serial-to-usb-cable-from-a-scale-to-pc-some-values-are-just-question-marks/65971845#65971845 . – Tu deschizi eu inchid Sep 04 '22 at 15:11
  • If you click on my username, then in the search box add `serialport` after my userid and search, you'll find additional posts that may be helpful. – Tu deschizi eu inchid Sep 04 '22 at 15:21
  • Please refer to these articles as they show the same idea even if the means are different. [Serial Port communication using PowerShell](https://stackoverflow.com/q/69949507/9014308), [Windows serial: discard all bytes received in the input buffer before a start bytes received](https://stackoverflow.com/q/68162181/9014308) – kunif Sep 04 '22 at 23:57
  • Thank you, although this doesn't really clear things up. I am reading many kilobytes of data correctly by reading them byte by byte so I guess I am most wondering about what is different between puting a Read() method in a loop and reading a single byte each time (which is what SerialPort.ReadByte() does) and just specifying the total data length directly as an argument. I also checked the properties and baud rate, parity, data bits, stop bits, rts and dts are all set correctly, although rts and dts do not seem to have any effect as the code works the same iwth or wiithout them. – Avalyah Sep 05 '22 at 10:30

0 Answers0