Quadricottero da zero...

Salve a tutti, sono nuovo di queste parti, anche se da già un po seguo il forum. Fra le tanti post interessanti ne ho trovato uno in particolare...pilota per ardupilot, ma troppo complesso x me...non riesco a stargli dietro, quindi ho deciso di cominciare da zero.

Detto questo, avendo il mio arduino, mi sono preocurato un accelerometro 3 assi,(motori,eliche, radio ecc li avevo già) ed ho cominciato...

ecco un video dei miei test.

(perche non riesco ad aggiungere un video sul post???come si fa??))

Primo problema: :o
il sensore sembra essere troppo sensibile alle vibrazioni provocate dai motori, infatti , tenendolo in mano il tutto funziona discretamente, mettendolo sul telaio le letture sono imprecise, facendo impazire i motori.
come primo tentativo per rimediare ho fatto:
una prima lettura,
delay(5),
seconda lettura
confronto fra le due letture
scrittura.

nel video si vede lampegiare il led al pin 13, indica ke le letture coincidono.
con questo sistema va meglio...ma non credo possa ancora stare in aria...
stavo pensado di far calcolare una media dalle letture...
ovviamente si accettano consigli/collaborazioni...
cmq, continuerò ad aggiornare il post...sprando di suscitare qualke interessante collaborazione...
saluuuuuti
:sunglasses:

ciao maxmili80
2 possibilitá
o fai una media di piú letture oppure colleghi 3 condensatori sulle uscite del sensore in modo da fare elettricamente una media. grandezza tra 1 e 10 µF.
Ciao Uwe

Ottima intuizione quella dei condesatori! :wink: ci ho già provato, ma solo con uno..il difetto era uguale, ma rispondeva più lentamente....come dici di collegarne 3?? Premetto che al momento, solo per i test, sto usando solo uno degli assi del sensolre, dopo mi basterà fare "copia incolla" ... Cmq non mi arrendo...

buongiorno....scusate ma sono nuovo nuovo...se posso provare a darvi un consiglio...poco elettronico ma molto piu pratico....ma cosa ne pensi di mettere un quadratino di gommapiuma tra il telaio e il sensore...o qualcosa che possa attenuare le vibrazioni...con poca densità...tipo della spugna...o qualcosa del genere...magari ci hai già pensato...ma passavo di qua e se fossi nelle tue stesse condizioni e quello che avrei fatto....
booo che dici? :wink:

ciao
@ maxmili80
Il sensore misura l'acelerazione nelle 3 assi e ha 3 uscite. Ogni uscita deve avere un condensatore.
@ mkmax
Ti serve una massa che fa da inerzia per il sensore. che devi collegare molleggiato all' apparecchio. 2 problemi: masse é peso; un sitema molleggiato ha una frequenza di risonanza.
ciao Uwe

prova ad ancorare il sensore alla strruttura portante con due strati di nastro bi-adesivo (quello morbido bianco in schiuma) io avevo risolto cosi'.

ho alcune domande:

  1. che motori usi?
  2. che radiocomando usi e come lo hai interfacciato con arduino?
  3. che struttura userai?
  4. come piloti i motori?
  5. usi una lipo? e se si come la ricarichi? metterai un circuito di carica embedded oppure il classico caricatore esterno?
  6. pensi che un solo accelerometro ti basti per un quadcopter oppure ne metterai diversi?

io voglio costruirmi un elicottero però con 3 bracci. sono sempre in fase di progettazione però!

Per un quadricottero o tricottero consiglio:
se potete motori brushless consumano meno e sono piu' efficienti, certi hanno rapporti perso/potenza assurdi!! Ci sono motori da 250w che pesano meno di 250g!! :o :o un esempio:
http://www.hobbyking.com/hobbycity/store/uh_viewItem.asp?idProduct=4917&Product_Name=HXT_35-42A_1450kv_Brushless_Outrunner_(Eq:_2820)
io ne sto montando uno decisamente piu' grosso su una bici da downhill con in mezzo il cambio della bici.
Questa era la versione 1:

Cmq tornando ai cotteri, per giroscopi/accelerometri consiglio di guardare nel mondo del modellismo, esistono dei tail block gyro con uscita servo, cioè comandano direttamente il servo del rotore di coda per mantenere elicottero in assetto che costano davvero poco. con la funzione pulseIn() leggi il dato (Gioblu.com is for sale | HugeDomains).
Credo che se si vuole un co-pilot automatizzato che faciliti la guida tramite telecomando possano bastare due giroscopi.
Se lo si vuole fare autonomo imu 6 assi per forza ;D

Se volete spendere poco motori dc classe 900 sono ottimi accoppiati tramite ogiva in alluminio ed eliche in plastica per aerei lenti
se usate motori dc lipo per forza se no non si alza credo
se usate brushless nicad nimh possono andare ma per voli brevi (durano poco e non ne potete imbarcare molte perchè pesano).

Ma direi che chi dovrebbe parlare qui dovrebbe essere redfox74 e mostrare il suo capolavoro

Quante belle domande ... :slight_smile:
Io provengo dal mondo del modellismo (per hobby) a dall'elletronica (per lavoro) sto cercando di unire i mondi.
Per uwefed, avevi ragione, ho rimesso un condensatore, ma un po più grande, siamo a 47 µF, ed insieme alla doppia lettura che dicevo, ho risolto il primo grande problema. Di seguito i test ...

1

2

3

ho scoperto acnhe una GRANDE cosa: quando arduino opera e si alimenta attraverso il cavo usb, rallenta parecchio :o, provabilmente per il flusso dei dati con il pc; infatti , alimetnandolo con apposita alimentzione esterna ...mette il turbo...DA NON DIMENTICARE PER IL FUTURO...
I motori sono i famigerati brushless(con appositi regolatori che si comportano più o meno come un servo), che il buon gbm sponzorizza..vanno stra-benissimo!!!! e le celle li-po(costano un po) ed hanno una particolare procedura per la carica...infatti i carica, sono abbastanza complessi...
Per interfacciare la radio non è difficile...ne parliamo fra qualche giorno...
Buona anche l'idea di ammortizzare le vibrazione, in maniera "ardware" ci avevo pensato, ma non ho ancora provato...anche se le cose adesso sembrano andare abbastanza bene...
Per il momento è tutto...a presto!!!!!

Per filtrare il segnale dell'accelerometro (o di qualsiasi altra cosa) un'altra soluzione potrebbe essere quella di implementare un filtro di kalman, ho visto che ne parlavano sul forum internazionale.
Il mio parere che non è quello di un esperto è che questa soluzione è troppo esagerata per un Arduino, visto che non ha capacità di calcolo straordinarie e poi dietro c'è una teoria mica da poco.

W la gommapiuma

Grande Max complimenti ottimo risultato!!
Magari se puoi posta il codice!!

Nn male l'idea del bi-adesivo...che combinata all'idea della massa inerziale di uwefed, potrebbe dare discreti risultati.
Quindi proverò mettendo 2 strati di biadesivo..una moneta(giusto per provare), altri 2 strati..ed in fine il sensore.

al momento preferisco postaee solo il codice riguardante al test con il servo...

#include <Servo.h>
Servo servo1;

int xpin = 0, xpin1 = 0; //prima e seconda lettura asse x
int val, val1; // variabile di lettura asse X
int led = 13;

void setup()
{
servo1.attach(9); // collegamento
Serial.begin(9600);
pinMode(led, OUTPUT);
}

void loop()
{
val = analogRead(xpin); // legge valore dal sensore(da 363 a 284) 1° lettura
val = map(val, 363, 284, 0, 180); // imposta scala

delay(5); //attesa per 2° lettura
val1 = analogRead(xpin1); // legge valore dal sensore(da 363 a 284) 2° lettura
val1 = map(val1, 363, 284, 0, 180); //imposta scala
if (val == val1) //confronto letture
{servo1.write(val), //scrittura sl servo
digitalWrite(led, HIGH); //scrittura su led
}
else
{
digitalWrite(led, LOW);
}
Serial.println();
Serial.print(val);
Serial.print(" VAL ");
Serial.print(val1);
Serial.print(" VAL1 ");
}

(ma xkè non mi funzionano i tasti per inserire??ma c'è qualche trucco?? devo chiedere attivazione??)

Il prossimo passo sarà quello di miscelare il risultato della lettura, per dividerlo ai 2 motori dell'asse, cioè, i giri che tolgo ad un motore li aggiungo all'altro e viceversa....presto vi informerò...
Ciauuuuuu

Rieccoci con un problema...ed ammeto che questo mi sembra più scocciante. >:(
fin ora ero riuscito senza grandi problemi a leggere i dati di un accelerometro, e scriverlo in un servo; ero riuscito senza problemi a leggere il segnale PPM dalla mia ricevente e scrivere su un servo...qui nasce il problema: unendo i due codici, tutto continua a funzionare..ma a rallentatore, cioè i servi vengono aggiornati circa ogni secondo...anche le letture sulla seriale sono molto lente...
Non credo che sia questione di prestazioni fisiche...almeno spero..
Tempo fa ho visto un codice con una libreria servodecode.h...qualcuno ne sa qualcosa??

Consigli???

#include <Servo.h> 
 
Servo servo1, servo2;             //motori 1 e 2 asse x
Servo servo3, servo4;             //motori 1 e 2 asse x

int xpin = 0, xpin1 = 0;          //prima e seconda lettura asse x accelerometro
int ypin = 1, ypin1 = 1;          //prima e seconda lettura asse y accelerometro

int valx, valx1;                  // variabile di lettura asse X accelerometro
int valy, valy1;                  // variabile di lettura asse y accelerometro

int assex, assey;

int  letturagas = 7, letturaroll = 6;              //ingresso segnale radio GAS,ROLL
unsigned long gas, roll;                //variabile di lettura(radio)
int led = 13; 

void setup() 
{ 
  servo1.attach(9), servo2.attach(10);                 // collegamento motori assex
  servo3.attach(11), servo4.attach(12);                // collegamento motori assey
  Serial.begin(9600);                                  //imposta letturagas imput
  pinMode(letturagas, INPUT),(letturaroll, INPUT);
  
  pinMode(led, OUTPUT);
} 
 
void loop() 
{ 
  valx = analogRead(xpin);                // legge valore x dal sensore(da 363 a 284) 1° lettura
  valx = map(valx, 363, 284, 0, 180);     // imposta scala
  valy = analogRead(ypin);                // legge valore y dal sensore(da 363 a 284) 1° lettura
  valy = map(valy, 363, 284, 0, 180);     // imposta scala

  delay(2);
  valx1 = analogRead(xpin1);               // legge valore dal sensore(da 363 a 284) 2° lettura
  valx1 = map(valx1, 363, 284, 0, 180);    //imposta scala
  valy1 = analogRead(ypin1);               // legge valore dal sensore(da 363 a 284) 2° lettura
  valy1 = map(valy1, 363, 284, 0, 180);    //imposta scala
  if (valx == valx1)                        //confronto letture asse x
  {servo3.write(valx),
   digitalWrite(led, HIGH);               //scrittura su led
 }
   else
 {
   digitalWrite(led, LOW);
 }
   if (valy == valy1)                        //confronto letture asse x
  {servo2.write(valy);
  }
  gas = pulseIn(letturagas, LOW);
  gas = map(gas, 870, 1990, 0, 180);        //imposta scala gas
  roll = pulseIn(letturaroll, LOW);
  roll = map(roll, 870, 1990, 0, 50);       //imposta scala roll
   
  servo1.write(gas);                        //scrive gas su servo2
  Serial.print(gas);
  Serial.print("  gas ");
  Serial.println();  
  Serial.print(valx);
  Serial.print("  VALx ");  
  Serial.print(valy);
  Serial.print("  VALy ");
}

ciao maxmili80

Usa una velocitá della seriale piú alta. Puoi andare fino a 115200.
Spesso quello rallenta tanto l'esecuzione di un sketch. Devi considerare che 9600 Baud sono meno di 1kbyte al secondo.

Domanda: la fiunzione pulseIn() blocca l' esecuzione dello sketch? nel senso continua l' esecuzione o l'arduino aspetta finche la lettura sia terminata - cosa analoga al delay()?

Ciao Uwe

Complimenti max, molto utile!
Sperimento la stessa anomalia con tutti i codici in cui "decodo" impulsi servo tramite pulseIn() ho paura che mentre aspetta la fine dell'impulso non possa fare nient'altro!!

Usa una velocitá della seriale piú alta. Puoi andare fino a 115200.

Questo può valere per la lettura sulla seriale, ma non credo possa rallentare l'esecuzione del codice...temo invece che il comportamento sia proprio quello del delay, e se così fosse sarebbe un problema...MA stanotte il lampo di genio...almeno credo...devo trovare il modo di convertire il mio ppm, in 0-5 Volts, in maniera ardware ed in questo modo, potrei dare ad arduino 4 segnali analogici( uno per canale della mia radio) e quindi diminuire il carico di lavoro...pernsavo di usare la semplice elettronica di un servocomando, o un regolatore...oppure...si accettano consigli.. :-/

Ciao maxmili80
Devo contraddire anche una seriale con velocitá lenta Ti rallenta tutto lo sketch perché serve tempo per spedire i dati via seriale.
Ciao Uwe

Son d'accordo ma a 9600 gira cmq veloce noi stiamo parlando di un paio di loop al secondo, direi che decisamente lento!! Credo che il problema sia pulseIn o map() applicato alla lettura di un impulso servo.

Sí, ma tutto fa brodo; maxmili80 trasmette 36 caratteri per loop. se conti che un carattere ci mette ca 1 milisecondo (9600 Baud a 10 a 11 bit/byte) sono solo lí sopra 40 mSec che ralentano (calcolo molto approssimato).
Ciao Uwe

Io non vorrei contraddire nessuno, e cmq proverò ad eliminare il "Serial.begin(9600); dal codice, ma il rallentamento dovuto alla velocità della seriale potrebbe avere senzo se arduino fosse collegato alla usb...ma con o senza il cavo non cambia niente, ricordiamoci che durante i miei test alimento la sheda a 12 volts...