-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a5d7975
commit e62aa83
Showing
29 changed files
with
1,443 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
Binary file not shown.
Empty file.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,13 @@ | |||
#!/usr/bin/python | |||
|
|||
import time | |||
from protocols import i2c | |||
|
|||
class ADC: | |||
def __init__(self, address): | |||
self.i2c = i2c.I2C(address = address) | |||
self.address = address | |||
|
|||
def readChannel(self, channel): | |||
val_list = self.i2c.readList(channel,2) | |||
return val_list[0] + val_list[1]**8 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,237 @@ | |||
#!/usr/bin/python | |||
|
|||
import time | |||
from protocols import i2c | |||
|
|||
# =========================================================================== | |||
# BMP085 Class | |||
# =========================================================================== | |||
|
|||
class BMP085: | |||
i2c = None | |||
|
|||
# Operating Modes | |||
__BMP085_ULTRALOWPOWER = 0 | |||
__BMP085_STANDARD = 1 | |||
__BMP085_HIGHRES = 2 | |||
__BMP085_ULTRAHIGHRES = 3 | |||
|
|||
# BMP085 Registers | |||
__BMP085_CAL_AC1 = 0xAA # R Calibration data (16 bits) | |||
__BMP085_CAL_AC2 = 0xAC # R Calibration data (16 bits) | |||
__BMP085_CAL_AC3 = 0xAE # R Calibration data (16 bits) | |||
__BMP085_CAL_AC4 = 0xB0 # R Calibration data (16 bits) | |||
__BMP085_CAL_AC5 = 0xB2 # R Calibration data (16 bits) | |||
__BMP085_CAL_AC6 = 0xB4 # R Calibration data (16 bits) | |||
__BMP085_CAL_B1 = 0xB6 # R Calibration data (16 bits) | |||
__BMP085_CAL_B2 = 0xB8 # R Calibration data (16 bits) | |||
__BMP085_CAL_MB = 0xBA # R Calibration data (16 bits) | |||
__BMP085_CAL_MC = 0xBC # R Calibration data (16 bits) | |||
__BMP085_CAL_MD = 0xBE # R Calibration data (16 bits) | |||
__BMP085_CONTROL = 0xF4 | |||
__BMP085_TEMPDATA = 0xF6 | |||
__BMP085_PRESSUREDATA = 0xF6 | |||
__BMP085_READTEMPCMD = 0x2E | |||
__BMP085_READPRESSURECMD = 0x34 | |||
|
|||
# Private Fields | |||
_cal_AC1 = 0 | |||
_cal_AC2 = 0 | |||
_cal_AC3 = 0 | |||
_cal_AC4 = 0 | |||
_cal_AC5 = 0 | |||
_cal_AC6 = 0 | |||
_cal_B1 = 0 | |||
_cal_B2 = 0 | |||
_cal_MB = 0 | |||
_cal_MC = 0 | |||
_cal_MD = 0 | |||
|
|||
# Constructor | |||
def __init__(self, address=0x77, mode=1, debug=False): | |||
self.i2c = i2c.I2C(address) | |||
|
|||
self.address = address | |||
self.debug = debug | |||
# Make sure the specified mode is in the appropriate range | |||
if ((mode < 0) | (mode > 3)): | |||
if (self.debug): | |||
print "Invalid Mode: Using STANDARD by default" | |||
self.mode = self.__BMP085_STANDARD | |||
else: | |||
self.mode = mode | |||
# Read the calibration data | |||
self.readCalibrationData() | |||
|
|||
def readCalibrationData(self): | |||
"Reads the calibration data from the IC" | |||
self._cal_AC1 = self.i2c.readS16(self.__BMP085_CAL_AC1) # INT16 | |||
self._cal_AC2 = self.i2c.readS16(self.__BMP085_CAL_AC2) # INT16 | |||
self._cal_AC3 = self.i2c.readS16(self.__BMP085_CAL_AC3) # INT16 | |||
self._cal_AC4 = self.i2c.readU16(self.__BMP085_CAL_AC4) # UINT16 | |||
self._cal_AC5 = self.i2c.readU16(self.__BMP085_CAL_AC5) # UINT16 | |||
self._cal_AC6 = self.i2c.readU16(self.__BMP085_CAL_AC6) # UINT16 | |||
self._cal_B1 = self.i2c.readS16(self.__BMP085_CAL_B1) # INT16 | |||
self._cal_B2 = self.i2c.readS16(self.__BMP085_CAL_B2) # INT16 | |||
self._cal_MB = self.i2c.readS16(self.__BMP085_CAL_MB) # INT16 | |||
self._cal_MC = self.i2c.readS16(self.__BMP085_CAL_MC) # INT16 | |||
self._cal_MD = self.i2c.readS16(self.__BMP085_CAL_MD) # INT16 | |||
if (self.debug): | |||
self.showCalibrationData() | |||
|
|||
def showCalibrationData(self): | |||
"""Displays the calibration values for debugging purposes""" | |||
print "DBG: AC1 = %6d" % (self._cal_AC1) | |||
print "DBG: AC2 = %6d" % (self._cal_AC2) | |||
print "DBG: AC3 = %6d" % (self._cal_AC3) | |||
print "DBG: AC4 = %6d" % (self._cal_AC4) | |||
print "DBG: AC5 = %6d" % (self._cal_AC5) | |||
print "DBG: AC6 = %6d" % (self._cal_AC6) | |||
print "DBG: B1 = %6d" % (self._cal_B1) | |||
print "DBG: B2 = %6d" % (self._cal_B2) | |||
print "DBG: MB = %6d" % (self._cal_MB) | |||
print "DBG: MC = %6d" % (self._cal_MC) | |||
print "DBG: MD = %6d" % (self._cal_MD) | |||
|
|||
def readRawTemp(self): | |||
"""Reads the raw (uncompensated) temperature from the sensor""" | |||
self.i2c.write8(self.__BMP085_CONTROL, self.__BMP085_READTEMPCMD) | |||
time.sleep(0.005) # Wait 5ms | |||
raw = self.i2c.readU16(self.__BMP085_TEMPDATA) | |||
if (self.debug): | |||
print "DBG: Raw Temp: 0x%04X (%d)" % (raw & 0xFFFF, raw) | |||
return raw | |||
|
|||
def readRawPressure(self): | |||
"""Reads the raw (uncompensated) pressure level from the sensor""" | |||
self.i2c.write8(self.__BMP085_CONTROL, self.__BMP085_READPRESSURECMD + (self.mode << 6)) | |||
if (self.mode == self.__BMP085_ULTRALOWPOWER): | |||
time.sleep(0.005) | |||
elif (self.mode == self.__BMP085_HIGHRES): | |||
time.sleep(0.014) | |||
elif (self.mode == self.__BMP085_ULTRAHIGHRES): | |||
time.sleep(0.026) | |||
else: | |||
time.sleep(0.008) | |||
msb = self.i2c.readU8(self.__BMP085_PRESSUREDATA) | |||
lsb = self.i2c.readU8(self.__BMP085_PRESSUREDATA+1) | |||
xlsb = self.i2c.readU8(self.__BMP085_PRESSUREDATA+2) | |||
raw = ((msb << 16) + (lsb << 8) + xlsb) >> (8 - self.mode) | |||
if (self.debug): | |||
print "DBG: Raw Pressure: 0x%04X (%d)" % (raw & 0xFFFF, raw) | |||
return raw | |||
|
|||
def readTemperature(self): | |||
"""Gets the compensated temperature in degrees celcius""" | |||
UT = 0 | |||
X1 = 0 | |||
X2 = 0 | |||
B5 = 0 | |||
temp = 0.0 | |||
|
|||
# Read raw temp before aligning it with the calibration values | |||
UT = self.readRawTemp() | |||
X1 = ((UT - self._cal_AC6) * self._cal_AC5) >> 15 | |||
X2 = (self._cal_MC << 11) / (X1 + self._cal_MD) | |||
B5 = X1 + X2 | |||
temp = ((B5 + 8) >> 4) / 10.0 | |||
if (self.debug): | |||
print "DBG: Calibrated temperature = %f C" % temp | |||
return temp | |||
|
|||
def readPressure(self): | |||
"""Gets the compensated pressure in pascal""" | |||
UT = 0 | |||
UP = 0 | |||
B3 = 0 | |||
B5 = 0 | |||
B6 = 0 | |||
X1 = 0 | |||
X2 = 0 | |||
X3 = 0 | |||
p = 0 | |||
B4 = 0 | |||
B7 = 0 | |||
|
|||
UT = self.readRawTemp() | |||
UP = self.readRawPressure() | |||
|
|||
# You can use the datasheet values to test the conversion results | |||
# dsValues = True | |||
dsValues = False | |||
|
|||
if (dsValues): | |||
UT = 27898 | |||
UP = 23843 | |||
self._cal_AC6 = 23153 | |||
self._cal_AC5 = 32757 | |||
self._cal_MC = -8711 | |||
self._cal_MD = 2868 | |||
self._cal_B1 = 6190 | |||
self._cal_B2 = 4 | |||
self._cal_AC3 = -14383 | |||
self._cal_AC2 = -72 | |||
self._cal_AC1 = 408 | |||
self._cal_AC4 = 32741 | |||
self.mode = self.__BMP085_ULTRALOWPOWER | |||
if (self.debug): | |||
self.showCalibrationData() | |||
|
|||
# True Temperature Calculations | |||
X1 = ((UT - self._cal_AC6) * self._cal_AC5) >> 15 | |||
X2 = (self._cal_MC << 11) / (X1 + self._cal_MD) | |||
B5 = X1 + X2 | |||
if (self.debug): | |||
debugDict = {'X1' : X1, 'X2' : X2, 'B5' : B5} | |||
self._printDebugDictionary(debugDict) | |||
print "DBG: True Temperature = %.2f C" % (((B5 + 8) >> 4) / 10.0) | |||
|
|||
# Pressure Calculations | |||
B6 = B5 - 4000 | |||
X1 = (self._cal_B2 * (B6 * B6) >> 12) >> 11 | |||
X2 = (self._cal_AC2 * B6) >> 11 | |||
X3 = X1 + X2 | |||
B3 = (((self._cal_AC1 * 4 + X3) << self.mode) + 2) / 4 | |||
if (self.debug): | |||
debugDict = {'B6':B6, 'X1' : X1, 'X2' : X2, 'B3': B3} | |||
self._printDebugDictionary(debugDict) | |||
|
|||
X1 = (self._cal_AC3 * B6) >> 13 | |||
X2 = (self._cal_B1 * ((B6 * B6) >> 12)) >> 16 | |||
X3 = ((X1 + X2) + 2) >> 2 | |||
B4 = (self._cal_AC4 * (X3 + 32768)) >> 15 | |||
B7 = (UP - B3) * (50000 >> self.mode) | |||
if (self.debug): | |||
debugDict = {'X1' : X1, 'X2' : X2, 'B4':B4, 'B7':B7} | |||
self._printDebugDictionary(debugDict) | |||
|
|||
if (B7 < 0x80000000): | |||
p = (B7 * 2) / B4 | |||
else: | |||
p = (B7 / B4) * 2 | |||
|
|||
X1 = (p >> 8) * (p >> 8) | |||
X1 = (X1 * 3038) >> 16 | |||
X2 = (-7375 * p) >> 16 | |||
if (self.debug): | |||
debugDict = {'X1' : X1, 'X2' : X2, 'p':p} | |||
self._printDebugDictionary(debugDict) | |||
|
|||
p = p + ((X1 + X2 + 3791) >> 4) | |||
if (self.debug): | |||
print "DBG: Pressure = %d Pa" % (p) | |||
|
|||
return p | |||
|
|||
def readAltitude(self, seaLevelPressure=101325): | |||
"Calculates the altitude in meters" | |||
altitude = 0.0 | |||
pressure = float(self.readPressure()) | |||
altitude = 44330.0 * (1.0 - pow(pressure / seaLevelPressure, 0.1903)) | |||
if (self.debug): | |||
print "DBG: Altitude = %d" % (altitude) | |||
return altitude | |||
|
|||
def _printDebugDictionary(self,dict): | |||
for key,value in dict: | |||
print "DBG | %s = %d" % (key,value) |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,57 @@ | |||
#!/usr/bin/python | |||
|
|||
""" camera module """ | |||
|
|||
""" The camera module allows the flight computer to capture photographs from | |||
a USB-connected digital camera and store them in a filesystem location | |||
designated at initialization. | |||
To create a new instance of the class, caminstance = camera.Camera('path_to_writable_img_store') | |||
To capture an image: caminstance.captureimage() when the image is captured it will be returned | |||
downloaded from the camera into the path designated at initialization and will be renamed | |||
with a timestamp. | |||
NOTE: This module requires a helper shell script 'captphoto.sh' | |||
""" | |||
import subprocess | |||
import datetime as utcclock | |||
import time | |||
import re | |||
import shutil | |||
from os import rename | |||
|
|||
HELPER_SCRIPT_PATH = '/var/www/webpy/scripts/captphoto.sh' | |||
|
|||
class Camera: | |||
def __init__(self,path): | |||
self.storagepath = path | |||
self.imgregex = re.compile('(IMG_\d{4}.JPG)') | |||
|
|||
def captureimage(self): | |||
d = utcclock.datetime.now() | |||
fn = """%02d_%02d_%02d_%02d_%02d_%02d.jpg""" % (d.year,d.month,d.day,d.hour,d.minute, d.second) | |||
""" capture the image from the camera """ | |||
procname = HELPER_SCRIPT_PATH | |||
proc = subprocess.Popen([procname],stdout=subprocess.PIPE,shell=True) | |||
(out,err) = proc.communicate() | |||
#print "OUTPUT = %s END" % out | |||
matches = self.imgregex.findall(out) | |||
if matches != None: | |||
if len(matches) != 0: | |||
ofn = matches[0] | |||
oldname = '%s/%s' % (self.storagepath,ofn) | |||
newname = '%s/%s' % (self.storagepath,fn) | |||
try: | |||
rename(oldname,newname) | |||
except OSError as err: | |||
print 'ERROR | %s old = %s and new = %s' % (err,oldname,newname) | |||
finally: | |||
return | |||
|
|||
def isavailable(self): | |||
""" returns True if the camera is available, False if not""" | |||
return True | |||
|
|||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,53 @@ | |||
#!/usr/bin/python | |||
|
|||
import os | |||
from protocols import i2c | |||
|
|||
DS1307_SECONDS = 0x00 | |||
DS1307_MINUTES = 0x01 | |||
DS1307_HOURS = 0x02 | |||
DS1307_DAY = 0x03 | |||
DS1307_DATE = 0x04 | |||
DS1307_MONTH = 0x05 | |||
DS1307_YEAR = 0x06 | |||
DS1307_CONTROL = 0x07 | |||
|
|||
CH = (1<<7) | |||
|
|||
class RTCMode: | |||
(H12,H24) = range(2) | |||
|
|||
|
|||
class DS1307: | |||
def __init__(self): | |||
self.i2c = i2c.I2C(address= 0x68) | |||
seconds = self.i2c.readU8(DS1307_SECONDS) | |||
// start the oscillator | |||
seconds |= CH | |||
self.i2c.write8(DS1307_SECONDS,control) | |||
|
|||
h = self.i2c.readU8(DS1307_HOURS) | |||
if h & (1<<6): | |||
self.mode = RTCMode.H12 | |||
else: | |||
self.mode = RTCMode.H24 | |||
|
|||
def setMode(self, aMode): | |||
self.mode = aMode; | |||
h = self.i2c.readU8(DS1307_HOURS) | |||
if self.mode == RTCMode.H12: | |||
h |= (1<<6) | |||
else: | |||
h &= ~(1<<6) | |||
self.i2c.write8(DS1307_HOURS,h) | |||
|
|||
def setTime(self,h,m,s): | |||
self.i2c.write8(DS1307_SECONDS,self.decimalToBCD(h) | CH) | |||
self.i2c.write8(DS1307_MINUTES,self.decimalToBCD(m)) | |||
self.i2c.write8(DS1307_HOURS,self.decimalToBCD(h) & (1<<6)) | |||
|
|||
def decimalToBCD(self,dec): | |||
msb = dec / 10 | |||
lsb = dec - 10 * msb | |||
return (msb << 4) | lsb | |||
|
Oops, something went wrong.