![]() |
Citazione:
:yeah: |
Rispolvero la discussione perché, dopo aver accantonato per qualche mese il progetto, lo sto riprendendo in mano. Alla fine avevo creato uno sketch che sfruttava i dmp interni dei due MPU6050. Al bus i2c sono collegati i due sensori e un cristalli liquidi. Avevo imbastito un buon 80% del programma con i menù e un' autocalibrazione che, provato a pezzi, funzionava. Alla fine ho cablato il tutto, messo assieme il codice e non funzionava più nulla. Adesso stò riprendendo in mano l'accrocchio e mi accorgo che probabilmente non funziona nulla a causa dell'eccessiva lunghezza dei cavi che non va d'accordo con il bus I2c. Avete suggerimenti per far funzionare il tutto? So che esistono I2c extender ma, forse, piuttosto che mettere 4 I2C extender, conviene mettere due arduino pro mini a fianco dei sensori e trasformare la comunicazione da I2c a seriale. Questa soluzione mi scoccia parecchio perché dovrei mettere mano al codice ma mi permetterebbe di dividere il codice su 3 arduino che, a quel punto lavorerebbero in scioltezza. Considerando che allo stato attuale gira tutto su un arduino nano con flash e EEPROM quasi piene... |
Citazione:
Hai usato resistenze di pull-up ai 5V e che cavi usi ? Il bus I2C va a 400kHz o 100kHz ? :yeah: |
Non ho usato resistenze di pull up affidandomi a quelle integrate nella scheda. Come cavo ho usato un vecchio cavo di rete che avrà certamente alta capacità essendo twistato e i cavi saranno lunghi meno di un metro l'uno. Se mi dici che utilizzando resistenze di pull up posso risolvere faccio delle prove in quella direzione. Considera che per me è tutta una esperienza nuova e ogni volta che faccio qualcosa la devo studiare per impararla. Già l'aver scritto tutto quel codice per me è stato uno sforzo enorme. Inviato dal mio Mi A1 utilizzando Tapatalk |
Piccola precisazione: le resistenze di pull up dovrebbero essere presenti sulla scheda. Proverò ad aggiungerne di più grandi se può fare la differenza ma non so se posso modificare il circuito. Stasera ci guardo Inviato dal mio Mi A1 utilizzando Tapatalk |
Spero di non aver detto castronerie. Inviato dal mio Mi A1 utilizzando Tapatalk |
Sono in viaggio e ne ho approfittato per spulciare lo schema della scheda gy 521 contenente il mpu6050 , sembra che siano previste resistenze di pull up da 4.7K. Evidentemente non è quello il problema. L'unico dubbio è che, siccome la scheda può essere alimentata a 5V ma l'MPU lavora a 3.3 può essere che non sia tollerante ai segnali a 5V provenienti dalla Arduino e dal display. In rete ho visto millemila applicazioni di gy521 collegate direttamente all Arduino. Inviato dal mio Mi A1 utilizzando Tapatalk |
Per la comunicazione I2C è importante che i livelli del segnale siano congrui, cioè se la MPU prevede sui segnali SCK e SDA un livello di 3,3V anche il micro deve poter funzionare con tali tensioni e le resistenze di pull up vanno connesse al +3,3V e di valore adatto (3,3kohm in genere vanno bene) nel caso ambedue i dispositivi abbiano i pin 5V tollerant è bene mettere le resistenze di pull up (4,7kohm) al +5V. Altro punto importante è, se possibile, configurare i pin in modo Open Drain e non PushPull; essendo i segnali SDA e SCK non bilanciati non penso sia indicato usare un doppino twistato, meglio un classico flat cable. :yeah: |
Mi sono procurato uno scatolone di convertitori di livello (me ne serviva uno ma tant'è...) e, effettivamente, sembra andare meglio ma, dopo un po' che l'ambaram funziona, comincia ad impallarsi. Probabilmente una libreria simil wire.h non bloccante potrebbe aiutare ma non può essere quella la soluzione al problema. Idee? Gli I2c extender non mi piacciono molto come soluzione. Ne andrebbero usati 4 (due per sensore, o sbaglio?) e allora preferirei mettere un paio di arduini pro micro assieme ai sensori che si occuperebbero di comunicare con i sensori tramite I2C (a breve distanza) e un terzo arduino che si occuperebbe di interfacciarsi con il resto dell'hardware. In questo modo dovrei trasferire gran parte del codice sui due arduini in periferia e sgraverei un po' l'arduino che prima doveva occuparsi di tutto. Facendo tutto ciò però dovrei comunicare in seriale, purtroppo gli arduino che ho possiedono solo una seriale. Potrei risolvere con un arduino mega (che non ho) o con un arduino due (che ho e che non ho mai usato) ma mi sembra di starmi addentrando parecchio nell'ufficio UCAS. Se avete idee illuminanti (dal basso della mia esperienza a me ne vengono poche) sono tutt'orecchi. |
Citazione:
Per prima cosa tutti i dispositivi devono usare la stessa tensione del bus I2C o 3,3V o 5V e quindi un pull-up unico, fare mescola e combina non va bene, se hai bisogno di un convertitore di livello del bus, le resistenze di pull-up vanno messe sia in ingresso che uscita del convertitore. Altri punti importanti sono: - gli indirizzi dei dispositivi devono essere tutti differenti. - la frequenza del bus I2C deve essere la più bassa di quelle accettetata dai dispositivi connessi. - quando connessi singolarmente i dispositivi devono funzionare in modo affidabile e sicuro. Se come dici, il sistema per un po funziona e poi si impalla il problema è da ricercare nel fw e non nel hw; probabilmente hai temporizzazioni d'interrogazione errate o routine che interferiscono a vicenda (occhio se usi più di un interrupt). Come ho scritto per leggere 8 sensori sul bus I2C utilizzo un micro a 32bit, però ho realizzato anche uno strumento "da cantiere" basato su Arduino Mega 2560 che non solo legge i sensori, può programmarne gli indirizzi fa da tester hw, li visualizza su display touch a colori e può anche loggare i dati scrivendoli su una SD, quindi anche il piccol Arduino ce la può fare.... :wink: http://win.wallytech.it/public/Tester_HIH_17.JPG http://win.wallytech.it/public/Tester_HIH_18.JPG http://win.wallytech.it/public/Tester_HIH_19.JPG :yeah: |
Citazione:
Siccome l'arduino e il display viaggiano a 5 V ho messo il convertitore tra l'arduino e i due sensori. I due sensori sono collegato in parallelo (ovvio) con DUE cavi di circa un metro per ogni cavo. Il convertitore di livello converte i segnali da 3V a 5V e viceversa. Il parallelo tra i SCL e SDA dei sensori è al comparto a 3.3V del convertitore. Al comparto a 5 V c'è il parallelo tra convertitore e I2C del display. Le resistenze di pull up non le ho messe perchè sia arduino sia schede dei sensori dovrebbero averle già a bordo. Quì trovi lo schema dell'integrato GY-521 che monta il sensore MPU 6050 http://www.haoyuelectronics.com/Atta...GY-521-SCH.jpg Gli indirizzi sono ovviamente diversi. La frequenza non dovrebbe essere il problema perchè ho provato diverse frequenze senza successo mentre ho avuto successo quando provavo i pezzi del programma con i sensori vicino all'arduino su bread board. Lo sketch utilizza due interrupt provenienti dai sensori (uno a testa) che insicano all'arduino quando il buffer del sensore è pieno e vanno scaricati i dati. |
Citazione:
Come seconda cosa non utilizzare interrupt dai sensori ma vai in polling degli stessi e controlla il bit di (data ready), l'ideale sarebbe avviare da sw lo start di lettura del sensore ed attendere che i dati siano disponibili e poi passare al successivo. In alternativa dare lo start di lettura in rapida sequenza ad ambedue i sensori e poi attendere in polling il risultato, quindi elaborare i dati e poi mandarli al display. Il problema al 90% è imputabile al fw, i due interrupt possono arrivare insieme od a breve distanza e poichè Arduino non brilla per la gestione degli stessi è facile incappare in un blocco del sistema o nella lettura di dati farlocchi. Come consigliato prova prima, dopo le modifiche hw, con un solo sensore e senza interrupt, poi aggiungi il secondo. :yeah: |
Dopo essermi documentato mi è parso di capire che la gestione delle routine di interrupt sia non simultanea ovvero il secondo interrupt attende la fine dell'esecuzione del primo per avviare la sua funzione. In ogni modo le 2 funzioni di interrupt mettono semplicemente a 1 una variabile booleana che, a sua volta, attende di essere letta per avviare con un if la funzione di lettura dati. In ogni modo domani sera mi rileggo il tuo messaggio e cerco di capirlo meglio, studio e provo a fare come mi hai consigliato. Intanto ti ringrazio infinitamente per l'aiuto. PS. dopo aver letto in rete ho appreso che la libreria wire.h è bloccante ovvero, in caso di errore sul bus, rimane in un loop infinito all'interno di un while(). Potrei risolvere con una libreria (se esiste) non bloccante ma preferirei eliminarli quegli errori piuttosto che accettarli ed ignorarli. |
Citazione:
|
Citazione:
In altri casi ci sono dei dispositivi (a memoria anche Arduino) che consento di disabilitare i pull-up-dwn settando dei bit in un registro. :yeah: |
Citazione:
Inviato dal mio Mi A1 utilizzando Tapatalk |
Ho guardato le schede GY-521, puoi dissaldare le resistenze dal PCB, sono marchiate "222" levale e prova. sono quelle vicino a C3. :yeah: |
Ho provato di tutto a parte il dissaldare le resistenze di pull up delle schede. Le pull up sull Arduino le ho cambiate ma nulla. Gli interrupt li ho tolti ma nulla. Oramai mi rimane solo cercare una soluzione software ai blocchi della libreria. Ho provato una libreria wire non bloccante ma non funziona, evidentemente è stata fatta per vecchie versioni dell IDE e su quella più recente non funziona. Avete idea di come fare a rendere non bloccante la libreria wire? Ho anche incluso la libreria liquidcrystal i2c ma mi sembra di capire che faccia uso anche lei a sua volta della wire.h. Inviato dal mio Mi A1 utilizzando Tapatalk |
Aggiornamenti finali Alla fine ho portato a termine il progettino ma ho cambiato completamente strada. Ho abbandonato l'idea del processore centrale con display unico LCD I2C e i due giroscopi montati sulle unità di misura. Ora ho due arduino pro mini , ognuno a bordo di un'unità di misura, che pilotano due display a 7 segmenti e 4 cifre e che ricevono direttamente i dati dai sensori. Una di queste unità è master ed è dotata di batteria mentre l'altra è slave e riceve tensione dalla prima. Le due unità dialogano tramite seriale in modo da lasciare il bus I2C libero per il sensore. Ora il tutto funziona benissimo e ho potuto anche mettere qualche menù e qualche controllo della tensione della batteria. Detto questo però non sono mai riuscito a capire il perchè il primo approccio non funzionasse e mi mandasse in tilt l'arduino (o i sensori). Questa settimana ho dovuto fare delle prove per lavoro con un sensore giroscopico/accelerometrico ed ho imbastito una sorta di plc "casereccio" con un arduino uno, qualche relè ed il buon vecchio lcd avanzato dal "vecchio" progetto. Stessi problemi e stesse noie!!! Stavolta non c'erano problemi di cavi e di lunghezze degli stessi perchè ho preparato una scheda con una piastra preforata. Il sensore era nuovo. A questo punto ho cambiato il codice eliminando l'utilizzo del DMP del sensore e dell'interrupt ed ho fatto fare i calcoli all'arduino invece che al sensore; così facendo tutto funziona in modo stabile e senza problemi. A questo punto mi vien da dire che il problema non fosse affatto il bus I2C ma qualcosa d'altro legato all'interrupt, non so che dire. Di fatto l'interrupt mette semplicemente a 1 una variabile booleana che poi, tornando al loop, avvia il processo di scarico dei dati dal buffer del sensore. Mi vien da pensare che se l'interrupt viene avviato durante una comunicazione sul bus I2C (ad esempio con il display) la comunicazione I2C salti (il bus I2C non è tollerante agli errori). Boh.. |
A proposito di giroscopi: Mi sarebbe servito un giroscopio preciso che rilevasse l'angolo con l'orizzontale di una barra che sale e scende sorretta da due cilindri pneumatici all'estremità. Mi son trovato che il MPU6050 non è affatto abbastanza veloce e preciso per il lavoro che serviva a me. Probabilmente ho sbagliato qualcosa ma ho provato anche a variare i fondoscala dei sensori senza trarne beneficio. Avete da consigliarmi qualche giroscopio che possa fare al caso mio e che possa correggere la deriva con l'accelerometro che sia facile da gestire (magari analogico) ? Grazie |
Citazione:
Usando anche solo due assi e giocando con la trigonometria leggo l'assetto con la precisione di 1/20° anche con escursioni termiche da -30°C a +40°C, se è richiesta velocità per i calcoli un Arduino Nano forse è un poco limitato, anche perchè per ottenere la stessa precisione su 180° è necessario implementare una tabella per la linearizzazione, se la ritrovo ti giro una application note che spiega bene gli algoritmi necessari, se ti servisse posso mandarti il pezzo di programma in C che realizzai. :yeah: |
Il programma lo leggo volentieri. In ogni modo temo che il problema sia proprio l'accelerometro, a mio avviso, che legge anche le vibrazioni e le scambia per variazioni angolari. Devo provare a fare fare i calcoli all'Arduino e non al dmp interno filtrando i valori dell'accelerometro. Inviato dal mio Mi A1 utilizzando Tapatalk |
1 Allegato/i Questa è la parte del programma che legge tramite AD i canali X e Z dell'accelerometro, effettua alcuni calcoli preliminari, linearizza e poi rende il risultato finale in 1/10°, cioè 90,0° = 900; trasmettere numeri interi richiede meno tempo e memoria che inviare dei float. naturalmente è scritto in C puro e per un PIC18Fxxx quindi non è direttamente usabile con Arduino, se hai dubbi chiedi pure. :yeah: |
Quando termino le ferie me lo leggo con calma. Intanto grazie. Inviato dal mio Mi A1 utilizzando Tapatalk |
Hai provato e risolto ? :yeah: |
Ho letto il tuo codice, tu usi il processore in maniera molto più efficiente di come lo uso io ed ho preso spunto per migliorare il mio codice, di fatto però la sostanza non cambia molto, solo l'esecuzione è più veloce (forse). Tu hai fatto una livella con solo accelerometri, nel mio caso non va bene perché l'accelerometro fornisce un output sporco e non può essere letto velocemente e senza filtri, ecco perché della necessità di usare anche il giroscopio. Per quanto riguarda l'incidenziometro ho risolto cambiando l'approccio ed usando due arduino che comunicano in seriale e non in I2c eliminando anche il display che comunicava anche esso in I2c. A tempo debito però svilupperò anche la prima versione del progetto perchè PENSO finalmente di aver capito che il problema sia la comunicazione I2C che veniva interrotta dagli interrupt dei sensori e bloccava il codice. Rinunciando ad utilizzare il processore interno dei sensori e facendo fare tutti i calcoli all' Arduino non avrei più necessità di usare l'interrupt e potrei aver risolto il problema. Questa cosa mi era stata consigliata all'inizio della discussione ma non ho dato il giusto peso al consiglio. Probabilmente un programmatore capace avrebbe intuito il problema alla svelta, io ci ho messo un po' di più (sempre che il problema fosse quello). Per quanto riguarda l'altra applicazione ho deciso che l'utilizzo di un sensore come questo rende l'applicazione troppo complessa ed ho optato per l'utilizzo di sensori lineari che forniscono informazione precisa e diretta della posizione delle due estremità della barra, una semplice sottrazione mi dà poi l'informazione del dislivello, che è quello che mi interessa. La seconda soluzione è più costosa ma più semplice, più diretta e sicura. |
Citazione:
Per il resto se hai problemi di velocità di acquisizione e necessiti di filtraggio è meglio che abbandoni Arduino Uno (ma anche MEGA) e passi ad altri processori, molto indicati allo scopo sono i dsPIC della Microchip, capisco che Arduino sia come il prezzemolo perchè apparentemente semplice da programmare ma quando il gioco si fa duro mostra tutti i suoi limiti specialmente se si utilizza il suo IDE e le librerie preconfezionate; programmandolo direttamente le prestazioni migliorerebbero non poco. Comunque se hai risolto facendo comunicare due Arduino con la seriale non dovresti avere grandi problemi di velocità d'acquisizione e per me basterebbe usare solamente un accelerometro, la fusione di dati da acc+gyro comporta calcoli complessi e molto lenti su un UNO. IMHO :yeah: |
Citazione:
Per quanto riguarda l'inclinometro problemi di velocità non ce ne sono perchè tanto è uno strumento che deve misurare l'inclinazione dell'ala e può essere lento quanto vuole. Mi ero impuntato ad usare il processore interno dei sensori proprio perchè volevo sgravare l'arduino dai calcoli di sensor fusion. Di fatto, se si usa un filtro complementare e non si ha bisogno di grande velocità di esecuzione un atmel 328 può anche andare. La sensor fusion a questo punto serve più che altro per pulire e filtrare il dato degli accelerometri che è molto sporco di suo e sente tutte le vibrazioni, fa le veci della media in virgola mobile. Per quanto riguarda il problema della barra invece l'esperimento che ho fatto con Arduino mi serviva solo per capire se fosse una strada applicabile senza comprare sensori commerciali e tutta l'attrezzeria che necessitano per funzionare. Sono sicuro che con dei sensori commerciali confezionati ad hoc il sistema potrebbe anche funzionare ma l'esperimento mi è bastato per scartare questa possibilità in quanto troppo complessa. Preferisco sempre soluzioni semplici, anche se sono più costose. Alla fine ci sarà un plc che si occuperà della lettura dei sensori oltre alle altre cose. |
In ambito industriale concordo con la scelta di un PLC + sensori dedicati specialmente se esistono soluzioni già testate e chiavi in mano. Per il filtraggio io ho usato una doppia media mobile perchè il movimento dell'asse verticale dei pannelliFV è estremamente lento e pressochè privo di vibrazioni o giochi meccanici, in altri casi ho implementato filtri FIR ed IIR progettati in funzione del tipo di disturbo e/o tempi di risposta richiesti, misurare l'nclinazione con un giroscopio comporto o un tempo di campionamento fisso e preciso (come normalmente avviene con il mio micro S.O.) oppure un calcolo aggiuntivo per il deltaT dello stesso. Se non è richiesta velocità anche Arduino ce la può fare, quello che trovo strano è che in un sistema quasi statico, come quello dell'incidenziometro, l'uscita dell'accelerometro fosse molto "sporca", dovresti provare a misurarla e visualizzarla con un accelerometro analogico ed un oscilloscopio. :yeah: |
| Tutti gli orari sono GMT +2. Adesso sono le 23:36. |
Basato su: vBulletin versione 3.8.11
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
E' vietata la riproduzione, anche solo in parte, di contenuti e grafica. Copyright 1998/2019 - K-Bits P.I. 09395831002