Hey, hat jemand schon einmal eine Einheit zum Auslesen der Informationen eines Beschleunigungssensors ADXL202 von Analog Devices "gebaut"? Ich weiß nicht genau wo ich anfangen soll, bzw. wie. Der Sensor misst auf 2 Achsen, hat dementsprechend 2 outputsignale, die PWM sind. Die Info steckt (o.k., das ist eigentlich klar) darin, wie lang das "hoch" im Vergleich zum "Tief" ist. Man müßte nun mit einer wesentlich höheren Lesefrequenz das Signal des Sensors "zerhacken" und dann den Punkt bestimmen, wo sich das Signal ändert. Wie kann ich das geschickt bewerkstelligen und dann zum PC bringen? Gruß, Matthias
Hallo Matthias, der ADXL202 hat auch einen, bzw. zwei(?) analoge Ausgangänge. Ich habe lieber diese, anstele des PWM-Signals benutzt, denn einen analogen Wert kann ich öfters hinterienander "scannen". Wenn ich z.B. 16x den Wert kurz hintereinander erfasse, dann kann ich den Durchschnitt aus diesen Werten berechnen und somit, das ziemlich flatterige Signal des Sensors glätten. Hier zum Einlesen des AD-Wertes: //////////////////////////////////////////////////////////////////////// ////////////////// // sample ADC PortC... //////////////////////////////////////////////////////////////////////// ////////////////// uint16_t sample_ADC( uint8_t adc_channel, uint8_t noumber_of_samples) // 1x-->(1/8000000)*32*13*32-->3,33ms { // 1/fCK* DivFactor* ConvCykl* j uint8_t adc_l, adc_h, j ; uint16_t adc_conv=0, ADC_=0; ADCSR=(1<<ADEN)|(0<<ADSC)|(0<<ADFR)|(1<<ADPS2)|(1<<ADPS0);//enable ADC single conversion ADMUX = adc_channel; // select channel for(j=0;j<noumber_of_samples;j++) // do an average over "noumber_of_samples" samples to get rid of the noise { ADCSRA|=_BV(ADSC); // start conversion loop_until_bit_is_clear(ADCSR,ADSC); // wait until conversion is finished adc_l=inp(ADCL); adc_h=inp(ADCH); adc_conv=u16from2u08(adc_l,adc_h); ADC_+=adc_conv; //create summ } ADC_=(ADC_+(noumber_of_samples/2))/noumber_of_samples; //+32 (64/2) um Duchschnitt um 0,5 nach oben zu verschieben return ADC; } das ganze wird aufgerufen mit z.B.: uint16_t ADXL202 = sample_ADC(0,16); // Pin PC0 //ADC liefert 16x geglaetteten Wert Senden an den PC kannst Du das ganze über den UART: //////////////////////////////////////////////////////////////////////// ////////////////// // USART sendet 8 bit //////////////////////////////////////////////////////////////////////// ////////////////// void uart_send_u8(uint8_t data) { UCSRB |= _BV(TXEN); // TX aktivieren while (bit_is_clear(UCSRA,UDRE)); // Warten, bis UDRE eins ist-->UDR ist leer UDR=(uint8_t)data; // data_to_send in das UDR Register schreiben } //////////////////////////////////////////////////////////////////////// ////////////////// // USART sendet 16 bit //////////////////////////////////////////////////////////////////////// ////////////////// void uart_send_u16(uint16_t data_to_send) { uart_send_u8((uint8_t)(data_to_send & 0xFF)); // Low Wert ->PC uart_send_u8((uint8_t)(data_to_send >> 8)); // High Wert ->PC } wieder aufrufen über: uart_send_u16(ADXL202); // Wert an PC Um diese 2x 8Bit, die an den PC gesendet werden wieder im PC zusammenzufügen benutzt ich dieses Terminalprogramm im Anhang. Ist noch nicht ganz fertig, aber den Zweck erfüllt er. Man muss zuerst die reinkommenden 16 x8bit Werte mit den Häkchen zusammenfassen. So z.B. 1. 2. Wert anklicken, dann auf SET, rechts. Unten leuchtet dann eine grüne Anzeige auf. Genauso die mit den restlichen Eingänge verknüpfen. Hier ist noch meine Schaltung mit dem ADXL202. Du musst den analogen Signal noch verstärken. Das ist eben der Nachteil gegenüber den PWM, dass noch mehr Bauteile benutzt werden müssen. http://ngrad.bei.t-online.de/Mikrokontroller/Submarine_Dive_Control_Syst.gif Nach diesem Lösungsansatzt hast Du zwar nicht gefragt, ich hoffe aber, dass es Dich trotztem weiterbringt. Gruß Zoltan
Da Du hier ja im mikrocontroller-Forum fragst, willst Du also auch einen mikrocontroller benutzen. Z.B. der AT89C2051 ist dafür geeignet. Du läßt einen Timer durchlaufen und den anderen im Gate-Mode, d.h. er läuft nur solange der Gate-Eingang =1 ist. Beim 1.Interrupt (Gate und externer Interrupt ist der gleiche Pin) setz t Du beide Timer auf 0 und beim 2. liest du sie beide aus. Dann ist der eine die Periodendauer und der andere die High-Dauer. Brauchst Du das mehrfach, nimmst Du entweder einen 2. AT89C2051 oder einen T89C51RB2, der hat dann gleich 5 Capture-Eingänge, damit gehts dann ähnlich. Peter
Hey, das analoge signal zu benutzen ist glaub ich jetzt wirklich die bessere idee, ich hab auch schon gelesen, daß das signal stark "flattert". Ich hab aber noch ne frage, da ich mit UART noch nie etwas gemacht habe. geht das analoge signaldirekt in den UART, ohne A/D wandler? kann ich den auch in-system-programmieren, und zuletzt, wie ist die genaue bezeichnung, denn ich hab kein datenblatt dazu gefunden. Gruß Matthias
Hallo @Matthias Was wolltest du uns mit dem letzten beitrag sagen. Komm da nicht ganz mit. Desweiteren ist wichtig was für nen µC du verwendest und uns genauer beschreibts was du machen willst und wie du es machen willst Gruß jochen
Hallo Matthias, es gibt auch eine Variante des ADXL, den ADXL311JE, der nur analoge signale liefert. Das ist dann günstiger, wenn Du nicht den PWM-Signal benutzten willst. Um das Singnale zu glätten sind die beiden Kondensatoren Cx/Cy vorhanden. Dadurch reagiert aber der Sensor auch träger auf Bewegungen. http://www.analog.com/UploadedFiles/Data_Sheets/567227477ADXL202E_a.pdf http://www.analog.com/UploadedFiles/Data_Sheets/39398238692761ADXL311_a.pdf UART: Allgemein: Nein der analoge Wert muss durch den Analog Digitalwandler in eine Zahl umgewandelt werden. In dem Bsp. von oben würde das so ungf. aussehen: uint16_t ADXL202 = sample_ADC(0,16); // Pin PC0 //ADC liefert 16x Das Umwandeln erledigt dann die sample_ADC Funktion, und speichert das Ergebnis in dem unsigned 16bit Wert genannt ADXL202. Anschließend muss diese Zahl an den PC gesendet werden: uart_send_u16(ADXL202); // Wert an PC Viele AVR-s haben Analog-Digitalwandler integriert. Wenn Du dich noch nicht auskennst, würde ich den ATMEGA8 empfehlen. Dieser besitzt 6 A/D Wandler, und auch den besagten UART und vieles mehr... Dadurch erübrigt sich Deine Frage nach dem "in system programmieren" . Der A/D Wandler wird in dem Datenblatt des ATMEGA8 ( AVR allgemein auch) sehr ausführlich beschrieben.
Noch ein paar Lins zu dem ADXL202: http://innovexpo.itee.uq.edu.au/2001/projects/s369518/thesis2.pdf http://undershorts.org/espresso/air_whammy/index.html http://web.mit.edu/cinnamon/www/project7.htm http://www.rdforrest.freeserve.co.uk/ http://www.gamages.com/vito.htm ... und das Beste zum Schluss: http://www.analog.com/Analog_Root/static/techSupport/designTools/interactiveTools/accelerometer/adxl202.html Gruß Zoltan
Ok, danke schön. ich arbeite mich erst ein, daher einige verständnisprobleme. Matthias
Also das mit dem PWM Ausgang funktioniert bei mir einwandfrei, brauchst entweder einen Timer mit Gate-Funktion wie beschrieben, oder einen Interrupt der auf steigende und fallende Flanke detektieren kann.
Hallo Leute Eien Frage Zoltan: Die Internetseiten, die du hier veröffentlicht hast, sind spitze, jedoch ist mein Englisch nicht grad perfekt, also wollte ich dich fragen, ob du auch informationen über ADXL202 auf Deutsch besitzt. Wenn nicht, würd ich mich trotzdem freuen, noch mehr Infos über ADXL202 zu bekommen (Egal welche Sprache, von mir aus Chinesisch g) mfg, Michi
Hi Michi, leider sind die Datenblätter allgemein in Englisch verfasst. Es steht eigentlich alles dort drinn, was man über das Teil wissen müsste. Oft ist eine Beschriebung von Anwendern aber hilfreicher (siehe dieses Forum ;-)). Ich habe noch diese zwei Sieten mit Google gefunden, oder du nimmst einen Wörterbuch, wie z.B. http://dict.leo.org/, so habe ichs immer gemacht. Die 2 Links: http://www.robosoccer.de/fileadmin/dortmunddroids/documents/PG-Berichte/Diplomarbeiten/diplomarbeit_klute.pdf http://www.fh-aalen.de/dti/D_proj/ADXL202/ADXL202.html Wenn Du aber eine konkrete Frage hast, dann kann ich dir vielleicht weiterhelfen. Gruß ZOltan
@Mike: Ich bin auch gerade daran einen ADXL202 über einen ATmega8 auszulesen, bisher aber leider ohne Erfolg :-( Ich weiss nicht so recht ob es an der Hard oder Software liegt, Hardware kann man ja nicht viel falsch machen, habe den einen Ausgang des ADXLs an einen Interrupteingang des AVRs gehängt, die Beschaltung des Beschleunigugssensors natürlich nicht vergessen, aber es will nicht, daher denke ich dass es an der Software liegt. Nun zu meiner Frage, dürfte ich mal deinen Code, oder der relevante Schnipsel haben? Ich blick irgendwie nicht ganz durch wie das mit dem Gate und so gehen soll. Leider hat mein Beschleuningungssensor nur PWMausgänge und keinen Analogausgang:-(
Hi DuMitDemKomischenNamen (;-)), der ADXL202 hat auch analoge Ausgänge, http://www.analog.com/UploadedFiles/Data_Sheets/567227477ADXL202E_a.pdf Seite 11: "XFILT, YFILT Output". Vielleicht hilft Dir der Ausgang, um die Funktion des Sensors zu überprüfen, denn man weiß ja nie... Gruß Zoltan
Ich habe das Teil mal mit einem Pic verwendet. Um nur zu sehen, ob es überhaupt arbeitet, misst man mit einem Multimeter, ob an einem PWM-Ausgang eine Frequenz heraus kommt. Achtung: Diese Frequenz ist vollkommen unabhängig von der gemessenen Beschl., also nicht wundern, wenn das Teil in jeder Lage die gleiche Frequenz herausgibt. Mit dieser Frequenz kann man das Ganze auch direkt abgleichen. Allerdings sollte man den Offset noch ermitteln und im MC abspeichern, den dieser war bei meinen Sensoren nicht unerheblich. Das mit dem analogen Messen ist meiner Meinung nach nicht zu empfehlen, wenn man einen MC verwendet, das schreibt auch Analog irgendwo. Die Änderungen an X-,Y-Filt sind nämlich pro g nur ein paar mV, für eine exakte Messung wohl nicht wirklich geeignet. Habe ich aber nicht probiert, wenn es einer probiert, bitte Ergebniss hier posten, würde mich doch interessieren, ob man das so stehen lassen kann. Henrik
Hi Henrik, wie gesagt verwende ich den analogen Ausgang, und es funktioniert bestens. Die mV Spannung wird von einem Op. auf 0..4V verstärkt, so dass ich den AD-Wandler (Aref auf 4V) voll ausnutzten kann. Ich habe aus dem Grund den analogen Ausgang genommen, weil 1. ich mich nicht nach dem Taktsignal des ADXL202 richten wollte, bzw. wollte ich keine unvorhersehbaren Interrupts im Programm. Mein Programm wurde von einer anderen Quelle bereits getriggert, und das hätte einen riesen Durcheinander mit den Interrupts gegeben, was ich unbedingt vermeiden wollte. 2. ich den analogen Eingang schneller Filtern kann: Wenn ich z.B. 16x hintereinander den Eingangsport lese und aus der Summe den Durchschnitt bilde, bekomme ich einen "saubereren" Wert wie durch nur einen Rechtecksignal, und das in der selben Zeit. Zoltan
Hast du ein Rauschen mit der analogen Messung? Bei mir stand die Stelle wo die Milli-g angezeigt wurden nie richtig still, die zitterte immer um ca 3-4 mg, obwohl das errechnet Rauschen nur knapp über 1 mg liegen sollte. Henrik
Also leider hat mein ADXL keinen Analogausgang. Kann mir mal jemand kurz beschreiben wie ich das mit dem messen der PWM machen muss, ich verwende Atmega8. Es muss nicht ein fertigen Code sein (das schaffe ich hoffentlich selber), sondern einfach wie man es grob macht, wo hänge ich zum Beispiel den PWM Ausgang des ADXL202 hin, Interrupteingang? Bin für jede Hilfe dankbar...
@Henrik Ja dieses Rauschen hatte ich auch, aber frag mich jetzt nicht, wie groß der war, auf jeden Fall klein, und ich habs dann auch im MC nochmal (wie oben beschrieben) gefiltert. Errechnet habe ich den Wert nicht, aber es schadet sicherlich nicht, wenn man den Ferritkern und den Kondensator+R mit einfügt, ( nochmal der Link von oben : http://www.analog.com/UploadedFiles/Data_Sheets/567227477ADXL202E_a.pdf) Siehe S.8 . @IchUndNichtDu Versuchs mal mit RSet=1M ( T=Rset/125M) was einer Periodendauer von T=8ms entsprechen sollte. Dann hängst Du einen der "Duty Cycle" Ausgangänge des Sensors an PD2 (INT0) des Atmega8. Hier ein kleines Programm (mit Interrupts), welches dir dann nie Pulslänge an den PC schicken sollte : #include <avr/io.h> #include <avr/signal.h> #include <avr/interrupt.h> #include <inttypes.h> // um Register auch bitweise in Binärformat ansprechen zu können #define BIN8(b7,b6,b5,b4,b3,b2,b1,b0) ((unsigned char)\ (b0 << 0)\ | (b1 << 1)\ | (b2 << 2)\ | (b3 << 3)\ | (b4 << 4)\ | (b5 << 5)\ | (b6 << 6)\ | (b7 << 7)) void uart_send_u8(uint8_t data); // Prototype uint16_t PulsL; int main(void) { DDRB=0xFF; // use all pins on PortB for output (to servo) DDRD=0; // use PortD PIN2 for input (signal) PORTD= BIN8(0,0,0,0,0,1,0,0); // pull up (signal INT0) DDRC= BIN8(0,0,1,1,0,0,0,0); GICR=(1<<INT0); // enable external int0 MCUCR=(0<<ISC01)|(1<<ISC00); // any logical change creates interrupt0 sei(); // enable interrupts for(;;){} // loop "forewer", wait for signal return 0; } SIGNAL(SIG_INTERRUPT0) // signal handler for external interrupt int0 { if(bit_is_clear(PIND,2)) { TCCR1B=0; // Stop timer1 PulsL=TCNT1; uart_send_u8(PulsL); } else { TCCR1B=(1<<CS11); // Start timer1 with CK/8, 8MHz } } //////////////////////////////////////////////////////////////////////// ////////////////// // USART sendet 8 bit //////////////////////////////////////////////////////////////////////// ////////////////// void uart_send_u8(uint8_t data) { UCSRB |= _BV(TXEN); // TX aktivieren while (bit_is_clear(UCSRA,UDRE)); // Warten, bis UDRE eins ist-->UDR ist leer UDR=(uint8_t)data; // data_to_send in das UDR Register schreiben } Gruß Zoltan
Da fällt mir auf, dass es mit dem "uart_send_u8(PulsL);" nicht gehen wird, weil ja die Zahlen für die 8-bit zu groß werden. Hier nochmal das ganze etwas geändert und das passende Terminalprogramm, das die 2 8-bit wieder zusammensetzt, schick ich dir per Mail. #include <avr/io.h> #include <avr/signal.h> #include <avr/interrupt.h> #include <inttypes.h> // um Register auch bitweise in Binärformat ansprechen zu können #define BIN8(b7,b6,b5,b4,b3,b2,b1,b0) ((unsigned char)\ (b0 << 0)\ | (b1 << 1)\ | (b2 << 2)\ | (b3 << 3)\ | (b4 << 4)\ | (b5 << 5)\ | (b6 << 6)\ | (b7 << 7)) void uart_send_u8(uint8_t data); // Prototype void uart_send_u16(uint16_t data); uint16_t PulsL; int main(void) { DDRB=0xFF; // use all pins on PortB for output (to servo) DDRD=0; // use PortD PIN2 for input (signal) PORTD= BIN8(0,0,0,0,0,1,0,0); // pull up (signal INT0) DDRC= BIN8(0,0,1,1,0,0,0,0); GICR=(1<<INT0); // enable external int0 MCUCR=(0<<ISC01)|(1<<ISC00); // any logical change creates interrupt0 sei(); // enable interrupts for(;;){} // loop "forewer", wait for signal return 0; } SIGNAL(SIG_INTERRUPT0) // signal handler for external interrupt int0 { if(bit_is_clear(PIND,2)) { TCCR1B=0; // Stop timer1 PulsL=TCNT1; uart_send_u16(PulsL); } else { TCCR1B=(1<<CS11); // Start timer1 with CK/8, 8MHz } } //////////////////////////////////////////////////////////////////////// ////////////////// // USART sendet 8 bit //////////////////////////////////////////////////////////////////////// ////////////////// void uart_send_u8(uint8_t data) { UCSRB |= _BV(TXEN); // TX aktivieren while (bit_is_clear(UCSRA,UDRE)); // Warten, bis UDRE eins ist-->UDR ist leer UDR=(uint8_t)data; // data_to_send in das UDR Register schreiben } //////////////////////////////////////////////////////////////////////// ////////////////// // USART sendet 16 bit //////////////////////////////////////////////////////////////////////// ////////////////// void uart_send_u16(uint16_t data_to_send) { uart_send_u8((uint8_t)(data_to_send & 0xFF)); // Low Wert ->PC uart_send_u8((uint8_t)(data_to_send >> 8)); // High Wert ->PC } Gruß Zoltan P.S. Lass es mal dann hören, ob es geklappt hat.
@Zoltan: Für unser Projekt haben wir extra ein Beschleunigungssensor, bzw. einen Verzögerunssensor gesucht, da wir mit Hilfe von 16LEDs anzeigen möchte, wie stark die Verzögerung ist. Jedenfalls hab ich auch beschlossen den analogen Output zu verwenden, weil es, wie es scheint, viel besser ist. Nur würde ich gerne wissen, wie ich das ganze dann beschalten muss, bzw. was für einen A/D Wandler du benutzt, und woher ich es kriegen kann. (Ich weiß, ich verlange zu viel :)) Und noch eine Frage: Wie soll ich es programmieren, dass ich den Wert, den der A/D-Wandler sendet, in den µController (Typ:89S52) hineinbekommen, sprich, dass ich gscheite Werte habe, damit ich mit ihnen arbeiten kann. Falls ihr auch Informationen über den 89S52 habt, würd ich mich freuen, sie zu erhalten ... oder noch besser, wenn ihr Erfahrung damit habt :)) Danke mfg Michi
Hi Michi, Ich verwende einen OP (TLC274), der eine Ausgangspannung im Bereich von 0..4.2V hat. Dieser Baustein verstärkt den kleinen analogen Ausgangssignal des Sensors. Der 10bit A/D-Wandler war bereits in meine ATMEGA8 integriert, und so musste ich nur den OP an den entsprechenden Pin anschließen. Das zu der Frage nach dem "hineinbekommen". Mit externen A/D-Wandlern hatte ich noch nichts gemacht, da kann ich dir grad nicht weiterhelfen und mit dem 89S52 habe ich auch keine Erfahrungen. Wie ich aber den OP beschaltet habe siehst du hier: http://ngrad.bei.t- online.de/Mikrokontroller/Submarine_Dive_Control_Syst.gif Woher du einen A/D wandler nehmen kannst z.B.: http://www.reichelt.de/ http://www.conrad.com/ Gruß Zoltan
Hallo liebe "PWM-User"! Mich würde mal interessieren, wieviel Millisekunden Eure tatsächliche Periodendauer dauert, sprich, mich interessiert Eure Messfrequenz. Gruß Markuso
Hallo Leute Ich hab ein Problem, und zwar: 1.Ich möchte unseren Sensor ADXL202 in Eagle zeichnen, aber ich möchte mir das ersprachen alles zu zeichnen, hab zwar ein Bauteil gefunden, welches Package dem ADXL202 passt, aber dafür stimmt die Schematic nicht. Bauteil: Linear-ADC08032S mit 14 Pins (Board) aber mit 8 Pins (in Schematic), aber ich brauche min. 8 Pins in Schematic, natürlich wärs super, wenn alle 14 Pins in Schematic gezeigt werden, ist aber nicht notwendig. Also könnte ihr mir irgendwie helfen? 2.Es wird in den Datenblättern sehr schön gezeigt, wie man T2 und T1 berechnen, bzw. wiedergeben kann, jedoch wird aber nicht beschrieben, in welche richtung T1 bei Verzögerung wandert? Ich meine, bei Stillstand ist T1 50% vom T2 .... aber, was passiert bei Verzögerung, bzw. Beschleunigung??? Wird T1 bei Beschleunigung größer, oder kleiner?? Wär euch sehr dankbar, wenn ihr mir helfen könntet. Ich könnte es zwar auch nachmessen, aber damit ich es nachmessen kann, muss ich mir zuerst mal die Kondensatoren, bzw. Widerstände aussuchen, was ich noch nicht hab. Ich weiß noch nicht, welchen T2 ich verwenden soll, und welche Bandbreite. Falls ihr daüfr Ideen habt, wär ich euch auch dafür dankbar. Mit freundlichen Grüßen Michi T. P.S.: Ich weiß, ich verlange viel :))
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.