├── README.md ├── alarm_clock ├── README.md ├── alarm.py └── buzzer.py ├── buffer-ph-adjuster ├── README.md ├── buffer-ph-range.py ├── buffer-ph.py └── calibrate.py ├── dna-flashing-led ├── RTT103.fasta ├── bioseq.py ├── nu_blink.py └── readme.md ├── ldn-bus-ticker ├── README.md ├── TfLAPI.py ├── TfLAPI.pyc ├── data │ └── tfl-bus-stops.csv ├── dist │ └── ldn-bus-ticker.tar.gz └── ldn-bus-ticker.py ├── led-matrix ├── LEDController │ ├── __init__.py │ ├── __init__.pyc │ ├── controller.pyc │ ├── functions.py │ └── functions.pyc ├── MANIFEST ├── README.md ├── dist │ └── LEDController-0.1.1.tar.gz ├── gui-matrix.ui ├── icon.ico ├── icon.png ├── led-controller-gui.py ├── london-underground-neopixel │ ├── README.md │ └── underground_status.py └── setup.py ├── london-underground-neopixel ├── README.md └── underground_status.py ├── neopixel-timer ├── README.md ├── neopixel-timer.py └── potentiometer.py ├── servo-temp ├── README.md ├── main.py └── temp.py └── streaming-temp-neopixel ├── README.md ├── config.json ├── main.py └── temp.py /README.md: -------------------------------------------------------------------------------- 1 | Raspberry Pi related projects 2 | =========== 3 | 4 | A collection of Python 2-based Raspberry Pi code projects, accompanying tutorials at www.scienceexposure.com 5 | -------------------------------------------------------------------------------- /alarm_clock/README.md: -------------------------------------------------------------------------------- 1 | # Alarm clock 2 | 3 | ### Summary 4 | This script is to accompany the 'Alarm clock' tutorial at www.scienceexposure.com. A full explanation on how to set up the RPi using a breadboard, as well as an explanation of this script is available in the post. 5 | 6 | ### Requirements 7 | - Raspberry Pi 8 | - Buzzer 9 | - Switch 10 | 11 | _Recommended:_ 12 | - Breadboard 13 | 14 | ### Usage 15 | Run from a terminal on the RPi using the following `sudo python alarm.py`. Ensure the accompanying `buzzer.py` file / module is in the same directory as this file. 16 | -------------------------------------------------------------------------------- /alarm_clock/alarm.py: -------------------------------------------------------------------------------- 1 | # Raspberry Pi Alarm Clock 2 | # 2014, Ismail Uddin 3 | # www.scienceexposure.com 4 | 5 | import time 6 | import RPi.GPIO as GPIO 7 | from buzzer import buzz 8 | 9 | GPIO.setmode(GPIO.BCM) 10 | GPIO.setup(25, GPIO.IN, pull_up_down=GPIO.PUD_UP) 11 | 12 | response = raw_input("Please input the time for the alarm in format HHMM: \n") 13 | 14 | print("Alarm has been set for %s hrs" % response) 15 | buzz(500,0.1) 16 | 17 | alarm = int(response) 18 | awake = 0 19 | 20 | try: 21 | # Loop to continuously check time, buzz the buzzer for the set alarm time 22 | while True: 23 | # Continually get's the time as an integer value 24 | curr_time = int(time.strftime("%H%M")) 25 | 26 | # Buzzes the buzzer when the time reaches the set alarm time 27 | if curr_time == alarm: 28 | buzz(10,0.5) 29 | time.sleep(0.25) 30 | buzz(20,0.5) 31 | time.sleep(0.25) 32 | awake = 1 33 | 34 | # Snoozes the alarm for 8 minutes from the current time 35 | # Only works whilst the alarm is buzzing 36 | if GPIO.input(25) == 0 and awake == 1: 37 | alarm += 8 38 | awake = 0 39 | print(alarm) 40 | 41 | # If alarm continues past the set alarm time without being 42 | # snoozed, the alarm time is changed to the current time. 43 | # This ensures the alarm buzzes continuously until the 44 | # snooze button is pressed. 45 | elif curr_time != alarm and awake == 1: 46 | alarm = curr_time 47 | buzz(10,0.5) 48 | time.sleep(0.25) 49 | buzz(20,0.5) 50 | 51 | finally: 52 | GPIO.cleanup() 53 | print("End") 54 | -------------------------------------------------------------------------------- /alarm_clock/buzzer.py: -------------------------------------------------------------------------------- 1 | # Script forked from Simon Monk's 'Pi Starter Kit' repo 2 | # https://github.com/simonmonk/pi_starter_kit 3 | 4 | import RPi.GPIO as GPIO 5 | import time 6 | 7 | GPIO.setmode(GPIO.BCM) 8 | 9 | buzzer_pin = 24 10 | 11 | GPIO.setup(buzzer_pin, GPIO.OUT) 12 | 13 | def buzz(pitch, duration): 14 | period = 1.0 / pitch 15 | delay = period / 2 16 | cycles = int(duration * pitch) 17 | for i in range(cycles): 18 | GPIO.output(buzzer_pin, True) 19 | time.sleep(delay) 20 | GPIO.output(buzzer_pin, False) 21 | time.sleep(delay) 22 | -------------------------------------------------------------------------------- /buffer-ph-adjuster/README.md: -------------------------------------------------------------------------------- 1 | # Buffer pH adjuster 2 | This code accompanies the 'Buffer pH adjuster' tutorial at www.scienceexposure.com. To use this code, you will need necessary accompanying hardware (listed in full detail on the tutorial page). This code allows you to build a project that monitors the pH of a solution, and adjusts it automatically by dispensing from an acid or alkali reservoir, to the pH value you have set. 3 | 4 | The `calibrate.py` code is run once a day for calibrating the pH meter, and the `buffer-ph.py` is the main code for the project. 5 | 6 | ## Requirements 7 | * Raspberry Pi (any model will do) 8 | * PySerial 2.6 9 | * Atlas Scientific pH kit 10 | * RaspiRobot board v2 11 | * Monk Makes 'RaspiRobot board' API (https://github.com/simonmonk/raspirobotboard2) 12 | 13 | ## Running the code 14 | Type `sudo python calibrate.py` to run the calibration code, and `sudo python buffer-ph.py` to run the main code. For more details, see the 'Buffer pH adjuster' tutorial at www.scienceexposure.com 15 | -------------------------------------------------------------------------------- /buffer-ph-adjuster/buffer-ph-range.py: -------------------------------------------------------------------------------- 1 | # Buffer pH adjuster 2 | # www.scienceexposure.com 3 | # Ismail Uddin, 2015 4 | # This has sections adapted from the sample code provided by Atlas Scientific 5 | # provided here: http://atlas-scientific.com/_files/code/pi_sample_code.pdf 6 | 7 | from rrb2 import * 8 | import serial 9 | pH_range_upper = ("Please iput the upper value of pH you would like to set as a digit:") 10 | pH_range_lower = ("Please iput the lower value of pH you would like to set as a digit:") 11 | time_intvl = ("Please input the time interval for taking readings, in seconds:") 12 | 13 | print("Press Ctrl-C to stop adjusting the pH") 14 | 15 | # Initialising EZO pH circuit 16 | usbport = '/dev/ttyAMA0' 17 | ser = serial.Serial(usbport,9600) 18 | 19 | # Initialize RaspiRobot board 20 | rr = RRB2() 21 | 22 | 23 | 24 | pH_range = range(pH_range_lower, pH_range_upper) 25 | 26 | def ph_reading(): 27 | # pH meter readings 28 | line = "" 29 | data = ser.read() 30 | if data == "/r": 31 | ph_value = float(line) 32 | line = "" 33 | else: 34 | line = line + data 35 | return ph_value 36 | 37 | curr_ph = ph_reading() 38 | 39 | while True: 40 | time.sleep(time_intvl) 41 | curr_ph = ph_reading() 42 | print("Current pH: %s" % curr_ph) 43 | 44 | 45 | if curr_ph < pH_range_lower: 46 | # Turn on pump supplying alkali 47 | rr.set_motors(0.25,0,0,0) 48 | print("Dispensing alkali...") 49 | time.sleep(0.35) 50 | rr.stop() 51 | 52 | elif curr_ph > pH_range_upper: 53 | # Turn on pump supplying acid_pump 54 | rr.set_motors(0,0,0.25,0) 55 | print("Dispensing acid...") 56 | time.sleep(0.35) 57 | rr.stop() 58 | -------------------------------------------------------------------------------- /buffer-ph-adjuster/buffer-ph.py: -------------------------------------------------------------------------------- 1 | # Buffer pH adjuster 2 | # www.scienceexposure.com 3 | # Ismail Uddin, 2015 4 | # This has sections adapted from the sample code provided by Atlas Scientific 5 | # provided here: http://atlas-scientific.com/_files/code/pi_sample_code.pdf 6 | 7 | from rrb2 import * 8 | import serial 9 | rr = RRB2() 10 | 11 | # pH value to set buffer at 12 | ph_set = ("Input the value of pH you would like set as a digit:") 13 | print("Press Ctrl-C to stop adjusting the pH") 14 | 15 | # Initialising EZO pH circuit 16 | usbport = '/dev/ttyAMA0' 17 | ser = serial.Serial(usbport,9600) 18 | 19 | 20 | 21 | def ph_reading(): 22 | # pH meter readings 23 | line = "" 24 | data = ser.read() 25 | if data == "/r": 26 | ph_value = float(line) 27 | line = "" 28 | else: 29 | line = line + data 30 | return ph_value 31 | 32 | curr_ph = ph_reading 33 | 34 | while ph_set != curr_ph: 35 | curr_ph = ph_reading() 36 | print("Current pH: %s" % curr_ph) 37 | 38 | if curr_ph < ph_set: 39 | # Turn on pump supplying alkali 40 | rr.set_motors(0.25,0,0,0) 41 | print("Dispensing alkali...") 42 | time.sleep(0.35) 43 | rr.stop() 44 | 45 | elif curr_ph > ph_set: 46 | # Turn on pump supplying acid_pump 47 | rr.set_motors(0,0,0.25,0) 48 | print("Dispensing acid...") 49 | time.sleep(0.35) 50 | rr.stop() 51 | 52 | time.sleep(0.5) 53 | 54 | -------------------------------------------------------------------------------- /buffer-ph-adjuster/calibrate.py: -------------------------------------------------------------------------------- 1 | # Buffer pH adjuster 2 | # www.scienceexposure.com 3 | # Ismail Uddin, 2015 4 | # This has sections adapted from the sample code provided by Atlas Scientific 5 | # provided here: http://atlas-scientific.com/_files/code/pi_sample_code.pdf 6 | 7 | from rrb2 import * 8 | import serial 9 | 10 | print("Calibration will begin with ph solution 4, followed by 7 and 10") 11 | 12 | # Initialising EZO pH circuit 13 | usbport = '/dev/ttyAMA0' 14 | ser = serial.Serial(usbport,9600) 15 | 16 | # pH meter readings 17 | 18 | 19 | def ph_reading(): 20 | line = "" 21 | data = ser.read() 22 | if data == "/r": 23 | ph_value = float(line) 24 | line = "" 25 | else: 26 | line = line + data 27 | return ph_value 28 | 29 | 30 | curr_ph = ph_reading() 31 | 32 | # Calibrating at pH 4 33 | try: 34 | curr_ph = ph_reading() 35 | ser.write("cal,low,4\r") 36 | while curr_pH != 4: 37 | try: 38 | time.sleep(0.5) 39 | print("Current pH: %s" % curr_ph) 40 | finally: 41 | pass 42 | finally: 43 | pass 44 | 45 | # Calibrating at pH 7 46 | try: 47 | curr_ph = ph_reading() 48 | ser.write("cal,mid,7\r") 49 | while curr_pH != 7: 50 | try: 51 | time.sleep(0.5) 52 | print("Current pH: %s" % curr_ph) 53 | finally: 54 | pass 55 | finally: 56 | pass 57 | 58 | # Calibrating at pH 10 59 | try: 60 | curr_ph = ph_reading() 61 | ser.write("cal,high,10\r") 62 | while curr_pH != 10: 63 | try: 64 | time.sleep(0.5) 65 | print("Current pH: %s" % curr_ph) 66 | finally: 67 | pass 68 | finally: 69 | pass 70 | -------------------------------------------------------------------------------- /dna-flashing-led/RTT103.fasta: -------------------------------------------------------------------------------- 1 | >gi|330443520:1038095-1039692 Saccharomyces cerevisiae S288c chromosome IV, complete sequence 2 | TATTCTATATAGCATTGCATAGGTGTCCATGTAGTTTAGGTGCGCATCTTTTTTGTCGAGGAAATAGTGA 3 | AGATGAATACGAAATAAACTATGGGCAAATAGTTACGAAAAAAGACTGGACTTAAACGGGTTACTATATA 4 | TTTGTATAAGTTATCTCCTTGTTTTCTTTTTACTCAACCATCATATTAATTTGCAAGCTTACTTAACAAG 5 | TCTTGTATACTAGAAGAAACCCCTCCGGAATTCTCAACACCTTCGTCGGTTTGGGCGCCGACGTGGCCTT 6 | CTATATCTAACTCATAATGTCCATCCTCACTGTTGAAAGTACCATCTTCACTCGTCTTCGAATCAAGATG 7 | AACCTTTTTTTCCGGTATGTCATTAGCGTCATCATGACCTATCATATCATGTGTTCGTTTCATACCAAAT 8 | TGATTGTCACTAGGATTATGAGTAGAGTTTTTATGTTCGCTATCTGTCTTTTCTACAACTTCATTCTTCT 9 | TATCTGTGGTGCTAATATTAGTAACGCCATAATTGCTGTCATTGGATCTATCATCGTAATTTTTGTCATC 10 | ATCATCATCATCATCATCATCATCATTATCACCATCATCGTCATCGTCATCTCCATCCCCCACTTCATAC 11 | GTAGGAATAATATTGTCTTCATCAACGTTTTTATTTAATCTGGATGGGTCTTTAGCAGATAAAACGAATT 12 | CTATTTCACTTAACATATTCTGTTCCTCATCTAGATGCCTTTTTTCATCGTCCAGTGTGCTTTGCAGTTT 13 | ATGGATACCGCTTTCTCTTTTTAGAATTGATTCATTTATTATATCTTTAGCCATGTTCCCAATCTTACTT 14 | ATTGTTTTAAAATTTTCCTCGTAAACTGAGCTGGATGGATCCAATTCATCTGATGATTTGTCAAATCTCA 15 | TTTTCATCGCGCAAACATTATGGTGCATTTTCACTAATTTTTCATAGTCCTTAGCAAAATCTTTCAATTT 16 | CTGGGGTAACACCAACGCTTCCACTGGTGAGCTCTCGGTTTTAAGACTTCTTTCTATGTCATTGACTACC 17 | TGCTTGGAAAATATATTTCTTTCTTTTAGTATATTCACAACTCTTGACAACTTCTTTTTTAGGTCCCTCG 18 | GAAACTCTTGATTAATTCTTCCCAATACTTCTGCTGCCACCTTTCCAAAGGAATCTTGAAATTGAATAAT 19 | TTTTTGACCTTTAGCCTGTTGAACAACATGATTCATTAAGTAAAGACCCAATAACTTCCTTCTTGTGTTT 20 | ACACTAGGCCTTAACATGTATTCTTTCCACATTTCTGCCACTTTGGGAGCATCTCTATACTGTAGAAGCA 21 | ACCACTTTGAGGCACTGGAAATAGATTCTTGGGAATCTTCCAACGTATTTAATTTGGTTGTGAATTGCTC 22 | AGAAGAGAAAGGCATACCGTCTATTTTAATCTTGGATTATTGCTTTCTTCAAATTTTCTACCTCTTCGTT 23 | AAAACCTTCTTCGCTTGTACTTATATTATTATGTTGGCTTTTCAAGTTTATATATTTTTAAAGGAAAAAA 24 | ATAACTTTTTCATTTTTCGTTATAAAACAGAACCGTTATACATATTGAGATGGTTAAG 25 | 26 | -------------------------------------------------------------------------------- /dna-flashing-led/bioseq.py: -------------------------------------------------------------------------------- 1 | def parse_FASTA(filename): 2 | """Parse all entries in FASTA file into a dictionary""" 3 | 4 | import collections 5 | 6 | file = open(filename, 'r') 7 | entry_id = '' 8 | sequence = '' 9 | entries = collections.OrderedDict() 10 | for line in file: 11 | if line[0] == '>': 12 | sequence = '' 13 | entry_id = '' 14 | s = line[1:].rstrip() 15 | entry_id += s 16 | elif line[0] != '>': 17 | d = line.rstrip().upper() 18 | sequence += d 19 | entries[entry_id] = sequence 20 | elif line == '': 21 | file.close() 22 | return entries -------------------------------------------------------------------------------- /dna-flashing-led/nu_blink.py: -------------------------------------------------------------------------------- 1 | import RPi.GPIO as GPIO 2 | import time 3 | import sys 4 | from bioseq import parse_FASTA 5 | 6 | dna_file = sys.argv[1] 7 | database = parse_FASTA(dna_file) 8 | sequences = database.values() 9 | dna = sequences[0] 10 | 11 | GPIO.setmode(GPIO.BCM) 12 | GPIO.cleanup() 13 | GPIO.setup(18, GPIO.OUT) 14 | GPIO.setup(23, GPIO.OUT) 15 | GPIO.setup(24, GPIO.OUT) 16 | 17 | 18 | red = GPIO.PWM(18, 500) 19 | green = GPIO.PWM(23, 500) 20 | blue = GPIO.PWM(24, 500) 21 | 22 | def blink(nucleotide): 23 | if nucleotide == 'A': 24 | red.start(100) 25 | green.start(0) 26 | blue.start(100) 27 | print('A (purple)') 28 | elif nucleotide == 'T': 29 | red.start(0) 30 | green.start(0) 31 | blue.start(100) 32 | print('T (blue)') 33 | elif nucleotide == 'C': 34 | red.start(0) 35 | green.start(100) 36 | blue.start(0); 37 | print('C (green)') 38 | elif nucleotide == 'G': 39 | red.start(0) 40 | green.start(100) 41 | blue.start(100) 42 | print('G (cyan)') 43 | 44 | while True: 45 | for nt in dna: 46 | blink(nt) 47 | time.sleep(1.5) 48 | -------------------------------------------------------------------------------- /dna-flashing-led/readme.md: -------------------------------------------------------------------------------- 1 | #DNA flashing LED box 2 | This code accompanies the 'DNA flashing LED box' project over at scienceexposure.com. Two scripts are provided: 3 | * FASTA file parser 4 | * LED flashing script 5 | 6 | The first file acts as a module, and parses FASTA files by extracting their DNA sequences alongside their ID into a dictionary. Use the `.keys()` function to extract the IDs of the sequences, and the `.values()` function to extract the sequences. These functions maybe applied directly to the dictionary that is returned by running the method `parse_FASTA(filename)` where 'filename' is the full name of the .FASTA file including extension. 7 | 8 | 9 | ### Recommended requirements 10 | * Python 2.7.6 or newer 11 | * Raspberry Pi (any model) with Python GPIO library installed 12 | * Electrical components (LED, 3x 470 Ω resistor, jumper wires). See article page for more details. 13 | 14 | ### How to run the script 15 | Simply launch from the terminal in RPi using command `sudo python nu_blink.py f`. Argument `f` is replaced with the full name of the .FASTA formatted file including extension. An example .FASTA file is provided, tilted `RTT103.fasta`. 16 | 17 | 18 | ©2015, Ismail Uddin & Science Exposure. www.scienceexposure.com 19 | Link to project: http://www.scienceexposure.com/raspberry-pi/dna-flashing-led-box-raspberry-pi/ 20 | -------------------------------------------------------------------------------- /ldn-bus-ticker/README.md: -------------------------------------------------------------------------------- 1 | # TfL Bus Arrivals Ticker 2 | ![Image](http://www.scienceexposure.com/wp-content/uploads/2015/10/ftrd-img-1024x570.jpg) 3 | 4 | Raspberry Pi project to display the latest bus arrivals for a given bus stop in London on a Hitachi HD44780 based 16x2 character LCD. 5 | 6 | This project is detailed at [scienceexposure.com](http://wp.me/p5wMDR-76) with diagrams. 7 | 8 | ## Notes 9 | * The default set up is for Raspberry Pi model B+, where pin 21 is in renamed to pin 27. If you're using an older Pi, simply change 27 to 21 on line 13. 10 | -------------------------------------------------------------------------------- /ldn-bus-ticker/TfLAPI.py: -------------------------------------------------------------------------------- 1 | import csv 2 | import urllib2 3 | import json 4 | 5 | class TfLBusArrivalsAPI: 6 | def __init__(self): 7 | self.naptanDict = {} 8 | self.busStopDict = {} 9 | 10 | # row[1] Bus stop code 11 | # row[2] Naptan ID 12 | # row[3] Stop name 13 | 14 | with open('data/tfl-bus-stops.csv') as csvfile: 15 | reader = csv.reader(csvfile,delimiter=',') 16 | for row in reader: 17 | self.naptanDict[str(row[3])] = str(row[2]) 18 | self.busStopDict[str(row[1])] = str(row[2]) 19 | 20 | def searchBusStop(self, queryString): 21 | """ 22 | Returns a list of matching bus stops to queried bus stop name, 23 | and their respective Naptan IDs 24 | 25 | # Arugments 26 | queryString String value for the bus stop name 27 | 28 | # Usage 29 | $ from TfLAPI import * 30 | $ tfl = TfLBusArrivalsAPI() 31 | 32 | $ tfl.searchBusStop('mile end') 33 | """ 34 | outputList = {} 35 | 36 | for busStopName, naptanID in self.naptanDict.items(): 37 | if queryString.upper() in str(busStopName): 38 | outputList[str(busStopName)] = str(naptanID) 39 | else: 40 | pass 41 | 42 | if not outputList: 43 | print("No matching station found") 44 | 45 | 46 | for busStopName, naptanID in outputList.items(): 47 | print("%s, %s" % (busStopName, naptanID)) 48 | 49 | def returnTfLJSON(self, **kwargs): 50 | """ 51 | Returns a JSON style Python list containing all information 52 | from TfL regarding bus arrivals at specified bus stop. 53 | """ 54 | 55 | try: 56 | naptanID = kwargs['naptan_id'] 57 | except KeyError: 58 | try: 59 | busStopCode = str(kwargs['bus_stop_code']) 60 | naptanID = self.busStopDict[str(busStopCode)] 61 | except KeyError: 62 | print("You have not specified a bus stop code (bus_stop_code='1234' or Naptan ID (naptan_id='4905N')") 63 | 64 | 65 | data = urllib2.urlopen("https://api.tfl.gov.uk/StopPoint/" + "%s" % naptanID + "/arrivals") 66 | string_data = data.read()[2:-2] 67 | jsonList = string_data.split('},{') 68 | 69 | jsonObject = [] 70 | 71 | for element in jsonList: 72 | json_format = '{' + element + '}' 73 | jsonObject.append(json.loads(json_format)) 74 | 75 | return jsonObject 76 | 77 | def queryBusArrival(self, **kwargs): 78 | """ 79 | Returns a dictionary of bus arrival times in minutes for 80 | the queried bus line at the specified bus stop. 81 | 82 | # Arguments 83 | bus_line String value for the bus line 84 | 85 | bus_stop_code Integer value for the bus stop code 86 | ### OR (not both) 87 | naptan_id String value for the Naptan ID 88 | for bus stop (obtained using searchBusStop()) 89 | 90 | # Usage 91 | $ from TfLAPI import * 92 | $ tfl = TfLBusArrivalsAPI() 93 | 94 | $ tfl.queryBusArrival(bus_line='205', bus_stop_code=48439) 95 | """ 96 | 97 | try: 98 | naptanID = kwargs['naptan_id'] 99 | except KeyError: 100 | try: 101 | busStopCode = str(kwargs['bus_stop_code']) 102 | naptanID = self.busStopDict[busStopCode] 103 | except KeyError: 104 | print("You have not specified a bus stop code (bus_stop_code='1234' or Naptan ID (naptan_id='49015N')") 105 | 106 | try: 107 | busLine = kwargs['bus_line'] 108 | except KeyError: 109 | print("You have not specified a bus line (bus_line='339')") 110 | 111 | jsonObject = self.returnTfLJSON(bus_line=kwargs['bus_line'], naptan_id=str(naptanID)) 112 | 113 | busArrivalTimes = [] 114 | 115 | for entry in jsonObject: 116 | if busLine in entry.values(): 117 | arrivalMinutes = int(entry['timeToStation'])/60.0 118 | busArrivalTimes.append(arrivalMinutes) 119 | 120 | busArrivalTimes.sort() 121 | 122 | return busArrivalTimes 123 | -------------------------------------------------------------------------------- /ldn-bus-ticker/TfLAPI.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ismailuddin/raspberrypi/90b0dd6b737a12c92ade54aa4606f4d3d4a96d4f/ldn-bus-ticker/TfLAPI.pyc -------------------------------------------------------------------------------- /ldn-bus-ticker/dist/ldn-bus-ticker.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ismailuddin/raspberrypi/90b0dd6b737a12c92ade54aa4606f4d3d4a96d4f/ldn-bus-ticker/dist/ldn-bus-ticker.tar.gz -------------------------------------------------------------------------------- /ldn-bus-ticker/ldn-bus-ticker.py: -------------------------------------------------------------------------------- 1 | # London Bus arrivals ticker 2 | # Ismail Uddin, 2015 3 | # www.scienceexposure.com 4 | 5 | from TfLAPI import * 6 | import Adafruit_CharLCD as LCD 7 | import time 8 | import sys 9 | 10 | bSC = sys.argv[1] 11 | 12 | # RS,EN,D4,D5,D6,D7,Co,Ro,BL 13 | RPi_PIN_config = [27,22,25,24,23,18,16, 2, 4] 14 | try: 15 | if sys.argv[2] == "i2c": 16 | lcd = LCD.Adafruit_CharLCDPlate() 17 | else: 18 | lcd = LCD.Adafruit_CharLCD(*RPi_PIN_config) 19 | except IndexError: 20 | lcd = LCD.Adafruit_CharLCD(*RPi_PIN_config) 21 | 22 | lcd.clear() 23 | 24 | lcd.message('Initialising...') 25 | print('Initialising...') 26 | lcd.show_cursor(True) 27 | lcd.blink(True) 28 | tfl = TfLBusArrivalsAPI() 29 | 30 | 31 | lcd.clear() 32 | lcd.message('Fetching TfL bus\narrivals...') 33 | print('Fetching TfL bus\narrivals...') 34 | lcd.blink(True) 35 | 36 | def fetchBusArrivals(): 37 | lcd.show_cursor(False) 38 | lcd.blink(False) 39 | try: 40 | jsonObject = tfl.returnTfLJSON(bus_stop_code=bSC) 41 | except urllib2.URLError: 42 | lcd.clear() 43 | print("Unable to connect to Internet...") 44 | lcd.message("Unable to connect \nto Internet...") 45 | 46 | busLineDestinationTime = [] 47 | 48 | for entry in jsonObject: 49 | bLDT = [] 50 | bLDT.append(entry['lineName']) 51 | bLDT.append(entry['destinationName']) 52 | bLDT.append(int(entry['timeToStation'])/60.0) 53 | busLineDestinationTime.append(bLDT) 54 | 55 | arrivalsList = sorted(busLineDestinationTime, key=lambda x:x[2]) 56 | 57 | return arrivalsList 58 | 59 | 60 | while True: 61 | arrivalsList = fetchBusArrivals() 62 | for bus in arrivalsList: 63 | lcd.clear() 64 | tickerInfo = '%s to %s \nin %.0f minutes' % (bus[0], bus[1], bus[2]) 65 | lcd.message(tickerInfo) 66 | print(tickerInfo) 67 | time.sleep(3) 68 | for i in range(16): 69 | time.sleep(0.1) 70 | lcd.move_left() 71 | -------------------------------------------------------------------------------- /led-matrix/LEDController/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ismailuddin/raspberrypi/90b0dd6b737a12c92ade54aa4606f4d3d4a96d4f/led-matrix/LEDController/__init__.py -------------------------------------------------------------------------------- /led-matrix/LEDController/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ismailuddin/raspberrypi/90b0dd6b737a12c92ade54aa4606f4d3d4a96d4f/led-matrix/LEDController/__init__.pyc -------------------------------------------------------------------------------- /led-matrix/LEDController/controller.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ismailuddin/raspberrypi/90b0dd6b737a12c92ade54aa4606f4d3d4a96d4f/led-matrix/LEDController/controller.pyc -------------------------------------------------------------------------------- /led-matrix/LEDController/functions.py: -------------------------------------------------------------------------------- 1 | # MAX719-driven LED matrix functions library 2 | # 2015, Ismail Uddin 3 | # www.scienceexposure.com 4 | # www.github.com/ismailuddin/raspberrypi/led-matrix/ 5 | 6 | 7 | import max7219.led as LED 8 | import numpy as np 9 | import time 10 | 11 | class MatrixFunctions(object): 12 | def __init__(self): 13 | self.device = LED.matrix() 14 | self.device.brightness(5) 15 | 16 | def updateMatrix(self,array,transition=0,update=False): 17 | """ 18 | Function to read in a NumPy 1-D array or 2-D matrix, and update 19 | LEDs on LED matrix. 20 | 21 | --- 22 | 23 | **Matrix format: 24 | 0 Turn LED off 25 | 1 Turn LED on 26 | Data type: Integer values 27 | Order of data: From top left hand corner, row by row, till bottom right hand corner 28 | 29 | **Arguments: 30 | array 1-D array / 2-D NumPy matrix 31 | update Set by default to False. Set to True to update LEDs, one by one, creating a transition effect. 32 | transition Integer value in milliseconds. Only active if 'update' argument set to True. 33 | Specifies time delay for updating LEDs in matrix. 34 | 35 | """ 36 | if 'matrix' in str(type(array)): 37 | mat = array 38 | else: 39 | mat = np.matrix(array) 40 | height = mat.shape[0] 41 | width = mat.shape[1] 42 | for i in range(0,height): 43 | for k in range(0,width): 44 | self.device.pixel(k, i, mat[i,k],redraw=update) 45 | time.sleep(transition) 46 | self.device.flush() 47 | 48 | def readMatrix(self,filename,output='list'): 49 | """ 50 | Reads file generated by 'Generate Matrix' button in LED GUI Controller 51 | and outputs a NumPy array or matrix (specified by second argument) that 52 | can be used for the 'updateMatrix' function. 53 | 54 | --- 55 | 56 | **Arguments: 57 | filename String or variable, directing to file. 58 | output Specify 'list' to output a 1-D NumPy array 59 | 'matrix' to output a 8*8 2-D NumPy matrix 60 | """ 61 | a = np.genfromtxt(str(filename),delimiter=',') 62 | if str(output) == 'list': 63 | return a[:-1] 64 | else: 65 | m = a[:-1].reshape(8,8) 66 | return m 67 | 68 | def setOrientation(self,number): 69 | """ 70 | Alias function for orientation() function from 'max7219' module. 71 | 72 | **Arguments: 73 | number Integer value for phyiscal orientation in degrees of 74 | matrix. Accepted values: 0, 90, 180, 270. 75 | 76 | """ 77 | self.device.orientation(number) 78 | 79 | def rotationAnim(self,matrix,delay=0.25,transition=0,redraw=False): 80 | """ 81 | Function to create a rotation animation on the LED matrix. 82 | 83 | **Arguments: 84 | matrix NumPy 2-D matrix, shape: 8x8 85 | delay Float value, default at 0.25. Specifies the time delay between rotations. 86 | transition Alias to 'transition' argument in 'updateMatrix' function 87 | redraw Alias to 'redraw' argument in 'updateMatrix' function 88 | """ 89 | print("Press Ctrl+C to stop animation.") 90 | i = 0 91 | while True: 92 | i += 1 93 | rot = np.rot90(matrix, i) 94 | self.updateMatrix(rot,transition,redraw) 95 | time.sleep(delay) 96 | 97 | -------------------------------------------------------------------------------- /led-matrix/LEDController/functions.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ismailuddin/raspberrypi/90b0dd6b737a12c92ade54aa4606f4d3d4a96d4f/led-matrix/LEDController/functions.pyc -------------------------------------------------------------------------------- /led-matrix/MANIFEST: -------------------------------------------------------------------------------- 1 | # file GENERATED by distutils, do NOT edit 2 | setup.py 3 | LEDController\__init__.py 4 | LEDController\functions.py 5 | -------------------------------------------------------------------------------- /led-matrix/README.md: -------------------------------------------------------------------------------- 1 | LED Matrix GUI controller and Python library 2 | =========== 3 | ## LED Controller GUI 4 | This PyQt4 based GUI, allows you to control the individual LEDs on your matrix, as well as generate a text file encoding the 8x8 graphic. 5 | 6 | ### Requirements 7 | * Python 2 8 | * PyQt4 9 | * max7219 (https://github.com/rm-hull/max7219) 10 | 11 | ### Usage 12 | Launch either via the terminal, or through the Python 2 IDLE in Raspbian, when controlling the Desktop over a VNC server. PyQt4 programs do not work over the X11 remote desktop service, hence they must be launched through the Python 2 IDLE, and not through the terminal. 13 | ``` 14 | sudo python led-controller-gui.py 15 | ``` 16 | To control the LEDs on your matrix, simply click the radio buttons to enable them. Once you've made your design, press the 'Update Matrix' button to light up the LEDs.  17 | 18 | Press the 'Generate Matrix' button to output a `.txt` file containing a 1-dimensional array which you can read into the Python library in your own project. The 'Output style' dropdown box will let you control the output style of the file, although currently there's only one output coded in.  19 | The 'Matrix orientation' dropdown box let's you control the orientation of the matrix, so as to ensure you see your 8x8 graphic upright as in the program. This sometimes becomes an issue if you plug in the matrix using the pins into the breadboard, meaning it's actually upside down. 20 | 21 | ![LED GUI controller interface](http://www.scienceexposure.com/wp-content/uploads/2015/07/led-gui-screenshot.png) 22 | 23 | ## LEDController Python package 24 | This small library provides simple functions for lighting up the LEDs on a MAX7219 LED matrix using an array / matrix. 25 | 26 | ### Requirements 27 | * Python 2 28 | * Raspberry Pi (any model will do) with Raspbian 29 | * max7219 (https://github.com/rm-hull/max7219) 30 | 31 | ### Installation 32 | ``` 33 | wget https://github.com/ismailuddin/raspberrypi/raw/master/led-matrix/dist/LEDController-0.1.1.tar.gz 34 | tar -xzf LEDController-0.1.1.tar.gz 35 | cd LEDController-0.1.1/ 36 | sudo python setup.py install 37 | ``` 38 | 39 | ### Usage 40 | ``` 41 | from LEDController.functions import MatrixFunctions 42 | func = MatrixFunctions() 43 | ``` 44 | 45 | ### Functions 46 | `func.readMatrix()` 47 | 48 | Reads file generated by 'Generate Matrix' button in LED GUI Controller 49 | and outputs a NumPy array or matrix (specified by second argument) that 50 | can be used for the 'updateMatrix' function. 51 | 52 | ###### Arguments 53 | Argument | Description 54 | --- | --- 55 | filename | String or variable, directing to file. 56 | output | Specify 'list' to output a 1-D NumPy array; 'matrix' to output a 8*8 2-D NumPy matrix 57 | 58 | `func.updateMatrix()` 59 | 60 | Function to read in a NumPy 1-D array or 2-D matrix, and update 61 | LEDs on LED matrix. 62 | 63 | ###### Arguments 64 | Argument | Description 65 | --- | --- 66 | array | 1-D array / 2-D NumPy matrix 67 | update | Set by default to False. Set to True to update LEDs, one by one, creating a transition effect. 68 | transition | Integer value in milliseconds. Only active if 'update' argument set to True. Specifies time delay for updating LEDs in matrix. 69 | 70 | 71 | 72 | `func.rotationAnim()` 73 | 74 | Function to create an inifinitely looping rotation animation on the matrix. 75 | 76 | ###### Arguments 77 | Argument | Description 78 | --- | --- 79 | matrix | NumPy 2-D matrix, shape: 8x8 80 | delay | Float value, default at 0.25. Specifies the time delay between rotations. 81 | transition | Alias to 'transition' argument in 'updateMatrix' function 82 | redraw | Alias to 'redraw' argument in 'updateMatrix' function 83 | -------------------------------------------------------------------------------- /led-matrix/dist/LEDController-0.1.1.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ismailuddin/raspberrypi/90b0dd6b737a12c92ade54aa4606f4d3d4a96d4f/led-matrix/dist/LEDController-0.1.1.tar.gz -------------------------------------------------------------------------------- /led-matrix/gui-matrix.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Form 4 | 5 | 6 | 7 | 0 8 | 0 9 | 296 10 | 533 11 | 12 | 13 | 14 | MAX7219 LED Matrix - Raspberry Pi 15 | 16 | 17 | 18 | :/newPrefix/icon.ico:/newPrefix/icon.ico 19 | 20 | 21 | 22 | 23 | 30 24 | 30 25 | 241 26 | 251 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | false 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | false 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | false 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | false 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | false 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | false 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | false 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | false 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | false 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | false 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | false 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | false 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | false 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | false 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | false 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | false 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | false 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | false 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | false 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | false 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | false 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | false 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | false 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | false 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | false 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | false 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | false 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | false 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | false 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | false 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | false 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | false 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | false 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | false 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | false 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | false 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | false 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | false 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | false 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | false 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | false 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | false 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | false 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | false 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | false 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | false 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | false 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | false 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | false 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | false 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | false 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | false 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | false 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | false 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | false 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | false 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | false 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | false 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | false 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | false 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | false 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | false 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | false 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | false 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 30 676 | 310 677 | 241 678 | 41 679 | 680 | 681 | 682 | 683 | 12 684 | 685 | 686 | 687 | Update matrix 688 | 689 | 690 | 691 | 692 | 693 | 30 694 | 370 695 | 241 696 | 41 697 | 698 | 699 | 700 | 701 | 12 702 | 703 | 704 | 705 | Generate matrix 706 | 707 | 708 | 709 | 710 | 711 | 30 712 | 430 713 | 241 714 | 80 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 0 725 | 726 | 727 | 728 | 729 | 90 730 | 731 | 732 | 733 | 734 | 180 735 | 736 | 737 | 738 | 739 | 270 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 10 751 | 50 752 | false 753 | 754 | 755 | 756 | Matrix orientation: 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 10 765 | 50 766 | false 767 | 768 | 769 | 770 | Output style: 771 | 772 | 773 | 774 | 775 | 776 | 777 | 778 | Numpy-style matrix 779 | 780 | 781 | 782 | 783 | Binary 784 | 785 | 786 | 787 | 788 | 789 | 790 | gridLayoutWidget 791 | pushButton 792 | pushButton_2 793 | radioButton_67 794 | gridLayoutWidget_2 795 | 796 | 797 | 798 | 799 | 800 | 801 | -------------------------------------------------------------------------------- /led-matrix/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ismailuddin/raspberrypi/90b0dd6b737a12c92ade54aa4606f4d3d4a96d4f/led-matrix/icon.ico -------------------------------------------------------------------------------- /led-matrix/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ismailuddin/raspberrypi/90b0dd6b737a12c92ade54aa4606f4d3d4a96d4f/led-matrix/icon.png -------------------------------------------------------------------------------- /led-matrix/led-controller-gui.py: -------------------------------------------------------------------------------- 1 | # PyQt4 GUI / interface for MAX7219 LED Matrices 2 | # www.scienceexposure.com 3 | 4 | from PyQt4 import QtCore, QtGui 5 | import sys 6 | import numpy as np 7 | try: 8 | from LEDController.functions import MatrixFunctions 9 | led_matrix = MatrixFunctions() 10 | except ImportError: 11 | print('MAX7219 module or LEDController module missing. Program continuing...') 12 | 13 | from datetime import date 14 | 15 | try: 16 | _fromUtf8 = QtCore.QString.fromUtf8 17 | except AttributeError: 18 | def _fromUtf8(s): 19 | return s 20 | 21 | try: 22 | _encoding = QtGui.QApplication.UnicodeUTF8 23 | def _translate(context, text, disambig): 24 | return QtGui.QApplication.translate(context, text, disambig, _encoding) 25 | except AttributeError: 26 | def _translate(context, text, disambig): 27 | return QtGui.QApplication.translate(context, text, disambig) 28 | 29 | class Ui_Form(object): 30 | def setupUi(self, Form): 31 | Form.setObjectName(_fromUtf8("Form")) 32 | Form.resize(296, 533) 33 | icon = QtGui.QIcon() 34 | icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/newPrefix/icon.ico")), QtGui.QIcon.Normal, QtGui.QIcon.Off) 35 | Form.setWindowIcon(icon) 36 | self.gridLayoutWidget = QtGui.QWidget(Form) 37 | self.gridLayoutWidget.setGeometry(QtCore.QRect(30, 30, 241, 251)) 38 | self.gridLayoutWidget.setObjectName(_fromUtf8("gridLayoutWidget")) 39 | self.gridLayout = QtGui.QGridLayout(self.gridLayoutWidget) 40 | self.gridLayout.setMargin(0) 41 | self.gridLayout.setObjectName(_fromUtf8("gridLayout")) 42 | self.radioButton_1 = QtGui.QRadioButton(self.gridLayoutWidget) 43 | self.radioButton_1.setText(_fromUtf8("")) 44 | self.radioButton_1.setAutoExclusive(False) 45 | self.radioButton_1.setObjectName(_fromUtf8("radioButton_1")) 46 | self.gridLayout.addWidget(self.radioButton_1, 0, 0, 1, 1) 47 | self.radioButton_3 = QtGui.QRadioButton(self.gridLayoutWidget) 48 | self.radioButton_3.setText(_fromUtf8("")) 49 | self.radioButton_3.setAutoExclusive(False) 50 | self.radioButton_3.setObjectName(_fromUtf8("radioButton_3")) 51 | self.gridLayout.addWidget(self.radioButton_3, 0, 2, 1, 1) 52 | self.radioButton_10 = QtGui.QRadioButton(self.gridLayoutWidget) 53 | self.radioButton_10.setText(_fromUtf8("")) 54 | self.radioButton_10.setAutoExclusive(False) 55 | self.radioButton_10.setObjectName(_fromUtf8("radioButton_10")) 56 | self.gridLayout.addWidget(self.radioButton_10, 1, 1, 1, 1) 57 | self.radioButton_2 = QtGui.QRadioButton(self.gridLayoutWidget) 58 | self.radioButton_2.setText(_fromUtf8("")) 59 | self.radioButton_2.setAutoExclusive(False) 60 | self.radioButton_2.setObjectName(_fromUtf8("radioButton_2")) 61 | self.gridLayout.addWidget(self.radioButton_2, 0, 1, 1, 1) 62 | self.radioButton_9 = QtGui.QRadioButton(self.gridLayoutWidget) 63 | self.radioButton_9.setText(_fromUtf8("")) 64 | self.radioButton_9.setAutoExclusive(False) 65 | self.radioButton_9.setObjectName(_fromUtf8("radioButton_9")) 66 | self.gridLayout.addWidget(self.radioButton_9, 1, 0, 1, 1) 67 | self.radioButton_8 = QtGui.QRadioButton(self.gridLayoutWidget) 68 | self.radioButton_8.setText(_fromUtf8("")) 69 | self.radioButton_8.setAutoExclusive(False) 70 | self.radioButton_8.setObjectName(_fromUtf8("radioButton_8")) 71 | self.gridLayout.addWidget(self.radioButton_8, 0, 7, 1, 1) 72 | self.radioButton_12 = QtGui.QRadioButton(self.gridLayoutWidget) 73 | self.radioButton_12.setText(_fromUtf8("")) 74 | self.radioButton_12.setAutoExclusive(False) 75 | self.radioButton_12.setObjectName(_fromUtf8("radioButton_12")) 76 | self.gridLayout.addWidget(self.radioButton_12, 1, 3, 1, 1) 77 | self.radioButton_11 = QtGui.QRadioButton(self.gridLayoutWidget) 78 | self.radioButton_11.setText(_fromUtf8("")) 79 | self.radioButton_11.setAutoExclusive(False) 80 | self.radioButton_11.setObjectName(_fromUtf8("radioButton_11")) 81 | self.gridLayout.addWidget(self.radioButton_11, 1, 2, 1, 1) 82 | self.radioButton_13 = QtGui.QRadioButton(self.gridLayoutWidget) 83 | self.radioButton_13.setText(_fromUtf8("")) 84 | self.radioButton_13.setAutoExclusive(False) 85 | self.radioButton_13.setObjectName(_fromUtf8("radioButton_13")) 86 | self.gridLayout.addWidget(self.radioButton_13, 1, 4, 1, 1) 87 | self.radioButton_16 = QtGui.QRadioButton(self.gridLayoutWidget) 88 | self.radioButton_16.setText(_fromUtf8("")) 89 | self.radioButton_16.setAutoExclusive(False) 90 | self.radioButton_16.setObjectName(_fromUtf8("radioButton_16")) 91 | self.gridLayout.addWidget(self.radioButton_16, 1, 7, 1, 1) 92 | self.radioButton_14 = QtGui.QRadioButton(self.gridLayoutWidget) 93 | self.radioButton_14.setText(_fromUtf8("")) 94 | self.radioButton_14.setAutoExclusive(False) 95 | self.radioButton_14.setObjectName(_fromUtf8("radioButton_14")) 96 | self.gridLayout.addWidget(self.radioButton_14, 1, 5, 1, 1) 97 | self.radioButton_18 = QtGui.QRadioButton(self.gridLayoutWidget) 98 | self.radioButton_18.setText(_fromUtf8("")) 99 | self.radioButton_18.setAutoExclusive(False) 100 | self.radioButton_18.setObjectName(_fromUtf8("radioButton_18")) 101 | self.gridLayout.addWidget(self.radioButton_18, 2, 1, 1, 1) 102 | self.radioButton_21 = QtGui.QRadioButton(self.gridLayoutWidget) 103 | self.radioButton_21.setText(_fromUtf8("")) 104 | self.radioButton_21.setAutoExclusive(False) 105 | self.radioButton_21.setObjectName(_fromUtf8("radioButton_21")) 106 | self.gridLayout.addWidget(self.radioButton_21, 2, 4, 1, 1) 107 | self.radioButton_15 = QtGui.QRadioButton(self.gridLayoutWidget) 108 | self.radioButton_15.setText(_fromUtf8("")) 109 | self.radioButton_15.setAutoExclusive(False) 110 | self.radioButton_15.setObjectName(_fromUtf8("radioButton_15")) 111 | self.gridLayout.addWidget(self.radioButton_15, 1, 6, 1, 1) 112 | self.radioButton_17 = QtGui.QRadioButton(self.gridLayoutWidget) 113 | self.radioButton_17.setText(_fromUtf8("")) 114 | self.radioButton_17.setAutoExclusive(False) 115 | self.radioButton_17.setObjectName(_fromUtf8("radioButton_17")) 116 | self.gridLayout.addWidget(self.radioButton_17, 2, 0, 1, 1) 117 | self.radioButton_19 = QtGui.QRadioButton(self.gridLayoutWidget) 118 | self.radioButton_19.setText(_fromUtf8("")) 119 | self.radioButton_19.setAutoExclusive(False) 120 | self.radioButton_19.setObjectName(_fromUtf8("radioButton_19")) 121 | self.gridLayout.addWidget(self.radioButton_19, 2, 2, 1, 1) 122 | self.radioButton_20 = QtGui.QRadioButton(self.gridLayoutWidget) 123 | self.radioButton_20.setText(_fromUtf8("")) 124 | self.radioButton_20.setAutoExclusive(False) 125 | self.radioButton_20.setObjectName(_fromUtf8("radioButton_20")) 126 | self.gridLayout.addWidget(self.radioButton_20, 2, 3, 1, 1) 127 | self.radioButton_23 = QtGui.QRadioButton(self.gridLayoutWidget) 128 | self.radioButton_23.setText(_fromUtf8("")) 129 | self.radioButton_23.setAutoExclusive(False) 130 | self.radioButton_23.setObjectName(_fromUtf8("radioButton_23")) 131 | self.gridLayout.addWidget(self.radioButton_23, 2, 6, 1, 1) 132 | self.radioButton_28 = QtGui.QRadioButton(self.gridLayoutWidget) 133 | self.radioButton_28.setText(_fromUtf8("")) 134 | self.radioButton_28.setAutoExclusive(False) 135 | self.radioButton_28.setObjectName(_fromUtf8("radioButton_28")) 136 | self.gridLayout.addWidget(self.radioButton_28, 3, 3, 1, 1) 137 | self.radioButton_31 = QtGui.QRadioButton(self.gridLayoutWidget) 138 | self.radioButton_31.setText(_fromUtf8("")) 139 | self.radioButton_31.setAutoExclusive(False) 140 | self.radioButton_31.setObjectName(_fromUtf8("radioButton_31")) 141 | self.gridLayout.addWidget(self.radioButton_31, 3, 6, 1, 1) 142 | self.radioButton_26 = QtGui.QRadioButton(self.gridLayoutWidget) 143 | self.radioButton_26.setText(_fromUtf8("")) 144 | self.radioButton_26.setAutoExclusive(False) 145 | self.radioButton_26.setObjectName(_fromUtf8("radioButton_26")) 146 | self.gridLayout.addWidget(self.radioButton_26, 3, 1, 1, 1) 147 | self.radioButton_27 = QtGui.QRadioButton(self.gridLayoutWidget) 148 | self.radioButton_27.setText(_fromUtf8("")) 149 | self.radioButton_27.setAutoExclusive(False) 150 | self.radioButton_27.setObjectName(_fromUtf8("radioButton_27")) 151 | self.gridLayout.addWidget(self.radioButton_27, 3, 2, 1, 1) 152 | self.radioButton_22 = QtGui.QRadioButton(self.gridLayoutWidget) 153 | self.radioButton_22.setText(_fromUtf8("")) 154 | self.radioButton_22.setAutoExclusive(False) 155 | self.radioButton_22.setObjectName(_fromUtf8("radioButton_22")) 156 | self.gridLayout.addWidget(self.radioButton_22, 2, 5, 1, 1) 157 | self.radioButton_29 = QtGui.QRadioButton(self.gridLayoutWidget) 158 | self.radioButton_29.setText(_fromUtf8("")) 159 | self.radioButton_29.setAutoExclusive(False) 160 | self.radioButton_29.setObjectName(_fromUtf8("radioButton_29")) 161 | self.gridLayout.addWidget(self.radioButton_29, 3, 4, 1, 1) 162 | self.radioButton_30 = QtGui.QRadioButton(self.gridLayoutWidget) 163 | self.radioButton_30.setText(_fromUtf8("")) 164 | self.radioButton_30.setAutoExclusive(False) 165 | self.radioButton_30.setObjectName(_fromUtf8("radioButton_30")) 166 | self.gridLayout.addWidget(self.radioButton_30, 3, 5, 1, 1) 167 | self.radioButton_25 = QtGui.QRadioButton(self.gridLayoutWidget) 168 | self.radioButton_25.setText(_fromUtf8("")) 169 | self.radioButton_25.setAutoExclusive(False) 170 | self.radioButton_25.setObjectName(_fromUtf8("radioButton_25")) 171 | self.gridLayout.addWidget(self.radioButton_25, 3, 0, 1, 1) 172 | self.radioButton_24 = QtGui.QRadioButton(self.gridLayoutWidget) 173 | self.radioButton_24.setText(_fromUtf8("")) 174 | self.radioButton_24.setAutoExclusive(False) 175 | self.radioButton_24.setObjectName(_fromUtf8("radioButton_24")) 176 | self.gridLayout.addWidget(self.radioButton_24, 2, 7, 1, 1) 177 | self.radioButton_33 = QtGui.QRadioButton(self.gridLayoutWidget) 178 | self.radioButton_33.setText(_fromUtf8("")) 179 | self.radioButton_33.setAutoExclusive(False) 180 | self.radioButton_33.setObjectName(_fromUtf8("radioButton_33")) 181 | self.gridLayout.addWidget(self.radioButton_33, 4, 0, 1, 1) 182 | self.radioButton_5 = QtGui.QRadioButton(self.gridLayoutWidget) 183 | self.radioButton_5.setText(_fromUtf8("")) 184 | self.radioButton_5.setAutoExclusive(False) 185 | self.radioButton_5.setObjectName(_fromUtf8("radioButton_5")) 186 | self.gridLayout.addWidget(self.radioButton_5, 0, 4, 1, 1) 187 | self.radioButton_4 = QtGui.QRadioButton(self.gridLayoutWidget) 188 | self.radioButton_4.setText(_fromUtf8("")) 189 | self.radioButton_4.setAutoExclusive(False) 190 | self.radioButton_4.setObjectName(_fromUtf8("radioButton_4")) 191 | self.gridLayout.addWidget(self.radioButton_4, 0, 3, 1, 1) 192 | self.radioButton_32 = QtGui.QRadioButton(self.gridLayoutWidget) 193 | self.radioButton_32.setText(_fromUtf8("")) 194 | self.radioButton_32.setAutoExclusive(False) 195 | self.radioButton_32.setObjectName(_fromUtf8("radioButton_32")) 196 | self.gridLayout.addWidget(self.radioButton_32, 3, 7, 1, 1) 197 | self.radioButton_34 = QtGui.QRadioButton(self.gridLayoutWidget) 198 | self.radioButton_34.setText(_fromUtf8("")) 199 | self.radioButton_34.setAutoExclusive(False) 200 | self.radioButton_34.setObjectName(_fromUtf8("radioButton_34")) 201 | self.gridLayout.addWidget(self.radioButton_34, 4, 1, 1, 1) 202 | self.radioButton_7 = QtGui.QRadioButton(self.gridLayoutWidget) 203 | self.radioButton_7.setText(_fromUtf8("")) 204 | self.radioButton_7.setAutoExclusive(False) 205 | self.radioButton_7.setObjectName(_fromUtf8("radioButton_7")) 206 | self.gridLayout.addWidget(self.radioButton_7, 0, 6, 1, 1) 207 | self.radioButton_6 = QtGui.QRadioButton(self.gridLayoutWidget) 208 | self.radioButton_6.setText(_fromUtf8("")) 209 | self.radioButton_6.setAutoExclusive(False) 210 | self.radioButton_6.setObjectName(_fromUtf8("radioButton_6")) 211 | self.gridLayout.addWidget(self.radioButton_6, 0, 5, 1, 1) 212 | self.radioButton_36 = QtGui.QRadioButton(self.gridLayoutWidget) 213 | self.radioButton_36.setText(_fromUtf8("")) 214 | self.radioButton_36.setAutoExclusive(False) 215 | self.radioButton_36.setObjectName(_fromUtf8("radioButton_36")) 216 | self.gridLayout.addWidget(self.radioButton_36, 4, 3, 1, 1) 217 | self.radioButton_35 = QtGui.QRadioButton(self.gridLayoutWidget) 218 | self.radioButton_35.setText(_fromUtf8("")) 219 | self.radioButton_35.setAutoExclusive(False) 220 | self.radioButton_35.setObjectName(_fromUtf8("radioButton_35")) 221 | self.gridLayout.addWidget(self.radioButton_35, 4, 2, 1, 1) 222 | self.radioButton_39 = QtGui.QRadioButton(self.gridLayoutWidget) 223 | self.radioButton_39.setText(_fromUtf8("")) 224 | self.radioButton_39.setAutoExclusive(False) 225 | self.radioButton_39.setObjectName(_fromUtf8("radioButton_39")) 226 | self.gridLayout.addWidget(self.radioButton_39, 4, 6, 1, 1) 227 | self.radioButton_40 = QtGui.QRadioButton(self.gridLayoutWidget) 228 | self.radioButton_40.setText(_fromUtf8("")) 229 | self.radioButton_40.setAutoExclusive(False) 230 | self.radioButton_40.setObjectName(_fromUtf8("radioButton_40")) 231 | self.gridLayout.addWidget(self.radioButton_40, 4, 7, 1, 1) 232 | self.radioButton_37 = QtGui.QRadioButton(self.gridLayoutWidget) 233 | self.radioButton_37.setText(_fromUtf8("")) 234 | self.radioButton_37.setAutoExclusive(False) 235 | self.radioButton_37.setObjectName(_fromUtf8("radioButton_37")) 236 | self.gridLayout.addWidget(self.radioButton_37, 4, 4, 1, 1) 237 | self.radioButton_38 = QtGui.QRadioButton(self.gridLayoutWidget) 238 | self.radioButton_38.setText(_fromUtf8("")) 239 | self.radioButton_38.setAutoExclusive(False) 240 | self.radioButton_38.setObjectName(_fromUtf8("radioButton_38")) 241 | self.gridLayout.addWidget(self.radioButton_38, 4, 5, 1, 1) 242 | self.radioButton_44 = QtGui.QRadioButton(self.gridLayoutWidget) 243 | self.radioButton_44.setText(_fromUtf8("")) 244 | self.radioButton_44.setAutoExclusive(False) 245 | self.radioButton_44.setObjectName(_fromUtf8("radioButton_44")) 246 | self.gridLayout.addWidget(self.radioButton_44, 5, 3, 1, 1) 247 | self.radioButton_41 = QtGui.QRadioButton(self.gridLayoutWidget) 248 | self.radioButton_41.setText(_fromUtf8("")) 249 | self.radioButton_41.setAutoExclusive(False) 250 | self.radioButton_41.setObjectName(_fromUtf8("radioButton_41")) 251 | self.gridLayout.addWidget(self.radioButton_41, 5, 0, 1, 1) 252 | self.radioButton_43 = QtGui.QRadioButton(self.gridLayoutWidget) 253 | self.radioButton_43.setText(_fromUtf8("")) 254 | self.radioButton_43.setAutoExclusive(False) 255 | self.radioButton_43.setObjectName(_fromUtf8("radioButton_43")) 256 | self.gridLayout.addWidget(self.radioButton_43, 5, 2, 1, 1) 257 | self.radioButton_42 = QtGui.QRadioButton(self.gridLayoutWidget) 258 | self.radioButton_42.setText(_fromUtf8("")) 259 | self.radioButton_42.setAutoExclusive(False) 260 | self.radioButton_42.setObjectName(_fromUtf8("radioButton_42")) 261 | self.gridLayout.addWidget(self.radioButton_42, 5, 1, 1, 1) 262 | self.radioButton_45 = QtGui.QRadioButton(self.gridLayoutWidget) 263 | self.radioButton_45.setText(_fromUtf8("")) 264 | self.radioButton_45.setAutoExclusive(False) 265 | self.radioButton_45.setObjectName(_fromUtf8("radioButton_45")) 266 | self.gridLayout.addWidget(self.radioButton_45, 5, 4, 1, 1) 267 | self.radioButton_46 = QtGui.QRadioButton(self.gridLayoutWidget) 268 | self.radioButton_46.setText(_fromUtf8("")) 269 | self.radioButton_46.setAutoExclusive(False) 270 | self.radioButton_46.setObjectName(_fromUtf8("radioButton_46")) 271 | self.gridLayout.addWidget(self.radioButton_46, 5, 5, 1, 1) 272 | self.radioButton_49 = QtGui.QRadioButton(self.gridLayoutWidget) 273 | self.radioButton_49.setText(_fromUtf8("")) 274 | self.radioButton_49.setAutoExclusive(False) 275 | self.radioButton_49.setObjectName(_fromUtf8("radioButton_49")) 276 | self.gridLayout.addWidget(self.radioButton_49, 6, 0, 1, 1) 277 | self.radioButton_47 = QtGui.QRadioButton(self.gridLayoutWidget) 278 | self.radioButton_47.setText(_fromUtf8("")) 279 | self.radioButton_47.setAutoExclusive(False) 280 | self.radioButton_47.setObjectName(_fromUtf8("radioButton_47")) 281 | self.gridLayout.addWidget(self.radioButton_47, 5, 6, 1, 1) 282 | self.radioButton_48 = QtGui.QRadioButton(self.gridLayoutWidget) 283 | self.radioButton_48.setText(_fromUtf8("")) 284 | self.radioButton_48.setAutoExclusive(False) 285 | self.radioButton_48.setObjectName(_fromUtf8("radioButton_48")) 286 | self.gridLayout.addWidget(self.radioButton_48, 5, 7, 1, 1) 287 | self.radioButton_51 = QtGui.QRadioButton(self.gridLayoutWidget) 288 | self.radioButton_51.setText(_fromUtf8("")) 289 | self.radioButton_51.setAutoExclusive(False) 290 | self.radioButton_51.setObjectName(_fromUtf8("radioButton_51")) 291 | self.gridLayout.addWidget(self.radioButton_51, 6, 2, 1, 1) 292 | self.radioButton_50 = QtGui.QRadioButton(self.gridLayoutWidget) 293 | self.radioButton_50.setText(_fromUtf8("")) 294 | self.radioButton_50.setAutoExclusive(False) 295 | self.radioButton_50.setObjectName(_fromUtf8("radioButton_50")) 296 | self.gridLayout.addWidget(self.radioButton_50, 6, 1, 1, 1) 297 | self.radioButton_55 = QtGui.QRadioButton(self.gridLayoutWidget) 298 | self.radioButton_55.setText(_fromUtf8("")) 299 | self.radioButton_55.setAutoExclusive(False) 300 | self.radioButton_55.setObjectName(_fromUtf8("radioButton_55")) 301 | self.gridLayout.addWidget(self.radioButton_55, 6, 6, 1, 1) 302 | self.radioButton_52 = QtGui.QRadioButton(self.gridLayoutWidget) 303 | self.radioButton_52.setText(_fromUtf8("")) 304 | self.radioButton_52.setAutoExclusive(False) 305 | self.radioButton_52.setObjectName(_fromUtf8("radioButton_52")) 306 | self.gridLayout.addWidget(self.radioButton_52, 6, 3, 1, 1) 307 | self.radioButton_53 = QtGui.QRadioButton(self.gridLayoutWidget) 308 | self.radioButton_53.setText(_fromUtf8("")) 309 | self.radioButton_53.setAutoExclusive(False) 310 | self.radioButton_53.setObjectName(_fromUtf8("radioButton_53")) 311 | self.gridLayout.addWidget(self.radioButton_53, 6, 4, 1, 1) 312 | self.radioButton_54 = QtGui.QRadioButton(self.gridLayoutWidget) 313 | self.radioButton_54.setText(_fromUtf8("")) 314 | self.radioButton_54.setAutoExclusive(False) 315 | self.radioButton_54.setObjectName(_fromUtf8("radioButton_54")) 316 | self.gridLayout.addWidget(self.radioButton_54, 6, 5, 1, 1) 317 | self.radioButton_56 = QtGui.QRadioButton(self.gridLayoutWidget) 318 | self.radioButton_56.setText(_fromUtf8("")) 319 | self.radioButton_56.setAutoExclusive(False) 320 | self.radioButton_56.setObjectName(_fromUtf8("radioButton_56")) 321 | self.gridLayout.addWidget(self.radioButton_56, 6, 7, 1, 1) 322 | self.radioButton_57 = QtGui.QRadioButton(self.gridLayoutWidget) 323 | self.radioButton_57.setText(_fromUtf8("")) 324 | self.radioButton_57.setAutoExclusive(False) 325 | self.radioButton_57.setObjectName(_fromUtf8("radioButton_57")) 326 | self.gridLayout.addWidget(self.radioButton_57, 7, 0, 1, 1) 327 | self.radioButton_58 = QtGui.QRadioButton(self.gridLayoutWidget) 328 | self.radioButton_58.setText(_fromUtf8("")) 329 | self.radioButton_58.setAutoExclusive(False) 330 | self.radioButton_58.setObjectName(_fromUtf8("radioButton_58")) 331 | self.gridLayout.addWidget(self.radioButton_58, 7, 1, 1, 1) 332 | self.radioButton_59 = QtGui.QRadioButton(self.gridLayoutWidget) 333 | self.radioButton_59.setText(_fromUtf8("")) 334 | self.radioButton_59.setAutoExclusive(False) 335 | self.radioButton_59.setObjectName(_fromUtf8("radioButton_59")) 336 | self.gridLayout.addWidget(self.radioButton_59, 7, 2, 1, 1) 337 | self.radioButton_60 = QtGui.QRadioButton(self.gridLayoutWidget) 338 | self.radioButton_60.setText(_fromUtf8("")) 339 | self.radioButton_60.setAutoExclusive(False) 340 | self.radioButton_60.setObjectName(_fromUtf8("radioButton_60")) 341 | self.gridLayout.addWidget(self.radioButton_60, 7, 3, 1, 1) 342 | self.radioButton_61 = QtGui.QRadioButton(self.gridLayoutWidget) 343 | self.radioButton_61.setText(_fromUtf8("")) 344 | self.radioButton_61.setAutoExclusive(False) 345 | self.radioButton_61.setObjectName(_fromUtf8("radioButton_61")) 346 | self.gridLayout.addWidget(self.radioButton_61, 7, 4, 1, 1) 347 | self.radioButton_62 = QtGui.QRadioButton(self.gridLayoutWidget) 348 | self.radioButton_62.setText(_fromUtf8("")) 349 | self.radioButton_62.setAutoExclusive(False) 350 | self.radioButton_62.setObjectName(_fromUtf8("radioButton_62")) 351 | self.gridLayout.addWidget(self.radioButton_62, 7, 5, 1, 1) 352 | self.radioButton_63 = QtGui.QRadioButton(self.gridLayoutWidget) 353 | self.radioButton_63.setText(_fromUtf8("")) 354 | self.radioButton_63.setAutoExclusive(False) 355 | self.radioButton_63.setObjectName(_fromUtf8("radioButton_63")) 356 | self.gridLayout.addWidget(self.radioButton_63, 7, 6, 1, 1) 357 | self.radioButton_64 = QtGui.QRadioButton(self.gridLayoutWidget) 358 | self.radioButton_64.setText(_fromUtf8("")) 359 | self.radioButton_64.setAutoExclusive(False) 360 | self.radioButton_64.setObjectName(_fromUtf8("radioButton_64")) 361 | self.gridLayout.addWidget(self.radioButton_64, 7, 7, 1, 1) 362 | self.pushButton = QtGui.QPushButton(Form) 363 | self.pushButton.setGeometry(QtCore.QRect(30, 310, 241, 41)) 364 | font = QtGui.QFont() 365 | font.setPointSize(12) 366 | self.pushButton.setFont(font) 367 | self.pushButton.setObjectName(_fromUtf8("pushButton")) 368 | self.pushButton_2 = QtGui.QPushButton(Form) 369 | self.pushButton_2.setGeometry(QtCore.QRect(30, 370, 241, 41)) 370 | font = QtGui.QFont() 371 | font.setPointSize(12) 372 | self.pushButton_2.setFont(font) 373 | self.pushButton_2.setObjectName(_fromUtf8("pushButton_2")) 374 | self.gridLayoutWidget_2 = QtGui.QWidget(Form) 375 | self.gridLayoutWidget_2.setGeometry(QtCore.QRect(30, 430, 241, 80)) 376 | self.gridLayoutWidget_2.setObjectName(_fromUtf8("gridLayoutWidget_2")) 377 | self.gridLayout_2 = QtGui.QGridLayout(self.gridLayoutWidget_2) 378 | self.gridLayout_2.setMargin(0) 379 | self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2")) 380 | self.horizontalLayout = QtGui.QHBoxLayout() 381 | self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) 382 | self.comboBox = QtGui.QComboBox(self.gridLayoutWidget_2) 383 | self.comboBox.setObjectName(_fromUtf8("comboBox")) 384 | self.comboBox.addItem(_fromUtf8("")) 385 | self.comboBox.addItem(_fromUtf8("")) 386 | self.comboBox.addItem(_fromUtf8("")) 387 | self.comboBox.addItem(_fromUtf8("")) 388 | self.horizontalLayout.addWidget(self.comboBox) 389 | self.gridLayout_2.addLayout(self.horizontalLayout, 1, 0, 1, 1) 390 | self.label = QtGui.QLabel(self.gridLayoutWidget_2) 391 | font = QtGui.QFont() 392 | font.setPointSize(10) 393 | font.setBold(False) 394 | font.setWeight(50) 395 | self.label.setFont(font) 396 | self.label.setObjectName(_fromUtf8("label")) 397 | self.gridLayout_2.addWidget(self.label, 0, 0, 1, 1) 398 | self.label_2 = QtGui.QLabel(self.gridLayoutWidget_2) 399 | font = QtGui.QFont() 400 | font.setPointSize(10) 401 | font.setBold(False) 402 | font.setWeight(50) 403 | self.label_2.setFont(font) 404 | self.label_2.setObjectName(_fromUtf8("label_2")) 405 | self.gridLayout_2.addWidget(self.label_2, 0, 1, 1, 1) 406 | self.comboBox_2 = QtGui.QComboBox(self.gridLayoutWidget_2) 407 | self.comboBox_2.setObjectName(_fromUtf8("comboBox_2")) 408 | self.comboBox_2.addItem(_fromUtf8("")) 409 | self.comboBox_2.addItem(_fromUtf8("")) 410 | self.gridLayout_2.addWidget(self.comboBox_2, 1, 1, 1, 1) 411 | 412 | self.retranslateUi(Form) 413 | QtCore.QMetaObject.connectSlotsByName(Form) 414 | self.pushButton.clicked.connect(self.updtMat) 415 | self.pushButton_2.clicked.connect(self.genMatrix) 416 | 417 | def retranslateUi(self, Form): 418 | Form.setWindowTitle(_translate("Form", "MAX7219 LED Matrix - Raspberry Pi", None)) 419 | self.pushButton.setText(_translate("Form", "Update matrix", None)) 420 | self.pushButton_2.setText(_translate("Form", "Generate matrix", None)) 421 | self.comboBox.setItemText(0, _translate("Form", "0", None)) 422 | self.comboBox.setItemText(1, _translate("Form", "90", None)) 423 | self.comboBox.setItemText(2, _translate("Form", "180", None)) 424 | self.comboBox.setItemText(3, _translate("Form", "270", None)) 425 | self.label.setText(_translate("Form", "Matrix orientation:", None)) 426 | self.label_2.setText(_translate("Form", "Output style:", None)) 427 | self.comboBox_2.setItemText(0, _translate("Form", "Numpy-style matrix", None)) 428 | self.comboBox_2.setItemText(1, _translate("Form", "Binary", None)) 429 | 430 | def updtMat(self): 431 | arr = np.array(np.zeros(64)) 432 | orientation = int(self.comboBox.currentText()) 433 | led_matrix.setOrientation(orientation) 434 | 435 | for i in range(1,65): 436 | method = getattr(self, "radioButton_%s" % i) 437 | a = method.isChecked() 438 | if a == True: 439 | arr[i-1] = 1 440 | else: 441 | pass 442 | matrix = arr.reshape(8,8) 443 | led_matrix.updateMatrix(matrix) 444 | 445 | 446 | def genMatrix(self): 447 | arr = np.array(np.zeros(64)) 448 | 449 | for i in range(1,65): 450 | method = getattr(self, "radioButton_%s" % i) 451 | a = method.isChecked() 452 | if a == True: 453 | arr[i-1] = 1 454 | else: 455 | pass 456 | mx = arr.reshape(8,8) 457 | today = date.today() 458 | d = today.strftime('%d%m%Y') 459 | np.savetxt('%s_led_matrix.txt' % d,mx,fmt='%d',newline=',',delimiter=',') 460 | 461 | 462 | 463 | if __name__ == "__main__": 464 | app = QtGui.QApplication(sys.argv) 465 | Form = QtGui.QWidget() 466 | ui = Ui_Form() 467 | ui.setupUi(Form) 468 | Form.show() 469 | sys.exit(app.exec_()) 470 | -------------------------------------------------------------------------------- /led-matrix/london-underground-neopixel/README.md: -------------------------------------------------------------------------------- 1 | # London Underground Line status - Adafruit Neopixel 2 | ![London Underground Line status using Neopixels](http://www.scienceexposure.com/wp-content/uploads/2015/07/DSC5152-1024x686.jpg) 3 | This script allows you to display live London Underground line's status on a Neopixel LED ring using a Raspberry Pi. For more information on setting up this project, visit 4 | 5 | ## Requirements 6 | * Raspberry Pi (any model will do) 7 | * Internet connectivity 8 | * Adafruit Neopixel LED ring 9 | * Push button 10 | * 5 V power supply (you may borrow from a Arduino board) 11 | 12 | ## Usage 13 | To run the script, type `sudo python underground_status.py` at the terminal. To cycle between the London Underground lines, press the push button. 14 | -------------------------------------------------------------------------------- /led-matrix/london-underground-neopixel/underground_status.py: -------------------------------------------------------------------------------- 1 | from xml.dom import minidom 2 | import urllib2 3 | import time 4 | import RPi.GPIO as GPIO 5 | from neopixel import * 6 | 7 | # LED strip configuration: 8 | LED_COUNT = 12 # Number of LED pixels. 9 | LED_PIN = 18 # GPIO pin connected to the pixels (must support PWM!). 10 | LED_FREQ_HZ = 800000 # LED signal frequency in hertz (usually 800khz) 11 | LED_DMA = 5 # DMA channel to use for generating signal (try 5) 12 | LED_BRIGHTNESS = 60 # Set to 0 for darkest and 255 for brightest 13 | LED_INVERT = False # True to invert the signal (when using NPN transistor level shift) 14 | 15 | lastButton = False 16 | GPIO.setmode(GPIO.BCM) 17 | switchPin = 25 18 | 19 | GPIO.setup(switchPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) 20 | 21 | linestatus_dict = {} 22 | 23 | def update_underground_status(): 24 | xmlfile = urllib2.urlopen('http://cloud.tfl.gov.uk/TrackerNet/LineStatus') 25 | parsed = minidom.parse(xmlfile) 26 | linestatus = parsed.getElementsByTagName("LineStatus") 27 | 28 | for entry in linestatus: 29 | line = entry.getElementsByTagName("Line") 30 | name = line[0].getAttribute("Name") 31 | status_details = entry.getAttribute("StatusDetails") 32 | if status_details != '': 33 | linestatus_dict[str(name)] = 1 34 | else: 35 | linestatus_dict[str(name)] = 0 36 | parsed, linestatus, line, name, status_details = None, None, None, None, None 37 | return linestatus_dict 38 | 39 | 40 | uc = { 41 | 'Bakerloo':[50,18,0], 42 | 'Central':[229,0,0], 43 | 'Circle':[255,255,0], 44 | 'DLR':[134,253,215], 45 | 'District':[0,255,0], 46 | 'Hammersmith and City':[255,192,203], 47 | 'Jubilee':[60,60,60], 48 | 'Metropolitan':[128,0,128], 49 | 'Northern':[10,10,10], 50 | 'Overground':[255,165,0], 51 | 'Piccadilly':[30,30,102], 52 | 'Victoria':[40,220,255], 53 | 'Waterloo and City':[0,255,255], 54 | 'TfL Rail':[53,92,125] 55 | } 56 | 57 | def reset(): 58 | for i in range(0,12): 59 | strip.setPixelColorRGB(i,0,0,0) 60 | strip.show() 61 | 62 | def neopixel_status(ugline): 63 | if linestatus_dict[str(ugline)] == 0: 64 | reset() 65 | for i in range(0,12): 66 | strip.setPixelColorRGB(i,uc[str(ugline)][0],uc[str(ugline)][1],uc[str(ugline)][2]) 67 | strip.show() 68 | else: 69 | reset() 70 | for i in range(0,12,2): 71 | strip.setPixelColorRGB(i,uc[str(ugline)][0],uc[str(ugline)][1],uc[str(ugline)][2]) 72 | strip.show() 73 | print(str(ugline)) 74 | 75 | i = 0 76 | 77 | def next_line(): 78 | global i 79 | if i >= (len(line_names)-1): 80 | i = 0 81 | else: 82 | i += 1 83 | return line_names[i] 84 | 85 | if __name__ == '__main__': 86 | # Create NeoPixel object with appropriate configuration. 87 | strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS) 88 | # Intialize the library (must be called once before other functions). 89 | strip.begin() 90 | strip.setBrightness(25) 91 | 92 | update_underground_status() 93 | line_names = linestatus_dict.keys() 94 | curr_line = line_names[0] 95 | neopixel_status(curr_line) 96 | 97 | try: 98 | while True: 99 | if GPIO.input(switchPin) == 0: 100 | update_underground_status() 101 | line_names = linestatus_dict.keys() 102 | curr_line = next_line() 103 | neopixel_status(curr_line) 104 | else: 105 | pass 106 | finally: 107 | pass -------------------------------------------------------------------------------- /led-matrix/setup.py: -------------------------------------------------------------------------------- 1 | from distutils.core import setup 2 | 3 | setup( 4 | name = "LEDController", 5 | version = "0.1.1", 6 | author = "Ismail Uddin", 7 | author_email = "ismail.sameeuddin@gmail.com", 8 | license = "Apache 2.0", 9 | description = ("Collection of functions to control MAX7219 LED matrices using Python on Raspberry Pi"), 10 | long_description = """ 11 | A small library of functions for controlling the LED matrices driven by the MAX7219 driver. 12 | Dependencies: max7219 (https://github.com/rm-hull/max7219) 13 | Complements the PyQt4 GUI LED controller. 14 | www.scienceexposure.com 15 | """, 16 | keywords = "raspberry pi led controller max7219", 17 | packages=['LEDController'], 18 | url = "https://github.com/ismailuddin/raspberrypi/led-matrix/", 19 | ) -------------------------------------------------------------------------------- /london-underground-neopixel/README.md: -------------------------------------------------------------------------------- 1 | # London Underground Line status - Adafruit Neopixel 2 | ![London Underground Line status using Neopixels](http://www.scienceexposure.com/wp-content/uploads/2015/07/DSC5152-1024x686.jpg) 3 | This script allows you to display live London Underground line's status on a Neopixel LED ring using a Raspberry Pi. For more information on setting up this project, visit 4 | 5 | ## Requirements 6 | * Raspberry Pi (any model will do) 7 | * Internet connectivity 8 | * Adafruit Neopixel LED ring 9 | * Push button 10 | * 5 V power supply (you may borrow from a Arduino board) 11 | 12 | ## Usage 13 | To run the script, type `sudo python underground_status.py` at the terminal. To cycle between the London Underground lines, press the push button. 14 | -------------------------------------------------------------------------------- /london-underground-neopixel/underground_status.py: -------------------------------------------------------------------------------- 1 | from xml.dom import minidom 2 | import urllib2 3 | import time 4 | import RPi.GPIO as GPIO 5 | from neopixel import * 6 | 7 | # LED strip configuration: 8 | LED_COUNT = 12 # Number of LED pixels. 9 | LED_PIN = 18 # GPIO pin connected to the pixels (must support PWM!). 10 | LED_FREQ_HZ = 800000 # LED signal frequency in hertz (usually 800khz) 11 | LED_DMA = 5 # DMA channel to use for generating signal (try 5) 12 | LED_BRIGHTNESS = 60 # Set to 0 for darkest and 255 for brightest 13 | LED_INVERT = False # True to invert the signal (when using NPN transistor level shift) 14 | 15 | lastButton = False 16 | GPIO.setmode(GPIO.BCM) 17 | switchPin = 25 18 | 19 | GPIO.setup(switchPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) 20 | 21 | linestatus_dict = {} 22 | 23 | def update_underground_status(): 24 | xmlfile = urllib2.urlopen('http://cloud.tfl.gov.uk/TrackerNet/LineStatus') 25 | parsed = minidom.parse(xmlfile) 26 | linestatus = parsed.getElementsByTagName("LineStatus") 27 | 28 | for entry in linestatus: 29 | line = entry.getElementsByTagName("Line") 30 | name = line[0].getAttribute("Name") 31 | status_details = entry.getAttribute("StatusDetails") 32 | if status_details != '': 33 | linestatus_dict[str(name)] = 1 34 | else: 35 | linestatus_dict[str(name)] = 0 36 | parsed, linestatus, line, name, status_details = None, None, None, None, None 37 | return linestatus_dict 38 | 39 | 40 | uc = { 41 | 'Bakerloo':[50,18,0], 42 | 'Central':[229,0,0], 43 | 'Circle':[255,255,0], 44 | 'DLR':[134,253,215], 45 | 'District':[0,255,0], 46 | 'Hammersmith and City':[255,192,203], 47 | 'Jubilee':[60,60,60], 48 | 'Metropolitan':[128,0,128], 49 | 'Northern':[10,10,10], 50 | 'Overground':[255,165,0], 51 | 'Piccadilly':[30,30,102], 52 | 'Victoria':[40,220,255], 53 | 'Waterloo and City':[0,255,255], 54 | 'TfL Rail':[53,92,125] 55 | } 56 | 57 | def reset(): 58 | for i in range(0,12): 59 | strip.setPixelColorRGB(i,0,0,0) 60 | strip.show() 61 | 62 | def neopixel_status(ugline): 63 | if linestatus_dict[str(ugline)] == 0: 64 | reset() 65 | for i in range(0,12): 66 | strip.setPixelColorRGB(i,uc[str(ugline)][0],uc[str(ugline)][1],uc[str(ugline)][2]) 67 | strip.show() 68 | else: 69 | reset() 70 | for i in range(0,12,2): 71 | strip.setPixelColorRGB(i,uc[str(ugline)][0],uc[str(ugline)][1],uc[str(ugline)][2]) 72 | strip.show() 73 | print(str(ugline)) 74 | 75 | i = 0 76 | 77 | def next_line(): 78 | global i 79 | if i >= (len(line_names)-1): 80 | i = 0 81 | else: 82 | i += 1 83 | return line_names[i] 84 | 85 | if __name__ == '__main__': 86 | # Create NeoPixel object with appropriate configuration. 87 | strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS) 88 | # Intialize the library (must be called once before other functions). 89 | strip.begin() 90 | strip.setBrightness(25) 91 | 92 | update_underground_status() 93 | line_names = linestatus_dict.keys() 94 | curr_line = line_names[0] 95 | neopixel_status(curr_line) 96 | 97 | try: 98 | while True: 99 | if GPIO.input(switchPin) == 0: 100 | update_underground_status() 101 | line_names = linestatus_dict.keys() 102 | curr_line = next_line() 103 | neopixel_status(curr_line) 104 | else: 105 | pass 106 | finally: 107 | pass -------------------------------------------------------------------------------- /neopixel-timer/README.md: -------------------------------------------------------------------------------- 1 | # Neopixel Countdown Timer on a Raspberry Pi 2 | Python script to build a countdown timer using a Neopixel LED ring, and control dial using a potentiometer. 3 | 4 | This script accompanies a tutorial on the Pi Supply Maker Zone. 5 | -------------------------------------------------------------------------------- /neopixel-timer/neopixel-timer.py: -------------------------------------------------------------------------------- 1 | # 2015, Ismail Uddin 2 | # www.scienceexposure.com 3 | 4 | from threading import Thread 5 | import random 6 | import sys 7 | import RPi.GPIO as GPIO 8 | import time 9 | from potentiometer import * 10 | 11 | GPIO.setmode(GPIO.BCM) 12 | GPIO.setup(25, GPIO.IN, pull_up_down=GPIO.PUD_UP) 13 | 14 | from neopixel import * 15 | 16 | # LED strip configuration: 17 | LED_COUNT = 12 # Number of LED pixels. 18 | LED_PIN = 18 # GPIO pin connected to the pixels (must support PWM!). 19 | LED_FREQ_HZ = 800000 # LED signal frequency in hertz (usually 800khz) 20 | LED_DMA = 5 # DMA channel to use for generating signal (try 5) 21 | LED_INVERT = False # True to invert the signal (when using NPN transistor level shift) 22 | 23 | # Create NeoPixel object with appropriate configuration. 24 | strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT) 25 | # Intialize the library (must be called once before other functions). 26 | strip.begin() 27 | strip.setBrightness(50) 28 | strip.show() 29 | 30 | 31 | 32 | low_end = 19 33 | high_end = 251 34 | pot_range = high_end - low_end 35 | smallest_unit = pot_range / 11 36 | 37 | currentNumber = 0 38 | timerValue = 0 39 | setTimerMode = True 40 | timerCountdownMode = True 41 | alarmMode = False 42 | 43 | 44 | 45 | def neopixel_number(): 46 | resistance = analog_read() 47 | number = (resistance / smallest_unit) + 1 48 | return number 49 | 50 | def updateNeopixels(number, color): 51 | global currentNumber 52 | if number != currentNumber: 53 | for i in range(0,strip.numPixels()): 54 | strip.setPixelColorRGB(i,0,0,0) 55 | strip.show() 56 | print(number) 57 | for i in range(0, number): 58 | strip.setPixelColorRGB(i,color[0],color[1],color[2]) 59 | strip.show() 60 | currentNumber = number 61 | 62 | def loopForButton(): 63 | global setTimerMode 64 | global timerValue 65 | while setTimerMode == True: 66 | if GPIO.input(25) == 0: 67 | timerValue = neopixel_number() 68 | print("Timer set for %s minutes" % timerValue) 69 | setTimerMode = False 70 | else: 71 | pass 72 | time.sleep(0.1) 73 | 74 | def alarmAnimation(): 75 | strip.setBrightness(128) 76 | for i in range(strip.numPixels()): 77 | r = random.randrange(0,255) 78 | g = random.randrange(0,255) 79 | b = random.randrange(0,255) 80 | strip.setPixelColorRGB(i,r,g,b) 81 | strip.show() 82 | time.sleep(0.1) 83 | 84 | 85 | def mainLoop(): 86 | global timerCountdownMode 87 | global alarmMode 88 | while timerCountdownMode == True: 89 | if setTimerMode == True: 90 | newNumber = neopixel_number() 91 | updateNeopixels(newNumber,[30,30,102]) 92 | time.sleep(0.5) 93 | elif setTimerMode == False and alarmMode == False: 94 | strip.setBrightness(25) 95 | updateNeopixels(timerValue, [0,255,0]) 96 | print("Started loop") 97 | time.sleep(timerValue * 60) 98 | print("Stuck in loop") 99 | alarmAnimation() 100 | alarmMode = True 101 | elif setTimerMode == False and alarmMode == True: 102 | alarmAnimation() 103 | if GPIO.input(25) == 0: 104 | print("Exiting program") 105 | for i in range(strip.numPixels()): 106 | strip.setPixelColorRGB(i,0,0,0) 107 | strip.show() 108 | sys.exit() 109 | else: 110 | pass 111 | 112 | if __name__ == "__main__": 113 | try: 114 | t1 = Thread(target=mainLoop) 115 | t1.daemon = True 116 | t1.start() 117 | t2 = Thread(target=loopForButton) 118 | t2.daemon = True 119 | t2.start() 120 | while True: 121 | time.sleep(100) 122 | except (KeyboardInterrupt, SystemExit): 123 | print("End") 124 | 125 | -------------------------------------------------------------------------------- /neopixel-timer/potentiometer.py: -------------------------------------------------------------------------------- 1 | # Code from Simon Monk 2 | # Raspberry Pi Cookbook 3 | # http://razzpisampler.oreilly.com/ch08.html 4 | 5 | import RPi.GPIO as GPIO 6 | import time 7 | 8 | GPIO.setmode(GPIO.BCM) 9 | 10 | a_pin = 24 11 | b_pin = 23 12 | 13 | def discharge(): 14 | GPIO.setup(a_pin, GPIO.IN) 15 | GPIO.setup(b_pin, GPIO.OUT) 16 | GPIO.output(b_pin, False) 17 | time.sleep(0.005) 18 | 19 | def charge_time(): 20 | GPIO.setup(b_pin, GPIO.IN) 21 | GPIO.setup(a_pin, GPIO.OUT) 22 | count = 0 23 | GPIO.output(a_pin, True) 24 | while not GPIO.input(b_pin): 25 | count = count + 1 26 | return count 27 | 28 | def analog_read(): 29 | discharge() 30 | return charge_time() 31 | 32 | if __name__ == "__main__": 33 | while True: 34 | print(analog_read()) 35 | time.sleep(1) -------------------------------------------------------------------------------- /servo-temp/README.md: -------------------------------------------------------------------------------- 1 | # Servo thermometer gauge with a Raspberry Pi 2 | This code accompanies the review and project for [Monk Make's Servo Kit](https://www.monkmakes.com/servo-kit/), seen in the Science Exposure [article](http://wp.me/p5wMDR-8C). 3 | 4 | To use the code in this project, follow the instructions below to download this folder on to your Pi and then execute the code. Instructions for components and wirings are provided in the above article. 5 | 6 | ``` 7 | $ sudo apt-get install subversion 8 | $ svn export https://github.com/ismailuddin/raspberrypi/trunk/servo-temp servo-temp 9 | $ cd servo-temp 10 | $ sudo python main.py 11 | ``` 12 | -------------------------------------------------------------------------------- /servo-temp/main.py: -------------------------------------------------------------------------------- 1 | import max7219.led as led 2 | from temp import * 3 | from servosix import ServoSix 4 | import time 5 | 6 | ss = ServoSix() 7 | device = led.matrix() 8 | device.orientation(180) 9 | 10 | min_temp, max_temp = 15, 45 11 | min_servo, max_servo = 0, 180 12 | 13 | 14 | def servoScale(val): 15 | temp_range = (max_temp - min_temp) 16 | servo_range = (max_servo - min_servo) 17 | 18 | servo_val = (((val - min_temp)*servo_range) / temp_range) + min_servo 19 | return servo_val 20 | 21 | while True: 22 | time.sleep(1) 23 | temp = temp_from_r(read_resistance()) 24 | device.show_message("{0:0.0f}".format(temp)) 25 | s = servoScale(temp) 26 | ss.set_servo(1, (180-s)) 27 | print("{0:0.0f}".format(temp)) 28 | -------------------------------------------------------------------------------- /servo-temp/temp.py: -------------------------------------------------------------------------------- 1 | # Code adapted from Simon Monk's Pi Starter Kit 2 | # https://github.com/simonmonk/pi_starter_kit 3 | 4 | import RPi.GPIO as GPIO 5 | import time, math 6 | 7 | GPIO.setmode(GPIO.BCM) 8 | 9 | a_pin = 5 10 | b_pin = 6 11 | 12 | fiddle_factor = 0.9; 13 | 14 | def discharge(): 15 | GPIO.setup(a_pin, GPIO.IN) 16 | GPIO.setup(b_pin, GPIO.OUT) 17 | GPIO.output(b_pin, False) 18 | time.sleep(0.01) 19 | 20 | def charge_time(): 21 | GPIO.setup(b_pin, GPIO.IN) 22 | GPIO.setup(a_pin, GPIO.OUT) 23 | GPIO.output(a_pin, True) 24 | t1 = time.time() 25 | while not GPIO.input(b_pin): 26 | #print("Waiting...") 27 | pass 28 | t2 = time.time() 29 | return (t2 - t1) * 1000000 30 | 31 | def analog_read(): 32 | discharge() 33 | return charge_time() 34 | 35 | def read_resistance(): 36 | n = 100 37 | total = 0; 38 | for i in range(1, n): 39 | total = total + analog_read() 40 | reading = total / float(n) 41 | resistance = reading * 6.05 - 939 42 | return resistance 43 | 44 | def temp_from_r(R): 45 | B = 3800.0 46 | R0 = 1000.0 47 | t0 = 273.15 48 | t25 = t0 + 25.0 49 | inv_T = 1/t25 + 1/B * math.log(R/R0) 50 | T = 1/inv_T - t0 51 | return T * fiddle_factor -------------------------------------------------------------------------------- /streaming-temp-neopixel/README.md: -------------------------------------------------------------------------------- 1 | # Neopixel LED temperature gauge 2 | 3 | This script accompanies the 'Neopixel LED temperature gauge' project at www.scienceexposure.com. The primary file `main.py` contains the bulk of the code, that runs the project. Temperature readings are calculated from the thermistor using the `temp.py` file, which contains code part of the Monk Makes Raspbery Pi Starter Kit project. The `config.json` file houses the credentials for enabling plotting the temperature values in real time. 4 | 5 | ## Requirements 6 | * Raspberry Pi model B, B+ or A (Pi 2 is not supported by one of the libraries required for this project) 7 | * Internet access to the Raspberry Pi for real time plotting (not obligatory) 8 | * Adafruit Neopixel RGB 12 LED 9 | * Monk Makes Starter Kit (or suitable temperature sensor) 10 | 11 | ## How to run the code 12 | Before running the code, a number of libraries must be installed beforehand. Please the blog post on www.scienceexposure.com for details. 13 | 14 | To run the code without plotting temperature values, type `sudo python main.py run`. 15 | 16 | To run the code with plotting temperatures values to Plot.ly, type `sudo python main.py plotly`. 17 | -------------------------------------------------------------------------------- /streaming-temp-neopixel/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "plotly_streaming_tokens": ["",""], 3 | "plotly_api_key": "", 4 | "plotly_username": "" 5 | } -------------------------------------------------------------------------------- /streaming-temp-neopixel/main.py: -------------------------------------------------------------------------------- 1 | # Neopixel LED temperature gauge 2 | # Real time plotting through Plotly 3 | # www.scienceexposure.com 4 | 5 | import time 6 | from neopixel import * 7 | import sys 8 | 9 | plotting = sys.argv[1] 10 | 11 | # LED strip configuration: 12 | LED_COUNT = 12 # Number of LED pixels. 13 | LED_PIN = 18 # GPIO pin connected to the pixels (must support PWM!). 14 | LED_FREQ_HZ = 800000 # LED signal frequency in hertz (usually 800khz) 15 | LED_DMA = 5 # DMA channel to use for generating signal (try 5) 16 | LED_BRIGHTNESS = 60 # Set to 0 for darkest and 255 for brightest 17 | LED_INVERT = False # True to invert the signal (when using NPN transistor level shift) 18 | 19 | import random 20 | from temp import * 21 | 22 | def reset(): 23 | for i in range(strip.numPixels()): 24 | strip.setPixelColorRGB(i,0,0,0) 25 | 26 | # Function to calculate which colour and how many LEDs to light up 27 | def colour(temp): 28 | if temp < 18: 29 | reset() 30 | l = int((temp/18)*4) 31 | for i in range(0,l): 32 | # Cyan colour for low temperatures 33 | strip.setPixelColorRGB(i,0,255,255) 34 | strip.show() 35 | elif temp < 24: 36 | reset() 37 | l = int(temp - 14) 38 | for i in range(0,l): 39 | # Green colour for medium temperatures 40 | strip.setPixelColorRGB(i,50,205,50) 41 | strip.setBrightness(25) 42 | strip.show() 43 | elif temp < 35: 44 | reset() 45 | l = int(((3/10.0)*temp) + 1.5) 46 | for i in range(0,l): 47 | # Red colour for high temperatures 48 | strip.setPixelColorRGB(i,255,0,0) 49 | strip.show() 50 | 51 | if __name__ == '__main__': 52 | # Create NeoPixel object with appropriate configuration. 53 | strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS) 54 | # Intialize the library (must be called once before other functions). 55 | strip.begin() 56 | 57 | print 'Press Ctrl-C to end this script.' 58 | 59 | # Plot.ly functions to stream temperature values online 60 | if plotting == 'plotly': 61 | 62 | import plotly.plotly as py 63 | import json 64 | import datetime 65 | 66 | with open('./config.json') as config_file: 67 | plotly_user_config = json.load(config_file) 68 | py.sign_in(plotly_user_config["plotly_username"], plotly_user_config["plotly_api_key"]) 69 | 70 | url = py.plot([ 71 | { 72 | 'x' : [], 'y' : [], 'type': 'scatter', 73 | 'stream': { 74 | 'token': plotly_user_config['plotly_streaming_tokens'][0], 75 | 'maxpoints': 200 76 | } 77 | 78 | }], filename='RPi streaming temperature') 79 | 80 | print("Link to Plot.ly online graph:", url) 81 | 82 | stream = py.Stream(plotly_user_config['plotly_streaming_tokens'][0]) 83 | stream.open() 84 | else: 85 | pass 86 | 87 | while True: 88 | t = temp_from_r(read_resistance()) 89 | print(t) # Prints temperature values in real time 90 | colour(t) 91 | if plotting == 'plotly': 92 | stream.write({'x': datetime.datetime.now(), 'y':t}) 93 | else: 94 | pass 95 | time.sleep(0.25) # Time interval for taking readings in seconds 96 | -------------------------------------------------------------------------------- /streaming-temp-neopixel/temp.py: -------------------------------------------------------------------------------- 1 | # Functions for calculating temperature values from 2 | # Monk Makes Starter Kit. 3 | # Code originally from pi_starter_kit repository. 4 | # https://github.com/simonmonk/pi_starter_kit 5 | 6 | import RPi.GPIO as GPIO 7 | import time, math 8 | 9 | GPIO.setmode(GPIO.BCM) 10 | 11 | a_pin = 23 12 | b_pin = 24 13 | 14 | fiddle_factor = 0.9; 15 | 16 | def discharge(): 17 | GPIO.setup(a_pin, GPIO.IN) 18 | GPIO.setup(b_pin, GPIO.OUT) 19 | GPIO.output(b_pin, False) 20 | time.sleep(0.01) 21 | 22 | def charge_time(): 23 | GPIO.setup(b_pin, GPIO.IN) 24 | GPIO.setup(a_pin, GPIO.OUT) 25 | GPIO.output(a_pin, True) 26 | t1 = time.time() 27 | while not GPIO.input(b_pin): 28 | pass 29 | t2 = time.time() 30 | return (t2 - t1) * 1000000 31 | 32 | def analog_read(): 33 | discharge() 34 | return charge_time() 35 | 36 | def read_resistance(): 37 | n = 100 38 | total = 0; 39 | for i in range(1, n): 40 | total = total + analog_read() 41 | reading = total / float(n) 42 | resistance = reading * 6.05 - 939 43 | return resistance 44 | 45 | def temp_from_r(R): 46 | B = 3800.0 47 | R0 = 1000.0 48 | t0 = 273.15 49 | t25 = t0 + 25.0 50 | inv_T = 1/t25 + 1/B * math.log(R/R0) 51 | T = 1/inv_T - t0 52 | return T * fiddle_factor --------------------------------------------------------------------------------