DESIGNED & ENGINEERED IN LONDON, UK

© 2019 Creoqode

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 2048.

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. 
 

MATHEMATICAL FUNCTIONS

When using Creoqode 2048 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 2048

Whilst working with Creoqode 2048, we will be using Adafruit_GFX as the graphics library and RGBmatrixPanel 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/RGB-matrix-Panel

 

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

 

Download the RGBmatrixPanel library by clicking the green download button near the top right corner, click download .zip and rename the uncompressed folder RGBmatrixPanel. Check that the RGBmatrixPanel folder contains RGBmatrixPanel.cpp and RGBmatrixPanel.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/Genuino Mega or Mega 2560. Creoqode Mini Mega development board is fully compatible with Arduino Mega 2560. Then, click Processor menu and choose Mega 2560. This will inform Arduino IDE about which development board the codes will be uploaded to.


Now let’s turn on Creoqode 2048. In the kit, you will see two blue USB cables. Pick the one with mini USB terminal and connect 2048 to your computer through the mini USB port on Mini Mega, which can be reached from the top. After connecting 2048 to your computer, go to Tools tab, click Port menu and pick the communication channel that your computer has chosen for Creoqode 2048.


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

 

Creoqode 2048 - Template Sketch

Please find the screenshot below to see the template you will be using for 2048. It includes the libraries in your sketch, defines the pins of the LED display and defines the pins that the push buttons 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). 

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

GRAPHICAL FUNCTIONS FOR CREOQODE 2048

In this chapter, we will start coding and uploading them to Creoqode 2048. 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 RGBmatrixPanel libraries. Adafruit_GFX, is a graphics library created by Adafruit Industries and RGBmatrixPanel is a hardware library specifically prepared for LED matrix displays. These libraries define the functions and communication protocols we will be using whilst working with Creoqode 2048. 


#define command allows different variables to be described. These variables define where A, B, C, D, CLK, LAT and OE pins are connected to on Creoqode Mini Mega development board. 


RGBmatrixPanel creoqode ( A, B, C, D, CLK, LAT, OE, false, 64 )  allows us to create the Creoqode function with the defined pins of the display. Therefore, the signals we send using Creoqode functions will reach to the correct address in the LED matrix display. 


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


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

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

 

  • creoqode.drawPixel( x, y, creoqode.Color333( r, g, b ) )

 

This function commands one pixel to be lit on Creoqode 2048 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 2048 LED chips aligned in a 64 x 32 matrix. We need to define the coordinates in a two-dimensional space in terms of ‘x’ and ‘y’. The LED chip on the top left corner has (0, 0) coordinates referred to as the origin, and the top right corner has (63, 31) coordinates. 


The third variable determines the colour of the LED chip 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 an LED chip, the variables ‘r’, ‘g’ and ‘b’ used in the creoqode.Color333( r, g, b ) function need to take integer values between 0 and 7. For instance, if you would like an LED chip to be lit in red colour you would use creoqode.Color333( 7, 0, 0 ). Similarly, you would use for green colour ( 0, 7, 0 ), for blue colour ( 0, 0, 7 ). 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 ( 7, 7, 0 ). To achieve orange, you would lower the intensity of green relative to the red, like this combination ( 7, 3, 0 ).


