3d view of a face using an SD card, accelerometer and a TFT LCD Screen
String img2 = "fs_"; img2 += String(x_index); img2 += String(y_index); img2 += ".bmp"; char img2c[10] ; for(int ii = 0; ii < 9; ii++){ img2c[ii] = img2.charAt(ii); } img2c[9] = 0; open_file(img2c,file_pos);
We take the normalized x and y values from the accelerometer and use them to choose an image from a set of bitmaps stored on the SD card. The images have names like "fs_XY.bmp" where X is a number between 0 and 6 and y is a number between o and 4. Each of these numbers corrseponds to different points of view of the face along the horizontal and vertical axes.
/* LucidTronix 3D Accelerometer Picture Frame * For instructions, details and schematic, See: * http://www.lucidtronix.com/tutorials/31 * Uses the adafruit st7735 library * calibrates the accelerometer readings */#include#include #include // If we are using the hardware SPI interface, these are the pins (for future ref)#define sclk 13#define mosi 11// You can also just connect the reset pin to +5V (we do a software reset)#define rst 8// these pins are required#define cs 10#define dc 9// Color definitions#defineBLACK 0x0000#defineBLUE 0x001F#defineRED 0xF800#defineGREEN 0x07E0#define CYAN 0x07FF#define MAGENTA 0xF81F#define YELLOW 0xFFE0 #define WHITE 0xFFFF// For Arduino Uno/Duemilanove, etc// connect the SD card with MOSI going to pin 11, MISO going to pin 12 and SCK going to pin 13 (standard)// Then pin 4 goes to CS (or whatever you have set up)#define SD_CS 4 // Set the chip select line to whatever you use (4 doesnt conflict with the library)// to draw images from the SD card, we will share the hardware SPI interfaceST7735 tft = ST7735(cs, dc, rst);// the file itselfFile bmpFile1;// information we extract about the bitmap fileint bmpWidth, bmpHeight;uint8_t bmpDepth, bmpImageoffset;int btn1 = 1;int btn0 = 0;int cur_h = 1;int cur_v = 1;int sensor_maxx = 0;int sensor_minx = 1024;int sensor_maxy = 0;int sensor_miny = 1024;int old_x = 0;int old_y = 0;boolean change_img = false;void setup(void) { //Serial.begin(9600); pinMode(cs, OUTPUT); digitalWrite(cs, HIGH); // initialize a ST7735R TFT tft.initR(); // change this to initB() for ST7735B TFT's // Just do a simple test tft.writecommand(ST7735_DISPON); tft.fillScreen(WHITE); delay(200); tft.drawString(10,20,"Gyro setup..." , GREEN); tft.drawString(12,22, "Try SD" ,BLUE); if (!SD.begin(SD_CS)) { tft.drawString(12,42, "SD Failed" ,RED); return; } tft.drawString(12,42, "SD Good" ,BLUE); delay(500); pinMode(btn0,INPUT); pinMode(btn1,INPUT); tft.fillScreen(BLACK); bmp_load_and_draw_image("frame.bmp",0,0); bmp_load_and_draw_image("fs_00.bmp",40,50); delay (1000); change_img = true;}void loop() { bmpdraw(40,50);}void open_file(char * filename, unsigned int file_pos){ bmpFile1.close(); delay(20); bmpFile1 = SD.open(filename); delay(20); bmpFile1.seek(0); bmpFile1.seek(file_pos); if (!bmpFile1) { tft.drawString(12,62, "Coodn't open image" ,RED); return; }} void bmp_load_and_draw_image(char* filename, int ax, int ay) { bmpFile1 = SD.open(filename); if (!bmpFile1) { tft.drawString(12,62, "Coodn't find image" ,RED); return; } if (!bmpReadHeader(bmpFile1)) { tft.drawString(12,82, "Bad image" ,RED); return; } tft.drawString(12,102, "Try 2 draw image" ,GREEN); bmpdraw( ax, ay); //bmpFile1.close();}/*********************************************/// This procedure reads a bitmap and draws it to the screen// its sped up by reading many pixels worth of data at a time// instead of just one pixel at a time. increading the buffer takes// more RAM but makes the drawing a little faster. 20 pixels' worth// is probably a good place#define BUFFPIXEL 20void bmpdraw(int x, int y) { bmpFile1.seek(bmpImageoffset); unsigned int file_pos = bmpImageoffset; uint32_t time = millis(); uint16_t p; uint8_t g, b; int i, j; uint8_t sdbuffer[3 * BUFFPIXEL]; // 3 * pixels to buffer uint8_t buffidx = 3*BUFFPIXEL; if ( change_img ) check_acc_data(file_pos); for (i=0; i< bmpHeight; i++) { // bitmaps are stored with the BOTTOM line first so we have to move 'up' for (j=0; j = 3*BUFFPIXEL) { bmpFile1.read(sdbuffer, 3*BUFFPIXEL); buffidx = 0; } // convert pixel from 888 to 565 b = sdbuffer[buffidx++]; // blue g = sdbuffer[buffidx++]; // green p = sdbuffer[buffidx++]; // red file_pos += 3; p >>= 3; p <<= 6; g >>= 2; p |= g; p <<= 5; b >>= 3; p |= b; tft.drawPixel(x+j, y+i, p); } }}boolean bmpReadHeader(File f) { // read header uint32_t tmp; f.seek(0); if (read16(f) != 0x4D42) { // magic bytes missing return false; } // read file size tmp = read32(f); //Serial.print("size 0x"); Serial.println(tmp, HEX); // read and ignore creator bytes read32(f); bmpImageoffset = read32(f); //Serial.print("offset "); Serial.println(bmpImageoffset, DEC); // read DIB header tmp = read32(f); //Serial.print("header size "); Serial.println(tmp, DEC); bmpWidth = read32(f); bmpHeight = read32(f); if (read16(f) != 1) return false; bmpDepth = read16(f); //Serial.print("bitdepth "); Serial.println(bmpDepth, DEC); if (read32(f) != 0) { // compression not supported! return false; } //Serial.print("compression "); Serial.println(tmp, DEC); return true;}/*********************************************/// These read data from the SD card file and convert them to big endian // (the data is stored in little endian format!)// LITTLE ENDIAN!uint16_t read16(File f) { uint16_t d; uint8_t b; b = f.read(); d = f.read(); d <<= 8; d |= b; return d;}// LITTLE ENDIAN!uint32_t read32(File f) { uint32_t d; uint16_t b; b = read16(f); d = read16(f); d <<= 16; d |= b; return d;}void check_acc_data(unsigned int file_pos){ int ax = analogRead(1); int ay = analogRead(0); if ( ay > sensor_maxy) sensor_maxy = ay; if ( ay < sensor_miny ) sensor_miny = ay; if ( ax > sensor_maxx) sensor_maxx = ax; if ( ax < sensor_minx ) sensor_minx = ax; float y_adjust = ay - sensor_miny; float ratioy = y_adjust / (float)(1+sensor_maxy-sensor_miny); float x_adjust = ax - sensor_minx; float ratiox = x_adjust / (float)(1+sensor_maxx-sensor_minx); int x_index = (int)(ratiox*6.0); int y_index = (int)(ratioy*4.0); boolean changed = false; if ( x_index != old_x || y_index != old_y ){ String img2 = "fs_"; img2 += String(x_index); img2 += String(y_index); img2 += ".bmp"; char img2c[10] ; for(int ii = 0; ii < 9; ii++){ img2c[ii] = img2.charAt(ii); } img2c[9] = 0; open_file(img2c,file_pos); old_y = y_index; old_x = x_index; }}
| Title | Description | # | Cost | Link | Picture |
| HSB Joy PCB | PCB controls a screen, thermal printer, joystick and SD card | 1 | $11.95 | Link |
|
| SD Card (micro 4GB) | MicroSD Card 4GB with full-size SD card adapterValue:4GB | 1 | $5.35 | Link |
|
| microSD Card Connector | Secure Digital - microSD™ Push In, Push OutValue: microSD | 1 | $3.44 | Link |
|
| Accelerometer | ±4g, 9gValue:X, Y | 1 | $3.22 | Link |
|
| ATMEGA328P-AU | Integrated Circuits (ICs) MCU AVR 32K FLASH 32TQFPValue:1.8 V ~ 5.5 V 20MHz | 1 | $3.05 | Link |
|
| USB connector | USB Mini type BValue:female | 1 | $0.68 | Link |
|
| Crystal | CRYSTAL 16.00000 MHZ 20PF SMDValue:16MHz | 1 | $0.53 | Link |
|
| CD4050 | IC BUFF/CONVERTER HEX 16SOICN 8mA, 48mAValue: 3 V ~ 18 V | 1 | $0.45 | Link |
|
| Capacitor | CAP CER 0.1UF 50V Y5V 0805Value:0.1µF | 4 | $0.1 | Link |
|
| Resistor | Chip Resistor - Surface Mount RES 10K OHM 1/8W 5% 0805 SMDValue: 10k | 4 | $0.1 | Link |
|
Comments: