0

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.

Shea Riley
  • 31
  • 3
  • 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 Aug 14 '19 at 19:36

2 Answers2

0

Try SerialPort.ReadExisiting().

Taha teber
  • 20
  • 7
  • That returns a string. I need the binary data (the bytes). – Shea Riley Aug 14 '19 at 20:25
  • May I ask why you recommend this? – Shea Riley Aug 14 '19 at 20:26
  • Take a look at this: https://stackoverflow.com/questions/30545162/how-to-convert-string-to-byte-array – Taha teber Aug 14 '19 at 20:33
  • This is an unnecessary step and will impact performance. I shouldn't have to convert a string back into bytes that was unnecessarily converted to a string in the first place. – Shea Riley Aug 14 '19 at 20:45
  • You have a computer running C# and it will slow down because of converting a string to byte. No offense but that's some crappy computer. Parsing variables is a common procedure in computers – Haroun Hajem Aug 15 '19 at 17:37
  • This operation happens many times a second and is very time sensitive. Every operation must be considered carefully. It was obvious that this answer was a very generic one that wasn't given much thought about how it relates to the problem that I'm trying to solve. I appreciate the attempt at helping, but it wasn't the answer I was looking for. – Shea Riley Aug 18 '19 at 23:21
0

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!

Shea Riley
  • 31
  • 3