用Ameba打造智慧盆栽監控器

作者:賴桑

目前市面上已經有很多的開發平台,可是面對琳瑯滿目的選擇,使用者常常不知所以然,這次我介紹的是Realtek推出的Arduino Compatible開發硬體平台Ameba,我利用了Ameba牛刀小試,製作了一個可以連接居家空氣品質、居家光照以及盆栽水位的感測值讀取裝置,當作開箱文。

家庭智慧植物園監控器

家庭智慧植物園監控器

材料清單

點以下連結可以看到各個感測器、模組的詳細說明:
1. Grove – Air Quality Sensor

Grove - Air Quality Sensor

Grove – Air Quality Sensor

  1. Grove – Light Sensor
Grove - Light Sensor

Grove – Light Sensor

  1. 水位感測模組
水位感測模組

水位感測模組

  1. Grove – Base Shield
 Grove - Base Shield

Grove – Base Shield

Ameba系統與接腳描述

1_6

接腳對應位置

接腳對應位置

以下是本文各裝置的實際對應接腳:

  • A0 : Grove – Air Quality Sensor
  • A1 : Grove – Light Sensor
  • A2 : 水位感測模組

原始程式碼:


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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
int i ;
long vol_standard;
int init_voltage;
int first_vol;
int last_vol;
int temp;
int counter;
boolean timer_index;
boolean error;

int current_quality =-1;

void setup()
{
    Serial.begin(9600);

    Serial.println("sys_starting...");
    delay(20000);
    init_voltage=analogRead(0);
    Serial.println("The init voltage is ...");
    Serial.println(init_voltage);
    while(init_voltage)
    {
        if(init_voltage<798 && init_voltage>10)// the init voltage is ok
        {
            first_vol=analogRead(0);//initialize first value
            last_vol=first_vol;
            vol_standard=last_vol;
            Serial.println("Sensor ready.");
            error=false;;
            break;
        }
        else if(init_voltage>798||init_voltage<=10)
        {  
            i++;
            delay(60000);//60000
            Serial.println("waitting sensor init..");
            init_voltage=analogRead(0);
            if(i==5)
            {
                i=0;
                error=true;
                Serial.println("Sensor Error!");
            }
          }
        else
        break;
    }
}

void avgVoltage()
{
    if(i==150)//sum 5 minutes
    {
        vol_standard=temp/150;
        temp=0;
        Serial.print("Vol_standard in 5 minutes:");        
        Serial.println(vol_standard);      
        i=0;        
    }
    else
    {
        temp+=first_vol;
        i++;
    }
}

int slope(void)
{
    while(timer_index)
    {
        if(first_vol-last_vol>400||first_vol>700)
        {
            Serial.println("High pollution! Force signal active.");    
            timer_index=0;  
            avgVoltage();  
            return 0;  
        }
        else if((first_vol-last_vol>400&&first_vol<700)||first_vol-vol_standard>150)
        {  
            Serial.print("sensor_value:");      
            Serial.print(first_vol);            
            Serial.println("\t High pollution!");      
            timer_index=0;  
            avgVoltage();
            return 1;
           
        }
        else if((first_vol-last_vol>200&&first_vol<700)||first_vol-vol_standard>50)
        {
            //Serial.println(first_vol-last_vol);
            Serial.print("sensor_value:");
            Serial.print(first_vol);            
            Serial.println("\t Low pollution!");        
            timer_index=0;
            avgVoltage();
            return 2;  
        }
        else
        {
            avgVoltage();  
            Serial.print("sensor_value:");
            Serial.print(first_vol);
            Serial.println("\t Air fresh");
            timer_index=0;
            return 3;
        }
    }
    return -1;
}

void loop()
{
    current_quality= slope();
    if (current_quality >= 0)// if a valid data returned.
    {
        if (current_quality==0)
            Serial.println("High pollution! Force signal active");
        else if (current_quality==1)
            Serial.println("High pollution!");
        else if (current_quality==2)
            Serial.println("Low pollution!");
        else if (current_quality ==3)
            Serial.println("Fresh air");

        Serial.print("Photo-resistor: ");
        Serial.println(analogRead(1));
        Serial.print("Water level: ");
        Serial.println(analogRead(2));
    }

    delay(10);      //Adjust here to make the time interval gets close to
                     //2 seconds
    virtualTimer();
}

void virtualTimer()  //Intel didn't support Timer2 ISR
{
    if(counter==122)//set 2 seconds as a detected duty
    {

            last_vol=first_vol;
            first_vol=analogRead(0);
            counter=0;
            timer_index=1;
    }
    else
    {
        counter++;
    }
}

基本原理解說

系統大約需要兩分鐘啟動,使得Grove – Air Quality Sensor能夠取樣進入穩定狀態,接著每次程式會以大約兩秒為間隔,求取A0、A1、A2的讀值,然後回報;這三個感測器A0、A2都是與感測目標成正比關係,也就是說汙染程度越高,A0會得到越高的讀值,水位越高A2的讀值也相對升高;只有A1,會因為遮蔽產生光照不足而讀值越低。

整個系統架構及實作過程可參考以下影片:

結語

Ameba的設計就是一個強過Arduino Due的Arduino!執行效能非常高,因為本身就是ARM Cortex系列的CPU為基礎開發的,此外還外帶了內建的WiFi、NFC reader,在很多Arduino應用的場合,根據價格、性能兩項來比較,確實有其優勢。

賴建宏

Author: 賴建宏

社群稱號為「賴桑」的他,以電子電機的背景,熱衷於OSHW的應用開發與實作。取得台北科技大學電子所博士學位,目前主推「農林漁牧大業」計畫的迷你型魚菜共生系統開發。

Share This Post On

Submit a Comment

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *