Attiny的功耗和功能在我看来做一个浇花的水泵控制器还是很不错的。以前动手做过,但失败的一塌糊涂,也懒得找原因。今天又把过去的玩儿捡起来,重新鼓捣一番,给它加了个LED显示器,看看它的葫芦里到底装的什么药。结果还真发现了它的秘密。原来在用Arduino IDE为它做C++编程时,表达式中不接受 unsigned long 和 int 两种类型时间的混用,不知道这算不算是bug。总之数据是乱的,动作自然就失控了。
这次做了一个复古风格的设计,用电位器(而不是按键)设定水泵工作的时长。自我感觉有点儿意思。
好久没过来了,这里把代码贴出来:
#include "SSD1306_minimal.h"
#include <avr/pgmspace.h>
SSD1306_Mini oled;
#define PUMP 1
unsigned long t; //浇水间隔的周期
unsigned long tnext;
void setup() {
oled.init(0x3c);
oled.clear();
oled.startScreen();
oled.cursorTo(0, 1);
oled.printString("Pump Controler");
oled.cursorTo(0, 2);
oled.printString("Based on Attiny85");
oled.cursorTo(0, 4);
oled.printString("By zintiger");
oled.cursorTo(0, 6);
oled.printString("v1.0 2021.6");
delay(3000);
oled.clear();
pinMode(PUMP, OUTPUT);
t=86400; //每间隔24小时启动一次。
tnext=t;
}
void loop() {
char s[32];
unsigned long tc=millis()/1000;
sprintf(s,"CPU clock=%d",tc);
//oled.clear();
oled.cursorTo(0, 1);
oled.printString(s);
//注意,attiny的C程序在unsigned long 和 unsigned int 混用的时候,会出现计算错误。
unsigned long cdt = tnext-tc; //倒计时时长(s)
unsigned long h=cdt/3600;
unsigned long m=(cdt-h*3600)/60;
unsigned long sec=cdt-h*3600-m*60;
sprintf(s,"%02lu:%02lu:%02lu",h,m,sec);
oled.cursorTo(0, 3);
oled.printString(s);
int sensorValue = analogRead(A2);//芯片的第3脚,获得电位器数据(0-1023)
int dt=sensorValue/34; //换算成水泵工作时长0-30秒。
sprintf(s,"Pump work %2d(s)",dt);
oled.cursorTo(0, 5);
oled.printString(s);
if(tc>tnext){
tnext+=t;
digitalWrite(PUMP, HIGH); // turn the Pump on.
delay(dt*1000);
digitalWrite(PUMP, LOW); // turn the Pump off.
}
delay(1000);
}