作为制造者社区的成员,我们一直在寻找创造性的方式来使用硬件和软件。 这次, Patrick Lima和我决定我们想使用Arduino开发板扩展Raspberry Pi的端口,以便我们可以访问更多功能和端口并为设备添加一层保护。 有许多方法可以使用此设置,例如,构建跟随太阳的太阳能电池板,家庭气象站,操纵杆交互等等。

我们决定从构建一个仪表盘开始,该仪表盘允许以下串行端口交互:

  • 控制三个LED以打开和关闭它们
  • 控制三个LED调整其光强度
  • 识别正在使用的端口
  • 在操纵杆上显示输入动作
  • 测量温度

我们还想在一个漂亮的用户界面(UI)中显示端口,硬件和传感器之间的所有交互,如下所示:

(Bruno Muniz, CC BY-SA 4.0 )

您可以使用本文中的概念来构建使用许多不同组件的许多不同项目。 您的想象力是极限!

1.开始

(Bruno Muniz, CC BY-SA 4.0 )

第一步是将Raspberry Pi的端口扩展为也使用Arduino端口。 使用Linux ARM的本机串行通信实现可以实现这一点,该实现使您能够使用Arduino的数字,模拟和脉宽调制(PWM)端口在Raspberry Pi上运行应用程序。

该项目使用TotalCross (一种用于构建嵌入式设备的UI的开源软件开发套件)来通过终端执行外部应用程序并使用本机串行通信。 您可以使用两个类来实现此目的: Runtime.exec和PortConnector 。 它们代表执行这些操作的不同方法,因此在本教程中我们将展示如何使用这两种方法,您可以决定哪种方法最适合您。

要启动该项目,您需要:

  • 1树莓派3
  • 1个Arduino Uno
  • 3个LED
  • 2个电阻介于1K和2.2K欧姆之间
  • 1个按钮
  • 1个电位计,介于1K和50K欧姆之间
  • 1个原型板(又名面包板)
  • 跳线

2.设置Arduino

创建通信协议以接收消息,处理消息,执行请求并在Raspberry Pi和Arduino之间发送响应。 这是在Arduino上完成的。

2.1定义消息格式

每条收到的消息将具有以下格式:

  • 指示的功能称为
  • 使用的端口
  • 字符分隔符(如果需要)
  • 需要发送的值
  • 消息结束的指示

下表列出了具有相应功能,示例值和示例说明的字符列表。 本示例中使用的字符选择是任意的,可以随时更改。

性格 功能 示例说明
* 指令结束 -- --
, 分隔器 -- --
# 设置模式 #8,0 * 引脚8输入模式
< 设定数字值 <1,0 * 将引脚1设置为低电平
> 获得数字价值 > 13 * 获取值针13
+ 获取PWM值 + 6,250 * 设置引脚6的值250
- 获得类比价值 -14 * 获取值引脚A0

2.2源代码

以下源代码实现了上面指定的通信协议。 必须将其发送到Arduino,以便它可以解释和执行消息的命令:

void setup ( ) {
Serial. begin ( 9600 ) ;
Serial. println ( "Connected" ) ;
Serial. println ( "Waiting command..." ) ;
}

void loop ( ) {
String text = "" ;
char character ;
String pin = "" ;
String value = "0" ;
char separator = '.' ;
char inst = '.' ;

while ( Serial. available ( ) ) { // verify RX is getting data
delay ( 10 ) ;
character = Serial. read ( ) ;
if ( character == '*' ) {
action ( inst , pin , value ) ;
break ;
}
else {
text. concat ( character ) ; }

if ( character == ',' ) {
separator = character ;

if ( inst == '.' ) {
inst = character ; }
else if ( separator != ',' && character != inst ) {
pin. concat ( character ) ; }
else if ( character != separator && character != inst ) {
value. concat ( character ) ; }
}
}

void action ( char instruction , String pin , String value ) {
if ( instruction == '#' ) { //pinMode
pinMode ( pin. toInt ( ) , value. toInt ( ) ) ;
}

if ( instruction == '<' ) { //digitalWrite
digitalWrite ( pin. toInt ( ) , value. toInt ( ) ) ;
}

if ( instruction == '>' ) { //digitalRead
String aux = pin + ':' + String ( digitalRead ( pin. toInt ( ) ) ) ;
Serial. println ( aux ) ;
}

if ( instruction == '+' ) { // analogWrite = PWM
analogWrite ( pin. toInt ( ) , value. toInt ( ) ) ;
}

if ( instruction == '-' ) { // analogRead
String aux = pin + ':' + String ( analogRead ( pin. toInt ( ) ) ) ;
Serial. println ( aux ) ;
}
}


2.3制作电子产品

定义您需要测试以检查与Arduino的通信并确保输入和输出按预期响应的内容:

  • LED以正逻辑连接。 通过电阻连接到GND引脚,并通过数字端口I / O 2和PWM 3激活它。
  • 该按钮具有连接到数字端口I / O 4的下拉电阻,如果未按下则发送信号0,如果按下则发送信号1。
  • 电位计的中心引脚连接到模拟输入A0,其中一个侧面引脚位于正极,而另一个侧面引脚位于负极。

(Bruno Muniz, CC BY-SA 4.0 )

2.4测试通讯

将第2.2节中的代码发送到Arduino。 发送以下命令,打开串行监视器并检查通讯协议:

#2,1*<2,1*>2*
#3,1*+3,10*
#4,0*>4*
#14,0*-14*

这应该是串行监视器中的结果:

(Bruno Muniz, CC BY-SA 4.0 )

设备上的一个LED应该以最大强度点亮,而另一个应以较低强度点亮。

(Bruno Muniz, CC BY-SA 4.0 )

发送读数命令时,按下按钮并更改电位计的位置将显示不同的值。 例如,将电位计转到正极,然后按按钮。 在仍然按下按钮的情况下,发送命令:

> 4 *
- 14 *

应该出现两行:

(Bruno Muniz, CC BY-SA 4.0 )

3.设置Raspberry Pi

使用Raspberry Pi通过终端使用cat命令读取条目,并使用echo命令发送消息,通过终端访问串行端口。

3.1进行串行测试

将Arduino连接到Raspberry Pi的USB端口之一,打开终端,然后执行以下命令:

 cat / dev / ttyUSB0 9600 

这将启动与Arduino的连接并显示返回串行的内容。

(Bruno Muniz, CC BY-SA 4.0 )

要测试发送命令,请打开一个新的终端窗口(保持前一个打开),然后发送以下命令:

 echo "command" > / dev / ttyUSB0 9600 

您可以发送与2.4节相同的命令。

您应该在第一个终端中看到反馈以及在2.4节中得到的相同结果:

(Bruno Muniz, CC BY-SA 4.0 )

4.创建图形用户界面

第一部分使用两个UI组件:一个列表框和一个编辑。 它们在Raspberry Pi和Arduino之间建立连接,并测试一切是否按预期工作。

模拟您在其中放置命令的终端并观察答案:

  • 编辑用于发送消息。 将其放置在底部,其填充宽度可将组件扩展到屏幕的整个宽度。
  • 列表框用于显示结果,例如在终端中。 将其添加到TOP位置(从左端开始),其宽度等于Edit,而FIT高度则垂直占据未被Edit填充的所有空间。
package com.totalcross.sample.serial ;

import totalcross.sys.Settings ;
import totalcross.ui.Edit ;
import totalcross.ui.ListBox ;
import totalcross.ui.MainWindow ;
import totalcross.ui.gfx.Color ;

public class SerialSample extends MainWindow {
ListBox Output ;
Edit Input ;
public SerialSample ( ) {
setUIStyle ( Settings. MATERIAL_UI ) ;
}

@Override
public void initUI ( ) {
Input = new Edit ( ) ;
add ( Input, LEFT, BOTTOM, FILL, PREFERRED ) ;
Output = new ListBox ( ) ;
Output. setBackForeColors ( Color . BLACK , Color . WHITE ) ;
add ( Output, LEFT, TOP, FILL, FIT ) ;
}
}


它看起来应该像这样:

(Bruno Muniz, CC BY-SA 4.0 )

5.设置串行通讯

如上所述,有两种设置串行通信的方法:Runtime.exec和PortConnector。

5.1选项1:使用Runtime.exec

java.lang.Runtime类允许应用程序与其运行环境一起创建连接接口。 它允许程序使用Raspberry Pi的本机串行通信。

使用与第3.1节中使用的命令相同的命令,但现在使用UI上的“编辑”组件将命令发送到设备。

阅读序列

应用程序必须不断读取序列号,如果返回值,请使用线程将其添加到列表框中。 线程是在后台处理进程而不阻止用户交互的一种好方法。

以下代码在此线程上创建一个新进程,该进程执行cat命令,测试串行,并启动无限循环以检查是否接收到新消息。 如果收到内容,则该值将添加到“列表框”组件的下一行。 只要应用程序正在运行,此过程就将继续运行:

new Thread ( ) {
@Override
public void run ( ) {
try {
Process Runexec2 = Runtime . getRuntime ( ) . exec ( "cat /dev/ttyUSB0 9600 \n " ) ;
LineReader lineReader = new LineReader ( Stream. asStream ( Runexec2. getInputStream ( ) ) ) ;
String input ;

while ( true ) {
if ( ( input = lineReader. readLine ( ) ) != null ) {
Output. add ( input ) ;
Output. selectLast ( ) ;
Output. repaintNow ( ) ;
}
}
} catch ( IOException ioe ) {
ioe. printStackTrace ( ) ;
}
}
} . start ( ) ;
}


