2015-07-03 2 views
0

Я очень новый для Arduino и я не могу найти способ сделать следующее. У меня есть ЬурейаЯ структура, которая заполняет несколько значений:Хранить несколько переменных в буфере с memcpy

void loop() { 
accel.process(); 
AccelerationReading accelData; 
accelData.xAxis = accel.xAxis; 
accelData.yAxis = accel.yAxis; 
accelData.zAxis = accel.zAxis; 
//Irrelevant code after this 
} 

После того, как структура заполнена я memcpy его в буфер:

uint8_t buffer[6]; 
memcpy((void*)buffer, (void*)&accelData, 6); 

Теперь это прекрасно работает, но я также нужно прочитать значение из двух аналоговых портов, и эти два значения также необходимо добавить в memcpy. Код, который заполняет две переменные:

//New variables 
int shortflexposition; 
int longflexposition; 
//Filling up the variables. 
shortflexposition = analogRead(shortflexpin); 
longflexposition = analogRead(longflexpin); 

accelData содержит 6 байт исходных значений и теперь я хочу, чтобы добавить shortflexposition и longflexposition после этих байтов. Значения в shortflexposition и longflexposition всегда находятся между 0 и 1023. Как точно следует добавить эти другие переменные в memcpy? Например, я пытался:

uint8_t buffer[8]; 
memcpy((void*)buffer, (void*)&accelData + shortflexposition, 8); 

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

Спасибо! Yenthe

Update: Это попытка на код из Лундин ..

typedef union 
{ 
    struct s 
    { 
    AccelerationReading accelData; 
    uint16_t shortflexposition; 
    uint16_t longflexposition; 
    }; 
uint8_t raw_data [sizeof(struct s)]; 
} my_data; 

void setup() { 
// Bean Serial is at a fixed baud rate. Changing the value in Serial.begin() has no effect. 
Serial.begin(); 
accel.init(); 
} 

void loop() { 
    accel.process(); 
    AccelerationReading accelData; 
    my_data data; 
    data.accelData.xAxis = accel.xAxis; 
    data.accelData.yAxis = accel.yAxis; 
    data.accelData.zAxis = accel.zAxis; 

    //Get flex readings 
    int shortflexposition; 
    int longflexposition; 

    //Read the position of the flex sensor (0 to 1023?) 
    data.shortflexposition = analogRead(shortflexpin); 
    data.longflexposition = analogRead(longflexpin); 
    my_data some_other_data = data; 

    uint8_t buffer[6]; 
    memcpy((void*)buffer, (void*)&accelData, 6); 
    Bean.setScratchData(1,buffer,6); 
    Bean.sleep(1000); 
} 

Но дает следующие ошибки:

GetReader.ino: In function 'void loop()': 
GetReader.ino:54:8: error: 'union loop()::my_data' has no member named 'accelData' 
GetReader.ino:55:8: error: 'union loop()::my_data' has no member named 'accelData' 
GetReader.ino:56:8: error: 'union loop()::my_data' has no member named 'accelData' 
GetReader.ino:63:8: error: 'union loop()::my_data' has no member named 'shortflexposition' 
GetReader.ino:64:8: error: 'union loop()::my_data' has no member named 'longflexposition' 

ответ

1

Прежде всего, это не имеет смысл увеличить размер буфера с помощью 2 байтов, если вы хотите добавить два 16-разрядных номера == 4 байта. Я хотел бы предложить вам сделать что-то вроде этого:

typedef union 
{ 
    struct s 
    { 
    AccelerationReading accelData; 
    uint16_t shortflexposition; 
    uint16_t longflexposition; 
    }; 
    uint8_t raw_data [sizeof(struct s)]; 
} my_data; 


// use whatever compile-time assert you have available to check for padding: 
static_assert(sizeof(my_data) == sizeof(AccelerationReading) + 2*sizeof(uint16_t), 
       "Unwanted padding detected."); 


my_data data; 
data.accelData.xAxis = x; 
data.accelData.yAxis = y; 
data.accelData.ZAxis = z; 
data.shortflexposition = something; 
data.longflexposition = something; 

my_data some_other_data = data; // equivalent of memcpy 

Если вам необходимо получить доступ байт данных байта, вы просто используете data.raw_data[i] вместо этого.


Если вы используете старый компилятор, вам придется изменить код:

typedef union 
{ 
    struct s 
    { 
    AccelerationReading accelData; 
    uint16_t shortflexposition; 
    uint16_t longflexposition; 
    } my_compiler_is_old; 
    uint8_t raw_data [sizeof(struct s)]; 
} my_data; 

data.my_compiler_is_old.accelData.xAxis = x; 
data.my_compiler_is_old.accelData.yAxis = y; 
... 
+0

Спасибо за ваш ответ @Lundin! Я пытался его реализовать, но я получаю ошибки. Я обновил свой вопрос с полным кодом, который у меня есть сейчас! Что мне не хватает? – Yenthe

+0

@Yenthe Обновлен с примером, который будет работать для старых компиляторов. – Lundin

+0

Хм да, похоже, что работает! Итак, как теперь я могу заменить Bean.setScratchData (1, buffer, 6); с новыми данными? Я попытался изменить буфер на some_other_data, но ему нужна переменная const uint8_t. Я не уверен, как мне это преобразовать? – Yenthe

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