[記錄]學習樹莓派3B接DHT11和LCD1602和修改樹莓派時區


前提

  1. 樹莓派系統安裝好 apache web 服務器,如未安裝,可在樹莓派內執行sudo apt-get install apache2 進行安裝apache

也可以通過命令獲取GPIO信息:

gpio --version #查看gpio版本
gpio readall # 查看樹莓派所有管腳的基本信息

樹莓派針腳說明圖如下圖:

注: 在GPIO接線或接模塊的時候,建議關閉樹莓派之后進行操作,避免造成元電子損壞。


參考基於樹莓派3B,DHT11/DHT22,LCD1602的一個實時溫度濕度檢測系統的詳細說明,LCD1602和DHT11和樹莓派3B連線成功。后來參考博文,使用了ntp和修改時區,才把日期時間與北京時間一致。
在未操作之前,輸入date,返回的是"Fri 17 Mar 16:03:16 UTC 2017",我看電腦時間,好像已經是03-18 00:03了,時間不對。
按照教你如何修改樹莓派的時區和網絡對時的方法按照好了ntpdate.

安裝 ntpdate

sudo apt-get install ntpdate

選擇時區:

tzselect

最后時區為"Asia/Shanghai"。最后執行sudo ntpdate cn.pool.ntp.org,提示:

沒有更新成功。
最后嘗試了樹莓派系統時間同步中的sudo dpkg-reconfigure tzdata的命令來修改本地時區,依次選擇的是"Asia","Chongqing" 回車確認之后,就更新好了時間,輸出的date與本地電腦的時區一樣。


只接DHT11,不接 LCD

DHT11 接線

DHT11有3個腳,VCC,DATA,GND

符號 含義 樹莓派 Pin 樹莓派 含義
VCC 供電電源(+3.3V) 1 3.3V電源
DATA 數據輸出腳 32 GPIO 12
GND 9

按照使用Github倉庫 rpi-TempRuntime 上的說明:

安裝依賴:

sudo apt-get update
sudo apt-get install python-dev python-rpi.gpio
sudo apt-get install build-essential python-dev python-smbus python-pip
git clone https://github.com/adafruit/Adafruit_Python_DHT.git
cd Adafruit_Python_DHT
sudo python setup.py install
sudo pip install RPi.GPIO
git clone https://github.com/adafruit/Adafruit_Python_CharLCD
cd Adafruit_Python_CharLCD
sudo python setup.py install

安裝

將開源庫下載克隆到樹莓派Apache 默認的/var/www/html 目錄下,命令如下:

#from Raspberry pi ssh
sudo apt-get install -y git # 如果沒有安裝git,需要執行這一句安裝git
cd /var/www/html # 進入Apache默認的document_root
git clone https://github.com/yfgeek/rpi-TempRuntime.git # 使用git clone使用的github倉庫
sed -i "s|26|12|" /var/www/html/rpi-TempRuntime/DHT11-WITHOUT-LCD.py #將監聽數據口 GPIO 26 改為GPIO 12

運行

cd /var/www/html/rpi-TempRuntime
python DHT11-WITHOUT-LCD.py

創建快速啟動腳本

#from Raspberry pi ssh
vim start.sh

創建一個啟動的 shell 腳本,文件名為 start.sh,腳本內容如下:

#!/bin/bash
cd /var/www/html/rpi-TempRuntime
python -u DHT11-WITHOUT-LCD.py

4位數碼管顯示模塊(帶時鍾點)

數碼管接線說明:

符號 含義 樹莓派 Pin 樹莓派含義
CLK 時鍾信號腳 16 GPIO 23
DIO 數據輸入輸出腳 18 GPIO 24
VCC 供電電源(+5V) 4 5V 電源
GND 14

獲取 TM1637 腳本

#from Raspberry pi ssh
pi@raspberrypi:~/workspace $ wget https://raspberrytips.nl/files/tm1637.py

原始的代碼可以在 Github 這里 找到

顯示數碼管的python47digitclock.py 源文件,我存放的文件夾路徑是: /home/pi/workspace

47digitclock.py 文件,將源碼的時間計算為直接獲取當前時間(24小時制),使用字符串截取的方式獲取每個LED顯示的字符,源碼是:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# https://raspberrytips.nl/tm1637-4-digit-led-display-raspberry-pi/

import sys
import time
import datetime
import RPi.GPIO as GPIO
import tm1637

#CLK -> GPIO23 (Pin 16)
#DI0 -> GPIO24 (Pin 18)

Display = tm1637.TM1637(23,24,tm1637.BRIGHT_TYPICAL)

Display.Clear()
Display.SetBrightnes(1)

while(True):
   todaytime = time.strftime('%H:%M:%S',time.localtime(time.time()))
   todaystr  = todaytime.split(":");
   second = int(todaystr[2])
   
   currenttime = [int(todaystr[0][0]), int(todaystr[0][1]), int(todaystr[1][0]), int(todaystr[1][1]) ]
   
   Display.Show(currenttime)
   Display.ShowDoublepoint(second % 2)

   time.sleep(1)

演示代碼可以直接下載:

#from Raspberry pi ssh
pi@raspberrypi:~/workspace $ wget https://raspberrytips.nl/files/47digitclock.py 

確保存放47digitclock.py 文件所在的文件夾內有tm1637.py 腳本文件,即可運行命令來啟動數碼管:

python 47digitclock.py

創建名為startclock.sh的一個shell文件,用於快速執行顯示時間的python文件,startclock.sh文件的內容如下:

#!/bin/bash
cd /home/pi/workspace
python -u 47digitclock.py

每次重新開機啟動時,啟動這兩個文件

nohup ./start.sh &
nohup ./startclock.sh &

運行之后的出現的我問題

問題1 : 顯示時鍾一段時間之后的時候,如果出現 LED的數字亂跳、忽然變亮又變暗、LED全不量的情況,可以登入樹莓派中,運行

ps -ef | grep 47

在輸出結果中,看一下是否有兩個或者兩個以上的 47digitclock.py 進程在運行,如果是有兩個或者兩個以上的47digitclock.py進程的話,請用 kill -9 進程編號將全部的47digitclock.py進程都停止,然后再運行nohup ./startclock.sh &

最終效果是:

--- 2017-05月19日 更新----
如果經歷過兩次晚上深夜停電,每次都要起床之后,登入ssh 手動兩個命令,故參考文獻14,自己將開機啟動的sh改為以服務的形式開機啟動

  1. 時鍾模塊隨開機啟動服務
sudo vim /etc/init.d/startmy47digitclock

/etc/init.d/startmy47digitclock 文件中的寫入以下內容

#!/bin/bash
# /etc/init.d/startmy47digitclock

### BEGIN INIT INFO
# Provides: 47digitclock
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: pi startclock initscript
# Description: This service is used to manage a 47digitclock
### END INIT INFO

case "$1" in
     start)
          echo "Starting lcd"
          python -u /home/pi/workspace/47digitclock.py &
        ;;
     stop)
        echo "Stopping lcd"
        #killall 47digitclock.py
        kill $(ps aux | grep -m 1 'python -u /home/pi/workspace/47digitclock.py' | awk '{ print $2 }')
        ;;
     *)
         echo "Usage: service lcd start|stop"
         exit 1
        ;;
esac
exit 0

設置47digitclock.py python腳本開機啟動

給文件添加執行權限

sudo chmod +x /etc/init.d/startmy47digitclock

這樣47digitclock的啟動腳本改用service 命令就可以

sudo service startmy47digitclock start#啟動
sudo service startmy47digitclock stop#停止

最后設置開機啟動

sudo update-rc.d startmy47digitclock defaults

取消開機啟動(從update-rc.d中移除這個開機啟動)

sudo update-rc.d startmy47digitclock remove
  1. DHT11 沒有LCD的 啟動服務
sudo vim /etc/init.d/startmydht11

/etc/init.d/startmydht11中添加以下內容:

#!/bin/bash
# /etc/init.d/startmydht11

### BEGIN INIT INFO
# Provides: mydht11
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: pi start DHT11 initscript
# Description: This service is used to manage a humiture
### END INIT INFO

case "$1" in
     start)
          echo "Starting DHT11 humiture"
          cd /var/www/html/rpi-TempRuntime && python -u DHT11-WITHOUT-LCD.py &
        ;;
     stop)
        echo "Stopping  DHT11 humiture"
        #killall DHT11-WITHOUT-LCD.py
        kill $(ps aux | grep -m 1 'python -u DHT11-WITHOUT-LCD.py' | awk '{ print $2 }')
        ;;
     *)
         echo "Usage: service lcd start|stop"
         exit 1
        ;;
esac
exit 0

設置DHT11-WITHOUT-LCD.py python腳本開機啟動

給文件添加執行權限

sudo chmod +x /etc/init.d/startmydht11

這樣DHT11-WITHOUT-LCD.py(start.sh)的啟動腳本改用service 命令就可以

sudo service startmydht11 start#啟動
sudo service startmydht11 stop#停止

最后設置開機啟動

sudo update-rc.d startmydht11 defaults

注:啟動腳本中的Provides不能重復,不然在設置開機啟動時會提示

insserv: script startmydht11: service embbnux already provided!
insserv: exiting now!
update-rc.d: error: insserv rejected the script header

Nokia 5110顯示屏

接口為串行SPI接口

本想加一個todo list顯示在一個顯示器上面,上班之前看看有什么忘記帶了的,可是自己先前買了的Nokia 5110顯示屏,找了網上的資料和教程,不能顯示中文,只好放棄,可能要買另外一個顯示屏了。目前用這個Nokia 5110 顯示屏來顯示和教程一樣的資料,啟動時間(Up),Cpu占用率,內存使用率,當前樹莓派的溫度,時間,Ip地址。

Nokia5110顯示屏與樹莓派連接,以下gpio編號使用wiringPi編號。

符號 含義 樹莓派 Pin 樹莓派 含義 樹莓派 wiringPi
RST 復位 29 GPIO.5 21
CE 片選 31 GPIO.6 22
DC 數據/指令選擇 33 GPIO.13 23
Din 串行數據線 35 GPIO.19 24
CLK 串行時鍾線 37 GPIO.26 25
Vcc 電源輸入(3.3v和5v均可) 38 GPIO.16 28
BL 背光控制端 40 GPIO.20 29
Gnd 地線 34 地線

#from Raspberry pi ssh
wget http://blog.lxx1.com/wp-content/uploads/2016/07/nokia510.zip
chmod +x nokia510.zip
cd nokia510
pi@raspberrypi:~/workspace/nokia510 $ ls -lah
total 72K
drwxr-xr-x 2 pi pi 4.0K Dec 22 23:48 .
drwxrwxrwx 3 pi pi 4.0K Dec 23 22:31 ..
-rwxr-xr-x 1 pi pi  21K Dec 22 23:46 cpushow
-rw-r--r-- 1 pi pi  25K Jan 17  2015 PCD8544.c #Nokia5110顯示屏的驅動文件
-rw-r--r-- 1 pi pi 3.2K Jan 17  2015 PCD8544.h #驅動文件的頭文件
-rw-r--r-- 1 pi pi 6.0K Jul 13  2016 pcd8544_rpi.c #顯示程序 
## 編譯運行,生成 cpushow 文件
pi@raspberrypi:~/workspace/nokia510 $ cc -o cpushow pcd8544_rpi.c PCD8544.c -L /usr/local/lib -l wiringPi

參考文章的pcd8544_rpi.c 文件內容是:

/*
=================================================================================
 Name        : pcd8544_rpi.c
 Version     : 0.1

 Copyright (C) 2012 by Andre Wussow, 2012, desk@binerry.de

 Description :
     A simple PCD8544 LCD (Nokia3310/5110) for Raspberry Pi for displaying some system informations.
         Makes use of WiringPI-library of Gordon Henderson (https://projects.drogon.net/raspberry-pi/wiringpi/)

         Recommended connection (http://www.raspberrypi.org/archives/384):
         LCD pins      Raspberry Pi
         LCD1 - GND    P06  - GND
         LCD2 - VCC    P01 - 3.3V
         LCD3 - CLK    P11 - GPIO0
         LCD4 - Din    P12 - GPIO1
         LCD5 - D/C    P13 - GPIO2
         LCD6 - CS     P15 - GPIO3
         LCD7 - RST    P16 - GPIO4
         LCD8 - LED    P01 - 3.3V

================================================================================
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.
================================================================================
 */
#include <wiringPi.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/sysinfo.h>
#include "PCD8544.h"

//devin modify
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <net/if.h>

#define TEMP_PATH "/sys/class/thermal/thermal_zone0/temp"
#define MAX_SIZE 32
#define NETWORK_FILE "/etc/network/interfaces"

// 引腳連接
int _din = 24;
int _sclk = 25;
int _dc = 23;
int _rst = 21;
int _cs = 22;

int _vcc = 28;
int _bl = 29;

// 對比度調節,根據屏幕亮度選擇
//may be need modify to fit your screen!  normal: 30- 90 ,default is:45 !!!maybe modify this value!
int contrast = 30;

time_t timep;
struct tm *p;
char *wday[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};

char get_temp(void);
char* getip(char* ip_buf);
char* get_temp2(void);
int min,hour,sec,mday;
char week;
struct tm *localtime(const time_t *timep);
int main(void)
{

 // 打印程序運行信息
  printf("Raspberry Pi Nokia5110 sysinfo display\n");
  printf("========================================\n");

  // 檢查wiringPi是否啟動
  if (wiringPiSetup() == -1)
  {
        printf("wiringPi-Error\n");
    exit(1);
  }

  // 初始化Nokia並且清楚顯示
  LCDInit(_sclk, _din, _dc, _cs, _rst, _vcc, _bl, contrast);
  LCDclear();

  // 顯示樹莓派Logo
  LCDshowLogo();

  delay(2000);

  for (;;)
  {
          // 清楚屏幕顯示
          LCDclear();

          //獲得當前時間
          char timeInfo[16];
          time(&timep);
          p=localtime(&timep);
          mday=p->tm_mday;
          min=p->tm_min;
          week=p->tm_wday;
          hour=p->tm_hour;
          sec=p->tm_sec;
          sprintf(timeInfo, "%d %d:%d:%d",mday,hour,min,sec);

          // 獲得 system usage / info
          struct sysinfo sys_info;
          if(sysinfo(&sys_info) != 0)
          {
                printf("sysinfo-Error\n");
          }

          // 啟動時間
          char uptimeInfo[15];
          unsigned long uptime = sys_info.uptime / 60;
          sprintf(uptimeInfo, "Up %ld min", uptime);

          // CPU占用
          char cpuInfo[10];
          unsigned long avgCpuLoad = sys_info.loads[0] / 1000;
          sprintf(cpuInfo, "CPU %ld%%\r", avgCpuLoad);

          // 內存使用量及占用
          char ramInfo[10];
          unsigned long totalRam = sys_info.totalram / 1024 / 1024;
          unsigned long freeRam = sys_info.freeram /1024 /1024;
          unsigned long usedRam = totalRam - freeRam;
          unsigned long ram_load = (usedRam * 100) / totalRam;
          sprintf(ramInfo, "RAM %.3dM %.2d", usedRam,ram_load);

          // 樹莓派溫度
          char tempInfo[10];
          sprintf(tempInfo, "TEM %.2dC %s", get_temp(),wday[week]);

          //IP 信息
          char ipInfo[16];
          getip(ipInfo);

          //開始顯示
          LCDdrawstring(0, 0, uptimeInfo);
          LCDdrawstring(0, 8, cpuInfo);
          LCDdrawstring(0, 16, ramInfo);
          LCDdrawstring(0, 24, tempInfo);
          LCDdrawstring(0, 32, timeInfo);
          LCDdrawstring(0, 40, ipInfo);
          LCDdisplay();

          delay(1000);
  }
  return 0;
}

//decin modify

char get_temp(void)
{
    int fd;
    double temp = 0;
    char buf[MAX_SIZE];

    // 打開/sys/class/thermal/thermal_zone0/temp
    fd = open(TEMP_PATH, O_RDONLY);
    if (fd < 0) {
        fprintf(stderr, "failed to open thermal_zone0/temp\n");
                // 關閉文件
                close(fd);
        return -1;
    }

    // 讀取內容
    if (read(fd, buf, MAX_SIZE) < 0) {
        fprintf(stderr, "failed to read temp\n");
                // 關閉文件
                close(fd);
        return -1;
    }

    // 轉換為浮點數打印
    temp = atoi(buf) / 1000.0;
        // 關閉文件
        close(fd);
        return temp;
}

// 獲取eth0端口的IP地址,可根據需要設置為wlan0
char* getip(char* ip_buf)
{
    struct ifreq temp;
    struct sockaddr_in *myaddr;
    int fd = 0;
    int ret = -1;
    strcpy(temp.ifr_name, "eth0");
    if((fd=socket(AF_INET, SOCK_STREAM, 0))<0)
    {
        return NULL;
    }
    ret = ioctl(fd, SIOCGIFADDR, &temp);
    close(fd);
    if(ret < 0) return NULL; myaddr = (struct sockaddr_in *)&(temp.ifr_addr); strcpy(ip_buf, inet_ntoa(myaddr->sin_addr));
        //printf("IP: %s", ip_buf);
    return ip_buf;
}

運行命令,讓 Nokia 5110顯示屏顯示資料:

sudo ./cpushow

如需后台運行:

sudo ./cpushow &

查找啟動的這個進程

ps aux | grep 'cpushow'

根據查找結果,kill -9 查詢結果的Pid 就停止了。

接了Nokia 5110和DHT11效果

參考文獻

  1. 基於樹莓派3B,DHT11/DHT22,LCD1602的一個實時溫度濕度檢測系統
  2. 樹莓派系統時間同步
  3. 教你如何修改樹莓派的時區和網絡對時
  4. 【手把手教你樹莓派3 (五)】DHT11傳感器
  5. 樹莓派國內可用鏡像源 最后選擇的是中國科學技術大學開源軟件鏡像,清華大學的好像是https的鏈接,提示了
     E: The method driver /usr/lib/apt/methods/https could not be found.
     N: Is the package apt-transport-https installed?
    
  6. 我使用過的Linux命令之nano - 比vi簡單易用的文本編輯器 學習到了nano的基本使用,Ctrl + O保存文件,Ctrl + x退出nano。之前一直怕用nano,現在暫時會用nano編輯器了。
  7. PYTHON的程序在LINUX后台運行
  8. linux后台運行python程序 將運行的python命令,改為bash文件
  9. Linux中讓進程在后台運行的方法 按照這里的方法,將自己寫的start.sh,后台運行
  10. 4 digits-7 segmenten LED display met TM1637 controller aansturen 4位數碼管帶時鍾點積木顯示當前的時間,下載了里面的樹莓派針腳圖片
  11. 樹莓派系統時間同步 用來參考樹莓派自動同步網絡時間
  12. Python用特殊符號切割字符串並生成list(簡單)
  13. python datetime模塊用strftime 格式化時間
  14. 樹莓派用服務方式設置開機啟動
  15. Ubuntu啟動項設置——之update-rc.d 命令使用
  16. 樹莓派 之 使用Nokia5110顯示屏顯示系統信息 Nokia 5110顯示資料主要參考源
  17. 樹莓派3B--WiringPi控制GPIO - csdn 學習到 gpio 命令的用法


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM