Теперь буду знать!!!
Это мне кажется или где то нуля не хватает?
Код не полностью вставлен.
Да код полность вставлен.
И 20 или 200 не имеет значентя
Обновляются данные только после перезагрузки
А зачем такое преобразование? 16 битное число приводится к 32 битному числу и присваивается 16 битному числу. Зачем?
Я точно незнаю(.скачал скетч и переделал.
А что было не так в оригинальном и что переделывал?
Вообще скетч выдавал 4 параметра. Но мне нужен был только один. На жк экране нижняяя строка битая и пришлось скетч переделать только на верхнию.
Убрал все что было связана с мощьностью т. е. силу тока с шунтом и без. Мне нужен был только вольтаж.
можно сделать только один вывод, в строке
int16_t kodVoltRaw = sensor.getVoltBus(ADDRESS_INA226);
вы получаете одно и то же значение, попросту датчик либо соединение с ним неисправно.
А что за библиотека используется? Я какую-то нашел на гитхабе, но там нет такой функции (или я проглядел).
А не, есть. Всё-таки проглядел.
Там возвращаемый тип float.
/*********************************************************************************************************************************************
** Файл реализации библиотеки INA226a **
*********************************************************************************************************************************************/
#include "INA226a.h" // подключаем заголовочный файл библиотеки
#include <Wire.h> // I2C Library definition
INA226_Class::INA226_Class() {} // Class constructor
INA226_Class::~INA226_Class() {} // Unused class destructor
/*********************************************************************************************************************************************
** Метод begin() проверяет наличие датчика на шине по адресу deviceAddress. Если датчик присутствует, то: **
** - проводится расчёт калибровочного регистра, определение множителей для регистров тока и мощности, если указаны **
** ток maxBusAmps в амперах и сопротивление шунта microOhmR в микроомах; **
** - проводится запись калибровочного и конфигурационного (по умолчанию) регистров в устройство; **
** - возвращается true; **
** При отсутствии датчика возвращается false. **
*********************************************************************************************************************************************/
bool INA226_Class::begin(uint8_t deviceAddress, const uint8_t maxBusAmps, const uint32_t microOhmR)
{
uint16_t configuration = 0x127; // значение конфигурации по умолчанию
bool answer;
// Проверяем наличие устройства на шине
Wire.begin(); // запуск интефейса I2C
Wire.beginTransmission(deviceAddress);
if (Wire.endTransmission() == 0) // by checking the return error
{
if (readWord(INA_MANUFACTURER_ID_REGISTER,deviceAddress) == 0x5449) // Check hard-coded manufacturerId
{
writeWord(INA_CONFIGURATION_REGISTER,INA_RESET_DEVICE,deviceAddress); // запись сигнала RESET (фактически сброс устройства)
delay(I2C_DELAY); // даём время для сброса
if (readWord(INA_CONFIGURATION_REGISTER,deviceAddress) // если ответ совпал с ожидаемым,
== INA_DEFAULT_CONFIGURATION) // то
{
answer = true; // отклик - true
// Расчёт калибровочного регистра
if (maxBusAmps != 0 && microOhmR != 0) // если аргументы указаны, то
{
_current_LSB = (uint64_t)maxBusAmps*1000000000/32767; // определяем множитель для тока в пА/бит
_calibration = (uint64_t)51200000 / ((uint64_t)_current_LSB * // рассчитываем калибровочный регистр,
(uint64_t)microOhmR / (uint64_t)100000); // используя 64р переменные
_power_LSB = (uint32_t)25 * _current_LSB; // фиксируем множитель для расчёта мощности
}
else
{
_current_LSB = 0; // обнуление множителя для тока в пА/бит
_calibration = 0; // обнуление значения калибровки
_power_LSB = 0; // обнуление множителя для расчёта мощности
}
writeWord(INA_CALIBRATION_REGISTER,_calibration,deviceAddress); // запись калибровочного значения в указанное устройство
writeWord(INA_CONFIGURATION_REGISTER,configuration,deviceAddress); // запись калибровочного значения в указанное устройство
}
else answer = false; // отклик - false
}
}
return answer; // возврат отклика
}
/*********************************************************************************************************************************************
** Метод readByte читает 1 байт **
*********************************************************************************************************************************************/
uint8_t INA226_Class::readByte(const uint8_t addr,const uint8_t deviceAddr)
{
Wire.beginTransmission(deviceAddr); // Address the I2C device
Wire.write(addr); // Send the register address to read
_TransmissionStatus = Wire.endTransmission(); // Close transmission
delayMicroseconds(I2C_DELAY); // delay required for sync
Wire.requestFrom(deviceAddr, (uint8_t)1); // Request 1 byte of data
return Wire.read(); // read it and return it
} // of method readByte()
/*********************************************************************************************************************************************
** Метод readWord читает 2 байта **
*********************************************************************************************************************************************/
int16_t INA226_Class::readWord(const uint8_t addr,const uint8_t deviceAddr)
{
int16_t returnData; // Store return value
Wire.beginTransmission(deviceAddr); // Address the I2C device
Wire.write(addr); // Send the register address to read
_TransmissionStatus = Wire.endTransmission(); // Close transmission
delayMicroseconds(I2C_DELAY); // delay required for sync
Wire.requestFrom(deviceAddr, (uint8_t)2); // Request 2 consecutive bytes
returnData = Wire.read(); // Read the msb
returnData = returnData << 8; // shift the data over
returnData|= Wire.read(); // Read the lsb
return returnData; // read it and return it
} // of method readWord()
/*********************************************************************************************************************************************
** Метод writeByte записывает 1 байт **
*********************************************************************************************************************************************/
void INA226_Class::writeByte(const uint8_t addr, const uint8_t data, const uint8_t deviceAddr)
{
Wire.beginTransmission(deviceAddr); // Address the I2C device
Wire.write(addr); // Send register address to write
Wire.write(data); // Send the data to write
_TransmissionStatus = Wire.endTransmission(); // Close transmission
} // of method writeByte()
/*********************************************************************************************************************************************
** Метод writeWord записывает 2 байта **
*********************************************************************************************************************************************/
void INA226_Class::writeWord(const uint8_t addr, const uint16_t data, const uint8_t deviceAddr)
{
Wire.beginTransmission(deviceAddr); // Address the I2C device
Wire.write(addr); // Send register address to write
Wire.write((uint8_t)(data >> 8)); // Write the first byte
Wire.write((uint8_t)data); // and then the second
_TransmissionStatus = Wire.endTransmission(); // Close transmission
} // of method writeWord()
/*********************************************************************************************************************************************
** Метод getVoltBusRaw получает "сырой" код из регистра Bus Voltage **
*********************************************************************************************************************************************/
uint16_t INA226_Class::getVoltBusRaw(const uint8_t address)
{
uint16_t voltBusRaw = readWord(INA_BUS_VOLTAGE_REGISTER,address);
return voltBusRaw;
}
/*********************************************************************************************************************************************
** Метод getVoltShuntRaw получает "сырой" код из регистра Shunt Voltage **
*********************************************************************************************************************************************/
int16_t INA226_Class::getVoltShuntRaw(const uint8_t address)
{
int16_t voltShuntRaw = readWord(INA_SHUNT_VOLTAGE_REGISTER,address);
return voltShuntRaw;
}
/*********************************************************************************************************************************************
** Метод getVoltBus получает напряжение шины в миливольтах **
*********************************************************************************************************************************************/
// Получение напряжения шины в миливольтах
uint16_t INA226_Class::getVoltBus(const uint8_t address)
{
uint16_t voltBus = (uint32_t)getVoltBusRaw(address) * INA_BUS_VOLTAGE_LSB / 100; // mV
return voltBus;
}
/*********************************************************************************************************************************************
** Метод getVoltShunt получает напряжение шунта в микровольтах **
*********************************************************************************************************************************************/
int32_t INA226_Class::getVoltShunt(const uint8_t address)
{
int32_t voltShunt = (int32_t)getVoltShuntRaw(address) * INA_SHUNT_VOLTAGE_LSB / 10; // uV
return voltShunt;
}
/*********************************************************************************************************************************************
** Метод getMicroAmps получает ток в микроамперах **
*********************************************************************************************************************************************/
int32_t INA226_Class::getMicroAmps(const uint8_t address)
{
int32_t microAmps = readWord(INA_CURRENT_REGISTER,address);
microAmps = (int64_t)microAmps * _current_LSB / 1000; // uA
return(microAmps);
}
/*********************************************************************************************************************************************
** Метод getMicroWatts получает мощность в микроватаах **
*********************************************************************************************************************************************/
// Получение мощности в микроваттах
int32_t INA226_Class::getMicroWatts(const uint8_t address)
{
int32_t microWatts = readWord(INA_POWER_REGISTER,address);
microWatts = (int64_t)microWatts * _power_LSB/1000; // uWt
return (microWatts);
}
/*********************************************************************************************************************************************
** Метод reset осуществляет сброс датчика **
*********************************************************************************************************************************************/
void INA226_Class::reset(const uint8_t address)
{
writeWord(INA_CONFIGURATION_REGISTER,0x8000,address);
delay(I2C_DELAY);
}
/*********************************************************************************************************************************************
** Метод setConfiguration записывает конфигурацию работы в датчик **
*********************************************************************************************************************************************/
void INA226_Class::setConfiguration(uint8_t averaging, uint8_t conTimeBus, uint8_t conTimeShunt, uint8_t mode, const uint8_t address)
{
writeWord(INA_CONFIGURATION_REGISTER,(averaging << 9) | (conTimeBus << 6) | (conTimeShunt << 3) | mode, address);
}
/*********************************************************************************************************************************************
** Метод getConfiguration получает конфигурацию работы из датчика **
*********************************************************************************************************************************************/
uint16_t INA226_Class::getConfiguration(const uint8_t address)
{
return readWord(INA_CONFIGURATION_REGISTER,address) &0xBFFF;
}
/*********************************************************************************************************************************************
** Метод setAveraging записывает количество усреднений в датчик **
*********************************************************************************************************************************************/
void INA226_Class::setAveraging(uint8_t averaging, const uint8_t address)
{
uint16_t conf = getConfiguration(address);
conf &= ~INA_CONFIG_AVG_MASK;
conf |= (uint16_t)averaging << 9;
writeWord(INA_CONFIGURATION_REGISTER, conf, address);
}
/*********************************************************************************************************************************************
** Метод getAveraging получает количество усреднений из датчика **
*********************************************************************************************************************************************/
uint8_t INA226_Class::getAveraging(const uint8_t address)
{
uint16_t avg = getConfiguration(address);
avg &= INA_CONFIG_AVG_MASK;
return (uint8_t)(avg >> 9);
}
/*********************************************************************************************************************************************
** Метод setConfersionTimeBus записывает время преобразования напряжения на шине **
*********************************************************************************************************************************************/
void INA226_Class::setConfersionTimeBus(uint8_t timeBus, const uint8_t address)
{
uint16_t timeConfersion = getConfiguration(address);
timeConfersion &= ~INA_CONFIG_BUS_TIME_MASK;
timeConfersion |= (uint16_t)timeBus << 6;
writeWord(INA_CONFIGURATION_REGISTER, timeConfersion, address);
}
/*********************************************************************************************************************************************
** Метод getConfersionTimeBus получает время преобразования напряжения на шине **
*********************************************************************************************************************************************/
uint8_t INA226_Class::getConfersionTimeBus(const uint8_t address)
{
uint16_t timeConfersion = getConfiguration(address);
timeConfersion &= INA_CONFIG_BUS_TIME_MASK;
return (uint8_t)(timeConfersion >> 6);
}
/*********************************************************************************************************************************************
** Метод setConfersionTimeShunt записывает время преобразования напряжения на шине **
*********************************************************************************************************************************************/
void INA226_Class::setConfersionTimeShunt(uint8_t timeShunt, const uint8_t address)
{
uint16_t timeConfersion = getConfiguration(address);
timeConfersion &= ~INA_CONFIG_SHUNT_TIME_MASK;
timeConfersion |= (uint16_t)timeShunt << 3;
writeWord(INA_CONFIGURATION_REGISTER, timeConfersion, address);
}
/*********************************************************************************************************************************************
** Метод setConfersionTimeShunt получает время преобразования напряжения на шине **
*********************************************************************************************************************************************/
uint8_t INA226_Class::getConfersionTimeShunt(const uint8_t address)
{
uint16_t timeConfersion = getConfiguration(address);
timeConfersion &= INA_CONFIG_SHUNT_TIME_MASK;
return (uint8_t)(timeConfersion >> 3);
}
/*********************************************************************************************************************************************
** Метод setModeDevice записывает режим работы датчика **
*********************************************************************************************************************************************/
void INA226_Class::setModeDevice(uint8_t mode, const uint8_t address)
{
uint16_t modeDevice = getConfiguration(address);
modeDevice &= ~INA_CONFIG_MODE_MASK;
modeDevice |= (uint16_t)mode;
writeWord(INA_CONFIGURATION_REGISTER, modeDevice, address);
}
/*********************************************************************************************************************************************
** Метод setConfersionTimeShunt получает режим работы датчика **
*********************************************************************************************************************************************/
uint8_t INA226_Class::getModeDevice(const uint8_t address)
{
uint16_t modeDevice = getConfiguration(address);
modeDevice &= INA_CONFIG_MODE_MASK;
return (uint8_t)modeDevice;
}
/*********************************************************************************************************************************************
** Метод getCalibration получает значение калибровочного регистра из датчика **
*********************************************************************************************************************************************/
uint16_t INA226_Class::getCalibration(const uint8_t address)
{
return readWord(INA_CALIBRATION_REGISTER,address);
}
/*********************************************************************************************************************************************
** Метод getRegisterMask получает значение калибровочного регистра из датчика **
*********************************************************************************************************************************************/
uint16_t INA226_Class::getRegisterMask(const uint8_t address)
{
return readWord(INA_MASK_ENABLE_REGISTER,address);
}
/*********************************************************************************************************************************************
** Метод askFlagConfersion получает значение калибровочного регистра из датчика **
*********************************************************************************************************************************************/
bool INA226_Class::askFlagConfersion(const uint8_t address)
{
uint16_t flag = getRegisterMask(address);
if (flag & INA_CONVERSION_READY_MASK) return true;
else return false;
}
/*********************************************************************************************************************************************
** Метод setBitExcess устанавливает тип параметра, превышение уставки которого приведёт к возникновению сигнала на выводе ALERT **
*********************************************************************************************************************************************/
void INA226_Class::setBitExcess(uint8_t bitExcess, const uint8_t address)
{
uint16_t bits = getRegisterMask(address);
bits &= ~INA_MASK_EXCESS;
bits |= bitExcess << 11;
writeWord(INA_MASK_ENABLE_REGISTER, bits, address);
}
/*********************************************************************************************************************************************
** Метод setAlertLimit устанавливает численное значение уставки **
*********************************************************************************************************************************************/
void INA226_Class::setAlertLimit(uint16_t data, const uint8_t address)
{
writeWord(INA_ALERT_LIMIT_REGISTER, data, address);
}
/*********************************************************************************************************************************************
** Метод getAlertLimit получает численное значение уставки из датчика **
*********************************************************************************************************************************************/
uint16_t INA226_Class::getAlertLimit(const uint8_t address)
{
return readWord(INA_ALERT_LIMIT_REGISTER,address);
}
Не, я не ту библиотеку нашел… )))
По поводу соединения с датчиком. Я сомневаюсь что неправильно соединил, уже много разных подключений проверил. только этот работает.
Покажи исходный код, чего гадать то…
Он точно работал?
/* ТЕСТ МОНИТОРА ТОКА (МОЩНОСТИ) INA226 */
#include "LiquidCrystal_I2C.h" // подключение библиотеки LCD дисплея
#include "INA226a.h" // подключение библиотеки датчика
#define ADDRESS_INA226 0X40 // адрес датчика по шине I2C
#define SET_OVER_VOLTAGE 4400 // уставка превышения по напряжению шунта (чуть больше 1А)
// Объекты
LiquidCrystal_I2C lcd(0x27, 16, 2);
INA226_Class sensor;
int8_t Rsh = 10; // сопротивление шунта в милиОмах
uint8_t stateSensor = 0;
bool answerDevice;
void setup()
{
Serial.begin(115200);
lcd.begin(); // настройка дисплея
lcd.backlight(); // включение подсветки
lcd.clear(); // очистка экрана
lcd. print(" TEST INA226"); // вывод надписи
delay(1000); // пауза 1 секунда
lcd.clear(); // очистка экрана
lcd. print("Sensor INA226"); // вывод надписи
lcd.setCursor(2, 1); // переход на 2 строку
answerDevice = sensor.begin(ADDRESS_INA226); // инициализация датчика INA226
if (answerDevice == true) lcd.print(" found"); // если датчик присутствует на шине, то выводим надпись "Датчик найден""
else
{
lcd.print(" isn't found"); // иначе выводим надпись "Датчик не найден"
while(1); // и зависаем!
}
sensor.setModeDevice(MODE_SHUNT_CONTINUOUS, ADDRESS_INA226); // установка режима "Измерение Ush, непрерывно"
sensor.setAveraging(AVERAGING_64, ADDRESS_INA226); // установка усреднения, равного 64
sensor.setBitExcess(SHUNT_VOLTAGE_OVER, ADDRESS_INA226); // установка режима тревоги "Превышение по Ush"
sensor.setAlertLimit(SET_OVER_VOLTAGE, ADDRESS_INA226); // запись в регистр сравнения уставки
delay(2000); // пауза 2 секунда
lcd.clear(); // очистка экрана
}
void loop()
{
int16_t kodVoltRaw = sensor.getVoltShuntRaw(ADDRESS_INA226) + 2; // получение "сырого кода" напряжения шунта + корректировка
//int16_t current_mA = (int32_t)kodVoltRaw * 25 /100; // вычисление тока, мА
int16_t current_mA = (int32_t)kodVoltRaw * 23 /100; // вычисление тока, мА с корректировкой
lcd.setCursor(0, 0); // переход на первую строку
lcd.print("Raw = 0x"); // вывод сырого кода
lcd.print(kodVoltRaw, HEX); // напряжения шунта
lcd.print(" "); // затираем лишние символы (возможно не потребуется)
lcd.setCursor(0, 1); // переход на вторую строку
lcd.print(" I = "); // начало вывода тока
if (current_mA < 0) // если ток отрицательный
{
lcd.print("-"); // выводим знак "минус"
current_mA *= -1; // преобразуем отрицательное число в положительное
}
lcd.print(current_mA / 1000); // выводим значение тока в амперах (целай часть)
lcd.print("."); // ставим разделительную точку
lcd.print(current_mA % 1000); // выводим значение тока в амперах (десятичная часть)
lcd.print("A "); // символ ампера
delay(200);
Это как раз скетч от Гайвера