Windmesser mit SevenSeg Library

Hallo,
folgenden Sketch habe ich aus dem Beispiel der SevenSeg-Library und einem Windmesser-Scetch zusammengestellt. Wenn ich die auskommentierte Funktion "meassure" aufnehme ist auf dem Seriellen Monitor alles in Ordnung aber die 3-Stellige Anzeige gibt nur wechselnd umlaufend auf jedem Digit gleiche einfache Balken aus. Kommentiere ich "meassure" aus, wird angezeigt, was ich bei "sevseg.setNumber" vorgebe. Würde es vielleicht etwas bringen, wenn ich statt Interruptpin 0 den Pin 1(3) verwende? Ist schon alles fest verdrahtet.

#include "SevSeg.h"
SevSeg sevseg; //Instantiate a seven segment controller object

const int RecordTime = 3; //Define Measuring Time (Seconds)
const int SensorPin = 2;  //Define Interrupt Pin (2 or 3 @ Arduino Uno)

int InterruptCounter;
float WindSpeed;
int WindSpeedGanzZahl;

void setup()
{
  byte numDigits = 3;
  byte digitPins[] = {13, 10, 3};
  byte segmentPins[] = {6, 5, 7, 8, 9, 4, 11, 12};
  bool resistorsOnSegments = false; // 'false' means resistors are on digit pins
  byte hardwareConfig = COMMON_ANODE; // See README.md for options
  bool updateWithDelays = false; // Default. Recommended
  bool leadingZeros = false; // Use 'true' if you'd like to keep the leading zeros
  sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros);
  sevseg.setBrightness(50);
  Serial.begin(9600);
}

void loop() {
 // meassure();
  Serial.print("Wind Speed: ");
  Serial.print(WindSpeedGanzZahl);  //Speed in km/h
  Serial.print(WindSpeed / 3.6); //Speed in m/s
  Serial.println(" m/s");
  //sevseg.setNumber(WindSpeedGanzZahl, 4);
  sevseg.setNumber(123, 4);
  sevseg.refreshDisplay(); // Must run repeatedly
}

void meassure() {
  InterruptCounter = 0;
  attachInterrupt(digitalPinToInterrupt(SensorPin), countup, RISING);
  delay(1000 * RecordTime);
  detachInterrupt(digitalPinToInterrupt(SensorPin));
  WindSpeed = (float)InterruptCounter / (float)RecordTime * 2.4;
  WindSpeedGanzZahl=(int)WindSpeed;
}

void countup() {
  InterruptCounter++;
}

Mit freundlichen Grüßen
Gerald

Irgendwie wirfst Du die Pins durcheinander. Du bist mit dem Sensor auf Pin 2, nicht auf 0.
Irgendwie fehlt mir die Stelle, an der Du den InterruptCounter wieder auf 0 setzt.
Erwartest Du negative Zählerstände, weil Du int nutzt?

Gruß Tommy

Bei 7 Segment Anzeigen darf man kein delay() benutzen, die Ansteuerung geschieht so schnell, dass es für das menschliche Auge aussieht, als würden alle drei Ziffern gleichzeitig angezeigt werde

Pin 2 ist meines Wissens nach InterruptPin 0, oder nicht?
Die Messung funktiniert ja laut seriellem Monitor.
int habe ich eingefügt, da ich dachte, dass die Anzeige möglicherweise nur mit ganzzahligen Werten klar kommt. Der Counter wird gleich a Anfang der "meassure" Funktion auf 0 gesetzt.
Würde es denn was bringen, das Delay durch millis zu ersetzen?

Nein, das ist Interrupt 0 (ohne Pin ran zu hängen).

int hat negative und positive Zahlen. Besser unsigned int verwenden.
Ok, die Stelle habe ich überlesen.

Es millis() anstelle von delay() würde nicht nur etwas bringen, es ist die Voraussetzung für die Anzeige.

Gruß Tommy

So, hab alles mal umgestrickt.
Millis eingeführt. Seriellen Monitor entfernt (schien zu stören).
Jetzt bekomme ich eine Anzeige der, in 3 Sekunden gezählten Impulse, was schon zahlenmäßig in der Nähe der Windgeschwindigkeit in km/h ist.

