Skocz do zawartości

Połączenie cyfrowych wejść z wyjściami


Pomocna odpowiedź

Napisano

Witam serdecznie!

Zaczynam dopiero zabawę z arduino (zestaw zaproponowany w kursie) i pojawił się problem banalny, na który nie potrafię znaleźć odpowiedzi w sieci. Podczas realizacji prostego zadania okazało się że połączenie wejścia cyfrowego z wyjściem daje złe wyniki. Podanie "low" na wyjście powoduje różne odczyty na wejściu (raz "high" raz "low"). Podanie raz na wyjście "high" powoduje odczyt "high" nawet po zmianie wyjścia na "low". Próbowałem wstawiać rezystor (10k oraz 2,2M) do masy przy wejściu i nic to nie dało. Co ciekawe miernik pokazuje, że stan na wejściu i wyjściu jest poprawny: "0V" lub "4,95V" (bez rezystora do masy) dokładnie tak jak ustawiono.

Proszę o wskazówkę. Przepraszam za banalne pytanie, ale na prawdę nie potrafię znaleźć i zrozumieć tego problemu.

Pozdrawiam

Projekt dotyczy wykrywania miejsca przyciśnięcia struny gitarowej. Chodzi o detekcję, którego progu dotyka dana struna. Z tego powodu tylko na jedno wejście jest podawana "1" sekwencyjnie.

Troszkę poeksperymentowałem i popytałem i wyszło, że:

- wejścia nie mogą "wisieć w powietrzu" w trybie INPUT,
- wejścia trzeba ustawić w trybie INPUT_PULLUP (wtedy, gdy "wiszą" czytają stan "1"),
- przyciśnięcie dwóch progów przez strunę przeniesie stan logiczny na inne struny stykające przynajmniej jeden z tych progów (problem raczej nie do obejścia),
- na wyjścia (struny) trzeba podawać sekwencyjnie "0" lub nic, bo mogą nastąpić zwarcia strun przez progi.

Ostatni problem wydaje mi się, że można rozwiązać tranzystorem MOSFET na wyjściu (do struny). Wtedy można podłączyć strunę do masy wystawiając "1", a wystawiając "0" pozostawić strunę "wiszącą" tzn. niepodłączoną.

Pod spodem kod programu przed modyfikacjami. Schemat niestety teraz mogę zrobić tylko taki prymitywny . W testach używaliśmy 2 łączników (odwzorowano 2 struny i jeden próg).

Dzięki za wszelkie wskazówki i uwagi.

int prog = 2; // wejscie podłączone progu

int strunaE = 8; // wyjscie podłączone do strune E
int strunaB = 9; // wyjscie podłączone do strune B


void setup()
{
   pinMode(prog, INPUT);
   pinMode(strunaE, OUTPUT);
   pinMode(strunaB, OUTPUT);

   Serial.begin(9600);

}

void loop() 
{
   int sczytywanieNapiecia = digitalRead(prog);

  digitalWrite(strunaE, LOW);
  Serial.println("Struna E: 0");
  Serial.print("Prog: ");
  Serial.println(sczytywanieNapiecia);
  Serial.println("");
  Serial.println("");
  Serial.println("");
  Serial.println("");
  Serial.println("");
  Serial.println("");
  Serial.println("");
  Serial.println("");
  Serial.println("");
  Serial.println("");
  Serial.println("");
  Serial.println("");

  delay(2000);

  digitalWrite(strunaE, HIGH);
  Serial.println("Struna E: 1");
  Serial.print("Prog: ");
  Serial.println(sczytywanieNapiecia);
  Serial.println("");
  Serial.println("");
  Serial.println("");
  Serial.println("");
  Serial.println("");
  Serial.println("");
  Serial.println("");
  Serial.println("");
  Serial.println("");
  Serial.println("");
  Serial.println("");
  Serial.println("");

  delay(2000);


}

Ja bym to zrobił tak:

Przewodnik na każdym progu podzielony na tyle części ile jest strun.

Każda struna ma swój port do odczytywania podpięty rezystorem do GND.

Struny podłączone do VCC, a poszczególne części progu różnymi rezystorami do wspomnianych portów.

W ten sposób gdy struna dotyka progu, rezystor pomiędzy progiem (VCC) a pinem i pinem a GND tworzy dzielnik z którego napięcie sczytujemy ADC. I voilla.

Tak jak napisał deshipu, poczytaj o klawiaturach matrycowych - to co robisz to dokładny dopowiednik takiej klawiatury, tylko zamiast przycisków masz struny.

Natomiast jak chodzi o układ to możesz prościej zrealizować sterowanie, bez dodatkowych elementów. Wystarczy mieć wyjście typu open-collector, czyli zwierać do masy, albo wystawiać stan "wysokiej impedancji". Tłumacząc na ludzki:

1) aby wystawic 0 - ustawiasz port jako wyjście, wystawiasz 0

2) aby "nic nie wystawić" - przestawiasz port jako wejście (bez pullup-a)

Ja bym to zrobił tak:

Przewodnik na każdym progu podzielony na tyle części ile jest strun.

Każda struna ma swój port do odczytywania podpięty rezystorem do GND.

Struny podłączone do VCC, a poszczególne części progu różnymi rezystorami do wspomnianych portów.

W ten sposób gdy struna dotyka progu, rezystor pomiędzy progiem (VCC) a pinem i pinem a GND tworzy dzielnik z którego napięcie sczytujemy ADC. I voilla.

Tak, dziękuję. Zdałem sobie z tego sprawę dwa dni temu wieczorem. Wygląda na to, że źle zaplanowałem temat. Progów mamy 22 (a więc trzeba 22 ADC) i przecięcie ich na sześć części na dzień dzisiejszy przekracza nasze możliwości, nie wspominając o poprowadzeniu w gryfie 132 przewodów. Zakładamy, że niestety odczyt będzie poprawny przy naciskaniu bez zwierania stanów poprzez struny. Wiem, brzmi tandetnie, ale część elektryczną (podłączenia do progów i strun mamy gotową = 22 kabelki do progów i 6 do strun) oraz mechaniczną mamy wykonaną. Chcemy to zakończyć w tej wersji, gdyż szkoda wykonanej pracy, a w jak to zadziała, to można myśleć o modyfikacji. Pewnie problemów będzie jeszcze po drodze kilka.

Dziękuję i pozdrawiam

Kamil

[ Dodano: 17-12-2015, 10:17 ]

Tak jak napisał deshipu, poczytaj o klawiaturach matrycowych - to co robisz to dokładny dopowiednik takiej klawiatury, tylko zamiast przycisków masz struny.

Natomiast jak chodzi o układ to możesz prościej zrealizować sterowanie, bez dodatkowych elementów. Wystarczy mieć wyjście typu open-collector, czyli zwierać do masy, albo wystawiać stan "wysokiej impedancji". Tłumacząc na ludzki:

1) aby wystawic 0 - ustawiasz port jako wyjście, wystawiasz 0

2) aby "nic nie wystawić" - przestawiasz port jako wejście (bez pullup-a)

Witam!

Jak przeczytałem tego posta to mnie olśniło. Eureka! Świetna rada, bardzo dziękuję, dziś to wypróbujemy. Ułatwiłoby to znacznie układ.

Dalej, chcemy się zmierzyć ze standardem MIDI (przesłanie do komputera), więc jest jeszcze co robić.

Dzięki, dam znać co nam wyszło.

To jeszcze podpowiem, że do Arduino jest gotowy moduł do obsługi klawiatury matrycowej: http://playground.arduino.cc/Code/Keypad

A sztuczka ze zmianą kierunku wyjścia jest w pliku Keypad.cpp:

// Private : Hardware scan
void Keypad::scanKeys() {
// Re-intialize the row pins. Allows sharing these pins with other hardware.
for (byte r=0; r<sizeKpd.rows; r++) {
	pin_mode(rowPins[r],INPUT_PULLUP);
}

// bitMap stores ALL the keys that are being pressed.
for (byte c=0; c<sizeKpd.columns; c++) {
	pin_mode(columnPins[c],OUTPUT);
	pin_write(columnPins[c], LOW);	// Begin column pulse output.
	for (byte r=0; r<sizeKpd.rows; r++) {
		bitWrite(bitMap[r], c, !pin_read(rowPins[r]));  // keypress is active low so invert to high.
	}
	// Set pin to high impedance input. Effectively ends column pulse.
	pin_write(columnPins[c],HIGH);
	pin_mode(columnPins[c],INPUT);
}
}

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...