commit
2fecde937c
322 changed files with 50932 additions and 0 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 9.1 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 2.0 KiB |
File diff suppressed because one or more lines are too long
@ -0,0 +1,39 @@
@@ -0,0 +1,39 @@
|
||||
|
||||
This directory is intended for project header files. |
||||
|
||||
A header file is a file containing C declarations and macro definitions |
||||
to be shared between several project source files. You request the use of a |
||||
header file in your project source file (C, C++, etc) located in `src` folder |
||||
by including it, with the C preprocessing directive `#include'. |
||||
|
||||
```src/main.c |
||||
|
||||
#include "header.h" |
||||
|
||||
int main (void) |
||||
{ |
||||
... |
||||
} |
||||
``` |
||||
|
||||
Including a header file produces the same results as copying the header file |
||||
into each source file that needs it. Such copying would be time-consuming |
||||
and error-prone. With a header file, the related declarations appear |
||||
in only one place. If they need to be changed, they can be changed in one |
||||
place, and programs that include the header file will automatically use the |
||||
new version when next recompiled. The header file eliminates the labor of |
||||
finding and changing all the copies as well as the risk that a failure to |
||||
find one copy will result in inconsistencies within a program. |
||||
|
||||
In C, the usual convention is to give header files names that end with `.h'. |
||||
It is most portable to use only letters, digits, dashes, and underscores in |
||||
header file names, and at most one dot. |
||||
|
||||
Read more about using header files in official GCC documentation: |
||||
|
||||
* Include Syntax |
||||
* Include Operation |
||||
* Once-Only Headers |
||||
* Computed Includes |
||||
|
||||
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html |
||||
@ -0,0 +1,567 @@
@@ -0,0 +1,567 @@
|
||||
/*! \file ELClient.cpp
|
||||
\brief Constructor and functions for ELClient |
||||
\author B. Runnels |
||||
\author T. von Eicken |
||||
\date 2016 |
||||
*/ |
||||
// Copyright (c) 2016 by B. Runnels and T. von Eicken
|
||||
|
||||
#include "ELClient.h" |
||||
|
||||
#define SLIP_END 0300 /**< Indicates end of packet */ |
||||
#define SLIP_ESC 0333 /**< Indicates byte stuffing */ |
||||
#define SLIP_ESC_END 0334 /**< ESC ESC_END means END data byte */ |
||||
#define SLIP_ESC_ESC 0335 /**< ESC ESC_ESC means ESC data byte */ |
||||
|
||||
//===== Input
|
||||
|
||||
/*! protoCompletedCb(void *res)
|
||||
@brief Process a received SLIP message |
||||
@details Callback to process a SLIP message and check CRCs |
||||
If a user callback function was defined in the message, ELClientResponse is called to handle the callback. |
||||
@note |
||||
This function is usually not needed for applications. The communication to the ESP8266 is handled by the cmd, rest, mqtt, tcp and udp library parts. |
||||
@return <code>ELClientPacket</code> |
||||
Pointer to ELClientPacket structure generated or NULL if it the message is from a callback or if an error occured |
||||
@par Example |
||||
@code |
||||
no example code yet |
||||
@endcode |
||||
*/ |
||||
ELClientPacket* ELClient::protoCompletedCb(void) { |
||||
// the packet starts with a ELClientPacket
|
||||
ELClientPacket* packet = (ELClientPacket*)_proto.buf; |
||||
if (_debugEn) { |
||||
_debug->print("ELC: got "); |
||||
_debug->print(_proto.dataLen); |
||||
_debug->print(" @"); |
||||
_debug->print((uint32_t)_proto.buf, 16); |
||||
_debug->print(": "); |
||||
_debug->print(packet->cmd, 16); |
||||
_debug->print(" "); |
||||
_debug->print(packet->value, 16); |
||||
_debug->print(" "); |
||||
_debug->print(packet->argc, 16); |
||||
for (uint16_t i=8; i<_proto.dataLen; i++) { |
||||
_debug->print(" "); |
||||
_debug->print(*(uint8_t*)(_proto.buf+i), 16); |
||||
} |
||||
_debug->println(); |
||||
} |
||||
|
||||
// verify CRC
|
||||
uint16_t crc = crc16Data(_proto.buf, _proto.dataLen-2, 0); |
||||
uint16_t resp_crc = *(uint16_t*)(_proto.buf+_proto.dataLen-2); |
||||
if (crc != resp_crc) { |
||||
DBG("ELC: Invalid CRC"); |
||||
return NULL; |
||||
} |
||||
|
||||
// dispatch based on command
|
||||
switch (packet->cmd) { |
||||
case CMD_RESP_V: // response with a value: return the packet
|
||||
// value response
|
||||
if (_debugEn) { |
||||
_debug->print("RESP_V: "); |
||||
_debug->println(packet->value); |
||||
} |
||||
return packet; |
||||
case CMD_RESP_CB: // response callback: perform the callback!
|
||||
FP<void, void*> *fp; |
||||
// callback reponse
|
||||
if (_debugEn) { |
||||
_debug->print("RESP_CB: "); |
||||
_debug->print(packet->value); |
||||
_debug->print(" "); |
||||
_debug->println(packet->argc); |
||||
} |
||||
fp = (FP<void, void*>*)packet->value; |
||||
if (fp->attached()) { |
||||
ELClientResponse resp(packet); |
||||
(*fp)(&resp); |
||||
} |
||||
return NULL; |
||||
case CMD_SYNC: // esp-link is not in sync, it may have reset, signal up the stack
|
||||
_debug->println("NEED_SYNC!"); |
||||
if (resetCb != NULL) (*resetCb)(); |
||||
return NULL; |
||||
default: |
||||
// command (NOT IMPLEMENTED)
|
||||
if (_debugEn) _debug->println("CMD??"); |
||||
return NULL; |
||||
} |
||||
} |
||||
|
||||
/*! Process()
|
||||
@brief Handle serial input. |
||||
@details Read all characters available on the serial input and process any messages that arrive, |
||||
but stop if a non-callback response comes in |
||||
@return <code>ELClientPacket</code> |
||||
Pointer to ELClientResponse structure with the received response |
||||
@par Example |
||||
@code |
||||
void loop() |
||||
{ |
||||
ELClientPacket *packet; |
||||
// process any callbacks coming from esp_link
|
||||
packet = esp.Process(); |
||||
if (packet != 0) |
||||
{ |
||||
// process the received package //
|
||||
} |
||||
} |
||||
@endcode |
||||
*/ |
||||
ELClientPacket *ELClient::Process() { |
||||
int value; |
||||
while (_serial->available()) { |
||||
value = _serial->read(); |
||||
if (value == SLIP_ESC) { |
||||
_proto.isEsc = 1; |
||||
} else if (value == SLIP_END) { |
||||
ELClientPacket *packet = _proto.dataLen >= 8 ? protoCompletedCb() : 0; |
||||
_proto.dataLen = 0; |
||||
_proto.isEsc = 0; |
||||
if (packet != NULL) return packet; |
||||
} else { |
||||
if (_proto.isEsc) { |
||||
if (value == SLIP_ESC_END) value = SLIP_END; |
||||
if (value == SLIP_ESC_ESC) value = SLIP_ESC; |
||||
_proto.isEsc = 0; |
||||
} |
||||
if (_proto.dataLen < _proto.bufSize) { |
||||
_proto.buf[_proto.dataLen++] = value; |
||||
} |
||||
} |
||||
} |
||||
return NULL; |
||||
} |
||||
|
||||
//===== Output
|
||||
|
||||
/*! write(uint8_t data)
|
||||
@brief Send a byte |
||||
@details Write a byte to the output stream and perform SLIP escaping |
||||
@note |
||||
This function is usually not needed for applications. The communication to the ESP8266 is handled by the cmd, rest, mqtt, tcp and udp library parts. |
||||
@param data |
||||
Byte to be sent |
||||
@par Example |
||||
@code |
||||
no example code yet |
||||
@endcode |
||||
*/ |
||||
void ELClient::write(uint8_t data) { |
||||
switch (data) { |
||||
case SLIP_END: |
||||
_serial->write(SLIP_ESC); |
||||
_serial->write(SLIP_ESC_END); |
||||
break; |
||||
case SLIP_ESC: |
||||
_serial->write(SLIP_ESC); |
||||
_serial->write(SLIP_ESC_ESC); |
||||
break; |
||||
default: |
||||
_serial->write(data); |
||||
} |
||||
} |
||||
|
||||
/*! write(void* data, uint16_t len)
|
||||
@brief Send several byte |
||||
@details Write some bytes to the output stream, no SLIP escaping is performed |
||||
@note |
||||
This function is usually not needed for applications. The communication to the ESP8266 is handled by the cmd, rest, mqtt, tcp and udp library parts. |
||||
@param data |
||||
Pointer to data buffer to be sent |
||||
@param len |
||||
Size of data buffer |
||||
@par Example |
||||
@code |
||||
no example code yet |
||||
@endcode |
||||
*/ |
||||
void ELClient::write(void* data, uint16_t len) { |
||||
uint8_t *d = (uint8_t*)data; |
||||
while (len--) |
||||
write(*d++); |
||||
} |
||||
|
||||
/*! Request(uint16_t cmd, uint32_t value, uint16_t argc)
|
||||
@brief Start a request |
||||
@details Start preparing a request by sending the command, number of arguments |
||||
and the first argument (which can be a callback pointer) |
||||
@note |
||||
This function is usually not needed for applications. The communication to the ESP8266 is handled by the cmd, rest, mqtt, tcp and udp library parts. |
||||
@param cmd |
||||
Command for the ESP, see enum CmdName for available commands |
||||
@param value |
||||
First argument or pointer to a callback function |
||||
@param argc |
||||
Number of arguments in this request |
||||
@par Example |
||||
@code |
||||
_elc->Request(CMD_MQTT_LWT, 0, 4); |
||||
_elc->Request(topic, strlen(topic)); |
||||
_elc->Request(message, strlen(message)); |
||||
_elc->Request(&qos, 1); |
||||
_elc->Request(&retain, 1); |
||||
_elc->Request(); |
||||
@endcode |
||||
*/ |
||||
void ELClient::Request(uint16_t cmd, uint32_t value, uint16_t argc) { |
||||
crc = 0; |
||||
_serial->write(SLIP_END); |
||||
write(&cmd, 2); |
||||
crc = crc16Data((unsigned const char*)&cmd, 2, crc); |
||||
|
||||
write(&argc, 2); |
||||
crc = crc16Data((unsigned const char*)&argc, 2, crc); |
||||
|
||||
write(&value, 4); |
||||
crc = crc16Data((unsigned const char*)&value, 4, crc); |
||||
} |
||||
|
||||
/*! Request(uint16_t cmd, uint32_t value, uint16_t argc)
|
||||
@brief Append an argument to the request |
||||
@details Send additional arguments as appendment to the ESP |
||||
@note |
||||
This function is usually not needed for applications. The communication to the ESP8266 is handled by the cmd, rest, mqtt, tcp and udp library parts. |
||||
@param data |
||||
Pointer to the buffer with the argument |
||||
@param len |
||||
Size of the argument buffer |
||||
@par Example |
||||
@code |
||||
_elc->Request(CMD_MQTT_LWT, 0, 4); |
||||
_elc->Request(topic, strlen(topic)); |
||||
_elc->Request(message, strlen(message)); |
||||
_elc->Request(&qos, 1); |
||||
_elc->Request(&retain, 1); |
||||
_elc->Request(); |
||||
@endcode |
||||
*/ |
||||
void ELClient::Request(const void* data, uint16_t len) { |
||||
uint8_t *d = (uint8_t*)data; |
||||
|
||||
// write the length
|
||||
write(&len, 2); |
||||
crc = crc16Data((unsigned const char*)&len, 2, crc); |
||||
|
||||
// output the data
|
||||
for (uint16_t l=len; l>0; l--) { |
||||
write(*d); |
||||
crc = crc16Add(*d, crc); |
||||
d++; |
||||
} |
||||
|
||||
// output padding
|
||||
uint16_t pad = (4-(len&3))&3; |
||||
uint8_t temp = 0; |
||||
while (pad--) { |
||||
write(temp); |
||||
crc = crc16Add(temp, crc); |
||||
} |
||||
} |
||||
|
||||
/*! Request(const __FlashStringHelper* data, uint16_t len)
|
||||
@brief Append an argument to the request |
||||
@details Send additional arguments located in flash as appendment to the ESP |
||||
@note |
||||
This function is usually not needed for applications. The communication to the ESP8266 is handled by the cmd, rest, mqtt, tcp and udp library parts. |
||||
@param data |
||||
Pointer to the buffer with the argument |
||||
@param len |
||||
Size of the argument buffer |
||||
@par Example |
||||
@code |
||||
_elc->Request(CMD_MQTT_LWT, 0, 4); |
||||
_elc->Request(topic, strlen(topic)); |
||||
_elc->Request(message, strlen(message)); |
||||
_elc->Request(&qos, 1); |
||||
_elc->Request(&retain, 1); |
||||
_elc->Request(); |
||||
@endcode |
||||
*/ |
||||
void ELClient::Request(const __FlashStringHelper* data, uint16_t len) { |
||||
// write the length
|
||||
write(&len, 2); |
||||
crc = crc16Data((unsigned const char*)&len, 2, crc); |
||||
|
||||
// output the data
|
||||
PGM_P p = reinterpret_cast<PGM_P>(data); |
||||
for (uint16_t l=len; l>0; l--) { |
||||
uint8_t c = pgm_read_byte(p++); |
||||
write(c); |
||||
crc = crc16Add(c, crc); |
||||
} |
||||
|
||||
// output padding
|
||||
uint16_t pad = (4-(len&3))&3; |
||||
uint8_t temp = 0; |
||||
while (pad--) { |
||||
write(temp); |
||||
crc = crc16Add(temp, crc); |
||||
} |
||||
} |
||||
|
||||
/*! Request(void)
|
||||
@brief Finish the request |
||||
@details Send final CRC and SLIP_END to the ESP to finish the request |
||||
@note |
||||
This function is usually not needed for applications. The communication to the ESP8266 is handled by the cmd, rest, mqtt, tcp and udp library parts. |
||||
@par Example |
||||
@code |
||||
_elc->Request(CMD_MQTT_LWT, 0, 4); |
||||
_elc->Request(topic, strlen(topic)); |
||||
_elc->Request(message, strlen(message)); |
||||
_elc->Request(&qos, 1); |
||||
_elc->Request(&retain, 1); |
||||
_elc->Request(); |
||||
@endcode |
||||
*/ |
||||
void ELClient::Request(void) { |
||||
write((uint8_t*)&crc, 2); |
||||
_serial->write(SLIP_END); |
||||
} |
||||
|
||||
//===== Initialization
|
||||
|
||||
/*! init()
|
||||
@brief Initialize ELClient protocol |
||||
@details Prepare buffer for protocol |
||||
@note |
||||
This function is usually not needed for applications. The communication to the ESP8266 is handled by the cmd, rest, mqtt, tcp and udp library parts. |
||||
@par Example |
||||
@code |
||||
no example code yet |
||||
@endcode |
||||
*/ |
||||
void ELClient::init() { |
||||
_proto.buf = _protoBuf; |
||||
_proto.bufSize = sizeof(_protoBuf); |
||||
_proto.dataLen = 0; |
||||
_proto.isEsc = 0; |
||||
} |
||||
|
||||
/*! ELClient(Stream* serial)
|
||||
@brief Initialize ELClient |
||||
@details Store serial stream to be used for the communication |
||||
@param serial |
||||
Serial stream for communication with ESP |
||||
@par Example for hardware serial ports |
||||
@code |
||||
//###########################################################
|
||||
// For boards using the hardware serial port!
|
||||
//###########################################################
|
||||
// Initialize a connection to esp-link using the normal hardware serial port for SLIP messages.
|
||||
ELClient esp(&Serial); |
||||
@endcode |
||||
@par Example for ARDUINO UNO WIFI board with I2C to serial chip connected to the ESP8266 |
||||
@code |
||||
//###########################################################
|
||||
// For ARDUINO UNO WIFI board with I2C to serial chip connected to the ESP8266!
|
||||
//###########################################################
|
||||
// Serial port to ESP8266
|
||||
#include <SC16IS750.h> |
||||
SC16IS750 i2cuart = SC16IS750(SC16IS750_PROTOCOL_I2C,SC16IS750_ADDRESS_AA); |
||||
// Initialize a connection to esp-link using the I2Cuart chip of the Arduino Uno WiFi board for SLIP messages.
|
||||
ELClient esp(&i2cuart); |
||||
@endcode |
||||
*/ |
||||
ELClient::ELClient(Stream* serial) : |
||||
_serial(serial) { |
||||
_debugEn = false; |
||||
init(); |
||||
} |
||||
|
||||
/*! ELClient(Stream* serial, Stream* debug)
|
||||
@brief Initialize ELClient and enable debug output |
||||
@details Store serial streams to be used for the communication |
||||
@param serial |
||||
Serial stream for communication with ESP |
||||
@param debug |
||||
Serial stream for debug output |
||||
@par Example for hardware serial ports |
||||
@code |
||||
//###########################################################
|
||||
// For boards using the hardware serial port!
|
||||
//###########################################################
|
||||
// Initialize a connection to esp-link using the normal hardware serial port both for SLIP and for debug messages.
|
||||
ELClient esp(&Serial, &Serial); |
||||
@endcode |
||||
@par Example for ARDUINO UNO WIFI board with I2C to serial chip connected to the ESP8266 |
||||
@code |
||||
//###########################################################
|
||||
// For ARDUINO UNO WIFI board with I2C to serial chip connected to the ESP8266!
|
||||
//###########################################################
|
||||
// Serial port to ESP8266
|
||||
#include <SC16IS750.h> |
||||
SC16IS750 i2cuart = SC16IS750(SC16IS750_PROTOCOL_I2C,SC16IS750_ADDRESS_AA); |
||||
// Initialize a connection to esp-link using the I2Cuart chip of the Arduino Uno WiFi board for SLIP messages.
|
||||
ELClient esp(&i2cuart, &Serial); |
||||
@endcode |
||||
*/ |
||||
ELClient::ELClient(Stream* serial, Stream* debug) : |
||||
_debug(debug), _serial(serial) { |
||||
_debugEn = true; |
||||
init(); |
||||
} |
||||
|
||||
/*! ELClient::DBG(const char* info)
|
||||
@brief Send debug message over serial debug stream |
||||
@param info |
||||
Debug message |
||||
@par Example |
||||
@code |
||||
no example code yet |
||||
@endcode |
||||
*/ |
||||
void ELClient::DBG(const char* info) { |
||||
if (_debugEn) _debug->println(info); |
||||
} |
||||
|
||||
//===== Responses
|
||||
|
||||
/*! WaitReturn(uint32_t timeout)
|
||||
@brief Wait for a response from ESP for a given timeout |
||||
@param timeout |
||||
Time in milliseconds to wait for a response, defaults to ESP_TIMEOUT |
||||
@return <code>ELClientPacket</code> |
||||
Received packet or null if timeout occured |
||||
@par Example |
||||
@code |
||||
// Wait for WiFi to be connected.
|
||||
esp.GetWifiStatus(); |
||||
ELClientPacket *packet; |
||||
Serial.print("Waiting for WiFi "); |
||||
if ((packet=esp.WaitReturn()) != NULL) { |
||||
Serial.print("."); |
||||
Serial.println(packet->value); |
||||
} |
||||
Serial.println(""); |
||||
@endcode |
||||
*/ |
||||
ELClientPacket *ELClient::WaitReturn(uint32_t timeout) { |
||||
uint32_t wait = millis(); |
||||
while (millis() - wait < timeout) { |
||||
ELClientPacket *packet = Process(); |
||||
if (packet != NULL) return packet; |
||||
} |
||||
return NULL; |
||||
} |
||||
|
||||
//===== CRC helper functions
|
||||
|
||||
/*! crc16Add(unsigned char b, uint16_t acc)
|
||||
@brief Create CRC for a byte add it to an existing CRC checksum and return the result |
||||
@param b |
||||
Byte which CRC will be added |
||||
@param acc |
||||
Existing CRC checksum |
||||
@return <code>uint16_t</code> |
||||
New CRC checksum |
||||
@par Example |
||||
@code |
||||
no example code yet |
||||
@endcode |
||||
*/ |
||||
uint16_t ELClient::crc16Add(unsigned char b, uint16_t acc) |
||||
{ |
||||
acc ^= b; |
||||
acc = (acc >> 8) | (acc << 8); |
||||
acc ^= (acc & 0xff00) << 4; |
||||
acc ^= (acc >> 8) >> 4; |
||||
acc ^= (acc & 0xff00) >> 5; |
||||
return acc; |
||||
} |
||||
|
||||
/*! crc16Data(const unsigned char *data, uint16_t len, uint16_t acc)
|
||||
@brief Create/add CRC for a data buffer |
||||
@param data |
||||
The data buffer which will be CRCed |
||||
@param len |
||||
Size of the data buffer |
||||
@param acc |
||||
Existing CRC checksum |
||||
@return <code>uint16_t</code> |
||||
New CRC checksum |
||||
@par Example |
||||
@code |
||||
no example code yet |
||||
@endcode |
||||
*/ |
||||
uint16_t ELClient::crc16Data(const unsigned char *data, uint16_t len, uint16_t acc) |
||||
{ |
||||
for (uint16_t i=0; i<len; i++) |
||||
acc = crc16Add(*data++, acc); |
||||
return acc; |
||||
} |
||||
|
||||
//===== Basic requests built into ElClient
|
||||
|
||||
/*! Sync(uint32_t timeout)
|
||||
@brief Synchronize the communication between the MCU and the ESP |
||||
@param timeout |
||||
Timeout for synchronization request |
||||
@return <code>boolean</code> |
||||
True if synchronization succeeds or False if it fails |
||||
@par Example |
||||
@code |
||||
// Sync-up with esp-link, this is required at the start of any sketch and initializes the callbacks to the wifi status change callback. The callback gets called with the initial status right after Sync() below completes.
|
||||
esp.wifiCb.attach(wifiCb); // wifi status change callback, optional (delete if not desired)
|
||||
bool ok; |
||||
do |
||||
{ |
||||
ok = esp.Sync(); // sync up with esp-link, blocks for up to 2 seconds
|
||||
if (!ok) Serial.println("EL-Client sync failed!"); |
||||
} while(!ok); |
||||
Serial.println("EL-Client synced!"); |
||||
@endcode |
||||
*/ |
||||
boolean ELClient::Sync(uint32_t timeout) { |
||||
// send a SLIP END char to make sure we get a clean start
|
||||
_serial->write(SLIP_END); |
||||
// send sync request
|
||||
Request(CMD_SYNC, (uint32_t)&wifiCb, 0); |
||||
Request(); |
||||
// we don't want to get a stale response that we need to sync 'cause that has the effect of
|
||||
// calling us again recursively....
|
||||
void (*rr)() = resetCb; |
||||
resetCb = NULL; |
||||
// empty the response queue hoping to find the wifiCb address
|
||||
ELClientPacket *packet; |
||||
while ((packet = WaitReturn(timeout)) != NULL) { |
||||
if (packet->value == (uint32_t)&wifiCb) { |
||||
if (_debugEn) _debug->println("SYNC!"); |
||||
resetCb = rr; |
||||
return true; |
||||
} |
||||
if (_debugEn) { |
||||
_debug->print("BAD: "); |
||||
_debug->println(packet->value); |
||||
} |
||||
} |
||||
// doesn't look like we got a real response
|
||||
resetCb = rr; |
||||
return false; |
||||
} |
||||
|
||||
/*! GetWifiStatus(void)
|
||||
@brief Request WiFi status from the ESP |
||||
@par Example |
||||
@code |
||||
// Wait for WiFi to be connected.
|
||||
esp.GetWifiStatus(); |
||||
ELClientPacket *packet; |
||||
Serial.print("Waiting for WiFi "); |
||||
if ((packet=esp.WaitReturn()) != NULL) { |
||||
Serial.print("."); |
||||
Serial.println(packet->value); |
||||
} |
||||
Serial.println(""); |
||||
@endcode |
||||
*/ |
||||
void ELClient::GetWifiStatus(void) { |
||||
Request(CMD_WIFI_STATUS, 0, 0); |
||||
Request(); |
||||
} |
||||
@ -0,0 +1,139 @@
@@ -0,0 +1,139 @@
|
||||
/*! \file ELClient.h
|
||||
\brief Definitions for ELClient |
||||
*/ |
||||
|
||||
#ifndef _EL_CLIENT_H_ |
||||
#define _EL_CLIENT_H_ |
||||
|
||||
#include <avr/pgmspace.h> |
||||
#include <HardwareSerial.h> |
||||
#include <Arduino.h> |
||||
#include "ELClientResponse.h" |
||||
#include "FP.h" |
||||
|
||||
#define ESP_TIMEOUT 5000 /**< Default timeout for TCP requests when waiting for a response */ |
||||
#define MQTT_MAX_PACKET_SIZE 300 |
||||
|
||||
// Enumeration of commands supported by esp-link, this needs to match the definition in
|
||||
// esp-link!
|
||||
typedef enum { |
||||
CMD_NULL = 0, /**< null, mainly to prevent 0 from doing something bad */ |
||||
CMD_SYNC, /**< Synchronize, starts the protocol */ |
||||
CMD_RESP_V, /**< Response with a value */ |
||||
CMD_RESP_CB, /**< Response with a callback */ |
||||
CMD_WIFI_STATUS, /**< Get the wifi status */ |
||||
CMD_CB_ADD, /**< Add a custom callback */ |
||||
CMD_CB_EVENTS, /**< ??? */ |
||||
CMD_GET_TIME, /**< Get current time in seconds since the unix epoch */ |
||||
//CMD_GET_INFO,
|
||||
|
||||
CMD_MQTT_SETUP = 10, /**< Register callback functions */ |
||||
CMD_MQTT_PUBLISH, /**< Publish MQTT topic */ |
||||
CMD_MQTT_SUBSCRIBE, /**< Subscribe to MQTT topic */ |
||||
CMD_MQTT_LWT, /**< Define MQTT last will */ |
||||
|
||||
CMD_REST_SETUP = 20, /**< Setup REST connection */ |
||||
CMD_REST_REQUEST, /**< Make request to REST server */ |
||||
CMD_REST_SETHEADER, /**< Define HTML header */ |
||||
|
||||
CMD_WEB_SETUP = 30, /**< web-server setup */ |
||||
CMD_WEB_DATA, /**< used for publishing web-server data */ |
||||
|
||||
CMD_SOCKET_SETUP = 40, /**< Setup socket connection */ |
||||
CMD_SOCKET_SEND, /**< Send socket packet */ |
||||
} CmdName; /**< Enumeration of commands supported by esp-link, this needs to match the definition in esp-link! */ |
||||
|
||||
enum WIFI_STATUS { |
||||
STATION_IDLE = 0, /**< Idle status */ |
||||
STATION_CONNECTING, /**< Trying to connect */ |
||||
STATION_WRONG_PASSWORD, /**< Connection error, wrong password */ |
||||
STATION_NO_AP_FOUND, /**< Connection error, AP not found */ |
||||
STATION_CONNECT_FAIL, /**< Connection error, connection failed */ |
||||
STATION_GOT_IP /**< Connected, received IP */ |
||||
}; /**< Enumeration of possible WiFi status */ |
||||
|
||||
typedef struct { |
||||
uint8_t* buf; |
||||
uint16_t bufSize; |
||||
uint16_t dataLen; |
||||
uint8_t isEsc; |
||||
} ELClientProtocol; /**< Protocol structure */ |
||||
|
||||
// The ELClient class implements the basic protocol to communicate with esp-link using SLIP.
|
||||
// The SLIP protocol just provides framing, i.e., it delineates the start and end of packets.
|
||||
// The format of each packet is dictated by ELClient and consists of a 2-byte command, a 2-byte
|
||||
// count of arguments, a 4-byte callback addr, then the arguments, and finally 1 2-byte CRC.
|
||||
//
|
||||
// ELClient handles communication set-up and reset. It has to take a number of scenarios into
|
||||
// account, including simultaneous power-on reset of arduino and esp-link, spontaneous reset of
|
||||
// esp-link, and reset of arduino. Returning to a consistent state in all these cases is handled by
|
||||
// the Sync function and null commands.
|
||||
//
|
||||
// When ELClient starts it needs to send a Sync to esp-link. This clears all state and callbacks on
|
||||
// the esp-link side and then ELClient can install callbacks, etc. In order to catch the cases where
|
||||
// esp-link resets ELClient ensures that it sends periodic commands to esp-link and checks whether
|
||||
// esp-link responds with a "not synced" error, which indicates that it reset. If such an error
|
||||
// occurs ELClient starts with a fresh Sync. Unfortunately this has to be propagated up the
|
||||
// communication layers because the client may have to re-subscribe to MQTT messages or to certain
|
||||
// callbacks.
|
||||
class ELClient { |
||||
public: |
||||
// Create an esp-link client based on a stream and with a specified debug output stream.
|
||||
ELClient(Stream* serial, Stream* debug); |
||||
// Create an esp-link client based on a stream with no debug output
|
||||
ELClient(Stream* serial); |
||||
|
||||
Stream* _debug; /**< Data stream for debug use */ |
||||
|
||||
//== Requests
|
||||
// Start a request. cmd is the command to execute, value is either the address of a function
|
||||
// to call with a response or a first argument to the command if there is no CB.
|
||||
// Argc is the number of additional arguments
|
||||
void Request(uint16_t cmd, uint32_t value, uint16_t argc); |
||||
// Add a an argument consisting of a data block to a request
|
||||
void Request(const void* data, uint16_t len); |
||||
// Add a an argument consisting of a data block in flash to a request
|
||||
void Request(const __FlashStringHelper* data, uint16_t len); |
||||
// Finish a request
|
||||
void Request(void); |
||||
|
||||
//== Responses
|
||||
// Process the input stream, call this in loop() to dispatch call-back based responses.
|
||||
// Callbacks on FP are invoked with an ElClientResponse pointer as argument.
|
||||
// Returns the ELClientPacket if a non-callback response was received, typically this is
|
||||
// used to create an ELClientResponse. Returns NULL if no response needs to be processed.
|
||||
ELClientPacket *Process(void); |
||||
// Busy wait for a response with a timeout in milliseconds, returns an ELClientPacket
|
||||
// if a response was recv'd and NULL otherwise. The ELClientPacket is typically used to
|
||||
// create an ELClientResponse.
|
||||
ELClientPacket *WaitReturn(uint32_t timeout=ESP_TIMEOUT); |
||||
|
||||
//== Commands built-into ELClient
|
||||
// Initialize and synchronize communication with esp-link with a timeout in milliseconds,
|
||||
// and remove all existing callbacks. Registers the wifiCb and returns true on success
|
||||
boolean Sync(uint32_t timeout=ESP_TIMEOUT); |
||||
// Request the wifi status
|
||||
void GetWifiStatus(void); |
||||
|
||||
// Callback for wifi status changes. This callback must be attached before calling Sync
|
||||
FP<void, void*> wifiCb; /**< Pointer to callback function */ |
||||
// Callback to indicate protocol reset, typically due to esp-link resetting. The callback
|
||||
// should call Sync and perform any other callback registration afresh.
|
||||
void (*resetCb)(); /**< Pointer to callback function */ |
||||
|
||||
//private:
|
||||
Stream* _serial; /**< Serial stream for communication with ESP */ |
||||
boolean _debugEn; /**< Flag for debug - True = enabled, False = disabled */ |
||||
uint16_t crc; /**< CRC checksum */ |
||||
ELClientProtocol _proto; /**< Protocol structure */ |
||||
uint8_t _protoBuf[MQTT_MAX_PACKET_SIZE]; /**< Protocol buffer */ |
||||
|
||||
void init(); |
||||
void DBG(const char* info); |
||||
ELClientPacket *protoCompletedCb(void); |
||||
void write(uint8_t data); |
||||
void write(void* data, uint16_t len); |
||||
uint16_t crc16Add(unsigned char b, uint16_t acc); |
||||
uint16_t crc16Data(const unsigned char *data, uint16_t len, uint16_t acc); |
||||
}; |
||||
#endif // _EL_CLIENT_H_
|
||||
@ -0,0 +1,38 @@
@@ -0,0 +1,38 @@
|
||||
/*! \file ELClientCmd.cpp
|
||||
\brief Constructor and functions for ELClientCmd |
||||
\author B. Runnels |
||||
\author T. von Eicken |
||||
\date 2016 |
||||
*/ |
||||
// Copyright (c) 2016 by B. Runnels and T. von Eicken
|
||||
|
||||
#include "ELClientCmd.h" |
||||
|
||||
/*! ELClientCmd(ELClient* elc)
|
||||
@brief Constructor for ELClientCmd |
||||
*/ |
||||
ELClientCmd::ELClientCmd(ELClient* elc) :_elc(elc) {} |
||||
|
||||
/*! GetTime()
|
||||
@brief Get time from ESP |
||||
@details Time from the ESP is unformated value of seconds |
||||
@warning If the ESP cannot connect to the NTP server or the connection NTP server is not setup,
|
||||
then this time is the number of seconds since the last reboot of the ESP |
||||
@return <code>uint32_t</code> |
||||
current time as number of seconds |
||||
- since Thu Jan 1 00:00:58 UTC 1970 if ESP has time from NTP |
||||
- since last reboot of ESP if no NTP time is available |
||||
@par Example |
||||
@code |
||||
uint32_t t = cmd.GetTime(); |
||||
Serial.print("Time: "); Serial.println(t); |
||||
@endcode |
||||
*/ |
||||
uint32_t ELClientCmd::GetTime() { |
||||
_elc->Request(CMD_GET_TIME, 0, 0); |
||||
_elc->Request(); |
||||
|
||||
ELClientPacket *pkt = _elc->WaitReturn(); |
||||
return pkt ? pkt->value : 0; |
||||
} |
||||
|
||||
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
/*! \file ELClientCmd.h
|
||||
\brief Definitions for ELClientCmd |
||||
\note Miscellaneous commands |
||||
*/ |
||||
// Miscellaneous commands
|
||||
|
||||
#ifndef _EL_CLIENT_CMD_H_ |
||||
#define _EL_CLIENT_CMD_H_ |
||||
|
||||
#include <Arduino.h> |
||||
#include "ELClient.h" |
||||
#include "FP.h" |
||||
|
||||
class ELClientCmd { |
||||
public: |
||||
// Constructor
|
||||
ELClientCmd(ELClient* elc); |
||||
// Get the current time in seconds since the epoch, 0 if the time is unknown
|
||||
uint32_t GetTime(); |
||||
|
||||
private: |
||||
ELClient* _elc; /**< ELClient instance */ |
||||
}; |
||||
#endif |
||||
@ -0,0 +1,302 @@
@@ -0,0 +1,302 @@
|
||||
/*! \file ELClientMqtt.cpp
|
||||
\brief Constructor and functions for ELClientMqtt |
||||
\author B. Runnels |
||||
\author T. von Eicken |
||||
\date 2016 |
||||
*/ |
||||
// Copyright (c) 2016 by B. Runnels and T. von Eicken
|
||||
|
||||
#include <Arduino.h> |
||||
#include "ELClientMqtt.h" |
||||
|
||||
// constructor
|
||||
/*! ELClientMqtt(ELClient* elc)
|
||||
@brief Constructor for ELClientMqtt |
||||
@par Example |
||||
@code |
||||
ELClientMqtt(ELClient* elc); |
||||
@endcode |
||||
*/ |
||||
ELClientMqtt::ELClientMqtt(ELClient* elc) :_elc(elc) {} |
||||
|
||||
/*! setup(void)
|
||||
@brief Setup mqtt |
||||
@details Send callback functions for MQTT events to the ESP |
||||
@par Example |
||||
@code |
||||
mqtt.connectedCb.attach(mqttConnected); |
||||
mqtt.disconnectedCb.attach(mqttDisconnected); |
||||
mqtt.publishedCb.attach(mqttPublished); |
||||
mqtt.dataCb.attach(mqttData); |
||||
mqtt.setup(); |
||||
@endcode |
||||
*/ |
||||
void ELClientMqtt::setup(void) { |
||||
//Serial.print(F("ConnectedCB is 0x")); Serial.println((uint32_t)&connectedCb, 16);
|
||||
_elc->Request(CMD_MQTT_SETUP, 0, 4); |
||||
uint32_t cb = (uint32_t)&connectedCb; |
||||
_elc->Request(&cb, 4); |
||||
cb = (uint32_t)&disconnectedCb; |
||||
_elc->Request(&cb, 4); |
||||
cb = (uint32_t)&publishedCb; |
||||
_elc->Request(&cb, 4); |
||||
cb = (uint32_t)&dataCb; |
||||
_elc->Request(&cb, 4); |
||||
_elc->Request(); |
||||
} |
||||
|
||||
// LWT
|
||||
|
||||
/*! lwt(const char* topic, const char* message, uint8_t qos, uint8_t retain)
|
||||
@brief Set MQTT last will. |
||||
@details Sends the "last will" to the ESP. |
||||
@param topic |
||||
Last will topic name |
||||
@param message |
||||
Last will message |
||||
@param qos |
||||
(optional) Requested qos level, default 0 |
||||
@param retain |
||||
(optional) Requested retain level, default 0 |
||||
@warning At the moment only qos level 0 is implemented and supported! |
||||
@par Example |
||||
@code |
||||
Serial.println("ARDUINO: setup mqtt lwt"); |
||||
mqtt.lwt("/lwt", "offline", 0, 0); //or mqtt.lwt("/lwt", "offline");
|
||||
@endcode |
||||
*/ |
||||
void ELClientMqtt::lwt(const char* topic, const char* message, uint8_t qos, uint8_t retain) { |
||||
_elc->Request(CMD_MQTT_LWT, 0, 4); |
||||
_elc->Request(topic, strlen(topic)); |
||||
_elc->Request(message, strlen(message)); |
||||
_elc->Request(&qos, 1); |
||||
_elc->Request(&retain, 1); |
||||
_elc->Request(); |
||||
} |
||||
|
||||
/*! lwt(const __FlashStringHelper* topic, const __FlashStringHelper* message, uint8_t qos, uint8_t retain)
|
||||
@brief Set MQTT last will. |
||||
@details Sends the "last will" to the ESP with the topic and message stored in program memory |
||||
@param topic |
||||
Last will topic name |
||||
@param message |
||||
Last will message |
||||
@param qos |
||||
(optional) Requested qos level, default 0 |
||||
@param retain |
||||
(optional) Requested retain level, default 0 |
||||
@warning At the moment only qos level 0 is implemented and supported! |
||||
@par Example |
||||
@code |
||||
no example code yet |
||||
@endcode |
||||
*/ |
||||
void ELClientMqtt::lwt(const __FlashStringHelper* topic, const __FlashStringHelper* message, |
||||
uint8_t qos, uint8_t retain) |
||||
{ |
||||
_elc->Request(CMD_MQTT_LWT, 0, 4); |
||||
_elc->Request(topic, strlen_P((const char*)topic)); |
||||
_elc->Request(message, strlen_P((const char*)message)); |
||||
_elc->Request(&qos, 1); |
||||
_elc->Request(&retain, 1); |
||||
_elc->Request(); |
||||
} |
||||
|
||||
// SUBSCRIBE
|
||||
|
||||
/*! subscribe(const char* topic, uint8_t qos)
|
||||
@brief Subscribe to MQTT topic |
||||
@details Sends the MQTT subscription request to the ESP |
||||
@param topic |
||||
Topic name |
||||
@param qos |
||||
(optional) Requested qos level, default 0 |
||||
@warning At the moment only qos level 0 is implemented and supported! |
||||
@par Example |
||||
@code |
||||
mqtt.subscribe("/esp-link/1"); |
||||
mqtt.subscribe("/hello/world/#"); |
||||
@endcode |
||||
*/ |
||||
void ELClientMqtt::subscribe(const char* topic, uint8_t qos) { |
||||
_elc->Request(CMD_MQTT_SUBSCRIBE, 0, 2); |
||||
_elc->Request(topic, strlen(topic)); |
||||
_elc->Request(&qos, 1); |
||||
_elc->Request(); |
||||
} |
||||
|
||||
/*! subscribe(const __FlashStringHelper* topic, uint8_t qos)
|
||||
@brief Subscribe to MQTT topic |
||||
@details Sends the MQTT subscription request to the ESP with the topic and message stored in program memory |
||||
@param topic |
||||
Topic name |
||||
@param qos |
||||
(optional) Requested qos level, default 0 |
||||
@warning At the moment only qos level 0 is implemented and supported! |
||||
@par Example |
||||
@code |
||||
no example code yet |
||||
@endcode |
||||
*/ |
||||
void ELClientMqtt::subscribe(const __FlashStringHelper* topic, uint8_t qos) { |
||||
_elc->Request(CMD_MQTT_SUBSCRIBE, 0, 2); |
||||
_elc->Request(topic, strlen_P((const char*)topic)); |
||||
_elc->Request(&qos, 1); |
||||
_elc->Request(); |
||||
} |
||||
|
||||
// PUBLISH
|
||||
|
||||
/*! publish(const char* topic, const uint8_t* data, const uint16_t len, uint8_t qos, uint8_t retain)
|
||||
@brief Subscribe to MQTT topic |
||||
@details Sends the MQTT subscription request to the ESP |
||||
@param topic |
||||
Topic name |
||||
@param data |
||||
Pointer to data buffer |
||||
@param len |
||||
Size of data buffer |
||||
@param qos |
||||
(optional) Requested qos level, default 0 |
||||
@param retain |
||||
(optional) Requested retain level, default 0 |
||||
@warning At the moment only qos level 0 is implemented and supported! |
||||
@par Example |
||||
@code |
||||
char buf[12]; |
||||
itoa(count++, buf, 10); |
||||
mqtt.publish("/esp-link/1", buf); |
||||
itoa(count+99, buf, 10); |
||||
mqtt.publish("/hello/world/arduino", buf, 12); |
||||
@endcode |
||||
*/ |
||||
void ELClientMqtt::publish(const char* topic, const uint8_t* data, const uint16_t len, |
||||
uint8_t qos, uint8_t retain) |
||||
{ |
||||
_elc->Request(CMD_MQTT_PUBLISH, 0, 5); |
||||
_elc->Request(topic, strlen(topic)); |
||||
_elc->Request(data, len); |
||||
_elc->Request(&len, 2); |
||||
_elc->Request(&qos, 1); |
||||
_elc->Request(&retain, 1); |
||||
_elc->Request(); |
||||
} |
||||
|
||||
/*! publish(const char* topic, const char* data, uint8_t qos, uint8_t retain)
|
||||
@brief Subscribe to MQTT topic |
||||
@details Sends the MQTT subscription request to the ESP. Data must be null-terminated |
||||
@param topic |
||||
Topic name |
||||
@param data |
||||
Pointer to data buffer |
||||
@param qos |
||||
(optional) Requested qos level, default 0 |
||||
@param retain |
||||
(optional) Requested retain level, default 0 |
||||
@warning At the moment only qos level 0 is implemented and supported! |
||||
@par Example |
||||
@code |
||||
char buf[12]; |
||||
itoa(count++, buf, 10); |
||||
mqtt.publish("/esp-link/1", buf); |
||||
itoa(count+99, buf, 10); |
||||
mqtt.publish("/hello/world/arduino", buf); |
||||
@endcode |
||||
*/ |
||||
void ELClientMqtt::publish(const char* topic, const char* data, uint8_t qos, uint8_t retain) |
||||
{ |
||||
publish(topic, (uint8_t*)data, strlen(data), qos, retain); |
||||
} |
||||
|
||||
/*! publish(const __FlashStringHelper* topic, const __FlashStringHelper* data, const uint16_t len, uint8_t qos, uint8_t retain)
|
||||
@brief Subscribe to MQTT topic |
||||
@details Sends the MQTT subscription request to the ESP with the topic and data stored in program memory |
||||
@param topic |
||||
Topic name |
||||
@param data |
||||
Pointer to data buffer |
||||
@param len |
||||
Size of data buffer |
||||
@param qos |
||||
(optional) Requested qos level, default 0 |
||||
@param retain |
||||
(optional) Requested retain level, default 0 |
||||
@warning At the moment only qos level 0 is implemented and supported! |
||||
@par Example |
||||
@code |
||||
no example code yet |
||||
@endcode |
||||
*/ |
||||
void ELClientMqtt::publish(const __FlashStringHelper* topic, const __FlashStringHelper* data, |
||||
const uint16_t len, uint8_t qos, uint8_t retain) |
||||
{ |
||||
_elc->Request(CMD_MQTT_PUBLISH, 0, 5); |
||||
_elc->Request(topic, strlen_P((const char*)topic)); |
||||
_elc->Request(data, len); |
||||
_elc->Request(&len, 2); |
||||
_elc->Request(&qos, 1); |
||||
_elc->Request(&retain, 1); |
||||
_elc->Request(); |
||||
} |
||||
|
||||
/*! ELClientMqtt::publish(const char* topic, const __FlashStringHelper* data, const uint16_t len, uint8_t qos, uint8_t retain)
|
||||
@brief Subscribe to MQTT topic |
||||
@details Sends the MQTT subscription request to the ESP with the data stored in program memory |
||||
@param topic |
||||
Topic name |
||||
@param data |
||||
Pointer to data buffer |
||||
@param len |
||||
Size of data buffer |
||||
@param qos |
||||
(optional) Requested qos level, default 0 |
||||
@param retain |
||||
(optional) Requested retain level, default 0 |
||||
@warning At the moment only qos level 0 is implemented and supported! |
||||
@par Example |
||||
@code |
||||
no example code yet |
||||
@endcode |
||||
*/ |
||||
void ELClientMqtt::publish(const char* topic, const __FlashStringHelper* data, |
||||
const uint16_t len, uint8_t qos, uint8_t retain) |
||||
{ |
||||
_elc->Request(CMD_MQTT_PUBLISH, 0, 5); |
||||
_elc->Request(topic, strlen(topic)); |
||||
_elc->Request(data, len); |
||||
_elc->Request(&len, 2); |
||||
_elc->Request(&qos, 1); |
||||
_elc->Request(&retain, 1); |
||||
_elc->Request(); |
||||
} |
||||
|
||||
/*! publish(const __FlashStringHelper* topic, const uint8_t* data, const uint16_t len, uint8_t qos, uint8_t retain)
|
||||
@brief Subscribe to MQTT topic |
||||
@details Sends the MQTT subscription request to the ESP with the topic stored in program memory |
||||
@param topic |
||||
Topic name |
||||
@param data |
||||
Pointer to data buffer |
||||
@param len |
||||
Size of data buffer |
||||
@param qos |
||||
(optional) Requested qos level, default 0 |
||||
@param retain |
||||
(optional) Requested retain level, default 0 |
||||
@warning At the moment only qos level 0 is implemented and supported! |
||||
@par Example |
||||
@code |
||||
no example code yet |
||||
@endcode |
||||
*/ |
||||
void ELClientMqtt::publish(const __FlashStringHelper* topic, const uint8_t* data, |
||||
const uint16_t len, uint8_t qos, uint8_t retain) |
||||
{ |
||||
_elc->Request(CMD_MQTT_PUBLISH, 0, 5); |
||||
_elc->Request(topic, strlen_P((const char*)topic)); |
||||
_elc->Request(data, len); |
||||
_elc->Request(&len, 2); |
||||
_elc->Request(&qos, 1); |
||||
_elc->Request(&retain, 1); |
||||
_elc->Request(); |
||||
} |
||||
@ -0,0 +1,65 @@
@@ -0,0 +1,65 @@
|
||||
/*! \file ELClientMqtt.h
|
||||
\brief Definitions for ELClientMqtt |
||||
\author B. Runnels |
||||
\author T. von Eicken |
||||
\date 2016 |
||||
*/ |
||||
// Copyright (c) 2016 by B. Runnels and T. von Eicken
|
||||
|
||||
#ifndef _EL_CLIENT_MQTT_H_ |
||||
#define _EL_CLIENT_MQTT_H_ |
||||
|
||||
#include <stdint.h> |
||||
#include "FP.h" |
||||
#include "ELClient.h" |
||||
|
||||
// Class to send and receive MQTT messages. This class should be used with a singleton object
|
||||
// because the esp-link implementation currently only supports a single MQTT server, so there is
|
||||
// no value in instantiating multiple ELClientMqtt objects (although it's possible).
|
||||
// All the server settings are made in esp-link and esp-link takes care to automatically
|
||||
// reconnect and retry if the connection is lost. This means that on the arduino side the only
|
||||
// code that is necessary is to send and receive messsages.
|
||||
class ELClientMqtt { |
||||
public: |
||||
// Initialize with an ELClient object
|
||||
ELClientMqtt(ELClient* elc); |
||||
|
||||
// setup transmits the set of callbacks to esp-link. It assumes that the desired callbacks
|
||||
// have previously been attached using something like mqtt->connectedCb.attach(myCallbackFun).
|
||||
// After setup is called either the connectedCb or the disconnectedCb is invoked to provide
|
||||
// information about the initial connection status.
|
||||
void setup(void); |
||||
|
||||
// callbacks that can be attached prior to calling setup
|
||||
FP<void, void*> connectedCb; /**< callback with no args when MQTT is connected */ |
||||
FP<void, void*> disconnectedCb; /**< callback with no args when MQTT is disconnected */ |
||||
FP<void, void*> publishedCb; /**< not yet implemented */ |
||||
FP<void, void*> dataCb; /**< callback when a message is received, called with two arguments: the topic and the message (max ~110 bytes for both) */ |
||||
|
||||
// subscribe to a topic, the default qos is 0. When messages are recevied for the topic the
|
||||
// data callback is invoked.
|
||||
void subscribe(const char* topic, uint8_t qos=0); |
||||
void subscribe(const __FlashStringHelper* topic, uint8_t qos=0); |
||||
|
||||
// publish a message to a topic
|
||||
void publish(const char* topic, const uint8_t* data, |
||||
const uint16_t len, uint8_t qos=0, uint8_t retain=0); |
||||
void publish(const char* topic, const char* data, |
||||
uint8_t qos=0, uint8_t retain=0); |
||||
void publish(const __FlashStringHelper* topic, const __FlashStringHelper* data, |
||||
const uint16_t len, uint8_t qos=0, uint8_t retain=0); |
||||
void publish(const char* topic, const __FlashStringHelper* data, |
||||
const uint16_t len, uint8_t qos=0, uint8_t retain=0); |
||||
void publish(const __FlashStringHelper* topic, const uint8_t* data, |
||||
const uint16_t len, uint8_t qos=0, uint8_t retain=0); |
||||
|
||||
// set a last-will topic & message
|
||||
void lwt(const char* topic, const char* message, uint8_t qos=0, uint8_t retain=0); |
||||
void lwt(const __FlashStringHelper* topic, const __FlashStringHelper* message, |
||||
uint8_t qos=0, uint8_t retain=0); |
||||
|
||||
private: |
||||
ELClient* _elc; /**< ELClient instance */ |
||||
}; |
||||
|
||||
#endif // _EL_CLIENT_MQTT_H_
|
||||
@ -0,0 +1,157 @@
@@ -0,0 +1,157 @@
|
||||
/*! \file ELClientResponse.cpp
|
||||
\brief Constructor and functions for ELClientResponse |
||||
*/ |
||||
#include "ELClientResponse.h" |
||||
|
||||
/*! ELClientResponse(ELClientPacket* packet)
|
||||
@brief Constructor for ELClientResponse with ELClientPacket packet |
||||
@param packet |
||||
Pointer to packet for response |
||||
@par Example |
||||
@code |
||||
no example code yet |
||||
@endcode |
||||
*/ |
||||
ELClientResponse::ELClientResponse(ELClientPacket* packet) { |
||||
_cmd = packet; |
||||
_arg_ptr = _cmd->args; |
||||
_arg_num = 0; |
||||
} |
||||
|
||||
/*! ELClientResponse(void* packet)
|
||||
@brief Constructor for ELClientResponse with void packet |
||||
@param packet |
||||
Pointer to packet for response |
||||
@par Example |
||||
@code |
||||
no example code yet |
||||
@endcode |
||||
*/ |
||||
ELClientResponse::ELClientResponse(void* packet) { |
||||
_cmd = (ELClientPacket *)packet; |
||||
_arg_ptr = _cmd->args; |
||||
_arg_num = 0; |
||||
} |
||||
|
||||
/*! popArgPtr(void **data)
|
||||
@brief Extract pointer to an argument from the response packet |
||||
@param data |
||||
Pointer to buffer for the argument pointer |
||||
@return <code>int16_t</code> |
||||
Size of argument |
||||
@par Example |
||||
@code |
||||
no example code yet |
||||
@endcode |
||||
*/ |
||||
int16_t ELClientResponse::popArgPtr(void **data) { |
||||
if (_arg_num >= _cmd->argc) return -1; |
||||
|
||||
uint16_t len = *(uint16_t*)_arg_ptr; |
||||
uint16_t pad = (4-((len+2)&3))&3; // pad to next multiple of 4, including length
|
||||
_arg_ptr += 2; |
||||
_arg_num++; |
||||
|
||||
*data = _arg_ptr; |
||||
_arg_ptr += len + pad; |
||||
return len; |
||||
} |
||||
|
||||
/*! popArg(void* d, uint16_t maxLen)
|
||||
@brief Extract an argument from the response packet |
||||
@param d |
||||
Pointer to buffer for the argument |
||||
@param maxLen |
||||
Size of the buffer for the argument |
||||
@return <code>int16_t</code> |
||||
Size of argument |
||||
@par Example |
||||
@code |
||||
no example code yet |
||||
@endcode |
||||
*/ |
||||
int16_t ELClientResponse::popArg(void* d, uint16_t maxLen) { |
||||
if (_arg_num >= _cmd->argc) return -1; |
||||
|
||||
uint16_t len = *(uint16_t*)_arg_ptr; |
||||
uint16_t pad = (4-((len+2)&3))&3; // pad to next multiple of 4, including length
|
||||
_arg_ptr += 2; |
||||
_arg_num++; |
||||
|
||||
uint8_t *data = (uint8_t *)d; |
||||
uint16_t l = len > maxLen ? maxLen : len; |
||||
uint8_t *p = _arg_ptr; |
||||
while (l--) |
||||
*data++ = *p++; |
||||
|
||||
_arg_ptr += len + pad; |
||||
return len; |
||||
} |
||||
|
||||
/*! popChar(char* buffer)
|
||||
@brief Extract a character from the response packet |
||||
@param buffer |
||||
Pointer to buffer for the character |
||||
@par Example |
||||
@code |
||||
no example code yet |
||||
@endcode |
||||
*/ |
||||
void ELClientResponse::popChar(char* buffer) { |
||||
uint16_t len = *(uint16_t*)_arg_ptr; |
||||
uint16_t pad = (4-((len+2)&3))&3; // pad to next multiple of 4, including length
|
||||
_arg_ptr += 2; |
||||
_arg_num++; |
||||
|
||||
uint8_t i; |
||||
for (i = 0; i < len; i++) { |
||||
buffer[i] = (char)*_arg_ptr++; |
||||
} |
||||
buffer[i] = '\0'; |
||||
|
||||
_arg_ptr += pad; |
||||
} |
||||
|
||||
/*! popString()
|
||||
@brief Extract a string from the response packet |
||||
@return <code>String</code> |
||||
String extracted from the response packet |
||||
@par Example |
||||
@code |
||||
no example code yet |
||||
@endcode |
||||
*/ |
||||
String ELClientResponse::popString() { |
||||
String ret; |
||||
uint16_t len = *(uint16_t*)_arg_ptr; |
||||
uint16_t pad = (4-((len+2)&3))&3; // pad to next multiple of 4, including length
|
||||
_arg_ptr += 2; |
||||
_arg_num++; |
||||
|
||||
while (len--) |
||||
ret += (char)*_arg_ptr++; |
||||
|
||||
_arg_ptr += pad; |
||||
return ret; |
||||
} |
||||
|
||||
/*! popString(String* data)
|
||||
@brief Extract the pointer to a string from the response packet |
||||
@param data |
||||
Pointer to be set to the string in the response packet |
||||
@par Example |
||||
@code |
||||
no example code yet |
||||
@endcode |
||||
*/ |
||||
void ELClientResponse::popString(String* data) { |
||||
uint16_t len = *(uint16_t*)_arg_ptr; |
||||
uint16_t pad = (4-((len+2)&3))&3; // pad to next multiple of 4, including length
|
||||
_arg_ptr += 2; |
||||
_arg_num++; |
||||
|
||||
while (len--) |
||||
data->concat((char)*_arg_ptr++); |
||||
|
||||
_arg_ptr += pad; |
||||
} |
||||
@ -0,0 +1,58 @@
@@ -0,0 +1,58 @@
|
||||
/*! \file ELClientResponse.h
|
||||
\brief Definitions for ELClientResponse |
||||
*/ |
||||
#ifndef _EL_CLIENT_RESPONSE_H_ |
||||
#define _EL_CLIENT_RESPONSE_H_ |
||||
|
||||
#if _MSC_VER |
||||
#define PACKED |
||||
#else |
||||
#define PACKED __attribute__ ((__packed__)) |
||||
#endif |
||||
|
||||
#include <Arduino.h> |
||||
|
||||
#define VARIABLE_ARG_NUM 255 |
||||
|
||||
typedef struct PACKED { |
||||
uint16_t cmd; /**< Command to execute */ |
||||
uint16_t argc; /**< Number of arguments */ |
||||
uint32_t value; /**< Callback to invoke, NULL if none; or response value */ |
||||
uint8_t args[0]; /**< Arguments */ |
||||
} ELClientPacket; /**< Packet structure */ |
||||
|
||||
// ELClientResponse is a parser for responses. The constructor initializes the parser based on
|
||||
// a packet and the various pop functions consume one response argument at a time.
|
||||
class ELClientResponse { |
||||
public: |
||||
// Create a response from a packet, this is done internally in ELClient
|
||||
ELClientResponse(ELClientPacket* packet); |
||||
ELClientResponse(void *packet); |
||||
|
||||
// Accessors to the response fields
|
||||
uint16_t argc() { return _cmd->argc; } /**< Get number of arguments */ |
||||
uint16_t cmd() { return _cmd->cmd; } /**< Get command */ |
||||
uint32_t value() { return _cmd->value; } /**< Get returned value */ |
||||
|
||||
// Return the length of the next argument
|
||||
uint16_t argLen() { return *(uint16_t*)_arg_ptr; } /**< Get length of argument */ |
||||
// Pop one argument from the response, returns the actual length. Returns -1 if there is
|
||||
// no arg left.
|
||||
int16_t popArg(void* data, uint16_t maxLen); |
||||
// Pop one argument as a poiner from the response, returns the actual length.
|
||||
int16_t popArgPtr(void **data); |
||||
// Pop one argument into a string buffer and append a null character. The buffer needs to
|
||||
// be large enough (argLen()+1)
|
||||
void popChar(char* buffer); |
||||
// Pop one argument into a String buffer
|
||||
String popString(); |
||||
// Pop one argument into a String buffer
|
||||
void popString(String* data); |
||||
|
||||
private: |
||||
uint16_t _arg_num; /**< Argument number */ |
||||
uint8_t* _arg_ptr; /**< Pointer to argument */ |
||||
ELClientPacket* _cmd; /**< Pointer to packet */ |
||||
}; |
||||
|
||||
#endif // _EL_CLIENT_RESPONSE_H_
|
||||
@ -0,0 +1,381 @@
@@ -0,0 +1,381 @@
|
||||
/*! \file ELClientRest.cpp
|
||||
\brief Constructor and functions for ELClientRest |
||||
\author B. Runnels |
||||
\author T. von Eicken |
||||
\date 2016 |
||||
*/ |
||||
// Copyright (c) 2016 by B. Runnels and T. von Eicken
|
||||
|
||||
#include "ELClientRest.h" |
||||
|
||||
typedef enum { |
||||
HEADER_GENERIC = 0, /**< Header is generic */ |
||||
HEADER_CONTENT_TYPE, /**< Header is content type */ |
||||
HEADER_USER_AGENT /**< Header is user agent */ |
||||
} HEADER_TYPE; /**< Enum of header types */ |
||||
|
||||
/*! ELClientRest(ELClient *e)
|
||||
@brief Constructor for ELClientRest |
||||
@param e |
||||
Pointer to ELClient structure |
||||
@par Example |
||||
@code |
||||
ELClientRest(ELClient *e); |
||||
@endcode |
||||
*/ |
||||
ELClientRest::ELClientRest(ELClient *e) |
||||
{ |
||||
_elc = e; |
||||
remote_instance = -1; |
||||
} |
||||
|
||||
/*! restCallback(void *res)
|
||||
@brief Function called by esp-link when data is sent, received or an error occured. |
||||
@details The function is called by esp-link when data is sent or received from the remote server. |
||||
@note Internal library function |
||||
@param res |
||||
Pointer to ELClientResponse structure |
||||
@warning The content of the response structure is overwritten when the next package arrives! |
||||
*/ |
||||
void ELClientRest::restCallback(void *res) |
||||
{ |
||||
if (!res) return; |
||||
|
||||
ELClientResponse *resp = (ELClientResponse *)res; |
||||
|
||||
resp->popArg(&_status, sizeof(_status)); |
||||
if (_elc->_debugEn) { |
||||
_elc->_debug->print("REST code "); |
||||
_elc->_debug->println(_status); |
||||
} |
||||
|
||||
_len = resp->popArgPtr(&_data); |
||||
} |
||||
|
||||
/*! begin(const char* host, uint16_t port, boolean security)
|
||||
@brief Initialize communication to a REST server |
||||
@details Initialize communication to a remote server, |
||||
this communicates with esp-link but does not open a connection to the remote server. |
||||
@param host |
||||
Host to be connected. Can be a URL or an IP address in the format of xxx.xxx.xxx.xxx . |
||||
@param port |
||||
Port to be used to send/receive packets. Port MUST NOT be 80, 23 or 2323, as these ports are already used by EL-CLIENT on the ESP8266 |
||||
@param security |
||||
Flag if secure connection should be established |
||||
@warning Port MUST NOT be 80, 23 or 2323, as these ports are already used by EL-CLIENT on the ESP8266. |
||||
Max 4 connections are supported! |
||||
@par Example |
||||
@code |
||||
int err = rest.begin("www.timeapi.org"); |
||||
if (err != 0)
|
||||
{ |
||||
Serial.print("REST begin failed: "); |
||||
Serial.println(err); |
||||
while(1) ; |
||||
} |
||||
@endcode |
||||
*/ |
||||
int ELClientRest::begin(const char* host, uint16_t port, boolean security) |
||||
{ |
||||
uint8_t sec = !!security; |
||||
restCb.attach(this, &ELClientRest::restCallback); |
||||
|
||||
_elc->Request(CMD_REST_SETUP, (uint32_t)&restCb, 3); |
||||
_elc->Request(host, strlen(host)); |
||||
_elc->Request(&port, 2); |
||||
_elc->Request(&sec, 1); |
||||
_elc->Request(); |
||||
|
||||
ELClientPacket *pkt = _elc->WaitReturn(); |
||||
if (pkt && (int32_t)pkt->value >= 0) { |
||||
remote_instance = pkt->value; |
||||
return 0; |
||||
} |
||||
return (int)pkt->value; |
||||
} |
||||
|
||||
/*! request(const char* path, const char* method, const char* data, int len)
|
||||
@brief Send request to REST server. |
||||
@param path |
||||
Path that extends the URL of the REST request (command or data for the REST server) |
||||
@param method |
||||
REST method, allowed values are "GET", "POST", "PUT" or "DELETE" |
||||
@param data |
||||
Pointer to data buffer |
||||
@param len |
||||
Size of data buffer |
||||
@par Example |
||||
@code |
||||
no example code yet |
||||
@endcode |
||||
*/ |
||||
void ELClientRest::request(const char* path, const char* method, const char* data, int len) |
||||
{ |
||||
_status = 0; |
||||
if (remote_instance < 0) return; |
||||
if (data != 0 && len > 0) _elc->Request(CMD_REST_REQUEST, remote_instance, 3); |
||||
else _elc->Request(CMD_REST_REQUEST, remote_instance, 2); |
||||
_elc->Request(method, strlen(method)); |
||||
_elc->Request(path, strlen(path)); |
||||
if (data != NULL && len > 0) { |
||||
_elc->Request(data, len); |
||||
} |
||||
|
||||
_elc->Request(); |
||||
} |
||||
|
||||
/*! request(const char* path, const char* method, const char* data)
|
||||
@brief Send request to REST server. |
||||
@details The data must be null-terminated. |
||||
@param path |
||||
Path that extends the URL of the REST request (command or data for the REST server) |
||||
@param method |
||||
REST method, allowed values are "GET", "POST", "PUT" or "DELETE" |
||||
@param data |
||||
Pointer to data buffer |
||||
@par Example |
||||
@code |
||||
no example code yet |
||||
@endcode |
||||
*/ |
||||
void ELClientRest::request(const char* path, const char* method, const char* data) |
||||
{ |
||||
request(path, method, data, strlen(data)); |
||||
} |
||||
|
||||
/*! get(const char* path, const char* data)
|
||||
@brief Send GET request to REST server |
||||
@warning The received data might not be null-terminated. |
||||
@param path |
||||
Path that extends the URL of the REST request (command or data for the REST server) |
||||
@param data |
||||
Pointer to data buffer
|
||||
@par Example |
||||
@code |
||||
// Request /utc/now from the previously set-up server
|
||||
rest.get("/utc/now"); |
||||
@endcode |
||||
*/ |
||||
void ELClientRest::get(const char* path, const char* data) { request(path, "GET", data); } |
||||
|
||||
/*! post(const char* path, const char* data)
|
||||
@brief Send POST request to REST server |
||||
@warning The received data must be null-terminated. |
||||
@param path |
||||
Path that extends the URL of the REST request (command or data for the REST server) |
||||
@param data |
||||
Pointer to data buffer
|
||||
@par Example |
||||
@code |
||||
// Generate a fake value starting from 100 going up to 300
|
||||
solarValue = solarValue + 0.5; |
||||
if (solarValue == 300)
|
||||
{ |
||||
solarValue = 100; |
||||
} |
||||
String solarValString = String(solarValue); |
||||
const char *solarValChar = solarValString.c_str(); |
||||
// Reserve a buffer for sending the data
|
||||
char path_data[BUFLEN]; |
||||
// Copy the path and API key into the buffer
|
||||
sprintf(path_data, "%s", "/update?api_key="); |
||||
sprintf(path_data + strlen(path_data), "%s", api_key); |
||||
// Copy the field number and value into the buffer
|
||||
// If you have more than one field to update,
|
||||
// repeat and change field1 to field2, field3, ...
|
||||
sprintf(path_data + strlen(path_data), "%s", "&field1="); |
||||
sprintf(path_data + strlen(path_data), "%s", solarValChar); |
||||
// Send PUT request to thingspeak.com
|
||||
rest.post(path_data,"");
|
||||
@endcode |
||||
*/ |
||||
void ELClientRest::post(const char* path, const char* data) { request(path, "POST", data); } |
||||
|
||||
/*! put(const char* path, const char* data)
|
||||
@brief Send PUT request to REST server |
||||
@warning The received data must be null-terminated. |
||||
@param path |
||||
Path that extends the URL of the REST request (command or data for the REST server) |
||||
@param data |
||||
Pointer to data buffer
|
||||
@par Example |
||||
@code |
||||
no example code yet |
||||
@endcode |
||||
*/ |
||||
void ELClientRest::put(const char* path, const char* data) { request(path, "PUT", data); } |
||||
|
||||
/*! del(const char* path)
|
||||
@brief Send DELETE request to REST server |
||||
@param path |
||||
Path that extends the URL of the REST request (command or data for the REST server) |
||||
@par Example |
||||
@code |
||||
no example code yet |
||||
@endcode |
||||
*/ |
||||
void ELClientRest::del(const char* path) { request(path, "DELETE", 0); } |
||||
|
||||
/*! setHeader(const char* value)
|
||||
@brief Set generic header content |
||||
@details If no generic header is set, it defaults to an empty string |
||||
@param value |
||||
Header content |
||||
@par Example |
||||
@code |
||||
no example code yet |
||||
@endcode |
||||
*/ |
||||
void ELClientRest::setHeader(const char* value) |
||||
{ |
||||
uint8_t header_index = HEADER_GENERIC; |
||||
_elc->Request(CMD_REST_SETHEADER, remote_instance, 2); |
||||
_elc->Request(&header_index, 1); |
||||
_elc->Request(value, strlen(value)); |
||||
_elc->Request(); |
||||
} |
||||
|
||||
/*! setContentType(const char* value)
|
||||
@brief Set content type of header |
||||
@details If no content type is set, it defaults to "x-www-form-urlencoded" |
||||
@param value |
||||
Content type |
||||
@par Example |
||||
@code |
||||
no example code yet |
||||
@endcode |
||||
*/ |
||||
void ELClientRest::setContentType(const char* value) |
||||
{ |
||||
uint8_t header_index = HEADER_CONTENT_TYPE; |
||||
_elc->Request(CMD_REST_SETHEADER, remote_instance, 2); |
||||
_elc->Request(&header_index, 1); |
||||
_elc->Request(value, strlen(value)); |
||||
_elc->Request(); |
||||
} |
||||
|
||||
/*! setUserAgent(const char* value)
|
||||
@brief Set user agent of header |
||||
@details If no user agent is set, it defaults to "esp-link" |
||||
@param value |
||||
User agent |
||||
@par Example |
||||
@code |
||||
no example code yet |
||||
@endcode |
||||
*/ |
||||
void ELClientRest::setUserAgent(const char* value) |
||||
{ |
||||
uint8_t header_index = HEADER_USER_AGENT; |
||||
_elc->Request(CMD_REST_SETHEADER, remote_instance, 2); |
||||
_elc->Request(&header_index, 1); |
||||
_elc->Request(value, strlen(value)); |
||||
_elc->Request(); |
||||
} |
||||
|
||||
/*! getResponse(char* data, uint16_t maxLen)
|
||||
@brief Retrieve response. |
||||
@details Checks if a response from the remote server was received, |
||||
returns the HTTP status code or 0 if no response (may need to wait longer) |
||||
@param data |
||||
Pointer to buffer for received packet |
||||
@param maxLen |
||||
Size of buffer for received packet. If the received packet is larger than the buffer, the received packet will be truncated. |
||||
@return <code>uint16_t</code> |
||||
Size of received packet or number of sent bytes or 0 if no response |
||||
@par Example |
||||
@code |
||||
#define BUFLEN 266 |
||||
void loop() |
||||
{ |
||||
// process any callbacks coming from esp_link
|
||||
esp.Process(); |
||||
void loop() |
||||
{ |
||||
// process any callbacks coming from esp_link
|
||||
esp.Process(); |
||||
// if we're connected make an HTTP request
|
||||
if(wifiConnected) |
||||
{ |
||||
// Request /utc/now from the previously set-up server
|
||||
rest.get("/utc/now"); |
||||
char response[BUFLEN]; |
||||
memset(response, 0, BUFLEN); |
||||
uint16_t code = rest.waitResponse(response, BUFLEN); |
||||
if(code == HTTP_STATUS_OK) |
||||
{ |
||||
Serial.println("ARDUINO: GET successful:"); |
||||
Serial.println(response); |
||||
} |
||||
else |
||||
{ |
||||
Serial.print("ARDUINO: GET failed: "); |
||||
Serial.println(code); |
||||
} |
||||
delay(1000); |
||||
} |
||||
} |
||||
} |
||||
@endcode |
||||
*/ |
||||
uint16_t ELClientRest::getResponse(char* data, uint16_t maxLen) |
||||
{ |
||||
if (_status == 0) return 0; |
||||
memcpy(data, _data, _len>maxLen?maxLen:_len); |
||||
int16_t s = _status; |
||||
_status = 0; |
||||
return s; |
||||
} |
||||
|
||||
/*! waitResponse(char* data, uint16_t maxLen, uint32_t timeout)
|
||||
@brief Wait for the response |
||||
@details Wait for the response from the remote server for <code>time_out</code>, |
||||
returns the HTTP status code, 0 if no response (may need to wait longer) |
||||
@warning Blocks the Arduino code for 5 seconds! not recommended to use. |
||||
Received packet is NOT null-terminated |
||||
@param data |
||||
Pointer to buffer for received packet |
||||
@param maxLen |
||||
Size of buffer for received packet. If the received packet is larger than the buffer, the received packet will be truncated. |
||||
@param timeout |
||||
(optional) Timout in milli seconds to wait for a response, defaults to 5000ms |
||||
@return <code>uint16_t</code> |
||||
Size of received packet or number of sent bytes or 0 if no response |
||||
@par Example |
||||
@code |
||||
#define BUFLEN 266 |
||||
void loop()
|
||||
{ |
||||
// process any callbacks coming from esp_link
|
||||
esp.Process(); |
||||
// if we're connected make an HTTP request
|
||||
if(wifiConnected)
|
||||
{ |
||||
// Request /utc/now from the previously set-up server
|
||||
rest.get("/utc/now"); |
||||
char response[BUFLEN]; |
||||
memset(response, 0, BUFLEN); |
||||
uint16_t code = rest.waitResponse(response, BUFLEN); |
||||
if(code == HTTP_STATUS_OK) |
||||
{ |
||||
Serial.println("ARDUINO: GET successful:"); |
||||
Serial.println(response); |
||||
} |
||||
else |
||||
{ |
||||
Serial.print("ARDUINO: GET failed: "); |
||||
Serial.println(code); |
||||
} |
||||
delay(1000); |
||||
} |
||||
} |
||||
@endcode |
||||
*/ |
||||
uint16_t ELClientRest::waitResponse(char* data, uint16_t maxLen, uint32_t timeout) |
||||
{ |
||||
uint32_t wait = millis(); |
||||
while (_status == 0 && (millis() - wait < timeout)) { |
||||
_elc->Process(); |
||||
} |
||||
return getResponse(data, maxLen); |
||||
} |
||||
@ -0,0 +1,97 @@
@@ -0,0 +1,97 @@
|
||||
/*! \file ELClientRest.h
|
||||
\brief Definitions for ELClientRes |
||||
\author B. Runnels |
||||
\author T. von Eicken |
||||
\date 2016 |
||||
*/ |
||||
// Copyright (c) 2016 by B. Runnels and T. von Eicken
|
||||
|
||||
#ifndef _EL_CLIENT_REST_H_ |
||||
#define _EL_CLIENT_REST_H_ |
||||
|
||||
#include <Arduino.h> |
||||
#include "FP.h" |
||||
#include "ELClient.h" |
||||
|
||||
// Default timeout for REST requests when waiting for a response
|
||||
#define DEFAULT_REST_TIMEOUT 5000 /**< Default timeout for REST requests when waiting for a response */ |
||||
|
||||
typedef enum { |
||||
HTTP_STATUS_OK = 200 /**< HTTP status OK response. */ |
||||
} HTTP_STATUS; |
||||
|
||||
// The ELClientRest class makes simple REST requests to a remote server. Each instance
|
||||
// is used to communicate with one server and multiple instances can be created to make
|
||||
// requests to multiple servers.
|
||||
// The ELClientRest class does not support concurrent requests to the same server because
|
||||
// only a single response can be recevied at a time and the responses of the two requests
|
||||
// may arrive out of order.
|
||||
// A major limitation of the REST class is that it does not store the response body. The
|
||||
// response status is saved in the class instance, so after a request completes and before
|
||||
// the next request is made a call to getResponse will return the status. However, only a pointer
|
||||
// to the response body is saved, which means that if any other message arrives and is
|
||||
// processed then the response body is overwritten by it. What this means is that if you
|
||||
// need the response body you best use waitResponse or ensure that any call to ELClient::process
|
||||
// is followed by a call to getResponse. Ideally someone improves this class to take a callback
|
||||
// into the user's sketch?
|
||||
// Another limitation is that the response body is 100 chars long at most, this is due to the
|
||||
// limitation of the SLIP protocol buffer available.
|
||||
class ELClientRest { |
||||
public: |
||||
ELClientRest(ELClient *e); |
||||
|
||||
// Initialize communication to a remote server, this communicates with esp-link but does not
|
||||
// open a connection to the remote server. Host may be a hostname or an IP address,
|
||||
// security causes HTTPS to be used (not yet supported). Returns 0 if the set-up is
|
||||
// successful, returns a negative error code if it failed.
|
||||
int begin(const char* host, uint16_t port=80, boolean security=false); |
||||
|
||||
// Make a request to the remote server. The data must be null-terminated
|
||||
void request(const char* path, const char* method, const char* data=NULL); |
||||
|
||||
// Make a request to the remote server.
|
||||
void request(const char* path, const char* method, const char* data, int len); |
||||
|
||||
// Make a GET request to the remote server with NULL-terminated data
|
||||
void get(const char* path, const char* data=NULL); |
||||
|
||||
// Make a POST request to the remote server with NULL-terminated data
|
||||
void post(const char* path, const char* data); |
||||
|
||||
// Make a PUT request to the remote server with NULL-terminated data
|
||||
void put(const char* path, const char* data); |
||||
|
||||
// Make a DELETE request to the remote server
|
||||
void del(const char* path); |
||||
|
||||
// Retrieve the response from the remote server, returns the HTTP status code, 0 if no
|
||||
// response (may need to wait longer)
|
||||
uint16_t getResponse(char* data, uint16_t maxLen); |
||||
|
||||
// Wait for the response from the remote server, returns the HTTP status code, 0 if no
|
||||
// response (timeout occurred). This is not recommended except for quick demos, use
|
||||
// getResponse periodically instead.
|
||||
uint16_t waitResponse(char* data, uint16_t maxLen, uint32_t timeout=DEFAULT_REST_TIMEOUT); |
||||
|
||||
// Set the user-agent for all subsequent requests
|
||||
void setUserAgent(const char* value); |
||||
|
||||
// Set the Content-Type Header for all subsequent requests
|
||||
void setContentType(const char* value); |
||||
|
||||
// Set a custom header for all subsequent requests
|
||||
void setHeader(const char* value); |
||||
|
||||
private: |
||||
int32_t remote_instance; /**< Connection number, value can be 0 to 3 */ |
||||
ELClient *_elc; /**< ELClient instance */ |
||||
void restCallback(void* resp); |
||||
FP<void, void*> restCb; /**< Pointer to external callback function */ |
||||
|
||||
int16_t _status; /**< Connection status */ |
||||
uint16_t _len; /**< Number of sent/received bytes */ |
||||
void *_data; /**< Buffer for received data */ |
||||
|
||||
|
||||
}; |
||||
#endif // _EL_CLIENT_REST_H_
|
||||
@ -0,0 +1,318 @@
@@ -0,0 +1,318 @@
|
||||
/*! \file ELClientSocket.cpp
|
||||
\brief Constructor and functions for ELClientSocket |
||||
\author BeeGee |
||||
\version 1.0 |
||||
\date 2016 |
||||
\copyright GNU Public License. |
||||
\warning Needs ESP-LINK V2.4 |
||||
*/ |
||||
|
||||
#include "ELClientSocket.h" |
||||
|
||||
/*! ELClientSocket(ELClient *e)
|
||||
@brief Class to send/receive data |
||||
@details The ELClientSocket class sends data over a Socket to a remote server or acts as a TCP socket server. |
||||
Each instance is used to communicate with one server and multiple instances can be created to send to multiple servers. |
||||
The ELClientSocket class does not support concurrent requests to the same server because only a single response can be recevied at a time and the responses of the two requests may arrive out of order. |
||||
@param e |
||||
Pointer to ELClient. Check ELClient API documentation. |
||||
@par Example |
||||
@code |
||||
ELClientSocket socket(&esp); |
||||
@endcode |
||||
*/ |
||||
ELClientSocket::ELClientSocket(ELClient *e) |
||||
{ |
||||
_elc = e; |
||||
remote_instance = -1; |
||||
} |
||||
|
||||
/*! socketCallback(void *res)
|
||||
@brief Callback function when data is sent, received or an error occured. |
||||
@details The function is called when data is sent or received from the remote server. |
||||
If a user callback function (userCb) was defined it is called and the response is sent as an argument. |
||||
@note Internal library function |
||||
@param res |
||||
Pointer to ELClientResponse structure |
||||
@warning The content of the response structure is overwritten when the next package arrives! |
||||
*/ |
||||
void ELClientSocket::socketCallback(void *res) |
||||
{ |
||||
if (!res) return; |
||||
|
||||
ELClientResponse *resp = (ELClientResponse *)res; |
||||
|
||||
#ifdef DEBUG_EN |
||||
int argNum = resp->argc(); |
||||
Serial.println("Number of arguments: "+String(argNum)); |
||||
uint16_t _cmd = resp->cmd(); |
||||
Serial.println("Command: "+String(_cmd)); |
||||
uint16_t _value = resp->value(); |
||||
Serial.println("Value: "+String(_value)); |
||||
#endif |
||||
|
||||
resp->popArg(&_resp_type, 1); |
||||
resp->popArg(&_client_num, 1); |
||||
resp->popArg(&_len, 2); |
||||
#ifdef DEBUG_EN |
||||
Serial.print("Type: "); |
||||
Serial.print(_resp_type); |
||||
Serial.print(" client: "); |
||||
Serial.print(_client_num); |
||||
Serial.print(" size: "+String(_len)); |
||||
#endif |
||||
if (_resp_type == 1) |
||||
{ |
||||
#ifdef DEBUG_EN |
||||
int argLen = resp->argLen(); |
||||
Serial.print(" data length: "+String(argLen)); |
||||
#endif |
||||
resp->popArgPtr((void**)&_data); |
||||
#ifdef DEBUG_EN |
||||
_data[_len] = '\0'; |
||||
Serial.print(" data: "+String(_data)); |
||||
#endif |
||||
} |
||||
#ifdef DEBUG_EN |
||||
Serial.println(""); |
||||
#endif |
||||
_status = 1; |
||||
if (_hasUserCb) |
||||
{ |
||||
_userCb(_resp_type, _client_num, _len, _data); |
||||
} |
||||
} |
||||
|
||||
/*! begin(const char* host, uint16_t port, uint8_t sock_mode, void (*userCb)(uint8_t resp_type, uint8_t client_num, uint16_t len, char *data))
|
||||
@brief Initialize communication to a remote server |
||||
@details Initialize communication to a remote server, |
||||
this communicates with esp-link but does not open a connection to the remote server. |
||||
@param host |
||||
Host to be connected. Can be a URL or an IP address in the format of xxx.xxx.xxx.xxx . |
||||
@param port |
||||
Port to be used to send/receive packets. Port MUST NOT be 80, 23 or 2323, as these ports are already used by EL-CLIENT on the ESP8266 |
||||
@param sock_mode |
||||
Set socket mode to SOCKET_TCP_CLIENT, SOCKET_TCP_CLIENT_LISTEN, SOCKET_TCP_SERVER or SOCKET_UDP |
||||
@param (*userCb)(uint8_t resp_type, uint8_t client_num, uint16_t len, char *data) |
||||
(optional) Pointer to callback function that is called if data after data has been sent, received or if an error occured |
||||
@warning Port MUST NOT be 80, 23 or 2323, as these ports are already used by EL-CLIENT on the ESP8266. |
||||
Max 4 connections are supported! |
||||
@par Example1 |
||||
@code |
||||
// Setup a simple client to send data and disconnect after data was sent
|
||||
socketConnNum = socket.begin(socketServer, socketPort, SOCKET_TCP_CLIENT, socketCb); |
||||
@endcode |
||||
@par Example2 |
||||
@code |
||||
// Setup a client to send data and wait for response from remote server
|
||||
socketConnNum = socket.begin(socketServer, socketPort, SOCKET_TCP_CLIENT_LISTEN, socketCb); |
||||
@endcode |
||||
@par Example3 |
||||
@code |
||||
// Setup a TCP server and wait for a client to connect
|
||||
socketConnNum = socket.begin(socketServer, socketPort, SOCKET_TCP_SERVER, socketCb); |
||||
@endcode |
||||
@par Example3 |
||||
@code |
||||
// Setup a TCP server and wait for a client to connect
|
||||
socketConnNum = socket.begin(socketServer, socketPort, SOCKET_UDP, socketCb); |
||||
@endcode |
||||
*/ |
||||
int ELClientSocket::begin(const char* host, uint16_t port, uint8_t sock_mode, void (*userCb)(uint8_t resp_type, uint8_t client_num, uint16_t len, char *data)) |
||||
{ |
||||
if (userCb != 0) |
||||
{ |
||||
_userCb = userCb; |
||||
_hasUserCb = true; |
||||
} |
||||
|
||||
socketCb.attach(this, &ELClientSocket::socketCallback); |
||||
|
||||
_elc->Request(CMD_SOCKET_SETUP, (uint32_t)&socketCb, 3); |
||||
_elc->Request(host, strlen(host)); |
||||
_elc->Request(&port, 2); |
||||
_elc->Request(&sock_mode, 1); |
||||
_elc->Request(); |
||||
|
||||
ELClientPacket *pkt = _elc->WaitReturn(); |
||||
|
||||
if (pkt && (int32_t)pkt->value >= 0) |
||||
{ |
||||
remote_instance = pkt->value; |
||||
// return 0;
|
||||
} |
||||
return (int)pkt->value; |
||||
} |
||||
|
||||
/*! send(const char* data, int len)
|
||||
@brief Send data to the remote server. |
||||
@param data |
||||
Pointer to SOCKET packet |
||||
@param len |
||||
Length of SOCKET packet |
||||
@par Example |
||||
@code |
||||
Serial.println("Sending JSON array to SOCKET server"); |
||||
char socketPacket = "{"device":"spm","s":622.02,"c":-165.86}" |
||||
socket.send(socketPacket, 39); |
||||
@endcode |
||||
*/ |
||||
void ELClientSocket::send(const char* data, int len) |
||||
{ |
||||
_status = 0; |
||||
if (remote_instance < 0) return; |
||||
_elc->Request(CMD_SOCKET_SEND, remote_instance, 2); |
||||
_elc->Request(data, strlen(data)); |
||||
if (data != NULL && len > 0) |
||||
{ |
||||
_elc->Request(data, len); |
||||
} |
||||
|
||||
_elc->Request(); |
||||
} |
||||
|
||||
/*! send(const char* data)
|
||||
@brief Send null-terminated data to the remote server. |
||||
@param data |
||||
Pointer to SOCKET packet, must be null-terminated |
||||
@par Example |
||||
@code |
||||
Serial.println("Sending text message to SOCKET server"); |
||||
socket.send("Message from your Arduino Uno WiFi over TCP socket"); |
||||
@endcode |
||||
*/ |
||||
void ELClientSocket::send(const char* data) |
||||
{ |
||||
send(data, strlen(data)); |
||||
} |
||||
|
||||
/*! getResponse(uint8_t *resp_type, uint8_t *client_num, char* data, uint16_t maxLen)
|
||||
@brief Retrieve response. |
||||
@details Check if a response from the remote server was received, |
||||
returns the number of send or received bytes, |
||||
0 if no response (may need to wait longer) |
||||
@param resp_type |
||||
Pointer to response type. Is USERCB_SENT if packet was sent or USERCB_RECV if a packet was received. |
||||
@param client_num |
||||
Pointer to connection number. Can be used to distinguish between different socket clients. |
||||
@param data |
||||
Pointer to buffer for received packet |
||||
@param maxLen |
||||
Size of buffer for received packet. If the received packet is larger than the buffer, the received packet will be truncated. |
||||
@return <code>uint16_t</code> |
||||
Size of received packet or number of sent bytes or 0 if no response |
||||
@par Example |
||||
@code |
||||
#define BUFLEN 266 |
||||
void loop() |
||||
{ |
||||
// process any callbacks coming from esp_link
|
||||
esp.Process(); |
||||
// Check if we received a packet or if the last send request has finished
|
||||
char response[BUFLEN]; |
||||
memset(response, 0, BUFLEN); |
||||
uint8_t resp_type; |
||||
uint8_t client_num; |
||||
uint16_t len = socket.getResponse(&resp_type, &client_num, response, BUFLEN); |
||||
if (len != 0) |
||||
{ |
||||
if (resp_type == USERCB_SENT) |
||||
{ |
||||
Serial.println("Sent "+String(len)+" bytes"); |
||||
} |
||||
else |
||||
{ |
||||
Serial.print("Received packet: "); |
||||
for (int i=0; i<len; i++) |
||||
{ |
||||
Serial.print(response[i]); |
||||
} |
||||
Serial.println(""); |
||||
} |
||||
} |
||||
} |
||||
@endcode |
||||
*/ |
||||
uint16_t ELClientSocket::getResponse(uint8_t *resp_type, uint8_t *client_num, char* data, uint16_t maxLen) |
||||
{ |
||||
if (_status == 0) return 0; |
||||
memcpy(data, _data, _len>maxLen?maxLen:_len); |
||||
*resp_type = _resp_type; |
||||
*client_num = _client_num; |
||||
_status = 0; |
||||
return _len; |
||||
} |
||||
|
||||
/*! waitResponse(uint8_t *resp_type, uint8_t *client_num, char* data, uint16_t maxLen, uint32_t timeout)
|
||||
@brief Wait for the response |
||||
@details Checks if a response from the remote server has arrived for <code>timeout</code> seconds, |
||||
returns the number of send or received bytes, |
||||
0 if no response (may need to wait longer) |
||||
@warning Blocks the Arduino code for 5 seconds! not recommended to use. Use callback function instead! |
||||
Received packet is NOT null-terminated |
||||
@param resp_type |
||||
Pointer to response type. Is USERCB_SENT if packet was sent or USERCB_RECV if a packet was received. |
||||
@param client_num |
||||
Pointer to connection number. Can be used to distinguish between different socket clients. |
||||
@param data |
||||
Pointer to buffer for received packet |
||||
@param maxLen |
||||
Size of buffer for received packet. If the received packet is larger than the buffer, the received packet will be truncated. |
||||
@param timeout |
||||
(optional) Timout in milli seconds to wait for a response, defaults to 5000ms |
||||
@return <code>uint16_t</code> |
||||
Size of received packet or number of sent bytes or 0 if no response |
||||
@par Example |
||||
@code |
||||
#define BUFLEN 266 |
||||
bool haveRemoteResponse = true; |
||||
void loop() |
||||
{ |
||||
// process any callbacks coming from esp_link
|
||||
esp.Process(); |
||||
if (haveRemoteResponse) // If last packet was sent, send a new one
|
||||
{ |
||||
Serial.println("Sending JSON array to TCP server"); |
||||
char socketPacket = "{"device":"spm","s":622.02,"c":-165.86}" |
||||
socket.send(socketPacket, 39); |
||||
haveRemoteResponse = false; |
||||
} |
||||
// Check if we received a packet or if the last send request has finished
|
||||
char response[BUFLEN]; |
||||
memset(response, 0, BUFLEN); |
||||
uint8_t resp_type; |
||||
uint8_t client_num; |
||||
uint16_t len = socket.waitResponse(&resp_type, &client_num, response, BUFLEN); |
||||
if (len != 0) |
||||
{ |
||||
if (resp_type == USERCB_SENT) |
||||
{ |
||||
Serial.println("Sent "+String(len)+" bytes"); |
||||
} |
||||
else |
||||
{ |
||||
Serial.print("Received packet: "); |
||||
for (int i=0; i<len; i++) |
||||
{ |
||||
Serial.print(response[i]); |
||||
} |
||||
Serial.println(""); |
||||
haveRemoteResponse = true; |
||||
} |
||||
} |
||||
} |
||||
@endcode |
||||
*/ |
||||
uint16_t ELClientSocket::waitResponse(uint8_t *resp_type, uint8_t *client_num, char* data, uint16_t maxLen, uint32_t timeout) |
||||
{ |
||||
uint32_t wait = millis(); |
||||
while (_status == 0) { |
||||
if ( millis() - wait < timeout) |
||||
{ |
||||
_elc->Process(); |
||||
} else { |
||||
return -3; |
||||
} |
||||
} |
||||
return getResponse(resp_type, client_num, data, maxLen); |
||||
} |
||||
@ -0,0 +1,149 @@
@@ -0,0 +1,149 @@
|
||||
/*! \file ELClientSocket.h
|
||||
\brief Definitions for ELClientSocket |
||||
\author BeeGee |
||||
\version 1.0 |
||||
\date 2016 |
||||
\copyright GNU Public License. |
||||
\warning Needs ESP-LINK V2.4 |
||||
*/ |
||||
|
||||
#ifndef _EL_CLIENT_SOCKET_H_ |
||||
#define _EL_CLIENT_SOCKET_H_ |
||||
|
||||
#include <Arduino.h> |
||||
#include "FP.h" |
||||
#include "ELClient.h" |
||||
|
||||
#define DEFAULT_SOCKET_TIMEOUT 5000 /**< Default timeout for SOCKET requests when waiting for a response */ |
||||
|
||||
#define USERCB_SENT 0 /**< Type of callback from ELClient. SOCKET packet has been sent */ |
||||
#define USERCB_RECV 1 /**< Type of callback from ELClient. SOCKET packet has been received */ |
||||
#define USERCB_RECO 2 /**< Type of callback from ELClient. SOCKET connection error */ |
||||
#define USERCB_CONN 3 /**< Type of callback from ELClient. SOCKET socket connected or disconnected */ |
||||
|
||||
// Socket mode definitions
|
||||
#define SOCKET_TCP_CLIENT 0 /**< TCP socket client for sending only, doesn't wait for response from server */ |
||||
#define SOCKET_TCP_CLIENT_LISTEN 1 /**< TCP socket client, waits for response from server after sending */ |
||||
#define SOCKET_TCP_SERVER 2 /**< TCP socket server */ |
||||
#define SOCKET_UDP 3 /**< UDP socket for sending and receiving UDP packets */ |
||||
|
||||
// Enable/disable debug output. If defined enables the debug output on Serial port
|
||||
//#define DEBUG_EN /**< Enable/disable debug output */
|
||||
|
||||
// The ELClientSocket class sends data over a simple Socket connection to a remote server. Each instance
|
||||
// is used to communicate with one server and multiple instances can be created to send
|
||||
// to multiple servers.
|
||||
// The ELClientSocket class does not support concurrent requests to the same server because
|
||||
// only a single response can be recevied at a time and the responses of the two requests
|
||||
// may arrive out of order.
|
||||
// A major limitation of the Socket class is that it does not wait for the response data.
|
||||
class ELClientSocket { |
||||
public: |
||||
ELClientSocket(ELClient *e); |
||||
|
||||
// Initialize communication to a remote server, this communicates with esp-link but does not
|
||||
// open a connection to the remote server. Host may be a hostname or an IP address.
|
||||
// Port needs to be defined different from usual HTTP/HTTPS/FTP/SSH ports
|
||||
// sock_mode defines whether the socket act as a client (with or without receiver) or as a server
|
||||
// Returns 0 if the set-up is
|
||||
// successful, returns a negative error code if it failed.
|
||||
// Optional a pointer to a callback function be added. The callback function will be called after data is sent out,
|
||||
// after data was received or when an error occured. See example code port how to use it.
|
||||
int begin(const char* host, uint16_t port, uint8_t sock_mode, void (*userCb)(uint8_t resp_type, uint8_t client_num, uint16_t len, char *data)=0); |
||||
|
||||
// Send data to the remote server. The data must be null-terminated
|
||||
void send(const char* data); |
||||
|
||||
// Send data to the remote server.
|
||||
void send(const char* data, int len); |
||||
|
||||
// Retrieve the response from the remote server, returns the number of send or received bytes, 0 if no
|
||||
// response (may need to wait longer)
|
||||
// !!! UDP doesn't check if the data was received or if the receiver IP/socket is available !!! You need to implement your own
|
||||
// error control!
|
||||
uint16_t getResponse(uint8_t *resp_type, uint8_t *client_num, char* data, uint16_t maxLen); |
||||
|
||||
// Wait for the response from the remote server, returns the length of received data or 0 if no
|
||||
// response (timeout occurred)
|
||||
// Blocks the Arduino code for 5 seconds! not recommended to use. See code examples how to use the callback function instead
|
||||
uint16_t waitResponse(uint8_t *resp_type, uint8_t *client_num, char* data, uint16_t maxLen, uint32_t timeout=DEFAULT_SOCKET_TIMEOUT); |
||||
|
||||
int32_t remote_instance; /**< Connection number, value can be 0 to 3 */ |
||||
|
||||
private: |
||||
ELClient *_elc; /**< ELClient instance */ |
||||
void socketCallback(void* resp); |
||||
FP<void, void*> socketCb; /**< Pointer to external callback function */ |
||||
|
||||
/*! void (* _userCallback)(uint8_t resp_type, uint8_t client_num, uint16_t len, char *data)
|
||||
@brief Callback function when data is sent or received |
||||
@details This function is called by ELClient library when a packet was sent, a packet was received or an error occured |
||||
The function is user specific and therefor included in the program code, not in the library |
||||
This function does not block the Arduino code execution |
||||
@param resp_type |
||||
Response type. Is USERCB_SENT if packet was sent, USERCB_RECV if a packet was received, USERCB_RECO if a connection error occured or USERCB_CONN on a connect or disconnect event |
||||
@param client_num |
||||
Connection number. Can be used to distinguish between different UDP clients. |
||||
@param len |
||||
Size of received packet or number of sent bytes. |
||||
@param data |
||||
Buffer with the received packet. |
||||
@note |
||||
The function is user specific and therefor included in the program code, not in the library |
||||
@par Example |
||||
@code |
||||
void socketCb(uint8_t resp_type, uint8_t client_num, uint16_t len, char *data) |
||||
{ |
||||
Serial.println("socketCb connection #"+String(client_num)); |
||||
if (resp_type == USERCB_SENT) |
||||
{ |
||||
Serial.println("\tSent " + String(len) + " bytes over client#" + String(client_num)); |
||||
} |
||||
else if (resp_type == USERCB_RECV) |
||||
{ |
||||
char recvData[len+1]; // Prepare buffer for the received data
|
||||
memcpy(recvData, data, len); // Copy received data into the buffer
|
||||
recvData[len] = '\0'; // Terminate the buffer with 0 for proper printout!
|
||||
Serial.println("\tReceived " + String(len) + " bytes over the server on connection #" + String(client_num)); |
||||
Serial.println("\tReceived: " + String(recvData)); |
||||
char respData[len+11]; // Prepare buffer for the response data
|
||||
char *respHdr = "Received: "; |
||||
memcpy (respData, respHdr, 10); |
||||
memcpy(&respData[10], recvData, len); // Copy received data into the buffer
|
||||
respData[len+10] = '\0'; |
||||
Serial.println("\tSend response: " + String(respData)); |
||||
socket.send(respData); |
||||
} |
||||
else if (resp_type == USERCB_RECO) |
||||
{ |
||||
Serial.println("Connection problem: "+String(len)); |
||||
} |
||||
else if (resp_type == USERCB_CONN) |
||||
{ |
||||
if (len == 0) |
||||
{ |
||||
Serial.println("\tDisconnected"); |
||||
} |
||||
else |
||||
{ |
||||
Serial.println("\tConnected"); |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
Serial.println("Received invalid response type"); |
||||
} |
||||
} |
||||
@endcode |
||||
*/ |
||||
typedef void (* _userCallback)(uint8_t resp_type, uint8_t client_num, uint16_t len, char *data); |
||||
_userCallback _userCb; /**< Pointer to internal callback function */ |
||||
|
||||
bool _hasUserCb = false; /**< Flag for user callback, true if user callback has been set */ |
||||
int16_t _status; /**< Connection status */ |
||||
uint16_t _len; /**< Number of sent/received bytes */ |
||||
char *_data; /**< Buffer for received data */ |
||||
uint8_t _resp_type; /**< Response type: 0 = send, 1 = receive; 2 = reset connection, 3 = connection */ |
||||
uint8_t _client_num; /**< Connection number, value can be 0 to 3 */ |
||||
}; |
||||
#endif // _EL_CLIENT_SOCKET_H_
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,203 @@
@@ -0,0 +1,203 @@
|
||||
/*! \file ELClientWebServer.h
|
||||
\brief Definitions for ELClientWebServer |
||||
\author Cs. Karai |
||||
\author T. von Eicken |
||||
\date 2016 |
||||
*/ |
||||
// Copyright (c) 2016 by Cs. Karai and T. von Eicken
|
||||
|
||||
#ifndef _EL_CLIENT_WEB_SERVER_H_ |
||||
#define _EL_CLIENT_WEB_SERVER_H_ |
||||
|
||||
#include <Arduino.h> |
||||
#include "ELClient.h" |
||||
#include "FP.h" |
||||
|
||||
/** Web Server URL handler structure. */ |
||||
typedef struct URL_HANDLER |
||||
{ |
||||
|
||||
String URL; ///< the URL to handle
|
||||
|
||||
/*! loadCb()
|
||||
@brief Callback for HTML page loading |
||||
@details This callback is called when browser loads a custom page for the first time. |
||||
The callback should populate all the fields that are required for displaying the page. |
||||
@param url |
||||
The URL of the page to load. |
||||
@par Example |
||||
@code |
||||
void loadCb(char * url) |
||||
{ |
||||
webServer.setArgString(F("field1"), F("value")); |
||||
webServer.setArgInt(F("field2"), 123); |
||||
webServer.setArgFloat(F("field3"), 12.3); |
||||
} |
||||
@endcode |
||||
*/ |
||||
FP<void, char*> loadCb; |
||||
|
||||
/*! refreshCb()
|
||||
@brief Callback for HTML page refresh |
||||
@details This callback is called when browser refreshes a page. The callback should populate |
||||
all the fields that are required for displaying changes on the page. |
||||
@param url |
||||
The URL of the page to load. |
||||
@par Example |
||||
@code |
||||
void refreshCb(char * url) |
||||
{ |
||||
webServer.setArgString(F("field1"), F("changed_value")); |
||||
webServer.setArgInt(F("field2"), 543); |
||||
webServer.setArgFloat(F("field3"), 54.3); |
||||
} |
||||
@endcode |
||||
*/ |
||||
FP<void, char*> refreshCb; |
||||
|
||||
/*! buttonCb()
|
||||
@brief callback for setting a field from a HTML form |
||||
@details This callback is called when a HTML form is submitted. The callback should save |
||||
field changes. After processing the callback, a page refresh will also be initiated to |
||||
reflect the changes. |
||||
|
||||
The size of the receive buffer on ELClient is 128 bytes which can be small for receiving |
||||
a large form. When the data exceeds 128 bytes, Esp-Link segments the query into smaller |
||||
parts. If the callback is slow, it's possible that the UART buffer overruns while receiving |
||||
the next packet causing data loss. The callback has 5ms to process the request if data comes |
||||
at 115200 baud. |
||||
|
||||
If debugging is enabled, data loss is very likely to happen because of packet logging. |
||||
@warning Write this routine to be as fast as possible and turn off debugging for receiving |
||||
large forms. |
||||
|
||||
@param field_id |
||||
The ID of the field |
||||
@par Example |
||||
@code |
||||
int32_t value; |
||||
|
||||
// this code should be fast
|
||||
void setFieldCb(char * field_id) |
||||
{ |
||||
String id = field_id; |
||||
|
||||
if( id == F("my_field") ) |
||||
{ |
||||
value = webServer.getArgInt(); |
||||
} |
||||
} |
||||
@endcode |
||||
*/ |
||||
FP<void, char*> setFieldCb; |
||||
|
||||
/*! buttonCb()
|
||||
@brief callback for a HTML button press |
||||
@details This callback is called when user presses a HTML button. After processing this |
||||
callback, a page refresh will also be called to reflect the changes. |
||||
@param button_id |
||||
The ID of the button |
||||
@par Example |
||||
@code |
||||
void buttonCb(char * button_id) |
||||
{ |
||||
String id = button_id; |
||||
|
||||
if( id == F("my_button") ) |
||||
{ |
||||
Serial.println("My button was pressed"); |
||||
} |
||||
} |
||||
@endcode |
||||
*/ |
||||
FP<void, char*> buttonCb; |
||||
struct URL_HANDLER * next; ///< next handler
|
||||
} URLHandler; |
||||
|
||||
// This class implements functions for the web-server
|
||||
class ELClientWebServer { |
||||
public: |
||||
// Initialize with an ELClient object
|
||||
ELClientWebServer(ELClient* elc); |
||||
|
||||
// initializes the web-server
|
||||
void setup(); |
||||
|
||||
// creates a URL handler
|
||||
URLHandler * createURLHandler(const char * URL); |
||||
// creates a URL handler from flash
|
||||
URLHandler * createURLHandler(const __FlashStringHelper * URL); |
||||
// creates a URL handler from String
|
||||
URLHandler * createURLHandler(const String &s); |
||||
|
||||
// destroys a URL handler
|
||||
void destroyURLHandler(URLHandler * handler); |
||||
|
||||
// sets int value of a HTML field
|
||||
void setArgInt(const char * name, int32_t value); |
||||
// sets int value of a HTML field
|
||||
void setArgInt(const __FlashStringHelper * name, int32_t value); |
||||
// sets JSON value of a HTML field
|
||||
void setArgJson(const char * name, const char * value); |
||||
// sets JSON value of a HTML field
|
||||
void setArgJson(const __FlashStringHelper * name, const char * value); |
||||
// sets JSON value of a HTML field
|
||||
void setArgJson(const __FlashStringHelper * name, const __FlashStringHelper * value); |
||||
// sets string value of a HTML field
|
||||
void setArgString(const char * name, const char * value); |
||||
// sets string value of a HTML field
|
||||
void setArgString(const __FlashStringHelper * name, const char * value); |
||||
// sets string value of a HTML field
|
||||
void setArgString(const __FlashStringHelper * name, const __FlashStringHelper * value); |
||||
// sets boolean value of a HTML field
|
||||
void setArgBoolean(const char * name, uint8_t value); |
||||
// sets boolean value of a HTML field
|
||||
void setArgBoolean(const __FlashStringHelper * name, uint8_t value); |
||||
// sets null value of a HTML field
|
||||
void setArgNull(const char * name); |
||||
// sets null value of a HTML field
|
||||
void setArgNull(const __FlashStringHelper * name); |
||||
// sets float value of a HTML field
|
||||
void setArgFloat(const char * name, float f); |
||||
// sets float value of a HTML field
|
||||
void setArgFloat(const __FlashStringHelper * name, float f); |
||||
|
||||
|
||||
// setFieldCb: gets the value of the field as integer
|
||||
int32_t getArgInt(); |
||||
// setFieldCb: gets the value of the field as string
|
||||
char * getArgString(); |
||||
// setFieldCb: gets the value of the field as boolean
|
||||
uint8_t getArgBoolean(); |
||||
// setFieldCb: gets the value of the field as float
|
||||
float getArgFloat(); |
||||
|
||||
|
||||
/*! ELClientWebServer::getInstance()
|
||||
@brief Returns the singleton web-server instance. |
||||
@details Web-Server is a singleton object. This object can be read by calling ELClientWebServer::getInstance(). |
||||
@returns |
||||
The singleton web-server instance. |
||||
@par Example code |
||||
@code |
||||
ELClientWebServer *webServer = ELClientWebServer::getInstance(); |
||||
@endcode |
||||
*/ |
||||
static ELClientWebServer * getInstance() { return instance; } |
||||
|
||||
private: |
||||
ELClient* _elc; |
||||
|
||||
static void webServerPacketHandler(void * packet); |
||||
void processResponse(ELClientResponse *packet); // internal
|
||||
static ELClientWebServer * instance; |
||||
|
||||
uint8_t remote_ip[4]; |
||||
uint16_t remote_port; |
||||
|
||||
struct URL_HANDLER * handlers; |
||||
char * arg_ptr; |
||||
FP<void, void*> webServerCb; |
||||
}; |
||||
|
||||
#endif // _EL_CLIENT_WEB_SERVER_H_
|
||||
@ -0,0 +1,600 @@
@@ -0,0 +1,600 @@
|
||||
/**
|
||||
* @file FP.cpp |
||||
* @brief Core Utility - Templated Function Pointer Class |
||||
* @author sam grove |
||||
* @version 1.0 |
||||
* @see
|
||||
* |
||||
* Copyright (c) 2013 |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
#include "FP.h" |
||||
#include <stdint.h> |
||||
|
||||
template<class retT, class argT> |
||||
FP<retT, argT>::FP() |
||||
{ |
||||
obj_callback = 0; |
||||
c_callback = 0; |
||||
} |
||||
|
||||
template<class retT, class argT> |
||||
bool FP<retT, argT>::attached() |
||||
{ |
||||
return obj_callback || c_callback; |
||||
} |
||||
|
||||
|
||||
template<class retT, class argT> |
||||
void FP<retT, argT>::detach() |
||||
{ |
||||
obj_callback = 0; |
||||
c_callback = 0; |
||||
} |
||||
|
||||
|
||||
template<class retT, class argT> |
||||
void FP<retT, argT>::attach(retT (*function)(argT)) |
||||
{ |
||||
c_callback = function; |
||||
} |
||||
|
||||
template<class retT, class argT> |
||||
retT FP<retT, argT>::operator()(argT arg) const |
||||
{ |
||||
if( 0 != c_callback ) |
||||
{ |
||||
return obj_callback ? (obj_callback->*method_callback)(arg) : (*c_callback)(arg); |
||||
} |
||||
return (retT)0; |
||||
} |
||||
|
||||
// pre-define the types for the linker
|
||||
template class FP<void,char>; |
||||
template class FP<void,char*>; |
||||
template class FP<void,int8_t>; |
||||
template class FP<void,int8_t*>; |
||||
template class FP<void,uint8_t>; |
||||
template class FP<void,uint8_t*>; |
||||
template class FP<void,int16_t>; |
||||
template class FP<void,int16_t*>; |
||||
template class FP<void,uint16_t>; |
||||
template class FP<void,uint16_t*>; |
||||
template class FP<void,int32_t>; |
||||
template class FP<void,int32_t*>; |
||||
template class FP<void,uint32_t>; |
||||
template class FP<void,uint32_t*>; |
||||
template class FP<void,int64_t>; |
||||
template class FP<void,int64_t*>; |
||||
template class FP<void,uint64_t>; |
||||
template class FP<void,uint64_t*>; |
||||
template class FP<void,bool>; |
||||
template class FP<void,bool*>; |
||||
template class FP<void,float>; |
||||
template class FP<void,float*>; |
||||
template class FP<void,double>; |
||||
template class FP<void,double*>; |
||||
template class FP<void,void*>; |
||||
|
||||
template class FP<int8_t,char>; |
||||
template class FP<int8_t,char*>; |
||||
template class FP<int8_t,int8_t>; |
||||
template class FP<int8_t,int8_t*>; |
||||
template class FP<int8_t,uint8_t>; |
||||
template class FP<int8_t,uint8_t*>; |
||||
template class FP<int8_t,int16_t>; |
||||
template class FP<int8_t,int16_t*>; |
||||
template class FP<int8_t,uint16_t>; |
||||
template class FP<int8_t,uint16_t*>; |
||||
template class FP<int8_t,int32_t>; |
||||
template class FP<int8_t,int32_t*>; |
||||
template class FP<int8_t,uint32_t>; |
||||
template class FP<int8_t,uint32_t*>; |
||||
template class FP<int8_t,int64_t>; |
||||
template class FP<int8_t,int64_t*>; |
||||
template class FP<int8_t,uint64_t>; |
||||
template class FP<int8_t,uint64_t*>; |
||||
template class FP<int8_t,bool>; |
||||
template class FP<int8_t,bool*>; |
||||
template class FP<int8_t,float>; |
||||
template class FP<int8_t,float*>; |
||||
template class FP<int8_t,double>; |
||||
template class FP<int8_t,double*>; |
||||
|
||||
template class FP<int8_t*,char>; |
||||
template class FP<int8_t*,char*>; |
||||
template class FP<int8_t*,int8_t>; |
||||
template class FP<int8_t*,int8_t*>; |
||||
template class FP<int8_t*,uint8_t>; |
||||
template class FP<int8_t*,uint8_t*>; |
||||
template class FP<int8_t*,int16_t>; |
||||
template class FP<int8_t*,int16_t*>; |
||||
template class FP<int8_t*,uint16_t>; |
||||
template class FP<int8_t*,uint16_t*>; |
||||
template class FP<int8_t*,int32_t>; |
||||
template class FP<int8_t*,int32_t*>; |
||||
template class FP<int8_t*,uint32_t>; |
||||
template class FP<int8_t*,uint32_t*>; |
||||
template class FP<int8_t*,int64_t>; |
||||
template class FP<int8_t*,int64_t*>; |
||||
template class FP<int8_t*,uint64_t>; |
||||
template class FP<int8_t*,uint64_t*>; |
||||
template class FP<int8_t*,bool>; |
||||
template class FP<int8_t*,bool*>; |
||||
template class FP<int8_t*,float>; |
||||
template class FP<int8_t*,float*>; |
||||
template class FP<int8_t*,double>; |
||||
template class FP<int8_t*,double*>; |
||||
|
||||
template class FP<uint8_t,char>; |
||||
template class FP<uint8_t,char*>; |
||||
template class FP<uint8_t,int8_t>; |
||||
template class FP<uint8_t,int8_t*>; |
||||
template class FP<uint8_t,uint8_t>; |
||||
template class FP<uint8_t,uint8_t*>; |
||||
template class FP<uint8_t,int16_t>; |
||||
template class FP<uint8_t,int16_t*>; |
||||
template class FP<uint8_t,uint16_t>; |
||||
template class FP<uint8_t,uint16_t*>; |
||||
template class FP<uint8_t,int32_t>; |
||||
template class FP<uint8_t,int32_t*>; |
||||
template class FP<uint8_t,uint32_t>; |
||||
template class FP<uint8_t,uint32_t*>; |
||||
template class FP<uint8_t,int64_t>; |
||||
template class FP<uint8_t,int64_t*>; |
||||
template class FP<uint8_t,uint64_t>; |
||||
template class FP<uint8_t,uint64_t*>; |
||||
template class FP<uint8_t,bool>; |
||||
template class FP<uint8_t,bool*>; |
||||
template class FP<uint8_t,float>; |
||||
template class FP<uint8_t,float*>; |
||||
template class FP<uint8_t,double>; |
||||
template class FP<uint8_t,double*>; |
||||
|
||||
template class FP<uint8_t*,char>; |
||||
template class FP<uint8_t*,char*>; |
||||
template class FP<uint8_t*,int8_t>; |
||||
template class FP<uint8_t*,int8_t*>; |
||||
template class FP<uint8_t*,uint8_t>; |
||||
template class FP<uint8_t*,uint8_t*>; |
||||
template class FP<uint8_t*,int16_t>; |
||||
template class FP<uint8_t*,int16_t*>; |
||||
template class FP<uint8_t*,uint16_t>; |
||||
template class FP<uint8_t*,uint16_t*>; |
||||
template class FP<uint8_t*,int32_t>; |
||||
template class FP<uint8_t*,int32_t*>; |
||||
template class FP<uint8_t*,uint32_t>; |
||||
template class FP<uint8_t*,uint32_t*>; |
||||
template class FP<uint8_t*,int64_t>; |
||||
template class FP<uint8_t*,int64_t*>; |
||||
template class FP<uint8_t*,uint64_t>; |
||||
template class FP<uint8_t*,uint64_t*>; |
||||
template class FP<uint8_t*,bool>; |
||||
template class FP<uint8_t*,bool*>; |
||||
template class FP<uint8_t*,float>; |
||||
template class FP<uint8_t*,float*>; |
||||
template class FP<uint8_t*,double>; |
||||
template class FP<uint8_t*,double*>; |
||||
|
||||
template class FP<int16_t,char>; |
||||
template class FP<int16_t,char*>; |
||||
template class FP<int16_t,int8_t>; |
||||
template class FP<int16_t,int8_t*>; |
||||
template class FP<int16_t,uint8_t>; |
||||
template class FP<int16_t,uint8_t*>; |
||||
template class FP<int16_t,int16_t>; |
||||
template class FP<int16_t,int16_t*>; |
||||
template class FP<int16_t,uint16_t>; |
||||
template class FP<int16_t,uint16_t*>; |
||||
template class FP<int16_t,int32_t>; |
||||
template class FP<int16_t,int32_t*>; |
||||
template class FP<int16_t,uint32_t>; |
||||
template class FP<int16_t,uint32_t*>; |
||||
template class FP<int16_t,int64_t>; |
||||
template class FP<int16_t,int64_t*>; |
||||
template class FP<int16_t,uint64_t>; |
||||
template class FP<int16_t,uint64_t*>; |
||||
template class FP<int16_t,bool>; |
||||
template class FP<int16_t,bool*>; |
||||
template class FP<int16_t,float>; |
||||
template class FP<int16_t,float*>; |
||||
template class FP<int16_t,double>; |
||||
template class FP<int16_t,double*>; |
||||
|
||||
template class FP<int16_t*,char>; |
||||
template class FP<int16_t*,char*>; |
||||
template class FP<int16_t*,int8_t>; |
||||
template class FP<int16_t*,int8_t*>; |
||||
template class FP<int16_t*,uint8_t>; |
||||
template class FP<int16_t*,uint8_t*>; |
||||
template class FP<int16_t*,int16_t>; |
||||
template class FP<int16_t*,int16_t*>; |
||||
template class FP<int16_t*,uint16_t>; |
||||
template class FP<int16_t*,uint16_t*>; |
||||
template class FP<int16_t*,int32_t>; |
||||
template class FP<int16_t*,int32_t*>; |
||||
template class FP<int16_t*,uint32_t>; |
||||
template class FP<int16_t*,uint32_t*>; |
||||
template class FP<int16_t*,int64_t>; |
||||
template class FP<int16_t*,int64_t*>; |
||||
template class FP<int16_t*,uint64_t>; |
||||
template class FP<int16_t*,uint64_t*>; |
||||
template class FP<int16_t*,bool>; |
||||
template class FP<int16_t*,bool*>; |
||||
template class FP<int16_t*,float>; |
||||
template class FP<int16_t*,float*>; |
||||
template class FP<int16_t*,double>; |
||||
template class FP<int16_t*,double*>; |
||||
|
||||
template class FP<uint16_t,char>; |
||||
template class FP<uint16_t,char*>; |
||||
template class FP<uint16_t,int8_t>; |
||||
template class FP<uint16_t,int8_t*>; |
||||
template class FP<uint16_t,uint8_t>; |
||||
template class FP<uint16_t,uint8_t*>; |
||||
template class FP<uint16_t,int16_t>; |
||||
template class FP<uint16_t,int16_t*>; |
||||
template class FP<uint16_t,uint16_t>; |
||||
template class FP<uint16_t,uint16_t*>; |
||||
template class FP<uint16_t,int32_t>; |
||||
template class FP<uint16_t,int32_t*>; |
||||
template class FP<uint16_t,uint32_t>; |
||||
template class FP<uint16_t,uint32_t*>; |
||||
template class FP<uint16_t,int64_t>; |
||||
template class FP<uint16_t,int64_t*>; |
||||
template class FP<uint16_t,uint64_t>; |
||||
template class FP<uint16_t,uint64_t*>; |
||||
template class FP<uint16_t,bool>; |
||||
template class FP<uint16_t,bool*>; |
||||
template class FP<uint16_t,float>; |
||||
template class FP<uint16_t,float*>; |
||||
template class FP<uint16_t,double>; |
||||
template class FP<uint16_t,double*>; |
||||
|
||||
template class FP<uint16_t*,char>; |
||||
template class FP<uint16_t*,char*>; |
||||
template class FP<uint16_t*,int8_t>; |
||||
template class FP<uint16_t*,int8_t*>; |
||||
template class FP<uint16_t*,uint8_t>; |
||||
template class FP<uint16_t*,uint8_t*>; |
||||
template class FP<uint16_t*,int16_t>; |
||||
template class FP<uint16_t*,int16_t*>; |
||||
template class FP<uint16_t*,uint16_t>; |
||||
template class FP<uint16_t*,uint16_t*>; |
||||
template class FP<uint16_t*,int32_t>; |
||||
template class FP<uint16_t*,int32_t*>; |
||||
template class FP<uint16_t*,uint32_t>; |
||||
template class FP<uint16_t*,uint32_t*>; |
||||
template class FP<uint16_t*,int64_t>; |
||||
template class FP<uint16_t*,int64_t*>; |
||||
template class FP<uint16_t*,uint64_t>; |
||||
template class FP<uint16_t*,uint64_t*>; |
||||
template class FP<uint16_t*,bool>; |
||||
template class FP<uint16_t*,bool*>; |
||||
template class FP<uint16_t*,float>; |
||||
template class FP<uint16_t*,float*>; |
||||
template class FP<uint16_t*,double>; |
||||
template class FP<uint16_t*,double*>; |
||||
|
||||
template class FP<int32_t,char>; |
||||
template class FP<int32_t,char*>; |
||||
template class FP<int32_t,int8_t>; |
||||
template class FP<int32_t,int8_t*>; |
||||
template class FP<int32_t,uint8_t>; |
||||
template class FP<int32_t,uint8_t*>; |
||||
template class FP<int32_t,int16_t>; |
||||
template class FP<int32_t,int16_t*>; |
||||
template class FP<int32_t,uint16_t>; |
||||
template class FP<int32_t,uint16_t*>; |
||||
template class FP<int32_t,int32_t>; |
||||
template class FP<int32_t,int32_t*>; |
||||
template class FP<int32_t,uint32_t>; |
||||
template class FP<int32_t,uint32_t*>; |
||||
template class FP<int32_t,int64_t>; |
||||
template class FP<int32_t,int64_t*>; |
||||
template class FP<int32_t,uint64_t>; |
||||
template class FP<int32_t,uint64_t*>; |
||||
template class FP<int32_t,bool>; |
||||
template class FP<int32_t,bool*>; |
||||
template class FP<int32_t,float>; |
||||
template class FP<int32_t,float*>; |
||||
template class FP<int32_t,double>; |
||||
template class FP<int32_t,double*>; |
||||
|
||||
template class FP<int32_t*,char>; |
||||
template class FP<int32_t*,char*>; |
||||
template class FP<int32_t*,int8_t>; |
||||
template class FP<int32_t*,int8_t*>; |
||||
template class FP<int32_t*,uint8_t>; |
||||
template class FP<int32_t*,uint8_t*>; |
||||
template class FP<int32_t*,int16_t>; |
||||
template class FP<int32_t*,int16_t*>; |
||||
template class FP<int32_t*,uint16_t>; |
||||
template class FP<int32_t*,uint16_t*>; |
||||
template class FP<int32_t*,int32_t>; |
||||
template class FP<int32_t*,int32_t*>; |
||||
template class FP<int32_t*,uint32_t>; |
||||
template class FP<int32_t*,uint32_t*>; |
||||
template class FP<int32_t*,int64_t>; |
||||
template class FP<int32_t*,int64_t*>; |
||||
template class FP<int32_t*,uint64_t>; |
||||
template class FP<int32_t*,uint64_t*>; |
||||
template class FP<int32_t*,bool>; |
||||
template class FP<int32_t*,bool*>; |
||||
template class FP<int32_t*,float>; |
||||
template class FP<int32_t*,float*>; |
||||
template class FP<int32_t*,double>; |
||||
template class FP<int32_t*,double*>; |
||||
|
||||
template class FP<uint32_t,char>; |
||||
template class FP<uint32_t,char*>; |
||||
template class FP<uint32_t,int8_t>; |
||||
template class FP<uint32_t,int8_t*>; |
||||
template class FP<uint32_t,uint8_t>; |
||||
template class FP<uint32_t,uint8_t*>; |
||||
template class FP<uint32_t,int16_t>; |
||||
template class FP<uint32_t,int16_t*>; |
||||
template class FP<uint32_t,uint16_t>; |
||||
template class FP<uint32_t,uint16_t*>; |
||||
template class FP<uint32_t,int32_t>; |
||||
template class FP<uint32_t,int32_t*>; |
||||
template class FP<uint32_t,uint32_t>; |
||||
template class FP<uint32_t,uint32_t*>; |
||||
template class FP<uint32_t,int64_t>; |
||||
template class FP<uint32_t,int64_t*>; |
||||
template class FP<uint32_t,uint64_t>; |
||||
template class FP<uint32_t,uint64_t*>; |
||||
template class FP<uint32_t,bool>; |
||||
template class FP<uint32_t,bool*>; |
||||
template class FP<uint32_t,float>; |
||||
template class FP<uint32_t,float*>; |
||||
template class FP<uint32_t,double>; |
||||
template class FP<uint32_t,double*>; |
||||
|
||||
template class FP<uint32_t*,char>; |
||||
template class FP<uint32_t*,char*>; |
||||
template class FP<uint32_t*,int8_t>; |
||||
template class FP<uint32_t*,int8_t*>; |
||||
template class FP<uint32_t*,uint8_t>; |
||||
template class FP<uint32_t*,uint8_t*>; |
||||
template class FP<uint32_t*,int16_t>; |
||||
template class FP<uint32_t*,int16_t*>; |
||||
template class FP<uint32_t*,uint16_t>; |
||||
template class FP<uint32_t*,uint16_t*>; |
||||
template class FP<uint32_t*,int32_t>; |
||||
template class FP<uint32_t*,int32_t*>; |
||||
template class FP<uint32_t*,uint32_t>; |
||||
template class FP<uint32_t*,uint32_t*>; |
||||
template class FP<uint32_t*,int64_t>; |
||||
template class FP<uint32_t*,int64_t*>; |
||||
template class FP<uint32_t*,uint64_t>; |
||||
template class FP<uint32_t*,uint64_t*>; |
||||
template class FP<uint32_t*,bool>; |
||||
template class FP<uint32_t*,bool*>; |
||||
template class FP<uint32_t*,float>; |
||||
template class FP<uint32_t*,float*>; |
||||
template class FP<uint32_t*,double>; |
||||
template class FP<uint32_t*,double*>; |
||||
|
||||
template class FP<int64_t,char>; |
||||
template class FP<int64_t,char*>; |
||||
template class FP<int64_t,int8_t>; |
||||
template class FP<int64_t,int8_t*>; |
||||
template class FP<int64_t,uint8_t>; |
||||
template class FP<int64_t,uint8_t*>; |
||||
template class FP<int64_t,int16_t>; |
||||
template class FP<int64_t,int16_t*>; |
||||
template class FP<int64_t,uint16_t>; |
||||
template class FP<int64_t,uint16_t*>; |
||||
template class FP<int64_t,int32_t>; |
||||
template class FP<int64_t,int32_t*>; |
||||
template class FP<int64_t,uint32_t>; |
||||
template class FP<int64_t,uint32_t*>; |
||||
template class FP<int64_t,int64_t>; |
||||
template class FP<int64_t,int64_t*>; |
||||
template class FP<int64_t,uint64_t>; |
||||
template class FP<int64_t,uint64_t*>; |
||||
template class FP<int64_t,bool>; |
||||
template class FP<int64_t,bool*>; |
||||
template class FP<int64_t,float>; |
||||
template class FP<int64_t,float*>; |
||||
template class FP<int64_t,double>; |
||||
template class FP<int64_t,double*>; |
||||
|
||||
template class FP<int64_t*,char>; |
||||
template class FP<int64_t*,char*>; |
||||
template class FP<int64_t*,int8_t>; |
||||
template class FP<int64_t*,int8_t*>; |
||||
template class FP<int64_t*,uint8_t>; |
||||
template class FP<int64_t*,uint8_t*>; |
||||
template class FP<int64_t*,int16_t>; |
||||
template class FP<int64_t*,int16_t*>; |
||||
template class FP<int64_t*,uint16_t>; |
||||
template class FP<int64_t*,uint16_t*>; |
||||
template class FP<int64_t*,int32_t>; |
||||
template class FP<int64_t*,int32_t*>; |
||||
template class FP<int64_t*,uint32_t>; |
||||
template class FP<int64_t*,uint32_t*>; |
||||
template class FP<int64_t*,int64_t>; |
||||
template class FP<int64_t*,int64_t*>; |
||||
template class FP<int64_t*,uint64_t>; |
||||
template class FP<int64_t*,uint64_t*>; |
||||
template class FP<int64_t*,bool>; |
||||
template class FP<int64_t*,bool*>; |
||||
template class FP<int64_t*,float>; |
||||
template class FP<int64_t*,float*>; |
||||
template class FP<int64_t*,double>; |
||||
template class FP<int64_t*,double*>; |
||||
|
||||
template class FP<uint64_t,char>; |
||||
template class FP<uint64_t,char*>; |
||||
template class FP<uint64_t,int8_t>; |
||||
template class FP<uint64_t,int8_t*>; |
||||
template class FP<uint64_t,uint8_t>; |
||||
template class FP<uint64_t,uint8_t*>; |
||||
template class FP<uint64_t,int16_t>; |
||||
template class FP<uint64_t,int16_t*>; |
||||
template class FP<uint64_t,uint16_t>; |
||||
template class FP<uint64_t,uint16_t*>; |
||||
template class FP<uint64_t,int32_t>; |
||||
template class FP<uint64_t,int32_t*>; |
||||
template class FP<uint64_t,uint32_t>; |
||||
template class FP<uint64_t,uint32_t*>; |
||||
template class FP<uint64_t,int64_t>; |
||||
template class FP<uint64_t,int64_t*>; |
||||
template class FP<uint64_t,uint64_t>; |
||||
template class FP<uint64_t,uint64_t*>; |
||||
template class FP<uint64_t,bool>; |
||||
template class FP<uint64_t,bool*>; |
||||
template class FP<uint64_t,float>; |
||||
template class FP<uint64_t,float*>; |
||||
template class FP<uint64_t,double>; |
||||
template class FP<uint64_t,double*>; |
||||
|
||||
template class FP<uint64_t*,char>; |
||||
template class FP<uint64_t*,char*>; |
||||
template class FP<uint64_t*,int8_t>; |
||||
template class FP<uint64_t*,int8_t*>; |
||||
template class FP<uint64_t*,uint8_t>; |
||||
template class FP<uint64_t*,uint8_t*>; |
||||
template class FP<uint64_t*,int16_t>; |
||||
template class FP<uint64_t*,int16_t*>; |
||||
template class FP<uint64_t*,uint16_t>; |
||||
template class FP<uint64_t*,uint16_t*>; |
||||
template class FP<uint64_t*,int32_t>; |
||||
template class FP<uint64_t*,int32_t*>; |
||||
template class FP<uint64_t*,uint32_t>; |
||||
template class FP<uint64_t*,uint32_t*>; |
||||
template class FP<uint64_t*,int64_t>; |
||||
template class FP<uint64_t*,int64_t*>; |
||||
template class FP<uint64_t*,uint64_t>; |
||||
template class FP<uint64_t*,uint64_t*>; |
||||
template class FP<uint64_t*,bool>; |
||||
template class FP<uint64_t*,bool*>; |
||||
template class FP<uint64_t*,float>; |
||||
template class FP<uint64_t*,float*>; |
||||
template class FP<uint64_t*,double>; |
||||
template class FP<uint64_t*,double*>; |
||||
|
||||
template class FP<float,char>; |
||||
template class FP<float,char*>; |
||||
template class FP<float,int8_t>; |
||||
template class FP<float,int8_t*>; |
||||
template class FP<float,uint8_t>; |
||||
template class FP<float,uint8_t*>; |
||||
template class FP<float,int16_t>; |
||||
template class FP<float,int16_t*>; |
||||
template class FP<float,uint16_t>; |
||||
template class FP<float,uint16_t*>; |
||||
template class FP<float,int32_t>; |
||||
template class FP<float,int32_t*>; |
||||
template class FP<float,uint32_t>; |
||||
template class FP<float,uint32_t*>; |
||||
template class FP<float,int64_t>; |
||||
template class FP<float,int64_t*>; |
||||
template class FP<float,uint64_t>; |
||||
template class FP<float,uint64_t*>; |
||||
template class FP<float,bool>; |
||||
template class FP<float,bool*>; |
||||
template class FP<float,float>; |
||||
template class FP<float,float*>; |
||||
template class FP<float,double>; |
||||
template class FP<float,double*>; |
||||
|
||||
template class FP<float*,char>; |
||||
template class FP<float*,char*>; |
||||
template class FP<float*,int8_t>; |
||||
template class FP<float*,int8_t*>; |
||||
template class FP<float*,uint8_t>; |
||||
template class FP<float*,uint8_t*>; |
||||
template class FP<float*,int16_t>; |
||||
template class FP<float*,int16_t*>; |
||||
template class FP<float*,uint16_t>; |
||||
template class FP<float*,uint16_t*>; |
||||
template class FP<float*,int32_t>; |
||||
template class FP<float*,int32_t*>; |
||||
template class FP<float*,uint32_t>; |
||||
template class FP<float*,uint32_t*>; |
||||
template class FP<float*,int64_t>; |
||||
template class FP<float*,int64_t*>; |
||||
template class FP<float*,uint64_t>; |
||||
template class FP<float*,uint64_t*>; |
||||
template class FP<float*,bool>; |
||||
template class FP<float*,bool*>; |
||||
template class FP<float*,float>; |
||||
template class FP<float*,float*>; |
||||
template class FP<float*,double>; |
||||
template class FP<float*,double*>; |
||||
|
||||
template class FP<double,char>; |
||||
template class FP<double,char*>; |
||||
template class FP<double,int8_t>; |
||||
template class FP<double,int8_t*>; |
||||
template class FP<double,uint8_t>; |
||||
template class FP<double,uint8_t*>; |
||||
template class FP<double,int16_t>; |
||||
template class FP<double,int16_t*>; |
||||
template class FP<double,uint16_t>; |
||||
template class FP<double,uint16_t*>; |
||||
template class FP<double,int32_t>; |
||||
template class FP<double,int32_t*>; |
||||
template class FP<double,uint32_t>; |
||||
template class FP<double,uint32_t*>; |
||||
template class FP<double,int64_t>; |
||||
template class FP<double,int64_t*>; |
||||
template class FP<double,uint64_t>; |
||||
template class FP<double,uint64_t*>; |
||||
template class FP<double,bool>; |
||||
template class FP<double,bool*>; |
||||
template class FP<double,float>; |
||||
template class FP<double,float*>; |
||||
template class FP<double,double>; |
||||
template class FP<double,double*>; |
||||
|
||||
template class FP<double*,char>; |
||||
template class FP<double*,char*>; |
||||
template class FP<double*,int8_t>; |
||||
template class FP<double*,int8_t*>; |
||||
template class FP<double*,uint8_t>; |
||||
template class FP<double*,uint8_t*>; |
||||
template class FP<double*,int16_t>; |
||||
template class FP<double*,int16_t*>; |
||||
template class FP<double*,uint16_t>; |
||||
template class FP<double*,uint16_t*>; |
||||
template class FP<double*,int32_t>; |
||||
template class FP<double*,int32_t*>; |
||||
template class FP<double*,uint32_t>; |
||||
template class FP<double*,uint32_t*>; |
||||
template class FP<double*,int64_t>; |
||||
template class FP<double*,int64_t*>; |
||||
template class FP<double*,uint64_t>; |
||||
template class FP<double*,uint64_t*>; |
||||
template class FP<double*,bool>; |
||||
template class FP<double*,bool*>; |
||||
template class FP<double*,float>; |
||||
template class FP<double*,float*>; |
||||
template class FP<double*,double>; |
||||
template class FP<double*,double*>; |
||||
|
||||
template class FP<char, char>; |
||||
template class FP<char, char*>; |
||||
template class FP<char, const char*>; |
||||
|
||||
template class FP<char*, char>; |
||||
template class FP<char*, char*>; |
||||
template class FP<char*, const char*>; |
||||
|
||||
|
||||
|
||||
@ -0,0 +1,188 @@
@@ -0,0 +1,188 @@
|
||||
/**
|
||||
* @file FP.h |
||||
* @brief Core Utility - Templated Function Pointer Class |
||||
* @author sam grove |
||||
* @version 1.0 |
||||
* @see
|
||||
* |
||||
* Copyright (c) 2013 |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
#ifndef FP_H |
||||
#define FP_H |
||||
|
||||
/** Example using the FP Class with global functions
|
||||
* @code |
||||
* #include "mbed.h" |
||||
* #include "FP.h" |
||||
*
|
||||
* FP<void,bool>fp; |
||||
* DigitalOut myled(LED1); |
||||
*
|
||||
* void handler(bool value) |
||||
* { |
||||
* myled = value; |
||||
* return; |
||||
* } |
||||
*
|
||||
* int main() |
||||
* { |
||||
* fp.attach(&handler); |
||||
*
|
||||
* while(1)
|
||||
* { |
||||
* fp(1); |
||||
* wait(0.2); |
||||
* fp(0); |
||||
* wait(0.2); |
||||
* } |
||||
* } |
||||
* @endcode |
||||
*/ |
||||
|
||||
/** Example using the FP Class with different class member functions
|
||||
* @code |
||||
* #include "mbed.h" |
||||
* #include "FP.h" |
||||
*
|
||||
* FP<void,bool>fp; |
||||
* DigitalOut myled(LED4); |
||||
*
|
||||
* class Wrapper |
||||
* { |
||||
* public: |
||||
* Wrapper(){} |
||||
*
|
||||
* void handler(bool value) |
||||
* { |
||||
* myled = value; |
||||
* return; |
||||
* } |
||||
* }; |
||||
*
|
||||
* int main() |
||||
* { |
||||
* Wrapper wrapped; |
||||
* fp.attach(&wrapped, &Wrapper::handler); |
||||
*
|
||||
* while(1)
|
||||
* { |
||||
* fp(1); |
||||
* wait(0.2); |
||||
* fp(0); |
||||
* wait(0.2); |
||||
* } |
||||
* } |
||||
* @endcode |
||||
*/ |
||||
|
||||
/** Example using the FP Class with member FP and member function
|
||||
* @code |
||||
* #include "mbed.h" |
||||
* #include "FP.h" |
||||
*
|
||||
* DigitalOut myled(LED2); |
||||
*
|
||||
* class Wrapper |
||||
* { |
||||
* public: |
||||
* Wrapper() |
||||
* { |
||||
* fp.attach(this, &Wrapper::handler); |
||||
* } |
||||
*
|
||||
* void handler(bool value) |
||||
* { |
||||
* myled = value; |
||||
* return; |
||||
* } |
||||
*
|
||||
* FP<void,bool>fp; |
||||
* }; |
||||
*
|
||||
* int main() |
||||
* { |
||||
* Wrapper wrapped; |
||||
*
|
||||
* while(1)
|
||||
* { |
||||
* wrapped.fp(1); |
||||
* wait(0.2); |
||||
* wrapped.fp(0); |
||||
* wait(0.2); |
||||
* } |
||||
* } |
||||
* @endcode |
||||
*/ |
||||
|
||||
/**
|
||||
* @class FP |
||||
* @brief API abstraction for a Function Pointers |
||||
*/
|
||||
template<class retT, class argT> |
||||
class FP |
||||
{ |
||||
public: |
||||
/** Create the FP object
|
||||
*/
|
||||
FP(); |
||||
|
||||
/** Add a callback function to the class
|
||||
* @param item - Address of the initialized class |
||||
* @param method - Address of the member function (dont forget the scope that the function is defined in) |
||||
*/ |
||||
template<class T> |
||||
void attach(T *item, retT (T::*method)(argT)) |
||||
{ |
||||
obj_callback = (FPtrDummy *)(item); |
||||
method_callback = (retT (FPtrDummy::*)(argT))(method); |
||||
return; |
||||
} |
||||
|
||||
/** Add a callback function to the class
|
||||
* @param function - The address of a globally defined function |
||||
*/ |
||||
void attach(retT (*function)(argT)); |
||||
|
||||
/** Invoke the function attached to the class
|
||||
* @param arg - An argument that is passed into the function handler that is called |
||||
* @return The return from the function hanlder called by this class |
||||
*/ |
||||
retT operator()(argT arg) const; |
||||
|
||||
bool attached(); |
||||
|
||||
void detach(); |
||||
|
||||
private: |
||||
|
||||
// empty type used for casting
|
||||
class FPtrDummy; |
||||
|
||||
FPtrDummy *obj_callback; |
||||
|
||||
/**
|
||||
* @union Funciton |
||||
* @brief Member or global callback function |
||||
*/
|
||||
union |
||||
{ |
||||
retT (*c_callback)(argT); /*!< Footprint for a global function */ |
||||
retT (FPtrDummy::*method_callback)(argT); /*!< Footprint for a member function */ |
||||
}; |
||||
}; |
||||
|
||||
#endif |
||||
|
||||
@ -0,0 +1,526 @@
@@ -0,0 +1,526 @@
|
||||
#_______________________________________________________________________________
|
||||
#
|
||||
# edam's Arduino makefile
|
||||
#_______________________________________________________________________________
|
||||
# version 0.6dev
|
||||
#
|
||||
# Copyright (C) 2011-2014 to 2013 Tim Marston <tim@ed.am>.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#_______________________________________________________________________________
|
||||
#
|
||||
#
|
||||
# This is a general purpose makefile for use with Arduino hardware and
|
||||
# software. It is intended to be a drop-in replacement for the Arduino IDE's
|
||||
# build system. It works with the Arduino 1.0 and 1.5 software releases, on
|
||||
# GNU/Linux and OS X. To download the latest version of this makefile visit
|
||||
# the following website where you can also find documentation on it's use.
|
||||
# (The following text can only really be considered a reference.)
|
||||
#
|
||||
# http://ed.am/dev/make/arduino-mk
|
||||
#
|
||||
# To use this makefile, copy arduino.mk in to your project directory. Or, you
|
||||
# could save it somewhere (I keep mine at ~/src/arduino.mk) and create a
|
||||
# symlink to it in your project directory, named "Makefile". For example:
|
||||
#
|
||||
# $ ln -s ~/src/arduino.mk Makefile
|
||||
#
|
||||
# The Arduino software (version 1.0 or later, including the new 1.5 BETA) is
|
||||
# required. On GNU/Linux you can probably install the software from your
|
||||
# package manager. If you are using Debian (or a derivative), try `apt-get
|
||||
# install arduino`. Otherwise, you can download the Arduino software manually
|
||||
# from http://arduino.cc/. It is suggested that you install it at
|
||||
# ~/opt/arduino (or /Applications on OS X) if you are unsure.
|
||||
#
|
||||
# If you downloaded the Arduino software manually and unpacked it somewhere
|
||||
# *other* than ~/opt/arduino (or /Applications), you will need to set up the
|
||||
# ARDUINODIR environment variable to be the directory where you unpacked it.
|
||||
# (If unset, ARDUINODIR defaults to some sensible places). You could set this
|
||||
# in your ~/.profile by adding something like this:
|
||||
#
|
||||
# export ARDUINODIR=~/somewhere/arduino-1.0.5
|
||||
#
|
||||
# For each project, you will also need to set BOARD to the type of Arduino
|
||||
# you're building for. Type `make boards` for a list of acceptable values.
|
||||
# For example:
|
||||
#
|
||||
# $ export BOARD=uno
|
||||
#
|
||||
# Note that if you're using the newer 1.5 Arduino software and the board you
|
||||
# want to use is availble with different processors, you will also need to
|
||||
# specify one. For example:
|
||||
#
|
||||
# $ export BOARD=mini.atmega328
|
||||
#
|
||||
# You may also need to set SERIALDEV if your Arduino is not detected correctly.
|
||||
#
|
||||
# The presence of a .ino (or .pde) file causes the arduino.mk to automatically
|
||||
# determine values for SOURCES, TARGET and which libraries to pull-in to the
|
||||
# build (although you can still override thius by setting LIBRARIES). Any .c,
|
||||
# .cc and .cpp files in the project directory (or any "util" or "utility"
|
||||
# subdirectories) are automatically included in the build and are scanned for
|
||||
# Arduino libraries that have been #included. Note, there can only be one .ino
|
||||
# (or .pde) file in a project directory and if you want to be compatible with
|
||||
# the Arduino IDE, it should be called the same as the directory name.
|
||||
#
|
||||
# Alternatively, if you want to manually specify build variables, create a
|
||||
# Makefile that defines SOURCES and LIBRARIES and then includes arduino.mk.
|
||||
# (You don't need to define TARGET). You can also specify the BOARD here, if
|
||||
# the project has a specific one. Here is an example Makefile:
|
||||
#
|
||||
# SOURCES := main.cc other.cc
|
||||
# LIBRARIES := EEPROM
|
||||
# BOARD := pro5v
|
||||
# include ~/src/arduino.mk
|
||||
#
|
||||
# Here is a complete list of environment variables that affect the build:
|
||||
#
|
||||
# ARDUINODIR The directory where the Arduino software resides on your system.
|
||||
#
|
||||
# ARDUINOCONST The Arduino software version, as an integer, used to define the
|
||||
# ARDUINO version constant. This defaults to 100 if undefined.
|
||||
#
|
||||
# AVRDUDECONF The avrdude.conf to use. If undefined, this defaults to a guess
|
||||
# based on where avrdude is. If set empty, no avrdude.conf is
|
||||
# passed to avrdude (so the system default is used).
|
||||
#
|
||||
# AVRDUDEFLAGS Specify any additional flags for avrdude. The usual flags,
|
||||
# required to build the project, will be appended to this.
|
||||
#
|
||||
# AVRTOOLSPATH A space-separated list of directories that is searched in order
|
||||
# when looking for the avr build tools. This defaults to PATH,
|
||||
# followed by subdirectories in ARDUINODIR.
|
||||
#
|
||||
# BOARD Specify a target board type. Run `make boards` to see available
|
||||
# board types. For Arduino 1.5, you will also need to specify a
|
||||
# processor if the board supports multiple processors (see above).
|
||||
#
|
||||
# CPPFLAGS Specify any additional flags for the compiler. The usual flags,
|
||||
# required to build the project, will be appended to this.
|
||||
#
|
||||
# LINKFLAGS Specify any additional flags for the linker. The usual flags,
|
||||
# required to build the project, will be appended to this.
|
||||
#
|
||||
# LIBRARIES A list of Arduino libraries to build and include. This is set
|
||||
# automatically if a .ino (or .pde) is found.
|
||||
#
|
||||
# LIBRARYPATH A space-separated list of directories that is searched in order
|
||||
# when looking for Arduino libraries. This defaults to "libs",
|
||||
# "libraries" (in the project directory), then your sketchbook
|
||||
# "libraries" directory, then the Arduino libraries directory.
|
||||
#
|
||||
# SERIALDEV The POSIX device name of the serial device that is the Arduino.
|
||||
# If unspecified, an attempt is made to guess the name of a
|
||||
# connected Arduino's serial device, which may work in some cases.
|
||||
#
|
||||
# SOURCES A list of all source files of whatever language. The language
|
||||
# type is determined by the file extension. This is set
|
||||
# automatically if a .ino (or .pde) is found.
|
||||
#
|
||||
# TARGET The name of the target file. This is set automatically if a
|
||||
# .ino (or .pde) is found, but it is not necessary to set it
|
||||
# otherwise.
|
||||
#
|
||||
# This makefile also defines the following goals for use on the command line
|
||||
# when you run make:
|
||||
#
|
||||
# all This is the default if no goal is specified. It builds the
|
||||
# target.
|
||||
#
|
||||
# target Builds the target.
|
||||
#
|
||||
# upload Uploads the target (building it, as necessary) to an attached
|
||||
# Arduino.
|
||||
#
|
||||
# clean Deletes files created during the build.
|
||||
#
|
||||
# boards Display a list of available board names, so that you can set the
|
||||
# BOARD environment variable appropriately.
|
||||
#
|
||||
# monitor Start `screen` on the serial device. This is meant to be an
|
||||
# equivalent to the Arduino serial monitor.
|
||||
#
|
||||
# size Displays size information about the built target.
|
||||
#
|
||||
# bootloader Burns the bootloader for your board to it.
|
||||
#
|
||||
# <file> Builds the specified file, either an object file or the target,
|
||||
# from those that that would be built for the project.
|
||||
#_______________________________________________________________________________
|
||||
#
|
||||
|
||||
# default arduino software directory
|
||||
ifndef ARDUINODIR |
||||
ARDUINODIR := $(firstword $(wildcard ~/opt/arduino /usr/share/arduino \
|
||||
/Applications/Arduino.app/Contents/Resources/Java \
|
||||
$(HOME)/Applications/Arduino.app/Contents/Resources/Java))
|
||||
endif |
||||
|
||||
# check ARDUINODIR (and determine which backends are available)
|
||||
ifneq "" "$(wildcard $(ARDUINODIR)/hardware/arduino/boards.txt)" |
||||
ARDUINOBACKENDS := /
|
||||
else ifneq "" "$(wildcard $(ARDUINODIR)/hardware/arduino/avr/boards.txt)" |
||||
ARDUINOBACKENDS := /avr /sam
|
||||
else |
||||
$(error ARDUINODIR is not set correctly; arduino software not found) |
||||
endif |
||||
|
||||
# no board?
|
||||
ifndef BOARD |
||||
ifneq "$(MAKECMDGOALS)" "boards" |
||||
ifneq "$(MAKECMDGOALS)" "clean" |
||||
$(error BOARD is unset. Type 'make boards' to see possible values) |
||||
endif |
||||
endif |
||||
endif |
||||
|
||||
# obtain board parameters from the arduino boards.txt file(s)
|
||||
BOARDSFILES := $(foreach dir, $(ARDUINOBACKENDS), \
|
||||
$(ARDUINODIR)/hardware/arduino$(dir)/boards.txt)
|
||||
ifeq "$(ARDUINOBACKENDS)" "/" |
||||
readboardsparam = $(shell sed -ne "s/^$(BOARD)\\.$(1)=\(.*\)/\1/p" \
|
||||
$(BOARDSFILES))
|
||||
else |
||||
readboardsparam = $(firstword \
|
||||
$(call readboardsmenuparam,$(1),$(basename $(BOARD)),$(suffix $(BOARD))) \
|
||||
$(shell sed -ne "s/^$(basename $(BOARD))\\.$(1)=\(.*\)/\1/p" \
|
||||
$(BOARDSFILES)))
|
||||
ifneq "$(wildcard /usr/bin/perl)" "" |
||||
readboardsmenuparam = $(shell perl -ne \
|
||||
'/^$(2)\.menu\.cpu/ && s/.*$(3)\.$(1)=(.*)/\1/i && print' $(BOARDSFILES))
|
||||
else |
||||
readboardsmenuparam = $(shell sed -ne '/^$(2)\.menu\.cpu/ {' \
|
||||
-e 's/.*$(3)\.$(1)=\(.*\)/\1/p' -e '}' $(BOARDSFILES))
|
||||
endif |
||||
endif |
||||
BOARD_BUILD_MCU := $(call readboardsparam,build.mcu)
|
||||
BOARD_BUILD_FCPU := $(call readboardsparam,build.f_cpu)
|
||||
BOARD_BUILD_VARIANT := $(call readboardsparam,build.variant)
|
||||
BOARD_BUILD_CORE := $(call readboardsparam,build.core)
|
||||
BOARD_BUILD_BOARD := $(call readboardsparam,build.board)
|
||||
BOARD_UPLOAD_SPEED := $(call readboardsparam,upload.speed)
|
||||
BOARD_UPLOAD_PROTOCOL := $(call readboardsparam,upload.protocol)
|
||||
BOARD_USB_VID := $(call readboardsparam,build.vid)
|
||||
BOARD_USB_PID := $(call readboardsparam,build.pid)
|
||||
BOARD_BOOTLOADER_UNLOCK := $(call readboardsparam,bootloader.unlock_bits)
|
||||
BOARD_BOOTLOADER_LOCK := $(call readboardsparam,bootloader.lock_bits)
|
||||
BOARD_BOOTLOADER_LFUSES := $(call readboardsparam,bootloader.low_fuses)
|
||||
BOARD_BOOTLOADER_HFUSES := $(call readboardsparam,bootloader.high_fuses)
|
||||
BOARD_BOOTLOADER_EFUSES := $(call readboardsparam,bootloader.extended_fuses)
|
||||
BOARD_BOOTLOADER_PATH := $(call readboardsparam,bootloader.path)
|
||||
BOARD_BOOTLOADER_FILE := $(call readboardsparam,bootloader.file)
|
||||
|
||||
# invalid board?
|
||||
ifeq "$(BOARD_BUILD_MCU)" "" |
||||
ifneq "$(MAKECMDGOALS)" "boards" |
||||
ifneq "$(MAKECMDGOALS)" "clean" |
||||
$(error BOARD is invalid. Type 'make boards' to see possible values) |
||||
endif |
||||
endif |
||||
endif |
||||
|
||||
# obtain preferences from the IDE's preferences.txt
|
||||
PREFERENCESFILE := $(firstword $(wildcard \
|
||||
$(HOME)/.arduino/preferences.txt $(HOME)/Library/Arduino/preferences.txt))
|
||||
ifneq "$(PREFERENCESFILE)" "" |
||||
readpreferencesparam = $(shell sed -ne "s/$(1)=\(.*\)/\1/p" $(PREFERENCESFILE))
|
||||
SKETCHBOOKDIR := $(call readpreferencesparam,sketchbook.path)
|
||||
endif |
||||
|
||||
# arduino directories
|
||||
ARDUINOBACKENDDIR := $(strip $(foreach dir, $(ARDUINOBACKENDS), \
|
||||
$(if $(shell grep ^$(basename $(BOARD))\\.name \
|
||||
$(ARDUINODIR)/hardware/arduino$(dir)/boards.txt), \
|
||||
$(ARDUINODIR)/hardware/arduino$(dir))))
|
||||
ARDUINOBACKENDARCH=AVR
|
||||
ARDUINOCOREDIR := $(ARDUINOBACKENDDIR)/cores/$(BOARD_BUILD_CORE)
|
||||
|
||||
# default library path (places to look for libraries)
|
||||
LIBRARYPATH ?= libraries libs $(SKETCHBOOKDIR)/libraries \
|
||||
$(ARDUINODIR)/libraries $(ARDUINOBACKENDDIR)/libraries
|
||||
|
||||
# auto mode?
|
||||
INOFILE := $(wildcard *.ino *.pde)
|
||||
ifdef INOFILE |
||||
ifneq "$(words $(INOFILE))" "1" |
||||
$(error There is more than one .pde or .ino file in this directory!) |
||||
endif |
||||
|
||||
# automatically determine sources and target
|
||||
TARGET := $(basename $(INOFILE))
|
||||
SOURCES := $(INOFILE) \
|
||||
$(wildcard *.c *.cc *.cpp *.C *.s *.S) \
|
||||
$(wildcard $(addprefix util/, *.c *.cc *.cpp *.C *.s *.S)) \
|
||||
$(wildcard $(addprefix utility/, *.c *.cc *.cpp *.C *.s *.S))
|
||||
|
||||
# automatically determine library directories (to pull library sources in from)
|
||||
# by matching included headers in project sources to headers that exist in the
|
||||
# roots of any library directories, giving priority to libraries in the order
|
||||
# they're in LIBRARYPATH, and then to the alphabetically-greater named library
|
||||
# (this is a really stupid way of doing it, but it's how the IDE works -- if
|
||||
# it's causing problems, you can override it by setting LIBRARIES manually)
|
||||
INCLUDEDHEADERS := $(shell sed -ne '/^[ \t]*\#[ \t]*include[ \t<"]/ {' \
|
||||
-e 's/^.*[<"]\(.*\)[>"].*/\1/p' -e '}' $(SOURCES))
|
||||
reverse = $(if $(1),$(call reverse,$(wordlist 2,$(words $(1)),$(1)))) \
|
||||
$(firstword $(1))
|
||||
LIBRARYHEADERS := $(foreach dir, $(LIBRARYPATH), \
|
||||
$(call reverse, $(sort $(wildcard $(dir)/*))))
|
||||
LIBRARYHEADERS := $(foreach dir, $(LIBRARYHEADERS), $(wildcard $(dir)/*.h))
|
||||
LIBRARYDIRS := $(foreach hdr, $(INCLUDEDHEADERS), $(patsubst %/$(hdr), %, \
|
||||
$(firstword $(filter %/$(hdr), $(LIBRARYHEADERS)))))
|
||||
|
||||
endif |
||||
|
||||
# expand LIBRARYDIRS (initialised from LIBRARIES, if specified)
|
||||
ifneq "$(LIBRARIES)" "" |
||||
LIBRARYDIRS := $(foreach lib, $(LIBRARIES), \
|
||||
$(firstword $(wildcard $(addsuffix /$(lib), $(LIBRARYPATH)))))
|
||||
$(info LIBRARIES=$(LIBRARIES) LIBRARYDIRS=$(LIBRARYDIRS)) |
||||
endif |
||||
LIBRARYDIRS := $(LIBRARYDIRS) \
|
||||
$(addsuffix /utility, $(LIBRARYDIRS)) \
|
||||
$(addsuffix /src, $(LIBRARYDIRS))
|
||||
|
||||
|
||||
# files
|
||||
TARGET := $(if $(TARGET),$(TARGET),a.out)
|
||||
OBJECTS := $(addsuffix .o, $(basename $(SOURCES)))
|
||||
DEPFILES := $(patsubst %, .dep/%.dep, $(SOURCES))
|
||||
ARDUINOLIB := .lib/arduino.a
|
||||
ARDUINOLIBOBJS := $(foreach dir, $(ARDUINOCOREDIR) $(LIBRARYDIRS), \
|
||||
$(patsubst %, .lib/%.o, $(wildcard $(addprefix $(dir)/, \
|
||||
*.c *.cc *.cpp *.C *.s *.S))))
|
||||
BOOTLOADERHEX := $(addprefix \
|
||||
$(ARDUINOBACKENDDIR)/bootloaders/$(BOARD_BOOTLOADER_PATH)/, \
|
||||
$(BOARD_BOOTLOADER_FILE))
|
||||
|
||||
# software
|
||||
BUILDTOOLSPATH ?= $(subst :, , $(PATH)) $(ARDUINODIR)/hardware/tools \
|
||||
$(ARDUINODIR)/hardware/tools/avr/bin
|
||||
findsoftware = $(firstword $(wildcard $(addsuffix /$(1), $(BUILDTOOLSPATH))))
|
||||
CC := $(call findsoftware,avr-gcc)
|
||||
CXX := $(call findsoftware,avr-g++)
|
||||
LD := $(call findsoftware,avr-ld)
|
||||
AR := $(call findsoftware,avr-ar)
|
||||
AS := $(call findsoftware,avr-as)
|
||||
OBJCOPY := $(call findsoftware,avr-objcopy)
|
||||
AVRDUDE := $(call findsoftware,avrdude)
|
||||
AVRSIZE := $(call findsoftware,avr-size)
|
||||
|
||||
# default arduino version
|
||||
ARDUINOCONST ?= $(if $(filter /, $(ARDUINOBACKENDS)),100,150)
|
||||
|
||||
# default serial device to a poor guess (something that might be an arduino)
|
||||
SERIALDEVGUESS := 0
|
||||
ifndef SERIALDEV |
||||
SERIALDEV := $(firstword $(wildcard \
|
||||
/dev/ttyACM? /dev/ttyUSB? /dev/tty.usbserial* /dev/tty.usbmodem*))
|
||||
SERIALDEVGUESS := 1
|
||||
endif |
||||
|
||||
# avrdude confifuration
|
||||
ifeq "$(AVRDUDECONF)" "" |
||||
ifeq "$(AVRDUDE)" "$(ARDUINODIR)/hardware/tools/avr/bin/avrdude" |
||||
AVRDUDECONF := $(ARDUINODIR)/hardware/tools/avr/etc/avrdude.conf
|
||||
else |
||||
AVRDUDECONF := $(wildcard $(AVRDUDE).conf)
|
||||
endif |
||||
endif |
||||
|
||||
# flags
|
||||
CPPFLAGS += -Os -Wall -fno-exceptions -ffunction-sections -fdata-sections
|
||||
CPPFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
|
||||
CPPFLAGS += -fpermissive -mmcu=$(BOARD_BUILD_MCU)
|
||||
CPPFLAGS += -DF_CPU=$(BOARD_BUILD_FCPU) -DARDUINO=$(ARDUINOCONST)
|
||||
CPPFLAGS += -DARDUINO_$(BOARD_BUILD_BOARD) -DARDUINO_ARCH_$(ARDUINOBACKENDARCH)
|
||||
CPPFLAGS += -DUSB_VID=$(BOARD_USB_VID) -DUSB_PID=$(BOARD_USB_PID)
|
||||
CPPFLAGS += -I. -Iutil -Iutility -I $(ARDUINOCOREDIR)
|
||||
CPPFLAGS += -I $(ARDUINOBACKENDDIR)/variants/$(BOARD_BUILD_VARIANT)/
|
||||
CPPFLAGS += $(addprefix -I , $(LIBRARYDIRS))
|
||||
CPPDEPFLAGS = -MMD -MP -MF .dep/$<.dep
|
||||
CPPINOFLAGS := -x c++ -include $(ARDUINOCOREDIR)/Arduino.h
|
||||
AVRDUDEFLAGS += $(addprefix -C , $(AVRDUDECONF)) -DV
|
||||
AVRDUDEFLAGS += -p$(BOARD_BUILD_MCU) -P$(SERIALDEV) -c$(BOARD_UPLOAD_PROTOCOL)
|
||||
AVRDUDEFLAGS += $(addprefix -b, $(BOARD_UPLOAD_SPEED))
|
||||
LINKFLAGS += -Os -Wl,--gc-sections -mmcu=$(BOARD_BUILD_MCU)
|
||||
|
||||
# figure out which arg to use with stty (for OS X, GNU and busybox stty)
|
||||
STTYFARG := $(shell stty --help 2>&1 | \
|
||||
grep -q 'illegal option' && echo -f || echo -F)
|
||||
|
||||
# include dependencies
|
||||
ifneq "$(MAKECMDGOALS)" "clean" |
||||
-include $(DEPFILES) |
||||
endif |
||||
|
||||
# default rule
|
||||
.DEFAULT_GOAL := all
|
||||
|
||||
#_______________________________________________________________________________
|
||||
# RULES
|
||||
|
||||
.PHONY: all target upload clean boards monitor size bootloader |
||||
|
||||
all: target |
||||
|
||||
target: $(TARGET).hex |
||||
|
||||
upload: target |
||||
@echo "\nUploading to board..."
|
||||
@test -n "$(SERIALDEV)" || { \
|
||||
echo "error: SERIALDEV could not be determined automatically." >&2; \
|
||||
exit 1; }
|
||||
@test 0 -eq $(SERIALDEVGUESS) || { \
|
||||
echo "*GUESSING* at serial device:" $(SERIALDEV); \
|
||||
echo; }
|
||||
ifeq "$(BOARD_BOOTLOADER_PATH)" "caterina" |
||||
stty $(STTYFARG) $(SERIALDEV) speed 1200
|
||||
sleep 1
|
||||
else ifeq "" "$(filter net:% usb:%,$(SERIALDEV))" |
||||
stty $(STTYFARG) $(SERIALDEV) hupcl
|
||||
endif |
||||
$(AVRDUDE) $(AVRDUDEFLAGS) -U flash:w:$(TARGET).hex:i
|
||||
|
||||
clean: |
||||
rm -f $(OBJECTS)
|
||||
rm -f $(TARGET).elf $(TARGET).hex $(ARDUINOLIB) *~
|
||||
rm -rf .lib .dep
|
||||
|
||||
boards: |
||||
@echo "Available BOARD values:"
|
||||
@sed -ne '/[[:alnum:]]*\.name=/p' \
|
||||
-e '/^[[:alnum:]]*\.menu\.cpu\.[[:alnum:]]*=/p' $(BOARDSFILES) | \
|
||||
sed -e 's/\([[:alnum:]]*\)\.name=\(.*\)/\1 \2/' \
|
||||
-e 's/^.*\(\.[[:alnum:]]*\)=\(.*\)/ \1 --\2/' \
|
||||
-e 's/\(.\{19\}\) *\(.*\)/ \1 \2/' -e 's/--/ ...with /'
|
||||
ifneq "$(ARDUINOBACKENDS)" "/" |
||||
@echo
|
||||
@echo "NOTE: where a board supports multiple CPUs, you must specify" \
|
||||
"one. For example,"
|
||||
@echo "'uno' is OK, and so is 'pro.16mhzatmega328'. But 'pro', on" \
|
||||
"its own, is not."
|
||||
endif |
||||
|
||||
monitor: |
||||
@test -n "$(SERIALDEV)" || { \
|
||||
echo "error: SERIALDEV could not be determined automatically." >&2; \
|
||||
exit 1; }
|
||||
@test -n `which screen` || { \
|
||||
echo "error: can't find GNU screen, you might need to install it." >&2 \
|
||||
exit 1; }
|
||||
@test 0 -eq $(SERIALDEVGUESS) || { \
|
||||
echo "*GUESSING* at serial device:" $(SERIALDEV); \
|
||||
echo; }
|
||||
screen $(SERIALDEV)
|
||||
|
||||
size: $(TARGET).elf |
||||
echo "\n" && $(AVRSIZE) --format=avr --mcu=$(BOARD_BUILD_MCU) $(TARGET).elf
|
||||
|
||||
bootloader: |
||||
@echo "Burning bootloader to board..."
|
||||
@test -n "$(SERIALDEV)" || { \
|
||||
echo "error: SERIALDEV could not be determined automatically." >&2; \
|
||||
exit 1; }
|
||||
@test 0 -eq $(SERIALDEVGUESS) || { \
|
||||
echo "*GUESSING* at serial device:" $(SERIALDEV); \
|
||||
echo; }
|
||||
stty $(STTYFARG) $(SERIALDEV) hupcl
|
||||
$(AVRDUDE) $(AVRDUDEFLAGS) -U lock:w:$(BOARD_BOOTLOADER_UNLOCK):m
|
||||
$(AVRDUDE) $(AVRDUDEFLAGS) -eU lfuse:w:$(BOARD_BOOTLOADER_LFUSES):m
|
||||
$(AVRDUDE) $(AVRDUDEFLAGS) -U hfuse:w:$(BOARD_BOOTLOADER_HFUSES):m
|
||||
ifneq "$(BOARD_BOOTLOADER_EFUSES)" "" |
||||
$(AVRDUDE) $(AVRDUDEFLAGS) -U efuse:w:$(BOARD_BOOTLOADER_EFUSES):m
|
||||
endif |
||||
ifneq "$(BOOTLOADERHEX)" "" |
||||
$(AVRDUDE) $(AVRDUDEFLAGS) -U flash:w:$(BOOTLOADERHEX):i
|
||||
endif |
||||
$(AVRDUDE) $(AVRDUDEFLAGS) -U lock:w:$(BOARD_BOOTLOADER_LOCK):m
|
||||
|
||||
# building the target
|
||||
|
||||
$(TARGET).hex: $(TARGET).elf |
||||
$(OBJCOPY) -O ihex -R .eeprom $< $@
|
||||
|
||||
.INTERMEDIATE: $(TARGET).elf |
||||
|
||||
$(TARGET).elf: $(ARDUINOLIB) $(OBJECTS) |
||||
$(CC) $(LINKFLAGS) $(OBJECTS) $(ARDUINOLIB) -lm -o $@
|
||||
|
||||
%.o: %.ino |
||||
mkdir -p .dep/$(pathsubst ./%,%,$(dir $<))
|
||||
$(COMPILE.cpp) $(CPPDEPFLAGS) -o $@ $(CPPINOFLAGS) $<
|
||||
|
||||
%.o: %.pde |
||||
mkdir -p .dep/$(pathsubst ./%,%,$(dir $<))
|
||||
$(COMPILE.cpp) $(CPPDEPFLAGS) -o $@ $(CPPINOFLAGS) $<
|
||||
|
||||
%.o: %.c |
||||
mkdir -p .dep/$(pathsubst ./%,%,$(dir $<))
|
||||
$(COMPILE.c) $(CPPDEPFLAGS) -o $@ $<
|
||||
|
||||
%.o: %.cpp |
||||
mkdir -p .dep/$(pathsubst ./%,%,$(dir $<))
|
||||
$(COMPILE.cpp) $(CPPDEPFLAGS) -o $@ $<
|
||||
|
||||
%.o: %.cc |
||||
mkdir -p .dep/$(pathsubst ./%,%,$(dir $<))
|
||||
$(COMPILE.cpp) $(CPPDEPFLAGS) -o $@ $<
|
||||
|
||||
%.o: %.C |
||||
mkdir -p .dep/$(pathsubst ./%,%,$(dir $<))
|
||||
$(COMPILE.cpp) $(CPPDEPFLAGS) -o $@ $<
|
||||
|
||||
%.o: %.S |
||||
mkdir -p .dep/$(pathsubst ./%,%,$(dir $<))
|
||||
$(COMPILE.S) $(CPPDEPFLAGS) -o $@ $<
|
||||
|
||||
# building the arduino library
|
||||
|
||||
$(ARDUINOLIB): $(ARDUINOLIBOBJS) |
||||
$(AR) rcs $@ $?
|
||||
|
||||
.lib/%.c.o: %.c |
||||
mkdir -p $(dir $@)
|
||||
$(COMPILE.c) -o $@ $<
|
||||
|
||||
.lib/%.cpp.o: %.cpp |
||||
mkdir -p $(dir $@)
|
||||
$(COMPILE.cpp) -o $@ $<
|
||||
|
||||
.lib/%.cc.o: %.cc |
||||
mkdir -p $(dir $@)
|
||||
$(COMPILE.cpp) -o $@ $<
|
||||
|
||||
.lib/%.C.o: %.C |
||||
mkdir -p $(dir $@)
|
||||
$(COMPILE.cpp) -o $@ $<
|
||||
|
||||
.lib/%.s.o: %.s |
||||
mkdir -p $(dir $@)
|
||||
$(COMPILE.s) -o $@ $<
|
||||
|
||||
.lib/%.S.o: %.S |
||||
mkdir -p $(dir $@)
|
||||
$(COMPILE.S) -o $@ $<
|
||||
|
||||
# Local Variables:
|
||||
# mode: makefile
|
||||
# tab-width: 4
|
||||
# End:
|
||||
@ -0,0 +1,110 @@
@@ -0,0 +1,110 @@
|
||||
#! /bin/bash |
||||
# |
||||
# Flash an AVR with optiboot using the esp-link built-in programmer |
||||
# Basically we first reset the AVR and get in sync, and then send the hex file |
||||
# |
||||
# ---------------------------------------------------------------------------- |
||||
# "THE BEER-WARE LICENSE" (Revision 42): |
||||
# Thorsten von Eicken wrote this file. As long as you retain |
||||
# this notice you can do whatever you want with this stuff. If we meet some day, |
||||
# and you think this stuff is worth it, you can buy me a beer in return. |
||||
# ---------------------------------------------------------------------------- |
||||
|
||||
show_help() { |
||||
cat <<EOT |
||||
Usage: ${0##*/} [-options...] hostname sketch.hex |
||||
Flash the AVR running optiboot attached to esp-link with the sketch. |
||||
-v Be verbose |
||||
-h show this help |
||||
|
||||
Example: ${0##*/} -v esp-link mysketch.hex |
||||
${0##*/} 192.168.4.1 mysketch.hex |
||||
EOT |
||||
} |
||||
|
||||
if ! which curl >/dev/null; then |
||||
echo "ERROR: Cannot find curl: it is required for this script." >&2 |
||||
exit 1 |
||||
fi |
||||
|
||||
start=`date +%s` |
||||
|
||||
# ===== Parse arguments |
||||
|
||||
verbose= |
||||
|
||||
while getopts "hvx:" opt; do |
||||
case "$opt" in |
||||
h) show_help; exit 0 ;; |
||||
v) verbose=1 ;; |
||||
x) foo="$OPTARG" ;; |
||||
'?') show_help >&2; exit 1 ;; |
||||
esac |
||||
done |
||||
|
||||
# Shift off the options and optional --. |
||||
shift "$((OPTIND-1))" |
||||
|
||||
# Get the fixed arguments |
||||
if [[ $# != 2 ]]; then |
||||
show_help >&2 |
||||
exit 1 |
||||
fi |
||||
hostname=$1 |
||||
hex=$2 |
||||
|
||||
re='[-A-Za-z0-9.]+' |
||||
if [[ ! "$hostname" =~ $re ]]; then |
||||
echo "ERROR: hostname ${hostname} is not a valid hostname or ip address" >&2 |
||||
exit 1 |
||||
fi |
||||
|
||||
if [[ ! -r "$hex" ]]; then |
||||
echo "ERROR: cannot read hex file ($hex)" >&2 |
||||
exit 1 |
||||
fi |
||||
|
||||
# ===== Get AVR in sync |
||||
|
||||
[[ -n "$verbose" ]] && echo "Resetting AVR with http://$hostname/pgm/sync" >&2 |
||||
v=; [[ -n "$verbose" ]] && v=-v |
||||
sync=`curl -m 10 $v -s -w '%{http_code}' -XPOST "http://$hostname/pgm/sync"` |
||||
if [[ $? != 0 || "$sync" != 204 ]]; then |
||||
echo "Error resetting AVR" >&2 |
||||
exit 1 |
||||
fi |
||||
|
||||
while true; do |
||||
sync=`curl -m 10 $v -s "http://$hostname/pgm/sync"` |
||||
if [[ $? != 0 ]]; then |
||||
echo "Error checking sync" >&2 |
||||
exit 1 |
||||
fi |
||||
case "$sync" in |
||||
SYNC*) |
||||
echo "AVR in $sync" >&2 |
||||
break;; |
||||
"NOT READY"*) |
||||
[[ -n "$verbose" ]] && echo " Waiting for sync..." >&2 |
||||
;; |
||||
*) |
||||
echo "Error checking sync: $sync" >&2 |
||||
exit 1 |
||||
;; |
||||
esac |
||||
sleep 0.1 |
||||
done |
||||
|
||||
# ===== Send HEX file |
||||
|
||||
[[ -n "$verbose" ]] && echo "Sending HEX file for programming" >&2 |
||||
sync=`curl -m 10 $v -s -g -d "@$hex" "http://$hostname/pgm/upload"` |
||||
echo $sync |
||||
if [[ $? != 0 || ! "$sync" =~ ^Success ]]; then |
||||
echo "Error programming AVR" >&2 |
||||
exit 1 |
||||
fi |
||||
|
||||
sec=$(( `date +%s` - $start )) |
||||
echo "Success, took $sec seconds" >&2 |
||||
exit 0 |
||||
@ -0,0 +1,50 @@
@@ -0,0 +1,50 @@
|
||||
demo.o: demo.ino \ |
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/Arduino.h \ |
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/binary.h \ |
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/WCharacter.h \ |
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/WString.h \ |
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/HardwareSerial.h \ |
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/Stream.h \ |
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/Print.h \ |
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/Printable.h \ |
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/new.h \ |
||||
/home/arduino/arduino-1.0.5/hardware/arduino//variants/standard/pins_arduino.h \ |
||||
../../../espduino/espduino.h \ |
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/HardwareSerial.h \ |
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/Arduino.h \ |
||||
../../../espduino/FP.h ../../../espduino/crc16.h \ |
||||
../../../espduino/ringbuf.h ../../../espduino/rest.h |
||||
|
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/Arduino.h: |
||||
|
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/binary.h: |
||||
|
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/WCharacter.h: |
||||
|
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/WString.h: |
||||
|
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/HardwareSerial.h: |
||||
|
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/Stream.h: |
||||
|
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/Print.h: |
||||
|
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/Printable.h: |
||||
|
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/new.h: |
||||
|
||||
/home/arduino/arduino-1.0.5/hardware/arduino//variants/standard/pins_arduino.h: |
||||
|
||||
../../../espduino/espduino.h: |
||||
|
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/HardwareSerial.h: |
||||
|
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/Arduino.h: |
||||
|
||||
../../../espduino/FP.h: |
||||
|
||||
../../../espduino/crc16.h: |
||||
|
||||
../../../espduino/ringbuf.h: |
||||
|
||||
../../../espduino/rest.h: |
||||
@ -0,0 +1,50 @@
@@ -0,0 +1,50 @@
|
||||
temperature.o: temperature.ino \ |
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/Arduino.h \ |
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/binary.h \ |
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/WCharacter.h \ |
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/WString.h \ |
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/HardwareSerial.h \ |
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/Stream.h \ |
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/Print.h \ |
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/Printable.h \ |
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/new.h \ |
||||
/home/arduino/arduino-1.0.5/hardware/arduino//variants/standard/pins_arduino.h \ |
||||
../../../espduino/espduino.h \ |
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/HardwareSerial.h \ |
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/Arduino.h \ |
||||
../../../espduino/FP.h ../../../espduino/crc16.h \ |
||||
../../../espduino/ringbuf.h ../../../espduino/rest.h |
||||
|
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/Arduino.h: |
||||
|
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/binary.h: |
||||
|
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/WCharacter.h: |
||||
|
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/WString.h: |
||||
|
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/HardwareSerial.h: |
||||
|
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/Stream.h: |
||||
|
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/Print.h: |
||||
|
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/Printable.h: |
||||
|
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/new.h: |
||||
|
||||
/home/arduino/arduino-1.0.5/hardware/arduino//variants/standard/pins_arduino.h: |
||||
|
||||
../../../espduino/espduino.h: |
||||
|
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/HardwareSerial.h: |
||||
|
||||
/home/arduino/arduino-1.0.5/hardware/arduino//cores/arduino/Arduino.h: |
||||
|
||||
../../../espduino/FP.h: |
||||
|
||||
../../../espduino/crc16.h: |
||||
|
||||
../../../espduino/ringbuf.h: |
||||
|
||||
../../../espduino/rest.h: |
||||
@ -0,0 +1,8 @@
@@ -0,0 +1,8 @@
|
||||
LIBRARYPATH = $(ARDUINODIR)/libraries ../../..
|
||||
LIBRARIES = espduino
|
||||
CPPFLAGS =
|
||||
SERIALDEV = net:esp-link:23
|
||||
include ../arduino.mk |
||||
|
||||
run: upload size |
||||
nc esp-link 23
|
||||
@ -0,0 +1,5 @@
@@ -0,0 +1,5 @@
|
||||
Simple demo |
||||
=========== |
||||
|
||||
**WARNING: this example has not been updated for EL-Client!** |
||||
|
||||
@ -0,0 +1,656 @@
@@ -0,0 +1,656 @@
|
||||
:100000000C9463000C948B000C948B000C948B006C |
||||
:100010000C948B000C948B000C948B000C948B0034 |
||||
:100020000C948B000C948B000C948B000C948B0024 |
||||
:100030000C948B000C948B000C948B000C948B0014 |
||||
:100040000C94EE060C948B000C94D9070C942708A2 |
||||
:100050000C948B000C948B000C948B000C948B00F4 |
||||
:100060000C948B000C948B000000000024002700EF |
||||
:100070002A0000000000250028002B0000000000DE |
||||
:1000800023002600290004040404040404040202DA |
||||
:100090000202020203030303030301020408102007 |
||||
:1000A0004080010204081020010204081020000012 |
||||
:1000B0000007000201000003040600000000000029 |
||||
:1000C00000001505930911241FBECFEFD8E0DEBF55 |
||||
:1000D000CDBF12E0A0E0B1E0E2E3F7E202C005909C |
||||
:1000E0000D92A83AB107D9F715E0A8EAB2E001C02D |
||||
:1000F0001D92A339B107E1F710E0C6ECD0E004C0CF |
||||
:100100002297FE010E945C13C23CD107C9F70E94EE |
||||
:10011000E9090C9497130C940000CF93DF93BC0172 |
||||
:100120008230910510F462E070E0A0919105B091E9 |
||||
:100130009205ED0140E050E0E0E0F0E021C0888170 |
||||
:1001400099818617970769F48A819B81309719F006 |
||||
:100150009383828304C09093920580939105FE015E |
||||
:1001600034C06817790738F44115510519F0841720 |
||||
:10017000950708F4AC01FE018A819B819C01E9018D |
||||
:100180002097E9F641155105A9F1CA01861B970B85 |
||||
:10019000049708F4BA01E0E0F0E02AC08D919C9148 |
||||
:1001A000119784179507F9F46417750781F412966F |
||||
:1001B0008D919C911397309719F09383828304C09B |
||||
:1001C0009093920580939105FD0132964CC0CA012F |
||||
:1001D000861B970BFD01E80FF91F6193719302973E |
||||
:1001E0008D939C9340C0FD01828193819C01D90134 |
||||
:1001F0001097A1F680918F0590919005892B41F47D |
||||
:1002000080919302909194029093900580938F0532 |
||||
:1002100040919502509196024115510541F44DB718 |
||||
:100220005EB78091910290919202481B590B2091E8 |
||||
:100230008F0530919005CA01821B930B8617970793 |
||||
:1002400080F0AB014E5F5F4F8417950750F0420F6F |
||||
:10025000531F5093900540938F05F901619371935B |
||||
:1002600002C0E0E0F0E0CF01DF91CF910895CF939D |
||||
:10027000DF93009709F450C0EC0122971B821A8289 |
||||
:10028000A0919105B0919205109709F140E050E0DE |
||||
:10029000AC17BD0708F1BB83AA83FE012191319100 |
||||
:1002A000E20FF31FAE17BF0779F48D919C91119760 |
||||
:1002B000280F391F2E5F3F4F3983288312968D9167 |
||||
:1002C0009C9113979B838A834115510571F4D093B8 |
||||
:1002D0009205C093910520C012968D919C91139721 |
||||
:1002E000AD01009711F0DC01D3CFFA01D383C283B3 |
||||
:1002F00021913191E20FF31FCE17DF0769F4888156 |
||||
:100300009981280F391F2E5F3F4FFA0131832083D7 |
||||
:100310008A819B8193838283DF91CF910895A0E0AE |
||||
:10032000B0E0E5E9F1E00C9462136C01009729F468 |
||||
:10033000CB010E948D006C01C1C08EEF882E8FEF23 |
||||
:10034000982E8C0C9D1C8601060F171F0815190589 |
||||
:1003500008F4B2C0F401A081B181A617B707B8F0C4 |
||||
:10036000A530B10508F4AAC0CD01049786179707F8 |
||||
:1003700008F4A4C01297A61BB70BF801A193B19380 |
||||
:10038000D4016D937C93CF010E94370197C07B010C |
||||
:10039000EA1AFB0AEEEFFFEFEE0EFF1E36016A0EC1 |
||||
:1003A0007B1EC0919105D0919205AA24BB244424C0 |
||||
:1003B00055244AC0C615D705E1F5488159814E1527 |
||||
:1003C0005F05B8F1CA0104978E159F05B0F4129627 |
||||
:1003D000A40FB51FF401B183A0832A813B8141148E |
||||
:1003E000510431F0D20113963C932E93129766C0BC |
||||
:1003F000309392052093910561C08A819B81F80119 |
||||
:1004000093838283425050404E195F095183408349 |
||||
:100410004114510431F0D20113961C930E9312979C |
||||
:1004200004C01093920500939105F40171836083D9 |
||||
:1004300045C088819981A816B90608F45C012E018F |
||||
:100440008A819B819C01E901209709F0B3CF8091BB |
||||
:100450008F059091900586159705E9F4A616B706C5 |
||||
:10046000D0F420919502309196022115310541F486 |
||||
:100470002DB73EB78091910290919202281B390BC3 |
||||
:1004800002171307C8F41093900500938F05D40149 |
||||
:100490006D937C9313C0CB010E948D00EC010097FB |
||||
:1004A00059F0F40140815181B6010E946402C601F5 |
||||
:1004B0000E9437016E0102C0CC24DD24C601CDB7F5 |
||||
:1004C000DEB7E0E10C947E13FB01DC0102C0019079 |
||||
:1004D0000D9241505040D8F70895FB01DC01019086 |
||||
:1004E0000D920020E1F70895AEE0B0E0EAE7F2E017 |
||||
:1004F0000C946E130D891E8986E08C831A83098300 |
||||
:100500008FEF9FE79E838D839E01275E3F4FCE0135 |
||||
:1005100001966F89788DA9010E9498022F813885F4 |
||||
:10052000020F131FF80110822E96E4E00C948A1338 |
||||
:10053000ABE0B0E0EEE9F2E00C9460133C012B017B |
||||
:100540005A01FC0117821682838181FD03C06FEF7F |
||||
:100550007FEFC6C19AE0892E1E010894211C311C30 |
||||
:10056000F3012381F20123FD859123FF81912F0166 |
||||
:10057000882309F4B2C1853239F423FD859123FF24 |
||||
:1005800081912F01853229F490E0B3010E948B0400 |
||||
:10059000E7CF982FFF24EE249924FFE1FF15D0F038 |
||||
:1005A0009B3269F09C3228F4903259F0933291F4E6 |
||||
:1005B0000EC09D3249F0903369F441E024C052E00E |
||||
:1005C000F52A84E0F82A28C098E0F92A25C0E0E15D |
||||
:1005D000FE2A22C0F7FC29C0892F80538A3070F48C |
||||
:1005E000F6FE05C0989C902C1124980E15C0E89C2E |
||||
:1005F000E02C1124E80EF0E2FF2A0EC09E3229F40E |
||||
:10060000F6FC6BC140E4F42A07C09C3619F450E8AC |
||||
:10061000F52A02C0983649F4F20123FD959123FF93 |
||||
:1006200091912F01992309F0B8CF892F85548330F8 |
||||
:1006300018F08052833038F444E050E0A40EB51E28 |
||||
:100640005FE359830FC0933631F0933779F09335D8 |
||||
:1006500009F056C020C0F5018081898342E050E056 |
||||
:10066000A40EB51E610101E010E012C0F501C080CA |
||||
:10067000D180F6FC03C06FEF7FEF02C0692D70E000 |
||||
:1006800042E050E0A40EB51EC6010E9480048C0119 |
||||
:100690005FE7F52214C0F501C080D180F6FC03C0ED |
||||
:1006A0006FEF7FEF02C0692D70E042E050E0A40ED2 |
||||
:1006B000B51EC6010E9475048C0150E8F52AF3FEB0 |
||||
:1006C00007C01AC080E290E0B3010E948B04EA9454 |
||||
:1006D0008E2D90E008171907A8F30EC0F601F7FC5D |
||||
:1006E0008591F7FE81916F0190E0B3010E948B0428 |
||||
:1006F000E110EA94015010400115110579F7EAC0A4 |
||||
:10070000943611F0993669F5F7FE08C0F50120819D |
||||
:1007100031814281538184E090E00AC0F5018081FB |
||||
:1007200091819C01442737FD4095542F82E090E051 |
||||
:10073000A80EB91E9FE6F92257FF09C050954095B3 |
||||
:10074000309521953F4F4F4F5F4FE0E8FE2ACA0199 |
||||
:10075000B901A1012AE030E00E94B704D82ED218D6 |
||||
:1007600040C0953729F41F2D1F7E2AE030E01DC0C0 |
||||
:100770001F2D197F9F3661F0903720F4983509F0CE |
||||
:10078000ACC00FC0903739F0983709F0A6C004C04C |
||||
:1007900028E030E00AC0106114FD146020E130E070 |
||||
:1007A00004C014FD166020E132E017FF08C0F50117 |
||||
:1007B000608171818281938144E050E008C0F5013D |
||||
:1007C00080819181BC0180E090E042E050E0A40E85 |
||||
:1007D000B51EA1010E94B704D82ED2188FE7F82EBB |
||||
:1007E000F122F6FE0BC05EEFF522D91438F4F4FEC8 |
||||
:1007F00007C0F2FC05C08FEEF82202C01D2D01C01B |
||||
:10080000192DF4FE0DC0FE01ED0DF11D8081803328 |
||||
:1008100019F499EEF92208C01F5FF2FE05C003C06B |
||||
:100820008F2D867809F01F5F0F2DF3FC14C0F0FEAA |
||||
:100830000FC01E1510F09D2C0BC09D2C9E0C911A04 |
||||
:100840001E2D06C080E290E0B3010E948B041F5F62 |
||||
:100850001E15C0F304C01E1510F4E11A01C0EE24E9 |
||||
:1008600004FF0FC080E390E0B3010E948B0402FFFD |
||||
:100870001DC001FD03C088E790E00EC088E590E050 |
||||
:100880000BC0802F867891F001FF02C08BE201C07F |
||||
:1008900080E2F7FC8DE290E0B3010E948B0406C079 |
||||
:1008A00080E390E0B3010E948B049A94D914C0F3C2 |
||||
:1008B000DA94F101ED0DF11D808190E0B3010E9409 |
||||
:1008C0008B04DD20A9F706C080E290E0B3010E940E |
||||
:1008D0008B04EA94EE20C1F743CEF3016681778161 |
||||
:1008E000CB012B96E2E10C947C13FC010590615046 |
||||
:1008F00070400110D8F7809590958E0F9F1F089536 |
||||
:10090000FC016150704001900110D8F780959095DE |
||||
:100910008E0F9F1F08950F931F93CF93DF938C012A |
||||
:10092000EB018B8181FF1BC082FF0DC02E813F81B7 |
||||
:100930008C819D812817390764F4E881F98101933E |
||||
:10094000F983E88306C0E885F985802F0995892B0E |
||||
:1009500031F48E819F8101969F838E8302C00FEFB9 |
||||
:100960001FEFC801DF91CF911F910F910895FA01F8 |
||||
:10097000AA27283051F1203181F1E8946F936E7FDE |
||||
:100980006E5F7F4F8F4F9F4FAF4FB1E03ED0B4E0CF |
||||
:100990003CD0670F781F891F9A1FA11D680F791F10 |
||||
:1009A0008A1F911DA11D6A0F711D811D911DA11D21 |
||||
:1009B00020D009F468943F912AE0269F1124301931 |
||||
:1009C000305D3193DEF6CF010895462F4770405DCC |
||||
:1009D0004193B3E00FD0C9F7F6CF462F4F70405D7B |
||||
:1009E0004A3318F0495D31FD4052419302D0A9F7D6 |
||||
:1009F000EACFB4E0A6959795879577956795BA95D0 |
||||
:100A0000C9F700976105710508959B01AC010A2E95 |
||||
:100A100006945795479537952795BA95C9F7620F6C |
||||
:100A2000731F841F951FA01D08950F931F9308EA3D |
||||
:100A300012E0C8016DE675E044E050E00E94E00C71 |
||||
:100A400084EC94E0B8010E943C121F910F9108952C |
||||
:100A50001F93182F80528E35E0F08DE695E060E010 |
||||
:100A600071E00E94F60A612F62956F706A3010F093 |
||||
:100A7000695C01C0605D8DE695E00E94220A612FED |
||||
:100A80006F706A3010F0695C01C0605D8DE695E0C2 |
||||
:100A900003C08DE695E0612F0E94220A1F91089500 |
||||
:100AA0008F929F92AF92BF92CF92DF92EF92FF927E |
||||
:100AB0000F931F93DF93CF93CDB7DEB7CA54D140C6 |
||||
:100AC0000FB6F894DEBF0FBECDBF88EA92E00E9459 |
||||
:100AD0002B0F8091D704882309F4BFC00E943607EA |
||||
:100AE0004B015C018DB79EB708970FB6F8949EBF77 |
||||
:100AF0000FBE8DBFEDB7FEB731968E010F5F1F4F52 |
||||
:100B0000ADB7BEB712961C930E93119783E091E098 |
||||
:100B1000938382838091D8049091D904A091DA04C0 |
||||
:100B2000B091DB0484839583A683B7830E9474020B |
||||
:100B3000EDB7FEB738960FB6F894FEBF0FBEEDBF07 |
||||
:100B40008DE695E06FE271E00E94F60A8DE695E091 |
||||
:100B5000B8010E94F90A84EC94E0B8010E94841163 |
||||
:100B600081E4C82ED12CCC0EDD1E84EC94E0B601BD |
||||
:100B70004AE051E00E945E108C01883C910549F5E5 |
||||
:100B80008DE695E062E471E00E94F90A8DE695E059 |
||||
:100B90006AE571E00E94F60AD6010D900020E9F79F |
||||
:100BA0007D010894E108F108EC18FD0800E010E070 |
||||
:100BB00008C0F601E00FF11F80810E9428050F5F39 |
||||
:100BC0001F4F0E151F05ACF38DE695E06AE671E048 |
||||
:100BD00006C0009739F48DE695E06DE671E00E945D |
||||
:100BE000F90A0DC08DE695E064E871E00E94F60A0E |
||||
:100BF0008DE695E0B8014AE050E00E94D90A0E94D3 |
||||
:100C00003607681979098A099B096093D80470939B |
||||
:100C1000D9048093DA049093DB048DE695E06AE9C9 |
||||
:100C200071E00E94F60A4091D8045091D904609175 |
||||
:100C3000DA047091DB048DE695E02AE030E00E9452 |
||||
:100C4000CA0A8DE695E069EA71E00E94F90A68EB4C |
||||
:100C50007BE080E090E00E94440764E670E080E082 |
||||
:100C600090E00E944407C65BDE4F0FB6F894DEBFEB |
||||
:100C70000FBECDBFCF91DF911F910F91FF90EF90ED |
||||
:100C8000DF90CF90BF90AF909F908F9008958DE6AA |
||||
:100C900095E040E052EC61E070E00E9462086AE09A |
||||
:100CA00070E080E090E00E9444078DE695E06CEAF9 |
||||
:100CB00071E00E94F90A88EA92E00E94C60C6AE09C |
||||
:100CC00070E080E090E00E94440788EA92E00E9491 |
||||
:100CD000F60D6AE070E080E090E00AC08DE695E0F5 |
||||
:100CE0006EEB71E00E94F90A68EE73E080E090E03C |
||||
:100CF0000E94440788EA92E00E94BF0F882371F3A4 |
||||
:100D00008DE695E068ED71E00E94F90A84EC94E0CC |
||||
:100D100063EF71E00E943612882339F48DE695E086 |
||||
:100D200066E072E00E94F90AFFCF8DE695E06BE283 |
||||
:100D300072E00E94F90A8AEA92E06FEA76E00E9485 |
||||
:100D40001F1088EA92E06FE372E0AB010E94190E77 |
||||
:100D50008DE695E060E472E00E94F90A08950F9331 |
||||
:100D60001F93DF93CF93CDB7DEB72A970FB6F894D2 |
||||
:100D7000DEBF0FBECDBFBC018E010B5F1F4FC80190 |
||||
:100D80000E94ED0BC8010E94F70B0197E1F4C80126 |
||||
:100D9000BE016F5F7F4F44E050E00E94FF0B8981EE |
||||
:100DA0009A81AB81BC810597A105B10551F48DE60F |
||||
:100DB00095E068E572E00E94F90A81E08093D7042B |
||||
:100DC00002C01092D7042A960FB6F894DEBF0FBE69 |
||||
:100DD000CDBFCF91DF911F910F9108951F920F9278 |
||||
:100DE0000FB60F9211242F933F938F939F93AF933E |
||||
:100DF000BF938091E0049091E104A091E204B0914E |
||||
:100E0000E3043091E4040196A11DB11D232F2D5F51 |
||||
:100E10002D3720F02D570196A11DB11D2093E4041C |
||||
:100E20008093E0049093E104A093E204B093E30480 |
||||
:100E30008091DC049091DD04A091DE04B091DF0488 |
||||
:100E40000196A11DB11D8093DC049093DD04A09355 |
||||
:100E5000DE04B093DF04BF91AF919F918F913F91DA |
||||
:100E60002F910F900FBE0F901F9018958FB7F89489 |
||||
:100E70002091E0043091E1044091E2045091E304B8 |
||||
:100E80008FBFB901CA0108959B01AC017FB7F894E7 |
||||
:100E90008091DC049091DD04A091DE04B091DF0428 |
||||
:100EA00066B5A89B05C06F3F19F00196A11DB11D45 |
||||
:100EB0007FBFBA2FA92F982F8827860F911DA11DBC |
||||
:100EC000B11D62E0880F991FAA1FBB1F6A95D1F759 |
||||
:100ED000BC012DC0FFB7F8948091DC049091DD0433 |
||||
:100EE000A091DE04B091DF04E6B5A89B05C0EF3FFA |
||||
:100EF00019F00196A11DB11DFFBFBA2FA92F982F80 |
||||
:100F000088278E0F911DA11DB11DE2E0880F991F4A |
||||
:100F1000AA1FBB1FEA95D1F7861B970B885E9340EB |
||||
:100F2000C8F2215030404040504068517C4F21155C |
||||
:100F300031054105510571F60895789484B58260B4 |
||||
:100F400084BD84B5816084BD85B5826085BD85B56D |
||||
:100F5000816085BDEEE6F0E0808181608083E1E81C |
||||
:100F6000F0E0108280818260808380818160808354 |
||||
:100F7000E0E8F0E0808181608083E1EBF0E0808157 |
||||
:100F800084608083E0EBF0E0808181608083EAE729 |
||||
:100F9000F0E08081846080838081826080838081B2 |
||||
:100FA000816080838081806880831092C100089571 |
||||
:100FB00008951F920F920FB60F9211242F933F9313 |
||||
:100FC0004F938F939F93EF93FF938091C00082FD87 |
||||
:100FD0001DC04091C60020912505309126052F5F48 |
||||
:100FE0003F4F2F7330708091270590912805281767 |
||||
:100FF000390771F0E0912505F0912605EB51FB4F83 |
||||
:101000004083309326052093250502C08091C600B9 |
||||
:10101000FF91EF919F918F914F913F912F910F9061 |
||||
:101020000FBE0F901F901895E0917905F0917A0509 |
||||
:10103000E05CFF4F8191919120813181821B930B64 |
||||
:101040008F739070892B11F00E94D80708951F921A |
||||
:101050000F920FB60F9211242F933F938F939F936C |
||||
:10106000EF93FF932091690530916A0580916B059C |
||||
:1010700090916C052817390731F48091C1008F7D5C |
||||
:101080008093C10014C0E0916B05F0916C05E75DA1 |
||||
:10109000FA4F208180916B0590916C0501968F73BA |
||||
:1010A000907090936C0580936B052093C600FF9120 |
||||
:1010B000EF919F918F913F912F910F900FBE0F90C5 |
||||
:1010C0001F901895AF92BF92DF92EF92FF920F930D |
||||
:1010D0001F93CF93DF93EC017A018B01DD24403025 |
||||
:1010E00081EE580780E0680780E0780711F0DD2482 |
||||
:1010F000D39491E0A92EB12CEC89FD89DD2069F013 |
||||
:10110000C50108A002C0880F991F0A94E2F78083E6 |
||||
:1011100060E079E08DE390E005C0108260E874E85B |
||||
:101120008EE190E0A80197010E94381321503040D1 |
||||
:1011300040405040569547953795279580E120309F |
||||
:10114000380720F0DD2011F0DD24D6CFE889F989B9 |
||||
:101150003083EA89FB89208319A2EE89FF894081C7 |
||||
:1011600021E030E0C9010C8C02C0880F991F0A945D |
||||
:10117000E2F7482B4083EE89FF894081C9010D8C3D |
||||
:1011800002C0880F991F0A94E2F7482B4083EE892A |
||||
:10119000FF894081C9010E8C02C0880F991F0A94F3 |
||||
:1011A000E2F7482B4083EE89FF8980810F8C02C0D3 |
||||
:1011B000220F331F0A94E2F7209528232083DF9122 |
||||
:1011C000CF911F910F91FF90EF90DF90BF90AF9064 |
||||
:1011D0000895DC011C96ED91FC911D97E05CFF4F9A |
||||
:1011E0002191319180819181281B390B2F733070AF |
||||
:1011F000C9010895DC011C96ED91FC911D97E05CFE |
||||
:10120000FF4F20813181E054F040DF01AE5BBF4FE2 |
||||
:101210008D919C9111972817390719F42FEF3FEF03 |
||||
:1012200007C08D919C91E80FF91F8081282F30E035 |
||||
:10123000C9010895DC011C96ED91FC911D97E05CBD |
||||
:10124000FF4F20813181E054F040DF01AE5BBF4FA2 |
||||
:101250008D919C9111972817390719F42FEF3FEFC3 |
||||
:1012600010C08D919C911197E80FF91F20818D91ED |
||||
:101270009C91119701968F73907011969C938E9309 |
||||
:1012800030E0C9010895DC0191968C9191978823F3 |
||||
:1012900039F05496ED91FC915597808186FFF9CFF6 |
||||
:1012A00091961C920895CF93DF93EC01EE85FF8514 |
||||
:1012B000E05CFF4F20813181E054F0402F5F3F4FD1 |
||||
:1012C0002F733070DF01AE5BBF4F8D919C911197F2 |
||||
:1012D00028173907D1F3E05CFF4F80819181E054FA |
||||
:1012E000F040E80FF91F6083EE85FF85E05CFF4F5B |
||||
:1012F00031832083EE89FF89208181E090E00F8C8B |
||||
:1013000002C0880F991F0A94E2F7282B208381E0FE |
||||
:1013100089A3EC89FD8980818064808381E090E0ED |
||||
:10132000DF91CF9108951092700510926F0588EEAD |
||||
:1013300093E0A0E0B0E08093710590937205A093D4 |
||||
:101340007305B09374058BE992E090936E058093DA |
||||
:101350006D0585EE94E090937A058093790589E296 |
||||
:1013600095E090937C0580937B0585EC90E09093CD |
||||
:101370007E0580937D0584EC90E0909380058093BA |
||||
:101380007F0580EC90E0909382058093810581EC4D |
||||
:1013900090E0909384058093830582EC90E0909395 |
||||
:1013A00086058093850586EC90E090938805809370 |
||||
:1013B000870584E08093890583E080938A0587E030 |
||||
:1013C00080938B0585E080938C0581E080938D056B |
||||
:1013D0000895CF93DF930E949D070E944706C4E1C2 |
||||
:1013E000D8E00E9450052097E1F30E941408F9CF3D |
||||
:1013F000CF92DF92EF92FF920F931F93CF93DF93E1 |
||||
:101400007C016B018A01C0E0D0E00FC0D6016D9174 |
||||
:101410006D01D701ED91FC910190F081E02DC701A4 |
||||
:101420000995C80FD91F015010400115110571F71A |
||||
:10143000CE01DF91CF911F910F91FF90EF90DF9040 |
||||
:10144000CF900895DC01ED91FC910190F081E02DA9 |
||||
:1014500009950895EF92FF920F931F938C01DC0181 |
||||
:10146000ED91FC910190F081E02D6DE009957C01FA |
||||
:10147000D801ED91FC910190F081E02DC8016AE066 |
||||
:1014800009959C012E0D3F1DC9011F910F91FF90E1 |
||||
:10149000EF900895CF93DF93EC016115710519F476 |
||||
:1014A00020E030E00FC0DB010D900020E9F711973C |
||||
:1014B000A61BB70BE881F9810280F381E02DAD0115 |
||||
:1014C00009959C01C901DF91CF9108954F925F92D8 |
||||
:1014D0007F928F929F92AF92BF92CF92DF92EF92C4 |
||||
:1014E000FF920F931F93DF93CF93CDB7DEB7A197F2 |
||||
:1014F0000FB6F894DEBF0FBECDBF2C01742ECB010A |
||||
:10150000223008F42AE019A231E2C32ED12CCC0EED |
||||
:10151000DD1E822E9924AA24BB24672D752FA501D8 |
||||
:1015200094010E94381379018A01C801B701A5010D |
||||
:1015300094010E941913472D461B0894C108D10835 |
||||
:101540004A3010F4405D01C0495CF6014083E1146B |
||||
:10155000F1040105110521F07E2C5F2DC801DDCFBE |
||||
:10156000C201B6010E944A0AA1960FB6F894DEBFE6 |
||||
:101570000FBECDBFCF91DF911F910F91FF90EF90E4 |
||||
:10158000DF90CF90BF90AF909F908F907F905F90B3 |
||||
:101590004F900895DC012115310541F4ED91FC9146 |
||||
:1015A0000190F081E02D642F099508950E94660A4C |
||||
:1015B0000895CF92DF92EF92FF920F931F936C01E9 |
||||
:1015C0007B019A0100E010E0B801A7010E94CA0A5D |
||||
:1015D0008C01C6010E942A0A080F191FC8011F9119 |
||||
:1015E0000F91FF90EF90DF90CF9008950E944A0AEC |
||||
:1015F0000895EF92FF920F931F937C010E944A0A75 |
||||
:101600008C01C7010E942A0A080F191FC8011F91E7 |
||||
:101610000F91FF90EF900895AF92BF92CF92DF921B |
||||
:10162000EF92FF920F931F93CF93DF935C016B01B7 |
||||
:10163000EE24FF24C0E0D0E010C0D501ED91FC9174 |
||||
:1016400000811181C601BE010E94530B682FC501A4 |
||||
:10165000F8010995E80EF91E2196F601848195811D |
||||
:10166000C817D90750F3C701DF91CF911F910F9190 |
||||
:10167000FF90EF90DF90CF90BF90AF900895EF92E2 |
||||
:10168000FF920F931F937C010E940C0B8C01C701EA |
||||
:101690000E942A0A9C01200F311FC9011F910F913E |
||||
:1016A000FF90EF900895FC01848195816817790778 |
||||
:1016B00048F40190F081E02D309721F0E60FF71FFC |
||||
:1016C0008081089580E008950F931F93CF93DF9357 |
||||
:1016D000EC018B016F5F7F4F888199810E948F01A0 |
||||
:1016E000009711F480E005C0998388831B830A83E7 |
||||
:1016F00081E0DF91CF911F910F910895CF93DF93F8 |
||||
:10170000EC0188819981892B29F08A819B81861738 |
||||
:10171000970760F4CE010E94640B882341F08C810E |
||||
:101720009D81892B19F4E881F981108281E0DF9194 |
||||
:10173000CF910895CF93DF93EC0188819981009731 |
||||
:1017400011F00E943701198218821D821C821B82AF |
||||
:101750001A82DF91CF910895EF92FF920F931F931A |
||||
:10176000CF93DF93EC017B018A01BA010E947E0BCB |
||||
:10177000882321F4CE010E949A0B07C01D830C839D |
||||
:1017800088819981B7010E946D02CE01DF91CF91CE |
||||
:101790001F910F91FF90EF900895CF93DF93EC018D |
||||
:1017A000198218821B821A821D821C821E82611578 |
||||
:1017B000710551F0DB010D900020E9F71197A61B90 |
||||
:1017C000B70BAD010E94AC0BDF91CF910895FC01E6 |
||||
:1017D000808191810E9437010895FC01CB017583BE |
||||
:1017E00064830C9693838283118210820895DC01B6 |
||||
:1017F0001496ED91FC9115978285938508950F932A |
||||
:101800001F93CF93DF93DC01EB018A011496ED91D6 |
||||
:10181000FC9115972D913C911197828593852817FE |
||||
:10182000390728F02FEF3FEF4FEF5FEF34C01296EC |
||||
:10183000ED91FC911397619171911396FC93EE9346 |
||||
:101840001297AB0120E030E01AC01296ED91FC91A6 |
||||
:101850001397819188831396FC93EE9312972F5FD1 |
||||
:101860003F4F415050400217130740F48D919C9117 |
||||
:10187000119701968D939C9398010BC02196411569 |
||||
:10188000510519F78D919C91119701968D939C9319 |
||||
:101890009B0140E050E0B901CA01DF91CF911F9157 |
||||
:1018A0000F9108951F93CF93DF93EC01162F862F8E |
||||
:1018B0008D57AF85B8898330A8F4ED91FC911197CD |
||||
:1018C0000190F081E02DCD016DE70995EF85F88954 |
||||
:1018D000A081B18160E261272D913C91CF01F90196 |
||||
:1018E000099508C0ED91FC9111970190F081E02DD0 |
||||
:1018F000CD010995DF91CF911F910895EF92FF924D |
||||
:101900000F931F93CF93DF937C018B01EA0107C0F4 |
||||
:10191000F80161918F01C7010E94520C2197209715 |
||||
:10192000B9F7DF91CF911F910F91FF90EF9008953C |
||||
:101930000F931F93DF93CF9300D0CDB7DEB78C0109 |
||||
:101940007A836983BE016F5F7F4F42E050E00E945F |
||||
:101950007E0CD8011F96ED91FC915097A081B1812A |
||||
:101960002D913C91CF016FE7F90109950F900F90F0 |
||||
:10197000CF91DF911F910F910895FC0181898823F8 |
||||
:1019800021F0808191810E943F0B0895FC01E65E69 |
||||
:10199000FD4F808161E00E9498120895FC014A96F3 |
||||
:1019A000938B828B80E092E0958B848B178A168ACA |
||||
:1019B000108EE65EFD4F808161E00E94591208950D |
||||
:1019C000CF92DF92EF92FF920F931F938C017B01D6 |
||||
:1019D0006A0102960E941910F801F08AE786065EF5 |
||||
:1019E0001D4FF801D182C0820A511240F801118ABC |
||||
:1019F000C8010E94CE0C1F910F91FF90EF90DF90D5 |
||||
:101A0000CF9008958F929F92AF92BF92CF92DF9224 |
||||
:101A1000EF92FF920F931F93DF93CF9300D00F921B |
||||
:101A2000CDB7DEB75C014B016A017901A9014F5FB7 |
||||
:101A30005F4FC90183709070892B11F09A01F6CF26 |
||||
:101A40003B832A8319828E010E5F1F4FC501B801A7 |
||||
:101A500042E050E00E947E0CC80162E070E0A40108 |
||||
:101A60000E94EC128C0119C0C501F60160810E9430 |
||||
:101A7000520CC60161E070E0A8010E94EC128C01DA |
||||
:101A80008A819B81009719F001979B838A83089430 |
||||
:101A9000C11CD11C0894E108F108E114F10421F7FC |
||||
:101AA0000FC0698101979B838A83C5010E94520CF4 |
||||
:101AB000C70161E070E0A8010E94EC128C0104C033 |
||||
:101AC0007E010894E11CF11C8A819B81009749F7F3 |
||||
:101AD000C8010F900F900F90CF91DF911F910F9140 |
||||
:101AE000FF90EF90DF90CF90BF90AF909F908F903E |
||||
:101AF0000895AF92BF92CF92DF92EF92FF920F9331 |
||||
:101B00001F93DF93CF93CDB7DEB72C970FB6F89422 |
||||
:101B1000DEBF0FBECDBF5C017A8369832B833C831C |
||||
:101B20004D835E83EF82F88609871A87DC86CB8631 |
||||
:101B3000DC011F96ED91FC915097A081B1812D9110 |
||||
:101B40003C91CF016EE7F9010995C5018E010F5F48 |
||||
:101B50001F4FB80142E050E00E947E0CC80162E0D5 |
||||
:101B600070E040E050E00E94EC127C018E010D5FBD |
||||
:101B70001F4FC501B80144E050E00E947E0CC8012F |
||||
:101B800064E070E0A7010E94EC127C018E01095F05 |
||||
:101B90001F4FC501B80144E050E00E947E0CC8010F |
||||
:101BA00064E070E0A7010E94EC127C018E01055FE9 |
||||
:101BB0001F4FC501B80142E050E00E947E0CC801F1 |
||||
:101BC00062E070E0A7010E94EC122C960FB6F89428 |
||||
:101BD000DEBF0FBECDBFCF91DF911F910F91FF9060 |
||||
:101BE000EF90DF90CF90BF90AF900895AF92BF92EB |
||||
:101BF000CF92DF92EF92FF920F931F935C0161E00F |
||||
:101C000070E020E030E040E050E0EE24FF24870167 |
||||
:101C1000CC24DD240E94790DBC01C5010E94980CE2 |
||||
:101C20001F910F91FF90EF90DF90CF90BF90AF90FA |
||||
:101C300008956F927F928F929F92AF92BF92CF92B0 |
||||
:101C4000DF92EF92FF920F931F935C01962E872EE7 |
||||
:101C5000742E652E82E090E0A80EB91E95014427EF |
||||
:101C600037FD4095542F8EEF9FEFA80EB91EC5018A |
||||
:101C700063E070E0EE24FF248701E2E0CE2ED12C59 |
||||
:101C80000E94790DBC01E92DF82DDF010D90002097 |
||||
:101C9000E9F71197AE1BBF0BC501492D582D9D01CA |
||||
:101CA0000E94020DBC01E72DF62DDF010D900020F2 |
||||
:101CB000E9F71197AE1BBF0BC501472D562D9D01AE |
||||
:101CC0000E94020DBC01C5010E94980C1F910F914A |
||||
:101CD000FF90EF90DF90CF90BF90AF909F908F904C |
||||
:101CE0007F906F9008954F925F926F927F928F9244 |
||||
:101CF0009F92AF92BF92CF92DF92EF92FF920F939B |
||||
:101D00001F93DF93CF93CDB7DEB727970FB6F89425 |
||||
:101D1000DEBF0FBECDBF5C01FC01C288D388F601D7 |
||||
:101D2000628473848601045F1F4FC6016CE070E01B |
||||
:101D300040E050E00E94EC12AC0122C0C80162E019 |
||||
:101D400070E00E94EC12AC01F2E04F2E512C400EDC |
||||
:101D5000511E720184010BC0C70161E070E00E9456 |
||||
:101D6000EC12AC010894E11CF11C0150104001156B |
||||
:101D7000110591F78201080D191D08946108710879 |
||||
:101D8000F8018080918061147104C1F648155905ED |
||||
:101D900081F08E010F5F1F4FC80167E672E00E945D |
||||
:101DA000CD0BC501B8010E94BD0CC8010E94E70B14 |
||||
:101DB0003BC0F601E280F38004811581E114F10457 |
||||
:101DC00001051105C9F080819181F501958784870E |
||||
:101DD000F60186819781A085B185F501808791877D |
||||
:101DE000A287B387C7010E944B108823E9F0C7017F |
||||
:101DF000B6010E94231018C0F60182859385892BB5 |
||||
:101E000099F481E0F5018687F60180819181F501E1 |
||||
:101E100095878487F60186819781A085B185F50134 |
||||
:101E200080879187A287B38727960FB6F894DEBF85 |
||||
:101E30000FBECDBFCF91DF911F910F91FF90EF901B |
||||
:101E4000DF90CF90BF90AF909F908F907F906F90DA |
||||
:101E50005F904F9008950F931F93CF93DF93EC0102 |
||||
:101E600011E000E243C0EF85F889A081B1811696A8 |
||||
:101E70002D913C911797CF01F9010995682F8E3765 |
||||
:101E800031F08F3749F08D3761F4188F2FC01F8ADA |
||||
:101E90001E8A188E198F2AC0CE010E94730E198EC9 |
||||
:101EA00025C0898D882369F489898823F9F0E88120 |
||||
:101EB000F981A081B1812D913C91CF01F901099562 |
||||
:101EC00015C0888D882311F06027188E2E893F89D0 |
||||
:101ED0008C899D892817390748F4EA89FB89E20F24 |
||||
:101EE000F31F60832F5F3F4F3F8B2E8BEF85F88969 |
||||
:101EF000A081B18114962D913C911597CF01F901E4 |
||||
:101F00000995892B09F0AFCFDF91CF911F910F91E8 |
||||
:101F10000895AF92BF92CF92DF92EF92FF920F930C |
||||
:101F20001F93CF93DF93EC015A016B011E86188635 |
||||
:101F300019861A861B861D861C860E9436077B0121 |
||||
:101F40008C018E85882379F40E9436076E197F09EB |
||||
:101F5000800B910B6A157B058C059D0520F4CE0145 |
||||
:101F60000E942B0FEECF8E85DF91CF911F910F91A5 |
||||
:101F7000FF90EF90DF90CF90BF90AF900895BF9209 |
||||
:101F8000CF92DF92EF92FF920F931F93CF93DF9345 |
||||
:101F9000EC01B5E0BB2E39C01E86188619861A865C |
||||
:101FA0001B86CE0162E070E020E030E040E050E0CF |
||||
:101FB000A1E0EA2EF12C012D112DCC24DD240E946C |
||||
:101FC000790DBC01CE010E94980C0E9436077B015E |
||||
:101FD0008C018E85882349F50E9436076E197F098A |
||||
:101FE000800B910B685E734080409040F0F4CE010E |
||||
:101FF0000E942B0FEECF88859985AA85BB85009717 |
||||
:10200000A105B10511F081E006C0BA948FEFB816B2 |
||||
:1020100009F0C2CF80E0DF91CF911F910F91FF9027 |
||||
:10202000EF90DF90CF90BF9008958E85882319F7A9 |
||||
:10203000ECCFFC0111821082138212820895FC0100 |
||||
:10204000738362830895FC01228133812115310558 |
||||
:1020500009F14081518141155105C9F08481958173 |
||||
:1020600080FF0EC0FC01F595E795E40FF51F019088 |
||||
:10207000F081E02DE20FF31F0190F081E02D01C00F |
||||
:10208000F90195958795840F951F09950895CB01C2 |
||||
:10209000F90109950895FC0180819181892B29F42A |
||||
:1020A00020E082819381892B09F021E0822F08951D |
||||
:1020B000FC0181E0808B728B618B08956F927F921F |
||||
:1020C0008F929F92AF92BF92CF92DF92EF92FF9248 |
||||
:1020D0000F931F93DF93CF9300D000D000D0CDB7E4 |
||||
:1020E000DEB77C013B014A01DC0150961C920E9444 |
||||
:1020F00036075B016C01F7018089882309F056C01F |
||||
:102100000E9436076A197B098C099D09D70114962C |
||||
:102110002D913D914D915C9117976217730784073C |
||||
:10212000950708F043C018968D919C9119970E94CD |
||||
:102130002B0FE1CFF701618972898E010F5F1F4F6D |
||||
:10214000C8010E94ED0BC801B301A4010E94FF0B5E |
||||
:102150009B01AC01C401A0E0B0E0281739074A0791 |
||||
:102160005B0710F4F90102C0F4013197E60DF71D89 |
||||
:102170001082D7011896ED91FC9119972085318531 |
||||
:10218000C90126960FB6F894DEBF0FBECDBFCF9122 |
||||
:10219000DF911F910F91FF90EF90DF90CF90BF9054 |
||||
:1021A000AF909F908F907F906F900895F7018089F6 |
||||
:1021B000882309F0BFCF20E030E0E2CF4F925F925A |
||||
:1021C0006F927F928F929F92AF92BF92CF92DF9247 |
||||
:1021D000EF92FF920F931F93DF93CF9300D0CDB771 |
||||
:1021E000DEB75C01562E472E942E852E39011A83B8 |
||||
:1021F0000983FC0180819181A281B3810097A105AF |
||||
:10220000B10509F46EC0208531851016110674F4ED |
||||
:10221000C9016CE070E020E030E040E050E0EE24E6 |
||||
:10222000FF248701E5E0CE2ED12C0DC0C9016CE062 |
||||
:1022300070E020E030E040E050E0EE24FF24870131 |
||||
:10224000B3E0CB2ED12C0E94790DBC01F501808525 |
||||
:102250009185A50124E030E00E94020DBC01E92D2A |
||||
:10226000F82DDF010D900020E9F71197AE1BBF0B91 |
||||
:10227000F50180859185492D582D9D010E94020D03 |
||||
:10228000BC01E52DF42DDF010D900020E9F7119739 |
||||
:10229000AE1BBF0BF50180859185452D542D9D0109 |
||||
:1022A0000E94020DBC0189819A8118161906A4F4B6 |
||||
:1022B000F50180859185AE014F5F5F4F22E030E0F0 |
||||
:1022C0000E94020DBC0129813A81F501808591852A |
||||
:1022D000A3010E94020DBC01F501808591850E9439 |
||||
:1022E000980C0F900F90CF91DF911F910F91FF905D |
||||
:1022F000EF90DF90CF90BF90AF909F908F907F90A6 |
||||
:102300006F905F904F9008950F931F934DE752E0A9 |
||||
:1023100020E030E000E010E00E94DE101F910F91FD |
||||
:1023200008958F929F92AF92BF92CF92DF92EF92D9 |
||||
:10233000FF920F931F93DF93CF9300D00F92CDB7EF |
||||
:10234000DEB75C01962E872E5B834A831982222397 |
||||
:1023500011F081E0898380E090E0A0E0B0E088E5C2 |
||||
:1023600090E1F501B386A28684879587A687B78713 |
||||
:102370008AE090E0A80EB91E9501442737FD4095EC |
||||
:10238000542FA6EFBFEFAA0EBB1EF50180859185E5 |
||||
:102390006BE070E0A1E0EA2EF12C012D112DF3E0AD |
||||
:1023A000CF2ED12C0E94790DBC01E92DF82DDF0133 |
||||
:1023B0000D900020E9F71197AE1BBF0BF50180854A |
||||
:1023C0009185492D582D9D010E94020DBC01D5011A |
||||
:1023D00018968D919C911997AE014E5F5F4F22E048 |
||||
:1023E00030E00E94020DBC01F50180859185AE01AF |
||||
:1023F0004F5F5F4F21E030E00E94020DBC01D5012C |
||||
:1024000018968D919C9119970E94980CF501448122 |
||||
:10241000558166817781808591850E94890F882307 |
||||
:10242000A1F0D5011896ED91FC91199780859185C1 |
||||
:10243000A285B3850097A105B10539F0F501808328 |
||||
:102440009183A283B38381E001C080E00F900F905D |
||||
:102450000F90CF91DF911F910F91FF90EF90DF9040 |
||||
:10246000CF90BF90AF909F908F90089540E550E03F |
||||
:1024700020E00E9491110895EF92FF920F931F9315 |
||||
:102480008C017B010A960E941910F801F186E08602 |
||||
:10249000108211821282138288E893E1A0E0B0E0FA |
||||
:1024A00084839583A683B7831F910F91FF90EF904C |
||||
:1024B0000895CF93DF93482F50E0CA0186569F4F6F |
||||
:1024C000FC0134914A575F4FFA018491882369F1E6 |
||||
:1024D00090E0880F991FFC01E859FF4FA591B49136 |
||||
:1024E000FC01EE58FF4FC591D491662351F42FB7EC |
||||
:1024F000F8948C91932F909589238C9388818923CC |
||||
:102500000BC0623061F42FB7F8948C91932F9095A3 |
||||
:1025100089238C938881832B88832FBF06C09FB724 |
||||
:10252000F8948C91832B8C939FBFDF91CF9108956A |
||||
:10253000482F50E0CA0182559F4FFC012491CA01E7 |
||||
:1025400086569F4FFC0194914A575F4FFA01349190 |
||||
:10255000332309F440C0222351F1233071F0243099 |
||||
:1025600028F42130A1F0223011F514C02630B1F04A |
||||
:102570002730C1F02430D9F404C0809180008F77D7 |
||||
:1025800003C0809180008F7D8093800010C084B54F |
||||
:102590008F7702C084B58F7D84BD09C08091B00063 |
||||
:1025A0008F7703C08091B0008F7D8093B000E32FC0 |
||||
:1025B000F0E0EE0FFF1FEE58FF4FA591B4912FB73B |
||||
:1025C000F894662321F48C919095892302C08C9114 |
||||
:1025D000892B8C932FBF0895CF93DF93EC01A0E05C |
||||
:1025E000B0E020C0899190E084279527F82FE92F4B |
||||
:1025F000CF01807024E0880F991F2A95E1F78E277C |
||||
:102600009F279C01232F332722952F7028273927B6 |
||||
:10261000A9014070E5E056954795EA95E1F7422714 |
||||
:1026200053271196A617B707ECF2CA01DF91CF9195 |
||||
:102630000895629FD001739FF001829FE00DF11D0C |
||||
:10264000649FE00DF11D929FF00D839FF00D749F2C |
||||
:10265000F00D659FF00D9927729FB00DE11DF91FD8 |
||||
:10266000639FB00DE11DF91FBD01CF011124089535 |
||||
:10267000A1E21A2EAA1BBB1BFD010DC0AA1FBB1F86 |
||||
:10268000EE1FFF1FA217B307E407F50720F0A21BF8 |
||||
:10269000B30BE40BF50B661F771F881F991F1A9465 |
||||
:1026A00069F760957095809590959B01AC01BD018F |
||||
:1026B000CF010895EE0FFF1F0590F491E02D0994CE |
||||
:1026C0002F923F924F925F926F927F928F929F9242 |
||||
:1026D000AF92BF92CF92DF92EF92FF920F931F9330 |
||||
:1026E000CF93DF93CDB7DEB7CA1BDB0B0FB6F894E1 |
||||
:1026F000DEBF0FBECDBF09942A88398848885F8421 |
||||
:102700006E847D848C849B84AA84B984C884DF8091 |
||||
:10271000EE80FD800C811B81AA81B981CE0FD11D75 |
||||
:102720000FB6F894DEBF0FBECDBFED010895F8944B |
||||
:02273000FFCFD9 |
||||
:102732005C78002F7570646174653F6170695F6BCE |
||||
:1027420065793D4D41593033414B4A444D505034E7 |
||||
:10275200593449266669656C64313D256C640041D3 |
||||
:10276200524455494E4F3A2073656E642067657432 |
||||
:10277200200041524455494E4F3A20474554207358 |
||||
:1027820075636365737366756C0041524455494EB7 |
||||
:102792004F3A20676F74203C3C003E3E0041524459 |
||||
:1027A20055494E4F3A204745542074696D6564205F |
||||
:1027B2006F75740041524455494E4F3A2047455473 |
||||
:1027C200206661696C65643A200041524455494E65 |
||||
:1027D2004F3A20746F6F6B20006D73004152445565 |
||||
:1027E200494E4F3A207374617274696E67004152A8 |
||||
:1027F2004455494E4F3A20455350206E6F74207213 |
||||
:10280200656164792E2E2E0041524455494E4F3A4D |
||||
:10281200207365747570207265737420636C6965CA |
||||
:102822006E74006170692E7468696E677370656199 |
||||
:102832006B2E636F6D0041524455494E4F3A2066EC |
||||
:1028420061696C656420746F2073657475702072A1 |
||||
:1028520065737420636C69656E7400415244554916 |
||||
:102862004E4F3A207365747570207769666900006F |
||||
:1028720041524455494E4F3A2073797374656D2025 |
||||
:1028820073746172746564005749464920434F4E20 |
||||
:102892004E45435445440041524455494E4F3A2017 |
||||
:1028A200496E76616C696420435243000047455487 |
||||
:1028B2000044454C4554450050555400504F535424 |
||||
:1028C20000200093050000000000005309F809E908 |
||||
:0828D200081A09FA0843090085 |
||||
:00000001FF |
||||
@ -0,0 +1,104 @@
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
* Demo sketch that makes a rest request to api.thingspeak.com with the RTT of the previous |
||||
* request. |
||||
*/ |
||||
|
||||
#include <espduino.h> |
||||
#include <rest.h> |
||||
|
||||
ESP esp(&Serial, 4); |
||||
|
||||
REST rest(&esp); |
||||
|
||||
boolean wifiConnected = false; |
||||
|
||||
void wifiCb(void* response) |
||||
{ |
||||
uint32_t status; |
||||
RESPONSE res(response); |
||||
|
||||
if(res.getArgc() == 1) { |
||||
res.popArgs((uint8_t*)&status, 4); |
||||
if(status == STATION_GOT_IP) { |
||||
Serial.println("WIFI CONNECTED"); |
||||
|
||||
wifiConnected = true; |
||||
} else { |
||||
wifiConnected = false; |
||||
} |
||||
} |
||||
} |
||||
|
||||
void setup() { |
||||
Serial.begin(115200); |
||||
delay(10); |
||||
Serial.println("ARDUINO: starting"); |
||||
esp.enable(); |
||||
delay(10); |
||||
esp.reset(); |
||||
delay(10); |
||||
while(!esp.ready()) { |
||||
Serial.println("ARDUINO: ESP not ready..."); |
||||
delay(1000); |
||||
} |
||||
|
||||
Serial.println("ARDUINO: setup rest client"); |
||||
if(!rest.begin("api.thingspeak.com")) { |
||||
Serial.println("ARDUINO: failed to setup rest client"); |
||||
while(1); |
||||
} |
||||
|
||||
/*setup wifi*/ |
||||
Serial.println("ARDUINO: setup wifi"); |
||||
esp.wifiCb.attach(&wifiCb); |
||||
|
||||
esp.wifiConnect("",""); |
||||
Serial.println("ARDUINO: system started"); |
||||
} |
||||
|
||||
void printChar(char c) { |
||||
if (c < ' ' || c >= '~') { |
||||
Serial.print("\\x"); |
||||
uint8_t c1 = (uint8_t)c >> 4; |
||||
Serial.print((char)(c1 >= 10 ? 'A'+c1-10 : '0' + c1)); |
||||
uint8_t c2 = (uint8_t)c & 0xf; |
||||
Serial.print((char)(c2 >= 10 ? 'A'+c2-10 : '0' + c2)); |
||||
} else { |
||||
Serial.print(c); |
||||
} |
||||
} |
||||
|
||||
uint32_t timer = 0; |
||||
|
||||
void loop() { |
||||
char response[266]; |
||||
esp.process(); |
||||
if(wifiConnected) { |
||||
char buff[64]; |
||||
uint32_t t0 = millis(); |
||||
sprintf(buff, "/update?api_key=MAY03AKJDMPP4Y4I&field1=%ld", timer); |
||||
Serial.print("ARDUINO: send get "); |
||||
Serial.println(buff); |
||||
rest.get((const char*)buff); |
||||
|
||||
uint16_t err = rest.getResponse(response, 266); |
||||
if(err == HTTP_STATUS_OK){ |
||||
Serial.println("ARDUINO: GET successful"); |
||||
Serial.print("ARDUINO: got <<"); |
||||
int len = strlen(response); |
||||
for (int i=0; i<len; i++) printChar(response[i]); |
||||
Serial.println(">>"); |
||||
} else if (err == 0) { |
||||
Serial.println("ARDUINO: GET timed out"); |
||||
} else { |
||||
Serial.print("ARDUINO: GET failed: "); |
||||
Serial.println(err); |
||||
} |
||||
timer = millis() - t0; |
||||
Serial.print("ARDUINO: took "); |
||||
Serial.print(timer); |
||||
Serial.println("ms"); |
||||
delay(3000); |
||||
} |
||||
delay(100); |
||||
} |
||||
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
HOST ?= esp-link
|
||||
LIBRARYPATH = $(ARDUINODIR)/libraries ../../..
|
||||
LIBRARIES = ELClient
|
||||
CPPFLAGS =
|
||||
SERIALDEV = net:$(HOST):2323
|
||||
include ../arduino.mk |
||||
|
||||
flash: all |
||||
../avrflash $(HOST) mqtt.hex
|
||||
nc $(HOST) 23
|
||||
|
||||
run: upload size |
||||
nc $(HOST) 23
|
||||
@ -0,0 +1,9 @@
@@ -0,0 +1,9 @@
|
||||
MQTT example |
||||
============ |
||||
|
||||
This is a simple example of a sketch that subscribes to an mqtt topic and then publishes messages |
||||
to that topic, which it subsequently receives and prints. |
||||
|
||||
**Important** For this sketch to work you must turn off the UART debug log in esp-link (on |
||||
the Debug Log page). The reason is that otherwise esp-link prints too much to its uart and then |
||||
misses incoming characters. |
||||
@ -0,0 +1,516 @@
@@ -0,0 +1,516 @@
|
||||
:100000000C943F000C9467000C9467000C946700FC |
||||
:100010000C9467000C9467000C9467000C946700C4 |
||||
:100020000C9467000C9467000C9467000C946700B4 |
||||
:100030000C9467000C9467000C9467000C946700A4 |
||||
:100040000C94F8010C9467000C944D030C947F03FE |
||||
:100050000C9467000C9467000C9467000C94670084 |
||||
:100060000C9467000C946700436F6E6E6563746553 |
||||
:1000700064434220697320307800E501AF03112406 |
||||
:100080001FBECFEFD8E0DEBFCDBF12E0A0E0B1E0F1 |
||||
:10009000E8EBFEE102C005900D92A436B107D9F756 |
||||
:1000A00023E0A4E6B2E001C01D92A73CB207E1F74D |
||||
:1000B00010E0CFE3D0E004C02197FE010E94E10CE4 |
||||
:1000C000CD33D107C9F70E9426050C945A0F0C9422 |
||||
:1000D000000066E071E086E293E00E946604109200 |
||||
:1000E0006A02089568E171E086E293E00C94660488 |
||||
:1000F00067E271E086E293E00E94660440E067E315 |
||||
:1001000071E08BE692E00E94070740E063E471E053 |
||||
:100110008BE692E00E94070781E080936A020895CF |
||||
:100120000F931F93CF93DF93CDB7DEB72C970FB606 |
||||
:10013000F894DEBF0FBECDBF8C0162E571E086E2B0 |
||||
:1001400093E00E944E04B801CE0107960E94510C24 |
||||
:10015000BE01695F7F4F86E293E00E94540463E62C |
||||
:1001600071E086E293E00E944E04B801CE01019650 |
||||
:100170000E94510CBE016F5F7F4F86E293E00E94A8 |
||||
:100180005404CE0101960E948902CE0107960E9476 |
||||
:1001900089022C960FB6F894DEBF0FBECDBFDF915B |
||||
:1001A000CF911F910F910895CF93DF931F92CDB7F9 |
||||
:1001B000DEB7DC011496ED91FC9115972281338115 |
||||
:1001C00021303105F1F441E050E0BE016F5F7F4F17 |
||||
:1001D0000E940C0C8981853039F469E671E086E271 |
||||
:1001E00093E00E9466040DC068E771E086E293E048 |
||||
:1001F0000E944E044AE050E0698186E293E00E944A |
||||
:10020000E0040F90DF91CF91089526E040E052EC9A |
||||
:1002100061E070E086E293E00E94FB0569E871E02E |
||||
:1002200086E293E00E94660464ED70E089E892E063 |
||||
:100230000E94CA0740ED57E060E070E087E892E076 |
||||
:100240000E94880B811107C06DE971E086E293E09E |
||||
:100250000E946604EFCF64EB71E086E293E00E94B7 |
||||
:10026000660468E770E08BE692E00E94CA0769E6E0 |
||||
:1002700070E081E792E00E94CA0762E770E087E7DA |
||||
:1002800092E00E94CA0760E970E08DE792E00E9468 |
||||
:10029000CA078BE692E00E947B0666EC71E086E27C |
||||
:1002A00093E00C946604CF92DF92EF92FF920F934B |
||||
:1002B000CF93DF93CDB7DEB72C970FB6F894DEBFA0 |
||||
:1002C0000FBECDBF87E892E00E94190A80916A02B2 |
||||
:1002D000882309F46CC00E944202C0906402D0904E |
||||
:1002E0006502E0906602F0906702DC01CB018C1998 |
||||
:1002F0009D09AE09BF09813A9F40A105B10508F4E7 |
||||
:1003000056C064ED71E086E293E00E94660480913D |
||||
:100310006802909169029C012F5F3F4F3093690200 |
||||
:10032000209368024AE0BE016F5F7F4F0E94EE0E8D |
||||
:1003300000E020E0AE014F5F5F4F67E371E08BE6C6 |
||||
:1003400092E00E94B30780916802909169024AE0AE |
||||
:10035000BE016F5F7F4F8D599F4F0E94EE0E20E0D0 |
||||
:10036000AE014F5F5F4F6FED71E08BE692E00E9450 |
||||
:10037000B30785E892E00E94930C6B017C0164EF67 |
||||
:1003800071E086E293E00E944E042AE030E0B7017B |
||||
:10039000A60186E293E00E9413050E944202609348 |
||||
:1003A00064027093650280936602909367022C96B4 |
||||
:1003B0000FB6F894DEBF0FBECDBFDF91CF910F9186 |
||||
:1003C000FF90EF90DF90CF90089546E253E0BA019E |
||||
:1003D00087E892E00E94680867E872E085E892E0AA |
||||
:1003E0000E948F0C67E872E08BE692E00C94600646 |
||||
:1003F0001F920F920FB60F9211242F933F938F935A |
||||
:100400009F93AF93BF9380911E0390911F03A09180 |
||||
:100410002003B091210330911D0323E0230F2D37DA |
||||
:1004200020F40196A11DB11D05C026E8230F0296F8 |
||||
:10043000A11DB11D20931D0380931E0390931F03E4 |
||||
:10044000A0932003B0932103809122039091230372 |
||||
:10045000A0912403B09125030196A11DB11D8093A5 |
||||
:10046000220390932303A0932403B0932503BF9109 |
||||
:10047000AF919F918F913F912F910F900FBE0F9051 |
||||
:100480001F9018952FB7F89460911E0370911F0369 |
||||
:1004900080912003909121032FBF0895789484B513 |
||||
:1004A000826084BD84B5816084BD85B5826085BD70 |
||||
:1004B00085B5816085BDEEE6F0E080818160808356 |
||||
:1004C000E1E8F0E010828081826080838081816039 |
||||
:1004D0008083E0E8F0E0808181608083E1EBF0E000 |
||||
:1004E000808184608083E0EBF0E0808181608083A4 |
||||
:1004F000EAE7F0E08081846080838081826080838D |
||||
:100500008081816080838081806880831092C100B7 |
||||
:100510000895FC01808191810C947C0DCF93DF9331 |
||||
:10052000EC0188819981009711F00E947C0D19825D |
||||
:1005300018821D821C821B821A82DF91CF9108953E |
||||
:100540000F931F93CF93DF93EC018B016F5F7F4F6E |
||||
:10055000888199810E94140E009731F099838883D5 |
||||
:100560001B830A8381E001C080E0DF91CF911F915E |
||||
:100570000F910895CF93DF93EC0188819981892BA6 |
||||
:1005800029F08A819B818617970760F4CE010E942B |
||||
:10059000A002882341F08C819D81892B19F4E88188 |
||||
:1005A000F981108281E0DF91CF910895EF92FF925F |
||||
:1005B0000F931F93CF93DF93EC017B018A01BA0164 |
||||
:1005C0000E94BA02811104C0CE010E948E0207C0AF |
||||
:1005D0001D830C83B701888199810E94E70ECE01AB |
||||
:1005E000DF91CF911F910F91FF90EF900895FC0143 |
||||
:1005F0001182108213821282158214826115710594 |
||||
:1006000051F0FB0101900020E9F73197AF01461B43 |
||||
:10061000570B0C94D6020895EF92FF920F931F93FD |
||||
:10062000CF93DF93FC01248135816115710511F4AD |
||||
:1006300080E019C041155105A9F07B01EC018A0148 |
||||
:10064000020F131FB8010E94BA02882389F3288180 |
||||
:1006500039818C819D81B701820F931F0E94E70E23 |
||||
:100660001D830C8381E0DF91CF911F910F91FF904B |
||||
:10067000EF900895CF93DF9300D0CDB7DEB76983B5 |
||||
:100680001A8241E050E0BE016F5F7F4F0E940C0371 |
||||
:100690000F900F90DF91CF9108951F920F920FB698 |
||||
:1006A0000F9211242F938F939F93EF93FF93E091D9 |
||||
:1006B0003603F09137038081E0913C03F0913D03D4 |
||||
:1006C00082FD12C0908180913F038F5F8F732091D4 |
||||
:1006D0004003821751F0E0913F03F0E0EA5DFC4FE8 |
||||
:1006E000958F80933F0301C08081FF91EF919F918F |
||||
:1006F0008F912F910F900FBE0F901F9018951F9202 |
||||
:100700000F920FB60F9211242F933F934F935F9345 |
||||
:100710006F937F938F939F93AF93BF93EF93FF93C9 |
||||
:1007200086E293E00E947105FF91EF91BF91AF9136 |
||||
:100730009F918F917F916F915F914F913F912F91F9 |
||||
:100740000F900FBE0F901F90189586E293E00E94C5 |
||||
:10075000350521E0892B09F420E0822F0895E6E297 |
||||
:10076000F3E01382128288EE93E0A0E0B0E084838D |
||||
:100770009583A683B78380E192E09183808385ECA3 |
||||
:1007800090E09587848784EC90E09787868780EC5B |
||||
:1007900090E0918B808B81EC90E0938B828B82EC4C |
||||
:1007A00090E0958B848B86EC90E0978B868B118EF6 |
||||
:1007B000128E138E148E0895CF92DF92EF92FF92D5 |
||||
:1007C0000F931F93CF93DF936C017A018B01C0E0ED |
||||
:1007D000D0E0CE15DF0589F0D8016D918D01D601ED |
||||
:1007E000ED91FC910190F081E02DC6010995892BD6 |
||||
:1007F00011F47E0102C02196ECCFC701DF91CF91A9 |
||||
:100800001F910F91FF90EF90DF90CF9008956115A9 |
||||
:10081000710579F0FB0101900020E9F73197AF01F4 |
||||
:10082000461B570BDC01ED91FC910280F381E02D1A |
||||
:10083000099480E090E00895EF92FF920F931F9348 |
||||
:10084000CF93DF938C017B01C0E0D0E0F701EC0F88 |
||||
:10085000FD1F6491662361F0D801ED91FC91019038 |
||||
:10086000F081E02DC8010995892B11F02196EECF7A |
||||
:10087000CE01DF91CF911F910F91FF90EF900895DE |
||||
:10088000DC01ED91FC91DB0114964D915C91159783 |
||||
:100890006D917C910280F381E02D09940C94070402 |
||||
:1008A0006BEF71E00C9407040F931F93CF93DF93CA |
||||
:1008B000EC010E9440048C01CE010E945004800F84 |
||||
:1008C000911FDF91CF911F910F9108950F931F9367 |
||||
:1008D000CF93DF93EC010E9407048C01CE010E94AC |
||||
:1008E0005004800F911FDF91CF911F910F910895B8 |
||||
:1008F0008F929F92AF92BF92CF92DF92EF92FF9230 |
||||
:100900000F931F93CF93DF93CDB7DEB7A1970FB6A9 |
||||
:10091000F894DEBF0FBECDBF7C01D42EC52EDB0107 |
||||
:1009200019A2223008F42AE08E010F5D1F4F822E9B |
||||
:10093000912CA12CB12C6D2D7C2DCD01A501940104 |
||||
:100940000E94BF0CD22EC32EDA01015011096A3069 |
||||
:1009500071058105910510F4605D01C0695CF801C5 |
||||
:100960006083232B242B252B31F7B801C7010E946C |
||||
:100970000704A1960FB6F894DEBF0FBECDBFDF917E |
||||
:10098000CF911F910F91FF90EF90DF90CF90BF908C |
||||
:10099000AF909F908F9008952115310541F4DC01AF |
||||
:1009A000ED91FC910190F081E02D642F09940C945D |
||||
:1009B00078049A01462F50E060E070E00C94CC047B |
||||
:1009C0000F931F93CF93DF93EC019A01462F50E0D2 |
||||
:1009D00060E070E00E94CC048C01CE010E945004C3 |
||||
:1009E000800F911FDF91CF911F910F9108959A0170 |
||||
:1009F000AB0160E070E00C94CC040F931F93CF9395 |
||||
:100A0000DF93EC019A01AB0160E070E00E94CC043E |
||||
:100A10008C01CE010E945004800F911FDF91CF9175 |
||||
:100A20001F910F9108950F931F93CF93DF93EC01C4 |
||||
:100A30000E94CC048C01CE010E945004800F911FB3 |
||||
:100A4000DF91CF911F910F91089508950E944E025A |
||||
:100A50000E9425050E940501C3E6D5E00E945301CE |
||||
:100A60002097E1F30E946305F9CFFC01918D228D5F |
||||
:100A7000892F90E0805C9F4F821B91098F7399278B |
||||
:100A80000895FC01918D828D981731F0828DE80FC9 |
||||
:100A9000F11D858D90E008958FEF9FEF0895FC0183 |
||||
:100AA000918D828D981761F0828DDF01A80FB11DA5 |
||||
:100AB0005D968C91928D9F5F9F73928F90E00895C9 |
||||
:100AC0008FEF9FEF089585EA93E0892B49F080E04E |
||||
:100AD00090E0892B29F00E94A50381110C9400005D |
||||
:100AE0000895FC01848DDF01A80FB11DA35ABF4FEB |
||||
:100AF0002C91848D90E001968F739927848FA6891D |
||||
:100B0000B7892C93A089B1898C9180648C93938D43 |
||||
:100B1000848D981306C00288F389E02D80818F7D33 |
||||
:100B200080830895CF93DF93EC01888D8823C9F0EB |
||||
:100B3000EA89FB89808185FD05C0A889B9898C91E6 |
||||
:100B400086FD0FC00FB607FCF5CF808185FFF2CF81 |
||||
:100B5000A889B9898C9185FFEDCFCE010E947105DE |
||||
:100B6000E7CFDF91CF910895EF92FF920F931F93FC |
||||
:100B7000CF93DF93EC0181E0888F9B8D8C8D981350 |
||||
:100B800005C0E889F989808185FD24C0F62E0B8D8A |
||||
:100B900010E00F5F1F4F0F731127E02E8C8DE812AE |
||||
:100BA0000CC00FB607FCFACFE889F989808185FF70 |
||||
:100BB000F5CFCE010E947105F1CF8B8DFE01E80FBC |
||||
:100BC000F11DE35AFF4FF0820B8FEA89FB89808188 |
||||
:100BD000806207C0EE89FF896083E889F989808196 |
||||
:100BE0008064808381E090E0DF91CF911F910F912D |
||||
:100BF000FF90EF900895CF92DF92EF92FF921F93B4 |
||||
:100C0000CF93DF93EC016A017B01122FE889F98908 |
||||
:100C100082E080834115514E61057105B1F060E0BD |
||||
:100C200079E08DE390E0A70196010E94BF0CDA0104 |
||||
:100C3000C9010197A109B109B695A795979587951F |
||||
:100C4000AC01411580E15807A8F0E889F9891082C4 |
||||
:100C500060E874E88EE190E0A70196010E94BF0C65 |
||||
:100C6000BA01A90141505109610971097695679549 |
||||
:100C700057954795EC85FD855083EE85FF8540832C |
||||
:100C8000188EEC89FD891083EA89FB898081806157 |
||||
:100C90008083EA89FB89808188608083EA89FB8977 |
||||
:100CA000808180688083EA89FB8980818F7D808351 |
||||
:100CB000DF91CF911F91FF90EF90DF90CF9008953B |
||||
:100CC0000F931F93CF93DF93EC018B010E94C40716 |
||||
:100CD000CE0106960E94C407CE010C960E94C4075E |
||||
:100CE000CE0142960E94C407198F088FDF91CF91E1 |
||||
:100CF0001F910F9108958F929F92AF92BF92EF92A2 |
||||
:100D0000FF920F931F93CF93DF9300D000D0CDB706 |
||||
:100D1000DEB77C0168E670E086E293E00E941C0486 |
||||
:100D200047010F2C000CAA08BB0820E130E0B501F8 |
||||
:100D3000A40186E293E00E94130504E010E020E0A5 |
||||
:100D400030E0A9016AE070E0F701808D918D0E948A |
||||
:100D5000A80A89829A82AB82BC8244E050E0BE013C |
||||
:100D60006F5F7F4FF701808D918D0E94250BC7012A |
||||
:100D70000696092E000CAA0BBB0B89839A83AB83C2 |
||||
:100D8000BC8344E050E0BE016F5F7F4FF701808D70 |
||||
:100D9000918D0E94250BC7010C96092E000CAA0B01 |
||||
:100DA000BB0B89839A83AB83BC8344E050E0BE01D4 |
||||
:100DB0006F5F7F4FF701808D918D0E94250BC701DA |
||||
:100DC0004296092E000CAA0BBB0B89839A83AB8336 |
||||
:100DD000BC8344E050E0BE016F5F7F4FF701808D20 |
||||
:100DE000918D0E94250BF701808D918D0E945208F4 |
||||
:100DF0000F900F900F900F90DF91CF911F910F9157 |
||||
:100E0000FF90EF90BF90AF909F908F900895CF92FA |
||||
:100E1000DF92EF92FF920F931F93CF93DF931F9276 |
||||
:100E2000CDB7DEB77C016B01498302E010E020E022 |
||||
:100E300030E0A9016CE070E0FC01808D918D0E9492 |
||||
:100E4000A80AF60101900020E9F73197AF014C198B |
||||
:100E50005D09B601F701808D918D0E94250B41E05F |
||||
:100E600050E0BE016F5F7F4FF701808D918D0E9432 |
||||
:100E7000250BF701808D918D0E9452080F90DF9114 |
||||
:100E8000CF911F910F91FF90EF90DF90CF90089539 |
||||
:100E90008F929F92AF92BF92CF92DF92EF920F9379 |
||||
:100EA0001F93CF93DF9300D000D0CDB7DEB76C0196 |
||||
:100EB0005B014A013A8329830B83EC8205E010E051 |
||||
:100EC00020E030E0A9016BE070E0FC01808D918DA5 |
||||
:100ED0000E94A80AF50101900020E9F73197AF01BF |
||||
:100EE0004A195B09B501F601808D918D0E94250B91 |
||||
:100EF00049815A81B401F601808D918D0E94250BA4 |
||||
:100F000042E050E0BE016F5F7F4FF601808D918D12 |
||||
:100F10000E94250B41E050E0BE016D5F7F4FF6015E |
||||
:100F2000808D918D0E94250B41E050E0BE016C5FE9 |
||||
:100F30007F4FF601808D918D0E94250BF601808DEB |
||||
:100F4000918D0E9452080F900F900F900F90DF919B |
||||
:100F5000CF911F910F91EF90DF90CF90BF90AF9006 |
||||
:100F60009F908F900895EF920F93FA0101900020C7 |
||||
:100F7000E9F73197E41BF50BE02E022F9F010E9449 |
||||
:100F800048070F91EF900895FC011182108213829F |
||||
:100F900012820895FC01738362830895DC01129626 |
||||
:100FA000ED91FC9113973097F1F02D913C911197B1 |
||||
:100FB00021153105B1F014964D915C911597CA0138 |
||||
:100FC0009595879540FF0AC0D901A80FB91F4D918B |
||||
:100FD0005C91E40FF51F0190F081E02D820F931FCB |
||||
:100FE0000994CB0109940895FC0180819181892B9A |
||||
:100FF00039F481E022813381232B19F480E00895B4 |
||||
:1010000081E00895CF93DF93EC018A859B85603C56 |
||||
:10101000A1F06B3D21F5DC01ED91FC910190F08197 |
||||
:10102000E02D6BED09958A859B85DC01ED91FC91A6 |
||||
:101030000190F081E02D6DED18C0DC01ED91FC9187 |
||||
:101040000190F081E02D6BED09958A859B85DC018F |
||||
:10105000ED91FC910190F081E02D6CED06C0DC017A |
||||
:10106000ED91FC910190F081E02DDF91CF910994F9 |
||||
:10107000EF92FF920F931F93CF93DF937C01EB01CD |
||||
:101080008B01040F151FC017D10729F06991C70103 |
||||
:101090000E940208F8CFDF91CF911F910F91FF902E |
||||
:1010A000EF900895CF93DF93EC01BC01635F7F4F16 |
||||
:1010B00042E050E00E9438088A859B85DC01ED9172 |
||||
:1010C000FC910190F081E02D60ECDF91CF910994CB |
||||
:1010D0000F931F93CF93DF93EC018B01FC0141939E |
||||
:1010E0005193CF010E94C4071B870A8781E08C8738 |
||||
:1010F000CE014696988B8F8780E890E09A8B898BFB |
||||
:101100001C8A1B8A1D8ADF91CF911F910F91089530 |
||||
:10111000FC012485222321F0808191810C946604B6 |
||||
:1011200008954627342F252FA901442784E0440F32 |
||||
:10113000551F8A95E1F742275327CA01892F99271E |
||||
:1011400082958F7048275927CA01882735E09695E0 |
||||
:1011500087953A95E1F7842795270895EF92FF92B6 |
||||
:101160000F931F93CF93DF937C01C901EB018B0198 |
||||
:10117000040F151FC017D10731F06991AC01C701E9 |
||||
:101180000E949108F7CFDF91CF911F910F91FF90AF |
||||
:10119000EF900895AF92BF92CF92DF92EF92FF92BD |
||||
:1011A0000F931F93CF93DF9300D000D000D0CDB723 |
||||
:1011B000DEB78C01DC011F96ED90FC9050971C96D9 |
||||
:1011C0008C911C97882309F47DC06CE172E08D91AD |
||||
:1011D0009C910E944E04F801638974894AE050E0B2 |
||||
:1011E000808191810E94F70466E272E0D8018D91BE |
||||
:1011F0009C910E944E04F80147855089052E000CF1 |
||||
:10120000660B770B20E130E0808191810E94CC0455 |
||||
:101210006AE472E0D8018D919C910E944E04F7011E |
||||
:101220006081718140E150E0D8018D919C910E94D4 |
||||
:10123000F7046BE472E0F801808191810E944E0412 |
||||
:10124000D70114964D915D916D917C91179720E196 |
||||
:1012500030E0F801808191810E94CC046BE472E05F |
||||
:10126000D8018D919C910E944E04F7016281738197 |
||||
:1012700040E150E0D8018D919C910E94F70488E0F4 |
||||
:10128000C82ED12CF8012389348980819181C2161E |
||||
:10129000D306B0F46BE472E00E944E04D8011F96AE |
||||
:1012A000ED91FC915097EC0DFD1D40E150E0608107 |
||||
:1012B0008D919C910E94D904BFEFCB1ADB0AE2CF3B |
||||
:1012C0000E945004D8015396CD90DC905497B2E020 |
||||
:1012D000CB1AD108F801A784B08820E030E0A6013D |
||||
:1012E000B501C8010E94AE08F501EC0DFD1D20817D |
||||
:1012F00031818217930731F069E272E0C8010E94E0 |
||||
:10130000880882C0D7018D919C918230910539F077 |
||||
:1013100083309105F1F0019709F06CC05BC0F801D2 |
||||
:101320008485882309F473C06AE372E08081918127 |
||||
:101330000E944E04D70114964D915D916D917C9160 |
||||
:1013400017972AE030E0F801808191810E9413050F |
||||
:101350005EC0D8011C968C911C97882329F163E408 |
||||
:1013600072E08D919C910E944E04F7014481558159 |
||||
:10137000668177812AE030E0D8018D919C910E94AE |
||||
:10138000CC046BE472E0F801808191810E944E04EC |
||||
:10139000D70112966D917C9113974AE050E0F801C5 |
||||
:1013A000808191810E94FD04D70114960D911C91BA |
||||
:1013B0001597C8010E94F407882331F1B701CE01C7 |
||||
:1013C00001960E94020CBE016F5F7F4FC8010E9410 |
||||
:1013D000CE071AC06DE472E0F801808191810E940D |
||||
:1013E0006604D8011896ED91FC911997309761F039 |
||||
:1013F00009950AC0F8018485882331F068E572E018 |
||||
:10140000808191810E94660480E090E001C0C70164 |
||||
:1014100026960FB6F894DEBF0FBECDBFDF91CF91F9 |
||||
:101420001F910F91FF90EF90DF90CF90BF90AF9002 |
||||
:1014300008951F93CF93DF93EC0111E08A859B857C |
||||
:10144000DC01ED91FC910480F581E02D0995892B5B |
||||
:1014500009F443C08A859B85DC01ED91FC910680EF |
||||
:10146000F781E02D09958B3D910511F41D8BE6CF99 |
||||
:101470002B893C89803C910579F42830310520F096 |
||||
:10148000CE010E94CA0802C080E090E01C8A1B8A3C |
||||
:101490001D8A009799F223C04D89442361F08C3D49 |
||||
:1014A000910531F08D3D910529F48BED90E002C05E |
||||
:1014B00080EC90E01D8A49895A892417350708F085 |
||||
:1014C000BDCF4F855889B9016F5F7F4F7C8B6B8B88 |
||||
:1014D000FA01E20FF31F8083B1CF80E090E0DF914B |
||||
:1014E000CF911F9108958F929F92AF92BF92CF920A |
||||
:1014F000DF92EF92FF920F931F93CF93DF93EC0154 |
||||
:101500006A017B010E9442024B015C010E9442027F |
||||
:101510008B019C01081919092A093B090C151D05A5 |
||||
:101520002E053F0530F4CE010E94190A009771F391 |
||||
:1015300002C080E090E0DF91CF911F910F91FF906A |
||||
:10154000EF90DF90CF90BF90AF909F908F900895D5 |
||||
:10155000EF92FF920F931F93CF93DF93CDB7DEB738 |
||||
:1015600028970FB6F894DEBF0FBECDBF7C017A83FB |
||||
:1015700069832B833C834D835E8318870F83DC0153 |
||||
:101580001E961C921E921D971A968D919C911B97E8 |
||||
:10159000DC01ED91FC910190F081E02D60EC09956A |
||||
:1015A00042E050E0BE016F5F7F4FC7010E943808E4 |
||||
:1015B000F7012585368542E050E0BE016F5F7F4F21 |
||||
:1015C000C7010E94AE08D7011E969C938E931D976B |
||||
:1015D00042E050E0BE01695F7F4FC7010E943808BA |
||||
:1015E000F7012585368542E050E0BE01695F7F4FF7 |
||||
:1015F000C7010E94AE08D7011E969C938E931D973B |
||||
:1016000044E050E0BE016D5F7F4FC7010E94380883 |
||||
:10161000F7012585368544E050E0BE016D5F7F4FC0 |
||||
:10162000C7010E94AE08D7011E969C938E931D970A |
||||
:1016300028960FB6F894DEBF0FBECDBFDF91CF91D5 |
||||
:101640001F910F91FF90EF900895CF92DF92EF924C |
||||
:10165000FF920F931F93CF93DF9300D0CDB7DEB7E8 |
||||
:101660008C017B015A83498342E050E0BE016F5FE9 |
||||
:101670007F4F0E943808F8012585368542E050E00A |
||||
:10168000BE016F5F7F4FC8010E94AE08F8019687C8 |
||||
:101690008587C980DA80CE0CDF1CEC14FD0491F044 |
||||
:1016A000F7016081C8010E940208F801458556854E |
||||
:1016B000F70161917F01C8010E949108F8019687A6 |
||||
:1016C0008587EBCFE980FA80F194E194F108F3E0AB |
||||
:1016D000EF22FF24F1E0EF1AF10878F060E0C80192 |
||||
:1016E0000E940208F8014585568560E0C8010E9405 |
||||
:1016F0009108F80196878587EDCF0F900F90DF91C5 |
||||
:10170000CF911F910F91FF90EF90DF90CF900895B0 |
||||
:101710004F925F926F927F92AF92BF92CF92DF9281 |
||||
:10172000EF92FF920F931F93CF93DF93EC012A0167 |
||||
:101730003B018A859B85DC01ED91FC910190F08154 |
||||
:10174000E02D60EC09956E01B2E0CB0ED11C0D2CA2 |
||||
:10175000000CEE08FF0800E010E0A701960161E030 |
||||
:1017600070E0CE010E94A80ACE010E945208A8840F |
||||
:10177000B98419861886B301A201CE010E94730AAA |
||||
:101780008C01892B69F1F80144815581668177814B |
||||
:101790008C854C155D056E057F0561F4882331F05D |
||||
:1017A00062E572E0888199810E946604B986A88604 |
||||
:1017B00081E019C08823F9F26EE572E08881998191 |
||||
:1017C0000E944E04D80114964D915D916D917C91CB |
||||
:1017D00017972AE030E0888199810E941305CBCFCA |
||||
:1017E000B986A88680E0DF91CF911F910F91FF907D |
||||
:1017F000EF90DF90CF90BF90AF907F906F905F9011 |
||||
:101800004F900895FC0175836483685F7F4F7383F5 |
||||
:101810006283118210820895EF92FF920F931F93BB |
||||
:10182000CF93DF93EC0188819981EC81FD81228146 |
||||
:1018300033818217930760F5EA81FB810191119151 |
||||
:101840002EEF3FEF201B310B7901A3E0EA22FF24AA |
||||
:10185000FB83EA83019699838883CB019A0104175D |
||||
:10186000150708F49801260F371F8217930729F0F0 |
||||
:101870004191DC014D93CD01F8CF9701200F311F2D |
||||
:101880008A819B81280F391F3B832A83C80102C0AC |
||||
:101890008FEF9FEFDF91CF911F910F91FF90EF900E |
||||
:1018A0000895CF92DF92EF92FF920F931F93CF9301 |
||||
:1018B000DF936C01EB016DEF71E00E94F702EA81AA |
||||
:1018C000FB81E190F1900EEF1FEF0E191F090370DD |
||||
:1018D0001127FB83EA838881998101969983888304 |
||||
:1018E000EA81FB81E114F10461F0CF0101969B8351 |
||||
:1018F0008A836081C6010E943A0381E0E81AF108F8 |
||||
:10190000EFCF0E0F1F1F1B830A83C601DF91CF91FC |
||||
:101910001F910F91FF90EF90DF90CF900895FC0101 |
||||
:101920007183608308950F931F93CF93DF93EC012E |
||||
:1019300000E010E020E030E0A90167E070E088817D |
||||
:1019400099810E94A80A888199810E94520840EDDD |
||||
:1019500057E060E070E0888199810E94730A0097E7 |
||||
:1019600031F0FC01648175818681978103C060E05C |
||||
:1019700070E0CB01DF91CF911F910F910895A1E20B |
||||
:101980001A2EAA1BBB1BFD010DC0AA1FBB1FEE1FF9 |
||||
:10199000FF1FA217B307E407F50720F0A21BB30B44 |
||||
:1019A000E40BF50B661F771F881F991F1A9469F7C0 |
||||
:1019B00060957095809590959B01AC01BD01CF011C |
||||
:1019C0000895EE0FFF1F0590F491E02D0994CF9339 |
||||
:1019D000DF938230910510F482E090E0E091C5033E |
||||
:1019E000F091C60320E030E0C0E0D0E0309711F184 |
||||
:1019F0004081518148175907C0F04817590761F4D1 |
||||
:101A000082819381209719F09B838A832BC09093C6 |
||||
:101A1000C6038093C50326C02115310519F042176E |
||||
:101A2000530718F49A01BE01DF01EF010280F38130 |
||||
:101A3000E02DDCCF2115310509F1281B390B2430AD |
||||
:101A4000310590F412968D919C9113976115710553 |
||||
:101A500021F0FB019383828304C09093C60380939B |
||||
:101A6000C503FD01329644C0FD01E20FF31F8193CF |
||||
:101A70009193225031092D933C933AC02091C30396 |
||||
:101A80003091C403232B41F42091020130910301D2 |
||||
:101A90003093C4032093C3032091000130910101CE |
||||
:101AA0002115310541F42DB73EB740910401509105 |
||||
:101AB0000501241B350BE091C303F091C403E21729 |
||||
:101AC000F307A0F42E1B3F0B2817390778F0AC0161 |
||||
:101AD0004E5F5F4F2417350748F04E0F5F1F50933E |
||||
:101AE000C4034093C3038193919302C0E0E0F0E00C |
||||
:101AF000CF01DF91CF9108950F931F93CF93DF9381 |
||||
:101B0000009709F48CC0FC01329713821282009175 |
||||
:101B1000C5031091C6030115110581F4208131819F |
||||
:101B2000820F931F2091C3033091C40328173907F4 |
||||
:101B300079F5F093C403E093C30371C0D80140E08A |
||||
:101B400050E0AE17BF0750F412962D913C911397B9 |
||||
:101B5000AD012115310509F1D901F3CF9D01DA015C |
||||
:101B60003383228360817181860F971F82179307C9 |
||||
:101B700069F4EC0128813981260F371F2E5F3F4F12 |
||||
:101B8000318320838A819B8193838283452B29F42F |
||||
:101B9000F093C603E093C50342C01396FC93EE9303 |
||||
:101BA0001297ED01499159919E01240F351FE217BB |
||||
:101BB000F30771F480819181840F951F029611962D |
||||
:101BC0009C938E938281938113969C938E9312970C |
||||
:101BD000E0E0F0E0D80112968D919C911397009768 |
||||
:101BE00019F0F8018C01F6CF8D919C9198012E5F30 |
||||
:101BF0003F4F820F931F2091C3033091C4032817D6 |
||||
:101C0000390769F4309729F41092C6031092C5037E |
||||
:101C100002C0138212821093C4030093C303DF91A6 |
||||
:101C2000CF911F910F910895A0E0B0E0EAE1FEE0AE |
||||
:101C30000C94270FEC01009721F4CB010E94E70CD4 |
||||
:101C4000B8C0FC01E60FF71F9C0122503109E217D2 |
||||
:101C5000F30708F4ACC0D9010D911C911197061738 |
||||
:101C60001707B0F00530110508F49FC0C8010497AC |
||||
:101C70008617970708F499C002501109061B170B25 |
||||
:101C8000019311936D937C93CF010E947C0D8DC0C5 |
||||
:101C90005B01A01AB10A4C01800E911EA091C503F0 |
||||
:101CA000B091C60340E050E0E12CF12C109709F40C |
||||
:101CB0004AC0A815B905D1F56D907C9011976301C4 |
||||
:101CC00082E0C80ED11CCA14DB0480F1A3014A19BA |
||||
:101CD0005B096A0182E0C80ED11C1296BC90129773 |
||||
:101CE0001396AC91B5E0CB16D10440F0B282A38339 |
||||
:101CF00051834083D9016D937C930AC00E5F1F4FBF |
||||
:101D0000C301800F911FF90191838083EB2DFA2F7E |
||||
:101D1000E114F10431F0D7011396FC93EE9312977E |
||||
:101D200044C0F093C603E093C5033FC08D919C91DE |
||||
:101D300011974817590708F4AC017D0112960D90D0 |
||||
:101D4000BC91A02DB3CF8091C3039091C40388159B |
||||
:101D50009905E1F446175707C8F480910001909166 |
||||
:101D60000101009741F48DB79EB740910401509155 |
||||
:101D70000501841B950BE817F907C8F4F093C40319 |
||||
:101D8000E093C303F901718360830FC0CB010E940C |
||||
:101D9000E70C7C01009759F0A801BE010E94DE0EFD |
||||
:101DA000CE010E947C0DC70104C0CE0102C080E0BC |
||||
:101DB00090E0CDB7DEB7EEE00C94430FFB01DC0101 |
||||
:101DC00002C001900D9241505040D8F70895FB0198 |
||||
:101DD000DC0101900D920020E1F70895BB274A3005 |
||||
:101DE00031F4992322F4BDE2909581959F4F0C9494 |
||||
:101DF000FA0EBB27FB015527AA27880F991FAA1F98 |
||||
:101E0000A41710F0A41B83955051B9F7A05DAA3315 |
||||
:101E100008F0A95DA193009779F7B111B1931192E0 |
||||
:101E2000CB010C94130FDC01FC01672F7191772318 |
||||
:101E3000E1F7329704C07C916D9370836291AE1785 |
||||
:101E4000BF07C8F308952F923F924F925F926F920F |
||||
:101E50007F928F929F92AF92BF92CF92DF92EF923A |
||||
:101E6000FF920F931F93CF93DF93CDB7DEB7CA1BBB |
||||
:101E7000DB0B0FB6F894DEBF0FBECDBF09942A88E6 |
||||
:101E8000398848885F846E847D848C849B84AA848E |
||||
:101E9000B984C884DF80EE80FD800C811B81AA811B |
||||
:101EA000B981CE0FD11D0FB6F894DEBF0FBECDBFE6 |
||||
:081EB000ED010895F894FFCF45 |
||||
:101EB8000000C70380004D51545420646973636F58 |
||||
:101EC8006E6E6563746564004D515454207075627C |
||||
:101ED8006C6973686564004D51545420636F6E6E6D |
||||
:101EE800656374656421002F6573702D6C696E6B72 |
||||
:101EF8002F31002F68656C6C6F2F776F726C642FB1 |
||||
:101F0800230052656365697665643A20746F706969 |
||||
:101F1800633D00646174613D005749464920434F61 |
||||
:101F28004E4E45435445440057494649204E4F5468 |
||||
:101F38002052454144593A2000454C2D436C69656F |
||||
:101F48006E74207374617274696E672100454C2D3C |
||||
:101F5800436C69656E742073796E63206661696C81 |
||||
:101F680065642100454C2D436C69656E7420737956 |
||||
:101F78006E6365642100454C2D4D515454207265A3 |
||||
:101F8800616479007075626C697368696E67002FA7 |
||||
:101F980068656C6C6F2F776F726C642F61726475F3 |
||||
:101FA800696E6F0054696D653A20000D0A006E6114 |
||||
:101FB8006E00696E66006F7666002E0000000000F5 |
||||
:101FC800B405DC0335054F0541059205454C433AF8 |
||||
:101FD80020676F742000204000454C433A20496E2A |
||||
:101FE80076616C69642043524300524553505F56F2 |
||||
:101FF8003A2000524553505F43423A20004E45452F |
||||
:10200800445F53594E432100434D443F3F004241F2 |
||||
:04201800443A200026 |
||||
:00000001FF |
||||
@ -0,0 +1,120 @@
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
* Simple example to demo the esp-link MQTT client |
||||
*/ |
||||
|
||||
#include <ELClient.h> |
||||
#include <ELClientCmd.h> |
||||
#include <ELClientMqtt.h> |
||||
|
||||
// Initialize a connection to esp-link using the normal hardware serial port both for
|
||||
// SLIP and for debug messages.
|
||||
ELClient esp(&Serial, &Serial); |
||||
|
||||
// Initialize CMD client (for GetTime)
|
||||
ELClientCmd cmd(&esp); |
||||
|
||||
// Initialize the MQTT client
|
||||
ELClientMqtt mqtt(&esp); |
||||
|
||||
// Callback made from esp-link to notify of wifi status changes
|
||||
// Here we just print something out for grins
|
||||
void wifiCb(void* response) { |
||||
ELClientResponse *res = (ELClientResponse*)response; |
||||
if (res->argc() == 1) { |
||||
uint8_t status; |
||||
res->popArg(&status, 1); |
||||
|
||||
if(status == STATION_GOT_IP) { |
||||
Serial.println("WIFI CONNECTED"); |
||||
} else { |
||||
Serial.print("WIFI NOT READY: "); |
||||
Serial.println(status); |
||||
} |
||||
} |
||||
} |
||||
|
||||
bool connected; |
||||
|
||||
// Callback when MQTT is connected
|
||||
void mqttConnected(void* response) { |
||||
Serial.println("MQTT connected!"); |
||||
mqtt.subscribe("/esp-link/1"); |
||||
mqtt.subscribe("/hello/world/#"); |
||||
//mqtt.subscribe("/esp-link/2", 1);
|
||||
//mqtt.publish("/esp-link/0", "test1");
|
||||
connected = true; |
||||
} |
||||
|
||||
// Callback when MQTT is disconnected
|
||||
void mqttDisconnected(void* response) { |
||||
Serial.println("MQTT disconnected"); |
||||
connected = false; |
||||
} |
||||
|
||||
// Callback when an MQTT message arrives for one of our subscriptions
|
||||
void mqttData(void* response) { |
||||
ELClientResponse *res = (ELClientResponse *)response; |
||||
|
||||
Serial.print("Received: topic="); |
||||
String topic = res->popString(); |
||||
Serial.println(topic); |
||||
|
||||
Serial.print("data="); |
||||
String data = res->popString(); |
||||
Serial.println(data); |
||||
} |
||||
|
||||
void mqttPublished(void* response) { |
||||
Serial.println("MQTT published"); |
||||
} |
||||
|
||||
void setup() { |
||||
Serial.begin(115200); |
||||
Serial.println("EL-Client starting!"); |
||||
|
||||
// Sync-up with esp-link, this is required at the start of any sketch and initializes the
|
||||
// callbacks to the wifi status change callback. The callback gets called with the initial
|
||||
// status right after Sync() below completes.
|
||||
esp.wifiCb.attach(wifiCb); // wifi status change callback, optional (delete if not desired)
|
||||
bool ok; |
||||
do { |
||||
ok = esp.Sync(); // sync up with esp-link, blocks for up to 2 seconds
|
||||
if (!ok) Serial.println("EL-Client sync failed!"); |
||||
} while(!ok); |
||||
Serial.println("EL-Client synced!"); |
||||
|
||||
// Set-up callbacks for events and initialize with es-link.
|
||||
mqtt.connectedCb.attach(mqttConnected); |
||||
mqtt.disconnectedCb.attach(mqttDisconnected); |
||||
mqtt.publishedCb.attach(mqttPublished); |
||||
mqtt.dataCb.attach(mqttData); |
||||
mqtt.setup(); |
||||
|
||||
//Serial.println("ARDUINO: setup mqtt lwt");
|
||||
//mqtt.lwt("/lwt", "offline", 0, 0); //or mqtt.lwt("/lwt", "offline");
|
||||
|
||||
Serial.println("EL-MQTT ready"); |
||||
} |
||||
|
||||
static int count; |
||||
static uint32_t last; |
||||
|
||||
void loop() { |
||||
esp.Process(); |
||||
|
||||
if (connected && (millis()-last) > 4000) { |
||||
Serial.println("publishing"); |
||||
char buf[12]; |
||||
|
||||
itoa(count++, buf, 10); |
||||
mqtt.publish("/esp-link/1", buf); |
||||
|
||||
itoa(count+99, buf, 10); |
||||
mqtt.publish("/hello/world/arduino", buf); |
||||
|
||||
uint32_t t = cmd.GetTime(); |
||||
Serial.print("Time: "); Serial.println(t); |
||||
|
||||
last = millis(); |
||||
} |
||||
} |
||||
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
HOST ?= esp-link
|
||||
LIBRARYPATH = $(ARDUINODIR)/libraries ../../..
|
||||
LIBRARIES = ELClient
|
||||
CPPFLAGS =
|
||||
SERIALDEV = net:$(HOST):2323
|
||||
include ../arduino.mk |
||||
|
||||
flash: all |
||||
../avrflash $(HOST) rest.hex
|
||||
nc $(HOST) 23
|
||||
|
||||
run: upload size |
||||
nc $(HOST) 23
|
||||
@ -0,0 +1,8 @@
@@ -0,0 +1,8 @@
|
||||
REST example |
||||
============ |
||||
|
||||
Simple REST example that configures a REST client to talk to www.timeapi.org and then |
||||
makes a request every second to get the current time and print it. |
||||
|
||||
This example prints a whole lot more than one would normally given the typical space constraints... |
||||
|
||||
@ -0,0 +1,411 @@
@@ -0,0 +1,411 @@
|
||||
:100000000C9436000C945E000C945E000C945E0020 |
||||
:100010000C945E000C945E000C945E000C945E00E8 |
||||
:100020000C945E000C945E000C945E000C945E00D8 |
||||
:100030000C945E000C945E000C945E000C945E00C8 |
||||
:100040000C947A010C945E000C9456020C94880275 |
||||
:100050000C945E000C945E000C945E000C945E00A8 |
||||
:100060000C945E000C945E006D01B80211241FBE5A |
||||
:10007000CFEFD8E0DEBFCDBF12E0A0E0B1E0E8E313 |
||||
:10008000F8E102C005900D92AE35B107D9F723E033 |
||||
:10009000AEE5B2E001C01D92AB3AB207E1F710E065 |
||||
:1000A000CCE6D0E004C02297FE010E940D0CC836B9 |
||||
:1000B000D107C9F70E9441040C941A0C0C9400005B |
||||
:1000C000CF93DF931F92CDB7DEB7DC011496ED918D |
||||
:1000D000FC911597228133812130310519F541E0DA |
||||
:1000E00050E0BE016F5F7F4F0E94C3098981853058 |
||||
:1000F00051F466E071E08EE093E00E949B0481E0A1 |
||||
:1001000080935E020FC065E171E08EE093E00E9493 |
||||
:100110008E044AE050E069818EE093E00E947C0505 |
||||
:1001200010925E020F90DF91CF910895CF93DF93ED |
||||
:1001300026E040E052EC61E070E08EE093E00E9447 |
||||
:10014000DE0366E271E08EE093E00E949B0460E6CD |
||||
:1001500070E083E792E00E94AF0B40ED57E060E073 |
||||
:1001600070E081E792E00E941A09811107C06AE3FA |
||||
:1001700071E08EE093E00E949B04EFCF61E971E0B3 |
||||
:100180008EE093E00E949B0481E792E00E94750953 |
||||
:1001900040ED57E060E070E081E792E00E940908DE |
||||
:1001A000EC01009781F061E571E08EE093E00E9440 |
||||
:1001B0008E044C815D816E817F812AE030E08EE08B |
||||
:1001C00093E00E94AF0520E040E550E06FE571E06C |
||||
:1001D0008FE592E00E94490AEC01009771F06FE60A |
||||
:1001E00071E08EE093E00E948E044AE050E0BE0190 |
||||
:1001F0008EE093E00E945005FFCF63E871E08EE04F |
||||
:1002000093E0DF91CF910C949B04EF92FF920F93B8 |
||||
:100210001F93CF93DF93CDB7DEB7CA50D1400FB64F |
||||
:10022000F894DEBF0FBECDBF81E792E00E94B00719 |
||||
:1002300080915E02882309F442C040E050E063EA06 |
||||
:1002400071E08FE592E00E94440B9E012F5F3F4FCB |
||||
:1002500079018AE091E0F9019C011192215030402E |
||||
:10026000E1F708E813E120E030E04AE051E0B701AF |
||||
:100270008FE592E00E94670B8C01883C910561F448 |
||||
:100280006CEA71E08EE093E00E949B04B7018EE07F |
||||
:1002900093E00E949B040DC065EC71E08EE093E05A |
||||
:1002A0000E948E044AE050E0B8018EE093E00E9484 |
||||
:1002B000990568EE73E080E090E00E94F301C65F6C |
||||
:1002C000DE4F0FB6F894DEBF0FBECDBFDF91CF91EA |
||||
:1002D0001F910F91FF90EF9008954EE053E0BA0107 |
||||
:1002E00081E792E00E94270661E772E08FE592E0E5 |
||||
:1002F0000C94320A1F920F920FB60F9211242F9373 |
||||
:100300003F938F939F93AF93BF93809106039091F8 |
||||
:100310000703A0910803B09109033091050323E07E |
||||
:10032000230F2D3720F40196A11DB11D05C026E82D |
||||
:10033000230F0296A11DB11D209305038093060390 |
||||
:1003400090930703A0930803B093090380910A03D5 |
||||
:1003500090910B03A0910C03B0910D030196A11D88 |
||||
:10036000B11D80930A0390930B03A0930C03B093E9 |
||||
:100370000D03BF91AF919F918F913F912F910F905E |
||||
:100380000FBE0F901F9018952FB7F8946091060339 |
||||
:100390007091070380910803909109032FBF08957E |
||||
:1003A0003FB7F89480910A0390910B03A0910C033E |
||||
:1003B000B0910D0326B5A89B05C02F3F19F00196FB |
||||
:1003C000A11DB11D3FBF6627782F892F9A2F620F7D |
||||
:1003D000711D811D911D42E0660F771F881F991FB7 |
||||
:1003E0004A95D1F70895CF92DF92EF92FF92CF9383 |
||||
:1003F000DF936B017C010E94D001EB01C114D10499 |
||||
:10040000E104F10489F00E94E80B0E94D0016C1B0A |
||||
:100410007D0B683E734090F381E0C81AD108E10873 |
||||
:10042000F108C851DC4FEACFDF91CF91FF90EF90F8 |
||||
:10043000DF90CF900895789484B5826084BD84B5B0 |
||||
:10044000816084BD85B5826085BD85B5816085BDCF |
||||
:10045000EEE6F0E0808181608083E1E8F0E01082E8 |
||||
:10046000808182608083808181608083E0E8F0E029 |
||||
:10047000808181608083E1EBF0E080818460808313 |
||||
:10048000E0EBF0E0808181608083EAE7F0E080814A |
||||
:1004900084608083808182608083808181608083AA |
||||
:1004A0008081806880831092C10008951F920F920E |
||||
:1004B0000FB60F9211242F938F939F93EF93FF9377 |
||||
:1004C000E0911E03F0911F038081E0912403F091DD |
||||
:1004D000250382FD12C09081809127038F5F8F7367 |
||||
:1004E00020912803821751F0E0912703F0E0E25FAA |
||||
:1004F000FC4F958F8093270301C08081FF91EF917E |
||||
:100500009F918F912F910F900FBE0F901F90189574 |
||||
:100510001F920F920FB60F9211242F933F934F9378 |
||||
:100520005F936F937F938F939F93AF93BF93EF935B |
||||
:10053000FF938EE093E00E943603FF91EF91BF910D |
||||
:10054000AF919F918F917F916F915F914F913F916B |
||||
:100550002F910F900FBE0F901F9018958EE093E093 |
||||
:100560000E94FB0221E0892B09F420E0822F0895EC |
||||
:10057000109211031092100388EE93E0A0E0B0E017 |
||||
:100580008093120390931303A0931403B093150365 |
||||
:100590008FED91E090930F0380930E0385EC90E034 |
||||
:1005A00090931B0380931A0384EC90E090931D03B7 |
||||
:1005B00080931C0380EC90E090931F0380931E03B4 |
||||
:1005C00081EC90E0909321038093200382EC90E0F3 |
||||
:1005D000909323038093220386EC90E0909325036D |
||||
:1005E000809324031092270310922803109229036A |
||||
:1005F00010922A030895FC01818D228D90E0805C89 |
||||
:100600009F4F821B91098F7399270895FC01918D4B |
||||
:10061000828D981731F0828DE80FF11D858D90E065 |
||||
:1006200008958FEF9FEF0895FC01918D828D9817AB |
||||
:1006300061F0828DDF01A80FB11D5D968C91928DC6 |
||||
:100640009F5F9F73928F90E008958FEF9FEF0895C3 |
||||
:100650008EEA92E0892B49F080E090E0892B29F026 |
||||
:100660000E94AE0281110C9400000895FC01848D5B |
||||
:10067000DF01A80FB11DA35ABF4F2C91848D90E0CC |
||||
:1006800001968F739927848FA689B7892C93A089A7 |
||||
:10069000B1898C9180648C93938D848D981306C05E |
||||
:1006A0000288F389E02D80818F7D80830895CF9328 |
||||
:1006B000DF93EC01888D8823C9F0EA89FB8980816A |
||||
:1006C00085FD05C0A889B9898C9186FD0FC00FB63C |
||||
:1006D00007FCF5CF808185FFF2CFA889B9898C917D |
||||
:1006E00085FFEDCFCE010E943603E7CFDF91CF919A |
||||
:1006F0000895CF92DF92FF920F931F93CF93DF93D2 |
||||
:100700001F92CDB7DEB76C0181E0D60158968C936D |
||||
:1007100058975B969C915B975C968C915C9798132D |
||||
:1007200007C05096ED91FC915197808185FD2EC0B8 |
||||
:10073000F601038D10E00F5F1F4F0F731127F02E8E |
||||
:10074000F601848DF81211C00FB607FCF9CFD6015F |
||||
:100750005096ED91FC915197808185FFF1CFC601B4 |
||||
:1007600069830E9436036981EBCF838DE80FF11D09 |
||||
:10077000E35AFF4F6083D6015B960C935B975296CA |
||||
:10078000ED91FC915397808180620CC0D601569602 |
||||
:10079000ED91FC91579760835096ED91FC915197A4 |
||||
:1007A00080818064808381E090E00F90DF91CF9121 |
||||
:1007B0001F910F91FF90DF90CF900895BF92CF923D |
||||
:1007C000DF92EF92FF92CF93DF93EC016A017B01FE |
||||
:1007D000B22EE889F98982E08083411581EE5807BD |
||||
:1007E00061057105A1F060E079E08DE390E0A7017B |
||||
:1007F00096010E94E90B2150310941095109569592 |
||||
:10080000479537952795211580E1380798F0E889B5 |
||||
:10081000F989108260E874E88EE190E0A701960102 |
||||
:100820000E94E90B2150310941095109569547951C |
||||
:1008300037952795EC85FD853083EE85FF852083F0 |
||||
:10084000188EEC89FD89B082EA89FB8980818061FC |
||||
:100850008083EA89FB89808188608083EA89FB89BB |
||||
:10086000808180688083EA89FB8980818F7D808395 |
||||
:10087000DF91CF91FF90EF90DF90CF90BF900895E0 |
||||
:1008800008950E941B020E9440040E949600C8E244 |
||||
:10089000D3E00E9405012097E1F30E942803F9CFDD |
||||
:1008A000CF92DF92EF92FF920F931F93CF93DF933C |
||||
:1008B0006C017A01EB01E60EF71E00E010E0CE15A8 |
||||
:1008C000DF0561F06991D601ED91FC910190F08115 |
||||
:1008D000E02DC6010995080F191FF1CFC801DF915E |
||||
:1008E000CF911F910F91FF90EF90DF90CF900895DF |
||||
:1008F0006115710581F0DB010D900020E9F7AD0174 |
||||
:1009000041505109461B570BDC01ED91FC910280CF |
||||
:10091000F381E02D099480E090E008950C94780430 |
||||
:10092000DC01ED91FC910190F081E02D09946BEEDA |
||||
:1009300071E00C9478040F931F93CF93DF93EC0135 |
||||
:100940000E9478048C01CE010E949704800F911FB1 |
||||
:10095000DF91CF911F910F9108958F929F92AF9247 |
||||
:10096000BF92CF92DF92EF92FF920F931F93CF939C |
||||
:10097000DF93CDB7DEB7A1970FB6F894DEBF0FBEF9 |
||||
:10098000CDBF7C01C42EE52FCB01D22E19A221E0D0 |
||||
:100990002D1510F02AE0D22E8E010F5D1F4F8D2CE9 |
||||
:1009A000912CA12CB12C6C2D7E2FA50194010E94BD |
||||
:1009B000E90B8C2DD29E80191124015011098A3027 |
||||
:1009C00010F4805D01C0895CF80180832115310538 |
||||
:1009D0004105510521F0C22EE32FCA01E4CFB80131 |
||||
:1009E000C7010E947804A1960FB6F894DEBF0FBE2F |
||||
:1009F000CDBFDF91CF911F910F91FF90EF90DF90CE |
||||
:100A0000CF90BF90AF909F908F900895CF92DF923C |
||||
:100A1000EF92FF920F931F93CF93DF93EC016A0144 |
||||
:100A20007B012115310579F4E881F9810190F0818C |
||||
:100A3000E02D642FDF91CF911F910F91FF90EF90E8 |
||||
:100A4000DF90CF9009942A303105E9F477FF1AC07E |
||||
:100A50006DE20E9490048C0144275527BA014C197D |
||||
:100A60005D096E097F092AE0CE010E94AD04800F66 |
||||
:100A7000911FDF91CF911F910F91FF90EF90DF9029 |
||||
:100A8000CF9008952AE0B701A601CE01DF91CF9162 |
||||
:100A90001F910F91FF90EF90DF90CF900C94AD04D9 |
||||
:100AA0000F931F93CF93DF93EC019A01AB0166275D |
||||
:100AB00057FD6095762F0E9406058C01CE010E949D |
||||
:100AC0009704800F911FDF91CF911F910F9108958F |
||||
:100AD0002115310541F4DC01ED91FC910190F0818B |
||||
:100AE000E02D642F09940C94AD049A01462F50E038 |
||||
:100AF00060E070E00C9468050F931F93CF93DF9331 |
||||
:100B0000EC019A01462F50E060E070E00E94680519 |
||||
:100B10008C01CE010E949704800F911FDF91CF912D |
||||
:100B20001F910F9108959A01AB0160E070E00C9461 |
||||
:100B300068050F931F93CF93DF93EC019A01AB01EC |
||||
:100B400060E070E00E9468058C01CE010E9497046D |
||||
:100B5000800F911FDF91CF911F910F9108950F93F7 |
||||
:100B60001F93CF93DF93EC010E9468058C01CE01A7 |
||||
:100B70000E949704800F911FDF91CF911F910F91D9 |
||||
:100B80000895CF93DF93EC0188859985603CA1F0AF |
||||
:100B90006B3D21F5DC01ED91FC910190F081E02DA0 |
||||
:100BA0006BED099588859985DC01ED91FC910190AB |
||||
:100BB000F081E02D6DED18C0DC01ED91FC9101900C |
||||
:100BC000F081E02D6BED099588859985DC01ED912B |
||||
:100BD000FC910190F081E02D6CED06C0DC01ED91FF |
||||
:100BE000FC910190F081E02DDF91CF910994EF927B |
||||
:100BF000FF920F931F93CF93DF937C018A01EB0148 |
||||
:100C0000060F171FC017D10729F06991C7010E946D |
||||
:100C1000C105F8CFDF91CF911F910F91FF90EF9019 |
||||
:100C20000895CF93DF93EC01BC01655F7F4F42E0F5 |
||||
:100C300050E00E94F70588859985DC01ED91FC91D3 |
||||
:100C40000190F081E02D60ECDF91CF9109940F933A |
||||
:100C50001F93CF93DF93EC018B01FC0141935193E0 |
||||
:100C6000CF010E94A90B1987088781E08A87CE01EE |
||||
:100C700044969E878D8780E890E0988B8F871A8AAC |
||||
:100C8000198A1B8ADF91CF911F910F910895FC0162 |
||||
:100C90002285222321F0808191810C949B04089568 |
||||
:100CA00046275427452754279A01222784E0220FFC |
||||
:100CB000331F8A95E1F724273527C901892F992702 |
||||
:100CC00082958F70822793279C01222755E03695C5 |
||||
:100CD00027955A95E1F7822793270895EF92FF927F |
||||
:100CE0000F931F93CF93DF937C018A01C901EB011E |
||||
:100CF000060F171FC017D10731F06991AC01C7016A |
||||
:100D00000E945006F7CFDF91CF911F910F91FF9076 |
||||
:100D1000EF900895AF92BF92CF92DF92EF92FF9241 |
||||
:100D20000F931F93CF93DF9300D000D000D0CDB7A7 |
||||
:100D3000DEB78C01DC011D96ED90FC901E971A9693 |
||||
:100D40008C911A97882309F47DC06CEF71E08D9126 |
||||
:100D50009C910E948E04F801618972894AE050E0FA |
||||
:100D6000808191810E94930566E072E0D8018D91A7 |
||||
:100D70009C910E948E04F80145855685662757FD93 |
||||
:100D80006095762F20E130E0808191810E94680596 |
||||
:100D90006AE272E0D8018D919C910E948E04F70165 |
||||
:100DA0006081718140E150E0D8018D919C910E9459 |
||||
:100DB00093056BE272E0F801808191810E948E04BC |
||||
:100DC000D70114964D915D916D917C91179720E11B |
||||
:100DD00030E0F801808191810E9468056BE272E049 |
||||
:100DE000D8018D919C910E948E04F70162817381DC |
||||
:100DF00040E150E0D8018D919C910E94930568E0FC |
||||
:100E0000C62ED12CF8012189328980819181C216A8 |
||||
:100E1000D306B0F46BE272E00E948E04D8011D96F6 |
||||
:100E2000ED91FC911E97EC0DFD1D40E150E06081BD |
||||
:100E30008D919C910E947505BFEFCB1ADB0AE2CF22 |
||||
:100E40000E949704D8015196CD90DC905297B2E061 |
||||
:100E5000CB1AD108F801A584B68420E030E0A601C1 |
||||
:100E6000B501C8010E946E06F501EC0DFD1D208143 |
||||
:100E700031818217930731F069E072E0C8010E9466 |
||||
:100E800047065BC0D7012D913C91F801808191818B |
||||
:100E900022303105A1F46AE172E00E948E04D7018C |
||||
:100EA00014964D915D916D917C9117972AE030E0F9 |
||||
:100EB000F801808191810E94AF05C70140C02330B5 |
||||
:100EC0003105B9F563E272E00E948E04D7011496F1 |
||||
:100ED0004D915D916D917C9117972AE030E0F8017A |
||||
:100EE000808191810E9468056BE272E0D8018D914A |
||||
:100EF0009C910E948E04F701628173814AE050E068 |
||||
:100F0000D8018D919C910E949905F701048115816A |
||||
:100F1000C8010E94DA0B882381F0B701CE01019647 |
||||
:100F20000E948A09BE016F5F7F4FC8010E94B30B08 |
||||
:100F300004C06DE272E00E949B0480E090E026967F |
||||
:100F40000FB6F894DEBF0FBECDBFDF91CF911F91DA |
||||
:100F50000F91FF90EF90DF90CF90BF90AF900895EA |
||||
:100F60001F93CF93DF93EC0111E088859985DC0115 |
||||
:100F7000ED91FC910480F581E02D0995892B09F410 |
||||
:100F800042C088859985DC01ED91FC910680F7814E |
||||
:100F9000E02D09958B3D910511F41B8BE6CF298936 |
||||
:100FA0003A89803C910579F42830310520F0CE0152 |
||||
:100FB0000E948A0602C080E090E01A8A198A1B8A81 |
||||
:100FC000009799F222C04B89442361F08C3D910532 |
||||
:100FD00031F08D3D910529F48BED90E002C080EC5D |
||||
:100FE00090E01B8A4F8558892417350708F0BDCF3C |
||||
:100FF000ED85FE85A9014F5F5F4F5A8B498BE20F4C |
||||
:10100000F31F8083B2CF80E090E0DF91CF911F91FA |
||||
:1010100008958F929F92AF92BF92CF92DF92EF92FC |
||||
:10102000FF92CF93DF93EC016A017B010E94C40120 |
||||
:101030004B015C010E94C401681979098A099B0966 |
||||
:101040006C157D058E059F0530F4CE010E94B0071A |
||||
:10105000009781F302C080E090E0DF91CF91FF9094 |
||||
:10106000EF90DF90CF90BF90AF909F908F900895BA |
||||
:10107000EF92FF920F931F93CF93DF93CDB7DEB71D |
||||
:1010800028970FB6F894DEBF0FBECDBF7C017A83E0 |
||||
:1010900069832B833C834D835E8318870F83DC0138 |
||||
:1010A0001C961C921E921B9718968D919C911997D5 |
||||
:1010B000DC01ED91FC910190F081E02D60EC09954F |
||||
:1010C00042E050E0BE016F5F7F4FC7010E94F7050D |
||||
:1010D000F7012385348542E050E0BE016F5F7F4F0A |
||||
:1010E000C7010E946E06D7011C969C938E931B9796 |
||||
:1010F00042E050E0BE01695F7F4FC7010E94F705E3 |
||||
:10110000F7012385348542E050E0BE01695F7F4FDF |
||||
:10111000C7010E946E06D7011C969C938E931B9765 |
||||
:1011200044E050E0BE016D5F7F4FC7010E94F705AC |
||||
:10113000F7012385348544E050E0BE016D5F7F4FA9 |
||||
:10114000C7010E946E06D7011C969C938E931B9735 |
||||
:1011500028960FB6F894DEBF0FBECDBFDF91CF91BA |
||||
:101160001F910F91FF90EF900895CF92DF92EF9231 |
||||
:10117000FF920F931F93CF93DF9300D0CDB7DEB7CD |
||||
:101180008C017B015A83498342E050E0BE016F5FCE |
||||
:101190007F4F0E94F705F8012385348542E050E037 |
||||
:1011A000BE016F5F7F4FC8010E946E06F8019487F1 |
||||
:1011B0008387C980DA80CE0CDF1CEC14FD0491F02B |
||||
:1011C000F7016081C8010E94C105F801438554857B |
||||
:1011D000F70161917F01C8010E945006F8019487D0 |
||||
:1011E0008387EBCFE980FA80F194E194F108F3E092 |
||||
:1011F000EF22FF24E114F10491F060E0C8010E94A5 |
||||
:10120000C105F8014385548560E0C8010E9450067D |
||||
:10121000F80194878387F1E0EF1AF108EBCF0F9084 |
||||
:101220000F90DF91CF911F910F91FF90EF90DF9082 |
||||
:10123000CF9008958F929F92AF92BF92CF92DF92FC |
||||
:10124000EF92FF920F931F93CF93DF93EC014A012C |
||||
:101250005B016C0182E0C80ED11CEE24D7FCE09447 |
||||
:10126000FE2C00E010E0A701960161E070E0CE01E5 |
||||
:101270000E943808CE010E941106B501A401CE01DA |
||||
:101280000E9409088C01009711F1F80144815581F1 |
||||
:1012900066817781888199814C155D056E057F0592 |
||||
:1012A00031F463E372E00E949B0481E011C069E3C2 |
||||
:1012B00072E00E948E04F801448155816681778135 |
||||
:1012C0002AE030E0888199810E94AF05D6CF80E086 |
||||
:1012D000DF91CF911F910F91FF90EF90DF90CF9012 |
||||
:1012E000BF90AF909F908F9008950F931F93CF93CF |
||||
:1012F000DF93EC0100E010E020E030E0A90164E0C1 |
||||
:1013000070E00E943808CE01DF91CF911F910F91BC |
||||
:101310000C941106FC0175836483685F7F4F7383AF |
||||
:101320006283118210820895CF93DF93FC01808144 |
||||
:101330009181A481B58112962D913C9113978217CA |
||||
:101340009307E0F4A281B3812D913D91B383A283F1 |
||||
:10135000019691838083EB01B983A8838EEF9FEF81 |
||||
:10136000821B930B83709927820F931F42815381B5 |
||||
:10137000480F591F53834283C90102C08FEF9FEF6B |
||||
:10138000DF91CF9108950F931F93CF93DF93FC01CB |
||||
:10139000A081B181C481D5818A819B81A817B907B9 |
||||
:1013A00050F5C281D381299139918EEF9FEF821B35 |
||||
:1013B000930B83709927D383C2831196B183A08343 |
||||
:1013C0008E01EB01DA012417350708F4D9016A0F01 |
||||
:1013D0007B1FC617D70729F0D8014D918D0149937E |
||||
:1013E000F8CF820F931F42815381480F591F5383B7 |
||||
:1013F0004283C90102C08FEF9FEFDF91CF911F9110 |
||||
:101400000F9108950F931F93CF93DF93EC018B01FE |
||||
:101410006115710511F1BC01645F7F4F42E050E03E |
||||
:10142000C8010E94C309EC81FD816FE372E08081F5 |
||||
:1014300091810E948E046C857D85EC81FD814AE05E |
||||
:1014400050E0808191810E945005BE01605F7F4F16 |
||||
:10145000C8010E9494099F878E87DF91CF911F91C9 |
||||
:101460000F9108950F931F93CF93DF93EC018B019E |
||||
:1014700006960E94A90B1D830C834FEF5FEFBA0104 |
||||
:10148000488359836A837B83DF91CF911F910F91AA |
||||
:101490000895CF92DF92EF92FF920F931F93CF9315 |
||||
:1014A000DF9300D01F92CDB7DEB77C016B015B8369 |
||||
:1014B0004A832983FC019783868342E05AE060E0F7 |
||||
:1014C00070E040875187628773879C012A5F3F4F96 |
||||
:1014D000442737FD4095542F03E010E064E170E0AD |
||||
:1014E000848195810E943808F60101900020E9F777 |
||||
:1014F000AF01415051094C195D09B601F7018481D2 |
||||
:1015000095810E94B50842E050E0BE016E5F7F4FBA |
||||
:10151000F701848195810E94B50841E050E0BE0149 |
||||
:101520006F5F7F4FF701848195810E94B508F701B5 |
||||
:10153000848195810E94110640ED57E060E070E0E3 |
||||
:10154000F701848195810E940908009779F0FC01D8 |
||||
:10155000448155816681778177FD08C0F70140831A |
||||
:1015600051836283738380E090E003C0FC01848137 |
||||
:1015700095810F900F900F90DF91CF911F910F9158 |
||||
:10158000FF90EF90DF90CF9008958F929F92AF924F |
||||
:10159000BF92CF92DF92EF92FF920F931F93CF9360 |
||||
:1015A000DF93EC015B014A01790168011D861C860D |
||||
:1015B000288139814A815B8157FD49C08C819D8199 |
||||
:1015C000E114F10431F0101611061CF403E010E0F0 |
||||
:1015D00002C002E010E065E170E00E943808F4010A |
||||
:1015E00001900020E9F7AF0141505109481959090C |
||||
:1015F000B4018C819D810E94B508F5010190002005 |
||||
:10160000E9F7AF01415051094A195B09B5018C81D5 |
||||
:101610009D810E94B508E114F10449F01C141D04D9 |
||||
:1016200034F4A601B7018C819D810E94B5088C819C |
||||
:101630009D81DF91CF911F910F91FF90EF90DF90EF |
||||
:10164000CF90BF90AF909F908F900C941106DF9138 |
||||
:10165000CF911F910F91FF90EF90DF90CF90BF90AF |
||||
:10166000AF909F908F9008950F931F93F901019071 |
||||
:101670000020E9F78F0101501109021B130B0E9492 |
||||
:10168000C50A1F910F9108959A014AE452E00C9403 |
||||
:10169000340BCF93DF93EC01CB012C853D85232BBD |
||||
:1016A00089F0EE85FF859A01E417F50708F49F019C |
||||
:1016B00068897989A9010E94110C8C859D851D86F8 |
||||
:1016C0001C8602C080E090E0DF91CF9108954F9298 |
||||
:1016D0005F926F927F928F929F92AF92BF92CF92C2 |
||||
:1016E000DF92EF92FF920F931F93CF93DF93EC0162 |
||||
:1016F0005B014A01280139010E94C4016B017C0190 |
||||
:101700008C859D85892BA9F0A401B501CE01DF91BF |
||||
:10171000CF911F910F91FF90EF90DF90CF90BF90EE |
||||
:10172000AF909F908F907F906F905F904F900C94B0 |
||||
:10173000490B0E94C4016C197D098E099F0964152B |
||||
:1017400075058605970500F78C819D810E94B0077D |
||||
:10175000D7CFFC0111821082138212820895FC01FE |
||||
:10176000738362830895DC011296ED91FC911397C7 |
||||
:101770003097F9F02D913C91119721153105B9F071 |
||||
:1017800014968D919C911597AC015595479580FFC6 |
||||
:101790000AC0D901A40FB51F0D90BC91A02DAE0FAA |
||||
:1017A000BF1FED91FC91C901840F951F0994CB01D6 |
||||
:1017B00009940895FC0180819181892B39F481E09D |
||||
:1017C00022813381232B19F480E0089581E008956C |
||||
:1017D0000895A1E21A2EAA1BBB1BFD010DC0AA1F72 |
||||
:1017E000BB1FEE1FFF1FA217B307E407F50720F08A |
||||
:1017F000A21BB30BE40BF50B661F771F881F991F05 |
||||
:101800001A9469F760957095809590959B01AC014D |
||||
:10181000BD01CF010895EE0FFF1F0590F491E02D5B |
||||
:101820000994FB01DC0102C001900D92415050402F |
||||
:08183000D8F70895F894FFCFEA |
||||
:101838000000AB0380005749464920434F4E4E45B0 |
||||
:10184800435445440057494649204E4F5420524579 |
||||
:101858004144593A2000454C2D436C69656E74200B |
||||
:101868007374617274696E672100454C2D436C690D |
||||
:10187800656E742073796E63206661696C65642196 |
||||
:101888000057696669207374617475733A2000772C |
||||
:1018980077772E74696D656170692E6F7267005273 |
||||
:1018A80045535420626567696E206661696C65649A |
||||
:1018B8003A2000454C2D5245535420726561647995 |
||||
:1018C80000454C2D436C69656E742073796E6365B1 |
||||
:1018D8006421002F7574632F6E6F77004152445551 |
||||
:1018E800494E4F3A204745542073756363657373B7 |
||||
:1018F80066756C3A0041524455494E4F3A20474567 |
||||
:1019080054206661696C65643A2000000000007923 |
||||
:10191800035004FB021403060357030D0A006E610B |
||||
:101928006E00696E66006F7666002E00454C433A7D |
||||
:1019380020676F742000204000454C433A20496ED0 |
||||
:1019480076616C69642043524300524553505F5698 |
||||
:101958003A2000524553505F43423A2000434D44D9 |
||||
:101968003F3F0053594E4321004241443A20005220 |
||||
:1019780045535420636F6465200047455400504F19 |
||||
:0E1988005354005055540044454C45544500FE |
||||
:00000001FF |
||||
@ -0,0 +1,94 @@
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* Simple example to demo the El-Client REST calls |
||||
*/ |
||||
|
||||
#include <ELClient.h> |
||||
#include <ELClientRest.h> |
||||
|
||||
// Initialize a connection to esp-link using the normal hardware serial port both for
|
||||
// SLIP and for debug messages.
|
||||
ELClient esp(&Serial, &Serial); |
||||
|
||||
// Initialize a REST client on the connection to esp-link
|
||||
ELClientRest rest(&esp); |
||||
|
||||
boolean wifiConnected = false; |
||||
|
||||
// Callback made from esp-link to notify of wifi status changes
|
||||
// Here we print something out and set a global flag
|
||||
void wifiCb(void *response) { |
||||
ELClientResponse *res = (ELClientResponse*)response; |
||||
if (res->argc() == 1) { |
||||
uint8_t status; |
||||
res->popArg(&status, 1); |
||||
|
||||
if(status == STATION_GOT_IP) { |
||||
Serial.println("WIFI CONNECTED"); |
||||
wifiConnected = true; |
||||
} else { |
||||
Serial.print("WIFI NOT READY: "); |
||||
Serial.println(status); |
||||
wifiConnected = false; |
||||
} |
||||
} |
||||
} |
||||
|
||||
void setup() { |
||||
Serial.begin(115200); // the baud rate here needs to match the esp-link config
|
||||
Serial.println("EL-Client starting!"); |
||||
|
||||
// Sync-up with esp-link, this is required at the start of any sketch and initializes the
|
||||
// callbacks to the wifi status change callback. The callback gets called with the initial
|
||||
// status right after Sync() below completes.
|
||||
esp.wifiCb.attach(wifiCb); // wifi status change callback, optional (delete if not desired)
|
||||
bool ok; |
||||
do { |
||||
ok = esp.Sync(); // sync up with esp-link, blocks for up to 2 seconds
|
||||
if (!ok) Serial.println("EL-Client sync failed!"); |
||||
} while(!ok); |
||||
Serial.println("EL-Client synced!"); |
||||
|
||||
// Get immediate wifi status info for demo purposes. This is not normally used because the
|
||||
// wifi status callback registered above gets called immediately.
|
||||
esp.GetWifiStatus(); |
||||
ELClientPacket *packet; |
||||
if ((packet=esp.WaitReturn()) != NULL) { |
||||
Serial.print("Wifi status: "); |
||||
Serial.println(packet->value); |
||||
} |
||||
|
||||
// Set up the REST client to talk to www.timeapi.org, this doesn't connect to that server,
|
||||
// it just sets-up stuff on the esp-link side
|
||||
int err = rest.begin("www.timeapi.org"); |
||||
if (err != 0) { |
||||
Serial.print("REST begin failed: "); |
||||
Serial.println(err); |
||||
while(1) ; |
||||
} |
||||
Serial.println("EL-REST ready"); |
||||
} |
||||
|
||||
#define BUFLEN 266 |
||||
|
||||
void loop() { |
||||
// process any callbacks coming from esp_link
|
||||
esp.Process(); |
||||
|
||||
// if we're connected make an HTTP request
|
||||
if(wifiConnected) { |
||||
// Request /utc/now from the previously set-up server
|
||||
rest.get("/utc/now"); |
||||
|
||||
char response[BUFLEN]; |
||||
memset(response, 0, BUFLEN); |
||||
uint16_t code = rest.waitResponse(response, BUFLEN); |
||||
if(code == HTTP_STATUS_OK){ |
||||
Serial.println("ARDUINO: GET successful:"); |
||||
Serial.println(response); |
||||
} else { |
||||
Serial.print("ARDUINO: GET failed: "); |
||||
Serial.println(code); |
||||
} |
||||
delay(1000); |
||||
} |
||||
} |
||||
@ -0,0 +1,193 @@
@@ -0,0 +1,193 @@
|
||||
/**
|
||||
* Simple example to demo the El-Client TCP client |
||||
* This example sends out a message to a TCP socket server
|
||||
* and doesn't wait for a response from the server |
||||
*/ |
||||
|
||||
#include <ELClient.h> |
||||
#include <ELClientSocket.h> |
||||
|
||||
// IP address for this demo is a local IP.
|
||||
// Replace it with the IP address where you have a TCP socket server running
|
||||
char * const tcpServer PROGMEM = "192.168.0.102"; |
||||
// Port for this demo is the port used by the TCP socket server.
|
||||
// Replace it with the port that your TCP socket server is listening to
|
||||
uint16_t const tcpPort PROGMEM = 7001; |
||||
|
||||
//###########################################################
|
||||
// For ARDUINO UNO WIFI with I2C to serial chip!
|
||||
//###########################################################
|
||||
// Serial port to ESP8266
|
||||
#include <SC16IS750.h> |
||||
SC16IS750 i2cuart = SC16IS750(SC16IS750_PROTOCOL_I2C,SC16IS750_ADDRESS_AA); |
||||
|
||||
// Initialize a connection to esp-link using the I2Cuart chip of the Arduino Uno WiFi board for
|
||||
// SLIP messages.
|
||||
ELClient esp(&i2cuart); |
||||
|
||||
//###########################################################
|
||||
// For boards using the hardware serial port!
|
||||
//###########################################################
|
||||
// Initialize a connection to esp-link using the normal hardware serial port both for
|
||||
// SLIP and for debug messages.
|
||||
//ELClient esp(&Serial, &Serial);
|
||||
|
||||
// Initialize a TCP socket client on the connection to esp-link
|
||||
ELClientSocket tcp(&esp); |
||||
// Connection number for tcp
|
||||
int tcpConnNum; |
||||
|
||||
// Timer value to send out data
|
||||
uint32_t wait; |
||||
// Time to wait between sending out data
|
||||
uint32_t waitTime; |
||||
// Flag for wifi connection
|
||||
boolean wifiConnected = false; |
||||
|
||||
// Parse error codes and returns error message as char *
|
||||
// Definitions from error values from espconn.h (Espressif SDK)
|
||||
// #define ESPCONN_OK 0 /**< No error, everything OK. */
|
||||
// #define ESPCONN_MEM -1 /**< Out of memory. */
|
||||
// #define ESPCONN_TIMEOUT -3 /**< Timeout. */
|
||||
// #define ESPCONN_RTE -4 /**< Routing problem. */
|
||||
// #define ESPCONN_INPROGRESS -5 /**< Operation in progress. */
|
||||
// #define ESPCONN_MAXNUM -7 /**< Total number exceeds the maximum limitation. */
|
||||
|
||||
// #define ESPCONN_ABRT -8 /**< Connection aborted. */
|
||||
// #define ESPCONN_RST -9 /**< Connection reset. */
|
||||
// #define ESPCONN_CLSD -10 /**< Connection closed. */
|
||||
// #define ESPCONN_CONN -11 /**< Not connected. */
|
||||
|
||||
// #define ESPCONN_ARG -12 /**< Illegal argument. */
|
||||
// #define ESPCONN_IF -14 /**< UDP send error. */
|
||||
// #define ESPCONN_ISCONN -15 /**< Already connected. */
|
||||
|
||||
char* const errTxt[] PROGMEM = {"No error, everything OK.","Out of memory.","Unknown code.","Timeout.","Routing problem.","Operation in progress.", |
||||
"Unknown code.","Total number exceeds the maximum limitation.","Connection aborted.","Connection reset.","Connection closed.", |
||||
"Not connected.","Illegal argument.","Unknown code.","UDP send error.","Already connected."}; |
||||
char * getErrTxt(int16_t commError) { |
||||
commError = commError*-1; |
||||
if (commError <= 15) { |
||||
return (char *) pgm_read_word (&errTxt[commError]); |
||||
} else { |
||||
return (char *) pgm_read_word (&errTxt[2]); // Unknown code
|
||||
} |
||||
} |
||||
|
||||
// Callback for TCP socket, called if data was sent or received
|
||||
// Receives socket client number, can be reused for all initialized TCP socket connections
|
||||
void tcpCb(uint8_t resp_type, uint8_t client_num, uint16_t len, char *data) { |
||||
Serial.println("tcpCb connection #"+String(client_num)); |
||||
if (resp_type == USERCB_SENT) { |
||||
Serial.println("\tSent " + String(len) + " bytes over client#" + String(client_num)); |
||||
} else if (resp_type == USERCB_RECV) { |
||||
char recvData[len+1]; // Prepare buffer for the received data
|
||||
memcpy(recvData, data, len); // Copy received data into the buffer
|
||||
recvData[len] = '\0'; // Terminate the buffer with 0 for proper printout!
|
||||
|
||||
Serial.println("\tReceived " + String(len) + " bytes over the client on connection #" + String(client_num)); |
||||
Serial.println("\tReceived: " + String(recvData)); |
||||
} else if (resp_type == USERCB_RECO) { |
||||
if (len != -11) { // ignore "not connected" error, handled in USERCB_CONN
|
||||
Serial.print("\tConnection problem: "); |
||||
Serial.println(getErrTxt(len)); |
||||
} |
||||
} else if (resp_type == USERCB_CONN) { |
||||
if (len == 0) { |
||||
Serial.println("\tDisconnected"); |
||||
} else { |
||||
Serial.println("\tConnected"); |
||||
} |
||||
} else { |
||||
Serial.println("Received invalid response type"); |
||||
} |
||||
} |
||||
|
||||
// Callback made from esp-link to notify of wifi status changes
|
||||
// Here we print something out and set a global flag
|
||||
void wifiCb(void *response) { |
||||
ELClientResponse *res = (ELClientResponse*)response; |
||||
if (res->argc() == 1) { |
||||
uint8_t status; |
||||
res->popArg(&status, 1); |
||||
|
||||
if(status == STATION_GOT_IP) { |
||||
Serial.println(F("WIFI CONNECTED")); |
||||
wifiConnected = true; |
||||
} else { |
||||
Serial.print(F("WIFI NOT READY: ")); |
||||
Serial.println(status); |
||||
wifiConnected = false; |
||||
} |
||||
} |
||||
} |
||||
|
||||
void setup() { |
||||
Serial.begin(115200); |
||||
//###########################################################
|
||||
// For ARDUINO UNO WIFI with I2C to serial chip!
|
||||
//###########################################################
|
||||
i2cuart.begin(9600); |
||||
|
||||
Serial.println(F("EL-Client starting!")); |
||||
|
||||
// Sync-up with esp-link, this is required at the start of any sketch and initializes the
|
||||
// callbacks to the wifi status change callback. The callback gets called with the initial
|
||||
// status right after Sync() below completes.
|
||||
esp.wifiCb.attach(wifiCb); // wifi status change callback, optional (delete if not desired)
|
||||
bool ok; |
||||
do { |
||||
ok = esp.Sync(); // sync up with esp-link, blocks for up to 2 seconds
|
||||
if (!ok) Serial.println(F("EL-Client sync failed!")); |
||||
} while(!ok); |
||||
Serial.println(F("EL-Client synced!")); |
||||
|
||||
// Wit for WiFi to be connected.
|
||||
esp.GetWifiStatus(); |
||||
ELClientPacket *packet; |
||||
Serial.print(F("Waiting for WiFi ")); |
||||
if ((packet=esp.WaitReturn()) != NULL) { |
||||
Serial.print(F(".")); |
||||
Serial.println(packet->value); |
||||
} |
||||
Serial.println(""); |
||||
|
||||
// Set up the TCP socket client for a connection to <tcpServer> on port <>, this doesn't connect to that server,
|
||||
// it just sets-up stuff on the esp-link side and waits until we send some data
|
||||
tcpConnNum = tcp.begin(tcpServer, tcpPort, SOCKET_TCP_CLIENT, tcpCb); // SOCKET_CLIENT ==> we don't expect a response
|
||||
if (tcpConnNum < 0) { |
||||
Serial.println(F("TCP socket setup failed, try again in 10 seconds after reboot")); |
||||
delay(10000); |
||||
asm volatile (" jmp 0"); |
||||
} else { |
||||
Serial.println(String(tcpServer)+":"+String(tcpPort)+" is served over connection number # = "+String(tcpConnNum)); |
||||
} |
||||
|
||||
Serial.println(F("EL-TCP ready")); |
||||
wait = millis()+29000; // Start first sending in 1 second
|
||||
} |
||||
|
||||
void loop() { |
||||
// process any callbacks coming from esp_link
|
||||
esp.Process(); |
||||
|
||||
// if we're connected send data over TCP socket
|
||||
if(wifiConnected) { |
||||
if (millis() - wait > 30000) { // Send some data every 30 seconds
|
||||
wait = millis(); |
||||
|
||||
// Send message to the previously set-up server #1
|
||||
Serial.print(F("Sending message to ")); |
||||
Serial.print(tcpServer); |
||||
Serial.print(":"); |
||||
Serial.println(tcpPort); |
||||
tcp.send("Message from Arduino Uno WiFi over TCP"); |
||||
} |
||||
} else { |
||||
// This is just for demo, you can as well just try to reconnect
|
||||
// and setup the connection to esp-link again
|
||||
Serial.println(F("Lost WiFi connection, try to reboot")); |
||||
delay(10000); |
||||
asm volatile (" jmp 0"); |
||||
} |
||||
} |
||||
@ -0,0 +1,193 @@
@@ -0,0 +1,193 @@
|
||||
/**
|
||||
* Simple example to demo the El-Client TCP client |
||||
* This example sends out a message to a TCP socket server
|
||||
* and waits for a response from the server |
||||
*/ |
||||
|
||||
#include <ELClient.h> |
||||
#include <ELClientSocket.h> |
||||
|
||||
// IP address for this demo is a local IP.
|
||||
// Replace it with the IP address where you have a TCP socket server running
|
||||
char * const tcpServer PROGMEM = "192.168.0.102"; |
||||
// Port for this demo is the port used by the TCP socket server.
|
||||
// Replace it with the port that your TCP socket server is listening to
|
||||
uint16_t const tcpPort PROGMEM = 7001; |
||||
|
||||
//###########################################################
|
||||
// For ARDUINO UNO WIFI with I2C to serial chip!
|
||||
//###########################################################
|
||||
// Serial port to ESP8266
|
||||
#include <SC16IS750.h> |
||||
SC16IS750 i2cuart = SC16IS750(SC16IS750_PROTOCOL_I2C,SC16IS750_ADDRESS_AA); |
||||
|
||||
// Initialize a connection to esp-link using the I2Cuart chip of the Arduino Uno WiFi board for
|
||||
// SLIP messages.
|
||||
ELClient esp(&i2cuart); |
||||
|
||||
//###########################################################
|
||||
// For boards using the hardware serial port!
|
||||
//###########################################################
|
||||
// Initialize a connection to esp-link using the normal hardware serial port both for
|
||||
// SLIP and for debug messages.
|
||||
//ELClient esp(&Serial, &Serial);
|
||||
|
||||
// Initialize a TCP socket client on the connection to esp-link
|
||||
ELClientSocket tcp(&esp); |
||||
// Connection number for tcp
|
||||
int tcpConnNum; |
||||
|
||||
// Timer value to send out data
|
||||
uint32_t wait; |
||||
// Time to wait between sending out data
|
||||
uint32_t waitTime; |
||||
// Flag for wifi connection
|
||||
boolean wifiConnected = false; |
||||
|
||||
// Parse error codes and returns error message as char *
|
||||
// Definitions from error values from espconn.h (Espressif SDK)
|
||||
// #define ESPCONN_OK 0 /**< No error, everything OK. */
|
||||
// #define ESPCONN_MEM -1 /**< Out of memory. */
|
||||
// #define ESPCONN_TIMEOUT -3 /**< Timeout. */
|
||||
// #define ESPCONN_RTE -4 /**< Routing problem. */
|
||||
// #define ESPCONN_INPROGRESS -5 /**< Operation in progress. */
|
||||
// #define ESPCONN_MAXNUM -7 /**< Total number exceeds the maximum limitation. */
|
||||
|
||||
// #define ESPCONN_ABRT -8 /**< Connection aborted. */
|
||||
// #define ESPCONN_RST -9 /**< Connection reset. */
|
||||
// #define ESPCONN_CLSD -10 /**< Connection closed. */
|
||||
// #define ESPCONN_CONN -11 /**< Not connected. */
|
||||
|
||||
// #define ESPCONN_ARG -12 /**< Illegal argument. */
|
||||
// #define ESPCONN_IF -14 /**< UDP send error. */
|
||||
// #define ESPCONN_ISCONN -15 /**< Already connected. */
|
||||
|
||||
char* const errTxt[] PROGMEM = {"No error, everything OK.","Out of memory.","Unknown code.","Timeout.","Routing problem.","Operation in progress.", |
||||
"Unknown code.","Total number exceeds the maximum limitation.","Connection aborted.","Connection reset.","Connection closed.", |
||||
"Not connected.","Illegal argument.","Unknown code.","UDP send error.","Already connected."}; |
||||
char * getErrTxt(int16_t commError) { |
||||
commError = commError*-1; |
||||
if (commError <= 15) { |
||||
return (char *) pgm_read_word (&errTxt[commError]); |
||||
} else { |
||||
return (char *) pgm_read_word (&errTxt[2]); // Unknown code
|
||||
} |
||||
} |
||||
|
||||
// Callback for TCP socket, called if data was sent or received
|
||||
// Receives socket client number, can be reused for all initialized TCP socket connections
|
||||
void tcpCb(uint8_t resp_type, uint8_t client_num, uint16_t len, char *data) { |
||||
Serial.println("tcpCb connection #"+String(client_num)); |
||||
if (resp_type == USERCB_SENT) { |
||||
Serial.println("\tSent " + String(len) + " bytes over client#" + String(client_num)); |
||||
} else if (resp_type == USERCB_RECV) { |
||||
char recvData[len+1]; // Prepare buffer for the received data
|
||||
memcpy(recvData, data, len); // Copy received data into the buffer
|
||||
recvData[len] = '\0'; // Terminate the buffer with 0 for proper printout!
|
||||
|
||||
Serial.println("\tReceived " + String(len) + " bytes over the client on connection #" + String(client_num)); |
||||
Serial.println("\tReceived: " + String(recvData)); |
||||
} else if (resp_type == USERCB_RECO) { |
||||
if (len != -11) { // ignore "not connected" error, handled in USERCB_CONN
|
||||
Serial.print("\tConnection problem: "); |
||||
Serial.println(getErrTxt(len)); |
||||
} |
||||
} else if (resp_type == USERCB_CONN) { |
||||
if (len == 0) { |
||||
Serial.println("\tDisconnected"); |
||||
} else { |
||||
Serial.println("\tConnected"); |
||||
} |
||||
} else { |
||||
Serial.println("Received invalid response type"); |
||||
} |
||||
} |
||||
|
||||
// Callback made from esp-link to notify of wifi status changes
|
||||
// Here we print something out and set a global flag
|
||||
void wifiCb(void *response) { |
||||
ELClientResponse *res = (ELClientResponse*)response; |
||||
if (res->argc() == 1) { |
||||
uint8_t status; |
||||
res->popArg(&status, 1); |
||||
|
||||
if(status == STATION_GOT_IP) { |
||||
Serial.println(F("WIFI CONNECTED")); |
||||
wifiConnected = true; |
||||
} else { |
||||
Serial.print(F("WIFI NOT READY: ")); |
||||
Serial.println(status); |
||||
wifiConnected = false; |
||||
} |
||||
} |
||||
} |
||||
|
||||
void setup() { |
||||
Serial.begin(115200); |
||||
//###########################################################
|
||||
// For ARDUINO UNO WIFI with I2C to serial chip!
|
||||
//###########################################################
|
||||
i2cuart.begin(9600); |
||||
|
||||
Serial.println(F("EL-Client starting!")); |
||||
|
||||
// Sync-up with esp-link, this is required at the start of any sketch and initializes the
|
||||
// callbacks to the wifi status change callback. The callback gets called with the initial
|
||||
// status right after Sync() below completes.
|
||||
esp.wifiCb.attach(wifiCb); // wifi status change callback, optional (delete if not desired)
|
||||
bool ok; |
||||
do { |
||||
ok = esp.Sync(); // sync up with esp-link, blocks for up to 2 seconds
|
||||
if (!ok) Serial.println(F("EL-Client sync failed!")); |
||||
} while(!ok); |
||||
Serial.println(F("EL-Client synced!")); |
||||
|
||||
// Wit for WiFi to be connected.
|
||||
esp.GetWifiStatus(); |
||||
ELClientPacket *packet; |
||||
Serial.print(F("Waiting for WiFi ")); |
||||
if ((packet=esp.WaitReturn()) != NULL) { |
||||
Serial.print(F(".")); |
||||
Serial.println(packet->value); |
||||
} |
||||
Serial.println(""); |
||||
|
||||
// Set up the TCP socket client for a connection to <tcpServer> on port <>, this doesn't connect to that server,
|
||||
// it just sets-up stuff on the esp-link side and waits until we send some data
|
||||
tcpConnNum = tcp.begin(tcpServer, tcpPort, SOCKET_TCP_CLIENT_LISTEN, tcpCb); // SOCKET_CLIENT ==> we expect a response
|
||||
if (tcpConnNum < 0) { |
||||
Serial.println(F("TCP socket setup failed, try again in 10 seconds after reboot")); |
||||
delay(10000); |
||||
asm volatile (" jmp 0"); |
||||
} else { |
||||
Serial.println(String(tcpServer)+":"+String(tcpPort)+" is served over connection number # = "+String(tcpConnNum)); |
||||
} |
||||
|
||||
Serial.println(F("EL-TCP ready")); |
||||
wait = millis()+29000; // Start first sending in 1 second
|
||||
} |
||||
|
||||
void loop() { |
||||
// process any callbacks coming from esp_link
|
||||
esp.Process(); |
||||
|
||||
// if we're connected send data over TCP socket
|
||||
if(wifiConnected) { |
||||
if (millis() - wait > 30000) { // Send some data every 30 seconds
|
||||
wait = millis(); |
||||
|
||||
// Send message to the previously set-up server #1
|
||||
Serial.print(F("Sending message to ")); |
||||
Serial.print(tcpServer); |
||||
Serial.print(":"); |
||||
Serial.println(tcpPort); |
||||
tcp.send("Message from Uno WiFi over TCP socket"); |
||||
} |
||||
} else { |
||||
// This is just for demo, you can as well just try to reconnect
|
||||
// and setup the connection to esp-link again
|
||||
Serial.println(F("Lost WiFi connection, try to reboot")); |
||||
delay(10000); |
||||
asm volatile (" jmp 0"); |
||||
} |
||||
} |
||||
@ -0,0 +1,179 @@
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
* Simple example to demo the El-Client TCP server |
||||
* This example starts a TCP socket server and waits |
||||
* for clients to connect |
||||
*/ |
||||
|
||||
#include <ELClient.h> |
||||
#include <ELClientSocket.h> |
||||
|
||||
// IP address for this demo is a local IP.
|
||||
// Replace it with the IP address where you have a TCP socket server running
|
||||
char * const tcpServer PROGMEM = "192.168.0.102"; |
||||
// Port for this demo is the port used by the TCP socket server.
|
||||
// Replace it with the port that your TCP socket server is listening to
|
||||
uint16_t const tcpPort PROGMEM = 7002; |
||||
|
||||
//###########################################################
|
||||
// For ARDUINO UNO WIFI with I2C to serial chip!
|
||||
//###########################################################
|
||||
// Serial port to ESP8266
|
||||
#include <SC16IS750.h> |
||||
SC16IS750 i2cuart = SC16IS750(SC16IS750_PROTOCOL_I2C,SC16IS750_ADDRESS_AA); |
||||
|
||||
// Initialize a connection to esp-link using the I2Cuart chip of the Arduino Uno WiFi board for
|
||||
// SLIP messages.
|
||||
ELClient esp(&i2cuart); |
||||
|
||||
//###########################################################
|
||||
// For boards using the hardware serial port!
|
||||
//###########################################################
|
||||
// Initialize a connection to esp-link using the normal hardware serial port both for
|
||||
// SLIP and for debug messages.
|
||||
//ELClient esp(&Serial, &Serial);
|
||||
|
||||
// Initialize a TCP socket client on the connection to esp-link
|
||||
ELClientSocket tcp(&esp); |
||||
// Connection number for tcp
|
||||
int tcpConnNum; |
||||
|
||||
// Timer value to send out data
|
||||
uint32_t wait; |
||||
// Time to wait between sending out data
|
||||
uint32_t waitTime; |
||||
// Flag for wifi connection
|
||||
boolean wifiConnected = false; |
||||
|
||||
// Parse error codes and returns error message as char *
|
||||
// Definitions from error values from espconn.h (Espressif SDK)
|
||||
// #define ESPCONN_OK 0 /**< No error, everything OK. */
|
||||
// #define ESPCONN_MEM -1 /**< Out of memory. */
|
||||
// #define ESPCONN_TIMEOUT -3 /**< Timeout. */
|
||||
// #define ESPCONN_RTE -4 /**< Routing problem. */
|
||||
// #define ESPCONN_INPROGRESS -5 /**< Operation in progress. */
|
||||
// #define ESPCONN_MAXNUM -7 /**< Total number exceeds the maximum limitation. */
|
||||
|
||||
// #define ESPCONN_ABRT -8 /**< Connection aborted. */
|
||||
// #define ESPCONN_RST -9 /**< Connection reset. */
|
||||
// #define ESPCONN_CLSD -10 /**< Connection closed. */
|
||||
// #define ESPCONN_CONN -11 /**< Not connected. */
|
||||
|
||||
// #define ESPCONN_ARG -12 /**< Illegal argument. */
|
||||
// #define ESPCONN_IF -14 /**< UDP send error. */
|
||||
// #define ESPCONN_ISCONN -15 /**< Already connected. */
|
||||
|
||||
char* const errTxt[] PROGMEM = {"No error, everything OK.","Out of memory.","Unknown code.","Timeout.","Routing problem.","Operation in progress.", |
||||
"Unknown code.","Total number exceeds the maximum limitation.","Connection aborted.","Connection reset.","Connection closed.", |
||||
"Not connected.","Illegal argument.","Unknown code.","UDP send error.","Already connected."}; |
||||
char * getErrTxt(int16_t commError) { |
||||
commError = commError*-1; |
||||
if (commError <= 15) { |
||||
return (char *) pgm_read_word (&errTxt[commError]); |
||||
} else { |
||||
return (char *) pgm_read_word (&errTxt[2]); // Unknown code
|
||||
} |
||||
} |
||||
|
||||
// Callback for TCP socket, called if data was sent or received
|
||||
// Receives socket client number, can be reused for all initialized TCP socket connections
|
||||
void tcpCb(uint8_t resp_type, uint8_t client_num, uint16_t len, char *data) { |
||||
Serial.println("tcpCb connection #"+String(client_num)); |
||||
if (resp_type == USERCB_SENT) { |
||||
Serial.println("\tSent " + String(len) + " bytes over client#" + String(client_num)); |
||||
} else if (resp_type == USERCB_RECV) { |
||||
char recvData[len+1]; // Prepare buffer for the received data
|
||||
memcpy(recvData, data, len); // Copy received data into the buffer
|
||||
recvData[len] = '\0'; // Terminate the buffer with 0 for proper printout!
|
||||
|
||||
Serial.println("\tReceived " + String(len) + " bytes over the server on connection #" + String(client_num)); |
||||
Serial.println("\tReceived: " + String(recvData)); |
||||
// TODO add some functions to react to the received data
|
||||
char respData[len+11]; // Prepare buffer for the response data
|
||||
char *respHdr = "Received: "; |
||||
memcpy (respData, respHdr, 10); |
||||
memcpy(&respData[10], recvData, len); // Copy received data into the buffer
|
||||
respData[len+10] = '\0'; |
||||
Serial.println("\tSend response: " + String(respData)); |
||||
tcp.send(respData); |
||||
} else if (resp_type == USERCB_RECO) { |
||||
if (len != -11) { // ignore "not connected" error, handled in USERCB_CONN
|
||||
Serial.print("\tConnection problem: "); |
||||
Serial.println(getErrTxt(len)); |
||||
} |
||||
} else if (resp_type == USERCB_CONN) { |
||||
if (len == 0) { |
||||
Serial.println("\tDisconnected"); |
||||
} else { |
||||
Serial.println("\tConnected"); |
||||
} |
||||
} else { |
||||
Serial.println("Received invalid response type"); |
||||
} |
||||
} |
||||
|
||||
// Callback made from esp-link to notify of wifi status changes
|
||||
// Here we print something out and set a global flag
|
||||
void wifiCb(void *response) { |
||||
ELClientResponse *res = (ELClientResponse*)response; |
||||
if (res->argc() == 1) { |
||||
uint8_t status; |
||||
res->popArg(&status, 1); |
||||
|
||||
if(status == STATION_GOT_IP) { |
||||
Serial.println(F("WIFI CONNECTED")); |
||||
wifiConnected = true; |
||||
} else { |
||||
Serial.print(F("WIFI NOT READY: ")); |
||||
Serial.println(status); |
||||
wifiConnected = false; |
||||
} |
||||
} |
||||
} |
||||
|
||||
void setup() { |
||||
Serial.begin(115200); |
||||
//###########################################################
|
||||
// For ARDUINO UNO WIFI with I2C to serial chip!
|
||||
//###########################################################
|
||||
i2cuart.begin(9600); |
||||
|
||||
Serial.println(F("EL-Client starting!")); |
||||
|
||||
// Sync-up with esp-link, this is required at the start of any sketch and initializes the
|
||||
// callbacks to the wifi status change callback. The callback gets called with the initial
|
||||
// status right after Sync() below completes.
|
||||
esp.wifiCb.attach(wifiCb); // wifi status change callback, optional (delete if not desired)
|
||||
bool ok; |
||||
do { |
||||
ok = esp.Sync(); // sync up with esp-link, blocks for up to 2 seconds
|
||||
if (!ok) Serial.println(F("EL-Client sync failed!")); |
||||
} while(!ok); |
||||
Serial.println(F("EL-Client synced!")); |
||||
|
||||
// Wit for WiFi to be connected.
|
||||
esp.GetWifiStatus(); |
||||
ELClientPacket *packet; |
||||
Serial.print(F("Waiting for WiFi ")); |
||||
if ((packet=esp.WaitReturn()) != NULL) { |
||||
Serial.print(F(".")); |
||||
Serial.println(packet->value); |
||||
} |
||||
Serial.println(""); |
||||
|
||||
// Set up the TCP socket server to wait for a client on port <>,
|
||||
// it just sets-up stuff on the esp-link side and waits until a client sends some data
|
||||
tcpConnNum = tcp.begin(tcpServer, tcpPort, SOCKET_TCP_SERVER, tcpCb); // SOCKET_SERVER ==> accept connections
|
||||
if (tcpConnNum < 0) { |
||||
Serial.println(F("TCP socket setup failed, try again in 10 seconds after reboot")); |
||||
delay(10000); |
||||
asm volatile (" jmp 0"); |
||||
} else { |
||||
Serial.println(String(tcpServer)+":"+String(tcpPort)+" is served over connection number # = "+String(tcpConnNum)); |
||||
} |
||||
Serial.println(F("EL-TCP ready")); |
||||
} |
||||
|
||||
void loop() { |
||||
// process any callbacks coming from esp_link
|
||||
esp.Process(); |
||||
} |
||||
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
ESP_HOSTNAME ?= esp-link
|
||||
LIBRARYPATH = $(ARDUINODIR)/libraries ../../..
|
||||
LIBRARIES = ELClient
|
||||
CPPFLAGS =
|
||||
SERIALDEV = net:$(ESP_HOSTNAME):2323
|
||||
include ../arduino.mk |
||||
|
||||
flash: all |
||||
../avrflash $(ESP_HOSTNAME) test.hex
|
||||
nc $(ESP_HOSTNAME) 23
|
||||
|
||||
run: upload size |
||||
nc $(ESP_HOSTNAME) 23
|
||||
@ -0,0 +1,9 @@
@@ -0,0 +1,9 @@
|
||||
MQTT example |
||||
============ |
||||
|
||||
This is a simple example of a sketch that subscribes to an mqtt topic and then publishes messages |
||||
to that topic, which it subsequently receives and prints. |
||||
|
||||
**Important** For this sketch to work you must turn off the UART debug log in esp-link (on |
||||
the Debug Log page). The reason is that otherwise esp-link prints too much to its uart andthen |
||||
misses incoming characters. |
||||
@ -0,0 +1,308 @@
@@ -0,0 +1,308 @@
|
||||
:100000000C9436000C945E000C945E000C945E0020 |
||||
:100010000C945E000C945E000C945E000C945E00E8 |
||||
:100020000C945E000C945E000C945E000C945E00D8 |
||||
:100030000C945E000C945E000C945E000C945E00C8 |
||||
:100040000C9412010C945E000C94A3010C94D50145 |
||||
:100050000C945E000C945E000C945E000C945E00A8 |
||||
:100060000C945E000C945E000501050211241FBE75 |
||||
:10007000CFEFD8E0DEBFCDBF11E0A0E0B1E0ECE310 |
||||
:10008000F2E102C005900D92A83EB107D9F723E036 |
||||
:10009000A8EEB1E001C01D92AA32B207E1F710E06C |
||||
:1000A000CCE6D0E004C02297FE010E941809C836B1 |
||||
:1000B000D107C9F70E948E030C941C090C94000010 |
||||
:1000C00066E071E08DE892E00E94E10340ED57E0C8 |
||||
:1000D00060E070E08EEE91E00E94F207811103C0B3 |
||||
:1000E0006FE171E0EFCF66E371E08DE892E00C9490 |
||||
:1000F000E103CF93DF931F92CDB7DEB7DC011496F7 |
||||
:10010000ED91FC9115972281338121303105F1F475 |
||||
:1001100041E050E0BE016F5F7F4F0E947608898109 |
||||
:10012000853039F468E471E08DE892E00E94E103E3 |
||||
:100130000DC067E571E08DE892E00E94DB034AE0C4 |
||||
:1001400050E069818DE892E00E9460040F90DF9199 |
||||
:10015000CF91089526E040E052EC61E070E08DE838 |
||||
:1001600092E00E942B0369E770E080EF91E00E942B |
||||
:10017000BB0880E690E09093F7018093F6010C9421 |
||||
:100180006000CF92DF92EF92FF928EEE91E00E949C |
||||
:10019000ED060E945C01C090E801D090E901E0907A |
||||
:1001A000EA01F090EB016C197D098E099F09613A13 |
||||
:1001B0007F408105910520F168E671E08DE892E0CD |
||||
:1001C0000E94E1038CEE91E00E94A9046B017C0186 |
||||
:1001D00068E771E08DE892E00E94DB032AE030E0FE |
||||
:1001E000B701A6018DE892E00E9493040E945C0191 |
||||
:1001F0006093E8017093E9018093EA019093EB0129 |
||||
:10020000FF90EF90DF90CF9008954DE852E0BA0153 |
||||
:100210008EEE91E00E943B056EEE71E08CEE91E077 |
||||
:100220000C94A5041F920F920FB60F9211242F93D6 |
||||
:100230003F938F939F93AF93BF938091850290914B |
||||
:100240008602A0918702B09188023091840223E057 |
||||
:10025000230F2D3720F40196A11DB11D05C026E8FE |
||||
:10026000230F0296A11DB11D209384028093850265 |
||||
:1002700090938602A0938702B093880280918902AE |
||||
:1002800090918A02A0918B02B0918C020196A11DDF |
||||
:10029000B11D8093890290938A02A0938B02B09340 |
||||
:1002A0008C02BF91AF919F918F913F912F910F90B1 |
||||
:1002B0000FBE0F901F9018952FB7F894609185028C |
||||
:1002C0007091860280918702909188022FBF0895D5 |
||||
:1002D000789484B5826084BD84B5816084BD85B521 |
||||
:1002E000826085BD85B5816085BDEEE6F0E08081E8 |
||||
:1002F00081608083E1E8F0E0108280818260808309 |
||||
:10030000808181608083E0E8F0E08081816080838B |
||||
:10031000E1EBF0E0808184608083E0EBF0E08081BD |
||||
:1003200081608083EAE7F0E080818460808380815F |
||||
:100330008260808380818160808380818068808307 |
||||
:100340001092C10008951F920F920FB60F921124C0 |
||||
:100350002F938F939F93EF93FF93E0919D02F091E2 |
||||
:100360009E028081E091A302F091A40282FD12C05E |
||||
:1003700090818091A6028F5F8F732091A7028217D0 |
||||
:1003800051F0E091A602F0E0E357FD4F958F809386 |
||||
:10039000A60201C08081FF91EF919F918F912F91D3 |
||||
:1003A0000F900FBE0F901F9018951F920F920FB6CF |
||||
:1003B0000F9211242F933F934F935F936F937F93EB |
||||
:1003C0008F939F93AF93BF93EF93FF938DE892E04A |
||||
:1003D0000E948302FF91EF91BF91AF919F918F9106 |
||||
:1003E0007F916F915F914F913F912F910F900FBE31 |
||||
:1003F0000F901F9018958DE892E00E94480221E02E |
||||
:10040000892B09F420E0822F089510929002109217 |
||||
:100410008F0288EE93E0A0E0B0E080939102909389 |
||||
:100420009202A0939302B093940283E891E0909398 |
||||
:100430008E0280938D0285EC90E090939A028093D7 |
||||
:10044000990284EC90E090939C0280939B0280EC54 |
||||
:1004500090E090939E0280939D0281EC90E09093B7 |
||||
:10046000A00280939F0282EC90E09093A20280937E |
||||
:10047000A10286EC90E09093A4028093A3021092D4 |
||||
:10048000A6021092A7021092A8021092A902089543 |
||||
:10049000FC01818D228D90E0805C9F4F821B910931 |
||||
:1004A0008F7399270895FC01918D828D981731F0F3 |
||||
:1004B000828DE80FF11D858D90E008958FEF9FEFFD |
||||
:1004C0000895FC01918D828D981761F0828DDF0176 |
||||
:1004D000A80FB11D5D968C91928D9F5F9F73928F37 |
||||
:1004E00090E008958FEF9FEF08958BEF91E0892BB7 |
||||
:1004F00049F080E090E0892B29F00E94FB018111F6 |
||||
:100500000C9400000895FC01848DDF01A80FB11D3B |
||||
:10051000A35ABF4F2C91848D90E001968F73992739 |
||||
:10052000848FA689B7892C93A089B1898C91806426 |
||||
:100530008C93938D848D981306C00288F389E02DE7 |
||||
:1005400080818F7D80830895CF93DF93EC01888D28 |
||||
:100550008823C9F0EA89FB89808185FD05C0A889C7 |
||||
:10056000B9898C9186FD0FC00FB607FCF5CF80814D |
||||
:1005700085FFF2CFA889B9898C9185FFEDCFCE0197 |
||||
:100580000E948302E7CFDF91CF910895CF92DF924F |
||||
:10059000FF920F931F93CF93DF931F92CDB7DEB7D8 |
||||
:1005A0006C0181E0D60158968C9358975B969C918C |
||||
:1005B0005B975C968C915C97981307C05096ED9171 |
||||
:1005C000FC915197808185FD2EC0F601038D10E0CE |
||||
:1005D0000F5F1F4F0F731127F02EF601848DF81255 |
||||
:1005E00011C00FB607FCF9CFD6015096ED91FC91E2 |
||||
:1005F0005197808185FFF1CFC60169830E948302F4 |
||||
:100600006981EBCF838DE80FF11DE35AFF4F6083C3 |
||||
:10061000D6015B960C935B975296ED91FC915397A4 |
||||
:10062000808180620CC0D6015696ED91FC9157975F |
||||
:1006300060835096ED91FC91519780818064808316 |
||||
:1006400081E090E00F90DF91CF911F910F91FF908B |
||||
:10065000DF90CF900895BF92CF92DF92EF92FF92FA |
||||
:10066000CF93DF93EC016A017B01B22EE889F9890F |
||||
:1006700082E08083411581EE580761057105A1F084 |
||||
:1006800060E079E08DE390E0A70196010E94F40814 |
||||
:1006900021503109410951095695479537952795BC |
||||
:1006A000211580E1380798F0E889F989108260E81F |
||||
:1006B00074E88EE190E0A70196010E94F4082150B1 |
||||
:1006C0003109410951095695479537952795EC858C |
||||
:1006D000FD853083EE85FF852083188EEC89FD89AA |
||||
:1006E000B082EA89FB89808180618083EA89FB8905 |
||||
:1006F000808188608083EA89FB898081806880832B |
||||
:10070000EA89FB8980818F7D8083DF91CF91FF9083 |
||||
:10071000EF90DF90CF90BF90089508950E946801F8 |
||||
:100720000E948D030E94AA00C5E7D2E00E94C1008A |
||||
:100730002097E1F30E947502F9CFCF92DF92EF92FA |
||||
:10074000FF920F931F93CF93DF936C017A01EB011C |
||||
:10075000E60EF71E00E010E0CE15DF0561F06991AE |
||||
:10076000D601ED91FC910190F081E02DC601099533 |
||||
:10077000080F191FF1CFC801DF91CF911F910F9181 |
||||
:10078000FF90EF90DF90CF9008956115710581F093 |
||||
:10079000DB010D900020E9F7AD0141505109461BE6 |
||||
:1007A000570BDC01ED91FC910280F381E02D09945F |
||||
:1007B00080E090E008950C94C5036FE871E00C941C |
||||
:1007C000C5030F931F93CF93DF93EC010E94C503E2 |
||||
:1007D0008C01CE010E94DD03800F911FDF91CF912C |
||||
:1007E0001F910F9108958F929F92AF92BF92CF92D7 |
||||
:1007F000DF92EF92FF920F931F93CF93DF93CDB7CA |
||||
:10080000DEB7A1970FB6F894DEBF0FBECDBF7C0157 |
||||
:10081000C42EE52FCB01D22E19A221E02D1510F008 |
||||
:100820002AE0D22E8E010F5D1F4F8D2C912CA12C12 |
||||
:10083000B12C6C2D7E2FA50194010E94F4088C2D03 |
||||
:10084000D29E80191124015011098A3010F4805D64 |
||||
:1008500001C0895CF80180832115310541055105EE |
||||
:1008600021F0C22EE32FCA01E4CFB801C7010E94D4 |
||||
:10087000C503A1960FB6F894DEBF0FBECDBFDF91C2 |
||||
:10088000CF911F910F91FF90EF90DF90CF90BF908D |
||||
:10089000AF909F908F9008952115310541F4DC01B0 |
||||
:1008A000ED91FC910190F081E02D642F09940C945E |
||||
:1008B000F3039A01462F50E060E070E00C944C0482 |
||||
:1008C0000F931F93CF93DF93EC019A01462F50E0D3 |
||||
:1008D00060E070E00E944C048C01CE010E94DD03B8 |
||||
:1008E000800F911FDF91CF911F910F9108959A0171 |
||||
:1008F000AB0160E070E00C944C040F931F93CF9316 |
||||
:10090000DF93EC019A01AB0160E070E00E944C04BF |
||||
:100910008C01CE010E94DD03800F911FDF91CF91EA |
||||
:100920001F910F9108950F931F93CF93DF93EC01C5 |
||||
:100930000E944C048C01CE010E94DD03800F911FA8 |
||||
:10094000DF91CF911F910F910895FC017183608316 |
||||
:1009500008950F931F93CF93DF93EC0100E010E015 |
||||
:1009600020E030E0A90167E070E0888199810E9471 |
||||
:100970007507888199810E94250540ED57E060E068 |
||||
:1009800070E0888199810E944607009731F0FC0150 |
||||
:10099000648175818681978103C060E070E0CB013E |
||||
:1009A000DF91CF911F910F910895CF93DF93EC01C9 |
||||
:1009B0008A859B85603CA1F06B3D21F5DC01ED91C2 |
||||
:1009C000FC910190F081E02D6BED09958A859B8566 |
||||
:1009D000DC01ED91FC910190F081E02D6DED18C0EE |
||||
:1009E000DC01ED91FC910190F081E02D6BED09951A |
||||
:1009F0008A859B85DC01ED91FC910190F081E02DD1 |
||||
:100A00006CED06C0DC01ED91FC910190F081E02DD0 |
||||
:100A1000DF91CF910994EF92FF920F931F93CF93A1 |
||||
:100A2000DF937C018A01EB01060F171FC017D10766 |
||||
:100A300029F06991C7010E94D504F8CFDF91CF91C9 |
||||
:100A40001F910F91FF90EF900895CF93DF93EC01EA |
||||
:100A5000BC01635F7F4F42E050E00E940B058A8536 |
||||
:100A60009B85DC01ED91FC910190F081E02D60EC23 |
||||
:100A7000DF91CF9109940F931F93CF93DF93EC01F4 |
||||
:100A80008B01FC0141935193CF010E94B5081B8754 |
||||
:100A90000A8781E08C87CE014696988B8F8780E805 |
||||
:100AA00090E09A8B898B1C8A1B8A1D8ADF91CF91DB |
||||
:100AB0001F910F910895FC012485222321F080814C |
||||
:100AC00091810C94E1030895462754274527542724 |
||||
:100AD0009A01222784E0220F331F8A95E1F7242709 |
||||
:100AE0003527C901892F992782958F7082279327EF |
||||
:100AF0009C01222755E0369527955A95E1F78227E4 |
||||
:100B000093270895EF92FF920F931F93CF93DF9354 |
||||
:100B10007C018A01C901EB01060F171FC017D1071D |
||||
:100B200031F06991AC01C7010E946405F7CFDF91F4 |
||||
:100B3000CF911F910F91FF90EF900895AF92BF92C8 |
||||
:100B4000CF92DF92EF92FF920F931F93CF93DF9399 |
||||
:100B500000D000D000D0CDB7DEB78C01DC011F96ED |
||||
:100B6000ED90FC9050971C968C911C97882309F46B |
||||
:100B70007DC060EA71E08D919C910E94DB03F801D9 |
||||
:100B8000638974894AE050E0808191810E947704F2 |
||||
:100B90006AEA71E0D8018D919C910E94DB03F80113 |
||||
:100BA00047855089662757FD6095762F20E130E014 |
||||
:100BB000808191810E944C046EEC71E0D8018D918E |
||||
:100BC0009C910E94DB03F7016081718140E150E05C |
||||
:100BD000D8018D919C910E9477046FEC71E0F8012F |
||||
:100BE000808191810E94DB03D70114964D915D9124 |
||||
:100BF0006D917C91179720E130E0F801808191811F |
||||
:100C00000E944C046FEC71E0D8018D919C910E9480 |
||||
:100C1000DB03F7016281738140E150E0D8018D91DF |
||||
:100C20009C910E94770468E0C62ED12CF80123899C |
||||
:100C3000348980819181C216D306B0F46FEC71E0E3 |
||||
:100C40000E94DB03D8011F96ED91FC915097EC0DAB |
||||
:100C5000FD1D40E150E060818D919C910E945904FE |
||||
:100C6000BFEFCB1ADB0AE2CF0E94DD03D801539617 |
||||
:100C7000CD90DC905497B2E0CB1AD108F801A7844C |
||||
:100C8000B08820E030E0A601B501C8010E948205CD |
||||
:100C9000F501EC0DFD1D208131818217930731F0A4 |
||||
:100CA0006DEA71E0C8010E945B0582C0D7018D9199 |
||||
:100CB0009C918230910539F083309105F1F00197D4 |
||||
:100CC00009F06CC05BC0F8018485882309F473C007 |
||||
:100CD0006EEB71E0808191810E94DB03D701149655 |
||||
:100CE0004D915D916D917C9117972AE030E0F8016C |
||||
:100CF000808191810E9493045EC0D8011C968C91E2 |
||||
:100D00001C97882329F167EC71E08D919C910E94DA |
||||
:100D1000DB03F70144815581668177812AE030E069 |
||||
:100D2000D8018D919C910E944C046FEC71E0F80108 |
||||
:100D3000808191810E94DB03D70112966D917C9195 |
||||
:100D400013974AE050E0F801808191810E947D0470 |
||||
:100D5000D70114960D911C911597C8010E94E608C1 |
||||
:100D6000882331F1B701CE0101960E946C08BE01C3 |
||||
:100D70006F5F7F4FC8010E94BF081AC061ED71E02C |
||||
:100D8000F801808191810E94E103D8011896ED91CC |
||||
:100D9000FC911997309761F009950AC0F801848594 |
||||
:100DA000882331F06CED71E0808191810E94E10334 |
||||
:100DB00080E090E001C0C70126960FB6F894DEBF30 |
||||
:100DC0000FBECDBFDF91CF911F910F91FF90EF909C |
||||
:100DD000DF90CF90BF90AF9008951F93CF93DF9394 |
||||
:100DE000EC0111E08A859B85DC01ED91FC9104808A |
||||
:100DF000F581E02D0995892B09F442C08A859B85F0 |
||||
:100E0000DC01ED91FC910680F781E02D09958B3D89 |
||||
:100E1000910511F41D8BE6CF2B893C89803C91050F |
||||
:100E200079F42830310520F0CE010E949E0502C0E1 |
||||
:100E300080E090E01C8A1B8A1D8A009799F222C0EC |
||||
:100E40004D89442361F08C3D910531F08D3D910534 |
||||
:100E500029F48BED90E002C080EC90E01D8A498976 |
||||
:100E60005A892417350708F0BDCFEF85F889A90105 |
||||
:100E70004F5F5F4F5C8B4B8BE20FF31F8083B2CFD2 |
||||
:100E800080E090E0DF91CF911F9108958F929F9223 |
||||
:100E9000AF92BF92CF92DF92EF92FF92CF93DF9308 |
||||
:100EA000EC016A017B010E945C014B015C010E9424 |
||||
:100EB0005C01681979098A099B096C157D058E0505 |
||||
:100EC0009F0530F4CE010E94ED06009781F302C029 |
||||
:100ED00080E090E0DF91CF91FF90EF90DF90CF9096 |
||||
:100EE000BF90AF909F908F900895EF92FF920F93D5 |
||||
:100EF0001F93CF93DF93CDB7DEB728970FB6F89443 |
||||
:100F0000DEBF0FBECDBF7C017A8369832B833C8318 |
||||
:100F10004D835E8318870F83DC011E961C921E9200 |
||||
:100F20001D971A968D919C911B97DC01ED91FC9178 |
||||
:100F30000190F081E02D60EC099542E050E0BE01A7 |
||||
:100F40006F5F7F4FC7010E940B05F701258536852E |
||||
:100F500042E050E0BE016F5F7F4FC7010E948205F3 |
||||
:100F6000D7011E969C938E931D9742E050E0BE01E0 |
||||
:100F7000695F7F4FC7010E940B05F7012585368504 |
||||
:100F800042E050E0BE01695F7F4FC7010E948205C9 |
||||
:100F9000D7011E969C938E931D9744E050E0BE01AE |
||||
:100FA0006D5F7F4FC7010E940B05F70125853685D0 |
||||
:100FB00044E050E0BE016D5F7F4FC7010E94820593 |
||||
:100FC000D7011E969C938E931D9728960FB6F89482 |
||||
:100FD000DEBF0FBECDBFDF91CF911F910F91FF906C |
||||
:100FE000EF9008956F927F928F929F92AF92BF92EF |
||||
:100FF000CF92DF92EF92FF920F931F93CF93DF93E5 |
||||
:10100000EC014A015B018A859B85DC01ED91FC9135 |
||||
:101010000190F081E02D60EC09956E01B2E0CB0EFD |
||||
:10102000D11CEE24D7FCE094FE2C00E010E0A701D8 |
||||
:10103000960161E070E0CE010E947507CE010E942A |
||||
:1010400025050885198519861886B501A401CE01E4 |
||||
:101050000E9446073C01009769F1F3018481958164 |
||||
:10106000A681B7812C858C159D05AE05BF0561F461 |
||||
:10107000222331F066ED71E0888199810E94E103BD |
||||
:101080001987088781E019C02223F9F262EE71E026 |
||||
:10109000888199810E94DB03D30114964D915D9163 |
||||
:1010A0006D917C9117972AE030E0888199810E94A8 |
||||
:1010B0009304CBCF1987088780E0DF91CF911F91F0 |
||||
:1010C0000F91FF90EF90DF90CF90BF90AF909F90E7 |
||||
:1010D0008F907F906F900895FC0175836483685FA3 |
||||
:1010E0007F4F738362831182108208950F931F9341 |
||||
:1010F000CF93DF93FC01A081B181C481D5818A8126 |
||||
:101100009B81A817B90750F5C281D38129913991E4 |
||||
:101110008EEF9FEF821B930B83709927D383C2833B |
||||
:101120001196B183A0838E01EB01DA0124173507F4 |
||||
:1011300008F4D9016A0F7B1FC617D70729F0D80119 |
||||
:101140004D918D014993F8CF820F931F42815381B6 |
||||
:10115000480F591F53834283C90102C08FEF9FEF8D |
||||
:10116000DF91CF911F910F910895FC0111821082A0 |
||||
:10117000138212820895FC01738362830895DC0157 |
||||
:101180001296ED91FC9113973097F9F02D913C91C7 |
||||
:10119000119721153105B9F014968D919C911597F1 |
||||
:1011A000AC015595479580FF0AC0D901A40FB51F22 |
||||
:1011B0000D90BC91A02DAE0FBF1FED91FC91C90108 |
||||
:1011C000840F951F0994CB0109940895FC01808137 |
||||
:1011D0009181892B39F481E022813381232B19F409 |
||||
:1011E00080E0089581E00895A1E21A2EAA1BBB1B9E |
||||
:1011F000FD010DC0AA1FBB1FEE1FFF1FA217B307E3 |
||||
:10120000E407F50720F0A21BB30BE40BF50B661FF8 |
||||
:10121000771F881F991F1A9469F7609570958095BC |
||||
:1012200090959B01AC01BD01CF010895EE0FFF1F0A |
||||
:0C1230000590F491E02D0994F894FFCF94 |
||||
:10123C0000002A038000454C2D436C69656E7420B8 |
||||
:10124C002872652D297374617274696E672100456B |
||||
:10125C004C2D436C69656E742073796E63206661E6 |
||||
:10126C00696C65642100454C2D436C69656E742076 |
||||
:10127C0073796E63656421005749464920434F4E8C |
||||
:10128C004E45435445440057494649204E4F54203F |
||||
:10129C0052454144593A2000726571756573746901 |
||||
:1012AC006E672074696D650054696D653A200000A5 |
||||
:1012BC00000000C6029D03480261025302A4020D05 |
||||
:1012CC000A006E616E00696E66006F7666002E0015 |
||||
:1012DC00454C433A20676F742000204000454C4336 |
||||
:1012EC003A20496E76616C69642043524300524542 |
||||
:1012FC0053505F563A2000524553505F43423A20B8 |
||||
:10130C00004E4545445F53594E432100434D443FE5 |
||||
:08131C003F004241443A200069 |
||||
:00000001FF |
||||
@ -0,0 +1,68 @@
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* Simple example to test resetting either arduino or esp-link while doing MQTT |
||||
*/ |
||||
|
||||
#include <ELClient.h> |
||||
#include <ELClientCmd.h> |
||||
|
||||
// Initialize a connection to esp-link using the normal hardware serial port both for
|
||||
// SLIP and for debug messages. Esp-link will show the debug messages in the uC console
|
||||
// because they are not SLIP framed.
|
||||
ELClient esp(&Serial, &Serial); |
||||
|
||||
// Initialize CMD client (for GetTime)
|
||||
ELClientCmd cmd(&esp); |
||||
|
||||
// Callback made from esp-link to notify of wifi status changes
|
||||
// Here we just print something out for grins
|
||||
void wifiCb(void* response) { |
||||
ELClientResponse *res = (ELClientResponse*)response; |
||||
if (res->argc() == 1) { |
||||
uint8_t status; |
||||
res->popArg(&status, 1); |
||||
|
||||
if(status == STATION_GOT_IP) { |
||||
Serial.println("WIFI CONNECTED"); |
||||
} else { |
||||
Serial.print("WIFI NOT READY: "); |
||||
Serial.println(status); |
||||
} |
||||
} |
||||
} |
||||
|
||||
// Callback made form esp-link to notify that it has just come out of a reset. This means we
|
||||
// need to initialize it!
|
||||
void resetCb(void) { |
||||
Serial.println("EL-Client (re-)starting!"); |
||||
bool ok = false; |
||||
do { |
||||
ok = esp.Sync(); // sync up with esp-link, blocks for up to 2 seconds
|
||||
if (!ok) Serial.println("EL-Client sync failed!"); |
||||
} while(!ok); |
||||
Serial.println("EL-Client synced!"); |
||||
} |
||||
|
||||
void setup() { |
||||
Serial.begin(115200); |
||||
|
||||
// Sync-up with esp-link, this is required at the start of any sketch and initializes the
|
||||
// callbacks to the wifi status change callback. The callback gets called with the initial
|
||||
// status right after Sync() below completes.
|
||||
esp.wifiCb.attach(wifiCb); // wifi status change callback, optional (delete if not desired)
|
||||
esp.resetCb = resetCb; |
||||
resetCb(); |
||||
} |
||||
|
||||
static uint32_t last; |
||||
|
||||
void loop() { |
||||
esp.Process(); |
||||
|
||||
if ((millis()-last) > 4000) { |
||||
Serial.println("requesting time"); |
||||
uint32_t t = cmd.GetTime(); |
||||
Serial.print("Time: "); Serial.println(t); |
||||
|
||||
last = millis(); |
||||
} |
||||
} |
||||
@ -0,0 +1,4 @@
@@ -0,0 +1,4 @@
|
||||
Thingspeak example |
||||
================== |
||||
|
||||
**WARNING: this example has not been updated for EL-Client!** |
||||
@ -0,0 +1,156 @@
@@ -0,0 +1,156 @@
|
||||
/**
|
||||
* \file |
||||
* ESP8266 RESTful Thingspeak example |
||||
* \author |
||||
* BeeGee |
||||
*/ |
||||
|
||||
#include <ELClient.h> |
||||
#include <ELClientRest.h> |
||||
|
||||
//###########################################################
|
||||
// For ARDUINO UNO WIFI with I2C to serial chip!
|
||||
//###########################################################
|
||||
// Serial port to ESP8266
|
||||
// #include <SC16IS750.h>
|
||||
// SC16IS750 i2cuart = SC16IS750(SC16IS750_PROTOCOL_I2C,SC16IS750_ADDRESS_AA);
|
||||
|
||||
// Initialize a connection to esp-link using the I2Cuart chip of the Arduino Uno WiFi board for
|
||||
// SLIP messages.
|
||||
// ELClient esp(&i2cuart);
|
||||
|
||||
//###########################################################
|
||||
// For boards using the hardware serial port!
|
||||
//###########################################################
|
||||
// Initialize a connection to esp-link using the normal hardware serial port both for
|
||||
// SLIP and for debug messages.
|
||||
ELClient esp(&Serial, &Serial); |
||||
|
||||
// Initialize a REST client on the connection to esp-link
|
||||
ELClientRest rest(&esp); |
||||
|
||||
boolean wifiConnected = false; |
||||
|
||||
// Callback made from esp-link to notify of wifi status changes
|
||||
// Here we print something out and set a global flag
|
||||
void wifiCb(void *response) { |
||||
ELClientResponse *res = (ELClientResponse*)response; |
||||
if (res->argc() == 1) { |
||||
uint8_t status; |
||||
res->popArg(&status, 1); |
||||
|
||||
if(status == STATION_GOT_IP) { |
||||
Serial.println("WIFI CONNECTED"); |
||||
wifiConnected = true; |
||||
} else { |
||||
Serial.print("WIFI NOT READY: "); |
||||
Serial.println(status); |
||||
wifiConnected = false; |
||||
} |
||||
} |
||||
} |
||||
|
||||
void setup() { |
||||
Serial.begin(9600); |
||||
//###########################################################
|
||||
// For ARDUINO UNO WIFI with I2C to serial chip!
|
||||
//###########################################################
|
||||
// i2cuart.begin(9600);
|
||||
|
||||
Serial.println(""); |
||||
Serial.println("EL-Client starting!"); |
||||
|
||||
// Sync-up with esp-link, this is required at the start of any sketch and initializes the
|
||||
// callbacks to the wifi status change callback. The callback gets called with the initial
|
||||
// status right after Sync() below completes.
|
||||
esp.wifiCb.attach(wifiCb); // wifi status change callback, optional (delete if not desired)
|
||||
bool ok; |
||||
do { |
||||
ok = esp.Sync(); // sync up with esp-link, blocks for up to 2 seconds
|
||||
if (!ok) { |
||||
Serial.print("\nEL-Client sync failed! err: "); |
||||
Serial.println(ok); |
||||
} |
||||
} while(!ok); |
||||
Serial.println("EL-Client synced!"); |
||||
|
||||
// Wait for WiFi to be connected.
|
||||
Serial.println("esp.GetWifiStatus()"); |
||||
esp.GetWifiStatus(); |
||||
ELClientPacket *packet; |
||||
Serial.println("Waiting for WiFi "); |
||||
if ((packet=esp.WaitReturn()) != NULL) { |
||||
Serial.print("."); |
||||
Serial.println(packet->value); |
||||
} |
||||
Serial.println(""); |
||||
|
||||
// Set up the REST client to talk to api.thingspeak.com, this doesn't connect to that server,
|
||||
// it just sets-up stuff on the esp-link side
|
||||
// int err = rest.begin("api.thingspeak.com");
|
||||
int err = rest.begin("184.106.153.149"); |
||||
if (err != 0) { |
||||
Serial.print("REST begin failed: "); |
||||
Serial.println(err); |
||||
while(1) ; |
||||
} |
||||
Serial.println("EL-REST ready"); |
||||
} |
||||
|
||||
float solarValue = 99.5; |
||||
// Change to your own Thingspeak API key
|
||||
char *api_key = "K9LDRXS7BXSN8X1J"; |
||||
// expand buffer size to your needs
|
||||
#define BUFLEN 266 |
||||
|
||||
void loop() { |
||||
// process any callbacks coming from esp_link
|
||||
esp.Process(); |
||||
|
||||
// if we're connected make an REST request
|
||||
if(wifiConnected) { |
||||
|
||||
// Generate a fake value starting from 100 going up to 300
|
||||
solarValue = solarValue + 0.5; |
||||
if (solarValue == 300) { |
||||
solarValue = 100; |
||||
} |
||||
String solarValString = String(solarValue); |
||||
const char *solarValChar = solarValString.c_str(); |
||||
|
||||
// Reserve a buffer for sending the data
|
||||
char path_data[BUFLEN]; |
||||
// Copy the path and API key into the buffer
|
||||
sprintf(path_data, "%s", "/update?api_key="); |
||||
sprintf(path_data + strlen(path_data), "%s", api_key); |
||||
|
||||
// Copy the field number and value into the buffer
|
||||
// If you have more than one field to update,
|
||||
// repeat and change field1 to field2, field3, ...
|
||||
sprintf(path_data + strlen(path_data), "%s", "&field1="); |
||||
sprintf(path_data + strlen(path_data), "%s", solarValChar); |
||||
|
||||
// Send PUT request to thingspeak.com
|
||||
rest.post(path_data,"");
|
||||
|
||||
// Reserve a buffer for the response from Thingspeak
|
||||
char response[BUFLEN]; |
||||
// Clear the buffer
|
||||
memset(response, 0, BUFLEN); |
||||
// Wait for response from Thingspeak
|
||||
uint16_t code = rest.waitResponse(response, BUFLEN-1); |
||||
// Check the response from Thingspeak
|
||||
if(code == HTTP_STATUS_OK){ |
||||
Serial.println("Thingspeak: POST successful:"); |
||||
Serial.print("Response: "); |
||||
Serial.println(response); |
||||
} else { |
||||
Serial.print("Thingspeak: POST failed with error "); |
||||
Serial.println(code); |
||||
Serial.print("Response: "); |
||||
Serial.println(response); |
||||
} |
||||
// Send next data in 20 seconds
|
||||
delay(20000); |
||||
} |
||||
} |
||||
@ -0,0 +1,193 @@
@@ -0,0 +1,193 @@
|
||||
/**
|
||||
* Simple example to demo the El-Client UDP calls |
||||
*/ |
||||
|
||||
#include <ELClient.h> |
||||
#include <ELClientSocket.h> |
||||
|
||||
// IP address for this demo is a local IP.
|
||||
// Replace it with the IP address where you have a UDP socket server running
|
||||
char * const udpServer PROGMEM = "192.168.0.102"; // Send to single ip address
|
||||
char * const udpServer2 PROGMEM = "192.168.0.255"; // Broadcast to given network ip mask
|
||||
// Port for this demo is the port used by the UDP socket server.
|
||||
// Replace it with the port that your UDP socket server is listening to
|
||||
uint16_t const udpPort PROGMEM = 5000; |
||||
uint16_t const udpPort2 PROGMEM = 7000; |
||||
|
||||
//###########################################################
|
||||
// For ARDUINO UNO WIFI with I2C to serial chip!
|
||||
//###########################################################
|
||||
// Serial port to ESP8266
|
||||
#include <SC16IS750.h> |
||||
SC16IS750 i2cuart = SC16IS750(SC16IS750_PROTOCOL_I2C,SC16IS750_ADDRESS_AA); |
||||
|
||||
// Initialize a connection to esp-link using the I2Cuart chip of the Arduino Uno WiFi board for
|
||||
// SLIP messages.
|
||||
ELClient esp(&i2cuart); |
||||
|
||||
//###########################################################
|
||||
// For boards using the hardware serial port!
|
||||
//###########################################################
|
||||
// Initialize a connection to esp-link using the normal hardware serial port both for
|
||||
// SLIP and for debug messages.
|
||||
//ELClient esp(&Serial, &Serial);
|
||||
|
||||
// Initialize a UDP client on the connection to esp-link
|
||||
ELClientSocket udp(&esp); |
||||
// Initialize a UDP client on the connection to esp-link
|
||||
ELClientSocket udp2(&esp); |
||||
|
||||
// Timer value to send out data
|
||||
uint32_t wait; |
||||
// Time to wait between sending out data
|
||||
uint32_t waitTime; |
||||
// Flag for wifi connection
|
||||
boolean wifiConnected = false; |
||||
|
||||
// Parse error codes and returns error message as char *
|
||||
// Definitions from error values from espconn.h (Espressif SDK)
|
||||
// #define ESPCONN_OK 0 /**< No error, everything OK. */
|
||||
// #define ESPCONN_MEM -1 /**< Out of memory. */
|
||||
// #define ESPCONN_TIMEOUT -3 /**< Timeout. */
|
||||
// #define ESPCONN_RTE -4 /**< Routing problem. */
|
||||
// #define ESPCONN_INPROGRESS -5 /**< Operation in progress. */
|
||||
// #define ESPCONN_MAXNUM -7 /**< Total number exceeds the maximum limitation. */
|
||||
|
||||
// #define ESPCONN_ABRT -8 /**< Connection aborted. */
|
||||
// #define ESPCONN_RST -9 /**< Connection reset. */
|
||||
// #define ESPCONN_CLSD -10 /**< Connection closed. */
|
||||
// #define ESPCONN_CONN -11 /**< Not connected. */
|
||||
|
||||
// #define ESPCONN_ARG -12 /**< Illegal argument. */
|
||||
// #define ESPCONN_IF -14 /**< UDP send error. */
|
||||
// #define ESPCONN_ISCONN -15 /**< Already connected. */
|
||||
|
||||
char* const errTxt[] PROGMEM = {"No error, everything OK.","Out of memory.","Unknown code.","Timeout.","Routing problem.","Operation in progress.", |
||||
"Unknown code.","Total number exceeds the maximum limitation.","Connection aborted.","Connection reset.","Connection closed.", |
||||
"Not connected.","Illegal argument.","Unknown code.","UDP send error.","Already connected."}; |
||||
char * getErrTxt(int16_t commError) { |
||||
commError = commError*-1; |
||||
if (commError <= 15) { |
||||
return (char *) pgm_read_word (&errTxt[commError]); |
||||
} else { |
||||
return (char *) pgm_read_word (&errTxt[2]); // Unknown code
|
||||
} |
||||
} |
||||
|
||||
// Callback for UDP socket, called if data was sent or received
|
||||
// Receives socket client number, can be reused for all initialized UDP socket connections
|
||||
// !!! UDP doesn't check if the data was received or if the receiver IP/socket is available !!! You need to implement your own
|
||||
// error control!
|
||||
void udpCb(uint8_t resp_type, uint8_t client_num, uint16_t len, char *data) { |
||||
Serial.println("udpCb is called"); |
||||
if (len > 0) { // sending complete (no confirmation that it was received!) or we received something
|
||||
if (resp_type == USERCB_SENT) { |
||||
Serial.println("\tSent " + String(len) + " bytes over connection #" + String(client_num)); |
||||
} else if (resp_type == USERCB_RECV) { |
||||
char recvData[len+1]; // Prepare buffer for the received data
|
||||
memcpy(recvData, data, len); // Copy received data into the buffer
|
||||
recvData[len] = '\0'; // Terminate the buffer with 0 for proper printout!
|
||||
|
||||
Serial.println("\tReceived " + String(len) + " bytes over client#" + String(client_num)); |
||||
Serial.println("\tReceived: " + String(recvData)); |
||||
} else { |
||||
Serial.println("Received invalid response type"); |
||||
} |
||||
} else if (len < 0) { // negative result means there was a problem
|
||||
Serial.print(F("Send error: ")); |
||||
Serial.println(getErrTxt(len)); |
||||
} |
||||
} |
||||
|
||||
// Callback made from esp-link to notify of wifi status changes
|
||||
// Here we print something out and set a global flag
|
||||
void wifiCb(void *response) { |
||||
ELClientResponse *res = (ELClientResponse*)response; |
||||
if (res->argc() == 1) { |
||||
uint8_t status; |
||||
res->popArg(&status, 1); |
||||
|
||||
if(status == STATION_GOT_IP) { |
||||
Serial.println(F("WIFI CONNECTED")); |
||||
wifiConnected = true; |
||||
} else { |
||||
Serial.print(F("WIFI NOT READY: ")); |
||||
Serial.println(status); |
||||
wifiConnected = false; |
||||
} |
||||
} |
||||
} |
||||
|
||||
void setup() { |
||||
Serial.begin(115200); |
||||
i2cuart.begin(9600); |
||||
Serial.println(F("EL-Client starting!")); |
||||
|
||||
// Sync-up with esp-link, this is required at the start of any sketch and initializes the
|
||||
// callbacks to the wifi status change callback. The callback gets called with the initial
|
||||
// status right after Sync() below completes.
|
||||
esp.wifiCb.attach(wifiCb); // wifi status change callback, optional (delete if not desired)
|
||||
bool ok; |
||||
do { |
||||
ok = esp.Sync(); // sync up with esp-link, blocks for up to 2 seconds
|
||||
if (!ok) Serial.println(F("EL-Client sync failed!")); |
||||
} while(!ok); |
||||
Serial.println(F("EL-Client synced!")); |
||||
|
||||
// Get immediate wifi status info for demo purposes. This is not normally used because the
|
||||
// wifi status callback registered above gets called immediately.
|
||||
esp.GetWifiStatus(); |
||||
ELClientPacket *packet; |
||||
if ((packet=esp.WaitReturn()) != NULL) { |
||||
Serial.print(F("Wifi status: ")); |
||||
Serial.println(packet->value); |
||||
} |
||||
|
||||
// Set up the UDP socket client to send a short message to <udpServer> on port <>, this doesn't connect to that server,
|
||||
// it just sets-up stuff on the esp-link side
|
||||
int err = udp.begin(udpServer, udpPort, SOCKET_UDP, udpCb); |
||||
if (err < 0) { |
||||
Serial.print(F("UDP begin failed: ")); |
||||
Serial.println(err); |
||||
delay(10000); |
||||
asm volatile (" jmp 0"); |
||||
} |
||||
|
||||
err = udp2.begin(udpServer2, udpPort2, SOCKET_UDP, udpCb); |
||||
if (err < 0) { |
||||
Serial.print(F("UDP2 begin failed: ")); |
||||
Serial.println(err); |
||||
delay(10000); |
||||
asm volatile (" jmp 0"); |
||||
} |
||||
|
||||
Serial.println(F("EL-Client ready!")); |
||||
wait = millis()+29000; // Start first sending in 1 second
|
||||
} |
||||
|
||||
void loop() { |
||||
// process any callbacks coming from esp_link
|
||||
esp.Process(); |
||||
|
||||
// if we're connected send data over UDP socket
|
||||
if(wifiConnected) { |
||||
if (millis() - wait > 30000) { // Send some data every 30 seconds
|
||||
wait = millis(); |
||||
// Send message to the previously set-up server #1
|
||||
Serial.print(F("Sending message to ")); |
||||
Serial.println(udpServer); |
||||
udp.send("Message from your Arduino Uno WiFi over UDP socket"); |
||||
|
||||
// Send message to the previously set-up server #2
|
||||
Serial.print(F("Sending broadcast to ")); |
||||
Serial.println(udpServer2); |
||||
udp2.send("Broadcast from your Arduino Uno WiFi over UDP socket"); |
||||
} |
||||
} else { |
||||
// This is just for demo, you can as well just try to reconnect
|
||||
// and setup the connection to esp-link again
|
||||
Serial.println(F("Lost connection, try to reboot")); |
||||
delay(10000); |
||||
asm volatile (" jmp 0"); |
||||
} |
||||
} |
||||
@ -0,0 +1,36 @@
@@ -0,0 +1,36 @@
|
||||
<!-- EspLink will add header here --> |
||||
|
||||
<div class="header"> |
||||
<h1>LED configuration</h1> |
||||
</div> |
||||
|
||||
<div class="content"> |
||||
<div class="pure-g"><div class="pure-u-1 pure-u-md-1-2"> |
||||
<div class="card"> |
||||
<h1>Control</h1> |
||||
<button id="btn_on" type="button">Turn on</button> |
||||
<button id="btn_blink" type="button">Start blinking</button> |
||||
<button id="btn_off" type="button">Turn off</button> |
||||
<p id="text"/> |
||||
</div> |
||||
<div class="card"> |
||||
<h1>Frequency and duty</h1> |
||||
<form> |
||||
<b>Duty:</b><br/> |
||||
<input type="radio" name="duty" value="25_75">25% on 75% off</input><br/> |
||||
<input type="radio" name="duty" value="50_50">50% on 50% off</input><br/> |
||||
<input type="radio" name="duty" value="75_25">75% on 25% off</input><br/> |
||||
|
||||
<b>Frequency:</b><br/> |
||||
<input type="range" name="frequency" min="1" max="25"><br/> |
||||
<input type="submit"> |
||||
</form> |
||||
</div></div> |
||||
<div class="pure-u-1 pure-u-md-1-2"> |
||||
<div class="card" style="min-height: 400px"> |
||||
<h1>Logs</h1> |
||||
<ul id="led_history"/> |
||||
</div> |
||||
</div></div> |
||||
</div> |
||||
</body></html> |
||||
@ -0,0 +1,227 @@
@@ -0,0 +1,227 @@
|
||||
#include <ELClientWebServer.h> |
||||
|
||||
// the PIN to flash
|
||||
#define LED_PIN 13 |
||||
|
||||
int8_t blinking = 0; // whether LED is blinking
|
||||
uint8_t blinking_duty = 2; // blinking duty
|
||||
int8_t blinking_frequency = 10; // blinking frequency
|
||||
|
||||
uint32_t blinking_next_ts = 0; // the next timestamp to blink
|
||||
uint16_t blinking_phase = 100; // blinking phase
|
||||
uint16_t blinking_period = 200; // blinking period (2000 / frequency)
|
||||
|
||||
#define MAX_LOGS 5 |
||||
uint32_t log_ts[MAX_LOGS]; // log timestamp
|
||||
uint8_t log_msg[MAX_LOGS]; // log message
|
||||
uint8_t log_ptr = 0; // log pointer
|
||||
|
||||
typedef enum |
||||
{ |
||||
LOG_DUTY_25_75 = 0xE1, |
||||
LOG_DUTY_50_50, |
||||
LOG_DUTY_75_25, |
||||
LOG_SET_LED_ON = 0xF0, |
||||
LOG_SET_LED_BLINKING, |
||||
LOG_SET_LED_OFF, |
||||
} LogMessage; |
||||
|
||||
// LED loop code
|
||||
void ledLoop() |
||||
{
|
||||
if( blinking ) // if blinking is enabled
|
||||
{ |
||||
if( blinking_next_ts <= millis() ) |
||||
{ |
||||
digitalWrite(LED_PIN, !digitalRead(LED_PIN)); // blink LED
|
||||
blinking_next_ts += blinking_phase; |
||||
blinking_phase = blinking_period - blinking_phase; |
||||
} |
||||
} |
||||
} |
||||
|
||||
// adds a new log message
|
||||
void ledAddLog(uint8_t msg) |
||||
{ |
||||
// check if max log is reached
|
||||
if( log_ptr >= MAX_LOGS ) |
||||
log_ptr = MAX_LOGS - 1; |
||||
|
||||
// move logs back with one and delete the oldest log
|
||||
for(int8_t i=log_ptr-1; i >= 0; i--) |
||||
{ |
||||
log_ts[i+1] = log_ts[i]; |
||||
log_msg[i+1] = log_msg[i]; |
||||
} |
||||
|
||||
log_msg[0] = msg; // log message
|
||||
log_ts[0] = millis(); // log timestamp
|
||||
log_ptr++; // a new log was added
|
||||
} |
||||
|
||||
// create log messages to string
|
||||
String ledHistoryToLog() |
||||
{ |
||||
String str = "["; |
||||
|
||||
for(uint8_t i=0; i < log_ptr; i++) |
||||
{ |
||||
if( i != 0 ) |
||||
str += ','; |
||||
|
||||
str += '\"'; |
||||
str += (log_ts[i] / 1000); |
||||
str += "s: "; |
||||
|
||||
switch(log_msg[i]) // log message
|
||||
{ |
||||
case LOG_DUTY_25_75: |
||||
str += F("set duty to 25%-75%"); |
||||
break; |
||||
case LOG_DUTY_50_50: |
||||
str += F("set duty to 50%-50%"); |
||||
break; |
||||
case LOG_DUTY_75_25: |
||||
str += F("set duty to 75%-25%"); |
||||
break; |
||||
case LOG_SET_LED_ON: |
||||
str += F("set led on"); |
||||
break; |
||||
case LOG_SET_LED_BLINKING: |
||||
str += F("set led blinking"); |
||||
break; |
||||
case LOG_SET_LED_OFF: |
||||
str += F("set led off"); |
||||
break; |
||||
default: |
||||
str += F("set frequency to "); |
||||
str += (int)log_msg[i]; |
||||
str += F(" Hz"); |
||||
break; |
||||
} |
||||
str += '\"'; |
||||
} |
||||
str += ']'; |
||||
|
||||
return str; |
||||
} |
||||
|
||||
// called at button pressing
|
||||
void ledButtonPressCb(const char * button) |
||||
{ |
||||
String btn = button; |
||||
if( btn == F("btn_on") ) |
||||
{ |
||||
if( blinking || digitalRead(LED_PIN) == false ) |
||||
ledAddLog(LOG_SET_LED_ON); |
||||
blinking = 0; |
||||
digitalWrite(LED_PIN, true); |
||||
} |
||||
else if( btn == F("btn_off") ) |
||||
{ |
||||
if( blinking || digitalRead(LED_PIN) == true ) |
||||
ledAddLog(LOG_SET_LED_OFF); |
||||
blinking = 0; |
||||
digitalWrite(LED_PIN, false); |
||||
} |
||||
else if( btn == F("btn_blink") ) |
||||
{ |
||||
if( !blinking ) |
||||
ledAddLog(LOG_SET_LED_BLINKING); |
||||
blinking = 1; |
||||
blinking_next_ts = millis() + blinking_phase; |
||||
} |
||||
} |
||||
|
||||
// setting the value of a field
|
||||
//
|
||||
// handle data as fast as possible
|
||||
// - huge HTML forms can arrive in multiple packets
|
||||
// - if this method is slow, UART receive buffer may overrun
|
||||
void ledSetFieldCb(const char * field) |
||||
{ |
||||
String fld = field; |
||||
if( fld == F("frequency") ) |
||||
{ |
||||
int8_t oldf = blinking_frequency; |
||||
blinking_frequency = webServer.getArgInt(); |
||||
|
||||
blinking_period = 2000 / blinking_frequency; |
||||
blinking_phase = blinking_duty * blinking_period / 4; |
||||
|
||||
if( oldf != blinking_frequency ) |
||||
{ |
||||
ledAddLog(blinking_frequency); |
||||
if( blinking ) |
||||
digitalWrite(LED_PIN, false); |
||||
} |
||||
} |
||||
else if( fld == F("duty") ) |
||||
{ |
||||
int8_t oldp = blinking_duty; |
||||
String arg = webServer.getArgString(); |
||||
|
||||
if( arg == F("25_75") ) |
||||
blinking_duty = 1; |
||||
else if( arg == F("50_50") ) |
||||
blinking_duty = 2; |
||||
else if( arg == F("75_25") ) |
||||
blinking_duty = 3; |
||||
|
||||
if( blinking ) |
||||
digitalWrite(LED_PIN, false); |
||||
|
||||
blinking_phase = blinking_duty * blinking_period / 4; |
||||
|
||||
if( oldp != blinking_duty ) |
||||
ledAddLog(LOG_DUTY_25_75 - 1 + blinking_duty); |
||||
} |
||||
} |
||||
|
||||
// called at page refreshing
|
||||
void ledRefreshCb(const char * url) |
||||
{ |
||||
if( blinking ) |
||||
webServer.setArgString(F("text"), F("LED is blinking")); |
||||
else |
||||
webServer.setArgString(F("text"), digitalRead(LED_PIN) ? F("LED is turned on") : F("LED is turned off")); |
||||
|
||||
String log = ledHistoryToLog(); |
||||
webServer.setArgJson(F("led_history"), log.begin()); |
||||
} |
||||
|
||||
// called at page loading
|
||||
void ledLoadCb(const char * url) |
||||
{ |
||||
webServer.setArgInt(F("frequency"), blinking_frequency); |
||||
|
||||
switch(blinking_duty) |
||||
{ |
||||
case 1: |
||||
webServer.setArgString(F("duty"), F("25_75")); |
||||
break; |
||||
case 2: |
||||
webServer.setArgString(F("duty"), F("50_50")); |
||||
break; |
||||
case 3: |
||||
webServer.setArgString(F("duty"), F("75_25")); |
||||
break; |
||||
} |
||||
|
||||
ledRefreshCb( url ); |
||||
} |
||||
|
||||
// LED setup code
|
||||
void ledInit() |
||||
{ |
||||
// set mode to output and turn LED off
|
||||
pinMode(LED_PIN, OUTPUT); |
||||
digitalWrite(LED_PIN, false); |
||||
|
||||
URLHandler *ledHandler = webServer.createURLHandler(F("/LED.html.json")); |
||||
ledHandler->buttonCb.attach(ledButtonPressCb); |
||||
ledHandler->setFieldCb.attach(ledSetFieldCb); |
||||
ledHandler->loadCb.attach(ledLoadCb); |
||||
ledHandler->refreshCb.attach(ledRefreshCb); |
||||
} |
||||
|
||||
@ -0,0 +1,14 @@
@@ -0,0 +1,14 @@
|
||||
#ifndef PAGES_H |
||||
#define PAGES_H |
||||
|
||||
void ledLoop(); |
||||
void ledInit(); |
||||
|
||||
void userInit(); |
||||
|
||||
void voltageLoop(); |
||||
void voltageInit(); |
||||
|
||||
#endif /* PAGES_H */ |
||||
|
||||
|
||||
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
<!-- EspLink will add header here --> |
||||
|
||||
<div class="header"> |
||||
<h1>User setup</h1> |
||||
</div> |
||||
|
||||
<div class="content"> |
||||
<form> |
||||
First name:<br/><input name="first_name" type="text"/> |
||||
Last name:<br/><input name="last_name" type="text"/> |
||||
Age: |
||||
<input name="age" type="number"/> |
||||
Gender: |
||||
<select name="gender"> |
||||
<option value="female">Female</option> |
||||
<option value="male">Male</option> |
||||
</select> |
||||
<br> |
||||
Notifications<input name="notifications" type="checkbox"/> |
||||
<br> |
||||
<input type="submit"> |
||||
</form> |
||||
</div> |
||||
</body></html> |
||||
@ -0,0 +1,95 @@
@@ -0,0 +1,95 @@
|
||||
#include <EEPROM.h> |
||||
#include <ELClientWebServer.h> |
||||
|
||||
#define MAGIC 0xABEF |
||||
#define MAX_STR_LEN 32 |
||||
|
||||
// EEPROM content
|
||||
#define EEPROM_POS_MAGIC 0 |
||||
#define EEPROM_POS_FIRST_NAME (EEPROM_POS_MAGIC + 2) |
||||
#define EEPROM_POS_LAST_NAME (EEPROM_POS_FIRST_NAME + MAX_STR_LEN) |
||||
#define EEPROM_POS_AGE (EEPROM_POS_LAST_NAME + MAX_STR_LEN) |
||||
#define EEPROM_POS_GENDER (EEPROM_POS_AGE+1) |
||||
#define EEPROM_POS_NOTIFICATIONS (EEPROM_POS_GENDER+1) |
||||
|
||||
// write a string to EEPROM
|
||||
void userWriteStr(char * str, int ndx) |
||||
{ |
||||
for(uint8_t i=0; i < MAX_STR_LEN-1; i++) |
||||
{ |
||||
EEPROM.update(ndx + i, str[i]); |
||||
if( str[i] == 0 ) |
||||
break; |
||||
} |
||||
EEPROM.update(ndx + MAX_STR_LEN - 1, 0); |
||||
} |
||||
|
||||
|
||||
// read a string from EEPROM
|
||||
void userReadStr(char * str, int ndx) |
||||
{ |
||||
for(uint8_t i=0; i < MAX_STR_LEN; i++) |
||||
{ |
||||
str[i] = EEPROM[ndx + i]; |
||||
} |
||||
} |
||||
|
||||
|
||||
// setting the value of a field
|
||||
//
|
||||
// handle data as fast as possible
|
||||
// - huge HTML forms can arrive in multiple packets
|
||||
// - if this method is slow, UART receive buffer may overrun
|
||||
void userSetFieldCb(const char * field) |
||||
{ |
||||
String fld = field; |
||||
if( fld == F("first_name")) |
||||
userWriteStr(webServer.getArgString(), EEPROM_POS_FIRST_NAME); |
||||
else if( fld == F("last_name")) |
||||
userWriteStr(webServer.getArgString(), EEPROM_POS_LAST_NAME); |
||||
else if( fld == F("age")) |
||||
EEPROM.update(EEPROM_POS_AGE, (uint8_t)webServer.getArgInt()); |
||||
else if( fld == F("gender")) |
||||
{ |
||||
String gender = webServer.getArgString(); |
||||
EEPROM.update(EEPROM_POS_GENDER, (gender == F("male")) ? 'm' : 'f'); |
||||
} |
||||
else if( fld == F("notifications")) |
||||
EEPROM.update(EEPROM_POS_NOTIFICATIONS, webServer.getArgBoolean()); |
||||
} |
||||
|
||||
// called at page loading
|
||||
void userLoadCb(const char * url) |
||||
{ |
||||
char buf[MAX_STR_LEN]; |
||||
userReadStr( buf, EEPROM_POS_FIRST_NAME ); |
||||
webServer.setArgString(F("first_name"), buf); |
||||
userReadStr( buf, EEPROM_POS_LAST_NAME ); |
||||
webServer.setArgString(F("last_name"), buf); |
||||
webServer.setArgInt(F("age"), (uint8_t)EEPROM[EEPROM_POS_AGE]); |
||||
webServer.setArgString(F("gender"), (EEPROM[EEPROM_POS_GENDER] == 'm') ? F("male") : F("female")); |
||||
webServer.setArgBoolean(F("notifications"), EEPROM[EEPROM_POS_NOTIFICATIONS] != 0); |
||||
} |
||||
|
||||
// initialization
|
||||
void userInit() |
||||
{ |
||||
uint16_t magic; |
||||
EEPROM.get(EEPROM_POS_MAGIC, magic); |
||||
|
||||
if( magic != MAGIC ) // EEPROM is uninitialized?
|
||||
{ |
||||
magic = MAGIC; |
||||
// set default values
|
||||
EEPROM.put(EEPROM_POS_MAGIC, magic); |
||||
EEPROM.update(EEPROM_POS_FIRST_NAME, 0); |
||||
EEPROM.update(EEPROM_POS_LAST_NAME, 0); |
||||
EEPROM.update(EEPROM_POS_AGE, 0); |
||||
EEPROM.update(EEPROM_POS_GENDER, 'f'); |
||||
EEPROM.update(EEPROM_POS_NOTIFICATIONS, 0); |
||||
} |
||||
|
||||
URLHandler *userPageHandler = webServer.createURLHandler(F("/User.html.json")); |
||||
userPageHandler->setFieldCb.attach(userSetFieldCb); |
||||
userPageHandler->loadCb.attach(userLoadCb); |
||||
} |
||||
@ -0,0 +1,15 @@
@@ -0,0 +1,15 @@
|
||||
<!-- EspLink will add header here --> |
||||
|
||||
<meta name="refresh-rate" content="500" /> |
||||
|
||||
<div class="header"> |
||||
<h1>Voltage measurement</h1> |
||||
</div> |
||||
|
||||
<div class="content"> |
||||
<p id="voltage" align="center" style="font-size: 800%"/> |
||||
|
||||
<table class="pure-table pure-table-bordered" align="center" id="table"/> |
||||
</div> |
||||
|
||||
</body></html> |
||||
@ -0,0 +1,129 @@
@@ -0,0 +1,129 @@
|
||||
#include <ELClientWebServer.h> |
||||
#include <avr/io.h> |
||||
|
||||
#define SAMPLE_COUNT 100 |
||||
#define PERIOD_COUNT (135 * SAMPLE_COUNT) |
||||
|
||||
uint16_t adc_min = 0xFFFF; // min value of ADC
|
||||
uint16_t adc_max = 0; // max value of ADC
|
||||
uint32_t adc_avg = 0; // AVG average
|
||||
|
||||
uint16_t sample_count; // collected sample
|
||||
uint32_t voltage_avg = 0; // AVG used for voltage measurement
|
||||
uint16_t measured_voltage = 0; // measured voltage
|
||||
|
||||
#define MAX_HISTORY 3 // max history count
|
||||
|
||||
uint8_t history_cnt = 0; // number of histories
|
||||
uint32_t history_ts[MAX_HISTORY]; // timestamp
|
||||
uint16_t history_min[MAX_HISTORY]; // min
|
||||
uint16_t history_max[MAX_HISTORY]; // max
|
||||
uint16_t history_avg[MAX_HISTORY]; // avg
|
||||
|
||||
uint16_t calibrate = 0x128; // calibrate this manually
|
||||
|
||||
// voltage measuring loop
|
||||
void voltageLoop() |
||||
{ |
||||
uint16_t adc = analogRead(A0); // read ADC
|
||||
|
||||
// set min/max/avg
|
||||
if( adc < adc_min ) |
||||
adc_min = adc; |
||||
if( adc > adc_max ) |
||||
adc_max = adc; |
||||
adc_avg += adc; |
||||
|
||||
voltage_avg += adc; |
||||
sample_count++; |
||||
|
||||
if( (sample_count % SAMPLE_COUNT) == 0 ) // max samples reached?
|
||||
{ |
||||
// calculate measured voltage
|
||||
voltage_avg /= SAMPLE_COUNT; |
||||
measured_voltage = voltage_avg * calibrate / 256; |
||||
voltage_avg = 0; |
||||
} |
||||
if( sample_count == PERIOD_COUNT ) |
||||
{ |
||||
// calculate min/max/avg and put into history
|
||||
|
||||
for(int8_t i=MAX_HISTORY-2; i >=0; i-- ) |
||||
{ |
||||
history_ts[i+1] = history_ts[i]; |
||||
history_min[i+1] = history_min[i]; |
||||
history_max[i+1] = history_max[i]; |
||||
history_avg[i+1] = history_avg[i]; |
||||
} |
||||
|
||||
history_ts[0] = millis(); |
||||
history_min[0] = (uint32_t)adc_min * calibrate / 256; |
||||
history_max[0] = (uint32_t)adc_max * calibrate / 256; |
||||
history_avg[0] = (adc_avg / PERIOD_COUNT) * calibrate / 256; |
||||
|
||||
adc_min = 0xFFFF; |
||||
adc_max = 0; |
||||
adc_avg = 0; |
||||
|
||||
if( history_cnt < MAX_HISTORY ) |
||||
history_cnt++; |
||||
sample_count = 0; |
||||
} |
||||
} |
||||
|
||||
// sprintf %f is not supported on Arduino...
|
||||
String floatToString(float f) |
||||
{ |
||||
int16_t intg = (int16_t)(f * 100.f); |
||||
int16_t int_part = intg / 100; |
||||
int16_t fract_part = intg % 100; |
||||
|
||||
char buf[20]; |
||||
sprintf(buf, "%d.%02d", int_part, fract_part); |
||||
|
||||
return String(buf); |
||||
} |
||||
|
||||
void voltageRefreshCb(const char * url) |
||||
{ |
||||
// calculate voltage value
|
||||
String v = floatToString((float)measured_voltage / 256.f); |
||||
v += " V"; |
||||
webServer.setArgString(F("voltage"), v.begin()); |
||||
|
||||
char buf[20]; |
||||
// calculate history table
|
||||
String table = F("[[\"Time\",\"Min\",\"AVG\",\"Max\"]"); |
||||
|
||||
for(uint8_t i=0; i < history_cnt; i++ ) |
||||
{ |
||||
float min_f = (float)history_min[i] / 256.f; |
||||
float max_f = (float)history_max[i] / 256.f; |
||||
float avg_f = (float)history_avg[i] / 256.f; |
||||
|
||||
table += F(",[\""); |
||||
table += (history_ts[i] / 1000); |
||||
table += F(" s\",\""); |
||||
table += floatToString(min_f); |
||||
table += " V\",\""; |
||||
table += floatToString(avg_f); |
||||
table += " V\",\""; |
||||
table += floatToString(max_f); |
||||
table += " V\"]"; |
||||
} |
||||
|
||||
table += ']'; |
||||
webServer.setArgJson(F("table"), table.begin()); |
||||
} |
||||
|
||||
// page setup
|
||||
void voltageInit() |
||||
{ |
||||
analogReference(DEFAULT); |
||||
sample_count = 0; |
||||
|
||||
URLHandler *voltageHandler = webServer.createURLHandler(F("/Voltage.html.json")); |
||||
|
||||
voltageHandler->loadCb.attach(voltageRefreshCb); |
||||
voltageHandler->refreshCb.attach(voltageRefreshCb); |
||||
} |
||||
@ -0,0 +1,65 @@
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* This is a sample for trying out each HTML control |
||||
*
|
||||
* Test board: |
||||
* ESP8266 RX <--level shifter--> Arduino TX |
||||
* ESP8266 TX <--level shifter--> Arduino RX |
||||
* ESP8266 GPIO0 <--level shifter--> Arduino RESET (optional) |
||||
*
|
||||
* Arduino LED is on PIN 13 |
||||
* Connect an 1K trimmer to Arduino (voltage): VCC <-> A0 <-> GND |
||||
*
|
||||
*
|
||||
* Video: |
||||
* https://www.youtube.com/watch?v=vBESCO0UhYI
|
||||
*/ |
||||
|
||||
#include <ELClient.h> |
||||
#include <ELClientWebServer.h> |
||||
#include "Pages.h" |
||||
|
||||
// Initialize a connection to esp-link using the normal hardware serial port
|
||||
//
|
||||
// DEBUG is disasbled as
|
||||
// - packet logging is slow and UART receive buffer can overrun (HTML form submission)
|
||||
ELClient esp(&Serial, &Serial); |
||||
|
||||
// Initialize the Web-Server client
|
||||
ELClientWebServer webServer(&esp); |
||||
|
||||
|
||||
// Callback made form esp-link to notify that it has just come out of a reset. This means we
|
||||
// need to initialize it!
|
||||
void resetCb(void) { |
||||
Serial.println("EL-Client (re-)starting!"); |
||||
bool ok = false; |
||||
do { |
||||
ok = esp.Sync(); // sync up with esp-link, blocks for up to 2 seconds
|
||||
if (!ok) Serial.println("EL-Client sync failed!"); |
||||
} while(!ok); |
||||
Serial.println("EL-Client synced!"); |
||||
|
||||
webServer.setup(); |
||||
} |
||||
|
||||
void setup() |
||||
{ |
||||
Serial.begin(115200); |
||||
|
||||
esp.resetCb = resetCb; |
||||
|
||||
ledInit(); |
||||
userInit(); |
||||
voltageInit(); |
||||
|
||||
resetCb(); |
||||
} |
||||
|
||||
void loop() |
||||
{ |
||||
esp.Process(); |
||||
|
||||
ledLoop(); |
||||
voltageLoop(); |
||||
} |
||||
|
||||
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
HOST ?= esp-link
|
||||
LIBRARYPATH = $(ARDUINODIR)/libraries ../../..
|
||||
LIBRARIES = ELClient
|
||||
CPPFLAGS =
|
||||
SERIALDEV = net:$(HOST):2323
|
||||
include ../arduino.mk |
||||
|
||||
flash: all |
||||
../avrflash $(HOST) webserver_led.hex
|
||||
nc $(HOST) 23
|
||||
|
||||
run: upload size |
||||
nc $(HOST) 23
|
||||
@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
|
||||
<!-- EspLink will add header here --> |
||||
|
||||
<h1 class="header">Simple LED control</h1> |
||||
<h2><div id="text"/></h2> |
||||
<button id="btn_on" type="button">Turn on</button> |
||||
<button id="btn_off" type="button">Turn off</button> |
||||
</body></html> |
||||
@ -0,0 +1,543 @@
@@ -0,0 +1,543 @@
|
||||
:100000000C948D000C94B5000C94B5000C94B500C4 |
||||
:100010000C94B5000C94B5000C94B5000C94B5008C |
||||
:100020000C94B5000C94B5000C94B5000C94B5007C |
||||
:100030000C94B5000C94B5000C94B5000C94B5006C |
||||
:100040000C94680D0C94B5000C9417030C944903A0 |
||||
:100050000C94B5000C94B5000C94B5000C94B5004C |
||||
:100060000C94B5000C94B5002F53696D706C654C01 |
||||
:1000700045442E68746D6C2E6A736F6E0062746EE8 |
||||
:100080005F6F66660062746E5F6F6E007465787491 |
||||
:10009000004C4544206973206F666600746578746F |
||||
:1000A000004C4544206973206F6E0000000008007A |
||||
:1000B000020100000304070000000000000000012E |
||||
:1000C00002040810204080010204081020010204EC |
||||
:1000D00008102004040404040404040202020202BE |
||||
:1000E000020303030303030000000023002600298A |
||||
:1000F0000000000000250028002B0048616E646CA1 |
||||
:100100006572206E6F7420666F756E6420666F7204 |
||||
:100110002055524C3A006301790311241FBECFEFE2 |
||||
:10012000D8E0DEBFCDBF11E0A0E0B1E0E2E1F1E256 |
||||
:1001300002C005900D92A23BB107D9F723E0A2EBD4 |
||||
:10014000B1E001C01D92A630B207E1F710E0CDE8A2 |
||||
:10015000D0E004C02197FE010E941D0ECB38D107CC |
||||
:10016000C9F70E94C0040C9487100C9400001F93E0 |
||||
:10017000CF93DF93CDB7DEB72C970FB6F894DEBFE1 |
||||
:100180000FBECDBFBC01CE0107960E945F0265E89D |
||||
:1001900070E0CE0101960E94CD02BE016F5F7F4FDD |
||||
:1001A000CE0107960E940603182FCE0101960E94E9 |
||||
:1001B000F101112311F061E015C06DE770E0CE018F |
||||
:1001C00001960E94CD02BE016F5F7F4FCE01079660 |
||||
:1001D0000E940603182FCE0101960E94F1011123FF |
||||
:1001E00021F060E08DE00E949801CE0107960E9408 |
||||
:1001F000F1012C960FB6F894DEBF0FBECDBFDF9194 |
||||
:10020000CF911F91089566E071E08AE592E00E9427 |
||||
:10021000170440ED57E060E070E084EC91E00E944C |
||||
:10022000700C811103C06FE171E0EFCF66E371E004 |
||||
:100230008AE592E00E94170482EB91E00C94E506B7 |
||||
:100240008DE00E94C801892B29F041EA50E06CE959 |
||||
:1002500070E004C041E950E06CE870E082EB91E0AE |
||||
:100260000C948D08CF93DF9326E040E052EC61E0E0 |
||||
:1002700070E08AE592E00E94950568E670E082EB06 |
||||
:1002800091E00E94C006EC0160E271E006960E94D7 |
||||
:10029000000660E271E0CE010C960E94000667EB5A |
||||
:1002A00070E0CE0148960E94000683E091E09093B2 |
||||
:1002B000CD018093CC01DF91CF910C94030184ECAC |
||||
:1002C00091E00C94010B6AE572E084EC91E00E94ED |
||||
:1002D000540964EC71E082EB91E00C946806833081 |
||||
:1002E00081F028F4813099F08230A1F008958730B0 |
||||
:1002F000A9F08830B9F08430D1F4809180008F7DEE |
||||
:1003000003C0809180008F7780938000089584B52A |
||||
:100310008F7702C084B58F7D84BD08958091B00031 |
||||
:100320008F7703C08091B0008F7D8093B0000895D7 |
||||
:100330001F93CF93DF93282F30E0F901E555FF4F4E |
||||
:100340008491F901E154FF4FD491F901ED52FF4F2F |
||||
:10035000C491CC23C9F0162F81110E946F01EC2F9C |
||||
:10036000F0E0EE0FFF1FEF50FF4FA591B4918FB754 |
||||
:10037000F894111105C09C91ED2FE095E92302C07E |
||||
:10038000EC91ED2BEC938FBFDF91CF911F910895EE |
||||
:10039000CF93DF93282F30E0F901E555FF4F84918B |
||||
:1003A000F901E154FF4FD491F901ED52FF4FC4918F |
||||
:1003B000CC2391F081110E946F01EC2FF0E0EE0F41 |
||||
:1003C000FF1FE951FF4FA591B491EC91ED2381E01E |
||||
:1003D00090E021F480E002C080E090E0DF91CF91D6 |
||||
:1003E0000895FC01808191810C94B80ECF93DF9326 |
||||
:1003F000EC0188819981009711F00E94B80E198252 |
||||
:1004000018821D821C821B821A82DF91CF9108956F |
||||
:100410000F931F93CF93DF93EC018B016F5F7F4F9F |
||||
:10042000888199810E94500F009731F099838883C9 |
||||
:100430001B830A8381E001C080E0DF91CF911F918F |
||||
:100440000F910895CF93DF93EC0188819981892BD7 |
||||
:1004500029F08A819B818617970760F4CE010E945C |
||||
:100460000802882341F08C819D81892B19F4E88151 |
||||
:10047000F981108281E0DF91CF910895EF92FF9290 |
||||
:100480000F931F93CF93DF93EC017B018A01BA0195 |
||||
:100490000E942202811104C0CE010E94F60107C011 |
||||
:1004A0001D830C83B701888199810E944910CE0178 |
||||
:1004B000DF91CF911F910F91FF90EF900895FC0174 |
||||
:1004C00011821082138212821582148261157105C5 |
||||
:1004D00051F0FB0101900020E9F73197AF01461B75 |
||||
:1004E000570B0C943E020895EF92FF920F931F93C7 |
||||
:1004F000CF93DF93EC017B018A01BA010E942202B3 |
||||
:10050000811104C0CE010E94F60107C01D830C8337 |
||||
:10051000B701888199810E941A10CE01DF91CF9195 |
||||
:100520001F910F91FF90EF900895CF93DF93EC010F |
||||
:10053000FB018617970761F0608171816115710574 |
||||
:1005400029F0448155810E943E0202C00E94F601BA |
||||
:10055000CE01DF91CF9108950F931F93CF93DF9337 |
||||
:1005600000D0CDB7DEB78C016115710561F0CB010C |
||||
:1005700069837A830E942110AC0169817A81C80164 |
||||
:100580000E94740202C00E94F601C8010F900F90F1 |
||||
:10059000DF91CF911F910F910895FC01118210827C |
||||
:1005A00013821282158214820C94AC02CF93DF93D3 |
||||
:1005B000DC01ED91FC91EB01A881B981309711F03C |
||||
:1005C0001097C9F4109759F0EB012C813D81232B32 |
||||
:1005D00031F08C9190E091958195910914C03097FC |
||||
:1005E00081F0DC0114968D919C911597892B49F02F |
||||
:1005F000808190E008C0BD01CF01DF91CF910C94C4 |
||||
:10060000401080E090E0DF91CF910895FC0144819B |
||||
:100610005581FB01248135814217530729F40E943B |
||||
:10062000D60221E0892B09F020E0822F08951F9245 |
||||
:100630000F920FB60F9211242F938F939F93EF93E6 |
||||
:10064000FF93E0916A02F0916B028081E091700269 |
||||
:10065000F091710282FD12C09081809173028F5FD0 |
||||
:100660008F7320917402821751F0E0917302F0E0D1 |
||||
:10067000E65AFD4F958F8093730201C08081FF91F0 |
||||
:10068000EF919F918F912F910F900FBE0F901F9020 |
||||
:1006900018951F920F920FB60F9211242F933F932C |
||||
:1006A0004F935F936F937F938F939F93AF93BF937A |
||||
:1006B000EF93FF938AE592E00E940B05FF91EF9183 |
||||
:1006C000BF91AF919F918F917F916F915F914F916A |
||||
:1006D0003F912F910F900FBE0F901F9018958AE5B4 |
||||
:1006E00092E00E94CF0421E0892B09F420E0822FC0 |
||||
:1006F0000895EAE5F2E01382128288EE93E0A0E02A |
||||
:10070000B0E084839583A683B7838DE591E09183E0 |
||||
:10071000808385EC90E09587848784EC90E09787D0 |
||||
:10072000868780EC90E0918B808B81EC90E0938BBE |
||||
:10073000828B82EC90E0958B848B86EC90E0978B9B |
||||
:10074000868B118E128E138E148E0895CF92DF92A7 |
||||
:10075000EF92FF920F931F93CF93DF936C017A0177 |
||||
:100760008B01C0E0D0E0CE15DF0589F0D8016D9196 |
||||
:100770008D01D601ED91FC910190F081E02DC60133 |
||||
:100780000995892B11F47E0102C02196ECCFC70197 |
||||
:10079000DF91CF911F910F91FF90EF90DF90CF905D |
||||
:1007A00008956115710579F0FB0101900020E9F7CA |
||||
:1007B0003197AF01461B570BDC01ED91FC91028094 |
||||
:1007C000F381E02D099480E090E00895EF92FF928C |
||||
:1007D0000F931F93CF93DF938C017B01C0E0D0E098 |
||||
:1007E000F701EC0FFD1F6491662361F0D801ED91D4 |
||||
:1007F000FC910190F081E02DC8010995892B11F041 |
||||
:100800002196EECFCE01DF91CF911F910F91FF90F6 |
||||
:10081000EF9008950C94D103DC01ED91FC910190CF |
||||
:10082000F081E02D099468E471E00C94D1030F93FA |
||||
:100830001F93CF93DF93EC010E94D1038C01CE0173 |
||||
:100840000E941304800F911FDF91CF911F910F9190 |
||||
:1008500008958F929F92AF92BF92CF92DF92EF92C4 |
||||
:10086000FF920F931F93CF93DF93CDB7DEB7A1977E |
||||
:100870000FB6F894DEBF0FBECDBF7C01D42EC52EBF |
||||
:10088000DB0119A2223008F42AE08E010F5D1F4F10 |
||||
:10089000822E912CA12CB12C6D2D7C2DCD01A5018A |
||||
:1008A00094010E94FB0DD22EC32EDA0101501109D2 |
||||
:1008B0006A3071058105910510F4605D01C0695CC5 |
||||
:1008C000F8016083232B242B252B31F7B801C701B6 |
||||
:1008D0000E94D103A1960FB6F894DEBF0FBECDBF24 |
||||
:1008E000DF91CF911F910F91FF90EF90DF90CF900C |
||||
:1008F000BF90AF909F908F9008952115310541F4DE |
||||
:10090000DC01ED91FC910190F081E02D642F0994C0 |
||||
:100910000C9429049A01462F50E060E070E00C949A |
||||
:100920007D049A01AB0160E070E00C947D040F93AC |
||||
:100930001F93CF93DF93EC019A01AB0160E070E06D |
||||
:100940000E947D048C01CE010E941304800F911F30 |
||||
:10095000DF91CF911F910F9108950F931F93CF9324 |
||||
:10096000DF93EC010E947D048C01CE010E941304F0 |
||||
:10097000800F911FDF91CF911F910F9108950895DE |
||||
:100980000E94BE0D0E94BF040E943201CDEFD4E050 |
||||
:100990000E945F012097E1F30E94FD04F9CFFC0162 |
||||
:1009A000918D228D892F90E0805C9F4F821B910951 |
||||
:1009B0008F7399270895FC01918D828D981731F0DE |
||||
:1009C000828DE80FF11D858D90E008958FEF9FEFE8 |
||||
:1009D0000895FC01918D828D981761F0828DDF0161 |
||||
:1009E000A80FB11D5D968C91928D9F5F9F73928F22 |
||||
:1009F00090E008958FEF9FEF08958FE693E0892BA5 |
||||
:100A000049F080E090E0892B29F00E946F0381116A |
||||
:100A10000C9400000895FC01848DDF01A80FB11D26 |
||||
:100A2000A35ABF4F2C91848D90E001968F73992724 |
||||
:100A3000848FA689B7892C93A089B1898C91806411 |
||||
:100A40008C93938D848D981306C00288F389E02DD2 |
||||
:100A500080818F7D80830895CF93DF93EC01888D13 |
||||
:100A60008823C9F0EA89FB89808185FD05C0A889B2 |
||||
:100A7000B9898C9186FD0FC00FB607FCF5CF808138 |
||||
:100A800085FFF2CFA889B9898C9185FFEDCFCE0182 |
||||
:100A90000E940B05E7CFDF91CF910895EF92FF926F |
||||
:100AA0000F931F93CF93DF93EC0181E0888F9B8D91 |
||||
:100AB0008C8D981305C0E889F989808185FD24C053 |
||||
:100AC000F62E0B8D10E00F5F1F4F0F731127E02ED6 |
||||
:100AD0008C8DE8120CC00FB607FCFACFE889F989B3 |
||||
:100AE000808185FFF5CFCE010E940B05F1CF8B8D64 |
||||
:100AF000FE01E80FF11DE35AFF4FF0820B8FEA89E8 |
||||
:100B0000FB898081806207C0EE89FF896083E88964 |
||||
:100B1000F98980818064808381E090E0DF91CF91CA |
||||
:100B20001F910F91FF90EF900895CF92DF92EF9277 |
||||
:100B3000FF921F93CF93DF93EC016A017B01122F89 |
||||
:100B4000E889F98982E080834115514E610571057C |
||||
:100B5000B1F060E079E08DE390E0A70196010E949A |
||||
:100B6000FB0DDA01C9010197A109B109B695A79555 |
||||
:100B700097958795AC01411580E15807A8F0E88961 |
||||
:100B8000F989108260E874E88EE190E0A70196018F |
||||
:100B90000E94FB0DBA01A901415051096109710977 |
||||
:100BA0007695679557954795EC85FD855083EE853D |
||||
:100BB000FF854083188EEC89FD891083EA89FB89C3 |
||||
:100BC000808180618083EA89FB898081886080835D |
||||
:100BD000EA89FB89808180688083EA89FB8980813A |
||||
:100BE0008F7D8083DF91CF911F91FF90EF90DF90F9 |
||||
:100BF000CF900895FC011182108213821282089511 |
||||
:100C0000FC01738362830895DC011296ED91FC91DF |
||||
:100C100013973097F1F02D913C91119721153105E3 |
||||
:100C2000B1F014964D915C911597CA0195958795F1 |
||||
:100C300040FF0AC0D901A80FB91F4D915C91E40F84 |
||||
:100C4000F51F0190F081E02D820F931F0994CB01D5 |
||||
:100C500009940895FC011182108213821282089572 |
||||
:100C6000FC01738362830895DC011296ED91FC917F |
||||
:100C700013973097F1F02D913C9111972115310583 |
||||
:100C8000B1F014964D915C911597CA019595879591 |
||||
:100C900040FF0AC0D901A80FB91F4D915C91E40F24 |
||||
:100CA000F51F0190F081E02D820F931F0994CB0175 |
||||
:100CB00009940895FC0180819181892B39F481E0A8 |
||||
:100CC00022813381232B19F480E0089581E0089577 |
||||
:100CD0000F931F93CF93DF93EC0179836883198679 |
||||
:100CE00018861B861A868C01045F1F4FC8010E945C |
||||
:100CF0002A06D093F802C093F70266E878E0C801AC |
||||
:100D0000DF91CF911F910F910C943006EF92FF92DB |
||||
:100D10000F931F93CF93DF938C017B0180E290E0D0 |
||||
:100D20000E94F90DEC0180E2FE0111928A95E9F72B |
||||
:100D30006AE471E0CE010E945F02CE0106960E9435 |
||||
:100D4000FA05CE010C960E94FA05CE0142960E9449 |
||||
:100D5000FA05CE0148960E94FA05B701CE010E941D |
||||
:100D60009502F801808591859F8F8E8FD187C087EE |
||||
:100D7000CE01DF91CF911F910F91FF90EF900895D9 |
||||
:100D80000F931F93CF93DF9300D000D000D0CDB747 |
||||
:100D9000DEB78C01CE0101960E94CD02BE016F5FCD |
||||
:100DA0007F4FC8010E9486068C01CE0101960E94E9 |
||||
:100DB000F101C80126960FB6F894DEBF0FBECDBF75 |
||||
:100DC000DF91CF911F910F910895EF92FF920F93B2 |
||||
:100DD0001F93CF93DF9300D000D0CDB7DEB77C0157 |
||||
:100DE00001E010E020E030E0A9016EE170E0FC01DC |
||||
:100DF000808191810E94900BC7010C96092E000CF6 |
||||
:100E0000AA0BBB0B89839A83AB83BC8344E050E07D |
||||
:100E1000BE016F5F7F4FF701808191810E940D0CB1 |
||||
:100E2000F701808191810E943E090F900F900F90F1 |
||||
:100E30000F90DF91CF911F910F91FF90EF90089548 |
||||
:100E40002F923F924F925F926F927F928F929F92DA |
||||
:100E5000AF92BF92CF92DF92EF92FF920F931F93C8 |
||||
:100E6000CF93DF93CDB7DEB728970FB6F894DEBFE8 |
||||
:100E70000FBECDBF7C018B012DB73EB738872F83C6 |
||||
:100E800042E050E0BE016B5F7F4FC8010E94230D1E |
||||
:100E90004D805E80470132E0830E911C44E050E0BB |
||||
:100EA000B401C8010E94230D370186E0680E711C51 |
||||
:100EB00042E050E0B301C8010E94230DBE016D5F06 |
||||
:100EC0007F4FC8010E94F40C5C01D7011896CD90A9 |
||||
:100ED000DC9019972B803C80C114D10431F1F601CC |
||||
:100EE000848195818A159B0541F460817181A501FA |
||||
:100EF000C1010E942A10892B31F0D6015E96CD9057 |
||||
:100F0000DC905F97E9CFC20199278230910599F172 |
||||
:100F10000CF4A6C0039709F0D9C084E0882E912C68 |
||||
:100F2000160122E1220E311C51C0D701ED91FC9136 |
||||
:100F30008485882309F4CAC06BEF70E080819181B9 |
||||
:100F40000E94E60300E010E0F701A081B1810A15DC |
||||
:100F50001B0561F0EB81FC81E00FF11F60818D9139 |
||||
:100F60009C910E940C040F5F1F4FEECF8D919C91BE |
||||
:100F70000E941304ABC02DB63EB6BE016F5F7F4F1B |
||||
:100F8000C8010E94F40C8C0101962DB73EB7281BB6 |
||||
:100F9000390B0FB6F8943EBF0FBE2DBF8DB79EB76D |
||||
:100FA00001965C0169817A81A8010E943710F501E0 |
||||
:100FB000E00FF11F1082B501C60148960E94040699 |
||||
:100FC0000FB6F8943EBE0FBE2DBE4AC0D80114968F |
||||
:100FD000ED91FC911597828193818816990608F00E |
||||
:100FE00075C0BE016F5F7F4FC8010E94F40C49803D |
||||
:100FF0005A803201AFEF6A1A7A0AF3010190002099 |
||||
:10100000E9F731976F01C618D7085C01AC18BD0825 |
||||
:10101000C50101970E94230EF70193878287A501DE |
||||
:1010200042505109FC01E40FF51F1082F2E0CF0E8F |
||||
:10103000D11CB2016C0D7D1D0E943710B301C1019E |
||||
:101040000E940406D7011A968D919C911B970E94CD |
||||
:10105000B80EF70113861286FFEF8F1A9F0AB6CFDC |
||||
:101060000FEF10E024E630E040E050E06FE170E088 |
||||
:10107000F701808191810E94900B44E050E0B4011F |
||||
:10108000D7018D919C910E940D0C42E050E0B3017C |
||||
:10109000F701808191810E940D0CD6016D917C91A8 |
||||
:1010A000C601411002C0069601C00C960E940406BB |
||||
:1010B00040E050E060E070E0F701808191810E94A3 |
||||
:1010C0000D0CD7018D919C910E943E09EF81F8850E |
||||
:1010D0000FB6F894FEBF0FBEEDBF28960FB6F8947A |
||||
:1010E000DEBF0FBECDBFDF91CF911F910F91FF905B |
||||
:1010F000EF90DF90CF90BF90AF909F908F907F90B8 |
||||
:101100006F905F904F903F902F900895BC01809119 |
||||
:10111000F7029091F8020C9420076F927F928F92C1 |
||||
:101120009F92AF92BF92CF92DF92EF92FF920F9376 |
||||
:101130001F93CF93DF9300D0CDB7DEB74C016A0188 |
||||
:10114000ADB6BEB6CB0169837A830E9421108C01B3 |
||||
:10115000C6010E94211011279801280F311DC901D5 |
||||
:10116000390132E0630E711C0396EDB7FEB7E81B40 |
||||
:10117000F90B0FB6F894FEBF0FBEEDBF2DB73EB70B |
||||
:101180002F5F3F4F7901118269817A81C9010196F0 |
||||
:101190000E941A10C8010296B6018E0D9F1D0E9472 |
||||
:1011A0001A10A301B701F401808191810E940D0CF6 |
||||
:1011B0000FB6F894BEBE0FBEADBE0F900F90DF917C |
||||
:1011C000CF911F910F91FF90EF90DF90CF90BF9044 |
||||
:1011D000AF909F908F907F906F900895CF93DF9303 |
||||
:1011E000EC018A859B85603CA1F06B3D21F5DC011B |
||||
:1011F000ED91FC910190F081E02D6BED09958A85D0 |
||||
:101200009B85DC01ED91FC910190F081E02D6DED6D |
||||
:1012100018C0DC01ED91FC910190F081E02D6BEDA7 |
||||
:1012200009958A859B85DC01ED91FC910190F08107 |
||||
:10123000E02D6CED06C0DC01ED91FC910190F08198 |
||||
:10124000E02DDF91CF910994EF92FF920F931F93BE |
||||
:10125000CF93DF937C01EB018B01040F151FC017A7 |
||||
:10126000D10729F06991C7010E94EE08F8CFDF91FC |
||||
:10127000CF911F910F91FF90EF900895CF93DF933F |
||||
:10128000EC01BC01635F7F4F42E050E00E94240903 |
||||
:101290008A859B85DC01ED91FC910190F081E02D28 |
||||
:1012A00060ECDF91CF9109940F931F93CF93DF935D |
||||
:1012B000EC018B0102960E942A061B870A871C8676 |
||||
:1012C000CE014696988B8F8780E890E09A8B898B29 |
||||
:1012D0001C8A1B8A1D8ADF91CF911F910F9108955F |
||||
:1012E000FC012485222321F0808191810C94170434 |
||||
:1012F00008954627342F252FA901442784E0440F61 |
||||
:10130000551F8A95E1F742275327CA01892F99274C |
||||
:1013100082958F7048275927CA01882735E096950E |
||||
:1013200087953A95E1F7842795270895EF92FF92E4 |
||||
:101330000F931F93CF93DF937C01C901EB018B01C6 |
||||
:10134000040F151FC017D10731F06991AC01C70117 |
||||
:101350000E947909F7CFDF91CF911F910F91FF90F4 |
||||
:10136000EF900895AF92BF92CF92DF92EF92FF92EB |
||||
:101370000F931F93CF93DF9300D000D000D0CDB751 |
||||
:10138000DEB78C01DC011F96ED90FC9050971C9607 |
||||
:101390008C911C97882309F47DC069E671E08D91DA |
||||
:1013A0009C910E940A04F801638974894AE050E024 |
||||
:1013B000808191810E94910463E771E0D8018D9151 |
||||
:1013C0009C910E940A04F80147855089052E000C63 |
||||
:1013D000660B770B20E130E0808191810E947D04D3 |
||||
:1013E00067E971E0D8018D919C910E940A04F70190 |
||||
:1013F0006081718140E150E0D8018D919C910E9403 |
||||
:10140000910468E971E0F801808191810E940A04E9 |
||||
:10141000D70114964D915D916D917C91179720E1C4 |
||||
:1014200030E0F801808191810E947D0468E971E0DB |
||||
:10143000D8018D919C910E940A04F7016281738109 |
||||
:1014400040E150E0D8018D919C910E94910488E088 |
||||
:10145000C82ED12CF8012389348980819181C2164C |
||||
:10146000D306B0F468E971E00E940A04D8011F961F |
||||
:10147000ED91FC915097EC0DFD1D40E150E0608135 |
||||
:101480008D919C910E948A04BFEFCB1ADB0AE2CFB8 |
||||
:101490000E941304D8015396CD90DC905497B2E08B |
||||
:1014A000CB1AD108F801A784B08820E030E0A6016B |
||||
:1014B000B501C8010E949609F501EC0DFD1D2081C2 |
||||
:1014C00031818217930731F066E771E0C8010E940D |
||||
:1014D000700982C0D7018D919C918230910539F0BD |
||||
:1014E00083309105F1F0019709F06CC05BC0F80101 |
||||
:1014F0008485882309F473C067E871E08081918155 |
||||
:101500000E940A04D70114964D915D916D917C91D2 |
||||
:1015100017972AE030E0F801808191810E94AD04A4 |
||||
:101520005EC0D8011C968C911C97882329F160E934 |
||||
:1015300071E08D919C910E940A04F70144815581CC |
||||
:10154000668177812AE030E0D8018D919C910E94DC |
||||
:101550007D0468E971E0F801808191810E940A04AC |
||||
:10156000D70112966D917C9113974AE050E0F801F3 |
||||
:10157000808191810E949704D70114960D911C914E |
||||
:101580001597C8010E945A06882331F1B701CE0190 |
||||
:1015900001960E94EA0CBE016F5F7F4FC8010E9456 |
||||
:1015A00034061AC06AE971E0F801808191810E94D5 |
||||
:1015B0001704D8011896ED91FC911997309761F0B6 |
||||
:1015C00009950AC0F8018485882331F065EA71E045 |
||||
:1015D000808191810E94170480E090E001C0C701E2 |
||||
:1015E00026960FB6F894DEBF0FBECDBFDF91CF9128 |
||||
:1015F0001F910F91FF90EF90DF90CF90BF90AF9031 |
||||
:1016000008951F93CF93DF93EC0111E08A859B85AA |
||||
:10161000DC01ED91FC910480F581E02D0995892B89 |
||||
:1016200009F443C08A859B85DC01ED91FC9106801D |
||||
:10163000F781E02D09958B3D910511F41D8BE6CFC7 |
||||
:101640002B893C89803C910579F42830310520F0C4 |
||||
:10165000CE010E94B20902C080E090E01C8A1B8A81 |
||||
:101660001D8A009799F223C04D89442361F08C3D77 |
||||
:10167000910531F08D3D910529F48BED90E002C08C |
||||
:1016800080EC90E01D8A49895A892417350708F0B3 |
||||
:10169000BDCF4F855889B9016F5F7F4F7C8B6B8BB6 |
||||
:1016A000FA01E20FF31F8083B1CF80E090E0DF9179 |
||||
:1016B000CF911F9108958F929F92AF92BF92CF9238 |
||||
:1016C000DF92EF92FF920F931F93CF93DF93EC0182 |
||||
:1016D0006A017B010E94B20D4B015C010E94B20DB8 |
||||
:1016E0008B019C01081919092A093B090C151D05D4 |
||||
:1016F0002E053F0530F4CE010E94010B009771F3D7 |
||||
:1017000002C080E090E0DF91CF911F910F91FF9098 |
||||
:10171000EF90DF90CF90BF90AF909F908F90089503 |
||||
:10172000EF92FF920F931F93CF93DF93CDB7DEB766 |
||||
:1017300028970FB6F894DEBF0FBECDBF7C017A8329 |
||||
:1017400069832B833C834D835E8318870F83DC0181 |
||||
:101750001E961C921E921D971A968D919C911B9716 |
||||
:10176000DC01ED91FC910190F081E02D60EC099598 |
||||
:1017700042E050E0BE016F5F7F4FC7010E94240925 |
||||
:10178000F7012585368542E050E0BE016F5F7F4F4F |
||||
:10179000C7010E949609D7011E969C938E931D97B0 |
||||
:1017A00042E050E0BE01695F7F4FC7010E942409FB |
||||
:1017B000F7012585368542E050E0BE01695F7F4F25 |
||||
:1017C000C7010E949609D7011E969C938E931D9780 |
||||
:1017D00044E050E0BE016D5F7F4FC7010E942409C5 |
||||
:1017E000F7012585368544E050E0BE016D5F7F4FEF |
||||
:1017F000C7010E949609D7011E969C938E931D9750 |
||||
:1018000028960FB6F894DEBF0FBECDBFDF91CF9103 |
||||
:101810001F910F91FF90EF900895CF92DF92EF927A |
||||
:10182000FF920F931F93CF93DF9300D0CDB7DEB716 |
||||
:101830008C017B015A83498342E050E0BE016F5F17 |
||||
:101840007F4F0E942409F8012585368542E050E04B |
||||
:10185000BE016F5F7F4FC8010E949609F80196870D |
||||
:101860008587C980DA80CE0CDF1CEC14FD0491F072 |
||||
:10187000F7016081C8010E94EE08F8014585568590 |
||||
:10188000F70161917F01C8010E947909F8019687EB |
||||
:101890008587EBCFE980FA80F194E194F108F3E0D9 |
||||
:1018A000EF22FF24F1E0EF1AF10878F060E0C801C0 |
||||
:1018B0000E94EE08F8014585568560E0C8010E9447 |
||||
:1018C0007909F80196878587EDCF0F900F90DF910A |
||||
:1018D000CF911F910F91FF90EF90DF90CF900895DF |
||||
:1018E0004F925F926F927F92AF92BF92CF92DF92B0 |
||||
:1018F000EF92FF920F931F93CF93DF93EC012A0196 |
||||
:101900003B018A859B85DC01ED91FC910190F08182 |
||||
:10191000E02D60EC09956E01B2E0CB0ED11C0D2CD0 |
||||
:10192000000CEE08FF0800E010E0A701960161E05E |
||||
:1019300070E0CE010E94900BCE010E943E09A88467 |
||||
:10194000B98419861886B301A201CE010E945B0BEF |
||||
:101950008C01892B69F1F801448155816681778179 |
||||
:101960008C854C155D056E057F0561F4882331F08B |
||||
:101970006FE971E0888199810E941704B986A88671 |
||||
:1019800081E019C08823F9F26BEA71E088819981BE |
||||
:101990000E940A04D80114964D915D916D917C913D |
||||
:1019A00017972AE030E0888199810E94AD04CBCF5F |
||||
:1019B000B986A88680E0DF91CF911F910F91FF90AB |
||||
:1019C000EF90DF90CF90BF90AF907F906F905F903F |
||||
:1019D0004F900895FC0175836483685F7F4F738324 |
||||
:1019E0006283118210820895CF93DF93FC0180817E |
||||
:1019F0009181A481B58112962D913C911397821704 |
||||
:101A00009307E0F4A281B3814D915D91B383A283EA |
||||
:101A1000019691838083EB01B983A8832EEF3FEF7A |
||||
:101A2000241B350B23703327240F351F82819381AC |
||||
:101A3000280F391F33832283CA0102C08FEF9FEF23 |
||||
:101A4000DF91CF910895EF92FF920F931F93CF9361 |
||||
:101A5000DF93EC0188819981EC81FD8122813381C2 |
||||
:101A60008217930760F5EA81FB81019111912EEFB6 |
||||
:101A70003FEF201B310B7901A3E0EA22FF24FB8317 |
||||
:101A8000EA83019699838883CB019A01041715078D |
||||
:101A900008F49801260F371F8217930729F0419108 |
||||
:101AA000DC014D93CD01F8CF9701200F311F8A81C2 |
||||
:101AB0009B81280F391F3B832A83C80102C08FEF07 |
||||
:101AC0009FEFDF91CF911F910F91FF90EF900895BD |
||||
:101AD0001F920F920FB60F9211242F933F938F9363 |
||||
:101AE0009F93AF93BF938091FA029091FB02A091D4 |
||||
:101AF000FC02B091FD023091F90223E0230F2D3753 |
||||
:101B000020F40196A11DB11D05C026E8230F029601 |
||||
:101B1000A11DB11D2093F9028093FA029093FB025C |
||||
:101B2000A093FC02B093FD028091FE029091FF020F |
||||
:101B3000A0910003B09101030196A11DB11D8093F6 |
||||
:101B4000FE029093FF02A0930003B0930103BF91A4 |
||||
:101B5000AF919F918F913F912F910F900FBE0F905A |
||||
:101B60001F9018952FB7F8946091FA027091FB02BC |
||||
:101B70008091FC029091FD022FBF0895789484B566 |
||||
:101B8000826084BD84B5816084BD85B5826085BD79 |
||||
:101B900085B5816085BDEEE6F0E08081816080835F |
||||
:101BA000E1E8F0E010828081826080838081816042 |
||||
:101BB0008083E0E8F0E0808181608083E1EBF0E009 |
||||
:101BC000808184608083E0EBF0E0808181608083AD |
||||
:101BD000EAE7F0E080818460808380818260808396 |
||||
:101BE0008081816080838081806880831092C100C1 |
||||
:101BF00008950C94230EA1E21A2EAA1BBB1BFD0113 |
||||
:101C00000DC0AA1FBB1FEE1FFF1FA217B307E407DB |
||||
:101C1000F50720F0A21BB30BE40BF50B661F771F33 |
||||
:101C2000881F991F1A9469F7609570958095909513 |
||||
:101C30009B01AC01BD01CF010895EE0FFF1F059080 |
||||
:101C4000F491E02D0994CF93DF938230910510F445 |
||||
:101C500082E090E0E0910403F091050320E030E0A1 |
||||
:101C6000C0E0D0E0309711F1408151814817590709 |
||||
:101C7000C0F04817590761F482819381209719F0C9 |
||||
:101C80009B838A832BC0909305038093040326C013 |
||||
:101C90002115310519F04217530718F49A01BE01B6 |
||||
:101CA000DF01EF010280F381E02DDCCF211531054A |
||||
:101CB00009F1281B390B2430310590F412968D91CF |
||||
:101CC0009C9113976115710521F0FB019383828329 |
||||
:101CD00004C09093050380930403FD01329644C031 |
||||
:101CE000FD01E20FF31F81939193225031092D934F |
||||
:101CF0003C933AC02091020330910303232B41F41B |
||||
:101D000020910201309103013093030320930203D9 |
||||
:101D100020910001309101012115310541F42DB7C9 |
||||
:101D20003EB74091040150910501241B350BE09111 |
||||
:101D30000203F0910303E217F307A0F42E1B3F0BFD |
||||
:101D40002817390778F0AC014E5F5F4F241735072D |
||||
:101D500048F04E0F5F1F509303034093020381939B |
||||
:101D6000919302C0E0E0F0E0CF01DF91CF910895C0 |
||||
:101D70000F931F93CF93DF93009709F48CC0FC015E |
||||
:101D8000329713821282009104031091050301150A |
||||
:101D9000110581F420813181820F931F209102036C |
||||
:101DA000309103032817390779F5F0930303E09383 |
||||
:101DB000020371C0D80140E050E0AE17BF0750F4F5 |
||||
:101DC00012962D913C911397AD012115310509F122 |
||||
:101DD000D901F3CF9D01DA013383228360817181C0 |
||||
:101DE000860F971F8217930769F4EC0128813981C8 |
||||
:101DF000260F371F2E5F3F4F318320838A819B81BF |
||||
:101E000093838283452B29F4F0930503E093040325 |
||||
:101E100042C01396FC93EE931297ED0149915991AC |
||||
:101E20009E01240F351FE217F30771F48081918121 |
||||
:101E3000840F951F029611969C938E9382819381B5 |
||||
:101E400013969C938E931297E0E0F0E0D8011296DF |
||||
:101E50008D919C911397009719F0F8018C01F6CFA2 |
||||
:101E60008D919C9198012E5F3F4F820F931F20917F |
||||
:101E70000203309103032817390769F4309729F4D6 |
||||
:101E8000109205031092040302C013821282109371 |
||||
:101E9000030300930203DF91CF911F910F910895E7 |
||||
:101EA000A0E0B0E0E6E5FFE00C945410EC010097F0 |
||||
:101EB00021F4CB010E94230EB8C0FC01E60FF71FEE |
||||
:101EC0009C0122503109E217F30708F4ACC0D90194 |
||||
:101ED0000D911C91119706171707B0F005301105E9 |
||||
:101EE00008F49FC0C80104978617970708F499C0A3 |
||||
:101EF00002501109061B170B019311936D937C93EC |
||||
:101F0000CF010E94B80E8DC05B01A01AB10A4C012E |
||||
:101F1000800E911EA0910403B091050340E050E0B3 |
||||
:101F2000E12CF12C109709F44AC0A815B905D1F598 |
||||
:101F30006D907C901197630182E0C80ED11CCA1489 |
||||
:101F4000DB0480F1A3014A195B096A0182E0C80E33 |
||||
:101F5000D11C1296BC9012971396AC91B5E0CB169B |
||||
:101F6000D10440F0B282A38351834083D9016D93A1 |
||||
:101F70007C930AC00E5F1F4FC301800F911FF901B0 |
||||
:101F800091838083EB2DFA2FE114F10431F0D70116 |
||||
:101F90001396FC93EE93129744C0F0930503E093DD |
||||
:101FA00004033FC08D919C9111974817590708F47D |
||||
:101FB000AC017D0112960D90BC91A02DB3CF809104 |
||||
:101FC00002039091030388159905E1F4461757071A |
||||
:101FD000C8F48091000190910101009741F48DB700 |
||||
:101FE0009EB74091040150910501841B950BE817A1 |
||||
:101FF000F907C8F4F0930303E0930203F901718336 |
||||
:1020000060830FC0CB010E94230E7C01009759F022 |
||||
:10201000A801BE010E943710CE010E94B80EC70170 |
||||
:1020200004C0CE0102C080E090E0CDB7DEB7EEE0A4 |
||||
:102030000C947010FB01DC0105900D920020E1F77B |
||||
:102040000895FC0105900020E9F7809590958E0F8A |
||||
:102050009F1F0895FB01DC0104C08D910190801940 |
||||
:1020600021F441505040C8F7881B990B0895FB019B |
||||
:10207000DC0102C001900D9241505040D8F7089504 |
||||
:10208000FB01DC018D91019080190110D9F3990BAE |
||||
:102090000895FB01DC0101900D920020E1F7089505 |
||||
:1020A0002F923F924F925F926F927F928F929F9268 |
||||
:1020B000AF92BF92CF92DF92EF92FF920F931F9356 |
||||
:1020C000CF93DF93CDB7DEB7CA1BDB0B0FB6F89407 |
||||
:1020D000DEBF0FBECDBF09942A88398848885F8447 |
||||
:1020E0006E847D848C849B84AA84B984C884DF80B8 |
||||
:1020F000EE80FD800C811B81AA81B981CE0FD11D9C |
||||
:102100000FB6F894DEBF0FBECDBFED010895F89471 |
||||
:02211000FFCFFF |
||||
:10211200000006038000454C2D436C69656E7420F7 |
||||
:102122002872652D297374617274696E6721004586 |
||||
:102132004C2D436C69656E742073796E6320666101 |
||||
:10214200696C65642100454C2D436C69656E742091 |
||||
:1021520073796E63656421000D0A006E616E006919 |
||||
:102162006E66006F7666002E00000000004E05A627 |
||||
:1021720003CF04E904DB042C05454C433A20676F86 |
||||
:10218200742000204000454C433A20496E76616C31 |
||||
:1021920069642043524300524553505F563A20002F |
||||
:1021A200524553505F43423A20004E4545445F53E7 |
||||
:1021B200594E432100434D443F3F004241443A209F |
||||
:0221C20000001B |
||||
:00000001FF |
||||
@ -0,0 +1,77 @@
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* Simple example for LED flashing using web-server |
||||
*
|
||||
* Test board: |
||||
* ESP8266 RX <--level shifter--> Arduino TX |
||||
* ESP8266 TX <--level shifter--> Arduino RX |
||||
* ESP8266 GPIO0 <--level shifter--> Arduino RESET (optional) |
||||
*
|
||||
* Arduino LED is on PIN 13 |
||||
*
|
||||
* Video: |
||||
* https://www.youtube.com/watch?v=vBESCO0UhYI
|
||||
*/ |
||||
|
||||
#include <ELClient.h> |
||||
#include <ELClientWebServer.h> |
||||
|
||||
// flash LED on PIN 13
|
||||
#define LED_PIN 13 |
||||
|
||||
// Initialize a connection to esp-link using the normal hardware serial port
|
||||
//
|
||||
// DEBUG is disasbled as
|
||||
// - packet logging is slow and UART receive buffer can overrun (HTML form submission)
|
||||
ELClient esp(&Serial); |
||||
|
||||
// Initialize the Web-Server client
|
||||
ELClientWebServer webServer(&esp); |
||||
|
||||
void ledPageLoadAndRefreshCb(char * url) |
||||
{ |
||||
if( digitalRead(LED_PIN) ) |
||||
webServer.setArgString(F("text"), F("LED is on")); |
||||
else |
||||
webServer.setArgString(F("text"), F("LED is off")); |
||||
} |
||||
|
||||
void ledButtonPressCb(char * btnId) |
||||
{ |
||||
String id = btnId; |
||||
if( id == F("btn_on") ) |
||||
digitalWrite(LED_PIN, true); |
||||
else if( id == F("btn_off") ) |
||||
digitalWrite(LED_PIN, false); |
||||
} |
||||
|
||||
// Callback made form esp-link to notify that it has just come out of a reset. This means we
|
||||
// need to initialize it!
|
||||
void resetCb(void) { |
||||
Serial.println("EL-Client (re-)starting!"); |
||||
bool ok = false; |
||||
do { |
||||
ok = esp.Sync(); // sync up with esp-link, blocks for up to 2 seconds
|
||||
if (!ok) Serial.println("EL-Client sync failed!"); |
||||
} while(!ok); |
||||
Serial.println("EL-Client synced!"); |
||||
|
||||
webServer.setup(); |
||||
} |
||||
|
||||
void setup() |
||||
{ |
||||
Serial.begin(115200); |
||||
|
||||
URLHandler *ledHandler = webServer.createURLHandler(F("/SimpleLED.html.json")); |
||||
ledHandler->loadCb.attach(&ledPageLoadAndRefreshCb); |
||||
ledHandler->refreshCb.attach(&ledPageLoadAndRefreshCb); |
||||
ledHandler->buttonCb.attach(&ledButtonPressCb); |
||||
|
||||
esp.resetCb = resetCb; |
||||
resetCb(); |
||||
} |
||||
|
||||
void loop() |
||||
{ |
||||
esp.Process(); |
||||
} |
||||
@ -0,0 +1,18 @@
@@ -0,0 +1,18 @@
|
||||
{ |
||||
"name": "ELClient", |
||||
"keywords": "wifi, mqtt, rest, socket", |
||||
"description": "Wifi library (Chip ESP8266 Wifi SoC) using SLIP protocol via Serial port", |
||||
"url": "https://github.com/jeelabs/esp-link", |
||||
"repository": |
||||
{ |
||||
"type": "git", |
||||
"url": "https://github.com/jeelabs/esp-link" |
||||
}, |
||||
"include": "ELClient", |
||||
"frameworks": "arduino", |
||||
"platforms": [ |
||||
"atmelavr", |
||||
"atmelsam", |
||||
"teensy" |
||||
] |
||||
} |
||||
@ -0,0 +1,17 @@
@@ -0,0 +1,17 @@
|
||||
# Auto detect text files and perform LF normalization |
||||
* text=auto |
||||
|
||||
# Custom for Visual Studio |
||||
*.cs diff=csharp |
||||
|
||||
# Standard to msysgit |
||||
*.doc diff=astextplain |
||||
*.DOC diff=astextplain |
||||
*.docx diff=astextplain |
||||
*.DOCX diff=astextplain |
||||
*.dot diff=astextplain |
||||
*.DOT diff=astextplain |
||||
*.pdf diff=astextplain |
||||
*.PDF diff=astextplain |
||||
*.rtf diff=astextplain |
||||
*.RTF diff=astextplain |
||||
@ -0,0 +1,34 @@
@@ -0,0 +1,34 @@
|
||||
--- |
||||
name: Bug report |
||||
about: Create a report to help us improve |
||||
|
||||
--- |
||||
|
||||
**NOTE: If you are seeking help or have questions, this is NOT the place to do it.** For questions and support, jump on Gitter and ask away. |
||||
[](https://gitter.im/Makuna/Rtc?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) |
||||
|
||||
**Describe the bug** |
||||
A clear and concise description of what the bug is. |
||||
|
||||
**To Reproduce** |
||||
Steps to reproduce the behavior: |
||||
1. Go to '...' |
||||
2. Click on '....' |
||||
3. Scroll down to '....' |
||||
4. See error |
||||
|
||||
**Expected behavior** |
||||
A clear and concise description of what you expected to happen. |
||||
|
||||
**Development environment (please complete the following information):** |
||||
- OS: [e.g. Win10] |
||||
- Build Environment [e.g. Arduino IDE v.1.8.10] |
||||
- Board target [e.g. AVR Mege 2560, v 1.10.31 ] - you will need to check the board manager for this. |
||||
- Library version [e.g. v2.3.4] - you will need to check the library manager for this. If you used github to clone it, mention this and include the reference. |
||||
|
||||
**Minimal Sketch that reproduced the problem:** |
||||
If an example will demonstrate the problem, list which example you used. |
||||
If its your sketch, take the time to remove unneeded parts and minimize it to the smallest sketch that reproduces the problem. Then include the sketch here using `code` markup. Start with a line with three single left quotes and then end with a line with three single left quotes. |
||||
|
||||
**Additional context** |
||||
Add any other context about the problem here. |
||||
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
--- |
||||
name: Feature request |
||||
about: Suggest an idea for this project |
||||
|
||||
--- |
||||
|
||||
**NOTE: If you are seeking help or have questions, this is NOT the place to do it.** For questions and support, jump on Gitter and ask away. |
||||
[](https://gitter.im/Makuna/Rtc?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) |
||||
|
||||
**Is your feature request related to a problem? Please describe.** |
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] |
||||
|
||||
**Describe the solution you'd like** |
||||
A clear and concise description of what you want to happen. |
||||
|
||||
**Describe alternatives you've considered** |
||||
A clear and concise description of any alternative solutions or features you've considered. |
||||
|
||||
**Additional context** |
||||
Add any other context or screenshots about the feature request here. |
||||
@ -0,0 +1,43 @@
@@ -0,0 +1,43 @@
|
||||
# Windows image file caches |
||||
Thumbs.db |
||||
ehthumbs.db |
||||
|
||||
# Folder config file |
||||
Desktop.ini |
||||
|
||||
# Recycle Bin used on file shares |
||||
$RECYCLE.BIN/ |
||||
|
||||
# Windows Installer files |
||||
*.cab |
||||
*.msi |
||||
*.msm |
||||
*.msp |
||||
|
||||
# Windows shortcuts |
||||
*.lnk |
||||
|
||||
# ========================= |
||||
# Operating System Files |
||||
# ========================= |
||||
|
||||
# OSX |
||||
# ========================= |
||||
|
||||
.DS_Store |
||||
.AppleDouble |
||||
.LSOverride |
||||
|
||||
# Thumbnails |
||||
._* |
||||
|
||||
# Files that might appear on external disk |
||||
.Spotlight-V100 |
||||
.Trashes |
||||
|
||||
# Directories potentially created on remote AFP share |
||||
.AppleDB |
||||
.AppleDesktop |
||||
Network Trash Folder |
||||
Temporary Items |
||||
.apdisk |
||||
@ -0,0 +1,165 @@
@@ -0,0 +1,165 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE |
||||
Version 3, 29 June 2007 |
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> |
||||
Everyone is permitted to copy and distribute verbatim copies |
||||
of this license document, but changing it is not allowed. |
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates |
||||
the terms and conditions of version 3 of the GNU General Public |
||||
License, supplemented by the additional permissions listed below. |
||||
|
||||
0. Additional Definitions. |
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser |
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU |
||||
General Public License. |
||||
|
||||
"The Library" refers to a covered work governed by this License, |
||||
other than an Application or a Combined Work as defined below. |
||||
|
||||
An "Application" is any work that makes use of an interface provided |
||||
by the Library, but which is not otherwise based on the Library. |
||||
Defining a subclass of a class defined by the Library is deemed a mode |
||||
of using an interface provided by the Library. |
||||
|
||||
A "Combined Work" is a work produced by combining or linking an |
||||
Application with the Library. The particular version of the Library |
||||
with which the Combined Work was made is also called the "Linked |
||||
Version". |
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the |
||||
Corresponding Source for the Combined Work, excluding any source code |
||||
for portions of the Combined Work that, considered in isolation, are |
||||
based on the Application, and not on the Linked Version. |
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the |
||||
object code and/or source code for the Application, including any data |
||||
and utility programs needed for reproducing the Combined Work from the |
||||
Application, but excluding the System Libraries of the Combined Work. |
||||
|
||||
1. Exception to Section 3 of the GNU GPL. |
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License |
||||
without being bound by section 3 of the GNU GPL. |
||||
|
||||
2. Conveying Modified Versions. |
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a |
||||
facility refers to a function or data to be supplied by an Application |
||||
that uses the facility (other than as an argument passed when the |
||||
facility is invoked), then you may convey a copy of the modified |
||||
version: |
||||
|
||||
a) under this License, provided that you make a good faith effort to |
||||
ensure that, in the event an Application does not supply the |
||||
function or data, the facility still operates, and performs |
||||
whatever part of its purpose remains meaningful, or |
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of |
||||
this License applicable to that copy. |
||||
|
||||
3. Object Code Incorporating Material from Library Header Files. |
||||
|
||||
The object code form of an Application may incorporate material from |
||||
a header file that is part of the Library. You may convey such object |
||||
code under terms of your choice, provided that, if the incorporated |
||||
material is not limited to numerical parameters, data structure |
||||
layouts and accessors, or small macros, inline functions and templates |
||||
(ten or fewer lines in length), you do both of the following: |
||||
|
||||
a) Give prominent notice with each copy of the object code that the |
||||
Library is used in it and that the Library and its use are |
||||
covered by this License. |
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license |
||||
document. |
||||
|
||||
4. Combined Works. |
||||
|
||||
You may convey a Combined Work under terms of your choice that, |
||||
taken together, effectively do not restrict modification of the |
||||
portions of the Library contained in the Combined Work and reverse |
||||
engineering for debugging such modifications, if you also do each of |
||||
the following: |
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that |
||||
the Library is used in it and that the Library and its use are |
||||
covered by this License. |
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license |
||||
document. |
||||
|
||||
c) For a Combined Work that displays copyright notices during |
||||
execution, include the copyright notice for the Library among |
||||
these notices, as well as a reference directing the user to the |
||||
copies of the GNU GPL and this license document. |
||||
|
||||
d) Do one of the following: |
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this |
||||
License, and the Corresponding Application Code in a form |
||||
suitable for, and under terms that permit, the user to |
||||
recombine or relink the Application with a modified version of |
||||
the Linked Version to produce a modified Combined Work, in the |
||||
manner specified by section 6 of the GNU GPL for conveying |
||||
Corresponding Source. |
||||
|
||||
1) Use a suitable shared library mechanism for linking with the |
||||
Library. A suitable mechanism is one that (a) uses at run time |
||||
a copy of the Library already present on the user's computer |
||||
system, and (b) will operate properly with a modified version |
||||
of the Library that is interface-compatible with the Linked |
||||
Version. |
||||
|
||||
e) Provide Installation Information, but only if you would otherwise |
||||
be required to provide such information under section 6 of the |
||||
GNU GPL, and only to the extent that such information is |
||||
necessary to install and execute a modified version of the |
||||
Combined Work produced by recombining or relinking the |
||||
Application with a modified version of the Linked Version. (If |
||||
you use option 4d0, the Installation Information must accompany |
||||
the Minimal Corresponding Source and Corresponding Application |
||||
Code. If you use option 4d1, you must provide the Installation |
||||
Information in the manner specified by section 6 of the GNU GPL |
||||
for conveying Corresponding Source.) |
||||
|
||||
5. Combined Libraries. |
||||
|
||||
You may place library facilities that are a work based on the |
||||
Library side by side in a single library together with other library |
||||
facilities that are not Applications and are not covered by this |
||||
License, and convey such a combined library under terms of your |
||||
choice, if you do both of the following: |
||||
|
||||
a) Accompany the combined library with a copy of the same work based |
||||
on the Library, uncombined with any other library facilities, |
||||
conveyed under the terms of this License. |
||||
|
||||
b) Give prominent notice with the combined library that part of it |
||||
is a work based on the Library, and explaining where to find the |
||||
accompanying uncombined form of the same work. |
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License. |
||||
|
||||
The Free Software Foundation may publish revised and/or new versions |
||||
of the GNU Lesser General Public License from time to time. Such new |
||||
versions will be similar in spirit to the present version, but may |
||||
differ in detail to address new problems or concerns. |
||||
|
||||
Each version is given a distinguishing version number. If the |
||||
Library as you received it specifies that a certain numbered version |
||||
of the GNU Lesser General Public License "or any later version" |
||||
applies to it, you have the option of following the terms and |
||||
conditions either of that published version or of any later version |
||||
published by the Free Software Foundation. If the Library as you |
||||
received it does not specify a version number of the GNU Lesser |
||||
General Public License, you may choose any version of the GNU Lesser |
||||
General Public License ever published by the Free Software Foundation. |
||||
|
||||
If the Library as you received it specifies that a proxy can decide |
||||
whether future versions of the GNU Lesser General Public License shall |
||||
apply, that proxy's public statement of acceptance of any version is |
||||
permanent authorization for you to choose that version for the |
||||
Library. |
||||
@ -0,0 +1,22 @@
@@ -0,0 +1,22 @@
|
||||
# Rtc |
||||
|
||||
Arduino Real Time Clock library. |
||||
An RTC library with deep device support. |
||||
|
||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6AA97KE54UJR4) |
||||
|
||||
For quick questions jump on Gitter and ask away. |
||||
[](https://gitter.im/Makuna/Rtc?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) |
||||
|
||||
For bugs, make sure there isn't an active issue and then create one. |
||||
|
||||
## Documentation |
||||
[See Wiki](https://github.com/Makuna/Rtc/wiki) |
||||
|
||||
## Installing This Library (prefered, you just want to use it) |
||||
Open the Library Manager and search for "Rtc by Makuna" and install |
||||
|
||||
## Installing This Library From GitHub (advanced, you want to contribute) |
||||
Create a directory in your Arduino\Library folder named "Rtc" |
||||
Clone (Git) this project into that folder. |
||||
It should now show up in the import list when you restart Arduino IDE. |
||||
@ -0,0 +1,8 @@
@@ -0,0 +1,8 @@
|
||||
# Support |
||||
|
||||
For questions and help, jump on Gitter and ask away. |
||||
[](https://gitter.im/Makuna/Rtc?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) |
||||
|
||||
For documentation [See the Wiki](https://github.com/Makuna/Rtc/wiki) |
||||
|
||||
For bugs, make sure there isn't an active issue and then create one. Understand that issues are for bugs found in the library and not issues you are having with the library. |
||||
@ -0,0 +1,135 @@
@@ -0,0 +1,135 @@
|
||||
|
||||
// CONNECTIONS:
|
||||
// DS1302 CLK/SCLK --> 5
|
||||
// DS1302 DAT/IO --> 4
|
||||
// DS1302 RST/CE --> 2
|
||||
// DS1302 VCC --> 3.3v - 5v
|
||||
// DS1302 GND --> GND
|
||||
|
||||
#include <ThreeWire.h> |
||||
#include <RtcDS1302.h> |
||||
|
||||
ThreeWire myWire(4,5,2); // IO, SCLK, CE
|
||||
RtcDS1302<ThreeWire> Rtc(myWire); |
||||
|
||||
#define countof(a) (sizeof(a) / sizeof(a[0])) |
||||
|
||||
const char data[] = "what time is it"; |
||||
|
||||
void setup ()
|
||||
{ |
||||
Serial.begin(57600); |
||||
|
||||
Serial.print("compiled: "); |
||||
Serial.print(__DATE__); |
||||
Serial.println(__TIME__); |
||||
|
||||
Rtc.Begin(); |
||||
|
||||
RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__); |
||||
printDateTime(compiled); |
||||
Serial.println(); |
||||
|
||||
if (!Rtc.IsDateTimeValid())
|
||||
{ |
||||
Serial.println("RTC lost confidence in the DateTime!"); |
||||
Rtc.SetDateTime(compiled); |
||||
} |
||||
|
||||
if (Rtc.GetIsWriteProtected()) |
||||
{ |
||||
Serial.println("RTC was write protected, enabling writing now"); |
||||
Rtc.SetIsWriteProtected(false); |
||||
} |
||||
|
||||
if (!Rtc.GetIsRunning()) |
||||
{ |
||||
Serial.println("RTC was not actively running, starting now"); |
||||
Rtc.SetIsRunning(true); |
||||
} |
||||
|
||||
RtcDateTime now = Rtc.GetDateTime(); |
||||
if (now < compiled)
|
||||
{ |
||||
Serial.println("RTC is older than compile time! (Updating DateTime)"); |
||||
Rtc.SetDateTime(compiled); |
||||
} |
||||
|
||||
|
||||
/* comment out on a second run to see that the info is stored long term */ |
||||
// Store something in memory on the RTC
|
||||
uint8_t count = sizeof(data); |
||||
uint8_t written = Rtc.SetMemory((const uint8_t*)data, count); // this includes a null terminator for the string
|
||||
if (written != count)
|
||||
{ |
||||
Serial.print("something didn't match, count = "); |
||||
Serial.print(count, DEC); |
||||
Serial.print(", written = "); |
||||
Serial.print(written, DEC); |
||||
Serial.println(); |
||||
} |
||||
/* end of comment out section */ |
||||
} |
||||
|
||||
void loop ()
|
||||
{ |
||||
RtcDateTime now = Rtc.GetDateTime(); |
||||
|
||||
printDateTime(now); |
||||
Serial.println(" +"); |
||||
|
||||
if (!now.IsValid()) |
||||
{ |
||||
// Common Causes:
|
||||
// 1) the battery on the device is low or even missing and the power line was disconnected
|
||||
Serial.println("RTC lost confidence in the DateTime!"); |
||||
} |
||||
|
||||
delay(5000); |
||||
|
||||
// read data
|
||||
uint8_t buff[20]; |
||||
const uint8_t count = sizeof(buff); |
||||
// get our data
|
||||
uint8_t gotten = Rtc.GetMemory(buff, count); |
||||
|
||||
if (gotten != count)
|
||||
{ |
||||
Serial.print("something didn't match, count = "); |
||||
Serial.print(count, DEC); |
||||
Serial.print(", gotten = "); |
||||
Serial.print(gotten, DEC); |
||||
Serial.println(); |
||||
} |
||||
|
||||
Serial.print("data read ("); |
||||
Serial.print(gotten); |
||||
Serial.print(") = \""); |
||||
// print the string, but terminate if we get a null
|
||||
for (uint8_t ch = 0; ch < gotten && buff[ch]; ch++) |
||||
{ |
||||
Serial.print((char)buff[ch]); |
||||
} |
||||
Serial.println("\""); |
||||
|
||||
delay(5000); |
||||
} |
||||
|
||||
|
||||
|
||||
void printDateTime(const RtcDateTime& dt) |
||||
{ |
||||
char datestring[20]; |
||||
|
||||
snprintf_P(datestring,
|
||||
countof(datestring), |
||||
PSTR("%02u/%02u/%04u %02u:%02u:%02u"), |
||||
dt.Month(), |
||||
dt.Day(), |
||||
dt.Year(), |
||||
dt.Hour(), |
||||
dt.Minute(), |
||||
dt.Second() ); |
||||
Serial.print(datestring); |
||||
} |
||||
|
||||
@ -0,0 +1,101 @@
@@ -0,0 +1,101 @@
|
||||
|
||||
// CONNECTIONS:
|
||||
// DS1302 CLK/SCLK --> 5
|
||||
// DS1302 DAT/IO --> 4
|
||||
// DS1302 RST/CE --> 2
|
||||
// DS1302 VCC --> 3.3v - 5v
|
||||
// DS1302 GND --> GND
|
||||
|
||||
#include <ThreeWire.h> |
||||
#include <RtcDS1302.h> |
||||
|
||||
ThreeWire myWire(4,5,2); // IO, SCLK, CE
|
||||
RtcDS1302<ThreeWire> Rtc(myWire); |
||||
|
||||
void setup ()
|
||||
{ |
||||
Serial.begin(57600); |
||||
|
||||
Serial.print("compiled: "); |
||||
Serial.print(__DATE__); |
||||
Serial.println(__TIME__); |
||||
|
||||
Rtc.Begin(); |
||||
|
||||
RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__); |
||||
printDateTime(compiled); |
||||
Serial.println(); |
||||
|
||||
if (!Rtc.IsDateTimeValid())
|
||||
{ |
||||
// Common Causes:
|
||||
// 1) first time you ran and the device wasn't running yet
|
||||
// 2) the battery on the device is low or even missing
|
||||
|
||||
Serial.println("RTC lost confidence in the DateTime!"); |
||||
Rtc.SetDateTime(compiled); |
||||
} |
||||
|
||||
if (Rtc.GetIsWriteProtected()) |
||||
{ |
||||
Serial.println("RTC was write protected, enabling writing now"); |
||||
Rtc.SetIsWriteProtected(false); |
||||
} |
||||
|
||||
if (!Rtc.GetIsRunning()) |
||||
{ |
||||
Serial.println("RTC was not actively running, starting now"); |
||||
Rtc.SetIsRunning(true); |
||||
} |
||||
|
||||
RtcDateTime now = Rtc.GetDateTime(); |
||||
if (now < compiled)
|
||||
{ |
||||
Serial.println("RTC is older than compile time! (Updating DateTime)"); |
||||
Rtc.SetDateTime(compiled); |
||||
} |
||||
else if (now > compiled)
|
||||
{ |
||||
Serial.println("RTC is newer than compile time. (this is expected)"); |
||||
} |
||||
else if (now == compiled)
|
||||
{ |
||||
Serial.println("RTC is the same as compile time! (not expected but all is fine)"); |
||||
} |
||||
} |
||||
|
||||
void loop ()
|
||||
{ |
||||
RtcDateTime now = Rtc.GetDateTime(); |
||||
|
||||
printDateTime(now); |
||||
Serial.println(); |
||||
|
||||
if (!now.IsValid()) |
||||
{ |
||||
// Common Causes:
|
||||
// 1) the battery on the device is low or even missing and the power line was disconnected
|
||||
Serial.println("RTC lost confidence in the DateTime!"); |
||||
} |
||||
|
||||
delay(10000); // ten seconds
|
||||
} |
||||
|
||||
#define countof(a) (sizeof(a) / sizeof(a[0])) |
||||
|
||||
void printDateTime(const RtcDateTime& dt) |
||||
{ |
||||
char datestring[20]; |
||||
|
||||
snprintf_P(datestring,
|
||||
countof(datestring), |
||||
PSTR("%02u/%02u/%04u %02u:%02u:%02u"), |
||||
dt.Month(), |
||||
dt.Day(), |
||||
dt.Year(), |
||||
dt.Hour(), |
||||
dt.Minute(), |
||||
dt.Second() ); |
||||
Serial.print(datestring); |
||||
} |
||||
|
||||
@ -0,0 +1,172 @@
@@ -0,0 +1,172 @@
|
||||
|
||||
// CONNECTIONS:
|
||||
// DS1307 SDA --> SDA
|
||||
// DS1307 SCL --> SCL
|
||||
// DS1307 VCC --> 5v
|
||||
// DS1307 GND --> GND
|
||||
|
||||
#define countof(a) (sizeof(a) / sizeof(a[0])) |
||||
|
||||
/* for software wire use below
|
||||
#include <SoftwareWire.h> // must be included here so that Arduino library object file references work |
||||
#include <RtcDS1307.h> |
||||
|
||||
SoftwareWire myWire(SDA, SCL); |
||||
RtcDS1307<SoftwareWire> Rtc(myWire); |
||||
for software wire use above */ |
||||
|
||||
/* for normal hardware wire use below */ |
||||
#include <Wire.h> // must be included here so that Arduino library object file references work |
||||
#include <RtcDS1307.h> |
||||
RtcDS1307<TwoWire> Rtc(Wire); |
||||
/* for normal hardware wire use above */ |
||||
|
||||
|
||||
const char data[] = "what time is it"; |
||||
|
||||
void setup ()
|
||||
{ |
||||
Serial.begin(57600); |
||||
|
||||
Serial.print("compiled: "); |
||||
Serial.print(__DATE__); |
||||
Serial.println(__TIME__); |
||||
|
||||
//--------RTC SETUP ------------
|
||||
// if you are using ESP-01 then uncomment the line below to reset the pins to
|
||||
// the available pins for SDA, SCL
|
||||
// Wire.begin(0, 2); // due to limited pins, use pin 0 and 2 for SDA, SCL
|
||||
|
||||
Rtc.Begin(); |
||||
|
||||
RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__); |
||||
printDateTime(compiled); |
||||
Serial.println(); |
||||
|
||||
if (!Rtc.IsDateTimeValid())
|
||||
{ |
||||
if (Rtc.LastError() != 0) |
||||
{ |
||||
// we have a communications error
|
||||
// see https://www.arduino.cc/en/Reference/WireEndTransmission for
|
||||
// what the number means
|
||||
Serial.print("RTC communications error = "); |
||||
Serial.println(Rtc.LastError()); |
||||
} |
||||
else |
||||
{ |
||||
Serial.println("RTC lost confidence in the DateTime!"); |
||||
Rtc.SetDateTime(compiled); |
||||
} |
||||
} |
||||
|
||||
if (!Rtc.GetIsRunning()) |
||||
{ |
||||
Serial.println("RTC was not actively running, starting now"); |
||||
Rtc.SetIsRunning(true); |
||||
} |
||||
|
||||
RtcDateTime now = Rtc.GetDateTime(); |
||||
if (now < compiled)
|
||||
{ |
||||
Serial.println("RTC is older than compile time! (Updating DateTime)"); |
||||
Rtc.SetDateTime(compiled); |
||||
} |
||||
|
||||
// never assume the Rtc was last configured by you, so
|
||||
// just clear them to your needed state
|
||||
Rtc.SetSquareWavePin(DS1307SquareWaveOut_Low);
|
||||
|
||||
/* comment out on a second run to see that the info is stored long term */ |
||||
// Store something in memory on the RTC
|
||||
Rtc.SetMemory(0, 13); |
||||
uint8_t written = Rtc.SetMemory(13, (const uint8_t*)data, sizeof(data) - 1); // remove the null terminator strings add
|
||||
Rtc.SetMemory(1, written); |
||||
/* end of comment out section */ |
||||
} |
||||
|
||||
void loop ()
|
||||
{ |
||||
if (!Rtc.IsDateTimeValid())
|
||||
{ |
||||
if (Rtc.LastError() != 0) |
||||
{ |
||||
// we have a communications error
|
||||
// see https://www.arduino.cc/en/Reference/WireEndTransmission for
|
||||
// what the number means
|
||||
Serial.print("RTC communications error = "); |
||||
Serial.println(Rtc.LastError()); |
||||
} |
||||
else |
||||
{ |
||||
// Common Causes:
|
||||
// 1) the battery on the device is low or even missing and the power line was disconnected
|
||||
Serial.println("RTC lost confidence in the DateTime!"); |
||||
} |
||||
} |
||||
|
||||
RtcDateTime now = Rtc.GetDateTime(); |
||||
|
||||
printDateTime(now); |
||||
Serial.println(); |
||||
|
||||
delay(5000); |
||||
|
||||
// read data
|
||||
|
||||
// get the offset we stored our data from address zero
|
||||
uint8_t address = Rtc.GetMemory(0); |
||||
if (address != 13) |
||||
{ |
||||
Serial.println("address didn't match"); |
||||
} |
||||
else |
||||
{ |
||||
// get the size of the data from address 1
|
||||
uint8_t count = Rtc.GetMemory(1); |
||||
uint8_t buff[20]; |
||||
|
||||
// get our data from the address with the given size
|
||||
uint8_t gotten = Rtc.GetMemory(address, buff, count); |
||||
|
||||
if (gotten != count || |
||||
count != sizeof(data) - 1) // remove the extra null terminator strings add
|
||||
{ |
||||
Serial.print("something didn't match, count = "); |
||||
Serial.print(count, DEC); |
||||
Serial.print(", gotten = "); |
||||
Serial.print(gotten, DEC); |
||||
Serial.println(); |
||||
} |
||||
Serial.print("data read ("); |
||||
Serial.print(gotten); |
||||
Serial.print(") = \""); |
||||
for (uint8_t ch = 0; ch < gotten; ch++) |
||||
{ |
||||
Serial.print((char)buff[ch]); |
||||
} |
||||
Serial.println("\""); |
||||
} |
||||
|
||||
|
||||
delay(5000); |
||||
} |
||||
|
||||
|
||||
|
||||
void printDateTime(const RtcDateTime& dt) |
||||
{ |
||||
char datestring[20]; |
||||
|
||||
snprintf_P(datestring,
|
||||
countof(datestring), |
||||
PSTR("%02u/%02u/%04u %02u:%02u:%02u"), |
||||
dt.Month(), |
||||
dt.Day(), |
||||
dt.Year(), |
||||
dt.Hour(), |
||||
dt.Minute(), |
||||
dt.Second() ); |
||||
Serial.print(datestring); |
||||
} |
||||
|
||||
@ -0,0 +1,137 @@
@@ -0,0 +1,137 @@
|
||||
|
||||
// CONNECTIONS:
|
||||
// DS1307 SDA --> SDA
|
||||
// DS1307 SCL --> SCL
|
||||
// DS1307 VCC --> 5v
|
||||
// DS1307 GND --> GND
|
||||
|
||||
/* for software wire use below
|
||||
#include <SoftwareWire.h> // must be included here so that Arduino library object file references work |
||||
#include <RtcDS1307.h> |
||||
|
||||
SoftwareWire myWire(SDA, SCL); |
||||
RtcDS1307<SoftwareWire> Rtc(myWire); |
||||
for software wire use above */ |
||||
|
||||
/* for normal hardware wire use below */ |
||||
#include <Wire.h> // must be included here so that Arduino library object file references work |
||||
#include <RtcDS1307.h> |
||||
RtcDS1307<TwoWire> Rtc(Wire); |
||||
/* for normal hardware wire use above */ |
||||
|
||||
void setup ()
|
||||
{ |
||||
Serial.begin(57600); |
||||
|
||||
Serial.print("compiled: "); |
||||
Serial.print(__DATE__); |
||||
Serial.println(__TIME__); |
||||
|
||||
//--------RTC SETUP ------------
|
||||
// if you are using ESP-01 then uncomment the line below to reset the pins to
|
||||
// the available pins for SDA, SCL
|
||||
// Wire.begin(0, 2); // due to limited pins, use pin 0 and 2 for SDA, SCL
|
||||
|
||||
Rtc.Begin(); |
||||
|
||||
RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__); |
||||
printDateTime(compiled); |
||||
Serial.println(); |
||||
|
||||
if (!Rtc.IsDateTimeValid())
|
||||
{ |
||||
if (Rtc.LastError() != 0) |
||||
{ |
||||
// we have a communications error
|
||||
// see https://www.arduino.cc/en/Reference/WireEndTransmission for
|
||||
// what the number means
|
||||
Serial.print("RTC communications error = "); |
||||
Serial.println(Rtc.LastError()); |
||||
} |
||||
else |
||||
{ |
||||
// Common Causes:
|
||||
// 1) first time you ran and the device wasn't running yet
|
||||
// 2) the battery on the device is low or even missing
|
||||
|
||||
Serial.println("RTC lost confidence in the DateTime!"); |
||||
// following line sets the RTC to the date & time this sketch was compiled
|
||||
// it will also reset the valid flag internally unless the Rtc device is
|
||||
// having an issue
|
||||
|
||||
Rtc.SetDateTime(compiled); |
||||
} |
||||
} |
||||
|
||||
if (!Rtc.GetIsRunning()) |
||||
{ |
||||
Serial.println("RTC was not actively running, starting now"); |
||||
Rtc.SetIsRunning(true); |
||||
} |
||||
|
||||
RtcDateTime now = Rtc.GetDateTime(); |
||||
if (now < compiled)
|
||||
{ |
||||
Serial.println("RTC is older than compile time! (Updating DateTime)"); |
||||
Rtc.SetDateTime(compiled); |
||||
} |
||||
else if (now > compiled)
|
||||
{ |
||||
Serial.println("RTC is newer than compile time. (this is expected)"); |
||||
} |
||||
else if (now == compiled)
|
||||
{ |
||||
Serial.println("RTC is the same as compile time! (not expected but all is fine)"); |
||||
} |
||||
|
||||
// never assume the Rtc was last configured by you, so
|
||||
// just clear them to your needed state
|
||||
Rtc.SetSquareWavePin(DS1307SquareWaveOut_Low);
|
||||
} |
||||
|
||||
void loop ()
|
||||
{ |
||||
if (!Rtc.IsDateTimeValid())
|
||||
{ |
||||
if (Rtc.LastError() != 0) |
||||
{ |
||||
// we have a communications error
|
||||
// see https://www.arduino.cc/en/Reference/WireEndTransmission for
|
||||
// what the number means
|
||||
Serial.print("RTC communications error = "); |
||||
Serial.println(Rtc.LastError()); |
||||
} |
||||
else |
||||
{ |
||||
// Common Causes:
|
||||
// 1) the battery on the device is low or even missing and the power line was disconnected
|
||||
Serial.println("RTC lost confidence in the DateTime!"); |
||||
} |
||||
} |
||||
|
||||
RtcDateTime now = Rtc.GetDateTime(); |
||||
|
||||
printDateTime(now); |
||||
Serial.println(); |
||||
|
||||
delay(10000); // ten seconds
|
||||
} |
||||
|
||||
#define countof(a) (sizeof(a) / sizeof(a[0])) |
||||
|
||||
void printDateTime(const RtcDateTime& dt) |
||||
{ |
||||
char datestring[20]; |
||||
|
||||
snprintf_P(datestring,
|
||||
countof(datestring), |
||||
PSTR("%02u/%02u/%04u %02u:%02u:%02u"), |
||||
dt.Month(), |
||||
dt.Day(), |
||||
dt.Year(), |
||||
dt.Hour(), |
||||
dt.Minute(), |
||||
dt.Second() ); |
||||
Serial.print(datestring); |
||||
} |
||||
|
||||
@ -0,0 +1,207 @@
@@ -0,0 +1,207 @@
|
||||
|
||||
// CONNECTIONS:
|
||||
// DS3231 SDA --> SDA
|
||||
// DS3231 SCL --> SCL
|
||||
// DS3231 VCC --> 3.3v or 5v
|
||||
// DS3231 GND --> GND
|
||||
// SQW ---> (Pin19) Don't forget to pullup (4.7k to 10k to VCC)
|
||||
|
||||
/* for software wire use below
|
||||
#include <SoftwareWire.h> // must be included here so that Arduino library object file references work |
||||
#include <RtcDS3231.h> |
||||
|
||||
SoftwareWire myWire(SDA, SCL); |
||||
RtcDS3231<SoftwareWire> Rtc(myWire); |
||||
for software wire use above */ |
||||
|
||||
/* for normal hardware wire use below */ |
||||
#include <Wire.h> // must be included here so that Arduino library object file references work |
||||
#include <RtcDS3231.h> |
||||
RtcDS3231<TwoWire> Rtc(Wire); |
||||
/* for normal hardware wire use above */ |
||||
|
||||
|
||||
// Interrupt Pin Lookup Table
|
||||
// (copied from Arduino Docs)
|
||||
//
|
||||
// CAUTION: The interrupts are Arduino numbers NOT Atmel numbers
|
||||
// and may not match (example, Mega2560 int.4 is actually Atmel Int2)
|
||||
// this is only an issue if you plan to use the lower level interupt features
|
||||
//
|
||||
// Board int.0 int.1 int.2 int.3 int.4 int.5
|
||||
// ---------------------------------------------------------------
|
||||
// Uno, Ethernet 2 3
|
||||
// Mega2560 2 3 21 20 [19] 18
|
||||
// Leonardo 3 2 0 1 7
|
||||
|
||||
#define RtcSquareWavePin 19 // Mega2560
|
||||
#define RtcSquareWaveInterrupt 4 // Mega2560
|
||||
|
||||
// marked volatile so interrupt can safely modify them and
|
||||
// other code can safely read and modify them
|
||||
volatile uint16_t interuptCount = 0; |
||||
volatile bool interuptFlag = false; |
||||
|
||||
void InteruptServiceRoutine() |
||||
{ |
||||
// since this interupted any other running code,
|
||||
// don't do anything that takes long and especially avoid
|
||||
// any communications calls within this routine
|
||||
interuptCount++; |
||||
interuptFlag = true; |
||||
} |
||||
|
||||
void setup ()
|
||||
{ |
||||
Serial.begin(57600); |
||||
|
||||
// set the interupt pin to input mode
|
||||
pinMode(RtcSquareWavePin, INPUT); |
||||
|
||||
//--------RTC SETUP ------------
|
||||
// if you are using ESP-01 then uncomment the line below to reset the pins to
|
||||
// the available pins for SDA, SCL
|
||||
// Wire.begin(0, 2); // due to limited pins, use pin 0 and 2 for SDA, SCL
|
||||
|
||||
Rtc.Begin(); |
||||
|
||||
RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__); |
||||
|
||||
if (!Rtc.IsDateTimeValid())
|
||||
{ |
||||
if (Rtc.LastError() != 0) |
||||
{ |
||||
// we have a communications error
|
||||
// see https://www.arduino.cc/en/Reference/WireEndTransmission for
|
||||
// what the number means
|
||||
Serial.print("RTC communications error = "); |
||||
Serial.println(Rtc.LastError()); |
||||
} |
||||
else |
||||
{ |
||||
Serial.println("RTC lost confidence in the DateTime!"); |
||||
Rtc.SetDateTime(compiled); |
||||
} |
||||
} |
||||
|
||||
if (!Rtc.GetIsRunning()) |
||||
{ |
||||
Serial.println("RTC was not actively running, starting now"); |
||||
Rtc.SetIsRunning(true); |
||||
} |
||||
|
||||
RtcDateTime now = Rtc.GetDateTime(); |
||||
if (now < compiled)
|
||||
{ |
||||
Serial.println("RTC is older than compile time! (Updating DateTime)"); |
||||
Rtc.SetDateTime(compiled); |
||||
} |
||||
|
||||
Rtc.Enable32kHzPin(false); |
||||
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeAlarmBoth);
|
||||
|
||||
// Alarm 1 set to trigger every day when
|
||||
// the hours, minutes, and seconds match
|
||||
RtcDateTime alarmTime = now + 88; // into the future
|
||||
DS3231AlarmOne alarm1( |
||||
alarmTime.Day(), |
||||
alarmTime.Hour(), |
||||
alarmTime.Minute(),
|
||||
alarmTime.Second(), |
||||
DS3231AlarmOneControl_HoursMinutesSecondsMatch); |
||||
Rtc.SetAlarmOne(alarm1); |
||||
|
||||
// Alarm 2 set to trigger at the top of the minute
|
||||
DS3231AlarmTwo alarm2( |
||||
0, |
||||
0, |
||||
0,
|
||||
DS3231AlarmTwoControl_OncePerMinute); |
||||
Rtc.SetAlarmTwo(alarm2); |
||||
|
||||
// throw away any old alarm state before we ran
|
||||
Rtc.LatchAlarmsTriggeredFlags(); |
||||
|
||||
// setup external interupt
|
||||
attachInterrupt(RtcSquareWaveInterrupt, InteruptServiceRoutine, FALLING); |
||||
} |
||||
|
||||
void loop ()
|
||||
{ |
||||
if (!Rtc.IsDateTimeValid())
|
||||
{ |
||||
if (Rtc.LastError() != 0) |
||||
{ |
||||
// we have a communications error
|
||||
// see https://www.arduino.cc/en/Reference/WireEndTransmission for
|
||||
// what the number means
|
||||
Serial.print("RTC communications error = "); |
||||
Serial.println(Rtc.LastError()); |
||||
} |
||||
else |
||||
{ |
||||
Serial.println("RTC lost confidence in the DateTime!"); |
||||
} |
||||
} |
||||
|
||||
RtcDateTime now = Rtc.GetDateTime(); |
||||
|
||||
printDateTime(now); |
||||
Serial.println(); |
||||
|
||||
// we only want to show time every 10 seconds
|
||||
// but we want to show responce to the interupt firing
|
||||
for (int timeCount = 0; timeCount < 20; timeCount++) |
||||
{ |
||||
if (Alarmed()) |
||||
{ |
||||
Serial.print(">>Interupt Count: "); |
||||
Serial.print(interuptCount); |
||||
Serial.println("<<"); |
||||
} |
||||
delay(500); |
||||
} |
||||
} |
||||
|
||||
bool Alarmed() |
||||
{ |
||||
bool wasAlarmed = false; |
||||
if (interuptFlag) // check our flag that gets sets in the interupt
|
||||
{ |
||||
wasAlarmed = true; |
||||
interuptFlag = false; // reset the flag
|
||||
|
||||
// this gives us which alarms triggered and
|
||||
// then allows for others to trigger again
|
||||
DS3231AlarmFlag flag = Rtc.LatchAlarmsTriggeredFlags(); |
||||
|
||||
if (flag & DS3231AlarmFlag_Alarm1) |
||||
{ |
||||
Serial.println("alarm one triggered"); |
||||
} |
||||
if (flag & DS3231AlarmFlag_Alarm2) |
||||
{ |
||||
Serial.println("alarm two triggered"); |
||||
} |
||||
} |
||||
return wasAlarmed; |
||||
} |
||||
|
||||
#define countof(a) (sizeof(a) / sizeof(a[0])) |
||||
|
||||
void printDateTime(const RtcDateTime& dt) |
||||
{ |
||||
char datestring[20]; |
||||
|
||||
snprintf_P(datestring,
|
||||
countof(datestring), |
||||
PSTR("%02u/%02u/%04u %02u:%02u:%02u"), |
||||
dt.Month(), |
||||
dt.Day(), |
||||
dt.Year(), |
||||
dt.Hour(), |
||||
dt.Minute(), |
||||
dt.Second() ); |
||||
Serial.print(datestring); |
||||
} |
||||
|
||||
@ -0,0 +1,197 @@
@@ -0,0 +1,197 @@
|
||||
|
||||
// CONNECTIONS:
|
||||
// DS1307 SDA --> SDA
|
||||
// DS1307 SCL --> SCL
|
||||
// DS1307 VCC --> 5v
|
||||
// DS1307 GND --> GND
|
||||
|
||||
#define countof(a) (sizeof(a) / sizeof(a[0])) |
||||
|
||||
/* for software wire use below
|
||||
#include <SoftwareWire.h> // must be included here so that Arduino library object file references work |
||||
#include <RtcDS3231.h> |
||||
#include <EepromAt24C32.h> |
||||
|
||||
SoftwareWire myWire(SDA, SCL); |
||||
RtcDS1307<SoftwareWire> Rtc(myWire); |
||||
/* for software wire use above */ |
||||
|
||||
/* for normal hardware wire use below */ |
||||
#include <Wire.h> // must be included here so that Arduino library object file references work |
||||
#include <RtcDS3231.h> |
||||
#include <EepromAt24C32.h> |
||||
|
||||
RtcDS3231<TwoWire> Rtc(Wire); |
||||
EepromAt24c32<TwoWire> RtcEeprom(Wire); |
||||
|
||||
// if you have any of the address pins on the RTC soldered together
|
||||
// then you need to provide the state of those pins, normally they
|
||||
// are connected to vcc with a reading of 1, if soldered they are
|
||||
// grounded with a reading of 0. The bits are in the order A2 A1 A0
|
||||
// thus the following would have the A2 soldered together
|
||||
// EepromAt24c32<TwoWire> RtcEeprom(Wire, 0b011);
|
||||
|
||||
/* for normal hardware wire use above */ |
||||
|
||||
// nothing longer than 32 bytes
|
||||
// rtc eeprom memory is 32 byte pages
|
||||
// writing is limited to each page, so it will wrap at page
|
||||
// boundaries.
|
||||
// But reading is only limited by the buffer in Wire class which
|
||||
// by default is 32
|
||||
const char data[] = "What time is it in Greenwich?"; |
||||
const uint16_t stringAddr = 64; // stored on page boundary
|
||||
|
||||
void setup ()
|
||||
{ |
||||
Serial.begin(57600); |
||||
|
||||
Serial.print("compiled: "); |
||||
Serial.print(__DATE__); |
||||
Serial.println(__TIME__); |
||||
|
||||
//--------RTC SETUP ------------
|
||||
// if you are using ESP-01 then uncomment the line below to reset the pins to
|
||||
// the available pins for SDA, SCL
|
||||
// Wire.begin(0, 2); // due to limited pins, use pin 0 and 2 for SDA, SCL
|
||||
|
||||
Rtc.Begin(); |
||||
RtcEeprom.Begin(); |
||||
|
||||
RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__); |
||||
printDateTime(compiled); |
||||
Serial.println(); |
||||
|
||||
if (!Rtc.IsDateTimeValid())
|
||||
{ |
||||
if (Rtc.LastError() != 0) |
||||
{ |
||||
// we have a communications error
|
||||
// see https://www.arduino.cc/en/Reference/WireEndTransmission for
|
||||
// what the number means
|
||||
Serial.print("RTC communications error = "); |
||||
Serial.println(Rtc.LastError()); |
||||
} |
||||
else |
||||
{ |
||||
Serial.println("RTC lost confidence in the DateTime!"); |
||||
Rtc.SetDateTime(compiled); |
||||
} |
||||
} |
||||
|
||||
if (!Rtc.GetIsRunning()) |
||||
{ |
||||
Serial.println("RTC was not actively running, starting now"); |
||||
Rtc.SetIsRunning(true); |
||||
} |
||||
|
||||
RtcDateTime now = Rtc.GetDateTime(); |
||||
if (now < compiled)
|
||||
{ |
||||
Serial.println("RTC is older than compile time! (Updating DateTime)"); |
||||
Rtc.SetDateTime(compiled); |
||||
} |
||||
|
||||
// never assume the Rtc was last configured by you, so
|
||||
// just clear them to your needed state
|
||||
Rtc.Enable32kHzPin(false); |
||||
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeNone);
|
||||
|
||||
/* comment out on a second run to see that the info is stored long term */ |
||||
// Store something in memory on the Eeprom
|
||||
|
||||
// store starting address of string
|
||||
RtcEeprom.SetMemory(0, stringAddr);
|
||||
// store the string, nothing longer than 32 bytes due to paging
|
||||
uint8_t written = RtcEeprom.SetMemory(stringAddr, (const uint8_t*)data, sizeof(data) - 1); // remove the null terminator strings add
|
||||
// store the length of the string
|
||||
RtcEeprom.SetMemory(1, written); // store the
|
||||
/* end of comment out section */ |
||||
} |
||||
|
||||
void loop ()
|
||||
{ |
||||
if (!Rtc.IsDateTimeValid())
|
||||
{ |
||||
if (Rtc.LastError() != 0) |
||||
{ |
||||
// we have a communications error
|
||||
// see https://www.arduino.cc/en/Reference/WireEndTransmission for
|
||||
// what the number means
|
||||
Serial.print("RTC communications error = "); |
||||
Serial.println(Rtc.LastError()); |
||||
} |
||||
else |
||||
{ |
||||
// Common Causes:
|
||||
// 1) the battery on the device is low or even missing and the power line was disconnected
|
||||
Serial.println("RTC lost confidence in the DateTime!"); |
||||
} |
||||
} |
||||
|
||||
RtcDateTime now = Rtc.GetDateTime(); |
||||
|
||||
printDateTime(now); |
||||
Serial.println(); |
||||
|
||||
delay(5000); |
||||
|
||||
// read data
|
||||
|
||||
// get the offset we stored our data from address zero
|
||||
uint8_t address = RtcEeprom.GetMemory(0); |
||||
if (address != stringAddr) |
||||
{ |
||||
Serial.print("address didn't match "); |
||||
Serial.println(address); |
||||
} |
||||
|
||||
{ |
||||
// get the size of the data from address 1
|
||||
uint8_t count = RtcEeprom.GetMemory(1); |
||||
uint8_t buff[64]; |
||||
|
||||
// get our data from the address with the given size
|
||||
uint8_t gotten = RtcEeprom.GetMemory(address, buff, count); |
||||
|
||||
if (gotten != count || |
||||
count != sizeof(data) - 1) // remove the extra null terminator strings add
|
||||
{ |
||||
Serial.print("something didn't match, count = "); |
||||
Serial.print(count, DEC); |
||||
Serial.print(", gotten = "); |
||||
Serial.print(gotten, DEC); |
||||
Serial.println(); |
||||
} |
||||
Serial.print("data read ("); |
||||
Serial.print(gotten); |
||||
Serial.print(") = \""); |
||||
for (uint8_t ch = 0; ch < gotten; ch++) |
||||
{ |
||||
Serial.print((char)buff[ch]); |
||||
} |
||||
Serial.println("\""); |
||||
} |
||||
|
||||
|
||||
delay(5000); |
||||
} |
||||
|
||||
|
||||
|
||||
void printDateTime(const RtcDateTime& dt) |
||||
{ |
||||
char datestring[20]; |
||||
|
||||
snprintf_P(datestring,
|
||||
countof(datestring), |
||||
PSTR("%02u/%02u/%04u %02u:%02u:%02u"), |
||||
dt.Month(), |
||||
dt.Day(), |
||||
dt.Year(), |
||||
dt.Hour(), |
||||
dt.Minute(), |
||||
dt.Second() ); |
||||
Serial.print(datestring); |
||||
} |
||||
|
||||
@ -0,0 +1,145 @@
@@ -0,0 +1,145 @@
|
||||
|
||||
// CONNECTIONS:
|
||||
// DS3231 SDA --> SDA
|
||||
// DS3231 SCL --> SCL
|
||||
// DS3231 VCC --> 3.3v or 5v
|
||||
// DS3231 GND --> GND
|
||||
|
||||
/* for software wire use below
|
||||
#include <SoftwareWire.h> // must be included here so that Arduino library object file references work |
||||
#include <RtcDS3231.h> |
||||
|
||||
SoftwareWire myWire(SDA, SCL); |
||||
RtcDS3231<SoftwareWire> Rtc(myWire); |
||||
for software wire use above */ |
||||
|
||||
/* for normal hardware wire use below */ |
||||
#include <Wire.h> // must be included here so that Arduino library object file references work |
||||
#include <RtcDS3231.h> |
||||
RtcDS3231<TwoWire> Rtc(Wire); |
||||
/* for normal hardware wire use above */ |
||||
|
||||
|
||||
void setup ()
|
||||
{ |
||||
Serial.begin(57600); |
||||
|
||||
Serial.print("compiled: "); |
||||
Serial.print(__DATE__); |
||||
Serial.println(__TIME__); |
||||
|
||||
//--------RTC SETUP ------------
|
||||
// if you are using ESP-01 then uncomment the line below to reset the pins to
|
||||
// the available pins for SDA, SCL
|
||||
// Wire.begin(0, 2); // due to limited pins, use pin 0 and 2 for SDA, SCL
|
||||
|
||||
Rtc.Begin(); |
||||
|
||||
RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__); |
||||
printDateTime(compiled); |
||||
Serial.println(); |
||||
|
||||
if (!Rtc.IsDateTimeValid())
|
||||
{ |
||||
if (Rtc.LastError() != 0) |
||||
{ |
||||
// we have a communications error
|
||||
// see https://www.arduino.cc/en/Reference/WireEndTransmission for
|
||||
// what the number means
|
||||
Serial.print("RTC communications error = "); |
||||
Serial.println(Rtc.LastError()); |
||||
} |
||||
else |
||||
{ |
||||
// Common Causes:
|
||||
// 1) first time you ran and the device wasn't running yet
|
||||
// 2) the battery on the device is low or even missing
|
||||
|
||||
Serial.println("RTC lost confidence in the DateTime!"); |
||||
|
||||
// following line sets the RTC to the date & time this sketch was compiled
|
||||
// it will also reset the valid flag internally unless the Rtc device is
|
||||
// having an issue
|
||||
|
||||
Rtc.SetDateTime(compiled); |
||||
} |
||||
} |
||||
|
||||
if (!Rtc.GetIsRunning()) |
||||
{ |
||||
Serial.println("RTC was not actively running, starting now"); |
||||
Rtc.SetIsRunning(true); |
||||
} |
||||
|
||||
RtcDateTime now = Rtc.GetDateTime(); |
||||
if (now < compiled)
|
||||
{ |
||||
Serial.println("RTC is older than compile time! (Updating DateTime)"); |
||||
Rtc.SetDateTime(compiled); |
||||
} |
||||
else if (now > compiled)
|
||||
{ |
||||
Serial.println("RTC is newer than compile time. (this is expected)"); |
||||
} |
||||
else if (now == compiled)
|
||||
{ |
||||
Serial.println("RTC is the same as compile time! (not expected but all is fine)"); |
||||
} |
||||
|
||||
// never assume the Rtc was last configured by you, so
|
||||
// just clear them to your needed state
|
||||
Rtc.Enable32kHzPin(false); |
||||
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeNone);
|
||||
} |
||||
|
||||
void loop ()
|
||||
{ |
||||
if (!Rtc.IsDateTimeValid())
|
||||
{ |
||||
if (Rtc.LastError() != 0) |
||||
{ |
||||
// we have a communications error
|
||||
// see https://www.arduino.cc/en/Reference/WireEndTransmission for
|
||||
// what the number means
|
||||
Serial.print("RTC communications error = "); |
||||
Serial.println(Rtc.LastError()); |
||||
} |
||||
else |
||||
{ |
||||
// Common Causes:
|
||||
// 1) the battery on the device is low or even missing and the power line was disconnected
|
||||
Serial.println("RTC lost confidence in the DateTime!"); |
||||
} |
||||
} |
||||
|
||||
RtcDateTime now = Rtc.GetDateTime(); |
||||
printDateTime(now); |
||||
Serial.println(); |
||||
|
||||
RtcTemperature temp = Rtc.GetTemperature(); |
||||
temp.Print(Serial); |
||||
// you may also get the temperature as a float and print it
|
||||
// Serial.print(temp.AsFloatDegC());
|
||||
Serial.println("C"); |
||||
|
||||
delay(10000); // ten seconds
|
||||
} |
||||
|
||||
#define countof(a) (sizeof(a) / sizeof(a[0])) |
||||
|
||||
void printDateTime(const RtcDateTime& dt) |
||||
{ |
||||
char datestring[20]; |
||||
|
||||
snprintf_P(datestring,
|
||||
countof(datestring), |
||||
PSTR("%02u/%02u/%04u %02u:%02u:%02u"), |
||||
dt.Month(), |
||||
dt.Day(), |
||||
dt.Year(), |
||||
dt.Hour(), |
||||
dt.Minute(), |
||||
dt.Second() ); |
||||
Serial.print(datestring); |
||||
} |
||||
|
||||
@ -0,0 +1,100 @@
@@ -0,0 +1,100 @@
|
||||
|
||||
// CONNECTIONS:
|
||||
// DS3231 SDA --> SDA
|
||||
// DS3231 SCL --> SCL
|
||||
// DS3231 VCC --> 3.3v or 5v
|
||||
// DS3231 GND --> GND
|
||||
|
||||
/* for software wire use below
|
||||
#include <SoftwareWire.h> // must be included here so that Arduino library object file references work |
||||
#include <RtcDS3231.h> |
||||
|
||||
SoftwareWire myWire(SDA, SCL); |
||||
RtcDS3231<SoftwareWire> Rtc(myWire); |
||||
for software wire use above */ |
||||
|
||||
/* for normal hardware wire use below */ |
||||
#include <Wire.h> // must be included here so that Arduino library object file references work |
||||
#include <RtcDS3231.h> |
||||
RtcDS3231<TwoWire> Rtc(Wire); |
||||
/* for normal hardware wire use above */ |
||||
|
||||
|
||||
void setup ()
|
||||
{ |
||||
Serial.begin(57600); |
||||
|
||||
Serial.print("compiled: "); |
||||
Serial.print(__DATE__); |
||||
Serial.println(__TIME__); |
||||
|
||||
//--------RTC SETUP ------------
|
||||
// if you are using ESP-01 then uncomment the line below to reset the pins to
|
||||
// the available pins for SDA, SCL
|
||||
// Wire.begin(0, 2); // due to limited pins, use pin 0 and 2 for SDA, SCL
|
||||
|
||||
Rtc.Begin(); |
||||
|
||||
RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__); |
||||
printDateTime(compiled); |
||||
Serial.println(); |
||||
|
||||
if (!Rtc.IsDateTimeValid())
|
||||
{ |
||||
Serial.println("RTC lost confidence in the DateTime!"); |
||||
Rtc.SetDateTime(compiled); |
||||
} |
||||
|
||||
if (!Rtc.GetIsRunning()) |
||||
{ |
||||
Serial.println("RTC was not actively running, starting now"); |
||||
Rtc.SetIsRunning(true); |
||||
} |
||||
|
||||
RtcDateTime now = Rtc.GetDateTime(); |
||||
if (now < compiled)
|
||||
{ |
||||
Serial.println("RTC is older than compile time! (Updating DateTime)"); |
||||
Rtc.SetDateTime(compiled); |
||||
} |
||||
|
||||
// never assume the Rtc was last configured by you, so
|
||||
// just clear them to your needed state
|
||||
Rtc.Enable32kHzPin(false); |
||||
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeNone);
|
||||
} |
||||
|
||||
void loop ()
|
||||
{ |
||||
RtcDateTime now = Rtc.GetDateTime(); |
||||
|
||||
printDateTime(now); |
||||
Serial.println(); |
||||
|
||||
for(;;) |
||||
{ |
||||
Rtc.SetIsRunning(false); |
||||
Serial.println(">>> Rtc ready for storage <<<"); |
||||
|
||||
delay(10000); // ten seconds
|
||||
} |
||||
} |
||||
|
||||
#define countof(a) (sizeof(a) / sizeof(a[0])) |
||||
|
||||
void printDateTime(const RtcDateTime& dt) |
||||
{ |
||||
char datestring[20]; |
||||
|
||||
snprintf_P(datestring,
|
||||
countof(datestring), |
||||
PSTR("%02u/%02u/%04u %02u:%02u:%02u"), |
||||
dt.Month(), |
||||
dt.Day(), |
||||
dt.Year(), |
||||
dt.Hour(), |
||||
dt.Minute(), |
||||
dt.Second() ); |
||||
Serial.print(datestring); |
||||
} |
||||
|
||||
@ -0,0 +1,179 @@
@@ -0,0 +1,179 @@
|
||||
|
||||
// Reference for connecting SPI see https://www.arduino.cc/en/Reference/SPI
|
||||
// CONNECTIONS:
|
||||
// DS3234 MISO --> MISO
|
||||
// DS3234 MOSI --> MOSI
|
||||
// DS3234 CLK --> CLK (SCK)
|
||||
// DS3234 CS (SS) --> 5 (pin used to select the DS3234 on the SPI)
|
||||
// DS3234 VCC --> 3.3v or 5v
|
||||
// DS3234 GND --> GND
|
||||
// SQW ---> (Pin19) Don't forget to pullup (4.7k to 10k to VCC)
|
||||
|
||||
const uint8_t DS3234_CS_PIN = 5; |
||||
|
||||
#include <SPI.h> |
||||
#include <RtcDS3234.h> |
||||
|
||||
RtcDS3234<SPIClass> Rtc(SPI, DS3234_CS_PIN); |
||||
|
||||
// Interrupt Pin Lookup Table
|
||||
// (copied from Arduino Docs)
|
||||
//
|
||||
// CAUTION: The interrupts are Arduino numbers NOT Atmel numbers
|
||||
// and may not match (example, Mega2560 int.4 is actually Atmel Int2)
|
||||
// this is only an issue if you plan to use the lower level interupt features
|
||||
//
|
||||
// Board int.0 int.1 int.2 int.3 int.4 int.5
|
||||
// ---------------------------------------------------------------
|
||||
// Uno, Ethernet 2 3
|
||||
// Mega2560 2 3 21 20 [19] 18
|
||||
// Leonardo 3 2 0 1 7
|
||||
// esp8266 (pin and interrupt should be the same thing)
|
||||
// esp32 (pin and interrupt should be the same thing)
|
||||
|
||||
#define RtcSquareWavePin 19 // Mega2560
|
||||
#define RtcSquareWaveInterrupt 4 // Mega2560
|
||||
|
||||
// marked volatile so interrupt can safely modify them and
|
||||
// other code can safely read and modify them
|
||||
volatile uint16_t interuptCount = 0; |
||||
volatile bool interuptFlag = false; |
||||
|
||||
void InteruptServiceRoutine() |
||||
{ |
||||
// since this interupted any other running code,
|
||||
// don't do anything that takes long and especially avoid
|
||||
// any communications calls within this routine
|
||||
interuptCount++; |
||||
interuptFlag = true; |
||||
} |
||||
|
||||
void setup ()
|
||||
{ |
||||
Serial.begin(115200); |
||||
while (!Serial); |
||||
|
||||
// set the interupt pin to input mode
|
||||
pinMode(RtcSquareWavePin, INPUT_PULLUP); // external pullup maybe required still
|
||||
|
||||
SPI.begin(); |
||||
Rtc.Begin(); |
||||
|
||||
RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__); |
||||
|
||||
if (!Rtc.IsDateTimeValid())
|
||||
{ |
||||
Serial.println("RTC lost confidence in the DateTime!"); |
||||
Rtc.SetDateTime(compiled); |
||||
} |
||||
|
||||
if (!Rtc.GetIsRunning()) |
||||
{ |
||||
Serial.println("RTC was not actively running, starting now"); |
||||
Rtc.SetIsRunning(true); |
||||
} |
||||
|
||||
RtcDateTime now = Rtc.GetDateTime(); |
||||
if (now < compiled)
|
||||
{ |
||||
Serial.println("RTC is older than compile time! (Updating DateTime)"); |
||||
Rtc.SetDateTime(compiled); |
||||
} |
||||
|
||||
Rtc.Enable32kHzPin(false); |
||||
Rtc.SetSquareWavePin(DS3234SquareWavePin_ModeAlarmBoth);
|
||||
|
||||
// Alarm 1 set to trigger every day when
|
||||
// the hours, minutes, and seconds match
|
||||
RtcDateTime alarmTime = now + 88; // into the future
|
||||
DS3234AlarmOne alarm1( |
||||
alarmTime.Day(), |
||||
alarmTime.Hour(), |
||||
alarmTime.Minute(),
|
||||
alarmTime.Second(), |
||||
DS3234AlarmOneControl_HoursMinutesSecondsMatch); |
||||
Rtc.SetAlarmOne(alarm1); |
||||
|
||||
// Alarm 2 set to trigger at the top of the minute
|
||||
DS3234AlarmTwo alarm2( |
||||
0, |
||||
0, |
||||
0,
|
||||
DS3234AlarmTwoControl_OncePerMinute); |
||||
Rtc.SetAlarmTwo(alarm2); |
||||
|
||||
// throw away any old alarm state before we ran
|
||||
Rtc.LatchAlarmsTriggeredFlags(); |
||||
|
||||
// setup external interupt
|
||||
attachInterrupt(RtcSquareWaveInterrupt, InteruptServiceRoutine, FALLING); |
||||
} |
||||
|
||||
void loop ()
|
||||
{ |
||||
if (!Rtc.IsDateTimeValid())
|
||||
{ |
||||
Serial.println("RTC lost confidence in the DateTime!"); |
||||
} |
||||
|
||||
RtcDateTime now = Rtc.GetDateTime(); |
||||
|
||||
printDateTime(now); |
||||
Serial.println(); |
||||
|
||||
// we only want to show time every 10 seconds
|
||||
// but we want to show responce to the interupt firing
|
||||
for (int timeCount = 0; timeCount < 20; timeCount++) |
||||
{ |
||||
if (Alarmed()) |
||||
{ |
||||
Serial.print(">>Interupt Count: "); |
||||
Serial.print(interuptCount); |
||||
Serial.println("<<"); |
||||
} |
||||
delay(500); |
||||
} |
||||
} |
||||
|
||||
bool Alarmed() |
||||
{ |
||||
bool wasAlarmed = false; |
||||
if (interuptFlag) // check our flag that gets sets in the interupt
|
||||
{ |
||||
wasAlarmed = true; |
||||
interuptFlag = false; // reset the flag
|
||||
|
||||
// this gives us which alarms triggered and
|
||||
// then allows for others to trigger again
|
||||
DS3234AlarmFlag flag = Rtc.LatchAlarmsTriggeredFlags(); |
||||
|
||||
if (flag & DS3234AlarmFlag_Alarm1) |
||||
{ |
||||
Serial.println("alarm one triggered"); |
||||
} |
||||
if (flag & DS3234AlarmFlag_Alarm2) |
||||
{ |
||||
Serial.println("alarm two triggered"); |
||||
} |
||||
} |
||||
return wasAlarmed; |
||||
} |
||||
|
||||
#define countof(a) (sizeof(a) / sizeof(a[0])) |
||||
|
||||
void printDateTime(const RtcDateTime& dt) |
||||
{ |
||||
char datestring[20]; |
||||
|
||||
snprintf_P(datestring,
|
||||
countof(datestring), |
||||
PSTR("%02u/%02u/%04u %02u:%02u:%02u"), |
||||
dt.Month(), |
||||
dt.Day(), |
||||
dt.Year(), |
||||
dt.Hour(), |
||||
dt.Minute(), |
||||
dt.Second() ); |
||||
Serial.print(datestring); |
||||
} |
||||
|
||||
@ -0,0 +1,139 @@
@@ -0,0 +1,139 @@
|
||||
|
||||
// Reference for connecting SPI see https://www.arduino.cc/en/Reference/SPI
|
||||
// CONNECTIONS:
|
||||
// DS3234 MISO --> MISO
|
||||
// DS3234 MOSI --> MOSI
|
||||
// DS3234 CLK --> CLK (SCK)
|
||||
// DS3234 CS (SS) --> 5 (pin used to select the DS3234 on the SPI)
|
||||
// DS3234 VCC --> 3.3v or 5v
|
||||
// DS3234 GND --> GND
|
||||
|
||||
const uint8_t DS3234_CS_PIN = 5; |
||||
|
||||
#include <SPI.h> |
||||
#include <RtcDS3234.h> |
||||
|
||||
RtcDS3234<SPIClass> Rtc(SPI, DS3234_CS_PIN); |
||||
|
||||
const char data[] = "what time is it"; |
||||
|
||||
void setup ()
|
||||
{ |
||||
Serial.begin(115200); |
||||
while (!Serial); |
||||
|
||||
Serial.print("compiled: "); |
||||
Serial.print(__DATE__); |
||||
Serial.println(__TIME__); |
||||
|
||||
SPI.begin(); |
||||
Rtc.Begin(); |
||||
|
||||
RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__); |
||||
printDateTime(compiled); |
||||
Serial.println(); |
||||
|
||||
if (!Rtc.IsDateTimeValid())
|
||||
{ |
||||
Serial.println("RTC lost confidence in the DateTime!"); |
||||
Rtc.SetDateTime(compiled); |
||||
} |
||||
|
||||
if (!Rtc.GetIsRunning()) |
||||
{ |
||||
Serial.println("RTC was not actively running, starting now"); |
||||
Rtc.SetIsRunning(true); |
||||
} |
||||
|
||||
RtcDateTime now = Rtc.GetDateTime(); |
||||
if (now < compiled)
|
||||
{ |
||||
Serial.println("RTC is older than compile time! (Updating DateTime)"); |
||||
Rtc.SetDateTime(compiled); |
||||
} |
||||
|
||||
// never assume the Rtc was last configured by you, so
|
||||
// just clear them to your needed state
|
||||
Rtc.SetSquareWavePin(DS3234SquareWavePin_ModeNone);
|
||||
|
||||
/* comment out on a second run to see that the info is stored long term */ |
||||
// Store something in memory on the RTC
|
||||
Rtc.SetMemory(0, 13); // address of a data item
|
||||
uint8_t written = Rtc.SetMemory(13, (const uint8_t*)data, sizeof(data) - 1); // remove the null terminator strings add
|
||||
Rtc.SetMemory(1, written); // size of data time
|
||||
/* end of comment out section */ |
||||
} |
||||
|
||||
void loop ()
|
||||
{ |
||||
if (!Rtc.IsDateTimeValid())
|
||||
{ |
||||
// Common Causes:
|
||||
// 1) the battery on the device is low or even missing and the power line was disconnected
|
||||
Serial.println("RTC lost confidence in the DateTime!"); |
||||
} |
||||
|
||||
RtcDateTime now = Rtc.GetDateTime(); |
||||
|
||||
printDateTime(now); |
||||
Serial.println(); |
||||
|
||||
delay(5000); |
||||
|
||||
// read data
|
||||
|
||||
// get the offset we stored our data from address zero
|
||||
uint8_t address = Rtc.GetMemory(0); |
||||
if (address != 13) |
||||
{ |
||||
Serial.println("address didn't match"); |
||||
} |
||||
else |
||||
{ |
||||
// get the size of the data from address 1
|
||||
uint8_t count = Rtc.GetMemory(1); |
||||
uint8_t buff[20]; |
||||
|
||||
// get our data from the address with the given size
|
||||
uint8_t gotten = Rtc.GetMemory(address, buff, count); |
||||
|
||||
if (gotten != count || |
||||
count != sizeof(data) - 1) // remove the extra null terminator strings add
|
||||
{ |
||||
Serial.print("something didn't match, count = "); |
||||
Serial.print(count, DEC); |
||||
Serial.print(", gotten = "); |
||||
Serial.print(gotten, DEC); |
||||
Serial.println(); |
||||
} |
||||
Serial.print("data read ("); |
||||
Serial.print(gotten); |
||||
Serial.print(") = \""); |
||||
for (uint8_t ch = 0; ch < gotten; ch++) |
||||
{ |
||||
Serial.print((char)buff[ch]); |
||||
} |
||||
Serial.println("\""); |
||||
} |
||||
|
||||
delay(5000); |
||||
} |
||||
|
||||
#define countof(a) (sizeof(a) / sizeof(a[0])) |
||||
|
||||
void printDateTime(const RtcDateTime& dt) |
||||
{ |
||||
char datestring[20]; |
||||
|
||||
snprintf_P(datestring,
|
||||
countof(datestring), |
||||
PSTR("%02u/%02u/%04u %02u:%02u:%02u"), |
||||
dt.Month(), |
||||
dt.Day(), |
||||
dt.Year(), |
||||
dt.Hour(), |
||||
dt.Minute(), |
||||
dt.Second() ); |
||||
Serial.print(datestring); |
||||
} |
||||
|
||||
@ -0,0 +1,115 @@
@@ -0,0 +1,115 @@
|
||||
|
||||
// Reference for connecting SPI see https://www.arduino.cc/en/Reference/SPI
|
||||
// CONNECTIONS:
|
||||
// DS3234 MISO --> MISO
|
||||
// DS3234 MOSI --> MOSI
|
||||
// DS3234 CLK --> CLK (SCK)
|
||||
// DS3234 CS (SS) --> 5 (pin used to select the DS3234 on the SPI)
|
||||
// DS3234 VCC --> 3.3v or 5v
|
||||
// DS3234 GND --> GND
|
||||
|
||||
const uint8_t DS3234_CS_PIN = 5; |
||||
|
||||
#include <SPI.h> |
||||
#include <RtcDS3234.h> |
||||
|
||||
RtcDS3234<SPIClass> Rtc(SPI, DS3234_CS_PIN); |
||||
|
||||
void setup ()
|
||||
{ |
||||
Serial.begin(115200); |
||||
while (!Serial); |
||||
|
||||
Serial.print("compiled: "); |
||||
Serial.print(__DATE__); |
||||
Serial.println(__TIME__); |
||||
|
||||
SPI.begin(); |
||||
Rtc.Begin(); |
||||
|
||||
RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__); |
||||
printDateTime(compiled); |
||||
Serial.println(); |
||||
|
||||
if (!Rtc.IsDateTimeValid())
|
||||
{ |
||||
// Common Causes:
|
||||
// 1) first time you ran and the device wasn't running yet
|
||||
// 2) the battery on the device is low or even missing
|
||||
|
||||
Serial.println("RTC lost confidence in the DateTime!"); |
||||
|
||||
// following line sets the RTC to the date & time this sketch was compiled
|
||||
// it will also reset the valid flag internally unless the Rtc device is
|
||||
// having an issue
|
||||
|
||||
Rtc.SetDateTime(compiled); |
||||
} |
||||
|
||||
if (!Rtc.GetIsRunning()) |
||||
{ |
||||
Serial.println("RTC was not actively running, starting now"); |
||||
Rtc.SetIsRunning(true); |
||||
} |
||||
|
||||
RtcDateTime now = Rtc.GetDateTime(); |
||||
if (now < compiled)
|
||||
{ |
||||
Serial.println("RTC is older than compile time! (Updating DateTime)"); |
||||
Rtc.SetDateTime(compiled); |
||||
} |
||||
else if (now > compiled)
|
||||
{ |
||||
Serial.println("RTC is newer than compile time. (this is expected)"); |
||||
} |
||||
else if (now == compiled)
|
||||
{ |
||||
Serial.println("RTC is the same as compile time! (not expected but all is fine)"); |
||||
} |
||||
|
||||
// never assume the Rtc was last configured by you, so
|
||||
// just clear them to your needed state
|
||||
Rtc.Enable32kHzPin(false); |
||||
Rtc.SetSquareWavePin(DS3234SquareWavePin_ModeNone);
|
||||
} |
||||
|
||||
void loop ()
|
||||
{ |
||||
if (!Rtc.IsDateTimeValid())
|
||||
{ |
||||
// Common Causes:
|
||||
// 1) the battery on the device is low or even missing and the power line was disconnected
|
||||
Serial.println("RTC lost confidence in the DateTime!"); |
||||
} |
||||
|
||||
RtcDateTime now = Rtc.GetDateTime(); |
||||
printDateTime(now); |
||||
Serial.println(); |
||||
|
||||
RtcTemperature temp = Rtc.GetTemperature(); |
||||
temp.Print(Serial); |
||||
// you may also get the temperature as a float and print it
|
||||
// Serial.print(temp.AsFloatDegC());
|
||||
Serial.println("C"); |
||||
|
||||
delay(10000); // ten seconds
|
||||
} |
||||
|
||||
#define countof(a) (sizeof(a) / sizeof(a[0])) |
||||
|
||||
void printDateTime(const RtcDateTime& dt) |
||||
{ |
||||
char datestring[20]; |
||||
|
||||
snprintf_P(datestring,
|
||||
countof(datestring), |
||||
PSTR("%02u/%02u/%04u %02u:%02u:%02u"), |
||||
dt.Month(), |
||||
dt.Day(), |
||||
dt.Year(), |
||||
dt.Hour(), |
||||
dt.Minute(), |
||||
dt.Second() ); |
||||
Serial.print(datestring); |
||||
} |
||||
|
||||
@ -0,0 +1,204 @@
@@ -0,0 +1,204 @@
|
||||
// These tests do not rely on RTC hardware at all
|
||||
|
||||
//#include <Wire.h> // must be included here so that Arduino library object file references work
|
||||
#include <RtcDS3231.h> |
||||
|
||||
void PrintPassFail(bool passed) |
||||
{ |
||||
if (passed) |
||||
{ |
||||
Serial.print("passed"); |
||||
} |
||||
else |
||||
{ |
||||
Serial.print("failed"); |
||||
} |
||||
} |
||||
|
||||
void ComparePrintlnPassFail(RtcTemperature& rtcTemp, float compare) |
||||
{ |
||||
Serial.print(rtcTemp.AsFloatDegC()); |
||||
Serial.print("C "); |
||||
PrintPassFail(rtcTemp.AsFloatDegC() == compare); |
||||
Serial.println(); |
||||
} |
||||
|
||||
void ConstructorTests() |
||||
{ |
||||
// RTC constructors
|
||||
Serial.println("Constructors:"); |
||||
{ |
||||
RtcTemperature temp075Below(0b11111111, 0b01000000); // -0.75
|
||||
ComparePrintlnPassFail(temp075Below, -0.75f); |
||||
|
||||
RtcTemperature temp050Below(0b11111111, 0b10000000); // -0.5
|
||||
ComparePrintlnPassFail(temp050Below, -0.50f); |
||||
|
||||
RtcTemperature temp025Below(0b11111111, 0b11000000); // -0.25
|
||||
ComparePrintlnPassFail(temp025Below, -0.25f); |
||||
|
||||
RtcTemperature tempZero(0b00000000, 0b00000000); // 0.0
|
||||
ComparePrintlnPassFail(tempZero, -0.0f); |
||||
|
||||
RtcTemperature temp025Above(0b00000000, 0b01000000); // 0.25
|
||||
ComparePrintlnPassFail(temp025Above, 0.25f); |
||||
|
||||
RtcTemperature temp050Above(0b00000000, 0b10000000); // 0.5
|
||||
ComparePrintlnPassFail(temp050Above, 0.5f); |
||||
|
||||
RtcTemperature temp075Above(0b00000000, 0b11000000); // 0.75
|
||||
ComparePrintlnPassFail(temp075Above, 0.75f); |
||||
|
||||
RtcTemperature temp25Above(0b00011001, 0b00000000); // 25.0
|
||||
ComparePrintlnPassFail(temp25Above, 25.0f); |
||||
|
||||
RtcTemperature temp25Below(0b11100111, 0b00000000); // -25.0
|
||||
ComparePrintlnPassFail(temp25Below, -25.0f); |
||||
} |
||||
Serial.println(); |
||||
|
||||
// SameType
|
||||
{ |
||||
Serial.print("same type "); |
||||
RtcTemperature temp25Below(0b11100111, 0b00000000); // -25.0
|
||||
RtcTemperature test = temp25Below; |
||||
ComparePrintlnPassFail(test, -25.0f); |
||||
} |
||||
|
||||
// CentiDegrees
|
||||
{ |
||||
Serial.print("centi degrees "); |
||||
RtcTemperature temp025Below(-25); // -0.25
|
||||
ComparePrintlnPassFail(temp025Below, -0.25f); |
||||
|
||||
Serial.print("centi degrees "); |
||||
RtcTemperature temp025Above(25); // 0.25
|
||||
ComparePrintlnPassFail(temp025Above, 0.25f); |
||||
|
||||
Serial.print("centi degrees "); |
||||
RtcTemperature temp25Below(-2500); // -25.0
|
||||
ComparePrintlnPassFail(temp25Below, -25.0f); |
||||
|
||||
Serial.print("centi degrees "); |
||||
RtcTemperature temp25Above(2500); // 25.0
|
||||
ComparePrintlnPassFail(temp25Above, 25.0f); |
||||
} |
||||
|
||||
Serial.println(); |
||||
} |
||||
|
||||
void PrintlnExpected(RtcTemperature& temp, uint16_t digits) |
||||
{ |
||||
Serial.print(" = "); |
||||
Serial.print(temp.AsFloatDegC(), digits); |
||||
Serial.println(); |
||||
} |
||||
|
||||
void PrintTests() |
||||
{ |
||||
Serial.println("Prints:"); |
||||
|
||||
RtcTemperature temp25Above(2500); |
||||
temp25Above.Print(Serial); |
||||
PrintlnExpected(temp25Above, 2); |
||||
|
||||
RtcTemperature temp25Below(-2500); |
||||
temp25Below.Print(Serial); |
||||
PrintlnExpected(temp25Below, 2); |
||||
|
||||
RtcTemperature temp025Above(25); |
||||
temp025Above.Print(Serial); |
||||
PrintlnExpected(temp025Above, 2); |
||||
temp025Above.Print(Serial, 1); |
||||
PrintlnExpected(temp025Above, 1); |
||||
|
||||
RtcTemperature temp025Below(-25); |
||||
temp025Below.Print(Serial); |
||||
PrintlnExpected(temp025Below, 2); |
||||
temp025Below.Print(Serial, 1); |
||||
PrintlnExpected(temp025Below, 1); |
||||
|
||||
RtcTemperature temp050Above(50); |
||||
temp050Above.Print(Serial); |
||||
PrintlnExpected(temp050Above, 2); |
||||
temp050Above.Print(Serial, 0); |
||||
PrintlnExpected(temp050Above, 0); |
||||
|
||||
RtcTemperature temp050Below(-50); |
||||
temp050Below.Print(Serial); |
||||
PrintlnExpected(temp050Below, 2); |
||||
temp050Below.Print(Serial, 0); |
||||
PrintlnExpected(temp050Below, 0); |
||||
temp050Below.Print(Serial, 2, ','); |
||||
Serial.println(" == -0,50"); |
||||
|
||||
Serial.println(); |
||||
} |
||||
|
||||
void MathmaticalOperatorTests() |
||||
{ |
||||
Serial.println("Mathmaticals:"); |
||||
|
||||
RtcTemperature temp050Below(-50); |
||||
RtcTemperature temp050Above(50); |
||||
RtcTemperature temp050Diff(100); |
||||
RtcTemperature temp050Same(-50); |
||||
RtcTemperature tempResult; |
||||
|
||||
Serial.print("equality "); |
||||
PrintPassFail(temp050Below == temp050Same); |
||||
Serial.println(); |
||||
|
||||
Serial.print("inequality "); |
||||
PrintPassFail(temp050Below != temp050Above); |
||||
Serial.println(); |
||||
|
||||
Serial.print("less than "); |
||||
PrintPassFail(temp050Below < temp050Above); |
||||
Serial.println(); |
||||
|
||||
Serial.print("greater than "); |
||||
PrintPassFail(temp050Above > temp050Below); |
||||
Serial.println(); |
||||
|
||||
Serial.print("less than "); |
||||
PrintPassFail(temp050Below <= temp050Above); |
||||
Serial.print(" or equal "); |
||||
PrintPassFail(temp050Below <= temp050Same); |
||||
Serial.println(); |
||||
|
||||
Serial.print("greater than "); |
||||
PrintPassFail(temp050Above >= temp050Below); |
||||
Serial.print(" or equal "); |
||||
PrintPassFail(temp050Below >= temp050Same); |
||||
Serial.println(); |
||||
|
||||
tempResult = temp050Above - temp050Below; |
||||
Serial.print("subtraction "); |
||||
PrintPassFail(tempResult == temp050Diff); |
||||
Serial.println(); |
||||
|
||||
tempResult = temp050Above + temp050Above; |
||||
Serial.print("addition "); |
||||
PrintPassFail(tempResult == temp050Diff); |
||||
Serial.println(); |
||||
|
||||
Serial.println(); |
||||
} |
||||
|
||||
void setup ()
|
||||
{ |
||||
Serial.begin(115200); |
||||
while (!Serial); |
||||
Serial.println(); |
||||
|
||||
ConstructorTests(); |
||||
PrintTests(); |
||||
MathmaticalOperatorTests(); |
||||
} |
||||
|
||||
void loop ()
|
||||
{ |
||||
delay(500); |
||||
} |
||||
|
||||
@ -0,0 +1,146 @@
@@ -0,0 +1,146 @@
|
||||
####################################### |
||||
# Syntax Coloring Map RTC |
||||
####################################### |
||||
|
||||
####################################### |
||||
# Datatypes (KEYWORD1) |
||||
####################################### |
||||
|
||||
ThreeWire KEYWORD1 |
||||
RtcDS1302 KEYWORD1 |
||||
RtcDS1307 KEYWORD1 |
||||
DS3234AlarmOne KEYWORD1 |
||||
DS3234AlarmTwo KEYWORD1 |
||||
RtcDS3234 KEYWORD1 |
||||
DS3231AlarmOne KEYWORD1 |
||||
DS3231AlarmTwo KEYWORD1 |
||||
RtcDS3231 KEYWORD1 |
||||
EepromAt24c32 KEYWORD1 |
||||
RtcTemperature KEYWORD1 |
||||
RtcDateTime KEYWORD1 |
||||
DayOfWeek KEYWORD1 |
||||
|
||||
####################################### |
||||
# Methods and Functions (KEYWORD2) |
||||
####################################### |
||||
|
||||
Begin KEYWORD2 |
||||
LastError KEYWORD2 |
||||
IsDateTimeValid KEYWORD2 |
||||
GetIsRunning KEYWORD2 |
||||
SetIsRunning KEYWORD2 |
||||
GetIsWriteProtected KEYWORD2 |
||||
SetIsWriteProtected KEYWORD2 |
||||
SetDateTime KEYWORD2 |
||||
GetDateTime KEYWORD2 |
||||
GetTemperature KEYWORD2 |
||||
Enable32kHzPin KEYWORD2 |
||||
SetSquareWavePin KEYWORD2 |
||||
SetSquareWavePinClockFrequency KEYWORD2 |
||||
SetAlarmOne KEYWORD2 |
||||
SetAlarmTwo KEYWORD2 |
||||
GetAlarmOne KEYWORD2 |
||||
GetAlarmTwo KEYWORD2 |
||||
LatchAlarmsTriggeredFlags KEYWORD2 |
||||
ForceTemperatureCompensationUpdate KEYWORD2 |
||||
SetTemperatureCompensationRate KEYWORD2 |
||||
GetTemperatureCompensationRate KEYWORD2 |
||||
GetAgingOffset KEYWORD2 |
||||
SetAgingOffset KEYWORD2 |
||||
GetMemory KEYWORD2 |
||||
SetMemory KEYWORD2 |
||||
GetTrickleChargeSettings KEYWORD2 |
||||
SetTrickleChargeSettings KEYWORD2 |
||||
AsFloatDegC KEYWORD2 |
||||
AsFloatDegF KEYWORD2 |
||||
AsCentiDegC KEYWORD2 |
||||
Print KEYWORD2 |
||||
Year KEYWORD2 |
||||
Month KEYWORD2 |
||||
Day KEYWORD2 |
||||
Hour KEYWORD2 |
||||
Minute KEYWORD2 |
||||
Second KEYWORD2 |
||||
DayOfWeek KEYWORD2 |
||||
TotalSeconds KEYWORD2 |
||||
DayOf KEYWORD2 |
||||
ControlFlags KEYWORD2 |
||||
|
||||
####################################### |
||||
# Constants (LITERAL1) |
||||
####################################### |
||||
|
||||
DS3231SquareWaveClock_1Hz LITERAL1 |
||||
DS3231SquareWaveClock_1kHz LITERAL1 |
||||
DS3231SquareWaveClock_4kHz LITERAL1 |
||||
DS3231SquareWaveClock_8kHz LITERAL1 |
||||
DS3231SquareWavePin_ModeNone LITERAL1 |
||||
DS3231SquareWavePin_ModeClock LITERAL1 |
||||
DS3231SquareWavePin_ModeAlarmOne LITERAL1 |
||||
DS3231SquareWavePin_ModeAlarmTwo LITERAL1 |
||||
DS3231SquareWavePin_ModeAlarmBoth LITERAL1 |
||||
DS3231AlarmOneControl_HoursMinutesSecondsDayOfMonthMatch LITERAL1 |
||||
DS3231AlarmOneControl_OncePerSecond LITERAL1 |
||||
DS3231AlarmOneControl_SecondsMatch LITERAL1 |
||||
DS3231AlarmOneControl_MinutesSecondsMatch LITERAL1 |
||||
DS3231AlarmOneControl_HoursMinutesSecondsMatch LITERAL1 |
||||
DS3231AlarmOneControl_HoursMinutesSecondsDayOfWeekMatch LITERAL1 |
||||
DS3231AlarmTwoControl_HoursMinutesDayOfMonthMatch LITERAL1 |
||||
DS3231AlarmTwoControl_OncePerMinute LITERAL1 |
||||
DS3231AlarmTwoControl_MinutesMatch LITERAL1 |
||||
DS3231AlarmTwoControl_HoursMinutesMatch LITERAL1 |
||||
DS3231AlarmTwoControl_HoursMinutesDayOfWeekMatch LITERAL1 |
||||
DS3231AlarmFlag_Alarm1 LITERAL1 |
||||
DS3231AlarmFlag_Alarm2 LITERAL1 |
||||
DS3231AlarmFlag_AlarmBoth LITERAL1 |
||||
DS1302RamSize LITERAL1 |
||||
DS1302Tcr_Disabled LITERAL1 |
||||
DS1302TcrResistor_2KOhm LITERAL1 |
||||
DS1302TcrResistor_4KOhm LITERAL1 |
||||
DS1302TcrResistor_8KOhm LITERAL1 |
||||
DS1302TcrDiodes_One LITERAL1 |
||||
DS1302TcrDiodes_Two LITERAL1 |
||||
DS1302TcrStatus_Enabled LITERAL1 |
||||
DS1302TcrStatus_Disabled LITERAL1 |
||||
DS1307SquareWaveOut_1Hz LITERAL1 |
||||
DS1307SquareWaveOut_4kHz LITERAL1 |
||||
DS1307SquareWaveOut_8kHz LITERAL1 |
||||
DS1307SquareWaveOut_32kHz LITERAL1 |
||||
DS1307SquareWaveOut_High LITERAL1 |
||||
DS1307SquareWaveOut_Low LITERAL1 |
||||
DS3234SquareWaveClock_1Hz LITERAL1 |
||||
DS3234SquareWaveClock_1kHz LITERAL1 |
||||
DS3234SquareWaveClock_4kHz LITERAL1 |
||||
DS3234SquareWaveClock_8kHz LITERAL1 |
||||
DS3234SquareWavePin_ModeNone LITERAL1 |
||||
DS3234SquareWavePin_ModeBatteryBackup LITERAL1 |
||||
DS3234SquareWavePin_ModeClock LITERAL1 |
||||
DS3234SquareWavePin_ModeAlarmOne LITERAL1 |
||||
DS3234SquareWavePin_ModeAlarmTwo LITERAL1 |
||||
DS3234SquareWavePin_ModeAlarmBoth LITERAL1 |
||||
DS3234AlarmOneControl_HoursMinutesSecondsDayOfMonthMatch LITERAL1 |
||||
DS3234AlarmOneControl_OncePerSecond LITERAL1 |
||||
DS3234AlarmOneControl_SecondsMatch LITERAL1 |
||||
DS3234AlarmOneControl_MinutesSecondsMatch LITERAL1 |
||||
DS3234AlarmOneControl_HoursMinutesSecondsMatch LITERAL1 |
||||
DS3234AlarmOneControl_HoursMinutesSecondsDayOfWeekMatch LITERAL1 |
||||
DS3234AlarmTwoControl_HoursMinutesDayOfMonthMatch LITERAL1 |
||||
DS3234AlarmTwoControl_OncePerMinute LITERAL1 |
||||
DS3234AlarmTwoControl_MinutesMatch LITERAL1 |
||||
DS3234AlarmTwoControl_HoursMinutesMatch LITERAL1 |
||||
DS3234AlarmTwoControl_HoursMinutesDayOfWeekMatch LITERAL1 |
||||
DS3234AlarmFlag_Alarm1 LITERAL1 |
||||
DS3234AlarmFlag_Alarm2 LITERAL1 |
||||
DS3234AlarmFlag_AlarmBoth LITERAL1 |
||||
DS3234TempCompensationRate_64Seconds LITERAL1 |
||||
DS3234TempCompensationRate_128Seconds LITERAL1 |
||||
DS3234TempCompensationRate_256Seconds LITERAL1 |
||||
DS3234TempCompensationRate_512Seconds LITERAL1 |
||||
DayOfWeek_Sunday LITERAL1 |
||||
DayOfWeek_Monday LITERAL1 |
||||
DayOfWeek_Tuesday LITERAL1 |
||||
DayOfWeek_Wednesday LITERAL1 |
||||
DayOfWeek_Thursday LITERAL1 |
||||
DayOfWeek_Friday LITERAL1 |
||||
DayOfWeek_Saturday LITERAL1 |
||||
|
||||
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
{ |
||||
"name": "RTC", |
||||
"keywords": "RTC, DS1302, DS1307, DS3231, DS3234, AT24C32, clock", |
||||
"description": "A library that makes interfacing DS1302, DS1307, DS3231, and DS3234 Real Time Clock modules easy.", |
||||
"repository": { |
||||
"type": "git", |
||||
"url": "https://github.com/Makuna/Rtc.git" |
||||
}, |
||||
"version": "2.3.3", |
||||
"frameworks": "arduino", |
||||
"platforms": "*" |
||||
} |
||||
|
||||
@ -0,0 +1,9 @@
@@ -0,0 +1,9 @@
|
||||
name=Rtc by Makuna |
||||
version=2.3.3 |
||||
author=Michael C. Miller (makuna@live.com) |
||||
maintainer=Michael C. Miller (makuna@live.com) |
||||
sentence=A library that makes interfacing DS1302, DS1307, DS3231, and DS3234 Real Time Clock modules easy. |
||||
paragraph=Includes deep support of module features, including temperature, alarms and memory storage if present. Tested on esp8266. |
||||
category=Device Control |
||||
url=https://github.com/Makuna/Rtc/wiki |
||||
architectures=* |
||||
@ -0,0 +1,106 @@
@@ -0,0 +1,106 @@
|
||||
#pragma once |
||||
|
||||
//I2C Slave Address
|
||||
const uint8_t AT24C32_ADDRESS = 0x50; // 0b0 1010 A2 A1 A0
|
||||
|
||||
template<class T_WIRE_METHOD> class EepromAt24c32 |
||||
{ |
||||
public: |
||||
EepromAt24c32(T_WIRE_METHOD& wire, uint8_t addressBits = 0b111) : |
||||
_address(AT24C32_ADDRESS | (addressBits & 0b00000111)), |
||||
_wire(wire), |
||||
_lastError(0) |
||||
{ |
||||
} |
||||
|
||||
void Begin() |
||||
{ |
||||
_wire.begin(); |
||||
} |
||||
|
||||
uint8_t LastError() |
||||
{ |
||||
return _lastError; |
||||
} |
||||
|
||||
void SetMemory(uint16_t memoryAddress, uint8_t value) |
||||
{ |
||||
SetMemory(memoryAddress, &value, 1); |
||||
} |
||||
|
||||
uint8_t GetMemory(uint16_t memoryAddress) |
||||
{ |
||||
uint8_t value; |
||||
|
||||
GetMemory(memoryAddress, &value, 1); |
||||
|
||||
return value; |
||||
} |
||||
|
||||
// note: this method will write within a single page of eeprom.
|
||||
// Pages are 32 bytes (5 bits), so writing past a page boundary will
|
||||
// just wrap within the page of the starting memory address.
|
||||
//
|
||||
// xxxppppp pppaaaaa => p = page #, a = address within the page
|
||||
//
|
||||
uint8_t SetMemory(uint16_t memoryAddress, const uint8_t* pValue, uint8_t countBytes) |
||||
{ |
||||
uint8_t countWritten = 0; |
||||
|
||||
beginTransmission(memoryAddress); |
||||
|
||||
while (countBytes > 0) |
||||
{ |
||||
_wire.write(*pValue++); |
||||
delay(10); // per spec, memory writes
|
||||
|
||||
countBytes--; |
||||
countWritten++; |
||||
} |
||||
|
||||
_lastError = _wire.endTransmission(); |
||||
|
||||
return countWritten; |
||||
} |
||||
|
||||
// reading data doea not wrap within pages, but due to only using
|
||||
// 12 (32K) or 13 (64K) bits are used, they will wrap within the memory limits
|
||||
// of the installed EEPROM
|
||||
uint8_t GetMemory(uint16_t memoryAddress, uint8_t* pValue, uint8_t countBytes) |
||||
{ |
||||
// set address to read from
|
||||
beginTransmission(memoryAddress); |
||||
_lastError = _wire.endTransmission(); |
||||
|
||||
if (_lastError != 0) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
// read the data
|
||||
uint8_t countRead = 0; |
||||
|
||||
countRead = _wire.requestFrom(_address, countBytes); |
||||
countBytes = countRead; |
||||
|
||||
while (countBytes-- > 0) |
||||
{ |
||||
*pValue++ = _wire.read(); |
||||
} |
||||
|
||||
return countRead; |
||||
} |
||||
|
||||
private: |
||||
const uint8_t _address; |
||||
|
||||
T_WIRE_METHOD& _wire; |
||||
uint8_t _lastError; |
||||
|
||||
void beginTransmission(uint16_t memoryAddress) |
||||
{ |
||||
_wire.beginTransmission(_address); |
||||
_wire.write(memoryAddress >> 8); |
||||
_wire.write(memoryAddress & 0xFf); |
||||
} |
||||
}; |
||||
@ -0,0 +1,266 @@
@@ -0,0 +1,266 @@
|
||||
|
||||
|
||||
#ifndef __RTCDS1302_H__ |
||||
#define __RTCDS1302_H__ |
||||
|
||||
#include <Arduino.h> |
||||
#include "RtcDateTime.h" |
||||
#include "RtcUtility.h" |
||||
|
||||
|
||||
|
||||
//DS1302 Register Addresses
|
||||
const uint8_t DS1302_REG_TIMEDATE = 0x80; |
||||
const uint8_t DS1302_REG_TIMEDATE_BURST = 0xBE; |
||||
const uint8_t DS1302_REG_TCR = 0x90; |
||||
const uint8_t DS1302_REG_RAM_BURST = 0xFE; |
||||
const uint8_t DS1302_REG_RAMSTART = 0xc0; |
||||
const uint8_t DS1302_REG_RAMEND = 0xfd; |
||||
// ram read and write addresses are interleaved
|
||||
const uint8_t DS1302RamSize = 31; |
||||
|
||||
|
||||
// DS1302 Trickle Charge Control Register Bits
|
||||
enum DS1302TcrResistor { |
||||
DS1302TcrResistor_Disabled = 0, |
||||
DS1302TcrResistor_2KOhm = B00000001, |
||||
DS1302TcrResistor_4KOhm = B00000010, |
||||
DS1302TcrResistor_8KOhm = B00000011, |
||||
DS1302TcrResistor_MASK = B00000011, |
||||
}; |
||||
|
||||
enum DS1302TcrDiodes { |
||||
DS1302TcrDiodes_None = 0, |
||||
DS1302TcrDiodes_One = B00000100, |
||||
DS1302TcrDiodes_Two = B00001000, |
||||
DS1302TcrDiodes_Disabled = B00001100, |
||||
DS1302TcrDiodes_MASK = B00001100, |
||||
}; |
||||
|
||||
enum DS1302TcrStatus { |
||||
DS1302TcrStatus_Enabled = B10100000, |
||||
DS1302TcrStatus_Disabled = B01010000, |
||||
DS1302TcrStatus_MASK = B11110000, |
||||
}; |
||||
|
||||
const uint8_t DS1302Tcr_Disabled = DS1302TcrStatus_Disabled | DS1302TcrDiodes_Disabled | DS1302TcrResistor_Disabled; |
||||
|
||||
// DS1302 Clock Halt Register & Bits
|
||||
const uint8_t DS1302_REG_CH = 0x80; // bit in the seconds register
|
||||
const uint8_t DS1302_CH = 7; |
||||
|
||||
// Write Protect Register & Bits
|
||||
const uint8_t DS1302_REG_WP = 0x8E;
|
||||
const uint8_t DS1302_WP = 7; |
||||
|
||||
template<class T_WIRE_METHOD> class RtcDS1302 |
||||
{ |
||||
public: |
||||
RtcDS1302(T_WIRE_METHOD& wire) : |
||||
_wire(wire) |
||||
{ |
||||
} |
||||
|
||||
void Begin() |
||||
{ |
||||
_wire.begin(); |
||||
} |
||||
|
||||
bool GetIsWriteProtected() |
||||
{ |
||||
uint8_t wp = getReg(DS1302_REG_WP); |
||||
return !!(wp & _BV(DS1302_WP)); |
||||
} |
||||
|
||||
void SetIsWriteProtected(bool isWriteProtected) |
||||
{ |
||||
uint8_t wp = getReg(DS1302_REG_WP); |
||||
if (isWriteProtected) |
||||
{ |
||||
wp |= _BV(DS1302_WP); |
||||
} |
||||
else |
||||
{ |
||||
wp &= ~_BV(DS1302_WP); |
||||
} |
||||
setReg(DS1302_REG_WP, wp); |
||||
} |
||||
|
||||
bool IsDateTimeValid() |
||||
{ |
||||
return GetDateTime().IsValid(); |
||||
} |
||||
|
||||
bool GetIsRunning() |
||||
{ |
||||
uint8_t ch = getReg(DS1302_REG_CH); |
||||
return !(ch & _BV(DS1302_CH)); |
||||
} |
||||
|
||||
void SetIsRunning(bool isRunning) |
||||
{ |
||||
uint8_t ch = getReg(DS1302_REG_CH); |
||||
if (isRunning) |
||||
{ |
||||
ch &= ~_BV(DS1302_CH); |
||||
} |
||||
else |
||||
{ |
||||
ch |= _BV(DS1302_CH); |
||||
} |
||||
setReg(DS1302_REG_CH, ch); |
||||
} |
||||
|
||||
uint8_t GetTrickleChargeSettings() |
||||
{ |
||||
uint8_t setting = getReg(DS1302_REG_TCR); |
||||
return setting; |
||||
} |
||||
|
||||
void SetTrickleChargeSettings(uint8_t setting) |
||||
{ |
||||
if ((setting & DS1302TcrResistor_MASK) == DS1302TcrResistor_Disabled) { |
||||
// invalid resistor setting, set to disabled
|
||||
setting = DS1302Tcr_Disabled; |
||||
goto apply; |
||||
} |
||||
if ((setting & DS1302TcrDiodes_MASK) == DS1302TcrDiodes_Disabled || |
||||
(setting & DS1302TcrDiodes_MASK) == DS1302TcrDiodes_None) { |
||||
// invalid diode setting, set to disabled
|
||||
setting = DS1302Tcr_Disabled; |
||||
goto apply; |
||||
} |
||||
if ((setting & DS1302TcrStatus_MASK) != DS1302TcrStatus_Enabled) { |
||||
// invalid status setting, set to disabled
|
||||
setting = DS1302Tcr_Disabled; |
||||
goto apply; |
||||
} |
||||
|
||||
apply: |
||||
setReg(DS1302_REG_TCR, setting); |
||||
} |
||||
|
||||
void SetDateTime(const RtcDateTime& dt) |
||||
{ |
||||
// set the date time
|
||||
_wire.beginTransmission(DS1302_REG_TIMEDATE_BURST); |
||||
|
||||
_wire.write(Uint8ToBcd(dt.Second())); |
||||
_wire.write(Uint8ToBcd(dt.Minute())); |
||||
_wire.write(Uint8ToBcd(dt.Hour())); // 24 hour mode only
|
||||
_wire.write(Uint8ToBcd(dt.Day())); |
||||
_wire.write(Uint8ToBcd(dt.Month())); |
||||
|
||||
// RTC Hardware Day of Week is 1-7, 1 = Monday
|
||||
// convert our Day of Week to Rtc Day of Week
|
||||
uint8_t rtcDow = RtcDateTime::ConvertDowToRtc(dt.DayOfWeek()); |
||||
|
||||
_wire.write(Uint8ToBcd(rtcDow)); |
||||
_wire.write(Uint8ToBcd(dt.Year() - 2000)); |
||||
_wire.write(0); // no write protect, as all of this is ignored if it is protected
|
||||
|
||||
_wire.endTransmission(); |
||||
} |
||||
|
||||
RtcDateTime GetDateTime() |
||||
{ |
||||
_wire.beginTransmission(DS1302_REG_TIMEDATE_BURST | THREEWIRE_READFLAG); |
||||
|
||||
uint8_t second = BcdToUint8(_wire.read() & 0x7F); |
||||
uint8_t minute = BcdToUint8(_wire.read()); |
||||
uint8_t hour = BcdToBin24Hour(_wire.read()); |
||||
uint8_t dayOfMonth = BcdToUint8(_wire.read()); |
||||
uint8_t month = BcdToUint8(_wire.read()); |
||||
|
||||
_wire.read(); // throwing away day of week as we calculate it
|
||||
|
||||
uint16_t year = BcdToUint8(_wire.read()) + 2000; |
||||
|
||||
_wire.read(); // throwing away write protect flag
|
||||
|
||||
_wire.endTransmission(); |
||||
|
||||
return RtcDateTime(year, month, dayOfMonth, hour, minute, second); |
||||
} |
||||
|
||||
void SetMemory(uint8_t memoryAddress, uint8_t value) |
||||
{ |
||||
// memory addresses interleaved read and write addresses
|
||||
// so we need to calculate the offset
|
||||
uint8_t address = memoryAddress * 2 + DS1302_REG_RAMSTART; |
||||
if (address <= DS1302_REG_RAMEND) |
||||
{ |
||||
setReg(address, value); |
||||
} |
||||
} |
||||
|
||||
uint8_t GetMemory(uint8_t memoryAddress) |
||||
{ |
||||
uint8_t value = 0; |
||||
// memory addresses interleaved read and write addresses
|
||||
// so we need to calculate the offset
|
||||
uint8_t address = memoryAddress * 2 + DS1302_REG_RAMSTART; |
||||
if (address <= DS1302_REG_RAMEND) |
||||
{ |
||||
value = getReg(address); |
||||
} |
||||
return value; |
||||
} |
||||
|
||||
uint8_t SetMemory(const uint8_t* pValue, uint8_t countBytes) |
||||
{ |
||||
uint8_t countWritten = 0; |
||||
|
||||
_wire.beginTransmission(DS1302_REG_RAM_BURST); |
||||
|
||||
while (countBytes > 0 && countWritten < DS1302RamSize) |
||||
{ |
||||
_wire.write(*pValue++); |
||||
countBytes--; |
||||
countWritten++; |
||||
} |
||||
|
||||
_wire.endTransmission(); |
||||
|
||||
return countWritten; |
||||
} |
||||
|
||||
uint8_t GetMemory(uint8_t* pValue, uint8_t countBytes) |
||||
{ |
||||
uint8_t countRead = 0; |
||||
|
||||
_wire.beginTransmission(DS1302_REG_RAM_BURST | THREEWIRE_READFLAG); |
||||
|
||||
while (countBytes > 0 && countRead < DS1302RamSize) |
||||
{ |
||||
*pValue++ = _wire.read(); |
||||
countRead++; |
||||
countBytes--; |
||||
} |
||||
|
||||
_wire.endTransmission(); |
||||
|
||||
return countRead; |
||||
} |
||||
|
||||
private: |
||||
T_WIRE_METHOD& _wire; |
||||
|
||||
uint8_t getReg(uint8_t regAddress) |
||||
{ |
||||
|
||||
_wire.beginTransmission(regAddress | THREEWIRE_READFLAG); |
||||
uint8_t regValue = _wire.read(); |
||||
_wire.endTransmission(); |
||||
return regValue; |
||||
} |
||||
|
||||
void setReg(uint8_t regAddress, uint8_t regValue) |
||||
{ |
||||
_wire.beginTransmission(regAddress); |
||||
_wire.write(regValue); |
||||
_wire.endTransmission(); |
||||
} |
||||
}; |
||||
|
||||
#endif // __RTCDS1302_H__
|
||||
@ -0,0 +1,244 @@
@@ -0,0 +1,244 @@
|
||||
|
||||
|
||||
#ifndef __RTCDS1307_H__ |
||||
#define __RTCDS1307_H__ |
||||
|
||||
#include <Arduino.h> |
||||
#include "RtcDateTime.h" |
||||
#include "RtcUtility.h" |
||||
|
||||
//I2C Slave Address
|
||||
const uint8_t DS1307_ADDRESS = 0x68; |
||||
|
||||
//DS1307 Register Addresses
|
||||
const uint8_t DS1307_REG_TIMEDATE = 0x00; |
||||
const uint8_t DS1307_REG_STATUS = 0x00; |
||||
const uint8_t DS1307_REG_CONTROL = 0x07; |
||||
const uint8_t DS1307_REG_RAMSTART = 0x08; |
||||
const uint8_t DS1307_REG_RAMEND = 0x3f; |
||||
const uint8_t DS1307_REG_RAMSIZE = DS1307_REG_RAMEND - DS1307_REG_RAMSTART; |
||||
|
||||
//DS1307 Register Data Size if not just 1
|
||||
const uint8_t DS1307_REG_TIMEDATE_SIZE = 7; |
||||
|
||||
// DS1307 Control Register Bits
|
||||
const uint8_t DS1307_RS0 = 0; |
||||
const uint8_t DS1307_RS1 = 1; |
||||
const uint8_t DS1307_SQWE = 4; |
||||
const uint8_t DS1307_OUT = 7; |
||||
|
||||
// DS1307 Status Register Bits
|
||||
const uint8_t DS1307_CH = 7; |
||||
|
||||
enum DS1307SquareWaveOut |
||||
{ |
||||
DS1307SquareWaveOut_1Hz = 0b00010000, |
||||
DS1307SquareWaveOut_4kHz = 0b00010001, |
||||
DS1307SquareWaveOut_8kHz = 0b00010010, |
||||
DS1307SquareWaveOut_32kHz = 0b00010011, |
||||
DS1307SquareWaveOut_High = 0b10000000, |
||||
DS1307SquareWaveOut_Low = 0b00000000, |
||||
}; |
||||
|
||||
template<class T_WIRE_METHOD> class RtcDS1307 |
||||
{ |
||||
public: |
||||
RtcDS1307(T_WIRE_METHOD& wire) : |
||||
_wire(wire), |
||||
_lastError(0) |
||||
{ |
||||
} |
||||
|
||||
void Begin() |
||||
{ |
||||
_wire.begin(); |
||||
} |
||||
|
||||
uint8_t LastError() |
||||
{ |
||||
return _lastError; |
||||
} |
||||
|
||||
bool IsDateTimeValid() |
||||
{ |
||||
return GetIsRunning(); |
||||
} |
||||
|
||||
bool GetIsRunning() |
||||
{ |
||||
uint8_t sreg = getReg(DS1307_REG_STATUS); |
||||
return !(sreg & _BV(DS1307_CH)); |
||||
} |
||||
|
||||
void SetIsRunning(bool isRunning) |
||||
{ |
||||
uint8_t sreg = getReg(DS1307_REG_STATUS); |
||||
if (isRunning) |
||||
{ |
||||
sreg &= ~_BV(DS1307_CH); |
||||
} |
||||
else |
||||
{ |
||||
sreg |= _BV(DS1307_CH); |
||||
} |
||||
setReg(DS1307_REG_STATUS, sreg); |
||||
} |
||||
|
||||
void SetDateTime(const RtcDateTime& dt) |
||||
{ |
||||
// retain running state
|
||||
uint8_t sreg = getReg(DS1307_REG_STATUS) & _BV(DS1307_CH); |
||||
|
||||
// set the date time
|
||||
_wire.beginTransmission(DS1307_ADDRESS); |
||||
_wire.write(DS1307_REG_TIMEDATE); |
||||
|
||||
_wire.write(Uint8ToBcd(dt.Second()) | sreg); |
||||
_wire.write(Uint8ToBcd(dt.Minute())); |
||||
_wire.write(Uint8ToBcd(dt.Hour())); // 24 hour mode only
|
||||
|
||||
// RTC Hardware Day of Week is 1-7, 1 = Monday
|
||||
// convert our Day of Week to Rtc Day of Week
|
||||
uint8_t rtcDow = RtcDateTime::ConvertDowToRtc(dt.DayOfWeek()); |
||||
|
||||
_wire.write(Uint8ToBcd(rtcDow));
|
||||
_wire.write(Uint8ToBcd(dt.Day())); |
||||
_wire.write(Uint8ToBcd(dt.Month())); |
||||
_wire.write(Uint8ToBcd(dt.Year() - 2000)); |
||||
|
||||
_lastError = _wire.endTransmission(); |
||||
} |
||||
|
||||
RtcDateTime GetDateTime() |
||||
{ |
||||
_wire.beginTransmission(DS1307_ADDRESS); |
||||
_wire.write(DS1307_REG_TIMEDATE); |
||||
_lastError = _wire.endTransmission(); |
||||
if (_lastError != 0) |
||||
{ |
||||
RtcDateTime(0); |
||||
} |
||||
|
||||
_wire.requestFrom(DS1307_ADDRESS, DS1307_REG_TIMEDATE_SIZE); |
||||
uint8_t second = BcdToUint8(_wire.read() & 0x7F); |
||||
uint8_t minute = BcdToUint8(_wire.read()); |
||||
uint8_t hour = BcdToBin24Hour(_wire.read()); |
||||
|
||||
_wire.read(); // throwing away day of week as we calculate it
|
||||
|
||||
uint8_t dayOfMonth = BcdToUint8(_wire.read()); |
||||
uint8_t month = BcdToUint8(_wire.read()); |
||||
uint16_t year = BcdToUint8(_wire.read()) + 2000; |
||||
|
||||
return RtcDateTime(year, month, dayOfMonth, hour, minute, second); |
||||
} |
||||
|
||||
void SetMemory(uint8_t memoryAddress, uint8_t value) |
||||
{ |
||||
uint8_t address = memoryAddress + DS1307_REG_RAMSTART; |
||||
if (address <= DS1307_REG_RAMEND) |
||||
{ |
||||
setReg(address, value); |
||||
} |
||||
} |
||||
|
||||
uint8_t GetMemory(uint8_t memoryAddress) |
||||
{ |
||||
uint8_t value = 0; |
||||
uint8_t address = memoryAddress + DS1307_REG_RAMSTART; |
||||
if (address <= DS1307_REG_RAMEND) |
||||
{ |
||||
value = getReg(address); |
||||
} |
||||
return value; |
||||
} |
||||
|
||||
uint8_t SetMemory(uint8_t memoryAddress, const uint8_t* pValue, uint8_t countBytes) |
||||
{ |
||||
uint8_t address = memoryAddress + DS1307_REG_RAMSTART; |
||||
uint8_t countWritten = 0; |
||||
if (address <= DS1307_REG_RAMEND) |
||||
{ |
||||
_wire.beginTransmission(DS1307_ADDRESS); |
||||
_wire.write(address); |
||||
|
||||
while (countBytes > 0 && address <= DS1307_REG_RAMEND) |
||||
{ |
||||
_wire.write(*pValue++); |
||||
address++; |
||||
countBytes--; |
||||
countWritten++; |
||||
} |
||||
|
||||
_lastError = _wire.endTransmission(); |
||||
} |
||||
return countWritten; |
||||
} |
||||
|
||||
uint8_t GetMemory(uint8_t memoryAddress, uint8_t* pValue, uint8_t countBytes) |
||||
{ |
||||
uint8_t address = memoryAddress + DS1307_REG_RAMSTART; |
||||
uint8_t countRead = 0; |
||||
if (address <= DS1307_REG_RAMEND) |
||||
{ |
||||
if (countBytes > DS1307_REG_RAMSIZE) |
||||
{ |
||||
countBytes = DS1307_REG_RAMSIZE; |
||||
} |
||||
|
||||
_wire.beginTransmission(DS1307_ADDRESS); |
||||
_wire.write(address); |
||||
_lastError = _wire.endTransmission(); |
||||
if (_lastError != 0) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
countRead = _wire.requestFrom(DS1307_ADDRESS, countBytes); |
||||
countBytes = countRead; |
||||
|
||||
while (countBytes-- > 0) |
||||
{ |
||||
*pValue++ = _wire.read(); |
||||
} |
||||
} |
||||
|
||||
return countRead; |
||||
} |
||||
|
||||
void SetSquareWavePin(DS1307SquareWaveOut pinMode) |
||||
{ |
||||
setReg(DS1307_REG_CONTROL, pinMode); |
||||
} |
||||
|
||||
private: |
||||
T_WIRE_METHOD& _wire; |
||||
uint8_t _lastError; |
||||
|
||||
uint8_t getReg(uint8_t regAddress) |
||||
{ |
||||
_wire.beginTransmission(DS1307_ADDRESS); |
||||
_wire.write(regAddress); |
||||
_lastError = _wire.endTransmission(); |
||||
if (_lastError != 0) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
// control register
|
||||
_wire.requestFrom(DS1307_ADDRESS, (uint8_t)1); |
||||
|
||||
uint8_t regValue = _wire.read(); |
||||
return regValue; |
||||
} |
||||
|
||||
void setReg(uint8_t regAddress, uint8_t regValue) |
||||
{ |
||||
_wire.beginTransmission(DS1307_ADDRESS); |
||||
_wire.write(regAddress); |
||||
_wire.write(regValue); |
||||
_lastError = _wire.endTransmission(); |
||||
} |
||||
}; |
||||
|
||||
#endif // __RTCDS1307_H__
|
||||
@ -0,0 +1,599 @@
@@ -0,0 +1,599 @@
|
||||
|
||||
|
||||
#ifndef __RTCDS3231_H__ |
||||
#define __RTCDS3231_H__ |
||||
|
||||
#include <Arduino.h> |
||||
|
||||
#include "RtcDateTime.h" |
||||
#include "RtcTemperature.h" |
||||
#include "RtcUtility.h" |
||||
|
||||
|
||||
//I2C Slave Address
|
||||
const uint8_t DS3231_ADDRESS = 0x68; |
||||
|
||||
//DS3231 Register Addresses
|
||||
const uint8_t DS3231_REG_TIMEDATE = 0x00; |
||||
const uint8_t DS3231_REG_ALARMONE = 0x07; |
||||
const uint8_t DS3231_REG_ALARMTWO = 0x0B; |
||||
|
||||
const uint8_t DS3231_REG_CONTROL = 0x0E; |
||||
const uint8_t DS3231_REG_STATUS = 0x0F; |
||||
const uint8_t DS3231_REG_AGING = 0x10; |
||||
|
||||
const uint8_t DS3231_REG_TEMP = 0x11; |
||||
|
||||
//DS3231 Register Data Size if not just 1
|
||||
const uint8_t DS3231_REG_TIMEDATE_SIZE = 7; |
||||
const uint8_t DS3231_REG_ALARMONE_SIZE = 4; |
||||
const uint8_t DS3231_REG_ALARMTWO_SIZE = 3; |
||||
|
||||
const uint8_t DS3231_REG_TEMP_SIZE = 2; |
||||
|
||||
// DS3231 Control Register Bits
|
||||
const uint8_t DS3231_A1IE = 0; |
||||
const uint8_t DS3231_A2IE = 1; |
||||
const uint8_t DS3231_INTCN = 2; |
||||
const uint8_t DS3231_RS1 = 3; |
||||
const uint8_t DS3231_RS2 = 4; |
||||
const uint8_t DS3231_CONV = 5; |
||||
const uint8_t DS3231_BBSQW = 6; |
||||
const uint8_t DS3231_EOSC = 7; |
||||
const uint8_t DS3231_AIEMASK = (_BV(DS3231_A1IE) | _BV(DS3231_A2IE)); |
||||
const uint8_t DS3231_RSMASK = (_BV(DS3231_RS1) | _BV(DS3231_RS2)); |
||||
|
||||
// DS3231 Status Register Bits
|
||||
const uint8_t DS3231_A1F = 0; |
||||
const uint8_t DS3231_A2F = 1; |
||||
const uint8_t DS3231_BSY = 2; |
||||
const uint8_t DS3231_EN32KHZ = 3; |
||||
const uint8_t DS3231_OSF = 7; |
||||
const uint8_t DS3231_AIFMASK = (_BV(DS3231_A1F) | _BV(DS3231_A2F)); |
||||
|
||||
|
||||
// seconds accuracy
|
||||
enum DS3231AlarmOneControl |
||||
{ |
||||
// bit order: A1M4 DY/DT A1M3 A1M2 A1M1
|
||||
DS3231AlarmOneControl_HoursMinutesSecondsDayOfMonthMatch = 0x00, |
||||
DS3231AlarmOneControl_OncePerSecond = 0x17, |
||||
DS3231AlarmOneControl_SecondsMatch = 0x16, |
||||
DS3231AlarmOneControl_MinutesSecondsMatch = 0x14, |
||||
DS3231AlarmOneControl_HoursMinutesSecondsMatch = 0x10, |
||||
DS3231AlarmOneControl_HoursMinutesSecondsDayOfWeekMatch = 0x08, |
||||
}; |
||||
|
||||
class DS3231AlarmOne |
||||
{ |
||||
public: |
||||
DS3231AlarmOne( uint8_t dayOf, |
||||
uint8_t hour, |
||||
uint8_t minute, |
||||
uint8_t second, |
||||
DS3231AlarmOneControl controlFlags) : |
||||
_flags(controlFlags), |
||||
_dayOf(dayOf), |
||||
_hour(hour), |
||||
_minute(minute), |
||||
_second(second) |
||||
{ |
||||
} |
||||
|
||||
uint8_t DayOf() const |
||||
{ |
||||
return _dayOf; |
||||
} |
||||
|
||||
uint8_t Hour() const |
||||
{ |
||||
return _hour; |
||||
} |
||||
|
||||
uint8_t Minute() const |
||||
{ |
||||
return _minute; |
||||
} |
||||
|
||||
uint8_t Second() const |
||||
{ |
||||
return _second; |
||||
} |
||||
|
||||
DS3231AlarmOneControl ControlFlags() const |
||||
{ |
||||
return _flags; |
||||
} |
||||
|
||||
bool operator == (const DS3231AlarmOne& other) const |
||||
{ |
||||
return (_dayOf == other._dayOf && |
||||
_hour == other._hour && |
||||
_minute == other._minute && |
||||
_second == other._second && |
||||
_flags == other._flags); |
||||
} |
||||
|
||||
bool operator != (const DS3231AlarmOne& other) const |
||||
{ |
||||
return !(*this == other); |
||||
} |
||||
|
||||
protected: |
||||
DS3231AlarmOneControl _flags; |
||||
|
||||
uint8_t _dayOf; |
||||
uint8_t _hour; |
||||
uint8_t _minute; |
||||
uint8_t _second;
|
||||
}; |
||||
|
||||
// minutes accuracy
|
||||
enum DS3231AlarmTwoControl |
||||
{ |
||||
// bit order: A2M4 DY/DT A2M3 A2M2
|
||||
DS3231AlarmTwoControl_HoursMinutesDayOfMonthMatch = 0x00, |
||||
DS3231AlarmTwoControl_OncePerMinute = 0x0b, |
||||
DS3231AlarmTwoControl_MinutesMatch = 0x0a, |
||||
DS3231AlarmTwoControl_HoursMinutesMatch = 0x08, |
||||
DS3231AlarmTwoControl_HoursMinutesDayOfWeekMatch = 0x04, |
||||
}; |
||||
|
||||
class DS3231AlarmTwo |
||||
{ |
||||
public: |
||||
DS3231AlarmTwo( uint8_t dayOf, |
||||
uint8_t hour, |
||||
uint8_t minute, |
||||
DS3231AlarmTwoControl controlFlags) : |
||||
_flags(controlFlags), |
||||
_dayOf(dayOf), |
||||
_hour(hour), |
||||
_minute(minute) |
||||
{ |
||||
} |
||||
|
||||
uint8_t DayOf() const |
||||
{ |
||||
return _dayOf; |
||||
} |
||||
|
||||
uint8_t Hour() const |
||||
{ |
||||
return _hour; |
||||
} |
||||
|
||||
uint8_t Minute() const |
||||
{ |
||||
return _minute; |
||||
} |
||||
|
||||
DS3231AlarmTwoControl ControlFlags() const |
||||
{ |
||||
return _flags; |
||||
} |
||||
|
||||
bool operator == (const DS3231AlarmTwo& other) const |
||||
{ |
||||
return (_dayOf == other._dayOf && |
||||
_hour == other._hour && |
||||
_minute == other._minute && |
||||
_flags == other._flags); |
||||
} |
||||
|
||||
bool operator != (const DS3231AlarmTwo& other) const |
||||
{ |
||||
return !(*this == other); |
||||
} |
||||
|
||||
protected: |
||||
DS3231AlarmTwoControl _flags; |
||||
|
||||
uint8_t _dayOf; |
||||
uint8_t _hour; |
||||
uint8_t _minute; |
||||
}; |
||||
|
||||
|
||||
enum DS3231SquareWaveClock |
||||
{ |
||||
DS3231SquareWaveClock_1Hz = 0b00000000, |
||||
DS3231SquareWaveClock_1kHz = 0b00001000, |
||||
DS3231SquareWaveClock_4kHz = 0b00010000, |
||||
DS3231SquareWaveClock_8kHz = 0b00011000, |
||||
}; |
||||
|
||||
enum DS3231SquareWavePinMode |
||||
{ |
||||
DS3231SquareWavePin_ModeNone, |
||||
DS3231SquareWavePin_ModeAlarmOne, |
||||
DS3231SquareWavePin_ModeAlarmTwo, |
||||
// note: the same as DS3231SquareWavePin_ModeAlarmOne | DS3231SquareWavePin_ModeAlarmTwo
|
||||
DS3231SquareWavePin_ModeAlarmBoth,
|
||||
DS3231SquareWavePin_ModeClock |
||||
}; |
||||
|
||||
enum DS3231AlarmFlag |
||||
{ |
||||
DS3231AlarmFlag_Alarm1 = 0x01, |
||||
DS3231AlarmFlag_Alarm2 = 0x02, |
||||
DS3231AlarmFlag_AlarmBoth = 0x03, |
||||
}; |
||||
|
||||
template<class T_WIRE_METHOD> class RtcDS3231 |
||||
{ |
||||
public: |
||||
RtcDS3231(T_WIRE_METHOD& wire) : |
||||
_wire(wire), |
||||
_lastError(0) |
||||
{ |
||||
} |
||||
|
||||
void Begin() |
||||
{ |
||||
_wire.begin(); |
||||
} |
||||
|
||||
uint8_t LastError() |
||||
{ |
||||
return _lastError; |
||||
} |
||||
|
||||
bool IsDateTimeValid() |
||||
{ |
||||
uint8_t status = getReg(DS3231_REG_STATUS); |
||||
return !(status & _BV(DS3231_OSF)); |
||||
} |
||||
|
||||
bool GetIsRunning() |
||||
{ |
||||
uint8_t creg = getReg(DS3231_REG_CONTROL); |
||||
return !(creg & _BV(DS3231_EOSC)); |
||||
} |
||||
|
||||
void SetIsRunning(bool isRunning) |
||||
{ |
||||
uint8_t creg = getReg(DS3231_REG_CONTROL); |
||||
if (isRunning) |
||||
{ |
||||
creg &= ~_BV(DS3231_EOSC); |
||||
} |
||||
else |
||||
{ |
||||
creg |= _BV(DS3231_EOSC); |
||||
} |
||||
setReg(DS3231_REG_CONTROL, creg); |
||||
} |
||||
|
||||
void SetDateTime(const RtcDateTime& dt) |
||||
{ |
||||
// clear the invalid flag
|
||||
uint8_t status = getReg(DS3231_REG_STATUS); |
||||
status &= ~_BV(DS3231_OSF); // clear the flag
|
||||
setReg(DS3231_REG_STATUS, status); |
||||
|
||||
// set the date time
|
||||
_wire.beginTransmission(DS3231_ADDRESS); |
||||
_wire.write(DS3231_REG_TIMEDATE); |
||||
|
||||
_wire.write(Uint8ToBcd(dt.Second())); |
||||
_wire.write(Uint8ToBcd(dt.Minute())); |
||||
_wire.write(Uint8ToBcd(dt.Hour())); // 24 hour mode only
|
||||
|
||||
uint8_t year = dt.Year() - 2000; |
||||
uint8_t centuryFlag = 0; |
||||
|
||||
if (year >= 100) |
||||
{ |
||||
year -= 100; |
||||
centuryFlag = _BV(7); |
||||
} |
||||
|
||||
// RTC Hardware Day of Week is 1-7, 1 = Monday
|
||||
// convert our Day of Week to Rtc Day of Week
|
||||
uint8_t rtcDow = RtcDateTime::ConvertDowToRtc(dt.DayOfWeek()); |
||||
|
||||
_wire.write(Uint8ToBcd(rtcDow)); |
||||
|
||||
_wire.write(Uint8ToBcd(dt.Day())); |
||||
_wire.write(Uint8ToBcd(dt.Month()) | centuryFlag); |
||||
_wire.write(Uint8ToBcd(year)); |
||||
|
||||
_lastError = _wire.endTransmission(); |
||||
} |
||||
|
||||
RtcDateTime GetDateTime() |
||||
{ |
||||
_wire.beginTransmission(DS3231_ADDRESS); |
||||
_wire.write(DS3231_REG_TIMEDATE); |
||||
_lastError = _wire.endTransmission(); |
||||
if (_lastError != 0) |
||||
{ |
||||
return RtcDateTime(0); |
||||
} |
||||
|
||||
_wire.requestFrom(DS3231_ADDRESS, DS3231_REG_TIMEDATE_SIZE); |
||||
uint8_t second = BcdToUint8(_wire.read() & 0x7F); |
||||
uint8_t minute = BcdToUint8(_wire.read()); |
||||
uint8_t hour = BcdToBin24Hour(_wire.read()); |
||||
|
||||
_wire.read(); // throwing away day of week as we calculate it
|
||||
|
||||
uint8_t dayOfMonth = BcdToUint8(_wire.read()); |
||||
uint8_t monthRaw = _wire.read(); |
||||
uint16_t year = BcdToUint8(_wire.read()) + 2000; |
||||
|
||||
if (monthRaw & _BV(7)) // century wrap flag
|
||||
{ |
||||
year += 100; |
||||
} |
||||
uint8_t month = BcdToUint8(monthRaw & 0x7f); |
||||
|
||||
|
||||
return RtcDateTime(year, month, dayOfMonth, hour, minute, second); |
||||
} |
||||
|
||||
RtcTemperature GetTemperature() |
||||
{ |
||||
_wire.beginTransmission(DS3231_ADDRESS); |
||||
_wire.write(DS3231_REG_TEMP); |
||||
_lastError = _wire.endTransmission(); |
||||
if (_lastError != 0) |
||||
{ |
||||
return RtcTemperature(0); |
||||
} |
||||
|
||||
// Temperature is represented as a 10-bit code with a resolution
|
||||
// of 1/4th °C and is accessable as a signed 16-bit integer at
|
||||
// locations 11h and 12h.
|
||||
//
|
||||
// | r11h | DP | r12h |
|
||||
// Bit: 15 14 13 12 11 10 9 8 . 7 6 5 4 3 2 1 0 -1 -2
|
||||
// s i i i i i i i . f f 0 0 0 0 0 0
|
||||
//
|
||||
// As it takes (8) right-shifts to register the decimal point (DP) to
|
||||
// the right of the 0th bit, the overall word scaling equals 256.
|
||||
//
|
||||
// For example, at +/- 25.25°C, concatenated registers <r11h:r12h> =
|
||||
// 256 * (+/- 25+(1/4)) = +/- 6464, or 1940h / E6C0h.
|
||||
|
||||
_wire.requestFrom(DS3231_ADDRESS, DS3231_REG_TEMP_SIZE); |
||||
int8_t r11h = _wire.read(); // MS byte, signed temperature
|
||||
return RtcTemperature( r11h, _wire.read() ); // LS byte is r12h
|
||||
} |
||||
|
||||
void Enable32kHzPin(bool enable) |
||||
{ |
||||
uint8_t sreg = getReg(DS3231_REG_STATUS); |
||||
|
||||
if (enable == true) |
||||
{ |
||||
sreg |= _BV(DS3231_EN32KHZ); |
||||
} |
||||
else |
||||
{ |
||||
sreg &= ~_BV(DS3231_EN32KHZ); |
||||
} |
||||
|
||||
setReg(DS3231_REG_STATUS, sreg); |
||||
} |
||||
|
||||
void SetSquareWavePin(DS3231SquareWavePinMode pinMode, bool enableWhileInBatteryBackup = true) |
||||
{ |
||||
uint8_t creg = getReg(DS3231_REG_CONTROL); |
||||
|
||||
// clear all relevant bits to a known "off" state
|
||||
creg &= ~(DS3231_AIEMASK | _BV(DS3231_BBSQW)); |
||||
creg |= _BV(DS3231_INTCN); // set INTCN to disables clock SQW
|
||||
|
||||
if (pinMode != DS3231SquareWavePin_ModeNone) |
||||
{ |
||||
if (pinMode == DS3231SquareWavePin_ModeClock) |
||||
{ |
||||
creg &= ~_BV(DS3231_INTCN); // clear INTCN to enable clock SQW
|
||||
} |
||||
else |
||||
{ |
||||
if (pinMode & DS3231SquareWavePin_ModeAlarmOne) |
||||
{ |
||||
creg |= _BV(DS3231_A1IE); |
||||
} |
||||
if (pinMode & DS3231SquareWavePin_ModeAlarmTwo) |
||||
{ |
||||
creg |= _BV(DS3231_A2IE); |
||||
} |
||||
} |
||||
|
||||
if (enableWhileInBatteryBackup) |
||||
{ |
||||
creg |= _BV(DS3231_BBSQW); // set enable int/sqw while in battery backup flag
|
||||
} |
||||
} |
||||
setReg(DS3231_REG_CONTROL, creg); |
||||
} |
||||
|
||||
void SetSquareWavePinClockFrequency(DS3231SquareWaveClock freq) |
||||
{ |
||||
uint8_t creg = getReg(DS3231_REG_CONTROL); |
||||
|
||||
creg &= ~DS3231_RSMASK; // Set to 0
|
||||
creg |= (freq & DS3231_RSMASK); // Set freq bits
|
||||
|
||||
setReg(DS3231_REG_CONTROL, creg); |
||||
} |
||||
|
||||
|
||||
void SetAlarmOne(const DS3231AlarmOne& alarm) |
||||
{ |
||||
_wire.beginTransmission(DS3231_ADDRESS); |
||||
_wire.write(DS3231_REG_ALARMONE); |
||||
|
||||
_wire.write(Uint8ToBcd(alarm.Second()) | ((alarm.ControlFlags() & 0x01) << 7)); |
||||
_wire.write(Uint8ToBcd(alarm.Minute()) | ((alarm.ControlFlags() & 0x02) << 6)); |
||||
_wire.write(Uint8ToBcd(alarm.Hour()) | ((alarm.ControlFlags() & 0x04) << 5)); // 24 hour mode only
|
||||
|
||||
uint8_t rtcDow = alarm.DayOf(); |
||||
if (alarm.ControlFlags() == DS3231AlarmOneControl_HoursMinutesSecondsDayOfWeekMatch) |
||||
{ |
||||
rtcDow = RtcDateTime::ConvertDowToRtc(rtcDow); |
||||
} |
||||
|
||||
_wire.write(Uint8ToBcd(rtcDow) | ((alarm.ControlFlags() & 0x18) << 3)); |
||||
|
||||
_lastError = _wire.endTransmission(); |
||||
} |
||||
|
||||
void SetAlarmTwo(const DS3231AlarmTwo& alarm) |
||||
{ |
||||
_wire.beginTransmission(DS3231_ADDRESS); |
||||
_wire.write(DS3231_REG_ALARMTWO); |
||||
|
||||
_wire.write(Uint8ToBcd(alarm.Minute()) | ((alarm.ControlFlags() & 0x01) << 7)); |
||||
_wire.write(Uint8ToBcd(alarm.Hour()) | ((alarm.ControlFlags() & 0x02) << 6)); // 24 hour mode only
|
||||
|
||||
// convert our Day of Week to Rtc Day of Week if needed
|
||||
uint8_t rtcDow = alarm.DayOf(); |
||||
if (alarm.ControlFlags() == DS3231AlarmTwoControl_HoursMinutesDayOfWeekMatch) |
||||
{ |
||||
rtcDow = RtcDateTime::ConvertDowToRtc(rtcDow); |
||||
} |
||||
|
||||
_wire.write(Uint8ToBcd(rtcDow) | ((alarm.ControlFlags() & 0x0c) << 4)); |
||||
|
||||
_lastError = _wire.endTransmission(); |
||||
} |
||||
|
||||
DS3231AlarmOne GetAlarmOne() |
||||
{ |
||||
_wire.beginTransmission(DS3231_ADDRESS); |
||||
_wire.write(DS3231_REG_ALARMONE); |
||||
_lastError = _wire.endTransmission(); |
||||
if (_lastError != 0) |
||||
{ |
||||
return DS3231AlarmOne(0, 0, 0, 0, DS3231AlarmOneControl_HoursMinutesSecondsDayOfMonthMatch); |
||||
} |
||||
|
||||
_wire.requestFrom(DS3231_ADDRESS, DS3231_REG_ALARMONE_SIZE); |
||||
|
||||
uint8_t raw = _wire.read(); |
||||
uint8_t flags = (raw & 0x80) >> 7; |
||||
uint8_t second = BcdToUint8(raw & 0x7F); |
||||
|
||||
raw = _wire.read(); |
||||
flags |= (raw & 0x80) >> 6; |
||||
uint8_t minute = BcdToUint8(raw & 0x7F); |
||||
|
||||
raw = _wire.read(); |
||||
flags |= (raw & 0x80) >> 5; |
||||
uint8_t hour = BcdToBin24Hour(raw & 0x7f); |
||||
|
||||
raw = _wire.read(); |
||||
flags |= (raw & 0xc0) >> 3; |
||||
uint8_t dayOf = BcdToUint8(raw & 0x3f); |
||||
|
||||
if (flags == DS3231AlarmOneControl_HoursMinutesSecondsDayOfWeekMatch) |
||||
{ |
||||
dayOf = RtcDateTime::ConvertRtcToDow(dayOf); |
||||
} |
||||
|
||||
return DS3231AlarmOne(dayOf, hour, minute, second, (DS3231AlarmOneControl)flags); |
||||
} |
||||
|
||||
DS3231AlarmTwo GetAlarmTwo() |
||||
{ |
||||
_wire.beginTransmission(DS3231_ADDRESS); |
||||
_wire.write(DS3231_REG_ALARMTWO); |
||||
_lastError = _wire.endTransmission(); |
||||
if (_lastError != 0) |
||||
{ |
||||
return DS3231AlarmTwo(0, 0, 0, DS3231AlarmTwoControl_HoursMinutesDayOfMonthMatch); |
||||
} |
||||
|
||||
_wire.requestFrom(DS3231_ADDRESS, DS3231_REG_ALARMTWO_SIZE); |
||||
|
||||
uint8_t raw = _wire.read(); |
||||
uint8_t flags = (raw & 0x80) >> 7; |
||||
uint8_t minute = BcdToUint8(raw & 0x7F); |
||||
|
||||
raw = _wire.read(); |
||||
flags |= (raw & 0x80) >> 6; |
||||
uint8_t hour = BcdToBin24Hour(raw & 0x7f); |
||||
|
||||
raw = _wire.read(); |
||||
flags |= (raw & 0xc0) >> 4; |
||||
uint8_t dayOf = BcdToUint8(raw & 0x3f); |
||||
|
||||
if (flags == DS3231AlarmTwoControl_HoursMinutesDayOfWeekMatch) |
||||
{ |
||||
dayOf = RtcDateTime::ConvertRtcToDow(dayOf); |
||||
} |
||||
|
||||
return DS3231AlarmTwo(dayOf, hour, minute, (DS3231AlarmTwoControl)flags); |
||||
} |
||||
|
||||
// Latch must be called after an alarm otherwise it will not
|
||||
// trigger again
|
||||
DS3231AlarmFlag LatchAlarmsTriggeredFlags() |
||||
{ |
||||
uint8_t sreg = getReg(DS3231_REG_STATUS); |
||||
uint8_t alarmFlags = (sreg & DS3231_AIFMASK); |
||||
sreg &= ~DS3231_AIFMASK; // clear the flags
|
||||
setReg(DS3231_REG_STATUS, sreg); |
||||
return (DS3231AlarmFlag)alarmFlags; |
||||
} |
||||
|
||||
void ForceTemperatureCompensationUpdate(bool block) |
||||
{ |
||||
uint8_t creg = getReg(DS3231_REG_CONTROL); |
||||
creg |= _BV(DS3231_CONV); // Write CONV bit
|
||||
setReg(DS3231_REG_CONTROL, creg); |
||||
|
||||
while (block && (creg & _BV(DS3231_CONV)) != 0) |
||||
{ |
||||
// Block until CONV is 0
|
||||
creg = getReg(DS3231_REG_CONTROL); |
||||
} |
||||
} |
||||
|
||||
int8_t GetAgingOffset() |
||||
{ |
||||
return getReg(DS3231_REG_AGING); |
||||
} |
||||
|
||||
void SetAgingOffset(int8_t value) |
||||
{ |
||||
setReg(DS3231_REG_AGING, value); |
||||
} |
||||
|
||||
private: |
||||
T_WIRE_METHOD& _wire; |
||||
uint8_t _lastError; |
||||
|
||||
uint8_t getReg(uint8_t regAddress) |
||||
{ |
||||
_wire.beginTransmission(DS3231_ADDRESS); |
||||
_wire.write(regAddress); |
||||
_lastError = _wire.endTransmission(); |
||||
if (_lastError != 0) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
// control register
|
||||
_wire.requestFrom(DS3231_ADDRESS, (uint8_t)1); |
||||
|
||||
uint8_t regValue = _wire.read(); |
||||
return regValue; |
||||
} |
||||
|
||||
void setReg(uint8_t regAddress, uint8_t regValue) |
||||
{ |
||||
_wire.beginTransmission(DS3231_ADDRESS); |
||||
_wire.write(regAddress); |
||||
_wire.write(regValue); |
||||
_lastError = _wire.endTransmission(); |
||||
} |
||||
|
||||
}; |
||||
|
||||
#endif // __RTCDS3231_H__
|
||||
@ -0,0 +1,699 @@
@@ -0,0 +1,699 @@
|
||||
|
||||
|
||||
#ifndef __RTCDS3234_H__ |
||||
#define __RTCDS3234_H__ |
||||
|
||||
#include <Arduino.h> |
||||
#include <SPI.h> |
||||
|
||||
#include "RtcDateTime.h" |
||||
#include "RtcTemperature.h" |
||||
#include "RtcUtility.h" |
||||
|
||||
|
||||
//DS3234 Register Addresses
|
||||
const uint8_t DS3234_REG_WRITE_FLAG = 0x80; |
||||
|
||||
const uint8_t DS3234_REG_TIMEDATE = 0x00; |
||||
|
||||
const uint8_t DS3234_REG_ALARMONE = 0x07; |
||||
const uint8_t DS3234_REG_ALARMTWO = 0x0B; |
||||
|
||||
const uint8_t DS3234_REG_CONTROL = 0x0E; |
||||
const uint8_t DS3234_REG_STATUS = 0x0F; |
||||
const uint8_t DS3234_REG_AGING = 0x10; |
||||
|
||||
const uint8_t DS3234_REG_TEMP = 0x11; |
||||
|
||||
const uint8_t DS3234_REG_RAM_ADDRESS = 0x18; |
||||
const uint8_t DS3234_REG_RAM_DATA = 0x19; |
||||
|
||||
const uint8_t DS3234_RAMSTART = 0x00; |
||||
const uint8_t DS3234_RAMEND = 0xFF; |
||||
const uint8_t DS3234_RAMSIZE = DS3234_RAMEND - DS3234_RAMSTART; |
||||
|
||||
// DS3234 Control Register Bits
|
||||
const uint8_t DS3234_A1IE = 0; |
||||
const uint8_t DS3234_A2IE = 1; |
||||
const uint8_t DS3234_INTCN = 2; |
||||
const uint8_t DS3234_RS1 = 3; |
||||
const uint8_t DS3234_RS2 = 4; |
||||
const uint8_t DS3234_CONV = 5; |
||||
const uint8_t DS3234_BBSQW = 6; |
||||
const uint8_t DS3234_EOSC = 7; |
||||
const uint8_t DS3234_AIEMASK = (_BV(DS3234_A1IE) | _BV(DS3234_A2IE)); |
||||
const uint8_t DS3234_RSMASK = (_BV(DS3234_RS1) | _BV(DS3234_RS2)); |
||||
|
||||
// DS3234 Status Register Bits
|
||||
const uint8_t DS3234_A1F = 0; |
||||
const uint8_t DS3234_A2F = 1; |
||||
const uint8_t DS3234_BSY = 2; |
||||
const uint8_t DS3234_EN32KHZ = 3; |
||||
const uint8_t DS3234_CRATE0 = 4; |
||||
const uint8_t DS3234_CRATE1 = 5; |
||||
const uint8_t DS3234_BB32KHZ = 6; |
||||
const uint8_t DS3234_OSF = 7; |
||||
const uint8_t DS3234_AIFMASK = (_BV(DS3234_A1F) | _BV(DS3234_A2F)); |
||||
const uint8_t DS3234_CRATEMASK = (_BV(DS3234_CRATE0) | _BV(DS3234_CRATE1)); |
||||
|
||||
// seconds accuracy
|
||||
enum DS3234AlarmOneControl |
||||
{ |
||||
// bit order: A1M4 DY/DT A1M3 A1M2 A1M1
|
||||
DS3234AlarmOneControl_HoursMinutesSecondsDayOfMonthMatch = 0x00, |
||||
DS3234AlarmOneControl_OncePerSecond = 0x17, |
||||
DS3234AlarmOneControl_SecondsMatch = 0x16, |
||||
DS3234AlarmOneControl_MinutesSecondsMatch = 0x14, |
||||
DS3234AlarmOneControl_HoursMinutesSecondsMatch = 0x10, |
||||
DS3234AlarmOneControl_HoursMinutesSecondsDayOfWeekMatch = 0x08, |
||||
}; |
||||
|
||||
class DS3234AlarmOne |
||||
{ |
||||
public: |
||||
DS3234AlarmOne( uint8_t dayOf, |
||||
uint8_t hour, |
||||
uint8_t minute, |
||||
uint8_t second, |
||||
DS3234AlarmOneControl controlFlags) : |
||||
_flags(controlFlags), |
||||
_dayOf(dayOf), |
||||
_hour(hour), |
||||
_minute(minute), |
||||
_second(second) |
||||
{ |
||||
} |
||||
|
||||
uint8_t DayOf() const |
||||
{ |
||||
return _dayOf; |
||||
} |
||||
|
||||
uint8_t Hour() const |
||||
{ |
||||
return _hour; |
||||
} |
||||
|
||||
uint8_t Minute() const |
||||
{ |
||||
return _minute; |
||||
} |
||||
|
||||
uint8_t Second() const |
||||
{ |
||||
return _second; |
||||
} |
||||
|
||||
DS3234AlarmOneControl ControlFlags() const |
||||
{ |
||||
return _flags; |
||||
} |
||||
|
||||
bool operator == (const DS3234AlarmOne& other) const |
||||
{ |
||||
return (_dayOf == other._dayOf && |
||||
_hour == other._hour && |
||||
_minute == other._minute && |
||||
_second == other._second && |
||||
_flags == other._flags); |
||||
} |
||||
|
||||
bool operator != (const DS3234AlarmOne& other) const |
||||
{ |
||||
return !(*this == other); |
||||
} |
||||
|
||||
protected: |
||||
DS3234AlarmOneControl _flags; |
||||
|
||||
uint8_t _dayOf; |
||||
uint8_t _hour; |
||||
uint8_t _minute; |
||||
uint8_t _second;
|
||||
}; |
||||
|
||||
// minutes accuracy
|
||||
enum DS3234AlarmTwoControl |
||||
{ |
||||
// bit order: A2M4 DY/DT A2M3 A2M2
|
||||
DS3234AlarmTwoControl_HoursMinutesDayOfMonthMatch = 0x00, |
||||
DS3234AlarmTwoControl_OncePerMinute = 0x0b, |
||||
DS3234AlarmTwoControl_MinutesMatch = 0x0a, |
||||
DS3234AlarmTwoControl_HoursMinutesMatch = 0x08, |
||||
DS3234AlarmTwoControl_HoursMinutesDayOfWeekMatch = 0x04, |
||||
}; |
||||
|
||||
class DS3234AlarmTwo |
||||
{ |
||||
public: |
||||
DS3234AlarmTwo( uint8_t dayOf, |
||||
uint8_t hour, |
||||
uint8_t minute, |
||||
DS3234AlarmTwoControl controlFlags) : |
||||
_flags(controlFlags), |
||||
_dayOf(dayOf), |
||||
_hour(hour), |
||||
_minute(minute) |
||||
{ |
||||
} |
||||
|
||||
uint8_t DayOf() const |
||||
{ |
||||
return _dayOf; |
||||
} |
||||
|
||||
uint8_t Hour() const |
||||
{ |
||||
return _hour; |
||||
} |
||||
|
||||
uint8_t Minute() const |
||||
{ |
||||
return _minute; |
||||
} |
||||
|
||||
DS3234AlarmTwoControl ControlFlags() const |
||||
{ |
||||
return _flags; |
||||
} |
||||
|
||||
bool operator == (const DS3234AlarmTwo& other) const |
||||
{ |
||||
return (_dayOf == other._dayOf && |
||||
_hour == other._hour && |
||||
_minute == other._minute && |
||||
_flags == other._flags); |
||||
} |
||||
|
||||
bool operator != (const DS3234AlarmTwo& other) const |
||||
{ |
||||
return !(*this == other); |
||||
} |
||||
|
||||
protected: |
||||
DS3234AlarmTwoControl _flags; |
||||
|
||||
uint8_t _dayOf; |
||||
uint8_t _hour; |
||||
uint8_t _minute; |
||||
}; |
||||
|
||||
|
||||
enum DS3234SquareWaveClock |
||||
{ |
||||
DS3234SquareWaveClock_1Hz = 0b00000000, |
||||
DS3234SquareWaveClock_1kHz = 0b00001000, |
||||
DS3234SquareWaveClock_4kHz = 0b00010000, |
||||
DS3234SquareWaveClock_8kHz = 0b00011000, |
||||
}; |
||||
|
||||
enum DS3234SquareWavePinMode |
||||
{ |
||||
DS3234SquareWavePin_ModeNone, |
||||
DS3234SquareWavePin_ModeBatteryBackup, |
||||
DS3234SquareWavePin_ModeClock, |
||||
DS3234SquareWavePin_ModeAlarmOne, |
||||
DS3234SquareWavePin_ModeAlarmTwo, |
||||
DS3234SquareWavePin_ModeAlarmBoth |
||||
}; |
||||
|
||||
enum DS3234TempCompensationRate |
||||
{ |
||||
DS3234TempCompensationRate_64Seconds, |
||||
DS3234TempCompensationRate_128Seconds, |
||||
DS3234TempCompensationRate_256Seconds, |
||||
DS3234TempCompensationRate_512Seconds, |
||||
}; |
||||
|
||||
enum DS3234AlarmFlag |
||||
{ |
||||
DS3234AlarmFlag_Alarm1 = 0x01, |
||||
DS3234AlarmFlag_Alarm2 = 0x02, |
||||
DS3234AlarmFlag_AlarmBoth = 0x03, |
||||
}; |
||||
|
||||
const SPISettings c_Ds3234SpiSettings(1000000, MSBFIRST, SPI_MODE1); // CPHA must be used, so mode 1 or mode 3 are valid
|
||||
|
||||
template<class T_SPI_METHOD> class RtcDS3234 |
||||
{ |
||||
public: |
||||
RtcDS3234(T_SPI_METHOD& spi, uint8_t csPin) : |
||||
_spi(spi), |
||||
_csPin(csPin) |
||||
{ |
||||
} |
||||
|
||||
void Begin() |
||||
{ |
||||
UnselectChip(); |
||||
pinMode(_csPin, OUTPUT); |
||||
} |
||||
|
||||
bool IsDateTimeValid() |
||||
{ |
||||
uint8_t status = getReg(DS3234_REG_STATUS); |
||||
return !(status & _BV(DS3234_OSF)); |
||||
} |
||||
|
||||
bool GetIsRunning() |
||||
{ |
||||
uint8_t creg = getReg(DS3234_REG_CONTROL); |
||||
return !(creg & _BV(DS3234_EOSC)); |
||||
} |
||||
|
||||
void SetIsRunning(bool isRunning) |
||||
{ |
||||
uint8_t creg = getReg(DS3234_REG_CONTROL); |
||||
if (isRunning) |
||||
{ |
||||
creg &= ~_BV(DS3234_EOSC); |
||||
} |
||||
else |
||||
{ |
||||
creg |= _BV(DS3234_EOSC); |
||||
} |
||||
setReg(DS3234_REG_CONTROL, creg); |
||||
} |
||||
|
||||
void SetDateTime(const RtcDateTime& dt) |
||||
{ |
||||
// clear the invalid flag
|
||||
uint8_t status = getReg(DS3234_REG_STATUS); |
||||
status &= ~_BV(DS3234_OSF); // clear the flag
|
||||
setReg(DS3234_REG_STATUS, status); |
||||
|
||||
// set the date time
|
||||
_spi.beginTransaction(c_Ds3234SpiSettings); |
||||
SelectChip(); |
||||
_spi.transfer(DS3234_REG_TIMEDATE | DS3234_REG_WRITE_FLAG); |
||||
|
||||
_spi.transfer(Uint8ToBcd(dt.Second())); |
||||
_spi.transfer(Uint8ToBcd(dt.Minute())); |
||||
_spi.transfer(Uint8ToBcd(dt.Hour())); // 24 hour mode only
|
||||
|
||||
uint8_t year = dt.Year() - 2000; |
||||
uint8_t centuryFlag = 0; |
||||
|
||||
if (year >= 100) |
||||
{ |
||||
year -= 100; |
||||
centuryFlag = _BV(7); |
||||
} |
||||
|
||||
// RTC Hardware Day of Week is 1-7, 1 = Monday
|
||||
// convert our Day of Week to Rtc Day of Week
|
||||
uint8_t rtcDow = RtcDateTime::ConvertDowToRtc(dt.DayOfWeek()); |
||||
|
||||
_spi.transfer(Uint8ToBcd(rtcDow)); |
||||
|
||||
_spi.transfer(Uint8ToBcd(dt.Day())); |
||||
_spi.transfer(Uint8ToBcd(dt.Month()) | centuryFlag); |
||||
_spi.transfer(Uint8ToBcd(year)); |
||||
UnselectChip(); |
||||
_spi.endTransaction(); |
||||
} |
||||
|
||||
RtcDateTime GetDateTime() |
||||
{ |
||||
_spi.beginTransaction(c_Ds3234SpiSettings); |
||||
SelectChip(); |
||||
|
||||
_spi.transfer(DS3234_REG_TIMEDATE); |
||||
|
||||
uint8_t second = BcdToUint8(_spi.transfer(0)); |
||||
uint8_t minute = BcdToUint8(_spi.transfer(0)); |
||||
uint8_t hour = BcdToBin24Hour(_spi.transfer(0)); |
||||
|
||||
_spi.transfer(0); // throwing away day of week as we calculate it
|
||||
|
||||
uint8_t dayOfMonth = BcdToUint8(_spi.transfer(0)); |
||||
uint8_t monthRaw = _spi.transfer(0); |
||||
uint16_t year = BcdToUint8(_spi.transfer(0)) + 2000; |
||||
|
||||
UnselectChip(); |
||||
_spi.endTransaction(); |
||||
|
||||
if (monthRaw & _BV(7)) // century wrap flag
|
||||
{ |
||||
year += 100; |
||||
} |
||||
uint8_t month = BcdToUint8(monthRaw & 0x7f); |
||||
|
||||
return RtcDateTime(year, month, dayOfMonth, hour, minute, second); |
||||
} |
||||
|
||||
RtcTemperature GetTemperature() |
||||
{ |
||||
_spi.beginTransaction(c_Ds3234SpiSettings); |
||||
SelectChip(); |
||||
_spi.transfer(DS3234_REG_TEMP); |
||||
|
||||
// Temperature is represented as a 10-bit code with a resolution
|
||||
// of 1/4th °C and is accessable as a signed 16-bit integer at
|
||||
// locations 11h and 12h.
|
||||
//
|
||||
// | r11h | DP | r12h |
|
||||
// Bit: 15 14 13 12 11 10 9 8 . 7 6 5 4 3 2 1 0 -1 -2
|
||||
// s i i i i i i i . f f 0 0 0 0 0 0
|
||||
//
|
||||
// As it takes (8) right-shifts to register the decimal point (DP) to
|
||||
// the right of the 0th bit, the overall word scaling equals 256.
|
||||
//
|
||||
// For example, at +/- 25.25°C, concatenated registers <r11h:r12h> =
|
||||
// 256 * (+/- 25+(1/4)) = +/- 6464, or 1940h / E6C0h.
|
||||
|
||||
int8_t ms = _spi.transfer(0); // MS byte, signed temperature
|
||||
uint8_t ls = _spi.transfer(0); // LS byte is r12h
|
||||
|
||||
UnselectChip(); |
||||
_spi.endTransaction(); |
||||
|
||||
return RtcTemperature(ms, ls); // LS byte is r12h
|
||||
} |
||||
|
||||
void Enable32kHzPin(bool enable) |
||||
{ |
||||
uint8_t sreg = getReg(DS3234_REG_STATUS); |
||||
|
||||
if (enable == true) |
||||
{ |
||||
sreg |= _BV(DS3234_EN32KHZ); |
||||
} |
||||
else |
||||
{ |
||||
sreg &= ~_BV(DS3234_EN32KHZ); |
||||
} |
||||
|
||||
setReg(DS3234_REG_STATUS, sreg); |
||||
} |
||||
|
||||
void SetSquareWavePin(DS3234SquareWavePinMode pinMode) |
||||
{ |
||||
uint8_t creg = getReg(DS3234_REG_CONTROL); |
||||
|
||||
// clear all relevant bits to a known "off" state
|
||||
creg &= ~(DS3234_AIEMASK | _BV(DS3234_BBSQW)); |
||||
creg |= _BV(DS3234_INTCN); // set INTCN to disables SQW
|
||||
|
||||
switch (pinMode) |
||||
{ |
||||
case DS3234SquareWavePin_ModeNone: |
||||
break; |
||||
|
||||
case DS3234SquareWavePin_ModeBatteryBackup: |
||||
creg |= _BV(DS3234_BBSQW); // set battery backup flag
|
||||
creg &= ~_BV(DS3234_INTCN); // clear INTCN to enable SQW
|
||||
break; |
||||
|
||||
case DS3234SquareWavePin_ModeClock: |
||||
creg &= ~_BV(DS3234_INTCN); // clear INTCN to enable SQW
|
||||
break; |
||||
|
||||
case DS3234SquareWavePin_ModeAlarmOne: |
||||
creg |= _BV(DS3234_A1IE); |
||||
break; |
||||
|
||||
case DS3234SquareWavePin_ModeAlarmTwo: |
||||
creg |= _BV(DS3234_A2IE); |
||||
break; |
||||
|
||||
case DS3234SquareWavePin_ModeAlarmBoth: |
||||
creg |= _BV(DS3234_A1IE) | _BV(DS3234_A2IE); |
||||
break; |
||||
} |
||||
|
||||
setReg(DS3234_REG_CONTROL, creg); |
||||
} |
||||
|
||||
void SetSquareWavePinClockFrequency(DS3234SquareWaveClock freq) |
||||
{ |
||||
uint8_t creg = getReg(DS3234_REG_CONTROL); |
||||
|
||||
creg &= ~DS3234_RSMASK; // Set to 0
|
||||
creg |= (freq & DS3234_RSMASK); // Set freq bits
|
||||
|
||||
setReg(DS3234_REG_CONTROL, creg); |
||||
} |
||||
|
||||
|
||||
void SetAlarmOne(const DS3234AlarmOne& alarm) |
||||
{ |
||||
_spi.beginTransaction(c_Ds3234SpiSettings); |
||||
SelectChip(); |
||||
|
||||
_spi.transfer(DS3234_REG_ALARMONE | DS3234_REG_WRITE_FLAG); |
||||
|
||||
_spi.transfer(Uint8ToBcd(alarm.Second()) | ((alarm.ControlFlags() & 0x01) << 7)); |
||||
_spi.transfer(Uint8ToBcd(alarm.Minute()) | ((alarm.ControlFlags() & 0x02) << 6)); |
||||
_spi.transfer(Uint8ToBcd(alarm.Hour()) | ((alarm.ControlFlags() & 0x04) << 5)); // 24 hour mode only
|
||||
|
||||
uint8_t rtcDow = alarm.DayOf(); |
||||
if (alarm.ControlFlags() == DS3234AlarmOneControl_HoursMinutesSecondsDayOfWeekMatch) |
||||
{ |
||||
rtcDow = RtcDateTime::ConvertDowToRtc(rtcDow); |
||||
} |
||||
|
||||
_spi.transfer(Uint8ToBcd(rtcDow) | ((alarm.ControlFlags() & 0x18) << 3)); |
||||
|
||||
UnselectChip(); |
||||
_spi.endTransaction(); |
||||
} |
||||
|
||||
void SetAlarmTwo(const DS3234AlarmTwo& alarm) |
||||
{ |
||||
_spi.beginTransaction(c_Ds3234SpiSettings); |
||||
SelectChip(); |
||||
|
||||
_spi.transfer(DS3234_REG_ALARMTWO | DS3234_REG_WRITE_FLAG); |
||||
|
||||
_spi.transfer(Uint8ToBcd(alarm.Minute()) | ((alarm.ControlFlags() & 0x01) << 7)); |
||||
_spi.transfer(Uint8ToBcd(alarm.Hour()) | ((alarm.ControlFlags() & 0x02) << 6)); // 24 hour mode only
|
||||
|
||||
// convert our Day of Week to Rtc Day of Week if needed
|
||||
uint8_t rtcDow = alarm.DayOf(); |
||||
if (alarm.ControlFlags() == DS3234AlarmTwoControl_HoursMinutesDayOfWeekMatch) |
||||
{ |
||||
rtcDow = RtcDateTime::ConvertDowToRtc(rtcDow); |
||||
} |
||||
|
||||
_spi.transfer(Uint8ToBcd(rtcDow) | ((alarm.ControlFlags() & 0x0c) << 4)); |
||||
|
||||
UnselectChip(); |
||||
_spi.endTransaction(); |
||||
} |
||||
|
||||
DS3234AlarmOne GetAlarmOne() |
||||
{ |
||||
_spi.beginTransaction(c_Ds3234SpiSettings); |
||||
SelectChip(); |
||||
|
||||
_spi.transfer(DS3234_REG_ALARMONE); |
||||
|
||||
uint8_t raw = _spi.transfer(0); |
||||
uint8_t flags = (raw & 0x80) >> 7; |
||||
uint8_t second = BcdToUint8(raw & 0x7F); |
||||
|
||||
raw = _spi.transfer(0); |
||||
flags |= (raw & 0x80) >> 6; |
||||
uint8_t minute = BcdToUint8(raw & 0x7F); |
||||
|
||||
raw = _spi.transfer(0); |
||||
flags |= (raw & 0x80) >> 5; |
||||
uint8_t hour = BcdToBin24Hour(raw & 0x7f); |
||||
|
||||
raw = _spi.transfer(0); |
||||
flags |= (raw & 0xc0) >> 3; |
||||
uint8_t dayOf = BcdToUint8(raw & 0x3f); |
||||
|
||||
UnselectChip(); |
||||
_spi.endTransaction(); |
||||
|
||||
if (flags == DS3234AlarmOneControl_HoursMinutesSecondsDayOfWeekMatch) |
||||
{ |
||||
dayOf = RtcDateTime::ConvertRtcToDow(dayOf); |
||||
} |
||||
|
||||
return DS3234AlarmOne(dayOf, hour, minute, second, (DS3234AlarmOneControl)flags); |
||||
} |
||||
|
||||
DS3234AlarmTwo GetAlarmTwo() |
||||
{ |
||||
_spi.beginTransaction(c_Ds3234SpiSettings); |
||||
SelectChip(); |
||||
|
||||
_spi.transfer(DS3234_REG_ALARMTWO); |
||||
|
||||
uint8_t raw = _spi.transfer(0); |
||||
uint8_t flags = (raw & 0x80) >> 7; |
||||
uint8_t minute = BcdToUint8(raw & 0x7F); |
||||
|
||||
raw = _spi.transfer(0); |
||||
flags |= (raw & 0x80) >> 6; |
||||
uint8_t hour = BcdToBin24Hour(raw & 0x7f); |
||||
|
||||
raw = _spi.transfer(0); |
||||
flags |= (raw & 0xc0) >> 4; |
||||
uint8_t dayOf = BcdToUint8(raw & 0x3f); |
||||
|
||||
UnselectChip(); |
||||
_spi.endTransaction(); |
||||
|
||||
if (flags == DS3234AlarmTwoControl_HoursMinutesDayOfWeekMatch) |
||||
{ |
||||
dayOf = RtcDateTime::ConvertRtcToDow(dayOf); |
||||
} |
||||
|
||||
return DS3234AlarmTwo(dayOf, hour, minute, (DS3234AlarmTwoControl)flags); |
||||
} |
||||
|
||||
// Latch must be called after an alarm otherwise it will not
|
||||
// trigger again
|
||||
DS3234AlarmFlag LatchAlarmsTriggeredFlags() |
||||
{ |
||||
uint8_t sreg = getReg(DS3234_REG_STATUS); |
||||
uint8_t alarmFlags = (sreg & DS3234_AIFMASK); |
||||
sreg &= ~DS3234_AIFMASK; // clear the flags
|
||||
setReg(DS3234_REG_STATUS, sreg); |
||||
return (DS3234AlarmFlag)alarmFlags; |
||||
} |
||||
|
||||
void SetTemperatureCompensationRate(DS3234TempCompensationRate rate) |
||||
{ |
||||
uint8_t sreg = getReg(DS3234_REG_STATUS); |
||||
|
||||
sreg &= ~DS3234_CRATEMASK; |
||||
sreg |= (rate << DS3234_CRATE0); |
||||
|
||||
setReg(DS3234_REG_STATUS, sreg); |
||||
} |
||||
|
||||
DS3234TempCompensationRate GetTemperatureCompensationRate() |
||||
{ |
||||
uint8_t sreg = getReg(DS3234_REG_STATUS); |
||||
return (sreg & DS3234_CRATEMASK) >> DS3234_CRATE0; |
||||
} |
||||
|
||||
void ForceTemperatureCompensationUpdate(bool block) |
||||
{ |
||||
uint8_t creg = getReg(DS3234_REG_CONTROL); |
||||
creg |= _BV(DS3234_CONV); // Write CONV bit
|
||||
setReg(DS3234_REG_CONTROL, creg); |
||||
|
||||
while (block && (creg & _BV(DS3234_CONV)) != 0) |
||||
{ |
||||
// Block until CONV is 0
|
||||
creg = getReg(DS3234_REG_CONTROL); |
||||
} |
||||
} |
||||
|
||||
int8_t GetAgingOffset() |
||||
{ |
||||
return getReg(DS3234_REG_AGING); |
||||
} |
||||
|
||||
void SetAgingOffset(int8_t value) |
||||
{ |
||||
setReg(DS3234_REG_AGING, value); |
||||
} |
||||
|
||||
void SetMemory(uint8_t memoryAddress, uint8_t value) |
||||
{ |
||||
SetMemory(memoryAddress, &value, 1); |
||||
} |
||||
|
||||
uint8_t GetMemory(uint8_t memoryAddress) |
||||
{ |
||||
uint8_t value; |
||||
|
||||
GetMemory(memoryAddress, &value, 1); |
||||
|
||||
return value; |
||||
} |
||||
|
||||
uint8_t SetMemory(uint8_t memoryAddress, const uint8_t* pValue, uint8_t countBytes) |
||||
{ |
||||
uint8_t countWritten = 0; |
||||
|
||||
setReg(DS3234_REG_RAM_ADDRESS, memoryAddress); |
||||
|
||||
_spi.beginTransaction(c_Ds3234SpiSettings); |
||||
SelectChip(); |
||||
_spi.transfer(DS3234_REG_RAM_DATA | DS3234_REG_WRITE_FLAG); |
||||
|
||||
while (countBytes > 0) |
||||
{ |
||||
_spi.transfer(*pValue++); |
||||
|
||||
countBytes--; |
||||
countWritten++; |
||||
} |
||||
|
||||
UnselectChip(); |
||||
_spi.endTransaction(); |
||||
|
||||
return countWritten; |
||||
} |
||||
|
||||
uint8_t GetMemory(uint8_t memoryAddress, uint8_t* pValue, uint8_t countBytes) |
||||
{ |
||||
// set address to read from
|
||||
setReg(DS3234_REG_RAM_ADDRESS, memoryAddress); |
||||
|
||||
_spi.beginTransaction(c_Ds3234SpiSettings); |
||||
SelectChip(); |
||||
_spi.transfer(DS3234_REG_RAM_DATA); |
||||
|
||||
// read the data
|
||||
uint8_t countRead = 0; |
||||
|
||||
while (countBytes-- > 0) |
||||
{ |
||||
*pValue++ = _spi.transfer(0); |
||||
countRead++; |
||||
} |
||||
|
||||
UnselectChip(); |
||||
_spi.endTransaction(); |
||||
|
||||
return countRead; |
||||
} |
||||
|
||||
private: |
||||
T_SPI_METHOD& _spi; |
||||
uint8_t _csPin; |
||||
|
||||
void SelectChip() |
||||
{ |
||||
digitalWrite(_csPin, LOW); |
||||
} |
||||
void UnselectChip() |
||||
{ |
||||
digitalWrite(_csPin, HIGH); |
||||
} |
||||
|
||||
uint8_t getReg(uint8_t regAddress) |
||||
{ |
||||
uint8_t regValue; |
||||
_spi.beginTransaction(c_Ds3234SpiSettings); |
||||
SelectChip(); |
||||
_spi.transfer(regAddress); |
||||
regValue = _spi.transfer(0); |
||||
UnselectChip(); |
||||
_spi.endTransaction(); |
||||
|
||||
return regValue; |
||||
} |
||||
|
||||
void setReg(uint8_t regAddress, uint8_t regValue) |
||||
{ |
||||
_spi.beginTransaction(c_Ds3234SpiSettings); |
||||
SelectChip(); |
||||
_spi.transfer(regAddress | DS3234_REG_WRITE_FLAG); |
||||
_spi.transfer(regValue); |
||||
UnselectChip(); |
||||
_spi.endTransaction(); |
||||
} |
||||
|
||||
}; |
||||
|
||||
#endif // __RTCDS3234_H__
|
||||
@ -0,0 +1,211 @@
@@ -0,0 +1,211 @@
|
||||
|
||||
#include <Arduino.h> |
||||
#include "RtcDateTime.h" |
||||
|
||||
const uint8_t c_daysInMonth[] PROGMEM = { 31,28,31,30,31,30,31,31,30,31,30,31 }; |
||||
|
||||
RtcDateTime::RtcDateTime(uint32_t secondsFrom2000) |
||||
{ |
||||
_initWithSecondsFrom2000<uint32_t>(secondsFrom2000); |
||||
} |
||||
|
||||
bool RtcDateTime::IsValid() const |
||||
{ |
||||
// this just tests the most basic validity of the value ranges
|
||||
// and valid leap years
|
||||
// It does not check any time zone or daylight savings time
|
||||
if ((_month > 0 && _month < 13) && |
||||
(_dayOfMonth > 0 && _dayOfMonth < 32) && |
||||
(_hour < 24) && |
||||
(_minute < 60) && |
||||
(_second < 60)) |
||||
{ |
||||
// days in a month tests
|
||||
//
|
||||
if (_month == 2) |
||||
{ |
||||
if (_dayOfMonth > 29) |
||||
{ |
||||
return false; |
||||
} |
||||
else if (_dayOfMonth > 28) |
||||
{ |
||||
// leap day
|
||||
// check year to make sure its a leap year
|
||||
uint16_t year = Year(); |
||||
|
||||
if ((year % 4) != 0) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
if ((year % 100) == 0 && |
||||
(year % 400) != 0) |
||||
{ |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
else if (_dayOfMonth == 31) |
||||
{ |
||||
if ((((_month - 1) % 7) % 2) == 1) |
||||
{ |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
uint8_t StringToUint8(const char* pString) |
||||
{ |
||||
uint8_t value = 0; |
||||
|
||||
// skip leading 0 and spaces
|
||||
while ('0' == *pString || *pString == ' ') |
||||
{ |
||||
pString++; |
||||
} |
||||
|
||||
// calculate number until we hit non-numeral char
|
||||
while ('0' <= *pString && *pString <= '9') |
||||
{ |
||||
value *= 10; |
||||
value += *pString - '0'; |
||||
pString++; |
||||
} |
||||
return value; |
||||
} |
||||
|
||||
RtcDateTime::RtcDateTime(const char* date, const char* time) |
||||
{ |
||||
// sample input: date = "Dec 06 2009", time = "12:34:56"
|
||||
_yearFrom2000 = StringToUint8(date + 9); |
||||
// Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
|
||||
switch (date[0]) |
||||
{ |
||||
case 'J': |
||||
if ( date[1] == 'a' ) |
||||
_month = 1; |
||||
else if ( date[2] == 'n' ) |
||||
_month = 6; |
||||
else |
||||
_month = 7; |
||||
break; |
||||
case 'F': |
||||
_month = 2; |
||||
break; |
||||
case 'A': |
||||
_month = date[1] == 'p' ? 4 : 8; |
||||
break; |
||||
case 'M': |
||||
_month = date[2] == 'r' ? 3 : 5; |
||||
break; |
||||
case 'S': |
||||
_month = 9; |
||||
break; |
||||
case 'O': |
||||
_month = 10; |
||||
break; |
||||
case 'N': |
||||
_month = 11; |
||||
break; |
||||
case 'D': |
||||
_month = 12; |
||||
break; |
||||
} |
||||
_dayOfMonth = StringToUint8(date + 4); |
||||
_hour = StringToUint8(time); |
||||
_minute = StringToUint8(time + 3); |
||||
_second = StringToUint8(time + 6); |
||||
} |
||||
|
||||
template <typename T> T DaysSinceFirstOfYear2000(uint16_t year, uint8_t month, uint8_t dayOfMonth) |
||||
{ |
||||
T days = dayOfMonth; |
||||
for (uint8_t indexMonth = 1; indexMonth < month; ++indexMonth) |
||||
{ |
||||
days += pgm_read_byte(c_daysInMonth + indexMonth - 1); |
||||
} |
||||
if (month > 2 && year % 4 == 0) |
||||
{ |
||||
days++; |
||||
} |
||||
return days + 365 * year + (year + 3) / 4 - 1; |
||||
} |
||||
|
||||
template <typename T> T SecondsIn(T days, uint8_t hours, uint8_t minutes, uint8_t seconds) |
||||
{ |
||||
return ((days * 24L + hours) * 60 + minutes) * 60 + seconds; |
||||
} |
||||
|
||||
uint8_t RtcDateTime::DayOfWeek() const |
||||
{ |
||||
uint16_t days = DaysSinceFirstOfYear2000<uint16_t>(_yearFrom2000, _month, _dayOfMonth); |
||||
return (days + 6) % 7; // Jan 1, 2000 is a Saturday, i.e. returns 6
|
||||
} |
||||
|
||||
// 32-bit time; as seconds since 1/1/2000
|
||||
uint32_t RtcDateTime::TotalSeconds() const |
||||
{ |
||||
uint16_t days = DaysSinceFirstOfYear2000<uint16_t>(_yearFrom2000, _month, _dayOfMonth); |
||||
return SecondsIn<uint32_t>(days, _hour, _minute, _second); |
||||
} |
||||
|
||||
// 64-bit time; as seconds since 1/1/2000
|
||||
uint64_t RtcDateTime::TotalSeconds64() const |
||||
{ |
||||
uint32_t days = DaysSinceFirstOfYear2000<uint32_t>(_yearFrom2000, _month, _dayOfMonth); |
||||
return SecondsIn<uint64_t>(days, _hour, _minute, _second); |
||||
} |
||||
|
||||
// total days since 1/1/2000
|
||||
uint16_t RtcDateTime::TotalDays() const |
||||
{ |
||||
return DaysSinceFirstOfYear2000<uint16_t>(_yearFrom2000, _month, _dayOfMonth); |
||||
} |
||||
|
||||
void RtcDateTime::InitWithIso8601(const char* date) |
||||
{ |
||||
// sample input: date = "Sat, 06 Dec 2009 12:34:56 GMT"
|
||||
_yearFrom2000 = StringToUint8(date + 13); |
||||
// Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
|
||||
switch (date[8]) |
||||
{ |
||||
case 'J': |
||||
if (date[1 + 8] == 'a') |
||||
_month = 1; |
||||
else if (date[2 + 8] == 'n') |
||||
_month = 6; |
||||
else |
||||
_month = 7; |
||||
break; |
||||
case 'F': |
||||
_month = 2; |
||||
break; |
||||
case 'A': |
||||
_month = date[1 + 8] == 'p' ? 4 : 8; |
||||
break; |
||||
case 'M': |
||||
_month = date[2 + 8] == 'r' ? 3 : 5; |
||||
break; |
||||
case 'S': |
||||
_month = 9; |
||||
break; |
||||
case 'O': |
||||
_month = 10; |
||||
break; |
||||
case 'N': |
||||
_month = 11; |
||||
break; |
||||
case 'D': |
||||
_month = 12; |
||||
break; |
||||
} |
||||
_dayOfMonth = StringToUint8(date + 5); |
||||
_hour = StringToUint8(date + 17); |
||||
_minute = StringToUint8(date + 20); |
||||
_second = StringToUint8(date + 23); |
||||
} |
||||
@ -0,0 +1,185 @@
@@ -0,0 +1,185 @@
|
||||
|
||||
|
||||
#ifndef __RTCDATETIME_H__ |
||||
#define __RTCDATETIME_H__ |
||||
|
||||
// ESP32 complains if not included
|
||||
#if defined(ARDUINO_ARCH_ESP32) |
||||
#include <inttypes.h> |
||||
#endif |
||||
|
||||
enum DayOfWeek |
||||
{ |
||||
DayOfWeek_Sunday = 0, |
||||
DayOfWeek_Monday, |
||||
DayOfWeek_Tuesday, |
||||
DayOfWeek_Wednesday, |
||||
DayOfWeek_Thursday, |
||||
DayOfWeek_Friday, |
||||
DayOfWeek_Saturday, |
||||
}; |
||||
|
||||
const uint16_t c_OriginYear = 2000; |
||||
const uint32_t c_Epoch32OfOriginYear = 946684800; |
||||
extern const uint8_t c_daysInMonth[] PROGMEM; |
||||
|
||||
class RtcDateTime |
||||
{ |
||||
public: |
||||
RtcDateTime(uint32_t secondsFrom2000 = 0); |
||||
RtcDateTime(uint16_t year, |
||||
uint8_t month, |
||||
uint8_t dayOfMonth, |
||||
uint8_t hour, |
||||
uint8_t minute, |
||||
uint8_t second) : |
||||
_yearFrom2000((year >= c_OriginYear) ? year - c_OriginYear : year), |
||||
_month(month), |
||||
_dayOfMonth(dayOfMonth), |
||||
_hour(hour), |
||||
_minute(minute), |
||||
_second(second) |
||||
{ |
||||
} |
||||
|
||||
// RtcDateTime compileDateTime(__DATE__, __TIME__);
|
||||
RtcDateTime(const char* date, const char* time); |
||||
|
||||
bool IsValid() const; |
||||
|
||||
uint16_t Year() const |
||||
{ |
||||
return c_OriginYear + _yearFrom2000; |
||||
} |
||||
uint8_t Month() const |
||||
{ |
||||
return _month; |
||||
} |
||||
uint8_t Day() const |
||||
{ |
||||
return _dayOfMonth; |
||||
} |
||||
uint8_t Hour() const |
||||
{ |
||||
return _hour; |
||||
} |
||||
uint8_t Minute() const |
||||
{ |
||||
return _minute; |
||||
} |
||||
uint8_t Second() const |
||||
{ |
||||
return _second; |
||||
} |
||||
// 0 = Sunday, 1 = Monday, ... 6 = Saturday
|
||||
uint8_t DayOfWeek() const; |
||||
|
||||
// 32-bit time; as seconds since 1/1/2000
|
||||
uint32_t TotalSeconds() const; |
||||
|
||||
// 64-bit time; as seconds since 1/1/2000
|
||||
uint64_t TotalSeconds64() const; |
||||
|
||||
// total days since 1/1/2000
|
||||
uint16_t TotalDays() const; |
||||
|
||||
// add seconds
|
||||
void operator += (uint32_t seconds) |
||||
{ |
||||
RtcDateTime after = RtcDateTime( TotalSeconds() + seconds ); |
||||
*this = after; |
||||
} |
||||
|
||||
// remove seconds
|
||||
void operator -= (uint32_t seconds) |
||||
{ |
||||
RtcDateTime before = RtcDateTime( TotalSeconds() - seconds ); |
||||
*this = before; |
||||
} |
||||
|
||||
// allows for comparisons to just work (==, <, >, <=, >=, !=)
|
||||
operator uint32_t() const |
||||
{ |
||||
return TotalSeconds(); |
||||
} |
||||
|
||||
// Epoch32 support
|
||||
uint32_t Epoch32Time() const |
||||
{ |
||||
return TotalSeconds() + c_Epoch32OfOriginYear; |
||||
} |
||||
void InitWithEpoch32Time(uint32_t time) |
||||
{ |
||||
_initWithSecondsFrom2000<uint32_t>(time - c_Epoch32OfOriginYear); |
||||
} |
||||
|
||||
// Epoch64 support
|
||||
uint64_t Epoch64Time() const |
||||
{ |
||||
return TotalSeconds64() + c_Epoch32OfOriginYear; |
||||
} |
||||
void InitWithEpoch64Time(uint64_t time) |
||||
{ |
||||
_initWithSecondsFrom2000<uint64_t>(time - c_Epoch32OfOriginYear); |
||||
} |
||||
|
||||
void InitWithIso8601(const char* date); |
||||
|
||||
|
||||
// convert our Day of Week to Rtc Day of Week
|
||||
// RTC Hardware Day of Week is 1-7, 1 = Monday
|
||||
static uint8_t ConvertDowToRtc(uint8_t dow) |
||||
{ |
||||
if (dow == 0) |
||||
{ |
||||
dow = 7; |
||||
} |
||||
return dow; |
||||
} |
||||
|
||||
// convert Rtc Day of Week to our Day of Week
|
||||
static uint8_t ConvertRtcToDow(uint8_t rtcDow) |
||||
{ |
||||
return (rtcDow % 7); |
||||
} |
||||
|
||||
protected: |
||||
uint8_t _yearFrom2000; |
||||
uint8_t _month; |
||||
uint8_t _dayOfMonth; |
||||
uint8_t _hour; |
||||
uint8_t _minute; |
||||
uint8_t _second; |
||||
|
||||
template <typename T> void _initWithSecondsFrom2000(T secondsFrom2000) |
||||
{ |
||||
_second = secondsFrom2000 % 60; |
||||
T timeFrom2000 = secondsFrom2000 / 60; |
||||
_minute = timeFrom2000 % 60; |
||||
timeFrom2000 /= 60; |
||||
_hour = timeFrom2000 % 24; |
||||
T days = timeFrom2000 / 24; |
||||
T leapDays; |
||||
|
||||
for (_yearFrom2000 = 0;; ++_yearFrom2000) |
||||
{ |
||||
leapDays = (_yearFrom2000 % 4 == 0) ? 1 : 0; |
||||
if (days < 365U + leapDays) |
||||
break; |
||||
days -= 365 + leapDays; |
||||
} |
||||
for (_month = 1;; ++_month) |
||||
{ |
||||
uint8_t daysPerMonth = pgm_read_byte(c_daysInMonth + _month - 1); |
||||
if (leapDays && _month == 2) |
||||
daysPerMonth++; |
||||
if (days < daysPerMonth) |
||||
break; |
||||
days -= daysPerMonth; |
||||
} |
||||
_dayOfMonth = days + 1; |
||||
} |
||||
|
||||
}; |
||||
|
||||
#endif // __RTCDATETIME_H__
|
||||
@ -0,0 +1,153 @@
@@ -0,0 +1,153 @@
|
||||
|
||||
|
||||
#ifndef __RTCTEMPERATURE_H__ |
||||
#define __RTCTEMPERATURE_H__ |
||||
|
||||
|
||||
class RtcTemperature |
||||
{ |
||||
public: |
||||
// Constructor
|
||||
// a) Merge RTC registers into signed scaled temperature (x256),
|
||||
// then bind to RTC resolution.
|
||||
// | r11h | DP | r12h |
|
||||
// Bit: 15 14 13 12 11 10 9 8 . 7 6 5 4 3 2 1 0 -1 -2
|
||||
// s i i i i i i i . f f 0 0 0 0 0 0
|
||||
//
|
||||
// b) Rescale to (x4) by right-shifting (6) bits
|
||||
// | | DP | |
|
||||
// Bit: 15 14 13 12 11 10 9 8 7 6 5 4 3 2 . 1 0 -1 -2
|
||||
// s s s s s s s i i i i i i i f f 0 0
|
||||
RtcTemperature(int8_t highByteDegreesC, uint8_t lowByteDegreesC) |
||||
{ |
||||
int16_t scaledDegC = ((highByteDegreesC << 8) | (lowByteDegreesC & 0xC0)) >> 6; |
||||
_centiDegC = scaledDegC * 100 / 4; |
||||
} |
||||
|
||||
RtcTemperature(int16_t centiDegC = 0) : |
||||
_centiDegC(centiDegC) |
||||
{ |
||||
} |
||||
|
||||
// Float temperature Celsius
|
||||
float AsFloatDegC() |
||||
{ |
||||
return (float)_centiDegC / 100.0f; |
||||
} |
||||
|
||||
// Float temperature Fahrenheit
|
||||
float AsFloatDegF() |
||||
{ |
||||
return AsFloatDegC() * 1.8f + 32.0f; |
||||
} |
||||
|
||||
// centi degrees (1/100th of a degree),
|
||||
int16_t AsCentiDegC() |
||||
{ |
||||
return _centiDegC; |
||||
} |
||||
|
||||
void Print(Stream& target, uint8_t decimals = 2, char decimal = '.') |
||||
{ |
||||
int16_t decimalDivisor = 1; |
||||
int16_t integerPart; |
||||
int16_t decimalPart; |
||||
|
||||
{ |
||||
int16_t rounded = abs(_centiDegC); |
||||
// round up as needed
|
||||
if (decimals == 0) |
||||
{ |
||||
rounded += 50; |
||||
} |
||||
else if (decimals == 1) |
||||
{ |
||||
rounded += 5; |
||||
decimalDivisor = 10; |
||||
} |
||||
|
||||
integerPart = rounded / 100; |
||||
decimalPart = (rounded % 100) / decimalDivisor; |
||||
} |
||||
|
||||
// test for zero before printing negative sign to not print-0.00
|
||||
if (_centiDegC < 0 && (integerPart != 0 || decimalPart != 0)) |
||||
{ |
||||
target.print('-'); |
||||
} |
||||
|
||||
// print integer part
|
||||
target.print(integerPart); |
||||
|
||||
// print decimal part
|
||||
if (decimals != 0) |
||||
{ |
||||
target.print(decimal); |
||||
|
||||
if (decimalPart != 0) |
||||
{ |
||||
target.print(decimalPart); |
||||
} |
||||
else |
||||
{ |
||||
// append zeros as requested
|
||||
while (decimals > 0) |
||||
{ |
||||
target.print('0'); |
||||
decimals--; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
bool operator==(const RtcTemperature& other) const |
||||
{ |
||||
return (_centiDegC == other._centiDegC); |
||||
}; |
||||
|
||||
bool operator>(const RtcTemperature& other) const |
||||
{ |
||||
return (_centiDegC > other._centiDegC); |
||||
}; |
||||
|
||||
bool operator<(const RtcTemperature& other) const |
||||
{ |
||||
return (_centiDegC < other._centiDegC); |
||||
}; |
||||
|
||||
bool operator>=(const RtcTemperature& other) const |
||||
{ |
||||
return (_centiDegC >= other._centiDegC); |
||||
}; |
||||
|
||||
bool operator<=(const RtcTemperature& other) const |
||||
{ |
||||
return (_centiDegC <= other._centiDegC); |
||||
}; |
||||
|
||||
bool operator!=(const RtcTemperature& other) const |
||||
{ |
||||
return (_centiDegC != other._centiDegC); |
||||
}; |
||||
|
||||
RtcTemperature operator-(const RtcTemperature& right) |
||||
{ |
||||
RtcTemperature result; |
||||
|
||||
result._centiDegC = (_centiDegC - right._centiDegC); |
||||
return result; |
||||
} |
||||
|
||||
RtcTemperature operator+(const RtcTemperature& right) |
||||
{ |
||||
RtcTemperature result; |
||||
|
||||
result._centiDegC = (_centiDegC + right._centiDegC); |
||||
return result; |
||||
} |
||||
|
||||
protected: |
||||
int16_t _centiDegC; // 1/100th of a degree temperature (100 x degC)
|
||||
}; |
||||
|
||||
#endif // __RTCTEMPERATURE_H__
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue