log, some small fixes

This commit is contained in:
livello
2018-10-11 00:43:09 +03:00
parent 9432898b03
commit 39f655ff78
7 changed files with 131 additions and 68 deletions

View File

@@ -153,6 +153,9 @@ platformio device monitor -b 115200
* WIFI_MANAGER_DISABLE //Disable wifi manager for esp8266 * WIFI_MANAGER_DISABLE //Disable wifi manager for esp8266
* DHT_DISABLE //disable DHT Input support * DHT_DISABLE //disable DHT Input support
* RESTART_LAN_ON_MQTT_ERRORS //reinit LAN if many mqtt errors occured * RESTART_LAN_ON_MQTT_ERRORS //reinit LAN if many mqtt errors occured
* WITH_STREAMING_LIB use streaming libriary for serial debug output otherwise use PrintEx library
* DEVICE_NAME short handy device name which is used instead of mac for download config http://{MY_CONFIG_SERVER}/{DEVICE_NAME}_config.json
* SYSLOG_ENABLE enable UDP SYSLOG support feature(under DEVELOPMENT) that must be configured through config file
@@ -176,5 +179,8 @@ platformio device monitor -b 115200
* DHT support enabled * DHT support enabled
* Wifi manager for esp8266 enabled * Wifi manager for esp8266 enabled
* RESTART_LAN_ON_MQTT_ERRORS disabled * RESTART_LAN_ON_MQTT_ERRORS disabled
* WITH_STREAMING_LIB disabled
* DEVICE_NAME disabled
* SYSLOG_ENABLE disabled
If you've using Arduino IDE to compile & flash firmware, it will use Default options above and you will not able to configure additional compilers options except edit "options.h" file If you've using Arduino IDE to compile & flash firmware, it will use Default options above and you will not able to configure additional compilers options except edit "options.h" file

View File

@@ -25,5 +25,7 @@
# export FLAGS="$FLAGS -DDHCP_RETRY_INTERVAL=60000" # export FLAGS="$FLAGS -DDHCP_RETRY_INTERVAL=60000"
# export FLAGS="$FLAGS -DRESTART_LAN_ON_MQTT_ERRORS" # export FLAGS="$FLAGS -DRESTART_LAN_ON_MQTT_ERRORS"
# export FLAGS="$FLAGS -DW5500_CS_PIN=53" # export FLAGS="$FLAGS -DW5500_CS_PIN=53"
#export FLAGS="$FLAGS -DSYSLOG_ENABLE"
#export FLAGS="$FLAGS -DDEVICE_NAME=MYDEVICE"
export FLAGS="$FLAGS -DPIO_SRC_REV="$(git log --pretty=format:%h_%ad -1 --date=short) export FLAGS="$FLAGS -DPIO_SRC_REV="$(git log --pretty=format:%h_%ad -1 --date=short)
echo $FLAGS echo $FLAGS

View File

@@ -67,6 +67,7 @@ PWM Out
#include "Arduino.h" #include "Arduino.h"
#include "main.h" #include "main.h"
#include "options.h" #include "options.h"
#include "utils.h"
#ifdef WITH_STREAMING_LIB #ifdef WITH_STREAMING_LIB
#include "Streaming.h" #include "Streaming.h"
#else #else
@@ -113,7 +114,7 @@ WiFiClient ethClient;
EthernetClient ethClient; EthernetClient ethClient;
#endif #endif
#ifndef SYSLOG_DISABLE #ifdef SYSLOG_ENABLE
#include <Syslog.h> #include <Syslog.h>
EthernetUDP udpSyslogClient; EthernetUDP udpSyslogClient;
Syslog udpSyslog(udpSyslogClient, SYSLOG_PROTO_IETF); Syslog udpSyslog(udpSyslogClient, SYSLOG_PROTO_IETF);
@@ -208,8 +209,11 @@ void mqttCallback(char *topic, byte *payload, unsigned int length) {
void printIPAddress(IPAddress ipAddress) { void printIPAddress(IPAddress ipAddress) {
for (byte i = 0; i < 4; i++) for (byte i = 0; i < 4; i++)
// (i < 3) ? debugSerial << _DEC(ipAddress[i]) << F(".") : debugSerial << _DEC(ipAddress[i])<<F(", "); #ifdef WITH_STREAMING_LIB
(i < 3) ? debugSerial << (ipAddress[i]) << F(".") : debugSerial << (ipAddress[i])<<F(", "); (i < 3) ? debugSerial << _DEC(ipAddress[i]) << F(".") : debugSerial << _DEC(ipAddress[i]) << F(", ");
#else
(i < 3) ? debugSerial << (ipAddress[i]) << F(".") : debugSerial << (ipAddress[i])<<F(", ");
#endif
} }
void printMACAddress() { void printMACAddress() {
@@ -282,7 +286,7 @@ lan_status lanLoop() {
break; break;
case READ_RE_CONFIG: case READ_RE_CONFIG:
if (loadConfigFromEEPROM(0, NULL)) lanStatus = IP_READY_CONFIG_LOADED_CONNECTING_TO_BROKER;//2; if (loadConfigFromEEPROM()) lanStatus = IP_READY_CONFIG_LOADED_CONNECTING_TO_BROKER;//2;
else { else {
nextLanCheckTime = millis() + 5000; nextLanCheckTime = millis() + 5000;
lanStatus = AWAITING_ADDRESS;//-10; lanStatus = AWAITING_ADDRESS;//-10;
@@ -348,7 +352,7 @@ void ip_ready_config_loaded_connecting_to_broker() {
char *user = &empty; char *user = &empty;
char passwordBuf[16] = ""; char passwordBuf[16] = "";
char *password = passwordBuf; char *password = passwordBuf;
#ifndef SYSLOG_DISABLE #ifdef SYSLOG_ENABLE
debugSerial<<"debugSerial:"; debugSerial<<"debugSerial:";
delay(100); delay(100);
if (udpSyslogArr && aJson.getArraySize(udpSyslogArr)) { if (udpSyslogArr && aJson.getArraySize(udpSyslogArr)) {
@@ -575,9 +579,7 @@ void Changed(int i, DeviceAddress addr, int val) {
owEmit = aJson.getObjectItem(owObj, "emit")->valuestring; owEmit = aJson.getObjectItem(owObj, "emit")->valuestring;
if (owEmit) { if (owEmit) {
strncpy(addrbuf, owEmit, sizeof(addrbuf)); strncpy(addrbuf, owEmit, sizeof(addrbuf));
debugSerial<<owEmit; debugSerial<<owEmit<<F("=")<<val;
debugSerial<<F("=");
debugSerial<<val;
} }
owItem = aJson.getObjectItem(owObj, "item")->valuestring; owItem = aJson.getObjectItem(owObj, "item")->valuestring;
} else debugSerial<<F("1w-item not found in config"); } else debugSerial<<F("1w-item not found in config");
@@ -601,12 +603,12 @@ void Changed(int i, DeviceAddress addr, int val) {
void cmdFunctionHelp(int arg_cnt, char **args) void cmdFunctionHelp(int arg_cnt, char **args)
{ {
printFirmwareVersionAndBuildOptions(); printFirmwareVersionAndBuildOptions();
#ifndef SYSLOG_DISABLE #ifdef SYSLOG_ENABLE
// udpSyslog.logf(LOG_INFO, "free RAM: %d",freeRam()); // udpSyslog.logf(LOG_INFO, "free RAM: %d",freeRam());
#endif #endif
printCurentLanConfig(); printCurentLanConfig();
printFreeRam();
debugSerial<<F(" free RAM: ")<<freeRam()<<F(" Use the commands: 'help' - this text\n" debugSerial<<F("\nUse these commands: 'help' - this text\n"
"'mac de:ad:be:ef:fe:00' set and store MAC-address in EEPROM\n" "'mac de:ad:be:ef:fe:00' set and store MAC-address in EEPROM\n"
"'ip [ip[,dns[,gw[,subnet]]]]' - set static IP\n" "'ip [ip[,dns[,gw[,subnet]]]]' - set static IP\n"
"'save' - save config in NVRAM\n" "'save' - save config in NVRAM\n"
@@ -730,11 +732,11 @@ void printConfigSummary() {
} }
void cmdFunctionLoad(int arg_cnt, char **args) { void cmdFunctionLoad(int arg_cnt, char **args) {
loadConfigFromEEPROM(arg_cnt, args); loadConfigFromEEPROM();
restoreState(); restoreState();
} }
int loadConfigFromEEPROM(int arg_cnt, char **args) int loadConfigFromEEPROM()
{ {
char ch; char ch;
debugSerial<<F("loading Config"); debugSerial<<F("loading Config");
@@ -847,7 +849,6 @@ void cmdFunctionClearEEPROM(int arg_cnt, char **args){
} }
void cmdFunctionPwd(int arg_cnt, char **args) void cmdFunctionPwd(int arg_cnt, char **args)
//(char* tokens)
{ char empty[]=""; { char empty[]="";
if (arg_cnt) if (arg_cnt)
saveFlash(OFFSET_MQTT_PWD,args[1]); saveFlash(OFFSET_MQTT_PWD,args[1]);
@@ -856,16 +857,7 @@ void cmdFunctionPwd(int arg_cnt, char **args)
} }
void cmdFunctionSetMac(int arg_cnt, char **args) { void cmdFunctionSetMac(int arg_cnt, char **args) {
if (sscanf(args[1], "%x:%x:%x:%x:%x:%x%с", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]) < 6) {
//debugSerial<<"Got:");
//debugSerial<<args[1]);
if (sscanf(args[1], "%x:%x:%x:%x:%x:%x%с",
&mac[0],
&mac[1],
&mac[2],
&mac[3],
&mac[4],
&mac[5]) < 6) {
debugSerial<<F("could not parse: ")<<args[1]; debugSerial<<F("could not parse: ")<<args[1];
return; return;
} }
@@ -905,9 +897,9 @@ void saveFlash(short n, IPAddress& ip) {
} }
int ipLoadFromFlash(short n, IPAddress &ip) { int ipLoadFromFlash(short n, IPAddress &ip) {
for(int i=0;i<4;i++) ip[i]=EEPROM.read(n++); for (int i = 0; i < 4; i++)
if (ip[0] && (ip[0] != 0xff)) return 1; ip[i] = EEPROM.read(n++);
return 0; return (ip[0] && (ip[0] != 0xff));
} }
lan_status loadConfigFromHttp(int arg_cnt, char **args) lan_status loadConfigFromHttp(int arg_cnt, char **args)
@@ -921,9 +913,12 @@ lan_status loadConfigFromHttp(int arg_cnt, char **args)
saveFlash(OFFSET_CONFIGSERVER, configServer); saveFlash(OFFSET_CONFIGSERVER, configServer);
} else if (!loadFlash(OFFSET_CONFIGSERVER, configServer)) } else if (!loadFlash(OFFSET_CONFIGSERVER, configServer))
strncpy_P(configServer,configserver,sizeof(configServer)); strncpy_P(configServer,configserver,sizeof(configServer));
#ifndef DEVICE_NAME
snprintf(URI, sizeof(URI), "/%02x-%02x-%02x-%02x-%02x-%02x.config.json", mac[0], mac[1], mac[2], mac[3], mac[4], snprintf(URI, sizeof(URI), "/%02x-%02x-%02x-%02x-%02x-%02x.config.json", mac[0], mac[1], mac[2], mac[3], mac[4],
mac[5]); mac[5]);
#else
snprintf(URI, sizeof(URI), "/%s_config.json",QUOTE(DEVICE_NAME));
#endif
debugSerial<<F("Config URI: http://")<<configServer<<URI; debugSerial<<F("Config URI: http://")<<configServer<<URI;
#if defined(__AVR__) #if defined(__AVR__)
@@ -1084,7 +1079,7 @@ void setup_main() {
sd_card_w5100_setup(); sd_card_w5100_setup();
#endif #endif
setupMacAddress(); setupMacAddress();
loadConfigFromEEPROM(0, NULL); loadConfigFromEEPROM();
#ifdef _modbus #ifdef _modbus
#ifdef CONTROLLINO #ifdef CONTROLLINO
@@ -1128,7 +1123,7 @@ void setup_main() {
} }
void printFirmwareVersionAndBuildOptions() { void printFirmwareVersionAndBuildOptions() {
debugSerial<<F("\nLazyhome.ru LightHub controller ")<<F(QUOTE(PIO_SRC_REV))<<F("C++ version:")<<F(QUOTE(__cplusplus)); debugSerial<<F("\nLazyhome.ru LightHub controller ")<<F(QUOTE(PIO_SRC_REV))<<F(" C++ version:")<<F(QUOTE(__cplusplus));
#ifdef CONTROLLINO #ifdef CONTROLLINO
debugSerial<<F("\n(+)CONTROLLINO"); debugSerial<<F("\n(+)CONTROLLINO");
#endif #endif
@@ -1145,8 +1140,7 @@ void printFirmwareVersionAndBuildOptions() {
#endif #endif
#ifdef USE_1W_PIN #ifdef USE_1W_PIN
debugSerial<<F("(-)DS2482-100 USE_1W_PIN="); debugSerial<<F("\n(-)DS2482-100 USE_1W_PIN=")<<QUOTE(USE_1W_PIN);
debugSerial<<QUOTE(USE_1W_PIN);
#else #else
debugSerial<<F("\n(+)DS2482-100"); debugSerial<<F("\n(+)DS2482-100");
#endif #endif
@@ -1156,7 +1150,7 @@ void printFirmwareVersionAndBuildOptions() {
#endif #endif
#ifdef DMX_DISABLE #ifdef DMX_DISABLE
debugSerial<<F("(-)DMX"); debugSerial<<F("\n(-)DMX");
#else #else
debugSerial<<F("\n(+)DMX"); debugSerial<<F("\n(+)DMX");
#endif #endif
@@ -1183,8 +1177,7 @@ void printFirmwareVersionAndBuildOptions() {
#endif #endif
#ifdef RESET_PIN #ifdef RESET_PIN
debugSerial<<F("\n(+)HARDRESET on pin="); debugSerial<<F("\n(+)HARDRESET on pin=")<<F(QUOTE(RESET_PIN);
debugSerial<<F(QUOTE(RESET_PIN);
#else #else
debugSerial<<F("\n(-)HARDRESET, using soft"); debugSerial<<F("\n(-)HARDRESET, using soft");
#endif #endif
@@ -1195,6 +1188,9 @@ void printFirmwareVersionAndBuildOptions() {
debugSerial<<F("\n(-)RESTART_LAN_ON_MQTT_ERRORS"); debugSerial<<F("\n(-)RESTART_LAN_ON_MQTT_ERRORS");
#endif #endif
} }
void printFreeRam(){
debugSerial<<F("\nfree RAM: ")<<freeRam();
}
void setupMacAddress() { void setupMacAddress() {
@@ -1271,7 +1267,7 @@ void loop_main() {
dmxout.update(); dmxout.update();
#endif #endif
#ifndef SYSLOG_DISABLE #ifdef SYSLOG_ENABLE
// debugSerial<<F("#")); // debugSerial<<F("#"));
// udpSyslog.log(LOG_INFO, "Ping syslog:"); // udpSyslog.log(LOG_INFO, "Ping syslog:");
#endif #endif
@@ -1416,8 +1412,7 @@ void thermoLoop(void) {
nextThermostatCheck = millis() + THERMOSTAT_CHECK_PERIOD; nextThermostatCheck = millis() + THERMOSTAT_CHECK_PERIOD;
#ifndef DISABLE_FREERAM_PRINT #ifndef DISABLE_FREERAM_PRINT
(thermostatCheckPrinted) ? debugSerial<<F("\nfree:") : debugSerial<<F(" "); (thermostatCheckPrinted) ? debugSerial<<F("\nfree:")<<freeRam()<<" " : debugSerial<<F(" ")<<freeRam()<<F(" ");
debugSerial<<freeRam()<<" ";
#endif #endif
} }

View File

@@ -169,7 +169,7 @@ void applyConfig();
void cmdFunctionLoad(int arg_cnt, char **args); void cmdFunctionLoad(int arg_cnt, char **args);
int loadConfigFromEEPROM(int arg_cnt, char **args); int loadConfigFromEEPROM();
void cmdFunctionReq(int arg_cnt, char **args); void cmdFunctionReq(int arg_cnt, char **args);
@@ -237,3 +237,5 @@ void ip_ready_config_loaded_connecting_to_broker();
void printCurentLanConfig(); void printCurentLanConfig();
void printFreeRam();

View File

@@ -47,7 +47,7 @@ int owUpdate() {
short sr; short sr;
//net.setStrongPullup(); //net.setStrongPullup();
Serial.println(F("Searching")); debugSerial.println(F("Searching"));
if (net) net->reset_search(); if (net) net->reset_search();
for (short i = 0; i < t_count; i++) wstat[i] &= ~SW_FIND; //absent for (short i = 0; i < t_count; i++) wstat[i] &= ~SW_FIND; //absent
@@ -58,18 +58,18 @@ int owUpdate() {
if (!memcmp(term[i], term[t_count], 8)) { if (!memcmp(term[i], term[t_count], 8)) {
ifind = i; ifind = i;
wstat[i] |= SW_FIND; wstat[i] |= SW_FIND;
Serial.print(F(" Node:")); debugSerial.print(F(" Node:"));
PrintBytes(term[t_count], 8); PrintBytes(term[t_count], 8,0);
Serial.println(F(" alive")); debugSerial.println(F(" alive"));
break; break;
}; //alive }; //alive
if (ifind < 0 && sensors) { if (ifind < 0 && sensors) {
wstat[t_count] = SW_FIND; //Newly detected wstat[t_count] = SW_FIND; //Newly detected
Serial.print(F("dev#")); debugSerial.print(F("dev#"));
Serial.print(t_count); debugSerial.print(t_count);
Serial.print(F(" Addr:")); debugSerial.print(F(" Addr:"));
PrintBytes(term[t_count], 8); PrintBytes(term[t_count], 8,0);
Serial.println(); debugSerial.println();
if (term[t_count][0] == 0x28) { if (term[t_count][0] == 0x28) {
sensors->setResolution(term[t_count], TEMPERATURE_PRECISION); sensors->setResolution(term[t_count], TEMPERATURE_PRECISION);
net->setStrongPullup(); net->setStrongPullup();
@@ -80,8 +80,8 @@ int owUpdate() {
}//if }//if
} //while } //while
Serial.print(F("1-wire count: ")); debugSerial.print(F("1-wire count: "));
Serial.println(t_count); debugSerial.println(t_count);
#endif #endif
} }
@@ -91,12 +91,12 @@ int owSetup(owChangedType owCh) {
//// todo - move memory allocation to here //// todo - move memory allocation to here
if (net) return true; // Already initialized if (net) return true; // Already initialized
#ifdef DS2482_100_I2C_TO_1W_BRIDGE #ifdef DS2482_100_I2C_TO_1W_BRIDGE
Serial.println(F("DS2482_100_I2C_TO_1W_BRIDGE init")); debugSerial.println(F("DS2482_100_I2C_TO_1W_BRIDGE init"));
net = new OneWire; net = new OneWire;
#else #else
Serial.print(F("One wire setup on PIN:")); debugSerial.print(F("One wire setup on PIN:"));
Serial.println(QUOTE(USE_1W_PIN)); debugSerial.println(QUOTE(USE_1W_PIN));
net = new OneWire (USE_1W_PIN); net = new OneWire (USE_1W_PIN);
#endif #endif
@@ -112,29 +112,29 @@ net = new OneWire (USE_1W_PIN);
#ifdef DS2482_100_I2C_TO_1W_BRIDGE #ifdef DS2482_100_I2C_TO_1W_BRIDGE
Wire.begin(); Wire.begin();
if (net->checkPresence()) { if (net->checkPresence()) {
Serial.println(F("DS2482-100 present")); debugSerial.println(F("DS2482-100 present"));
net->deviceReset(); net->deviceReset();
#ifdef APU_OFF #ifdef APU_OFF
Serial.println(F("APU off")); debugSerial.println(F("APU off"));
#else #else
net->setActivePullup(); net->setActivePullup();
#endif #endif
Serial.println(F("\tChecking for 1-Wire devices...")); debugSerial.println(F("\tChecking for 1-Wire devices..."));
if (net->wireReset()) if (net->wireReset())
Serial.println(F("\tReset done")); debugSerial.println(F("\tReset done"));
sensors->begin(); sensors->begin();
owChanged = owCh; owChanged = owCh;
//owUpdate(); //owUpdate();
//Serial.println(F("\t1-w Updated")); //debugSerial.println(F("\t1-w Updated"));
sensors->setWaitForConversion(false); sensors->setWaitForConversion(false);
return true; return true;
} }
#endif #endif
Serial.println(F("\tDS2482 error")); debugSerial.println(F("\tDS2482 error"));
return false; return false;
// IC Default 9 bit. If you have troubles consider upping it 12. Ups the delay giving the IC more time to process the temperature measurement // IC Default 9 bit. If you have troubles consider upping it 12. Ups the delay giving the IC more time to process the temperature measurement
@@ -158,7 +158,7 @@ int sensors_loop(void) {
case 0x28: // Thermomerer case 0x28: // Thermomerer
t = sensors->getTempC(term[si]);//*10.0; t = sensors->getTempC(term[si]);//*10.0;
//Serial.println("o"); //debugSerial.println("o");
if (owChanged) owChanged(si, term[si], t); if (owChanged) owChanged(si, term[si], t);
sensors->requestTemperaturesByAddress(term[si]); sensors->requestTemperaturesByAddress(term[si]);
si++; si++;
@@ -192,11 +192,11 @@ void owAdd(DeviceAddress addr) {
memcpy(term[t_count], addr, 8); memcpy(term[t_count], addr, 8);
//term[t_count]=addr; //term[t_count]=addr;
Serial.print(F("dev#")); debugSerial.print(F("dev#"));
Serial.print(t_count); debugSerial.print(t_count);
Serial.print(F(" Addr:")); debugSerial.print(F(" Addr:"));
PrintBytes(term[t_count], 8); PrintBytes(term[t_count], 8,0);
Serial.println(); debugSerial.println();
if (term[t_count][0] == 0x28) { if (term[t_count][0] == 0x28) {
sensors->setResolution(term[t_count], TEMPERATURE_PRECISION); sensors->setResolution(term[t_count], TEMPERATURE_PRECISION);
net->setStrongPullup(); net->setStrongPullup();

View File

@@ -19,6 +19,7 @@ e-mail anklimov@gmail.com
*/ */
#include "utils.h" #include "utils.h"
#include "options.h"
#if defined(__SAM3X8E__) || defined(ARDUINO_ARCH_STM32F1) #if defined(__SAM3X8E__) || defined(ARDUINO_ARCH_STM32F1)
#include <malloc.h> #include <malloc.h>
@@ -134,5 +135,61 @@ void parseBytes(const char *str, char separator, byte *bytes, int maxBytes, int
str++; // Point to next character after separator str++; // Point to next character after separator
} }
} }
#define ARDBUFFER 16 //Buffer for storing intermediate strings. Performance may vary depending on size.
int log(const char *str, ...)//TODO: __FlashStringHelper str support
{
int i, count=0, j=0, flag=0;
char temp[ARDBUFFER+1];
for(i=0; str[i]!='\0';i++) if(str[i]=='%') count++; //Evaluate number of arguments required to be printed
va_list argv;
va_start(argv, count);
for(i=0,j=0; str[i]!='\0';i++) //Iterate over formatting string
{
if(str[i]=='%')
{
//Clear buffer
temp[j] = '\0';
Serial.print(temp);
j=0;
temp[0] = '\0';
//Process argument
switch(str[++i])
{
case 'd': debugSerial.print(va_arg(argv, int));
break;
case 'l': debugSerial.print(va_arg(argv, long));
break;
case 'f': debugSerial.print(va_arg(argv, double));
break;
case 'c': debugSerial.print((char)va_arg(argv, int));
break;
case 's': debugSerial.print(va_arg(argv, char *));
break;
default: ;
};
}
else
{
//Add to buffer
temp[j] = str[i];
j = (j+1)%ARDBUFFER;
if(j==0) //If buffer is full, empty buffer.
{
temp[ARDBUFFER] = '\0';
debugSerial.print(temp);
temp[0]='\0';
}
}
};
Serial.println(); //Print trailing newline
return count + 1; //Return number of arguments detected
}
#pragma message(VAR_NAME_VALUE(debugSerial)) #pragma message(VAR_NAME_VALUE(debugSerial))
#pragma message(VAR_NAME_VALUE(SERIAL_BAUD)) #pragma message(VAR_NAME_VALUE(SERIAL_BAUD))

View File

@@ -25,10 +25,11 @@ e-mail anklimov@gmail.com
#include <Arduino.h> #include <Arduino.h>
void PrintBytes(uint8_t* addr, uint8_t count, bool newline=0); void PrintBytes(uint8_t* addr, uint8_t count, bool newline);
void SetBytes(uint8_t* addr, uint8_t count, char * out); void SetBytes(uint8_t* addr, uint8_t count, char * out);
void SetAddr(char * out, uint8_t* addr); void SetAddr(char * out, uint8_t* addr);
uint8_t HEX2DEC(char i); uint8_t HEX2DEC(char i);
int getInt(char ** chan); int getInt(char ** chan);
unsigned long freeRam (); unsigned long freeRam ();
void parseBytes(const char* str, char separator, byte* bytes, int maxBytes, int base); void parseBytes(const char* str, char separator, byte* bytes, int maxBytes, int base);
int log(const char *str, ...);