commit a4ea4795a0724f9946a68a3043684acda0096088 Author: Luis Rodil-Fernandez Date: Sat Jul 30 22:49:21 2022 +0200 first commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..a4c550e --- /dev/null +++ b/README.md @@ -0,0 +1,12 @@ +<<< a bunch of classic demoscene effects running on an esp32 >>> +___. .__ __ .__ .___ __ +\_ |__ |__|_______/ |_| |__ __| _/____ ___.__._/ |________ ____ + | __ \| \_ __ \ __\ | \ / __ |\__ \< | |\ __\_ __ \/ _ \ + | \_\ \ || | \/| | | Y \/ /_/ | / __ \\___ | | | | | \( <_> ) + |___ /__||__| |__| |___| /\____ |(____ / ____| |__| |__| \____/ + \/ \/ \/ \/\/ + +----- - - --- - - --- - -- - - - --- - - - --- --- -- - - - -- -- --+ + : reliving some teenage coding on a lazy summer day . + . oldskool effects running on an ESP32 with a monochrome display : + : http://www.derfunke.net . + +-- (( 2022 )) ------ -- - -------------- -- --- ---------------- -- --+ diff --git a/include/README b/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/lib/README b/lib/README new file mode 100644 index 0000000..6debab1 --- /dev/null +++ b/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..c1dfa14 --- /dev/null +++ b/platformio.ini @@ -0,0 +1,22 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:lolin32] +platform = espressif32 +board = lolin32 +framework = arduino + +monitor_speed = 115200 + +; NeoGPS=slashdevin/NeoGPS@^4.2.9 + +lib_deps = + SSD1306=adafruit/Adafruit SSD1306@^2.5.6 + Time=paulstoffregen/Time@^1.6.1 diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..75cc1be --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,157 @@ +#include + +#include +#include +#include +#include + +#define DEG2RAD 0.01745329f + +#define SCREEN_WIDTH 128 +#define SCREEN_HEIGHT 64 + +#define OLED_RESET -1 +#define SCREEN_ADDRESS 0x3C +Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); + +#define STAR_COUNT 300 + +#define TEXT_COUNT 17 +int textIdx = 0; +unsigned long lastText = 0; +const char *texts[] = { + "REMEMBER WHERE YOU ARE", + "THIS\nSPECK\nOF MATTER", + "YOU ARE\nSTARDUST", + "THAT WILL\nWALK HERE", + "ONLY\nONCE", + "GO FIND\nOTHERS", + "8000\nLIGHT\nYEARS", + "ISN'T\nFAR", + "WHEN YOU\nTRAVEL", + "IN YOUR\nMIND", + "", + "", + "", + "HAPPY\nBIRTHDAY", + "HAPPY\nBIRTHDAY", + "", + "", +}; + +struct Star { + int angle; + int age; + int speed; +}; + +Star sfield[STAR_COUNT]; + +void init_display() { + Wire.begin(5, 4); + + if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS, false, false)) { + Serial.println(F("SSD1306 allocation failed")); + while(true) ; // do not proceed + } + + display.clearDisplay(); +} + +void star_reset(int which) { + sfield[which].angle = random(360); + sfield[which].speed = random(1, 6); +} + +void init_starfield() { + for (int i = 0; i < STAR_COUNT; i++) { + sfield[i].age = random(0, 100); + star_reset( i ); + } +} + +void setup() { + Serial.begin(115200); + init_display(); + init_starfield(); + Serial.println("Kicking off starfield"); +} + +void draw_starfield() { + int xstar, ystar; + + // compute center of screen + int xc = SCREEN_WIDTH >> 1; + int yc = SCREEN_HEIGHT >> 1; + + display.clearDisplay(); + + for (int i = 0; i < STAR_COUNT; i++) { + + if (sfield[i].age > 100) { + sfield[i].age = sfield[i].age - 100; + star_reset(i); + } else { + sfield[i].age = sfield[i].age + sfield[i].speed; + } + + xstar = (xc + (sin(sfield[i].angle * DEG2RAD) * sfield[i].age )); + ystar = (yc + (cos(sfield[i].angle * DEG2RAD) * sfield[i].age )); + display.drawPixel(xstar, ystar, WHITE); + } +} + +void draw_moire() { + float t = millis() * 0.001; + + float cx1 = sin(t / 2) * SCREEN_WIDTH / 3 + SCREEN_WIDTH / 2; + float cy1 = sin(t / 4) * SCREEN_HEIGHT / 3 + SCREEN_HEIGHT / 2; + float cx2 = cos(t / 3) * SCREEN_WIDTH / 3 + SCREEN_WIDTH / 2; + float cy2 = cos(t) * SCREEN_HEIGHT / 3 + SCREEN_HEIGHT / 2; + + for(int y = 0; y < SCREEN_HEIGHT; y++) { + float dy = (y - cy1) * (y - cy1); + float dy2 = (y - cy2) * (y - cy2); + for(int x = 0; x < SCREEN_WIDTH; x++) { + float dx = (x - cx1) * (x - cx1); + float dx2 = (x - cx2) * (x - cx2); + int ic = (int)ceil(sqrt(dx + dy)); + int ic2 = (int)ceil(sqrt(dx2 + dy2)); + int shade = ((( ic ^ ic2 ) >> 3) & 1) * 255; + + if(shade > 128) { + display.drawPixel(x, y, WHITE); + } else { + display.drawPixel(x, y, BLACK); + } + + } + } +} + +void draw_text1() { + if( (millis() - lastText) >= 3200 ) { + textIdx++; + lastText = millis(); + if(textIdx >= TEXT_COUNT) textIdx = 0; + } + display.setTextSize(2); + display.setTextColor(SSD1306_WHITE); + display.setCursor(10, 12); + display.println(F( texts[textIdx] )); + // display.setCursor(10, 32); + // display.setTextSize(2); + // display.println(F("WHERE YOU ARE")); +} + +void loop() { + if( (textIdx > 9) && (textIdx <= 12) ) { + draw_moire(); + } else { + draw_starfield(); + } + draw_text1(); + + // draw_moire(); + display.display(); +}