8012年最后一天也要坦然面对 arduino 啊

已经为桌子上这一坨单片机折腾了三天,总是觉得自己可以当天搞完[拍桌]
想到很久没更了,还是写点经历和过程吧,一些收获如能给你带来帮助,不胜荣幸。

基于arduino的智能狗粮机

第一部分 任务需求

一、现状:
在波谲云诡的国际局势中,快节奏的生活像一把达摩克利斯剑悬在当代人的头上,许多人在忙碌与盲目中碌碌终生。作为新时代的新青年,时代的弄潮儿,青年人理应在纷乱的环境中寻求自我,很多人选择养宠物来坚守自己的初心,但是无奈常常因为忙于一个ppt一次加班一次出差忘记给小动物喂食,让它们蜷缩在阴冷的角落里挨饿,可怜!弱小!又无助!!!无数真实的故事,令人扼腕。很多人会想,如果有一个机器能够自动喂狗粮,那可该有多好!无奈囿于市面上的狗粮投食机价格太高功能离奇,丰满的理想被骨感的钱包所掣肘。
二、目的:
为了养汪星人、喵星人等动物时,增加其成活概率,从而为忙碌主人的闲暇生活增添更多欢乐,我们产品诣在实现培养过程的半无人化,从而达到人与其他生命和谐共处。

三、功能:
1.水泵定时定量抽水,给动物提供饮用水。
2.装置定时定量喂食(狗粮猫粮)
3.显示时间
4.显示一周喂食次数,每周一零点清零。
5.喂食前鸣奏特殊铃声,提醒动物吃食。
6.夜晚喂食时LED灯照射,避免动物在黑暗环境下无法看清食物的量导致浪费。
7.自定义喂食间隔和投食量。
8. 利用8*8点阵组建字模“做狗狗精彩不停”(……),让小狗和主人感受到不一般的温暖。

第二部分 任务总体设计

1.水泵定时定量抽水,给动物提供饮用水。
利用增水泵和硅胶水管,通过水管泵水的时间控制流量。
2 .装置定时定量喂食(狗粮猫粮)
设想:双仓双闸装置,具体示意图如附件一。
注:实现程度仍需老师指导。
3.显示时间:
利用四位数码管,定向显示时间编程即可。
4.显示一周喂食次数,每周一零点清零:
利用一位数码管,编程使数次每周一零点清零
5.喂食前鸣奏特殊铃声,提醒动物吃食:
利用蜂鸣器,在投食前一分钟,编程使蜂鸣器演奏音乐《天空之城》。
6.夜晚喂食时LED灯照射,避免动物在黑暗环境下无法看清食物的量导致浪费。
7.自定义喂食间隔和投食量。
在电脑上编程设置时间间隔和投食量参数。
8. 利用88点阵组建字模“做狗狗精彩不停”(……),让小狗和主人感受到不一般的温暖。
利用8
8LED显示屏字模提取软件构建字模,设置时间间隔,循环播放。

附件一:(自动狗粮机示意图)
在这里插入图片描述

以上是计划中的任务总体设计…注意…计划中


一条华丽的分割线
实践得真知,这句话比较真实。实践得现实。
看起来很简单的八个功能,其实每个的实现都遇到了很多问题。
骏洁说:“我们 arduino 的实现历程,除了瓶底就是瓶颈”

一、水泵定时抽水
经过讨论我们决定从水泵入手 //这是错误的开始
但是当时并没有同学成功实现水泵功能,因为没有成功的案例,大部分人都选择放弃或者观望。关键是有关水泵网上找到的代码,可能是兼容性的问题,在我们的板子上都会有蛇皮结果hhh

最后总归是成功了。直接放图:在这里插入图片描述
代码很简单,可能是因为接触的问题很多人没有成功叭。
注意一定要加公母线,用胶带缠一圈。

    int water=3;
    void setup(){
      pinMode(3,OUTPUT);
    }
    void loop(){
      digitalWrite(water,HIGH);
      delay(3000);
      digitalWrite(water,LOW);
      for(long a = 0; a<=6*60*60; a++){
        delay(1000);
      }
    }

二、 8*8点阵显示
最初准备做的“做狗狗精彩不停”实在是太睿智了[-_-||]
还是换成了一个简单美观的图hiahia

这里的主要难点是不同型号的8*8点阵的兼容性存在较大差异,我们的串口和网上找的教程的串口完全不同,助教提供的串口序号有一个口有问题,这都是需要不断调试才能得到的结论,另外在这里可以使用模拟端口去实现数字端口的功能。

在这里插入图片描述
(当然还有很多字的显示,这是显示了一个大写的I)
目前可以实现的还包括跳动的爱心 ❥
其实通过字模软件基本可以实现各种字的各种字体,当然也可以用手自己模拟画。
下面就该粘代码了

int x[] = {18,17,16,15,14,13,12,11};
int y[] = {6,7,8,9,5,4,3,2};
void setup()
 
{
 
  for(int i=0;i<=7;i++){
    pinMode(y[i],OUTPUT);//定义小灯接口为输出接口
  }
  for(int i=0;i<=7;i++)
    pinMode(x[i],OUTPUT);//定义小灯接口为输出接口
 
  clear_();
//pinMode(inpin,INPUT);//定义按键接口为输入接口
 
}
 
void clear_(void)//清除屏幕
{
 for(int i=0;i<8;i++)
 digitalWrite(y[i], LOW);
 for(int i=0;i<8;i++)
 digitalWrite(x[i], HIGH);
}
 
void putChar(unsigned char c[]){
    unsigned char data;
     for(int j=0;j<8;j++){
       data = c[j];
       for(int i=0;i<8;i++){
         if(data & 0x01){
           clear_();
           digitalWrite(y[j],HIGH);
           digitalWrite(x[i],LOW); 
           delay(1);
         }  
         data >>= 1;
       }
     }
}
 
unsigned char love[] = {0xe7,0x99,0x81,0x81,0x81,0x42,0x24,0x18};
unsigned char I[] = {0x3c,0x18,0x18,0x18,0x18,0x18,0x18,0x3c};
unsigned char U[] = {0x00,0x42,0x42,0x42,0x42,0x42,0x24,0x18};
void loop()
{
  for(int i=0;i<50;i++)
    putChar(I);
  for(int i=0;i<50;i++)
    putChar(love); 
  for(int i=0;i<50;i++)
    putChar(U); 
}

三、狗粮自动投食机(精华)
智能狗粮机的精华所在。
因为这个模块的大部分功能都没有现成的工具,DIY为主。先看一下实体图:在这里插入图片描述
是不是看上去很傻
但是真正做一个这样的东西真的很折磨人,从舵机的摆动角,选用的角速度使狗粮能够大致稳定的释放一定量同时不至于产生过大阻力使舵机驱动的纸板受阻变形等等都是需要反复测试,尝试之后才能选择一个相对优解。同时,狗粮机的高度,四根筷子做支撑的相互角度,舵机高度,都是相互影响相互制约的,这就导致了错误时整个装置的很多部分都要重新定规格重新制作。
说来感觉很轻松,但是其中收了很多罪只有我和骏洁老弟可以感受啦哈哈哈,希望大家也不要受这么大的罪了。
舵机定时摆动的代码:

#include <Servo.h>
Servo myservo;
int potpin=A0;
int pos=0,val;//定义舵机转动位置
int servoPin=9;
void setup(){
	myservo.attach(9);//设置舵机控制针脚
	pinMode(servoPin,OUTPUT);
}
void loop(){

	for(pos=0;pos<30;pos++){
		myservo.write(pos);
		delay(15);
	}
        delay(1000);
	for(pos=30;pos>=1;pos--){
		myservo.write(pos);
		delay(15);
	}
      for (int i=1;i<=*6*60;i++) delay(1000);

}

p.s. 最后选择了 30° 的摆动角和 delay(15)所带来的角速度。
俯视图:
在这里插入图片描述
选择了舵机嵌入矿泉水瓶,水瓶里记得留一些水保持稳定性但是不要过多防止湿度过大损坏舵机。
在这里插入图片描述

四、蜂鸣器播放就餐前音乐
饭前播放好听的音乐让人食欲大增,对狗狗应该也是一样。
在音乐方面我们选择了 《天空之城》
实测效果很不错。
这个功能比较显然,就直接贴代码了:

#define NOTE_D0 -1 
#define NOTE_D1 294 
#define NOTE_D2 330 
#define NOTE_D3 350 
#define NOTE_D4 393 
#define NOTE_D5 441 
#define NOTE_D6 495 
#define NOTE_D7 556 

#define NOTE_DL1 147 
#define NOTE_DL2 165 
#define NOTE_DL3 175 
#define NOTE_DL4 196 
#define NOTE_DL5 221 
#define NOTE_DL6 248 
#define NOTE_DL7 278 

#define NOTE_DH1 589 
#define NOTE_DH2 661 
#define NOTE_DH3 700 
#define NOTE_DH4 786 
#define NOTE_DH5 882 
#define NOTE_DH6 990 
#define NOTE_DH7 112  

#define WHOLE 1 
#define HALF 0.5 
#define QUARTER 0.25 
#define EIGHTH 0.25 
#define SIXTEENTH 0.625  

int tune[] = {  
 NOTE_D0,NOTE_D0,NOTE_D0,NOTE_D6,NOTE_D7,NOTE_DH1,NOTE_D7,NOTE_DH1,NOTE_DH3,NOTE_D7,NOTE_D7,NOTE_D7,NOTE_D3,NOTE_D3,
 NOTE_D6,NOTE_D5,NOTE_D6,NOTE_DH1,NOTE_D5,NOTE_D5,NOTE_D5,NOTE_D3,NOTE_D4,NOTE_D3,NOTE_D4,NOTE_DH1,
 NOTE_D3,NOTE_D3,NOTE_D0,NOTE_DH1,NOTE_DH1,NOTE_DH1,NOTE_D7,NOTE_D4,NOTE_D4,NOTE_D7,NOTE_D7,NOTE_D7,NOTE_D0,NOTE_D6,NOTE_D7,
 NOTE_DH1,NOTE_D7,NOTE_DH1,NOTE_DH3,NOTE_D7,NOTE_D7,NOTE_D7,NOTE_D3,NOTE_D3,NOTE_D6,NOTE_D5,NOTE_D6,NOTE_DH1,
 NOTE_D5,NOTE_D5,NOTE_D5,NOTE_D2,NOTE_D3,NOTE_D4,NOTE_DH1,NOTE_D7,NOTE_D7,NOTE_DH1,NOTE_DH1,NOTE_DH2,NOTE_DH2,NOTE_DH3,NOTE_DH1,NOTE_DH1,NOTE_DH1,
 NOTE_DH1,NOTE_D7,NOTE_D6,NOTE_D6,NOTE_D7,NOTE_D5,NOTE_D6,NOTE_D6,NOTE_D6,NOTE_DH1,NOTE_DH2,NOTE_DH3,NOTE_DH2,NOTE_DH3,NOTE_DH5,
 NOTE_DH2,NOTE_DH2,NOTE_DH2,NOTE_D5,NOTE_D5,NOTE_DH1,NOTE_D7,NOTE_DH1,NOTE_DH3,NOTE_DH3,NOTE_DH3,NOTE_DH3,NOTE_DH3,
 NOTE_D6,NOTE_D7,NOTE_DH1,NOTE_D7,NOTE_DH2,NOTE_DH2,NOTE_DH1,NOTE_D5,NOTE_D5,NOTE_D5,NOTE_DH4,NOTE_DH3,NOTE_DH2,NOTE_DH1,
 NOTE_DH3,NOTE_DH3,NOTE_DH3,NOTE_DH3,NOTE_DH6,NOTE_DH6,NOTE_DH5,NOTE_DH5,NOTE_DH3,NOTE_DH2,NOTE_DH1,NOTE_DH1,NOTE_D0,NOTE_DH1,
 NOTE_DH2,NOTE_DH1,NOTE_DH2,NOTE_DH2,NOTE_DH5,NOTE_DH3,NOTE_DH3,NOTE_DH3,NOTE_DH3,NOTE_DH6,NOTE_DH6,NOTE_DH5,NOTE_DH5,
 NOTE_DH3,NOTE_DH2,NOTE_DH1,NOTE_DH1,NOTE_D0,NOTE_DH1,NOTE_DH2,NOTE_DH1,NOTE_DH2,NOTE_DH2,NOTE_D7,NOTE_D6,NOTE_D6,NOTE_D6,NOTE_D6,NOTE_D7
};

float duration[]= {  
  1,1,1,0.5,0.5,     1+0.5,0.5,1,1,     1,1,1,0.5,0.5,
  1+0.5,0.5,1,1,     1,1,1,1,          1+0.5,0.5,1,1, 
  1,1,0.5,0.5,0.5,0.5,    1+0.5,0.5,1,1,     1,1,1,0.5,0.5,
  1+0.5,0.5,1,1,    1,1,1,0.5,0.5,     1+0.5,0.5,1,1,
  1,1,1,0.5,0.5,    1,0.5,0.25,0.25,0.25,0.5,    0.5,0.5,0.5,0.25,0.5,1,
  0.5,0.5,0.5,0.5,1,1,    1,1,1,0.5,0.5,    1+0.5,0.5,1,1,
  1,1,1,0.5,0.5,    1.5,0.5,1,1,    1,1,1,1,
  0.5,0.5,1,1,0.5,0.5,    1.5,0.25,0.5,1,    1,1,1,1,
  1,1,1,1,    1,1,1,1,    0.5,0.5,1,1,0.5,0.5,
  1,0.5,0.5,1,1,    1,1,1,1,    1,1,1,1,
  0.5,0.5,1,1,0.5,0.5,    1,0.5,0.25,0.5,1,    1,1,1,0.5,0.5
};

int length;
int tonePin=13;

void setup(){  
  pinMode(tonePin,OUTPUT);
  length = sizeof(tune)/sizeof(tune[0]);
} 

void loop(){  
  for(int x=0;x<length;x++){  
    tone(tonePin,tune[x]);
    delay(400 * duration[x]);
    noTone(tonePin);
  } 
  delay(5000);
}

五、按键控制LED灯暗灭
作为智能家居的一部分,肯定是需要包含灯光照明的功能的。
在这里我们选择了较为简单的单色LED灯。
原本也曾考虑了三色灯,主要是太占数字端口了(又是三个)而且其实好像也没有必要。但是三色灯的效果是很漂亮的。
在这里插入图片描述

代码还是一贯的简单:

const int buttonPin = 2;     

const int ledPin =  8;      

int buttonState = 0;         

void setup() {

  pinMode(ledPin, OUTPUT);

  pinMode(buttonPin, INPUT_PULLUP);
  
}

void loop() {

  if (digitalRead(buttonPin) == HIGH){
    delay(20);
  if (digitalRead(buttonPin) == HIGH) {

   digitalWrite(ledPin,!digitalRead(ledPin));
   while(digitalRead(buttonPin)==HIGH);

  }
  }
}

六、显示功能
采用了一个液晶显示屏和电位器,用电位器来调整电阻从而调节显示亮度。
在这里插入图片描述

代码:

  #include <LiquidCrystal.h>
    LiquidCrystal LCD(12, 11, 4, 5, 6, 7);
    void setup(){
      LCD.begin(16, 2);
    }
    void loop(){
      LCD.setCursor(1, 0);
      LCD.print("Remember to");
      LCD.setCursor(1, 1);
      LCD.print("feed your dog");
    }

猜你喜欢

转载自blog.csdn.net/qq_42447015/article/details/85466337