Текст внутри структуры

Тема в разделе "Микроконтроллеры AVR", создана пользователем Tomasina, 22 авг 2017.

Метки:
  1. Tomasina

    Tomasina Иномирянин

    Есть структура:
    Код (C++):
    struct          // структура пакета данных
    {
      byte thisDeviceID;
      int  status;
    }  Message;
    Вот ее использование:
    Код (C++):
     Message.thisDeviceID = rs485myAddress;
    Message.status = 0;
    Как добавить в структуру текст, чтобы можно было писать так:
    Код (C++):
    Message.text = "Comment";
     
    BAR__MEN нравится это.
  2. rkit

    rkit Гуру

    Добавляем поле String text
     
  3. Tomasina

    Tomasina Иномирянин

    Не выходит что-то.
    Master:
    Код (C++):
    #include <RS485_non_blocking.h>
    #include <SoftwareSerial.h>

    #define RS485_RX_PIN          6
    #define RS485_TX_PIN          5
    SoftwareSerial rs485(RS485_RX_PIN, RS485_TX_PIN);  // receive pin, transmit pin

    struct          // структура пакета данных
    {
      byte thisDeviceID;
      byte destinationID;
      int  value;
      String msg;
    } data;

    size_t fWrite(const byte what)
    {
      return rs485.write(what);
    }

    RS485 network(NULL, NULL, fWrite, 0);

    void setup()
    {
      Serial.begin(9600);
      rs485.begin(9600); // software serial for talking to other devices
      network.begin(); // initialize the RS485 library
    }  // end of setup

    void loop()
    {
      //const byte msg[] = "Hello world";  // Этот вариант передается корректно. Только почему "byte"?
      //network.sendMsg(msg, sizeof (msg));

      memset(&data, 0, sizeof(data));

      data.thisDeviceID = 3;
      data.destinationID = 0;
      data.value = 8;
      data.msg = "Test point";

      network.sendMsg((byte *) &data, sizeof data);

      delay (1000);  
    }  // end of loop
     
    Slave:
    Код (C++):
    #include <RS485_non_blocking.h>
    #include <SoftwareSerial.h>
    #define RS485_RX_PIN          6
    #define RS485_TX_PIN          5
    SoftwareSerial rs485(RS485_RX_PIN, RS485_TX_PIN);  // receive pin, transmit pin

    struct          // структура пакета данных
    {
      byte thisDeviceID;
      byte destinationID;
      int  value;
      String msg;
    } data;


    int fAvailable()
    {
      return rs485.available();
    }


    int fRead()
    {
      return rs485.read();
    }

    RS485 network(fRead, fAvailable, NULL, 20);

    void setup()
    {
      Serial.begin(9600);
      rs485.begin(9600); // software serial for talking to other devices
      network.begin(); // initialize the RS485 library
    }  // end of setup

    void loop()
    {
      if (network.update())
      {
        //    Serial.write(network.getData(), network.getLength());  это работает с byte msg[] = "Hello world"
        //  Serial.println();

        memset(&data, 0, sizeof (data));
        int len = network.getLength();
        if (len > sizeof (data)) len = sizeof (data);
        memcpy(&data, network.getData(), len);

        Serial.println(data.thisDeviceID);
        Serial.println(data.destinationID);
        Serial.println(data.value);
        Serial.println(data.msg);
        Serial.println();
      }
    }  // end of loop
     
    Результат:
     
  4. rkit

    rkit Гуру

    Это уже совсем другой вопрос.
    Вот так данные сериализовывать не следует.
    Нужно определить четкий формат, четко его сформировать и переслать.
     
  5. Tomasina

    Tomasina Иномирянин

    а в чем тут бяка?
     
  6. rkit

    rkit Гуру

    Ну в первую очередь в том, что у строки бывает разная длина, а sizeof data - константа.
     
  7. Tomasina

    Tomasina Иномирянин

    если String заменить на unsigned char* msg[32]?
     
  8. rkit

    rkit Гуру

    Ну если без указателя. Но это все равно плохая практика и может не работать, если принимающая и отправляющая железка разные.
     
  9. Tomasina

    Tomasina Иномирянин

    все железки в сети - Uno и Mega2560.
    Как тогда сделать правильно?
     
  10. rkit

    rkit Гуру

    Проще всего взять какой-нибудь существующий формат обмена данными, и воспользоваться готовыми библиотеками. Например вот выглядит прилично, но я не пользовался https://github.com/HEADS-project/arduino_msgpack
    А самостоятельно городить это довольно много возни.
     
    Tomasina нравится это.
  11. ostrov

    ostrov Гуру

    Массив char должен срадобать теоретически. Поле же фиксированной и известной длины, в отличии от String. Я так понимаю так формируете пакеты для передачи данных по RS485?
     
  12. Tomasina

    Tomasina Иномирянин

    теоретически да, но, похоже, протокол автора исходного скетча не предполагает передачу текстового массива внутри struct. А жаль, ибо это подходящий для меня скетч - он реализует мультимастера в сети (каждое устройство может быть мастером в свой временной слот, в остальное время slave).
    Пришлось отказаться от строк и использовать цифровую замену.
     
  13. ostrov

    ostrov Гуру

    Я делал мультимастера, работало без текста. Но в итоге вернулся к мономастеру, показалось что так надежнее для одноранговой сети. А вот когда сеть двух и более ступенчатая, тогда приходится использовать элементы мультисастера. Но все равно не знаю куда там текст пригодился бы.