Title:Let's try the function on GR-KURUMI, ethernet vol.
Displayed Name:@chobichan
Concept / Overview |
---|
Let's try to use the ethernet library for GR-KURUMI. |
Ethernet with GR-KURUMI
We can use sketch reference without fail on GR-KURUMI, even though it appears as if “under construction”.
Standard is WIZ550io including Wiznet W5500 as controller chip instead of Arduino Ether Shield.
Though it’s not so popular yet.
http://www.wiznet.co.kr/product-item/wiz550io/
Controller chip W5500 is a grand-successor of W5100 used for Ether Shield, with enhancement of the function, hardware bag has been fixed or the number of socket has been increased.
Let’s try out W5500.
Isn’t this WIZ550io?
The picture shows an originally designed board, called WalNet. It’s not so different from WIZ550io.
Now let’s operate WalNet, please refer to the examples for Arduino、customize for WalNet.
https://www.arduino.cc/en/Tutorial/WebClient
Here is the code for your reference.
/* ------------------------------------------------------------------------ */ /* W5500を使ってみる */ /* designed by hamayan */ /* Copyright(C) hamayan */ /* since 2004 - 2016 */ /* ------------------------------------------------------------------------ */ //https://www.arduino.cc/en/Tutorial/WebClient #include#include #define RSTn 4 byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; char server[] = "www.google.com"; IPAddress ip(192, 168, 100, 177); EthernetClient client; void setup() { Serial.begin(9600); Serial.println("W5500 Ethernet controller chip test."); pinMode( RSTn, OUTPUT ); //w5500 hardware reset digitalWrite( RSTn, LOW ); delay( 10UL ); digitalWrite( RSTn, HIGH ); // start the Ethernet connection: if(Ethernet.begin(mac) == 0) { Serial.println("Failed to configure Ethernet using DHCP"); // try to congifure using IP address instead of DHCP: Ethernet.begin(mac, ip); } // give the Ethernet shield a second to initialize: delay(1000); Serial.println("connecting..."); if( client.connect(server, 80) ) { Serial.println("connected"); // Make a HTTP request: client.println("GET /search?q=GR-KURUMI HTTP/1.1"); client.println("Host: www.google.com"); client.println("Connection: close"); client.println(); } else { // if you didn't get a connection to the server: Serial.println("connection failed"); } } void loop() { // if there are incoming bytes available // from the server, read them and print them: if( client.available() ) { char c = client.read(); Serial.print(c); } // if the server's disconnected, stop the client: if( !client.connected() ) { Serial.println(); Serial.println("disconnecting."); client.stop(); // do nothing forevermore: while (true) {} } }
Found “ the document has been transferred here” in the response.
it seems that the program works and connect to Google by HTTP without fail.
How comfortable! Both DHCP and DNS are working.
On trying out WalNet, amendment is required for the part of library.
gr_common/RLduino78/libraries/Ethernet/utility
w5100.h WIZ550io_WITH_MACADDRESS
Disables by commenting out or defining under another name.
While WIZ550io has EEPROM storing MAC Address on board, WalNet doesn’t have.
Working out of internet radio
Using MP3 decoder IC to play music with SD card.
Please refer to SD Card vol.
There are many music distribution service sites on internet.
They are called internet radio.
Let’s combine WalNet network function and WalSound board for SD card. Then access the internet radio station to play music.
We might say this is a kind of IOT, since these are the internet-connected things.
How to access internet radio?
The application “Winamp” on PC help search internet radio station, so listeners can take the music distribution service easily. However, this is not GR-KURUMI’s case. Since there is no search engine on it, we have to search internet radio station by ourselves.
To specify the radio station in advance, please refer to this site for radio station information.
http://www.shoutcast.com
Opening the site, you can see the chart showing the Bit Rate, audio compression technology form such as MP3, AAC etc. by genre.
Click on the icon for download sign, then you can choose the application among Winamp, M3U, XSPF.
This time, choose Winamp.
Once download, the file with extension of “.PLS” shows up.
Open this with appropriate text editor.
[playlist]
numberofentries=1
File1=http://167.114.131.90:5344/stream
Title1=(#1 - 0/1000) ebrandradio
Length1=-1
Version=2
Global IP address of server for music distribution service:167.114.131.90
The port number of the server:5344
File name:stream
※Sometimes the file shows the domain name instead of global IP address.
Sending HTTP sentence to get file to the address as well as port number, you can get a lot of music data, MP3 form in this case, then tear them to pieces and throw into MP3 decoder IC.
Rather than MP3, VS1063A support AAC form as well, corresponding to almost all distribution services.
※For more information, please refer to the document about VS1063A.
Enhancement of bit rate
SD Card case, there seems to be no problem to play music even with 192kbps.
Internet radio case, we can listen to a tune up to 32kbps.
There seems to be a problem with efficiency by internet side.
Identify the issue with packet monitor on network.
Please refer to PacMon by Layer.
http://www.layer.co.jp
Supporting Japanese language, very convenient.
Blue inverted sign shows the packet data from server.
Found the data is divided into 1,024byte,
interval diverge up to 170ms.
On TCP, transmission Control Protocol, flow control which adjust the size of sending data would work in accordance with the amount of empty capacity of the receiving buffer.
Seeing the contents of the packet data from EalNet Just before the server transmit the data, we can see how flow control work.
The blue Inverted “Window” shows 2,048byte.
confirmed that the server hesitate to send the big size of data, considering the window size.
What shall we do?
Recommend to extend the buffer size at receiving side.
Controller chip W5500 can have 8 piece of sockets,
the buffer for receiving/sending used at each socket would be divided by several patterns among 32kbyte of RAM.
Rather than the application of using several sockets at the same time, only a socket will cover the usage like this.
Set 32kbyte into transmission part and receiving part with each 16kbyte.
Suggested that this change be executed in w5500.cpp under gr_common/RLduino78/libraries/Ethernet/utility
In reset function init, the buffer size of each socket has been set at 2kbyte across the board,reset 16 for socket 0, reset 0 for others.
Operating the program after compile, confirmed the empty space has been 16kbyte for receiving buffer on WalNet.
The data size sending from server remarkably has increased.
Notice on sending HTTP sentence
Just in case, this is the brief note just on sending HTTP sentence.
Please see the screen on the packet monitor,
found a large amount of packet data by 1byte has been sent out from WalNet on sending HTTP sentence.
Since HTTP sentence has 96 characters, the packet data is suppose to be sent 96 times more than we need.
As a matter of course, one time transmission is enough.
This is caused by
client.print
which is the character function for serial, assumed to be sent the packet data by 1 byte unit,
Client.print do so in Ethernet as well.
Ethernet can proceed the data by block, sending by 1 byte unit cause traffic jam on network to no avail.
Please don’t say IOT.
The counter measure is done at one time with
client.write
We will never know unless we check the packet data running in LAN cable in the packet monitor.
For your reference, here is the code.
/* ------------------------------------------------------------------------ */ /* W5500でインターネットラジオ */ /* designed by hamayan */ /* Copyright(C) hamayan */ /* since 2004 - 2016 */ /* ------------------------------------------------------------------------ */ #include#include #include #include //for vs1063a #define RSTn 4 extern "C" { #include "string.h" } #if !defined( _MULTITASK_H_ ) #define dly_tsk(tim) delay(tim) #define rot_rdq() #endif /*_MULTITASK_H_ */ void VS1011e_Wait_DREQ( void ); void vs1011eInit( void ); void VS1011e_SCI_Write( unsigned char adr, unsigned short data ); unsigned short VS1011e_SCI_Read( unsigned char adr ); void VS1011e_SDI_Write( const char *data, unsigned long size ); void setVolum( unsigned short vol ); bool isDREQ( void ); byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; IPAddress ip(192, 168, 100, 177); struct INTERNET_RADIO { const char *name; //station name const char *domain; //server domain unsigned short port; //server port const char *fn; //file name int rate; //bit rate //const char *type; //mp3 or aac } station[] = { {"ABC Lounge","listen.radionomy.com",80,"/ABC-Lounge",128}, {"SmoothJazz.com Global Radio","75.126.221.202",8000,"/",128}, {"TheJazzGroove.com","199.180.72.2",8015,"/",128}, {"ALL SMOOTH JAZZ","listen.radionomy.com",80,"/all-smooth-jazz",128}, {"ABC Jazz","listen.radionomy.com",80,"/ABC-Jazz",128}, {"KHNY Honey 103","listen.shoutcast.com",80,"/Honey103",128}, {"181.fm - The Breeze","108.61.73.120",8004,"/",128}, {"Smooth Jazz 247","listen.radionomy.com",80,"/Smoothjazz247",128}, {"SwissGroove","184.154.202.243",8053,"/",128}, {"Instrumentals Forever","listen.radionomy.com",80,"/Instrumentals-Forever",128}, {"SmoothJazz.com Global Radio","173.244.199.248",80,"/",128}, {"Smooth Jazz Florida","162.244.80.41",8802,"/",128}, {"BEST SMOOTH JAZZ - UK (LONDON)","64.95.243.43",8002,"/",128}, {"JAZZ.FM91 (CJRT-FM)","206.223.188.170",8000,"/",96}, }; int stationNumber = 0; EthernetClient client; /*DREQ:D3(p16),XRESET:D5(p15),XCS:D6(p10),XDCS:D9(p13) */ #define VS_DRQ (P1.BIT.bit6 == 1) #define VS_RST_IS_0 P1.BIT.bit5 = 0 #define VS_RST_IS_1 P1.BIT.bit5 = 1 #define VS_XDCS_IS_0 P1.BIT.bit3 = 0 #define VS_XDCS_IS_1 P1.BIT.bit3 = 1 #define VS_XCS_IS_0 P1.BIT.bit0 = 0 #define VS_XCS_IS_1 P1.BIT.bit0 = 1 #define VS_SCI_OPE_WRITE 0x02 #define VS_SCI_OPE_READ 0x03 enum VS_REGISTERS { VS_MODE, VS_STATUS, VS_BASS, VS_CLOCKF, VS_DECODE_TIME, VS_AUDATA, VS_WRAM, VS_WRAMADDR, VS_HDAT0, VS_HDAT1, VS_AIADDR, VS_VOL, VS_AICTRL0, VS_AICTRL1, VS_AICTRL2, VS_AICTRL3 }; void setup() { Serial.begin(230400); Serial.println("W5500 internet radio."); pinMode( RSTn, OUTPUT ); //w5500 hardware reset digitalWrite( RSTn, LOW ); delay( 10UL ); digitalWrite( RSTn, HIGH ); SPI.begin(); SPI.setClockDivider(SPI_CLOCK_DIV8); //2mhz SPI.setDataMode(SPI_MODE0); vs1011eInit(); setVolum( 0x2020 ); //上位と下位に分かれている。数字が大きくなると音が小さくなる。 SPI.setClockDivider(SPI_CLOCK_DIV2); //8mhz // start the Ethernet connection: if(Ethernet.begin(mac) == 0) { Serial.println("Failed to configure Ethernet using DHCP"); // try to congifure using IP address instead of DHCP: Ethernet.begin(mac, ip); } // give the Ethernet shield a second to initialize: delay(1000); Serial.print("connect to "); Serial.println(station[stationNumber].domain); while( true ) { if( client.connect(station[stationNumber].domain, station[stationNumber].port) ) { Serial.print(station[stationNumber].name); Serial.println(" connected."); // Make a HTTP request: String str = "GET "; str += station[stationNumber].fn; str += " HTTP/1.1\r\n"; str += "Host: "; str += station[stationNumber].domain; str += "\r\n"; str += "Accept: */*\r\n"; str += "User-Agent: GR-KURUMI\r\n"; str += "Connection: Close\r\n\r\n"; client.write((const unsigned char*)&str[0],str.length()); Serial.print( str ); unsigned long lastTime = millis(); #define TIMEOUT 5000UL #define RCV_BUFFER_LIMIT 2048 int rcvSz; byte *mp3Data; while( true ) { rcvSz = client.available(); if(rcvSz > 0) { Serial.print("rcvSz="); Serial.println(rcvSz,DEC); rcvSz = (rcvSz > RCV_BUFFER_LIMIT) ? RCV_BUFFER_LIMIT : rcvSz; mp3Data = new byte[rcvSz]; rcvSz = client.read( mp3Data, rcvSz ); SPI.setClockDivider(SPI_CLOCK_DIV8); VS1011e_SDI_Write( (const char *)mp3Data, (unsigned long)rcvSz ); SPI.setClockDivider(SPI_CLOCK_DIV2); delete[] mp3Data; lastTime = millis(); } else { if( (millis() - lastTime) > TIMEOUT ) { Serial.println("TIMEOUT!"); client.stop(); if( ++stationNumber >= (sizeof(station) / sizeof(station[0])) ) stationNumber = 0; break; } } if(!client.connected()) { Serial.println("DISCONNECTED!"); client.stop(); if( ++stationNumber >= (sizeof(station) / sizeof(station[0])) ) stationNumber = 0; break; } } } else { // if you didn't get a connection to the server: Serial.println("connection failed"); delay( 60 * 1000UL ); } } } void loop() { } /****************************************************************************/ /* vs1011e初期化 */ /****************************************************************************/ void vs1011eInit( void ) { int i; char dummy; unsigned short loud; /*PORTの設定*/ PM1.BIT.bit6 = 1; //dreq input mode PIM1.BIT.bit6 = 1; //ttl input PM1.BIT.bit5 = 0; //xreset output mode POM1.BIT.bit5 = 0; //cmos PM1.BIT.bit3 = 0; //xdcs output mode POM1.BIT.bit3 = 0; //cmos PM1.BIT.bit0 = 0; //xcs output mode POM1.BIT.bit0 = 0; //cmos /*XRESET*/ VS_RST_IS_0; dly_tsk(10); /*XRESETの解除*/ VS_RST_IS_1; /*ソフトウエアリセット*/ VS1011e_SCI_Write( VS_MODE, 0x0804 ); VS1011e_SCI_Write( VS_MODE, 0x0800 ); /*モード設定完了*/ VS1011e_SCI_Write( VS_CLOCKF, 0xa000 + 1072 ); /*クロック設定 x4 0x8000:x3.5*/ VS1011e_SCI_Write( VS_VOL, 0x2020 ); /*音量設定 夜、寝ている時にいい感じ*/ //VS1011e_SCI_Write( VS_VOL, 0x1010 ); /*音量設定*/ loud = VS1011e_SCI_Read( VS_VOL ); dly_tsk(100); /*バッファを0で埋める*/ for( i = 0, dummy = 0; i < 2048; i++ ) VS1011e_SDI_Write( &dummy, 1 ); } /****************************************************************************/ /* VS1011eのDREQがネゲートされるのを待つ */ /****************************************************************************/ void VS1011e_Wait_DREQ( void ) { while( VS_DRQ == false ) rot_rdq(); } /****************************************************************************/ /* SCIの書き込み */ /****************************************************************************/ void VS1011e_SCI_Write( unsigned char adr, unsigned short data ) { /*DREQのチェック*/ if( VS_DRQ == false ) VS1011e_Wait_DREQ(); /*XCSのアサート*/ VS_XCS_IS_0; /*オペレーションコードの書き込み*/ SPI.transfer(VS_SCI_OPE_WRITE); /*アドレスの書き込み*/ SPI.transfer(adr); /*データの書き込み*/ SPI.transfer(data >> 8); SPI.transfer(data >> 0); /*XCSのネゲート*/ VS_XCS_IS_1; } /****************************************************************************/ /* SCIの読み込み */ /****************************************************************************/ unsigned short VS1011e_SCI_Read( unsigned char adr ) { int i; unsigned char ope; unsigned short data = 0; /*DREQのチェック*/ if( VS_DRQ == false ) VS1011e_Wait_DREQ(); /*XCSのアサート*/ VS_XCS_IS_0; /*オペレーションコードの書き込み*/ SPI.transfer(VS_SCI_OPE_READ); /*アドレスの書き込み*/ SPI.transfer(adr); /*データの読み込み*/ data = SPI.transfer(0xff) << 8; data |= SPI.transfer(0xff) << 0; /*XCSのネゲート*/ VS_XCS_IS_1; return data; } /****************************************************************************/ /* SDIの読み込み */ /****************************************************************************/ void VS1011e_SDI_Write( const char *data, unsigned long size ) { /*XDCSのアサート*/ VS_XDCS_IS_0; for( ;size > 0; size-- ) { /*書き込めるまで待ちを入れる*/ while( size > 32 && VS_DRQ == false ) rot_rdq(); //while( size > 32 && digitalRead(dreq) == LOW ) rot_rdq(); /*データの書き込み*/ SPI.transfer(*data++); } /*XDCSのネゲート*/ VS_XDCS_IS_1; } /****************************************************************************/ /* volume control */ /* 上位と下位に分かれている。数字が大きくなると音が小さくなる。 */ /****************************************************************************/ void setVolum( unsigned short vol ) { VS1011e_SCI_Write( VS_VOL, vol ); /*音量設定*/ } /****************************************************************************/ /* what is state of dreq pin ? */ /****************************************************************************/ bool isDREQ( void ) { return VS_DRQ; }
General hard engineer... occasionally writing for technical magazine.