Ostatnio oprogramowałem sobie aparaturę RC dwukanałową proporcjonalną .
Zasada działania :
Wysyła 4 paczki 8 bitowe niosące informacje o synchronizacji, wybranym potku/serwie, o nastawie potka/serwa, sumę sprawdzającą adres i nastawę potka/serwa
Problem zaczyna się w momencie zaniku sygnału na wejściu odbiornika ... Z założenia odbiornik powinien od razu ustawić serwa w pozycji 90 stopni (robi to dopiero po kilku sekundach od zaniku sygnału)
W sytuacji odwrotnej kiedy w nadajniku zmienię kod a dokładniej adres potka na nieistniejący to wszystko działa poprawnie .
Wniosek z tego taki że przy błędnym sygnale z nadajnika wszystko działa a przy jego braku działa z dużym opóźnieniem ...
Czy może mnie ktoś naprowadzić ??
Fragment odpowiedzialny za ustawienie serw w pozycji 90 stopni
Maziu
Zasada działania :
Wysyła 4 paczki 8 bitowe niosące informacje o synchronizacji, wybranym potku/serwie, o nastawie potka/serwa, sumę sprawdzającą adres i nastawę potka/serwa
Problem zaczyna się w momencie zaniku sygnału na wejściu odbiornika ... Z założenia odbiornik powinien od razu ustawić serwa w pozycji 90 stopni (robi to dopiero po kilku sekundach od zaniku sygnału)
W sytuacji odwrotnej kiedy w nadajniku zmienię kod a dokładniej adres potka na nieistniejący to wszystko działa poprawnie .
Wniosek z tego taki że przy błędnym sygnale z nadajnika wszystko działa a przy jego braku działa z dużym opóźnieniem ...
Czy może mnie ktoś naprowadzić ??
//********************************************************************************
// NADAJNIK
// UART
//********************************************************************************
#include <avr/io.h> // wejścia wyjścia
#include <util/delay.h>
#ifndef F_CPU
#define F_CPU 8000000 // częstotliwość zegara w Hz
#endif
#define BAUDRATE 1200 // prędkość transmisji
#define UBRRVAL ((F_CPU/(BAUDRATE*16UL))-1)
#define SYNC 0xAA // sygnał synchronizacji 8bitów
//********************************************************************************
// INICJOWANIE UsART
//********************************************************************************
void USART(void)
{
UBRRL = (uint8_t)UBRRVAL; // ustawienie prędkości transmisji
UBRRH = (UBRRVAL>>8);
UCSRC = (1<<URSEL)|
(0<<UMSEL)|
(0<<UPM1) |
(0<<UPM0) | // ustawienie formatu ramki
(0<<USBS) | // 8bitów danych, 1bit stopu, brak synchronizacji
(0<<UCSZ2)|
(1<<UCSZ1)|
(1<<UCSZ0);
UCSRB = (1<<TXEN); // włączenie nadajnika i odbiornika
}
//********************************************************************************
void USART_vSendByte(uint8_t u8Data)
{
while((UCSRA&(1<<UDRE)) == 0);
UDR = u8Data;
}
void Send_Packet(uint8_t addr, uint8_t cmd)
{
USART_vSendByte(SYNC); // synchronizacja 8bit
USART_vSendByte(addr); // adres 8bit
USART_vSendByte(cmd); // dane 8bit
USART_vSendByte((addr+cmd)); // suma adresu i danych 8bit
}
void delayms(uint8_t t) //delay in ms
{
uint8_t i;
for(i=0;i<t;i++)
_delay_ms(1);
}
//********************************************************************************
// INICJOWANIE PRZETWORNIKA AC
//********************************************************************************
unsigned int pomiar1; // Zmienna do przechowywania wyniku pomiaru
unsigned int pomiar2; // Zmienna do przechowywania wyniku pomiaru
void PRZETWORNIK(void)
{
DDRC=0x00; // Port jako wejścia
PORTC=0x00; // Wejścia bez podciągania
ADMUX = (1<<REFS0) | // Wybór źródła napięcia odniesienia.
(0<<REFS1) | // zewnętrznne
(1<<ADLAR) ; // Bit wyboru sposobu zapisu wyniku w rejestrach ADCL i ADCH
/* (0<<MUX3) | // Bity wyboru wejścia analogowego. Wejście wybrane kombinacją
(0<<MUX2) | // tych bitów jest dołączone do przetwornika.
(0<<MUX1) | // MUX 3 2 1 0 MUX 3 2 1 0
(1<<MUX0) ; // 0 0 0 0 ADC0 0 0 0 1 ADC1 */
ADCSRA= (1<<ADEN) | // Ustawienie go zezwala na pracę przetwornika
(1<<ADPS0) | // Wybranie częstotliwości dla taktowania przetwornika
(0<<ADPS1) | // 1/32
(1<<ADPS2) ;
}
//********************************************************************************
// Program główny
//********************************************************************************
int main(void)
{
int RADDR;
USART();
PRZETWORNIK();
while(1)
{
RADDR=0x35; // sygnał adresu adres serva OC1B 8bitów
ADMUX |= _BV(0) ; // Wybór odpowiedniego wejścia ADC0
ADCSRA |= _BV(ADSC); // Rozpoczęcie przetwarzania
while(bit_is_set(ADCSRA,ADSC)) // Oczekiwanie na zakończenie przetwarzania
{};
pomiar2=ADCH; // Zapisanie starszych 8 bitów wyniku konwersji
Send_Packet(RADDR, ~pomiar1); // Wyslanie wyniku !!!!!!!!!!!!!!!!!!!!!!!
_delay_ms(1);
RADDR=0x8E; // sygnał adresu adres serva OC1B 8bitów
ADMUX &= ~_BV(0); // Wybór odpowiedniego wejścia ADC1
ADCSRA |= _BV(ADSC); // Rozpoczęcie przetwarzania
while(bit_is_set(ADCSRA,ADSC)) // Oczekiwanie na zakończenie przetwarzania
{};
pomiar1=ADCH; // Zapisanie starszych 8 bitów wyniku konwersji
Send_Packet(RADDR, ~pomiar2); // Wyslanie wyniku !!!!!!!!!!!!!!!!!!!!!!!
_delay_ms(1);
}
return 0;
}
//***************************************************************
// Odbiornik
// Atmega8 UsART
//***************************************************************
#include <avr/io.h> // wejścia wyjścia
#include <avr/interrupt.h> // przerwania
#include <util/delay.h> //
//********************************************************************************
// DEKLARACJA dla UsART
//********************************************************************************
#ifndef F_CPU
#define F_CPU 8000000
#endif
#define BAUDRATE 1200 // prędkość transmisji
#define UBRRVAL ((F_CPU/(BAUDRATE*16UL))-1)
#define SYNC 0xAA // sygnał synchronizacji 8bitów
#define RADDR1 0x8E // dopiero w pętli głwnej
#define RADDR2 0x35
//***************************************************************
// INICJOWANIE UsART
//***************************************************************
void USART(void)
{
UBRRL=(uint8_t)UBRRVAL; // ustawienie prędkości transmisji
UBRRH=(UBRRVAL>>8);
UCSRC= (1<<URSEL)| // ustawienie formatu ramki
(0<<UMSEL)| // 0 Asynchronous Operation // 1 Synchronous Operation
(0<<UPM1)|
(0<<UPM0)|
(0<<USBS)| // 0 1-bit stopu // 1 2-bity stopu
(0<<UCSZ2)| // 8bitów danych,
(1<<UCSZ1)|
(1<<UCSZ0);
UCSRB= (1<<RXEN)| // włączenie nadajnika i odbiornika
(1<<RXCIE);
}
//********************
// ODBIERANIE DANYCH
//********************
uint8_t USART_vReceiveByte(void)
{
while((UCSRA&(1<<RXC)) == 0);
return UDR;
}
//********************
// DESZYFROWANIE DANYCH
//********************
ISR(USART_RXC_vect)
{
uint8_t raddress, data, chk;
raddress=USART_vReceiveByte();
data=USART_vReceiveByte();
chk=USART_vReceiveByte();
if(chk==(raddress+data))
{
if(raddress==RADDR1)
{
OCR1A = 0;
OCR1A = data*0x10+260; // podaj na servo 1
}
else if(raddress==RADDR2)
{
OCR1B = 0;
OCR1B = data*0x10+280; // podaj na servo 2
}
else
{
OCR1A = 740;
_delay_ms(10);
OCR1B = 740;
_delay_ms(10);
}
}
}
//********************************************************************************
// DEKLARACJA PWM SERVA
//********************************************************************************
#include <avr/interrupt.h>
#include <string.h>
#include <avr/signal.h>
//********************************************************************************
// INICJOWANIE PWM SERVA
//********************************************************************************
void SERVO(void)
{
// int s1=750; // 1400 , 750 , 300
// int s2=750; // wpisywanie ręczne
DDRB = (1<<PB1) | (1<<PB2); //OC1A OC1B jako wyjscia
ICR1 = 10000; // gorna granica timera
// OCR1A = s1; // wpisywanie ręczne
// OCR1B = s2;
TCCR1A= (1<<COM1A1) | (1<<COM1B1); // COM1A1 COM1A0 COM1B1 COM1B0 FOC1A FOC1B WGM11 WGM10
TCCR1B = (1<<WGM13) | (1<<CS10); // ICNC1 ICES1 --- WGM13 WGM12 CS12 CS11 CS10
}
//********************************************************************************
// Program główny
//********************************************************************************
int main(void)
{
USART();
SERVO();
sei();
while(1)
{
}
//nothing here interrupts are working
return 0;
}
Fragment odpowiedzialny za ustawienie serw w pozycji 90 stopni
if(chk==(raddress+data))
{
if(raddress==RADDR1)
{
OCR1A = 0;
OCR1A = data*0x10+260; // podaj na servo 1
}
else if(raddress==RADDR2)
{
OCR1B = 0;
OCR1B = data*0x10+280; // podaj na servo 2
}
else
{
OCR1A = 740;
_delay_ms(10);
OCR1B = 740;
_delay_ms(10);
}
}
}
Maziu