|
arduino IDEArduino
|
|
|
fusion360 |
|
|
OrCad Cadance |
WALKPi PCB Version
Greetings everyone and welcome back, This is the WalkPi, a homebrew audio player that plays music from an SD card. It is made out of a Raspberry Pi Pico 2 and a DF Mini Player.
Remember the Walkman? The phrase "walkpi" is a pun.
The WalkPi gets its name from the fact that it is just a walkman that is powered by a Raspberry Pi and is a little less sophisticated.
This project is a follow-up to the walkpi project I created earlier using a breadboard.
We added an SSD1306 OLED display and a few buttons that allow the user to use the WalkPi. The buttons let the user choose songs from the menu on the OLED screen, adjust the volume, choose a song, and switch the device on or off.
Let us get started with the construction since this article is about the entire process of constructing this basic setup, including the code and other specifics.
Materials Required
These were the materials used in this project:
- Custom PCB
- Raspberry Pi PICO 2
- IP5306 Power Management IC
- 10uF capacitors, 1206 Package
- 1uH Inductor
- Vertical Push Button
- SSD1306 OLED
- DF MINI Player
- SD Card with MP3 Songs
- WS2812B
- Type C port
- Battery 3.7V, 600mAh Cell
- Slide Switch
- Audio Jack
- Speaker
Breadboard Setup
We already designed the WalkPi's Basic Breadboard configuration.
The star of this project is the DFPlayer Mini, which is a mini MP3 Player Module that is based around a 24-bit DAC IC along with an onboard SD Card reader that fully supports the FAT16 and FAT32 file systems.
The project's brain, the Raspberry Pi Pico, is connected to the DF Mini Player, a small, low-cost MP3 module with a simple output straight to the speaker.
We included the SSD1306 OLED screen to show the song list, volume settings, and other information in addition to song names.
Here's the brief article about how we setup the breadboard setup:
https://www.hackster.io/Arnov_Sharma_makes/walkpi-breadboard-version-317c16
In order to simplify the design process for subsequent iterations, we evaluated all of the device's internal workings in the breadboard version, which was the first step of testing this project before proceeding to the PCB design phase.
PCB Design
The project's PCB design begins with the creation of a schematic, which is separated into seven circuit parts: the Raspberry Pi Pico 2, the WS2812B LED array, the RIGHT Angle Switch Array, the OLED screen, the DFPLAYER, the Audio Jack-Speaker Switch, and the Power Managamenet Setup.
The IP5306 Power Management Board Setup is the first thing we will go over. Its basic configuration includes the IP5306 IC itself, along with decoupling capacitors on the input, output, and battery sides, LEDs for the battery fuel level, a Type C port for input that will be used to charge the cell, and an SMD inductor that will increase the 3.7V cell's output to a constant 5V.
Next comes the Pico 2 Setup, which connects to the OLED display's I2C ports as well as the DF Mini Player's TX and RX pins. To function, the DF Player, the OLED screen, and the PICO's VCC require 5V from the power management board setup.
We added an interesting feature to this device: the DF Mini player's output is connected to the central terminal of a Slide DPDT Slide switch, which is also connected to an audio jack and speaker. The sliding switch allows the user to play music via either the audio jack or the speaker.
An array of WS2812B LEDs was also added; four of the LEDs were connected in their standard configuration, with the first LED's Din connected to PICO's GPIO0. The first LED's dout is connected to the second's din, the second's dout is connected to the third's din, and so on, up to the fourth LED.
Finally, we employed a total of six buttons in this project, five of which are connected to PICO and will be used for up-and-down navigation, music selection, and volume up-and-down control. In order to turn the device on and off, the sixth button is connected to the power management setup.
Following the creation of the schematic, we also created a mockup CAD file for the board, in which we modeled every component that we would need to install in the circuit, including the PCB, vertical push buttons, Raspberry Pi Pico, DF Mini Player, slide switch, and Type C port.
We create the board layout and arrange all the parts to complete the circle using the dimensions obtained from the Cad file.
PCBWAY Service
Following the completion of the board design, we ordered PCBs in white solder masks with black silkscreen and submitted the PCB's Gerber data on the PCBWAY quote page.
PCBs were received within a week, and the PCB quality was outstanding. Here, we added a few design elements on the board's silkscreen layer to increase the aesthetic appeal of the project. PCBWAY made the custom layer properly, which shows their great PCB manufacturing capabilities.
Also, PCBWay is hosting its 7th Project Design Contest, a global competition that invites electronics enthusiasts, engineers, and makers to showcase their innovative projects. The contest provides a platform for participants to share their creativity and technical expertise with the broader community.
This year’s competition includes three major categories: electronic project, mechanical project and SMT 32 project
With prizes awarded for the most exceptional designs, the contest aims to inspire and support innovation, making it an exciting opportunity for both professionals and hobbyists to gain recognition and connect with like-minded creators.
We also used PCBWAY's Giftshop for sourcing the Pico 2, DF Mini Player, and the SSD1306 Display.
PCBWAY gift shop is an online marketplace where you can get a variety of electronics modules and boards for their genuine price
You guys can check out PCBWAY if you want great PCB service at an affordable rate.
PCB Assembly Process
- Applying solder paste to each component pad is the initial step in the circuit-building procedure. In this case, a solder paste dispenser synringe with 63/37 Sn/Pb solder paste is used.
- Next, we pick and place each component in its proper place.
- After that, we lift the circuit and place it on the reflow hotplate, which increases the PCB's temperature to the point where solder paste melts and all SMD components attach to their pads.
- Then, using a soldering iron, we solder all of the component leads in their proper locations after placing all of the through-hole components, such as the horizontal push buttons, Type C port, and CON2 JST connectors.
Adding Modules onto the Circuit (OLED, PICO, DF Player)
We now set up every module, including the DF Mini Player, Pico 2, and SSD1306 Display, in its proper location. The SSD1306 Display is first added to the circuit from the top side, and its pad is subsequently soldered from the bottom side.
- Using a soldering iron, the terminals of the DF Mini Player are soldered from the top side of the board to the bottom side of the circuit.
- We also included two JST connectors, which will be used to connect the battery and speaker.
- In its place, we finally installed the Raspbery Pi Pico 2. We soldered the Pico directly onto the circuit using its castellated pads.
- The circuit assembly is now complete.
CODE
Next is the project's code, which is large but takes a very straightforward approach.
#include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #include <SoftwareSerial.h> #include <DFRobotDFPlayerMini.h> #include <Adafruit_NeoPixel.h> #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define SSD1306_I2C_ADDRESS 0x3C #define LED_PIN 0 #define NUM_LEDS 4 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT); Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800); // DFPlayer connections SoftwareSerial mySerial(9, 8); // RX (Pico) to TX (DFPlayer), TX (Pico) to RX (DFPlayer) DFRobotDFPlayerMini myDFPlayer; // Button pins const int buttonPinNext = 27; // Next song button const int buttonPinPrev = 26; // Previous song button const int buttonPinSelect = 12; // Select song button const int buttonPinVolumeUp = 13; // Volume up button const int buttonPinVolumeDown = 14; // Volume down button String songNames[50]; // Placeholder for song names from the SD card int totalSongs = 0; int currentSongIndex = 0; // Start with the first song int volume = 10; // Initial volume level (0-30) unsigned long lastDebounceTime = 0; // For navigation button debounce unsigned long debounceDelay = 250; // Debounce delay in milliseconds for navigation buttons bool isPlaying = false; // Function declarations void listSongsFromSD(); void displayVolume(); void playVisualizer(); void displaySongInfo(); void setLEDsRed(); void setLEDsPurpleAndBlue(); void setup() { // Initialize Serial and the display Serial.begin(9600); mySerial.begin(9600); display.begin(SSD1306_SWITCHCAPVCC, SSD1306_I2C_ADDRESS); display.clearDisplay(); // Initialize DFPlayer display.setTextSize(1); display.setTextColor(SSD1306_WHITE); display.setCursor(0, 0); display.println("Init DFPlayer..."); display.display(); delay(1000); // Pause for observation if (!myDFPlayer.begin(mySerial)) { display.setCursor(0, 10); display.println("DFPlayer Init Failed!"); display.display(); while (true); // Halt further execution } myDFPlayer.volume(10); // Set initial volume display.setCursor(0, 20); display.println("DFPlayer Initialized"); display.display(); delay(1000); // Pause for observation // Set up button pins pinMode(buttonPinNext, INPUT_PULLUP); pinMode(buttonPinPrev, INPUT_PULLUP); pinMode(buttonPinSelect, INPUT_PULLUP); pinMode(buttonPinVolumeUp, INPUT_PULLUP); pinMode(buttonPinVolumeDown, INPUT_PULLUP); // Initialize the LED strip strip.begin(); strip.show(); // Initialize all pixels to 'off' setLEDsRed(); // Set initial state to red // Display welcome message display.clearDisplay(); display.setTextSize(2); display.setTextColor(SSD1306_WHITE); display.setCursor(0, 0); display.drawRect(0, 0, 128, 64, SSD1306_WHITE); // Frame box display.setCursor(18, 25); display.println("Welcome!"); display.display(); delay(2000); display.clearDisplay(); display.display(); // Read and display song names from SD card listSongsFromSD(); } void loop() { unsigned long currentMillis = millis(); // Display song menu display.clearDisplay(); display.setTextSize(1); display.setTextColor(SSD1306_WHITE); display.setCursor(0, 0); display.drawRect(0, 0, 128, 64, SSD1306_WHITE); // Frame box display.drawLine(0, 10, 128, 10, SSD1306_WHITE); // Line under the title display.setCursor(5, 0); display.print("Select Song:"); // Display the list of songs with an arrow display.setTextColor(SSD1306_WHITE); display.setCursor(5, 13 + currentSongIndex * 10); display.print(">"); for (int i = 0; i < totalSongs; i++) { display.setCursor(15, 13 + i * 10); display.print(songNames[i]); } // Display current volume display.setTextColor(SSD1306_WHITE); display.setCursor(5, 55); display.print("Volume: "); display.print(volume); display.display(); // Check for button presses with debounce for navigation buttons if ((currentMillis - lastDebounceTime) > debounceDelay) { if (digitalRead(buttonPinNext) == LOW) { currentSongIndex = (currentSongIndex + 1) % totalSongs; // Loop back to start lastDebounceTime = currentMillis; } if (digitalRead(buttonPinPrev) == LOW) { currentSongIndex = (currentSongIndex - 1 + totalSongs) % totalSongs; // Loop to end lastDebounceTime = currentMillis; } if (digitalRead(buttonPinSelect) == LOW) { myDFPlayer.play(currentSongIndex + 1); // Play selected song isPlaying = true; lastDebounceTime = currentMillis; playVisualizer(); } } // Check for volume button presses separately with a shorter debounce delay if (digitalRead(buttonPinVolumeUp) == LOW) { if ((currentMillis - lastDebounceTime) > 50) { // Shorter debounce delay for volume buttons if (volume < 30) { // Max volume is 30 volume++; myDFPlayer.volume(volume); // Update volume on DFPlayer displayVolume(); } lastDebounceTime = currentMillis; } } if (digitalRead(buttonPinVolumeDown) == LOW) { if ((currentMillis - lastDebounceTime) > 50) { // Shorter debounce delay for volume buttons if (volume > 0) { // Min volume is 0 volume--; myDFPlayer.volume(volume); // Update volume on DFPlayer displayVolume(); } lastDebounceTime = currentMillis; } } // Automatically play the next song if the current one ends if (myDFPlayer.available()) { if (myDFPlayer.readType() == DFPlayerPlayFinished) { currentSongIndex = (currentSongIndex + 1) % totalSongs; myDFPlayer.play(currentSongIndex + 1); displaySongInfo(); } } // Handle LED colors based on whether a song is playing if (isPlaying) { setLEDsPurpleAndBlue(); } else { setLEDsRed(); } } // Function to list songs from SD card (Mock implementation) void listSongsFromSD() { // Placeholder implementation to list songs songNames[0] = "Song 1"; songNames[1] = "Song 2"; songNames[2] = "Song 3"; totalSongs = 3; } // Function to display volume change void displayVolume() { display.clearDisplay(); display.setTextSize(2); display.setTextColor(SSD1306_WHITE); display.setCursor(0, 0); display.drawRect(0, 0, 128, 64, SSD1306_WHITE); // Frame box display.setCursor(35, 10); // Adjusted position display.print("Volume"); display.setCursor(55, 35); // Position below the word display.print(volume); display.display(); delay(1000); // Show volume for 1 second } // Simple visualizer function void playVisualizer() { // Basic visualization while playing display.clearDisplay(); display.setTextSize(2); display.setTextColor(SSD1306_WHITE); display.setCursor(0, 0); display.drawRect(0, 0, 128, 64, SSD1306_WHITE); // Frame box display.setCursor(10, 20); display.print("Now Playing:"); display.setTextSize(1); display.setCursor(10, 40); display.print(songNames[currentSongIndex]); display.display(); // Visualizer loop for (int i = 0; i < 20; i++) { display.fillRect(i * 6, 50, 5, random(10, 30), SSD1306_WHITE); display.display(); delay(50); display.fillRect(i * 6, 50, 5, random(10, 30), SSD1306_BLACK); } } // Function to display current song info void displaySongInfo() { display.clearDisplay(); display.setTextSize(2); display.setTextColor(SSD1306_WHITE); display.setCursor(0, 0); display.drawRect(0, 0, 128, 64, SSD1306_WHITE); // Frame box display.setCursor(10, 20); display.print("Playing:"); display.setTextSize(1); display.setCursor(10, 40); display.print(songNames[currentSongIndex]); display.display(); } // Functions to control the LED strip void setLEDsRed() { for (int i = 0; i < NUM_LEDS; i++) { strip.setPixelColor(i, strip.Color(255, 0, 0)); // Red color } strip.show(); } void setLEDsPurpleAndBlue() { for (int i = 0; i < NUM_LEDS; i++) { strip.setPixelColor(i, strip.Color(128, 0, 128)); // Purple color } strip.show(); delay(500); for (int i = 0; i < NUM_LEDS; i++) { strip.setPixelColor(i, strip.Color(0, 0, 255)); // Blue color } strip.show(); delay(500); }
The constants that specify the display's dimensions and I2C address, as well as the LED pin and number of LEDs, are all included in the first section of this code, which also includes all the libraries you must right away install. Additionally, it includes objects such as the NeoPixel strip and the OLED display, respectively.
The first section also assigns button pins, stores song names in an array called songNames, and uses certain variables to monitor the number of songs, the song index that is currently selected, and the volume level.
The OLED display and the DF Mini player are initiated by the Section's Setup Function, which also includes a tiny part that checks to see if the DF player's initialization failed or was functioning well.
Along with the WS2812B LED, which is configured to glow red, this function also includes buttons that configure each button as an input. We also added a welcome message that will appear each time the device starts on.
The third section, or the Loop Function, is made up of seven parts, including the Current Time, which keeps track of time in microseconds and manages button debounding, Song Menu Structure, Song List, and volume display. The navigation button functions by detecting if buttons are being pressed and updating the song index accordingly. The volume buttons perform the same function as the song index but also control the LED and play the next song segment.
Before using this sketch, make sure you install the libraries listed below.
#include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #include <SoftwareSerial.h> #include <DFRobotDFPlayerMini.h> #include <Adafruit_NeoPixel.h>
Power Source
We are using a 14500 3.7V 600mAH Li-ion battery as the power supply, which is a smaller formfactored cell than the 18650 cells that are often utilized. In order to give the lithium battery both low-cut and high-cut functionality, we added a wire harness and a PCM.
- The JST connector on the wireharness links to the battery connector on the circuit.
- The device turns on when the Power button is pressed, and the four side LEDs that indicate the battery's current fuel level glow.
- The device can be turned off by double-pressing the Power Button.
- Because of its small capacity, the lithium cell can be charged using the Type C connector in a maximum of two hours using a 5V/2A charger.
Result
After the gadget has been set up and updated with the code and power, it turns on when we push the power button. The RGB LEDs illuminate red when the device first powers on, and a welcome message shows on the screen.
The song we wish to play is selected using the navigation buttons, and the song is picked using the select button. When the song has been selected and begins to play, we are presented with a Playing Now splash screen.
The slide switch allows the user to choose whether to connect earphones or play music on the built-in speaker.
RED RGB LEDs turn purple while the song is playing, then change color to blue and back to purple again. This pattern repeats itself.
As of right now, we have only finished the main board for this project. We will be adding a battery layer to the back side of the device's along with a frontside enclosure and making a few small code changes because, as of right now, the device only lists the song names SONG 1, 2, and 3 as specified in the code. However, it will be changed so that it will display the names of the songs that have been added to the SD card and appear directly on the OLED screen.
In addition, we appreciate PCBWAY's support of this project. Visit them for a variety of PCB-related services, such as stencil and PCB assembly services, as well as 3D printing services.
Stay tuned for the upcoming update.
Thanks for reaching this far, and I will be back with a new project pretty soon.
Peace.
WALKPi PCB Version
*PCBWay community is a sharing platform. We are not responsible for any design issues and parameter issues (board thickness, surface finish, etc.) you choose.
- Comments(0)
- Likes(0)
- 0 USER VOTES
- YOUR VOTE 0.00 0.00
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
More by Arnov Arnov sharma
- WALKPi PCB Version Greetings everyone and welcome back, This is the WalkPi, a homebrew audio player that plays music fr...
- Delete Button XL Greetings everyone and welcome back, and here's something fun and useful.In essence, the Delete Butt...
- Arduino Retro Game Controller Greetings everyone and welcome back. Here's something fun.The Arduino Retro Game Controller was buil...
- Super Power Buck Converter Greetings everyone and welcome back!Here's something powerful, The SUPER POWER BUCK CONVERTER BOARD ...
- Pocket Temp Meter Greetings and welcome back.So here's something portable and useful: the Pocket TEMP Meter project.As...
- Pico Powered DC Fan Driver Hello everyone and welcome back.So here's something cool: a 5V to 12V DC motor driver based around a...
- Mini Solar Light Project with a Twist Greetings.This is the Cube Light, a Small and compact cube-shaped emergency solar light that boasts ...
- PALPi V5 Handheld Retro Game Console Hey, Guys what's up?So this is PALPi which is a Raspberry Pi Zero W Based Handheld Retro Game Consol...
- DIY Thermometer with TTGO T Display and DS18B20 Greetings.So this is the DIY Thermometer made entirely from scratch using a TTGO T display board and...
- Motion Trigger Circuit with and without Microcontroller GreetingsHere's a tutorial on how to use an HC-SR505 PIR Module with and without a microcontroller t...
- Motor Driver Board Atmega328PU and HC01 Hey, what's up folks here's something super cool and useful if you're making a basic Robot Setup, A ...
- Power Block Hey Everyone what's up!So this is Power block, a DIY UPS that can be used to power a bunch of 5V Ope...
- Goku PCB Badge V2 Hey everyone what's up!So here's something SUPER cool, A PCB Board themed after Goku from Dragon Bal...
- RGB Mixinator V2 Hey Everyone how you doin!So here's a fun little project that utilizes an Arduino Nano, THE MIXINATO...
- Gengar PCB Art Hey guys and how you doing!So this is the GENGAR PCB Badge or a Blinky Board which is based around 5...
- R2D2 Mini Edition So here's something special, A Mini R2D2 PCB that speaks ASTROMECH.Astromech is a fictional language...
- C-3PO Blinky Board Hey guys and how you doing!So this is the C3P0 PCB Badge or a Blinky Board which is based around 555...
- WALKPi Breadboard Version Greetings everyone and welcome back, Here's something loud and musical.Similar to a traditional walk...
-
Box & Bolt, 3D Printed Cardboard Crafting Tools
29 0 1 -
-
A DIY Soldering Station Perfect for Learning (Floppy Soldering Station 3.0)
85 0 1 -
Custom Mechanic Keyboard - STM32
130 0 1 -
Radio Frequency Emitter and Reciever Remote with Attiny
97 3 1 -
-
-
Air Quality Monitor (for CO2, TVOC, Temperature and Humidity) With RP2040
139 0 0