Пытаюсь скомпилить скетч для Attiny85 на Digispark Attiny85.
Получаю ошибку
....\ina226_driver.cpp: In member function 'void Ina226Driver::calibrate(float, float)':
...\ina226_driver.cpp:31:19: error: 'InaReg' is not a class or namespace
writeRegister16(InaReg::Calibration, calibration_value);
И тоже самое для всех функций…
Компилю на arduino IDE 2.2, для платы Digispark (Default - 16.5 mhz).
Если попытаться этот же скетч скомпилить для платы ATtiny25/45/85, всё прокатывает.
Но залить скомпиленный скетч не могу, т.к. он требует программатор…
Вот скетч (т.к. дисплея и Serial нет, закомментировал относящиеся к ним блоки)
/*
PowerMeter
A voltage, current and power meter using the INA226, with an ATtiny85 driving the process and displaying measurements to a 128X32 OLED display.
For info and circuit diagrams see https://github.com/tardate/LittleArduinoProjects/tree/master/Equipment/PowerMeter
*/
#include "ina226_driver.h"
//
#if defined(__AVR_ATtiny85__)
#include <TinyWireM.h>
// #include <Tiny4kOLED.h>
// #define LARGE_FONT FONT8X16
// #define SMALL_FONT FONT6X8
#else
#include <U8x8lib.h>
U8X8_SSD1306_128X32_UNIVISION_HW_I2C oled(U8X8_PIN_NONE);
const uint8_t * LARGE_FONT = u8x8_font_px437wyse700a_2x2_r;
const uint8_t * SMALL_FONT = u8x8_font_amstrad_cpc_extended_r;
const uint32_t SERIAL_SPEED = 115200;
#endif
//
const float R_SHUNT = 0.046758; // needs to be replaced with the actual shunt resistance (in ohms)
const float MAX_BUS_AMPS = 0.500; // set desired full-range current (used to scale the calibration factor)
const uint8_t INA_ADDR = 0x40; // I²C address of the INA226
const uint16_t DELAY_SPLASH = 2000; // ms delay on the initial splash screen
const uint16_t DELAY_BETWEEN_SAMPLES = 1000; // ms delay between updating the display with a new value
Ina226Driver ina = Ina226Driver();
void setup() {
/*
#ifdef HAVE_HWSERIAL0
Serial.begin(SERIAL_SPEED);
while (!Serial) {}
Serial.print("\n\nINA226 Power Meter\n");
#endif
*/
ina.begin(INA_ADDR);
ina.calibrate(R_SHUNT, MAX_BUS_AMPS);
/*
#if defined(__AVR_ATtiny85__)
oled.begin();
oled.clear();
oled.switchRenderFrame();
oled.clear();
oled.switchRenderFrame();
oled.on();
oled.setFont(LARGE_FONT);
oled.setCursor(40, 0); oled.print(F("INA226"));
oled.setFont(SMALL_FONT);
oled.setCursor(26, 2); oled.print(F("Power Meter"));
oled.setCursor(16, 3); oled.print(F("leap.tardate.com"));
#else
oled.begin();
oled.setFont(LARGE_FONT);
oled.drawString(2, 0, "INA226");
oled.setFont(SMALL_FONT);
oled.drawString(2, 2, "Power Meter");
oled.drawString(0, 3, "leap.tardate.com");
#endif
*/
delay(DELAY_SPLASH);
/*
#if defined(__AVR_ATtiny85__)
oled.clear();
oled.setFont(LARGE_FONT);
oled.setCursor(94, 0); oled.print(F("V"));
oled.setFont(SMALL_FONT);
oled.setCursor(94, 2); oled.print(F("mA"));
oled.setCursor(94, 3); oled.print(F("mW"));
#else
oled.clearDisplay();
oled.setFont(LARGE_FONT);
oled.drawString(14, 0, "V");
oled.setFont(SMALL_FONT);
oled.drawString(14, 2, "mA");
oled.drawString(14, 3, "mW");
#endif
*/
}
void loop() {
static char bus_V[15], shunt_mV[15], current_mA[15], bus_mW[15];
dtostrf(ina.readBusVoltage() , 7, 3, bus_V);
dtostrf(ina.readShuntVoltage() , 9, 3, shunt_mV);
dtostrf(ina.readCurrent() * 1000.0, 9, 3, current_mA);
dtostrf(ina.readPower() * 1000.0 , 9, 3, bus_mW);
/*
#if defined(__AVR_ATtiny85__)
oled.setFont(LARGE_FONT);
oled.setCursor(35, 0); oled.print(bus_V);
oled.setFont(SMALL_FONT);
oled.setCursor(36, 2); oled.print(current_mA);
oled.setCursor(36, 3); oled.print(bus_mW);
#else
oled.setFont(LARGE_FONT);
oled.drawString(0, 0, bus_V);
oled.setFont(SMALL_FONT);
oled.drawString(4, 2, current_mA);
oled.drawString(4, 3, bus_mW);
#endif
*/
delay(DELAY_BETWEEN_SAMPLES);
}
ina226_driver.h
#pragma once
#include <Arduino.h>
#if defined(__AVR_ATtiny85__)
#include <TinyWireM.h>
#define Wire TinyWireM
#else
#include <Wire.h>
#endif
enum InaReg : uint8_t {
Configuration = 0x00,
ShuntVoltage = 0x01,
BusVoltage = 0x02,
Power = 0x03,
Current = 0x04,
Calibration = 0x05,
MaskEnable = 0x06,
AlertLimit = 0x07,
ManID = 0xFE,
DieID = 0xFF,
};
//
/**
* A simplified INA226 interface using the Wire library
*/
class Ina226Driver {
public:
/**
* Command: init for specified I²C address
*/
void begin(uint8_t address);
/**
* Command: set calibration for particular shunt and current combination
*/
void calibrate(float shunt_resistance, float max_current);
/**
* Returns: the latest bus voltage (in volts)
*/
float readBusVoltage(void);
/**
* Returns: the latest shunt voltage (in millivolts)
*/
float readShuntVoltage(void);
/**
* Returns: the latest bus/shunt current (in amps)
*/
float readCurrent(void);
/**
* Returns: the latest bus power (in watts)
*/
float readPower(void);
private:
uint8_t address;
float shunt_resistance;
uint16_t calibration_value;
float current_LSB;
float power_LSB;
int16_t readRegister16(InaReg reg);
void writeRegister16(InaReg reg, uint16_t value);
};
ina226_driver.cpp
#include "ina226_driver.h"
void Ina226Driver::begin(uint8_t address) {
Wire.begin();
this->address = address;
}
void Ina226Driver::calibrate(float shunt_resistance, float max_current) {
this->shunt_resistance = shunt_resistance;
float minimum_lsb = max_current / 32768;
current_LSB = ceil(minimum_lsb * 10000000000) / 10000000000;
power_LSB = current_LSB * 25;
calibration_value = (uint16_t)((512) / (current_LSB * 100000 * shunt_resistance));
/*
#ifdef HAVE_HWSERIAL0
Serial.print("Manufacturer ID : "); Serial.println(readRegister16(InaReg::ManID), HEX);
Serial.print("Die ID : "); Serial.println(readRegister16(InaReg::DieID), HEX);
Serial.print("Calibrating for shunt resistance of ");
Serial.print(shunt_resistance, 3);
Serial.print("Ω and maximum current of ");
Serial.print(max_current, 3);
Serial.println("A");
Serial.print(" * current_LSB : "); Serial.print(current_LSB * 1000.0, 6); Serial.println("mA");
Serial.print(" * power_LSB : "); Serial.print(power_LSB * 1000.0, 6); Serial.println("mW");
Serial.print(" * CAL : "); Serial.println(calibration_value);
#endif
*/
writeRegister16(InaReg::Calibration, calibration_value);
}
float Ina226Driver::readBusVoltage(void) {
int16_t voltage = readRegister16(InaReg::BusVoltage);
return (voltage * 0.00125);
}
float Ina226Driver::readShuntVoltage(void) {
float voltage = readRegister16(InaReg::ShuntVoltage);
return (voltage * 0.0025);
}
float Ina226Driver::readCurrent(void) {
return (readRegister16(InaReg::Current) * current_LSB);
}
float Ina226Driver::readPower(void) {
return (readRegister16(InaReg::Power) * power_LSB);
}
int16_t Ina226Driver::readRegister16(InaReg reg) {
Wire.beginTransmission(address);
Wire.write(reg);
Wire.endTransmission();
Wire.requestFrom(address, (uint8_t)2);
uint8_t hi = Wire.read();
uint8_t lo = Wire.read();
return hi << 8 | lo;
}
void Ina226Driver::writeRegister16(InaReg reg, uint16_t value) {
uint8_t lo = (uint8_t)value;
uint8_t hi = value >>= 8;
Wire.beginTransmission(address);
Wire.write(reg);
Wire.write(hi);
Wire.write(lo);
Wire.endTransmission();
}
Пытался погуглить по тексту ошибки - ничего кроме проблемы с многократным включением #include не нашёл…
Да и с другой платой скетч компилится!