Ankündigung

Einklappen
Keine Ankündigung bisher.

OneWire2HS

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

    HS/FS OneWire2HS

    Was looking for an affordable solution to get a substantial number of temperature sensors connected to the Homeserver3.
    Measured are the floor and the floor heating tubes temperatures.
    The cheapest solution was an Arduino UNO + ethernet shield.
    By connecting the ethernet shield to the home network I'm getting the 1wire ID's and temperatures on my laptop and on the HS3.
    Total cost excluding the 1-wire sensors (which were $1,50 each) was only €26,95
    That does include a nice enclosure for the Arduino.
    All temperatures are sent every 10 seconds and when there's a change of 0,1C or more.
    I used Bascom-AVR to make the program but it could be done with the Arduino program as well of course.
    Just tested with 17 sensors and the program has been set up to use up to 100 sensors.

    #2
    Test setup

    OneWire2HS.jpg

    Strings sent with UDP to HS3

    temp.jpg

    Kommentar


      #3
      would you provide more information about your project?
      it sounds interesting.

      Kommentar


        #4
        Sure, just tell me what you want to know.
        Regarding the 3 LED's on the breadboard, the red one is to indicate there was a CRC error, the green one is being toggled in the main loop and the yellow one is being toggled in the interrupt service routine.
        This Timer routine is used to interrupt every 2 seconds and set a flag.
        The main loop has a variable that is incremented when this flag is set and after reaching the value 5 all the temperatures are sent (every 5x2seconds).
        I can post the Basic code which can be used with Bascom-AVR.
        Should not be to hard to translate it into "Arduino language" which is a kind of C I believe.
        For me C stands for Chinese or Complicated.
        That's why I have choosen Basic.
        Right now I am implementing a function which enables the user to reset the Arduino with a simple UDP message.
        Whenever you add or remove a sensor this is required to build up the 1-wire ID table.

        Kommentar


          #5
          Hi,
          I'm also interested in building your solution.
          I will be using one of the newer Arduino Ethernet with PoE, which is ideal suited for the needs in my cellar.
          what Pins/Ports are you using to connect LEDs and DS-Sensors?
          Will your software work with more complex DS-temperatur-sensors aswell?
          i have'nt programmeed in Arduino-Bascom up to now. How is the procedure to get the code to the board?
          I would be glad, if you can send me a short description and your BASCOM-Code
          Best regards
          Nick
          GIRA HS3, HS2, Mobotix, Shuttle X50, Selve SMI-Antriebe, GEZE-Tür- & Fenster Antriebe, Siemens-, ABB- & Eigenbau-Aktoren, GIRA TS2, Jung RCD 3096, Hoppe enOcean Fenstergriffe mit Schlaps-GW, Bluetooth-Türöffner, MicroVis II, Elsner Suntracer, Hager Stellantriebe, KOSTAL PV-WR, u.v.a.m...

          Kommentar


            #6
            For the LED's I use D.5 D.6 D.7 and the 1wire is connected to C.5
            I'm using the DS18B20, which sensors are you planning to use?
            For this program you will need Bascom-AVR but you should be able to write a similar program with the free Arduino software.
            The compiled code is transferred to the board by USB.
            In Bascom you can select ARDUINO as programmer.

            Short description:
            The W5100 ethernet module has 4 sockets.
            I use the first to send the temperature data to the production Homeserver.
            The second for the test Homeserver.
            The third for my laptop to be able to monitor what is being sent by the Arduino.
            The last socket is used to receive commands.
            So far the only command I implemented is a Reset of the program.
            This could be activated with a pushbutton in QC.
            In case a sensor is added or exchanged this is necessary to get the 1-wire ID's.
            In the main loop all the temperatures are retrieved and a new temperature conversion is initiated.
            The most recent temperatures are compared to their previous value and if changed by >0,1C the new temperature is sent.
            Every 10 seconds all the temperatures (including the temperature of the ATmega328P chip) are sent regardless whether changed or not.
            So far the program uses 21% of the Flash and has 522 bytes of RAM left.
            Plenty of space left for improvements

            In HS Expert - Communication - IP/EIB telegrams (reception) it looks like this:
            1.jpg

            2.jpg


            Code:
            '--------------------------------------------------------------------------------------------
            'name                     : Onewire2UDP_UNOv3.bas
            'purpose                  : read max 100 DS18B20 temp sensors, send output via UDP to HS4
            '                         : All data stored in SRAM, no EEPROM used
            'micro                    : Arduino UNO, ATmega328P-PU 32KB FlashROM, 2KB SRAM, 1KB EEPROM
            '--------------------------------------------------------------------------------------------
            '
            'Error codes:
            'Fill 1w_data with values depending on the error
            '0xAA - 1w_id not valid in get_temperatures routine
            '0xBB - CRC is not correct in get_temperatures routine
            '
            '
            $regfile = "m328pdef.dat"                                                                 'UNO
            $programmer = 22                                                                          'ARDUINO (using stk500v1 protocol)
            $crystal = 16000000
            $hwstack = 80
            $swstack = 32
            $framesize = 64
            $baud = 38400
            '
            Declare Sub Get_onewire_addresses
            Declare Sub Set_onewire_resolution
            Declare Sub Convert_t
            Declare Sub Get_temperatures
            '
            Dim Isr_timer1_flag As Bit                                                                'Timer1 is a 16-bit timer
            Dim Auto_temp_send As Bit                                                                 'When Set all temps are sent, even when unchanged
            '
            Dim Temp_byte_array(2) As Byte
            Dim Temp_byte1 As Byte , Temp_byte2 As Byte
            Dim Teller1 As Byte , Teller2 As Byte
            Dim Interval As Byte
            Dim Idx0 As Byte , Idx1 As Byte , Idx2 As Byte , Idx3 As Byte
            Dim Socket2_rx_buffer(20) As Byte
            Dim Numberofdevices As Byte
            Dim 1w_id(800) As Byte                                                                    'Max 100 ID's 1 byte family code + 6 bytes ID + 1 byte CRC = 8 bytes
            Dim 1w_id_index As Byte
            Dim 1w_scratchpad(9) As Byte
            '
            Dim 1w_temp_old(100) As Integer                                                           'Previous measured temperature
            Dim 1w_temp_new(100) As Integer                                                           'Last measured temperature
            Dim Temp_delta As Integer                                                                 'Difference between previous and last measured temperature
            Dim Temp_integer As Integer
            '
            Dim Temp_word1 As Word , Temp_word2 As Word
            Dim Udp0_bytes_written As Word
            Dim Udp1_bytes_written As Word
            Dim Udp2_bytes_written As Word
            Dim Socketstat1 As Word
            Dim Chip_temperature As Word                                                              'Internal temperature of the ATmega328P chip
            '
            Dim Temp_single As Single
            '
            Dim Temp_string As String * 10
            Dim Udp_string As String * 50
            '
            1wire_port1 Alias Pinc                                                                    'Port to be used for 1-wire
            1wire_pin1 Alias 5                                                                        'Pin to be used for 1-wire
            Config 1wire_port1.1wire_pin1 = Input                                                     'Use pin 28 (Port C.5) for DS18B20 data
            '
            Config Portd.6 = Output                                                                   'Heartbeat indicatie LED voor main Loop
            Heartbeat_main_loop_led Alias Portd.6                                                     'LED connected to +5V and pin
            Reset Heartbeat_main_loop_led
            '
            Config Portd.5 = Output                                                                   'Timer1 ISR
            Timer1_isr_led Alias Portd.5                                                              'LED connected to +5V and pin
            Reset Timer1_isr_led
            '
            Config Portd.7 = Output                                                                   'Bad CRC
            Bad_crc_led Alias Portd.7                                                                 'LED connected to +5V and pin
            Reset Bad_crc_led
            '
            Config Adc = Single , Prescaler = Auto , Reference = Internal_1.1                         'Measure internal chip temperature (ADC8)
            '
            Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 4 , Noss = 0
            Spiinit
            Enable Interrupts                                                                         'Before we use config tcpip , we need to enable the interrupts
            Config Tcpip = Noint , _
                   Mac = 144.162.218.0.145.254 , _
                   Ip = 192.168.1.101 , _
                   Submask = 255.255.255.0 , _
                   Gateway = 192.168.1.1 , _
                   Localport = 9980 , _
                   Tx = $55 , Rx = $55 , _
                   Chip = W5100 , _
                   Spi = 1 , _
                   Cs = Portb.2
            Idx0 = Getsocket(0 , 2 , 9980 , 0)                                                        'Get socket for UDP mode port 9980 (HS3)
            Idx1 = Getsocket(1 , 2 , 9981 , 0)                                                        'Get socket for UDP mode port 9981 (HS4)
            Idx2 = Getsocket(2 , 2 , 9982 , 0)                                                        'Get socket for UDP mode port 9982 (MBP)
            Idx3 = Getsocket(3 , 2 , 9983 , 0)                                                        'Get socket for UDP mode port 9983 (commands from MBP/Homeserver)
            '
            Config Timer1 = Timer , Prescale = 1024
            On Timer1 Isr_timer1
            Enable Timer1
            Start Adc                                                                                 'To read the ATmega328P's internal temperature
            Config Watchdog = 8192
            '
            '
            '=========================================================================================================
            '===================================================== Main Program ======================================
            '=========================================================================================================
            '
            '
            Get_onewire_addresses                                                                     'Collect all 1Wire addresses
            Set_onewire_resolution                                                                    'Set resolution
            Udp_string = "Reset"
            Udp2_bytes_written = Udpwritestr(192.168.1.114 , 9982 , Idx2 , Udp_string , 255)          'Send the string "Reset" via UDP to MBP
            Wait 1                                                                                    'LEDs on for 1 second during startup
            Set Heartbeat_main_loop_led                                                               'Switch LED off
            Set Timer1_isr_led                                                                        'Switch LED off
            Set Bad_crc_led                                                                           'Switch LED off
            Start Watchdog
            '
            Do
              Reset Watchdog
              Toggle Heartbeat_main_loop_led                                                          'To check loop activity
              If Isr_timer1_flag = 1 Then
                Reset Isr_timer1_flag
                Toggle Timer1_isr_led
                Incr Interval
                If Interval = 5 Then                                                                  'Every 5 x Isr_timer1 time
                  Set Auto_temp_send                                                                  'all the temperatures will be sent
                  Interval = 0
                  Chip_temperature = Getadc(8)                                                        'ATmega328P's internal temperature
                End If
              End If
            '
              Temp_word1 = Socketstat(idx3 , Sel_recv)                                                'Get number of bytes waiting
              If Temp_word1 > 0 Then                                                                  'A command was sent over UDP port 9983
                Udpreadheader Idx3
                If Peersize > 0 Then                                                                  'The actual number of bytes
                  Temp_byte1 = Udpread(idx3 , Temp_byte_array(1) , Peersize)                          'Move the bytes into Temp_byte_array
                  If Temp_byte_array(1) = "r" Then Goto 0                                             'Reset by jumping to address 0 if the first byte is "r"
                End If
              End If
            '
              Waitms 750                                                                              'required time for a DS18B20 12 bit temperature conversion
              Get_temperatures                                                                        'Get the temperatures
              Convert_t                                                                               'Start temperature conversion again for all DS18B20 sensors
            '
              1w_id_index = 1
              For Teller1 = 1 To Numberofdevices                                                      'Check whether delta new/old temperature >=0.1
                Temp_delta = 1w_temp_new(teller1) - 1w_temp_old(teller1)
                Temp_delta = Abs(temp_delta)
                If Temp_delta > 1 Or Auto_temp_send = 1 Then
                  1w_id_index = Teller1 * 8
                  1w_id_index = 1w_id_index - 7
                  Udp_string = "DS18B20ID="                                                           'Start the Udp_string with DS18B20ID=
                  For Teller2 = 1 To 8                                                                'Add the HEX representation of the 8 ID bytes
                   Udp_string = Udp_string + Hex(1w_id(1w_id_index))
                    Incr 1w_id_index
                  Next
                  Udp_string = Udp_string + "="                                                       'Add a = sign
                  Temp_single = 1w_temp_new(teller1) / 16
                  Temp_string = Fusing(temp_single , "##.#")
                  Udp_string = Udp_string + Temp_string                                               'Add the temperature
                  Udp_string = Udp_string + "C"                                                       'To indicate the end of the numeric value for the Gira Homeserver
                  1w_temp_old(teller1) = 1w_temp_new(teller1)                                         'copy the latest temperature value to the old value
                  Udp0_bytes_written = Udpwritestr(192.168.1.200 , 9980 , Idx0 , Udp_string , 255)    'send data via UDP to HS3
                  Udp1_bytes_written = Udpwritestr(192.168.1.201 , 9981 , Idx1 , Udp_string , 255)    'send data via UDP to HS4
                  Udp2_bytes_written = Udpwritestr(192.168.1.114 , 9982 , Idx2 , Udp_string , 255)    'send data via UDP to MBP
                End If
              Next
              If Auto_temp_send = 1 Then
                Temp_single = Chip_temperature
                Temp_single = Temp_single - 314
                Temp_single = Temp_single / 1.1
                Temp_single = 25 + Temp_single
                Temp_single = Round(temp_single)
                Udp_string = "ATmega328C: " + Str(temp_single) + "C"
                Udp0_bytes_written = Udpwritestr(192.168.1.200 , 9980 , Idx0 , Udp_string , 255)      'send data via UDP to HS3
                Udp1_bytes_written = Udpwritestr(192.168.1.201 , 9981 , Idx1 , Udp_string , 255)      'send data via UDP to HS4
                Udp2_bytes_written = Udpwritestr(192.168.1.114 , 9982 , Idx2 , Udp_string , 255)      'send data via UDP to MBP
            '
                Udp_string = "ATmega328mV: " + Str(chip_temperature) + "mV"
                Udp0_bytes_written = Udpwritestr(192.168.1.200 , 9980 , Idx0 , Udp_string , 255)      'send data via UDP to HS3
                Udp1_bytes_written = Udpwritestr(192.168.1.201 , 9981 , Idx1 , Udp_string , 255)      'send data via UDP to HS4
                Udp2_bytes_written = Udpwritestr(192.168.1.114 , 9982 , Idx2 , Udp_string , 255)      'send data via UDP to MBP
                Reset Auto_temp_send
              End If
            Loop
            
            
            '=========================================================================================================
            '=============================================== SUB's ===================================================
            '=========================================================================================================
            
            
            Sub Get_onewire_addresses
              Numberofdevices = 0
              1w_id_index = 1
              Do                                                                                      'Stay in this loop until a DS18B20 with valid CRC was found
                1w_id(1w_id_index) = 1wsearchfirst(1wire_port1 , 1wire_pin1)                          'Search for the first device on the bus and get the 8 byte ID
                If Err = 1 Then
                  Print "No 1-wire devices found"
                  Wait 2
                Else                                                                                  'Device found, now check whether CRC is correct
                  If 1w_id(1w_id_index + 7) <> Crc8(1w_id(1w_id_index) , 7) Then                      'If CRC (byte 8) does not match then
                    Reset Bad_crc_led                                                                 'switch on the bad CRC led and
                    Print 1w_id_index ; " Bad CRC"                                                    'print this message
                  Else                                                                                'If CRC is correct then continue and
                    Numberofdevices = 1
                  End If
                End If
              Loop Until Numberofdevices <> 0                                                         'Loop will exit when valid ID found
              1w_id_index = 9
              Do                                                                                      'Search for other ID's
                1w_id(1w_id_index) = 1wsearchnext(1wire_port1 , 1wire_pin1)                           'Fill the array with iwire addresses
                If Err = 0 Then                                                                       'Another device found, now check whether CRC is correct
                  If 1w_id(1w_id_index + 7) <> Crc8(1w_id(1w_id_index) , 7) Then                      'If CRC is not correct then
                    Reset Bad_crc_led
                    Print 1w_id_index ; " Bad CRC"                                                    'CRC not correct
                  Else
                    Incr Numberofdevices
                  End If
                End If
                1w_id_index = 1w_id_index + 8
              Loop Until Err = 1
            End Sub
            '
            '
            Sub Set_onewire_resolution                                                                'Set resolution to 12 bits for all sensors
              1w_id_index = 1
              For Teller1 = 1 To Numberofdevices
                1wreset 1wire_port1 , 1wire_pin1                                                      'Reset the bus
                1wwrite &H55 , 1 , 1wire_port1 , 1wire_pin1                                           'Match rom command
                For Teller2 = 1 To 8
                  1wwrite 1w_id(1w_id_index) , 1 , 1wire_port1 , 1wire_pin1
                  Incr 1w_id_index
                Next
                1wwrite &H4E , 1 , 1wire_port1 , 1wire_pin1
                1wwrite &H00 , 1 , 1wire_port1 , 1wire_pin1
                1wwrite &H00 , 1 , 1wire_port1 , 1wire_pin1
                1wwrite &B0111_1111 , 1 , 1wire_port1 , 1wire_pin1
              Next
            End Sub
            '
            '
            Sub Convert_t
              1wreset 1wire_port1 , 1wire_pin1                                                        'Reset the bus
              1wwrite &HCC , 1 , 1wire_port1 , 1wire_pin1                                             '0xCC Skip Rom command
              1wwrite &H44 , 1 , 1wire_port1 , 1wire_pin1                                             '0x44 Convert T command
            End Sub
            '
            '
            Sub Get_temperatures                                                                      'Read complete scratchpad (9 bytes) and save the 2 temperature bytes only
              1w_id_index = 1
              For Teller1 = 1 To Numberofdevices
                1wverify 1w_id(1w_id_index) , 1wire_port1 , 1wire_pin1                                'This verifies if an ID is available on the 1wire bus
                If Err = 1 Then                                                                       'ID not available?
                  1w_temp_new(teller1) = &HAAAA                                                       'Fill temperature word with 0xAAAA
                Else
                  1wwrite &HBE , 1 , 1wire_port1 , 1wire_pin1                                         '0xBE = Read Scratchpad command
                  1w_scratchpad(1) = 1wread(9 , 1wire_port1 , 1wire_pin1)                             'Put all 9 bytes in 1w_scratchpad array
                  If 1w_scratchpad(9) <> Crc8(1w_scratchpad(1) , 8) Then                              'Check CRC of scratchpad
                    Reset Bad_crc_led                                                                 'Bad CRC, LED on
                    1w_temp_new(teller1) = &HBBBB                                                     'Temperature is 0xBBBB if the CRC is not correct,
                    Set Bad_crc_led
                  Else
                    1w_temp_new(teller1) = Makeint(1w_scratchpad(1) , 1w_scratchpad(2))               'Convert temperature bytes into an integer
                  End If
                End If
                1w_id_index = 1w_id_index + 8                                                         'Point to next 1-wire ID
              Next
            End Sub
            '
            '
            '=========================================================================================================
            '=============================================== ISR's ===================================================
            '=========================================================================================================
            '
            '
            Isr_timer1:                                                                               'Timer value = 65536 - (interrupt interval * $crystal / prescale)
            '  Reset Watchdog
              Set Isr_timer1_flag
            '  Timer1 = 49911                                                                'For 1sec: 65536 - (1 * 16.000.000 / 1024) = 49911
              Timer1 = 34286                                                                          'For 2sec: 65536 - (2 * 16.000.000 / 1024) = 34286
            '  Timer1 = 18661                                                                'For 3sec: 65536 - (3 * 16.000.000 / 1024) = 18661
            '  Timer1 = 3036                                                                 'For 4sec: 65536 - (4 * 16.000.000 / 1024) = 3036
            Return

            Kommentar


              #7
              Arduino Sketch

              Hi,

              thank you for sharing your BASCOM-code...
              3 weeks later, I nearly made it :-)
              With your BASCOM-structure in mind, I started to convert everything to an Arduino sketch.

              I´ve come up to a highly specialised version, that will suite my needs.
              - up to 13 1Wire Sensors, no family Class handling (10),
              - sending the temperatures once every 20 seconds to 1 HS-IP UDP Port.
              - Sensors identified by unique ID and clear text description
              - In addition, I´ve integrated an HP03S air pressure sensor.

              It was my first experience with the Arduino IDE, and hopefully my last.

              My program is facing severe RAM-size limitations on the 328P, because I had to increase the UDP Buffer to (at least) 512bytes.

              This is clearly none of my best S/W-pieces, but if anyone is interested, I will share the code.

              Have a nice weekend
              Nick
              GIRA HS3, HS2, Mobotix, Shuttle X50, Selve SMI-Antriebe, GEZE-Tür- & Fenster Antriebe, Siemens-, ABB- & Eigenbau-Aktoren, GIRA TS2, Jung RCD 3096, Hoppe enOcean Fenstergriffe mit Schlaps-GW, Bluetooth-Türöffner, MicroVis II, Elsner Suntracer, Hager Stellantriebe, KOSTAL PV-WR, u.v.a.m...

              Kommentar


                #8
                The Sketch

                Due to overwheling demand...
                This is my sketch.

                Good Luck,
                Nick
                Angehängte Dateien
                GIRA HS3, HS2, Mobotix, Shuttle X50, Selve SMI-Antriebe, GEZE-Tür- & Fenster Antriebe, Siemens-, ABB- & Eigenbau-Aktoren, GIRA TS2, Jung RCD 3096, Hoppe enOcean Fenstergriffe mit Schlaps-GW, Bluetooth-Türöffner, MicroVis II, Elsner Suntracer, Hager Stellantriebe, KOSTAL PV-WR, u.v.a.m...

                Kommentar


                  #9
                  Bug Reports

                  during the last 3 month of 24x7 operation, I have encountered two (at least) bugs:

                  1. after an error on the 1wire Bus is encountered, the ERROR-LED gets lit but never cleared. (my 1wire bus takes about 5 minutes after a power-on, to encounter the first error...)

                  2. if my program somehow can not convert the temperature recieved from the 1wire-device, it sends the fixed value of 4711 degrees to distiguish from 85.
                  This is a really bad idea, because it corrupts the HS archives and diagrams.

                  Currently there is no time and NO fixed sketch available
                  GIRA HS3, HS2, Mobotix, Shuttle X50, Selve SMI-Antriebe, GEZE-Tür- & Fenster Antriebe, Siemens-, ABB- & Eigenbau-Aktoren, GIRA TS2, Jung RCD 3096, Hoppe enOcean Fenstergriffe mit Schlaps-GW, Bluetooth-Türöffner, MicroVis II, Elsner Suntracer, Hager Stellantriebe, KOSTAL PV-WR, u.v.a.m...

                  Kommentar

                  Lädt...
                  X