• 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
Problem z pętlą "for"
#1
Witam, 
jestem kompletnym nowicjuszem w dziedzinie programowania. Skonstruowałem slider do wykonywania filmów poklatkowych i chcę sterować nim poprzez Arduino Nano.  Napisałem swój pierwszy sketch, który nie działa prawidłowo. Chodzi mi o to, by opisana w kodzie funkcja "ruch()" była wykonana "i" razy. Niestety funkcja ta jest wywoływana nieskończenie wiele razy. Nie potrafię znaleźć błędu. Może ktoś mi pomoże? Będę wdzięczny.
 
Odpowiedź
#2
Bez kodu nie ruszymy.

Wysłane z mojego POCOPHONE F1 przy użyciu Tapatalka
 
Odpowiedź
#3
const int stepPin1 = 7; // Silnik nr 1 ruch poziomy
const int dirPin1 = 6;

const int stepPin2 = 9; //Silnik nr 2 ruch obrotowy głowicy
const int dirPin2 = 8;

const int Ik = 80; //Ilość kroków na 1mm
const int m = 0; // Czas odtwarzania (minuty)
const int s = 1; // Czas odtwarzania (sekundy)
const int Czof = m*60+s; //Czas odtwarzania filmu w sek przy 25 klatkach/s
const int Dp = 700; // Długość prowadnicy slidera w mm
const int Omk = 2; // Odstęp między klatkami w sek
const int Lz = Czof*25; //Liczba zdjęć
const int Lkk =Dp/(Czof*25)*Ik; // Liczba kroków między klatkami
const int Pred =200;

void setup() {

pinMode(stepPin1,OUTPUT);
pinMode(dirPin1,OUTPUT);
pinMode(stepPin2,OUTPUT);
pinMode(dirPin2,OUTPUT);
}


void loop() {

for(int i = 0; i < 3; i++){
ruch();}
}

void ruch(){

digitalWrite(dirPin1,HIGH);
digitalWrite(dirPin2,HIGH);

for(int x = 0; x < Lkk; x++) {


digitalWrite(stepPin1,HIGH);
delayMicroseconds(Pred);
digitalWrite(stepPin1,LOW);
delayMicroseconds(Pred);

digitalWrite(stepPin2,HIGH);
delayMicroseconds(Pred);
digitalWrite(stepPin2,LOW);
delayMicroseconds(Pred);

}
delay(1000*Omk);

}
 
Odpowiedź
#4
Dziwną matematykę zadajesz i z drugiej strony const jest stała zmienną

Lkk =Dp/(Czof*25)*Ik;

Lkk = 700/((0*60+1)*25)*80
Lkk = 700/2000
Lkk =0

przemyśl to

for(int x = 0; x < 0; x++)

Ale pewnie ci chodzi o

for(int i = 0; i < 3; i++){
ruch();}
}

Że funkcja ruch wykonuje się 3 razy ale to jest pętla i w sumie wykonuje się w nieskończoność bo po spełnieniu robi od nowa. Musiał byś dać coś co zablokuje ponowne wykonanie...

Np

bool flag =true;

void loop() {

if(flag){
for(int i = 0; i < 3; i++){
ruch();}
flag=false;
}
}

Wykona się wtedy tylko 4 razy
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#5
Bardzo dziękuję za pomoc.
Nie rozumiem tylko dlaczego przy zapisie "i<3" funkcja wywołuje się 3 razy a nie 4. Przy innych wartościach "i<" dzieje się to samo. Mnie to nie przeszkadza, ale chciałbym wiedzieć dlaczego.
Matematyka jest dobra. Z tego działania "Lkk = 700/((0*60+1)*25)*80" wynik wynosi 2240.
 
Odpowiedź
#6
Przecież to oczywiste, warunek i<3 jest spełniony dla 0,1,2 co łatwo policzyć na palcach jednej ręki, a dla i<=3 byłoby 0,1,2,3.
 
Odpowiedź
#7
Rzeczywiście banalnie proste. Dziękuję.
 
Odpowiedź
#8
(31-01-2022, 10:39)andrzejn napisał(a): Matematyka jest dobra. Z tego działania "Lkk = 700/((0*60+1)*25)*80" wynik wynosi 2240.

Dobra albo i nie Smile mnie bardziej przekonałby zapis (700*80)/((0*60+1)*25), bo wnioskuję, że to zamierzona kolejność działań, ale jak zwykle się czepiam.

Inna sprawa to otrzymane wyniki - zauważ, że znak '/' zwraca część całkowitą z dzielenia dwóch liczb dlatego w Twoim wypadku wszystko jest cacy, ale tylko do określonej wartości czasu - przy np. 50 minutach licznik ma wartość 56000, a mianownik 75025 czyli cały wynik będzie 0. Wartością graniczną jest w tym wypadku ok. 37 minut.



Wysłane z mojego POCOPHONE F1 przy użyciu Tapatalka
 
Odpowiedź
#9
Oczywiście masz rację. Zapis (700*80)/((0*60+1)*25) nie budzi wątpliwości.
W moim przypadku liczba minut nie przekroczy 2, a i tak w tej sytuacji trzeba by było zrobić 3000 zdjęć.
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości