initial files checked in

This commit is contained in:
irekzielinski
2019-08-26 12:25:39 +01:00
parent 6309acb788
commit af3142174e
7 changed files with 1316 additions and 0 deletions

View File

@ -0,0 +1,113 @@
#ifndef circ_buffer_h
#define circ_buffer_h
#include <stdlib.h>
/// <summary>
/// This class allows a fixed size circular buffer.
/// When push_back is called, oldest data is overwritten.
/// Does not use any dynamic allocators.
/// </summary>
template <class ItemType, int elementCnt> class circular_buffer
{
private:
ItemType m_arr[elementCnt];
int m_writePos;
int m_size;
void advanceWritePos()
{
if(m_size < elementCnt)
{
m_size++;
}
m_writePos++;
if(m_writePos >= elementCnt)
{
m_writePos = 0;
}
}
circular_buffer(const circular_buffer<ItemType, elementCnt>& rhs);
public:
circular_buffer()
{
clear();
}
void operator=(const circular_buffer<ItemType, elementCnt>& rhs)
{
memcpy(m_arr, rhs.m_arr, sizeof(m_arr));
m_size = rhs.m_size;
m_writePos = rhs.m_writePos;
}
void push_back(const ItemType& item)
{
m_arr[m_writePos] = item;
advanceWritePos();
}
void clear()
{
memset(m_arr,0,sizeof(m_arr));
m_size = m_writePos = 0;
}
void sort()
{
if (size() < 2)
return;
bool swapped;
do
{
swapped = false;
for(int ix=0; ix<size()-1; ix++)
{
if(at(ix) > at(ix+1))
{
ItemType tmp = at(ix);
at(ix) = at(ix+1);
at(ix+1) = tmp;
swapped = true;
}
}
}while(swapped);
}
int size() const { return m_size; }
bool isFull() const { return size() == elementCnt; }
ItemType& operator[](int pos) {return at(pos);}
ItemType& at(int pos)
{
if(m_size < elementCnt)
{
return m_arr[pos];
}
int readPos = m_writePos + pos;
if(readPos >= elementCnt)
{
readPos -= elementCnt;
}
return m_arr[readPos];
}
#if _DEBUG_ENABLED
void print()
{
printf("---\n");
for(int i=0; i<size(); i++)
{
printf("%d = %d\n", i, at(i));
}
}
#endif
};
#endif //circ_buffer_h

View File

@ -0,0 +1,96 @@
#ifndef circ_log_h
#define circ_log_h
#include <TimeLib.h> //https://github.com/PaulStoffregen/Time
#include <stdlib.h>
template <int elementCnt> class circular_log
{
private:
char m_log[elementCnt];
bool removeLastFromLog()
{
char* nextLine = strstr(m_log+1, "<BR>");
if(nextLine == NULL)
{
return false;
}
int newLineLen = strlen(nextLine);
memmove(m_log, nextLine, newLineLen);
m_log[newLineLen] = '\0';
return true;
}
public:
circular_log()
{
memset(m_log, 0, sizeof(m_log));
}
const char* c_str() const { return m_log; }
int freeSpace() const { return elementCnt - strlen(m_log) - 1; }
void LogXml(const char* msg)
{
char szNew[256] = "";
snprintf(szNew, sizeof(szNew)-1, "<BR>%02d - %02d:%02d | ", day(), hour(), minute());
int ix = strlen(szNew);
while(*msg != '\0' && ix < 250)
{
if(*msg == '<')
{
szNew[ix++] = '&';
szNew[ix++] = 'l';
szNew[ix++] = 't';
szNew[ix++] = ';';
}
else if(*msg == '>')
{
szNew[ix++] = '&';
szNew[ix++] = 'g';
szNew[ix++] = 't';
szNew[ix++] = ';';
}
else
{
szNew[ix++] = *msg;
}
msg++;
}
const int newLen = strlen(szNew);
while(freeSpace() < newLen)
{
if(removeLastFromLog() == false)
{
return;
}
}
strcat(m_log, szNew);
}
void Log(const char* msg)
{
char szNew[256] = "";
snprintf(szNew, sizeof(szNew)-1, "<BR>%02d - %02d:%02d | %s", day(), hour(), minute(), msg);
const int newLen = strlen(szNew);
while(freeSpace() < newLen)
{
if(removeLastFromLog() == false)
{
return;
}
}
strcat(m_log, szNew);
}
};
#endif //circular_log_h

View File

@ -0,0 +1,81 @@
#ifndef ntp_time_h
#define ntp_time_h
#include <WiFiUdp.h>
// NTP Servers:
static const char ntpServerName[] = "0.uk.pool.ntp.org";
const int timeZone = 0;
unsigned int localPort = 8888; // local port to listen for UDP packets
/*-------- NTP code ----------*/
const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets
WiFiUDP udpNtp;
// send an NTP request to the time server at the given address
void sendNTPpacket(IPAddress &address)
{
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clock
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
udpNtp.beginPacket(address, 123); //NTP requests are to port 123
udpNtp.write(packetBuffer, NTP_PACKET_SIZE);
udpNtp.endPacket();
}
time_t getNtpTime()
{
if(WiFi.status() != WL_CONNECTED)
{
return 0;
}
static bool udpStarted = false;
if(udpStarted == false)
{
udpStarted = true;
udpNtp.begin(localPort);
}
IPAddress ntpServerIP; // NTP server's ip address
while (udpNtp.parsePacket() > 0) ; // discard any previously received packets
// get a random server from the pool
WiFi.hostByName(ntpServerName, ntpServerIP);
sendNTPpacket(ntpServerIP);
delay(100);
uint32_t beginWait = millis();
while (millis() - beginWait < 1500) {
int size = udpNtp.parsePacket();
if (size >= NTP_PACKET_SIZE) {
udpNtp.read(packetBuffer, NTP_PACKET_SIZE); // read packet into the buffer
unsigned long secsSince1900;
// convert four bytes starting at location 40 to a long integer
secsSince1900 = (unsigned long)packetBuffer[40] << 24;
secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
secsSince1900 |= (unsigned long)packetBuffer[43];
return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
}
delay(10);
}
return 0; // return 0 if unable to get the time
}
#endif //ntp_time_h

View File

@ -0,0 +1,2 @@
Visit this page for more information:
http://playground.arduino.cc/Code/SimpleTimer

View File

@ -0,0 +1,250 @@
/*
* SimpleTimer.cpp
*
* SimpleTimer - A timer library for Arduino.
* Author: mromani@ottotecnica.com
* Copyright (c) 2010 OTTOTECNICA Italy
*
* This library is free software; you can redistribute it
* and/or modify it under the terms of the GNU Lesser
* General Public License as published by the Free Software
* Foundation; either version 2.1 of the License, or (at
* your option) any later version.
*
* This library is distributed in the hope that it will
* be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser
* General Public License along with this library; if not,
* write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "SimpleTimer.h"
// Select time function:
//static inline unsigned long elapsed() { return micros(); }
static inline unsigned long elapsed() { return millis(); }
SimpleTimer::SimpleTimer()
: numTimers (-1)
{
}
void SimpleTimer::init() {
unsigned long current_millis = elapsed();
for (int i = 0; i < MAX_TIMERS; i++) {
enabled[i] = false;
callbacks[i] = 0; // if the callback pointer is zero, the slot is free, i.e. doesn't "contain" any timer
prev_millis[i] = current_millis;
numRuns[i] = 0;
}
numTimers = 0;
}
void SimpleTimer::run() {
int i;
unsigned long current_millis;
// get current time
current_millis = elapsed();
for (i = 0; i < MAX_TIMERS; i++) {
toBeCalled[i] = DEFCALL_DONTRUN;
// no callback == no timer, i.e. jump over empty slots
if (callbacks[i]) {
// is it time to process this timer ?
// see http://arduino.cc/forum/index.php/topic,124048.msg932592.html#msg932592
if (current_millis - prev_millis[i] >= delays[i]) {
// update time
//prev_millis[i] = current_millis;
prev_millis[i] += delays[i];
// check if the timer callback has to be executed
if (enabled[i]) {
// "run forever" timers must always be executed
if (maxNumRuns[i] == RUN_FOREVER) {
toBeCalled[i] = DEFCALL_RUNONLY;
}
// other timers get executed the specified number of times
else if (numRuns[i] < maxNumRuns[i]) {
toBeCalled[i] = DEFCALL_RUNONLY;
numRuns[i]++;
// after the last run, delete the timer
if (numRuns[i] >= maxNumRuns[i]) {
toBeCalled[i] = DEFCALL_RUNANDDEL;
}
}
}
}
}
}
for (i = 0; i < MAX_TIMERS; i++) {
switch(toBeCalled[i]) {
case DEFCALL_DONTRUN:
break;
case DEFCALL_RUNONLY:
(*callbacks[i])();
break;
case DEFCALL_RUNANDDEL:
(*callbacks[i])();
deleteTimer(i);
break;
}
}
}
// find the first available slot
// return -1 if none found
int SimpleTimer::findFirstFreeSlot() {
int i;
// all slots are used
if (numTimers >= MAX_TIMERS) {
return -1;
}
// return the first slot with no callback (i.e. free)
for (i = 0; i < MAX_TIMERS; i++) {
if (callbacks[i] == 0) {
return i;
}
}
// no free slots found
return -1;
}
int SimpleTimer::setTimer(long d, timer_callback f, int n) {
int freeTimer;
if (numTimers < 0) {
init();
}
freeTimer = findFirstFreeSlot();
if (freeTimer < 0) {
return -1;
}
if (f == NULL) {
return -1;
}
delays[freeTimer] = d;
callbacks[freeTimer] = f;
maxNumRuns[freeTimer] = n;
enabled[freeTimer] = true;
prev_millis[freeTimer] = elapsed();
numTimers++;
return freeTimer;
}
int SimpleTimer::setInterval(long d, timer_callback f) {
return setTimer(d, f, RUN_FOREVER);
}
int SimpleTimer::setTimeout(long d, timer_callback f) {
return setTimer(d, f, RUN_ONCE);
}
void SimpleTimer::deleteTimer(int timerId) {
if (timerId >= MAX_TIMERS) {
return;
}
// nothing to delete if no timers are in use
if (numTimers == 0) {
return;
}
// don't decrease the number of timers if the
// specified slot is already empty
if (callbacks[timerId] != NULL) {
callbacks[timerId] = 0;
enabled[timerId] = false;
toBeCalled[timerId] = DEFCALL_DONTRUN;
delays[timerId] = 0;
numRuns[timerId] = 0;
// update number of timers
numTimers--;
}
}
// function contributed by code@rowansimms.com
void SimpleTimer::restartTimer(int numTimer) {
if (numTimer >= MAX_TIMERS) {
return;
}
prev_millis[numTimer] = elapsed();
}
boolean SimpleTimer::isEnabled(int numTimer) {
if (numTimer >= MAX_TIMERS) {
return false;
}
return enabled[numTimer];
}
void SimpleTimer::enable(int numTimer) {
if (numTimer >= MAX_TIMERS) {
return;
}
enabled[numTimer] = true;
}
void SimpleTimer::disable(int numTimer) {
if (numTimer >= MAX_TIMERS) {
return;
}
enabled[numTimer] = false;
}
void SimpleTimer::toggle(int numTimer) {
if (numTimer >= MAX_TIMERS) {
return;
}
enabled[numTimer] = !enabled[numTimer];
}
int SimpleTimer::getNumTimers() {
return numTimers;
}

View File

@ -0,0 +1,126 @@
/*
* SimpleTimer.h
*
* SimpleTimer - A timer library for Arduino.
* Author: mromani@ottotecnica.com
* Copyright (c) 2010 OTTOTECNICA Italy
*
* This library is free software; you can redistribute it
* and/or modify it under the terms of the GNU Lesser
* General Public License as published by the Free Software
* Foundation; either version 2.1 of the License, or (at
* your option) any later version.
*
* This library is distributed in the hope that it will
* be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser
* General Public License along with this library; if not,
* write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef SIMPLETIMER_H
#define SIMPLETIMER_H
#if defined(ARDUINO) && ARDUINO >= 100
#include <Arduino.h>
#else
#include <WProgram.h>
#endif
typedef void (*timer_callback)(void);
class SimpleTimer {
public:
// maximum number of timers
const static int MAX_TIMERS = 10;
// setTimer() constants
const static int RUN_FOREVER = 0;
const static int RUN_ONCE = 1;
// constructor
SimpleTimer();
void init();
// this function must be called inside loop()
void run();
// call function f every d milliseconds
int setInterval(long d, timer_callback f);
// call function f once after d milliseconds
int setTimeout(long d, timer_callback f);
// call function f every d milliseconds for n times
int setTimer(long d, timer_callback f, int n);
// destroy the specified timer
void deleteTimer(int numTimer);
// restart the specified timer
void restartTimer(int numTimer);
// returns true if the specified timer is enabled
boolean isEnabled(int numTimer);
// enables the specified timer
void enable(int numTimer);
// disables the specified timer
void disable(int numTimer);
// enables the specified timer if it's currently disabled,
// and vice-versa
void toggle(int numTimer);
// returns the number of used timers
int getNumTimers();
// returns the number of available timers
int getNumAvailableTimers() { return MAX_TIMERS - numTimers; };
private:
// deferred call constants
const static int DEFCALL_DONTRUN = 0; // don't call the callback function
const static int DEFCALL_RUNONLY = 1; // call the callback function but don't delete the timer
const static int DEFCALL_RUNANDDEL = 2; // call the callback function and delete the timer
// find the first available slot
int findFirstFreeSlot();
// value returned by the millis() function
// in the previous run() call
unsigned long prev_millis[MAX_TIMERS];
// pointers to the callback functions
timer_callback callbacks[MAX_TIMERS];
// delay values
long delays[MAX_TIMERS];
// number of runs to be executed for each timer
int maxNumRuns[MAX_TIMERS];
// number of executed runs for each timer
int numRuns[MAX_TIMERS];
// which timers are enabled
boolean enabled[MAX_TIMERS];
// deferred function call (sort of) - N.B.: this array is only used in run()
int toBeCalled[MAX_TIMERS];
// actual number of timers in use
int numTimers;
};
#endif