0
votes

For some context, I'm trying to create my own high-torque servo.

I've created an Arduino sketch that tracks of the position of a 2-phase rotary encoder, using 2 interrupt pins. It also tracks the state of 2 limit switches using 2 additional interrupt pins.

This all works fine and I can see data coming back in the Arduino Serial Monitor (I'm using VSCode to actually write the code, but it works the same as the Arduino IDE in respect to the serial monitor.)

However, I'm having trouble writing a C# console app, targeting Windows x64, to receive the serial packets that I'm creating in the Arduino sketch.

I've set breakpoints and added Console.WriteLines, but they never get hit. I've done a fair amount of searching on the web and tried several different code examples, but to no avail. It feels like I'm doing everything correctly. I've done a fair amount of serial programming in the past, using the .Net framework, so I know my way around serial protocols and using the SerialPort class. However, that was a while ago (several years).

Here is my C# console app code:

using System;
using System.IO.Ports;

namespace ArduinoSerialTest
{
  class Program
  {

    public const byte PacketStart = 1;
    public const byte PacketEnd = 4;
    public const byte PacketSize = 5;

    static void Main(string[] args)
    {

      bool isStopping = false;

      SerialPort serialPort = new SerialPort();
      serialPort.PortName = "COM3";
      serialPort.BaudRate = 9600;
      serialPort.ReadTimeout = 500;

      serialPort.Open();

      try
      {
        while (!isStopping)
        {
          try
          {
            int startByte = serialPort.ReadByte();
            if (startByte == PacketStart)
            {
              byte[] positionState = new byte[] { (byte)serialPort.ReadByte(), (byte)serialPort.ReadByte() };
              byte limitSwitchState = (byte)serialPort.ReadByte();
              byte packetEnd = (byte)serialPort.ReadByte();

              // simple verification before we process the data
              if (packetEnd != PacketEnd)
              {
                throw new Exception("Invalid packet received.");
              }

              short position = BitConverter.ToInt16(positionState, 0);

              Console.WriteLine("Position: {0}", position); // TODO: Remove me
            }
          }
          catch (TimeoutException) { }
          catch (System.IO.IOException) { }
        }

      }
      finally
      {
        serialPort.Close();
      }

    }

  }
}

Here is the applicable part of my Arduino sketch:

void reportStatus() {
    Serial.write((byte)1); // SOH
    // position split into 2 bytes
    Serial.write((byte)lowByte(encoderAccumulator));
    Serial.write((byte)highByte(encoderAccumulator));
    // limit switches
    Serial.write((byte)limitSwitchState);
    Serial.write((byte)4); // EOT
}

It doesn't ever seem to be receiving the packets; or anything for that matter. I feel like there's something obvious that I'm overlooking, but I can't put my finger on it.

As for the try/catch, I'm seeing the timeout exceptions in the debugger output console in VSCode. I also see the IOException sometimes, but only when I forcefully stop the app using Ctrl+C. I've tried it without the IOException catch, but that didn't reveal anything either.

2
P.S. I've tried using Visual Studio 2017 Community, the same code, and .Net framework 4.7.1 and I still get the same results.Shea Riley

2 Answers

0
votes

Try SerialPort.ReadExisiting().

0
votes

I figured out what was wrong. The Arduino is using the DTR signal to initiate communication. All I had to do was set SerialPort.DtrEnable = true before opening the serial port and it worked. I knew it was something simple! YAY!