Created
May 12, 2019 15:38
Star
You must be signed in to star a gist
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Texas Instruments INA226 Control sample | |
tomozh@gmail.com | |
2013.09.03 fix power miscalculation bug | |
2013.03.16 1st release | |
https://ore-kb.net/archives/150 | |
がベース。計算部分を単純化したり、ambientにデータを投げたり。 | |
tomoaki@akiyama.nu | |
*/ | |
#include <esp_wifi.h> | |
#include <Wire.h> | |
#include "Ambient.h" | |
#define NELEMS(arg) (sizeof(arg) / sizeof((arg)[0])) | |
const unsigned int PERIOD = 58; // 秒 | |
const unsigned int uS_TO_S_FACTOR = 1000000; | |
const unsigned int channelId = 00000; | |
const char* writeKey = "xxxxxxxxxxxxxxxx"; | |
const char* ssid = "SSID"; | |
const char* password = "PASSWORD"; | |
const byte GPIO_34 = 34; | |
const int INA226_PANNEL_ADDR = 0x40; | |
const int INA226_BATTERY_ADDR = 0x41; | |
const word INA226_CAL_VALUE = 0x0A00; | |
// INA226 Registers | |
#define INA226_REG_CONGIGURATION_REG 0x00 // Configuration Register (R/W) | |
#define INA226_REG_SHUNT_VOLTAGE 0x01 // Shunt Voltage (R) | |
#define INA226_REG_BUS_VOLTAGE 0x02 // Bus Voltage (R) | |
#define INA226_REG_POWER 0x03 // Power (R) | |
#define INA226_REG_CURRENT 0x04 // Current (R) | |
#define INA226_REG_CALIBRATION 0x05 // Calibration (R/W) | |
#define INA226_REG_MASK_ENABLE 0x06 // Mask/Enable (R/W) | |
#define INA226_REG_ALERT_LIMIT 0x07 // Alert Limit (R/W) | |
#define INA226_REG_DIE_ID 0xFF // Die ID (R) | |
// Operating Mode (Mode Settings [2:0]) | |
#define INA226_CONF_MODE_POWER_DOWN (0<<0) // Power-Down | |
#define INA226_CONF_MODE_TRIG_SHUNT_VOLTAGE (1<<0) // Shunt Voltage, Triggered | |
#define INA226_CONF_MODE_TRIG_BUS_VOLTAGE (2<<0) // Bus Voltage, Triggered | |
#define INA226_CONF_MODE_TRIG_SHUNT_AND_BUS (3<<0) // Shunt and Bus, Triggered | |
#define INA226_CONF_MODE_POWER_DOWN2 (4<<0) // Power-Down | |
#define INA226_CONF_MODE_CONT_SHUNT_VOLTAGE (5<<0) // Shunt Voltage, Continuous | |
#define INA226_CONF_MODE_CONT_BUS_VOLTAGE (6<<0) // Bus Voltage, Continuous | |
#define INA226_CONF_MODE_CONT_SHUNT_AND_BUS (7<<0) // Shunt and Bus, Continuous (default) | |
// Shunt Voltage Conversion Time (VSH CT Bit Settings [5:3]) | |
#define INA226_CONF_VSH_140uS (0<<3) // 140us | |
#define INA226_CONF_VSH_204uS (1<<3) // 204us | |
#define INA226_CONF_VSH_332uS (2<<3) // 332us | |
#define INA226_CONF_VSH_588uS (3<<3) // 588us | |
#define INA226_CONF_VSH_1100uS (4<<3) // 1.1ms (default) | |
#define INA226_CONF_VSH_2116uS (5<<3) // 2.116ms | |
#define INA226_CONF_VSH_4156uS (6<<3) // 4.156ms | |
#define INA226_CONF_VSH_8244uS (7<<3) // 8.244ms | |
// Bus Voltage Conversion Time (VBUS CT Bit Settings [8:6]) | |
#define INA226_CONF_VBUS_140uS (0<<6) // 140us | |
#define INA226_CONF_VBUS_204uS (1<<6) // 204us | |
#define INA226_CONF_VBUS_332uS (2<<6) // 332us | |
#define INA226_CONF_VBUS_588uS (3<<6) // 588us | |
#define INA226_CONF_VBUS_1100uS (4<<6) // 1.1ms (default) | |
#define INA226_CONF_VBUS_2116uS (5<<6) // 2.116ms | |
#define INA226_CONF_VBUS_4156uS (6<<6) // 4.156ms | |
#define INA226_CONF_VBUS_8244uS (7<<6) // 8.244ms | |
// Averaging Mode (AVG Bit Settings[11:9]) | |
#define INA226_CONF_AVG_1 (0<<9) // 1 (default) | |
#define INA226_CONF_AVG_4 (1<<9) // 4 | |
#define INA226_CONF_AVG_16 (2<<9) // 16 | |
#define INA226_CONF_AVG_64 (3<<9) // 64 | |
#define INA226_CONF_AVG_128 (4<<9) // 128 | |
#define INA226_CONF_AVG_256 (5<<9) // 256 | |
#define INA226_CONF_AVG_512 (6<<9) // 512 | |
#define INA226_CONF_AVG_1024 (7<<9) // 1024 | |
// Reset Bit (RST bit [15]) | |
#define INA226_CONF_RESET_ACTIVE (1<<15) | |
#define INA226_CONF_RESET_INACTIVE (0<<15) | |
WiFiClient client; | |
Ambient ambient; | |
static void writeRegister(byte deviceAddress, byte reg, word value) | |
{ | |
Wire.beginTransmission(deviceAddress); | |
Wire.write(reg); | |
Wire.write((value >> 8) & 0xFF); | |
Wire.write(value & 0xFF); | |
Wire.endTransmission(); | |
} | |
static void setupRegister(byte deviceAddress) | |
{ | |
writeRegister(deviceAddress, | |
INA226_REG_CONGIGURATION_REG, | |
INA226_CONF_RESET_INACTIVE | |
| INA226_CONF_MODE_CONT_SHUNT_AND_BUS | |
| INA226_CONF_VSH_1100uS | |
| INA226_CONF_VBUS_1100uS | |
| INA226_CONF_AVG_64 | |
); | |
writeRegister(deviceAddress, INA226_REG_CALIBRATION, INA226_CAL_VALUE); | |
} | |
static word readRegister(byte deviceAddress, byte reg) | |
{ | |
word value = 0x0000; | |
Wire.beginTransmission(deviceAddress); | |
Wire.write(reg); | |
if (Wire.endTransmission() == 0) { | |
if (Wire.requestFrom(deviceAddress, 2) >= 2) { | |
value = Wire.read() << 8; | |
value += Wire.read(); | |
} | |
} | |
return value; | |
} | |
typedef struct tagREG_INFO { | |
byte reg; | |
const char* name; | |
} REG_INFO; | |
const static REG_INFO st_aRegs[] = { | |
{ INA226_REG_CONGIGURATION_REG, "Configuration Register" }, | |
{ INA226_REG_SHUNT_VOLTAGE, "Shunt Voltage" }, | |
{ INA226_REG_BUS_VOLTAGE, "Bus Voltage" }, | |
{ INA226_REG_POWER, "Power" }, | |
{ INA226_REG_CURRENT, "Current" }, | |
{ INA226_REG_CALIBRATION, "Calibration" }, | |
{ INA226_REG_MASK_ENABLE, "Mask/Enable" }, | |
{ INA226_REG_ALERT_LIMIT, "Alert Limit" }, | |
{ INA226_REG_DIE_ID, "Die ID" }, | |
}; | |
static void dumpRegisters(byte deviceAddress) | |
{ | |
int i; | |
const REG_INFO* pInfo; | |
static word REGS[NELEMS(st_aRegs)]; | |
for (i = 0; i < NELEMS(REGS); i++) { | |
pInfo = &st_aRegs[i]; | |
REGS[i] = readRegister(deviceAddress, pInfo->reg); | |
} | |
Serial.printf("---INA226 Registers ---\n"); | |
for (i = 0; i < NELEMS(REGS); i++) { | |
pInfo = &st_aRegs[i]; | |
Serial.printf("%24s (%02Xh) : %04Xh (%u)\n", pInfo->name, pInfo->reg, REGS[i], REGS[i]); | |
} | |
} | |
int wifiConnect(void) | |
{ | |
int count = 0; | |
WiFi.disconnect(true); | |
WiFi.begin(ssid, password); | |
while (WiFi.status() != WL_CONNECTED) { | |
delay(500); | |
Serial.print("."); | |
if (6 < count++) { | |
Serial.printf("\nWiFi connect faild.\n"); | |
return(false); | |
} | |
} | |
Serial.printf("\nWiFi connected.\n"); | |
Serial.printf("IP address: "); | |
Serial.println(WiFi.localIP()); | |
return(true); | |
} | |
void setup() | |
{ | |
pinMode(21, INPUT_PULLUP); | |
pinMode(22, INPUT_PULLUP); | |
Wire.begin(); | |
Serial.begin(115200); | |
analogSetPinAttenuation(GPIO_34, ADC_11db); | |
setupRegister(INA226_PANNEL_ADDR); | |
setupRegister(INA226_BATTERY_ADDR); | |
ambient.begin(channelId, writeKey, &client); | |
float currentPannel = readRegister(INA226_PANNEL_ADDR, INA226_REG_CURRENT) / 1000.0; | |
while (10.0 < currentPannel) { | |
currentPannel = readRegister(INA226_PANNEL_ADDR, INA226_REG_CURRENT) / 1000.0; | |
} | |
float voltagePannel = 1.25 * readRegister(INA226_PANNEL_ADDR, INA226_REG_BUS_VOLTAGE) / 1000.0; | |
float powerPannel = 25.0 * readRegister(INA226_PANNEL_ADDR, INA226_REG_POWER) / 1000.0; | |
int cb = readRegister(INA226_BATTERY_ADDR, INA226_REG_CURRENT); | |
if (cb & 0x8000) { | |
cb -= 0x10000; | |
} | |
float currentBattery = cb / 1000.0; | |
while (10.0 < currentBattery) { | |
currentBattery = readRegister(INA226_BATTERY_ADDR, INA226_REG_CURRENT) / 1000.0; | |
} | |
float voltageBattery = 1.25 * readRegister(INA226_BATTERY_ADDR, INA226_REG_BUS_VOLTAGE) / 1000.0; | |
float powerBattery = 25.0 * readRegister(INA226_BATTERY_ADDR, INA226_REG_POWER) / 1000.0; | |
if (currentBattery < 0) { | |
powerBattery = -powerBattery; | |
} | |
int sensorValue = analogRead(GPIO_34); | |
float voltagePower = 3.3 * sensorValue / 4095.0; | |
Serial.printf("\n%5.2fV, %5.2fA, %5.2fW, %5d %5.2fV\n", voltagePannel, currentPannel, powerPannel, sensorValue, voltagePower); | |
dumpRegisters(INA226_PANNEL_ADDR); | |
Serial.printf("\n%5.2fV, %5.2fA, %5.2fW\n", voltageBattery, currentBattery, powerBattery); | |
dumpRegisters(INA226_BATTERY_ADDR); | |
if (wifiConnect()) { | |
ambient.set(1, voltagePannel); | |
ambient.set(2, currentPannel); | |
ambient.set(3, powerPannel); | |
ambient.set(4, voltagePower); | |
ambient.set(5, voltageBattery); | |
ambient.set(6, currentBattery); | |
ambient.set(7, powerBattery); | |
ambient.send(); | |
} | |
Serial.println("Setup ESP32 to sleep for every " + String(PERIOD) + " Seconds"); | |
Serial.println("Going to sleep now"); | |
esp_wifi_stop(); | |
esp_deep_sleep(PERIOD * uS_TO_S_FACTOR); | |
delay(1000); | |
} | |
void loop() | |
{ | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment