CatYou-远程宠物投食器
CatYou-远程宠物投食器

CatYou-远程宠物投食器

目录

CatYou,一款针对宠物照顾问题的物联网解决方案。有助于主人不在家无法远程喂养猫的困扰,而且可以及时收集猫的身体状况数据,经过专业社区内宠物医生的分析以便给主人更好的宠物健康报告,让养宠更简单、更舒心。

问题陈述

爱猫人士可能经历的最糟糕的事情之一就是失去他们心爱的猫。

当我们考虑猫的疾病和死亡时,一个重要的事情是猫非常善于隐藏自己的疾病作为生存措施,这让猫在任何人意识到之前就生病了很长时间。对于那些白天和猫在一起并且没有注意到体重减轻、脱落、睡得更多或毛发暗淡等细微变化的人来说尤其如此。随着我们的猫变老,我们可能认为体重减轻、活动减少和/或嗜睡等症状是由于它们随着年龄的增长而减慢,而不是由于疾病。

此外,饮食失调也可能对猫的健康产生不良影响。宠物猫的肥胖是一个日益严重的问题。宠物猫的肥胖不仅会影响它们的外表和动物福利,而且额外的体重和多余的脂肪也会导致许多健康风险,如肝病、糖尿病、呼吸障碍、体力消耗引起的疼痛,甚至缩短宠物的寿命。而且,近年来家庭宠物猫的饲养越来越精细,主人也越来越意识到猫的饮食习惯和体重之间的关系。另一种饮食失调,即食欲不振,可能来自药物、糖尿病、肾脏疾病、胰腺炎、肠胃问题、免疫疾病、癌症、接触有毒物质、压力或环境或食物的变化等。

猫迫切需要有健康监测来追踪它们的雕像,以确保它们的安全。

市场同类产品对比与分析

这些年来,人们发明了猫喂食器以拯救无法每天在家喂猫的主人。 上料机实际上主要有3种,包括自动重力机、自动上料机和智能上料机。 但他们到目前为止做了什么?

虽然重力装置很容易添加猫粮,但食物会不断落入托盘供猫吃,这会导致肥胖。 暴露出来的食物也会发霉,吃起来不健康。 另一件事是它没有准确记录猫吃的食物。

自动机器比以前的机器工作得更好,因为它可以固定数量和固定时间喂猫,但是它不会提供其他功能来满足铲屎官额外关于检测的需求

我们的CatYou完美的解决这些问题,比如记录摄入量,允许远程控制,而且我们的解决方案还将涵盖其他独特的健康检测功能!

主人在工作的同时,难免会关心家中宠物的安全和健康,每天给猫咪量体温和体重很麻烦。

所以一些宠物主人经常无法告诉猫的健康状况,以及它是否过度喂食,喂食不足甚至感冒,直到为时已晚,因为宠物无法为自己说话。 但在目前的状态下,检测猫的健康状态几乎没有物联网解决方案。

考虑到所有这些因素,我们决定构建一个物联网设备来“拯救”这些“留守”的猫。

针对用户

该产品的针对用户是猫主人。

正如我们之前提到的,随着社会和工作压力的增加,越来越多的独居年轻人选择养宠物陪伴,这大大缓解了他们的孤独感。

他们需要我们的设备的原因是他们关心被遗忘的猫的健康。

使用我们的物联网设备,猫主人可以每天获取温度和体重数据。 此外,喂食过程是远程控制的并记录准确的食物摄入量,供业主参考。 然后可以参考这些记录来设置未来的喂食量。

只要产品定价合理,猫主人都会欣然接受。

解决方案

验收标准

  1. 系统必须能够检测到猫在 50 厘米内的接近
  2. 系统必须能够在 5 秒内测量 10 厘米距离内的猫的温度
  3. 系统必须能够在 10 秒内测量出猫的重量
  4. 供料系统必须能够在用户操作后 10 秒内做出反应

成功目标

  1. 该产品上线后1个月内必须能够获得10,000+新用户
  2. 使用社区必须有 1,000+ 日活跃用户
  3. 预计每季末用户群增加 3% – 5%
  4. 自动生成的报告的平均准确率必须至少为 70%

前提假设

  1. 宠物饲养员将携带他们的手机并保持互联网连接
  2. 系统不会断电
  3. 红外温度传感器能够在 5 秒内给出温度读数
  4. 红外传感器能够以灵敏的水平检测移动
  5. 压力传感器与数据转换模块连接良好,可传输重量读数

约束条件

  1. 物联网原型的总成本不能超过 300 SGD(约合1400RMB)
  2. 远程喂猫护理系统不会影响猫的正常生活
  3. 整个系统应该能够使用电池运行至少 24 小时
  4. 安装屋内所有设备所需的电源插头数不能超过 5 个

技术依赖

  1. 必须先建立数据库,然后才能将传感器数据传输到后端
  2. 在获取传感器数据并将其发送到后端之前,必须设置物联网网关并连接到 Wi-Fi
  3. 应开发微信小程序并建立用户社区,然后用户才能在该平台共享报告

系统架构

在设备端,我们有红外运动传感器来检测猫的接近,红外温度传感器来测量猫的温度,压力传感器来测量猫的重量,喂食伺服来控制喂食过程和喂食量。 所有这些传感器都通过电线连接到 Arduino 主芯片。 Arduino UNO 就像一个中央处理器来监控所有传感器。 之后,连接 Arduino 的 Wi-Fi 模块会将采集到的数据上传到腾讯云。 处理后数据会发送到我们的前端微信小程序。 对于MVP,我们只有微信小程序平台,可以简单的报告猫的温度和体重读数。 对于成熟的商业产品,我们会加入一些高级功能,比如报表自动分析、报表可视化和用户社区。

模块选择

主芯片选择

在我们的项目中,我们选择了 Arduino UNO 作为主芯片,而不是其他的,例如 Micro:bit、Raspberry PI 等,因为以下优点:

  1. 功能性:Arduino产品非常友好,广泛用于入门级学习者。 它有很多pin端口,可以连接各种模块。
  2. 可行性:虽然 Arduino UNO 比较大,但是如果我们想在某个有限的空间里把所有的部分组合起来,使其成为一个成熟的产品,我们可以将整个代码转移到一个更小的芯片上,比如 Arduino Micro、Arduino Nano。
  3. 可编程性:Arduino 更容易编码,它还提供了一些支持软件,比如 BLYNK。
  4. 社区环境:Arduino拥有成熟的用户社区,提供丰富的支持信息和问题解决方案,初学者更容易学习和调试。
  5. 负担能力:考虑到成本,Arduino不贵,但计算能力也不错。

投食模块选择

对于投食模块驱动的电机,在项目初期我们有两种选择:马达,以及舵机。最终我们选择了舵机而不是马达。首先,因为在Arduino芯片中使用马达通常需要在电路中添加继电器来防止电路过载,会徒增项目成本; 其次,通过考虑项目化需求,我们需要能控制每次喂猫的食物量,舵机可以控制旋角度以实现对投食量的精确把控。

程序代码

首先要做的是设置 Arduino 环境和定义所有引脚端口。

				
					#include <Wire.h>//Use Wire library
#include <Adafruit_GFX.h>//Use Adafruit_GFX.h library
#include <Adafruit_SSD1306.h>//Use Adafruit_SSD1306.h library
#include "dht11.h"
#include <MsTimer2.h> //Time-clock Library 
#include <Servo.h>  //Arduino IDE Servo library

//define Servo inout
#Define Servo_Pin      5                   
//press value pin
int fsrPin = 14;     // A0 port
int fsrReading;

//display value pin
const uint8_t OLED_CS = 9;
//Define OLED 12864 CS port to arduino 9
const uint8_t OLED_DC = 10; 
//Define OLED 12864 DC port to arduino 10
const uint8_t OLED_RESET = 11;
//Define OLED 12864 RES port to arduino 11
const uint8_t OLED_MOSI = 12;
//Define OLED 12864 D1(MOST) port to arduino 12
const uint8_t  OLED_CLK = 13;
//Define OLED 12864 D0(CLK) port to arduino 13
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

//movement test
int Move_Sensor_pin = 8;

//Temperature
int incomingByte = 0;                    
// Receive data byte
String inputString = "";                 
// Store  data byte
boolean newLineReceived = false;         
// Last data end flag
boolean startBit  = false;               
//protocol Start sign
String returntemp = "";           
//Store return value
char temp[100] = {0};

//motuo
Servo myservo;      
//Define the servo object myservo
/*printfFormat string initialization*/
int serial_putc( char c, struct __file * )
{
  Serial.write( c );
  return c;
}
void printf_begin(void)
{
  fdevopen( &serial_putc, 0 );
}
以下代码块是主要部分,每个子函数的注释说明了各个算法模块的功能以及逻辑。

void setup(void) {
  //common
  Serial.begin(9600);
  
  //movement
  pinMode(Move_Sensor_pin,INPUT);
  //Set the infrared interface of the human body to the input state

  //display
  display.begin(SSD1306_SWITCHCAPVCC);
  //initialization OLED 12864
  display.clearDisplay();   // Clean screen
  display.setTextSize(2);   //Set word font to 2
  display.setTextColor(WHITE);//Set word color to white
  display.setCursor(0,0);   //Position the cursor in column 0, row 0
  display.print("  SMU-IoT");//Display characters
  display.setCursor(0,16); 
  display.print("Team03");
  display.setCursor(0,32); 
  display.print("CatYou"); 
  display.setCursor(0,48); 
  display.print("0ighting"); 
  display.display();//Display

  //Temperature
  Wire.begin(0);
  //Wire.begin();         
  //join i2c bus (address optional for master)

  //motuo
  printf_begin();
  //Set the servo control pin to 5
  myservo.attach(Servo_Pin);
  //Initialize the servo position 0
  myservo.write(0);
}
uint16_t result;
float temp1;

void loop(void) {
  Serial.print("run");
  delay(500);
  fsrReading = analogRead(fsrPin); //heavy
  delay(2000);
  display.clearDisplay();
  display.setCursor(0,0); //Position the cursor in column 0, row 0
  display.print("  SMU-IoT");//Display characters
  display.setCursor(0,16); 
  display.print("presre "); display.print(fsrReading);
  Serial.print(fsrReading);
  
  Wire.beginTransmission(0x5A);
  Wire.write(0x07);                // sends instruction byte
  Wire.endTransmission(false);     // stop transmitting
  Wire.requestFrom(0x5A, 3);   //Send data n-bytes read
  result = Wire.read(); //Receive DATA
  result |= Wire.read() << 8; //Receive DATA
  uint8_t pec = Wire.read();
  temp1 =  result*0.02-273.15;  //Temperature value conversion
  Serial.print(temp1);

  float fTemp = temp1;
  display.setCursor(0,32); 
  display.print("Temp "); 
  display.print(fTemp);
  display.display();

  while (newLineReceived)// and digitalRead(Move_Sensor_pin)>0
  { 
    Serial.print("run1");
    delay(500);
    while(inputString.indexOf("SERVO") == 1)
      //If the string value "SERVO" to be retrieved appears
       {//$SERVO,90# 
       int i = inputString.indexOf("#",7);  
      //Retrieve the position of the character string "#" from the received data starting with 7
       if(i > 0)        
         //If retrieved
       {String temp = inputString.substring(7, i);  
         //Extract the characters between the specified subscript 7 to i in the string and assign them to temp
         int Pos = temp.toInt();
         //Convert string temp to integer
         if(Pos >=0 && Pos <= 180)
           //If the angle of the steering gear to be rotated in the received agreement is within 0-180
         {myservo.write(Pos);
           returntemp = "$SERVO,0,#"; 
           //Return matching success
          Serial.print(returntemp);
          //Return protocol packet     
          inputString = "";   
          // clear the string
          newLineReceived = false;}
         else
         { returntemp = "$SERVO,1,#";  
           //Return match failed
            Serial.print(returntemp); 
            //Return protocol packet      
            inputString = "";   
            // clear the string
            newLineReceived = false;
            break;    
         }
       }
       }

        if(inputString.indexOf("SERVO") == -1)  
          //If the string value "TH" to be retrieved does not appear
       {    
           break;}
       }

    while(inputString.indexOf("TH") == 1){
    //int fTemp = (float)DHT11.temperature;
    //fTempAssigned to the temperature value read in floating point type
       //int  weight = DHT11.humidity;
       //iHumidity Assign value to the humidity value read
       Serial.print("run2");
      delay(500);
        fsrReading = analogRead(fsrPin); //heavy
        Wire.beginTransmission(0x5A);
        Wire.write(0x07);                // sends instruction byte
        Wire.endTransmission(false);     // stop transmitting
        Wire.requestFrom(0x5A, 3);   //Send data n-bytes read
        result = Wire.read();        //Receive DATA
        result |= Wire.read() << 8;  //Receive DATA
        uint8_t pec = Wire.read();
        temp1 =  result*0.02-273.15;  //Temperature value conversion
        float fTemp = temp1;
        float weight=fsrReading;  //weightAssigned to the weight read
        Serial.println(fsrReading);
        
       //Parsing switch
       // $TH,1#
       
       memset(temp, 0x00, sizeof(temp));
       //Empty the temp array
       dtostrf(fTemp, 3, 1, temp);  // Equivalent to %3.2f
       String sTemp = temp;
       //The string in the array temp is assigned to sTemp
       String sWt =  "";    
       sWt += weight;
       returntemp = "$TH,T" + sTemp + ",H" + sWt + "#";
       Serial.print(returntemp); //Return protocol packet  
       inputString = "";   // clear the string
       newLineReceived = false;
      
       if(inputString.indexOf("TH") == -1)
         //If the string value "TH" to be retrieved does not appear
       {
       break;} 
      }
}

void serialEvent()
{
  while (Serial.available()) 
  {    
    incomingByte = Serial.read();
    //Read byte by byte, the next sentence is to put the read into the string array to form a completed data packet
    if(incomingByte == '$') 
      //If the serial port receives data, it enters the loop
    {
      startBit= true;
      //If the incoming byte is'$', start reading
    }
    if(startBit == true)
    {
       inputString += (char) incomingByte;     
      // The full-duplex serial port does not need to add a delay below, and half-duplex has to be added
    }  
    if (incomingByte == '#') 
    {
       newLineReceived = true;
      //If the incoming byte is'#', the reading ends
       startBit = false;
    }
  }
}
				
			

需科学上网可于下方窗口浏览视频;若下方未成功加载视频窗口,可点击此模块标题(左上方)查看Demo视频。

挑战

  • 编码产品中涉及多个模块/传感器,不同模块之间的协作以及与主芯片的连接的编码部分复杂,调试需要大量时间。
  • 该项目的目的是建立一个远程喂猫的设备。 但尽管我们是猫咪爱好者,但我们都不是养猫人。因此…我们需要一只猫!!!
  • 成本:我们的预算有限,因此项目很少有机会探索其他功能以与市场上的当前产品竞争,在项目蓝图制定期间我们应做出权衡决策。

局限性

  • 识别度:目前,每个产品仅适配一只猫,因为它无法识别和区分不同的猫,并单独记录它们的测量值。
  • 可扩展性:到目前为止,该产品被设计为仅适用于猫喂养。如果用户希望将此产品应用于其他宠物或更大的宠物(如狗),则该产品需要一些更新。可能需要更强的进料伺服系统、更大的进料容器和更多的压力传感器。
  • 可操作性:目前,运动传感器(接近检测传感器)和微信小程序(控制部分)之间没有反应 – 响应关系。因此,用户不会直接通过运动传感器知道猫是否来了。但运动传感器控制压力传感器和温度传感器的启动,用户可以通过接收温度和重量读数来了解猫的接近。为了进一步发展,可以应用摄像头模块来提高猫的识别和接近检测精度。

数据分析

我们通过咨询猫主人并询问相关数据分析来进行数据模拟。

首先,当猫的体温高于正常水平时,体重和食物摄入量往往会减少。

我们用这个设备喂养并记录了猫一个月的健康状况。 周统计数据看似稳定,但日气温波动明显。 从3月17日到3月21日,由于体温高于猫的平均体温,可以推断猫发烧了。 与此同时,猫睡得更多,与主人的互动更少。 在此期间,猫的体重和食物摄入量都减少了。 在其他时间,猫的摄食量和体温都正常,猫的状况很健康。

其次,如果猫的摄食量明显下降,体重也下降了,猫可能生病了。 当这种情况持续三天以上时,我们会发出警报,提醒主人注意猫的情况,及时就医。

总之,不同的猫可能有不同的正常体温。

我们根据下图将猫体温异常的报警阈值设置为39.2℃。 但是,小猫的体温可能会更高。 另外,通过这个实验,我们发现了猫的个体差异,所以这个临界温度应该根据猫的不同年龄和品种手动调整。

综上所述,我们的数据测量具有很高的准确性。 它可以监测和记录猫咪的异常情况,甚至是微小的异常,让喂猫器及时意识到猫咪的身体不适。

总结

我们从这个项目中得到的关键词是激励和解决方案契合。作为一个项目,既涉及技术部分,也涉及非技术部分。关键点的最初想法是解决方案部署,但根据讲师的有意义的反馈来解决用户的需求同样重要。识别利益相关者和存在的相应问题以相应地解决是很重要的。它突出了问题识别部分,这花了我们很多时间来调整原型设计。这种工作一开始让我们很担心。此外,由于我们团队中不同成员的专业是多样化的,分工和协作是我们项目的另一个重点。分工明确,技术部分和非技术部分由2个小组妥善完成。

 

但由于时间的限制,我们无法做详细的市场投资,虽然它是商业产品的强烈需要。

尽管受到时间和预算的限制,我们还是以巨大的成绩完成了这个项目。我们要感谢教授和讲师的意义指导和及时的反馈和跟进,帮助我们有条不紊地设计和完成项目。愿我们的产品能为猫咪和主人提供更舒适的生活。

发表回复

您的电子邮箱地址不会被公开。