• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Zdalnie sterowany robot na module RF 433 Mhz
#1
Witam.
w najbliższym czasie zamierzam zabrać się za zbudowanie robota, który napędzany będzie jednym silnikiem DC wraz z przekładnią oraz 2 serwami. Do sterowania tymi komponentami użyję Motor Shielda V1 - link- niestety nie posiadam wersji V2, modułu nadajnika i odbiornika radiowego 433 Mhz - link, dwóch Arduino UNO oraz 2 joysticków 5V od PS2.

Z początku chciałem wykorzystać moduł NRF24L01 jednak okazało się, że wykorzystuje on te same piny co motor shield i nie mógł bym wykorzystać silnika DC tylko serwo, co w moim przypadku nie wchodzi w grę, dlatego zdecydowałem się na moduł RF.

Napisanie kodu niestety mnie przerosło, gdyż co tu dużo mówić jestem zielony w tym temacie.
Jeżeli ktoś zna się na tym lepiej niż ja, był bym bardzo wdzięczny za pomoc w modyfikacji kodu czyli:
- zastąpieniu 2 silników DC na 1 silnik(sterowany pierwszym joystickiem) i dodaniu dwóch serv(sterowanych przy pomocy drugiego joysticka)

Nadajnik:

Kod:
#include <VirtualWire.h>
const int transmit_pin = 3; // do tego pinu pin TX nadajnika XY-FST
int joystickPion = A0; // pin joysticka dla pionu
int joystickPoziom=A1; // pin joysticka dla poziomu
int a,b; // zmienne pomocnicze do obliczeń
long X = 0; // zmienna wynikowa, do przetworzenia w wiadomości
char wiadomosc[10]; // wiadomość tekstowa
// ------------------------------------------------------------------------------
void setup()
{
 Serial.begin(9600);
 // konfiguracja nadajnika i protokołu transmisji
 vw_set_tx_pin(transmit_pin);
 vw_set_ptt_inverted(true);
 vw_setup(2000);
}
// -----------------------------------------------------------------------------
void loop() {
// czytamy stan manetek joysticka
 a=analogRead(joystickPion);Serial.println(a);
 b=analogRead(joystickPoziom);Serial.println(b);Serial.println("------");
 X = a+b*1024L; // przetwarzamy stany na liczbę
 ltoa(X, wiadomosc,10);  // zamiana liczby na text do wysłania
 vw_send((uint8_t *)wiadomosc, strlen(wiadomosc));  // wysłanie wiadomości
 vw_wait_tx();                                      // konieczne dla skomunikowania modułów Nad.-Odb.
}

Odbiornik:

