SI4432 и GY-521

Тема в разделе "Проводная и беспроводная связь", создана пользователем 4aini4ek, 18 июл 2019.

  1. 4aini4ek

    4aini4ek Нуб

    Всем привет.

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

    Передатчик состоит из контроллера Arduino NANO, гироскопического датчика GY-521 и датчик температуры и влажности DHT11.
    С радиомодулем работаю впервые, почитал тут про библиотеку, которая используется для работы, вроде разобрался с принципом написания кода.
    Радио модуль SI4432 подключается следующим образом:
    SDN -> GND
    nIRQ -> 2
    nSEL -> 10
    SCK -> 13
    SDI -> 11
    SDO -> 12
    VCC -> 5V (на некоторых источниках подключают к пину 3,3V, но у меня при подключении к данному пину не работал, всегда теряет сам модуль при инициализации. Поэтому включил в 5V и отлично работает)
    GND -> GND

    Запускал программы, которые предоставляются в библиотеке RF22, все работает. Дальше я решил передать показания с GY-521 на сервер. Датчик GY-521 подключил следующим образом:
    VCC - 5V
    GND - GND
    SCL - A5
    SDA - A4
    INT - 2 (подключил, так как требовалось в примере. Тут как раз у меня возникает вопрос, а можно ли подключиться к 2-ому пину, когда уже подключен туда nIRQ?)

    Программу для GY-521 взял из примера, который предоставляется в библиотеке MPU6050 и не много переделал под себя, причем если переделанную программу использовать без радио модуля, то она работает как ни в чем не бывало, как только я прописываю инициализацию радиомодуля, то все... Во время работы выдает ошибки, как я понял что-то связано с памятью, но могу ошибаться. Прошу помочь, может кто с подобным встречался?

    И есть какой-нибудь хороший пример, в котором рассматривается работа с GY-521?

    Код (C++):
    #include <SPI.h>
    #include <RF22.h>

    #include <I2Cdev.h>
    #include "MPU6050_6Axis_MotionApps20.h"

    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        #include "Wire.h"
    #endif

    RF22 SI4432Client;
    MPU6050 MPU56050Sensor;

    /*
      Переменные для работы с MPU6050
    */


    bool dmpReady = false;  // set true if DMP init was successful
    uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
    uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
    uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
    uint16_t fifoCount;     // count of all bytes currently in FIFO
    uint8_t fifoBuffer[64]; // FIFO storage buffer

    // orientation/motion vars
    Quaternion q;           // [w, x, y, z]         quaternion container
    VectorInt16 aa;         // [x, y, z]            accel sensor measurements
    VectorInt16 aaReal;     // [x, y, z]            gravity-free accel sensor measurements
    VectorInt16 aaWorld;    // [x, y, z]            world-frame accel sensor measurements
    VectorFloat gravity;    // [x, y, z]            gravity vector
    float euler[3];         // [psi, theta, phi]    Euler angle container
    float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector

    // packet structure for InvenSense teapot demo
    uint8_t teapotPacket[14] = { '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' };

    volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
    void dmpDataReady() {
        mpuInterrupt = true;
    }

    /*

    */


    void setup() {
      #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
        TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
      #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
      #endif

      Serial.begin(115200);
      Serial.println(F("Initializing I2C devices..."));
      MPU56050Sensor.initialize();

    // verify connection
      Serial.println(F("Testing device connections..."));
      Serial.println(MPU56050Sensor.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));

    // load and configure the DMP
      Serial.println(F("Initializing DMP..."));
      devStatus = MPU56050Sensor.dmpInitialize();

    // supply your own gyro offsets here, scaled for min sensitivity
      MPU56050Sensor.setXGyroOffset(220);
      MPU56050Sensor.setYGyroOffset(76);
      MPU56050Sensor.setZGyroOffset(-85);
      MPU56050Sensor.setZAccelOffset(1788); // 1688 factory default for my test chip

    // make sure it worked (returns 0 if so)
      if (devStatus == 0) {
      // turn on the DMP, now that it's ready
        Serial.println(F("Enabling DMP..."));
        MPU56050Sensor.setDMPEnabled(true);

      // enable Arduino interrupt detection
        Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
        attachInterrupt(0, dmpDataReady, RISING);
        mpuIntStatus = MPU56050Sensor.getIntStatus();

      // set our DMP Ready flag so the main loop() function knows it's okay to use it
        Serial.println(F("DMP ready! Waiting for first interrupt..."));
        dmpReady = true;

      // get expected DMP packet size for later comparison
        packetSize = MPU56050Sensor.dmpGetFIFOPacketSize();
      } else {
        /*
          Error
          1 - initial memoyr load failed
          2 - DMP configuration updates failed
      */
     
        Serial.print(F("DMP Initialization failed (code "));
        Serial.print(devStatus);
        Serial.println(F(")"));
      }

      if(!SI4432Client.init()) {
        Serial.println("SI4432 no init...");
      } else {
        Serial.println("SI4432 - running...");
      }

      SI4432Client.setTxPower(RF22_TXPOW_8DBM);
      SI4432Client.setFrequency(446.0);
     
      SI4432Client.setModemConfig(RF22::GFSK_Rb4_8Fd45);
    }

    String stringData = "";
    int flag = 1;

    void loop() {
      UpdateValueMPU6050(1);
      /*
      if(flag == 1) {
        UpdateValueMPU6050(1);
        flag = 2;
        Serial.print("flag: "); Serial.println(flag);
      } else {
        Sending(stringData);
        flag = 1;
        Serial.print("flag: "); Serial.println(flag);
      }
      */

    }

    void UpdateValueMPU6050(int ParameterSettingsDevice) {
      if (!dmpReady) return;
      while (!mpuInterrupt && fifoCount < packetSize) {
       
      }
     
      mpuInterrupt = false;
      mpuIntStatus = MPU56050Sensor.getIntStatus();
      fifoCount = MPU56050Sensor.getFIFOCount();

      if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
      // reset so we can continue cleanly
        MPU56050Sensor.resetFIFO();
        Serial.println(F("FIFO overflow!"));
       
      } else if (mpuIntStatus & 0x02) {
        while (fifoCount < packetSize) fifoCount = MPU56050Sensor.getFIFOCount();
        MPU56050Sensor.getFIFOBytes(fifoBuffer, packetSize);
        fifoCount -= packetSize;

        if(ParameterSettingsDevice == 1) {
          // display Euler angles in degrees
          MPU56050Sensor.dmpGetQuaternion(&q, fifoBuffer);
          MPU56050Sensor.dmpGetGravity(&gravity, &q);
          MPU56050Sensor.dmpGetYawPitchRoll(ypr, &q, &gravity);
         
          Serial.print("ypr\t");
          Serial.print(ypr[0] * 180/M_PI);
          Serial.print("\t");
          Serial.print(ypr[1] * 180/M_PI);
          Serial.print("\t");
          Serial.println(ypr[2] * 180/M_PI);

          /* Формирование строки данных */
          stringData = String(ypr[0] * 180/M_PI) + " "
            + String(ypr[1] * 180/M_PI) + " " + String(ypr[2] * 180/M_PI);
        }

        if(ParameterSettingsDevice == 2) {
        // display quaternion values in InvenSense Teapot demo format:
          teapotPacket[2] = fifoBuffer[0];
          teapotPacket[3] = fifoBuffer[1];
          teapotPacket[4] = fifoBuffer[4];
          teapotPacket[5] = fifoBuffer[5];
          teapotPacket[6] = fifoBuffer[8];
          teapotPacket[7] = fifoBuffer[9];
          teapotPacket[8] = fifoBuffer[12];
          teapotPacket[9] = fifoBuffer[13];
         
          Serial.write(teapotPacket, 14);
          teapotPacket[11]++; // packetCount, loops at 0xFF on purpose
        }
      }
    }

    void Sending(String strData) {  
      uint8_t sendData[20];

      strData.toCharArray(sendData, sizeof(sendData));

      SI4432Client.send(sendData, sizeof(sendData));
      SI4432Client.waitPacketSent();

      uint8_t getData[RF22_MAX_MESSAGE_LEN];
      uint8_t lengthData = sizeof(getData);

      if(SI4432Client.waitAvailableTimeout(1000)) {
        if(SI4432Client.recv(getData, &lengthData)) {
          Serial.print("Got reply: ");
          Serial.println((char*)getData);
        } else { Serial.println("SI4432 Server receiver failed..."); }
      } else { Serial.println("No reply, is RF4432 server running?"); }
    }
     
    Последнее редактирование: 19 июл 2019
  2. parovoZZ

    parovoZZ Гуру

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

    подключиться откуда и чем? Тестером в режиме вольтметра - можно, в режиме амперметра - нет. Из программы - тоже можно,

    даташит.

    Раз описание и текст ошибок не приводится, значит оно под грифом секретно. А с секретными данными мы не работаем - допуска нет.
     
  3. 4aini4ek

    4aini4ek Нуб

    Ой... Вчера хотел вставить код, так и забыл его добавить...
     
  4. 4aini4ek

    4aini4ek Нуб

    Я данный скетч загружаю на Arduino Nano с подключенным радио модулем SI4432 и GY-521, как описывал выше, и при работе в Serial port выводит: FIFO overflow!, но порой там промелькивают значения положения в пространстве. Если же я отключу полностью радио модуль, то все работает нормально и никаких других сообщений не выводится.
     
  5. 4aini4ek

    4aini4ek Нуб

    Подключать контакт INT гироскопа GY-521 и контакт nIRQ радио модуля SI4432.
     
  6. parovoZZ

    parovoZZ Гуру

    А можно сцепить два трактора вместе и чтобы они поехали в противоположные стороны?
     
  7. b707

    b707 Гуру

    В ардуино два пина внешних прерываний, поэтому подключите один модуль на пин2, а другой на пин 3
    Только не забудьте сменить номер прерывания в программе
     
  8. parovoZZ

    parovoZZ Гуру

    Если речь про AVR, то там их не два, а все, которые помечены PCINTх.
     
  9. b707

    b707 Гуру

    речь про ардуино. Почитай ТС - я не уверен. что он в ардуино-то прерывания найдет
     
  10. parovoZZ

    parovoZZ Гуру

    stm - это тоже ардуино. Там вроде кто-то и SAM уже воткнул. И 25 аттиньку тоже. Поэтому надо уточнять.
     
  11. Onkel

    Onkel Гуру

    Due на AT91SAM3X8E