欢迎光临
我们一直在努力

通信部分-串口双向调用(使用ASCII字符串)

本例向你展示如何使用握手连接在Arduino板和电脑之间建立以字符串为载体的通信(本例与4-8的不同在下面有提到)。

代码最开始在setup()中不断输出一个ASCII字符串到串口监视器,直到收到电脑的“回复”(收到电脑的一个byte)才进入loop()。第一次进入**loop()**后代码将三个传感器的值用ASCII解码过的字符串形式发送到电脑一次。(这个字符串以逗号分隔,以换行符结束)而后在loop循环中,程序一直等待电脑的信息(不会再发送字符串),直到下次再收到一个来自电脑的byte再返回三个传感器值一次,不断重复。

你可以使用Arduino IDE 串口监视器来查看数据,或者也可用Processing(下附代码),Flash, PD, Max/MSP(下附补丁)等代替。下面的例子将发来的string用逗号分隔,并且再次将String转换为数字。

如果你将这个例子和**4-8 串口双向调用 (握手连接)比较,就会发现它们很相似——都使用了握手连接。但是4-9与4-8的不同之处在于,本例将传感器值读成字符串,而4-9中是将传感器值直接用二进制形式(byte)发送。虽然说以String发送要在串口传输更多的字节,可是用String你可以随意发送大于255的值而不受byte的限制**。而如果以字符串发送,接收端处理的时候也会更加容易些。

【备注:读者可多关注String操作的部分。其他代码和文字与4-8差不多。】

硬件需求

Arduino板

2个模拟信号传感器(电位器, 光电管, 压力传感器等等均可)

按键

3 个10kΩ电阻

跳线

面包板

连接线

软件需求

Processing 或 Max/MSP version 5.x

电路

clip_image002

将模拟信号传感器连接到A0口、A1口。然后用一个10kΩ电阻连接按键或者开关到D2口。

原理图

clip_image004

程序逻辑

Arduino程序流程

进入setup()函数establishContact() {Arduino不断发送握手连接请求信号}是否收到电脑请求字节?进入loop()函数yesno

进入loop()函数串口是否有数据?返回三个传感器值yes

大家可以这样理解

Arduino第一次收到输入之前处于“空闲状态”,因此不断广播信息:“我已经准备好,如果要传感器信息就来吧”。【Arduino尝试找电脑握手】

电脑说:“Arduino,我需要串口数据,我和你握手”,这时Arduino就知道电脑要数据了。因此就不再发送“我已经准备好……”的信息。默默等待电脑需要数据的时刻。Arduino目前出于“等待状态”,等待给电脑发送传感器信息。【电脑和Arduino握手成功】

电脑说:“现在给我数据”。Arduino返回三个传感器值,然后继续等待电脑的下一个请求。【握手成功后的通信】

这就是握手连接,大家也可以网上搜搜握手连接的含义和作用。

代码

/*
   串口双向调用(使用ASCII字符串)
   语言: Arduino
  
   代码不断输出字母A到串口监视器(用ASCII方式,对应byte值65),
   代码最开始在setup()中不断输出一个ASCII字符串到串口监视器,直到收到电脑的“回复”(收 
   到电脑的一个byte)才进入loop()。第一次进入loop()后代码将三个传感器的值用ASCII解 
   码过的字符串形式发送到电脑一次。(这个字符串以逗号分隔,以换行符结束)
 
  感谢Greg Shakar和Scott Fitzgerald 改善代码
 
    电路搭建:
  * 两个电位器分别连接到A0、A1
  * 按键连接到2号引脚
 
  代码是公开的。
  */ 
  
int firstSensor = 0;    // 第一个模拟信号传感器 
int secondSensor = 0;   // 第二个模拟信号传感器 
int thirdSensor = 0;    // 数字信号传感器 
int inByte = 0;         // 收到的串口数据 
  
void setup() { 
   // 用9600波特率打开串口: 
   Serial.begin(9600); 
   while (!Serial) { 
    // 等待串口建立完成,只有当使用本地USB口时有用 
   } 
  
   pinMode(2, INPUT);   // 2号引脚为数字传感器 
   establishContact();  // 发送字符串到电脑,直到电脑发送回来数据才返回 

  
void loop() { 
   // 如果串口有一个byte的数据,就读取传感器值: 
   if (Serial.available() > 0) { 
      // 获取发送来的byte: 
     inByte = Serial.read(); 
     // 读取第一个模拟信号传感器 
     firstSensor = analogRead(A0); 
     // 读取第二个模拟信号传感器 
     secondSensor = analogRead(A1); 
     // 读取开关,将值映射到0-255 
     thirdSensor = map(digitalRead(2), 0, 1, 0, 255); 
     // 发送传感器值: 
     Serial.print(firstSensor); 
     Serial.print(","); 
     Serial.print(secondSensor); 
     Serial.print(","); 
     Serial.println(thirdSensor); 
   } 

  
void establishContact() { 
   while (Serial.available() <= 0) { 
     Serial.println("0,0,0");   // 发送初始化字符串 
     delay(300); 
   } 

Processing代码

将下列代码拷贝到Processing工程,当你改变模拟信号传感器时,你会看到屏幕上有一个小球跳动。只有当你按下按钮时才会看到小球。

clip_image001

// 代码公开. 
   
  import processing.serial.*;     // 导入Processing串口库 
  Serial myPort;                  // 当前串口 
   
  float bgcolor;          // 背景色 
  float fgcolor;          // 填充色 
  float xpos, ypos;           // 小球初始位置 
  
void setup() { 
   size(640,480); 
  
   // 将串口枚举并且输出 
  // 如果使用Processing 2.1或更早版本,使用Serial.printArray() 
   println(Serial.list()); 
  
   // 在我的mac上第一个总归是Arduino,因此我直接打开了Serial.list()[0]。 
   // 下列代码根据你使用的串口进行调整。 
   myPort = new Serial(this, Serial.list()[0], 9600); 
  
   // 将字节存入数组直到收到换行符(换行符ASCII码为10): 
   myPort.bufferUntil('\n'); 
  
   // 用边缘平滑模式画图: 
   smooth(); 

  
void draw() { 
   background(bgcolor); 
   fill(fgcolor); 
   // 画球 
   ellipse(xpos, ypos, 20, 20); 

  
// serialEvent函数是由Processing applet自动调用的。(applet会在串口收到setup函数体中的bufferUntil()传入的那个字符时回调serialEvent(本代码用了换行符\n)) 
  
void serialEvent(Serial myPort) { 
   // 读取串口字符串: 
   String myString = myPort.readStringUntil('\n'); 
   // 如果你收到了换行符以外的字符时: 
     myString = trim(myString); 
  
     // 将用逗号分隔的string,并且将传感器值转换成整型数组 
     int sensors[] = int(split(myString, ',')); 
  
     // 将收到的值输出: 
     for (int sensorNum = 0; sensorNum < sensors.length; sensorNum++) { 
       print("传感器 " + sensorNum + ": " + sensors[sensorNum] + "\t"); 
     } 
     // 在所有内容输出后添加换行符: 
     println(); 
     if (sensors.length > 1) { 
       xpos = map(sensors[0], 0,1023,0,width); 
       ypos = map(sensors[1], 0,1023,0,height); 
       fgcolor = sensors[2]; 
     } 
     // 发送大写字母A,请求Arduino反馈更多的数据: 
     myPort.write("A"); 
   } 

Max补丁

clip_image002[6]

———-begin_max5_patcher———-
3640.3oc6cs0jZajE94Y9UzKkeHoVloTeSHkm1II0VkeHIthSs6C1obIjZ.E
KjHRhY7jT4+9d5KBj.jTCAXfoV6x.sj5VmyWet127ed6MCFm8EQw.z2f9.5l
a9yau4F0kjW3FS4aFLO3KgIAEpGaPX174hzxAC02qT7kR80mkkUHPAnBQdbP
BZQVdIZRd1bT4r3BDTmkU0YQPY3r3zoeJWDVpe2ttr6cFhvXt7KhyH8W26f9
USkhiTulrw+1czQUszjrzxzf4B0sdP9dqtS5x4woIhREQiWewrkkUW0oViTD
+GpFASt2Qd0+51akeLzRPIU7DPXagIFnH.4653f9WAKKyxVHRQNcfDXlih2w
puvbdWHAlcTPBRKHg4x5mr74EBMINHV1+iFL.8qG.VMWTTDLUrs.TBH+zAvP
nTEhvvxun9pBd6FWH38DWH6DWv6ItbX.RKBOJ7XbP5ztvDesvhBLb6VTwcOg
DmiBjnXfiIrjjED0CpP490PEmtPExwQA5EGUVjK.CKQJqtcYl0nCMRAJi76D
Z7dQflCCVV1i+ENiTy3AwYaghEA4.KVJx+jHMXbhntJPceO3iBpPOPKtZqtU
jUoXtw28fkEimmEIlOI.3Q4iMT9wO+iLxc9O7sN28928t6Ve8uMYo.7EUN6t
ePVoUW+6E4hOW7CAgeaV1meWd1cuWnYLy8mKhhClGDd25F3ce+C2si1Ud42+
bZ3IQJOXg7q96t80e50YvDjqHw7VvkRTXhHHuKEerRwmqfBFsS.g9h.HZN3X
hJf5Qd+xHZHgzc.mrqeYjbn4E84evfIDUjDtjNwD2iRHV6anmGdbmsfKxTTJ
dd93rjtBJ2U42foCwZDqKfYzKkrh4VgYIY4FxVRmN2646f8ck+xw7KrjzOlZ
ZYAVfdZgKlaWn29FzA8nfdR2quj.3ejflBJnKr.Dwpf13cZBm85P0rPj.rOB
6fvztPFGkVI0SAPi5NKHmih7E8Ph2e35uOtYN6x6JEQtJVWpV7gRtm2dZy9W
+YMCxLHrEvAknQktDVdY7v82SFosgmSGHO56BRRt6mEEKxRKDnGd+2812h9X
5GSeODOcAJ.M9YHHAfjPkyD0GIugn.Ht6bQ.7TTS8DoPtCQCQxWobX+jYPUJ
hPn3zgnx7kogphieFZ2j3TwDgH5dzaUscJ77kEnIY4hoYKglVYzcH5KKxJzu
qmgegxl.0MLNGBNDsr.5IUz0iAPZFE.0TtLOEdClQYrAAeORwW+XVo3aP+hb
DHUBCH.mfbEKfGOPyjQhGiCAdNUUBRcQjij4X.u5MZRDzHSyTDQFbcYdHHIM
AzlF1lnoLjKG8UZH5guV1vEkA4kKWbOPGPC9YgjNdJHVy+ZJQ1.Cq.FUWQpA
ke.8DbUwi.YEWBUCDhPyAXCEETFbuhICg9EIRiYnGVjKyt0+io.r+9vrxRz+
Nt7OlJxCRhT35u.X0amlI9X5xEQppQwneJrLarPVU7JkGYWVHz2njevz1UoX
XkoEWOkxDWO9kXYocoTwuzF611zXJyimB3F5qf9nOT9qesryJTJ1EOcV4cIh
IPVWYoOBUMFTl.4sGRRzRT4AOIkRjn8h7LnNJI2mhg6OSk5JZrPJ4i9gfu.R
w+NHLCcpfAMij88n+qTPPMt4UTwj3bAnY.h.aIe.RiAEeF8Pdzx3zLkLUs1Z
mcmczah0FH4ZmpLcp.rVbX3d0zalKhSiKAxBZ9BU2zTP3uPobgL1Q.U0.kl+
jcBZj1AMOpzsJYjdz0n53QXsfYrqELKblH7yUFoDfPVXbrwDGXqCjwjviT7a
rXZbpxOvxzXvpOnPH0GlTJMZog8l2UZJcdPjxjG7ywIYgeFULaInFDk8jpxZ
apvMA4cv9X.7.vaRRGFAcPYHMR0dF2BZC7wEJ2TOKeZnCRD+HzJo.OLWSW6r
qk2wfI6pGf.pdjC4rpfL2YeK8JYloVf93.ocJEvocv9wAcEiMQgBtl.lb0y9
heKnvtGRs+iHOJHM3uaZbN1jDrhED4FfwfLPCEmH8jV.BB0Z+aF.Vkqc4apU
EIb9a5zAcGt5Rf3WdsNJ3R4PXDU0mouHzIca0MWO.KpQjT8oq1SIyqV3mP24
ToxfHpdyOPNqgwoK.W.fxfRNtwsiDSBVlT9ociSMu+jfPQqUtk9paFLMONJK
URFMpq7xUuvOXF1HBuN6ndhzfE6nxPXQkKKFGjKQNyHtSptYYVVRyaspyBD3
CRiA0YQYrlbgHdptY77E4wZk5UWSOf9yJByyRRZzT5673NtiNrvmhiJmoZq5
fI73wKp5DFrBihhmBNxadsxfoEMuRiIbutfVcM4FWuyr.2bvrlNF5.3U+q9C
sKaa5jkMt70iSd8bC2ZbEFUuAa0DWqYF0tJ91p43649br2nZ2usLGuoxrnQq
6TArNx+1CjRLPpVWf62Kj59ZFRa38Y6D0kRo8AnT8b0g0e4p8+f6.P4sBnaX
TqMmPsOdOcjG+dMtOmdzcgLdIGqjX0J+FAVrmSu.L8fAX19Ky1C.e1.z+IB2
qpeCIUV+.I4fARxQGH0i.9ECVZrhZMTheMCkc4XRMsoCgbef2ZFjaF5MXzaH
n2PQugYmhe0WjdcU47Z1Ukhb6CwFISy2HNtcvtaNRWdshHNVgHcNMUlopRm4
tJByyLXfI0UN6GM7eUiFTm8BMbctZQC8atOegDu6oveXrgpeaGnfaETvsBJN
6AKuNsT4n+zRVXJtQd+ciEEYKyCq.8ptRTSdBRQrLNcUd5eXcjoa7fyhihZl
UrNQxBYZo5g.vpdt8klkJi1QyPvdH7UFMStbvYu8Amu1nY7ECMKGXBqnY2KH
Z18Jjl4aYNnEYiQWVzrUxytWNzL0VZ14xglI6isN5kAMi2GZlbYPyNma6FqC
aJRs9qEogO+ovfvYFxxjGV07cLnH3QQzm.R.BG7SAkk4wiWVpC2p9jwX23ka
0zSz4M6e1QZY.8mljMNHwLURqZ9FuzslMk8ZJXtcMPeblVut1XYDhdMCpmjZ
8BAqsU9DezKxJAa8Hmbbfi+wccuVv7c0qELrEHB+UAhHWzCfCbKPEyBki24Z
clythVwfkYSmlHrPdX8tC5v1iPb5ArPuOWc8NVrRZspq24UxhE0wBcAsMyt2
2LLuqvkKZRXjEq5CM6S3tq9Zm6HD+8Prm0F+jDWn1paUe+2ZuF259kxkiR5W
Qf6vzKBtMm+gFrMeuWsKW.6B61VyWOFjz0Zsmwza+.ikxQcAL3iDtbLWMTKm
OtyMEFcjWM9iu0rMa81D8kUl3v2ewcHWP5B2HX6kK7t7DL5fs6JVIrO0Z1l3
bEpOP3zih9.gbspPzKDYbRVAQ7CFhtZsYzhW1ko0WEJcG3oAC0aRIyxKsUEI
+iDPwOLfp0uNA68MmtSUSmRuNb8d1ttWya7sVWf5Iwf.1LQtZUnqNvT1bS6z
E5o2vfqNSH5bufQbuZV09M.E04Mj8XBUiBqNGl5FSt3NGlZaGRpV6wc4kiWi
q0twaaORhul1jjsIi7cMjQlJJUaQuhR495nlfRQWRJXkrgmMGXWjKM4jdGJH
yovkl4HUetutzWuY5tjFHneGn77rtG3iJ92whCVJxKhBwgGtRaFIzabfNrRn
WThd9q24vsZjf9JvHwOKBhprFDmtXYIZ7xISjaO1GE4OK2V9yiS.qFhvrznh
8cKyMZs7EVepT01FlCe0rIC0lUk6NX4N9syCyAE660+ovE9hyGqjaGurrLak
G0YwoMlFO4YMSZjd9DcWucsjUr1Yqgy8TluCY3N9Q8.+k0JCD3ZTS0CW8Qyb
s19nOxrgjw7VFU+3ooYviK66pCfimt8AAxHOOBkK+EajC2yayWtciMzgdvpM
NKORj29YyGcS4wFVlql0wcZTg1yw5wvMNiTpuUzpu.Y0miRlgO0w7wpZI2Em
SUBGayVM5eqU4C+rV4ZSPkvXqLJbAHlR3mKwT5ISL8+Kv0k.GWEKwpP3ewk3
7omKIN7EtDmp4ZtHk0BfatXgLhgasHgZrVYaY8AIO7fq8Pas1fFzjd4ibwpd
XO4GXOeOG+lcyasNh1R+wVx2yBxeTOT+wiZFYA0P48PNyiiVjAhJlNT4Qvpb
uj3aN2qYqJcBfSWhMbf+YCPcsfbNeTC2l9WNc+5eIlkST0RJgupzIn+kysgC
X6GGXnYpdYfP0GP6MKQXM3N1Ih6XVvcLuym7B0B5w8v.ahqBI49qJcJ.TaX.
N+xBP4NGHhhqYfkRNM9q1f3ZweqyYCQYdGCSZGQ5wBx47o.Ssw+CkcgQOmud
KZic4QKzCw+7ROm8nY2LfMsEDtdfeMKSn5Ev95IQhorcqJcBrzPsQUhRNe8M
1X6lhOezC4Bidv1nKcFs8YimJ9n8RWZXiO7aSCxDRLdjd91qU5TnmXCeRvmR
9jnm7b15RmJ9rO4Kr+IgO04BfczyOpqx9npzofOsIlaR8Mo0IUMR48i0mYly
lVMwlw6gbloGRezy4yKEw6BHBBWik.eRi3DNM5KDahS.SOE1EjmXl7Uyqo9T
AtQAO8fG3oLX3cZFxKh0FLNSRfDaoG74gdvW.ZDU9FMGSdFMBt+IQh.6eIvw
FujTkJREGKKcJ3X2WtXf7Ub1HywEqxh2tJnE.FcZhMByrcXQw1x+bOWJYjpy
lv8oq55aEHLcwD8hJjxbVU5EigcNtL7Ql76KVVp69Huhcb87vpoCkRYT+96v
Hd5Ay1rofMqm+FkLYvv0+GL3FkL6bLp21kL6QFNV8BNM48foWBV4zt1wXm5V
4jkNEbL45dtNw13Iltmi9sAyY0S0l8BR+3yWjVXax7eOmKrp4m0QKIal6VYo
SAf5XQxSrCa5l0qk45k5kAzqEgMNgzkz9FmL5abpnu4IhNzZ+0s+OKCSg0.
———–end_max5_patcher———–

未经允许不得转载:Arduino-Maker » 通信部分-串口双向调用(使用ASCII字符串)

支付宝扫码打赏 微信打赏

原创文章,若帮到您,欢迎打赏

分享到:更多 ()

评论 抢沙发

评论前必须登录!

 

线上商城

中贝斯特创客空间蘑菇云创客教育