Regulowany włącznik sekwencji

Masz problem z Arduino? Tutaj możesz szukać pomocy.
ODPOWIEDZ
stanis69
Młodszy majsterkowicz
Posty: 9
Rejestracja: 10 gru 2014, 20:04

Regulowany włącznik sekwencji

Post autor: stanis69 » 10 gru 2014, 20:44

Witam.
Na tym forum to mój pierwszy post więc przy okazji chciałem wszystkich powitać. Arduino posiadam już od jakiegoś czasu, już nawet udało mi się pozytywnie przekształcić kilka gotowych kodów na potrzeby własne ale z pisaniem to już większy problem.
Ale przejdę do rzeczy. Chcę napisać program a następnie przenieść go na jakiś mały procesorek i zmontować na osobnej płytce gotowy produkt. Ma to być taki trochę bardziej skomplikowany włącznik, po wciśnięciu przycisku ma nastąpić włączenie sterowanego elementu przyjmijmy tu dla ułatwienia diody która ma świecić określony czas po czym ma zgasnąć, następnie ma być przerwa także określonej długości po której ma się zapalić druga dioda która również ma świecić określony czas. Ale co najważniejsze wszystkie te czasy mają być regulowane za pomocą trzech potencjometrów. Dodatkowo wciśnięcie przycisku w czasie trwania sekwencji ma być ignorowane, dopiero po zakończeniu całej sekwencji można wcisnąć przycisk kolejny raz. Czasy trwania "nadawania" oraz przerwy powinny być regulowane w przedziale 10ms - 500ms.

I tu jest mój problem "JAK TO UGRYŹĆ?" Proszę o pomoc bardziej doświadczonych programistów ode mnie, ewentualnie jakiś podobny program który da się zaadoptować. Wujek G. nie bardzo jest mi tu pomocny, tym bardziej że w naszym ojczystym języku za dużo materiałów w necie niema.

Co miesiąc do wygrania nagrody o wartości ponad 1600 zł!


mateuszmp
Młodszy majsterkowicz
Posty: 3
Rejestracja: 10 gru 2014, 21:49

Re: Regulowany włącznik sekwencji

Post autor: mateuszmp » 10 gru 2014, 22:25

Witam. Już jakiś czas nie siedzę w Arduino, lecz zamierzam po nowym roku na nową zacząć z nim eksperymentować, więc wybacz jeśli opiszę coś niejasno lub niepoprawnie. Przejrzałem moje dawne projekty i poleciłbym ci zastosowanie składni, która będzie odpowiedzialna za odczyt wartości z potencjometru np. na początku definiujesz każdy z podłączonych potencjometrów

Kod: Zaznacz cały

#define Potencjometr1 0
(wejście analogowe 0), później zapętlenie kodu

Kod: Zaznacz cały

int value1 = analogRead(Potencjometr1);
a następnie przeskalowanie odczytanej wartości

Kod: Zaznacz cały

byte time1 = map(value1, 0, 1023, 0, 255);
gdzie (0, 1023) oznacza rozdzielczość wejścia analogowego (czyli zostaje bez zmian), a w miejsce (0, 255) możesz wstawić dowolny przedział, który będzie odpowiadał minimalnemu i maksymalnemu czasowi działania (oczywiście w ms). Robisz tak dla każdego potencjometru z osobna, a następnie przy ustawieniu załączania poszczególnych diod kodem

Kod: Zaznacz cały

digitalWrite(led1, HIGH);
przy czasie trwania stanu wyżej określonego, ustawiasz zmienną time1, czyli np.

Kod: Zaznacz cały

delay(time1);
O definiowaniu wyjść (diod) nie wspominam, ponieważ uważam, że z tym chyba sobie poradzisz. A co do załączania przyciskiem, to nadajesz na początku pętli polecenie, w którym umieszczasz, że program czeka na podanie sygnału z przycisku, po którym wykonuje swój cykl, wraca do początku pętli i jeśli nie jest podany sygnał na wejście, to czeka. Mam nadzieję, że pomogłem. Z góry przepraszam jeśli coś jest niejasne, ale od jakiegoś czasu wogóle się nie dotykałem tej płytki, czego bardzo żałuję. Pozdrawiam
stanis69
Młodszy majsterkowicz
Posty: 9
Rejestracja: 10 gru 2014, 20:04

Re: Regulowany włącznik sekwencji

Post autor: stanis69 » 11 gru 2014, 07:19

Jak będzie miał dzisiaj czas to trochę pokombinuje, myślę że twoje podpowiedzi jakoś mnie naprawdzą na rozwiązanie.
zgred125
Majsterkowicz
Posty: 88
Rejestracja: 23 gru 2013, 22:39

Re: Regulowany włącznik sekwencji

Post autor: zgred125 » 11 gru 2014, 19:05

Jeżeli to ma być tylko włącznik to oczywiście funkcja delay wystarczy ale jeśli to coś ma robić coś jeszcze to dobrze jest oprzeć temat o czas od włączenia mC
stanis69
Młodszy majsterkowicz
Posty: 9
Rejestracja: 10 gru 2014, 20:04

Re: Regulowany włącznik sekwencji

Post autor: stanis69 » 11 gru 2014, 21:13

No to ma być właśnie zwykły włącznik, dokładnie to ma sterować załączaniem elektrozaworów w układzie pneumatycznym w odpowiednich odstępach czasu te diody to dałem tylko tak dla ułatwienia. Ale ma działać tak że wciskamy przycisk i jest tylko ta sekwencja ruchów i czeka na kolejny pstryk.
Więc chyba sam delay wystarczy. Dzisiaj chyba nie będę miał czasu ale przez weekend postaram się wyskrobać jakiś programik do sprawdzenia.
stanis69
Młodszy majsterkowicz
Posty: 9
Rejestracja: 10 gru 2014, 20:04

Re: Regulowany włącznik sekwencji

Post autor: stanis69 » 12 gru 2014, 11:40

Na szybko wyskrobałem taki programik, kompilator nie pokazuje błędów ale może jakieś słowo krytyki od innych użytkowników?



#define pot1 0
#define pot2 1
#define pot3 2
const int led1 = 10;
const int led2 = 11;
const int button = 12;
int buttonpos = 0;
byte time1 = 0;
byte time2 = 0;
byte time3 = 0;

void setup()
{
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(button, INPUT);
buttonpos = digitalRead(button);
int value1 = analogRead(pot1);
int value2 = analogRead(pot2);
int value3 = analogRead(pot3);
byte time1 = map(value1, 0, 1023, 10, 255);
byte time2 = map(value2, 0, 1023, 10, 255);
byte time3 = map(value3, 0, 1023, 10, 255);


}

void loop()
{

if (buttonpos == HIGH)
{
digitalWrite(led1, HIGH);
delay(time1);
delay(time2);
digitalWrite(led2, HIGH);
delay(time3);
}
else
{
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
}
}

Na płytce przetestuje w weekend bo na razie mało czasu i brak potencjometrów.
stiven
Złota rączka
Posty: 1644
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Regulowany włącznik sekwencji

Post autor: stiven » 12 gru 2014, 12:11

Kod: Zaznacz cały

#define pot1 0
#define pot2 1
#define pot3 2
const int led1 = 10;
const int led2 = 11;
const int button = 12;
int buttonpos = 0;
byte time1 = 0;
byte time2 = 0;
byte time3 = 0;

void setup()
{
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(button, INPUT_PULLUP);
}

