Stepper Motor 17HS4401 come derotatore di campo per telescopio

Salve a tutti.
Vorrei costruire un derotatore di campo per telescopio per permettere alla mia camera di fare riprese anche in deep sky, a lunga esposizione su montatura altazimutale. Ho un passo passo, precisamente il 17HS440 (se non erro detto anche NEMA17), che controllerò con Arduino via bluetooth tramite app. Drive utilizzato A4899. Qui nessun problema, il fatto è che ovviamente gli step del motore (200 passi) non andrebbero bene per derotare con dei micropassi la camera e quindi avevo pensato pertanto di aggiungergli dei riduttori planetari, nonchè di settare il driver A4899 a 1/16 (è il massimo che si può fare con questo driver per fare i microstep). Il problema è che se non erro, per non avere problemi durante le acquisizioni la camera dovrebbe ruotare di 1.15 arcosec/sec, giusto o sto dicendo una sciocchezza? Quindi con questo motore e il suo relativo driver qualcuno saprebbe precisamente che rapporto di riduzione dovrei applicare? So cheSpero che qualcuno possa aiutarmi a sciogliere questo dubbio. Grazie in anticipo.

Uhm, aspetta ... ma 1 grado non sono 3600 secondi d'arco ? (per cui 1 arcosecondo=0.00027777777777778 gradi), quindi 1.15 arcosecondi=0,000319444 gradi ...

