- Messages
- 1 909
- Réactions
- 284
- Points
- 309
Bonjour à tous,
second épisode dans mes tutos SIOC et aussi .lua
Au début, jutilisais un offset par fonction. Un offset d'une longueur de 1 comprend 8 bits qui sont numérotés de 0 à 7.
Le bit 0 correspond à la valeur 1, le bit 1 correspond à la valeur 2, le bit 2 correspond à la valeur 4 etc. Ce sont des puissances de 2. Autrement dit le bit 7 vaut 2 puissance de 7 soit 128.
Dans le code suivant OVH vaut donc 1.
Dans mon script .lua je vais vérifier cette valeur.
Si mon offset 3344 a une valeur de 1 alors on génère de lélectricité à partir de la puissance du moteur 1. Mon offset 3344 avec le bit 0 sera vu dans FSUIPC comme le bouton 0 du joystick 65. Je lassocie avec mon script .lua ci-dessus et ça marche.
Ce code a un inconvénient, je n'utilise par les bits 1, 2, 3, 4, 5, 6 et 7 ; quel gâchis.
Malheureusement, rien n'est jamais simple
On veut contrôler que le bit 0 est activé par mon interrupteur. Pour cela je le vérifie en observant la valeur de l'offset 3344. Quand un seul interrupteur est sur ON, tout va bien. Mais si j'active un autre interrupteur.
Quand je déclenche mon Générateur du moteur 4 mon offset 3344 va ajouter à la valeur courante 2 puissance de 1 soit 2. Comme le premier interrupteur est sur ON, mon offset va prendre la valeur 3 (1 + 2).
Mon script .lua
ne fonctionnera pas dans tous les cas puisque mon offset 3344 pourra prendre la valeur 1 ou 2 ou 3.
J'ai un peu pataugé, alors pour éviter une grande frustation, je vais vous expliquer comment faire.
Au lieu de tester : if ovh == 1 then, je vais vérifier par exemple que 3 contient 2 puissance de 0. On écrit par convention 2 ^ 0
Par exemple, si j'utilise 3 interrupteurs avec les bits 0, 1 et 2. Si j'active :
l'interrupteur 1, j'ai 1 (2 ^ 0)
les interrupteurs 1 et 2, j'ai 3 ( 2 ^ 0 + 2 ^ 1 )
les interrupteurs 1, 2 et 3, j'ai 7 ( 2 ^ 0 + 2 ^ 1 + 2 ^ 2 )
les interrupteurs 1 et 3, j'ai 5 ( 2 ^ 0 + 2 ^ 2 )
Ce qu'il faut arriver à faire c'est quand j'ai 5, quels sont les interrupteurs sur ON. Ben, 1 et 3. Oui mais on va le faire de manière mathématique car sinon, c'est lenfer.
C'est niveau math sup cette histoire ! Peut-être, mais Google est aussi mon ami
Mieux que Google, il y a Greg qui ma donné une solution plus simple.
La fonction if logic.And(ovh, 2 ^ 0) ~= 0 va tester que le bit 0 est vrai.
Certaines de mes LVAR sont des bascules simples. La même variable fait passer interrupteur de la position ON à OFF ou de OFF à ON en utilisant par exemple la commande ipc.writeLvar("L:fuel_l_inner_pump_feed_switch_clicked",1). Dans ce cas, pas besoin de faire de test.
Et voilà , super simple, hein
##################### Solution plus compliquée #####################
Ci-dessous la solution que j'avais trouvée que je conserve ici pour mémoire.
J'ai remplacé mon test par celui-ci : if hasbit(ovh, 2 ^ 0) then
Ce test utilise une fonction, hasbit qui est déclarée en tête de script
Cette fonction va retourner true (vrai) ou false (faux)
ovh = 5 et je dois tester si 5 contient le bit 0, soit 2 ^ 0
La fonction va vérifier que : 5 % (1+1) >= 1
% est un modulo ou dit plus simplement le reste d'une division. 5 / 2 = 2 reste 1. Si je souhaite savoir le reste je peux écrire plus simplement : 5 % 2 et le résultat est 1
Ce qui veut dire ici que la condition est vrai puisque le reste de la division de 5 / 2 est égale ou supérieure à 1 ; jexécute donc la commande : ipc.writeLvar("L:elec_gen1_switch_clicked",1).
second épisode dans mes tutos SIOC et aussi .lua
Au début, jutilisais un offset par fonction. Un offset d'une longueur de 1 comprend 8 bits qui sont numérotés de 0 à 7.
Le bit 0 correspond à la valeur 1, le bit 1 correspond à la valeur 2, le bit 2 correspond à la valeur 4 etc. Ce sont des puissances de 2. Autrement dit le bit 7 vaut 2 puissance de 7 soit 128.
Dans le code suivant OVH vaut donc 1.
Code:
[== SIOC ==]
Var 500, name OVH, Link FSUIPC_INOUT, Offset $3344, Length 1
Var 501, name GEN1_SW, Link IOCARD_SW, Input 0
{
IF &GEN1_SW = 0
{
&OVH = SETBIT 0
}
ELSE
{
&OVH = CLEARBIT 0
}
}
Dans mon script .lua je vais vérifier cette valeur.
Code:
[== LUA ==]
-- bouton 0
ovh= ipc.readUB(0x3344)
if ovh == 1 then
ipc.writeLvar("L:elec_gen1_switch_clicked",1)
else
ipc.writeLvar("L:elec_gen1_switch_clicked",2)
end
Si mon offset 3344 a une valeur de 1 alors on génère de lélectricité à partir de la puissance du moteur 1. Mon offset 3344 avec le bit 0 sera vu dans FSUIPC comme le bouton 0 du joystick 65. Je lassocie avec mon script .lua ci-dessus et ça marche.
Ce code a un inconvénient, je n'utilise par les bits 1, 2, 3, 4, 5, 6 et 7 ; quel gâchis.
Malheureusement, rien n'est jamais simple
On veut contrôler que le bit 0 est activé par mon interrupteur. Pour cela je le vérifie en observant la valeur de l'offset 3344. Quand un seul interrupteur est sur ON, tout va bien. Mais si j'active un autre interrupteur.
Code:
[== SIOC ==]
Var 503, name GEN4_SW, Link IOCARD_SW, Input 3
{
IF &GEN4_SW = 1
{
&OVH= SETBIT 1
}
ELSE
{
&OVH= CLEARBIT 1
}
}
Quand je déclenche mon Générateur du moteur 4 mon offset 3344 va ajouter à la valeur courante 2 puissance de 1 soit 2. Comme le premier interrupteur est sur ON, mon offset va prendre la valeur 3 (1 + 2).
Mon script .lua
Code:
[== LUA ==]
-- bouton 0
ovh= ipc.readUB(0x3344)
if ovh == 1 then
ipc.writeLvar("L:elec_gen1_switch_clicked",1)
else
ipc.writeLvar("L:elec_gen1_switch_clicked",2)
end
ne fonctionnera pas dans tous les cas puisque mon offset 3344 pourra prendre la valeur 1 ou 2 ou 3.
J'ai un peu pataugé, alors pour éviter une grande frustation, je vais vous expliquer comment faire.
Au lieu de tester : if ovh == 1 then, je vais vérifier par exemple que 3 contient 2 puissance de 0. On écrit par convention 2 ^ 0
Par exemple, si j'utilise 3 interrupteurs avec les bits 0, 1 et 2. Si j'active :
l'interrupteur 1, j'ai 1 (2 ^ 0)
les interrupteurs 1 et 2, j'ai 3 ( 2 ^ 0 + 2 ^ 1 )
les interrupteurs 1, 2 et 3, j'ai 7 ( 2 ^ 0 + 2 ^ 1 + 2 ^ 2 )
les interrupteurs 1 et 3, j'ai 5 ( 2 ^ 0 + 2 ^ 2 )
Ce qu'il faut arriver à faire c'est quand j'ai 5, quels sont les interrupteurs sur ON. Ben, 1 et 3. Oui mais on va le faire de manière mathématique car sinon, c'est lenfer.
C'est niveau math sup cette histoire ! Peut-être, mais Google est aussi mon ami
Mieux que Google, il y a Greg qui ma donné une solution plus simple.
Code:
[== LUA ==]
ovh = ipc.readUB(0x3340)
if logic.And(ovh, 2 ^ 0) ~= 0 then
ipc.writeLvar("L:elec_gen1_switch_clicked",1)
else
ipc.writeLvar("L:elec_gen1_switch_clicked",2)
end
La fonction if logic.And(ovh, 2 ^ 0) ~= 0 va tester que le bit 0 est vrai.
Certaines de mes LVAR sont des bascules simples. La même variable fait passer interrupteur de la position ON à OFF ou de OFF à ON en utilisant par exemple la commande ipc.writeLvar("L:fuel_l_inner_pump_feed_switch_clicked",1). Dans ce cas, pas besoin de faire de test.
Et voilà , super simple, hein
##################### Solution plus compliquée #####################
Ci-dessous la solution que j'avais trouvée que je conserve ici pour mémoire.
Code:
[== LUA ==]
function hasbit(x, p)
return x % (p + p) >= p
end
-- bouton 23
ovh = ipc.readUB(0x3340)
if hasbit(ovh, 2 ^ 0) then
ipc.writeLvar("L:elec_gen1_switch_clicked",1)
else
ipc.writeLvar("L:elec_gen1_switch_clicked",2)
end
J'ai remplacé mon test par celui-ci : if hasbit(ovh, 2 ^ 0) then
Ce test utilise une fonction, hasbit qui est déclarée en tête de script
Code:
[== LUA ==]
function hasbit(x, p)
return x % (p + p) >= p
end
Cette fonction va retourner true (vrai) ou false (faux)
ovh = 5 et je dois tester si 5 contient le bit 0, soit 2 ^ 0
La fonction va vérifier que : 5 % (1+1) >= 1
% est un modulo ou dit plus simplement le reste d'une division. 5 / 2 = 2 reste 1. Si je souhaite savoir le reste je peux écrire plus simplement : 5 % 2 et le résultat est 1
Ce qui veut dire ici que la condition est vrai puisque le reste de la division de 5 / 2 est égale ou supérieure à 1 ; jexécute donc la commande : ipc.writeLvar("L:elec_gen1_switch_clicked",1).