0
votes

I am currently working on a robotics project with Arduino. I want to access the serial port from different methods at different times.

For instance, I want to read the ADC at time t1 and get the motor currents at time t2. So I create readADC() and motorCurrents() methods which should both return int arrays of different sizes. The serial port data received is given below.

private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
    int n = serialPort1.BytesToRead;

    serialPort1.Read(data, 0, data.Length);
}

I have implemented all the relevant coding on the Arduino side. I also have set the serial port. I need to implement the following commands in C#

private int[] ReadADC()
{
    string input = "AN\n";  // This is the command for reading the ADC on the Wildthumper board.
    serialPort1.Write(input);

    // The Wildthumper now sends 11 bytes, the last of which is '*' and the first
    // 10 bytes are the data that I want. I need to combine two bytes together
    // from data received and make five values and return it.
    for (int i = 0; i < 5; i++)
    {
        adcValues[i] = data[0 + i * 2] <<8+ data[1 + i * 2];
    }

    return adcValues;
    // Where data is the bytes received on serial port;
}

Similarly:

    private int[] getMotorCurrents()
    {
        string input = "MC\n";  // Wildthumper board command
        serialPort1.Write(input);

        // The Wildthumper now sends 5 bytes with the last one being '*'.
        // And the first four bytes are the data that I want.

        for (int i = 0; i < 2; i++)
        {
            MotorCurrents[i] = data[0 + i * 2] <<8 +data[1 + i * 2];
        }

        return MotorCurrents;
     }

First of all, the number of bytes sent to me change. So how can I use a global variable? For data (the variable used to store serial data received as given above)?

1
Do not ever ignore the return value of the Read() method. It is not what you hope it will be. Serial ports are slow, you usually only get 1 or 2 bytes. Consider using ReadLine() instead, it blocks until the NewLine string is received. Or just don't process the data until you got a full response. - Hans Passant
@HansPassant I actually don't ignore the value of Read(). I read all the bytes sent; though on a few occasions, it splits the 11 bytes sent by readADC() into like 10 and 1 or 8 and 3 etc. - Nazim Ali
You most certainly ignore it in your snippet. You seemed to want to do something with BytesToRead but gave up on that as well. And that goes wrong exactly like you describe, getting less and the rest in the next Read() call. Don't ignore it. - Hans Passant

1 Answers

0
votes

You need to create a global variable and save the data to it when data received fires. This isn't hard.

Here is a code example:

public class myclass{
    public string arduinoData = "";

    private void serialPort1_DataReceived(
        object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    {
        this.arduinoData = serialPort1.ReadLine(data, 0, data.Length);
    }
    //....The rest of your code, such as main methods, etc...
}