Ankündigung

Einklappen
Keine Ankündigung bisher.

Arduino 1Wire Siemens BCU

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    KNX/EIB Arduino 1Wire Siemens BCU

    Zurzeit bin ich dabei von Bticino Bus auf KNX umzustellen Geräte sind bestellt und in der Zwischenzeit hab ich mal so gelesen was manche hier so umgesetzt haben.

    Oft ist 1Wire und Arduino gefallen https://knx-user-forum.de/forum/%C3%...arduino-am-knx

    und da ich am vorbereiten war die Steuerung meiner Heizung mit dem Raspi und den 1Wire sensoren umzusetzen habe ich mich entschieden das ganze jetzt auf den Bus zu bringen
    Was ich habe:

    1. 1Wire Sensoren DS18B20
    2. Arduino Nano und Leonardo letzeres noch in Bestellung
    3. Siemens BCU 5WG1117-2AB12
    4. Den Gesamten Thread Arduino am KNX gelesen

    Irgendwo am ende des Threads hat jemand das ganze auch mit mehreren Sensoren am Laufen gehabt ich hab mir einfach mal seinen code geschnappt nur viele stellen sind für mich so nicht ersichtlich das ich das ganze für mich umbauen kann


    Der erste teil ist eigt. Noch verständlich für mich

    Code:
    #include <OneWire.h>
    #include <KnxTpUart.h>
    
    // Initialize the KNX TP-UART library on the Serial1 port of Arduino
    // PA Vergeben
    KnxTpUart knx(&Serial, "1.1.199");
    
    // 1Wire Pin Angeben
    OneWire ds(10); // an pin 10
    
    // 1Wire Settings?
    int haveSent = 0;
    byte i;
    byte present = 0;
    byte data[12];
    byte addr[8];
    int HighByte, LowByte, TReading, SignBit;
    float Tc_100, a;
    
    void setup() {
    // Serieller Port für Siemens BCU
    Serial.begin(19200);
    UCSR0C = UCSR0C | B00100000; // Irgendwo aus dem Forum Reinkopiert keine ahnung ob es richtig ist
    
    knx.uartReset();
    
    }
    Dieser Teil sucht die Sensoren und wertet die temperatur aus ?
    Code:
    void loop() {
    
    // Sensoren suchen
    
    delay(1000); // Zeit in der die Sensoren abgefragt werden ?
    
    if ( !ds.search(addr)) {
    
    // Serial.print("Keine weiteren Addressen.\n");
    
    ds.reset_search();
    
    return;
    
    }
    Wird in diesem teil jeder 1Wire sensore der Angeschlossen ist abgefragt ?

    Code:
    ds.reset();
    
    ds.select(addr);
    
    ds.write(0x44,1); // start Konvertierung, mit power-on am Ende
    
    present = ds.reset();
    
    ds.select(addr);
    
    ds.write(0xBE); // Wert lesen
    
    LowByte = data[0];
    HighByte = data[1];
    TReading = (HighByte << 8) + LowByte;
    SignBit = TReading & 0x8000; // test most sig bit
    Hier bin ich jetzt komplette ratlos aber ich vermute hier wird die ausgelesene Temperatur Umgerechnet ?
    Code:
    if (SignBit) {// negative
    //TReading = (TReading ^ 0xffff) + 1; // 2's comp
    TReading = !TReading + 1;
    TReading = (TReading * -1);
    }
    
    // Tc_100 = (6 * TReading) + TReading / 4; // mal (100 * 0.0625) oder 6.25 bei ds18B20
    // Tc_100 = (TReading*100/2); //bei ds18s20
    
    Tc_100 = (TReading*100/2);
    dort müsste ich vermutlich bei den DS18B20 sensoren den Punkt
    Code:
    Tc_100 = (6 * TReading) + TReading / 4 * 100 * 6.25
    nutzen? hab dazu auch schon Beispiele gesucht aber keine gefunden

    Im letzen teil übergibt er das ganze ja auf den Bus
    Code:
    if (addr[6] == 0 && addr[7] == 135){
    delay (100);
    haveSent = false;
    if (!haveSent) {
    float success = knx.groupWrite2ByteFloat("2/3/2", (Tc_100 / 100)); //Isttemp Schlafen
    haveSent = true;
    }
    }
    else if (addr[6] == 0 && addr[7] == 2){
    delay (100);
    haveSent = false;
    if (!haveSent) {
    float success = knx.groupWrite2ByteFloat("5/3/2", (Tc_100 / 100)); //Isttemp Bad
    haveSent = true;
    }
    }
    else if (addr[6] == 0 && addr[7] == 252){
    delay (100);
    haveSent = false;
    if (!haveSent) {
    float success = knx.groupWrite2ByteFloat("7/3/2", (Tc_100 / 100)); //Isttemp Wohnen
    haveSent = true;
    }
    }
    Kurz hinter seiner Frage kam aber von @ThorstenGehrig das das ausreichen würde (hoffe ich hab das ordnetlich umgesetzt)
    Code:
    else if (addr[6] == 0 && addr[7] == 252){
    delay (100);
    haveSend = knx.groupWrite2ByteFloat("2/3/2", (Tc_100 / 100)); //Isttemp Schlafen
    }
    }
    Die letzen zwei abschnitte sind für mich jetzt nicht so nachzuvollziehen

    Code:
    for ( i = 0; i < 9; i++) { // 9 bytes
    
    data[i] = ds.read();
    
    }
    Serial.print( OneWire::crc8( data, 8), HEX);

    Ich hoffe ihr könnt mir helfen etwas licht ins dunkle zu bringen denn irgendwie geht nach 56 seiten Thread lesen nichts mehr ^^

    #2
    Der Beitrag war von mir.
    Ich habe das aber mangels Zeit (Garten , Terrasse, Wasserbecken und Outdoorküche haben oberste Priorität) erst einmal auf die kalte Jahreszeit verschoben.
    Ich habe mein Steckbrett aber noch einsatzbereit und erkläre Dir morgen mal meine Lösung.
    Jetzt gehts zum Grillen :-)

    Jens

    Kommentar


      #3
      Zitat von intelligente Haustechnik Beitrag anzeigen
      Jetzt gehts zum Grillen :-)

      Jens
      Heißt bei mir im Saarland Schwenken aber guten Hunger und schonmal vielen Dank

      Kommentar


        #4
        Fallst du einfachere (HW)Lösung suchst.: https://knx-user-forum.de/forum/proj...itale-i-os-etc

        Kommentar


          #5
          So,

          ich versuche mich mal wieder reinzudenken.

          Es gibt 2 verschiedene 1-wire-Tempsensoren, die sich in der Genauigkeit unterscheiden. Daher die unterschiedlichen Berechnungsarten:

          Code:
           // Tc_100 = (6 * TReading) + TReading / 4; // mal (100 * 0.0625)
          oder
          6.25 bei ds18B20 // Tc_100 = (TReading*100/2); //bei ds18s20
          Die Sensoren habe ich einfach ausgelesen, in dem ich den 1-wire-Bus resetet und abgewartet habe, was zurückkommt:

          Code:
           ds.reset();  
          ds.select(addr);  
          ds.write(0x44,1);
          // start Konvertierung, mit power-on am Ende  
          present = ds.reset();  
          ds.select(addr);  
          ds.write(0xBE);
          // Wert lesen
          Die Sensoren haben jeweils eine eigene feste 8Byte-Adresse (?) Zur Auswertung habe ich einfach nur die letzten 2 Byte verglichen, das hat bei meinem Beispiel mit 3 Sensoren ausgereicht, bei später mehr Sensoren müssten die kompletten Adressen dann evtl in einem Array hinterlegt und verglichen werden:

          Code:
           if (addr[6] == 0 && addr[7] == 135)
          Danach werden die Werte auf den Bus gesendet. Auf Anraten von Thorsten habe ich dann noch einen Teil in meinem neuen Code, der prüft, ob sich der Wert geändert hat, um die Buslast zu reduzieren.

          Der letzte Abschnitt kam von Thorsten, da bin ich noch nicht ganz dahintergestiegen:

          Code:
           for ( i = 0; i < 9; i++) { // 9 bytes  data[i] = ds.read();  }
          Serial.print( OneWire::crc8( data, 8), HEX);
          Ich hoffe, das hat erst mal ein bisschen Licht ins Dunkel gebracht.
          Was hast Du denn genau vor?

          Jens

          Kommentar


            #6
            Also vor hab ich "nur" an an der Heizung an ca Sechs punkten die Temperatur zu Messen geplant war das ganze Über ein RaspberryPi und ein Webfrontend da aber jetzt KNX ansteht bring ich das auf den Bus und kann das in einem Gemeinsamen Frontend schauen

            Hast du vllt. die Aktuellste Version deines Codes mit der Änderung das nur bei einer Änderung der Temperatur gesendet wird?

            Es gibt 2 verschiedene 1-wire-Tempsensoren, die sich in der Genauigkeit unterscheiden. Daher die unterschiedlichen Berechnungsarten:

            Das habe ich soweit verstanden einzige was mir jetzt nicht so ersichtlich war wie ich das ganze umstellen muss für DS18B20 Sensoren

            So?
            Code:
            Tc_100 = TReading *(100 * 6.25)
            Die Sensoren habe ich einfach ausgelesen, in dem ich den 1-wire-Bus resetet und abgewartet habe, was zurückkommt:


            also der Teil der auskommentiert ist mit "SerialPrint" gibt dann die Adressen aus um die Später in deinen Vergleicher einzusetzen?
            Gut das mit dem Vergleicher hab ich dann Verstanden woher du die Adressen hast auch

            Wie war das noch gleich bei dem Arduino Nano Senden ist kein Problem aber empfangen schon wegen des FTDI chips ?



            Tobias

            Kommentar


              #7
              Allegemein zum Aufbau der ID:
              addr[0] ist die Familie, z.B. 28 steht für DS18B20, 01 für iButton usw.
              addr[1]-addr[6] sind die Adresse, aber ACHTUNG, OneWire Lib liefert die in der umgekehrter Reihnfolge. (d.h wenn man die Adresse z.B. mit OW-Server vergleich würde , muss man die so ausgeben: addr[0], addr[6], addr[5] addr[4] addr[3] addr[2] addr[1] add[7]
              Beispiel: https://github.com/KONNEKTING/Konnek...ctions.ino#L16

              addr[7] ist die Checksumme, die kann man mit
              Code:
               
               if (OneWire::crc8( addr, 7) != addr[7]){   Serial.println("CRC is not valid!\n"); }

              Kommentar


                #8
                Anbei der Teilcode für 2 Sensoren:

                Code:
                if (addr[6] == 2 && addr[7] == 244){
                delay (100);
                //haveSent = false;
                //if (!haveSent) {
                a = (Tc_100 / 100);
                if (b != a){
                haveSent = knx.groupWrite2ByteFloat("2/3/2", (Tc_100 / 100)); //Isttemp Schlafen
                }
                b = a;
                //haveSent = true;
                //}
                }
                
                
                else if (addr[6] == 1 && addr[7] == 28){
                delay (100);
                //haveSent = false;
                //if (!haveSent) {
                a = (Tc_100 / 100);
                if (c != a){
                haveSent = knx.groupWrite2ByteFloat("5/3/2", (Tc_100 / 100)); //Isttemp Bad
                }
                c = a;
                //haveSent = true;
                //}
                }
                Für ds18B20 mußt Du diese Umrechnung nehmen

                Code:
                Tc_100 = (6 * TReading) + TReading / 4;
                und für ds18s20 diese

                Code:
                /Tc_100 = (TReading*100/2);
                Zum Nano kann ich leider nichts sagen


                Jens

                Kommentar

                Lädt...
                X