物联网自动猫粮机 您所在的位置:网站首页 猫粮搅拌机 物联网自动猫粮机

物联网自动猫粮机

2022-12-18 04:47| 来源: 网络整理| 查看: 265

项目背景

       当你忙于工作,中午无法回家;当你回家途中惨遭堵车,无法按时到家;当时需要出差,当你需要约会…...这些情况都会导致家里的宠物处于挨饿或无法按时按量吃饭的状态! 宠物比人类脆弱的多,以上的种种情况都有可能导致宠物患上肠胃疾病!这时候,你就需要一款可以自动或者远程控制的智能猫/狗粮机,来帮你按时按量的投喂家里的小可爱们!并且可以统计小可爱们的吃饭时间,以便在需要的时候向宠物医生反馈,时刻关注家中宠物的健康! 

        那么先看看我们需要准备些什么吧!~

材料清单

3mm椴木板 X1 4mm椴木板 X2 Gravity: UART OBLOQ - IoT物联网模块 X3 链接Romeo V2 多合一Arduino兼容控制器 X4 链接Gravity I2C OLED-2864 显示屏 X5 链接带编码器金属直流减速电机 (6V 300rpm 3.6Kg.cm) X6 链接数字触摸开关Touch(Arduino兼容) X7 链接75*2.3mmPVC水管 X8

步骤1 猫粮机结构件制作

木板激光切割

       首先,我们需要进行猫粮机整体结构的加工,考虑到拼装的便捷性和材料的成本,我们的猫粮机采用木板和螺丝固定的结构。猫粮机的激光切割图纸,我会放在帖子最后的资料中供大家下载,大家也可以在现有的基础上,给猫粮机增加更好看的外观,给家里的“主子”们做一个独一无二的猫粮机。

PVC水管切割

       木板切割完成后,我们需要制作猫粮机输送猫粮的管道,这个就需要我们之前准备的PVC水管(直径和厚度千万不要买错哦~)。我们需要切割一段178mm长的PVC水管,然后在其中一侧用手锯切出一个35mm长,5mm深的槽,以便于安装我们猫粮机的入口。

3D打印

       最后,我们还缺一个推动猫粮的绞龙,以及安装在PVC水管两侧防止猫粮从管道中掉落的封盖。3D打印时需要用到的STL文件,我也会在帖子最后的资料中贴上的~绞龙最终打印出来就是下图的效果啦~

步骤2 猫粮机的拼装

        完成了所有的结构件制作,接下来我们就要进到最繁琐的拼装环节!在进行拼装之前,提醒一下各位!在猫粮机外壳拼装的时候,需要在螺丝和螺母的基础上,添加一个垫片,增加结构的稳定性,也防止了用力过猛拧断木板的情况(即使这样也不要用力太猛!)!正确的安装方式如下~

      因为制作拼装图纸过于繁琐,我给大家一个安装到一半的图,以便大家理解拼装过程。拼装过程中,如果遇到一些不稳定的结构,各位可以使用热熔胶或者502辅助固定。

       拼装到还剩最后一块侧面板时,我们将主控以及各种模块放入机器中。

步骤3 烧录程序

        这一版的猫粮机,具有可以使用OBLOQ控制猫粮机运行模式的功能。向optic2发送数据1,猫粮机持续出粮;发送数据0,猫粮机停止出粮;发送数据2,猫粮机进入自动模式,外接的触摸传感器每隔一段时间(这段时间可以在程序中自行更改)允许猫咪触摸后出粮。烧录完程序后,将最后一块木板装上,猫粮机就制作完成啦!

