Luis Rodil-Fernandez
2 years ago
commit
a4ea4795a0
5 changed files with 276 additions and 0 deletions
-
12README.md
-
39include/README
-
46lib/README
-
22platformio.ini
-
157src/main.cpp
@ -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 )) ------ -- - -------------- -- --- ---------------- -- --+ |
@ -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 |
@ -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 <Foo.h> |
|||
#include <Bar.h> |
|||
|
|||
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 |
@ -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 |
@ -0,0 +1,157 @@ |
|||
#include <Arduino.h>
|
|||
|
|||
#include <SPI.h>
|
|||
#include <Wire.h>
|
|||
#include <Adafruit_GFX.h>
|
|||
#include <Adafruit_SSD1306.h>
|
|||
|
|||
#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(); |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue