采用了oled显示屏,用于显示设置菜单和数据可以设置定时浇花,背光,继电器参数和智能浇花
通过多线程,做到精确定时和浇花时播放洒水车BGM
实际测试
启动LOGO
代码片段
单片机源程序如下:
- #include <Metro.h>
- #include <Adafruit_GFX.h>
- #include <Adafruit_SSD1306.h>
- #define OLED_RESET 4
- Adafruit_SSD1306 display(OLED_RESET);
- #define LOGO16_GLCD_HEIGHT 16 //定义显示高度
- #define LOGO16_GLCD_WIDTH 16 //定义显示宽度
- #if (SSD1306_LCDHEIGHT != 64)
- #error("Height incorrect, please fix Adafruit_SSD1306.h!");
- #endif
- int h=0;
- int m=0;
- int s=0;
- int SOLEDT=300; //默认背光时间为300刻
- int SRT=5; //设置浇灌时间为5 警告:如果为0将无限浇灌 导致水浸田
- int RT=0; //浇灌时间
- boolean RTM=false; //继电器模式 默认为True即VCC
- boolean WSP=false; //是否开启缺水保护
- int SM=0; // 传感器值的存储变量
- int HC=50; // 湿度缓存
- int CST=0; //运行周期检测一次泥土湿度
- int OLEDT=300; //OLED点亮时间
- int NKey=0; //按键数量
- int CL=1; //选择图标位置
- String CM="SET"; //选择处在模式
- String soil = "ERROR"; //土壤状态初始化
- boolean DEBUG = false; //DEBUG模式
- boolean TR=false; //计时器默认关闭 除非手动设置
- int TH=0; //默认计时浇灌为0小时 除非手动设置
- //字符存储区
- static const unsigned char PROGMEM choose[] = {0x18,0x38,0x78,0xF8,0xF8,0x78,0x38,0x18,}; //选择图案
- static const unsigned char PROGMEM logo[] = {
- 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,
- …………
- …………
- …………限于本文篇幅 字库请从51黑下载附件…………
- 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,}; //LOGO
- //请不要修改上面这一部分,尊重一下作者谢谢!
- //声音合成器音调
- #define NOTE_G0 -1
- #define NOTE_G1 393
- #define NOTE_G2 441
- #define NOTE_G3 495
- #define NOTE_G4 556
- #define NOTE_G5 624
- #define NOTE_G6 661
- #define NOTE_G7 742
- #define NOTE_GL1 196
- #define NOTE_GL2 221
- #define NOTE_GL3 234
- #define NOTE_GL4 262
- #define NOTE_GL5 294
- #define NOTE_GL6 330
- #define NOTE_GL7 371
- #define NOTE_GH1 786
- #define NOTE_GH2 882
- #define NOTE_GH3 990
- #define NOTE_GH4 1049
- #define NOTE_GH5 1178
- #define NOTE_GH6 1322
- #define NOTE_GH7 1484
- #define WHOLE 1
- #define HALF 0.5
- #define QUARTER 0.25
- #define EIGHTH 0.25
- #define SIXTEENTH 0.625
- //列出所有节拍
- int tune[]= //根据简谱列出各频率
- {
- /*
- NOTE_GL3,NOTE_GL4,
- NOTE_GL5,NOTE_GL3,
- NOTE_G1,NOTE_G2,NOTE_G1,
-
- NOTE_G1,NOTE_GL7,
- NOTE_GL7,NOTE_GL2,NOTE_GL3,
- NOTE_GL4,NOTE_G2,
- NOTE_GL7,NOTE_G1,NOTE_GL7,
- NOTE_GL6,NOTE_GL5,
- NOTE_GL5,NOTE_GL3,NOTE_GL4,
- NOTE_GL5,NOTE_G1,NOTE_G2,
- NOTE_G3,NOTE_G2,NOTE_G1,
- NOTE_GL6,NOTE_G2,NOTE_G3,
- NOTE_G4,NOTE_G3,NOTE_G2,
- NOTE_GL5,NOTE_G4,
- NOTE_G3,NOTE_G2,
- NOTE_G1,
- NOTE_G1,
- */
- NOTE_G1,
- NOTE_G3,NOTE_G1,
- NOTE_G2,NOTE_G2,
- NOTE_G2,
- NOTE_G2,NOTE_G2,
- NOTE_G4,NOTE_G2,
- NOTE_G3,NOTE_G3,
- NOTE_G3,
- NOTE_G3,NOTE_G3,
- NOTE_G5,NOTE_G3,
- NOTE_G4,NOTE_G4,
- NOTE_G4,NOTE_G3,NOTE_G2,
- NOTE_GL5,
- NOTE_GL7,
- NOTE_G1,
- NOTE_G1,
- };
- float duration[]={1,2,2,3,1,4,3,1,2,2,3,1,4,3,1,2,2,3,1,2,1,1,4,4,4,2,};
- int length;//这里定义一个变量,后面用来表示共有多少个音符
- Metro T1 = Metro(0); //主程序
- Metro T2 = Metro(1000); //定时器
- void setup() {
- display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3D (for the 128x64)
- pinMode(12, OUTPUT); //继电器GPIO
- pinMode(11, INPUT); //上GPIO
- pinMode(10, INPUT); //下GPIO
- pinMode(9, INPUT); //左GPIO
- pinMode(8, INPUT); //右GPIO
- pinMode(7, INPUT); //AGPIO
- pinMode(6, INPUT); //BGPIO
- digitalWrite(11,LOW);
- digitalWrite(10,LOW);
- digitalWrite(9,LOW);
- digitalWrite(8,LOW);
- digitalWrite(7,LOW);
- digitalWrite(6,LOW);
- display.clearDisplay();
- pinMode(5,OUTPUT);//设置蜂鸣器的pin为输出模式
- length = sizeof(tune)/sizeof(tune[0]);//这里用了一个sizeof函数,可以查出tone序列里有多少个音符
- display.drawBitmap(0, 0, logo, 128, 64, 1);
- display.display();
- delay(2000);
- }
- void loop() {
- if(T1.check()){
- //###############################################################
- //检测按键 如果其中一个按键激活 那么点亮屏幕
- for (int i = 6; i < 12; i++) {
- if (digitalRead(i) == HIGH) {
- NKey +=1;
- OLEDT=SOLEDT; //设置OLED亮屏时间为多少个程序周期
- }
- }
- //###############################################################
- if (WSP == true) {
- if (CST > 30) {
- CST=0;
- //100个程序周期执行一次
- SM = analogRead(A0); //获取泥土湿度数据
- if (SM > 500) {
- soil = "wet";
- if (HC < 100) {
- HC +=1;
- }
- } else {
- soil = "dry";
- HC -=1;
- }
- if (HC < 1) {
- HC = 50;
- RT = 10;
- }
- }
- }
- //###############################################################
- //浇灌程序
- if (RT > 0) {
- for(int x=0;x<length;x++)//循环音符的次数
- {
- tone(5,tune[x]);//此函数依次播放tune序列里的数组,即每个音符
- delay(300*duration[x]);//每个音符持续的时间,即节拍duration,400是调整时间的越大,曲子速度越慢,越小曲子速度越快,自己掌握吧
- noTone(5);//停止当前音符,进入下一音符
- }
- if (RTM == true) {digitalWrite(12,HIGH);} else {digitalWrite(12,LOW);}
- delay(1000*RT);
- RT=0;
- }
- if (RTM == true) {digitalWrite(12,LOW);} else {digitalWrite(12,HIGH);}
- //###############################################################
- //计算部分
- CST +=1; //土壤检测器运行周期
- if (NKey == 2) {
- if (DEBUG == true) {DEBUG=false;}else{DEBUG=true;}
- delay(200);
- }
- NKey=0; //有多少个按键同时在按
- //菜单选择按钮移动
- if (digitalRead(11) == HIGH) {if (CL > 1) {CL -=1;}delay(100);} //按上键
- if (digitalRead(10) == HIGH) {CL +=1;delay(100);} //按下键
- if (CM == "SET") {if (CL > 4) CL=4;}
- if (CM == "RW") {if (CL > 3) CL=3;}
- if (CM == "BL") {if (CL > 1) CL=1;}
- if (CM == "R") {if (CL > 1) CL=1;}
- if (CM == "WSP") {if (CL > 1) CL=1;}
- //按下左键
- if (digitalRead(9) == HIGH) {
- if (CM == "RW") {if (CL == 2) {if (TH > 0) {TH -=1;TR=false;}}} //进入设置定时减一小时
- if (CM == "RW") {if (CL == 3) {if (SRT > 5) {SRT -=1;TR=false;}}} //进入设置定时-1s
- if (CM == "BL") {if (CL == 1) {if (SOLEDT > 10) {SOLEDT -=10 ;}}} //设置背光
- delay(50);
- }
- //按下右键
- if (digitalRead(8) == HIGH) {
- if (CM == "RW") {if (CL == 2) {if (TH < 999) {TH +=1;TR=false;}}} //进入设置定时加一小时
- if (CM == "RW") {if (CL == 3) {if (SRT < 999) {SRT +=1;TR=false;}}} //进入设置定时+1s
- if (CM == "BL") {if (CL == 1) {SOLEDT +=10;}} //设置背光
- delay(50);
- }
- //当按下A键后
- if (digitalRead(7) == HIGH) {
- if (CM == "RW") {if (CL == 1) {if (TR == true) {TR=false;} else {if (TH > 0){TR=true;h=TH;}}}} //进入设置定时浇灌是否开启
- if (CM == "R") {if (CL == 1) {if (RTM == true) {RTM=false;} else {RTM=true;}}} //设置继电器触发模式
- if (CM == "WSP") {if (CL == 1) {if (WSP == true) {WSP=false;} else {WSP=true;}}} //设置继电器触发模式
- if (CM == "SET") {if (CL == 1) {CM="RW";}} //进入设置定时器
- if (CM == "SET") {if (CL == 2) {CM="BL";}} //进入设置背光时间
- if (CM == "SET") {if (CL == 3) {CM="R";}} //进入设置继电器
- if (CM == "SET") {if (CL == 4) {CM="WSP";}} //进入设置缺水保护
- delay(150);
- }
- //按下B键
- if (digitalRead(6) == HIGH) {CM="SET";delay(50);} //返回主菜单
- //如果定时浇花到时间就启动浇灌
- //if (TR == true) {if (millis()/1000/3600 > TS) {TS=((millis()/1000/3600)+TH)-1; RT=SRT;}}
- //###############################################################
- //显示部分
- display.clearDisplay();
- if (OLEDT > 0) {
- OLEDT -=1;
- display.setTextSize(1); //设置字体大小
- display.setTextColor(WHITE); //设置字体颜色白色
- display.setCursor(0,0); //设置字体的起始位置
- //DEBUG显示
- if (DEBUG == true) {
- display.println(" DEBUG MODE"); //输出字符
- display.print("soil moisture: "); //输出字符
- display.println(soil); //输出字符并换行
- display.print("HC: "); //输出字符
- display.println(HC); //输出字符并换行
- display.print("Running Time: "); //输出字符并换行
- display.println(millis()/1000); //输出字符并换行
- display.print(h);
- display.print(":");
- display.print(m);
- display.print(":");
- display.println(s);
- }else{
- //正常显示区
- display.setTextSize(1); //设置字体大小
- //设置界面
- if (CM == "SET") {
- display.println(">>SET"); //输出字符
- display.println("1.Regular watering");
- display.println("2.Backlight");
- display.println("3.Relay");
- display.println("4.Soil detector");
- display.println("");
- display.println("");
- display.println("2018-1-17 v2.1.1");
- display.drawBitmap(119, 8*CL, choose, 8, 8, 1);
- }
- //设置定时界面
- if (CM == "RW") {
- display.println(">>Regular Watering"); //输出字符
- display.print("1.state: ");
- if (TR == true) {display.println("True");}else{display.println("False");}
- display.print("2.timing: ");
- display.print(TH);
- display.println(" Hours");
- display.println("3.Watering time: ");
- display.print(" ");
- display.print(SRT);
- display.println(" Sin");
- }
- //设置背光界面
- if (CM == "BL") {
- display.println(">>Backlight"); //输出字符
- display.print("1.Time: ");
- display.print(SOLEDT);
- display.println(" t");
- }
- //设置继电器界面
- if (CM == "R") {
- display.println(">>Relay"); //输出字符
- display.print("1.Trigger mode: ");
- if (RTM == true) {display.println("HIGH");}else{display.println("LOW");}
- }
- //设置缺水保护界面
- if (CM == "WSP") {
- display.println(">>WSP"); //输出字符
- display.print("1.state: ");
- if (WSP == true) {display.println("True");}else{display.println("False");}
- }
- //画光标
- display.drawBitmap(119, 8*CL, choose, 8, 8, 1);
- }
- }
- display.display(); //把缓存的都显示
- }
- if(T2.check()){
- if (TR == true) {
- s -=1; //续一秒献给长者
- if (s<0) {
- if (m>0) {
- m -=1;
- s=59;
- }else{
- if (h>0) {
- h -=1;
- m=59;
- s=59;
- }else{
- //时间到了浇花!
- h=TH-1;
- …………
- …………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
water.zip
(4.19 KB, 下载次数: 95)
|