ATtiny als Digitalpotentiometer?

Moin,

ich möchte einen ATtiny45 dazu verwenden einen anderen ATtiny84 zu steuern, über PWM 0-255. Der 45’er funktioniert dabei wie ein Digipot. Das Programm sieht im Prinzip so aus:

45:

analogWrite(1, 10);
...
analogWrite(1, 100);
...
analogWrite(1, 225);

84:

if ((analogRead(5)/4) >= 0 && <=90 ){...}
...
if ((analogRead(5)/4) >= 95 && <=200){...}
...
if ((analogRead(5)/4) >= 200 && <=255){...}

Mein Problem ist nur, dass bei dem 84’er keine korrekten Werte ankommen, sondern entweder 0 oder 1023, habe separat nochmal über serial nachgesehen. Die Verbindung von Pin1 des 45’er zum Pin5 des 84’er erfolgt direkt auf kurzem Weg. Muss ich, wie bei einem Schalter, noch irgendwo einen Widerstand nach GND oder VCC setzen (Pull-Down)? Gibt es sonst eine andere Möglichkeit die Attinys untereinander kommunizieren zu lassen?

Gruß
Dennis

Wenn ich das richtig verstanden habe möchtest du das PWM-Signal des 45'er am A/D-Wandler des 84'er einlesen. Das funktioniert aber nicht mit PWM, weil dann am A/D-Eingang des 84'er entweder 0V oder 5V anliegen. Korrekter weise liefert dein analogRead auch nur 0 oder 1023 zurück. Um das Signal so einzulesen, müsstest du die PWM entsprechend glätten (mit Widerstand und Kondensator). Besser wäre es sicher mit dem 84'er einfach die Zahl der Flanken der PWM pro Zeiteinheit zu bestimmen und so ihn zu steuern. Oder einfach die Werte über serielle Kommunikation übertragen.

Ich dachte mir das so, dass man ein Signal eines PWM-Pins auch an einem anderen PWM-Pin einlesen kann. Entsprechend habe ich die Pins der beiden Attinys ausgewählt. Was genau muss ich machen um das Signal zu glätten? Ich habe mich auch gefragt warum ein PWM-Pin wie ein normaler Pin HIGH/LOW anzeigt, trotz dass er Zwischenwerte über PWM bekommt.

Gruß Dennis

Das PWM Signal (Puls-Weiten-Modulation) ist ein Rechtecksignal mit konstanter Frequenz aber mit variablem Puls-Pausen Verhältnis. Der resultierende Mittelwert ist vom Puls-Pausen Verhältnis abhängig. Es ist kein Analogsignal sondern ein Digitalsignal!! Beispiel: Wenn Du die Microwelle 1 Minute einschaltest und dann 1 Minute ausschaltest ist Dein Kaffee halbso warm als wenn Du die Mikrowelle 2 Minuten eingeschaltet hast.

Du kannst ein PWM Signal einlesen aber nicht mit analogRead() sondern mit pulseIn()

Grüße Uwe

uwefed: Du kannst ein PWM Signal einlesen aber nicht mit analogRead() sondern mit pulseIn()

Hey Uwe, vielen Dank für die Aufklärung! Das Signal sende ich dann aber mit digitalWrite(pin, value)?

Um es mal auf mein Beispiel anzuwenden, sieht der Code im Prinzip so aus:

[u]45:[/u]

digitalWrite(1,HIGH);
delay(10);
digitalWrite(1,LOW);
...
digitalWrite(1,HIGH);
delay(20);
digitalWrite(1,LOW);
...

[u]84:[/u]

...
duration = pulseIn(pin, HIGH);
...
if (duration == 10){...}
...
if (duration == 20){...}
...

Korrekt?

Gruß Dennis

...

if (duration == 20){…}




Korrekt?

Fast. Was passiert, wenn du evtl. 19 oder 21 als duration gemessen hast?
Sei’s drum dass ich es Pech nenn’,
man muss doch damit rechnen

michael_x:

...

if (duration == 20){…}




Korrekt?

Fast. Was passiert, wenn du evtl. 19 oder 21 als duration gemessen hast?
Sei’s drum dass ich es Pech nenn’,
man muss doch damit rechnen

Das wäre dann meine nächste Frage gewesen, wie genau dieses Verfahren ist :wink: Ist eine Differenz von +1/-1 machbar oder sollte ich mehr einkalkulieren?

wie genau dieses Verfahren ist

Das war eher ein genereller Einwand. Ganz abgesehen davon, dass pulseIn micros liefert, dein delay aber mit millis arbeitet.

Wenn du mehrere verschiedene diskrete ( = unterschiedliche, mit unterschiedlicher Bedeutung ) Werte übertragen willst, wäre eine seriell codierte Übertragung besser. Wenn du aber ein quasi analoges Signal haben willst (PWM nur ohne elektrische Glättung), ist dein

 if(duration == 20) {}

ein unpassendes Verfahren

michael_x:

wie genau dieses Verfahren ist

Das war eher ein genereller Einwand. Ganz abgesehen davon, dass pulseIn micros liefert, dein delay aber mit millis arbeitet.

Wenn du mehrere verschiedene diskrete ( = unterschiedliche, mit unterschiedlicher Bedeutung ) Werte übertragen willst, wäre eine seriell codierte Übertragung besser. Wenn du aber ein quasi analoges Signal haben willst (PWM nur ohne elektrische Glättung), ist dein

 if(duration == 20) {}

ein unpassendes Verfahren

Okay, für eine serielle Verbindung habe ich am 84' keine Pins mehr frei, lediglich einen für die Signalübertragung. Ich habe aktuell etwa 20 unterschiedliche Funktionen, die vom 84'er ausgeführt werden sollen, entsprechend viele Eingangssignale mit unterschiedlichen delays soll es im 45'er geben. Wenn pulseIn mit millis arbeitet, kann ich doch entsprechend delay(10) angeben und duration == 10000 abfragen oder nicht?

Gruß Dennis

Ich habe aktuell etwa 20 unterschiedliche Funktionen, die vom 84'er ausgeführt werden sollen

OK Zählt da die Funktion "nix tun" dazu ? Sind das Dauerfunktionen ? Wie schnell soll der Wechsel zwischen Funktionen sein ?

pulseIn(pin, HIGH) wartet übrigens auf LOW und dann wieder auf HIGH Damit pulseIn sauber funktioniert, müssen also immer Pulse kommen!

Ein Vorschlag:

    0 -  1999 µs = Grundzustand    delay(1)

 2000 -  4000 µs = Funktion A      delay(3)
 4000 -  6000 µs = Funktion B
 ...
52000 - 54000 µs = Funktion Z      delay(53)
54000 - ...      =    Fehler  ???

Zum Dekodieren:

 byte funktion = (byte)(pulseIn(pin, HIGH)/2000)*2 + 1;
 switch (funktion) {
   case 1: break;
   case 3: Funktion_A(); break;
   ...
 }

*2 + 1 ist nur dafür da, um auf Sender- (delay ) und Empfängerseite (case ) die gleichen Werte zu haben, ...

michael_x:

Ich habe aktuell etwa 20 unterschiedliche Funktionen, die vom 84'er ausgeführt werden sollen

OK Zählt da die Funktion "nix tun" dazu ? Sind das Dauerfunktionen ? Wie schnell soll der Wechsel zwischen Funktionen sein ?

pulseIn(pin, HIGH) wartet übrigens auf LOW und dann wieder auf HIGH Damit pulseIn sauber funktioniert, müssen also immer Pulse kommen!

Ein Vorschlag:

    0 -  1999 µs = Grundzustand    delay(1)

2000 -  4000 µs = Funktion A      delay(3) 4000 -  6000 µs = Funktion B ... 52000 - 54000 µs = Funktion Z      delay(53) 54000 - ...      =    Fehler  ???




Zum Dekodieren:



byte funktion = (byte)(pulseIn(pin, HIGH)/2000)*2 + 1; switch (funktion) {    case 1: break;    case 3: Funktion_A(); break;    ... } ```

*2 + 1 ist nur dafür da, um auf Sender- (delay ) und Empfängerseite (case ) die gleichen Werte zu haben, ...

Hui! :relaxed:

Der 84' hat in seinen Funktionen diverse Delays, in denen das Programm bekanntlich nicht mehr auf Tastendrücke oder sonstige Veränderungen reagiert. Der 45' ist mit einem Taster verbunden und schaltet die entsprechenden Modis durch, die dann jeweils die Signale an den 84' senden. Jedoch wird vor dem Senden des Signals ein kurzes LOW an den Reset des 84' gesendet um ihn neuzustarten und direkt im Setup dann den Modus abzufragen. Hier wird die Schwierigkeit sein diesen Vorgang möglichst synchron zu schalten. Darum dachte ich ja, dass es mit PWM besonders einfach geht, weil es hier dann Werte zwischen 0-255 gibt, die auch einfach zu interpretieren/messen sind ...

Um das Thema nochmal aufzugreifen: wie wandle ich ein PWM-Signal in ein analoges Signal (positive Spannung) um? Ich habe mir hierzu bereits einiges angesehen, von Logik-Relais-Steuerung bis Tiefpass-Filter. Ich kann allerdings nicht entscheiden ob diese Methoden für mein Vorhaben ausreichend sind. Reicht es nicht das Singal mit Elkos entsprechend zu glätten?

Gruß Dennis

Das glätten mittels eines elkos entspricht am ende in etwa einem tiefpassfilter (1. ordnung)...

ich kann also mit einem Elko das digitale Signal in ene halbwegs konstante Spannung umwandeln?

Mit einem Elko und einem Widerstand. Grüße Uwe

uwefed: Mit einem Elko und einem Widerstand. Grüße Uwe

Wie sieht so eine Schaltung aus und von welchen Werten sprechen wir?

Gruß Dennis

Wenn der Attiny als digitales Potentiometer arbeiten soll, wäre es dann nicht einfacher wenn er das Signal über analogRead einliest, umrechnet und dann über analogWrite an den 2. sendet ?

Megaionstorm: Wenn der Attiny als digitales Potentiometer arbeiten soll, wäre es dann nicht einfacher wenn er das Signal über analogRead einliest, umrechnet und dann über analogWrite an den 2. sendet ?

das war ja auch mein Ausgangspunkt, der funktioniert nur nicht, weil analogWrite nicht wie angenommen eine Spannung sendet, sondern PWM..

laemmen: Wie sieht so eine Schaltung aus und von welchen Werten sprechen wir?

Gruß Dennis

so sollte das aussehen, weitere informationen findest du bei http://de.wikipedia.org/wiki/Tiefpass und die werte von kondensator und widerstand solltest du so anpassen, das die grenzfrequenz im bereich der PWM-Frequenz ist denke ich mal, da dann vielleicht mal ein wenig rumprobieren, wobei dafür sicher ein oszilloskop gutwäre... oder uwe hat erfahrungswerte zu guten grenzfrequenzen

Hier werden low-, high- und bandpass Filter beschrieben. In der der passiven aber auch aktiven Form. http://www.electronics-tutorials.ws/filter/filter_2.html