30 | #include "htu21dflib.h"
31 |
32 | static const char I2CDEV[] = "/dev/i2c-1"; // raspberry pi
33 | static const uint8_t I2CADDR = 0x40; // htu21df i2c address
34 |
35 | static const char MQTT_HOST[] = "bbone"; // mqtt host
36 | static const char MQTT_TOPIC_TEMPERATURE[] = "temperature/mbed"; // mqtt temp topic
37 | static const char MQTT_TOPIC_HUMIDITY[] = "humidity/mbed"; // mqtt humi topic
38 |
39 | int main(int argc, char *argv[])
40 | {
41 | int rc; // return code
42 | int i2cfd; // i2c file descriptor
43 | float temperature, humidity;
44 | char mqttstr[256];
45 |
46 | i2cfd = i2c_open(I2CDEV);
47 | if (i2cfd < 0) {
48 | printf("i2c_open failed %d\n", i2cfd);
49 | return -1;
50 | }
51 |
52 | rc = htu21df_init(i2cfd, I2CADDR);
53 | if (rc < 0) {
54 | printf("i2c_init failed %d\n", rc);
55 | return -2;
56 | }
57 |
58 | while (1) {
59 | rc = htu21df_read_temperature(i2cfd, &temperature);
60 | if (rc < 0) {
61 | printf("i2c_read_temperature failed %d\n", rc);
62 | return -3;
63 | }
64 |
65 | rc = htu21df_read_humidity(i2cfd, &humidity);
66 | if (rc < 0) {
67 | printf("i2c_read_humidity failed %d\n", rc);
68 | return -4;
69 | }
70 | // Format the command to mqtt the temperature
71 | rc = snprintf(mqttstr, sizeof(mqttstr),
72 | "mosquitto_pub -h %s -t %s -m %0.1f",
73 | MQTT_HOST, MQTT_TOPIC_TEMPERATURE, temperature);
74 | if (rc < 0) {
75 | printf("snprintf failed %d\n", rc);
76 | }
77 | // Run the command to dweet the data
78 | rc = system(mqttstr);
79 | if (rc != 0) {
80 | printf("system failed %d\n", rc);
81 | }
82 | // Format the command to mqtt the humidity
83 | rc = snprintf(mqttstr, sizeof(mqttstr),
84 | "mosquitto_pub -h %s -t %s -m %0.1f",
85 | MQTT_HOST, MQTT_TOPIC_HUMIDITY, humidity);
86 | if (rc < 0) {
87 | printf("snprintf failed %d\n", rc);
88 | }
89 | // Run the command to dweet the data
90 | rc = system(mqttstr);
91 | if (rc != 0) {
92 | printf("system failed %d\n", rc);
93 | }
94 | // Wait 10 seconds
95 | sleep(10);
96 | }
97 |
98 | rc = i2c_close(i2cfd);
99 | if (rc < 0) {
100 | printf("i2c_close failed %d\n", rc);
101 | return -5;
102 | }
103 |
104 | return 0;
105 | }
106 |
--------------------------------------------------------------------------------
/graphs/PowerCurrentGraph.py:
--------------------------------------------------------------------------------
1 | # PowerCurrentGraph
2 | # filename: PowerCurrentGraph.py
3 | # Version 1.3 09/12/13
4 | # Version 1.4 03/30/15
5 | #
6 | # contains event routines for data collection
7 | #
8 | #
9 |
10 | import sys
11 | import time
12 | import RPi.GPIO as GPIO
13 |
14 | import gc
15 | import datetime
16 |
17 | import matplotlib
18 | # Force matplotlib to not use any Xwindows backend.
19 | matplotlib.use('Agg')
20 |
21 | from matplotlib import pyplot
22 | from matplotlib import dates
23 |
24 | import pylab
25 |
26 | import MySQLdb as mdb
27 |
28 | # Check for user imports
29 | try:
30 | import conflocal as config
31 | except ImportError:
32 | import config
33 |
34 | def PowerCurrentGraph(source,days,delay):
35 |
36 |
37 |
38 | print("PowerCurrentGraph source:%s days:%s delay:%i" % (source,days,delay))
39 | print("sleeping :",delay)
40 | time.sleep(delay)
41 | print("PowerCurrentGraph running now")
42 |
43 | # blink GPIO LED when it's run
44 | GPIO.setup(18, GPIO.OUT)
45 | GPIO.output(18, True)
46 | time.sleep(0.2)
47 | GPIO.output(18, False)
48 |
49 | # now we have get the data, stuff it in the graph
50 |
51 | try:
52 | print("trying database")
53 | db = mdb.connect('localhost', 'root', config.MySQL_Password, 'GroveWeatherPi');
54 |
55 | cursor = db.cursor()
56 |
57 | query = "SELECT TimeStamp, solarCurrent, batteryCurrent, loadCurrent FROM PowerSystem where now() - interval %i hour < TimeStamp" % (days*24)
58 | cursor.execute(query)
59 | result = cursor.fetchall()
60 |
61 | t = []
62 | s = []
63 | u = []
64 | v = []
65 | #x = []
66 |
67 | for record in result:
68 | t.append(record[0])
69 | s.append(record[1])
70 | u.append(record[2])
71 | v.append(record[3])
72 | #x.append(record[4])
73 | fig = pyplot.figure()
74 |
75 |
76 | print ("count of t=",len(t))
77 | #print (t)
78 | if (len(t) == 0):
79 | return
80 | #dts = map(datetime.datetime.fromtimestamp, t)
81 | #print dts
82 | #fds = dates.date2num(t) # converted
83 | # matplotlib date format object
84 | hfmt = dates.DateFormatter('%m/%d-%H')
85 |
86 | fig.set_facecolor('white')
87 | ax = fig.add_subplot(111,axisbg = 'white')
88 | #ax.vlines(fds, -200.0, 1000.0,colors='w')
89 |
90 | ax.xaxis.set_major_locator(dates.HourLocator(interval=6))
91 | ax.xaxis.set_major_formatter(hfmt)
92 | ax.set_ylim(bottom = -200.0)
93 | pyplot.xticks(rotation='vertical')
94 | pyplot.subplots_adjust(bottom=.3)
95 | pylab.plot(t, s, color='b',label="Solar",linestyle="-",marker=".")
96 | pylab.plot(t, u, color='r',label="Battery",linestyle="-",marker=".")
97 | pylab.plot(t, v, color='g',label="Load",linestyle="-",marker=".")
98 | #pylab.plot(t, x, color='m',label="Power Eff",linestyle="-",marker=".")
99 | pylab.xlabel("Hours")
100 | pylab.ylabel("Current ma")
101 | pylab.legend(loc='upper left')
102 |
103 | if (max(u) > max(s)):
104 | myMax = max(u)+ 100.0
105 | else:
106 | myMax = max(s)
107 | pylab.axis([min(t), max(t), min(u), myMax])
108 | pylab.figtext(.5, .05, ("GroveWeatherPi Power Current Last %i Days" % days),fontsize=18,ha='center')
109 | pyplot.setp( ax.xaxis.get_majorticklabels(), rotation=70)
110 |
111 | pylab.grid(True)
112 |
113 | pyplot.show()
114 | try:
115 | pyplot.savefig("/home/pi/RasPiConnectServer/static/PowerCurrentGraph.png",facecolor=fig.get_facecolor())
116 | except:
117 | pyplot.savefig("/home/pi/SDL_Pi_GroveWeatherPi/static/PowerCurrentGraph.png",facecolor=fig.get_facecolor())
118 |
119 |
120 | except mdb.Error, e:
121 |
122 | print "Error %d: %s" % (e.args[0],e.args[1])
123 |
124 | finally:
125 |
126 | cursor.close()
127 | db.close()
128 |
129 | del cursor
130 | del db
131 |
132 | fig.clf()
133 | pyplot.close()
134 | pylab.close()
135 | del t, s, u, v
136 | gc.collect()
137 | print("PowerCurrentGrapGraph finished now")
138 |
--------------------------------------------------------------------------------
/graphs/PowerVoltageGraph.py:
--------------------------------------------------------------------------------
1 | # PowerVoltageGraph
2 | # filename: VoltageGraph.py
3 | # Version 1.3 09/12/13
4 | # Version 1.4 03/30/15
5 | #
6 | # contains event routines for data collection
7 | #
8 | #
9 |
10 | import sys
11 | import time
12 | import RPi.GPIO as GPIO
13 |
14 | import gc
15 | import datetime
16 |
17 | import matplotlib
18 | # Force matplotlib to not use any Xwindows backend.
19 | matplotlib.use('Agg')
20 |
21 | from matplotlib import pyplot
22 | from matplotlib import dates
23 |
24 | import pylab
25 |
26 | import MySQLdb as mdb
27 |
28 | # Check for user imports
29 | try:
30 | import conflocal as config
31 | except ImportError:
32 | import config
33 |
34 | def PowerVoltageGraph(source,days,delay):
35 |
36 |
37 |
38 | print("PowerVoltageGraph source:%s days:%s delay:%i" % (source,days,delay))
39 | print("sleeping :",delay)
40 | time.sleep(delay)
41 | print("PowerVoltageGraph running now")
42 |
43 | # blink GPIO LED when it's run
44 | GPIO.setup(18, GPIO.OUT)
45 | GPIO.output(18, True)
46 | time.sleep(0.2)
47 | GPIO.output(18, False)
48 |
49 | # now we have get the data, stuff it in the graph
50 |
51 | try:
52 | print("trying database")
53 | db = mdb.connect('localhost', 'root', config.MySQL_Password, 'GroveWeatherPi');
54 |
55 | cursor = db.cursor()
56 |
57 | query = "SELECT TimeStamp, solarVoltage, batteryVoltage, loadVoltage FROM PowerSystem where now() - interval %i hour < TimeStamp" % (days*24)
58 | cursor.execute(query)
59 | result = cursor.fetchall()
60 |
61 | t = []
62 | s = []
63 | u = []
64 | v = []
65 | #x = []
66 |
67 | for record in result:
68 | t.append(record[0])
69 | s.append(record[1])
70 | u.append(record[2])
71 | v.append(record[3])
72 | #x.append(record[4])
73 | fig = pyplot.figure()
74 |
75 | print ("count of t=",len(t))
76 | #print (t)
77 | if (len(t) == 0):
78 | return
79 | #dts = map(datetime.datetime.fromtimestamp, t)
80 | #print dts
81 | #fds = dates.date2num(t) # converted
82 | # matplotlib date format object
83 | hfmt = dates.DateFormatter('%m/%d-%H')
84 |
85 | fig = pyplot.figure()
86 | fig.set_facecolor('white')
87 | ax = fig.add_subplot(111,axisbg = 'white')
88 | #ax.vlines(fds, -200.0, 1000.0,colors='w')
89 |
90 | ax.xaxis.set_major_locator(dates.HourLocator(interval=6))
91 | ax.xaxis.set_major_formatter(hfmt)
92 | ax.set_ylim(bottom = -200.0)
93 | pyplot.xticks(rotation='vertical')
94 | pyplot.subplots_adjust(bottom=.3)
95 | pylab.plot(t, s, color='b',label="Solar",linestyle="-",marker=".")
96 | pylab.plot(t, u, color='r',label="Battery",linestyle="-",marker=".")
97 | pylab.plot(t, v, color='g',label="Load",linestyle="-",marker=".")
98 | #pylab.plot(t, x, color='m',label="Power Eff",linestyle="-",marker=".")
99 | pylab.xlabel("Hours")
100 | pylab.ylabel("Voltage V")
101 | pylab.legend(loc='upper left')
102 |
103 | if (max(u) > max(s)):
104 | myMax = max(u)+ 100.0
105 | else:
106 | myMax = max(s)
107 | pylab.axis([min(t), max(t), min(u), myMax])
108 | pylab.figtext(.5, .05, ("GroveWeatherPi Power Voltage Last %i Days" % days),fontsize=18,ha='center')
109 | pyplot.setp( ax.xaxis.get_majorticklabels(), rotation=70)
110 |
111 | pylab.grid(True)
112 |
113 | pyplot.show()
114 | try:
115 | pyplot.savefig("/home/pi/RasPiConnectServer/static/PowerVoltageGraph.png",facecolor=fig.get_facecolor())
116 | except:
117 | pyplot.savefig("/home/pi/SDL_Pi_GroveWeatherPi/static/PowerVoltageGraph.png",facecolor=fig.get_facecolor())
118 |
119 |
120 | except mdb.Error, e:
121 |
122 | print "Error %d: %s" % (e.args[0],e.args[1])
123 |
124 | finally:
125 |
126 | cursor.close()
127 | db.close()
128 |
129 | del cursor
130 | del db
131 |
132 | fig.clf()
133 | pyplot.close()
134 | pylab.close()
135 | del t, s, u, v
136 | gc.collect()
137 | print("PowerVoltageGraph finished now")
138 |
--------------------------------------------------------------------------------
/graphs/TemperatureHumidityGraph.py:
--------------------------------------------------------------------------------
1 | # TemperatureHumidityGraph
2 | # filename:TemperatureHumidityGraph.py
3 | # Version 1.1 03/30/15
4 | #
5 | # contains event routines for data collection
6 | #
7 | #
8 |
9 | import sys
10 | import time
11 | import RPi.GPIO as GPIO
12 |
13 | import gc
14 | import datetime
15 |
16 | import matplotlib
17 | # Force matplotlib to not use any Xwindows backend.
18 | matplotlib.use('Agg')
19 |
20 | from matplotlib import pyplot
21 | from matplotlib import dates
22 |
23 | import pylab
24 |
25 | import MySQLdb as mdb
26 |
27 | # Check for user imports
28 | try:
29 | import conflocal as config
30 | except ImportError:
31 | import config
32 |
33 |
34 |
35 | def TemperatureHumidityGraph(source,days,delay):
36 |
37 |
38 |
39 | print("TemperatureHumidityGraph source:%s days:%s" % (source,days))
40 | print("sleeping seconds:", delay)
41 | time.sleep(delay)
42 | print("TemperatureHumidityGraph running now")
43 |
44 |
45 | # blink GPIO LED when it's run
46 | GPIO.setup(18, GPIO.OUT)
47 | GPIO.output(18, True)
48 | time.sleep(0.2)
49 | GPIO.output(18, False)
50 |
51 | # now we have get the data, stuff it in the graph
52 |
53 | try:
54 | print("trying database")
55 | db = mdb.connect('localhost', 'root', config.MySQL_Password, 'GroveWeatherPi');
56 |
57 | cursor = db.cursor()
58 |
59 | query = "SELECT TimeStamp, bmp180Temperature, outsideTemperature, outsideHumidity, insideHumidity FROM WeatherData where now() - interval %i hour < TimeStamp" % (days*24)
60 |
61 | print "query=", query
62 | cursor.execute(query)
63 | result = cursor.fetchall()
64 |
65 | t = []
66 | u = []
67 | v = []
68 | x = []
69 | z = []
70 |
71 | fig = pyplot.figure()
72 |
73 |
74 |
75 | for record in result:
76 | t.append(record[0])
77 | u.append(record[1])
78 | v.append(record[2])
79 | x.append(record[3])
80 | z.append(record[4])
81 |
82 | print ("count of t=",len(t))
83 | if (len(t) == 0):
84 | return
85 |
86 | #dts = map(datetime.datetime.fromtimestamp, s)
87 | #fds = dates.date2num(dts) # converted
88 | # matplotlib date format object
89 | hfmt = dates.DateFormatter('%m/%d-%H')
90 |
91 |
92 | ax = fig.add_subplot(111)
93 | ax.xaxis.set_major_locator(dates.HourLocator(interval=6))
94 | ax.xaxis.set_major_formatter(hfmt)
95 | pylab.xticks(rotation='vertical')
96 |
97 | pyplot.subplots_adjust(bottom=.3)
98 | pylab.plot(t, v, color='g',label="Outside Temp (C)",linestyle="-",marker=".")
99 | pylab.plot(t, u, color='r',label="Inside Temp (C)",linestyle="-",marker=".")
100 | pylab.xlabel("Hours")
101 | pylab.ylabel("degrees C")
102 | pylab.legend(loc='upper left')
103 | pylab.axis([min(t), max(t), 0, 40])
104 | ax2 = pylab.twinx()
105 | pylab.ylabel("% ")
106 | pylab.plot(t, x, color='y',label="Outside Hum %",linestyle="-",marker=".")
107 | pylab.plot(t, z, color='b',label="Inside Hum %",linestyle="-",marker=".")
108 | pylab.axis([min(t), max(t), 0, 100])
109 | pylab.legend(loc='lower left')
110 | pylab.figtext(.5, .05, ("Environmental Statistics Last %i Days" % days),fontsize=18,ha='center')
111 |
112 | #pylab.grid(True)
113 |
114 | pyplot.setp( ax.xaxis.get_majorticklabels(), rotation=70)
115 | ax.xaxis.set_major_formatter(dates.DateFormatter('%m/%d-%H'))
116 | pyplot.show()
117 | try:
118 | pyplot.savefig("/home/pi/RasPiConnectServer/static/TemperatureHumidityGraph.png")
119 | except:
120 | pyplot.savefig("/home/pi/SDL_Pi_GroveWeatherPi/static/TemperatureHumidityGraph.png")
121 |
122 |
123 | except mdb.Error, e:
124 |
125 | print "Error %d: %s" % (e.args[0],e.args[1])
126 |
127 | finally:
128 |
129 | cursor.close()
130 | db.close()
131 |
132 | del cursor
133 | del db
134 |
135 | fig.clf()
136 | pyplot.close()
137 | pylab.close()
138 | del t, u, v, x
139 | gc.collect()
140 | print("TemperatureHumidityGraph finished now")
141 |
--------------------------------------------------------------------------------
/graphs/BarometerLightningGraph.py:
--------------------------------------------------------------------------------
1 | # BarometerLightningGraph
2 | # filename: BarometerLightningGraph.py
3 | # Version 1.1 03/30/15
4 | #
5 | # contains graphing code
6 | #
7 | #
8 |
9 | import sys
10 | import time
11 | import RPi.GPIO as GPIO
12 |
13 | import gc
14 | import datetime
15 |
16 | import matplotlib
17 | # Force matplotlib to not use any Xwindows backend.
18 | matplotlib.use('Agg')
19 |
20 | from matplotlib import pyplot
21 | from matplotlib import dates
22 |
23 | import pylab
24 |
25 | import MySQLdb as mdb
26 |
27 | # Check for user imports
28 | try:
29 | import conflocal as config
30 | except ImportError:
31 | import config
32 |
33 |
34 | def BarometerLightningGraph(source,days,delay):
35 |
36 |
37 |
38 | print("BarometerLightningGraph source:%s days:%s" % (source,days))
39 | print("sleeping seconds:", delay)
40 | time.sleep(delay)
41 | print("BarometerLightningGraph running now")
42 |
43 | # blink GPIO LED when it's run
44 | GPIO.setup(18, GPIO.OUT)
45 | GPIO.output(18, True)
46 | time.sleep(0.2)
47 | GPIO.output(18, False)
48 |
49 |
50 | # now we have get the data, stuff it in the graph
51 |
52 | try:
53 | print("trying database")
54 | db = mdb.connect('localhost', 'root', config.MySQL_Password, 'GroveWeatherPi');
55 |
56 | cursor = db.cursor()
57 |
58 | query = "SELECT TimeStamp, bmp180SeaLevel, as3935LastInterrupt, as3935LastDistance FROM WeatherData where now() - interval %i hour < TimeStamp" % (days*24)
59 | print "query=", query
60 | cursor.execute(query)
61 | result = cursor.fetchall()
62 |
63 | t = []
64 | s = []
65 | u = []
66 | v = []
67 |
68 | for record in result:
69 | t.append(record[0])
70 | s.append(record[1])
71 | u.append(record[2])
72 | v.append(record[3])
73 |
74 |
75 | fig = pyplot.figure()
76 |
77 | print ("count of t=",len(t))
78 | if (len(t) == 0):
79 | return
80 | #dts = map(datetime.datetime.fromtimestamp, s)
81 | #fds = dates.date2num(t) # converted
82 | # matplotlib date format object
83 | hfmt = dates.DateFormatter('%m/%d-%H')
84 |
85 |
86 | ax = fig.add_subplot(111)
87 | for i in range(len(s)):
88 | s[i] = s[i] * 10
89 |
90 | #ax.vlines(fds, -200.0, 1000.0,colors='w')
91 | ax.xaxis.set_major_locator(dates.HourLocator(interval=6))
92 | ax.xaxis.set_major_formatter(hfmt)
93 | pylab.xticks(rotation='vertical')
94 |
95 | pyplot.subplots_adjust(bottom=.3)
96 | pylab.plot(t, s, color='b',label="Barometric Pressure (mb) ",linestyle="-",marker=".")
97 | pylab.xlabel("Hours")
98 | pylab.ylabel("millibars")
99 | pylab.legend(loc='upper left')
100 | pylab.axis([min(t), max(t), 900, 1100])
101 | ax2 = pylab.twinx()
102 | pylab.ylabel("Last Interrupt / Distance ")
103 |
104 | # scale array
105 |
106 | for i in range(len(v)):
107 | v[i] = v[i] * 10
108 | for i in range(len(u)):
109 | u[i] = u[i] * 10
110 |
111 |
112 | pylab.plot(t, u, color='y',label="as3935 Last Interrupt",linestyle="-",marker=".")
113 | pylab.plot(t, v, color='r',label="as3935 Last Distance",linestyle="-",marker=".")
114 | pylab.axis([min(t), max(t), 0, max(u)])
115 | pylab.legend(loc='lower left')
116 | pylab.figtext(.5, .05, ("Barometer and Lightning Statistics Last %i Days" % days),fontsize=18,ha='center')
117 |
118 | #pylab.grid(True)
119 |
120 | pyplot.setp( ax.xaxis.get_majorticklabels(), rotation=70)
121 | ax.xaxis.set_major_formatter(dates.DateFormatter('%m/%d-%H'))
122 | pyplot.show()
123 | try:
124 | pyplot.savefig("/home/pi/RasPiConnectServer/static/BarometerLightningGraph.png")
125 | except:
126 | pyplot.savefig("/home/pi/SDL_Pi_GroveWeatherPi/static/BarometerLightningGraph.png")
127 |
128 |
129 | except mdb.Error, e:
130 |
131 | print "Error %d: %s" % (e.args[0],e.args[1])
132 |
133 | finally:
134 |
135 | cursor.close()
136 | db.close()
137 |
138 | del cursor
139 | del db
140 |
141 | fig.clf()
142 | pyplot.close()
143 | pylab.close()
144 | del t, s, u, v
145 | gc.collect()
146 | print("BarometerLightningGraph finished now")
147 |
--------------------------------------------------------------------------------
/Adafruit_Python_GPIO/Adafruit_GPIO/Platform.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2014 Adafruit Industries
2 | # Author: Tony DiCola
3 |
4 | # Permission is hereby granted, free of charge, to any person obtaining a copy
5 | # of this software and associated documentation files (the "Software"), to deal
6 | # in the Software without restriction, including without limitation the rights
7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | # copies of the Software, and to permit persons to whom the Software is
9 | # furnished to do so, subject to the following conditions:
10 |
11 | # The above copyright notice and this permission notice shall be included in all
12 | # copies or substantial portions of the Software.
13 |
14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | # SOFTWARE.
21 | import platform
22 | import re
23 |
24 | # Platform identification constants.
25 | UNKNOWN = 0
26 | RASPBERRY_PI = 1
27 | BEAGLEBONE_BLACK = 2
28 |
29 |
30 | def platform_detect():
31 | """Detect if running on the Raspberry Pi or Beaglebone Black and return the
32 | platform type. Will return RASPBERRY_PI, BEAGLEBONE_BLACK, or UNKNOWN."""
33 | # Handle Raspberry Pi
34 | pi = pi_version()
35 | if pi is not None:
36 | return RASPBERRY_PI
37 |
38 | # Handle Beaglebone Black
39 | # TODO: Check the Beaglebone Black /proc/cpuinfo value instead of reading
40 | # the platform.
41 | plat = platform.platform()
42 | if plat.lower().find('armv7l-with-debian') > -1:
43 | return BEAGLEBONE_BLACK
44 | elif plat.lower().find('armv7l-with-ubuntu') > -1:
45 | return BEAGLEBONE_BLACK
46 | elif plat.lower().find('armv7l-with-glibc2.4') > -1:
47 | return BEAGLEBONE_BLACK
48 |
49 | # Couldn't figure out the platform, just return unknown.
50 | return UNKNOWN
51 |
52 |
53 | def pi_revision():
54 | """Detect the revision number of a Raspberry Pi, useful for changing
55 | functionality like default I2C bus based on revision."""
56 | # Revision list available at: http://elinux.org/RPi_HardwareHistory#Board_Revision_History
57 | with open('/proc/cpuinfo', 'r') as infile:
58 | for line in infile:
59 | # Match a line of the form "Revision : 0002" while ignoring extra
60 | # info in front of the revsion (like 1000 when the Pi was over-volted).
61 | match = re.match('Revision\s+:\s+.*(\w{4})$', line, flags=re.IGNORECASE)
62 | if match and match.group(1) in ['0000', '0002', '0003']:
63 | # Return revision 1 if revision ends with 0000, 0002 or 0003.
64 | return 1
65 | elif match:
66 | # Assume revision 2 if revision ends with any other 4 chars.
67 | return 2
68 | # Couldn't find the revision, throw an exception.
69 | raise RuntimeError('Could not determine Raspberry Pi revision.')
70 |
71 |
72 | def pi_version():
73 | """Detect the version of the Raspberry Pi. Returns either 1, 2 or
74 | None depending on if it's a Raspberry Pi 1 (model A, B, A+, B+),
75 | Raspberry Pi 2 (model B+), or not a Raspberry Pi.
76 | """
77 | # Check /proc/cpuinfo for the Hardware field value.
78 | # 2708 is pi 1
79 | # 2709 is pi 2
80 | # Anything else is not a pi.
81 | with open('/proc/cpuinfo', 'r') as infile:
82 | cpuinfo = infile.read()
83 | # Match a line like 'Hardware : BCM2709'
84 | match = re.search('^Hardware\s+:\s+(\w+)$', cpuinfo,
85 | flags=re.MULTILINE | re.IGNORECASE)
86 | if not match:
87 | # Couldn't find the hardware, assume it isn't a pi.
88 | return None
89 | if match.group(1) == 'BCM2708':
90 | # Pi 1
91 | return 1
92 | elif match.group(1) == 'BCM2709':
93 | # Pi 2
94 | return 2
95 | else:
96 | # Something else, not a pi.
97 | return None
98 |
--------------------------------------------------------------------------------
/Adafruit_Python_GPIO/test/test_PWM.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2014 Adafruit Industries
2 | # Author: Tony DiCola
3 | #
4 | # Permission is hereby granted, free of charge, to any person obtaining a copy
5 | # of this software and associated documentation files (the "Software"), to deal
6 | # in the Software without restriction, including without limitation the rights
7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | # copies of the Software, and to permit persons to whom the Software is
9 | # furnished to do so, subject to the following conditions:
10 | #
11 | # The above copyright notice and this permission notice shall be included in
12 | # all copies or substantial portions of the Software.
13 | #
14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | # THE SOFTWARE.
21 |
22 | import unittest
23 |
24 | from mock import Mock, patch
25 |
26 | import Adafruit_GPIO.PWM as PWM
27 |
28 |
29 | class TestRPi_PWM_Adapter(unittest.TestCase):
30 | def test_setup(self):
31 | rpi_gpio = Mock()
32 | pwm = PWM.RPi_PWM_Adapter(rpi_gpio)
33 | pwm.start(1, 50)
34 | rpi_gpio.PWM.assert_called_with(1, 2000)
35 |
36 | def test_set_duty_cycle_valid(self):
37 | rpi_gpio = Mock()
38 | pwm = PWM.RPi_PWM_Adapter(rpi_gpio)
39 | pwm.start(1, 50)
40 | pwm.set_duty_cycle(1, 75)
41 | # Implicit verification that no assertion or other error thrown.
42 |
43 | def test_set_duty_cycle_invalid(self):
44 | rpi_gpio = Mock()
45 | pwm = PWM.RPi_PWM_Adapter(rpi_gpio)
46 | pwm.start(1, 50)
47 | self.assertRaises(ValueError, pwm.set_duty_cycle, 1, 150)
48 | self.assertRaises(ValueError, pwm.set_duty_cycle, 1, -10)
49 |
50 | def test_set_frequency(self):
51 | rpi_gpio = Mock()
52 | pwm = PWM.RPi_PWM_Adapter(rpi_gpio)
53 | pwm.start(1, 50)
54 | pwm.set_frequency(1, 1000)
55 | # Implicit verification that no assertion or other error thrown.
56 |
57 |
58 | class TestBBIO_PWM_Adapter(unittest.TestCase):
59 | def test_setup(self):
60 | bbio_pwm = Mock()
61 | pwm = PWM.BBIO_PWM_Adapter(bbio_pwm)
62 | pwm.start('P9_16', 50)
63 | bbio_pwm.start.assert_called_with('P9_16', 50, 2000)
64 |
65 | def test_set_duty_cycle_valid(self):
66 | bbio_pwm = Mock()
67 | pwm = PWM.BBIO_PWM_Adapter(bbio_pwm)
68 | pwm.start('P9_16', 50)
69 | pwm.set_duty_cycle('P9_16', 75)
70 | bbio_pwm.set_duty_cycle.assert_called_with('P9_16', 75)
71 |
72 | def test_set_duty_cycle_invalid(self):
73 | bbio_pwm = Mock()
74 | pwm = PWM.BBIO_PWM_Adapter(bbio_pwm)
75 | pwm.start('P9_16', 50)
76 | self.assertRaises(ValueError, pwm.set_duty_cycle, 'P9_16', 150)
77 | self.assertRaises(ValueError, pwm.set_duty_cycle, 'P9_16', -10)
78 |
79 | def test_set_frequency(self):
80 | bbio_pwm = Mock()
81 | pwm = PWM.BBIO_PWM_Adapter(bbio_pwm)
82 | pwm.start('P9_16', 50)
83 | pwm.set_frequency('P9_16', 1000)
84 | bbio_pwm.set_frequency.assert_called_with('P9_16', 1000)
85 |
86 |
87 | class TestGetPlatformPWM(unittest.TestCase):
88 | @patch.dict('sys.modules', {'RPi': Mock(), 'RPi.GPIO': Mock()})
89 | @patch('platform.platform', Mock(return_value='Linux-3.10.25+-armv6l-with-debian-7.4'))
90 | def test_raspberrypi(self):
91 | pwm = PWM.get_platform_pwm()
92 | self.assertIsInstance(pwm, PWM.RPi_PWM_Adapter)
93 |
94 | @patch.dict('sys.modules', {'Adafruit_BBIO': Mock(), 'Adafruit_BBIO.PWM': Mock()})
95 | @patch('platform.platform', Mock(return_value='Linux-3.8.13-bone47-armv7l-with-debian-7.4'))
96 | def test_beagleboneblack(self):
97 | pwm = PWM.get_platform_pwm()
98 | self.assertIsInstance(pwm, PWM.BBIO_PWM_Adapter)
99 |
100 | @patch('platform.platform', Mock(return_value='Darwin-13.2.0-x86_64-i386-64bit'))
101 | def test_otherplatform(self):
102 | self.assertRaises(RuntimeError, PWM.get_platform_pwm)
103 |
--------------------------------------------------------------------------------
/testSI1145.py:
--------------------------------------------------------------------------------
1 |
2 | #!/usr/bin/python
3 |
4 | # Author: Joe Gutting
5 | # With use of Adafruit SI1145 library for Arduino, Adafruit_GPIO.I2C & BMP Library by Tony DiCola
6 | #
7 | # Permission is hereby granted, free of charge, to any person obtaining a copy
8 | # of this software and associated documentation files (the "Software"), to deal
9 | # in the Software without restriction, including without limitation the rights
10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | # copies of the Software, and to permit persons to whom the Software is
12 | # furnished to do so, subject to the following conditions:
13 | #
14 | # The above copyright notice and this permission notice shall be included in
15 | # all copies or substantial portions of the Software.
16 | #
17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | # THE SOFTWARE.
24 |
25 | # Can enable debug output by uncommenting:
26 | #import logging
27 | #logging.basicConfig(level=logging.DEBUG)
28 | import sys
29 |
30 | sys.path.append('./SDL_Pi_TCA9545')
31 | sys.path.append('./SDL_Pi_SI1145')
32 |
33 | import time
34 | import SDL_Pi_SI1145
35 | import SI1145Lux
36 |
37 |
38 | import SDL_Pi_TCA9545
39 |
40 |
41 |
42 |
43 | ################
44 | # TCA9545 I2C Mux
45 |
46 | #/*=========================================================================
47 | # I2C ADDRESS/BITS
48 | # -----------------------------------------------------------------------*/
49 | TCA9545_ADDRESS = (0x73) # 1110011 (A0+A1=VDD)
50 | #/*=========================================================================*/
51 |
52 | #/*=========================================================================
53 | # CONFIG REGISTER (R/W)
54 | # -----------------------------------------------------------------------*/
55 | TCA9545_REG_CONFIG = (0x00)
56 | # /*---------------------------------------------------------------------*/
57 |
58 | TCA9545_CONFIG_BUS0 = (0x01) # 1 = enable, 0 = disable
59 | TCA9545_CONFIG_BUS1 = (0x02) # 1 = enable, 0 = disable
60 | TCA9545_CONFIG_BUS2 = (0x04) # 1 = enable, 0 = disable
61 | TCA9545_CONFIG_BUS3 = (0x08) # 1 = enable, 0 = disable
62 |
63 | #/*=========================================================================*/
64 |
65 | # I2C Mux TCA9545 Detection
66 | try:
67 | tca9545 = SDL_Pi_TCA9545.SDL_Pi_TCA9545(addr=TCA9545_ADDRESS, bus_enable = TCA9545_CONFIG_BUS0)
68 |
69 |
70 | # turn I2CBus 1 on
71 | tca9545.write_control_register(TCA9545_CONFIG_BUS3)
72 | TCA9545_I2CMux_Present = True
73 | except:
74 | print ">>>>>>>>>>>>>>>>>>><<<<<<<<<<<"
75 | print "TCA9545 I2C Mux Not Present"
76 | print ">>>>>>>>>>>>>>>>>>><<<<<<<<<<<"
77 |
78 |
79 |
80 | # Default constructor will pick a default I2C bus.
81 | #
82 | # For the Raspberry Pi this means you should hook up to the only exposed I2C bus
83 | # from the main GPIO header and the library will figure out the bus number based
84 | # on the Pi's revision.
85 | #
86 | # For the Beaglebone Black the library will assume bus 1 by default, which is
87 | # exposed with SCL = P9_19 and SDA = P9_20.
88 | indoor =0
89 | sensor = SDL_Pi_SI1145.SDL_Pi_SI1145(indoor=indoor)
90 |
91 | time.sleep(1.0)
92 |
93 |
94 |
95 | print 'Press Cntrl + Z to cancel'
96 |
97 | while True:
98 | vis = sensor.readVisible()
99 | IR = sensor.readIR()
100 | UV = sensor.readUV()
101 | IR_Lux = SI1145Lux.SI1145_IR_to_Lux(IR)
102 | vis_Lux = SI1145Lux.SI1145_VIS_to_Lux(vis)
103 | uvIndex = UV / 100.0
104 | print '--------------------'
105 | print '--------------------'
106 | print 'indoor=', indoor
107 | print '--------------------'
108 | print 'Vis: ' + str(vis)
109 | print 'IR: ' + str(IR)
110 | print 'UV: ' + str(UV)
111 | print '--------------------'
112 | print 'Vis Lux: ' + str(vis_Lux)
113 | print 'IR Lux: ' + str(IR_Lux)
114 | print 'UV Index: ' + str(uvIndex)
115 | print '--------------------'
116 | print '--------------------'
117 | time.sleep(5)
118 |
119 |
--------------------------------------------------------------------------------
/SDL_Pi_TCA9545/testSDL_Pi_TCA9545.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # Test SDL_Pi_INA3221
4 | # John C. Shovic, SwitchDoc Labs
5 | # 03/05/2015
6 | #
7 | #
8 |
9 | # imports
10 |
11 | import sys
12 | import time
13 | import datetime
14 | import random
15 | import SDL_Pi_TCA9545
16 | import subprocess
17 |
18 |
19 |
20 | #/*=========================================================================
21 | # I2C ADDRESS/BITS
22 | # -----------------------------------------------------------------------*/
23 | TCA9545_ADDRESS = (0x73) # 1110011 (A0+A1=VDD)
24 | #/*=========================================================================*/
25 |
26 | #/*=========================================================================
27 | # CONFIG REGISTER (R/W)
28 | # -----------------------------------------------------------------------*/
29 | TCA9545_REG_CONFIG = (0x00)
30 | # /*---------------------------------------------------------------------*/
31 |
32 | TCA9545_CONFIG_BUS0 = (0x01) # 1 = enable, 0 = disable
33 | TCA9545_CONFIG_BUS1 = (0x02) # 1 = enable, 0 = disable
34 | TCA9545_CONFIG_BUS2 = (0x04) # 1 = enable, 0 = disable
35 | TCA9545_CONFIG_BUS3 = (0x08) # 1 = enable, 0 = disable
36 |
37 | #/*=========================================================================*/
38 |
39 | # Main Program
40 |
41 | print ""
42 | print "Test SDL_Pi_TCA9545 Version 1.0 - SwitchDoc Labs"
43 | print ""
44 | print "Sample uses 0x73"
45 | print "Program Started at:"+ time.strftime("%Y-%m-%d %H:%M:%S")
46 | print ""
47 |
48 | filename = time.strftime("%Y-%m-%d%H:%M:%SRTCTest") + ".txt"
49 | starttime = datetime.datetime.utcnow()
50 |
51 | tca9545 = SDL_Pi_TCA9545.SDL_Pi_TCA9545(addr=TCA9545_ADDRESS, bus_enable = TCA9545_CONFIG_BUS0)
52 |
53 | # rotates through all 4 I2C buses and prints out what is available on each
54 |
55 | while True:
56 | print "-----------BUS 0-------------------"
57 |
58 | tca9545.write_control_register(TCA9545_CONFIG_BUS0)
59 | # read the control register back
60 | control_register = tca9545.read_control_register()
61 | print "tca9545 control register B3-B0 = 0x%x"% (control_register & 0x0f )
62 | print "ignore Interrupts if INT3' - INT0' not connected"
63 | print "tca9545 control register Interrupts = 0x%x"% ((control_register & 0xf0) >> 4)
64 |
65 | i2ccommand = "sudo i2cdetect -y 1"
66 | output = subprocess.check_output (i2ccommand,shell=True, stderr=subprocess.STDOUT )
67 | print output
68 |
69 | print "-----------------------------------"
70 | print
71 | time.sleep(5.0)
72 |
73 | print "-----------BUS 1-------------------"
74 |
75 | tca9545.write_control_register(TCA9545_CONFIG_BUS1)
76 | # read the control register back
77 | control_register = tca9545.read_control_register()
78 | print "tca9545 control register B3-B0 = 0x%x"% (control_register & 0x0f )
79 | print "ignore Interrupts if INT3' - INT0' not connected"
80 | print "tca9545 control register Interrupts = 0x%x"% ((control_register & 0xf0) >> 4)
81 |
82 | i2ccommand = "sudo i2cdetect -y 1"
83 | output = subprocess.check_output (i2ccommand,shell=True, stderr=subprocess.STDOUT )
84 | print output
85 |
86 | print "-----------------------------------"
87 | print
88 | time.sleep(5.0)
89 |
90 | print "-----------BUS 2-------------------"
91 |
92 | tca9545.write_control_register(TCA9545_CONFIG_BUS2)
93 | # read the control register back
94 | control_register = tca9545.read_control_register()
95 | print "tca9545 control register B3-B0 = 0x%x"% (control_register & 0x0f )
96 | print "ignore Interrupts if INT3' - INT0' not connected"
97 | print "tca9545 control register Interrupts = 0x%x"% ((control_register & 0xf0) >> 4)
98 |
99 | i2ccommand = "sudo i2cdetect -y 1"
100 | output = subprocess.check_output (i2ccommand,shell=True, stderr=subprocess.STDOUT )
101 | print output
102 |
103 | print "-----------------------------------"
104 | print
105 | time.sleep(5.0)
106 |
107 | print "-----------BUS 3-------------------"
108 |
109 | tca9545.write_control_register(TCA9545_CONFIG_BUS3)
110 | # read the control register back
111 | control_register = tca9545.read_control_register()
112 | print "tca9545 control register B3-B0 = 0x%x"% (control_register & 0x0f )
113 | print "ignore Interrupts if INT3' - INT0' not connected"
114 | print "tca9545 control register Interrupts = 0x%x"% ((control_register & 0xf0) >> 4)
115 |
116 | i2ccommand = "sudo i2cdetect -y 1"
117 | output = subprocess.check_output (i2ccommand,shell=True, stderr=subprocess.STDOUT )
118 | print output
119 |
120 | print "-----------------------------------"
121 | print
122 | time.sleep(5.0)
123 |
124 |
--------------------------------------------------------------------------------
/SDL_Pi_SSD1306/SDL_shapes.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2014 Adafruit Industries
2 | # Author: Tony DiCola
3 | #
4 | # Permission is hereby granted, free of charge, to any person obtaining a copy
5 | # of this software and associated documentation files (the "Software"), to deal
6 | # in the Software without restriction, including without limitation the rights
7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | # copies of the Software, and to permit persons to whom the Software is
9 | # furnished to do so, subject to the following conditions:
10 | #
11 | # The above copyright notice and this permission notice shall be included in
12 | # all copies or substantial portions of the Software.
13 | #
14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | # THE SOFTWARE.
21 | import time
22 |
23 | import Adafruit_GPIO.SPI as SPI
24 | import Adafruit_SSD1306
25 |
26 | import Image
27 | import ImageDraw
28 | import ImageFont
29 |
30 |
31 | # Raspberry Pi pin configuration:
32 | RST = 24
33 | # Note the following are only used with SPI:
34 | DC = 23
35 | SPI_PORT = 0
36 | SPI_DEVICE = 0
37 |
38 | # Beaglebone Black pin configuration:
39 | # RST = 'P9_12'
40 | # Note the following are only used with SPI:
41 | # DC = 'P9_15'
42 | # SPI_PORT = 1
43 | # SPI_DEVICE = 0
44 |
45 | # 128x32 display with hardware I2C:
46 | # disp = Adafruit_SSD1306.SSD1306_128_32(rst=RST)
47 |
48 | # 128x64 display with hardware I2C:
49 | #disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST)
50 |
51 | # Note you can change the I2C address by passing an i2c_address parameter like:
52 | disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST, i2c_address=0x3C)
53 |
54 | # Alternatively you can specify an explicit I2C bus number, for example
55 | # with the 128x32 display you would use:
56 | # disp = Adafruit_SSD1306.SSD1306_128_32(rst=RST, i2c_bus=2)
57 |
58 | # 128x32 display with hardware SPI:
59 | # disp = Adafruit_SSD1306.SSD1306_128_32(rst=RST, dc=DC, spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE, max_speed_hz=8000000))
60 |
61 | # 128x64 display with hardware SPI:
62 | # disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST, dc=DC, spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE, max_speed_hz=8000000))
63 |
64 | # Alternatively you can specify a software SPI implementation by providing
65 | # digital GPIO pin numbers for all the required display pins. For example
66 | # on a Raspberry Pi with the 128x32 display you might use:
67 | # disp = Adafruit_SSD1306.SSD1306_128_32(rst=RST, dc=DC, sclk=18, din=25, cs=22)
68 |
69 | # Initialize library.
70 | disp.begin()
71 |
72 | # Clear display.
73 | disp.clear()
74 | disp.display()
75 |
76 | # Create blank image for drawing.
77 | # Make sure to create image with mode '1' for 1-bit color.
78 | width = disp.width
79 | height = disp.height
80 | image = Image.new('1', (width, height))
81 |
82 | # Get drawing object to draw on image.
83 | draw = ImageDraw.Draw(image)
84 |
85 | # Draw a black filled box to clear the image.
86 | draw.rectangle((0,0,width,height), outline=0, fill=0)
87 |
88 | # Draw some shapes.
89 | # First define some constants to allow easy resizing of shapes.
90 | padding = 2
91 | shape_width = 20
92 | top = padding
93 | bottom = height-padding
94 | # Move left to right keeping track of the current x position for drawing shapes.
95 | x = padding
96 | # Draw an ellipse.
97 | draw.ellipse((x, top , x+shape_width, bottom), outline=255, fill=0)
98 | x += shape_width+padding
99 | # Draw a rectangle.
100 | draw.rectangle((x, top, x+shape_width, bottom), outline=255, fill=0)
101 | x += shape_width+padding
102 | # Draw a triangle.
103 | draw.polygon([(x, bottom), (x+shape_width/2, top), (x+shape_width, bottom)], outline=255, fill=0)
104 | x += shape_width+padding
105 | # Draw an X.
106 | draw.line((x, bottom, x+shape_width, top), fill=255)
107 | draw.line((x, top, x+shape_width, bottom), fill=255)
108 | x += shape_width+padding
109 |
110 | # Load default font.
111 | font = ImageFont.load_default()
112 |
113 | # Alternatively load a TTF font. Make sure the .ttf font file is in the same directory as the python script!
114 | # Some other nice fonts to try: http://www.dafont.com/bitmap.php
115 | #font = ImageFont.truetype('Minecraftia.ttf', 8)
116 |
117 | # Write two lines of text.
118 | draw.text((x, top), 'Hello', font=font, fill=255)
119 | draw.text((x, top+20), 'World!', font=font, fill=255)
120 |
121 | # Display image.
122 | disp.image(image)
123 | disp.display()
124 |
--------------------------------------------------------------------------------
/Adafruit_Python_SSD1306/examples/shapes.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2014 Adafruit Industries
2 | # Author: Tony DiCola
3 | #
4 | # Permission is hereby granted, free of charge, to any person obtaining a copy
5 | # of this software and associated documentation files (the "Software"), to deal
6 | # in the Software without restriction, including without limitation the rights
7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | # copies of the Software, and to permit persons to whom the Software is
9 | # furnished to do so, subject to the following conditions:
10 | #
11 | # The above copyright notice and this permission notice shall be included in
12 | # all copies or substantial portions of the Software.
13 | #
14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | # THE SOFTWARE.
21 | import time
22 |
23 | import Adafruit_GPIO.SPI as SPI
24 | import Adafruit_SSD1306
25 |
26 | from PIL import Image
27 | from PIL import ImageDraw
28 | from PIL import ImageFont
29 |
30 |
31 | # Raspberry Pi pin configuration:
32 | RST = 24
33 | # Note the following are only used with SPI:
34 | DC = 23
35 | SPI_PORT = 0
36 | SPI_DEVICE = 0
37 |
38 | # Beaglebone Black pin configuration:
39 | # RST = 'P9_12'
40 | # Note the following are only used with SPI:
41 | # DC = 'P9_15'
42 | # SPI_PORT = 1
43 | # SPI_DEVICE = 0
44 |
45 | # 128x32 display with hardware I2C:
46 | disp = Adafruit_SSD1306.SSD1306_128_32(rst=RST)
47 |
48 | # 128x64 display with hardware I2C:
49 | # disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST)
50 |
51 | # Note you can change the I2C address by passing an i2c_address parameter like:
52 | # disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST, i2c_address=0x3C)
53 |
54 | # Alternatively you can specify an explicit I2C bus number, for example
55 | # with the 128x32 display you would use:
56 | # disp = Adafruit_SSD1306.SSD1306_128_32(rst=RST, i2c_bus=2)
57 |
58 | # 128x32 display with hardware SPI:
59 | # disp = Adafruit_SSD1306.SSD1306_128_32(rst=RST, dc=DC, spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE, max_speed_hz=8000000))
60 |
61 | # 128x64 display with hardware SPI:
62 | # disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST, dc=DC, spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE, max_speed_hz=8000000))
63 |
64 | # Alternatively you can specify a software SPI implementation by providing
65 | # digital GPIO pin numbers for all the required display pins. For example
66 | # on a Raspberry Pi with the 128x32 display you might use:
67 | # disp = Adafruit_SSD1306.SSD1306_128_32(rst=RST, dc=DC, sclk=18, din=25, cs=22)
68 |
69 | # Initialize library.
70 | disp.begin()
71 |
72 | # Clear display.
73 | disp.clear()
74 | disp.display()
75 |
76 | # Create blank image for drawing.
77 | # Make sure to create image with mode '1' for 1-bit color.
78 | width = disp.width
79 | height = disp.height
80 | image = Image.new('1', (width, height))
81 |
82 | # Get drawing object to draw on image.
83 | draw = ImageDraw.Draw(image)
84 |
85 | # Draw a black filled box to clear the image.
86 | draw.rectangle((0,0,width,height), outline=0, fill=0)
87 |
88 | # Draw some shapes.
89 | # First define some constants to allow easy resizing of shapes.
90 | padding = 2
91 | shape_width = 20
92 | top = padding
93 | bottom = height-padding
94 | # Move left to right keeping track of the current x position for drawing shapes.
95 | x = padding
96 | # Draw an ellipse.
97 | draw.ellipse((x, top , x+shape_width, bottom), outline=255, fill=0)
98 | x += shape_width+padding
99 | # Draw a rectangle.
100 | draw.rectangle((x, top, x+shape_width, bottom), outline=255, fill=0)
101 | x += shape_width+padding
102 | # Draw a triangle.
103 | draw.polygon([(x, bottom), (x+shape_width/2, top), (x+shape_width, bottom)], outline=255, fill=0)
104 | x += shape_width+padding
105 | # Draw an X.
106 | draw.line((x, bottom, x+shape_width, top), fill=255)
107 | draw.line((x, top, x+shape_width, bottom), fill=255)
108 | x += shape_width+padding
109 |
110 | # Load default font.
111 | font = ImageFont.load_default()
112 |
113 | # Alternatively load a TTF font. Make sure the .ttf font file is in the same directory as the python script!
114 | # Some other nice fonts to try: http://www.dafont.com/bitmap.php
115 | #font = ImageFont.truetype('Minecraftia.ttf', 8)
116 |
117 | # Write two lines of text.
118 | draw.text((x, top), 'Hello', font=font, fill=255)
119 | draw.text((x, top+20), 'World!', font=font, fill=255)
120 |
121 | # Display image.
122 | disp.image(image)
123 | disp.display()
124 |
--------------------------------------------------------------------------------
/SDL_Pi_SSD1306/SDL_animate.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2014 Adafruit Industries
2 | # Author: Tony DiCola
3 | #
4 | # Permission is hereby granted, free of charge, to any person obtaining a copy
5 | # of this software and associated documentation files (the "Software"), to deal
6 | # in the Software without restriction, including without limitation the rights
7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | # copies of the Software, and to permit persons to whom the Software is
9 | # furnished to do so, subject to the following conditions:
10 | #
11 | # The above copyright notice and this permission notice shall be included in
12 | # all copies or substantial portions of the Software.
13 | #
14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | # THE SOFTWARE.
21 | import math
22 | import time
23 |
24 | import Adafruit_GPIO.SPI as SPI
25 | import Adafruit_SSD1306
26 |
27 | import Image
28 | import ImageFont
29 | import ImageDraw
30 |
31 |
32 | # Raspberry Pi pin configuration:
33 | RST = 24
34 | # Note the following are only used with SPI:
35 | DC = 23
36 | SPI_PORT = 0
37 | SPI_DEVICE = 0
38 |
39 | # Beaglebone Black pin configuration:
40 | # RST = 'P9_12'
41 | # Note the following are only used with SPI:
42 | # DC = 'P9_15'
43 | # SPI_PORT = 1
44 | # SPI_DEVICE = 0
45 |
46 | # 128x32 display with hardware I2C:
47 | disp = Adafruit_SSD1306.SSD1306_128_32(rst=RST)
48 |
49 | # 128x64 display with hardware I2C:
50 | #disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST)
51 |
52 |
53 | # Note you can change the I2C address by passing an i2c_address parameter like:
54 | disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST, i2c_address=0x3C)
55 |
56 | # 128x32 display with hardware SPI:
57 | # disp = Adafruit_SSD1306.SSD1306_128_32(rst=RST, dc=DC, spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE, max_speed_hz=8000000))
58 |
59 | # 128x64 display with hardware SPI:
60 | # disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST, dc=DC, spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE, max_speed_hz=8000000))
61 |
62 | # Initialize library.
63 | disp.begin()
64 |
65 | # Get display width and height.
66 | width = disp.width
67 | height = disp.height
68 |
69 | # Clear display.
70 | disp.clear()
71 | disp.display()
72 |
73 | # Create image buffer.
74 | # Make sure to create image with mode '1' for 1-bit color.
75 | image = Image.new('1', (width, height))
76 |
77 | # Load default font.
78 | font = ImageFont.load_default()
79 |
80 | # Alternatively load a TTF font. Make sure the .ttf font file is in the same directory as this python script!
81 | # Some nice fonts to try: http://www.dafont.com/bitmap.php
82 | # font = ImageFont.truetype('Minecraftia.ttf', 8)
83 |
84 | # Create drawing object.
85 | draw = ImageDraw.Draw(image)
86 |
87 | # Define text and get total width.
88 | text = 'SSD1306 ORGANIC LED DISPLAY. THIS IS AN OLD SCHOOL DEMO SCROLLER!! GREETZ TO: LADYADA & THE ADAFRUIT CREW, TRIXTER, FUTURE CREW, AND FARBRAUSCH'
89 | maxwidth, unused = draw.textsize(text, font=font)
90 |
91 | # Set animation and sine wave parameters.
92 | amplitude = height/4
93 | offset = height/2 - 4
94 | velocity = -2
95 | startpos = width
96 |
97 | # Animate text moving in sine wave.
98 | print 'Press Ctrl-C to quit.'
99 | pos = startpos
100 | while True:
101 | # Clear image buffer by drawing a black filled box.
102 | draw.rectangle((0,0,width,height), outline=0, fill=0)
103 | # Enumerate characters and draw them offset vertically based on a sine wave.
104 | x = pos
105 | for i, c in enumerate(text):
106 | # Stop drawing if off the right side of screen.
107 | if x > width:
108 | break
109 | # Calculate width but skip drawing if off the left side of screen.
110 | if x < -10:
111 | char_width, char_height = draw.textsize(c, font=font)
112 | x += char_width
113 | continue
114 | # Calculate offset from sine wave.
115 | y = offset+math.floor(amplitude*math.sin(x/float(width)*2.0*math.pi))
116 | # Draw text.
117 | draw.text((x, y), c, font=font, fill=255)
118 | # Increment x position based on chacacter width.
119 | char_width, char_height = draw.textsize(c, font=font)
120 | x += char_width
121 | # Draw the image buffer.
122 | disp.image(image)
123 | disp.display()
124 | # Move position for next frame.
125 | pos += velocity
126 | # Start over if text has scrolled completely off left side of screen.
127 | if pos < -maxwidth:
128 | pos = startpos
129 | # Pause briefly before drawing next frame.
130 | time.sleep(0.1)
131 |
--------------------------------------------------------------------------------
/Adafruit_Python_SSD1306/examples/animate.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2014 Adafruit Industries
2 | # Author: Tony DiCola
3 | #
4 | # Permission is hereby granted, free of charge, to any person obtaining a copy
5 | # of this software and associated documentation files (the "Software"), to deal
6 | # in the Software without restriction, including without limitation the rights
7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | # copies of the Software, and to permit persons to whom the Software is
9 | # furnished to do so, subject to the following conditions:
10 | #
11 | # The above copyright notice and this permission notice shall be included in
12 | # all copies or substantial portions of the Software.
13 | #
14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | # THE SOFTWARE.
21 | import math
22 | import time
23 |
24 | import Adafruit_GPIO.SPI as SPI
25 | import Adafruit_SSD1306
26 |
27 | from PIL import Image
28 | from PIL import ImageFont
29 | from PIL import ImageDraw
30 |
31 |
32 | # Raspberry Pi pin configuration:
33 | RST = 24
34 | # Note the following are only used with SPI:
35 | DC = 23
36 | SPI_PORT = 0
37 | SPI_DEVICE = 0
38 |
39 | # Beaglebone Black pin configuration:
40 | # RST = 'P9_12'
41 | # Note the following are only used with SPI:
42 | # DC = 'P9_15'
43 | # SPI_PORT = 1
44 | # SPI_DEVICE = 0
45 |
46 | # 128x32 display with hardware I2C:
47 | disp = Adafruit_SSD1306.SSD1306_128_32(rst=RST)
48 |
49 | # 128x64 display with hardware I2C:
50 | # disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST)
51 |
52 | # 128x32 display with hardware SPI:
53 | # disp = Adafruit_SSD1306.SSD1306_128_32(rst=RST, dc=DC, spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE, max_speed_hz=8000000))
54 |
55 | # 128x64 display with hardware SPI:
56 | # disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST, dc=DC, spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE, max_speed_hz=8000000))
57 |
58 | # Initialize library.
59 | disp.begin()
60 |
61 | # Get display width and height.
62 | width = disp.width
63 | height = disp.height
64 |
65 | # Clear display.
66 | disp.clear()
67 | disp.display()
68 |
69 | # Create image buffer.
70 | # Make sure to create image with mode '1' for 1-bit color.
71 | image = Image.new('1', (width, height))
72 |
73 | # Load default font.
74 | font = ImageFont.load_default()
75 |
76 | # Alternatively load a TTF font. Make sure the .ttf font file is in the same directory as this python script!
77 | # Some nice fonts to try: http://www.dafont.com/bitmap.php
78 | # font = ImageFont.truetype('Minecraftia.ttf', 8)
79 |
80 | # Create drawing object.
81 | draw = ImageDraw.Draw(image)
82 |
83 | # Define text and get total width.
84 | text = 'SSD1306 ORGANIC LED DISPLAY. THIS IS AN OLD SCHOOL DEMO SCROLLER!! GREETZ TO: LADYADA & THE ADAFRUIT CREW, TRIXTER, FUTURE CREW, AND FARBRAUSCH'
85 | maxwidth, unused = draw.textsize(text, font=font)
86 |
87 | # Set animation and sine wave parameters.
88 | amplitude = height/4
89 | offset = height/2 - 4
90 | velocity = -2
91 | startpos = width
92 |
93 | # Animate text moving in sine wave.
94 | print('Press Ctrl-C to quit.')
95 | pos = startpos
96 | while True:
97 | # Clear image buffer by drawing a black filled box.
98 | draw.rectangle((0,0,width,height), outline=0, fill=0)
99 | # Enumerate characters and draw them offset vertically based on a sine wave.
100 | x = pos
101 | for i, c in enumerate(text):
102 | # Stop drawing if off the right side of screen.
103 | if x > width:
104 | break
105 | # Calculate width but skip drawing if off the left side of screen.
106 | if x < -10:
107 | char_width, char_height = draw.textsize(c, font=font)
108 | x += char_width
109 | continue
110 | # Calculate offset from sine wave.
111 | y = offset+math.floor(amplitude*math.sin(x/float(width)*2.0*math.pi))
112 | # Draw text.
113 | draw.text((x, y), c, font=font, fill=255)
114 | # Increment x position based on chacacter width.
115 | char_width, char_height = draw.textsize(c, font=font)
116 | x += char_width
117 | # Draw the image buffer.
118 | disp.image(image)
119 | disp.display()
120 | # Move position for next frame.
121 | pos += velocity
122 | # Start over if text has scrolled completely off left side of screen.
123 | if pos < -maxwidth:
124 | pos = startpos
125 | # Pause briefly before drawing next frame.
126 | time.sleep(0.1)
127 |
--------------------------------------------------------------------------------
/state.py:
--------------------------------------------------------------------------------
1 | #
2 | # Contains updated State Variables for Blynk and Sections
3 | #
4 | #
5 |
6 | # Weather Variables
7 |
8 | currentOutsideTemperature = 2.0
9 | currentOutsideHumidity = 2
10 |
11 | currentInsideTemperature = 1.0
12 | currentInsideHumidity = 4
13 |
14 | currentRain60Minutes = 0.1
15 |
16 | currentSunlightVisible = 1
17 | currentSunlightIR = 2
18 | currentSunlightUV = 3
19 | currentSunlightUVIndex = 4
20 |
21 | ScurrentWindSpeed = 6
22 | ScurrentWindGust = 7
23 | ScurrentWindDirection = 7.5
24 | currentTotalRain = 8
25 |
26 | currentBarometricPressure = 9
27 | currentAltitude = 10
28 | currentSeaLevel = 10
29 | barometricTrend = True
30 | pastBarometricReading = 9
31 |
32 | AirQuality_Sensor_Value = 101
33 |
34 |
35 |
36 |
37 | # Lightning Values
38 |
39 | currentAs3935Interrupt = 11
40 |
41 | currentAs3935LastInterrupt = 12
42 | currentAs3935LastDistance = 13
43 | currentAs3935LastStatus = 14
44 |
45 | currentAs3935LastLightningTimeStamp = 0
46 |
47 | # Button Variables
48 |
49 | runRainbow = False
50 | flashStrip = False
51 | runOLED = True
52 |
53 |
54 |
55 | # status Values
56 |
57 | Last_Event = "My Last Event"
58 | EnglishMetric = 0
59 |
60 |
61 | # Solar Values
62 |
63 |
64 | batteryVoltage = 0
65 | batteryCurrent = 0
66 | solarVoltage = 0
67 | solarCurrent = 0
68 | loadVoltage = 0
69 | loadCurrent = 0
70 | batteryPower = 0
71 | solarPower = 0
72 | loadPower = 0
73 | batteryCharge = 0
74 |
75 | # WXLink Values
76 | WXbatteryVoltage = 0
77 | WXbatteryCurrent = 0
78 | WXsolarVoltage = 0
79 | WXsolarCurrent = 0
80 | WXloadVoltage = 0
81 | WXloadCurrent = 0
82 | WXbatteryPower = 0
83 | WXsolarPower = 0
84 | WXloadPower = 0
85 | WXbatteryCharge = 0
86 |
87 |
88 |
89 |
90 | def printState():
91 |
92 | print "-------------"
93 | print "Current State"
94 | print "-------------"
95 | print"currentOutsideTemperature = ",currentOutsideTemperature
96 | print"currentOutsideHumidity = ", currentOutsideHumidity
97 |
98 | print"currentInsideTemperature = ",currentInsideTemperature
99 | print"currentInsideHumidity = ", currentInsideHumidity
100 |
101 | print"currentRain60Minutes = ", currentRain60Minutes
102 |
103 | print"currentSunlightVisible = ", currentSunlightVisible
104 | print"currentSunlightIR = ", currentSunlightIR
105 | print"currentSunlightUV = ", currentSunlightUV
106 | print"currentSunlightUVIndex = ", currentSunlightUVIndex
107 |
108 | print"ScurrentWindSpeed = ", ScurrentWindSpeed
109 | print"ScurrentWindGust = ", ScurrentWindGust
110 | print"ScurrentWindDirection = ", ScurrentWindDirection
111 | print"currentTotalRain = ", currentTotalRain
112 |
113 | print "currentBarometricPressure = ", currentBarometricPressure
114 | print "currentAltitude = ", currentAltitude
115 | print "currentSeaLevel = ", currentSeaLevel
116 | print "barometricTrend =",barometricTrend
117 | print "pastBarometricReading = ", pastBarometricReading
118 |
119 | print "AirQuality_Sensor_Value = ", AirQuality_Sensor_Value
120 |
121 | print "-------------"
122 |
123 |
124 | print "currentAs3935Interrupt = ", currentAs3935Interrupt
125 |
126 | print "currentAs3935LastInterrupt = ", currentAs3935LastInterrupt
127 | print "currentAs3935LastDistance = ", currentAs3935LastDistance
128 | print "currentAs3935LastStatus = ", currentAs3935LastStatus
129 |
130 | print "currentAs3935LastLightningTimeStamp = ", currentAs3935LastLightningTimeStamp
131 |
132 |
133 |
134 | print "-------------"
135 |
136 |
137 | print "runRainbow = ", runRainbow
138 | print "flashStrip = ", flashStrip
139 | print "runOLED =", runOLED
140 | print "-------------"
141 |
142 |
143 |
144 | print "Last_Event = ", Last_Event
145 | print "EnglishMetric = ", EnglishMetric
146 |
147 |
148 | print "-------------"
149 |
150 | print "batteryVoltage", batteryVoltage
151 | print "batteryCurrent", batteryCurrent
152 | print "solarVoltage", solarVoltage
153 | print "solarCurrent", solarCurrent
154 | print "loadVoltage", loadVoltage
155 | print "loadCurrent", loadCurrent
156 | print "batteryPower", batteryPower
157 | print "solarPower", solarPower
158 | print "loadPower", loadPower
159 | print "batteryCharge", batteryCharge
160 |
161 | print "-------------"
162 |
163 | print "-------------"
164 |
165 | print "WXbatteryVoltage", WXbatteryVoltage
166 | print "WXbatteryCurrent", WXbatteryCurrent
167 | print "WXsolarVoltage", WXsolarVoltage
168 | print "WXsolarCurrent", WXsolarCurrent
169 | print "WXloadVoltage", WXloadVoltage
170 | print "WXloadCurrent", WXloadCurrent
171 | print "WXbatteryPower", WXbatteryPower
172 | print "WXsolarPower", WXsolarPower
173 | print "WXloadPower", WXloadPower
174 | print "WXbatteryCharge", WXbatteryCharge
175 |
176 | print "-------------"
177 |
178 |
179 |
--------------------------------------------------------------------------------
/Adafruit_I2C/Adafruit_I2C.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | import re
3 | import smbus
4 |
5 | # ===========================================================================
6 | # Adafruit_I2C Class
7 | # ===========================================================================
8 |
9 | class Adafruit_I2C(object):
10 |
11 | @staticmethod
12 | def getPiRevision():
13 | "Gets the version number of the Raspberry Pi board"
14 | # Revision list available at: http://elinux.org/RPi_HardwareHistory#Board_Revision_History
15 | try:
16 | with open('/proc/cpuinfo', 'r') as infile:
17 | for line in infile:
18 | # Match a line of the form "Revision : 0002" while ignoring extra
19 | # info in front of the revsion (like 1000 when the Pi was over-volted).
20 | match = re.match('Revision\s+:\s+.*(\w{4})$', line)
21 | if match and match.group(1) in ['0000', '0002', '0003']:
22 | # Return revision 1 if revision ends with 0000, 0002 or 0003.
23 | return 1
24 | elif match:
25 | # Assume revision 2 if revision ends with any other 4 chars.
26 | return 2
27 | # Couldn't find the revision, assume revision 0 like older code for compatibility.
28 | return 0
29 | except:
30 | return 0
31 |
32 | @staticmethod
33 | def getPiI2CBusNumber():
34 | # Gets the I2C bus number /dev/i2c#
35 | return 1 if Adafruit_I2C.getPiRevision() > 1 else 0
36 |
37 | def __init__(self, address, busnum=-1, debug=False):
38 | self.address = address
39 | # By default, the correct I2C bus is auto-detected using /proc/cpuinfo
40 | # Alternatively, you can hard-code the bus version below:
41 | # self.bus = smbus.SMBus(0); # Force I2C0 (early 256MB Pi's)
42 | # self.bus = smbus.SMBus(1); # Force I2C1 (512MB Pi's)
43 | self.bus = smbus.SMBus(busnum if busnum >= 0 else Adafruit_I2C.getPiI2CBusNumber())
44 | self.debug = debug
45 |
46 | def reverseByteOrder(self, data):
47 | "Reverses the byte order of an int (16-bit) or long (32-bit) value"
48 | # Courtesy Vishal Sapre
49 | byteCount = len(hex(data)[2:].replace('L','')[::2])
50 | val = 0
51 | for i in range(byteCount):
52 | val = (val << 8) | (data & 0xff)
53 | data >>= 8
54 | return val
55 |
56 | def errMsg(self):
57 | print "Error accessing 0x%02X: Check your I2C address" % self.address
58 | return -1
59 |
60 | def write8(self, reg, value):
61 | "Writes an 8-bit value to the specified register/address"
62 | try:
63 | self.bus.write_byte_data(self.address, reg, value)
64 | if self.debug:
65 | print "I2C: Wrote 0x%02X to register 0x%02X" % (value, reg)
66 | except IOError, err:
67 | return self.errMsg()
68 |
69 | def write16(self, reg, value):
70 | "Writes a 16-bit value to the specified register/address pair"
71 | try:
72 | self.bus.write_word_data(self.address, reg, value)
73 | if self.debug:
74 | print ("I2C: Wrote 0x%02X to register pair 0x%02X,0x%02X" %
75 | (value, reg, reg+1))
76 | except IOError, err:
77 | return self.errMsg()
78 |
79 | def writeRaw8(self, value):
80 | "Writes an 8-bit value on the bus"
81 | try:
82 | self.bus.write_byte(self.address, value)
83 | if self.debug:
84 | print "I2C: Wrote 0x%02X" % value
85 | except IOError, err:
86 | return self.errMsg()
87 |
88 | def writeList(self, reg, list):
89 | "Writes an array of bytes using I2C format"
90 | try:
91 | if self.debug:
92 | print "I2C: Writing list to register 0x%02X:" % reg
93 | print list
94 | self.bus.write_i2c_block_data(self.address, reg, list)
95 | except IOError, err:
96 | return self.errMsg()
97 |
98 | def readList(self, reg, length):
99 | "Read a list of bytes from the I2C device"
100 | try:
101 | results = self.bus.read_i2c_block_data(self.address, reg, length)
102 | if self.debug:
103 | print ("I2C: Device 0x%02X returned the following from reg 0x%02X" %
104 | (self.address, reg))
105 | print results
106 | return results
107 | except IOError, err:
108 | return self.errMsg()
109 |
110 | def readU8(self, reg):
111 | "Read an unsigned byte from the I2C device"
112 | try:
113 | result = self.bus.read_byte_data(self.address, reg)
114 | if self.debug:
115 | print ("I2C: Device 0x%02X returned 0x%02X from reg 0x%02X" %
116 | (self.address, result & 0xFF, reg))
117 | return result
118 | except IOError, err:
119 | return self.errMsg()
120 |
121 | def readS8(self, reg):
122 | "Reads a signed byte from the I2C device"
123 | try:
124 | result = self.bus.read_byte_data(self.address, reg)
125 | if result > 127: result -= 256
126 | if self.debug:
127 | print ("I2C: Device 0x%02X returned 0x%02X from reg 0x%02X" %
128 | (self.address, result & 0xFF, reg))
129 | return result
130 | except IOError, err:
131 | return self.errMsg()
132 |
133 | def readU16(self, reg, little_endian=True):
134 | "Reads an unsigned 16-bit value from the I2C device"
135 | try:
136 | result = self.bus.read_word_data(self.address,reg)
137 | # Swap bytes if using big endian because read_word_data assumes little
138 | # endian on ARM (little endian) systems.
139 | if not little_endian:
140 | result = ((result << 8) & 0xFF00) + (result >> 8)
141 | if (self.debug):
142 | print "I2C: Device 0x%02X returned 0x%04X from reg 0x%02X" % (self.address, result & 0xFFFF, reg)
143 | return result
144 | except IOError, err:
145 | return self.errMsg()
146 |
147 | def readS16(self, reg, little_endian=True):
148 | "Reads a signed 16-bit value from the I2C device"
149 | try:
150 | result = self.readU16(reg,little_endian)
151 | if result > 32767: result -= 65536
152 | return result
153 | except IOError, err:
154 | return self.errMsg()
155 |
156 | if __name__ == '__main__':
157 | try:
158 | bus = Adafruit_I2C(address=0)
159 | print "Default I2C bus is accessible"
160 | except:
161 | print "Error accessing default I2C bus"
162 |
--------------------------------------------------------------------------------
/SDL_Adafruit_ADS1x15/Adafruit_I2C.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | import re
3 | import smbus
4 |
5 | # ===========================================================================
6 | # Adafruit_I2C Class
7 | # ===========================================================================
8 |
9 | class Adafruit_I2C(object):
10 |
11 | @staticmethod
12 | def getPiRevision():
13 | "Gets the version number of the Raspberry Pi board"
14 | # Revision list available at: http://elinux.org/RPi_HardwareHistory#Board_Revision_History
15 | try:
16 | with open('/proc/cpuinfo', 'r') as infile:
17 | for line in infile:
18 | # Match a line of the form "Revision : 0002" while ignoring extra
19 | # info in front of the revsion (like 1000 when the Pi was over-volted).
20 | match = re.match('Revision\s+:\s+.*(\w{4})$', line)
21 | if match and match.group(1) in ['0000', '0002', '0003']:
22 | # Return revision 1 if revision ends with 0000, 0002 or 0003.
23 | return 1
24 | elif match:
25 | # Assume revision 2 if revision ends with any other 4 chars.
26 | return 2
27 | # Couldn't find the revision, assume revision 0 like older code for compatibility.
28 | return 0
29 | except:
30 | return 0
31 |
32 | @staticmethod
33 | def getPiI2CBusNumber():
34 | # Gets the I2C bus number /dev/i2c#
35 | return 1 if Adafruit_I2C.getPiRevision() > 1 else 0
36 |
37 | def __init__(self, address, busnum=-1, debug=False):
38 | self.address = address
39 | # By default, the correct I2C bus is auto-detected using /proc/cpuinfo
40 | # Alternatively, you can hard-code the bus version below:
41 | # self.bus = smbus.SMBus(0); # Force I2C0 (early 256MB Pi's)
42 | # self.bus = smbus.SMBus(1); # Force I2C1 (512MB Pi's)
43 | self.bus = smbus.SMBus(busnum if busnum >= 0 else Adafruit_I2C.getPiI2CBusNumber())
44 | self.debug = debug
45 |
46 | def reverseByteOrder(self, data):
47 | "Reverses the byte order of an int (16-bit) or long (32-bit) value"
48 | # Courtesy Vishal Sapre
49 | byteCount = len(hex(data)[2:].replace('L','')[::2])
50 | val = 0
51 | for i in range(byteCount):
52 | val = (val << 8) | (data & 0xff)
53 | data >>= 8
54 | return val
55 |
56 | def errMsg(self):
57 | print "Error accessing 0x%02X: Check your I2C address" % self.address
58 | return -1
59 |
60 | def write8(self, reg, value):
61 | "Writes an 8-bit value to the specified register/address"
62 | try:
63 | self.bus.write_byte_data(self.address, reg, value)
64 | if self.debug:
65 | print "I2C: Wrote 0x%02X to register 0x%02X" % (value, reg)
66 | except IOError, err:
67 | return self.errMsg()
68 |
69 | def write16(self, reg, value):
70 | "Writes a 16-bit value to the specified register/address pair"
71 | try:
72 | self.bus.write_word_data(self.address, reg, value)
73 | if self.debug:
74 | print ("I2C: Wrote 0x%02X to register pair 0x%02X,0x%02X" %
75 | (value, reg, reg+1))
76 | except IOError, err:
77 | return self.errMsg()
78 |
79 | def writeRaw8(self, value):
80 | "Writes an 8-bit value on the bus"
81 | try:
82 | self.bus.write_byte(self.address, value)
83 | if self.debug:
84 | print "I2C: Wrote 0x%02X" % value
85 | except IOError, err:
86 | return self.errMsg()
87 |
88 | def writeList(self, reg, list):
89 | "Writes an array of bytes using I2C format"
90 | try:
91 | if self.debug:
92 | print "I2C: Writing list to register 0x%02X:" % reg
93 | print list
94 | self.bus.write_i2c_block_data(self.address, reg, list)
95 | except IOError, err:
96 | return self.errMsg()
97 |
98 | def readList(self, reg, length):
99 | "Read a list of bytes from the I2C device"
100 | try:
101 | results = self.bus.read_i2c_block_data(self.address, reg, length)
102 | if self.debug:
103 | print ("I2C: Device 0x%02X returned the following from reg 0x%02X" %
104 | (self.address, reg))
105 | print results
106 | return results
107 | except IOError, err:
108 | return self.errMsg()
109 |
110 | def readU8(self, reg):
111 | "Read an unsigned byte from the I2C device"
112 | try:
113 | result = self.bus.read_byte_data(self.address, reg)
114 | if self.debug:
115 | print ("I2C: Device 0x%02X returned 0x%02X from reg 0x%02X" %
116 | (self.address, result & 0xFF, reg))
117 | return result
118 | except IOError, err:
119 | return self.errMsg()
120 |
121 | def readS8(self, reg):
122 | "Reads a signed byte from the I2C device"
123 | try:
124 | result = self.bus.read_byte_data(self.address, reg)
125 | if result > 127: result -= 256
126 | if self.debug:
127 | print ("I2C: Device 0x%02X returned 0x%02X from reg 0x%02X" %
128 | (self.address, result & 0xFF, reg))
129 | return result
130 | except IOError, err:
131 | return self.errMsg()
132 |
133 | def readU16(self, reg, little_endian=True):
134 | "Reads an unsigned 16-bit value from the I2C device"
135 | try:
136 | result = self.bus.read_word_data(self.address,reg)
137 | # Swap bytes if using big endian because read_word_data assumes little
138 | # endian on ARM (little endian) systems.
139 | if not little_endian:
140 | result = ((result << 8) & 0xFF00) + (result >> 8)
141 | if (self.debug):
142 | print "I2C: Device 0x%02X returned 0x%04X from reg 0x%02X" % (self.address, result & 0xFFFF, reg)
143 | return result
144 | except IOError, err:
145 | return self.errMsg()
146 |
147 | def readS16(self, reg, little_endian=True):
148 | "Reads a signed 16-bit value from the I2C device"
149 | try:
150 | result = self.readU16(reg,little_endian)
151 | if result > 32767: result -= 65536
152 | return result
153 | except IOError, err:
154 | return self.errMsg()
155 |
156 | if __name__ == '__main__':
157 | try:
158 | bus = Adafruit_I2C(address=0)
159 | print "Default I2C bus is accessible"
160 | except:
161 | print "Error accessing default I2C bus"
162 |
--------------------------------------------------------------------------------
/Adafruit_Python_GPIO/Adafruit_GPIO/PWM.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2014 Adafruit Industries
2 | # Author: Tony DiCola
3 | #
4 | # Permission is hereby granted, free of charge, to any person obtaining a copy
5 | # of this software and associated documentation files (the "Software"), to deal
6 | # in the Software without restriction, including without limitation the rights
7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | # copies of the Software, and to permit persons to whom the Software is
9 | # furnished to do so, subject to the following conditions:
10 | #
11 | # The above copyright notice and this permission notice shall be included in
12 | # all copies or substantial portions of the Software.
13 | #
14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | # THE SOFTWARE.
21 | import Adafruit_GPIO.Platform as Platform
22 |
23 |
24 | class RPi_PWM_Adapter(object):
25 | """PWM implementation for the Raspberry Pi using the RPi.GPIO PWM library."""
26 |
27 | def __init__(self, rpi_gpio, mode=None):
28 | self.rpi_gpio = rpi_gpio
29 | # Suppress warnings about GPIO in use.
30 | rpi_gpio.setwarnings(False)
31 | # Set board or BCM pin numbering.
32 | if mode == rpi_gpio.BOARD or mode == rpi_gpio.BCM:
33 | rpi_gpio.setmode(mode)
34 | elif mode is not None:
35 | raise ValueError('Unexpected value for mode. Must be BOARD or BCM.')
36 | else:
37 | # Default to BCM numbering if not told otherwise.
38 | rpi_gpio.setmode(rpi_gpio.BCM)
39 | # Store reference to each created PWM instance.
40 | self.pwm = {}
41 |
42 | def start(self, pin, dutycycle, frequency_hz=2000):
43 | """Enable PWM output on specified pin. Set to intiial percent duty cycle
44 | value (0.0 to 100.0) and frequency (in Hz).
45 | """
46 | if dutycycle < 0.0 or dutycycle > 100.0:
47 | raise ValueError('Invalid duty cycle value, must be between 0.0 to 100.0 (inclusive).')
48 | # Make pin an output.
49 | self.rpi_gpio.setup(pin, self.rpi_gpio.OUT)
50 | # Create PWM instance and save a reference for later access.
51 | self.pwm[pin] = self.rpi_gpio.PWM(pin, frequency_hz)
52 | # Start the PWM at the specified duty cycle.
53 | self.pwm[pin].start(dutycycle)
54 |
55 | def set_duty_cycle(self, pin, dutycycle):
56 | """Set percent duty cycle of PWM output on specified pin. Duty cycle must
57 | be a value 0.0 to 100.0 (inclusive).
58 | """
59 | if dutycycle < 0.0 or dutycycle > 100.0:
60 | raise ValueError('Invalid duty cycle value, must be between 0.0 to 100.0 (inclusive).')
61 | if pin not in self.pwm:
62 | raise ValueError('Pin {0} is not configured as a PWM. Make sure to first call start for the pin.'.format(pin))
63 | self.pwm[pin].ChangeDutyCycle(dutycycle)
64 |
65 | def set_frequency(self, pin, frequency_hz):
66 | """Set frequency (in Hz) of PWM output on specified pin."""
67 | if pin not in self.pwm:
68 | raise ValueError('Pin {0} is not configured as a PWM. Make sure to first call start for the pin.'.format(pin))
69 | self.pwm[pin].ChangeFrequency(frequency_hz)
70 |
71 | def stop(self, pin):
72 | """Stop PWM output on specified pin."""
73 | if pin not in self.pwm:
74 | raise ValueError('Pin {0} is not configured as a PWM. Make sure to first call start for the pin.'.format(pin))
75 | self.pwm[pin].stop()
76 | del self.pwm[pin]
77 |
78 |
79 | class BBIO_PWM_Adapter(object):
80 | """PWM implementation for the BeagleBone Black using the Adafruit_BBIO.PWM
81 | library.
82 | """
83 |
84 | def __init__(self, bbio_pwm):
85 | self.bbio_pwm = bbio_pwm
86 |
87 | def start(self, pin, dutycycle, frequency_hz=2000):
88 | """Enable PWM output on specified pin. Set to intiial percent duty cycle
89 | value (0.0 to 100.0) and frequency (in Hz).
90 | """
91 | if dutycycle < 0.0 or dutycycle > 100.0:
92 | raise ValueError('Invalid duty cycle value, must be between 0.0 to 100.0 (inclusive).')
93 | self.bbio_pwm.start(pin, dutycycle, frequency_hz)
94 |
95 | def set_duty_cycle(self, pin, dutycycle):
96 | """Set percent duty cycle of PWM output on specified pin. Duty cycle must
97 | be a value 0.0 to 100.0 (inclusive).
98 | """
99 | if dutycycle < 0.0 or dutycycle > 100.0:
100 | raise ValueError('Invalid duty cycle value, must be between 0.0 to 100.0 (inclusive).')
101 | self.bbio_pwm.set_duty_cycle(pin, dutycycle)
102 |
103 | def set_frequency(self, pin, frequency_hz):
104 | """Set frequency (in Hz) of PWM output on specified pin."""
105 | self.bbio_pwm.set_frequency(pin, frequency_hz)
106 |
107 | def stop(self, pin):
108 | """Stop PWM output on specified pin."""
109 | self.bbio_pwm.stop(pin)
110 |
111 |
112 | def get_platform_pwm(**keywords):
113 | """Attempt to return a PWM instance for the platform which the code is being
114 | executed on. Currently supports only the Raspberry Pi using the RPi.GPIO
115 | library and Beaglebone Black using the Adafruit_BBIO library. Will throw an
116 | exception if a PWM instance can't be created for the current platform. The
117 | returned PWM object has the same interface as the RPi_PWM_Adapter and
118 | BBIO_PWM_Adapter classes.
119 | """
120 | plat = Platform.platform_detect()
121 | if plat == Platform.RASPBERRY_PI:
122 | import RPi.GPIO
123 | return RPi_PWM_Adapter(RPi.GPIO, **keywords)
124 | elif plat == Platform.BEAGLEBONE_BLACK:
125 | import Adafruit_BBIO.PWM
126 | return BBIO_PWM_Adapter(Adafruit_BBIO.PWM, **keywords)
127 | elif plat == Platform.UNKNOWN:
128 | raise RuntimeError('Could not determine platform.')
129 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | GroveWeatherPi Libraries and Example for Raspberry Pi Solar Powered Weather Station
2 |
3 | Supports SwitchDoc Labs WeatherRack WeatherBoard (WeatherPiArduino V2 and above)
4 |
5 | Version 3.17
6 |
7 | http://www.switchdoc.com/
8 |
9 | June 7, 2019 - Version 3.17 Improved AM2315 reliablity - fixed 0 CRC error
10 |
11 | March 30, 2019 - Version 3.16 Improved AM2315 reliablity - added support for Grove PowerSave
12 |
13 | February 8, 2019 - Version 3.15 Increase Max Retries on AM2315 to 10 per suggestion
14 |
15 | January 12, 2019 - Version 3.14 Fixed am2315 not assigned error
16 |
17 | January 10, 2019 - Version 3.13 Added "None" detection to AM2315, added Try, Except loop on AM2315 read
18 |
19 | December 19, 2018 - Version 3.12 Improved Blynk reliability
20 |
21 | November 28, 2018 - Version 3.11 Further improved AM2315, fixed startup glitch with English/Metric units, fixed Rain Status
22 |
23 | November 26, 2018 - Version 3.10 Added Blynk App support and changed sampling method to remove I2C errors - fixed AM2315 humidity/temperature mixup
24 |
25 | November 14, 2018 - Version 3.04 Added CRC checking to the AM2315 Python Driver.
26 |
27 | November 14, 2018 - Version 3.03 Added New AM2315 Python Driver. removed tentacle_pi
28 |
29 | October 1, 2018 - Improved README.md install instructions
30 |
31 | June 19, 2018 - Version 3.02 Fixed SI1145 Gain (made for outdoors) Adjusted Lux readings for outdoor sunlight rough calibration
32 |
33 | May 30, 2018 - Version 3.01 Fixed MySQL Garding, bad read issues with SI1145, gave fix for Mising BBIO Library in README.md
34 |
35 | November 18, 2017 - Version 2.99 Adjusted Lightning Detector detection for 0x02 or 0x03
36 |
37 | November 16, 2017 - Version 2.98 Fixed name clash with latest OS version
38 |
39 | October 2, 2017 - Version 2.97 Fixed SI1145 issues with reading
40 |
41 | August 24, 2017 - Fixed AS3935 Missing issue with Interrupt variable
42 |
43 | July 20, 2017 - Fixed Rainfall 2X inaccuracy and 60 minute and midnight issues
44 |
45 | July 17, 2017 - Updated Bounce Times to fix wind speed issues - This probably fixes the Wind Gust problem too. Not conclusive.
46 |
47 | June 19, 2017 - Fixed uninitialized variable errors
48 |
49 | June 17, 2017 - Changed the README.md to require the installation of the software suporting SI1145 detection
50 |
51 | May 5, 2017 - Commented out 48 Reboot add_job (uncomment to add back in), Fixed SI1145 bad installation detection
52 |
53 | May 4, 2017 - Fixed problem with inside temperature being zero when you have an HTU rather than a HDC1080
54 |
55 | March 9, 2017 - Added time based scheduler into the main loop instead of polling (APscheduler). Added support for Grove HDC1000
56 |
57 | October 26, 2016 - Support added for Grove Sunlight/IR/UV SI1145 sensor. Database updated. Run mysql as below
58 |
59 | October 24, 2016 - Improved WXLink Error Checking
60 |
61 | October 3, 2016 - Added CRC Check to WXLink support, changed Barometric report on WU to Sea Level, added Altitude configuration in confif.py
62 |
63 | September 9, 2016 - Added WeatherUnderground Support - see Blog article on www.switchdoc.com for instructions. The summary of the instructions are:
64 |
65 | 1) sign up for a personal weather station on weatherunderground.com
66 |
67 | 2) Get your station name and key and put them in your config.py file, and then setting the WeatherUnderground_Present to True
68 |
69 |
70 | August 30, 2016 - Improved WXLink support reliablity - now detects and adjusts for missing records from WXLink reads
71 |
72 | August 26, 2016 - Added Support for WXLink Wireless Weather Connector
73 |
74 | August 17, 2016 - Added support back in for RasPiConnect
75 |
76 | August 16, 2016 - Support for Weather Board and improved device detection without exceptions
77 |
78 | March 28, 2015 - added subdirectories
79 |
80 | May 9, 2015 - Updated software for WatchDog Timer and Email
81 |
82 | May 10, 2015 - Added mysql table SQL files for database building
83 |
84 | -----------------
85 | Install this for smbus:
86 |
87 | sudo apt-get install python-smbus
88 |
89 | Install this next:
90 |
91 |
92 | git clone https://github.com/adafruit/Adafruit_Python_PureIO.git
93 | cd Adafruit_Python_PureIO
94 | sudo python setup.py install
95 |
96 | Other installations required for AM2315:
97 |
98 | sudo apt-get install python-pip
99 |
100 | sudo apt-get install libi2c-dev
101 |
102 |
103 | #Installing apscheduler
104 |
105 | sudo pip install --upgrade setuptools pip
106 |
107 | sudo pip install setuptools --upgrade
108 | sudo pip install apscheduler
109 |
110 |
111 | ----------------
112 | Note some configurations of Raspberry Pi software requres the following:
113 | It won't hurt to do this in any case.
114 | ----------------
115 |
116 | sudo apt-get update
117 | sudo apt-get install build-essential python-pip python-dev python-smbus git
118 | git clone https://github.com/adafruit/Adafruit_Python_GPIO.git
119 | cd Adafruit_Python_GPIO
120 | sudo python setup.py install
121 | cd ..
122 | cd SDL_Pi_GroveWeatherPi
123 | cd Adafruit_Python_SSD1306
124 | sudo python setup.py install
125 |
126 | SwitchDocLabs Documentation for WeatherRack/WeatherPiArduino under products on: store.switchdoc.com
127 |
128 | Read the GroveWeatherPi Instructable on instructables.com for more software installation instructions
129 |
130 | or
131 |
132 | Read the tutorial on GroveWeatherPi on http://www.switchdoc.com/2016/08/tutorial-part-1-building-a-solar-powered-raspberry-pi-weather-station-groveweatherpi/
133 | for more software installation instructions.
134 |
135 | -----------
136 | setup your configuration variables in config.py!
137 | -----------
138 |
139 | --------
140 | Add SQL instructions
141 | ----------
142 |
143 | Use phpmyadmin or sql command lines to add the included SQL file to your MySQL databases.
144 | Note: If the database has been updated, run the example below to update your database. The current contents will not be lost.
145 |
146 |
147 | example: sudo mysql -u root -p GroveWeatherPi< GroveWeatherPi.sql
148 |
149 | user: root
150 |
151 | password: password
152 |
153 | Obviously with these credentials, don't connect port 3306 to the Internet. Change them if you aren't sure.
154 |
155 | NOTE:
156 |
157 | If you have a WXLink wireless transmitter installed, the software assumes you have connected your AM2315 outdoor temp/humidity sensor to the WXLink. If you put another AM2315 on your local system, it will use those values instead of the WXLink values
158 |
159 |
160 |
161 |
--------------------------------------------------------------------------------
/SDL_Pi_HDC1000/SDL_Pi_HDC1000.py:
--------------------------------------------------------------------------------
1 | #
2 | #
3 | # SDL_Pi_HDC1000
4 | # Raspberry Pi Driver for the SwitchDoc Labs HDC1000 Breakout Board
5 | #
6 | # SwitchDoc Labs
7 | # January 2017
8 | #
9 | # Version 1.1
10 |
11 | #constants
12 |
13 | # I2C Address
14 | HDC1000_ADDRESS = (0x40) # 1000000
15 | # Registers
16 | HDC1000_TEMPERATURE_REGISTER = (0x00)
17 | HDC1000_HUMIDITY_REGISTER = (0x01)
18 | HDC1000_CONFIGURATION_REGISTER = (0x02)
19 | HDC1000_MANUFACTURERID_REGISTER = (0xFE)
20 | HDC1000_DEVICEID_REGISTER = (0xFF)
21 | HDC1000_SERIALIDHIGH_REGISTER = (0xFB)
22 | HDC1000_SERIALIDMID_REGISTER = (0xFC)
23 | HDC1000_SERIALIDBOTTOM_REGISTER = (0xFD)
24 |
25 | #Configuration Register Bits
26 |
27 | HDC1000_CONFIG_RESET_BIT = (0x8000)
28 | HDC1000_CONFIG_HEATER_ENABLE = (0x2000)
29 | HDC1000_CONFIG_ACQUISITION_MODE = (0x1000)
30 | HDC1000_CONFIG_BATTERY_STATUS = (0x0800)
31 | HDC1000_CONFIG_TEMPERATURE_RESOLUTION = (0x0400)
32 | HDC1000_CONFIG_HUMIDITY_RESOLUTION_HBIT = (0x0200)
33 | HDC1000_CONFIG_HUMIDITY_RESOLUTION_LBIT = (0x0100)
34 |
35 | HDC1000_CONFIG_TEMPERATURE_RESOLUTION_14BIT = (0x0000)
36 | HDC1000_CONFIG_TEMPERATURE_RESOLUTION_11BIT = (0x0400)
37 |
38 | HDC1000_CONFIG_HUMIDITY_RESOLUTION_14BIT = (0x0000)
39 | HDC1000_CONFIG_HUMIDITY_RESOLUTION_11BIT = (0x0100)
40 | HDC1000_CONFIG_HUMIDITY_RESOLUTION_8BIT = (0x0200)
41 |
42 | import smbus
43 | import time
44 |
45 |
46 | class SDL_Pi_HDC1000:
47 | def __init__(self, twi=1, addr=HDC1000_ADDRESS ):
48 | self._bus = smbus.SMBus(twi)
49 | self._addr = addr
50 | # 0x10(48) Temperature, Humidity enabled, Resolultion = 14-bits, Heater off
51 | config = HDC1000_CONFIG_ACQUISITION_MODE
52 | self._bus.write_byte_data(HDC1000_ADDRESS,HDC1000_CONFIGURATION_REGISTER, config>>8)
53 |
54 |
55 | # public functions
56 |
57 | def readTemperature(self):
58 |
59 | # Send temp measurement command, 0x00(00)
60 |
61 | self._bus.write_byte(HDC1000_ADDRESS, HDC1000_TEMPERATURE_REGISTER )
62 | time.sleep(0.020)
63 |
64 |
65 | # Read data back, 2 bytes
66 |
67 | # temp MSB, temp LSB
68 | data0 = self._bus.read_byte(HDC1000_ADDRESS)
69 | data1 = self._bus.read_byte(HDC1000_ADDRESS)
70 | # Convert the data
71 | temp = (data0 * 256) + data1
72 | cTemp = (temp / 65536.0) * 165.0 - 40
73 | return cTemp
74 |
75 |
76 | def readHumidity(self):
77 | # Send humidity measurement command, 0x01(01)
78 |
79 | self._bus.write_byte(HDC1000_ADDRESS, HDC1000_HUMIDITY_REGISTER)
80 |
81 | time.sleep(0.020)
82 |
83 |
84 | # Read data back, 2 bytes
85 |
86 | # humidity MSB, humidity LSB
87 | data0 = self._bus.read_byte(HDC1000_ADDRESS)
88 | data1 = self._bus.read_byte(HDC1000_ADDRESS)
89 | # Convert the data
90 | humidity = (data0 * 256) + data1
91 | humidity = (humidity / 65536.0) * 100.0
92 | return humidity
93 |
94 | def readConfigRegister(self):
95 | # Read config register
96 |
97 | self._bus.write_byte(HDC1000_ADDRESS, HDC1000_CONFIGURATION_REGISTER)
98 |
99 | # config register
100 | data0 = self._bus.read_byte(HDC1000_ADDRESS)
101 | data1 = self._bus.read_byte(HDC1000_ADDRESS)
102 |
103 | #print "register=%d %X"% (data0, data0)
104 | return data0
105 |
106 | def turnHeaterOn(self):
107 | # Read config register
108 | config = self.readConfigRegister()
109 | config = config<<8 | HDC1000_CONFIG_HEATER_ENABLE
110 | self._bus.write_byte_data(HDC1000_ADDRESS,HDC1000_CONFIGURATION_REGISTER,config>>8)
111 |
112 | return
113 |
114 | def turnHeaterOff(self):
115 | # Read config register
116 | config = self.readConfigRegister()
117 | config = config<<8 & ~HDC1000_CONFIG_HEATER_ENABLE
118 | self._bus.write_byte_data(HDC1000_ADDRESS,HDC1000_CONFIGURATION_REGISTER,config>>8)
119 |
120 | return
121 |
122 | def setHumidityResolution(self,resolution):
123 | # Read config register
124 | config = self.readConfigRegister()
125 | config = (config<<8 & ~0x0300) | resolution
126 | self._bus.write_byte_data(HDC1000_ADDRESS,HDC1000_CONFIGURATION_REGISTER,config>>8)
127 | return
128 |
129 | def setTemperatureResolution(self,resolution):
130 | # Read config register
131 | config = self.readConfigRegister()
132 | config = (config<<8 & ~0x0400) | resolution
133 | self._bus.write_byte_data(HDC1000_ADDRESS,HDC1000_CONFIGURATION_REGISTER,config>>8)
134 | return
135 |
136 |
137 | def readBatteryStatus(self):
138 |
139 | # Read config register
140 | config = self.readConfigRegister()
141 | config = config<<8 & ~ HDC1000_CONFIG_HEATER_ENABLE
142 |
143 | if (config == 0):
144 | return True
145 | else:
146 | return False
147 |
148 | return 0
149 |
150 | def readManufacturerID(self):
151 |
152 | data = self._bus.read_i2c_block_data (HDC1000_ADDRESS, HDC1000_MANUFACTURERID_REGISTER , 2)
153 | return data[0] * 256 + data[1]
154 |
155 | def readDeviceID(self):
156 |
157 | data = self._bus.read_i2c_block_data (HDC1000_ADDRESS, HDC1000_DEVICEID_REGISTER , 2)
158 | return data[0] * 256 + data[1]
159 |
160 | def readSerialNumber(self):
161 |
162 | serialNumber = 0
163 |
164 | data = self._bus.read_i2c_block_data (HDC1000_ADDRESS, HDC1000_SERIALIDHIGH_REGISTER , 2)
165 | serialNumber = data[0]*256+ data[1]
166 |
167 | data = self._bus.read_i2c_block_data (HDC1000_ADDRESS, HDC1000_SERIALIDMID_REGISTER , 2)
168 | serialNumber = serialNumber*256 + data[0]*256 + data[1]
169 |
170 | data = self._bus.read_i2c_block_data (HDC1000_ADDRESS, HDC1000_SERIALIDBOTTOM_REGISTER , 2)
171 | serialNumber = serialNumber*256 + data[0]*256 + data[1]
172 |
173 | return serialNumber
174 |
175 |
176 |
--------------------------------------------------------------------------------