예제 #1
0
class BTMUXcontrol:
    def __init__(self):
        self.temp = 0
        self.output_pins = [24, 25, 26, 27]
        self.IOLock = threading.Lock()  # mutual lock for R/W control
        self.gpio = Gpio()  # initialize GPIO controller

        # setup output pins
        self.IOLock.acquire()
        for pin in self.output_pins:
            self.gpio.pinMode(pin, self.gpio.OUTPUT)
            self.gpio.digitalWrite(pin, self.gpio.LOW)
        self.IOLock.release()

    def decToBin(self, n):
        num = [0, 0, 0, 0]
        if n == 0:
            return num
        else:
            for x in range(n):
                t = x + 1
                for y in range(4):
                    num[y] = t % 2
                    t = t / 2
            return num

    def mux_channel(self, channel):
        bin_list = self.decToBin(channel)  #binary list
        self.IOLock.acquire()
        for z in range(4):
            self.gpio.digitalWrite(self.output_pins[z], bin_list[z])
        self.IOLock.release()
        #return True

    def read_ADC(self):
        self.IOLock.acquire()
        raw = int(
            open("/sys/bus/iio/devices/iio:device0/in_voltage0_raw").read())
        scale = float(
            open("/sys/bus/iio/devices/iio:device0/in_voltage_scale").read())
        vout = raw * scale
        self.IOLock.release()
        return vout
예제 #2
0
class SensorServer(Thread):
    """Sensor server that keeps reading sensors and provide get_sensor_output() method for user"""
    def __init__(self, database_name="air_pollution_data.db"):
        # Parent class constructor
        Thread.__init__(self)

        # Assign GPIO pins that controls MUX, LSB to MSB
        self.gpio_pins = [24, 25, 26, 27]
        self.gpio = Gpio()
        # Set GPIO pins to output
        try:
            for pin in self.gpio_pins:
                self.gpio.pinMode(pin, self.gpio.OUTPUT)
        except Exception as e:
            logger.error("Error setting GPIO pin {}, reason {}".format(
                pin, e.message))

        # Use A0 port
        self.adc_raw = "/sys/bus/iio/devices/iio:device0/in_voltage0_raw"
        self.adc_scale = "/sys/bus/iio/devices/iio:device0/in_voltage_scale"

        self.sensor_names = ['temp', 'CO', 'NO2', 'SO2', 'O3', 'PM25']

        # Use a dict to store sensor output, the format is:
        # { "time": [time stamp],
        #   [sensor1 name]: [sensor1 output],
        #   ...
        #   [sensor6 name]: [sensor6 output]}
        self.sensor_output = {}

        # Create a lock to protect sensor output. That is, when updating the result, lock it on to prevent it from being
        # read at the same time; similarly, when reading the result, lock it on to prevent it from being updated.
        self.sensor_output_lock = Lock()

        # Here we have a decision to make. I decide to let sensor server write sensor outputs to the local database. Of
        # course we can do so in a different thread either in a synchronous way or in an asynchronous way. If we do it
        # with a synchronous approach, we need to use locks to keep synchronization; if we do it with an asynchronous
        # solution, then SQLite3 is already an asynchronous module and I don't see good reason of adding another layer
        # of complexity. Perhaps the most reasonable way would be specifying the database in the main thread and then
        # send it to the sensor server thread.
        self.database_name = database_name

        try:
            # Create the database file and get the connection object.
            self.db_conn = sqlite3.connect(self.database_name)
            # Get database cursor from the connection object.
            self.db_cur = self.db_conn.cursor()
        except Exception as e:
            logger.error("Error connecting the database {}, reason: {}".format(
                self.database_name, e.message))
            self.__del__()

        # Create a 'history' table for history data.
        #  TIME | Temp |  SN1 |  SN2 |  SN3 |  SN4 | PM25
        # -----------------------------------------------
        #   int | real | real | real | real | real | real
        self.db_cur.execute((
            "CREATE TABLE IF NOT EXISTS history (time int PRIMARY KEY NOT NULL,"
            " {0} real, {1} real, {2} real, {3} real, {4} real, {5} real)"
        ).format(self.sensor_names[0], self.sensor_names[1],
                 self.sensor_names[2], self.sensor_names[3],
                 self.sensor_names[4], self.sensor_names[5]))

        # Commit the changes. When a database is accessed by multiple connections, and one of the processes modifies the
        # database, the SQLite database is locked until that transaction is committed. The timeout parameter specifies
        # how long the connection should wait for the lock to go away until raising an exception. The default for the
        # timeout parameter is 5.0 (five seconds).
        self.db_conn.commit()

    def __del__(self):
        # Gracefully close the database connection.
        self.db_conn.close()
        # Reset GPIOs.
        for i in xrange(0, 4):
            self.gpio.digitalWrite(24 + i, Gpio.LOW)

    def get_sensor_output(self):
        # Get the latest sensor output
        return self.sensor_output.copy()

    def set_mux_channel(self, m):
        # Set MUX channel
        # Convert n into a binary string
        bin_repr = "{0:04b}".format(m)
        # Assign value to pin
        for i in xrange(0, 4):
            self.gpio.digitalWrite(24 + i, bin_repr[i])

    def read_sensor(self, n):
        # Read raw data from sensor n, we allocate 2 channels for each sensor:
        # sensor 0: channel 0, 1
        # sensor 1: channel 2, 3
        # ...
        # sensor 7: channel 15, 16

        # Set MUX to read the first channel
        try:
            self.set_mux_channel(2 * n)
            # Wait for 50 ms
            sleep(0.05)
            v1 = int(open(self.adc_raw).read()) * float(
                open(self.adc_scale).read())

            # Set MUX to read the second channel
            self.set_mux_channel(2 * n + 1)
            sleep(0.05)
            v2 = int(open(self.adc_raw).read()) * float(
                open(self.adc_scale).read())

            return v1, v2
        except Exception as e:
            logger.error("Error reading sensor {}, reason: {}".format(
                n, e.message))
            return 0.0, 0.0

    def run(self):
        try:
            # Create the database file and get the connection object.
            self.db_conn = sqlite3.connect(self.database_name)
            # Get database cursor from the connection object.
            self.db_cur = self.db_conn.cursor()
        except Exception as e:
            logger.error("Error connecting the database {}, reason: {}".format(
                self.database_name, e.message))
            self.__del__()

        # Keep reading sensors.
        while True:
            # Acquire the lock
            self.sensor_output_lock.acquire()
            # Add time stamp
            epoch_time = int(time())
            self.sensor_output['time'] = epoch_time

            # Do sensor reading here
            #  1. set MUX to sensor 0, read sensor 0;
            #  2. set MUX to sensor 1, read sensor 1;
            #  ...
            #  n. set MUX to sensor n - 1, read sensor n - 1.
            logger.info("Reading {} sensor...".format(self.sensor_names[0]))
            # Temperature constant
            t0 = 550
            c0, c1 = self.read_sensor(0)
            temp = (1.22 * c0) - t0

            # Channel 1 is not connected so we don't care about its output
            logger.info("{} sensor outputs {} degree".format(
                self.sensor_names[0], temp))
            # Save output to the dict
            self.sensor_output[self.sensor_names[0]] = temp

            logger.info("Reading {} sensor...".format(self.sensor_names[1]))
            c2, c3 = self.read_sensor(1)
            sn1 = (((1.22 * c2) - 345) -
                   ((0.03) * ((1.22 * c3) - ((1.22 * c3) - 314)))) * 3.42465753
            logger.info("{} sensor outputs {} ppb".format(
                self.sensor_names[1], sn1))
            # Save output to the dict
            self.sensor_output[self.sensor_names[1]] = sn1

            logger.info("Reading {} sensor...".format(self.sensor_names[2]))
            c4, c5 = self.read_sensor(2)
            sn2 = (((1.22 * c4) - 287) - ((1.18) * (1.22 * c5) -
                                          ((1.22 * c5) - 292))) * 3.87596899
            logger.info("{} sensor outputs {} ppb".format(
                self.sensor_names[2], sn2))
            # Save output to the dict
            self.sensor_output[self.sensor_names[2]] = sn2

            logger.info("Reading {} sensor...".format(self.sensor_names[3]))
            c6, c7 = self.read_sensor(3)
            sn3 = (((1.22 * c6) - 333) - ((1.15) * (1.22 * c7) -
                                          ((1.22 * c7) - 274))) * 3.47222222
            logger.info("{} sensor outputs {} ppb".format(
                self.sensor_names[3], sn3))
            # Save output to the dict
            self.sensor_output[self.sensor_names[3]] = sn3

            logger.info("Reading {} sensor...".format(self.sensor_names[4]))
            c8, c9 = self.read_sensor(4)
            sn4 = (((1.22 * c8) - 418) - ((0.18) * (1.22 * c9) -
                                          ((1.22 * c9) - 404))) * 2.54452926
            logger.info("{} sensor outputs {} ppb".format(
                self.sensor_names[4], sn4))
            # Save output to the dict
            self.sensor_output[self.sensor_names[4]] = sn4

            logger.info("Reading {} sensor...".format(self.sensor_names[5]))
            c10, c11 = self.read_sensor(5)
            pm25 = 0.518 + 0.00274 * (240.0 * (1.22 * c10)**6 - 2491.3 *
                                      (1.22 * c10)**5 + 9448.7 *
                                      (1.22 * c10)**4 - 14840.0 *
                                      (1.22 * c10)**3 + 10684.0 *
                                      (1.22 * c10)**2 + 2211.8 *
                                      (1.22 * c10) + 7.9623)
            logger.info("{} sensor outputs {} ppb".format(
                self.sensor_names[5], pm25))
            # Save output to the dict
            self.sensor_output[self.sensor_names[5]] = pm25

            self.db_cur.execute(
                "INSERT INTO history VALUES ({}, {}, {}, {}, {}, {}, {})".
                format(epoch_time, temp, sn1, sn2, sn3, sn4, pm25))

            self.db_conn.commit()
            self.sensor_output_lock.release()

            # Idle for 3 seconds
            sleep(1.8)
예제 #3
0
class SensorServer(Thread):
    """Sensor server that keeps reading sensors and provide get_sensor_output() method for user"""
    def __init__(self):
        # Parent class constructor
        Thread.__init__(self)

        # Assign GPIO pins that controls MUX, LSB to MSB
        self.gpio_pins = [24, 25, 26, 27]
        self.gpio = Gpio()
        # Set GPIO pins to output
        try:
            for pin in self.gpio_pins:
                self.gpio.pinMode(pin, self.gpio.OUTPUT)
        except Exception as e:
            logger.error("Error setting GPIO pin, reason %s" % e.message)
            print "Error setting GPIO pin %d, reason %s" % e.message

        # Use A0 port
        self.adc_raw = "/sys/bus/iio/devices/iio:device0/in_voltage0_raw"
        self.adc_scale = "/sys/bus/iio/devices/iio:device0/in_voltage_scale"

        self.sensor_names = ['Temp', 'SN1', 'SN2', 'SN3', 'SN4', 'PM25']

        # Use a dict to store sensor output, the format is:
        # { "time": [time stamp],
        #   [sensor1 name]: [sensor1 output],
        #   ...
        #   [sensor6 name]: [sensor6 output]}
        self.sensor_output = {}

        # Create a lock to protect sensor output. That is, when updating the result, lock it on to prevent it from being
        # read at the same time; similarly, when reading the result, lock it on to prevent it from being updated.
        self.sensor_output_lock = Lock()  #스레드의 값이 이상하게 나오는 것을 막기 위해 Lock()

        self.db_conn = sqlite3.connect("air_pollution_data.db")
        self.db_cur = self.db_conn.cursor()
        for sensor_name in self.sensor_names:
            self.db_cur.execute(
                "CREATE TABLE IF NOT EXISTS %s (time int PRIMARY KEY NOT NULL, value real)"
                % sensor_name)

    def get_sensor_output(self):
        # Get the latest sensor output
        return self.sensor_output.copy()

    def set_mux_channel(self, m):
        # Set MUX channel
        # Convert n into a binary string
        bin_repr = "{0:04b}".format(m)
        # Assign value to pin
        for i in xrange(0, 4):
            self.gpio.digitalWrite(24 + i, bin_repr[i])

    def read_sensor(self, n):
        # Read raw data from sensor n, we allocate 2 channels for each sensor:
        # sensor 0: channel 0, 1
        # sensor 1: channel 2, 3
        # ...
        # sensor 7: channel 15, 16

        # Set MUX to read the first channel
        try:
            self.set_mux_channel(2 * n)
            v1 = int(open(self.adc_raw).read()) * float(
                open(self.adc_scale).read())

            # Set MUX to read the second channel
            self.set_mux_channel(2 * n + 1)
            v2 = int(open(self.adc_raw).read()) * float(
                open(self.adc_scale).read())

            return v1, v2
        except Exception as e:
            logger.error("Error reading sensor %d, reason: %s" %
                         (n, e.message))
            print "Error reading sensor %d, reason: %s" % (n, e.message)
            return 0.0, 0.0

    def run(self):
        # Keep reading sensors
        while True:
            # Acquire the lock
            self.sensor_output_lock.acquire()
            # Add time stamp
            self.sensor_output['time'] = int(time())

            # Do sensor reading here
            #  1. set MUX to sensor 1, read sensor 1;
            #  2. set MUX to sensor 2, read sensor 2;
            #  ...
            #  n. set MUX to sensor n, read sensor n.
            for i in xrange(0, 6):
                logger.info("Reading %s sensor..." % self.sensor_names[i])
                print "Reading %s sensor..." % self.sensor_names[i]
                v1, v2 = self.read_sensor(i)
                self.sensor_output[self.sensor_names[i]] = v1 - v2

            self.sensor_output_lock.release()

            # Idle for 3 seconds
            sleep(3)
예제 #4
0
    gpiopins = [8, 9, 10, 11]
    gpio = Gpio()

    pinnum = [0, 0, 0, 0]

    # Set GPIO pins to output
    # try:
    #   for pin in gpiopins:
    #       gpio.pinMode(pin, gpio.OUTPUT)
    # except Exception as e:
    #    logger.error("Error : GPIO pin {} .reason {}".format(pin, e.message))

    # Blink example
    for i in range(4):
        neo.pinMode(gpiopins[i], neo.OUTPUT)

    while True:
        for client_handler in server.active_client_handlers.copy():

            # C0
            raw, scale = contol_mux(0, 0, 0, 0)
            sleep(0.05)
            v = raw * scale
            t = (v - 500) / 10 - 6
            t = (t * 1.8) + 32
            print("Temp: {} F ".format(t))

            # C1= NO2_WE
            raw, scale = contol_mux(0, 0, 1, 0)
            sleep(0.05)
예제 #5
0
from neo import Gpio # import Gpio library
from time import sleep # import sleep to wait for blinks

neo = Gpio() #create new Neo object

pinOne = 25 #pin to use

neo.pinMode(pinOne, neo.OUTPUT)# Use innerbank pin 2 and set it as output either 0 (neo.INPUT) or 1 (neo.OUTPUT)

#Blink example
while True: #Do for five times
	neo.digitalWrite(pinOne,neo.HIGH) #write high value to pin
	sleep(1)# wait one second
	neo.digitalWrite(pinOne,neo.LOW) #write low value to pin
	sleep(1)# wait one second
