Solar-Inselanlage überwachen
Moderator: Co-Administratoren
-
- Beiträge: 12925
- Registriert: 16.01.2009, 18:48
- Wohnort: Steingaden
- Hat sich bedankt: 1599 Mal
- Danksagung erhalten: 222 Mal
Re: Solar-Inselanlage überwachen
dann sollte die lösung auch hier vollständig dokumentiert gezeigt werden ... der titel des themas sagt das ja
-------
!!! der download der handbüchern auf den seiten von eq3 und das lesen der tips und tricks kann das hm-leben sehr erleichtern - das nutzen der suche nach schlagworten ebenso !!!
wer schreibfehler findet darf sie behalten.
!!! der download der handbüchern auf den seiten von eq3 und das lesen der tips und tricks kann das hm-leben sehr erleichtern - das nutzen der suche nach schlagworten ebenso !!!
wer schreibfehler findet darf sie behalten.
- Hoppla
- Beiträge: 341
- Registriert: 29.12.2018, 19:39
- System: Alternative CCU (auf Basis OCCU)
- Wohnort: Leipzsch
- Hat sich bedankt: 35 Mal
- Danksagung erhalten: 12 Mal
Re: Solar-Inselanlage überwachen
Nun, da ich nur so lange an dem Quelltext von Papa und jp112sdl rumgemalt habe bis ich mein Ergebnis hatte erhebe ich nicht den Anspruch, etwas entwickelt zu haben.
Wenn einer der Autoren durch meinen Quelltext geht schlagen die sicher die Hände über dem Kopf zusammen.
Ich hab die Adafruit-Bibliothek zum INA eingebunden und folgenden Quelltext verwendet.
Den Strom messe ich nicht, dazu müsste der elektrische Aufbau komplett anders gestaltet werden um auch die Ströme im Fehlerfall zu überleben.
Ausserdem macht das der Laderegler schon. Primär geht es darum den Akku mit dem bösen Kohlestrom nachzuladen, wenn die Sonne schwächelt. Und das funktioniert klasse.
Die Verdrahtung sollte sich von selbst ergeben aus den Datenblatt der Sensorplatine und der Doku zu AskSinPP.
ps: Ich hab versucht, eine LCD-Anzeige einzubinden, das überstieg meine Fähigkeiten und habs sein lassen....
Wenn einer der Autoren durch meinen Quelltext geht schlagen die sicher die Hände über dem Kopf zusammen.
Ich hab die Adafruit-Bibliothek zum INA eingebunden und folgenden Quelltext verwendet.
Code: Alles auswählen
//- -----------------------------------------------------------------------------------------------------------------------
// AskSin++
// 2016-10-31 papa Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
// 2018-09-14 jp112sdl Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
// dranrumgemalt durch Hoppla
//- -----------------------------------------------------------------------------------------------------------------------
// define this to read the device id, serial and device type from bootloader section
// #define USE_OTA_BOOTLOADER
//#define USE_LCD
//#define LCD_ADDRESS 0x3f
#define EI_NOTEXTERNAL
#include <EnableInterrupt.h>
#include <AskSinPP.h>
#include <LowPower.h>
// INA _____________________
#include <Wire.h>
#include <Adafruit_INA219.h>
Adafruit_INA219 ina219; // Initialize first board (default address 0x40)
//Adafruit_INA219 ina219_A;
//Adafruit_INA219 ina219_B(0x41);
// INA ________________
#include <Register.h>
#include <MultiChannelDevice.h>
//#ifdef USE_LCD
//#include <LiquidCrystal_I2C.h>
//LiquidCrystal_I2C lcd(0x27, 20, 2);
//#endif
// Arduino Pro mini 8 Mhz
// Arduino pin for the config button
#define CONFIG_BUTTON_PIN 8
#define LED_PIN 4
// Number of voltage measurement channels
#define NUM_CHANNELS 1
// number of available peers per channel
#define PEERS_PER_CHANNEL 6
// all library classes are placed in the namespace 'as'
using namespace as;
//Korrekturfaktor der Clock-Ungenauigkeit, wenn keine RTC verwendet wird
#define SYSCLOCK_FACTOR 0.88
// define all device properties
const struct DeviceInfo PROGMEM devinfo = {
{0xF3, 0x4A, 0x00}, // Device ID
"JPVOLT0000", // Device Serial
{0xF3, 0x4A}, // Device Model
0x20, // Firmware Version
0x53, // Device Type
{0x01, 0x01} // Info Bytes
};
/**
Configure the used hardware
*/
typedef AskSin<StatusLed<LED_PIN>, BatterySensor, Radio<AvrSPI<10, 11, 12, 13>, 2>> BaseHal;
class Hal : public BaseHal {
public:
void init (const HMID& id) {
BaseHal::init(id);
//measure battery every 1h
battery.init(seconds2ticks(60UL * 60), sysclock);
battery.low(22);
battery.critical(19);
}
bool runready () {
return sysclock.runready() || BaseHal::runready();
}
} hal;
DEFREGISTER(UReg0, MASTERID_REGS, DREG_LOWBATLIMIT, 0x20, 0x21)
class UList0 : public RegList0<UReg0> {
public:
UList0 (uint16_t addr) : RegList0<UReg0>(addr) {}
bool Sendeintervall (uint16_t value) const {
return this->writeRegister(0x20, (value >> 8) & 0xff) && this->writeRegister(0x21, value & 0xff);
}
uint16_t Sendeintervall () const {
return (this->readRegister(0x20, 0) << 8) + this->readRegister(0x21, 0);
}
void defaults () {
clear();
lowBatLimit(22);
Sendeintervall(15);
}
};
DEFREGISTER(UReg1, 0x01, 0x02, 0x03)
class UList1 : public RegList1<UReg1> {
public:
UList1 (uint16_t addr) : RegList1<UReg1>(addr) {}
void defaults () {
clear();
}
};
class MeasureEventMsg : public Message {
public:
void init(uint8_t msgcnt, uint8_t channel, uint16_t voltage) {
Message::init(0x0e, msgcnt, 0x53, BIDI | WKMEUP, channel & 0xff, (voltage >> 8) & 0xff);
pload[0] = voltage & 0xff;
}
};
class MeasureChannel : public Channel<Hal, UList1, EmptyList, List4, PEERS_PER_CHANNEL, UList0>, public Alarm {
MeasureEventMsg msg;
uint16_t voltage;
uint8_t last_flags = 0xff;
public:
MeasureChannel () : Channel(), Alarm(0), voltage(0) {}
virtual ~MeasureChannel () {}
void measure() {
// HIER DIE MESSUNG DURCHFÃœHREN
// Spannung muss mit Faktor 10 übertragen werden
// 12.8V -> voltage = 128;
//voltage = random(2300);
float shuntvoltage = 0;
float busvoltage = 0;
float current_mA = 0;
float loadvoltage = 0;
float power_mW = 0;
//float voltage = 0;
shuntvoltage = ina219.getShuntVoltage_mV();
busvoltage = ina219.getBusVoltage_V();
current_mA = ina219.getCurrent_mA();
power_mW = ina219.getPower_mW();
loadvoltage = busvoltage + (shuntvoltage / 1000);
Serial.print("Bus Voltage: "); Serial.print(busvoltage); Serial.println(" V");
Serial.print("Shunt Voltage: "); Serial.print(shuntvoltage); Serial.println(" mV");
Serial.print("Load Voltage: "); Serial.print(loadvoltage); Serial.println(" V");
Serial.print("Current: "); Serial.print(current_mA); Serial.println(" mA");
Serial.print("Power: "); Serial.print(power_mW); Serial.println(" mW");
Serial.println("");
voltage = ina219.getBusVoltage_V()* 10;
Serial.print("voltage: "); Serial.print(voltage); //Serial.println(" V");
Serial.println("");
// lcd.print(voltage);
// delay(2000);
}
virtual void trigger (__attribute__ ((unused)) AlarmClock& clock) {
uint8_t msgcnt = device().nextcount();
measure();
if (last_flags != flags()) {
if (number() == 1) this->changed(true);
last_flags = flags();
}
tick = delay();
msg.init(msgcnt, number(), voltage);
if (msgcnt % 20 == 1) device().sendPeerEvent(msg, *this); else device().broadcastEvent(msg, *this);
sysclock.add(*this);
}
uint32_t delay () {
uint16_t d = (max(10, device().getList0().Sendeintervall()) * SYSCLOCK_FACTOR) + random(10); //add some small random difference between channels
return seconds2ticks(d);
}
void configChanged() {
}
void setup(Device<Hal, UList0>* dev, uint8_t number, uint16_t addr) {
Channel::setup(dev, number, addr);
sysclock.add(*this);
}
uint8_t status () const {
return 0;
}
uint8_t flags () const {
uint8_t flags = this->device().battery().low() ? 0x80 : 0x00;
return flags;
}
};
class UType : public MultiChannelDevice<Hal, MeasureChannel, NUM_CHANNELS, UList0> {
public:
typedef MultiChannelDevice<Hal, MeasureChannel, NUM_CHANNELS, UList0> TSDevice;
UType(const DeviceInfo& info, uint16_t addr) : TSDevice(info, addr) {}
virtual ~UType () {}
virtual void configChanged () {
TSDevice::configChanged();
DPRINT(F("*LOW BAT Limit: "));
DDECLN(this->getList0().lowBatLimit());
this->battery().low(this->getList0().lowBatLimit());
DPRINT(F("*Sendeintervall: ")); DDECLN(this->getList0().Sendeintervall());
}
};
UType sdev(devinfo, 0x20);
ConfigButton<UType> cfgBtn(sdev);
void setup () {
DINIT(57600, ASKSIN_PLUS_PLUS_IDENTIFIER);
sdev.init(hal);
buttonISR(cfgBtn, CONFIG_BUTTON_PIN);
sdev.initDone();
// Initialize the INA219.
// By default the initialization will use the largest range (32V, 2A). However
// you can call a setCalibration function to change this range (see comments).
ina219.begin();
// To use a slightly lower 32V, 1A range (higher precision on amps):
//ina219.setCalibration_32V_1A();
// Or to use a lower 16V, 400mA range (higher precision on volts and amps):
ina219.setCalibration_16V_400mA();
Serial.println("Measuring voltage and current with INA219 ...");
}
void loop() {
bool worked = hal.runready();
bool poll = sdev.pollRadio();
if ( worked == false && poll == false ) {
hal.activity.savePower<Sleep<>>(hal);
}
}
Ausserdem macht das der Laderegler schon. Primär geht es darum den Akku mit dem bösen Kohlestrom nachzuladen, wenn die Sonne schwächelt. Und das funktioniert klasse.
Die Verdrahtung sollte sich von selbst ergeben aus den Datenblatt der Sensorplatine und der Doku zu AskSinPP.
ps: Ich hab versucht, eine LCD-Anzeige einzubinden, das überstieg meine Fähigkeiten und habs sein lassen....