Skocz do zawartości

Budowa prostej aparatury RC


Mieciu11

Rekomendowane odpowiedzi

Witam,

Ostatnio bardzo mocno zainteresował mnie temat budowy a właściwie złożenia jak najniższym kosztem aparatury, która z powodzeniem miałaby być używana w sterowaniu kołowymi modelami rc. Projekt będzie oparty na fabrycznym module nadawczym turnigy 9x, który od jakiegoś czasu leży u mnie bezczynnie. Głównym zadaniem jest wygenerowanie sygnału ppm wszystkich kanałów i sterowanie każdym z nich odpowiednim czasem trwania impulsu od 1 do 2milisekund(minimalne i maksymalne wychylenie serwa). Idealnie nadaje się do tego arduino w moim przypadku nano które na aliexpress można zdobyć za około 7zł. Najtrudniejszym jest napisanie programu, który to wszystko obsłuży, więc na razie wykorzystam kod który można znaleźć w sieci. Być może jak trochę przysiądę do programowania to uda się coś takiego napisać  :) Niestety twórca nie przewidział w kodzie trymerów ani rewersów, więc pozostanie tylko zewnętrznie wpływać na działanie kanałów. Rewers można uzyskać np prostym przełącznikiem zmiany kierunku obrotów silnika, który będzie przełączał na potencjometrze 5v oraz GND. Nie mam jednak pomysłu jak rozwiązać problem trymowania.

 

W kodzie autor przewidział sterowanie sześcioma kanałami. Potencjometry do nich będą podpięte do wejść arduino a0-a5, natomiast sygnał ppm wychodzi z pinu cyfrowego D13 wprost do modułu. Podłączenie tak jak na schemacie. Dziś pierwsze próby i wszystko ładnie działa.  :D cdn.

Wątek, z którego zaczerpnąłem kod: https://www.rcgroups.com/forums/showthread.php?2037080-DIY-Arduino-joystick-to-PPM

post-14366-0-68351900-1513372932_thumb.jpg

 

Kod:

#define NB_WAY 6 // number of ways
#define LOW_LENGTH 300 // How long last (in µs) a low between 2 pulses
#define MIN_PPM_PULSE 600 // minimum pulse length in µs
#define PPM_PULSE_LENGTH 1200 // how much more µs will last the max pulse length
#define PACKET_LENGTH 20000 // How long (µs) last a full trame
 
// trame length is fixed ! Every trame will make PACKET_LENGTH µs !
// MUST NO BE MORE THAN 32ms !!! (timer's prescaler constraint)
 
#define PPM_OUTPUT 13 // OUTPUT PIN
 
int way_value[NB_WAY];
int way_pin[NB_WAY];
int way_min[NB_WAY];
int way_max[NB_WAY];
 
int i = 0;
int p = 0; // temp var for duty cycle calculation
int last_i_timer = 0; // last way's value sent through PPM signal
unsigned long int trame_elapsed_time = 0;
bool output_state = LOW;
 
void setup() {
  // ppm output :
  pinMode(PPM_OUTPUT, OUTPUT);
  digitalWrite(PPM_OUTPUT, output_state);
  
  // inits arrays
  for(i=0;i<NB_WAY;i++)
  {
    way_pin = 14 + i;
    pinMode(way_pin, INPUT);
    way_value = analogRead(way_pin);
    way_min = way_value;
    way_max = way_value;
  }
 
  // init timer
  cli();          // desactivation interruptions
  TCCR1A = 0x00;  // set timer1 registers to 0
  TCCR1B = 0x00;     
  TIMSK1 = 0x00;
    
  OCR1A = 65535;// set to the max
    // CTC mode:
  TCCR1B |= (1 << WGM12);
    // prescaler to 8, that allow (@16mhz) 32.8ms trame
  TCCR1B |= (0 << CS10);
  TCCR1B |= (1 << CS11);
  TCCR1B |= (0 << CS12);
    // timer activation
  TIMSK1 |= (1 << OCIE1A);
  sei();
  for(i=0;i<NB_WAY;i++)
  {
    way_min = 512;
    way_max = 1023;
  }
}
 
ISR(TIMER1_COMPA_vect)
{
  TIMSK1 &= (0 << OCIE1A);
  if(output_state)
  { // END OF A HIGH, we have to wait LOW_LENGTH ms before next pulse 
    output_state = LOW;
    digitalWrite(PPM_OUTPUT, output_state);
    OCR1A = 2 * LOW_LENGTH; // set when next timer interruption will occur
    TIMSK1 |= (1 << OCIE1A);  // restart timer
    trame_elapsed_time += LOW_LENGTH;
  }
  else
  { // END of a LOW_LENGTH, new pulse !
    output_state = HIGH;
    digitalWrite(PPM_OUTPUT, output_state);
    if(last_i_timer >= NB_WAY) // last way, so wait until next packet
    {
      OCR1A = (2 * PACKET_LENGTH) - (trame_elapsed_time * 2);// set when next timer interruption will occur
      TIMSK1 |= (1 << OCIE1A); // restart timer
      last_i_timer = 0;
      trame_elapsed_time = 0; 
    }
    else
    {
      OCR1A = 2 * way_value[last_i_timer];// set when next timer interruption will occur
      TIMSK1 |= (1 << OCIE1A); // restart timer
      last_i_timer ++;
      trame_elapsed_time += way_value[NB_WAY];
    }
  }  
}
 
 
void loop() {
 
  for(i=0;i<NB_WAY;i++)
  {
     // Read current value of way i :
     p = analogRead(way_pin);
     
     // auto calibration...
     if(p > way_max) way_max = p;
     if(p < way_min) way_min = p;
     
     // Arduino map function sucks
      way_value = MIN_PPM_PULSE + PPM_PULSE_LENGTH * (float)((float)(p - way_min) / (float)(way_max - way_min));
  }
}
Odnośnik do komentarza
Udostępnij na innych stronach

To forum raczej dla modelarzy a nie elektroników i informatyków (ale nie kasują tzn że jest OK) :)
Choć czasem coś sie tu pokazuje.

Ja też coś buduję, ale jeszcze mi to zejdzie bo zmieniam architekturę z AVR na ARM. I mój projekt ma być dużo bardziej rozbudowany.

Jeśli dam radę to z chęcią pomogę, ale od razu mówię że jak chcesz mieć konkret do czeka Cię dużo pracy i z kodem i z elektroniką.

 

Na wstępie Ci mogę powiedzieć że twój kod będzie szalał :D

Tzn, musisz mieć filtry RC do potencjometrów i w kodzie ustabilizować odczyt. bo na 100% wszystko będzie skakać :) To jest norma.

 

Trymery, no cóż są dwa rozwiązania:

1. Używasz innych kanałów ADC do trymowania, ale wtedy masz dwa razy mniej kanałów, z 6 schodzisz na 3. Lepiej z 8 na 4.

2. Używasz mechanicznych trymerow, chyba najlepsze rozwiązanie.

3*) Na pewno bedziesz potrzebowal trymerow? 

 

Rewersy? Możesz użyć przełączników i podpiąć do innych pinów, w zależności od stanu, zmieniasz wartość na wyjściu PPM.

 

Mnie się udało wysterować FRSY XJT, póki co tylko PPM, może uda się wskoczyć na PXX. Albo coś nowszego.

 

Kolejna sprawa, nie używaj bibliotek arduino. Osobiście uważam że przy dużych projektach są mega nie optymalne. Oczywiście ostateczny wybór pozostawiam Tobie.

Wydajność AVR. Uważaj na bolączki arch AVR. Dzielenie zajmuje kupę czasu. Póki co ten kod jest prosty, może nie odbije się bardzo na efekcie końcowym, ale musisz o tym wiedzieć.

 

Pozdro i powodzenia!

Odnośnik do komentarza
Udostępnij na innych stronach

  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • 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ę.