{"id":557,"date":"2014-10-27T18:56:35","date_gmt":"2014-10-27T17:56:35","guid":{"rendered":"http:\/\/www.verelec.nl\/?page_id=557"},"modified":"2014-10-27T18:56:35","modified_gmt":"2014-10-27T17:56:35","slug":"create-your-own-at-commands-on-the-esp8266","status":"publish","type":"page","link":"https:\/\/www.verelec.nl\/?page_id=557","title":{"rendered":"Create your own AT commands on the ESP8266"},"content":{"rendered":"<p>Nou doubt I will be, as we call it here in Holland, &#8220;swearing in the church&#8221; but I will show you how to create your own functions in the AT Demo. This to give you some idea how to build your own software. I am assuming you know how to create source and header files in Eclipse as I am using that for this example. Also I am assuming you have a project already created\/loaded containing the AT demo as described in my previous post about installing the<a href=\"https:\/\/www.verelec.nl\/?page_id=547\"> ESP8266 SDK under Eclipse in Ubuntu<\/a>.<\/p>\n<p><strong>Create a new myFunctions.c and a new myFunctions.h.<\/strong><\/p>\n<p>In <strong>myFunctions.c<\/strong> enter the following text :<\/p>\n<pre><code>\r\n\/*\r\n * \tmyFunctions.c\r\n *\r\n *  Created on: 27 okt. 2014\r\n *\tAuthor: nico\r\n *\/\r\n\r\n\/\/\r\n\/\/ includes\r\n\/\/\r\n#include \"c_types.h\"\t\t\/\/ C types used in this applicationm\r\n#include \"at.h\"\t\t\t\t\/\/ needed for AT enumerations and sending info to caller\r\n#include \"myFunctions.h\"\t\/\/ my function prototypes\r\n#include \"osapi.h\"\t\t\t\/\/ enables OS api calls\r\n#include \"driver\/uart.h\"\t\/\/ needed to use the uart\r\n#include \t\t\t\/\/ standard C library functions\r\n\r\n\/**\r\n * @brief  command to return the MAC address of the ESP8266 to the user\r\n * @param  id: command id number (we actually do not need this)\r\n * @retval None\r\n *\/\r\nICACHE_FLASH_ATTR\r\nat_exeCmdGetMacAddress(uint8_t id) {\r\n\r\n\tchar temp[20];\t\t\t\/\/ buffer for formatting the output (xx:xx:xx:xx:xx:xx\\r\\n) = 20 bytes\r\n\tuint8_t macaddr[6];\t\t\/\/ array that will receive the MAC address from the chip\r\n\t\/\/\r\n\t\/\/ get the mac address from the API. This is described in the  documentation from\r\n\t\/\/ SDK 0.9.1. The document is\/was missing in SDK 0.9.2. If anyone needs it, let me know\r\n\t\/\/\r\n\twifi_get_macaddr(0x00, macaddr);\r\n\t\/\/\r\n\t\/\/ format the a string into temp field as 6 hex numbers with a colon in between\r\n\t\/\/\r\n\tos_sprintf(temp, \"%02x:%02x:%02x:%02x:%02x:%02x\\r\\n\", macaddr[0],\r\n\t\t\tmacaddr[1], macaddr[2], macaddr[3], macaddr[4], macaddr[5]);\r\n\t\/\/\r\n\t\/\/ and return the string to the caller through the uart\r\n\t\/\/\r\n\tuart0_sendStr(temp);\r\n\t\/\/\r\n\t\/\/ send Ok to caller\r\n\t\/\/\r\n\tat_backOk;\r\n}\r\n<\/code><\/pre>\n<p>and in <strong>myFunctions.h<\/strong> enter :<\/p>\n<pre><code>\r\n\/*\r\n * myFunctions.h\r\n *\r\n * Created on: 27 okt. 2014\r\n * Author: nico\r\n *\/\r\n\r\n#ifndef MYFUNCTIONS_H_\r\n#define MYFUNCTIONS_H_\r\n\/\/\r\n\/\/ function prototypes\r\n\/\/\r\nICACHE_FLASH_ATTR at_exeCmdGetMacAddress(uint8_t id);\r\n\r\n#endif \/* MYFUNCTIONS_H_ *\/\r\n<\/code><\/pre>\n<p>We are almost done. So far we have created our function which does the following:<\/p>\n<ul>\n<li>get the ESP8266 mac address from the chip in an array of 6 bytes<\/li>\n<li>convert the array in a formatted mac address (i.e. yy:yy:zz:aa:bb:cc)<\/li>\n<li>send the formatted string through the uart0 port<\/li>\n<li>send the text &#8220;\\r\\nOK\\r\\n&#8221; through the uart0 port<\/li>\n<\/ul>\n<p>Although we have now created our function() we are not there yet. The system needs a mapping from an AT command to our function. this is done in the file at_cmd.h. This file contains an array of known commands and different actions to take place with a command like the &#8220;?&#8221; or &#8220;=&#8221; addition. this is the contents as it is received in the example AT firmware:<\/p>\n<pre><code>\r\n#ifndef __AT_CMD_H\r\n#define __AT_CMD_H\r\n\r\n#include \"at.h\"\r\n#include \"at_wifiCmd.h\"\r\n#include \"at_ipCmd.h\"\r\n#include \"at_baseCmd.h\"\r\n\r\n#define at_cmdNum   20\r\n\r\nat_funcationType at_fun[at_cmdNum]={\r\n  {NULL, 0, NULL, NULL, NULL, at_exeCmdNull},\r\n  {\"E\", 1, NULL, NULL, at_setupCmdE, NULL},\r\n  {\"+RST\", 4, NULL, NULL, NULL, at_exeCmdRst},\r\n  {\"+GMR\", 4, NULL, NULL, NULL, at_exeCmdGmr},\r\n  {\"+CWMODE\", 7, at_testCmdCwmode, at_queryCmdCwmode, at_setupCmdCwmode, NULL},\r\n  {\"+CWJAP\", 6, NULL, at_queryCmdCwjap, at_setupCmdCwjap, NULL},\r\n  {\"+CWLAP\", 6, NULL, NULL, at_setupCmdCwlap, at_exeCmdCwlap},\r\n  {\"+CWQAP\", 6, at_testCmdCwqap, NULL, NULL, at_exeCmdCwqap},\r\n  {\"+CWSAP\", 6, NULL, at_queryCmdCwsap, at_setupCmdCwsap, NULL},\r\n  {\"+CWLIF\", 6, NULL, NULL, NULL, at_exeCmdCwlif},\r\n  {\"+CIFSR\", 6, at_testCmdCifsr, NULL, at_setupCmdCifsr, at_exeCmdCifsr},\r\n  {\"+CIPSTATUS\", 10, at_testCmdCipstatus, NULL, NULL, at_exeCmdCipstatus},\r\n  {\"+CIPSTART\", 9, at_testCmdCipstart, NULL, at_setupCmdCipstart, NULL},\r\n  {\"+CIPCLOSE\", 9, at_testCmdCipclose, NULL, at_setupCmdCipclose, at_exeCmdCipclose},\r\n  {\"+CIPSEND\", 8, at_testCmdCipsend, NULL, at_setupCmdCipsend, at_exeCmdCipsend},\r\n  {\"+CIPMUX\", 7, NULL, at_queryCmdCipmux, at_setupCmdCipmux, NULL},\r\n  {\"+CIPSERVER\", 10, NULL, NULL,at_setupCmdCipserver, NULL},\r\n  {\"+CIPMODE\", 8, NULL, at_queryCmdCipmode, at_setupCmdCipmode, NULL},\r\n  {\"+CIPSTO\", 7, NULL, at_queryCmdCipsto, at_setupCmdCipsto, NULL},\r\n  {\"+CIUPDATE\", 9, NULL, NULL, NULL, at_exeCmdUpdate}\r\n};\r\n\r\n#endif\r\n<\/code><\/pre>\n<p>I will not go into details of how the array works although it is quite obvious looking at the names of the different functions. Now let&#8217;s expand this array with our extra user command. Expand the array like this:<\/p>\n<pre><code>\r\n#ifndef __AT_CMD_H\r\n#define __AT_CMD_H\r\n\r\n#include \"at.h\"\r\n#include \"at_wifiCmd.h\"\r\n#include \"at_ipCmd.h\"\r\n#include \"at_baseCmd.h\"\r\n\r\n#define at_cmdNum   21\r\n\r\nat_funcationType at_fun[at_cmdNum]={\r\n  {NULL, 0, NULL, NULL, NULL, at_exeCmdNull},\r\n  {\"E\", 1, NULL, NULL, at_setupCmdE, NULL},\r\n  {\"+RST\", 4, NULL, NULL, NULL, at_exeCmdRst},\r\n  {\"+GMR\", 4, NULL, NULL, NULL, at_exeCmdGmr},\r\n  {\"+CWMODE\", 7, at_testCmdCwmode, at_queryCmdCwmode, at_setupCmdCwmode, NULL},\r\n  {\"+CWJAP\", 6, NULL, at_queryCmdCwjap, at_setupCmdCwjap, NULL},\r\n  {\"+CWLAP\", 6, NULL, NULL, at_setupCmdCwlap, at_exeCmdCwlap},\r\n  {\"+CWQAP\", 6, at_testCmdCwqap, NULL, NULL, at_exeCmdCwqap},\r\n  {\"+CWSAP\", 6, NULL, at_queryCmdCwsap, at_setupCmdCwsap, NULL},\r\n  {\"+CWLIF\", 6, NULL, NULL, NULL, at_exeCmdCwlif},\r\n  {\"+CIFSR\", 6, at_testCmdCifsr, NULL, at_setupCmdCifsr, at_exeCmdCifsr},\r\n  {\"+CIPSTATUS\", 10, at_testCmdCipstatus, NULL, NULL, at_exeCmdCipstatus},\r\n  {\"+CIPSTART\", 9, at_testCmdCipstart, NULL, at_setupCmdCipstart, NULL},\r\n  {\"+CIPCLOSE\", 9, at_testCmdCipclose, NULL, at_setupCmdCipclose, at_exeCmdCipclose},\r\n  {\"+CIPSEND\", 8, at_testCmdCipsend, NULL, at_setupCmdCipsend, at_exeCmdCipsend},\r\n  {\"+CIPMUX\", 7, NULL, at_queryCmdCipmux, at_setupCmdCipmux, NULL},\r\n  {\"+CIPSERVER\", 10, NULL, NULL,at_setupCmdCipserver, NULL},\r\n  {\"+CIPMODE\", 8, NULL, at_queryCmdCipmode, at_setupCmdCipmode, NULL},\r\n  {\"+CIPSTO\", 7, NULL, at_queryCmdCipsto, at_setupCmdCipsto, NULL},\r\n  {\"+CIUPDATE\", 9, NULL, NULL, NULL, at_exeCmdUpdate},\r\n  \/\/\r\n  \/\/ user commands\r\n  \/\/\r\n  {\"+CIUSRMAC\", 9, NULL, NULL, NULL, at_exeCmdGetMacAddress}\r\n};\r\n\r\n#endif\r\n\r\n<\/code><\/pre>\n<p>Notice the extra comma (&#8220;,&#8221;) after at_exeCmdUpdate. As the array shows I have added the function CIUSRMAC and if entered like &#8220;AT+CIUSRMAC&#8221; the function at_exeCmdGetMacAddress() will be called which is in our myFunctions.c. <\/p>\n<p>Thats it&#8230;.. compile and upload it into the firmware and try it out.<br \/>\n&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nou doubt I will be, as we call it here in Holland, &#8220;swearing in the church&#8221; but I will show you how to create your own functions in the AT Demo. This to give you some idea how to build &hellip; <a href=\"https:\/\/www.verelec.nl\/?page_id=557\">Lees verder <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"open","ping_status":"open","template":"","meta":{"footnotes":""},"_links":{"self":[{"href":"https:\/\/www.verelec.nl\/index.php?rest_route=\/wp\/v2\/pages\/557"}],"collection":[{"href":"https:\/\/www.verelec.nl\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.verelec.nl\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.verelec.nl\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.verelec.nl\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=557"}],"version-history":[{"count":1,"href":"https:\/\/www.verelec.nl\/index.php?rest_route=\/wp\/v2\/pages\/557\/revisions"}],"predecessor-version":[{"id":559,"href":"https:\/\/www.verelec.nl\/index.php?rest_route=\/wp\/v2\/pages\/557\/revisions\/559"}],"wp:attachment":[{"href":"https:\/\/www.verelec.nl\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=557"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}