2015-12-05 1 views
0

Я написал эскиз Arduino, который считывает данные с приемника удаленного управления и возвращает значение от 0 до 1023 для этого канала. Я в основном хочу отправить эти данные (что-то в формате канала: значение, например, Channel 1: 1023, Channel 2: 511) в программу ПК (которую я планирую написать сам).Лучший способ передать переменные между Arduino и ПК через последовательный порт?

Самый эффективный способ, которым я могу это сделать, - использовать два байта данных, причем первые 6 бит представляют канал (2^6 = 64 возможных канала, путь больше, чем мне нужно), и последние десять представляя значение (2^10 = 1024, совершенное). Но я не уверен, что лучше всего реализовать это на C++, или если это даже самый лучший способ сделать это. Итак:

  1. Каков наилучший способ создания отдельных байтов и работы с двоичными числами на C++? Предпочтительно хранить значения в памяти как таковые (т. Е. Нет массивов bool, где каждый индекс занимает свой собственный байт). Два байта данных более чем достаточно для того, что мне нужно.
  2. Является ли это самым простым/простейшим/наиболее эффективным/рекомендуемым способом реализации того, чего я пытаюсь достичь? Я в основном хочу передавать переменные, как между программами, есть ли другие способы сделать это?

ответ

1

Вы можете объявить упакованную struct держать эти два значения:

struct chan_value_t 
{ 
    uint8_t channel : 6; 
    uint16_t value : 10; 
}; 

Но чтобы отправить его как два байта , вам нужно либо (1) «союз» с ней массив двухбайтным:

union chan_value_t 
{ 
    struct { 
    uint8_t channel : 6; 
    uint16_t value : 10; 
    }; 
    uint8_t bytes[2]; 
}; 

chan_value_t cv; 

void setup() 
{ 
    Serial.begin(9600); 

    cv.channel = 2; 
    cv.value = 800; 
    for (int i=0; i<sizeof(cv.bytes); i++) { 
    Serial.print(cv.bytes[i], HEX); 
    Serial.print(' '); 
    } 
    Serial.println(); 
} 

void loop() {} 

(struct является анонимным, когда вложенные в этот союз, объединение имеет название .)

Or (2) бросить указатель на структуру в указатель на байт:

struct chan_value_t { 
    uint8_t channel : 6; 
    uint16_t value : 10; 
}; 

chan_value_t cv; 

void setup() 
{ 
    Serial.begin(9600); 

    cv.channel = 2; 
    cv.value = 800; 
    uint8_t *bytes = (uint8_t *) &cv; // cast &cv to a pointer to bytes 
    for (int i=0; i<sizeof(cv); i++) { 
    Serial.print(bytes[i], HEX); 
    Serial.print(' '); 
    } 
    Serial.println(); 
} 

void loop() {} 

Обе печатают шестнадцатеричное значение байтов: 0x02 и 0xC8. 800 - 0x320, сдвинутый налево на 6 бит - 0xC800.

Чтобы отправить это на ПК, вы можете начать с специальной последовательности символов и закончить с помощью контрольной суммы какого-либо рода (контрольная сумма Fletcher проста). Тогда легко выбросить мусорных персонажей и узнать, когда есть ошибки при передаче.

+0

Итак, я бы использовал битовые поля, создал объединение с байтовым массивом, а затем прочитал данные «через» массив байтов? Я раньше не использовал битовые поля, поэтому, чтобы прояснить, если я объявляю что-то вроде int myInt: 6, это определит целое число с 2^6 возможными значениями? То же самое с 2^10? –

+0

Итак, я реализовал это на моем конце, но я получаю неожиданное поведение. Кажется, что эти байты печатаются и читаются правильно, поэтому, скорее всего, это не проблема с тем, как я реализовал это решение, но в другом месте моего кода. Чтобы помочь устранить неполадки, есть ли какие-либо проблемы с этим, о которых я должен знать? Например, есть ли какое-либо смещение битов, которое я должен выполнять при назначении переменных, являются ли члены, не упакованные рядом друг с другом в память и т. Д.? –

+0

Кроме того, для контрольной суммы я просто XORed два байта вместе (я понял, что это будет самый простой для двух байтов данных). Любые советы, если это хороший метод? –

1

Это направлено на ваше отсутствие. 2 вопрос.

OSC (OpenSoundControl) - удобный способ отправки сообщений на разных платформах и устройствах. Библиотеки существуют для большинства платформ.

Вы можете использовать библиотеку OSC for Arduino и реализовать свое собственное решение для specification или используя библиотеку, которая соответствует вашему контексту.

сообщение вы уже могли быть отправлены как/канал/1/значение/1023

+0

OSC кажется немного тяжелым для того, что он делает. OSC использует память кучи через 'new/malloc' и' delete/free', что может быть проблематичным в средах с ограниченной ОЗУ, таких как Arduino. Кроме того, сообщение было бы более подробной текстовой строкой (24 байта?) Вместо короткого двоичного пакета (6 байтов?). –

+0

Да, это выглядит немного тяжеловесным, но хорошо знать об альтернативах, которые я имею в наличии, особенно если для них, похоже, есть готовые библиотеки. –

Смежные вопросы