Hi,
ich versuche mit einem ATtiny44a über einen Shunt den Stromfluss in eine
Batterie zu messen.
Dabei wird Differentiell gemessen, wobei auch der Bipolar Modus zum
Einsatz kommt um sowohl Lade- als auch Entladeströme zu erfassen.
Da die interne 1.1V Ref verwendet wird, beabsichtige ich zuvor eine
Offsetkalibrierung der Differentiellen Eingänge um den Fehler nach
Möglichkeit klein zu halten. (also den Gain fehler der nachgeschalteten
Verstärkerstufe im ADC)
Ich bin jetzt soweit nach dem Datasheet verfahren, komme jedoch zu kein
vernüftiges Ergebnis.
Wird der Unipolar modus verwendet, dann beträgt der Offset ca. 10-15 LSB
Wird jedoch der Bipolar modus angewandt, so schnell der Offset auf 50-60
LSB hoch.
Das erscheint mir doch etwas zu viel, zumal im Datasheet ca. 8 LSB als
typ. angegeben wird.
Habt ihr schon ähnliche Erfahrungen gemacht? Woran könnte es denn
liegen?
-Andy
Da laufen gerade ein paar Sachen durcheinander.
Andy S. schrieb:> Dabei wird Differentiell gemessen, wobei auch der Bipolar Modus zum> Einsatz kommt um sowohl Lade- als auch Entladeströme zu erfassen.
Der Bipolar Modus ist der Differenzbetrieb. "Wobei auch..." läßt aber
vermuten daß Du das anders aufgefaßt hast.
Andy S. schrieb:> Da die interne 1.1V Ref verwendet wird
Die ist ungenau. Ist der Kondensator dran der da hingehört? Je nach
Schaltung und je nach Meßmethode geht der Fehler stärker oder schwächer
ein. Was wird wie kalibriert? Ohne Schaltplan und Code und ohne genau zu
wissen was womit abgeglichen wird ist das nicht beurteilbar wie stark
die Abweichung das Endergebnis verfälscht.
Andy S. schrieb:> Wird der Unipolar modus verwendet, dann beträgt der Offset ca. 10-15 LSB
Das ist nicht möglich. Es ist ein 10 Bit Wandler. LSB bedeutet Least
Significant Bit. Ein Fehler von 3 LSB bdeutet das die letzten 3 Bits
Grütze sind. Das Ergebnis kann also um 0 bis 2^3=8 Abweichen. 15
verkehrte Bits sind nicht möglich. So viele Bits hat der Wandler nicht.
Andy S. schrieb:> Wird jedoch der Bipolar modus angewandt, so schnell der Offset auf 50-60> LSB hoch.
Fehler in verketteten Operationen verstärken sich. Ist der erste Wert
verkehrt, dazu die Referenz falsch und dann das ganze verstärkt, so wird
auch der Endfehler entsprechend verstärkt. Hinzu kommt, daß die
Verstärkung selbst auch noch einen eigenen Fehler mitbringt. Das kann
sich wie schon gesagt aufsummieren/multiplizieren. Ohne Kenntnis des
genauen Verfahrens ist das nicht beurteilbar wie sehr sich das
aufschaukelt.
Andy S. schrieb:> Das erscheint mir doch etwas zu viel, zumal im Datasheet ca. 8 LSB als> typ. angegeben wird.
Das ist in der Tat blöd formuliert im Handbuch. Das ist ein Fehler. Du
beziehst dich vermutlich auch die Angabe absolute Accuracy auf Sete 179.
Da steht 8 LSB. Eine Genauigkeit gibt man nicht in LSB an. Da müßte
entweder MSB für Most Significant Bit oder einfach nur Bit stehen.
LSB bei Genauigkeit macht einfach keinen Sinn, es sei denn man möchte
damit zum Ausdruck bringen, daß es um das niedrigste noch gültige Bit
geht. Das wäre aber eine unübliche, eigenwillige Neuinterpretation. Das
wäre zudem noch inkonsistent, da zuvor LSB noch in der üblichen Art und
Weise verwendet wird. In anderen Atmel-Handbüchern für andere Modelle
steht es auch anders geschrieben. Es ist also eher ein
Flüchtigkeitsfehler bei der Eintragung der Einheiten im Dokument.
Ferner wäre noch von Bedeutung wie schnell du mißt. Der ADC hat einen
eigenen Takt. Dieser wird über einen Taktteiler aus dem Haupttakt
erzeugt. Ich meine damit aber NICHT die Samplingrate. Die gibt nur an
wie oft gemessen wird. Die beiden Werte sind nur indirekt
zusammenhängend in sofern, daß der Takt angibt wie hoch die Samplingrate
maximal sein kann. Ist der ADC Takt zu hoch, wird die Wandlung zunehmend
ungenau. Der Taktteiler des ADC ist also je nach Haupttakt entsprechend
anzupassen.
Auch ist zu beachten daß nach der (re)Konfiguration des ADC das erste
Ergebnis machmal Schrott ist, ja nachdem was man gerade umgeändert hat.
Z.B. ist die erste Messung nch dem Setzen der Referenz ungültig. Dann
muß also vor dem eigentlichen Messen eine zusätzliche Dummy-Messung
vorab erfolgen, dessen Ergebnis verworfen wird.
Also ich empfehle noch einmal das Tutorial hier zum ADC und das
Datenblatt in Ruhe zu lesen und ein paar Projekte ebenso um einen
Überblick über die Stolperfallen beim ADC zu erhalten.
Um dieses Dokument geht es
http://www.atmel.com/Images/doc8183.pdfCarsten R. schrieb:> LSB bei Genauigkeit macht einfach keinen Sinn
Machmal wird das zwar auch gemacht, dann ist aber gemeint, "Genau bis
auf die letzten 2 Bits" bei 2 LSB. Das macht Atmel auch. Aber dann im
selben Dokument zu schreiben Genauigkeit 8 LSB macht bei einem 10 Bit
ADC nun wirklich gar keinen Sinn. Dann bleiben nur noch 2 Bit übrig^^ Da
geht in dem besagten Dokument ein bissl was durcheinander. Und das dann
auf Seite 178 steht 15 LSB macht es nicht besser. Da kann an sich auch
nicht mehr herausreden mit: Es sollte eigentlich 1.5 LSB heißen. Was
soll dann die 8 auf der nächsten Seite?
Wie gesagt, die anderen Datenblätter wie zum Beispiel das vom ATtiny261
sind besser.
http://www.atmel.com/Images/Atmel-2588-8-bit-AVR-Microcontrollers-tinyAVR-ATtiny261-ATtiny461-ATtiny861_Datasheet.pdf
Aufgrund der Ähnlichkeit der Chips würde ich in diesem Falle also auch
mal die anderen Datenblätter nutzen bis dieses überarbeitet wurde.
@Andy
Da hast Du bezüglich der Dokumentation für den Einstieg genau den
richtigen Chip erwischt ;-)
Carsten R. schrieb:> Andy S. schrieb:>> Dabei wird Differentiell gemessen, wobei auch der Bipolar Modus zum>> Einsatz kommt um sowohl Lade- als auch Entladeströme zu erfassen.>> Der Bipolar Modus ist der Differenzbetrieb. "Wobei auch..." läßt aber> vermuten daß Du das anders aufgefaßt hast.
Ist schon klar. Jedoch besteht die Möglichkeit die Basis für die
Differezmessung auf 0-1023 fest zu legen wie es bei der Unipolaren
Methode ist, oder halt von -512 bis + 511 wie es bei der Bipolaren
Methode der Fall ist.
Der einzige Unterschied zw. Single Ended Messungen und der
Differnezmessung im Unipolaren Modus ist der, dass du dein GND beliebig
legen kannst (also logisch im bereich von Gnd - Vcc) und halt nicht
unbedingt auf den AGND angewiesen bist.
Carsten R. schrieb:> Aber dann im> selben Dokument zu schreiben Genauigkeit 8 LSB macht bei einem 10 Bit> ADC nun wirklich gar keinen Sinn. Dann bleiben nur noch 2 Bit übrig^^ Da> geht in dem besagten Dokument ein bissl was durcheinander.
Das hab ich mir auch gedacht ^^
Ich habe es dann einfach so interpretiert, dass Atmel damit +- 8(dez.)
bezeichnet und logischer weise nicht +-8 bit.
Vielleicht sollte ich noch erwähnen, dass die Angaben die ich weiter
oben gemacht habe, also die Ungenauigkeit dann natürlich als 10-15
(dez.), respektiv 50-60 (dez.) zu interpretieren sind.
Zurück zum Thema:
Selbst wenn die Genauigkeit bei 1.5 LSB (bit) oder von mir aus auch bei
3 LSB (bit) liegen mag, sind die Werte von bis zu 60(dez.) als Offset
deutlich darüber. Mich wundert es halt, dass so große Abweichungen
auftreten, damit lässt sich nicht schön arbeiten.
Carsten R. schrieb:> Also ich empfehle noch einmal das Tutorial hier zum ADC und das> Datenblatt in Ruhe zu lesen und ein paar Projekte ebenso um einen> Überblick über die Stolperfallen beim ADC zu erhalten.
Da steht leider nix über Differentielle Messungen so wie ich sie gerne
hätte.
Es ist auch nicht das Erste mal für mich, dass ich mit einem ADC
Messungen anstelle. Soll heißen: Der ADC wurde meines Wissens nach
richtig konfiguriert.
Also das Übliche halt: Takt nicht zu hoch Referenz richtig gesetzt.
(Muss hier nicht mit einem externen Kondensator entkoppelt werden,
glaube dazu gibt es auch einen Thread hier im Forum der sich damit
beschäftigt. Es wird auf jeden fall nicht explizit im Datasheet verlangt
und die V_REF Spannung wird auch nicht nach drausen geführt)
Aktualisierung der MUX Einstellungen erst nach erfolgreicher Wandlung
usw.
Hier ist noch der Teil des Source-Codes der sich mit dem ADC
beschäftigt:
Zur Schaltung gibt es nicht viel zu sagen:
ATtiny 44a mit minimal Beschaltung zu testzwecken. Also das Übliche...
alle ic´s mit 100n entkoppelt Bypass Kondensator an den Messeingängen
Spannungen mit Multimeter abgleichen.
Saubere DC als Vcc.
void init_all(void)
{
//UART
init_suart();
//ADC
ADCSRA|=_BV(ADPS1)^_BV(ADPS2); //ADC an Fosc/64
ADMUX|=_BV(REFS1); //Interne 1.1V
ADCSRB|=_BV(BIN); //Bipolar iput mode
offset_calib();
}
int16_t get_adc(uint16_t mux)
{
ADMUX&=~ADC_MUX_MASK; //ADC mux löschen
ADMUX|=mux; //Kanal einstellen
ADCSRA|=_BV(ADEN)^_BV(ADSC); //einzelne Messung starten
while (!(ADCSRA & (1 << ADIF))); //Warten bis fertig
ADCSRA|=(1<<ADIF); //interrupt bit löschen
ADCSRA&=~_BV(ADEN);
return(ADC);
}
void offset_calib(void)
{
int16_t sum=0;
for (uint8_t i=0;i<16;i++)
{
sum+=get_adc(ADC_MUX_OFFSETT_CALC);
//convert_transmit(sum,MITVZ);
}
offset_adc=(sum/16);
}
int main(void)
{
init_all();
//sei();
while(1)
{
_delay_ms(1000);
convert_transmit(get_adc(6),MITVZ); //Single ended
convert_transmit(get_adc(0b00100100),MITVZ); //Diff gain1 pos und
neg beide an adc3 --> offset calib
sputchar('\n');
}
}
Andy S. schrieb:> Muss hier nicht mit einem externen Kondensator entkoppelt werden,
Richtig. Aber man kann. Dann ist der Pin allerdings damit belegt und
nicht mehr anderwertig nutzbar. Man macht das also nur, wenn notwendig
oder wenn der Pin ohnehin frei ist und man unbedingt Teile verbauen
will. Somit haben wir beide Recht.
Zum Code:
Er ist ja nur auszugsweise und ich schreibe in Assembler. Daher bin ich
mir bei ein oder zwei Details nicht sicher ob sie von Dir oder von einer
der Standard-Deklarationen stammen. Wie auch immer.
Deine offset_calib(void) hinterlegt den Offset in offset_adc. Danach
wird das Teil nicht mehr angefasst. Ich kenne zwar ADC_MUX_OFFSETT_CALC
nicht, aber ich nehme an das ist irgendwo schon richtig deklariert und
definiert.
Mir ist jetzt nicht klar wo Dir nun der Offset ausgegeben wird. In der
offset_calib(void) ist es ja auskommentiert. Also bleibt nur die Stelle
am Ende der Main(). Beide stützen sich auf get_adc. Und da hakt es.
1. Du setzt die Referenz und kalibrierst dann. Die erste Messung ist
Schrott (s.O. Referenz ändern). Also vor dem Kalibrieren Dummymessung
einführen.
2. Dann wird in der get_adc(xxx) jedesmal der MUX neu gesetzt. Bei
differentiellen Messungen braucht der Verstärker Zeit zum Einschwingen
vor der Messung. Daß du jedesmal zwar den selben Kanal wählst ändert
daran nichts. Den Hinweis findest du auf Seite 144 unten. Auch hier
Dummymessung einfügen und verwerfen oder durch Ein- und Ausschalten eine
long conversion erzwingen.
3. Du mißt im Pollingbetrieb anstatt im Sleep. Die CPU arbeitet weiter
und erzeugt so Störungen.
4. Du verwendest keinen Kondensator zum stabilisieren der Referenz.
Jeweils einzelnd mag das noch gehen. Aber in der Summe schaukelt es sich
dann auf. Weitere Störquellen, eventuell auch Schaltungstechnische
Störungen, sind nicht ausgeschlossen.
Ich hoffe ich konnte Dir weiterhelfen.
schönes WE
Carsten
Carsten R. schrieb:> 2. Dann wird in der get_adc(xxx) jedesmal der MUX neu gesetzt. Bei> differentiellen Messungen braucht der Verstärker Zeit zum Einschwingen> vor der Messung. Daß du jedesmal zwar den selben Kanal wählst ändert> daran nichts. Den Hinweis findest du auf Seite 144 unten. Auch hier> Dummymessung einfügen und verwerfen oder durch Ein- und Ausschalten eine> long conversion erzwingen.
Wird ja hier gemacht. Nach jeder Messung wird der ADC angehalten und vor
jeder Messung erneut gestartet.
ADCSRA|=_BV(ADEN)^_BV(ADSC); //einzelne Messung starten
...
ADCSRA&=~_BV(ADEN);
Dies sollte meines Wissens nach eine längere Wandlung erzwingen.
Das mit dem Dummy-Read sowie dem Tip mit ADC Noise Reduction und doch
mal die V_REF mit einem Kondensator entkoppeln werde ich mal
ausprobieren.
Danke soweit!
Ah sorry,
das hatte ich glatt überlesen. _BV(ADEN) ist für meine Augen etwas
ungewohnt^^ Da hast du recht. Damit sollte eine long conversion
erzwungen werden.
Somit wäre Nummer 2 zu streichen. Im zweifel würde ch trotzdem mal eine
zusätzliche Dummymessung testen wenn man nicht weiterkommt. Nummer 1,
das Setzen der Referenz, bleibt trotz An- und Abschalten per ADEN ein
Problem. Hier sollte die erstn Messung auf jeden Fall verworfen werden.
Viel Glück bei der Optimierung der Genauigkeit.