currently happily under construction :)

low power digital artworks

sun powered growth simulation

This prototype migh work in the following scenario : As soon as enough sunlight powers up the harvesting rig with the ESP onboard – a partial update will be drawn to the e-paper display. With light intensity and light temperature over time, the visuals will change significantly and produce always unique visuals on update.

The following sketches are done in a PROCESSING simulation setup.


// GxEPD_MinimumExample by Jean-Marc Zingg
// PINS ON ESP32
// BUSY -> 4, RST -> 16, DC -> 17, CS -> SS(5), CLK -> SCK(18), DIN -> MOSI(23), GND -> GND, 3.3V -> 3.3V
 
#include <GxEPD.h>

#include <FastLED.h>

long tick = 0;
long max_tick = 100;

long cts = 10;
long ct = 0;
 
// select the display class to use, only one, copy from GxEPD_Example
 #include <GxGDEW042T2/GxGDEW042T2.h>      // 4.2" b/w
 
 
#include <GxIO/GxIO_SPI/GxIO_SPI.h>
#include <GxIO/GxIO.h>
 
GxIO_Class io(SPI, /*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16); // arbitrary selection of 17, 16
GxEPD_Class display(io, /*RST=*/ 16, /*BUSY=*/ 4); // arbitrary selection of (16), 4

uint16_t rx = 0;
uint16_t ry = 0;
 
int width = 300;
int height = 400;
 
void setup()
{
 
  Serial.begin(9600);
  display.init();
   display.eraseDisplay();
   display.fillScreen(GxEPD_WHITE);
   display.setRotation(1);
   display.update();
   drawNoise();

}

void loop() {

}


int gridsize = 2;

void drawNoise(){
  
    // go thu all gridpoints
    for(int x=0;x<150 ;x+= gridsize){
      for(int y=0;y<400  ;y+= gridsize){ 
        
    // do some noise fake growth magic here for now
     float n =  (inoise8(x*12.8,y*12.8,millis()*.001)*0.004) -.5;

      // add some osciallation here
      n = sin(n*8);

      drawBlock(x,y,gridsize,gridsize,n);
  }}

 display.update();
}


void drawBlock(int ax,int ay,int w, int h,float type){
 
    if(type>0){
        display.fillRect(ax,ay,w,h, GxEPD_BLACK);
        display.fillRect(width-ax-w,ay,w,h, GxEPD_BLACK);

       // if mirrored y
     // display.fillRect(ax,height-ay-h,w,h, GxEPD_BLACK);
      //display.fillRect(width-ax-w,height-ay-h,w,h, GxEPD_BLACK);
    }else{
       display.fillRect(ax,ay,w,h, GxEPD_WHITE);
       display.fillRect(width-ax-w,ay,w,h, GxEPD_WHITE);

        // if mirrored y
        //  display.fillRect(ax,height-ay-h,w,h, GxEPD_WHITE);
      //  display.fillRect(width-ax-w,height-ay-h,w,h, GxEPD_WHITE);
     }
    
}

int gridsize = 2;

void setup(){
  size(300,400);
  background(244);
}

void draw(){
  
  // make a fast simulation loop
 for(int i=0;i<40;i++){ 
   
    // pick random point in grid 
    int x = (int)random(width/gridsize/2+1);
    int y = (int)random(height/gridsize/2+1);
    
    // do some noise fake growth magic here for now
     float n = noise(x*.08,y*.08,millis()*.0001)-.5;
     n = sin(n*8);
     n += sin(millis()*.01 + x*.01+y*.04)*.1;
     
     drawBlock(x*gridsize,y*gridsize,gridsize,gridsize,n);
  }
}

void drawBlock(int ax,int ay,int w, int h,float type){

  if(type>0){fill(255);}else{fill(0);}
  
    //fill basic area
    noStroke();
    rect(ax,ay,w,h);
    rect(width-ax-w,ay,w,h);
    
    rect(ax,height-ay-h,w,h);
    rect(width-ax-w,height-ay-h,w,h);

}

needs the newer GxEPD Lib installed for arduino

see references here:
https://learn.adafruit.com/adafruit-gfx-graphics-library/graphics-primitives

// GxEPD_MinimumExample by Jean-Marc Zingg
// PINS ON ESP32
// BUSY -> 4, RST -> 16, DC -> 17, CS -> SS(5), CLK -> SCK(18), DIN -> MOSI(23), GND -> GND, 3.3V -> 3.3V

#include <GxEPD.h>

// select the display class to use, only one, copy from GxEPD_Example
 #include <GxGDEW042T2/GxGDEW042T2.h>      // 4.2" b/w

#include <GxIO/GxIO_SPI/GxIO_SPI.h>
#include <GxIO/GxIO.h>

GxIO_Class io(SPI, /*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16); // arbitrary selection of 17, 16
GxEPD_Class display(io, /*RST=*/ 16, /*BUSY=*/ 4); // arbitrary selection of (16), 4

void setup()
{
  display.init();
  display.eraseDisplay();
  // comment out next line to have no or minimal Adafruit_GFX code
  //display.drawPaged(drawHelloWorld); // version for AVR using paged drawing, works also on other processors
  display.drawPaged(drawGEN);

}

void drawHelloWorld()
{
  display.setTextColor(GxEPD_BLACK);
  display.print("TURBOFLIP is the Greatest.");
}


void drawGEN(){

  for(int x=0;x<400;x++){

    for(int y=0;y<150;y++){

       // float n = random(10) -5;
       float n = sin( x*.1+ y*.2)*10;
     n /= sin( x*.3 +y*.3 ) ;
      
      n /= sin( x*.2 +y*.1) ;
      
      n+= (random(10)-5)*.1;

        if(n>0){
    
            display.drawPixel(x,y,GxEPD_BLACK);
            display.drawPixel(x,299-y,GxEPD_BLACK);
        }else{
            //display.drawPixel(x,y,GxEPD_GREY);
         }
   }

   }

  }


void loop() {};

SIMULATOR

Deploying for the ESP32/E-paper is taking a lot of compling time, so it makes sense to work in a simulation environment. For obvious sharing reasons, p5.js is not the best, but most agile solution for this. Here you go:

function setup() {
  createCanvas(400, 300);
  noLoop();
}

function draw() {
  background(255);
  
  for(let x=0;x<400;x++){

    for(let y=0;y<150;y++){
    
      let n = sin( x*.1 +  y*.2) ;
      
      n /= sin( x*.3 +y*.3 ) ;
      
      n /= sin( x*.2 +y*.1) ;
      
      n+= (random(10)-5)*.1;  
    
      
       if(n>0){
         noStroke();
         fill(255);
         rect(x,y,1,1);
         rect(x,299-y,1,1);
         
       }else{
         
          noStroke();
         fill(0);
         rect(x,y,1,1);
         rect(x,299-y,1,1);
         
         
       }
      
    }
  }  
}