PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Oszilloskop erster Versuch, kleine Probleme



Ceos
24.09.2008, 01:05
ich versuche mit einem extern 16Mhz getakteten Mega32 den 1kHz Impuls eines Mega8 der auf intern 8Mhz läuft zu messen, das ergebnis seht ihr im Bild
http://img223.imageshack.us/img223/5745/osziv1xlssf4.jpg (http://imageshack.us)
http://img223.imageshack.us/img223/osziv1xlssf4.jpg/1/w905.png (http://g.imageshack.us/img223/osziv1xlssf4.jpg/1/)
der M8 läuft auf Timer1, PS: 1, FPWM mode (ICR1 def. Top), ICR1 = 99, 80 Samples, der Impuls steigt von 0 auf max langsam an, fällt dann ungefähr auf die hälfte ab und hat hinten noch eine totzeit, 1kHz impulsfreuquenz wie gesagt

M32 ADC Freerun PS: 8 (niedriger geht nicht) , 13 ADC clocks = 1 ADC wert, von Impuls zu Impuls 152-153 Werte also ungefähr 1010Hz, vermutlich läuft der M8 mit dem internen takt etwas ungenau (an nem echten osziloskop hab ich auch nen drift gemessen aber der lag eher bei -15Hz, also 9985Hz, allerdings in anderer Umgebung)

zum Problem, da ist so eine unschöne oberwelle zu erkennen, die läuft mit ca. 9,1kHz (alle 17 messwerte) und ich kann mir beim besten willen nciht ausmalen woher die kommen, hat jemand ne idee zur ursache oder zur bekämpfung?

wenn ich nur irgendwie den prescaler des ADC weiter runter bekäme, aber wenn ich tiefer als 8 gehe stimmt die berechnete frequenz vorn und hinten nicht mehr

PS: der RC-Filter für diese messung war 100Ohm 330nF , mehr als 100 Ohm verzerrt meinen Impuls zu stark und wenn cih weniger nehme kommen die PWM stärker raus ... aufm analog oszi sah der impuls viel schöner aus (vermutlich weil die oberwelle da nicht zu sehen ist, ohne die wäre das ergebnis fast perfekt)

PPS: 10nF kondensator an VREF, abblockkondensator zwischen AVCC und AGND muss ich gestehn hab ich vergesssen seh ich grade.

Hubert.G
24.09.2008, 18:22
Bist du sicher das du nicht etwa siehst das gar nicht relevant ist?
Wenn doch, gibt es eine große Anzahl von Möglichkeiten, angefangen von der gegenseitigen Beeinflussung über die Versorgungsspannung oder über die Masseleitung, einstreuungen von anderen Geräten, LCD usw.

Ceos
24.09.2008, 19:10
naja es ist einfach nur n steckbrett, die beiden controller drauf, batteriepack als versorgung
ich vermute es iss ne interferrenz zwischen den 2 controllern die sich da etwas heftig verstärkt, ich würde diese interferrenz am liebsten irgendwie neutralisieren aber leider hab cih keine ahnung wo ich anfangen soll .... in der software könnte ich die sampledichte verringern oder 2 aufeinanderfolgende extremwerte miteinander verrechnen, damit was sauberes rauskommt ... cih schliesse mcih da nochmal mit ner studienkollegin kurz, die hat mehr talent was statistische algorithmen angeht ^^

Besserwessi
24.09.2008, 20:16
Der Filter ist mit 100 Ohm / 330 nF sehr nieder ohmig. Da muß man dann schon den Ausgangswiderstand des Ports berücksichtigen, und der ist nicht unbedingt Spannungsunabhängig. Das könnte schon mal das Signal verfälschen. Dann kommen bei einem Filter 1.ter Ordnung immer noch ein paar Reste der PWM Frequenz durch. Je nach ESR der Kondesators und der Masseführung kommt noch ein direktes durchkopplen dazu. Je nachdem wie der genaue Abtastzeitpukt des AD-wandlers mit der Phase des PWM Signals zusammenfällt gibt es dann die extra Störungen die mal da sind und dann wieder nicht so stark.

Die Bezeichnung Oberwellen ist übrigens hier nicht richtig, denn Oberwellen sind exakte Vielfache der Grundfrequenz und führen zu einer nicht sinusförmigen Signalform, die man hier auch noch hat. Die höherfrequenten Störungen sind mehr als Schwebunng zu bezeichnen und das gibt es gerade wenn die Frequenzen gerade nicht ganz zusammenpassen, weil ein Quarz und der interne Oszillator zusammenkommen.

Ceos
25.09.2008, 00:52
wohoo, ich muss gestehen dass ich beim lesen deines post ein wenig lange gebraucht habe (und das liegt nicht an der zeit)... ja gut, goldwage mal beiseite, dein einwand mit dem widerstand des portpin ist nich schlecht, ich kanns ja mal mit 10nF versuchen aber dann müsste ich 3.6kOhm (hab nur 10nF und 330nF, bzw. 100Ohm und 1,2kOhm im sortiment, deshalb die werte) nehm, dämpft mir das die spannung nicht zu weit runter ?

schwebung ... danke das war der begriff nach dem ich den ganzen tag schon gesucht hatte XD

die masseführung und VOR ALLEM kabelführung ist milde gesagt GRUSELIG , iss halt nur n steckbrett ...

ich werd mich wohl erstmal mit dem ergebnis zufrieden geben müssen und softwareseitig kompensieren müssen

falls noch wer ne idee hat wie ich die schwebung einfach eliminieren könnte raus damit

johns
25.09.2008, 11:22
falls noch wer ne idee hat wie ich die schwebung einfach eliminieren könnte raus damit

- stimmen
- gemeinsame taktquelle, ev. takt vom zu messenden signal ableiten

..ist zumindest beim musizieren recht einfach ;)

lg

Ceos
25.09.2008, 12:09
ob ich 2 controller mit EINEM 16MHz Quarz betreiben kann ?
ich probiers mal aus

markusj
25.09.2008, 13:20
Ja, diverse neuere AVRs bieten dir die Möglichkeit, den Takt an einem Pin auszugeben.
Der M32 kann aber nur einen externen Takt eingespeist bekommen.
Details sind im Datasheet unter System Clock and Options.
Evtl. kann man auch am Quarz den Takt abgreifen, das ist aber nur eine Vermutung, ich würde den taktgebenden AVR aber dann auf Rail-to-Rail-Swing umstellen, um ein stärkeres Signal zu bekommen.

mfG
Markus

Ceos
25.09.2008, 14:58
die laufen bei mir immer rail to rail, stromsparen muss ich net XD

mh synchron laufen lassen indem ich µC-1 über quarz laufen lasse und den anderen dann mit dem takt des ersten controller speise auch gut ^^ ich versuchs heute abend mal

Besserwessi
25.09.2008, 17:59
Ein hochohmigerer Ausgang sollte moch kein Porblem sein. Wenn da beine große externe Last dranhängt sind auch 10 KOhm noch kein Problem die Spannung wird nur kleiner wenn der Widerstand vergelichbar mit dem Lastwiderstand wird. Bei 1 M Eingangswiderstand vom analogen Oszilloskop oder ca. 100 M vom AD Eingang sollte das noch kein Problem sein. Bei mehr als 10 K muß aber mir den ersten Einflüssen auf den AD rechenen, wegen der kurzen Abtastung.

Ceos
25.09.2008, 19:48
nagut ich muss dazu sagen, dass ich noch nicht einschätzen kann was genau die anforderungen sind aber das ist ne vorbereiitung auf nen projekt und mir wurden nur rahmenbedingungen und noch keine details gegeben, also lass cih das auch mich zukommen jetzt und behalte deine tips im hinterkopf, wenns mal soweit kommt ^^ danke besserwessi, vll. komm ich nochmal auf dein fachwissen zurück, wenn ich ein anderes elektrisches problem habe, analoge schaltungen habe ich einfach noch keine erfahrungen gemacht, auch dass ich die tiefpassfrequenz erheblich tiefer als die PWM frequenz legen muss, wurde mir erst im experiment klar

EDIT: also die anpassung mit 10nF und 3,6kOhm hat nix gebracht, cih geh mal die datenblätter durch wegen taktein- und ausgang

EDIT: synchroner takt hilft auch nicht, die schwebung bleibt bestehen

Ceos
26.09.2008, 12:38
ich weis ich weis doppelpost, aber cih hab ne neue frage

wie stelle ich den controller ein, dass er nur 8bit ADC wandelt statt 12bit ?
ich datenblatt steht, dass ich so die ADC clock höher schrauben kann , aber nicht WIE ich ihn auf 8bit reduziere
im moment häng ich bei ADC prescaler 8 fest, alles darunter ergibt keine normal berechnbare frequenz mehr, da müsste ich die werte erst eineichen!

oder kann das an der geschwindigkeit liegen, dass ich vielleicht die interrupts verschleppe ?


#include <avr/io.h>
#include <avr/interrupt.h>
unsigned char tval;
unsigned char adcval[923];
unsigned char* end;
unsigned char* pos;

ISR(SIG_OUTPUT_COMPARE0)
{
cli();
if (tval++ > 125) {
TIMSK &= ~(1<<OCIE0);
while (!(UCSRA & (1<<UDRE)));
UDR = 'A';
while (!(UCSRA & (1<<UDRE)));
UDR = 'D';
while (!(UCSRA & (1<<UDRE)));
UDR = 'C';
while (!(UCSRA & (1<<UDRE)));
UDR = '\r';
ADCSRA |= (1<<ADIE);
}
sei();
}

ISR(SIG_ADC)
{
*pos = ((unsigned char)(ADC/16))+'!';
pos++;
if (pos > end) {
ADCSRA &= ~((1<<ADEN) | (1<<ADIE));
while (!(UCSRA & (1<<UDRE)));
UDR = 'F';
while (!(UCSRA & (1<<UDRE)));
UDR = 'I';
while (!(UCSRA & (1<<UDRE)));
UDR = 'N';
while (!(UCSRA & (1<<UDRE)));
UDR = '\r';
pos = adcval;
do {
while (!(UCSRA & (1<<UDRE)));
UDR = *pos;
while (!(UCSRA & (1<<UDRE)));
UDR = '\r';
} while (pos++ < end);
}
}

ISR(SIG_UART_RECV)
{

}

ISR(SIG_UART_TRANS)
{

}

int main()
{
end = &(adcval[922]);
pos = adcval;
tval = 1;
UBRRH = 0;
UBRRL = 25;
UCSRC = (1<<USBS) | (1<<UCSZ1) | (1<<UCSZ0) | (1<<URSEL);
UCSRB = (1<<RXEN) | (1<<TXEN);
while (!(UCSRA & (1<<UDRE)));
UDR = 'S';
while (!(UCSRA & (1<<UDRE)));
UDR = 't';
while (!(UCSRA & (1<<UDRE)));
UDR = 'a';
while (!(UCSRA & (1<<UDRE)));
UDR = 'r';
while (!(UCSRA & (1<<UDRE)));
UDR = 't';
while (!(UCSRA & (1<<UDRE)));
UDR = '\n';
while (!(UCSRA & (1<<UDRE)));
UDR = '\r';
TCNT0 = 0;
OCR0 = 124;
TCCR0 = (1<<WGM01) | (1<<CS02) | (1<<CS00);
ADMUX = (1<<REFS0);
ADCSRA = (1<<ADPS1) | (1<<ADPS0) | (1<<ADEN) | (1<<ADATE);
ADCSRA |= (1<<ADSC);
TIMSK = (1<<OCIE0);
sei();
while(1);
return 0;
}


der code ist momentan noch frickelage und auf hyperterminal abgestimmt, ich schreibe die werte in einen textdatei und importier die werte in eine excel tabelle um sie wie oben zu sehen auszuwerten

