Shop OBEX P1 Docs P2 Docs Learn Events
Unexpected result — Parallax Forums

Unexpected result

ZeusZeus Posts: 79
edited 2012-07-16 16:18 in BASIC Stamp
Hello All,

I am having a problem with my program after changing some of my inputs. In short I switched the input button from one side of the stamp the other in order to simplify the physical layout of the circuit. I made what I thought would be the simple necessary changes to the program and assumed that I would be fine, this is not the case. Here is what happened. My button inputs were IN10, IN12, IN13, IN14 & IN15. They are now IN0, IN1, IN2 & IN3.

When I send the values to the DEBUG window they display the correct values as expexted however the program does not behave accordingly. When IN0 should increase the "Menu" value it decreases it and when IN1 should decrease the "Menu" value it increases.

IN2 & IN3 have no effect at all on the respective values.

What am I missing? Is this me not understanding the Select Case statement or something else entirely?

Any input you can offer is appreciated.

Thanks,

Zeus


Buttons_Sub:                                            ' Start of Sub Routine.

' Menu Number Buttons Block
  IF (IN0 = 0) AND (IN1 = 0) THEN               ' Start of "If" statement which adresses both buttons being presses.
    MenuNum = 0                                        ' If above statement is true "MenuNum" is set equal to zero.
    ELSEIF (IN0 = 0) THEN                          ' Begining of "If" Statement which adds 1 from "MenuNum" variable.
    MenuNum = MenuNum + 1                     ' If above condition is true, adds 1 from "MenuNum" variable.
    ELSEIF (IN1 = 0) THEN                           ' Begining of "If" Statement which subtracts 1 from "MenuNum" variable.
    MenuNum = MenuNum - 1                       ' If above condition is true, subtracts 1 from "MenuNum" variable.
  ENDIF                                                      ' End of "IF" statement.


' Alarm Hours Buttons Block
IF (MenuNum = 0) THEN
  SELECT INA & 3                                       ' Start of "Select Case" statement, possibilities are 00, 01, 10 and 11.
    CASE = 0                                               ' Case 3, both buttons pressed... Reset
      AlmHrs = 6                                           ' If both buttons are pressed alarm hours set TO 6 Am.
      AlarmAmPm = 0
      AlmMins = 0
      AlarmAmPm = 0

      SnzMins = 0                                          ' Resets snooze minutes to zero when alarm is switched off.
      SnzHrs = 0                                            ' Resets snooze hour to zero when alarm is switched off.

    CASE = 1                                                ' Case 1, one button is pressed... advance 1.
      AlmHrs = AlmHrs + 1

      SnzMins = 0                                          ' Resets snooze minutes to zero when alarm is switched off.
      SnzHrs = 0                                            ' Resets snooze hour to zero when alarm is switched off.

      IF AlmHrs > 12 THEN AlmHrs = (AlmHrs - 12)        ' Starts variable counting over at "12" if value is less than "1".
    CASE = 2                                                ' Case 2, other button is pressed... subtract 1.
      AlmHrs = AlmHrs - 1

      SnzMins = 0                                          ' Resets snooze minutes to zero when alarm is switched off.
      SnzHrs = 0                                            ' Resets snooze hour to zero when alarm is switched off.

      IF AlmHrs < 1 THEN AlmHrs = 12            ' Starts variable counting over at "1" if value is greater than "12".
  ENDSELECT
ENDIF


' Alarm Minutes Buttons Block
IF (MenuNum = 1) THEN
  SELECT INA & 3                                        ' Possibilities are 00, 01, 10 and 11.
    CASE = 0
      AlmMins = 0                                           ' Reset to Zero

    CASE = 1
      AlmMins = AlmMins + 1 // 60                   ' Count up mod 60 using // operator

      SnzMins = 0                                           ' Resets snooze minutes to zero when alarm is switched off.
      SnzHrs = 0                                             ' Resets snooze hour to zero when alarm is switched off.

    IF AlmMins//10 = 0 THEN
      FREQOUT Speaker, 100, 2000
      PAUSE 1
    ENDIF

    CASE = 2
      AlmMins = AlmMins - 1 MAX 59                ' Count down mod 60, return to 59 when value becomes 255

      SnzMins = 0                                            ' Resets snooze minutes to zero when alarm is switched off.
      SnzHrs = 0                                              ' Resets snooze hour to zero when alarm is switched off.

     IF ((AlmMins - 10)//10 = 0) THEN
      FREQOUT Speaker, 100, 2000
      PAUSE 1
    ENDIF
  ENDSELECT
ENDIF


' Am/Pm Buttons Block                                    ' MAY BE ABLE TO SIMPLIFY THIS CODE AS EITHER CASE TOGGLES AM/PM FLAG.
IF (MenuNum = 2) THEN
  SELECT INA & 3                                            ' Possibilities are 00, 01, and 10.
    CASE = 0
      DEBUG CRSRXY, 0, 2, "Test"
    CASE = 1
      AlarmAmPm = AlarmAmPm + 1 MAX 1        ' Alarm set to "PM" mode.
      AlmAmPmFlag = 0                                     ' Flips Alarm Am/Pm indicator "AlmAmPmFlag" to alternate "AM" state.

    CASE = 2
      AlarmAmPm = AlarmAmPm - 1 MAX 0        ' Alarm set to "AM" mode.
      AlmAmPmFlag = 1                                     ' Flips Alarm Am/Pm indicator "AlmAmPmFlag" to alternate "PM" state.

  ENDSELECT
ENDIF

Comments

  • Mike GMike G Posts: 2,702
    edited 2012-07-10 19:46
    IF IN0 is high MenuNum is decremented. How are the buttons wired? Active High or Low?

    All of the SELECT/CASE statements mask at bits 0 and 1; INA & %0011. I do not see where bits 2 and 3 (IN2 and IN3) are being used.
  • StephenMooreStephenMoore Posts: 188
    edited 2012-07-10 21:49
    Is the = sign necessary in the CASE statement?
  • ZeusZeus Posts: 79
    edited 2012-07-11 03:40
    Thanks for the replys Guys,

    Mike - The circuit is wired Active Low and was previously when it was operating correctly.

    Stephen - All that I can say is that my program worked perfectly before I reassigned my button input inputs, given this I have not looked into the equal signs being the source of the problem.

    Zeus
  • skylightskylight Posts: 1,915
    edited 2012-07-11 14:46
    Would you be using the professional development board?
  • ZeusZeus Posts: 79
    edited 2012-07-11 15:14
    Skylight,

    Yes I am, how did you know? Is this contrubuting to my problem?

    Also - Mike G I missed the last part of your post... IN2 & IN3 were increasing and decreasing the value(s) accordingly.

    Zeus
  • UnsoundcodeUnsoundcode Posts: 1,532
    edited 2012-07-11 18:07
    Hi Zeus, I think what Mike was getting at is that the code you posted does not use IN2 or IN3.

    You say IN2 and IN3 should increase or decrease the "values", if that is the case you need to modify the Select Case conditions.

    I am assuming here that IN0 and IN1 are the menu selection bits and that bits IN2 and IN3 adjust the alarm, unless there is some code you have not shown us.
    ' Alarm Hours Buttons Block
    IF (MenuNum = 0) THEN
      SELECT INA & 12                                       ' Start of "Select Case" statement, possibilities are 0000 (0), 0100 (4), 1000 (8) and 1100 (12).
        CASE = 12                                               ' Case 12, both buttons pressed... Reset
          AlmHrs = 6                                           ' If both buttons are pressed alarm hours set TO 6 Am.
          AlarmAmPm = 0
          AlmMins = 0
          AlarmAmPm = 0
    
          SnzMins = 0                                          ' Resets snooze minutes to zero when alarm is switched off.
          SnzHrs = 0                                            ' Resets snooze hour to zero when alarm is switched off.
    
        CASE = 4                                                ' Case 4, one button is pressed... advance 1.
          AlmHrs = AlmHrs + 1
    
          SnzMins = 0                                          ' Resets snooze minutes to zero when alarm is switched off.
          SnzHrs = 0                                            ' Resets snooze hour to zero when alarm is switched off.
    
          IF AlmHrs > 12 THEN AlmHrs = (AlmHrs - 12)        ' Starts variable counting over at "12" if value is less than "1".
        CASE = 8                                                ' Case 8, other button is pressed... subtract 1.
          AlmHrs = AlmHrs - 1
    
          SnzMins = 0                                          ' Resets snooze minutes to zero when alarm is switched off.
          SnzHrs = 0                                            ' Resets snooze hour to zero when alarm is switched off.
    
          IF AlmHrs < 1 THEN AlmHrs = 12            ' Starts variable counting over at "1" if value is greater than "12".
      ENDSELECT
    
  • ZeusZeus Posts: 79
    edited 2012-07-11 18:50
    Unsoundcode,

    You are correct. IN0 & IN1 scroll up and down through the alarm clock menu. IN2 & IN3 scroll up and down respectively allowing the user to set the alarm time.

    I have been looking to a good Select Case reference for some time. My code used to work well but I adjusted the inputs and now it doesn't function at all so clearly I do not understand how Select Case statement work, and for that matter "INA/INA & #".

    How do 12, 4 and 8 influence the Select Case statement?

    Thanks,

    Zeus


    P.S. - Your changes helped and it is functional again, however I am still dealing with an issue where the up button decreases the value and the down button increases the value. While I realize that I could just edit the code and patch this my real concern is that I am still missing the fundamental concept(s).
  • UnsoundcodeUnsoundcode Posts: 1,532
    edited 2012-07-12 06:22
    Hi Zeus, SELECT CASE is very similar to IF THEN.

    Both instructions look for a certain condition so they are classed as conditional instructions, the condition they look for is usually the value of a variable.

    So using IF THEN the first thing to do is specify which variable you are looking at
    IF MyVar
    

    The SELECT instruction goes along the same lines, first specify the variable to watch for
    SELECT Myvar
    

    The next part of both these instructions is to compare Myvar with some other value and to see if the comparison is true.
    IF Myvar<>1 THEN
    

    Using SELECT
    SELECT Myvar
    	CASE <>1
    

    The condition you are looking for would be Myvar is not equal to 1, this condition can only be true or false.

    Additional conditions can be added to both instructions, the instructions are completed with an END IF and an END SELECT respectively.
    IF Myvar<>1 THEN
    	condition 1 has been met
          ELSE IF Myvar=6
            condition 2 has been met 
    	etc etc............
          END IF
    
    SELECT Myvar
    	CASE <>1
    	  condition 1 has been met
    	CASE =6	
    	  condition 2 has been met
    	  etc etc......
    	END SELECT
    

    The above code samples are examples and the syntax may not be right but the principal is the same for all forms of basic.

    I think your usage of SELECT CASE is fine I think that using the INS register and masking binary values are probably where things might seem to get confusing, don't worry this is confusing for everyone to begin with.

    As for 12 8 and 4 look at what happens to P0 P1 P2 and P3 when a button is pressed and Google binary.

    Press button 1 = 0001 = 1 decimal
    Press button 2 = 0010 = 2 decimal
    Press button 1 & 2 = 0011 = 3 decimal
    Press button 3 = 0100 = 4 decimal
    Press button 1 & 3 = 0101 = 5 decimal
    Press button 2 & 3 = 0110 = 6 decimal
    Press button 1 & 2 & 3 = 0111 = 7 decimal
    Press button 4 = 1000 = 8 decimal
    Press button 1 & 4 = 1001 = 9 decimal
    Press button 2 & 4 = 1010 = 10 decimal
    Press button 1 & 2 & 4 = 1011 = 11 decimal
    Press button 3 & 4 = 1100 = 12 decimal
    Press button 1 & 3 & 4 = 1101 = 13 decimal
    Press button 2 & 3 & 4 = 1110 = 14 decimal
    Press button 1 & 2 & 3 & 4 = 1100 = 15 decimal
  • ZeusZeus Posts: 79
    edited 2012-07-12 09:42
    Unsoundcode,

    Thank you very much for your detailed explanation. I have printed it out and will try to implement the changes tonight.One thing that still confuses me is that if I send the button state to the Debug widow the appropriate button registers low when pressed. The disconnect for me is that this very input somehow has become inverted program wise. By this I mean this low should drive the program to increase the value but instead it is decreased, could this be caused by the INS registry statement somehow.

    Zeus
  • UnsoundcodeUnsoundcode Posts: 1,532
    edited 2012-07-12 10:22
    Hi, my truth table/explanation was for active high switches sorry about that, not a problem though just invert all the binary values, which will obviously give different values for your SELECT CASE.

    The INS instruction will work the same whether active low or active high.
  • davejamesdavejames Posts: 4,047
    edited 2012-07-12 12:15
    Hi Jeff (long time),

    Should not:
    Press button 1 & 2 & 3 & 4 = 1100 = 15 decimal

    really read:
    Press button 1 & 2 & 3 & 4 = 1111 = 15 decimal

    Dave
  • UnsoundcodeUnsoundcode Posts: 1,532
    edited 2012-07-12 14:28
    Correct Dave thanks for pointing that out, I have to admit to copy and pasting that section of the post and modifying each line, except the one :o(
  • UnsoundcodeUnsoundcode Posts: 1,532
    edited 2012-07-12 16:10
    Hi Zeus, a couple of things about buttons, switches, relays etc.

    Mechanical switches tend to "bounce" when going from one state to another, this has the effect of producing several pulses from just one button press. Its normal practice to code a small timer that ensures the microcontroller sees only one pulse for one press of the button, the timer is usually called a "debounce timer".

    The sequence might look like this

    If button is pressed then
    pause 25mS and let the bounce settle
    If button is still pressed then
    produce one pulse

    Its also practically impossible to press more than one switch at exactly the same time so depending how its coded this may also need a debounce timer.

    To detect the press of two buttons it might go something like the following. I give the example using active low as this is how it should be if using the Stamp PDB. When writing the values of INA in your code you can use decimal notation (e.g. 9) or binary (e.g. %1001), which ever is your preference.

    With no buttons pressed INA will contain all 1's %1111 which is decimal 15, the initial check does not look for a specific value it only checks to see if INA is less than 15, pressing any button will drop the value of INA below 15.

    If INA < %1111 then a button is pressed
    pause 25mS to let the switches settle

    SELECT INA
    CASE INA=x

    CASE INA=y

    etc etc

    the SELECT CASE is where we look for a value which will indicate which buttons have been pressed, for example if buttons 1 and 4 are pressed INA will contain %0110 a decimal value of 6
  • ZeusZeus Posts: 79
    edited 2012-07-12 16:15
    To All,

    I think I understand what you two are driving at however I cannot explain the code below delivering an inverse result? I am lost here.
    ' Menu Number Buttons Block
    IF (IN0 = 0) AND (IN1 = 0) THEN        ' Start of "If" statement which adresses both buttons being presses.
    MenuNum = 0                                   ' If above statement is true "MenuNum" is set equal to zero.
    ELSEIF (IN0 = 0) THEN                    ' Begining of "If" Statement which adds 1 from "MenuNum" variable.
    MenuNum = MenuNum + 1              ' If above condition is true, adds 1 from "MenuNum" variable.
    ELSEIF (IN1 = 0) THEN             ' Begining of "If" Statement which subtracts 1 from "MenuNum" variable.
    MenuNum = MenuNum - 1                  ' If above condition is true, subtracts 1 from "MenuNum" variable.
    ENDIF                                                ' End of "IF" statement.
    

    The above does not employ a select case statement however it exhibits the same inverse behavior just as the select case statements do elsewhere in the code.

    What have I missed? All that I changed was to switch IN12, IN13, IN14 and IN15 over to IN2, IN3, IN0 and IN1 respectively, and then adjusted my code accordingly. There has to be something else going on here.

    Thanks,

    Zeus
  • UnsoundcodeUnsoundcode Posts: 1,532
    edited 2012-07-13 05:12
    Hi Zeus, this is how I assume your hardware to be, correct me if I am wrong.

    Stamp PDB with 4 buttons active low
    Button1 connected to P0
    Button2 connected to P1
    Button3 connected to P2
    Button4 connected to P3
    Button1 and Button2 = menu selection
    Button3 and button4 = alarm adjustment

    If there are only three possible menu numbers and you want to use Button1 and Button2 for selection you might want to code your menu selection differently.

    I mentioned debouncing and multiple pulses, I have not seen your complete program code but looking at the menu selection adding and subtracting in this way can give MenuNum unwanted values.

    Try this, it ensures MenuNum gets a predetermined value. Debounce the switches before you enter the following block
    IF INA=12 THEN  	   'both buttons pressed %1100
    MenuNum = 0
    ELSEIF INA=14 THEN  	'button1 pressed %1110
    MenuNum = 1  
    ELSEIF INA=13 THEN	   'button2 pressed %1101
    MenuNum = 2
    ENDIF
    
  • Mike GMike G Posts: 2,702
    edited 2012-07-13 07:39
    Zeus, double check your connects and walk through the source code.

    Truth table for the first IF block
    IN1	IN0	MenuItem	INA Value
    0	0	0		0
    0	1	-1		1
    1	0	+1		2
    1	1	x		3
    

    Let's assume both IN0 and IN1 are low (Pressed). The first IF block is invoked, (MenuNum = 0). It is highly likely that both buttons are still pressed when execution leaves the first IF. INA is logically ANDed with 3; INA & %0011. Since INA equals XX00, the first CASE branch is executed. It seems to me that you would have to push or release a button perfectly when execution moves from the first IF block to the next.
    IF (MenuNum = 0) THEN
      SELECT INA & 3                                       ' Start of "Select Case" statement, possibilities are 00, 01, 10 and 11.
        CASE = 0                                               ' Case 3, both buttons pressed... Reset
          AlmHrs = 6                                           ' If both buttons are pressed alarm hours set TO 6 Am.
          AlarmAmPm = 0
          AlmMins = 0
          AlarmAmPm = 0
    
          SnzMins = 0                                          ' Resets snooze minutes to zero when alarm is switched off.
          SnzHrs = 0                                            ' Resets snooze hour to zero when alarm is switched off.
    
  • skylightskylight Posts: 1,915
    edited 2012-07-13 16:11
    Sorry taking so long to get back, The reason I asked about the PDB is that I remember posts re something about when used with a BS240p there have been issues in the past with I/O's wired up wrongly due to the pins going to different connectors MAIN and AUX if I remember rightly? The PDB info details this, perhaps you have been caught out by this?
  • ZeusZeus Posts: 79
    edited 2012-07-13 16:38
    No problem Skyline as I am still in the same boat.

    My code was working and I reconfigured my inputs, what I thought would be a simple matter of straight forward substitutions and now I am completely without any bearing.

    My code below was working...
    Buttons_Sub:                          ' Start of Sub Routine.
    
    ' Menu Number Buttons Block
      IF (IN14 = 0) AND (IN15 = 0) THEN   ' Start of "If" statement which adresses both buttons being presses.
        MenuNum = 0                       ' If above statement is true "MenuNum" is set equal to zero.
        ELSEIF (IN14 = 0) THEN            ' Begining of "If" Statement which adds 1 from "MenuNum" variable.
        MenuNum = MenuNum + 1             ' If above condition is true, adds 1 from "MenuNum" variable.
        ELSEIF (IN15 = 0) THEN            ' Begining of "If" Statement which subtracts 1 from "MenuNum" variable.
        MenuNum = MenuNum - 1             ' If above condition is true, subtracts 1 from "MenuNum" variable.
      ENDIF                               ' End of "IF" statement.
    
    
    ' Alarm Hours Buttons Block
    IF (MenuNum = 0) THEN
      SELECT IND & 3                            ' Start of "Select Case" statement, possibilities are 00, 01, 10 and 11.
        CASE = 0                                ' Case 3, both buttons pressed... Reset
          AlmHrs = 6                            ' If both buttons are pressed alarm hours set TO 6 Am.
          AlarmAmPm = 0
          AlmMins = 0
          AlarmAmPm = 0
    
          SnzMins = 0                           ' Resets snooze minutes to zero when alarm is switched off.
          SnzHrs = 0                            ' Resets snooze hour to zero when alarm is switched off.
    
        CASE = 1                                ' Case 1, one button is pressed... advance 1.
          AlmHrs = AlmHrs + 1
    
          SnzMins = 0                           ' Resets snooze minutes to zero when alarm is switched off.
          SnzHrs = 0                            ' Resets snooze hour to zero when alarm is switched off.
    
          IF AlmHrs > 12 THEN AlmHrs = (AlmHrs - 12)        ' Starts variable counting over at "12" if value is less than "1".
        CASE = 2                                ' Case 2, other button is pressed... subtract 1.
          AlmHrs = AlmHrs - 1
    
          SnzMins = 0                           ' Resets snooze minutes to zero when alarm is switched off.
          SnzHrs = 0                            ' Resets snooze hour to zero when alarm is switched off.
    
          IF AlmHrs < 1 THEN AlmHrs = 12        ' Starts variable counting over at "1" if value is greater than "12".
      ENDSELECT
    ENDIF
    
    
    ' Alarm Minutes Buttons Block
    IF (MenuNum = 1) THEN
      SELECT IND & 3                      ' Possibilities are 00, 01, 10 and 11.
        CASE = 0
          AlmMins = 0                     ' Reset to Zero
    
        CASE = 1
          AlmMins = AlmMins + 1 // 60     ' Count up mod 60 using // operator
    
          SnzMins = 0                           ' Resets snooze minutes to zero when alarm is switched off.
          SnzHrs = 0                            ' Resets snooze hour to zero when alarm is switched off.
    
        IF AlmMins//10 = 0 THEN
          FREQOUT Speaker, 100, 2000
          PAUSE 1
        ENDIF
    
        CASE = 2
          AlmMins = AlmMins - 1 MAX 59    ' Count down mod 60, return to 59 when value becomes 255
    
          SnzMins = 0                           ' Resets snooze minutes to zero when alarm is switched off.
          SnzHrs = 0                            ' Resets snooze hour to zero when alarm is switched off.
    
         IF ((AlmMins - 10)//10 = 0) THEN
          FREQOUT Speaker, 100, 2000
          PAUSE 1
        ENDIF
      ENDSELECT
    ENDIF
    
    
    ' Am/Pm Buttons Block                   ' MAY BE ABLE TO SIMPLIFY THIS CODE AS EITHER CASE TOGGLES AM/PM FLAG.
    IF (MenuNum = 2) THEN
      SELECT IND & 3                        ' Possibilities are 00, 01, and 10.
        CASE = 0
          DEBUG CRSRXY, 0, 2, "Test"
        CASE = 1
          AlarmAmPm = AlarmAmPm + 1 MAX 1   ' Alarm set to "PM" mode.
          AlmAmPmFlag = 0                   ' Flips Alarm Am/Pm indicator "AlmAmPmFlag" to alternate "AM" state.
    
          'SnzMins = 0                           ' Resets snooze minutes to zero when alarm is switched off.
          'SnzHrs = 0                            ' Resets snooze hour to zero when alarm is switched off.
    
        CASE = 2
          AlarmAmPm = AlarmAmPm - 1 MAX 0   ' Alarm set to "AM" mode.
          AlmAmPmFlag = 1                   ' Flips Alarm Am/Pm indicator "AlmAmPmFlag" to alternate "PM" state.
    
          'SnzMins = 0                           ' Resets snooze minutes to zero when alarm is switched off.
          'SnzHrs = 0                            ' Resets snooze hour to zero when alarm is switched off.
    
      ENDSELECT
    ENDIF
    

    It is now...

    IN14 is now IN0
    IN15 is now IN1
    IN12 is now IN2
    IN13 is now IN3
    ' Menu Number Buttons Block
      IF (IN0 = 0) AND (IN1 = 0) THEN   ' Start of "If" statement which adresses both buttons being presses.
        MenuNum = 0                       ' If above statement is true "MenuNum" is set equal to zero.
        ELSEIF (IN0 = 0) THEN            ' Begining of "If" Statement which adds 1 from "MenuNum" variable.
        MenuNum = MenuNum + 1             ' If above condition is true, adds 1 from "MenuNum" variable.
        ELSEIF (IN1 = 0) THEN            ' Begining of "If" Statement which subtracts 1 from "MenuNum" variable.
        MenuNum = MenuNum - 1             ' If above condition is true, subtracts 1 from "MenuNum" variable.
      ENDIF                               ' End of "IF" statement.
    
    
    ' Alarm Hours Buttons Block
    IF (MenuNum = 0) THEN
      SELECT IND & 3                            ' Start of "Select Case" statement, possibilities are 00, 01, 10 and 11.
        CASE = 0                                ' Case 3, both buttons pressed... Reset
          AlmHrs = 6                            ' If both buttons are pressed alarm hours set TO 6 Am.
          AlarmAmPm = 0
          AlmMins = 0
          AlarmAmPm = 0
    
          SnzMins = 0                           ' Resets snooze minutes to zero when alarm is switched off.
          SnzHrs = 0                            ' Resets snooze hour to zero when alarm is switched off.
    
        CASE = 1                                ' Case 1, one button is pressed... advance 1.
          AlmHrs = AlmHrs + 1
    
          SnzMins = 0                           ' Resets snooze minutes to zero when alarm is switched off.
          SnzHrs = 0                            ' Resets snooze hour to zero when alarm is switched off.
    
          IF AlmHrs > 12 THEN AlmHrs = (AlmHrs - 12)        ' Starts variable counting over at "12" if value is less than "1".
        CASE = 2                                ' Case 2, other button is pressed... subtract 1.
          AlmHrs = AlmHrs - 1
    
          SnzMins = 0                           ' Resets snooze minutes to zero when alarm is switched off.
          SnzHrs = 0                            ' Resets snooze hour to zero when alarm is switched off.
    
          IF AlmHrs < 1 THEN AlmHrs = 12        ' Starts variable counting over at "1" if value is greater than "12".
      ENDSELECT
    ENDIF
    
    
    ' Alarm Minutes Buttons Block
    IF (MenuNum = 1) THEN
      SELECT IND & 3                      ' Possibilities are 00, 01, 10 and 11.
        CASE = 0
          AlmMins = 0                     ' Reset to Zero
    
        CASE = 1
          AlmMins = AlmMins + 1 // 60     ' Count up mod 60 using // operator
    
          SnzMins = 0                           ' Resets snooze minutes to zero when alarm is switched off.
          SnzHrs = 0                            ' Resets snooze hour to zero when alarm is switched off.
    
        IF AlmMins//10 = 0 THEN
          FREQOUT Speaker, 100, 2000
          PAUSE 1
        ENDIF
    
        CASE = 2
          AlmMins = AlmMins - 1 MAX 59    ' Count down mod 60, return to 59 when value becomes 255
    
          SnzMins = 0                           ' Resets snooze minutes to zero when alarm is switched off.
          SnzHrs = 0                            ' Resets snooze hour to zero when alarm is switched off.
    
         IF ((AlmMins - 10)//10 = 0) THEN
          FREQOUT Speaker, 100, 2000
          PAUSE 1
        ENDIF
      ENDSELECT
    ENDIF
    
    
    ' Am/Pm Buttons Block                   ' MAY BE ABLE TO SIMPLIFY THIS CODE AS EITHER CASE TOGGLES AM/PM FLAG.
    IF (MenuNum = 2) THEN
      SELECT IND & 3                        ' Possibilities are 00, 01, and 10.
        CASE = 0
          DEBUG CRSRXY, 0, 2, "Test"
        CASE = 1
          AlarmAmPm = AlarmAmPm + 1 MAX 1   ' Alarm set to "PM" mode.
          AlmAmPmFlag = 0                   ' Flips Alarm Am/Pm indicator "AlmAmPmFlag" to alternate "AM" state.
    
        CASE = 2
          AlarmAmPm = AlarmAmPm - 1 MAX 0   ' Alarm set to "AM" mode.
          AlmAmPmFlag = 1                   ' Flips Alarm Am/Pm indicator "AlmAmPmFlag" to alternate "PM" state.
    
      ENDSELECT
    ENDIF
    

    I do not have a good understanding of "INS" statements despite Mike G and Unsoundcode's best efforts, and I am convinced that this is the root of my problem.

    In short my code now produces then inverse menu value, up is down and down is up, and I am no longer able to change the alarm time values at all, again everything was working with my old code, no inversion of inputs at all.

    When I send the current state to the debug window everything checks out and goes low as expected, the code however ultimately produces the inverse result.

    Completely confused.

    Zeus
  • Mike GMike G Posts: 2,702
    edited 2012-07-13 17:52
    Are you sure you want
    IN14 is now IN0
    IN15 is now IN1
    IN12 is now IN2
    IN13 is now IN3
    

    I would think this would make more sense.
    IN15 is now IN3
    IN14 is now IN2
    IN13 is now IN1
    IN12 is now IN0
    
  • ZeusZeus Posts: 79
    edited 2012-07-13 18:34
    Mike,

    I don't care so much about the order at this point, my real concern is understanding why my substitution is not working. Does the substitution have to ascend just as it did in the original code in order for the INS statement and/or Select Case statement to work properly? And how does this affect my initial Menu "If Then" statement?

    Zeus
  • Mike GMike G Posts: 2,702
    edited 2012-07-13 20:19
    Order does matter because the INS register is ordered.

    IND is PIN 15, 14, 13, and 12
    INA is PIN 03, 02, 01, and 00

    IND & 3 means - I only want to deal with PIN 13 and 12
    INA & 3 means - I only want to deal with PIN 01 and 00

    Take some time to experiment with the INS register outside of your project. This might help your understanding.
  • ZeusZeus Posts: 79
    edited 2012-07-13 21:59
    Mike,

    Thank you for explaining that. I had thought that that was how it worked early on but where I had multiple "INx & 3" statements I think buttons were getting locked out and then I presumed that my understanding was incorrect. (Knowing that the order is critical is important as well.) I will have to experiment a bit to fully understand it but I think that I am headed in the right direction now. I will let everyone know how I make out.

    Thank you very much for your persistence and patience.

    Zeus
  • ZeusZeus Posts: 79
    edited 2012-07-15 04:46
    Mike,

    Still no luck. All four inputs are still delivering the inverse results. When I send the current state of each button to the Debug window the all behave as expected (0), however the program produces the opposite result. As a test I stripped everything out of the button sub and just focused in the initial Menu "If Then" statement as this does not employ a "Select Case" statement just to limit the variables, variables in the scientific testing sense, and despite the fact that the menu value increased by one in the Debug window it still decreased by one on the clock. I am convinced that I have a "Select Case" problem as well but it is clear that there is something bigger going on. Hopefully someone can help me spot what I am missing. I have included a portion of the code below.
    Buttons_Sub:                          ' Start of Sub Routine.
    
    ' Menu Number Buttons Block
      IF (IN2 = 0) AND (IN3 = 0) THEN     ' Start of "If" statement which adresses both buttons being presses.
      MenuNum = 0                       ' If above statement is true "MenuNum" is set equal to zero.
      ELSEIF (IN2 = 0) THEN             ' Begining of "If" Statement which adds 1 from "MenuNum" variable.
      MenuNum = MenuNum + 1             ' If above condition is true, adds 1 from "MenuNum" variable.
      ELSEIF (IN3 = 0) THEN             ' Begining of "If" Statement which subtracts 1 from "MenuNum" variable.
      MenuNum = MenuNum - 1             ' If above condition is true, subtracts 1 from "MenuNum" variable.
      ENDIF                               ' End of "IF" statement.
    
    
    ' Alarm Hours Buttons Block
     IF (MenuNum = 0) THEN
     SELECT INA & 3                            ' Start of "Select Case" statement, possibilities are 00, 01, 10 and 11.
     CASE = 3                                ' Case 3, both buttons pressed... Reset
     AlmHrs = 6                            ' If both buttons are pressed alarm hours set TO 6 Am.
     AlarmAmPm = 0
     AlmMins = 0
     AlarmAmPm = 0
    
      SnzMins = 0                           ' Resets snooze minutes to zero when alarm is switched off.
      SnzHrs = 0                            ' Resets snooze hour to zero when alarm is switched off.
    
      CASE = 1                                ' Case 1, one button is pressed... advance 1.
      AlmHrs = AlmHrs + 1
    
       SnzMins = 0                           ' Resets snooze minutes to zero when alarm is switched off.
       SnzHrs = 0                            ' Resets snooze hour to zero when alarm is switched off.
    
       IF AlmHrs > 12 THEN AlmHrs = (AlmHrs - 12)        ' Starts variable counting over at "12" if value is less than "1".
       CASE = 2                                ' Case 2, other button is pressed... subtract 1.
       AlmHrs = AlmHrs - 1
    
       SnzMins = 0                           ' Resets snooze minutes to zero when alarm is switched off.
       SnzHrs = 0                            ' Resets snooze hour to zero when alarm is switched off.
    
        IF AlmHrs < 1 THEN AlmHrs = 12        ' Starts variable counting over at "1" if value is greater than "12".
        ENDSELECT
        ENDIF
    

    Thanks,

    Zeus
  • Mike GMike G Posts: 2,702
    edited 2012-07-15 10:26
    Zeus, post all your code - including the debug code - and a schematic of your setup.

    Also the button input should be debouced.
  • ZeusZeus Posts: 79
    edited 2012-07-15 13:21
    Mike,

    Here you go. The schematic is borrowed from Chris Savage's alarm clock project so I do not use some of the ICs, but regardless this is the schematic that I based my alarm clock off of.

    I agree that the debounce statement would be nice, however I am holding off for now on adding it for now for two reasons.One, before I changed my inputs the code worked without a debounce and more importantly, as you will see in the attachment, I am running out of code space.

    Thanks again,

    Zeus

    Modified Digital Alarm Clock - New Pin Layout - 7.8.12.bs2Schematic Small.bmp
  • Mike GMike G Posts: 2,702
    edited 2012-07-16 09:03
    Zeus, either the buttons are not wired as expected or the code does not reflect the correct IO.

    Here's a simple button debouce example that reads all 4 buttons connected to INA - at one time - and places the result in buttons. Use this script to debug your wiring. It can also be used to optimize your alarm clock code.
    ' {$STAMP BS2p}
    ' {$PBASIC 2.5}
    
    
    
    buttons    VAR  Nib
    btn0       VAR  buttons.BIT0
    btn1       VAR  buttons.BIT1
    btn2       VAR  buttons.BIT2
    btn3       VAR  buttons.BIT3
    
    btnDirs    VAR DIRA
    btnOut     VAR OUTA
    btnIn      VAR INA
    
    scan       VAR Nib
    
    
    Init:
      btnDirs = %0000
    
    Main:
      GOSUB LCD_Get_Buttons
      GOSUB Print_Button_Press
      PAUSE 1000
      GOTO Main
    
    'Debounce and return button press
    LCD_Get_Buttons:
      buttons = %1111
      FOR scan = 1 TO 10
        buttons = buttons & btnIn
        PAUSE 5
      NEXT
    RETURN
    
    Print_Button_Press:
      DEBUG CLS, BIN ?buttons
      RETURN
    
  • ZeusZeus Posts: 79
    edited 2012-07-16 16:18
    Thanks for your help Mike, but still no luck.

    I have confirmed that the button inputs are wired correctly physically as well as separate two ways via the Debug window. There is something strange going on as the menu value is indexing correctly however the menu selection that is actually displayed on the LCD is indexed in the opposite direction from what the numeric menu value is actually instructing it to do. I also seem to have some cross talk going on where the menu buttons are now affecting the alarm values.

    Regardless, thank you for sticking with it. If I ever get it figured out I will post the solution.

    Zeus
Sign In or Register to comment.