Enchanted Weather Clock using W5300 and Raspberry Pi Pico
W5300 + RP2040 Based weather clock that uses NTP server for time, realtime/predicted weather displayed on clock using led and speaker
Software Apps and online services
Objectives
1 Development of RPi Pico Compatible W5300 Arduino Library - Done
2 Replicate my WizFi360 Project entry 'Enchanted Weather Clock' using W5300 - Done
Project Video
Features
Update Weather every 15 minutes using API of openweathermap.org
sync with network time every 1 hour using API of worldtimeapi.org
Timer interrupt used so time keeping and Neopixel update runs in background and no other task interrupt it so no need to use dedicated RTC Hardware for time keeping
button press can play current time / weather when required
Automatically play weather condition every 15 minutes
Automatically play time on speaker every hour'
Play time in 24 hour time format on Speaker default press both button at same time makes it 12 hour format
As flexible NEOPIXEL LED Strip used to display enchanted time, It can be fixed on wall in any shape Circle, oval, square, heart shape etc
By using neopixel led with different LED distance, smaller to very bigger clock can be made
As this project made in limited time taken out of my free time will add more function in future like play date and day with time, automatic LED brightness adjustment based on ambient light by feedback from external LDR sensor, find more intuitive and simple way to update weather/weather forecast on same led ring etc
W5300 Raspberry Pi Pico library developed for this project by adding IO Driver to this W5300 Library
Download link for my W5300 RP2040 Arduino Library
Hardware setup
Led color mapping and push button function mapping
BLUE LED - HOUR
RED LED - MINUTE
GREEN LED - SECOND
BUTTON W - PLAYS WEATHER FORECAST ON SPEAKER
BUTTON T - PLAYS CURRENT TIME ON SPEAKER
Modules used in project
60 PIXEL 2 METER NEOPIXEL STRIPE
Hardware Connection
RPi PICO GPIO Utilization for W5300 Interface
RPi PICO Available GPIO for interface Other peripherals
one can just copy paste this code in arduino ide or download from attachment with my w5300 RP2040 Library, DF Mini mp3 player functions are included in code so no library needed for DF Mini Mp3 player, All MP3 files are also in attachment.
Rest API from openweathermap.org with Json response used to get current weather and forecast - https://api.openweathermap.org/data/2.5/weather?lat=23.2167&lon=72.6833&appid=cd6370f2d6a5912dbb5b2bae7594c0.
find above line and change latitude longitude and API key before use, to get API key create account with openweathermap.org
Rest API from worldtimeapi.org with Json response used to get current time - http://worldtimeapi.org/api/timezone/Asia/Kolkata
find above line and change timezone before use.
one need to change atleast wifi credential and api key of openweathermap before uploading this code
One need to install Raspberry Pi Pico Board package for Arduino from https://github.com/earlephilhower/arduino-pico
one also need to install following library to make this code work
- W5300 modified arduino library by Madhurivaghasia
- ADAFRUIT NEO PIXEL
- ARDUINO JSON
- RASPBERRY PI PICO TIMER INTERRUPT
Above Listed W5300 Library works with Arduino Mega only, I edited this to work with RP2040 and shared in document section below
Weather forecast and current weather derived from icon id and correspondingly MP3 file play weather report description. mapping of icon ID to description in next pic,
SD Card Setup
All MP3 Files used in project attached at last of this blog, Download it unzip it and use attached python file to copy mp3 files to SD card one by one automatically with small delay.
Note : normal copy paste can not work as it messed up with DF player mini's file indexing and it will play wrong file randomly so use this python file and change source destination path to copy paste mp3 files to sd card root one by one automatically.
Arduino W5300 Library edited w5300_anymcu.h
// Written By Madhuri Vaghasia edited by njchhasatia to use RP2040 instead of Arduino Mega
#ifndef _W5300_ANYMCU_H_
#define _W5300_ANYMCU_H_
#include <Arduino.h>
#include <hardware/gpio.h> // needed to access rp2040 32 bit gpio API
#define DBUS_STRT 14 // 8bit Databus GPIO 22 ... 14
#define ADDR_STRT 7 // 3bit Address (A2 A1 A0) 7->A0, 8->A1, 9->A2
#define CTRL_STRT 10 // 3bit Control (CS WR RD) 10->RD, 11->WR, 12->CS
#define DBUS_MASK 0xFF // 8bits
#define ADDR_MASK 0x07 // 8bits
#define CTRL_MASK 0x07 // 8bits
#define ADDR_0 0x00 //bit seq A2 A1 A0
#define ADDR_1 0x01
#define ADDR_2 0x02
#define ADDR_3 0x03
#define ADDR_4 0x04
#define ADDR_5 0x05
#define ADDR_6 0x06
#define ADDR_7 0x07
#define CTRL_IDLE 0x07 //b111 //bit seq CS WR RD
#define CTRL_RDST 0x06 //b110
#define CTRL_RDEX 0x02 //b010
#define CTRL_WRST 0x05 //b101
#define CTRL_WREX 0x01 //b001
uint16_t w5300_read_indirect(uint16_t addr);
void w5300_write_indirect(uint16_t addr, uint16_t data1);
void w5300_setup_indirect_MR(void);
void w5300_init(void);
void w5300_reset(void);
#endif
Arduino W5300 Library edited w5300anymcu.cpp
// Written By Madhuri Vaghasia edited by njchhasatia to use RP2040 instead of Arduino Mega
#include "w5300_anymcu.h"
#include <Arduino.h>
// Initlize W5300 in use 8 bit Indirect addressing mode
void w5300_init(void)
{
// init all w5300 connection pins as output
gpio_init_mask((DBUS_MASK<<DBUS_STRT) | (ADDR_MASK<<ADDR_STRT) | (CTRL_MASK<<CTRL_STRT));
gpio_set_dir_masked((DBUS_MASK<<DBUS_STRT) | (ADDR_MASK<<ADDR_STRT) | (CTRL_MASK<<CTRL_STRT), (DBUS_MASK<<DBUS_STRT) | (ADDR_MASK<<ADDR_STRT) | (CTRL_MASK<<CTRL_STRT));
delay(2000);
Serial.println("\r\n--> Modified W5300 Arduino ethernet library for any mcu with Indirect Addressing (need 14 GPIO Only) \r\n--> Developed by - M.Vaghasia (rcele_85@yahoo.com) edited ny njchhasatia \r\n--> Current MCU Selected - Raspberry Pi Pico");
Serial.println("--> Soft Reset W5300");
w5300_reset();
delay(1000);
// configure W5300 to work in indirect addressing mode
w5300_setup_indirect_MR();
//Serial.println(w5300_read_indirect(0),HEX);
delay(1000);
if(w5300_read_indirect(0) == 0x3801) Serial.println("--> w5300 indirect addressing Init - Success ;)");
else
{
while(1)
{
Serial.println("--> w5300 indirect addressing Init - Fail :(\r\n--> Check w5300 hardware connections and reset mcu");
delay(5000);
}
}
delay(1000);
}
// Soft Reset W5300
void w5300_reset(void)
{
gpio_init_mask(DBUS_MASK<<DBUS_STRT); // Set Databus as output
gpio_set_dir_masked(DBUS_MASK<<DBUS_STRT,DBUS_MASK<<DBUS_STRT);
// Write 0x80 to MR_LOW (Addr - 0x01) for soft reset w5300
gpio_put_masked((DBUS_MASK<<DBUS_STRT) | (ADDR_MASK<<ADDR_STRT) | (CTRL_MASK<<CTRL_STRT), (0x80<<DBUS_STRT) | (ADDR_1<<ADDR_STRT) | (CTRL_WRST<<CTRL_STRT));
delayMicroseconds(1);
gpio_put_masked(CTRL_MASK<<CTRL_STRT, CTRL_WREX<<CTRL_STRT);
delayMicroseconds(1);
gpio_put_masked(CTRL_MASK<<CTRL_STRT, CTRL_IDLE<<CTRL_STRT);
delayMicroseconds(1);
}
// Setup W5300 to use 8 bit Indirect addressing mode
void w5300_setup_indirect_MR(void)
{
gpio_init_mask(DBUS_MASK<<DBUS_STRT); // Set Databus as output
gpio_set_dir_masked(DBUS_MASK<<DBUS_STRT,DBUS_MASK<<DBUS_STRT);
// Write 0x01 to MR_LOW (Addr - 0x01) for configure w5300 indirect addressing
gpio_put_masked((DBUS_MASK<<DBUS_STRT) | (ADDR_MASK<<ADDR_STRT) | (CTRL_MASK<<CTRL_STRT), (0x01<<DBUS_STRT) | (ADDR_1<<ADDR_STRT) | (CTRL_WRST<<CTRL_STRT));
delayMicroseconds(1);
gpio_put_masked(CTRL_MASK<<CTRL_STRT, CTRL_WREX<<CTRL_STRT);
delayMicroseconds(1);
gpio_put_masked(CTRL_MASK<<CTRL_STRT, CTRL_IDLE<<CTRL_STRT);
delayMicroseconds(1);
}
// Write 16 Bit register of W5300 using 8 bit indirect addressing
void w5300_write_indirect(uint16_t addr, uint16_t data1)
{
uint16_t data = data1;
gpio_init_mask(DBUS_MASK<<DBUS_STRT); // Set Databus as output
gpio_set_dir_masked(DBUS_MASK<<DBUS_STRT,DBUS_MASK<<DBUS_STRT);
// set desired addr in indirect address reg 0x02, 0x03 address
gpio_put_masked((DBUS_MASK<<DBUS_STRT) | (ADDR_MASK<<ADDR_STRT) | (CTRL_MASK<<CTRL_STRT), (((addr>>8) & 0xFF)<<DBUS_STRT) | (ADDR_2<<ADDR_STRT) | (CTRL_WRST<<CTRL_STRT));
delayMicroseconds(1);
gpio_put_masked(CTRL_MASK<<CTRL_STRT, CTRL_WREX<<CTRL_STRT);
delayMicroseconds(1);
gpio_put_masked(CTRL_MASK<<CTRL_STRT, CTRL_IDLE<<CTRL_STRT);
delayMicroseconds(1);
gpio_put_masked((DBUS_MASK<<DBUS_STRT) | (ADDR_MASK<<ADDR_STRT) | (CTRL_MASK<<CTRL_STRT), ((addr & 0xFF)<<DBUS_STRT) | (ADDR_3<<ADDR_STRT) | (CTRL_WRST<<CTRL_STRT));
delayMicroseconds(1);
gpio_put_masked(CTRL_MASK<<CTRL_STRT, CTRL_WREX<<CTRL_STRT);
delayMicroseconds(1);
gpio_put_masked(CTRL_MASK<<CTRL_STRT, CTRL_IDLE<<CTRL_STRT);
delayMicroseconds(1);
// set desired data in indirect data reg 0x04, 0x05 address
gpio_put_masked((DBUS_MASK<<DBUS_STRT) | (ADDR_MASK<<ADDR_STRT) | (CTRL_MASK<<CTRL_STRT), (((data1>>8) & 0xFF)<<DBUS_STRT) | (ADDR_4<<ADDR_STRT) | (CTRL_WRST<<CTRL_STRT));
delayMicroseconds(1);
gpio_put_masked(CTRL_MASK<<CTRL_STRT, CTRL_WREX<<CTRL_STRT);
delayMicroseconds(1);
gpio_put_masked(CTRL_MASK<<CTRL_STRT, CTRL_IDLE<<CTRL_STRT);
delayMicroseconds(1);
gpio_put_masked((DBUS_MASK<<DBUS_STRT) | (ADDR_MASK<<ADDR_STRT) | (CTRL_MASK<<CTRL_STRT), ((data1 & 0xFF)<<DBUS_STRT) | (ADDR_5<<ADDR_STRT) | (CTRL_WRST<<CTRL_STRT));
delayMicroseconds(1);
gpio_put_masked(CTRL_MASK<<CTRL_STRT, CTRL_WREX<<CTRL_STRT);
delayMicroseconds(1);
gpio_put_masked(CTRL_MASK<<CTRL_STRT, CTRL_IDLE<<CTRL_STRT);
delayMicroseconds(1);
}
// Read 16 Bit register of W5300 using 8 bit indirect addressing
uint16_t w5300_read_indirect(uint16_t addr)
{
uint16_t data =0;
uint32_t data1 = 0;
uint32_t data2 = 0;
gpio_init_mask(DBUS_MASK<<DBUS_STRT); // Set Databus as output
gpio_set_dir_masked(DBUS_MASK<<DBUS_STRT, DBUS_MASK<<DBUS_STRT);
// set desired addr in indirect address reg 0x02, 0x03 address
gpio_put_masked((DBUS_MASK<<DBUS_STRT) | (ADDR_MASK<<ADDR_STRT) | (CTRL_MASK<<CTRL_STRT), (((addr>>8) & 0xFF)<<DBUS_STRT) | (ADDR_2<<ADDR_STRT) | (CTRL_WRST<<CTRL_STRT));
delayMicroseconds(1);
gpio_put_masked(CTRL_MASK<<CTRL_STRT, CTRL_WREX<<CTRL_STRT);
delayMicroseconds(1);
gpio_put_masked(CTRL_MASK<<CTRL_STRT, CTRL_IDLE<<CTRL_STRT);
delayMicroseconds(1);
gpio_put_masked((DBUS_MASK<<DBUS_STRT) | (ADDR_MASK<<ADDR_STRT) | (CTRL_MASK<<CTRL_STRT), ((addr & 0xFF)<<DBUS_STRT) | (ADDR_3<<ADDR_STRT) | (CTRL_WRST<<CTRL_STRT));
delayMicroseconds(1);
gpio_put_masked(CTRL_MASK<<CTRL_STRT, CTRL_WREX<<CTRL_STRT);
delayMicroseconds(1);
gpio_put_masked(CTRL_MASK<<CTRL_STRT, CTRL_IDLE<<CTRL_STRT);
delayMicroseconds(1);
gpio_init_mask(DBUS_MASK<<DBUS_STRT); // Set Data Bus input
gpio_set_dir_masked(DBUS_MASK<<DBUS_STRT,0);
// read data from indirect data register
gpio_put_masked((ADDR_MASK<<ADDR_STRT) | (CTRL_MASK<<CTRL_STRT), (ADDR_4<<ADDR_STRT) | (CTRL_RDEX<<CTRL_STRT));
delayMicroseconds(2);
data1 = (gpio_get_all()>>DBUS_STRT)&0xFF;
gpio_put_masked(CTRL_MASK<<CTRL_STRT, CTRL_IDLE<<CTRL_STRT);
delayMicroseconds(1);
gpio_put_masked((ADDR_MASK<<ADDR_STRT) | (CTRL_MASK<<CTRL_STRT), (ADDR_5<<ADDR_STRT) | (CTRL_RDEX<<CTRL_STRT));
delayMicroseconds(2);
data2 = (gpio_get_all()>>DBUS_STRT)&0xFF;
data = (uint16_t)((data1<<8)|data2);
gpio_put_masked(CTRL_MASK<<CTRL_STRT, CTRL_IDLE<<CTRL_STRT);
delayMicroseconds(1);
return data;
}
Arduino Code
Serial Terminal log showing setting up W5300 ethernet connection and network time and weather data fetched from server using api
Arduino final sketch
// W5300 TOE SHIELD AND RPi PICO Based Enchanted Weather Clock
// Developer - N.J. Chhasatia
// Wiznet Contest project 2023
// Please install Edited W5300 Ethernet Library to work with W5300 from
// https://github.com/nitiraj/W5300-RP2040-arduino
//
#include <ArduinoJson.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include "RPi_Pico_TimerInterrupt.h"
#include <Adafruit_NeoPixel.h>
#define PIXEL_PIN 28 // pico pin
#define PIXEL_NUM 60 // NeoPixel clock size
#define MP3_TXPIN 4
#define MP3_RXPIN 5
#define PB_TIME 0 // Push button for play time
#define PB_WETH 1 // Push button for play weather
// MP3 number to name mapping
#define NWCH 102
#define NWOK 101
#define TMOK 113
#define HOUR 111
#define MINT 110
#define TIME 105
#define TEMP 108
#define HUMD 107
#define TMUN 104
#define HDUN 103
#define WLCM 112
#define WETH 106
#define FCST 109
#define BRIGHTNESS 90
uint8_t mp3_cmd[] = {0x7E,0xFF,0x06,0x03,0x00,0x00,0x03,0xFE,0xF5,0xEF};
uint8_t mp3_cmd_vol[] = {0x7E,0xFF,0x06,0x06,0x01,0x00,0x15,0xFE,0xDF,0xEF};
unsigned long epoche = 1666081881;
unsigned long premillis = 0;
static uint8_t sec;
static uint8_t mint;
static uint8_t hor;
static uint8_t hor_12;
static uint8_t flasher = 0;
float main_temp = 0;
int main_pressure = 0;
int main_humidity = 0;
uint8_t time_flag = 0;
uint8_t cweather_flag = 0;
/* Network */
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192, 168, 137, 5);
StaticJsonDocument<16> filter_time;
StaticJsonDocument<250> filter_weather;
StaticJsonDocument<48> doc_time;
StaticJsonDocument<250> doc_weather;
EthernetClient client;
RPI_PICO_Timer ITimer0(0);
Adafruit_NeoPixel pixels(PIXEL_NUM, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
Serial.begin(115200); // Initialize Serial port
pinMode(PB_TIME,INPUT_PULLUP);
pinMode(PB_WETH,INPUT_PULLUP);
init_mp3_player(); // Initlize MP3 Player
setup_neopixel(); // Initlize NeoPixel strip object (REQUIRED)
neopixel_wave();
play_mp3_many(WLCM,0,0,0,0,0);// Play welcome msg
delay(1000);
play_mp3_many(NWCH,0,0,0,0,0); // Play connecting to AP
setup_w5300(); // Setup w5300
delay(1000);
play_mp3_many(NWOK,0,0,0,0,0); // Play connected to AP
while(time_flag == 0){check_time_nw();neopixel_wave();} // Wait until Time available
setup_timer();
delay(20);
while(cweather_flag == 0){check_current_weather_nw();delay(4000);}
play_mp3_many(TMOK,0,0,0,0,0); // Play Time and weather available
delay(2000);
play_mp3_many(TIME,hor,HOUR,mint,MINT,0); // Play Time
delay(2000);
play_mp3_many(FCST,TEMP,(int)main_temp-273,TMUN,HUMD,(int)main_humidity); // Play forcast
play_mp3_many(HDUN,WETH,0,0,0,0); // Play forcast
}
void loop() {
if(mint%60 == 0 && sec == 0)
{
play_mp3_many(TIME,hor,HOUR,mint,MINT,0); // Play Time
delay(100);
check_time_nw();
delay(100);
}
if(mint%20 == 0 && sec == 0)
{
delay(100);
check_current_weather_nw();
delay(100);
}
if(digitalRead(PB_TIME) == 0)
{
play_mp3_many(TIME,hor,HOUR,mint,MINT,0); // Play Time
}
if(digitalRead(PB_WETH) == 0)
{
play_mp3_many(FCST,TEMP,(int)main_temp-273,TMUN,HUMD,(int)main_humidity); // Play forcast
play_mp3_many(HDUN,WETH,0,0,0,0); // Play forcast
}
//Debug Messages print time
//Serial.print(hor);Serial.print(":");
//Serial.print(mint);Serial.print(":");
//Serial.println(sec);
delay(10);
}
// ================ convert unix to local time ===========
void epoche2dt(unsigned long ep)
{
sec = ep%60;
ep = ep/60;
mint = ep%60;
ep = ep/60;
hor = ep%24;
epoche = ep/24;
Serial.print("Network_Time = ");
Serial.print(hor);Serial.print(":");
Serial.print(mint);Serial.print(":");
Serial.println(sec);
}
// ================ Setup w5300 connection ===========
void setup_w5300(void)
{
Ethernet.begin(mac, ip);
print_network_info();
}
void print_network_info(void){
byte print_mac[6] ;
Serial.println("\r\n-------------------------------------------------");
Serial.print("MAC : ");
Ethernet.MACAddress(print_mac);
for (byte i = 0; i < 6; i++) {
Serial.print(print_mac[i], HEX);
if (i < 5) {
Serial.print(":");
}
}
Serial.println();
Serial.print("IP : ");
Serial.print(Ethernet.localIP());
Serial.println("\r\n-------------------------------------------------");
}
// ================ Update latest time from network and convert unix to local time ===========
void check_time_nw(void)
{
client.setTimeout(15000);
//http://worldtimeapi.org/api/timezone/Asia/Kolkata
if (!client.connect("worldtimeapi.org", 80)) {
Serial.println("Connection failed");
return;
}
Serial.println("Connected!");
// Send HTTP request
client.println("GET /api/timezone/Asia/Kolkata HTTP/1.0");
client.println("Host: arduinojson.org");
client.println("Connection: close");
if (client.println() == 0) {
Serial.println("Failed to send request");
client.stop();
return;
}
// Check HTTP status
char status[32] = {0};
client.readBytesUntil('\r', status, sizeof(status));
// It should be "HTTP/1.0 200 OK" or "HTTP/1.1 200 OK"
if (strcmp(status + 9, "200 OK") != 0) {
Serial.print("Unexpected response: ");
Serial.println(status);
client.stop();
return;
}
// Skip HTTP headers
char endOfHeaders[] = "\r\n\r\n";
if (!client.find(endOfHeaders)) {
Serial.println("Invalid response");
client.stop();
return;
}
// Allocate the JSON document
// Use https://arduinojson.org/v6/assistant to compute the capacity.
filter_time["unixtime"] = true;
DeserializationError error = deserializeJson(doc_time, client, DeserializationOption::Filter(filter_time));
if (error) {
Serial.print("deserializeJson() failed: ");
return;
}
time_flag = 1;
epoche = doc_time["unixtime"];
client.stop();
delay(100);
//client.flush();
epoche2dt(epoche + 19800);
}
// ================ Update current weather from network ===========
void check_current_weather_nw(void)
{
client.setTimeout(10000);
//https://api.openweathermap.org/data/2.5/weather?lat=23.2167&lon=72.6833&appid=cd6370f2d6a5912dbb5b2bae7594c0
if (!client.connect("api.openweathermap.org", 80)) {
Serial.println("Connection failed");
return;
}
Serial.println("Connected!");
// Send HTTP request
client.println("GET /data/2.5/weather?lat=23.2167&lon=72.6833&appid=0c6ff099e8d97303f77801851380f84f HTTP/1.0");
client.println("Host: arduinojson.org");
client.println("Connection: close");
if (client.println() == 0) {
Serial.println("Failed to send request");
client.stop();
return;
}
// Check HTTP status
char status[32] = {0};
client.readBytesUntil('\r', status, sizeof(status));
// It should be "HTTP/1.0 200 OK" or "HTTP/1.1 200 OK"
if (strcmp(status + 9, "200 OK") != 0) {
Serial.print("Unexpected response: ");
Serial.println(status);
client.stop();
return;
}
// Skip HTTP headers
char endOfHeaders[] = "\r\n\r\n";
if (!client.find(endOfHeaders)) {
Serial.println("Invalid response");
client.stop();
return;
}
// Allocate the JSON document
// Use https://arduinojson.org/v6/assistant to compute the capacity.
filter_weather["weather"][0]["icon"] = true;
filter_weather["main"]["temp"] = true;
filter_weather["main"]["pressure"] = true;
filter_weather["main"]["humidity"] = true;
DeserializationError error = deserializeJson(doc_weather, client, DeserializationOption::Filter(filter_weather));
if (error) {
Serial.print("deserializeJson() failed: ");
return;
}
const char* weather_0_icon = doc_weather["weather"][0]["icon"]; // "01d"
main_temp = doc_weather["main"]["temp"]; // 309.14
main_pressure = doc_weather["main"]["pressure"]; // 1009
main_humidity = doc_weather["main"]["humidity"]; // 34
client.stop();
cweather_flag = 1;
delay(100);
//client.flush();
Serial.println("Current Weather : ");
Serial.print("-->temp = ");Serial.println(main_temp);
Serial.print("-->humd = ");Serial.println(main_humidity);
Serial.print("-->pressure = ");Serial.println(main_pressure);
Serial.print("-->icon = ");Serial.println(weather_0_icon);
}
// ================ ISR Handler for Timer triggered at every 1 second ================
bool TimerHandler0(struct repeating_timer *t)
{
sec=sec+1;
if(sec>59){sec = 0; mint = mint+1;}
if(mint>59){mint = 0; hor = hor+1;}
if(hor>23){hor = 0;}
if(hor>11)hor_12 = hor-12;
else hor_12 = hor;
pixels.clear();
pixels.setPixelColor(sec, pixels.Color(0, BRIGHTNESS, 0)); // Set pixel's color (in RAM)
if((hor_12*5)+(mint/12) == mint)
{
if(flasher%2 == 1)pixels.setPixelColor(mint, pixels.Color(BRIGHTNESS, 0, 0));
else pixels.setPixelColor(mint, pixels.Color(0, 0, BRIGHTNESS));
flasher++;
}
else
{
pixels.setPixelColor(mint, pixels.Color(BRIGHTNESS, 0, 0)); // Set pixel's color (in RAM)
pixels.setPixelColor(((hor_12*5)+(mint/12)), pixels.Color(0, 0, BRIGHTNESS)); // Set pixel's color (in RAM)
}
pixels.show();
return true;
}
// ================ initlize timer 0 pico ==================
void setup_timer(void)
{
delay(100);
Serial.print(F("CPU Frequency = ")); Serial.print(F_CPU / 1000000); Serial.println(F(" MHz"));
// Interval in microsecs
if (ITimer0.attachInterruptInterval(1000000, TimerHandler0))
Serial.print(F("Starting ITimer0 OK"));
else
Serial.println(F("Can't set ITimer0. Select another freq. or timer"));
}
// ================ Neo pixel clock ring setup ==================
void setup_neopixel(void)
{
pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
pixels.clear(); // Set all pixel colors to 'off'
for(int i=0; i<pixels.numPixels(); i++) { // For each pixel in strip...
pixels.setPixelColor(i, pixels.Color(0, BRIGHTNESS/2, 0)); // Set pixel's color (in RAM)
pixels.show(); // Update strip to match
delay(20); // Pause for a moment
}
for(int i=pixels.numPixels()-1; i>=0; i--) { // For each pixel in strip...
pixels.setPixelColor(i, pixels.Color(0, 0, 0)); // Set pixel's color (in RAM)
pixels.show(); // Update strip to match
delay(20); // Pause for a moment
}
}
// ================ Neo pixel wave red ==================
void neopixel_wave(void)
{
pixels.clear(); // Set all pixel colors to 'off'
for(int i=0; i<pixels.numPixels(); i++) { // For each pixel in strip...
pixels.setPixelColor(i, pixels.Color(BRIGHTNESS/2, 0, 0)); // Set pixel's color (in RAM)
pixels.show(); // Update strip to match
delay(20); // Pause for a moment
}
for(int i=pixels.numPixels()-1; i>=0; i--) { // For each pixel in strip...
pixels.setPixelColor(i, pixels.Color(0, 0, 0)); // Set pixel's color (in RAM)
pixels.show(); // Update strip to match
delay(20); // Pause for a moment
}
}
// =========== init MP3 Player ========
void init_mp3_player(void)
{
Serial2.setTX(MP3_TXPIN); // TX PIN for Serial2 MP3
Serial2.setRX(MP3_RXPIN); // RX PIN for Serial2 MP3
Serial2.begin(9600); // MP3
delay(1000);
Serial2.write(mp3_cmd_vol,5);
delay(100);
}
//========== Play Track ==========
void play_mp3(uint8_t track)
{
uint8_t btx;
mp3_cmd[6] = track;
mp3_cmd[8] = 0xF8 - track;
for(btx=0;btx<=9;btx++)
{
Serial2.write(mp3_cmd[btx]);
}
}
//========== Play multiple Track upto 6 ==========
void play_mp3_many(uint8_t track1,uint8_t track2,uint8_t track3,uint8_t track4,uint8_t track5,uint8_t track6)
{
char dummy;
Serial.println("Playing tracks..");
while(Serial2.available()>0) dummy = Serial2.read();
if(track1 != 0){play_mp3(track1);
while(Serial2.available()==0);
delay(40);
while(Serial2.available()>0)dummy = Serial2.read();}
delay(40);
if(track2 != 0){play_mp3(track2);
while(Serial2.available()==0);
delay(40);
while(Serial2.available()>0)dummy = Serial2.read();}
delay(40);
if(track3 != 0){play_mp3(track3);
while(Serial2.available()==0);
delay(40);
while(Serial2.available()>0)dummy = Serial2.read();}
delay(40);
if(track4 != 0){play_mp3(track4);
while(Serial2.available()==0);
delay(40);
while(Serial2.available()>0)dummy = Serial2.read();}
delay(40);
if(track5 != 0){play_mp3(track5);
while(Serial2.available()==0);
delay(40);
while(Serial2.available()>0)dummy = Serial2.read();}
delay(40);
if(track6 != 0){play_mp3(track6);
while(Serial2.available()==0);
delay(40);
while(Serial2.available()>0)dummy = Serial2.read();}
Serial.println("Playing tracks done.");
}
This Project is minor project of my Coursework of subject "IoT and Embedded Systems"
Thank you my guide Prof. M.V Vaghasia for Providing me Valuable Guidance and W5300 Hardware for implementation of this project
Thank you to wiznet and Raspberry Pi Pico community for providing valuable support
-
W5300 Arduino RP2040 Library
W5300 Arduino RP2040 Library (Edited to work with RP2040)
-
W5300 RPi PICO Enchanted Weather clock Schematic
W5300 RPi PICO Enchanted Weather clock Schematic
-
Python Code to copy mp3 files in SD card one by one
Python Code to copy mp3 files in SD card one by one
-
W5300 RPi PICO Enchanted Weather clock Arduino sketch
W5300 RPi PICO Enchanted Weather clock Arduino sketch
-
All MP3 files used in this project
All MP3 files used in this project