ich will den code so bauen dass ich 5 mal pro sekunde eine aufzeichnung von 923 byte mache (beim niedrigsten "unerreichbaren" prescalewert müssten das 1,5 perioden sein bei 1kHz) und dann die daten per comport versende also 5 * 923byte * 10bit = 46150Baud

das ganze dann verbunden mit nem kleinen programm wass dann die parameter für die messung festlegt und die daten grafisch auswertet, vll. setz ich das programm auf nen 2ten mega mit LCD um der es dann darstellt (quasi tragbar machen)

hat jemand verbesserungsvorschläge ?

markusj
26.09.2008, 13:49
Erstens ist im AVR ein 10 Bit ADC.
Zweitens kannst du ihm nicht sagen, dass er nur 8 Bit machen soll, er wandelt immer 10 Bit. Du kannst ihm aber mitteilen, dass er das Ergebnis linksbündig ablegen soll, dann brauchst du nur das High-Byte auslesen (spart platz), wenn du weißt, dass dein Ergebnis aufgrund der hohen Wandlungsfrequenz zwar 10 Bits hat, die letzten beiden aber keine zuverlässigen Werte sind.
Du behandelst ihn dann einfach wie einen 8 Bit ADC.

Deine ISR macht ferner genau das, was eine ISR NICHT tun sollte: Warten.
Sinnvoller wäre es, einen Puffer einzurichten, in den der ADC seine Werte reinspeichert und entweder in der Hauptschleife oder in einer UDRE-ISR zu verschicken.

mfG
Markus

Besserwessi
26.09.2008, 17:24
Da ist noch ein 2 tes problem in der ISR. In einer ISR sollte man die Befehle SEI() un CLI() sehr vorsichtig einsetzen. Wenn man nicht genau weiss was man da macht (geschalchtelte ISRs) dann haben cli() und Sei() in einer ISR nichts zu suchen.

Ceos
26.09.2008, 22:26
scheeeeiiii ... vergessen rauszumachn ^_^ aber die haben an der stelle ja keine kritische wirkung, der timer dient(im moment) nur als verzögerung damit der ADC sich vernünftig einpegeln kann, auch wenn 4/5tel sekunden reichlich zu viel dafür sind
nachdem der timer abgelaufen iss lösche ich den interrupt ja

Besserwessi
27.09.2008, 10:41
Das sei() in der ISR kann durchaus kritisch sein. Gerade durch das warten auf die UART in der ISR (was man auch nicht tun sollte) kann erneut der selbe Interrrupt aufgerufen werden. Auch wenn das sei() am ende des isr codes steht, kommt da noch das wiederherstellen der Register. Es kann also sehr leicht zu einem erneuten aufruf der selben ISR routine kommen, bevor sie zu ende ist und damit zum Crash wegen Stacküberlaufs und Hängen im der ISR. Gerade am Ende der ISR sollte keine sei() stehen, das wird ganz am Ende, nach dem wiederherstellen der Register ohnehin getan. Das cli() ist nicht so schlimm, aber definitiv überflüssig.

Hier geht das ganze noch gerade mal gut das der Interrupt abgeschaltet wird.

Ceos
27.09.2008, 12:08
darum gehts hier doch jetzt garnicht, während der messung passiert doch garnüscht mit den cli() und sei()!!!

das problem ist ein ganz anderes, ausserdem war das cli/sei mal wieder einer meiner unüberlegten verzweiflungstaten und verdankt meiner vergesslichkeit, dass das jetzt noch drinne steht XD

der motor läuft nicht, aber dich stört dass ich die spiegel nicht eingestellt habe :p

EDIT:


Deine ISR macht ferner genau das, was eine ISR NICHT tun sollte: Warten.
Sinnvoller wäre es, einen Puffer einzurichten, in den der ADC seine Werte reinspeichert und entweder in der Hauptschleife oder in einer UDRE-ISR zu verschicken.

also markusj jetzt wirds krümelig hier .... ich hab oben geschrieben dass dass erstmal nur frickelcode iss ........... die ISR fürs uart sind wenn man genau hinsieht LEER .... ich hab auch geschrieben dass ich es so machen will, dass er mir eie mess-serie auf befehl anfertigt, also hätte ich das senden schon interruptartig gelöst, in einer schönen statemachine .... der puffer ist da, nur wollt ich im moment noch speicher sparen, da ich nicht wusste wieviel ich für eine 1kHz messerie tatsächlich brauche und wieviel mir der controller zur verfügung stellt .....

PS: mein programmierstil ist ein wenig eigenwillig, ich zerleg mein problem in module, schreib die module so dass sie funktionieren, beseitige probleme(an der stelle bin ich grade), bereinige den quellcode(!!!) und setze dann das programm zusammen .... dass man dann anfängt die goldwage zu bemühen kratzt ein wenig an meiner ehre tut mir leid dass ich da so ausfällig werde

EDIT EDIT:


hat jemand verbesserungsvorschläge ?

AUUU SCCHHHEEEIII .... .... .... ok tut mir leid ich hab das jetzt selber erst gemekrt .... ungünstig formuliert .... optimierungsvorschläge triffts besser, frühere versuche haben gezeigt das arrayzugriffe ala array[x++] = ADC; SEHR ineffizeint sind, da hab ich schon optimiert aber ob es halt NOCH effektiver gehen würde OMG ok asche auf mein haupt verdammt >_<

markusj
27.09.2008, 12:50
Ceos, du hast recht. Ich hatte übersehen, dass das verschicken erst dann stattfindet wenn deine Messung abgeschlossen ist.
Eine Frage: Bist du sicher dass deine Zuweisung am Anfang der ISR so funktioniert?
Ich meine diese hier:

*pos = ((unsigned char)(ADC/16))+'!';
Ich bin noch nicht ganz so erfahren im Umgang mit C, aber das schaut komisch aus.

mfG
Markus

Ceos
27.09.2008, 13:16
der 10bit ADC wert wird um 4 bit verkleiner 6 bit, macht 64 stufen, addiert mit dem zahlenwert des ausrufezeichen (33 als das niedrigste darstellbare textzeichen) ergibt eine reichweite von '!' (33) bis '`' (96), da der ADC 12 bit hat wird die gesamte rechenoperation als 16bit wert ausgeführt und ich downcaste es auf 8bit, da ich es in einem charwert speichern möchte

den zeichensalat importiere ich dann in eine exceltabelle, wo ich mir dann mittels der formel
=CODE("datenzelle")-33
mir einen zahlenwert von 0 bis 63 ausrechnen lasse, den ich dann in einem liniendiagramm interpretiere (siehe bild erster post)

wenn ich die werte von 0 - 256 (also durch 4 statt 16 geteilt hätte) versucht hätte zu übertragen hätte ich steuerzeichen und sonst irgendwelchen müll gehabt, den ich nicht in einer excel tabelle interpretieren kann

wenn ich mein programm fertig habe, werde ich 8bit werte übertragen und im prgramm direkt auswerten, leider muss ich den ADC dennoch komplett auslesen, also 12bit weil ich ja die volle spannung messen möchte und anschliessend durch 4 teilen also auf 8bit runterrechnen, deshalb war ja meine frage danach ob ich dem ADC per hardware mitteilen kann gleich auf 8bit basis zu arbeiten, aber leider klappt das ja nicht :p

Besserwessi
27.09.2008, 13:57
Der AD Wandler wandelt immer 10 Bit, aber man kann einstellen wie die Bits auf ADCL und ADCH aufgeteilt werden. Wenn das Bit ADLAR im Register ADMUX gestezt ist, enthält ADCH die obernen 8 Bits und ADCL die unteren 2. Dann kann man also aus ADCH die werte mit 8 Bis auflösung auslesen.

Entschuldigung wenn ich zu sehr vom Thema abgewichen bin.
Ohne Kommentare ist so ein programm schwer zu verstehen, und die Verzögerung ist schon etwas ungewöhnlich.

Die wartezeiten sind ja nur in der ISR wenn nicht gemessen wird. Ich weiss nicht wie gut GCC beim optimieren ist, aber das ADC/16 könnte relativ lange dauern wenn es nicht vom optimierer durch (ADC >>4) ersetzt wird. Immerhin ist der Prescaler nur bei 8 d.h. maximal 8*13 Zyklen für die AD ISR routine. Das kann immerhin schon mal erhlären wieso keine kleinerer Teiler geht, denn dann reicht offensichtlich die Zeit nicht mehr für die ISR und es werden werte ausgelassen.
Wenn der Controller mit 16 MHz läuft ist das auch schon reichlich schnell für den AD, da sollte eher ein Teiler von 32 oder so hin.

Die Schwebungen können auch bei gleichem Quarz noch vorkommen die PWM Frequenz ist 8 MHz / 99 (oder 100 ?). Die AD Frequenz 16 MHz / 8 / 13 = 16 MHz / 104 = ca. 153 kHz. Da kann es immernoch zu einer Art schwebung kommen, denn der AD Eingang wird ja nur ganz kurz für ca. 1 µs abgefragt. Jenachdem ob da gerade das PWM Signal H oder L ist kann das schon einen Unterschied machen. Selbst auf eine geätzten Platine ist es nicht leicht da kleine Störungen zu vermeiden.

Ceos
27.09.2008, 15:07
8Mhz geteilt durch 100, er zählt von 0 bis 99 löst dann zeitgleich mit 99 den interrupt aus und erst im nächsten timerschritt setzt er wieder auf 0, hab mich auch erst vom echten oszilloskop überzeugen lassen ... im moment zu mindest habe ich ja ADC prescaler 8 * 13 ADC clock rechentakte zeit zum dividieren, ein prescaler unter 8 gibt keine berechenbaren ffrequenzen mehr, deine idee mit (ADC>>4) ist genial ... warum ist mr das nciht eingefallen XD ... es könnt wirklich sein dass bei PS 4 oder gar PS 2 die 26 bzw, 52 rechenzyklen nicht ganz ausreichen, ich redduzier mal die ISR und verfrachte das senden in die uart ISR

achhhhssoooooooooooo jetzt hab ich das mit dem adlar erst richtig gefressen, stimmt so spar ich mir die division!!! danke besserwessi ^^

markusj
27.09.2008, 16:07
Ok, und ich habe deine rumrechnerei verstanden. Du machst es aber auch umständlich ;)
Es würde mich schwer wundern wenn GCC diese Optimierung nicht von alleine hinbekommt, immerhin hat er es ja nur mit unsinged Werten zu tun, denen man beim Shiften ja nicht weht tut.

mfG
Markus

Ceos
27.09.2008, 16:47
ja mei hüpertärminel und excel zwingen mich zu optimierungen

ISR(SIG_ADC)
{
*pos = ADCH;
if (++pos > end) {
ADCSRA &= ~((1<<ADEN) | (1<<ADIE));
pos = adcval;
UCSRB |= (1<<UDRIE);
}
}

ISR(SIG_UART_RECV)
{

}

ISR(SIG_UART_TRANS)
{

}

ISR(SIG_UART_DATA)
{
UDR = (*pos)/4+'!';
while (!(UCSRA & (1<<UDRE)));
UDR = '\r';
pos++;
if (pos > end) UCSRB &= ~(1<<UDRIE);
}

messreihen haben ergeben dass ich DENNOCH nicht unter ADC prescaler 8 gehen kann, da kommt nur schrott raus .... die schwebung hängt wirklich nur mit der frequenz zusammen, wenn ich die impulsfrequenz nur ein wenig verschiebe, klärt sich die schwebung zu einer gleichmäßigen schwingung, die um +/- 2 vom zielwert herumschwingt

da es im moent nur provisorisch ist und die zeit unkritisch habe ich die ascii anpassung in die UART ISR verlegt

also wie ich mit dem prescaler noch vernünftig auf 2 runterkommen soll ist mir absolut unklar, liegt vermutlich an den 16Mhz dass ich nicht tiefer als 8 komme, bei 4 komme ich auf umgerechnet eine frequenz von 1,8kHz also 0.8kHz zu viel die abtastung wird also nur um etwa 10% schneller statt sich zu verdoppeln

markusj
27.09.2008, 17:32
Das Verhältnis zwischen Rechenzeit und Wandlungszeit bleibt bei unterschiedlichen Taktfrequenzen immer gleich!

Das was du beschreibst deutet darauf hin, dass die Eingangsimpedanz zu hoch ist.
Der ADC ist laut Datenblatt darauf ausgelegt, bei Normfrequenz mit einer Eingangsimpedanz von maximal 10kOhm (Datasheet, Abschnitt ADC: "Analog Input Circuitry")
Wenn du den ADC mit einer höheren Frequenz betreibst, muss der interne Kondesator schneller aufgeladen werden => deine Stromquelle darf keinen so hohen Widerstand bieten.
Wenn sie das dennoch tut, kann es sein, dass du Schrott misst.

mfG
Markus

PS: Hoffentlich habe ich dich richtig verstanden ;)

Besserwessi
27.09.2008, 19:38
Wenn es schneller sein soll könnte man auf den Interrupt verzichten und die Daten im Hauptprogram in den Speicher kopieren. Viel Zeit wird schon für Anfang und Ende der ISR zum Retten der Register verbraucht.
Man hat aber immer noch sie Probleme mit dem AD-wandler, der nicht für so hohen Takt ausgelegt ist. Auch eine Niederohmige Qualle hilft da nicht unbedingt viel.

markusj
27.09.2008, 21:07
Klar wird der ADC ungenauer bei steigender Frequenz. Aber nachdem was ich bisher so zwischen den Zeilen im Forum und im Datenblatt gelesen habe, ist die Impedanz der "Qualle" eben bei steigender Frequenz durchaus von Bedeutung.

mfG
Markus

Ceos
28.09.2008, 01:40
naja ich sage es mal so, wenn ich mti prescaler 8 messe, bekomme ich in 1mS ~153 werte, wenn ich mit ps 4 ODER 2 rechne werden es nicht wie zu erwarten wäre ~306 sondern nur rund 185 werte, der wandler ist schlicht zu langsam bei 16Mhz takt ... die daten für meinen tiefpass haste ja, rechne doch mal die Eingangsimpedanz aus, 100Ohm 330nF und 3,6kOhm und 10nF, die ergebnisse sind immer gleich, bei ps2 und 4 rund 185 werte pro impulse == 1mS ... das würde aber schon fast an die im datenblatt genannten 200kHz rankommen obwohl ich aus dem datenblatt nicht wirklich entnehmen kann worauf diese 200kHz sich beziehen .... die schwebung zu eliminieren wird wohl fast unmöglich sein, es sei denn ich schaffe eine passene kombination aus auflösung und samplezahl um mein signal zu erzeugen wo die, naja ich nenns mal "oberschwingung" gleichmäßig ist ... mhhh ndas hab ich ja noch garnicht probiert ^^

Besserwessi
28.09.2008, 10:43
Die 200 kHz im Datenblatt beziehen sich auf den AD Takt. Also Quarztakt / Prescaler. Das gibt dann eine maximale Samplingrate von 200 kHz / 13 = 15,4 Khz. Diese einschränkung ist aber nur für die volle 10 Bit Genauigkeit. Sonst sind bis 1 MHz AD takt vorgesehen, also Prescaler 16 bei 16 Mhz Takt.

Mit dem Interrrupt geht das einfach nicht schnell genug die daten auszulesen, der AD wandler würde noch schneller Daten liefern, allerdings ist nicht sicher das die gut sind. Geht dann aber nicht mehr mit ISR in C, sondern nur noch in ASM oder per polling.

