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.

1
  • 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. Commented Aug 14, 2019 at 19:36

2 Answers 2

0

Try SerialPort.ReadExisiting().

Sign up to request clarification or add additional context in comments.

6 Comments

That returns a string. I need the binary data (the bytes).
May I ask why you recommend this?
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.
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
|
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!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.