Передача нескольких значений по serial.

Тема в разделе "Arduino & Shields", создана пользователем greiverff, 11 сен 2012.

  1. greiverff

    greiverff Нерд

    Доброе время суток.
    Подскажите пожалуйста как лучше(как вариант проще) передавать значения нескольких переменных по сериал соединению(точнее при помощи xbee). А так же как их распознать на устройстве.
    Пример: на передатчике 2 потенциометра 2 кнопки, на приемнике 2 мотора и 2 светодиода.
    Как сделать нормальное управление моторами и светодиодами, что бы они не мешали друг другу? Смотреть в сторону прерываний? Может есть еще способ?
     
  2. А как именно?
    Кнопки будут управлять светодиодами, а потенциометр моторами? :D
    Или как у вас?
     
  3. greiverff

    greiverff Нерд

    Да, именно так.
     
  4. hibiki

    hibiki Гик

    так и передавайте. хотите - байтами по 4, две кнопки + два положения потенциометров (от 0 до 255 соотв.), хотите - какой-н протокол придумайте, с контрольной суммой и прочими плюшками. или готовую реализацию любого протокола полегче найдите (не надо это все, скажем, в TCP поверх XBee заворачивать)
     
  5. greiverff

    greiverff Нерд

    "байтами по 4" Будет передаваться 4 переменных? Пример чисто теоретический, на практике больше параметров надо будет передавать(до 7). 4 решил просто для тренировки и пробы пера, так сказать.

    Попробую понять, нужно будет сразу передавать например 7 байт, в каждом из которых значения от 0 до 255, так?
     
  6. hibiki

    hibiki Гик

    хм.. еще раз - как вы реализуете протокол обмена, так и будет

    ну смотрите, например, - у вас есть органы управления, 4 штуки. у каждого из них есть состояние - у кнопок 0 или 1, у потенциометров приведенные к цифровому виду функцией analogRead() - 0..1023.

    значит, простейший пакет данных может выглядеть так
    b1 b2 b3 b4 b5 b6, где байты

    b1 и b2 - по одному байту для каждой кнопки
    b3 и b4 - старший и младший байты для значения первого потенциометра
    b5 и b6 - старший и младший байты для значения второго потенциометра

    и вот это все значение вы передаете. на приемнике разбираете:
    первый байт - включение/выключение светодиода 1
    второй - включение/выключение светодиода 2
    (третий << 8) || четвертый - 0..1023 для первого мотора
    (пятый << 8) || шестой - 0..1023 для второго мотора

    это для примера.
     
  7. greiverff

    greiverff Нерд

    Спасибо, теория примерно понятна. А как на практике реализовать данную передачу и расшифровку байтов? Упрощается тем что после analogRead на передатчике будет функция map приводящая 1024 к 255. Или подскажите какие мануалы почитать. Может ссылкой на какие-нибудь протоколы, подходящие для ардуино, поможете?
     
  8. greiverff

    greiverff Нерд

    Тут подумалось, может можно передавать массив(строковый?), а на устройстве как то распознать нужные переменные(например по специальному разделителю или разным буквам).
     
  9. <Lame>

    <Lame> Гик

    я передаю так:
    A(0...)B(1...)C(2...)D(3...)E(4...)F(5...)
    в данном примере шесть каналов передачи данных
    х... - это данные,
    где х (0; 5);
    По I2C между МК'ами так-же...
     
  10. greiverff

    greiverff Нерд

    Lame, ты передаешь "A(0...)B(1...)C(2...)D(3...)E(4...)F(5...)" как строку функцией serial.println()? А как расшифровываешь на микроконтроллере?
     
  11. hibiki

    hibiki Гик

    а какая, простите, разница между строковой переменной и целочисленной? разве что для 255 уже не байт будет нужен, а два (если записывать в шестнадцатиричной форме: FF)

    greiverff, в чем именно проблема? и зачем мапить значения с потерей точности, если можно передать все?
     
  12. hibiki

    hibiki Гик

  13. greiverff

    greiverff Нерд

    Hibiki, так для управления моторами 255 градаций и так выше крыши.

    Правильно ли будет передавать 6 значений так
    Код (Text):
    for(i=1; i<=6; i++)
    {
      serial.print(x[i]);  \\выводим по порядку 6 значений
      if (i==6) serial.print('\0');  \\выводим в конце символ перевода строки
    }
     
  14. greiverff

    greiverff Нерд

    Я лишь пытаюсь попробовать разные методы передачи данных, так как не одного не знаю. И в последствие выбрать наиболее удобный.

    Спасибо за ссылку.
     
  15. hibiki

    hibiki Гик

    и даже нулевой символ в конце не нужен, если не выводите в терминал, а разбираете на приемнике так же - по шесть байтов. в качестве разделителя пакетов лучше какую-н более информативную последовательность, а не $00. если потеряется серединка пакета, то приемник может подумать, что $00 - это, скажем, "выключено" для определенного канала управления.

    добавьте лучше контроль четности/crc, чтобы была уверенность, что данные не испортились в процессе передачи. то есть в if'е седьмым байтом добавляете "контрольную сумму"
     
  16. greiverff

    greiverff Нерд

    В итоге получится что на ардуину будут отсылаться строки вида:

    10 33 42 250 240 60
    11 37 60 220 225 70
    7 45 88 210 219 99

    то как эти цифры на мк присвоить переменным x1, x2, ... или массиву x?
     
  17. greiverff

    greiverff Нерд

    Я правильно понял как передаются данный на мк? Надеюсь не сильно напрягаю, тем что туплю в очевидных местах?
     
  18. hibiki

    hibiki Гик

    я сам ступил. вам нужно Serial.write()
    и тогда на приемнике берете переменную или массив и присваиваете ей значение Serial.read()

    http://arduino.cc/en/Serial/Read
     
  19. greiverff

    greiverff Нерд

    То есть нужно успользовать
    Serial.write(buf, len)
    где
    • buf: массив байт
    • len: длина массива
    Получается на передатчике:
    Код (Text):
    serial.Write(x[i], 6); \\где x[i] массив 6 длинна его
     
    или
     
    serial.Write(x1 x2 x3 x4 x5 x6, 6);
     
  20. hibiki

    hibiki Гик

    как хотите :)

    в первом случае первый параметр - просто x, без индекса
    во втором
    Serial.write(x1);
    Serial.write(x2);
    ...
    Serial.write(x6);