树莓派作为它作为全新的物联网开发方式,其的家族越来越强大,从1A到当前的4B系统列为主,另外还有zero系列,计算模块,不久前推出了pi pico开发板,其价格比较低,适合各种人学习从儿童编程到开发者都可以使用,儿童编程可以使用switch进行编程,还可以使用switch控制LED灯开关(电路高低电平原理),它主推的python语言,同时支持java、c、c++语言,pi pico 使用micro python进行编程,它也可以使用c、c++进行编程。这有别与其它的arm开发板,大大降低我们作为java程序员的学习难度,我从三年前3B开始,无意间接触树莓派的,到现在已经有四年时间了,由于开发工作经常比较忙,但有空闲的时候我也想摆弄一下东西,从三年前第一次使用其demo程序把led灯控制和打开后,我兴奋的睡不着觉,四年前使用java代码使用树莓派3b实现了自动售卖机原理实践代码,近两个月由于工作比较空闲使用树莓派4b实现了家庭智能家具的控制,由于我家里使用开关都是射频(315开关)信号,而我的智能音响是小度(红外)——不到一百块,之前网购了一个万能红外转射频(一二百块)的转换器(现在已经被我淘汰掉),我考虑到如果在没有外网情况下就不能智能控制开关了,于是使用树莓派开发了一个一方面即可以红外转射频,又可以在局域网内通过浏览器访问树莓派作为服务器地址作为没有外网情况下可使用手机电脑控制的另一种选择方式,由于我本身做java开发,所以使用java语言开发,其它语言自行开发。现把我所做的经过和踩过的坑记录下来:
树莓派4b(它有4G版,运行速度较快),可作为开发工具,真正部署可以使用zero或zero w,
树莓派4B
树莓派zero w
串口转射频信号(315和433)
红外解码模块,为什么不使用红包模块——新版本不支持红外io模块读取,详见:https://www.cnblogs.com/punkrocker/p/11223137.html
ch340G USB TO TTL,这种推荐使用,我现在就是用的这种,不建议使用下种:
这种PL-2303HX芯片5个针的的usbl转TTL请不要购买,踩到坑里死都不知道怎么死的信号灯会闪亮,但中间数据时断时通,如果它不通也就罢了,但偶尔又会通。尤其是对于新手来说,不知道那方面毛病会把人整疯的。
请注意:由于串口转射频是无线不稳定性,建议使用的学习型射频开关模块,可以单键开,单键关的遥控模块,目前市面上大部分学习型的开关模块基本上都支持单开和单关,不适用仅单键开关控制(按一下开,再按同一个遥控键关闭,这样切换的),不是学习型的,不支持单键开、单键关的不支持使用,不是学习型的需要购买串口转射频模块公司的射频解码模块(解码射频遥控器的编码,便于通过串口转射频通过编码把其命令发送出去——上位机发送命令给下位机)。
原理图
使用语音,小度红外音箱把语音转化为红外信号,红外信号再经过红外解码器识别为16进制的byte数据,向上位机树莓派传送数据,树莓派接到信号数据,在库中查到相应的射频信号数据,再由串口转射频发送给灯的遥控开关模块,来控制开关的通路或断路,达到灯的开关与熄灭;如果人们使用手机或者电脑登陆树莓派的服务,访问网站点击按纽,即可发送相应的射频信号。
需要要说明的是,红外解码器是串口(ttl),串口转射频也是串口,由于树莓派板载仅一个串口,因此需要购一个usb转串口的(ttl)的,由于一个串口仅能对应一个设备(ttl或232通信),可以考虑485通信,由于我的ttl转485通信模块不够(要3个),因此没有使用此方案进行,后期看有时间可以考虑此方案。
代码已经存在github上,使用的是spring boot 框架,使用pi4j 1.3包。
<dependency>
<groupId>com.pi4j</groupId>
<artifactId>pi4j-core</artifactId>
<version>1.3</version>
</dependency>
物联网中,一切都要从上位机和下位机通信开始,这些对于从事物联网开发的人并不陌生,但是,我们做java网络应用开发的就不是很熟悉了,什么是上位机,什么是下位机,这些名词不多做解释,不明白自行百度,但它们间的通信都是串口通信的,使用UART(通用异步收发传输器)进行通信的,说白了上位机就像你的领导,下位机就是你,领导给你说一段话(16进制一串数字,代表的意义只有你们知道),其实就是一个命令,他说的你明白,然后你再执行他的命令要求就完了,至于你怎么执行的,或执行命令中遇到问题都要向上级通报(返回值),但如果你不明白这命令的意思,可以不理他,他可能给别人讲的,这就是上位机和下位机的通信。那我们就用电脑控制灯的开关吧。
认真阅读串口转射频说明书,如下:
其实大部分串口转射频无论315还是433信号使用的规则都是差不多的,我的是双频率的,仅的发射频率时选择即可,我是315信号,帧头和帧尾不能改变的,注意发射时间,一般看学习型开关需要多长的时间,正常情况下使用3秒以上,FD,01,03,01,01,01,60,DF,为一个开关的开灯键,根据开关模块说明书操作,把开关模块设置为常开学习使用电脑串口调试工具发送命令(注意不带逗号,选择十六进制——HEX)
特别注意:如果你的开关不具有常开
或常关
的功能——同一个遥控器按一下开就开了,按其它键就关了,或者制服控器上仅有开关两个按纽的话,这种一般情况下仅带自锁
功能——同一个遥控器无论多少按键,只有学习后的编码那个按纽是开的命令,其它按键都能把其关掉,因此这种在使用串口转射频模块时,要更换地址,而不是键值——的地址可以看作不同个的遥控器,键值仅看作是同一遥控器上的不同按键
。
根据串口模块的波特率设置(常用多是9600),发送给开关的常开学习,,蓝色数据表示返回值,即发送的去了帧头和帧尾及315和433区分码后的值,学习后测试一下,再次发送一次同样的命令开关打开,表示学习成功,再设置FD,01,03,01,02,01,60,DF(注意一般自己家里要地址改,不要区分键值,我区分键值导致发送命令时两个灯同时开或关——一个命令两个开关同时执行),看一下命令,再加入键值区分,6个16进制数字能模拟多少遥控器来?然后再学习其它灯的控制开关。
我们使用到红外解码器,它可以解码,但同时它又能够发射红外信号,查看其说明红外解码说明:
同样帧头和操作位是固定的,通过串口调试工具发送红外信号给小度,让其学习,小度学习完红外信号,等我们使用语言唤起开关灯命令时,红外解码器收到小度发送的红外信号妈是后三个两位16进制的数据——地址和键值。
红外开启信号 | 红外关闭信号 | 群组 | 名称 | 开关状态 | 开启射频信号 | 关闭射频信号 |
---|---|---|---|---|---|---|
FF0001 | FF0101 | 客厅 | 灯 | 1 | FD010101010160DF | FD010101020260DF |
FF0201 | FF0301 | 卫生间 | 灯 | 0 | FD010101030260DF | FD010101040260DF |
FF0401 | FF0501 | 卫生间 | 热水器 | 0 | FD010101050260DF | FD010101060260DF |
FF0601 | FF0701 | 厨房 | 灯 | 0 | FD010101070260DF | FD010101080260DF |
注意红外信号不加入帧头和操作位,这样便于数据查询(当然也可以)
到现在基本上系统设计架构就有了,呼唤小度开灯——小度发送红外信号给红外解码器,红外解码器收到信号,给数据树莓派,数据莓派通过查询库中对就的数据编码找到相对应的射频信号后转给串口转射频,发送射频信号即可以控制电路通路或断路。
树莓派4b安装自带有java,但是zero w不带java环境,需要自己安装,树莓派原版系统和乌班图系统一样操作。
我们使用的是2021-01-11-raspios-buster-armhf-lite
版本,它是不含桌面版,可以到其官网下载,初次玩树莓派的,官方建议烧录含桌版的(full
)。使用烧录软件balenaEtcher
:
然后点击flash时行烧录:
烧录完后,不要拨sd卡,加入wifi连接 ssid和密码,打开网站:
点击提交它会自动生成一个文件:wpa_supplicant.conf
打开为:
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
ap_scan=1
fast_reauth=1
country=HK
network={
#ssid="he"
ssid=6865
#psk="123456789"
psk=a13b170506e9b8b2756f52857f9b950e8c6d9acbe554943297af2ea7abcf6616
id_str="0"
priority=100
}
你可以不用此网站直接复制此代码修改ssid和psk(密码)为你的wifi密码,把文件wpa_supplicant.conf
复制到boot下:
同时还在要目录下建一个名字为ssh空文件(不是文件夹)
把卡插入树莓派,然后插电树莓派指示灯不闪,打开路由器看到树莓派连接上后的ip地址,无法打开路由器查看,可以使用局域网扫瞄工具,电脑或手机都有,我使用的是安卓局域网扫瞄工具扫瞄——要在同一局域网上扫瞄:
使用ssh工具连接树莓派,用户名:pi,默认密码:raspberry
桌面版设置不在此说明,仅使用ssh访问使用树莓派,linux(乌班图)命令不好的,请自补
ssh命令:
sudo raspi-config
一步步进行操作:
按上下键、tab制表符(光标位置选项切换)、空格(选择)、回车(确认)
按上下键,空格表示 选择到:
选择:en_GB.UTF-8``zh_CN GBK
和zh_CN UTF-8
三个后按tab键选择ok
,再次按tab选择OK,回车设定完毕
同样一步步选择:
选择亚洲:
tab制表符到ok到地区选择,在键盘英文情况下按s键——找上海(Shanghai)后确定,时间设置成功东八区
系统时间设置成功:
sudo apt-get update
至到系统从更新完成。
WiringPi是树莓派java开发工具类,里面有大量的demo测试案例,包含gpio控制和串口调试的类库,pi4j.com是其官方网站。
查看是否安装java环境(树莓派full完整版中有java环境):
java -version
看到没有安装java环境(注意老版本树莓派有些已经内置jdk1.7版本),如果没有java环境就别说wingpi,我们先去网站看一下:
说明WiringPi的1.3版本必须要jdk1.8以上版本,如果是老版系统,请先卸载java 1.7版本的,
我们直接使用命令安装opnejdk:
sudo apt-get purge openjdk-8-jre-headless
sudo apt-get install openjdk-8-jre-headless -y
sudo apt-get install openjdk-8-jre -y
我们直接使用命令安装java
安装完成后再次查看版本:
已经满足了WiringPi版本1.3的要求,接着安装WiringPi——树莓派的java开发工具类:
sudo apt-get remove wiringpi -y
sudo apt-get --yes install git-core gcc make
cd ~
git clone https://github.com/WiringPi/WiringPi --branch master --single-branch wiringpi
cd ~/wiringpi
sudo ./build
如果没有出现粉红字如下,表示wiringPi没有下载成功,github下载由于网络原因常常下载不成功:
ls
查看文件时:
表明wiringPi安装成功了。
树莓派系统4b和zero w都能安装redis,由于要使用数据库,我直接使用redis——原因我使用比较方便,如果你对sqlite数据库比较用的可以的话,建议使用SQLite数据库(前端的同事告诉我安卓系统开发经常使用到这个数据库),它比较量级。
sudo apt-get install redis-server -y
打开redis客户端:
redis-cli
能够进入redis客户端,并测试,表示安装成功,quit回车退出redis客户端。
1)从github下载程序并打包:
打包并上传到树莓派上:
本人使用的是Xshell工具,上传使用xFtp工具,
首先退到根目录下:
cd ~
在树莓派下,默认使用pi用户,其实路径为:
点周XFTP:
直上传打包文件:
sudo nano start.sh
树莓派使用nano编辑器比较好用,使用vi有时候出问题,现默认使用nano编辑器
复制代码进去:
#!/bin/sh
echo "项目正在启动中。。。。。。"
sudo mkdir logs
time=`date +%Y%m%d`
sudo touch logs/${time}.log
sudo nohup java -jar /home/pi/piHome-0.0.1-SNAPSHOT.jar >>logs/${time}.log /dev/null 2>&1 &
echo "项目启动了》》》》》》》》》》》》"
ctr+o回车保存,ctr+x退出nano编辑器
sudo chmod 777 start.sh
sudo ./start.sh
注意一定要加sudo,否则会出错
出现这些表示项目后台启动了,再看日志,目录在logs下
查看日志文件:
仅能使用cat命令
项目正常启动
设置参数数据(截止目前系统还不太完善,逐步升级,很多接口没有时间写,慢慢完善),把上面数据结构表,使用csv格式保存,使用postman把其数据能过接口写进系统中(使用swagger测试会出问题):
post请求,数据是csv格式的(utf-8编码)——excel保存的csv默认不是utf-8格式,请转换格式。返回状态码为200表示上传数据成功。
呼唤一下小度让开灯和关灯命令看一下。。。。。。。。。。。。。。
树莓派开机启动比较麻烦,尤其是新的版本更是麻烦,国内各大论坛都是以前的老版本,过时了,通过查找目前最简单的使用,详见:
使用crontab设置开机启动:
crontab -e
第一次使用crontab时要绑定文本编辑工具,我习惯nano,其它习惯自行选择
加入启动命令——为了保险期间写绝对路径啊!
sudo /home/pi/start.sh
重启树莓派,项目也启动了。
sudo reboot
使用手机或电脑访问路径是ip+端口号/home
花了近半个多月的时间终于把系统写完并开发完成了,但里面还有很多要完善的,无论是代码还是需要求,比如加入一个开机会响的模块(程序运行完成会响两声,信号成功发送响一下)等需求都可以,试用485通信仅板载串口即可(不使用usb to ttl),更可以方便加入其它485模块,比较电表及温湿度等。。。
前天在中关村中发电子市场买到了蜂鸣器(5v),仅有两个插头一个正级一个负级。
接入树莓派gpio_01口(第18针和19针)——gpio口与其上面排针对应关系
当io口为高电平时,它的电压为3.3V,5V蜂鸣器可以响,原以为3.3v电压低响声不是太大,但当我把蜂响器上面的贴纸撕开,响声刺耳。
蜂鸣器代码:
@Service
public class Gpio {
/**
* 蜂鸣器响应声音
* @param num 响几声
* @throws InterruptedException
*/
public void sendSound(int num) {
// 创建gpio控制器——实用了单例模式的工厂类
final GpioController gpio = GpioFactory.getInstance();
// gpio引脚#01作为输出引脚并打开——RaspiPin.GPIO_01为第18针
final GpioPinDigitalOutput pin = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_01, "sound", PinState.LOW);
for (int i = 0; i < num; i++) {
//声音100毫秒短催较好
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
//high为高电平
pin.high();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
//低电平
pin.low();
}
//pin关闭,设置状态为low
pin.setShutdownOptions(true, PinState.LOW);
}
}