Привет! Роман, спасибо за наводку на хабре. Буду следить за творчеством этого чела
Добавлено after 3 hours 25 minutes 52 seconds: Запилил тестовый макет с возможностью переключить шину i2c магнитометра через MPU-6500 Есть желание пощупать DMP. Первый раз об этом слышу Примерная компоновка в коробочке КМ41212-01 (в Бауцентре покупал) примерно такая
Долго ждать посылки... А так, что в закромах нашел тем и пользуюсь Использовать платы с SPI смысла не вижу. Время для оцифровки данных акселерометра и гироскопа до 10ms, а если задействовать DMP будет еще больше. Аппаратное прерывание не используется. Забор данных по таймеру сделаю. И для автопилота дискретность получения этих данных в 0.5-1 сек будет выше крыши. Лодки под парусами быстро не ходят. 7-10 узлов это уже хорошо. Так что быстрые интерфейсы ни к чему
вопрос не в скорости... вопрос в унификации и стандартизации... к примеру в нашем кораблике все модули подключены к центральному процессору по общей шине SPI
Я не возражаю Здесь не много другая концепция... Центральный процессор, он же мастер устройство, общается с различными модулями, датчиками и исполнительными устройствами посредством ModBus. Все эти девайсы устанавливаются в разных местах, вплоть до топа мачты. Это не в одной коробке. А конкретная реализация конечных устройств истекает из элементной базы что под рукой. Как то так
потом решили сделать автопилот... но оказалось что один процессор не тянет и управление всеми устройствами и автопилот... пришлось ставить отдельный процессор на автопилот... ESP32
Ну так... я же выше писал что в качестве мастера нетбук (или промышленный/милитари ноут) буду использовать Зачем велосипед изобретать. А отвечает он за все... Центральное ПО - OpenCPN Вспомогательное ПО - Processing (он же Java) Ну и самописные плагины... Автопилот заюзаю pyPilot. Там только с сопряжением повозиться надо Смартфоны сейчас конечно продвинутые, но я им не доверяю И еще, как вариант, малинка 4 с 8Гб на борту или Rock PI
_________________ Девице - Device
Последний раз редактировалось maxlab Ср фев 09, 2022 17:08:49, всего редактировалось 1 раз.
только ноут имеет свойство иногда зависать)) это надо учитывать... мы это решили очень просто - в случае если пульт (или ПК) не отвечает то в кораблике через секунду срабатывает таймер и кораблик останавливает - выключается двигатель, руль в переводится в среднее положение и кораблик сообщает нам о потери связи с пультом (или ПК) ярким миганием фонарей со звуковой сигнализацией))
надо ещё сделать удалённую перезагрузку ПК... а в идеале надо сделать горячее резервирование - в случае отказа одного ПК всё управление переходит к резервному ПК...
Резервирование будет. Главный резерв это команда и традиционные способы навигации. Ну, или я... если в одно рыло ходить Роман, а что за плата эхолота в Вашем проекте?
в случае отказа одного ПК всё управление переходит к резервному ПК...
что то сразу вспомнилось "а на этот случай у меня проездной"
_________________ "Вся военная пропаганда, все крики, ложь и ненависть исходят от людей, которые на эту войну не пойдут !" / Джордж Оруэлл / "Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
Привет всем! В общем с IMU-6500 (аксель-гироскоп) какие то непонятки. Вроде пишут что отклонение между текущим замером в неподвижном состоянии и фабричным не должно превышать 14% по всем измерениям. А у меня какая то фигня. Хотя, уже 3 часа наблюдаю за процедурой самотестирования, дает одни и те же результаты. Апнота по selftest в сети не нашел. Может я что то делаю не так? Или забить на это??? Все равно в ручную калибровать буду
Добавлено after 5 minutes 8 seconds: Процедура само-тестирования у практически всех поставщиков библиотек на ГитХабе примерно одинаковая и выглядит так
Спойлер
Код:
// Accelerometer and gyroscope self test; check calibration wrt factory settings bool self_test_impl() // Should return percent deviation from factory trim values, +/- 14 or less deviation is a pass { uint8_t raw_data[6] = {0, 0, 0, 0, 0, 0}; int32_t gAvg[3] = {0}, aAvg[3] = {0}, aSTAvg[3] = {0}, gSTAvg[3] = {0}; float factoryTrim[6]; uint8_t FS = 0;
writeByte(MPU6500_ADDRESS, SMPLRT_DIV, 0x00); // Set gyro sample rate to 1 kHz writeByte(MPU6500_ADDRESS, CONFIG, 0x02); // Set gyro sample rate to 1 kHz and DLPF to 92 Hz writeByte(MPU6500_ADDRESS, GYRO_CONFIG, FS << 3); // Set full scale range for the gyro to 250 dps writeByte(MPU6500_ADDRESS, ACCEL_CONFIG2, 0x02); // Set accelerometer rate to 1 kHz and bandwidth to 92 Hz writeByte(MPU6500_ADDRESS, ACCEL_CONFIG, FS << 3); // Set full scale range for the accelerometer to 2 g
for (int ii = 0; ii < 200; ii++) { // get average current values of gyro and acclerometer
readBytes(MPU6500_ADDRESS, ACCEL_XOUT_H, 6, &raw_data[0]); // Read the six raw data registers into data array aAvg[0] += (int16_t)(((int16_t)raw_data[0] << 8) | raw_data[1]); // Turn the MSB and LSB into a signed 16-bit value aAvg[1] += (int16_t)(((int16_t)raw_data[2] << 8) | raw_data[3]); aAvg[2] += (int16_t)(((int16_t)raw_data[4] << 8) | raw_data[5]);
readBytes(MPU6500_ADDRESS, GYRO_XOUT_H, 6, &raw_data[0]); // Read the six raw data registers sequentially into data array gAvg[0] += (int16_t)(((int16_t)raw_data[0] << 8) | raw_data[1]); // Turn the MSB and LSB into a signed 16-bit value gAvg[1] += (int16_t)(((int16_t)raw_data[2] << 8) | raw_data[3]); gAvg[2] += (int16_t)(((int16_t)raw_data[4] << 8) | raw_data[5]); }
for (int ii = 0; ii < 3; ii++) { // Get average of 200 values and store as average current readings aAvg[ii] /= 200; gAvg[ii] /= 200; }
// Configure the accelerometer for self-test writeByte(MPU6500_ADDRESS, ACCEL_CONFIG, 0xE0); // Enable self test on all three axes and set accelerometer range to +/- 2 g writeByte(MPU6500_ADDRESS, GYRO_CONFIG, 0xE0); // Enable self test on all three axes and set gyro range to +/- 250 degrees/s delay(25); // Delay a while to let the device stabilize
for (int ii = 0; ii < 200; ii++) { // get average self-test values of gyro and acclerometer
readBytes(MPU6500_ADDRESS, ACCEL_XOUT_H, 6, &raw_data[0]); // Read the six raw data registers into data array aSTAvg[0] += (int16_t)(((int16_t)raw_data[0] << 8) | raw_data[1]); // Turn the MSB and LSB into a signed 16-bit value aSTAvg[1] += (int16_t)(((int16_t)raw_data[2] << 8) | raw_data[3]); aSTAvg[2] += (int16_t)(((int16_t)raw_data[4] << 8) | raw_data[5]);
readBytes(MPU6500_ADDRESS, GYRO_XOUT_H, 6, &raw_data[0]); // Read the six raw data registers sequentially into data array gSTAvg[0] += (int16_t)(((int16_t)raw_data[0] << 8) | raw_data[1]); // Turn the MSB and LSB into a signed 16-bit value gSTAvg[1] += (int16_t)(((int16_t)raw_data[2] << 8) | raw_data[3]); gSTAvg[2] += (int16_t)(((int16_t)raw_data[4] << 8) | raw_data[5]); }
for (int ii = 0; ii < 3; ii++) { // Get average of 200 values and store as average self-test readings aSTAvg[ii] /= 200; gSTAvg[ii] /= 200; }
// Configure the gyro and accelerometer for normal operation writeByte(MPU6500_ADDRESS, ACCEL_CONFIG, 0x00); writeByte(MPU6500_ADDRESS, GYRO_CONFIG, 0x00); delay(25); // Delay a while to let the device stabilize
// Report results as a ratio of (STR - FT)/FT; the change from Factory Trim of the Self-Test Response // To get percent, must multiply by 100 for (int i = 0; i < 3; i++) { self_test_result[i] = 100.0 * ((float)(aSTAvg[i] - aAvg[i])) / factoryTrim[i] - 100.; // Report percent differences self_test_result[i + 3] = 100.0 * ((float)(gSTAvg[i] - gAvg[i])) / factoryTrim[i + 3] - 100.; // Report percent differences }
// Serial.print("x-axis self test: acceleration trim within : "); // Serial.print(self_test_result[0], 1); // Serial.println("% of factory value"); // Serial.print("y-axis self test: acceleration trim within : "); // Serial.print(self_test_result[1], 1); // Serial.println("% of factory value"); // Serial.print("z-axis self test: acceleration trim within : "); // Serial.print(self_test_result[2], 1); // Serial.println("% of factory value"); // Serial.print("x-axis self test: gyration trim within : "); // Serial.print(self_test_result[3], 1); // Serial.println("% of factory value"); // Serial.print("y-axis self test: gyration trim within : "); // Serial.print(self_test_result[4], 1); // Serial.println("% of factory value"); // Serial.print("z-axis self test: gyration trim within : "); // Serial.print(self_test_result[5], 1); // Serial.println("% of factory value");
bool b = true; for (uint8_t i = 0; i < 6; ++i) { b &= fabs(self_test_result[i]) <= 14.f; } return b; }
Это вишенка на торте Когда основная инфраструктура будет готова, тогда можно будет подумать о дистанционном управлении. Кроме того, эту инфраструктуру нужно будет обкатать в реальных условиях. Т.е. этот проект у меня как минимум на год-полтора. А там видно будет... Практическое применение этому на лодках есть. Например, стоит твоя красавица на муринге посреди бухты... А ты на берегу. Вот, сбросить конец и подойти к удобному месту посадки людей используя пульт ДУ. Правда, обратная процедура затруднительна... Это еще на лодку надо манипулятор типа Kuka прикрутить чтобы веревку от муринга из воды подобрать и зафиксировать в стопоре В качестве развлекухи https://www.youtube.com/watch?v=bAdqazixuRY
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 14
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения