Witam
Walczę od kilku dni z "analogowym" wskaźnikiem wysterowania. Jest to projekt niejakiego Daniela C.:
https://sites.google.com/view/arduino-co...d_attiny85
Kod źródłowy nie zawiera instrukcji sterujących wyświetlaczem, ale nie to jest problemem.
Do oryginalnego kodu próbuję dorobić funkcję regulacji kontrastu za pomocą potencjometru oraz zmiany trybu wyświetlania negatyw/pozytyw poprzez zwarcie pinu do masy.
Ponieważ PB0 i PB2 używane są do obsługi magistrali I2C zaś PB3 jest wejściem sygnału, wybór padł na PB1 do przełączania pozytyw/negatyw oraz PB4 (ADC3) do obsługi potencjometru.
Przełączanie negatyw/pozytyw zostawiam na koniec, bo to nie powinno sprawiać problemów. Uznałem, że zacznę od regulacji kontrastu, ponieważ ta z wielu powodów może sprawiać problemy. Niestety wykrakałem, choć nie takich problemów się spodziewałem.
Oryginalny kod odpowiedzialny za obsługę wejścia analogowego wygląda tak:
Analogicznie dopisałem obsługę potencjometru:
Oczywiście zmienna "Contrast" jest wcześniej zadeklarowana jako zmienna globalna i zainicjowana.
Całość pętli głównej wygląda tak:
Taki kod działa, ale regulacja kontrastu zmienia także poziom wskazywany przez wskaźnik i na odwrót - sygnał wejściowy dla wskaźnika zmienia kontrast. Dzieje się to w pełnym zakresie tzn. min kontrast = min wskazanie VU, zaś max kontrast = max wskazanie VU.
Zachowuje się to tak jakby wyprowadzenia portów PB3 i PB4 były fizycznie zwarte ale nie są.
Wiele wskazuje na to, że przetwornik ADC pracuje w trybie "Differential", a nie "Single End".
Częściowo dowodzi temu modyfikacja kodu wymuszająca w rejestrze ADMUX odpowiednie ustawienie bitów:
Taki kod działa zdecydowanie lepiej, jednak nadal widoczny jest niewielki wpływ regulacji kontrastu na wskazania VU i na odwrót choć to może wynikać z jakiegoś przesłuchu. Poza tym wydaje mi się, że samo analogRead() powinno ustawić odpowiednie bity w rejestrze ADMUX.
Elektronikiem podobno jestem niezłym, ale programistą raczej marnym i skończyły mi się pomysły. Gotów jestem uznać, że jest to jakiś błąd Arduino. Nie mam pojęcia jak sprawdzić co dokładnie robi funkcja analogRead() i w jaki sposób ustawiane są bity konfiguracyjne ADC w rejestrze ADMUX w zależności od parametru przekazywanego do funkcji.
Nigdzie nie znalazłem informacji o tym że wejścia ADC domyślnie pracują w trybie różnicowym ani też jak to zmienić. Znalezione w sieci przykłady dotyczą obsługi jednego wejścia analogowego, a nie dwóch.
Jednak z jakiegoś powodu autor kodu w innych swoich projektach korzysta z ADC0 i ADC3, a nie ADC3 i ADC2 gdy potrzebuje dwóch wejść analogowych, co może sugerować że również natknął się na ten problem.
Czy ktoś ma pomysł co można zrobić aby to działało prawidłowo bez żadnych kombinacji?
Walczę od kilku dni z "analogowym" wskaźnikiem wysterowania. Jest to projekt niejakiego Daniela C.:
https://sites.google.com/view/arduino-co...d_attiny85
Kod źródłowy nie zawiera instrukcji sterujących wyświetlaczem, ale nie to jest problemem.
Do oryginalnego kodu próbuję dorobić funkcję regulacji kontrastu za pomocą potencjometru oraz zmiany trybu wyświetlania negatyw/pozytyw poprzez zwarcie pinu do masy.
Ponieważ PB0 i PB2 używane są do obsługi magistrali I2C zaś PB3 jest wejściem sygnału, wybór padł na PB1 do przełączania pozytyw/negatyw oraz PB4 (ADC3) do obsługi potencjometru.
Przełączanie negatyw/pozytyw zostawiam na koniec, bo to nie powinno sprawiać problemów. Uznałem, że zacznę od regulacji kontrastu, ponieważ ta z wielu powodów może sprawiać problemy. Niestety wykrakałem, choć nie takich problemów się spodziewałem.
Oryginalny kod odpowiedzialny za obsługę wejścia analogowego wygląda tak:
Kod:
while(1){
sig_Read=map(analogRead(A3),0,1023,14,120); //14 start 120 end
if (sig_Read>sig_Mem) {Refresh=0;}
}Analogicznie dopisałem obsługę potencjometru:
Kod:
ReadContrast = map(analogRead(A2), 0, 1023, 0, 255);
if (ReadContrast != Contrast){
Contrast = ReadContrast;
TinyOLED_send_command(0x81);
TinyOLED_send_command(Contrast);
}Oczywiście zmienna "Contrast" jest wcześniej zadeklarowana jako zmienna globalna i zainicjowana.
Całość pętli głównej wygląda tak:
Kod:
while(1){
ReadContrast = map(analogRead(A2), 0, 1023, 0, 255);
if (ReadContrast != Contrast){
Contrast = ReadContrast;
TinyOLED_send_command(0x81);
TinyOLED_send_command(Contrast);
}
sig_Read=map(analogRead(A3),0,1023,14,120); //14 start 120 end
if (sig_Read>sig_Mem) {Refresh=0;}
FIRST_RUN:;
switch (Refresh) {
case 0:sig_Send=VuDelay();Tiny_Flip_VU();Refresh++;break;
case 1 ... 4 :Refresh=(Refresh<4)?Refresh+1:0;break;
default:break;
}
}
}Taki kod działa, ale regulacja kontrastu zmienia także poziom wskazywany przez wskaźnik i na odwrót - sygnał wejściowy dla wskaźnika zmienia kontrast. Dzieje się to w pełnym zakresie tzn. min kontrast = min wskazanie VU, zaś max kontrast = max wskazanie VU.
Zachowuje się to tak jakby wyprowadzenia portów PB3 i PB4 były fizycznie zwarte ale nie są.
Wiele wskazuje na to, że przetwornik ADC pracuje w trybie "Differential", a nie "Single End".
Częściowo dowodzi temu modyfikacja kodu wymuszająca w rejestrze ADMUX odpowiednie ustawienie bitów:
Kod:
while(1){
ADMUX = 00000010;
ReadContrast = map(analogRead(A2), 0, 1023, 0, 255);
if (ReadContrast != Contrast){
Contrast = ReadContrast;
TinyOLED_send_command(0x81);
TinyOLED_send_command(Contrast);
}
ADMUX = 00000011;
sig_Read=map(analogRead(A3),0,1023,14,120); //14 start 120 end
if (sig_Read>sig_Mem) {Refresh=0;}
FIRST_RUN:;
switch (Refresh) {
case 0:sig_Send=VuDelay();Tiny_Flip_VU();Refresh++;break;
case 1 ... 4 :Refresh=(Refresh<4)?Refresh+1:0;break;
default:break;
}
}
}Taki kod działa zdecydowanie lepiej, jednak nadal widoczny jest niewielki wpływ regulacji kontrastu na wskazania VU i na odwrót choć to może wynikać z jakiegoś przesłuchu. Poza tym wydaje mi się, że samo analogRead() powinno ustawić odpowiednie bity w rejestrze ADMUX.
Elektronikiem podobno jestem niezłym, ale programistą raczej marnym i skończyły mi się pomysły. Gotów jestem uznać, że jest to jakiś błąd Arduino. Nie mam pojęcia jak sprawdzić co dokładnie robi funkcja analogRead() i w jaki sposób ustawiane są bity konfiguracyjne ADC w rejestrze ADMUX w zależności od parametru przekazywanego do funkcji.
Nigdzie nie znalazłem informacji o tym że wejścia ADC domyślnie pracują w trybie różnicowym ani też jak to zmienić. Znalezione w sieci przykłady dotyczą obsługi jednego wejścia analogowego, a nie dwóch.
Jednak z jakiegoś powodu autor kodu w innych swoich projektach korzysta z ADC0 i ADC3, a nie ADC3 i ADC2 gdy potrzebuje dwóch wejść analogowych, co może sugerować że również natknął się na ten problem.
Czy ktoś ma pomysł co można zrobić aby to działało prawidłowo bez żadnych kombinacji?


