DESIGNED & ENGINEERED IN LONDON, UK

© 2019 Creoqode

Educational Guide to PYXA

June 1, 2019 | Creoqode Team

This comprehensive tutorial includes information about the components of Pyxa and guides the user through the process of creating a video game from scratch. For easier access to individual chapters, you can click the headings from the table of contents.

WHAT IS ANALYTIC AND SYSTEMATIC THINKING?

After having a brief look at the components of Pyxa, we can now start learning about coding by looking at some fundamental concepts. In order to excel in coding, one must have an effective thinking process. Prior to writing a code to control a computer-based device, one needs to analyse comprehensively the problem that needs solving, the conditions set, and the limitations one may encounter.

This effective thinking process falls under two main headings, which are analytic thinking and systematic thinking.

Analytic thinking can be defined as the abstract separation of a whole into its constituent parts, in order to study the parts and their relations. In simple terms, it is the ability to identify the key issues from a base of information, the ability to separate a problem into its sub-elements in order to determine the cause and draw conclusions.

Systematic thinking is creating a methodology to solve a problem within a well-defined order. Systematic thinking can be subdivided under four headings:

  • Understanding what the problem is and thoroughly analysing it.

  • Examining different components of the problem and coming up with multiple solutions.

  • Deriving a strategy and evaluating possible solutions aligned with your strategy.

  • Being decisive and staying on track with the strategic path chosen.

 

Once you adapt to this thinking mechanism you are more likely to have the capability to comprehensively evaluate the options and give effective decisions. For coding, this capability is essential. The first step in coding should always be understanding what the objective, conditions and limitations are, and then deriving a solution in a systematic way. Following this methodology, one can effectively code and meet the objectives set. This methodology is demonstrated in the example below.

Q. A sailboat needs to sail to island A, island B and island C and then return to its initial point. What is the most logical order for the sailboat to sail to these islands?

In order to come up with a solution, one might answer this question by calculating the distance between the islands in order to figure out the shortest total distance that the sailboat can travel. This way of answering the question would not demonstrate an analytic and systematic thinking ability, as the person answering would have overlooked the objective, conditions and limitations.

Analytic and systematic thinking would involve evaluating the question comprehensively.

First of all, the question asks what is the most ‘logical’ order that the sailboat should sail to these islands. Does logical mean the shortest distance, the fastest way, the safest way or the most fuel-efficient way for the sailboat to travel?

After clarifying the objective, the factors affecting a sailboat’s travel should be investigated. Factors such as the direction of the wind, ocean currents and weather are critical in determining the route for the sailboat.

Once the objective is determined, the methodology and strategy should be derived to come up with a solution.

Following an analytic and systematic thinking approach, one would be in a position to answer the question above effectively. When faced with a problem, one needs to think comprehensively, identify the objective and if needed break down the components of the problem and build a strategy accordingly.

Analytical and systematic thinking capabilities are the fundamentals of coding education. When coding a computer program, one needs to understand the objective, evaluate the functions that will be used, and comprehend the advantages and disadvantages of using these functions. Afterwards, a systematic method should be derived and the strategy should be adapted. By following this approach, one would succeed in coding in the shortest amount of time with minimum mistakes.

WHAT IS AN ALGORITHM?

An algorithm can be defined as a set of mathematical instructions or necessary steps that will help to calculate an answer to a problem. In programming creating algorithms consists of three main headings:

  • Variable: The names that hold a value, which can stay constant or change depending on conditions or information passed to the program.

  • Algorithm: The framework in which the necessary steps to reach the solution is set.

  • Flow diagram: The schematic way of displaying the steps of the solution in order depending on their functionality and priority.

 

It is important to acknowledge that algorithms are not programming languages. In coding, an algorithm is a guiding strategic method.  The example below demonstrates what an algorithm consists of and its importance.


Q. Let’s imagine we are coding a computer program which calculates whether students have passed or failed a course depending on their exam scores. Let’s assume that an English course student have 3 written exams that are equally weighted and that the passing score is 45%. If you were asked the question whether Robert has passed or failed his course, how would you answer the question?


The first step would be asking Robert what were his exam scores from his written exams and then second step would be taking their average. If the average was less than 45, you would conclude that he has failed. If the average was equal or higher than 45, you would conclude that he has passed. By doing this, you have found a solution method to determine whether Robert has failed or passed his course, which is basically what creating an algorithm is. Creating a methodology to derive a solution to achieve your objective and defining each step that is necessary for your solution is called creating an algorithm.


Below is the example of an algorithm for the problem above:


     Step 1: Start
     Step 2: Enter the student’s name
     Step 3: Enter first written exam score
     Step 4: Enter second written exam score
     Step 5: Enter third written exam score
     Step 6: Take the average of three written exam scores
     Step 7: If average is below 45;
     Step 8: Failed
     Step 9: If average is equal or above 45;
     Step 10: Passed
     Step 11: Stop


Seen above is the algorithm that needs to be created prior to coding the computer program. “Start” and “Stop” are commands to inform the computer when the task should be completed. In the following chapters, we will look into these commands in more depth.


One of the most enjoyable parts of coding is creating an algorithm. One can code a computer program to solve the same problem, but in many different ways and with different algorithms.  Even though the result is the same, the way the program works will vary depending on how the programmer thinks. This freedom of variety and flow of thought in coding gives programmer the chance to be creative and find alternative solutions.


Q. As an exercise, let’s see the variety that can emerge in creating an algorithm. Let’s discuss how we can create an algorithm for a computer program that asks the user to enter 6 two-digit numbers and calculates the largest common divider. After the discussion, let’s write the necessary steps for the algorithm.

BASIC CODING SKILLS, FUNCTIONS AND STATEMENTS

In the previous chapter, we used conditional statements whilst creating algorithms. The most common statements used in coding are very similar to the conditional situations faced in daily life. This chapter will look into the widely used conditional statements (‘if’, ‘while’ and ‘for-loop’). Let’s start with looking at what these statements are and where they could be used. 

  • ‘if’: A feature that performs different computations or actions depending on whether a condition is true or false

For instance, in the previous chapter we had created an algorithm to determine whether Robert had passed or failed his course:


     Step 7: If average is below 45;
     Step 8: Failed
     Step 9: If average is equal or above 45;
     Step 10: Passed


The steps above could be written mathematically as the following: 
 

     if (average<45)
          Course Result = Fail

     if (average=45 or average>45)
          Course Result = Pass


In the above example ‘if’ statement is used. In the following chapters, we are going to learn how ‘if’ statement is truly exercised on the Arduino Software (IDE).

  • ‘while’: A control flow statement that allows code to be executed repeatedly depending on whether a condition is true or false.

 

For instance, let’s imagine we are designing a self-driving car and we are programming that the car follows traffic rules. Our objective is writing a code that commands the car to stop at red light.


     Step 1: At red light;
     Step 2: Stop.
     Step 3: When not at red light;
     Step 4: Go.

 

After having a look at the algorithm above, you might wonder what is the difference between ‘if’ and ‘while’ statements. ‘if’ statement checks if an expression is true or false, and then runs the code inside the statement only if it is true. ‘while’ statement continues to execute the code as long as the given condition is true. It is basically a loop function. For instance, if we had used ‘while’ statement for Robert’s pass or fail test, the program would have kept repeating whether Robert failed or passed his course and wouldn’t have let the program move on to the next command.


For the self-driving car example, the ‘while’ statement is appropriate as our objective is to make the car stop as long as it is at a red light. When at green light it will continue going as the condition to stop have not been met. ‘else’ statement can be used in order to command what to do if the same condition is false.


We would write this command in the following way: 
 

     While (Traffic Light = Red)
          State of Car = Stop
     Else
          State of Car = Go

  • ‘for-loop’: A control flow statement for specifying iteration, which allows code to be executed repeatedly. This statement consists of three parts:

 

     for (Current State, Condition, New State)
 

For instance, let’s imagine we are designing a robot and we are coding that the robot needs to flash a blue light 5 times with one-second gaps in between. In order to program a computer-based device to light 5 times, we need to define a variable. Let this variable be ‘x’ with the initial value of 0.


     Step 1: When x<5;
     Step 2: Flash the blue light.
     Step 3: Wait for a second.
     Step 4: Stop flashing the blue light.
     Step 5: Wait for a second.
     Step 6: Increase x’s value by 1.

 

This loop will allow the robot to flash the blue light as long as x’s value is less than 5. Once x’s value exceeds 5, as the condition will no longer be valid, the robot will stop flashing the blue light. This command can be programmed as the following:


     for (x = 0, x < 5, x = x + 1)
 

          State of blue light: Flash.
               Wait one second.
          State of blue light: Don’t Flash.
               Wait one second.

In the following chapters, we will see different applications of these statements.


Q. In order to understand the statements better, let’s do an exercise. Let’s add another function and program the robot to give a signal when the battery is low. The code should involve commanding the robot to flash a red light three times in case the battery level fall below 10%. Which of the statements we have learnt so far could be used and how could we form an algorithm?

GETTING FAMILIAR WITH THE ARDUINO SOFTWARE (IDE)

In this chapter, we will be turning on our PC and working on the Arduino Software (IDE). When using Creoqode Pyxa, we will be programming and uploading our codes using this platform.


In order to download Arduino IDE please click on the link below:
 

https://www.arduino.cc/en/Main/Software

Following a very simple download process, when you open Arduino IDE for the first time you will see the screen below.
 

Prior to using Arduino IDE, there are some fundamental basics that we need to learn.

 

  • Verify: Checks your code for errors compiling it.

  • Upload: Compiles your code and uploads it to the configured board. Before uploading your sketch, you need to select the correct items from the Tools > Board, Tools > Processor and Tools > Port menus. While working with Creoqode Pyxa, you will be choosing 'Arduino Nano' from Board menu, 'ATmega328' from Processor menu and the serial port that Pyxa is connected to from Port menu. Serial port should automatically appear in the Port menu right after you connect Pyxa to your computer. If you experience any upload problems, try 'ATmega328 (Old bootloader)'.

  • Serial Monitor: Displays serial data being sent from Creoqode Pyxa or an Arduino board. To send data to the board, enter text and click on the "send" button or press enter.

To have a more in depth understanding of the Arduino Software (IDE), please visit:

 

https://www.arduino.cc/en/Guide/Environment

 

One of the terms you have to get familiar with is ‘sketch’, which is the name of the computer program on the Arduino platform. Codes that will be uploaded to Creoqode Pyxa will be referred as sketch. In the following chapters, we will be looking into the structure of a sketch.

SETUP() & LOOP() FUNCTIONS & LIBRARIES

 

The setup() function is used when a sketch starts. It is used to initialise variables, pin modes and start using libraries. The setup function will only run once, after each power up or reset of the Arduino board.
 

The loop() function does exactly what its name suggests, loops consecutively, allowing your program to iterate continuously, by refreshing variables, receiving signals, evaluating them, sending signals etc. Loop() is the function which is continuously iterated in Creoqode Pyxa or other Arduino development boards. It is not possible to programme without using setup() and loop() functions. Even if you do not include anything in these functions, you still need to include these two functions in your sketch.


     void setup() {
          pinMode (ledPin, OUTPUT) ;
     }

 

In the example above ‘setup’ function is used. ‘void’ signals that after setup() function is executed, no value will be returned. Code which is in between these parenthesises ‘{ }’, are commands of the function. Within a function another function that was previously defined can be used. In the example above, pinMode(a, b) function was called within setup() function.


Libraries are files written in C or C++ that provide your sketches with extra functionality. One can use existing libraries or create their own library. By writing at the beginning of the code ‘#include’ and the library name, the sketch will be uploaded to Creqode Pyxa with the library mentioned. In the following chapters, we will gain a better understanding of what libraries are.

COMMENT / UNCOMMENT

At the beginning of each sketch it is useful to describe what your programme does, how it works, which date it was coded, the name of the programmer and any other information that is thought to be necessary. In order to write these as comments and for them not be perceived as codes by your computer, it is important to add ‘/*’ sign at the beginning and ‘*/’ sign at the end of each comment. Without interrupting the flow of codes, these notes will allow other users to have a better understanding of what the sketch does.


Similarly, if one needs to include notes in between codes, one needs to add ‘//’ sign to the beginning of the notes in order for the computer to recognise what is written as comments and not codes. As seen in the example above:    


“// put your setup code here, to run once:” and “// put your main code here, to run repeatedly:” are comments that are not perceived as commands by the computer and that inform other users about the functions of a code piece.
 

DEFINING VARIABLES & ASSIGNING VALUES

The first step in coding is to define a variable and assign a value to it. For instance in mathematics, we are creating variables as such:


     a = 3
     b = 2


In the example above we have created two variables ‘a’ and ‘b’ with the values of 3 and 2, respectively.


When programming we will be assigning values to the variables in a similar way. The only difference between using variables in programming and mathematics is that in coding we also need to inform the computer about the type of variable we have created.


Let’s start with looking at the most common types of variables used in programming:

 

  • Integer (int): An integer is a whole number that can be positive, negative, or zero.

  • Float (float): Float is a term used to define a variable with a fractional value. Numbers created using a float variable declaration will have digits on both sides of a decimal point. This is in contrast to the integer data type, which houses only a whole number.

  • Double (double): Double is used to define numeric variables holding numbers with decimal points, which accommodate fractions. Double can have up to 16 digits after the decimal point, which is more than float that has up to 8 digits.

  • Character (char): Character is a unit of information that roughly corresponds to a grapheme, grapheme-like unit, or symbol, such as in an alphabet in the written form of a natural language. 

IF, WHILE & FOR-LOOP STATEMENTS WITH THE ARDUINO SOFTWARE (IDE)

In this chapter, we will learn how to code using ‘if’, ‘while’ and ‘for-loop’ statements.

 

  • ‘if’: This performs different computations or actions depending on whether a condition is true or false.

 

Let’s have a look at the example below:
 

     if ( a > 50 ) {
       // do something
     }
     else {
       // do something else
     }

 

