Skip to content

Commit 1547622

Browse files
Data logging wip
1 parent fa18a9b commit 1547622

File tree

6 files changed

+180
-4
lines changed

6 files changed

+180
-4
lines changed

src/board/conversions.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ import {
1212
MICROBIT_HAL_ACCELEROMETER_EVT_TILT_LEFT,
1313
MICROBIT_HAL_ACCELEROMETER_EVT_TILT_RIGHT,
1414
MICROBIT_HAL_ACCELEROMETER_EVT_TILT_UP,
15+
MICROBIT_HAL_LOG_TIMESTAMP_DAYS,
16+
MICROBIT_HAL_LOG_TIMESTAMP_HOURS,
17+
MICROBIT_HAL_LOG_TIMESTAMP_MILLISECONDS,
18+
MICROBIT_HAL_LOG_TIMESTAMP_MINUTES,
19+
MICROBIT_HAL_LOG_TIMESTAMP_NONE,
20+
MICROBIT_HAL_LOG_TIMESTAMP_SECONDS,
1521
MICROBIT_HAL_MICROPHONE_LEVEL_THRESHOLD_HIGH,
1622
MICROBIT_HAL_MICROPHONE_LEVEL_THRESHOLD_LOW,
1723
} from "./constants";
@@ -113,3 +119,22 @@ export function convertAccelerometerNumberToString(value: number): string {
113119
throw new Error(`Invalid value ${value}`);
114120
}
115121
}
122+
123+
export function convertTimestampToString(value: number): string {
124+
switch (value) {
125+
case MICROBIT_HAL_LOG_TIMESTAMP_NONE:
126+
return "none";
127+
case MICROBIT_HAL_LOG_TIMESTAMP_MILLISECONDS:
128+
return "milliseconds";
129+
case MICROBIT_HAL_LOG_TIMESTAMP_SECONDS:
130+
return "seconds";
131+
case MICROBIT_HAL_LOG_TIMESTAMP_MINUTES:
132+
return "minutes";
133+
case MICROBIT_HAL_LOG_TIMESTAMP_HOURS:
134+
return "hours";
135+
case MICROBIT_HAL_LOG_TIMESTAMP_DAYS:
136+
return "days";
137+
default:
138+
throw new Error(`Invalid value ${value}`);
139+
}
140+
}

src/board/sensors.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,38 @@ export class EnumSensor extends Sensor {
123123
};
124124
}
125125
}
126+
127+
export interface LogData {
128+
key: string;
129+
value: string | number;
130+
}
131+
132+
export class DataLoggingSensor extends Sensor {
133+
public value: LogData[][] | null = null;
134+
public period: string = "none";
135+
public delete: boolean = false;
136+
public serial: boolean = false;
137+
138+
constructor(id: string) {
139+
super("log", id);
140+
this.id = id;
141+
}
142+
143+
setValue(value: any): void {
144+
if (!Array.isArray(value)) {
145+
throw this.valueError(value);
146+
}
147+
this.value = value;
148+
}
149+
150+
toSerializable() {
151+
return {
152+
type: "log",
153+
id: this.id,
154+
value: this.value,
155+
period: this.period,
156+
serial: this.serial,
157+
delete: this.delete,
158+
};
159+
}
160+
}

