Example drawing mandelbrot on the RA8875 with touch to zoom in or out. Touch and hold > 4s to zoom out, touch to zoom in.
Saw the nice mandelbrot demo from Bob Stone and leverage it to use this library.
main.cpp@6:3979c5ff6d32, 2019-07-28 (annotated)
- Committer:
- WiredHome
- Date:
- Sun Jul 28 03:06:38 2019 +0000
- Revision:
- 6:3979c5ff6d32
- Parent:
- 5:3efba02a1cb2
Update RA lib
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
WiredHome | 4:857e3bf77211 | 1 | #include "mbed.h" // v112 |
WiredHome | 4:857e3bf77211 | 2 | #include "RA8875.h" // v102 |
WiredHome | 1:14319ec53540 | 3 | |
WiredHome | 5:3efba02a1cb2 | 4 | // These two defines can be enabled, or commented out |
WiredHome | 5:3efba02a1cb2 | 5 | #define BIG_SCREEN |
WiredHome | 5:3efba02a1cb2 | 6 | #define CAP_TOUCH |
WiredHome | 5:3efba02a1cb2 | 7 | #define LCD_C 16 // color - bits per pixel |
WiredHome | 5:3efba02a1cb2 | 8 | |
WiredHome | 5:3efba02a1cb2 | 9 | #ifdef CAP_TOUCH |
WiredHome | 6:3979c5ff6d32 | 10 | RA8875 lcd(p5,p6,p7,p12,NC, p9,p10,p13, "tft"); // MOSI,MISO,SCK,/ChipSelect,/reset, SDA,SCL,/IRQ, name |
WiredHome | 5:3efba02a1cb2 | 11 | #else |
WiredHome | 6:3979c5ff6d32 | 12 | RA8875 lcd(p5,p6,p7,p12,NC, "tft"); //MOSI, MISO, SCK, /ChipSelect, /reset, name |
WiredHome | 5:3efba02a1cb2 | 13 | LocalFileSystem local("local"); // access to calibration file for resistive touch. |
WiredHome | 5:3efba02a1cb2 | 14 | #endif |
WiredHome | 5:3efba02a1cb2 | 15 | |
WiredHome | 5:3efba02a1cb2 | 16 | #ifdef BIG_SCREEN |
WiredHome | 5:3efba02a1cb2 | 17 | #define LCD_W 800 |
WiredHome | 5:3efba02a1cb2 | 18 | #define LCD_H 480 |
WiredHome | 5:3efba02a1cb2 | 19 | #else |
WiredHome | 5:3efba02a1cb2 | 20 | #define LCD_W 480 |
WiredHome | 5:3efba02a1cb2 | 21 | #define LCD_H 272 |
WiredHome | 5:3efba02a1cb2 | 22 | #endif |
WiredHome | 5:3efba02a1cb2 | 23 | |
WiredHome | 1:14319ec53540 | 24 | Serial pc(USBTX, USBRX); |
WiredHome | 1:14319ec53540 | 25 | |
WiredHome | 1:14319ec53540 | 26 | uint16_t width, height; |
WiredHome | 0:702ce703348d | 27 | |
WiredHome | 1:14319ec53540 | 28 | int GetScreenCapture(void) |
WiredHome | 1:14319ec53540 | 29 | { |
WiredHome | 1:14319ec53540 | 30 | char fqfn[50]; |
WiredHome | 1:14319ec53540 | 31 | int i = 0; |
WiredHome | 1:14319ec53540 | 32 | |
WiredHome | 1:14319ec53540 | 33 | pc.printf("Screen Capture... "); |
WiredHome | 1:14319ec53540 | 34 | for (i=1; i< 100; i++) { |
WiredHome | 1:14319ec53540 | 35 | snprintf(fqfn, sizeof(fqfn), "/local/Screen%02d.bmp", i); |
WiredHome | 1:14319ec53540 | 36 | FILE * fh = fopen(fqfn, "rb"); |
WiredHome | 1:14319ec53540 | 37 | if (!fh) { |
WiredHome | 1:14319ec53540 | 38 | lcd.PrintScreen(0,0,480,272,fqfn); |
WiredHome | 1:14319ec53540 | 39 | pc.printf(" as /local/Screen%02d.bmp\r\n", i); |
WiredHome | 1:14319ec53540 | 40 | return i; |
WiredHome | 1:14319ec53540 | 41 | } else { |
WiredHome | 1:14319ec53540 | 42 | fclose(fh); // close this and try the next |
WiredHome | 1:14319ec53540 | 43 | } |
WiredHome | 1:14319ec53540 | 44 | } |
WiredHome | 1:14319ec53540 | 45 | return 0; |
WiredHome | 1:14319ec53540 | 46 | } |
WiredHome | 0:702ce703348d | 47 | |
WiredHome | 0:702ce703348d | 48 | |
WiredHome | 0:702ce703348d | 49 | void drawMandelbrot(float centrex, float centrey, float zoom, int maxIter) { |
WiredHome | 0:702ce703348d | 50 | float xmin = centrex - 1.0/zoom; |
WiredHome | 0:702ce703348d | 51 | float xmax = centrex + 1.0/zoom; |
WiredHome | 0:702ce703348d | 52 | float ymin = centrey - height / (width * zoom); |
WiredHome | 5:3efba02a1cb2 | 53 | float ymax = centrey + height / (width * zoom); |
WiredHome | 0:702ce703348d | 54 | float dx = (xmax - xmin) / width; |
WiredHome | 0:702ce703348d | 55 | float dy = (ymax - ymin) / height; |
WiredHome | 0:702ce703348d | 56 | float y = ymin; |
WiredHome | 0:702ce703348d | 57 | float c; |
WiredHome | 0:702ce703348d | 58 | unsigned int cr, cg, cb; |
WiredHome | 0:702ce703348d | 59 | |
WiredHome | 0:702ce703348d | 60 | lcd.SetGraphicsCursor(0, 0); |
WiredHome | 1:14319ec53540 | 61 | // shows use of a pixel (one line scan) buffer. |
WiredHome | 0:702ce703348d | 62 | color_t * pixelBuffer = (color_t *)malloc(width * sizeof(color_t)); |
WiredHome | 0:702ce703348d | 63 | |
WiredHome | 0:702ce703348d | 64 | for (int j = 0; j < height; j++) { |
WiredHome | 0:702ce703348d | 65 | float x = xmin; |
WiredHome | 0:702ce703348d | 66 | |
WiredHome | 0:702ce703348d | 67 | for (int i = 0; i < width; i++) { |
WiredHome | 0:702ce703348d | 68 | float a = x; |
WiredHome | 0:702ce703348d | 69 | float b = y; |
WiredHome | 0:702ce703348d | 70 | int n = 0; |
WiredHome | 0:702ce703348d | 71 | |
WiredHome | 0:702ce703348d | 72 | while (n < maxIter) { |
WiredHome | 0:702ce703348d | 73 | float aa = a * a; |
WiredHome | 0:702ce703348d | 74 | float bb = b * b; |
WiredHome | 0:702ce703348d | 75 | float twoab = 2.0 * a * b; |
WiredHome | 0:702ce703348d | 76 | |
WiredHome | 0:702ce703348d | 77 | a = aa - bb + x; |
WiredHome | 0:702ce703348d | 78 | b = twoab + y; |
WiredHome | 0:702ce703348d | 79 | if(aa + bb > 16.0) { |
WiredHome | 0:702ce703348d | 80 | break; |
WiredHome | 0:702ce703348d | 81 | } |
WiredHome | 0:702ce703348d | 82 | n++; |
WiredHome | 0:702ce703348d | 83 | } |
WiredHome | 0:702ce703348d | 84 | |
WiredHome | 0:702ce703348d | 85 | if (n == maxIter) { |
WiredHome | 0:702ce703348d | 86 | //It's in the set - Black |
WiredHome | 1:14319ec53540 | 87 | pixelBuffer[i] = Black; // if not using the pixel buffer, then lcd.pixel(i,j,Black); |
WiredHome | 0:702ce703348d | 88 | } else { |
WiredHome | 0:702ce703348d | 89 | //Not in the set - pick a colour |
WiredHome | 0:702ce703348d | 90 | c = 3.0 * (maxIter-n)/maxIter; |
WiredHome | 0:702ce703348d | 91 | cr = ((c < 1.0) ? 255 * ( 1.0 - c) : (c > 2.0) ? 255 * (c - 2.0) : 0); |
WiredHome | 0:702ce703348d | 92 | cg = ((c < 1.0) ? 255 * c : (c > 2.0) ? 0 : 255 * (2.0 - c)); |
WiredHome | 0:702ce703348d | 93 | cb = ((c < 1.0) ? 0 : (c > 2.0) ? 255 * (3.0 - c) : 255 * (c - 1.0)); |
WiredHome | 0:702ce703348d | 94 | pixelBuffer[i] = RGB(cr,cg,cb); //lcd.pixel(i,j, RGB(cr,cg,cb)); |
WiredHome | 0:702ce703348d | 95 | } |
WiredHome | 0:702ce703348d | 96 | x += dx; |
WiredHome | 0:702ce703348d | 97 | } |
WiredHome | 0:702ce703348d | 98 | lcd.pixelStream(pixelBuffer, width, 0, j); // send this scanline |
WiredHome | 0:702ce703348d | 99 | y += dy; |
WiredHome | 0:702ce703348d | 100 | } |
WiredHome | 1:14319ec53540 | 101 | free(pixelBuffer); // don't leak memory. |
WiredHome | 0:702ce703348d | 102 | } |
WiredHome | 1:14319ec53540 | 103 | |
WiredHome | 1:14319ec53540 | 104 | |
WiredHome | 1:14319ec53540 | 105 | |
WiredHome | 0:702ce703348d | 106 | int main() |
WiredHome | 0:702ce703348d | 107 | { |
WiredHome | 0:702ce703348d | 108 | Timer timer; |
WiredHome | 1:14319ec53540 | 109 | point_t p; |
WiredHome | 1:14319ec53540 | 110 | |
WiredHome | 0:702ce703348d | 111 | pc.baud(460800); // I like a snappy terminal, so crank it up! |
WiredHome | 0:702ce703348d | 112 | pc.printf("\r\nRA8875 Portrait Mode Dev. - Build " __DATE__ " " __TIME__ "\r\n"); |
WiredHome | 1:14319ec53540 | 113 | pc.printf("Press 'P' to PrintScreen as bmp on local file system\r\n"); |
WiredHome | 1:14319ec53540 | 114 | |
WiredHome | 5:3efba02a1cb2 | 115 | lcd.init(LCD_W, LCD_H, LCD_C); |
WiredHome | 5:3efba02a1cb2 | 116 | lcd.Backlight(0.5f); |
WiredHome | 5:3efba02a1cb2 | 117 | |
WiredHome | 5:3efba02a1cb2 | 118 | #ifndef CAP_TOUCH |
WiredHome | 5:3efba02a1cb2 | 119 | InitTS(); |
WiredHome | 5:3efba02a1cb2 | 120 | #endif |
WiredHome | 5:3efba02a1cb2 | 121 | |
WiredHome | 1:14319ec53540 | 122 | width = lcd.width(); // Could have set the dimensions, let's just adapt. |
WiredHome | 0:702ce703348d | 123 | height = lcd.height(); |
WiredHome | 0:702ce703348d | 124 | |
WiredHome | 0:702ce703348d | 125 | lcd.claim(stdout); // send stdout to the TFT display |
WiredHome | 0:702ce703348d | 126 | lcd.background(Black); // set background to black |
WiredHome | 0:702ce703348d | 127 | lcd.foreground(White); // set chars to white |
WiredHome | 0:702ce703348d | 128 | lcd.cls(); // clear the screen |
WiredHome | 5:3efba02a1cb2 | 129 | |
WiredHome | 0:702ce703348d | 130 | //Setup base Mandelbrot |
WiredHome | 0:702ce703348d | 131 | float centrex = -0.5; |
WiredHome | 0:702ce703348d | 132 | float centrey = 0.0; |
WiredHome | 0:702ce703348d | 133 | float zoom=0.5; |
WiredHome | 0:702ce703348d | 134 | int maxiterations = 150; |
WiredHome | 0:702ce703348d | 135 | |
WiredHome | 0:702ce703348d | 136 | while(true) { |
WiredHome | 0:702ce703348d | 137 | //Draw it |
WiredHome | 0:702ce703348d | 138 | drawMandelbrot(centrex, centrey, zoom, maxiterations); |
WiredHome | 0:702ce703348d | 139 | |
WiredHome | 0:702ce703348d | 140 | pc.printf("ready for touch\r\n"); |
WiredHome | 1:14319ec53540 | 141 | bool waitingOnUser = true; |
WiredHome | 1:14319ec53540 | 142 | while (waitingOnUser) { |
WiredHome | 5:3efba02a1cb2 | 143 | TouchCode_t t; |
WiredHome | 5:3efba02a1cb2 | 144 | |
WiredHome | 1:14319ec53540 | 145 | if (pc.readable()) { |
WiredHome | 1:14319ec53540 | 146 | int c = pc.getc(); |
WiredHome | 1:14319ec53540 | 147 | if (c == 'P') |
WiredHome | 1:14319ec53540 | 148 | GetScreenCapture(); |
WiredHome | 1:14319ec53540 | 149 | } |
WiredHome | 5:3efba02a1cb2 | 150 | t = lcd.TouchPanelReadable(); |
WiredHome | 5:3efba02a1cb2 | 151 | if (t != no_touch) { |
WiredHome | 1:14319ec53540 | 152 | bool zoomOut = false; |
WiredHome | 1:14319ec53540 | 153 | |
WiredHome | 5:3efba02a1cb2 | 154 | pc.printf("touch: %d\r\n", t); |
WiredHome | 1:14319ec53540 | 155 | timer.start(); |
WiredHome | 1:14319ec53540 | 156 | timer.reset(); |
WiredHome | 5:3efba02a1cb2 | 157 | t = lcd.TouchPanelReadable(&p); |
WiredHome | 5:3efba02a1cb2 | 158 | pc.printf(" t: %d\r\n", t); |
WiredHome | 5:3efba02a1cb2 | 159 | while (t == touch || t == held) { |
WiredHome | 1:14319ec53540 | 160 | if (timer.read_ms() > 2000) { |
WiredHome | 1:14319ec53540 | 161 | zoomOut = true; |
WiredHome | 1:14319ec53540 | 162 | break; |
WiredHome | 1:14319ec53540 | 163 | } |
WiredHome | 5:3efba02a1cb2 | 164 | t = lcd.TouchPanelReadable(&p); |
WiredHome | 5:3efba02a1cb2 | 165 | pc.printf(" u: %d\r\n", t); |
WiredHome | 1:14319ec53540 | 166 | } |
WiredHome | 1:14319ec53540 | 167 | if (zoomOut) { // long held is zoom out. |
WiredHome | 1:14319ec53540 | 168 | // zoom out |
WiredHome | 1:14319ec53540 | 169 | lcd.puts(50, 250, "Zooming out..."); |
WiredHome | 1:14319ec53540 | 170 | pc.printf("zoom out\r\n"); |
WiredHome | 1:14319ec53540 | 171 | centrex = -0.5; |
WiredHome | 1:14319ec53540 | 172 | centrey = 0.0; |
WiredHome | 1:14319ec53540 | 173 | zoom=0.5; |
WiredHome | 1:14319ec53540 | 174 | } else { |
WiredHome | 1:14319ec53540 | 175 | //Set new centre and zoom |
WiredHome | 1:14319ec53540 | 176 | lcd.puts(50, 250, "Zooming in..."); |
WiredHome | 1:14319ec53540 | 177 | pc.printf("zoom in\r\n"); |
WiredHome | 1:14319ec53540 | 178 | centrex += (2.0 * p.x - width) / (zoom * height); |
WiredHome | 1:14319ec53540 | 179 | centrey += (2.0 * p.y - height) / (zoom * width); |
WiredHome | 1:14319ec53540 | 180 | zoom *= 4.0; |
WiredHome | 1:14319ec53540 | 181 | lcd.rect(p.x - width / 8.0, p.y - height / 8.0, |
WiredHome | 1:14319ec53540 | 182 | p.x + width / 8.0, p.y + height / 8.0, Yellow); |
WiredHome | 2:feda27c3a523 | 183 | wait_ms(100); |
WiredHome | 1:14319ec53540 | 184 | } |
WiredHome | 1:14319ec53540 | 185 | waitingOnUser = false; |
WiredHome | 1:14319ec53540 | 186 | } |
WiredHome | 0:702ce703348d | 187 | } |
WiredHome | 0:702ce703348d | 188 | } |
WiredHome | 0:702ce703348d | 189 | } |
WiredHome | 0:702ce703348d | 190 |