Servoansteuerung mit Potis

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    Aufgrund technischer Veränderungen ist der Mailverkehr innerhalb des Forums (Private Nachrichten) nur noch eingeschränkt möglich. Die Einschränkung ist notwendig, um zusätzliche Betriebskosten für das Forum zu vermeiden. Näheres zu den Hintergründen im Thread "Aktuelles zum Forum".Wir bitten um Verständnis.

    Hinweis kann nach Kenntnisnahme deaktiviert werden!

    • Servoansteuerung mit Potis

      Hallo,

      ich weiß nicht ob das Thema im Forum schon behandelt wurde.
      Ich möchte Servos mit einem Poti über ADC-Ports am Atmega8 o.ä. ansteuern.

      Die Ansteuerung ist nicht das Problem selbst,
      sondern durch das Schwanken des AD-Wertes zappeln auch die Servos in Ruhepostion.
      Hat jemand schon Erfahrung damit, oder das Problem gelöst.

      Im Voraus vielen Dank für Eure Hilfe
      MfG

      ds1074
    • Ok, und deine Referenz ist auf AVCC eingestellt? Dann würde ich empfehlen den 'oberen' Anschluss des Potis möglichst ohne lange Leitung oder Umwege an den AVCC des Kontrollers anzuschließen. Für Gnd gilt dasselbe, nur ist da die Verbindung normalerweise schon direkter. Auf was ich hinaus will, durch Stromspitzen (Servobewegung) könnte es zu einem Spannungsabfall entweder am Kontroller oder Potianschluss kommen, dann schwanken auch die Messungen.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Wenn AVCC von Kontroller und Poti direkt verbunden sind und diese Leitung nicht mit zusätzlichen Verbrauchen belastet wird, sollte die Messung stabil sein. Könnte es sein, dass der mögliche Bereich von 1024 Werten nicht für den Servobereich ausgenutzt wird? Also der volle Schwenkbereich des Servos nur mit einem kleinen Wertebereich des Adwandlers abgedeckt wird?
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Für meinen Servoplotter hatte ich mir mal ein Testprogramm geschrieben, da kann man mit Potis die Servos bewegen und es wird der zugehörige timerwert angezeigt. Vielleicht nützt dir das. Ein Zittern hatte ich nicht.

      BASCOM-Quellcode

      1. '----------------------------------------------------------------------------
      2. $regfile = "m168pdef.dat"
      3. $crystal = 20000000
      4. $lib "YwRobot_Lcd_i2c.lib" 'YwRobot Treiber für LCD
      5. $hwstack = 64
      6. $swstack = 10
      7. $framesize = 40
      8. '**********************************************************
      9. '******************* Deklarationen ************************
      10. Const Pcf8574_lcd = &B0100_1110 'Adresse des I2C-LCDs
      11. Dim Lcd_backlight As Byte '1 = an; 0 = aus. Wird erst durch einen LCD-Befehl umgesetzt!
      12. Dim Puls_n As Byte 'Servonummer in der isr
      13. Dim Servo1 As Word 'Stellwert0=1msec, 156=2msec
      14. Dim Servo2 As Word 'Stellwert0=1msec, 156=2msec
      15. Dim Servo3 As Word 'Stellwert0=1msec, 156=2msec
      16. Dim Servo4 As Word 'Stellwert0=1msec, 156=2msec
      17. Servoport Alias Portd
      18. Ddrd = &B0000_1111 'port0..port3=output
      19. Config Timer1 = Timer , Prescale = 8 , Clear_timer = 1 '2500 Takte für 1 msec
      20. On Compare1a Timer1_isr
      21. Start Timer1
      22. Enable Interrupts
      23. Dim N As Word
      24. Dim Trigger As Byte '10msec Zeit ohne interrupt
      25. Compare1a = 4000 'Startwert
      26. Puls_n = 0 'Startwert
      27. Enable Compare1a
      28. Servo1 = 4000
      29. Servo2 = 4000
      30. Servo3 = 4000
      31. Servo4 = 4000
      32. Ddrc = &B0000_0000
      33. Config Adc = Single , Prescaler = Auto , Reference = Avcc
      34. Start Adc
      35. Dim P_1 As Word , P_2 As Word , P_3 As Word , P_4 As Word
      36. Dim C_1 As Word , C_2 As Word , C_3 As Word , C_4 As Word
      37. Dim S_1 As String * 4 , S_2 As String * 4 , S_3 As String * 4 , S_4 As String * 4
      38. Config Scl = Portc.5 'Konfigurieren von I2C
      39. Config Sda = Portc.4
      40. Config Lcd = 16x2 'nicht unbedingt nötig
      41. Config I2cdelay = 1
      42. Initlcd
      43. Waitms 300 'warte bis Kondensator bei Ta0 geladen, auch für LCD-Init!
      44. Lcd_backlight = 1
      45. 'Damit Backlight-Zustand an LCD übermittelt wird
      46. '**********************************************************
      47. '******************** Hauptprogramm ***********************
      48. Cls
      49. Locate 1 , 1 : Lcd " Servo"
      50. Locate 2 , 1 : Lcd " Handsteuerung"
      51. Wait 1
      52. Cls
      53. Do
      54. P_1 = Getadc(0) 'Poti
      55. P_2 = Getadc(1) 'Poti
      56. P_3 = Getadc(2) 'Poti
      57. P_4 = Getadc(3) 'Poti
      58. P_1 = P_1 * 40 : P_1 = P_1 / 10 'auf Werte 0..4000 bringen
      59. P_2 = P_2 * 40 : P_2 = P_2 / 10 'auf Werte 0..4000 bringen
      60. P_3 = P_3 * 40 : P_3 = P_3 / 10 'auf Werte 0..4000 bringen
      61. P_4 = P_4 * 40 : P_4 = P_4 / 10 'auf Werte 0..4000 bringen
      62. C_1 = P_1 + 1500 'Compare-Wert anzeigen
      63. C_2 = P_2 + 1500 'Compare-Wert anzeigen
      64. C_3 = P_3 + 1500 'Compare-Wert anzeigen
      65. C_4 = P_4 + 1500 'Compare-Wert anzeigen
      66. S_1 = Str(c_1) : S_1 = Format(s_1 , "0000")
      67. S_2 = Str(c_2) : S_2 = Format(s_2 , "0000")
      68. S_3 = Str(c_3) : S_3 = Format(s_3 , "0000")
      69. S_4 = Str(c_4) : S_4 = Format(s_4 , "0000")
      70. Locate 1 , 1 : Lcd " 1 " ; S_1 ; " 2 " ; S_2
      71. Locate 2 , 1 : Lcd " 3 " ; S_3 ; " 4 " ; S_4
      72. While Trigger > 0
      73. Decr Trigger
      74. Servo1 = C_1
      75. Servo2 = C_2
      76. Servo3 = C_3
      77. Servo4 = C_4
      78. Wend
      79. Loop
      80. End
      81. Timer1_isr:
      82. Select Case Puls_n
      83. Case 0 :
      84. Servoport.0 = 1
      85. Compare1a = Servo1 'Pulsdauer + 1 msec =max 2 msec
      86. Incr Puls_n 'Servonummer hochzählen
      87. Case 1 :
      88. Servoport.1 = 1
      89. Servoport.0 = 0
      90. Compare1a = Servo2 'Pulsdauer + 1 msec =max 2 msec
      91. Incr Puls_n 'Servonummer hochzählen
      92. Case 2 :
      93. Servoport.2 = 1
      94. Servoport.1 = 0
      95. Compare1a = Servo3 'Pulsdauer + 1 msec =max 2 msec
      96. Incr Puls_n 'Servonummer hochzählen
      97. Case 3 :
      98. Servoport.3 = 1
      99. Servoport.2 = 0
      100. Compare1a = Servo4 'Pulsdauer + 1 msec =max 2 msec
      101. Incr Puls_n 'Servonummer hochzählen
      102. Case 4 :
      103. Servoport.3 = 0
      104. Compare1a = 2500 * 10 '10msec Pause
      105. Puls_n = 0
      106. Trigger = 1
      107. End Select
      108. Return
      Alles anzeigen
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Ich fände das Programm von ds1074 interessanter.
      Einfach um zu sehen, ob es an der Software liegt.
      Daneben spielt die Hardware auch eine Rolle. Getrennte Versorgung mit gemeinsamen GND ist schon mal gut, manchmal sorgt aber der GND-Pfad auch für Verschiebungen.
      Hier wäre das Layout aufschlussreich.
      Vielleicht kannst du ja noch ein Foto anhängen, ds1074?
    • Vielen Dank für Eure Antworten,

      ich habe die Servos bisher über die Bascom-Routinen angesteuert
      (config Servos ... ADCx/4, da dort die Servos im Bereich von 0 -255 angesteuert werden)

      Vielleicht muss ich das nochmal überdenken.
      werde am WE mal weiter testen und mich dann wieder melden.
    • Dann muss aber dein Adwandlerwert mehr als +-1 schwanken, ein Wert von 100 und 103 hätten bei /4 das gleiche Ergebnis von 25.

      Äh, vergiss das obige, 99 und 100 geben eben 24 und 25 als Ergebnis, also auch eine deutliche Schwankung.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Hallo ds1074,
      ich weis nicht, was du für Servos nutzt. Ich hatte auch "Billigservos", die haben auch
      gezappelt,selbst bei festem Ansteuerpegel. Teste mal , ob die Servos auch zappeln,
      wenn du einen festen Wert ausgibst (also keinen ADC). Wenn die Servos dann auch unruhig sind, liegt es
      nicht nur an den ADC-Werten.

      Detlef
      Leichtsinn ist kein Mut, Vorsicht keine Feigheit.
    • Wenn's an den ADC Werten liegt, hilft vielleicht eine Software-Hysterese. a_27_b277ca12
      Ich hatte mal das Problem, dass einzulesende RC-Signale leicht verfälscht wurden, wenn die Flanken zu der Zeit kamen, als mein Programm eine andere ISR abarbeitete. Durch die verfälschten Eingangssignale wurde auch die weitere Berechnung und finale Servoausgabe verfälscht und die Servos zitterten hin und wieder. Abhilfe schaffte damals eine Software-Hysterese. Eine Berechnungen der Eingangssignale fand nur noch dann statt, wenn sich seit der letzten Messung der Wert "weit genug" verändert hatte. Keine Ahnung, ob diese auch bei ADC-Werten funktionieren würde (kann's im Moment leider nicht selbst testen). Der Code wäre in etwa so:

      BASCOM-Quellcode

      1. Const Jitterausgleich = 2
      2. .
      3. .
      4. Adc_wert = Getadc(1)
      5. .
      6. .
      7. Adc_schwankung = Adc_alt - Adc_wert 'SW-Hysterese
      8. If Abs(adc_schwankung) > Jitterausgleich Then
      9. Adc_alt = Adc_wert
      10. 'Hier stehen dann Deine weiteren Berechnungen, z.B. x = Adc_wert/4
      11. End If
      12. Servo(1) = x
      Alles anzeigen
    • Bascom Hysterese ADC. Hysteresewerte wählbar.Anstelle von PWM0A Servo oder Pulseout verwenden.

      BASCOM-Quellcode

      1. 'Bascom Poti einlesen
      2. $regfile = "attiny45.dat"
      3. $crystal = 1000000
      4. $hwstack = 40
      5. $swstack = 16
      6. $framesize = 32
      7. Config Adc = Single , Prescaler = Auto , Reference = Avcc
      8. Start Adc
      9. Config Timer0 = Pwm , Compare_a_pwm = Clear_up , Prescale = 8
      10. Dim Raw As Word
      11. Dim Raw_last As Word
      12. Dim Raw_min As Word
      13. Dim Raw_max As Word
      14. Dim Pwm As Word
      15. Const Hysterese = 10
      16. Do
      17. Raw = Getadc(3)
      18. Pwm = Raw_last / 4
      19. Pwm0a = Pwm
      20. Raw_min = Raw_last - Hysterese
      21. Raw_max = Raw_last + Hysterese
      22. If Raw <> Raw_last And Raw > 10 Then
      23. If Raw > Raw_max Or Raw < Raw_min Then
      24. Raw_last = Raw
      25. End If
      26. End If
      27. Loop
      28. End
      Alles anzeigen
    • Hier die Möglichkeit über ADC-Stop zittern verhindern.

      BASCOM-Quellcode

      1. $regfile = "attiny85.dat"
      2. $crystal = 1000000
      3. $hwstack = 40
      4. $swstack = 40
      5. $framesize = 40
      6. Dim W As Word
      7. Dim Channel As Byte
      8. Channel = 3
      9. Config Adc = Single , Prescaler = Auto , Reference = Avcc
      10. Config Servos = 1 , Servo1 = Portb.2 , Reload = 10
      11. Config Portb.2 = Output
      12. Enable Interrupts
      13. Do
      14. Start Adc
      15. W = Getadc(3)
      16. Stop Adc
      17. If W > 1000 Then W = 1000
      18. W = W / 10 'hier muss evtl. für andere Servos
      19. W = W + 100 'etwas angepasst werden.
      20. Servo(1) = W
      21. Loop
      22. End
      Alles anzeigen
    • @ftelektro hm, wo siehst du den Unterschied/Verbesserung, wenn du den Wandler ein- und ausschaltest? Es ist die Messung doch immer eine Momentaufnahme. Wenn das Signal am Eingang zittert, hilft das nix, besser wäre, mehrere Messungen mitteln. Meine ich.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Hallo an alle,

      zuerst mal vielen Dank für die vielen Tips.

      ich muss mich aber erst mal mit der Hardware des " Rollarms " befassen, besonders mit der Belegung des Erweiterungsboards. Vielleich hat jemand das Teil und weiß, was ich meine. Habe dazu noch keinen Schaltplan gefunden.

      Beim Pollinboard habe ich das Problem mit einem Drehencoder gelöst, was auch ganz gut funktioniert.
      Dort wähle ich jeden Servo einzeln aus, und stelle ihn damit ein.
      Sonst müsste ich für 4 Drehencoder 8 Ports verwenden, gegenüber 4 ADC-Ports.

      Werde mich also weiterhin eingehend damit befassen.
    • "Rollarm" ist vielleicht besser bekannt unter "Robotic Arm" hier der Link

      Robotic Arm


      ist aber z.Z. ausverkauft, habe noch einen der letzten preisgesenkt erwischt.
      Weiß jetzt auch warum, die 4 Potis spinnen total (interne Wackelkontakte).
      Da brauche ich mich nicht zu wundern, das die Servos verrückt spielen.


      Muss also erst mal sehen, das ich neue Potis bekomme, dann werde ich weitersehen.
      Also nochmals vielen Dank für Eure Tipps.


      Melde mich wieder, wenn es was Neues zu diesem Thema gibt