// ============================================================
// sketch.ino — Test INA226 Custom Chip Wokwi
// Membaca: Shunt Voltage, Bus Voltage, Current, Power
// ============================================================
#include <Wire.h>
// ─── Konstanta INA226 ──────────────────────────────────────
#define INA226_ADDR 0x40
#define REG_CONFIG 0x00
#define REG_SHUNT_VOLTAGE 0x01
#define REG_BUS_VOLTAGE 0x02
#define REG_POWER 0x03
#define REG_CURRENT 0x04
#define REG_CALIBRATION 0x05
#define REG_MASK_ENABLE 0x06
#define REG_MANUFACTURER 0xFE
#define REG_DIE_ID 0xFF
// ─── Kalibrasi ─────────────────────────────────────────────
// R_shunt = 0.1 Ω, I_max = 1 A
// current_lsb = I_max / 32768 = 30.518 µA
// CAL = 0.00512 / (current_lsb × R_shunt)
// = 0.00512 / (30.518e-6 × 0.1)
// = 1677 → gunakan 1677 atau 2048 (lebih mudah hitung)
#define CAL_VALUE 1677
// ─── LSB per bit ───────────────────────────────────────────
#define SHUNT_LSB_UV 2.5f // µV per bit (signed)
#define BUS_LSB_MV 1.25f // mV per bit
#define CURRENT_LSB_uA 30.518f // µA per bit
#define POWER_LSB_uW (25.0f * CURRENT_LSB_uA) // µW per bit
// ──────────────────────────────────────────────────────────
uint16_t readReg16(uint8_t reg) {
Wire.beginTransmission(INA226_ADDR);
Wire.write(reg);
Wire.endTransmission(false); // repeated START
Wire.requestFrom(INA226_ADDR, 2);
uint8_t msb = Wire.read();
uint8_t lsb = Wire.read();
return (uint16_t)((msb << 8) | lsb);
}
void writeReg16(uint8_t reg, uint16_t val) {
Wire.beginTransmission(INA226_ADDR);
Wire.write(reg);
Wire.write((val >> 8) & 0xFF); // MSB dulu
Wire.write(val & 0xFF); // LSB
Wire.endTransmission();
}
// ──────────────────────────────────────────────────────────
void setup() {
Serial.begin(115200);
Wire.begin();
delay(300);
Serial.println(F("\n╔═══════════════════════════════╗"));
Serial.println(F("║ INA226 Custom Chip - Wokwi ║"));
Serial.println(F("╚═══════════════════════════════╝"));
// Verifikasi chip
uint16_t mfg = readReg16(REG_MANUFACTURER);
uint16_t die = readReg16(REG_DIE_ID);
Serial.print(F("Manufacturer ID : 0x")); Serial.print(mfg, HEX);
Serial.println(mfg == 0x5449 ? F(" ✓ (TI)") : F(" ✗ ERROR!"));
Serial.print(F("Die ID : 0x")); Serial.print(die, HEX);
Serial.println(die == 0x2260 ? F(" ✓ (INA226)") : F(" ✗ ERROR!"));
// Konfigurasi: AVG=16 avg, VBUSCT=1.1ms, VSHCT=1.1ms, continuous
writeReg16(REG_CONFIG, 0x4527);
Serial.println(F("Config : 0x4527 (AVG=16, continuous)"));
// Set kalibrasi
writeReg16(REG_CALIBRATION, CAL_VALUE);
Serial.print(F("Calibration : ")); Serial.println(CAL_VALUE);
Serial.println(F("───────────────────────────────────────────────"));
Serial.println(F(" Shunt(mV) Bus(V) Current(mA) Power(mW) "));
Serial.println(F("───────────────────────────────────────────────"));
}
void loop() {
// Baca semua register pengukuran
int16_t raw_shunt = (int16_t)readReg16(REG_SHUNT_VOLTAGE);
uint16_t raw_bus = readReg16(REG_BUS_VOLTAGE);
uint16_t raw_power = readReg16(REG_POWER);
int16_t raw_curr = (int16_t)readReg16(REG_CURRENT);
// Konversi ke satuan nyata
float shunt_mV = raw_shunt * SHUNT_LSB_UV / 1000.0f;
float bus_V = raw_bus * BUS_LSB_MV / 1000.0f;
float curr_mA = raw_curr * CURRENT_LSB_uA / 1000.0f;
float power_mW = raw_power * POWER_LSB_uW / 1000.0f;
// Tampilkan hasil
char buf[60];
snprintf(buf, sizeof(buf),
" %+8.3f %6.3f %+10.3f %8.3f",
shunt_mV, bus_V, curr_mA, power_mW);
Serial.println(buf);
// Tampilkan raw juga (sekali tiap 5 detik)
static uint32_t last_raw = 0;
if (millis() - last_raw > 5000) {
last_raw = millis();
Serial.println();
Serial.print(F("[RAW] Shunt=")); Serial.print(raw_shunt);
Serial.print(F(", Bus=")); Serial.print(raw_bus);
Serial.print(F(", Curr=")); Serial.print(raw_curr);
Serial.print(F(", Pwr=")); Serial.println(raw_power);
Serial.println();
}
delay(1000);
}