[电子技术]温度收集


20141108_063907

一个有点物联网感觉的作品。原理是使用温度传感器(模拟输出)得到当前温度,网络上传,网络显示。
因为是模拟输出,raspberry pi不能直接使用。简单起见,直接用Arudino作为ADC,和raspberry pi串口通信。
网络上传是raspberry pi的强项。再加上我给raspberry pi装了无线USB网卡,更加方便,直接电源输入即可。
网络显示依赖于网络上传,本次使用的是yeelink的服务。提供类似温度记录的功能。直接拿来使用了。

20141107_211802

温度收集部分,为了调试,增加了LCD用于显示当前温度。

20141107_211818

raspberry pi部分。使用绿灯表示上传成功,红灯表示上传失败。实际运行没一次失败……
串口通信其实很简单,把USB相连即可。通讯上采用raspberry pi发一次请求,Arduino回应一次的被动方式。

raspberry pi的代码

import serial
import RPi.GPIO as GPIO
import datetime
from time import sleep
import httplib

PIN_LED_PASSED=22
PIN_LED_FAILED=23

API_KEY='API_KEY_HERE'
HOST='api.yeelink.net'
URI='/v1.0/device/15530/sensor/26740/datapoints'

def loop(s):
    s.writelines(['G']) # send serial command to get current temperature
    c = s.readline().strip()
    if not c:
        return
    now = datetime.datetime.now().isoformat()
    print '[INFO]', now, c
    if send_sensor_data(now, c):
        GPIO.output(PIN_LED_PASSED, GPIO.HIGH)
    else:
        GPIO.output(PIN_LED_FAILED, GPIO.HIGH)
    sleep(1)
    GPIO.output(PIN_LED_PASSED, GPIO.LOW)
    GPIO.output(PIN_LED_FAILED, GPIO.LOW)
    sleep(10) # sleep 10 seconds for yeelink limit(> 10s after previous request)

def send_sensor_data(timestamp, value):
    payload = '{"timestamp":"' + timestamp + '","value":' + value + '}'
    headers = {'U-ApiKey': API_KEY}

    conn = httplib.HTTPConnection(HOST)
    conn.request('POST', URI, payload, headers)
    resp = conn.getresponse()
    conn.close()
    if resp.status == 200:
        return True
    else:
        print '[WARN] failed to send sensor data,', resp.reason
        return False

if __name__ == '__main__':
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(PIN_LED_PASSED, GPIO.OUT)
    GPIO.setup(PIN_LED_FAILED, GPIO.OUT)

    s = serial.Serial('/dev/ttyACM0', 9600, timeout = 1)
    s.open()
    print '[INFO] sensor data collector start'
    try:
        while True:
            loop(s)
    except KeyboardInterrupt:
        s.close()
        GPIO.cleanup()

Arduino的代码

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

// TMP sensor connect to A0
#define PIN_TMP 0

int analogValue = 0;
float voltage = 0;
float celsius = 0;
int serialCmd;

LiquidCrystal_I2C lcd(0x27,16,2); 

void setup() {
  Serial.begin(9600);
  
  lcd.init();
  // lcd.backlight();
  lcd.print("ALL CLEAR!");
}

void loop() {
  analogValue = analogRead(PIN_TMP);
  voltage = analogValue * 5000.0 / 1024;
  celsius = (voltage - 500) / 10;
  
  // show temperature on LCD
  lcd.clear();
  lcd.print(celsius);
  
  // send to serial if necessary
  if(Serial.available() && Serial.read() == 71 /* G */) {
    Serial.println(celsius);
  }
  
  delay(1000);
}