Arduino nebo STM, jak naprogramovat STEP/DIR řízení
Ahoj,
potřeboval bych nakopnutí pro blbce (neprogramátora), jak naprogramovat řízení krokového motoru pro jednoduché polohování.
Potřebuji popojet o nějakou zadanou vzdálenost s rozjezdem a dojezdem po rampě s možností ručního zastavení od obsluhy po krátké rampě.
V Arduinu jsem použil knihovnu Accelstepper a narazil jsem na problémy:
1) Pokud použiju mód řízení jako indexovanou osu, tak samotný rozjezd a dojezd na žádanou vzdálenost po rampě funguje, akorát jsem nevymyslel, jak do toho zakomponovat zastavení od stisknutí tlačítka.
2) Když použiju mód rychlostního řízení, tak mi to koliduje s knihovnou pro řízení LCD displeje - obsluha LCD 4x20 znaků trvá moc dlouho. Plus schodová rampa generovaná programem není moc dobrá.
Aplikace je pojezd foťáku, který je na dlouhé tyči na vozíku. Problém je , že bez rampy se tyč rozklepe a uklidnění po zastavení trvá moc dlouho. Druhý problém je, že se kolem toho motá moc lidí, takže je tam optická závora a stop tlačítko, aby se to zastavilo, když se někdo připlete do cesty.
potřeboval bych nakopnutí pro blbce (neprogramátora), jak naprogramovat řízení krokového motoru pro jednoduché polohování.
Potřebuji popojet o nějakou zadanou vzdálenost s rozjezdem a dojezdem po rampě s možností ručního zastavení od obsluhy po krátké rampě.
V Arduinu jsem použil knihovnu Accelstepper a narazil jsem na problémy:
1) Pokud použiju mód řízení jako indexovanou osu, tak samotný rozjezd a dojezd na žádanou vzdálenost po rampě funguje, akorát jsem nevymyslel, jak do toho zakomponovat zastavení od stisknutí tlačítka.
2) Když použiju mód rychlostního řízení, tak mi to koliduje s knihovnou pro řízení LCD displeje - obsluha LCD 4x20 znaků trvá moc dlouho. Plus schodová rampa generovaná programem není moc dobrá.
Aplikace je pojezd foťáku, který je na dlouhé tyči na vozíku. Problém je , že bez rampy se tyč rozklepe a uklidnění po zastavení trvá moc dlouho. Druhý problém je, že se kolem toho motá moc lidí, takže je tam optická závora a stop tlačítko, aby se to zastavilo, když se někdo připlete do cesty.
Elektrikář, mechaniku dělám jen z donucení a jako hobby.
Můžeš ten mód nějak blíže specifikovat? Na https://github.com/waspinator/AccelStepper nic o těchto módech na první pohled nevidím. Možná přilož ukázku tvého kódu.
mimooborová naplavenina • kolowratský zázrak™ • NPS • GCU • HirthCalc • ncDP.ino
kód je zkopírovaný příklad runToPosition () a runSpeedToPosition ()Thomeeque píše: ↑4. 4. 2023, 10:17Můžeš ten mód nějak blíže specifikovat? Na https://github.com/waspinator/AccelStepper nic o těchto módech na první pohled nevidím. Možná přilož ukázku tvého kódu.
- to první zahájí pohyb a na další příkaz to skočí až po dojetí na pozici. Během pojezdu není možné vykonávat jiný kód.
- to druhé se volá jako funkce ve smyčce a vrátí příznak po dojetí na pozici. Bohužel to neumí rampy.
Elektrikář, mechaniku dělám jen z donucení a jako hobby.
Mě přijde, že toto by mělo podle popisu podporovat rampu:
Ale pokud píšeš, že to ani nedělá moc plynulé rampy, tak to asi stejně nemá smysl moc ladit.
Jakou steprate potřebuješ? Do toho displaye posíláš co, aktuální pozici? V ASCII módu nebo tam posíláš nějakou grafiku?
Kód: Vybrat vše
// Run the motor to implement speed and acceleration in order to proceed to the target position
// You must call this at least once per step, preferably in your main loop
// If the motor is in the desired position, the cost is very small
// returns true if the motor is still running to the target position.
boolean AccelStepper::run()
{
if (runSpeed())
computeNewSpeed();
return _speed != 0.0 || distanceToGo() != 0;
}
Jakou steprate potřebuješ? Do toho displaye posíláš co, aktuální pozici? V ASCII módu nebo tam posíláš nějakou grafiku?
mimooborová naplavenina • kolowratský zázrak™ • NPS • GCU • HirthCalc • ncDP.ino
To použití "computeNewSpeed()" bude ono. To mně nenapadlo. Vyzkouším.Thomeeque píše: ↑4. 4. 2023, 11:36 Mě přijde, že toto by mělo podle popisu podporovat rampu:
Ale pokud píšeš, že to ani nedělá moc plynulé rampy, tak to asi stejně nemá smysl moc ladit.Kód: Vybrat vše
// Run the motor to implement speed and acceleration in order to proceed to the target position // You must call this at least once per step, preferably in your main loop // If the motor is in the desired position, the cost is very small // returns true if the motor is still running to the target position. boolean AccelStepper::run() { if (runSpeed()) computeNewSpeed(); return _speed != 0.0 || distanceToGo() != 0; }
Jakou steprate potřebuješ? Do toho displaye posíláš co, aktuální pozici? V ASCII módu nebo tam posíláš nějakou grafiku?
Na tom LCD se nastavuje rychlost přejezdu a vzdálenost o jakou se má přejet. Na malou vzdálenost si obsluha přejíždí joystickem a na větší si zadá o kolik cm to má přejet a pak jen tlačítkem potvrdí na kterou stranu to má odjet aby nemusel držet joystick protože přejetí celé dráhy na max rychlost trvá asi 1,5 minuty. Během přejezdu není potřeba nic zobrazovat.
Elektrikář, mechaniku dělám jen z donucení a jako hobby.
To boolean AccelStepper::run() je přímo příkaz té knihovny, použítí viz https://github.com/waspinator/AccelStep ... Bounce.pde
Edit: dá se využít i jeho návratová hodnota, imho elegantnější:
Edit: dá se využít i jeho návratová hodnota, imho elegantnější:
Kód: Vybrat vše
void loop() {
if (!stepper.run()) {
// If at the end of travel go to the other end
stepper.moveTo(-stepper.currentPosition());
}
}
mimooborová naplavenina • kolowratský zázrak™ • NPS • GCU • HirthCalc • ncDP.ino
Tohle mám právě na obsluhu od ovládání joystickem. Problém je, že se musí stepper.run volat dostatečně často, minimálně jednou na krok, a není tam místo pro vložení obsluhy něčeho časově náročnějšího jako je to LCD.Thomeeque píše: ↑4. 4. 2023, 12:00 To boolean AccelStepper::run() je přímo příkaz té knihovny, použítí viz https://github.com/waspinator/AccelStep ... Bounce.pde
Edit: dá se využít i jeho návratová hodnota, imho elegantnější:
Kód: Vybrat vše
void loop() { if (!stepper.run()) { // If at the end of travel go to the other end stepper.moveTo(-stepper.currentPosition()); } }
GRBL to má vyřešené lépe přes přerušení na pozadí, ale je to momentálně vysoce nad moje možnosti pochopení, abych to byl schopný přizpůsobit na moje potřeby.
Elektrikář, mechaniku dělám jen z donucení a jako hobby.
Knihovna Accel Stepper je sice uživatelsky přívětivá, ale protože vše počítá v reálném čase, nezbývá už moc času na nic jiného. Já osobně jsem ji přestal používat a rampy si buď počítám nebo nebo čtu z matice. Na LCD pak zapisovat když motor stojí. Do generování kroků prostě zobrazení dát nejde. Ovšem dá se to "očůrat" tím že arduina použiješ dvě. Jedno pracuje a druhé zobrazuje. Použil jsem to už hodně složitých aplikacích 2x a pohoda. Překvapivě pokud použiješ STM32 s emulovaným wiringem, tak je výsledek ještě pomalejší.
To dvouprocesorové řešení mně napadlo, ale přišel jsem na to, že během přejezdu zapisovat na LCD nepotřebuju. Jenom jsem nepřišel na cestu, jak dosáhnout zastavení po rampě od zmáčknutí tlačítka.lubbez píše: ↑4. 4. 2023, 4:36 Knihovna Accel Stepper je sice uživatelsky přívětivá, ale protože vše počítá v reálném čase, nezbývá už moc času na nic jiného. Já osobně jsem ji přestal používat a rampy si buď počítám nebo nebo čtu z matice. Na LCD pak zapisovat když motor stojí. Do generování kroků prostě zobrazení dát nejde. Ovšem dá se to "očůrat" tím že arduina použiješ dvě. Jedno pracuje a druhé zobrazuje. Použil jsem to už hodně složitých aplikacích 2x a pohoda. Překvapivě pokud použiješ STM32 s emulovaným wiringem, tak je výsledek ještě pomalejší.
Displej je nějaký klon HD44xxxx má to vícedrátové řízení (nemám tam I2C), pak tam mám ještě maticovou klávesnici.
Frekvence stačí 4kHz.
Elektrikář, mechaniku dělám jen z donucení a jako hobby.
budu řešit něco podobného a po testech různých knihoven mě na většinu pohybů stačí tupé cyklování step výstupu s definovanou prodlevou.
plynulost vyřeším jednoduchým prodlužováním / zkracováním prodlevy, jednoduchá for smyčka.
výhoda je že si do každého pohybu doplním sledování potřebných podmínek, můžu tak snadno houmovat na snímače, zpomalit před plánovanou polohou apod.
akorát to je řízení step by step
plynulost vyřeším jednoduchým prodlužováním / zkracováním prodlevy, jednoduchá for smyčka.
výhoda je že si do každého pohybu doplním sledování potřebných podmínek, můžu tak snadno houmovat na snímače, zpomalit před plánovanou polohou apod.
akorát to je řízení step by step
Na konci poznávacího procesu je omyl zcela vyvrácen a my nevíme nic. Zato to víme správně.
Ta "knihovna" je ve formě zdrojového kódu, tak si ji můžeš upravit.
Jde v podstatě o to, doplnit do třídy funkci Stop(), která nastaví požadovanou pozici na takovou, kterou by pohon dosáhl při brždění z aktuální rychlosti na nulu.
Když se podíváš do funkce pro získání nové rychlosti, pak tam najdeš výraz
long stepsToStop = (long)((_speed * _speed) / (2.0 * _acceleration));
který to řeší.
Takže jde pouze o to změnit aktuální požadovanou pozici na pozici spočítanou z aktuální skutečné pozice plus nebo minus (podle směru otáčení) stepsToStop.
Ta funkce už tam jemiv píše: ↑4. 4. 2023, 9:35 Jde v podstatě o to, doplnit do třídy funkci Stop(), která nastaví požadovanou pozici na takovou, kterou by pohon dosáhl při brždění z aktuální rychlosti na nulu.
Když se podíváš do funkce pro získání nové rychlosti, pak tam najdeš výraz
long stepsToStop = (long)((_speed * _speed) / (2.0 * _acceleration));
který to řeší.
Kód: Vybrat vše
void AccelStepper::stop()
{
if (_speed != 0.0) {
long stepsToStop = (long)((_speed * _speed) / (2.0 * _acceleration)) + 1; // Equation 16 (+integer rounding)
if (_speed > 0)
move(stepsToStop);
else
move(-stepsToStop);
}
}
mimooborová naplavenina • kolowratský zázrak™ • NPS • GCU • HirthCalc • ncDP.ino
No vidíš, vymyslel jsem kolo.Thomeeque píše: ↑5. 4. 2023, 9:15Ta funkce už tam jemiv píše: ↑4. 4. 2023, 9:35 Jde v podstatě o to, doplnit do třídy funkci Stop(), která nastaví požadovanou pozici na takovou, kterou by pohon dosáhl při brždění z aktuální rychlosti na nulu.
Když se podíváš do funkce pro získání nové rychlosti, pak tam najdeš výraz
long stepsToStop = (long)((_speed * _speed) / (2.0 * _acceleration));
který to řeší.
Po jejím zavolání stále musíš volat ve smyčce run(), dokud nevrátí false, což je asi trochu matoucí.Kód: Vybrat vše
void AccelStepper::stop() { if (_speed != 0.0) { long stepsToStop = (long)((_speed * _speed) / (2.0 * _acceleration)) + 1; // Equation 16 (+integer rounding) if (_speed > 0) move(stepsToStop); else move(-stepsToStop); } }
To, že se musí run volat ve smyčce i nadále, plyne celkem jasně ze způsobu obsluhy. Po pravdě nejlepší je udělat si irq rutinu od nějakého časovače a volat to z ní. Pak to neotravuje.
Myslím, že jsem to pochopil. Na stránce s popisem knihovny AccelStepper je odkaz na http://web.archive.org/web/201407051439 ... rofile.pdf
Na poslední stránce je schéma jak to generovat pomocí hw prostředků CPU. Ve výpočtech stačí jen nahradit úhel za dráhu a je to
Na poslední stránce je schéma jak to generovat pomocí hw prostředků CPU. Ve výpočtech stačí jen nahradit úhel za dráhu a je to
Elektrikář, mechaniku dělám jen z donucení a jako hobby.