Nachbau AsksinPP Phasenanschnittdimmer HM-LC-Dim1L-CV

Begonnen von m_schmid@posteo.de, 16 März 2024, 14:36:32

Vorheriges Thema - Nächstes Thema

m_schmid@posteo.de

Hallo zusammen,

ich versuche gerade, einen Phasenanschnittdimmer auf AsksinPP-Basis nachzubauen.
Auf https://asksinpp.de habe ich kein passendes Projekt gefunden und da dachte ich, dass fehlt doch noch in der Sammlung :-).

Jetzt bin ich leider an einem Punkt, an dem ich nicht weiterkomme. Vielleicht lesen hier ein paar Profis mit, die mir helfen können?!
So weit bin ich in der Zwischenzeit: https://maschmid.next-cloud.org/index.php/s/7gZ2EqyjfMeqoK9

Ich bin auf 3 Probleme gestoßen:

1. Nach dem Einstecken / Anlegen der Netzspannung bleibt er nicht aus sondern schickt alle 40ms einen Zündimpuls mit ca. 8ms Länge.
Dieser verschwindet erst, wenn ich den Dimmer über FHEM einschalte bzw. irgendeinen Dim-Grad >0 vorgebe.

2. Schalte ich auf "off", kommt es manchmal (nicht reproduzierbar) vor, dass er ein Dauersignal (true) am Zündausgang anlegt.

3. Dimme ich auf 0 Prozent herunter, fährt er zwar ordnungsgemäß entsprechend der Rampe bis auf 0, schaltet dann aber statt auf "aus" auf Dauer-Ein wie bei Punkt 2

Jetzt habe ich zwar Lösungen dafür gefunden, die sind aber eher Pfusch. Wenn auch funktionell ;-).
Problem Nr.1 und 2. habe ich so gelöst:
Innerhalb von void setup() die Zeile
phaseCut.stop();
hinzugefügt

Innerhalb von void loop() die Zeile
if(!phaseCut.isrunning()) digitalWrite(DIMMERPIN, false);
hinzugefügt.

Was das Problem Nr. 3 angeht habe ich auch eine Lösung gefunden. Zugegeben durch ausprobieren. Ich weiß leider nicht, *warum* ich das Problem damit behoben habe. In der PWM.h findet sich die Lookup-Table für die Output-Compare-Interrupts des Timer 2. Wenn ich dieses Array um 5 vergrößere und die Umrechnung weiter unten passend abändere, verschwindet das Problem und er bringt eine saubere Nulllinie, wenn er soll.

PWM.h, Zeile 25:
static const uint8_t zctable[50] PROGMEM = {
 9, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 53, 55, 60, 62, 64, 68, 70, 72, 76
};


PWM.h, Zeile 86:
#if PHASECUTMODE == 1   
  uint8_t offset = (STEPS - value)*49/STEPS;


Jetzt könnte ich damit zufrieden sein, was mich selbst angeht. So ist das aber nicht sauber als Projekt veröffentlichbar. Hat irgendjemand Erfahrung damit und kann mir sagen, ob ich einen groben Fehler gemacht habe? Im Anhang ist ein Oszi-Bild für den Zustand nach dem Einschalten (Problem Nr. 1). Dabei ist die gelbe Kurve die Spannung des Nulldurchgangsdetektors und die blaue die Spannung an der LED des Opto-TRIAC, der den Haupt-TRIAC schaltet.

Die main.cpp sieht bei mir so aus:
//- -----------------------------------------------------------------------------------------------------------------------
// AskSin++
// 2016-10-31 papa Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
// 2018-10-07 jp112sdl Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
// 2019-01-10 scuba82 Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
// ci-test=yes board=328p aes=no
//- -----------------------------------------------------------------------------------------------------------------------
// define this to read the device id, serial and device type from bootloader section
//#define USE_OTA_BOOTLOADER
#define NDEBUG
#define EI_NOTEXTERNAL
#define NORTC
// PIN definitions
#define DIMMERPIN          7 
#define LED_PIN            4
#define CONFIG_BUTTON_PIN  8
#define GDO0_PIN           2
#define ZEROPIN            3
#define NTC_SENSE_PIN      A0
#define NTC_ACTIVATOR_PIN   0  // pin to power ntc (or 0 if connected to vcc)
// NTC definitions
#define NTC_T0 25 // temperature where ntc has resistor value of R0
#define NTC_R0 10000 // resistance both of ntc and known resistor
#define NTC_B 3977 // b value of ntc (see datasheet)
#define NTC_OVERSAMPLING 2 // number of additional bits by oversampling (should be between 0 and 6, highly increases number of measurements)
// Phase Cut mode
#define PHASECUT_MODE 1 // 0 = trailing-edge phase cut; 1 = leading-edge phase cut
// number of available peers per channel
#define PEERS_PER_DimChannel     4
#define PEERS_PER_RemoteChannel  8
#include <Arduino.h>
#include <Wire.h>
#include <EnableInterrupt.h>
#include <AskSinPP.h>
#include <Dimmer.h>
#include <sensors/Ntc.h>
// all library classes are placed in the namespace 'as'
using namespace as;
// define all device properties
const struct DeviceInfo PROGMEM devinfo = {
    {0x10,0x12,0x22},       // Device ID
    "mankutHM02",           // Device Serial
    {0x00,0x12},            // Device Model
    0x10,                   // Firmware Version
    as::DeviceType::Dimmer, // Device Type
    {0x01,0x00}             // Info Bytes
};
/**
   Configure the used hardware
*/
typedef AvrSPI<10,11,12,13> SPIType;
typedef Radio<SPIType, GDO0_PIN> RadioType;
typedef StatusLed<LED_PIN> LedType;
typedef AskSin<LedType, NoBattery, RadioType> Hal;
Hal hal;
typedef DimmerChannel<Hal, PEERS_PER_DimChannel> DimChannel;
typedef DimmerDevice<Hal, DimChannel, 3, 3> DimDevice;
DimDevice sdev(devinfo, 0x20);
DimmerControl<Hal,DimDevice,ZC_Control<>> control(sdev);
ConfigToggleButton<DimDevice> cfgBtn(sdev);
class TempSens : public Alarm {
  Ntc<NTC_SENSE_PIN,NTC_R0,NTC_B,NTC_ACTIVATOR_PIN,NTC_T0,NTC_OVERSAMPLING> ntc;
 
  public:
  TempSens () : Alarm(0) {}
  virtual ~TempSens () {}
  void init () {
    ntc.init();
    set(seconds2ticks(15));
    sysclock.add(*this);
  }
  virtual void trigger (AlarmClock& clock) {
    ntc.measure();
    DPRINT("Temp: ");DDECLN(ntc.temperature());
    control.setTemperature(ntc.temperature());
    set(seconds2ticks(2));
    clock.add(*this);
  }
};
TempSens tempsensor;
void setup () {
  DINIT(57600, ASKSIN_PLUS_PLUS_IDENTIFIER);
  if( control.init(hal,DIMMERPIN) ){
    sdev.channel(1).peer(cfgBtn.peer());
  }
 
  buttonISR(cfgBtn, CONFIG_BUTTON_PIN);
  tempsensor.init();
  // Set frequency for CC1101 to 868.370MHz
  hal.radio.initReg(CC1101_FREQ2, 0x21);
  hal.radio.initReg(CC1101_FREQ1, 0x66);
  hal.radio.initReg(CC1101_FREQ0, 0x1A);
 
  sdev.initDone();
  phaseCut.Stop();
 
}
void loop() {
  hal.runready();
  sdev.pollRadio();
  if(!phaseCut.isrunning()) digitalWrite(DIMMERPIN, false);
}