PWM abfragen Digital schalten

Hallo zusammen,

bin noch nicht lange mit dem Arduino UNO unterwegs, und habe jetzt ein Problem bei dem ich nicht weiterkomme.

Ich möchte gern einen PWM-PIN abfragen (Pin 2). Wenn dieser Null ist soll der Digitalpin 10 eingeschaltet werden und umgekehrt. Ich hoffe ich habe mich soweit verständlich ausgedrückt.

Vielen Dank für die Hilfe im voraus

Gruß Bernd

Über Software geht das nicht?

analogwrite(2,PWMwert);
if (PWMwert==0)
{
digitalwrite(10, HIGH)
}
else
{
digitalwrite(10, LOW)
}

Grüße Uwe

Komiche Frage Uwe... wie sollte mab es sonst lösen?

Wäre nicht analogRead(PWMwert besser ? :-))

Es ist immer wieder merkwürdig, wie Anfragen formuliert werden können, dass jeder was anderes darunter versteht. ;) Alkso ich habe das so verstanden: An Pin2 (Digitalpin) liegt ein Signal an, in diesem Fall eine PWM von einer externen Schaltung. Die ist gekennzeichnet durch ein bestimmtes Puls-Pause-Verhältnis, immer im Pausenbereich (also LOW) soll Pin 10 HIGH werden, also eigentlich nur eine Invertierung des Signals.

Und da sind wir schon beim nächsten Punkt: Wofür soll das denn sein? Vielleicht gibt es ja bessere Alternativen als die Ver(sch)wendung eines Mikrocontrollers bzw. von dessen Pins.

sth77, Deine Version hat was für sich da Pin 2 ja gar kein PWM -fähiges Pin ist. Dann würd ich es aber über pulsIn() lösen. KRISTALLKUGEL wo bist du? Grüße Uwe

Hallo zusammen,

entschuldigung, das meine Frage so verschieden interpretiert werden kann.

Als Vorbild habe ich den Sketch aus diesem Topic: http://arduino.cc/forum/index.php/topic,95007.0.html

Den Sketch habe ich soweit auf meine Bedürfnisse zugeschnitten.

Mein PWM pin ist als blue1pin deklariert. Es geht um eine Lichtsteuerung. Der Pin wird soll tagsüber eine LED ansteuern. Ich möchte gerne den Pin (2) so abfragen, das wenn er ausserhalb der Zeit auf null ist, ein Digitaler Pin (10) eingeschaltet wird. Mit dem Aktiv werden von Pin 2 soll Pin 10 wieder ausgeschaltet werden.

Ich hoffe das es jetzt etwas klarer ist.

Gruss Bernd

maverick1509: Wäre nicht analogRead(PWMwert besser ? :-))

Das geht aus 2 Gründen nicht. analogRead() liesst Daten von den analogen Pins und liefert einen Wert zwischen 0 und 1023, je nach anliegender Spannung (im Vergleich zu Referenzspannung). Mit analogRead() kann man nicht den aktuell auf einem PWM-Pin gesetzten Wert für PWM auslesen. Selbst wenn das ginge, hast Du ja trotzdem nur einen "gemittelten" Wert einer Spannung, der sich aus dem PWM-Verhältnis ergibt, aber nicht das PWM-Signal selbst.

Okay, ganz verstanden hab ich es noch nicht, leichter wäre es, wenn du deinen Code hier einstellen würdest. Also geht es im konkreten Fall nicht um die Invertierung eines Signals, sondern um nur um eine einfache if-then-Anweisung abhängig vom PWM-Wert?

If (PWMwert==0) digitalWrite(10, HIGH);

Reicht das nicht aus, ggf. noch durch ein else ergänzt?

[edit] Okay, das läuft auf den Codeschnipsel von Uwe hinaus, nur eben ohne die analogWrite-Anweisung...

Bernd_S:
Mein PWM pin ist als blue1pin deklariert. Es geht um eine Lichtsteuerung. Der Pin wird soll tagsüber eine LED ansteuern.
Ich möchte gerne den Pin (2) so abfragen, das wenn er ausserhalb der Zeit auf null ist, ein Digitaler Pin (10) eingeschaltet wird.
Mit dem Aktiv werden von Pin 2 soll Pin 10 wieder ausgeschaltet werden.

Ich hoffe das es jetzt etwas klarer ist.

So ganz verstehe ich das noch nicht. Wird der “PWM-Pin” von “Außen” geschaltet, oder ist das nur ein Wert innerhalb des Programms, der auf Pin 2 als PWM ausgegeben wird (was aber nicht geht, das Pin 2 kein PWM Pin ist) und Du willst nur für den Fall das der Wert innerhalb des Programms auf “0” steht den Pin 10 auf HIGH schalten?

Wenn der Pin von außen ein PWM-Signal bekommt, dann hast Du vermutlich das Problem, das der Eingang ja zwischen HIGH und LOW hin und her schaltet. Jenachdem wann Du gerade den Pin abfragst, kann es passieren, das der halt gerade LOW ist, obwohl er ein PWM-Signal von außen bekommt. Dann solltest Du über pulseIn() auf einen HIGH-Puls warten und einen timeout-Wert angeben. Wenn der Timeout greift, kannst Du sicher sein, das kein PWM-Signal anliegt, sondern der Pin tatsächlich auf LOW steht.

Hallo,

Der PWM-Pin (2) dient zur Ausgabe und Steuerung einer LED. Diese soll den Sonnenaufgang, die Sonne und den Untergang simulieren. Der digitale Pin (10) soll ausserhalb dieser Zeit eine LED als Mond einschalten.

Meinen Sketch kann ich leider im Moment nicht zur Verfügung stellen, da ich arbeiten muss

Der angefügte Sketch funktioniert zwar, so ganz verstanden habe ich ihn aber auch noch nicht, und mein Wissen in Bezug auf Arduino programmieren steckt noch in den Anfängen. Ich kann mir zwar aus meinen Basic-Anfängen (vor 30 Jahren) innerhalb des Programms das ein oder andere zusammen reimen, aber das war es schon.

Ich hoffe ihr könnt mir weiter helfen

Gruss Bernd

Naja, Uwe hat doch schlicht in "Arduinisch" genau das geschrieben was Du beschrieben hast.

Wenn Sonne aus dann Mond an sonst Mond aus.

Und in Basic sieht das doch fast gleich aus.

Ihr überseht fast alle, daß Pin 2 kein PWM Ausgang ist. Pin 10 ist PWM fähig. Also Sonne und Mond umtauschen :wink: .
Ciao Uwe

uwefed: ...Also Sonne und Mond umtauschen ;) .

Kannst doch nicht so einfach machen, wenn da jeder macht kommt ja das ganze Raumzeitgefüge durcheinander :-D

Eine ungedimmte Sonne aber auch nicht 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) ;) Grüße Uwe

Blöde Frage, aber wäre es nicht besser Sonne UND Mond zu dimmen? Beide leuchten und gehen auf und unter. Die Sonne ist halt etwas heller. Also statt Pin 2 und 10 vielleicht einfach Pin 5 und 6 verwenden, die können beide PWM und liegen auch noch schön nebeneinander. Mario.

Hallo zusammen

@Mario, der Mond dient nicht zur Ausleuchtung, sondern nur als Notlicht, (besteht nur aus zwei bis drei normalen LED) Die Sonne hingegen aus 2x10W LED. Ich glaube da muß der Mond nicht gedimmt werden.

@Uwe, habe deinen Vorschlag aus dem zweiten Post mal in meinen Sketch integriert. Warte zur Zeit auf Ergebnisse, da das ganze über RTC läuft, und ich leider nicht weiss wie ich einen Zeitraffer einbauen könnte. Und du hast Recht, Pin 2 ist kein PWM, Habe ich auch direkt geändert Danke

Werde berichten oder nachfragen je nach Ergebnis.

Gruß Bernhard

Hallo Uwe,

anei mal mein ganzer Code.
kannst du mir sagen was ich bei der analogwrite in der Zeile 85 und in der If in 86 anstatt der Fragezeichen einsetzen muß?

Da mir das ganze noch zu frisch ist komme ich nicht weiter.

#include <Wire.h>

#include <Button.h>
#include <DS1307.h>
#include <LiquidCrystal.h>
#define DS1307_ADDRESS 0x68 // This is the I2C address

// SainSmart LCD 16x2
LiquidCrystal lcd(8, 13, 9, 4, 5, 6);

// Arduino Mega 2560
const int Blue1Pin = 10;
const int White2Pin = 3;
//const int White3Pin = 7;
//const int White4Pin = 12;
const int Night1Pin = 2;
const unsigned long HOUR = 60 * 60;
const unsigned long MINUTE = 60;
const int TARGET_BRIGHTNESS = (255 * 3) / 4; // Target brightness is 3/4 of full

void setup()
{
Serial.begin(9600);
lcd.begin(16, 2);
Wire.begin();
}

byte bcdToDec(byte val) {
// Convert binary coded decimal to normal decimal numbers
return ( (val/16*10) + (val%16) );
}

void loop()
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("***");
lcd.setCursor(4,0);

///// Get time from RTC into RTCHour, RTCMinute, RTCSecond

// Set the register pointer to 0 (Second)
Wire.beginTransmission(DS1307_ADDRESS);
Wire.send((byte)0);
Wire.endTransmission();

// Read Second, Minute, and Hour
Wire.requestFrom(DS1307_ADDRESS, 3);

int RTCSecond = bcdToDec(Wire.receive());
int RTCMinute = bcdToDec(Wire.receive());
int RTCHour = bcdToDec(Wire.receive() & 0b111111); //24 hour time

// write Time to LCD XX:XX:XX
if(RTCHour < 10) {
lcd.print(“0”);
}
lcd.print(RTCHour);
Serial.println(" “);
Serial.print(RTCHour);
lcd.print(”:");
Serial.print(":");
if(RTCMinute < 10) {
lcd.print(“0”);
}
lcd.print(RTCMinute);
lcd.print(":");
Serial.print(RTCMinute);
Serial.print(":");
if(RTCSecond < 10) {
lcd.print(“0”);
}
lcd.print(RTCSecond);
Serial.print(RTCSecond);
lcd.setCursor(13,0);
lcd.print("***");

unsigned long time = RTCHour * HOUR + RTCMinute * MINUTE + RTCSecond; // Time in seconds

// write value within the timeframe to PWM
analogWrite(Blue1Pin, brightness(time, 7HOUR+00MINUTE, 21HOUR+00MINUTE));
analogWrite(White2Pin, brightness(time, 8HOUR+30MINUTE, 19HOUR+30MINUTE));

// write actual value in % to LCD (max. 255 = 100%)
analogWrite(10,??);
if (??==0)
{
digitalWrite(2, HIGH);
}
else
{
digitalWrite(2, LOW);
}
//Blue1Pin
lcd.setCursor(0,1);
lcd.print(“Blue “);
if(((brightness(time, 7HOUR+00MINUTE, 21HOUR+00MINUTE))100/255) < 10) {
lcd.print(“0”);
}
lcd.print((brightness(time, 7
HOUR+00MINUTE, 21HOUR+00*MINUTE))*100/255);
lcd.print(”%”);

//White2Pin

lcd.setCursor(9,1);
lcd.print(“Sun “);
if(((brightness(time, 8HOUR+30MINUTE, 19HOUR+30MINUTE))100/255) < 10) {
lcd.print(“0”);
}
lcd.print((brightness(time, 8
HOUR+30MINUTE, 19HOUR+30*MINUTE))*100/255);
lcd.print(”%”);
delay(1000);
}

byte brightness(unsigned long time, unsigned long fadeUpStart, unsigned long fadeDownStart)
{
// Mid day, light is at maximum brightness
if (time >= fadeUpStart + HOUR && time <= fadeDownStart)
return TARGET_BRIGHTNESS;

// Dawn: fade up the light
if (time >= fadeUpStart && time <= fadeUpStart + HOUR) // Fading up
{
unsigned long seconds = time - fadeUpStart; // Number of seconds into the fade time
return TARGET_BRIGHTNESS * seconds / (HOUR); // Fade up based on portion of interval completed.
}

// Evening: Fade down the light
if (time >= fadeDownStart && time <= fadeDownStart + HOUR) // Fading down
{
unsigned long seconds = (fadeDownStart + (HOUR)) - time; // Number of seconds remaining in the fade time
return TARGET_BRIGHTNESS * seconds / (HOUR); // Fade down based on portion of interval left.
}

// The remaining times are night and the lights is off
return 0; // Shouldn’t get here
}

Hat eventuell jemand noch ein Codeschnipsel, damit ich mit zwei Tasten die Uhrzeit manuell verstellen kann??

Danke und Gruss

Bernd

muß ich jetzt die Zeilen Zählen? Ok in eine Editor kopiert und schon sind die Zeilennummern da.

Hast Du jetzt einen Arduino UNO oder einen Arduino Mega 2560?

analogWrite(Blue1Pin,   brightness(time, 7*HOUR+00*MINUTE,                 21*HOUR+00*MINUTE));
analogWrite(White2Pin,  brightness(time, 8*HOUR+30*MINUTE,                 19*HOUR+30*MINUTE));

Was willst Du mit dem bezwecken?

Erklärst Du mir bitte wie Du Dir die Tageslichtgeschtaltung vorschwebt.

Grüße Uwe

@Uwe: Da steht aber noch eine Funktion drin:

// write value within the timeframe to PWM
  analogWrite(Blue1Pin,   brightness(time, 7*HOUR+00*MINUTE,                 21*HOUR+00*MINUTE));
  analogWrite(White2Pin,  brightness(time, 8*HOUR+30*MINUTE,                 19*HOUR+30*MINUTE));

Die Funktion "brightness()" rechnet vermutlich die Helligkeit aus, die für das Auf- und Untergehen, abhängig von der Zeit, gesetzt werden soll. 00*MINUTE ist aber immer 0, daher würde ich das weglassen.

@All: Viel spannender finde ich folgendes Konstrukt:

// write actual value in % to LCD (max. 255 = 100%)
analogWrite(10,??);
if (??==0)
{
digitalWrite(2, HIGH);
}
else
{
digitalWrite(2, LOW);
}

Was bitte ist "??" ? Falls das eine Variable sein soll, wird das kaum funktionieren. Es wundert mich schon, das der Compiler hier nicht meckert. Dazu kommt, das für diese Variable der Wert nie gesetzt wird, da wird der wohl immer "0" sein. das analogWrite(10,??) schreibt dann den "vermutlichen" Wert 0 auf der Pin 10. Das ist aber Dein Blue1Pin, das Du 3 Zeilen darüber gerade gesetzt hast. Am Ende wird dann also immer 0 auf das Blue1Pin geschrieben, also "Sonne aus" und weil Sonne aus, dürfte dann der Mond immer an sein, weil Du dann immer das "digitalWrite(2, HIGH);".

Wenn Du schon Variable definierst, um Pins zu identifizieren, dann verwende die auch konsequent im Code, sonst bekommst Du irgendwann Probleme. Versuch mal die Helligkeit in Variablen zu speichern und die dann zu verwenden, z.B.:

int sonneHelligeit= brightness(time, 7*HOUR+00*MINUTE,21*HOUR+00*MINUTE);
...
if(sonneHelligkeit==0) {
    digitalWrite(mondPIN,HIGH);
} else {
    digitalWrite(mondPIN,LOW);
}
...

Damit wird Dein Code auch deutlich lesbarer, weil klar ist auf welche Werte sich einzelne Codeabschnitte beziehen. Mario.