void loop()
{
  value1 = analogRead(pot1);
  value2 = analogRead(pot2);
  value3 = analogRead(pot3);
  time1 = map(value1, 0, 1023, 10, 255);
  time2 = map(value2, 0, 1023, 10, 255);
  time3 = map(value3, 0, 1023, 10, 255);
  
  buttonpos = digitalRead(button);

  if (buttonpos == LOW)
  {
    digitalWrite(led1, HIGH);
    delay(time1);
	digitalWrite(led1, LOW);
    delay(time2);
    digitalWrite(led2, HIGH);
    delay(time3);
	digitalWrite(led2, LOW);
  }
}
Jeśli gdziekolwiej w programie napiszesz na przykład "byte time1" czyli zadeklarujesz zmienną time1 typu byte, to już nigdzie indziej nie możesz znowu napisać "byte time1", od tej pory możesz już tylko używać samej nazwy zmiennej, czyli temp1. Dlatego są dwa wyjścia teraz, po prostu usuwasz te deklaracje, które napisałeś na górze (byte time1 = 0 itd), one nie muszą być tu w tym programie zerowane przy deklaracji, albo usuwasz w pętli loop typy danych zmiennych, czyli int, byte. Ja wybrałem tą drugą opcję.
Dla przycisku najlepiej zadeklarować wejście tak: pinMode(button, INPUT_PULLUP), wtedy już żadnych dodatkowych elementów do przycisku nie trzeba dawać (deklarując jako zwykłe wejście INPUT, trzeba dać zewnętrzny rezystor podciągający do masy albo +5V). Daklarując tak, przycisk będzie zwierał do masy (INPUT_PULLUP powoduje wewnętrzne podciągnięcie wejścia na napięcia zasilania - +5V), przy wciśniętym przycisku będzie stan niski (if (buttonpos == LOW)).
http://arduino.cc/en/Tutorial/InputPullupSerial
http://arduino.cc/en/tutorial/button
Nie możesz tak użyć tego ifa z else, bo wyłączenie led1 i led2 nastąpiłoby w tym samym czasie, już po "wszystkim". Poprawiłem tak, żeby było dobrze.
Jeśli chciałbyś zrobić time1 = map(value1, 0, 1023, 10, 500), bo pisałeś wcześniej, że chcesz mieć czasy do 500ms, to wtedy zamiast deklarować time1 jako byte (byte time1), musiałbyś zmienić na int time1, ponieważ typ byte może mieć maksymalną wartość 255.
Odczytywanie wartości z potencjometrów i ich mapowanie musi być w pętli loop, bo to co jest w setup wykonuje się tylko raz przy uruchamianiu programu, czyli już później program nie sprawdzałby tego.
stanis69
Młodszy majsterkowicz
Posty: 9
Rejestracja: 10 gru 2014, 20:04

Re: Regulowany włącznik sekwencji

Post autor: stanis69 » 12 gru 2014, 12:56

Nie wiem czy dobrze wszystko zrozumiałem ale poprawiłem tak:

Kod: Zaznacz cały

#define pot1 0
#define pot2 1
#define pot3 2
const int led1 = 10;
const int led2 = 11;
const int button = 12;
int buttonpos = 0;

void setup() 
{
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(button, INPUT_PULLUP);
  buttonpos = digitalRead(button);
}
void loop() 
{
  int value1 = analogRead(pot1);
  int value2 = analogRead(pot2);
  int value3 = analogRead(pot3);
  int time1 = map(value1, 0, 1023, 10, 500);
  int time2 = map(value2, 0, 1023, 10, 500);
  int time3 = map(value3, 0, 1023, 10, 500);
   
if (buttonpos == LOW) 
  {
  digitalWrite(led1, HIGH);
  delay(time1);
  delay(time2);
  digitalWrite(led2, HIGH);
  delay(time3); 
  }
}
Czyli jeśli tak zostawię "if" to czynności w nim będą wykonywane po kolei od początku do końca? I jeszcze pytanie czy podczas trwania sekwencji ponowne wciśnięcie przycisku spowoduje jej zresetowanie? Chciał bym tego uniknąć. I jeszcze takie pojęcie jak drganie styków, chyba trzeba będzie tu zastosować lekarstwo na to (widziałem rozwiązanie tego problemu i dam rade to zastosować tylko będę musiał poszukać) z drugiej strony jeśli sekwencja nie będzie się resetowała w czasie pracy to chyba nie trzeba.
stiven
Złota rączka
Posty: 1644
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Regulowany włącznik sekwencji

Post autor: stiven » 12 gru 2014, 13:04

Ja już dałem program poprawiony, tylko rozpędziłem się i usunąłem przy value1 2 i 3 int, reszta już jest dobrze. Odczytywanie stanu przycisku tak jak potencjometrów musi być w loop.
Tak jak piszesz, kod jest wykonywany po kolei, jeśli warunek w ifie będzie spełniony, to on się wykona od początku do końca (nie ważne czy przycisk będzie ponownie wciskany, czy nie). Po ifie juz nic nie ma w kodzie, to program wróci na początek pętli loop i znowu sprawdzi stan potencjometrów, zmapuje wartości, no i znowu musi sprawdzić stan przycisku, potem if się wykona lub nie w zależności od tego czy przycisk będzie wciśnięty i znowu program wróci na początek loop i tak w kółko.

Kod: Zaznacz cały

#define pot1 0
#define pot2 1
#define pot3 2
const int led1 = 10;
const int led2 = 11;
const int button = 12;
int buttonpos = 0;
int time1 = 0;
int time2 = 0;
int time3 = 0;

void setup()
{
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(button, INPUT_PULLUP);
}

void loop()
{
  int value1 = analogRead(pot1);
  int value2 = analogRead(pot2);
  int value3 = analogRead(pot3);
  time1 = map(value1, 0, 1023, 10, 500);
  time2 = map(value2, 0, 1023, 10, 500);
  time3 = map(value3, 0, 1023, 10, 500);
 
  buttonpos = digitalRead(button);

  if (buttonpos == LOW)
  {
    digitalWrite(led1, HIGH);
    delay(time1);
   digitalWrite(led1, LOW);
    delay(time2);
    digitalWrite(led2, HIGH);
    delay(time3);
   digitalWrite(led2, LOW);
  }
}
stanis69
Młodszy majsterkowicz
Posty: 9
Rejestracja: 10 gru 2014, 20:04

Re: Regulowany włącznik sekwencji

Post autor: stanis69 » 12 gru 2014, 13:19

Ja te "int" zostawiłem w loopie bo zauważyłem że jak jest na początku to program waży 2x tyle a chcę go później na procka wsadzić więc doże jak by był możliwie najmniejszy to wejdzie na jakąś małą attinke. Tak zajmuje ponad 25 bitów a jak są inty w pętli to ok 13. W działaniu programu raczej nie powinno byś różnic? No i się zastanawiałem czy trzeba kazać mu gasić diody po czasie i okazało się że trzeba czyli powinno być już ok. Dzisiaj skompletuję części i będę testował.
stiven
Złota rączka
Posty: 1644
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Regulowany włącznik sekwencji

Post autor: stiven » 12 gru 2014, 13:21

Aha, jeszcze w setup trzeba dodać:

Kod: Zaznacz cały

digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
ponieważ jeśli się tego nie da, to zaraz po uruchomieniu programu ten stan na tych wyjściach może być wysoki i okazałoby się, że te diody byłyby włączone.

Kod: Zaznacz cały

#define pot1 0
#define pot2 1
#define pot3 2
const int led1 = 10;
const int led2 = 11;
const int button = 12;
int buttonpos = 0;
int time1 = 0;
int time2 = 0;
int time3 = 0;

void setup()
{
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(button, INPUT_PULLUP);

  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
}

void loop()
{
  int value1 = analogRead(pot1);
  int value2 = analogRead(pot2);
  int value3 = analogRead(pot3);
  time1 = map(value1, 0, 1023, 10, 500);
  time2 = map(value2, 0, 1023, 10, 500);
  time3 = map(value3, 0, 1023, 10, 500);
 
  buttonpos = digitalRead(button);

  if (buttonpos == LOW)
  {
    digitalWrite(led1, HIGH);
    delay(time1);
    digitalWrite(led1, LOW);
    delay(time2);
    digitalWrite(led2, HIGH);
    delay(time3);
    digitalWrite(led2, LOW);
  }
}
EDIT
nie ma znaczenia czy deklaracja będzie w loop czy wcześniej. Żeby zmniejszyć program to samo możesz zrobić z tymi zmiennymi time. Ja nawet nie wiedziałem, że to wpływa na wielkość programu.
stanis69
Młodszy majsterkowicz
Posty: 9
Rejestracja: 10 gru 2014, 20:04

Re: Regulowany włącznik sekwencji

Post autor: stanis69 » 12 gru 2014, 13:26

No ja to zauważyłem przez przypadek podczas robienia poprawek. Oczywiście wszystkie sugestie uwzględnię ;) Pozdrawiam i dzięki za pomoc.
stanis69
Młodszy majsterkowicz
Posty: 9
Rejestracja: 10 gru 2014, 20:04

Re: Regulowany włącznik sekwencji

Post autor: stanis69 » 12 gru 2014, 18:39

Pełen sukces, wszystko działa jak należy :D Dzięki wszystkim za pomoc. A dla zainteresowanych wersja finalna programu:

Kod: Zaznacz cały

#define pot1 0
#define pot2 1
#define pot3 2
const int led1 = 10;
const int led2 = 11;
const int button = 12;
int buttonpos = 0;

void setup() 
{
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(button, INPUT_PULLUP);
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
}
void loop() 
{
  
  int value1 = analogRead(pot1);
  int value2 = analogRead(pot2);
  int value3 = analogRead(pot3);
  int time1 = map(value1, 0, 1023, 10, 1000);
  int time2 = map(value2, 0, 1023, 10, 1000);
  int time3 = map(value3, 0, 1023, 10, 1000);
   
  int buttonpos = digitalRead(button);
  
if (buttonpos == LOW) 
  {
  digitalWrite(led1, HIGH);
  delay(time1);
  digitalWrite(led1, LOW);
  delay(time2);
  digitalWrite(led2, HIGH);
  delay(time3); 
  digitalWrite(led2, LOW);
  delay(100);
  }
}
A jeszcze jedno pytanie bo nie zwróciłem wcześniej na to uwagi, obecnie jeśli przytrzymam przycisk sekwencja się powtarza a dało by rade zrobić tak żeby kolejna sekwencja była po ponownym wciśnięciu przycisku? Czyli trzeba puścić przycisk i wcisnąć go ponownie.

Ważne że podczas trwania sekwencji ponowne wciśnięcie nie resetuje jej.
Ostatnio zmieniony 12 gru 2014, 18:47 przez stanis69, łącznie zmieniany 1 raz.
stiven
Złota rączka
Posty: 1644
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Regulowany włącznik sekwencji

Post autor: stiven » 12 gru 2014, 22:45

Tak, można.

Kod: Zaznacz cały

#define pot1 0
#define pot2 1
#define pot3 2
const int led1 = 10;
const int led2 = 11;
const int button = 12;
int buttonpos = 0;
int x = 0;

void setup()
{
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(button, INPUT_PULLUP);
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
}
void loop()
{
 
  int value1 = analogRead(pot1);
  int value2 = analogRead(pot2);
  int value3 = analogRead(pot3);
  int time1 = map(value1, 0, 1023, 10, 1000);
  int time2 = map(value2, 0, 1023, 10, 1000);
  int time3 = map(value3, 0, 1023, 10, 1000);
   
  int buttonpos = digitalRead(button);

if(buttonpos == HIGH) x = 0;
  
if(buttonpos == LOW && x == 0)
{
  x = 1;  
  
  digitalWrite(led1, HIGH);
  delay(time1);
  digitalWrite(led1, LOW);
  delay(time2);
  digitalWrite(led2, HIGH);
  delay(time3);
  digitalWrite(led2, LOW);
  delay(100);
  }
}
stanis69
Młodszy majsterkowicz
Posty: 9
Rejestracja: 10 gru 2014, 20:04

Re: Regulowany włącznik sekwencji

Post autor: stanis69 » 13 gru 2014, 07:22

Program działa jak należy. Dziękuję bardzo za pomoc. "Piwko" leci dla kolegi ;)
ODPOWIEDZ

Strony partnerskie: