Vcancy's Home

电影|阅读|记录


  • 首页

  • 标签

  • 分类

  • 归档

树莓派与Arduino串口通讯获取DH11温度湿度

发表于 2018-05-26 | 分类于 开源硬件

本文记录通过树莓派USB连接Arduino进行通讯的过程。
实现的功能:
Arduino上连接机智云GoKit开发套件,获取DH11温度与湿度返回给树莓派。

原材料:

树莓派b3+
Arduino Uno R3

Arduino代码编写

首先我们需要调用DHT获取温度湿度数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <DHT.h>

#define DHTPIN 3
#define DHTTYPE DHT11

DHT dht(DHTPIN, DHTTYPE);

void setup() {
// put your setup code here, to run once:

Serial.begin(9600);

dht.begin();

Serial.println("Hi Vcancy. Arduino is running...");

}

/**
Arduino loop
@param none
@return none
*/
char target[] = "GET TH";

void loop() {
// 每次等待2秒后再输出(这里必须等大于1秒,不然不准确)
delay(2000);
// 从串口读数据并判断
if (Serial.available() > 0) {
if ( Serial.find(target)) {
// 获取温度或者湿度需要250毫秒!
// 传感器获取到的温度和湿度可能是2秒内的

float h = dht.readHumidity();// 读取当前的湿度

float t = dht.readTemperature(); // 读取当前的温度,单位C

float f = dht.readTemperature(true);//读取当前的温度,单位F

// 如果读取失败则退出,再读取一次
if (isnan(h) || isnan(t) || isnan(f)) {
Serial.println("Failed to read from DHT sensor!");
return;
}

// 读取体感温度,单位F
float hif = dht.computeHeatIndex(f, h);
// 读取体感温度,单位C
float hic = dht.computeHeatIndex(t, h, false);

Serial.print("湿度: ");
Serial.print(h);
Serial.print(" %\t");
Serial.print("温度: ");
Serial.print(t);
Serial.print(" *C ");
Serial.print(f);
Serial.print(" *F\t");
Serial.print("体感温度: ");
Serial.print(hic);
Serial.print(" *C ");
Serial.print(hif);
Serial.println(" *F");
}
}

}

串口调试:输入 “GET TH”,串口返回数据

image.png

树莓派

树莓派USB连接到Arduino

ls /dev

找到Arduino的串口地址:/dev/ttyUSB0

编写一个python程序,调用串口获取数据。

安装pyserial,串口库
pip install pyserial

编写一个python脚本

1
2
3
4
5
6
7
8
9
10
11
import serial
ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)

try:
while 1:
ser.write(b"GET TH")
response = str(ser.readline().decode())
if response.startswith('湿度:'):
print(response.strip('\n'))
except KeyboardInterrupt:
ser.close()

image.png

Hbase之happybase[TTransportException Broken pipe]分析二

发表于 2018-05-24

前一篇介绍了使用happybase连接池未关闭连接引起Broken pipe异常

这篇继续分析,当每次我们使用完连接后手动close依然会存在一个问题。

通常我们使用连接池会在全局变量中实例话一个pool对象,后续再通过pool获取连接进行后续操作。

当我们创建连接池对象后,happybase会根据size创建多个connection实例到队列中,同时会将第一个connection连接打开,注释中提到之所以打开一个连接是为了确保如果出现一些找不到主机之类的错误能第一时间发现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class ConnectionPool(object):
def __init__(self, size, **kwargs):
if not isinstance(size, int):
raise TypeError("Pool 'size' arg must be an integer")

if not size > 0:
raise ValueError("Pool 'size' arg must be greater than zero")

logger.debug(
"Initializing connection pool with %d connections", size)

self._lock = threading.Lock()
self._queue = queue.LifoQueue(maxsize=size)
self._thread_connections = threading.local()

connection_kwargs = kwargs
connection_kwargs['autoconnect'] = False

for i in range(size):
connection = Connection(**connection_kwargs)
self._queue.put(connection)

# The first connection is made immediately so that trivial
# mistakes like unresolvable host names are raised immediately.
# Subsequent connections are connected lazily.
with self.connection():
pass

但是问题就出现在这里,当我们初始化一个连接池后如果没有立即使用,那么第一个连接池中的连接会出现被断开的情况,那么接下来拿到这个连接去操作都会出现broken pipe异常。

这里只探讨对于这个问题可能的解决方法

  1. 外部使用的时候为方法增加异常重试,连接池中出现异常本身会重置连接

2.第一次不打开连接,如#147处理方案
这个解决新家了一个autoconnect的参数,当autoconnect为False就不执行第一个连接。但是在connection的异常处理中还是会打开一个连接,这样也会出现同样的问题,所以这里也应该加上。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
try:
# Open connection, because connections are opened lazily.
# This is a no-op for connections that are already open.
connection.open()

# Return value from the context manager's __enter__()
yield connection

connection.close()

except (TException, socket.error):
# Refresh the underlying Thrift client if an exception
# occurred in the Thrift layer, since we don't know whether
# the connection is still usable.
logger.info("Replacing tainted pool connection")
connection._refresh_thrift_client()
if autoconnect:
connection.open()

3.和1类似,只是在 happybase中处理网络异常重置连接后重试#184

Hbase之happybase[TTransportException Broken pipe]分析

发表于 2018-05-23 | 分类于 大数据

Hbase提供Thrift实现多语言的支持,python的happybase就是其中一个实现。

最近在使用happybase出现TTransportException和Broken pipe的异常,记录一下解决方案。

环境:
python:3.6.2
happbase:1.1.0
hbase:1.2.4

现象:要每几分钟左右往HBase插入一条数据,但是,在大约1分钟过后,被服务器断开了连接,然后再尝试插入的时候,抛出broken pipe.

复现代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import happybase
import time

def put(pool,data):
with pool.connection() as conn:
table = conn.table('Log')
row_key = str(int(time.time())) + '000001'
data = data
table.put(row_key, data)

if __name__ == '__main__':
pool = happybase.ConnectionPool(size=3, host='127.0.0.1', table_prefix='TL')
put(pool,{})
time.sleep(60) # 模拟间隔时间
put(pool, {})

分析:Broken pipe往往是因为客户端和服务器的TCP连接断开引起的。

通过google发现hbase thrift server有一个超时的配置hbase.thrift.server.socket.read.timeout,当客户端和服务器的连接超过该值没有收到消息的时候,该连接会被断开,默认值为60秒,正好跟本次现象发生的场景一致,每隔60秒连接断开。参考[HBASE-14926]https://issues.apache.org/jira/browse/HBASE-14926

查看happybase连接池相关的代码发现在with完成后connection并没有close,直接返回到连接池当中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@contextlib.contextmanager
def connection(self, timeout=None):
connection = getattr(self._thread_connections, 'current', None)
return_after_use = False
if connection is None:
return_after_use = True
connection = self._acquire_connection(timeout)
with self._lock:
self._thread_connections.current = connection
try:
connection.open()
yield connection
except (TException, socket.error):
logger.info("Replacing tainted pool connection")
connection._refresh_thrift_client()
connection.open()
raise
finally:
if return_after_use:
del self._thread_connections.current
self._return_connection(connection)

而问题就出现在这里,返回到连接池中的connection在1分钟后没有使用,被断开了连接,当下一次再拿这个connection去请求资源就会出现Broken pipe的异常。

接下来就到了解决问题的时候,一般来讲可以有两个解决方案:

1.配置hbase.thrift.server.socket.read.timeout,增加超时时间

2.在使用connection后关闭连接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import happybase
import time

def put(pool,data):
with pool.connection() as conn:
table = conn.table('Log')
row_key = str(int(time.time())) + '000001'
data = data
table.put(row_key, data)
conn.close() # 关闭连接

if __name__ == '__main__':
pool = happybase.ConnectionPool(size=3, host='127.0.0.1', table_prefix='TL')
put(pool,{})
time.sleep(60) # 模拟间隔时间
put(pool, {})

docker 常用命令

发表于 2018-05-19 | 分类于 备忘录

查看

1
2
3
4
5
6
7
docker ps 表示查看当前正在运行的容器 

-a,查看所有容器包括停止状态的容器

-l,查看最新创建的容器

-n=x,查看最后创建的x个容器

查看容器详细信息

docker inspect 容器名或容器ID

进入容器

docker exec -it 775c7c9ee1e1 /bin/bash

删除 :不能删除一个正在运行的容器,必须先docker stop或者docker kill后才能删除

docker rm 容器名或容器ID

加-f这个参数我们也是可以删除一个正在运行的容器的

删除所有容器

docker rm `docker ps -a -q` 

容器重命名

docker rename 容器名或容器ID

更新容器启动参数

docker update --restart=no 容器名或容器ID

docker 从容器里面拷文件到宿主机

docker cp 容器名:要拷贝的文件在容器里面的路径       要拷贝到宿主机的相应路径

docker 从宿主机拷文件到容器里面

docker cp 要拷贝的文件路径 容器名:要拷贝到容器里面对应的路径```

plex X-Plex-Token 获取

发表于 2018-05-19 | 分类于 智能家居

1.登录plex web:https://www.plex.tv/

2.进入plex desktop

image.png

3.开启Chrome开发者工具,刷新页面查看url

image.png

树莓派debian 9 stretch 替换apt-get国内源 安装docker 18.03 ce

发表于 2018-05-19 | 分类于 树莓派

配置apt

nano```
1
2
3
4

将文件里的默认的官方软件源用# 注释掉,添加以下:

```deb http://mirrors.ustc.edu.cn/raspbian/raspbian/ stretch main contrib non-free rpi
nanolink
1
2
3
4

将文件里的默认的官方软件源用# 注释掉,添加以下:

```deb http://mirrors.ustc.edu.cn/archive.raspberrypi.org/ stretch main ui

添加docker apt源

1
2
3
4
5
6

echo "deb [arch=armhf] https://download.docker.com/linux/debian \

$(lsb_release -cs) stable" | \

sudo tee /etc/apt/sources.list.d/docker.list

更新apt

update```
1
2
3
4

### 安装docker

```sudo apt-get install docker-ce

docker配置国内镜像

在 /etc/docker/daemon.json 中写入如下内容(如果文件不存在请新建该文件)

1
2
3
4
5
6
7
8
9
10

{

"registry-mirrors": [

"https://registry.docker-cn.com"

]

}

参考

https://docs.docker.com/install/linux/docker-ce/debian/#install-docker-ce-1

https://yeasy.gitbooks.io/docker_practice/content/install/mirror.html

树莓派docker swarm集群部署 portainer 管理实践

发表于 2018-05-19 | 分类于 树莓派

portainer

介绍

Swarm 在 Docker 1.12 版本之前属于一个独立的项目,在 Docker 1.12 版本发布之后,该项目合并到了 Docker 中,成为 Docker 的一个子命令。目前,Swarm 是 Docker 社区提供的唯一一个原生支持 Docker 集群管理的工具。它可以把多个 Docker 主机组成的系统转换为单一的虚拟 Docker 主机,使得容器可以组成跨主机的子网网络。

Swarm 是目前 Docker 官方唯一指定(绑定)的集群管理工具。Docker 1.12 内嵌了 swarm mode 集群管理模式。

阅读全文 »

Arduino+Blynk 第一个Demo

发表于 2018-05-17 | 分类于 Arduino

Arduino起步项目:通过Blynk应用程序控制板载LED

需要:

Arduino UNO

Blynk

第一步

  1. 下载Blynk并注册账号登录app

image.png

  1. 创建一个项目,创建成功后Blynk会发送一封包含Auth Token的邮件

image.png

image.png

  1. 在app上添加widgets

image.png

  1. 在本例子中我添加一个按钮,设置为Switch开关,同时选择D13作为控制点
    image.png

第二步

  1. 下载Blynk Libraries https://github.com/blynkkk/blynk-library/releases/latest

解压并复制到Arduino IDE的Libraries目录

Windows: File → Preferences
Mac OS: Arduino → Preferences

image.png

  1. 打开https://examples.blynk.cc/ 网页,选择Arduino UNO,选择Serial or USB 串口共享电脑的网络连接

image.png

  1. 复制代码到IDE并烧录到 Arduino Uno
    image.png

第三步

  1. 打开终端进入到Libraries的Blynk路径下的scripts目录

image.png

  1. 执行./blynk-ser.sh 提示需要安装socat

image.png

  1. 再次执行脚本,这里注意:我执行后没有显示串口的地址,可以通过-c参数手动指定
    1
    ./blynk-ser.sh -c /dev/cu.wchusbserial1420

/dev/cu.wchusbserial1420可以从Arduino IDE中查看

image.png

image.png

image.png

  1. 最后打开Blynk app,点击运行,就可以通过button按钮控制Arduino Uno的IDE了
    image.png

[SqlAlchemy实践]seesion线程安全管理

发表于 2018-05-15 | 分类于 python

普通情况下session使用情况如下

1
2
3
4
5
6
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

engine = create_engine('sqlite:///:memory:', echo=True)
DB_Session = sessionmaker(bind=engine)
session = DB_Session()

这种在单线程场景是没有问题的,但是在多线程场景下就不适用了。

我们可以通过scoped_session来实现多线程场景下的应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from sqlalchemy.orm import scoped_session
from sqlalchemy.orm import sessionmaker
from contextlib import contextmanager
from sqlalchemy import create_engine, MetaData

# 线程安全session
engine = create_engine("mysql+pymysql://root:123456@127.0.0.1:3306/mydb?charset=utf8")

session_factory = sessionmaker(bind=engine)
sc_session = scoped_session(session_factory)

@contextmanager
def session_scope():
"""Provide a transactional scope around a series of operations."""
session = sc_session()
try:
yield session
except:
raise
finally:
sc_session.remove()

MySQL数据库规范

发表于 2018-05-10 | 分类于 数据库

目录

基础规范
命名规范
表设计规范

阅读全文 »
123…7
Vcancy

Vcancy

TO BE OR NOT TO BE.

67 日志
15 分类
36 标签
GitHub E-Mail
© 2021 Vcancy
由 Hexo 强力驱动
|
主题 — NexT.Mist v6.0.6