Go Down

Topic: Analogwert Ausgabe mit 7-Segment Anzeige (Read 2719 times) previous topic - next topic

Berti

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.

Code: [Select]
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);
}



uwefed

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

Berti

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).

karlok

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.
using Arduino Uno Rev 3

Berti

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

thewknd

#5
Nov 05, 2012, 07:39 am Last Edit: Nov 05, 2012, 07:41 am by thewknd Reason: 1
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.

Code: [Select]
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.
duemilanove / OSX & WIN
Arduino & Teensy: http://bit.ly/13rbdtQ

uwefed


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

Nicht von 0 bis 1023?
Grüße Uwe

michael_x

Quote
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. ;)

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

Code: [Select]
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 ...

thewknd

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 ;)

Aber wenn er in seinem Code loop so abändert, müsste es funktionieren
Code: [Select]
void loop(){
analogWert = analogRead(analogPin);
anzeige(map(analogWert, 543, 1023, 0, 40));
}


Wobei mich der Startwert 543 etwas irritiert.
duemilanove / OSX & WIN
Arduino & Teensy: http://bit.ly/13rbdtQ

Berti

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   :smiley-eek:

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)

Moeoeoep

Hallo
ich arbeite mit dem gleichen buch und bin gerade bei dem gleichen Thema :)
(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.

Berti

#11
Nov 05, 2012, 09:30 pm Last Edit: Nov 05, 2012, 09:32 pm by Berti Reason: 1
Tüftel mal mit den delay Werten rum.

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

Moeoeoep

#12
Nov 05, 2012, 09:45 pm Last Edit: Nov 05, 2012, 09:49 pm by Moeoeoep Reason: 1
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

michael_x

Quote
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 ;)

volvodani

#14
Nov 06, 2012, 03:03 pm Last Edit: Nov 06, 2012, 03:12 pm by volvodani Reason: 1
Bei unlineraren Werten am Analog Eingang kannst du interprolieren mit der Map funktion. Also für verschiedene Analog bereiche verschiendene Augaben.
Pseudo code

Code: [Select]

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
So ist das Leben:
Manchmal bis du das Denkmal, manchmal die Taube!

Go Up