-
        

Ergebnis 1 bis 5 von 5

Thema: 16 Servos an einem Controller

  1. #1
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    24.09.2006
    Ort
    Nähe Mannheim
    Beiträge
    269

    16 Servos an einem Controller

    Anzeige

    HI,
    Ich habe ja versucht knapp 20 Servos über einen Microcontroller laufen zu lassen.
    Dummerweise kam mir meien Abschlussprüfung in die quere und somit hatte ich keien Zeit mehr dafür.
    Aber da der ganze Käse endlich vorbei ist hatte ich malwieder etwas zeit und habe eine Software PWM geschrieben die auf vorschläge in diesem forum bassiert.

    Maximal können 16 Servos unabhängig von einander angesteuert werden
    Es ist im Grunde aber rellativ einfach gesammt 32 anzusteuern aber da bin ch noch am rumprobieren.

    Falls jemand einene vorschlag hat wie man das verbessern könnte wär ich sehr froh drüber

    Achja und ein Guten Rutsch ins neue Jahr ^^


    Code:
    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------
    '----------------------------- Software PWM ------------------------------------
    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------
    '------- Voreinstellungen
    '-------------------------------------------------------------------------------
    Restart:
    
    $regfile = "m8535.dat"                                      'ATMega8535
    $framesize = 32
    $swstack = 32
    $hwstack = 32
    $crystal = 8000000                                          'Quarz: 8.0000 MHz
    $baud = 9600
    '-------------------------------------------------------------------------------
    '------- Timer 0
    '-------------------------------------------------------------------------------
    Print "Programm Start"
    Config Timer1 = Timer , Prescale = 256                      'Konfiguriere Timer1
    Enable Timer1                                               'schalte den Timer1 ein
    On Timer1 Isr_von_timer_fuer_f                              'verzweige bei Timer1 überlauf zu   Isr_von_Timer1
    Enable Interrupts
    Load Timer1 , 625                                           '64911                                   'Timer1 soll schon von 625 wegzählen
    
    
    Enable Interrupts
    'Load Timer0 224                                             'Timer0 Zählwert ergibt 1MHz
    
    
    
    
    
    '-------------------------------------------------------------------------------
    '------- Output
    '-------------------------------------------------------------------------------
    Config Porta = Output
    Config Portc = Output
    
    
    
    '-------------------------------------------------------------------------------
    '------- Servo Variablen
    '-------------------------------------------------------------------------------
    Dim Servos(20) As Word
    Dim Servos_a(8) As Word
    Dim Servos_b(8) As Word
    
    
    Dim Input_aw As Byte
    Dim Output_aw As Byte
    Dim Rech_aw As Byte
    
    '-------------------------------------------------------------------------------
    '------- Wait Variablen
    '-------------------------------------------------------------------------------
    
    Dim Z As Word                                               'Zähl Variable als waitus ersatz ;P
    Dim W_s(8) As Word                                          'Waitzeiten Save für übergabe vorgerechnet
    Dim Wa(8) As Word
    Dim Wb(8) As Word
    Dim Wa_s(8) As Word
    Dim Wb_s(8) As Word
    '-------------------------------------------------------------------------------
    '------- Berechnungsvariablen
    '-------------------------------------------------------------------------------
    Dim Rech(20) As Word                                        ' rechen Variable
    Dim Nr_a(20) As Byte                                        'Port nummer
    Dim Nr_b(20) As Byte                                        'Port nummer
    
    Dim Index As Byte
    Dim Wert As Word
    Dim Index_plus As Byte
    Dim Nr As Byte
    
    Dim Durchgang As Byte                                       'gibt an welche stelle des bytes grade berechnet wird: 1 - 8
    Dim Durchgang_plus As Byte                                  'durchgang + 1
    Dim Durchgang_minus As Byte
    Dim Save_rech(10) As Word
    
    Dim Port_s(8) As Byte                                       'Port Save = Zwischenspeicher von port Byte's
    Dim Port_s_a(8) As Byte                                     'Port Save = Zwischenspeicher von port Byte's
    Dim Port_s_b(8) As Byte                                     'Port Save = Zwischenspeicher von port Byte's
    
    Dim Akt_byte As Byte
    
    
    '-------------------------------------------------------------------------------
    '------- Hauptprogramm
    '-------------------------------------------------------------------------------
    Akt_byte = 3
    Do
    Servos_a(1) = 10
    Servos_a(2) = 20
    Servos_a(3) = 30
    Servos_a(4) = 40
    Servos_a(5) = 50
    Servos_a(6) = 60
    Servos_a(7) = 70
    Servos_a(8) = 80                                            'Pa7
    
    Servos_b(1) = 90
    Servos_b(2) = 100
    Servos_b(3) = 110
    Servos_b(4) = 120
    Servos_b(5) = 130
    Servos_b(6) = 140
    Servos_b(7) = 150
    Servos_b(8) = 160
    
    '-------------------------------------------------------------------------------
    '------- Byte übergabe
    '-------------------------------------------------------------------------------
    
    If Akt_byte = 2 Then Akt_byte = 3
    If Akt_byte = 1 Then Akt_byte = 2
    If Akt_byte = 3 Then Akt_byte = 1
    
    
    If Akt_byte = 1 Then
    Servos(1) = Servos_a(1)
    Servos(2) = Servos_a(2)
    Servos(3) = Servos_a(3)
    Servos(4) = Servos_a(4)
    Servos(5) = Servos_a(5)
    Servos(6) = Servos_a(6)
    Servos(7) = Servos_a(7)
    Servos(8) = Servos_a(8)
    End If
    If Akt_byte = 2 Then
    Servos(1) = Servos_b(1)
    Servos(2) = Servos_b(2)
    Servos(3) = Servos_b(3)
    Servos(4) = Servos_b(4)
    Servos(5) = Servos_b(5)
    Servos(6) = Servos_b(6)
    Servos(7) = Servos_b(7)
    Servos(8) = Servos_b(8)
    End If
    
    
    
    '-------------------------------------------------------------------------------
    '------- Umrechnen der 0 - 180 werte auf 0 - 390  (390 = maximaler Schleifenwert)
    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------
    For Nr = 1 To 8
    Rech(nr) = Servos(nr) * 217
    Rech(nr) = Rech(nr) / 100
    Next Nr                                                     'Rechnung klappt perfekt
    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------
    '------- Berechnen der Ausgangswerte
    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------
    'Input = rech 1 - 8 des wars
    'output = Die Byte werte der 50 HZ schleife
    'Zu rechnen:
    '1. kleinster Wert mit Index
    '2. vergleich auf anderer index mit gleichen werten und auf 1000 setzen
    '3. alle Werte mit 1000 vom Byte abziehen
    '4. Nun muss die Schleife von vorne beginnen und besagte werte ignorieren
    ' Zu Beachten: Alle Werte müssen verstellbare Var's sein um eine große Schleife
    ' zu verwirklichen was weniger speicher braucht als ein Byte komplett zu
    ' scripten und den uC unnötig aufzuhalten.
    '-------------------------------------------------------------------------------
    
    '-------------------------------------------------------------------------------
    '------- Übergabe von Rech auf Rech_save
    '-------------------------------------------------------------------------------
    For Save_rech(10) = 1 To 8
    Save_rech(save_rech(10)) = Rech(save_rech(10))
    W_s(save_rech(10)) = 0
    Next Save_rech(10)
    Save_rech(9) = 500
    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------
    For Durchgang = 1 To 8                                      'Variable die angibt welche Stelle berechnet wird
    '-------------------------------------------------------------------------------
    Durchgang_plus = Durchgang + 1
    Durchgang_minus = Durchgang - 1
    Wert = 500
    Rech(9) = 500
    '-------------------------------------------------------------------------------
    '------- Berechnen der niedrigsten Zahl und des Index
    '------- Die namen erklären sich von selbst ^^
    '-------------------------------------------------------------------------------
    'Größenvergleich der aktuellen Zahl (nr) und der nachfolgenden Zahl (index_plus)
    'Falls Rech(nr) unter der aktuellen niedrigsten zahl ist wird der niedrigste
    'Wert aktualisiert. Der index ist einfach die NR des durchgangs
    'Der WERT wird bei jedem neuen Durchgang (var: Durchgang) auf 500 gesetzt.
    'Um damit den alten Wert zu löschen und die 2...7 niedrigste Zahl zu berechnen
    For Nr = 1 To 8
    Index_plus = Nr + 1
    
       If Rech(nr) < Rech(index_plus) Then
    
          If Rech(nr) < Wert Then
    
    
                Wert = Rech(nr)
                Index = Nr
    
    
          End If
       End If
    
    Next Nr
    '-------------------------------------------------------------------------------
    '------- Erste Wait Zeit = Niedrigster Wert somit Rech(index)
    '-------------------------------------------------------------------------------
    'Da Rech(1...8) ja auf 1000 gesetz werden muss dessen eigentliche werte in
    'Save_rech gespeichert werden
    '-------------------------------------------------------------------------------
    Save_rech(durchgang) = Rech(index)
    If Durchgang = 1 Then
    W_s(1) = Rech(index)
    Else
    If Save_rech(durchgang_minus) = Rech(index) Or Rech(index) = 1000 Then
    W_s(durchgang) = 0
    Else
    W_s(durchgang) = Rech(index) - Save_rech(durchgang_minus)
    End If
    End If
    '-------------------------------------------------------------------------------
    '------- Auf gleiche Werte überprüfen und ggf auf 1000 setzen
    '-------------------------------------------------------------------------------
    Port_s(durchgang) = 255
    '-------------------------------------------------------------------------------
    For Nr = 1 To 8
    '-------------------------------------------------------------------------------
    '------- Auf gleiche Werte Testen
    'Alle werte die mit rech(index) identisch sind auf 1000 setzen
    '-------------------------------------------------------------------------------
    If Rech(nr) = Rech(index) Then
    If Nr <> Index Then
    Rech(nr) = 1000
    End If
    End If
    Next Nr
    Rech(index) = 1000
    '-------------------------------------------------------------------------------
    '------- Ende Vergleich es folg Ausgangsbyte 1000er vergleich
    '------- Alle Werte die 1000 sind vom byte abziehen
    '-------------------------------------------------------------------------------
    'Print "Ende Vergleich es folg Ausgangsbyte 1000er vergleich"
    '-------------------------------------------------------------------------------
    For Nr = 1 To 8
    If Rech(nr) = 1000 Then
    Input_aw = Nr
    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------
    'Eingang: Input_aw  1- 8
    'Ausgang: Output_aw 1,2,4,8,16,32,64,128
    '-------------------------------------------------------------------------------
    'Werte umrechnen
    Input_aw = Input_aw - 1
    Output_aw = 1
    'Berechnungsschleife
    For Rech_aw = 1 To Input_aw
    Output_aw = Output_aw * 2
    Next Input_aw
    '-------------------------------------------------------------------------------
    Port_s(durchgang) = Port_s(durchgang) - Output_aw
    '-------------------------------------------------------------------------------
    End If
    Next Nr
    '-------------------------------------------------------------------------------
    '------- Neuer Berechnungszyklus
    '-------------------------------------------------------------------------------
    Next Durchgang
    '-------------------------------------------------------------------------------
    '------- Berechnung Fertig => Wert Übergabe
    '-------------------------------------------------------------------------------
    'Print "Berechnungs Ende => Wertuebergabe"
    '-------------------------------------------------------------------------------
    'Erst fertig berechnete Werte schnellstmöglich übergeben
    
    If Akt_byte = 2 Then
    For Nr = 1 To 8
    Wb_s(nr) = W_s(nr)
    Port_s_b(nr) = Port_s(nr)
    Next Nr
    For Nr = 1 To 8
    Wa(nr) = Wa_s(nr)
    Wb(nr) = Wb_s(nr)
    Nr_a(nr) = Port_s_a(nr)
    Nr_b(nr) = Port_s_b(nr)
    Next Nr
    End If
    
    
    If Akt_byte = 1 Then
    For Nr = 1 To 8
    Wa_s(nr) = W_s(nr)
    Port_s_a(nr) = Port_s(nr)
    Next Nr
    End If
    
    '-------------------------------------------------------------------------------
    '------- Schleifen Ende
    '-------------------------------------------------------------------------------
    Loop
    '-------------------------------------------------------------------------------
    '------- ENDE
    '-------------------------------------------------------------------------------
    Print "ENDE"
    End
    '-------------------------------------------------------------------------------
    '------- ISR TImer 1 (theoretische 50Hz Schleife hab kein Oszi^^)
    '-------------------------------------------------------------------------------
    Isr_von_timer_fuer_f:
    Enable Interrupts
    
    Load Timer1 , 625                                           'Timer1 soll schon von 625 wegzählen
    Porta = 255
    Waitus 520
    
    '-------------------------------------------------------------------------------
    '------- Byte A
    '-------------------------------------------------------------------------------
    For Z = 1 To Wa(1)
    Next Z
    
    Porta = Nr_a(1)
    
    For Z = 1 To Wa(2)
    Next Z
    
    Porta = Nr_a(2)
    
    For Z = 1 To Wa(3)
    Next Z
    
    Porta = Nr_a(3)
    
    For Z = 1 To Wa(4)
    Next Z
    
    Porta = Nr_a(4)
    
    For Z = 1 To Wa(5)
    Next Z
    
    Porta = Nr_a(5)
    
    For Z = 1 To Wa(6)
    Next Z
    
    Porta = Nr_a(6)
    
    For Z = 1 To Wa(7)
    Next Z
    
    Porta = Nr_a(7)
    
    For Z = 1 To Wa(8)
    Next Z
    
    Porta = Nr_a(8)
    
    '-------------------------------------------------------------------------------
    '------- Byte C
    '-------------------------------------------------------------------------------
    Portc = 255
    Waitus 520
    
    For Z = 1 To Wb(1)
    Next Z
    
    Portc = Nr_b(1)
    
    For Z = 1 To Wb(2)
    Next Z
    
    Portc = Nr_b(2)
    
    For Z = 1 To Wb(3)
    Next Z
    
    Portc = Nr_b(3)
    
    For Z = 1 To Wb(4)
    Next Z
    
    Portc = Nr_b(4)
    
    For Z = 1 To Wb(5)
    Next Z
    
    Portc = Nr_b(5)
    
    For Z = 1 To Wb(6)
    Next Z
    
    Portc = Nr_b(6)
    
    For Z = 1 To Wb(7)
    Next Z
    
    Portc = Nr_b(7)
    
    For Z = 1 To Wb(8)
    Next Z
    
    Portc = Nr_b(8)
    
    Return
    '-------------------------------------------------------------------------------
    '------- ENDE
    '-------------------------------------------------------------------------------
    End

  2. #2
    Moderator Robotik Einstein Avatar von HannoHupmann
    Registriert seit
    19.11.2005
    Ort
    München
    Alter
    34
    Beiträge
    4.528
    Blog-Einträge
    1
    @Feratu das nächste mal bitte den Queltext mit [ Code] posten dann muss der nicht durchgescrollt werden und bleibt auch in der ursprünglichen Formatierung.

    Außerdem bin ich mir nicht sicher, ob du hier im richtigen Unterforum gelandet bist, da es sich ja mehr um Software Problem handelt als um Hardwareproblem. Also vielleicht nen Admin bitten in ein geeigneteres zu verschieben, wenn du hier keine Antworten bekommst.

  3. #3
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    24.09.2006
    Ort
    Nähe Mannheim
    Beiträge
    269
    So war noch einfacher als ich anfangs dachte
    Das Programm kann jetzt 24 Servos unabhängig von einander ansteuern.

    Eingabe:
    Servos_a(7) = 180
    => Servo 7 des Bytes A (Porta.6) fährt auf 180° also ausschlag rechts.

    Das ganze funktioniert aber nur Ausgangsbyte weise also nicht Porta.6 und Portc.1 soweit bin ich noch net ^^ .

    Aktuell verbraucht es 54% des Speichers des AVR.
    Ja groß aber es klappt ^^


    Code:
    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------
    '----------------------------- Software PWM ------------------------------------
    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------
    '------- Voreinstellungen
    '-------------------------------------------------------------------------------
    Restart:
    
    $regfile = "m8535.dat"                                      'ATMega8535
    $framesize = 32
    $swstack = 32
    $hwstack = 32
    $crystal = 8000000                                          'Quarz: 8.0000 MHz
    $baud = 9600
    '-------------------------------------------------------------------------------
    '------- Timer 0
    '-------------------------------------------------------------------------------
    Print "Programm Start"
    Config Timer1 = Timer , Prescale = 256                      'Konfiguriere Timer1
    Enable Timer1                                               'schalte den Timer1 ein
    On Timer1 Isr_von_timer_fuer_f                              'verzweige bei Timer1 überlauf zu   Isr_von_Timer1
    Enable Interrupts
    Load Timer1 , 625                                           '64911                                   'Timer1 soll schon von 625 wegzählen
    
    
    Enable Interrupts
    'Load Timer0 224                                             'Timer0 Zählwert ergibt 1MHz
    
    
    
    
    
    '-------------------------------------------------------------------------------
    '------- Output
    '-------------------------------------------------------------------------------
    Config Porta = Output
    Config Portb = Output
    Config Portc = Output
    
    
    
    '-------------------------------------------------------------------------------
    '------- Servo Variablen
    '-------------------------------------------------------------------------------
    Dim Servos(8) As Word
    Dim Servos_a(8) As Word
    Dim Servos_b(8) As Word
    Dim Servos_c(8) As Word
    
    
    Dim Input_aw As Byte                                        'Servo 1..8 auf Byte umrechen 1,2,4,8....
    Dim Output_aw As Byte
    Dim Rech_aw As Byte
    
    '-------------------------------------------------------------------------------
    '------- Wait Variablen
    '-------------------------------------------------------------------------------
    
    Dim Z As Word                                               'Zähl Variable als waitus ersatz ;P
    Dim W_s(8) As Word                                          'Waitzeiten Save für übergabe vorgerechnet
    Dim Wa(8) As Word
    Dim Wb(8) As Word
    Dim Wc(8) As Word
    Dim Wa_s(8) As Word
    Dim Wb_s(8) As Word
    Dim Wc_s(8) As Word
    
    '-------------------------------------------------------------------------------
    '------- Berechnungsvariablen
    '-------------------------------------------------------------------------------
    Dim Rech(9) As Word                                         ' rechen Variable
    Dim Nr_a(8) As Byte                                         'Port nummer
    Dim Nr_b(8) As Byte                                         'Port nummer
    Dim Nr_c(8) As Byte                                         'Port nummer
    
    Dim Index As Byte
    Dim Wert As Word
    Dim Index_plus As Byte
    Dim Nr As Byte
    
    Dim Durchgang As Byte                                       'gibt an welche stelle des bytes grade berechnet wird: 1 - 8
    Dim Durchgang_plus As Byte                                  'durchgang + 1
    Dim Durchgang_minus As Byte
    Dim Save_rech(10) As Word
    
    Dim Port_s(8) As Byte                                       'Port Save = Zwischenspeicher von port Byte's
    Dim Port_s_a(8) As Byte                                     'Port Save = Zwischenspeicher von port Byte's
    Dim Port_s_b(8) As Byte                                     'Port Save = Zwischenspeicher von port Byte's
    Dim Port_s_c(8) As Byte                                     'Port Save = Zwischenspeicher von port Byte's
    
    Dim Akt_byte As Byte
    
    
    '-------------------------------------------------------------------------------
    '------- Hauptprogramm
    '-------------------------------------------------------------------------------
    Akt_byte = 0
    Do
    '-------------------- Byte A
    Servos_a(1) = 60                                            '60
    Servos_a(2) = 80                                            '80  'hoch nach links / runter nach rechts
    Servos_a(3) = 142                                           '142
    Servos_a(4) = 110                                           '110 'rechts = hoch   / Links = runter
    Servos_a(5) = 30                                            '30  'rechts = hoch / links = runter
    Servos_a(6) = 38                                            '38
    Servos_a(7) = 83                                            '83
    Servos_a(8) = 110                                           '110 'Pa7
    '-------------------- Byte B
    Servos_b(1) = 0
    Servos_b(2) = 0
    Servos_b(3) = 0
    Servos_b(4) = 0
    Servos_b(5) = 0
    Servos_b(6) = 0
    Servos_b(7) = 0                                             '85
    Servos_b(8) = 0                                             '100
    '-------------------- Byte C
    Servos_c(1) = 0
    Servos_c(2) = 0
    Servos_c(3) = 0
    Servos_c(4) = 0
    Servos_c(5) = 0
    Servos_c(6) = 0
    Servos_c(7) = 85                                            '85
    Servos_c(8) = 100                                           '100
    
    '-------------------------------------------------------------------------------
    '------- Byte übergabe
    '-------------------------------------------------------------------------------
    Incr Akt_byte
    If Akt_byte = 4 Then Akt_byte = 1
    
    
    If Akt_byte = 1 Then
    Servos(1) = Servos_a(1)
    Servos(2) = Servos_a(2)
    Servos(3) = Servos_a(3)
    Servos(4) = Servos_a(4)
    Servos(5) = Servos_a(5)
    Servos(6) = Servos_a(6)
    Servos(7) = Servos_a(7)
    Servos(8) = Servos_a(8)
    End If
    If Akt_byte = 2 Then
    Servos(1) = Servos_b(1)
    Servos(2) = Servos_b(2)
    Servos(3) = Servos_b(3)
    Servos(4) = Servos_b(4)
    Servos(5) = Servos_b(5)
    Servos(6) = Servos_b(6)
    Servos(7) = Servos_b(7)
    Servos(8) = Servos_b(8)
    End If
    If Akt_byte = 3 Then
    Servos(1) = Servos_c(1)
    Servos(2) = Servos_c(2)
    Servos(3) = Servos_c(3)
    Servos(4) = Servos_c(4)
    Servos(5) = Servos_c(5)
    Servos(6) = Servos_c(6)
    Servos(7) = Servos_c(7)
    Servos(8) = Servos_c(8)
    End If
    
    
    
    '-------------------------------------------------------------------------------
    '------- Umrechnen der 0 - 180 werte auf 0 - 390  (390 = maximaler Schleifenwert)
    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------
    For Nr = 1 To 8
    Rech(nr) = Servos(nr) * 217
    Rech(nr) = Rech(nr) / 100
    Next Nr
    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------
    '------- Berechnen der Ausgangswerte
    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------
    'Input = rech 1 - 8 des wars
    'output = Die Byte werte der 50 HZ schleife
    'Zu rechnen:
    '1. kleinster Wert mit Index
    '2. vergleich auf anderer index mit gleichen werten und auf 1000 setzen
    '3. alle Werte mit 1000 vom Byte abziehen
    '4. Nun muss die Schleife von vorne beginnen und besagte werte ignorieren
    ' Zu Beachten: Alle Werte müssen verstellbare Var's sein um eine große Schleife
    ' zu verwirklichen was weniger speicher braucht als ein Byte komplett zu
    ' scripten und den uC unnötig aufzuhalten.
    '-------------------------------------------------------------------------------
    
    '-------------------------------------------------------------------------------
    '------- Übergabe von Rech auf Rech_save
    '-------------------------------------------------------------------------------
    For Save_rech(10) = 1 To 8
    Save_rech(save_rech(10)) = Rech(save_rech(10))
    W_s(save_rech(10)) = 0
    Next Save_rech(10)
    Save_rech(9) = 500
    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------
    For Durchgang = 1 To 8                                      'Variable die angibt welche Stelle berechnet wird
    '-------------------------------------------------------------------------------
    Durchgang_plus = Durchgang + 1
    Durchgang_minus = Durchgang - 1
    Wert = 500
    Rech(9) = 500
    '-------------------------------------------------------------------------------
    '------- Berechnen der niedrigsten Zahl und des Index
    '------- Die namen erklären sich von selbst ^^
    '-------------------------------------------------------------------------------
    'Größenvergleich der aktuellen Zahl (nr) und der nachfolgenden Zahl (index_plus)
    'Falls Rech(nr) unter der aktuellen niedrigsten zahl ist wird der niedrigste
    'Wert aktualisiert. Der index ist einfach die NR des durchgangs
    'Der WERT wird bei jedem neuen Durchgang (var: Durchgang) auf 500 gesetzt.
    'Um damit den alten Wert zu löschen und die 2...7 niedrigste Zahl zu berechnen
    For Nr = 1 To 8
    Index_plus = Nr + 1
    
       If Rech(nr) < Rech(index_plus) Then
    
          If Rech(nr) < Wert Then
    
    
                Wert = Rech(nr)
                Index = Nr
    
    
          End If
       End If
    
    Next Nr
    '-------------------------------------------------------------------------------
    '------- Erste Wait Zeit = Niedrigster Wert somit Rech(index)
    '-------------------------------------------------------------------------------
    'Da Rech(1...8) ja auf 1000 gesetz werden muss dessen eigentliche werte in
    'Save_rech gespeichert werden
    '-------------------------------------------------------------------------------
    Save_rech(durchgang) = Rech(index)
    If Durchgang = 1 Then
    W_s(1) = Rech(index)
    Else
    If Save_rech(durchgang_minus) = Rech(index) Or Rech(index) = 1000 Then
    W_s(durchgang) = 0
    Else
    W_s(durchgang) = Rech(index) - Save_rech(durchgang_minus)
    End If
    End If
    '-------------------------------------------------------------------------------
    '------- Auf gleiche Werte überprüfen und ggf auf 1000 setzen
    '-------------------------------------------------------------------------------
    Port_s(durchgang) = 255
    '-------------------------------------------------------------------------------
    For Nr = 1 To 8
    '-------------------------------------------------------------------------------
    '------- Auf gleiche Werte Testen
    'Alle werte die mit rech(index) identisch sind auf 1000 setzen
    '-------------------------------------------------------------------------------
    If Rech(nr) = Rech(index) Then
    If Nr <> Index Then
    Rech(nr) = 1000
    End If
    End If
    Next Nr
    Rech(index) = 1000
    '-------------------------------------------------------------------------------
    '------- Ende Vergleich es folg Ausgangsbyte 1000er vergleich
    '------- Alle Werte die 1000 sind vom byte abziehen
    '-------------------------------------------------------------------------------
    'Print "Ende Vergleich es folg Ausgangsbyte 1000er vergleich"
    '-------------------------------------------------------------------------------
    For Nr = 1 To 8
    If Rech(nr) = 1000 Then
    Input_aw = Nr
    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------
    'Eingang: Input_aw  1- 8
    'Ausgang: Output_aw 1,2,4,8,16,32,64,128
    '-------------------------------------------------------------------------------
    'Werte umrechnen
    Input_aw = Input_aw - 1
    Output_aw = 1
    'Berechnungsschleife
    For Rech_aw = 1 To Input_aw
    Output_aw = Output_aw * 2
    Next Input_aw
    '-------------------------------------------------------------------------------
    Port_s(durchgang) = Port_s(durchgang) - Output_aw
    '-------------------------------------------------------------------------------
    End If
    Next Nr
    '-------------------------------------------------------------------------------
    '------- Neuer Berechnungszyklus
    '-------------------------------------------------------------------------------
    Next Durchgang
    '-------------------------------------------------------------------------------
    '------- Berechnung Fertig => Wert Übergabe
    '-------------------------------------------------------------------------------
    'Print "Berechnungs Ende => Wertuebergabe"
    '-------------------------------------------------------------------------------
    'Erst fertig berechnete Werte schnellstmöglich übergeben
    
    If Akt_byte = 3 Then
    For Nr = 1 To 8
    Wc_s(nr) = W_s(nr)
    Port_s_c(nr) = Port_s(nr)
    Next Nr
    For Nr = 1 To 8
    Wa(nr) = Wa_s(nr)
    Wb(nr) = Wb_s(nr)
    Wc(nr) = Wc_s(nr)
    Nr_a(nr) = Port_s_a(nr)
    Nr_b(nr) = Port_s_b(nr)
    Nr_c(nr) = Port_s_c(nr)
    Next Nr
    End If
    
    
    If Akt_byte = 1 Then
    For Nr = 1 To 8
    Wa_s(nr) = W_s(nr)
    Port_s_a(nr) = Port_s(nr)
    Next Nr
    End If
    
    If Akt_byte = 2 Then
    For Nr = 1 To 8
    Wb_s(nr) = W_s(nr)
    Port_s_b(nr) = Port_s(nr)
    Next Nr
    End If
    '-------------------------------------------------------------------------------
    '------- Schleifen Ende
    '-------------------------------------------------------------------------------
    Loop
    
    '-------------------------------------------------------------------------------
    '------- ISR TImer 1 (theoretische 50Hz Schleife hab kein Oszi^^)
    '-------------------------------------------------------------------------------
    Isr_von_timer_fuer_f:
    Enable Interrupts
    
    Load Timer1 , 625                                           'Timer1 soll schon von 625 wegzählen
    Porta = 255
    Waitus 520
    
    '-------------------------------------------------------------------------------
    '------- Byte A
    '-------------------------------------------------------------------------------
    For Z = 1 To Wa(1)
    Next Z
    
    Porta = Nr_a(1)
    
    For Z = 1 To Wa(2)
    Next Z
    
    Porta = Nr_a(2)
    
    For Z = 1 To Wa(3)
    Next Z
    
    Porta = Nr_a(3)
    
    For Z = 1 To Wa(4)
    Next Z
    
    Porta = Nr_a(4)
    
    For Z = 1 To Wa(5)
    Next Z
    
    Porta = Nr_a(5)
    
    For Z = 1 To Wa(6)
    Next Z
    
    Porta = Nr_a(6)
    
    For Z = 1 To Wa(7)
    Next Z
    
    Porta = Nr_a(7)
    
    For Z = 1 To Wa(8)
    Next Z
    
    Porta = Nr_a(8)
    
    '-------------------------------------------------------------------------------
    '------- Byte B
    '-------------------------------------------------------------------------------
    Portb = 255
    Waitus 520
    
    For Z = 1 To Wb(1)
    Next Z
    
    Portb = Nr_b(1)
    
    For Z = 1 To Wb(2)
    Next Z
    
    Portb = Nr_b(2)
    
    For Z = 1 To Wb(3)
    Next Z
    
    Portb = Nr_b(3)
    
    For Z = 1 To Wb(4)
    Next Z
    
    Portb = Nr_b(4)
    
    For Z = 1 To Wb(5)
    Next Z
    
    Portb = Nr_b(5)
    
    For Z = 1 To Wb(6)
    Next Z
    
    Portb = Nr_b(6)
    
    For Z = 1 To Wb(7)
    Next Z
    
    Portb = Nr_b(7)
    
    For Z = 1 To Wb(8)
    Next Z
    
    Portb = Nr_b(8)
    
    '-------------------------------------------------------------------------------
    '------- Byte C
    '-------------------------------------------------------------------------------
    Portc = 255
    Waitus 520
    
    For Z = 1 To Wc(1)
    Next Z
    
    Portc = Nr_c(1)
    
    For Z = 1 To Wc(2)
    Next Z
    
    Portc = Nr_c(2)
    
    For Z = 1 To Wc(3)
    Next Z
    
    Portc = Nr_c(3)
    
    For Z = 1 To Wc(4)
    Next Z
    
    Portc = Nr_c(4)
    
    For Z = 1 To Wc(5)
    Next Z
    
    Portc = Nr_c(5)
    
    For Z = 1 To Wc(6)
    Next Z
    
    Portc = Nr_c(6)
    
    For Z = 1 To Wc(7)
    Next Z
    
    Portc = Nr_c(7)
    
    For Z = 1 To Wc(8)
    Next Z
    
    Portc = Nr_c(8)
    
    
    
    Return

    ps: @HannoHupmann besser ? ^^

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    21.02.2007
    Beiträge
    6

    Re: 16 Servos an einem Controller

    Hallo Feratu,

    Zitat Zitat von Feratu
    HI,
    Ich habe ja versucht knapp 20 Servos über einen Microcontroller laufen zu lassen.
    Dummerweise kam mir meien Abschlussprüfung in die quere und somit hatte ich keien Zeit mehr dafür.
    Aber da der ganze Käse endlich vorbei ist hatte ich malwieder etwas zeit und habe eine Software PWM geschrieben die auf vorschläge in diesem forum bassiert.

    Maximal können 16 Servos unabhängig von einander angesteuert werden
    Es ist im Grunde aber rellativ einfach gesammt 32 anzusteuern aber da bin ch noch am rumprobieren.

    Falls jemand einene vorschlag hat wie man das verbessern könnte wär ich sehr froh drüber

    Achja und ein Guten Rutsch ins neue Jahr ^^
    .
    .

    '------- ENDE
    '-------------------------------------------------------------------------------
    End
    wünsche Dir und allen anderen geneigten Lesern noch ein gutes Jahr.

    Deine Servosteuerung per Software ist für mich eine interessante Geschichte.

    Mich würde aber auch Deine Hardware neben dem ATMega8535 zu diesem Projekt interessieren.

    Würde mich freuen, wenn Du mal hierzu ein paar Worte sagen könntest.


    Gruß

    Edgar

  5. #5
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    24.09.2006
    Ort
    Nähe Mannheim
    Beiträge
    269
    Dir auch frohes neues ;P

    Im Grunde hab ich nur die Spannungsversorgung für den ATmega also ein 7805 und eine Spannungsversorgung für die Servos (78S06).
    Dann ein paar Kondensatoren sowie der 8 MHz Quarz und schon läuft das ding.
    Mir ist nur aufgefallen das man 2 verschiedene Spannungsregler nehmen sollte um den uC und die Servos zu versorgen.
    Ich hatte anfangs nur einen Servo sowie den uC an dem 7805 hängen.
    Bei dem tollen Versuch ist mir der Servo und der uC drauf geggangen der 7805 geht heute noch ?! oO

    Da das meine Testplatine ist, befindet sich noch ein "152281 MAX 232N" zur übertragung der "PRINT " Befehle zum PC auf der Platine. .
    Alldergings braucht man den eigentlich nicht.

    Zwischen den Ports und den Servos ist nix.
    Da kommt gleich meine Frage:
    Ist es sinnvoll ein Pull-Down Widerstand an die PWM Ports zu hängen um eventuelle Störungen rauszufiltern oder eher egal ?

    mfg Feratu

Berechtigungen

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