【Arduino官方教程第一辑】示例程序 4-8 串口双向调用 (握手连接)

来源:互联网 发布:qq群淘宝客的含义 编辑:程序博客网 时间:2024/06/04 17:44

串口双向调用 (握手连接)

本例向你展示使用握手连接在Arduino和Genuino板和电脑之间建立多字节的通信(multi-byte communication)。
代码最开始在setup()中不断输出字母A到串口监视器(用ASCII方式,对应byte值65),直到收到电脑的“回复”(收到一个byte)才进入loop。第一次进入loop()后代码将发送三个传感器的值到电脑一次。而后在loop循环中,程序一直等待电脑的信息(不会再发送字母A的等待信息),直到下次再收到一个byte再返回三个传感器值一次,不断重复。

译者注:为了帮助大家理解,我在译者解析程序逻辑板块绘制了流程图,不懂的可以看看。

你可以使用Arduino IDE 串口监视器来查看数据,或者也可用Processing(下附代码),Flash, PD, Max/MSP(下附补丁)等代替。

完成本例所需的硬件设备

  • Arduino板或Genuino板
  • 2个模拟信号传感器 (电位器, 光电管, 压力传感器等等均可)
  • 按键
  • 3 个10kΩ电阻
  • 跳线
  • 面包板
  • 连接线

完成本例所需的软件

Processing 或 Max/MSP version 5.x

电路连接

图片来自官网
将模拟信号传感器连接到A0口、A1口(还要用10kΩ电阻进行分压)。然后用一个10kΩ电阻连接按键或者开关到A2口。

原理图

图片来自官网

译者解析程序逻辑

Arduino程序流程图

(此处为流程图,如果看不见可能是浏览器问题)

Created with Raphaël 2.1.0进入setup()函数establishContact() {Arduino不断发送握手连接请求信号}是否收到电脑请求字节?进入loop()函数yesno
Created with Raphaël 2.1.0进入loop()函数串口是否有数据?返回三个传感器值yes

大家可以这样理解

  1. Arduino第一次收到输入之前处于“空闲状态”,因此不断广播信息:“我已经准备好,如果要传感器信息就来吧”。【Arduino尝试找电脑握手
  2. 电脑说:“Arduino,我日后要串口数据,我和你握手”,这时Arduino就知道电脑要数据了。因此就不再发送“我已经准备好……”的信息。默默等待电脑需要数据的时刻。Arduino目前出于“等待状态”,等待给电脑发送传感器信息。【电脑和Arduino握手成功
  3. 电脑说:”现在给我数据“。Arduino返回三个传感器值,然后继续等待电脑的下一个请求。【握手成功后的通信

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

例程代码

/*  串口双向调用  语言: Arduino 代码不断输出字母A到串口监视器(用ASCII方式,对应byte值65),直到收到电脑的“回复”才   停止。收到电脑的“回复”后(收到一个byte),代码将发送三个传感器的值到电脑。 感谢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();  // 发送A字符到电脑,直到电脑发送回来数据才返回}void loop() {  // 如果串口有一个byte的数据,就读取传感器值:  if (Serial.available() > 0) {    // 获取发送来的byte:    inByte = Serial.read();    // 读取第一个模拟信号传感器,然后除以4,以保证值域在0-255:    firstSensor = analogRead(A0) / 4;    // 等待10ms,让ADC数模转换电路完成处理工作:    delay(10);    //读取第一个模拟信号传感器,然后除以4,以保证值域在0-255:    secondSensor = analogRead(1) / 4;    //读取开关,将值映射到0-255    thirdSensor = map(digitalRead(2), 0, 1, 0, 255);    // 发送传感器值:    Serial.write(firstSensor);    Serial.write(secondSensor);    Serial.write(thirdSensor);  }}void establishContact() {  while (Serial.available() <= 0) {    Serial.print('A');   // 发送A字符    delay(300);  }}

Processing代码

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

// 代码公开.import processing.serial.*;int bgcolor;                 // 背景色int fgcolor;                 // 填充色Serial myPort;                       // 串口int[] serialInArray = new int[3];    // 串口接收数据存储int serialCount = 0;                 // 串口数据数量int xpos, ypos;                  // 小球初始位置boolean firstContact = false;        // 是否从板子收到了数据void setup() {  size(256, 256);  // 设置舞台(窗口)大小  noStroke();      // 设置下一个绘制的东西无边框  // 设置小球初始位置在舞台(窗口)中间  xpos = width/2;  ypos = height/2;  // 为了调试方便,将串口枚举并且输出  // 如果使用Processing 2.1或更早版本,使用Serial.printArray()  println(Serial.list());  // 在我的mac上第一个总归是Arduino的FTDI串口适配器,因此我直接打开了Serial.list()[0]。  // Windows系统上一般都是COM1。  // 下列代码根据你使用的串口进行调整。  String portName = Serial.list()[0];  myPort = new Serial(this, portName, 9600);}void draw() {  background(bgcolor);  fill(fgcolor);  // 画球  ellipse(xpos, ypos, 20, 20);}void serialEvent(Serial myPort) {  // 从串口读取一个值:  int inByte = myPort.read();  // 如果是第一次获取到数据,说明Arduino上的程序第一次运行,将串口数据清空。如果不是第一次,则说明是传感器数据收到了。:  if (firstContact == false) {    if (inByte == 'A') {      myPort.clear();          // 清除数组存储      firstContact = true;     // 这是第一次连接,收到了Arduino的握手请求      myPort.write('A');       // 电脑发送一个字节到Arduino,以此获取更多组传感器数据。    }  }  else {    // 将最新数据放入数组:    serialInArray[serialCount] = inByte;    serialCount++;    //如果有三个字节:    if (serialCount > 2 ) {      xpos = serialInArray[0];      ypos = serialInArray[1];      fgcolor = serialInArray[2];      // 打印值(调试用):      println(xpos + "\t" + ypos + "\t" + fgcolor);      // 发送大写字母A,请求Arduino反馈更多的数据:      myPort.write('A');      serialCount = 0;    }  }}

Max补丁

图片来自官网

----------begin_max5_patcher----------3908.3oc6ckziiaiE9b0+J3XjCIXpp.WzZNMURv.jCInQ5fYNjNngrDssRKK4nkp6JA4+973hrkrsjncKu0SRiXasQ83G+dKj7QV+4qtaxzrOxKlf9Zzuft6t+7U2cm7ThSbm936lrL3igIAExaaRJ+CYS+sI2qtTI+ikxSuBMKNojm+N3D4Aua5KkPwpuoUAkgKhSm+tbdXo5cQXVOhuGwrohuHD4WT7iXzupen3HY4BuqGrH0kzrrzxzfkb4kdJONHo9JoUKiSS3kRgjt4jYUk0mkznPJh+CYgHewpSqtyxWVwUh3jIqkEYEfmqQEMr.ETbB+YddQbVZix+tIAqV03z203QDX4ukIKHm6Wep3T0ovqOUN+435m2Rcx+5U0E+FTzVBh9xOsHXIh5YuADg1x4IYgumG0r3mjshmFmtJmWvSKCJ0um0WNhOKnJo7c6GmZe8YAg7Ne381Rc2j44wQYoBgn0SJNc8qCHH1RhQqJi7NRCVsmGt.pGUESCxE31zDdCV.PRyxRZeo0MU.WOHMdYPIuLVIrT75BMd4p73zxVuHdZ.TFKJByyRRZUTpq77dtRDzZFx+PbT4BYY0DJgaOdUcSvj0XTT7bdQY6yUFLun8YZo71jl0TIt042RYNLa4RfCTWfsznKWDWfJpltJHrbgV6t.AZInfzWP.4INpJHA8za91u+6QN1nk7hh.PpQwonxEbTAWzpilVMimilkmsDtPbo3TPiUdY0pGa9ZShS4gYUJz1pwE1iwCpxbAgJI9DGGwWNzFTksLf3z7M0MybG6Hj1WngsD7VEXS8j5q7Wu5U0+39ir8QJJS5GMHdtRimL4m10e1EVX0YsE2YssINriYRoFRyWVMoRRUGQvnkmms3pnXDYHbBKMPpIOL5i1s83rMPwFcRCsGRyPH780.8HBnpWz.vlEQBWJ+0CSunehJSmJxiIZRtNGhhDYrUjt3ZQyA2fHJhZDifXIQHUHH8oGYgOREI5nqHIzhFWUndPyBdB3VzHJGwUhkVrgvRl2UCVNMHcd234lf1DN16HFEIdHt99A5hrp7v5WWMSBQZgMP.Tkwoqig8W1.Sn1f3h3nn1wLpBypPDzlJ7XinEGkLiMPloWOhrgR7dpZWJQV1faDy35QjMThMFkWFGsJChQPqrQp8iorV6Q28HBVF4nMVDJj7f1xyYACFScisg.ruLHOWuMUS4Am4pI4PTnHi.6bi02HNzSYnDBe4cgAgKzRk1jc8PJLoH3Ydz6.Q.7K8tfxx73oUkJq1MGuCy5TpAi.POWZ3AenidLOOIaZPhdjZVW3sdk6LXEGzHb7pMfr7SEy3SXHyBSxJ3J2ncNNYVJsXG6Me10nj4cfCRFdTFjLo7q3SiCpjjEDM.nvra.GN39.E2CDTHWXPo8.xzfqrHCHKnf5QUYUVdoZPUjCSC7LU8.XtTUXlX8vr51GjwFGLC2AlMdLkU4RiaRrnmJuiudnDk0ZW+9p6TuKBe433JUCzp6fUiOF0SUk2UQYUPNTEkiZubvKa1tsmgL5SCTXGHnnG0CceLpkpR9Rs28IUESWlEwWNKfHlg.zj6Ee7S+nE8A+m9F7Cu40u9gMm+aRp3kYYkKd3GDOz5y+c7b96K9gfvuIK68uNO6g2vUUL80WxihCVFD9vlB30e2SOrmxUb527RZ3nZNrljGrR70vs1J9suWuZ3zaHVdG3RIJLgGj2Gfn6TcGcstEfvtH.hpFLlnBndjOLGQAIz98BXc6yQxghmOn6gZqj0ShPOXhynLOjzCESt+XwE8TxrCvrdXo16rqnLgvbHaFmbh29QD+K0DyNdjDwvzQL.NXpoMvoOBxkger0HwMRQbpbCh91fjjG9IdwprTH9SzaSea5a.GQEPnnh43WNefMlsOgx18n.vgUNO.tKl7tDyI3iHzafJHZVVNedVEbGgYIY42i93prB0i7B7KT1LnnCiyAiinpBnsPV7OG.tYKfBsrJOkGUG5aq26iJw6GyJ4eM5mEgEKaNQPMEBUp.t8.krplOVTlZdJAW27bjvGK7p2pHQPgLOSJDYv4E9gQBYBjMUselRxDy+4WplIzm9JQAWOEmfb.E364B43CAwp5uRRDEv8hWXprjADMUOYpOg9.bVQpEfhKgGCnAnk.rghBJCdTVICA3sDvAhE5oU4hf67ea5zWPuILqrD8uiK+i477fjHIt9y.V88yy3uMsZUj7wnxGKNAdPx5fAZMErDZOcJU4M01WFQokix.pKa+JE1WacmnKFeYd7b.0PeIzB8Kk+5WIZpBEjt34KJeHgOCh4HK8Y3QiAkAfs8TRhhOkG7AAGQf0qxyfmQxa+PLb8Ex.2PS4BdO5GB9Hvg+cfJCMofAIMu9Qz+UPCjckqVJlEmyA8Bf.rC6.3hAEuG8TdTUbZljQ0nr1ayIqmTwQYfyRGafZhur5vfuyMSqYNWmtAPwWHalDSuUgT0Bosh.JpAR89Y6Ez5QEfPTQO4J0DHLInIliz8BZV2JfV3Bd36qsQwAVVXbr1BGXp6sSd5sSDruo74wofx.HxUgxQwTnMLqTXvRmiGh2PUZr5pBynKChjl6feNUjSRnhEUfRPT1GfG9Ik4TQBm.hEZZ.bc38HjAMKGzDRijEm1ifx1dbgzQyKh6FZc3wOCkRJH+KUh0daWs6wzltWx1puXxlWW6NZWY2JiTBzzILRIANku02NourySMVI1VJTvQZff32AJr+dS9e34QAoA6EGXlGFH9yk7yyQAlVd3SR94g+TxOu1sUFlgd6ICI96LzazyPu1cgqsZ8r74SgF.65+efbMf4pGHT7lgHh30Sha3N5Ia.oqjMf7nsuMwycf7iYDybiAAVr3eC.oTMjpzEr8GDRc9bFRGHYXDrzg.Tlx+qNW8TY1IkzCfZ2IftkQstbB08HUezoDS+oFyI.cWIhWBaDiUo7qIrDO7f.L6nAXqCmyNT9act.z+Iv.GR0uES0ZXfjdz.IczAxQOUR+zvRsUTigRxmyPYeNljyXv8Peef2ZFzuLzWPPeAE8ELzWXYlhe8WzAcUg+b1UkIoCLzIH60zwASGXaua1Dq2nUY.sox4vng+m0nACePngC9lEMLZMBPodOxf+yx5d4uMCTHm3kJvIIGjcLMedEQldkjpoBkQyjY1Hk.hmSY95Iwos8NDb9VSlIWOIntqgxryUjL6bCJy1lli5tWWxrQ7YmqGYlc6shK1iY2dr0wtNjYxgHyzaq0OznY235awCr8zSz6EGd1QNUKf.74dADTBbTbeotjpW95IolY0WpKYONY8M83Rx2MChx3fL+iG5MmtXpdmvXj8uTvaAL1WjbbarQD4Z6kXBpnm6a69oKV2PY9WY174IbC3CaRQ9iKQ4sYGQpwdtZ5wFrc7n569.M83OOR5ydSB1ZcAWCxdbKuavz9LILxfD.wWO.WNq+Zu4Es+AP6s5p9jDWH8ET+c85+XbW0.N1nDCTD7U4DGc6ohnU019fS7kQ0o43luuOGjv5agHp0DT.CysOfgLR3xXlXTUKm16RivRsn3z0O6cl3YScAvtrbhwekGB7BZuqESUzBJWmCvK7t9HF8Ts6cUAPoFWso3aP8ApWyJ3wqOPo2pJDCBQ0NI0Pj8QCQ2r1L5vKaU5lDRYX7yRur1UYYZmJQ9iDHwN9dndB5n5ejflmmUsBwLHnDkKXWRuAkb3NeuzqRstiQGP.fCQFdHNzaE.8u58Nz9svFE9SGIE1Xkv9Iwfl1BdNWjA7xcThsWCS847loyFD8pZq2E2F04lYULzBTDYhrFSDDJdjofisN2NUN26e4xRu51zD5ZseJ4HC63WyIX6jRqsp0jangBnK.Qlo58PCpWevtahzqK7fbKsdX6R64aao8LmWhBPh9jKVAPMzb5a2cV6opdWHneMmqMEmAGsPhieigIjV+4gF1GgbMNXg+NH44YaRYyd..S1ThHzKhFwwGRaWVITqyj9FvPqMTd0pDuSqDrOGF.Uogf.juCFi9WAUkYR+rFPanDcPG8SbrtjyG03ZQ8m3AqC5HNcUUoXSwVrqXKVcZu.5ZnkwIfIVdXVZTwAuTTUiYuxwjZDK6ZgnRtYV8tJmPhEcuXgz2Goxyaiw35UkaWbpqtfzD02oUkkYqi.YQbZqIIWrIljFolsdmMKFRwCJ2+DTn.9QlkOld+d9Qy9IJdpLfy05Ik2b8GsG9h8rdm1ZFx1FrmmlA2snwqI9Mcdi2nr6q3Gc87nLawurbw1dda+tMyGJ9HaQmlkGwy6davisMgrkM65ozeulfYCzG46am8tSDK144xV4cEvVMTRXq9CIX8+ALNWb6sttKNkiZetnbz+lxcQnb1Nds2C0tvLNe14hwQtxYbxhqc17qHfamUcZZ3NYSWqjJuiDoizZ+ud2jnaRK4k3346IIVdR1kKiQjM39adMamvc6n+Xp36Yf3SIGh3uKbquqs1JksTIIkuJ7RrZSFb2Cn9j5a6DT8cMo0iczU+lsYaU8YNVh5k5uzJLU26ZcfuJE6XLY0mcRp9NTCp+L+Ap+in7Xf3b9jFQBLtIY06PbrGhcrU6N00Qlaf9N0+QPo9nSP6qsI7aYNLSNOHpsAxis0ggnZLjYqyyFkdSqinVsPaqSDZaYBZ6c93uLCjGmiCroJVLzU45iNE.pIUfs3TWb.0FejHp9uANr0GcJPTroFDNOHpkIweLnI1QTdHl3P7LhOF3Ahd9rnvLwAMy5JSdNezGlsIsW9mW44r26js+alhxjlkdhN0YEYqiH5MTeWo6D4Qm.ieLS7OynmuVGSbmbFUlnWWhiQlhOeN+Yl35bq.tGo9JRcj8AVqdz7nSgVB9zNj.FTOU68o5d9KO5TUOGxVMw+jTO8T6wqD0hEiHsOJO5TTOMoS.zlqN0SpZjz6GcH05ylVM0jwuidlkmAif374ih5M5QPfccr8HqifffotN8pt3hUcaWu8nosBhwmD0Epw5KmoF.poxy4YHbnjqfPJqcM3Y2vun7nS.if3eETiqcRX2LR.4QmhZrkoCSGwzZrqKHrVR8caari+55d2caPqmq5n.ywe8QWrZL9fpwVXeaogMByE6y1SMdjk+gbavbN7fYvVtt1C2XwHJSzpk+tidUO25HUB9onw9mlFQ10fhpZBaDatcMTTEGcJpwzqg92qqiVtM6Cu0IRQ0ndEdfCAqVl0qYAUmPrctbxO4XCuPMa1asYzKDks1D52ZCne6Mednz9qW8+.vfqkDA-----------end_max5_patcher-----------

相关资料

serial.begin()
serial.available()
serial.print()
analogRead()
ASCIl表:展示Arduino先进的串口输出函数。
调光器:轻点鼠标来改变LED的亮度。
数据图表:发送数据到电脑,并且使用Processing来绘图。
MIDI音乐: 以串口发送MIDI音符。
多串口[Mega]:使用Arduino Mega上的两个串口。
原来标题译为MIDI音乐MEGA,是错译
控制LED:从Processing或Max/MSP来开关LED.
读取ASCII字符串:解析一串用逗号分隔的整数(以字符串类型传递)来让LED渐隐。
串口双向调用:用双向调用/握手连接(handshaking)的方法发送多个变量值。
串口双向调用(使用ASCII码):用双向调用/握手连接(handshaking)的方法发送多个变量值,并且在转发之前将这些变量的值通过ASCII解码。
串口事件:展示SerialEvent()函数的使用。
虚拟调色盘:用Arduino发送多个变量的值到电脑,然后用Processing或Max/MSP读取它们


更新进程

日期 日志 译者 2016年5月18日 创建并翻译文档 唐家勋 2016年5月19日 setup()的注释写错了,串口波特率是9600 唐家勋

译者:唐家勋
邮箱:mrsteventang@gmail.com
QQ:649196486
转载请注明出处,一切只因为热爱。
希望您能指出宝贵意见,谢谢。
我的微信公众号欢迎关注,2016年6月开始更新

1 0
原创粉丝点击