Let’s exercise this function on Creoqode 2048. Choose an LED chip and its colour then write the code under loop() function and upload this new sketch to Creoqode 2048. Seen in the example below, use the same template code and add under loop() function creoqode.drawPixel(). Within loop() function, you can use creoqode.drawPixel() as many times as you like in different colours and coordinates to light LED chips.

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

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

 

  • creoqode.fillRect( x, y, a, b, matrix.Color333( 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.

 

  • creoqode.drawRect( x, y, a, b, matrix.Color333( 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.

  • creoqode.drawLine( x1, y1, x2, y2, matrix.Color333( r, g, b ) )

 

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

  • creoqode.drawCircle( x, y, r, matrix.Color333( r, g, b ) )

  • creoqode.fillCircle( x, y, r, matrix.Color333( 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: 

  • creoqode.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. 

  • creoqode.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.

  • creoqode.setTextColor(creoqode.Color333(0,0,0));

 

This function determines the colour of the text.

  • creoqode.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.

Educational Guide to 2048

August 1, 2017 | Creoqode Team

This comprehensive tutorial includes information about the components of 2048 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.

HARDWARE

Let’s begin with a look at the components of Creoqode 2048. Examining the structure and the purpose of these electronic components will help us understand the following chapters better.

CREOQODE MINI MEGA DEVELOPMENT BOARD

 

Creoqode Mini Mega is an Arduino-based development board. In other terms, it is the brain of 2048. Mini Mega receives signals from the buttons and other sensors if there is any connected, and sends out signals to the LED matrix to display what we want. 

 

It is fully compatible with Arduino Mega 2560 and is much smaller in terms of physical size. The fact that Creoqode Mini Mega offers the same technical specifications in a compact package makes it an ideal solution for projects with space restrictions that require numerous input/output pins. Mini Mega allows many electronic gadgets and sensors to be simultaneously used without the need of another microcontroller or a development board.

Mini Mega is based on the ATmega2560 microcontroller that is manufactured by Atmel. This microcontroller has 256 KB of memory to save your codes and 8 KB of RAM. There are 54 digital input/output pins, 16 analog input pins, an oscillator with 16 MHz frequency, ICSP pins for both ATmega2560 and ATmega16U2, and a reset button. Operating voltage for Creoqode Mini Mega is 5V.

As mentioned above, ATmega16U2 is the other microcontroller on Creoqode Mini Mega development board allowing communication with a PC through the USB port. Your PC will immediately recognize Mini Mega and allow data transfer through the USB port due to ATmega16U2. 

CREOQODE 64 x 32 LED MATRIX DISPLAY

 

The display is made of 2048 individual LED chips that are aligned as a 64 x 32 matrix. These LED chips are placed on the printed circuit board with 3 mm distances between each and they work based on the RGB (red, green, blue) colour system. The operating voltage of the display is 5V.

On the backside of the display, there are three connection ports. Input port is the one on the left that is situated next to the Creoqode logo, with the names of each pin printed. The one on the right is the output port and it allows you to build a larger display by connecting another LED matrix, but we will not be using this feature for Creoqode 2048. The one in the middle is the power port and we will be using it to supply the necessary voltage and current to the LED matrix display.

CREOQODE POWER SUPPLIER & CHARGER MODULE

 

This module allows users to supply the necessary voltage and current to Creoqode 2048, to charge the battery and to turn 2048 on/off with the switch mounted on the circuit board.

Micro USB port on the module is to charge the battery. The tiny switch located just next to the micro USB port is the on/off button. When pressed once, 2048 will be turned on, and when kept pressed for 3 seconds, it will be turned off. On the right side of the module, there is a dual USB port. Both USB ports supply 5V voltage, but the one on top can provide 1A current maximum; whereas the one on the bottom can provide current up to 2A.

The battery holder that is soldered to this module is made for lithium ion batteries with standard 18650 size. In the kit, users receive a 18650 lithium ion battery that can supply 3.7V voltage with a capacity of 3400 mAh.

One of the essential roles of the power supplier and charger module is to convert the 3.7V voltage supplied through the battery to 5V which is the operating voltage for Creoqode 2048. Without this module, it would not be possible to run 2048 with a 3.7V battery.

The four LED chips on this module demonstrates the charge level. 4 of them lighting at the same time means the battery is fully charged, and 1 of them lighting means it is low battery.

USB - TTL CONVERTER MODULE

 

This tiny converter is a USB breakout board. If you look closer into a USB port, you will notice there are 4 pins. These are VCC, D+, D- and GND, respectively. This module allows us to use these pins individually.

PUSH BUTTONS

 

The push buttons we use for Creoqode 2048 connect their terminals when pressed, and disconnect them when released. They have a diameter of 16 mm. Due to the screw terminals of the push buttons; no soldering is required during the assembly. Jumper wires can be connected simply with a screw.

JUMPER WIRES, CHARGING & DATA CABLES, POWER CABLE OF THE DISPLAY

 

In the kit, there are jumper wires with both 10 cm and 20 cm length. The fact that they come in different colours help significantly during the assembly, as it might be challenging to keep track of each wire whilst making the connections. There are two blue USB cables, one with a micro USB terminal and the other with a mini USB terminal. Micro USB cable is used for charging the battery; whereas mini USB is used with Creoqode Mini Mega board for data transferring. The last cable, with a USB terminal on one end and a 4-pin connector on the other end is the power cable for the display. It is used for supplying the necessary voltage and current to the display.

WHAT IS ANALYTIC AND SYSTEMATIC THINKING?

After having a brief look at the components of 2048, 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 2048, 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 2048, you will be choosing 'Arduino/Genuino Mega or Mega 2560' from Board menu, 'ATmega2560 (Mega 2560)' from Processor menu and the serial port that 2048 is connected to from Port menu. Serial port should automatically appear in the Port menu right after you connect 2048 to your computer.

  • Serial Monitor: Displays serial data being sent from Creoqode Mini Mega 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 Mini Mega development board 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 Mini Mega or other alternative 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 Mini Mega 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. 

 
 
 
 
 
 
 
 
 
 
 
 
 

Now, let’s look at some other functions we will be using when working with 2048. 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 LED chip by sending an electric signal. For instance, when we write pinMode ( 9, INPUT ) the 9th pin on Creoqode Mini Mega 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 2048 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 Mini Mega Development Board recognises them. As you remember, when assembling 2048, we had connected the positive terminals of the buttons to a different pin through jumper wires. 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 ‘const int’ variable and then equal these variables to the specific pin numbers the buttons are connected to:


     const int button1 = 34;
     const int button2 = 35;
     const int button3 = 36;
     const int button4 = 37;
     const int button5 = 38;
     const int button6 = 39;

 

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;
     int button2state;
     int button3state;
     int button4state;
     int button5state;
     int button6state;

 

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 Mini Mega development board 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);

 

Here you should pay attention to INPUT_PULLUP. This variable is used to activate the internal resistors when using the buttons. Creoqode Mini Mega Development Board 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);


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 2048’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 – creoqode.drawPixel( x, y, creoqode.Color333( 0, 7, 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.

     creoqode.drawPixel( x, y, creoqode.Color333( 0, 7, 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 2048 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 LED chip 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 LED chip in (x, y) position needs to be turned off.


Writing the code below can satisfy this condition:
 

     creoqode.drawPixel( x, y, creoqode.Color333( 0, 7, 0));
 

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

 

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

 

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

 

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

 

As seen in the code above, after each movement the LED chip in the previous position has been turned off by creoqode.Color333(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 7 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 LED chip at the current coordinates (x, y) will light green and the LED chip in the previous coordinates (x-1, y) will turn off.
 

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

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 Mini Mega. 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(100) within the loop() function of the code we just uploaded. By doing this, we are commanding the microcontroller to stop 1/10th of a second within each loop. In other words, when the button is pressed, in 1 second a pixel can move 10 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 creoqode.drawPixel() function to draw a pixel. Now let’s change this function with creoqode.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, creoqode.drawCircle( x, y, r, matrix.Color333( 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. 


     creoqode.drawCircle( x, y, r, creoqode.Color333( 0, 7, 0));
 

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

 

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

 

Let’s upload this sketch to Creoqode 2048 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 2048 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 instance, if we decide to draw a 7x7 pixel smiley face, this will be in the size seen below:

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 2048 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 Mini Mega to read the values from our smiley char file and command different LED chips 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 LED chip off for (0, 0) coordinate (black).
     Step 4 – If character is ‘1’;
     Step 5 – Light the LED chip 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 LED chip off in (0, 1) coordinate (black).
     Step 9 – If character is ‘1’;
     Step 10 – Light the LED chip 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 LED chip 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 LED chip.

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 )
          creoqode.drawPixel(w, q, creoqode.Color333(7, 7, 0));
                 else
          creoqode.drawPixel(w, q, creoqode.Color333(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 )
creoqode.drawPixel( w, q, creoqode.Color333(7, 7, 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
creoqode.drawPixel( w, q, creoqode.Color333(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 2048 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 )
          creoqode.drawPixel( w, q, creoqode.Color333(7, 7, 0) );
                 else
          creoqode.drawPixel( w, q, creoqode.Color333(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 )
          creoqode.drawPixel( w, q, creoqode.Color333(7, 7, 0) );
                 else
          creoqode.drawPixel( w, q, creoqode.Color333(0, 0, 0) );
      }
}

 

delay(1000);
 

}
 

By doing this, whenever Creoqode Mini Mega 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 creoqode.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 creoqode.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:

     creoqode.drawPixel( w + x, q + y, creoqode.Color333(7, 7, 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 LED chips in the previous location. By using creoqode.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 LED chips in the previous location can be turned off.

 

Let’s upload our sketch to Creoqode 2048 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 2048 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.05 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 2048, 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 2048. 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 2048 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 2048 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 2048. 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 creoqode.drawLine() command.

     creoqode.drawLine(0,0,63,0,creoqode.Color333(0,0,7));

     creoqode.drawLine(0,0,0,31,creoqode.Color333(0,0,7));

     creoqode.drawLine(0,31,63,31,creoqode.Color333(0,0,7));

     creoqode.drawLine(63,0,63,31,creoqode.Color333(0,0,7));

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 2048’s display. 

     If x > 1

     If y > 1

     If x + 6 < 62

     If y + 6 < 30

 

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

After uploading the new code to 2048, 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 2048. 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.