代码 #include #include "U8glib.h" #include #include "Obloq.h" U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE | U8G_I2C_OPT_DEV_0); // I2C / TWI static const unsigned char PROGMEM str_kong[] = {0x02,0x00,0x01,0x00,0x7F,0xFE,0x40,0x02,0x88,0x24,0x10,0x10,0x20,0x08,0x00,0x00, 0x1F,0xF0,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x7F,0xFC,0x00,0x00};/*"空",0*/ static const unsigned char PROGMEM str_bai[] = {0x01,0x00,0x02,0x00,0x04,0x00,0x3F,0xF8,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08, 0x3F,0xF8,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x3F,0xF8,0x20,0x08};/*"白",1*/ static const unsigned char PROGMEM str_zong[] = {0x10,0x10,0x08,0x20,0x04,0x40,0x00,0x00,0x1F,0xF0,0x10,0x10,0x10,0x10,0x10,0x10, 0x1F,0xF0,0x10,0x10,0x01,0x00,0x08,0x84,0x48,0x92,0x48,0x12,0x87,0xF0,0x00,0x00};/*"总",2*/ static const unsigned char PROGMEM str_liang[] = {0x00,0x00,0x1F,0xF0,0x10,0x10,0x1F,0xF0,0x10,0x10,0xFF,0xFE,0x00,0x00,0x1F,0xF0, 0x11,0x10,0x1F,0xF0,0x11,0x10,0x1F,0xF0,0x01,0x00,0x1F,0xF0,0x01,0x00,0x7F,0xFC};/*"量",3*/ static const unsigned char PROGMEM str_ci[] = {0x00,0x80,0x40,0x80,0x20,0x80,0x20,0xFC,0x01,0x04,0x09,0x08,0x0A,0x40,0x14,0x40, 0x10,0x40,0xE0,0xA0,0x20,0xA0,0x21,0x10,0x21,0x10,0x22,0x08,0x24,0x04,0x08,0x02};/*"次",4*/ static const unsigned char PROGMEM str_shu[] = {0x08,0x20,0x49,0x20,0x2A,0x20,0x08,0x3E,0xFF,0x44,0x2A,0x44,0x49,0x44,0x88,0xA4, 0x10,0x28,0xFE,0x28,0x22,0x10,0x42,0x10,0x64,0x28,0x18,0x28,0x34,0x44,0xC2,0x82};/*"数",5*/ static const unsigned char PROGMEM str_shi[] = {0x02,0x00,0x01,0x00,0x7F,0xFE,0x40,0x02,0x88,0x84,0x04,0x80,0x04,0x80,0x10,0x80, 0x08,0x80,0x08,0x80,0xFF,0xFE,0x01,0x40,0x02,0x20,0x04,0x10,0x18,0x08,0x60,0x04};/*"实",6*/ static const unsigned char PROGMEM str_m[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00};/*":",0*/ static const unsigned char PROGMEM str_g[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x44,0x44,0x38,0x40,0x3C,0x42,0x42,0x3C};/*"g",0*/ static const unsigned char PROGMEM str_cat[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x01,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xE0,0x00,0x00,0x00,0x00, 0x00,0x00,0x01,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xF8,0x00,0x00,0x00,0x00, 0x00,0x00,0x03,0xDC,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xEF,0x8F,0x80,0x00,0x00, 0x00,0x00,0x03,0xE7,0xFF,0x00,0x00,0x00,0x00,0x00,0x03,0xE3,0xFF,0x00,0x00,0x00, 0x00,0x00,0x0F,0xE0,0x0F,0x00,0x00,0x00,0x00,0x00,0x0F,0x38,0x1E,0x00,0x00,0x00, 0x00,0x00,0x0F,0xF8,0x1E,0x00,0x00,0x00,0x00,0x00,0x0F,0xF8,0x7C,0x00,0x00,0x00, 0x00,0x00,0x07,0xFB,0xFE,0x00,0x00,0x00,0x00,0x00,0x06,0xC3,0xFE,0x00,0x00,0x00, 0x00,0x00,0x07,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0x38,0x00,0x00,0x00, 0x00,0x00,0x03,0x80,0x70,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0x70,0x00,0x00,0x00, 0x00,0x00,0x03,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x38,0x00,0x00,0x00, 0x00,0x00,0x03,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x0F,0x00,0x00,0x00, 0x00,0x00,0x03,0x00,0x07,0x80,0x00,0x00,0x00,0x00,0x03,0x00,0x03,0xC0,0x00,0x00, 0x00,0x00,0x03,0x80,0x01,0xE0,0x00,0x00,0x00,0x00,0x03,0xC0,0x00,0xE0,0x1C,0x00, 0x00,0x00,0x03,0xE0,0x00,0x60,0x3E,0x00,0x00,0x00,0x03,0x60,0x18,0x70,0x73,0x80, 0x00,0x00,0x03,0x70,0x38,0x30,0x79,0x80,0x00,0x00,0x03,0x39,0xB0,0x30,0x79,0xC0, 0x00,0x00,0x03,0xB9,0xF0,0x30,0x19,0xC0,0x00,0x00,0x01,0xBD,0xF0,0x30,0x3D,0x80, 0x00,0x00,0x01,0xBF,0xF0,0x7C,0xF9,0x80,0x00,0x00,0x01,0xFF,0xF0,0xFF,0xF3,0x00, 0x00,0x00,0x01,0xFF,0xE1,0xFF,0x8E,0x00,0x00,0x00,0x01,0xEF,0x7F,0xFF,0xFC,0x00, 0x00,0x00,0x00,0xEE,0x7F,0x0F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/*"C:\Users\lx\Desktop\0604abee9b593c0e2bf6df460d4623d8.bmp",0*/ const byte encoder0pinA = 2;//A pin -> the interrupt pin 0 const byte encoder0pinB = 3;//B pin -> the digital pin 3 int E_left =5; //L298P直流电机驱动板的使能端口连接到数字接口5 int M_left =4; //L298P直流电机驱动板的转向端口连接到数字接口4 int button =7; //控制电机转动按钮7 int i =0; byte encoder0PinALast; double duration,abs_duration;//the number of the pulses boolean Direction;//the rotation direction boolean result; double val_output;//用于提供给电机PWM功率值。 double Setpoint; double Kp=0.6, Ki=5, Kd=0; PID myPID(&abs_duration, &val_output, &Setpoint, Kp, Ki, Kd, DIRECT); static unsigned long currentTime = 0; int buttonState =0; int times =0; int iotState =0; SoftwareSerial softSerial(10,11); //生成OBLOQ对象,参数:串口指针,wifiSsid, WifiPwd, iotId, iotPwd //Generate OBLOQ object, parameters: serial pointer, wifiSsid, WifiPwd, iotId, iotPwd Obloq olq(&softSerial,"DFRobot-guest","dfrobot@2017","xxxxxxxxxx","xxxxxxxxxx"); const String devTopic = "xxxxxxxxxx"; const String devTopic2 = "xxxxxxxxxx"; void setup() { Serial.begin(9600);//Initialize the serial port pinMode(M_left, OUTPUT); //L298P直流电机驱动板的控制端口设置为输出模式 pinMode(E_left, OUTPUT); Setpoint =80; //设置PID的输出值 myPID.SetMode(AUTOMATIC);//设置PID为自动模式 myPID.SetSampleTime(20);//设置PID采样频率为100ms EncoderInit();//Initialize the module pinMode(button, INPUT); softSerial.begin(9600); olq.setMsgHandle(msgHandle);//注册消息回调函数 register message callback function olq.subscribe(devTopic2); //监听设备 Subscribe topic } void loop() { Serial.print(iotState); abs_duration=abs(duration); result=myPID.Compute();//PID转换完成返回值为1 if(result) { Serial.print("Pluse: "); Serial.println(duration); duration = 0; //计数清零等待下次计数 } millis(); olq.update(); u8g.firstPage(); do { // u8g.setFont(u8g_font_04b_03b_short); // 字体设置 // u8g.drawStr(36,48,times); u8g.setColorIndex(1); drawSTART(); drawURL(); u8g.setFont(u8g_font_unifont); u8g.setPrintPos(48,64); u8g.print(times); } while ( u8g.nextPage() ); if(iotState == 1) { advance(); } if(iotState == 0) { Stop(); } if(iotState == 2) { if(digitalRead(button) == HIGH) { buttonState =1; } if(i>=10) { Stop();//电机停止 olq.publish("HkHyId8rX",String(times++)); delay(5000); buttonState =0; i=0; } if(i Forward pinMode(encoder0pinB,INPUT); attachInterrupt(0, wheelSpeed, CHANGE); } void wheelSpeed() { int Lstate = digitalRead(encoder0pinA); if((encoder0PinALast == LOW) && Lstate==HIGH) { int val = digitalRead(encoder0pinB); if(val == LOW && Direction) { Direction = false; //Reverse } else if(val == HIGH && !Direction) { Direction = true; //Forward } } encoder0PinALast = Lstate; if(!Direction) duration++; else duration--; } void advance()//电机正转 { digitalWrite(M_left,LOW); analogWrite(E_left,val_output); } void back()//电机反转 { digitalWrite(M_left,HIGH); analogWrite(E_left,val_output); } void Stop()//电机停止 { digitalWrite(E_left, LOW); } void drawSTART(void) { u8g.drawBitmapP(0,16,2,16,str_zong);u8g.drawBitmapP(16,16,2,16,str_liang);u8g.drawBitmapP(32,16,2,16,str_m);u8g.drawBitmapP(64,16,1,16,str_g); u8g.drawBitmapP(0,32,2,16,str_shi);u8g.drawBitmapP(16,32,2,16,str_liang);u8g.drawBitmapP(32,32,2,16,str_m);u8g.drawBitmapP(64,32,1,16,str_g); u8g.drawBitmapP(0,48,2,16,str_ci);u8g.drawBitmapP(16,48,2,16,str_shu);u8g.drawBitmapP(32,48,2,16,str_m); u8g.drawBitmapP(64,16,8,64,str_cat); } void drawURL(void) { #ifndef MINI_LOGO u8g.setFont(u8g_font_4x6); if ( u8g.getHeight() < 59 ) { u8g.drawStr(53, 9, "www.dfrobot"); u8g.drawStr(77, 18, ".com.cn"); } else { u8g.drawStr(53,8, "www.dfrobot.com.cn"); } #endif } void msgHandle(const String& topic,const String& message) { if(devTopic2 == topic) { if(message == "1") iotState = 1; else if(message == "0") iotState = 0; else iotState = 2; } }

总结

这一版的猫粮机还是有很多缺陷的,比如没有留更换电池的接口,结构还不够紧凑等。接下来会不断的改进这款猫粮机的,为大家的猫主子提供更好的投喂机器!

资料

猫粮机激光切割木板资料:链接:https://pan.baidu.com/s/18wUuxueBqd2N9shGOfW4hg 提取码:96jj

3D打印件资料:链接:https://pan.baidu.com/s/1K5I8p9uzllz6FDyLMTp81g 提取码:j1co



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有