Dzielenie odcinka na równe części na podstawie "widełek" [BASCOM]

Pytania, kody i porady dotyczące nie tylko Bascom.
airman
Posty: 7
Rejestracja: 13 gru 2019, 7:30

Dzielenie odcinka na równe części na podstawie "widełek" [BASCOM]

Post autor: airman » 13 gru 2019, 8:00

Witam.

Potrzebuje podzielić odcinek na równe części i wyliczyć ilość punktów uwzględniając przy tym wytyczne dot długości min. i max. odcinka.
W skrócie po podaniu długości odcinka dostaje informację o ilości punktów oraz wyliczonej długości podziału.

Przykład
Odcinek: 1200mm
"widełki" podziału: 220-300mm
początek i koniec odcinka to stała wartość 60mm

W jaki sposób mogę to obliczyć ? i czy w ogóle jest możliwość wykonania tego przy użyciu BASCOM ?

Obrazek

Dziękuję za ewentualną pomoc.
Pozdrawiam
Awatar użytkownika
niveasoft
Posty: 1216
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: Dzielenie odcinka na równe części na podstawie "widełek" [BASCOM]

Post autor: niveasoft » 13 gru 2019, 17:59

Przepraszam, że wcześniej nie odpowiedziałem. Jakoś silnik Forum nie powiadomił mnie o zapytaniu. Trudno :D
Pan to chyba źle opisał :
W skrócie po podaniu długości odcinka dostaje informację o ilości punktów oraz wyliczonej długości podziału.
Tak pobieżnie rozumuje, że chcesz dostać informacje o wyliczonej długości podziału po podaniu ilości punktów oraz długości odcinka?

Nie obraź się, ale coraz więcej ludzi ma problem z określeniem swoich oczekiwań :D Potraktuj to jako żart, ale też przeczytaj swoje pytanie i moje.

Nie, nie jestem kobietą. Nie potrafię się domyśleć. W technice nie ma na to miejsca.
airman
Posty: 7
Rejestracja: 13 gru 2019, 7:30

Re: Dzielenie odcinka na równe części na podstawie "widełek" [BASCOM]

Post autor: airman » 16 gru 2019, 7:47

Nie obrażam się w żadnym wypadku, sam byłem świadom, że mi ciężko wytłumaczyć a innemu może być ciężko to zrozumieć :D
to dlatego narysowałem prosty przykład ^^

Długość wkładanego elementu do maszyny zgodnie z rysunkiem to 1200mm (długości mogą być od 800 do 5000mm)

po wpisaniu wymiaru na klawiaturze numerycznej urządzenie powinno automatycznie rozmierzyć punkty obróbki oraz wyświetlić ich ilość na hd44780 czyli:
pierwszy punkt zawsze 60mm od początku profilu, każdy kolejny równo rozmieszczony ma się zmieścić w przedziale 220-300mm lecz ostatni musi wypaść 60mm od końca.

Wydziorgałem wstępnie program którego testuje w symulatorze jednak wymiar mi się nie zgadza. Przy wymiarze 2345mm powinno być 10 otworów w rozstawie 247,22mm Oto on:

temp- wpisany wymiar
  1. $sim
  2. $regfile = "m32def.dat"
  3. $crystal = 8000000
  4. $hwstack = 64
  5. $swstack = 32
  6. $framesize = 64
  7. $baud = 1200
  8. $timeout = 10000
  9.  
  10.  
  11. Config Submode = New
  12. Config Lcdpin = Pin , Db4 = Portc.5 , Db5 = Portc.4 , Db6 = Portc.3 , Db7 = Portc.2 , E = Portc.6 , Rs = Portc.7 , Wr = Portb.1
  13. Config Lcd = 16x2
  14. Cursor Off , Noblink
  15. Cls
  16.  
  17. config portd.1=input
  18.  
  19. dim PrzerwaMax as word
  20. dim PrzerwaMin as word
  21. dim Przerwaa as word
  22. dim Przerwa as word
  23. dim Otwory as word
  24. dim Skrajnyotwor as byte
  25. dim Temp as word
  26. dim x as single
  27. dim y as word
  28. dim z as single
  29.  
  30.  
  31. PrzerwaMax=300             'przerwa maksymalna
  32. PrzerwaMin=220             'przerwa minimalna
  33. Skrajnyotwor=120           'skrajny otwor 60x2=120mm
  34. Temp=2345                  'calkowity wymiar elementu obrabianego
  35. przerwa=0
  36.  
  37.  
  38. set portd.1=0
  39.  
  40. Do
  41.  
  42. przerwa=temp-skrajnyotwor
  43. przerwa=przerwa\otwory
  44.  
  45. locate 1,1
  46. lcd temp
  47. locate 2,1
  48. lcd Otwory
  49.  
  50. otwory=otwory+1
  51.  
  52.  
  53. if przerwa>=PrzerwaMin and przerwa<=PrzerwaMax then
  54. gosub wiercenie
  55.  
  56.  
  57. end if
  58.  
  59. Loop
  60. End
  61.  
  62.  
  63.  
  64.  
  65. wiercenie:
  66. cls
  67. do
  68. locate 1,1
  69. lcd "OK!"
  70.  
  71. y=otwory+1
  72. x=przerwa/y
  73.  
  74. locate 1,6
  75. lcd otwory
  76.  
  77. locate 2,1
  78. lcd "wymiar ";x;"mm"
  79. loop until portd.1=1      'czekaj az przycisk nie zostanie wcisniety
  80. return
Awatar użytkownika
niveasoft
Posty: 1216
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: Dzielenie odcinka na równe części na podstawie "widełek" [BASCOM]

Post autor: niveasoft » 16 gru 2019, 8:23

No nie zawsze można podzielić bez reszty. Zerknij co tu wymodziłem.
...a nie wiem czy wcześniej pisałeś, że możemy zejść do ułamków milimetra czyli liczb z przecinkiem ;)
  1. $sim
  2. $regfile = "m32def.dat"
  3. $crystal = 8000000
  4. $hwstack = 64
  5. $swstack = 32
  6. $framesize = 64
  7. $baud = 1200
  8. $timeout = 10000
  9.  
  10.  
  11. Config Submode = New
  12. Config Lcdpin = Pin , Db4 = Portc.5 , Db5 = Portc.4 , Db6 = Portc.3 , Db7 = Portc.2 , E = Portc.6 , Rs = Portc.7 , Wr = Portb.1
  13. Config Lcd = 16x2
  14. Cursor Off , Noblink
  15. Cls
  16.  
  17. Config Portd.1 = Input
  18.  
  19. Dim Przerwamax As Word
  20. Dim Przerwamin As Word
  21. Dim Przerwaa As Word
  22. Dim Przerwa As Word
  23. Dim Otwory As Word
  24. Dim Skrajnyotwor As Byte
  25. Dim Temp As Word
  26. Dim X As Single
  27. Dim Y As Word
  28. Dim Z As Single
  29.  
  30. Dim My_temp1 As Word , My_temp2 As Word , Helpb As Byte , Mem1 As Word , Mem2 As Word
  31.  
  32.  
  33. Przerwamax = 300                                            'przerwa maksymalna
  34. Przerwamin = 220                                            'przerwa minimalna
  35. Skrajnyotwor = 120                                          'skrajny otwor 60x2=120mm
  36. Temp = 2345                                                 'calkowity wymiar elementu obrabianego
  37. Przerwa = 0
  38.  
  39.  
  40. Przerwa = Temp - Skrajnyotwor                               '2225
  41. My_temp2 = Przerwamin - 1
  42. Mem1 = Przerwamax
  43.  
  44. Do
  45.  Incr My_temp2                                              'zwiększaj przerwe 220, 221, 223, 224...
  46.  My_temp1 = Przerwa                                         'przypomnij długość początkową
  47.  My_temp1 = My_temp1 Mod My_temp2                           'dziel przez przerwę i sprawdź resztę
  48.  If My_temp1 = 0 Then                                       'nie ma reszty->Okay!
  49.   Helpb = 1
  50.   Exit Do
  51.  Else                                                       'niestety mamy resztę z dzielenia
  52.   If My_temp1 < Mem1 Then                                   'jeśli reszta mniejsza od poprzedniej to
  53.    Mem1 = My_temp1                                          'zapamietaj reszte
  54.    Mem2 = My_temp2                                          'zapamietaj przerwe
  55.   End If
  56.  End If
  57.  If My_temp2 >= Przerwamax Then                             'gdyby przerwa miała już 300 to opuść
  58.   Helpb = 2
  59.   Exit Do
  60.  End If
  61. Loop
  62.  
  63. Select Case Helpb
  64.  Case 1 :
  65.   Print "Okay! Przerwa powinna wynosić " ; My_temp2
  66.  Case 2
  67.   Print "Nie udało się podzielić bez reszty. Wynik z najniższą resztą=" ; Mem1 ; " to " ; Mem2
  68. End Select
  69.  
  70. End
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
airman
Posty: 7
Rejestracja: 13 gru 2019, 7:30

Re: Dzielenie odcinka na równe części na podstawie "widełek" [BASCOM]

Post autor: airman » 16 gru 2019, 8:45

Możemy zejść do ułamków milimetra,tak by w późniejszym czasie można było łatwo przerzucić na kroki silnika. Jak już dzielenie będzie poprawne to muszę dodać jeszcze obsługę klawiatury i wspomnianego silnika krokowego step/dir

Jednak Przy wymiarze 2345mm powinno być 10 otworów w rozstawie 247,22mm
wynik z programu to 278 z resztą 1.
7444691100_1576143990.jpg
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
Ostatnio zmieniony 16 gru 2019, 14:58 przez airman, łącznie zmieniany 3 razy.
Awatar użytkownika
niveasoft
Posty: 1216
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: Dzielenie odcinka na równe części na podstawie "widełek" [BASCOM]

Post autor: niveasoft » 16 gru 2019, 9:06

Trzeba nad tym pomyśleć, bo Ty tak piszesz, ze otworów ma być dziesięć przy tym wymiarze a jak sprawdzisz kalkulatorem to (2345-120)/278=8,003597122302158
Może to później policzę na Single, albo wszystko się pomnoży x100 żeby się pozbyć ułamków. Na razie mam poniedziałkowy młyn.
airman
Posty: 7
Rejestracja: 13 gru 2019, 7:30

Re: Dzielenie odcinka na równe części na podstawie "widełek" [BASCOM]

Post autor: airman » 16 gru 2019, 9:38

niveasoft pisze:
16 gru 2019, 9:06
Trzeba nad tym pomyśleć, bo Ty tak piszesz, ze otworów ma być dziesięć przy tym wymiarze a jak sprawdzisz kalkulatorem to (2345-120)/278=8,003597122302158
Może to później policzę na Single, albo wszystko się pomnoży x100 żeby się pozbyć ułamków. Na razie mam poniedziałkowy młyn.
Masz rację.
Można to podzielić w dwojaki sposób mieszcząc się w widełkach. Jeden otwór trzeba dodać gdyż nie jest liczony w programie czyli wychodzi 9.
20191216_093153.jpg
A co do młyna to i tak dziękuję, że znajdujesz czas by pomóc innym.
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
Awatar użytkownika
Oldman
Posty: 61
Rejestracja: 19 cze 2019, 11:15

Re: Dzielenie odcinka na równe części na podstawie "widełek" [BASCOM]

Post autor: Oldman » 16 gru 2019, 15:25

Wymyśliłem taki algorytm ;) który może ułatwi obliczenia.
Masz odcinek o długości np. 2500mm. Najpierw odejmujesz od niego 2x60 czyli zostaje 2380. Teraz dzielisz to przez dolną wartość widełek czyli przez 220. Wynik to 10,82.
Część całkowita czyli 10 to największa ilość możliwych odcinków. Teraz dzielisz 2380 przez górną wartość widełek czyli 300 i otrzymujesz 7,9. Znowu bierzesz część całkowitą, w tym wypadku 7, i gdy część dziesiętna nie jest równa zeru to zwiększasz o jeden (7+1). Jeżeli z dzielenia wyjdzie liczba całkowita np. 8,00 to oczywiście już jej nie zwiększasz. Otrzymujesz najmniejsza ilość równych odcinków =8. Czyli w grę wchodzi podział przez 8, 9, i 10. Przy długościach odcinków odpowiednio: 297,5 264,4 i 238.

Napisałem krótki program, w którym wykorzystałem mój algorytm.
  1. $sim
  2. $regfile = "m32def.dat"
  3. $crystal = 8000000
  4. $hwstack = 64
  5. $swstack = 32
  6. $framesize = 64
  7. $baud = 1200
  8. $timeout = 10000
  9.  
  10.  
  11. Config Submode = New
  12. Config Lcdpin = Pin , Db4 = Portc.5 , Db5 = Portc.4 , Db6 = Portc.3 , Db7 = Portc.2 , E = Portc.6 , Rs = Portc.7 , Wr = Portb.1
  13. Config Lcd = 16x2
  14. Cursor Off , Noblink
  15. Cls
  16.  
  17. Config Portd.1 = Input
  18.  
  19. Dim Gabaryt As Single
  20. Dim Pomoc As Single
  21. Dim Przerwamax As Word
  22. Dim Przerwamin As Word
  23. Dim N As Byte                                               'minimalna ilość odcinków
  24. Dim M As Byte                                               'maksymalna ilość odcinków
  25. Dim Reszta As Single
  26. Dim Przerwa As Single
  27.  
  28.  
  29. Gabaryt = 2345
  30. Przerwamax = 300                                            'przerwa maksymalna
  31. Przerwamin = 220                                            'przerwa minimalna
  32.  
  33.  
  34. Gabaryt = Gabaryt - 120
  35. M = Gabaryt \ Przerwamin                                 'tu uzyskujemy wynik w liczbach całkowitych, dziesiętne z automatu zostają odrzucone (odwrotna kreska ukośna)
  36.                                                                          ' czyli M to największa możliwa ilość odcinków przy zadanych widełkach
  37. Pomoc = Gabaryt / Przerwamax                          'a tu dzielimy przez zwykłą kreskę ukośną więc otrzymujemy wynik z częścią ułamkową
  38. Reszta = Frac(pomoc)                                         'wyciągamy część ułamkową, tą po kropce
  39. Print "Pomoc=" ; Pomoc                                       'te dwa "printy" dopisałem żeby było widać jak to pracuje
  40. Print "Reszta=" ; Reszta
  41. If Reszta = 0 Then                                              ' i sprawdzamy czy ma wartość zerową
  42.      N = Pomoc                                                       'jeśli tak to wynik dzielenia jest gotową minimalną ilością odcinków
  43.                                                                             ' (przy przepisaniu do N tracimy to co po kropce bo N jest liczbą typu Byte
  44.  Else
  45.      N = Pomoc + 1                                                  'jeżeli z dzielenia wyszły jakieś ułamki to zwiększamy N o jeden
  46. End If
  47.  '&&&&&&&&&&&&&&&&&& Właściwie tu się kończy "mój " algorytm, reszta to już jest tylko część obliczeniowa dla sprawdzenia poprawności działania
  48.  
  49. Do                                                                                       'to NIE JEST pętla główna programu
  50.   Przerwa = Gabaryt \ N                                                         'najpierw zaczynamy dzielić materiał na minimalną ilość odcinków
  51.   Print "Ilość odcinków=" ; N ; "   Długość odcinka=" ; Przerwa             ' tu wypisujemy wynik działania
  52.   Incr N                                                                                                ' przechodzimy do kolejnej liczby podziału
  53.   If N > M Then Exit Do                                                                          'dopóki nie zaliczymy wszystkich możliwych wariantów
  54. Loop
  55.  
  56. End
Ostatnio zmieniony 17 gru 2019, 11:20 przez Oldman, łącznie zmieniany 3 razy.
airman
Posty: 7
Rejestracja: 13 gru 2019, 7:30

Re: Dzielenie odcinka na równe części na podstawie "widełek" [BASCOM]

Post autor: airman » 17 gru 2019, 9:11

Program działa bardzo dobrze i bardzo dziękuję Oldman za nakierowanie, mam wrażenie, że zajmuje troszkę więcej miejsca w pamięci ale to nie jest problem (jeszcze :D).

gabaryt | Przerwa
1500 | 276,000mm
2345 | 247,222mm
4214 | 272,933mm

To przykładowe wyniki z kalkulatora którego posiadam. Czy można zrobić działanie które wypluje mi takie wyniki ? ewentualnie czy możesz Opisać w komentarzach działanie każdej linii ?
Na marginesie nie wiedziałem, że istnieje funkcja FRAC zastanawiam się dlaczego wyciągamy dziesiętne funkcją FRAC wcześniej dzieląc
  1. Pomoc = Gabaryt \ Przerwamax
bez reszty ?
Być może zadaję śmieszne pytania jednak programowanie to dla mnie ciągła nauka o tyle o ile układy potrafię zmontować tak z językami się biję od dłuższego czasu ;)
Awatar użytkownika
Oldman
Posty: 61
Rejestracja: 19 cze 2019, 11:15

Re: Dzielenie odcinka na równe części na podstawie "widełek" [BASCOM]

Post autor: Oldman » 17 gru 2019, 10:16

Dla każdego programowanie to ciągła nauka, niezależnie od zaawansowania ;) Oczywiście nie dotyczy Bartka :P
W programie dopisałem komentarze a tu jeszcze kilka uwag.
Program oblicza wszystkie możliwe podziały dla zadanej długości materiału i widełek, dlatego następnie musisz mieć możliwość wyboru tego, który Cię interesuje. Przykładowo dla długości materiału 5000mm mamy aż 6 możliwych podziałów (od 17 do 22). Dopiero po wybraniu podziału (z klawiatury?) należy obliczyć pozycje kolejnych otworów. Pierwszy oczywiście na 60-tym milimetrze, kolejny na "60 + Przerwa" itd.
W moim przykładzie brakuje jakiejkolwiek kontroli wpisanych wartości. Na przykład czy Gabaryt jest większy od Przerwamax, czy Przerwamax jest większa od Przerwymin itp.
Jakby co to pytaj. Mirek.
Edit: Dopisałem dwa "Printy" żebyś mógł podejrzeć jak zmieniają się wartości Pomoc i Reszta. Sprawdź dla długości np. 3720 (podział bez reszty)
ODPOWIEDZ