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

Arduino:Примеры/SerialCallResponseASCII

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

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

Контакты:

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


Последовательная передача данных методом вызова и ответа с зашифровкой в ASCII [1]

Этот пример демонстрирует передачу данных в виде строк от Arduino к компьютеру при помощи метода вызова и ответа (рукопожатия).

При запуске скетч отправляет по последовательному порту ASCII-строку и повторяет это до тех пор, пока компьютер не даст ответ. Получив его, скетч отправляет компьютеру новые данные – строку с тремя значениями от датчиков (эти значения зашифрованы в ASCII-символы и разделены запятыми), заканчивающуюся символами новой строки и разрыва строки. Отправив их, скетч начинает ждать от компьютера еще одного ответа. Увидеть эти данные можно в окне Serial Monitor. Кроме того, их можно прочесть при помощи Processing (см. код ниже), Flash, PD, Max/MSP (см. код ниже) и т.д. В примерах, указанных ниже, входящая строка «разрезается» по запятым, а результат снова конвертируется в числа.

Сравните этот пример с «Последовательной передачей данных методом вызова и ответа». Они похожи, т.к. оба используют метод «рукопожатия», но конкретно в этом данные от датчиков считываются в виде строк, тогда как в том – в виде бинарных значений. И хотя передача строк требует больше байтов, этот метод хорош тем, что вы за один заход можете отправить сразу несколько значений. Кроме того, такую информацию легче прочесть в Serial Monitor.

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

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

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

Цепь

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

SerialCallResponse-circuit3.png

Схема

SerialCallResponse sch.png

Код

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

Код к Processing

  1. /*
  2. Код к Processing для этого примера:
  3. */
  4. // Этот код не защищен авторским правом.
  5.  
  6. import processing.serial.*;     // импортируем библиотеку Processing для работы с последовательной передачей данных
  7. Serial myPort;                  // последовательный порт
  8.  
  9. float bgcolor;          // фоновый цвет
  10. float fgcolor;          // цвет заливки
  11. float xpos, ypos;           // стартовая позиция шарика
  12.  
  13. void setup() {
  14.   size(640,480);
  15.  
  16.   // выводим список всех доступных последовательных портов
  17.   println(Serial.list());
  18.  
  19.   // я знаю, что на моем Mac самый первый последовательный порт – это тот,
  20.   // который подключен к Arduino, поэтому я сразу вписываю Serial.list()[0].
  21.   // Вам же нужно поменять 0 на номер того порта, который подключен к Arduino у вас.
  22.   myPort = new Serial(this, Serial.list()[0], 9600);
  23.  
  24.   // считываем байты в буфер, пока не увидим символ новой строки («10» в кодировке ASCII):
  25.   myPort.bufferUntil('\n');
  26.  
  27.   // рисуем со сглаженными краями:
  28.   smooth();
  29. }
  30.  
  31. void draw() {
  32.   background(bgcolor);
  33.   fill(fgcolor);
  34.   // рисуем фигуру (т.е. шарик)
  35.   ellipse(xpos, ypos, 20, 20);
  36. }
  37.  
  38. // метод serialEvent будет запускаться автоматически всякий раз,
  39. // когда в буфер попадет набор данных
  40.  
  41. void serialEvent(Serial myPort) {
  42.   // считываем данные, находящиеся в буфере последовательного порта:
  43.   String myString = myPort.readStringUntil('\n');
  44.   // на тот случай, если вы получили не символ новой строки, а что-то еще:
  45.     myString = trim(myString);
  46.  
  47.     // «разрезаем» строку в местах, где находятся запятые,
  48.     // и конвертируем получившиеся значения в целые числа:
  49.     int sensors[] = int(split(myString, ','));
  50.  
  51.     // выводим полученные данные:
  52.     for (int sensorNum = 0; sensorNum < sensors.length; sensorNum++) {
  53.       print("Sensor " + sensorNum + ": " + sensors[sensorNum] + "\t");
  54.     }
  55.     // после каждого вывода данных добавляем символ новой строки:
  56.     println();
  57.     if (sensors.length > 1) {
  58.       xpos = map(sensors[0], 0,1023,0,width);
  59.       ypos = map(sensors[1], 0,1023,0,height);
  60.       fgcolor = sensors[2];
  61.     }
  62.     // отправляем байт (в качестве запроса новых данных):
  63.     myPort.write("A");
  64.   }

