Attiny13 Switch / Frage dazu

OP #2845935
Lesenswert?

Hi!

Hab mir einen RC Switch gebaut mit einem Attiny13

Funktioniert eigentlich ganz gut, aber dennoch hätte ich gern eine 
Funktion die ich nicht gebacken bekomme.

Hier mal der Code: http://pastebin.com/4LHvHmCT

So wie der Code jetzt aussieht kann ich 2 Ports getrennt einschalten.
Allerdings sind diese nur so lange an wie der Impuls von 10-13ms oder 
17-20ms anliegt. In Mittelstellung bei ca 15ms sind beide aus. Ich hätte 
aber gern eine art "Taster" funktion. Port soll an bleiben bis der 
gleiche Impuls noch einmal anliegt. Dann soll der Port wieder aus sein.

Ist das so überhaupt umsetzbar mit dem Tiny13? Und wenn ja könnte mir 
evtl jemand einen Tipp geben wie dabei vorgehen könnte.

Ich würde dafür auch weiterhin gern Bascom nutzen :)

Vielen Dank :)
#2845994
Lesenswert?

Marco Ha schrieb:

> So wie der Code jetzt aussieht kann ich 2 Ports getrennt einschalten.
> Allerdings sind diese nur so lange an wie der Impuls von 10-13ms oder
> 17-20ms anliegt. In Mittelstellung bei ca 15ms sind beide aus. Ich hätte
> aber gern eine art "Taster" funktion. Port soll an bleiben bis der
> gleiche Impuls noch einmal anliegt. Dann soll der Port wieder aus sein.

Erst mal musst du deine Aufgtabenstellung etwas präzissieren.
Denn 'der gleiche Impuls' liegt ungefähr 50 mal in der Sekunde an.

Was du eigentlich willst, ist ganz was anderes. Du willst den Pin 
toggeln, wenn die Pulslänge sich aus dem Mittelbereich in den 
Schaltbereich bewegt.

D.h. du musst 2 hintereinander folgende Messdurchgänge vergleichen. Nur 
dann wenn im vorhergehenden Durchgang die Klassifikation 'mitte' vorlag 
und in diesem Durchgang die Klassifikation 'im SChaltbereich', dann 
passiert tatsächlich was.
(Oder aber du hast für jede Schaltfunktion eine Variable, die dir sagt, 
ob bei der Pulslänge schon geschaltet wurde oder nicht und die dann im 
Mittenbereich zurückgesetzt wird.
#2846052
Lesenswert?

Marco Ha schrieb:
> Ja du hast Recht. Alle 20ms kommt je nach Knüppelstellung ein Impuls mit
> der länge von 1.0ms 1,5ms oder 2,0ms
>
> Ich werde das Heute mal so Testen:
>
> If W > 170 And W <= 200 Then
> Toggle Portb.0
> End If

Das bringt dir so nichts!

Denn die Aussage "Die Pulslänge ist jetzt im Bereich in dem geschaltet 
werden muss" ist eben nur die halbe Miete. Du brauchst noch eine 
zusätzliche Information. Deine Aussage muss lauten

"Die Pulslänge ist jetzt im Bereich in dem geschaltet werden muss UND 
beim letzten mal Pulslänge messen war sie das noch nicht"

Du brauchst noch eine zusätzliche Variable, mit deren Hilfe du diese 
zusätzliche Information unter- und in die Auswertung einbringst.

zb so.

  if W > 170 And W <= 200 then
    if Schalte1 = 0 then
      Toggle Portb.0
      Schalte1 = 1
    endif
  else
    Schalte1 = 0
  endif

Schalte1 führt darüber Buch, ob sich die Pulslänge im Schaltbereich 
befindet. Ist die Pulslänge ausserhalb (der Teil nach dem else) dann 
wird die Variable auf 0 gesetzt. Geht die Pulslänge dann in den 
Schaltbereich, dann wird getoggelt und in Schalte1 vermerkt, dass schon 
getoggelt wurde, so dass bei der nächsten Auswertung der Pulslänge nicht 
mehr getoggelt wird. Die Pulslänge muss erst wieder aus dem Bereich 
herausfallen, damit (über das else) Schalte1 wieder zu 0 wird und das 
nächste Toggeln zulässt.
#2846080
Lesenswert?

Marco Ha schrieb:
> Ok!
>
> Ich war der meinung das der Port bei "Toggle bei 1,7-2,0ms" Automatisch
> so lange offen/geschlossen bleibt bis ich den Impuls mit passender Länge
> noch einmal anlege.

Ja.
Bei EINEM Impuls.

Aber deine Fernsteuerung generiert nicht EINEN Impuls. Die generiert 
LAUFEND Impulse. 50 Stück in der Sekunde. Die sind dann halt in der 
Mehrzahl der Fälle alle gleich (weil sich die Knüppelstellung nicht 
verändert hat), aber das macht ja nichts. Ganz im Gegenteil: Wenn aus 
irgendeinem Grund mal die Funkverbindung unterbrochen ist (Störung), 
dann wird mit dem nächsten sauber empfangenen Puls die aktuelle Position 
wieder hergestellt. Die Fernsteuerung schickt ständig die aktuelle 
Position und nicht nur, wenn du am Knüppel rumrührst.
OP #2846093
Lesenswert?

Aber ist hier nicht die Impulslänge für die Schaltung verantwortlich? So 
wie der Code jetzt aussieht, könnte der Empfänger auch 1000x pro Sekunde 
senden und nichts würde Passieren bevor sich die Impulslänge ändert.

Also würde sich doch der Status des Ports nicht ändern? Dieser erwartet 
doch keine 1,5ms (normalstellung) sondern min 1,3 nach unten oder 1,7 
nach oben! Sitz ich auf dem schlauch?

Grüzle Marco
#2846105
Lesenswert?

Marco Ha schrieb:
> Aber ist hier nicht die Impulslänge für die Schaltung verantwortlich?

Ja natürlich.

Aber wenn du dir 50 mal in der Sekunde die Pulslänge ansiehst und dich 
bei JEDEM ansehen fragst: Ist die jetzt zwischen 170 und 200 und wenn 
ja, dann toggle den Pin, dann toggelt dein Pin 50 mal in der Sekunde, 
wenn der Knüppel auf der Fernsteuerung in diesem Bereich ist.
d.h. der schaltet dann 50 mal in der Sekunde um zwischen 0 und 1. Denn 
bei jeder Messung kommen dann zb 1.5ms raus. Und da das im Bereich ist, 
wird auch jedes mal der Pin getoggelt.
Das ist aber ganz sicher nicht das was du willst.

> Also würde sich doch der Status des Ports nicht ändern?
Doch.
Würde er. Nämlich dann, wenn das erste mal 1.3-1.7 ms detektiert werden. 
Kommt bei der nächsten Messung wieder 1.5ms raus, dann passiert nichts 
mehr. Erst dann, wenn die Pulslänge irgendwann wieder mal unter 1.3ms 
fällt, wird das System wieder scharf geschaltet und wenn dann das 
nächste mal 1.5ms festgestellt werden, wird wieder geschaltet. Aber: 
wieder nur ein einziges mal und nicht solange diese Pulslänge 
festgestellt wird.


> doch keine 1,5ms (normalstellung) sondern min 1,3 nach unten oder 1,7
> nach oben! Sitz ich auf dem schlauch?

Du sitzt auf dem Schlauch.

Was dir nicht klar ist:
Wenn ich dir den Auftrag gebe "jede Sekunde beim Nachbarn ins Fenster zu 
schauen und du dort Licht siehst, dann sollst du den Lichtschalter 
umlegen", dann schaltest du laufend im Sekundentakt dein eigenes Licht 
an und aus, wenn beim Nachbarn Licht brennt. Das ist so, weil du den 
Auftrag hast, jede Sekunde die Entscheidung 'muss ich den Lichtschalter 
umlegen' neu zu treffen. Und wenn die Antwort auf diese Frage jedes mal 
'Ja' lautet, dann schaltest du eben ständig.
#2846307
Lesenswert?

In C könnte das so aussehen:
1
  switch( input ){
2
    static char state = 0;
3

4
    case 100 ... 130:
5
      if( state != 1 ){
6
        state = 1;
7
        action1();  // do something once
8
      }
9
      break;
10

11
    case 170 ... 200:
12
      if( state != -1 ){
13
        state = -1;
14
        action2();  // do something once
15
      }
16
      break;
17

18
    case 140 ... 160:
19
      state = 0;
20
      break;
21
  }


Peter
OP #2846557
Lesenswert?

Mein Dank geht an Karl Heinz Buchegger

Dank ihm klappt es wunderbar und ich hab es auch verstanden.

Der fertige code sieht dann so aus:

$regfile = "attiny13.dat"
$crystal = 9600000
$hwstack = 16
$swstack = 8
$framesize = 24

Config Portb.2 = Input
Config Portb.1 = Output
Config Portb.0 = Output

Dim W As Word
Dim Sw1 As Word
Dim Sw2 As Word

Do
Pulsein W , Pinb , 2 , 1

If W > 170 And W <= 220 Then
If Sw1 = 0 Then
Toggle Portb.0
Sw1 = 1
End If
Else
Sw1 = 0
End If

If W <= 130 And W > 80 Then
If Sw2 = 0 Then
Toggle Portb.1
Sw2 = 1
End If
Else
Sw2 = 0
End If

Loop
End

Grüzle Marco
#2846584
Lesenswert?

Simon K. schrieb:
> Peter, der Datentyp char ist doch für Zeichen gedacht... ;-)

Die Sprache C unterscheidet das nicht. Mathematische Operationen sind 
für alle Bitbreiten erlaubt: 8, 16, 32 und 64 Bit.
Auf 8-Bittern bieten sich 8Bit-Variablen geradezu an.

Wären Zeichen keine Variablen, wäre es verdammt schwierig, ein itoa oder 
atoi zu implementieren.


Peter
Persönliche Seite #2846601
Lesenswert?

Peter Dannegger schrieb:
> Simon K. schrieb:
>> Peter, der Datentyp char ist doch für Zeichen gedacht... ;-)
>
> Die Sprache C unterscheidet das nicht. Mathematische Operationen sind
> für alle Bitbreiten erlaubt: 8, 16, 32 und 64 Bit.
> Auf 8-Bittern bieten sich 8Bit-Variablen geradezu an.
>
> Wären Zeichen keine Variablen, wäre es verdammt schwierig, ein itoa oder
> atoi zu implementieren.

Tja, da predigt man hier oft genug, dass char nicht zum Rechnen benutzt 
werden soll (u.A. wegen unsigned/signed Problem) und das stattdessen 
uintX_t Datentypen besser geeignet sind.
Und dann machst du wieder ein Strich durch die Rechnung.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren