mirror of
https://github.com/MarlinFirmware/Marlin.git
synced 2025-03-15 02:36:19 +00:00
Initial INA3211 Support, Rework Existing INA226 Code to allow pin reassignment using SlowSoftI2CMaster, Remove Dependencies On Wire and INA226Lib.
This commit is contained in:
parent
3ee1248cf2
commit
91f04f448d
4 changed files with 126 additions and 23 deletions
|
@ -3704,10 +3704,22 @@
|
|||
//
|
||||
// Laser I2C Ammeter (High precision INA226 low/high side module)
|
||||
//
|
||||
//#define I2C_AMMETER
|
||||
#define I2C_AMMETER
|
||||
#if ENABLED(I2C_AMMETER)
|
||||
#define I2C_AMMETER_IMAX 0.1 // (Amps) Calibration value for the expected current range
|
||||
#define I2C_AMMETER_SHUNT_RESISTOR 0.1 // (Ohms) Calibration shunt resistor value
|
||||
|
||||
#define I2C_AMMETER_SDA_PIN 66 // D66 (AUX2.9)
|
||||
#define I2C_AMMETER_SCL_PIN 65 // D65 (AUX2.10)
|
||||
|
||||
#define I2C_AMMETER_ADDRESS 0x41
|
||||
|
||||
#define I2C_AMMETER_MONITOR_CHANNEL 3
|
||||
#define I2C_AMMETER_WARN_CURRENT_MA 14 //Hardware Warn Level (INA3221 Only)
|
||||
#define I2C_AMMETER_ALARM_CURRENT_MA 25 //Hardware Alarm Level
|
||||
|
||||
#define I2C_AMMETER_IMAX 0.5 // (Amps) Calibration value for the expected current range
|
||||
#define I2C_AMMETER_SHUNT_RESISTOR 0.1 // (Ohms) Calibration shunt resistor value
|
||||
|
||||
//#define I2C_AMMETER_DEBUGGING
|
||||
#endif
|
||||
|
||||
//
|
||||
|
|
|
@ -23,32 +23,124 @@
|
|||
#include "../inc/MarlinConfig.h"
|
||||
|
||||
#if ENABLED(I2C_AMMETER)
|
||||
|
||||
#include "ammeter.h"
|
||||
|
||||
#ifndef I2C_AMMETER_SDA_PIN
|
||||
#define I2C_AMMETER_SDA_PIN SDA
|
||||
#endif
|
||||
#ifndef I2C_AMMETER_SCL_PIN
|
||||
#define I2C_AMMETER_SCL_PIN SCL
|
||||
#endif
|
||||
#ifndef I2C_AMMETER_ADDRESS
|
||||
#define I2C_AMMETER_ADDRESS 0x40
|
||||
#endif
|
||||
#ifndef I2C_AMMETER_IMAX
|
||||
#define I2C_AMMETER_IMAX 0.500 // Calibration range 500 Milliamps
|
||||
#define I2C_AMMETER_IMAX 0.500 // Calibration range 500 Milliamps
|
||||
#endif
|
||||
|
||||
INA226 ina;
|
||||
#ifndef I2C_AMMETER_MONITOR_CHANNEL
|
||||
#define I2C_AMMETER_MONITOR_CHANNEL 3
|
||||
#endif
|
||||
|
||||
#define I2C_AMMETER_WARN_CURRENT_MA 14
|
||||
#define I2C_AMMETER_ALARM_CURRENT_MA 25
|
||||
|
||||
Ammeter ammeter;
|
||||
|
||||
float Ammeter::scale;
|
||||
float Ammeter::current;
|
||||
uint32_t Ammeter::currentLSB;
|
||||
int Ammeter::sensor_type = 0;
|
||||
|
||||
void Ammeter::init() {
|
||||
ina.begin();
|
||||
ina.configure(INA226_AVERAGES_16, INA226_BUS_CONV_TIME_1100US, INA226_SHUNT_CONV_TIME_1100US, INA226_MODE_SHUNT_BUS_CONT);
|
||||
ina.calibrate(I2C_AMMETER_SHUNT_RESISTOR, I2C_AMMETER_IMAX);
|
||||
SlowSoftI2CMaster si = SlowSoftI2CMaster(I2C_AMMETER_SDA_PIN, I2C_AMMETER_SCL_PIN, true);
|
||||
uint16_t _ammeter_read_register(uint8_t reg)
|
||||
{
|
||||
if (!si.i2c_start((I2C_AMMETER_ADDRESS << 1) | I2C_WRITE))
|
||||
return -1; // No ACK from slave
|
||||
|
||||
if (!si.i2c_write(reg))
|
||||
return -2; // failed write
|
||||
|
||||
delayMicroseconds(600); // max 586us from datasheet
|
||||
|
||||
if (!si.i2c_rep_start((I2C_AMMETER_ADDRESS << 1) | I2C_READ))
|
||||
return -3; // no ACK from slave on second transaction
|
||||
|
||||
int ret = (si.i2c_read(false) << 8 | si.i2c_read(true));
|
||||
|
||||
si.i2c_stop();
|
||||
return ret;
|
||||
}
|
||||
|
||||
float Ammeter::read() {
|
||||
scale = 1;
|
||||
current = ina.readShuntCurrent();
|
||||
if (current <= 0.0001f) current = 0; // Clean up least-significant-bit amplification errors
|
||||
if (current < 0.1f) scale = 1000;
|
||||
return current * scale;
|
||||
void _ammeter_write_register(uint8_t reg, uint16_t value)
|
||||
{
|
||||
if (!si.i2c_start((I2C_AMMETER_ADDRESS << 1) | I2C_WRITE))
|
||||
return; // No ACK from slave
|
||||
|
||||
si.i2c_write(reg);
|
||||
si.i2c_write((value >> 8) & 0xFF);
|
||||
si.i2c_write(value & 0xFF);
|
||||
si.i2c_stop();
|
||||
}
|
||||
void Ammeter::init()
|
||||
{
|
||||
if (si.i2c_init())
|
||||
{
|
||||
if (_ammeter_read_register(0xFE) == 0x5449)
|
||||
{
|
||||
|
||||
uint16_t id = _ammeter_read_register(0xFF);
|
||||
sensor_type = id;
|
||||
|
||||
#ifdef I2C_AMMETER_DEBUGGING
|
||||
SERIAL_ECHO("TI I2C Device: 0x");
|
||||
SERIAL_PRINT(id, PrintBase::Hex);
|
||||
SERIAL_ECHO(" @ 0x");
|
||||
SERIAL_PRINT(I2C_AMMETER_ADDRESS, PrintBase::Hex);
|
||||
SERIAL_ECHOLNPGM(" OK ( SDA: ", I2C_AMMETER_SDA_PIN, " SCL: ", I2C_AMMETER_SCL_PIN, " )");
|
||||
#endif
|
||||
|
||||
switch (sensor_type)
|
||||
{
|
||||
case 0x3220:
|
||||
_ammeter_write_register(0x00, 0x927 | (0x8000 >> I2C_AMMETER_MONITOR_CHANNEL)); // [CH_x_EN, AVERAGES_256, BUS_CONV_TIME_1100US, SHUNT_CONV_TIME_1100US, MODE_SHUNT_BUS_CONT]
|
||||
TERN_(I2C_AMMETER_WARN_CURRENT_MA, _ammeter_write_register(0x6 + (I2C_AMMETER_MONITOR_CHANNEL * 2), I2C_AMMETER_WARN_CURRENT_MA / I2C_AMMETER_IMAX);)
|
||||
TERN_(I2C_AMMETER_ALARM_CURRENT_MA, _ammeter_write_register(0x5 + (I2C_AMMETER_MONITOR_CHANNEL * 2), I2C_AMMETER_ALARM_CURRENT_MA / I2C_AMMETER_IMAX);)
|
||||
break;
|
||||
|
||||
case 0x2260:
|
||||
{
|
||||
currentLSB = ((I2C_AMMETER_IMAX / 32767) * 100000000);
|
||||
currentLSB /= 100000000;
|
||||
currentLSB /= 0.0001; // CHOP CHOP?
|
||||
currentLSB = ceil(currentLSB);
|
||||
currentLSB *= 0.0001;
|
||||
|
||||
_ammeter_write_register(0x00, 0x927); // [AVERAGES_256, BUS_CONV_TIME_1100US, SHUNT_CONV_TIME_1100US, MODE_SHUNT_BUS_CONT]
|
||||
_ammeter_write_register(0x05, (uint16_t)((0.00512) / (currentLSB * I2C_AMMETER_SHUNT_RESISTOR)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
float Ammeter::read()
|
||||
{
|
||||
switch (sensor_type)
|
||||
{
|
||||
case 0x3220: // INA3221
|
||||
current = _ammeter_read_register((I2C_AMMETER_MONITOR_CHANNEL * 2) - 1) * (I2C_AMMETER_IMAX * I2C_AMMETER_SHUNT_RESISTOR);
|
||||
break;
|
||||
|
||||
case 0x2260: // INA226
|
||||
current = _ammeter_read_register(0x04) * currentLSB;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
#endif // I2C_AMMETER
|
||||
|
|
|
@ -22,14 +22,13 @@
|
|||
#pragma once
|
||||
|
||||
#include "../inc/MarlinConfigPre.h"
|
||||
#include <SlowSoftI2CMaster.h>
|
||||
|
||||
#include <Wire.h>
|
||||
#include <INA226.h>
|
||||
|
||||
class Ammeter {
|
||||
private:
|
||||
static float scale;
|
||||
|
||||
static int sensor_type;
|
||||
static uint32_t currentLSB;
|
||||
public:
|
||||
static float current;
|
||||
static void init();
|
||||
|
|
|
@ -31,7 +31,7 @@ HAS_MOTOR_CURRENT_I2C = SlowSoftI2CMaster
|
|||
LIB_INTERNAL_MAX31865 = build_src_filter=+<src/libs/MAX31865.cpp>
|
||||
NEOPIXEL_LED = adafruit/Adafruit NeoPixel@~1.8.0
|
||||
build_src_filter=+<src/feature/leds/neopixel.cpp>
|
||||
I2C_AMMETER = peterus/INA226Lib@1.1.2
|
||||
I2C_AMMETER = SlowSoftI2CMaster
|
||||
build_src_filter=+<src/feature/ammeter.cpp>
|
||||
USES_LIQUIDCRYSTAL = LiquidCrystal=https://github.com/MarlinFirmware/New-LiquidCrystal/archive/1.5.1.zip
|
||||
USES_LIQUIDCRYSTAL_I2C = marcoschwartz/LiquidCrystal_I2C@1.1.4
|
||||
|
|
Loading…
Add table
Reference in a new issue