Kod:
#include <VirtualWire.h>
// --- piny dla układu L293D ( nie możesz używać pinu nr 3 !!! )------
#define IN1 2   // dla silnika 1 (przód-tył)
#define IN2 4   // dla silnika 1 (przód-tył)
#define EN1 10  // koniecznie pin PWM (~)
#define IN3 6   // dla serwa (lewo-prawo)
#define IN4 7   // dla serwa (lewo-prawo)
#define EN2 11  // koniecznie pin PWM (~)
// --- moce silników -------------------------------------------------
int PWM1;
int PWM2;
// --- zmienne -------------------------------------------------------
char *kierunek; // kierunek ruchu, potrzebne tylko dla Seriala :-)
long X; // stan joysticka XY (przetworzona wiadomość)
// --- dla modułu XY-MK ----------------------------------------------
const int receive_pin = 3; // koniecznie ten pin
char wiadomosc[10]; // odebrana wiadomość
// -------------------------------------------------------------------
void setup()
{
 Serial.begin(9600);
 vw_set_rx_pin(receive_pin); // konfiguracja odbiornika
 vw_set_ptt_inverted(true); // konfiguracja protokołu
 vw_setup(2000);             // konfiguracja protokołu
 vw_rx_start();              // start odbiornika
 
 // --- konfiguracja pinów ------------------------------------------
 pinMode(IN1,OUTPUT);digitalWrite(IN1,LOW);
 pinMode(IN2,OUTPUT);digitalWrite(IN2,LOW);
 pinMode(IN3,OUTPUT);digitalWrite(IN3,LOW);
 pinMode(IN4,OUTPUT);digitalWrite(IN4,LOW);
 pinMode(EN1,OUTPUT);
 pinMode(EN2,OUTPUT);
}
// -------------------------------------------------------------------
void loop()
{
  uint8_t buf[VW_MAX_MESSAGE_LEN]; // definiujemy bufor do odbioru inf.
  uint8_t buflen = VW_MAX_MESSAGE_LEN; // rozmiar bufora
  if (vw_get_message(buf, &buflen)) // pobieramy wiadomość
  {
    int i;
    for (i = 0; i < buflen; i++) // kopiujemy ją do zmiennej wiadomosc
      {
      wiadomosc[i] = char(buf[i]);
      }
   wiadomosc[buflen] = '\0'; // znak końca tekstu
   X = atol(wiadomosc);              // przetwarzamy tekst na liczbę
   PWM1 = (int)(X%1024L); // obliczamy wychylenie w osi Y
   if(PWM1>535){kierunek="do przodu";digitalWrite(IN1,HIGH);digitalWrite(IN2,LOW);PWM1 = map(PWM1,535,1023,0,255);analogWrite(EN1,PWM1);}
   else if(PWM1<505){kierunek="do tylu";digitalWrite(IN1,LOW);digitalWrite(IN2,HIGH);PWM1 = map(PWM1,505,0,0,255);analogWrite(EN1,PWM1);}
   if(PWM1>=505 && PWM1<=535){kierunek=" stop ";PWM1=0;analogWrite(EN1,0);}
   Serial.print("Silnik 1: kierunek: ");Serial.print(kierunek);Serial.print(" moc: ");Serial.println(PWM1);
   PWM2 = int(X/1024L); // obliczamy wychylenie w osi X
   if(PWM2>535){kierunek="w prawo ";digitalWrite(IN3,HIGH);digitalWrite(IN4,LOW);PWM2 = map(PWM2,535,1023,0,255);analogWrite(EN2,PWM2);}
   else if(PWM2<505){kierunek="w lewo";digitalWrite(IN3,LOW);digitalWrite(IN4,HIGH);PWM2 = map(PWM2,505,0,0,255);analogWrite(EN2,PWM2);}
   if(PWM2>=505 && PWM2<=535){kierunek=" stop ";PWM2=0;analogWrite(EN2,0);}
   Serial.print("Silnik 2: kierunek: ");Serial.print(kierunek);Serial.print(" moc: ");Serial.println(PWM2);
   
   Serial.println("--------------------------------------");
  }
}

Z góry chciałbym podziękować za pomoc i poświęcony czas.
 
Odpowiedź
#2
jakiej mocy silniki to ważne
nie wim czy dobrze myślę i morze koledzy mnie  z krytykując ale tak to wysyłać nie możesz musisz wysłać najpierw pion potem poziom bo:
100+100/1024=0,19
i
0+200/1024=0.19
bo to samo i kontroler nie wie czy skręcasz w lewo i masz pul gazu czy jedziesz do prosta i masz prawie cały gaz
ja bym kombinowal tak(nie mam teraz dostępu do odbiornika wiec pisze teoretycznie)

Kod:
int adres=0;
int pion=0;
int poziom=0;
//10=pion, 20=poziom

void loop() {
// czytamy stan manetek joysticka
pion=analogRead(joystickPion);Serial.println(a);
poziom=analogRead(joystickPoziom);Serial.println(b);Serial.println("------");
if(pion<=0  || poziom<=0){//proszę o weryfikacje teko zapisu bo nie jestem pewien czy tak morzna tu ma być jeśli poziom albo pion będzie większy wykonaj funkcje
adres=10;
ltoa(adres, wiadomosc,10);  // zamiana liczby na text do wysłania  - wy miejsce Wiadomości zrobił bym jakiś algorytm kodowania
ltoa(pion, wiadomosc,10);
adres=20;
ltoa(adres, wiadomosc,10);
ltoa(poziom, wiadomosc,10);
}

vw_send((uint8_t *)wiadomosc, strlen(wiadomosc));  // wysłanie wiadomości //nie pamiętam czy to potrzebne
vw_wait_tx();                                      // konieczne dla skomunikowania modułów Nad.-Odb.

nie testowany nie wiem czy działa w tym momencie gotowca nie zrobię

Kod:
wiadomosc[buflen] = '\0'; // znak końca tekstu
 X = atol(wiadomosc);              // przetwarzamy tekst na liczbę
 PWM1 = (int)(X%1024L); // obliczamy wychylenie w osi Y
 if(PWM1>535){kierunek="do przodu";digitalWrite(IN1,HIGH);digitalWrite(IN2,LOW);PWM1 = map(PWM1,535,1023,0,255);analogWrite(EN1,PWM1);}
 else if(PWM1<505){kierunek="do tylu";digitalWrite(IN1,LOW);digitalWrite(IN2,HIGH);PWM1 = map(PWM1,505,0,0,255);analogWrite(EN1,PWM1);}
 if(PWM1>=505 && PWM1<=535){kierunek=" stop ";PWM1=0;analogWrite(EN1,0);}
 Serial.print("Silnik 1: kierunek: ");Serial.print(kierunek);Serial.print(" moc: ");Serial.println(PWM1);
 PWM2 = int(X/1024L); // obliczamy wychylenie w osi X
 if(PWM2>535){kierunek="w prawo ";digitalWrite(IN3,HIGH);digitalWrite(IN4,LOW);PWM2 = map(PWM2,535,1023,0,255);analogWrite(EN2,PWM2);}
 else if(PWM2<505){kierunek="w lewo";digitalWrite(IN3,LOW);digitalWrite(IN4,HIGH);PWM2 = map(PWM2,505,0,0,255);analogWrite(EN2,PWM2);}
 if(PWM2>=505 && PWM2<=535){kierunek=" stop ";PWM2=0;analogWrite(EN2,0);}
 Serial.print("Silnik 2: kierunek: ");Serial.print(kierunek);Serial.print(" moc: ");Serial.println(PWM2);


moja rada nie pisz tak kodu to bałagan pisz linia po lini bo jak zrobisz byka tydzień będziesz szukał zero przejrzystości
masz moze mniej linijek ale wszystko sie zlewa usune ci jeden ; i szukasz 10 min

to dobre jak masz 3k kodu ale jak bedziesz mial 200k kodu
 
Odpowiedź
#3
Niestety nie znam specyfikacji tego silnika, był wymontowany ze starego aparatu fotograficznego. Użyłem go, ponieważ posiada swego rodzaju sprzęgło w postaci sprężynowego docisku zębatki, która w przypadku dużego obciążenia nie powoduje uszkodzenia przekładni z plastikowymi zębami.
Czy bez znajomości parametrów nie da się nic dalej zrobić ?


Dziękuję za pomoc i radę Wink

A co w przypadku serwomechanizmów, ponieważ mam problem z napisaniem tego.
 
Odpowiedź
#4
(01-09-2015, 17:34)Deynox napisał(a): Niestety nie znam specyfikacji tego silnika, był wymontowany ze starego aparatu fotograficznego. Użyłem go, ponieważ posiada swego rodzaju sprzęgło w postaci sprężynowego docisku zębatki, która w przypadku dużego obciążenia nie powoduje uszkodzenia przekładni z plastikowymi zębami.
Czy bez znajomości parametrów nie da się nic dalej zrobić ?


Dziękuję za pomoc i radę Wink

A co w przypadku serwomechanizmów, ponieważ mam problem z napisaniem tego.
da się to silnik malej mocy ten układ go uciągnie jak słyszę robot to mam na myśli silniki o moczy 100w co najmniej
na jakim mikro uc bazujesz

nie wim jakie masz serwa ale te co na allegro są takie małe sterowane są wypełnieniem czyli częstością impulsów na sekund

http://allegro.pl/servo-serwo-tower-pro-...80810.html

kod który napisałem to poglądowy nie jestem wstanie go sprawdzić czy działa poprawnie
 
Odpowiedź
#5
Tak to te serva, robot rzeczywiście to może brzmi zbyt poważnie jednak ma to być pojazd lekki wyposażony w kamerę oraz kilka innych czujników.

Po wgraniu programu otrzymałem takie coś - joystick nie reaguje.


Kod:
0
------
0
0
------
0
0
------
0
0
------
0
0
------
0
0
------
0
0
------
0
0
------
0

Odnośnie serwa to o to chodziło: http://www.micropik.com/PDF/SG90Servo.pdf

Niestety nie jest to mój program, ale ten który podałem wcześniej odczytuje pozycje z joysticka.
Kod:
1023
495
------
957
34
------
514
0
------
513
0
------
360
0
------
0
0
------
0
412
------
0
847
------
152
1023
------
514
1023
------
968
924
------
1023
495
------
983
44
------
513
0
------
514
495
------
514
1023
------
514
1023
------
514
495
------
514
495
------
514
495
------
514
495
 
Odpowiedź
#6
to tak jak ci pisałem podajesz wypełnienie nie pamiętam dokładnie ale w nocie masz opisane ile ms

to twój program tak robi
przeanalizowałem i działa tak jak ci pisałem mój z tym ze wiadomość to właśnie adres i tak rozpoznaje dopiero musiałem twój kod rozłożyć  na
Kod:
#include <VirtualWire.h>
const int transmit_pin = 3; // do tego pinu pin TX nadajnika XY-FST
int joystickPion = A0; // pin joysticka dla pionu
int joystickPoziom=A1; // pin joysticka dla poziomu
int a,b; // zmienne pomocnicze do obliczeń
long X = 0; // zmienna wynikowa, do przetworzenia w wiadomości
char wiadomosc[10]; // wiadomość tekstowa
// ------------------------------------------------------------------------------
void setup()
{
Serial.begin(9600);
// konfiguracja nadajnika i protokołu transmisji
vw_set_tx_pin(transmit_pin);
vw_set_ptt_inverted(true);
vw_setup(2000);
}
// -----------------------------------------------------------------------------
void loop() {
// czytamy stan manetek joysticka
a=analogRead(joystickPion);Serial.println(a);
b=analogRead(joystickPoziom);Serial.println(b);Serial.println("------");
X = a+b*1024L; // przetwarzamy stany na liczbę
ltoa(X, wiadomosc,10);  // zamiana liczby na text do wysłania
vw_send((uint8_t *)wiadomosc, strlen(wiadomosc));  // wysłanie wiadomości
vw_wait_tx();                                      // konieczne dla skomunikowania modułów Nad.-Odb.
}


Odbiornik:

Kod:
Kod:
#include <VirtualWire.h>
// --- piny dla układu L293D ( nie możesz używać pinu nr 3 !!! )------
#define IN1 2   // dla silnika 1 (przód-tył)
#define IN2 4   // dla silnika 1 (przód-tył)
#define EN1 10  // koniecznie pin PWM (~)
#define IN3 6   // dla serwa (lewo-prawo)
#define IN4 7   // dla serwa (lewo-prawo)
#define EN2 11  // koniecznie pin PWM (~)
// --- moce silników -------------------------------------------------
int PWM1;
int PWM2;
// --- zmienne -------------------------------------------------------
char *kierunek; // kierunek ruchu, potrzebne tylko dla Seriala :-)
long X; // stan joysticka XY (przetworzona wiadomość)
// --- dla modułu XY-MK ----------------------------------------------
const int receive_pin = 3; // koniecznie ten pin
char wiadomosc[10]; // odebrana wiadomość
// -------------------------------------------------------------------
void setup()
{
Serial.begin(9600);
vw_set_rx_pin(receive_pin); // konfiguracja odbiornika
vw_set_ptt_inverted(true); // konfiguracja protokołu
vw_setup(2000);             // konfiguracja protokołu
vw_rx_start();              // start odbiornika

// --- konfiguracja pinów ------------------------------------------
pinMode(IN1,OUTPUT);digitalWrite(IN1,LOW);
pinMode(IN2,OUTPUT);digitalWrite(IN2,LOW);
pinMode(IN3,OUTPUT);digitalWrite(IN3,LOW);
pinMode(IN4,OUTPUT);digitalWrite(IN4,LOW);
pinMode(EN1,OUTPUT);
pinMode(EN2,OUTPUT);
}
// -------------------------------------------------------------------
void loop()
{
uint8_t buf[VW_MAX_MESSAGE_LEN]; // definiujemy bufor do odbioru inf.
uint8_t buflen = VW_MAX_MESSAGE_LEN; // rozmiar bufora
if (vw_get_message(buf, &buflen)) // pobieramy wiadomość
{
  int i;
  for (i = 0; i < buflen; i++) // kopiujemy ją do zmiennej wiadomosc
    {
    wiadomosc[i] = char(buf[i]);
    }
 wiadomosc[buflen] = '\0'; // znak końca tekstu
 X = atol(wiadomosc);              // przetwarzamy tekst na liczbę
 PWM1 = (int)(X%1024L); // obliczamy wychylenie w osi Y
 if(PWM1>535){
 kierunek="do przodu";
digitalWrite(IN1,HIGH);
digitalWrite(IN2,LOW);
PWM1 = map(PWM1,535,1023,0,255);
analogWrite(EN1,PWM1);
}
 else
if(PWM1<505){
kierunek="do tylu";
digitalWrite(IN1,LOW);
digitalWrite(IN2,HIGH);
PWM1 = map(PWM1,505,0,0,255);
analogWrite(EN1,PWM1);
}
 if(PWM1>=505 && PWM1<=535){
 kierunek=" stop ";PWM1=0;
 analogWrite(EN1,0);
}
 Serial.print("Silnik 1: kierunek: ");
 Serial.print(kierunek);Serial.print(" moc: ");
 Serial.println(PWM1);
 PWM2 = int(X/1024L); // obliczamy wychylenie w osi X
 if(PWM2>535){
 kierunek="w prawo ";
digitalWrite(IN3,HIGH);
digitalWrite(IN4,LOW);
PWM2 = map(PWM2,535,1023,0,255);
analogWrite(EN2,PWM2);
}
 else
if(PWM2<505){
kierunek="w lewo";
digitalWrite(IN3,LOW);
digitalWrite(IN4,HIGH);
PWM2 = map(PWM2,505,0,0,255);
analogWrite(EN2,PWM2);
}
 if(PWM2>=505 && PWM2<=535){
   kierunek=" stop ";
PWM2=0;analogWrite(EN2,0);
}
 Serial.print("Silnik 2: kierunek: ");
 Serial.print(kierunek);
 Serial.print(" moc: ");
 Serial.println(PWM2);
 
 Serial.println("--------------------------------------");
}
}
 
Odpowiedź
#7
(01-09-2015, 18:28)adix20_20 napisał(a): to tak jak ci pisałem podajesz wypełnienie nie pamiętam dokładnie ale w nocie masz opisane ile ms

to twuj program tak robi

Po wpisaniu Twojego kodu wyskakują 0, chyba że coś źle przeniosłem.

Kod:
#include <VirtualWire.h>
const int transmit_pin = 12; // do tego pinu pin TX nadajnika XY-FST
int joystickPion = A0; // pin joysticka dla pionu
int joystickPoziom = A1; // pin joysticka dla poziomu
int a,b; // zmienne pomocnicze do obliczeń
int adres=0;
int pion=0;
int poziom=0;
//10=pion, 20=poziom
char wiadomosc[10]; // wiadomość tekstowa
// ------------------------------------------------------------------------------
void setup()
{
 Serial.begin(9600);
 // konfiguracja nadajnika i protokołu transmisji
 vw_set_tx_pin(transmit_pin);
 vw_set_ptt_inverted(true);
 vw_setup(2000);
}
// -----------------------------------------------------------------------------
void loop() {
// czytamy stan manetek joysticka
pion=analogRead(joystickPion);Serial.println(a);
poziom=analogRead(joystickPoziom);Serial.println(b);Serial.println("------");
if(pion<=0 || poziom<=0){//proszę o weryfikacje teko zapisu bo nie jestem pewien czy tak morzna tu ma być jeśli poziom albo pion będzie większy wykonaj funkcje
adres=10;
ltoa(adres, wiadomosc,10); // zamiana liczby na text do wysłania - wy miejsce Wiadomości zrobił bym jakiś algorytm kodowania
ltoa(pion, wiadomosc,10);
adres=20;
ltoa(adres, wiadomosc,10);
ltoa(poziom, wiadomosc,10);
}

vw_send((uint8_t *)wiadomosc, strlen(wiadomosc)); // wysłanie wiadomości //nie pamiętam czy to potrzebne
vw_wait_tx(); // konieczne dla skomunikowania modułów Nad.-Odb.
}


Znalazłem jeszcze taki kod: https://gist.github.com/conoro/223035df942b72d2d2f6



Rzeczywiście teraz jest dużo bardziej czytelny.
 
Odpowiedź
#8
nie do końca kod który napisałem morze nie działać nie testowałem go wiec nie wiem jak podaje gotowca to na 100% działa to tylko program pogodowy
poza tym to kod nadajnika teraz potrzeba było by dopisać kod odbiornika mogę napisać i sprawdzisz czy zadziała z mim nadajnikiem

już zrozumiałem działanie tamtego próbuje ci go przerobić i wyrzucić co nie potrzebujesz potem dam ci do sprawdzenia następnie spróbuję ci dorobić serwa
 
Odpowiedź
#9
Ok z góry dzięki za pomoc i chęci Wink
Tak przy okazji mam rozpisane piny dla motor shielda, którego używam:

About pins:

All 6 analog input pins are available. They can also be used as digital pins (pins #14 thru 19)

Digital pin 2, and 13 are not used.

The following pins are in use only if the DC/Stepper noted is in use:

Digital pin 11: DC Motor #1 / Stepper #1 (activation/speed control)

Digital pin 3: DC Motor #2 / Stepper #1 (activation/speed control)

Digital pin 5: DC Motor #3 / Stepper #2 (activation/speed control)

Digital pin 6: DC Motor #4 / Stepper #2 (activation/speed control)

The following pins are in use if any DC/steppers are used

Digital pin 4, 7, 8 and 12 are used to drive the DC/Stepper motors via the 74HC595 serial-to-parallel latch

The following pins are used only if that particular servo is in use:

Digitals pin 9: Servo #1 control

Digital pin 10: Servo #2 control
 
Odpowiedź
#10
Digital pin 4, 7, 8 and 12 are used to drive the DC/Stepper motors via the 74HC595 serial-to-parallel latch
używasz 1 silnika nie 2
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości