• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
funkcja krótkiego/ długiego wciśnięcia ale z wejścia analogowego
#1
Witam, moje doswiadczenia z arduino są bardzo małe, coś tam wiem, ale głównie posługuje się tutorialami. 

Zrobiłem dzielnik napięcia z jakiegoś tutoriala o budowaniu omomierza z arduino i uprościłem go do moich potrzeb. zczytałem dane o konkretnych rezystorach które mnie interesują, przykłądowo, gdy wrzuce opornik 1,2kohm to na monitorze szeregowym wyskakuje 556/557.

Tylko stanąłem w miejscu bo nie wiem jak zrobić, żeby arduino wykonywało różne funkcje w zależności od tego jak długo bedzie opornik "wciśnięty" 

konkretniej- miedzy opornikiem a masą jest przycisk i gdy go wcisnę krótko, to arduino ma odpalać jeden przekaźnik ( na powiedzmy 500ms)  a gdy wcisnę długo, powyżej jednej sekundy to arduino ma odpalać inny przekaźnik ( również na 500ms)


Załączone pliki Miniatury
   
 
Odpowiedź
#2
Zmierz czas wciśnięcia. Wykorzystaj funkcję millis().
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
#3
Są postępy Smile  
Uprościłem to do jednego przycisku i zamiast przekaźników narazie używam monitora 
przy kliknięciu krótkim, wysyłany jest napis "ODBIERZ" a po przytrzymaniu powyżej sekundy "ROZLACZ" -- czyli dokładnie tak jak chciałem.
będę szczery nie do końca wiem jak to działa, ale przerobiłem kod znaleziony na internecie Smile 

Tylko został mały problem bo w momencie gdy przytrzymam przycisk i tak najpierw jest wysyłyany sygnał "ODBIERZ" i dopiero po upływie sekundy "Rozłącz" 
Jak zrobić, żeby gdy wcisne i przytrzymam przycisk to nie wysyłał się sygnał "ODBIERZ" i po sekundzie "ROZLACZ", 
 tylko sam sygnał "ROZLACZ" (po upływie sekundy) ? 

Kod:
boolean tak = 0;
unsigned long czas= millis();
int analogPin= 0;
int r= 0;

void setup()
{

Serial.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
}

void loop()
{
r= analogRead(analogPin);

if(r > 763 && r < 768)
{
  if(tak == 0)
  {
    delay(50);
    tak = 1;
    czas = millis();
  Serial.println("ODBIERZ");
  } 
}
else {
  delay(50);
  tak = 0;
}
if(tak == 1 && millis() - czas > 1000)
{
  Serial.println("ROZLACZ");
}


}
 
Odpowiedź
#4
Najpierw sprawdź czy przycisk jest naciśnięty długo, a jeśli nie (else if) to czy krótko, ewentualnie wcale. Stwierdzenia dokonuje się na podstawie był wciśnięty i został puszczony, pytanie po jakim czasie. Czyli dopiero po puszczeniu przycisku jest akcja. Można ewentualnie zrobić akcję przy dłuższym wciśnięciu i zablokować ponowne sprawdzanie aż do puszczenia. Jeśli logikę oprzesz o został wciśnięty to zawsze będzie krótki + ewentualnie długi.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#5
prażą mi sie styki w głowie i nie mam pojęcia jak to zrobić , nie mam również pojęcia do czego służy "tak" i dlaczego jest go tyle, ale bez niego na monitorze ciagle przewija sie "rozlacz" albo "odbierz"


Zrobiłem tak 
Kod:
boolean tak = 0;
unsigned long czas= millis();
int analogPin= 0;
int r= 0;

void setup()
{

Serial.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
}

void loop()
{
r= analogRead(analogPin);

if(r > 763 && r < 768)
{
  if(tak == 0)
  {
    delay(50);
    tak = 1;
    czas = millis();
  }
}
else {
  delay(50);
  tak = 0;
}
if(tak == 1 && millis() - czas > 2000)
{
  Serial.println("ROZLACZ");
  delay(50);
}
else
{
if (tak == 1 && millis() - czas < 800)
{
    Serial.println("ODBIERZ");
    delay(50);
}
}

}


Ale bez efektów, nadal jest to samo .

Edit. Trochę mi cierpliwość wróciła, jeszcze raz

Opisze mi ktoś jak zacząć pomiar czasu gdy na wejściu odczytam wartość w przedziale 763-768 
A jak zakończyć pomiar gdy wartość będzie inna ?
 
Odpowiedź
#6
Niepotrzebnie sprawdzasz zakresy. Jeśli masz drabinkę przycisków to:
Kod:
wyzerujwszystkiebuttony();
if(adc>900) //zaden nie jest wcisniety
else if (adc>800) btn1=1; //jak ten wcisniety to te ponizej juz nie sa sprawdzane
else if (adc>600) btn2=1;
else if (adc>400) btn3=1;
etc...

Chyba że boisz się, że ktoś wciśnie dwa przyciski jednocześnie.
Można tak samo idąc od 0 w drugą stronę zmieniając znak > na <. Pierwszy spełniony spowoduje, że reszta już nie.
Tak najprościej dla każdego przycisku możesz napisać funkcję, masz stan aktualny przycisku, poprzedni zapisany w zmiennej static bool, jak aktualny = poprzedni to nic nie robisz. Zapisujesz czas w zmiennej static uint32_t startczasu=millis() gdy przycisk został wciśnięty, potem odczytujesz znowu gdy został puszczony i po odjęciu masz czas. Zmienne static zachowują się w pamięci po wyjściu z funkcji.

Podziel sobie program na sekcje gdzie coś przyjmujesz i to gdzie coś wykonujesz.
Np. zaświecenie jednego led na 1500ms. Ustaliłeś, że przycisk jest wciśnięty długo:
dlugo=1;

Kod:
#define led 13
#define btn A0
bool dlugo;
void setup() {
  // put your setup code here, to run once:
pinMode(led,OUTPUT);
pinMode(btn, INPUT_PULLUP);
}

void loop() {
 
  // put your main code here, to run repeatedly:
if (! digitalRead(btn)) dlugo=1; else dlugo=0;
pracaled1();
}


void pracaled1()
{
static bool pracaled1=0;
static uint32_t startswiecenia =0;
if (dlugo and pracaled1==0) //przycisk zostal wcisniety dlugo i wczesniej nie byl bo pracaled1==0
{startswiecenia=millis();
pracaled1=1;
}
if (pracaled1 and (uint32_t)(millis()-startswiecenia>=1500) ) //jesli swieci i minelo 1500ms
{
pracaled1=0;
}
digitalWrite(led,pracaled1); //na koniec wlaczenie lub wylaczenie led

}

Podłącz sobie przycisk między A0 i GND, potestuj jak to działa z millis().
W poprzednich moich postach jest gdzieś tu na forum wrzucony szkic z funkcją czas(). Można w nim wybrać sobie tik, że np. co 10ms flaga jest ustawiona na 1. Wystarczy w odpowiednim if sprawdzić czy przy tym tyknięciu jest przycisk wciśnięty i zwiększyć jego zmienną, w momencie gdy jest puszczony sprawdzić wartość zmiennej, czy to było długie czy krótkie wciśnięcie, po czym wyzerować tą zmienną a ustawić odpowiednio krotkie=1 i dlugie=0 lub na odwrót.
Na pewno jest też biblioteka do analog button.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#7
Przemyślałem wszystko i wystarczy mi jeden przycisk, reszta będzie "omijała " arduino.
Może napisze do czego mi to potrzebne, bedzie prościej Smile
Sterowanie z kierownicy radiem pioneer:
Zwarcie jednego pinu do masy przez opornik - dana akcja na radiu z kierownicy wychodzi tylko jeden przewód ( aktualnie jest to komunikacja IBUS, ale bez problemu przerobię manetki w kierownicy, żeby zwierały do masy z danym rezystorem.. )

I tak mam głośność +/- ;
przewijanie piosenek +/- ;
przycisk od zmiany wejścia, czyli radio/usb/bluetooth/itd.

I zostaje mi tylko jeden przycisk do odbierania telefonu i sprawa jest bardzo prosta bo wystarczy dać opornik 3KOHM i gdy ktoś dzwoni to odbiera, ale żeby się rozłączyć to już niestety trzeba opornik 5,5KOHM

I pomysł był taki, żeby zrobić to tak jak to jest w adapterach które można dokupić, czyli jeśli krótko kliknę to odbierze ( zewrze do masy przez 3KOHM) a gdy przytrzymam powyżej 1 / 2 sek to się rozłączy ( zewrze 5,5KOHM) .

Tylko troche mnie to przerasta i mimo klepania w google każdej nie znanej mi "frazy " z języka C to nadal nie mogę tego załapać.

pierwszą część twojej odpowiedzi zrozumiałem, ale jak napisałem wyżej, bedzie jednak jeden przycisk, więc nie bedzie mi to potrzebne, a drugą część niby coś łapie ale nie moge tego pojąć.

Arduino musi mi odczytać gdy bedzie wiśniety dany przeze mnie rezystor i jeśli odpowiedni ( w tym wypadku 3KOHM) to zmierzyć jak długo jest wciskany, jeśli poniżej sekundy to ma zewrzeć mase do opornika 3KOHM, a jeśli przez dłużej niż sekunde to ma zewrzeć masę do opornika 5,5KOHM


Edit: Tak, mam kupiony adapter i działa wszystko ( odbieranie i rozlaczanie rownież) ale przycisk od zmiany wejścia nie działa, jest bezużyteczny. Pisałem do producenta bo miało wszystko działać, broni się tym, że wszystko zależy od samochodu i modelu/marki radia...
A ja jak coś mam a nie działa to mnie denerwuje.. już lepiej żeby tego nie było Big Grin
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości