Napoli
Offline
Full Member
Karma: 0
Posts: 200
|
 |
« Reply #150 on: March 26, 2011, 07:46:33 am » |
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Tesla Member
Karma: 83
Posts: 8242
:(){:|:&};:
|
 |
« Reply #151 on: April 03, 2011, 06:27:56 pm » |
eccomiii!!!! finalmente ho avuto la voglia di scrivere la classe.... come al solito NON è testata, perché non ho i pezzi... se mi fate un po' di debug mi fate un favore, che la mettiamo nel playground ERER.cpp #import "ERER.h"
/* ERER.cpp - Library for ERER sensors. (use 2 infrared LEDs to build a distance sensor) Rewritten by Mauro Mombelli 03/04/2011 Based on code of Giovanni Blu Mitolo, March 11, 2011. Released with Creative Commons Attribution licence */
volatile byte _oldbit; byte _changed, _newbit; volatile boolean _hasChanged=false; volatile long rawDistance=0; volatile byte BCDreceiverN, BCDreceiverP, BCDemitterP; volatile byte MASKreceiverN, MASKemitterP, MASKreceiverP; volatile boolean emitterStatus; unsigned long _time; unsigned long _startIn[2]; unsigned long _rawIn[2];
ERER::ERER(byte PCINTemitterP, byte PCINTreceiverP, byte PCINTreceiverN){
//set emitterP pin mode BCDemitterP = getBCDpin(PCINTemitterP); //find BCD (see PortManipulation) MASKemitterP = (1<< (PCINTemitterP - (8*BCDemitterP) ) ); //find MASK for esy port manipulation //set as OUTPUT and HIGH switch (BCDemitterP){ case 0: DDRB |= MASKemitterP; PORTB |= MASKemitterP; break; case 1: DDRC |= MASKemitterP; PORTC |= MASKemitterP; break; case 2: DDRD |= MASKemitterP; PORTD |= MASKemitterP; break; } emitterStatus=true; //set receiverP pin mode BCDreceiverP = getBCDpin(PCINTreceiverP); //find BCD (see PortManipulation) MASKreceiverP = (1<< (PCINTreceiverP - (8*BCDreceiverP) ) ); //find MASK for esy port manipulation //set as OUTPUT and LOW switch (BCDreceiverP){ case 0: DDRB |= MASKreceiverP; PORTB &= ~MASKemitterP; break; case 1: DDRC |= MASKreceiverP; PORTC &= ~MASKemitterP; break; case 2: DDRD |= MASKreceiverP; PORTD &= ~MASKemitterP; break; } //set PCINTreceiverN as INPUT AND attach Interrupt /* remember: PORTB maps to Arduino digital pins 8 to 13 (PCIE0) form PCINT0 to PCINT7 PORTC maps to Arduino analog pins 0 to 5 (PCIE1) form PCINT8 to PCINT14 PORTD maps to Arduino digital pins 0 to 7 (PCIE2) form PCINT16 to PCINT23 */ BCDreceiverN = getBCDpin(PCINTreceiverN); MASKreceiverN = (1<< (PCINTreceiverN - (8*BCDreceiverN) ) ); //find MASK for esy port manipulation switch (BCDreceiverN){ case 0: PORTB &= ~MASKreceiverN;//set as INPUT PCICR |= (1 << PCIE0); //INTERRUPT ON PCIE0 CHANGE ACTIVATED PCMSK0 |= MASKreceiverN; //UMASKING INTERRUPT FOR PIN _oldbit = PINB;//To understand witch pin has changed break; case 1: PORTC &= ~MASKreceiverN;//set as INPUT PCICR |= (1 << PCIE1); //INTERRUPT ON PCIE0 CHANGE ACTIVATED PCMSK1 |= MASKreceiverN; //UMASKING INTERRUPT FOR PIN _oldbit = PINC;//To understand witch pin has changed break; case 2: PORTD &= ~MASKreceiverN;//set as INPUT PCICR |= (1 << PCIE2); //INTERRUPT ON PCIE0 CHANGE ACTIVATED PCMSK2 |= MASKreceiverN; //UMASKING INTERRUPT FOR PIN _oldbit = PIND;//To understand witch pin has changed break; } //charge ReceiverN using internal pull-up setStatus(BCDreceiverN, MASKreceiverN, true); //stop charge ReceiverP setStatus(BCDreceiverN, MASKreceiverN, false); }
long ERER::getRawDistance(){ return rawDistance; }
byte ERER::getBCDpin(byte PCINTpin){ if (PCINTpin>=0 && PCINTpin<=7){ return 0; } if (PCINTpin>=8 && PCINTpin<=14){ return 1; } if (PCINTpin>=16 && PCINTpin<=23){ return 2; } return 3; }
void ERER::setStatus(byte BCD, byte MASK, boolean state){ if (state){ switch (BCD){ case 0: PORTB |= MASK; break; case 1: PORTC |= MASK; break; case 2: PORTD |= MASK; break; } }else{ switch (BCD){ case 0: PORTB &= ~MASK; break; case 1: PORTC &= ~MASK; break; case 2: PORTD &= ~MASK; break; } } }
ISR(PCINT2_vect) { if (BCDreceiverN == 2){ _newbit=PIND; _changed=_newbit^_oldbit; if (_changed & MASKreceiverN){//if PCINTreceiverN has changed _time=micros(); _hasChanged=true; if (_newbit & MASKreceiverN) { //if PCINTreceiverN now is high _startIn[emitterStatus]=_time; }else{ _rawIn[emitterStatus]=_time-_startIn[emitterStatus]; if (!emitterStatus){ //if we read with emitter HIGH and then LOW we have a distace rawDistance = _rawIn[0]-_rawIn[1]; //because dark read teorically is lower than light read } //start a new reading changing emitter status emitterStatus!=emitterStatus; if (emitterStatus){ switch (BCDemitterP){ case 0: PORTB |= MASKemitterP; break; case 1: PORTC |= MASKemitterP; break; case 2: PORTD |= MASKemitterP; break; } }else{ switch (BCDemitterP){ case 0: PORTB &= ~MASKemitterP; break; case 1: PORTC &= ~MASKemitterP; break; case 2: PORTD &= ~MASKemitterP; break; } } //charge ReceiverN using internal pull-up PORTD |= MASKreceiverN; //we alreadi know it's PORTD becuse we are in this interrupt :-) //stop charge ReceiverN PORTD &= ~MASKreceiverN; } } _oldbit=_newbit; } }
ISR(PCINT1_vect) { if (BCDreceiverN == 1){ _newbit=PINC; _changed=_newbit^_oldbit; if (_changed & MASKreceiverN){//if PCINTreceiverN has changed _time=micros(); _hasChanged=true; if (_newbit & MASKreceiverN) { //if PCINTreceiverN now is high _startIn[emitterStatus]=_time; }else{ _rawIn[emitterStatus]=_time-_startIn[emitterStatus]; if (!emitterStatus){ //if we read with emitter HIGH and then LOW we have a distace rawDistance = _rawIn[0]-_rawIn[1]; //because dark read teorically is lower than light read } //start a new reading changing emitter status emitterStatus!=emitterStatus; if (emitterStatus){ switch (BCDemitterP){ case 0: PORTB |= MASKemitterP; break; case 1: PORTC |= MASKemitterP; break; case 2: PORTD |= MASKemitterP; break; } }else{ switch (BCDemitterP){ case 0: PORTB &= ~MASKemitterP; break; case 1: PORTC &= ~MASKemitterP; break; case 2: PORTD &= ~MASKemitterP; break; } } //charge ReceiverN using internal pull-up PORTC |= MASKreceiverN; //we alreadi know it's PORTC becuse we are in this interrupt :-) //stop charge ReceiverN PORTC &= ~MASKreceiverN; } } _oldbit=_newbit; } }
ISR(PCINT0_vect) { if (BCDreceiverN == 0){ _newbit=PINB; _changed=_newbit^_oldbit; if (_changed & MASKreceiverN){//if PCINTreceiverN has changed _time=micros(); _hasChanged=true; if (_newbit & MASKreceiverN) { //if PCINTreceiverN now is high _startIn[emitterStatus]=_time; }else{ _rawIn[emitterStatus]=_time-_startIn[emitterStatus]; if (!emitterStatus){ //if we read with emitter HIGH and then LOW we have a distace rawDistance = _rawIn[0]-_rawIn[1]; //because dark read teorically is lower than light read } //start a new reading changing emitter status emitterStatus!=emitterStatus; if (emitterStatus){ switch (BCDemitterP){ case 0: PORTB |= MASKemitterP; break; case 1: PORTC |= MASKemitterP; break; case 2: PORTD |= MASKemitterP; break; } }else{ switch (BCDemitterP){ case 0: PORTB &= ~MASKemitterP; break; case 1: PORTC &= ~MASKemitterP; break; case 2: PORTD &= ~MASKemitterP; break; } } //charge ReceiverN using internal pull-up PORTB |= MASKreceiverN; //we alreadi know it's PORTB becuse we are in this interrupt :-) //stop charge ReceiverN PORTB &= ~MASKreceiverN; } } _oldbit=_newbit; } }
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Tesla Member
Karma: 83
Posts: 8242
:(){:|:&};:
|
 |
« Reply #152 on: April 03, 2011, 06:28:28 pm » |
ERER.h #ifndef ERER_h #define ERER_h
#include "WProgram.h"
class ERER { public: ERER(byte, byte, byte); long getRawDistance(); private: byte getBCDpin(byte); void setStatus(byte, byte, boolean); };
#endif
attenzione ERER non vuole in input i PIN ma il loro valore PCINT (vedere http://arduino.cc/en/Hacking/PinMapping168) questo permette di usare sia pin digitali che analogici ESEMPIO DI UTILIZZO: con irEmitter digital pin 13 = pcint5 irReceiverN digital 2 = PCINT18 irReceiverP digital 5 = PCINT21 #inlcude "ERER.h"
ERER lettore = ERER(5, 21, 18);
void setup(){ //non c'è nulla da fare }
void loop(){ Serial.println( lettore.getRawDistance() ); }
scusate il doppio post ma ho superato il limite di caratteri per post (9500) EDIT: TODO: funzione di reset e piccolo watch-dog che la richiama. In teoria dovrebbe bastare //charge ReceiverN using internal pull-up setStatus(BCDreceiverN, MASKreceiverN, true); //stop charge ReceiverP setStatus(BCDreceiverN, MASKreceiverN, false);
|
|
|
|
« Last Edit: April 03, 2011, 06:33:07 pm by lesto »
|
Logged
|
|
|
|
|
Rome
Offline
God Member
Karma: 1
Posts: 972
Arduino rocks
|
 |
« Reply #153 on: April 04, 2011, 02:48:53 am » |
Scusa, mi fai capire bene come posso usare questi sorgenti? La "classe" sarebbe una libreria? Come la installo?
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Tesla Member
Karma: 83
Posts: 8242
:(){:|:&};:
|
 |
« Reply #154 on: April 04, 2011, 06:44:59 am » |
le classi sono programmazione ad oggetti, sono più una struttura che una libreria, poiché contengono sia funzioni che variabili, e vengono usate come una variabile. Le "installi" come una normale libreria, e le usi come una normale libreria (il file .cpp anche se non menzionato mai viene poi autocaricato)
|
|
|
|
|
Logged
|
|
|
|
|
Tortona
Offline
God Member
Karma: 2
Posts: 590
|
 |
« Reply #155 on: April 04, 2011, 08:40:07 am » |
ottimo lavoro! appena posso la provo...
|
|
|
|
|
Logged
|
Se gommo tiene,io vince gara! Se gommo non tiene,io come bomba dentro montagna
|
|
|
|
Napoli
Offline
Full Member
Karma: 0
Posts: 200
|
 |
« Reply #156 on: April 04, 2011, 05:06:42 pm » |
Qualcuno ci darebbe un occhio per piacere? 
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Tesla Member
Karma: 83
Posts: 8242
:(){:|:&};:
|
 |
« Reply #157 on: April 05, 2011, 04:15:15 am » |
ottimo lavoro! appena posso la provo...
sarà difficile che funzioni al primo colpo, anche se ad occhio non ci sono errori, salteranno sicuramente fuoi... Fammi sapere!
|
|
|
|
|
Logged
|
|
|
|
|
Tortona
Offline
God Member
Karma: 2
Posts: 590
|
 |
« Reply #158 on: April 05, 2011, 05:17:51 am » |
il fatto è che ho rotto uno dei led IR che avevo (non chiedermi come  ) e devo andare in negozio a prenderne un paio...
|
|
|
|
|
Logged
|
Se gommo tiene,io vince gara! Se gommo non tiene,io come bomba dentro montagna
|
|
|
|
Milan
Offline
Edison Member
Karma: 1
Posts: 1128
gioblu.com
|
 |
« Reply #159 on: April 06, 2011, 09:29:26 am » |
Ciao Lesto ma sei un grande l'hai scritta???  La provo subito!! Non sai che piacere!! Ti farebbe piacere mostrarla su Gioblu.com?? Piu' che altro quasi tutti gli utenti che hanno costruito un robot hanno usato il sistema ERER e tornerebbe PIU CHE UTILE!!
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Tesla Member
Karma: 83
Posts: 8242
:(){:|:&};:
|
 |
« Reply #160 on: April 06, 2011, 09:57:56 am » |
eheheh l'altra notte avevo voglia di programmare ma i miei progetti non mi attiravano... così mi son messo su questa libreria  Ripeto non è ancora testata e data la sua complessità (si lavora direttamente con i registri) mi stupirebbe assai se funzionasse al primo colpo  Se la testate la finiamo per bene, i test da fare sono: 1: prova generale del funzionamento 2: prova con loop() molto cpu intensive 3: prova di più istanze della classe contemporanemente (ovviamente necessita di 2 led per ogni classe) 4: test a lunga durata: non vorrei fosse necessario creare anche un piccolo watchdog, che però può essere utile anche per evitare poche letture troppo distanti ma farne molte vicine (aumentare la frequenza a discapito della distanza) piccola domanda: ma visto che reciverP è sempre a LOW, non è meglio collegarlo a GND così si risparmia un PIN? Infine una volta finita e testata la libreria volevo postarla nel reference con tanto di spiegazione di funzionamento, quindi la metto anche su gioblu. quello che non mi torna molto è il fatto di chiamare ISR, se si creano più istanze di classe non vorrei che rompesse le balle per funzione già dichiarata...
|
|
|
|
|
Logged
|
|
|
|
|
Napoli
Offline
Full Member
Karma: 0
Posts: 200
|
 |
« Reply #161 on: June 07, 2011, 03:45:29 pm » |
Rispolvero questo topic per capire qual è il codice che devo usare per questi sensori 
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Tesla Member
Karma: 83
Posts: 8242
:(){:|:&};:
|
 |
« Reply #162 on: June 07, 2011, 04:07:02 pm » |
questa funziona bene, usa gli interrupt ma in maniera tanto semplice da poter essere un esempio per imparare ad usarli int ricevitore = 2; int emettitore = 9;
void setup(){ Serial.begin(115200); pinMode(ricevitore, INPUT); pinMode(emettitore, OUTPUT); delay(1000); }
unsigned long ris, lastAlto=0; boolean statoEmettitore=true; void loop(){ //accende e spegne il led emettitore, e ne stampa lo stato if (statoEmettitore){ statoEmettitore=false; Serial.print("f "); } else{ statoEmettitore=true; Serial.print("t "); } digitalWrite(emettitore, statoEmettitore);
//legge la durata del segnale HIGH sul ricevitore e la stampa a video ris=durataHigh(); Serial.println( ris ); if (statoEmettitore){ lastAlto=ris; }else{ if (lastAlto<ris){ Serial.print( "distanza: " ); Serial.println( ris-lastAlto ); }else{ Serial.println( "lettura incongruente" ); } } }
//FUNZIONE DI LETTURA BLOCCANTE //per implementare un time-out basta modificare il while //non è gestito l'overflow di micro() unsigned long timeHigh; volatile unsigned long timeLow;
unsigned long durataHigh(){ timeHigh=micros(); timeLow=0;//inizializza la lettura a un valore noto, che fungerà da "tappo" per il while digitalWrite(ricevitore, HIGH);//attiva pullUP, per caricare il ricevitore attachInterrupt(0, tempoLow, FALLING);//vogliamo intercettare quando il digitalPin2 diverrà LOW ("cade" il segnale da 1 a 0) digitalWrite(ricevitore, LOW);//disattiva pullUP, il ricevitore è carico
//attende che la lettura sia completata while ( timeLow==0 )//finchè c'è il valore di tappo (il ricevitore è ancora HIGH) ;//non fare niente
detachInterrupt(0); return timeLow-timeHigh; }
//FUNZIONE DI INTERRUPT //più minimale di così non mi viene :-) void tempoLow(){ timeLow=micros(); }
|
|
|
|
|
Logged
|
|
|
|
|
Napoli
Offline
Full Member
Karma: 0
Posts: 200
|
 |
« Reply #163 on: June 08, 2011, 04:55:21 pm » |
Grazie!
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 38
|
 |
« Reply #164 on: December 27, 2011, 05:16:06 am » |
Mi son letto tutto il topic e vorrei capire: Quindi la libreria non è stata realizzata alla fine? Lesto confermi che l'ultimo codice che hai postato è quello "definitivo"? MA soprattutto, anche se un po' OT,sono su Ubuntu e lo stavo provando, ma nel serial monitor leggo solo caratteri strani, c'e' qualche impostazione da dargli per la codifica? la versione dell'IDE è la 0022Ubuntu0.1 Grazie!
|
|
|
|
|
Logged
|
|
|
|
|
|