Go Down

Topic: Official topic: multicotteri con arduino! (Read 359454 times) previous topic - next topic

lestofante

stavo programmandomi una libreria apposta per comunicare, senza entrare troppo nel dettaglio ho controllato a priori la durata di una digital read... 4ms.
Troppo, viene un baudrate di 250.. Potrei usare gli input/output a livello di registro, ma tanto vale usare la NewSoftSerial, che arriva fino a 57600baud in ricezione e 115200baud in trasmissione. Quindi userò la seriale simulata per comunicare con il PC, tanto l'output è pensato per funzionare a 19200baud (ed ecco perché la seriale mi sembrava così lenta, pensavo di usare una delle velocità più alte... :smiley-mr-green:) )
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

astrobeed


stavo programmandomi una libreria apposta per comunicare, senza entrare troppo nel dettaglio ho controllato a priori la durata di una digital read... 4ms.


Non so come hai fatto questa misura, però è totalmente sbagliata, sia la digitalRread che la digitalWrite richiedono un tempo di esecuzione leggermente inferiore a 2 us, sempre molto rispetto alla scrittura/lettura diretta del registro del port che richiede solo 62 ns, o 124 a seconda del tipo di indirizzamento, come avevo già fatto notare in un altro thread.
Scientia potentia est

lestofante

uhhh hai completamente ragione, ho confuso 4microsec con 4ms!!! mea culpa

Code: [Select]
void setup(){
  Serial.begin(19200);
}

void loop(){
    int a;
  unsigned long time2;
 
  pinMode(12, INPUT);
  unsigned long time1 = micros();
  for (int i=0; i < 1000; i++){
    a=digitalRead(12);
  }
  time2 = micros()-time1;
 
  Serial.print("1000 read duration:");
  Serial.println(time2);
 
  pinMode(12, OUTPUT);
  boolean stat=false;
  time1 = micros();
  for (int i=0; i < 1000; i++){
    digitalWrite(12, stat?HIGH:LOW);
    stat=!stat;
  }
  time2 = micros()-time1;
 
  Serial.print("1000 write duration:");
  Serial.println(time2);
}


OUTPUT:
Code: [Select]
1000 write duration:5664
1000 read duration:4156


quindi dovrebbe venire un baud di circa 250.000 (in realtà raggiungere 200.000 credo sia già un bel traguardo)

boh mi sa che oramai vado di seriale, poi magari in un'altra discussione posto il codice che ho scritto finora, anche se è molto "hard coded". Usa due pin fissi, il lettore richiede i messaggi semplicemente alzando e abbassando un pin(una specie di clock che lavora su entrambi i fronti), lo scrittore riceve l'interrupt change dal pin di clock e scrive un bit nel pin "dati"

In questo modo il lettore NON conosce a priori se ci sono dati pronti, semplicemente legge sempre 0.
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

astrobeed


uhhh hai completamente ragione, ho confuso 4microsec con 4ms!!! mea culpa


Comunque il test che fai è sbagliato lo stesso perché nel conteggio del tempo ci va pure il ciclo for, che si prende i suoi 2-3us, il tempo reale sono i poco meno 2us che ti ho detto, misurati strumentalmente a suo tempo sul tempo che ci mette un pin a cambiare stato tra due digitalWrite consecutive, stessa cosa per la digitalRead misurata come offset in mezzo a due digitalWrite.
In tutti i casi non puoi ottenere un baud rate pari ad 1/2 del tempo di commutazione perché in mezzo c'è pure il tempo per eseguire lo shift del registro da inviare/leggere bit a bit su un pin.
Non a caso ti ho detto di usare la I2C hardware come slave, a 400 kHz, per comunicare con il resto del sistema e usare la I2C emulata in software per leggere il Nunchuk.
Prima di tutto è più semplice emulare un master che uno slave, e poi c'è il fatto che il Nunchuk ha una banda limitata, mi pare al massimo 100Hz, quindi puoi prenderti tutto il tempo che vuoi per leggerlo, non ti serve spingere l'I2C master ad alte velocità, anche se lo leggi 1000 volte al secondo non cambia nulla, alla fine sempre 100 valori diversi, distanziati di circa 10 ms, ottieni.
Non scordarti che i valori 100kHz e 400kHz sono i limiti di velocità e non la velocità obbligatoria, ovvero l'I2C puoi farla funzionare con un clock che parte da poche centinaia di Hz, con alcuni device pure meno di 1 Hz, fino al limite massimo ammesso e non deve nemmeno essere costante perché è una seriale sincrona, ovvero tutto va in funzione del clock generato dal master.
Scientia potentia est

lestofante

ok, ma il problema è trovare una libreria software i2c. ne ho trovata una ma è molto basica e non specifica i propri limiti. vediamo se riesco a farci stare la newSoftSerial, altrimenti rimedio sull'i2c software

purtroppo l'i2c non l'ho mai usato se non per il wmp e il nunchuck, e quindi non sono pratico del protocollo, sopratutto per quanti riguarda controllare se una libreria è valida oppure no.

quella che ho trovato io è questa: http://www.bese.it/~segv/twi.tar.gz
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

astrobeed

Soluzione alternativa, intercetta le tre uscite analogiche dell'accelerometro e collegale direttamente all'ADC di Arduino, sempre 10 bit di risoluzione ottieni, anzi volendo ne puoi ottenere 12 con l'oversampling.
Scientia potentia est

superlol

allora chi inizia a buttare giù qualche algoritmo di stabilizzazione? (PID, kallmann ecc..)  XD
http://www.aug-altogarda.it/ <- Il nuovo AUG per basso trentino e dintorni!

ratto93

Se corri veloce come un fulmine, ti schianterai come un tuono.

astrobeed


allora chi inizia a buttare giù qualche algoritmo di stabilizzazione? (PID, kallmann ecc..)  XD


Prima di partire con un lavoro che richiederà molto impegno sarebbe il caso di capire chi è disposto a collaborare sul serio e se c'è realmente l'intenzione di sviluppare un hardware/software "made in Italy" per i quadricotteri.
Scientia potentia est

lestofante

io uso la DCM, leggera veloce e abbastanza semplice. Certo usa seni, coseni e una radice quadrata, e per poi passare dal quaternione di rotazione agli angoli euleriani è un'altra bella botta di seni/coseni... dovremmo mettere al confronto un kallman e una DCM, dopo pranzo controllo quanto mi dura un loop, ma se non erro era sui 700 microsec, DCM + conversione a euleriani. magari si può evitare la conversione, o magari sovrapporre i due metodi (se abbiamo abbastanza potenza di calcolo)
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

astrobeed


io uso la DCM, leggera veloce e abbastanza semplice.


Per come la vedo io con la DCM ti sei solo complicato la vita senza trarre nessun reale beneficio, non ho dati per la combinata PID e Kalman su un ATmega, li uso per altre cose, in compenso ho dati molto precisi su i PIC serie 18, per un ciclo completo mi bastano meno di 200 us (pid e kalman ottimizzati sull'applicazione), dovrebbe essere lo stesso anche su ATmega 328.
Si può sempre prendere in considerazione di portare il clock del micro a 20 MHz, avevo già postato la cosa diverso tempo fa con tanto di bootloader modificato per tale frequenza, il 25% di velocità nei calcoli fa sicuramente comodo in questa applicazione.
Scientia potentia est

lestofante

ad occhio la DCM è più semplice da implementare, almeno per me che qualcosina di algebra lineare la so. Il codice che ho usato non l'ho scritto io, ho solo risolto un problemino quando l'accelerometro legge 0,0,0 (caso quasi impossibile, ma prevenire...)

io per tutto il ciclo (compresa lettura RX tramite interrupt, che probabilmente rallenta un pò tutto) trasformazioni e tutto mi pare che arrivassi a 1ms per loop

però è difficile trovare un paragone, bisognerebbe vedere anche la qualità dei dati in uscita

per i 20MHz mi sa che diventa un pò un casino per ci usa la board arduino, sarebbe obbligatorio usare un chip stand alone

ps. ho controllato l'idea del collegamento analogico... il chip è uno ADXL335B (perchè è un fake nunchuck) foglio dati: http://docs.google.com/viewer?a=v&q=cache:VtX3g1Lcf4wJ:www.sparkfun.com/datasheets/Components/SMD/adxl335.pdf+adxl335b+accelerometer&hl=en&pid=bl&srcid=ADGEESipeGlTX4n5OKnMEdGa4brKTPdTzKchHCT-2C0wRhDYJAKQJbdMyPC8xYrTH8104HBRChs5oNgoB8En7lcaWaQIftwDIIBmuRylYziVLbH9W4MViJDPDLD6qPlvR-l8qWc-8W20&sig=AHIEtbTugPuomcYswsiC2j8iBBhZFsvlTw
l'oversampling se ho capito bene è leggere più volte il dato prima che il sensore lo aggiorni, e fare la media di queste letture, giusto?
Quindi in questo caso facendo 3200 letture analogiche al secondo avrei un oversampling di 2 dati per x e y(1600Hz), e di ~6 dati per l'asse z(550Hz), giusto?

data la disposizione dei pin, credo che volendo riuscirei pure a saldarci sopra dei cavi volanti... è indubbio che fare una board apposita sia la soluzione migliore però.. rischio di rovinare il chip, magari "strappando" le piste?
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

superlol

io sono disposto a rischiare il mio quadricottero per gente come voi basta non mi facciate scherzi ;)

per di più tra poco credo ordinerò la freeIMU di Fabio Varesano ]:D
(questo volta definitivamente  :~)

riguardo la clock vero che il 25% di velocità in più sarebbe davvero comoda ma come è stato detto renderebbe il tutto più complicato per chi si avvicina per la prima volta.

io direi intanto di dire:
che parti salviamo di multiwii? quali eliminiamo?

visto che è stato riscritta la parte riguardante l'I2C che non rallenti il software (almeno è quello che ho capito) si potrebbe tenere, così il sistema di leggere i segnali dalla ricevente sempre che non usi un misero pulsein  :smiley-roll-blue:

inoltre prevederei uno switch per abilitare oppure non la comunicazione seriale che porta via un sacco di tempo, se uno vuole poi collegarlo alla GUI si mette su ON lo switch e così in volo non si rallenta il programma sbaglio forse?
http://www.aug-altogarda.it/ <- Il nuovo AUG per basso trentino e dintorni!

ratto93

#463
Aug 02, 2011, 05:24 pm Last Edit: Aug 02, 2011, 05:26 pm by ratto93 Reason: 1
Appena ho i pezzi monto il mio lo testo con multiwii e poi anche io posso usarlo per testare il codice....
per programmare viste la mia modesta preparazione non so qunto sarò utile ma ce la metterò tutta ;)
buona l'idea di spegnere la seriale... ed anche quella di overcloccare il micro...
ora non vorrei dire una baggianata ma ne ho visti alcuni che sono addirittura oltre i 20Mhz... che sia controproducente spingersi così oltre ?
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1266309691     a 32Mhz
magari con un bel dissipatorino... però se cresha finchè è su son cavoli amari...
Se corri veloce come un fulmine, ti schianterai come un tuono.

astrobeed


per i 20MHz mi sa che diventa un pò un casino per ci usa la board arduino, sarebbe obbligatorio usare un chip stand alone


Basta cambiare il quarzo e mettere il bootloader modificato.

Quote

ps. ho controllato l'idea del collegamento analogico... il chip è uno ADXL335B


Che è pure meglio del 330 montato sull'originale.

Quote

l'oversampling se ho capito bene è leggere più volte il dato prima che il sensore lo aggiorni, e fare la media di queste letture, giusto?


Se fai la media esatta ottieni un filtro che aiuta molto ad eliminare il rumore, per ottenere i bit in più devi shiftare a destra di uno per ogni potenza di 4 dei samples, ovvero :

per ottenere 11 bit somma di  4 samples diviso  2 (>>1)
per ottenere 12 bit somma di 16 samples diviso 4 (>>2)
per ottenere 13 bit somma di 64 samples diviso 8 (>>3)

>Quindi in questo caso facendo 3200 letture analogiche al secondo avrei un oversampling di 2 dati per x e y(1600Hz), e di ~6 dati per l'asse >z(550Hz), giusto?

Non scordati che la banda reale di quei sensori è circa 100 Hz, ci vuole un filtro passa basso tra l'out del ADXL e l'input del ADC, è già presente sulla schedina del Nunchuk.
In pratica è inutile leggerli troppo velocemente, basta fare la lettura dei tre ingressi ADC ad ogni ciclo di 1 ms, quando ne hai 4 fai il conto ed hai i valori a 11 bit con un refresh di circa 250 Hz.

Quote

data la disposizione dei pin, credo che volendo riuscirei pure a saldarci sopra dei cavi volanti... è indubbio che fare una board apposita sia la soluzione migliore però.. rischio di rovinare il chip, magari "strappando" le piste?


Non devi collegarti sui pin, ci sono i tre condensatori che fanno da filtro passa basso, sfruttano l'impedenza d'uscita del sensore, su i quali è molto più semplice saldare tre fili senza fare danni.
Li trovi facilmente con un multimetro, su un lato sono collegati a GND mentre sull'altro c'è una tensione pari a 1/2 Vcc, circa 1.65 v, quando l'accelerometro è in bolla per gli assi X e Y e una tensione minore, circa 1.1 v, per l'asse Z.
Scientia potentia est

Go Up