Last active
September 19, 2020 21:31
-
-
Save tobozo/ccea73d786cb82a56a3a5c1adbc11867 to your computer and use it in GitHub Desktop.
Code used in this ESP32 Wrover Kit (v3) LCD Test video https://youtu.be/jsKxpVOI6no
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Rotatey Hector Nunchuck is placed under the MIT license | |
Copyleft (c+) 2017 tobozo | |
Permission is hereby granted, free of charge, to any person obtaining a copy | |
of this software and associated documentation files (the "Software"), to deal | |
in the Software without restriction, including without limitation the rights | |
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
copies of the Software, and to permit persons to whom the Software is | |
furnished to do so, subject to the following conditions: | |
The above copyright notice and this permission notice shall be included in | |
all copies or substantial portions of the Software. | |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
THE SOFTWARE. | |
This project is heavily inspired from the work of Gerard Ferrandez http://codepen.io/ge1doot/details/eWzQBm/ | |
who developed and implemented the function for HTML5 Canvas. | |
This is just a ripoff with mouse controls replaced by a Wii Nunchuk | |
*/ | |
//#define N 5000 // number of calls to make during test | |
#define NS 1024 // number of entries in sin table | |
#define MAXI 32768 // max integer value in table | |
#define I2F (1./MAXI) // conversion from integer to float | |
#ifndef _swap_int16_t | |
#define _swap_int16_t(a, b) { int16_t t = a; a = b; b = t; } | |
#endif | |
int i ; | |
long startTime, endTime ; | |
float dt ; | |
float d = 0.0 ; // argument to sin function, degrees | |
float s ; // result of sin function | |
// sin table | |
// values for first quadrant, other quadrants calculated by symetry | |
const PROGMEM prog_uint16_t sintab[NS] = { | |
0, | |
50,100,150,201,251, | |
301,351,402,452,502, | |
552,603,653,703,753, | |
804,854,904,954,1005, | |
1055,1105,1155,1206,1256, | |
1306,1356,1407,1457,1507, | |
1557,1607,1658,1708,1758, | |
1808,1858,1909,1959,2009, | |
2059,2109,2159,2210,2260, | |
2310,2360,2410,2460,2510, | |
2560,2611,2661,2711,2761, | |
2811,2861,2911,2961,3011, | |
3061,3111,3161,3211,3261, | |
3311,3361,3411,3461,3511, | |
3561,3611,3661,3711,3761, | |
3811,3861,3911,3961,4011, | |
4061,4110,4160,4210,4260, | |
4310,4360,4409,4459,4509, | |
4559,4609,4658,4708,4758, | |
4808,4857,4907,4957,5006, | |
5056,5106,5155,5205,5255, | |
5304,5354,5403,5453,5503, | |
5552,5602,5651,5701,5750, | |
5800,5849,5898,5948,5997, | |
6047,6096,6146,6195,6244, | |
6294,6343,6392,6442,6491, | |
6540,6589,6639,6688,6737, | |
6786,6835,6884,6934,6983, | |
7032,7081,7130,7179,7228, | |
7277,7326,7375,7424,7473, | |
7522,7571,7620,7669,7717, | |
7766,7815,7864,7913,7961, | |
8010,8059,8108,8156,8205, | |
8254,8302,8351,8400,8448, | |
8497,8545,8594,8642,8691, | |
8739,8788,8836,8884,8933, | |
8981,9029,9078,9126,9174, | |
9223,9271,9319,9367,9415, | |
9463,9512,9560,9608,9656, | |
9704,9752,9800,9848,9896, | |
9944,9991,10039,10087,10135, | |
10183,10230,10278,10326,10374, | |
10421,10469,10517,10564,10612, | |
10659,10707,10754,10802,10849, | |
10897,10944,10991,11039,11086, | |
11133,11181,11228,11275,11322, | |
11369,11416,11464,11511,11558, | |
11605,11652,11699,11746,11793, | |
11839,11886,11933,11980,12027, | |
12073,12120,12167,12213,12260, | |
12307,12353,12400,12446,12493, | |
12539,12586,12632,12678,12725, | |
12771,12817,12864,12910,12956, | |
13002,13048,13094,13140,13186, | |
13232,13278,13324,13370,13416, | |
13462,13508,13554,13599,13645, | |
13691,13736,13782,13828,13873, | |
13919,13964,14010,14055,14100, | |
14146,14191,14236,14282,14327, | |
14372,14417,14462,14507,14552, | |
14598,14642,14687,14732,14777, | |
14822,14867,14912,14956,15001, | |
15046,15090,15135,15180,15224, | |
15269,15313,15357,15402,15446, | |
15491,15535,15579,15623,15667, | |
15712,15756,15800,15844,15888, | |
15932,15976,16019,16063,16107, | |
16151,16195,16238,16282,16325, | |
16369,16413,16456,16499,16543, | |
16586,16630,16673,16716,16759, | |
16802,16846,16889,16932,16975, | |
17018,17061,17104,17146,17189, | |
17232,17275,17317,17360,17403, | |
17445,17488,17530,17573,17615, | |
17658,17700,17742,17784,17827, | |
17869,17911,17953,17995,18037, | |
18079,18121,18163,18204,18246, | |
18288,18330,18371,18413,18454, | |
18496,18537,18579,18620,18662, | |
18703,18744,18785,18826,18868, | |
18909,18950,18991,19032,19073, | |
19113,19154,19195,19236,19276, | |
19317,19358,19398,19439,19479, | |
19519,19560,19600,19640,19681, | |
19721,19761,19801,19841,19881, | |
19921,19961,20001,20040,20080, | |
20120,20159,20199,20239,20278, | |
20318,20357,20396,20436,20475, | |
20514,20553,20592,20631,20671, | |
20709,20748,20787,20826,20865, | |
20904,20942,20981,21020,21058, | |
21097,21135,21173,21212,21250, | |
21288,21326,21365,21403,21441, | |
21479,21517,21555,21592,21630, | |
21668,21706,21743,21781,21818, | |
21856,21893,21931,21968,22005, | |
22042,22080,22117,22154,22191, | |
22228,22265,22301,22338,22375, | |
22412,22448,22485,22521,22558, | |
22594,22631,22667,22703,22740, | |
22776,22812,22848,22884,22920, | |
22956,22992,23027,23063,23099, | |
23134,23170,23205,23241,23276, | |
23312,23347,23382,23417,23453, | |
23488,23523,23558,23593,23627, | |
23662,23697,23732,23766,23801, | |
23835,23870,23904,23939,23973, | |
24007,24041,24075,24109,24144, | |
24177,24211,24245,24279,24313, | |
24346,24380,24414,24447,24480, | |
24514,24547,24580,24614,24647, | |
24680,24713,24746,24779,24812, | |
24845,24877,24910,24943,24975, | |
25008,25040,25073,25105,25137, | |
25169,25201,25234,25266,25298, | |
25330,25361,25393,25425,25457, | |
25488,25520,25551,25583,25614, | |
25645,25677,25708,25739,25770, | |
25801,25832,25863,25894,25925, | |
25955,25986,26016,26047,26077, | |
26108,26138,26169,26199,26229, | |
26259,26289,26319,26349,26379, | |
26409,26438,26468,26498,26527, | |
26557,26586,26615,26645,26674, | |
26703,26732,26761,26790,26819, | |
26848,26877,26905,26934,26963, | |
26991,27020,27048,27076,27105, | |
27133,27161,27189,27217,27245, | |
27273,27301,27329,27356,27384, | |
27411,27439,27466,27494,27521, | |
27548,27576,27603,27630,27657, | |
27684,27711,27737,27764,27791, | |
27817,27844,27870,27897,27923, | |
27949,27976,28002,28028,28054, | |
28080,28106,28131,28157,28183, | |
28208,28234,28259,28285,28310, | |
28335,28361,28386,28411,28436, | |
28461,28486,28511,28535,28560, | |
28585,28609,28634,28658,28682, | |
28707,28731,28755,28779,28803, | |
28827,28851,28875,28898,28922, | |
28946,28969,28993,29016,29039, | |
29062,29086,29109,29132,29155, | |
29178,29201,29223,29246,29269, | |
29291,29314,29336,29359,29381, | |
29403,29425,29447,29469,29491, | |
29513,29535,29557,29578,29600, | |
29621,29643,29664,29686,29707, | |
29728,29749,29770,29791,29812, | |
29833,29854,29874,29895,29915, | |
29936,29956,29977,29997,30017, | |
30037,30057,30077,30097,30117, | |
30137,30156,30176,30196,30215, | |
30235,30254,30273,30292,30312, | |
30331,30350,30368,30387,30406, | |
30425,30443,30462,30480,30499, | |
30517,30535,30554,30572,30590, | |
30608,30626,30644,30661,30679, | |
30697,30714,30732,30749,30766, | |
30784,30801,30818,30835,30852, | |
30869,30886,30902,30919,30936, | |
30952,30969,30985,31001,31018, | |
31034,31050,31066,31082,31098, | |
31114,31129,31145,31161,31176, | |
31192,31207,31222,31237,31253, | |
31268,31283,31298,31312,31327, | |
31342,31357,31371,31386,31400, | |
31414,31429,31443,31457,31471, | |
31485,31499,31513,31526,31540, | |
31554,31567,31581,31594,31607, | |
31620,31634,31647,31660,31673, | |
31685,31698,31711,31723,31736, | |
31749,31761,31773,31785,31798, | |
31810,31822,31834,31846,31857, | |
31869,31881,31892,31904,31915, | |
31927,31938,31949,31960,31971, | |
31982,31993,32004,32015,32025, | |
32036,32047,32057,32067,32078, | |
32088,32098,32108,32118,32128, | |
32138,32148,32157,32167,32176, | |
32186,32195,32205,32214,32223, | |
32232,32241,32250,32259,32268, | |
32276,32285,32294,32302,32311, | |
32319,32327,32335,32343,32351, | |
32359,32367,32375,32383,32390, | |
32398,32405,32413,32420,32427, | |
32435,32442,32449,32456,32463, | |
32469,32476,32483,32489,32496, | |
32502,32509,32515,32521,32527, | |
32533,32539,32545,32551,32557, | |
32562,32568,32573,32579,32584, | |
32589,32595,32600,32605,32610, | |
32615,32619,32624,32629,32633, | |
32638,32642,32647,32651,32655, | |
32659,32663,32667,32671,32675, | |
32679,32682,32686,32689,32693, | |
32696,32700,32703,32706,32709, | |
32712,32715,32718,32720,32723, | |
32726,32728,32730,32733,32735, | |
32737,32739,32741,32743,32745, | |
32747,32749,32750,32752,32754, | |
32755,32756,32758,32759,32760, | |
32761,32762,32763,32764,32764, | |
32765,32766,32766,32767,32767, | |
32767,32767,32767 | |
} ; | |
float TWOPI = PI*2; | |
float HALFPI = PI*0.5; | |
float ITWOPI = 1./TWOPI; | |
float romsin(float x) { | |
return dosincos(x, false); | |
} | |
float romcos(float x) { | |
return dosincos(x, true); | |
} | |
float dosincos(float x, bool iscos) { | |
int ix ; // index into sin table | |
int is ; // value read from sin table | |
int q ; // quadrant number 0,1,2,3 | |
int j ; | |
if(iscos) x += HALFPI; | |
x *= ITWOPI; | |
x -= (int)x ; | |
if (x < 0) | |
x += 1.0 ; // x is now between 0 and 1, representing 0 to 360 degrees | |
q = x * 4 ; // get quadrant number | |
ix = (int)(x*4*NS) % NS ; // get index into table | |
switch(q) { | |
case 0: // 0-90 | |
is = pgm_read_word_near(sintab + ix); | |
break ; | |
case 1: // 90-180 | |
ix = NS - ix - 1 ; // reflect | |
is = pgm_read_word_near(sintab + ix); ; | |
break ; | |
case 2: // 180-270 | |
is = -pgm_read_word_near(sintab + ix); ; // negate | |
break ; | |
case 3: // 270-360 | |
ix = NS - ix - 1; // reflect | |
is = -pgm_read_word_near(sintab + ix); ; // negate | |
break ; | |
} | |
return((float)is*I2F) ; | |
} | |
/** | |
#include "Wire.h" | |
//#include <WiiChuck.h> | |
#include "SSD1306.h" // alias for `#include "SSD1306Wire.h"` | |
#include "OLEDDisplayUi.h" | |
**/ | |
#include "SPI.h" | |
#include "Adafruit_GFX.h" | |
#include "WROVER_KIT_LCD.h" | |
#define DEBUG false | |
//Nunchuck nunchuck(SDA, SCL); | |
WROVER_KIT_LCD display; | |
// Accel and gyro data | |
int16_t gx, gy; | |
long int timeLast = -100; | |
long framecount = 0; | |
int ispeed = 36000; // interpolation speed | |
float bouncespeed = 1; | |
float lastspeedpot; | |
long lastnunchukread = 0; | |
long nunchukreaddelay = 500; | |
const float size = 256; | |
const int step = 8; | |
const int doublestep = step*2; | |
const float speed = 0.06; | |
const int num = size / step; | |
float tsize = 0.85*size; | |
const int halfsize = size * 0.5; | |
float zoom = 1.25; | |
float halfzoom = 0.5 * zoom; | |
float k = 0; | |
// this is the point matrix | |
int tx[256]; // tx[size / step] | |
int ty[256]; // tx[size / step] | |
int tz[256]; | |
int sy[320]; // depth cache, for 'solid' visual effect | |
int txlast; | |
int tylast; | |
#define SCREEN_WIDTH 320 | |
#define SCREEN_HEIGHT 240 | |
#define SCREEN_HALF_WIDTH SCREEN_WIDTH * 0.5 | |
#define SCREEN_HALF_HEIGHT SCREEN_HEIGHT * 0.5 | |
int screen[16384]; | |
int totalpixels = 0; | |
uint16_t WROVER_GRAY; | |
// f(x,y) equation | |
float surface(float x, float y, float k) { | |
float r = 0.001 * (x * x + y * y); | |
return 100 * romcos((-k + r) / 1) / (2 + r); | |
} | |
// projection | |
void project(int p, float x, float y, float z, float ah, float av) { | |
float cosah = romcos(ah); | |
float sinah = romsin(ah); | |
float x1 = x * cosah - y * sinah; | |
float y1 = x * sinah + y * cosah; | |
float z2 = z * romcos(av) - x1 * romsin(av); | |
float s = size / (tsize - x1); | |
tx[p] = SCREEN_HALF_WIDTH - (zoom * (y1 * s)); | |
ty[p] = SCREEN_HALF_HEIGHT - (zoom * (z2 * s)); | |
} | |
// handle depth cache while line-drawing | |
void mySetPixel(int x, int y, uint16_t color) { | |
uint16_t ocolor; | |
if(sy[x]>y) { | |
// pixel already there, no need to draw | |
y = sy[x]; | |
ocolor = WROVER_GRAY; | |
} else { | |
//display.setPixel(x, y); | |
display.writePixel(x, y, color); | |
//display.writePixel(x, y+1, WROVER_BLACK); | |
//display.writeFillRect(x, y+1, 1, 15, WROVER_BLACK); | |
//int index = totalpixels*2; | |
//screen[index] = x; | |
//screen[index+1] = y; | |
totalpixels++; | |
//screen[(y*SCREEN_WIDTH)+x] = color; | |
ocolor = WROVER_BLACK; | |
display.writePixel(x, y+1, ocolor); | |
sy[x] = y; | |
} | |
} | |
void moveTo(int x, int y) { | |
txlast = x; | |
tylast = y; | |
} | |
// draw helpers, just a copy of drawLine, calling mySetPixel() instead of setPixel() | |
// to handle depth, mainly here to compensate the lack of fill/stroke | |
void drawOverlap(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color) { | |
int16_t steep = abs(y1 - y0) > abs(x1 - x0); | |
if (steep) { | |
_swap_int16_t(x0, y0); | |
_swap_int16_t(x1, y1); | |
} | |
if (x0 > x1) { | |
_swap_int16_t(x0, x1); | |
_swap_int16_t(y0, y1); | |
} | |
int16_t dx, dy; | |
dx = x1 - x0; | |
dy = abs(y1 - y0); | |
int16_t err = dx / 2; | |
int16_t ystep; | |
if (y0 < y1) { | |
ystep = 1; | |
} else { | |
ystep = -1; | |
} | |
for (; x0<=x1; x0++) { | |
if (steep) { | |
mySetPixel(y0, x0, color); | |
} else { | |
mySetPixel(x0, y0, color); | |
} | |
err -= dy; | |
if (err < 0) { | |
y0 += ystep; | |
err += dx; | |
} | |
} | |
} | |
void lineTo(int x, int y, uint16_t color) { | |
if(x>SCREEN_WIDTH) return; | |
if(y>SCREEN_HEIGHT) return; | |
if(x<0) return; | |
if(y<0) return; | |
drawOverlap(txlast, tylast, x, y, color); | |
txlast = x; | |
tylast = y; | |
} | |
//draw | |
void drawPath(int tx[], int ty[]) { | |
moveTo(tx[0], ty[0]); | |
for (int p = 0; p < num; p++) { | |
lineTo(tx[p], ty[p], tz[p]); | |
} | |
} | |
float min = 1024; | |
float max = -1024; | |
// main loop | |
void sinLoop() { | |
// reset depth cache | |
memset(sy,-1,sizeof(sy)); | |
totalpixels = 0; | |
//memset(screen,WROVER_BLACK,sizeof(screen)); | |
uint8_t kr; | |
uint8_t kg; | |
uint8_t kb; | |
k += speed; | |
kr = ((uint8_t)(k*50)) / 8; | |
kg = ((uint8_t)(k*55)) / 8; | |
kb = ((uint8_t)(k*60)) / 8; | |
float ah = ((-0.5 * gx + SCREEN_HALF_WIDTH) / SCREEN_WIDTH); | |
float av = 0.5 * gy / SCREEN_HEIGHT; | |
display.startBitmap(0, 0, 320,240); | |
//display.writeColor(WROVER_BLACK, 76800); | |
//display.writeFillRect(0,0,320,200,WROVER_BLACK); | |
for (float x = halfsize; x >= -halfsize; x -= doublestep) { | |
int p = 0; | |
for (float y = -halfsize; y <= halfsize; y += step) { | |
float z = surface(x, y, k); | |
project(p++, x, y, z, ah, av); | |
uint8_t zstrength = (255 - ((z+50)*2.55)) *.75; | |
uint8_t green = zstrength + kr; | |
uint8_t red = zstrength + kg; | |
uint8_t blue = zstrength + kb; | |
tz[p] = display.color565(red, green, blue); | |
/* | |
if(z<min) { | |
min = z; | |
Serial.print("New Min: "); | |
Serial.print(uint8_t((z+50)*2.55)); | |
Serial.print("\t"); | |
Serial.println(z); | |
} | |
if(z>max) { | |
Serial.print("New Max: "); | |
Serial.print(uint8_t((z+50)*2.55)); | |
Serial.print("\t"); | |
Serial.println(z); | |
max = z; | |
}*/ | |
//Serial.print("\t"); | |
} | |
drawPath(tx, ty); | |
} | |
display.endBitmap(); | |
//display.display(); | |
timeLast = millis(); | |
} | |
void setup() { | |
Serial.println("hello"); | |
// assign default color value | |
Serial.begin(115200); | |
display.begin(); | |
display.setRotation(3); | |
/* | |
display.init(); | |
display.clear(); // clears the screen and buffer | |
display.display(); | |
display.setColor(WHITE); | |
*/ | |
//nunchuck.begin(); | |
gx = 256 + (k*20); | |
gy = -305; | |
display.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, WROVER_BLACK); | |
WROVER_GRAY = display.color565(200, 200, 200); | |
} | |
void loop() { | |
gx = romsin(k/16)*256 + 128; | |
//display.clear(); | |
//display.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, WROVER_BLACK); | |
/* | |
if(lastnunchukread + nunchukreaddelay < timeLast) { | |
nunchuck.readData(); // Read inputs and update maps | |
delay(10); | |
int mx = nunchuck.getAccelX(); | |
int my = nunchuck.getAccelY(); | |
if(nunchuck.checkButtonC()) { | |
zoom += 0.05; | |
halfzoom = 0.5 * zoom; | |
} | |
if(nunchuck.checkButtonZ()) { | |
zoom -= 0.05; | |
halfzoom = 0.5 * zoom; | |
} | |
if(mx>5 && mx < 1020) gx = (mx - 512)/4 + 30; //give some default angle | |
if(my>5 && my < 1020) gy = (my - 512)/4 - 75; | |
Serial.print( gx); | |
Serial.print( "\t"); | |
Serial.println( gy ); | |
lastnunchukread = timeLast; | |
} | |
*/ | |
sinLoop(); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment