Analogwert Ausgabe mit 7-Segment Anzeige

Hallo Forum,

ich bin neu auf dem Bereich der Arduino und habe mir ein UNO zugelegt.
Bisher habe ich für den Einstieg Erik Barthmann´s Buch (die Welt mit Arduino.....) und "Arduino für Einsteiger" gelesen, wobei ich letzteres eher als "Quer lesen" sehe.
Aus Barthmann´s Buch habe ich versucht einen Sketch für meine Bedürfnisse umzuschreiben aber irgendwie ist da der Bock drin.
Da ich gerade erst anfange hoffe ich Ihr verzeiht Fehler im Sketch.
Die Aufgabe soll sein den Inhalt eines Wassertanks später in Liter anzuzeigen. Im Moment ist als Tankgeber ein Poti eingesetzt. Später kommt ein Tankgeber zu Einsatz, deren
Werte ich dann hoffentlich mittels maps() anpassen kann.
Der ursprüngliche Sketch sollte einfach die Zahl "43" anzeigen, weshalb in der ersten Zeile in der loop einfach { anzeige(43) } stand.
Hier wollte ich jetzt einfügen, das er den Wert des analogen Pins (0) lesen soll und ihn mittels map umsetzen soll, so dass der Ausgabewert zwischen 0 und 40 liegt.
Leider reagieren die beiden 7-Segment Anzeigen auf das Poti, zeigen aber nur Schrott an.

 byte segmente[10]={
                   B01111110,//0
                   B00110000,//1
                   B01101101,//2
                   B01111001,//3
                   B00110011,//4
                   B01011011,//5
                   B01011111,//6
                   B01110000,//7
                   B01111111,//8
                   B01111011};//9
                   
byte pinArray[] = {2,3,4,5,6,7,8};
byte einerStelle = 12, zehnerStelle = 13;
int analogPin = 0;
int analogWert = 0;

void setup (){
  for(int i=0; i<7; i++)
  pinMode(pinArray[i], OUTPUT);
  pinMode(einerStelle, OUTPUT);
  pinMode(zehnerStelle, OUTPUT);
}

void loop(){
analogWert = analogRead(analogPin);
ansteuerung(analogWert);
int ansteuerung = map(analogWert, 543, 1023, 0, 40);

}  

void anzeige(int analogWert){
  byte einer, zehner;
  zehner = int(analogWert / 10);
  einer = analogWert - zehner * 10;
  digitalWrite(einerStelle, LOW);
  digitalWrite(zehnerStelle, HIGH);
  ansteuerung(einer);
  digitalWrite(einerStelle, HIGH);
  digitalWrite(zehnerStelle, LOW);
  ansteuerung(zehner);
}

void ansteuerung(int a){

  for(int j = 6; j >= 0; j--)
  digitalWrite(pinArray[6 -j], bitRead(segmente[a], j) ==1?LOW:HIGH);
  delay(1000);
}

Ich vermute es liegt an der Beschaltung.
Grüße Uwe

Solange statt " analogWert = analogRead(analogPin);
ansteuerung(analogWert);
int ansteuerung = map(analogWert, 543, 1023, 0, 40);
einfach nur
anzeige(43) da steht läuft es. ( also es wird 43 auf den 7-Segment Anzeigen angezeigt).

Ich empfehle hier einfaches Debugging mit
Serial.println(analogWert)
und für andere Variablen, deren Werte dich interessieren
Am Anfang Serial.begin(9600); einfügen und den Serial Monitor starten
Dann kannst du das Problem einkreisen und schließlich, wenn du es gefunden hast, beheben.

Der wert lässt sich mit dem Monitor auslesen und geht exakt von 0 - 1020.

in deinem Code wird die Funktion anzeige nie aufgerufen. Diese kann also gelöscht werden. int ansteuerung = map(analogWert, 543, 1023, 0, 40); habe ich auch entfernt, da es nicht verwendet wird. So wird der Code übersichtlicher.

byte segmente[10]={
                   B01111110,//0
                   B00110000,//1
                   B01101101,//2
                   B01111001,//3
                   B00110011,//4
                   B01011011,//5
                   B01011111,//6
                   B01110000,//7
                   B01111111,//8
                   B01111011};//9
                   
byte pinArray[] = {2,3,4,5,6,7,8};
byte einerStelle = 12, zehnerStelle = 13;
int analogPin = 0;
int analogWert = 0;

void setup (){
  for(int i=0; i<7; i++)
  pinMode(pinArray[i], OUTPUT);
  pinMode(einerStelle, OUTPUT);
  pinMode(zehnerStelle, OUTPUT);
}

void loop(){
  analogWert = analogRead(analogPin);
  ansteuerung(analogWert);
}  

void ansteuerung(int a){

  for(int j = 6; j >= 0; j--)
  digitalWrite(pinArray[6 -j], bitRead(segmente[a], j) ==1?LOW:HIGH);
  delay(1000);
}

Der Funktion ansteuerung übergibst du den analogWert. In der Funktion ansteuerung verwendest du diesen Wert als index für das Byte Array segmente, das aus 10 Elementen besteht. AnalogWert kann aber bis zu 1023 betragen, du greifst so auf nicht definierten Speicher zu, darum auch nur der Schrott an der Ausgabe.

Berti:
Der wert lässt sich mit dem Monitor auslesen und geht exakt von 0 - 1020.

Nicht von 0 bis 1023?
Grüße Uwe

in deinem Code wird die Funktion anzeige nie aufgerufen. Diese kann also gelöscht werden

Das ist zwar richtig, führt aber wohl nicht zum Ziel, zumal wenn als Endergebnis nur rauskommt, dass es erklärbar ist, warum nur Schrott rauskommt. :wink:

Wenn
anzeige(43);
richtig geht, würde ich diese Funktion doch komplett testen

void loop() {
 for (int i = 0; i < 100; i++)
 {
   anzeige (i);
   delay (500);
 }
}

und sie dann auch verwenden. ( Dass sie bei Zahlen ausserhalb 0 .. 99 Unsinn produziert, ist dir ja klar, oder )
Eventuell mit passernderer Definition: void anzeige (byte wert);
...und Luxus-Fehlerbehadlung: Eine 7-Segment Anzeige kann auch ein 'E' anzeigen

Serial.println() als Testausgaben sind auch immer hilfreich ...

Mit dem Löschen des nicht verwendeten Code wollte/will ich Berti zum nachdenken anregen und nicht gleich den ( möglicherweise ) richtigen Weg präsentieren :wink:

Aber wenn er in seinem Code loop so abändert, müsste es funktionieren

void loop(){
analogWert = analogRead(analogPin);
anzeige(map(analogWert, 543, 1023, 0, 40));
}

Wobei mich der Startwert 543 etwas irritiert.

Also vielen Dank erst einmal, dass ihr euch meines Problems angenommen habt.
Der Sketch entstand so durch das zusammensetzen von Sketchen, die ich in Eriks Buch gelesen habe.
Ob die die Struktur je verstehen werde ist mir bis jetzt noch nicht klar. Gerade die (i=0, I<7........) begreif ich überhaupt nicht.
Die map Funktion ist gut nachvollziehbar.
Das löschen des "nicht brauchbaren" hat mich nur noch mehr aus der Ruhe gebracht :astonished:

Nachdem ich jetzt die loop erneuert hatte lief es erst immer noch nicht. Die zehnerStelle war OK aber die einer zuckten noch wie
wild herum. Erst nachdem ich die Begriffe wert in analogWert geändert hatte wars in Ordnung.
Also vielen Dank noch einmal für die Hilfe.

Wenn ich das richtig verstehe funktioniert dieser Sketch nur bei linearen Sachen. Was aber wenn ich nicht....sagen wir mal pro
Liter immer genau gleich viel Änderung hätte ( am analogen Eingang ).
Dann müsste ich doch schauen ( mittels Monitor ) was bei welchem Wasserstand gelesen wird und dann genau sagen was er bei
welchem Wert ( 0 - 1023 ) anzeigen soll.
(z.B 223 = 12, 256 =13)

Hallo
ich arbeite mit dem gleichen buch und bin gerade bei dem gleichen Thema :slight_smile:
(bedeutet also das ich auch Absoluter Anfänger bin)

Vielleicht hätte man dabei schreiben müssen das die Anzeige Multiplexen soll.

Also wenn ich das nun richtig verstanden habe ist die Funktion Anzeige für das Multipelxen verantwordlich.
Kann also nicht einfach gelöscht werden.
Ok du hattest sie auser Kraft gesetzt mit der Änderung ---> ansteuerung(analogWert);
Für mein verständniss hätte das anzeige(analogWert); sein müssen.

Wie gesagt ich bin auch Anfänger und bekomme das auch noch nicht so hin wie ich möchte,

Meine "Bombe" die ich mal bauen werde wird keinen schönen count down haben.
Momentan zeigt er mir die zweite ziffer immer nur sehr kurz an.

Grüße
Benedikt der auch noch mit struckturen kämpft.

Tüftel mal mit den delay Werten rum.

@all. Bringt es was ( als Einsteiger ) wenn man sich noch das Kochbuch holt ?

Ich versteh es halt auch noch nicht richtig.

Ich hatte das letzte delay auch auf 0
Im Buch stand es sollte was passieren aber bei mir Kamm die 43

Ob die die Struktur je verstehen werde ist mir bis jetzt noch nicht klar. Gerade die (i=0, I<7........) begreif ich überhaupt nicht.

meinst du die Zeile

  for(int i=0; i<7; i++)

in void setup() { ... } ?

Versuch mal den Befehl Strg-T ( Tools - AutoFormat )
dann siehst du, dass man in C auch mal { } Klammern weglassen kann, wenn sie nur einen Befehl umklammern würden.
Was eine for - Schleife ist, weisst du schon, und dass grosses I und kleines i zwei verschiedene Zeichen sind , auch (oder ?)
Welches jetzt die Beste Einführung in C ist, weiss ich leider nicht.

Sachen kopieren und sehen dass es funktioniert ist super, zu verstehen was da abläuft ist aber noch viel superer :wink:

Bei unlineraren Werten am Analog Eingang kannst du interprolieren mit der Map funktion. Also für verschiedene Analog bereiche verschiendene Augaben.
Pseudo code

y = map(Wert1,100,400, 10,14);
y = map(Wert1,401,800, 15,17);
y = map(Wert1,801,1020, 18, 20);

So hast du eine nicht ganz lineare Gerade sonden nur zwischen den jeweils zwei Punkten die du angegeben in dem jeweiligen map angegeben hast.

Gruß
Der Dani

Damit aus dem

Pseudo code

richtiger Code wird, brauchst du noch ein paar if, da z.B. die dritte Zeile das y auch verändert, wenn Wert1 ausserhalb des Bereichs 801 .. 1020 ist.