A library to manipulate 2D arrays, and output them to an LED Dot Matrix Display. The display must be wired up using a shift register combined with a nor latch.
Revision 1:44819562ea31, committed 2012-02-13
- Comitter:
- EricWieser
- Date:
- Mon Feb 13 23:20:30 2012 +0000
- Parent:
- 0:1deae5ffe9ed
- Commit message:
- Template ALL THE THINGS
Changed in this revision
diff -r 1deae5ffe9ed -r 44819562ea31 LEDMatrix.h --- a/LEDMatrix.h Mon Feb 13 22:19:58 2012 +0000 +++ b/LEDMatrix.h Mon Feb 13 23:20:30 2012 +0000 @@ -1,52 +1,47 @@ #include "mbed.h" -#include "Locations.h" #include "Matrix.h" template <int WIDTH, int HEIGHT> class LEDMatrix : public Matrix<bool> { private: - DigitalOut* _rows; - DigitalOut* _colClk; - DigitalOut* _colReset; + //Array of row pins + DigitalOut* _rows; + + //Pointers to column control pins + DigitalOut* _nextCol; + DigitalOut* _firstCol; int _usPerColumn; - //Column control - void firstColumn() { - *_colReset = 1; - wait_us(10); - *_colReset = 0; - } - void nextColumn() { - *_colClk = 1; - wait_us(10); - *_colClk = 0; - } - void showColumn(int c) { - bool* col = column(WIDTH - 1 - c); - for(int i = 0; i < HEIGHT; i++) { - _rows[i] = col[HEIGHT - 1 - i]; - } - delete [] col; - } - void hideColumn(int c) { - for(int i = 0; i < HEIGHT; i++) { - _rows[i] = false; - } - } public: - LEDMatrix(DigitalOut rows[HEIGHT], DigitalOut* colClk, DigitalOut* colReset, int usPerFrame) : - Matrix<bool>(WIDTH, HEIGHT), _rows(rows), _colClk(colClk), _colReset(colReset) { + LEDMatrix(DigitalOut rows[HEIGHT], DigitalOut* nextCol, DigitalOut* firstCol, int usPerFrame) : Matrix<bool>(WIDTH, HEIGHT), _rows(rows), _nextCol(nextCol), _firstCol(firstCol) { clear(); - firstColumn(); _usPerColumn = usPerFrame / WIDTH; } void redraw() { - firstColumn(); - for (int col = 0; col < WIDTH; col++) { - nextColumn(); - showColumn(col); + //Pulse firstCol + *_firstCol = 1; + wait_us(10); + *_firstCol = 0; + + //Account for reverse column ordering + for (int col = WIDTH - 1; col >= 0; col--) { + //Pulse nextCol + *_nextCol = 1; + wait_us(10); + *_nextCol = 0; + + //Output a column of data to the row pins. + for(int row = 0; row < HEIGHT; row++) { + _rows[row] = (*this)(col, row); + } + + //Wait wait_us(_usPerColumn); - hideColumn(col); + + //Clear the column, ready for the next iteration + for(int i = 0; i < HEIGHT; i++) { + _rows[i] = false; + } } } }; \ No newline at end of file
diff -r 1deae5ffe9ed -r 44819562ea31 Locations.h --- a/Locations.h Mon Feb 13 22:19:58 2012 +0000 +++ b/Locations.h Mon Feb 13 23:20:30 2012 +0000 @@ -1,31 +1,33 @@ #ifndef LOCATIONS_H #define LOCATIONS_H -class FloatLocation; -class IntLocation { -public: - IntLocation(int x = 0, int y = 0) : x(x), y(y) { } - int x, y; - operator FloatLocation(); - bool operator==(IntLocation l) { return l.x == x && l.y == y; } - IntLocation operator+(IntLocation l) { return IntLocation(l.x + x, l.y + y); } -}; - -class FloatLocation { -public: - FloatLocation(float x = 0, float y = 0) : x(x), y(y) { } - float x, y; - operator IntLocation() { - return IntLocation((int) (x + 0.5), (int) (y + 0.5)); - } - FloatLocation lerp(FloatLocation to, float alpha) { - return FloatLocation( +template <typename T> class Location { + public: + T x, y; + //Constructor + Location(T x = 0, T y = 0) : x(x), y(y) { }; + + //Equals operator + bool operator==(Location<T> l) { return l.x == x && l.y == y; } + + //Addition operator + Location<T> operator+(Location<T> l) { return Location<T>(l.x + x, l.y + y); } + + //Linerearly interpolate + Location<T> lerp(Location<T> to, float alpha) { + return Location<T>( x*(1 - alpha) + to.x*alpha, y*(1 - alpha) + to.y*alpha ); } - bool operator==(FloatLocation l) { return l.x == x && l.y == y; } + + template <typename T2> operator Location<T2>(); }; -IntLocation::operator FloatLocation() { - return FloatLocation(x, y); + +//Convert from Location<int> to Location<float> and back +template <> Location<int>::operator Location<float>() { + return Location<float>(x, y); +} +template <> Location<float>::operator Location<int>() { + return Location<int>((int) (x + 0.5), (int) (y + 0.5)); } #endif \ No newline at end of file
diff -r 1deae5ffe9ed -r 44819562ea31 Matrix.h --- a/Matrix.h Mon Feb 13 22:19:58 2012 +0000 +++ b/Matrix.h Mon Feb 13 23:20:30 2012 +0000 @@ -5,50 +5,48 @@ #define Matrix_H template <class T> class Matrix { private: + //Internal data T* _data; int _width; int _height; - T& item(int x, int y) const{ - return _data[y*_width + x]; - } + //Unsafe cell accessors + const T& item(int x, int y) const { return _data[y*_width + x]; } + T& item(int x, int y) { return _data[y*_width + x]; } - void init() { - _data = new T[_width*_height]; - } + //Initializer + void init() { _data = new T[_width*_height]; } public: - Matrix(int width, int height) : _width(width), _height(height) { - init(); - } + //Construct an empty matrix + Matrix(int width, int height) : _width(width), _height(height) { init(); } + //Construct a matrix from a 2D array template <int w, int h> Matrix(T (&array)[h][w]) : _width(w), _height(h) { init(); - for(int x = 0; x < w; x++) { - for(int y = 0; y < h; y++) { + for(int x = 0; x < w; x++) + for(int y = 0; y < h; y++) item(x, y) = array[y][x]; - } - } } + //Copy constructor Matrix(const Matrix<T> &that) : _width(that._width), _height(that._height) { init(); - for(int i = 0; i < _width; i++) { - for(int j = 0; j < _height; j++) { + for(int i = 0; i < _width; i++) + for(int j = 0; j < _height; j++) this->item(i, j) = that.item(i, j); - } - } } - ~Matrix() { - delete [] _data; - } + //Destructor - clean up pointers + ~Matrix() { delete [] _data; } - int getWidth() const { return _width; } + //Size accessors + int getWidth() const { return _width; } int getHeight() const { return _height; } + //Bounds checking bool contains(int x, int y) const { return x >= 0 && x < _width && y >= 0 && y < _height; } @@ -56,61 +54,15 @@ return x >= 0 && x + w <= _width && y >= 0 && y + h <= _height; } - T& operator() (const int x, const int y) { - assert(contains(x, y)); - return item(x, y); - } - - - const T& operator() (const int x, const int y) const { - assert(contains(x, y)); - return item(x, y); - } - - T& operator[] (const IntLocation p) { - return (*this)(p.x, p.y); - } - const T& operator[] (const IntLocation p) const { - return (*this)(p.x, p.y); - } - + //Safe cell accessors + const T& operator() (int x, int y) const { assert(contains(x, y)); return item(x, y); } + T& operator() (int x, int y) { assert(contains(x, y)); return item(x, y); } + const T& operator[] (const Location<int> &p) const { return (*this)(p.x, p.y); } + T& operator[] (const Location<int> &p) { return (*this)(p.x, p.y); } - Matrix<T> slice(int x, int y, int w, int h) const { - assert(containsRect(x, y, w, h)); - - Matrix<T> b = Matrix<T>(w, h); - - for(int i = 0; i < w; i++) { - for(int j = 0; j < h; j++) { - b.item(i, j) = this->item(x + i, y + j); - } - } - return b; - } - - - void overlay(const Matrix<T> &that, int x, int y) { - assert(containsRect(x, y, that._width, that._height)); - - for(int i = 0; i < that._width; i++) { - for(int j = 0; j < that._height; j++) { - this->item(i, j) = that.item(x + i, y + j); - } - } - } - - void overlay(const Matrix<T> &that, int sx, int sy, int w, int h, int dx, int dy) { - assert(containsRect(dx, dy, w, h) && that.containsRect(sx, sy, w, h)); - - for(int i = 0; i < w; i++) { - for(int j = 0; j < h; j++) { - this->item(dx + i, dy + j) = that.item(sx + i, sy + j); - } - } - } - + //Row and column accessors T* column(int x) const { - assert(x >= 0 && x <= _width); + assert(x >= 0 && x <= _width); T* col = new T[_height]; for(int j = 0; j < _height; j++) { col[j] = this->item(x, j); @@ -126,10 +78,35 @@ return row; } + //Cut out a rectangle from an existing matrix + Matrix<T> slice(int x, int y, int w, int h) const { + assert(containsRect(x, y, w, h)); + + Matrix<T> m = Matrix<T>(w, h); + + for(int i = 0; i < w; i++) + for(int j = 0; j < h; j++) + m.item(i, j) = this->item(x + i, y + j); + + return m; + } + + //Copy the data in the rectangle (sx, sy, w, h) from "that" to "this" at (dx, dy) + void overlay(const Matrix<T> &that, int sx, int sy, int w, int h, int dx, int dy) { + assert(containsRect(dx, dy, w, h) && that.containsRect(sx, sy, w, h)); + + for(int x = 0; x < w; x++) { + for(int y = 0; y < h; y++) { + this->item(dx + x, dy + y) = that.item(sx + x, sy + y); + } + } + } + + //Empty the matrix void clear() { for(int x = 0; x < _width; x++) - for(int y = 0; y < _width; y++) - (*this)(x, y) = T(); + for(int y = 0; y < _height; y++) + this->item(x, y) = T(); } }; #endif \ No newline at end of file