Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
DigiHzData committed Nov 11, 2023
1 parent e436f71 commit 636b31d
Show file tree
Hide file tree
Showing 15 changed files with 3,035 additions and 0 deletions.
404 changes: 404 additions & 0 deletions DigiHz_EasyTransfer.cpp

Large diffs are not rendered by default.

128 changes: 128 additions & 0 deletions DigiHz_EasyTransfer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
//Version 1.0.7
#ifndef DigiHz_EasyTransfer_h
#define DigiHz_EasyTransfer_h

//Make it a little prettier on the front end.
#define details(name) (byte*)&name, sizeof(name)

#if (ARDUINO >=100)
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

#include "Stream.h"

class DigiHz_EasyTransfer {
public:
const uint8_t rxBufferMinSize = 1;
static const uint8_t rxBufferMaxSize = 254;
const uint8_t txMaxSize = 254;

//Constructor.
DigiHz_EasyTransfer(bool debug = false, uint32_t rxBufferSize = rxBufferMaxSize);
/*
In constructor, we use a bigger uint than really needed for rxBufferSize.
Thats because we want to make it easier for the end user to not have to handle with overflow problems.
It will use 3 bytes more memory, but i think it is better to do it this way.
*/

//tx and rx start.
bool begin(Stream *theStream, uint8_t flushRxPortBufferWaitTime = 0, Stream *debugPort = NULL);
void setHeaders(byte header1 = 0x06, byte header2 = 0x85);
//tx and rx end.

//tx start.
enum txStatusCode : uint8_t {
TX_STATUS_OK = 0, //Success.
TX_STATUS_DATA_TO_BIG = 1, //Exceeded the max size of 254 bytes.
TX_INVALID_IDENTIFIER = 2, //Invalid id, 0 is reserved for ack.
TX_STATUS_ACK_TIMEOUT = 3, //Timeout in communication.
TX_STATUS_UNKNOWN = 255 //Unknown status.
};
void setTxRetries(uint8_t txRetries = 5);
void setTxAckTimeout(uint16_t txAckTimeout = 50);
bool sendData(uint8_t *, uint32_t, uint8_t identifier = 1, bool requestAck = false);
/*
In sendData method, we use a bigger uint than really needed for txLength.
Thats because we want to make it easier for the end user to not have to handle with overflow problems.
It will use 3 bytes more memory, but i think it is better to do it this way.
*/
uint8_t getTxMaxSize();
uint8_t getTxStatus();
uint8_t getTxAttemptsDone();
//tx end.

//rx start.
enum rxStatusCode : uint8_t {
RX_STATUS_OK = 0, //Success.
RX_STATUS_BUFFER_TO_SMALL = 1, //Buffer size set to small.
RX_STATUS_DATA_CHECKSUM_FAILED = 2, //Data checksum failed.
RX_STATUS_ACK_CHECKSUM_FAILED = 3, //Ack checksum failed.
RX_STATUS_ACK_RECIEVED = 254,//Recieved ack ok.
RX_STATUS_UNKNOWN = 255 //Unknown status.
};
void clearRxBuffer();
bool receiveData();
uint8_t * rxBuffer; //Address for temporary storage and recieve buffer.
uint8_t rxBufferLength;//Length of the buffer available to end user.
uint8_t rxIdentifier;//Identifier of the buffer available to end user.
uint8_t getRxBufferSize();
uint8_t getRxStatus();
void clearRxBufferOnRecieve(bool clearRxBufferOnRecieve = false);
void flushRxPortBuffer(uint8_t = 0);
void setFlushRxPortBufferWaitTime(uint8_t = 0);
//rx end.

private:
//https://github.com/esp8266/Arduino/issues/7201
//https://stackoverflow.com/questions/35413821/how-to-fix-this-array-used-as-initializer-error/35414564#35414564
//const char _version[8] = {"1.0.7"};//Does not compile on 8266
//const char _version[6] = {'1.0.7'};//This compiles on 8266, but only shows 7, not 1.0.7
const char _version[6] = {'1','.','0','.','7','\0'};// ugly :( But... This compiles on 8266 correctly.

//tx and rx start.
bool _debug;
Stream *_stream;
Stream *_debugPort;
byte _header1 = 0x06;
byte _header2 = 0x85;
unsigned long _txRxStartMeasure;
unsigned long _txRxEndMeasure;
unsigned long _txRxAckStartMeasure;
unsigned long _txRxAckEndMeasure;
//tx and rx end.

//tx start.
bool _txRequestAck;
uint16_t _txAckTimeout = 50;
uint8_t _txIdentifier;
uint8_t _txRetries = 5;
uint8_t * _txAddress; //Address of struct or var or array.
uint8_t _txSize; //Size of struct or var or array.
unsigned long _txWaitForAckStart;
bool _txAckRecieved = false;
uint8_t _txChecksum;
uint8_t _txStatus = 0;//0 = success.
bool _clearRxBufferOnRecieve = false;
uint8_t _txAttemptsDone;
//tx end.

//rx start.
uint32_t _rxBufferSize;
/*
We use a bigger uint than really needed for _rxBufferSize.
Thats because we want to make it easier for the end user to not have to handle with overflow problems.
It will use 3 bytes more memory, but i think it is better to do it this way.
*/
uint8_t _rxLength; //RX packet length according to the packet.
uint8_t _rxIdentifier;
bool _rxSendAck;
uint8_t _rxArrayInx; //Index for RX parsing buffer.
uint8_t _rxCalculatedChecksum; //Calculated Checksum.
bool _rxSendTheAck(uint8_t *, uint8_t);
uint8_t _rxStatus = 0;//0 = success.
uint8_t _flushRxPortBufferWaitTime = 0;
//rx end.
};
#endif
66 changes: 66 additions & 0 deletions doc.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
V1.0.7
------
Constructor:
DigiHz_EasyTransfer myTransfer(false); Creates object myTransfer with no debug and default rx buffer size 254 bytes.
DigiHz_EasyTransfer myTransfer(true); Creates object myTransfer with debug and default rx buffer size 254 bytes.
DigiHz_EasyTransfer myTransfer(false, 64); Creates object myTransfer with no debug and rx buffer size 64 bytes.
DigiHz_EasyTransfer myTransfer(true, 64); Creates object myTransfer with debug and rx buffer size 64 bytes.


Begin method:
myTransfer.begin(&transferPort); Transfer port, 0 mS rx port buffer flush(default), with no debug port(default).
myTransfer.begin(&transferPort, 10); Transfer port, 10 mS rx port buffer flush, with no debug port(default).
myTransfer.begin(&transferPort, 0, &debugPort); Transfer port, 0 mS rx port buffer flush, with debug port.
myTransfer.begin(&transferPort, 10, &debugPort); Transfer port, 10 mS rx port buffer flush, with debug port.

Configuration methods:
Must be called after begin method has been called. (Can be called at runtime to if needed).

myTransfer.setHeaders(); Sets the headers to default. Default is 0x06, 0x85.
myTransfer.setHeaders(0x07, 0x86); Sets the headers to 0x07 and 0x86.
myTransfer.setHeaders(0x07); Sets the headers to 0x07 and 0x85(default).

myTransfer.setTxRetries(); Sets tx retries to 5(default). Only have affect if ack is requested in sendData method.
myTransfer.setTxRetries(10); Sets tx retries to 10. Only have affect if ack is requested in sendData method.

myTransfer.setTxAckTimeout(); Sets tx ack timeout to 50(default). Only have affect if ack is requested in sendData method.
myTransfer.setTxAckTimeout(200); Sets tx ack timeout to 200. Only have affect if ack is requested in sendData method.

myTransfer.clearRxBufferOnRecieve(); Does not clear the temporary rx buffer with zeros on each recieve(Default).
myTransfer.clearRxBufferOnRecieve(false); Does not clear the temporary rx buffer with zeros on each recieve.
myTransfer.clearRxBufferOnRecieve(true); Clears the temporary rx buffer with zeros on each recieve.

myTransfer.setFlushRxPortBufferWaitTime(); Does not flush the rx port buffer 0 mS(default)
myTransfer.setFlushRxPortBufferWaitTime(20); Flushes the rx port buffer for 20 mS or until the rx port buffer is empty so we not get garbage when we recieve a data packet.

Rx methods:
myTransfer.receiveData(); Returns true if data was recieved correctly. returns false if any error.

myTransfer.getRxStatus(); Returns myTransfer.RX_STATUS_OK if data was recieved correctly.
Returns myTransfer.RX_STATUS_BUFFER_TO_SMALL if the rx buffer is to small to recieve the data. //NOTE:This error might show if the rx port buffer is not flushed quickly enough.
Returns myTransfer.RX_STATUS_DATA_CHECKSUM_FAILED if the data checksum failed!
Returns myTransfer.RX_STATUS_ACK_CHECKSUM_FAILED if the ack checksum failed!

myTransfer.getRxBufferSize(); Returns the number of bytes you reserved in the constructor of the rx buffer.

myTransfer.clearRxBuffer(); Clears the temporary rx buffer with zeros.

myTransfer.flushRxPortBuffer(); Does not flush the rx port buffer 0 mS(default)
myTransfer.flushRxPortBuffer(50); Flushes the rx port buffer for 50 mS or until the rx port buffer is empty so we not get garbage when we recieve a data packet.

Tx methods:
myTransfer.sendData(var or array or struct); Sends var or array or struct with identifier set to 1(Default) and not requesting ack(Default). Returns true if data was sent. returns false if any error.
myTransfer.sendData(var or array or struct, 2); Sends var or array or struct with identifier 2 and not requesting ack(Default). Returns true if data was sent. returns false if any error.
myTransfer.sendData(var or array or struct, 3, true); Sends var or array or struct with identifier 3 and requesting ack. Returns true if data was sent. returns false if any error.

myTransfer.getTxStatus(); Returns myTransfer.TX_STATUS_OK if data was sent and ack was requested an ack was recieved. //NOTE:If ack request is false, this will return true even if the reciever did not recieve the packet.
Returns myTransfer.TX_STATUS_DATA_TO_BIG if data packet is bigger than 254 bytes.
Returns myTransfer.TX_INVALID_IDENTIFIER if the identifier is set to 0. (0 is reserved for ack)
Returns myTransfer.TX_STATUS_ACK_TIMEOUT if the ack did not get back in time. //NOTE:This will only be returned if ack request is set to true.

myTransfer.getTxMaxSize(); Returns the number of max bytes you can send.

myTransfer.getTxAttemptsDone(); Will return how many attempts done to send a data packet. //NOTE:If ack request is false, then this will allways return 1.



161 changes: 161 additions & 0 deletions examples/recieve_chunks_with_ack/parsing_helpers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
//Helper functions for printing 64 bit start.
//https://github.com/greiman/SdFat/issues/130
size_t printUint64_t(Print* pr, uint64_t n) {
char buf[21];
char *str = &buf[sizeof(buf) - 1];
*str = '\0';
do {
uint64_t m = n;
n /= 10;
*--str = m - 10*n + '0';
} while (n);
pr->print(str);
}

size_t printInt64_t(Print* pr, int64_t n) {
size_t s = 0;
if (n < 0) {
n = -n;
s = pr->print('-');
} return s + printUint64_t(pr, (uint64_t)n);
}

size_t printlnUint64_t(Print* pr, uint64_t n) {
return printUint64_t(pr, n) + pr->println();
}

size_t printlnInt64_t(Print* pr, int64_t n) {
return printInt64_t(pr, n) + pr->println();
}
//Helper functions for printing 64 bit end.

//Helper functions for parsing recieved data start.
unsigned long processBytes2UnsignedLong(uint8_t * address, uint8_t startByte, bool bytes8 = false){
if (!bytes8){
uint8_t bytes2UnsignedLong[4];//Temporary array for making 4 bytes to a unsigned long.
//Cast 4 bytes to a unsigned long
bytes2UnsignedLong[0] = address[startByte];
bytes2UnsignedLong[1] = address[startByte + 1];
bytes2UnsignedLong[2] = address[startByte + 2];
bytes2UnsignedLong[3] = address[startByte + 3];
return *( (unsigned long*) bytes2UnsignedLong );//Pointer typecast method.
} else {
uint8_t bytes2UnsignedLong[8];//Temporary array for making 8 bytes to a unsigned long.
//Cast 8 bytes to a unsigned long
bytes2UnsignedLong[0] = address[startByte];
bytes2UnsignedLong[1] = address[startByte + 1];
bytes2UnsignedLong[2] = address[startByte + 2];
bytes2UnsignedLong[3] = address[startByte + 3];
bytes2UnsignedLong[4] = address[startByte + 4];
bytes2UnsignedLong[5] = address[startByte + 5];
bytes2UnsignedLong[6] = address[startByte + 6];
bytes2UnsignedLong[7] = address[startByte + 7];
return *( (unsigned long*) bytes2UnsignedLong );//Pointer typecast method.
}
}

long processBytes2Long(uint8_t * address, uint8_t startByte, bool bytes8 = false){
if (!bytes8){
uint8_t bytes2Long[4];//Temporary array for making 4 bytes to a long.
//Cast 4 bytes to a long
bytes2Long[0] = address[startByte];
bytes2Long[1] = address[startByte + 1];
bytes2Long[2] = address[startByte + 2];
bytes2Long[3] = address[startByte + 3];
return *( (long*) bytes2Long );//Pointer typecast method.
} else {
uint8_t bytes2Long[8];//Temporary array for making 8 bytes to a long.
//Cast 8 bytes to a long
bytes2Long[0] = address[startByte];
bytes2Long[1] = address[startByte + 1];
bytes2Long[2] = address[startByte + 2];
bytes2Long[3] = address[startByte + 3];
bytes2Long[4] = address[startByte + 4];
bytes2Long[5] = address[startByte + 5];
bytes2Long[6] = address[startByte + 6];
bytes2Long[7] = address[startByte + 7];
return *( (long*) bytes2Long );//Pointer typecast method.
}
}

uint16_t processBytes2Uint16_t(uint8_t * address, uint8_t startByte){
uint8_t bytes2Uint16_t[2];//Temporary array for making 2 bytes to a uint16_t.
//Cast 2 bytes to a uint16_t
bytes2Uint16_t[0] = address[startByte];
bytes2Uint16_t[1] = address[startByte + 1];
return *( (uint16_t*) bytes2Uint16_t );//Pointer typecast method.
}

uint32_t processBytes2Uint32_t(uint8_t * address, uint8_t startByte){
uint8_t bytes2Uint32_t[4];//Temporary array for making 4 bytes to a uint32_t.
//Cast 4 bytes to a uint32_t
bytes2Uint32_t[0] = address[startByte];
bytes2Uint32_t[1] = address[startByte + 1];
bytes2Uint32_t[2] = address[startByte + 2];
bytes2Uint32_t[3] = address[startByte + 3];
return *( (uint32_t*) bytes2Uint32_t );//Pointer typecast method.
}

uint64_t processBytes2Uint64_t(uint8_t * address, uint8_t startByte){
uint8_t bytes2Uint64_t[8];//Temporary array for making 8 bytes to a uint64_t.
//Cast 8 bytes to a uint64_t
bytes2Uint64_t[0] = address[startByte];
bytes2Uint64_t[1] = address[startByte + 1];
bytes2Uint64_t[2] = address[startByte + 2];
bytes2Uint64_t[3] = address[startByte + 3];
bytes2Uint64_t[4] = address[startByte + 4];
bytes2Uint64_t[5] = address[startByte + 5];
bytes2Uint64_t[6] = address[startByte + 6];
bytes2Uint64_t[7] = address[startByte + 7];
return *( (uint64_t*) bytes2Uint64_t );//Pointer typecast method.
}

float processBytes2Float(uint8_t * address, uint8_t startByte){
uint8_t bytes2Float[4];//Temporary array for making 4 bytes to a float.
//Cast 4 bytes to a float
bytes2Float[0] = address[startByte];
bytes2Float[1] = address[startByte + 1];
bytes2Float[2] = address[startByte + 2];
bytes2Float[3] = address[startByte + 3];
return *( (float*) bytes2Float );//Pointer typecast method.
}

int8_t processByte2Int8_t(uint8_t * address, uint8_t startByte){
int8_t byte2Int8_t[1];//Temporary array for making 1 byte to a int8_t.
//Cast 1 byte to a int8_t
byte2Int8_t[0] = address[startByte];
return *( (int8_t*) byte2Int8_t );//Pointer typecast method.
}

int16_t processBytes2Int16_t(uint8_t * address, uint8_t startByte){
int8_t bytes2Int16_t[2];//Temporary array for making 2 bytes to a int16_t.
//Cast 2 bytes to a int16_t
bytes2Int16_t[0] = address[startByte];
bytes2Int16_t[1] = address[startByte + 1];
return *( (int16_t*) bytes2Int16_t );//Pointer typecast method.
}

int32_t processBytes2Int32_t(uint8_t * address, uint8_t startByte){
uint8_t bytes2Int32_t[4];//Temporary array for making 4 bytes to a int32_t.
//Cast 4 bytes to a int32_t
bytes2Int32_t[0] = address[startByte];
bytes2Int32_t[1] = address[startByte + 1];
bytes2Int32_t[2] = address[startByte + 2];
bytes2Int32_t[3] = address[startByte + 3];
return *( (int32_t*) bytes2Int32_t );//Pointer typecast method.
}

int64_t processBytes2Int64_t(uint8_t * address, uint8_t startByte){
uint8_t bytes2Int64_t[8];//Temporary array for making 8 bytes to a int64_t.
//Cast 8 bytes to a int64_t
bytes2Int64_t[0] = address[startByte];
bytes2Int64_t[1] = address[startByte + 1];
bytes2Int64_t[2] = address[startByte + 2];
bytes2Int64_t[3] = address[startByte + 3];
bytes2Int64_t[4] = address[startByte + 4];
bytes2Int64_t[5] = address[startByte + 5];
bytes2Int64_t[6] = address[startByte + 6];
bytes2Int64_t[7] = address[startByte + 7];
return *( (int64_t*) bytes2Int64_t );//Pointer typecast method.
}
//Helper functions for parsing recieved data end.
Loading

0 comments on commit 636b31d

Please sign in to comment.