Download NHK English news podcast automatically. XML Parser "spxml" is used. This application requires mpod mother board. See also http://mbed.org/users/geodenx/notebook/mpod/

Dependencies:   BlinkLed HTTPClient EthernetInterface FatFileSystemCpp MSCFileSystem spxml mbed-rtos mbed

Fork of mpod_nhk_english by Satoshi Togawa

Download NHK English news podcast automatically.
XML Parser "spxml" is used.
This application requires mpod mother board.
See also http://mbed.org/users/geodenx/notebook/mpod/

Files at this revision

API Documentation at this revision

Comitter:
togayan
Date:
Sat Aug 18 16:46:40 2012 +0000
Parent:
1:1637e625b21b
Child:
3:07562878d3c3
Commit message:
Fixed some bugs.

Changed in this revision

BlinkLed.cpp Show annotated file Show diff for this revision Revisions of this file
BlinkLed.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/BlinkLed.cpp	Fri Aug 17 12:49:12 2012 +0000
+++ b/BlinkLed.cpp	Sat Aug 18 16:46:40 2012 +0000
@@ -1,60 +1,61 @@
-#include "BlinkLed.h"
-    
-BlinkLed::BlinkLed(PinName pin, uint32_t millisecWait, const char* name) :
-led(pin, name),
-millisecWait(millisecWait),
-thread(0)
-{
-}
-
-BlinkLed::~BlinkLed()
-{
-}
-
-void BlinkLed::startBlink()
-{
-    if(thread == 0)
-    {
-        thread = new Thread(blink, this);
-    }
-}
-
-void BlinkLed::finishBlink()
-{
-    if(thread != 0)
-    {
-        thread->terminate();
-        thread = 0;
-        led = 0.0;
-    }
-}
-
-void BlinkLed::blink(void const *argument)
-{
-    BlinkLed* blinkLed = (BlinkLed*)argument;
-    
-    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;
-        }
-        blinkLed->led = brightness;
-        
-        Thread::wait(blinkLed->millisecWait);
-    }
-}
+#include "BlinkLed.h"
+    
+BlinkLed::BlinkLed(PinName pin, uint32_t millisecWait, const char* name) :
+led(pin, name),
+millisecWait(millisecWait),
+thread(0)
+{
+}
+
+BlinkLed::~BlinkLed()
+{
+}
+
+void BlinkLed::startBlink()
+{
+    if(thread == 0)
+    {
+        thread = new Thread(blink, this, osPriorityNormal, 128, NULL);
+    }
+}
+
+void BlinkLed::finishBlink()
+{
+    if(thread != 0)
+    {
+        thread->terminate();
+        delete thread;
+        thread = 0;
+        led = 0.0;
+    }
+}
+
+void BlinkLed::blink(void const *argument)
+{
+    BlinkLed* blinkLed = (BlinkLed*)argument;
+    
+    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;
+        }
+        blinkLed->led = brightness;
+        
+        Thread::wait(blinkLed->millisecWait);
+    }
+}
--- a/BlinkLed.h	Fri Aug 17 12:49:12 2012 +0000
+++ b/BlinkLed.h	Sat Aug 18 16:46:40 2012 +0000
@@ -5,25 +5,55 @@
 #include "mbed.h"
 #include "rtos.h"
 
+/** LED which blinks automatically with RTOS
+*/
 class BlinkLed
 {
 public:
+    /** Constructor
+     */
     BlinkLed(PinName pin, uint32_t millisecWait, const char* name = NULL);
     
+    /** Destructor
+     */
     ~BlinkLed();
     
+    /** Start biinking
+     */
     void startBlink();
     
+    /** Finish biinking
+     */
     void finishBlink();
       
 private:
+    /** Copy constructor
+     *  Disable because it is only declaration
+     */
+    BlinkLed(const BlinkLed&);
+    
+    /** Copy assignment operators
+     *  Disable because it is only declaration
+     */
+    BlinkLed& operator=(const BlinkLed&);
+    
+    /** Function for blinking
+     *  This function will be bind to new thread
+     */
     static void blink(void const *argument);
     
+    /** Target Led
+     */
     PwmOut led;
+    
+    /** Waiting time for making the cycle to change brightness
+     */
     uint32_t millisecWait;
     
+    /** Pointer to thread for blinking
+     */
     Thread* thread;
 };
 
 
