Stránka 6 z 6
Re: regulátor otáček ( kroků ) krokového motoru
Napsal: 9. 9. 2015, 7:26
od Pidrman
Tak jsem asi lama
Nevím jak to zkrátit, nerad bych narušil ten program nějakou mezetru nebo smazáním mezery v programu.
Re: regulátor otáček ( kroků ) krokového motoru
Napsal: 9. 9. 2015, 9:57
od Thomeeque
Teď už nijak, post se dá upravit jen pár hodin po odeslání. Jinak jak jsem psal, uzavřenim do tagu CODE:
Pidrman píše:Co se týče programu, tak tady je..... jen jsem upravil podle rad typ hodnoty u
tick_count, změnil jsem původní hodnotu
int tick_count; na
unsigned long tick_count; :
Kód: Vybrat vše
#include <LiquidCrystal.h>
#include <TimerOne.h>
// buttons code
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5
// directions
#define FORWARD HIGH
#define BACKWARD LOW
// debounce time (milliseconds)
#define DEBOUNCE_TIME 200
// PINs for Pololu controller
#define PIN_STEP 2
#define PIN_DIR 3
// lookup table speed - ticks (interrupts)
const int speed_ticks[] = {-1, 600, 300, 200, 150, 120, 100, 86, 75, 67, 60, 55, 50, 46, 43};
// global variables
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int actual_speed;
int actual_direction;
int ticks;
unsigned long tick_count;
int button;
boolean debounce;
int previous_time;
// custom LCD square symbol for progress bar
byte square_symbol[8] = {
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
};
// string constants
char forward_arrow[] = "-->";
char backward_arrow[] = "<--";
void setup() {
// init the timer1, interrupt every 0.1ms
Timer1.initialize(100);
Timer1.attachInterrupt(timerIsr);
// init LCD and custom symbol
lcd.begin(16, 2);
lcd.setCursor(0,0);
lcd.createChar(0, square_symbol);
// pins direction
pinMode(PIN_STEP, OUTPUT);
pinMode(PIN_DIR, OUTPUT);
// initial values
actual_speed = 0;
actual_direction = FORWARD;
tick_count = 0;
ticks = -1;
debounce = false;
digitalWrite(PIN_DIR, actual_direction);
updateLCD();
}
void loop() {
// check if debounce active
if(debounce) {
button = btnNONE;
if(millis() > previous_time + DEBOUNCE_TIME) debounce = false;
} else button = read_buttons();
// if a button is pressed, start debounce time
if(button != btnNONE) {
previous_time = millis();
debounce = true;
}
// check which button was pressed
switch(button) {
case btnUP:
increase_speed();
break;
case btnDOWN:
decrease_speed();
break;
case btnLEFT:
change_direction(BACKWARD);
break;
case btnRIGHT:
change_direction(FORWARD);
break;
case btnSELECT:
emergency_stop();
break;
}
// finally update the LCD
updateLCD();
}
// increase speed if it's below the max (70)
void increase_speed() {
if(actual_speed < 70) {
actual_speed += 1;
tick_count = 0;
ticks = speed_ticks[actual_speed / 5];
}
}
// decrease speed if it's above the min (0)
void decrease_speed() {
if(actual_speed > 0) {
actual_speed -= 1;
tick_count = 0;
ticks = speed_ticks[actual_speed / 5];
}
}
// change direction if needed
void change_direction(int new_direction) {
if(actual_direction != new_direction) {
actual_direction = new_direction;
digitalWrite(PIN_DIR, actual_direction);
}
}
// emergency stop: speed 0
void emergency_stop() {
actual_speed = 0;
tick_count = 0;
ticks = speed_ticks[actual_speed / 5];
}
// update LCD
void updateLCD() {
// print first line:
// Speed: xxxRPM -> (or <-)
lcd.setCursor(0,0);
lcd.print("SPEED: ");
lcd.print(actual_speed);
lcd.print("RPM ");
lcd.setCursor(13,0);
if(actual_direction == FORWARD) lcd.print(forward_arrow);
else lcd.print(backward_arrow);
// print second line:
// progress bar [##### ]
// 15 speed steps: 0 - 5 - 10 - ... - 70
lcd.setCursor(0,1);
lcd.print("[");
for(int i = 1; i <= 14; i++) {
if(actual_speed > (5 * i) - 1) lcd.write(byte(0));
else lcd.print(" ");
}
lcd.print("]");
}
// timer1 interrupt function
void timerIsr() {
if(actual_speed == 0) return;
tick_count++;
if(tick_count == ticks) {
// make a step
digitalWrite(PIN_STEP, HIGH);
digitalWrite(PIN_STEP, LOW);
tick_count = 0;
}
}
// read buttons connected to a single analog pin
int read_buttons() {
int adc_key_in = analogRead(0);
if (adc_key_in > 1000) return btnNONE;
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 195) return btnUP;
if (adc_key_in < 380) return btnDOWN;
if (adc_key_in < 555) return btnLEFT;
if (adc_key_in < 790) return btnSELECT;
}
Citovanej kód to nijak nemodifikuje, jen ho to vhodně nastyluje. S formátovánim na githubu, pastebinu atp. se to nedá srovnat (takže pokud to máš tam, je to asi nejlepší možnost), ale je to imho lepší, než to prásknout do příspěvku jen tak.
Pidrman píše:Přípona není povolena.
Jak to mam tady sem vložit ?
Standardní trik je přidat ke jménu souboru ještě nějakou podporovanou příponu (tipuju, že třeba .txt by prošla) a upozornit na to.
T.
Re: regulátor otáček ( kroků ) krokového motoru
Napsal: 9. 9. 2015, 10:54
od Pidrman
Ok a díky, už jsem moudřejší

Re: regulátor otáček ( kroků ) krokového motoru
Napsal: 11. 9. 2015, 3:58
od Thomeeque
Pidrman (SZ) píše:Ahoj
Pomohl by jsi mi tedy s tím programem na to arduino prosím ? Já z toho fakt nejsem
Předem díky Honza
Ahoj, já si s arduinem nikdy nehrál. Nicméně program jsem si přečet a celkem ho i chápu. Pár věcí bych dělal jinak (to násobení-dělení 5ti kolem actual_speed např.), ale očividný důvod pro zamrzání tam nevidim. Jen tak baj voko tipuju, jestli by to nemohl být konflikt mezi obsluhou Timer1 a obsluhou LCD, ten Timer se volá s poměrně velkou frekvencí a kolem LCD se toho možná bude dít taky dost. Zkusil bych to o LCD obsluhu pro začátek zcela očesat. Ale nevim (autorovi to zjevně funguje - používáte stejný HW?), snad se ozve někdo znalejší.
T.
Btw. smysl změny tick_count z
int na
unsigned long moc nechápu (pokud ticks a speed_ticks zůstávájí
int), kde to bylo doporučeno?
Re: regulátor otáček ( kroků ) krokového motoru
Napsal: 11. 9. 2015, 4:58
od Mex
Já teda na používání knihovem moc nejsem. Ale docela se mi zalíbila (zatím jen teoreticky, ještě jsem nezkoušel) knihovna AccelStep.
S tou by se ta tvoje aplikace měla dát napsat na pár řádků (myslím to focení mimozemšťanů).
Re: regulátor otáček ( kroků ) krokového motoru
Napsal: 17. 9. 2015, 9:06
od teensy
Ahoj, program se nekousne, jen přestane generovat signál STEP kvůli striktní podmínce tick_count == ticks v obsluze přerušení timmeru. Správně by mělo být tick_count >= ticks. Protože pokud se program jednou dostane do situace, kdy je tick_count větší než ticks, bude se tick_count už jen zvětšovat a vzdalovat se tak od možnosti podmínku splnit
// timer1 interrupt function
void timerIsr()
{
...
tick_count++;
if(tick_count == ticks)
{
// make a step
digitalWrite(PIN_STEP, HIGH);
digitalWrite(PIN_STEP, LOW);
tick_count = 0;
}
}
Pozn: tiscks není konstanta. Řekněme že tick_count se už pomalu blíží hodnotě ticks. Procesor opustí obsluhu interruptu a vrátí se k vykonávání main loop, kde proměnnou ticks skokově změní na hodnotu menší než tick_count. Poté nastane další přerušení timeru a jsme v situaci, kdy je tick_count ostře větší než ticks. A v tomto blbém stavu program setrvá až do doby než typ long přeteče svůj rozsah.
Re: regulátor otáček ( kroků ) krokového motoru
Napsal: 17. 9. 2015, 9:37
od teensy
a také si prověř, zda doba trvání pulsu STEP, není pro tvůj driver příliš krátká. Tahle sekvence generuje puls v řádu mikrosekund a driver by na ni nemusel bezpečně reagovat.
// make a step
digitalWrite(PIN_STEP, HIGH);
digitalWrite(PIN_STEP, LOW);
Re: regulátor otáček ( kroků ) krokového motoru
Napsal: 17. 9. 2015, 9:50
od Thomeeque
Jo, to jsem si taky řikal.
Ale s těmi ticks nevim, všude, kde mění hodnotu ticks, zároveň nastavuje tick_count = 0.. ale zkusit to může.
Re: regulátor otáček ( kroků ) krokového motoru
Napsal: 18. 9. 2015, 5:41
od Pidrman
Tak problém je vyřešen a úspěšně vše funguje
V příloze je celý kod. akonec zabrala změny typ proměnné z "int" na "unsigned long"
Jinak všem moc a moc děkuji ................ tyhle poslední změny taky zkusím, chci se to naučit, tak si s tím budu pořád hrát
Honza