由於發電技術目前正向使用更清潔、更智能的原料的方向發展,因此小規模的光電板陣列如雨後春筍般湧現。其中有些安裝很複雜,涉及到高度的監控和自調節功能;有些則沒有自我感知 (self-awareness) 功能。在後一種情況下,對於所有者而言,若能有一種好的、經濟的渠道來獲得基本的運行數據,則很有幫助。
您可能想知道,在給定條件下,光電板能否有效工作。光和溫度,外加風速和其他因素都能影響面板的輸出。光越多產生的電就越多,但是發電越多,單元就會受熱,會導致降低效率。氣流有助於散熱。理論而言,最理想的是明光低溫的條件,外加涼風或其他的人工冷卻方式。
Arduino 可充當傳感器和數據存儲器之間的媒介。製作永久性記錄以及根據需要顯示數據是再直白不過的事情了。本文將研究如何使用 TMP36 溫度傳感器記錄溫度數據,如何用一個簡單的發光二極體 (LED) 進行發光。
回頁首
ArduinoArduino 是一種經濟的、可調節和可編程的開源微處理器,可讀取其模擬插腳處的電壓形式的數據輸入。請參考 參考資料 部分,以獲得有關此單元的基本信息,以及對遊戲環境下的該單元的 developerWorks 簡介。傳感器連接到特定的輸入插腳後,此單元便可通過編程的方式讀取這些插腳處的數據。而它處理該信息的方式則取決於硬體的配置。
從 Arduino 獲得數據最簡單的方式是讓此單元直接連接到主機計算機的 Universal Serial Bus (USB) 接口,像串行連接那樣讀取數據。不過,如果給定供電電源和一個備用通信信道,Arduino 也可以獨立於計算機工作。可以向 Arduino 添加擴展板(即 "shields"),將數據直接存儲到一個 microSD 內存卡內,通過 mini Web 伺服器在一個 cat5e 的網絡電纜上傳遞數據,甚至可以將數據無線傳輸到一個兼容的接收器中。
圖 1 顯示了一個裝了 Ethernet shield、cat5 Ethernet 及電源電纜的 Arduino 微處理器,此圖可讓您對此單元的規模有一個大致的了解。
圖 1. 具有 Ethernet shield 的 Arduino某些傳感器自身就具有數據平滑內部電路。而有些較簡單的傳感器則不具備。因此,這裡就會有問題出現,比如 Arduino 應該在存儲或傳輸之前進行所有必需的處理,還是應該簡單地按原始觀測的數據那樣報告數據,以便日後在另一臺機器上處理這些數據。這兩種方式都是完全可以接受的。本項目選擇了只簡單報告原始的觀測數據供日後處理。這就提供了根據需要對算法進行更改的可能性。在應用平滑過程之後,就會固定該過程,且該過程可能是不可逆的。在實際的數據情況下,如果已經知道平滑的要求,那麼讓 Arduino 來做平滑處理就更為有意義了。
回頁首
傳感器可用於 Arduino 的傳感器種類繁多。在這裡,TMP36 和 LED 的使用展示了一種簡單、經濟且容易重複的方式。
TMP36 是一個特殊構造的電晶體。給它一個電壓,它會返回根據不同組合連接器上的外界溫度而不斷改變的另一個電壓。只需記錄輸出電壓並執行一些簡單的計算,就能找到以攝氏度或華氏度為單位的溫度。參見 參考資料 部分,以獲得有關此晶片以及如何將其連接到 Arduino 的幫助。
在一個太陽能發電的環境中記錄溫度數據看起來再簡單不過了,但還是有一些困難需要克服。第一個問題與外界溫度有關,即決定將傳感器放到哪裡。為了避免錯誤的讀數,一般要將其放置於直射陽光之外、不受天氣影響且通風很好的一個地方。第二,太陽能板是由一些非同單元組成的,在相同的外界條件下,每個單元各自的運行溫度不同。在理想條件下,可以測試所有的單元,然後採用平均數。另一種方式是試驗一系列單元,以確定一個具有代表性的平均單元,然後再單獨監測這個單元。
一個 LED 既可以在給定了電壓且電流合適時亮起來,又可以在光照下生成電壓(請參見 參考資料 部分給出的 Mike Cook 的文章)。光照越強,Arduino 在連接插腳處讀取的電壓越多。設計為可對應於某個特定溫標的溫度傳感器有所不同,您必須通過試驗來了解如何將 LED 的輸出轉變成數值範圍已知的光強。
實用設置假設您太陽能陣列的位置有電源,沒有 Ethernet 的區域網 (LAN) 插口,但是處於無線接入點的範圍之內。本地的電源可支撐這個無線接入點和 Arduino 的用電,且 Arduino 及 Ethernet shield 插入到中繼器。模擬的插腳 3 到 6 可供傳感器輸入使用;假設插腳 1 和 2 保留給 Ethernet shield 使用(查看 參考資料,以了解有關插腳使用的更多信息)。四個插腳意味著可以有四個傳感器,比如兩個溫度傳感器(一個用於外界溫度,一個用於面板溫度)、一個光傳感器和一個風速傳感器。對於一個被動面板設置而言,這已經是一組豐富的數據集了。
Arduino 和傳感器之間的短距離連接可以用常規的 cat3 電話線(兩對未屏蔽的 24 美國線標的電線)就可以實現。這意味著您將能夠使用現成可用的電話適配器和布線。
與只有 USB/串行連接的 Arduino 相比,Arduino 與 Ethernet shield 的組合使用並不那麼容易。以下是一些需要特別考慮的細節:
通常您無需輪詢沒有連接傳感器的插腳處的電壓。
通過一個圓柱式連接器,Arduino 能夠接受一定電壓範圍內的電源(有關更多細節,請參閱 參考資料)。模擬管腳電壓讀數緊密取決於 Arduino 的供電電壓。請確保您進行傳感器校準所用的供電單元與將來在現場使用的供電單元是相同的。高級用戶一般還會使用 Analog Reference (AREF) 管腳來提供參考電壓。
請將溫度傳感器放在太陽能單元的背後。管帶 (duct tape) 完全可以將該傳感器固定在單元背後,在短時間溫暖較高的情況下也沒有問題,但需要確保所有裸露的電線和連接器都用良好的絕緣膠帶保護好和絕緣好。在外界溫度為 20 攝氏度(69 華氏度)、有亮光照射並且有穩定的微風吹動下,單元的正常運行單元溫度 (NOCT) 上升到 50 攝氏度(124 華氏度)的情況並不罕見。
附帶 Ethernet shield 的 Arduino 對電源需求很大。如果您使用的是一組全充的 AA 電池來提供電壓和電流,那麼它們只能支撐幾個小時。高級用戶一般會用睡眠模式來控制用電。
圖 2 顯示了連接到太陽能架和面板的 TMP36 傳感器。在右側的黑色絕緣膠帶下,是一個感應金屬杆的外界溫度的傳感器。左側是用布基膠帶連接到太陽能單元背後的第二個傳感器。與普通的絕緣膠帶相比,布基膠帶的粘性要更好一些,至少短期內如此。
圖 2. 面板上的傳感器圖 3 顯示了位於一個倒轉試管(用來做防雨保護)內的一個綠色 LED。
圖 3. 光傳感器用來訪問所收集數據的 Arduino 程序(或 sketch,Arduino 對它的稱謂)是一個簡單的 Web 伺服器,可通過一個瀏覽器或其他腳本(參見 清單 1)訪問它。基本代碼由 Arduino 作為示例集合的一部分提供,並需要根據您自身的需求做一些修改(參見 參考資料)。
清單 1. Arduino web 伺服器// based on example web server sketch from http://arduino.cc/#include <SPI.h>#include <Ethernet.h>//byte mac[] = { 0x!!, 0x!!, 0x!!, 0x!!, 0x!!, 0x!! };byte ip[] = { 192,168,0,xxx };Server server(80);//void setup(){ // start the Ethernet connection and the server: delay(10000); Ethernet.begin(mac, ip); server.begin();}//void loop(){ // listen for incoming clients Client client = server.available(); if (client) { // an http request ends with a blank line boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); // if you've gotten to the end of the line (received a newline // character) and the line is blank, the http request has ended, // so you can send a reply if (c == '\n' && currentLineIsBlank) { // send a standard http response header client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println(); // // output the value of each analog input pin for (int analogChannel = 3; analogChannel < 7; analogChannel++) { //client.print("analog input "); client.print(analogChannel); client.print(" : "); client.print(analogRead(analogChannel)); client.println("<br />"); } break; } if (c == '\n') { // you're starting a new line currentLineIsBlank = true; } else if (c != '\r') { // you've gotten a character on the current line currentLineIsBlank = false; } } } // give the web browser time to receive the data delay(1); // close the connection: client.stop(); }}
清單 1 首先指定所需的 header 庫、Ethernet shield 的 Media Access Control (MAC) 地址以及 Internet Protocol (IP) 地址(通過該地址標識 Arduino)。它還設置了一個伺服器對象和一個變量來存儲可能以後會丟棄的值。setup() 子例程只在啟動時運行一次,以便初始化伺服器。loop() 子例程無限循環,等待一個 Hypertext Transfer Protocol (HTTP) 請求,然後用所需數據進行回答。為了響應此請求,它發送一個標準的 HTTP 響應頭、從相關管腳收集讀數並以文本格式發送數據包。在本例中,所提供的數據是該請求瞬間在模擬管腳 3、4、5 和 6 上所經歷的電壓值。沒有針對管腳 1 和 2 發送數據,因為這兩個管腳由 Arduino 板和 Ethernet shield 之間的接口使用。可更改通道的範圍來只讀取使用中的管腳的值。
響應應該類似於 清單 2 所示的輸出。
清單 2. Arduino 響應3 : 2924 : 2885 : 2866 : 280
上述代碼給出了管腳的編號以及 0 至 1023 範圍內的數值,兩個數字之間以冒號分隔。輸出也可能比僅指定模擬管腳編號更為具體,但是本機編號靈活性更好,因為它不會將任何一個管腳束縛到某一項作業上。
回頁首
數據存儲接下來要考慮的事情是數據如何存儲。在本例中,將使用 MySQL 作為後端,如 清單 3 所示。
清單 3. 後端表CREATE TABLE IF NOT EXISTS `readings` ( `readid` int(11) NOT NULL AUTO_INCREMENT, `tstamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `pin` int(11) NOT NULL, `value` float NOT NULL, PRIMARY KEY (`readid`)) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
此代碼會創建一個表,其中包含 ID 欄位、默認為此項的系統時間的時間戳、讀數所對應的管腳以及實際讀數所對應的一個欄位,在本例中,存儲用一個浮點數表示。
回頁首
數據收集和整理定義好後端之後,現在就可以使用 PHP 來查詢此 Arduino、分析響應以及在後端存儲觀察結果,如 清單 4 內所示。
清單 4. PHP 數據記錄腳本<?php// reader for panel monitors$fp = fopen("http://192.168.0.xxx","r");$mysqli = new mysqli("$server",$username,$password,$mysolar);while ($line = fgets($fp,32)) { $line = str_replace("
","",trim($line)); $key = substr($line,0,1); switch ($key) { case 3: // things to do break; case 4: // things to do break; case 5: // this is light from LED recorded as is $val = (int) substr($line,4); $sql = "insert into readings values(NULL,NULL,$key,$val)"; $result = $mysqli->query($sql); //echo "val = $val\n"; break; case 6: // temperature from a TMP36 attached to back of solar cell $val = (int) substr($line,4); $tmp = degc($val); // convert to Celsius/Centigrade $tmp -= 5; // calibration $sql = "insert into readings values(NULL,NULL,$key,$tmp)"; $result = $mysqli->query($sql); break; default: //echo "Found strange key $key!\n"; break; }}function degc($v) { $t = $v * (5/1024); $t -= 0.5; $t *= 100; return round($t,1);}?>
腳本首先在一個文件指針內打開對 Arduino 的連接,以便讀取它。然後打開對 MySQL 後端的連接,以便處理數據輸出。之後它會等待來自 Arduino 的響應,並進入某個循環來讀取所報告的行。這四個預期行中的任何一行都會包含一個 Hypertext Markup Language (HTML) 回車標記,這使得在測試的同時在瀏覽器中讀取輸出變得更為簡單。本腳本會刪除這個回車。結果行以管腳編號開始,後跟所找到的電壓。以管腳編號為中心,然後再進入到一個 switch 結構,根據連接到此管腳的傳感器來採取不同的措施。
校準也是在這一步中進行。也就是說,如果您發現某個傳感器總是偏高於某個特定數值,那麼就可以減去該數值後再報告最終的數值。有一個特定的函數可以將從 TMP36 測得的毫伏數轉變為攝氏度,範圍也將從 0-1023 轉改為從 1-5,找到零點後即可將結果縮放 100。最後,它將處理好結果,並將四捨五入後的數值存儲在資料庫內。那麼如何才能知道傳感器是否需要校正呢?其中的一個方法是測量行為類似於針對某個點的單元,並記錄輻射率溫度讀取器。
insert SQL 語句以兩個 NULL 值開頭,允許後端用第一個 NULL 值替代自增量的 ID 號,用第二個 NULL 值替換當前的時間戳,然後插入此管腳的編號以及該管腳處的讀數。您從 crontab 列表使用此腳本進行常規的處理,也可以根據需要從命令行運行該腳本。
回頁首
圖表顯示後端填充好數據後,下一個任務就是讓讀者很容易讀懂這些數據。可用的圖表庫有很多,各自有各自的優缺點。Flotr(參見 參考資料)是使用 JavaScript 在瀏覽器窗口中顯示圖表的一個例子。清單 5 中所示的代碼可以讀取存儲在讀數表中的數據,然後以不同的圖表顯示溫度和光數據。
清單 5. 使用 Flotr 的 PHP 圖表生成程序<?php// read solar data and display in flotr chart$doctype = "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en'><head><title>LOG reader</title><meta http-equiv='Content-Type' content='text/html;charset=UTF-8' /><script language=\"javascript\" type=\"text/javascript\" src=\"../flotr/lib/prototype.js\"></script><script language=\"javascript\" type=\"text/javascript\" src=\"../flotr/lib/base64.js\"></script><script language=\"javascript\" type=\"text/javascript\" src=\"../flotr/lib/canvas2image.js\"></script><script language=\"javascript\" type=\"text/javascript\" src=\"../flotr/lib/canvastext.js\"></script><script language=\"javascript\" type=\"text/javascript\" src=\"../flotr/flotr.js\"></script></head><body>";$mysqli = new mysqli($server,$username,$password,$dbname);// get temp and light data and chart it$sensors = array('Temp'=>6,"Light"=>5);foreach ($sensors as $label=>$sensor) { $sql = "select tstamp,value from readings where pin=$sensor order by tstamp asc"; $result = $mysqli->query($sql) or die($mysqli->error); $mydata1 = "[ "; while ($row = $result->fetch_array()) { $cfdoy = $row[0]; $cfdoy = (strtotime($cfdoy)-(5*60*60))*1000; $cfamt = $row[1]; $mydata1 .= "[ $cfdoy , $cfamt ] ,"; } $mydata1 = substr($mydata1,0,-2)." ]"; $leg = ($sensor == 18) ? "dC" : "mV"; $title = ($sensor == 18) ? "Cell Temperature" : "Light"; $conth .= "<div>$label</div>\n <div id=\"container$sensor\" style='width:600px; height:250px;'> <script type='text/javascript'> var f = Flotr.draw( $('container$sensor'), [ { // => first series data: ".$mydata1.", label: '$leg', htmlText: false, lines: {show: true} }], { xaxis: { title: 'Time', mode:'time', noTicks: 10, labelsAngle:45 }, yaxis: { title: '$leg', noTicks: 8 }, title: '$title', selection: { mode: 'x', color: '#B6D9FF', fps: 20 }, mouse: { track: true, relative: true, margin: 5, trackFormatter: function(obj) { var dd = parseInt(obj.x); var d = new Date(dd); return (d.getHours()+4) + ':' + d.getMinutes() + ' | ' + obj.y; }, position: 'sw', lineColor: '#FF3F19', trackDecimals: 1, sensibility: 2, fillOpacity: 0.4 } } ); </script></div>";}echo "$doctype"."<html><body>".$conth."</body></html>";?>
清單 5 內的代碼從定義一個字符串作為 Extensible Hypertext Markup Language (XHTML) 輸出的開始,其中包括對 JavaScript Flotr 庫的引用。然後它打開對數據存儲於的 MySQL 伺服器的連接,設置一個數組來包含所使用的管腳編號,遍歷這些數組元素以獲取相關傳感器的數據,並將其代入 JavaScript 腳本。
腳本被設置成將兩個圖表中的 X 軸數據視為 24 小時的時間值,其中包含滑鼠指導,允許您將滑鼠懸停在所生成的線上並顯示相關坐標。
在顯示階段,您可能會考慮到平滑。這可以是使用一個移動平均量或者使用其他基於權重的模式來中和極端值。
使用根據此設置生成的真實數據,每隔五分鐘進行一次取樣,此圖表腳本生成了如 圖 4 所示的未平滑化的輸出。在安大略省的五月,天氣晴朗,偶爾有風。您可以從 下載 部分獲得此數據的一個副本。
圖 4. 示例輸出請注意光級和單元溫度之間的緊密校正,這也是預期進行的操作。
結束語開源 Arduino 可以作為太陽能發電環境中的傳感器數據的一個簡單且可調整的處理器,它非常有用。如今可供使用的傳感器很多,只要傳感器能生成合適的輸出電壓,或是一個可由 Arduino 明確登記的數字輸出,它就能夠收集並報告該數據。TMP36 和 LED 是您可以獲得的最基本的傳感器,高級用戶將需要從這些傳感器進行升級。
對變化條件下的面板的行為進行良好的編碼,這對光電單元的管理者會很有幫助,因為就給定的數據記錄而言,它們可以形成觀察的基線。管理者以後可以根據推斷和建議進行相應的更改,然後再評估面板操控是否已經產生了積極的效果。