05-12-2017, 19:44
Witam. Mam w planie wysterować kilka serwomechanizmów przez moduł RF, a dokładniej taki:
https://botland.com.pl/moduly-radiowe/31...3-mhz.html
Na początek założyłem sobie, żeby niezależnie sterować jasnością dwóch diod i tak. Wymyśliłem sobie, że będę dzielić wartość z przetwornika ADC na 8 i wysyłać wartości od 0 do 127 przetwarzając je na kod ASCII. I tutaj pojawia się taki problem, że jak wysyłam więcej tych znaków, to regulacja zaczyna "zacinać się", a na monitorze portu szeregowego dzieją się dziwne rzeczy. W nadajniku wszystko ładnie się wysyła tzn. na zmianę raz wartość z pierwszego potencjometru, a raz z drugiego. W odbiorniku natomiast (tylko przy większej ilości znaków), zaczyna się dziać coś takiego, że np. 5 razy wyśle się pierwsza wartość, a 2 razy druga wartość, aż w końcu całkiem się zatnie i jasność diod pozostanie na poziomie wypełnienia takim na jakim się "zacięła". Kręcenie potencjometrem wtedy już nic nie daje (no czasem po 10 sekundach zaskoczy). Ale mam kilka pomysłów jak rozwiązać ten problem i możliwe że sobie z nim poradzę, ale jak ktoś chciałby coś doradzić to się nie obrażę
Główny mój problem, to że biblioteki VirtualWire.h i Servo.h nie chcą ze sobą współpracować. Nie mam pojęcia jak naprawić ten problem, tak na prawdę dopiero uczę się C i nie mam za bardzo pojęcia jak działają biblioteki. Podczas kompilacji pojawia się taki błąd:
Szukałem rozwiązania w angielskim internecie, ale niestety bariera językowa trochę mi przeszkadza. Czytałem też coś, że biblioteki te mogą korzystać z jednego timera i to jest problem.
Myślałem jeszcze o tym, żeby sterować sygnałem PWM bez biblioteki, ale okazało się to trudniejsze niż podejrzewałem. Ktoś mi wytłumaczy dlaczego generując sygnał za pomocą zwykłej funkcji digitalWrite i delay np.
1.5ms stanu wysokiego, 18.5ms czasu niskiego serwo ani drgnie? Napisałem też program na modulowanie potencjometrem tego stanu wysokiego w zakresie od 1ms do 2ms i częstotliwości 50Hz, za pomocą dwóch pętli for, na diodzie było widać jakiś efekt, serwo nic. Oczywiście zdaję sobie sprawę, że funkcja delay ogranicza wielowątkowość, ale teoretycznie myślę, że mógłbym jakoś wykminić tak żeby stan wysoki kolejnych serw był przesunięty o te 2ms, tylko jak wtedy kontrolować stan niski? Może jakbym zagłębił się w timery to bym to ogarnął.
Jakie rozwiązanie mi proponujecie?
A tak wygląda kod jakby to coś pomogło.
Nadajnik:
Odbiornik:
Ale to jeszcze taka wczesna koncepcja.
https://botland.com.pl/moduly-radiowe/31...3-mhz.html
Na początek założyłem sobie, żeby niezależnie sterować jasnością dwóch diod i tak. Wymyśliłem sobie, że będę dzielić wartość z przetwornika ADC na 8 i wysyłać wartości od 0 do 127 przetwarzając je na kod ASCII. I tutaj pojawia się taki problem, że jak wysyłam więcej tych znaków, to regulacja zaczyna "zacinać się", a na monitorze portu szeregowego dzieją się dziwne rzeczy. W nadajniku wszystko ładnie się wysyła tzn. na zmianę raz wartość z pierwszego potencjometru, a raz z drugiego. W odbiorniku natomiast (tylko przy większej ilości znaków), zaczyna się dziać coś takiego, że np. 5 razy wyśle się pierwsza wartość, a 2 razy druga wartość, aż w końcu całkiem się zatnie i jasność diod pozostanie na poziomie wypełnienia takim na jakim się "zacięła". Kręcenie potencjometrem wtedy już nic nie daje (no czasem po 10 sekundach zaskoczy). Ale mam kilka pomysłów jak rozwiązać ten problem i możliwe że sobie z nim poradzę, ale jak ktoś chciałby coś doradzić to się nie obrażę
Główny mój problem, to że biblioteki VirtualWire.h i Servo.h nie chcą ze sobą współpracować. Nie mam pojęcia jak naprawić ten problem, tak na prawdę dopiero uczę się C i nie mam za bardzo pojęcia jak działają biblioteki. Podczas kompilacji pojawia się taki błąd:
Kod:
libraries\VirtualWire\VirtualWire.cpp.o (symbol from plugin): In function `crc16_update(unsigned int, unsigned char)':
(.text+0x0): multiple definition of `__vector_17'
libraries\Servo\avr\Servo.cpp.o (symbol from plugin):(.text+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
exit status 1
Błąd kompilacji dla płytki Arduino Leonardo.
Szukałem rozwiązania w angielskim internecie, ale niestety bariera językowa trochę mi przeszkadza. Czytałem też coś, że biblioteki te mogą korzystać z jednego timera i to jest problem.
Myślałem jeszcze o tym, żeby sterować sygnałem PWM bez biblioteki, ale okazało się to trudniejsze niż podejrzewałem. Ktoś mi wytłumaczy dlaczego generując sygnał za pomocą zwykłej funkcji digitalWrite i delay np.
1.5ms stanu wysokiego, 18.5ms czasu niskiego serwo ani drgnie? Napisałem też program na modulowanie potencjometrem tego stanu wysokiego w zakresie od 1ms do 2ms i częstotliwości 50Hz, za pomocą dwóch pętli for, na diodzie było widać jakiś efekt, serwo nic. Oczywiście zdaję sobie sprawę, że funkcja delay ogranicza wielowątkowość, ale teoretycznie myślę, że mógłbym jakoś wykminić tak żeby stan wysoki kolejnych serw był przesunięty o te 2ms, tylko jak wtedy kontrolować stan niski? Może jakbym zagłębił się w timery to bym to ogarnął.
Jakie rozwiązanie mi proponujecie?
A tak wygląda kod jakby to coś pomogło.
Nadajnik:
Kod:
#include <VirtualWire.h> // dodaj bibliotekę obsługującą moduły RF
int wartoscADC1 = 0; // utwórz zmienną, która będzie przechowywać wartość ADC
int wartoscADC2 = 0;
int potencjometr1 = A0; // potencjometr podłączony do pinu A0
int potencjometr2 = A1;
void setup()
{
pinMode(potencjometr1,INPUT); // definiujemy potencjometr jako wejście
pinMode(potencjometr2,INPUT);
vw_set_tx_pin(11); // nadajnik RF podłączamy do pinu 12
vw_setup(8000); // ustawiamy prędkość transmisji
Serial.begin(9600);
}
void loop()
{
char adc1[1];
char adc2[2];
wartoscADC1 = (analogRead(A0)/8);
dtostrf(wartoscADC1, 1, 0, adc1);
vw_send((uint8_t *)adc1, strlen(adc1)); // wyślij zawartość zmiennej ADC
vw_wait_tx(); // poczekaj aż całość zostanie wysłanab
Serial.println(adc1);
wartoscADC2 = (analogRead(A1)/8)+128;
dtostrf(wartoscADC2, 2, 0, adc2);
vw_send((uint8_t *)adc2, strlen(adc2)); // wyślij zawartość zmiennej ADC
vw_wait_tx(); // poczekaj aż całość zostanie wysłana
Serial.println(adc2);
}
Odbiornik:
Kod:
#include <VirtualWire.h> // dodaj bibliotekę VirtualWire.h
int dioda1 = 3;
int dioda2 = 5;
void setup()
{
pinMode(dioda1,OUTPUT);
analogWrite(dioda1,0);
pinMode(dioda2,OUTPUT);
analogWrite(dioda2,0);
Serial.begin(9600); // rozpocznij transmisję UART o prędkości 9600 baud
vw_setup(8000); // ustal prędkość odbioru RF na 2000 baud
vw_rx_start(); // rozpocznij transmisję RF
vw_set_rx_pin(11); // odbiornik RF podłączony do pinu 11
}
void loop()
{
uint8_t buf[VW_MAX_MESSAGE_LEN]; // definicja buforu odbioru danych
uint8_t buflen = VW_MAX_MESSAGE_LEN; // oraz dlugości otrzymanych danych
if (vw_get_message(buf, &buflen)) // jeżeli do buforu danych dotarły dane oraz
// transmisja została zakończona i długość danych nie przekracza 8-bitów
{
int i; // utwórz zmienną i
String odczytADC;
for (i = 0; i < buflen; i++) // jeżeli wartość i < 0 to odbieraj znaki
{
odczytADC +=char(buf[i]); // do zmiennej string wprowadź wszystkie otrzymane znaki i je połącz
}
int PWM = atoi(odczytADC.c_str()); //utwórz zmienną PWM, a następnie przekonwertuj zmienną string na int
if(PWM<128)
{
int D1 = map(PWM, 0, 127, 0, 255);
Serial.println(D1);
analogWrite(dioda1,D1); //przypisz diodzie wartość zmiennej int PWM
}
if(PWM>=128)
{
PWM=PWM-128;
int D2 = map(PWM, 0, 127, 0, 255);
Serial.println(D2);
analogWrite(dioda2,D2);
}
}
}
Ale to jeszcze taka wczesna koncepcja.