I have little experience with Raspberry Pi and Python but I managed to integrate a solution for a system that reacts when people are present (with PIR sensor) and based on the count of persons, it commands changes to the speed of a peristaltic pump controlled by an Arduino (communication made via Bluetooth using HC-06).
The job made by the RPi is getting event by PIR sensor, making the count of people using a camera, send BT command and playing or changing a sound track.
Problem I just got is static sound in the 3.5mm jack while playing the audio.
Things that I already checked: + Speakers and connections are working fine with other devices + GPIOs are well connected and isolated + Audios play fine outside the program + Added "pwm_mode = 2" and "disable_audio_dither=1" to config.txt
Raspberry Pi 3B+ running NOOBS, OpenCV and Python 3 on virtualenv Code:
from picamera import PiCamera
from time import sleep
from threading import Timer
from random import randint
import numpy as np
import imutils
import RPi.GPIO as GPIO
import serial
import cv2
import pygame
pygame.mixer.init(frequency=44100, size=-16, channels=2, buffer=4096)
pir = 4
crowd = 0
last = 0
lv = 1
waiting = True
state = False
active = False
GPIO.setmode(GPIO.BCM)
GPIO.setup(pir, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
camera = PiCamera()
camera.resolution = (640, 480)
intro = pygame.mixer.Sound('./audio/0.wav')
first = pygame.mixer.Sound('./audio/1.wav')
second = pygame.mixer.Sound('./audio/2.wav')
third = pygame.mixer.Sound('./audio/3.wav')
outro = pygame.mixer.Sound('./audio/m1.wav')
btSerial = serial.Serial( "/dev/rfcomm0", baudrate=9600 )
sleep(2)
hog = cv2.HOGDescriptor()
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
def shot(channel):
global waiting
print(channel)
waiting = False
t.cancel()
k.cancel()
camera.start_preview()
sleep(2)
camera.capture('/home/pi/Desktop/crowd.bmp')
camera.stop_preview()
print ('Photo captured')
people_counter()
if not active:
start()
else:
update()
def deactiv():
global active
global last
active = False
intro.fadeout(8200)
first.fadeout(8200)
second.fadeout(8200)
third.fadeout(8200)
outro.play(0,10000,6500)
last = 0
send_bt('OFF')
def keep_on():
send_bt('READY')
def people_counter():
global crowd
image = cv2.imread('crowd.bmp')
image = imutils.resize(image, width=min(400, image.shape[1]))
(rects, weights) = hog.detectMultiScale(image, winStride=(4, 4),
padding=(16, 16), scale=1.003)
crowd = len(rects)
print(crowd)
def start():
global active
active = True
intro.play(0,-1, 6500)
send_bt('TRIG')
def update():
global last
global lv
if 0 <= crowd <= 2 :
lv = 1
elif 2 < crowd <= 5 :
lv = 2
elif crowd >= 5 :
lv = 3
if lv == last and last != 3:
pass
else:
if lv == 1:
intro.fadeout(8200)
first.fadeout(8200)
second.fadeout(8200)
third.fadeout(8200)
first.play(-1,-1,6500)
send_bt('SET:50')
elif lv == 2:
intro.fadeout(8200)
first.fadeout(8200)
second.fadeout(8200)
third.fadeout(8200)
second.play(-1,-1,6500)
send_bt('SET:160')
elif lv == 3:
if last != 3:
intro.fadeout(8200)
first.fadeout(8200)
second.fadeout(8200)
third.fadeout(8200)
third.play(-1,-1,6500)
n_sp = randint(200, 350)
send_bt('SET:'+str(n_sp))
last = lv
def send_bt(pump_com):
print('sending'+pump_com)
btSerial.write(pump_com.encode())
#Wait "Done!"
send_bt('READY')
t = Timer(180, deactiv)
k = Timer(30, keep_on)
GPIO.add_event_detect(pir, GPIO.RISING, shot)
while True:
state = GPIO.input(pir)
if active and not state:
if not waiting:
t = Timer(180, deactiv)
t.start()
waiting = True
elif flag:
k = Timer(30, keep_on)
k.start()
flag = False