Jak ustalić stabilne 200 kroków na obrót.
-
Autor tematu - Nowy użytkownik, używaj wyszukiwarki
- Posty w temacie: 2
- Posty: 3
- Rejestracja: 07 sie 2011, 19:06
- Lokalizacja: Dzierzoniów
Jak ustalić stabilne 200 kroków na obrót.
Wybaczcie, że pytanie z poziomu piaskownicy, ale jakoś nie mogę sobie poradzić.
odpaliłem programik z zastosowaniem micros. O ile da się regulować szybkość o tyle nie wymyśliłem jak wymusić ileś tam obrotów. Mam typowy silnik 200-krokowy. A jak zachowywałby się silnik z inną ilością kroków czy też przekładnią ? Próbowałem różnych sposobów, ale wyniki watpliwe. Silnik zatrzymywał się w przypadkowych pozycjach...stąd moje podejrzenie, że trzeba takiego patentu jak np: int liczba_krokow_na_obrot = 200;
Oto kod:
const int stepPin = 8;
unsigned long stepperTimer;
int currentStepperSpeedDelay = 500; //changing this value changes the stepper motor speed.
byte stepInState = 0; //high or low state for next step
int stepCounter; // na razie nie używane
int stepperDirection; //stores the current direction of rotation
int targetSteps = 0;
void setup() {
pinMode(stepPin, OUTPUT);
}
void loop() {
unsigned long currentMicros;
currentMicros = micros();
if ((currentMicros - stepperTimer) >= currentStepperSpeedDelay) {
stepperTimer = currentMicros;
if (stepInState > 0) {
stepInState = 0;
} else {
stepInState = 1;
}
digitalWrite(stepPin, stepInState );
//stepCounter++;
}
}
odpaliłem programik z zastosowaniem micros. O ile da się regulować szybkość o tyle nie wymyśliłem jak wymusić ileś tam obrotów. Mam typowy silnik 200-krokowy. A jak zachowywałby się silnik z inną ilością kroków czy też przekładnią ? Próbowałem różnych sposobów, ale wyniki watpliwe. Silnik zatrzymywał się w przypadkowych pozycjach...stąd moje podejrzenie, że trzeba takiego patentu jak np: int liczba_krokow_na_obrot = 200;
Oto kod:
const int stepPin = 8;
unsigned long stepperTimer;
int currentStepperSpeedDelay = 500; //changing this value changes the stepper motor speed.
byte stepInState = 0; //high or low state for next step
int stepCounter; // na razie nie używane
int stepperDirection; //stores the current direction of rotation
int targetSteps = 0;
void setup() {
pinMode(stepPin, OUTPUT);
}
void loop() {
unsigned long currentMicros;
currentMicros = micros();
if ((currentMicros - stepperTimer) >= currentStepperSpeedDelay) {
stepperTimer = currentMicros;
if (stepInState > 0) {
stepInState = 0;
} else {
stepInState = 1;
}
digitalWrite(stepPin, stepInState );
//stepCounter++;
}
}
-
- Lider FORUM (min. 2000)
- Posty w temacie: 2
- Posty: 9320
- Rejestracja: 26 lut 2011, 23:24
- Lokalizacja: mazowieckie
Re: Jak ustalić stabilne 200 kroków na obrót.
Przecież tu nie ma żadnej pętli liczącej kroki, no to jakim cudem silnik miałby się zatrzymać w zadanym położeniu?
A potem będziesz miał taki problem, że po wykonaniu zadanego ruchu silnik będzie stał i sam nie ruszy, więc znowu trzeba będzie dodać jakiś "start", może i "stop", albo "kierunek".
Jak już wszystko nadludzkim wysiłkiem zrobisz, to zrozumiesz, że twój program się do niczego nie nadaje, bo nie ma ramp i nie da się sterować powyżej pewnej żółwiej prędkości...
Tak więc najlepszym rozwiązaniem będzie użycie gotowej biblioteki, jakiś accelstepper, czy coś w tym stylu.
Osobiście uważam, że jakość tych bibliotek jest tragiczna, ale zawsze to lepiej niż wyważać otwarte drzwi i wynajdować koło na nowo...
A potem będziesz miał taki problem, że po wykonaniu zadanego ruchu silnik będzie stał i sam nie ruszy, więc znowu trzeba będzie dodać jakiś "start", może i "stop", albo "kierunek".
Jak już wszystko nadludzkim wysiłkiem zrobisz, to zrozumiesz, że twój program się do niczego nie nadaje, bo nie ma ramp i nie da się sterować powyżej pewnej żółwiej prędkości...
Tak więc najlepszym rozwiązaniem będzie użycie gotowej biblioteki, jakiś accelstepper, czy coś w tym stylu.
Osobiście uważam, że jakość tych bibliotek jest tragiczna, ale zawsze to lepiej niż wyważać otwarte drzwi i wynajdować koło na nowo...
-
Autor tematu - Nowy użytkownik, używaj wyszukiwarki
- Posty w temacie: 2
- Posty: 3
- Rejestracja: 07 sie 2011, 19:06
- Lokalizacja: Dzierzoniów
Re: Jak ustalić stabilne 200 kroków na obrót.
Dzięki, słuszne uwagi, ale nadal jestem ciekawy jak ustalić tu liczbę kroków na obrót. Oczywiście zdaję sobie sprawę, że potrzebne jest zliczanie i to jestem w stanie zrobić. ale nie zmienia to faktu, że Accelstepper totalnie mi nie odpowiada ( dziwne zależności wpływające np na szybkość silnika, niezgodną z założeniami itd.) Szukam prostego rozwiązania opartego na millis czy micros bo potrzebuję sterowania równocześnie dwoma silnikami (nawijarka). Wiem, że można zastosować enkoder ( ale tu jestem jeszcze w lesie).
Kto walczy ten się uczy.....( he he, czasami -ze trzy lata w jednej klasie, ale zawsze !) Próbuję dokonać zmian w poniższym programie, na razie z miernymi wynikami. Jeśli mógłbyś polecić prostą do bólu bibliotekę z millis byłbym bardzo zobowiązany.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
int cycle_delay = 1; //np. 100 ms opóźnienia przy sterowaniu pinu 8 - czylu PUL+. Zatem pełny prostokąt zamknie się w 200ms. Czyli jeden krok silnika będzie co 200ms (5 razy na sekundę)
int liczba_krokow = 0;
int liczba_krokow_na_obrot = 200;
int zw_na_warstwe = 0;
float zmienna_srednica = 0.10;
int zmienna_start = 0;
bool kierunek = false;
const int menu_zwoje = 1;
const int menu_srednica = 2;
const int menu_start = 3;
int wybrana_funkcja = 1; //wstepnie wybrana funkcja men
void setup() {
Serial.begin(9600);
lcd.init();
pinMode(3, OUTPUT); // Motor 2 kierunek
digitalWrite(3, kierunek);
pinMode(2, OUTPUT); // Motor 2 posuw
pinMode(8, OUTPUT); // Motor 1
pinMode(10, INPUT_PULLUP); // menu
pinMode(5, INPUT_PULLUP); //zmniejsz
pinMode(6, INPUT_PULLUP); //zwiększ
pinMode(7, INPUT_PULLUP); // start
lcd.begin(16, 2);
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("zw_na_warstwe");
}
void loop() {
switch (wybrana_funkcja) {
case 1:
zwoje();
lcd.print(" ");
break;
case 2:
srednica();
break;
case 3:
start();
break;
default:
wybrana_funkcja = 1;
break;
}
/* ten kawalek kodu powoduje po nacisnieciu guzika na pin10 przejscie do kolejnego elementu menu*/
if (digitalRead(10) == LOW) {
wybrana_funkcja++;
delay(500);
if (wybrana_funkcja > 3) {
wybrana_funkcja = 1;
}
}
}
void zwoje() {
lcd.setCursor(0, 0); //dzięki tej sekcji będzie od razu widać po naciśnięciu klawisza 10 do jakiej funkcji program wchodzi.
lcd.print(" ");
lcd.setCursor(0, 0);
lcd.print("Zwoje: ");
lcd.print(zw_na_warstwe);
if (digitalRead(6) == LOW) {
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 0);
zw_na_warstwe++;
lcd.print("Zwoje: ");
lcd.print(zw_na_warstwe);
lcd.print(" ");
delay(300);
}
if (digitalRead(5) == LOW) {
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 0);
zw_na_warstwe--;
lcd.print("Zwoje: ");
lcd.print(zw_na_warstwe);
//lcd.print(" ");
delay(300);
}
}
void srednica() {
lcd.setCursor(0, 0); //dzięki tej sekcji będzie od razu widać po naciśnięciu klawisza 10 do jakiej funkcji program wchodzi.
lcd.print(" ");
lcd.setCursor(0, 0);
lcd.print("Srednica ");
lcd.print(zmienna_srednica);
lcd.print(" ");
if (digitalRead(6) == LOW) {
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 0);
zmienna_srednica += 0.01;
lcd.print("Srednica: ");
lcd.print(zmienna_srednica);
lcd.print(" ");
delay(300);
}
if (digitalRead(5) == LOW) {
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 0);
zmienna_srednica -= 0.01;
lcd.print("Srednica: ");
lcd.print(zmienna_srednica);
lcd.print(" ");
delay(300);
}
}
void krok() {
digitalWrite(8, LOW);
delay(cycle_delay);
digitalWrite(8, HIGH);
delay(cycle_delay);
}
void start() {
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 0);
lcd.print("Start: ");
if (digitalRead(7) == LOW) {
digitalWrite(8, HIGH);
digitalWrite(3, kierunek);
obracaj();
kierunek=!kierunek;
}
}
void obracaj() {
for (int obr = 0; obr < zw_na_warstwe; obr++) {
for (int i = 0; i < liczba_krokow_na_obrot; i++) {
krok(); //tu wywołujemy funkcję "krok", która wysyła pojedyńczy prostokąt na pin 8
}
przesun_o_zwoj(); //wywołuję funkcję, która obróci MOTOR2 o 50 kroków
}
}
//funkcja wykonująca krok silnika 2 - MOTOR2
void krok_m2() {
digitalWrite(2, LOW);
delay(cycle_delay);
digitalWrite(2, HIGH);
delay(cycle_delay);
}
void przesun_o_zwoj() {
for (int j = 0; j < zmienna_srednica * 200; j++) {
krok_m2();
}
}
Kto walczy ten się uczy.....( he he, czasami -ze trzy lata w jednej klasie, ale zawsze !) Próbuję dokonać zmian w poniższym programie, na razie z miernymi wynikami. Jeśli mógłbyś polecić prostą do bólu bibliotekę z millis byłbym bardzo zobowiązany.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
int cycle_delay = 1; //np. 100 ms opóźnienia przy sterowaniu pinu 8 - czylu PUL+. Zatem pełny prostokąt zamknie się w 200ms. Czyli jeden krok silnika będzie co 200ms (5 razy na sekundę)
int liczba_krokow = 0;
int liczba_krokow_na_obrot = 200;
int zw_na_warstwe = 0;
float zmienna_srednica = 0.10;
int zmienna_start = 0;
bool kierunek = false;
const int menu_zwoje = 1;
const int menu_srednica = 2;
const int menu_start = 3;
int wybrana_funkcja = 1; //wstepnie wybrana funkcja men
void setup() {
Serial.begin(9600);
lcd.init();
pinMode(3, OUTPUT); // Motor 2 kierunek
digitalWrite(3, kierunek);
pinMode(2, OUTPUT); // Motor 2 posuw
pinMode(8, OUTPUT); // Motor 1
pinMode(10, INPUT_PULLUP); // menu
pinMode(5, INPUT_PULLUP); //zmniejsz
pinMode(6, INPUT_PULLUP); //zwiększ
pinMode(7, INPUT_PULLUP); // start
lcd.begin(16, 2);
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("zw_na_warstwe");
}
void loop() {
switch (wybrana_funkcja) {
case 1:
zwoje();
lcd.print(" ");
break;
case 2:
srednica();
break;
case 3:
start();
break;
default:
wybrana_funkcja = 1;
break;
}
/* ten kawalek kodu powoduje po nacisnieciu guzika na pin10 przejscie do kolejnego elementu menu*/
if (digitalRead(10) == LOW) {
wybrana_funkcja++;
delay(500);
if (wybrana_funkcja > 3) {
wybrana_funkcja = 1;
}
}
}
void zwoje() {
lcd.setCursor(0, 0); //dzięki tej sekcji będzie od razu widać po naciśnięciu klawisza 10 do jakiej funkcji program wchodzi.
lcd.print(" ");
lcd.setCursor(0, 0);
lcd.print("Zwoje: ");
lcd.print(zw_na_warstwe);
if (digitalRead(6) == LOW) {
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 0);
zw_na_warstwe++;
lcd.print("Zwoje: ");
lcd.print(zw_na_warstwe);
lcd.print(" ");
delay(300);
}
if (digitalRead(5) == LOW) {
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 0);
zw_na_warstwe--;
lcd.print("Zwoje: ");
lcd.print(zw_na_warstwe);
//lcd.print(" ");
delay(300);
}
}
void srednica() {
lcd.setCursor(0, 0); //dzięki tej sekcji będzie od razu widać po naciśnięciu klawisza 10 do jakiej funkcji program wchodzi.
lcd.print(" ");
lcd.setCursor(0, 0);
lcd.print("Srednica ");
lcd.print(zmienna_srednica);
lcd.print(" ");
if (digitalRead(6) == LOW) {
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 0);
zmienna_srednica += 0.01;
lcd.print("Srednica: ");
lcd.print(zmienna_srednica);
lcd.print(" ");
delay(300);
}
if (digitalRead(5) == LOW) {
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 0);
zmienna_srednica -= 0.01;
lcd.print("Srednica: ");
lcd.print(zmienna_srednica);
lcd.print(" ");
delay(300);
}
}
void krok() {
digitalWrite(8, LOW);
delay(cycle_delay);
digitalWrite(8, HIGH);
delay(cycle_delay);
}
void start() {
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 0);
lcd.print("Start: ");
if (digitalRead(7) == LOW) {
digitalWrite(8, HIGH);
digitalWrite(3, kierunek);
obracaj();
kierunek=!kierunek;
}
}
void obracaj() {
for (int obr = 0; obr < zw_na_warstwe; obr++) {
for (int i = 0; i < liczba_krokow_na_obrot; i++) {
krok(); //tu wywołujemy funkcję "krok", która wysyła pojedyńczy prostokąt na pin 8
}
przesun_o_zwoj(); //wywołuję funkcję, która obróci MOTOR2 o 50 kroków
}
}
//funkcja wykonująca krok silnika 2 - MOTOR2
void krok_m2() {
digitalWrite(2, LOW);
delay(cycle_delay);
digitalWrite(2, HIGH);
delay(cycle_delay);
}
void przesun_o_zwoj() {
for (int j = 0; j < zmienna_srednica * 200; j++) {
krok_m2();
}
}
-
- Lider FORUM (min. 2000)
- Posty w temacie: 2
- Posty: 9320
- Rejestracja: 26 lut 2011, 23:24
- Lokalizacja: mazowieckie
Re: Jak ustalić stabilne 200 kroków na obrót.
Nie mógłbym, za to mogę dać Ci świetną radę.
Kup takie silniki https://www.aliexpress.com/item/1005006333855394.html
Albo podobne.
Serwokrokowce mają własne rampy i dają się rozkręcić do 1000 obr/min.
Dzięki temu, tak prostym programem jaki piszesz, da się wysterować nawijarkę o zupełnie użytecznych parametrach.
No bo jak czytam, że planujesz jeden obrót na czterdzieści sekund, to mam pewność, że nie wiesz o czym piszesz...
-
- Moderator
-
Lider FORUM (min. 2000)
- Posty w temacie: 2
- Posty: 4463
- Rejestracja: 13 wrz 2008, 22:40
- Lokalizacja: PL,OP
Re: Jak ustalić stabilne 200 kroków na obrót.
W accelstepper to trzeba tylko w pętli wykonywać .run() i wcześniej zadeklarować parametry ruchu.
Przykład:
Kod: Zaznacz cały
AccelStepper osX(1, pinSTEPX, pinDIRX); // pin - STEP, pin - DIR
osX.setMaxSpeed(2000.0);
osX.setSpeed(2000.0);
osX.setAcceleration(50000.0);
Kod: Zaznacz cały
// rozkaz ruchu jednej osi:
osX.moveTo(osX.currentPosition()+3880400);
// przykladowa kontrola ruchu z dodatkowymi przerywaczami ruchu:
while( n < 4 && osX.distanceToGo()!=0 && koniec == 1 ) {
osX.run() ; // wymagane ciagle wywolywanie dla plynnego ruchu
INDU = digitalRead(pinINDU) ; // dodatkowo czujnik indukcyjny zatrzymuje ruch
if ( INDU==0 ) { ale po kilku wykryciach, co stosowalem gdy zdarzaly sie zaklocenia przy czujniku mechanicznym
Serial.print("i"); // to mi sygnalizowalo zadzialanie czujnika mechanicznego
n=n+1; // i po zliczeniu do zadanej wyżej w warunku granicy przerwało dzialanie
}
if ( czasn < millis() ) { // to wywolanie yield() potrzebne jest na esp8266 zeby soft watch dog nie restartowal procka
yield() ; czasn = millis() + 200 ;
koniec = int(pcf.read(5)) ; // i przy okazji co te 0,2s sprawdzam czy z ekspadera nie ma sygnalu konca.
if (koniec == 0 ) {
Serial.print("!");// sygnalizacja że stąd jest zatrzymanie
}
}
} ;
zachowanie spokoju oznacza zdolności do działania
ᐃ 🜂 ⃤ ꕔ △ 𐊅 ∆ ▵ ߡ
ᐃ 🜂 ⃤ ꕔ △ 𐊅 ∆ ▵ ߡ
-
- Lider FORUM (min. 2000)
- Posty w temacie: 1
- Posty: 3775
- Rejestracja: 21 kwie 2011, 10:58
- Lokalizacja: ::
Re: Jak ustalić stabilne 200 kroków na obrót.
Mylisz się. On robi nawijarkę, i tak powolny ruch może być tam potrzebny.
Owszem.
Tylko że użycie accelstepper nic tu nie wnosi.
Podobnie użycie dowolnej biblioteki używającej millis.
anszun ma konkretny problem tylko nie umie go nazwać.
Tu chodzi o to żeby sterować dwoma albo i trzeba silnikami na raz (synchronicznie).
Żadna prosta biblioteka do sterowania silnikami tego nie zapewnia.
Póki co anszun ma problem nawet z jednym silnikiem. Ale nie dlatego że nie umie sterować jednym. Już przecież zakładał temat o sterowaniu jednego silnika, i dostał odpowiedz.
Teraz znowu coś kombinuje, tylko widocznie sam nie wie co. Tamten program mu nie pasował, i on sam nie wie dlaczego.
Ale ja wiem: bo on sterował tylko jednym silnikiem, a do nawijarki trzeba minimum dwoma na raz.
-
- Moderator
-
Lider FORUM (min. 2000)
- Posty w temacie: 2
- Posty: 4463
- Rejestracja: 13 wrz 2008, 22:40
- Lokalizacja: PL,OP
Re: Jak ustalić stabilne 200 kroków na obrót.
zachowanie spokoju oznacza zdolności do działania
ᐃ 🜂 ⃤ ꕔ △ 𐊅 ∆ ▵ ߡ
ᐃ 🜂 ⃤ ꕔ △ 𐊅 ∆ ▵ ߡ