ESP8266 Non-OS SDK開發應用之一 — 控制水泵定時澆花

esp8266做到現在,該應用一下了,就做了個定時澆花的。

原理上不外乎該系列前面的文章,多加了一個鬧鈴設置程序。並且在tcp server和MQTT配置里加上了設置方式。

硬件上除了自己打板的esp8266-01繼電器控制板,另外需要一個小板子用來插接控制板和水泵,水泵的兩極需要電容和續流二極管,否則繼電器工作會受影響。供電部分因爲是四套控制裝置,總電流峯值會達到近4A,所以用了個5V6A的電源。

總的來說,硬件上集合了浪涌防護,反接保護,短路保護,繼電器續流保護,手動復位按鍵,復位電容泄放二極管,多IO口引出,多取電接口,軟件上有flash參數讀寫保護,參數序列化掉電恢復,內存允許範圍內可定義多組鬧鈴(一個鬧鈴佔12字節空間,上百組沒問題),ntp時間同步,自動域名解析,web配置,tcp server配置服務,tcp client狀態上報,MQTT客戶端狀態發佈和控制命令訂閱等等。這裏只重點說下鬧鈴功能編碼。

鬧鈴設置支持MQTT推送設置,支持TCP server命令控制,可以按時、分、秒、日、星期重複。鬧鈴結構體,包含成員:ID,重複模式,開始時間,結束時間,重複間隔(在某些重複模式下有效):

1

2

3

4

5

6

7

typedef struct STAlarm{

uint8 ID;

EPepeatMode RptMode;

uint32 Start;

uint32 Stop;

uint32 RptIntvl; //<0 error, =0 for no repeat, >0 for seconds wait to realarm

}STAlarm;

用一個重複的系統定時任務進行鬧鈴響應檢測,在定時任務回調函數裏進行鬧鈴判斷、ntp同步等,該定時任務可以根據所需要的定時精度進行宏設定,比如要實現秒級的鬧鈴,可將定時任務的間隔設置小於1000,但是不能太小,否則系統頻繁觸發定時任務,而且注意該定時任務並不精確,因而不能指望鬧鈴的時間準確,包括ntp時間同步也不精確,只是期望獲得日期信息。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

void ICACHE_FLASH_ATTR

AlarmTimerCB(){

LOCAL uint32 sntpQueryCtn = 0;

if(sntpQueryCtn == 0 || timeStamp==0){

uint32 timeStampTmp;

timeStampTmp = sntp_get_current_timestamp();

if(timeStampTmp !=0){

timeStamp = timeStampTmp;

//9-10 0:0:0 -- 17784 days= 1,536,451,200s

TRACE("sntp time stamp:%d,%s\n",timeStamp,sntp_get_real_time(timeStamp));

}else if(timeStamp> SNTP_QUERY_INTVL * 2){

timeStamp += ALARM_CHK_INTVL/1000;

}

}else if(timeStamp> SNTP_QUERY_INTVL * 2){

timeStamp += ALARM_CHK_INTVL/1000;

}

os_printf("time stamp:%d,%s\r\n",timeStamp,sntp_get_real_time(timeStamp));

 

if(timeStamp>0 && bAlarmEnable){

bool bRun = false;

int i=0;

for(i=0;i<MAX_ALARM_NUM;i++){

 

TRACE("alarm id:%d:%d:%d:%d:%d\r\n",stFlashProtParam.AlarmQueue[i].ID,

stFlashProtParam.AlarmQueue[i].RptMode,

stFlashProtParam.AlarmQueue[i].Start,

stFlashProtParam.AlarmQueue[i].Stop,

stFlashProtParam.AlarmQueue[i].RptIntvl);

 

if(stFlashProtParam.AlarmQueue[i].RptMode == RPT_ONLY_ONCE ){

if(timeStamp >= stFlashProtParam.AlarmQueue[i].Start && timeStamp < stFlashProtParam.AlarmQueue[i].Stop){

bRun = true;

}else if(timeStamp >= stFlashProtParam.AlarmQueue[i].Stop && timeStamp <= stFlashProtParam.AlarmQueue[i].Stop + ALARM_EXPIRE){

stFlashProtParam.AlarmQueue[i].RptMode = 0-RPT_ONLY_ONCE;

SaveFlashProtParam();

}

}else if(stFlashProtParam.AlarmQueue[i].RptMode > 0 && stFlashProtParam.AlarmQueue[i].RptMode <= DAYS_OF_WEEK){

if(timeStamp >= stFlashProtParam.AlarmQueue[i].Start && timeStamp < stFlashProtParam.AlarmQueue[i].Stop){

bRun = true;

}else if(timeStamp >= stFlashProtParam.AlarmQueue[i].Stop){// && timeStamp <= stFlashProtParam.AlarmQueue[i].Stop + ALARM_EXPIRE){

switch(stFlashProtParam.AlarmQueue[i].RptMode){

case EVERY_HOUR:

stFlashProtParam.AlarmQueue[i].Start += 3600;

stFlashProtParam.AlarmQueue[i].Stop += 3600;

break;

case EVERY_DAY:

stFlashProtParam.AlarmQueue[i].Start += 86400;

stFlashProtParam.AlarmQueue[i].Stop += 86400;

break;

case EVERY_WEEK:

stFlashProtParam.AlarmQueue[i].Start += 86400*7;

stFlashProtParam.AlarmQueue[i].Stop += 86400*7;

break;

case EVERY_MONTH:

break;

case EVERY_YEAR:

break;

case INTVL_SECS:

stFlashProtParam.AlarmQueue[i].Start += stFlashProtParam.AlarmQueue[i].RptIntvl;

stFlashProtParam.AlarmQueue[i].Stop += stFlashProtParam.AlarmQueue[i].RptIntvl;

break;

case INTVL_MINS:

stFlashProtParam.AlarmQueue[i].Start += stFlashProtParam.AlarmQueue[i].RptIntvl * 60;

stFlashProtParam.AlarmQueue[i].Stop += stFlashProtParam.AlarmQueue[i].RptIntvl * 60;

break;

case INTVL_HOURS:

stFlashProtParam.AlarmQueue[i].Start += stFlashProtParam.AlarmQueue[i].RptIntvl * 3600;

stFlashProtParam.AlarmQueue[i].Stop += stFlashProtParam.AlarmQueue[i].RptIntvl * 3600;

break;

case INTVL_DAYS:

stFlashProtParam.AlarmQueue[i].Start += stFlashProtParam.AlarmQueue[i].RptIntvl * 86400;

stFlashProtParam.AlarmQueue[i].Stop += stFlashProtParam.AlarmQueue[i].RptIntvl * 86400;

break;

case DAYS_OF_WEEK:

break;

default:

break;

}

SaveFlashProtParam();

}

}

}

if(bRun){

RelayOn();

}else{

RelayOff();

}

}

 

sntpQueryCtn++;

sntpQueryCtn %= SNTP_QUERY_INTVL;

下面放圖

原博客:

http://www.straka.cn/blog/esp8266-alarm-to-water/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章