-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBarkBack.py
184 lines (148 loc) · 5.5 KB
/
BarkBack.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
####################################################
#Bark Back: Monitor & Interact with Pets!##
####################################################
# Code written by jenfoxbot <jenfoxbot@gmail.com>
# Code is open-source, coffee/beer-ware license.
# Please keep header + if you like the content,
# buy me a coffee and/or beer if you run into me!
#####################################################
# Many thanks to the folks who create & document the libraries
# and functions used in this project.
#Libraries
#SPI
import spidev
#OMXPlayer
from threading import Thread
import subprocess
#MQTT
import paho.mqtt.client as paho
#Other
import random, time, os, urlparse
import time
songList = ["SongFile1", #e.g. "/home/pi/Desktop/SongFile.mp3"
"SongFile2",
"SongFile3",
"SongFile4"]
creds = {
'CloudMQTT URL': 'INSERT_CLOUDMQTT_URL', #e.g. 'https://m10.cloudmqtt.com'
'user': 'INSERT_CLOUDMQTT_USERNAME',
'password': 'INSERT__CLOUDMQTT_PASSWORD',
'host': 'INSERT_CLOUDMQTT_SERVER'
'port': 'INSERT_CLOUDMQTT_PORT',
'topic': 'INSERT_ACL_TOPIC'
}
########################################################
# Reading SparkFun MEMS Microphone Breakout Board
########################################################
#Start SPI protocol.
spi = spidev.SpiDev()
spi.open(0,0) #This is the CE0 Pin (GPIO 08) on the RPi, for CE1, use (0,1)
#Function to read in CE0 channel
def read_spi(channel):
spidata = spi.xfer2([96,0]) ##sending 2 bytes of data (96 and 0)
data = ((spidata[0] & 3) << 8) + spidata[1]
return data
#Function to calculate Peak to Peak Amplitude from MEMS mic
def PTPAmp():
sampleTime = 0.05 #Sample Rate of 50 ms
startTime = time.time()
PTPAmp = 0
maxAmp = 0
minAmp = 1023
while(time.time() - startTime < sampleTime):
micOut = read_spi(0) #Read in channel CE0
if(micOut < 1023): #Prevent erroneous readings
if(micOut > maxAmp):
maxAmp = micOut
elif(micOut < minAmp):
minAmp = micOut
PTPAmp = maxAmp - minAmp #Calculate peak-to-peak amp.
return PTPAmp
#Function to map peak-to-peak amp to a volume unit between 0 and 10
def VolumeUnit(data, fromLow, fromHigh, toLow, toHigh):
return (data - fromLow) * (toHigh - toLow) / (fromHigh - fromLow) + toLow
########################################################
# Class to Control OMXPlayer for Audio
########################################################
class OMXPlayer():
def call_omxplayer(self):
print ("playing " + self.file_path + '\n')
pid = subprocess.Popen(['omxplayer', '-o', 'local',
self.file_path], stderr=subprocess.PIPE,
stdout=subprocess.PIPE)
self.is_running = False
def play_song(self):
if not self.is_running:
self.song_thread = Thread(target=self.call_omxplayer, args=())
self.song_thread.start()
self.is_running = True
def __init__(self, file_path):
self.file_path = file_path
self.is_running = False
self.play_song()
#Function to select random song from list
def pickRandom(songList):
return(random.choice(songList))
########################################################
# CloudMQTT Server
########################################################
# Define event callbacks
def on_connect(mosq, obj, rc):
print("rc: " + str(rc))
def on_message(mosq, obj, msg):
print(msg.topic + " " + str(msg.qos) + " " + str(msg.payload))
def on_publish(mosq, obj, mid):
print("mid: " + str(mid))
def on_subscribe(mosq, obj, mid, granted_qos):
print("Subscribed: " + str(mid) + " " + str(granted_qos))
def on_log(mosq, obj, level, string):
print(string)
########################################################
# Main Function
########################################################
def main():
#Call Paho Python Client Server
mqttc = paho.Client()
#Assign event callbacks
mqttc.on_message = on_message
mqttc.on_connect = on_connect
mqttc.on_publish = on_publish
mqttc.on_subscribe = on_subscribe
# Uncomment to enable debug messages
#mqttc.on_log = on_log
# Parse CLOUDMQTT_URL (or fallback to localhost)
url_str = os.environ.get(creds['CloudMQTT URL'], 'mqtt://localhost:1883')
url = urlparse.urlparse(url_str)
# Connect
mqttc.username_pw_set(creds['user'], creds['password'])
mqttc.connect(creds['host'], creds['port'])
# Start subscribe, with QoS level 0
mqttc.subscribe(creds['topic'], 0)
while True:
#1. Find ADC value for MEMS mic peak-to-peak amp
PTPamp = PTPAmp()
#2. Calculate ptp amp (Volts)
PTPampV = round(((PTPamp*3.3) / 1024), 2)
#3. Map ptp amp (ADC value) to Volume Unit between 0 and 10
VolUnit = VolumeUnit(PTPamp, 0, 700, 0, 10)
#For debugging purposes
print(PTPamp, VolUnit)
#4. If Volume Unit is greater than 7, play one of the songs
if(VolUnit > 7):
playBack = pickRandom(songList)
OMXPlayer(playBack)
time.sleep(0.1)
#5. Upload data to CloudMQTT Server
mqttc.publish("Volume", str(VolUnit))
rc = True
while rc:
rc = mqttc.loop()
time.sleep(0.1)
print("rc: " + str(rc))
try:
while True:
pass
except KeyboardInterrupt:
myprocess.kill()
if __name__ == '__main__':
main()