Tag Archive:Remove term: raspberry pi

Byamber

基于树莓派的触摸开关

Overview

本文介绍如何用树莓派设计数字触摸开关,并通过这个数字触摸开关控制继电器通断。程序启动树莓派不间断检测TTP223数字触摸传感器模块输出信号,当检测到有触摸动作发生时候,继电器闭合,并且在触摸时候蜂鸣器会响一声,代表被触摸。该模块是一个基于触摸检测ICTTP223B的电容式点动型触摸开关模块。常态下,模块输出低电平,模式为低功耗模式;当用手指触摸相应位置时,模块会输出高电平,模式切换为快速模式;当持续12秒没有触摸时,模式又切换为低功耗模式。

DSC_5484

Experimental Parts

为了完成设计需要用到一下器件

PI
Pi3 x1
18
有源蜂鸣器模块 x1
13
数字触摸开关TTP223 x1
17
2路继电器模块 x1
LACC2006AD-12
面包板 x1
LACC2006AD-31
公对公跳线 x若干
19
公对母跳线 x若干

Hardware

本文中用到了三个传感器,分别是数字触摸开关TTP223模块、有源蜂鸣器模块和2路继电器模块。数字触摸开关TTP223模块工作在DC2—5.5V,本文中采用3.3V供电,检测到有触摸动作时候输出高电平,否则输出低电平;有源蜂鸣器模块采用2TY三极管(S8550)驱动,工作在3.3V-5V之间,本文将其接到3.3V电压上,模块低电平触发;2路继电器模块低电平触发,同样用3.3V供电。

与树莓派具体连线参考下图

Untitled Sketch_touchsensor

在接线的时候请认清模块正负极,不要接反了,否则会烧坏你的Pi和模块。模块的上的GND接Pi上的0V;模块上的VCC接3.3V。对于如何识别Pi的IO口请参考这篇文章: How to read Raspberry Pi i/o pin diagram (GPIO pin graph)

Software

可以把pi直接接到显示器上,也可以通过SSH方式远程登录Pi。

1)编写代码

在/home/pi路径下用nano新建一个touchsensor.py(名字随意,你喜欢就好!)

sudo nano touchsensor.py

并往新建的文件中写入如下代码:

import RPi.GPIO as GPIO
import time
import os

#sensor pin define
buzzer = 14
touch = 26
relay_in1 = 13
relay_in2 = 19

#GPIO port init
def init():
         GPIO.setwarnings(False)
         GPIO.setmode(GPIO.BCM)
         GPIO.setup(buzzer,GPIO.OUT)
         GPIO.setup(relay_in1,GPIO.OUT)
         GPIO.setup(relay_in2,GPIO.OUT)
         GPIO.setup(touch,GPIO.IN,pull_up_down=GPIO.PUD_UP)
         pass

#turn on buzzer
def buzzer_on():
         GPIO.output(buzzer,GPIO.LOW)
         time.sleep(0.2)
         GPIO.output(buzzer,GPIO.HIGH)
         time.sleep(0.2)
         pass
#turn off buzzer
def buzzer_off():
         GPIO.output(buzzer,GPIO.HIGH)
         pass

#turn on relay
def relay_on():
         #open relay channal1 ana channal2
         GPIO.output(relay_in1,GPIO.LOW)
         GPIO.output(relay_in2,GPIO.LOW)

#turn off relay
def relay_off():
                  GPIO.output(relay_in1,GPIO.HIGH)
                  GPIO.output(relay_in2,GPIO.HIGH)


touchstatus = False
#read digital touch sensor
def read_touchsensor():
         global touchstatus
         if (GPIO.input(touch)==True):
                  touchstatus = not touchstatus
                  if touchstatus:
                           print"Turn on relay"
         print"\n"
                           buzzer_on()
                           relay_on()
                  
                  else:
                           print"Turn off relay"
         print"\n"
                           buzzer_on()
                           relay_off()
         pass
                  

#main loop
def main():
         print"...................................................................System initializing..."
         init()
         buzzer_off()
         relay_off()
         print"...................................................................Ok"
         print"...................................................................Please touch"
         print"\n"
         while True:
                  read_touchsensor()

if __name__ == '__main__':
         try:
                  main()
                  pass
         except KeyboardInterrupt:
                  pass
         pass
GPIO.cleanup()

上面的代码可以通过执行下面的shell命令得到

sudo wget --no-check-certificate   http://osoyoo.com/driver/touchsensor.py

2)执行python脚本

sudo python ./touchsensor.py

2017-03-25-070337_1824x984_scrot

3)测试

用手指触摸数字触摸开关模块上同心圆位置,会听到滴答声,这是蜂鸣器吸合的声音,在触摸同时蜂鸣器会响一声。可以将一些其他设备接到继电器,就可以通过自己设计的触摸开关来控制了。

Byamber

树莓派读取DHT11

Overview

在本文中将介绍如何用树莓派读取温湿度传感器DHT11 温湿度数据。温度湿度模块看起来简单,只有三个引脚(实际4个接口,有一个脚悬空),但仔细一想,3个引脚分别作为VCC、GND、DATA用,因为传给树莓派GPIO的只有高电平、低电平,那么怎么来读取温度数字和湿度数字呢?这么一想,并不简单!因为引脚少,它需要高低变化的时序信号来表达数值,还有一些其它信号如开始信号等等。所以得先深入了解一下DHT11模块了。

DSC_5467

DHT11时序介绍

1)数据帧格式

DHT11会向主机发送40位(5子节)数据,第一二个子节数据表示温度值;第三四个子节数据代表湿度值;最后一个子节是校验码。如果数据无误的情况下,前4个子节的和等于校验码。

e1

2)握手阶段

默认状态下DATA脚为高电平,主机端GPIO发送开始信号,首先拉低DATA脚至少18ms,然后拉高DATA脚20-40us等待DHT11的响应信号
e2

一旦DHT11收到开始信号,DHT11将向主机发送响应信号,同时将DATA脚拉低80us作为响应,然后DHT11拉高DATA脚80us,握手完毕。

3)数据发送阶段

一次的湿度和温度数据,DHT11需要发送40bits数据,每一位数据之前都以50us低电平开始,随后的高电平时序信号,持续26us-28us的表示这一位是0,持续70us表示这一位是1,然后继续50us低电平,紧接着下一位的高电平开始。

数据 ‘0’:

e3

数据 ‘1’:

e4

Parts

为了完成本项目需要用到如下器件

PI
Pi3 x1
EASM100600
DS18B20 x1
EACW100500
杜邦线 x3

Hardware

硬件连接很简单,将DHT11的VCC接到Pi的3.3V;DHT11的GND接到Pi的GND;DHT11的DATA接到Pi的GPIO14(BCM编码方式),关于GPIO的识别请参考: How to read Raspberry Pi i/o pin diagram (GPIO pin graph)

Untitled Sketch_dht11

Software

本文将介绍2中方式读取DHT11数据,一种是Python方式读取,一种是C语言方式读取。

1)Python方式

在任一路径下(如/home/pi)用nano新建一个dht11-test.py文件

sudo nano dht11-test.py

往dht11-test.py文件写入如下代码:

# _____ _____ _____ __ __ _____ _____ 
#|     |   __|     |  |  |     |     |
#|  |  |__   |  |  |_   _|  |  |  |  |
#|_____|_____|_____| |_| |_____|_____|
#
# Use Raspberry Pi to get temperature/humidity from DHT11 sensor
#  
import time
import dht11
import RPi.GPIO as GPIO

#define GPIO 14 as DHT11 data pin
Temp_sensor=14
def main():
  # Main program block
  GPIO.setwarnings(False)
  GPIO.setmode(GPIO.BCM)       # Use BCM GPIO numbers
  # Initialise display
#  lcd_init()
  instance = dht11.DHT11(pin = Temp_sensor)

  while True:
        #get DHT11 sensor value
        result = instance.read()
  print"Temperature = ",result.temperature,"C"," Humidity = ",result.humidity,"%"
  time.sleep(1)

if __name__ == '__main__':

  try:
    main()
  except KeyboardInterrupt:
    pass
#  finally:
#    lcd_byte(0x01, LCD_CMD)

运行Python代码需要依赖一个dht11.py文件,用下面的命令下载,需要保证dht11.py文件与dht11-test.py在同一路径下。

sudo sudo wget --no-check-certificate   http://osoyoo.com/driver/dht11.py

运行Python程序

sudo python ./dht11-test.p

2017-03-22-063517_1824x984_scrot

执行完上面的命令后会在屏幕上打印出温湿度值,但是很多时候会出现温湿度都等于0的情况,这是为什么?原因在于树莓派读取DHT11的输出信号,需要微秒级的定时,否则在数据传输阶段,很难准确的识别出每一位是“0”还是“1”,树莓派运行的Raspbian系统是一个非实时系统,很难实现准确的微秒级定时,会导致数据丢失,使DHT11在数据校验时候不正确。

2)C语言方式

A.在树莓派下用C语言操作GPIO需要首先安装GPIO库,运行下面命令(如果已经安装请跳过)

sudo git clone git://git.drogon.net/wiringPi
sudo cd wiringPi
sudo ./build

B.在任一路径下(如/home/pi)用nano新建一个dht11-test.py文件

sudo nano dht11-test.c

往dht11-test.c里面写入如下代码

/*
 *  dht11.c:
 *  Simple test program to test the wiringPi functions
 *  DHT11 test
 */

#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define MAXTIMINGS  85
#define DHTPIN    15
int dht11_dat[5] = { 0, 0, 0, 0, 0 };

void read_dht11_dat()
{
  uint8_t laststate = HIGH;
  uint8_t counter   = 0;
  uint8_t j   = 0, i;
  float f; /* fahrenheit */

  dht11_dat[0] = dht11_dat[1] = dht11_dat[2] = dht11_dat[3] = dht11_dat[4] = 0;

  /* pull pin down for 18 milliseconds */
  pinMode( DHTPIN, OUTPUT );
  digitalWrite( DHTPIN, LOW );
  delay( 18 );
  /* then pull it up for 40 microseconds */
  digitalWrite( DHTPIN, HIGH );
  delayMicroseconds( 40 );
  /* prepare to read the pin */
  pinMode( DHTPIN, INPUT );

  /* detect change and read data */
  for ( i = 0; i < MAXTIMINGS; i++ )
  {
    counter = 0;
    while ( digitalRead( DHTPIN ) == laststate )
    {
      counter++;
      delayMicroseconds( 1 );
      if ( counter == 255 )
      {
        break;
      }
    }
    laststate = digitalRead( DHTPIN );

    if ( counter == 255 )
      break;

    /* ignore first 3 transitions */
    if ( (i >= 4) && (i % 2 == 0) )
    {
      /* shove each bit into the storage bytes */
      dht11_dat[j / 8] <<= 1;
      if ( counter > 16 )
        dht11_dat[j / 8] |= 1;
      j++;
    }
  }

  /*
   * check we read 40 bits (8bit x 5 ) + verify checksum in the last byte
   * print it out if data is good
   */
  if ( (j >= 40) &&
       (dht11_dat[4] == ( (dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xFF) ) )
  {
    f = dht11_dat[2] * 9. / 5. + 32;
    printf( "Humidity = %d.%d %% Temperature = %d.%d *C (%.1f *F)\n",
      dht11_dat[0], dht11_dat[1], dht11_dat[2], dht11_dat[3], f );
  }else  {
    printf( "Data not good, skip\n" );
  }
}

int main( void )
{
  printf( "Raspberry Pi wiringPi DHT11 Temperature test program\n" );

  if ( wiringPiSetup() == -1 )
    exit( 1 );

  while ( 1 )
  {
    read_dht11_dat();
    delay( 1000 ); /* wait 1sec to refresh */
  }

  return(0);
}

C.编译、执行程序

sudo gcc  -o dht11-test dht11-test.c  -lwiringPi
sudo  ./dht11-test

2017-03-22-063018_1824x984_scrot

本文中所有用到的代码可以通过下面的命令获取到

sudo wget --no-check-certificate   http://osoyoo.com/wp-content/uploads/2017/03/dht11_code.rar

对比发现,C语言方式虽然也有数据丢失的情况,但是总体来说比Python少一些,,这是因为C语言是高级语言,直接对树莓派GPIO进行操作。

Byamber

树莓派读取DS18B20温度值

Overview

DS18B20是一个比较常用的温度传感器,采用单总线控制,以前用单片机编程控制时严格按照单总线的时序控制,今天来看看在树莓派Raspbian系统下如何控制DS18B20,体验一下在linux世界,一切都是文件。读取DS18B20温度也是对文件的操作。

DSC_5465

Parts

为了完成本项目需要用到如下器件

PI
Pi3 x1
EASM100100
DS18B20 x1
EACW100500
杜邦线 x3

Hardware

将DS18B20温度传感器模块的”S”引脚接到树莓派的4脚(BCM编码方式);”-“接到树莓派的GND引脚;DS18B20中间应交接到树莓派5V电源处。如图

ds18b20_python

加载内核单总线模块

Raspbian支持单总线协议,能挂接如DS18B20之类的单总线设备,并读取其数据。但是需要加载这个模块

在命令行输入如下命令

sudo nano /boot/config.txt

将光标移动到最后添加下面一句话

dtoverlay=w1-gpio

按下键盘上的Ctrl X后按照提示保存退出

查看模块是否启动

重启树莓派是上面的配置生效

sudo reboot

待树莓派启动起来后,命令行输入

lsmod

如果如发现红色方框所示说明模块已启动。

2017-03-20-075235_1824x984_scrot

如果没有发现,也可以运行如下命令加载模块

sudo modprobe w1-gpio
sudo modprobe w1-therm

读取温度

如果一切顺利,在/sys/bus/w1/devices中发现一个28-XXXX开头的文件夹,这个就是DS18B20的ROM,每个DS18B20都一样,在这个文件夹中读取w1_slave文件则会返回当前温度值。

sudo modprobe w1-gpio
sudo modprobe w1-therm
cd /sys/bus/w1/devices
cd /28-xxxxxx
cat w1_slave

Software

用nano编辑器新建一个temp.py文件,并输入如下代码

sudo nano temp.py
import os
import glob
import time

os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')

base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + '28*')[0]
device_file = device_folder + '/w1_slave'

def read_temp_raw():
    f = open(device_file, 'r')
    lines = f.readlines()
    f.close()
    return lines

def read_temp():
    lines = read_temp_raw()
    while lines[0].strip()[-3:] != 'YES':
        time.sleep(0.2)
        lines = read_temp_raw()
    equals_pos = lines[1].find('t=')
    if equals_pos != -1:
        temp_string = lines[1][equals_pos+2:]
        temp_c = float(temp_string) / 1000.0
        temp_f = temp_c * 9.0 / 5.0 + 32.0
        return temp_c, temp_f
  
while True:
  print('C =%3.3f F = %3.3f'% read_temp())  
  time.sleep(1)

上面的代码将每隔1秒钟以摄氏温度和华氏温度的格式打印一次温度值。

2017-03-20-084757_1824x984_scrot

注解:1)os.system(‘modprobe w1-gpio’)os.system(‘modprobe w1-therm’)两句在程序的开头运行了一下modprobe命令

2)base_dir = ‘/sys/bus/w1/devices/’和device_folder = glob.glob(base_dir + ’28*’)[0] 是获取/sys/bus/w1/devices/下面所有以28开头的目录文件

3)device_file = device_folder + ‘/w1_slave’ 打开文件并读取数据

4)while lines[0].strip()[3:] != ‘YES’: 判断所读取文件的第一行的末尾三个字符是否等于YES

5)equals_pos = lines[1].find(‘t=’) 查找所读取文件中第二行中t=开始的位置,如果查找失败返回-1