Cat hungry.png
Здравствуйте! Собираем деньги на перевод материалов по электронике(https://www.allaboutcircuits.com/education/). Реквизиты указаны здесь.

Arduino:Примеры/SerialCallResponse

Материал из Онлайн справочника
Перейти к: навигация, поиск

Перевод: Максим Кузьмин (Cubewriter)
Перевел 2686 статей для сайта.

Контакты:

Проверка/Оформление/Редактирование: Мякишев Е.А.


Последовательная передача данных методом вызова и ответа (рукопожатия) [1]

Этот пример демонстрирует многобайтную передачу данных от Arduino к компьютеру при помощи метода вызова и ответа (рукопожатия). При запуске скетч отправляет ASCII-символ «А» (байт со значением «65») и повторяет это до тех пор, пока компьютер не даст ответ. Получив его, он отправляет на компьютер еще три байта (по одному от каждого из трех датчиков) и снова ждет ответа от компьютера. Для того, чтобы увидеть полученные данные, можно воспользоваться окном Serial Monitor, а можно прочитать их программой Processing (см. код ниже), Flash, PD, Max/MSP (см. код ниже) и т.д.

Необходимое оборудование

  • Плата Arduino;
  • Два аналоговых датчика (подойдут потенциометры, фотоэлементы, силоизмерительные резисторы и т.д.);
  • Одна кнопка;
  • Три резистора на 10 кОм;
  • Макетная плата Breadboard;
  • Провода-перемычки;

Необходимое ПО

Цепь

Подсоедините аналоговые датчики к 0-ому и 1-ому входным аналоговым контактам, а также к двум 10 кОм резисторам, ведущим к «земле» – для того, чтобы создать два делителя напряжения. Кнопку подключите ко 2-ому цифровому контакту и к 10 кОм резистору, тоже ведущему к «земле».

SerialCallResponse-circuit3.png

Схема

SerialCallResponse sch.png

Код к Arduino

  1. /*
  2.  Последовательная передача данных методом вызова и ответа
  3.  Язык – Wiring/Arduino
  4.  
  5.  Эта программа при запуске отправляет ASCII-символ «А» (байт со значением «65») и повторяет это, пока в ответ тоже не получит данные.
  6.  Затем, дождавшись байта, переданного через последовательный порт, она передает компьютеру три значения от аналоговых датчиков.
  7.  Спасибо Грегу Шакару (Greg Shakar) и Скотту Фитцджеральду (Scott Fitzgerald) за поправки.
  8.  
  9.    Цепь:
  10.  * потенциометры, подключенные к 0-ому и 1-ому входным аналоговым контактам
  11.  * кнопка, подключенная ко 2-ому цифровому контакту
  12.  
  13.  Создан 26 сентября 2005 Томом Иго (Tom Igoe),
  14.  модифицирован 24 апреля 2012 Томом Иго (Tom Igoe)
  15.  и Скоттом Фитцджеральдом (Scott Fitzgerald).
  16.  
  17.  Этот код не защищен авторским правом.
  18.  
  19.  http://www.arduino.cc/en/Tutorial/SerialCallResponse
  20.  
  21.  */
  22.  
  23. int firstSensor = 0;    // первый аналоговый датчик
  24. int secondSensor = 0;   // второй аналоговый датчик
  25. int thirdSensor = 0;    // цифровой датчик
  26. int inByte = 0;         // переменная для байта, передаваемого через последовательный порт
  27.  
  28. void setup()
  29. {
  30.   // начинаем последовательную передачу данных со скоростью 9600 бит/сек:
  31.   Serial.begin(9600);
  32.   while (!Serial) {
  33.     ; // ждем подключения последовательного порта (это нужно только для Leonardo)
  34.   }
  35.  
  36.   pinMode(2, INPUT);   // цифровой датчик подключен ко 2-ому цифровому контакту
  37.   establishContact();  // отправляем байт, чтобы установить связь; делаем так, пока не приходит ответ
  38. }
  39.  
  40. void loop()
  41. {
  42.   // если получаем нужный байт, считываем данные с аналоговых датчиков:
  43.   if (Serial.available() > 0) {
  44.     // получаем байт от компьютера:
  45.     inByte = Serial.read();
  46.     // считываем данные на первом аналоговом контакте, а затем делим их на 4, чтобы получить число в диапазоне от 0 до 255:
  47.     firstSensor = analogRead(A0)/4;
  48.     // делаем задержку в 10 миллисекунд, чтобы аналогово-цифровой преобразователь немного «отдохнул»:
  49.     delay(10);
  50.     // считываем данные на втором аналоговом контакте, а затем делим их на 4, чтобы получить число с диапазоне от 0 до 255:
  51.     secondSensor = analogRead(1)/4;
  52.     // считываем данные с кнопки, присваиваем ей одно из двух значений – 0 или 255L
  53.     thirdSensor = map(digitalRead(2), 0, 1, 0, 255);  
  54.     // передаем компьютеру данные от датчиков:
  55.     Serial.write(firstSensor);
  56.     Serial.write(secondSensor);
  57.     Serial.write(thirdSensor);              
  58.   }
  59. }
  60.  
  61. void establishContact() {
  62.   while (Serial.available() <= 0) {
  63.     Serial.print('A');   // отсылаем прописную «А»
  64.     delay(300);
  65.   }
  66. }

Код к Processing

  1. /* Скетч к Processing для этого примера: */
  2.  
  3. // Этот код не защищен авторским правом.
  4.  
  5. import processing.serial.*;
  6.  
  7. int bgcolor;                 // фоновый цвет
  8. int fgcolor;                 // цвет заливки
  9. Serial myPort;                       // последовательный порт
  10. int[] serialInArray = new int[3];    // переменная, куда мы запишем значение, которое получили
  11. int serialCount = 0;                 // переменная, в которой мы будем считать, сколько байтов получили
  12. int xpos, ypos;                  // стартовая позиция для шарика
  13. boolean firstContact = false;        // был ли первый контакт с Arduino или нет (по умолчанию false, т.е. «нет»)
  14.  
  15. void setup() {
  16.   size(256, 256);  // размер экрана
  17.   noStroke();      // контур не рисуем
  18.  
  19.   // задаем стартовую позицию шарика (в середине экрана)
  20.   xpos = width/2;
  21.   ypos = height/2;
  22.  
  23.   // выводим список последовательных портов (в целях отладки):
  24.   println(Serial.list());
  25.  
  26.   // я знаю, что первый последовательный порт на моем Mac –
  27.   // это всегда FDTI-адаптер, поэтому я сразу открываю Serial.list()[0].
  28.   // на Windows-устройствах это, как правило, открывает порт COM1.
  29.   // впрочем, вам нужно тот порт, который используется у вас.
  30.   String portName = Serial.list()[0];
  31.   myPort = new Serial(this, portName, 9600);
  32. }
  33.  
  34. void draw() {
  35.   background(bgcolor);
  36.   fill(fgcolor);
  37.   // рисуем фигуру (т.е. шарик)
  38.   ellipse(xpos, ypos, 20, 20);
  39. }
  40.  
  41. void serialEvent(Serial myPort) {
  42.   // считываем байт, который пришел по последовательному порту:
  43.   int inByte = myPort.read();
  44.   // если это первый полученный байт и это «А»,
  45.   // очищаем буфер последовательного порта
  46.   // и отмечаем, что у нас состоялся первый контакт с микроконтроллером (т.е. с Arduino).
  47.   // в противном случае добавляем пришедший байт в массив
  48.   if (firstContact == false) {
  49.     if (inByte == 'A') {
  50.       myPort.clear();          // очищаем буфер последовательного порта
  51.       firstContact = true;     // пишем, что был первый контакт с микроконтроллером
  52.       myPort.write('A');       // запрашиваем еще
  53.     }
  54.   }
  55.   else {
  56.     // добавляем в массив последний байт, полученный по последовательному порту:
  57.     serialInArray[serialCount] = inByte;
  58.     serialCount++;
  59.  
  60.     // если получили три байта:
  61.     if (serialCount > 2 ) {
  62.       xpos = serialInArray[0];
  63.       ypos = serialInArray[1];
  64.       fgcolor = serialInArray[2];
  65.  
  66.       // выводим эти данные (только в целях отладки):
  67.       println(xpos + "\t" + ypos + "\t" + fgcolor);
  68.  
  69.       // отсылаем прописную «А» в качестве запроса на новые данные от датчиков:
  70.       myPort.write('A');
  71.       // сбрасываем значение в serialCount:
  72.       serialCount = 0;
  73.     }
  74.   }
  75. }

Используем в Processing скетч, указанный выше. Теперь при изменении данных от аналоговых датчиков шарик будет менять свое положение. Если нажмете на кнопку, то шарик исчезнет.

SerialCallResponse-output.png

Код к Max

  1. /* Патч к Max/MSP (версия 5) для запуска этого примера: */
  2.  
  3. ----------begin_max5_patcher----------
  4. 3908.3oc6ckziiaiE9b0+J3XjCIXpp.WzZNMURv.jCInQ5fYNjNngrDssRKK
  5. 4nkp6JA4+973hrkrsjncKu0SRiXasQ83G+dKj7QV+4qtaxzrOxKlf9Zzuft6
  6. t+7U2cm7ThSbm936lrL3igIAExaaRJ+CYS+sI2qtTI+ikxSuBMKNojm+N3D4
  7. Aua5KkPwpuoUAkgKhSm+tbdXo5cQXVOhuGwrohuHD4WT7iXzupen3HY4BuqG
  8. rH0kzrrzxzfkb4kdJONHo9JoUKiSS3kRgjt4jYUk0mkznPJh+CYgHewpSqty
  9. xWVwUh3jIqkEYEfmqQEMr.ETbB+YddQbVZix+tIAqV03z203QDX4ukIKHm6W
  10. ep3T0ovqOUN+435m2Rcx+5U0E+FTzVBh9xOsHXIh5YuADg1x4IYgumG0r3mj
  11. shmFmtJmWvSKCJ0um0WNhOKnJo7c6GmZe8YAg7Ne381Rc2j44wQYoBgn0SJN
  12. c8qCHH1RhQqJi7NRCVsmGt.pGUESCxE31zDdCV.PRyxRZeo0MU.WOHMdYPIu
  13. LVIrT75BMd4p73zxVuHdZ.TFKJByyRRZUTpq77dtRDzZFx+PbT4BYY0DJgaO
  14. dUcSvj0XTT7bdQY6yUFLun8YZo71jl0TIt042RYNLa4RfCTWfsznKWDWfJpl
  15. tJHrbgV6t.AZInfzWP.4INpJHA8za91u+6QN1nk7hh.PpQwonxEbTAWzpilV
  16. MimilkmsDtPbo3TPiUdY0pGa9ZShS4gYUJz1pwE1iwCpxbAgJI9DGGwWNzFT
  17. ksLf3z7M0MybG6Hj1WngsD7VEXS8j5q7Wu5U0+39ir8QJJS5GMHdtRimL4m1
  18. 0e1EVX0YsE2YssINriYRoFRyWVMoRRUGQvnkmms3pnXDYHbBKMPpIOL5i1s8
  19. 3rMPwFcRCsGRyPH780.8HBnpWz.vlEQBWJ+0CSunehJSmJxiIZRtNGhhDYrU
  20. jt3ZQyA2fHJhZDifXIQHUHH8oGYgOREI5nqHIzhFWUndPyBdB3VzHJGwUhkV
  21. rgvRl2UCVNMHcd234lf1DN16HFEIdHt99A5hrp7v5WWMSBQZgMP.Tkwoqig8
  22. W1.Sn1f3h3nn1wLpBypPDzlJ7XinEGkLiMPloWOhrgR7dpZWJQV1faDy35Qj
  23. MThMFkWFGsJChQPqrQp8iorV6Q28HBVF4nMVDJj7f1xyYACFScisg.ruLHOW
  24. uMUS4Am4pI4PTnHi.6bi02HNzSYnDBe4cgAgKzRk1jc8PJLoH3Ydz6.Q.7K8
  25. tfxx73oUkJq1MGuCy5TpAi.POWZ3AenidLOOIaZPhdjZVW3sdk6LXEGzHb7p
  26. Mfr7SEy3SXHyBSxJ3J2ncNNYVJsXG6Me10nj4cfCRFdTFjLo7q3SiCpjjEDM
  27. .nvra.GN39.E2CDTHWXPo8.xzfqrHCHKnf5QUYUVdoZPUjCSC7LU8.XtTUXl
  28. X8vr51GjwFGLC2AlMdLkU4RiaRrnmJuiudnDk0ZW+9p6TuKBe433JUCzp6fU
  29. iOF0SUk2UQYUPNTEkiZubvKa1tsmgL5SCTXGHnnG0CceLpkpR9Rs28IUESWl
  30. EwWNKfHlg.zj6Ee7S+nE8A+m9F7Cu40u9gMm+aRp3kYYkKd3GDOz5y+c7b96
  31. K9gfvuIK68uNO6g2vUUL80WxihCVFD9vlB30e2SOrmxUb527RZ3nZNrljGrR
  32. 70vs1J9suWuZ3zaHVdG3RIJLgGj2Gfn6TcGcstEfvtH.hpFLlnBndjOLGQAI
  33. z98BXc6yQxghmOn6gZqj0ShPOXhynLOjzCESt+XwE8TxrCvrdXo16rqnLgvb
  34. HaFmbh29QD+K0DyNdjDwvzQL.NXpoMvoOBxkger0HwMRQbpbCh91fjjG9Idw
  35. prTH9SzaSea5a.GQEPnnh43WNefMlsOgx18n.vgUNO.tKl7tDyI3iHzafJHZ
  36. VVNedVEbGgYIY42i93prB0i7B7KT1LnnCiyAiinpBnsPV7OG.tYKfBsrJOkG
  37. UG5aq26iJw6GyJ4eM5mEgEKaNQPMEBUp.t8.krplOVTlZdJAW27bjvGK7p2p
  38. HQPgLOSJDYv4E9gQBYBjMUselRxDy+4WplIzm9JQAWOEmfb.E364B43CAwp5
  39. uRRDEv8hWXprjADMUOYpOg9.bVQpEfhKgGCnAnk.rghBJCdTVICA3sDvAhE5
  40. oU4hf67ea5zWPuILqrD8uiK+i477fjHIt9y.V88yy3uMsZUj7wnxGKNAdPx5
  41. fAZMErDZOcJU4M01WFQokix.pKa+JE1WacmnKFeYd7b.0PeIzB8Kk+5WIZpB
  42. Ejt34KJeHgOCh4HK8Y3QiAkAfs8TRhhOkG7AAGQf0qxyfmQxa+PLb8Ex.2PS
  43. 4BdO5GB9Hvg+cfJCMofAIMu9Qz+UPCjckqVJlEmyA8Bf.rC6.3hAEuG8TdTU
  44. bZljQ0nr1ayIqmTwQYfyRGafZhur5vfuyMSqYNWmtAPwWHalDSuUgT0Bosh.
  45. JpAR89Y6Ez5QEfPTQO4J0DHLInIliz8BZV2JfV3Bd36qsQwAVVXbr1BGXp6s
  46. Sd5sSDruo74wofx.HxUgxQwTnMLqTXvRmiGh2PUZr5pBynKChjl6feNUjSRn
  47. hEUfRPT1GfG9Ik4TQBm.hEZZ.bc38HjAMKGzDRijEm1ifx1dbgzQyKh6FZc3
  48. wOCkRJH+KUh0daWs6wzltWx1puXxlWW6NZWY2JiTBzzILRIANku02NourySM
  49. VI1VJTvQZff32AJr+dS9e34QAoA6EGXlGFH9yk7yyQAlVd3SR94g+TxOu1sU
  50. Flgd6ICI96LzazyPu1cgqsZ8r74SgF.65+efbMf4pGHT7lgHh30Sha3N5Ia.
  51. oqjMf7nsuMwycf7iYDybiAAVr3eC.oTMjpzEr8GDRc9bFRGHYXDrzg.Tlx+q
  52. NW8TY1IkzCfZ2IftkQstbB08HUezoDS+oFyI.cWIhWBaDiUo7qIrDO7f.L6n
  53. AXqCmyNT9act.z+Iv.GR0uES0ZXfjdz.IczAxQOUR+zvRsUTigRxmyPYeNlj
  54. yXv8Peef2ZFzuLzWPPeAE8ELzWXYlhe8WzAcUg+b1UkIoCLzIH60zwASGXau
  55. a1Dq2nUY.sox4vng+m0nACePngC9lEMLZMBPodOxf+yx5d4uMCTHm3kJvIIG
  56. jcLMedEQldkjpoBkQyjY1Hk.hmSY95Iwos8NDb9VSlIWOIntqgxryUjL6bCJ
  57. y1lli5tWWxrQ7YmqGYlc6shK1iY2dr0wtNjYxgHyzaq0OznY235awCr8zSz6
  58. EGd1QNUKf.74dADTBbTbeotjpW95IolY0WpKYONY8M83Rx2MChx3fL+iG5Mm
  59. tXpdmvXj8uTvaAL1WjbbarQD4Z6kXBpnm6a69oKV2PY9WY174IbC3CaRQ9iK
  60. Q4sYGQpwdtZ5wFrc7n569.M83OOR5ydSB1ZcAWCxdbKuavz9LILxfD.wWO.W
  61. Nq+Zu4Es+AP6s5p9jDWH8ET+c85+XbW0.N1nDCTD7U4DGc6ohnU019fS7kQ0
  62. o43luuOGjv5agHp0DT.CysOfgLR3xXlXTUKm16RivRsn3z0O6cl3YScAvtrb
  63. hwekGB7BZuqESUzBJWmCvK7t9HF8Ts6cUAPoFWso3aP8ApWyJ3wqOPo2pJDC
  64. BQ0NI0Pj8QCQ2r1L5vKaU5lDRYX7yRur1UYYZmJQ9iDHwN9dndB5n5ejflmm
  65. UsBwLHnDkKXWRuAkb3NeuzqRstiQGP.fCQFdHNzaE.8u58Nz9svFE9SGIE1X
  66. kv9Iwfl1BdNWjA7xcThsWCS847loyFD8pZq2E2F04lYULzBTDYhrFSDDJdjo
  67. fisN2NUN26e4xRu51zD5ZseJ4HC63WyIX6jRqsp0jangBnK.Qlo58PCpWevt
  68. ahzqK7fbKsdX6R64aao8LmWhBPh9jKVAPMzb5a2cV6opdWHneMmqMEmAGsPh
  69. ieigIjV+4gF1GgbMNXg+NH44YaRYyd..S1ThHzKhFwwGRaWVITqyj9FvPqMT
  70. d0pDuSqDrOGF.Uogf.juCFi9WAUkYR+rFPanDcPG8SbrtjyG03ZQ8m3AqC5H
  71. NcUUoXSwVrqXKVcZu.5ZnkwIfIVdXVZTwAuTTUiYuxwjZDK6ZgnRtYV8tJmP
  72. hEcuXgz2Goxyaiw35UkaWbpqtfzD02oUkkYqi.YQbZqIIWrIljFolsdmMKFR
  73. wCJ2+DTn.9QlkOld+d9Qy9IJdpLfy05Ik2b8GsG9h8rdm1ZFx1FrmmlA2snw
  74. qI9Mcdi2nr6q3Gc87nLawurbw1dda+tMyGJ9HaQmlkGwy6davisMgrkM65oz
  75. eulfYCzG46am8tSDK144xV4cEvVMTRXq9CIX8+ALNWb6sttKNkiZetnbz+lx
  76. cQnb1Nds2C0tvLNe14hwQtxYbxhqc17qHfamUcZZ3NYSWqjJuiDoizZ+ud2j
  77. naRK4k3346IIVdR1kKiQjM39adMamvc6n+Xp36Yf3SIGh3uKbquqs1JksTII
  78. kuJ7RrZSFb2Cn9j5a6DT8cMo0iczU+lsYaU8YNVh5k5uzJLU26ZcfuJE6XLY
  79. 0mcRp9NTCp+L+Ap+in7Xf3b9jFQBLtIY06PbrGhcrU6N00Qlaf9N0+QPo9nS
  80. P6qsI7aYNLSNOHpsAxis0ggnZLjYqyyFkdSqinVsPaqSDZaYBZ6c93uLCjGm
  81. iCroJVLzU45iNE.pIUfs3TWb.0FejHp9uANr0GcJPTroFDNOHpkIweLnI1QT
  82. dHl3P7LhOF3Ahd9rnvLwAMy5JSdNezGlsIsW9mW44r26js+alhxjlkdhN0YE
  83. YqiH5MTeWo6D4Qm.ieLS7OynmuVGSbmbFUlnWWhiQlhOeN+Yl35bq.tGo9JR
  84. cj8AVqdz7nSgVB9zNj.FTOU68o5d9KO5TUOGxVMw+jTO8T6wqD0hEiHsOJO5
  85. TTOMoS.zlqN0SpZjz6GcH05ylVM0jwuidlkmAif374ih5M5QPfccr8Hqifff
  86. otN8pt3hUcaWu8nosBhwmD0Epw5KmoF.poxy4YHbnjqfPJqcM3Y2vun7nS.i
  87. f3eETiqcRX2LR.4QmhZrkoCSGwzZrqKHrVR8caari+55d2caPqmq5n.ywe8Q
  88. WrZL9fpwVXeaogMByE6y1SMdjk+gbavbN7fYvVtt1C2XwHJSzpk+tidUO25H
  89. UB9onw9mlFQ10fhpZBaDatcMTTEGcJpwzqg92qqiVtM6Cu0IRQ0ndEdfCAqV
  90. l0qYAUmPrctbxO4XCuPMa1asYzKDks1D52ZCne6Mednz9qW8+.vfqkDA
  91. -----------end_max5_patcher-----------

Скопируйте патч к Max (он указан выше) и вставьте его в новое окно.

Max5SerialCallResponse.png

См.также

  1. serial.begin()
  2. serial.available()
  3. serial.print()
  4. analogRead()
  5. Dimmer
  6. Graph
  7. Physical Pixel
  8. Virtual Color Mixer
  9. Serial Call and Response ASCII
  10. Serial Input (Switch (case) Statement)

Внешние ссылки

  1. Arduino - Serial Call and Response (handshaking)