PD6 und PC7 sind nicht vergleichbar, weil PD6 der "ICP" Pin ist und diese Funktion wird hier gebraucht.
PD6 und PC7 sind nicht vergleichbar, weil PD6 der "ICP" Pin ist und diese Funktion wird hier gebraucht.
Gruß
Dirk
Hi inka,
mein Nachbarssohn hat so ein Einsteigerpaket mit Arduino bekommen. Da ist auch der hc-sr04 mit bei. Mal sehen ob ich den mal mopsen kann. Funktioniert das nun bei dir ?
Ich würde das gerne mal ausprobieren und gleich noch eine Frage. Wir haben ja nur ein ICP Pin, kann man trotzdem 2 Sensoren benutzen. Hast Du da mal was gemacht ?
Gruß TrainMen
Mal so, nur ganz Allgemein und sicher reichlich OT : Ich wundere mich.
Über die Funktion (eher die Fehlfunktion-en) des hc-sr04 habe ich gerade in der letzten Zeit hier recht viel gelesen. Klar, bei Preisen um die zwei Euro neigt man schnell dazu mal zuzugreifen. Und ich habe auch oft bei der Kaufentscheidung bei billigen Angeboten mit meiner Meinung zu kämpfen "... wird schon werden ... werd ich schon hinkriegen ...".
Ich habe mir für mehr als zwölf Flocken ein paar SRF02 gekauft - und finde, dass der Mehrpreis den Vorteil mehr als rechtfertigt. Klartext-Messwertausgabe über UART oder so richtig pfiffig über I²C . . . und in mehreren Tests musste ich und ein paar Jungs von einer Jugend-forscht-Gruppe eigentlich kaum Fehlfunktionen feststellen. Gut, die Funktionsgrenzen sind bei Ultraschall bekannt - aber innerhab derer hatten wir beim höherpreisigen Sensor schnelle Inbetriebnahme und zuverlässige, zentimetergenaue Messungen festgestellt. Mal abgesehen von dem äusserst geringen Platzbedarf.
Ciao sagt der JoeamBerg
also mir geht es ja um den RP6 und den Sensor HC-SR04.
Ich habe gestern mit dem Nachbarssohn den Sensor am Arduino am laufen gehabt. Die Resultate waren gut. Vieleicht 1-2 cm unterschied. Gemessen haben wir den Bereich unter 50cm. Deswegen fand ich das gut und will den mal am RP6 ausprobieren.
Gruß TrainMen
also ich finde den HC-04 sogar besser als den SRF-02. Im messbereich, im preis(unter 2 eur/st. bei 5 stück). Und die genauigkeit lässt meiner meinung nach auch keine wünsche offen. Habe sogar versucht die dinger ohne jegliche anpassung zu tauschen, in den messungen minimale bis keine unterschiede. Der einziger nachteil ist kein I2c...
Wie ich den HC-04 abfrage kann man im code weiter oben sehen...
was den ICP-pin betrifft bin ich nicht weitergekommen - nur umstecken funktioniert. Es gibt ja z.b. i2c-port-expander, gibts sowas nicht für den ICP?
Geändert von inka (27.12.2014 um 14:43 Uhr)
gruß inka
ich glaube nicht das es sowas gibt.gibts sowas nicht für den ICP
Ich habe mir noch mal gedanken gemacht. Beim PD6 wird ja die "Input Capture" Funktion benutzt, dieser Teil dient zur genauen Zeitmessung. Also kann ich doch in einer Funktion PD6 und PC6 und in der anderen Funktion PD6 und PC5 benutzen. Nur gleichzeitig wird es nicht gehen. Probier das doch mal aus wenn Du Zeit findest, Du hast doch mehrere von den Dingern.
Gruß TrainMen
also ich hab mir die zeit genommen. Vorausgeschickt - es funktioniert nur wenn am echo-pin (ICS) umgesteckt wird. Aber es kann durchaus an meinen programmierkünsten liegen. Von den timern verstehe ich nämlich immer noch wenig bis nix...
folgendes habe ich jetzt gemacht:
die funktionen um PC5 und PC6 erweitert:
die variablen im hauptprogramm:Code:/********************* ULTRASCHALL & HC-SR-04 ******************************/ uint16_t distanz_PC5 = 0; volatile uint16_t zeit_PC5 = 0; volatile uint16_t timestamp_last_PC5 = 0; uint16_t distanz_PC6 = 0; volatile uint16_t zeit_PC6 = 0; volatile uint16_t timestamp_last_PC6 = 0; ISR(TIMER1_CAPT_vect) { //Wenn steigende Flanke if(TCCR1B & (1<<ICES1)) { //Flankenerkennung auf fallend TCCR1B ^= (1<<ICES1); //aktuelen timer-wert speichern timestamp_last_PC5 = ICR1; timestamp_last_PC6 = ICR1; } //fallende Flanke else { //Flankenerkennung auf steigend TCCR1B ^= (1<<ICES1); //Laufzeit = aktueller timerwert - vorheriger timerwert zeit_PC5 = ICR1 - timestamp_last_PC5; zeit_PC6 = ICR1 - timestamp_last_PC6; } } /*************** trig ***************************/ void trig_PC5(void) { PORTC |= (1<<PC5);//Trig high _delay_us(12); PORTC &= ~(1<<PC5);//TRIG auf low } void trig_PC6(void) { PORTC |= (1<<PC6);//Trig high _delay_us(12); PORTC &= ~(1<<PC6);//TRIG auf low } /***************** messung_SR_04 ********************/ void messung_SR_04_PC5 (void) { DDRC |= (1 << PC5);//Trig als Ausgang PORTC &= ~(1<<PC5);//TRIG auf low DDRD &= ~(1<<PD6);//Echo als Eingang PORTD &= ~(1<<PD6);//ECHO pullup AUS //Timer konfigurieren TCCR1A = 0; // normal mode, keine PWM Ausgänge //Noise Canceler aktivieren, Flankenerkennung auf steigende, Prescaler auf 64 TCCR1B |= (1<<ICNC1) | (1<<ICES1) | (1<<CS11) |(1<<CS10); //ICP Interrupt aktivieren TIMSK |= (1<<TICIE1); //Globale Interrupts aktivieren sei(); distanz_PC5 = (zeit_PC5*4)/58; } void messung_SR_04_PC6 (void) { DDRC |= (1 << PC6);//Trig als Ausgang PORTC &= ~(1<<PC6);//TRIG auf low DDRD &= ~(1<<PD6);//Echo als Eingang PORTD &= ~(1<<PD6);//ECHO pullup AUS //Timer konfigurieren TCCR1A = 0; // normal mode, keine PWM Ausgänge //Noise Canceler aktivieren, Flankenerkennung auf steigende, Prescaler auf 64 TCCR1B |= (1<<ICNC1) | (1<<ICES1) | (1<<CS11) |(1<<CS10); //ICP Interrupt aktivieren TIMSK |= (1<<TICIE1); //Globale Interrupts aktivieren sei(); distanz_PC6 = (zeit_PC6*4)/58; }
Code:extern volatile uint16_t zeit_PC5, zeit_PC6; extern uint16_t distanz_PC5, distanz_PC6;
und das ist die eigentliche abfrage:
Code:case 2:// setLEDs(0b0010); writeString_P("\n\n HC-SR-04 PC5_trig & PC6_trig\n\n"); writeChar('\n'); initRP6Control(); multiio_init(); initLCD(); setCursorPosLCD(1, 0); writeStringLCD("HC-SR04 messung"); mSleep(1500); while(1) { //Messung starten messung_SR_04_PC5 (); mSleep(100); //Signal auslösen trig_PC5(); _delay_ms(50); //Werte ausgeben writeString("zeit_PC5: "); writeIntegerLength(zeit_PC5, DEC, 4); writeString(" distanz_PC5: "); writeIntegerLength(distanz_PC5, DEC, 4); writeChar('\n'); mSleep(2000); //Messung starten messung_SR_04_PC6 (); mSleep(100); //Signal auslösen trig_PC6(); _delay_ms(50); //Werte ausgeben writeString("zeit_PC6: "); writeIntegerLength(zeit_PC6, DEC, 4); writeString(" distanz_PC6: "); writeIntegerLength(distanz_PC6, DEC, 4); writeChar('\n'); mSleep(2000); /**************************/ uint8_t key_1 = getMultiIOPressedButtonNumber(); key_1 = getMultiIOPressedButtonNumber(); if(key_1 != 0) break; /**************************/ } break;
gruß inka
schön das Du dir Zeit genommen hast.
Aber irgendwie hast Du nicht verstanden was ich geschrieben habe. Der Echo Pin muß schon PD6 sein, diese ICP Funktion wird ja gebraucht.
Bei meiner Frage ob das auch mit 2 Sensoren geht solltest Du von beide Sensoren den Echo Pin an PD6 bringen. Den Trigger von einen an PC6 und den anderen an PC5 z.B.
So wie ich dich verstanden habe funktioniert ja die Messung mit einem und es kommen vernünftige Werte.
Gruß TrainMen
also, es funktioniert, zumindest teilweise. Ich musste (wegen code:blocks) noch ein paar libs inkludieren und auch die multiIO initialisieren, jetzt lässt sich der code bei mir auch starten:
die jeweiligen messungen werden durch die tasten der m32 ausgelöst, allerdings wird beim druck auf die taste 2 das vorhergehende ergebnis der taste 1 ausgegeben. Also muss man die ausgaben die durch die taste 1 entstehen noch irgendwo "nullen"...Code://#include "RP6ControlLib.h" #include "RP6ControlLib.h" #include "RP6I2CmasterTWI.h" #include "RP6Control_MultiIOLib.h" #include "RP6Control_I2CMasterLib.h" #include "RP6Control_LFSBumperLib.h" #include "RP6ControlServoLib.h" #include "RP6Control_OrientationLib.h" //#include "standard.h" /*****************************************************************************/ uint16_t distanz_PC5 = 0; volatile uint16_t zeit_PC5 = 0; volatile uint16_t timestamp_last_PC5 = 0; uint16_t distanz_PC6 = 0; volatile uint16_t zeit_PC6 = 0; volatile uint16_t timestamp_last_PC6 = 0; /*****************************************************************************/ ISR(TIMER1_CAPT_vect) { //Wenn steigende Flanke if(TCCR1B & (1<<ICES1)) { //Flankenerkennung auf fallend TCCR1B ^= (1<<ICES1); //aktuelen timer-wert speichern timestamp_last_PC5 = ICR1; timestamp_last_PC6 = ICR1; } //fallende Flanke else { //Flankenerkennung auf steigend TCCR1B ^= (1<<ICES1); //Laufzeit = aktueller timerwert - vorheriger timerwert zeit_PC5 = ICR1 - timestamp_last_PC5; zeit_PC6 = ICR1 - timestamp_last_PC6; } } /*****************************************************************************/ void HCSR04_vorn (void) { // Messung DDRC |= (1 << PC5);//Trig als Ausgang PORTC &= ~(1<<PC5);//TRIG auf low DDRD &= ~(1<<PD6);//Echo als Eingang PORTD &= ~(1<<PD6);//ECHO pullup AUS //Timer konfigurieren TCCR1A = 0; // normal mode, keine PWM Ausgänge //Noise Canceler aktivieren, Flankenerkennung auf steigende, Prescaler auf 64 TCCR1B |= (1<<ICNC1) | (1<<ICES1) | (1<<CS11) |(1<<CS10); //ICP Interrupt aktivieren TIMSK |= (1<<TICIE1); //Globale Interrupts aktivieren sei(); distanz_PC5 = (zeit_PC5*4)/58; mSleep(100); // Trig PORTC |= (1<<PC5);//Trig high _delay_us(12); PORTC &= ~(1<<PC5);//TRIG auf low _delay_ms(50); //Werte ausgeben writeString("zeit_PC5: "); writeIntegerLength(zeit_PC5, DEC, 4); writeChar('\n'); writeString("distanz_PC5: "); writeIntegerLength(distanz_PC5, DEC, 4); writeChar('\n'); mSleep(2000); } /*****************************************************************************/ void HCSR04_hinten (void) { // Messung DDRC |= (1 << PC6);//Trig als Ausgang PORTC &= ~(1<<PC6);//TRIG auf low DDRD &= ~(1<<PD6);//Echo als Eingang PORTD &= ~(1<<PD6);//ECHO pullup AUS //Timer konfigurieren TCCR1A = 0; // normal mode, keine PWM Ausgänge //Noise Canceler aktivieren, Flankenerkennung auf steigende, Prescaler auf 64 TCCR1B |= (1<<ICNC1) | (1<<ICES1) | (1<<CS11) |(1<<CS10); //ICP Interrupt aktivieren TIMSK |= (1<<TICIE1); //Globale Interrupts aktivieren sei(); distanz_PC6 = (zeit_PC6*4)/58; mSleep(100); // Trig PORTC |= (1<<PC6);//Trig high _delay_us(12); PORTC &= ~(1<<PC6);//TRIG auf low _delay_ms(50); //Werte ausgeben writeString("zeit_PC6: "); writeIntegerLength(zeit_PC6, DEC, 4); writeChar('\n'); writeString("distanz_PC6: "); writeIntegerLength(distanz_PC5, DEC, 4); writeChar('\n'); mSleep(2000); } /*****************************************************************************/ void taster_M32(void) { uint8_t key = getPressedKeyNumber(); if(key) { while(getPressedKeyNumber()); switch(key) { case 1: setLEDs(0b0001); HCSR04_vorn(); break; case 2: setLEDs(0b0010); HCSR04_hinten(); break; } } } /*****************************************************************************/ int main(void) { // initRP6Control(); initRP6Control(); multiio_init(); initLCD(); while(true) { taster_M32(); } return 0; }
ansonsten ähnelt die situation meinem vorhergehenden test, wenn ich auf PD6 die Sensoren umstecke, läufts, wenn beide Sensoren angeschlossen sind - nicht...
die ausgabe im terminal:
Code:Terminal cleared! zeit_PC5: 0694 distanz_PC5: 0047 zeit_PC6: 0694 distanz_PC6: 0047 zeit_PC5: 0694 distanz_PC5: 0047 zeit_PC6: 0694 distanz_PC6: 0047
gruß inka
da ist ein Fehler bei der hinten Funktion, Werte ausgeben da steht PC5 statt PC6, ich mach weiter wenn meine Sensoren da sind.
Vielleicht sollte man den PD6 nach dem Messen auch neu setzen. Also denn auf Ausgang.
Gruß TrainMen
Lesezeichen