Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge Feature_Add_Callback... to Main #65

Merged
merged 2 commits into from
Jun 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 55 additions & 16 deletions src/SerialManagerBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,21 @@ void SerialManagerBase::respondToByte(char c) {
case STREAM_LENGTH:
if (c == DATASTREAM_SEPARATOR) {
// Get the datastream length:
stream_length = *((int*)(stream_data));
serial_read_state = STREAM_DATA;
stream_chars_received = 0;
Serial.print("SerialManagerBase: RespondToByte: Stream length = ");
Serial.println(stream_length);
if (stream_chars_received==4) {
memcpy(&stream_length, &stream_data[0], 4);
serial_read_state = STREAM_DATA;
stream_chars_received = 0;
Serial.print("SerialManagerBase: RespondToByte: Stream length = ");
Serial.println(stream_length);
}
// Error, length must be 4-byte int
else {
Serial.println("Error: Message length must be 4 byte Int");
//Reset for next message
serial_read_state = SINGLE_CHAR;
stream_chars_received = 0;
}

} else {
stream_data[stream_chars_received] = c;
stream_chars_received++;
Expand Down Expand Up @@ -122,10 +132,11 @@ bool SerialManagerBase::processCharacter(char c) {
void SerialManagerBase::processStream(void) {
int idx = 0;
String streamType;
int tmpInt;
float tmpFloat;
int tmpInt = 0;
float tmpFloat = 0;

while (stream_data[idx] != DATASTREAM_SEPARATOR) {
//Look for message type by finding the next separating character
while ( (stream_data[idx] != DATASTREAM_SEPARATOR) && (idx < stream_length) ) {
streamType.append(stream_data[idx]);
idx++;
}
Expand All @@ -145,13 +156,34 @@ void SerialManagerBase::processStream(void) {
//interpretStreamAFC(idx);
} else if (streamType == "test") {
Serial.println("Stream is of type 'test'.");
tmpInt = *((int*)(stream_data+idx)); idx = idx+4;
Serial.print("int is "); Serial.println(tmpInt);
tmpFloat = *((float*)(stream_data+idx)); idx = idx+4;
Serial.print("float is "); Serial.println(tmpFloat);

//Print first 4-bytes as integer
if ( (stream_length-idx) >= 4) {
memcpy(&tmpInt, stream_data+idx, 4);
idx = idx+4;
Serial.print("int is "); Serial.println(tmpInt);
}

//Print the next 4-bytes as float
if (stream_length-idx >= 4) {
memcpy(&tmpFloat, stream_data+idx, 4);
Serial.print("float is "); Serial.println(tmpFloat);
}

// Else the message type was not identifued
} else {
Serial.print("Unknown stream type: ");
Serial.println(streamType);
// If a custom callback was set, call it
if (_datastreamCallback_p!=NULL)
{
_datastreamCallback_p(stream_data+idx, &streamType, stream_length-idx);
}

// Else no message type found, so ignore it
else
{
Serial.print("Unknown stream type: ");
Serial.println(streamType);
}
}
}

Expand All @@ -173,6 +205,14 @@ bool SerialManagerBase::interpretQuadChar(char mode_char, char chan_char, char d
return ret_val;
}


void SerialManagerBase::setDataStreamCallback(callback_t callBackFunc_p)
{
Serial.print("Datastream callback set");
_datastreamCallback_p = callBackFunc_p;
}


void SerialManagerBase::setFullGUIState(bool activeButtonsOnly) {
if (UI_element_ptr.size() == 0) return;

Expand Down Expand Up @@ -239,5 +279,4 @@ void SerialManagerBase::sendTxBuffer(void) {
if (ble) ble->sendMessage(TX_string); //send the message
}
TX_string.remove(0,TX_string.length()); //clear out the string
}

}
44 changes: 40 additions & 4 deletions src/SerialManagerBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,39 @@
inadvertently invoking these modes, never send characters such as 0x02, 0x03, 0x04.
In fact, you should generally avoid any non-printable character or you risk seeing
unexpected behavior.

License: MIT License. Use at your own risk. Have fun!

Datastreams expect the following message protocol. Note that the message length and payload are sent as little endian (LSB, MSB):
1. DATASTREAM_START_CHAR (0x02)
2. Message Length (int32): number of bytes including parts-4 thru part-6
3. DATASTREAM_SEPARATOR (0x03)
4. Message Type (char): Avoid using the special characters 0x03 or 0x04. (if set to ‘test’, it will print out the payload as an int, then a float)
5. DATASTREAM_SEPARATOR (0x03)
6. Payload
7. DATASTREAM_END_CHAR (0x04)

Use RealTerm to send a 'test' message:
0x02 0x0D 0x00 0x00 0x00 0x03 0x74 0x65 0x73 0x74 0x03 0xD2 0x02 0x96 0x49 0xD2 0x02 0x96 0x49 0x04
1. DATASTREAM_START_CHAR (0x02)
2. Message Length (int32): (0x000D) = 13
3. DATASTREAM_SEPARATOR (0x03)
4. Message Type (char): (0x74657374) = 'test'
5. DATASTREAM_SEPARATOR (0x03)
6. Payload (0x499602D2, 0x499602D2) = [1234567890, 1234567890]
7. DATASTREAM_END_CHAR (0x04)

- Expected output
- SerialManagerBase: RespondToByte: Start data stream.
- SerialManagerBase: RespondToByte: Stream length = 13
- SerialManagerBase: RespondToByte: Time to process stream!
- Stream is of type 'test'.
- int is 1234567890
- float is 1228890.25

To register a callback when a datastream message is received, use setDataStreamCallback() and set a unique message type (i.e. not 'gha', 'dsl', afc', or 'test'):
- `serialManager.setDataStreamCallback(&dataStreamCallback);`
- `void dataStreamCallback(char* payload_p, String *msgType_p, int numBytes)`

License: MIT License. Use at your own risk. Have fun!
*/


Expand All @@ -98,6 +128,9 @@ class SerialManager_UI; //forward declare. Assume SerialManager_UI.h will be i
#define QUADCHAR_CHAR__USE_PERSISTENT_MODE ((char)'_') //this is an underscore

#define SERIALMANAGERBASE_MAX_UI_ELEMENTS 30

typedef void(*callback_t)(char* payload_p, String* msgType_p, int numBytes); //typedef for datastream callback pointer

class SerialManagerBase {
public:
SerialManagerBase(void) {};
Expand All @@ -118,6 +151,8 @@ class SerialManagerBase {
SINGLE_CHAR, STREAM_LENGTH, STREAM_DATA, QUAD_CHAR_1, QUAD_CHAR_2, QUAD_CHAR_3
};

void setDataStreamCallback(callback_t callBackFunc_p);

SerialManager_UI* add_UI_element(SerialManager_UI *);

protected:
Expand All @@ -129,13 +164,14 @@ class SerialManagerBase {

int serial_read_state; // Are we reading one character at a time, or a stream?
char stream_data[MAX_DATASTREAM_LENGTH];
int stream_length;
int stream_length = 0;
int stream_chars_received;
BLE *ble;
char GUI_persistent_mode = 'g'; //is this used? I don't think so.
String TX_string;
char mode_char, chan_char, data_char; //for quad_char processing

callback_t _datastreamCallback_p = NULL;

std::vector<SerialManager_UI *> UI_element_ptr;
};

Expand Down