Adaptive kinetic roof for solar tracking

concept


SOLCYCLE is an adaptive solar energy system that captures sunlight during the day and converts it into usable electricity for night-time illumination.
By tracking the Sun’s movement, the system optimises solar energy collection through its panels, stores the harvested energy in a battery, and uses it to power bulbs after sunset. Integrating solar tracking, energy harvesting, storage, and illumination into a unified system, the project explores a continuous day-to-night energy cycle, demonstrating how responsive technology can harness renewable energy efficiently to create a more sustainable future.
system Overview

Interactive Simulation : https://lively-hummingbird-929bf7.netlify.app
Schematic

Bill of Materials

Prototype
STAGE 01


STAGE 02


STAGE 03
Development of Light



Final Model



Modular Configurations


DAY / NIGHT


video
Arduino Control Code
#include <Servo.h>
Servo x;
Servo y;
int angleX = 90;
int angleY = 90;
int targetX = 90;
int targetY = 90;
unsigned long moveTime = 0;
unsigned long lightTime = 0;
const int northPin = A0;
const int southPin = A2;
const int eastPin = A3;
const int westPin = A6;
const int buttonPin = 7;
const int pirPin = 2;
const int leds[] = {8, 9, 10, 11, 12, 13};
bool nightMode = false;
int buttonState = HIGH;
int lastButtonReading = HIGH;
unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = 50;
const unsigned long pirFilterTime = 500;
int lastPirReading = LOW;
int stablePirState = LOW;
unsigned long lastPirChangeTime = 0;
const unsigned long lightHoldTime = 3000;
unsigned long lastMotionTime = 0;
bool motionDetected = false;
int previousPir = -1;
bool previousLedState = false;
unsigned long pirPrintTime = 0;
void setup() {
Serial.begin(9600);
x.attach(5);
y.attach(3);
x.write(90);
y.write(90);
pinMode(buttonPin, INPUT_PULLUP);
pinMode(pirPin, INPUT);
for (int i = 0; i < 6; i++) {
pinMode(leds[i], OUTPUT);
digitalWrite(leds[i], LOW);
}
Serial.println(“SYSTEM READY”);
Serial.println(“MODE: DAY”);
}
void loop() {
int reading = digitalRead(buttonPin);
if (reading != lastButtonReading) {
lastDebounceTime = millis();
}
if (millis() – lastDebounceTime > debounceDelay) {
if (reading != buttonState) {
buttonState = reading;
if (buttonState == LOW) {
nightMode = !nightMode;
if (nightMode) {
targetX = angleX;
targetY = angleY;
motionDetected = false;
lastMotionTime = 0;
lastPirReading = LOW;
stablePirState = LOW;
lastPirChangeTime = millis();
previousPir = -1;
previousLedState = false;
Serial.println(“MODE: NIGHT”);
} else {
for (int i = 0; i < 6; i++) {
digitalWrite(leds[i], LOW);
}
previousLedState = false;
Serial.println(“MODE: DAY”);
}
}
}
}
lastButtonReading = reading;
if (!nightMode) {
if (millis() – lightTime >= 200) {
lightTime = millis();
int north = analogRead(northPin);
int south = analogRead(southPin);
int east = analogRead(eastPin);
int west = analogRead(westPin);
targetX = 90;
targetY = 90;
if (east > 750) {
targetX = 135;
}
else if (south > 750) {
targetX = 45;
}
if (north > 750 && north > west + 150) {
targetY = 135;
}
else if (west > 750 && west > north + 150) {
targetY = 45;
}
}
if (millis() – moveTime >= 40) {
moveTime = millis();
if (angleX < targetX) angleX++;
else if (angleX > targetX) angleX–;
if (angleY < targetY) angleY++;
else if (angleY > targetY) angleY–;
x.write(angleX);
y.write(angleY);
}
for (int i = 0; i < 6; i++) {
digitalWrite(leds[i], LOW);
}
} else {
int pirReading = digitalRead(pirPin);
if (pirReading != lastPirReading) {
lastPirChangeTime = millis();
}
if (millis() – lastPirChangeTime >= pirFilterTime) {
stablePirState = pirReading;
}
lastPirReading = pirReading;
bool motion = (stablePirState == HIGH);
if (motion) {
lastMotionTime = millis();
motionDetected = true;
}
bool lightsOn =
motion ||
(motionDetected &&
millis() – lastMotionTime < lightHoldTime);
for (int i = 0; i < 6; i++) {
digitalWrite(leds[i], lightsOn ? HIGH : LOW);
}
if (stablePirState != previousPir) {
Serial.print(“PIR CHANGED: “);
Serial.println(stablePirState);
previousPir = stablePirState;
}
if (millis() – pirPrintTime >= 1000) {
pirPrintTime = millis();
Serial.print(“PIR RAW = “);
Serial.print(pirReading);
Serial.print(” | FILTERED = “);
Serial.println(stablePirState);
}
if (lightsOn != previousLedState) {
Serial.println(lightsOn ? “LEDS: ON” : “LEDS: OFF”);
previousLedState = lightsOn;
}
}
}