Raspberry Pi LESSON 28: Build a Programmable Temperature Sensing Alarm

preview_player
Показать описание
Announcing the Most Awesome Raspberry Pi Lessons of All Times! This time we RUMBLE!

In this class series, we will be using the most excellent Sunfounder Ultimate Raspberry Pi kit, available here: (Affiliate Link)

In this video lesson I will show you my project to create a temperature sensing alarm. The device is programmable from a push button and potentiometer. An audible alarm is sounded when the temperature crosses your trip point.

If you want to grab those cool little straight jumper wires I am using to keep my breadboard builds neat and clean you can snag a box of them here:

If you guys are interested in the oscilloscope I am using, you can pick one up here (affiliate link):

You guys get your hardware ordered so you can follow along at home!

You will also need a Raspberry Pi. I suggest the Raspberry Pi 4. If you do not already have one, this is the most suitable gear I could find:

The Raspberry Pi's are sort of pricy right now, so you can look on ebay or elsewhere to see if there are any deals. You will need a SD card. If you do not already have one, this is a good one:

I like using a wireless keyboard and mouse to have fewer wires. You can certainly use your USB keyboard and mouse, but if you want a nice wireless one, this one works on the pi. We demonstrate this by using a button switch to control a LED.

You guys can help me out over at Patreon, and that will help me keep my gear updated, and help me keep this quality content coming:

#TUTORIAL
#buzzerrp
#RASPBERRYPI
Рекомендации по теме
Комментарии
Автор

Like the most popular YouTube math channel "Math and Science", Paul never showed off or acted, instead you have always been down to earth with solid results and easy-to-follow instructions, so we audience could do what you did.

Those "showed off or acted" channels presented un-realistic contents that are not best practices and misleading.

For example, in real life, engineers should not solder the whole PCB in one go with a stencil, instead, he/she should solder a part, then test the parts with a multimeter, then continue to solder, then test it....until the whole board is done. Soldering the whole board in one go with a stencil would lead to a situation where debugging would be very difficult, especially for beginners.

Bob-zgzf
Автор

I had a teacher (long ago) who told us students to figure out these things you learn. Today it was a temp sensor and a programmable alarm. We go to the shop and buy one and we find it normal that it does what it does. The thing is, nobody knows how it works and does what it does. What was the thinking behind it. I'm greatful you teach us these things in a very clear way. Thank you Sir.

wendygrant
Автор

I gave myself an 85% for the build, I put the 10K resistor on the DHT11 in the wrong location. 50% for the program, I started to shoot blanks when got to while True:! Thanks this was awesome.

stephenlightkep
Автор

Thank you. Am having a great time. There are no silly cat videos but am watching them less in favor your classes. Thank you again.

danrichardson
Автор

I can't thank you enough for helping me discover this hobby!

iamblue
Автор

I am legend. I had to use an MCP3008 ADC chip and a 1602LCD Display with no I2C board. These last several lessons have required some digging into alternate libraries to figure out how to tell the Pi what I want it to do, but it is so rewarding to work through those frustrations once you finally get the results you want. I'm sure there are many things in this program that could have been written much better by someone who knows what they're doing, but here is the code that I wrote with a mix of what I learned from you and what I had to figure out on my own.

import RPi.GPIO as GPIO
import time
import dht11
import busio
import digitalio
import board
import adafruit_mcp3xxx.mcp3008 as MCP
from adafruit_mcp3xxx.analog_in import AnalogIn
import as characterlcd
spi=busio.SPI(clock=board.SCK, MISO=board.MISO, MOSI=board.MOSI)

mcp=MCP.MCP3008(spi, cs)

chan1=AnalogIn(mcp, MCP.P1)

#LCD Display size
lcd_columns=16
lcd_rows=2








# Initialise the lcd class
lcd=characterlcd.Character_LCD_Mono(lcd_rs, lcd_en, lcd_d4, lcd_d5, lcd_d6, lcd_d7, lcd_columns, lcd_rows)

buzzPin=27
buttonPin=20
GPIO.setmode(GPIO.BCM)
GPIO.setup(buzzPin, GPIO.OUT)
GPIO.output(buzzPin, GPIO.HIGH)
GPIO.setup(buttonPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
buzz=GPIO.PWM(buzzPin, 400)
myDHT=dht11.DHT11(pin=21)
buttonState=1
buttonStateOld=1
tempSetting=0
setReadTemp=True

lcd.clear()

try:

while True:


if buttonState==1 and buttonStateOld==0:
setReadTemp=not setReadTemp
lcd.clear()
buttonStateOld=buttonState
time.sleep(.1)

result=myDHT.read()
tempC=result.temperature
tempF=tempC*1.8+32
tempF=round(tempF, 1) #number of decimal places
hum=result.humidity
if result.is_valid():
if setReadTemp==True:
lcd.message='Temp F:'
lcd.row=0
lcd.column=10
lcd.message=str(tempF)
lcd.row=1
lcd.column=0
lcd.message='Humidity:'
lcd.row=1
lcd.column=10
lcd.message=str(hum)
lcd.row=1
lcd.column=14
lcd.message='%'
if int(tempSetting)==int(tempF):
lcd.clear()
lcd.message='Temp F:'
lcd.row=0
lcd.column=10
lcd.message=str(tempF)
lcd.row=1
lcd.column=0
lcd.message='Temp Alert!'
buzz.start(50)
for i in range(200, 1500):
buzz.ChangeFrequency(i)
time.sleep(.0002)
for i in range(1500, 200, -1):
buzz.ChangeFrequency(i)
time.sleep(.0002)
buzz.stop()
lcd.clear()

if setReadTemp==False:
trim_pot0=chan1.value

if tempSetting>=100:
tempSetting=99
lcd.message='Set Temp Alert:'
if tempSetting<10:
lcd.clear()
lcd.message='Set Temp Alert:'
lcd.row=1
lcd.column=8
if tempSetting>=10:
lcd.row=1
lcd.column=7


except KeyboardInterrupt:
lcd.clear()
GPIO.cleanup()
print('Clear')

blansettj
Автор

I'm legend but, oh boy! I did not think about shutting off alarm when programming mode on... I just chained an extra condition for that in my checkTempThreshold method, perfect! Thanks for this lesson, Paul

freddyveza
Автор

Thank! I had a lot of fun doing this homework. My version added another limit alarm for too low of a temperatures, as well as the too high of a temperature alarm. This made the menu scheme using only one button for four different task (enter Low Limit Menu, Enter Low Limit Value, enter high Limit Menu, Enter High Limit Value) pretty rough. But it is fully functional.

wilsonlittle
Автор

Fun project, Paul, TY. My build uses the slide switch from the kit to to power the rails and an LED is on during Run Mode, just because. During Run Mode I make function calls to update buzzVal in real time. No need for switching Set/Run Mode. The LCD shows both the Temp and the Temp Setting. Alarm works great, weird thing, tho: after first time alarm goes off, there remains a very feint but constant buzz in either mode and when alarm is on or off. May be fun figuring that out... or not. 🤔 I use Set Mode just for initial setting. The Youtube streaming IP lesson is out of date and doesn't work. Will find something else on the Web for that... someday.

JohnHickmott
Автор

Wow.. It's just awesome lesson.. We get a god in youtube that's you sir.. 🙏🙏

pralaymajumdar
Автор

Another awesome lesson, Paul! I have always been fascinated by transistors: I recall as a child having my Mom buy me a huge book on transistors at a garage sale. I remember being impressed with all the cool information in the book, even though I did not understand it.
I know most of us appreciate how you perform debugging in your videos. Seeing you work through it gives us very valuable troubleshooting knowledge. High-five, Paul!!

DrDave
Автор

I am Legend Mid Term == PASS great to see your solution, .... ready for the next lesson ...

davidschnider
Автор

It took me over a week to do it, but I am Legend! I used 2 potentiometers and made both high and low temp limits and alarms.

brucemilyko
Автор

yet another great lesson BOOM! holding my breath as I type :)

waynel
Автор

Can we get that lesson on transistors that's would be awesome thank you

a-aron
Автор

irLegend

Got a little carried away. LCD display has an selectable F or C screen with H and the alarm values, the alarm setpoints are adjustable using a single potentiometer for both min and max temp, RGB LED to indicate 5 functions, a silence alarm function which is also indicated on LCD, button press passive beep and alarm active beep.
Feels like I'm forgetting about something since there are 210 lines of code.
The code reads like a wild goose chase in a choose your own adventure book. So, if I knew more python functions this could be done a lot better. But happy with the end result and works well enough for a homebrew lesson, even with the bugs.

My homework:

billgregg
Автор

Hi Paul

Unfortunately, I haven't been able to make my video yet as we have workmen banging and crashing in the house all week.

Because you were anxious about the smoke drifting over the river in the last video, I tried making my buzzer play the beginning of 'smoke on the water' for you. It only needed 4 different notes and it was quite easy to do but the sound quality was so bad that it gave me a blinding headache and I deleted the program before my husband divorced me.

charlotteswift
Автор

For some reason the S8550 transistors did not work as expected. They all only reduced volume when when buzzPin was set HIGH. I tried various pins and base resistor values but was only able to reduce the volume. The solution that worked was to use the S8050 and just reverse the "GPIO.HIGH" and "GPIO.LOW" to set buzzPin in the program.

timefactortheoryofgravitya
Автор

I managed to get the homework working this Tuesday. My main problem was to find a free timeslot in my busy calender...
I think it can be good to have some weeks now and then without any new video, so we are able to catch up.

peterkarlsson
Автор

Couldn't video so here is code - kind of messy - but it works
# lesson27HW

# display temp and humidity read from dht22 sensor on LCD screen
# blue button toggles temp between celsius and fahrenhiut
# yellow button enters temp setmode for high and low alarms
# variable resistor and adc is used to change alarm temp set points.
# led show state green normal, blue low alarm, red high alarm
# buzzer beeps when in alarm state.
# red button stops the program.
import RPi.GPIO as gp
import Adafruit_DHT
import LCD1602
import ADC0834
import time
dhtPin = 17
nowOld = 0.0
unit = True # indicator to display celsius or fahrenheit
gp.setmode(gp.BCM)
ADC0834.setup()
myDHT = Adafruit_DHT.DHT22
LCD1602.init(0x27, 1)
rLed = 27
gp.setup(rLed, gp.OUT, initial=gp.LOW)
gLed = 22
gp.setup(gLed, gp.OUT, initial=gp.LOW)
bLed = 6
gp.setup(bLed, gp.OUT, initial=gp.LOW)
btn1 = 21
gp.setup(btn1, gp.IN, pull_up_down = gp.PUD_UP)
stopStateOld = 1
btn2 = 26
gp.setup(btn2, gp.IN, pull_up_down = gp.PUD_UP)
unitStateOld =1
ybtn = 19
gp.setup(ybtn, gp.IN, pull_up_down = gp.PUD_UP)
ybtnStateOld = 1
beepPin = 13
gp.setup(beepPin, gp.OUT, initial=gp.HIGH)
stp = 0 # stop program indicator
tempL = -40 # so buzzer does not beep on startup
tempH = 80 # so buzzer does not beep on startup
temp = 20 # initial setting so buzzer does not beep on startup

# read data from dht22 sensor
def getTemp():
global temp
global humid
global nowOld
now = time.time()
if now - nowOld > 4:
nowOld = now
humid_t, temp_t = Adafruit_DHT.read_retry(myDHT, dhtPin)
time.sleep(.001)
if humid_t is not None and temp_t is not None:
temp = temp_t
humid = humid_t
# alarms for low and high temps.
# there is a slide switch to disable audiable alarm
# led will still show status, low, normal or high (blue, green, red)
def alarm():
global temp
global tempL
global tempH
if temp > tempL and temp < tempH:
gp.output(gLed, 1)
gp.output(rLed, 0)
gp.output(bLed, 0)
if temp < tempL+1:
gp.output(gLed, 0)
gp.output(rLed, 0)
gp.output(bLed, 1)
gp.output(beepPin, 0)
time.sleep(.05)
gp.output(beepPin, 1)
time.sleep(.05)
if temp > tempH:
gp.output(rLed, 1)
gp.output(bLed, 0)
gp.output(gLed, 0)

gp.output(beepPin, 0)
time.sleep(.05)
gp.output(beepPin, 1)
time.sleep(.05)
# read analog to digital convertor
def adc():
result = ADC0834.getResult(1)
convert = (120/255 * result + (-40))-1 # convert result to dht22 scale (-40 to 80)
return convert
# write temp and humidity to lcd screen
def displayLCD():
global unit
global temp
global humid
global unitStateOld
unitState = gp.input(btn2)
if unitState == 1 and unitStateOld == 0:
unit = not unit
LCD1602.write(0, 0, "Temp")
if unit == False:
tempF = temp * 9/5 + 32
LCD1602.write(10, 0, str(round(tempF, 1)))
LCD1602.write(16, 0, "F")
if unit == True:
LCD1602.write(10, 0, str(round(temp, 1)))
LCD1602.write(16, 0, "C")
LCD1602.write(0, 1, "Humidity")
LCD1602.write(10, 1, str(round(humid, 1)))
LCD1602.write(16, 1, "%")
unitStateOld = unitState
# prog mode to set low and high temp alarm points
def progMode():
while True:
LCD1602.clear()
while True: # set lower alarm point
global ybtnStateOld
global tempL
tempL = adc()
tempL = round(tempL, 2)
LCD1602.write(2, 0, "Low Setpoint")
LCD1602.write(5, 1, str(tempL))
LCD1602.write(11, 1, "C.")
ybtnState = gp.input(ybtn)
if ybtnState == 1 and ybtnStateOld == 0:
ybtnStateOld = ybtnState
LCD1602.clear()
break
ybtnStateOld = ybtnState
time.sleep(.1)

while True: # set high alarm point
global tempH
ybtnStateOld
tempH = adc()
tempH = round(tempH, 2)
LCD1602.write(2, 0, "High Setpoint")
LCD1602.write(5, 1, str(tempH))
LCD1602.write(11, 1, "C.")
ybtnState = gp.input(ybtn)
if ybtnState == 1 and ybtnStateOld == 0:
ybtnStateOld = ybtnState
LCD1602.clear()
break
ybtnStateOld = ybtnState
time.sleep(.001)
break

# to stop program and exit.
def stop():
stopState = gp.input(btn1)
if stopState == 0:
LCD1602.clear()
gp.cleanup()
print("Red stop button was pushed")
time.sleep(.001)
stp = 1
return stp

# start of main program
try:
while True:
getTemp()
adc()
alarm()
displayLCD()
time.sleep(.001)
stp = stop()
if stp == 1:
break
ybtnState = gp.input(ybtn)
if ybtnState == 1 and ybtnStateOld == 0:
ybtnStateOld = ybtnState
progMode()
ybtnStateOld = ybtnState

except KeyboardInterrupt:
LCD1602.clear()
gp.cleanup()
print('Bye')

daveslack