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.
regulátor otáček ( kroků ) krokového motoru
Teď už nijak, post se dá upravit jen pár hodin po odeslání. Jinak jak jsem psal, uzavřenim do tagu CODE:
T.
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: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; }
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.Pidrman píše:Přípona není povolena.
Jak to mam tady sem vložit ?
T.
mimooborová naplavenina • kolowratský zázrak™ • NPS • GCU • HirthCalc • ncDP.ino
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ší.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
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?
mimooborová naplavenina • kolowratský zázrak™ • NPS • GCU • HirthCalc • ncDP.ino
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.
// 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.
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);
// make a step
digitalWrite(PIN_STEP, HIGH);
digitalWrite(PIN_STEP, LOW);
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.
Ale s těmi ticks nevim, všude, kde mění hodnotu ticks, zároveň nastavuje tick_count = 0.. ale zkusit to může.
mimooborová naplavenina • kolowratský zázrak™ • NPS • GCU • HirthCalc • ncDP.ino
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
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
- Přílohy
-
- cntrSpeedDir_uprava.zip
- (1.82 KiB) Staženo 181 x