樹莓派接收溫濕度感應器數據
成員:林亮村,白秉軒,姜義新,賴沅承,陳仲磊,許崇嘉,戴子桓
指導老師:高慧君
Github專案網址:https://github.com/Gu-Zhi-Technology/Automatic-plantswall/
姜義新個人網站:https://www.jamesch.cf/
## 1/22今日目標:利用DT11模組感測溫濕度
### 一.我們利用樹梅派結合植物牆達成智慧物聯*
目的:利用pythonX樹梅派.達成一個自動的物聯網系統
材料:抽水馬達.光感測器.水位感測器.溫溼度感測器
我們發現植物牆需要感測溫溼度,才能偵測植物需不需要澆水etc.因此我們上網尋Raspberry Pi支援的溫溼度感測器,後發現了DHT11,畫面如下:

連結Raspberry Pi 跟 DHT11 對接之過程如下:
#針腳分布如下:

code:
```python=
import Adafruit_DHT
DHT_SENSOR = Adafruit_DHT.DHT11
DHT_PIN = 4
while True:
humidity, temperature = Adafruit_DHT.read_retry(DHT_SENSOR, DHT_PIN)
if humidity is not None and temperature is not None:
print("Temp={0:0.2f}*C Humidity={1:0.2f}%".format(temperature, humidity))
else:
print("Failed")
```
## 2/26今日目標:查詢水位偵測的模組以及思考可行性
### 一.我們查詢到water level detection

我們查詢到可以利用這個water sensor去偵測水位,可以直接對接arduino,P1
這個sensor在台灣就有賣(H1-311)
### 二.我們查詢利用python對接這個sensor的這個可行性
## 3/5今日目標:學習Pi GPIO的針腳定義
### 一.我們今天將學習Pi上的針腳

透過這張圖,我們可以瞭解到各個針腳
## 3/09 智慧物聯環境光度感測器
我們上網搜尋之後找到了 BH1750FVI這款環境光度感測器
Raspberry Pi針腳如下:

光度感測器控制程式如下:
```python=
#!/usr/bin/env python
# encoding: utf-8
import smbus
import time
#BH1750地址
__DEV_ADDR=0x23
#控制字
__CMD_PWR_OFF=0x00 #关机
__CMD_PWR_ON=0x01 #开机
__CMD_RESET=0x07 #重置
__CMD_CHRES=0x10 #持续高分辨率检测
__CMD_CHRES2=0x11 #持续高分辨率模式2检测
__CMD_CLHRES=0x13 #持续低分辨率检测
__CMD_THRES=0x20 #一次高分辨率
__CMD_THRES2=0x21 #一次高分辨率模式2
__CMD_TLRES=0x23 #一次分辨率
__CMD_SEN100H=0x42 #灵敏度100%,高位
__CMD_SEN100L=0X65 #灵敏度100%,低位
__CMD_SEN50H=0x44 #50%
__CMD_SEN50L=0x6A #50%
__CMD_SEN200H=0x41 #200%
__CMD_SEN200L=0x73 #200%
bus=smbus.SMBus(1)
bus.write_byte(__DEV_ADDR,__CMD_PWR_ON)
bus.write_byte(__DEV_ADDR,__CMD_RESET)
bus.write_byte(__DEV_ADDR,__CMD_SEN100H)
bus.write_byte(__DEV_ADDR,__CMD_SEN100L)
bus.write_byte(__DEV_ADDR,__CMD_PWR_OFF)
def getIlluminance():
bus.write_byte(__DEV_ADDR,__CMD_PWR_ON)
bus.write_byte(__DEV_ADDR,__CMD_THRES2)
time.sleep(0.2)
res=bus.read_word_data(__DEV_ADDR,0)
#read_word_data
res=((res>>8)&0xff)|(res<<8)&0xff00
res=round(res/(2*1.2),2)
result="光照强度: "+str(res)+"lx"
return result
```
## 3/10 app開發:
我們發現可以用手機app的方式控制植物牆的運行,並傳輸偵測器所感測的資料;
經過搜尋之後發現android studio 這款介面開發android介面加以控制植物牆

示意圖如上:
code:



## 3/16 app互聯(mqtt)
我們發現傳輸資料需要:客戶端與主控端,經上網搜尋後查到了mptt這個東西:
mqtt(Message Queuing Telemetry Transport)訊息佇列遙測傳輸;可作為「資料傳遞的橋梁」
## 3/30 socket的技術問題
我們發現使用mqtt用在做點對點會比較少,直接使用socket走tcp協議不會佔資源,並且速度也是很快的。故我們開始學習socket,並放棄mqtt。
## 4/2 水位偵測器
以下為水位偵測器連接到樹梅派的針腳:

coding:
``` python
from time import sleep
import RPi.GPIO as GPIO
import spidev
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 250000
GPIO.setmode(GPIO.BCM)
GPIO.setup(14, GPIO.OUT)
GPIO.setup(15, GPIO.OUT)
def poll_sensor(channel):
"""Poll MCP3002 ADC
Args:
channel (int): ADC channel 0 or 1
Returns:
int: 10 bit value relating voltage 0 to 1023
"""
assert 0 <= channel <= 1, 'ADC channel must be 0 or 1.'
# First bit of cbyte is single=1 or diff=0.
# Second bit is channel 0 or 1
if channel:
cbyte = 0b11000000
else:
cbyte = 0b10000000
# Send (Start bit=1, cbyte=sgl/diff & odd/sign & MSBF = 0)
r = spi.xfer2([1, cbyte, 0])
# 10 bit value from returned bytes (bits 13-22):
# XXXXXXXX, XXXX####, ######XX
return ((r[1] & 31) << 6) + (r[2] >> 2)
try:
while True:
channel = 0
channeldata = poll_sensor(channel)
voltage = round(((channeldata * 3300) / 1024), 0)
print('Voltage (mV): {}'.format(voltage))
print('Data : {}\n'.format(channeldata))
if voltage < 50:
# Green
GPIO.output(14, GPIO.HIGH)
GPIO.output(15, GPIO.LOW)
elif voltage < 1800:
# Yellow
GPIO.output(14, GPIO.HIGH)
GPIO.output(15, GPIO.HIGH)
else:
# Red
GPIO.output(14, GPIO.LOW)
GPIO.output(15, GPIO.HIGH)
sleep(2)
finally: # run on exit
spi.close() # clean up
GPIO.cleanup()
print "\n All cleaned up."
```
## 4/3 生長燈
# 圖片:
# 數梅派程式:
``` python
import RPi.GPIO as GPIO
import time
LED_PIN = 37
GPIO.setmode(GPIO.BOARD)
GPIO.setup(LED_PIN, GPIO.OUT)
GPIO.output(LED_PIN, GPIO.LOW)
time.sleep(5)
GPIO.output(LED_PIN, GPIO.HIGH)
GPIO.cleanup()
def led():
LED_PIN = 37
GPIO.setmode(GPIO.BOARD)
GPIO.setup(LED_PIN, GPIO.OUT)
try:
while True:
#return "LED is on"
GPIO.output(LED_PIN, GPIO.LOW)
time.sleep(5)
#return "LED is off"
GPIO.output(LED_PIN, GPIO.HIGH)
time.sleep(5)
except KeyboardInterrupt:
return "Exception: KeyboardInterrupt"
finally:
GPIO.cleanup()
```
## 4/4 python socket開發
我們開始使用python寫socket,我們一開始使用python寫server和client
srever:
```python=
# -*- coding: utf-8 -*-
import socket
import time
HOST = '127.0.0.1'
PORT = 8000
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((HOST, PORT))
server.listen(10)
conn, addr = server.accept()
print("connected")
serverMessage = 'START'
serverMessage = serverMessage+'\n'
conn.sendall(serverMessage.encode())
conn.close
```
client:
```python=
import socket
HOST = '127.0.0.1'
PORT = 8000
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((HOST, PORT))
serverMessage = str(client.recv(1024), encoding='utf-8')
print('Server:', serverMessage)
client.close()
```
## 4/5 Android studio使用心得
本件作品的程式碼是用Android studio來撰寫的,因為其包含了Java和Kotlin,不過本次只有使用到Kotlin的部分。我們使用Kotlin來寫客戶端的程式碼,而這也是我們第一次接觸到Kotlin這個工具,過程中我們也向許多的人請教他的使用方法,不過因為身邊的人較少接觸到他,所以能得到的資訊較少,最後我們選擇了從網路上尋找答案。在用了Android studio後,我們學到了如何配置environment,還有如何開啟VM。

## 4/8 sht1X 溫濕度感測器程式:
# 圖片:



# code:
``` python=
from time import sleep
import RPi.GPIO as GPIO
from pi_sht1x import SHT1x
import time
def test_sht1x(DATA_PIN, SCK_PIN):
with SHT1x(DATA_PIN, SCK_PIN, gpio_mode=GPIO.BOARD) as sensor:
for i in range(1):
temp = sensor.read_temperature()
humidity = sensor.read_humidity(temp)
sensor.calculate_dew_point(temp, humidity)
print(temp,humidity)
return temp, humidity
sleep(2)
print('Test complete.\n')
if __name__ == "__main__":
main()
```
## 4/9 更新水位增測器code:
### code:
# 心得:
在4/2時我們完成了水位增測器的初始code
但之後發現了問題,程式完全不和。
關於硬體的部分,因為水位增測器為非防水的,所以放在儲水箱中只能放在頂端,也因為水位增測器只能輸出1/0訊號,無法精準得到數據。
## 4/11 kotlin學習
我們使用kotlin開發client socket,我們將socket運算的部分另外寫,解決程式碼雜亂的問題。
```kotlin=
package com.example.myapplication123
import java.io.BufferedReader
import java.io.InputStreamReader
import java.net.Socket
import java.util.logging.Handler
import java.io.PrintWriter
class ClientSo(host: String, port: Int) : Socket(host, port) {
var reader = BufferedReader(InputStreamReader(inputStream))
private lateinit var handler: Handler
var writer : PrintWriter? = null
var text = ""
fun setHandler(handler: Handler) {
this.handler = handler
}
fun sendMessage(string: String) {
writer?.println(string)
}
fun run(): String? {
val line = reader.readLine()
val conn= super.isConnected()
if(line!= null)
return line
else
return "fail"
}
}
```
## 4/12 SHT1X 安裝過程:





### SHT1X纏線感想:
我覺得纏線的過程好複雜,一條電線必須先用剪線鉗將末端的鐵絲露出來,再來由於鐵絲是一條一條的所以必須將鐵絲纏逞一條再將它們與另一條繞在一起,用膠帶黏住之後又是一個考驗,能不能將膠帶牢牢的纏上,纏上之後兩條電線有沒有接觸不良或者是纏膠帶的電線中兩電線繞著的鐵絲鬆脫導致不能用,通過了以上的關卡之後才能用...
### sht1X溫濕度感測器安裝心得:
我覺得SHT1X的濕度偵測功能DHT11穩定,溫度測得比我們的DHT11精準;且具有飽和度計算的功能,也因為它的線長不夠和我們沒又那麼多孔可以給每一個SHT1X供電,所以我們就用接線將她們都接成一條線,這樣子供電的問題跟針腳不夠的問題都解決了.至於訊號原的部分:每個sht1X都有兩條訊號線,雖然是沒有問題但是讓數梅派整體的線路顯得好亂
### SHT1X安裝結果呈現:
## 4/13 kotlin開發測試
我們在本地運行4/11開發的kotlin socket在本地運行可以順利執行,並且我們和python連線,在不同的裝置也正常運行。
## 4/19 APP開發學習
因為我們沒有開發app的相關經驗所以我們先學習開發一個可以顯示文字 有button的app 再配合上我們的kotlin client即可完成開發。

我們開發了一個按+就可以將數字+1,按-就可以將數字-1
## 4/26 xml學習
一開始在學習xml是因為當時正在看UI的教學,然後突然看見了這個陌生的詞彙:xml,後來才得知它的用處,
## 5/4 抽水馬達:
# 照片:
# code:
``` python
import RPi.GPIO as GPIO
import time
GPIO.cleanup()
PUMP_PIN = 38
GPIO.setmode(GPIO.BOARD)
GPIO.setup(PUMP_PIN, GPIO.OUT)
GPIO.output(PUMP_PIN, GPIO.LOW)
time.sleep(100)
#return "PUMP is off"
GPIO.output(PUMP_PIN, GPIO.HIGH)
time.sleep(4)
GPIO.cleanup()
```
# 技術困難:
我們得預想是到了指定的水位時它會自動的加水,但是目前我們只能讓它抽指定時間的水
# 抽水馬達安裝心得:
# 5/11 水位偵測器的技術問題:
我們發現水位偵測器的程式有點問題,海有水位偵測器的防水問題,因為水箱太深.水位偵測器會完全泡進水裡.
# Slides




























# 實作心得 && 給學弟妹們的話
各位努力奮鬥中的學弟妹好,我是你們的學長姜義新。
在這個專案中,其實有很多想法最後並沒有完成出來,實作的部分,APP和硬體也都非常的簡陋,有非常多可以進步的地方。
不過最終結果如何我認為不管在申請大學上或是自我成長上都毫無關聯。更重要的是在專案開發過程中學到什麼,知道自己不足什麼。
## Linux
我會建議學弟妹們在學期間可以稍微了解 Linux 的一些操作。
當初我們在開發的時候,對於 Linux 的一些基礎知識淺薄,導致開發上會浪費很多時間去鑽研一些不是重要卻是必要的知識。
對於這些有關硬體上的實作,很多都與 Embedded system 相關,因此學習 Linux 顯得格外重要。另外學 Linux 對於未來任何有關資訊領域的,要不碰到真的很難,因此我建議可以視 Linux 為基礎。不管如何,至少要知道基本的指令。
## APP 開發的心得
記得當初是因為我去詢問高老師安排的一場演講者,他建議我們用 Kotlin 開發,所以我們馬上補齊 Kotlin 的相關知識 (非常淺薄的那種) ,後期也是在 Socket 的部分遇到相當大的阻礙。
可以很坦白地告訴各位,上大學兩年後 Kotlin 的一些 instruction 我也是忘的一乾二淨。但是要我再回去看一些寫過的 code 就可以馬上回憶起來。不過因為你有遇到困難,以後就有更多話去跟你的教授聊你到底高中科學班學了什麼。
另外有些東西你翻遍各種海內外社群可能都找不到解答,但也許只是你的一個小觀念錯誤導致的問題。所以我會建議真的找不到解答一定要尋求各種幫助(問老師、社團發問等等等)