Ok, bij gebrek aan code zet ik de glazenbol modus aan
Volgens mij hoef je helemaal niets met bits te pielen.
- Je hebt een afstandsbediening met knoppen omhoog / omlaag.
- De luiken worden blijkbaar gestuurd, door een relais aan te zetten, even te wachten en dan de motor in een richting te laten draaien
- Na een tijdje stopt die (luik is helemaal open of dicht, of door een tegengestelde knop richting)
- Na een bepaalde tijd kan het relais dus weer uit, omdat het luik stil zou moeten staan.
Ik denk dat je dat met een paar array's beter kan oplossen
Een array voor de knoppen (niets ingedrukt, omhoog, omlaag), met de laatste knop opdracht (zolang het relais aanstaat)
En een array met de luik status (relais uit, omhoog, omlaag)
Een array met relais tijden wanneer die uit kan.
- Als je een knop indrukt, controleer je of het nieuwe knop opdracht is
- Als het relais uit staat, zet je die eerst aan. En bepaal je de stop tijd
- Dan geef je de motor de opdracht
- Zet het luik status gelijk aan de knop status
Na een tijdje kan het relais weer uit en zet je de statussen van het luik en knop weer op "uit"
Zoiets dus:
C:
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
| #define KNOP_NIET_INGEDRUKT 0
#define RELAIS_UIT 0
#define OMHOOG 1
#define OMLAAG 2
#define GESTOPT 4
int knop_status[aantal_luiken];
int luik_status[aantal_luiken];
tijd relais_tijd[aantal_luiken];
for (i = 0; i < aantal_luiken; i++) {
knop_status[i] = KNOP_NIET_INGEDRUKT;
luik_status[i] = RELAIS_UIT;
relais_tijd[i] = 0;
}
while (true) {
// Ga alle knoppen op de afstandsbediening af
knop_status[i] = KNOP_NIET_INGEDRUKT;
if (knop_luik_1_omhoog_ingedrukt) {
knop_status[0] = OMHOOG;
|
if (knop_luik_1_naar_beneden_ingedrukt && !knop_luik_1_omhoog_ingedrukt) {
knop_status[0] = OMLAAG;
}
// en zo voor alle knoppen op de afstandsbediening
// controle nieuwe opdracht
for (i = 0; i < aantal_luiken; i++) {
if (knop_status[i] == KNOP_NIET_INGEDRUKT && (luik_status[i] | GESTOPT)) {
// Als je een tegengestelde beweging hebt ingedrukt,
// dan, als je de knop weer loslaat, de richting van het luik vergeten
luik_status[i] = GESTOPT;
*** doe hier een kleine wachtlus ***
// Als je namelijk 2x snel de tegengestelde richting klikt, wil je toch
// die richting op, maar de motor moet wel tijd hebben om dat ook te
// kunnen volgen
continue;
}
if ((knop_status[i] == KNOP_NIET_INGEDRUKT) ||
(knop_status[i] & luik_status[i] & OMHOOG + OMLAAG)) {
// niets ingedrukt, of dezelfde knop nog steeds / opnieuw ingedrukt
continue;
}
// Er is een knop ingedrukt en het is een nieuwe opdracht
// Controleer of het relais aan staat
if (luik_status[i] == RELAIS_UIT)) {
*** Zet het juiste relais aan en wacht even ***
}
// zet de uiterste relay tijd (na elke nieuwe knop opdracht)
relais_tijd[i] = nu + maximale looptijd
if (knop_status[i] == OMHOOG) {
*** Schakel de uitgaande lijn voor motor omhoog ***
}
if (knop_status[i] == OMLAAG) {
*** Schakel de uitgaande lijn voor motor omlaag ***
}
if (luik_status[i] == RELAIS_UIT) {
// Nieuwe beweging
luik_status[i] = knop_status[i];
} else {
// Tegengestelde beweging, daarmee zou de motor moeten stoppen
if (luik_status[i] == OMHOOG) {
luik_status[i] = OMLAAG;
} else {
luik_status[i] = OMHOOG;
}
luik_status[i] += GESTOPT; // stop, maar onthoud wel de richting
}
}
// Kan een relais uit
for (i = 0; i < aantal_luiken; ++) {
if ((luik_status[i] != RELAIS_UIT) && (nu > relais_tijd[i])) {
// Luik zou gestopt moeten zijn
// (helemaal beneden, boven, of door tegengestelde knop)
*** Zet het relais uit ***
luik_status[i] = RELAIS_UIT;
knop_status[i] = KNOP_NIET_INGEDRUKT;
}
}
// Ga even een paar tiende seconde uit je neus vreten of zo
} |
Sowieso vind ik dit nog best lastig om goed in mijn hoofd te krijgen.
Aangezien je geen feedback van de motor krijgt, moet je de status maar aannemen.
Daar gaat 100 jaar PLC programmeer ervaring je nog niet bij helpen.
Klik eens snel op-neer-op, dat gaat de motor niet altijd bijhouden en geen idee wat de status is (omhoog of nog steeds in stilstand?)
Of als het luik al open is en je drukt op-neer (luik gaat naar beneden, programma denkt: gestopt)
Hoe dan ook zal je programma dus aan elkaar hangen van aannames.
En gaat af en toe (tot het relais weer uitschakelt) iets niet doen, wat jij wil.
-edit tig-
@farlane hieronder (en om niet onder creepy te posten en toch antwoord)
Hmm, ja misschien heb je gelijk
Ok, dan een voorbeeldje met bit AND, OR, NOT en shift (en haakjes en accolades):
C:
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
| luik
3 1
4 2
sig_up = 0b0101 // luik 3 en 1 gaan omhoog
sig_down = 0b0010 // luik 2 gaat naar beneden
bit_nr = 0; // Luik 1
// Zet signaal van een luik naar omlaag
set_sig_down(bit_nr) {
// sig_up bit van luik uit (just to be sure):
// NOT luik bit en AND die hele waarde met de oude
sig_up &= ~(1 << bit_nr); // sig_up: 0b0100, alleen 3 omhoog
// sig_down bit van luik aan (of aanlaten als dat al zo was)
// OR waarde met luik bit
sig_down |= 1 << bit_nr; // sig_down: 0b0011, 2 en 1 omlaag
}
// Zet signaal van een luik naar omhoog
set_sig_up(v) {
sig_down &= ~(1 << bit_nr); // bit down uit
sig_up |= 1 << bit_nr; // bit up aan
}
// Zet signaal van een luik uit
reset_sig(bit_nr) {
sig_up &= ~(1 << bit_nr); // bit up uit;
sig_down &= ~(1 << bit_nr); // bit down uit
} |
Of alle signalen in 1 waarde:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| luik
3 1 3 1
4 2 4 2
DOWN UP
signal = 0bxxxx0010xxxx0101 // luik 3 en 1 gaan omhoog, 2 omlaag
LSB_UP = 0
LSB_DOWN = 8
index = 0; // luik 1
set_sig_down(index) {
signal &= ~(1 << (index + LSB_UP)); // bit up uit
signal |= 1 << (index + LSB_DOWN); // bit down aan
}
set_sig_up(index) {
signal &= ~(1 << (index + LSB_DOWN)); // bit down uit
signal |= 1 << (index + LSB_UP); // bit up aan
} |
Of desnoods nog met een macro
C:
1
2
3
4
5
| #define BITVALUE(bit_nr) (1 << (bit_nr))
set_sig_down(index) {
signal &= ~BITVALUE(index + LSB_UP); // bit up uit
signal |= BITVALUE(index + LSB_DOWN); // bit down aan
} |
[
Voor 43% gewijzigd door
Vaan Banaan op 26-04-2020 18:27
]