亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

热水器热电偶电压监测器

组件和用品

Adafruit Raspberry Pi 零 WH
× 1
Arduino Nano R3
× 1

关于这个项目

热水器指示灯监控系统

传统的燃气热水器保持 24x7 的指示灯。该指示灯加热热电偶,产生小电压(高达 30 毫伏)。热水器恒温器使用该电压来保持打开燃气阀。如果指示灯熄灭,则电压停止,燃气阀自动关闭。

在我的热水器中,指示灯偶尔会熄灭。由于这种情况每年仅发生 3 次左右,我不想更换昂贵的热水器。我尝试更换热电偶,但这并没有解决问题。

我的解决方案:监控热电偶产生的电压。如果它降为零,请发送文本和电子邮件,以便我可以重新点亮指示灯。请记住,这里没有燃气泄漏的危险,因为只要热电偶电压降为零,燃气阀就会关闭。

概览

当指示灯熄灭时,Raspberry Pi Zero WH 将用于发送电子邮件和文本。因为树莓派没有测量电压的方法,所以使用Arduino Nano来监测热电偶的电压。

Arduino 具有模数转换器 (ADC),可以读取电压并将其转换为 0 到 1023 之间的数字。在该项目中,Arduino 从热电偶读取电压并将该值传达给 Raspberry Pi。 Raspberry Pi 接收电压读数并对其进行解释。如果值太低,我们假设指示灯已经熄灭并发送通知。

第 1 步:准备您的 Raspberry Pi

在您的网络上启动并运行 Raspberry Pi(您可以查看我的其他项目以获取有关执行此操作的说明)。

创建一个 Python 程序,该程序将从 Arduino 接收电压读数。当电压读数过低时,程序将循环并发送通知。附上源码。

第 2 步:准备您的 Arduino

我买了便宜的中国 Arduino Nanos,所以我需要反复试验才能让它们在我的 Windows 10 计算机上运行。

用草图加载 Arduino,每 30 秒测量一次其输入引脚上的电压。 Arduino 可以测量 0 和参考电压之间的电压。可以选择 1.1V 或 5V 作为参考电压。因为热电偶最多只能输出 30 毫伏,我们将使用 1.1V 参考电压以获得更高的分辨率。 Arduino ADC 为 0V 输出 0,为 1.1V 输出 1023。如前所述,热电偶最多输出 30 毫伏,因此读数将是 28 或更少。

第 3 步:将 Arduino 连接到电压源

热电偶通过同轴线向热水器恒温器发送电压。导线外侧为正极。

在距离热水器恒温器约 5 英寸处切断电线。将同轴线的外部向后切一点,以便可以接触到中间的电线。不要破坏涂在中间电线上的任何绝缘层。我们不希望中间线短路到同轴线外面。

连接电线,使其向热水器恒温器和 Arduino 输入引脚提供正电压。我使用了输入引脚 A0。电压源的负极应连接到Arduino的地,以及热水器恒温器的负极。

我使用了 1 英尺长的电线,末端带有鳄鱼夹来进行连接。

第 4 步:将 Arduino 连接到 Raspberry Pi

我们在 Arduino 上运行的草图会将电压数从 ADC 传输到 Raspberry Pi。 Arduino 将发送信号作为其数字引脚 9 的输出。

Arduinos 以+5V 发送信号。 Raspberry Pi 只能接收 3V 输入。因此,在Arduino和树莓派之间,必须有一个分压器。这将电压从 5V 降低到 2.8V 左右。

分压器是降低输入电压的电阻系统。

输出电压由分压关系决定。

不能使用单个电阻来降低电压,因为当没有电流流动时,电阻两侧的电压将为 Vin (5V)。即使在无电流的情况下,使用分压器也会降低电压。

所有东西的地线都必须连接。见接线图。

第 5 步:Arduino 传输电压测量值

Arduino 草图每 30 秒从 ADC 获取电压测量值并将该数字传输到 Raspberry Pi。我决定使用从 Arduino 引脚 9 到 Raspberry Pi 引脚 16 的原始单线信号系统。

第 6 步:Raspberry Pi 接收电压测量值

树莓派使用了一个无限循环的Python程序来监听16脚的上升沿。当检测到上升沿时,假设Arduino已经开始传输一个数字。

信号系统
传输一个两位数的数字(例如:“12”)。每个数字前面都有一个在引脚 16 上接收到的正脉冲。间隔小于 20 毫秒 (ms) 的后续正脉冲会增加该数字的值。超过 40 毫秒的停顿表示该数字已完成,下一个数字开始。另一个超过 40 毫秒的暂停表示第二位数字已完成。整个两位数现在完成了。

在 Raspberry Pi 上运行的 Python 代码中,从 Arduino 接收到的数字是从解释来自 Arduino 的信号的方法中返回的。其他 Python 代码决定是否需要发送通知。然后,代码返回等待引脚 16 的下一个上升沿。

第 7 步:发送通知

如果电压太低,增加低计数。保持低计数以防止误报。如果低计数达到 5,则电压在 5 次测量中一直很低。每次测量间隔 30 秒。发送通知并重置低计数。使用 smtplib 和 Gmail 帐户发送通知。发送通知时,时间戳会存储在 Python 代码中。下一个通知将在 6 小时内不会发送。

为了发送文本警报,我使用了大多数手机提供商提供的功能:通过电子邮件向用户发送文本的功能。例如:Verizon:[email protected] 向该号码发送短信。

Gmail
我创建了一个新的 Gmail 帐户用于发送通知。起初,我在这个 Gmail 帐户上配置了安全设置以允许“不太安全”的访问,因此 Python 代码可以发送电子邮件。但是,几个月后,Gmail 可能会禁用这种安全性较低的访问。我发现 Gmail 更喜欢用户使用应用密码。

设置应用密码
https://support.google.com/accounts/answer/185833

第 8 步:连接一切

通过分压器将 Arduino 连接到热水器热电偶线和 Raspberry Pi。 (我的分压器的顶部使用了两个总电阻为 550 欧姆的电阻器——因为这些是我手头上的电阻器。)打开 Arduino 电源,它将开始测量电压并每 30 秒向 Raspberry Pi 发送信号。

第 9 步:运行 Python 程序

  • 创建一个脚本来启动您的 Python 程序。
  • 编辑根 crontab 以在启动时自动运行您的脚本。根据您的 Raspberry Pi 和保存 Python 程序的位置编辑目录路径。
  • 编辑 crontab:
    sudo crontab -e
  • 添加一行以在 Raspberry Pi 重新启动时运行您的“启动”脚本:
    @reboot sh /home/pi/hotwater/run_HotWaterNotifier.sh>> /home/pi/hotwater /logs/HotWaterNotifier.log 2>&1
  • 手动运行(在设置 crontab 之前)
    首先执行进程(执行 run_HotWaterNotifier.sh 脚本)
    然后输入 ctrl-Z 暂停你的进程
    然后输入 bg 一次或两次将进程发送到后台
    键入disown ,这可以让进程在您注销后继续运行
  • 查看进程是否还在运行
    ps aux | grep -i 热水


代码

  • Arduino 代码
  • Phython 代码
  • 启动 Python 代码的脚本
Arduino 代码Arduino
这每 30 秒读取一次电压并将信号发送到 Raspberry Pi
/******************************** ********************************************** HotWaterHeater 测量电压来自热水器的热电偶。使用信号将此电压传感器测量值发送到 Raspberry Pi。 ****************************************************** **************************////double ReferenceVoltage =5.0; //未使用的参考电压double ReferenceVoltage =1.1;int OUTPUT_PIN =9;int INTRA_DIGIT_WAIT=20;int BETWEEN_DIGIT_WAIT=50;//////////////////////// ////////////////////////////////////////////////// /////当您按下复位键或为电路板供电时,设置功能运行一次////////////////////////////// ///////////////////////////////////////////////无效设置( ) { // 将数字引脚 LED_BUILTIN 初始化为输出。 pinMode(LED_BUILTIN,输出); pinMode(OUTPUT_PIN, OUTPUT); // 将数字引脚 9 设置为输出模拟参考(内部); Serial.begin(9600); // 打开串口,将数据速率设置为 9600 bps}/////////////////////////////////// //////////////////////////////////////// 循环函数运行结束永远重新开始。//测量输入引脚上的电压。//然后将该读数发送到Raspberry Pi//////////////////////// ////////////////////////////////////////////////// ///void loop() { int pinInput;双倍电压; pinInput =模拟读取(A0); // 探针输入 Serial.print("PinInputA0="); Serial.print(pinInput); //Arduino ADC 是一个十位转换器,这意味着输出值范围从 0 到 1023 电压 =(pinInput * ReferenceVoltage ) / 1023; Serial.print(", voltageA0="); Serial.println(电压); //注意:读数为 5 =5.38 mV sendNumberSignal(pinInput, OUTPUT_PIN, INTRA_DIGIT_WAIT, BETWEEN_DIGIT_WAIT); //每30秒执行一次检查 delay(30000);}/********************************** ******************************************** * 在单线。 * * 对于每个数字发送一系列脉冲。 * 还有一个初始启动脉冲。 * 每个脉冲看起来像: __/ 20ms \__20ms__ * 20+20ms 在同一数字内的上升沿之间 * * 数字之间: __/ 20ms \__20ms__ 50ms___ * 数字之间 20+20+50ms ********* ****************************************************** ******************/void sendNumberSignal(int number, int pin, int intraDigitWait, int betweenDigitWait) { int tens =number/10; int 个 =数字 % 10; Serial.print("信号:"); Serial.println(number); // 调试 /////// //Serial.print("tens:"); //Serial.println(十位); //Serial.print("ones:"); //Serial.println(ones); //Serial.print("millis:"); //Serial.println(millis()); // 调试 /////// //Serial.println("send tens"); //Serial.print("millis:"); //Serial.println(millis()); //发送十位数 sendPulse(pin, intraDigitWait); for (int i=0; i 
Phython 代码Python
此代码接收来自 Arduino 的信号。它将信号解释为电压读数。然后它决定电压是否太低。如果电压太低,它会发送电子邮件和文本。
################################ ########################################### HotWaterNotifier.py#监控输入引脚并接收来自 Arduino 的信号。# 将信号解码为数字电压传感器测量值。# 当接收到的电压读数太低时,这表明#指示灯熄灭。当连续 5 次测量出现这种情况时,假设#指示灯真的熄灭了。发送电子邮件/文本并记录时间。# 仅每六个小时发送一次电子邮件/文本。## 这是为 Python 2.7 编写的。 Python 3.########################################################################################### ####################################import smtplibimport RPi.GPIO as GPIOimport osimport os.pathimport timeimport datetimeimport stringimport loggingimport sys#Input GPIO to receive signal from the ArduinoGPIO_Alert=16#emailsemailWaitHours=6#低电压传感器读数之间等待多少小时。#小于或等于这是低电压。lowSensorReading=1#一旦这么多低达到传感器读数,发送alertmaxLowVoltageCount=5#进行GPIO编号,选择BCMGPIO.setmode(GPIO.BCM)GPIO.setup(GPIO_Alert, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)lastEmailSentTime =datetime.datetime(2000,1, 1,0,0,0,0) #declare 全局变量################################# ########################################## 设置记录器。## ############################################### ##########################def setup_custom_logger(name):formatter =logging.Formatter(fmt='%(asctime)s %(levelname) )-8s %( message)s', datefmt='%Y-%m-%d %H:%M:%S') handler =logging.FileHandler('HotWaterLog.txt', mode='a') handler.setFormatter(formatter) screen_handler =logging.StreamHandler(stream=sys.stdout) screen_handler.setFormatter(formatter) logger =logging.getLogger(name) logger.setLevel(logging.DEBUG) logger.addHandler(handler) logger.addHandler(screen_handler) return logger## ############################################### ########################### 发送电子邮件/文本的功能############### ############################################### #############def send_email_alert():# 允许写入全局变量 global lastEmailSentTime # 检查自上一封电子邮件以来是否已经过去了足够的时间 nowTime =datetime.datetime.now() emailWaitDelta =datetime .timedelta(hours=emailWaitHours) limitTime =nowTime - emailWaitDelta #如果时间足够,发送电子邮件。如果 lastEmailSentTime 为 None 或 limitTime> lastEmailSentTime:logger.info('Sending email alert...') HOST ="smtp.gmail.com" PORT =587 SUBJECT ="Hot Water Heater Alert" #This 应该是一个列表对象多个地址 TO =["[email protected]", "[email protected]"] #TO =["[email protected]"] FROM ="[email protected]" PWD ="XXXXXXXXXXXXXXX" text ="在热水器上测得的低电压”#To 字段在此处连接为 1 个字符串。 #这是收件人在电子邮件中显示的内容。 BODY =string.join(("from:%s" %FROM, "to:%s" %", ".join(TO), "Subject:%s" %SUBJECT, " ", text), "\r \n") 尝试:s =smtplib.SMTP(HOST,PORT) s.set_debuglevel(1) s.ehlo() s.starttls() s.login(FROM, PWD) s.sendmail(FROM,TO,BODY) s.quit except Exception as e:logger.exception('异常捕获文件发送电子邮件。6 小时后重试') #设置时间,以便 6 小时内不发送电子邮件 lastEmailSentTime =nowTime else:logger.info('不发送电子邮件。最后一封电子邮件发送于:' + lastEmailSentTime.strftime("%Y-%m-%d %H:%M:%S"))############## ############################################### ############### 接收来自 Arduino 的信号。# 一个数字由两位数字组成。 (一个十位数字,一个个位数字)# Arduino 总是传输一个数字,由 2 位数字组成。# 接收到的信号是输入引脚上的一系列高脉冲。# waitReceiveNumber() 方法计算高脉冲并且[count -1]是#数字的值。#每个数字前面有1个脉冲。##同一数字内的信号边沿之间最大70毫秒#间隔小于70ms的上升沿是相同数字#如果更大超过 70 毫秒,然后移动到下一个数字# 200 毫秒表示数字已完成############################### ##########################################def waitReceiveNumber(GPIO_Alert ):lastSignalTime =datetime.datetime(2000,1,1,0,0,0,0) isTens=True isFirstIteration=True tensValue=0 onesValue=0 receivedEdge=None #脉冲间隔小于70ms:这还是同一个数字正在传输 #增加当前数字的值 #超过70ms:切换到下一个数字 singleDigitMilliseconds =datetime.timedelta(milliseconds=70) #如果这个超时到达,它是数字的结尾 WholeNumberWaitTime =200 # 在这里等待,直到检测到上升沿 #logger.info('Waiting on GPIO pin:' + str(GPIO_Alert)) while True:#Arduino 在您闪烁时发送一个脉冲它,第二次启动树莓派。 #如果停电,Arduino 应该启动得更快。 if isFirstIteration:receivedEdge =GPIO.wait_for_edge(GPIO_Alert, GPIO.RISING, timeout=-1) #永远等待直到一个启动脉冲 else:receivedEdge =GPIO.wait_for_edge(GPIO_Alert, GPIO.RISING, timeout=wholeNumberWaitTime) #wait for最多 waitTime ms #计算此信号的计时指标 signalTime =datetime.datetime.now() signalInterval =signalTime - lastSignalTime lastSignalTime =signalTime #debugging:logger.info('signalInterval:' + str(signalInterval.total_seconds() * 1000 )) #确定要增加的数字 if (signalInterval =singleNumberMilliseconds:if isTens:#shift to one isTens =FalseonesValue+=1 else:#isOnes #can't shift to next digit, so the number is complete. #这不应该发生。一旦数字完成,#the wait 应该超时并且 receivedEdge 应该是 None。 return ((tensValue -1)*10) + (onesValue -1) else:#timeout,所以数字是完整的。 return ((tensValue -1)*10) + (onesValue -1)################################ ###########################################主要方法# ############################################### ##########################def main():logger.info('Starting HotWaterNotifier') referenceVoltage =1.1 lowVoltageCount=0 尝试: while True:#This 将阻塞,直到它收到来自 Arduino 的信号。 #它只会在收到完整的数字后返回。 sensorReading =waitReceiveNumber(GPIO_Alert) #从Arduino传感器读取电压计算电压=(sensorReading * referenceVoltage)/1023; logger.info('sensorReading:' + str(sensorReading) + ', voltage:' + str(voltage)) if sensorReading <=lowSensorReading:lowVoltageCount+=1 #increment if lowVoltageCount>=maxLowVoltageCount:logger.info('低电压警报') send_email_alert() lowVoltageCount=0 #重置计数器,因为我们发送了一个警报 else:lowVoltageCount=0 #重置计数器,因为除了KeyboardInterrupt 之外收到了良好的电压:logger.info('Keyboard interrupt received') GPIO.cleanup() # CTRL+C 清除GPIO exit GPIO.cleanup() # 清除GPIO############################## ################################################ 考试电子邮件方法############################################# ############################def testEmail():logger.info('Starting HotWaterNotifier') referenceVoltage =1.1 lowVoltageCount=0 try:send_email_alert() except KeyboardInterrupt:logger.info('Keyboard interrupt received') GPIO.cleanup() # 在CTRL+C 上清理GPIO exit GPIO.cleanup() # 清理GPIO######## ############# ############################################### ##########一个全局变量################################## ######################################### 设置日志文件记录器 =setup_custom_logger ('HotWaterNotifier')######################################### ################################## 调用 main 方法。## 在这里调用 testEmail() 如果你想测试电子邮件功能。######################################## ##################################if __name__=="__main__":main()
启动 Python 代码的脚本SH
这是crontab调用启动Python代码的脚本
#!/bin/bash# run_HotWaterNotifier.sh#启动notifiercd /home/pi/hotwatersudo python HotWaterNotifier.py

制造工艺

  1. 使用 Moteino 和 Raspberry Pi 监测室温
  2. 使用 Arduino 制作流光溢彩监视器
  3. 使用 Arduino 的太阳能电池板实时数据采集
  4. 用 Arduino 捕捉水滴
  5. 如何构建 Arduino 能源监视器和数据记录器
  6. 使用物联网的心率监测器
  7. Arduino 温度。使用 3.2 显示的监视器和实时时钟
  8. 可定制的盖革穆勒计数器
  9. 运动感应水枪
  10. 完美的热泵热水
  11. 如何选择最好的家用热水泵?
  12. 热水泵简介