Forum: Mikrocontroller und Digitale Elektronik Licht mit Tiny13


von Timm (Gast)


Lesenswert?

Hallo, ich programmiere gerade für ein Schulprojekt eine 
Helligkeitssteuerung und On/ Off über ein Taster mit Tiny13A. Wenn lange 
drauf bleibe so es hell und dunkel werden und wenn kurz drauf tippe soll 
es on bzw off gehen. Die Helligkeitssteuerung habe ich hinbekommen aber 
on / Off mit d selbe Taste kriege ich nicht hin.
Kann jemand mir helfen???

Danke

von spontan (Gast)


Lesenswert?

Kurzes Drücken erkannt, ja ?
Licht ist grad an - > ausschalten
Licht ist grad aus -> einschalten

Wo ist das Problem?
Schreibts Du die Software selbst, oder suchst Du Code für Copy&Paste?

von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


Lesenswert?

1. Timer aufsetzen und darin das Tastensignal einlesen und entprellen.
2. Zustandsautomat aufsetzen.
3. Entprellte Tastensignale als Ereignisse innerhalb des 
Zustandsautomaten auswerten.
4. Ebenso Timerereignisse auswerten.

von Thomas D. (thomasderbastler)


Lesenswert?

Welche Sprache ?

von Timm (Gast)


Lesenswert?

Die Software habe ich soweit selber geschrieben. Es funktioniert auch 
soweit mit der Helligkeit aber on off geht irgend wie nicht.

Hier ist der Code

/*
* ledproject.c
*
* Created: 18.09.2013 13:21:05
*  Author: Timm
*/


#include <avr/io.h>
#include <avr/interrupt.h>


void main(void)
{
  unsigned int pwm_duty,direction=0,count_1=0,count_2=0;

  DDRB  = ((1<<DDB0)|(1<<DDB1)|(0<<DDB2));
  PORTB = ((1<<PB0)|(1<<PB1)|(0<<PB2));


  TCCR0A = ((1<<COM0A0) |(1<<COM0A1)| (1<<WGM01) | (1<<WGM00));
  TCNT0  = 0;
  TCCR0B = (1<<CS01);

  while(1)
  {
    if(!(PINB &(1<<PB2)))
    {
      if(direction==1)
      {
        count_1++;
        if(count_1>=500)
        {
          pwm_duty++;
          count_1=0;
        }
      }
    }

    if(!(PINB &(1<<PB2)))
    {
      if(direction==0)
      {
        count_2++;
        if(count_2>=500)
        {
          pwm_duty--;
          count_2=0;
        }
      }
    }

    OCR0A=pwm_duty;

    if(pwm_duty>=254)
    {
      pwm_duty=254;
      if((PINB &(1<<PB2)))
      {
        direction=0;
      }

    }
    if(pwm_duty<=5)
    {
      pwm_duty=5;
      if((PINB &(1<<PB2)))
      {
        direction=1;
      }
    }

  }
}

von Timm (Gast)


Lesenswert?

Dass ist die Helligkeitssteuerung, wo oder wie kann ich die Taster on 
off abfrage machen. Mit Zustandsautomat sollte es eigentlich einfacher 
gehen oder??? Aber wie mache ich hier dann die auswertungen(wegen der 
Tipped time)? <4sec off >4sec helligkeitssteuerung.

Brauche dringend unterstützung

danke

von spontan (Gast)


Lesenswert?

Wo in Deinem Code wird denn das Licht an oder ausgeschaltet?
Wo ist denn eine Auswertung der Drück-Dauer?

von Timm (Gast)


Lesenswert?

ich habe es so probiert, aber erfolgs los


while(1)
  {
    if(btnpresscount>2 && btnpresscount<50)
    {
      DDRB  =(0<<DDB0);
      PORTB=(0<<PB0);
      return 0;
    }

  else

  {................
         ................
        }
       }

von Thomas E. (thomase)


Lesenswert?

Timm schrieb:
> Hier ist der Code
da gehört er aber nicht hin, sondern in den Anhang deines Posts.

>   PORTB = ((1<<PB0)|(1<<PB1)|(0<<PB2));
>

>   while(1)
>   {
>     if(!(PINB &(1<<PB2)))
>     {
...
>     }
>
>     if(!(PINB &(1<<PB2)))
>     {
....
>     }

Kanst du das mal erklären. Über das bescheuerte "Nullgeschiebe" lohnt es 
sich schon gar nicht mehr aufzuregen, aber wo ist der Pullup für PB2?
Und wo ist deine Entprellung? Auch dein Programm wird ohne nicht 
funktionieren.

mfg.

von Timm (Gast)


Lesenswert?

habe vorhin eine Zeile vergessen


  while(1)
  {
    if(!(PINB &(1<<PB2)))
    {
      btnpresscount++;
    }
    if(btnpresscount>2 && btnpresscount<50)
    {
      DDRB  =(0<<DDB0);
      PORTB=(0<<PB0);
      return 0;
    }

  else

  {

}

von Thomas E. (thomase)


Lesenswert?

Timm schrieb:
> habe vorhin eine Zeile vergessen
>       DDRB  =(0<<DDB0);
>       PORTB=(0<<PB0);

Vergiss diesen Mist. Ich glaube, du weisst überhaupt nicht, was das 
macht.

http://www.mikrocontroller.net/articles/Bitmanipulation

mfg.

von cppler (Gast)


Lesenswert?

Ist die Vorgabe das Du es selber tun mußt ?
Wenn nein nimm die Entprellroutine von PeDa hier.
Wenn ja überlege Dir wie Du entprellst und wie Du dort einen Timestamp 
hinterlegen kannst.

von Timm (Gast)


Lesenswert?

Wir dürfen im Internet recherchieren, lesen und unterstützung holen. 
Wichtig ist, dass ich es dann auch verstanden habe und erklären kann.

wo finde ich die Entprellroutine von PeDa??

von Thomas E. (thomase)


Lesenswert?

Timm schrieb:
> Wir dürfen im Internet recherchieren, lesen und unterstützung holen.
> Wichtig ist, dass ich es dann auch verstanden habe und erklären kann.
>
> wo finde ich die Entprellroutine von PeDa??

In der Artikelsammlung unter "Entprellung". Aber vergiss es. Die 
Funktion wirst du nicht erklären können.

Entprellung geht im einfachsten Fall so:
-Feststellen, daß Taste gedrückt
-Warten(~20-50ms)
-Testen, ob Taste immer noch gedrückt

Damit hast du das Prellen eliminiert.

Das reicht aber noch nicht. Du musst die Zustandsänderung der Taste 
erfassen.
Also:
-Feststellen, ob Taste, die vorher nicht gedrückt war, jetzt in diesem
 Moment gedrückt wurde
-Warten
-Testen, ob immer noch gedrückt
-Sich merken, daß Taste jetzt gedrückt ist.
...
-Feststellen, ob Taste gehalten wird oder die gerade gedrückte Taste
 jetzt in diesem Moment losgelassen wurde.
-Warten
-Testen ob losgelassen
-Sich merken, daß Taste nicht mehr gedrückt ist.

Solange die Taste gehalten wird, lässt du einen Zähler laufen, der dir 
ab einem bestimmten Zählerstand "lang" liefert. Wenn "lang" erkannt 
wurde, veränderst du die Helligkeit.
"kurz" kannst du erst nach dem Loslassen der Taste erkennen. Nämlich aus 
der Tatsache, daß die Taste gerade losgelassen wurde und während sie 
gedrückt war, nicht "lang" erkannt wurde. Du kannst "kurz" nicht an der 
gedrückten Taste erkennen. Woher soll der Controller wissen, wie lange 
der Benutzer die Taste jetzt drücken wird? Wenn er das wüsste, könnte er 
auch die Lottozahlen vorhersagen.

-"kurz": Taste losgelassen und Zähler < Langwert
-"lang": Taste gehalten und Zähler >= Langwert
-"nichts tun": Taste losgelassen und Zähler > Langwert

Der Langwertzähler muß nach den Loslassen grundsätzlich auf 0 gesetzt 
werden.

mfg.

: Bearbeitet durch User
von Timm (Gast)


Lesenswert?

Danke für die Erklärung. Ich habe jetzt den Code für Kurz geschrieben, 
kann es so stimmen?


  while(1)
  {
    if(!(PINB &(0<<PB2))
    {
      btnpresscount++;
    }

        if(btnpresscount<btntipped)
        {
          btnpresscount=0;
          tipped=1;
        }

        if((PINB &(0<<PB2)))
        {
          btnpresscount++;
        }

        if(btnpresscount<btnrelease)
        {
          btnpresscount=0;
          release=1;
        }


    if(tipped==1)
    {
      DDRB  =0x01;
      PORTB=0x01;
      tipped=0;
    }

    if(release==1)
    {
      if(tipped==1)
      {
        DDRB  =0xFE;
        PORTB=0xFE;
        release=0;
      }
    }

danke

von Gerhard H. (Firma: Rentner) (spectro)


Lesenswert?

100n parallel zum Schaltkontakt wirken oft Wunder. Wenn man das weiss, 
wird der Thread kürzer. ;-)

von Gerhard H. (Firma: Rentner) (spectro)


Lesenswert?

/* Belehrungsmodus  *Marke oberg'scheit!*

Ich habe oft  - bestimmt fälschlicherweise - den sehr schlimmen 
Verdacht, dass sich die meisten von Euch zwar hinsichtlich 
Programmierung perfekt auskennen, aber, dass es sehr oft an 
Grundkenntnissen von elektronischen Schaltungen mangelt.  Ich sage 
immer, dass das Display-Rubbeln und die Black-Box-Grundeinstellung, 
Marke "Scheissegal-was dahinter-steckt-Hauptsache-die Kiste-rennt" , 
einfach zu wenig ist. Und eben deshalb sollte man niemals mit 
Scheuklappen (beidseitig 'ne Klappe) hier im Forum herumrennen!
Dazu ist das Forum einfach zu schade!
Holt Euch Elektronik-Grundkenntnisse, dann seid Ihr allen anderen 
voraus!
Viele von Euch wissen nicht einmal, wie man den Vorwiderstand für eine 
LED berechnet, wie man die Formel U=R*I umstellen kann, wenn man zum 
Bleistift die Stromaufnahme bräuchte! Das ist grundlegend!
Und Linux kann weit mehr,Leute, als Eure Buntklick- IDE's! Wenn Ihr da 
reinschnüffelt, wisst Ihr erst , was wirklich läuft!

Und von elektronischen GRUND-Kenntnissen sollte man ausgehen, BEVOR man 
versucht, zu programmieren und keineswegs umgekehrt! Amen!

Obergescheitmodus aus */

von Thomas E. (thomase)


Lesenswert?

Timm schrieb:
> Danke für die Erklärung. Ich habe jetzt den Code für Kurz geschrieben,
> kann es so stimmen?
>
>
>   while(1)
>   {
>     if(!(PINB &(0<<PB2))

Was erwartest du da als Ergebnis?

(0<<PB2).
Ich weiss nicht, wer sich das ausgedacht hat und welche Vollpfosten das 
immer wieder als sinnvoll verteidigen. Aber tu dir selbst den Gefallen 
und vergiss, daß du das jemals gesehen hast.
Das ist eine völlig unbrauchbare Konstruktion. Eine 0 kannst du 
versuchen, sonstwo hinzuschieben. Das ist und bleibt immer 0. Und wenn 
du 0 mit irgendwas UND-verknüpfst ist auch das Ergebnis immer 0. Also 
kann man damit etwas abfragen, wenn das Ergebnis immer 0 ist?

Guck dir an, wie man das richtig macht:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Zugriff_auf_IO-Ports

Der Bitmaniplationslink oben ist nicht ganz so prickelnd.

mfg.

von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


Lesenswert?

Thomas Eckmann schrieb:
> Eine 0 kannst du versuchen, sonstwo hinzuschieben. Das ist und bleibt immer 0.

Ähem, das trifft leider nicht immer zu. Gemäß C-Spezifikation ist das 
Schieben um mehr als die Datentypbreite undefiniert. Folglich kann jeder 
beliebige Wert herauskommen, also auch ungleich Null. Es gibt 
irgendeinen kommerziellen Compiler, der bei höheren Optimierungsstufen 
tatsächlich mit solchen üblen Tricks arbeitet, um bei irgendwelchen 
fingierten Benchmarks besonders gut abzuschneiden.

von Thomas E. (thomase)


Lesenswert?

Andreas Schweigstill schrieb:
> Thomas Eckmann schrieb:
>> Eine 0 kannst du versuchen, sonstwo hinzuschieben. Das ist und bleibt immer 0.
>
> Ähem, das trifft leider nicht immer zu. Gemäß C-Spezifikation ist das
> Schieben um mehr als die Datentypbreite undefiniert. Folglich kann jeder
> beliebige Wert herauskommen, also auch ungleich Null. Es gibt
> irgendeinen kommerziellen Compiler, der bei höheren Optimierungsstufen
> tatsächlich mit solchen üblen Tricks arbeitet, um bei irgendwelchen
> fingierten Benchmarks besonders gut abzuschneiden.

Unsinn.
Hier wird gar nichts geschoben, sondern vom Compiler eine Konstante 
eingesetzt. Und wenn der sieht, "0 schieb 10^36 mal nach links", dann 
setzt er da 0 rein. Weil er bei "0 schieb..." gar nicht mehr weiter 
macht. Schliesslich lassen sich die Compilerbauer nicht jeden Blödsinn 
unterjubeln. Um das Schieben zur Laufzeit geht es dabei überhaupt nicht. 
Aber schön, daß du drüber geschrieben hast.

Vielleicht solltest du deinen Nachnamen manchmal zum Omen machen.

mfg.

: Bearbeitet durch User
von Timm (Gast)


Lesenswert?

Thomas Eckmann schrieb:
> Was erwartest du da als Ergebnis?

Das war ein Shreibfehler sry.

von Timm (Gast)


Lesenswert?

Ich habe jetzt die entprellung hinbekommen, allerdings tue ich mir sehr 
schwer die beide Funktionen zu vereinen. Kurz tippen an aus und lang 
drücken dimmen.

kann mir jemand bitte weiter helfen?? Ich mach da seit freitag rum und 
kreig es einfach nicht hin.

Hier ist der entprell teil:

  while(1)
  {
    if(bit_is_clear(PINB, 2))
    {
      btnpress++;
      if(btnpress<20)
      {
        if(pressed==0)
        {
          PORTB ^= 1<< PINB1;
          pressed=1;
        }
      }

    }

    else
    {
      btnrelease++;
      if(btnrelease<20)
      {
        pressed=0;
        btnrelease=0;
      }

    }

  }

von Thomas E. (thomase)


Lesenswert?

Timm schrieb:
>       btnpress++;
>       if(btnpress<20)

Das macht doch auch keinen Sinn, daß das darauf Folgende 20 mal 
ausgeführt wird.
Ist das wieder ein Tipfehler?

Hör auf, Programmfetzen (fehlerhaft) abzutippen. Sondern stell deinen 
ganzen Programmtext als Anhang ein. Dann kann man das auch mal laufen 
lassen.

mfg.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.