SBB Micro
Source code for the self-balancing-bike microcontroller unit (Teensy 4.1-based). 🚀️
Loading...
Searching...
No Matches
logger.h
Go to the documentation of this file.
1
2#ifndef __LOG_H__
3#define __LOG_H__
4
10
11//defines
12#define DOLOG 1
13#define LOG_SAMPLING_FAC 1
14#define sd SD.sdfs
15#define SD_CONFIG SdioConfig(FIFO_SDIO)
16#define PREALLOC 1024L*1024L*1024L
17#define DATAPACKET_SIZE sizeof(float)*64
18#define RING_BUF_SIZE DATAPACKET_SIZE*10
19#define SDSECTOR_SIZE 512
20#define FILENAME_MAXSIZE 32
21#define FILENAME_FORMAT "log_%04d-%02d-%02d_%02d.%02d.%02d.sbb"
22#define FILENAME_ENTRIES year(), month(), day(), hour(), minute(), second()
23#define FILENAME_REPORT "report.log"
24
25#if DOLOG == 1
26
27//variables and objects
28boolean doLog = false;
30float fill_packet[(DATAPACKET_SIZE - sizeof(ControlClass::controlModel_U) - sizeof(ControlClass::controlModel_Y)) / sizeof(float)];
31uint64_t logSampleWritten = 0;
32FsFile logFile;
33FsFile reportFile;
34RingBuf<FsFile, RING_BUF_SIZE> log_buf;
35
36//print report
37void print_report(int mode) {
38 if (SD.exists(FILENAME_REPORT)) reportFile = sd.open(FILENAME_REPORT, O_RDWR | O_APPEND); //open with append
39 else {
40 reportFile = sd.open(FILENAME_REPORT, O_RDWR | O_CREAT | O_TRUNC);
41 reportFile.preAllocate(10*1024*1024);
42 }; //open with create
43 if (!reportFile) { return; }
44
45 switch (mode)
46 {
47 case 0: //startup info
48 reportFile.printf("\n#### NEW LOG on %04d-%02d-%02d at %02d:%02d:%02d ####\n", year(), month(), day(), hour(), minute(), second());
49 reportFile.printf("Code generated on %s at %s\n", __DATE__, __TIME__);
50 reportFile.printf("Log file created with name %s (%.0f ms/sample)\n", filename, ((float) LOG_SAMPLING_FAC*SAMPLING_TIME)/1000.0F);
51 reportFile.print("STARTUP INFO:\n");
52 reportFile.printf("\tIMU: %d (AccEn: %d, GyroEn: %d)\n", iostatus.imu, iostatus.accen, iostatus.gyroen);
53 reportFile.printf("\tMAG: %d (MagEn: %d)\n", iostatus.mag, iostatus.magen);
54 reportFile.printf("\tSPEEDSENS: %d\n", iostatus.speedsens);
55 reportFile.printf("\tDAC: %d\n", iostatus.dac);
56 reportFile.printf("\tGPS: %d\n", iostatus.gps);
57 reportFile.printf("\tSBUS: %d\n", iostatus.sbus);
58
59 reportFile.print("CONFIG INFO:\n\tplease refer to config.h\n");
60 /*
61 reportFile.print("CONFIG INFO:\n");
62 reportFile.printf("\tSAMPLING TIME: %.0f us", SAMPLING_TIME);
63 reportFile.printf("\tACC ODR: %.0f Hz", ACC_ODR);
64 reportFile.printf("\tGYRO ODR: %.0f Hz", GYRO_ODR);
65 reportFile.printf("\tMAG ODR: %.0f Hz", MAG_ODR);
66 reportFile.printf("\tADC RES: %d", ADC_RES);
67 reportFile.printf("\tADC AVER: %d", ADC_AVERAGE);
68 reportFile.printf("\tMTR CTRL MODE: %d", MTR_CTRL_MODE);
69 reportFile.printf("\tLONG CTRL EN: %d", EN_LONG_CTRL);
70 */
71
72 reportFile.print("SENSOR OFFSET:\n");
73 reportFile.printf("\tRDR TRQ: %f\n", riderTorque_raw.riderTorque_offset);
74 reportFile.printf("\tACT CURR: %f\n", actCurr_raw.actCurr_offset);
75 reportFile.printf("\tSTEER VEL: %f\n", steer_raw.steerVel_offset);
76 reportFile.printf("\tBAT VOLT: %f\n", voltage_raw.batVolt_offset);
77 reportFile.printf("\tFORK DISP: %f\n", forkDisp_raw.forkDisp_offset);
78 reportFile.printf("\tGYRO (X,Y,Z): %f, %f, %f\n", imuData_raw.gyros_offset[0], imuData_raw.gyros_offset[1], imuData_raw.gyros_offset[2]);
79
80 reportFile.print("MCU CRASH REPORT:\n");
81 reportFile.print(CrashReport);
82
83 reportFile.print("Running...\n");
84 break;
85 case 1: //turnoff info
86 reportFile.printf("Closing log file at %d bytes (%f MB, %d samples written)\n", DATAPACKET_SIZE*logSampleWritten, ((float) DATAPACKET_SIZE*logSampleWritten)/1024.0F/1024.0F, logSampleWritten);
87 reportFile.printf("Maximum TET: %f ms\n", ((float) timing.max_tet)/1000.0);
88 reportFile.printf("Minimum TET: %f ms\n", ((float) timing.min_tet)/1000.0);
89 reportFile.printf("Turning off on %04d-%02d-%02d at %02d:%02d:%02d\n", year(), month(), day(), hour(), minute(), second());
90 break;
91 default:
92 break;
93 }
94 reportFile.flush();
95 reportFile.close();
96}
97
98//start logger function
99void start_logger(void) {
100
101 //start SD card
102 doLog = true; //init to true
103 if (!sd.begin(SD_CONFIG)) doLog = false;
104
105 //create filename
107
108 //create log file
109 logFile = sd.open(filename, O_RDWR | O_CREAT | O_TRUNC); //open with read&write, create file, truncate with 0 length
110 if (!logFile) doLog = false;
111 logFile.preAllocate(PREALLOC);
112
113 //begin ring buffer
114 log_buf.begin(&logFile);
115
116 //fill log_packet with nan vals
117 for (int i = 0; i < (sizeof(fill_packet) / sizeof(float)); i++) fill_packet[i] = *((float*) &nanVal);
118
119 //print report
120 if (doLog) print_report(0);
121
123}
124
125//log closer function
126void log_closer(void) {
127 if (doLog) {
128 log_buf.writeOut(log_buf.bytesUsed());
129 logFile.flush();
131 logFile.close();
132 print_report(1);
133 doLog = false;
135 }
136}
137
138
139//do log stuff
140void do_logger(void) {
141 uint32_t startWriteLogTime = micros();
142
143 if (!doLog) {
144 return;
145 }
146
147 //write data to buffer
148 if (counters.log == 0) {
149
150 //write to ring buffer
151 log_buf.write((uint8_t*) &ctrl.controlModel_U, sizeof(ControlClass::controlModel_U));
152 log_buf.write((uint8_t*) &ctrl.controlModel_Y, sizeof(ControlClass::controlModel_Y));
153 log_buf.write((uint8_t*) &fill_packet[0], sizeof(fill_packet));
155
156 //reset counter
157 counters.log = LOG_SAMPLING_FAC - 1;
158 }
159 else counters.log--;
160
161
162 //check used bytes in ring buffer
163 size_t ringBufBytesUsed = log_buf.bytesUsed();
164 if ((ringBufBytesUsed + logFile.curPosition() > (PREALLOC - DATAPACKET_SIZE))) {
165 log_closer();
166 return;
167 }
168
169 //write out SDSECTOR_SIZE bytes from ring buffer if logFile is free
170 if ((ringBufBytesUsed >= SDSECTOR_SIZE) && !logFile.isBusy()) {
171 if (SDSECTOR_SIZE != log_buf.writeOut(SDSECTOR_SIZE)) {
172 log_closer(); //issue if written-out bytes are not equal to SDSECTOR_SIZE
173 return;
174 }
175 }
176
177 //timing
178 timing.dt_logger = micros() - startWriteLogTime;
179}
180
181#else //empty funs if not logging
182void start_logger(void) {}
183void do_logger(void) {}
184void log_closer(void) {}
185//add more empty logging functions here if necessary
186
187#endif
188#endif
#define SAMPLING_TIME
Sampling time of the control loop (us).
Definition config.h:119
#define SD_CONFIG
Configuration type of sd card.
Definition logger.h:15
boolean doLog
True when logging.
Definition logger.h:28
RingBuf< FsFile, RING_BUF_SIZE > log_buf
Ring buffer object.
Definition logger.h:34
char filename[FILENAME_MAXSIZE]
Log filename.
Definition logger.h:29
void log_closer(void)
Close the log file.
Definition logger.h:126
void start_logger(void)
Initialize the logger.
Definition logger.h:99
uint64_t logSampleWritten
Number of logged bytes.
Definition logger.h:31
#define LOG_SAMPLING_FAC
Sampling factor of data logging (expressed in units of SAMPLING_TIME).
Definition logger.h:13
#define DATAPACKET_SIZE
Size of logged data packet (in bytes).
Definition logger.h:17
FsFile reportFile
File for report log.
Definition logger.h:33
void print_report(int mode)
Print the report.
Definition logger.h:37
FsFile logFile
Log file object.
Definition logger.h:32
#define PREALLOC
Log file preallocation (in bytes).
Definition logger.h:16
#define sd
SD fat object (uses sd fat included in SD library).
Definition logger.h:14
float fill_packet[(DATAPACKET_SIZE - sizeof(ControlClass::controlModel_U) - sizeof(ControlClass::controlModel_Y))/sizeof(float)]
Fill the data packet.
Definition logger.h:30
#define FILENAME_ENTRIES
Entries of the log filename format.
Definition logger.h:22
#define FILENAME_FORMAT
Log filename format.
Definition logger.h:21
#define FILENAME_MAXSIZE
Max length of the name of the log file.
Definition logger.h:20
void do_logger(void)
Log signals.
Definition logger.h:140
#define SDSECTOR_SIZE
Size of the SD sector (in bytes).
Definition logger.h:19
Timing timing
Timing of functions.
Definition objects.h:222
Steer steer_raw
Raw data from the steering sensors.
Definition objects.h:229
ImuData imuData_raw
Raw data from IMU and magnetometer.
Definition objects.h:224
ControlClass ctrl
Control object.
Definition objects.h:241
int8_t LEDmode
LED mode variable.
Definition objects.h:220
IOstatus iostatus
IO status flags.
Definition objects.h:233
ActCurr actCurr_raw
Raw data from the motor current sensor.
Definition objects.h:228
ForkDisp forkDisp_raw
Raw data from the fork-displacement sensor.
Definition objects.h:230
RiderTorque riderTorque_raw
Raw data from the torsiometer.
Definition objects.h:227
Voltage voltage_raw
Raw data from the battery voltage sensor.
Definition objects.h:231
Counter counters
Counters for lower sampling rate.
Definition objects.h:223
uint32_t nanVal
NaN variable.
Definition objects.h:219
#define FILENAME_REPORT
Filename for report log.
Definition logger.h:23
constexpr int8_t DEF
Default mode without signal-logging.
Definition objects.h:31
constexpr int8_t LOG
Default mode with signal-logging.
Definition objects.h:32