Skip to content

Commit 10e5c50

Browse files
committed
Add timestamp functionality to PinHistory
1 parent 3479e4a commit 10e5c50

File tree

4 files changed

+170
-10
lines changed

4 files changed

+170
-10
lines changed

CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
88
## [Unreleased]
99
### Added
1010
* `release-new-version.sh` script
11+
* outputs for `PinHistory` can now report timestamps
1112

1213
### Changed
1314
* Shortened `ArduinoQueue` push and pop operations
1415
* `ci/Queue.h` is now `MockEventQueue.h`, with timing data
15-
* `MockEventQueue::Node` now contains struct `MockEvenntQueue::Event`, which contains both the templated type `T` and a field for a timestamp.
16+
* `MockEventQueue::Node` now contains struct `MockEventQueue::Event`, which contains both the templated type `T` and a field for a timestamp.
1617
* Construction of `MockEventQueue` now includes a constructor argument for the time-fetching function
18+
* Construction of `PinHistory` now includes a constructor argument for the time-fetching function
19+
* `PinHistory` can now return an array of timestamps for its events
1720

1821
### Deprecated
1922

SampleProjects/TestSomething/test/pinhistory.cpp

Lines changed: 121 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
#include <ArduinoUnitTests.h>
22
#include <Arduino.h>
3+
#include "fibonacciClock.h"
34

4-
5-
unittest(pin_read_history) {
6-
PinHistory<int> phi;
5+
unittest(pin_read_history_int) {
6+
PinHistory<int> phi; // pin history int
77

88
const int future[6] = {33, 22, 55, 11, 44, 66};
99
assertEqual(0, phi.queueSize());
@@ -16,8 +16,10 @@ unittest(pin_read_history) {
1616

1717
// assert end of history works
1818
assertEqual(future[5], phi.retrieve());
19+
}
1920

20-
PinHistory<bool> phb;
21+
unittest(pin_read_history_bool_to_ascii) {
22+
PinHistory<bool> phb; // pin history bool
2123
phb.fromAscii("Yo", true);
2224

2325
// digitial history as serial data, big-endian
@@ -32,7 +34,19 @@ unittest(pin_read_history) {
3234
assertEqual("Yo", phb.toAscii(0, true));
3335
}
3436

35-
unittest(ascii_stuff) {
37+
unittest(assignment_dumps_queue) {
38+
PinHistory<bool> phb; // pin history bool
39+
assertEqual(0, phb.queueSize());
40+
assertEqual(0, phb.historySize());
41+
phb.fromAscii("Yo", true);
42+
assertEqual(16, phb.queueSize());
43+
assertEqual(0, phb.historySize());
44+
phb = false;
45+
assertEqual(0, phb.queueSize());
46+
assertEqual(1, phb.historySize());
47+
}
48+
49+
unittest(ascii_to_bool_and_back) {
3650
PinHistory<bool> phb;
3751
assertEqual(0, phb.historySize());
3852
phb.reset(false);
@@ -50,4 +64,106 @@ unittest(ascii_stuff) {
5064
assertEqual("hi", phb.toAscii(1, true));
5165
}
5266

67+
unittest(write_history) {
68+
PinHistory<int> phi; // pin history int
69+
int expectedA[6] = {0, 11, 22, 33, 44, 55};
70+
for (int i = 0; i < 6; ++i)
71+
{
72+
assertEqual(i, phi.historySize());
73+
phi = expectedA[i];
74+
assertEqual(i + 1, phi.historySize());
75+
assertEqual(0, phi.queueSize());
76+
assertEqual(phi, expectedA[i]);
77+
}
78+
79+
int actualA[6];
80+
int numMoved = phi.toArray(actualA, 6);
81+
assertEqual(6, numMoved);
82+
// assert non-destructive by repeating the operation
83+
numMoved = phi.toArray(actualA, 6);
84+
assertEqual(6, numMoved);
85+
for (int i = 0; i < 6; ++i)
86+
{
87+
assertEqual(expectedA[i], actualA[i]);
88+
}
89+
}
90+
91+
unittest(null_timing) {
92+
PinHistory<int> phi; // pin history int
93+
int expectedA[6] = {0, 11, 22, 33, 44, 55};
94+
for (int i = 0; i < 6; ++i)
95+
{
96+
phi = expectedA[i];
97+
}
98+
99+
unsigned long tStamps[6];
100+
int numMoved = phi.toTimestampArray(tStamps, 6);
101+
assertEqual(6, numMoved);
102+
// assert non-destructive by repeating the operation
103+
numMoved = phi.toTimestampArray(tStamps, 6);
104+
assertEqual(6, numMoved);
105+
for (int i = 0; i < 6; ++i)
106+
{
107+
assertEqual(0, tStamps[i]);
108+
}
109+
}
110+
111+
unittest(actual_timing_set_in_constructor) {
112+
resetFibClock();
113+
PinHistory<int> phi(fibMicros); // pin history int
114+
for (int i = 0; i < 6; ++i)
115+
{
116+
phi = 0;
117+
}
118+
119+
int expectedT[6] = {1, 1, 2, 3, 5, 8};
120+
unsigned long tStamps[6];
121+
int numMoved = phi.toTimestampArray(tStamps, 6);
122+
assertEqual(6, numMoved);
123+
for (int i = 0; i < 6; ++i)
124+
{
125+
assertEqual(expectedT[i], tStamps[i]);
126+
}
127+
}
128+
129+
unittest(actual_timing_set_after_constructor) {
130+
resetFibClock();
131+
PinHistory<int> phi; // pin history int
132+
phi.setMicrosRetriever(fibMicros);
133+
for (int i = 0; i < 6; ++i)
134+
{
135+
phi = 0;
136+
}
137+
138+
int expectedT[6] = {1, 1, 2, 3, 5, 8};
139+
unsigned long tStamps[6];
140+
int numMoved = phi.toTimestampArray(tStamps, 6);
141+
assertEqual(6, numMoved);
142+
for (int i = 0; i < 6; ++i)
143+
{
144+
assertEqual(expectedT[i], tStamps[i]);
145+
}
146+
}
147+
148+
unittest(event_history) {
149+
resetFibClock();
150+
PinHistory<int> phi(fibMicros); // pin history int
151+
for (int i = 0; i < 6; ++i)
152+
{
153+
phi = i;
154+
}
155+
156+
int expectedT[6] = {1, 1, 2, 3, 5, 8};
157+
MockEventQueue<int>::Event event[6];
158+
int numMoved = phi.toEventArray(event, 6);
159+
assertEqual(6, numMoved);
160+
for (int i = 0; i < 6; ++i)
161+
{
162+
assertEqual(i, event[i].data);
163+
assertEqual(expectedT[i], event[i].micros);
164+
}
165+
}
166+
167+
168+
53169
unittest_main()

cpp/arduino/MockEventQueue.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ class MockEventQueue {
77
T data;
88
unsigned long micros;
99

10+
Event() : data(T()), micros(0) {}
1011
Event(const T &d, unsigned long const t) : data(d), micros(t) { }
1112
};
1213

cpp/arduino/PinHistory.h

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,25 @@ class PinHistory : public ObservableDataStream {
5959
return ret;
6060
}
6161

62+
void init() {
63+
asciiEncodingOffsetIn = 0; // default is sensible
64+
asciiEncodingOffsetOut = 1; // default is sensible
65+
}
66+
6267
public:
6368
unsigned int asciiEncodingOffsetIn;
6469
unsigned int asciiEncodingOffsetOut;
6570

71+
PinHistory(unsigned long (*getMicros)(void)) : ObservableDataStream(), qOut(getMicros) {
72+
init();
73+
}
74+
6675
PinHistory() : ObservableDataStream() {
67-
asciiEncodingOffsetIn = 0; // default is sensible
68-
asciiEncodingOffsetOut = 1; // default is sensible
76+
init();
6977
}
7078

79+
void setMicrosRetriever(unsigned long (*getMicros)(void)) { qOut.setMicrosRetriever(getMicros); }
80+
7181
void reset(T val) {
7282
clear();
7383
qOut.push(val);
@@ -135,7 +145,7 @@ class PinHistory : public ObservableDataStream {
135145
// copy data elements to an array, up to a given length
136146
// return the number of elements moved
137147
int toArray (T* arr, unsigned int length) const {
138-
MockEventQueue<T> q2(qOut);
148+
MockEventQueue<T> q2(qOut); // preserve const by copying
139149

140150
int ret = 0;
141151
for (int i = 0; i < length && q2.size(); ++i) {
@@ -146,10 +156,40 @@ class PinHistory : public ObservableDataStream {
146156
return ret;
147157
}
148158

159+
// copy pin history timing to an array, up to a given length.
160+
// note that this records times between calls to the pin, not between transitions
161+
// return the number of elements moved
162+
int toTimestampArray(unsigned long* arr, unsigned int length) const {
163+
MockEventQueue<T> q2(qOut); // preserve const by copying
164+
165+
int ret = 0;
166+
for (int i = 0; i < length && q2.size(); ++i) {
167+
arr[i] = q2.frontTime();
168+
q2.pop();
169+
++ret;
170+
}
171+
return ret;
172+
}
173+
174+
// copy pin history timing to an array, up to a given length.
175+
// note that this records times between calls to the pin, not between transitions
176+
// return the number of elements moved
177+
int toEventArray(typename MockEventQueue<T>::Event* arr, unsigned int length) const {
178+
MockEventQueue<T> q2(qOut); // preserve const by copying
179+
180+
int ret = 0;
181+
for (int i = 0; i < length && q2.size(); ++i) {
182+
arr[i] = q2.front();
183+
q2.pop();
184+
++ret;
185+
}
186+
return ret;
187+
}
188+
149189
// see if the array matches the data of the elements in the queue
150190
bool hasElements (T const * const arr, unsigned int length) const {
151191
int i;
152-
MockEventQueue<T> q2(qOut);
192+
MockEventQueue<T> q2(qOut); // preserve const by copying
153193
for (i = 0; i < length && q2.size(); ++i) {
154194
if (q2.frontData() != arr[i]) return false;
155195
q2.pop();

0 commit comments

Comments
 (0)