C ++ Союз с функциями, ошибка компилятора Arduino "не может быть перегружен" - PullRequest
0 голосов
/ 08 мая 2019

Я пишу библиотеку для Arduino и теперь застрял при преобразовании байтового массива с неправильным порядком байтов в float, uint32 или uuint16.

Я получил рабочий код, в котором я использую memcpy для копирования массива, обращенного для правильного порядка байтов, в память с плавающей запятой, но теперь я обнаружил, что union { uint8_t bytes[4]; float result; } - это быстрый и эффективный способ сделать то же самое, но с использованием меньше ресурсов.

Концепция, которую я создал, работает на моем ПК (C ++ 14 на Windows 10 с использованием Cygwin), но она не будет компилироваться в Arduino IDE для моего Arduino, потому что 'float Converter::ToFloat(uint8_t*)' cannot be overloaded, и я понятия не имею, где компилятор получает Идея, что я что-то перегружаю.

union Converter {
  float ToFloat(uint8_t data[]) {
    inValue[0] = data[3];
    inValue[1] = data[2];
    inValue[2] = data[1];
    inValue[3] = data[0];
    return floatOutValue;
  };
  uint32_t ToUint32(uint8_t data[]) {
    inValue[0] = data[3];
    inValue[1] = data[2];
    inValue[2] = data[1];
    inValue[3] = data[0];
    return uint32OutValue;
  };
  uint32_t ToUint16(uint8_t data[]) {
    inValue[0] = data[1];
    inValue[1] = data[0];
    return uint16OutValue;
  };
private:
  uint8_t inValue[4];
  float floatOutValue;
  uint32_t uint32OutValue;
  uint16_t uint16OutValue;
};

void setup() {
  uint8_t t1[4] = {0x0A, 0xC3, 0x53, 0x48}; //180573000
  Converter converter;
  Serial.println(converter.ToUint32(t1));
  uint8_t t2[2] = {0x07, 0xE3}; //2019
  Serial.println(converter.ToUint16(t2));
  uint8_t t3 = 0x05; //5
  Serial.println(t3 * 1);
  uint8_t t4[9][4] = {
    {0x3F, 0x7F, 0xCC, 0x8C}, //0.99921
    {0x3D, 0x21, 0x43, 0x00}, //0.039371
    {0x3B, 0x92, 0x07, 0xDF}, //0.0044565
    {0xBD, 0x21, 0xBE, 0x6E}, //-0.039488
    {0x3F, 0x7F, 0xAE, 0x7E}, //0.99876
    {0x3C, 0xF9, 0x64, 0x38}, //0.030443
    {0xBB, 0x55, 0x26, 0x18}, //-0.0032524
    {0xBC, 0xFA, 0xA3, 0x24}, //-0.030595
    {0x3F, 0x7F, 0xE0, 0xFC}, //0.99953
  };
  for (int i = 0; i < 9; i++) {
    Serial.println(converter.ToFloat(t4[i]));
  }
}

Итак, почему этот код не компилируется для Arduino, но отлично работает на Windows 10 с правильными выходами? Что на самом деле означает ошибка компилятора?

1 Ответ

0 голосов
/ 10 мая 2019

Решение: не пытайтесь делать то, что я делал на Arduino, если оно не работает.

Я обнаружил, что если я удаляю все функции внутри объединения, кроме одной, он будет компилироваться, если эта функция имеет параметрlist (uint8_t data []), но не тогда, когда я добавляю второй параметр в список параметров, и я понятия не имею, почему.

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

static union {
    float floatValue;
    uint32_t uint32Value;
    uint16_t uint16Value;
    uint8_t inValue[4];
};

float bytesToFloat(uint8_t data[]){
    inValue[ 0 ] = data[ 3 ];
    inValue[ 1 ] = data[ 2 ];
    inValue[ 2 ] = data[ 1 ];
    inValue[ 3 ] = data[ 0 ];
    return floatValue;
}
uint32_t bytesToUint32(uint8_t data[]){
    inValue[ 0 ] = data[ 3 ];
    inValue[ 1 ] = data[ 2 ];
    inValue[ 2 ] = data[ 1 ];
    inValue[ 3 ] = data[ 0 ];
    return uint32Value;
}
uint16_t bytesToUint16(uint8_t data[]){
    inValue[ 0 ] = data[ 1 ];
    inValue[ 1 ] = data[ 0 ];
    return uint16Value;
}

void setup() {
    uint8_t t1[4] = {0x0A, 0xC3, 0x53, 0x48}; //180573000
    cout << bytesToUint32(t1) << endl;
    uint8_t t2[2] = {0x07, 0xE3}; //2019
    cout << bytesToUint16(t2) << endl;
    uint8_t t3 = 0x05; //5
    cout << t3 * 1 << endl;
    cout.precision(5);
    uint8_t t4[9][4] = {
            {0x3F, 0x7F, 0xCC, 0x8C}, //0.99921
            {0x3D, 0x21, 0x43, 0x00}, //0.039371
            {0x3B, 0x92, 0x07, 0xDF}, //0.0044565
            {0xBD, 0x21, 0xBE, 0x6E}, //-0.039488
            {0x3F, 0x7F, 0xAE, 0x7E}, //0.99876
            {0x3C, 0xF9, 0x64, 0x38}, //0.030443
            {0xBB, 0x55, 0x26, 0x18}, //-0.0032524
            {0xBC, 0xFA, 0xA3, 0x24}, //-0.030595
            {0x3F, 0x7F, 0xE0, 0xFC}, //0.99953
    };
    for (int i = 0; i < 9; i++) {
        cout << bytesToFloat(t4[ i ]) << endl;
    }
}
...