热门资讯
猫粮自动分配器
来源:3XMaker 发布时间:2018年08月24日猫粮自动分配器
它通过提供每日猫食量,在预设时间自动为宠物提供食物。
养宠物需要承担很大的责任,首先是给他们食物;不幸的是,繁忙的生活方式和强制的工作时间并不能满足我们四脚朋友的需要,而且任何靠自己生活的人都很难按时提供宠物餐。为了解决任何宠物主人,特别是猫和狗主人都非常重视的问题,我们设计了一种称为Felixmatic的设备:它是一种实用的自动干食分配器,为猫(或小狗)配备了一个大容量容器,可以很容易地从顶部打开,当它是一个碗收集kibble时,它是PPLIDE。我们知道我们已经可以在市场上找到自动售货机,但是,我们的例子是独特的,因为它可以编程为每天9餐,以提供非常精确的数量的干粮。
项目
分配器的工作方式比市场上的普通产品更为复杂和完整,事实上,它不仅提供食物,而且还提供我们确定的确切剂量;基本上,在预先设定的时间,容器底部的耳蜗会转动,并在碗中滴下一定量的kibble,由专门的卫士进行调节。右侧传感器。
为了实现这一功能,我们的点胶机由一个机械部分和一个电子部分组成;前者由PLA、3-D打印部件组装而成,而电子部分由一个Arduino UNO板组成,我们在该板上应用了一个RTC屏蔽,一个带LCD显示屏的特定屏蔽,一个连续旋转的模型。伺服和称重传感器;后者用于称重干燥食物的量,一旦达到所需的量,伺服操作耳蜗停止。LCD显示器通过Arduino板的插脚8、3、5、6、7进行管理;相反,称重传感器通过A0插脚进行读取,它本身提供模拟信号。为了设计简单,我们决定使用专门用于测量和重量显示的屏蔽,如图所示与Arduino UNO Rev.3接口,并连接到称重传感器。这个被称为重量防护罩的防护罩安装了一个8个字符的2行液晶显示屏,在我们的项目中,它被用来安装机器。除显示器外,我们还集成了INA125,一种专门为测量仪器(如天平)开发的高精度放大器。我们将在这个屏蔽上焊接键连接,这将遵循这些页面上提出的接线图(图1),显示与称重传感器的连接(我们已经为这些连接提供了一个接线板)。
如你所见,五个常开的键必须连接到公共接地,电阻的刻度,因为我们将使用A/D转换器读取它们以保存Arduino的线路;基本上,由Arduino的5 V供电的多个分频器在A2模拟线路上输出8 V,。
0V for P1;
1,7V for P2;
2,53V for P3;
2,92 for P4;
3,26V for P5.
图 1
称重传感器的重量可达1.000克,其主体由铝合金制成;输出灵敏度为1 mV/V(±0.15 mV),非线性(满刻度)为0.05%;满刻度滞后为0.05%。在10°C的满刻度下,由于热推导产生的误差为0.05%。电池的输入电阻为1千欧(±10欧姆),与输出电阻相同。绝缘电阻为2.000 mohm,工作温度范围为-10°C至+55°C。为了连接称重传感器,有四根电线:
rad为正(5伏);
黑色为负(GND);
绿色是OUT +;
白色是OUT–。
四根电线必须延伸到重量护罩右侧的接线板上。
固件
#include <LiquidCrystal.h>来管理LCD 8×2监视器
#include <EEPROM.h>在eeprom中写入一些值
#include <Wire.h>与RTC的接口
#include <DS1307RTC.h>管理rtc
#include <TimeLib.h>方便管理已用时间
让我们来看一下代码中的主要变量和函数,这样您就可以轻松地为其他目的定制项目。
为了管理称重传感器检测到的值,我们包括5个变量,其中4个变量用于校准称重传感器本身:
loadA 净重量(皮重,单位:克);
AnalogvalA 称重传感器读取的与load相关的克数相对应的类似物的重量;
loadB任何载荷的重量(单位:g);
AnalogvalB称重传感器读取的与克数相对应且与loadB相关的模拟值重量;
第五个变量是模拟值average,它将包含使用称重传感器测量的有效重量的结果,即净重,对应发行的kibble克数。注意,loada是用来计算皮重的,这使得分配器可以将kibble的设定重量减去皮重,放到碗中。
在固件中,还有两个数据阵列:
MealHour[10]
MealMinute[10]
如你所见,这些阵列包含食物的分配时间,并将在每次打开分配器时进行计算。在此阶段中,草图将初始化串行端口(通过该端口,您可以使用PC监视程序调试)和LCD。之后,它将调用函数 ResetMeals() and Initialize().
reset meals()函数重置与进餐分配相关的存储单元:在EEPROM(其结构如表1所示)中,通过设置一个标志来设置有效进餐分配,该标志在每天00.00恢复为零,再次由reset meals()函数设置,因此允许重新开始一天的进餐周期。
函数initialize()调用其内部的其他函数:
reset()
load()
sort()
函数reset()允许重置数组mealhour[]和mealminute[],以确保这些变量没有错误的值。
load()例程负责从eeprom中获取值,并将其复制到作为参数传递的数组中。
最后,sort()函数负责使用算法(冒泡排序)对数组进行排序,当我们希望确保进餐时间由分配器自动管理时,它非常有用,即使它们是随机存储的,而不是以增加的方式存储的,因此确保您的宠物在正确的时间吃饭。
分配器工作核心的最后一个功能称为supply():它是一个功能,当调用时,根据称重传感器检测到的重量来管理伺服;换句话说,例程命令伺服向上旋转,直到称重传感器向Arduino提供与DoS对应的重量相等的读数。e待供应,然后停止伺服。此后,伺服旋转输出螺旋并停止它,这样当供给必须停止时,它就像一个分隔器阻止了kibble。
在这个例行程序中,还有一个函数unjam()用于取消供应机构的平衡,以防某些kibble卡在节流孔中并阻止其旋转;通过使节流孔在一个方向旋转五次,在另一个方向旋转五次来尝试解锁。如果操作完成后,食物仍有库存,系统将在LCD上显示错误消息;如果食物用完,也会发生同样的情况,并且LCD上会显示另一个错误消息。由于kibble用完或供给机构卡住而导致的供给缺失都以同样的方式检测到:在发送分配命令后的几分钟内没有净重。
用户界面
现在,让我们来看看用户界面,它由五个键和安装在重量保护板上的显示器组成,键的功能如下:
P1(向下按钮):用于向下滚动菜单;
P2(OK按钮):用于确认选项;
P3(减少按钮):用于减少用餐次数;
P4(减少按钮)用于增加用餐次数;
P5(分配按钮);只能在初始屏幕中使用(图2),此键用于手动分配kibble,无论何时我们想要添加超过预设剂量的食物,或随时供应食物。
启动系统后,您将看到主屏幕(图2),第一行显示当前时间(如果显示00:00:00,则必须配置时间;我们将在下面看到如何操作);第二行显示单词push,箭头朝下:表示我们将继续配置分配器的功能字符。特性。当我们看到这个屏幕时,我们可以按P5手动分配kibble,并决定剂量。
现在,您将看到菜单有两个选项:膳食和克(图3)。如果按两次键,返回命令(图4)将带您返回主屏幕。
使用键选择“Feeds”(膳食)选项,将打开一个菜单(图5),您可以在其中选择要为您的猫提供的膳食数量,最多每天9顿。
要选择用餐数量,请使用指针停留在第一行,然后按下减少键(P3)以减少用餐数量。您可以按“增加”键(之前),这将增加一天的用餐次数。按OK确认(P2)。要返回主屏幕,请单击“上一步”保留以前的设置。按下OK(p2)后,您将返回上一个子菜单;这用于设置进餐时间(图6)。选择餐数后,我们可以继续并指示分发kibble的时间和分钟数。例如,如果我们一天选择三顿饭,图6中的屏幕将显示三次,每顿饭一次;对于每个屏幕,我们必须指示分发食物所需的时间。
综上所述,为了在分配器上设置显示时钟,放置在按键上,您必须将指针放在第一行,然后您可以按“增加或减少”键来增加或减少与时间相对应的数字,直到您想要的时间为止。要修改分钟数,请按“确定”,然后再次按“减少”或“增加”以使用相同的步骤选择分钟数。选择小时和分钟后,按向下移动第二行上的指针,然后按OK确认并保存确切时间。完成时间设置后,可以返回图2所示的主屏幕。要设置每顿饭的克数,请按向下键;这样您就可以进入主菜单。再向下按一次,将指针移到克数的第二行(图7),然后按OK。打开子菜单(图8)设置每顿饭的克数后,可以按“增加”或“减少”来调整体重。
一旦你决定了每餐食物的重量(即克数),如图9所示,移动第二行的指针,按OK保存设置。如果您不想确认新的设置,请使用指针向下滚动,直到回到上一步,然后按OK返回上一个菜单(图9)。
机械结构
既然我们已经解释了系统的工作原理,我们就可以进入组装阶段:电子部分放在基座上,三维打印作为机械结构的其余部分。在底座中,我们将Arduino、护罩和钥匙放置在专用隔间的右侧,如图1所示进行连接,并将其安装在盖子上,使用小的自螺纹2.5×10 mm金属螺钉固定;盖子上印有五个钥匙的孔和显示器的窗口。仍然在底座内部,在实际分配器下方的部分,您将使用两个螺钉将大理石板固定到称重传感器上,然后必须将哪个传感器应用到底座上;在移动板上,您将放置收集Kibble的碗。
后者是3-D打印,但你也可以自己使用,前提是它的底座比放置在称重传感器上的移动板小(直径),并且它足够短以避免接触结构的其余部分。事实上,重量并不重要,正如本文开头所解释的,固件计算皮重,然后将皮重减去将kibble放入碗中时检测到的重量。图10所示为块,图11所示为结构的分解图,图12所示为机构的内部视图,尤其是关于基于伺服机构作用的螺旋元件的Kibble分配机构的内部视图。
请注意,通过一个3D打印圆适配器,用两个螺钉将固定碗的移动板应用到称重传感器臂上。列表1显示允许设置供应时间的固件部分。在那一方面,清单2显示了管理Kibble分配的固件部分:它是用于供应食物的功能。
List1
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 | void SetOra(int i) { char bottone[8]; int posCursor=0, opcMenu=-2; int Ore=0,Minuti=0; int flag=0; int NO=1,NM=10; lcd.clear(); lcd.setCursor(2,0); stampa(Ore); lcd.setCursor(4,0); lcd.print(“:”); lcd.setCursor(5,0); stampa(Minuti); lcd.setCursor(2,1); lcd.print(“ok”); do{ strcpy(bottone,”null”); LeggiBottone( bottone, A2, 200); lcd.setCursor(0, posCursor); lcd.write(byte(0)); if(!strcmp(bottone,”giu”)) MuoviCursore(&posCursor, 1, ‘m’); else if(!strcmp(bottone,”ok”)||!strcmp(bottone,”incr”)||!strcmp(bottone,”decr”))
opcMenu = posCursor; switch( opcMenu ) { case 0: if(!strcmp(bottone,”incr”)) { if(flag==0){ Ore=Ore+1; if(Ore>= 25) Ore--; lcd.setCursor(2, 0); stampa(Ore); } else{ Minuti=Minuti+1; if(Minuti >= 60) Minuti--; lcd.setCursor(5, 0); stampa(Minuti); } } else if( !strcmp(bottone,”decr”) ) { if(flag==0){ Ore=Ore-1; if (Ore <= 0) Ore++; lcd.setCursor(2, 0); stampa(Ore); } else{ Minuti=Minuti-1; if(Minuti <= 0 ) Minuti++; lcd.setCursor(5, 0); stampa(Minuti); } } else if(!strcmp(bottone,”ok”)) { if(flag==0) flag=1; else flag=0; } opcMenu = -2; break; case 1: if(!strcmp(bottone,”ok”)){ EEPROM.update(NO+i,Ore); EEPROM.update(NM+i,Minuti); opcMenu = -1; } break; }; }while(opcMenu != -1); mem=1; } |
如您所见,计数器变量检查尝试丢弃食物的次数;如果达到5,它将提供错误消息,因为这意味着机制有问题或容器为空。
List2
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 | void eroga(){ float load; int analogValue; float flag=0; contatore=0; int val = word(EEPROM.read(19), EEPROM.read(30)); do { analogValue = analogRead(A1); analogValueAverage = 0.99*analogValueAverage + 0.01*analogValue; unsigned long currentMillis = millis(); if(currentMillis - previousMillis2 > interval2){ previousMillis2 = currentMillis; load = analogToLoad(analogValueAverage); if(currentMillis - previousMillis5 > interval5){ previousMillis5 = currentMillis; Serial.println(“copio flag”); flag=load; } if(currentMillis - previousMillis4 > interval4){ previousMillis4 = currentMillis; Serial.println(“controllo se blocca”); if(load<=flag+1 && load>=flag-1) sblocca(); if(contatore>=5){ servo.detach(); lcd.clear(); lcd.setCursor(1,0); lcd.print(“ERRORE”); lcd.setCursor(0,1); lcd.print(“!!!!!!!!”); while(1){} } } servo.attach(9); servo.write(0); } }while(load <= val); servo.detach(); } |
在这两种情况下,您都需要照顾它,因为机器不提供食物,而且……您的宠物的肚子会隆隆作响!!
结论
对于任何宠物主人来说,我们的自动售货机都是一个有用的好主意,尤其是整个系统都是基于现有的Arduino,这使得一切变得简单。我们建议的机制不具有约束力,因为任何拥有3-D打印机的人都可以根据需要采用商用分配器。
然而,该系统可以适应其他用途,而不是严格地指给宠物喂食:它可以用来供应各种物质,也可以……通过提供少量的糖和烟来避免一些不良习惯,例如过度消费糖和烟……
总之,它是一个定时分配器,可以很容易地定制,这里看到用于供应食物,但也能够管理许多其他事情。