Arduino Core API Library besed on mbed platform.

Dependents:   WeeESP8266 ESP8266_moj

Files at this revision

API Documentation at this revision

Comitter:
itead
Date:
Thu Feb 05 07:24:30 2015 +0000
Child:
1:2179048af332
Commit message:
First commit for ArduinoAPI library by Wu Pengfei<pengfei.wu@itead.cc>

Changed in this revision

ArduinoAPI.h Show annotated file Show diff for this revision Revisions of this file
ArduinoSerial.cpp Show annotated file Show diff for this revision Revisions of this file
ArduinoSerial.h Show annotated file Show diff for this revision Revisions of this file
Print.cpp Show annotated file Show diff for this revision Revisions of this file
Print.h Show annotated file Show diff for this revision Revisions of this file
WString.cpp Show annotated file Show diff for this revision Revisions of this file
WString.h Show annotated file Show diff for this revision Revisions of this file
itoas.cpp Show annotated file Show diff for this revision Revisions of this file
itoas.h Show annotated file Show diff for this revision Revisions of this file
time.cpp Show annotated file Show diff for this revision Revisions of this file
time.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ArduinoAPI.h	Thu Feb 05 07:24:30 2015 +0000
@@ -0,0 +1,10 @@
+#ifndef __ARDUINOAPI_H__
+#define __ARDUINOAPI_H__
+
+#include "itoas.h"
+#include "time.h"
+#include "WString.h"
+#include "Print.h"
+#include "ArduinoSerial.h"
+
+#endif /* #ifndef __ARDUINOAPI_H__ */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ArduinoSerial.cpp	Thu Feb 05 07:24:30 2015 +0000
@@ -0,0 +1,161 @@
+#include "ArduinoSerial.h"
+
+ArduinoSerialLinkedNode ArduinoSerial::ms_list_head = {NULL, NULL};
+unsigned int ArduinoSerial::ms_instance_counter = 0;
+
+void ArduinoSerial::uartIrqCallback(void) {
+    ArduinoSerialLinkedNode *p;
+    for (p = ms_list_head.next; p != &ms_list_head; p = p->next) {
+        if (p->data != NULL) {
+            while(p->data->readable()) {
+                p->data->writeChr(p->data->getc());
+            }
+        }
+    }
+}
+
+ArduinoSerial::ArduinoSerial(PinName tx, PinName rx):Serial(tx, rx) {
+    ms_instance_counter++;
+    if (ms_instance_counter == 1) {
+        initHeadNode(&ms_list_head);
+    }
+    
+    if (addNode(&ms_list_head, this) != NULL) {
+        this->attach(&uartIrqCallback);   
+    } else {
+    }
+}
+
+ArduinoSerial::~ArduinoSerial(void) {
+    ms_instance_counter--;
+    if (delNode(&ms_list_head, this) != NULL) {
+        this->attach(NULL); 
+    } else {
+    }
+}
+    
+void ArduinoSerial::begin(int baud_rate) {
+    baud(baud_rate);
+    flush();
+}
+    
+int ArduinoSerial::available(void) {
+    return (unsigned int)(ARDUINOSERIAL_BUFFER_SIZE + m_rx_buffer.head - m_rx_buffer.tail) % ARDUINOSERIAL_BUFFER_SIZE;
+}
+
+void ArduinoSerial::flush(void)
+{
+    memset(&m_rx_buffer, 0, sizeof(m_rx_buffer));
+}
+
+char ArduinoSerial::readChr(void) {
+    // if the head isn't ahead of the tail, we don't have any characters
+    if (m_rx_buffer.head == m_rx_buffer.tail) {
+        return (char)-1;
+    } else {
+        unsigned char c = m_rx_buffer.buffer[m_rx_buffer.tail];
+        m_rx_buffer.tail = (unsigned int)(m_rx_buffer.tail + 1) % ARDUINOSERIAL_BUFFER_SIZE;
+        return c;
+    }
+}
+
+void ArduinoSerial::setTimeout(unsigned long millisecond) {
+    m_find_timeout = millisecond;
+}
+
+bool ArduinoSerial::find(const char *str) {
+    bool ret = false;
+    String data;
+    char c;
+    unsigned long i;
+    for (i = 0; i < m_find_timeout; i++) {
+        while(available() > 0) {
+            c = readChr();
+            data += c;
+        }
+        if (data.indexOf(String(str)) != -1) {
+            ret = true;
+            break;
+        }
+        wait_ms(1);
+    }
+    return ret;
+}
+
+size_t ArduinoSerial::write(uint8_t data) {
+    putc(data);
+    return 1;
+}
+
+void ArduinoSerial::writeChr(unsigned char c) {
+    int i = (unsigned int)(m_rx_buffer.head + 1) % ARDUINOSERIAL_BUFFER_SIZE;
+
+    // if we should be storing the received character into the location
+    // just before the tail (meaning that the head would advance to the
+    // current location of the tail), we're about to overflow the buffer
+    // and so we don't write the character or advance the head.
+    if (i != m_rx_buffer.tail) {
+        m_rx_buffer.buffer[m_rx_buffer.head] = c;
+        m_rx_buffer.head = i;
+    }
+}
+
+ArduinoSerialLinkedNode *ArduinoSerial::initHeadNode(ArduinoSerialLinkedNode *head) {
+    if (head == NULL) {
+        return NULL;
+    }
+    head->data = NULL;
+    head->next = head;
+    return head;
+}
+
+ArduinoSerialLinkedNode *ArduinoSerial::addNode(ArduinoSerialLinkedNode *head, ArduinoSerial* data) {
+    ArduinoSerialLinkedNode *p;
+    ArduinoSerialLinkedNode *node = (ArduinoSerialLinkedNode *)malloc(sizeof(ArduinoSerialLinkedNode));
+    if (node == NULL) {
+        return NULL;
+    }
+    /* Setting node */
+    node->data = data;
+    node->next = head;
+    
+    /* Add node to tail */
+    for(p = head; p->next != head; p = p->next);
+    p->next = node;
+    
+    return head;
+}
+ArduinoSerialLinkedNode *ArduinoSerial::delNode(ArduinoSerialLinkedNode *head, ArduinoSerial* data) {
+    ArduinoSerialLinkedNode *p;
+    ArduinoSerialLinkedNode *prev;
+    
+    if (head == NULL) {
+        return NULL;
+    }
+    
+    prev = head, p = head->next; 
+    while(p != head) {
+        if (p->data == data) {
+            prev->next = p->next;
+            free(p);
+            p = prev->next;
+        } else {
+            prev = p;
+            p = p->next;    
+        }
+    }
+    return head;
+}
+ArduinoSerialLinkedNode *ArduinoSerial::findNode(ArduinoSerialLinkedNode *head, ArduinoSerial* data) {
+    ArduinoSerialLinkedNode *p;
+    if (head == NULL) {
+        return NULL;
+    }
+    
+    for (p = head->next; p != head; p = p->next) {
+        if (p->data == data) {
+            return p;
+        }
+    }
+    return NULL;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ArduinoSerial.h	Thu Feb 05 07:24:30 2015 +0000
@@ -0,0 +1,60 @@
+#ifndef __ARDUINOAPI_ARDUINOSERIAL_H__
+#define __ARDUINOAPI_ARDUINOSERIAL_H__
+
+#include "Print.h"
+#include "WString.h"
+
+typedef enum {
+    ARDUINOSERIAL_BUFFER_SIZE = 4096,
+} ArduinoSerialConstant;
+
+typedef struct {
+    unsigned char buffer[ARDUINOSERIAL_BUFFER_SIZE];
+    volatile unsigned int head;
+    volatile unsigned int tail;
+} ArduinoSerialRingBuffer;
+
+class ArduinoSerial;
+
+typedef struct ArduinoSerialLinkedNode{
+    ArduinoSerial* data;
+    struct ArduinoSerialLinkedNode *next;
+} ArduinoSerialLinkedNode;
+
+class ArduinoSerial: public Serial, public Print
+{
+public:
+    ArduinoSerial(PinName tx, PinName rx);
+    
+    virtual ~ArduinoSerial(void);
+    
+    void begin(int baud_rate);
+    
+    int available(void);
+
+    void flush(void);
+    
+    char readChr(void);
+    
+    void setTimeout(unsigned long millisecond);
+    
+    bool find(const char *str);
+    
+private:
+    static void uartIrqCallback(void);
+    static ArduinoSerialLinkedNode *initHeadNode(ArduinoSerialLinkedNode *head);
+    static ArduinoSerialLinkedNode *addNode(ArduinoSerialLinkedNode *head, ArduinoSerial* data);
+    static ArduinoSerialLinkedNode *delNode(ArduinoSerialLinkedNode *head, ArduinoSerial* data);
+    static ArduinoSerialLinkedNode *findNode(ArduinoSerialLinkedNode *head, ArduinoSerial* data);
+    
+    static ArduinoSerialLinkedNode ms_list_head;
+    static unsigned int ms_instance_counter;
+    
+    virtual size_t write(uint8_t data);
+    void writeChr(unsigned char c);
+ 
+    ArduinoSerialRingBuffer m_rx_buffer;
+    unsigned long m_find_timeout;
+};
+
+#endif /* #ifndef __ARDUINOAPI_ARDUINOSERIAL_H__ */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Print.cpp	Thu Feb 05 07:24:30 2015 +0000
@@ -0,0 +1,237 @@
+/*
+ Print.cpp - Base class that provides print() and println()
+ Copyright (c) 2008 David A. Mellis.  All right reserved.
+ 
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+ 
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Lesser General Public License for more details.
+ 
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ 
+ Modified 23 November 2006 by David A. Mellis
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#include "Print.h"
+
+// Public Methods //////////////////////////////////////////////////////////////
+
+/* default implementation: may be overridden */
+size_t Print::write(const uint8_t *buffer, size_t size)
+{
+  size_t n = 0;
+  while (size--) {
+    n += write(*buffer++);
+  }
+  return n;
+}
+
+
+size_t Print::print(const String &s)
+{
+  size_t n = 0;
+  for (uint16_t i = 0; i < s.length(); i++) {
+    n += write(s[i]);
+  }
+  return n;
+}
+
+size_t Print::print(const char str[])
+{
+  return write(str);
+}
+
+size_t Print::print(char c)
+{
+  return write(c);
+}
+
+size_t Print::print(unsigned char b, int base)
+{
+  return print((unsigned long) b, base);
+}
+
+size_t Print::print(int n, int base)
+{
+  return print((long) n, base);
+}
+
+size_t Print::print(unsigned int n, int base)
+{
+  return print((unsigned long) n, base);
+}
+
+size_t Print::print(long n, int base)
+{
+  if (base == 0) {
+    return write(n);
+  } else if (base == 10) {
+    if (n < 0) {
+      int t = print('-');
+      n = -n;
+      return printNumber(n, 10) + t;
+    }
+    return printNumber(n, 10);
+  } else {
+    return printNumber(n, base);
+  }
+}
+
+size_t Print::print(unsigned long n, int base)
+{
+  if (base == 0) return write(n);
+  else return printNumber(n, base);
+}
+
+size_t Print::print(double n, int digits)
+{
+  return printFloat(n, digits);
+}
+
+size_t Print::println(void)
+{
+  size_t n = print('\r');
+  n += print('\n');
+  return n;
+}
+
+size_t Print::println(const String &s)
+{
+  size_t n = print(s);
+  n += println();
+  return n;
+}
+
+size_t Print::println(const char c[])
+{
+  size_t n = print(c);
+  n += println();
+  return n;
+}
+
+size_t Print::println(char c)
+{
+  size_t n = print(c);
+  n += println();
+  return n;
+}
+
+size_t Print::println(unsigned char b, int base)
+{
+  size_t n = print(b, base);
+  n += println();
+  return n;
+}
+
+size_t Print::println(int num, int base)
+{
+  size_t n = print(num, base);
+  n += println();
+  return n;
+}
+
+size_t Print::println(unsigned int num, int base)
+{
+  size_t n = print(num, base);
+  n += println();
+  return n;
+}
+
+size_t Print::println(long num, int base)
+{
+  size_t n = print(num, base);
+  n += println();
+  return n;
+}
+
+size_t Print::println(unsigned long num, int base)
+{
+  size_t n = print(num, base);
+  n += println();
+  return n;
+}
+
+size_t Print::println(double num, int digits)
+{
+  size_t n = print(num, digits);
+  n += println();
+  return n;
+}
+
+// Private Methods /////////////////////////////////////////////////////////////
+
+size_t Print::printNumber(unsigned long n, uint8_t base) {
+  char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
+  char *str = &buf[sizeof(buf) - 1];
+
+  *str = '\0';
+
+  // prevent crash if called with base == 1
+  if (base < 2) base = 10;
+
+  do {
+    unsigned long m = n;
+    n /= base;
+    char c = m - base * n;
+    *--str = c < 10 ? c + '0' : c + 'A' - 10;
+  } while(n);
+
+  return write(str);
+}
+
+size_t Print::printFloat(double number, uint8_t digits) 
+{ 
+  size_t n = 0;
+  
+  if (isnan(number)) return print("nan");
+  if (isinf(number)) return print("inf");
+  if (number > 4294967040.0) return print ("ovf");  // constant determined empirically
+  if (number <-4294967040.0) return print ("ovf");  // constant determined empirically
+  
+  // Handle negative numbers
+  if (number < 0.0)
+  {
+     n += print('-');
+     number = -number;
+  }
+
+  // Round correctly so that print(1.999, 2) prints as "2.00"
+  double rounding = 0.5;
+  for (uint8_t i=0; i<digits; ++i)
+    rounding /= 10.0;
+  
+  number += rounding;
+
+  // Extract the integer part of the number and print it
+  unsigned long int_part = (unsigned long)number;
+  double remainder = number - (double)int_part;
+  n += print(int_part);
+
+  // Print the decimal point, but only if there are digits beyond
+  if (digits > 0) {
+    n += print("."); 
+  }
+
+  // Extract digits from the remainder one at a time
+  while (digits-- > 0)
+  {
+    remainder *= 10.0;
+    int toPrint = int(remainder);
+    n += print(toPrint);
+    remainder -= toPrint; 
+  } 
+  
+  return n;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Print.h	Thu Feb 05 07:24:30 2015 +0000
@@ -0,0 +1,78 @@
+/*
+  Print.h - Base class that provides print() and println()
+  Copyright (c) 2008 David A. Mellis.  All right reserved.
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef __ARDUINOAPI_PRINT_H__
+#define __ARDUINOAPI_PRINT_H__
+#ifdef __cplusplus
+
+#include <inttypes.h>
+#include <stdio.h> // for size_t
+
+#include "WString.h"
+
+
+#define DEC 10
+#define HEX 16
+#define OCT 8
+#define BIN 2
+
+class Print
+{
+  private:
+    int write_error;
+    size_t printNumber(unsigned long, uint8_t);
+    size_t printFloat(double, uint8_t);
+  protected:
+    void setWriteError(int err = 1) { write_error = err; }
+  public:
+    Print() : write_error(0) {}
+  
+    int getWriteError() { return write_error; }
+    void clearWriteError() { setWriteError(0); }
+  
+    virtual size_t write(uint8_t) = 0;
+    size_t write(const char *str) {
+      if (str == NULL) return 0;
+      return write((const uint8_t *)str, strlen(str));
+    }
+    virtual size_t write(const uint8_t *buffer, size_t size);
+    
+    size_t print(const String &);
+    size_t print(const char[]);
+    size_t print(char);
+    size_t print(unsigned char, int = DEC);
+    size_t print(int, int = DEC);
+    size_t print(unsigned int, int = DEC);
+    size_t print(long, int = DEC);
+    size_t print(unsigned long, int = DEC);
+    size_t print(double, int = 2);
+
+    size_t println(const String &s);
+    size_t println(const char[]);
+    size_t println(char);
+    size_t println(unsigned char, int = DEC);
+    size_t println(int, int = DEC);
+    size_t println(unsigned int, int = DEC);
+    size_t println(long, int = DEC);
+    size_t println(unsigned long, int = DEC);
+    size_t println(double, int = 2);
+    size_t println(void);
+};
+#endif  // __cplusplus
+#endif /* #ifndef __ARDUINOAPI_PRINT_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WString.cpp	Thu Feb 05 07:24:30 2015 +0000
@@ -0,0 +1,644 @@
+/*
+  WString.cpp - String library for Wiring & Arduino
+  ...mostly rewritten by Paul Stoffregen...
+  Copyright (c) 2009-10 Hernando Barragan.  All rights reserved.
+  Copyright 2011, Paul Stoffregen, paul@pjrc.com
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#include "WString.h"
+
+
+/*********************************************/
+/*  Constructors                             */
+/*********************************************/
+
+String::String(const char *cstr)
+{
+    init();
+    if (cstr) copy(cstr, strlen(cstr));
+}
+
+String::String(const String &value)
+{
+    init();
+    *this = value;
+}
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+String::String(String &&rval)
+{
+    init();
+    move(rval);
+}
+String::String(StringSumHelper &&rval)
+{
+    init();
+    move(rval);
+}
+#endif
+
+String::String(char c)
+{
+    init();
+    char buf[2];
+    buf[0] = c;
+    buf[1] = 0;
+    *this = buf;
+}
+
+String::String(unsigned char value, unsigned char base)
+{
+    init();
+    char buf[9];
+    utoa(value, buf, base);
+    *this = buf;
+}
+
+String::String(int value, unsigned char base)
+{
+    init();
+    char buf[18];
+    itoa(value, buf, base);
+    *this = buf;
+}
+
+String::String(unsigned int value, unsigned char base)
+{
+    init();
+    char buf[17];
+    utoa(value, buf, base);
+    *this = buf;
+}
+
+String::String(long value, unsigned char base)
+{
+    init();
+    char buf[34];
+    ltoa(value, buf, base);
+    *this = buf;
+}
+
+String::String(unsigned long value, unsigned char base)
+{
+    init();
+    char buf[33];
+    ultoa(value, buf, base);
+    *this = buf;
+}
+
+String::~String()
+{
+    free(buffer);
+}
+
+/*********************************************/
+/*  Memory Management                        */
+/*********************************************/
+
+inline void String::init(void)
+{
+    buffer = NULL;
+    capacity = 0;
+    len = 0;
+    flags = 0;
+}
+
+void String::invalidate(void)
+{
+    if (buffer) free(buffer);
+    buffer = NULL;
+    capacity = len = 0;
+}
+
+unsigned char String::reserve(unsigned int size)
+{
+    if (buffer && capacity >= size) return 1;
+    if (changeBuffer(size)) {
+        if (len == 0) buffer[0] = 0;
+        return 1;
+    }
+    return 0;
+}
+
+unsigned char String::changeBuffer(unsigned int maxStrLen)
+{
+    char *newbuffer = (char *)realloc(buffer, maxStrLen + 1);
+    if (newbuffer) {
+        buffer = newbuffer;
+        capacity = maxStrLen;
+        return 1;
+    }
+    return 0;
+}
+
+/*********************************************/
+/*  Copy and Move                            */
+/*********************************************/
+
+String & String::copy(const char *cstr, unsigned int length)
+{
+    if (!reserve(length)) {
+        invalidate();
+        return *this;
+    }
+    len = length;
+    strcpy(buffer, cstr);
+    return *this;
+}
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+void String::move(String &rhs)
+{
+    if (buffer) {
+        if (capacity >= rhs.len) {
+            strcpy(buffer, rhs.buffer);
+            len = rhs.len;
+            rhs.len = 0;
+            return;
+        } else {
+            free(buffer);
+        }
+    }
+    buffer = rhs.buffer;
+    capacity = rhs.capacity;
+    len = rhs.len;
+    rhs.buffer = NULL;
+    rhs.capacity = 0;
+    rhs.len = 0;
+}
+#endif
+
+String & String::operator = (const String &rhs)
+{
+    if (this == &rhs) return *this;
+    
+    if (rhs.buffer) copy(rhs.buffer, rhs.len);
+    else invalidate();
+    
+    return *this;
+}
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+String & String::operator = (String &&rval)
+{
+    if (this != &rval) move(rval);
+    return *this;
+}
+
+String & String::operator = (StringSumHelper &&rval)
+{
+    if (this != &rval) move(rval);
+    return *this;
+}
+#endif
+
+String & String::operator = (const char *cstr)
+{
+    if (cstr) copy(cstr, strlen(cstr));
+    else invalidate();
+    
+    return *this;
+}
+
+/*********************************************/
+/*  concat                                   */
+/*********************************************/
+
+unsigned char String::concat(const String &s)
+{
+    return concat(s.buffer, s.len);
+}
+
+unsigned char String::concat(const char *cstr, unsigned int length)
+{
+    unsigned int newlen = len + length;
+    if (!cstr) return 0;
+    if (length == 0) return 1;
+    if (!reserve(newlen)) return 0;
+    strcpy(buffer + len, cstr);
+    len = newlen;
+    return 1;
+}
+
+unsigned char String::concat(const char *cstr)
+{
+    if (!cstr) return 0;
+    return concat(cstr, strlen(cstr));
+}
+
+unsigned char String::concat(char c)
+{
+    char buf[2];
+    buf[0] = c;
+    buf[1] = 0;
+    return concat(buf, 1);
+}
+
+unsigned char String::concat(unsigned char num)
+{
+    char buf[4];
+    itoa(num, buf, 10);
+    return concat(buf, strlen(buf));
+}
+
+unsigned char String::concat(int num)
+{
+    char buf[7];
+    itoa(num, buf, 10);
+    return concat(buf, strlen(buf));
+}
+
+unsigned char String::concat(unsigned int num)
+{
+    char buf[6];
+    utoa(num, buf, 10);
+    return concat(buf, strlen(buf));
+}
+
+unsigned char String::concat(long num)
+{
+    char buf[12];
+    ltoa(num, buf, 10);
+    return concat(buf, strlen(buf));
+}
+
+unsigned char String::concat(unsigned long num)
+{
+    char buf[11];
+    ultoa(num, buf, 10);
+    return concat(buf, strlen(buf));
+}
+
+/*********************************************/
+/*  Concatenate                              */
+/*********************************************/
+
+StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs)
+{
+    StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
+    if (!a.concat(rhs.buffer, rhs.len)) a.invalidate();
+    return a;
+}
+
+StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr)
+{
+    StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
+    if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate();
+    return a;
+}
+
+StringSumHelper & operator + (const StringSumHelper &lhs, char c)
+{
+    StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
+    if (!a.concat(c)) a.invalidate();
+    return a;
+}
+
+StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num)
+{
+    StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
+    if (!a.concat(num)) a.invalidate();
+    return a;
+}
+
+StringSumHelper & operator + (const StringSumHelper &lhs, int num)
+{
+    StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
+    if (!a.concat(num)) a.invalidate();
+    return a;
+}
+
+StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num)
+{
+    StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
+    if (!a.concat(num)) a.invalidate();
+    return a;
+}
+
+StringSumHelper & operator + (const StringSumHelper &lhs, long num)
+{
+    StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
+    if (!a.concat(num)) a.invalidate();
+    return a;
+}
+
+StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num)
+{
+    StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
+    if (!a.concat(num)) a.invalidate();
+    return a;
+}
+
+/*********************************************/
+/*  Comparison                               */
+/*********************************************/
+
+int String::compareTo(const String &s) const
+{
+    if (!buffer || !s.buffer) {
+        if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer;
+        if (buffer && len > 0) return *(unsigned char *)buffer;
+        return 0;
+    }
+    return strcmp(buffer, s.buffer);
+}
+
+unsigned char String::equals(const String &s2) const
+{
+    return (len == s2.len && compareTo(s2) == 0);
+}
+
+unsigned char String::equals(const char *cstr) const
+{
+    if (len == 0) return (cstr == NULL || *cstr == 0);
+    if (cstr == NULL) return buffer[0] == 0;
+    return strcmp(buffer, cstr) == 0;
+}
+
+unsigned char String::operator<(const String &rhs) const
+{
+    return compareTo(rhs) < 0;
+}
+
+unsigned char String::operator>(const String &rhs) const
+{
+    return compareTo(rhs) > 0;
+}
+
+unsigned char String::operator<=(const String &rhs) const
+{
+    return compareTo(rhs) <= 0;
+}
+
+unsigned char String::operator>=(const String &rhs) const
+{
+    return compareTo(rhs) >= 0;
+}
+
+unsigned char String::equalsIgnoreCase( const String &s2 ) const
+{
+    if (this == &s2) return 1;
+    if (len != s2.len) return 0;
+    if (len == 0) return 1;
+    const char *p1 = buffer;
+    const char *p2 = s2.buffer;
+    while (*p1) {
+        if (tolower(*p1++) != tolower(*p2++)) return 0;
+    } 
+    return 1;
+}
+
+unsigned char String::startsWith( const String &s2 ) const
+{
+    if (len < s2.len) return 0;
+    return startsWith(s2, 0);
+}
+
+unsigned char String::startsWith( const String &s2, unsigned int offset ) const
+{
+    if (offset > len - s2.len || !buffer || !s2.buffer) return 0;
+    return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0;
+}
+
+unsigned char String::endsWith( const String &s2 ) const
+{
+    if ( len < s2.len || !buffer || !s2.buffer) return 0;
+    return strcmp(&buffer[len - s2.len], s2.buffer) == 0;
+}
+
+/*********************************************/
+/*  Character Access                         */
+/*********************************************/
+
+char String::charAt(unsigned int loc) const
+{
+    return operator[](loc);
+}
+
+void String::setCharAt(unsigned int loc, char c) 
+{
+    if (loc < len) buffer[loc] = c;
+}
+
+char & String::operator[](unsigned int index)
+{
+    static char dummy_writable_char;
+    if (index >= len || !buffer) {
+        dummy_writable_char = 0;
+        return dummy_writable_char;
+    }
+    return buffer[index];
+}
+
+char String::operator[]( unsigned int index ) const
+{
+    if (index >= len || !buffer) return 0;
+    return buffer[index];
+}
+
+void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const
+{
+    if (!bufsize || !buf) return;
+    if (index >= len) {
+        buf[0] = 0;
+        return;
+    }
+    unsigned int n = bufsize - 1;
+    if (n > len - index) n = len - index;
+    strncpy((char *)buf, buffer + index, n);
+    buf[n] = 0;
+}
+
+/*********************************************/
+/*  Search                                   */
+/*********************************************/
+
+int String::indexOf(char c) const
+{
+    return indexOf(c, 0);
+}
+
+int String::indexOf( char ch, unsigned int fromIndex ) const
+{
+    if (fromIndex >= len) return -1;
+    const char* temp = strchr(buffer + fromIndex, ch);
+    if (temp == NULL) return -1;
+    return temp - buffer;
+}
+
+int String::indexOf(const String &s2) const
+{
+    return indexOf(s2, 0);
+}
+
+int String::indexOf(const String &s2, unsigned int fromIndex) const
+{
+    if (fromIndex >= len) return -1;
+    const char *found = strstr(buffer + fromIndex, s2.buffer);
+    if (found == NULL) return -1;
+    return found - buffer;
+}
+
+int String::lastIndexOf( char theChar ) const
+{
+    return lastIndexOf(theChar, len - 1);
+}
+
+int String::lastIndexOf(char ch, unsigned int fromIndex) const
+{
+    if (fromIndex >= len) return -1;
+    char tempchar = buffer[fromIndex + 1];
+    buffer[fromIndex + 1] = '\0';
+    char* temp = strrchr( buffer, ch );
+    buffer[fromIndex + 1] = tempchar;
+    if (temp == NULL) return -1;
+    return temp - buffer;
+}
+
+int String::lastIndexOf(const String &s2) const
+{
+    return lastIndexOf(s2, len - s2.len);
+}
+
+int String::lastIndexOf(const String &s2, unsigned int fromIndex) const
+{
+    if (s2.len == 0 || len == 0 || s2.len > len) return -1;
+    if (fromIndex >= len) fromIndex = len - 1;
+    int found = -1;
+    for (char *p = buffer; p <= buffer + fromIndex; p++) {
+        p = strstr(p, s2.buffer);
+        if (!p) break;
+        if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer;
+    }
+    return found;
+}
+
+String String::substring( unsigned int left ) const
+{
+    return substring(left, len);
+}
+
+String String::substring(unsigned int left, unsigned int right) const
+{
+    if (left > right) {
+        unsigned int temp = right;
+        right = left;
+        left = temp;
+    }
+    String out;
+    if (left > len) return out;
+    if (right > len) right = len;
+    char temp = buffer[right];  // save the replaced character
+    buffer[right] = '\0';   
+    out = buffer + left;  // pointer arithmetic
+    buffer[right] = temp;  //restore character
+    return out;
+}
+
+/*********************************************/
+/*  Modification                             */
+/*********************************************/
+
+void String::replace(char find, char replace)
+{
+    if (!buffer) return;
+    for (char *p = buffer; *p; p++) {
+        if (*p == find) *p = replace;
+    }
+}
+
+void String::replace(const String& find, const String& replace)
+{
+    if (len == 0 || find.len == 0) return;
+    int diff = replace.len - find.len;
+    char *readFrom = buffer;
+    char *foundAt;
+    if (diff == 0) {
+        while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
+            memcpy(foundAt, replace.buffer, replace.len);
+            readFrom = foundAt + replace.len;
+        }
+    } else if (diff < 0) {
+        char *writeTo = buffer;
+        while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
+            unsigned int n = foundAt - readFrom;
+            memcpy(writeTo, readFrom, n);
+            writeTo += n;
+            memcpy(writeTo, replace.buffer, replace.len);
+            writeTo += replace.len;
+            readFrom = foundAt + find.len;
+            len += diff;
+        }
+        strcpy(writeTo, readFrom);
+    } else {
+        unsigned int size = len; // compute size needed for result
+        while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
+            readFrom = foundAt + find.len;
+            size += diff;
+        }
+        if (size == len) return;
+        if (size > capacity && !changeBuffer(size)) return; // XXX: tell user!
+        int index = len - 1;
+        while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) {
+            readFrom = buffer + index + find.len;
+            memmove(readFrom + diff, readFrom, len - (readFrom - buffer));
+            len += diff;
+            buffer[len] = 0;
+            memcpy(buffer + index, replace.buffer, replace.len);
+            index--;
+        }
+    }
+}
+
+void String::toLowerCase(void)
+{
+    if (!buffer) return;
+    for (char *p = buffer; *p; p++) {
+        *p = tolower(*p);
+    }
+}
+
+void String::toUpperCase(void)
+{
+    if (!buffer) return;
+    for (char *p = buffer; *p; p++) {
+        *p = toupper(*p);
+    }
+}
+
+void String::trim(void)
+{
+    if (!buffer || len == 0) return;
+    char *begin = buffer;
+    while (isspace(*begin)) begin++;
+    char *end = buffer + len - 1;
+    while (isspace(*end) && end >= begin) end--;
+    len = end + 1 - begin;
+    if (begin > buffer) memcpy(buffer, begin, len);
+    buffer[len] = 0;
+}
+
+/*********************************************/
+/*  Parsing / Conversion                     */
+/*********************************************/
+
+long String::toInt(void) const
+{
+    if (buffer) return atol(buffer);
+    return 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WString.h	Thu Feb 05 07:24:30 2015 +0000
@@ -0,0 +1,203 @@
+/*
+  WString.h - String library for Wiring & Arduino
+  ...mostly rewritten by Paul Stoffregen...
+  Copyright (c) 2009-10 Hernando Barragan.  All right reserved.
+  Copyright 2011, Paul Stoffregen, paul@pjrc.com
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef __ARDUINOAPI_WSTRING_H__
+#define __ARDUINOAPI_WSTRING_H__
+#ifdef __cplusplus
+
+#include "mbed.h"
+
+#include "itoas.h"
+
+#include <ctype.h>
+#include <cstddef>
+#include <cstdlib>
+#include <cstdio>
+#include <cstring>
+
+
+// An inherited class for holding the result of a concatenation.  These
+// result objects are assumed to be writable by subsequent concatenations.
+class StringSumHelper;
+
+// The string class
+class String
+{
+    // use a function pointer to allow for "if (s)" without the
+    // complications of an operator bool(). for more information, see:
+    // http://www.artima.com/cppsource/safebool.html
+    typedef void (String::*StringIfHelperType)() const;
+    void StringIfHelper() const {}
+
+public:
+    // constructors
+    // creates a copy of the initial value.
+    // if the initial value is null or invalid, or if memory allocation
+    // fails, the string will be marked as invalid (i.e. "if (s)" will
+    // be false).
+    String(const char *cstr = "");
+    String(const String &str);
+    #ifdef __GXX_EXPERIMENTAL_CXX0X__
+    String(String &&rval);
+    String(StringSumHelper &&rval);
+    #endif
+    explicit String(char c);
+    explicit String(unsigned char, unsigned char base=10);
+    explicit String(int, unsigned char base=10);
+    explicit String(unsigned int, unsigned char base=10);
+    explicit String(long, unsigned char base=10);
+    explicit String(unsigned long, unsigned char base=10);
+    ~String(void);
+
+    // memory management
+    // return true on success, false on failure (in which case, the string
+    // is left unchanged).  reserve(0), if successful, will validate an
+    // invalid string (i.e., "if (s)" will be true afterwards)
+    unsigned char reserve(unsigned int size);
+    inline unsigned int length(void) const {return len;}
+
+    // creates a copy of the assigned value.  if the value is null or
+    // invalid, or if the memory allocation fails, the string will be 
+    // marked as invalid ("if (s)" will be false).
+    String & operator = (const String &rhs);
+    String & operator = (const char *cstr);
+    #ifdef __GXX_EXPERIMENTAL_CXX0X__
+    String & operator = (String &&rval);
+    String & operator = (StringSumHelper &&rval);
+    #endif
+
+    // concatenate (works w/ built-in types)
+    
+    // returns true on success, false on failure (in which case, the string
+    // is left unchanged).  if the argument is null or invalid, the 
+    // concatenation is considered unsucessful.  
+    unsigned char concat(const String &str);
+    unsigned char concat(const char *cstr);
+    unsigned char concat(char c);
+    unsigned char concat(unsigned char c);
+    unsigned char concat(int num);
+    unsigned char concat(unsigned int num);
+    unsigned char concat(long num);
+    unsigned char concat(unsigned long num);
+    
+    // if there's not enough memory for the concatenated value, the string
+    // will be left unchanged (but this isn't signalled in any way)
+    String & operator += (const String &rhs)    {concat(rhs); return (*this);}
+    String & operator += (const char *cstr)     {concat(cstr); return (*this);}
+    String & operator += (char c)           {concat(c); return (*this);}
+    String & operator += (unsigned char num)        {concat(num); return (*this);}
+    String & operator += (int num)          {concat(num); return (*this);}
+    String & operator += (unsigned int num)     {concat(num); return (*this);}
+    String & operator += (long num)         {concat(num); return (*this);}
+    String & operator += (unsigned long num)    {concat(num); return (*this);}
+
+    friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs);
+    friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr);
+    friend StringSumHelper & operator + (const StringSumHelper &lhs, char c);
+    friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num);
+    friend StringSumHelper & operator + (const StringSumHelper &lhs, int num);
+    friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num);
+    friend StringSumHelper & operator + (const StringSumHelper &lhs, long num);
+    friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num);
+
+    // comparison (only works w/ Strings and "strings")
+    operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; }
+    int compareTo(const String &s) const;
+    unsigned char equals(const String &s) const;
+    unsigned char equals(const char *cstr) const;
+    unsigned char operator == (const String &rhs) const {return equals(rhs);}
+    unsigned char operator == (const char *cstr) const {return equals(cstr);}
+    unsigned char operator != (const String &rhs) const {return !equals(rhs);}
+    unsigned char operator != (const char *cstr) const {return !equals(cstr);}
+    unsigned char operator <  (const String &rhs) const;
+    unsigned char operator >  (const String &rhs) const;
+    unsigned char operator <= (const String &rhs) const;
+    unsigned char operator >= (const String &rhs) const;
+    unsigned char equalsIgnoreCase(const String &s) const;
+    unsigned char startsWith( const String &prefix) const;
+    unsigned char startsWith(const String &prefix, unsigned int offset) const;
+    unsigned char endsWith(const String &suffix) const;
+
+    // character acccess
+    char charAt(unsigned int index) const;
+    void setCharAt(unsigned int index, char c);
+    char operator [] (unsigned int index) const;
+    char& operator [] (unsigned int index);
+    void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const;
+    void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const
+        {getBytes((unsigned char *)buf, bufsize, index);}
+    const char * c_str() const { return buffer; }
+
+    // search
+    int indexOf( char ch ) const;
+    int indexOf( char ch, unsigned int fromIndex ) const;
+    int indexOf( const String &str ) const;
+    int indexOf( const String &str, unsigned int fromIndex ) const;
+    int lastIndexOf( char ch ) const;
+    int lastIndexOf( char ch, unsigned int fromIndex ) const;
+    int lastIndexOf( const String &str ) const;
+    int lastIndexOf( const String &str, unsigned int fromIndex ) const;
+    String substring( unsigned int beginIndex ) const;
+    String substring( unsigned int beginIndex, unsigned int endIndex ) const;
+
+    // modification
+    void replace(char find, char replace);
+    void replace(const String& find, const String& replace);
+    void toLowerCase(void);
+    void toUpperCase(void);
+    void trim(void);
+
+    // parsing/conversion
+    long toInt(void) const;
+
+protected:
+    char *buffer;           // the actual char array
+    unsigned int capacity;  // the array length minus one (for the '\0')
+    unsigned int len;       // the String length (not counting the '\0')
+    unsigned char flags;    // unused, for future features
+protected:
+    void init(void);
+    void invalidate(void);
+    unsigned char changeBuffer(unsigned int maxStrLen);
+    unsigned char concat(const char *cstr, unsigned int length);
+
+    // copy and move
+    String & copy(const char *cstr, unsigned int length);
+    #ifdef __GXX_EXPERIMENTAL_CXX0X__
+    void move(String &rhs);
+    #endif
+};
+
+class StringSumHelper : public String
+{
+public:
+    StringSumHelper(const String &s) : String(s) {}
+    StringSumHelper(const char *p) : String(p) {}
+    StringSumHelper(char c) : String(c) {}
+    StringSumHelper(unsigned char num) : String(num) {}
+    StringSumHelper(int num) : String(num) {}
+    StringSumHelper(unsigned int num) : String(num) {}
+    StringSumHelper(long num) : String(num) {}
+    StringSumHelper(unsigned long num) : String(num) {}
+};
+
+#endif  // __cplusplus
+#endif  // __ARDUINOAPI_WSTRING_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/itoas.cpp	Thu Feb 05 07:24:30 2015 +0000
@@ -0,0 +1,88 @@
+#include "itoas.h"
+
+char* ltoa( long value, char *string, int radix )
+{
+  char tmp[33];
+  char *tp = tmp;
+  long i;
+  unsigned long v;
+  int sign;
+  char *sp;
+  if ( string == NULL )
+  {
+    return 0 ;
+  }
+  if (radix > 36 || radix <= 1)
+  {
+    return 0 ;
+  }
+  sign = (radix == 10 && value < 0);
+  if (sign)
+  {
+    v = -value;
+  }
+  else
+  {
+    v = (unsigned long)value;
+  }
+  while (v || tp == tmp)
+  {
+    i = v % radix;
+    v = v / radix;
+    if (i < 10)
+      *tp++ = i+'0';
+    else
+      *tp++ = i + 'a' - 10;
+  }
+  sp = string;
+  if (sign)
+    *sp++ = '-';
+  while (tp > tmp)
+    *sp++ = *--tp;
+  *sp = 0;
+  return string;
+}
+
+char* ultoa( unsigned long value, char *string, int radix )
+{
+  char tmp[33];
+  char *tp = tmp;
+  long i;
+  unsigned long v = value;
+  char *sp;
+  if ( string == NULL )
+  {
+    return 0;
+  }
+  if (radix > 36 || radix <= 1)
+  {
+    return 0;
+  }
+ 
+  while (v || tp == tmp)
+  {
+    i = v % radix;
+    v = v / radix;
+    if (i < 10)
+      *tp++ = i+'0';
+    else
+      *tp++ = i + 'a' - 10;
+  }
+  sp = string;
+ 
+  while (tp > tmp)
+    *sp++ = *--tp;
+  *sp = 0;
+  return string;
+}
+
+
+char* itoa( int value, char *string, int radix )
+{
+  return ltoa( value, string, radix ) ;
+}
+
+char* utoa( unsigned long value, char *string, int radix )
+{
+  return ultoa( value, string, radix ) ;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/itoas.h	Thu Feb 05 07:24:30 2015 +0000
@@ -0,0 +1,11 @@
+#ifndef __ARDUINOAPI_ITOAS_H__
+#define __ARDUINOAPI_ITOAS_H__
+
+#include "cstdlib"
+
+char* utoa( unsigned long value, char *string, int radix );
+char* itoa( int value, char *string, int radix );
+char* ultoa( unsigned long value, char *string, int radix );
+char* ltoa( long value, char *string, int radix );
+
+#endif /* #ifndef __ARDUINOAPI_ITOAS_H__ */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/time.cpp	Thu Feb 05 07:24:30 2015 +0000
@@ -0,0 +1,21 @@
+#include "time.h"
+
+static unsigned long one_millisecond_counter = 0;
+static void one_millisecond_callback(void) {
+    one_millisecond_counter++;
+}
+
+unsigned long millis(void) {
+    static Ticker milli_timer;
+    static bool attach_flag = true;
+    if (attach_flag) {
+        attach_flag = false;
+        milli_timer.attach_us(&one_millisecond_callback, 1000);
+    }
+    return one_millisecond_counter;
+}
+
+void delay(int t)
+{
+    wait_ms(t);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/time.h	Thu Feb 05 07:24:30 2015 +0000
@@ -0,0 +1,9 @@
+#ifndef _ARDUINOAPI_TIME_H__
+#define _ARDUINOAPI_TIME_H__
+
+#include "mbed.h"
+
+unsigned long millis(void);
+void delay(int t);
+
+#endif /*  _ARDUINOAPI_TIME_H__ */
\ No newline at end of file