Per fare un giro di 360 gradi in 24 ore, dato che in 24 ore ci sono 86400 secondi, non dovresti invece muovere di 0,0041666666666667 gradi al secondo( cioe' 15 arcosecondi) ? ... perche' se muovi di 0,000319444 gradi (1.15 arcosecondi) al secondo, in 24 ore avrai ruotato solo di circa 27.56 gradi ... :thinking:

Hai ragione. Devo muovere precisamente ad 1 arcosecondo, ho detto una cavolata prima. Quindi considerando che al motore farei fare 1 step al secondo, e dato che ogni step di questo motore corrispondono a 1,8°(consideriamo che c'è anche un margine di più o meno 0.9 er questi step motor), considerando che dovrei muovere 0,004167 gradi al secondo, quindi il rapporto di riduzione dovrebbe essere di 432:1 giusto?

come numero di step, si, con un motore da 200 step per 360 gradi ed uno step al secondo, con una riduzione di 432:1 avresti 360 gradi in 24 ore.

Se pero' vuoi usare i microstep per avere una maggiore fluidita' di movimento devi ricordarti di pilotare gli step proporzionalmente piu in fretta ... se imposti mezzo step, devi pilotarne uno ogni mezzo secondo, se usi un quarto di step, uno ogni quarto di secondo, e cosi via, in quel modo la meccanica dovrebbe avere un movimento piu fluido e con meno saltelli ... se vuoi usare il sedicesimo di step, il motore dovra' fare un microstep ogni 62,5 millisecondi (anche se secondo me' a questo livello un'ottavo di step ed un passo ogni 125mS dovrebbero essere piu che accettabili), ma a questo punto il problema maggiore potrebbe essere la precisione dovuta all'accumulo di errore se il programma che pilota il motore deve fare anche altro (perche presumo tu voglia realizzarlo con Arduino o comunque con una MCU simile)

Credo si possa comunque compensare l'errore, o calcolando il tempo occupato dalle altre operazioni e sottraendolo al ritardo (da fare con millis, niente delay, salvo che il programma non debba fare assolutamente nient'altro che pilotare il motore), o con altro, credo che comunque la parte hardware dovra' usare o una MCU con quarzo (il risuonatore ceramico dell'Arduino classico non e' sufficentemente preciso sulle 24 ore), o anche con un 328 standalone con oscillatore TXCO, ancora piu preciso.

No, no, nessun errore, basta che la scheda sia una scheda almeno quarzata (e non, come indichi, con un risuonatore ceramico) e poi si usa un timer che genera un interrupt con la cadenza voluta, indipendentemente da ciò che poi fa il programma :wink:

Guglielmo

Be', allora in quel modo probabilmente puo generare anche i 62.5mS per usare il sedicesimo di step (il timer lo consente ?), avrebbe un movimento quasi liscio come un sistema con motore DC, e non dovrebbe avere alcuna vibrazione sull'immagine, se realizza bene la meccanica :+1:

Il massimo sarebbe trovare un riduttore con l'annullamento del gioco incorporato, ma probabilmente e' chiedere troppo al mercato hobbystico.

62.5 mS sono 16 Hz, per cui su un Arduino a 16 MHz, usando Timer1:

// AVR Timer CTC Interrupts Calculator
// v. 8
// http://www.arduinoslovakia.eu/application/timer-calculator
// Microcontroller: ATmega328P, clock: 16MHz

void setupTimer1() {
  noInterrupts();
  // Clear registers
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;

  // 16 Hz (16000000/((15624+1)*64))
  OCR1A = 15624;
  // CTC
  TCCR1B |= (1 << WGM12);
  // Prescaler 64
  TCCR1B |= (1 << CS11) | (1 << CS10);
  // Output Compare Match A Interrupt Enable
  TIMSK1 |= (1 << OCIE1A);
  interrupts();
}

void setup() {
  ...
  setupTimer1();
  ...
}

void loop() {
  ...
  ...
}

ISR(TIMER1_COMPA_vect) {
  ...
  ...
  // questa ISR viene chiamata ogni 62.5 mS
  ...
  ...
}

Guglielmo

... oppure, sempre pensando all'utilizzo di un Timer, magari anche su un Arduino UNO con risuonatore ceramico, si può aumentare notevolmente la precisione usando, come clock esterno per detto Timer il segnale estremamente stabile che genera un RTC di tipo DS3231 che, ricordiamo, ha sia l'uscita fissa a 32768 Hz che quella programmabile a frequenze inferiori. :wink:

Oltretutto, con una frequenza così bassa, si puô anche usare Timer2, che è ad 8 bit, lasciandosi libero, magari per altri scopi, Timer1 che è invece a 16 bit.

Guglielmo

Grazie mille ancora per tutti i consigli.
Siccome una riduzione di 432:1 è difficile da trovare in giro (o meglio esiste anche ma sui 300 euro per un progetto a scopo hobbistico, non ne valeva la pena), avevo pensato, anzichè far fare un microsteps ogni 62,5mS, di utilizzare i microsteps a 1/16 ad ogni secondo, così da portare il rapporto a 27:1 (qui ci trovo senza problemi delle riduzioni planetarie a costi più fattibili). Lo so, sarà meno fluido e meno "continuo" il movimento, però così almeno riesco a reperire facilmente la riduzione 27:1. Avevo anche pensato di progettare quella 432:1 in 3D ma poi l'ho esclusa onde evitare che potessero esserci problemi di precisione.

Inoltre ringrazio anche l'intervento di @gpb01 e avevo già messo in conto che dovevo avere un timer molto preciso per far sì che i singoli microsteps avessero più precisamente il movimento ad ogni secondo (e non pià a 62.5mS,). Avevo pensato all'uso di un RTC ma Guglielmo mi ha illuminato con Timer1. Me lo studierò piano, piano. Grazie mille.

Con i 32768 Hz del RTC devi usare Timer2 ... datasheet, da pagina 150 in poi ed in particolare le sezioni "18.3 Timer/Counter Clock Sources" e "18.9 Asynchronous Operation of Timer/Counter2" (visto che è un clock esterno NON in sincrono con il clock della MCU).

Guglielmo

1 Like

Hai controllato se ne trovi 54:1 o 108:1 ? ... anche se solo ogni mezzo secondo o un quarto di secondo, il movimento sarebbe migliore.

EDIT: se proprio serve si possono accoppiare in cascata anche piu gearbox, per ottenere il rapporto desiderato, oppure un rapporto diverso ma che ti consenta sempre una migliore risoluzione (solo come esempio, il tuo 27:1 ed un 10:1, diventerebbe un 270:1 e potresti pilotare i sedicesimi di step con 10Hz)

1 Like

Ho trovato un motore già ridotto a 51:1 ad un prezzo accessibile, quindi ogni step farebbe 0,035 gradi. Penso che in tal caso si dovrebbe modificare il lasso di tempo tra uno step e un altro.
Quindi se per la volta celeste abbiamo 0,004167 in un secondo, il motore che compie 0,035 gradi ogni step dovrebbe muoversi di 8,4 secondi a step. Quindi suddividendo gli step in 16esimi, quindi ogni microstep dovrebbe essere 525mS. Giusto?

Guglielmo con Timer1 variando il prescaler non riesco a raggiungere 525mS giusto? Dovrei trovare un'altra strada?

Che MCU? Che clock?

Guglielmo

All'inizio avevo pensato ESP32, ma lascerò perdere la questione bluetooth e app dalla quale potevo gestire il motore. Quindi ho optato per fargli fare solo quello, ossia ogni microstep a 525ms. Quindi andrò per un ATMEGA328p con il suo classico oscillatore 16MHz, ossia un Arduino Uno che ho trovato nel cassetto

Come ti è stato detto, purtroppo Arduino UNO NON monta un quarzo, ma un risuonatore ceramico, la cui precisione è decisamente inferiore e non te lo consiglio su applicazioni con periodo così lunghi come quelli che occorrono a te.

Devi ripiegare sul RTC esterno e il Timer2.

Guglielmo

Aspetta però ... stavo rileggendomi il datasheet ...
... in effetti anche Timer0 e Timer1 hanno un pin che si chiama "External Clock", per Timer0 è il pin T0 (PD4) e per Timer1 è il pin T1 (PD5).

Quindi ... bisognerebbe provare, impostando il registro TCCR1B, che controlla il Timer1, nei Bit 2:0 – CS12:0: Clock Select, per avere, ad esempio, "External clock source on T1 pin. Clock on falling edge." (1 1 0) e programmando opportunamento gli altri registri, se puoi avere l'interrupt con la frequenza che ti serve ... :roll_eyes:

Dico questo perché, sulla UNO, i due pin che servono per dare il clock esterno al Timer2, ovvero TOSC1 e TOSC2 sono già usati per il risuonatore ceramico visto che, gli stessi pin, sono anche XTAL1 e XTAL2 :confused:

Guglielmo

Si, in effetti sui pin PB5 e PB6 di TOSC1 e TOSC2 c'è XTAL1 e XTAL2 per il risuonatore...
E se faccio un ATEMEGA328P standalone (ho già diverse PCB che mi sono progettato ancora da saldare) con un oscillatore TXCO? Potrebbe andare? Inoltre quale sarebbe consigliato? Sempre un 16Mhz?

Si, perché è una delle frequenze previste dal "core" di Arduino ... così non devi fare nessuna modifica :wink:

Con Timer1, che è a 16 bit, ce la fai ... 525mS sono pari a circa 1.90476190 Hz e quindi:

// AVR Timer CTC Interrupts Calculator
// v. 8
// http://www.arduinoslovakia.eu/application/timer-calculator
// Microcontroller: ATmega328P, clock: 16MHz


void setupTimer1() {
  noInterrupts();
  // Clear registers
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;

  // 1.904790930147507 Hz (16000000/((32811+1)*256))
  OCR1A = 32811;
  // CTC
  TCCR1B |= (1 << WGM12);
  // Prescaler 256
  TCCR1B |= (1 << CS12);
  // Output Compare Match A Interrupt Enable
  TIMSK1 |= (1 << OCIE1A);
  interrupts();
}

void setup() {
  setupTimer1();
}

void loop() {
}

ISR(TIMER1_COMPA_vect) {
}

Guglielmo

Che però NON sono esattamente 525mS, ma 524.992mS ... che comunque, su tempi lunghi, introduce un errore.

Era meglio il valore che avevamo calcolato prima. al post #7 :grin:

Guglielmo