The sample pattern seen above, is a sample ‘if’ statement that can be used on Arduino IDE platform. The code translates as ‘do something’ if ‘a’ is larger than 50 and if ‘a’ is not larger than 50 then ‘do something else’. 


The first thing you should notice in this style of coding is the parenthesis ‘{ }’. This parenthesis groups together the commands we want to be iterated depending on the condition. If the command is written outside the parenthesis, the command will be independently iterated regardless of the statement. 


Second thing you should notice is the comment sign, ‘//’. This tells the computer that any text piece that comes after this sign in the same line will not be perceived as code but as a comment. When coding, if the programmer wants to include notes for explanation, this sign should be used so that the notes or comments are not perceived as commands.  
 

Let’s have a look at the example below:
 

     int a = 9 ;
     int b = 3 ;
     int c ;

 

     If ( a > 50 ) {
          c = a * b ;
     }
     else {
          c = a / b ;
     }

 

In the example above, the value of ‘c’ would be 3. As ’a’ is not larger than 50, the command that will be iterated is c = a / b.
Another point worth noting down is whilst using ‘if’ statements one needs to know the mathematical symbols used in coding. Below are a few:


     if ( x == y ) // if x is equal to y
     if ( x != y ) // if x is not equal to y
     if ( x <  y ) // if x is smaller than y 
     if ( x >  y ) // if x is larger than y 
     if ( x <= y ) // if x is smaller than or equal to y 
     if ( x >= y ) // if x is larger than or equal to y

 

  • ‘while’: A control flow statement that allows code to be executed repeatedly.

 

Let’s have a look at the example below:
 

     int a = 0;
     int b = 2;
     int c = 4;
     int d = 0;

 

     while( a < 3 ) {
       d = a * b + c + d ;
       a++ ;
     }

 

The loop above will continue until the condition of ‘a<3’ no longer holds. The same principle applies to ‘for-loop’ statement.


For instance, let’s imagine we are designing a smart car, which automatically lights its headlights at sunset and keeps them lit until sunrise. For this example, an algorithm using while would be suitable, which can be seen below:


     while ( State of Sun == Sunset ) {
          Light the headlights ; 
     }

 

  • ‘for-loop’: a control flow statement for specifying iteration, which allows code to be executed repeatedly.

 

In the example below, first we need to introduce the variables to the computer:
 

     int b = 2;
     int c = 4;
     int d = 0; 

 

     for (int a = 0 ; a < 3 ; a++){
          d = a * b + c + d;
     }

 

The code above translates as such: as long as ‘a’ is smaller than 3, iterate the given operation ‘d = a * b + c + d’ and then increase the value of ‘a’ by 1. Let’s take a look at how this function works:


When a = 0, the condition of a < 3 holds. Therefore:
d = 0 * 2 + 4 + 0, following this statement, the new value of ‘d’ is 4. 
Now increment the value of ‘a’ by 1.


When a = 1, the condition of a < 3 holds. Therefore:
d = 1 * 2 + 4 + 4, following this statement, the new value of ‘d’ is 10. 
Now increment the value of ‘a’ by 1.


When a = 2, the condition of a < 3 holds. Therefore:
d = 2 * 2 + 4 + 10, following this statement, the new value of ‘d’ is 18.
Now increment the value of ‘a’ by 1.


When a = 3, the condition of a < 3 no longer holds. Therefore: ‘for-loop’ ends here and the final value of ‘d’ would be 18. 
 

 
 
 
 
 
 
 
 

In the example above, a, b, c and d variables are defined, the type of the variables are described and their initial values are assigned. Let’s gain a better understanding of the type of variables used this example. 


One needs to choose the type of variable depending on how many digits after the decimal point one would like the variable to have. For instance, below is an example of how differently the computer would acknowledge number pi if we define it as ‘integer’, ‘float’ and ‘double’:


     (pi = 3.141592653589793238462…)
 

     int pi = 3
     float pi = 3.1415927
     double pi = 3.141592653589793

 

‘Char’ is different than ‘int’, ‘float’ and ‘double’ because in ‘char’ type, programmer defines a unit of information that does not correspond to a numerical value. In the example, pi [ ] = “3.14159” means that ‘pi’ variable has a unit of information that consists of 7 characters. In the following chapters, we will discuss more in depth the use of char type variables whilst working with Pyxa.

 

MATHEMATICAL FUNCTIONS

When using Creoqode Pyxa we will be exercising the four operations. For instance, below is a mathematical function:
 

     y = ( a + 3 * b ) / c
 

In coding languages, this function could be written as such:
 

     int y;
     int a;
     int b;
     int c;

 

     y = ( a + 3 * b ) / c ;
 

As seen, the code is written similar to the mathematical function. The only differences are letting the computer know the type of variable before coding and including ‘;’ sign after each command.

 
We can use this function to find the value of ‘y’ by initialising other variables:
 

     int y;
     int a = 4;
     int b = 6;
     int c = 3;

 

     y = ( a + 3 * b ) / c ;
 

In this example, the value of ‘y’ is 22 / 3, which is 7,3333333333… However, as we defined ‘y’ variable as an integer, the value of ‘y’ will be 7.


As an in-class activity, let’s write the following function in coding language and let’s discuss the different results we get when ‘y’ variable is an integer, float or double:


     y = ( a * b ) / ( c + 4 ) – d

As seen in the examples above, using the four operations whilst coding is quite simple. The list below includes some of the most common mathematical functions used in programming on the Arduino Software (IDE).


Cosinus: y = cos (x);
Sinus: y = sin (x);
Square Root: y = sqrt (x); 
Tangent: y = tan (x); 
Logarithm in base e: y = log (x);
Logarithm in base 10: y = log10 (x);  
Square: y = square (x);

 

INSTALLING LIBRARIES & UPLOADING CODE TO CREOQODE PYXA

Whilst working with Creoqode Pyxa, we will be using Adafruit_GFX as the graphics library and Adafruit_ST7735 as the hardware library. Please find the links below to download these hardware and graphics libraries, both prepared by Adafruit Industries.

 

https://github.com/adafruit/Adafruit-ST7735-Library

 

https://github.com/adafruit/Adafruit-GFX-Library

 

Download the Adafruit_ST7735 library by clicking the green download button near the top right corner, click download .zip and rename the uncompressed folder Adafruit_ST7735. Check that the Adafruit_ST7735 folder contains Adafruit_ST7735.cpp and Adafruit_ST7735.h. Similarly, download the Adafruit_GFX library as well. Rename the uncompressed folder Adafruit_GFX and confirm it contains Adafruit_GFX.cpp and Adafruit_GFX.h. The Arduino Software (IDE) is sensitive to upper and lower case letters, therefore when renaming the folders ensure that you save these files exactly as the name appears here. Place both library folders inside your <arduinosketchfolder>/libraries/ folder. You may need to create the libraries subfolder if its your first library. After completing these steps, restart the Arduino Software (IDE) to see the libraries.

 

In this chapter, we will create a new sketch on the Arduino Software (IDE) and use the template we have discussed in the previous chapter. However, before we do that we need to make sure that in the Arduino Software (IDE) we have chosen the correct development board that we will be uploading our codes; otherwise Arduino IDE will give an error message.


As described previously, in the Arduino Software (IDE), click Tools tab and from Board menu choose Arduino Nano. Creoqode Pyxa has the same technical specifications as an Arduino Nano. Then, click Processor menu and choose Atmega328. This will inform Arduino IDE about which piece of hardware the codes will be uploaded to.


Now let’s turn on Creoqode Pyxa. On Pyxa, you will see two mini USB ports, one on the side and one on the top. Connect Pyxa to your PC with the mini USB port on top which is used for programming. After connecting Pyxa to your computer, go to Tools tab, click Port menu and pick the communication channel that your computer has chosen for Creoqode Pyxa.


Now, type the template code in your sketch which can be copied and pasted through the link below:

 

Creoqode Pyxa - Template Sketch

Please find the screenshot below to see the template you will be using for Pyxa. It includes the libraries in your sketch, defines the pins of the display and the pins that the push buttons and buzzer are connected to. We will explain each line in this template sketch in the next chapter. After copying the lines to your sketch, click upload which you will see on the top left corner of the Arduino Software (IDE). 

Other useful libraries to have are the Timer and Event libraries. You can download them here: Timer & Event Libraries

Follow the method explained above to install these libraries. Place Event.h and Event.cpp under 'event' folder and Timer.h and Timer.cpp under 'timer' folder.

When ‘Done Uploading’ sign appears, you will know the code has been successfully uploaded to Pyxa. As the sketch we have uploaded to Pyxa does not consist of any commands, you will not see anything appearing on your Pyxa at this stage.

GRAPHICAL FUNCTIONS FOR CREOQODE PYXA

In this chapter, we will start coding and uploading them to Creoqode Pyxa. The code we have seen in the previous chapter is always going to be the template format we will be using, let’s start by having a look at it:
 
As discussed in the previous chapters, comments are written in between ‘/*’ and ‘*/’ signs which will prevent the computer from perceiving them as codes. 


By using #include command, we upload Adafruit_GFX and Adafruit_ST7735 libraries. Adafruit_GFX, is a graphics library created by Adafruit Industries and Adafruit_ST7735 is a hardware library specifically prepared for display of Pyxa. These libraries define the functions and communication protocols we will be using whilst working with Creoqode Pyxa. 


#define command allows different variables to be described. These variables define where Pyxa_CS, Pyxa_RST, Pyxa_SCLK, Pyxa_DC and Pyxa_MOSI pins are connected to on Pyxa's circuit board. 


Adafruit_ST7735 Pyxa = Adafruit_ST7735(Pyxa_CS,  Pyxa_DC, Pyxa_RST)  allows us to create the Pyxa function with the defined pins of the display. Therefore, the signals we send using Pyxa functions will reach to the correct address in the display. 

Pyxa.begin() function that is under Setup() function is going to be used only once whenever we turn on Pyxa and it will give the command that Pyxa functions are now usable.


The sample code format we have seen in this chapter will be the format we will always be using whilst working with Creoqode Pyxa.

Let’s take a look at the most commonly used functions whilst working with Creoqode Pyxa:

 

  • Pyxa.drawPixel( x, y, Pyxa.Color565( r, g, b ) )

 

This function commands one pixel to be lit on Creoqode Pyxa screen, or in other words it draws a dot on the screen. As seen above, the function uses three variables. 


Firstly, we will be using coordinates in order to draw a dot on the display which consists of 20480 pixels aligned in a 128 x 160 matrix. We need to define the coordinates in a two-dimensional space in terms of ‘x’ and ‘y’. The pixel on the top left corner has (0, 0) coordinates referred to as the origin, and the bottom right corner has (127, 159) coordinates. 


The third variable determines the colour of the pixel that we have just defined the coordinates of. In order to define the colour of the LED chip, we will be using RGB (red, green, blue) colour system. You can see the colour palette of RGB below:

In order to assign a colour to a pixel, the variables ‘r’, ‘g’ and ‘b’ used in the Pyxa.Color565( r, g, b ) function need to take integer values between 0 and 255. For instance, if you would like a pixel to be lit in red colour you would use Pyxa.Color565( 255, 0, 0 ). Similarly, you would use for green colour ( 0, 255, 0 ), for blue colour ( 0, 0, 255 ). If you would like to use an intermediate colour you would use different combinations of numbers. For instance, for yellow you would mix green and red ( 255, 255, 0 ). To achieve orange, you would lower the intensity of green relative to the red, like this combination ( 255, 160, 0 ).


Let’s exercise this function on Creoqode Pyxa. Choose a pixel and its colour then write the code under loop() function and upload this new sketch to Creoqode Pyxa. Seen in the example below, use the same template code and add under loop() function Pyxa.drawPixel(). Within loop() function, you can use Pyxa.drawPixel() as many times as you like in different colours and coordinates to illuminate pixels.

In the example above the coordinates for ‘x’ is 30, ‘y’ is 10 and the colour combination is ( 255, 0, 0 ). You may choose different coordinates and colours to get different results on your Creoqode Pyxa screen.

Now let’s have a look at other functions we will be using:

 

  • Pyxa.fillRect( x, y, a, b, Pyxa.Color565( r, g, b ) )


Using this function, we can draw a rectangle and light its area. We can determine the location and size of the rectangle by typing the coordinates of the top left corner (x, y) and the length of the sides (a, b). The colour function has the same principle for all types of functions.

 

  • Pyxa.drawRect( x, y, a, b, Pyxa.Color565( r, g, b ) )


This function is very similar to fillRect() function, however instead of lighting the entire area of the rectangle it will only light the LED chips in the circumference of the rectangle, as seen in the picture below.

  • Pyxa.drawLine( x1, y1, x2, y2, Pyxa.Color565( r, g, b ) )

 

Using this function we can draw a line in between two points we determine, ( x1, y1 ) and ( x2, y2 ). 

  • Pyxa.drawCircle( x, y, r, Pyxa.Color565( r, g, b ) )

  • Pyxa.fillCircle( x, y, r, Pyxa.Color565( r, g, b ) )

 

Using these functions, you can draw a circle. (x, y) determine the centre point and ‘r’ determines the radius of the circle. Similar to the rectangle example, functions starting with ‘fill’ will be lighting the entire area of the circle whereas functions starting with ‘draw’ will be lighting only the LED chips in the circumference of the circle.

The functions below allow us to write on the screen: 

  • Pyxa.setTextSize(1);

 

This function determines the size of the text. In the parenthesis, the number ‘1’ is equivalent to 8 pixels in height for each character. ‘2’ and ‘3’ respectively corresponds to 16 and 24 pixels in height, and it continues increasing in number as the multiples of 8 pixels. 

  • Pyxa.setCursor(0, 0);

 

This function determines the left top corner coordinates of the text. In other words, it determines where the writing will start from on the screen.

  • Pyxa.setTextColor(Pyxa.Color565(r, g, b));

 

This function determines the colour of the text.

  • Pyxa.print(“HELLO”);

 

This function allows you to enter the text you wish to write on the screen. One important thing to note down here is to include “ ” these quotation marks inside the parenthesis.

 
 
 

