Hardware resource Open/Close methods
As Jesse C. Slicer mentioned, because your class seems to encapsulate an IDisposable object (assuming serialPort would be a private field - this would be clearer if you named it _serialPort), it's asking to implement the IDisposable interface.

Thus, instead of a destructor, you would simply have a Dispose method:

public void Dispose()
{
    serialPort.Dispose();
}


Another thing is this LibraryTrace whose Start and End static methods are a testability hinderance. If it's at all possible, I would wrap that with an interface like ILibraryTrace and implement it in a LibraryTraceWrapper : ILibraryTrace class that exposes the static LibraryTrace methods as instance methods - and inject it into the constructor as a dependency - same goes for the SerialPort:

private readonly ILibraryTrace _trace;
private readonly ISerialPort _serialPort;

public ComPortInput(ILibraryTrace tracer, ISerialPort sp, int delay) : base(delay)
{
    // ...
}


This way you could unit test your class and inject mocks as needed.

As for your non-null assertion, that's called a guard clause and it's good because you're failing fast; by throwing in the constructor you thwart the instantiation of your class without a serial port.

I don't know if it's a typo or if it could be an actual issue, but LibraryTrace.Start and LibraryTrace.End are not working off the same string parameter value (you have "ComPortInput" and "ComportInput" - those are not the same string in C#). Given you're passing in the type's name, I would seriously consider passing in typeof(this).Name instead of a magic string. This shields both calls from an eventual rename refactoring.