SKETCH 8 - colleghiamo gli encoder (IN LAVORAZIONE)
Adesso possiamo procedere con il collegamento degli encoder. Per la mia montatura equatoriale autocostruita, ho deciso di utilizzare due encoder incrementali prodotti dalla CUI: AMT102-V. Questi encoder, oltre ad essere affidabili e poco costosi, forniscono 16 differenti risoluzioni, selezionabili con dei dipswitch, da 48 a 2048 ppr e sono facilmente collegabili a motori e parti meccaniche.
Ho scelto di collegare l'encoder alla vite senza fine per poter compensare il backlash (seppur piccolo) del motoriduttore.
Nell'immagine seguente sono visibili i collegamenti elettrici.
Adesso possiamo procedere con il collegamento degli encoder. Per la mia montatura equatoriale autocostruita, ho deciso di utilizzare due encoder incrementali prodotti dalla CUI: AMT102-V. Questi encoder, oltre ad essere affidabili e poco costosi, forniscono 16 differenti risoluzioni, selezionabili con dei dipswitch, da 48 a 2048 ppr e sono facilmente collegabili a motori e parti meccaniche.
Ho scelto di collegare l'encoder alla vite senza fine per poter compensare il backlash (seppur piccolo) del motoriduttore.
Nell'immagine seguente sono visibili i collegamenti elettrici.
Avevo scritto il seguente sketch un po' di getto, il progetto era stato accantonato per mancanza di tempo, ma a seguito di più di una richiesta pubblico gli ultimi esperimenti. In questo sketch il funzionamento dei due motori durante il GOTO è simulato dall'accensione del led collegato al pin 13 di arduino. Il led si spegnerà quando entrambe le coordinate del telescopio hanno raggiunto quelle del target (era preferibile usare due led, uno per ogni coordinata, ma andavo di fretta).
Ricordo che inizialmente questo sketch mi aveva dato qualche problema, ma poi sembrava funzionare. Quindi lo pubblico con il beneficio del dubbio sul suo corretto funzionamento. Non vogliatemene male :-)
Prometto che appena avrò un po' di tempo riprenderò in mano il lavoro (anche perché la mia montatura è lì che aspetta...), intanto avete materiale su cui divertirvi :-)
Ricordo che inizialmente questo sketch mi aveva dato qualche problema, ma poi sembrava funzionare. Quindi lo pubblico con il beneficio del dubbio sul suo corretto funzionamento. Non vogliatemene male :-)
Prometto che appena avrò un po' di tempo riprenderò in mano il lavoro (anche perché la mia montatura è lì che aspetta...), intanto avete materiale su cui divertirvi :-)
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Created 26 April 2014 * * by EDC * * http://epsilonphoto.weebly.com/ * * * * This program is free software, you can redistribute it and/or modify. * * Is in the public domain, it only has a didactic purpose and you can modify it * * to your liking. I do not provide any guarantee for any damage it may cause * * to property or persons. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <stdlib.h> const int led = 13; const int buttonAlign = 53; // pin in cui l'interruttore abilita l'allineamento con una stella int buttonState = 0; // variabile in cui arduino andrà a leggere lo stato logico di buttonAlign char input[20]; // array di char in cui verranno memorizzati i dati in ingresso char txAR[10]; // array di char in cui verranno memorizzati i dati in uscita char txDEC[11]; // array di char in cui verranno memorizzati i dati in uscita volatile long ARtel, DECtel; // coordinate del telescopio espresse in secondi long ARtarget, DECtarget; // coordinate del target espresse in secondi long ARdist, ARdiff, DECdiff; // differenza tra le coordinate del target e del telescopio long arHH, arMM, arSS; // coordinata AR del telescopio da trasmattere a stellarium char SIGNtel; // segno della DEC: 43 = + 45 = - long decDEG, decMM, decSS; // coordinata DEC del telescopio da trasmettere a stellarium long memoDEC; // memorizza DECtarget (serve se si attraversa il polo celeste) long latitude; long betaN, deltaN, betaS, deltaS; int A = 0; boolean circumpolar, enablegoto; #define AR_clock 2 #define DEC_clock 3 #define AR_dir 4 #define DEC_dir 5 void setup() { pinMode (led, OUTPUT); pinMode(buttonAlign, INPUT); Serial.begin(9600); ARtarget = ARtel = 22300; // coordinata iniziale di AR (in secondi) per visualizzare il reticolo del telescopio DECtarget = DECtel = 35105; // coordinata iniziale di DEC (in secondi) per visualizzare il reticolo del telescopio latitude = 165600; circumpolar = false; enablegoto = false; attachInterrupt(0, AR_encoder, RISING); attachInterrupt(1, DEC_encoder, RISING); } void loop() { if(Serial.available()>0){ communication(); } ARdiff = ARtarget - ARtel; DECdiff = DECtarget - DECtel; if ((A == 1) && (abs(DECdiff) < 9)){ // una volta arrivato al polo, inverte di 12 ore la coordinata AR del telescopio A = 0; if(ARtel >= 43200){ ARtel = ARtel - 43200; }else{ ARtel = ARtel + 43200; } DECtarget = memoDEC; // ristabilisce le coordinate originali del target DECdiff = DECtarget - DECtel; } if ((A == 0) && (abs(DECdiff) < 9) && (ARdiff == 0)){ digitalWrite (led, LOW); enablegoto = false; // disabilita il goto } if((enablegoto == true) && ((ARdiff != 0) || (abs(DECdiff) > 9))){ goto_object(); } } //-------------------------------------------------------------------------------------------------------------------------------------------------------- void communication(){ int i=0; input[i++] = Serial.read(); delay(5); while((input[i++] = Serial.read()) != '#'){ delay(5); } input[i]='\0'; if(input[1]==':' && input[2]=='G' && input[3]=='R' && input[4]=='#'){ // con il comando #:GR# stellarium chiede l'invio della coordinata di AR transmitAR(); } if(input[1]==':' && input[2]=='G' && input[3]=='D' && input[4]=='#'){ // con il comando #:GD# stellarium chiede l'invio della coordinata di AR transmitDEC(); } if(input[1]==':' && input[2]=='Q' && input[3]=='#'){ // con il comando #:Q# stellarium chiede l'arresto dei motori // inviare l'arresto ai motori } if(input[0]==':' && input[1]=='S' && input[2]=='r'){ // con il comando :Sr stellarium invia la coordinata di AR getAR(); } if(input[0]==':' && input[1]=='S' && input[2]=='d'){ // con il comando :Sd stellarium invia la coordinata di DEC getDEC(); } if(input[0]==':' && input[1]=='M' && input[2]=='S' && input[3]=='#'){ // con il comando :MS# stellarium chiede se la rotazione è possibile Serial.print("0"); buttonState = digitalRead(buttonAlign); // legge se l'interruttore per l'allineamento iniziale è su ON o OFF if (buttonState == HIGH) { // se HIGH aggiorna le coordinate, altrimenti proseguià con il GOTO ARtel = ARtarget; DECtel = DECtarget; }else{ enablegoto = true; // abilita il goto } } } //-------------------------------------------------------------------------------------------------------------------------------------------------------- void transmitAR(){ // trasmissione dati nella forma HH:MM:SS# arHH = ARtel/3600; // ricava le ore della coordinata AR del telescopio arMM = (ARtel-arHH*3600)/60; // ricava i minuti della coordinata AR del telescopio arSS = (ARtel-arHH*3600)-arMM*60; // ricava i secondi della coordinata AR del telescopio sprintf(txAR, "%02d:%02d:%02d#", int(arHH), int(arMM), int(arSS)); Serial.print(txAR); } //-------------------------------------------------------------------------------------------------------------------------------------------------------- void transmitDEC(){ // trasmissione dati nella forma sDDßMM:SS# (dove s è il segno + o -) (DECtel < 0) ? SIGNtel = 45: SIGNtel = 43; // controllo del segno della coordinata DEC del telescopio decDEG = abs(DECtel)/3600; // ricava i gradi della coordinata DEC del telescopio decMM = (abs(DECtel) - decDEG*3600)/60; // ricava i minuti della coordinata DEC del telescopio decSS = (abs(DECtel) - decDEG*3600) - decMM*60; // ricava i secondi della coordinata DEC del telescopio sprintf(txDEC, "%c%02d%c%02d:%02d#", SIGNtel, int(decDEG), 223, int(decMM), int(decSS)); Serial.print(txDEC); } //-------------------------------------------------------------------------------------------------------------------------------------------------------- void getAR(){ // riceve la coordinata AR del target nel formato :Sr HH:MM:SS# Serial.print("1"); ARtarget = (atol(input+4))*3600 + (atol(input+7))*60 + atol(input+10); // converte in secondi la coordinata AR del target } //-------------------------------------------------------------------------------------------------------------------------------------------------------- void getDEC(){ // riceve la coordinata AR del target nel formato :Sd +DDßMM:SS# Serial.print("1"); DECtarget = (atol(input+5))*3600 + (atol(input+8))*60 + atol(input+11); // converte in secondi la coordinata DEC del target if (input[4] == '-'){ // per una corretta conversione ha prelevato solo la parte numerale DECtarget *=(-1); // (cioè senza il segno) pertanto se la coordinata DEC è negativa, dopo } // la conversione in secondi viene moltiplica per -1 memoDEC = DECtarget; betaN = (324000-DECtel)+(324000-DECtarget); deltaN = betaN + ((648000-betaN)/2); betaS = ((-324000)-DECtel)+((-324000)-DECtarget); deltaS = abs(betaS) + ((648000-abs(betaS))/2); if (((latitude > 0) && (DECtarget > (324000-latitude))) || ((latitude < 0) && (DECtarget < ((-324000)-latitude)))) { // verifica se il target è circumpolare circumpolar = true; }else{ circumpolar = false; } ARdist = ARtarget - ARtel; if (ARdist < (-43200)){ // calcola la distanza minima in AR ARdist = ARdist + 86400; } if (ARdist > 43200){ // calcola la distanza minima in AR ARdist = ARdist - 86400; } if ((latitude > 0) && (circumpolar = true) && ((abs(ARdist)*15) > deltaN)){ // ARdist*15 perché le grandezze devono essere omogenee (AR = 24h, DEC = 360°) DECtarget = 324000; // imposta la via per il polo nord celeste A = 1; } if ((latitude < 0) && (circumpolar = true) && ((abs(ARdist)*15) > deltaS)){ // ARdist*15 perché le grandezze devono essere omogenee (AR = 24h, DEC = 360°) DECtarget = (-324000); // imposta la via per il polo sud celeste A = 1; } } //-------------------------------------------------------------------------------------------------------------------------------------------------------- void goto_object(){ if (A != 1){ // il movimento in AR è disabilitato (A = 1) se si deve passare per il polo if ((ARdiff >0 && ARdiff <= 43200) || (ARdiff <=(-43200))){ // confronta le coordinate di AR e sceglie la via più breve per raggiungere il target go_east(); } if ((ARdiff > 43200) || (ARdiff <0 && ARdiff > (-43200))){ go_west(); } } if (DECtarget > DECtel){ // confronta le coordinate di DEC e sceglie la via più breve per raggiungere il target go_north(); } if (DECtarget < DECtel){ go_south(); } } //-------------------------------------------------------------------------------------------------------------------------------------------------------- void go_east(){ digitalWrite (led, HIGH); // inviare il comando al motore AR di ruotare per incrementare la coordinata AR } //-------------------------------------------------------------------------------------------------------------------------------------------------------- void go_west(){ digitalWrite (led, HIGH); // inviare il comando al motore AR di ruotare per decrementare la coordinata AR } //-------------------------------------------------------------------------------------------------------------------------------------------------------- void go_north(){ digitalWrite (led, HIGH); // inviare il comando al motore DEC di ruotare per incrementare la coordinata DEC } //-------------------------------------------------------------------------------------------------------------------------------------------------------- void go_south(){ digitalWrite (led, HIGH); // inviare il comando al motore DEC di ruotare per decrementare la coordinata DEC } //-------------------------------------------------------------------------------------------------------------------------------------------------------- void AR_encoder(){ // encoder AR programmato a 400 ppr if (digitalRead(AR_dir) == 1){ ARtel = (ARtel*100)+72; // incrementa AR di 0.72s ARtel = round(float(ARtel)/100); if(ARtel >= 86400){ ARtel = ARtel - 86400; } } else { ARtel = (ARtel*100)-72; // decrementa AR di 0.72s ARtel = round(float(ARtel)/100); if(ARtel < 0){ ARtel = ARtel + 86400; } } } //-------------------------------------------------------------------------------------------------------------------------------------------------------- void DEC_encoder(){ // encoder DEC programmato a 800 ppr if (digitalRead(DEC_dir) == 1){ DECtel += 9; // incrementa DEC di 9s (d'arco) } else { DECtel -= 9; // decrementa DEC di 9s (d'arco) } } //--------------------------------------------------------------------------------------------------------------------------------------------------------
sketch_8.ino | |
File Size: | 13 kb |
File Type: | ino |