Photon Drive — Intelligent IoT-Based Solar Car

by Ameya Angadi in Circuits > Robots

219 Views, 2 Favorites, 0 Comments

Photon Drive — Intelligent IoT-Based Solar Car

Photon Drive Cover Image.png

Photon Drive is a compact, IoT-enabled, solar-powered hybrid vehicle designed for clean, efficient, and interactive mobility. Using Raspberry Pi Pico W, the project combines solar and battery charging, Bluetooth-based control, sleek aesthetics, and smart lighting — all inside a custom-designed laser-cut acrylic chassis.

Whether you're a hobbyist, student, or sustainability enthusiast, this project is a great hands-on way to explore embedded systems, electronics, 3D design, and open-source prototyping.

Supplies

  1. Raspberry Pi Pico W
  2. TB6612FNG Motor Driver
  3. Servo Motor (SG90)
  4. Gear Motor (x1)
  5. 3mm White LEDs (x2)
  6. 3mm Red LEDs (x6)
  7. 3.7V Li-ion Batteries (1000–2000mAh, x1)
  8. Switches, Connectors (JST Recommended)
  9. Solar Panel (6V, ~1W recommended for demo)
  10. Acrylic sheets for chassis (laser cut)
  11. Wires, Resistors (for LEDs)
  12. USB Type-C TP4056 charging module
  13. Screws, glue, tools
  14. JLCPCB Custom PCB

Design the PCB (JLCPCB)

PCB_Final.png
PCB_Schematics.png
20250606_135506.jpg

Design your custom PCB to simplify wiring between motor driver, Pico W, lights, and power.

📌 I used KiCAD for schematic and board layout, then ordered from JLCPCB - a reliable and affordable PCB manufacturer.

🔗 Link to avail special coupon worth up to $70 - https://jlcpcb.com/?from=Ameya


Download gerber files by clicking here

Assemble Breadboard (Optional)

Circuit Diagram.png

Note: If you prefer using a breadboard instead of a PCB, you can follow the shared circuit diagram and build the setup on a breadboard for prototyping.

Laser Cut the Chassis

Laser_Cut_Chassis.png

The car body was made from laser-cut acrylic sheets. The design was done in RDWorks software and cut using a laser cutting machine.

I went with a black semi-transparent acrylic sheet for the chassis, as I felt it would match the overall look of the car.

I have created extra copies for each part just so that they can be used to solve any mistakes/breakage.

Downloads

Assemble the Steering System

20250705_204550.jpg
20250705_212712.jpg
20250706_200204.jpg
Solar Car Steering Demo | Full Open Source Project in Description!

To assemble the front steering system of the car, follow these steps using the reference images above:

  1. Mount the Vertical Supports: Insert the two vertical pen refill rods through the designated slots in the chassis. These act as the main pivot axis for the front wheels.
  2. Fix with Visor Rings: Use small acrylic visor-like rings to hold the pen refill rods firmly in place, both above and below the chassis surface. These prevent unwanted movement while allowing smooth rotation. Apply super glue sparingly to lock them in place, ensuring the rods remain vertical and free to rotate if needed.
  3. Connect the Tie Rods: Use the custom laser-cut acrylic connectors to link the vertical rods on either side. This linkage helps synchronize the rotation of both wheel axles during steering. Again, use small drops of glue where necessary for firm, non-sloppy movement.
  4. Attach to Servo Motor: Connect the center of the tie rod or one of the vertical shafts to a servo shaft with a thin wire to allow free movement. This servo will rotate the linkage bar, effectively steering the wheels left and right.


Design Note: I’ll be honest — this steering system is far from perfect. While it does the job, it lacks the precision, geometry, and durability of a professional Ackermann or rack-and-pinion setup. The use of refill rods and acrylic loops was a quick, makeshift solution suited for prototyping.
💡 That said, this is an open-source hardware project! If you’re reading this and have a better idea (or design upgrade) for the steering system, I would be absolutely thrilled to feature your work and credit you as a contributor to the Photon Drive project.

Attach the BO Motor

20250708_202741.jpg

The output shaft of the BO Motor is quite short, which makes it difficult to mount the wheels securely. To overcome this, I extended the shaft using a sturdy pen refill. Simply cut a section of the refill with a diameter that fits snugly over the motor shaft.

You can slightly heat the refill plastic to make it pliable, then press it onto the motor shaft and mold the other end to fit the wheel’s hub. This ensures a firm grip and smooth rotation. Use a strong adhesive like super glue or hot glue for added strength.

This isn’t the most conventional method, but it’s a quick and reliable hack if you’re working with limited parts.

Assembling the PCB

20250717_184133.jpg
20250606_135402.jpg

