wiring Pi 是专门为树莓派打造的类似于arduino下的wiring驱动库,安装好这个库后可以直接调用函数配置和控制GPIO功能。

我买的树莓派B+版本,如图:

raspberry_b+_version

可见共有个40pin的扩展 gpio,电源IO包含3.3v  5v  ,接口定义如下图所示:

gpio_detail

一、首先我们先安装开发环境
#首先安装依赖包
 sudo apt-get install libi2c-dev
 sudo apt-get install git-core
#获取安装包
 git clone git://git.drogon.net/wiringPi
 cd wiringPi
 git pull origin
#切换到编译目录
 cd wiringPi/
#编译并安装
 ./build
#检查安装
 gpio -v
 gpio readall


执行完 gpio readall 会显示当前板子的接口定义!如下图:

wiringPi_readall

比如 12 | 1 | IN   | GPIO. 1 | 1   | 18

表示你用wiring库中的函数操作gpio1,其实是操作BCM格式的gpio18端口,物理的12针脚。

二、模块准备

DHT11是比较常用的一块传感器,物美价廉,同时可以获取到环境的温度和湿度。由于比较简单,我就没有买那种焊接好的模块,只是一个DHT11的传感器,回来自己简单焊接封装了一下。

DHT11的针脚说明如下:

dht11_pin_define

从左至右分别是1、2、3、4针脚,使用的时候我们需要加装一个上拉电阻,简单地说就是在第一第二针脚之间接一个10K左右的电阻。

接线比较简单,就不过多介绍了。

三、获取传感器数据

由于树莓派比起Arduino还是强大的太多,所以无论是用c还是python都可以很方便的按照模块的时序图编写驱动。网上各种各样的版本也是太多,思路就是严格按照手册规范来,数据校验失败的作为垃圾数据扔掉。参照比较正统的做法,自己整理了一份代码,需要的朋友也可以顺手拿走。

代码很短,参考如下:

#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>

typedef unsigned char uint8;
typedef unsigned int  uint16;
typedef unsigned long uint32;

#define HIGH_TIME 32

int gpioPin =4;  
uint32 databuf;



uint8 readSensorData(void)
{
    uint8 crc; 
    uint8 i;

    pinMode(gpioPin,OUTPUT); 
    digitalWrite(gpioPin, 0); 
    delay(25);
    digitalWrite(gpioPin, 1); 
    pinMode(gpioPin, INPUT); 
    pullUpDnControl(gpioPin,PUD_UP);

    delayMicroseconds(27);
    if(digitalRead(gpioPin)==0) 
    {
        while(!digitalRead(gpioPin)); 

        for(i=0;i<32;i++)
        {
            while(digitalRead(gpioPin)); 
            while(!digitalRead(gpioPin)); 
            delayMicroseconds(HIGH_TIME);
            databuf*=2;
            if(digitalRead(gpioPin)==1) 
            {
                databuf++;
            }
        }

        for(i=0;i<8;i++)
        {
            while(digitalRead(gpioPin)); 
            while(!digitalRead(gpioPin)); 
            delayMicroseconds(HIGH_TIME);
            crc*=2;  
            if(digitalRead(gpioPin)==1) 
            {
                crc++;
            }
        }
        return 1;
    }
    else
    {
        return 0;
    }
}

int main (int argc, char **argv)
{

    if (argc != 2) {
        printf("usage: %s GPIOpin#\n", argv[0]);
        printf("example: %s 1 - Read from wiringPi GPIO #1\n", argv[0]);
        return 2;
    }

    gpioPin = atoi(argv[1]);

    if (gpioPin <= 0) {
        printf("Please select a valid GPIO pin #\n");
        return 3;
    }


    printf("Use GPIO%d to read data!\n",gpioPin);

    if (-1 == wiringPiSetup()) {
        printf("Setup wiringPi failed!");
        return 1;
    }

    pinMode(gpioPin, OUTPUT); 
    digitalWrite(gpioPin, 1); 

    while(1) {
        pinMode(gpioPin,OUTPUT); 
        digitalWrite(gpioPin, 1); 
        delay(3000);
        if(readSensorData())
        {
            printf("Success! Sensor data read ok!\n");
            printf("Hum=%d.%d\%\n",(databuf>>24)&0xff,(databuf>>16)&0xff); 
            printf("Temp=%d.%dC\n",(databuf>>8)&0xff,databuf&0xff);
            databuf=0;
            break;
        }
        else
        {
            
            databuf=0;
        }
    }
    return 0;
}

完整的代码放在了我的github共享:https://github.com/wujiwh/DHT11_yeelink/

 

使用方式:

1、首先编译,切换到工作目录

make

2、执行 ./dht11 GPIO端口号

看看是不是有数据显示了!

四、上传传感器数据到yeelink

数据上传就更简单了,这已经基本跟硬件没多少关系了,众多的物联网平台里面yeelink算是做的不错的,各方面的文档也很容易搜到。官网是:http://www.yeelink.net/ 你需要注册一个账号来获取你的apikey,有了这个apikey我们才能发布我们的数据到物联网平台。网上有很详细的介绍,我就不冗述了。

1、linux下面发送POST请求,最简单的莫过于直接使用crul了!我写了一个简陋的脚本来发送温度数据到yeelink平台,湿度类似。

代码如下:

#!/bin/sh
#=============================================================================
# FileName: dht11_curl.sh
# Desc:
# Author: wangheng
# Email: [email protected]
# HomePage: http://wangheng.org
# Version: 0.0.1
# LastChange: 2015-01-28 00:30:11
# History:
#=============================================================================
#填入yeelink的API KEY
 yeelink_ApiKey='XXX'
 yeelink_URL='http://api.yeelink.net/v1.1/device/XXX/sensor/XXX/datapoints'
 temp=$(./dht11 1 |awk '/Hum/' |awk -F '=' '{print $2}'|sed 's/%//')
 echo $temp
curl_cmd="curl --request POST --data '{\"value\":$temp}' --header U-ApiKey:$yeelink_ApiKey --verbose $yeelink_URL"
echo $curl_cmd|sh



PS:awk用的还不是很熟,写的比较啰嗦,有更专业的朋友看到,欢迎拍砖。

 

 

2、使用python似乎也是一个非常不错的选择,python漂亮的语法,写起来也很简单。

代码如下:

#!/usr/bin/python
'''
#=============================================================================
#     FileName: dht11_post.py
#         Desc: 
#       Author: wangheng
#        Email: [email protected]
#     HomePage: http://wangheng.org
#      Version: 0.0.1
#   LastChange: 2015-01-27 22:40:37
#      History:
#=============================================================================
'''

import subprocess
import re
import json
import sys
import time
import datetime
import requests

API_Headers = {'U-ApiKey': 'XXX', 'content-type': 'application/json'}  
API_URL="http://api.yeelink.net/v1.1/device/%s/sensor/%s/datapoints"

device_id="XXX"
hum_sensor_id="XXX"
temp_sensor_id="XXX"

hum_url = API_URL % (device_id, hum_sensor_id)
temp_url = API_URL % (device_id, temp_sensor_id)

# Continuously append data
while(True):
  #to get the humidity and temperature readings!
  output = subprocess.check_output(["./dht11", "1"]);
  #print output
  matches = re.search("Temp=([0-9.]+)C", output)
  if (not matches):
    time.sleep(3)
    continue
  temp = float(matches.group(1))
  
  # search for humidity printout
  matches = re.search("Hum=([0-9.]+)\%", output)
  if (not matches):
    time.sleep(3)
    continue
  humidity = float(matches.group(1))

  print "Temperature: %.1f C" % temp
  print "Humidity:    %.1f %%" % humidity
 
  try:

    #Post temp data
    post_data = {'value': temp}  
    r = requests.post(temp_url, headers=API_Headers, data=json.dumps(post_data))  
    #Post Humidity data
    post_data = {'value': humidity}  
    r = requests.post(hum_url, headers=API_Headers, data=json.dumps(post_data))  

    print "Post to yeelink success!"
  except:
    print "Unable to post data.  Check your connection?"
    sys.exit()

  # Wait seconds before continuing
  time.sleep(15)