Skip to content

Supports Full-duplex Serial Communication within a Single Arduino Thread #2

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

Merged
merged 12 commits into from
Jul 27, 2024
2 changes: 1 addition & 1 deletion keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ Controller KEYWORD1
Device KEYWORD1
VoltageSensor KEYWORD1
WheelSpeedSensor KEYWORD1
Peer KEYWORD1
pulseTriggered KEYWORD2
equivalent KEYWORD2
returnFloat KEYWORD2
returnDouble KEYWORD2
LEFT_FRONT_WHEEL_SPEED_SENSOR LITERAL1
Expand Down
38 changes: 28 additions & 10 deletions src/ArrayList.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,46 +39,64 @@ class ArrayList {
~ArrayList() { delete[] _array; }
int size() { return _size; }
E const *toArray() { return _array; }
void set(int index, E element) { _array[index] = element; }
void set(int index, const E &element) { _array[index] = element; }
E get(int index) { return _array[index]; }
void clear() {
delete[] _array;
_array = new E[0];
_size = _capacity = 0;
}
void add(E element) {
void add(const E &element) {
ensureCapacityInternal(_size + 1);
_array[_size++] = element;
}
ArrayList<E> add(const ArrayList<E> &other) {
ArrayList<E> result = copy();
result.add(other._array, other._size);
result += other;
return result;
}
bool contains(E element) { return indexOf(element) >= 0; }
int indexOfInRange(E element, int start, int stop) {
bool contains(const E &element) { return indexOf(element) >= 0; }
int indexOfInRange(const E &element, int start, int stop) {
for (int i = start; i < stop; i++)
if (_array[i] == element)
return i;
return -1;
}
int indexOf(E element) { return indexOfInRange(element, 0, _size); }
int lastIndexOfInRange(E element, int start, int stop) {
int indexOf(const E &element) { return indexOfInRange(element, 0, _size); }
int lastIndexOfInRange(const E &element, int start, int stop) {
for (int i = stop - 1; i >= start; i--)
if (_array[i] == element)
return i;
return -1;
}
int lastIndexOf(E element) { return lastIndexOfInRange(element, 0, _size); }
ArrayList<E> copy() { return ArrayList<E>(this); }
int lastIndexOf(const E &element) { return lastIndexOfInRange(element, 0, _size); }
ArrayList<E> copy() { return ArrayList<E>(reinterpret_cast<size_t>(this)); }
ArrayList<E> operator+(const E &element) {
ArrayList<E> result = copy();
result += element;
return result;
}
ArrayList<E> operator+(const ArrayList<E> &other) { return add(other); }
ArrayList<E> &operator+=(const E &element) {
add(element);
return *this;
}
ArrayList<E> &operator+=(const ArrayList<E> &other) {
add(other._array, other._size);
return *this;
}
ArrayList<E> &operator=(const ArrayList<E> &other) {
if (this != &other) {
ensureCapacityInternal(other._capacity);
memcpy(_array, other._array, _size * sizeof(E));
if (other._size > 0)
memcpy(_array, other._array, _size * sizeof(E));
}
return *this;
}
E *begin() { return _array; }
E *end() { return _array + _size; }
const E *begin() const { return _array; }
const E *end() const { return _array + _size; }
};


Expand Down
14 changes: 6 additions & 8 deletions src/Controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class Controller : public Device<T> {
protected:
ArrayList<String> _device_tags;
ArrayList<Device<E>> _devices;
void _attachDevice(String &tag, Device<E> device) {
void _attachDevice(const String &tag, Device<E> device) {
_device_tags.add(tag);
_devices.add(device);
device.tag(tag);
Expand All @@ -18,15 +18,13 @@ class Controller : public Device<T> {
public:
Controller() : Device<T>() {}
int level() { return this->_parentTags.size(); }
void device(const String &tag, Device<E> device) { _attachDevice(tag, device); }
const ArrayList<Device<E>> &devices() { return _devices; }
void device(const String &tag, const Device<E> &device) { _attachDevice(tag, device); }
Device<E> device(const String &tag) { return _devices.get(_device_tags.indexOf(tag)); }
virtual void initialize(const ArrayList<String> &parentTags) {
void initialize(const ArrayList<String> &parentTags) override {
Device<E>::initialize(parentTags);
for (Device<E> d: _devices) {
ArrayList<String> deviceParentTags = this->_parentTags.copy();
deviceParentTags.add(this->_tag);
d.initialize(deviceParentTags);
}
for (Device<E> d: _devices)
d.initialize(this->_parentTags + this->_tag);
}
};

Expand Down
8 changes: 5 additions & 3 deletions src/Device.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,21 @@ template<typename T>
class Device {
protected:
String _tag = "";
ArrayList<String> _parentTags = ArrayList<String>();
ArrayList<String> _parentTags = ArrayList<String>(0);
ArrayList<int> _pins;

public:
explicit Device(const ArrayList<int> &pins) : _pins(pins) {}
Device() : Device(ArrayList<int>(0)) {}
~Device() = default;
void tag(const String &tag) { _tag = tag; }
String tag() { return _tag; }
void parentTags(const ArrayList<String> &parentTags) { _parentTags = parentTags; }
const ArrayList<String> &parentTags() { return _parentTags; }
virtual void initialize(const ArrayList<String> &parentTags) { _parentTags = parentTags; }
virtual T read() = 0;
void initializeAsRoot() { initialize(ArrayList<String>(0)); }
virtual T read() { return T(); }
virtual void write(T payload) {}
virtual void update(T data) {}
virtual void close() {}
};

Expand Down
1 change: 1 addition & 0 deletions src/LEADS.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "Controller.h"
#include "Device.h"
#include "Peer.h"
#include "PredefinedTags.h"
#include "Utils.h"
#include "VoltageSensor.h"
Expand Down
29 changes: 29 additions & 0 deletions src/Peer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include "Peer.h"


Peer::Peer(unsigned int baudRate, String separator, String remainder) :
Controller<String, String>(), _baudRate(baudRate), _separator(separator), _remainder(remainder) {}
void Peer::initialize(const ArrayList<String> &parentTags) {
Controller<String, String>::initialize(parentTags);
Serial.begin(_baudRate);
}
String Peer::read() {
char c = Serial.read();
if (c > 0) {
_remainder += c;
if (!_remainder.endsWith(_separator))
return "";
String result = _remainder.substring(0, _remainder.length() - _separator.length());
_remainder = "";
return result;
}
return "";
}
void Peer::write(String payload) { Serial.print(payload + _separator); }
void Peer::refresh() {
String msg = read();
if (msg == "")
return;
for (Device<String> d: _devices)
d.update(msg);
}
22 changes: 22 additions & 0 deletions src/Peer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#ifndef PEER_H
#define PEER_H


#include "Controller.h"

// although we try to keep a consistent format, the C++ version does not support multithreading
class Peer : public Controller<String, String> {
protected:
unsigned int _baudRate;
String _separator, _remainder;

public:
explicit Peer(unsigned int baudRate = 9600, String separator = ";", String remainder = "");
void initialize(const ArrayList<String> &parentTags) override;
String read() override;
void write(String payload) override;
void refresh();
};


#endif // PEER_H
16 changes: 2 additions & 14 deletions src/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,6 @@

bool pulseTriggered(int pin) { return digitalRead(pin) == LOW; }

bool equivalent(float a, float b, float epsilon) { return abs(a - b) <= epsilon * max(abs(a), abs(b)); }
void returnFloat(Peer peer, const String &tag, float n) { peer.write(tag + ":" + n); }

bool equivalent(long a, long b, float epsilon) { return labs(a - b) <= epsilon * max(labs(a), labs(b)); }

void returnFloat(const String &tag, float n) {
Serial.print(tag + ":");
Serial.print(n);
Serial.print(";");
}

void returnDouble(const String &tag, double n) {
Serial.print(tag + ":");
Serial.print(n);
Serial.print(";");
}
void returnDouble(Peer peer, const String &tag, double n) { peer.write(tag + ":" + n); }
9 changes: 3 additions & 6 deletions src/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,13 @@


#include "Arduino.h"
#include "Peer.h"

bool pulseTriggered(int pin);

bool equivalent(long a, long b, float epsilon);
void returnFloat(Peer peer, const String &tag, float n);

bool equivalent(float a, float b, float epsilon);

void returnFloat(const String &tag, float n);

void returnDouble(const String &tag, double n);
void returnDouble(Peer peer, const String &tag, double n);


#endif // UTILS_H