Wiznet makers

nj_india

Published August 20, 2023 © Creative Commons Attribution CC BY version 4.0 or later (CC BY 4+)

0 UCC

0 VAR

2 Contests

0 Followers

0 Following

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

COMPONENTS Hardware components

WIZnet - W5300-TOE-Shield

x 1

TOE to access internet NTP and Weather Server


Raspberry Pi - Raspberry Pi Pico

x 1

main processor

Software Apps and online services

Arduino - Arduino IDE

x 1

Arduino IDE with RPi PICO package


PROJECT DESCRIPTION

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

W5300 TOE Shield

Raspberry Pi PICO

DF PLAYER MINI MP3 PLAYER

60 PIXEL 2 METER NEOPIXEL STRIPE

2W - 4W SPEAKER

 

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

  1. W5300 modified arduino library by Madhurivaghasia
  2. ADAFRUIT NEO PIXEL
  3. ARDUINO JSON
  4. 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

Documents
  • 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

Comments Write