Schrift
[thread]7874[/thread]

Definition einer abfallende Flanke!?



<< |< 1 2 >| >> 18 Einträge, 2 Seiten
EagleFox
 2006-04-10 15:44
#64650 #64650
User since
2006-04-10
66 Artikel
BenutzerIn
[default_avatar]
Hallo Leute,

wie kann ich eine abfallende Flanke nutzen, die vom Wert 5 auf 0 fällt.
Genauer:
Ich habe ein Triggersignal, welches so aussieht:

Code: (dl )
1
2
3
4
5
6
5                            |----------|
| |
| |
| |
| |
0------------------------- ------------------------------




Ich habe zum sortieren von damit verbundenen Werten anfangs die steigende Flanke genutzt, die aber, wie ich kürzlich feststellte, sehr unscharf ist. Nun möchte ich die abfallende Flanke nutzen, die recht scharf definiert ist. Wie stelle ich das in dem Programm hier an?
Bisher wurde einfach darauf geachtet bis das Triggersignal einen Wert hat, der mit 4 beginnt. Nun möchte ich aber einen Wert auf der anderen Flanke nutzen.


Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#! /usr/bin/perl

use strict;
use warnings;

my $file = 'test.dat';
my $out = 'test.dat.out';
my $count_ = 1;
my $datensatz = '';

{
open(my $outfh,">$out") or die $!;

open(my $fh,"<$file") or die $!;
while(my $entry = <$fh>){
$entry =~ s/\r?\n//g;
if($entry =~ /^\s*?#/){
print $outfh $entry,"\n";
}
else{
if($entry =~ /^\s*?$/){
$count_++;
}
else{
$datensatz .= $entry."\n";
}
if($count_ % 3 == 0){
$datensatz = getDatensatz($datensatz);
print $outfh $datensatz;
$count_ = 1;
$datensatz = '';
}
}
}
if($datensatz){
$datensatz = getDatensatz($datensatz);
print $outfh $datensatz;
}
close $fh;
close $outfh;
}

sub getDatensatz{
my ($entry) = @_;
my $bool = 0;
my $set = '';
my @steigend;
for my $line(split(/\r?\n/,$entry)){
chomp $line;
my $wert = (split(/\s+/,$line))[-1];
$bool = 1 if($bool || $wert =~ /^4/);
unless($bool){
push(@steigend,$line);
}
else{
$set .= $line."\n";
}
}
$set .= $_."\n" for(@steigend);
$set .= "\n\n";
return $set;
}


Danke schon mal im voraus!\n\n

<!--EDIT|EagleFox|1144673520-->
Ishka
 2006-04-10 16:54
#64651 #64651
User since
2003-08-04
771 Artikel
HausmeisterIn
[Homepage] [default_avatar]
Merk dir die Werte der letzten 3 (ggf. auch mehr oder weniger, kommt auf deine Daten an) Schritte in einem Array, und schau immer, ob die Differenz zwischen dem aktuellen und dem ältesten Wert im Array größer als 4.5 (oder so) ist.
sub z{if(@_){1while$x[$k=rand 10];t($t=$x[$k]=1)}print map"$z[$x[$_]]$_".($_%3?
"":"\n"),1..9}sub t{$j=0;$x[$_+1]==$t&&($j+=2**$_)for 0..8;z,die"Gewinner $z[$t]
"if grep$_==($j&$_),7,56,73,84,146,273,292,448;z,die"Gleichstand\n"if@x>9&&!grep
!$_,@x}@x=4;@z=qw{. [ (};z$^T&1;while(<>){next if$_>9||$x[$_];t$t=$x[$_]=2;z 1}
EagleFox
 2006-04-10 17:02
#64652 #64652
User since
2006-04-10
66 Artikel
BenutzerIn
[default_avatar]
Hmm, die Idee ist nicht so schlecht, aber eine Flanke besteht aus mehreren hundert Datenpunkten. Die so zu zerstückeln reicht glaube ich nicht aus, um das vernünftig zu machen. Ich dachte da eher an eine Lösung wie:

Warte bis der Wert des Triggers irgendetwas mit 5 beginnend erreicht hat und schaue dann, bis der Wert wieder auf etwas mit 3 beginnend gesunken ist.

Aber dazu spreche ich zu wenig perl, um das in das Programm zu integrieren.
Ishka
 2006-04-10 17:09
#64653 #64653
User since
2003-08-04
771 Artikel
HausmeisterIn
[Homepage] [default_avatar]
Das könntest du so in der Art machen
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
my $warte_auf_flanke=0;
while($daten=...)
{
if($daten > 5)
{
$warte_auf_flanke=1;
}
if($warte_auf_flanke and $daten < 3)
{
$warte_auf_flanke=0;
sub_die_bei_flanke_aufgerufen_wird();
}
}
sub z{if(@_){1while$x[$k=rand 10];t($t=$x[$k]=1)}print map"$z[$x[$_]]$_".($_%3?
"":"\n"),1..9}sub t{$j=0;$x[$_+1]==$t&&($j+=2**$_)for 0..8;z,die"Gewinner $z[$t]
"if grep$_==($j&$_),7,56,73,84,146,273,292,448;z,die"Gleichstand\n"if@x>9&&!grep
!$_,@x}@x=4;@z=qw{. [ (};z$^T&1;while(<>){next if$_>9||$x[$_];t$t=$x[$_]=2;z 1}
Crian
 2006-04-10 17:11
#64654 #64654
User since
2003-08-04
5872 Artikel
ModeratorIn
[Homepage]
user image
Das klingt nach einer ganz einfach State-Machine. Merk dir einfach einen Zustand ">3" und einen Zustand "<=3" und reagiere abhängig vom Zustand und dem eingelesenen Wert.

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
Wert | Ist-Zustand | Soll-Zustand | Flankenabfall ?
-----+-------------+--------------+-----------------
1 | >3 | <=3 | ja
1 | <=3 | <=3 | nein
2 | >3 | <=3 | ja
2 | <=3 | <=3 | nein
3 | >3 | <=3 | ja
3 | <=3 | <=3 | nein
4 | >3 | >3 | nein
4 | <=3 | >3 | nein
5 | >3 | >3 | nein
5 | <=3 | >3 | nein
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
EagleFox
 2006-04-10 17:17
#64655 #64655
User since
2006-04-10
66 Artikel
BenutzerIn
[default_avatar]
Jetzt muss ich nur noch verstehen, wie ich das in das Programm oben einbringe. Das ist ja von der Vorgehensweise etwas anders herum geschrieben, soweit ich das verstehe.
EagleFox
 2006-04-10 17:49
#64656 #64656
User since
2006-04-10
66 Artikel
BenutzerIn
[default_avatar]
@ crian,

wie das funktionieren soll, musst Du mir mal erklären! Mit Deinem Vorschlag kann ich nun garnichts anfangen.
Ich verstehe nicht mal, wie die Tabelle zu lesen ist. ;-(
Dubu
 2006-04-10 17:53
#64657 #64657
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
@Crian: Wenn es tatsächlich nur die fünf diskreten Werte gibt, dann mag das okay sein; bei Messungen denke ich als Physiker aber eher an quasi-kontuinierliche Werte und eine Hysterese-Funktion für einen Trigger, also so, wie es Ishka gezeigt hat und wie's ein Digitaloszi auch ungefähr macht.
Crian
 2006-04-10 18:26
#64658 #64658
User since
2003-08-04
5872 Artikel
ModeratorIn
[Homepage]
user image
@Dubu Ja, das sollten nur fünf Beispielwerte sein. Natürlich sollte er dann abfragen, ob der gemessene Wert < 3 oder >= 3 ist und das im Kontext des States entsprechend verarbeiten. Ich dachte das wäre klar =)

@EagleFox: Ich nehme an, Deine Werte liegen irgendwie vor, in einem Array oder in einer Datei, die man Zeilenweise einliest und jeweils einen Wert ermittelt oder wie auch immer.

Dann nehme ich an, man ruft mit jedem dieser Werte eine Funktion auf. Diese Funktion gibt dann zurück, ob ein Flankenabfall vorliegt oder nicht.

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
my $state = 'start';
my $crit = 3;

sub f_ab {
my ($value) = @_;
my $return = 0;

if ($value >= $crit and $state ne 'high') {
$state = 'high;
}
elsif ($value < $crit and $state ne 'low') {
if ($state eq 'high) {
$return = 1;
}
$state = 'low';
}

retrun $return;
}

}
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
EagleFox
 2006-04-10 18:26
#64659 #64659
User since
2006-04-10
66 Artikel
BenutzerIn
[default_avatar]
Aha, ein Physiker. Bin ich übrigens auch.
Also, es geht hier um sehr große Datenmengen. In einer Datei (mit Header) sind ca. 10000 Spektren (jeweils durch zwei Leerzeilen getrennt) mit jeweils 10000 Datenpunkten und das ganze auf drei Kanälen (drei Spalten) plus einem Triggersignal (vierte Spalte). Nun möchte ich den ersten Teil der Spektren bis zur fallenden Flanke abschneiden und anschließend wieder hinten an das jeweilige Spektrum dranhängen.
Die steigende Flanke ist leider, wie oben beschrieben, sehr unscharf, die fallende aber sehr viel schärfer. Eine Flanke besteht aus mehreren hundert Datenpunkten. Daher kam mir die Idee, dass ich eine Funktion auf "set" setzen muss, wenn der Trigger (Lichtschranke), der eigentlich entweder 0 oder 5 Volt geben soll (jedoch um die Extremwerte +- 0,005 schwankt), einen Wert >4,9 oder >5 hat, um dann eine Stelle im Trigger zu suchen, die <3 ist. Dort soll das Abschneiden stattfinden.

Ich kann nur leider kein Perl! ;-(
Das Programm oben, macht genau das, was ich brauche, nur leider schneidet es solange ab, bis der Trigger einen Wert von >4 erreicht hat, was in der unscharfen steigenden Flanke geschiet und nicht bis die Flanke wieder runter geht! Mein Perl reicht nur nicht, dass ich das umschreiben kann.:blush:
<< |< 1 2 >| >> 18 Einträge, 2 Seiten



View all threads created 2006-04-10 15:44.