DIY-Gamer Programming Overview

General structure

Always include the following at the start of the DIY-Gamer program:

#include <Gamer.h> Gamer gamer;

But if you wish to use infrared communication in your program, then start with:

#include <Gamer.h> #include <GamerIR.h> Gamer gamer; GamerIR infrared;

The setup routine will always be called once, when the DIY-Gamer is switched on. It should include the following instruction:

void setup() { gamer.begin(); // Any further setup goes here }

The main program should be in a function called loop(). This function is called repeatedly, until the DIY-Gamer is switched off.

void loop(){ // Main program goes here }

Input Buttons

To test whether a button has been pressed at any time since the previous test, use one or more of these if statements:

if( gamer.isPressed(UP) ) { /*...*/ } if( gamer.isPressed(RIGHT) ) { /*...*/ } if( gamer.isPressed(DOWN) ) { /*...*/ } if( gamer.isPressed(LEFT) ) { /*...*/ } if( gamer.isPressed(START) ) { /*...*/ }

To test if a button is currently being held down, use one of these if statements:

if( gamer.isHeld(UP) ) { /*...*/ } if( gamer.isHeld(RIGHT) ) { /*...*/ } if( gamer.isHeld(DOWN) ) { /*...*/ } if( gamer.isHeld(LEFT) ) { /*...*/ } if( gamer.isHeld(START) ) { /*...*/ }

Input LDR

The light sensor (LDR, Light Dependent Resistor) can be accessed directly. To get the raw light value (where 1023=dark, and 0=light) use the following:

int value = gamer.ldrValue();

The LDR can also be treated as if it were a button:

if( gamer.isPressed(LDR) ) { /*...*/ }

The above considers it pressed if the raw LDR value rose by 300 since it was last tested. This threshold value of 300 may be too large if you call isPressed often in quick succession, as there may not be enough time between tests for the value to change that much. The threshold value can be set like this:

word newThreshold = 100; gamer.setldrThreshold(newThreshold);

On the latest DIY-Gamer kits the LDR has been replaced by a capacitive touch sensor.

Input Capacitive Touch

The latest version of the DIY-Gamer has a Capacitive Touch button instead of an LDR. You can test whether it is currently being touched like this:

if( capTouch() ){ /*...*/ }

Output Display

The screen data is held in an 8x8 array of booleans, called gamer.display[x][y]. The first coordinate is the horizontal component, from 0 on the left to 7 on the right. The second coordinate is the vertical component, from 0 on the top to 7 on the bottom.

int x=1, y=0; gamer.display[x][y] = true; // switch on second pixel of top row

When you have changed the values of gamer.display, they will not actually be displayed until the following statement is executed:

gamer.updateDisplay(); // update screen with data from display[]

To turn all pixels on (i.e. fill gamer.display with true and update), use this:

gamer.allOn();

To clear the screen, turning all pixels off (i.e. fill gamer.display with false and update), use the statement below. There is no statement for clearing the display array without doing a screen update.

gamer.clear();

To print an 8 byte array onto the display (bytes are rows from top to bottom, high bit on left):

byte imageArray[8] = {0x06, 0x09, 0x09, 0x06, 0,0,0,0}; gamer.printImage(imageArray); // shows an o in top-right corner, rest of screen blank.

You can also change the location on the screen where the array is displayed. The image is allowed to be partly off-screen.

byte imageArray[8] = {0x06, 0x09, 0x09, 0x06, 0,0,0,0}; int xPos = -2; int yPos = 2; gamer.printImage(imageArray,xPos,yPos); // shows an o in the centre, rest of screen blank.

You can display a text, which will be scrolled across the screen. This is a routine that I wrote which was incorporated into the Gamer library.

String text = "Hello world"; gamer.printString(text);

You can display a score in large digits on the screen. The score must be between 0 and 99 inclusive. This is a routine that I wrote which was incorporated into the Gamer library.

int score = 42; gamer.showScore(score);

Lastly, you can set the refresh rate of the screen. The default value is 50. You should not need to change this value, but it is included here for completeness only. If you set it to 25, half the normal value, it means that the Arduino will update the screen and check for button presses twice as often.

word refreshRate = 25; gamer.setRefreshRate(refreshRate);

Output LED

To change the state of the red LED:

gamer.setLED(true);
Switch on the LED.
gamer.setLED(false);
Switch off on the LED.
gamer.toggleLED();
Toggle the LED (change from on to off, or off to on)

To read the current LED state:

boolean ledState = digitalRead(LED);

I tried dimming the LED, by using analogWrite(LED, byteValue); but that did not seem to work.

Input/Output Infra-red

To use the infrared communication, use the following lines at the start of your DIY-gamer program:

#include <Gamer.h> #include <GamerIR.h> Gamer gamer; GamerIR infrared;

Only single characters can be sent over the infrared link. To send a message via infrared:

char message = 'h'; infrared.send(message);

To receive a single character message:

char message = infrared.receive(); // is 0 if no message was received.

Output Buzzer

To produce a tone from the buzzer, use the following:

int note = 220; // note to be played, 0-255 gamer.playTone(note); // start tone delay(120); // wait a bit gamer.stopTone(); // end tone

The frequency played depends on the value passed to playTone - larger values give a lower tone, smaller values a higher tone.


Arduino Language Overview

The language is based on C++. Below I list only the commands and functions useful for the DIY-Gamer, so functions for interrupts or for particular pins on the Arduino are omitted because the code in the previous section should suffice for hardware control.

Data Types

void
-
boolean
{false, true}
char
[-128, 127], character
byte unsigned char
[0, 255], 8 bits
int
[-32768, 32767], 16 bits
word unsigned int
[0, 65535], 16 bits
long
[-2147483648, 2147483647], 32 bits
unsigned long
[0, 4294967295], 32 bits
float, double
[-3.4028235E+38, 3.4028235E+38], 32 bits

Arrays are handled exactly like C and C++, and likewise strings can be handled as arrays of the char type. There is also the String class for higher level string handling.

Functions

Time

unsigned long millis()
Number of milliseconds since program started (i.e. since setup call)
unsigned long micros()
Number of microseconds since program started (i.e. since setup call)
void delay(unsigned long ms)
Pauses for ms milliseconds
void delayMicroseconds(unsigned long us)
Pauses for us microseconds

Maths

In the code below, t stands for any numeric type, such as int or float.

t min(t x,t y)
Minimum of the two numbers x, y (any type). Implemented as macro!
t max(t x,t y)
Maximum of the two numbers x, y (any type). Implemented as macro!
t abs(t x)
Absolute value of the numbers x (any type). Implemented as macro!
t constrain(t x,t a,t b)
Value of x (any type) when constrained to lie within the interval a,b. Implemented as macro!
long map(long v,long fl,long fh,long tl,long th)
Converts v using the map that sends the interval [fl,fh] to [tl,th]. Uses integer arithmetic.
float pow(float b,float e)
Calculates b to power e.
float sqrt(t x)
Calculates square root of x.
float sin(float x)
Calculates sine of x radians.
float cos(float x)
Calculates cosine of x radians.
float tan(float x)
Calculates tangent of x radians.

The functions implemented as macros may evaluate some of the arguments more than once, so the arguments must not have side effects (so do not use for example x++).

Random Numbers

void randomSeed(long s)
Seed the random number generator
long random(long max)
Get random number between 0 (inclusive) and max (exclusive).
long random(long min, long max)
Get random number between min (inclusive) and max (exclusive).

Bits and Bytes

byte lowByte(t x)
Get low byte of x. Equivalent to x&0xFF
byte highByte(t x)
Get high byte of x. Equivalent to (x>>8)&0xFF
byte bit(t n)
Computes value represented by nth bit. Equivalent to 1<<n
void bitSet(t x,t n)
Sets nth bit of x. Equivalent to x |= bit(n)
void bitClear(t x,t n)
Clears nth bit of x. Equivalent to x &= ~bit(n)
byte bitRead(t x,t n)
Read nth bit of x. Equivalent to (x>>n)&1
void bitWrite(t x,t n,t b)
Writes b into nth bit of x. Equivalent to x += (b<<n) - x&(1<<n)

Serial Communication

This is useful for debugging. It allows you to add print statements within your program. The output of these statements appears in a console window in the IDE.

To set up the serial communication you need to include the following header:

#include <SoftwareSerial.h>

and add a statement to the setup function:

void setup() { gamer.begin(); Serial.begin(9600); // rest of the set up for your program }

To print to the serial console, you use one or more of the following commands:

Serial.print(t x);
Print numerical value of x as decimal number
Serial.print(char* string);
Print string of characters
Serial.println(t x);
Print numerical value of x as decimal number, followed by end-of-line characters.
Serial.println(char* string);
Print string of characters, followed by end-of-line characters.
Serial.println();
Print end-of-line characters.

Be careful not to use concatenation on string literals. For example Serial.println("value="+v); will compile but print nonsense. The string is of type char*, and the pointer arithmetic of adding v then results in a pointer to unknown data, which will be printed.

You can also receive data from the PC. To check whether there are characters in input buffer, use this:

if (Serial.available() > 0) { /*...*/ }

To read one character from the input buffer:

int inByte = Serial.read();


Written by Jaap Scherphuis, .

Back to DIY Gamer Home Page