- fchao-Sinus-Wechselrichter AliExpress         
Seite 3 von 3 ErsteErste 123
Ergebnis 21 bis 23 von 23

Thema: Homeautomatisierung mit RS485

  1. #21
    Erfahrener Benutzer Robotik Einstein Avatar von Vitis
    Registriert seit
    06.01.2005
    Ort
    Südpfalz
    Alter
    50
    Beiträge
    2.253
    Anzeige

    Praxistest und DIY Projekte
    so in etwa könnts laufen:

    Code:
    $regfile = "m8def.dat"
    $crystal = 8000000
    $hwstack = 70                                               ' default use 32 for the hardware stack
    $swstack = 250                                              ' default use 10 for the SW stack
    $framesize = 80
    
    
    $baud = 19200
    
    ' Konfiguration zum Kompilieren
    Const Max_framelen = 32
    
    
    Dim Slaveaddress As Byte
    ' dim slaveaddress as word
    Slaveaddress = &B00000011
    
    
    Rs485_set_io Alias Portd.2
    Config Rs485_set_io = Output
    
    
    Dim Tx_data(max_framelen) As Byte
    Dim Tx_string As String * Max_framelen At Tx_data Overlay
    #if Max_framelen > 255
       Dim Tx_pointer As Word
       dim tx_length as word
    #else
       Dim Tx_pointer As Byte
       Dim Tx_length As Byte
    #endif
    
    Dim Rx_data(max_framelen) As Byte
    Dim Rx_string As String * Max_framelen At Rx_data Overlay
    #if Max_framelen > 255
       Dim Rx_pointer As Word
    #else
       Dim Rx_pointer As Byte
    #endif
    
    Dim Data_array(max_framelen) As Byte
    Dim Flag_array(3) As Byte
    
    Dim Rx_flag As Byte
    Dim Timerflag As Byte
    Dim Frame_receive_flag As Byte
    
    Declare Sub Rx_verarbeitung()
    
    ' Interrupts initialisieren
    On Urxc Zeichenempfang
    Enable Urxc
    
    On Utxc Zeichen_gesendet
    Enable Utxc
    
    Config Timer0 = Timer , Prescale = 1024
    On Timer0 Timer_irq
    Const Timervorgabe = 178
    
    Disable Timer0
    Enable Interrupts
    
    
    ' Mainloop
    Do
    'Hier könnte Ihr Hauptprogramm stehen
    
    
       If Timerflag = 1 Then
          Timerflag = 0
          ' verarbeitung
          Call Rx_verarbeitung()
          Rx_pointer = 0
          Rx_flag = 0
       End If
       If Rx_flag = 1 And Rx_data(1) = &B01010100 And Rx_pointer > 3 Then
          Call Rx_verarbeitung()
       End If
    Loop
    
    
    
    Timer_irq:
       Timer0 = 0
       Timerflag = 1
       Disable Timer0
       Incr Rx_pointer
       Rx_data(rx_pointer) = 0
    Return
    
    Zeichenempfang:
       Timer0 = Timervorgabe
       Enable Timer0
       Rx_flag = 1
       If Rx_pointer < 19 Then
          Incr Rx_pointer
          Rx_data(rx_pointer) = Udr
       End If
    Return
    
    Zeichen_gesendet:
       If Tx_length > Tx_pointer Then
          Incr Tx_pointer
          Udr = Tx_data(tx_pointer)
       Else
          ' für rs485
          Reset Rs485_set_io
       End If
    Return
    
    
    
    ' ###########################################################
    '                    Protokollverarbeitung
    ' ###########################################################
    
    Sub Rx_verarbeitung()
       Local Hdb2_rx As Byte
       Local Hdb1_rx As Byte
    
       Local Dd_num As Byte
       Local Ss_num As Byte
       Local Pp_num As Byte
       Local Aa_num As Byte
       Local Eee_num As Byte
    
       Local Checksum_var As Word
       Local Checksum_byte_1 As Byte
       Local Checksum_byte_2 As Byte
       Local Checksum_check_flag As Byte
       Local Checksum_long As Long
    
       Local Temp_variable_1 As Word
       Local Temp_variable_2 As Word
       Local Temp_variable_3 As Word
       Local Temp_variable_4 As Word
       Local Nnnn_num As Word
    
       Local Rx_bytes_to_load As Word
       Local Slaveaddress_check_flag As Byte
    
       ' für test:
    '(
       Rx_pointer = 8
       Rx_data(1) = &B01010100
       Rx_data(2) = &B01010001
       Rx_data(3) = &B01000001
       Rx_data(4) = &B00000011
       Rx_data(5) = &B00000001
       Rx_data(6) = &B11110000
       Rx_data(7) = &B00100010
       Rx_data(8) = &B00110101
    ')
    
       ' hdb2
       Dd_num = Rx_data(2)
       Shift Dd_num , Right , 6
    
       Ss_num = Rx_data(2)
       Ss_num = Ss_num And &B00110000
       Shift Ss_num , Right , 4
    
       Pp_num = Rx_data(2)
       Pp_num = Pp_num And &B00001100
       Shift Pp_num , Right , 2
    
       Aa_num = Rx_data(2)
       Aa_num = Aa_num And &B00000011
    
       ' hdb1
       Eee_num = Rx_data(3)
       Eee_num = Eee_num And &B01110000
       Shift Eee_num , Right , 4
    
       Nnnn_num = Rx_data(3)
       Nnnn_num = Nnnn_num And &B00001111
    
       ' add framelength
       Select Case Nnnn_num
          Case &B00000000
               Rx_bytes_to_load = 0
          Case &B00000001
               Rx_bytes_to_load = 1
          Case &B00000010
               Rx_bytes_to_load = 2
          Case &B00000011
               Rx_bytes_to_load = 3
          Case &B00000100
               Rx_bytes_to_load = 4
          Case &B00000101
               Rx_bytes_to_load = 5
          Case &B00000110
               Rx_bytes_to_load = 6
          Case &B00000111
               Rx_bytes_to_load = 7
          Case &B00001000
               Rx_bytes_to_load = 8
          Case &B00001001
               Rx_bytes_to_load = 16
          #if Max_framelen > 16
          Case &B00001010
               Rx_bytes_to_load = 32
          #endif
          #if Max_framelen > 32
          Case &B00001011
               Rx_bytes_to_load = 64
          #endif
          #if Max_framelen > 64
          Case &B00001100
               Rx_bytes_to_load = 128
          #endif
          #if Max_framelen > 128
          Case &B00001101
               Rx_bytes_to_load = 256
          #endif
          #if Max_framelen > 256
          Case &B00001110
               Rx_bytes_to_load = 512
          #endif
          Case Else
               Rx_bytes_to_load = 0
       End Select
    
       ' add checksumlength
       Select Case Eee_num
          Case &B00000010
               Rx_bytes_to_load = Rx_bytes_to_load + 1
          Case &B00000011
               Rx_bytes_to_load = Rx_bytes_to_load + 1
          Case &B00000100
               Rx_bytes_to_load = Rx_bytes_to_load + 2
          Case &B00000101
               Rx_bytes_to_load = Rx_bytes_to_load + 4
          Case Else
               ' nix machen
               nop
       End Select
    
       Rx_bytes_to_load = Rx_bytes_to_load + Ss_num             ' source adress bytes
       Rx_bytes_to_load = Rx_bytes_to_load + Dd_num             ' destination adress bytes
       Rx_bytes_to_load = Rx_bytes_to_load + Pp_num             ' protokoll spec. flag bytes
       Rx_bytes_to_load = Rx_bytes_to_load + 3                  ' Sync, HDB2, HDB1
    
       ' Auf Adresse prüfen, geht im Moment nur auf 1 und 2 Byte Adresse
       Temp_variable_1 = 3 + Dd_num
       Temp_variable_2 = 3
       Temp_variable_3 = 0
       While Temp_variable_2 < Temp_variable_1
          Incr Temp_variable_2
          Shift Temp_variable_3 , Left , 1
          Temp_variable_3 = Temp_variable_3 + Rx_data(temp_variable_2)
       Wend
       If Temp_variable_3 = Slaveaddress Then
          Slaveaddress_check_flag = 1
       Else
          Slaveaddress_check_flag = 0
       End If
    
    
       ' Checksumme prüfen
       Checksum_check_flag = 0
       If Rx_bytes_to_load = Rx_pointer And Slaveaddress_check_flag = 1 Then       ' Frame ist ganz empfangen, Adresse stimmt
          Checksum_var = 0
          Checksum_byte_1 = 0
          Checksum_byte_2 = 0
          Select Case Eee_num
             Case &B00000010                                    ' 8-bit checksum
                  Temp_variable_1 = Rx_bytes_to_load - 2
                  For Temp_variable_2 = 2 To Temp_variable_1
                      Checksum_var = Checksum_var + Rx_data(temp_variable_2)
                  Next
                  Checksum_byte_1 = Low(checksum_var)
                  If Rx_data(rx_bytes_to_load) = Checksum_byte_1 Then
                      Checksum_check_flag = 1
                  Else
                      Checksum_check_flag = 0
                  End If
             Case &B00000011                                    ' 8-bit crc
                  Temp_variable_1 = Rx_bytes_to_load - 2
                  Checksum_byte_1 = Crc8(rx_data(2) , Temp_variable_1)
                  If Rx_data(rx_bytes_to_load) = Checksum_byte_1 Then
                      Checksum_check_flag = 1
                  Else
                      Checksum_check_flag = 0
                  End If
             Case &B00000100                                    ' 16-bit crc
                  Temp_variable_1 = Rx_bytes_to_load - 3
                  Checksum_var = Crc16(rx_data(2) , Temp_variable_1)
                  Checksum_byte_1 = Low(checksum_var)
                  Checksum_byte_2 = High(checksum_var)
                  Temp_variable_1 = Rx_bytes_to_load - 1
                  If Rx_data(rx_bytes_to_load) = Checksum_byte_1 And Rx_data(temp_variable_1) = Checksum_byte_2 Then
                      Checksum_check_flag = 1
                  Else
                      Checksum_check_flag = 0
                  End If
             Case &B00000101                                    ' 32-bit crc
                  Temp_variable_1 = Rx_bytes_to_load - 5
                  Checksum_long = Crc32(rx_data(2) , Temp_variable_1)
          End Select
       End If
    
       ' Frame war komplett, Adresse und Checksumme stimmt
       ' Daten in Datenarray kopieren und Flag setzen
       If Checksum_check_flag = 1 Then                          ' And Aa_num > 0
          Frame_receive_flag = 1                                ' Frame ist komplett und kann in der Mainloop verarbeitet werden
    
    
          Temp_variable_1 = 3
          Temp_variable_1 = Temp_variable_1 + Dd_num
          Temp_variable_1 = Temp_variable_1 + Ss_num
          If Pp_num > 0 Then
             Incr Temp_variable_1
             Flag_array(1) = Rx_data(temp_variable_1)
             If Pp_num > 1 Then
                Incr Temp_variable_1
                Flag_array(1) = Rx_data(temp_variable_1)
                If Pp_num > 2 Then
                   Incr Temp_variable_1
                   Flag_array(1) = Rx_data(temp_variable_1)
                End If
             End If
          End If
    
          Temp_variable_2 = Temp_variable_1 + Nnnn_num
          Temp_variable_3 = 0
          While Temp_variable_1 < Temp_variable_2
             Incr Temp_variable_1
             Incr Temp_variable_3
             Data_array(temp_variable_3) = Rx_data(temp_variable_1)
          Wend
       End If
    
       ' Frame gesetzt, acknowledge erzeugen wenn gebraucht
       If Frame_receive_flag = 1 And Aa_num > 0 Then
    
          Tx_data(1) = &B01010100                               ' Preamble
          Shift Dd_num , Left , 4
          Shift Ss_num , Left , 6
          Shift Pp_num , Left , 2
    
          If Checksum_check_flag = 1 Then
             Aa_num = &B00000010                                ' Ackn
          Else
             Aa_num = &B00000011                                ' Nack
          End If
    
          Tx_data(2) = Dd_num
          Tx_data(2) = Tx_data(2) Or Ss_num
          Tx_data(2) = Tx_data(2) Or Pp_num
          Tx_data(2) = Tx_data(2) Or Aa_num
    
          Shift Eee_num , Left , 4
          Tx_data(3) = Eee_num
          Tx_data(3) = Tx_data(3) Or 1                          ' 1 für Dummybyte
    
          ' Sender / Empfänger in umgekehrter Reihenfolge einkopieren
          Temp_variable_1 = 3
          Shift Dd_num , Right , 4
          Shift Ss_num , Right , 6
          Shift Pp_num , Right , 2
          Temp_variable_1 = Temp_variable_1 + Dd_num
          Temp_variable_2 = Temp_variable_1 + Ss_num
          Temp_variable_3 = 3
          While Temp_variable_1 < Temp_variable_2
             Incr Temp_variable_1
             Incr Temp_variable_3
             Tx_data(temp_variable_3) = Rx_data(temp_variable_1)
          Wend
    
          Temp_variable_1 = 3
          Temp_variable_2 = Temp_variable_1 + Dd_num
          While Temp_variable_1 < Temp_variable_2
             Incr Temp_variable_1
             Incr Temp_variable_3
             Tx_data(temp_variable_3) = Rx_data(temp_variable_1)
          Wend
    
          ' Die Flagbytes ebenfalls zurück kopieren
          If Pp_num > 0 Then
             Incr Temp_variable_3
             Tx_data(temp_variable_3) = Flag_array(1)
             If Pp_num > 1 Then
                Incr Temp_variable_3
                Tx_data(temp_variable_3) = Flag_array(1)
                If Pp_num > 2 Then
                   Incr Temp_variable_3
                   Tx_data(temp_variable_3) = Flag_array(1)
                End If
             End If
          End If
    
    
    
          ' Dummy Datenbyte
          Incr Temp_variable_3
          Tx_data(temp_variable_3) = 0
    
          ' Checksummen
          Select Case Eee_num
             Case &B0010_0000                                    ' 8-bit checksum
    
                  For Temp_variable_2 = 2 To Temp_variable_3
                      Checksum_var = Checksum_var + Tx_data(temp_variable_2)
                  Next
                  Incr Temp_variable_3
                  Tx_data(temp_variable_3) = Low(checksum_var)
             Case &B0011_0000                                   ' 8-bit crc
                  Temp_variable_1 = Temp_variable_3 - 1
                  Checksum_byte_1 = Crc8(tx_data(2) , Temp_variable_1)
                  Incr Temp_variable_3
                  Tx_data(temp_variable_3) = Checksum_byte_1
             Case &B0100_0000                                   ' 16-bit crc
                  Temp_variable_1 = Temp_variable_3 - 1
                  Checksum_var = Crc16(tx_data(2) , Temp_variable_1)
                  Incr Temp_variable_3
                  Tx_data(temp_variable_3) = High(checksum_var)
                  Incr Temp_variable_3
                  Tx_data(temp_variable_3) = Low(checksum_var)
             Case &B0101_0000                                   ' 32-bit crc
                  Temp_variable_1 = Temp_variable_3 - 1
                  Checksum_long = Crc32(tx_data(2) , Temp_variable_1)
          End Select
    
          ' Übertrag für Daten senden per UTXC
          Tx_pointer = 1
          Tx_length = Temp_variable_3
    
          ' Erstes Byte senden zum Start der Übertragung
          ' für RS-485
          Set Rs485_set_io
          nop
          nop
          nop
          Udr = Tx_data(1)
       End If
    
          ' Frame ist komplett, pointer zurücksetzen, Frame löschen
       If Rx_bytes_to_load >= Rx_pointer Then
          Rx_pointer = 0
          Rx_flag = 0
          For Temp_variable_1 = 1 To Rx_pointer
              Rx_data(temp_variable_1) = 0
          Next
       End If
    End Sub
    Vor den Erfolg haben die Götter den Schweiß gesetzt

  2. #22
    Benutzer Stammmitglied
    Registriert seit
    12.12.2004
    Ort
    Trier
    Beiträge
    38
    Hallo Vitis!

    Vielen Dank für deinen Quellcode. Aber hast du da S.N.A.P. (=Scaleable Node Address Protocol) nicht etwas zu wörtlich genommen.
    Während der Laufzeit sollte an einem Busprotokoll m.E. nichts mehr verändert werden. Auch sollten alle Busteilnehmer das gleiche Protokoll sprechen.
    Warum hast du dich für diese Lösung entschieden?

    MfG
    screwdriver
    Die Genialität einer Konstruktion liegt in ihrer Einfachheit. - Sergej P. Koroljow

  3. #23
    Erfahrener Benutzer Robotik Einstein Avatar von Vitis
    Registriert seit
    06.01.2005
    Ort
    Südpfalz
    Alter
    50
    Beiträge
    2.253
    ganz einfach, um den Code möglichst portabel zu machen

    Bin da auch noch nicht ganz fertig, die Statemachine für die Rückgabewerte fehlt noch, war aber die letzten Wochen etwas im Stress.
    Auch der Master ist in Arbeit, dauert aber ebenfalls noch.

    Wenn Du Codeteile nicht brauchst kannst Du die ja rauslöschen, der COde ansich ist ja recht übersichtlich in der Struktur, einfach nichbenötigte Teile auskommentieren.
    Vor den Erfolg haben die Götter den Schweiß gesetzt

Seite 3 von 3 ErsteErste 123

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Solar Speicher und Akkus Tests