Всем привет. Решил сделает проект с использованию радио модуля 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?"); } }
потому, что модули все разные с разными уровнями. Поэтому сперва необходимо прочитать инструкцию, а потом действовать. В электронике "наугад" всегда приводит к дыму, в электрике - к более тяжелым последствиям. подключиться откуда и чем? Тестером в режиме вольтметра - можно, в режиме амперметра - нет. Из программы - тоже можно, даташит. Раз описание и текст ошибок не приводится, значит оно под грифом секретно. А с секретными данными мы не работаем - допуска нет.
Я данный скетч загружаю на Arduino Nano с подключенным радио модулем SI4432 и GY-521, как описывал выше, и при работе в Serial port выводит: FIFO overflow!, но порой там промелькивают значения положения в пространстве. Если же я отключу полностью радио модуль, то все работает нормально и никаких других сообщений не выводится.
В ардуино два пина внешних прерываний, поэтому подключите один модуль на пин2, а другой на пин 3 Только не забудьте сменить номер прерывания в программе
stm - это тоже ардуино. Там вроде кто-то и SAM уже воткнул. И 25 аттиньку тоже. Поэтому надо уточнять.