Используем в Processing скетч, указанный выше. При изменении данных от датчиков шарик на экране поменяет свою позицию. А если нажать на кнопку, то шарик исчезнет.

SerialCallResponse-output.png

Код к Max

  1. /* Патч к Max/MSP (версия 5) для этого примера:*/
  2. ----------begin_max5_patcher----------
  3. 3640.3oc6cs0jZajE94Y9UzKkeHoVloTeSHkm1II0VkeHIthSs6C1obIjZ.E
  4. KjHRhY7jT4+9d5KBj.jTCAXfoV6x.sj5VmyWet127ed6MCFm8EQw.z2f9.5l
  5. a9yau4F0kjW3FS4aFLO3KgIAEpGaPX174hzxAC02qT7kR80mkkUHPAnBQdbP
  6. BZQVdIZRd1bT4r3BDTmkU0YQPY3r3zoeJWDVpe2ttr6cFhvXt7KhyH8W26f9
  7. USkhiTulrw+1czQUszjrzxzf4B0sdP9dqtS5x4woIhREQiWewrkkUW0oViTD
  8. +GpFASt2Qd0+51akeLzRPIU7DPXagIFnH.4653f9WAKKyxVHRQNcfDXlih2w
  9. puvbdWHAlcTPBRKHg4x5mr74EBMINHV1+iFL.8qG.VMWTTDLUrs.TBH+zAvP
  10. nTEhvvxun9pBd6FWH38DWH6DWv6ItbX.RKBOJ7XbP5ztvDesvhBLb6VTwcOg
  11. DmiBjnXfiIrjjED0CpP490PEmtPExwQA5EGUVjK.CKQJqtcYl0nCMRAJi76D
  12. Z7dQflCCVV1i+ENiTy3AwYaghEA4.KVJx+jHMXbhntJPceO3iBpPOPKtZqtU
  13. jUoXtw28fkEimmEIlOI.3Q4iMT9wO+iLxc9O7sN28928t6Ve8uMYo.7EUN6t
  14. ePVoUW+6E4hOW7CAgeaV1meWd1cuWnYLy8mKhhClGDd25F3ce+C2si1Ud42+
  15. bZ3IQJOXg7q96t80e50YvDjqHw7VvkRTXhHHuKEerRwmqfBFsS.g9h.HZN3X
  16. hJf5Qd+xHZHgzc.mrqeYjbn4E84evfIDUjDtjNwD2iRHV6anmGdbmsfKxTTJ
  17. dd93rjtBJ2U42foCwZDqKfYzKkrh4VgYIY4FxVRmN2646f8ck+xw7KrjzOlZ
  18. ZYAVfdZgKlaWn29FzA8nfdR2quj.3ejflBJnKr.Dwpf13cZBm85P0rPj.rOB
  19. 6fvztPFGkVI0SAPi5NKHmih7E8Ph2e35uOtYN6x6JEQtJVWpV7gRtm2dZy9W
  20. +YMCxLHrEvAknQktDVdY7v82SFosgmSGHO56BRRt6mEEKxRKDnGd+2812h9X
  21. 5GSeODOcAJ.M9YHHAfjPkyD0GIugn.Ht6bQ.7TTS8DoPtCQCQxWobX+jYPUJ
  22. hPn3zgnx7kogphieFZ2j3TwDgH5dzaUscJ77kEnIY4hoYKglVYzcH5KKxJzu
  23. qmgegxl.0MLNGBNDsr.5IUz0iAPZFE.0TtLOEdClQYrAAeORwW+XVo3aP+hb
  24. DHUBCH.mfbEKfGOPyjQhGiCAdNUUBRcQjij4X.u5MZRDzHSyTDQFbcYdHHIM
  25. AzlF1lnoLjKG8UZH5guV1vEkA4kKWbOPGPC9YgjNdJHVy+ZJQ1.Cq.FUWQpA
  26. ke.8DbUwi.YEWBUCDhPyAXCEETFbuhICg9EIRiYnGVjKyt0+io.r+9vrxRz+
  27. Nt7OlJxCRhT35u.X0amlI9X5xEQppQwneJrLarPVU7JkGYWVHz2njevz1UoX
  28. XkoEWOkxDWO9kXYocoTwuzF611zXJyimB3F5qf9nOT9qesryJTJ1EOcV4cIh
  29. IPVWYoOBUMFTl.4sGRRzRT4AOIkRjn8h7LnNJI2mhg6OSk5JZrPJ4i9gfu.R
  30. w+NHLCcpfAMij88n+qTPPMt4UTwj3bAnY.h.aIe.RiAEeF8Pdzx3zLkLUs1Z
  31. mcmczah0FH4ZmpLcp.rVbX3d0zalKhSiKAxBZ9BU2zTP3uPobgL1Q.U0.kl+
  32. jcBZj1AMOpzsJYjdz0n53QXsfYrqELKblH7yUFoDfPVXbrwDGXqCjwjviT7a
  33. rXZbpxOvxzXvpOnPH0GlTJMZog8l2UZJcdPjxjG7ywIYgeFULaInFDk8jpxZ
  34. apvMA4cv9X.7.vaRRGFAcPYHMR0dF2BZC7wEJ2TOKeZnCRD+HzJo.OLWSW6r
  35. qk2wfI6pGf.pdjC4rpfL2YeK8JYloVf93.ocJEvocv9wAcEiMQgBtl.lb0y9
  36. heKnvtGRs+iHOJHM3uaZbN1jDrhED4FfwfLPCEmH8jV.BB0Z+aF.Vkqc4apU
  37. EIb9a5zAcGt5Rf3WdsNJ3R4PXDU0mouHzIca0MWO.KpQjT8oq1SIyqV3mP24
  38. ToxfHpdyOPNqgwoK.W.fxfRNtwsiDSBVlT9ociSMu+jfPQqUtk9paFLMONJK
  39. URFMpq7xUuvOXF1HBuN6ndhzfE6nxPXQkKKFGjKQNyHtSptYYVVRyaspyBD3
  40. CRiA0YQYrlbgHdptY77E4wZk5UWSOf9yJByyRRZzT5673NtiNrvmhiJmoZq5
  41. fI73wKp5DFrBihhmBNxadsxfoEMuRiIbutfVcM4FWuyr.2bvrlNF5.3U+q9C
  42. sKaa5jkMt70iSd8bC2ZbEFUuAa0DWqYF0tJ91p43649br2nZ2usLGuoxrnQq
  43. 6TArNx+1CjRLPpVWf62Kj59ZFRa38Y6D0kRo8AnT8b0g0e4p8+f6.P4sBnaX
  44. TqMmPsOdOcjG+dMtOmdzcgLdIGqjX0J+FAVrmSu.L8fAX19Ky1C.e1.z+IB2
  45. qpeCIUV+.I4fARxQGH0i.9ECVZrhZMTheMCkc4XRMsoCgbef2ZFjaF5MXzaH
  46. n2PQugYmhe0WjdcU47Z1Ukhb6CwFISy2HNtcvtaNRWdshHNVgHcNMUlopRm4
  47. tJByyLXfI0UN6GM7eUiFTm8BMbctZQC8atOegDu6oveXrgpeaGnfaETvsBJN
  48. 6AKuNsT4n+zRVXJtQd+ciEEYKyCq.8ptRTSdBRQrLNcUd5eXcjoa7fyhihZl
  49. UrNQxBYZo5g.vpdt8klkJi1QyPvdH7UFMStbvYu8Amu1nY7ECMKGXBqnY2KH
  50. Z18Jjl4aYNnEYiQWVzrUxytWNzL0VZ14xglI6isN5kAMi2GZlbYPyNma6FqC
  51. aJRs9qEogO+ovfvYFxxjGV07cLnH3QQzm.R.BG7SAkk4wiWVpC2p9jwX23ka
  52. 0zSz4M6e1QZY.8mljMNHwLURqZ9FuzslMk8ZJXtcMPeblVut1XYDhdMCpmjZ
  53. 8BAqsU9DezKxJAa8Hmbbfi+wccuVv7c0qELrEHB+UAhHWzCfCbKPEyBki24Z
  54. clythVwfkYSmlHrPdX8tC5v1iPb5ArPuOWc8NVrRZspq24UxhE0wBcAsMyt2
  55. 2LLuqvkKZRXjEq5CM6S3tq9Zm6HD+8Prm0F+jDWn1paUe+2ZuF259kxkiR5W
  56. Qf6vzKBtMm+gFrMeuWsKW.6B61VyWOFjz0Zsmwza+.ikxQcAL3iDtbLWMTKm
  57. OtyMEFcjWM9iu0rMa81D8kUl3v2ewcHWP5B2HX6kK7t7DL5fs6JVIrO0Z1l3
  58. bEpOP3zih9.gbspPzKDYbRVAQ7CFhtZsYzhW1ko0WEJcG3oAC0aRIyxKsUEI
  59. +iDPwOLfp0uNA68MmtSUSmRuNb8d1ttWya7sVWf5Iwf.1LQtZUnqNvT1bS6z
  60. E5o2vfqNSH5bufQbuZV09M.E04Mj8XBUiBqNGl5FSt3NGlZaGRpV6wc4kiWi
  61. q0twaaORhul1jjsIi7cMjQlJJUaQuhR495nlfRQWRJXkrgmMGXWjKM4jdGJH
  62. yovkl4HUetutzWuY5tjFHneGn77rtG3iJ92whCVJxKhBwgGtRaFIzabfNrRn
  63. WThd9q24vsZjf9JvHwOKBhprFDmtXYIZ7xISjaO1GE4OK2V9yiS.qFhvrznh
  64. 8cKyMZs7EVepT01FlCe0rIC0lUk6NX4N9syCyAE660+ovE9hyGqjaGurrLak
  65. G0YwoMlFO4YMSZjd9DcWucsjUr1Yqgy8TluCY3N9Q8.+k0JCD3ZTS0CW8Qyb
  66. s19nOxrgjw7VFU+3ooYviK66pCfimt8AAxHOOBkK+EajC2yayWtciMzgdvpM
  67. NKORj29YyGcS4wFVlql0wcZTg1yw5wvMNiTpuUzpu.Y0miRlgO0w7wpZI2Em
  68. SUBGayVM5eqU4C+rV4ZSPkvXqLJbAHlR3mKwT5ISL8+Kv0k.GWEKwpP3ewk3
  69. 7omKIN7EtDmp4ZtHk0BfatXgLhgasHgZrVYaY8AIO7fq8Pas1fFzjd4ibwpd
  70. XO4GXOeOG+lcyasNh1R+wVx2yBxeTOT+wiZFYA0P48PNyiiVjAhJlNT4Qvpb
  71. uj3aN2qYqJcBfSWhMbf+YCPcsfbNeTC2l9WNc+5eIlkST0RJgupzIn+kysgC
  72. X6GGXnYpdYfP0GP6MKQXM3N1Ih6XVvcLuym7B0B5w8v.ahqBI49qJcJ.TaX.
  73. N+xBP4NGHhhqYfkRNM9q1f3ZweqyYCQYdGCSZGQ5wBx47o.Ssw+CkcgQOmud
  74. KZic4QKzCw+7ROm8nY2LfMsEDtdfeMKSn5Ev95IQhorcqJcBrzPsQUhRNe8M
  75. 1X6lhOezC4Bidv1nKcFs8YimJ9n8RWZXiO7aSCxDRLdjd91qU5TnmXCeRvmR
  76. 9jnm7b15RmJ9rO4Kr+IgO04BfczyOpqx9npzofOsIlaR8Mo0IUMR48i0mYly
  77. lVMwlw6gbloGRezy4yKEw6BHBBWik.eRi3DNM5KDahS.SOE1EjmXl7Uyqo9T
  78. AtQAO8fG3oLX3cZFxKh0FLNSRfDaoG74gdvW.ZDU9FMGSdFMBt+IQh.6eIvw
  79. FujTkJREGKKcJ3X2WtXf7Ub1HywEqxh2tJnE.FcZhMByrcXQw1x+bOWJYjpy
  80. lv8oq55aEHLcwD8hJjxbVU5EigcNtL7Ql76KVVp69Huhcb87vpoCkRYT+96v
  81. Hd5Ay1rofMqm+FkLYvv0+GL3FkL6bLp21kL6QFNV8BNM48foWBV4zt1wXm5V
  82. 4jkNEbL45dtNw13Iltmi9sAyY0S0l8BR+3yWjVXax7eOmKrp4m0QKIal6VYo
  83. SAf5XQxSrCa5l0qk45k5kAzqEgMNgzkz9FmL5abpnu4IhNzZ+0s+OKCSg0.
  84. -----------end_max5_patcher-----------

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

Max5SerialCallResponseASCII.png

См.также

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

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

  1. Arduino - Serial Call and Response (handshaking) with ASCII-encoded output