树莓派pi3B串口配置见:
https://blog.csdn.net/qq_40025335/article/details/81152028
#author@New
#Time:20180801
#Env:raspi、4G模块、4GSIM(本人用的移动、如用联通、电信按下文APN,修改接入点名称)
整体流程
一、配置
注意
1、ZIgBee连接传感器并采集数据发给ZigBee协调器(fan)
2、树莓派串口ttyS0(GpIO14\15)接受ZigBee协调器发来数据(通过串口发送)
python脚本实现读取串口数据保存、wxdial拨号然后发送到OneNet
3、配置4G模块,实现树莓派连网功能
(1)minicon 安装 详情见 : http://www.cnblogs.com/emouse/
sudo apt-get install minicom
(2)配置minicon-
sudo minicon -s
+-----[configuration]------+
| Filenames and paths |
| File transfer protocols -|
| Serial port setup |
| Modem and dialing |
| Screen and keyboard |
| Save setup as dfl |
| Save setup as.. |
| Exit |
Serial port setup [Enter]
+-------------------------------------------------------------+
| A - Serial Device : /dev/ttyUSB0 |
| B - Lockfile Location : /var/lock |
| C - Callin Program : |
| D - Callout Program -: |
| E - Bps/Par/Bits : 115200 8N1 |
| F - Hardware Flow Control : No |
| G - Software Flow Control : No |
| |
| Change which setting? | (Enter 退出并保存配置)
sudo minicom -s
可查看4G模块连接成功的回显信息
1)组合键 Ctrl+a 进入设置状态;(先按Ctrl+a后再按Q)
2)按 z 打开帮助菜单,或者你用的熟练的话,直接输入菜单对应的字母即可;
3)安装拨号: wxdial
sudo apt install wxdial
(4)lsusb 指令查看usb接口情况:树莓派USB无法直接识别4G模块,需要用USB转TTL--能识别PL232(对应ttyUSB0)
ifconfig -a
网络信息 :eth0/lo/wlan0/wwan0
dmesg 查看usb串口。倒数几行显示:pl2303 converter now attached to ttyUSB0。
(5)打开串口助手:sudo minicom
测试AT指令: 输入AT发 返回OK -即4G连接成功
及测试其他指令,检查SIM是否接入成功等
AT+CPSI?
(6) https://blog.csdn.net/jiaojian8063868/article/details/79295570
linux 加载 wxdial \ sudo apt-get install wvdial
sudo vi /etc/wvdial.conf %需要熟悉vi操作、自己在记事本中写完命令后再copy过来
linux vi 操作:百度 vi三种模式常用操作的学习
如下配置:(配置完成注意保存,vi操作--先键盘ESC--Shift+:wq 然后Enter 退出)
[Dialer Defaults]
Init1 = ATZ
Init2 = ATQ0 V1 E1 S0=0
Init3 = AT+CGDCONT=1,"IP","cmnet" %移动设置、联通、电信见下文
Modem Type = Analog Modem
Baud = 115200 # 波特率常见的是9600 115200 460800
New PPPD = yes
Modem = /dev/ttyUSB0
ISDN = 0
Phone = *98*1# 移动
Password = new #自行设置
Username = new
Auto DNS = on
拨号上网:
sudo wvdial Defaults
需要等待一会儿
此时可以通过ifconfig看到多出了个ppp0的网卡设备,并且已经获得IP地址
————————————————————————————————
sudo route %查看路由状态
如图1形式不需要修改。
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 0.0.0.0 0.0.0.0 U 0 0 0 ppp0
10.64.64.64 0.0.0.0 255.255.255.255 UH 0 0 0 ppp0
——————————————————————————————————
如图2形式需要修改:
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 0.0.0.0 0.0.0.0 U 0 0 0 eth0
10.64.64.64 0.0.0.0 255.255.255.255 UH 0 0 0 ppp0
——————————————————————————————————
修改后如图1即可
可以尝试ping内网和外网:(内外ping 通可能出现卡顿,没关系,直接关掉终端,ping 外网)
pi@raspberrypi:~ $ ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=0.522 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=0.470 ms
64 bytes from 192.168.1.1: icmp_seq=3 ttl=64 time=0.402 ms
64 bytes from 192.168.1.1: icmp_seq=4 ttl=64 time=0.449 ms
pi@raspberrypi:~ $ ping www.baidu.com
PING www.a.shifen.com (61.135.169.125) 56(84) bytes of data.
64 bytes from 61.135.169.125: icmp_seq=1 ttl=54 time=23.3 ms
64 bytes from 61.135.169.125: icmp_seq=2 ttl=54 time=27.0 ms
64 bytes from 61.135.169.125: icmp_seq=3 ttl=54 time=13.5 ms
64 bytes from 61.135.169.125: icmp_seq=4 ttl=54 time=23.1 ms
ping 通说明已经具有联网功能
上述配置结束,关闭终端,4G拨号上网
重新打开 输入:sudo wvdial Defaults
出现如下图:(不要关闭终端,此时已经能够上网了)
APN设置
移动: at+cgdcont=1,"ip","cmnet"
联通: at+cgdcont=1,"ip","3gnet"
电信: at+cgdcont=1,"ip","ctnet"
拨号
移动: *99***1#或*98*1#
联通: *99#
电信: #777
4、打开另一终端,运行python脚本,将数据传至OneNet
二、发送数据到OneNet
1 数据接收
树莓派3B的GPIO 14、15引脚分别于ZigBee 终端Tx、Rx 相连接,Python编程,分别每个10秒读取串口数据。
2 数据分割
考虑到读取的一帧数据,需要分割出各个数据节点数据,帧格式为:
ID:0001|BT: 34%|T:+23.6|ZD: 93%|PH: 2.1|DD:NoWater|
ID:0001|BT: 34%|T:+23.6|ZD: 93%|PH: 2.1|DD:2.04E-4|
帧开头表示为ID;0001表示设备标号;BT表示当前设备电池电量;T表示为当前水温度;
ZD表示为水质的浊度;PH表示为水质PH值;DD表示为水质电导率;
注:监测设备没有放入水中或者脱离水面,发送提醒信息NoWater。
3 数据发送
将各个节点数据按数据流发送,数据流格式:
values = {'datastreams': [{"id": "temperature", "datapoints": [{"at": CurTime.isoformat(), "value": temperature}]}
对json格式进行编码并设置HTTP访问。
下面代码为调试代码,仅供参考:
#!/usr/bin/python
# -*-coding: utf-8 -*-
#Time:201807231
#Function:save achieve and savecc2530 data
# wxdial online,and send data to OneNet
#Environment:Raspi3B、cc2530、4G模块、USB转TTL、4GSIM
#Runing OK
#author@New
# 多线程实现--实现由些问题,
import serial
import time
# from multiprocessing import Process, Queue
import urllib2
import json
import time
import datetime
APIKEY = 'xZcHvdq2gMptxrcWWxBXpRdg6RU=' # Project APIKEY
def read_serial(read_cc2530_data):
#初始化串口,读取cc2530 data
ser = serial.Serial(
port = '/dev/ttyS0',
#port = '/dev/usb,
baudrate = 115200,
parity = serial.PARITY_NONE,
stopbits = serial.STOPBITS_ONE,
bytesize = serial.EIGHTBITS,
timeout = 1
)
#读取串口数据并保存
counter1 = 111
# fileObject = open('/home/pi/Desktop/BirdVision/cc2530.txt', 'w')#注意:数据保存顺序及读取发送数据顺序
while True:
# for i in range(1,11):
print(counter1)
#x = ser.readline()
# 从串口读取cc2530数据
cc2530_data = ser.read(42)
print(cc2530_data)
read_cc2530_data.put(cc2530_data)
#fileObject = open('/home/pi/Desktop/BirdVision/cc2530.txt', 'w')
#for ip in ipTable:
#for data in x:
#将数据写入文件cc2530.txt or 或者数据不保证直接发送出去?
# fileObject.write(cc2530_data)
#fileObject.write('\n')
#print("Counter: %d" %x)
time.sleep(1)
#counter +=1
ser.close()
# fileObject.close()
#把read_serial data 给save_cc2530 保存到本地
def save_cc2530(read_cc2530_data):
sensor_data = read_cc2530_data.get()
# 通过管道获取cc2530 data
fileObject = open('/home/pi/Desktop/BirdVision/cc2530.txt', 'w') # 注意:数据保存顺序及读取发送数据顺序
fileObject.write(sensor_data)
fileObject.close()
"""
#把read_serial data 给get_cc2530 做数据类型转换
def get_cc2530():
#通过管道获取cc2530 data
# 打开文件
# file = open("/sys/class/thermal/thermal_zone0/temp")
# file = open("/home/pi/Desktop/BirdVision/cc2530.txt")
# 读取结果,并转换为浮点数
temp = float(file.read()) / 1000
# 关闭文件
# file.close()
# 向控制台打印结果
print"CPU温度值为: %.3f" % temp
# 返回温度值
return temp
"""
#将get_cc2530 换环后数据发送给OneNet
def http_put(read_cc2530_data):
# 通过管道获取cc2530 data
send_data = read_cc2530_data.get()
# temp = float(file.read()) / 1000
send_data = float(send_data) / 1000
# 向控制台打印结果
print("CPU温度值为: %.3f" % temp)
#数据分类
temperature = get_cc2530() # 获取CPU温度
#PH=
#
CurTime = datetime.datetime.now()
url = 'http://api.heclouds.com/devices/36680738/datapoints' # 36680738 -devices id
values = {'datastreams': [{"id": "temperature", "datapoints": [{"at": CurTime.isoformat(), "value": temperature}]}]}
print("当前ISO时间为: %s" % (CurTime.isoformat()))
print("上传的温度值为: %.3f" % temperature)
jdata = json.dumps(values) # 对json格式进行编码
# 打印json内容
print jdata
request = urllib2.Request(url, jdata)
request.add_header('api-key', APIKEY)
request.get_method = lambda: 'POST' # 设置HTTP访问
request = urllib2.urlopen(request)
if __name__ == "__main__":
# 父进程创建队列。,并传递给子进程
read_cc2530_data = Queue(3)
rs = Process(target=read_serial, args=(read_cc2530_data,))
rs.start()
sv = Process(target=save_cc2530, args=(read_cc2530_data,))
sv.start()
hp = Process(target=http_put, args=(read_cc2530_data,))
hp.start()
#
# pw.join()
# pr进程里是个死循环,无法等待期结束,只能强行结束
# pr.terminate()
while True:
pass
三、OneNet APi 配置及功能
OneNet目前支持大部分物联网协议,包括公网协议HTTP,MQTT,EDP等,还提供私有协议支持,方便开发者个人定制。
1、 OneNet创建产品
OneNET3.1更新后,一个重要的新特性就是在公有协议中,增加了一个全新的参数:注册码
API中,使用注册码作为参数,HTTP内容为相关设备属性,包括鉴权信息等,返回值为设备的api-key和设备id
2、 返回的设备API-KEY只对该设备有效,不能对其他设备进行操作;
3、 调用当allow_dup为true时,使用同一鉴权信息重复调用该API,可作为查询功能使用;当allow_dup为false时,当使用同一鉴权信息重复调用该API时,回返回错误信息。