Stairs/module/src/lib/RS485_non_blocking.h

108 lines
2.6 KiB
C++

/*
RS485 protocol library - non-blocking.
Devised and written by Nick Gammon.
Date: 4 December 2012
Version: 1.0
Licence: Released for public use.
*/
#include "Arduino.h"
class RS485
{
typedef size_t (*WriteCallback) (const byte what); // send a byte to serial port
typedef int (*AvailableCallback) (); // return number of bytes available
typedef int (*ReadCallback) (); // read a byte from serial port
enum {
STX = '\2', // start of text
ETX = '\3' // end of text
}; // end of enum
// callback functions to do reading/writing
ReadCallback fReadCallback_;
AvailableCallback fAvailableCallback_;
WriteCallback fWriteCallback_;
// where we save incoming stuff
byte * data_;
// how much data is in the buffer
const int bufferSize_;
// this is true once we have valid data in buf
bool available_;
// an STX (start of text) signals a packet start
bool haveSTX_;
// count of errors
unsigned long errorCount_;
// variables below are set when we get an STX
bool haveETX_;
byte inputPos_;
byte currentByte_;
bool firstNibble_;
unsigned long startTime_;
// helper private functions
byte crc8 (const byte *addr, byte len);
void sendComplemented (const byte what);
public:
// constructor
RS485 (ReadCallback fReadCallback,
AvailableCallback fAvailableCallback,
WriteCallback fWriteCallback,
const byte bufferSize) :
fReadCallback_ (fReadCallback),
fAvailableCallback_ (fAvailableCallback),
fWriteCallback_ (fWriteCallback),
data_ (NULL),
bufferSize_ (bufferSize)
{}
// destructor - frees memory used
~RS485 () { stop (); }
// allocate memory for buf_
void begin ();
// free memory in buf_
void stop ();
// handle incoming data, return true if packet ready
bool update ();
// reset to no incoming data (eg. after a timeout)
void reset ();
// send data
void sendMsg (const byte * data, const byte length);
// returns true if packet available
bool available () const { return available_; };
// once available, returns the address of the current message
byte * getData () const { return data_; }
byte getLength () const { return inputPos_; }
// return how many errors we have had
unsigned long getErrorCount () const { return errorCount_; }
// return when last packet started
unsigned long getPacketStartTime () const { return startTime_; }
// return true if a packet has started to be received
bool isPacketStarted () const { return haveSTX_; }
}; // end of class RS485