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.

Files at this revision

API Documentation at this revision

Comitter:
EricWieser
Date:
Mon Feb 13 23:20:30 2012 +0000
Parent:
0:1deae5ffe9ed
Commit message:
Template ALL THE THINGS

Changed in this revision

LEDMatrix.h Show annotated file Show diff for this revision Revisions of this file
Locations.h Show annotated file Show diff for this revision Revisions of this file
Matrix.h Show annotated file Show diff for this revision Revisions of this file
--- 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
--- 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
--- 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