Modified Bob Stone's code for ILI9341 QVGA TFT's without touch capability. Navigation is now done with rotary encoders - two for position, & one setting the maxiterations.
Dependencies: SPI_TFT_ILI9341 TFT_fonts mbed
Fork of Mandelbrot by
Should have mentioned in the above: Encoder code is specific to the STM32F4, tested on Nucleo F401, should work on the Nucleo F411..
main.cpp@0:a954bd7fd162, 2013-04-13 (annotated)
- Committer:
- RorschachUK
- Date:
- Sat Apr 13 19:27:43 2013 +0000
- Revision:
- 0:a954bd7fd162
- Child:
- 1:a9641f372bea
First version
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
RorschachUK | 0:a954bd7fd162 | 1 | /* Mandelbrot for mbed - April 2013 |
RorschachUK | 0:a954bd7fd162 | 2 | * Uses Peter Drescher's library for Mikroelektronika's TFT-Proto screen, an inexpensive SPI-driven QVGA touch panel |
RorschachUK | 0:a954bd7fd162 | 3 | * Library: http://mbed.org/cookbook/SPI-driven-QVGA-TFT |
RorschachUK | 0:a954bd7fd162 | 4 | * Manufacturer's page for the screen: http://www.mikroe.com/add-on-boards/display/tft-proto/ |
RorschachUK | 0:a954bd7fd162 | 5 | * UK distributor: http://www.mcustore.com/tft-proto-board.html |
RorschachUK | 0:a954bd7fd162 | 6 | * Partly adapted from Kamil Ondrousek's code for another screen: http://mbed.org/users/JLS/code/Mandelbrot-2/ |
RorschachUK | 0:a954bd7fd162 | 7 | */ |
RorschachUK | 0:a954bd7fd162 | 8 | #include "mbed.h" |
RorschachUK | 0:a954bd7fd162 | 9 | #include "SPI_TFT.h" |
RorschachUK | 0:a954bd7fd162 | 10 | #include "Arial12x12.h" |
RorschachUK | 0:a954bd7fd162 | 11 | #include "touch_tft.h" |
RorschachUK | 0:a954bd7fd162 | 12 | |
RorschachUK | 0:a954bd7fd162 | 13 | #define WIDTH 320 |
RorschachUK | 0:a954bd7fd162 | 14 | #define HEIGHT 240 |
RorschachUK | 0:a954bd7fd162 | 15 | |
RorschachUK | 0:a954bd7fd162 | 16 | touch_tft tt(p18,p19,p16,p17,p11, p12, p13, p14, p15,"TFT"); // x+,x-,y+,y-,mosi, miso, sclk, cs, reset |
RorschachUK | 0:a954bd7fd162 | 17 | |
RorschachUK | 0:a954bd7fd162 | 18 | void drawMandelbrot(float centrex, float centrey, float zoom, int maxIter) { |
RorschachUK | 0:a954bd7fd162 | 19 | float xmin = centrex - 1.0/zoom; |
RorschachUK | 0:a954bd7fd162 | 20 | float xmax = centrex + 1.0/zoom; |
RorschachUK | 0:a954bd7fd162 | 21 | float ymin = centrey - HEIGHT / (WIDTH * zoom); |
RorschachUK | 0:a954bd7fd162 | 22 | float ymax = centrey + HEIGHT / (WIDTH *zoom); |
RorschachUK | 0:a954bd7fd162 | 23 | |
RorschachUK | 0:a954bd7fd162 | 24 | float dx = (xmax - xmin) / WIDTH; |
RorschachUK | 0:a954bd7fd162 | 25 | float dy = (ymax - ymin) / HEIGHT; |
RorschachUK | 0:a954bd7fd162 | 26 | |
RorschachUK | 0:a954bd7fd162 | 27 | float y = ymin; |
RorschachUK | 0:a954bd7fd162 | 28 | |
RorschachUK | 0:a954bd7fd162 | 29 | float c; |
RorschachUK | 0:a954bd7fd162 | 30 | unsigned int cr, cg, cb; |
RorschachUK | 0:a954bd7fd162 | 31 | |
RorschachUK | 0:a954bd7fd162 | 32 | for (int j = 0; j < HEIGHT; j++) { |
RorschachUK | 0:a954bd7fd162 | 33 | float x = xmin; |
RorschachUK | 0:a954bd7fd162 | 34 | |
RorschachUK | 0:a954bd7fd162 | 35 | for (int i = 0; i < WIDTH; i++) { |
RorschachUK | 0:a954bd7fd162 | 36 | float a = x; |
RorschachUK | 0:a954bd7fd162 | 37 | float b = y; |
RorschachUK | 0:a954bd7fd162 | 38 | int n = 0; |
RorschachUK | 0:a954bd7fd162 | 39 | |
RorschachUK | 0:a954bd7fd162 | 40 | while (n < maxIter) { |
RorschachUK | 0:a954bd7fd162 | 41 | float aa = a * a; |
RorschachUK | 0:a954bd7fd162 | 42 | float bb = b * b; |
RorschachUK | 0:a954bd7fd162 | 43 | float twoab = 2.0 * a * b; |
RorschachUK | 0:a954bd7fd162 | 44 | |
RorschachUK | 0:a954bd7fd162 | 45 | a = aa - bb + x; |
RorschachUK | 0:a954bd7fd162 | 46 | b = twoab + y; |
RorschachUK | 0:a954bd7fd162 | 47 | |
RorschachUK | 0:a954bd7fd162 | 48 | if(aa + bb > 16.0) { |
RorschachUK | 0:a954bd7fd162 | 49 | break; |
RorschachUK | 0:a954bd7fd162 | 50 | } |
RorschachUK | 0:a954bd7fd162 | 51 | n++; |
RorschachUK | 0:a954bd7fd162 | 52 | } |
RorschachUK | 0:a954bd7fd162 | 53 | |
RorschachUK | 0:a954bd7fd162 | 54 | if (n == maxIter) { |
RorschachUK | 0:a954bd7fd162 | 55 | //It's in the set - Black |
RorschachUK | 0:a954bd7fd162 | 56 | tt.pixel(i,j,Black); |
RorschachUK | 0:a954bd7fd162 | 57 | } else { |
RorschachUK | 0:a954bd7fd162 | 58 | //Not in the set - pick a colour |
RorschachUK | 0:a954bd7fd162 | 59 | c = 3.0 * (maxIter-n)/maxIter; |
RorschachUK | 0:a954bd7fd162 | 60 | cr = ((c < 1.0) ? 255 * ( 1.0 - c) : (c > 2.0) ? 255 * (c - 2.0) : 0); |
RorschachUK | 0:a954bd7fd162 | 61 | cg = ((c < 1.0) ? 255 * c : (c > 2.0) ? 0 : 255 * (2.0 - c)); |
RorschachUK | 0:a954bd7fd162 | 62 | cb = ((c < 1.0) ? 0 : (c > 2.0) ? 255 * (3.0 - c) : 255 * (c - 1.0)); |
RorschachUK | 0:a954bd7fd162 | 63 | tt.pixel(i,j, RGB(cr,cg,cb)); |
RorschachUK | 0:a954bd7fd162 | 64 | } |
RorschachUK | 0:a954bd7fd162 | 65 | x += dx; |
RorschachUK | 0:a954bd7fd162 | 66 | } |
RorschachUK | 0:a954bd7fd162 | 67 | y += dy; |
RorschachUK | 0:a954bd7fd162 | 68 | } |
RorschachUK | 0:a954bd7fd162 | 69 | } |
RorschachUK | 0:a954bd7fd162 | 70 | |
RorschachUK | 0:a954bd7fd162 | 71 | int main() |
RorschachUK | 0:a954bd7fd162 | 72 | { |
RorschachUK | 0:a954bd7fd162 | 73 | //Setup screen |
RorschachUK | 0:a954bd7fd162 | 74 | tt.claim(stdout); // send stdout to the TFT display |
RorschachUK | 0:a954bd7fd162 | 75 | tt.background(Black); // set background to black |
RorschachUK | 0:a954bd7fd162 | 76 | tt.foreground(White); // set chars to white |
RorschachUK | 0:a954bd7fd162 | 77 | tt.cls(); // clear the screen |
RorschachUK | 0:a954bd7fd162 | 78 | tt.set_font((unsigned char*) Arial12x12); // select the font |
RorschachUK | 0:a954bd7fd162 | 79 | tt.set_orientation(1); |
RorschachUK | 0:a954bd7fd162 | 80 | tt.calibrate(); // calibrate the touch |
RorschachUK | 0:a954bd7fd162 | 81 | point p; |
RorschachUK | 0:a954bd7fd162 | 82 | |
RorschachUK | 0:a954bd7fd162 | 83 | tt.locate(0,0); |
RorschachUK | 0:a954bd7fd162 | 84 | |
RorschachUK | 0:a954bd7fd162 | 85 | //Setup base Mandelbrot |
RorschachUK | 0:a954bd7fd162 | 86 | float centrex = -0.5; |
RorschachUK | 0:a954bd7fd162 | 87 | float centrey = 0.0; |
RorschachUK | 0:a954bd7fd162 | 88 | float zoom=0.5; |
RorschachUK | 0:a954bd7fd162 | 89 | int maxiterations = 150; |
RorschachUK | 0:a954bd7fd162 | 90 | |
RorschachUK | 0:a954bd7fd162 | 91 | while(true) { |
RorschachUK | 0:a954bd7fd162 | 92 | //Draw it |
RorschachUK | 0:a954bd7fd162 | 93 | drawMandelbrot(centrex, centrey, zoom, maxiterations); |
RorschachUK | 0:a954bd7fd162 | 94 | |
RorschachUK | 0:a954bd7fd162 | 95 | //Wait for a touch |
RorschachUK | 0:a954bd7fd162 | 96 | p=tt.get_touch(); |
RorschachUK | 0:a954bd7fd162 | 97 | while(!tt.is_touched(p)) { |
RorschachUK | 0:a954bd7fd162 | 98 | p=tt.get_touch(); |
RorschachUK | 0:a954bd7fd162 | 99 | } |
RorschachUK | 0:a954bd7fd162 | 100 | //Set new centre and zoom |
RorschachUK | 0:a954bd7fd162 | 101 | p = tt.to_pixel(p); |
RorschachUK | 0:a954bd7fd162 | 102 | centrex += (2.0 * p.x - WIDTH) / (zoom * WIDTH); |
RorschachUK | 0:a954bd7fd162 | 103 | centrey += (2.0 * p.y - HEIGHT) / (zoom * HEIGHT); |
RorschachUK | 0:a954bd7fd162 | 104 | zoom *= 4.0; |
RorschachUK | 0:a954bd7fd162 | 105 | } |
RorschachUK | 0:a954bd7fd162 | 106 | } |