Still WIP, but there's now a bit more documentation

This commit is contained in:
Daniel Løvbrøtte Olsen 2017-06-06 10:53:59 +02:00 committed by GitHub
parent f10304b0dc
commit 75c0d75c8c

View File

@ -1,5 +1,272 @@
* [Introduction](#borg)
* [1 - Hardware](#1-hardware)
* [1.1 - Specification](#11-specification)
* [1.2 - Electrical](#12-electrical)
* [1.3 - Mechanical](#13-mechanical)
* [1.4 - Making of](#14-the-making-of)
* [1.5 - Electrical](#15-electrical)
* [1.6 - Mechanical](#16-mechanical)
* [2 - Software](#2-software)
* [2.1 - Library](#21-library)
* [Defines](#defines)
* [initMap](#initmap)
* [encodeLED](#encodeled)
* [decodeLED](#decodeled)
* [LEDSelectCmp](#ledselectcmp)
* [forceMove](#forcemove)
* [getNeighborLED](#getneighborled)
* [getRotNeighborLED](#getrotneighborled)
* [setColor](#setcolor)
* [updateColors](#updatecolors)
* [translate](#translate)
* [rotate](#rotate)
* [mirror](#mirror)
* [printError](#printerror)
# BORG
This is a project worked on by the entire 2DEA class for a year.
We wanted to make something that would become a bigger project that we could work on for the entirety of the year. And which would look amazing after it was done.
We already had a metal cube, we just needed somthing to fill it with. We decided on filling each side with 3\*3 LED matrixes.
## 1 Hardware
### 1.1 Specification
At first we needed to find a way at how to house all RGB-LEDs inside of the metal cube. So we decided to make these 'grids'.
![grid](./docs/grid.jpg)
They are 3 by 3 'grids' that house 9 RGB-LEDs, there are in total of 54 RGB-LEDs in the whole cube, and 6 of these 'grids'. One for each side.
## getRotNeighbor
![getRotNeighbor](./getRotNeighbor.png)
![](./docs/hardware-0.jpg)
![](./docs/hardware-1.jpg)
![](./docs/hardware-2.jpg)
![](./docs/hardware-3.jpg)
#### 1.2 Electrical
Every RGB-LED has 4 legs, first one is 'Signal In', second is VCC, third is 'Ground' and the last is 'Signal Out'.
![pinout](./docs/pinout.png)
Every single one of these legs had to have a wire soldered on, in total it made 216+ wires that where neccesary for this project.
#### 1.3 Mechanical
### 1.4 The Making of
#### 1.5 Eletrical
When we started working on these grids, at first we where just simply testing with cardboard squares and diffrent backgrounds, such as white, black and brown. We never got to glue together all 9 squares, but after we found out best background - Which was white (What a surpise right? /s).
We had access to third grade's 3D printer, and we printed out our grids.
![](./docs/backgrounds.jpg)
Our first plan was 5cm<sup>2</sup> squares,but after a few tries the walls were just too thin.
So we had to cut down to 4.6cm x 4.6cm x 5cm. With the wall thickness being 0.4cm. Thus keeping our ~15cm<sup>2</sup> requirement.
![](./docs/grid.jpg)
As it turned out, the plexiglass plates spread the light so well, it largely offsetted the screen-door effect. And this gap turned out fine.
Our first couple of prints failed, most likely due to too little infill on the 3D printer's settings, the walls became too brittle, and failed during the print. We were lucky however and got one column printed (attatched to two columns of fail).
After yelling at third grade so they would up the infill, our prints succeeded. The plastic color also changed during this, from white to brown.
These five prints, in addition to one of our students helpfully printing out a grid on his own 3D printer, we had enough to fill each side. The nonwhites, were recolored using spray paint.
As the 'grids' where being printed, we soldered the wires to the RGB-LEDs, This was a time consuming process seeing as there was 4 wires for all 54 LEDs, that makes 216 wires, each needing to be soldered and wrapped with heat shrink.
After we were done with the LEDs we needed to find a way to hold the LEDs inside a 'grid'.
We first thought of using cardboard, white coloured cardboard, but later our teacher found some photopaper which he got from the Media and Communications class. ??He refered to it as 'architect's paper'??, it was thicker and less flexible than normal paper.
We cut 16cm x 16cm extra for the 'grids' and we used two layers that were clued together. then we used a glue gun to glue these paper backgrouds onto the grids, and used tape to seal off and to finish them.
Then we had to cut small rectangular shaped holes in the back of paper, if those holes were to big, then we needed to find a way to fill them up.
Once a RGB-LEDs with wires were in place, all we did was glue them with a glue gun, if a hole was too big, then we needed to fil it up with alot of glue, which is not good.
The difficult part was when we needed to connect all those wires inside of the cube. First we needed to find an efficient way of connect those wires. After a bit of a discussion we agreed on a 'hub' system, which consisted off 8 'socket bits', 2 of those sockets where used for main 'Ground' and main 'VCC' and rest for RGB-LEDs 'Groud' and 'VCC' wires.
#### 1.6 Mechanical
## 2 Software
### 2.1 Library
#### Defines
```NORTH``` ```0```
```EAST``` ```1```
```SOUTH``` ```2```
```WEST``` ```3```
```UP``` ```0```
```RIGHT``` ```1```
```DOWN``` ```2```
```LEFT``` ```3```
```CLOCKW``` ```4```
```ACLOCKW``` ```5```
#### LEDSelect
```
struct LEDSelect {
byte side;
byte column;
byte row;
};
```
#### initMap
void initMap(void)
initMap is responsible for setting up the required memory structures so that the other functions can, well, *function*
That is the mappings of what sides are connected. And also the relative sides directions from the 0th side
This function should be called once in the setup function, before any other calls to borg.h functions.
If you are running out of memory, it could be an idea to reimplement the arrays inside this function to their own functions, moving the definition to program memory instead.
eg.
```
byte getDir(byte side, byte direction)
{
switch (side) {
case 0:
switch (direction) {
case NORTH:
return 4;
case EAST:
return 1;
case SOUTH:
return 5;
case WEST:
return 3;
}
case 1:
switch (direction) {
case NORTH:
return 4;
case EAST:
return 2;
case SOUTH:
return 5;
case WEST:
return 0;
}
...
}
}
```
And then replace all array checks in the functions with ```getDir(side, direction)```
This may have been the better thing to do all along, but we haven't met any significant memory constraints yet forcing us to change it.
If you're adding more programs however, this might prove neccecary.
#### encodeLED
void encodeLED(byte n, LEDSelect* Result)
Takes a number and converts it to a LEDSelect
#### decodeLED
inline byte decodeLED(LEDSelect selection)
Decodes side, column, row into n LED
This is useful if you want to set leds[n] directly
Example:
```
for (byte i = 0; i < 6; i++) {
leds[decodeLED({i, 1, 1})] = (CRGB) 0xff00ff;
}
```
Perhaps not too useful for most programs, but is extensively used internally in the library.
#### LEDSelectCmp
inline bool LEDSelectCmp(LEDSelect a, LEDSelect b)
returns true if LEDSElect a is equal to LEDSelect b.
C does not allow comparison of structs, instead, each member must be induvidually compared.
Maybe you could so something with memcmp, but that might require "stacked" structs.
#### forceMove
void forceMove(LEDSelect* selection, byte direction)
Internally used function for moving a LEDSelect in any direction. Does not handle wrapping.
You should never have a use for this, unless you're editing the library. See the getNeighborLED function for example in usage.
#### getNeighborLED
void getNeighborLED(LEDSelect* origin, byte origin_dir, LEDSelect* Result)
Gets neighbor led with sky directions, nice for single screen movement, but can also handle cross screen.
Takes origin LEDSelect and a direction, stores the Resulting LEDSelect in Result.
This is what you should use instead of forceMove in pretty much everything as it handles wrapping.
Example:
```
LEDSelect origin = {0, 1, 1};
/*Makes a LEDSelect selecting side 0,
column 1 (The middle)
row 1 (The middle)*/
LEDSelect next;
getNeighborLED(&origin, NORTH, &next);
/*LEDSelect next is now
side 0
column 1
row 0
Essetially movin one pixel north
*/
// You can also overwrite the origin LEDSelect with the result
getNeighborLED(&next, NORTH, &next);
/*LEDSelect next is now side 4, column 1, row 2.
Wrapping correctly to the other side*/
```
getNeighborLED works with more than just single pixel selects.
example:
```
LEDSelect origin = {0, 255, 255};
getNeighbor(&origin, EAST, &origin);
// origin is now {1, 255, 255}
```
```
LEDSelect origin = {0, 2, 255};
getNeighbor(&origin, WEST, &origin);
// origin is now {0, 1, 255}
```
#### getRotNeighborLED
void getRotNeighborLED(LEDSelect* origin, byte rot, LEDSelect* Result);
Gets neighbor led with set directions in reference to side 0, lets you move in one direction with one vector.
Instead of ```NORTH```, ```EAST```, ```SOUTH```, ```WEST```, this function uses ```UP```, ```RIGHT```, ```DOWN```, ```LEFT```, ```CLOCKW```, and ```ACLOCKW```. Relative to the 0th side.
See [Defines](#defines) for actual values of these
![getRotNeighbor](./docs/getRotNeighbor.png)
Similarly used like getNeighborLED. It turned out to be very useful in most applications.
It also wraps like getNeighborLED.
<sup><sub><sup>It actually just uses getNeighborLED</sup></sub></sup>
#### setColor
bool setColor(LEDSelect selection, CRGB color, CRGB* leds)
Takes a led selection,
The last two propertries can be 255, meaning no information
the property that is 255 will be inclusively filled with the CRGB color
Example:
```
// Sets the middle led on side 0 to the color blue
setColor({0, 1, 1}, (CRGB) 0x0000ff, leds);
// Sets the top row on side 1 to the color green
setColor({1, 255, 0}, (CRGB) 0x00ff00, leds);
// Sets the whole side of side 2 to red
setColor({2, 255, 255}, (CRGB) 0xff0000, leds);
```
returns true if successful, false if not. This is usually because of malformed input or whatever.
#### updateColors
#### translate
void translate(LEDSelect src, LEDSelect dst, CRGB* leds)
Copies colors from one LEDSelect to another LEDSelect of the same size
Example:
```
// Copies the middle LED on side 0, to the first led on side 5
translate({0, 1, 1}, {5, 0, 0}, leds);
// Copies the first row on side 1, to the last row on side 4
translate({1, 255, 0}, {4, 255, 2}, leds);
// Copies the entire 2nd side to the 3rd side
translate({2, 255, 255}, {3, 255, 255}, leds);
```
#### rotate
void rotate(byte side, bool dir, byte n, CRGB* leds)
Rotates a side by 45°*n, in given direction, ```0``` - Clockwise, ```1``` - Anticlockwise
Example:
```
/*
# + #
+ # +
# + #
*/
rotate(0, 0, 1, leds);
/*
+ # +
# # #
+ # +
*/
// rotate 90 degrees
rotate(0, 0, 2, leds);
```
#### mirror
#### printError