// Failed project
// --------------
// Status: I wanted to make an illusion
// of a rotating sphere.
// But that is not possible in this way.
// Maybe I will fix this project someday.
//
// Illusion.ino
//
// A visual illusion of a rotating circle.
//
// Version 1, 8 June 2025, by Koepel.
//
// Public Domain
//
// The number of pins is for the number of leds per row.
// There is no limit for the number of rows,
// but 5 is not enough and 10 seems to be too many.
#define NUM_PINS 20
#define NUM_ROWS 8
const int pins[NUM_PINS] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,A0,A1,A2,A3,A4,A5};
int index = 0;
int direction = 1;
int prevIndex = 0;
void setup()
{
for(int i=0; i<NUM_PINS; i++)
pinMode(pins[i],OUTPUT);
// Since pin 0 and 1 are also used,
// the animation does not run well
// when generating the diagram.
//GenerateDiagram();
}
void loop()
{
// The most important part is how
// all the leds are connected.
float rad = float(index)/float(NUM_PINS-1) * 2 * M_PI;
float delay1 = 150;
// Turn off the previous led in all rows
digitalWrite(pins[prevIndex],LOW);
// Turn on the new led in all rows.
digitalWrite(pins[index],HIGH);
delay((unsigned long)delay1);
prevIndex = index;
index += direction;
if(index == (NUM_PINS-1) || index == 0)
direction = -direction;
}
// The function GenerateDiagram() can be used to generate
// the complete diagram.json file for Wokwi.
// To use it, call it from the setup() function, and the
// serial output can be copied into the diagram.json file.
void GenerateDiagram()
{
// Design constants.
float radius = 500; // the radius of the full circle
float distance = radius * 2.0 / float(NUM_PINS); // distance between leds
Serial.begin(115200);
Serial.print( "{\n");
Serial.print( " \"version\": 1,\n");
Serial.print( " \"author\": \"Generated\",\n");
Serial.print( " \"editor\": \"wokwi\",\n");
Serial.print( " \"parts\": [\n");
Serial.print( " {\n");
Serial.print( " \"type\": \"wokwi-arduino-uno\",\n");
Serial.print( " \"id\": \"uno\",\n");
Serial.print( " \"top\": 300,\n");
Serial.print( " \"left\": 400,\n");
Serial.print( " \"attrs\": {}\n");
Serial.print( " },\n");
int i = 0;
for(int row=0; row<NUM_ROWS; row++)
{
float rad = M_PI * float(row) / float(NUM_ROWS);
for(int led=0; led<NUM_PINS; led++)
{
float l = float(led) - float(NUM_PINS-1)/2.0;
float left = l*distance*cos(rad);
float top = l*distance*sin(rad);
Serial.print( " {\n");
Serial.print( " \"type\": \"wokwi-led\",\n");
Serial.print( " \"id\": \"led");
Serial.print( i);
Serial.print( "\",\n");
Serial.print( " \"top\": ");
Serial.print( top);
Serial.print( ",\n");
Serial.print( " \"left\": ");
Serial.print( left);
Serial.print( ",\n");
Serial.print( " \"attrs\": { \"color\": \"Red\" }\n");
Serial.print( " }");
if( i < (NUM_ROWS*NUM_PINS)-1)
Serial.print( ",");
Serial.print( "\n");
i++;
}
}
Serial.print( " ],\n");
Serial.print( " \"connections\": [\n");
i=0;
for(int row=0; row<NUM_ROWS; row++)
{
for(int led=0; led<NUM_PINS; led++)
{
// 'j' should be calculated in a different way.
int j = (row + led)%NUM_PINS;
Serial.print( " [ \"led");
Serial.print( i);
Serial.print( ":A\", \"uno:");
if(pins[j] < A0)
{
Serial.print(j);
}
else
{
Serial.print("A");
Serial.print(j-A0);
}
Serial.print( "\", \"\", []],\n");
Serial.print( " [ \"led");
Serial.print( i);
Serial.print( ":C\", \"uno:GND.2\", \"\", []]");
if( i < (NUM_ROWS*NUM_PINS)-1)
Serial.print( ",");
Serial.print("\n");
i++;
}
}
Serial.print( " ]\n");
Serial.print( "}\n");
}