Die Mobsepu mit ttt Spif (Die Modellbauservoplotteruhr mit tictactoe Spielfunktion)

    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!

    • Die Mobsepu mit ttt Spif (Die Modellbauservoplotteruhr mit tictactoe Spielfunktion)

      Ich brauch mal wieder ein Geschenk, das auch bisschen aufwändiger sein darf. Dazu möchte ich ein paar meiner letzten Beschäftigungen kombinieren.
      Modellbauservo-Plotter, mein nächster Schritt
      Der Modellbauservoplotter als Anzeigeelement, Berechnung der Servostellungen mit 'inverser Kinematik'
      tic tac toe minimax-Algorithmus und Rekursion

      Das Ergebnis soll die Mobsepu werden. Ein Gerät, das im Normalfall die Uhrzeit hin schreibt und auf Anforderung mit einem tictactoe spielt, also das Spielfeld aufmalt und die entsprechenden x und o einzeichnet.

      Der mechanische Aufbau ist schon fortgeschritten, aber noch nicht ganz fertig
      Frontansicht.jpgRückansicht.jpgArme ohne Schreibspule.jpgGelenk.jpgSchreibkopf.jpg
      mir geht es jetzt darum, die inverse Kinematik-Berechnung zu testen. Dazu habe ich mir ein Rechenprogramm erstellt, das mir im Simulator zu einem XY-Punkt auf der Zeichenfläche den Drehwinkel der Servos aus gibt.
      (Programm wird im nächsten post nachgereicht)
      Die Bezeichnungen im Programm entsprechen der Beschriftung hier
      Frontansicht mit Bezeichnungen.jpg
      Mit einem weiteren Hilfsprogramm, mit dem ich per Poti die Servos steuern kann und mit die dazu gehörigen timerwerte (Pulslängen) anzeigt, kann ich das ganze überprüfen.
      Raum für Notizen

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

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

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von tschoeatsch ()

    • Die Winkelberechnung

      BASCOM-Quellcode

      1. $regfile = "m168pdef.dat"
      2. $crystal = 20000000
      3. $hwstack = 64
      4. $swstack = 10
      5. $framesize = 40
      6. 'Strecken
      7. Dim X As Single , Y As Single
      8. Dim L1 As Single , L12 As Single , L2 As Single , L22 As Single , Temp As Single
      9. Dim Dx1 As Single , Dx2 As Single , Dy1 As Single , Dy2 As Single
      10. Dim Cos_w12 As Single , Cos_w22 As Single
      11. 'Winkel
      12. Dim W1 As Single , W2 As Single , W11 As Single , W12 As Single , W21 As Single , W22 As Single
      13. Const Pi = 3.1416
      14. Const Pi_2 = Pi / 2
      15. 'konstante Werte haben:
      16. 'Hebelarme
      17. Const La = 150
      18. Const 2la = La * 2
      19. Const La2 = La * La
      20. Const Lb = 100
      21. Const 2lb = Lb * 2
      22. Const Lb2 = Lb * Lb
      23. Const Lb2_la2 = Lb2 - La2
      24. 'servos
      25. Const Servo1_x = 75
      26. Const Servo1_y = 216
      27. Const Servo2_x = 115
      28. Const Servo2_y = 216
      29. X = 190
      30. Y = 130
      31. 'Berechnung Servo1
      32. 'L1 nach Pythagoras berechnen
      33. Dx1 = X -servo1_x : Dx1 = Abs(dx1)
      34. Dy1 = Y -servo1_y : Dy1 = Abs(dy1)
      35. L12 = Dx1 * Dx1 : Temp = Dy1 * Dy1 : L12 = L12 + Temp
      36. L1 = Sqr(l12)
      37. 'W11 mit arctan2 berechnen
      38. W11 = Atn2(dy1 , Dx1)
      39. If X <= Servo1_x Then W11 = Pi - W11
      40. 'W12 mit dem Kosinussatz berechnen
      41. Cos_w12 = Lb2_la2 + L12 : Cos_w12 = Cos_w12 / 2lb : Cos_w12 = Cos_w12 / L1
      42. W12 = Acos(cos_w12)
      43. W1 = W11 + W12 'Winkel am Servo1
      44. 'Berechnung Servo2
      45. 'L2 nach Pythagoras berechnen
      46. Dx2 = X -servo2_x : Dx2 = Abs(dx2)
      47. Dy2 = Y -servo2_y : Dy2 = Abs(dy2)
      48. L22 = Dx2 * Dx2 : Temp = Dy2 * Dy2 : L22 = L22 + Temp
      49. L2 = Sqr(l22)
      50. 'W21 mit arctan2 berechnen
      51. W21 = Atn2(dy2 , Dx2)
      52. If X >= Servo2_x Then W21 = Pi - W21
      53. 'W22 mit dem Kosinussatz berechnen
      54. Cos_w22 = Lb2_la2 + L22 : Cos_w22 = Cos_w22 / 2lb : Cos_w22 = Cos_w22 / L2
      55. W22 = Acos(cos_w22)
      56. W2 = W21 + W22 'Winkel am Servo2
      57. Print W1
      58. Print W2
      59. End
      Alles anzeigen
      (Die Winkelberechnung braucht ca. 1,3 mSec)
      Die Handsteuerung mit Anzeige der Timerwerte

      BASCOM-Quellcode

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

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

      -----------------------------------------------------------------------------------------------------
    • Im Prinzip mach ich das gleiche (geplant). Zum ersten Test will ich mit der Handsteuerung 2 bestimmte Punkte in der Eichvorlage anfahren und deren vorher berechnete Winkel mit den dazu angezeigten Timerwerten verrechnen. Danach einen weiteren Punk ansteuern und das Ergebnis überprüfen. Im Original hab' ich ja keine Anzeige mehr und da will ich eine Eichfunktion einbauen, die mit den Tasten bedient wird und die die daraus ermittelten Werte im rom speichert. Auf die Linearität bin ich gespannt. Aus Lust am Risiko hab' ich natürlich günstige Servos bestellt :D Die machen jetzt noch keinen schlechten Eindruck.
      Raum für Notizen

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

      -----------------------------------------------------------------------------------------------------
    • Wir reden aneinander vorbei. Das Händische ist nur ein Test, einfach mal so, könnte ich einsparen. Meine Eichversion ist wie deine, nur von der anderen Seite. Mit den Tasten fahre ich Punkte an, von denen der Winkel bekannt ist. Die sich ergebenden Timerwerte werden diesen Winkeln zugeordnet. Du hattest es wohl anders rum gemacht, bekannte Timerwerte gemessenen Winkel zugeordnet. Nur kann ich bei mir die Winkel schlechter messen, leichter ist es bestimmte Koordinaten anzufahren (denke ich). Ich schließe auch nicht aus, eine weitere Ausführung zu bauen. Deren Servos sind sicherlich bisschen anders (hab' ich schon bemerkt, das es leichte Differenzen gibt, beim Drehwinkel zB.). Und die Arme stecken ja auf Verzahnungen, um einen Zahn verdreht, macht schon viel am Winkel aus. Das wird mit meiner Version ausgeglichen.
      Raum für Notizen

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

      -----------------------------------------------------------------------------------------------------
    • tschoeatsch schrieb:

      Mit den Tasten fahre ich Punkte an, von denen der Winkel bekannt ist. Die sich ergebenden Timerwerte werden diesen Winkeln zugeordnet.
      Ja, da reden wir wohl wirklich aneinander vorbei.
      Du brauchst keine Punkte anfahren, es reicht, zu wissen, welchen Winkel das Servo bei welchem Puls einnimmt.
      Die Punkte liegen dann ja auf einem Kreis um den ellenbogen herum.
      Es ist also eher nicht sinnvoll, einen Punkt anzufahren und den Winkel des Servos zu bestimmen, wo du es doch sowieso erst bei Bedarf errechnen musst.

      tschoeatsch schrieb:

      Und die Arme stecken ja auf Verzahnungen, um einen Zahn verdreht, macht schon viel am Winkel aus.
      Das ist nur ein Offset. Aber warum sollte man nach der Bestimmung des Winkels diesen wieder mechanisch verändern?
    • Michael schrieb:

      Ja, da reden wir wohl wirklich aneinander vorbei.
      Immer noch. Mein Eichen passiert beim ersten Start des Programms, da weiß ich noch keinen Zusammenhang zwischen Winkel und Puls bei diesem verwendeten Servo. Es werden mit den Tasten 2 oder mehrere Punkte der Eichvorlage angefahren und bei Erreichen bestätigt. Jetzt weiß das Programm: zu diesen Stellungen braucht man Timerwert xyz. Aus diesen verschiedenen Werten wird dann mit 3 Satz eben der Zusammenhang zwischen Timer und Winkel errechnet und im weiteren verwendet. Wichtig ist bei mir nur, die Arme so aufzustecken, dass alle Bereiche auf der Zeichenfläche erreicht werden. Um das zu erreichen, muss der Servo zB. so hingedreht werden, dass man den Arm in einer waagrechten Position aufstecken kann und so sicher sein kann, dass alles passt. Meine Geometrie habe ich so ausgelegt, dass ich fast 180° Drehwinkel vom Servo ausnutze um möglichst viel Auflösung zu haben. Ich habe den Drehwinkel der Servos vorher überprüft ^^
      Raum für Notizen

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

      -----------------------------------------------------------------------------------------------------
    • Das war jetzt ein schwieriges Unterfangen, der Mobsepu die ersten kontrollierten Striche zu entlocken. Natürlich lag's an meinen Fehlern, aber bis ich die alle gefunden hatte. Aber jetzt endlich kann sie ihre Ärmchen mit Hilfe von Bresenham doch leidlich so bewegen, dass eine gerade Linie gezeichnet wird.
      Raum für Notizen

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

      -----------------------------------------------------------------------------------------------------
    • Michael schrieb:

      na langsam wird's doch ;)
      Jetzt hast du es fast geschafft, brauchst nur noch den Zeichensatz als Vektoren und los gehts.
      Ja, fast. Jetzt geht's mit hardware weiter. Der Stift ist ja noch nicht fertig. Die Spule, die ich schon gezeigt habe, muss neu gewickelt werden (für 5-6V Betrieb, statt 24V, wie es mal im Relais vorgesehen war) und einen Treiber braucht es dazu (ist auf meiner vorhandenen Platine nicht vorhanden). Als reinen E-Magnet bekomm' ich nicht die Stärke hin, dass er wie der winzige Neodym auf der Tafel malt. Ich hab's nicht raus gebracht, warum. So wird jetzt mit dem E-Magnet der Neodym innerhalb des Messingröhrchens bewegt, das geht. Nur muss ich die Spule umschalten, damit der Magnet auch von der Tafel abhebt, wenn nicht geschrieben werden soll. Ich denke, ich mach das der Einfachheit mal mit 2 Relais.
      Raum für Notizen

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

      -----------------------------------------------------------------------------------------------------
    • @six1 sag' mal, hast du auch ein Programm für Kringel, das die Pixel nacheinander im Kreis anordnet? Dein Bresenham für Kreis macht das leider nicht, oder ich hab's nicht kapiert trinkende-smileys-211
      Raum für Notizen

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

      -----------------------------------------------------------------------------------------------------
    • Das hab' ich natürlich schon so gemacht. Aber die E-Magneten, die relativ gut 'malten', waren schon Brocken. Aus einer Türklingel zB. Wenn mein Aufbau fertig ist, zeige ich Details.
      Raum für Notizen

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

      -----------------------------------------------------------------------------------------------------
    • Moin,
      hier der Bresenham mit X und Y Punkten (gl_x, gl_y)

      BASCOM-Quellcode

      1. '-------------------------------------------------------------------------------
      2. ' Gl_circle
      3. ' Bresenham-Algorithm for CIRCLE
      4. '-------------------------------------------------------------------------------
      5. Sub Gl_circle(byval X0 As Word , Byval Y0 As Word , Byval Radius As Word )
      6. Local F As Integer
      7. Local Ddf_x As Integer
      8. Local Ddf_y As Integer
      9. Local X As Integer
      10. Local Y As Integer
      11. F = 1 - Radius
      12. Ddf_x = 0
      13. Ddf_y = -2 * Radius
      14. X = 0
      15. Y = Radius
      16. Gl_x = X0 : Gl_y = Y0 + Radius
      17. Gosub Disp_setpixel
      18. Gl_x = X0 : Gl_y = Y0 - Radius
      19. Gosub Disp_setpixel
      20. Gl_x = X0 + Radius : Gl_y = Y0
      21. Gosub Disp_setpixel
      22. Gl_x = X0 - Radius : Gl_y = Y0
      23. Gosub Disp_setpixel
      24. While X < Y
      25. If F >= 0 Then
      26. Decr Y
      27. Ddf_y = Ddf_y + 2
      28. F = F + Ddf_y
      29. End If
      30. Incr X
      31. Ddf_x = Ddf_x + 2
      32. F = F + Ddf_x
      33. Incr F
      34. Gl_x = X0 + X : Gl_y = Y0 + Y
      35. Gosub Disp_setpixel
      36. Gl_x = X0 - X : Gl_y = Y0 + Y
      37. Gosub Disp_setpixel
      38. Gl_x = X0 + X : Gl_y = Y0 - Y
      39. Gosub Disp_setpixel
      40. Gl_x = X0 - X : Gl_y = Y0 - Y
      41. Gosub Disp_setpixel
      42. Gl_x = X0 + Y : Gl_y = Y0 + X
      43. Gosub Disp_setpixel
      44. Gl_x = X0 - Y : Gl_y = Y0 + X
      45. Gosub Disp_setpixel
      46. Gl_x = X0 + Y : Gl_y = Y0 - X
      47. Gosub Disp_setpixel
      48. Gl_x = X0 - Y : Gl_y = Y0 - X
      49. Gosub Disp_setpixel
      50. Wend
      51. End Sub
      Alles anzeigen
      Code first, think later - Natural programmer :D
    • @six1 danke, aber den code kenne ich schon. Wie ich das sehe, werden zuerst an den 4 'Kanten' (mir fällt gerade nicht der Fachbegriff ein, Quadranten??) 4 Pixel gesetzt, Zeile 18 bis 25 und dann immer neben diesen 4 Pixeln auf beiden Seiten Pixel, bis der Kreis geschlossen ist. Das hilft mir hier nicht, ich möchte wie mit einem Zirkel malen und nicht von einem Punkt zu einem entfernten Punkt ständig springen. Mein Wunsch wäre so wie der Bresenham für die Linie einer für eine gekrümmte Linie, die einen Kreis bildet.
      Raum für Notizen

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

      -----------------------------------------------------------------------------------------------------
    • Es geht voran. Hier mal paar Details vom 'Stift'. Es ist ein E-Magnet, der als Kern eine Kombi aus Stahlnadeln und Neodymmagneten hat. Die Magnete erzeugen das Magnetfeld, das zum Malen notwendig ist, die Spule bewegt nur den Kern zur Tafel hin oder von der Tafel weg.
      Stift_Einzelteile.jpgStift_Detailansicht.jpgStift_montiert.jpgStift_montiert-1.jpg
      Die Stromversorgung geschieht über die Arme. Diese sind aus Leiterplattenmaterial und zur besseren Kontaktierung sind Schleifkontakte aufgebracht. Die komische Oberfläche soll Silber sein :S . Eigentlich wollte ich das alles mit meinem Handgalvanikset vergolden, sah noch bescheuerter aus <X . Also alles wieder runter und versilbert. Silberoxyd soll ja auch leiten :/

      Ja und nach einem Tag Arbeit, kann ich jetzt tictactoe spielen. Es hat so lange gedauert, bis ich einen komischen Fehler gefunden habe. Eine for..next-Schleife lief immer nur 1x statt 8x durch. Ewig rum gemacht, bis ich mal die dim-Anweisung für die for-Variable innerhalb der Variablen umgestellt habe. Und plötzlich geht alles a_27_b277ca12 Das muss ich noch genauer erforschen...
      Aber hier das Ergebnis
      Das Zucken der Arme am oberen Rand ist eine Kontrolle des 'Denkvorgangs'
      Raum für Notizen

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

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