Salve a tutti
Sto lavorando con la libreria Servo.h per muovere dei servi. Ho il problema di dover cambiare le frequenze e lavorare su campi più stretti del solito 20,000 (ventimila) microsecondi, ed ho risolto bene il problema intervenendo sul paramentro Refresh_Interval. Mi fermo qui per non dilungarmi troppo.
Il quesito che vi pongo è di tipo informatico, cioè se all'interno del file Servo.h viene definito
#define Refresh_interval
come si può portare fuori questa variabile e cambiarla dallo sketch? Farla diventare quindi una variabile dinamica?
Ciao a tutti e grazie
Allora questi giorni ci ho lavorato molto.....
Intervenendo sia su Servo.h che su Servo.cpp ho annullato la variabile REFRESH_INTERVAL e l'ho sostituita con MAX_PULSE_WIDTH, funziona bene tutto, in questo modo ho ridotto il numero delle variabili, e potendo passare max tramite attach() si dovrebbe riuscire a cambiare il valore in un lampo.
Ma il problema è che min e max non rispondono. Poichè sono stati dichiarati con #define, in Servo.h, ora li ha in carica il preprocessore e non si possono cambiare, di fatto la funzione attach(pin, min, max) funziona solo attach(pin), il resto NO.
Ho visto che in servo.cpp la classe servo è dichiarata in due tronconi:
unit8_t Servo::attach(int pin) che rimanda ai valori di default di MIN e MAX
uint8_t Servo::attach(int pin, int min, int max) che non si capisce dove rimanda.....
Grazie PaoloP
prima ti rispondo, poi vado a verificare se il tuo lavoro è OK.
Ma ti rispondo prima perchè ti devo chiarire cosa ho fatto. Dopo aver verificato con l'oscilloscopio che cambiando i valori di timer di arduino si creano solo casini, avevo la necessità di cambiare le frequenze di PWM, di avere un segnale pieno e di poter decidere liberamente quale frequenza avere, allora ho visto che se imposti MAX_PULSE_WIDTH con lo stesso valore di REFRESH_INTERVAL è come se dicessi che il duty cycle deve essere veramente variabile da 0 a 100%, perchè ho verificato che i servi da modellismo lavorano con un campionamento di 20.000 microsecondi ma l'impulso che ricevono è molto debole, massimo appunto 2400 us. Di fatto il segnale PWM che ne risulta è totalmente vuoto. Se invece imposti i valori allo stesso livello hai una variazione di onda quadra con un segnale pieno, difatti la tensione di uscita così varia tra 0.2V e 5V.
In questo modo arduino diventa uno strumento con le palle. Poi avevo appunto il problema di poter cambiare quel ca....o di #define in modo dinamico, così se voglio cambiare la frequenza non devo uscire dal programma....
Ho provato #undef, ma non funziona, ho anche provato a cambiarlo in volatile, ma non lo accetta il compilatore.... etc...
Comunque grazie per la risposta. vediamo.....
David
Comunque avevo fatto una cosa del genere, ma di diverso mi stai suggerendo l'uso di quel -> (arrow) che non ho capito come funziona, perdonami io il C lo conosco appena...... e ci sto facendo a cazzotti.
Sì, vanno dichiarati anche i puntatori. Tranne this, che è un oggetto particolare (se ti riferisci a questo).
Comunque per passare dei define che cambino il modo di operare di una libreria devi modificare la lib affinché essa diventi un unico file header con tutto dentro, compreso il contenuto del file cpp che carica.
Mi ci sono scontrato anche io con questo problema, avevo necessità di permettere all'utente di impostare un parametro direttamente dallo sketch perché non volevo fargli aprire il file .cpp. Parlo della libreria swRTC. Ma il define che mettevo prima dell'include era valido solo nel file .h della lib. Ho dovuto portare tutto al file .h, in questo modo il parametro messo prima dell'include viene visto da tutto il codice della classe.
Tu se non ho capito male vuoi fare una cosa simile:
Bravo. Hai capito perfettamente, se riusciamo a fare una cosa simile Arduino diventa uno strumento professionale per i servi ed i motori....
(Ah this non si dichiara..... ma pensa!!!)
Allora io ho provato anche a portare sia Servo.h che Servo.cpp tutto dentro lo sketch, ma poichè non conosco il C(++) mi ha preso di mano.
Devi riunire Servo.h e Servo.cpp in un unico file. In pratica invece di avere un file con le instestazioni ed uno con le funzioni, metti tutto in Servo.h. Non devi mettere il codice della lib nello sketch.
Aspetta. Devo mettere Servo.h e Servo.cpp tutto dentro un unico file, per es. Servo.h ? e trattarlo come una libreria?
Oppure devo mettere Servo.h e cpp dentro lo sketch?
Io ho messo .h e .cpp dentro lo sketch, ma non riesco a capire come devo gestire le classi che diventano funzioni, devo cambiare la classe in void?
Non mi pare di scrivere così male
Te l'ho specificato 2 volte: devi mettere tutto dentro Servo.h
Quel file .h diventa la tua libreria completa (è un merge di Servo.h e Servo.cpp).
Ti ho fatto l'esempio della mia swRTC per farti capire come fare. Se ti scarichi l'ultima versione vedi che ora è un unico file:
Ma allora il problema rimane, perchè il nostro #define REFRESH_INTERVAL sta in Servo.h , così come #define MAX_PULSE_WIDTH .
Dovrei riuscire a portare servo.h e cpp tutto dentro lo sketch, in questo modo gli posso cambiare il tipo in int.
Che ne pensi? Scusa se ti chiedo è solo per chiarezza, sono io che ti devo ringraziare....
Io quello che voglio fare di preciso è:
eliminare REFRESH_INTERVAL e dargli il valore di MAX_PULSE_WIDTH, e questo l'ho gia fatto.
Poi dichiarare servo.attach(pin, min, max) e in questo modo il mio servo dovrebbe lavorare a frequenza definita da max.
Sarebbe meraviglioso......... Uno strumento di una potenza pazzesca.
8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8)
E comunque per dove sono arrivato; sarebbe sufficiente che funzionasse la attach(pin, min, max) in questo modo è già tutto pronto.
Ma se guardi dentro Servo.cpp la funzione attach(pin, min, max) non si capisce come funziona, secondo me è sbagliata.
Basterebbe che questa funzione passasse le sue variabili in modo corretto.
uint8_t Servo::attach(int pin, int min, int max)
{
if(this->servoIndex < MAX_SERVOS ) {
pinMode( pin, OUTPUT) ;
// set servo pin to output
servos[this->servoIndex].Pin.nbr = pin;
// todo min/max check: abs(min - MIN_PULSE_WIDTH) /4 < 128
this->min = (MIN_PULSE_WIDTH - min)/4;
//resolution of min/max is 4 uS
this->max = (MAX_PULSE_WIDTH - max)/4;
// initialize the timer if it has not already been initialized
timer16_Sequence_t timer = SERVO_INDEX_TO_TIMER(servoIndex);
if(isTimerActive(timer) == false)
initISR(timer);
servos[this->servoIndex].Pin.isActive = true;
// this must be set after the check for isTimerActive
}
return this->servoIndex ;
}]
this->min = (MIN_PULSE_WIDTH - min)/4;
//resolution of min/max is 4 uS
this->max = (MAX_PULSE_WIDTH - max)/4;
// initialize the timer if it has not already been initialized
non dovrebbe essere il contarrio? (MIN_PULSE_WIDTH = this->min) oppure (min = this->min)
poi quel /4 ce l'hanno messo perchè serve come valore per far ridare i conti con SERVO_MIN() e SERVO_MAX().
Ma non si poteva tenere separate le due cose?
david_fiucci:
Io quello che voglio fare di preciso è:
eliminare REFRESH_INTERVAL e dargli il valore di MAX_PULSE_WIDTH, e questo l'ho gia fatto.
E allora non vedo tutto il problema, modifichi quel valore nella lib e fine. Quando compili, se hai necessità diverse, cambi prima il valore nel file .h e sei a posto.
Ciao Leo
scusa non ti ho salutato prima, stavo in trance "agonistica".
Il mio problema è proprio non dover intervenire su Servo.h uscendo dal programma....
Così ero bravo anch'io.
Quello che sto cercando di fare è cambiare il valore di frequenza tramite una variabile da sketch, così da poter cambiare tipo di servo semplicemente cliccando su un'icona del mio touch screen. Senza uscire dal programma, anzi è comandato dal programma.
Ho trovato qualcosa su TimerThree.h comando pwm(char pin, int duty, long microseconds), lo devo provare poi vi dico.
Comunque altra cosa: avete verificato che servo.attach(pin, min, max) non funziona? Cioè min e max rimangono inchiodati ai valori dichiarati da #define in Servo.h . Mi sapete dire come mai? Leggete il mio suggerimento postato sopra. Daiiiiii ragazzi che siete bravissimi.............