データの保存、更新、取得ができるWebサービス「milkcocoa」に接続し、データのプッシュ、送信、取得ができるライブラリです。EthernetIF版 https://mlkcca.com/
Dependents: MilkcocoaSample_Eth_tmp MilkcocoaSample_Eth uhuru_hallowin2
Fork of Milkcocoa by
Revision 1:4a634c06c5dc, committed 2015-12-18
- Comitter:
- jksoft
- Date:
- Fri Dec 18 04:30:59 2015 +0000
- Parent:
- 0:23e533c4b1ec
- Child:
- 2:a174c8a8d53e
- Commit message:
- ???EthernetIF???????????????????subscribe????
Changed in this revision
--- a/ESP8266InterfaceTiny/ESP8266/CBuffer.h Tue Dec 15 09:56:32 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -/* Copyright (C) 2012 mbed.org, MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef CIRCBUFFER_H_ -#define CIRCBUFFER_H_ - -template <class T> -class CircBuffer { -public: - CircBuffer(int length) { - write = 0; - read = 0; - size = length + 1; - buf = (T *)malloc(size * sizeof(T)); - }; - - bool isFull() { - return (((write + 1) % size) == read); - }; - - bool isEmpty() { - return (read == write); - }; - - void queue(T k) { - if (isFull()) { - read++; - read %= size; - } - buf[write++] = k; - write %= size; - } - - void flush() { - read = 0; - write = 0; - } - - - uint32_t available() { - return (write >= read) ? write - read : size - read + write; - }; - - bool dequeue(T * c) { - bool empty = isEmpty(); - if (!empty) { - *c = buf[read++]; - read %= size; - } - return(!empty); - }; - -private: - volatile uint32_t write; - volatile uint32_t read; - uint32_t size; - T * buf; -}; - -#endif
--- a/ESP8266InterfaceTiny/ESP8266/ESP8266.cpp Tue Dec 15 09:56:32 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,523 +0,0 @@ -/* Copyright (C) 2012 mbed.org, MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "mbed.h" -#include "ESP8266.h" -#include "Endpoint.h" -#include "SoftSerialSendOnry.h" - -extern SoftSerialSendOnry pc; - -//#include <string> -//#include <algorithm> - -//Debug is disabled by default -#if 0 -#define DBG(x, ...) pc.printf("[ESP8266 : DBG]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); -#define WARN(x, ...) pc.printf("[ESP8266 : WARN]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); -#define ERR(x, ...) pc.printf("[ESP8266 : ERR]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); -#else -#define DBG(x, ...) //wait_us(10); -#define WARN(x, ...) //wait_us(10); -#define ERR(x, ...) -#endif - -#if 0 -#define INFO(x, ...) printf("[ESP8266 : INFO]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); -#else -#define INFO(x, ...) -#endif - -#define ESP_MAX_TRY_JOIN 3 -#define ESP_MAXID 4 // the largest possible ID Value (max num of sockets possible) - -ESP8266 * ESP8266::inst; -char* ip = NULL; - -ESP8266::ESP8266(PinName tx, PinName rx, PinName reset, const char *ssid, const char *phrase, uint32_t baud) : - wifi(tx, rx), reset_pin(reset), buf_ESP8266(ESP_MBUFFE_MAX) -{ - INFO("Initializing ESP8266 object"); - memset(&state, 0, sizeof(state)); - - - strcpy(this->ssid, ssid); - strcpy(this->phrase, phrase); - inst = this; - attach_rx(false); - - wifi.baud(baud); // initial baud rate of the ESP8266 - - state.associated = false; - state.cmdMode = false; -} - -bool ESP8266::join() -{ - char cmd[100]; - sendCommand( "AT+CWMODE=1", "change", NULL, 1000); - //string cmd="AT+CWJAP=\""+(string)this->ssid+"\",\""+(string)this->phrase+"\""; - sprintf(cmd,"AT+CWJAP=\"%s\",\"%s\"",this->ssid,this->phrase); - if( sendCommand( cmd, "OK", NULL, 10000) ) { - // successfully joined the network - state.associated = true; - INFO("ssid: %s, phrase: %s", this->ssid, this->phrase); - return true; - } - return false; -} - -bool ESP8266::connect() -{ - sendCommand("AT+CWDHCP=1,1","OK",NULL,1000); // DHCP Enabled in Station Mode - return ESP8266::join(); -} - -bool ESP8266::is_connected() -{ - return true; -} - -bool ESP8266::start(bool type,char* ip, int port, int id) -{ - char cmd[256]; - // Error Check - if(id > ESP_MAXID) { - ERR("startUDPMulti: max id is: %d, id given is %d",ESP_MAXID,id); - return false; - } - // Single Connection Mode - if(id < 0) { - DBG("Start Single Connection Mode"); - //char portstr[5]; - bool check [3] = {0}; - //sprintf(portstr, "%d", port); - switch(type) { - case ESP_UDP_TYPE : //UDP - sprintf(cmd,"AT+CIPSTART=\"UDP\",\"%s\",%d",ip,port); - check[0] = sendCommand(cmd, "OK", NULL, 10000); - //check[0] = sendCommand(( "AT+CIPSTART=\"UDP\",\"" + (string) ip + "\"," + (string) portstr ).c_str(), "OK", NULL, 10000); - break; - case ESP_TCP_TYPE : //TCP - sprintf(cmd,"AT+CIPSTART=\"TCP\",\"%s\",%d",ip,port); - check[0] = sendCommand(cmd, "OK", NULL, 10000); - //check[0] = sendCommand(( "AT+CIPSTART=\"TCP\",\"" + (string) ip + "\"," + (string) portstr ).c_str(), "OK", NULL, 10000); - break; - default: - ERR("Default hit for starting connection, this shouldnt be possible!!"); - break; - } - check[1] = sendCommand("AT+CIPMODE=1", "OK", NULL, 1000);// go into transparent mode - check[2] = sendCommand("AT+CIPSEND", ">", NULL, 1000);// go into transparent mode - // check that all commands were sucessful - if(check[0] and check[1] and check[2]) { - state.cmdMode = false; - return true; - } else { - ERR("startUDPTransparent Failed for ip:%s, port:%d",ip,port); - return false; - } - } - // Multi Connection Mode - else { - //TODO: impliment Multi Connection Mode - ERR("Not currently Supported!"); - return false; - } -} - -bool ESP8266::startUDP(char* ip, int port, int id, int length) -{ - char cmd[256]; - char portstr[5]; - char idstr[1]; - char lenstr[2]; - - sprintf(portstr, "%d", port); - sprintf(idstr, "%d", id); - sprintf(lenstr, "%d", length); - - sendCommand("AT+CIPMUX=1", "OK", NULL, 1000); - sprintf(cmd,"AT+CIPSTART=%d,\"UDP\",\"%s\",%d,1112,0",id,ip,port); - sendCommand(cmd, "OK", NULL, 10000); - //sendCommand(( "AT+CIPSTART=" + string(idstr) + ",\"UDP\",\"" + (string) ip + "\"," + (string) portstr + ",1112,0").c_str(), "OK", NULL, 10000); - sprintf(cmd,"AT+CIPSEND=%d,%d",id,length); - sendCommand(cmd, ">", NULL, 1000);// go into transparent mode - //sendCommand(("AT+CIPSEND=" + (string)idstr + "," + (string)lenstr).c_str(), ">", NULL, 1000);// go into transparent mode - DBG("Data Mode\r\n"); - state.cmdMode = false; - - return true; -} - -bool ESP8266::startTCPServer(int port) -{ - char cmd[100]; - bool command_results[3]; - command_results[0]=sendCommand("AT+CWMODE=3", "OK", NULL, 1000); - command_results[1]=sendCommand("AT+CIPMUX=1", "OK", NULL, 1000); - if(port == 333){ - command_results[2]=sendCommand("AT+CIPSERVER=1", "OK", NULL, 1000); - } - else{ - sprintf(cmd,"AT+CIPSERVER=1,%d",port); - command_results[2]=sendCommand(cmd, "OK", NULL, 1000); - } - //sendCommand("AT+CIFSR", "OK", NULL, 1000); - DBG("Data Mode\r\n"); - state.cmdMode = false; - if (command_results[0] and command_results[1] and command_results[2]){ - return true; - } - else{ - return false; - } -} - -bool ESP8266::close() -{ - wait(0.1f); - send("+++",3); - wait(1.0f); - state.cmdMode = true; - sendCommand("AT+CIPCLOSE","OK", NULL, 10000); - return true; -} - -bool ESP8266::disconnect() -{ - // if already disconnected, return - if (!state.associated) - return true; - // send command to quit AP - sendCommand("AT+CWQAP", "OK", NULL, 10000); - state.associated = false; - return true; -} - -int ESP8266::strfind(const char *str,const char *chkstr,int pos) -{ - if( (strlen(str)-pos) < strlen(chkstr) ) return(-1); - - - for(int i=pos;i<strlen(str);i++) - { - if(memcmp(chkstr,&str[i],strlen(chkstr))==0) - { - return(i); - } - } - return(-1); -} - -char* ESP8266::substr(const char *str , char *outstr , int pos1 , int pos2 ) -{ - int size = pos2 - pos1; - - memcpy(outstr , &str[pos1] , size ); - outstr[size] = '\0'; - - return(outstr); -} - -int ESP8266::strcount(const char *str , char countstr ) -{ - int ret = 0; - - for(int i = 0 ; i < strlen(str) ; i++) - { - if( str[i] == countstr ) - { - ret++; - } - - } - - return(ret); -} - -/* - Assuming Returned data looks like this: - +CIFSR:STAIP,"192.168.11.2" - +CIFSR:STAMAC,"18:fe:34:9f:3a:f5" - grabbing IP from first set of quotation marks -*/ -char* ESP8266::getIPAddress() -{ - char result[30] = {0}; - char tmp[30] = {0}; - int check = 0; - check = sendCommand("AT+CIFSR", NULL, result, 1000); - //pc.printf("\r\nReceivedInfo for IP Command is: %s\r\n",result); - ip = ipString; - if(check) { - // Success - uint8_t pos1 = 0, pos2 = 0; - //uint8_t pos3 = 0, pos4 = 0; - pos1 = strfind(result,"+CIFSR:STAIP",0); - //pos1 = resultString.find("+CIFSR:STAIP"); - pos1 = strfind(result,"\"",pos1); - //pos1 = resultString.find('"',pos1); - pos2 = strfind(result,"\"",pos1+1); - //pos2 = resultString.find('"',pos1+1); - //pos3 = resultString.find('"',pos2+1); //would find mac address - //pos4 = resultString.find('"',pos3+1); - strncpy(ipString,substr(result,tmp,pos1,pos2),sizeof(ipString)); - INFO("IP: %s",ipString); - ip = ipString; - - } else { - // Failure - ERR("getIPAddress() failed"); - ip = NULL; - } - return ip; -} - -bool ESP8266::gethostbyname(const char * host, char * ip) -{ - int nb_digits = 0; - char tmp[100]; - - strcpy(ip,host); - - return true; -#if 0 - // no dns needed - int pos = strfind(host,".",0); - if (pos != -1) { - nb_digits = atoi(substr(host,tmp,0,pos)); - } - //printf("substrL %s\r\n", sub.c_str()); - if (strcount(host,'.') == 3 && nb_digits > 0) { - strcpy(ip, host); - return true; - } else { - // dns needed, not currently available - ERR("gethostbyname(): DNS Not currently available, only use IP Addresses!"); - return false; - } -#endif -} - -void ESP8266::reset() -{ - reset_pin = 0; - wait_us(20); - reset_pin = 1; - //wait(1); - //reset_pin = !reset_pin - //send("+++",3); - wait(1); - state.cmdMode = true; - sendCommand("AT", "OK", NULL, 1000); - sendCommand("AT+RST", "ready", NULL, 10000); - state.associated = false; - -} - -bool ESP8266::reboot() -{ - reset(); - return true; -} - -void ESP8266::handler_rx(void) -{ - //read characters - char c; - while (wifi.readable()) { - c=wifi.getc(); - buf_ESP8266.queue(c); - //if (state.cmdMode) pc.printf("%c",c); //debug echo, needs fast serial console to prevent UART overruns - } -} - -void ESP8266::attach_rx(bool callback) -{ - if (!callback) { - wifi.attach(NULL); - } - else { - wifi.attach(this, &ESP8266::handler_rx); - } -} - -int ESP8266::readable() -{ - return buf_ESP8266.available(); -} - -int ESP8266::writeable() -{ - return wifi.writeable(); -} - -char ESP8266::getc() -{ - char c=0; - while (!buf_ESP8266.available()); - buf_ESP8266.dequeue(&c); - return c; -} - -int ESP8266::putc(char c) -{ - while (!wifi.writeable() || wifi.readable()); //wait for echoed command characters to be read first - return wifi.putc(c); -} - -void ESP8266::flush() -{ - buf_ESP8266.flush(); -} - -int ESP8266::send(const char * buf, int len) -{ - //TODO: need to add handler for data > 2048B, this is the max packet size of the ESP8266. - if(len >= 2048){ - WARN("send buffer >= 2048B, need to chunk this up to be less."); - } - const char* bufptr=buf; - for(int i=0; i<len; i++) { - putc((int)*bufptr++); - } - return len; -} - -bool ESP8266::sendCommand(const char * cmd, const char * ACK, char * res, int timeout) -{ - char read; - char checking[512] = ""; - int checking_size = 0; - int fond = -1; - Timer tmr; - int result = 0; - - DBG("sendCmd:\t %s",cmd); - - attach_rx(true); - - //We flush the buffer - while (readable()) - getc(); - - if (!ACK || !strcmp(ACK, "NO")) { - for (int i = 0; i < strlen(cmd); i++) { - result = (putc(cmd[i]) == cmd[i]) ? result + 1 : result; - wait(0.005f); // prevents stuck recieve ready (?) need to let echoed character get read first - } - putc(13); //CR - wait(0.005f); // wait for echo - putc(10); //LF - - } else { - //We flush the buffer - while (readable()) - getc(); - - tmr.start(); - for (int i = 0; i < strlen(cmd); i++) { - result = (putc(cmd[i]) == cmd[i]) ? result + 1 : result; - wait(.005); // wait for echo - } - putc(13); //CR - wait(0.005f); // wait for echo - putc(10); //LF - - while (1) { - if (tmr.read_ms() > timeout) { - //We flush the buffer - while (readable()) - getc(); - - DBG("check:\t %s", checking); - - attach_rx(true); - return -1; - } else if (readable()) { - read = getc(); - //pc.printf("%c",read); //debug echo - if ( read != '\r' && read != '\n') { - checking[checking_size] = read; - checking_size++; - checking[checking_size] = '\0'; - fond = strfind(checking,ACK,0); - if (fond != -1) { - wait(0.01f); - - //We flush the buffer - while (readable()) - read = getc(); - //printf("%c",read); //debug echo - break; - } - } - } - } - DBG("check: %s", checking); - - attach_rx(true); - return result; - } - - //the user wants the result from the command (ACK == NULL, res != NULL) - if (res != NULL) { - int i = 0; - Timer timeout; - timeout.start(); - tmr.reset(); - while (1) { - if (timeout.read() > 2) { - if (i == 0) { - res = NULL; - break; - } - res[i] = '\0'; - DBG("user str 1: %s", res); - - break; - } else { - if (tmr.read_ms() > 300) { - res[i] = '\0'; - DBG("user str: %s", res); - - break; - } - if (readable()) { - tmr.start(); - read = getc(); - - // we drop \r and \n - if ( read != '\r' && read != '\n') { - res[i++] = read; - } - } - } - } - DBG("user str: %s", res); - } - - //We flush the buffer - while (readable()) - getc(); - - attach_rx(true); - DBG("result: %d", result) - return result; -}
--- a/ESP8266InterfaceTiny/ESP8266/ESP8266.h Tue Dec 15 09:56:32 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,235 +0,0 @@ -/* Copyright (C) 2012 mbed.org, MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * @section DESCRIPTION - * - * ESP8266 serial wifi module - * - * Datasheet: - * - * http://www.electrodragon.com/w/Wi07c - */ - -#ifndef ESP8266_H -#define ESP8266_H - -#include "mbed.h" -#include "CBuffer.h" - -#define DEFAULT_WAIT_RESP_TIMEOUT 500 -#define ESP_TCP_TYPE 1 -#define ESP_UDP_TYPE 0 -#define ESP_MBUFFE_MAX 256 - -/** - * The ESP8266 class - */ -class ESP8266 -{ - -public: - /** - * Constructor - * - * @param tx mbed pin to use for tx line of Serial interface - * @param rx mbed pin to use for rx line of Serial interface - * @param reset reset pin of the wifi module () - * @param ssid ssid of the network - * @param phrase WEP, WPA or WPA2 key - * @param baud the baudrate of the serial connection - */ - ESP8266( PinName tx, PinName rx, PinName reset, const char * ssid, const char * phrase, uint32_t baud ); - - /** - * Connect the wifi module to the ssid contained in the constructor. - * - * @return true if connected, false otherwise - */ - bool join(); - - /** - * Same as Join: connect to the ssid and get DHCP settings - * @return true if successful - */ - bool connect(); - - /** - * Check connection to the access point - * @return true if successful - */ - bool is_connected(); - - /** - * Disconnect the ESP8266 module from the access point - * - * @return true if successful - */ - bool disconnect(); - - /* - * Start up a UDP or TCP Connection - * @param type 0 for UDP, 1 for TCP - * @param ip A string that contains the IP, no quotes - * @param port Numerical port number to connect to - * @param id number between 0-4, if defined it denotes ID to use in multimode (Default to Single connection mode with -1) - * @return true if sucessful, 0 if fail - */ - bool start(bool type, char* ip, int port, int id = -1); - - /* - * Legacy Start for UDP only connection in transparent mode - * @param ip A string that contains the IP, no quotes - * @param id number between 0-4 - * @param port Numerical port number to connect to - * @param length number of characters in the message being sent - */ - bool startUDP(char* ip, int port, int id, int length); - - /* - * Legacy Start for UDP only connection in transparent mode - * @param ip A string that contains the IP, no quotes - * @param id number between 0-4 - * @param port Numerical port number to connect to - * @param length number of characters in the message being sent - */ - //bool startUDP(char* ip, int port, int id, int length); - - /* - *Starts the ESP chip as a TCP Server - *@param port Numerical port of the server, default is 333 - */ - bool startTCPServer(int port = 333); - - /** - * Close a connection - * - * @return true if successful - */ - bool close(); - - /** - * Return the IP address - * @return IP address as a string - */ - char* getIPAddress(); - - /** - * Return the IP address from host name - * @return true on success, false on failure - */ - bool gethostbyname(const char * host, char * ip); - - /** - * Reset the wifi module - */ - void reset(); - - /** - * Reboot the wifi module - */ - bool reboot(); - - /** - * Check if characters are available - * - * @return number of available characters - */ - int readable(); - - /** - * Check if characters are available - * - * @return number of available characters - */ - int writeable(); - - /** - * Read a character - * - * @return the character read - */ - char getc(); - - /** - * Write a character - * - * @param the character which will be written - */ - int putc(char c); - - /** - * Flush the buffer - */ - void flush(); - - /** - * Send a command to the wifi module. Check if the module is in command mode. If not enter in command mode - * - * @param str string to be sent - * @param ACK string which must be acknowledge by the wifi module. If ACK == NULL, no string has to be acknowledged. (default: "NO") - * @param res this field will contain the response from the wifi module, result of a command sent. This field is available only if ACK = "NO" AND res != NULL (default: NULL) - * - * @return true if successful - */ - bool sendCommand(const char * cmd, const char * ack = NULL, char * res = NULL, int timeout = DEFAULT_WAIT_RESP_TIMEOUT); - - /** - * Send a string to the wifi module by serial port. This function desactivates the user interrupt handler when a character is received to analyze the response from the wifi module. - * Useful to send a command to the module and wait a response. - * - * - * @param str string to be sent - * @param len string length - * @param ACK string which must be acknowledge by the wifi module. If ACK == NULL, no string has to be acknoledged. (default: "NO") - * @param res this field will contain the response from the wifi module, result of a command sent. This field is available only if ACK = "NO" AND res != NULL (default: NULL) - * - * @return true if ACK has been found in the response from the wifi module. False otherwise or if there is no response in 5s. - */ - int send(const char * buf, int len); - - static ESP8266 * getInstance() { - return inst; - }; - -protected: - int strfind(const char *str,const char *chkstr,int pos=0); - char* substr(const char *str , char *outstr , int pos1 , int pos2 ); - int strcount(const char *str , char countstr ); - - - RawSerial wifi; - DigitalOut reset_pin; - char phrase[30]; - char ssid[30]; - char ipString[20]; - CircBuffer<char> buf_ESP8266; - - static ESP8266 * inst; - - void attach_rx(bool null); - void handler_rx(void); - - - typedef struct STATE { - bool associated; - bool cmdMode; - } State; - - State state; -}; - -#endif \ No newline at end of file
--- a/ESP8266InterfaceTiny/ESP8266Interface.cpp Tue Dec 15 09:56:32 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +0,0 @@ -#include "ESP8266Interface.h" - -ESP8266Interface::ESP8266Interface( PinName tx, PinName rx, PinName reset, - const char * ssid, const char * phrase, uint32_t baud ) : - ESP8266(tx, rx, reset, ssid, phrase, baud ) -{ -} - -int ESP8266Interface::init() -{ - ESP8266::reset(); - return 0; -} - -bool ESP8266Interface::connect() -{ - return ESP8266::connect(); -} - -int ESP8266Interface::disconnect() -{ - return ESP8266::disconnect(); -} - -char * ESP8266Interface::getIPAddress() -{ - return ESP8266::getIPAddress(); -} \ No newline at end of file
--- a/ESP8266InterfaceTiny/ESP8266Interface.h Tue Dec 15 09:56:32 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/* ESP8266Interface.h */ -/* Copyright (C) 2012 mbed.org, MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef ESP8266INTERFACE_H_ -#define ESP8266INTERFACE_H_ - -#include "ESP8266.h" -#include "Endpoint.h" - - /** - * Interface using ESP8266 to connect to an IP-based network - */ -class ESP8266Interface: public ESP8266 { -public: - - /** - * Constructor - * - * \param tx mbed pin to use for tx line of Serial interface - * \param rx mbed pin to use for rx line of Serial interface - * \param reset reset pin of the wifi module () - * \param ssid ssid of the network - * \param phrase WEP or WPA key - * \param baud the baudrate of the serial connection (defaults to 115200, diff revs of the firmware use diff baud rates - */ - ESP8266Interface(PinName tx, PinName rx, PinName reset, const char * ssid, const char * phrase, uint32_t baud = 115200 ); - - /** Initialize the interface with DHCP. - * Initialize the interface and configure it to use DHCP (no connection at this point). - * \return 0 on success, a negative number on failure - */ - int init(); //With DHCP - - /** Connect - * Bring the interface up, start DHCP if needed. - * \return 0 on success, a negative number on failure - */ - bool connect(); - - /** Disconnect - * Bring the interface down - * \return 0 on success, a negative number on failure - */ - int disconnect(); - - /** Get IP address - * - * \return ip address - */ - char* getIPAddress(); - -private: -}; - -#include "UDPSocket.h" - -#endif /* ESP8266INTERFACE_H_ */
--- a/ESP8266InterfaceTiny/Helper/def.h Tue Dec 15 09:56:32 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +0,0 @@ -/* Copyright (C) 2012 mbed.org, MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef DEF_H -#define DEF_H - -#include "cmsis.h" -#define htons(x) __REV16(x) -#define ntohs(x) __REV16(x) -#define htonl(x) __REV(x) -#define ntohl(x) __REV(x) - -#endif \ No newline at end of file
--- a/ESP8266InterfaceTiny/Socket/Endpoint.cpp Tue Dec 15 09:56:32 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* Copyright (C) 2012 mbed.org, MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "Socket/Socket.h" -#include "Socket/Endpoint.h" -#include <cstring> - -using std::memset; - -Endpoint::Endpoint() -{ - ESP8266 = ESP8266::getInstance(); - if (ESP8266 == NULL) - error("Endpoint constructor error: no ESP8266 instance available!\r\n"); - reset_address(); -} -Endpoint::~Endpoint() {} - -void Endpoint::reset_address(void) -{ - _ipAddress[0] = '\0'; - _port = 0; - _id = -1; -} - -int Endpoint::set_address(const char* host, const int port) -{ - //Resolve DNS address or populate hard-coded IP address - if(ESP8266->gethostbyname(host, _ipAddress)) { - _port = port; - return 0; - } else { - return -1; - } -} - -char* Endpoint::get_address() -{ - return _ipAddress; -} - -int Endpoint::get_port() -{ - return _port; -} - -int Endpoint::get_id() -{ - return _id; -}
--- a/ESP8266InterfaceTiny/Socket/Endpoint.h Tue Dec 15 09:56:32 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/* Copyright (C) 2012 mbed.org, MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef ENDPOINT_H -#define ENDPOINT_H - -#include "ESP8266.h" - -class UDPSocket; - -/** -IP Endpoint (address, port) -*/ -class Endpoint { - friend class UDPSocket; - -public: - /** IP Endpoint (address, port) - */ - Endpoint(void); - - ~Endpoint(void); - - /** Reset the address of this endpoint - */ - void reset_address(void); - - /** Set the address of this endpoint - \param host The endpoint address (it can either be an IP Address or a hostname that will be resolved with DNS). - \param port The endpoint port - \return 0 on success, -1 on failure (when an hostname cannot be resolved by DNS). - */ - int set_address(const char* host, const int port); - - /** Get the IP address of this endpoint - \return The IP address of this endpoint. - */ - char* get_address(void); - - /** Get the port of this endpoint - \return The port of this endpoint - */ - int get_port(void); - - /** Get the id of this endpoint - \return The id of this endpoint - */ - int get_id(void); - -protected: - char _ipAddress[64]; - int _port; - int _id; - - ESP8266 * ESP8266; -}; - -#endif
--- a/ESP8266InterfaceTiny/Socket/Socket.cpp Tue Dec 15 09:56:32 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -/* Copyright (C) 2012 mbed.org, MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "Socket.h" -#include <cstring> - -//Debug is disabled by default -#if 0 -//Enable debug -#include <cstdio> -#define DBG(x, ...) std::printf("[Socket : DBG]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); -#define WARN(x, ...) std::printf("[Socket : WARN]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); -#define ERR(x, ...) std::printf("[Socket : ERR]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); - -#else -//Disable debug -#define DBG(x, ...) -#define WARN(x, ...) -#define ERR(x, ...) - -#endif - -Socket::Socket() : _blocking(true), _timeout(1500) { - wifi = ESP8266::getInstance(); - if (wifi == NULL) - ERR("Socket constructor error: no ESP8266 instance available!"); -} - -void Socket::set_blocking(bool blocking, unsigned int timeout) { - DBG("set blocking: %d %d", blocking, timeout); - _blocking = blocking; - _timeout = timeout; -} - -int Socket::close() { - - return (wifi->close()) ? 0 : -1; -} - -Socket::~Socket() { - close(); //Don't want to leak -}
--- a/ESP8266InterfaceTiny/Socket/Socket.h Tue Dec 15 09:56:32 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/* Copyright (C) 2012 mbed.org, MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef SOCKET_H_ -#define SOCKET_H_ - -#include "ESP8266.h" - -/** Socket file descriptor and select wrapper - */ -class Socket { -public: - /** Socket - */ - Socket(); - - /** Set blocking or non-blocking mode of the socket and a timeout on - blocking socket operations - \param blocking true for blocking mode, false for non-blocking mode. - \param timeout timeout in ms [Default: (1500)ms]. - */ - void set_blocking(bool blocking, unsigned int timeout=1500); - - /** Close the socket file descriptor - */ - int close(); - - ~Socket(); - -protected: - bool _blocking; - int _timeout; - ESP8266 * wifi; -}; - - -#endif /* SOCKET_H_ */
--- a/ESP8266InterfaceTiny/Socket/TCPSocketConnection.cpp Tue Dec 15 09:56:32 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,249 +0,0 @@ -/* Copyright (C) 2012 mbed.org, MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "TCPSocketConnection.h" -#include <cstring> -#include <algorithm> -#include "SoftSerialSendOnry.h" - -extern SoftSerialSendOnry pc; - -using std::memset; -using std::memcpy; - -//Debug is disabled by default -#if 0 -#define DBG(x, ...) pc.printf("[TCPConnection : DBG]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); -#define WARN(x, ...) pc.printf("[TCPConnection: WARN]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); -#define ERR(x, ...) pc.printf("[TCPConnection : ERR]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); -#else -#define DBG(x, ...) -#define WARN(x, ...) -#define ERR(x, ...) -#endif - -TCPSocketConnection::TCPSocketConnection() : - _is_connected(false) -{ -} - -int TCPSocketConnection::connect(const char* host, const int port) -{ -// if (init_socket(SOCK_STREAM) < 0) -// return -1; -// - if (set_address(host, port) != 0) - return -1; -// -// if (lwip_connect(_sock_fd, (const struct sockaddr *) &_remoteHost, sizeof(_remoteHost)) < 0) { -// close(); -// return -1; -// } -// _is_connected = true; - - _is_connected = ESP8266->start(ESP_TCP_TYPE,_ipAddress,_port); - if(_is_connected) { //success - return 0; - } else { // fail - return -1; - } -} - -bool TCPSocketConnection::is_connected(void) -{ - return _is_connected; -} - -int TCPSocketConnection::send(char* data, int length) -{ - if (!_is_connected) { - ERR("TCPSocketConnection::receive() - _is_connected is false : you cant receive data until you connect to a socket!"); - return -1; - } - Timer tmr; - int idx = 0; - tmr.start(); - while ((tmr.read_ms() < _timeout) || _blocking) { - - idx += wifi->send(data, length); - - if (idx == length) - return idx; - } - return (idx == 0) ? -1 : idx; - - //return wifi->send(data,length); -// -// if (!_blocking) { -// TimeInterval timeout(_timeout); -// if (wait_writable(timeout) != 0) -// return -1; -// } -// -// int n = lwip_send(_sock_fd, data, length, 0); -// _is_connected = (n != 0); -// -// return n; - -} - -// -1 if unsuccessful, else number of bytes written -int TCPSocketConnection::send_all(char* data, int length) -{ -// if ((_sock_fd < 0) || !_is_connected) -// return -1; -// -// int writtenLen = 0; -// TimeInterval timeout(_timeout); -// while (writtenLen < length) { -// if (!_blocking) { -// // Wait for socket to be writeable -// if (wait_writable(timeout) != 0) -// return writtenLen; -// } -// -// int ret = lwip_send(_sock_fd, data + writtenLen, length - writtenLen, 0); -// if (ret > 0) { -// writtenLen += ret; -// continue; -// } else if (ret == 0) { -// _is_connected = false; -// return writtenLen; -// } else { -// return -1; //Connnection error -// } -// } -// return writtenLen; - return send(data,length); // just remap to send -} - -int TCPSocketConnection::receive(char* buffer, int length) -{ - if (!_is_connected) { - ERR("TCPSocketConnection::receive() - _is_connected is false : you cant receive data until you connect to a socket!"); - return -1; - } - Timer tmr; - int idx = 0; - int nb_available = 0; - int time = -1; - - //make this the non-blocking case and return if <= 0 - // remember to change the config to blocking - // if ( ! _blocking) { - // if ( wifi.readable <= 0 ) { - // return (wifi.readable); - // } - // } - //--- - tmr.start(); - if (_blocking) { - while (1) { - nb_available = wifi->readable(); - if (nb_available != 0) { - break; - } - } - } - //--- - // blocking case - else { - tmr.reset(); - - while (time < _timeout) { - nb_available = wifi->readable(); - if (nb_available < 0) return nb_available; - if (nb_available > 0) break ; - time = tmr.read_ms(); - } - - if (nb_available == 0) return nb_available; - } - - // change this to < 20 mS timeout per byte to detect end of packet gap - // this may not work due to buffering at the UART interface - tmr.reset(); - // while ( tmr.read_ms() < 20 ) { - // if ( wifi.readable() && (idx < length) ) { - // buffer[idx++] = wifi->getc(); - // tmr.reset(); - // } - // if ( idx == length ) { - // break; - // } - // } - //--- - while (time < _timeout) { - - nb_available = wifi->readable(); - //for (int i = 0; i < min(nb_available, length); i++) { - for (int i = 0; i < min(nb_available, (length-idx)); i++) { - buffer[idx] = wifi->getc(); - idx++; - } - if (idx == length) { - break; - } - time = tmr.read_ms(); - } - //--- - return (idx == 0) ? -1 : idx; - -//************************ original code below -// -// if (!_blocking) { -// TimeInterval timeout(_timeout); -// if (wait_readable(timeout) != 0) -// return -1; -// } -// -// int n = lwip_recv(_sock_fd, data, length, 0); -// _is_connected = (n != 0); -// -// return n; - -} - -// -1 if unsuccessful, else number of bytes received -int TCPSocketConnection::receive_all(char* data, int length) -{ - //ERR("receive_all() not yet implimented"); - // if ((_sock_fd < 0) || !_is_connected) -// return -1; -// -// int readLen = 0; -// TimeInterval timeout(_timeout); -// while (readLen < length) { -// if (!_blocking) { -// //Wait for socket to be readable -// if (wait_readable(timeout) != 0) -// return readLen; -// } -// -// int ret = lwip_recv(_sock_fd, data + readLen, length - readLen, 0); -// if (ret > 0) { -// readLen += ret; -// } else if (ret == 0) { -// _is_connected = false; -// return readLen; -// } else { -// return -1; //Connnection error -// } -// } -// return readLen; - receive(data,length); -}
--- a/ESP8266InterfaceTiny/Socket/TCPSocketConnection.h Tue Dec 15 09:56:32 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -/* Copyright (C) 2012 mbed.org, MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef TCPSOCKET_H -#define TCPSOCKET_H - -#include "Socket/Socket.h" -#include "Socket/Endpoint.h" - -/** -TCP socket connection -*/ -class TCPSocketConnection : public Socket, public Endpoint { - friend class TCPSocketServer; - -public: - /** TCP socket connection - */ - TCPSocketConnection(); - - /** Connects this TCP socket to the server - \param host The host to connect to. It can either be an IP Address or a hostname that will be resolved with DNS. - \param port The host's port to connect to. - \return 0 on success, -1 on failure. - */ - int connect(const char* host, const int port); - - /** Check if the socket is connected - \return true if connected, false otherwise. - */ - bool is_connected(void); - - /** Send data to the remote host. - \param data The buffer to send to the host. - \param length The length of the buffer to send. - \return the number of written bytes on success (>=0) or -1 on failure - */ - int send(char* data, int length); - - /** Send all the data to the remote host. - \param data The buffer to send to the host. - \param length The length of the buffer to send. - \return the number of written bytes on success (>=0) or -1 on failure - */ - int send_all(char* data, int length); - - /** Receive data from the remote host. - \param data The buffer in which to store the data received from the host. - \param length The maximum length of the buffer. - \return the number of received bytes on success (>=0) or -1 on failure - */ - int receive(char* data, int length); - - /** Receive all the data from the remote host. - \param data The buffer in which to store the data received from the host. - \param length The maximum length of the buffer. - \return the number of received bytes on success (>=0) or -1 on failure - */ - int receive_all(char* data, int length); - -private: - bool _is_connected; - -}; - -#endif - \ No newline at end of file
--- a/ESP8266InterfaceTiny/Socket/TCPSocketServer.cpp Tue Dec 15 09:56:32 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -/* Copyright (C) 2012 mbed.org, MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "TCPSocketServer.h" - -#include <cstring> - -using std::memset; -using std::memcpy; - -TCPSocketServer::TCPSocketServer() { - -} - -int TCPSocketServer::bind(int port) { - if(!wifi->startTCPServer(port)) { - return(-1); - } - _port = port; - return 0; -} - -int TCPSocketServer::listen(int max) { - - return 0; -} - -int TCPSocketServer::accept(TCPSocketConnection& connection) { - return 0; -} \ No newline at end of file
--- a/ESP8266InterfaceTiny/Socket/TCPSocketServer.h Tue Dec 15 09:56:32 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* Copyright (C) 2012 mbed.org, MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef TCPSOCKETSERVER_H -#define TCPSOCKETSERVER_H - -#include "Socket/Socket.h" -#include "TCPSocketConnection.h" - -/** TCP Server. - */ -class TCPSocketServer : public Socket { - friend class TCPSocketConnection; - public: - /** Instantiate a TCP Server. - */ - TCPSocketServer(); - - /** Bind a socket to a specific port. - \param port The port to listen for incoming connections on. - \return 0 on success, -1 on failure. - */ - int bind(int port); - - /** Start listening for incoming connections. - \param backlog number of pending connections that can be queued up at any - one time [Default: 1]. - \return 0 on success, -1 on failure. - */ - int listen(int backlog=1); - - /** Accept a new connection. - \param connection A TCPSocketConnection instance that will handle the incoming connection. - \return 0 on success, -1 on failure. - */ - int accept(TCPSocketConnection& connection); -private: - int _port; -}; - -#endif \ No newline at end of file
--- a/ESP8266InterfaceTiny/Socket/UDPSocket.cpp Tue Dec 15 09:56:32 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,154 +0,0 @@ -/* Copyright (C) 2012 mbed.org, MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "UDPSocket.h" - -#include <string> -#include <algorithm> - -UDPSocket::UDPSocket() -{ - endpoint_configured = false; - endpoint_read = false; - Endpoint currentEndpoint; -} - -int UDPSocket::init(void) -{ - return 0; -} - -// Server initialization -int UDPSocket::bind(int port) -{ - return 0; -} - -// -1 if unsuccessful, else number of bytes written -int UDPSocket::sendTo(Endpoint &remote, char *packet, int length) -{ - Timer tmr; - int idx = 0; - - - confEndpoint(remote); - - // initialize transparent mode if not already done - if(!endpoint_configured) { - // initialize UDP (default id of -1 means transparent mode) - //!wifi->start(ESP_UDP_TYPE, remote._ipAddress, remote._port, remote._id - if(!wifi->startUDP(remote._ipAddress, remote._port, 0,length)) { - return(-1); - } - endpoint_configured = true; - } - - tmr.start(); - - while ((tmr.read_ms() < _timeout) || _blocking) { - - idx += wifi->send(packet, length); - - if (idx == length) - return idx; - } - return (idx == 0) ? -1 : idx; -} - -// -1 if unsuccessful, else number of bytes received -int UDPSocket::receiveFrom(Endpoint &remote, char *buffer, int length) -{ - Timer tmr; - int idx = 0; - int nb_available = 0; - int time = -1; - - //make this the non-blocking case and return if <= 0 - // remember to change the config to blocking - // if ( ! _blocking) { - // if ( wifi.readable <= 0 ) { - // return (wifi.readable); - // } - // } - //--- - tmr.start(); - if (_blocking) { - while (1) { - nb_available = wifi->readable(); - if (nb_available != 0) { - break; - } - } - } - //--- - // blocking case - else { - tmr.reset(); - - while (time < _timeout) { - nb_available = wifi->readable(); - if (nb_available < 0) return nb_available; - if (nb_available > 0) break ; - time = tmr.read_ms(); - } - - if (nb_available == 0) return nb_available; - } - - // change this to < 20 mS timeout per byte to detect end of packet gap - // this may not work due to buffering at the UART interface - tmr.reset(); - // while ( tmr.read_ms() < 20 ) { - // if ( wifi.readable() && (idx < length) ) { - // buffer[idx++] = wifi->getc(); - // tmr.reset(); - // } - // if ( idx == length ) { - // break; - // } - // } - //--- - while (time < _timeout) { - - nb_available = wifi->readable(); - //for (int i = 0; i < min(nb_available, length); i++) { - for (int i = 0; i < min(nb_available, (length-idx)); i++) { - buffer[idx] = wifi->getc(); - idx++; - } - if (idx == length) { - break; - } - time = tmr.read_ms(); - } - //--- - readEndpoint(remote); - return (idx == 0) ? -1 : idx; -} - -bool UDPSocket::confEndpoint(Endpoint & ep) -{ - currentEndpoint = ep; - return true; -} - -bool UDPSocket::readEndpoint(Endpoint & ep) -{ - ep = currentEndpoint; - return true; -}
--- a/ESP8266InterfaceTiny/Socket/UDPSocket.h Tue Dec 15 09:56:32 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -/* Copyright (C) 2012 mbed.org, MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef UDPSOCKET_H -#define UDPSOCKET_H - -#include "Endpoint.h" -#include "Socket.h" - -#include <cstdint> - -/** -UDP Socket -*/ -class UDPSocket: public Socket { - -public: - /** Instantiate an UDP Socket. - */ - UDPSocket(); - - /** Init the UDP Client Socket without binding it to any specific port - \return 0 on success, -1 on failure. - */ - int init(void); - - /** Bind a UDP Server Socket to a specific port - \param port The port to listen for incoming connections on - \return 0 on success, -1 on failure. - */ - int bind(int port = -1); - - /** Send a packet to a remote endpoint - \param remote The remote endpoint - \param packet The packet to be sent - \param length The length of the packet to be sent - \return the number of written bytes on success (>=0) or -1 on failure - */ - int sendTo(Endpoint &remote, char *packet, int length); - - /** Receive a packet from a remote endpoint - \param remote The remote endpoint - \param buffer The buffer for storing the incoming packet data. If a packet - is too long to fit in the supplied buffer, excess bytes are discarded - \param length The length of the buffer - \return the number of received bytes on success (>=0) or -1 on failure - */ - int receiveFrom(Endpoint &remote, char *buffer, int length); - -private: - bool confEndpoint(Endpoint & ep); - bool readEndpoint(Endpoint & ep); - bool endpoint_configured; - bool endpoint_read; - Endpoint currentEndpoint; - -}; - -#include "def.h" - -#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MClient.h Fri Dec 18 04:30:59 2015 +0000 @@ -0,0 +1,85 @@ +#ifndef _MCLIENT_H_ +#define _MCLIENT_H_ + +#define USE_ESP8266 +//#define USE_ETHERNET + +#include "mbed.h" +#ifdef USE_ESP8266 +#include "MQTTESP8266.h" +#else +#include "MQTTEthernet.h" +#endif +#include "MQTTClient.h" + +class MClient +{ + public: + typedef void (*messageHandler)(MQTT::MessageData&); +#ifdef USE_ESP8266 + MClient(MQTTESP8266 *ipstack) : client(MQTT::Client<MQTTESP8266, Countdown>(*ipstack)) +#else + MClient(MQTTEthernet *ipstack) : client(MQTT::Client<MQTTEthernet, Countdown>(*ipstack)) +#endif + { + _ipstack = ipstack; + } + void setDefaultMessageHandler(messageHandler mh) + { + client.setDefaultMessageHandler(mh); + } + int connect(char* host,int port) + { + return _ipstack->connect(host, port); + } + int connect() + { + return client.connect(); + } + int connect(MQTTPacket_connectData& options) + { + return client.connect(options); + } + int publish(const char* topicName, MQTT::Message& message) + { + return client.publish(topicName,message); + } + int publish(const char* topicName, void* payload, size_t payloadlen, enum MQTT::QoS qos = MQTT::QOS0, bool retained = false) + { + return client.publish(topicName,payload,payloadlen,qos,retained); + } + int publish(const char* topicName, void* payload, size_t payloadlen, unsigned short& id, enum MQTT::QoS qos = MQTT::QOS1, bool retained = false) + { + return client.publish(topicName,payload,payloadlen,id,qos,retained); + } + int subscribe(const char* topicFilter, enum MQTT::QoS qos, messageHandler mh) + { + return client.subscribe(topicFilter,qos,mh); + } + int unsubscribe(const char* topicFilter) + { + return client.unsubscribe(topicFilter); + } + int disconnect() + { + return client.disconnect(); + } + int yield(unsigned long timeout_ms = 1000L) + { + return client.yield(timeout_ms); + } + bool isConnected() + { + return client.isConnected(); + } +private: +#ifdef USE_ESP8266 + MQTT::Client<MQTTESP8266, Countdown> client; + MQTTESP8266 *_ipstack; +#else + MQTT::Client<MQTTEthernet, Countdown> client; + MQTTEthernet *_ipstack; +#endif +}; + +#endif \ No newline at end of file
--- a/MQTTESP8266.h Tue Dec 15 09:56:32 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ - -#if !defined(MQTTESP8266_H) -#define MQTTESP8266_H - -#include "MQTTmbed.h" -#include "ESP8266Interface.h" -#include "MQTTSocket.h" - -// This struct is only used to workaround the order that the interfaces are initialized -// MQTTSocket contains a TCPSocketConnection which needs the ESP8266Interface to be -// instantiated first. Unfortunately the only way to instantiate a member before a superclass -// is through another superclass. -struct MQTTESP8266Holder { - MQTTESP8266Holder(PinName tx, PinName rx, PinName reset, const char *ssid, const char *pass) : - _wifi(tx, rx, reset, ssid, pass) {} - - ESP8266Interface _wifi; -}; - -// Straightforward implementation of a MQTT interface -class MQTTESP8266 : public MQTTESP8266Holder, public MQTTSocket { -private: - MQTTESP8266Holder::_wifi; - //ESP8266Interface _wifi; - -public: - MQTTESP8266(PinName tx, PinName rx, PinName reset, const char *ssid, const char *pass) : - MQTTESP8266Holder(tx, rx, reset, ssid, pass) { - _wifi.init(); - _wifi.connect(); - } - - ESP8266Interface& getInterface() { - return _wifi; - } - - void reconnect() { - _wifi.disconnect(); - _wifi.connect(); - } -}; - - -#endif
--- a/Milkcocoa.cpp Tue Dec 15 09:56:32 2015 +0000 +++ b/Milkcocoa.cpp Fri Dec 18 04:30:59 2015 +0000 @@ -1,8 +1,12 @@ #include "Milkcocoa.h" -#if 1 +#if 0 +#if 0 #include "SoftSerialSendOnry.h" extern SoftSerialSendOnry pc; +#else +extern Serial pc; +#endif #define DBG(x) x #else #define DBG(x) @@ -87,9 +91,9 @@ return(json_msg); } -Milkcocoa::Milkcocoa(MQTTESP8266 *ipstack, const char *host, uint16_t port, const char *_app_id, const char *client_id) : client(MQTT::Client<MQTTESP8266, Countdown>(*ipstack)) { +Milkcocoa::Milkcocoa(MClient *_client, const char *host, uint16_t port, const char *_app_id, const char *client_id) { - _ipstack = ipstack; + client = _client; strcpy(servername,host); portnum = port; app_id = _app_id; @@ -99,9 +103,9 @@ } -Milkcocoa::Milkcocoa(MQTTESP8266 *ipstack, const char *host, uint16_t port, const char *_app_id, const char *client_id, char *_session) : client(MQTT::Client<MQTTESP8266, Countdown>(*ipstack)) { +Milkcocoa::Milkcocoa(MClient *_client, const char *host, uint16_t port, const char *_app_id, const char *client_id, char *_session) { - _ipstack = ipstack; + client = _client; strcpy(servername,host); portnum = port; app_id = _app_id; @@ -111,18 +115,18 @@ } -Milkcocoa* Milkcocoa::createWithApiKey(MQTTESP8266 *ipstack, const char *host, uint16_t port, const char *_app_id, const char *client_id, char *key, char *secret) { +Milkcocoa* Milkcocoa::createWithApiKey(MClient *_client, const char *host, uint16_t port, const char *_app_id, const char *client_id, char *key, char *secret) { char session[60]; sprintf(session, "k%s:%s", key, secret); - return new Milkcocoa(ipstack, host, port, _app_id, client_id, session); + return new Milkcocoa(_client, host, port, _app_id, client_id, session); } void Milkcocoa::connect() { - if(client.isConnected()) + if(client->isConnected()) return; - - if(_ipstack->connect(servername, portnum)!=0) { + + if(client->connect(servername, portnum)!=0) { DBG(pc.printf("Network connect err\r\n");) return; } @@ -135,7 +139,7 @@ data.username.cstring = username; data.password.cstring = password; - if (client.connect(data) != 0) { + if (client->connect(data) != 0) { DBG(pc.printf("Milkcocoa connect err\r\n");) return; } @@ -154,7 +158,7 @@ buf = dataelement.toCharArray(); message.payload = (void*)buf; message.payloadlen = strlen(buf); - if(client.publish(topic, message)!=0) + if(client->publish(topic, message)!=0) return(false); return true; @@ -172,7 +176,7 @@ buf = dataelement.toCharArray(); message.payload = (void*)buf; message.payloadlen = strlen(buf); - if(client.publish(topic, message)!=0) + if(client->publish(topic, message)!=0) return false; return true; @@ -180,18 +184,31 @@ void Milkcocoa::loop() { connect(); - client.yield(RECV_TIMEOUT); + client->yield(RECV_TIMEOUT); } bool Milkcocoa::on(const char *path, const char *event, GeneralFunction cb) { - static char topic[100]; + MilkcocoaSubscriber *sub = new MilkcocoaSubscriber(cb); + sprintf(sub->topic, "%s/%s/%s", app_id, path, event); - sprintf(topic, "%s/%s/%s", app_id, path, event); - - if (client.subscribe(topic, MQTT::QOS0, cb) != 0) { + if (client->subscribe(sub->topic, MQTT::QOS0, cb) != 0) { DBG(pc.printf("Milkcocoa subscribe err\r\n");) return false; } + for (int i=0; i<MILKCOCOA_SUBSCRIBERS; i++) { + if (milkcocoaSubscribers[i] == sub) { + return false; + } + } + for (int i=0; i<MILKCOCOA_SUBSCRIBERS; i++) { + if (milkcocoaSubscribers[i] == 0) { + milkcocoaSubscribers[i] = sub; + return true; + } + } return true; } +MilkcocoaSubscriber::MilkcocoaSubscriber(GeneralFunction _cb) { + cb = _cb; +} \ No newline at end of file
--- a/Milkcocoa.h Tue Dec 15 09:56:32 2015 +0000 +++ b/Milkcocoa.h Fri Dec 18 04:30:59 2015 +0000 @@ -2,10 +2,12 @@ #define _MILKCOCOA_H_ #include "mbed.h" -#include "MQTTESP8266.h" +#include "MQTTmbed.h" #include "MQTTClient.h" +#include "MClient.h" #define RECV_TIMEOUT 500 +#define MILKCOCOA_SUBSCRIBERS 8 class DataElement { public: @@ -25,12 +27,20 @@ typedef void (*GeneralFunction) (MQTT::MessageData& elem); +class MilkcocoaSubscriber { + public: + GeneralFunction cb; + char topic[100]; + MilkcocoaSubscriber(GeneralFunction _cb); +}; + class Milkcocoa { public: - Milkcocoa(MQTTESP8266 *ipstack, const char *host, uint16_t port, const char *_app_id, const char *client_id); - Milkcocoa(MQTTESP8266 *ipstack, const char *host, uint16_t port, const char *_app_id, const char *client_id, char *_session); - static Milkcocoa* createWithApiKey(MQTTESP8266 *ipstack, const char *host, uint16_t port, const char *_app_id, const char *client_id, char *key, char *secret); +// Milkcocoa(const char *host, uint16_t port, const char *_app_id, const char *client_id); + Milkcocoa(MClient *_client, const char *host, uint16_t port, const char *_app_id, const char *client_id); + Milkcocoa(MClient *_client, const char *host, uint16_t port, const char *_app_id, const char *client_id, char *_session); + static Milkcocoa* createWithApiKey(MClient *_client, const char *host, uint16_t port, const char *_app_id, const char *client_id, char *key, char *secret); void connect(); void loop(); bool push(const char *path, DataElement dataelement); @@ -45,9 +55,9 @@ char password[32]; const char *app_id; - MQTTESP8266 *_ipstack; - MQTT::Client<MQTTESP8266, Countdown> client; + MClient *client; GeneralFunction _cb; + MilkcocoaSubscriber *milkcocoaSubscribers[MILKCOCOA_SUBSCRIBERS]; };
--- a/SoftSerialSendOnly/SoftSerialSendOnry.cpp Tue Dec 15 09:56:32 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -#include "SoftSerialSendOnry.h" - -SoftSerialSendOnry::SoftSerialSendOnry(PinName TX, const char* name) { - tx_en = false; - if (TX != NC) { - tx = new DigitalOut(TX); - tx_en = true; - tx->write(1); - tx_bit = -1; - txticker.attach(this, &SoftSerialSendOnry::tx_handler); - } - - baud(9600); - format(); -} - -SoftSerialSendOnry::~SoftSerialSendOnry() { - if (tx_en) - delete(tx); -} - -void SoftSerialSendOnry::baud(int baudrate) { - bit_period = 1000000 / baudrate; -} - -void SoftSerialSendOnry::format(int bits, Parity parity, int stop_bits) { - _bits = bits; - _parity = parity; - _stop_bits = stop_bits; - _total_bits = 1 + _bits + _stop_bits + (bool)_parity; -} - -int SoftSerialSendOnry::_getc() -{ - return(0); -} \ No newline at end of file
--- a/SoftSerialSendOnly/SoftSerialSendOnry.h Tue Dec 15 09:56:32 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,105 +0,0 @@ -#ifndef SOFTSERIAL_SEND_ONRY_H -#define SOFTSERIAL_SEND_ONRY_H - -#include "mbed.h" -#include "SoftSerial_Ticker.h" -/** A software serial implementation - * - */ -class SoftSerialSendOnry: public Stream { - -public: - /** - * Constructor - * - * @param TX Name of the TX pin, NC for not connected - * @param name Name of the connection - */ - SoftSerialSendOnry(PinName TX, const char* name = NULL); - virtual ~SoftSerialSendOnry(); - - /** Set the baud rate of the serial port - * - * @param baudrate The baudrate of the serial port (default = 9600). - */ - void baud(int baudrate); - - enum Parity { - None = 0, - Odd, - Even, - Forced1, - Forced0 - }; - - enum IrqType { - RxIrq = 0, - TxIrq - }; - - /** Set the transmission format used by the serial port - * - * @param bits The number of bits in a word (default = 8) - * @param parity The parity used (SerialBase::None, SerialBase::Odd, SerialBase::Even, SerialBase::Forced1, SerialBase::Forced0; default = SerialBase::None) - * @param stop The number of stop bits (default = 1) - */ - void format(int bits=8, Parity parity=SoftSerialSendOnry::None, int stop_bits=1); - - /** Determine if there is space available to write a character - * - * @returns - * 1 if there is space to write a character, - * 0 otherwise - */ - int writeable(); - - /** Attach a function to call whenever a serial interrupt is generated - * - * @param fptr A pointer to a void function, or 0 to set as none - * @param type Which serial interrupt to attach the member function to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty) - */ - void attach(void (*fptr)(void), IrqType type=RxIrq) { - fpointer[type].attach(fptr); - } - - /** Attach a member function to call whenever a serial interrupt is generated - * - * @param tptr pointer to the object to call the member function on - * @param mptr pointer to the member function to be called - * @param type Which serial interrupt to attach the member function to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty) - */ - template<typename T> - void attach(T* tptr, void (T::*mptr)(void), IrqType type=RxIrq) { - fpointer[type].attach(tptr, mptr); - } - - /** Generate a break condition on the serial line - */ - void send_break(); - -protected: - DigitalOut *tx; - - bool tx_en; - int bit_period; - int _bits, _stop_bits, _total_bits; - Parity _parity; - - FunctionPointer fpointer[2]; - - //tx - void tx_handler(void); - void prepare_tx(int c); - FlexTicker txticker; - int _char; - volatile int tx_bit; - - - - virtual int _getc(); - virtual int _putc(int c); -}; - - -#endif -
--- a/SoftSerialSendOnly/SoftSerialSendOnry_tx.cpp Tue Dec 15 09:56:32 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -#include "SoftSerialSendOnry.h" - -int SoftSerialSendOnry::_putc(int c) -{ - while(!writeable()); - prepare_tx(c); - tx_bit = 0; - txticker.prime(); - tx_handler(); - return 0; -} - -void SoftSerialSendOnry::send_break(void) { - while(!writeable()); - tx_bit = 0; //Just to make sure it appears as non-writable to other threads/IRQs - tx->write(0); - wait_us((bit_period * _total_bits * 3) / 2); - tx->write(1); - tx_bit = -1; -} - -int SoftSerialSendOnry::writeable(void) -{ - if (!tx_en) - return false; - if (tx_bit == -1) - return true; - return false; -} - -void SoftSerialSendOnry::tx_handler(void) -{ - if (tx_bit == _total_bits) { - tx_bit = -1; - fpointer[TxIrq].call(); - return; - } - - //Flip output - int cur_out = tx->read(); - tx->write(!cur_out); - - //Calculate when to do it again - int count = bit_period; - tx_bit++; - while(((_char >> tx_bit) & 0x01) == !cur_out) { - count+=bit_period; - tx_bit++; - } - - txticker.setNext(count); -} - -void SoftSerialSendOnry::prepare_tx(int c) -{ - _char = c << 1; - - bool parity; - switch (_parity) { - case Forced1: - _char |= 1 << (_bits + 1); - case Even: - parity = false; - for (int i = 0; i<_bits; i++) { - if (((_char >> i) & 0x01) == 1) - parity = !parity; - } - _char |= parity << (_bits + 1); - case Odd: - parity = true; - for (int i = 0; i<_bits; i++) { - if (((_char >> i) & 0x01) == 1) - parity = !parity; - } - _char |= parity << (_bits + 1); - } - - _char |= 0xFFFF << (1 + _bits + (bool)_parity); - _char &= ~(1<<_total_bits); -}
--- a/SoftSerialSendOnly/SoftSerial_Ticker.h Tue Dec 15 09:56:32 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -//A modified version of the regular ticker/timeout libraries to allow us to do timeout without losing accuracy - -#ifndef FLEXTICKER_H -#define FLEXTICKER_H - -#include "mbed.h" - -class FlexTicker: public TimerEvent { - public: - template<typename T> - void attach(T* tptr, void (T::*mptr)(void)) { - _function.attach(tptr, mptr); - } - - /** Detach the function - */ - void detach() { - remove(); - } - - void setNext(int delay) { - insert(event.timestamp + delay); - } - - void prime(void) { - event.timestamp = us_ticker_read(); - } - -protected: - virtual void handler() { - _function.call(); - } - - unsigned int _delay; - FunctionPointer _function; -}; - -#endif \ No newline at end of file