Как изменить i2c-адрес Lidar Lite v3 с помощью библиотеки LidarLite (Решено)
У меня есть 2 лидара, которые являются Lidar Lite v3 и Lidar Lite v4, оба этих датчика имеют один и тот же адрес i2c. Я пытаюсь изменить свой i2c-адрес Lidar Lite v3 на arduino mega2560, используя функцию из библиотеки LidarLite с 0x62 на 0x63. Однако это, кажется, не работает, после того, как я загрузил код последовательный дисплей монитора
> nack
и когда я использую сканер i2c, он по-прежнему показывает адрес по умолчанию (0x62).
вот мой код arduino
#include <Wire.h>
#include <LIDARLite.h>
LIDARLite myLidarLite;
void setup(){
Serial.begin(115200); // Initialize serial connection to display distance readings
char newAddress = 0x63;
myLidarLite.setI2Caddr(newAddress , true);
Wire.begin();
}
void loop(){
**** i2c scanner code ****
}
Функция setI2Caddr из библиотеки
void LIDARLite::setI2Caddr(char newAddress, char disableDefault, char lidarliteAddress)
{
byte dataBytes[2];
// Считывайте байты серийного номера UNIT_ID и записывайте их в байтовые местоположения I2C_ID
read ((0x16 | 0x80), 2, dataBytes, false, lidarliteAddress);
write(0x18, dataBytes[0], lidarliteAddress);
write(0x19, dataBytes[1], lidarliteAddress);
// Записать новый адрес устройства I2C в регистры
dataBytes[0] = newAddress;
write(0x1a, dataBytes[0], lidarliteAddress);
// Включить новый адрес устройства I2C, используя адрес устройства I2C по умолчанию
dataBytes[0] = 0;
write(0x1e, dataBytes[0], lidarliteAddress);
// При желании отключите адрес устройства I2C по умолчанию (используя новый адрес устройства I2C)
if (disableDefault)
{
dataBytes[0] = (1 << 3); // set bit to disable default address
write(0x1e, dataBytes[0], newAddress);
}
}
Я проверил функцию чтения и нашел это условие
// nack означает, что устройство не отвечает, сообщите об ошибке по последовательному порту
int nackCatcher = Wire.endTransmission();
if(nackCatcher != 0)
{
Serial.println("> nack");
}
спецификация Lidar Lite v3 находится здесь, а тему изменения адреса i2c можно найти на 5-й странице
Я пытался сравнить эту функцию с таблицей данных, но до сих пор понятия не имею, почему она не работает. Итак, как я могу изменить адрес I2C Lidar Lite v3, чтобы они могли работать вместе?
Обновление
Наконец-то я нашел ошибку. Простой способ исправить это-просто вызвать функцию Wire.begin()
или myLidarLite.begin()
(которая содержит Wire.begin
внутри функции) перед использованием setI2Caddr()
.
Итак, код будет таким
#include <Wire.h>
#include <LIDARLite.h>
LIDARLite myLidarLite;
void setup(){
Serial.begin(115200); // Initialize serial connection to display distance readings
Wire.begin(); // или myLidarLite.begin();
char newAddress = 0x63;
myLidarLite.setI2Caddr(newAddress , true);
}
void loop(){
**** i2c scanner code ****
}
После загрузки на плату адрес окончательно меняется.
Ps. Кстати, когда я установил 0x64 в setI2Caddr
, он изменился на 0x63 вместо 0x64 и все еще сохраняет старый адрес, хотя я установил disabledefault как true.
1 ответ
Вероятно, вам нужно использовать LIDARLite_v3HP.h
. Функция setI2Caddr()
не совпадает между LIDARLite_v3HP.h
и LIDARLite.h
.
В таблице данных, которую вы предоставили, есть инструкция о том, как обновить адрес I2C. LIDARLite_v3HP.h
's setI2Caddr()
последовал этим инструкциям.
Чтобы проверить, если вы перейдете к этой строке исходного кода LIDARLite.h
, вы увидите, что функция не записывает 0x08
в 0x1e
, а записывает 0x00
. Либо так было в более ранних версиях, либо это ошибка.
Кроме того, в техническом описании упоминается, что если вы включите лидар, то адрес будет восстановлен по умолчанию.
Обновление
После того, как я более тщательно просмотрел библиотеку, я заметил, что запись "0x08" в "0x01" на самом деле обрабатывается, но по-другому в "LIDERLite.h".Вот код setI2Caddr()
из библиотеки (проверьте последние две строки):
void LIDARLite::setI2Caddr(char newAddress, char disableDefault, char lidarliteAddress)
{
byte dataBytes[2];
// Считайте байты серийного номера UNIT_ID и записывайте их в байтовые ячейки I2C_ID
read ((0x16 | 0x80), 2, dataBytes, false, lidarliteAddress);
write(0x18, dataBytes[0], lidarliteAddress);
write(0x19, dataBytes[1], lidarliteAddress);
// Запишите новый адрес устройства I2C в регистры
dataBytes[0] = newAddress;
write(0x1a, dataBytes[0], lidarliteAddress);
// Включите новый адрес устройства I2C, используя адрес устройства I2C по умолчанию
dataBytes[0] = 0;
write(0x1e, dataBytes[0], lidarliteAddress);
// При желании отключите адрес устройства I2C по умолчанию (используя новый адрес устройства I2C)
if (disableDefault)
{
dataBytes[0] = (1 << 3); // set bit to disable default address
write(0x1e, dataBytes[0], newAddress);
}
}
Все, что вам нужно сделать, это установить disableDefault
на любой положительный int
при вызове setI2Caddr()
.
- Отправка и получение различных типов данных через I2C в Arduino
- Как выбрать альтернативные контакты I2C на ESP32?
- Альтернативы библиотеке Wire для I2C
- Библиотека Wire.h работает на Uno, но не компилируется для ATtiny85
- Вызов I2C во время Wire.requestFrom
- I2C связь между Arduino Uno и Nodemcu32-s (ESP32)
- Как обнаружить ошибки I2C с помощью requestFrom()
- Проблемы с I2C и Wire.Available()
Привет, Фахад, спасибо за ответ. Однако я попробовал "LIDARLite_v3HP", он все еще не работает, адрес не меняется, и когда я пробую пример кода, он всегда отображает 0 м. Кроме того, я все еще получаю "> nack "снова, когда я ввожу функцию "чтение", потому что передача не остановится " (Wire.endTransmission == false) ` . Как вы упомянули, _ функция не записывает 0x08 в 0x1e, вместо этого записывает 0x00._ . Не могли бы вы, пожалуйста, подсказать мне, как изменить "0x00" на "0x08", потому что я плохо разбираюсь в программировании на двоичном уровне., @Akkapop Prasompon
Я обновил ответ., @Fahad
Наконец-то я нашел решение (обновлено в моем посте). Проблема не в том, что библиотека, а в моем коде. Я просто переключаю
`Wire.begin ()
наsetI2Caddr
, и все. Кроме того, как вы упомянули о том, что преобразование0x08
в0x1e
верно, после установки адреса старый по-прежнему отображается на последовательном мониторе вместе с новым. Однако я не заметил изменений в предоставленном вами коде, я что-то пропустил?, @Akkapop Prasompon