Jednoczesne zapalanie diody joystickiem oraz przyciskiem

0

Witam,
Jestem nowym użytkownikiem tego forum oraz osoba uczącą się obecnie zarówno programowania jak i elektryki/elektroniki. Od jakiegoś czasu bawię się STM32. Uczę się z różnych źródeł a jedną z nich jest książka: "Aplikacje i ćwiczenia w języku C z biblioteką HAL" Marka Galewskiego. Książka dedykowana do STM32, język programowania C a piszemy na pewnym zestawie uruchomieniowym. Ja tego zestawu uruchomieniowego nie mam, postanowiłem budować układy na płytkach stykowych z własnych elementów.
Jedno z ćwiczeń, początkowe. Zapalanie diod - 5 diod, 5 przycisków. Każdy przycisk do konkretnej diody - zapalenie i wyłączenie. Ćwiczenie to zrobiłem. Kolejne ćwiczenie: zapalanie diod przyciskami lub joystickiem. Celem ćwiczenia jest zapalenie kolejnej diody poprzez wychylenie joysticku lub wciśniecie przycisku (do wyboru). I teraz: zestaw uruchomieniowy ma joystick 5 pozycyjny (składający się z 5 mikrowyłączników). Ja natomiast użyłem joisticka analogowego. Udało mi się napisać program który obsługuje joystick analogowy tak jak sobie tego życzę: Wychylenie w lewo zapala diodę 1, w góre 2, w prawo 3, w dół 4, naciśniecie diodę 5. Nie potrafię jednak napisać kodu który obsługiwałby jednocześnie i joystick i przyciski (mikrowyłączniki). W moim programie przy wychylaniu joysticka diody zapalają się pełnym światłem jak napisałem wyżej, natomiast przy naciśnięciu przycisku widać tylko minimalne żarzenie się pomiędzy anodą a katodą w ledzie. Gdy usunę fragment kodu odpowiedzialny za obsługę joysticka, diody uruchamiane przyciskiem palą się pełnym światłem.

Jak połączyć te dwie funkcjonalności, bym daną diodę mógł zapalić jednocześnie i odpowiednim wychyleniem Joystickiem oraz przyciskiem. Fragment kodu obsługujący joystick i przyciski w obecnym kształcie zamieszczam poniżej - jak połączyć te dwie instrukcje i dać alternatywę, Joystick lub przycisk? Moim pomysłem jest zbudowanie instrukcji switch gdzie case 0 to kod odpowiedzialny za zapalanie diody nr 1 przyciskiem, case 1 zapalenie diody nr 1 joystickiem itd. Zrobiłem już takie podejście ale efekt był taki, że diody nie zapalały się ani przyciskami ani joystickiem mimo braku błędów przy kompilacji.

/* USER CODE BEGIN WHILE */
volatile static uint16_t joystick[2];
HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED);
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)joystick, 2);
while (1)
{

// Obsługa przycisków
//-------------------------------------------------------------Dioda zielona, przycisk 1
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_13)){
HAL_GPIO_WritePin(GPIOB, LED1_Pin, GPIO_PIN_RESET);
}else{
HAL_GPIO_WritePin(GPIOB, LED1_Pin, GPIO_PIN_SET);
}
//-----------------------------------------------------------------Dioda czerwona, przycisk 2
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_14)){
HAL_GPIO_WritePin(GPIOB, LED2_Pin, GPIO_PIN_RESET);
}else{
HAL_GPIO_WritePin(GPIOB, LED2_Pin, GPIO_PIN_SET);
}
//-----------------------------------------------------------------Dioda żółta, przycisk 3
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4)){
HAL_GPIO_WritePin(GPIOB, LED3_Pin, GPIO_PIN_RESET);
}else{
HAL_GPIO_WritePin(GPIOB, LED3_Pin, GPIO_PIN_SET);
}
//-----------------------------------------------------------------Dioda niebieska, przycisk 4
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_15)){
HAL_GPIO_WritePin(GPIOB, LED4_Pin, GPIO_PIN_RESET);
}else{
HAL_GPIO_WritePin(GPIOB, LED4_Pin, GPIO_PIN_SET);
}
//-----------------------------------------------------------------Dioda biała, przycisk 5 - przycisk w joysticku
if (HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)){
HAL_GPIO_WritePin(LED5_GPIO_Port, LED5_Pin, GPIO_PIN_RESET);
} else {
HAL_GPIO_WritePin(LED5_GPIO_Port, LED5_Pin, GPIO_PIN_SET);
}
/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */
// Obsługa joysticka 
if ((joystick[0]>=2000) && (joystick[0]<=3000))
{
HAL_GPIO_WritePin(GPIOB, LED2_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB, LED4_Pin, GPIO_PIN_RESET);
}
 if ((joystick[1]>=2000) && (joystick[1]<=3000))
 {
 HAL_GPIO_WritePin(GPIOB, LED1_Pin, GPIO_PIN_RESET);
 HAL_GPIO_WritePin(GPIOB, LED3_Pin, GPIO_PIN_RESET);
 }

 if ((joystick[0]>=4000))
 {
 HAL_GPIO_WritePin(GPIOB, LED4_Pin, GPIO_PIN_SET);
 HAL_GPIO_WritePin(GPIOB, LED2_Pin, GPIO_PIN_RESET);
 }

 if ((joystick[0]<=800))
 {
  HAL_GPIO_WritePin(GPIOB, LED4_Pin, GPIO_PIN_RESET);
  HAL_GPIO_WritePin(GPIOB, LED2_Pin, GPIO_PIN_SET);
 }

 if ((joystick[1]>=4000))
 {
  HAL_GPIO_WritePin(GPIOB, LED3_Pin, GPIO_PIN_RESET);
  HAL_GPIO_WritePin(GPIOB, LED1_Pin, GPIO_PIN_SET);
 }

 if ((joystick[1]<=800))
 {
  HAL_GPIO_WritePin(GPIOB, LED3_Pin, GPIO_PIN_SET);
  HAL_GPIO_WritePin(GPIOB, LED1_Pin, GPIO_PIN_RESET);
 }
}
/* USER CODE END 3 */
0

Źle mi się to czyta prawdę mówiąc ...

Obecnie masz natychmiastową reakcję wejście -> wyjście, a z tego co piszesz, wydaje się, chcesz mieć określony STAN, czyli jakaś zmienna / zespól zmiennych.

Po drugie obsługa joystika predestynuje do nieustannej zmiany warunku wyjściowego -> więc miganie. Też pewnie by się to leczyło przez "jakiś" stan, nie podejmuję się wskazać szczegółów, i zmiana wyjść tylko na wyraźną zmianę STANU.

DonMariano napisał(a):

Witam,
Jestem nowym użytkownikiem tego forum oraz osoba uczącą się obecnie zarówno programowania jak i elektryki/elektroniki.

Zawsze będę powtarzał, nauka, głębokie oswojenie /zinternalizowanie z pisaniem oprogramowania, to pecet a nie mikrokontrolery.
Programujesz A -> skutek B, po drodze debuger, porządne odpowiednie do zagadnienia struktury danych itd ...

0

Pamiętaj też o wyłączaniu diody. Bez tego możesz uruchomić diodę do odłaczenia joysticka od zasilania. To nie jest częsty błąd, ale raz musiałem się strasznie długo zanim ogarnąłem.


https://otomedi.pl/reumatyzm-objawy-i-leczenie/

2

Obsługa przycisku i joystick wchodzą sobie w paradę i modyfikują ten sam zasób, czyli pin portu. Niewciśnięty przycisk będzie wyłączał LED a wychylony drążek go włączał, w rezultacie na diodę zostanie podany sygnał prostokątny o wypełnieniu zależnym od ilości instrukcji znajdujących się między wywołaniami zapisu do portu. Trzeba zadeklarować dodatkowe zmienne np. boolowskie i dopiero na końcu zrobić odpowiedni warunek logiczny np. "or" || i zapisać do portu, np. coś w tym stylu:

bool sw1;

while(1) {
    sw1_on = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_13);
    ...
    if (sw1_on || joystick[1] >= 4000) { // tutaj warunki, które maja zapalać lub gasić diodę LED1
        HAL_GPIO_WritePin(GPIOB, LED1_Pin, GPIO_PIN_SET);
    } else {
        HAL_GPIO_WritePin(GPIOB, LED1_Pin, GPIO_PIN_RESET);
    }
}

Napięcia na przetworniku mogą być zaszumione i przy pozycji na granicy włączania mogą być problemy niewspominając już o drganiach styków. Przy odczytach z przetwornika implementacja filtru cyfrowego była by wskazana albo komparator z histerezą.

0

@jvotech - dzięki za odpowiedź. Typ logiczny zdefiniowałem tak

typedef enum {FALSE=0, TRUE = !FALSE} bool;
bool sw1_on = TRUE;

Reszta kodu:

while (1)
  {
    printf("VRx=%u, VRy=%u\n", joystick[0], joystick[1]);
    HAL_Delay(100);

   sw1_on = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_13);

   if ((joystick[0]>=2000) && (joystick[0]<=3000))
       	 {
       	 HAL_GPIO_WritePin(GPIOB, LED2_Pin, GPIO_PIN_RESET);
       	 HAL_GPIO_WritePin(GPIOB, LED4_Pin, GPIO_PIN_RESET);
       	 }

       	 if ((joystick[1]>=2000) && (joystick[1]<=3000))
       	 {
       	 HAL_GPIO_WritePin(GPIOB, LED1_Pin, GPIO_PIN_RESET);
       	 HAL_GPIO_WritePin(GPIOB, LED3_Pin, GPIO_PIN_RESET);
       	 }

    if (sw1_on || joystick[1] >= 4000) { 
    	HAL_GPIO_WritePin(GPIOB, LED1_Pin, GPIO_PIN_RESET);
        } else {
        HAL_GPIO_WritePin(GPIOB, LED1_Pin, GPIO_PIN_SET);
        }
    }

Efekt jest taki, że dioda LED1 zapala się z przypisanego jej przycisku, wychylenie joysticka natomiast nie zapala diody w ogóle.

Sprawdziłem jak wyglądają napięcia referencyjne na potencjometrach w joysticku.Przy wychyleniu które powinno zapalać diodę jest zmiana napięcia zgodna z oczekiwaniami - działa to prawidłowo.

Nie mniej, dziękuje za już udzielone informacje:)

PS:
Jak kopiujecie kod tu na forum, że widać numerację wierszy?:P

0
DonMariano napisał(a):

@jvotech - dzięki za odpowiedź. Typ logiczny zdefiniowałem tak

typedef enum {FALSE=0, TRUE = !FALSE} bool;
bool sw1_on = TRUE;

zamiast enuma zrób to tak:

#include <stdbool.h>
bool sw1_on = true;

1 użytkowników online, w tym zalogowanych: 0, gości: 1