2016-03-01 3 views
4

Я пытаюсь отправить & получать данные между малиной Pi (с использованием программирования C) & Arduino (с использованием Arduino IDE).C: Little Endian

Основываясь на том, что я могу найти в Интернете, он указывает на то, что оба они имеют малоформатный формат.

Я посылаю целые числа между ними с помощью последовательной связи (RS232) с библиотекой «RS232 для Linux и Windows» на teuniz.net/RS-232

На основе моих знаний, если оба находятся в маленького формата, мне не нужно делать какие-либо сдвиги на битах. Однако, в моем случае с приведенными ниже кодами, мне необходимо сдвинуть бит, прочитанный Arduino. Я не уверен, почему мне нужно выполнить смещение битов, когда оба они малочисленны (чтобы получить правильные данные). Без лишних слов ....

C Код:

unsigned char buf[4]; 
int g = 100; 
memcpy(buf, (char*)&g, sizeof(int)); 

// port 24 for ttyACM0 
if(RS232_SendBuf(24, buf, sizeof(int)) == -1) 
{ 
    // error processing here 
} 

Arduino Код:

long a[4]; 
long value = 0; 

void loop(){ 
    if(Serial.available()>=4){ 
    for(int i = 0; i < 4 ; i++){ 
     a[i] = Serial.read(); 
    } 

    // Over here i need to shift the LSB of the byte received to the MSB of the long var until the MSB of byte becomes LSB of long var 
    // i do not have the code which is faulty right now as its already past midnight and my group mates are already asleep so I will post again in the morning 
    value += a[0]; 
    value += a[1] << 8; 
    value += a[2] << 16; 
    value += a[3] << 24; 

    Serial.println(value); // now it prints out 100 correctly 

    value = 0; 
    } 

} 

Оценил всяческую помощь! Извините, все еще новичок в C и endian!

ОБНОВЛЕНИЕ: Я думаю, я знаю, почему это происходит! Пожалуйста, прокомментируйте ниже, чтобы сообщить мне, правильно ли я ошибаюсь.

Я отправляю значение int 170 в C. 170 - 0x000000aa в HEX. Когда я memcpy (здесь находится маленький конец), он сохраняется как aa 00 00 00 (от LSB до MSB). Поэтому, когда я получаю значение в arduino, мне определенно нужно будет сделать сдвиг, поскольку целое число считывается с MSB на LSB (и потому, что в arduino нет копии памяти/чтения, мне все равно, не проблема с этой проблемой).

Однако, как Arduino медленно в обработке (он имеет много других материалов для расчета !!), я могу сделать мой C код таким образом, чтобы:

int g = 170; 
unsigned char buf[4]; 
// below line not needed anymore?? 
//memcpy(buf, (char*)&g, sizeof(long)); 

if(RS232_SendBuf(24, (char *)&g, sizeof(int)) == -1) 
{ ... } 

хотел бы услышать больше, так что я могу выучить больше! Похоже, что вначале я понял свои основы, когда задал этот вопрос!

+0

related: http://stackoverflow.com/questions/17461623/byte-order-of-serial-communication-to-arduino – msw

+1

Почему вы комментируете, что 'value + = a [0]; значение + = a [1] << 8; 'является« большим аргументом для малочисленных ». Похоже на чтение маленького эндианта для меня. Никакой «большой эндиан» не участвовал. – chux

+0

@chux я прокомментировал это, потому что теперь я пытаюсь сделать наименее значимый бит, чтобы пройти весь путь влево и MSB до самого правильного! Однако когда я отправляю от малины pi, я уже убедился, что это LSB для MSB от buf [0] до buf [3]! Поэтому не очень понятно, почему на стороне Arduino я получаю MSB для LSB и должен был сделать это преобразование, чтобы правильно прочитать целое число! –

ответ

2

Ваш код выглядит хорошо для меня (я его не запускал).

  • Предположим, что у вас было целое число 0xaabbccdd.
  • На Pi, "buf" будет содержать dd, cc, bb, aa. Они будут отправлены по проводам в таком порядке.
  • На ардуине a также будет содержать dd, cc, bb, aa.
  • Затем вы создаете value как (dd << 0) + (cc << 8) + (bb << 16) + (aa << 24), что дает 0xaabbccdd.
+0

Да, это расстраивает! Мы отправили dd, cc, bb, aa из Raspberry pi в Arduino. Однако, когда Arduino читает из сериала, он печатает aa, bb, cc, dd, если мы не выполняем сдвиг бит! –

+0

Это, вероятно, потому, что ваш 'RS232_SendBuf()' отправляет байты таким образом. На принимающей стороне вы читаете каждый ** байт ** отдельно (а не как ** длинный ** тип). Поэтому не вопрос, является ли ваш Ардуино маленьким эндиантом или большим эндиантом. Пока вы храните байты в том порядке, который вам нужен, Arduino увидит то, что вы написали, как маленький endian. – jada12276

0

Вы анализируете 32-битное малое значение конца, а не значение большого конца. Первый байт заканчивается наименее значимыми битами; последний байт заканчивается в наиболее значительных байтах.

Если вы превращали буфер, который содержал большое значение Endian, код будет выглядеть следующим образом:

uint8_t a[4]; 
int value = 0; 
for (int i = 0; i < 4; ++i) 
{ 
    value << 8 * i; // shift everything over one byte 
    value += a[ i ]; // add the next byte to the LSByte 
} 

Вы видите разницу?

+0

да правильно! Однако, если я не выполняю сдвиг бит, если я посылаю AA 0 0 0, на стороне Arduino он принимается как 0 0 0 AA –

+0

@Doe Joe Код получения 'Serial.println (значение);' конечно не печатает "0 0 0 AA". Что печатает код? – chux

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