-
Notifications
You must be signed in to change notification settings - Fork 1
/
virtual_pycubed.py
303 lines (303 loc) · 10.7 KB
/
virtual_pycubed.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
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
# cubesat.acceleration
# Returns a 3-tuple with (X,Y,Z) acceleration values (m/s^2) from the BMX160
# cubesat.magnetic
# Returns a 3-tuple with (X,Y,Z) magnetometer values (gauss) from the BMX160
# cubesat.gyro
# Returns a 3-tuple with (X,Y,Z) gyroscope values (degrees/second) from the BMX160
# cubesat.temperature
# Returns a float of the temperature in Celsius measured by the BMX160 IMU
# cubesat.temperature_cpu
# Returns a float of the CPU temperature in Celsius measured on-chip by the SAMD51
# cubesat.system_voltage
# Returns a float of the system voltage right before the main 3.3V regulator.
# Value returned from the ADM1176 power-monitoring IC over I2C.
# cubesat.current_draw
# Returns a float of the system current flowing into the main 3.3V regulator.
# Value returned from the ADM1176 power-monitoring IC over I2C.
# cubesat.charge_current
# Returns a float of the charge current in mA. Measured with the SAMD51 16-bit
# ADC of the "L1 Prog" analog output from the LTC4121 energy harvesting circuit.
#
#
# import adafruit_gps
# import adafruit_sdcard
# import adafruit_rfm9x
# import board, microcontroller
# import busio, time
# import digitalio
# import analogio
# import storage, sys
# import pulseio, neopixel
# import bq25883
# import adm1176
# import bmx160
#
# class Satellite:
# def __init__(self):
# """
# Big init routine as the whole board is brought up.
# """
# self.hardware = {
# 'IMU': False,
# 'Radio1': False,
# 'Radio2': False,
# 'SDcard': False,
# 'GPS': False,
# 'MRAM': False,
# 'WDT': False,
# 'USB': False,
# 'PWR': False,
# }
#
# # Define burn wires:
# self._relayA = digitalio.DigitalInOut(board.RELAY_A)
# self._relayA.switch_to_output(drive_mode=digitalio.DriveMode.OPEN_DRAIN)
# self._deployA = False
#
# # Define battery voltage
# self._vbatt = analogio.AnalogIn(board.BATTERY)
#
# # Define MPPT charge current measurement
# self._ichrg = analogio.AnalogIn(board.L1PROG)
#
# # Define SPI,I2C,UART
# self.i2c = busio.I2C(board.SCL,board.SDA)
# # self.spi = busio.SPI(board.SCK,MOSI=board.MOSI,MISO=board.MISO)
#
# # Define GPS
# self.en_gps = digitalio.DigitalInOut(board.EN_GPS)
# self.en_gps.switch_to_output()
#
# # Define sdcard
# self._sdcs = digitalio.DigitalInOut(board.xSDCS)
# self._sdcs.switch_to_output(value=True)
#
# # Define radio
# self._rf_cs1 = digitalio.DigitalInOut(board.RF1_CS)
# self._rf_rst1 = digitalio.DigitalInOut(board.RF1_RST)
# self._rf_cs1.switch_to_output(value=True)
# self._rf_rst1.switch_to_output(value=True)
# self._rf_cs2 = digitalio.DigitalInOut(board.RF2_CS)
# self._rf_rst2 = digitalio.DigitalInOut(board.RF2_RST)
# self._rf_cs2.switch_to_output(value=True)
# self._rf_rst2.switch_to_output(value=True)
#
# # Define MRAM (manual-mode)
# # self._mram_cs = digitalio.DigitalInOut(microcontroller.pin.PB11)
# # self._mram_cs.switch_to_output(value=True)
#
# # Initialize Neopixel
# try:
# self.neopixel = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2, pixel_order=neopixel.GRBW)
# self.neopixel[0] = (0,0,0)
# self.hardware['Neopixel'] = True
# except Exception as e:
# print('[WARNING][Neopixel]',e)
#
# # Initialize USB charger
# try:
# self.usb = bq25883.BQ25883(self.i2c)
# self.usb.charging = False
# self.usb.wdt = False
# self.usb.led=False
# self.usb_charging=False
# self.hardware['USB'] = True
# except Exception as e:
# print('[ERROR][USB Charger]',e)
#
#
#
# # Initialize Power Monitor
# try:
# self.pwr = adm1176.ADM1176(self.i2c)
# self.pwr.sense_resistor = 1
# self.hardware['PWR'] = True
# except Exception as e:
# print('[ERROR][Power Monitor]',e)
#
# # Initialize IMU
# try:
# self.IMU = bmx160.BMX160_I2C(self.i2c)
# self.hardware['IMU'] = True
# except Exception as e:
# print('[ERROR]',e)
#
# # Initialize radio(s)
# try:
# self.radio1 = adafruit_rfm9x.RFM9x(self.spi, self._rf_cs1, self._rf_rst1, 433.0)
# self.hardware['Radio1'] = True
# except Exception as e:
# print('[ERROR][RADIO 1]',e)
# try:
# self.radio2 = adafruit_rfm9x.RFM9x(self.spi, self._rf_cs2, self._rf_rst2, 433.0)
# self.hardware['Radio2'] = True
# except Exception as e:
# print('[ERROR][RADIO 2]',e)
#
# # Initialize GPS
# # try:
# # self.GPS = adafruit_gps.GPS(self.uart)
# # self.hardware['GPS'] = True
# # except Exception as e:
# # print('[ERROR]',e)
#
#
# def mountSD(self):
# # Initialize sdcard
# try:
# self.spi = busio.SPI(board.SCK,MOSI=board.MOSI,MISO=board.MISO)
# self._sd = adafruit_sdcard.SDCard(self.spi, self._sdcs)
# self._vfs = storage.VfsFat(self._sd)
# storage.mount(self._vfs, "/sd")
# sys.path.append("/sd")
# self.hardware['SDcard'] = True
# except Exception as e:
# print('[ERROR][SD Card]',e)
#
# Returns a 3-tuple with (X,Y,Z) acceleration values (m/s^2) from the BMX160
# @property
# def acceleration(self):
# return self.IMU.accel
#
# Returns a 3-tuple with (X,Y,Z) magnetometer values (gauss) from the BMX160
# @property
# def magnetic(self):
# return self.IMU.mag
#
# Returns a 3-tuple with (X,Y,Z) gyroscope values (degrees/second) from the BMX160
# @property
# def gyro(self):
# return self.IMU.gyro
#
# Returns a float of the temperature in Celsius measured by the BMX160 IMU
# @property
# def temperature(self):
# return self.IMU.temperature # Celsius
#
# Returns a float of the CPU temperature in Celsius measured on-chip by the SAMD51
# @property
# def temperature_cpu(self):
# return microcontroller.cpu.temperature # Celsius
#
# @property
# def RGB(self):
# return self.neopixel[0]
# @RGB.setter
# def RGB(self,value):
# if self.hardware['Neopixel']:
# try:
# self.neopixel[0] = value
# except Exception as e:
# print('[WARNING]',e)
#
# @property
# def charge_batteries(self):
# return self.usb_charging
# @charge_batteries.setter
# def charge_batteries(self,value):
# self.usb_charging=value
# self.usb.led=value
# self.usb.charging=value
#
# @property
# def battery_voltage(self):
# _voltage = self._vbatt.value * 3.3 / (2 ** 16)
# _voltage = _voltage * (316/110) # 316/110 voltage divider
# return _voltage # volts
#
# Returns a float of the system voltage right before the main 3.3V regulator.
# Value returned from the ADM1176 power-monitoring IC over I2C.
# @property
# def system_voltage(self):
# if self.hardware['PWR']:
# try:
# return self.pwr.read()[0] # volts
# except Exception as e:
# print('[WARNING]',e)
# else:
# print('[WARNING] Power monitor not initialized')
#
# Returns a float of the system current flowing into the main 3.3V regulator.
# Value returned from the ADM1176 power-monitoring IC over I2C.
# @property
# def current_draw(self):
# if self.hardware['PWR']:
# idraw=0
# try:
# for _ in range(50): # average 50 readings
# idraw+=self.pwr.read()[1]
# return (idraw/50)*1000 # mA
# except Exception as e:
# print('[WARNING]',e)
# else:
# print('[WARNING] Power monitor not initialized')
#
# Returns a float of the charge current in mA. Measured with the SAMD51 16-bit
# ADC of the "L1 Prog" analog output from the LTC4121 energy harvesting circuit.
# @property
# def charge_current(self):
# _charge = self._ichrg.value * 3.3 / (2 ** 16)
# _charge = ((_charge*988)/6040)*1000
# return _charge # mA
#
# @property
# def reset_boot_count(self):
# microcontroller.nvm[0]=0
#
# @property
# def unique_file(self):
# import os
# if not self.hardware['SDcard']:
# return False
# try:
# name = 'DATA_000'
# files = []
# for i in range(0,50):
# _filename = name[:-2]+str(int(i/10))+str(int(i%10))+'.txt'
# if _filename not in os.listdir('/sd/'):
# with open('/sd/'+_filename, "a") as f:
# time.sleep(0.01)
# self.filename = '/sd/'+_filename
# print('filename is:',self.filename)
# return True
# except Exception as e:
# print('[ERROR] Unique File:', e)
# self.RGB = (255,0,0)
# return False
#
# def save(self, dataset, savefile=None):
# if savefile == None:
# savefile = self.filename
# try:
# with open(savefile, "a") as file:
# for item in dataset:
# for i in item:
# if isinstance(i,float):
# file.write('{:.9E},'.format(i))
# else:
# file.write('{},'.format(i))
# file.write('\n')
# return True
# except Exception as e:
# print('[ERROR] SD Save:', e)
# self.RGB = (255,0,0)
# return False
#
# # this deployment function is a placeholder
# def deploy(self,burnA=False,dutycycle=0,freq=5000,duration=1):
# print('BURNING with duty cycle of:',dutycycle)
# # if not self._deployA:
# burn = pulseio.PWMOut(board.PA22, frequency=freq, duty_cycle=0)
# self._relayA.drive_mode=digitalio.DriveMode.PUSH_PULL
# self._relayA.value = 1
# time.sleep(1)
# burn.duty_cycle=dutycycle
# time.sleep(duration)
# self._relayA.value = 0
# burn.duty_cycle=0
# self._deployA = True
# burn.deinit()
# self._relayA.drive_mode=digitalio.DriveMode.OPEN_DRAIN
# return self._deployA
#
# cubesat = Satellite()