RFD-FHEM / SIGNALDuino

System to capture digital signaldata and transfer them to another system
GNU General Public License v3.0
83 stars 35 forks source link

signalDecoder: Bugfixing und Verbesserungen #67

Open Ralf9 opened 7 years ago

Ralf9 commented 7 years ago

Ich habe in der doDetect() einige Verbesserungen vorgenommen. Die gleichen patterrnNr in Folge im message Puffer sind jetzt weg.

Damit waren die meisten gleichen patterrnNr in Folge weg. https://github.com/RFD-FHEM/SIGNALDuino/blob/2958b4ac2f989301f88eb8ca5367377eed279d0f/src/_micro-api/libraries/signalDecoder/src/signalDecoder.cpp#L183

Es blieben aber noch einige gleiche patterrnNr in Folge übrig, die schwer zu finden waren. Damit wurde der last pulse mit dem aktuellen first überschrieben. Der Fehler in der calcHisto Routine konnte sich da auch ausgewirkt haben

            for (uint8_t i = messageLen - 1; i >= 0 && histo[pattern_pos] > 0; --i)
            {
                if (message[i] == pattern_pos) // Finde den letzten Verweis im Array auf den Index der gleich ueberschrieben wird
                {
                    i++; // i um eins erhoehen, damit zukuenftigen Berechnungen darauf aufbauen koennen
                    bufferMove(i);
                    break;
                }

            }

Ich habe die Routine abgeändert. Nun wird zuerst ein compress_pattern versucht, falls kein compress möglich war, entferne ich Zeichen am Anfang des message Puffers:

                    uint8_t idx;
                    for (uint8_t i = 0; i<messageLen; i++)
                    {
                        idx = message[i];
                        if (histo[idx] == 1)
                        {
                            pattern[idx] = 0;
                            bufferMove(i+1);
                            pattern_pos = idx;
                            break;
                        }
                        else
                        {
                            histo[idx]--;
                        }
                    }

Diese Routine gefällt mir noch nicht so richtig: Damit wird processMessage() auch aufgerufen, wenn die mindest messageLen noch nicht erreicht wurde. Wenn beim Aufruf von processMessage() das "m_truncated = false" ist, dann wird in der processMessage() ein reset() durchgeführt!

        // Add pattern
        if (patternLen == maxNumPattern)
        {
            calcHisto();
            if (histo[pattern_pos] > 2)
            {
                processMessage();
                calcHisto();
sidey79 commented 7 years ago

Hi Ralf,

ich komme da leider noch nicht ganz mit. Ich würde auch in der SIGNALDetector Klasse vorerst noch nichts ändern, bis nicht die Fehler in der Bitstore Klasse beseitigt wurden.

Einige Fehler konnte ich schon identifizieren und ausbessern. Einen habe ich aber noch nicht gefunden. Da passen auf einmal die Variable valcount unt bitcount nicht mehr zusammen. Das führt dann auch zu Einträgen mit fehlerhaftem Vorzeichen.

Ralf9 commented 7 years ago

ich konnte außer dem bcnt Fehler in der moveLeft und der etwas unsauberen Variablen Definitionen keine weiteren Fehler in der Bitstore Klasse finden. Nach dem korrigieren des bcnt in der moveLeft und änderen einiger Variablen Definitionen, konnte ich in der Bitstore Klasse keine Fehler mehr finden. Kannst Du ausschliessen, daß die z.T. unsaubere Variablen Definitionen ein Teil deiner Probleme verursacht?

sidey79 commented 7 years ago

Hi Ralf,

Ich mache es aktuell so: Wenn ich einen Fehler anhand von Debug Ausgaben finde, dann Stelle ich die Situation in einem Testprogramm nach.

Mit diesem Testprogramm prüfe ich dann auch meine Fehlerbehebung und passe so lange an, bis alle Tests erfolgreich sind.

Dadurch habe ich nun schon einige Anpassungen verifiziert. Die Berechnung von valcount habe ich so angepasst, dass es relativ zum vorherigen Wert berechnet wird und nicht mehr absolut.

Irgendwo hapert es aber noch mit der Berechnung von bitcount . Da habe ich leider noch nicht genug Ausgaben eingebaut, um diesen Fehler reproduzieren zu können.

sidey79 commented 7 years ago

Uups, ich meinte die Berechnung von bytecount ist fehlerhaft und nicht bitcount

Ralf9 commented 7 years ago

Ich habe mal meine Verbesserungen und Überarbeitungen von doDetect() und bitstore.h in github commited. Es kann sein, das es noch nicht ganz passt https://github.com/Ralf9/SIGNALDuino/tree/dev-r332_cc1101

HomeAutoUser commented 7 years ago

Hallo @Ralf9 , deine Version empfängt auf jedenfall im Gegensatz zu @sidey79 seiner aktuellen Version die Hideki Protokolle wie von mir hier schon erwähnt. Im Groben kann ich erstmal sagen, läuft. Langzeit werde ich verfolgen.

sidey79 commented 7 years ago

Tia, ich weiss jetzt leider nicht , ob mir das hilft.

Ich weiss nicht genau, was der Fehler ist. Ich sehe nur sehr viele Änderungen, die ich so erst Mal nicht nachvollziehen kann.

Wieso damit jetzt Hideki besser sein soll verstehe ich auch nicht.

Ralf9 commented 6 years ago

Hallo Sidey,

ich habe versucht die doDetect Routine zu optimieren. Bei der jetztigen Struktur tue ich mich dabei etwas schwer. Mit der folgenden Struktur müsste es einfacher sein. Ich werde es mal so versuchen:

bool valid;
valid = (messageLen == 0 || last == NULL || (*first ^ *last) < 0); // true if a and b have opposite signs
valid &= (*first > -maxPulse); // if low maxPulse detected, start processMessage()

!valid bedeuted, daß ein Signalende erkannt wurde. Ein voller message Puffer ist kein Signalende. Stark vereinfacht stelle ich mir die Verarbeitung so ungefähr vor: Wenn !valid dann:

processMessage();
wenn messageLen < minMessageLen dann reset()
wenn nach dem processMessage messageLen > minMessageLen ist, dann gibt es noch Wiederholungen die mit einem weiteren processMessage() ausgegeben werden
last = NULL

Wenn valid dann:

wenn messagePuffer voll, dann processMessage()
wenn der PatternPuffer voll ist, dann compress_pattern()
wenn es danach immer noch kein Platz im PatternPuffer hat, dann werden Einträge vom messagePuffer entfernt
sidey79 commented 6 years ago

Ja ich denke ich verstehe deinen Ansatz.

Ich hatte das auch mal so ähnlich angedacht, aber wenn der Puffer voll ist und man kein processMessage probiert, dann verliert man alle Wiederholungen.

Ralf9 commented 6 years ago

Ich habe das mit dem !valid = Signalende erkannt, mal bei mir eingebaut. https://github.com/Ralf9/SIGNALDuino/tree/dev-r332_cc1101

Ich hatte vor die Add pattern Routine vom doDetect() zu optimieren, dies hat aber nicht so funktioniert wie ich es vor hatte. Dies ist doch sehr viel komplexer als ich dachte. Ich verwende nun wieder Deine Add pattern Routine.

Gefühlsmäßig müsste in der Add pattern Routine noch Verbesserungspotential sein. Z.B. bei den MU-Nachrichten ist mir aufgefallen, daß am Anfang was fehlt, beim decodieren wird dann die Wiederholung verwendet.

Mir ist auch aufgefallen, daß mein hideki Sensor mit dem RXB6 Empfänger sehr viel besser erkannt wird.

Beim RXB6 Empfänger werden in der Regel alle 3 Wiederholungen vollständig erkannt:

MC;LL=-1062;LH=890;SL=-569;SH=408;D=AE0B174A6183EBB1543B280;C=488;L=89;
MC;LL=-1010;LH=938;SL=-527;SH=449;D=A8FA745AEF3E0A2755E37CE;C=487;L=91;
MC;LL=-1005;LH=947;SL=-522;SH=456;D=AE0B174A4183EBB1543A320;C=488;L=90;

MC;LL=-1051;LH=898;SL=-567;SH=407;D=A8FA745ACA3E0A2755B24D6;C=487;L=91;
MC;LL=-1011;LH=941;SL=-523;SH=450;D=AE0B174A2B83EBB154994B0;C=487;L=90;
MC;LL=-1004;LH=947;SL=-517;SH=459;D=AE0B174A4B83EBB1549A7F0;C=487;L=90;

MC;LL=-1052;LH=896;SL=-564;SH=410;D=A8FA745ACF3E0A2755E26BE;C=486;L=91;
MC;LL=-1009;LH=941;SL=-523;SH=454;D=AE0B174A2183EBB15439060;C=487;L=90;
MC;LL=-1007;LH=941;SL=-522;SH=456;D=AE0B174A4183EBB1543A320;C=487;L=90;
Beim cc1101 werden in der Regel nur max 2 Wiederholungen vollständig erkannt:

MC;LL=-1028;LH=929;SL=-548;SH=422;D=AE0B174A6B83EBB1549B650;C=487;L=90;R=61;
MC;LL=-1013;LH=953;SL=-516;SH=458;D=A8FA745AEA3E0A2755B35A6;C=489;L=91;R=61;
MC;LL=-1023;LH=939;SL=-526;SH=443;D=A2D6D1F0513AAD9603;C=488;L=72;R=61;

MC;LL=-1011;LH=942;SL=-531;SH=448;D=ACA3E0A2755B24D6;C=488;L=63;R=67;
MC;LL=-1022;LH=931;SL=-548;SH=434;D=A8FA745AEA3E0A2755B35A6;C=489;L=91;R=67;
MC;LL=-1018;LH=944;SL=-531;SH=446;D=AE0B174A4B83EBB1549A7F0;C=489;L=90;R=67;

MC;LL=-1028;LH=917;SL=-532;SH=452;D=A8FA745ACA3E0A2755B24D6;C=488;L=91;R=71;
MC;LL=-1020;LH=938;SL=-524;SH=444;D=AEA3E0A2755B35A6;C=487;L=63;R=71;
MC;LL=-1011;LH=950;SL=-516;SH=455;D=A8FA745ADA3E0A2755B2C06;C=488;L=91;R=71;

Beim RXB6 Empfänger werden die beiden Wiederholungen vom FS10 Sender zuverlässig erkannt. Beim cc1101 werden die Tastendrücke vom FS10 Sender nicht zuverlässig erkannt.

sidey79 commented 6 years ago

Vielleicht liegt es daran, dass beim cc1101 kein rauchen empfangen wird und dadurch der Pin nicht permanent toggelt.

HomeAutoUser commented 6 years ago

Hallo, ich habe soeben mal @Ralf9 Firmware am laufen. Die Widerholung sieht schonmal gut aus. Diese funktioniert auch bei den 868Mhz - FHT Protokollen. Bei den anderen Protokollen muss ich dies noch verifzieren.

Mal "dahin" gefragt, was ist der große Unterschied in dem jetzigen Code zum "damaligen" Stand juni von @sidey79. Eines ist auffällig. Seitdem wir versuchen das ganze zu Debugen mit addData, ist der Empfang der Hideki Protokolle schlechter. Ich habe das mal durchgespielt als ich die alte FW nutzte und nun diese von Dir Ralf oder von Sidey. Der Count der Nachrichten ist immer mindestens ca. 1/3 geringer als bei der noch fehlerhaften Firmware vom Juni.

elektron-bbs commented 6 years ago

Mhmm, irgend etwas muss ich falsch machen :-( Bei mir splittet es die Nachrichten vom FHT80 nicht.

SIGNALDuino-dev-r332_cc1101_2017-10-30_Ralf9:

2017.10.30 13:42:20 4: sduino868/msg READredu: MU;P0=-32001;P1=379;P2=-409;P3=579;P4=-605;P5=-9312;D=0121212121212121212121212341234123412123412341212123434121234341212121212121212123412341212343412121212121212121212121212123434341234121512121212121212121212121234123412341212341234121212343412123434121212121212121212341234121234341212121212121212121212;CP=1;R=33;O;
2017.10.30 13:46:11 4: sduino868/msg READredu: MU;P0=-32001;P1=388;P2=-398;P3=581;P4=-597;P5=-9304;D=0121212121212121212121212341234123412123412341212123434121234341212121212121212123412341212343412121212121212121212121212123434341234121512121212121212121212121234123412341212341234121212343412123434121212121212121212341234121234341212121212121212121212;CP=1;R=33;O;

Die Wiederholung nach der Pause von ca. 9 mSek wird von FHEM an FHT80TF übergeben und dort natürlich nicht dekodiert, was ja auch so richtig ist.

Mit dem Parameter probiere ich jetzt gerade herum (war ursprünglich 0): CSmuthresh= -> Schwellwert für den split von MU Nachrichten (0=aus)

Werte von 1 bis 10 splitten die Nachrichten so:

2017.10.30 16:14:54 4: sduino868/msg READ: MS=1;MU=1;MC=0;Mred=1;Mdebug=0_MScnt=3;MuSplitThresh=10
2017.10.30 16:18:16 4: sduino868/msg READredu: MU;P0=-32001;P1=399;P2=-398;P3=575;P4=-611;P5=-9312;D=012121212121212121212121234123412341212;CP=1;R=33;O;
2017.10.30 16:18:16 4: sduino868/msg READredu: MU;P1=393;P2=-402;P3=584;P4=-595;P5=-9312;D=412341212123434121234341212121212121212;CP=1;R=33;e;
2017.10.30 16:18:16 4: sduino868/msg READredu: MU;P1=393;P2=-402;P3=584;P4=-595;P5=-9312;D=234123412123434121212121212121212121212;CP=1;R=33;e;
2017.10.30 16:18:16 4: sduino868/msg READredu: MU;P1=393;P2=-402;P3=584;P4=-595;P5=-9312;D=212343434123412151212121212121212121212;CP=1;R=33;e;
u.s.w.

Was versteckt sich hinter dem Parameter "CSmuthresh" genau? Durch probieren habe ich jetzt herausgefunden, das da wahrscheinlich die minimale Pausenzeit im mSek hin gehört. Mit einem Wert von 8000 trennt es mir jedenfalls jetzt die Nachrichten:

2017.10.30 16:29:55 4: sduino868/msg READ: MS=1;MU=1;MC=0;Mred=1;Mdebug=0_MScnt=3;MuSplitThresh=8000
2017.10.30 16:31:44 4: sduino868/msg READredu: MU;P0=-13904;P1=396;P2=-400;P3=590;P4=-598;P5=-9296;D=012121212121212121212121234123412341212341234121212343412123434121212121212121212341234121234341212121212121212121212121212343434123412;CP=1;R=33;O;
2017.10.30 16:31:44 4: sduino868/msg READredu: MU;P1=387;P2=-405;P3=577;P4=-604;P5=-9296;D=512121212121212121212121234123412341212341234121212343412123434121212121212121212341234121234341212121212121212121212121212343434123412;CP=1;R=33;e;
Ralf9 commented 6 years ago

Ja das muthresh ist der Patternwert ab dem eine Pause erkannt wird. Hier wäre es ca 9000. Das passt so jetzt, es sind 2 gleiche Nachrichten. Welche Vorteile habt Ihr, wenn Ihr bei dem MU Nachrichten die Wiederholungen habt? Wird bei diesem Protokoll die Nachricht einmal wiederholt? Ein "O" an Ende bedeutet übrigens, das der Puffer voll ist, und ein "e" bedeutet, daß ein Nachrichten ende erkannt wurde.

elektron-bbs commented 6 years ago

Da die Auswertung ja auf ">= MuSplitThresh" prüft, würde ich hier z.B. 5000 einstellen. Aber wie Sidey schon bemerkt hatte, wäre es sicher besser, diesen Wert nicht benutzerdefiniert zu machen. Das ist zum einen keinem Nutzer zumutbar, die Protokolle zu kennen und zum anderen braucht man ja u.U. bei verschiedenen Protokollen unterschiedlich Werte. Gefühlsmäßig würde ich den Wert so auf 5 bis 10 mal größte Pulslänge setzen.

Welche Vorteile habt Ihr, wenn Ihr bei dem MU Nachrichten die Wiederholungen habt?

Der Vorteil ist höhere Übertragungssicherheit, wenn der erste Teil vielleicht nicht erkannt wurde, klappt es halt mit dem zweiten :-) Außerdem erinnere ich mich an ein anderes Protokoll (Siro m.E.), da wurde ein bestimmter Befehl erst in einer Wiederholung übertragen.

Wird bei diesem Protokoll die Nachricht einmal wiederholt?

Beim FHT80 einmal, bei FS20 bis zu zweimal.

Ralf9 commented 6 years ago

Hallo Sidey,

ich verstehe noch nicht so richtig wie die Add pattern Routine funktioniert.

        // Add pattern
        if (patternLen == maxNumPattern)
        {
            calcHisto();
            if (histo[pattern_pos] > 2)
            {
                processMessage();
                calcHisto();

            }
            for (uint8_t i = messageLen - 1; i >= 0 && histo[pattern_pos] > 0; --i)
            {
                if (message[i] == pattern_pos) // Finde den letzten Verweis im Array auf den Index der gleich ueberschrieben wird
                {
                    i++; // i um eins erhoehen, damit zukuenftigen Berechnungen darauf aufbauen koennen
                    bufferMove(i);
                    break;
                }

            }

        }

Wenn ich das richtig verstehe, wird bei einem neuen Pattern das älteste Pattern im Patternpuffer überschrieben.

Mir ist aber nicht klar zu was dies nötig ist?

            if (histo[pattern_pos] > 2)
            {
                processMessage();
                calcHisto();
            }
sidey79 commented 6 years ago

Der Abschnitt dient dazu, processMessage aufzurufen, wenn das Pattern, welches überschrieben werden soll mehr als 2 Mal in der Nachricht vorkommt

Ralf9 commented 6 years ago

in findpatt() wird ein tolfact von 0,2 verwendet tol = abs(val)*0.2; und in reset() steht tolFact = 0.25;

ist dies so ok?

Ralf9 commented 6 years ago

Hallo Sidey,

ich habe in der calcHisto Routine noch einige Fehler gefunden. Eine ungerade startpos wurde nicht berücksichtigt und das endpos hat auch noch nicht ganz gepasst:

void SignalDetectorClass::calcHisto(const uint8_t startpos, uint8_t endpos)
{
    for (uint8_t i = 0; i<maxNumPattern; ++i)
    {
        histo[i] = 0;
    }

    if (endpos == 0) endpos = messageLen-1;
    uint8_t bstartpos = startpos/2;       // *4/8;
    uint8_t bendpos = endpos/2;           // *4/8;
    uint8_t bval;
    if (startpos % 2 == 1)  // ungerade
    {
        message.getByte(bstartpos,&bval);
        histo[bval & B00001111]++;
        bstartpos++;
    }
    for (uint8_t i = bstartpos; i <= bendpos; ++i)
    {
        message.getByte(i,&bval);
        histo[bval >> 4]++;
        histo[bval & B00001111]++;
    }
    if (endpos % 2 == 0)  // gerade
    {
        message.getByte(bendpos, &bval);
        histo[bval & B00001111]--;
    }
}

Nun ist mir aufgefallen, daß sich die Add pattern Routine jetzt etwas anders verhält. Bei MS Nachrichten ist nun das mStart viel größer als vorher:

Sync: -3894 -> SyncFact: -7.91, Clock: 492, Tol: 198, PattLen: 4 (4), Pulse: F/L 492, -980, mStart: 42, mend: 115, valcnt: 254, MCD: 0, mtrunc: 1, state: 2
Signal: 01020102020202020202020202010201010101020103010202010201020202010201010101010201020202020202020202020102010101010201030102020102010202020102010101010102010202020202020202020201020101010102010301020201020102020201020101010101020102020202020202020202010201.  [254]
Pattern:  P0: 37*[492] P1: 16*[-980] P2: 20*[-1938] P3: 1*[-3894]

MS;P0=492;P1=-980;P2=-1938;P3=-3894;D=03010202010201020202010201010101010201020202020202020202020102010101010201;CP=0;SP=3;R=11;O;
Sync: -9028 -> SyncFact: -17.07, Clock: 529, Tol: 6282, PattLen: 6 (6), Pulse: F/L -9168, -31412, mStart: 34, mend: 101, valcnt: 102, MCD: 0, mtrunc: 0, state: 2
Signal: 012121232321232321232123212323242124212323232123212121212123212121212323212321212121212323212323212325.  [102]
Pattern:  P0: 0*[180] P1: 19*[-2081] P2: 34*[529] P3: 13*[-4133] P4: 1*[-9028] P5: 1*[-31412]

MS;P1=-2081;P2=529;P3=-4133;P4=-9028;P5=-31412;D=24212323232123212121212123212121212323212321212121212323212323212325;CP=2;SP=4;R=249;
Sync: -8964 -> SyncFact: -15.30, Clock: 586, Tol: 1379, PattLen: 8 (0), Pulse: F/L -6896, 586, mStart: 45, mend: 71, valcnt: 72, MCD: 0, mtrunc: 1, state: 2
Signal: 012304540454645454645454645454545454545454645407645454545464646454646464.  [72]
Pattern:  P0: 1*[-8964] P1: 0*[204] P2: 0*[-116] P3: 0*[112] P4: 13*[586] P5: 5*[-2096] P6: 7*[-4144] P7: 1*[292]

MS;P0=-8964;P4=586;P5=-2096;P6=-4144;P7=292;D=407645454545464646454646464;CP=4;SP=0;R=249;

In der processMessage hat bei MS Nachrichten bei der Abfrage "(messageLen - mstart) >= minMessageLen" gefehlt: if ((m_endfound && (mend - mstart) >= minMessageLen) || (!m_endfound && messageLen < maxMsgSize && (messageLen - mstart) >= minMessageLen))

sidey79 commented 6 years ago

@Ralf9

Ich habe mir mal die Laufzeit einiger Passagen angesehen...

void SignalDetectorClass::processMessage()
{
    unsigned long t = micros();
    yield();

    if (mcDetected == true || messageLen >= minMessageLen) {
        success = false;
        m_overflow = (messageLen == maxMsgSize) ? true : false;

#if DEBUGDETECT >= 1
        DBG_PRINTLN("Message received:");
#endif

        compress_pattern();
        d = micros() - t;

compress_pattern kann durchaus mal 10 ms andauern. Da läuft der Puffer durchaus mal voll. :(

Ralf9 commented 6 years ago

Ja, das habe ich inzwischen auch festgestellt, daß in der compress_pattern anscheinend etwas nicht zu passen scheint. Der bug tritt aber recht selten auf. Ich denke, daß dies aber nichts mit der Laufzeit zu tun hat.

Ralf9 commented 6 years ago

Kann es sein, daß in dieser Zeile was nicht passt? pattern[idx] = ((long(pattern[idx]) * histo[idx]) + (pattern[idx2] * histo[idx2])) / sum;

Ich habe ein paar Debugausgaben eingefügt:

                int  sum = histo[idx] + histo[idx2];
                int lPatternIdx = pattern[idx];
                pattern[idx] = ((long(pattern[idx]) * histo[idx]) + (pattern[idx2] * histo[idx2])) / sum;
                if (abs(pattern[idx]) < 90) {
                    DBG_PRINT("upfirst<90 ");DBG_PRINT(idx);DBG_PRINT(" ");DBG_PRINT(idx2);DBG_PRINT(" ");DBG_PRINTLN(lPatternIdx);
                    printOut();
                }

und bekomme diese Ausgabe!

upfirst<90 0 4 724
Signal: 12305060606050505060605050605050505060506060605050605060606060505060605060505070507050606060505050606050506050505050605060606050506050606060605050606050605050705070506060605050506060505060505050506050606060505060506060606050506060506050507050705060606054.  [254]
Pattern:  P0: 1*[45] P1: 1*[-160] P2: 1*[208] P3: 1*[-92] P4: 125*[564] P5: 62*[-2094] P6: 57*[-4090] P7: 6*[-9019]

P0:1[724] + P4: 125[564] = 45 passt nicht so richtig!

oder

upfirst<90 0 3 -2084
Pattern:  P0: 9*[-53] P1: 2*[-764] P2: 125*[554] P3: 56*[-2068] P4: 53*[-4110] P5: 6*[-9015] P6: 2*[774] P7: 1*[-1008]

P0: 9[-2084] + P3: 56[-2068] = -53

sidey79 commented 6 years ago

Der Wertebereich läuft über, da pattern[idx2] * histo[idx2] in der Klammer steht und nur ein int ist (16 Bit)

Ralf9 commented 6 years ago

ist es so besser? pattern[idx] = ((long(pattern[idx]) * histo[idx]) + (long(pattern[idx2]) * histo[idx2])) / sum;

sidey79 commented 6 years ago

Ich würde Mal darauf tippen, dass es dann klappt ;)

Ralf9 commented 6 years ago

nun scheint es zu klappen, bis jetzt hatte ich keine Wrong Data after compress_pattern mehr. Kann sich durch den Wertebereich überlauf auch das Vorzeichen geändert haben?

Ralf9 commented 6 years ago

Zu was ist ein nach einem compresspattern noch ein calcHisto notwendig?

Ralf9 commented 6 years ago

Zu was ist nach einem compresspattern noch ein calcHisto notwendig?

sidey79 commented 6 years ago

Definitiv kann sich auch das Vorzeichen ändern ja.

Das CalcHisto ist notwendig, um die Anzahl an Pulsen zu berechnen. Gut, man könnte das auch in compressPattern einbaueb

Ralf9 commented 6 years ago

Am Ende der compressPattern ist die histo[] Anpassung schon drin. Dies müsste doch so reichen?

                histo[idx] += histo[idx2];
                pattern[idx2] = histo[idx2]= 0;
sidey79 commented 6 years ago

Das reicht ja.

sidey79 commented 6 years ago

Eigentlich könnte man die Pulse durch 8 teilen. Genauer ist der Microcontroller bei 16 Mhz nicht. Dadurch könnte man den ein oder anderen Fall auch verbessern.

71 dürfte damit aber gelöst sein schätze ich

sidey79 commented 6 years ago

Ich denke ich bekomme die Laufzeit von compress_pattern auf max 1,2 ms runter.

Ralf9 commented 6 years ago

Ich habe mal testweise in der findpatt die tol auf 0,25 erhöht tol = abs(val)*tolFact; Ich hatte gehofft, daß dann compress_pattern nichts mehr zu tun hat. Dem ist aber nicht so. Wo ist da mein Denkfehler?

Hier z.B. kann P0 & P4 und P3 & P6 und P5 & P7 durch compress_pattern zusammengefasst werden:

Signal: 01023101010102056131023101010102073102010135020.  [47]
Pattern:  P0: 17*[510] P1: 14*[-1965] P2: 6*[-1053] P3: 5*[899] P4: 1*[452] P5: 2*[-484] P6: 1*[1036] P7: 1*[-572]

Die Laufzeit von compress_pattern müsste man recht einfach etwas verringern können, wenn man idx und idx2 tauscht, wenn histo[idx2] > histo[idx])

if (inTol(pattern[idx2], pattern[idx], tol))  // Pattern are very equal, so we can combine them
    {
    nidx = idx;
    nidx2 = idx2;
    if (histo[idx2] > histo[idx]) {     // idx und idx2 tauschen
        nidx2 = idx;
        nidx = idx2;
    }
    for (uint8_t i = 0; i<messageLen; i++)
    {
        if (message[i] == nidx2)
        {
            message.changeValue(i, nidx);
        }
    }
    ..
sidey79 commented 6 years ago

@Ralf9 Ja, daran hatte ich auch gedacht, aber die Zeit geht beim suchen im message Puffer drauf. Da müsste man schon Glück haben und die Werte kommen ganz am Anfang.

Schau dir mal #73 an, dort habe ich die compress_pattern Routine umgeschrieben.

Ralf9 commented 6 years ago

Schau dir mal #73 an, dort habe ich die compress_pattern Routine umgeschrieben.

Sieht recht kompliziert und komplex aus. Kann ich auf die schnelle nicht überblicken muß ich mal in Ruhe anschauen. Damit kommen auch wieder einige neue evtl Fehlerquellen rein. Ich bleibe erst mal bei der momentanen Version. Ich kann bei mir keine FIFO Überläufe beobachten.

sidey79 commented 6 years ago

Ist vom Prinzip so wie auch in calc_histo dass man das Byte aus dem Puffer holt und vergleicht. Es könnten neue Fehler dazukommen, ich mag es mal lieber nicht ausschließen, aber nach ein bisschen testen sieht es jetzt eigentlich schon sehr gut bei mir aus.

Die alte Berechnung von mend war falsch ist mir beim Anpassen nun aufgefallen. Die stimmt nun auch.

Überläufe kann ich leider recht schnell erzeugen.

Ralf9 commented 6 years ago

Ich glaube ich habe in der BitStore.h noch einen Fehler gefunden:

bool BitStore<bufSize>::changeValue(const uint16_t pos, byte value)
{
    uint8_t bytepos = pos*valuelen / 8;
if ((bytepos) >= buffsize - 1) return false; // Out of Buffer

Bei "buffsize - 1" passt das "-1" nicht. Es müsste so sein: if ((bytepos) >= buffsize ) return false; // Out of Buffer

sidey79 commented 6 years ago

Stimmt, ich habe meinen Unittest gerade mal angepasst und den Fehler auch nachstellen können. Was ich mir dabei nur gedacht habe. Hmm.

Werde ich commiten, aber die changeValue Variante ist aber für Massenverarbeitung zu langsam

sidey79 commented 6 years ago

Ich frage mich gerade, wieso ich ein gleiches Bit an die MC Nachricht anfüge. Das sieht falsch aus:

https://github.com/RFD-FHEM/SIGNALDuino/blob/e613d7c3d0aa51cf6b327ef81ab8873dd8c50214/src/_micro-api/libraries/signalDecoder/src/signalDecoder.cpp#L1326

edit: Bin in de Zeile verrutscht

sidey79 commented 6 years ago

@Ralf9

Ich glaube ich habe heute zwei Fehler ausmerzen können. Nach einem quick check, sieht das mit dem MC Empfang jetzt auch bei mir deutlich besser aus,

sidey79 commented 6 years ago

@Ralf9

So ich denke ich weiss jetzt auch, wieso die MC Nachrichten invertiert sind.

Beschreibung: Auf ein MC Signal synchronisieren kann man sich in der Regel mit einem langen Puls. Je nachdem ob der high oder low ist, hat man das 1. bit (1 oder 0)

Vereinfacht kann man so demodulieren: Regel 1: A long pulse is the oppsosit of the last Regel 2: Two short pulses are the same as the last bit.

https://github.com/RFD-FHEM/SIGNALDuino/blob/6414e4fbd60901ee51e61e3c0fefb7ed2be7bae6/src/_micro-api/libraries/signalDecoder/src/signalDecoder.cpp#L1296-L1299

Das funktioniert und der Zustand des bits wird auch gesetzt.

Da die verschiedenen Sender das nicht unbedingt immer berücksichtigen, dass man sich auf das Signal erst einstellen muss und der erste long pulse ja durchaus recht "spät" kommt habe ich mir gedacht, ich erfasse alle short Pulse vor dem Long auch :) https://github.com/RFD-FHEM/SIGNALDuino/blob/6414e4fbd60901ee51e61e3c0fefb7ed2be7bae6/src/_micro-api/libraries/signalDecoder/src/signalDecoder.cpp#L1303-L1314

Danach beginnt dann ganz normal das Dekodieren, ab der gefundenen Position. https://github.com/RFD-FHEM/SIGNALDuino/blob/6414e4fbd60901ee51e61e3c0fefb7ed2be7bae6/src/_micro-api/libraries/signalDecoder/src/signalDecoder.cpp#L1437-L1454

Das Läuft jetzt falsch :-( .

  1. Alle short Puls vor dem Long werden mit dem zuerst ermittelten bit demoduliert.
  2. Der 1. long Puls wird invertiert, da Regel 1 greift.

Ich habe jetzt schon ein wenig experimentiert, aber bislang habe ich es noch nicht geschafft, die Bits vor dem 1. long korrekt zu demodulieren.

Beispiel:

Sendet man "0x0B" in den MC Decoder, dann entspricht das den Bits 0000 1011

Beispiel: Pattern: P0: 26[450] P1: 25[-450] P2: 101[-900] P3: 101[900] 0 10 10 10 2 3 2 01

Demoduliert wird aber "0x16" 0001 011 .

Das 1. Bit fehlt und das 4. Bit wird falsch mit 1 gesetzt (sollte ja 0 sein). Würde man Regel 1 anwenden, dann müssten die Bits vor dem ersten long pulse ja alle 1en sein. Stimmt aber nicht, man kanns nur nicht feststellen, da man ja nicht weiss welchen Teil der Übertragung man zuerst empfangen hat :(

Habe jetzt schon das ein oder andere experimentiert. Dabei kommt aber nie das richtige raus.

Ralf9 commented 6 years ago

mir wäre es lieber, wenn wir die invertierung beibehalten könnten. Bei einer nicht Invertierung würden wir wieder Probleme mit verschiedenen Firmwareversionen bekommen. Wir müssten in der MC_Parse Routine wieder eine Versionsabfrage einbauen. Bekommst Du es hin, das es so zuverlässig invertiert erkannt wird, wie es vor dem MCfix war?

sidey79 commented 6 years ago

Also aktuell ist es wohl invertiert und früher war es das vermutlich nicht. So genau weiss ich das jetzt nicht mehr auswendig ;-)

Ich würde es halt gerne richtig implementieren, weiss aber noch nicht so ganz wie ich das anstelle :(

Ralf9 commented 6 years ago

In der Version V 3.2 war es nicht invertiert, seit der Version V 3.3.x ist es invertiert

sidey79 commented 6 years ago

Naja, nicht invertiert scheint mir auch richtiger zu sein.

Ich hab nur gerade keine Idee wie ich die vier 0 am Anfang sicher erkennen könnte :-( Bin für jede Idee Dankbar.

sidey79 commented 6 years ago

Okay, ich habe eine Variante gefunden. Sieht im Testprogramm erst mal richtig aus. Eventuell muss ich jetzt die Preamble Detection noch mal anpassen. Daher erst mal eigener Branch

sidey79 commented 6 years ago

@Ralf9

Ich denke ich habs. Das meisste geht jetzt wie gewünscht.

Mein Somfy Testsignal, wird allerdings etwas anders demoduliert. Die ersten drei bits habe ich manuell verifiziert, das sollte so richtig sein.

sidey79 commented 6 years ago

@Ralf9

Für Oregon V2 haben wir die Polarität mit diesem Commit eingebaut:

https://github.com/RFD-FHEM/RFFHEM/blame/bbb51498c22cd7a2ac439a5b34e30fce8c6b4cc8/FHEM/00_SIGNALduino.pm#L283

Tia, der Salat ist, das funktioniert mit meinen Korrekturen nicht. Invert muss deakviert werden. Mache ich das, klappt der Empfang ganz gut.

Bisschen verzwickte Situation :( So eine Versionsabfrage haben wir ja schon im Code, aber ob das grundsätzlich hilft?

Ralf9 commented 6 years ago

Ich habe es mal getestet, für die Hideki passt es jetzt https://forum.fhem.de/index.php/topic,58396.msg717483.html#msg717483

Bisschen verzwickte Situation :( So eine Versionsabfrage haben wir ja schon im Code, aber ob das grundsätzlich hilft?

Eine Möglichkeit wäre z.B. als Kennzeichnung für die nichtinvertierung z.B. ein Buchstabe in der MC-Nachricht klein zu schreiben z.B. MC;ll=-1024;LH=93 oder MC#LL=-1024;LH=93 oder besser Mc;LL=-1024;LH=93