Pomoc przy pracy - komunikacja z Arduino

0

Witam, wszystkich jestem w trakcie pisania i tworzenia projektu na pracę inżynierską. Buduję skaner 3D oparty jest na znanym projekcie z tej stronki https://github.com/Sardau/Sardauscan . Części zaprojektowałem i wydrukowałem sam plus dodałem pewną funkcjonalność, która polega na tym że jest jeszcze jeden dodatkowy silnik który ma przyblizać bądz oddalać stolik ze skanowanym obiektem. I tu się zaczyna problem z jakim się zwracam do was. Nie wiem jak w programie napisanym w C# dodać taką komunikację z Arduino. Po odpaleniu programu w Visual Studio w zakładce calibrate ->dimension można podać odległość stolika od kamery. Chciałbym żeby po wpisaniu wartości stolik zaczął się przybliżać, bądź oddalać. Tak jak mówiłem konstrukcyjnie mam to rozwiązane i w arduino firmware też dodałem obsługę nowego silnika tylko tu też nie jestem pewien czy poprawnie.Jeżeli jest mi ktoś w stanie tutaj pomóc, to z góry dziękuję i czekam na konstruktywne odpowiedzi i pytania.
Pozdrawiam, Konrad.

3

Z tego co kojarzę, to Arduino ma USB, przez które podpinasz je do kompa. Na tym USB jest odpalona emulacja RS, więc po prostu otwierasz sobie w swojej aplikacji port COM i poprzez niego masz komunikację z Arduino.

Do poczytania:
https://medium.com/@araffin/simple-and-robust-computer-arduino-serial-communication-f91b95596788
https://www.instructables.com/id/C-Serial-Communication-With-Arduino/
oraz na wszelki wypadek coś po polsku:
https://forbot.pl/blog/kurs-arduino-uart-komunikacja-z-komputerem-pc-zmienne-id3836

A jeśli chodziło Ci o coś innego, to napisz jeszcze raz (ale trochę dokładniej) w czym jest problem ;)

0

Tak tylko tutaj chodzi aby oprogrowanie zewnętrzne się komunikowało. W linku który wysłałem jest program. Jest otwarty można go dowolnie przerabiać w Visual Studio. Tylko że ja tego nie rozumiem, w jaki sposób i gdzie są te komendy ukryte. Nic nie muszę wymyślać od nowa wystarczy to powielić dla drugiego silnika i umieścić w innym miejscu w interfejsie.

0

Skąd jesteś? Z ciekawości - po co robisz ten skaner? Moze byśmy mogli się dogadać, na modyfikacje tego programu.

0

Wysyłam to co do tej pory udało mi się zrobić. Na zdjęciu pokazałem o co chodzi myślę że w miarę jasno.

0

A jaki masz silnik do ustawiania odległości? Więcej szczegółów mechanicznych - zębatka, pasek, prowadnica? Z tym podawaniem odległości jest taki problem, że silnik musiałby wiedzieć w jakiej pozycji się znajduje (enkoder), i do tego musiałby się na początku referować (znaleźć swoje 0). Zapewne masz silnik krokowy, więc musisz przeliczyć ile kroków to Twój milimetr lub centymetr, ale i tak na początku musisz się zbazować. Może łatwiej byłoby zrobić +, - wymiar zamiast go podawać. I ewentualnie pomiar odległości (w standardowym zestawie arduino jest moduł pomiaru odległości). Jak będę przy laptopie to rzucę okiem na kod, bo na telefonie niewygodnie.

0

A więc tak silnik to popularny chińczyk 28BYJ-48 z ULN2003. Posów stolika jest zrealizowany na szpilce 5mm jeden pełny obrót to zmiana odległość o 1mm, sprawdzałem 6-krotnie w tym samym kierunku. W drugą stronę luz na nakrętce powoduje zgubienie jednego obrotu czyli ten 1mm, później wszystko odbywa się dokładnie tak samo czyli co 1mm. Silnik potrzebuje 4096 kroków na jeden pełny obrót. Enkoder czy krańcówka zerująca nie są tu konieczne moim zdaniem. Ta funkcja będzie ustawiana niezwykle rzadko. podczas skanu się nie zmienia a program musi pamiętać tylko wpisaną wartość, na tą chwile pamięta po ponownym włączeniu programu, tylko tak jak pisałem nie steruje to silnikiem w żaden sposób, bo to to nie jest zaprogramowane.

1