#include "SevSeg.h"
SevSeg sevseg; //Instantiate a seven segment controller object

const int RecordTime = 3; //Define Measuring Time (Seconds)
const int SensorPin = 2;  //Define Interrupt Pin (2 or 3 @ Arduino Uno)

int InterruptCounter;
unsigned int WindSpeed;
long unsigned int Intervall=3000;
long unsigned int Start;

void setup()
{
  byte numDigits = 3;
  byte digitPins[] = {13, 10, 3};
  byte segmentPins[] = {6, 5, 7, 8, 9, 4, 11, 12};
  bool resistorsOnSegments = false; // 'false' means resistors are on digit pins
  byte hardwareConfig = COMMON_ANODE; // See README.md for options
  bool updateWithDelays = false; // Default. Recommended
  bool leadingZeros = true; // Use 'true' if you'd like to keep the leading zeros
  sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros);
  sevseg.setBrightness(50);
  Start=millis();
  Serial.begin(9600);
  InterruptCounter = 0;
}

void loop()
{
  attachInterrupt(digitalPinToInterrupt(SensorPin), countup, RISING);
  if(millis()-Start>=Intervall)
  {
    detachInterrupt(digitalPinToInterrupt(SensorPin));
    WindSpeed = InterruptCounter;
    sevseg.setNumber(WindSpeed, 4);
    InterruptCounter = 0;
    Start=millis();
  }
  sevseg.refreshDisplay();
}

void countup() {
  InterruptCounter++;
}

Danke für die Hilfe

Eigenartig, so einen sevenSeg-Codeansatz habe ich doch heute schon mal gesehen....

Mal als Verbesserungsvorschlag:
edit: siehe weiter unten in #9 und #10

#include "SevSeg.h"
SevSeg sevseg; //Instantiate a seven segment controller object

const int RecordTime = 3; //Define Measuring Time (Seconds)
const int SensorPin = 2;  //Define Interrupt Pin (2 or 3 @ Arduino Uno)

volatile unsigned int InterruptCounter;
unsigned int WindSpeed;
long unsigned int Intervall = 3000;
long unsigned int Start;

void setup()
{
  byte numDigits = 3;
  byte digitPins[] = {13, 10, 3};
  byte segmentPins[] = {6, 5, 7, 8, 9, 4, 11, 12};
  bool resistorsOnSegments = false; // 'false' means resistors are on digit pins
  byte hardwareConfig = COMMON_ANODE; // See README.md for options
  bool updateWithDelays = false; // Default. Recommended
  bool leadingZeros = true; // Use 'true' if you'd like to keep the leading zeros
  sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros);
  sevseg.setBrightness(50);
  Start = millis();
  Serial.begin(9600);
  InterruptCounter = 0;
  attachInterrupt(digitalPinToInterrupt(SensorPin), countup, RISING);
  Start = millis();
}

void loop()
{
  if (millis() - Start >= Intervall)
  {
    detachInterrupt(digitalPinToInterrupt(SensorPin));
    WindSpeed = InterruptCounter;
    InterruptCounter = 0;
    attachInterrupt(digitalPinToInterrupt(SensorPin), countup, RISING);
    sevseg.setNumber(WindSpeed, 4);
    Start = millis();
  }
  sevseg.refreshDisplay();
}

void countup()
{
  InterruptCounter++;
}

Warum machst Du in jedem Loop-Durchlauf attach? Das würde doch genügen, wenn Du das am Ende der Auswertung machst.

Gruß Tommy

Edit:
@my_xy_projekt war schneller

Aber auch nur weil ich sonst nix dran geändert habe...
Ich überleg nur grad, ob der InterruptCounter nicht volatile gehört...

Ja, habe ich auch übersehen.

Gruß Tommy

Außerdem ist int der falsche Datentyp. Und je nach dem, ob der Bereich 0 .. 255 oder grösser (0 ..65535) erforderlich ist, muss man auch das auslesen "atomic" machen, wenn man das dauernde detachInterrupt weglassen will.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.