Operácie

Dvojosová kolíska na kameru ovládaná joystickom: Rozdiel medzi revíziami

Z SensorWiki

(Dvojosová kolíska na kameru ovládaná joystickom)
(Analýza a opis riešenia)
(18 medziľahlých úprav od rovnakého používateľa nie je zobrazených.)
Riadok 9: Riadok 9:
  
  
[[Obrázok:zllmbz1436799105781.jpg|280px|thumb|center|Model projekta.]]
+
[[Obrázok:Matsibora_a_Fietisov_koliska.jpg|280px|thumb|center|Model projekta.]]
 +
 
 +
== Zadanie ==
 +
Rozhodli sme sa naprogramovať držiak na kameru, ktorý by sa otáčal doľava a doprava a samotná kamera sa pohybovala vertikálne. V našom prípade pôjde o dva typy pohybu a dva programy:
 +
 
 +
1.) keď servopohony nasledujú polohu joysticku a pohybujú sa, kým posúvame joystick.
 +
 
 +
2.)servopohony pohybovať smerom, kam ukazuje joystick, a zostanú tam, kým opäť neposunieme páčku alebo nezmeníme smer.
  
 
'''Literatúra:'''  
 
'''Literatúra:'''  
Riadok 26: Riadok 33:
 
Musíme byť opatrní s joystickom, pretože sú dosť lacné a môže fungovať iba jedna os, čo sa stalo v našom prípade. Na kontrolu osej sme použili terminal PuTTY.
 
Musíme byť opatrní s joystickom, pretože sú dosť lacné a môže fungovať iba jedna os, čo sa stalo v našom prípade. Na kontrolu osej sme použili terminal PuTTY.
  
[[Súbor:джойстик.jpg|280px|thumb|center|Joystik.]]
+
[[Súbor:джойстик.jpg|280px|thumb|left|Joystik.]]
  
 +
[[Súbor:рис8.png|450px|thumb|center|schema Joystika.]]
  
  
Riadok 35: Riadok 43:
  
 
Servomotory majú tri vodiče: GND/VCC/signál, v tomto prípade je napájaný 5V z Arduina, môžme použiť 9V alebo 12V, ale najprv si prečítajme datasheet list servomotora, aby sme poznali podporované napätie. Externý zdroj napájania musí mať spoločnú zem. Mame take charakteristiky motorčekov:                               
 
Servomotory majú tri vodiče: GND/VCC/signál, v tomto prípade je napájaný 5V z Arduina, môžme použiť 9V alebo 12V, ale najprv si prečítajme datasheet list servomotora, aby sme poznali podporované napätie. Externý zdroj napájania musí mať spoločnú zem. Mame take charakteristiky motorčekov:                               
  Napätie: 4V ~ 6V
+
  Napätie: 3V ~ 7.2V
  Rýchlosť: 0,1 s/60 (4,8 V); 0,08 s/60 (6V)
+
  Rýchlosť 0,12 s/60°
Krútiaci moment: 1,8 kg (4,8 V)
+
Točivý moment (@ U=4,8V)1,2 kg.cm
 +
Točivý moment (@ U=6V) 1,6 kg.cm
 
  Uhol natočenia: 180°
 
  Uhol natočenia: 180°
  Hmotnosť: 13,4g
+
  Hmotnosť: 14g
  Rozmery: 23 mm x 12 mm x 29 mm
+
  Rozmery(mm): 22 x 11,5 x 27
[[Súbor:рис4.png|370px|thumb|left|Servomotor.]]
+
[[Súbor:sg90.png|370px|thumb|left|Servomotor.]]
[[Súbor:рис5.png|280px|thumb|center|Schéma zapojenia joystika a servomotorov k Arduino.]]
+
[[Súbor:рис51.png|350px|thumb|center|Schéma zapojenia joystika a servomotorov k Arduino.]]
 +
[[Súbor:ServoAnimation.gif|300px|thumb|center|Servomotor.]]
  
  
Riadok 59: Riadok 69:
  
 
<tabs>
 
<tabs>
<tab name="AVR C-code"><source lang="c++" style="background: LightYellow;">
+
<tab name="AVR C-code(bez návratu polohy kamery)"><source lang="c++" style="background: LightYellow;">
#include <avr/io.h>
 
  
 +
#define F_CPU 16000000UL // Define CPU Frequency()16MHz
 +
#include <avr/io.h> // Include AVR std. library file
 +
#include <stdio.h> // Include std. library file
 +
#include <util/delay.h> // Include Delay header file
 +
       
 +
void ADC_Init() // ADC Initialization function
 +
{
 +
DDRC=0x00; // Make ADC port as input
 +
ADCSRA = 0x87; // Enable ADC, with freq/128
 +
ADMUX = 0x40; // Vref: Avcc, ADC channel: 0
 +
}
 +
 +
int ADC_Read(char channel)
 +
{
 +
ADMUX = 0x40 | (channel & 0x07); // set input channel to read
 +
ADCSRA |= (1<<ADSC); // Start ADC conversion
 +
while (!(ADCSRA & (1<<ADIF)));
 +
/* Wait until end of conversion by polling ADC interrupt flag*/
 +
ADCSRA |= (1<<ADIF); // Clear interrupt flag
 +
_delay_ms(1); // Wait a little bit
 +
return ADCW; // Return ADC word
 +
}
 +
             
 
int main(void)
 
int main(void)
 
{
 
{
   unsigned int measuredValue;
+
   ADC_Init(); // ADC initialize function
 +
  DDRB|=(1<<PB1)|(1<<PB2); // Make OC1A and OC1B pin as output
 +
  TCNT1 = 0; // Set timer1 count zero
 +
  ICR1 = 4999; // Set TOP count for timer1 in ICR1 register //50Hz for 20ms pulse width
  
   while (1)
+
/* Set Fast PWM, TOP in ICR1, Clear OC1A, OC1B on compare match, clk/64 */
 +
  TCCR1A = (1<<WGM11)|(1<<COM1A1)|(1<<COM1B1);
 +
  TCCR1B = (1<<WGM12)|(1<<WGM13)|(1<<CS10)|(1<<CS11);
 +
 
 +
  int c_X = 90 + 512/2; // The value of the initial position
 +
  int c_Y = 90 + 512/2; // The value of the initial position
 +
 
 +
  int ADC_ValueX;
 +
  int ADC_ValueY;
 +
 
 +
  OCR1A = c_X; // motor to the initial position
 +
  OCR1B = c_Y; // motor to the initial position
 +
 
 +
   while(1)
 
   {
 
   {
    /*  relax  */
+
ADC_ValueX = ADC_Read(0); // reading the value from the joystick
 +
ADC_ValueY = ADC_Read(1); // reading the value from the joystick
 +
 +
if(ADC_ValueX >= 715) // when the joystick is tilted from its initial position
 +
{
 +
c_X = c_X +5; // changing the position value
 +
if(c_X >=600) {c_X = 600;} // to stay in the range of 90 - 600
 +
if(c_X <=90) {c_X = 90;} // to stay in the range of 90 - 600
 +
}
 +
if(ADC_ValueX <= 310)
 +
{
 +
c_X = c_X -5;
 +
if(c_X >=600) {c_X = 600;}
 +
if(c_X <=90) {c_X = 90;}
 +
}
 +
if(ADC_ValueY >= 715)
 +
{
 +
c_Y = c_Y +5;
 +
if(c_Y >=600) {c_Y = 600;}
 +
if(c_Y <=90) {c_Y = 90;}
 +
}
 +
    if(ADC_ValueY <= 310)
 +
{
 +
c_Y = c_Y -5;
 +
if(c_Y >=600) {c_Y = 600;}
 +
if(c_Y <=90) {c_Y = 90;}
 +
}
 +
OCR1A = c_X; // setting the motor to a new value
 +
OCR1B = c_Y; // setting the motor to a new value
 +
_delay_ms(16); // wait a bit
 
   }
 
   }
 
 
   return(0);
 
   return(0);
 
}
 
}
  
 
</source></tab>
 
</source></tab>
<tab name="filename.h"><source lang="c++" style="background: LightYellow;">
+
<tab name="AVR C-code(s vrátením polohy kamery)"><source lang="c++" style="background: LightYellow;">
#include <avr/io.h>
+
 
 +
#define F_CPU 16000000UL // Define CPU Frequency()16MHz
 +
#include <avr/io.h> // Include AVR std. library file
 +
#include <stdio.h> // Include std. library file
 +
#include <util/delay.h> // Include Delay header file
 +
       
 +
void ADC_Init() // ADC Initialization function
 +
{
 +
DDRC=0x00; // Make ADC port as input
 +
ADCSRA = 0x87; // Enable ADC, with freq/128
 +
ADMUX = 0x40; // Vref: Avcc, ADC channel: 0
 +
}
 +
int ADC_Read(char channel)
 +
{
 +
ADMUX = 0x40 | (channel & 0x07); // set input channel to read
 +
ADCSRA |= (1<<ADSC); // Start ADC conversion
 +
while (!(ADCSRA & (1<<ADIF)));
 +
/* Wait until end of conversion by polling ADC interrupt flag*/
 +
ADCSRA |= (1<<ADIF); // Clear interrupt flag
 +
_delay_ms(1); // Wait a little bit
 +
return ADCW; // Return ADC word
 +
}
 +
               
 +
int main(void)
 +
{
 +
  ADC_Init(); // ADC initialize function
 +
  DDRB|=(1<<PB1)|(1<<PB2); // Make OC1A and OC1B pin as output
 +
  TCNT1 = 0; // Set timer1 count zero
 +
  ICR1 = 4999; // Set TOP count for timer1 in ICR1 register //50Hz for 20ms pulse width
  
void adc_init(void);                                   // A/D converter initialization
+
/* Set Fast PWM, TOP in ICR1, Clear OC1A, OC1B on compare match, clk/64 */
 +
  TCCR1A = (1<<WGM11)|(1<<COM1A1)|(1<<COM1B1);
 +
  TCCR1B = (1<<WGM12)|(1<<WGM13)|(1<<CS10)|(1<<CS11);
 +
 
 +
  while(1)
 +
  {
 +
OCR1A = 90 + (ADC_Read(0)/2); // Read ADC channel 0 and make count in between 90-600
 +
OCR1B = 90 + (ADC_Read(1)/2); // Read ADC channel 1 and make count in between 90-600
 +
_delay_ms(16); // wait a bit
 +
  } 
 +
  return(0);
 +
}
  
unsigned int adc_read(char a_pin);
 
 
</source></tab>
 
</source></tab>
 
</tabs>
 
</tabs>
Riadok 87: Riadok 201:
  
 
Zdrojový kód: [[Médiá:projektMenoPriezvisko.zip|zdrojaky.zip]]
 
Zdrojový kód: [[Médiá:projektMenoPriezvisko.zip|zdrojaky.zip]]
 
  
 
=== Overenie ===
 
=== Overenie ===

Verzia zo dňa a času 15:38, 10. máj 2024

Záverečný projekt predmetu MIPS / LS2024 - Viacheslav Matsibora a Dmytro Fietisov


Dvojosová kolíska na kameru ovládaná joystickom

Držiak kamery pre servomotory SG90, MG90 a pod. Pohyb namontovanej kamery je možný v dvoch osiach (tzv. pan and tilt držiak kamery). Súčasťou balenia sú 4 kusy plastových komponentov a skrutky s maticami. Pre plnú funkčnosť budeme potrebovať 2 servomotory.

Takže budeme používať dva spôsoby riadenia servopohonmi: prvý, keď servopohony nasledujú polohu joysticku a pohybujú sa, kým posúvame joystick, druhý - servopohony začnú pohybovať smerom, kam ukazuje joystick, a zostanú tam, kým opäť neposunieme páčku alebo nezmeníme smer.


Model projekta.

Zadanie

Rozhodli sme sa naprogramovať držiak na kameru, ktorý by sa otáčal doľava a doprava a samotná kamera sa pohybovala vertikálne. V našom prípade pôjde o dva typy pohybu a dva programy:

1.) keď servopohony nasledujú polohu joysticku a pohybujú sa, kým posúvame joystick.

2.)servopohony pohybovať smerom, kam ukazuje joystick, a zostanú tam, kým opäť neposunieme páčku alebo nezmeníme smer.

Literatúra:


Analýza a opis riešenia

Celý projekt obsahuje dosku Arduino, dvojosový joystick, dve servá sg90, prepojovacie vodiče a samotný držiak kamery.

Použitý joystik má 5 pinov (Vcc, GND, Xaxis, Yaxis a kolík tlačidla). Joystick má 2 centrované potenciometre, pri napájaní produkujú analógový signál a pri použití s ​​Arduino má nasledujúce hodnoty: „0-1023“ a keďže sú v pohotovostnom režime vycentrované, vytvárajú hodnoty okolo „512“ a tlačidlo má digitálny výstup 0/1.

Musíme byť opatrní s joystickom, pretože sú dosť lacné a môže fungovať iba jedna os, čo sa stalo v našom prípade. Na kontrolu osej sme použili terminal PuTTY.

Joystik.
schema Joystika.


Schéma zapojenia joystika k Arduino.

Ďalej budeme hovoriť o servomotoroch.

Servomotory majú tri vodiče: GND/VCC/signál, v tomto prípade je napájaný 5V z Arduina, môžme použiť 9V alebo 12V, ale najprv si prečítajme datasheet list servomotora, aby sme poznali podporované napätie. Externý zdroj napájania musí mať spoločnú zem. Mame take charakteristiky motorčekov:

Napätie: 3V ~ 7.2V
Rýchlosť 0,12 s/60°
Točivý moment (@ U=4,8V)1,2 kg.cm
Točivý moment (@ U=6V) 1,6 kg.cm
Uhol natočenia: 180°
Hmotnosť: 14g
Rozmery(mm): 22 x 11,5 x 27
Servomotor.
Schéma zapojenia joystika a servomotorov k Arduino.
Servomotor.






Algoritmus a program

Algoritmus programu je....


#define F_CPU 16000000UL	// Define CPU Frequency()16MHz
#include <avr/io.h>		// Include AVR std. library file
#include <stdio.h>		// Include std. library file
#include <util/delay.h>		// Include Delay header file
        
void ADC_Init()			// ADC Initialization function
{
	DDRC=0x00;		// Make ADC port as input
	ADCSRA = 0x87;		// Enable ADC, with freq/128
	ADMUX = 0x40;		// Vref: Avcc, ADC channel: 0
}

int ADC_Read(char channel)
{
	ADMUX = 0x40 | (channel & 0x07);	// set input channel to read
	ADCSRA |= (1<<ADSC);			// Start ADC conversion 
	while (!(ADCSRA & (1<<ADIF)));
			/* Wait until end of conversion by polling ADC interrupt flag*/
	ADCSRA |= (1<<ADIF);			// Clear interrupt flag
	_delay_ms(1);				// Wait a little bit 
	return ADCW;				// Return ADC word
}
              
int main(void)
{
  ADC_Init();					// ADC initialize function
  DDRB|=(1<<PB1)|(1<<PB2);			// Make OC1A and OC1B pin as output
  TCNT1 = 0;					// Set timer1 count zero
  ICR1 = 4999;					// Set TOP count for timer1 in ICR1 register //50Hz for 20ms pulse width

	/* Set Fast PWM, TOP in ICR1, Clear OC1A, OC1B on compare match, clk/64 */
  TCCR1A = (1<<WGM11)|(1<<COM1A1)|(1<<COM1B1);
  TCCR1B = (1<<WGM12)|(1<<WGM13)|(1<<CS10)|(1<<CS11);
  
  int c_X = 90 + 512/2; 	// The value of the initial position
  int c_Y = 90 + 512/2;		// The value of the initial position

  int ADC_ValueX; 
  int ADC_ValueY;
  
  OCR1A = c_X;			// motor to the initial position
  OCR1B = c_Y;			// motor to the initial position
  
  while(1)
  {
	 ADC_ValueX = ADC_Read(0);	// reading the value from the joystick
	 ADC_ValueY = ADC_Read(1);	// reading the value from the joystick
	 
	 if(ADC_ValueX >= 715)			// when the joystick is tilted from its initial position	
	 {
		c_X = c_X +5;			// changing the position value
		if(c_X >=600)	{c_X = 600;}	// to stay in the range of 90 - 600
		if(c_X <=90)	{c_X = 90;}	// to stay in the range of 90 - 600
	 }
	 if(ADC_ValueX <= 310)
	 {
		c_X = c_X -5;
		if(c_X >=600)	{c_X = 600;}
		if(c_X <=90)	{c_X = 90;}
	 }
	 if(ADC_ValueY >= 715)
	 {
		c_Y = c_Y +5;
		if(c_Y >=600)	{c_Y = 600;}
		if(c_Y <=90)	{c_Y = 90;}
	 }
     if(ADC_ValueY <= 310)
	 {
		c_Y = c_Y -5;
		if(c_Y >=600)	{c_Y = 600;}
		if(c_Y <=90)	{c_Y = 90;}
	 } 
	 OCR1A = c_X;		// setting the motor to a new value
	 OCR1B = c_Y;		// setting the motor to a new value
	 _delay_ms(16);		// wait a bit
  }
  return(0);
}
#define F_CPU 16000000UL	// Define CPU Frequency()16MHz
#include <avr/io.h>		// Include AVR std. library file
#include <stdio.h>		// Include std. library file
#include <util/delay.h>		// Include Delay header file
        
void ADC_Init()				// ADC Initialization function
{
	DDRC=0x00;			// Make ADC port as input
	ADCSRA = 0x87;			// Enable ADC, with freq/128
	ADMUX = 0x40;			// Vref: Avcc, ADC channel: 0
}
int ADC_Read(char channel)
{
	ADMUX = 0x40 | (channel & 0x07);	// set input channel to read
	ADCSRA |= (1<<ADSC);			// Start ADC conversion 
	while (!(ADCSRA & (1<<ADIF)));
			/* Wait until end of conversion by polling ADC interrupt flag*/
	ADCSRA |= (1<<ADIF);			// Clear interrupt flag
	_delay_ms(1);				// Wait a little bit 
	return ADCW;				// Return ADC word
}
                 
int main(void)
{
  ADC_Init();				// ADC initialize function
  DDRB|=(1<<PB1)|(1<<PB2);		// Make OC1A and OC1B pin as output
  TCNT1 = 0;				// Set timer1 count zero
  ICR1 = 4999;				// Set TOP count for timer1 in ICR1 register //50Hz for 20ms pulse width

	/* Set Fast PWM, TOP in ICR1, Clear OC1A, OC1B on compare match, clk/64 */
  TCCR1A = (1<<WGM11)|(1<<COM1A1)|(1<<COM1B1);
  TCCR1B = (1<<WGM12)|(1<<WGM13)|(1<<CS10)|(1<<CS11);

  while(1)
  {
	 OCR1A = 90 + (ADC_Read(0)/2);	// Read ADC channel 0 and make count in between 90-600
	 OCR1B = 90 + (ADC_Read(1)/2);	// Read ADC channel 1 and make count in between 90-600
	 _delay_ms(16);			// wait a bit
  }  
  return(0);
}

Pridajte sem aj zbalený kompletný projekt, napríklad takto (použite jednoznačné pomenovanie, nemôžeme mať na serveri 10x zdrojaky.zip:

Zdrojový kód: zdrojaky.zip

Overenie

Všetko sme spojili, ako je popísané vyššie. Pomocou Datasheetu sme skontrolovali napäťové charakteristiky našich dielov a vyšlo toto:

Aplikácia.

V jednom prípade polohy servopohonov nasledujú polohu joysticku a pohybujú sa, kým posúvame joystick, druhý - servopohony posúvať smerom, kam ukazuje joystick, a zostanú tam, kým opäť neposunieme páčku alebo nezmeníme smer .

Aplikácia.

Video:

Kľúčové slová 'Category', ktoré sú na konci stránky nemeňte.