【Linux】树莓派控制光强传感器(C、python手把手教学)

2023-05-16

本文分为三个部分:

1.光强传感器说明 2.程序解读 3.前期准备(放在最后一部分,供小白查阅借鉴,包括本文需要用到的wiringPi库函数)

一、光强传感器说明

1.TSL256x 是 TAOS 公司推出的一种高速、低功耗、宽量程、可编程灵活配置的光强传感器芯片。外部引脚仅由3.3v电源引脚、SDA引脚、SCL引脚、中断控制引脚、地引脚组成。

2.TSL256x 数据传输遵循I2C总线协议,它只需要两根线即可在连接于总线上的器件之间传送信息。I2C的具体细节,详见I2C总线介绍

3.TSL256x 有 2 种封装形式: 6LEAD CHIPSCALE 和 6LEAD TMB。封装形式不同,相应的光照度计算公式也不同,下图为这两种封装形式的引脚分布图。

在这里插入图片描述
1 和脚 3: 分别是电源引脚和信号地。其工作电压范围是 2.7~3.5V

2: 器件访问地址选择引脚。由于该引脚电平不同,该器件有 3个不同的访问地址。具体关系如下图所示:
由上图所知:
当ADDR SEL接 GND 时I2C的访问地址为 0x29
当ADDR SEL 悬空 时I2C的访问地址为 0x39
当ADDR SEL接 VCC 时I2C的访问地址为 0x39

4 和脚 6: I2C 或 SMBus 总线的时钟信号线和数据线。

5: 中断信号输出引脚。当光强度超过用户编程配置的上或下阈值时,器件会输出一个中断信号。

** 树莓派的引脚图见 三、前期准备 部分**
(博客采用悬空的接法,访问地址为0x39,电源引脚接于3.3v)

4.设备检查
在接好线后开始下一步的准备工作,若树莓派上未安装i2c-tools的软件包,则先安装:

sudo apt-get install i2c-tools

观察设备地址:(按照版本不同有如下命令,在 v1 版本的树莓派上是 0,v2 版本上是 1)

sudo i2cdetect -y 0
sudo i2cdetect -y 1

或者使用 gpio 命令来调用 i2cdetect 命令,从而检测 I2C设备

gpio i2cdetect

结果如下图:可以观察到地址为0x39
在这里插入图片描述
我们还需要了解此命令,用来观察设备内部各个寄存器的值:(0x39要按照自己的地址更改)

sudo i2cdump -f -y 1 0x39

结果如下:( 此命令在后期调试代码的时候可能会有帮助 )
在这里插入图片描述
5.对TSL2561寄存器进行操作的说明
参照TSL2561的英文手册
关于命令寄存器:
在这里插入图片描述
在这里插入图片描述
红图中点标注处为重点,命令寄存器用于指定后续操作的目标寄存器的地址,所以要对其他寄存器操作时,要通过Command寄存器,由table 3与table可知,如果要对存储数据的寄存器(table 2中的DATA0LOW,DATA0HIGH,DATA1LOW,DATA1HIGH)进行读取操作,需要将命令寄存器分别设置为:0x8C,0x8D,0x8E,0x8F

关于控制寄存器:
TSL2561的开启与关闭与Control寄存器有关
在这里插入图片描述
由上图可知,把POWER位设置为11(即0x03)是开启,关闭是0(即0x00);

6.光照强度的计算

从数据寄存器读取到的数值还需要进行转换才能得到想要的结果
首先

CH0 = 256 * DATA0HIGH + DATA0LOW
CH1 = 256 * DATA1HIGH + DATA1LOW

接着按照产品的封装形式对应不同的计算公式,具体见自己的产品包装说明。
(此博客采用第二种计算公式)Lux为所得到的最终光强结果。

在这里插入图片描述
二、程序解读

strerror()需要包含库函数有

#include <errno.h>
#include <string.h>

若有疑问请点击:此链接

wiringPiSetup()
初始化 wiringPi,幵假定程序将使用 wiringPi 的管脚定义图。具体管脚映射,可以通过 gpio readall 命令来查看
int wiringPiI2CSetup(int devId);
该函数使用指定设备标示号来初始化 I2C 系统。参数 devId 是 I2C设备的地址,可以通过i2cdetect 命令可以查到该地址。该函数会获取树莓派的版本开依据此打开/dev 目录下对应的设备,函数的返回值是标准的 Linux 文件句柄,如果有错误,则返回-1

wiringPiSetup();
fd=wiringPiI2CSetup(I2C);

以下为打开TSL2561时的操作,注意要延时至少0.5s,此博客采样延时1s

 wiringPiI2CWrite(fd,CONTROL);
 wiringPiI2CWrite(fd,POWER_UP);
 sleep(1);

以下为读取数据寄存器中的数据操作
int wiringPiI2CRead(int fd);
简单的设备读操作。一些设备可以直接读取,而不需要发送任何寄存器地址。
int wiringPiI2CWrite(int fd, int data);

 for(i=0;i<datareg_num;i++)
 {
 	 wiringPiI2CWrite(fd,reg_addr[i]);
 	 reg_data[i]=wiringPiI2CRead(fd);
 }

接下来调用计算光强的函数进行计算:具体计算函数详见完整代码

 Lux=cal(reg_data);

若数据读取是无效的时候,返回值是-1,而Lux的定义是double类型,在将double类型与int类型做比较时需要如下操作

if(fabs(Lux+1)<0.00000001)
{
	printf("Data read error!\n");
}
else
{
	printf("The light intensity is %lf\n",Lux);
}

程序结束时,需要把TSL2561关闭,同打开操作类似:

 wiringPiI2CWrite(fd,CONTROL);
 wiringPiI2CWrite(fd,POWER_DOWN);

以下为完整C语言代码:(仅供测试使用)
若对里面的一些操作有些疑惑,请仔细查看第一部分的介绍
宏定义最好封装在头文件里,为了读者方便理解,本文没有封装

#include <stdio.h>
#include <wiringPi.h>
#include <wiringPiI2C.h>
#include <math.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

#define I2C 0x39
#define datareg_num 4
#define DATA0LOW 0x8C
#define DATA0HIGH 0x8D
#define DATA1LOW 0x8E
#define DATAHIGH 0x8F
#define CONTROL 0x80
#define POWER_UP 0x03
#define POWER_DOWN 0x00

double cal(int* reg_data);		//计算光强函数声明

int main()
{
    int i;
    int fd;
    double Lux;
    int reg_data[4];
    int reg_addr[datareg_num]={DATA0LOW,DATA0HIGH,DATA1LOW,DATAHIGH};

    wiringPiSetup();
    fd=wiringPiI2CSetup(I2C);
    
    if(fd==-1)
    {
        printf("I2C initialization failed: %s",strerror(errno));
        return -1;
    }
    
    wiringPiI2CWrite(fd,CONTROL);		//TSL2561打开
    wiringPiI2CWrite(fd,POWER_UP);
    sleep(1);
    
    for(i=0;i<datareg_num;i++)			//读取数据寄存器数据
    {
    	wiringPiI2CWrite(fd,reg_addr[i]);
        reg_data[i]=wiringPiI2CRead(fd);
     }
     
     Lux=cal(reg_data);				//获取光强数据
      
     if(fabs(Lux+1)<0.00000001)
     {
     	printf("Data read error!\n");
     }
     else
     {
     	 printf("The light intensity is %lf\n",Lux);
     }
     
     wiringPiI2CWrite(fd,CONTROL);		//关闭TSL2561
     wiringPiI2CWrite(fd,POWER_DOWN);
     return 0;
}

double cal(int* reg_data)		//此代码按照第二种计算公式
{
    double CH0,CH1,div,Lux;
    CH0=256*reg_data[1]+reg_data[0];
    CH1=256*reg_data[3]+reg_data[2];
    if(CH0<=0 || CH1<0)
    {
        return -1;
     }
     div=CH1/CH0;
     if(0<div<=0.5)
     {
     	Lux=0.0304*CH0-0.062*CH0*pow(div,1.4);
     }
     else if(0.5<div<=0.61)
     {
     	Lux=0.0224*CH0-0.031*CH1;
     }
     else if(0.61<div<=0.8)
     {
     	Lux=0.0128*CH0-0.0153*CH1;
     }
     else if(0.8<div<=1.3)
     {
     	Lux=0.00146*CH0-0.00112*CH1;
     }
     else if(div>1.3)
     {
     	Lux=0;
     }
     return Lux;
}    	

编译命令:(文件名为TSL2561.c)

gcc TSL2561.c -o TSL2561 -lwiringPi -lm

运行:

./TSL2561

调试代码时,可以利用以下命令去观察设备寄存器内部的值:(观察对应的数据寄存器)

sudo i2cdump -f -y 1 0x39

另附python代码:(仅供测试使用)逻辑与C相同

#!/usr/bin/python
#encoding:utf-8

import wiringpi as wp
import time

I2C         =0x39
datareg_num =4
DATA0LOW    =0x8C
DATA0HIGH   =0x8D
DATA1LOW    =0x8E
DATA1HIGH   =0x8F
CONTROL     =0x80
POWER_UP    =0x33
POWER_DOWN  =0x00

fd=wp.wiringPiI2CSetup(I2C)

wp.wiringPiI2CWrite(fd,CONTROL)
wp.wiringPiI2CWrite(fd,POWER_UP)
time.sleep(1)

##read data

wp.wiringPiI2CWrite(fd,DATA0LOW)
data0_L=wp.wiringPiI2CRead(fd)

wp.wiringPiI2CWrite(fd,DATA0HIGH)
data0_H=wp.wiringPiI2CRead(fd)

wp.wiringPiI2CWrite(fd,DATA1LOW)
data1_L=wp.wiringPiI2CRead(fd)

wp.wiringPiI2CWrite(fd,DATA1HIGH)
data1_H=wp.wiringPiI2CRead(fd)

##calulate Lux
CH0=256*data0_H+data0_L
CH1=256*data1_H+data1_L

if(CH0==0 | CH1==0):
    Lux=0
else:
	div=float(CH1)/float(CH0)
	if div<=0.5:
		 Lux=0.034*float(CH0)-0.063*float(CH0)*(div**1.4)

	elif div>0.5 & div<=0.61:
		 Lux=0.0224*float(CH0)-0.031*CH1

	elif div>0.61 & div<=0.8:
		Lux=0.0128*float(CH0)-0.0153*CH1

	 elif div>0.8 & div<=1.3:
		 Lux=0.00146*float(CH0)-0.00112*CH1

	elif div>1.3:
		  Lux=0

print '%f' % Lux

wp.wiringPiI2CWrite(fd,CONTROL)
wp.wiringPiI2CWrite(fd,POWER_DOWN)

三、前期准备

1.引脚图:

在这里插入图片描述

关于wiringPi的部分:请看此链接的中的 三、前期准备 有详细说明

因本人水平有限,如果有误,欢迎指正,如需转载请附上本文链接并注明。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Linux】树莓派控制光强传感器(C、python手把手教学) 的相关文章

  • opencv水印周围的轮廓

    我想在图像中的水印周围画一个框 我已经提取了水印并找到了轮廓 但是 不会在水印周围绘制轮廓 轮廓是在我的整个图像上绘制的 请帮我提供正确的代码 轮廓坐标的输出为 array 0 0 0 634 450 634 450 0 dtype int
  • 补丁 - 为什么相对补丁目标名称不起作用?

    我已经从模块导入了一个类 但是当我尝试修补类名而不使用模块作为前缀时 出现类型错误 TypeError Need a valid target to patch You supplied MyClass 例如 以下代码给出了上述错误 imp
  • Python - 来自 .进口

    我第一次尝试图书馆 我注意到解决图书馆内导入问题的最简单方法是使用如下结构 from import x from some module import y 我觉得这件事有些 糟糕 也许只是因为我不记得经常看到它 尽管公平地说我还没有深入研究
  • 删除 Django 1.7 中的应用程序(和关联的数据库表)

    是否可以使用 Django 1 7 迁移来完全删除 卸载应用程序及其所有跟踪 主要是其所有数据库表 如果没有 在 Django 1 7 中执行此操作的适当方法是什么 python manage py migrate
  • Mac OS X 中文件系统的 Unicode 编码在 Python 中不正确?

    在 OS X 和 Python 中处理 Unicode 文件名有点困难 我试图在代码中稍后使用文件名作为正则表达式的输入 但文件名中使用的编码似乎与 sys getfilesystemencoding 告诉我的不同 采取以下代码 usr b
  • sklearn 中的 pca.inverse_transform

    将我的数据拟合后 X 我的数据 pca PCA n components 1 pca fit X X pca pca fit transform X 现在 X pca 具有一维 当我根据定义执行逆变换时 它不是应该返回原始数据 即 X 二维
  • Pandas:如果单元格包含特定文本则删除行

    pandas 中的这段代码不起作用 如果该列包含提供的任何文本 数字 我希望它删除该行 目前 我只能在单元格与我的代码中传递的确切文本匹配时才能使其工作 因为它只删除显示 Fin 的单元格不是金融或金融 df2 df df Team Fin
  • 在没有模型的情况下将自定义页面添加到 django admin

    我正在尝试在没有模型关联的情况下向管理员添加自定义页面 这就是我迄今为止所取得的成就 class MyCustomAdmin AdminSite def get urls self from django conf urls import
  • 使用 Grep 查找两个短语之间的文本块(包括短语)

    是否可以使用 grep 来高亮所有以以下内容开头的文本 mutablePath CGPathCreateMutable 并以以下内容结尾 CGPathAddPath skinMutablePath NULL mutablePath 这两个短
  • 进程退出后 POSIX 名称信号量不会释放

    我正在尝试使用 POSIX 命名信号量进行跨进程同步 我注意到进程死亡或退出后 信号量仍然被系统打开 在进程 打开它 死亡或退出后是否有办法使其关闭 释放 早期的讨论在这里 当将信号量递减至零的进程崩溃时 如何恢复信号量 https sta
  • 用 python 编写的数学语法检查器

    我需要的只是使用 python 检查字符串是否是有效的数学表达式 为了简单起见 假设我只需要 运算符 也作为一元 带有数字和嵌套括号 为了完整性 我还添加了简单的变量名称 所以我可以这样测试 test 3 2 1 valid test 3
  • 确定我可以向文件句柄写入多少内容;将数据从一个 FH 复制到另一个 FH

    如何确定是否可以将给定数量的字节写入文件句柄 实际上是套接字 或者 如何 取消读取 我从其他文件句柄读取的数据 我想要类似的东西 n how much can I write w handle n read r handle buf n a
  • Jython 和 SAX 解析器:允许的实体不超过 64000 个?

    我做了一个简单的测试xml saxJython 中的解析器在处理大型 XML 文件 800 MB 时遇到以下错误 Traceback most recent call last File src project xmltools py li
  • 返回表示每组内最大值的索引的一系列数字位置

    考虑一下这个系列 np random seed 3 1415 s pd Series np random rand 100 pd MultiIndex from product list ABDCE list abcde One Two T
  • Mac OSX 10.6 上的 Python mysqldb 不工作

    我正在使用 Python 2 7 并尝试让 Django 项目在 MySQL 后端运行 我已经下载了 mysqldb 并按照此处的指南进行操作 http cd34 com blog programming python mysql pyth
  • 动态过滤 pandas 数据框

    我正在尝试使用三列的阈值来过滤 pandas 数据框 import pandas as pd df pd DataFrame A 6 2 10 5 3 B 2 5 3 2 6 C 5 2 1 8 2 df df loc df A gt 0
  • 当数据库不是 Django 模型时,是否可以使用数据库中的表?

    是否可以从应用程序数据库中的表获取查询集 该表不是应用程序中的模型 如果我有一个不是名为 cartable 的模型的表 从概念上讲 我想这样做 myqueryset cartable objects all 有没有相对简单的方法来做到这一点
  • Python SSL X509:KEY_VALUES_MISMATCH

    Python HTTPS server from http server import HTTPServer SimpleHTTPRequestHandler import ssl https stackoverflow com a 408
  • 混淆矩阵不支持多标签指示符

    multilabel indicator is not supported是我在尝试运行时收到的错误消息 confusion matrix y test predictions y test is a DataFrame其形状为 Horse
  • C++ Boost ASIO 简单的周期性定时器?

    我想要一个非常简单的周期性计时器每 50 毫秒调用我的代码 我可以创建一个始终休眠 50 毫秒的线程 但这很痛苦 我可以开始研究用于制作计时器的 Linux API 但它不可移植 I d like使用升压 我只是不确定这是否可能 boost

随机推荐

  • 【软件相关】Multisim完整教程

    文章目录 前言教程书籍安装基本使用快捷键总结高级操作1 示波器操作2 瞬态仿真3 MCU仿真 问题与解决1 添加场效应管不符合电气规律 xff1f 前言 电路仿真软件中 xff0c Multisim可能不是功能最强大的 xff0c 但一定是
  • 【单片机】C语言总结

    文章目录 文章内容1 位运算1 1 初级应用1 2 进阶应用1 2 1 给寄存器某一位置11 2 2 给寄存器某一位清01 2 3 翻转寄存器某一位1 2 4 数据的字节分解 2 宏定义和预编译2 1 理论指导2 2 看到一个宏定义在数据切
  • 【嵌入式工具】Keil下载,安装,配置教程大全

    文章目录 前言一 Keil下载及安装二 Keil兼容C51和ARM三 STM32支持包下载安装1 官网下载2 安装 四 常用配置1 代码补全和代码联想2 主题设置3 快捷键设置4 快速模板5 快速格式化代码6 转换文件编码格式 2022 3
  • 【嵌入式模块】蓝牙模块使用总结

    目录 前言参考链接常用的蓝牙模块有哪几种 xff1f 如何设置蓝牙模块 xff1f AT指令集BT 04HC 06HC 05 蓝牙主从配对工作手机与电脑端调试方法 前言 作为最为常用的无线通信模块 xff0c 蓝牙可以说是一些小型项目 xf
  • 【嵌入式模块】DS1302 时钟定时芯片

    文章目录 参考链接概述引脚与内部结构引脚定义常用电路内部寄存器及RAM分布 工作时序例程 xff08 51单片机 xff09 参考链接 CSDN 1 CSDN 2 博客园 概述 DS1302时钟芯片是DALLAS 公司推出的涓流充电时钟芯片
  • 【嵌入式模块】直流电机驱动L298N,TB6612详解

    文章目录 参考链接概述L298NTB6612FNG 参考链接 单片机 控制 直流电机 基于L9110S L298N TB6612FNG驱动 简书 概述 从上面那篇教程我们可以看出 xff0c 直流电机控制时 xff0c 只需要给它输入一个P
  • vue .npmrc 文件的作用

    有些项目根目录下有个 npmrc的文件 xff0c 点开看只有一句话 xff1a span class token assign left variable registry span span class token operator 6
  • 【嵌入式模块】ESP8266完整教程

    前言 无线通信中除了最为常用的蓝牙之外 xff0c 剩下的就是WiFi了 xff0c 但是相比于蓝牙模块一般只用来进行透传 xff0c WiFi模块的可自定义程度要更强 xff0c 而这也导致了WiFi模块的入门相对难了一点 参考资料 WI
  • 【MATLAB】(二)基本使用拾遗

    本文目录 0 前期教程1 前言2 输入输出2 1 input2 2 load2 3 importdata2 4 disp2 5 fopen amp fclose2 6 fscanf amp fprintf2 7 textread amp t
  • 【Linux】Ubuntu使用入门

    前言 本文主要记录一些Ubuntu中常用的基本操作 xff0c 记录自己的实践经历 xff0c 不断更新 xff01 xff01 xff01 0 基本文件交互 在Ubuntu系统中 xff0c 右键是没有创建文件的选项的 xff0c 只能创
  • 【嵌入式模块】MPU6050

    文章目录 0 前言1 MPU6050概述1 1 基本概述1 2 引脚和常用原理图 2 代码3 姿态解算3 1 欧拉角 amp 旋转矩阵3 2 DMP 3 校正 0 前言 作为惯性传感器中入门级别的器件 xff0c MPU6050凭借它出色的
  • 【PyQt】PyQt5进阶——串口上位机及实时数据显示

    文章目录 0 前期教程1 前言2 串口部分 QtSerialPort3 绘图部分3 1 QCustomPlot3 2 QtChart3 3 QWT3 4 Qt Designer中如何使用 参考链接 0 前期教程 Python PyQt5入门
  • 【软件相关】Proteus仿真STM32记录

    文章目录 0 前期教程1 前言2 先说说建议的流程3 需要注意的事项3 1 供电网配置不要忘了3 2 ADC模块的使用3 3 元器件查询手册 4 一些小技巧4 1 快速添加标号4 2 出现诡异问题的一种解决思路 0 前期教程 软件相关 Pr
  • 【嵌入式】Modbus实践

    前言 最近接了一个项目 xff0c 需要使用Modbus协议 xff0c 虽然之前有所耳闻 xff0c 但一直没有实操过 xff0c 但实践之后发现其实还是很简单的 xff0c 我认为它本质上就是对串口传输进行 二次封装 建议的入门顺序 大
  • 正则 ^ , \G , \A 区别

    正则 G A 区别 如图
  • c的string库常用函数记录

    1 strcat x xff0c y 将字符串y拼接在字符串x后面 2 strlen xff08 x xff09 返回字符串x的长度 3 strcopy xff08 x xff0c y xff09 将y复制给x xff08 类似于x 61
  • ROS发行版列表完整版

    官方原文 xff1a http wiki ros org Distributions Distro Release date EOL date ROS Melodic Morenia Recommended May 23rd 2018 Ma
  • React styled-components(三)—— 高级特性

    styled components 高级特性 样式继承嵌套设置主题 样式继承 新建 Demo js 文件 xff1a span class token keyword import span React span class token p
  • (九)Java算法:快速排序(详细图解)

    目录 一 前言1 1 概念1 2 算法过程 二 maven依赖三 流程解析3 1 全部数据分区3 2 左边数据分区3 3 右边数据分区 四 编码实现结语 一 前言 1 1 概念 快速排序 xff1a 用数组的第一个数作为基准数据 xff0c
  • 【Linux】树莓派控制光强传感器(C、python手把手教学)

    本文分为三个部分 xff1a 1 光强传感器说明 2 程序解读 3 前期准备 xff08 放在最后一部分 xff0c 供小白查阅借鉴 xff0c 包括本文需要用到的wiringPi库函数 xff09 一 光强传感器说明 1 TSL256x