Mandelbrot viewer for SPI TFT touchscreen

Dependencies:   SPI_TFT TFT_fonts Touch_tft mbed

/media/uploads/RorschachUK/_scaled_p4130004.jpg

A Mandelbrot viewer for Mikroelektronika's "TFT-Proto" 2.8" 320x240 TFT touch panel, which is a pretty inexpensive screen.

I used Peter Drescher's library for it - http://mbed.org/cookbook/SPI-driven-QVGA-TFT and also used his wiring diagram to make an adapter.

main.cpp

Committer:
RorschachUK
Date:
2013-04-17
Revision:
1:a9641f372bea
Parent:
0:a954bd7fd162

File content as of revision 1:a9641f372bea:

/* Mandelbrot for mbed - April 2013
 * Uses Peter Drescher's library for Mikroelektronika's TFT-Proto screen, an inexpensive SPI-driven QVGA touch panel
 * Library: http://mbed.org/cookbook/SPI-driven-QVGA-TFT
 * Manufacturer's page for the screen: http://www.mikroe.com/add-on-boards/display/tft-proto/
 * UK distributor: http://www.mcustore.com/tft-proto-board.html
 * Partly adapted from Kamil Ondrousek's code for another screen: http://mbed.org/users/JLS/code/Mandelbrot-2/
 */
#include "mbed.h"
#include "SPI_TFT.h"
#include "Arial12x12.h"
#include "touch_tft.h"

#define WIDTH 320
#define HEIGHT 240

touch_tft tt(p18,p19,p16,p17,p11, p12, p13, p14, p15,"TFT"); // x+,x-,y+,y-,mosi, miso, sclk, cs, reset

void drawMandelbrot(float centrex, float centrey, float zoom, int maxIter) {
    float xmin = centrex - 1.0/zoom;
    float xmax = centrex + 1.0/zoom;
    float ymin = centrey - HEIGHT / (WIDTH * zoom);
    float ymax = centrey + HEIGHT / (WIDTH *zoom);

    float dx = (xmax - xmin) / WIDTH;
    float dy = (ymax - ymin) / HEIGHT;

    float y = ymin;

    float c;
    unsigned int cr, cg, cb;
    
    for (int j = 0; j < HEIGHT; j++) {
        float x = xmin;

        for (int i = 0;  i < WIDTH; i++) {
            float a = x;
            float b = y;
            int n = 0;

            while (n < maxIter) {
                float aa = a * a;
                float bb = b * b;
                float twoab = 2.0 * a * b;

                a = aa - bb + x;
                b = twoab + y;

                if(aa + bb > 16.0) {
                    break;
                }
                n++;
            }

            if (n == maxIter) {
                //It's in the set - Black
                tt.pixel(i,j,Black);
            } else {
                //Not in the set - pick a colour
                c = 3.0 * (maxIter-n)/maxIter;
                cr = ((c < 1.0) ? 255 * ( 1.0 - c) : (c > 2.0) ? 255 * (c - 2.0) : 0);
                cg = ((c < 1.0) ? 255 * c : (c > 2.0) ? 0 : 255 * (2.0 - c));
                cb = ((c < 1.0) ? 0 : (c > 2.0) ? 255 * (3.0 - c) : 255 * (c - 1.0));
                tt.pixel(i,j, RGB(cr,cg,cb));
            }
            x += dx;
        }
        y += dy;
    }
}

int main()
{
    //Setup screen
    tt.claim(stdout);        // send stdout to the TFT display
    tt.background(Black);    // set background to black
    tt.foreground(White);    // set chars to white
    tt.cls();                // clear the screen
    tt.set_font((unsigned char*) Arial12x12);  // select the font
    tt.set_orientation(1);
    tt.calibrate();          // calibrate the touch
    point p;

    tt.locate(0,0);

    //Setup base Mandelbrot
    float centrex = -0.5;
    float centrey = 0.0;
    float zoom=0.5;
    int maxiterations = 150;

    while(true) {
        //Draw it    
        drawMandelbrot(centrex, centrey, zoom, maxiterations);
    
        //Wait for a touch
        p=tt.get_touch();
        while(!tt.is_touched(p)) {
            p=tt.get_touch();
        }
        //Set new centre and zoom
        p = tt.to_pixel(p);
        centrex += (2.0 * p.x - WIDTH) / (zoom * WIDTH);
        centrey += (2.0 * p.y - HEIGHT) / (zoom * WIDTH);
        zoom *= 4.0;
        tt.rect(p.x - WIDTH / 8.0, p.y - HEIGHT / 8.0, p.x + WIDTH / 8.0, p.y + HEIGHT / 8.0, Yellow);  
    }
}