Skip to main content
1 of 3
Mikael Patel
  • 8k
  • 2
  • 16
  • 21

Could look something like this:

class HammingStream : public Stream {
public:
  HammingStream(Stream& ios) : m_ios(ios) {}
  virtual size_t write(uint8_t byte);
  virtual int read();
  virtual int available();
  virtual void flush();
protected:
  Stream& m_ios;
  uint8_t encode4(uint8_t nibble);
  uint8_t decode8(uint8_t code);
};

size_t HammingStream::write(uint8_t byte)
{
   m_ios.write(encode4(byte >> 4));
   m_ios.write(encode4(byte & 0xf));
   return (1);
}

int HammingStream::read()
{
  if (available() == 0) return (-1);
  uint8_t nibble = decode8(m_ios.read());
  return ((nibble << 4) | decode8(m_ios.read());
}

int HammingStream::available()
{
  return (m_ios.available() / 2);
}

void HammingStream::flush()
{
  m_ios.flush();
}

Then you could:

HammingStream HammingSerial(&SoftwareSerial);
HammingSerial.println(F("hello world"));

The above leaves out the encoding/decoding but also error detection. The decoding can capture up to two bit errors and do one bit correction (on 4-bit data).

Cheers!

Mikael Patel
  • 8k
  • 2
  • 16
  • 21