nefungující omezení proměnné

Vítek
Příspěvky: 26
Registrován: 05 pro 2018, 17:47
Bydliště: Kladno
Kontaktovat uživatele:

nefungující omezení proměnné

Příspěvek od Vítek »

zdravím,

v jednom ze svých projektů potřebuji omezit hodnotu proměnné W0 (pontb) k vytváření hodnoty pro příkaz pwmduty na hodnoty od 1 do 1023, horní hranice bez problémů funguje a zvětšování se čísla se vždy zastaví na 1023, ale ta spodní nedělá absolutně nic a číslo vždy dojde až na nulu a poté na číslo 65527.

tady je kus kódu ve kterém je problém:

Kód: Vybrat vše

lustrop:
irin [3000,ovladac],ir,irb
select case irb
case 17
let pontb=pontb-10 min 1

case 16
let pontb=pontb+10 max 1023

case 73
pontb=1023

case 74
pontb=0

end select

let irb=0
pwmduty lustr,pontb
goto lustrop
myslím že je to zbytečné, ale raději zde přiložím i celý kód, ale místy je trochu zmatený:

Kód: Vybrat vše

;p - program
;b - promená

;out:
symbol lustr=B.1
symbol modra=C.3
symbol zluta=c.2

symbol dvV=B.5
symbol peV=B.4

symbol rep=B.3
symbol ledz=C.4
symbol ledc=C.0
;in:
symbol pont=B.6
symbol ir=B.0

symbol tl1=pinC.7
symbol tl2=pinC.6
symbol tl3=pinB.7

;proměnné:
symbol irb=B3
symbol pontb=W0
symbol ovl=B4 ;1=deska 2=ovladac tv 3=pic ovl (250=stisk)








init:
let ovl=1
pwmout C.2,150,100 ; inicializuj modul pwm
pwmout C.3,150,100
pwmout B.1,150,100


start:
select case ovl
case 1
gosub deska

case 2
gosub ovladac

end select
goto start


deska:
readadc10 pont, pontb
if tl3=1 then let ovl=250 gosub lustrp endif
if tl1=1 then let ovl=250 gosub modrap endif
if tl2=1 then let ovl=250 gosub zlutap endif

if ovl=250 then let ovl=1 goto deska end if
irin [200],ir,irb
if irb=21 then let ovl=2 low ledz high ledc sound rep,(50,50) endif
return

ovladac:
irin [50],ir,irb
select case irb

case 1
high dvV
sound rep,(100,10)
let irb=0

case 2
low dvV
sound rep,(100,50)
let irb=0

case 4
high peV
sound rep,(100,10)
let irb=0

case 5
low peV
sound rep,(100,50)
let irb=0

case 6
gosub modraop

case 7
gosub zlutaop

case 8
gosub lustrop

end select

if tl1=1 then let ovl=1 let irb=0 low ledc high ledz sound rep,(50,50) endif

return


lustrp:
pwmduty lustr,pontb ; nastav činitel plnění
return

modrap:
pwmduty modra,pontb ; nastav činitel plnění
return

zlutap:
pwmduty zluta,pontb ; nastav činitel plnění
return

modraop:
irin [3000,ovladac],ir,irb
debug
select case irb

case 17
let pontb=pontb-10 min 1
debug

case 16
let pontb=pontb+10 max 1023

case 73
pontb=1023

case 74
pontb=0

end select

let irb=0
pwmduty modra,pontb
goto modraop

zlutaop:
irin [3000,ovladac],ir,irb
select case irb
case 17
let pontb=pontb-10 min 1

case 16
let pontb=pontb+10 max 1023

case 73
pontb=1023

case 74
pontb=0

end select
let irb=0
pwmduty zluta,pontb
goto zlutaop

lustrop:
irin [3000,ovladac],ir,irb
select case irb
case 17
let pontb=pontb-10 min 1

case 16
let pontb=pontb+10 max 1023

case 73
pontb=1023

case 74
pontb=0

end select
let irb=0
pwmduty lustr,pontb
goto lustrop
Naposledy upravil(a) Vítek dne 19 bře 2019, 21:48, celkem upraveno 1 x.
Vítek
Příspěvky: 26
Registrován: 05 pro 2018, 17:47
Bydliště: Kladno
Kontaktovat uživatele:

Re: nefungující omezení proměnné

Příspěvek od Vítek »

Teď jsem ještě zkoušel pro omezení další čísla a nejnižší které funguje je číslo 10, to je ale moc vysoké na to, abych jej mohl použít.
DavidO
Příspěvky: 1133
Registrován: 01 kvě 2013, 21:27

Re: nefungující omezení proměnné

Příspěvek od DavidO »

Vyhodnocení příkazu let pontb=pontb-10 min 1 se dělá striktně odleva. Takže se nejdřív spočte pontb-10, což pro čísla menší než 10 podteče pod nulu a tedy se zalomí přes 65535, a teprve pak se kontroluje, jestli to není míň, než 1. A to není a výsledek se nechá těch 655xx. Takhle to dopadne pro skoro všechna počáteční čísla, až na násobky desítky, kdy se postupně po těch desítkách sleze až na něco mezi 1-9 a v dalším kroku vyjde něco mezi 65527 a 65535. Pokud se náhodou povede, že se začínalo na celých desítkách, tak to po desítkách sleze k nule, ta je menší než 1 a tedy se z toho udělá jednička, no a v dalším kroku se spočte 1-10 a jsme tam, co jsme byli.
Nikoho plánovaně neurážím. Jestli se Vám nelíbí co píšu, tak to nečtěte. A ostatně, třeba za to nemůžu - Researchers believe that dark humor can be a significant symptom of dementia.
DavidO
Příspěvky: 1133
Registrován: 01 kvě 2013, 21:27

Re: nefungující omezení proměnné

Příspěvek od DavidO »

Nestačilo by

Kód: Vybrat vše

IF pontb > 10 THEN 
pontb = pontb-10
ENDIF
?
Není to sice na jeden řádek, ale to ve výsledné velikosti kódu nehraje roli. Holt on Picaxe basic není úplně geniální jazyk, no.
Nikoho plánovaně neurážím. Jestli se Vám nelíbí co píšu, tak to nečtěte. A ostatně, třeba za to nemůžu - Researchers believe that dark humor can be a significant symptom of dementia.
Vítek
Příspěvky: 26
Registrován: 05 pro 2018, 17:47
Bydliště: Kladno
Kontaktovat uživatele:

Re: nefungující omezení proměnné

Příspěvek od Vítek »

Bohužel nestačilo, to že to není na jeden řádek nevadí, ale minimální hodnota je 11 a led pásky, které tento kus programu stmívá se zhasnou až na hodnotě 0
Uživatelský avatar
gilhad
Příspěvky: 262
Registrován: 29 kvě 2015, 00:36
Kontaktovat uživatele:

Re: nefungující omezení proměnné

Příspěvek od gilhad »

Tak pred to jeste dej test na hodnoty pod 11:

Kód: Vybrat vše

IF pontb < 11 THEN 
pontb = 1
ENDIF
; tim se udela to min 1 pro cisla, kde 10 nejde plne odecist aniz by to podteklo

IF pontb > 10 THEN 
pontb = pontb-10
ENDIF
; jinak se to zmensi o 10 a bude to urcite vetsi rovno jedne


Vítek
Příspěvky: 26
Registrován: 05 pro 2018, 17:47
Bydliště: Kladno
Kontaktovat uživatele:

Re: nefungující omezení proměnné

Příspěvek od Vítek »

gilhad píše: 20 bře 2019, 01:26

Kód: Vybrat vše

IF pontb < 11 THEN 
pontb = 1
ENDIF
; tim se udela to min 1 pro cisla, kde 10 nejde plne odecist aniz by to podteklo

IF pontb > 10 THEN 
pontb = pontb-10
ENDIF
; jinak se to zmensi o 10 a bude to urcite vetsi rovno jedne


Děkuji všem za ochotu, toto již funguje jen jsem musel změnit pontb = 1 na pontb = 0, aby světlo úplně zhaslo.
kdyby někoho zajímala celá současná verze programu zde je:

Kód: Vybrat vše

;p - program
;b - promená
;out:
symbol lustr=B.1    ;ledpásek (přes tranzistor)
symbol modra=C.3  ;bílý ledpásek do modra (přes tranzistor)
symbol zluta=c.2     ;bílý ledpásek do žluta nádechem (přes tranzistor)

symbol dvV=B.5 ;relé ovládající výstup 5V
symbol peV=B.4 ;relé ovládající výstup 12V

symbol rep=B.3 ;piezo reproduktor
symbol ledz=C.4 ;červená led
symbol ledc=C.0 ;zelená led
;in:
symbol pont=B.6 ;vstup potenciometru
symbol ir=B.0 ;vstup infrapřijímače

symbol tl1=pinC.7 ;tlečitko, stisk=1
symbol tl2=pinC.6 ;tlečitko, stisk=1
symbol tl3=pinB.7 ;tlečitko, stisk=1

;proměnné:
symbol irb=B3
symbol pontb=W0
symbol ovl=B4 ;1=deska 2=ovladac tv 3=pic ovl (250=stisk)








init:
let ovl=1
pwmout C.2,150,100 ; inicializuj modul pwm
pwmout C.3,150,100
pwmout B.1,150,100


start:
select case ovl
case 1
gosub deska

case 2
gosub ovladac

end select
goto start


deska:
readadc10 pont, pontb
if tl3=1 then let ovl=250 gosub lustrp endif
if tl1=1 then let ovl=250 gosub modrap endif
if tl2=1 then let ovl=250 gosub zlutap endif

if ovl=250 then let ovl=1 goto deska end if
irin [200],ir,irb
if irb=21 then let ovl=2 low ledz high ledc sound rep,(50,50) endif
return

ovladac:
irin [50],ir,irb
select case irb

case 1
high dvV
sound rep,(100,10)
let irb=0

case 2
low dvV
sound rep,(100,50)
let irb=0

case 4
high peV
sound rep,(100,10)
let irb=0

case 5
low peV
sound rep,(100,50)
let irb=0

case 6
gosub modraop

case 7
gosub zlutaop

case 8
gosub lustrop

end select

if tl1=1 then let ovl=1 let irb=0 low ledc high ledz sound rep,(50,50) endif

return


lustrp:
pwmduty lustr,pontb ; nastav činitel plnění
return

modrap:
pwmduty modra,pontb ; nastav činitel plnění
return

zlutap:
pwmduty zluta,pontb ; nastav činitel plnění
return

modraop:
irin [3000,ovladac],ir,irb
select case irb

case 17
IF pontb < 11 THEN let pontb=0 ENDIF
IF pontb > 10 THEN let pontb=pontb-10 ENDIF

case 16
let pontb=pontb+10 max 1023

case 73
pontb=1023

case 74
pontb=0

end select

let irb=0
pwmduty modra,pontb
goto modraop



zlutaop:
irin [3000,ovladac],ir,irb
select case irb
case 17
if pontb < 11 THEN let pontb=0 endif
if pontb > 10 THEN let pontb=pontb-10 endif

case 16
let pontb=pontb+10 max 1023

case 73
pontb=1023

case 74
pontb=0

end select
let irb=0
pwmduty zluta,pontb
goto zlutaop




lustrop:
irin [3000,ovladac],ir,irb
select case irb
case 17
if pontb < 11 THEN let pontb=0 endif
if pontb > 10 THEN let pontb=pontb-10 endif

case 16
let pontb=pontb+10 max 1023

case 73
pontb=1023

case 74
pontb=0

end select
let irb=0
pwmduty lustr,pontb
goto lustrop
Vladimir66
Příspěvky: 385
Registrován: 02 dub 2014, 15:30

Re: nefungující omezení proměnné

Příspěvek od Vladimir66 »

hloupy dotaz:
muze se pouzit namisto " let pontb=pontb-10 min 1 " toto " let pontb=pontb-10 min 0 "
(kdyz se zhasina na nulu a ne na jednicku)

tak nic, uz vyreseno :)
Vítek
Příspěvky: 26
Registrován: 05 pro 2018, 17:47
Bydliště: Kladno
Kontaktovat uživatele:

Re: nefungující omezení proměnné

Příspěvek od Vítek »

Samozřejmě, zhasíná li se na nule, je potřeba použít let pontb=pontb-10 min 0, ale tady je problém v tom, že to přeteče jak psal DavidO:
DavidO píše: 19 bře 2019, 21:49 Vyhodnocení příkazu let pontb=pontb-10 min 1 se dělá striktně odleva. Takže se nejdřív spočte pontb-10, což pro čísla menší než 10 podteče pod nulu a tedy se zalomí přes 65535, a teprve pak se kontroluje, jestli to není míň, než 1. A to není a výsledek se nechá těch 655xx. Takhle to dopadne pro skoro všechna počáteční čísla, až na násobky desítky, kdy se postupně po těch desítkách sleze až na něco mezi 1-9 a v dalším kroku vyjde něco mezi 65527 a 65535. Pokud se náhodou povede, že se začínalo na celých desítkách, tak to po desítkách sleze k nule, ta je menší než 1 a tedy se z toho udělá jednička, no a v dalším kroku se spočte 1-10 a jsme tam, co jsme byli.
mám-li v pontb třeba 5 vypadá to takto: 5-10=65530 a to je víc než 10
DavidO
Příspěvky: 1133
Registrován: 01 kvě 2013, 21:27

Re: nefungující omezení proměnné

Příspěvek od DavidO »

Vítek píše: 19 bře 2019, 22:12 Bohužel nestačilo, to že to není na jeden řádek nevadí, ale minimální hodnota je 11 a led pásky, které tento kus programu stmívá se zhasnou až na hodnotě 0
Žádnej problém. Zapiš to tak, jak o tom přemýšlíš - jestli to je větší jak 10 tak se to o 10 sníží,. a když ne, tak se to srazí na nulu:

Kód: Vybrat vše

IF pontb > 10 THEN 
pontb = pontb-1
ELSE
pontb = 0
ENDIF
Nikoho plánovaně neurážím. Jestli se Vám nelíbí co píšu, tak to nečtěte. A ostatně, třeba za to nemůžu - Researchers believe that dark humor can be a significant symptom of dementia.
Odpovědět