Skocz do zawartości

Arduino - prośba o pomoc


AdamK

Rekomendowane odpowiedzi

CHcę za pomocą serwa i Arduino Uno sterować zdalnie zakładaniem na obiektyw refraktora maski Bathinowa. 

Jednak wszystkie programy jakie znajduję, to demonstracje jak działa serwo i jedyne co one wykonują to obracają się w pętli "w te i we w te"...

Poniżej jeden z takich programów, który obraca dźwignią o 180 stopni w jedną stronę, a potem spowrotem i tak w kółko.

Czy ktoś znający temat, mógłby to przerobić na program, który tylko obróci mi dźwignię o 180 stopni raz, a potem po skończonym ostrzeniu refraktora, obróci tą dźwignię spowrotem?

Nie potrafię tego zrobić... pomoże ktoś?

 

#include <Servo.h>

Servo myservo;  // tworzy objekt servo do kontroli naszego serwa
                // na większości płytek można stworzyć takich obiektów 12

int pos = 0;    // zmienna do zapamiętania pozycji serwa

void setup()

  myservo.attach(9);  // zdefiniowanie do którego portu podłączone jest serwo

void loop()

  for(pos = 0; pos <= 180; pos += 1) // obrót od 0 do 180 stopni 
  {                                  // w krokach co 1 stopień
    myservo.write(pos);              // przekazanie do serwa obrotu o tyle ile jest zapisane w zmiennej 'pos'
    delay(15);                       // poczekaj 15ms, aby serwo osiągnęło ustaloną pozycje
  } 
  for(pos = 180; pos>=0; pos-=1)     // obrót od 180 do 0 stopni 
  {                                
    myservo.write(pos);              // przekazanie do serwa obrotu o tyle ile jest zapisane w zmiennej 'pos'
    delay(15);                       // poczekaj 15ms, aby serwo osiągnęło ustaloną pozycje
  } 
}

Odnośnik do komentarza
Udostępnij na innych stronach

Chciałbym, żeby to było coś prostego, bez wodotrysków: tylko ruch w jedną stronę i potem spowrotem

Pewnie żeby program wiedział w którą stronę ma przekręcić maskę, najlepiej byłoby użyć polecenia  (nie przyciski) sugerowane przez Ciebie: "otwórz" i "zamknij"... Przyciski odpadają, bo to ma być sterowane zdalnie z komputera.

Odnośnik do komentarza
Udostępnij na innych stronach

Tzn chcesz do maski podpiąć serwo, serwo do pinu arduino, a arduino kablem do kompa (schematycznie?) I żeby to działało z poziomu arduino ide? Pewnie będziesz musiał za każdym razem chcąc zmienić pozycję maski wgrać od nowa program do mikrokontrolera. Prawie jak przycisk:)

Spróbuj tak wrzuć taki kawałek kodu. powinno serwo stanąć na 180* i zostać ,,na zawsze"

#include <Servo.h>

Servo myservo;  // tworzy objekt servo do kontroli naszego serwa
                // na większości płytek można stworzyć takich obiektów 12

int pos = 0;    // zmienna do zapamiętania pozycji serwa

void setup()
{
  myservo.attach(9);  // zdefiniowanie do którego portu podłączone jest serwo
}

void loop()
{
  for(pos = 0; pos <= 180; pos += 1) // obrót od 0 do 180 stopni
  {                                  // w krokach co 1 stopień
    myservo.write(pos);              // przekazanie do serwa obrotu o tyle ile jest zapisane w zmiennej 'pos'
    delay(15);                       // poczekaj 15ms, aby serwo osiągnęło ustaloną pozycje
  }

 

 

Jak chcesz zmienic to wgrywasz drugi kawałek. Powinno wrócić i zostać

 

#include <Servo.h>

Servo myservo;  // tworzy objekt servo do kontroli naszego serwa
                // na większości płytek można stworzyć takich obiektów 12

int pos = 180;    // zmienna do zapamiętania pozycji serwa

void setup()
{
  myservo.attach(9);  // zdefiniowanie do którego portu podłączone jest serwo
}

void loop()

{

 for(pos = 180; pos>=0; pos-=1)     // obrót od 180 do 0 stopni
  {                                
    myservo.write(pos);              // przekazanie do serwa obrotu o tyle ile jest zapisane w zmiennej 'pos'
    delay(15);                       // poczekaj 15ms, aby serwo osiągnęło ustaloną pozycje
  }
}

 

To tak łopatologicznie. Odpisz czy działa :) (samo serwo)

Odnośnik do komentarza
Udostępnij na innych stronach

Dobrze zrozumiałeś, tak właśnie sobie wyobrażałem najprostsze rozwiązanie.

Jednak w tych kodach coś nie jest OK, bo serwo przekręca się o około 180 stopni, wraca do pozycji wyjściowej i tak w kółko....

Drugi kod robi to samo, ale na odwrót, w drugą stronę. Chyba tam gdzieś się to zapętla...

Odnośnik do komentarza
Udostępnij na innych stronach

2 minuty temu, AdamK napisał:

Jednak w tych kodach coś nie jest OK, bo serwo przekręca się o około 180 stopni, wraca do pozycji wyjściowej i tak w kółko....

Drugi kod robi to samo, ale na odwrót, w drugą stronę. Chyba tam gdzieś się to zapętla...

dosłownie się zapętla bo kod jest funkcji loop()

wystarczy przenieść jej zawartość i dopisać do setup() a loop() ma być puste (tylko { })

 

na dłuższą metę to nie jest dobre rozwiązanie bo procek można zaprogramować ograniczoną liczbę razy i nie chcemy tego robić przy każdym otwarciu i zamknięciu ale jako prowizorka to niech będzie...

 

Odnośnik do komentarza
Udostępnij na innych stronach

9 minut temu, szuu napisał:

dosłownie się zapętla bo kod jest funkcji loop()

wystarczy przenieść jej zawartość i dopisać do setup() a loop() ma być puste (tylko { })

 

na dłuższą metę to nie jest dobre rozwiązanie bo procek można zaprogramować ograniczoną liczbę razy i nie chcemy tego robić przy każdym otwarciu i zamknięciu ale jako prowizorka to niech będzie...

 

Nie umiem programować Arduino i nie bardzo wiem jak Twoje poprawki wprowadzić do kodu... Pomożesz?

A ile razy można taki procesor programować?

Odnośnik do komentarza
Udostępnij na innych stronach

28 minut temu, astroartur napisał:

Pewnie będziesz musiał za każdym razem chcąc zmienić pozycję maski wgrać od nowa program do mikrokontrolera.

Nie no, to jest bez sensu. Potrzeba programu, który po prostu będzie odczytywał polecenia z portu szeregowego (który masz dostępny poprzez kabel USB) i je wykonywał. Napisałem taki program, ale nie mam jak przetestować. Mam nadzieję, że działa :)

#include <Servo.h>

Servo myservo;  // tworzy objekt servo do kontroli naszego serwa
                // na większości płytek można stworzyć takich obiektów 12

void setup()
{
  Serial.begin(9600);
  Serial.println("Aby otworzyc wyslij \'o\', aby zamknac wyslij \'z\'");
  myservo.attach(9);  // zdefiniowanie do którego portu podłączone jest serwo
}

void loop()
{
  if (Serial.available() > 0)
  {
    char cmd = Serial.read();
    if(cmd == 'o')
    {
      Serial.println("Otwieram");
      for(int pos = 0; pos <= 180; pos += 1) // obrót od 0 do 180 stopni
      {                                  // w krokach co 1 stopień
        myservo.write(pos);              // przekazanie do serwa obrotu o tyle ile jest zapisane w zmiennej 'pos'
        delay(15);                       // poczekaj 15ms, aby serwo osiągnęło ustaloną pozycje
      }
    }
    else if(cmd == 'z')
    {
      Serial.println("Zamykam");
      for(int pos = 180; pos >= 0; pos -= 1)  // obrót od 180 do 0 stopni
      {                                  // w krokach co 1 stopień
        myservo.write(pos);              // przekazanie do serwa obrotu o tyle ile jest zapisane w zmiennej 'pos'
        delay(15);                       // poczekaj 15ms, aby serwo osiągnęło ustaloną pozycje
      }
    }
  }
}

Po wgraniu programu włączasz sobie monitor portu szeregowego (wybierasz prędkość 9600) i wysyłasz "z" lub "o". Możesz też wysyłać te polecenia z innego programu, np https://sites.google.com/site/terminalbpp/, żeby nie musieć za każdym razem uruchamiać arduino ide.

  • Lubię 5
Odnośnik do komentarza
Udostępnij na innych stronach

Do sterowania takim mechanizmem można wykorzystać jeden z dostępnych w sieci projektorów focuserów na Arduino. Są gotowe rozwiązania z aplikacją i sterownikami Ascom. Wystarczy eksperymentalnie dobrać ilość kroków silnika focusera odpowiadającą " założonej masce", a pozycję "0" jako "maska  zaparkowana"

Edytowane przez Piotr4d
  • Lubię 2
Odnośnik do komentarza
Udostępnij na innych stronach

11 minut temu, MateuszW napisał:

Nie no, to jest bez sensu. Potrzeba programu, który po prostu będzie odczytywał polecenia z portu szeregowego (który masz dostępny poprzez kabel USB) i je wykonywał. Napisałem taki program, ale nie mam jak przetestować. Mam nadzieję, że działa :)


#include <Servo.h>

Servo myservo;  // tworzy objekt servo do kontroli naszego serwa
                // na większości płytek można stworzyć takich obiektów 12

void setup()
{
  Serial.begin(9600);
  Serial.println("Aby otworzyc wyslij \'o\', aby zamknac wyslij \'z\'");
  myservo.attach(9);  // zdefiniowanie do którego portu podłączone jest serwo
}

void loop()
{
  if (Serial.available() > 0)
  {
    char cmd = Serial.read();
    if(cmd == 'o')
    {
      Serial.println("Otwieram");
      for(int pos = 0; pos <= 180; pos += 1) // obrót od 0 do 180 stopni
      {                                  // w krokach co 1 stopień
        myservo.write(pos);              // przekazanie do serwa obrotu o tyle ile jest zapisane w zmiennej 'pos'
        delay(15);                       // poczekaj 15ms, aby serwo osiągnęło ustaloną pozycje
      }
    }
    else if(cmd == 'z')
    {
      Serial.println("Zamykam");
      for(int pos = 180; pos >= 0; pos -= 1)  // obrót od 180 do 0 stopni
      {                                  // w krokach co 1 stopień
        myservo.write(pos);              // przekazanie do serwa obrotu o tyle ile jest zapisane w zmiennej 'pos'
        delay(15);                       // poczekaj 15ms, aby serwo osiągnęło ustaloną pozycje
      }
    }
  }
}

Po wgraniu programu włączasz sobie monitor portu szeregowego (wybierasz prędkość 9600) i wysyłasz "z" lub "o". Możesz też wysyłać te polecenia z innego programu, np https://sites.google.com/site/terminalbpp/, żeby nie musieć za każdym razem uruchamiać arduino ide.

Super działa!

Dziękuję Mateusz. trzeba by tylko poprawić coś, bo podczas otwierania przekręca o kąt trochę mniejszy niż 180stopni, o jakies 10-15 mniej. na tomiast podczas zamykania wraca dokładnie do pozycji wyjściowej. Gdzie to można zmienić, to spróbuję dobrać?

Odnośnik do komentarza
Udostępnij na innych stronach

1 minutę temu, AdamK napisał:

Super działa!

Dziękuję Mateusz. trzeba by tylko poprawić coś, bo podczas otwierania przekręca o kąt trochę mniejszy niż 180stopni, o jakies 10-15 mniej. na tomiast podczas zamykania wraca dokładnie do pozycji wyjściowej. Gdzie to można zmienić, to spróbuję dobrać?

Fajnie :) No to musisz zmienić (zwiększyć) te wartości 180, które występują w obu pętlach for. One określają, jaka jest pozycja po otwarciu. A że to się nie zgadza, to wynika już z niskiej dokładności serwa, trzeba to dobrać pod konkretny egzemplarz.

  • Lubię 1
Odnośnik do komentarza
Udostępnij na innych stronach

27 minut temu, Piotr4d napisał:

Do sterowania takim mechanizmem można wykorzystać jeden z dostępnych w sieci projektorów focuserów na Arduino. Są gotowe rozwiązania z aplikacją i sterownikami Ascom. Wystarczy eksperymentalnie dobrać ilość kroków silnika focusera odpowiadającą " założonej masce", a pozycję "0" jako "maska  zaparkowana"

Tego typu focusery mogą sterować serwem? Miałem ostatnio dokładnie taki sam pomysł aby takie coś przez Ascom-a zrobić do flatownicy. Jednak wydaje mi się, że one tylko silnikami krokowymi sterują. Serwo to całkiem inny mechanizm ale jak widać, mimo swoich ograniczeń może się sprawdzić. A sterowanie w sumie banalne.

 

Odnośnik do komentarza
Udostępnij na innych stronach

1 godzinę temu, Piotr4d napisał:

Do sterowania takim mechanizmem można wykorzystać jeden z dostępnych w sieci projektorów focuserów na Arduino. Są gotowe rozwiązania z aplikacją i sterownikami Ascom. Wystarczy eksperymentalnie dobrać ilość kroków silnika focusera odpowiadającą " założonej masce", a pozycję "0" jako "maska  zaparkowana"

Myślę, że musiałbym porzucić koncepcję prostoty rozwiązania. Wolałbym zostać przy serwo. Chyba, że się mylę i to co proponujesz też jest prostym rozwiązaniem

Odnośnik do komentarza
Udostępnij na innych stronach

Dla mnie prostym rozwiązaniem jest właśnie zastosowanie tego co już mam, czyli astrohuba 3.0 by jolo  i podpięcie pod niego jako sacondary focuser silnika krokowego z maską bahtinova na końcu i sterowanie nim z poziomu  dedykowanej doń aplikacji.

Twoje rozwiązanie jest równie ok jak moje.

  • Lubię 1
Odnośnik do komentarza
Udostępnij na innych stronach

Mateusz, bardzo pasuje mi Twoja wersja kodu, jednak jest pewien niepożądany efekt po wgraniu kodu: ramię serwa nagle przeskakuje o 90 stopni, a potem podczas wydawania pierwszej komendy najpierw cofa się o pewien kąt, a dopiero potem przekręca się o 180 do pozycji właściwej. Następne komendy już wykonuje poprawnie. Czy dałoby się jakoś wyeliminować te niepożądane ruchy na początku?

Odnośnik do komentarza
Udostępnij na innych stronach

Czy ktoś pomógłby zmodyfikować program przygotowany przez Mateusza, aby nie powodował niepożądanych ruchów serwa na początku, po włączeniu?

W takiej postaci niestety nie nadaje się do zastosowania, bo na początku macha z dużą szybkością dźwignią w obie strony...

Udało mi się dołączyć krótki film pokazujący ten niepożądany ruch na samym początku. Pomoże mi ktoś to ogarnąć, proszę.

 

Odnośnik do komentarza
Udostępnij na innych stronach

Nie jestem pewien czy to wina programu. 

Kiedyś latałem dużo samolotami RC i na tym samym nadajniku często serwa w modelach się ruszały podczas włączania. W innym modelu się nie ruszały. Różnie bywało. 

Pamiętam że mówiło się, że to się dzieje w tym krótkim okresie jak serwo dostaje napięcie a sygnału jeszcze nie, ale nie wiem ile w tym prawdy.  

Ale wiem że można dokupić takie coś co zwalnia ruchy serwa, np. żeby koła modelu się powoli chowały - o ile to by nie miało takich samych objawów.

Odnośnik do komentarza
Udostępnij na innych stronach

nie, na filmie nie ma żadnych przypadkowych ruchów.

na początku serwo jest w pozycji nazwijmy to "90"

program każe mu zrobić płynny ruch od "0" do "180" więc oczywiście najpierw robi skok do "0" i potem powoli do "180" zgodnie z programem.

nie da się tak po prostu zacząć ruchu od bieżącej pozycji gdy program nie wie jaka to pozycja bo serwo nie moze przekazac mu tej informacji.

w programie mogłoby być "90" zamiast "0" i już nie byłoby skoku przy takiej pozycji początkowej.

dla uniknięcia gwałtownych ruchów program mógłby zapisywać w pamięci nieulotnej na jakiej pozycji ostatnio skończył.

w sumie to wpisywanie "o" i "z" jest niepotrzebną komplikacją i w dodatku mozna sie pomylic wpisując dwa razy pod rząd to samo. może lepsza byłaby cykliczna zmiana między dwoma położeniami wywoływana jednym klawiszem.

 

  • Lubię 1
Odnośnik do komentarza
Udostępnij na innych stronach

a tutaj program który tak własnie robi :)

 

instrukcja obsługi:

- pusty enter przechodzi między dwoma zapamiętanymi pozycjami, nazwijmy je "otwartą" i "zamkniętą" (początkowo 45 i 135). przechodząc pisze do jakiej pozycji (liczbowo) właśnie się przełączyliśmy

- będąc w danej pozycji możemy ją skorygować wpisując liczbę i dopiero potem enter. w ten sposób poprawiamy daną pozycję do skutku aż jest dobrze i dopiero potem pusty enter przechodzi do tej drugiej pozycji którą też można w taki sam sposób ustawić

- ustawione kąty są zapamiętane i przywracane po ponownym włączeniu. o ile nie wyłączymy zasilania w czasie ruchu to zapamiętana będzie też aktualna pozycja tak żeby nie było szarpnięcia na początku

- prędkość ruchu można dostosować zmieniając wartości MAX_DT i MIN_DT

 

#include <Servo.h>
#include <EEPROM.h>

#define SERVO_PIN 9
#define MAX_DT 20   //im wieksza liczba tym wolniejszy poczatek i koniec ruchu
#define MIN_DT 2    //im wieksza liczba tym wolniejsza jest srodkowa najszybsza faza ruchu
#define EEPROM_ID 42

Servo myservo;
byte pozycje[2]={45,135};
byte wybrana=0;

void setup()
{
  Serial.begin(9600);
  if (EEPROM.read(0)==EEPROM_ID) {
    pozycje[0]=EEPROM.read(1);
    pozycje[1]=EEPROM.read(2);
    wybrana=EEPROM.read(3);
    }
  myservo.attach(SERVO_PIN);
  myservo.write(pozycje[wybrana]);
}

int czekaj() //zwraca liczbe >=0 którą odebrano z portu lub zwraca -1 jezeli byl sam enter
{
  String s;
  while (true)
    {
    int b=Serial.read();
    if (b=='\n') {
      if (s.length()>0)
        return s.toInt();
      else
        return -1;
    }    
    else
      if (isdigit(b)) s+=(char)b;
    }
}

byte absdif(byte a,byte b)
{ return (a>b)?(a-b):(b-a); }

byte bmin(byte a,byte b)
{ return a<b?a:b; }

void obracanie(byte p1, byte p2)
{
 Serial.print("obracanie do ");
 Serial.println(p2);
 for (byte p=p1;p!=p2;p=(p2>p1)?(p+1):(p-1)) {
    myservo.write(p);
    byte dt = MAX_DT - bmin(MAX_DT-MIN_DT,bmin(absdif(p,p1),absdif(p,p2)));
    delay(dt);
 } 
 myservo.write(p2);
}

void loop() {
  int liczba=czekaj();
  if (liczba>=0) {  
     Serial.print("zmieniam ");
     obracanie(pozycje[wybrana],liczba);
     pozycje[wybrana]=liczba;
  }
  else {
    Serial.println("enter");
    obracanie(pozycje[wybrana],pozycje[!wybrana]);
    wybrana=!wybrana;
  }
  EEPROM.update(0,EEPROM_ID);
  EEPROM.update(1,pozycje[0]);
  EEPROM.update(2,pozycje[1]);
  EEPROM.update(3,wybrana);
}

 

  • Lubię 2
  • Dziękuję 1
Odnośnik do komentarza
Udostępnij na innych stronach

Wielkie Dzięki @szuu!!! Program jest super i super działa. Właśnie go wypróbowałem na "szybko" i nie zauważyłem żadnych "nerwowych" ruchów.

Zaraz zabieram się aby go zaadoptować do mojego refraktorka. Dam znać jak wyszło, a może uda się wrzucić jakiś filmik...

Jeszcze raz DZIĘKI !

Odnośnik do komentarza
Udostępnij na innych stronach

Taki małe coś, może się komuś przyda.

1. Programik w C, wraz ze źródłami więc można sobie przerobić.

 

Arduino Control.rar

 

2. Szkic na Arduino.

serwo_i_dach.ino

 

Co to robi?

Sterowanie otwieraniem dekielka na teleskopie z poziomu PC. Do wyboru serwo 360' o ruchu ciągłym i po zmianie znaczników komentarza również serwo o ruchu ograniczonym.

Dodatkowo sterowanie otwieraniem dachu ROR przy pomocy silnika DC 12V (np. od wycieraczek) i takiego sterownika: https://elty.pl/pl/p/Sterownik-silnikow-z-BTS7960-mostek-H-43A/1763   (już nie za 60zł :movingtongue:) podpiętego do Arduino.

Wstępnie jest ustawiony port COM4 i do działania konieczne jest podpięcie Arduino, bo nie chciało mi się pisać procedur awaryjnych.

 

Edytowane przez Zywis
  • Lubię 1
Odnośnik do komentarza
Udostępnij na innych stronach

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.

Gość
Dodaj odpowiedź do tematu...

×   Wklejono zawartość z formatowaniem.   Usuń formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Odnośnik został automatycznie osadzony.   Przywróć wyświetlanie jako odnośnik

×   Przywrócono poprzednią zawartość.   Wyczyść edytor

×   Nie możesz bezpośrednio wkleić grafiki. Dodaj lub załącz grafiki z adresu URL.

×
×
  • Dodaj nową pozycję...

Powiadomienie o plikach cookie

Umieściliśmy na Twoim urządzeniu pliki cookie, aby pomóc Ci usprawnić przeglądanie strony. Możesz dostosować ustawienia plików cookie, w przeciwnym wypadku zakładamy, że wyrażasz na to zgodę.