This is a project for Arduino to make a 2D Level, aimed at beginners.

Arduino draws a circle on an LED Matrix that moves around according to readings from a 2D Accelerometer.

Objectives:

* Learn how to draw a circle using simple Maths

* Learn how to use the LOL shield for the Arduino

* Learn how an accelerometer works

Arduino draws a circle on an LED Matrix that moves around according to readings from a 2D Accelerometer.

Objectives:

* Learn how to draw a circle using simple Maths

* Learn how to use the LOL shield for the Arduino

* Learn how an accelerometer works

## Step 1: What You Need

You will need:

* Arduino UNO

* LOL shield (http://jimmieprodgers.com/kits/lolshield/)

* Accelerometer (http://www.oomlout.co.uk/accelerometer-3axis-adxl335-p-247.html)

* Breadboard for wiring up e.g. (http://www.oomlout.co.uk/prototyping-bundle-for-arduino-ardp-p-186.html)

* Some Wires

* Arduino UNO

* LOL shield (http://jimmieprodgers.com/kits/lolshield/)

* Accelerometer (http://www.oomlout.co.uk/accelerometer-3axis-adxl335-p-247.html)

* Breadboard for wiring up e.g. (http://www.oomlout.co.uk/prototyping-bundle-for-arduino-ardp-p-186.html)

* Some Wires

## Step 2: Wire It Up

Attach the LOL shield to the Arduino.

Wire the Accelerometer as follows:

+3V

GND

X => A0

Y => A1

Z => N/C (Not Connected)

Note: The LOL shield does not come with Headers (as shown in the picture), attached to the topside.

I bought some here: http://www.amazon.co.uk/gp/product/B004RASBVY/ref=oh_details_o06_s00_i00

Wire the Accelerometer as follows:

+3V

GND

X => A0

Y => A1

Z => N/C (Not Connected)

Note: The LOL shield does not come with Headers (as shown in the picture), attached to the topside.

I bought some here: http://www.amazon.co.uk/gp/product/B004RASBVY/ref=oh_details_o06_s00_i00

## Step 3: Install the LOL Shield Libraries

Install the Arduino libraries for the LOL shield if you don't have them already.

You can get the link to them from this page:

http://jimmieprodgers.com/kits/lolshield/

You can get the link to them from this page:

http://jimmieprodgers.com/kits/lolshield/

## Step 4: Let's Start With a Circle

We'll start by drawing a circle.

This circle will eventually move around as we tilt the device. But first things first....

We'll illuminate individual pixels on the LOL shield using the LOL library command:

where x and y are the coordinates on the shield of the LED we wish to illuminate

Our job is to figure out how to calculate the x,y values that make a circle.

In Pseudo code we do it like this to draw just one quarter (Quadrant) of the circle:

So what's the function?

where x^2 means "x squared" or "x to the power of 2"

We know

We know

So we re-arrange to find

When you code it up you get a circle as shown in the picture.

This circle will eventually move around as we tilt the device. But first things first....

We'll illuminate individual pixels on the LOL shield using the LOL library command:

*LedSign::Set(x, y , 1);*where x and y are the coordinates on the shield of the LED we wish to illuminate

Our job is to figure out how to calculate the x,y values that make a circle.

In Pseudo code we do it like this to draw just one quarter (Quadrant) of the circle:

**for x = 0 to RADIUS**

y=f(x); // This means y is some function of x. We haven't said what function yet

plot(x,y)

endy=f(x); // This means y is some function of x. We haven't said what function yet

plot(x,y)

end

So what's the function?

**r^2 = x^2 + y^2**where x^2 means "x squared" or "x to the power of 2"

We know

**because it's the for loop iterator;***x*We know

**because it's the radius,***r*So we re-arrange to find

*y***// sqrt() means square-root***y = sqrt(r^2 - x^2)*When you code it up you get a circle as shown in the picture.

## Step 5: Here's the Code

Here's the Arduino code to draw the circle.

Notice that the circle is drawn in 4 quadrants. We illuminate 4 LEDs for each

The pictures show the steps to draw the circle as x iterates from 0 to RADIUS

Notice that the circle is drawn in 4 quadrants. We illuminate 4 LEDs for each

*we calculate.***y**The pictures show the steps to draw the circle as x iterates from 0 to RADIUS

**#include <Charliplexing.h>**

// Circle: radius, inital and max x/y values

int radius = 3;

int cx = 6; // x-position of circle

int cy = 4; // y-position of circle

void setup()

{

Serial.begin(9600);

LedSign::Init();

}

void loop()

{

DrawCircle(1); // DRAW the circle

}

void DrawCircle(int ink)

// ink =0 : ERASE the circle

// ink =1 : DRAW the circle

{

for(int x = 0; x <= radius; x++) // x values from 0 to RADIUS (one Quadrant)

{

// solve r^2 = x^2 + y^2 for y

float y = sqrt(pow(radius, 2) - pow(x, 2));

y = round(y*1);

// Fill the y-position in the 4 quadrants of the circle

LedSign::Set(x + cx, y + cy, ink); // Quadrant 1

LedSign::Set(x + cx, cy - y, ink); // Quadrant 4

LedSign::Set(cx - x, y + cy, ink); // Quadrant 2

LedSign::Set(cx - x, cy - y, ink); // Quadrant 3

}

}// Circle: radius, inital and max x/y values

int radius = 3;

int cx = 6; // x-position of circle

int cy = 4; // y-position of circle

void setup()

{

Serial.begin(9600);

LedSign::Init();

}

void loop()

{

DrawCircle(1); // DRAW the circle

}

void DrawCircle(int ink)

// ink =0 : ERASE the circle

// ink =1 : DRAW the circle

{

for(int x = 0; x <= radius; x++) // x values from 0 to RADIUS (one Quadrant)

{

// solve r^2 = x^2 + y^2 for y

float y = sqrt(pow(radius, 2) - pow(x, 2));

y = round(y*1);

// Fill the y-position in the 4 quadrants of the circle

LedSign::Set(x + cx, y + cy, ink); // Quadrant 1

LedSign::Set(x + cx, cy - y, ink); // Quadrant 4

LedSign::Set(cx - x, y + cy, ink); // Quadrant 2

LedSign::Set(cx - x, cy - y, ink); // Quadrant 3

}

}

## Step 6: Move the Circle by Tilting

Now we add the code to move the x,y position from the accelerometer readings.

As the accelerometer is tilted on its x any y axes its readings change.

The program first calibrates by measuring the at-rest readings of the accelerometer.

Any deviation form these values is considered to be a tilt of the sensor.

The circle is drawn with centre at cx, cy:

As the accelerometer is tilted on its x any y axes its readings change.

The program first calibrates by measuring the at-rest readings of the accelerometer.

*// Calibrate x and y values from Accelerometer*

xAve = 0;

yAve = 0;

for (int i=0; i<8; i++) {

xAve = xAve + analogRead(A0);

yAve = yAve + analogRead(A1);

}

// Average x,y values correspond to "level"

xAve = xAve/8;

yAve = yAve/8;

}xAve = 0;

yAve = 0;

for (int i=0; i<8; i++) {

xAve = xAve + analogRead(A0);

yAve = yAve + analogRead(A1);

}

// Average x,y values correspond to "level"

xAve = xAve/8;

yAve = yAve/8;

}

Any deviation form these values is considered to be a tilt of the sensor.

*// Calculate the Tilt away from "level"*

// and draw the circle there

cx = cx0 + (xAve - analogRead(A0))/5;

cy = cy0 + (-yAve + analogRead(A1))/5;// and draw the circle there

cx = cx0 + (xAve - analogRead(A0))/5;

cy = cy0 + (-yAve + analogRead(A1))/5;

The circle is drawn with centre at cx, cy:

**DrawCircle(1); // DRAW the new circle**## Step 7: Here's the Full Code

**#include <Charliplexing.h>**

// Circle: radius, inital and max x/y values

int radius = 2;

int cx0 = 6;

int cy0 = 4;

int cxMax = 13 - radius;

int cyMax = 8 - radius;

int cx, cy, xAve, yAve;

void setup()

{

Serial.begin(9600);

LedSign::Init();

// Calibrate x and y values from Accelerometer

xAve = 0;

yAve = 0;

for (int i=0; i<8; i++) {

xAve = xAve + analogRead(A0);

yAve = yAve + analogRead(A1);

}

// Average x,y values correspond to "level"

xAve = xAve/8;

yAve = yAve/8;

}

void loop()

{

DrawCircle(0); // ERASE the previous circle

// Calculate the Tilt away from "level"

// and draw the circle there

cx = cx0 + (xAve - analogRead(A0))/5;

cy = cy0 + (-yAve + analogRead(A1))/5;

if (cx > cxMax) cx = cxMax;

else if (cx < radius) cx = radius;

if (cy > cyMax) cy = cyMax;

else if (cy < radius) cy = radius;

DrawCircle(1); // DRAW the new circle

delay(100);

}

void DrawCircle(int ink)

// ink =0 : ERASE the circle

// ink =1 : DRAW the circle

{

for(int x = 0; x <= radius; x++) // x values from 0 to RADIUS (one Quadrant)

{

// solve r^2 = x^2 + y^2 for y

float y = sqrt(pow(radius, 2) - pow(x, 2));

y = round(y*1);

// Fill the y-position in the 4 quadrants of the circle

LedSign::Set(x + cx, y + cy, ink); // Quadrant 1

LedSign::Set(x + cx, cy - y, ink); // Quadrant 4

LedSign::Set(cx - x, y + cy, ink); // Quadrant 2

LedSign::Set(cx - x, cy - y, ink); // Quadrant 3

}

}// Circle: radius, inital and max x/y values

int radius = 2;

int cx0 = 6;

int cy0 = 4;

int cxMax = 13 - radius;

int cyMax = 8 - radius;

int cx, cy, xAve, yAve;

void setup()

{

Serial.begin(9600);

LedSign::Init();

// Calibrate x and y values from Accelerometer

xAve = 0;

yAve = 0;

for (int i=0; i<8; i++) {

xAve = xAve + analogRead(A0);

yAve = yAve + analogRead(A1);

}

// Average x,y values correspond to "level"

xAve = xAve/8;

yAve = yAve/8;

}

void loop()

{

DrawCircle(0); // ERASE the previous circle

// Calculate the Tilt away from "level"

// and draw the circle there

cx = cx0 + (xAve - analogRead(A0))/5;

cy = cy0 + (-yAve + analogRead(A1))/5;

if (cx > cxMax) cx = cxMax;

else if (cx < radius) cx = radius;

if (cy > cyMax) cy = cyMax;

else if (cy < radius) cy = radius;

DrawCircle(1); // DRAW the new circle

delay(100);

}

void DrawCircle(int ink)

// ink =0 : ERASE the circle

// ink =1 : DRAW the circle

{

for(int x = 0; x <= radius; x++) // x values from 0 to RADIUS (one Quadrant)

{

// solve r^2 = x^2 + y^2 for y

float y = sqrt(pow(radius, 2) - pow(x, 2));

y = round(y*1);

// Fill the y-position in the 4 quadrants of the circle

LedSign::Set(x + cx, y + cy, ink); // Quadrant 1

LedSign::Set(x + cx, cy - y, ink); // Quadrant 4

LedSign::Set(cx - x, y + cy, ink); // Quadrant 2

LedSign::Set(cx - x, cy - y, ink); // Quadrant 3

}

}

## Step 8: Here's a Video of It Working

Have Fun!

<p>what is the purpose of drawing a circle instead of a single dot?</p><p>from the level use case point of view, a single dot will be well enough, no? (maybe I missed some point).</p>