Salve a tutti,
mi scuso dal principio se ho sbagliato sezione, ma non sono molto pratico del forum...
premesso che sono alle prime armi con Arduino e solo un pelino più esperto di programmazione mi sto scervellando su un progettino che prevede di tenere in equilibrio un leggero robottino grazie ad una IMU e due servo del lego NXT(per usare qualcosa che già ho in casa). Questo progetto è diventato una sfida con me stesso; vi spiego il mio problema:
Utilizzo una Arduino Uno per leggere attraverso il protocollo SPI una piattaforma inerziale (IMU, accelerometro+giroscopio) a sei gradi di libertà che mi restituisce roll, pitch e yaw e che sembra funzionare decentemente. Utilizzo i pin D10, D11, D12, D13 e l'interrupt 0 cioè il pin D2. Inoltre grazie ad un codice preso dal web ho anche corretto il drift, la deriva che infettava le mie rilevazioni.
Sto cercando di fare un test: voglio avere un movimento delle ruote quando muovo la mia IMU, ovviamente sensato e legato a quanto "sbanda" la IMU, poi quando avrò più tempo buttero giù qualcosa inerente alla struttura e ultimerò il progetto.
Per collegare i 2 servo uso una motor shield inserita sopra alla Arduino uno e anche i servo li controllo senza problemi.
I problemi arrivano quando voglio comporre il sistema collegando i due motori e la imu alle shield: i pin 3,8,9,11,12,13 me li occupa la motor shield per il controllo dei motori e non posso usarli per la IMU. Sono andato quindi dentro la libreria SPI e ho modificato il file pins_arduino.h ridefinendo altri pin per SCK MISO e MOSI, (avendo letto in giro per il web che è meglio non toccare il CS o SS, lo ho lasciato legato al pin 10). Dopo la ridefinizione però la IMU non ne vuole più sapere di restituire alcun valore. (non ho dimenticato di attaccare il pin di interrupt) :0 :0
Mi chiedo quindi se sia possibile fare la ridefinizione che ho fatto io o se manchi qualcosa da quello che sto considerando!! Se funzionasse potrei attaccare la shield e procedere... :~
Non so se usare le due shield separatamente (non so nemmeno se sia possibile); ho pensato anche di usare la imu con arduino uno e un ponte h per i motori (escludendo dal giro la motor shield che mi frega i pin di cui ho bisogno per l'SPI), ma mi giocherei la comodità della shield per i motori e di una libreria molto utile con funzioni per leggere gli encoder dei motori LEGO.
Riesco a fare convivere la IMU e la motor shield nello stesso sistema?
Probabilmente esiste una soluzione semplice al mio problema, ma non capisco proprio come fare...
NXTfreeDOmF:
Sono andato quindi dentro la libreria SPI e ho modificato il file pins_arduino.h ridefinendo altri pin per SCK MISO e MOSI, (avendo letto in giro per il web che è meglio non toccare il CS o SS, lo ho lasciato legato al pin 10).
Scusa ???
Spero di aver capito male io ... sei andato a cambiare la definizione di quali sono i pin di MISO, MOSI e SCK ???
Perché se è così ...
... invece di andare a leggere frescacce sul web, avresti fatto bene a leggere il datasheet della MCU e ti saresti accorto che i pin di MISO, MOSI e di SCK ... sono pin fisici che non è che puoi definire a tuo piacere !!!
Per l'esattezza sono i pin del chip : 17 -> MOSI, 18 -> MISO e 20 -> SCK che vengono riportati, sulla board di Arduino, rispettivamente sui pin 11, 12 e 13 e NON sono cambiabili !!!
... aggiungo ... che, salvo avere una vasta esperienza del core di Arduino e delle sue librerie ... NON DEVI TOCCARE i files di base di Arduino, pena il non funzionamento dei tuoi programmi e, per ripristinare una funzionalità del tutto, il dover ricaricare l'IDE ex-novo scaricandolo dal sito ufficiale !
Guglielmo ti ringrazio del tuo aiuto, purtroppo sono ancora un novizio a queste cose e faccio errori causa la poca esperienza.
Però mi hai fatto venire un dubbio: se non posso cambiare i pin del protocollo SPI chi ha progettato arduino come ha pensato di risolvere il problema di voler utilizzare pin che la motor shield occupa?
(Io per il mio progetto vorrei usare il protocollo SPI e non I2C.)
Purtroppo non tutte le shield sono compatibili con tutto ... per questo, nel reference dei prodotti, per ogni singolo prodotto, è descritto l'uso che fa dei pin.
E' responsabilità dell'utilizzatore verificare che non ci siano conflitti e pin in comune con altre cose che intende usare.
Ora, nel tuo caso ... purtroppo non credo ci sia una soluzione ... immagino che la Motor Shield abbia bisogno dei pin PWM (... per regolare la velocità dei motori) che, guarda caso, sono proprio i pin 3, 5, 6, 9, 10, and 11 e ... l'11 è anche il pin MOSI del bus SPI
Oddio ... magari una soluzione ci sarebbe pure, ma dovresti massacrare la Motor Shield per tagliare i pin in conflitto e rimapparli su pin liberi ... che dovrebbero esserci ... ... ma non mi sento di consigliarti una "porcheria" del genere !
NXTfreeDOmF:
Sono andato quindi dentro la libreria SPI e ho modificato il file pins_arduino.h ridefinendo altri pin per SCK MISO e MOSI, (avendo letto in giro per il web che è meglio non toccare il CS o SS, lo ho lasciato legato al pin 10).
Sicuro di non aver letto il contrario? Il pin CS/SS lo puoi cambiare con quello che vuoi, non è fisso. Come detto da @Guglielmo gli altri tre son fissi. Quello no. Anche perchè puoi collegare più sensori allo SPI e per ogni sensore devi usare un pin CS/SS che quindi non può essere lo stesso per ogni sensore.
"SS (Slave Select) - the pin on each device that the master can use to enable and disable specific devices."
nid69ita verissimo quello che dici! errore mio assolutamente!!
Le soluzioni sono due: o mi dimentico del protocollo spi in favore dell'i2c che usa altri pin oppure mi dimentico della motor shield e uso un L293 o simili per controllare i due servo
Purtroppo ho la necessità di usare l'SPI.
Non esiste una semplice soluzione per fare convivere nello stesso sistema un qualcosa che comunica spi e due servo!?
I motorini vecchi sono banali, a 9V, basta cambiare polarità e cambiano verso di movimento. Di solito i Mindstorm li pilotano con PWM per farli andare veloci/lenti.
Ma @NXTfree come li colleghi alla motor shield i NXT? Hanno un cavo speciale e molti fili, sai quali usare? E sai come leggere la posizione dell'encoder?
Mi interessa (senza friggerli però). Grazie
nid69ita se segui questa guida Synthesize-your-own NXT® connector plug ti ritrovi con sei cavetti attaccati alla breadboard:
blu secondo segnale encoder TACH1 PIN D4(deciso da me)
giallo primo segnale encoder TACH0 PIN D2(deciso da me)
verde 5 V (encoder) PER ALIMENTARE ENCODER
rosso GND
nero motor power
bianco motor power
Per collegare i motori alla shield definisci Direction e Pwm che sono legati a certi pin di default; io ho fatto così:
//USO SOLTANTO UN MOTORE(CHANNEL A)
int pinDirA=12; //D12
//int pinDirB=13; //D13
int pinPwmA=3; //D3
//int pinPwmB=11; //D11
//del mio motore uso l'encoder
pinMode( tacho0,INPUT );
digitalWrite(tacho0,HIGH);
attachInterrupt(0, encode, RISING);
l'ho omesso, ma anche Dir e Pwm vanno definiti come output usando pinMode(), inoltre bisogna definire un interrupt per l'encoder.
In alternativa si potrebbe usare la libreria Arduino2lego che prevede l'utilizzo di un ponteH L293D e qui torniamo al mio problema.
Qualcuno sa darmi qualche dritta per comandare il mio piccolo motore tramite arduino usando il ponte H?
NXTfreeDOmF:
Qualcuno sa darmi qualche dritta per comandare il mio piccolo motore tramite arduino usando il ponte H?
Se fai una ricerca qui sul forum per L298/L293 o simili, ti vengono fuori decine di risultati ...
... ne ricordo una in cui discutemmo quale era il modo corretto per comandarlo, QUI ... sono un paio di pagine, dagli una letta
@nid69ita c'è una cosa importante da dire! se usi la motor shield per dare una velocità ed una direzione ai motori sfrutti (di default) pin che, essendo così occupati, non ti permettono poi di attaccare un qualsiasi sensore, shield o altro che sfrutti il protocollo SPI, perchè da quello che ho capito per motivi hardware(fisici), l'SPI è legati ai digital pins 10,11,12,13...
Avendo necessità di usare una imu (la mpu6000 della drotek) e quindi occupare l'SPI, HO DOVUTO OPTARE PER L'UTILIZZO DI UN L293D PER IL CONTROLLO DEI MOTORI.
La funzione dentro all' attachInterrupt legge direttamente il valore dai registri (ho spulciato dal web se avessi dovuto cimentarmi io ci saremmo risentiti tra un mesetto )
Posto il codice:
//http://www.mauroalfieri.it/elettronica/tutorial-arduino-servo-2.html
//guarda anche l'uno
int encoderPin1 = 2;
int encoderPin2 = 3;
//int ledPin1 = 5; // PWM
volatile int lastEncoded = 0;
volatile long encoderValue = 0;
long lastencoderValue = 0;
int lastMSB = 0;
int lastLSB = 0;
void setup() {
Serial.begin (9600);
pinMode(12, OUTPUT); //abilita pin 12 come pin di uscita
pinMode(8, OUTPUT); //abilita pin 8 come pin di uscita
pinMode(encoderPin1, INPUT);
pinMode(encoderPin2, INPUT);
// pinMode(ledPin1, OUTPUT);
digitalWrite(encoderPin1, HIGH); //turn pullup resistor on
digitalWrite(encoderPin2, HIGH); //turn pullup resistor on
// analogWrite (ledPin1,LOW);
attachInterrupt(0, updateEncoder, CHANGE);
attachInterrupt(1, updateEncoder, CHANGE);
}
void loop() {
Serial.println(encoderValue);
if ( encoderValue > 255 ) { encoderValue = 255; }
if ( encoderValue < 0 ) { encoderValue = 0; }
// senso orario
digitalWrite(12 , HIGH); //pin 12 on
digitalWrite(8 , LOW); //pin 8 off
delay(4000); //gira per 4 secondi in senso orario
Serial.println(encoderValue);
if ( encoderValue > 255 ) { encoderValue = 255; }
if ( encoderValue < 0 ) { encoderValue = 0; }
//senso antiorario
digitalWrite(8,HIGH); //pin 8 on
digitalWrite(12,LOW); //pin 12 off
delay(4000); //gira per 4 secondi in senso antiorario
Serial.println(encoderValue);
if ( encoderValue > 255 ) { encoderValue = 255; }
if ( encoderValue < 0 ) { encoderValue = 0; }
}
void updateEncoder(){
int MSB = digitalRead(encoderPin1); //MSB = most significant bit
int LSB = digitalRead(encoderPin2); //LSB = least significant bit
int encoded = (MSB << 1) |LSB; //converting the 2 pin value to single number
int sum = (lastEncoded << 2) | encoded; //adding it to the previous encoded value
if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue ++;
if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue --;
lastEncoded = encoded; //store this value for next time
}
@NXTfree, ferma la mula!!!
Di quale motor-shield parliamo?
Perchè quella ufficiale di Arduino ha gli header passanti e nessuno vieta di usare i pin SPI (anche quelli fissi) per collegare altri sensori. Logicamente devi pensare ad un multi-SPI dove tutti i dispositivi usano i 3 pin fissi MOSI/MISO/SCK ma ogn'uno deve avere il suo pin di selezione (SS) che probabilmente per la shield è fisso a 10 ma per i tuoi sensori sarà un altro pin.
Il problema può essere nei comandi dei vari dispositivi, bisogna abilitarli/disabilitarli quando serve usando i vari pin SS (solo uno attivo alla volta)
Un momento.... mi sono perso: se attacco la motor shield alla mia arduino uno e nello sketch comando i motori in un qualsiasi modo... mi vuoi dire che se attacco all'SPI (10,11,12,13) UN solo device (la mia IMU) essa andrà!?
Function pins per Ch. A pins per Ch. B
Direction D12 D13
PWM D3 D11
Brake D9 D8
Current Sensing A0 A1
Mi era sembrato di capire che questi pin li occupa, come da link, la motor shield; volendo se ne hai bisogno puoi tagliare brake e current sensing, dopo di chè puoi usare quei pin. E' il motivo per cui sono ricorso all'L293D... ditemi che non ho sbagliato tutto...
ps. a supporto dell'idea che mi son fatto c'è anche il fatto che più di una persona si lamenti dell'uso che vien fatto nella motorshield del pin 3 (pin di interrupt), usato come power modulation per il canale A.
No, no, scusa. Mi sa che dico ca...volate.
Se la shield fosse un semplice dispositivo pilotato come SPI allora si, potresti usare quei pin con altri sensori.
Mi pare di capire, leggendo su sito della scheda ufficiale (e penso valga anche per altre tipo quella di Adafruit) che quei pin vengono usati in maniera esclusiva.
Function Ch.A Ch.B
Direction D12 D13
PWM D3 D11
Breake D9 D8
Current Sensing A0 A1
gpb01:
@ Nid : Il problema è che la Moto Shield usa un pin del SPI per ... il PWM dei motori ... e gli altri SPI ... per la direzione
Guglielmo
Si, e non come SPI lasciando spazio ad altri dispositivi SPI.
Ora non capisco però perchè aver occupato i pin SPI 11,12 e 13 ?!? Di tipo PWM c'e' ne sono altri, no?
Forse perchè la shield si può montare anche su Mega?
I pin PWM sono 3,5,6,9,10,11
La motorshield V1 di Adafruit lascia liberi i pin 2 e 13 ma anche lei usa per DC/Stepper 11,3,5,6
Mi pare che questa nuova MotorShield di Ardafruit (V2) invece usi I2C:
NXTfreeDOmF:
.... se ne hai bisogno puoi tagliare brake e current sensing, dopo di chè puoi usare quei pin.
.... più di una persona si lamenti dell'uso che vien fatto nella motorshield del pin 3 (pin di interrupt), usato come power modulation per il canale A.
-Giusto, se i brakes e i current senses non ti servono staccali così hai 4 pin liberi
-Per liberare il pin 3 taglia una pista sulla motor shield e fai un un ponte ad un pin con pwm
-purtroppo tempo che la SPI hardware sia inacessibile quindi puoi scrivere un driver per una soft-spi su qualsiasi pin libero oppure trovare una libreria già pronta , a te non serve estrema velocità quindi andrà bene