Go Down

Topic: Arduino Visual basic Firmata (Read 1 time) previous topic - next topic

Mork11

Salve ragazzi, sto realizzando un software in VB per poter gestire un Arm a 4 assi.
Uso il protocollo Firmata precaricato nell'arduino.
Leggo i valori in input dati dai potenziometri ma non riesco ad inviare tali valori in angoli per l'output digitale ai servo.
 Sono giorni che cerco in rete e non sono un'esperto di VB, sto andando a tentativi e l'ultimo è stato un ripiego, nel senso che ho diviso i valori dell'analog input per 5.69 ma non so se sia corretto.Quando però provo ad inviare tali risultati al pin digitale cui si trova il servo non succede niente.Se c' è qualcuno esperto in VB potrebbe darmi una mano nella soluzione?
Se volete posso riportare l'elaborato del programma

Mork11

Nel Timer associato al potenziometro 1 c'è:

potPin1 =  FirmataVB1.AnalogRead (0)
LggIngAnalog1.Text = potPin1
Angolo1 = potPin1 / 5.69
FirmataVB1. DigitalWrite (6, Angolo1)


nid69ita

#2
Oct 06, 2016, 10:13 am Last Edit: Oct 06, 2016, 10:16 am by nid69ita
Secondo me il firmare/sketch Firmata standard NON è in grado di pilotare un servo.
Solo una mia opinione, non conosco bene Firmata.

In tutti i casi, da VB scrivi i comandi che faresti su Arduino. 
Se il servo accetta un segnale PWM (dubito), allora su Arduino si usa analogWrite() su pin digitale ma che permette il PWM (su Arduino uno sono quelli indicati con ~ )     
Si spera che anche da firmata lato vb ci sia un analogWrite
my name is IGOR, not AIGOR

zoomx

Quello che manca in ciò che vuoi fare è la funzione che lega la posizione del potenziometro, e quindi il valore analogico che leggi, con la posizione del servo.
Credo che se i potenziometri sono lineari dovrebbe venir fuori una retta (Angolo1 = potPin1 / 5.69 sarebbe una retta se non sto dormendo) ma se i potenziometri sono logaritmici le cose si complicano di poco.


Mork11

Premetto che sto lavorando e al momento non posso portare molte delucidazioni ma...
Il servo collegato è sul pin 6 quindi PWM , ho già eseguito un programma test sui motori con potenziometri in arduino e funzionano quindi tu dici che dovrei cambiare se ho capito bene solo l'invio sul pin digitale e cioè:

potPin1 =  FirmataVB1.AnalogRead (0)        // leggo
LggIngAnalog1.Text = potPin1                  // Trasferisco al potenziometro
Angolo1 = potPin1 / 5.69                         // Converto

Ed anzichè
FirmataVB1. DigitalWrite (6, Angolo1)         // Invio in digitale

dovrò fare
FirmataVB1. AnalogWrite(6, Angolo1)         // Invio in PWM

Provo e vi faccio sapere

Ma un'occhiata al file dll di firmata gliela do comunque

Non so se sono logaritmici o lineari i potenziometri ma la conversione alla fine avviene in decimale non dovrebbe comportarmi problemi

zoomx

Traduco in parole terra terra: se il potenziometro è tutto a destra il servo in che posizione deve essere? Se il potenziometro è tutto a sinistra il servo in che posizione deve essere? Infine se il potenziometro è nel mezzo il servo in che posizione deve essere?
Se il potenziometro è lineare mi aspetto che il valore letto nella posizione di mezzo sia ... nel mezzo dell'intervallo letto nelle due posizioni estreme. Se è logaritmico no. Ad esempio per un potenziometro da 10K Ohm mi aspetto che nel mezzo legga un valore che corrisponde a circa 5K Ohm. Significa che ad esempio FirmataVB1.AnalogRead (0) mi restituisce 0 a sinistra 1000 a destra e 500 nel mezzo.


Ho usato Firmata una sola volta anni fa e non ricordo bene.I valori per analogWrite dovrebbero essere degli interi ma tu esegui una divisione con un float. Angolo1 dovrebbe essere un intero ma non ne sono sicuro.
Inoltre fai attenzione all'intervallo di Timer1, le istruzioni contenute devono essere svolte prima che scada l'intervallo.

Ricorda che non tutti i pin di Arduino supportano il PWM per cui puoi attaccare un servo solo ai pin 3,5,6,9,10,11

Mork11

Eccomi. ..allora l'errore che commettevo stava nel fatto di voler comandare il servo con uscite digitali a non in pwm, come mi ha fatto notare nid69ita.Adesso qualcosa viene fuori il motore per un attimo ha ruotato rispondendo all'impulsi inviati dalla rotazione del potenziometro ma tira fuori all'aumentare dei Volt dei sibili di tenzione che non succede quando comando i motori direttamente da arduino  sempre tramite l'uso del medesimo potenziometro. A questo punto credo che la conversione non sia più corretta e che quindi debba dividere i valori dell'ingresso analogico per i segnali in uscita in PWM ed infine portarli a valori angolari da inviare al motore.
Non credo sia cosa facile e se avete dritte sono ben accette

zoomx

#7
Oct 06, 2016, 09:48 pm Last Edit: Oct 06, 2016, 09:50 pm by zoomx
Giro il potenziometro tutto da un lato, prendo il valore dell'ADC m1.
Giro il potenziometro dall'altro lato e prendo il valore dell'ADC m2.

Il più piccolo lo chiamo Bitmin e il più grande Bitmax.

Prendo gli estremi dei valori che devo fornire al servo in corrispondenza dei due estremi del potenziometro, quelloin corrispondenza di bitmin lo chiamo valMin e l'altro valMax, questo anche se il valore di valMax è minore del valore di valMin.

Chiamiamo Valore_ADC adesso il valore che leggiamo dall'ADC per una qualsiasi posizione del potenziometro e Angolo il valore da calcolare.


Code: [Select]
Angolo=(Valore_ADC - Bitmin) / (Bitmax - Bitmin) *  (valMax - valMin) + valMin

Le due differenze Bitmax - Bitmin e valMax - valMin sono sempre le stesse e le puoi sostituire con i valori precalcolati.

Arduino ha la stessa funzione che si chiama Map
Code: [Select]

long map(long x, long in_min, long in_max, long out_min, long out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

Mork11

Grazie per l'aiuto che mi state dando lo apprezzo...se ruoto tutto a sinistra il potenziometro è pari a 0 mentre tutto a destra è 1023, aumentando in maniera graduale.Quando con un firmware in arduino ho testato il motore, se giravo il potenziometro tutto a sinistra si posizionava tutto da un lato a destra tutto dal lato opposto e nel mezzo si trovava esattamente a metà tra i due estremi.Adesso proverò ad eseguire con queste modalita...vi tengo aggiornati.

zoomx

Se leggi 0 da un lato e 1023 dall'altro stai attento a cosa succede quando le posizioni sono molto vicine agli estremi.
Se, per esempio, a pochi gradi dagli estremi leggi già i valori estremi, 0 da un lato e 1023 dall'altro, succederà che in quell'intervallo la lettura del potenziometro è sempre la stessa. Ma hai fatto un test e te ne saresti accorto per cui se tale zona morta c'è è molto poccola.
Dal test che hai fatto con l'altro firmware si può dedurre che il potenzimetro è lineare a meno che nel firmware c'era una correzione per i potenziometri logaritmici ma lo ritengo improbabile.

La formula riportata prima è quella di una retta che passa per i 2 punti bitmin, valmin e bitmax, valmax, significa che la relazione tra le due grandezze è lineare.

Mork11

Non ho ancora provato ma mi sono documentato sulla formula e mi si è accesa una lampadina....(che apre una parentesi e la richiude)
Ma utilizzando medesima formula potrei far eseguire un movimento lineare al robot? 

paulus1969

Anche io dubito che Firmata possa pilotare un servomotore... non lo uso mai, quindi potrei anche avere torto.
Quando lo hai provato con quel firmware, senza collegarlo al PC e senza Firmata, sicuramente avrai caricato la libreria servo.

Io in questi casi - come ho scritto prima - non uso Firmata, molto più semplicemente creo un piccolo protocollo di comunicazione seriale fra il programma sul PC ed il firmware sulla scheda.
Se invio "A120" dal PC, leggo questo dato e faccio posizionare il servomotore A alla posizione 120, tramite l'apposita libreria. Semplice ed efficace.
Per il potenziometro puoi fare al contrario, invii al PC qualcosa che comunica il valore. Qui hai diversi metodi per farlo, o invii l'informazione periodicamente, o la invii solo quando il valore cambia, o la invii come risposta ad una interrogazione proveniente dal PC (ti basta in questo caso adoperare un altro timer del VB). Così il PC riceve "P1000" e sai cosa hai letto... ovviamente ti conviene passare attraverso il PC solo se hai intenzione di intervenire in qualche modo sulla posizione del servomotore anche tramite PC, altrimenti sarebbe sufficiente una semplice comunicazione della posizione per visualizzarla a schermo.

zoomx

#12
Oct 07, 2016, 07:04 pm Last Edit: Oct 07, 2016, 07:10 pm by zoomx
Ma utilizzando medesima formula potrei far eseguire un movimento lineare al robot? 
Non ho capito cosa vorresti fare. La formula lega due grandezze con una relazione lineare. Ciò che significano le due grandezze sta a te così come la loro trasformazione in un movimento o in qualcos'altro come la posizione di un punto su uno schermo.

@paulus1969
Firmata è un modo per comandare l'Arduino dall'esterno come se il dispositivo esterno avesse lui le API di Arduino. E' un'astrazione.
Se per esempio vuoi alzare un piedino X mandi il comando "Alza il piedinoX" e Arduino esegue.
Se vuoi un valore Analogico chiedi il valore. Se vuoi mandare un PWM fai lo stesso.
La logica del programma si troverà nel dispositivo esterno, in questo caso il PC. Ovviamente il tutto a scapito della velocità.

nid69ita

Se vuoi un valore Analogico chiedi il valore. Se vuoi mandare un PWM fai lo stesso.
Ma mandare un PWM non credo basta per pilotare il Servo. La libreria Servo fa ben di più.
my name is IGOR, not AIGOR

gpb01

#14
Oct 07, 2016, 09:42 pm Last Edit: Oct 07, 2016, 09:42 pm by gpb01
Ma mandare un PWM non credo basta per pilotare il Servo. La libreria Servo fa ben di più.
Come Astro ha spiegato più di una volta, i servo NON lavorano in PWM, ma in PPM. Quoto le sue parole ...

Quote
In PWM l'informazione è veicolata dal rapporto tra parte bassa e parte alta del segnale, in PPM l'informazione può essere veicolata in due modi, sia dalla durata della sola parte alta, o parte bassa, del segnale, che dalla posizione dell'impulso se è un treno d'impulsi componente un pacchetto di dati.
Guglielmo
Search is Your friend ... or I am Your enemy !

Go Up