mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
0.2.2 major updates XMLWriter
This commit is contained in:
parent
6680ecdffd
commit
5b156b7099
21
libraries/XMLWriter/LICENSE
Normal file
21
libraries/XMLWriter/LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2013-2020 Rob Tillaart
|
||||||
|
|
||||||
|
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.
|
35
libraries/XMLWriter/README.md
Normal file
35
libraries/XMLWriter/README.md
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# XMLWriter
|
||||||
|
|
||||||
|
Arduino Library to create simple XML (messages, files, print, ...)
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
The XMLWriter class supports generating XML files and send these over a stream
|
||||||
|
like Ethernet SD.File or Serial.
|
||||||
|
|
||||||
|
When instantiating an XMLWriter one can define the internal buffer size.
|
||||||
|
This buffering makes the output faster, especially for Ethernet and SD.File.
|
||||||
|
The buffer size should be at least 2 bytes.
|
||||||
|
A bigger buffer is often faster but it also depends on the properties of the
|
||||||
|
stream to see real performance gains.
|
||||||
|
E.g. the baudrate and internal buffer of Serial, packet behaviour of Ethernet,
|
||||||
|
or paging of SD cards.
|
||||||
|
So if performance is an issue one should do some testruns with different sizes
|
||||||
|
for the buffer and choose one that is appropriate.
|
||||||
|
|
||||||
|
Indicative sizes based upon the examples.
|
||||||
|
Run your tests to find your application optimum.
|
||||||
|
|
||||||
|
| STREAM | SIZE |
|
||||||
|
|:------------|:----------|
|
||||||
|
| Ethernet | 20-30 |
|
||||||
|
| Serial | 5 |
|
||||||
|
| SD File | 10-16 |
|
||||||
|
|
||||||
|
Important to know when usinig buffering is that your code should always include
|
||||||
|
a call to **XML.flush()** at the end of the XML generation to flush the buffer.
|
||||||
|
|
||||||
|
## Operation
|
||||||
|
|
||||||
|
See examples
|
||||||
|
|
@ -1,9 +1,9 @@
|
|||||||
//
|
//
|
||||||
// FILE: XMLWriter.cpp
|
// FILE: XMLWriter.cpp
|
||||||
// AUTHOR: Rob Tillaart
|
// AUTHOR: Rob Tillaart
|
||||||
// VERSION: 0.1.8
|
// VERSION: 0.2.2
|
||||||
// DATE: 2013-11-06
|
// DATE: 2013-11-06
|
||||||
// PURPOSE: Simple XML library
|
// PURPOSE: Arduino library for creating XML
|
||||||
//
|
//
|
||||||
// HISTORY:
|
// HISTORY:
|
||||||
// 0.1.00 2013-11-06 initial version
|
// 0.1.00 2013-11-06 initial version
|
||||||
@ -15,39 +15,62 @@
|
|||||||
// 0.1.6 2016-03-16 added incrIndent(), decrIndent(), indent(), raw();
|
// 0.1.6 2016-03-16 added incrIndent(), decrIndent(), indent(), raw();
|
||||||
// 0.1.7 2017-07-26 added const where possible
|
// 0.1.7 2017-07-26 added const where possible
|
||||||
// 0.1.8 2017-12-09 fix casting issue #83 (long -> int32_t);
|
// 0.1.8 2017-12-09 fix casting issue #83 (long -> int32_t);
|
||||||
//
|
// 0.1.9 2017-12-09 add PROGMEM support for escape() strings
|
||||||
// Released to the public domain
|
// 0.2.0 2020-04-24 refactor, added examples, #pragma, print as base class
|
||||||
|
// 0.2.1 2020-04-26 performance optimized, setconfig() + newLine() added
|
||||||
|
// 0.2.2 2020-04-29 dynamic buffer size in constructor
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <XMLWriter.h>
|
#include <XMLWriter.h>
|
||||||
|
|
||||||
XMLWriter::XMLWriter(Print* stream)
|
XMLWriter::XMLWriter(Print* stream, uint8_t bufsize)
|
||||||
{
|
{
|
||||||
|
_bufsize = constrain(bufsize, 2, 250);
|
||||||
|
_buffer = (char *) malloc(_bufsize);
|
||||||
_stream = stream;
|
_stream = stream;
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XMLWriter::~XMLWriter()
|
||||||
|
{
|
||||||
|
if (_buffer != NULL) free(_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
void XMLWriter::reset()
|
void XMLWriter::reset()
|
||||||
{
|
{
|
||||||
_indent = 0;
|
_indent = 0;
|
||||||
_indentStep = 2;
|
_indentStep = 2;
|
||||||
_idx = 0;
|
_tidx = 0;
|
||||||
|
_bidx = 0;
|
||||||
|
_config = XMLWRITER_COMMENT | XMLWRITER_INDENT | XMLWRITER_NEWLINE;
|
||||||
|
_bytesOut = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLWriter::header()
|
void XMLWriter::header()
|
||||||
{
|
{
|
||||||
_stream->println(F("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"));
|
print(F("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLWriter::comment(const char* text, const bool multiLine)
|
void XMLWriter::comment(const char* text, const bool multiLine)
|
||||||
{
|
{
|
||||||
_stream->println();
|
if (_config & XMLWRITER_COMMENT)
|
||||||
|
{
|
||||||
|
print('\n');
|
||||||
if (!multiLine) indent();
|
if (!multiLine) indent();
|
||||||
_stream->print(F("<!-- "));
|
print(F("<!-- "));
|
||||||
if (multiLine) _stream->println();
|
if (multiLine) print('\n');
|
||||||
_stream->print(text);
|
print(text);
|
||||||
if (multiLine) _stream->println();
|
if (multiLine) print('\n');
|
||||||
_stream->println(F(" -->"));
|
print(F(" -->\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void XMLWriter::newLine(uint8_t n)
|
||||||
|
{
|
||||||
|
if (_config & XMLWRITER_NEWLINE)
|
||||||
|
{
|
||||||
|
while(n--) print('\n');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLWriter::tagOpen(const char* tag, const bool newline)
|
void XMLWriter::tagOpen(const char* tag, const bool newline)
|
||||||
@ -57,8 +80,15 @@ void XMLWriter::tagOpen(const char* tag, const bool newline)
|
|||||||
|
|
||||||
void XMLWriter::tagOpen(const char* tag, const char* name, const bool newline)
|
void XMLWriter::tagOpen(const char* tag, const char* name, const bool newline)
|
||||||
{
|
{
|
||||||
// TODO STACK GUARD
|
if (_tidx > XMLWRITER_MAXLEVEL)
|
||||||
strncpy(tagStack[_idx++], tag, XMLWRITER_MAXTAGSIZE);
|
{
|
||||||
|
comment("XMLWRITER_MAXLEVEL exceeded.");
|
||||||
|
comment(tag);
|
||||||
|
comment(name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// "unsafe" strcpy saves ~20 bytes
|
||||||
|
strncpy(_tagStack[_tidx++], tag, XMLWRITER_MAXTAGSIZE);
|
||||||
tagStart(tag);
|
tagStart(tag);
|
||||||
if (name[0] != 0) tagField("name", name);
|
if (name[0] != 0) tagField("name", name);
|
||||||
tagEnd(newline, NOSLASH);
|
tagEnd(newline, NOSLASH);
|
||||||
@ -69,36 +99,37 @@ void XMLWriter::tagClose(const bool ind)
|
|||||||
{
|
{
|
||||||
_indent -= _indentStep;
|
_indent -= _indentStep;
|
||||||
if (ind) indent();
|
if (ind) indent();
|
||||||
_stream->print(F("</"));
|
print("</");
|
||||||
_stream->print(tagStack[--_idx]);
|
print(_tagStack[--_tidx]);
|
||||||
_stream->println(F(">"));
|
print(">\n");
|
||||||
|
delay(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLWriter::tagStart(const char *tag)
|
void XMLWriter::tagStart(const char *tag)
|
||||||
{
|
{
|
||||||
indent();
|
indent();
|
||||||
_stream->print('<');
|
print('<');
|
||||||
_stream->print(tag);
|
print(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLWriter::tagField(const char *field, const char* str)
|
void XMLWriter::tagField(const char *field, const char* str)
|
||||||
{
|
{
|
||||||
_stream->print(' ');
|
print(' ');
|
||||||
_stream->print(field);
|
print(field);
|
||||||
_stream->print(F("=\""));
|
print("=\"");
|
||||||
#ifdef XMLWRITER_ESCAPE_SUPPORT
|
#ifdef XMLWRITER_ESCAPE_SUPPORT
|
||||||
escape(str);
|
escape(str);
|
||||||
#else
|
#else
|
||||||
_stream->print(str);
|
print(str);
|
||||||
#endif
|
#endif
|
||||||
_stream->print('"');
|
print('"');
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLWriter::tagEnd(const bool newline, const bool addSlash)
|
void XMLWriter::tagEnd(const bool newline, const bool addSlash)
|
||||||
{
|
{
|
||||||
if (addSlash) _stream->print('/');
|
if (addSlash) print("/>");
|
||||||
_stream->print('>');
|
else print('>');
|
||||||
if (newline) _stream->println();
|
if (newline) print('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLWriter::writeNode(const char* tag, const char* str)
|
void XMLWriter::writeNode(const char* tag, const char* str)
|
||||||
@ -107,7 +138,7 @@ void XMLWriter::writeNode(const char* tag, const char* str)
|
|||||||
#ifdef XMLWRITER_ESCAPE_SUPPORT
|
#ifdef XMLWRITER_ESCAPE_SUPPORT
|
||||||
escape(str);
|
escape(str);
|
||||||
#else
|
#else
|
||||||
_stream->print(str);
|
print(str);
|
||||||
#endif
|
#endif
|
||||||
tagClose(NOINDENT);
|
tagClose(NOINDENT);
|
||||||
}
|
}
|
||||||
@ -129,11 +160,11 @@ void XMLWriter::tagField(const char *field, const uint16_t value, const uint8_t
|
|||||||
|
|
||||||
void XMLWriter::tagField(const char *field, const uint32_t value, const uint8_t base)
|
void XMLWriter::tagField(const char *field, const uint32_t value, const uint8_t base)
|
||||||
{
|
{
|
||||||
_stream->print(' ');
|
print(' ');
|
||||||
_stream->print(field);
|
print(field);
|
||||||
_stream->print(F("=\""));
|
print("=\"");
|
||||||
_stream->print(value, base);
|
print(value, base);
|
||||||
_stream->print('"');
|
print('"');
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLWriter::tagField(const char *field, const int8_t value, const uint8_t base)
|
void XMLWriter::tagField(const char *field, const int8_t value, const uint8_t base)
|
||||||
@ -148,30 +179,28 @@ void XMLWriter::tagField(const char *field, const int16_t value, const uint8_t b
|
|||||||
|
|
||||||
void XMLWriter::tagField(const char *field, const int32_t value, const uint8_t base)
|
void XMLWriter::tagField(const char *field, const int32_t value, const uint8_t base)
|
||||||
{
|
{
|
||||||
_stream->print(' ');
|
print(' ');
|
||||||
_stream->print(field);
|
print(field);
|
||||||
_stream->print(F("=\""));
|
print("=\"");
|
||||||
_stream->print(value, base);
|
print(value, base);
|
||||||
_stream->print('"');
|
print('"');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void XMLWriter::tagField(const char *field, const bool value)
|
void XMLWriter::tagField(const char *field, const bool value)
|
||||||
{
|
{
|
||||||
_stream->print(' ');
|
print(' ');
|
||||||
_stream->print(field);
|
print(field);
|
||||||
_stream->print(F("=\""));
|
// F() is slower & uses less RAM but 15 bytes saved
|
||||||
_stream->print(value?F("true"):F("false"));
|
print(value ? F("=\"true\"") : F("=\"false\""));
|
||||||
_stream->print('"');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLWriter::tagField(const char *field, const double value, const uint8_t decimals)
|
void XMLWriter::tagField(const char *field, const double value, const uint8_t decimals)
|
||||||
{
|
{
|
||||||
_stream->print(' ');
|
print(' ');
|
||||||
_stream->print(field);
|
print(field);
|
||||||
_stream->print(F("=\""));
|
print(F("=\""));
|
||||||
_stream->print(value, decimals);
|
print(value, decimals);
|
||||||
_stream->print('"');
|
print('"');
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLWriter::writeNode(const char* tag, const uint8_t value, const uint8_t base)
|
void XMLWriter::writeNode(const char* tag, const uint8_t value, const uint8_t base)
|
||||||
@ -187,7 +216,7 @@ void XMLWriter::writeNode(const char* tag, const uint16_t value, const uint8_t b
|
|||||||
void XMLWriter::writeNode(const char* tag, const uint32_t value, const uint8_t base)
|
void XMLWriter::writeNode(const char* tag, const uint32_t value, const uint8_t base)
|
||||||
{
|
{
|
||||||
tagOpen(tag, "", NONEWLINE);
|
tagOpen(tag, "", NONEWLINE);
|
||||||
_stream->print(value, base); // todo: leading zero's
|
print(value, base);
|
||||||
tagClose(NOINDENT);
|
tagClose(NOINDENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,46 +233,106 @@ void XMLWriter::writeNode(const char* tag, const int16_t value, const uint8_t ba
|
|||||||
void XMLWriter::writeNode(const char* tag, const int32_t value, const uint8_t base)
|
void XMLWriter::writeNode(const char* tag, const int32_t value, const uint8_t base)
|
||||||
{
|
{
|
||||||
tagOpen(tag, "", NONEWLINE);
|
tagOpen(tag, "", NONEWLINE);
|
||||||
_stream->print(value, base); // todo: leading zero's
|
print(value, base);
|
||||||
tagClose(NOINDENT);
|
tagClose(NOINDENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLWriter::writeNode(const char* tag, const bool value)
|
void XMLWriter::writeNode(const char* tag, const bool value)
|
||||||
{
|
{
|
||||||
tagOpen(tag, "", NONEWLINE);
|
tagOpen(tag, "", NONEWLINE);
|
||||||
_stream->print(value?F("true"):F("false"));
|
// F() is slower & uses less RAM but saves 9 bytes
|
||||||
|
print(value ? F("true") : F("false"));
|
||||||
tagClose(NOINDENT);
|
tagClose(NOINDENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLWriter::writeNode(const char* tag, const double value, const uint8_t decimals)
|
void XMLWriter::writeNode(const char* tag, const double value, const uint8_t decimals)
|
||||||
{
|
{
|
||||||
tagOpen(tag, "", NONEWLINE);
|
tagOpen(tag, "", NONEWLINE);
|
||||||
_stream->print(value, decimals);
|
print(value, decimals);
|
||||||
tagClose(NOINDENT);
|
tagClose(NOINDENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLWriter::indent()
|
void XMLWriter::indent()
|
||||||
{
|
{
|
||||||
for (uint8_t i=_indent; i>0; i--) _stream->print(' ');
|
if (_config & XMLWRITER_INDENT)
|
||||||
|
{
|
||||||
|
// as indentation is a multiple of 2
|
||||||
|
// this is nice balance between speed and RAM.
|
||||||
|
for (uint8_t i = _indent; i > 0; i-= 2) print(" ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t XMLWriter::write(uint8_t c)
|
||||||
|
{
|
||||||
|
_buffer[_bidx++] = c;
|
||||||
|
if (_bidx == (_bufsize - 1)) flush();
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
void XMLWriter::flush()
|
||||||
|
{
|
||||||
|
_bytesOut += _bidx;
|
||||||
|
if (_bidx > 0)
|
||||||
|
{
|
||||||
|
_buffer[_bidx] = 0;
|
||||||
|
_stream->print(_buffer);
|
||||||
|
_bidx = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// ESCAPE
|
||||||
|
//
|
||||||
|
|
||||||
#ifdef XMLWRITER_ESCAPE_SUPPORT
|
#ifdef XMLWRITER_ESCAPE_SUPPORT
|
||||||
char c[6] = "\"\'<>&";
|
static char c[6] = "\"\'<>&";
|
||||||
char expanded[][7] = { """, "'","<",">","&"}; // todo in flash
|
|
||||||
|
#ifdef __PROGMEM__
|
||||||
|
PROGMEM const char quote[] = """;
|
||||||
|
PROGMEM const char apostrophe[] = "'";
|
||||||
|
PROGMEM const char lessthen[] = "<";
|
||||||
|
PROGMEM const char greaterthen[] = ">";
|
||||||
|
PROGMEM const char ampersand[] = "&";
|
||||||
|
|
||||||
|
PROGMEM const char* const expanded[] =
|
||||||
|
{
|
||||||
|
quote, apostrophe, lessthen, greaterthen, ampersand
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
// NOTE: & and ; are handled in code. // 25 bytes RAM
|
||||||
|
static char expanded[][5] = { "quot", "apos","lt","gt","amp"};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void XMLWriter::escape(const char* str)
|
void XMLWriter::escape(const char* str)
|
||||||
{
|
{
|
||||||
char* p = (char *)str;
|
char* p = (char *)str;
|
||||||
while(*p != 0)
|
while (*p != 0)
|
||||||
{
|
{
|
||||||
char* q = strchr(c, *p);
|
char* q = strchr(c, *p);
|
||||||
if (q == NULL) _stream->print(*p);
|
if (q == NULL) print(*p);
|
||||||
else _stream->print(expanded[q - c]); // uint8_t idx = q-c;
|
#ifdef __PROGMEM__
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char buf[8];
|
||||||
|
strcpy_P(buf, (char*)pgm_read_word(&(expanded[q - c])));
|
||||||
|
print(buf);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
else
|
||||||
|
{
|
||||||
|
print('&');
|
||||||
|
print(expanded[q - c]); // uint8_t idx = q-c;
|
||||||
|
print(';');
|
||||||
|
}
|
||||||
|
#endif
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// END OF FILE
|
|
||||||
|
// -- END OF FILE --
|
||||||
|
@ -1,19 +1,15 @@
|
|||||||
#ifndef XML_WRITER_H
|
#pragma once
|
||||||
#define XML_WRITER_H
|
|
||||||
//
|
//
|
||||||
// FILE: XMLWriter.h
|
// FILE: XMLWriter.h
|
||||||
// AUTHOR: Rob Tillaart
|
// AUTHOR: Rob Tillaart
|
||||||
// VERSION: 0.1.8
|
// VERSION: 0.2.2
|
||||||
// DATE: 2013-11-06
|
// DATE: 2013-11-06
|
||||||
// PURPOSE: Simple XML writer library
|
// PURPOSE: Arduino library for creating XML
|
||||||
//
|
|
||||||
// Released to the public domain
|
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
// no pre 1.0 support!
|
|
||||||
|
|
||||||
#define XMLWRITER_VERSION "0.1.8"
|
#define XMLWRITER_VERSION "0.2.2"
|
||||||
|
|
||||||
// for comment()
|
// for comment()
|
||||||
#define NOMULTILINE false
|
#define NOMULTILINE false
|
||||||
@ -30,88 +26,129 @@
|
|||||||
|
|
||||||
// deepness of XML tree 5..10
|
// deepness of XML tree 5..10
|
||||||
// needed for stack of tagStack
|
// needed for stack of tagStack
|
||||||
|
#ifndef XMLWRITER_MAXLEVEL
|
||||||
#define XMLWRITER_MAXLEVEL 5 // adjust for deeper nested structures
|
#define XMLWRITER_MAXLEVEL 5 // adjust for deeper nested structures
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef XMLWRITER_MAXTAGSIZE
|
||||||
#define XMLWRITER_MAXTAGSIZE 15 // adjust for longer fields - !! eats memory !!
|
#define XMLWRITER_MAXTAGSIZE 15 // adjust for longer fields - !! eats memory !!
|
||||||
|
#endif
|
||||||
|
|
||||||
// reduce footprint by commenting next line
|
// reduce footprint by commenting next line
|
||||||
#define XMLWRITER_ESCAPE_SUPPORT
|
#define XMLWRITER_ESCAPE_SUPPORT
|
||||||
|
|
||||||
class XMLWriter
|
// configuration - setConfig
|
||||||
|
#define XMLWRITER_NONE 0x00
|
||||||
|
#define XMLWRITER_COMMENT 0x01
|
||||||
|
#define XMLWRITER_INDENT 0x02
|
||||||
|
#define XMLWRITER_NEWLINE 0x04
|
||||||
|
|
||||||
|
// uncomment next line to reduce ~30bytes RAM in escape() (AVR oonly)
|
||||||
|
// #define __PROGMEM__
|
||||||
|
|
||||||
|
|
||||||
|
class XMLWriter : Print
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
XMLWriter(Print* stream);
|
// default = Serial
|
||||||
|
XMLWriter(Print* stream = &Serial, uint8_t bufsize = 10);
|
||||||
|
~XMLWriter();
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
|
// to show/strip comment, indent, newLine
|
||||||
|
// to minimize the output setConfig(0);
|
||||||
|
void setConfig(uint8_t cfg) { _config = cfg; };
|
||||||
|
|
||||||
// standard XML header
|
// standard XML header
|
||||||
void header();
|
void header();
|
||||||
|
|
||||||
// if multiline == true it does not indent to allow bigger text blocks
|
// if multiline == true it does not indent to allow bigger text blocks
|
||||||
// <!-- text -->
|
// <!-- text -->
|
||||||
void comment(const char* text, const bool multiLine=false);
|
void comment(const char* text, const bool multiLine = false);
|
||||||
|
|
||||||
|
// add a number of newlines to the output, default = 1.
|
||||||
|
void newLine(uint8_t n = 1);
|
||||||
|
|
||||||
// <tag>
|
// <tag>
|
||||||
void tagOpen(const char* tag, const bool newline=true);
|
void tagOpen(const char* tag, const bool newline = true);
|
||||||
// <tag name="name">
|
// <tag name="name">
|
||||||
void tagOpen(const char* tag, const char* name, const bool newline=true);
|
void tagOpen(const char* tag, const char* name, const bool newline = true);
|
||||||
// </tag>
|
// </tag>
|
||||||
void tagClose(const bool ind=true);
|
void tagClose(const bool ind = true);
|
||||||
|
|
||||||
// <tag
|
// <tag
|
||||||
void tagStart(const char* tag);
|
void tagStart(const char* tag);
|
||||||
// field="value"
|
// field="value"
|
||||||
void tagField(const char* field, const char* value);
|
void tagField(const char* field, const char* value);
|
||||||
// />
|
// />
|
||||||
void tagEnd(const bool newline=true, const bool addSlash=true);
|
void tagEnd(const bool newline = true, const bool addSlash = true);
|
||||||
|
|
||||||
// <tag>value</tag>
|
// <tag>value</tag>
|
||||||
void writeNode(const char* tag, const char* value);
|
void writeNode(const char* tag, const char* value);
|
||||||
|
|
||||||
// typically 0,2,4; default == 2;
|
// typically 0,2,4; default == 2;
|
||||||
|
// multiple of 2;
|
||||||
void setIndentSize(const uint8_t size = 2);
|
void setIndentSize(const uint8_t size = 2);
|
||||||
|
|
||||||
// for manual layout control
|
// for manual layout control
|
||||||
void incrIndent() { _indent += _indentStep; };
|
void incrIndent() { _indent += _indentStep; };
|
||||||
void decrIndent() { _indent -= _indentStep; };
|
void decrIndent() { _indent -= _indentStep; };
|
||||||
void indent();
|
void indent();
|
||||||
void raw(const char * str) { _stream->print(str); }; // TODO Q:other types?
|
void raw(const char * str) { print(str); };
|
||||||
|
|
||||||
void tagField(const char* field, const uint8_t value, const uint8_t base=DEC);
|
void tagField(const char* field, const uint8_t value, const uint8_t base = DEC);
|
||||||
void tagField(const char* field, const uint16_t value, const uint8_t base=DEC);
|
void tagField(const char* field, const uint16_t value, const uint8_t base = DEC);
|
||||||
void tagField(const char* field, const uint32_t value, const uint8_t base=DEC);
|
void tagField(const char* field, const uint32_t value, const uint8_t base = DEC);
|
||||||
void tagField(const char* field, const int8_t value, const uint8_t base=DEC);
|
void tagField(const char* field, const int8_t value, const uint8_t base = DEC);
|
||||||
void tagField(const char* field, const int16_t value, const uint8_t base=DEC);
|
void tagField(const char* field, const int16_t value, const uint8_t base = DEC);
|
||||||
void tagField(const char* field, const int32_t value, const uint8_t base=DEC);
|
void tagField(const char* field, const int32_t value, const uint8_t base = DEC);
|
||||||
void tagField(const char *field, const bool value);
|
void tagField(const char* field, const bool value);
|
||||||
void tagField(const char* field, const double value, const uint8_t decimals=2);
|
void tagField(const char* field, const double value, const uint8_t decimals = 2);
|
||||||
|
|
||||||
void writeNode(const char* tag, const uint8_t value, const uint8_t base=DEC);
|
void writeNode(const char* tag, const uint8_t value, const uint8_t base = DEC);
|
||||||
void writeNode(const char* tag, const uint16_t value, const uint8_t base=DEC);
|
void writeNode(const char* tag, const uint16_t value, const uint8_t base = DEC);
|
||||||
void writeNode(const char* tag, const uint32_t value, const uint8_t base=DEC);
|
void writeNode(const char* tag, const uint32_t value, const uint8_t base = DEC);
|
||||||
void writeNode(const char* tag, const int8_t value, const uint8_t base=DEC);
|
void writeNode(const char* tag, const int8_t value, const uint8_t base = DEC);
|
||||||
void writeNode(const char* tag, const int16_t value, const uint8_t base=DEC);
|
void writeNode(const char* tag, const int16_t value, const uint8_t base = DEC);
|
||||||
void writeNode(const char* tag, const int32_t value, const uint8_t base=DEC);
|
void writeNode(const char* tag, const int32_t value, const uint8_t base = DEC);
|
||||||
void writeNode(const char* tag, const bool value);
|
void writeNode(const char* tag, const bool value);
|
||||||
void writeNode(const char* tag, const double value, const uint8_t decimals=2);
|
void writeNode(const char* tag, const double value, const uint8_t decimals = 2);
|
||||||
|
|
||||||
#ifdef XMLWRITER_ESCAPE_SUPPORT
|
#ifdef XMLWRITER_ESCAPE_SUPPORT
|
||||||
// expands the special xml chars
|
// expands the special xml chars
|
||||||
void escape(const char* str);
|
void escape(const char* str);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// One need to call flush() at the end of writing to empty
|
||||||
|
// the internal buffer.
|
||||||
|
void flush();
|
||||||
|
|
||||||
|
// metrics
|
||||||
|
uint8_t bufferIndex() { return _bidx; };
|
||||||
|
uint32_t bytesWritten() { return _bytesOut; } ;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// outputstream
|
// outputstream, Print Class
|
||||||
Print* _stream;
|
Print* _stream;
|
||||||
|
size_t write(uint8_t c);
|
||||||
|
|
||||||
// for indentation
|
// for indentation
|
||||||
uint8_t _indent;
|
uint8_t _indent;
|
||||||
uint8_t _indentStep;
|
uint8_t _indentStep;
|
||||||
|
|
||||||
|
// configuration
|
||||||
|
uint8_t _config;
|
||||||
|
|
||||||
// stack - used to remember the current tagname to create
|
// stack - used to remember the current tagname to create
|
||||||
// automatic the right close tag.
|
// automatic the right close tag.
|
||||||
uint8_t _idx;
|
uint8_t _tidx;
|
||||||
char tagStack[XMLWRITER_MAXLEVEL][XMLWRITER_MAXTAGSIZE+1];
|
char _tagStack[XMLWRITER_MAXLEVEL][XMLWRITER_MAXTAGSIZE + 1];
|
||||||
|
|
||||||
|
char * _buffer;
|
||||||
|
uint8_t _bufsize;
|
||||||
|
uint8_t _bidx;
|
||||||
|
uint32_t _bytesOut;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
// -- END OF FILE --
|
||||||
// END OF FILE
|
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
//
|
//
|
||||||
// FILE: KMLWriterTest.ino
|
// FILE: KMLWriterTest.ino
|
||||||
// AUTHOR: Rob Tillaart
|
// AUTHOR: Rob Tillaart
|
||||||
// VERSION: 0.1.01
|
// VERSION: 0.1.3
|
||||||
// PURPOSE: simple KML writer
|
// PURPOSE: simple KML writer
|
||||||
// DATE: 2015-05-21
|
// DATE: 2015-05-21
|
||||||
// URL:
|
// URL: https://github.com/RobTillaart/XMLWriter
|
||||||
//
|
|
||||||
// Released to the public domain
|
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <XMLWriter.h>
|
#include <XMLWriter.h>
|
||||||
@ -19,7 +17,11 @@ void setup()
|
|||||||
{
|
{
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
uint32_t start = micros();
|
||||||
KMLTest();
|
KMLTest();
|
||||||
|
uint32_t stop = micros();
|
||||||
|
Serial.println();
|
||||||
|
Serial.println(stop - start);
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
@ -86,3 +88,6 @@ This is a demo of the XMLWriter lib for Arduino
|
|||||||
</Document>
|
</Document>
|
||||||
</kml>
|
</kml>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// -- END OF FILE --
|
||||||
|
@ -0,0 +1,122 @@
|
|||||||
|
//
|
||||||
|
// FILE: XMLWriterDefaultSerial.ino
|
||||||
|
// AUTHOR: Rob Tillaart
|
||||||
|
// VERSION: 0.1.1
|
||||||
|
// PURPOSE: make a simple XML generating lib
|
||||||
|
// DATE: 2020-04-24
|
||||||
|
// URL: https://github.com/RobTillaart/XMLWriter
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <XMLWriter.h>
|
||||||
|
|
||||||
|
XMLWriter XML;
|
||||||
|
|
||||||
|
char buffer[24];
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Serial.begin(115200);
|
||||||
|
uint32_t start = micros();
|
||||||
|
XML.header();
|
||||||
|
XML.comment("XMLWriterTest.ino\nThis is a demo of a simple XML lib for Arduino", true);
|
||||||
|
|
||||||
|
XML.tagOpen("Arduino", "42");
|
||||||
|
|
||||||
|
XML.tagOpen("Ports");
|
||||||
|
AnalogPorts("before");
|
||||||
|
DigitalPorts();
|
||||||
|
AnalogPorts("after");
|
||||||
|
XML.tagClose();
|
||||||
|
|
||||||
|
Weather();
|
||||||
|
Weather2();
|
||||||
|
DataTypes();
|
||||||
|
|
||||||
|
XML.tagClose();
|
||||||
|
|
||||||
|
uint32_t stop = micros();
|
||||||
|
Serial.println();
|
||||||
|
Serial.println(stop - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Weather2()
|
||||||
|
{
|
||||||
|
XML.comment("The weather in South Africa");
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
XML.tagStart("Weather");
|
||||||
|
XML.tagField("Date", "20131106");
|
||||||
|
XML.tagField("Time", "1:42");
|
||||||
|
XML.tagField("Temp", "23.4");
|
||||||
|
XML.tagField("Humi", "50%");
|
||||||
|
XML.tagField("Rain", "10mm");
|
||||||
|
XML.tagField("Sun", "40");
|
||||||
|
XML.tagEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Weather()
|
||||||
|
{
|
||||||
|
XML.comment("The weather in Nebraska");
|
||||||
|
XML.tagOpen("Weather");
|
||||||
|
XML.writeNode("Date", "20131106");
|
||||||
|
XML.writeNode("Time", "11:42");
|
||||||
|
XML.writeNode("Temp", "23.4");
|
||||||
|
XML.writeNode("Humi", "50%");
|
||||||
|
XML.writeNode("Rain", "10mm");
|
||||||
|
XML.writeNode("Sun", "40");
|
||||||
|
XML.tagClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnalogPorts(const char* name)
|
||||||
|
{
|
||||||
|
XML.comment("The analog ports are multiplexed");
|
||||||
|
XML.tagOpen("Analog", name);
|
||||||
|
XML.writeNode("Analog0", itoa(analogRead(A0), buffer, 10));
|
||||||
|
XML.writeNode("Analog1", analogRead(A1));
|
||||||
|
XML.writeNode("Analog2", (5.0 * analogRead(A2)) / 1023); // default nr decimals = 2
|
||||||
|
XML.writeNode("Analog3", (5.0 * analogRead(A2)) / 1023, 3);
|
||||||
|
XML.tagClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DigitalPorts()
|
||||||
|
{
|
||||||
|
XML.comment("The digital ports are not multiplexed");
|
||||||
|
XML.tagOpen("Digital");
|
||||||
|
XML.writeNode("D1", itoa(digitalRead(1), buffer, 10));
|
||||||
|
XML.writeNode("D13", digitalRead(13));
|
||||||
|
XML.tagClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataTypes()
|
||||||
|
{
|
||||||
|
XML.comment("Testing dataTypes I");
|
||||||
|
XML.tagOpen("Datatypes");
|
||||||
|
XML.writeNode("Bool", 1 == 1);
|
||||||
|
XML.writeNode("Bool", 1 == 0);
|
||||||
|
XML.writeNode("BIN", 42, BIN);
|
||||||
|
XML.writeNode("DEC", 42, DEC);
|
||||||
|
XML.writeNode("HEX", 42, HEX);
|
||||||
|
XML.writeNode("OCT", 42, OCT);
|
||||||
|
XML.tagClose();
|
||||||
|
|
||||||
|
XML.comment("Testing dataTypes II");
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
XML.tagStart("dataTypes");
|
||||||
|
XML.tagField("Bool", 1 == 1);
|
||||||
|
XML.tagField("Bool", 1 == 0);
|
||||||
|
int x = analogRead(A0);
|
||||||
|
XML.tagField("BIN", x, BIN);
|
||||||
|
XML.tagField("DEC", x, DEC);
|
||||||
|
XML.tagField("HEX", x, HEX);
|
||||||
|
XML.tagField("OCT", x, OCT);
|
||||||
|
XML.tagEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- END OF FILE --
|
@ -0,0 +1,69 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
XMLWriterTest.ino
|
||||||
|
This is a demo of a simple XML lib for Arduino
|
||||||
|
-->
|
||||||
|
<Arduino name="42">
|
||||||
|
<Ports>
|
||||||
|
|
||||||
|
<!-- The analog ports are multiplexed -->
|
||||||
|
<Analog name="before">
|
||||||
|
<Analog0>389</Analog0>
|
||||||
|
<Analog1>332</Analog1>
|
||||||
|
<Analog2>1.55</Analog2>
|
||||||
|
<Analog3>1.544</Analog3>
|
||||||
|
</Analog>
|
||||||
|
|
||||||
|
<!-- The digital ports are not multiplexed -->
|
||||||
|
<Digital>
|
||||||
|
<D1>0</D1>
|
||||||
|
<D13>1</D13>
|
||||||
|
</Digital>
|
||||||
|
|
||||||
|
<!-- The analog ports are multiplexed -->
|
||||||
|
<Analog name="after">
|
||||||
|
<Analog0>343</Analog0>
|
||||||
|
<Analog1>366</Analog1>
|
||||||
|
<Analog2>1.94</Analog2>
|
||||||
|
<Analog3>1.926</Analog3>
|
||||||
|
</Analog>
|
||||||
|
</Ports>
|
||||||
|
|
||||||
|
<!-- The weather in Nebraska -->
|
||||||
|
<Weather>
|
||||||
|
<Date>20131106</Date>
|
||||||
|
<Time>11:42</Time>
|
||||||
|
<Temp>23.4</Temp>
|
||||||
|
<Humi>50%</Humi>
|
||||||
|
<Rain>10mm</Rain>
|
||||||
|
<Sun>40</Sun>
|
||||||
|
</Weather>
|
||||||
|
|
||||||
|
<!-- The weather in South Africa -->
|
||||||
|
<Weather Date="20131106" Time="1:42" Temp="23.4" Humi="50%" Rain="10mm" Sun="40"/>
|
||||||
|
<Weather Date="20131106" Time="1:42" Temp="23.4" Humi="50%" Rain="10mm" Sun="40"/>
|
||||||
|
<Weather Date="20131106" Time="1:42" Temp="23.4" Humi="50%" Rain="10mm" Sun="40"/>
|
||||||
|
<Weather Date="20131106" Time="1:42" Temp="23.4" Humi="50%" Rain="10mm" Sun="40"/>
|
||||||
|
<Weather Date="20131106" Time="1:42" Temp="23.4" Humi="50%" Rain="10mm" Sun="40"/>
|
||||||
|
<Weather Date="20131106" Time="1:42" Temp="23.4" Humi="50%" Rain="10mm" Sun="40"/>
|
||||||
|
<Weather Date="20131106" Time="1:42" Temp="23.4" Humi="50%" Rain="10mm" Sun="40"/>
|
||||||
|
<Weather Date="20131106" Time="1:42" Temp="23.4" Humi="50%" Rain="10mm" Sun="40"/>
|
||||||
|
<Weather Date="20131106" Time="1:42" Temp="23.4" Humi="50%" Rain="10mm" Sun="40"/>
|
||||||
|
<Weather Date="20131106" Time="1:42" Temp="23.4" Humi="50%" Rain="10mm" Sun="40"/>
|
||||||
|
|
||||||
|
<!-- Testing dataTypes I -->
|
||||||
|
<Datatypes>
|
||||||
|
<Bool>true</Bool>
|
||||||
|
<Bool>false</Bool>
|
||||||
|
<BIN>101010</BIN>
|
||||||
|
<DEC>42</DEC>
|
||||||
|
<HEX>2A</HEX>
|
||||||
|
<OCT>52</OCT>
|
||||||
|
</Datatypes>
|
||||||
|
|
||||||
|
<!-- Testing dataTypes II -->
|
||||||
|
<dataTypes Bool="true" Bool="false" BIN="101110111" DEC="375" HEX="177" OCT="567"/>
|
||||||
|
<dataTypes Bool="true" Bool="false" BIN="101010010" DEC="338" HEX="152" OCT="522"/>
|
||||||
|
<dataTypes Bool="true" Bool="false" BIN="101111010" DEC="378" HEX="17A" OCT="572"/>
|
||||||
|
</Arduino>
|
@ -0,0 +1,271 @@
|
|||||||
|
//
|
||||||
|
// FILE: XMLWriterEthernet.ino
|
||||||
|
// AUTHOR: Rob Tillaart
|
||||||
|
// VERSION: 0.1.0
|
||||||
|
// PURPOSE: demo XML writer for EthernetClient
|
||||||
|
// DATE: 2020-04-24
|
||||||
|
// URL:
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <XMLWriter.h>
|
||||||
|
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <Ethernet.h>
|
||||||
|
|
||||||
|
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
|
||||||
|
IPAddress ip( 192, 168, 1, 177);
|
||||||
|
|
||||||
|
const int EthernetPIN = 10;
|
||||||
|
|
||||||
|
EthernetServer server(80); // change to your config
|
||||||
|
|
||||||
|
char httpRequest[40];
|
||||||
|
uint8_t reqCnt;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// HTTP HELPER CODE
|
||||||
|
//
|
||||||
|
void HTTP_header(EthernetClient* cl, const char *contentType, bool keepAlive = false, int refresh = 5)
|
||||||
|
{
|
||||||
|
cl->println("HTTP/1.1 200 OK");
|
||||||
|
cl->print("Content-Type: ");
|
||||||
|
cl->println( contentType );
|
||||||
|
cl->println("Connection: ");
|
||||||
|
cl->println(keepAlive ? "keep-alive":"close");
|
||||||
|
cl->println("Refresh: ");
|
||||||
|
cl->println(refresh);
|
||||||
|
cl->println();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Based upon webServer example demo
|
||||||
|
//
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println(__FILE__);
|
||||||
|
|
||||||
|
// Ethernet.init(pin) to configure the CS pin
|
||||||
|
Ethernet.init(EthernetPIN);
|
||||||
|
Ethernet.begin(mac, ip);
|
||||||
|
|
||||||
|
if (Ethernet.hardwareStatus() == EthernetNoHardware)
|
||||||
|
{
|
||||||
|
Serial.println("No hardware found");
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Ethernet.linkStatus() == LinkOFF)
|
||||||
|
{
|
||||||
|
Serial.println("Cable is not connected.");
|
||||||
|
Serial.println("Connect cable");
|
||||||
|
}
|
||||||
|
while (Ethernet.linkStatus() == LinkOFF); // wait for cable
|
||||||
|
|
||||||
|
server.begin();
|
||||||
|
Serial.print("ServerIP: ");
|
||||||
|
Serial.println(Ethernet.localIP());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
// listen for incoming clients
|
||||||
|
EthernetClient client = server.available();
|
||||||
|
|
||||||
|
if (client)
|
||||||
|
{
|
||||||
|
Serial.print("\n<CONNECTION>\n ");
|
||||||
|
// an http request ends with a blank line
|
||||||
|
boolean currentLineIsBlank = true;
|
||||||
|
reqCnt = 0;
|
||||||
|
while (client.connected())
|
||||||
|
{
|
||||||
|
if (client.available())
|
||||||
|
{
|
||||||
|
char c = client.read();
|
||||||
|
Serial.write(c); // collect HHTP request here..
|
||||||
|
if (reqCnt < 39)
|
||||||
|
{
|
||||||
|
httpRequest[reqCnt++] = c;
|
||||||
|
httpRequest[reqCnt] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if you've gotten to the end of the line (received a newline
|
||||||
|
// character) and the line is blank, the http request has ended,
|
||||||
|
// so you can send a reply
|
||||||
|
if (c == '\n' && currentLineIsBlank)
|
||||||
|
{
|
||||||
|
if (strstr(httpRequest, "1.xml"))
|
||||||
|
{
|
||||||
|
// send a standard http response header
|
||||||
|
HTTP_header(&client, "text/xml", true, 5);
|
||||||
|
XMLWriter XML(&client);
|
||||||
|
|
||||||
|
// XML body
|
||||||
|
XML.header();
|
||||||
|
XML.comment("XMLWriterTest.ino\nThis is a demo of a simple XML lib for Arduino", true);
|
||||||
|
|
||||||
|
// use of {} to get indentation that follows the XML (sort of)
|
||||||
|
// it adds no code size, but improves readability a lot
|
||||||
|
XML.tagOpen("Arduino", "42");
|
||||||
|
{
|
||||||
|
XML.tagOpen("Ports");
|
||||||
|
{
|
||||||
|
AnalogPorts(XML, "before");
|
||||||
|
DigitalPorts(XML);
|
||||||
|
AnalogPorts(XML,"after");
|
||||||
|
}
|
||||||
|
XML.tagClose();
|
||||||
|
}
|
||||||
|
XML.tagClose();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (strstr(httpRequest, "2.xml"))
|
||||||
|
{
|
||||||
|
// send a standard http response header
|
||||||
|
HTTP_header(&client, "text/xml", true, 5);
|
||||||
|
XMLWriter XML(&client);
|
||||||
|
|
||||||
|
// XML body
|
||||||
|
XML.header();
|
||||||
|
XML.comment("XMLWriterTest.ino\nThis is a demo of a simple XML lib for Arduino", true);
|
||||||
|
|
||||||
|
// use of {} to get indentation that follows the XML (sort of)
|
||||||
|
// it adds no code size, but improves readability a lot
|
||||||
|
XML.tagOpen("Arduino", "102");
|
||||||
|
{
|
||||||
|
Weather(XML);
|
||||||
|
Weather2(XML);
|
||||||
|
DataTypes(XML);
|
||||||
|
}
|
||||||
|
XML.tagClose();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// default page is simple HTML
|
||||||
|
// send a standard http response header
|
||||||
|
HTTP_header(&client, "text/html", true, 5);
|
||||||
|
|
||||||
|
client.println("<!DOCTYPE HTML>");
|
||||||
|
client.println("<html>");
|
||||||
|
client.println("<head>");
|
||||||
|
client.println("<title>Demo XML writer</title>");
|
||||||
|
client.println("</head>");
|
||||||
|
client.println("<body>");
|
||||||
|
client.println("<h1>Demo XML writer for EthernetClient</h1>");
|
||||||
|
client.println("<p>Get <a href=\"1.xml\">XML 1</a>.</p>");
|
||||||
|
client.println("<p>Get <a href=\"2.xml\">XML 2</a>.</p>");
|
||||||
|
client.println("</body>");
|
||||||
|
client.println("</html>");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (c == '\n') {
|
||||||
|
Serial.print(" ");
|
||||||
|
// you're starting a new line
|
||||||
|
currentLineIsBlank = true;
|
||||||
|
} else if (c != '\r') {
|
||||||
|
// you've gotten a character on the current line
|
||||||
|
currentLineIsBlank = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// give the web browser time to receive the data
|
||||||
|
delay(1);
|
||||||
|
client.stop();
|
||||||
|
Serial.println("</CONNECTION>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// XML CODE
|
||||||
|
//
|
||||||
|
void Weather2(XMLWriter xw)
|
||||||
|
{
|
||||||
|
xw.comment("The weather in South Africa");
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
xw.tagStart("Weather");
|
||||||
|
xw.tagField("Date", "20131106");
|
||||||
|
xw.tagField("Time", "1:42");
|
||||||
|
xw.tagField("Temp", "23.4");
|
||||||
|
xw.tagField("Humi", "50%");
|
||||||
|
xw.tagField("Rain", "10mm");
|
||||||
|
xw.tagField("Sun", "40");
|
||||||
|
xw.tagEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Weather(XMLWriter xw)
|
||||||
|
{
|
||||||
|
xw.comment("The weather in Nebraska");
|
||||||
|
xw.tagOpen("Weather");
|
||||||
|
xw.writeNode("Date", "20131106");
|
||||||
|
xw.writeNode("Time", "11:42");
|
||||||
|
xw.writeNode("Temp", "23.4");
|
||||||
|
xw.writeNode("Humi", "50%");
|
||||||
|
xw.writeNode("Rain", "10mm");
|
||||||
|
xw.writeNode("Sun", "40");
|
||||||
|
xw.tagClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AnalogPorts(XMLWriter xw, const char* name)
|
||||||
|
{
|
||||||
|
char buffer[24];
|
||||||
|
|
||||||
|
xw.comment("The analog ports are multiplexed");
|
||||||
|
xw.tagOpen("Analog", name);
|
||||||
|
xw.writeNode("Analog0", itoa(analogRead(A0), buffer, 10));
|
||||||
|
xw.writeNode("Analog1", analogRead(A1));
|
||||||
|
xw.writeNode("Analog2", (5.0 * analogRead(A2)) / 1023); // default nr decimals = 2
|
||||||
|
xw.writeNode("Analog3", (5.0 * analogRead(A2)) / 1023, 3);
|
||||||
|
xw.tagClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DigitalPorts(XMLWriter xw)
|
||||||
|
{
|
||||||
|
char buffer[24];
|
||||||
|
|
||||||
|
xw.comment("The digital ports are not multiplexed");
|
||||||
|
xw.tagOpen("Digital");
|
||||||
|
xw.writeNode("D1", itoa(digitalRead(1), buffer, 10));
|
||||||
|
xw.writeNode("D13", digitalRead(13));
|
||||||
|
xw.tagClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataTypes(XMLWriter xw)
|
||||||
|
{
|
||||||
|
xw.comment("Testing dataTypes I");
|
||||||
|
xw.tagOpen("Datatypes");
|
||||||
|
xw.writeNode("BoolT", 1 == 1);
|
||||||
|
xw.writeNode("BoolF", 1 == 0);
|
||||||
|
xw.writeNode("BIN", 42, BIN);
|
||||||
|
xw.writeNode("DEC", 42, DEC);
|
||||||
|
xw.writeNode("HEX", 42, HEX);
|
||||||
|
xw.writeNode("OCT", 42, OCT);
|
||||||
|
xw.tagClose();
|
||||||
|
|
||||||
|
xw.comment("Testing dataTypes II");
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
xw.tagStart("dataTypes");
|
||||||
|
xw.tagField("BoolT", 1 == 1);
|
||||||
|
xw.tagField("BoolF", 1 == 0);
|
||||||
|
int x = analogRead(A0);
|
||||||
|
xw.tagField("BIN", x, BIN);
|
||||||
|
xw.tagField("DEC", x, DEC);
|
||||||
|
xw.tagField("HEX", x, HEX);
|
||||||
|
xw.tagField("OCT", x, OCT);
|
||||||
|
xw.tagEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- END OF FILE --
|
@ -0,0 +1,289 @@
|
|||||||
|
//
|
||||||
|
// FILE: XMLWriterEthernet.ino
|
||||||
|
// AUTHOR: Rob Tillaart
|
||||||
|
// VERSION: 0.1.1
|
||||||
|
// PURPOSE: demo XML writer for EthernetClient
|
||||||
|
// DATE: 2020-04-24
|
||||||
|
// URL: https://github.com/RobTillaart/XMLWriter
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <XMLWriter.h>
|
||||||
|
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <Ethernet.h>
|
||||||
|
|
||||||
|
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
|
||||||
|
IPAddress ip( 192, 168, 1, 177);
|
||||||
|
|
||||||
|
const int EthernetPIN = 10;
|
||||||
|
|
||||||
|
EthernetServer server(80); // change to your config
|
||||||
|
|
||||||
|
char httpRequest[40];
|
||||||
|
uint8_t reqCnt;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// HTTP HELPER CODE
|
||||||
|
//
|
||||||
|
void HTTP_header(EthernetClient* cl, const char *contentType, bool keepAlive = false, int refresh = 5)
|
||||||
|
{
|
||||||
|
cl->println("HTTP/1.1 200 OK");
|
||||||
|
cl->print("Content-Type: ");
|
||||||
|
cl->println( contentType );
|
||||||
|
cl->println("Connection: ");
|
||||||
|
cl->println(keepAlive ? "keep-alive" : "close");
|
||||||
|
cl->println("Refresh: ");
|
||||||
|
cl->println(refresh);
|
||||||
|
cl->println();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Based upon webServer example demo
|
||||||
|
//
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println(__FILE__);
|
||||||
|
|
||||||
|
// Ethernet.init(pin) to configure the CS pin
|
||||||
|
Ethernet.init(EthernetPIN);
|
||||||
|
Ethernet.begin(mac, ip);
|
||||||
|
|
||||||
|
if (Ethernet.hardwareStatus() == EthernetNoHardware)
|
||||||
|
{
|
||||||
|
Serial.println("No hardware found");
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println(Ethernet.hardwareStatus());
|
||||||
|
Serial.println(Ethernet.linkStatus());
|
||||||
|
|
||||||
|
if (Ethernet.linkStatus() == LinkOFF)
|
||||||
|
{
|
||||||
|
Serial.println("Cable is not connected.");
|
||||||
|
Serial.println("Connect cable");
|
||||||
|
}
|
||||||
|
while (Ethernet.linkStatus() == LinkOFF); // wait for cable
|
||||||
|
|
||||||
|
server.begin();
|
||||||
|
Serial.print("ServerIP: ");
|
||||||
|
Serial.println(Ethernet.localIP());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
// listen for incoming clients
|
||||||
|
EthernetClient client = server.available();
|
||||||
|
|
||||||
|
if (client)
|
||||||
|
{
|
||||||
|
Serial.print("\n<CONNECTION>\n ");
|
||||||
|
// Serial.println(client.remoteIP());
|
||||||
|
// Serial.println(client.remotePort());
|
||||||
|
|
||||||
|
// an http request ends with a blank line
|
||||||
|
boolean currentLineIsBlank = true;
|
||||||
|
reqCnt = 0;
|
||||||
|
while (client.connected())
|
||||||
|
{
|
||||||
|
if (client.available())
|
||||||
|
{
|
||||||
|
char c = client.read();
|
||||||
|
Serial.write(c); // collect HHTP request here..
|
||||||
|
if (reqCnt < 39)
|
||||||
|
{
|
||||||
|
httpRequest[reqCnt++] = c;
|
||||||
|
httpRequest[reqCnt] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if you've gotten to the end of the line (received a newline
|
||||||
|
// character) and the line is blank, the http request has ended,
|
||||||
|
// so you can send a reply
|
||||||
|
if (c == '\n' && currentLineIsBlank)
|
||||||
|
{
|
||||||
|
if (strstr(httpRequest, "1.xml"))
|
||||||
|
{
|
||||||
|
uint32_t start = micros();
|
||||||
|
// send a standard http response header
|
||||||
|
HTTP_header(&client, "text/xml", true, 5);
|
||||||
|
XMLWriter XML(&client, 250);
|
||||||
|
|
||||||
|
// XML body
|
||||||
|
XML.header();
|
||||||
|
XML.comment("XMLWriterTest.ino\nThis is a demo of a simple XML lib for Arduino", true);
|
||||||
|
|
||||||
|
// use of {} to get indentation that follows the XML (sort of)
|
||||||
|
// it adds no code size, but improves readability a lot
|
||||||
|
XML.tagOpen("Arduino", "42");
|
||||||
|
{
|
||||||
|
XML.tagOpen("Ports");
|
||||||
|
{
|
||||||
|
AnalogPorts(&XML, "before");
|
||||||
|
DigitalPorts(&XML);
|
||||||
|
AnalogPorts(&XML, "after");
|
||||||
|
}
|
||||||
|
XML.tagClose();
|
||||||
|
}
|
||||||
|
XML.tagClose();
|
||||||
|
XML.flush();
|
||||||
|
uint32_t stop = micros();
|
||||||
|
Serial.println(stop - start);
|
||||||
|
Serial.println(XML.bytesWritten());
|
||||||
|
Serial.println(XML.bytesWritten() * 1e6 / (stop - start));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (strstr(httpRequest, "2.xml"))
|
||||||
|
{
|
||||||
|
uint32_t start = micros();
|
||||||
|
// send a standard http response header
|
||||||
|
HTTP_header(&client, "text/xml", true, 5);
|
||||||
|
XMLWriter XML(&client, 250);
|
||||||
|
|
||||||
|
// XML body
|
||||||
|
XML.header();
|
||||||
|
XML.comment("XMLWriterTest.ino\nThis is a demo of a simple XML lib for Arduino", true);
|
||||||
|
|
||||||
|
// use of {} to get indentation that follows the XML (sort of)
|
||||||
|
// it adds no code size, but improves readability a lot
|
||||||
|
XML.tagOpen("Arduino", "102");
|
||||||
|
{
|
||||||
|
Weather(&XML);
|
||||||
|
Weather2(&XML);
|
||||||
|
DataTypes(&XML);
|
||||||
|
}
|
||||||
|
XML.tagClose();
|
||||||
|
XML.flush();
|
||||||
|
uint32_t stop = micros();
|
||||||
|
Serial.println(stop - start);
|
||||||
|
Serial.println(XML.bytesWritten());
|
||||||
|
Serial.println(XML.bytesWritten() * 1e6 / (stop - start));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// default page is simple HTML
|
||||||
|
// send a standard http response header
|
||||||
|
HTTP_header(&client, "text/html", true, 5);
|
||||||
|
|
||||||
|
client.println("<!DOCTYPE HTML>");
|
||||||
|
client.println("<html>");
|
||||||
|
client.println("<head>");
|
||||||
|
client.println("<title>Demo XML writer</title>");
|
||||||
|
client.println("</head>");
|
||||||
|
client.println("<body>");
|
||||||
|
client.println("<h1>Demo XML writer for EthernetClient</h1>");
|
||||||
|
client.println("<p>Get <a href=\"1.xml\">XML 1</a>.</p>");
|
||||||
|
client.println("<p>Get <a href=\"2.xml\">XML 2</a>.</p>");
|
||||||
|
client.println("</body>");
|
||||||
|
client.println("</html>");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (c == '\n') {
|
||||||
|
Serial.print(" ");
|
||||||
|
// you're starting a new line
|
||||||
|
currentLineIsBlank = true;
|
||||||
|
} else if (c != '\r') {
|
||||||
|
// you've gotten a character on the current line
|
||||||
|
currentLineIsBlank = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// give the web browser time to receive the data
|
||||||
|
delay(1);
|
||||||
|
client.stop();
|
||||||
|
Serial.println("</CONNECTION>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// XML CODE
|
||||||
|
//
|
||||||
|
void Weather2(XMLWriter* xw)
|
||||||
|
{
|
||||||
|
xw->comment("The weather in South Africa");
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
xw->tagStart("Weather");
|
||||||
|
xw->tagField("Date", "20131106");
|
||||||
|
xw->tagField("Time", "1:42");
|
||||||
|
xw->tagField("Temp", "23.4");
|
||||||
|
xw->tagField("Humi", "50%");
|
||||||
|
xw->tagField("Rain", "10mm");
|
||||||
|
xw->tagField("Sun", "40");
|
||||||
|
xw->tagEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Weather(XMLWriter* xw)
|
||||||
|
{
|
||||||
|
xw->comment("The weather in Nebraska");
|
||||||
|
xw->tagOpen("Weather");
|
||||||
|
xw->writeNode("Date", "20131106");
|
||||||
|
xw->writeNode("Time", "11:42");
|
||||||
|
xw->writeNode("Temp", "23.4");
|
||||||
|
xw->writeNode("Humi", "50%");
|
||||||
|
xw->writeNode("Rain", "10mm");
|
||||||
|
xw->writeNode("Sun", "40");
|
||||||
|
xw->tagClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AnalogPorts(XMLWriter* xw, const char* name)
|
||||||
|
{
|
||||||
|
char buffer[24];
|
||||||
|
|
||||||
|
xw->comment("The analog ports are multiplexed");
|
||||||
|
xw->tagOpen("Analog", name);
|
||||||
|
xw->writeNode("Analog0", itoa(analogRead(A0), buffer, 10));
|
||||||
|
xw->writeNode("Analog1", analogRead(A1));
|
||||||
|
xw->writeNode("Analog2", (5.0 * analogRead(A2)) / 1023); // default nr decimals = 2
|
||||||
|
xw->writeNode("Analog3", (5.0 * analogRead(A2)) / 1023, 3);
|
||||||
|
xw->tagClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DigitalPorts(XMLWriter* xw)
|
||||||
|
{
|
||||||
|
char buffer[24];
|
||||||
|
|
||||||
|
xw->comment("The digital ports are not multiplexed");
|
||||||
|
xw->tagOpen("Digital");
|
||||||
|
xw->writeNode("D1", itoa(digitalRead(1), buffer, 10));
|
||||||
|
xw->writeNode("D13", digitalRead(13));
|
||||||
|
xw->tagClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataTypes(XMLWriter* xw)
|
||||||
|
{
|
||||||
|
xw->comment("Testing dataTypes I");
|
||||||
|
xw->tagOpen("Datatypes");
|
||||||
|
xw->writeNode("BoolT", 1 == 1);
|
||||||
|
xw->writeNode("BoolF", 1 == 0);
|
||||||
|
xw->writeNode("BIN", 42, BIN);
|
||||||
|
xw->writeNode("DEC", 42, DEC);
|
||||||
|
xw->writeNode("HEX", 42, HEX);
|
||||||
|
xw->writeNode("OCT", 42, OCT);
|
||||||
|
xw->tagClose();
|
||||||
|
|
||||||
|
xw->comment("Testing dataTypes II");
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
xw->tagStart("dataTypes");
|
||||||
|
xw->tagField("BoolT", 1 == 1);
|
||||||
|
xw->tagField("BoolF", 1 == 0);
|
||||||
|
int x = analogRead(A0);
|
||||||
|
xw->tagField("BIN", x, BIN);
|
||||||
|
xw->tagField("DEC", x, DEC);
|
||||||
|
xw->tagField("HEX", x, HEX);
|
||||||
|
xw->tagField("OCT", x, OCT);
|
||||||
|
xw->tagEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- END OF FILE --
|
@ -0,0 +1,96 @@
|
|||||||
|
//
|
||||||
|
// FILE: XMLWriterSDcard.ino.ino
|
||||||
|
// AUTHOR: Rob Tillaart
|
||||||
|
// VERSION: 0.1.1
|
||||||
|
// PURPOSE: XML writing to SD card
|
||||||
|
// DATE: 2020-04-24
|
||||||
|
// URL: https://github.com/RobTillaart/XMLWriter
|
||||||
|
//
|
||||||
|
// Note: this application will write to the SD card immediately
|
||||||
|
// and it will append to the data.xml file every time started.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <SD.h>
|
||||||
|
// SPI PINS
|
||||||
|
// MOSI 11
|
||||||
|
// MISO 12
|
||||||
|
// CLOCK 13
|
||||||
|
// CS 10
|
||||||
|
#define CS 10 // adjust this ChipSelect line if needed !
|
||||||
|
|
||||||
|
#include <XMLWriter.h>
|
||||||
|
|
||||||
|
char buffer[24];
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println(__FILE__);
|
||||||
|
|
||||||
|
// initialize the SD card
|
||||||
|
if (!SD.begin(CS))
|
||||||
|
{
|
||||||
|
Serial.println("Error: SD card failure");
|
||||||
|
while(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove file for proper timing
|
||||||
|
SD.remove("data.xml");
|
||||||
|
delay(1000);
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t start = micros();
|
||||||
|
File logfile = SD.open("data.xml", FILE_WRITE);
|
||||||
|
if (!logfile)
|
||||||
|
{
|
||||||
|
Serial.println("Error: SD card failure");
|
||||||
|
while(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
XMLWriter XML(&logfile);
|
||||||
|
XML.header();
|
||||||
|
XML.comment("XMLWriterSDcard.ino\nThis is a demo of a simple XML lib for Arduino", true);
|
||||||
|
XML.tagOpen("Arduino", "42");
|
||||||
|
XML.tagOpen("Ports");
|
||||||
|
AnalogPorts(&XML, "measurement");
|
||||||
|
DigitalPorts(&XML);
|
||||||
|
XML.tagClose();
|
||||||
|
XML.tagClose();
|
||||||
|
XML.flush();
|
||||||
|
|
||||||
|
logfile.close();
|
||||||
|
|
||||||
|
uint32_t stop = micros();
|
||||||
|
Serial.println();
|
||||||
|
Serial.println(stop - start);
|
||||||
|
Serial.println("Done...");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AnalogPorts(XMLWriter* xw, const char* name)
|
||||||
|
{
|
||||||
|
xw->comment("The analog ports are multiplexed");
|
||||||
|
xw->tagOpen("Analog", name);
|
||||||
|
xw->writeNode("Analog0", itoa(analogRead(A0), buffer, 10));
|
||||||
|
xw->writeNode("Analog1", analogRead(A1));
|
||||||
|
xw->writeNode("Analog2", (5.0*analogRead(A2))/1023); // default nr decimals = 2
|
||||||
|
xw->writeNode("Analog3", (5.0*analogRead(A2))/1023, 3);
|
||||||
|
xw->tagClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DigitalPorts(XMLWriter* xw)
|
||||||
|
{
|
||||||
|
xw->comment("The digital ports are not multiplexed");
|
||||||
|
xw->tagOpen("Digital");
|
||||||
|
xw->writeNode("D1", itoa(digitalRead(1), buffer, 10));
|
||||||
|
xw->writeNode("D13", digitalRead(13));
|
||||||
|
xw->tagClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- END OF FILE --
|
3
libraries/XMLWriter/examples/XMLWriterSDcard/note.txt
Normal file
3
libraries/XMLWriter/examples/XMLWriterSDcard/note.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
|
https://learn.adafruit.com/adafruit-data-logger-shield/using-the-sd-card
|
6
libraries/XMLWriter/examples/XMLWriterSDcard/readme.md
Normal file
6
libraries/XMLWriter/examples/XMLWriterSDcard/readme.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# XMLWriter
|
||||||
|
|
||||||
|
### SDCARD demo notes
|
||||||
|
|
||||||
|
Do not forget the **XML.flush();** before closing the FILE object.
|
||||||
|
|
@ -1,12 +1,10 @@
|
|||||||
//
|
//
|
||||||
// FILE: XMLWriterTest.ino
|
// FILE: XMLWriterTest.ino
|
||||||
// AUTHOR: Rob Tillaart
|
// AUTHOR: Rob Tillaart
|
||||||
// VERSION: 0.1.03
|
// VERSION: 0.1.5
|
||||||
// PURPOSE: make a simple XML generating lib
|
// PURPOSE: make a simple XML generating lib
|
||||||
// DATE: 2013-11-06
|
// DATE: 2013-11-06
|
||||||
// URL:
|
// URL: https://github.com/RobTillaart/XMLWriter
|
||||||
//
|
|
||||||
// Released to the public domain
|
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <XMLWriter.h>
|
#include <XMLWriter.h>
|
||||||
@ -19,9 +17,12 @@ void setup()
|
|||||||
{
|
{
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
uint32_t start = micros();
|
||||||
|
XML.setConfig(0); // comment this line to see difference
|
||||||
|
|
||||||
XML.header();
|
XML.header();
|
||||||
XML.comment("XMLWriterTest.ino\nThis is a demo of a simple XML lib for Arduino", true);
|
XML.comment("XMLWriterTest.ino\nThis is a demo of a simple XML lib for Arduino", true);
|
||||||
|
// XML.newLine(0);
|
||||||
XML.tagOpen("Arduino", "42");
|
XML.tagOpen("Arduino", "42");
|
||||||
|
|
||||||
XML.tagOpen("Ports");
|
XML.tagOpen("Ports");
|
||||||
@ -35,12 +36,15 @@ void setup()
|
|||||||
DataTypes();
|
DataTypes();
|
||||||
|
|
||||||
XML.tagClose();
|
XML.tagClose();
|
||||||
|
uint32_t stop = micros();
|
||||||
|
Serial.println(stop - start);
|
||||||
|
Serial.println("done...");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Weather2()
|
void Weather2()
|
||||||
{
|
{
|
||||||
XML.comment("The weather in South Africa");
|
XML.comment("The weather in South Africa");
|
||||||
for (int i=0; i<10; i++)
|
for (int i = 0; i < 10; i++)
|
||||||
{
|
{
|
||||||
XML.tagStart("Weather");
|
XML.tagStart("Weather");
|
||||||
XML.tagField("Date", "20131106");
|
XML.tagField("Date", "20131106");
|
||||||
@ -72,8 +76,8 @@ void AnalogPorts(const char* name)
|
|||||||
XML.tagOpen("Analog", name);
|
XML.tagOpen("Analog", name);
|
||||||
XML.writeNode("Analog0", itoa(analogRead(A0), buffer, 10));
|
XML.writeNode("Analog0", itoa(analogRead(A0), buffer, 10));
|
||||||
XML.writeNode("Analog1", analogRead(A1));
|
XML.writeNode("Analog1", analogRead(A1));
|
||||||
XML.writeNode("Analog2", (5.0*analogRead(A2))/1023); // default nr decimals = 2
|
XML.writeNode("Analog2", (5.0 * analogRead(A2)) / 1023); // default nr decimals = 2
|
||||||
XML.writeNode("Analog3", (5.0*analogRead(A2))/1023, 3);
|
XML.writeNode("Analog3", (5.0 * analogRead(A2)) / 1023, 3);
|
||||||
XML.tagClose();
|
XML.tagClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,8 +94,8 @@ void DataTypes()
|
|||||||
{
|
{
|
||||||
XML.comment("Testing dataTypes I");
|
XML.comment("Testing dataTypes I");
|
||||||
XML.tagOpen("Datatypes");
|
XML.tagOpen("Datatypes");
|
||||||
XML.writeNode("Bool", 1 == 1);
|
XML.writeNode("BoolT", 1 == 1);
|
||||||
XML.writeNode("Bool", 1 == 0);
|
XML.writeNode("BoolF", 1 == 0);
|
||||||
XML.writeNode("BIN", 42, BIN);
|
XML.writeNode("BIN", 42, BIN);
|
||||||
XML.writeNode("DEC", 42, DEC);
|
XML.writeNode("DEC", 42, DEC);
|
||||||
XML.writeNode("HEX", 42, HEX);
|
XML.writeNode("HEX", 42, HEX);
|
||||||
@ -99,11 +103,11 @@ void DataTypes()
|
|||||||
XML.tagClose();
|
XML.tagClose();
|
||||||
|
|
||||||
XML.comment("Testing dataTypes II");
|
XML.comment("Testing dataTypes II");
|
||||||
for (int i=0; i<3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
XML.tagStart("dataTypes");
|
XML.tagStart("dataTypes");
|
||||||
XML.tagField("Bool", 1 == 1);
|
XML.tagField("BoolT", 1 == 1);
|
||||||
XML.tagField("Bool", 1 == 0);
|
XML.tagField("BoolF", 1 == 0);
|
||||||
int x = analogRead(A0);
|
int x = analogRead(A0);
|
||||||
XML.tagField("BIN", x, BIN);
|
XML.tagField("BIN", x, BIN);
|
||||||
XML.tagField("DEC", x, DEC);
|
XML.tagField("DEC", x, DEC);
|
||||||
@ -116,3 +120,5 @@ void DataTypes()
|
|||||||
void loop()
|
void loop()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -- END OF FILE --
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
//
|
//
|
||||||
// FILE: XMLWriterDemo01.ino
|
// FILE: XMLWriterDemo01.ino
|
||||||
// AUTHOR: Rob Tillaart
|
// AUTHOR: Rob Tillaart
|
||||||
// VERSION: 0.1.00
|
// VERSION: 0.1.2
|
||||||
// PURPOSE: XML writer demo
|
// PURPOSE: XML writer demo
|
||||||
// DATE: 2016-03-16
|
// DATE: 2016-03-16
|
||||||
// URL:
|
// URL: https://github.com/RobTillaart/XMLWriter
|
||||||
//
|
|
||||||
// Released to the public domain
|
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <XMLWriter.h>
|
#include <XMLWriter.h>
|
||||||
@ -21,7 +19,11 @@ void setup()
|
|||||||
float y = random(100) * 1.0;
|
float y = random(100) * 1.0;
|
||||||
float r = random(100) * 1.0;
|
float r = random(100) * 1.0;
|
||||||
|
|
||||||
|
uint32_t start = micros();
|
||||||
shoot(p, y, r);
|
shoot(p, y, r);
|
||||||
|
uint32_t stop = micros();
|
||||||
|
Serial.println();
|
||||||
|
Serial.println(stop - start);
|
||||||
}
|
}
|
||||||
|
|
||||||
void shoot(float p, float y, float r)
|
void shoot(float p, float y, float r)
|
||||||
@ -80,9 +82,20 @@ void shoot(float p, float y, float r)
|
|||||||
XML.tagStart("/position");
|
XML.tagStart("/position");
|
||||||
XML.tagEnd(NEWLINE, NOSLASH);
|
XML.tagEnd(NEWLINE, NOSLASH);
|
||||||
|
|
||||||
|
XML.comment("test escape() codes");
|
||||||
|
XML.tagOpen("supported");
|
||||||
|
XML.writeNode("ampersand", "&");
|
||||||
|
XML.writeNode("lessthan", "<");
|
||||||
|
XML.writeNode("greaterthan", ">");
|
||||||
|
XML.writeNode("quote", "\"");
|
||||||
|
XML.writeNode("apostrophe", "\'");
|
||||||
|
XML.tagClose();
|
||||||
|
|
||||||
XML.tagClose(); // shoot
|
XML.tagClose(); // shoot
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -- END OF FILE --
|
||||||
|
@ -1,17 +1,9 @@
|
|||||||
#######################################
|
|
||||||
# Syntax Coloring Map For XMLWriter
|
# Syntax Coloring Map For XMLWriter
|
||||||
#######################################
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Datatypes (KEYWORD1)
|
# Datatypes (KEYWORD1)
|
||||||
#######################################
|
|
||||||
|
|
||||||
XMLWriter KEYWORD1
|
XMLWriter KEYWORD1
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Methods and Functions (KEYWORD2)
|
# Methods and Functions (KEYWORD2)
|
||||||
#######################################
|
|
||||||
|
|
||||||
reset KEYWORD2
|
reset KEYWORD2
|
||||||
header KEYWORD2
|
header KEYWORD2
|
||||||
comment KEYWORD2
|
comment KEYWORD2
|
||||||
@ -27,16 +19,12 @@ decrIndent KEYWORD2
|
|||||||
indent KEYWORD2
|
indent KEYWORD2
|
||||||
raw KEYWORD2
|
raw KEYWORD2
|
||||||
escape KEYWORD2
|
escape KEYWORD2
|
||||||
|
setConfig KEYWORD2
|
||||||
|
newLine KEYWORD2
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Instances (KEYWORD2)
|
# Instances (KEYWORD2)
|
||||||
#######################################
|
|
||||||
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Constants (LITERAL1)
|
# Constants (LITERAL1)
|
||||||
#######################################
|
|
||||||
|
|
||||||
NOMULTILINE LITERAL1
|
NOMULTILINE LITERAL1
|
||||||
MULTILINE LITERAL1
|
MULTILINE LITERAL1
|
||||||
NEWLINE LITERAL1
|
NEWLINE LITERAL1
|
||||||
@ -44,3 +32,6 @@ NONEWLINE LITERAL1
|
|||||||
NOINDENT LITERAL1
|
NOINDENT LITERAL1
|
||||||
SLASH LITERAL1
|
SLASH LITERAL1
|
||||||
NOSLASH LITERAL1
|
NOSLASH LITERAL1
|
||||||
|
XMLWRITER_NONE LITERAL1
|
||||||
|
XMLWRITER_COMMENT LITERAL1
|
||||||
|
XMLWRITER_INDENT LITERAL1
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "XMLWriter",
|
"name": "XMLWriter",
|
||||||
"keywords": "Write,XML,node,header,tag,indent,field,stream",
|
"keywords": "Write, XML, node, header, tag, indent, field, stream,",
|
||||||
"description": "Library for writing XML files.",
|
"description": "Arduino library for creating XML",
|
||||||
"authors":
|
"authors":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
@ -13,12 +13,12 @@
|
|||||||
"repository":
|
"repository":
|
||||||
{
|
{
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/RobTillaart/Arduino.git"
|
"url": "https://github.com/RobTillaart/XMLWriter"
|
||||||
},
|
},
|
||||||
"version":"0.1.8",
|
"version":"0.2.2",
|
||||||
"frameworks": "arduino",
|
"frameworks": "arduino",
|
||||||
"platforms": "*",
|
"platforms": "*",
|
||||||
"export": {
|
"export": {
|
||||||
"include": "libraries/XMLWriter"
|
"include": "XMLWriter"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
name=XMLWriter
|
name=XMLWriter
|
||||||
version=0.1.8
|
version=0.2.2
|
||||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||||
sentence=Library for writing XML files.
|
sentence=Arduino library for creating XML
|
||||||
paragraph=
|
paragraph=
|
||||||
category=Data Processing
|
category=Data Processing
|
||||||
url=https://github.com/RobTillaart/Arduino/tree/master/libraries
|
url=https://github.com/RobTillaart/XMLWriter
|
||||||
architectures=*
|
architectures=*
|
||||||
|
includes=XMLWriter.h
|
||||||
|
depends=
|
||||||
|
Loading…
x
Reference in New Issue
Block a user