Arduino:Примеры/SerialCallResponseASCII

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

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


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

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

При запуске скетч отправляет по последовательному порту ASCII-строку и повторяет это до тех пор, пока компьютер не даст ответ. Получив его, скетч отправляет компьютеру новые данные – строку с тремя значениями от датчиков (эти значения зашифрованы в ASCII-символы и разделены запятыми), заканчивающуюся символами новой строки и разрыва строки. Отправив их, скетч начинает ждать от компьютера еще одного ответа.

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

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

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

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

Цепь

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

Схема

Код

/*
 Вызов, ответ и зашифровка в ASCII 
 Язык: Wiring/Arduino
 
При запуске программа отправляет по последовательному порту 
ASCII-символ «А» (байт со значением «65») 
и повторяет это до тех пор, пока не получит ответные данные.
Получив, он отправляет компьютеру еще три разделенных запятой
ASCII-значения, заканчивающихся символами новой строки и разрыва   строки.
 
 Спасибо Грегу Шакару (Greg Shakar)
 и Скотту Фитцджеральду (Scott Fitzgerald) за поправки.
 
  Цепь:
 * потенциометры подключены к 0-ому и 1-ому входным аналоговым контактам 
 * кнопка подключена ко 2-ому цифровому контакту
 
 Создан 26 сентября 2005 Томом Иго (Tom Igoe),
 модифицирован 24 апреля 2012 Томом Иго (Tom Igoe)
 и Скоттом Фитцджеральдом (Scott Fitzgerald). 
 
 Этот код не защищен авторским правом.
 
 http://www.arduino.cc/en/Tutorial/SerialCallResponseASCII
 
 */

int firstSensor = 0;    // первый аналоговый датчик
int secondSensor = 0;   // второй аналоговый датчик
int thirdSensor = 0;    // цифровой датчик
int inByte = 0;         // переменная для байта, передаваемого через последовательный порт

void setup()
{
  // запускаем последовательную передачу данных со скоростью 9600 бит/с и ждем, когда порт откроется:
  Serial.begin(9600);
  while (!Serial) {
    ; // ждем, когда последовательный порт подключится (нужно только для Leonardo)
  }

  
  pinMode(2, INPUT);   // цифровой датчик подключен ко 2-ому цифровому контакту
  establishContact();  // отсылаем байт, чтобы установить контакт (пока по ту сторону не ответят) 
}

void loop()
{
  // если получили нужный байт, считываем данные с аналоговых контактов:
  if (Serial.available() > 0) {
    // берем пришедший байт:
    inByte = Serial.read();
    // считываем данные с первого входного аналогового контакта:
    firstSensor = analogRead(A0);
    // считываем данные со второго входного аналогового контакта:
    secondSensor = analogRead(A1);
    // считываем данные с кнопки (тут два варианта – 0 или 255L)
    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 для этого примера:
*/
// Этот код не защищен авторским правом.

import processing.serial.*;     // импортируем библиотеку Processing для работы с последовательной передачей данных
Serial myPort;                  // последовательный порт

float bgcolor;          // фоновый цвет
float fgcolor;          // цвет заливки
float xpos, ypos;           // стартовая позиция шарика

void setup() {
  size(640,480);

  // выводим список всех доступных последовательных портов
  println(Serial.list());

  // я знаю, что на моем Mac самый первый последовательный порт – это тот,
  // который подключен к Arduino, поэтому я сразу вписываю Serial.list()[0].
  // Вам же нужно поменять 0 на номер того порта, который подключен к Arduino у вас. 
  myPort = new Serial(this, Serial.list()[0], 9600);

  // считываем байты в буфер, пока не увидим символ новой строки («10» в кодировке ASCII):
  myPort.bufferUntil('\n');
  
  // рисуем со сглаженными краями:
  smooth();
}

void draw() {
  background(bgcolor);
  fill(fgcolor);
  // рисуем фигуру (т.е. шарик)
  ellipse(xpos, ypos, 20, 20);
}

// метод serialEvent будет запускаться автоматически всякий раз,
// когда в буфер попадет набор данных

void serialEvent(Serial myPort) { 
  // считываем данные, находящиеся в буфере последовательного порта:
  String myString = myPort.readStringUntil('\n');
  // на тот случай, если вы получили не символ новой строки, а что-то еще:
    myString = trim(myString);
 
    // «разрезаем» строку в местах, где находятся запятые,
    // и конвертируем получившиеся значения в целые числа:
    int sensors[] = int(split(myString, ','));

    // выводим полученные данные:
    for (int sensorNum = 0; sensorNum < sensors.length; sensorNum++) {
      print("Sensor " + 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];
    }
    // отправляем байт (в качестве запроса новых данных):
    myPort.write("A");
  }

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

Код к Max

/* Патч к Max/MSP (версия 5) для этого примера:*/
----------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-----------

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

См.также

  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)

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