mpod (prototype version)

"mpod" (mbed pod) downloads audio files from web servers as a HTTP client, stores them to a USB memory (Mass Storage Class) as a USB host controller, and switches its USB host function to an external USB-enabled audio player by using FSUSB30MUX (Fairchild's USB switch IC). With power supply from the audio player via a USB cable, you can listen the latest podcasts without your iPod or PC by just pushing a "Play USB" button on the audio player.

KENWOOD RD-UDA55 + mpod

/media/uploads/geodenx/_scaled_imgp5856.jpg

BOM (example)

  1. Sunhayato ICB-293 Series: 1 pc
  2. Fairchild FSUSB30MUX Low-Power, Two-Port, High-Speed USB 2.0 (480Mbps) Switch: 1 pc
  3. Sunhayato SSP-51 Conversion Board for SOP IC 0.5 mm pitch MAX 32pin: 1 pc (optional)
  4. USB miniB connector, Sunhayato CK-36 Connector Conversion Board USB miniB, or SparkFun BOB-09966 Breakout Board for USB Mini-B: 2 pcs
  5. USB A connector or Sunhayato CK-19 Connector Conversion Board USB A: 1 pc

Schematics

/media/uploads/geodenx/_scaled_mpod.png

Sample Code

This sample code reads a XML (RSS) file of "Radio News in English" on NHK World Radio Japan [nhk.or.jp] and downloads the latest MP3 file if there is an update.

#include "mbed.h"
#include "MSCFileSystem.h"
#include "EthernetNetIf.h"
#include "HTTPClient.h"
#include "SDFileSystem.h"
#include "TextLCD.h"

int GetXml(char *path);
int GetMp3(char *url);

EthernetNetIf eth;
HTTPClient http;
MSCFileSystem usb("usb");
// DigitalOut led(LED1);
PwmOut led(LED1);
DigitalOut fsusb30s(p9);
Timer timer; // debug
SDFileSystem sd(p5, p6, p7, p8, "sd"); // debug
TextLCD lcd(p24, p26, p27, p28, p29, p30);

int main() {
    fsusb30s = 0; // FSUSB30 switches to HSD1 (StarBoard Orange)
    lcd.cls();

// Network setup
    lcd.locate(0,0);
    lcd.printf("D");
    EthernetErr ethErr = eth.setup();
    if (ethErr) {
        error("Error in network setup: %d\n", ethErr);
    }
    IpAddr ethIp=eth.getIp();
    lcd.locate(1,0);
    lcd.printf("%03d.%03d.%03d.%03d", ethIp[0], ethIp[1], ethIp[2], ethIp[3]);

// Obtain lastBuildDate
    char lastBuildDate[256] = "";
    FILE *xmlfp = fopen("/usb/english.xml", "r");
    if (NULL == xmlfp) {
        strcat(lastBuildDate, "No english.xml in USB memory\n");
    } else {
        char linebuf[256];
        while (fgets(linebuf, 256, xmlfp)) {
            if (strstr(linebuf, "<lastBuildDate>")) {
                strcat(lastBuildDate, linebuf);
                break;
            }
        }
        fclose(xmlfp);
    }
    printf("lastBuildDate (original): %s", lastBuildDate); // debug

// RSS download and parse
    GetXml("/usb/english.xml");
    xmlfp = fopen("/usb/english.xml", "r");
    if (NULL == xmlfp) {
        error("Error: Failed in opening the downloaded english.xml\n");
    } else {
        char linebuf[256] = "", url[256];
        char *urlstart, *urlend;
        while (fgets(linebuf, 256, xmlfp)) {
            if (strstr(linebuf, "<lastBuildDate>")) {
                printf("lastBuildDate (current) : %s", linebuf); // debug
                if (strcmp(lastBuildDate, linebuf) == 0) {
                    printf("lastBuildDate (local) == lastBuildDate (current)\n");
                    char lcdbuf[17];
                    strncpy(lcdbuf, lastBuildDate+25, 16);
// 0         1         2         3         4
// 0123456789012345678901234567890123456789012345678901234567890
//      <lastBuildDate>Wed, 07 Sep 2011 21:15:11 +0900</lastBuildDate>
                    lcd.locate(0, 1);
                    lcd.printf("%s", lcdbuf);
                    FILE *mp3fp = fopen("/usb/english.mp3", "r"); // check an existance of english.mp3
                    if (mp3fp != NULL) {
                        fclose(mp3fp);
                        break;
                    } else {
                        printf("However, no enlish.mp3 in USB memory\n");
                    }
                }
            } else if (urlstart = strstr(linebuf, "<enclosure url=\"")) {
                urlstart += 16;
                urlend = strchr(urlstart, '"');
                strncpy(url, urlstart, urlend - urlstart);
                url[urlend - urlstart] = '\0';
                GetMp3(url);
                break;
            }
        }
        fclose(xmlfp);
    }

// Switch USB host from mbed to KWD
    fsusb30s = 1; // HSD2 (KWD)
    printf("USB host was switched to HSD2.\n");

// blink LED1
    int up = 1;
    float brightness = 0.0;
    while (1) {
        if (up == 1 && brightness < 1.0) {
            ;
        } else if (up == 1 && brightness >= 1.0) {
            up = 0;
        } else if (up == 0 && brightness > 0) {
            ;
        } else if (up == 0 && brightness <= 0.0) {
            up = 1;
        } else {
            error("LED PWM error\n");
        }

        if (up == 1) {
            brightness += 0.01;
        } else {
            brightness -= 0.01;
        }
        led = brightness;

        wait(0.02);
    }
}

int GetXml(char *path) {
    HTTPFile xml(path);
    printf("Getting http://www3.nhk.or.jp/rj/podcast/rss/english.xml\n");
    HTTPResult xmlr = http.get("http://www3.nhk.or.jp/rj/podcast/rss/english.xml", &xml);
    if (xmlr != HTTP_OK) {
        error("Error in http.get in GetXml(): %d\n", xmlr);
    }
    xml.clear();

    return (0);
}

int GetMp3(char *url) {
    HTTPFile mp3("/usb/english.mp3");
    // HTTPFile mp3("/sd/english.mp3"); // debug
    printf("Getting %s\n", url);
    char lcdbuf[17];
    strncpy(lcdbuf, strrchr(url,'/') + 1, 16); // find a file name
    lcdbuf[16] = '\0';
    lcd.locate(0, 1);
    lcd.printf("%s", lcdbuf);
    timer.stop(); // debug
    timer.reset(); // debug
    timer.start(); // debug
    HTTPResult mp3r = http.get(url, &mp3);
    if (mp3r != HTTP_OK) {
        error("Error in http.get in GetMp3(): %d\n", mp3r);
    }
    mp3.clear();
    timer.stop(); // debug
    printf("timer.read_ms(): %d\n", timer.read_ms());

    return (0);
}


Please log in to post comments.