Well, the issue resolved on its own. I am not sure of what I did but now it works. I was probably confused with the baudrates. For info, I am using the arduino demilanove, with atmega 328.
Anyway, I tidied up the code and I regrouped all the writing operations in one callback (fillsdbuffer). If you just leave the serial.print operation in this function, and you remove all the operations on the rMP3, this code sends the stream to the serial port, ready to be read.
The problem I have now is that, when I added the rMP3 code, I could not open the file /buf1 where I plan to write the stream (line 108). Is there anything obviously wrong?
Here is the code:
/*
* Stores a stream on the SD card, in buffer 1 (/stream/buf1)
*/
# define WWW_client
#include <EtherShield.h>
#include <NewSoftSerial.h>
#include <RogueMP3.h>
#include <RogueSD.h>
static uint8_t mymac[6] = {0x54,0x55,0x99,0x10,0x00,0x25};
static uint8_t myip[4] = {192,168,1,1};
// Default gateway. The ip address of your DSL router. It can be set to the same as
// websrvip the case where there is no default GW to access the
// web server (=web server is on the same lan as this host)
static uint8_t gwip[4] = {192,168,1,254};
//=========================== =================================================================================
// Website declarations
//============================================================================================================
#define PORT 80 // HTTP
// the etherShield library does not really support sending additional info in a get request
// here we fudge it in the host field to add the API key
// Http header is
// Keep-Alive: 330
// Host: mp3.live.tv-radio.com
// User-Agent: Arduino/1.0
// Accept: text/html
#define HOSTNAME "mp3.live.tv-radio.com\r\nKeep-Alive: 300" // API key
static uint8_t websrvip[4] = { 0,0,0,0 }; // Get pachube ip by DNS call
#define WEBSERVER_VHOST "mp3.live.tv-radio.com"
#define HTTPPATH "/franceinter/all/franceinterhautdebit.mp3" // Set your own feed ID here
static uint8_t resend=0;
static int8_t dns_state=0;
EtherShield es=EtherShield();
#define BUFFER_SIZE 900
static uint8_t buf[BUFFER_SIZE+1];
// setting the rMP3
NewSoftSerial rmp3_serial(6, 7);
RogueMP3 rmp3(rmp3_serial);
RogueSD filecommands(rmp3_serial);
char path[96]; // path of the buffers
uint8_t volume = 40; // sound volume
#define SD_BUFFER_SIZE 128000 // size of each buffer on the SD card
void browserresult_callback(uint8_t statuscode,uint16_t datapos){
// left here in case it is needed later
}
// fillsdbuffer transfers the data from the ethernet buffer to the SD cards
// fillsdbuffer( ethernet buffer, starting position, ending position,
// SD buffer handle, current SD position)
void fillsdbuffer(uint8_t *buf, int pos, int plen, uint8_t filehandle, uint16_t sdpos){
char s;
while (pos<=plen) // write the remaining data to the buffer
{
s = char(buf[pos]);
filecommands.write(filehandle,1,&s);
Serial.print(buf[pos]); // could use pos++, need to see that later
pos++;
sdpos++;
}
}
void setup(){
Serial.begin(230400);
/*initialize enc28j60*/
es.ES_enc28j60Init(mymac);
//init the ethernet/ip layer:
es.ES_init_ip_arp_udp_tcp(mymac, myip, PORT);
// init the web client:
es.ES_client_set_gwip(gwip); // e.g internal IP of dsl router
rmp3_serial.begin(9600); // parameter D3 in the RMP3.CFG config file (root dir)
rmp3.sync();
rmp3.stop();
rmp3.setvolume(volume);
filecommands.sync();
}
void loop()
{
static uint32_t timetosend;
int pos;
int dat_p;
int sec = 0;
long lastDnsRequest = 0L;
int plen = 0;
int reqsent = 0; // flags the request sending
int streamon = 0; // flags the streaming
int8_t filehandle; // handle to the active SD buffer
uint16_t sdpos = 0; // position of last data in the SD buffer
dns_state=0;
// open the 1st SD buffer, directory /stream/
filehandle = filecommands.open("/buf1",open_mode(OPEN_WRITE));
if (filehandle<1) // in case of an error during the opening
{
Serial.println("Error: cannot open the file.");
while (1) {}; // stops here, cannot continue anyway.
}
while(1) {
// handle ping and wait for a tcp packet - calling this routine powers the sending and receiving of data
plen = es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf);
dat_p=es.ES_packetloop_icmp_tcp(buf,plen);
if( plen > 0 ) {
// We have a packet
// Check if IP data
if (dat_p == 0 && reqsent == 0) {
if (es.ES_client_waiting_gw() ){
// No ARP received for gateway
continue;
}
// It has IP data
if (dns_state==0){
sec=0;
dns_state=1;
lastDnsRequest = millis();
es.ES_dnslkup_request(buf,(uint8_t*)WEBSERVER_VHOST);
continue;
}
if (dns_state==1 && es.ES_udp_client_check_for_dns_answer( buf, plen ) ){
dns_state=2;
es.ES_client_set_wwwip(es.ES_dnslkup_getip());
}
if (dns_state!=2){
// retry every minute if dns-lookup failed:
if (millis() > (lastDnsRequest + 60000L) ){
dns_state=0;
lastDnsRequest = millis();
}
// don't try to use web client before
// we have a result of dns-lookup
Serial.println("DS lookup failed");
continue;
}
}
else
{
if (dns_state==1 && es.ES_udp_client_check_for_dns_answer( buf, plen ) ){
dns_state=2;
es.ES_client_set_wwwip(es.ES_dnslkup_getip());
}
}
if (dat_p == 0 && reqsent == 1) // case where data was received
{
// case where the request was sent previously and we keep receiving data
if ( dns_state == 2 && reqsent == 1)
{
if (streamon==0) // here the stream has not started yet
//The stream data starts after a double linefeed (0x0a 0x0d 0x0a 0x0d), so we need to find that first
{
pos = 54; // we start at 54 bytes, that falls just after the minimum TCP header
while (pos<=plen) // loop until end of buffer (or we break out having found what we wanted)
{
while (buf[pos]) if (buf[pos++] == '\n') break; // find the first line feed
if (pos>plen) break; // run out of buffer
if (buf[pos++] == '\r') // if it is followed by a carriage return then it is a blank line (\r\n\r\n)
{
pos++; //skip over the '\n' remaining
if (pos>=plen) continue; // if there are no data, wait for the next packet
streamon = 1; // if the data is there, yeepee ! start the streaming officially
fillsdbuffer(buf,pos,plen,filehandle,sdpos);
continue;
}
}
}
else // if we are here, the streaming has already started and we just copy the data
{
fillsdbuffer(buf,dat_p+54,plen,filehandle,sdpos);
// for (int ii=dat_p+54;ii<plen;ii++)
// {
// Serial.print(buf[ii]);
// }
}
// need acknowledgement ?
//es.ES_enc28j60PacketSend(plen,buf);
}
}
}
// If we have IP address for server and its time then request data
if( dns_state == 2 && reqsent == 0 && millis() - timetosend > 31000) // every 31 seconds
{
timetosend = millis();
// note the use of PSTR - this puts the string into code space and is compulsory in this call
// second parameter is a variable string to append to HTTPPATH, this string is NOT a PSTR
es.ES_client_browse_url(PSTR(HTTPPATH), NULL, PSTR(HOSTNAME), &browserresult_callback);
reqsent = 1; // data sent, so flag up
}
}
}