src/board/ui.ts

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,14 @@ import {
1111
import {
1212
convertAccelerometerStringToNumber,
1313
convertSoundEventStringToNumber,
14+
convertTimestampToString,
1415
} from "./conversions";
1516
import { FileSystem } from "./fs";
1617
import { WebAssemblyOperations } from "./listener";
1718
import {
19+
DataLoggingSensor,
1820
EnumSensor,
21+
LogData,
1922
RangeSensor,
2023
RangeSensorWithThresholds,
2124
Sensor,
@@ -45,6 +48,7 @@ export class BoardUI {
4548
private temperature: RangeSensor;
4649
private microphone: MicrophoneUI;
4750
private accelerometer: AccelerometerUI;
51+
private dataLogging: DataLoggingUI;
4852

4953
// Perhaps we can remove this?
5054
public serialInputBuffer: number[] = [];
@@ -92,6 +96,7 @@ export class BoardUI {
9296
this.svg.querySelector("#LitMicrophone")!,
9397
onSensorChange
9498
);
99+
this.dataLogging = new DataLoggingUI("log", onSensorChange);
95100

96101
this.sensors = [
97102
this.display.lightLevel,
@@ -103,6 +108,7 @@ export class BoardUI {
103108
this.pins[MICROBIT_HAL_PIN_P0].pin,
104109
this.pins[MICROBIT_HAL_PIN_P1].pin,
105110
this.pins[MICROBIT_HAL_PIN_P2].pin,
111+
this.dataLogging.log,
106112
...this.accelerometer.sensors,
107113
];
108114
this.sensorsById = new Map();
@@ -142,6 +148,7 @@ export class BoardUI {
142148
this.display.initialize();
143149
this.accelerometer.initialize(this.operations.gestureCallback!);
144150
this.microphone.initialize(this.operations.soundLevelCallback!);
151+
this.dataLogging.initialize();
145152
this.serialInputBuffer.length = 0;
146153
}
147154

@@ -227,6 +234,7 @@ export class BoardUI {
227234
this.display.dispose();
228235
this.accelerometer.dispose();
229236
this.microphone.dispose();
237+
this.dataLogging.dispose();
230238
this.serialInputBuffer.length = 0;
231239
}
232240
}
@@ -624,3 +632,74 @@ export class PinUI {
624632

625633
dispose() {}
626634
}
635+
636+
export class DataLoggingUI {
637+
public log: DataLoggingSensor;
638+
private beginRowFlag: boolean = false;
639+
private endRowFlag: boolean = true;
640+
private logData: LogData[] = [];
641+
private startTime: number = 0;
642+
643+
constructor(label: string, private onSensorChange: () => void) {
644+
this.log = new DataLoggingSensor(label);
645+
}
646+
647+
delete() {
648+
this.log.delete = true;
649+
this.onSensorChange();
650+
}
651+
652+
setMirroring(serial: boolean) {
653+
this.log.serial = serial;
654+
this.onSensorChange();
655+
}
656+
657+
setTimestamp(period: number) {
658+
this.log.period = convertTimestampToString(period);
659+
this.onSensorChange();
660+
}
661+
662+
beginRow() {
663+
this.endRowFlag = false;
664+
this.beginRowFlag = true;
665+
}
666+
667+
endRow() {
668+
this.beginRowFlag = false;
669+
this.endRowFlag = true;
670+
this.sendData();
671+
}
672+
673+
setLogData(key: string, value: string) {
674+
if (this.beginRowFlag && !this.endRowFlag) {
675+
this.logData.push({ key, value });
676+
}
677+
}
678+
679+
sendData() {
680+
if (!this.startTime) {
681+
this.startTime = Date.now();
682+
}
683+
this.logData.unshift({
684+
key: "timestamp",
685+
value: Date.now() - this.startTime,
686+
});
687+
if (this.log.value) {
688+
this.log.setValue([...this.log.value, this.logData]);
689+
} else {
690+
this.log.setValue([this.logData]);
691+
}
692+
this.onSensorChange();
693+
this.logData = [];
694+
}
695+
696+
initialize() {}
697+
698+
dispose() {
699+
this.log.delete = false;
700+
this.log.serial = false;
701+
this.log.period = "none";
702+
this.logData = [];
703+
this.log.setValue(null);
704+
}
705+
}

src/jshal.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,11 @@ bool mp_js_hal_audio_is_expression_active(void);
7272

7373
void mp_js_hal_microphone_init(void);
7474
void mp_js_hal_microphone_set_threshold(int kind, int value);
75-
int mp_js_hal_microphone_get_level(void);
75+
int mp_js_hal_microphone_get_level(void);
76+
77+
void mp_js_hal_log_delete(bool full_erase);
78+
void mp_js_hal_log_set_mirroring(bool serial);
79+
void mp_js_hal_log_set_timestamp(int period);
80+
int mp_js_hal_log_begin_row(void);
81+
int mp_js_hal_log_end_row(void);
82+
int mp_js_hal_log_data(const char *key, const char *value);

src/jshal.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,4 +215,31 @@ mergeInto(LibraryManager.library, {
215215
mp_js_hal_audio_is_expression_active: function () {
216216
return board.audio.isSoundExpressionActive();
217217
},
218+
219+
mp_js_hal_log_delete: function (full_erase) {
220+
board.dataLogging.delete();
221+
},
222+
223+
mp_js_hal_log_set_mirroring: function (serial) {
224+
board.dataLogging.delete();
225+
},
226+
227+
mp_js_hal_log_set_timestamp: function (period) {
228+
board.dataLogging.setTimestamp(period);
229+
},
230+
231+
mp_js_hal_log_begin_row: function () {
232+
board.dataLogging.beginRow();
233+
return 0;
234+
},
235+
236+
mp_js_hal_log_end_row: function () {
237+
board.dataLogging.endRow();
238+
return 0;
239+
},
240+
241+
mp_js_hal_log_data: function (key, value) {
242+
board.dataLogging.setLogData(UTF8ToString(key), UTF8ToString(value));
243+
return 0;
244+
},
218245
});

src/microbithal_js.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -376,18 +376,21 @@ const uint8_t *microbit_hal_get_font_data(char c) {
376376
}
377377

378378
void microbit_hal_log_delete(bool full_erase) {
379+
mp_js_hal_log_delete(full_erase);
379380
/*
380381
uBit.log.clear(full_erase);
381382
*/
382383
}
383384

384385
void microbit_hal_log_set_mirroring(bool serial) {
386+
mp_js_hal_log_set_mirroring(serial);
385387
/*
386388
uBit.log.setSerialMirroring(serial);
387389
*/
388390
}
389391

390392
void microbit_hal_log_set_timestamp(int period) {
393+
mp_js_hal_log_set_timestamp(period);
391394
/*
392395
static_assert(MICROBIT_HAL_LOG_TIMESTAMP_NONE == (int)TimeStampFormat::None);
393396
static_assert(MICROBIT_HAL_LOG_TIMESTAMP_MILLISECONDS == (int)TimeStampFormat::Milliseconds);
@@ -400,33 +403,33 @@ void microbit_hal_log_set_timestamp(int period) {
400403
}
401404

402405
int microbit_hal_log_begin_row(void) {
406+
return mp_js_hal_log_begin_row();
403407
/*
404408
if (uBit.log.beginRow() != DEVICE_OK) {
405409
return -1;
406410
}
407411
return 0;
408412
*/
409-
return 0;
410413
}
411414

412415
int microbit_hal_log_end_row(void) {
416+
return mp_js_hal_log_end_row();
413417
/*
414418
if (uBit.log.endRow() != DEVICE_OK) {
415419
return -1;
416420
}
417421
return 0;
418422
*/
419-
return 0;
420423
}
421424

422425
int microbit_hal_log_data(const char *key, const char *value) {
426+
return mp_js_hal_log_data(key, value);
423427
/*
424428
if (uBit.log.logData(key, value) != DEVICE_OK) {
425429
return -1;
426430
}
427431
return 0;
428432
*/
429-
return 0;
430433
}
431434

432435
// This is needed by the microbitfs implementation.

0 commit comments

Comments
 (0)