Probleme mit Schaltung (Ohmmeter)

Hallöchen liebes Forum!

Ich hab hier einige Verständnisprobleme, ich hoffe ihr könnt mir helfen.

Ich habe folgende Schaltung versucht aufzubauen:

https://simple-circuit.com/arduino-auto-ranging-ohmmeter-lcd/

(Hier wurde dieselbe Schaltung auch schonmal besprochen: https://forum.arduino.cc/t/auto-ranging-ohmmeter-does-not-read-150k-ohm-solved/880215/17)

Ich habe mich rangesetzt und die Schaltung etwas modifiziert:

Der Code ist folgender:

Ohmmeter_multirangeOhm_simple_circuit.ino (4.9 KB)

Kann mir jemand folgende Code-Zeilen erklären? Ich bin da leider ein Noob...

  if(volt_image >= 550 && ch_number < 4) {
    ch_number++;
    ch_select(ch_number);
    delay(50);
    return;
  }

  if(volt_image <= 90 && ch_number > 0) {
    ch_number--;
    ch_select(ch_number);
    delay(50);
    return;
  }

Was genau macht er da, wenn der Wert von A0 größer gleich 550 und "Channel Number" kleiner als 4 ist, soll er was genau machen...? Zählt er da irgendwas hoch und runter?

 if(value < 1000.0)
      sprintf(_buffer, "%03u.%1u Ohm ", (uint16_t)value, (uint16_t)(value*10)%10);
    else if(value < 10000.0)
           sprintf(_buffer, "%1u.%03u kOhm", (uint16_t)(value/1000), (uint16_t)value%1000);
    else if(value < 100000.0)
           sprintf(_buffer, "%02u.%02u kOhm", (uint16_t)(value/1000), (uint16_t)(value/10)%100);
    else if(value < 1000000.0)
           sprintf(_buffer, "%03u.%1u kOhm", (uint16_t)(value/1000), (uint16_t)(value/100)%10);
    else
      sprintf(_buffer, "%1u.%03u MOhm", (uint16_t)(value/1000000), (uint16_t)(value/1000)%1000);

Was genau bedeutet jeweils der Code hinter sprintf??

Mein weiteres Problem ist nämlich nun, dass, wenn ich 1k Ohm und 100 Ohm bspw. messe, zeigt er mir Quatsch an (Ich habe den Code etwas modifiziert und lasse mir zwischendurch Werte von A0 (value_image), A1 (value_image1), Widerstandswerte an A0 (value) und A1 (value1) anzeigen):

Bei 1kOhm (zeigt er mir 159,69 kOhm an):

19:40:53.420 -> A0: 527
19:40:53.460 -> 
19:40:53.460 -> Value: 159693.73
19:40:53.460 -> 
19:40:53.460 -> A1: 531
19:40:53.460 -> 
19:40:53.460 -> Value1: 162214.01
19:40:53.460 -> 
19:40:53.460 -> A0: 527
19:40:53.460 -> 
19:40:53.460 -> Value: 159693.73
19:40:53.460 -> 
19:40:53.460 -> A1: 531
19:40:53.460 -> 
19:40:53.460 -> Value1: 162214.01
19:40:53.460 -> 
19:40:53.460 -> Buffer: 159.69 kOhm
19:40:53.460 -> 
19:40:53.460 -> 159.69 kOhm

Bei 100 Ohm (zeigt mir 15,92 kOhm an):

19:41:15.493 -> A0: 98

19:41:15.493 ->

19:41:15.493 -> Value: 15920.71

19:41:15.493 ->

19:41:15.493 -> A1: 102

19:41:15.493 ->

19:41:15.493 -> Value1: 16642.50

19:41:15.493 ->

19:41:15.493 -> Buffer: 15.920 kOhm

19:41:15.493 ->

19:41:15.493 -> 15.920 kOhm

Wenn nichts angesteckt wird, zeigt er richtig an:

19:41:05.466 -> Over Load 
19:41:05.466 -> 

Könnt ihr mir bei den Fehlern weiterhelfen??

schöne Grüße
Matthias

Er schaltet zum nächsten Kanal (Kanal = Meßbereich)
Gleiches passiert wenn die ADC Ablesung kleiner als 90. Da wird der nächstniedrigere Kanal geschaltet. Wenn 4 bzw 0 erreicht wird stoppt das, weil kein größerer/kleinerer Bereich da ist.

sprintf(_buffer, "%03u.%1u Ohm ", (uint16_t)value, (uint16_t)(value*10)%10);

Da wird die Ausgabe formattiert. genaues findest Du unter "sprintf" in einem C /C++ Buch / Webseite.

Hast Du die Schaltung richtig aufgebaut??

Grüße Uwe

Hallo Uwe,

ich habe die Schaltung wie auf dem Bild oben zu sehen, aufgebaut.
Das was ich verändert hatte, war, die Transen raus zu nehmen bis auf den 100er Ohm Bereich.

Evt. funktioniert jetzt das Programm nicht mehr mit der Schaltung, weil die Werte anders sind?? Hmmm....

schöne Grüße Matthias

Ich hab mir noch den Wert von der Widerstandstabelle geben lassen und von dem Buffer, direkt nach der Abfrage "if(volt_image < 900)" (für 1k Ohm Messwiderstand):

19:01:21.371 -> Res_Table: 150300
19:01:21.371 -> 
19:01:21.371 -> A0: 522
19:01:21.371 -> 
19:01:21.371 -> Value: 156600.00
19:01:21.371 -> 
19:01:21.371 -> A1: 536
19:01:21.371 -> 
19:01:21.371 -> Value1: 165422.59
19:01:21.371 -> 
19:01:21.371 -> Buffer: Over Load 

für 100 Ohm Messwiderstand:

19:01:37.418 -> Res_Table: 150300
19:01:37.463 -> 
19:01:37.463 -> A0: 94
19:01:37.463 -> 
19:01:37.463 -> Value: 15207.97
19:01:37.463 -> 
19:01:37.463 -> A1: 141
19:01:37.463 -> 
19:01:37.463 -> Value1: 24027.55
19:01:37.463 -> 
19:01:37.463 -> Buffer: Over Load 

Irgendwie rutscht er bei 1k und 100 Ohm schon in den falschen Widerstands-Bereich, er rechnet mit einem zu großen Widerstand aus dem "res_table"...

Aber wieso??

Danach habe ich mir die Werte wieder für 1k und 100 Ohm nach der gesamten Schleife ausspucken lassen:

19:01:21.371 -> A0: 522
19:01:21.371 -> 
19:01:21.371 -> Value: 156600.00
19:01:21.371 -> 
19:01:21.371 -> A1: 536
19:01:21.371 -> 
19:01:21.371 -> Value1: 165422.59
19:01:21.371 -> 
19:01:21.371 -> Buffer: 156.6 kOhm
19:01:21.371 -> 
19:01:21.371 -> 156.6 kOhm
19:01:37.463 -> A0: 94
19:01:37.463 -> 
19:01:37.463 -> Value: 15207.97
19:01:37.463 -> 
19:01:37.463 -> A1: 141
19:01:37.463 -> 
19:01:37.463 -> Value1: 24027.55
19:01:37.463 -> 
19:01:37.463 -> Buffer: 15.20 kOhm
19:01:37.463 -> 
19:01:37.463 -> 15.20 kOhm

VG

Ich sehe gerade, wenn nichts gemessen wird, sagt er ja "Over Load".

Ich habe mir die Werte von A0, A1, Channel-Nummer und "Res-Table" wieder anzeigen lassen, ganz am Ende, interessant:

19:36:28.691 -> Over Load 
19:36:28.691 -> 
19:36:28.691 -> A0: 1021
19:36:28.723 -> A1: 1021
19:36:28.723 -> Res_Table: 150300
19:36:28.723 -> CH_Nummer: 4

Irgendwie hängt er bei dem Wert 150300 Ohm rum, warum auch immer....

VG

Gib doch mal deinen gesamten Code her - dann kann man sich da einen Reim drauf machen.

Den habe ich oben gepostet, aber hier nochmal direkt:

/***********************************************************************
 * 
 * Arduino autoranging ohmmeter with 16x2 LCD.
 * This is a free software with NO WARRANTY.
 * https://simple-circuit.com/
 *
 ***********************************************************************/

#define CH0  12
#define CH1  11
#define CH2  10
#define CH3  9
#define CH4  8

// variables
byte ch_number;
uint32_t res;
const float messR50R = 52.66;      //   51 Ohm  
float RELres = 0;                           // REL-Widerstand (Bsp. Messleitung)
const uint32_t res_table[6] = {52.66, 149.4, 995.3, 9960, 150300, 999930};
char _buffer[11];

void setup(void) {
  //analogReference(EXTERNAL);   // benutze AREF für eine externe Spannung
  Serial.begin(115200);

   pinMode(CH0, OUTPUT);
  pinMode(CH1, OUTPUT);
  pinMode(CH2, OUTPUT);
  pinMode(CH3, OUTPUT);
  pinMode(CH4, OUTPUT);

  ch_number = 4;
  ch_select(ch_number);

}

// main loop
void loop() {

  uint16_t volt_image = analogRead(A0);
  uint16_t volt_image1 = analogRead(A1);

  if(volt_image >= 550 && ch_number < 4) {
    ch_number++;
    ch_select(ch_number);
    delay(50);
    return;
  }

  if(volt_image <= 90 && ch_number > 0) {
    ch_number--;
    ch_select(ch_number);
    delay(50);
    return;
  }



  if(volt_image < 900) {
    float value = (float)volt_image*res/(1023 - volt_image);
    float value1 = (float)volt_image1*res/(1023 - volt_image1);

Serial.print("Res_Table: ");
  Serial.println(res);
  Serial.println();

 Serial.print("A0: ");
  Serial.println(volt_image);
  Serial.println();
 
 Serial.print("Value: ");
  Serial.println(value);
  Serial.println();

Serial.print("A1: ");
  Serial.println(volt_image1);
  Serial.println();

Serial.print("Value1: ");
Serial.println(value1);
  Serial.println();

Serial.print("Buffer: ");
Serial.println(_buffer);
  Serial.println();

if (value1 <= 51)
  {
    pinMode(CH0, OUTPUT);
    digitalWrite(CH0, LOW); // <==== PNP-Transistor gibt 5V an 51 Ohm
  
    analogReference(INTERNAL);  // Referenz auf 1,1V intern umstellen
    delay(10);                  // benötigt ein paar ms zum einstellen der Vref!
    volt_image = 0;
    volt_image1 = 0;

    for (int i = 0; i < 4096; i++)
    {
      volt_image += analogRead(A0);
      delayMicroseconds(20);
      volt_image1 += analogRead(A1);
      delayMicroseconds(20);
    }
    digitalWrite(CH0, HIGH);  // <==== PNP nach Messung sofort wieder sperren!
  
    analogReference(DEFAULT);     // Referenz auf Ub+ zurückschalten
    delay(1);
    volt_image = volt_image / 4096;
    volt_image1 = volt_image1 / 4096;

    value1 = volt_image / (volt_image1 - volt_image) * messR50R - RELres;

      sprintf(_buffer, "%03u.%1u Ohm ", (uint16_t)value1, (uint16_t)(value1*10)%10);
  }

    if(value < 1000.0)
      sprintf(_buffer, "%03u.%1u Ohm ", (uint16_t)value, (uint16_t)(value*10)%10);
    else if(value < 10000.0)
           sprintf(_buffer, "%1u.%03u kOhm", (uint16_t)(value/1000), (uint16_t)value%1000);
    else if(value < 100000.0)
           sprintf(_buffer, "%02u.%02u kOhm", (uint16_t)(value/1000), (uint16_t)(value/10)%100);
    else if(value < 1000000.0)
           sprintf(_buffer, "%03u.%1u kOhm", (uint16_t)(value/1000), (uint16_t)(value/100)%10);
    else
      sprintf(_buffer, "%1u.%03u MOhm", (uint16_t)(value/1000000), (uint16_t)(value/1000)%1000);
 
  Serial.print("A0: ");
  Serial.println(volt_image);
  Serial.println();
 
 Serial.print("Value: ");
  Serial.println(value);
  Serial.println();

Serial.print("A1: ");
  Serial.println(volt_image1);
  Serial.println();

Serial.print("Value1: ");
Serial.println(value1);
  Serial.println();

 Serial.print("Buffer: ");
  Serial.println(_buffer);
  Serial.println();

  }

  else
    sprintf(_buffer, "Over Load ");

    Serial.println(_buffer);
  Serial.println();
 Serial.print("A0: ");
  Serial.println(volt_image);
  
 Serial.print("A1: ");
  Serial.println(volt_image1);
 
Serial.print("Res_Table: ");
  Serial.println(res);

Serial.print("CH_Nummer: ");
  Serial.println(ch_number);

  delay(2000);   // wait some time

}

void ch_select(byte n) {
  switch(n) {
    case 0:
      digitalWrite(CH0, LOW);
      digitalWrite(CH1, HIGH);
      digitalWrite(CH2, HIGH);
      digitalWrite(CH3, HIGH);
      digitalWrite(CH4, HIGH);
      break;
    case 1:
      digitalWrite(CH0, HIGH);
      digitalWrite(CH1, LOW);
      digitalWrite(CH2, HIGH);
      digitalWrite(CH3, HIGH);
      digitalWrite(CH4, HIGH);
      break;
    case 2:
      digitalWrite(CH0, HIGH);
      digitalWrite(CH1, HIGH);
      digitalWrite(CH2, LOW);
      digitalWrite(CH3, HIGH);
      digitalWrite(CH4, HIGH);
      break;
    case 3:
      digitalWrite(CH0, HIGH);
      digitalWrite(CH1, HIGH);
      digitalWrite(CH2, HIGH);
      digitalWrite(CH3, LOW);
      digitalWrite(CH4, HIGH);
      break;
    case 4:
      digitalWrite(CH0, HIGH);
      digitalWrite(CH1, HIGH);
      digitalWrite(CH2, HIGH);
      digitalWrite(CH3, HIGH);
      digitalWrite(CH4, LOW);
  }
  res = res_table[n];
}

// end of code.

Das ist richtig und fisiologisch.

Grüße Uwe

also so

statt:

Wieso änderst Du eine Schaltung wenn Du davon nicht viel verstehst?

Grüße Uwe

:man_facepalming: :brain: :light_bulb:
Bitte sag mir, was Du da erwartest.
Ich versteh es wirklich nicht.

Und das hier:

Zähl mal durch.
Gute Nacht.

Hallo Uwe,

Wieso änderst Du eine Schaltung wenn Du davon nicht viel verstehst?

  1. Ich versteh das dort gezeigte schon ganz gut.

  2. Ganz einfach, um Sachen mal auszuprobieren.

VG

Bitte sag mir, was Du da erwartest.

Nö.

Aber der Teil des Codes kommt von ihm hier:

https://www.arduinoforum.de/arduino-Thread-L-C-R-Meter

Ich versteh es wirklich nicht.

Ich auch nicht, deswegen bin ich ja hier und stelle Fragen.

Wenn du im Detail weißt, was da passiert, dann erleuchte mich doch, anstelle sich über mich lustig zu machen.

VG

Deine Sensorik scheint etwas ausser Gleichgewicht geraten zu sein.

Es ist DEIN Problem, was ich versucht habe logisch zu lösen.
Ich habe mich über Deinen Code gesetzt und hatte Fragen dazu.

Dann werd allein fertig damit.

Hallo,
glaube ich nicht.
ich versuche mal Dir auf die Sprünge zu helfen.
Das Messprinzip besteht doch daraus das man mit einem bekannten Widerstand und dem zu messenden unbekannten Widerstand einen Spannungsteiler aufbaut. Die Spannung in der Mitte misst und daraus den unbekannten Widerstand berechnet.
Nun hast Du deine "bekannten Widerstände" alle mit dem Messpunkt verbunden und legst die Ausgänge Ch0 - Ch4 alle auf 5V bis auf einen der eigentlich die ausgewählter Kanal ist.

case 0:
      digitalWrite(CH0, LOW);
      digitalWrite(CH1, HIGH);
      digitalWrite(CH2, HIGH);
      digitalWrite(CH3, HIGH);
      digitalWrite(CH4, HIGH);
      break;

Damit liegen die Widerstände alle an plus , bis auf einen der liegt auf minus. Damit hast Du einen zusätzlichen Spannungsteiler , bestehend aus allen Deinen Referenzwiderständen. Und zum zweiten stimmen Deine "bekannten Widerstände " auch nicht mehr da ja einige von denen parallel jetzt liegen.

const uint32_t res_table[6] = {52.66, 149.4, 995.3, 9960, 150300, 999930};

Jetzt hast Du so ein seltsames Array verwendet , sollen das die Werte der parallel geschalteten Widerstände sein ? oder ist das Magie. Da wäre jetzt mal ein Kommentar sinnvoll gewesen.

Die Transistoren in der Ursprungsschaltung machen schon Sinn, sie trennen die Widerstände sehr hochohmig gegeneinander ab wenn die Transistoren bist auf einen gesperrt sind. Und damit ist dann nur ein Widerstand aktiv.

Du kannst das ja mal testen . Trenne alle Verbindungen von Ch0 bis Ch4 , bis auf eine am Arduino ab und verwende einen Widerstand der in den Messbereich passt.

Also bau die Schaltung so auf wie sie vorgesehen war , dann sollte das auch klappen.

Heinz

Vorsicht. Nicht kritisieren.
Und bitte schreibe dazu, dass Du keine Kopie von mir bist. :sweat_smile:

:man_facepalming: :brain: :light_bulb:

Das ist Arroganz und hat aber mit Kritik nichts zu tun, solche Kommentare kannst du auch einfach weg lassen. Falls du nicht verstehst, was daran arrogant sein sollte, dann solltest du mal an deiner Sensorik arbeiten, nur mal so nebenbei.

So und um zu deinem restlichen Beitrag und zum Thema zurück kommen, was meinst du mit "zähl mal durch"?

Meinst du damit, dass im Array 6 Zahlen drin stehen und der "ch_select" aber nur 5 beinhaltet?

Was ich meine interessiert nicht.
Einfache Frage - einfache Antwort.
Du kannst natürlich auch darüber diskutieren, was Du wie und wie nicht verstehst.
Mir ist meine Zeit dafür zu schade,

Ich hatte gestern abend bereits Deinen Code überarbeitet.
Z.B. so:

void ch_select(byte n)
{
  for (byte b = 0; b < channels; b++)
  {
    digitalWrite(CH[b], HIGH);
  }
  digitalWrite(CH[n], LOW);
  res = res_table[n];
}

@Rentner wird Dir zeigen, wie Du da hin kommst.
Mich interessieren Deine Probleme herzlich wenig.
Ich löse Aufgaben.

Hallo,
Nöö, ich denke ich habe zur Funktion alles gesagt , und wie die Hardware sein sollte.
Das man dann dafür per Software sorgt das nur ein Referenzwiderstand aktiv ist würde auch erwähnt.

Dann kann man weiter sehen

Heinz

Hallo Heinz,

const uint32_t res_table[6] = {52.66, 149.4, 995.3, 9960, 150300, 999930};

Wie schon gesagt, der Ursprungscode ist nicht von mir, ich kann teilweise auch nur raten.
Aber ja, ich denke dass sind die Werte der eingezeichneten Widerstände.

Also bau die Schaltung so auf wie sie vorgesehen war , dann sollte das auch klappen.

Hatte ich auch, ich wollte aber die Transisitoren raus nehmen, weil die natürlich in die Messungen mit reinspielen, außer bei dem niederohmigen Teil.

Der Punkt ist, bei dem LCR-Projekt funktioniert die Schaltung ja auch ohne die Transistoren, woran liegt da jetzt der Unterschied? Wenn man mal die Schalter außer acht läßt, die habe ich ja weder verbaut noch im Programm drin.

Ok, die Base liegt an 5V an und ist mit einem digitalen Pin verbunden...gut das kann ich noch ändern.
Ja ok, der Code ist natürlich auch anders, da muss ich nochmal schauen warum das bei ihm so funktioniert.

Du kannst das ja mal testen . Trenne alle Verbindungen von Ch0 bis Ch4 , bis auf eine am Arduino ab und verwende einen Widerstand der in den Messbereich passt.

Das werde ich mal probieren, danke für den Tipp.

VG Matthias

Ah, ok...d.h. ich muss in das lcr projekt schauen, was dort anders ist und warum es dort funktioniert.