-#endif /* BLINKLED_H_ */
\ No newline at end of file
+#endif /* BLINKLED_H_ */
--- a/main.cpp	Fri Aug 17 12:49:12 2012 +0000
+++ b/main.cpp	Sat Aug 18 16:46:40 2012 +0000
@@ -5,7 +5,12 @@
 #include "HTTPFile.h"
 #include "BlinkLed.h"
 #include "tinyxml2.h"
+#include <string>
+#include <iostream>
 
+using std::string;
+using std::cout;
+using std::endl;
 using namespace tinyxml2;
 
 int GetFile(const char *path, const char *url);
@@ -13,7 +18,8 @@
 EthernetInterface eth;
 HTTPClient http;
 MSCFileSystem usb("usb");
-BlinkLed led1(LED1, 4);
+BlinkLed led1(LED1, 6);
+BlinkLed led2(LED2, 1);
 DigitalOut fsusb30s(p9);
 Timer timer;
 
@@ -37,77 +43,101 @@
     eth.connect();
     
     // Obtain original lastBuildDate
-    const char* lastBuildDateOriginal;
-    XMLDocument docOriginal;
-    if(XML_SUCCESS != docOriginal.LoadFile(rssPath))
+    string lastBuildDateOriginal;
     {
-        lastBuildDateOriginal = "No english.xml in USB memory";
+        XMLDocument docOriginal;
+        if(XML_SUCCESS != docOriginal.LoadFile(rssPath))
+        {
+            lastBuildDateOriginal = "No original english.xml in USB memory";
+        }
+        else
+        {
+            XMLElement* lastBuildDateOriginalElement = docOriginal.FirstChildElement("rss")->FirstChildElement("channel")->FirstChildElement("lastBuildDate");
+            if(NULL == lastBuildDateOriginalElement)
+            {
+                lastBuildDateOriginal = "No \"lastBuildDate\" element in original RSS";
+            }
+            else
+            {
+                lastBuildDateOriginal = lastBuildDateOriginalElement->GetText();
+            }
+        }
     }
-    XMLElement* lastBuildDateOriginalElement = docOriginal.FirstChildElement("rss")->FirstChildElement("channel")->FirstChildElement("lastBuildDate");
-    if(NULL == lastBuildDateOriginalElement)
-    {
-        lastBuildDateOriginal = "No \"lastBuildDate\" element in RSS";
-    }
-    else
-    {
-        lastBuildDateOriginal = lastBuildDateOriginalElement->GetText();
-    }
+    cout << endl << "lastBuildDate (original): " << lastBuildDateOriginal << endl;
     
     // Download RSS
     GetFile(rssPath, rssUrl);
     
     // Obtain current lastBuildDate 
-    const char* lastBuildDateCurrent;
-    XMLDocument docCurrent;
-    if(XML_SUCCESS != docCurrent.LoadFile(rssPath))
+    string lastBuildDateCurrent;
+    string mp3Url;
+    string mp3Length;
     {
-        lastBuildDateCurrent = "No english.xml in USB memory";
-    }
-    XMLElement* lastBuildDateCurrentElement = docCurrent.FirstChildElement("rss")->FirstChildElement("channel")->FirstChildElement("lastBuildDate");
-    if(NULL == lastBuildDateCurrentElement)
-    {
-        lastBuildDateCurrent = "No \"lastBuildDate\" element in RSS";
+        XMLDocument docCurrent;
+        if(XML_SUCCESS != docCurrent.LoadFile(rssPath))
+        {
+            fsusb30s = 1; // HSD2
+            error("No current english.xml in USB memory.\n");
+        }
+        
+        XMLElement* lastBuildDateCurrentElement = docCurrent.FirstChildElement("rss")->FirstChildElement("channel")->FirstChildElement("lastBuildDate");
+        if(NULL == lastBuildDateCurrentElement)
+        {
+            fsusb30s = 1; // HSD2
+            error("No \"lastBuildDate\" element in current RSS.\n");
+        }
+        lastBuildDateCurrent = lastBuildDateCurrentElement->GetText();
+        
+        XMLElement* enclosureElement = docCurrent.FirstChildElement("rss")->FirstChildElement("channel")->FirstChildElement("item")->FirstChildElement("enclosure");
+        if(NULL == enclosureElement)
+        {
+            fsusb30s = 1; // HSD2
+            error("No \"enclosure\" element in current RSS.\n");
+        }
+        mp3Url = enclosureElement->Attribute( "url" );
+        mp3Length = enclosureElement->Attribute( "length" );
     }
-    else
-    {
-        lastBuildDateCurrent = lastBuildDateCurrentElement->GetText();
-    }
+    cout << endl << "lastBuildDate (current) : " << lastBuildDateCurrent << endl;
     
-    printf("\n");
-    printf("lastBuildDate (original): %s\n", lastBuildDateOriginal);
-    printf("lastBuildDate (current) : %s\n", lastBuildDateCurrent);
-    
-    // Download new MP3
-    if (strcmp(lastBuildDateOriginal, lastBuildDateCurrent) == 0)
+    // Determine the necessity of downloading new MP3.
+    bool flgDownloadMp3 = false;
+    if (lastBuildDateOriginal == lastBuildDateCurrent)
     {
-        printf("lastBuildDate (original) == lastBuildDate (current)\n");
+        cout << "lastBuildDate (original) == lastBuildDate (current)" << endl;
         FILE* mp3fp = fopen(mp3Path, "r"); // check an existance of english.mp3
         if (mp3fp != NULL)
         {
+            fseek(mp3fp, 0, SEEK_END); // seek to end of file
+            if (ftell(mp3fp) != atol(mp3Length.c_str()))
+            {
+                cout << "MP3 file size is invalid." << endl;
+                flgDownloadMp3 = true;
+            }
             fclose(mp3fp);
         }
         else
         {
-            printf("However, no enlish.mp3 in USB memory\n");
+            cout << "However, no enlish.mp3 in USB memory" << endl;
+            flgDownloadMp3 = true;
         }
     }
     else
     {
-        printf("lastBuildDate (original) != lastBuildDate (current)\n");
-        XMLElement* enclosureElement = docCurrent.FirstChildElement("rss")->FirstChildElement("channel")->FirstChildElement("item")->FirstChildElement("enclosure");
-        if(NULL == enclosureElement)
-        {
-            printf("No \"enclosure\" element in RSS");
-        }
-        else
-        {
-            const char* mp3Url = enclosureElement->Attribute( "url" );
-            GetFile(mp3Path, mp3Url);
-        }
+        cout << "lastBuildDate (original) != lastBuildDate (current)" << endl;
+        flgDownloadMp3 = true;
     }
     
+    // Download new MP3
+    if(flgDownloadMp3 == true)
+    {
+        GetFile(mp3Path, mp3Url.c_str());
+    }
+    
+    // Wait for the completion of writing to USB Mass Storage Device.
+    wait(1);
+    
     // FSUSB30 switches to HSD2 (External Device)
-    printf("\nUSB host was switched to HSD2(External Device).\n");
+    cout << endl << "USB host was switched to HSD2(External Device)." << endl;
     fsusb30s = 1; // HSD2
 
     // blink LED
@@ -118,24 +148,27 @@
 
 int GetFile(const char *path, const char *url)
 {
-    HTTPFile file(path);
-    printf("\nGetting %s\n", url);
+    led2.startBlink();
+    cout << endl << "Getting " << url << endl;
     
     timer.stop();
     timer.reset();
     timer.start();
     
+    HTTPFile file(path);
     HTTPResult retGet = http.get(url, &file);
-    if (retGet != HTTP_OK) {
+    if (retGet != HTTP_OK)
+    {
         // FSUSB30 switches to HSD2 (External Device)
-        printf("USB host was switched to HSD2(External Device).\n");
+        cout << "USB host was switched to HSD2(External Device)." << endl;
         fsusb30s = 1; // HSD2
         error("Error in http.get in GetFile(): %d\n", retGet);
     }
     file.clear();
     
     timer.stop();
-    printf("timer.read_ms(): %d\n", timer.read_ms());
-
+    cout << "timer.read_ms(): " << timer.read_ms() << endl;
+    
+    led2.finishBlink();
     return (0);
 }