MAX9611/2 — получение ненужных данных
Я подключаюсь к MAX9611 на специальной печатной плате (используя SAMD Cortex M0 с загрузчиком Adafruit Feather) с помощью I2C. У меня есть код, который считывает напряжение, ток и температуру из внутренних регистров, но я получаю ненужные данные из регистров напряжения и тока. Температура работает надежно.
Иногда напряжение и ток равны 0. Иногда напряжение в 10 раз больше, чем должно быть (это исходное значение АЦП — это не ошибка преобразования). Текущее показание зависит от того, закомментирован запрос температуры или нет.
Я читаю документацию уже целый день и не могу понять, что я делаю не так. Самое интересное, что код для запроса данных регистра практически идентичен (просто указывает на разные регистры) между запросом рабочей температуры и нерабочими запросами напряжения и тока. Я разместил его ниже вместе с соответствующим разделом схемы — есть ли у кого-нибудь идеи, что я делаю неправильно?
Спасибо!
#include <Wire.h>
void setup()
{
Serial.begin(115200);
Wire.begin();
}
void loop()
{
Serial.print("mV: "); Serial.println(get_MAX9611_voltage());
Serial.print("mA: "); Serial.println(get_MAX9611_current());
Serial.print("Temp: "); Serial.println(get_MAX9611_temp());
Serial.println();
delay(1000);
}
uint16_t get_MAX9611_voltage (void)
{
Wire.beginTransmission(0x70);
Wire.write(0x0A); //Выбираем управляющий регистр 1
Wire.write(0x03); //Настраиваем мультиплексор на чтение с RS+
Wire.endTransmission();
Wire.beginTransmission(0x70);
Wire.write(0x02); //Выбор регистра данных RS+ MSB
Wire.endTransmission();
Wire.requestFrom(0x70,2);
uint8_t msb = Wire.read(); //Чтение RS+ MSB
uint8_t lsb = Wire.read(); //Чтение RS+ LSB
uint16_t MAX9611_voltage = word(msb,lsb);
MAX9611_voltage = MAX9611_voltage >> 4; //сдвиг вправо на 4 из-за 12-битного значения
MAX9611_voltage = MAX9611_voltage*14; // Полная шкала 57,3 В, 14 мВ на шаг АЦП
return MAX9611_voltage;
}
uint16_t get_MAX9611_current (void)
{
Wire.beginTransmission(0x70);
Wire.write(0x0A); //Выбираем управляющий регистр 1
Wire.write(0x02); // Установить мультиплексор для считывания с усилителя измерения тока с коэффициентом усиления 8x, полная шкала = 55 мВ
Wire.endTransmission();
Wire.beginTransmission(0x70);
Wire.write(0x00); //Выбор регистра данных CSA MSB
Wire.endTransmission();
Wire.requestFrom(0x70,2);
uint8_t msb = Wire.read(); // Чтение CSA MSB
uint8_t lsb = Wire.read(); // Чтение CSA LSB
uint16_t MAX9611_current = word(msb,lsb);
MAX9611_current = MAX9611_current >> 4; //сдвиг вправо на 4 из-за 12-битного значения
MAX9611_current = (MAX9611_current*0.01342)*5; //Значение АЦП в милливольтах, I=V/R, где R равно 0,2
return MAX9611_current;
}
int16_t get_MAX9611_temp (void)
{
Wire.beginTransmission(0x70);
Wire.write(0x0A); //Выбираем управляющий регистр 1
Wire.write(0x06); // Настраиваем мультиплексор на чтение с датчика температуры
Wire.endTransmission();
Wire.beginTransmission(0x70);
Wire.write(0x08); //Выбираем регистр временных данных MSB
Wire.endTransmission();
Wire.requestFrom(0x70,2);
uint8_t msb = Wire.read(); // Чтение временного старшего разряда
uint8_t lsb = Wire.read(); // Чтение временного LSB
int16_t MAX9611_temp = word(msb,lsb);
MAX9611_temp = (((MAX9611_temp >> 7) * 480)/1000); // сдвиг вправо на 7 из-за 9-битного значения, младший бит равен 480 мК
return MAX9611_temp;
}
@Joe of Loath, 👍-1
1 ответ
Лучший ответ:
Это не заняло много времени, чтобы найти ошибку... Режим непрерывного чтения требует паузы в 2 мс между каждым чтением ADC. Я читаю намного быстрее, особенно если учесть, что мой микропроцессор намного быстрее, чем 8-битные 328-е, которые используются во многих других примерах. Я добавил задержку в 2 мс между считываниями, и проблема, похоже, исчезла, хотя мне нужно будет проверить текущие измерения, когда у меня будет доступ к лучшему оборудованию.
- Отправка и получение различных типов данных через I2C в Arduino
- Как выбрать альтернативные контакты I2C на ESP32?
- Альтернативы библиотеке Wire для I2C
- Библиотека Wire.h работает на Uno, но не компилируется для ATtiny85
- Вызов I2C во время Wire.requestFrom
- I2C связь между Arduino Uno и Nodemcu32-s (ESP32)
- Как обнаружить ошибки I2C с помощью requestFrom()
- Проблемы с I2C и Wire.Available()
Со мной тоже иногда случается, что, написав пост в поисках ошибки, я вскоре нахожу ее сам. Хорошо, что вы опубликовали ответ, чтобы помочь другим с похожими проблемами., @Michel Keijzers