发送命令

发送命令是一个简单的过程。 每当您在“编辑”组件上按Enter时 ,它就会发生。

要将命令转发到设备,如3.1节所示,您必须实例化一个新终端。 为此,Runtime类必须在Linux上执行sh命令:

try {
Runexec = Runtime . getRuntime ( ) . exec ( "sh" ) . getOutputStream ( )        } catch ( IOException ioe ) {
ioe. printStackTrace ( ) ;
}

用户在“编辑”中编写命令并按Enter后 ,应用程序将触发一个事件,该事件以“编辑”中指示的值执行echo命令:

Input. addKeyListener ( new KeyListener ( ) {

@Override
public void specialkeyPressed ( KeyEvent e ) {
if ( e. key == SpecialKeys. ENTER ) {
String s = Input. getText ( ) ;
Input. clear ( ) ;
try {
Runexec. write ( ( "echo \" " + s + " \" > /dev/ttyUSB0 9600 \n " ) . getBytes ( ) ) ;
} catch ( IOException ioe ) {
ioe. printStackTrace ( ) ;
}
}
}

@Override
public void keyPressed ( KeyEvent e ) { } //auto-generate code
@Override
public void actionkeyPressed ( KeyEvent e ) { } //auto-generate code
} ) ;


在连接了Arduino的Raspberry Pi上运行应用程序,然后发送命令进行测试。 结果应为:

(Bruno Muniz, CC BY-SA 4.0 )

Runtime.exec源代码

以下是解释所有部分的源代码。 它包括将在第31行读取串行的线程和将在第55行发送命令的KeyListener :

package com.totalcross.sample.serial ;
import totalcross.ui.MainWindow ;
import totalcross.ui.event.KeyEvent ;
import totalcross.ui.event.KeyListener ;
import totalcross.ui.gfx.Color ;
import totalcross.ui.Edit ;
import totalcross.ui.ListBox ;
import java.io.IOException ;
import java.io.OutputStream ;
import totalcross.io.LineReader ;
import totalcross.io.Stream ;
import totalcross.sys.Settings ;
import totalcross.sys.SpecialKeys ;

public class SerialSample extends MainWindow {
OutputStream Runexec ;
ListBox Output ;

public SerialSample ( ) {
setUIStyle ( Settings. MATERIAL_UI ) ;
}

@Override
public void initUI ( ) {
Edit Input = new Edit ( ) ;
add ( Input, LEFT, BOTTOM, FILL, PREFERRED ) ;
Output = new ListBox ( ) ;
Output. setBackForeColors ( Color . BLACK , Color . WHITE ) ;
add ( Output, LEFT, TOP, FILL, FIT ) ;
new Thread ( ) {
@Override
public void run ( ) {
try {
Process Runexec2 = Runtime . getRuntime ( ) . exec ( "cat /dev/ttyUSB0 9600 \n " ) ;
LineReader lineReader = new
LineReader ( Stream. asStream ( Runexec2. getInputStream ( ) ) ) ;
String input ;

while ( true ) {
if ( ( input = lineReader. readLine ( ) ) != null ) {
Output. add ( input ) ;
Output. selectLast ( ) ;
Output. repaintNow ( ) ;
}
}

} catch ( IOException ioe ) {
ioe. printStackTrace ( ) ;
}
}
} . start ( ) ;

try {
Runexec = Runtime . getRuntime ( ) . exec ( "sh" ) . getOutputStream ( ) ;
} catch ( IOException ioe ) {
ioe. printStackTrace ( ) ;
}

Input. addKeyListener ( new KeyListener ( ) {
@Override
public void specialkeyPressed ( KeyEvent e ) {
if ( e. key == SpecialKeys. ENTER ) {
String s = Input. getText ( ) ;
Input. clear ( ) ;
try {
Runexec. write ( ( "echo \" " + s + " \" > /dev/ttyUSB0 9600 \n " ) . getBytes ( ) ) ;
} catch ( IOException ioe ) {
ioe. printStackTrace ( ) ;
}
}
}

@Override
public void keyPressed ( KeyEvent e ) {
}
@Override
public void actionkeyPressed ( KeyEvent e ) {
}
} ) ;
}
}


5.2选项2:使用PortConnector

PortConnector专门用于串行通信。 如果要遵循原始示例,则可以跳过本节,因为此处的目的是显示另一种更简单的串行操作方法。

更改原始源代码以与PortConnector一起使用:

package com.totalcross.sample.serial ;
import totalcross.io.LineReader ;
import totalcross.io.device.PortConnector ;
import totalcross.sys.Settings ;
import totalcross.sys.SpecialKeys ;
import totalcross.ui.Edit ;
import totalcross.ui.ListBox ;
import totalcross.ui.MainWindow ;
import totalcross.ui.event.KeyEvent ;
import totalcross.ui.event.KeyListener ;
import totalcross.ui.gfx.Color ;

public class SerialSample extends MainWindow {
PortConnector pc ;
ListBox Output ;

public SerialSample ( ) {
setUIStyle ( Settings. MATERIAL_UI ) ;
}

@Override
public void initUI ( ) {
Edit Input = new Edit ( ) ;
add ( Input, LEFT, BOTTOM, FILL, PREFERRED ) ;
Output = new ListBox ( ) ;
Output. setBackForeColors ( Color . BLACK , Color . WHITE ) ;
add ( Output, LEFT, TOP, FILL, FIT ) ;
new Thread ( ) {
@Override
public void run ( ) {
try {
pc = new PortConnector ( PortConnector. USB , 9600 ) ;
LineReader lineReader = new LineReader ( pc ) ;
String input ;
while ( true ) {
if ( ( input = lineReader. readLine ( ) ) != null ) {
Output. add ( input ) ;
Output. selectLast ( ) ;
Output. repaintNow ( ) ;
}
}
} catch ( totalcross. io . IOException ioe ) {
ioe. printStackTrace ( ) ;
}
}
} . start ( ) ;
Input. addKeyListener ( new KeyListener ( ) {
@Override
public void specialkeyPressed ( KeyEvent e ) {
if ( e. key == SpecialKeys. ENTER ) {
String s = Input. getText ( ) ;
Input. clear ( ) ;
try {
pc. writeBytes ( s ) ;
} catch ( totalcross. io . IOException ioe ) {
ioe. printStackTrace ( ) ;
}
}
}

@Override
public void keyPressed ( KeyEvent e ) {
}

@Override
public void actionkeyPressed ( KeyEvent e ) {
}
} ) ;
}
}


您可以在项目存储库中找到所有代码。

6.后续步骤

本文介绍如何通过使用Runtime或PortConnector类将Raspberry Pi串行端口与Java一起使用。 您还可以用其他语言调用外部文件,并创建无数其他项目,例如用于水族箱的水质监测系统,该水族箱可以通过模拟输入进行温度测量,或者可以控制温度和湿度的鸡笼和伺服电机来旋转卵。

以后的文章将使用PortConnector实现(因为它专注于串行连接)来完成与所有传感器的通信。 它还将添加一个数字输入并完成UI。

以下是一些参考资料,供您阅读:

  • TotalCross入门
  • TotalCross PortConnector类
  • 使用TotalCross运行C ++应用程序
  • VSCode TotalCross项目扩展插件

连接Arduino和Raspberry Pi后,请在下面留下您的评论。 我们希望阅读它们!

翻译自: https://opensource.com/article/20/7/arduino-raspberry-pi

通过Arduino端口扩展Raspberry Pi相关推荐

  1. Arduino vs Raspberry Pi vs BeagleBone

    软硬件整合是今年一再被提及的话题,如今我们也可以看到不少硬件创业的成功案例,比如Jawbone Up.Pebble手表等可穿戴设备,它们可与用户的手机同步,实现软件与硬件的结合.通过硬件创新与软件整合 ...

  2. Raspberry Pi, UPNP(二), Scala

    Raspberry Pi 概述 树莓派(Raspberry Pi)在极客领域可谓大名鼎鼎,它的官网是: https://www.raspberrypi.org/ 从型号来看,它可以分为三大类型: 1) ...

  3. raspberry pi_许多Raspberry Pi项目-您怎么不爱小型计算机?

    raspberry pi How can you not love a tiny computer? I posted about Top 10 Raspberry Pi Myths and Trut ...

  4. 我应该买Arduino还是Raspberry Pi?

    我花了很多时间参加诸如Maker Faires之类的会议和活动,并且与人合着了有关Raspberry Pi的书 ,我花了很多时间与人们谈论小型电子产品和开放硬件等问题. 我可能最常听到的问题是:&qu ...

  5. Raspberry Pi 与Arduino SPI通信

    本教程介绍了使用SPI(串行外围设备接口总线)进行Raspberry Pi与Arduino通讯和控制的基本框架. SPI代表了一种非常完善的芯片间通信方法,该方法在两种设备的硬件中均实现. 在这里,我 ...

  6. raspberry pi_PocketCHIP与Raspberry Pi相比如何?

    raspberry pi 当Raspberry Pi进入技术界时,它产生了巨大的影响. 无论如何,它都不是第一台小型计算机-Chumby,PogoPlug以及其他可在芯片上进行黑客攻击的系统都在出现- ...

  7. 龙邱树莓派Raspberry Pi 扩展板电路及其相关实验

    ▲ 树莓派与其扩展板 文章目录 ▌01 树莓派车模扩展板 1.车模的整体配置 2.扩展板 3.树莓派IO口管脚功能 (1)树莓派接口定义 (2)扩展板上各功能接口定义 ▌02 扩展板子模块 1.树莓派 ...

  8. 如何在Raspberry Pi上安装Fedora 25

    2016年10月,宣布了Fedora 25 Beta的发布,以及对Raspberry Pi 2和3的最初支持 . 一个月后发布了Fedora 25的最终"通用"版本,从那时起,我一 ...

  9. raspberry pi_如何使用Raspberry Pi测量颗粒物

    raspberry pi 我们在东南亚的学校定期测量空气中的颗粒物. 这里的值非常高,尤其是在2月到5月之间,那时天气非常干燥和炎热,许多田野都燃烧着. 这些因素会对空气质量产生负面影响. 在本文中, ...

最新文章

  1. Flex Socket 跨域问题的解决办法
  2. skynet给集群中的一个节点配置多个通道
  3. MyEclipse的Git配置
  4. DFS和BFS总结和代码演示(详解)
  5. 跳一跳python刷分_【Python跳一跳刷分辅助】iPhone版_Python跳一跳刷分辅助Ios最新版下载_Python跳一跳刷分辅助v1.0.1苹果版免费下载 - 九酷苹果网...
  6. FZU2218 Simple String Problem(状压DP)
  7. 为什么叫C++而不叫++C ?
  8. angular 解决闪烁问题_AngularJS页面访问时出现页面闪烁问题的解决
  9. linux zmq编译pgm,czmq交叉编译
  10. 我的保研之路-哈工大计算机,中科院信工所,复旦大数据学院
  11. 谈一谈企业部署erp系统的三大时间段
  12. 安全删除硬件并弹出媒体的列表中出现内置硬盘的解决办法.
  13. Unity ShaderLab Stencil Comp 枚举的对应数值
  14. Text to image论文精读 NAAF:基于负感知注意力的图像-文本匹配框架 Negative-Aware Attention Framework for Image-Text Matching
  15. jQuery实现AJAX定时刷新局部页面实例
  16. oracle 3135,oracle的imp问题。
  17. TensorFlow练习6: 基于WiFi指纹的室内定位(autoencoder)
  18. Mysql的下载、安装
  19. 面试官:策略模式和代理模式有什么区别?
  20. “离婚”华为后,荣耀第一胎满身伤痕

热门文章

  1. 解决android中java.lang.RuntimeException: Unable to start activity ComponentInfo问题
  2. GlboalMapper20 如何一次性把上百个经纬度投影的影像转为国家2000或者其他投影的影像
  3. TextView的android:maxHeight,android:minHeight的正确设置
  4. 关于微信小程序form表单无法触发提交的解决方案
  5. 如何解决偶然Maven项目中导入依赖,却一直报错,unresolved dependency
  6. 尺取法 --算法竞赛专题解析(2)
  7. 2022年大连理工大学计算机考研复试时间与复试范围
  8. html 原生滚动条详解,看这一篇就够了!
  9. 检查xml格式的linux自带方便好用的工具
  10. linux cacti安装教程,cacti安装教程