Hallo zusammen,
für ein Bastelprojekt hätte ich gerne einen ATTiny85 eingesetzt um
folgendes zu tun:
Aufwachen mit einer positiven Flanke an Pin X, dann 2 Sekunden warten,
dann 2 Sekunden High-Signal an Pin Y, dann wieder in den Tiefschlaf
fallen, bis erneut eine positive Flanke an Pin x auftaucht.
Kein Retriggern während der Ablaufzeit.
Kann mir bitten das jemand eine Codeunterstützung zukommen lassen? Bis
jetzt hab ich nur etwas mit der Arduinoumgebung gemacht, Digispark.
Nun muss es stromsparend sein, soll Batteriebetrieben sein.
Vielen Dank schon mal für eure Tips.
Was soll es werden? Eine Reichweitenverlängerung für eine
Funkfernbedienung. Die Idee: Ein Fertiger Low-Power-FB-Receiver empfängt
ein passendes FB-Signal, weckt den Tiny auf und der aktiviert dann einen
weiteren FB-Sender. Dann plaziere ich das Ganze in passendem Abstand und
schwupps verdopple ich die Senderreichweite. An den Originalempfänger
komme ich nicht ran um den „zu verbessern“.
Warum Attiny? Klein, handlich, sollte imho geeignet sein.
Wenn es bessere Ideen gibt, gerne her damit. ;-)
Uwe W. schrieb:> Kann mir bitten das jemand eine Codeunterstützung zukommen lassen?
Das ist eine Steilvorlage für einen Shitstorm. Wenn du den nicht haben
willst, dann versuche es erst mal selbst. Wir helfen wir dann, die
Fehler oder Lücken in deinem Code in Ordnung zu bringen.
Steilvorlage für einen Shitstorm; Sorry, das war nicht das Ziel!
@Mods, bitte einfach sperren oder löschen. Danke
@Philipp K., vielen lieben Dank für deine Zeilen!
Philipp K. schrieb:> ISR(PCINT0_vect) {> lastPinCheck = millis();> }
Es wird nicht wie zunächst erwartet funktionieren.
Und das nicht nur wegen dem fehlenden volatile.
Oliver
Oliver S. schrieb:> Es wird nicht wie zunächst erwartet funktionieren.> Und das nicht nur wegen dem fehlenden volatile.
Volatile ist hier Wayne da sowieso klar ist wann der Zugriff erfolgt.
Man kann das auch verkürzen in diesem Falle, ich habe 4 Input Pins und
einen Hold Eingang rausgenommen, dabei könnte mir ohne Gewähr ein Fehler
passiert sein. Ist halt nur ein Beispiel.
Ursprünglich sah das so aus und funktioniert wunderbar:
https://hackaday.io/project/163278-pushbutton-controller
Hier mit Delay da es ja sowieso nur eine definierte Funktion hat.
1
#include<avr/sleep.h>
2
#include<avr/interrupt.h>
3
constintausgang=0;
4
voidsetup(){
5
pinMode(1,INPUT);
6
pinMode(ausgang,OUTPUT);
7
digitalWrite(ausgang,LOW);
8
}// setup
9
voidsleep(){
10
GIMSK|=_BV(PCIE);
11
PCMSK|=_BV(PCINT1);
12
ADCSRA&=~_BV(ADEN);
13
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
14
sleep_enable();
15
sei();
16
sleep_cpu();
17
cli();
18
sleep_disable();
19
sei();
20
}
21
ISR(PCINT0_vect){}
22
voidloop(){
23
digitalWrite(ausgang,LOW);//wieder auf LOW
24
sleep();//loop Stoppen mit PowerDown
25
digitalWrite(ausgang,HIGH);//aufgeweckt weiter mit HIGH
Philipp K. schrieb:> Volatile ist hier Wayne da sowieso klar ist wann der Zugriff erfolgt.
Hier geht es um das überhaupt, nicht um das wann.
Volatile wegen „wann“ war schon immer verkehrt, und ist der Grund, warum
C++ das wegen andauernder Falschnutzung gleich ganz abschaffen wollte.
Ist aber egal, weil OT.
Oliver
Stefan F. schrieb:> Wie kommt man eigentlich auf die Idee, in direkt aufeinander folgenden> Zeilen einen Pin als Konstante zu definieren, und den anderen nicht?
DIVERSITÄT! Der heilige Gral des Zeitgeistes!
Und ich dachte, es wäre einfach einfach…. 🙄
Wenn selbst die Profis das nicht hinkriegen, dann bin ich ja vllt. doch
nicht ganz so doof wie ich dachte 😜
Schön, dass der angedrohte Shitstorm nicht losgebrochen ist!
Hat noch jemand andere Lösungsideen?
Schönen Abend für euch!
Stefan F. schrieb:> Wie kommt man eigentlich auf die Idee,
Zur Lesbarkeit, weil nur dieser Pin im Code wieder verwendet wird.. die
anderen Pins wurden lediglich nur einmal zur IO Definition genutzt.
Ist doch logisch, lol .. das ist halt kein 2000 Zeilen Code.
Uwe K. schrieb:> Hat noch jemand andere Lösungsideen?
Bin ich der einzige, der die Frage seltsam findet, nachdem bereits ein
fast fertiger Quelltext präsentiert wurde?
Ich helfe dir, wenn du mir hilfst. Bringe den Kram vorbei, dann
programmiere ich ihn dir. Während dessen wäschst du dann mein Auto und
machst den Garten. Ich wohne in Düsseldorf. Einverstanden?
Alternativ empfehle ich dir ein fertiges Zeitrelais von Eltako.
https://www.eltako.com/fileadmin/downloads/de/Gesamtkatalog/Eltako_Gesamtkatalog_Kap13_low_res.pdf
Uwe K. schrieb:> Und ich dachte, es wäre einfach einfach….
Das ist auch einfach.
So wie ich deine Anwendung verstehe, sollten keine exakten 2.00s
gefordert sein, oder? Und der µC hat sonst nichts Weiteres zu tun? Und
du willst es auch nicht mit einem Arduino lösen?
Dann mal so grob:
- aus der 8x-Serie tut es auch der Tiny25, aber letztlich egal
- man braucht auch keinen Quarz für die Zeiten
- zum Aufwachen einen der PCINT(x) Pins und den PCINT0 Interrupt
verwenden. Der reagiert jedoch auf beide Übergänge (H->L und L->H),
daher muss man in der ISR entsprechend die Flanke feststellen und eben
den falsch ausblenden, also dann nur wieder in Tiefschlaf gehen.
- die Zeiten für das Delay und die HIGH-Phase simpel mit dem
Watchdogtimer machen (etwas ungenau, aber siehe oben), anstatt einen der
Timer aufzusetzen. Auch während der WDT läuft, kann der µC schlafen bei
einstelligen µA. Um die 2s-Zeiten etwas besser zu treffen, kann man auch
die WDT-Zeit klein wählen und die Anzahl der Aufwachvorgänge zählen, bis
die 2s erreicht sind und ggf. die Anzahl anpassen (minimal 16ms Raster).
Achtung: hier den WD-Interrupt verwenden und nicht den Watchdog-Reset!
- danach wieder Tiefschlaf mit abgeschaltetem WD bis zum nächsten
PCINT0. Da wird der Stromverbrauch dann typ. < 1µA sein.
Man muss also zwei ISRs haben und den WD-Timer und den PCINT
konfigurieren und noch einige wenige Zeilen Code dazu schreiben.
Falls es mit Batterie betrieben werden soll: drei AA(A)-Zellen würden
vermutlich länger halten als ihr aufgedrucktes MHD.
Der INT0 wäre mir persönlich lieber, aber er weckt aus dem Sleep nur im
Levelmodus auf und damit nur beim Übergang nach LOW anstatt wie
gewünscht mit HIGH. Sonst müsste man den Idle-Schlafmodus verwenden, der
aber mehr Strom benötigt (100-200µA).
Alles gut, lieben Dank!
@ Stefan F. :
Wenn ich den Quellcode gleich verstanden hätte… war nicht so ;-/
Mit der Frage nach anderen Ideen war z.B. gemeint, nimm nen anderen uP
z.B. Tiny25 oder Tiny402 (den hab ich gefunden mit Blick auf den
Stromverbrauch im Sleep-Mode) oder vllt auf eine andere SW-Basis.
Aber sei‘s drum!
Das mit dem Eltako dürfte vermutlich schon am Batteriebetrieb scheitern.
8-/
@ Klaus H.
Dankeschön für deine Zeilen! Mit dem Stromverbrauch hast du recht, da
halten ein paar Batterien sehr lange. Der ständig bereitstehende
Empfänger ist der, der die Batterien leersaugen wird. Ich habe einen
angepriesen LowPower bestellt, mal sehen, was er dann wirklich nimmt…
Danke allen für eure Hilfestellungen!
Viele Grüße
Uwe K. schrieb:> Das mit dem Eltako dürfte vermutlich schon am Batteriebetrieb scheitern.
Ja. Ich war von Netzbetrieb ausgegangen, wegen dem Funkempfänger.
Wenn dir der Quelltext zu komplex ist, kannst du auch Monostabile
Kippstufen mit einem CD4584 (=CD40106) aufbauen.
Hier ein Beispiel von mir.
Der Eingang wird 50ms entprellt, damit nicht durch Störungen
versehentlich gesendet wird. Der Interrupt kann ja schon auf <50ns
anspringen.
Ändert sich der Eingang nicht in die gewünschte Richtung, wird
geschlafen.
Der Interrupt ist leer, muß ja nur aufwecken.
Anbei die sbit.h.
Uwe K. schrieb:> Der ständig bereitstehende> Empfänger ist der, der die Batterien leersaugen wird.
Gut, dann kann man sich den WD-Timer sparen und die zwei mal zwei
Sekunden, wie in Peters Vorschlag mit _delay_ms() erledigen.
Ich hatte zum Strom sparen darauf bewusst verzichtet, denn in der Zeit
läuft ja der µC im Kreis und braucht dann Strom im unteren mA-Bereich.
Entprellen ist natürlich ein gute Idee, aber nur notwendig, wenn man
keine ordentliches Signal am Eingang hat (wie von einem Taster z.B.).
Schaut mal, wie Googles Bard die Aufgabe löst:
"Programmiere ein Arduino Board. Es soll darauf warten, dass am Eingang
D2 ein Signal (HIGH Pegel) anliegt. Zwei Sekunden danach soll der
Ausgang D3 eine Sekunde lang einen HIGH Impuls liefern. Danach soll der
Mikrocontroller Strom sparen, bis zum nächsten Impuls."
1
// Pins definieren
2
constintEingang=2;
3
constintAusgang=3;
4
5
// Programminitialisierung
6
voidsetup(){
7
// Pins als Ein-/Ausgang definieren
8
pinMode(Eingang,INPUT);
9
pinMode(Ausgang,OUTPUT);
10
}
11
12
// Hauptschleife
13
voidloop(){
14
// Wenn der Eingang HIGH ist
15
if(digitalRead(Eingang)==HIGH){
16
// Zwei Sekunden warten
17
delay(2000);
18
// Den Ausgang HIGH setzen
19
digitalWrite(Ausgang,HIGH);
20
// Eine Sekunde warten
21
delay(1000);
22
// Den Ausgang LOW setzen
23
digitalWrite(Ausgang,LOW);
24
// Den Mikrocontroller in den Stromsparmodus versetzen
25
set_sleep_mode(SLEEP_MODE_IDLE);
26
sleep_mode();
27
}
28
}
Das sieht nach einem brauchbaren Anfang aus. Hier fehlen zwei Dinge:
1) dass er auch vor dem ersten Impuls schon schlafen gehen sollte. Habe
ich allerdings auch nicht ausdrücklich gesagt.
2) das Einrichten eines Interrupts zum Aufwecken, damit der nächste
Impuls überhaupt erkannt wird.
Ein bisschen Creepy ist das schon, oder?
Klaus H. schrieb:> Entprellen ist natürlich ein gute Idee, aber nur notwendig, wenn man> keine ordentliches Signal am Eingang hat (wie von einem Taster z.B.).
Der Pin-Change Interrupt ist sehr empfindlich gegen Störungen. Z.B. wenn
jemand an einer Steckdose in der Nähe den Rasenmäher, Staubsauger,
Waschmaschine usw. einschaltet.
Ein Handy kann auch gut stören, wenn der Empfang schlecht ist. Dieses
typische Zirpen in Radios usw. hat bestimmt jeder schon gehört.
Ist dann nicht so schön, wenn sich das Garagentor wie von Geisterhand
öffnet.
Peter D. schrieb:> Der Pin-Change Interrupt ist sehr empfindlich gegen Störungen.
Ohne Zweifel.
Aber das gilt in jeder digitalen Schaltung zumindest für die Taktleitung
auch und richtet u.U. einen vergleichbaren 'Schaden' an. Da kann man
weniger machen und daran dachte ich mit meinem Argument. Auch
R/S-Eingänge an FFs betrifft das - der Pin-Change wird ja letztlich wie
ein R/S-FF ausgeführt sein.
Aber du hast natürlich recht, dass man in dem Fall mit einfachstem Code
eine Sicherheit gegen Störung welcher Art auch immer erreichen kann.
Stefan F. schrieb:> Ein bisschen Creepy ist das schon, oder?
In der Tat, man benötigt ja auch keinen Pcint, das war von mir nur weil
ich 4 Pins mit Interrupt gebraucht habe.
Chatfpt brachte bei mir das: