×

小型光传感器站开源分享

消耗积分:0 | 格式:zip | 大小:0.05 MB | 2022-10-20

梁宏满

分享资料个

描述

在巴黎 Usine.io 举办的英特尔物联网黑客马拉松上,我有机会在英特尔 Edison Arduino 板和一堆 Grove 传感器/执行器旁边,还从 Snootlab 获得了新的 Akene 板。

感谢 Intel IoT 人员、来自 SigFox 的 Nicolas 以及 BeMyApp 的所有员工为这次 Hackaton...

第一步:项目...

我决定用 Intel Edison 板、Grove Shield、SigFox Akene Shield 和 I2C Grove TSL2561 构建一个小型光传感器站。

该站大约每 10 分钟通过 SigFox 网络上传与该 10 分钟周期相关的 3 个不同值(以勒克斯为单位):算术平均光、最小和最大光。

这将有助于了解这段时间内光线如何围绕其平均值波动,从而了解天空如何多云(如果至少有风推动云层……)。

我将在该项目中使用 Python。

第 2 步:友好的开发环境

 
pYYBAGNQx8eACpJSAABjC8Qfzgo184.png
Intel Edison + Arduino 分线板 + Grove shield
 

我假设英特尔 Edison 环境已准备好用于 Python,并且在 Edison 上设置了密码以打开 SSH 会话和 SFTP 以上传 Python 代码。

我正在使用 OS X,并将使用 CoolTerm 进行通信,并使用出色的 TextWrangler 作为代码编辑器和代码上传器 (SFTP)。

第 3 步:框架:sensor.py

#!/usr/bin/env python import time import mraa # Sensor initialisation import pyupm_tsl2561 tsl2561Ready = True if (tsl2561Ready) : # 在 I2C 上实例化一个数字光传感器 TSL2561 print "initialisation TLS2561" lightSensor = pyupm_tsl2561.TSL2561() time.sleep (10) # 值 numberSamples = 200 valueCount = 0 valueNow = 0 valueSum = 0 valueAvg = 0 valueMin = 32767 valueMax = 0 # 主循环 while True : if (valueCount == numberSamples) : print print "after", numberSamples, "samples (以勒克斯为单位的值):" print "valueAvg: %5d" % valueAvg, "- valueMin: %5d" % valueMin, "- valueMax: %5d" % valueMax valueCount = 0 if (valueCount == 0) : valueNow = 0 valueSum = 0 valueAvg = 0 valueMin = 32767 valueMax = 0 if (tsl2561Ready) :valueNow = lightSensor.getLux() if (valueNow >= 0) : valueCount = valueCount + 1 valueSum = valueSum + valueNow valueAvg = valueSum / valueCount if valueNow < valueMin : valueMin = valueNow if valueNow > valueMax : valueMax = valueNow now = time。 ctime(int(time.time())) if (valueCount == 1) : print print "Light (luxes):" print now,"(GMT)",": %5d" % valueNow,"- avg :%5d" % valueAvg,"- min:%5d" % valueMin,"- max:%5d" % valueMax,"-%4d 个样本" % valueCount time.sleep(1)valueMax = valueNow now = time.ctime(int(time.time())) if (valueCount == 1) : print print "Light (values in lux):" print now,"(GMT)",": %5d " % valueNow,"- avg:%5d" % valueAvg,"- min:%5d" % valueMin,"- max:%5d" % valueMax,"-%4d 个样本" % valueCount time.sleep(1 )valueMax = valueNow now = time.ctime(int(time.time())) if (valueCount == 1) : print print "Light (values in lux):" print now,"(GMT)",": %5d " % valueNow,"- avg:%5d" % valueAvg,"- min:%5d" % valueMin,"- max:%5d" % valueMax,"-%4d 个样本" % valueCount time.sleep(1 )

 

第 4 步:使用 sensor.py 得到什么

> 蟒蛇传感器.py

 
pYYBAGNQx8uAcHrVAAB5-35csaU200.png
样本输出 - 传感器值
 

第 5 步:SigFox 和 Akene 盾牌

 
poYBAGNQx82AAo_QAACIkVGXJHE319.png
Akene Arduino Shield,其 SIGFOX 模块 (TD1208) 在左侧
 

Akene 板是 SnootLab 的实验性 Arduino 扩展板,上面装有 TD1208 SoC(片上系统)。TD1208 是一款经过 SigFox 认证的无线电收发器,结合了 ARM Cortex M3,它实现了用于将值发送到 SigFox 操作的电信网络的电信调制解调器堆栈,并且除了其串行调制解调器链路之外,还包括用于物联网传感器的 I2C 功能。

SIgFox 服务依赖于目前部署在西欧、旧金山以及其他国家或城市的 LPWA(低功耗广域)网络。SigFox 协议专为小消息而设计,其技术专注于设备客户端的能源效率和每个基础设施基站的大区域覆盖。

SigFox 网络允许每个设备每天最多发送140 条消息(即每 1000 万次),每个消息最多可发送12 个可用字节,即 6 个短整数值(时间戳和唯一设备 ID 也会另外传输)。

更多信息: http: //maker.sigfox.com

 

第 6 步:让我们确保 Akene shield 及其调制解调器正常工作

 
poYBAGNQx9GAXJH9AABitEzsUuc433.png
Akene Shield 使用引脚 4 和 5 与 Sigfox 模块通信。
 

Akene shield 可以用作调制解调器,所以我们首先将它连接到 Edison:

• 地对地(黑线)

• 3.3v 至 3.3v(红线)

• Edison 的串行 Rx(引脚 0)到 Akene 的 Tx(引脚 D4) - 蓝线

• Edison 的串行 Tx(引脚 1)到 Akene 的 Rx(引脚 D5) - 白线

 

步骤 7:通过终端向 Akene shield 的 TD1208 发送直接命令

我们可以将 TD1208 视为调制解调器。

必须安装 PySerial 包。

python -m serial.tools.miniterm

我们使用 miniterm(PySerial 的一部分) - 并指定串行端口:/dev/ttyMFD1 - 发送直接命令,例如:

AT

应该回复OK(否则有问题),

AT&V

由TD1208标识回复,

AT$SS01234567

它将 01234567 消息发送到 SigFox 网络(最大十六进制数字为 24,即 12 个字节),以及

AT?

它返回可用命令的列表。

要退出 miniterm,在 OS X 上使用法语键盘:CTRL 6

 

第 8 步:向 SigFox 网络发送消息的简单 python 命令

这是专用于另一个 TD1208 板(来自 SNOC 的 RPISIGFOX)的 python 命令的快速改编,可在 Internet 上找到。

顺便提一下,为了与英特尔爱迪生一起使用串行,

• 必须先初始化将要使用的端口/引脚,在我们的例子中是/dev/ttyMFD1(引脚0 和1):

import libmraa
x=Uart(0)

• 调用serial.Serial(......

您可以这样使用命令:

python sendsigfox.py 01234567

这会将消息 01234567 发送到 SigFox 网络

#!/usr/bin/python


#  This script allow the control of the SNOOTLAB expansion board, and is adapted for Intel Edison.
#  3 lines of code were added (LINE ADDED)
#  script has been modified from:
#
#  This script is from the rpisigfox expansion board for Raspberry Pi.
#
#  V1.0 allow only to send regular message on the SigFox Network.
#  syntax is :
#  sendsigfox MESSAGE 
#  where MESSAGE is a HEXA string encoded. Can be 2 to 24 characters representing 1 to 12 bytes.
#  Example : sendsigfox 00AA55BF to send the 4 bytes 0x00 0xAA 0x55 0xBF
# 

import time
import serial
import sys
from time import sleep

#LINE ADDED
import mraa

SOH = chr(0x01)
STX = chr(0x02)
EOT = chr(0x04)
ACK = chr(0x06)
NAK = chr(0x15)
CAN = chr(0x18)
CRC = chr(0x43)

def getc(size, timeout=1):
    return ser.read(size)

def putc(data, timeout=1):
    ser.write(data)
    sleep(0.001) # give device time to prepare new buffer and start sending it

def WaitFor(ser, s, timeOut):
        nbMax = 0
        ser.timeout = timeOut
        currentMsg = ''
        while currentMsg.endswith(s) != True :
            # should add a try catch here
            c=ser.read()
            if c != '' :
                currentMsg += c
            else :
                print 'timeout waiting for ' + s
                return False
            nbMax = nbMax + 1
            if nbMax > 150:
		print 'Timeout expired'
		return False
        return True


print('Sending SigFox Message...')

#LINE ADDED: 0 ie '/dev/ttyMFD1'
uart = mraa.Uart(0)

modem = serial.Serial(
			uart.getDevicePath(),
			baudrate=9600,
        	parity=serial.PARITY_NONE,
        	stopbits=serial.STOPBITS_ONE,
        	bytesize=serial.EIGHTBITS
		)

#LINE ADDED: closing serial before opening it, as otherwise the Edison serial seems to be already open by calling serial.Serial
modem.close()

modem.open()

modem.write('AT\r')
if (WaitFor(modem, 'OK', 3)):
	print('SigFox Modem OK')
else:
	print('SigFox Modem Error')
	modem.close()
	exit()

modem.write("AT$SS={0}\r".format(sys.argv[1]))

print('Sending ...')
if (WaitFor(modem, 'OK', 15)):
	print('OK Message sent')
else:
	print('Error Sending message')
	modem.close()
	exit()

modem.close()

 

第 9 步:使用 sendigfox.py 得到什么

>python sendigfox.py 346723

 
pYYBAGNQx9OAUmKsAAAtDAYIChQ355.png
样本输出
 

 

第 10 步:完整程序:sensor2sigfox.py

也没有什么特别的困难,只是提一下:

• 每个发送的数据都是一个 2 字节的短整数。因此 valueAvg、valueMin 和 valueMax 是 6 个字节,即 12 个十六进制字符字符串。由于在我使用的情况下,SigFox 的设置是为了将数据重新发送到 actoboard.com,并且 actoboard.com 当前接受 LittleEndian 字节顺序的数据,所以在发送之前,每个数据都会进行相应的转换。 .

• Akene 防护罩完全插在 Grove 防护罩的顶部,为了将 Edison 串行的接线安装在引脚 0 和 1 上以及将 Akene 串行的接线安装在引脚 D4 和 D5 上,使用了带子(0 到 D4 :白色表带)和(1 到 D5:黄色表带),见第一张图......这意味着干净的接线,但不可能使用爱迪生的引脚 4 和 5......

#!/usr/bin/env python 

import time
import mraa
import serial


# convert a string (n chars) into its hexadecimal string representation (n bytes - 2*n chars)
def string2hex(s) :
	return str(s).encode("hex")

# convert a short integer (2 bytes) into its hexadecimal (2 bytes) representation with BigEndian/LittleEndian bytes order
def short2hex(i, bigEndian) : 
	if (bigEndian) :
		return "%04X" % i
	else :
		return "%04X" % (((i << 8) & 0xFF00) | ((i >> 8) & 0x00FF))


def WaitFor(serial, msg, timeOut):
        nbMax = 0
        serial.timeout = timeOut
        currentMsg = ''
        while currentMsg.endswith(msg) != True :
            c = serial.read()
            if c != '' :
                currentMsg += c
            else :
                print 'timeout waiting for ' + msg
                return False
            nbMax = nbMax + 1
            if nbMax > 150:
				print 'Timeout expired'
				return False
        return True

def sendsigfox(data):
	print('Sending SigFox Message...')
	# 0 i.e. pins 0 and 1 i.e. '/dev/ttyMFD1' for Intel Edison, allow usage of UART on port 0
	uart = mraa.Uart(0)
	# define sigfox and implicitely makes a sigfox.open()
	sigfox = serial.Serial(
		uart.getDevicePath(),
		baudrate=9600,
		parity=serial.PARITY_NONE,
		stopbits=serial.STOPBITS_ONE,
		bytesize=serial.EIGHTBITS
		)
	sigfox.write('AT\r')
	if (WaitFor(sigfox, 'OK', 3)):
		print('SigFox Modem OK')
	else:
		print('SigFox Modem Error')
		sigfox.close()
		return False
	print("sending data " + data + " to SigFox network:")
	print("Sigfox: AT$SS=" + data + "\r")
	sigfox.write("AT$SS=")
	sigfox.write(data)
	sigfox.write("\r")
	if (WaitFor(sigfox, 'OK', 15)):
		print('Message sent OK')
	else:
		print('Error Sending message')
		sigfox.close()
		return False
	sigfox.close()
	return True

	
# Sending Format of data - bytes order - required (True for BigEndian, False for LittleEndian)
# for sending to actoboard.com : LittleEndian (i.e. False) is expected for received data
sendingFormat = False


# Sensor initialisation
import 			pyupm_tsl2561
tsl2561Ready	= True

if (tsl2561Ready) :
	# Instantiate a digital light sensor TSL2561 on I2C
	print "initialisation TLS2561"
	lightSensor = pyupm_tsl2561.TSL2561()
	time.sleep (10)


# Value
numberSamples	= 200
valueCount		= 0
valueNow		= 0
valueSum		= 0
valueAvg 		= 0
valueMin		= 32767
valueMax		= 0


# Main loop
while True :
		
	if (valueCount == numberSamples) :
		print
		print "after", numberSamples, "samples (values in lux):"
		print "valueAvg: %5d" % valueAvg, "- valueMin: %5d" % valueMin, "- valueMax: %5d" % valueMax
		print "valueAvg: ", short2hex(valueAvg,True), "- valueMin: ", short2hex(valueMin,True), "- valueMax: ", short2hex(valueMax,True)
		if (sendingFormat) :
			print "sending valueAvg,valueMin,valueMax (BigEndian)"
		else :
			print "sending valueAvg,valueMin,valueMax (LittleEndian)"
		sendsigfox(short2hex(valueAvg,sendingFormat)+short2hex(valueMin,sendingFormat)+short2hex(valueMax,sendingFormat))
		valueCount = 0
		
	if (valueCount == 0) :
		valueNow = 0
		valueSum = 0
		valueAvg = 0
		valueMin = 32767
		valueMax = 0
		
	if (tsl2561Ready) :
		valueNow = lightSensor.getLux()
		if (valueNow >= 0) :
			valueCount	= valueCount + 1
			valueSum = valueSum + valueNow
			valueAvg = valueSum / valueCount
			if valueNow < valueMin :
				valueMin = valueNow
			if valueNow > valueMax :
				valueMax = valueNow
	
			now = time.ctime(int(time.time()))
			
			if (valueCount == 1) :
				print
				print "Light (values in lux):"
			print now,"(GMT)",": %5d" % valueNow,"- avg:%5d" % valueAvg,"- min:%5d" % valueMin,"- max:%5d" % valueMax,"-%4d sample(s)" % valueCount
		
	time.sleep(1) 

 

第 11 步:使用 sensor2sigfox.py 得到什么

python sensor2sigfox.py

 
poYBAGNQx9aAUzAvAABketGRTMw878.png
样本输出
 

 


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !