initial commit
This commit is contained in:
64
BluetoothSerialMessage.h
Normal file
64
BluetoothSerialMessage.h
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "SerialMessage.h"
|
||||||
|
#include <BluetoothSerial.h>
|
||||||
|
|
||||||
|
template <uint16_t byteSize>
|
||||||
|
class BluetoothSerialMessage : public SerialMessage<byteSize>{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Construct a new Bluetooth Serial Message object
|
||||||
|
*/
|
||||||
|
BluetoothSerialMessage(BluetoothSerial *serial);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the BluetoothSerialMessage object
|
||||||
|
*/
|
||||||
|
void Init(uint32_t baudRate = 115200) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief prints the args array to the serial monitor
|
||||||
|
*/
|
||||||
|
void PrintArgs() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* @brief reads the serial data and stores it in the data array
|
||||||
|
*/
|
||||||
|
char getChar() override;
|
||||||
|
uint32_t dataAvailable() override;
|
||||||
|
|
||||||
|
BluetoothSerial *serial;
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template <uint16_t byteSize>
|
||||||
|
char BluetoothSerialMessage<byteSize>::getChar(){
|
||||||
|
return serial->read();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint16_t byteSize>
|
||||||
|
uint32_t BluetoothSerialMessage<byteSize>::dataAvailable(){
|
||||||
|
return serial->available();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint16_t byteSize>
|
||||||
|
BluetoothSerialMessage<byteSize>::BluetoothSerialMessage(BluetoothSerial *serial){
|
||||||
|
this->serial = serial;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint16_t byteSize>
|
||||||
|
void BluetoothSerialMessage<byteSize>::Init(uint32_t baudRate){
|
||||||
|
serial->begin("MiniBot");
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint16_t byteSize>
|
||||||
|
void BluetoothSerialMessage<byteSize>::PrintArgs(){
|
||||||
|
serial->print("Current number of args: ");
|
||||||
|
serial->println(this->populatedArgs);
|
||||||
|
for (int i = 0; i < this->populatedArgs; i++) {
|
||||||
|
serial->print(this->args[i]);
|
||||||
|
serial->print(" ");
|
||||||
|
}
|
||||||
|
serial->println();
|
||||||
|
}
|
||||||
10
Message.h
Normal file
10
Message.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Message{
|
||||||
|
enum Messages{
|
||||||
|
MOTOR_READ,
|
||||||
|
MOTOR_WRITE,
|
||||||
|
CONSTANT_WRITE,
|
||||||
|
SET_POSE
|
||||||
|
};
|
||||||
|
}
|
||||||
225
SerialMessage.h
Normal file
225
SerialMessage.h
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
/**
|
||||||
|
* @file SerialMessage.h
|
||||||
|
* @brief This file contains the SerialMessage class
|
||||||
|
* @details This file contains the SerialMessage class which is used to parse serial messages
|
||||||
|
* @version 1.0.0
|
||||||
|
* @author Quinn Henthorne. Contact: quinn.henthorne@gmail.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SERIALMESSAGE_H
|
||||||
|
#define SERIALMESSAGE_H
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
|
||||||
|
template <uint16_t byteSize>
|
||||||
|
class SerialMessage{
|
||||||
|
public:
|
||||||
|
// @warning Never use this to construct a SerialMessage object
|
||||||
|
SerialMessage() = default;
|
||||||
|
/**
|
||||||
|
* @brief Construct a new Serial Message object
|
||||||
|
*/
|
||||||
|
SerialMessage(HardwareSerial *serial);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the SerialMessage object
|
||||||
|
*/
|
||||||
|
virtual void Init(unsigned int baud_rate = 115200);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Update the SerialMessage object and parse any data that's available
|
||||||
|
*/
|
||||||
|
void Update();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns true if there is new data available
|
||||||
|
* @return true if there is new data available
|
||||||
|
*/
|
||||||
|
bool IsNewData();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clears the new data flag
|
||||||
|
*/
|
||||||
|
virtual void ClearNewData();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return a pointer to the args array
|
||||||
|
* @return a pointer to the args array
|
||||||
|
*/
|
||||||
|
uint32_t * GetArgs();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the number of args that have been populated for the current message
|
||||||
|
* @return the number of args that have been populated for the current message
|
||||||
|
*/
|
||||||
|
int GetArgsLength();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the number of args that have been populated for the current message
|
||||||
|
* @return the number of args that have been populated for the current message
|
||||||
|
*/
|
||||||
|
int GetPopulatedArgs();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Prints the args array to the serial monitor
|
||||||
|
*/
|
||||||
|
virtual void PrintArgs();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
enum SerialState : uint8_t{
|
||||||
|
IDLE,
|
||||||
|
NEW_DATA,
|
||||||
|
DATA_RECIEVED,
|
||||||
|
RECIEVE_IN_PROGRESS
|
||||||
|
};
|
||||||
|
virtual void readSerial();
|
||||||
|
virtual void parseData();
|
||||||
|
/**
|
||||||
|
* @brief reads the serial data and stores it in the data array
|
||||||
|
* @return the next character in the serial buffer
|
||||||
|
*/
|
||||||
|
virtual char getChar();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief returns the number of bytes available in the serial buffer
|
||||||
|
* @return the number of bytes available in the serial buffer
|
||||||
|
*/
|
||||||
|
virtual uint32_t dataAvailable();
|
||||||
|
|
||||||
|
SerialState state{IDLE};
|
||||||
|
char data[byteSize]; // an array to store the received data
|
||||||
|
char temp_data[byteSize]; // an array that will be used with strtok()
|
||||||
|
uint16_t ndx{0};
|
||||||
|
static constexpr uint16_t args_length{30};
|
||||||
|
uint16_t populatedArgs{0}; // the number of args that have been populated for the current message
|
||||||
|
uint32_t args[args_length];
|
||||||
|
const char startMarker = '!';
|
||||||
|
const char endMarker = ';';
|
||||||
|
|
||||||
|
private:
|
||||||
|
HardwareSerial *serial{nullptr};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <uint16_t byteSize>
|
||||||
|
char SerialMessage<byteSize>::getChar(){
|
||||||
|
return this->serial->read();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint16_t byteSize>
|
||||||
|
uint32_t SerialMessage<byteSize>::dataAvailable(){
|
||||||
|
return this->serial->available();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint16_t byteSize>
|
||||||
|
SerialMessage<byteSize>::SerialMessage(HardwareSerial *serial) :
|
||||||
|
serial(serial){}
|
||||||
|
|
||||||
|
template <uint16_t byteSize>
|
||||||
|
void SerialMessage<byteSize>::Init(unsigned int baud_rate){
|
||||||
|
this->serial->begin(baud_rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint16_t byteSize>
|
||||||
|
void SerialMessage<byteSize>::readSerial(){
|
||||||
|
char c;
|
||||||
|
|
||||||
|
// read the incoming serial data:
|
||||||
|
while (this->dataAvailable() > 0 && this->state != SerialState::DATA_RECIEVED) {
|
||||||
|
// get the neext character in the serial buffer
|
||||||
|
c = this->getChar();
|
||||||
|
// only execute this if the startMarker has been received
|
||||||
|
// if the incoming character is the endMarker clean up and set the flags
|
||||||
|
if (this->state == SerialState::RECIEVE_IN_PROGRESS) {
|
||||||
|
if (c == endMarker) {
|
||||||
|
data[ndx] = '\0'; // terminate the string
|
||||||
|
ndx = 0;
|
||||||
|
this->state = SerialState::DATA_RECIEVED;
|
||||||
|
}
|
||||||
|
// if the incoming character is not the endMarker
|
||||||
|
else {
|
||||||
|
// add it to the data array
|
||||||
|
data[ndx] = c;
|
||||||
|
ndx++; // increment the data array index
|
||||||
|
// if the index is greater than the maximum data array size,
|
||||||
|
// keep overwriting the last element until the endMarker is received.
|
||||||
|
if (ndx >= byteSize) {
|
||||||
|
ndx = byteSize - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if the incoming character is the startMarker, set the recvInProgress flag
|
||||||
|
else if (c == startMarker) {
|
||||||
|
this->state = SerialState::RECIEVE_IN_PROGRESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint16_t byteSize>
|
||||||
|
void SerialMessage<byteSize>::parseData() { // split the data into its parts
|
||||||
|
this->populatedArgs = 0; // reset the populated args counter
|
||||||
|
char * indx; // this is used by strtok() as an index
|
||||||
|
int i = 0;
|
||||||
|
indx = strtok(temp_data, ","); // get the first part - the string
|
||||||
|
while(indx != NULL){
|
||||||
|
this->args[i] = atoi(indx);
|
||||||
|
populatedArgs++;
|
||||||
|
i++;
|
||||||
|
indx = strtok(NULL, ","); // this continues where the previous call left off
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint16_t byteSize>
|
||||||
|
void SerialMessage<byteSize>::Update(){
|
||||||
|
readSerial();
|
||||||
|
if (this->state == SerialState::DATA_RECIEVED) {
|
||||||
|
// for debug only:
|
||||||
|
// Serial.print("Received:");
|
||||||
|
// Serial.print(data);
|
||||||
|
// Serial.println(":End");
|
||||||
|
strcpy(temp_data, data);
|
||||||
|
// this temporary copy is necessary to protect the original data
|
||||||
|
// because strtok() used in parseData() replaces the commas with \0
|
||||||
|
parseData();
|
||||||
|
//PrintArgs();
|
||||||
|
this->state = SerialState::NEW_DATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint16_t byteSize>
|
||||||
|
bool SerialMessage<byteSize>::IsNewData(){
|
||||||
|
return this->state == SerialState::NEW_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint16_t byteSize>
|
||||||
|
void SerialMessage<byteSize>::ClearNewData(){
|
||||||
|
this->state = SerialState::IDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint16_t byteSize>
|
||||||
|
uint32_t * SerialMessage<byteSize>::GetArgs(){
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint16_t byteSize>
|
||||||
|
int SerialMessage<byteSize>::GetArgsLength(){
|
||||||
|
return args_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint16_t byteSize>
|
||||||
|
int SerialMessage<byteSize>::GetPopulatedArgs(){
|
||||||
|
return populatedArgs;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint16_t byteSize>
|
||||||
|
void SerialMessage<byteSize>::PrintArgs(){
|
||||||
|
return;
|
||||||
|
this->serial->print("Current number of args: ");
|
||||||
|
this->serial->println(this->populatedArgs);
|
||||||
|
for (int i = 0; i < populatedArgs; i++) {
|
||||||
|
this->serial->print(args[i]);
|
||||||
|
this->serial->print(" ");
|
||||||
|
}
|
||||||
|
this->serial->println();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
53
USBMessage.h
Normal file
53
USBMessage.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "SerialMessage.h"
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
template <uint16_t byteSize>
|
||||||
|
class USBMessage : public SerialMessage<byteSize>{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Construct a new Bluetooth Serial Message object
|
||||||
|
*/
|
||||||
|
USBMessage(USBCDC *serial);
|
||||||
|
void Init(uint32_t baudRate = 115200) override;
|
||||||
|
/**
|
||||||
|
* @brief prints the args array to the serial monitor
|
||||||
|
*/
|
||||||
|
void PrintArgs() override;
|
||||||
|
protected:
|
||||||
|
char getChar() override;
|
||||||
|
uint32_t dataAvailable() override;
|
||||||
|
private:
|
||||||
|
USBCDC *serial;
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template <uint16_t byteSize>
|
||||||
|
char USBMessage<byteSize>::getChar(){
|
||||||
|
return serial->read();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint16_t byteSize>
|
||||||
|
uint32_t USBMessage<byteSize>::dataAvailable(){
|
||||||
|
return serial->available();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint16_t byteSize>
|
||||||
|
USBMessage<byteSize>::USBMessage(USBCDC *serial) : serial(serial){}
|
||||||
|
|
||||||
|
template <uint16_t byteSize>
|
||||||
|
void USBMessage<byteSize>::Init(uint32_t baudRate){
|
||||||
|
serial->begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint16_t byteSize>
|
||||||
|
void USBMessage<byteSize>::PrintArgs(){
|
||||||
|
serial->print("Current number of args: ");
|
||||||
|
serial->println(this->populatedArgs);
|
||||||
|
for (int i = 0; i < this->populatedArgs; i++) {
|
||||||
|
serial->print(this->args[i]);
|
||||||
|
serial->print(" ");
|
||||||
|
}
|
||||||
|
serial->println();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user