To assemble the control PCB for the Photon Drive solar IoT car, begin by soldering all the THT (Through-Hole Technology) components onto the board.

  1. Use JST connectors for the headlight, backlight, left and right indicators, as well as for the battery connection. This allows easy plug-and-play functionality and quick replacement when needed.
  2. Solder four 220Ω resistors in series with each LED connection. If you find the brightness too low, you can replace these resistors with wires, but be careful not to overload the LEDs.
  3. I've used male headers for both the Raspberry Pi Pico W and the TB6612FNG motor driver, and the Servo making them removable and reusable for other future projects.
This is my first attempt at designing a PCB! While everything works correctly and looks quite professional, I welcome any feedback or improvements you might suggest in case there are technical mistakes I might've overlooked.

Upload Code to Pico W

Use Arduino IDE to upload the provided C++ code that controls:

  1. Bluetooth input
  2. Smart LED indicators
  3. Servo steering and movements
  4. Safety features like hazard lights

Make sure to install Earle Philhower's Pico core and required libraries. Follow this tutorial Getting Started with Raspberry Pi Pico in Arduino IDE

Code:

/*
* Project Name: Photon Drive – Intelligent IoT Based Solar Car
* Designed For: Raspberry Pi Pico W
*
* License: GPL3+
* This project is licensed under the GNU General Public License v3.0 or later.
* You are free to use, modify, and distribute this software under the terms
* of the GPL, as long as you preserve the original license and credit the original
* author. For more details, see <https://www.gnu.org/licenses/gpl-3.0.en.html>.
*
* Copyright (C) 2025 Ameya Angadi
*
* Code Created And Maintained By: Ameya Angadi
* Last Modified On: July 20, 2025
* Version: 1.0.0
*
*/


#include <SerialBT.h>
#include <Servo.h>


// ---------- Pin Configuration ----------
const int HeadLight = 0;
const int BrakeLight = 1;
const int LeftLight = 2;
const int RightLight = 3;


const int STBY = 17;
const int PWMA = 18;
const int AIN1 = 19;
const int AIN2 = 20;


const int SERVO_PIN = 9;


// ---------- Servo Angles ----------
// Change these values according to your needs
const int LeftServoAngle = 120;
const int RightServoAngle = 60;
const int CenterServoAngle = 90;

Servo Servo;


// ---------- Caution Light Blink Handling ----------
bool cautionBlinking = false;
bool cautionLightState = false;
unsigned long lastBlinkTime = 0;
const unsigned long blinkInterval = 400;


void setup() {
Serial.begin(115200);

SerialBT.setName("Photon Drive Car"); // Name of the bluetooth car
SerialBT.begin();

// Attach Servo
Servo.attach(SERVO_PIN, 500, 2500);
Servo.write(CenterServoAngle); // Set the servo to center position

// Initialize output pins
pinMode(HeadLight, OUTPUT);
pinMode(BrakeLight, OUTPUT);
pinMode(LeftLight, OUTPUT);
pinMode(RightLight, OUTPUT);

pinMode(AIN1, OUTPUT);
pinMode(AIN2, OUTPUT);
pinMode(PWMA, OUTPUT);
pinMode(STBY, OUTPUT);

digitalWrite(STBY, HIGH);
digitalWrite(LED_BUILTIN, HIGH); // Status LED to show that the car is turned on
}


void loop() {


// ---------- Bluetooth Input Handling ----------
while (SerialBT.available()) {
char input = char(SerialBT.read());

if (input == 'H') {
digitalWrite(HeadLight, HIGH);
}

else if (input == 'h') {
digitalWrite(HeadLight, LOW);
}

else if (input == 'F') {
moveForward();
}

else if (input == 'B') {
moveBackward();
}

else if (input == 'L') {
turnLeft();
}

else if (input == 'R') {
turnRight();
}

else if (input == '1') {
moveLeftForward();
}

else if (input == '2') {
moveRightForward();
}

else if (input == '3') {
moveLeftBackward();
}

else if (input == '4') {
moveRightBackward();
}

else if (input == 'S') {
stopCar();
}

else if (input == 'C') {
cautionBlinking = true;
}

else if (input == 'c') {
cautionBlinking = false;
digitalWrite(LeftLight, LOW);
digitalWrite(RightLight, LOW);
}
}


// ---------- Caution Blinking Logic ----------
if (cautionBlinking && millis() - lastBlinkTime >= blinkInterval) {
lastBlinkTime = millis();
cautionLightState = !cautionLightState;
digitalWrite(LeftLight, cautionLightState);
digitalWrite(RightLight, cautionLightState);
}
}


// ---------- Movement & Light Control Functions ----------


void moveForward() { // Function to move the car Forward
digitalWrite(AIN1, HIGH);
digitalWrite(AIN2, LOW);
analogWrite(PWMA, 200);

Servo.write(CenterServoAngle);
turnOffAllLights();
}

void moveBackward() { // Function to move the car Backward
digitalWrite(AIN1, LOW);
digitalWrite(AIN2, HIGH);
analogWrite(PWMA, 200);

Servo.write(CenterServoAngle);
digitalWrite(BrakeLight, HIGH);
digitalWrite(LeftLight, LOW);
digitalWrite(RightLight, LOW);
}

void turnLeft() { // Function to turn the car Left
digitalWrite(BrakeLight, LOW);
digitalWrite(LeftLight, HIGH);
digitalWrite(RightLight, LOW);
Servo.write(LeftServoAngle);
}

void turnRight() { // Function to turn the car Right
digitalWrite(BrakeLight, LOW);
digitalWrite(LeftLight, LOW);
digitalWrite(RightLight, HIGH);
Servo.write(RightServoAngle);
}

void moveLeftForward() { // Function to move the car Left-Forward
digitalWrite(AIN1, HIGH);
digitalWrite(AIN2, LOW);
analogWrite(PWMA, 150);

Servo.write(LeftServoAngle);
digitalWrite(LeftLight, HIGH);
digitalWrite(RightLight, LOW);
digitalWrite(BrakeLight, LOW);
}

void moveRightForward() { // Function to move the car Right-Forward
digitalWrite(AIN1, HIGH);
digitalWrite(AIN2, LOW);
analogWrite(PWMA, 150);

Servo.write(RightServoAngle);
digitalWrite(LeftLight, LOW);
digitalWrite(RightLight, HIGH);
digitalWrite(BrakeLight, LOW);
}

void moveLeftBackward() { // Function to move the car Left-Backward
digitalWrite(AIN1, LOW);
digitalWrite(AIN2, HIGH);
analogWrite(PWMA, 150);

Servo.write(LeftServoAngle);
digitalWrite(LeftLight, HIGH);
digitalWrite(RightLight, LOW);
digitalWrite(BrakeLight, HIGH);
}

void moveRightBackward() { // Function to move the car Right-Backward
digitalWrite(AIN1, LOW);
digitalWrite(AIN2, HIGH);
analogWrite(PWMA, 150);

Servo.write(RightServoAngle);
digitalWrite(LeftLight, LOW);
digitalWrite(RightLight, HIGH);
digitalWrite(BrakeLight, HIGH);
}

void stopCar() { // Function to stop the car
digitalWrite(AIN1, LOW);
digitalWrite(AIN2, LOW);
analogWrite(PWMA, 0);

Servo.write(CenterServoAngle);
turnOffAllLights();
}

void turnOffAllLights() { // Function to turn off all the lights
digitalWrite(BrakeLight, LOW);
digitalWrite(LeftLight, LOW);
digitalWrite(RightLight, LOW);
}

Attach All the Parts to the Base

20250717_173130.jpg
20250714_134332.jpg
20250717_190116.jpg

Begin by securely fixing the PCB onto the acrylic base plate using double-sided tape, hot glue, or screws — whatever suits your design. Make sure all loose wires, the power switch, and connectors are neatly arranged and fixed down to avoid any movement during motion.

Next, prepare four vertical rod-like structures (I’ve used pen refills for this purpose). Attach these rods at the four corners — they will act as support pillars for the top layer of the car.

💡 Tip: Ensure the rods are of equal length and aligned properly so that the top layer sits level.

Attach the Top Cover

20250717_212943 (1).jpg
20250717_213014.jpg

On the top layer, mount the solar panel securely. Also, attach a toggle switch to control the connection from the solar panel. Pass the wires from the solar panel through the pre-cut hole and connect it to the input of the TP4056 charging module.

Power & Solar Integration

  1. Connect Li-ion battery to the output (battery) pins of the TP4056 module.
  2. Add solar panel input to the TP4056 input (make sure panel voltage matches specs).
  3. Include switch for toggling power.

Final Testing and Output

Screenshot_20250719_202517.jpg
Screenshot_20250719_202537.png
20250718_011515.jpg
20250720_002613.jpg

Once everything is assembled and connected, it’s time to test your Photon Drive – IoT Solar Car in action!

Use the Photon Link App to connect and control the app.

Download the Photon Link App by clicking here.

Watching your creation come to life is the most rewarding part — make sure everything works as expected and troubleshoot any loose connections or servo misalignment.

Watch the Build & Testing on YouTube

Photon Drive &ndash; IoT Solar-Powered Car | Smart Bluetooth Car | Raspberry Pi Pico W | JLCPCB

Check out my YouTube video, where I walk you through the entire build process — from assembling the chassis and wiring the electronics to testing the app-controlled steering and lighting system.


And don’t forget to like, comment, and subscribe if you enjoyed the project or found it helpful!

Conclusion

This project started as a small idea but grew into a working open-source hybrid solar-powered vehicle — designed, coded, assembled, and tested from scratch.

I hope this inspires you to tinker, build, and innovate in your own maker journey.


Huge thanks to JLCPCB for sponsoring this project’s PCB manufacturing and helping bring this open-source idea to life.

🔗 Link to avail special coupon pack worth $70 - https://jlcpcb.com/?from=Ameya


If you want to explore more, check out my profile for related projects, and don’t forget to follow me for updates on new tutorials and advanced projects!