6.4 Change ball movement speed with buttons (using the button interrupt)

We continue to improve the code to increase the ball movement speed control: button A reduces the movement speed, button B increases the movement speed and the current small ball movement speed is displayed in the upper left corner of the display.

RPiSparkModule has prepared the basic entry for push button interrupt handling for us. We only need to complete the specific processing code. They are:

onKeyButtonDown(self, channel)

The button is pressed interrupt. Channel is the button ID, which can be used to determine which button was pressed.
We can get these button IDs via the RPiSparkModule.RPiSparkConfig class,
eg. self.RPiSparkConfig.BUTTON_ACT_A is push button A (red button). see SDK manual RPiSparkConfig get more information

onKeyButtonUp(self, channel)

The button is released interrupt. Channel is the button ID, which can be used to determine which button was pressed.
We can get these button IDs via the RPiSparkModule.RPiSparkConfig class,
eg. self.RPiSparkConfig.BUTTON_ACT_A is push button A (red button). see SDK manual RPiSparkConfig get more information

Here we use onKeyButtonUp to change the speed of the ball.

Note Time-consuming code can not be executed in the onKeyButtonDown and onKeyButtonUp interrupt entry functions, such as drawing, connecting to the network, sending data, updating the screen display and so on. Failure to do so may result in application deadlocks, stagnant and other unstable conditions!

In addition to button interrupt handling, we also need to add two member functions to display the current ball movement speed and change the ball movement speed:

_drawVel(self)

Draw the current ball movement speed in the upper left corner of the screen.

_changeVel(self, offsetVel)

Change the current ball movement speed. offsetVel > 0 increases speed, offsetVel < 0 decreases speed. The range of speed adjustment is: 1 ~ 9, default speed is: 3

We open the (6.3) completed BallBox_6_3.py program file now. Add the interrupt processing code of button A and button B and the code for displaying the speed and change the button processing mode to interrupt "INT".

from JMRPiFoundations.Skeleton.RPiSparkModule import RPiSparkModule
from Ball import Ball

class BallBox(RPiSparkModule):
    ball = None
    velocity = None

    def _drawVel(self):
        self.RPiSpark.Screen.Canvas.rectangle( (2, 2, 38, 16), 0, 0 )
        self.RPiSpark.Screen.write("VEL:{:1d}".format( self.velocity ), xy=(0,4))

    def _changeVel(self, offsetVel):
        """
        Change velocity of ball move
        offsetVel can be > 0 to increase velocity or < 0 to reduce velocity
        velocity is limited between 1 and 8
        """
        self.velocity += offsetVel
        if self.velocity < 1:
            self.velocity = 1

        if self.velocity > 9:
            self.velocity = 9

    def onKeyButtonUp(self, channel):
        # Press SW_A to reduce velocity
        if channel == self.RPiSparkConfig.BUTTON_ACT_A:
           self._changeVel(-1)
           return

        # Press SW_B to increase velocity
        if channel == self.RPiSparkConfig.BUTTON_ACT_B:
           self._changeVel(1)
           return

    def setup(self):
        self.velocity = 3
        self.ball = Ball(64, 32, 5)
        # setup all key buttons to INT mode, same time query work fine
        self.initKeyButtons("INT")

    def run(self):

        while True:

            # Check exit key status ( JOY_UP + SW_A )
            if self.readExitButtonStatus():
                break;

            # Move the ball up
            if self.readKeyButton(self.RPiSparkConfig.BUTTON_JOY_UP):
                self.ball.move(0, -self.velocity)

            # Move the ball down
            if self.readKeyButton(self.RPiSparkConfig.BUTTON_JOY_DOWN):
                self.ball.move(0, self.velocity)

            # Move the ball left
            if self.readKeyButton(self.RPiSparkConfig.BUTTON_JOY_LEFT):
                self.ball.move(-self.velocity, 0)

            # Move the ball right
            if self.readKeyButton(self.RPiSparkConfig.BUTTON_JOY_RIGHT):
                self.ball.move(self.velocity, 0)

            # Move the ball to center of screen
            if self.readKeyButton(self.RPiSparkConfig.BUTTON_JOY_OK):
                self.ball.reset()

            # Drawing the ball on the screen
            self.RPiSpark.Screen.clear()
            self._drawVel()
            self.RPiSpark.Screen.Canvas.ellipse( self.ball.getXY(), 1, 1 )
            self.RPiSpark.Screen.refresh()

        print("BallBox is done.")

Save as BallBox_6_4.py and execute the following command in the terminal:

$> rspk BallBox_6_4 -f

At this time, you can see a white solid circle in the center of the OLED screen (we use a solid circle to represent the ball). You can control the movement of the ball up and down and left and right by the Joystick and you can change the speed of the ball movement by pressing A or B.


 

Was this article helpful?

YES     |     NO

 

Enjoying the project? Spotted a mistake? Any opinions on the website? Let us know!