ADC Differenzeingang

Hallo an alle.
Ich bin neu im Forum und habe als kleines Kind mal mit Bascom die AVRs programmiert. :slight_smile:
Nun bin ich über Arduino gestolpert und habe gleich ein Projekt für mich gefunden um das System mal auszuprobieren.
Nun würde ich gerne die Differenz ADCs mit 20 facher Verstärkung nutzen, leider kann ich
keine Informationen finden wie die Ports in Arduino benutzt werden.
Also falls einer ein Code Beispiel für mich hat wäre ich echt dankbar.
Angeschlossen wird ein O2 Sensor mit einer Ausgangs Spannung von ca. 10 – 50 mV.

Gruß
Claus

ich verstehe nicht:

Nun würde ich gerne die Differenz ADCs mit 20 facher Verstärkung nutzen

Was meinst Du? Die ADC das Controllers oder einen externen ADC-Wandler?

Grüße Uwe

Wow was für eine Geschwindigkeit hier !!
Ich meine die ADCs eine Atmega2560.
Ich habe 2 von den Sensoren die ich auslesen muss.
Ich möchte mir einen OP für die verstärkung sparen.

Gruß
Claus

Dann bist du hier falsch.... alles was über "ich möchte eine LED 2x blinken lassen, bevor Pin 3 auf High schaltet" überfordert die meisten hier... mein Tipp: http://www.mikrocontroller.net

Marcus, hast Du heute eine Meinung ... :wink: :wink: :wink:

@Madwilli Jetzt überforderst Du mich auch.
Wenns mit Bascom auf dem ATmega2560 geht, dann funktionierts auch mit dem Arduino.
Ich hab im Datenblatt auf die schnelle nichts dazu gefunden. Vieleicht weiß jemand anders mehr.
Grüße Uwe

Ich habe keine Ahnung ob das auch mit Bascom funktioniert.
Ich dachte schon ich bin zu blöd.

Weiß den wirklich keiner wie der Code für die benutzung der ADC aussieht ?

danke
Claus

Auch auf die Gefahr, das ich am Ende als "doof" dastehe :slight_smile:
Du willst einen der analogen Eingänge nutzen, um die Spannung eines Sensors zwischen 10 und 50 mV zu messen.
Das würde aus meiner Sicht durch setzen der Referenzspannung gehen, siehe
analogReference() - Arduino Reference. Wobei 0,05V schon ziemlich "dünn" ist.
Du könntest aber mittels eines Operationsverstärkers die Spannung auf 1 bis 5 V anheben.
Da fehlt mir etwas die Erfahrung, aber aus meiner Sicht dürfte folgendes Schaltung verwendbar sein:
Operationsverstärker – Wikipedia

Eingelesen wird der Wert einfach per analogRead(analogPin), was einen Wert zwischen 0 und 1023 liefert, den Du dann auf die tatsächlichen Werte mappen kannst.
Mario.

Ich hoffe das war jetzt nicht komplett an der Frage vorbei :slight_smile:

Der ATmega2560 hat im Register in dem der Multiplexereingang für den AD-Wandler eingestellt wird die Möglichkeit eines verstärkten Differentialeingangs zu setzen.
Wies genau geht kann ich nicht sagen da ichs nie versucht habe.
Prinzipiell aber so wie einen bestimmten analogen Eingang per SW direkt zu lesen.
ADMUX – ADC Multiplexer Selection Register und ADCSRB – ADC Control and Status Register B

http://www.atmel.com/Images/doc2549.pdf ab Seite 275. und Table 26-4. Input Channel Selections auf Seite 290f

als 1. Hilfe: ATMEGA2560 ADC-Kanäle lesen - Roboternetz-Forum

Grüße Uwe

Hallo,
zufällig habe ich genau so was schon mal ausprobiert. Ich stell den Code mal rein. Ist zwar ziemlich viel Overhead drin (serielle Kontrollausgaben), aber ich kann den Code nicht zusammenkürzen und testen, weil ich gestern meinen Mega geschrottet habe :frowning: (12V von hinten übers Steckbrett kommt nicht so gut).
Ich hoffe der Code ist verständlich, zumindest geht daraus hervor, welche Register gesetzt werden müssen. Der Rest sollte sich aus dem Datenblatt ergeben.

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.flush();
  Serial.println("\nSelect Action:\n0 - Measure A0 and A1 single ended\n1 - Measure A0 and A1 differential\n2 - Measure differential continual\n");
  while(!Serial.available()){}   // waiting for input on serial interface
  switch(Serial.read())
  {
  case '0':
    single_ended();
    break;
  case '1':
    diff_mode();
    break;
  case '2':
    diff_mode_c();
    break;
  default:
    break;
  }
}

void single_ended()  {
  for (int i=1; i<=10; i++)  {
  int sensorValue0 = analogRead(A0);
  int sensorValue1 = analogRead(A1);
  Serial.print(i, DEC);
  Serial.print("\t");
  Serial.print(sensorValue0, DEC);
  Serial.print("\t");
  Serial.println(sensorValue1, DEC);
  }
}

void diff_mode()  {
//  pinMode(A0, INPUT);
//  pinMode(A1, INPUT);
  Serial.print("ADCSRA ");
  Serial.println(ADCSRA, BIN);
  Serial.print("ADCSRB ");
  Serial.println(ADCSRB, BIN);
  Serial.print("ADMUX ");
  Serial.println(ADMUX, BIN);
  ADCSRB = 0;
  ADMUX = 0;
  Serial.print("ADCSRA ");
  Serial.println(ADCSRA, BIN);
  Serial.print("ADCSRB ");
  Serial.println(ADCSRB, BIN);
  Serial.print("ADMUX ");
  Serial.println(ADMUX, BIN);
//  ADMUX |= ((1 << MUX3) | (1 << REFS0) | (1 << REFS1));
  ADMUX |= ((1 << MUX0) | (1 << MUX3) | (1 << REFS0));
  ADCSRA |= ((1 << ADEN));
  Serial.print("ADCSRA ");
  Serial.println(ADCSRA, BIN);
  Serial.print("ADCSRB ");
  Serial.println(ADCSRB, BIN);
  Serial.print("ADMUX ");
  Serial.println(ADMUX, BIN);
  for (int i=1; i<=10; i++)  {
    ADCSRA |= (1 << ADSC);
    delay(1);
    while (bit_is_set(ADCSRA, ADSC));
    int sensorValueL = ADCL;
    int sensorValueH = ADCH;
    int sensorValue = (sensorValueH << 8) | sensorValueL;
    Serial.print(i, DEC);
    Serial.print("\t");
//  Serial.print(sensorValueH, DEC);
//  Serial.print("\t");
//  Serial.println(sensorValueL, DEC);
    Serial.println(sensorValue, DEC);
    delay(10);
    }
}

void diff_mode_c()  {
  ADCSRB = 0;
  ADMUX = 0;
  ADMUX |= ((1 << MUX0) | (1 << MUX1)  | (1 << MUX3) | (1 << REFS0));      // VRef = AVCC with ext Cap, ADC1 +diff, ADC0 -diff, Gain 10x
  ADCSRA |= ((1 << ADEN) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0));
  Serial.println("Press any key and RETURN to stop reading");
  while(!Serial.available())  {
    ADCSRA |= (1 << ADSC);
//    delay(1);
    while (bit_is_set(ADCSRA, ADSC));
    int sensorValueL = ADCL;
    int sensorValueH = ADCH;
    int sensorValue = (sensorValueH << 8) | sensorValueL;
//    Serial.print(i, DEC);
//    Serial.print("\t");
    Serial.println(sensorValue, DEC);
    delay(100);
    }
  Serial.flush();   // don't care what key was pressed
}