Forum - MCS Electronics

 

FAQFAQ SearchSearch RegisterRegister Log inLog in

Do something when var changes

 
Post new topic   Reply to topic    www.mcselec.com Forum Index -> BASCOM-AVR
View previous topic :: View next topic  
Author Message
kinjark

Bascom Member



Joined: 06 Mar 2017
Posts: 10

PostPosted: Mon Apr 03, 2017 7:53 pm    Post subject: Do something when var changes Reply with quote

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
View user's profile
EDC

Bascom Expert



Joined: 26 Mar 2014
Posts: 692

poland.gif
PostPosted: Mon Apr 03, 2017 8:43 pm    Post subject: Reply with quote

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
View user's profile Visit poster's website
kinjark

Bascom Member



Joined: 06 Mar 2017
Posts: 10

PostPosted: Mon Apr 03, 2017 9:40 pm    Post subject: Reply with quote

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
View user's profile
EDC

Bascom Expert



Joined: 26 Mar 2014
Posts: 692

poland.gif
PostPosted: Mon Apr 03, 2017 10:13 pm    Post subject: Reply with quote

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
View user's profile Visit poster's website
kinjark

Bascom Member



Joined: 06 Mar 2017
Posts: 10

PostPosted: Tue Apr 04, 2017 7:48 am    Post subject: Reply with quote

EDC wrote:


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 Rolling Eyes

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
View user's profile
EDC

Bascom Expert



Joined: 26 Mar 2014
Posts: 692

poland.gif
PostPosted: Tue Apr 04, 2017 10:41 am    Post subject: Reply with quote

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 Very Happy

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 Very Happy

So if Refresh = 1 LCD wil be updated depending on variable C value Very Happy
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 Wink
Return

Timer_tick:
 Incr Ticker
  If Ticker > Period Then
   Ticker = 0 : Refresh = 1
  End If
Return
 


..and now its time for another tip Very Happy
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 Wink
Back to top
View user's profile Visit poster's website
kinjark

Bascom Member



Joined: 06 Mar 2017
Posts: 10

PostPosted: Tue Apr 04, 2017 5:20 pm    Post subject: Reply with quote

EDC wrote:


Well Bardzo dziękuję! Very Happy


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 Very Happy

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 Very Happy

As a first project it will do even if it is a little messy Very Happy But I am getting addicted to this.

Thank you very much again! Very Happy
Back to top
View user's profile
Display posts from previous:   
Post new topic   Reply to topic    www.mcselec.com Forum Index -> BASCOM-AVR All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
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