在巴黎 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。
我假设英特尔 Edison 环境已准备好用于 Python,并且在 Edison 上设置了密码以打开 SSH 会话和 SFTP 以上传 Python 代码。
我正在使用 OS X,并将使用 CoolTerm 进行通信,并使用出色的 TextWrangler 作为代码编辑器和代码上传器 (SFTP)。
> 蟒蛇传感器.py
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
Akene shield 可以用作调制解调器,所以我们首先将它连接到 Edison:
• 地对地(黑线)
• 3.3v 至 3.3v(红线)
• Edison 的串行 Rx(引脚 0)到 Akene 的 Tx(引脚 D4) - 蓝线
• Edison 的串行 Tx(引脚 1)到 Akene 的 Rx(引脚 D5) - 白线
我们可以将 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
这是专用于另一个 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()
>python sendigfox.py 346723
也没有什么特别的困难,只是提一下:
• 每个发送的数据都是一个 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)
python sensor2sigfox.py
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
全部0条评论
快来发表一下你的评论吧 !