예제 #6
0
    def getSamsungCode(self):

        # Learning mode feedback led
        pinLED = 26
        # IR receiver
        pinIR = 25

        command_length_samasung = 65

        neo = Gpio()
        neo.pinMode(pinIR, neo.INPUT)
        neo.pinMode(pinLED, neo.OUTPUT)
        neo.digitalWrite(pinLED, neo.HIGH)

        sample_number = 0
        # Compute the average result after MAX_SAMPLES
        bits_sum = [0] * 32
        MAX_SAMPLES = 3
        while True:

            # stop the receiver after MAX_SAMPLES
            if sample_number == MAX_SAMPLES:
                for x in range(0, len(bits_sum)):
                    bits_sum[x] = bits_sum[x] / (MAX_SAMPLES * 1.0)
                break

            value = 1

            # Loop until get IR data
            time_to_live = 45000
            while value and time_to_live:
                value = neo.digitalRead(pinIR)
                time_to_live -= 1

            if time_to_live == 0:
                neo.digitalWrite(pinLED, neo.LOW)
                return ""

            # Grab the start time of the command
            startTime = datetime.now()

            # Used to buffer the command pulses
            command = []

            # The end of the "command" happens when we read more than
            # a certain number of 1s (1 is off for the IR receiver)
            numOnes = 0

            # Used to keep track of transitions from 1 to 0
            previousVal = 0

            while True:

                if value != previousVal:
                    # The value has changed, so calculate the length of this run
                    now = datetime.now()
                    pulseLength = now - startTime
                    startTime = now

                    command.append((previousVal, pulseLength.microseconds))
#					print str(previousVal) + " " + str(pulseLength.microseconds)
#if len(command) == command_length_samasung:
#	break
                if value:
                    numOnes = numOnes + 1
                else:
                    numOnes = 0
                if numOnes > 100:
                    break
                #if numOnes > 300:
                #	break
                previousVal = value
                value = neo.digitalRead(pinIR)

            # A Sony IR signal starts with 2400 microseconds on and 600 microseconds off;
            # that's the first wide pulse. A "1" bit is transmitted with 1200 microseconds on and 600 microseconds off,
            # while a "0" bit is transmitted with 600 microseconds on and 600 microseconds off.
            # (This encoding is also called SIRC or SIRCS encoding.)

            # Chop the header of the received IR signal
            # print command

            command = command[2:]
            command = command[:64]
            #print "Command length: " + str(len(command))
            # Establish the payload of the received IR signal
            binaryString = "".join(
                map(lambda x: "1" if x[1] > 1080 else "0",
                    filter(lambda x: x[0] == 1, command)))

            # The length of the payload, according to SONY protocol is 12 bits; skip otherwise
            #print len(binaryString)
            if len(binaryString) != 32:
                continue
            #print "Good length!"
            sample_number = sample_number + 1
            binaryString = map(int, binaryString)

            bits_sum = [sum(x) for x in zip(bits_sum, binaryString)]

        # compute the IR code based on MAX_SAMPLES
        result = ""
        for x in bits_sum:
            if x < 0.5:
                result += '0'
            else:
                result += '1'
        neo.digitalWrite(pinLED, neo.LOW)

        print result
        return result
예제 #7
0
파일: sensor.py 프로젝트: 3mocki/TEAM_D
class Reader:
    # S0,S1,S2,S3
    selector_pins = [8, 9, 10, 11]

    # Number of connected to MUX Board
    mux_channel = {
        'temp1': 0,
        'no2': {
            'we': 1,
            'ae': 2
        },
        'o3': {
            'we': 3,
            'ae': 4
        },
        'co': {
            'we': 5,
            'ae': 6
        },
        'so2': {
            'we': 7,
            'ae': 8
        },
        'pm2_5': 9,
    }

    # Refer to 25-000160 Alphasense Datasheet
    calibration = {
        'no2': {
            'n': [1.18, 1.18, 1.18, 1.18, 1.18, 1.18, 1.18, 2.00],
            'we_zero': 295,
            'ae_zero': 282,
            'sensitivity': 0.228
        },
        'o3': {
            'n': [0.18, 0.18, 0.18, 0.18, 0.18, 0.18, 0.18, 0.18],
            'we_zero': 391,
            'ae_zero': 390,
            'sensitivity': 0.399
        },
        'co': {
            'n': [1.40, 1.03, 0.85, 0.62, 0.30, 0.03, -0.25, -0.48],
            'we_zero': 347,
            'ae_zero': 296,
            'sensitivity': 0.267
        },
        'so2': {
            'n': [0.85, 0.85, 0.85, 0.85, 0.85, 1.15, 1.45, 1.75],
            'we_zero': 345,
            'ae_zero': 255,
            'sensitivity': 0.318
        }
    }

    def __init__(self):
        self.lock = threading.Lock()
        self.gpio = Gpio()

        # init to LOW
        self.lock.acquire()
        for pin in Reader.selector_pins:
            self.gpio.pinMode(pin, self.gpio.OUTPUT)
            self.gpio.digitalWrite(pin, self.gpio.LOW)
        self.lock.release()

    # Read NO2, SO2, O3, CO, PM2.5, TEMP
    def read_no2(self):  # Had a problem on sensors
        return round(self.__calibrate('no2') * 1000, 2)

    def read_o3(self):
        return round(self.__calibrate('o3') * 100, 2)

    def read_co(self):
        return round(self.__calibrate('co'), 2)

    def read_so2(self):
        return round(self.__calibrate('so2') * 1000, 2)

    def read_temp(self):
        mV = self.__read_adc(Reader.mux_channel['temp1'])
        temp = (mV - 500) * 0.1  # Celcius Value
        ftemp = (temp * 1.8) + 32  # Celcius to Fahrenheit
        return round(ftemp, 2)

    def read_pm(self):
        mV = self.__read_adc(Reader.mux_channel['pm2_5'])
        v = mV / 1000

        hppcf = 240 * (v**6) - 2491.3 * (v**5) + 9448.7 * (v**4) - 14840 * (
            v**3) + 10684 * (v**2) + 2211.8 * v + 7.9623
        ugm3 = .518 + .00274 * hppcf
        return round(ugm3, 3)

    def __read_adc(self, channel):
        s_bin = self.__dec_to_bin(channel)

        self.lock.acquire()

        # write
        for i in range(4):
            self.gpio.digitalWrite(Reader.selector_pins[i], s_bin[i])

        # read
        raw = int(
            open("/sys/bus/iio/devices/iio:device0/in_voltage0_raw").read())
        scale = float(
            open("/sys/bus/iio/devices/iio:device0/in_voltage_scale").read())

        self.lock.release()

        return raw * scale

    def __calibrate(self, name):

        we = self.__read_adc(Reader.mux_channel[name]['we'])
        ae = self.__read_adc(Reader.mux_channel[name]['ae'])

        temperature = self.read_temp()
        calibration = Reader.calibration[name]
        we = we - calibration['we_zero']
        ae = ae - calibration['ae_zero']
        temp = int(temperature / 10) + 3
        if temp > 7:
            temp = 7
        ae = (calibration['n'][temp]) * ae
        we = (we - ae) / calibration['sensitivity']
        if we / 1000 > 0:
            return we / 1000
        else:
            return 0

    def __dec_to_bin(self, n):
        num = [0, 0, 0, 0]

        if n == 0:
            return num
        else:
            for x in range(n):
                t = x + 1
                for y in range(4):
                    num[y] = t % 2
                    t = t / 2
            return num
예제 #8
0
# A easy Gpio library example for the Udoo Neo created by David Smerkous
# The current things this library can do

# digitalWriting/Reading - Soon to come PWM

from neo import Gpio # import Gpio library
from time import sleep # import sleep to wait for blinks

neo = Gpio() #create new Neo object

pinTwo = 2 #pin to use
pinThree = 3

neo.pinMode(pinTwo, neo.OUTPUT)# Use innerbank pin 2 and set it as output either 0 (neo.INPUT) or 1 (neo.OUTPUT)
neo.pinMode(pinThree, neo.INPUT)# Use pin three(innerbank) and read set state to read

#Blink example
for a in range(0, 5): #Do for five times
	neo.digitalWrite(pinTwo,neo.HIGH) #write high value to pin
	sleep(1)# wait one second
	neo.digitalWrite(pinTwo,neo.LOW) #write low value to pin
	sleep(1)# wait one second

#Read pin
print "Current pin("+str(pinThree)+") state is: "+str(neo.digitalRead(pinThree)) # read current value of pinThree(To succesfully read a pin it must be either pulled to ground or 3.3v, a non connected wire will not work)
예제 #9
0
	def getCode(self):
		
		# Learning mode feedback led
		pinLED = 26
		# IR receiver 
		pinIR = 25

		neo = Gpio()
		neo.pinMode(pinIR, neo.INPUT) 
		neo.pinMode(pinLED, neo.OUTPUT)
		neo.digitalWrite(pinLED, neo.HIGH)

		# Compute the average result after MAX_SAMPLES
		gap_number = 0
		MAX_GAPS = 3
		GAP_TIME = 20000
		
		value = 1

		time_to_live = 45000 
		while value and time_to_live:
			value = neo.digitalRead(pinIR)
			time_to_live -= 1

		if time_to_live == 0:
			neo.digitalWrite(pinLED, neo.LOW)
			return ""

		# Grab the start time of the command
		startTime = datetime.now()

		# Used to buffer the command pulses
		command = []

		# Used to keep track of transitions from 1 to 0
		previousVal = 0

		while True:

			if value != previousVal:
				# The value has changed, so calculate the length of this run
				now = datetime.now()
				pulseLength = now - startTime
				startTime = now
				if pulseLength.microseconds > GAP_TIME:
					gap_number = gap_number + 1
				if gap_number == MAX_GAPS:
					break
				command.append((previousVal, pulseLength.microseconds))

			previousVal = value
			value = neo.digitalRead(pinIR)
		
		
		neo.digitalWrite(pinLED, neo.LOW)
		result = ""
		for (i, j) in command:
			result = result + " " + str(j)
		#result = result.replace(",", "")
		result = result[1:]
		print result
		return result
예제 #10
0
            epoch_time = int(time())  # epoch time
            neo = Gpio()

            S0 = 8  # pin to use
            S1 = 9
            S2 = 10
            S3 = 11

            pinNum = [S0, S1, S2, S3]

            num = [0, 0, 0, 0]

            # Blink example
            for i in range(4):
                neo.pinMode(pinNum[i], neo.OUTPUT)

            #Temperature sensor
            neo.digitalWrite(pinNum[0], 0)
            neo.digitalWrite(pinNum[1], 0)
            neo.digitalWrite(pinNum[2], 0)
            neo.digitalWrite(pinNum[3], 0)
            sleep(0.05)

            raw = int(
                open(
                    "/sys/bus/iio/devices/iio:device0/in_voltage0_raw").read())
            scale = float(
                open("/sys/bus/iio/devices/iio:device0/in_voltage_scale").read(
                ))
            c0 = raw * scale
예제 #11
0
class SensorServer(Thread):
    """Sensor server that keeps reading sensors and provide get_sensor_output() method for user"""
    def __init__(self, database_name="air_pollution_data.db"):
        # Parent class constructor
        Thread.__init__(self)

        # Assign GPIO pins that controls MUX, LSB to MSB
        self.gpio_pins = [24, 25, 26, 27]
        self.gpio = Gpio()
        # Set GPIO pins to output
        try:
            for pin in self.gpio_pins:
                self.gpio.pinMode(pin, self.gpio.OUTPUT)
        except Exception as e:
            logger.error("Error setting GPIO pin {}, reason {}".format(
                pin, e.message))

        # Use A0 port
        self.adc_raw = "/sys/bus/iio/devices/iio:device0/in_voltage0_raw"
        self.adc_scale = "/sys/bus/iio/devices/iio:device0/in_voltage_scale"

        self.sensor_names = ['Temp', 'SN1', 'SN2', 'SN3', 'SN4', 'PM25']

        # Use a dict to store sensor output, the format is:
        # { "time": [time stamp],
        #   [sensor1 name]: [sensor1 output],
        #   ...
        #   [sensor6 name]: [sensor6 output]}
        self.sensor_output = {}

        # Create a lock to protect sensor output. That is, when updating the result, lock it on to prevent it from being
        # read at the same time; similarly, when reading the result, lock it on to prevent it from being updated.
        self.sensor_output_lock = Lock()

        # Here we have a decision to make. I decide to let sensor server write sensor outputs to the local database. Of
        # course we can do so in a different thread either in a synchronous way or in an asynchronous way. If we do it
        # with a synchronous approach, we need to use locks to keep synchronization; if we do it with an asynchronous
        # solution, then SQLite3 is already an asynchronous module and I don't see good reason of adding another layer
        # of complexity. Perhaps the most reasonable way would be specifying the database in the main thread and then
        # send it to the sensor server thread.
        self.database_name = database_name

        try:
            # Create the database file and get the connection object.
            self.db_conn = sqlite3.connect(self.database_name)
            # Get database cursor from the connection object.
            self.db_cur = self.db_conn.cursor()
        except Exception as e:
            logger.error("Error connecting the database {}, reason: {}".format(
                self.database_name, e.message))
            self.__del__()

        # Create tables for each sensors. Each table consists a time stamp key (epoch time) in integer and a real value
        # to hold the result of the sensor. Create tables only if they are not exist.
        for sensor_name in self.sensor_names:
            self.db_cur.execute(
                "CREATE TABLE IF NOT EXISTS {} (time int PRIMARY KEY NOT NULL, value real)"
                .format(sensor_name))

        # Commit the changes. When a database is accessed by multiple connections, and one of the processes modifies the
        # database, the SQLite database is locked until that transaction is committed. The timeout parameter specifies
        # how long the connection should wait for the lock to go away until raising an exception. The default for the
        # timeout parameter is 5.0 (five seconds).
        self.db_conn.commit()

    def __del__(self):
        # Gracefully close the database connection.
        self.db_conn.close()
        # Reset GPIOs.
        for i in xrange(0, 4):
            self.gpio.digitalWrite(24 + i, Gpio.LOW)

    def get_sensor_output(self):
        # Get the latest sensor output
        return self.sensor_output.copy()

    def set_mux_channel(self, m):
        # Set MUX channel
        # Convert n into a binary string
        bin_repr = "{0:04b}".format(m)
        # Assign value to pin
        for i in xrange(0, 4):
            self.gpio.digitalWrite(24 + i, bin_repr[i])

    def read_sensor(self, n):
        # Read raw data from sensor n, we allocate 2 channels for each sensor:
        # sensor 0: channel 0, 1
        # sensor 1: channel 2, 3
        # ...
        # sensor 7: channel 15, 16

        # Set MUX to read the first channel
        try:
            self.set_mux_channel(2 * n)
            # Wait for 50 ms
            sleep(0.05)
            v1 = int(open(self.adc_raw).read()) * float(
                open(self.adc_scale).read())

            # Set MUX to read the second channel
            self.set_mux_channel(2 * n + 1)
            sleep(0.05)
            v2 = int(open(self.adc_raw).read()) * float(
                open(self.adc_scale).read())

            return v1, v2
        except Exception as e:
            logger.error("Error reading sensor {}, reason: {}".format(
                n, e.message))
            return 0.0, 0.0

    def run(self):
        try:
            # Create the database file and get the connection object.
            self.db_conn = sqlite3.connect(self.database_name)
            # Get database cursor from the connection object.
            self.db_cur = self.db_conn.cursor()
        except Exception as e:
            logger.error("Error connecting the database {}, reason: {}".format(
                self.database_name, e.message))
            self.__del__()

        # Keep reading sensors.
        while True:
            # Acquire the lock
            self.sensor_output_lock.acquire()
            # Add time stamp
            epoch_time = int(time())
            self.sensor_output['time'] = epoch_time

            # Do sensor reading here
            #  1. set MUX to sensor 0, read sensor 0;
            #  2. set MUX to sensor 1, read sensor 1;
            #  ...
            #  n. set MUX to sensor n - 1, read sensor n - 1.
            logger.info("Reading {} sensor...".format(self.sensor_names[0]))
            # Temperature constant
            t0 = 550
            c0, c1 = self.read_sensor(0)
            # Channel 1 is not connected so we don't care about its output
            temperature = c0 - t0
            logger.info("{} sensor outputs {} degree".format(
                self.sensor_names[0], temperature))
            # Save output to the dict
            self.sensor_output[self.sensor_names[0]] = temperature
            self.db_cur.execute("INSERT INTO {} VALUES ({}, {})".format(
                self.sensor_names[0], epoch_time, temperature))

            logger.info("Reading {} sensor...".format(self.sensor_names[1]))
            c2, c3 = self.read_sensor(1)  # NO2
            output = ((c2 - 0.215) - (1.35) * (c3 - 0.246)) / (-0.212)
            logger.info("{} sensor outputs {} ppb".format(
                self.sensor_names[1], output))
            # Save output to the dict
            self.sensor_output[self.sensor_names[1]] = output
            self.db_cur.execute("INSERT INTO {} VALUES ({}, {})".format(
                self.sensor_names[1], epoch_time, output))

            logger.info("Reading {} sensor...".format(self.sensor_names[2]))
            c4, c5 = self.read_sensor(2)  # O3
            output = ((c4 - 0.39) - (1.28) * (c5 - 0.393)) / (-0.276)
            logger.info("{} sensor outputs {} ppb".format(
                self.sensor_names[2], output))
            # Save output to the dict
            self.sensor_output[self.sensor_names[2]] = output
            self.db_cur.execute("INSERT INTO {} VALUES ({}, {})".format(
                self.sensor_names[2], epoch_time, output))

            logger.info("Reading {} sensor...".format(self.sensor_names[3]))
            c6, c7 = self.read_sensor(3)  #CO
            output = ((c4 - 0.39) - (1.28) * (c5 - 0.393)) / (-0.276)
            logger.info("{} sensor outputs {} ppb".format(
                self.sensor_names[3], output))
            # Save output to the dict
            self.sensor_output[self.sensor_names[3]] = output
            self.db_cur.execute("INSERT INTO {} VALUES ({}, {})".format(
                self.sensor_names[3], epoch_time, output))

            logger.info("Reading {} sensor...".format(self.sensor_names[4]))
            c8, c9 = self.read_sensor(4)  #SO2
            output = ((c8 - 0.28) - (1.82) * (c9 - 0.306)) / (-0.296)
            logger.info("{} sensor outputs {} ppb".format(
                self.sensor_names[4], output))
            # Save output to the dict
            self.sensor_output[self.sensor_names[4]] = output
            self.db_cur.execute("INSERT INTO {} VALUES ({}, {})".format(
                self.sensor_names[4], epoch_time, output))

            logger.info("Reading {} sensor...".format(self.sensor_names[5]))
            c10, c11 = self.read_sensor(5)
            output = c10 - c11
            logger.info("{} sensor outputs {} ppb".format(
                self.sensor_names[5], output))
            # Save output to the dict
            self.sensor_output[self.sensor_names[5]] = output
            self.db_cur.execute("INSERT INTO {} VALUES ({}, {})".format(
                self.sensor_names[5], epoch_time, output))

            self.db_conn.commit()
            self.sensor_output_lock.release()

            # Idle for 3 seconds
            sleep(1.8)