Nie wiem jaka duża dokładność jest potrzebna, bez bazowania musisz założyć, że nikt ręcznie nie przestawi stołu. Ja bym dodał małą krańcóweczkę i w aplikacji przycisk do bazowania po uruchomieniu.
Więc tak, w pliku "SardauscanHardwareProxy.cs" masz obsługę komunikacji z arduino. Metoda "SendCommand" wysyła poprzez serial stringa z poleceniem. Musisz sobie doprogramować nową komendę wysyłaną podczas zmieniania odległości i obsłużyć ja po stronie arduino (pisałeś już chyba, że masz zrobione).

W pliku z arduino masz jak wyglądają polecenia:

laser :
L => ask laser configuration => response number of lasers
L x => ask status of laser index X
      => 'x' laser number
L x y  => turn laser on or off 
    'x' laser number
    'y' state: 0=off 1=on

Table :
T => table position
T S => return the number of steps for a revolution 
T C => Set Current position as 0 (for absolute positionning
T R xxx => rotate relatively xxx steps 
T A xxx => turn position absolute xxx steps
0

Znalazłem to o czym mówiłeś, troche mi się rozjaśniło w arduino mam tak :


AccelStepper stepper2(HALFSTEP, motorPin5, motorPin6, motorPin7, motorPin8);


SerialCommand SCme;

int LenghtToSteps(int lenght)
{
  return lenght*STEP_BY_MINMOVE;
}
int StepsToLenght(int leng)
{
  return leng/STEP_BY_MINMOVE;
}
void Identification2()
{
  Serial.println("yes");
}
void Hun2()
{
  Serial.println("Hun?");
}
void TableCommand2()
{
   char *arg; 
   arg = SCmd.next(); 
   if (arg != NULL) 
   {
     if(arg[0]=='R'||arg[0]=='r') // T R
     {
                    char *arg2 = SCme.next(); 
                    int pos=atoi(arg2);
                    stepper2.move(RotationToSteps(pos));
                    stepper2.runToPosition();
        Serial.print("RELATIVE ROTATION :"); 
        Serial.print(pos); 
        Serial.print(" => "); 
        Serial.println(StepsToRotation(stepper2.currentPosition())); 
     }
     else if(arg[0]=='A'||arg[0]=='a') // T A
     {
                    char *arg2 = SCme.next(); 
                    int pos=atoi(arg2);
                    stepper2.moveTo(LenghtToSteps(pos));
                    stepper2.runToPosition();
        Serial.print("ABSOLUTE ROTATION "); 
        Serial.print(pos); 
        Serial.print(" => "); 
        Serial.println(StepsToLenght(stepper2.currentPosition())); 
     }
     else if(arg[0]=='S'||arg[0]=='s') //T S
                  {
        Serial.print("REVOLUTION STEPS "); 
        Serial.print(" => "); 
        Serial.println(StepsToLenght(REVOLUTION_STEP)); 
                  }
     else if(arg[0]=='C' ||arg[0]=='c') //T C
                  {
                    stepper2.setCurrentPosition(0);
        Serial.print("RESET CUTTENT POSITION "); 
        Serial.print(" => "); 
        Serial.println(StepsToLenght(stepper2.currentPosition())); 
                  }
                 else
                 {
        Serial.print("Unknown Table command :"); 
        Serial.println(arg); 
                 }
   } 
  else {
     Serial.print("Position "); 
    Serial.println(StepsToLenght(stepper2.currentPosition())); 
  }
}
0

Nie zrobię tego, ten kod jest dla mnie zbyt skomplikowany , nie rozumiem go, może lepiej dodam przyciski fizyczne. Znalazłem funkcje odpowiedzialne za rotację ale są dla mnie kompletnie nie jasne. Tak jakby czegoś brakowało. Jest ktoś w stanie pomóc ?

0

Ciut skomlikowane zależy dla kogo. :P Nie lepiej dorzucać, ta funkcja nie będzie często wykorzystywana i nie musi być dokładna. Wpadłem jeszcze na jeden pomysł wrzucę kod zaraz. Największy problem dla mnie to napisać stringa w Visual tak żeby zmiana w zakładce dimension była realizowana przez silnik krokowy. Spróbuję podeść do tego trochę inaczej jeszcze.

0

Skompilowałem i wgrałem jeszcze taki firmware ale powoduje zawiesznie i błąd łączności po serialu.

0

Przekombinowałeś. Metodę Loop z pliku arduino zostaw w spokoju tak jak była.
Całą obsługę komend masz w metodzie TableCommand (przesuwanie też dotyczy stołu).
Opis komend z pliku:
Table :
T => table position
T S => return the number of steps for a revolution
T C => Set Current position as 0 (for absolute positionning
T R xxx => rotate relatively xxx steps
T A xxx => turn position absolute xxx steps

Więc dodajesz sobie opis, żebyś pamiętał, np. "T M xxx => move position xxx"
I zgodnie z opisem obsługujesz tę komendę w metodzie TableCommand, czyli jak masz coś takiego dla komendy z literą "R":

if(arg[0]=='R'||arg[0]=='r') // T R

to dodajesz obsługę komendy z literą "M" i dalej co ma zrobić, czyli:

stepper2.move(DistanceToSteps);
stepper2.runToPosition(); 

W C# natomiast, najlepiej jakbyś dodał jakiś przycisk "MOVE" (żeby nie jechał co krok jak będziesz zmieniał dystans w numericUpDown) i dodaj do zdarzenia kliknięcia wysyłanie komendy do arduino:

SendCommand(string.Format("T {0} {1}", "M", distance), timeout);
0

Dzięki za odpowiedź, wszystko ok, wyjaśniłeś znowu. Ale coś mi się wydaje że moje umiejętności programistyczne nie pozwolą na skończenie tego. A szkoda bo nie wydaje mi się,że to może być coś skomplikowanego, no bo przecież będzie to uruchamiane tylko i wyłącznie przeze mnie. Mnie TC nie jest potrzebne np. TS też nie Mam taki kod teraz zaznaczyłem co i jak ale dalej nie działa. Chodź program się już nie zawiesza zawsze przy stararcie jedna dioda przy sterowniku się zaświeca. Przy tym drugim sterowniku dioda już się nie świeci, czyli z obsługą jest coś nie tak.

0
Konrad K napisał(a):

Ale coś mi się wydaje że moje umiejętności programistyczne nie pozwolą na skończenie tego.

Wymówka!

Przecież jak nie skończysz tego w tym roku, to skończysz za 3 lata i obronisz pracę z umiejętnościami wymaganymi od inżyniera, bo będziesz już miał odpowiednie umiejętności programistyczne.

Sam siebie ograniczasz...

0

Jakoś nie bardzo poszedłem w tym kierunku, wymówka, po prostu nie każdy musi być programistą. Podchodzilem do tego tematu wielokrotnie. Rozwijam się głównie w innym kierunku

0

No nie musi, masz rację. Ale napisz wprost, że Ci się nie chce, a nie że to jest za dużo dla Ciebie :p

0

Ja wszystko rozumiem, napisałem tutaj na forom, w sprawie pomocy i szanuję każdy post, nie mniej jednak najbardziej te w których jest ona widoczna. Jak na razie tylko jedna osoba odpisuje coś sensownego w sprawie kodu. Jeśli macie dla mnie jakieś wskazówki to bardzo proszę.

0

Skoro niepotrzebne Ci TS ani TC to wstaw tam swój kod i zamień na M, ponieważ dodałeś nowego ifa za ostatnim elsem, więc nie ma szans się wykonać. Uważaj na literówki, masz np.

 if(arg[1]=='M'||arg[1]=='r') //TM

Albo m albo r?
Czy Ty masz 2 sterowniki? Napisałeś, że dioda na drugim się nie zapala.
Najlepiej nie zmieniaj za dużo oryginalnego kodu, nawet jak czegoś nie potrzebujesz. Zamień sobie tylko TC na TM, dodaj w C# wywoływanie SendCommand przy zmianie dystansu. Zobacz jak się będzie zachowywał silnik jak będziesz mu zadawał jakieś kroki i dopasuj to do wymagań. Niech się zacznie w ogóle przesuwać na razie to już będzie sukces.
Kod Ci się kompiluje i wgrywa poprawnie?

0

W oryginale był jeden sterownik. Podłączając arduino do komputera sterownik zaświeca jedną z diód, co oznacza że silnik trzyma krok (pozycjonuje się). Teraz dodałem drugi, przy drugim sterowniku dioda się nie świeci, czyli nie ma napisanej lub nie działa ta procedura, program się kompiluje i wgrywa poprawnie. Stolik się obraca można nim sterować przez aplikację ale drugi silnik nie wykazuje znaku, najprawdopodobniej przez tą instrukcję która jest wstawiona w nieodpowiedni sposób. Czyli sugerujesz żebym przerobił kod tak dla pierwsze silnia by sterował przysuwaniem a dopiero później dograł to co już było ?

1 użytkowników online, w tym zalogowanych: 0, gości: 1