日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

如何用ARDUINO制作一个鸟蛋孵化器

發(fā)布時(shí)間:2023/12/20 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何用ARDUINO制作一个鸟蛋孵化器 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

項(xiàng)目背景介紹

經(jīng)常養(yǎng)寵物的朋友,遇到寵物繁殖很是頭疼,特別是鳥(niǎo)類(lèi)繁殖,更加需要一個(gè)恒溫恒濕的孵化箱。市面上孵化箱種類(lèi)繁多,從幾十塊的到上千塊的孵化箱都有,性能參差不齊,有些孵化箱的溫度相差3度是常有的事情,有些沒(méi)有濕度數(shù)據(jù),于是決定用自己多年自學(xué)的三腳貓功夫做一個(gè)孵化箱,把制作過(guò)程分享給大家。

項(xiàng)目開(kāi)發(fā)環(huán)境

`
arduino的c語(yǔ)言開(kāi)發(fā)環(huán)境,版本1.61


項(xiàng)目硬件設(shè)備

名稱(chēng)型號(hào)數(shù)量用途
單片機(jī)ARDUINO UNO1孵化器主要控制芯片
電源開(kāi)關(guān)電源12V100W1給整個(gè)孵化箱提供12v供電
照明LED燈帶1孵化箱照明用
保溫外箱蜥蜴保溫箱40CM1保溫
發(fā)熱片12V50W低壓型PTC鋁殼250度恒溫發(fā)熱片2給孵化箱提供熱源
CPU風(fēng)扇寬度6厘米厚度1.5厘米1恒溫箱空氣循環(huán)用
CPU散熱片散熱片1把散熱片的熱量散發(fā)到恒溫箱空氣中
魔術(shù)板EPP發(fā)泡板2毫米厚度若干制作發(fā)熱片散熱通風(fēng)管道
電子開(kāi)關(guān)MOS觸發(fā)開(kāi)關(guān)12V2用于控制散熱片和加濕器
加濕器usb加濕模塊1控制濕度
溫濕度傳感器SHT201溫濕度傳感器
塑料袋塑料袋若干用于鋪于鳥(niǎo)蛋底下,恒溫作用
降壓模塊12V轉(zhuǎn)5V降壓模塊1用于給usb加濕模塊提供5V電源用
液晶顯示器0.96寸OLED顯示屏1顯示溫度、濕度、孵化時(shí)間和孵化狀態(tài)

硬件接線圖

代碼

tempadmin.cpp

//#include <SHT1x.h> #include <EEPROM.h> #include <Servo.h> #include <Wire.h> #include "U8glib.h" #include "TempAdmin.h" #include "DFRobot_SHT20.h"//SHT1x sht1x(dataPin, clockPin); DFRobot_SHT20 sht20;void inQueue(QUEUE * pQueue,int value) {pQueue->pBase[pQueue->point]=value;pQueue->point=++pQueue->point%6;//Serial.println(pQueue->point); }int traverseQueue(QUEUE * pQueue) {int n=pQueue->point;int a=0,b=0,nCount=0;do{if(nCount<3){a+=pQueue->pBase[n];}else{b+=pQueue->pBase[n];}n=++n%6;nCount++;}while(n!=pQueue->point);return (b-a); }void TrunEggs(void) {int nAngle=myservo1.read();//Serial.println(nAngle);//Serial.println(nDestAngle);if(abs(nAngle-nDestAngle)<6){nAngle=nDestAngle;myservo1.write(nAngle);return;}if(nDestAngle>nAngle){nAngle+=6;myservo1.write(nAngle);return;}else if(nDestAngle<nAngle){nAngle-=6;myservo1.write(nAngle);return;} }void drawSetting(void) {char chShowStr[100],chTemp[100];float fPre;// graphic commands to redraw the complete screen should be placed here u8g.setColorIndex(1); // pixel onu8g.setFont(u8g_font_unifont);dtostrf(fSetTemp,4,2,chTemp);sprintf(chShowStr,"TEMP: %s C",chTemp);u8g.drawStr( 0, 12, chShowStr);u8g.drawBox( 0, 15, 128,16);u8g.setColorIndex(0); // pixel ondtostrf(fSetTempOff,4,2,chTemp);sprintf(chShowStr,"TEMP OFF: %s C",chTemp);u8g.drawStr( 0, 28, chShowStr);u8g.setColorIndex(1); // pixel ondtostrf(fSetHumi,4,2,chTemp);sprintf(chShowStr,"HUMI: %s %%",chTemp);u8g.drawStr( 0, 44, chShowStr);dtostrf(fSetHumiOff,4,2,chTemp);sprintf(chShowStr,"HUMI OFF: %s C",chTemp);u8g.drawStr( 0, 60, chShowStr);/*if(n_Status){dtostrf(fSetTemp,4,2,chTemp);sprintf(chShowStr,"TEMP: %s C",chTemp);u8g.drawStr( 0, 12, chShowStr);dtostrf(fSetTempOff,4,2,chTemp);sprintf(chShowStr,"TEMP OFF: %s C",chTemp);u8g.drawStr( 0, 28, chShowStr);dtostrf(fSetHumi,4,2,chTemp);sprintf(chShowStr,"HUMI: %s %%",chTemp);u8g.drawStr( 0, 44, chShowStr);dtostrf(fSetHumiOff,4,2,chTemp);sprintf(chShowStr,"HUMI OFF: %s C",chTemp);u8g.drawStr( 0, 60, chShowStr);}else{switch(n_SettingItem){case 0:u8g.drawStr( 0, 12, "TEMP:");break;case 1:u8g.drawStr( 0, 28, "TEMP OFF:");break;case 2:u8g.drawStr( 0, 44, "HUMI:");break;case 3:u8g.drawStr( 0, 60, "HUMI OFF:");break;}dtostrf(fSetTempOff,4,2,chTemp);sprintf(chShowStr,"TEMP OFF: %s C",chTemp);u8g.drawStr( 0, 28, chShowStr);dtostrf(fSetHumi,4,2,chTemp);sprintf(chShowStr,"HUMI: %s %%",chTemp);u8g.drawStr( 0, 44, chShowStr);dtostrf(fSetHumiOff,4,2,chTemp);sprintf(chShowStr,"HUMI OFF: %s C",chTemp);u8g.drawStr( 0, 60, chShowStr);}*///Serial.println(n_Status); }void draw(void) {// graphic commands to redraw the complete screen should be placed here u8g.setFont(u8g_font_unifont);char chShowStr[100],chTemp[100];float fPre;dtostrf(fTemp_c,4,2,chTemp);sprintf(chShowStr,"TEMP: %s C",chTemp);u8g.drawStr( 0, 12, chShowStr);dtostrf(fHumidity,4,2,chTemp);sprintf(chShowStr,"HUMI: %s %%",chTemp);u8g.drawStr( 0, 28, chShowStr);u8g.drawLine(0,32, 108,32);if(digitalRead(nLineHeat)==HIGH)u8g.drawStr( 0, 48, "HEATING");elseu8g.drawStr( 0, 48, " ");sprintf(chShowStr,"%ldDAY %02ld:%02ld:%02ld",nowtime/86400,(nowtime/3600)%24,(nowtime/60)%60,nowtime%60);//sprintf(chShowStr,"%02ld %02ld",nowtime,nowtime%60);u8g.drawStr( 0, 64, chShowStr); }void Process_Temp_Humi(void) {inQueue(&queueTemp,fTemp_c*100);value=traverseQueue(&queueTemp);if(abs(value)<3){//溫度沒(méi)有變化if((fSetTemp-fTemp_c)>0.3){digitalWrite(nLineHeat,HIGH);}else{digitalWrite(nLineHeat,LOW);}}else if(value>0){//升溫過(guò)程if(fTemp_c<fSetTemp-fSetTempOff){digitalWrite(nLineHeat,HIGH);}else{digitalWrite(nLineHeat,LOW);}}else{//降溫過(guò)程if(fTemp_c<fSetTemp+fSetTempOff){digitalWrite(nLineHeat,HIGH);}else{digitalWrite(nLineHeat,LOW);}}inQueue(&queueHumi,fHumidity*100);value=traverseQueue(&queueHumi);if(g_un_count%20==0){if(abs(value)<15){//濕度沒(méi)有變化if((fSetHumi-fHumidity)>5){digitalWrite(nLineHumid,HIGH);//Serial.println("code run here!");delaytime=currentMillis+20000;//digitalWrite(nLineHumid,LOW);}}else if(value>0){//加濕過(guò)程if(fHumidity<fSetHumi-fSetHumiOff){digitalWrite(nLineHumid,HIGH);delaytime=currentMillis+20000;}}else{//干燥過(guò)程if(fHumidity<fSetHumi+fSetHumiOff){digitalWrite(nLineHumid,HIGH);delaytime=currentMillis+20000;}}}g_un_count++; }void setup (void) {Serial.begin(9600); pinMode(nLineHeat, OUTPUT);pinMode(nLineHumid, OUTPUT);pinMode(nTurnEgg, OUTPUT);pinMode(nLineCO2, OUTPUT);pinMode(nSwitch1, INPUT);pinMode(nSwitch2, INPUT);pinMode(nSwitch3, INPUT);// assign default color valueif ( u8g.getMode() == U8G_MODE_R3G3B2 ) {u8g.setColorIndex(255); // white}else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {u8g.setColorIndex(3); // max intensity}else if ( u8g.getMode() == U8G_MODE_BW ) {u8g.setColorIndex(1); // pixel on}else if ( u8g.getMode() == U8G_MODE_HICOLOR ) {u8g.setHiColorByRGB(255,255,255);}queueTemp.point=0;queueHumi.point=0;previousMillis=0;previousMillis2=0;delay2hours=0;nowtime=0;fSetTemp=37.5;fSetHumi=60;fSetTempOff=0.3;fSetHumiOff=6;n_IsSetting=0;myservo1.attach(nTurnEgg);nAngleDirect=0;nDestAngle=20;sht20.initSHT20(); delay(100);sht20.checkSHT20(); }void loop (void) {//read temp and himidity loopcurrentMillis=millis(); //獲取當(dāng)前的系統(tǒng)運(yùn)行時(shí)間長(zhǎng)度if(currentMillis>=previousMillis+DELAY500){previousMillis=currentMillis;//fTemp_c = sht1x.readTemperatureC(); //讀取當(dāng)前溫度//fHumidity = sht1x.readHumidity(); //讀取濕度f(wàn)Temp_c = sht20.readTemperature(); //讀取當(dāng)前溫度f(wàn)Humidity = sht20.readHumidity(); //讀取當(dāng)前濕度Serial.println(fTemp_c);Serial.println(fHumidity);if(fTemp_c>0&&fTemp_c<40){//TrunEggs();Process_Temp_Humi();}else{digitalWrite(nLineHeat,LOW);digitalWrite(nLineHumid,HIGH);}// picture loopu8g.firstPage(); do {if(n_IsSetting)drawSetting();elsedraw();} while( u8g.nextPage() );}if(currentMillis-previousMillis2>=ONE_SECOND){previousMillis2=currentMillis;nowtime++;if(nowtime-delay1day>=259200){delay1day=nowtime;fSetTemp-=0.5;}if(nowtime-delay20second>=120){if(digitalRead(nLineCO2)==HIGH){digitalWrite(nLineCO2,LOW);}}if(nowtime-delay2hours>=3600){delay2hours=nowtime;delay20second=nowtime;digitalWrite(nLineCO2,HIGH);if(nAngleDirect){nDestAngle+=35;if(nDestAngle>=160){nDestAngle=160;nAngleDirect=!nAngleDirect;}}else{nDestAngle-=35;if(nDestAngle<=20){nDestAngle=20;nAngleDirect=!nAngleDirect;}}}}//delay fuction//Serial.println(delaytime-currentMillis);if(delaytime<=currentMillis){if(digitalRead(nLineHumid)==HIGH){digitalWrite(nLineHumid,LOW);}}n_IsSetting=0;n_SettingItem=1;//digitalWrite(nLineHumid,HIGH);/*if(digitalRead(nSwitch1)==HIGH){n_IsSetting=1;settingdelay=currentMillis+10000;n_SettingItem=++n_SettingItem&4;}if(settingdelay-currentMillis<=0){n_IsSetting=0;}*/ }

tempadmin.h

#ifndef _CPP_TEMPADMIN #define _CPP_TEMPADMIN typedef unsigned char uChar8; typedef unsigned int uInt16; typedef unsigned long int uInt32;//3,5,6,9,10,11對(duì)應(yīng)Pcduino V2單板的PWM引腳 //#define dataPin 10 //溫度傳感器data //#define clockPin 11 //溫度傳感器clock #define nLineHeat 9 //加熱引腳 #define nLineHumid 6 //加濕引腳 #define nLineCO2 12 //換氣引腳 #define nLineBeep 3 //報(bào)警接線 #define nTurnEgg 5 //翻蛋接口 #define nSwitch1 4 //switch1 #define nSwitch2 7 //switch2 #define nSwitch3 8 //switch3 #define nTempConst 300 //常量溫度,計(jì)算問(wèn)題的時(shí)候要加上這個(gè)常量除以10 #define DELAY500 500 #define ONE_SECOND 1000U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0); // I2C / TWI static float fTemp_c; static float fHumidity; int value; uInt32 g_un_count=0; static unsigned long currentMillis; static unsigned long previousMillis; static unsigned long nowtime; static unsigned long previousMillis2; static unsigned long delaytime; static unsigned long settingdelay; static unsigned long delay2hours; static unsigned long delay20second; static unsigned long delay1day=0;static float fSetTemp; static float fSetHumi; static float fSetTempOff; static float fSetHumiOff; static int n_IsSetting; static int n_SettingItem; static int nAngleDirect; //舵機(jī)旋轉(zhuǎn)方向 static int nDestAngle; //舵機(jī)目標(biāo)角度Servo myservo1;/* *循環(huán)隊(duì)列,用數(shù)組實(shí)現(xiàn) */ //隊(duì)列結(jié)構(gòu)體定義 typedef struct Queue { int pBase[6]; //用于動(dòng)態(tài)分配內(nèi)存,pBase保存數(shù)組的首地址 int point; //指向最后一個(gè)元素的下一結(jié)點(diǎn) } QUEUE; QUEUE queueTemp; QUEUE queueHumi;#endif

硬件安裝解讀

`










代碼的下載

`
https://github.com/rabbie-china/incubator

這個(gè)網(wǎng)站服務(wù)器放在國(guó)外,有時(shí)候打不開(kāi),多試幾次就能打開(kāi)


文件解讀

DFRobot_SHT20----------------------------溫濕度傳感器SHT20驅(qū)動(dòng)函數(shù)

u8glib_arduino_v1.18.1.zip---------------oled顯示驅(qū)動(dòng)

TempAdmin--------------------------------孵化箱主程序程序


函數(shù)解讀

為了控制溫度精準(zhǔn)性,程序用了隊(duì)列的形式處理濕度和溫度數(shù)據(jù)

void inQueue(QUEUE * pQueue,int value)-------------溫度和濕度壓入隊(duì)列等待處理

int traverseQueue(QUEUE * pQueue)------------------出隊(duì)列

void TrunEggs(void)--------------------------------翻蛋函數(shù),驅(qū)動(dòng)舵機(jī)

void draw(void)------------------------------------OLED顯示溫度和濕度

void Process_Temp_Humi(void)-----------------------處理當(dāng)前溫度和濕度模塊,程序采用了類(lèi)似pid的控制原理,精確控制溫度,精度可達(dá)到0.01度

溫度和濕度設(shè)定寫(xiě)在setup()函數(shù)

fSetTemp=37.5----------------------------------設(shè)定37.5度為目標(biāo)溫度

fSetHumi=60------------------------------------設(shè)定60%為目標(biāo)濕度

fSetTempOff=0.3--------------------------------設(shè)定上下0.3度為浮動(dòng)溫差

fSetHumiOff=6----------------------------------設(shè)定上下6%濕度為浮動(dòng)濕度差


關(guān)于孵化器的說(shuō)明

`
1.為啥不用傳統(tǒng)的繼電器,而改用MOS開(kāi)關(guān)的方式

因?yàn)槔^電器有壽命太短,通常繼電器只有幾萬(wàn)次開(kāi)關(guān)觸點(diǎn)。以前也用繼電器方式孵化雞蛋,因?yàn)槔^電器壽命的問(wèn)題,導(dǎo)致加熱電路無(wú)法斷開(kāi),導(dǎo)致雞蛋被烤熟的慘痛教訓(xùn),從此改用MOS開(kāi)關(guān)解決了這個(gè)問(wèn)題

2.關(guān)于加濕器的維護(hù)

我從網(wǎng)上購(gòu)買(mǎi)的USB加濕器模塊,很便宜,霧化片的壽命很短,建議購(gòu)買(mǎi)的時(shí)候另外購(gòu)買(mǎi)加濕器的霧化片配件。普通自來(lái)水中含有雜質(zhì),建議采用純凈水。

3.關(guān)于溫濕度

溫濕度都在程序里寫(xiě)死的,溫度保持在37.5攝氏度,濕度保持在60%左右,如果需要改溫濕度,可以自己修改,代碼在TempAdmin.ino文件,setup函數(shù),fSetTemp=37.5,fSetHumi=60

我將在下一個(gè)版本增加控制溫度和濕度的功能

4.孵化器有個(gè)自動(dòng)翻蛋功能,需要自己接舵機(jī)。函數(shù)模塊 TrunEggs(),只要在代碼里把功能模塊打開(kāi)就能起作用

5.關(guān)于溫濕度傳感器的保養(yǎng)

小雞孵化后,會(huì)在孵化箱內(nèi)到處跑,孵化箱的食物殘?jiān)鼤?huì)污染傳感器,很容易引起傳感器短路,買(mǎi)傳感器保護(hù)套來(lái)解決這個(gè)問(wèn)題。

6.孵化器工作溫度

由于傳感器或者開(kāi)關(guān)故障,引起溫度過(guò)高,程序做了保護(hù)模塊,當(dāng)傳感器的溫度處于1-40度之間,孵化器正常工作。如果孵化器的溫度低于0度或者高于40度,機(jī)器沒(méi)有任何反應(yīng)的,這是程序的保護(hù)機(jī)制。


作者列表

我叫rabbie,是一個(gè)熱愛(ài)自然的三腳貓程序員


聯(lián)系方式

如果你有問(wèn)題,請(qǐng)聯(lián)系我
郵箱:3126614@qq.com
QQ:3126614


總結(jié)

以上是生活随笔為你收集整理的如何用ARDUINO制作一个鸟蛋孵化器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。