예제 #12
0
파일: sensing.py 프로젝트: qi2018d/sensor
class SensingThread(threading.Thread):

    selector_pins = [16, 17, 18, 19]
    mux_channel = {
        'no2': {
            'we': 2,
            'ae': 3
        },
        'o3': {
            'we': 4,
            'ae': 5
        },
        'co': {
            'we': 6,
            'ae': 7
        },
        'so2': {
            'we': 8,
            'ae': 9
        },
        'temp': 0,
        'pm2_5': 1,
    }
    calibration = {
        'no2': {
            'n': [1.18, 1.18, 1.18, 1.18, 1.18, 1.18, 1.18, 2.00],
            'we_zero': 287,
            'ae_zero': 292,
            'sensitivity': 0.258
        },
        'o3': {
            'n': [0.18, 0.18, 0.18, 0.18, 0.18, 0.18, 0.18, 0.18],
            'we_zero': 418,
            'ae_zero': 404,
            'sensitivity': 0.393
        },
        'co': {
            'n': [1.40, 1.03, 0.85, 0.62, 0.30, 0.03, -0.25, -0.48],
            'we_zero': 345,
            'ae_zero': 314,
            'sensitivity': 0.292
        },
        'so2': {
            'n': [0.85, 0.85, 0.85, 0.85, 0.85, 1.15, 1.45, 1.75],
            'we_zero': 333,
            'ae_zero': 274,
            'sensitivity': 0.288
        }
    }

    read_time = 0.2

    def __init__(self, sender):
        threading.Thread.__init__(self)

        self.sender = sender
        self.gpio = Gpio()

        # init to LOW
        for pin in SensingThread.selector_pins:
            self.gpio.pinMode(pin, self.gpio.OUTPUT)
            self.gpio.digitalWrite(pin, self.gpio.LOW)

    def run(self):
        while True:
            data = self.__read_all()
            print "Raw value : " + str(data)
            DBManager.insert_air_data(data)
            self.sender.send({"type": "real-time", "data": data})

    def __read_all(self):
        """
        Read all sensor values
        :return: json string of sensor values (temp, so2, no2, co, o3, pm25)
        """

        temp = round(self.__read_temp(), 2)
        no2 = round(self.__read_no2_ppb(temp), 2)
        o3 = round(self.__read_o3_ppb(temp), 2)
        co = round(self.__read_co_ppm(temp), 2)
        so2 = round(self.__read_so2_ppb(temp), 2)
        pm2_5 = round(self.__read_pm2_5(), 2)
        timestamp = int(time.time())

        return {
            'temp': temp,
            'no2': no2,
            'o3': o3,
            'co': co,
            'so2': so2,
            'pm2_5': pm2_5,
            'time': timestamp
        }

    def __read_temp(self):

        channel = SensingThread.mux_channel['temp']
        subtotal = 0.0
        c = 0
        start_time = time.time()

        while time.time() - start_time < SensingThread.read_time:

            mV = self.__read_adc(channel)
            temp = (mV - 500) / 10 - 10

            subtotal += temp
            c += 1

        result = subtotal / c

        if result > 50:
            result = 50
        if result < -20:
            result = -20

        return result
        #return 25
    def __read_no2_ppb(self, temp):
        return self.__calibrate_op('no2', temp)

    def __read_o3_ppb(self, temp):
        return self.__calibrate_op('o3', temp)

    def __read_co_ppm(self, temp):
        return self.__calibrate_op('co', temp) / 1000

    def __read_so2_ppb(self, temp):
        return self.__calibrate_op('so2', temp)

    def __read_pm2_5(self):

        subtotal = 0.0
        c = 0
        start_time = time.time()

        while time.time() - start_time < SensingThread.read_time:

            v = self.__read_adc(SensingThread.mux_channel['pm2_5']) / 1000
            hppcf = 240.0 * (v**6) - 2491.3 * (v**5) + 9448.7 * (
                v**4) - 14840.0 * (v**3) + 10684.0 * (v**
                                                      2) + 2211.8 * v + 7.9623
            subtotal += .518 + .00274 * hppcf
            c += 1

        return subtotal / c

    def __calibrate_op(self, name, temp):

        channel_we = SensingThread.mux_channel[name]['we']
        channel_ae = SensingThread.mux_channel[name]['ae']
        calibration = SensingThread.calibration[name]
        zero_we = calibration['we_zero']
        zero_ae = calibration['ae_zero']

        subtotal = 0.0
        c = 0
        start_time = time.time()

        while time.time() - start_time < SensingThread.read_time:

            we = self.__read_adc(channel_we)
            ae = self.__read_adc(channel_ae)

            we = we - zero_we
            ae = ae - zero_ae

            if temp > 50:
                temp = 50
            elif temp < -20:
                temp = -20

            ae = (calibration['n'][int(temp / 10) + 2]) * ae
            we = (we - ae) / calibration['sensitivity']

            subtotal += we if we > 0 else 0
            c += 1

        # ppb
        return subtotal / c

    def __read_adc(self, channel):
        s_bin = self.__dec_to_bin(channel)

        # write
        for i in range(4):
            self.gpio.digitalWrite(SensingThread.selector_pins[i], s_bin[i])

        # read
        raw = int(
            open("/sys/bus/iio/devices/iio:device0/in_voltage0_raw").read())
        scale = float(
            open("/sys/bus/iio/devices/iio:device0/in_voltage_scale").read())

        return raw * scale

    def __dec_to_bin(self, n):
        num = [0, 0, 0, 0]

        if n == 0:
            return num
        else:
            for x in range(n):
                t = x + 1
                for y in range(4):
                    num[y] = t % 2
                    t = t / 2
            return num
예제 #13
0
from neo import Gpio
from time import sleep

neo = Gpio()

pinNum = [0, 1, 2, 3]

for i in pinNum:
    neo.pinMode(pinNum[i], neo.OUTPUT)

for x in range(15):
    num = [0, 0, 0, 0]
    t = x + 1
    for y in range(4):
        num[y] = t % 2
        t = t / 2

    neo.digitalWrite(pinNum[3], num[3])
    neo.digitalWrite(pinNum[2], num[2])
    neo.digitalWrite(pinNum[1], num[1])
    neo.digitalWrite(pinNum[0], num[0])
    sleep(1)