Carlo.Martinelli ha scritto:
Non ho trovato il sorgente probabilmente Ivaldo non lo ha messo a disposizione.
Svelato il terzo segreto di Fatima:
Codice:
/*
* AstroFocus - Servo fuocheggiatore ASCOM basato su Arduino
* Progetto di Ivaldo Cervini e Matteo Quadri
* Da un'idea di Simone Martina
* Codici di Ivaldo Cervini
*
* 23 luglio 2014 - Versione 2.0.0.0
* 17 novembre 2015 - Versione 2.0.0.1
* 25 dicembre 2015 - Versione 3.0.0.0
* 26 dicembre 2015 - Versione 3.0.0.1
* 27 dicembre 2015 - Versione 3.0.0.2
* 6 gennaio 2016 - Versione 3.0.0.3
* 7 gennaio 2016 - Versione 3.0.0.4
* 7 gennaio 2016 - Versione 3.1.0.0
* 7 gennaio 2016 - Versione 3.1.0.1
* 26 gennaio 2017 - Versione 4.0.0.0
* 9 marzo 2017 - Versione 4.0.1.0
* 12 marzo 2017 - Versione 5.0.0.0
* 5 febbraio 2019 - Versione 5.0.1.0
*
*
* Hardware per questa versione:
* - Arduino Uno
* - Arduino Motor Shield R3
* - Bipolar Steper Motor
* - Adafruit MCP9808 High Accuracy Temperature Sensor
*
* Compatibile con il software di controllo:
* - AstroFocus 5 ASCOM Driver
* Comandi seriali di AstroFocus 5
* -------------------------------
*
* 0,0 Restituisce posizione attuale
* 0,N Imposta la posizione attuale
* 1,N Va alla posizione assoluta N
* 2,N Va alla posizione relativa N ignorando i limiti
* 3,0 Imposta la posizione attuale come limite inferiore (punto 0)
* 4,0 Restituisce il limite superiore attuale
* 4,1 Imposta la posizione attuale come limite superiore
* 4,N Imposta il limite superiore a N (>1) (*)
* 5,0 Restituisce T se è presente il sensore di temperature, altrimenti F
* 5,1 Restituisce la temperatura attuale
* 6,0 Restituisce il coefficiente di temperatura
* 6,N Imposta il coefficiente di temperatura a N
* 7,0 Disattiva la compensazione della temperatura
* 7,1 Attiva la compensazione della temperatura
* 8,0 Restituisce la dimensione dei passi in 1/100 di micron
* 8,N Imposta la dimensione dei passi in 1/100 di micron
* 9,0 Restituisce la versione del programma
* 10,0 Restituisce la potenza del motore (1-255)
* 10,N Imposta la potenza del motore (1-255)
* 11,0 Restituisce la durata degli impulsi in millisecondi
* 11,N Imposta la durata degli impulsi in millisecondi
* 12,0 Restituisce la pausa prima dell'interruzione dell'alimentazione del motore in millisecondi
* 12,N Imposta la pausa prima dell'interruzione dell'alimentazione del motore in millisecondi
* 13,0 Restituisce la modalità di spostamento (1: One Phase Full Step, 2: Two Phase Full Step, 3: Half Step)
* 13,N Imposta la modalità di spostamento (1: One Phase Full Step, 2: Two Phase Full Step, 3: Half Step)
*/
#include <EEPROM.h>
#include <Wire.h>
#include "Adafruit_MCP9808.h"
// Impostazione dei parametri iniziali
Adafruit_MCP9808 tempSensor = Adafruit_MCP9808(); // Sensore di temperatura
const char ver[] = "5.0.1.0"; // Versione del firmware
const int pwmA = 3; // Pin di controllo della potenza A
const int pwmB = 11; // Pin di controllo della potenza B
const int dirA = 12; // Pin di controllo della polarità A
const int dirB = 13; // Pin di controllo della polarità B
const int brkA = 9; // Pin di controllo del freno A
const int brkB = 8; // Pin di controllo del freno B
// Variabili globali
int motorPosition = 0; // Posizione attuale del motore
int motorMax = 0; // Posizione massima del motore (limite superiore)
boolean tempComp = false; // Indica se è attiva la compensazione della temperatura
int positionBias = 0; // Posizione del fuocheggiatore all'inizio della funzione di compensazione
float temperatureBias = 0; // Temperatura all'inizio della funzione di compensazione
boolean tempSensorActive = false; // Indica se il sensore della temperatura è presente ed attivo
float temperature = 0; // Temperatura attuale in gradi Celsius
int tempCoeff = 0; // Coefficiente di dilatazione
int stepSize = 0; // Dimensione dei passi in micron
unsigned long timeOut = 0; // Tempo dopo cui eseguire una correzione della posizione a causa della temperatura
int pwr = 0; // Potenza applicata al motore (0-255)
int stepDelay = 0; // Pausa tra gli impulsi al motore (millisecondi)
int pwrOffDelay = 0; // Pausa prima dell'interruzione dell'alimentazione del motore dopo il movimanto (millisecondi)
int stepMode =0; // Modalità di spostamento del motore
/*
* Operazioni da eseguire all'avvio
*/
void setup() {
Serial.begin(9600); // Imposta la velocità della porta seriale
Serial.flush(); // Svuota il buffer della porta seriale
if (tempSensor.begin(0x18)) {tempSensorActive = true;} // Avvia e verifica il sensore di temperatura
pinMode(brkA, OUTPUT); // Modalità del pin del freno A
pinMode(brkB, OUTPUT); // Modalità del pin del freno B
pinMode(pwmA, OUTPUT); // Modalità del pin della potenza A
pinMode(pwmB, OUTPUT); // Modalità del pin della potenza B
pinMode(dirA, OUTPUT); // Modalità del pin della polarità A
pinMode(dirB, OUTPUT); // Modalità del pin della polarità B
digitalWrite (brkA, LOW); // Rilascia il freno A
digitalWrite (brkB, LOW); // Rilascia il freno B
motorPosition = recallInteger(0); // Richiama la posizione attuale del motore dalla EEPROM
motorMax = recallInteger(1); // Richiama la posizione massima del motore dalla EEPROM
tempCoeff = recallInteger(2); // Richiama il coefficiente di dilatazione
stepSize = recallInteger(3); // Richiama la dimensione dei passi in micron
pwr = recallInteger(4); // Richiama la potenza applicata al motore
stepDelay = recallInteger(5); // Richiama la pausa tra gli impulsi
pwrOffDelay = recallInteger(6); // Richiama la pausa prima dell'interruzione dell'alimentazione del motore
stepMode = recallInteger(7); // Richiama la modalità di spostamento del motore
// Verifica che il limite superiore sia valido, in caso contrario viene impostato a 32767
if(motorMax < 1){
motorMax = 32767;
storeInteger(1, motorMax);
}
}
/*
* Ciclo principale
*/
void loop() {
// Sposta il fuocheggiatore in funzione della temperatura
if(tempComp) {
if(timeOut < millis()){
timeOut = millis() + 1000;
temperature = tempSensor.readTempC();
float floatTempCompPosition = temperature - temperatureBias;
floatTempCompPosition = floatTempCompPosition * float(tempCoeff);
int tempCompPosition = int(floatTempCompPosition) + positionBias;
if (tempCompPosition < 0) {tempCompPosition = 0;}
if (tempCompPosition > motorMax) {tempCompPosition = motorMax;}
if(tempCompPosition != motorPosition){
motorMove(tempCompPosition - motorPosition);
storeInteger(0, motorPosition);
}
}
}
// Gestione dei comandi seriali
while (Serial.available() > 0) { // Controlla la porta seriale
int cmdOne = Serial.parseInt(); // Leggi il primo parametro dalla porta seriale
int cmdTwo = Serial.parseInt(); // Leggi il secondo parametro dalla porta seriale
if (Serial.read() == '\n') { // Quando si riceve un numero seguito da LF
switch(cmdOne) {
case 0:
if(cmdTwo == 0){
// Restituisci la posizione attuale
Serial.println(motorPosition);
}
else{
// Imposta la posizione attuale al valore indicato
motorPosition = cmdTwo;
storeInteger(0, motorPosition);
Serial.println("OK");
}
break;
case 1:
// Vai alla posizione assoluta passata come parametro
if (cmdTwo < 0) {cmdTwo = 0;}
if (cmdTwo > motorMax) {cmdTwo = motorMax;}
if(tempComp){
Serial.println("Error");
}
else{
// Vai alla posizione assoluta
if (cmdTwo != motorPosition){
motorMove(cmdTwo - motorPosition);
motorPosition = cmdTwo;
storeInteger(0, motorPosition);
}
Serial.println("OK");
}
break;
case 2:
// Sposta il motore in modo relativo e ignorando i limiti
if(tempComp){
Serial.println("Error");
}
else{
if(cmdTwo != 0){
motorMove(cmdTwo);
// motorPosition = motorPosition + cmdTwo;
storeInteger(0, motorPosition);
}
Serial.println("OK");
}
break;
case 3:
// Imposta il limite inferiore alla posizione attuale
if(tempComp){
Serial.println("Error");
}
else{
motorPosition = 0;
storeInteger(0, 0);
Serial.println("OK");
}
break;
case 4:
// Limite superiore
if(tempComp){
Serial.println("Error");
}
else{
if(cmdTwo == 0){
// Restituisci il limite superiore
Serial.println(motorMax);
}
if(cmdTwo == 1){
// Imposta il limite superiore alla posizione attuale
if(motorPosition > 0){
motorMax = motorPosition;
storeInteger(1, motorMax);
Serial.println("OK");
}
}
else{
if(motorPosition > 0){
// Imposta il limite superiore in una posizione arbitraria
if (motorPosition <= cmdTwo){
motorMax = cmdTwo;
storeInteger(1, motorMax);
Serial.println("OK");
}
}
}
break;
case 5:
// Restituisci la temperatura attuale
if (cmdTwo == 0){
if(tempSensorActive){Serial.println("T");}
else{Serial.println("F");}
}
else{
temperature = tempSensor.readTempC();
Serial.println(temperature);
}
break;
case 6:
// Coefficiente di temperatura
if(cmdTwo == 0){
Serial.println(tempCoeff);
}
else{
tempCoeff = cmdTwo;
storeInteger(2, tempCoeff);
Serial.println("OK");
}
break;
case 7:
// Compensazione delle variazioni di temperatura
switch(cmdTwo){
case 0:
tempComp = false;
Serial.println("OK");
break;
case 1:
if(tempSensorActive){
positionBias = motorPosition;
temperatureBias = tempSensor.readTempC();
tempComp = true;
Serial.println("OK");
}
else{Serial.println("Error");}
break;
case 2:
if(tempComp){Serial.println("T");}
else{Serial.println("F");}
break;
}
break;
case 8:
// Dimensione dei passi (micron)
if(cmdTwo == 0){
Serial.println(stepSize);
}
else{
stepSize = cmdTwo;
storeInteger(3, stepSize);
Serial.println("OK");
}
break;
case 9:
// Restituisci la versione del programma
Serial.println(ver);
break;
case 10:
// Potenza del motore
if(cmdTwo == 0){
Serial.println(pwr);
break;
}
else{
pwr = cmdTwo;
storeInteger(4, pwr);
Serial.println("OK");
break;
}
case 11:
// Durata degli impulsi
if(cmdTwo == 0){
Serial.println(stepDelay);
break;
}
else{
stepDelay = cmdTwo;
storeInteger(5, stepDelay);
Serial.println("OK");
break;
}
case 12:
// Pausa prima dell'interruzione dell'alimentazione del motore
if(cmdTwo == 0){
Serial.println(pwrOffDelay);
break;
}
else{
pwrOffDelay = cmdTwo;
storeInteger(6, pwrOffDelay);
Serial.println("OK");
break;
}
case 13:
// Modalità di spostamento del motore
if(cmdTwo == 0){
Serial.println(stepMode);
break;
}
else{
stepMode = cmdTwo;
storeInteger(7, stepMode);
Serial.println("OK");
break;
}
}
}
}
}
}
void motorMove(int motorSteps) {
// Imposta la velocità del motore a seconda del numero di passi da eseguire
motorOnePhaseFullStep();
delay(stepDelay);
if (motorSteps < 0) {
for (int n = 0; n < abs(motorSteps); n++){
motorPosition--;
switch (stepMode) {
case 1:
motorOnePhaseFullStep();
break;
case 2:
motorTwoPhaseFullStep();
break;
case 3:
motorHalfStep();
break;
}
delay(stepDelay);
}
}
else {
for (int n = 0; n < motorSteps; n++){
motorPosition++;
switch (stepMode) {
case 1:
motorOnePhaseFullStep();
break;
case 2:
motorTwoPhaseFullStep();
break;
case 3:
motorHalfStep();
break;
}
delay(stepDelay);
}
}
motorPowerOff();
}
void motorOnePhaseFullStep() {
// Muovi in modalità One Phase Full Step
int motorPhase = motorPosition % 4;
if(motorPhase < 0) {motorPhase = motorPhase + 4;}
switch (motorPhase) {
case 0:
digitalWrite(dirA, LOW);
digitalWrite(dirB, LOW);
analogWrite(pwmA, pwr);
analogWrite(pwmB, 0);
break;
case 1:
digitalWrite(dirA, LOW);
digitalWrite(dirB, LOW);
analogWrite(pwmA, 0);
analogWrite(pwmB, pwr);
break;
case 2:
digitalWrite(dirA, HIGH);
digitalWrite(dirB, HIGH);
analogWrite(pwmA, pwr);
analogWrite(pwmB, 0);
break;
case 3:
digitalWrite(dirA, HIGH);
digitalWrite(dirB, HIGH);
analogWrite(pwmA, 0);
analogWrite(pwmB, pwr);
break;
}
}
void motorTwoPhaseFullStep() {
// Muovi in modalità Two Phase Full Step
int motorPhase = motorPosition % 4;
if(motorPhase < 0) {motorPhase = motorPhase + 4;}
switch (motorPhase) {
case 0:
digitalWrite(dirA, LOW);
digitalWrite(dirB, LOW);
analogWrite(pwmA, pwr);
analogWrite(pwmB, pwr);
break;
case 1:
digitalWrite(dirA, HIGH);
digitalWrite(dirB, LOW);
analogWrite(pwmA, pwr);
analogWrite(pwmB, pwr);
break;
case 2:
digitalWrite(dirA, HIGH);
digitalWrite(dirB, HIGH);
analogWrite(pwmA, pwr);
analogWrite(pwmB, pwr);
break;
case 3:
digitalWrite(dirA, LOW);
digitalWrite(dirB, HIGH);
analogWrite(pwmA, pwr);
analogWrite(pwmB, pwr);
break;
}
}
void motorHalfStep() {
// Muovi in modalità Half Step
int motorPhase = motorPosition % 8;
if(motorPhase < 0) {motorPhase = motorPhase + 8;}
switch (motorPhase) {
case 0:
digitalWrite(dirA, LOW);
digitalWrite(dirB, LOW);
analogWrite(pwmA, pwr);
analogWrite(pwmB, 0);
break;
case 1:
digitalWrite(dirA, LOW);
digitalWrite(dirB, LOW);
analogWrite(pwmA, pwr);
analogWrite(pwmB, pwr);
break;
case 2:
digitalWrite(dirA, LOW);
digitalWrite(dirB, LOW);
analogWrite(pwmA, 0);
analogWrite(pwmB, pwr);
break;
case 3:
digitalWrite(dirA, HIGH);
digitalWrite(dirB, LOW);
analogWrite(pwmA, pwr);
analogWrite(pwmB, pwr);
break;
case 4:
digitalWrite(dirA, HIGH);
digitalWrite(dirB, HIGH);
analogWrite(pwmA, pwr);
analogWrite(pwmB, 0);
break;
case 5:
digitalWrite(dirA, HIGH);
digitalWrite(dirB, HIGH);
analogWrite(pwmA, pwr);
analogWrite(pwmB, pwr);
break;
case 6:
digitalWrite(dirA, HIGH);
digitalWrite(dirB, HIGH);
analogWrite(pwmA, 0);
analogWrite(pwmB, pwr);
break;
case 7:
digitalWrite(dirA, LOW);
digitalWrite(dirB, HIGH);
analogWrite(pwmA, pwr);
analogWrite(pwmB, pwr);
break;
}
}
void motorPowerOff(){
// Togli corrente dal motore
delay(pwrOffDelay);
analogWrite(pwmA, 0);
analogWrite(pwmB, 0);
}
void storeInteger(int storePosition, int storeValue) {
// Memorizza l'intero passato come parametro in due celle EEPROM adiacenti
long longValue = long(storeValue) + 32768;
EEPROM.write(storePosition * 2, longValue / 256);
EEPROM.write(storePosition * 2 + 1, longValue % 256);
}
int recallInteger(int storePosition) {
// Recupera un intero da due celle EEPROM adiacenti
int highValue = EEPROM.read(storePosition * 2);
int lowValue = EEPROM.read(storePosition * 2 + 1);
long longValue = long(highValue) * 256 + long(lowValue);
longValue= longValue - 32768;
return int(longValue);
}