-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserial_logger.py
260 lines (219 loc) · 10 KB
/
serial_logger.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
import serial
import csv
import keyboard
import time
# Change to match the desired serial ports
try:
leonardoSerial = serial.Serial(port = "COM8", baudrate=115200, timeout=1)
except:
leonardoSerial = None
try:
teensySerial = serial.Serial(port = "COM6", baudrate=9600, timeout=1)
except:
teensySerial = None
def read_monitors(teensyFileName, leonardoFileName, combinedFileName):
# Create log files
teensyFile = open(teensyFileName, "w", newline="")
leonardoFile = open(leonardoFileName, "w", newline="")
# Program stop flag
keyPressed = False
with open(combinedFileName, "w", newline="") as csvFile:
# Create a CSV writer object
csvWriter = csv.writer(csvFile)
# Write the CSV rows
csvWriter.writerow([
"Time",
"Current to/from Batteries (mA)",
"Current to Satellite (mA)",
"Current from Solar Panel (mA)",
"Battery Voltage (TB)",
"Satellite Voltage",
"Solar Panel Voltage",
"Power to/from Batteries (mW)",
"Power consumbed by Sattelite (mW)",
"Power from Solar Panel (mW)",
"Current Mission Mode",
"ACS Mode",
"ACS On/Off",
"Battery Voltage (Onboard)",
"IMU On/Off",
"Optical Sensor On/Off",
"Solar Current (Onboard)",
"RockBLOCK Sleeping/Awake",
"RockBLOCK Mode",
])
timestamp = round(time.time() * 1000)
currentBatteries = 0
currentSatellite = 0
currentSolarPanel = 0
batteryVoltageTB = 0
satelliteVoltage = 0
solarPanelVoltage = 0
powerBatteries = 0
powerSatellites = 0
powerSolarPanel = 0
currentMissionMode = 0
ACSMode = 0
ACSOnOff = 0
batteryVoltageOB = 0
IMUPowered = 0
opticalSensorPowered = 0
solarCurrentOB = 0
rockblockSleeping = 0
rockblockMode = 0
while not keyPressed:
# Flush serial lines
teensySerial.reset_input_buffer()
leonardoSerial.reset_input_buffer()
# Let the serial buffers fill up, characters get immediately after a reset
i = 0
while i < 25:
teensySerial.readline()
leonardoSerial.readline()
i = i + 1
# Wait until start of Teensy loop
if (teensySerial is not None):
teensyLine = teensySerial.readline().decode()
while ("START LOOP" not in teensyLine):
teensyLine = teensySerial.readline().decode()
pass
# Write start loop indicator
teensyFile.write(teensyLine)
# Wait until start of Leonardo loop
if (leonardoSerial is not None):
while ("Time" not in leonardoSerial.readline().decode()):
pass
# Process flight software data from Teensy serial line
if ((teensySerial is not None) and (teensySerial.inWaiting() > 0)):
# Write timestamp to logs
timestamp = round(time.time() * 1000)
teensyFile.write("Timestamp: " + str(timestamp) + "\n")
# print("----------------------------------------")
# print("Timestamp: " + str(timestamp))
leonardoFile.write("\nTimestamp: " + str(timestamp) + "\n")
# Process lines from the Teensy serial line for one loop
teensyLine = teensySerial.readline().decode()
while ("START LOOP" not in teensyLine):
# Write the line to the Teensy text log
teensyFile.write(teensyLine) # new line is included already
# print(teensyLine)
# Parse desired values to place in CSV
lineSplitColon = teensyLine.split(":")
if len(lineSplitColon) == 2:
label, value = lineSplitColon
value = value.strip()
if label == "Current Mission Mode":
currentMissionMode = value
# print("Mission Mode:", value)
elif label == "ACS Mode":
ACSMode = value
elif label == "Battery Voltage":
batteryVoltageOB = value.split(" ")[0]
# print("Battery Voltage:", value.split(" ")[0])
elif label == "Solar Current":
solarCurrentOB = value.split(" ")[0]
elif label == "RockBLOCK Mode":
rockblockMode = value
# print("Rockblock Mode:", value)
else:
lineSplitSpace = teensyLine.split(" ")
if (len(lineSplitSpace) == 2):
label, value = lineSplitSpace
value = value.strip()
if label == "ACS":
ACSOnOff = value
elif label == "IMU":
if value == "powered" or value == "UNpowered":
IMUPowered = value
elif label == "RockBLOCK":
rockblockSleeping = value
elif (len(lineSplitSpace) == 3):
label1, label2, value = lineSplitSpace
value = value.strip()
if label1 == "Optical" and label2 == "sensor":
if value == "powered" or value == "UNpowered":
opticalSensorPowered = value
# Read the next line
teensyLine = teensySerial.readline().decode()
# Process power data from Leonardo serial line
if ((leonardoSerial is not None) and (leonardoSerial.inWaiting() > 0)):
# Process lines from the Leonardo line for one loop
leonardoLine = leonardoSerial.readline().decode()
while ("Time" not in leonardoLine):
# Write the line to the Leonardo text log
leonardoFile.write(leonardoLine)
# print(leonardoLine)
# Parse desired values to place in CSV
lineSplit = leonardoLine.split(":")
if len(lineSplit) == 2:
label, value = lineSplit
value = value.strip()
if label == "Current to/from Batteries":
currentBatteries = value.split(" ")[0]
# print("Current to/from Batteries:", value.split(" ")[0])
elif label == "Current to Satellite":
currentSatellite = value.split(" ")[0]
# print("Current to Satellite:", value.split(" ")[0])
elif label == "Current from Solar Panel":
currentSolarPanel = value.split(" ")[0]
# print("Current from Solar Panel:", value.split(" ")[0])
elif label == "Battery Voltage":
batteryVoltageTB = value.split(" ")[0]
# print("Battery Voltage:", value.split(" ")[0])
elif label == "Satellite Voltage (from Charge Controller)":
satelliteVoltage = value.split(" ")[0]
# print("Satellite Voltage (from Charge Controller):", value.split(" ")[0])
elif label == "Solar Panel Voltage":
solarPanelVoltage = value.split(" ")[0]
# print("Solar Panel Voltage:", value.split(" ")[0])
elif label == "Power to/from Batteries":
powerBatteries = value.split(" ")[0]
elif label == "Power consumed by Satellite":
powerSatellites = value.split(" ")[0]
elif label == "Power from Solar Panel":
powerSolarPanel = value.split(" ")[0]
# Read the next line
leonardoLine = leonardoSerial.readline().decode()
# Write all the values to the CSV file
csvWriter.writerow([
timestamp,
currentBatteries,
currentSatellite,
currentSolarPanel,
batteryVoltageTB,
satelliteVoltage,
solarPanelVoltage,
powerBatteries,
powerSatellites,
powerSolarPanel,
currentMissionMode,
ACSMode,
ACSOnOff,
batteryVoltageOB,
IMUPowered,
opticalSensorPowered,
solarCurrentOB,
rockblockSleeping,
rockblockMode,
])
# Shut down program if "a" key is pressed
if keyboard.is_pressed("a"):
keyPressed = True
teensyFile.close()
leonardoFile.close()
def main():
if leonardoSerial == None:
print("No Leonardo serial line detected!")
if teensySerial == None:
print("No Teensy serial line detected!")
else:
testName = input("Enter name of this test run: ")
teensyFileName = "logs/" + testName + "_teensy.txt"
leonardoFileName = "logs/" + testName + "_leonardo.txt"
combinedFileName = "logs/" + testName + "_combined.csv"
print("Files will be saved to the 'power-budget-scripts/logs' directory")
print("Hold 'a' to stop logging")
read_monitors(teensyFileName, leonardoFileName, combinedFileName)
print("Program stopped!")
if __name__ == "__main__":
main()