отправлять массив Numpy в Arduino через последовательный порт? - PullRequest
0 голосов
/ 14 мая 2019

Я пытаюсь отправить Numpy массивы с плавающей точкой (каждый массив имеет 3 члена), например:

[-1.73921636 -0.47675802 -0.2068679 ]

на Arduino через последовательный порт.

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

import serial
arduino=serial.Serial('com4',9600)

while 1:  
     array = function(x,y,z);
     data=bytearray(array)
     arduino.write(data)
     time.sleep(.5)

Конечно, я не могу использовать последовательный монитор Arduino, поэтому я использую ЖК-дисплей 16x2, чтобы увидеть, что именно я получаю от Python. Все, что я вижу, это случайные символы (часто по-японски!). Я думаю, что это проблема с декодированием массива numpy, потому что я могу увидеть строку, если я вставлю ее в arduino.write(data).

Arduino код:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

char inputBuffer[32];

LiquidCrystal_I2C lcd(0x27, 16, 2);

void setup() {
  Serial.begin(9600);
  lcd.begin();
  lcd.backlight();
}

void loop() {
  if (Serial.available()) {

    lcd.clear();
    delay(200);

    if (Serial.available() > 0) {
      //lcd.print("                ");
      Serial.readBytesUntil('\n', inputBuffer, 32);
      //Serial.read();
      lcd.setCursor(0, 0);
      lcd.print(inputBuffer);
      memset(inputBuffer, 0, sizeof(inputBuffer));
    }
  }
}

1 Ответ

1 голос
/ 15 мая 2019

Когда вы вызываете bytearray в Python, он преобразует массив NumPy в массив байтов. Например, data = bytearray(np.array([-1.73921636, -0.47675802, -0.2068679])) дает вам байтовый массив с 24 элементами (каждый элемент в массиве numpy является двойным, который составляет 8 байтов каждый).

Когда вы читаете это на Arduino, вам нужно снова преобразовать этот массив байтов в удвоения, прежде чем выполнять какую-либо полезную операцию. union было бы полезно для этого. У меня нет ЖК-дисплея, чтобы проверить это, но что-то подобное должно правильно читать байты как двойные.

unsigned char inputBuffer[32];

union {float f; unsigned char b[8];} num1;
union {float f; unsigned char b[8];} num2;
union {float f; unsigned char b[8];} num3;

void loop() {
    if (Serial.available()) {

        lcd.clear();
        delay(200);

        if (Serial.available() > 0) {
            Serial.readBytesUntil('\n', inputBuffer, 32);

            for (int i = 0; i < 8; i++) {
                num1.b[i] = inputBuffer[i];
                num2.b[i] = inputBuffer[8 + i];
                num3.b[i] = inputBuffer[16 + i];
            }

        // you can call the read float numbers using num1.f, num2.f, ...
        // other operations to write to the LCD go here
    }
}

Кроме того, вы можете рассмотреть возможность отправки контрольной суммы CRC в конце сообщения, чтобы быть безопасным. Когда вы отправляете поток байтов, потеря одного байта может привести к действительно странным числам.

...