View previous topic :: View next topic |
Author |
Message |
kinjark
Joined: 06 Mar 2017 Posts: 10
|
Posted: Mon Apr 03, 2017 7:53 pm Post subject: Do something when var changes |
|
|
Dear MCSelec community,
the purpose is that I want to change 1 var when I press the button (Incr) and I want to use CLS if that var changes. Only once. I would also use that for example when pin = 1 then A=1 but I would like to incr A even if pin = 1. Pin would just set A back to 1 to start again.
So like if var C is not same as C in the previous cycle, or also maybe if one condition was true, but now it is not anymore and then again when it comes true. If I put cls in the code, it would clear all the time and it is annoying.
At the moment I used:
Code: |
Config Timer0 = Timer , Prescale = 64
On Timer0 Casovnik
Enable Timer0
Casovnik:
If C = 1 OR C = 2 OR C = 3 OR C = 4 then 'C is the var I change by pressing the button'
Cas4 = Cas4 + 1
If Cas4 >= 201 Then
Cas4= 0
End If
end if
If Cas4 = 200 then D = C 'D is only there so I have delay for cls'
If D <> C and Cas4 = 50 then cls
|
the problem is that sometime is working ok and sometimes not as it should or I would want to. If I scroll menu fast it doesn't cls.
I can post whole code but it is quite big and it is hard to find stuff.
(BASCOM-AVR version : 2.0.7.8 ) |
|
Back to top |
|
|
EDC
Joined: 26 Mar 2014 Posts: 971
|
Posted: Mon Apr 03, 2017 8:43 pm Post subject: |
|
|
I was try to understand question but..I dont understant it maybe.
But I have a tip:
Code: | Dim Value As Byte, Old_value As Byte
If Old_value <> Value Then
' do wanted staff
'...
Old_value = Value ' alignment values for purpose of doing this only once if they differ
End If |
|
|
Back to top |
|
|
kinjark
Joined: 06 Mar 2017 Posts: 10
|
Posted: Mon Apr 03, 2017 9:40 pm Post subject: |
|
|
EDC wrote: | I was try to understand question but..I dont understant it maybe.
But I have a tip:
Code: | Dim Value As Byte, Old_value As Byte
If Old_value <> Value Then
' do wanted staff
'...
Old_value = Value ' alignment values for purpose of doing this only once if they differ
End If |
|
Interrupts are enabled so I think this won't work.
For example:
Code: |
Config Timer0 = Timer , Prescale = 64
On Timer0 Casovnik
Enable Timer0
Casovnik:
Cas1 = Cas1 + 1
If Cas1 >= 490 Then
Cas1= 0
End If
If Cas1 = 1 then
Incr A
If A => 10 then A=0
End if |
How can I say if pina.0 = 0 then A = 1, but even if pina.0 is still 0 the cycle would incr A with pina.0 staying 0.
If I say
if pina.0=0 then A = 1
incr A
So I have a problem because it will stay 1 because condition is still true.
I need so when I press button I will incr C and for each number of C I have a menu on LCD that is shown. But I want to cls LCD only when C increases. if C = 3 and I incr C to 4, I want to cls only once, even if C is still 4. If I say If C=4 then cls it will cls every cycle (490 times a second) because C is still 4.
Same problem is with Incr. If I say: if pinA.0 = 0 then incr C and with interrupts means it will increase for 490 every second until pina.0 <> 0. I want C to be increased only once even if pina.0 is still 0. |
|
Back to top |
|
|
EDC
Joined: 26 Mar 2014 Posts: 971
|
Posted: Mon Apr 03, 2017 10:13 pm Post subject: |
|
|
Please post the code (short as possible but that show the issue)
For reading more than one pin from port I use pinmasks
Code: |
Const Sw_mask = &B00011110 'checked will be bits/pins 1,2,3 and 4
Sw_state = Pinb And Sw_mask
If Sw_state <> Sw_mask Then
End If
|
To understand how switches can be handle look at this short one button example.
Code: | ' This code toggle Led_1 after short push on Switch and toggle Led_2 when Switch is push and hold for long
$regfile = "m16def.dat"
$crystal = 8000000
$hwstack = 32
$swstack = 16
$framesize = 64
Config Porta.6 = Output : Led_1 Alias Porta.6
Config Porta.7 = Output : Led_2 Alias Porta.7
Config Porta.0 = Input : Set Porta.0 : Switch Alias Pina.0
Dim Sw_cnt As Byte , Lock As Byte
Config Timer2 = Timer , Prescale = 1024 , Compare = Disconnect , Clear_timer = 1
COMPARE2 = 77 '10ms @8MHz/1024
Do
If Tifr.ocf2 = 1 Then 'the 10ms is past, this flag set the Timer
Tifr.ocf2 = 1 'clearing the flags is done by writing ones NOT ZEROS!
If Switch = 0 Then 'if button is pressed
If Lock = 0 Then 'and lock is not triggered
If Sw_cnt < 50 Then 'we increase sw_counter if long_push value not reached
Incr Sw_cnt 'increasing counter
Else 'but if we hold button long..
Lock = 1 'lock increasing the counter
Toggle Led_2 '->and change state of LED_2 because it is long_push
End If
End If
Else '..if button is released
If Lock = 0 Then ' and previous,it was not a long push activity
If Sw_cnt > 3 Then Toggle Led_1 'check if button was pressed atleast 3 periods (3x10ms)
End If '->toggle LED_1 because it was short click
Lock = 0 : Sw_cnt = 0 'clear lock and counter
End If
End If
Loop
End |
This can be easy adapted for more switches or autorepeat action when buttons holded for long. |
|
Back to top |
|
|
kinjark
Joined: 06 Mar 2017 Posts: 10
|
Posted: Tue Apr 04, 2017 7:48 am Post subject: |
|
|
I will try if I can use your button/switch thing, it will definitely help me for some cases but it is hard to see it from my code because it is not working
Code: |
Enable Interrupts
Config Timer0 = Timer , Prescale = 64
On Timer0 Casovnik : Enable Timer0
Config Debounce = 20
Count = 1
wait 5
cls
B=0
C=1
Do
Debounce tipkaparametri , 0 , meni , Sub
If 0 < Ischarwaiting() Then
Inputbin Array(count) , 1
Timeout = 100
If Count < 17 Then
Incr Count
Else
|
If you remember you helped me with that transmission.
Code: |
'Meni za prikaz stanja vode v rezervarju'
If C = 1 then
Locate 1 , 1 : Lcd "Meritve vode: ";B;
Locate 1 , 20 : Lcd ;A;
Locate 2 , 2 : Lcd "Globina: " ; SP3 ;" cm "
Locate 3 , 2 : Lcd "Volumen: " ; Fusing(CUB1 , "#.###") ;" m"; Chr(4) ;" "
Locate 4 , 2 : Lcd "Nivo v %: " ; Fusing(procenti , "#.#") ;" % "
Locate 4 , 20 : Lcd ;C;
End if
'Osnovni meni'
If C = 2 then
Locate 1 , 1 : Lcd "*** STANJE VODE ***"
Locate 2 , 1 : Lcd "Breznica pod"
Locate 3 , 1 : Lcd " Lubnikom 15 "
Locate 4 , 8 : Lcd ;Fusing(procenti , "#.#") ;" %"
Locate 4 , 20 : Lcd ;C;
If procenti > 99 and pretokaktiven <> 0 then
Locate 4 , 4 : Lcd ;Chr(7);;Chr(7);;Chr(7);
end if
If procenti =< 99 and procenti > 98 and pretokaktiven <> 0 then
Locate 4 , 5 : Lcd ;Chr(7);;Chr(7);
end if
If procenti =< 98 and procenti => 97 and pretokaktiven <> 0 then
Locate 4 , 6 : Lcd ;Chr(7);
end if
if pretokaktiven = 0 then
Locate 4 , 4 : Lcd ;Chr(5);;Chr(5);;Chr(5);
end if
end if
|
So when I press the button I increase C, If C=1 then I have the first menu and if C=2 then it shows second menu.
When I press button, menu 1 will appear for example but if I press it again menu 2 will have some letters remaining from menu 1 because I don't have cls. If I put cls at the beginning of every menu, then menu will be blinking. What I want to do is that if I change the menu, I would cls so I don't have anything from previous menu, but then I do not cls unless I change the menu again.
The other part is that I have some signs for inputs. If I have some inputs active I have some arrows on my LCD (different for every input), but sometimes no input is active then I want to cls to remove all arrows. But only once not every time when atmega will read that pinc.0=0 because I would get blinking all the time again.
Code: |
Else
Cls
Lcd "";Chr(1);"akam povezavo..."
End If
Count = 1
End If
End If
Waitms 1
'this will set array pointer to start if not whole array arrive on time
If Timeout > 0 Then
Decr Timeout
Else
Count = 1
End If
Loop
Casovnik:
'Nastavitev 1 sekunde za Incr A intervala'
Cas1 = Cas1 + 1
If Cas1 >= 490 Then 'Nastavitev zakasnitve, št. ciklov po 64, ker PS=64'
Cas1= 0
End If
If Cas1 = 1 then
Incr A
If A => 10 then A=0
End if
'Nastavitev cls'
If C = 1 OR C = 2 OR C = 3 OR C = 4 then
Cas4 = Cas4 + 1
If Cas4 >= 201 Then 'Nastavitev zakasnitve, št. ciklov po 64, ker PS=64'
Cas4= 0
End If
end if
If Cas4 = 200 then D = C
If D <> C and Cas4 = 199 then cls
Return
Meni:
incr C
if C => 5 then C = 1
Return
|
This is just the end with timers, that I used so far. For example every second I increase A from 1 to 10. Is it possible to say if pinc.0=0 then A=1, but continues to count up to 10 even if pinc.0 stays = 0. Because if I write If pinc.0 = 0 then A=1, A will remain 1 and it will not increase until pinc.0 <> 0.
Whole file is attached in txt just in case.
Many thanks for your help already! |
|
Back to top |
|
|
EDC
Joined: 26 Mar 2014 Posts: 971
|
Posted: Tue Apr 04, 2017 10:41 am Post subject: |
|
|
If I understand the code enough program refresh LCD only if new data arrive and You want to view diferrent menu pages/values from that one transmission.
You also want to update some view with timer, and it would be nice to update LDC with button
This can be easy done. You must independ showing data on lcd from Ischarwaiting()
I add variable Refresh. This variable can be set by incomming data, by presing the button or timer tick
So if Refresh = 1 LCD wil be updated depending on variable C value
Look at this pseudo code
Code: | Dim Refresh As Byte
Do
If 0 < Ischarwaiting() Then
If Data Is Valid Then Refresh = 1
End If
Debounce Switch , 0 , Switch_sub , Sub 'button
If Refresh = 1 Then 'independent from Ischarwaiting
Refresh = 0 'show only once per "Refresh = 1"
'switch also can set this flag to 1
Cls 'clear then screen only once
Select Case Menu
Case 1
Case 2
Case 3
End Select
End If
Loop
End
Switch_sub :
Incr Menu : If Menu > 3 Then Menu = 1
Refresh = 1 'switch also can trig the refresh
Return
Timer_tick :
Incr Ticker
If Ticker > Period Then
Ticker = 0 : Refresh = 1
End If
Return
|
..and now its time for another tip
This is not nice solution
Code: | If C = 1 Or C = 2 Or C = 3 Or C = 4 Then
'all conditions are for the same variable
End If |
Better would be:
Code: | Select Case C
Case 1 To 4 : 'do something
End Select |
Your code slightly modified, but not tested, attached. This is for show the idea.
In this code much another points can be optimised.
Have a nice day |
|
Back to top |
|
|
kinjark
Joined: 06 Mar 2017 Posts: 10
|
Posted: Tue Apr 04, 2017 5:20 pm Post subject: |
|
|
Well Bardzo dziękuję!
I have found "case" thing few days ago because I was looking for this solution, but haven't put it in yet because I was not 100% sure in it and I had other problems to solve. But code is much bigger then I thought before I started this project and I am always adding something and deleting something else, that is why code is a mess. And also I did something the ways I knew how at that time but then I figured there is a command for it and can be done with much less effort
Your file will also help me understand this ifcharwaiting much better, first time when I got the code from you with interrupts I had no idea why simple incr A in the middle of code didn't work. So I guess that is a progress
As a first project it will do even if it is a little messy But I am getting addicted to this.
Thank you very much again! |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|