SKETCH 4 - modifiche importanti al terzo Sketch
Nel tentativo di scrivere lo Sketch per la prima parte del GOTO, ho scoperto un notevole rallentamento nei processi tra arduino e stellarium che provocavano dei malfunzionamenti. Dopo giorni di continue prove, sono giunto alla conclusione che il problema era nel modo in cui venivano memorizzati i dati in arrivo da stellarium.
Inizialmente i dati in arrivo venivano memorizzati in una stringa (inputString) durante un ciclo di while per poi essere prelevati con .substring(n,m) e convertiti in interi con .toInt( ).
In questo Sketch, invece, i dati in arrivo vengono memorizzati in un array di tipo char, che ho chiamato "input", sempre attraverso un ciclo di while. Questo array è in grado di contenere fino a 20 caratteri, più che sufficienti per i dati del protocollo LX200. I singoli caratteri memorizzati nell'array vengono prelevati sfruttando l'indicizzazione che caratterizza questi oggetti.
Con questa diversa modalità di memorizzazione dei dati, il processo è migliorato notevolmente.
Nelle prove che avevo effettuato, fissavo la declinazione al valore di +64° 00' 00'' e facevo muovere il reticolo del telescopio lungo la coordinata di AR. Il moto era garantito incrementando di un secondo alla volta la coordinata AR e impostando un ritardo di 1ms nel ciclo di loop.
Con la memorizzazione dei dati nel modo illustrato nel terzo Sketch, il periodo di rotazione risultava più lungo del 35% rispetto al metodo utilizzato nello Sketch che vedete sotto.
Riprendiamo il commento dello Sketch di questa pagina. Durante il prelievo dei caratteri, questi vengono convertiti in interi di tipo long attraverso la funzione atol( ), da non confondersi con atoi( ) che converte in interi di tipo int. Per usare queste funzioni bisogna includere all'inizio dello Sketch una libreria: <stdlib.h>.
Perché usare le variabili long? Perché per gestire il GOTO bisogna convertire tutte le coordinate in arrivo in secondi (secondi di tempo e secondi di grado) e lavorare con queste unità di misura. Una coordinata di AR convertita in secondi può arrivare anche a 86400s superando di gran lunga la capacità di una variabile di tipo int. Una volta pronti per la trasmissione a stellarium, i dati verranno convertiti nuovamente per la coordinata di AR in HH:MM:SS invece per la coordinata di DEC in sDD° MM' SS' dove "s" sta ad indicare il segno (+ o -).
Questo Sketch non fa nulla di diverso rispetto al precedente, si limita cioè ad aggiornare le coordinate del telescopio per allinearsi con stellarium. Questo avviene, sempre se l'ingresso digitale 53 è a livello alto, uguagliando semplicemente due coppie di variabili invece che sei... Un bel risparmio. Altro miglioramento!
Non finisce qui, sono sparite anche altre 7 variabili, quelle che iniziavano per "rx..." in quanto superflue proprio per la conversione.
Infine, per rendere più leggibile lo Sketch, ho preferito raggruppare varie parti dello stesso in specifiche funzioni: void nome_funzione () che vengono all'occorrenza invocate nel loop o all'interno di altre funzioni.
Abbiamo quindi le funzioni:
Lo Sketch è stato totalmente stravolto, ma è migliorato ed ha contribuito ad arricchire questa esperienza.
Nel tentativo di scrivere lo Sketch per la prima parte del GOTO, ho scoperto un notevole rallentamento nei processi tra arduino e stellarium che provocavano dei malfunzionamenti. Dopo giorni di continue prove, sono giunto alla conclusione che il problema era nel modo in cui venivano memorizzati i dati in arrivo da stellarium.
Inizialmente i dati in arrivo venivano memorizzati in una stringa (inputString) durante un ciclo di while per poi essere prelevati con .substring(n,m) e convertiti in interi con .toInt( ).
In questo Sketch, invece, i dati in arrivo vengono memorizzati in un array di tipo char, che ho chiamato "input", sempre attraverso un ciclo di while. Questo array è in grado di contenere fino a 20 caratteri, più che sufficienti per i dati del protocollo LX200. I singoli caratteri memorizzati nell'array vengono prelevati sfruttando l'indicizzazione che caratterizza questi oggetti.
Con questa diversa modalità di memorizzazione dei dati, il processo è migliorato notevolmente.
Nelle prove che avevo effettuato, fissavo la declinazione al valore di +64° 00' 00'' e facevo muovere il reticolo del telescopio lungo la coordinata di AR. Il moto era garantito incrementando di un secondo alla volta la coordinata AR e impostando un ritardo di 1ms nel ciclo di loop.
Con la memorizzazione dei dati nel modo illustrato nel terzo Sketch, il periodo di rotazione risultava più lungo del 35% rispetto al metodo utilizzato nello Sketch che vedete sotto.
Riprendiamo il commento dello Sketch di questa pagina. Durante il prelievo dei caratteri, questi vengono convertiti in interi di tipo long attraverso la funzione atol( ), da non confondersi con atoi( ) che converte in interi di tipo int. Per usare queste funzioni bisogna includere all'inizio dello Sketch una libreria: <stdlib.h>.
Perché usare le variabili long? Perché per gestire il GOTO bisogna convertire tutte le coordinate in arrivo in secondi (secondi di tempo e secondi di grado) e lavorare con queste unità di misura. Una coordinata di AR convertita in secondi può arrivare anche a 86400s superando di gran lunga la capacità di una variabile di tipo int. Una volta pronti per la trasmissione a stellarium, i dati verranno convertiti nuovamente per la coordinata di AR in HH:MM:SS invece per la coordinata di DEC in sDD° MM' SS' dove "s" sta ad indicare il segno (+ o -).
Questo Sketch non fa nulla di diverso rispetto al precedente, si limita cioè ad aggiornare le coordinate del telescopio per allinearsi con stellarium. Questo avviene, sempre se l'ingresso digitale 53 è a livello alto, uguagliando semplicemente due coppie di variabili invece che sei... Un bel risparmio. Altro miglioramento!
Non finisce qui, sono sparite anche altre 7 variabili, quelle che iniziavano per "rx..." in quanto superflue proprio per la conversione.
Infine, per rendere più leggibile lo Sketch, ho preferito raggruppare varie parti dello stesso in specifiche funzioni: void nome_funzione () che vengono all'occorrenza invocate nel loop o all'interno di altre funzioni.
Abbiamo quindi le funzioni:
- communication( ) che prevede alla comunicazione da e per Stellarium;
- transmitAR( ) che converte la coordinata in HH:MM:SS e poi la trasmette a stellarium;
- transmitDEC( ) che converte la coordinata in sDD° MM' SS'' e poi la trasmette a stellarium;
- getAR( ) che preleva dall'array la coordinata ricevuta da stellarium e poi la converte in secondi;
- getDEC( ) che preleva dall'array la coordinata ricevuta da stellarium e poi la converte in secondi;
Lo Sketch è stato totalmente stravolto, ma è migliorato ed ha contribuito ad arricchire questa esperienza.
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Created 27 March 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 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 long ARtel, DECtel; // coordinate del telescopio espresse in secondi long ARtarget, DECtarget; // coordinate del target espresse in secondi long 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 void setup() { 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 } void loop() { if(Serial.available()>0){ communication(); } } //-------------------------------------------------------------------------------------------------------------------------------------------------------- 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; } } } //-------------------------------------------------------------------------------------------------------------------------------------------------------- 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 } //--------------------------------------------------------------------------------------------------------------------------------------------------------
ATTENZIONE: in data 30/03/2014 mi sono accorto di un bug nello Sketch che provocava un non corretto allineamento degli oggetti posti in prossimità dell'equatore celeste. Se il target si trovava ad una declinazione negativa inferiore al grado, non veniva letto il segno "meno". Il problema è stato risolto modificando leggermente la funzione get_DEC( ). Lo Sketch visibile sopra e il file per il download sotto sono già aggiornati. Mi scuso per il disguido e invito tutti a segnalarmi eventuali altri errori, grazie.
quarto_sketch.ino | |
File Size: | 7 kb |
File Type: | ino |
log_telescopeserver1_4.txt | |
File Size: | 26 kb |
File Type: | txt |
Se scaricate lo Sketch e lo confrontate con il precedente, noterete la rapidità con cui aggiorna le coordinate allineando in telescopio con stellarium. Inoltre nel passare da un punto ad un altro del cielo, il cursore si sposta con continuità lungo la volta celeste del planetario.
Il programma è pronto per un successivo sviluppo...
Il programma è pronto per un successivo sviluppo...