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

Arduino 供电的水壶

组件和用品

SparkFun Arduino Pro Mini 328 - 5V/16MHz
× 1
防水超声波传感器
× 1
实时时钟 (RTC)
× 1
SparkFun 共阴极 4 位 7 段显示器
× 1
蜂鸣器
× 1
SparkFun 按钮开关 12mm
× 1
通用晶体管 NPN
× 1
锂离子电池 1000mAh
× 1
Adafruit USB 锂离子电池充电器
× 1
电阻 221 ohm
× 8
电阻 1k ohm
× 4
电阻 4.75k ohm
× 2

必要的工具和机器

烙铁(通用)
热胶枪(通用)

应用和在线服务

Arduino IDE

关于这个项目

简介:

喝足够的水对我们的健康非常重要。多喝水可以使皮肤更干净,整体健康状况更好,生产力和大脑功能得到改善,能量水平增加,甚至体重减轻。

在我们忙碌的生活中,真的很难记住要喝足够的水。大多数时候,无论是在家里、办公室还是在路上,我们都会忘记喝足够的水。大约 75% 的美国人一直处于慢性脱水状态。

因此,为了养成健康的饮水习惯,每天跟踪您的饮水量非常重要。

为了跟踪我的饮水量,我使用 Arduino 使我的水瓶变得智能。它可以:

1. 追踪我每天的饮水量

2. 追踪我每周的平均饮水量

3.提醒我喝水

4. 追踪上次摄入时间

5. 一次充电可运行一个月以上。

制作RTC模块

要记录或跟踪取水信息,需要将当前时间和日期信息与累积数据一起存储。实时时钟 (RTC) 芯片(例如 DS1307 和合适的备用电池)可用于提供所需的信息。 RTC芯片(在软件中)的编程过程也非常简单,大多数编程环境都支持。

这是基于流行的 RTC IC DS1307 的紧凑型 RTC 模块的设计,适用于您的日常微控制器项目。 DS1307 串行实时时钟 (RTC) 是一种低功耗、全二进制编码十进制 (BCD) 时钟/日历加上 56 字节的 NV SRAM。地址和数据通过 I2C 双向总线串行传输。 24 小时/12 小时格式时钟/日历提供秒、分、小时、日、日、月和年信息,包括闰年的更正。

让我们根据所附原理图制作实时时钟模块。 DS1307 RTC 需要外部晶振才能正常工作。 IC 的 SCL 和 SDA 引脚需要两个上拉电阻。电阻的值可能在 2k 到 10k 左右。我用了 4.7k。在焊接过程中,我试图使模块尽可能小,因为我的电路空间有限。您可以使用 DS3231 代替 DS1307,并且该 IC 具有内部晶体振荡器。因此,您无需添加任何外部晶体。如果您不喜欢自己制作,也可以购买现成的微型 RTC 模块。由于整个系统将由电池供电,因此我将 RTC 的 VBAT 引脚接地,而不使用纽扣电池。

DS1307 的重要引脚:

  • 5V 引脚 :当此脚为高电平时,ds1307发送数据,为低电平时,运行在备份纽扣电池上。
  • :这是模块的接地引脚。电池的接地和电源都连接在一起。
  • SCL :它是 I2C 时钟引脚 - 与微控制器通信。应与 Arduino SCL 引脚连接。
  • SDA :它是 I2C 数据引脚 - 与微控制器通信。应与 Arduino SDA 引脚连接。
  • VBAT :任何标准 3V 锂电池或其他能源的电池输入。不使用时必须接地。

制作七段显示板

对于这里的显示模块,我使用了一个独立的紧凑型共阴极模块,包含四个 7 段 LED 数字显示器,适合显示带有一些简单字符的数字数据。

显示模块中的每个部分都是多路复用的,这意味着它共享相同的阳极连接点。并且模块中的四位数字中的每一个都有自己的共阴极连接点。这允许单独打开或关闭每个数字。此外,这种多路复用技术将控制显示器所需的大量微控制器引脚变成了 11 或 12 个(而不是 32 个)!

当由 5 V 逻辑引脚供电时,显示器的 LED 段需要限流电阻器。对于 5 V,电阻器的值通常在 330 到 470 欧姆之间。对于锂离子电池操作,它可能是 220 欧姆。而且,建议驱动晶体管为 LED 段提供额外的驱动电流,因为微控制器的每个引脚只能提供或吸收接近 40 mA 的电流。当显示屏的所有(七)段同时打开(数字 8)时,电流需求将超过 40 mA 限制。下图为限流电阻和驱动三极管的基本接线图。

这个 4 位 7 段显示器部分连接四个共阴极 7 段 LED 显示器和四个 2N2222 NPN 晶体管。 1K电阻用于基极限流,220R电阻限制LED显示屏段的工作电流。

在Arduino板中,D10到D17的数字输出用于驱动段(a到g&dp),数字输出D6到D9用于4×7 LED显示屏的数字(D0-D3)。

显示模块增加了按钮开关以访问不同的选项。它还将用于使用外部硬件中断将 Arduino 从睡眠模式唤醒。因此,按钮连接到 Arduino 数字引脚 #2 (INT0)。

连接显示板与 Arduino Mini Pro

根据之前提供的示意图将所有段引脚焊接到 Arduino 迷你引脚。然后将 4 个公共引脚焊接到晶体管的集电极引脚。晶体管的基极连接到 Arduino 引脚。连接显示器后,将按钮开关与 Arduino 数字引脚 2(INT 0)连接。确保将按钮连接到 Arduino 引脚 2,因为我们将使用此按钮实现外部硬件中断以将 Arduino 从睡眠模式唤醒。

连接 RTC 模块和蜂鸣器

现在,将您之前制作的 RTC 模块连接到 Arduino 板。模块的 SDA 引脚必须连接到 Arduino 引脚的 SDA(A4)引脚,模块的 SCL 引脚必须连接到 Arduino 的 SCL(A5)引脚。然后将蜂鸣器连接到Arduino板。

连接:

RTC ------> Arduino Mini Pro

  • SDA ------> A4
  • SCL ------> A5
  • 蜂鸣器------> D3

安装带瓶盖的超声波传感器

如图所示,在瓶盖上打一个洞。将超声波传感器的四根线从孔中取出,将超声波传感器固定在瓶盖中间。传感器必须安装在瓶盖内侧,并置于中心位置。

连接:

超声波传感器------> Arduino Mini Pro

  • VCC ------> VCC
  • 地线------>地线
  • 触发器------> D4
  • 回声 ------> D5

上传程序和测试

完成所有连接后,就可以将程序上传到 Arduino 板并测试功能。您将需要几个库才能使程序正常工作。对于按钮接口,您需要添加 OneButton 库。由于设备将使用电池供电,因此功耗是一个重要问题。我为我的 Arduino 草图实现了睡眠模式。看门狗定时器和外部硬件中断用于将 Arduino 从睡眠模式唤醒。 Arduino 读取传感器读数 3 次,取平均值并计算必要信息并显示信息 10 秒,然后进入睡眠模式 1 分钟。它会在按下连接到 INT0(数字引脚 2)的按钮时随时唤醒。因此,如果您想查看有关进水量的信息,请随时按下选项按钮。它会为你醒来。如果不按任何按钮,它将每 1 分钟读取一次。为了实现睡眠模式,我使用了 Arduino 低功耗库。对于从 DS1307 RTC 模块读取时间,我使用了 DS1307RTC 库。因此,为了编译附加程序,将所有库添加到您的环境中。

我这里只简单介绍一下计算算法。有关完整草图,请参阅随附的填充。计算是根据五个传感器读数的平均值完成的,以使其足够准确。每日阅读在 24 小时重置,为新的一天阅读新书做好准备。

平均水摄入量是根据前 7 天每日摄入量的平均值得出的。 2 小时未喝水,每 15 分钟发出两声提示音,喝水后 2 小时内停止。

下载随附的代码并将其上传到您的 Arduino Mini Pro。连接所有模块并通电以测试所有组件是否正常工作。如果显示器显示一些结果,那么恭喜!你已经完成了艰难的事情。

用瓶盖固定 Arduino

使用热胶将 Arduino mini 连接到瓶盖的上侧。请记住,您必须将所有组件固定到瓶盖中。添加足够的胶水,使其紧贴瓶盖。

连接电池和充电器模块

现在,将锂离子电池固定在 Arduino 的顶部。小心使用任何开路引脚将电池短路。然后将充电器模块与盖子连接。保持 USB 端口易于从外侧接触到,以便轻松连接到充电器。

使所有电路防水

在连接所有组件和模块后,是时候让我们的设备完全防水了。这是非常重要的,因为它是水瓶,任何时候都有水滴到电路中并可能损坏电路。为了使其完全防水,在没有 USB 端口的电路的每个外部部分添加足够的胶水。你可以用胶水把盖子改成原来的盖子圆。

请勿将瓶盖浸入水中。

享受它

代码

  • Arduino 草图
Arduino SketchArduino
// 使用通过 I2C 和 Wire 连接的 DS1307 RTC 的日期和时间函数 lib#include #include #include #include #include " LowPower.h"#include "OneButton.h"OneButton button(2, true);const byte interruptPin =2;volatile int state =0;const int trigPin =4;const int echoPin =5;int piezoPin =3;const int digit[4] ={9,6,7,8};int digit_value[4];int digit_value1[4];int button_press_count =1;const int segment[8] ={16,10,12,14,15, 17,11,13};const 字节数[10][8] ={{1,1,1,1,1,1,0,0}, //0 {0,1,1,0,0, 0,0,0}, //1 {1,1,0,1,1,0,1,0}, //2 {1,1,1,1,0,0,1,0}, / /3 {0,1,1,0,0,1,1,0}, //4 {1,0,1,1,0,1,1,0}, //5 {1,0,1 ,1,1,1,1,0}, //6 {1,1,1,0,0,0,0,0}, //7 {1,1,1,1,1,1,1 ,0}, //8 {1,1,1,1,0,1,1,0}}; //9const byte d[8] ={0,1,1,1,1,0,1,1};const byte a[8] ={1,1,1,0,1,1,1,1 };常量字节r[8] ={0,0,0,0,1,0,1,1};常量字节t[8] ={0,0,0,1,1,1,1,1 };int 秒、分钟、小时;int water_in_ounch[15];int water_intake_ounch[15];int water_intake_days[7];int water_intake_times =0;int previous_water_amount =0;int total_water_intake_today =0;int average_intake_last_inatke_day =0;int 1;浮动average_water_level =0; //存储多次读数的平均值int water_amount_in_ounce =0; //存储计算出的水量int idle_time =0;int Intake_day =1;int previous_value =0;void setup() { Serial.begin(9600); pinMode(interruptPin, INPUT_PULLUP); // 把你的设置代码放在这里,运行一次: for(int i=6; i<=17; i++) pinMode(i, OUTPUT); pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); button.attachClick(pressed); button.attachDoubleClick(双击); button.attachLongPressStart(longPressStart); button.attachDuringLongPress(longPress);}long previous_state =millis();int count =1;int daily_intake =0;intweekly_intake =0;long sleep_time =millis();void loop() { read_time(); button.tick(); // 继续观察按钮:calculation();每日摄入量 =total_water_intake_in_day();每周摄入量 =average_water_intake_last_week(); if(button_press_count ==1){ display_d();显示数量(每日摄入量); } else if(button_press_count ==2){ display_a(); display_number(weekly_intake); } else if(button_press_count ==3){ display_r();显示数量(水量in_ounce); } else if(button_press_count ==4){ display_first_2(hours); display_last_2(分钟); } if(idle_time>=120){ alert();警报(); } if((millis() - sleep_time)>=15000){ display_off(); attachInterrupt(digitalPinToInterrupt(interruptPin),空白,下降); LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); detachInterrupt(digitalPinToInterrupt(interruptPin)); sleep_time =毫秒(); } }void display_digit(int digit){ for(int i=0; i<8; i++){ digitalWrite(segment[i], number[digit][i]); } }void display_number(int number){ int i=0; while(number>0){ digit_value[2-i] =number%10;数字 =数字/10;我++;数字写入(数字[1],高);数字写入(数字[2],低);数字写入(数字[3],低);显示数字(数字值[0]);延迟(5);数字写入(数字[1],低);数字写入(数字[2],高);数字写入(数字[3],低);显示数字(数字值[1]);延迟(5);数字写入(数字[1],低);数字写入(数字[2],低);数字写入(数字[3],高);显示数字(数字值[2]);延迟(5);数字写入(数字[3],低);数字值[0] =0;数字值[1] =0;数字值[2] =0; }void display_first_2(int number){ digitalWrite(digit[2], LOW);数字写入(数字[3],低);国际我=0; while(number>0){ digit_value[1-i] =number%10;数字 =数字/10;我++;数字写入(数字[0],高);数字写入(数字[1],低);显示数字(数字值[0]);延迟(3);数字写入(数字[0],低);数字写入(数字[1],高);显示数字(数字值[1]);延迟(3); }void display_last_2(int number){ digitalWrite(digit[0], LOW);数字写入(数字[1],低);国际我=0; while(number>0){ digit_value1[1-i] =number%10;数字 =数字/10;我++;数字写入(数字[2],高);数字写入(数字[3],低); display_digit(digit_value1[0]);延迟(3);数字写入(数字[2],低);数字写入(数字[3],高); display_digit(digit_value1[1]);延迟(3); }void display_d(){ digitalWrite(digit[0], HIGH); for(int i=0; i<8; i++){ digitalWrite(segment[i], d[i]); } 延迟(5);数字写入(数字[0],低); }void display_a(){ digitalWrite(digit[0], HIGH); for(int i=0; i<8; i++){ digitalWrite(segment[i], a[i]); } 延迟(5);数字写入(数字[0],低); } void display_r(){ digitalWrite(digit[0], HIGH); for(int i=0; i<8; i++){ digitalWrite(segment[i], r[i]); } 延迟(5);数字写入(数字[0],低); } void display_t(){ digitalWrite(digit[0], HIGH); for(int i=0; i<8; i++){ digitalWrite(segment[i], t[i]); } 延迟(5);数字写入(数字[0],低); }void display_off(){ digitalWrite(digit[0], LOW);数字写入(数字[1],低);数字写入(数字[2],低);数字写入(数字[3],低); for(int i=0; i<8; i++){ digitalWrite(segment[i], LOW); } 延迟(5); }void read_time() { tmElements_t tm;如果(RTC.read(tm)){秒=tm.Second;分钟 =tm.Minute;小时 =tm.Hour; } }int distance_in_cm(){ 持续时间长,厘米; // 传感器由 10 或更多微秒的高脉冲触发。 // 预先给出一个短的低脉冲以确保一个干净的高脉冲:digitalWrite(trigPin, LOW);延迟微秒(2);数字写入(触发引脚,高);延迟微秒(10);数字写入(trigPin,低); // 从传感器读取信号:一个高脉冲,其 // 持续时间是从发送 ping 到接收到物体的回声的时间(以微秒为单位)。持续时间 =脉冲输入(echoPin,高); // 将时间转换成距离 cm =microsecondsToCentimeters(duration);返回厘米; }long microsecondsToCentimeters(long microseconds) { // 声速为 340 m/s 或每厘米 29 微秒。 // ping 传出和返回,因此要找到 // 对象的距离,我们取走行距离的一半。返回微秒/29/2; }void alert(){tone(piezoPin, 2000, 50);音调(piezoPin, 2000, 200); //延迟(10); }void blank() { //tone(piezoPin, 2000, 100); //state++;}// 当 button1 被按下 1 次时将调用这个函数(并且没有 2. 按钮按下之后)。void press() { //Serial.println("Button 1 click."); button_press_count++;警报(); if(button_press_count ==5){ button_press_count =1; }} // 点击// 当 button1 在短时间内被按下 2 次时将调用此函数。void doubleclick() { Serial.println("Button 1 doubleclick.");} // doubleclick// 此函数将void longPressStart() { Serial.println("Button 1 longPress start");} // longPressStart// 这个函数会经常被调用,当button1被按下时很长一段时间.void longPress() { Serial.println("Button 1 longPress..."); water_intake_ounch[water_intake_times - 1] =0; //忽略最后一个值} // longPressvoid calculate(){ float water_level =0;// 每一步都存储级别 int read_value =0; //以厘米为单位读取传感器读数 for(int i=0; i<5; i++){ //取五个读数 read_value =distance_in_cm(); if(read_value>16 || read_value<3){// 读数不稳定返回; //返回调用函数,因为读取不稳定 } else if(read_value<=16 &&read_value>=3){//有效值 water_level =water_level + read_value; } 延迟(10); } average_water_level =17 - water_level/5; //从五个读数中求平均值,17 =botole height water_amount_in_ounce =int(average_water_level*1.87);//16 cm 水位 =30 ounch if(water_intake_times==0){ previous_water_amount =water_amount_in_ounce; water_intake_times =1; } if((water_amount_in_ounce  previous_water_amount){ //重新加水 //这里重新加水 previous_water_amount =water_amount_in_ounce; } else if(water_amount_in_ounce ==previous_water_amount){ //没有水消耗或重新填充 idle_time+=1; } if(hours==23 &&minutes==59){ // 一天结束,新一天的所有值从零开始 for(int i=0; i<15; i++){ water_intake_ounch[i] =0; } water_intake_times =0;摄入_天++; if(intake_day==8){intake_day =1; } }}int total_water_intake_in_day(){//计算一天的总饮水量 total_water_intake_today =0; for(int i=0; i 

示意图


制造工艺

  1. 草坪洒水器
  2. 洗碗机
  3. 水枪
  4. 厕所
  5. 消防栓
  6. 绝缘瓶
  7. 洗发水
  8. 石膏板
  9. 集成电路
  10. 皮划艇
  11. MOSMusic