Now, let’s look at some other functions we will be using when working with Pyxa. In many sketches, we will be coding with these functions.


pinMode():  This function allows you to define each pin either as an input or output pin. The pin you have defined as an input will be reading the signal sent from a sensor or button, whereas the pin defined as an output will be activating a motor or a pixel by sending an electric signal. For instance, when we write pinMode ( 9, INPUT ) the 9th pin on Creoqode Pyxa will be activated as an input pin. 


digitalRead(): This function allows you to read values from a digital pin that is defined as an input pin. It measures the voltage level of the pin. 


delay(): This function allows you to pause the program for the desired period of time. The parameter used in this function is in milliseconds, therefore writing delay(1000) means that the program will be paused for 1 second.


For instance: 


pinMode ( 7, INPUT ); //  This function determines the 7th pin as the input.
digitalRead ( 7 ); //  This function is reading the signal from the 7th pin.
delay (1000); // This function pauses the programme for a second.


It is important to note that delay() has some disadvantages if you have multiple functions working together as it pauses all the functions used in the programme at once. Delay() can be used for simple codes but in the following chapters we will introduce more effective functions which can be used instead of the delay() function.

MOVING PIXELS WITH BUTTONS

We have looked at functions that allow us to draw shapes on Creoqode Pyxa and now we will be looking at how we can move these shapes using buttons.


We will start this chapter by explaining the lines about buttons in the template sketch. We are defining these buttons so that Creoqode Pyxa recognises them. The circuit board of Pyxa is designed and manufactured so that each button is connected to a specific pin of the processor, which is Atmega328 in this case. Now using the Arduino Software (IDE), we need to define which pins are connected to which buttons, and then define these pins as input pins. 


In order to do that, we define the buttons as a ‘int’ variable and then equal these variables to the specific pin numbers the buttons are connected to:

int button1 = A2; // Left
int button2 = A3; // Down
int button3 = A4; // Right
int button4 = A5; // Up

int button5 = 7;  //  Y
int button6 = 6;  //  B
int button7 = 5;  //  A
int button8 = 2;  //  X

Then, we create variables which can store the information of whether the buttons are being pressed or not. We do not need to assign initial values to these variables, because they will take their value from the loop() function. 
 

int button1state = 0;
int button2state = 0;
int button3state = 0;
int button4state = 0;

int button5state = 0;
int button6state = 0;
int button7state = 0;
int button8state = 0;

Now, we write the commands under the setup() function. As you remember from the previous chapter, pinMode() function allows a pin to be defined as an input or output pin. We have defined the pin number each button is connected to and now we are defining the roles of each pin. Each time the program runs, the command below will be introducing the pins to the Pyxa once.


pinMode(button1, INPUT_PULLUP);
pinMode(button2, INPUT_PULLUP);
pinMode(button3, INPUT_PULLUP);
pinMode(button4, INPUT_PULLUP);
pinMode(button5, INPUT_PULLUP);
pinMode(button6, INPUT_PULLUP);
pinMode(button7, INPUT_PULLUP);
pinMode(button8, INPUT_PULLUP);

Here you should pay attention to INPUT_PULLUP. This variable is used to activate the internal resistors when using the buttons. Pyxa has internal resistors of 20k ohm, that can be activated using the Arduino Software (IDE). When we define a pin as INPUT_PULLUP, it means that we provide 5V through a 20k ohm resistor to that pin. As you remember during the assembly process, one of the terminals of the buttons was connected to the I/O pins and the other terminal was connected to the ground. Therefore, if we do not activate the resistor by using INPUT_PULLUP, we would be connecting a 5V pin to the ground directly, which in other words would cause a short circuit. In order to avoid this situation, we need to activate the resistor and limit the current passing through the pin. (As you remember: V = I * R ). If we would like to use INPUT instead of INPUT_PULLUP, we had to connect some resistors to our system in order to avoid short circuits. INPUT_PULLUP makes the assembly easier and also it saves us from using unnecessary resistors.


We need to get the data and save it to the variables that will store the information of whether the buttons are being pressed or not. By doing this, we will be able to give commands when the values of these variables change. As you remember we had looked at digitalRead() function in the previous chapter. Under loop() function, we write the following:

button1state = digitalRead(button1);
button2state = digitalRead(button2);
button3state = digitalRead(button3);
button4state = digitalRead(button4); 
button5state = digitalRead(button5);
button6state = digitalRead(button6);
button7state = digitalRead(button7);
button8state = digitalRead(button8);


When the buttons are not being pressed the pins will have the value ‘HIGH’ and when they are being pressed they will have the value ‘LOW’. When buttons are not pressed, pins are supplied with 5V, reading HIGH consequently. When buttons are pressed, pins will be directly connected to ground, thus reading LOW. These values will be sent through to the variables that store the information of the buttons being pressed or not. 


In our sketch, we define the state ‘LOW’ as ACTIVATED, because in the following chapters when working with buttons, defining the buttons pressed state as ‘ACTIVATED’ will simplify the process. 


     #define ACTIVATED LOW
 

We have defined the pins that are connected to the buttons and the variables that will store the information of whether the buttons are being pressed or not. Now, using the functions that we learned to draw shapes, let’s try to move the pixels on the screen.


Before we start coding, let’s create an algorithm that will move a pixel using Pyxa's buttons such as the following:


     Step 1 – On the screen, draw a pixel on a coordinate and in a colour you wish.
     Step 2 – If the upper button is pressed;
     Step 3 – Move the pixel upwards.
     Step 4 – If the lower button is pressed;
     Step 5 – Move the pixel downwards.
     Step 6 – If the left button is pressed;
     Step 7 – Move the pixel left.
     Step 8 – If the right button is pressed;
     Step 9 – Move the pixel right.

 

Let’s write the coordinates of the pixel with ‘x’ and ‘y’ variables. So that, when we increase the value of ‘x’, the pixel will move to the right and when we decrease the value of ‘x’, the pixel will move to the left. Similarly, when we increase the value of ‘y’, the pixel will move downwards and when we decrease the value of ‘y’, the pixel will move to upwards.


When creating our algorithm we used ‘if’ condition, therefore we need to use if() statement in our code. Let’s translate the steps above into coding language.
 

First of all, let’s define ‘x’ and ‘y’ variables which will determine the coordinates of the pixel and let’s give them initial values.
 

     int x = 32;
     int y = 16;
 

     Step 1 – On the screen, draw a pixel on a given coordinate and in a colour you wish. (In this example a green pixel on                         coordinates (32, 16) will be drawn)
     Step 1 – Pyxa.drawPixel( x, y, Pyxa.Color565( 0, 255, 0));

     

     Step 2 – If the upper button is pressed;
     Step 2 – if( button1state == ACTIVATED ){

     

     Step 3 – Move the pixel upwards.
     Step 3 – y--;

 

If the upper button is pressed the value of ‘y’ variable will decrease by 1, which will move the pixel upwards. The initial coordinates were (32, 16). A decrease by 1 for ‘y’ variable means the new coordinates are (32, 15), which will move the pixel in the direction we wanted. Let’s write the same code for the other direction buttons as well.

     Pyxa.drawPixel( x, y, Pyxa.Color565( 0, 255, 0));
 

     if( button1state == ACTIVATED ){
          y--;
     }
     

     if( button2state == ACTIVATED ){
          x--;
     }

 

     if( button3state == ACTIVATED ){
          y++;
     }

 

     if( button4state == ACTIVATED ){
          x++;
     }


Using the code above, you can use ‘x’ and ‘y’ variables to move pixels using direction buttons.
 
Let’s upload this code to Creoqode Pyxa and see whether our code is working or not.

 

As you will realise we have two problems that arise:
•    Instead of one pixel moving, a line is being drawn in the direction it should be moving.
•    The pixel moves way too quickly to be easily controlled.

 

Now let’s try to solve these problems. First of all, the reason the pixel is drawing a line is because when defining new coordinates for the pixel we are not updating the previous coordinates by turning them off. In the example above, as we didn’t update the previous coordinate when the pixel moved from coordinate (32, 16) to (32, 15), we created new pixels along the way, which resulted in us getting two different pixels with coordinates of (32, 16) and (32, 15).


In order to avoid this situation, we need to turn off the pixel that is lit in the previous coordinates once the pixel moves to a new coordinate. In simple terms, if a pixel with (x, y) coordinates is lit green, when the pixel moves to (x, y+1), the pixel in (x, y) position needs to be turned off.


Writing the code below can satisfy this condition:
 

     Pyxa.drawPixel( x, y, Pyxa.Color565( 0, 255, 0));
 

     if( button1state == ACTIVATED ){
          x--;
          Pyxa.drawPixel( x+1, y, Pyxa.Color565( 0, 0, 0));
     }

 

     if( button2state == ACTIVATED ){
          y++;
          Pyxa.drawPixel( x, y-1, Pyxa.Color565( 0, 0, 0));
     }

 

     if( button3state == ACTIVATED ){
          x++;
          Pyxa.drawPixel( x-1, y, Pyxa.Color565( 0, 0, 0));
     }

 

     if( button4state == ACTIVATED ){
         y--;
         Pyxa.drawPixel( x, y+1, Pyxa.Color565( 0, 0, 0));
     }

 

As seen in the code above, after each movement the pixel in the previous position has been turned off by Pyxa.Color565(0,0,0) command. In RGB giving the value of 0 to red, green and blue results in black colour and giving the value of 255 to red, green and blue results in white colour.


For instance, if a pixel moves to the right from (32, 16) coordinates to (33, 16) coordinates, the pixel at the current coordinates (x, y) will light green and the pixel in the previous coordinates (x-1, y) will turn off.
 

Let’s upload and test the code in Creoqode Pyxa.

As you see we have solved the problem of mistakenly forming a line. So now, we can solve the problem of the pixel moving too quickly. As we are not using a time-bounded function, the speed in which the pixel moves depends on the performance of the processor on Creoqode Pyxa. We will be using the delay() function we introduced in the previous chapters in order to adjust the speed of the pixel moving. 


Let’s write delay(50) within the loop() function of the code we just uploaded. By doing this, we are commanding the microcontroller to stop 1/20th of a second within each loop. In other words, when the button is pressed, in 1 second a pixel can move 20 units maximum, in any given direction. Within the delay() function you can write different time values and adjust the speed of the pixel movement as you wish.

Now that we have learnt how to command the direction buttons, let’s look at how to use buttons numbered 5 and 6. In this exercise, instead of commanding the direction of the pixel to change, let’s command the size of the shape to change.


In the code above, we used Pyxa.drawPixel() function to draw a pixel. Now let’s change this function with Pyxa.drawCircle() function. The direction buttons will have the same command as before and will move the central point of the circle we draw. Buttons numbered 5 and 6 will command the radius to decrease or increase.


As you remember, Pyxa.drawCircle( x, y, r, Pyxa.Color565( r, g, b)) consisted of 3 variables apart from colour. ‘x’ and ‘y’ determined the coordinates and ‘r’ determined the radius. Let’s think of an algorithm and write a code, which will increase ‘r’ when we press button 5 and decrease ‘r’ when we press button 6. 


     Pyxa.drawCircle( x, y, r, Pyxa.Color565( 0, 255, 0));
 

     if ( button5state == ACTIVATED ) {
          r--;
          Pyxa.drawCircle( x, y, r+1, Pyxa.Color565( 0, 0, 0));
     }

 

     if ( button6state == ACTIVATED ) {
          r++;
          Pyxa.drawCircle( x, y, r-1, Pyxa.Color565( 0, 0, 0));
     }

 

Let’s upload this sketch to Creoqode Pyxa and test it. Let’s discuss if we have a problem that needs solving. In this chapter, we learned how to define buttons, how to move and change shapes on our Pyxa using conditional statements when the buttons are being used. 

DRAWING A CHARACTER & MOVING IT

In this chapter, we will learn to design and draw characters that we create and move them based on a time interval. The most exciting part of creating our own video games will be designing our own characters and visuals. 


First of all, let’s start with drawing a character. Our first step is to assign a number for the colour of each pixel we will be using in our character, such as for black 0, for pink 1, for yellow etc. The assigned numbers are entirely up to you. Once you have assigned the numbers, draw a matrix in the size you wish. You can draw this on your notebook if you prefer for practising the character you are designing.


For this example, let's draw a 7x7 pixel smiley face on Pyxa's display.

Seen below is a matrix which has 7x7 pixel size:

As we want a smiley face, it will look as such:

In order to draw the shape above in Pyxa we need to assign a number to the colour we will be using. In the example above we are using black and yellow. For black let’s assign ‘0’ and for yellow let’s assign ‘1’. In accordance with the smiley face above, if we fill in the matrix with these numbers we will have the following:

Now let’s write this matrix on the Arduino Software (IDE).


In order to create a character, we will need ‘char’ type variables. Let’s define the variable type we will be using for our character as ‘const char’.


     const char smiley[] = {
     0, 0, 0, 0, 0, 0, 0,
     0, 0, 0, 0, 0, 0, 0,
     0, 0, 0, 0, 0, 0, 0,
     0, 0, 0, 0, 0, 0, 0,
     0, 0, 0, 0, 0, 0, 0,
     0, 0, 0, 0, 0, 0, 0,
     0, 0, 0, 0, 0, 0, 0
     };


This matrix will be the template for our character. As we defined 7x7 pixel for the smiley face the matrix is in this size. You can change the size of the matrix depending on the character you would like to form.


There are three important things to pay attention here: to use [] sign after defining the name of the matrix, to use { } sign on the outside when writing the elements of the matrix, and to separate these elements by a comma. 


In the example above, each pixel is defined as 0, which means depending on which colour we assign to 0, we will get a square consisting of pixels in that colour. However, our objective is not to form a square but to form a smiley face therefore let’s place the numbers in the matrix we had formed previously into here.


     const char smiley[] = {
     0, 0, 1, 1, 1, 0, 0,
     0, 1, 1, 1, 1, 1, 0,
     1, 1, 0, 1, 0, 1, 1,
     1, 1, 1, 1, 1, 1, 1,
     1, 0, 1, 1, 1, 0, 1,
     0, 1, 0, 0, 0, 1, 0,
     0, 0, 1, 1, 1, 0, 0
     };

As seen above, we have assigned a number for each pixel’s colour forming our character: 0 represents black and 1 represent yellow. Now, we need Pyxa to read the values from our smiley char file and command different pixels to light in the colours specified in the matrix.


Let’s create an algorithm to achieve our objective:
 

     Step 1 – Read the first character of the char file.
     Step 2 – If character is ‘0’ ;
     Step 3 – Keep the light of pixel off for (0, 0) coordinate (black).
     Step 4 – If character is ‘1’;
     Step 5 – Light the pixel yellow in (0, 0) coordinate.
     Step 6 – Read the second character of the char file.
     Step 7 – If character is ‘0’ ;
     Step 8 – Keep the light of pixel off in (0, 1) coordinate (black).
     Step 9 – If character is ‘1’;
     Step 10 – Light the pixel yellow in (0, 1) coordinate.
     Step 11 – Read the third character of the char file.
     …

 

To summarise the algorithm above: 
 

  1. According to the order of the elements in the char file, we define the coordinates of the pixel we will be commanding.

  2. According to the value of the elements of the char file, we define the colour of the light of the pixel.

In order to do this, we will be using both ‘for-loop’ and ‘if’ statements. Let’s have a look at the example below. 


for (int q = 0; q < 7; q++) {
        for (int w = 0; w < 7; w++) {
                 if ( smiley[q * 7 + w] == 1 )
         
Pyxa.drawPixel(w, q, Pyxa.Color565(255, 255, 0));
                 else
         
Pyxa.drawPixel(w, q, Pyxa.Color565(0, 0, 0));
      }
}


Let’s analyse the code above step by step and understand the working principle behind it: 
 

  • for ( int q = 0; q < 7; q++ ) {
     

“q” variable is defined as an integer and has the initial value of 0. As long as “q” variable has a value less that 7, this ‘for-loop’ statement will repeat. And after each full iteration, the value of “q” will increase by 1. “q” represents the rows in our matrix.


•    for ( int w = 0; w < 7; w++ ) {


“w” variable is defined as an integer and has the initial value of 0. As long as “w” variable has a value less that 7, this ‘for-loop’ statement will repeat. And after each full iteration, the value of “w” will increase by 1. “w” represents the columns in our matrix.


•    if ( smiley[q * 7 + w] == 1 )
Pyxa.drawPixel( w, q, Pyxa.Color565(255, 255, 0) );


According to the values of “q” and “w”, an element from the smiley[] matrix will be chosen and the value of the element will be read. For instance if q = 0 and w = 0, then ( q * 7 + w ) value will be 0. Then, smiley[ 0 ] will call for the first element in the smiley matrix. As the first character is 0, the condition of smiley[q * 7 + w] == 1 will not be held and the command will move to the next line.


•    else
Pyxa.drawPixel( w, q, Pyxa.Color565(0, 0, 0) );


As the character we defined consists of two colours, you do not need to write another ‘if’ function for the pixels that need to be in black colour. When elements in smiley[] is not 1, they will automatically fall under the ‘else’ function.
 

When you copy the code above to our sketch and upload it to Creoqode Pyxa you will see that our character is formed as seen below:

Now let’s change the character within a specific time interval we define. Let’s program to have a happy face for 1 second, followed by a sad face for 1 second. First step is to draw the sad face in a char folder.


     const char smiley[] = {
     0, 0, 1, 1, 1, 0, 0,
     0, 1, 1, 1, 1, 1, 0,
     1, 1, 0, 1, 0, 1, 1,
     1, 1, 1, 1, 1, 1, 1,
     1, 0, 1, 1, 1, 0, 1,
     0, 1, 0, 0, 0, 1, 0,
     0, 0, 1, 1, 1, 0, 0
     };


     const char sadface[] = {
     0, 0, 1, 1, 1, 0, 0,
     0, 1, 0, 1, 0, 1, 0,
     1, 1, 1, 1, 1, 1, 1,
     1, 1, 0, 0, 0, 1, 1,
     1, 0, 1, 1, 1, 0, 1,
     0, 1, 1, 1, 1, 1, 0,
     0, 0, 1, 1, 1, 0, 0
     };

for ( int q = 0; q < 7; q++ ) {
        for ( int w = 0; w < 7; w++ ) {
                 if ( smiley[q * 7 + w] == 1 )
         
Pyxa.drawPixel( w, q, Pyxa.Color565(255, 255, 0) );
                 else
         
Pyxa.drawPixel( w, q, Pyxa.Color565(0, 0, 0) );
      }
}


delay(1000);
 

for ( int q = 0; q < 7; q++ ) {
        for ( int w = 0; w < 7; w++ ) {
                 if ( sadface[q * 7 + w] == 1 )
         
Pyxa.drawPixel( w, q, Pyxa.Color565(255, 255, 0) );
                 else
         
Pyxa.drawPixel( w, q, Pyxa.Color565(0, 0, 0) );
      }
}

 

delay(1000);
 

}
 

By doing this, whenever Creoqode Pyxa completes a ‘for-loop’ (completes drawing the character) with the ‘delay’ function it will wait for 1 second and as our code is written below ‘loop’ function this loop will continue forever.

MOTION WITH TIME-BASED FUNCTIONS

In this chapter, we will examine the limitations of delay() function, and learn about alternative methods that can replace delay() function in circumstances it cannot be used.

In previous chapters, we have learned how to move a pixel by push buttons. In the last lesson, we have designed a character that changes shape at specified time intervals. Now, let’s try to bring these codes together in order to command our device to create a shape-changing character that can be moved with the push buttons.

While moving a pixel with the push buttons, we were changing the values of ‘x’ and ‘y’ variables in the Pyxa.drawPixel() function to relocate the pixel depending on its coordinates.

Similarly, while designing our character, we have used the variables ‘q’ and ‘w’ to locate each pixel that forms the character. In the Pyxa.drawPixel() function, we can add both ‘x’ and ‘y’ variables that relocate the pixel, and ‘q’ and ‘w’ variables that identify the location of each pixel that forms the character. As an example:

     Pyxa.drawPixel( w + x, q + y, Pyxa.Color565(255, 255, 0) );

 

This method will allow us to draw the character we want and to move it with the push buttons.

 

In the previous chapters we had learned that it is necessary to turn off the LED chip in the previous coordinates when moving a pixel to avoid drawing a line rather than moving a pixel. Therefore, when moving a character, let’s remember that we have to turn off all the pixels in the previous location. By using Pyxa.drawLine() function, we can turn them off by just one command. The character we designed is formed of 7 x 7 pixels. If we draw a black line of 7 pixels perpendicular to the movement direction, all the pixels in the previous location can be turned off.

 

Let’s upload our sketch to Creoqode Pyxa and see the results, as demonstrated below:

 

As you will notice, despite achieving our objective, we have encountered a problem which is the lack of speed between movements of our character. Our character does not change location at every 0.1 seconds as we would have preferred, but instead it waits 1.1 seconds to relocate. The reason for this is the delay() function. As discussed previously, delay() function pauses all the iterations in the sketch for the given period of time. During the time interval of 1 second for the character to change shape, no other commands are iterated, which causes the sketch to run slow.

For this specific reason, we have to use another time function that does not have these limitations. Delay() function is not suitable when using at circumstances whereby simultaneous events take place.

Let’s think of an example whereby we might encounter this limitation. Let’s imagine we are at a kitchen cooking two dishes at the same time. Our first dish is a casserole that is cooking on the hob and needs being stirred every 7 minutes, and our second dish is a cake baking in the oven that needs to be checked every 10 minutes. For this situation if you used delay() function, you would start cooking both dishes at the same time, and after stirring the first dish, you would wait another 7 minutes before the delay() function would permit you to check on the cake and therefore you might risk burning the cake. Similarly, after checking on your cake as you would have had to wait 10 minutes before the delay() function would permit you to stir the casserole, you might have burnt your first dish. In our daily life, when completing tasks simultaneously, we check our time and decide which action we need to take at the right time.

Therefore, in simple terms, the sketch we need to code needs to command Pyxa to always check the time and then act accordingly, instead of pausing all the program for a given period of time.  When the time is checked, if 1 second has passed, the character needs to change its shape and if 0.1 second has passed the character needs to relocate its place.

Let’s see how we can code this algorithm. Firstly, we need to define two new variables. The type of our variables is defined as ‘unsigned long’ and the reason behind this decision will be explained below. Let our first and second variable be “character_move”, and “character_change” respectively. “character_move” will define that when the character moves by the buttons, the time between each pixel movement will be 50 milisecond. “character_change” will define that when the character changes its shape, the time between the changes will be 1 second.

 

     unsigned long curtime;

     unsigned long character_move = 50;

     unsigned long character_change = 1000;

 

millis() is a time function previously defined by Arduino IDE. Whenever sketch runs, starting from 0 the chronometer works and carries a time value. This value has approximately 16 digits and therefore we define the type of our variables as long.

 

     curtime = millis();

 

With the execution of loop() function, millis() function will start running. This can be seen as the equivalent of pressing the start button on a chronometer. Once the chronometer starts, we can write commands that will be checking the time at specific time intervals and accordingly executing actions. The conditional functions below check whether the current time exceeds the time required for the character to move. If the current time exceeds the time specified, then the command will be executed and ‘character_move’ variable will be equal to 50 milliseconds more of the current time. By the use of this loop, every 50 milliseconds the command will be executed.

     if (curtime – character_move > 50) {

     …(move)…

     character_move = curtime;

     }

 

Similarly, the code below checks whether the current time exceeds the time required for the character to change its shape, which is 1 second.

 

     if (curtime – character_change < 1000) {

     …(smiley)…

     }

 

     if (curtime – character_change >= 1000 && curtime – character_change < 2000) {

     …(sadface)…

     }

 

     if (curtime – character_change >= 2000) {

     character_change = curtime;

     }

 

By using these functions, instead of pausing the entire programme, our sketch will be continuously checking the time and executing actions at the defined time intervals we have specified.

 

Now, let’s copy the code above into our sketch and remove the delay() function that we had used previously. Once the sketch is uploaded on Creoqode Pyxa, you will see that the problem we had encountered before no longer persists.

COLLISION DETECTION

In this chapter, we are going to learn about ‘Collision Detection’, which is a computational problem of detecting the intersection of two or more objects. We will examine this coding algorithm and structure, which will be essential in programming many different video games.

For instance, you will be using the collision detection if you are programming a racing game, and you want to code that two cars colliding is to be recognized as an accident, or in another game if the character getting shot needs to be recognized as injured, or the blocks in Tetris need to be programmed to stop moving once hitting the ground, or the character in Pac-Man needs to stop moving once it reaches the walls of the maze.

Let’s see an application of collision detection in an example. Let’s have two variables ‘x’ and ‘y’ that will take values of the coordinates of an object on the display of Pyxa. The location of the character we designed is always referred with ‘x’ and ‘y’ variables. Let the coordinates of the top-left pixel of our character be (x, y) and the coordinates of the bottom-right pixel be (x+6, y+6). If the coordinates of an object on Pyxa are between ‘y’ and ‘y+6’, and between ‘x’ and ‘x+6’, this means that the object and our character is in contact.

To understand this better, remember that it is similar to mathematical principles. Two objects displayed on Pyxa can represent two sets, and the pixels they occupy represent members of these sets. When the objects are not in collision, it means they occupy different pixels, thus they do not have any common members. However, if they collide, they are sharing one or more pixels at the same time, which means these two sets have an intersection. This condition will tell us if there is a collision or not.   

Let’s start by adding a couple of code lines to our sketch.

Firstly, we can start by drawing blue lines to the edges of Pyxa. Our aim for this example is to prevent our character from crossing the blue lines. Our command will order our character to stop when it reaches the blue lines, and therefore it will always stay within the boundaries.

Let’s draw the edge lines by using Pyxa.drawLine() command.

     Pyxa.drawLine(0, 0, 127, 0, Pyxa.Color333(0, 0, 255));

     Pyxa.drawLine(0, 0, 0, 159, Pyxa.Color333(0, 0, 255));

     Pyxa.drawLine(0, 159, 127, 159, Pyxa.Color333(0, 0, 255));

     Pyxa.drawLine(127, 0, 127, 159, Pyxa.Color333(0, 0, 255));

Now, we can write a new if() statement under the existing if() for each individual push button. These if() statements will be controlling whether the values of ‘x’ and ‘y’ can change at a given coordinate.

Our previous algorithm was as seen below:

     Step 1 – If the push button ‘1’ is pressed;

     Step 2 – Decrease the value of ‘x’ by 1.

The new algorithm will be as the one below:

     Step 1 – If the push button ‘1’ is pressed;

     Step 2 – If x is larger than 1;

     Step 3 – Decrease the value of ‘x’ by 1.

With this new algorithm, x can be decreased only if x is larger than 1. In other terms, our character will be detecting the edge of the display when it is at the most left point of the screen and will not be crossing the boundaries.

Similarly, if we add the necessary code lines to the other direction buttons as well, we would limit the motion capabilities of our character with the edges of the Creoqode Pyxa’s display. 

     If x > 1

     If y > 1

     If x < 120

     If y < 152

 

Let’s place the motion functions in the Loop() within the statements we have created. At iterations Creoqode Pyxa will be controlling whether the conditions necessary to move the character are met or not.

After uploading the new code to Pyxa, we will see that our character stays within the boundaries of the display.

FIRST VIDEO GAME PROJECT

What you have learned so far has equipped you with the necessary knowledge needed to create various different video games. Prior to creating your first video game, let’s discuss which of the functions you have learned in the previous chapters have been used in creating the video games below and how their coding structure might look like.

1.    Pacman
 

2.    Super Mario
 

3.    Flappy Bird
 

4.    Snake
 

5.    Tetris
 

Now using your creativity it is your turn to create your first video game with Creoqode Pyxa. You will be in a position to come up with numerous video games using different combinations of the functions you have learned in the previous chapters.