A neopixel light painting strip
Dependencies: NeoStrip PinDetect mbed
Revision 0:a26aca3e4760, committed 2015-11-10
- Comitter:
- lz307
- Date:
- Tue Nov 10 21:28:51 2015 +0000
- Commit message:
- Initial commit
Changed in this revision
diff -r 000000000000 -r a26aca3e4760 BitmapFile.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BitmapFile.cpp Tue Nov 10 21:28:51 2015 +0000 @@ -0,0 +1,287 @@ +#include "BitmapFile.h" + + +BitmapFile::BitmapFile(char* fname) : m_pFile(NULL) +{ + m_fileName = fname; + Initialize(); +} + +BitmapFile::~BitmapFile() +{ + delete[] m_fileName; +} + +bool BitmapFile::Initialize() +{ + bool success = true; + open(); + fread(&BMPHeader,sizeof(BMPHeader),1,m_pFile); + success = (BMPHeader.b == 'B' && BMPHeader.m == 'M'); + + fread(&m_headerlength,sizeof(m_headerlength),1,m_pFile); + fread(&DIBHeader,m_headerlength,1,m_pFile); + + /*Debugging code*/ + + Serial pc2(USBTX,USBRX); + + pc2.printf("\n\rFile = %s", m_fileName); + + pc2.printf("\n\rBMPHeader - Size = %d:\n\r",sizeof(BMPHeader)); + pc2.printf("\tbm:\t\t%c%c\n\r",BMPHeader.b,BMPHeader.m); + pc2.printf("\tfilesize:\t%d\n\r",BMPHeader.filesize); + pc2.printf("\treserved:\t%d,%d\n\r",BMPHeader.reserved1,BMPHeader.reserved2); + pc2.printf("\toffset:\t\t%d\n\r",BMPHeader.offset); + + pc2.printf("\n\rDIBHeader - Size = %d:\n\r",sizeof(DIBHeader)); + //pc2.printf("\theaderLength:\t%d\n\r",DIBHeader.headerLength); + pc2.printf("\theight:\t\t\t%d\n\r",DIBHeader.height); + pc2.printf("\twidth:\t\t%d\n\r",DIBHeader.width); + pc2.printf("\tcplanes:\t\t%d\n\r",DIBHeader.cplanes); + pc2.printf("\tcolordepth:\t\t%d\n\r",DIBHeader.colordepth); + pc2.printf("\tcompression:\t%d\n\r",DIBHeader.compression); + pc2.printf("\tdatasize:\t\t%d\n\r",DIBHeader.datasize); + pc2.printf("\tvres:\t\t%d\n\r",DIBHeader.vres); + pc2.printf("\thres:\t\t%d\n\r",DIBHeader.hres); + + + + m_rowsize = 4*((getColorDepth()*getWidth()+31)/32); + + close(); + return success; +} + +void BitmapFile::open() +{ + if(m_pFile==NULL) + { + m_pFile = fopen(m_fileName, "r"); + } +} + +void BitmapFile::close() +{ + if(m_pFile!=NULL) + { + fclose(m_pFile); + m_pFile = NULL; + } +} + +/**********************************************************/ +/*BMP Header Gets */ +/**********************************************************/ + +int BitmapFile::getFileSize() +{ + return BMPHeader.filesize; +} + +int BitmapFile::getReserved1() +{ + return BMPHeader.reserved1; +} + +int BitmapFile::getReserved2() +{ + return BMPHeader.reserved2; +} + +int BitmapFile::getOffset() +{ + return BMPHeader.offset; +} + +/**********************************************************/ +/*DIB Header Gets */ +/**********************************************************/ + +int BitmapFile::getHeaderType() +{ + return m_headerlength; +} + +int BitmapFile::getHeight() +{ + return DIBHeader.height; +} + +int BitmapFile::getWidth() +{ + return DIBHeader.width; +} + +int BitmapFile::getCPlanes() +{ + return DIBHeader.cplanes; +} + +int BitmapFile::getColorDepth() +{ + return DIBHeader.colordepth; +} + +int BitmapFile::getCompression() +{ + return DIBHeader.compression; +} + +int BitmapFile::getDataSize() +{ + return DIBHeader.datasize; +} + +int BitmapFile::getHRes() +{ + return DIBHeader.hres; +} + +int BitmapFile::getVRes() +{ + return DIBHeader.vres; +} + +int BitmapFile::getNumPaletteColors() +{ + return DIBHeader.numpalettecolors; +} + +int BitmapFile::getImportantColors() +{ + return DIBHeader.importantcolors; +} + +/**********************************************************/ +/*Data Gets */ +/**********************************************************/ + +int BitmapFile::getRowSize() +{ + return m_rowsize; +} + +int BitmapFile::getPixel(int row, int col, bool closefile) +{ + int color = -1; + if(row>=0 && row < getHeight() && col>=0 && col< getWidth()) + { + if(getColorDepth() == 24) + { + open(); + color = 0; //make sure the last byte is 00 + + int index = getOffset(); + index += col*3; + index += row*4*ceil(getWidth()*3/4.0); + fseek(m_pFile, index, SEEK_SET); + + fread (&color, 3,1,m_pFile); + + if(closefile) + { + close(); + } + } + } + return color; +} + +int *BitmapFile::getRow(int row, bool closefile) +{ + open(); + int *colors = new int[getWidth()]; + int index = getOffset() + m_rowsize*row; + fseek(m_pFile, index, SEEK_SET); + if(getColorDepth() == 24) + { + for(int i=0; i<getWidth(); i++) + { + fread(&colors[i],3,1,m_pFile); + } + } + else if(getColorDepth() == 1) + { + char *temp = new char[m_rowsize]; + for(int i=0; i<m_rowsize; i++) + { + fread(&temp[i],sizeof(char),1,m_pFile); + } + for(int i=0; i<getWidth(); i++) + { + int byte = i / 8; + int bit = i % 8; + colors[i] = ((temp[byte] << bit) & 0x80) ? 0xFFFFFF : 0x000000; + } + delete [] temp; + } + if(closefile) + { + close(); + } + return colors; +} + +int *BitmapFile::getRowBW(int row, bool closefile) +{ + open(); + int *colors = new int[getWidth()]; + int index = getOffset() + m_rowsize*row; + fseek(m_pFile, index, SEEK_SET); + if(getColorDepth() == 24) + { + for(int i=0; i<getWidth(); i++) + { + char temp[3]; + fread(temp,sizeof(char),3,m_pFile); + int average = (temp[0]+temp[1]+temp[2])/3; + colors[i] = average>128 ? 0xFFFFFF : 0x000000; + } + } + else if(getColorDepth() == 1) + { + delete [] colors; + colors = getRow(row, closefile); + } + if(closefile) + { + close(); + } + return colors; +} + +char *BitmapFile::getRowBitstream(int row, bool closefile) +{ + open(); + int bitsperrow = (getWidth()+7)/8; + char *data = new char[bitsperrow]; + for(int i = 0; i<bitsperrow; i++) + { + data[i] = 0; + } + int index = getOffset() + m_rowsize*row; + fseek(m_pFile, index, SEEK_SET); + + if(getColorDepth() == 24) + { + for(int i=0; i<getWidth(); i++) + { + char temp[3]; + fread(temp,sizeof(char),3,m_pFile); + int average = (temp[0]+temp[1]+temp[2])/3; + int val = average<128?0:1; + data[i/8] |= (val*0x80) >> (i%8); + } + } + else if(getColorDepth() == 1) + { + fread(data,sizeof(char),bitsperrow,m_pFile); + } + + if(closefile) + { + close(); + } + return data; +} \ No newline at end of file
diff -r 000000000000 -r a26aca3e4760 BitmapFile.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BitmapFile.h Tue Nov 10 21:28:51 2015 +0000 @@ -0,0 +1,158 @@ +/**********************************************************/ +/*BitmapFile.h */ +/**********************************************************/ + +#include "mbed.h" + +/* Class: BitmapFile + * A parser for bitmap files. +*/ +class BitmapFile +{ +private: + FILE *m_pFile; + char *m_fileName; + int m_rowsize; + + enum headerType { BITMAPCOREHEADER = 12, + BITMAPCOREHEADER2 = 64, + BITMAPINFOHEADER = 40, + BITMAPV4HEADER = 108, + BITMAPV5HEADER = 124}; + + enum compressType { BI_RGB, + BI_RLE8, + BI_RLE4, + BI_BITFIELDS, + BI_JPEG, + BI_PNG}; + + /* Struct: BMPHeader + * + * The BMP header of the bitmap is read into this. + * + * b - the first byte of the header. Should equal 'B'. + * m - the second byte of the header. Should equal 'M'. + * filesize - the size of the whole file, in bytes. + * reserved 1 and 2 - data specific to the applicaton which created the bitmap. + * offset - the offset at which the actual bitmap begins + */ + + __packed struct + { + char b:8; + char m:8; + int filesize:32; + int reserved1:16; + int reserved2:16; + int offset:32; + + } BMPHeader; + + + /* Struct: DIBHeader + * + * The DIB header of the bitmap is read into this. + * + * headerlength - the length of the header. Should equal 40. + * height - the height of the bitmap. + * width - the width of the bitmap. + * cplanes - the number of color planes. Should equal 1. + * colordepth - the number of bits per pixel. + * compression - the compression method used. + * datasize - the size of the bitmap data, in bytes. + */ + + int m_headerlength; + __packed struct + { + int width:32; + int height:32; + int cplanes:16; + int colordepth:16; + int compression:32; + int datasize:32; + int hres:32; + int vres:32; + int numpalettecolors:32; + int importantcolors:32; + } DIBHeader; + + +public: + /* Constructor: BitmapFile + * Create the BitmapFile class, and call <Initialize> + * + * Parameters: + * fname - The path of the file to open. + */ + BitmapFile(char* fname); + ~BitmapFile(); + + /* Function: Initialize + * Parses the headers of the bitmap. + * + * Returns: + * Whether the bitmap is valid. + */ + bool Initialize(); //parses the header + + /* Function: open + * Opens the bitmap for reading, if not already open. + */ + void open(); + + /* Function: close + * Closes the bitmap. + */ + void close(); + + /***BMP Header gets begin***/ + int getFileSize(); + int getReserved1(); + int getReserved2(); + int getOffset(); + + /***DIB Header gets begin***/ + int getHeaderType(); + int getHeight(); + int getWidth(); + int getCPlanes(); + int getColorDepth(); + int getCompression(); + int getDataSize(); + int getHRes(); + int getVRes(); + int getNumPaletteColors(); + int getImportantColors(); + /****DIB Header gets end****/ + + /******Data gets begin******/ + /* Function: getPixel + * Gets the color of a pixel + * + * Parameters: + * x - The x coordinate of the pixel. + * y - The y coordinate of the pixel. + * closefile - if specified, close the file after reading + * + * Returns: + * the color of the pixel, in hexadecimal. + */ + int getPixel(int x, int y, bool closefile = true); + /* Function: getRow + * Gets the colors of a row + * + * Parameters: + * row - The number of the row.. + * closefile - if specified, close the file after reading + * + * Returns: + * An array of the colors of the pixels, in hexadecimal. + */ + int *getRow(int row, bool closefile = true); + int *getRowBW(int row, bool closefile = true); + char *getRowBitstream(int row, bool closefile = true); + /*******Data gets end*******/ + int getRowSize(); +}; \ No newline at end of file
diff -r 000000000000 -r a26aca3e4760 NeoStrip.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NeoStrip.lib Tue Nov 10 21:28:51 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/aswild/code/NeoStrip/#f531a2be180d
diff -r 000000000000 -r a26aca3e4760 PinDetect.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PinDetect.lib Tue Nov 10 21:28:51 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/AjK/code/PinDetect/#cb3afc45028b
diff -r 000000000000 -r a26aca3e4760 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Nov 10 21:28:51 2015 +0000 @@ -0,0 +1,251 @@ +#include "mbed.h" +#include "BitmapFile.h" +#include <string> +#include "PinDetect.h" +#include "NeoStrip.h" + +# define MAX_FILE 30 + +#define N 32 +NeoStrip strip(p5, N); +float bright = 0.2; // 20% is plenty for indoor use + +PinDetect b1(p25, PullUp); +PinDetect b2(p29, PullUp); +PinDetect b3(p22, PullUp); +PinDetect b4(p27, PullUp); + +LocalFileSystem local("local"); // Create the local filesystem under the name "local" +Serial pc(USBTX, USBRX); // tx, rx +BitmapFile *MyBitmap; + +char *f_list[MAX_FILE]; +int file_index = 0; // get the index of file being displayed +unsigned max_file = 0; // register how many files there are + +char * get_file_name() { + char *fn = NULL; + unsigned i = 0; // index in the file list; + DIR *d = opendir("/local"); // Opens the root directory of the local file system + struct dirent *p; + while((p = readdir(d)) != NULL) { // Print the names of the files in the local file system + int l = strlen(p->d_name); + if (strcmp(&(p->d_name[l-3]), "BMP") == 0) { + i++; + if (file_index == i) { + fn = (char *) malloc(50); + strcpy(fn, p->d_name); + break; + } + } + } + closedir(d); + + return fn; +} + +void strip_off() { + for (int i=0; i<N; i++) { + strip.setPixel(i, 0); + } + strip.write(); +} + +void display_number(float f) { + for (int i=0; i<N; i++) { + if (i<(f*N)) + strip.setPixel(i, 0xffffff); + } + strip.write(); + wait(0.2); + strip_off(); +} + +void brightnessUp(void) { + if (bright < 1) + { + bright += 0.01; + if (bright > 1) + bright = 1; + printf("increase brightness\r\n"); + strip.setBrightness(bright); + display_number(bright); + } +} + +void brightnessDown(void) { + if (bright > 0) + { + bright -= 0.01; + if (bright < 0) + bright = 0; + printf("decrease brightness\r\n"); + strip.setBrightness(bright); + display_number(bright); + } +} + +void fileDown(void) { + file_index--; + if (file_index < 0) + file_index = max_file; + printf("fileDown to %i:%s\r\n", file_index, f_list[file_index]); + display_number(file_index/float(N)); +} + +void fileUp(void) { + file_index++; + if (file_index > max_file) + file_index = 0; + printf("fileUp to %i:%s\r\n", file_index, f_list[file_index]); + display_number(file_index/float(N)); +} + + +// Converts HSV to RGB with the given hue, assuming +// maximum saturation and value +int hueToRGB(float h) +{ + // lots of floating point magic from the internet and scratching my head + float r, g, b; + if (h > 360) + h -= 360; + if (h < 0) + h += 360; + int i = (int)(h / 60.0); + float f = (h / 60.0) - i; + float q = 1 - f; + + switch (i % 6) + { + case 0: r = 1; g = f; b = 0; break; + case 1: r = q; g = 1; b = 0; break; + case 2: r = 0; g = 1; b = f; break; + case 3: r = 0; g = q; b = 1; break; + case 4: r = f; g = 0; b = 1; break; + case 5: r = 1; g = 0; b = q; break; + default: r = 0; g = 0; b = 0; break; + } + + // scale to integers and return the packed value + uint8_t R = (uint8_t)(r * 255); + uint8_t G = (uint8_t)(g * 255); + uint8_t B = (uint8_t)(b * 255); + + return (R << 16) | (G << 8) | B; +} + + +void pattern1() +{ + static float dh = 360.0 / N; + static float x = 0; + printf("%f\r\n",x); + + for (int i = 0; i < N; i++) { + int c = hueToRGB((dh * i) - x); + //printf("R %i, G %i, B %i\r\n", (c>>16)&0xff, (c>>8)&0xff, c&0xff); + strip.setPixel(i, c); + } + + x += 1; + if (x > 360) + x = 0; +} + + +void patternStart(void) { + printf("file_index: %i\r\n", file_index); + if (file_index == 0) { + for ( int j=0; j<100; j++ ){ + pattern1(); + strip.write(); + wait_ms(20); + } + return; + } + + printf("fn: %s\r\n", f_list[file_index]); + + char *fn = get_file_name(); + + unsigned l = strlen(fn); + char *path = (char *) malloc(l+7); + path[0] = 0; + strcat(path, "/local/"); + strcat(path, fn); + printf("path: %s\r\n", path); + + MyBitmap = new BitmapFile(path); + for(int row = 0; row < MyBitmap->getHeight(); row++) + { + int *row_color = MyBitmap->getRow(row, false); + for(int col = 0; col < MyBitmap->getWidth(); col++) + { + unsigned c = row_color[col] & 0xffffff; + strip.setPixel(col, c); + if ( c > 0xfff ) + printf(" "); + else + printf("*"); + } + strip.write(); + wait_ms(20); + printf("\r\n"); + delete [] row_color; + } + printf("closing\r\n"); + MyBitmap->close(); + printf("closed\r\n"); + free(fn); + free(path); + strip_off(); +} + + + + +int main() { + b1.setAssertValue( 0 ); + b2.setAssertValue( 0 ); + b3.setAssertValue( 0 ); + b4.setAssertValue( 0 ); + + b1.attach_asserted( &brightnessDown ); + b2.attach_asserted( &patternStart ); + b3.attach_asserted( &brightnessUp ); + + b1.attach_asserted_held( &fileDown ); + b3.attach_asserted_held( &fileUp ); + + strip.setBrightness(bright); // set default brightness + + + // build a list of files + for (unsigned i=0; i<MAX_FILE; i++) + f_list[i] = NULL; + + unsigned i = 0; // index in the file list; + DIR *d = opendir("/local"); // Opens the root directory of the local file system + struct dirent *p; + while((p = readdir(d)) != NULL) { // Print the names of the files in the local file system + int l = strlen(p->d_name); + if (strcmp(&(p->d_name[l-3]), "BMP") == 0) { + char *tmp_str = (char *) malloc(l+1); + strcpy(tmp_str, p->d_name); + i++; + f_list[i] = tmp_str; + printf("f_list: %i:%s\r\n", i, tmp_str); + } + } + closedir(d); + + max_file = i; + b1.setSampleFrequency(); + b2.setSampleFrequency(); + b3.setSampleFrequency(); + b4.setSampleFrequency(); + + while(1) + __WFI(); +} \ No newline at end of file
diff -r 000000000000 -r a26aca3e4760 mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Tue Nov 10 21:28:51 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/7cff1c4259d7 \ No newline at end of file