Ceos
28.09.2008, 11:42
*grusel* ASM
das polling bleibt wohl die letzte variante die ich probieren kann, ich schrebis mal um ... hätt mir nie träumen lasen dass interrupts so stark bremsen ... ich dachte immer dass das registersichern in max 4 rechenzyklen erledigt ist, dann noch die kopieraktion aus register in speicheradresse, dann inkrement und vergleichen

markusj
28.09.2008, 12:36
Das Problem ist, dass AVR-GCC wohl immer alle Register sichert, auch wenn die ISR nur eine Hand voll braucht. Das macht >50 Operationen nur für die Katz.

mfG
Markus

Besserwessi
28.09.2008, 13:10
Mit polling könnte man in C wohl auf einen Vorteiler von 2 runterkommen. In ASM wäre auch eine 1 möglich, aber da wird der AD wohl kaum noch was brauchbares geben.
Den zweiten Vorteil den der Compiler ohne ISR hat, ist das mehr daten in den Registern gehalten werden können. Außer dem Pufferspeicher sollte der Rest in den Registesrn bleiben können.

Ceos
01.10.2008, 13:20
tatsache, mit polling bekomm cih echt mehr werte ... ich dachte das interrupthandling wäre irgendwie hardwareseitiig etwas optimiert sodass das registersichern scheller geht oder so .... jaja optimismus und leichtglaube ... leider hab ich ein problem, mit der abfrage

if ((convert > 0) && (ADCSRA & (1<<ADIF)) )

scheint er mir trotz sofortigen

ADCSRA &= ~(1<<ADIF);

dennoch mehrmals dasselbe ergebnis aus dem register zu lesen, obwohl scheinbar kein neues hinterlegt wurde

EDIT: kann das was mit dem sample and hold zu tun haben ? ich habs mehrfach gelesen aber nciht gefressen was es damit auf sich hat

PS: immernoch freerunning mode PS 8

PPS: PS4 hat ganz hässliche ausrutscher drinne, PS2 sieht OK aus aber das ergebnis ist eher unzufreidenstellend .... PS 8 reicht für meine zwecke aber auch aus, nur hatte ich gehofft die schwebung zu eliminieren, bei PS 2 ist die quasi nicht vorhanden !!!

kann cih eigentlich die ISR Assemblermäßig optimieren ? wenn ja, wie ?

markusj
01.10.2008, 14:03
Die ISR kostet dich mindestens acht Zyklen für Stackpointer+SREG sichern. Du hast bei PS2 13*2 Takte für ALLES was du zu tun hast zur Verfügung.
Tatsächlich wirst du um Polling nicht herum kommen.
Hast du mal das Datenblatt gelesen? Du löschst das ADIF-Bit, indem du eine EINS drauf schreibst.
ADCSRA |= (1 << ADIF)

mfG
Markus

Ceos
01.10.2008, 14:12
scheiii.... ja stimmt das war ja immer das hinundhergedrehe mit 1 und 0 mein fehler danke

Besserwessi
01.10.2008, 17:29
Für ein reines ASM programm könnte das noch per ISR gehen. Da kann man extra Register reservieren, braucht also das RAM nur noch für die Daten. Die meiste Rechenzeit wird zwar für den ISR overhead draufgehen, aber das eigentliche kopieren der daten braucht auch nur ganz wenige Zyklen. Allerdings wird da wirklichnicht mehr viel Rechenzeit übrigbleiben und man kann besser polling nehmen.

Ceos
01.10.2008, 23:03
polling brachte 1 a ergebnisse, PS 4 ... naaaaaja .... PS 2 ...... ganz ok, wenn man extremwerte mal rausfiltert

PS 8 ist echt die schmerzgrenze für den ADC, gott ehy (sry für die unchristliche bemerkung) die schwebung nervt echt tierisch, aber ES GEHT! ^_^

wieder so ne "fixe idee" die ich abhaken kann, bleiben nur noch 3 auf der liste :p (die software für die grafische auswertung ödet mich grad an zu schreiben, ich bleib erstmal bei meiner excel lösung XD)
ich freu mich dass es dieses forum gibt