Revert "latest :)"

This reverts commit 288a1ccd09.
This commit is contained in:
2024-01-20 15:04:46 +01:00
parent 4b9e47433f
commit 8f2516faff
4218 changed files with 1345255 additions and 209 deletions
@@ -0,0 +1,5 @@
Debug
src
__vm
.vs
node_modules
@@ -0,0 +1,51 @@
#include "Addon.h"
#include <Streaming.h>
#include <Vector.h>
#include <Arduino.h>
bool Addon::hasFlag(uchar flag)
{
return TEST(flags, flag);
}
void Addon::setFlag(uchar flag)
{
flags = SBI(flags, flag);
}
void Addon::clearFlag(uchar flag)
{
CBI(flags, flag);
}
void Addon::debug(Stream *stream)
{
}
void Addon::info(Stream *stream)
{
}
void Addon::enable()
{
this->clearFlag(DISABLED);
}
void Addon::disable()
{
this->setFlag(DISABLED);
}
bool Addon::enabled()
{
return this->hasFlag(DISABLED);
}
Addon *byId(Addons addons, uchar id)
{
uchar s = addons.size();
for (uchar i = 0; i < s; i++)
{
Addon *addon = addons[i];
if (addon->id == id)
{
return addon;
}
}
return NULL;
}
@@ -0,0 +1,72 @@
#ifndef ADDON_H
#define ADDON_H
#include <WString.h>
#include <Vector.h>
#include "enums.h"
#include "common/macros.h"
#define ADDON_NORMAL 1 << LOOP | 1 << INFO | 1 << SETUP
#ifdef HAS_STATES
#define ADDON_STATED ADDON_NORMAL | 1 << STATE
#else
#define ADDON_STATED ADDON_NORMAL
#endif
class Stream;
class Addon
{
public:
const String name;
const short id;
millis_t now;
millis_t last;
millis_t dt;
Addon(String _name, short _id) : name(_name),
id(_id),
now(0),
last(0),
dt(0)
{
flags = ADDON_NORMAL;
}
Addon(String _name, short _id, short _flags) : name(_name),
id(_id),
flags(_flags)
{
}
virtual void debug(Stream *stream);
virtual void info(Stream *stream);
virtual short setup(){};
virtual short loop(){};
virtual short ok(){};
virtual bool pause(){};
virtual bool resume(){};
virtual bool destroy(){};
virtual String state() { return ""; };
int flags;
void setFlag(uchar flag);
bool hasFlag(uchar flag);
void clearFlag(uchar flag);
void enable();
void disable();
bool enabled();
#ifdef HAS_ADDON_EEP_STORE
void save(void* store);
void restore(void* store);
#endif
};
typedef Vector<Addon *> Addons;
Addon *byId(Addons addons, uchar id);
typedef short (Addon::*AddonFnPtr)(short);
#endif
@@ -0,0 +1,26 @@
#ifndef MULTI_PID_CONTROLLER_H
#define MULTI_PID_CONTROLLER_H
#include <Arduino.h>
#include <Streaming.h>
#include "../Addon.h"
#include "../config.h"
#include "./common/macros.h"
#include "./common/ppmath.h"
class Partition;
class MultiPIDController : public Addon
{
public:
MultiPIDController() : Addon(MPID_CTRL_STR, MPIDCTRL, ADDON_STATED)
{
this->setFlag(DEBUG);
}
private:
Partition *partions[MAX_PARTITIONS];
};
#endif
@@ -0,0 +1,28 @@
#ifndef PARTITION_H
#define PARTITION_H
#include <max6675.h>
#include "./config.h"
#include "./macros.h"
#include "./time.h"
/***
* The heating cell
*/
class Partition
{
public:
ushort state; // type: PARTITION_STATE
private:
ushort pin; // GPIO
ushort id;
const char name[124]; // for logging
// computation memory
millis_t last_active;
millis_t last_duration;
Partition* next; // for prio/linking
};
#endif
@@ -0,0 +1,54 @@
/*
* Interrupt and PWM utilities for 16 bit Timer1 on ATmega168/328
* Original code by Jesse Tane for http://labs.ideo.com August 2008
* Modified March 2009 by Jérôme Despatis and Jesse Tane for ATmega328 support
* Modified June 2009 by Michael Polli and Jesse Tane to fix a bug in setPeriod() which caused the timer to stop
* Modified Oct 2009 by Dan Clemens to work with timer1 of the ATMega1280 or Arduino Mega
* Modified April 2012 by Paul Stoffregen
* Modified again, June 2014 by Paul Stoffregen
* Modified July 2017 by Stoyko Dimitrov - added support for ATTiny85 except for the PWM functionality
*
* This is free software. You can redistribute it and/or modify it under
* the terms of Creative Commons Attribution 3.0 United States License.
* To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/us/
* or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
*
*/
#include "TimerOne.h"
TimerOne Timer1; // preinstatiate
unsigned short TimerOne::pwmPeriod = 0;
unsigned char TimerOne::clockSelectBits = 0;
void (*TimerOne::isrCallback)() = TimerOne::isrDefaultUnused;
// interrupt service routine that wraps a user defined function supplied by attachInterrupt
#if defined (__AVR_ATtiny85__)
ISR(TIMER1_COMPA_vect)
{
Timer1.isrCallback();
}
#elif defined(__AVR__)
ISR(TIMER1_OVF_vect)
{
Timer1.isrCallback();
}
#elif defined(__arm__) && defined(CORE_TEENSY)
void ftm1_isr(void)
{
uint32_t sc = FTM1_SC;
#ifdef KINETISL
if (sc & 0x80) FTM1_SC = sc;
#else
if (sc & 0x80) FTM1_SC = sc & 0x7F;
#endif
Timer1.isrCallback();
}
#endif
void TimerOne::isrDefaultUnused()
{
}
@@ -0,0 +1,485 @@
/*
* Interrupt and PWM utilities for 16 bit Timer1 on ATmega168/328
* Original code by Jesse Tane for http://labs.ideo.com August 2008
* Modified March 2009 by Jérôme Despatis and Jesse Tane for ATmega328 support
* Modified June 2009 by Michael Polli and Jesse Tane to fix a bug in setPeriod() which caused the timer to stop
* Modified April 2012 by Paul Stoffregen - portable to other AVR chips, use inline functions
* Modified again, June 2014 by Paul Stoffregen - support Teensy 3.x & even more AVR chips
* Modified July 2017 by Stoyko Dimitrov - added support for ATTiny85 except for the PWM functionality
*
*
* This is free software. You can redistribute it and/or modify it under
* the terms of Creative Commons Attribution 3.0 United States License.
* To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/us/
* or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
*
*/
#ifndef TimerOne_h_
#define TimerOne_h_
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#include "config/known_16bit_timers.h"
#if defined (__AVR_ATtiny85__)
#define TIMER1_RESOLUTION 256UL // Timer1 is 8 bit
#elif defined(__AVR__)
#define TIMER1_RESOLUTION 65536UL // Timer1 is 16 bit
#else
#define TIMER1_RESOLUTION 65536UL // assume 16 bits for non-AVR chips
#endif
// Placing nearly all the code in this .h file allows the functions to be
// inlined by the compiler. In the very common case with constant values
// the compiler will perform all calculations and simply write constants
// to the hardware registers (for example, setPeriod).
class TimerOne
{
#if defined (__AVR_ATtiny85__)
public:
//****************************
// Configuration
//****************************
void initialize(unsigned long microseconds=1000000) __attribute__((always_inline)) {
TCCR1 = _BV(CTC1); //clear timer1 when it matches the value in OCR1C
TIMSK |= _BV(OCIE1A); //enable interrupt when OCR1A matches the timer value
setPeriod(microseconds);
}
void setPeriod(unsigned long microseconds) __attribute__((always_inline)) {
const unsigned long cycles = microseconds * ratio;
if (cycles < TIMER1_RESOLUTION) {
clockSelectBits = _BV(CS10);
pwmPeriod = cycles;
} else
if (cycles < TIMER1_RESOLUTION * 2UL) {
clockSelectBits = _BV(CS11);
pwmPeriod = cycles / 2;
} else
if (cycles < TIMER1_RESOLUTION * 4UL) {
clockSelectBits = _BV(CS11) | _BV(CS10);
pwmPeriod = cycles / 4;
} else
if (cycles < TIMER1_RESOLUTION * 8UL) {
clockSelectBits = _BV(CS12);
pwmPeriod = cycles / 8;
} else
if (cycles < TIMER1_RESOLUTION * 16UL) {
clockSelectBits = _BV(CS12) | _BV(CS10);
pwmPeriod = cycles / 16;
} else
if (cycles < TIMER1_RESOLUTION * 32UL) {
clockSelectBits = _BV(CS12) | _BV(CS11);
pwmPeriod = cycles / 32;
} else
if (cycles < TIMER1_RESOLUTION * 64UL) {
clockSelectBits = _BV(CS12) | _BV(CS11) | _BV(CS10);
pwmPeriod = cycles / 64UL;
} else
if (cycles < TIMER1_RESOLUTION * 128UL) {
clockSelectBits = _BV(CS13);
pwmPeriod = cycles / 128;
} else
if (cycles < TIMER1_RESOLUTION * 256UL) {
clockSelectBits = _BV(CS13) | _BV(CS10);
pwmPeriod = cycles / 256;
} else
if (cycles < TIMER1_RESOLUTION * 512UL) {
clockSelectBits = _BV(CS13) | _BV(CS11);
pwmPeriod = cycles / 512;
} else
if (cycles < TIMER1_RESOLUTION * 1024UL) {
clockSelectBits = _BV(CS13) | _BV(CS11) | _BV(CS10);
pwmPeriod = cycles / 1024;
} else
if (cycles < TIMER1_RESOLUTION * 2048UL) {
clockSelectBits = _BV(CS13) | _BV(CS12);
pwmPeriod = cycles / 2048;
} else
if (cycles < TIMER1_RESOLUTION * 4096UL) {
clockSelectBits = _BV(CS13) | _BV(CS12) | _BV(CS10);
pwmPeriod = cycles / 4096;
} else
if (cycles < TIMER1_RESOLUTION * 8192UL) {
clockSelectBits = _BV(CS13) | _BV(CS12) | _BV(CS11);
pwmPeriod = cycles / 8192;
} else
if (cycles < TIMER1_RESOLUTION * 16384UL) {
clockSelectBits = _BV(CS13) | _BV(CS12) | _BV(CS11) | _BV(CS10);
pwmPeriod = cycles / 16384;
} else {
clockSelectBits = _BV(CS13) | _BV(CS12) | _BV(CS11) | _BV(CS10);
pwmPeriod = TIMER1_RESOLUTION - 1;
}
OCR1A = pwmPeriod;
OCR1C = pwmPeriod;
TCCR1 = _BV(CTC1) | clockSelectBits;
}
//****************************
// Run Control
//****************************
void start() __attribute__((always_inline)) {
TCCR1 = 0;
TCNT1 = 0;
resume();
}
void stop() __attribute__((always_inline)) {
TCCR1 = _BV(CTC1);
}
void restart() __attribute__((always_inline)) {
start();
}
void resume() __attribute__((always_inline)) {
TCCR1 = _BV(CTC1) | clockSelectBits;
}
//****************************
// PWM outputs
//****************************
//Not implemented yet for ATTiny85
//TO DO
//****************************
// Interrupt Function
//****************************
void attachInterrupt(void (*isr)()) __attribute__((always_inline)) {
isrCallback = isr;
TIMSK |= _BV(OCIE1A);
}
void attachInterrupt(void (*isr)(), unsigned long microseconds) __attribute__((always_inline)) {
if(microseconds > 0) setPeriod(microseconds);
attachInterrupt(isr);
}
void detachInterrupt() __attribute__((always_inline)) {
//TIMSK = 0; // Timer 0 and Timer 1 both use TIMSK register so setting it to 0 will override settings for Timer1 as well
TIMSK &= ~_BV(OCIE1A);
}
static void (*isrCallback)();
static void isrDefaultUnused();
private:
static unsigned short pwmPeriod;
static unsigned char clockSelectBits;
static const byte ratio = (F_CPU)/ ( 1000000 );
#elif defined(__AVR__)
public:
//****************************
// Configuration
//****************************
void initialize(unsigned long microseconds=1000000) __attribute__((always_inline)) {
TCCR1B = _BV(WGM13); // set mode as phase and frequency correct pwm, stop the timer
TCCR1A = 0; // clear control register A
setPeriod(microseconds);
}
void setPeriod(unsigned long microseconds) __attribute__((always_inline)) {
const unsigned long cycles = (F_CPU / 2000000) * microseconds;
if (cycles < TIMER1_RESOLUTION) {
clockSelectBits = _BV(CS10);
pwmPeriod = cycles;
} else
if (cycles < TIMER1_RESOLUTION * 8) {
clockSelectBits = _BV(CS11);
pwmPeriod = cycles / 8;
} else
if (cycles < TIMER1_RESOLUTION * 64) {
clockSelectBits = _BV(CS11) | _BV(CS10);
pwmPeriod = cycles / 64;
} else
if (cycles < TIMER1_RESOLUTION * 256) {
clockSelectBits = _BV(CS12);
pwmPeriod = cycles / 256;
} else
if (cycles < TIMER1_RESOLUTION * 1024) {
clockSelectBits = _BV(CS12) | _BV(CS10);
pwmPeriod = cycles / 1024;
} else {
clockSelectBits = _BV(CS12) | _BV(CS10);
pwmPeriod = TIMER1_RESOLUTION - 1;
}
ICR1 = pwmPeriod;
TCCR1B = _BV(WGM13) | clockSelectBits;
}
//****************************
// Run Control
//****************************
void start() __attribute__((always_inline)) {
TCCR1B = 0;
TCNT1 = 0; // TODO: does this cause an undesired interrupt?
resume();
}
void stop() __attribute__((always_inline)) {
TCCR1B = _BV(WGM13);
}
void restart() __attribute__((always_inline)) {
start();
}
void resume() __attribute__((always_inline)) {
TCCR1B = _BV(WGM13) | clockSelectBits;
}
//****************************
// PWM outputs
//****************************
void setPwmDuty(char pin, unsigned int duty) __attribute__((always_inline)) {
unsigned long dutyCycle = pwmPeriod;
dutyCycle *= duty;
dutyCycle >>= 10;
if (pin == TIMER1_A_PIN) OCR1A = dutyCycle;
#ifdef TIMER1_B_PIN
else if (pin == TIMER1_B_PIN) OCR1B = dutyCycle;
#endif
#ifdef TIMER1_C_PIN
else if (pin == TIMER1_C_PIN) OCR1C = dutyCycle;
#endif
}
void pwm(char pin, unsigned int duty) __attribute__((always_inline)) {
if (pin == TIMER1_A_PIN) { pinMode(TIMER1_A_PIN, OUTPUT); TCCR1A |= _BV(COM1A1); }
#ifdef TIMER1_B_PIN
else if (pin == TIMER1_B_PIN) { pinMode(TIMER1_B_PIN, OUTPUT); TCCR1A |= _BV(COM1B1); }
#endif
#ifdef TIMER1_C_PIN
else if (pin == TIMER1_C_PIN) { pinMode(TIMER1_C_PIN, OUTPUT); TCCR1A |= _BV(COM1C1); }
#endif
setPwmDuty(pin, duty);
TCCR1B = _BV(WGM13) | clockSelectBits;
}
void pwm(char pin, unsigned int duty, unsigned long microseconds) __attribute__((always_inline)) {
if (microseconds > 0) setPeriod(microseconds);
pwm(pin, duty);
}
void disablePwm(char pin) __attribute__((always_inline)) {
if (pin == TIMER1_A_PIN) TCCR1A &= ~_BV(COM1A1);
#ifdef TIMER1_B_PIN
else if (pin == TIMER1_B_PIN) TCCR1A &= ~_BV(COM1B1);
#endif
#ifdef TIMER1_C_PIN
else if (pin == TIMER1_C_PIN) TCCR1A &= ~_BV(COM1C1);
#endif
}
//****************************
// Interrupt Function
//****************************
void attachInterrupt(void (*isr)()) __attribute__((always_inline)) {
isrCallback = isr;
TIMSK1 = _BV(TOIE1);
}
void attachInterrupt(void (*isr)(), unsigned long microseconds) __attribute__((always_inline)) {
if(microseconds > 0) setPeriod(microseconds);
attachInterrupt(isr);
}
void detachInterrupt() __attribute__((always_inline)) {
TIMSK1 = 0;
}
static void (*isrCallback)();
static void isrDefaultUnused();
private:
// properties
static unsigned short pwmPeriod;
static unsigned char clockSelectBits;
#elif defined(__arm__) && defined(CORE_TEENSY)
#if defined(KINETISK)
#define F_TIMER F_BUS
#elif defined(KINETISL)
#define F_TIMER (F_PLL/2)
#endif
public:
//****************************
// Configuration
//****************************
void initialize(unsigned long microseconds=1000000) __attribute__((always_inline)) {
setPeriod(microseconds);
}
void setPeriod(unsigned long microseconds) __attribute__((always_inline)) {
const unsigned long cycles = (F_TIMER / 2000000) * microseconds;
// A much faster if-else
// This is like a binary serch tree and no more than 3 conditions are evaluated.
// I haven't checked if this becomes significantly longer ASM than the simple ladder.
// It looks very similar to the ladder tho: same # of if's and else's
/*
// This code does not work properly in all cases :(
// https://github.com/PaulStoffregen/TimerOne/issues/17
if (cycles < TIMER1_RESOLUTION * 16) {
if (cycles < TIMER1_RESOLUTION * 4) {
if (cycles < TIMER1_RESOLUTION) {
clockSelectBits = 0;
pwmPeriod = cycles;
}else{
clockSelectBits = 1;
pwmPeriod = cycles >> 1;
}
}else{
if (cycles < TIMER1_RESOLUTION * 8) {
clockSelectBits = 3;
pwmPeriod = cycles >> 3;
}else{
clockSelectBits = 4;
pwmPeriod = cycles >> 4;
}
}
}else{
if (cycles > TIMER1_RESOLUTION * 64) {
if (cycles > TIMER1_RESOLUTION * 128) {
clockSelectBits = 7;
pwmPeriod = TIMER1_RESOLUTION - 1;
}else{
clockSelectBits = 7;
pwmPeriod = cycles >> 7;
}
}
else{
if (cycles > TIMER1_RESOLUTION * 32) {
clockSelectBits = 6;
pwmPeriod = cycles >> 6;
}else{
clockSelectBits = 5;
pwmPeriod = cycles >> 5;
}
}
}
*/
if (cycles < TIMER1_RESOLUTION) {
clockSelectBits = 0;
pwmPeriod = cycles;
} else
if (cycles < TIMER1_RESOLUTION * 2) {
clockSelectBits = 1;
pwmPeriod = cycles >> 1;
} else
if (cycles < TIMER1_RESOLUTION * 4) {
clockSelectBits = 2;
pwmPeriod = cycles >> 2;
} else
if (cycles < TIMER1_RESOLUTION * 8) {
clockSelectBits = 3;
pwmPeriod = cycles >> 3;
} else
if (cycles < TIMER1_RESOLUTION * 16) {
clockSelectBits = 4;
pwmPeriod = cycles >> 4;
} else
if (cycles < TIMER1_RESOLUTION * 32) {
clockSelectBits = 5;
pwmPeriod = cycles >> 5;
} else
if (cycles < TIMER1_RESOLUTION * 64) {
clockSelectBits = 6;
pwmPeriod = cycles >> 6;
} else
if (cycles < TIMER1_RESOLUTION * 128) {
clockSelectBits = 7;
pwmPeriod = cycles >> 7;
} else {
clockSelectBits = 7;
pwmPeriod = TIMER1_RESOLUTION - 1;
}
uint32_t sc = FTM1_SC;
FTM1_SC = 0;
FTM1_MOD = pwmPeriod;
FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_CPWMS | clockSelectBits | (sc & FTM_SC_TOIE);
}
//****************************
// Run Control
//****************************
void start() __attribute__((always_inline)) {
stop();
FTM1_CNT = 0;
resume();
}
void stop() __attribute__((always_inline)) {
FTM1_SC = FTM1_SC & (FTM_SC_TOIE | FTM_SC_CPWMS | FTM_SC_PS(7));
}
void restart() __attribute__((always_inline)) {
start();
}
void resume() __attribute__((always_inline)) {
FTM1_SC = (FTM1_SC & (FTM_SC_TOIE | FTM_SC_PS(7))) | FTM_SC_CPWMS | FTM_SC_CLKS(1);
}
//****************************
// PWM outputs
//****************************
void setPwmDuty(char pin, unsigned int duty) __attribute__((always_inline)) {
unsigned long dutyCycle = pwmPeriod;
dutyCycle *= duty;
dutyCycle >>= 10;
if (pin == TIMER1_A_PIN) {
FTM1_C0V = dutyCycle;
} else if (pin == TIMER1_B_PIN) {
FTM1_C1V = dutyCycle;
}
}
void pwm(char pin, unsigned int duty) __attribute__((always_inline)) {
setPwmDuty(pin, duty);
if (pin == TIMER1_A_PIN) {
*portConfigRegister(TIMER1_A_PIN) = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
} else if (pin == TIMER1_B_PIN) {
*portConfigRegister(TIMER1_B_PIN) = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
}
}
void pwm(char pin, unsigned int duty, unsigned long microseconds) __attribute__((always_inline)) {
if (microseconds > 0) setPeriod(microseconds);
pwm(pin, duty);
}
void disablePwm(char pin) __attribute__((always_inline)) {
if (pin == TIMER1_A_PIN) {
*portConfigRegister(TIMER1_A_PIN) = 0;
} else if (pin == TIMER1_B_PIN) {
*portConfigRegister(TIMER1_B_PIN) = 0;
}
}
//****************************
// Interrupt Function
//****************************
void attachInterrupt(void (*isr)()) __attribute__((always_inline)) {
isrCallback = isr;
FTM1_SC |= FTM_SC_TOIE;
NVIC_ENABLE_IRQ(IRQ_FTM1);
}
void attachInterrupt(void (*isr)(), unsigned long microseconds) __attribute__((always_inline)) {
if(microseconds > 0) setPeriod(microseconds);
attachInterrupt(isr);
}
void detachInterrupt() __attribute__((always_inline)) {
FTM1_SC &= ~FTM_SC_TOIE;
NVIC_DISABLE_IRQ(IRQ_FTM1);
}
static void (*isrCallback)();
static void isrDefaultUnused();
private:
// properties
static unsigned short pwmPeriod;
static unsigned char clockSelectBits;
#undef F_TIMER
#endif
};
extern TimerOne Timer1;
#endif
@@ -0,0 +1,9 @@
#ifndef VERSION_H
#define VERSION_H
#define VERSION "0.7|2f05843f89b2b8f6d75276ba363f7c2e17383e0b"
#define CID "47"
#endif
@@ -0,0 +1,59 @@
#ifndef CURRENT_SENSOR_H
#define CURRENT_SENSOR_H
#include <Arduino.h>
#include <Streaming.h>
#include "../Addon.h"
#include "../config.h"
#include "../common/macros.h"
#include "../common/ppmath.h"
class CurrentSensor : public Addon
{
public:
CurrentSensor(short _pin) : pin(_pin),
load(0),
Addon(CURRENT_SENSOR_STR, CURRENT_SENSOR)
{
// this->setFlag(DEBUG);
}
short setup()
{
pinMode(pin, INPUT);
loop();
}
short loop()
{
if (now - last > MOTOR_LOAD_READ_INTERVAL)
{
load = digitalRead(pin);
last = now;
}
return load;
}
short ok()
{
return !load;
}
void debug(Stream *stream)
{
*stream << this->name << ":" << ok();
}
void info(Stream *stream)
{
*stream << this->name << "\n\t : " SPACE("Pin:" << pin);
}
millis_t lastOverload;
protected:
short pin;
short load;
};
#endif
@@ -0,0 +1,56 @@
#ifndef DIRECTION_SWITCH_H
#define DIRECTION_SWITCH_H
#include "../config.h"
#include "../components/3PosAnalog.h"
#include "../Addon.h"
#include <Streaming.h>
#include "../common/macros.h"
class DirectionSwitch : public Addon
{
public:
Pos3Analog dir_switch;
DirectionSwitch() : dir_switch(DIR_SWITCH_UP_PIN, DIR_SWITCH_DOWN_PIN),
Addon(DIRECTION_SWITCH_STR, DIRECTION_SWITCH)
{
}
void debug(Stream *stream)
{
*stream << this->name << ":" << SPACE(dir_switch.switch_pos) << SPACE(dir_switch.last_switch);
}
void info(Stream *stream)
{
*stream << this->name << "\n\t : " SPACE("Up Pin:" << DIR_SWITCH_UP_PIN) << SPACE("\t | Down Pin :" << DIR_SWITCH_DOWN_PIN);
}
short setup()
{
dir_switch.setup();
return loop();
}
short loop()
{
if (now - dt > ANALOG_READ_INTERVAL)
{
_value = dir_switch.loop();
dt = now;
}
return _value;
}
short value()
{
return _value;
}
short last()
{
return dir_switch.last_switch;
}
private:
short _value;
};
#endif
@@ -0,0 +1,40 @@
#ifndef MOTOR_TEMPERATURE_H
#define MOTOR_TEMPERATURE_H
#include <Arduino.h>
#include "Addon.h"
#include "config.h"
#include <Streaming.h>
#include "../common/macros.h"
#include "TemperatureSensor.h"
class MotorTemperature : public Addon
{
private:
TemperatureSensor sensor;
public:
MotorTemperature() : sensor(MOTOR_TEMPERTURE_SCK_PIN, MOTOR_TEMPERTURE_CS_PIN, MOTOR_TEMPERTURE_SO_PIN, MOTOR_TEMPERTURE_MAX, MOTOR_TEMPERTURE_INTERVAL),
Addon(MOTOR_TEMPERATURE_STR, MOTOR_TEMPERATURE) {}
virtual short ok()
{
return sensor.ok();
}
void debug(Stream *stream)
{
// *stream << this->name << ":" << this->ok();
}
void info(Stream *stream)
{
/*
*stream << this->name << "\n\t : " <<
SPACE("Pin SCK:" << MOTOR_TEMPERTURE_SCK_PIN ) <<
SPACE("Pin CS :" << MOTOR_TEMPERTURE_CS_PIN ) <<
SPACE("Pin SO:" << MOTOR_TEMPERTURE_SO_PIN ) <<
SPACE("Max" << MOTOR_TEMPERTURE_MAX ) <<
SPACE("Interval" << MOTOR_TEMPERTURE_INTERVAL );
*/
}
};
#endif
@@ -0,0 +1,148 @@
#ifndef OPERATION_MODE_SWITCH_H
#define OPERATION_MODE_SWITCH_H
#ifdef HAS_STATES
#include <ArduinoJson.h>
#endif
#ifndef OP_MODE_ANALOG
#include <Bounce2.h>
#endif
#include "../config.h"
#include "../Addon.h"
#include <Streaming.h>
#include "../common/macros.h"
#include "../common/ppmath.h"
class OperationModeSwitch : public Addon
{
public:
short pin1;
#ifdef OP_MODE_ANALOG
ushort level1;
ushort level2;
ushort level3;
OperationModeSwitch(short _pin1, ushort _level1, ushort _level2, ushort _level3) : pin1(_pin1),
level1(_level1),
level2(_level2),
level3(_level3),
Addon(OPERATION_MODE_SWITCH_STR, OPERATION_MODE_SWITCH)
{
//setFlag(DEBUG);
}
#ifdef HAS_STATES
String state()
{
const int capacity = JSON_OBJECT_SIZE(2);
StaticJsonDocument<capacity> doc;
doc['0'] = id;
doc['1'] = value();
return doc.as<String>();
}
#endif
void debug(Stream *stream)
{
//*stream << this->name << SPACE(value());
}
void info(Stream *stream)
{
//*stream << this->name << "\n\t ";
}
short value()
{
ushort value = analogRead(pin1);
if (RANGE(value, level1 - 10, level1 + 10))
{
return OP_DEBUG;
}
if (RANGE(value, level2 - 10, level2 + 10))
{
return OP_NORMAL;
}
if (RANGE(value, level3 - 10, level3 + 10))
{
return OP_SERVICE;
}
return OP_NONE;
}
short setup()
{
}
short loop()
{
// Serial.println(analogRead(pin1));
}
#else
Bounce debouncer1;
Bounce debouncer2;
Bounce debouncer3;
short pin1;
short pin2;
short pin3;
OperationModeSwitch(short _pin1, short _pin2, short _pin3) : pin1(_pin1), // 1-2
pin2(_pin2), // 5-6
pin3(_pin3), // 9-10
Addon(OPERATION_MODE_SWITCH_STR, OPERATION_MODE_SWITCH)
{
}
void debug(Stream *stream)
{
*stream << this->name << ": PIN1 " << SPACE(!debouncer1.read()) << ": PIN2 " << SPACE(!debouncer2.read()) << ": PIN3 " << SPACE(!debouncer3.read());
}
void info(Stream *stream)
{
*stream << this->name << "\n\t : ";
}
short value()
{
if (!debouncer1.read())
{
return OP_DEBUG;
}
if (!debouncer2.read())
{
return OP_NORMAL;
}
if (!debouncer3.read())
{
return OP_SERVICE;
}
return OP_NONE;
}
short setup()
{
this->debouncer1 = Bounce();
this->debouncer1.attach(this->pin1, INPUT_PULLUP);
this->debouncer1.interval(25);
this->debouncer2 = Bounce();
this->debouncer2.attach(this->pin2, INPUT_PULLUP);
this->debouncer2.interval(25);
this->debouncer3 = Bounce();
this->debouncer3.attach(this->pin3, INPUT_PULLUP);
this->debouncer3.interval(25);
}
short loop()
{
this->debouncer1.update();
this->debouncer2.update();
this->debouncer3.update();
}
#endif
};
#endif
@@ -0,0 +1,30 @@
#ifndef RESET_H
#define RESET_H
// This module uses currently a normally closed momentary button.
static millis_t sw_reset_TS = 0;
static void reset_setup()
{
pinMode(RESET_PIN, INPUT_PULLUP);
sw_reset_TS = millis();
}
static void reset_loop()
{
if (millis() - sw_reset_TS > RESET_INTERVAL) {
#if RESET_NC == true
// globals.isReset = digitalRead(RESET_PIN);
#else
// globals.isReset = !digitalRead(RESET_PIN);
#endif
sw_reset_TS = millis();
// if(globals.isReset && DEBUG){
// Serial.println("reset");
// }
}
}
#endif
@@ -0,0 +1,110 @@
#ifndef STATUS_H
#define STATUS_H
#include "../addon.h"
#include "../types.h"
#include "../common/macros.h"
#include <Arduino.h>
class Status : public Addon
{
public:
Status(short _errorPin, short _okPin) : errorPin(_errorPin),
okPin(_okPin),
status_blink_TS(0),
doBlink(false),
last_blink(true),
blink_start_ts(0),
max_blink_time(HOUR_MS),
Addon(STATUS_STR, STATUS)
{
}
short setup()
{
pinMode(okPin, OUTPUT);
pinMode(errorPin, OUTPUT);
}
short loop()
{
if (now - status_blink_TS > 1000)
{
status_blink_TS = millis();
last_blink = !last_blink;
if (doBlink)
{
digitalWrite(errorPin, last_blink);
}
if (now - blink_start_ts > max_blink_time)
{
doBlink = false;
}
}
}
void status_blink(bool blink)
{
if (!doBlink && blink)
{
blink_start_ts = millis();
}
doBlink = blink;
}
void setStatusAllOn()
{
if (doBlink)
{
return;
}
digitalWrite(errorPin, HIGH);
digitalWrite(okPin, HIGH);
}
void setStatusAllOff()
{
if (doBlink)
{
return;
}
digitalWrite(errorPin, LOW);
digitalWrite(okPin, LOW);
}
void setStatus(bool error)
{
if (doBlink)
{
return;
}
if (error)
{
digitalWrite(errorPin, HIGH);
digitalWrite(okPin, LOW);
}
else
{
digitalWrite(okPin, HIGH);
digitalWrite(errorPin, LOW);
}
}
void info(Stream *stream)
{
*stream << this->name << "\n\t : " SPACE("Error Pin:" << errorPin) << SPACE("\t | Ok Pin :" << okPin);
}
private:
millis_t status_blink_TS;
bool doBlink;
bool last_blink;
millis_t blink_start_ts;
millis_t max_blink_time;
short okPin;
short errorPin;
};
#endif
@@ -0,0 +1,42 @@
#ifndef TEMPERATURE_SENSOR_H
#define TEMPERATURE_SENSOR_H
#include <max6675.h>
#include "../config.h"
#include "../macros.h"
#include "../time.h"
class TemperatureSensor
{
public:
TemperatureSensor(short sck, short cs, short so, short _max, short _interval) : ktc(MAX6675(sck, cs, so)),
temperature(),
temperature_TS(millis()),
maxTemp(_max),
interval(_interval) {}
bool ok()
{
return temperature < maxTemp;
}
void loop()
{
if (millis() - temperature_TS > interval)
{
temperature_TS = millis();
temperature = ktc.readCelsius();
}
}
private:
MAX6675 ktc;
short temperature;
short maxTemp;
short interval;
millis_t temperature_TS;
};
#endif
+192
View File
@@ -0,0 +1,192 @@
#include <Vector.h>
#include <Streaming.h>
#include <Arduino.h>
#include "app.h"
#include "features.h"
#include <MemoryFree.h>
#include "Version.h"
// #define DEBUG_MEM
static Addon *addonsArray[10];
#ifdef HAS_STATES
short App::appState(short nop)
{
uchar s = addons.size();
uchar si = 0;
String out = "";
uchar l = numByFlag(STATE);
for (uchar i = 0; i < s; i++)
{
Addon *addon = addons[i];
if (!!(addon->hasFlag(STATE)))
{
si++;
out += addon->state();
if (si < l)
{
out += ",";
}
}
}
const char *response = Bridge::CreateResponse(STATE_RESPONSE_CODE, 0, out.c_str());
Serial.write(response);
}
#endif
short App::ok()
{
return E_OK;
}
App::App() : Addon("APP", APP, 1 << STATE),
#ifdef HAS_STATUS
status(new Status(STATUS_ERROR_PIN, STATUS_OK_PIN)),
#endif
cSensor(new CurrentSensor(CURRENT_SENSOR_PIN))
{
}
short App::getAppState(short val)
{
return _state;
}
void (*resetFunction)(void) = 0; // Self reset (to be used with watchdog)
void printMem()
{
Serial.print("mem: ");
Serial.print(freeMemory());
Serial.println('--');
}
short App::setup()
{
Serial.begin(DEBUG_BAUD_RATE);
Serial.print("Booting Firmware ...................... \n\n");
Serial.print(FIRMWARE_VERSION);
Serial.print(" | ");
Serial.print(VERSION);
Serial.print(" | ");
Serial.print(CID);
Serial.println(" - \n");
addons.setStorage(addonsArray);
setup_addons();
#ifdef MEARSURE_PERFORMANCE
printPerfTS = 0;
addonLoopTime = 0;
bridgeLoopTime = 0;
#endif
debugTS = 0;
loopTS = 0;
_state = 0;
#ifdef DEBUG_MEM
timer.every(
5000, [](App *app) -> void {
printMem();
},
this);
#endif
}
void App::onError(int error)
{
if (_state != ERROR)
{
#ifdef HAS_STATUS
status->status_blink(true);
#endif
_state = ERROR;
}
}
short App::loop()
{
timer.tick();
now = millis();
loop_addons();
loop_com();
loop_pid();
delay(LOOP_DELAY);
}
void App::loop_com()
{
if (millis() - comTS > 300)
{
#if defined(HAS_BRIDGE) && defined(HAS_SERIAL)
PPSerial::Message *msg = serialBridge->read();
if (msg)
{
switch (msg->verb)
{
case Bridge::EC_METHOD:
{
char *strings[3];
char *ptr = NULL;
byte index = 0;
ptr = strtok(msg->payload, ":");
while (ptr != NULL && index < 4)
{
strings[index] = ptr;
index++;
ptr = strtok(NULL, ":");
}
int id = atoi(strings[0]);
char *_method = strings[1];
SKeyVal *method = VSL::instance()->hasMethod(id, _method);
if (method)
{
int arg = atoi(strings[2]);
Addon *addon = (Addon *)method->instance;
AddonFnPtr ptr = method->mPtr;
short ret = (addon->*ptr)(arg);
if (TEST(msg->flags, Bridge::STATE))
{
#ifdef HAS_STATES
this->appState(0);
#endif
}
else if (TEST(msg->flags, Bridge::RECEIPT))
{
#ifdef BRIDGE_HAS_RESPONSE
const char *response = Bridge::CreateResponse(msg->id, 0, ret);
Serial.write(response);
#endif
}
if (TEST(msg->flags, Bridge::DEBUG))
{
// Serial.println("Called command");
}
}
else
{
VSL::instance()->debug();
if (TEST(msg->flags, Bridge::DEBUG))
{
/*
Serial.print("Incoming message, cant find class & method ");
Serial.print(_class);
Serial.print(":");
Serial.print(_method);
Serial.print("\n");
*/
}
}
break;
}
}
msg->payload = NULL;
}
#endif
comTS = millis();
}
}
+97
View File
@@ -0,0 +1,97 @@
#ifndef APP_H
#define APP_H
#include "config.h"
#include <Vector.h>
#include "types.h"
#include "Addon.h"
#include "common/timer.h"
class DirectionSwitch;
class CurrentSensor;
class Status;
class PPSerial;
class ModbusBridge;
class App : public Addon
{
public:
App();
DirectionSwitch *dirSwitch;
CurrentSensor *cSensor;
Status *status;
PPSerial *serialBridge;
ModbusBridge *modbusBridge;
Addon *byId(short id);
short setup();
short loop();
short debug();
short info();
short ok();
void loop_service();
void loop_com();
void loop_simulate();
void loop_pid();
void loop_addons();
void setup_addons();
void onDidSetupAddons();
ushort numByFlag(ushort flag);
short shred(short value = 0);
ushort loopShred();
void loopShredCancel();
void onError(int error);
Vector<Addon *> addons;
// bridge
short setFlag(ushort addonId, ushort flag);
#ifdef HAS_STATES
short appState(short nop = 0);
String state();
#endif
millis_t loopTS;
millis_t wait;
millis_t comTS;
millis_t waitTS;
Timer<10, millis> timer; // 10 concurrent tasks, using micros as resolution
enum APP_STATE
{
RESET = 0,
REMOTE = 2,
LOCAL = 3,
TEST = 3,
ERROR = 5
};
short _state;
short _error;
short getLastError(short val = 0){
return _error;
}
short setLastError(short val = 0);
short setAppState(short newState);
short getAppState(short val);
private:
#ifdef MEARSURE_PERFORMANCE
millis_t addonLoopTime;
millis_t bridgeLoopTime;
millis_t printPerfTS;
#endif
millis_t debugTS;
};
#endif
@@ -0,0 +1,150 @@
#include <Vector.h>
#include <Streaming.h>
#include <Arduino.h>
#include "app.h"
#include "config.h"
#include "types.h"
#include "common/macros.h"
#include "Addon.h"
#include "features.h"
void App::onDidSetupAddons(){
#ifdef HAS_STATUS
status->setStatusAllOn();
delay(SECS * 2);
status->setStatusAllOff();
status->setStatus(false);
#endif
}
short App::setFlag(ushort addonId, ushort flag)
{
Addon *addon = byId(addonId);
if (addon)
{
addon->setFlag(flag);
return E_OK;
}
return ERROR_WARNING;
}
ushort App::numByFlag(ushort flag)
{
uchar s = addons.size();
uchar l = 0;
String out = "";
for (uchar i = 0; i < s; i++)
{
Addon *addon = addons[i];
if (!!(addon->hasFlag(flag)))
{
l++;
}
}
return l;
}
short App::debug()
{
#ifndef MEARSURE_PERFORMANCE
if (millis() - debugTS > DEBUG_INTERVAL)
{
uchar s = addons.size();
uchar nb = 0;
for (uchar i = 0; i < s; i++)
{
Addon *addon = addons[i];
if (addon->hasFlag(DEBUG))
{
(addon->debug)(&Serial);
Serial.println("\n");
nb++;
}
}
if (nb)
{
Serial.println("\n");
}
debugTS = millis();
}
#endif
}
short App::info()
{
Serial.print("Addon configuration : \n\n");
uchar s = addons.size();
for (uchar i = 0; i < s; i++)
{
Addon *addon = addons[i];
if (addon->hasFlag(INFO))
{
addon->info(&Serial);
Serial << "\n";
}
}
}
Addon *App::byId(short id)
{
uchar s = addons.size();
for (uchar i = 0; i < s; i++)
{
Addon *addon = addons[i];
if (addon->id == id)
{
return addon;
}
}
return NULL;
}
void App::setup_addons()
{
#ifdef HAS_STATUS
addons.push_back((Addon *)status);
#endif
addons.push_back((Addon *)cSensor);
addons.push_back((Addon *)this);
uchar s = addons.size();
for (uchar i = 0; i < s; i++)
{
Addon *addon = addons[i];
if (addon->hasFlag(SETUP))
{
addon->setup();
}
}
onDidSetupAddons();
}
void App::loop_addons()
{
#ifdef MEARSURE_PERFORMANCE
millis_t now = millis();
#endif
uchar s = addons.size();
for (uchar i = 0; i < s; i++)
{
Addon *addon = addons[i];
if (addon->hasFlag(LOOP))
{
addon->now = now;
addon->loop();
}
}
#ifdef MEARSURE_PERFORMANCE
addonLoopTime = millis() - now;
if (millis() - printPerfTS > 3000)
{
printPerfTS = now;
Serial << SPACE("Addon loop time") << addonLoopTime << "\n";
}
#endif
debug();
}
@@ -0,0 +1,2 @@
#include "app.h"
@@ -0,0 +1,161 @@
#include <PID_v1.h>
#include <PID_AutoTune_v0.h>
byte ATuneModeRemember=2;
double input=80, output=50, setpoint=180;
double kp=2,ki=0.5,kd=2;
double kpmodel=1.5, taup=100, theta[50];
double outputStart=5;
double aTuneStep=50, aTuneNoise=1, aTuneStartValue=100;
unsigned int aTuneLookBack=20;
boolean tuning = false;
unsigned long modelTime, serialTime;
PID myPID(&input, &output, &setpoint,kp,ki,kd, DIRECT);
PID_ATune aTune(&input, &output);
//set to false to connect to the real world
boolean useSimulation = true;
void setup()
{
if(useSimulation)
{
for(byte i=0;i<50;i++)
{
theta[i]=outputStart;
}
modelTime = 0;
}
//Setup the pid
myPID.SetMode(AUTOMATIC);
if(tuning)
{
tuning=false;
changeAutoTune();
tuning=true;
}
serialTime = 0;
Serial.begin(9600);
}
void loop()
{
unsigned long now = millis();
if(!useSimulation)
{ //pull the input in from the real world
input = analogRead(0);
}
if(tuning)
{
byte val = (aTune.Runtime());
if (val!=0)
{
tuning = false;
}
if(!tuning)
{ //we're done, set the tuning parameters
kp = aTune.GetKp();
ki = aTune.GetKi();
kd = aTune.GetKd();
myPID.SetTunings(kp,ki,kd);
AutoTuneHelper(false);
}
}
else myPID.Compute();
if(useSimulation)
{
theta[30]=output;
if(now>=modelTime)
{
modelTime +=100;
DoModel();
}
}
else
{
analogWrite(0,output);
}
//send-receive with processing if it's time
if(millis()>serialTime)
{
SerialReceive();
SerialSend();
serialTime+=500;
}
}
void changeAutoTune()
{
if(!tuning)
{
//Set the output to the desired starting frequency.
output=aTuneStartValue;
aTune.SetNoiseBand(aTuneNoise);
aTune.SetOutputStep(aTuneStep);
aTune.SetLookbackSec((int)aTuneLookBack);
AutoTuneHelper(true);
tuning = true;
}
else
{ //cancel autotune
aTune.Cancel();
tuning = false;
AutoTuneHelper(false);
}
}
void AutoTuneHelper(boolean start)
{
if(start)
ATuneModeRemember = myPID.GetMode();
else
myPID.SetMode(ATuneModeRemember);
}
void SerialSend()
{
Serial.print("setpoint: ");Serial.print(setpoint); Serial.print(" ");
Serial.print("input: ");Serial.print(input); Serial.print(" ");
Serial.print("output: ");Serial.print(output); Serial.print(" ");
if(tuning){
Serial.println("tuning mode");
} else {
Serial.print("kp: ");Serial.print(myPID.GetKp());Serial.print(" ");
Serial.print("ki: ");Serial.print(myPID.GetKi());Serial.print(" ");
Serial.print("kd: ");Serial.print(myPID.GetKd());Serial.println();
}
}
void SerialReceive()
{
if(Serial.available())
{
char b = Serial.read();
Serial.flush();
if((b=='1' && !tuning) || (b!='1' && tuning))changeAutoTune();
}
}
void DoModel()
{
//cycle the dead time
for(byte i=0;i<49;i++)
{
theta[i] = theta[i+1];
}
//compute the input
input = (kpmodel / taup) *(theta[0]-outputStart) + input*(1-1/taup) + ((float)random(-10,10))/100;
}
@@ -0,0 +1,196 @@
#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#include <PID_AutoTune_v0.h>
PID_ATune::PID_ATune(double* Input, double* Output)
{
input = Input;
output = Output;
controlType =0 ; //default to PI
noiseBand = 0.5;
running = false;
oStep = 30;
SetLookbackSec(10);
lastTime = millis();
}
void PID_ATune::Cancel()
{
running = false;
}
int PID_ATune::Runtime()
{
justevaled=false;
if(peakCount>9 && running)
{
running = false;
FinishUp();
return 1;
}
unsigned long now = millis();
if((now-lastTime)<sampleTime) return false;
lastTime = now;
double refVal = *input;
justevaled=true;
if(!running)
{ //initialize working variables the first time around
peakType = 0;
peakCount=0;
justchanged=false;
absMax=refVal;
absMin=refVal;
setpoint = refVal;
running = true;
outputStart = *output;
*output = outputStart+oStep;
}
else
{
if(refVal>absMax)absMax=refVal;
if(refVal<absMin)absMin=refVal;
}
//oscillate the output base on the input's relation to the setpoint
if(refVal>setpoint+noiseBand) *output = outputStart-oStep;
else if (refVal<setpoint-noiseBand) *output = outputStart+oStep;
//bool isMax=true, isMin=true;
isMax=true;isMin=true;
//id peaks
for(int i=nLookBack-1;i>=0;i--)
{
double val = lastInputs[i];
if(isMax) isMax = refVal>val;
if(isMin) isMin = refVal<val;
lastInputs[i+1] = lastInputs[i];
}
lastInputs[0] = refVal;
if(nLookBack<9)
{ //we don't want to trust the maxes or mins until the inputs array has been filled
return 0;
}
if(isMax)
{
if(peakType==0)peakType=1;
if(peakType==-1)
{
peakType = 1;
justchanged=true;
peak2 = peak1;
}
peak1 = now;
peaks[peakCount] = refVal;
}
else if(isMin)
{
if(peakType==0)peakType=-1;
if(peakType==1)
{
peakType=-1;
peakCount++;
justchanged=true;
}
if(peakCount<10)peaks[peakCount] = refVal;
}
if(justchanged && peakCount>2)
{ //we've transitioned. check if we can autotune based on the last peaks
double avgSeparation = (abs(peaks[peakCount-1]-peaks[peakCount-2])+abs(peaks[peakCount-2]-peaks[peakCount-3]))/2;
if( avgSeparation < 0.05*(absMax-absMin))
{
FinishUp();
running = false;
return 1;
}
}
justchanged=false;
return 0;
}
void PID_ATune::FinishUp()
{
*output = outputStart;
//we can generate tuning parameters!
Ku = 4*(2*oStep)/((absMax-absMin)*3.14159);
Pu = (double)(peak1-peak2) / 1000;
}
double PID_ATune::GetKp()
{
return controlType==1 ? 0.6 * Ku : 0.4 * Ku;
}
double PID_ATune::GetKi()
{
return controlType==1? 1.2*Ku / Pu : 0.48 * Ku / Pu; // Ki = Kc/Ti
}
double PID_ATune::GetKd()
{
return controlType==1? 0.075 * Ku * Pu : 0; //Kd = Kc * Td
}
void PID_ATune::SetOutputStep(double Step)
{
oStep = Step;
}
double PID_ATune::GetOutputStep()
{
return oStep;
}
void PID_ATune::SetControlType(int Type) //0=PI, 1=PID
{
controlType = Type;
}
int PID_ATune::GetControlType()
{
return controlType;
}
void PID_ATune::SetNoiseBand(double Band)
{
noiseBand = Band;
}
double PID_ATune::GetNoiseBand()
{
return noiseBand;
}
void PID_ATune::SetLookbackSec(int value)
{
if (value<1) value = 1;
if(value<25)
{
nLookBack = value * 4;
sampleTime = 250;
}
else
{
nLookBack = 100;
sampleTime = value*10;
}
}
int PID_ATune::GetLookbackSec()
{
return nLookBack * sampleTime / 1000;
}
@@ -0,0 +1,55 @@
#ifndef PID_AutoTune_v0
#define PID_AutoTune_v0
#define LIBRARY_VERSION 0.0.1
class PID_ATune
{
public:
//commonly used functions **************************************************************************
PID_ATune(double*, double*); // * Constructor. links the Autotune to a given PID
int Runtime(); // * Similar to the PID Compue function, returns non 0 when done
void Cancel(); // * Stops the AutoTune
void SetOutputStep(double); // * how far above and below the starting value will the output step?
double GetOutputStep(); //
void SetControlType(int); // * Determies if the tuning parameters returned will be PI (D=0)
int GetControlType(); // or PID. (0=PI, 1=PID)
void SetLookbackSec(int); // * how far back are we looking to identify peaks
int GetLookbackSec(); //
void SetNoiseBand(double); // * the autotune will ignore signal chatter smaller than this value
double GetNoiseBand(); // this should be acurately set
double GetKp(); // * once autotune is complete, these functions contain the
double GetKi(); // computed tuning parameters.
double GetKd(); //
private:
void FinishUp();
bool isMax, isMin;
double *input, *output;
double setpoint;
double noiseBand;
int controlType;
bool running;
unsigned long peak1, peak2, lastTime;
int sampleTime;
int nLookBack;
int peakType;
double lastInputs[101];
double peaks[10];
int peakCount;
bool justchanged;
bool justevaled;
double absMax, absMin;
double oStep;
double outputStart;
double Ku, Pu;
};
#endif
@@ -0,0 +1,121 @@
#include "bridge.h"
#include <Vector.h>
#include <Streaming.h>
#include "constants.h"
typedef struct
{
short key;
char *value;
} TAddons;
const TAddons addonsDict[]{};
static VSL *_instance;
class SKeyVal;
SKeyVal *clazzMaps[20];
Vector<SKeyVal *> clazzes;
class SKeyValS
{
public:
void *instance;
ushort id;
SKeyValS() {}
SKeyValS(void *_instance, ushort _id) : instance(_instance),
id(_id) {}
};
char *getAddonName(short key)
{
for (uchar i = 0; i < sizeof(addonsDict) / sizeof(TAddons); ++i)
{
if (addonsDict[i].key == key)
{
return addonsDict[i].value;
}
}
return NULL;
}
short getAddonKey(String name)
{
for (uchar i = 0; i < sizeof(addonsDict) / sizeof(TAddons); ++i)
{
if (name.equals(String(addonsDict[i].value)))
{
return addonsDict[i].value;
}
}
return -1;
}
void VSL::init()
{
_instance = new VSL();
clazzes.setStorage(clazzMaps);
}
VSL *VSL::instance()
{
if (!_instance)
{
VSL::init();
}
return _instance;
}
SKeyVal *VSL::hasMethod(ushort id, String methodName)
{
uchar s = clazzes.size();
for (uchar i = 0; i < s; i++)
{
SKeyVal *val = clazzes.at(i);
if (val->key == id && val->methodName.equals(methodName))
{
return val;
}
}
return NULL;
}
void VSL::debug()
{
#ifdef BRIDGE_DEBUG
uchar s = clazzes.size();
for (uchar i = 0; i < s; i++)
{
SKeyVal *val = clazzes.at(i);
Serial.print(val->className);
Serial.print(":");
Serial.print(val->methodName);
Serial.print("\n");
}
#endif
}
SKeyVal *VSL::registerMemberFunction(ushort id, Addon *clazz, char *method, AddonFnPtr ptr, char *ret)
{
SKeyVal *meth = hasMethod(id, method);
if (meth)
{
#ifdef BRIDGE_DEBUG
Serial << "Register class member: "
<< SPACE(name << "::" << method)
<< "already registered! \n";
#endif
}
else
{
#ifdef BRIDGE_DEBUG
if (!getAddonKey(name))
{
Serial.println("invalid addon key");
}
#endif
meth = new SKeyVal(id, clazz, method, ptr);
//Serial << "Register member method:"
// << SPACE(meth->className << "::" << meth->methodName)
// << "\n";
clazzes.push_back(meth);
}
}
@@ -0,0 +1,81 @@
#ifndef BRDIGE_H
#define BRIDGE_H
#include "Addon.h"
#include <WString.h>
class App;
class SKeyVal;
class SKeyValS;
class SKeyVal
{
public:
short key;
void *instance;
String methodName;
AddonFnPtr mPtr;
SKeyVal() {}
SKeyVal(ushort _key, void *_instance, String _methodName, AddonFnPtr _mPtr) : key(_key),
instance(_instance),
methodName(_methodName),
mPtr(_mPtr) {}
};
class VSL
{
public:
SKeyVal *registerMemberFunction(
ushort id,
Addon *clazz,
char *method,
AddonFnPtr ptr,
char *ret);
static void init();
static VSL *instance();
SKeyVal *VSL::hasMethod(ushort id, String method);
void debug();
};
#define REGISTER_CLASS_MEMBER_FN(id, inst, methodName, method, ret) \
{ \
VSL::instance()->registerMemberFunction(id, inst, methodName, method, "2"); \
}
#endif
namespace Bridge
{
static const char *START_STR = "<<";
static const char *END_STR = ">>";
static const char RESPONSE_DEL = ';';
static const char *CreateResponse(short id, short error, short ret)
{
static char response[1024] = {'\0'};
snprintf(response, sizeof(response), "%s%d%c%d%c%d%s\r", START_STR, id, RESPONSE_DEL, error, RESPONSE_DEL, ret, END_STR);
return response;
}
static const char *CreateResponse(short id, short error, const char *ret)
{
static char response[1024] = {'\0'};
snprintf(response, sizeof(response), "%s%d%c%d%c%s%s\r", START_STR, id, RESPONSE_DEL, error, RESPONSE_DEL, ret, END_STR);
return response;
}
enum ECALLS
{
EC_COMMAND = 1,
EC_METHOD = 2,
EC_FUNC = 3,
EC_USER = 10
};
enum MessageFlags
{
NEW = 1,
PROCESSING = 2,
PROCESSED = 3,
DEBUG = 4,
RECEIPT = 5,
STATE = 6
};
} // namespace Bridge
@@ -0,0 +1,512 @@
#ifndef PIN_H
#define PIN_H
// this class doesn't outperform fastgpio but is works with AtmelMega
#include <Arduino.h>
#define DDR_HIGH (*_DDR |= _offset) ///< Set the DDR register to HIGH for the pin
#define DDR_TOGGLE (*_DDR ^= _offset) ///< Set the DDR register to the inverse for the pin
#define DDR_LOW (*_DDR &= _ioffset) ///< Set the DDR register to LOW for the pin
#define PORT_HIGH (*_PORT |= _offset) ///< Set the PORT register to HIGH for the pin
#define PORT_TOGGLE (*_PORT ^= _offset) ///< Set the PORT register to the inverse for the pin
#define PORT_LOW (*_PORT &= _ioffset) ///< Set the PORT register to LOW for the pin
#define DDR_ON (*_DDR & _offset) ///< Get the DDR register for the pin (HIGH, LOW) with other pins forced to 0
#define DDR_OFF (*_DDR | _ioffset) ///< Get the DDR register for the pin (HIGH, LOW) with other pins forced to 1
#define PORT_ON (*_PORT & _offset) ///< Get the PORT register for the pin (HIGH, LOW) with other pins forced to 0
#define PORT_OFF (*_PORT | _ioffset) ///< Get the PORT register for the pin (HIGH, LOW) with other pins forced to 1
#define PIN_ON (*_PIN & _offset) ///< Get the PIN register for the pin (HIGH, LOW) with other pins forced to 0
#define PIN_OFF (*_PIN | _ioffset) ///< Get the PIN register for the pin (HIGH, LOW) with other pins forced to 1
class Pin
{
public:
Pin(uint8_t number)
{
_number = number;
_offset = digitalPinToBitMask(_number);
_ioffset = ~_offset;
_timer = digitalPinToTimer(_number);
_PIN = portInputRegister(digitalPinToPort(_number));
_PORT = portOutputRegister(digitalPinToPort(_number));
_DDR = portModeRegister(digitalPinToPort(_number));
}
/**
Custom board constructor
getAnalogValue() and setDutyCycle(int value) not supported
@param number pin number written on board
@param offset bit mask used to access pin in registers
@param timer timer for pin
@param PIN input register for pin
@param PORT data register for pin
@param DDR data direction register for pin
*/
Pin(uint8_t number, uint8_t offset, uint8_t timer, volatile uint8_t *PIN, volatile uint8_t *PORT, volatile uint8_t *DDR)
{
_number = number;
_offset = offset;
_ioffset = ~_offset;
_timer = timer;
_PIN = PIN;
_PORT = PORT;
_DDR = DDR;
}
// ################################# Operators #################################
/**
Get the value of the pin from the PIN register
@return true if the value of the pin is HIGH, false otherwise
*/
operator bool() const
{
return bool(PIN_ON);
}
/**
Set the pin state
@param state the state of the pin (HIGH, LOW)
*/
Pin &operator=(uint8_t state)
{
uint8_t oldSREG = SREG;
cli();
if (state == LOW)
{
PORT_LOW;
}
else
{
PORT_HIGH;
}
SREG = oldSREG;
return *this;
}
// ################################# Getters #################################
/**
Get the pin number
@return pin number
*/
uint8_t getNumber()
{
return _number;
}
/**
Get the pin offset
@return pin offset
*/
uint8_t getOffset()
{
return _offset;
}
/**
Get the inverse pin offset
@return inverse pin offset
*/
uint8_t getInverseOffset()
{
return _ioffset;
}
/**
Get the pin timer
@return pin timer
*/
uint8_t getTimer()
{
return _timer;
}
/**
Get a pointer to the PIN register
@return pointer to the PIN register
*/
volatile uint8_t *getPIN()
{
return _PIN;
}
/**
Get a pointer to the PORT register
@return pointer to the PORT register
*/
volatile uint8_t *getPORT()
{
return _PORT;
}
/**
Get a pointer to the DDR register
@return pointer to the DDR register
*/
volatile uint8_t *getDDR()
{
return _DDR;
}
/**
Get the mode of the pin from the DDR register
@return mode of the pin (OUTPUT, INPUT)
*/
uint8_t getMode()
{
if (DDR_ON)
{
return OUTPUT;
}
else
{
return INPUT;
}
}
/**
Get the state of the pin from the PORT register
@return state of the pin (HIGH, LOW)
*/
uint8_t getState()
{
if (PORT_ON)
{
return HIGH;
}
else
{
return LOW;
}
}
/**
Get the value of the pin from the PIN register
@return value of the pin (HIGH, LOW)
*/
uint8_t getValue()
{
if (PIN_ON)
{
return HIGH;
}
else
{
return LOW;
}
}
/**
Get the analog value of the pin
@return analog value of the pin (0-1023)
*/
uint16_t getAnalogValue()
{
return analogRead(_number);
}
/**
Set the pin mode and pin state
@param mode the mode of the pin (OUTPUT, INPUT)
@param state the state of the pin (HIGH, LOW)
*/
void set(uint8_t mode, uint8_t state)
{
uint8_t oldSREG = SREG;
cli();
if (mode == INPUT)
{
DDR_LOW;
}
else
{
DDR_HIGH;
}
if (state == LOW)
{
PORT_LOW;
}
else
{
PORT_HIGH;
}
SREG = oldSREG;
}
/**
Set the pin mode
@param mode the mode of the pin (OUTPUT, INPUT)
*/
void setMode(uint8_t mode)
{
uint8_t oldSREG = SREG;
cli();
if (mode == INPUT)
{
DDR_LOW;
}
else
{
DDR_HIGH;
}
SREG = oldSREG;
}
/**
Set the pin state
@param state the state of the pin (HIGH, LOW)
*/
void setState(uint8_t state)
{
uint8_t oldSREG = SREG;
cli();
if (state == LOW)
{
PORT_LOW;
}
else
{
PORT_HIGH;
}
SREG = oldSREG;
}
// #################### Input ####################
void setInput()
{
uint8_t oldSREG = SREG;
cli();
DDR_LOW;
SREG = oldSREG;
}
/**
Set the pin pullup resistor to on
*/
void setPullupOn()
{
uint8_t oldSREG = SREG;
cli();
PORT_HIGH;
SREG = oldSREG;
}
/**
Set the pin pullup resistor to off
*/
void setPullupOff()
{
uint8_t oldSREG = SREG;
cli();
PORT_LOW;
SREG = oldSREG;
}
/**
Set the pin mode to input and the pin pullup resistor to on
*/
void setInputPullupOn()
{
uint8_t oldSREG = SREG;
cli();
DDR_LOW;
PORT_HIGH;
SREG = oldSREG;
}
/**
Set the pin mode to input and the pin pullup resistor to off
*/
void setInputPullupOff()
{
uint8_t oldSREG = SREG;
cli();
DDR_LOW;
PORT_LOW;
SREG = oldSREG;
}
// #################### Output ####################
/**
Set the pin mode to output
*/
void setOutput()
{
uint8_t oldSREG = SREG;
cli();
DDR_HIGH;
SREG = oldSREG;
}
/**
Set the pin output to HIGH
*/
void setHigh()
{
uint8_t oldSREG = SREG;
cli();
PORT_HIGH;
SREG = oldSREG;
}
/**
Set the pin output to LOW
*/
void setLow()
{
uint8_t oldSREG = SREG;
cli();
PORT_LOW;
SREG = oldSREG;
}
/**
Set the pin mode to output and the pin output to HIGH
*/
void setOutputHigh()
{
uint8_t oldSREG = SREG;
cli();
DDR_HIGH;
PORT_HIGH;
SREG = oldSREG;
}
/**
Set the pin mode to output and the pin output to LOW
*/
void setOutputLow()
{
uint8_t oldSREG = SREG;
cli();
DDR_HIGH;
PORT_LOW;
SREG = oldSREG;
}
/**
Set the PWM duty cycle
@param value the duty cycle (0-255)
*/
void setDutyCycle(int value)
{
analogWrite(_number, value);
}
// ################################# Utilities #################################
/**
Toggle the pin mode (OUTPUT -> INPUT, INPUT -> OUTPUT)
*/
void toggleMode()
{
uint8_t oldSREG = SREG;
cli();
DDR_TOGGLE;
SREG = oldSREG;
}
/**
Toggle the pin state (HIGH -> LOW, LOW -> HIGH)
*/
void toggleState()
{
uint8_t oldSREG = SREG;
cli();
PORT_TOGGLE;
SREG = oldSREG;
}
// #################### RC Timer ####################
/**
Set the pin mode to input and decrement a counter until the pin goes HIGH or the counter reaches 0 then set the pin mode to output and return the counter value
@param count the initial value for the counter to start at (0-65535)
@return the value remaining on the counter when the pin state went to HIGH or 0 if the counter reached 0
*/
volatile unsigned int rcTimer(volatile unsigned int count)
{
uint8_t status;
asm volatile(
// Save interupt status and disable interupts
"in %[status], __SREG__ \n\t" // Store current interupt status in variable 's'
"cli \n\t" // Disable interupts
// Set Pin to input mode to start charging capacitor
"ld __tmp_reg__, %a[_DDR] \n\t" // Load the DDR register into r0 (__tmp_reg__)
"and __tmp_reg__, %[_ioffset] \n\t" // Apply the bit mask (offset) to r0 (__tmp_reg__)
"st %a[_DDR], __tmp_reg__ \n\t" // Store r0 (__tmp_reg__) in the DDR register
// Count time before Pin becomes high
"loop%=: \n\t" // Label for looping
//"ld __tmp_reg__,%a[_PIN] \n\t" // Load the PIN register into r0 (__tmp_reg__)
"and __tmp_reg__, %[_offset] \n\t" // Apply the bit mask (offset) to r0 (__tmp_reg__)
"brne end%= \n\t" // End the loop if r0 (__tmp_reg__) is not equal to zero by branching to label 'end'
"dec %[count] \n\t" // Decrement the value of 'count' by one
"brne loop%= \n\t" // If the value of 'count' is not equal to zero continue the loop by branching to label 'loop'
// Done counting
"end%=: \n\t" // Label for ending loop
// Set Pin to output mode to start discharging capacitor
"ld __tmp_reg__, %a[_DDR] \n\t" // Load the DDR register into r0 (__tmp_reg__)
"or __tmp_reg__, %[_offset] \n\t" // Apply the bit mask (offset) to r0 (__tmp_reg__)
"st %a[_DDR], __tmp_reg__ \n\t" // Store r0 (__tmp_reg__) in the PORT register
// Restore interupt status
"out __SREG__, %[status] \n\t" // Load interupt status from variable 's'
// Outputs
:
[ count ] "+r"(count), // The value the counter was at when the pin went high
[ status ] "=&r"(status) // The interupt status
// Inputs
:
[ _DDR ] "e"(_DDR), // The address of the DDR register for the pin
[ _PIN ] "e"(_PIN), // The address of the PIN register for the pin
[ _offset ] "r"(_offset), // The bit mask used to access pin in registers
[ _ioffset ] "r"(_ioffset) // The inverse bit mask used to access pin in registers
);
return count;
}
private:
uint8_t _number;
uint8_t _offset;
uint8_t _ioffset;
uint8_t _timer;
volatile uint8_t *_PIN;
volatile uint8_t *_PORT;
volatile uint8_t *_DDR;
};
#endif
@@ -0,0 +1,469 @@
#ifndef PIN_GROUP_H
#define PIN_GROUP_H
#include "Pin.h"
/**
Class for simultaneous operations on Arduino I/O pins
*/
class PinGroup
{
public:
template <size_t N>
PinGroup(Pin (&pins)[N])
{
_offset = pins[0].getOffset();
_PIN = pins[0].getPIN();
_PORT = pins[0].getPORT();
_DDR = pins[0].getDDR();
_numbers[0] = pins[0].getNumber();
_valid = true;
for (int i = 1; i < N; i++)
{
if (_DDR != pins[i].getDDR())
{
_valid = false;
}
_offset |= pins[i].getOffset();
_numbers[i] = pins[i].getNumber();
}
_ioffset = ~_offset;
}
// ################################# Operators #################################
/**
Compare the value of the pin
@param value the state of the pin (HIGH, LOW)
@return true if the value of all of the pins are equal to the value passed in, false otherwise
*/
bool operator==(uint8_t value)
{
uint8_t status = *_PIN;
if ((status & _offset) == _offset)
{
return (value == HIGH);
}
else if ((status | _ioffset) == _ioffset)
{
return (value == LOW);
}
else
{
return false;
}
}
/**
Compare the value of the pin
@param value the state of the pin (HIGH, LOW)
@return true if the value of all of the pins are not equal to the value passed in, false otherwise
*/
bool operator!=(uint8_t value)
{
uint8_t status = *_PIN;
if ((status & _offset) == _offset)
{
return (value == LOW);
}
else if ((status | _ioffset) == _ioffset)
{
return (value == HIGH);
}
else
{
return false;
}
}
/**
Set the pin state
@param state the state of the pin (HIGH, LOW)
*/
PinGroup &operator=(uint8_t state)
{
oldSREG = SREG;
cli();
if (state == LOW)
{
PORT_LOW;
}
else
{
PORT_HIGH;
}
SREG = oldSREG;
return *this;
}
// ################################# Getters #################################
/**
Get the pin numbers
@return array of pin numbers
*/
uint8_t *getNumbers()
{
return _numbers;
}
/**
Get the pin offset
@return pin offset
*/
uint8_t getOffset()
{
return _offset;
}
/**
Get the inverse pin offset
@return inverse pin offset
*/
uint8_t getInverseOffset()
{
return _ioffset;
}
/**
Get a pointer to the PIN register
@return pointer to the PIN register
*/
volatile uint8_t *getPIN()
{
return _PIN;
}
/**
Get a pointer to the PORT register
@return pointer to the PORT register
*/
volatile uint8_t *getPORT()
{
return _PORT;
}
/**
Get a pointer to the DDR register
@return pointer to the DDR register
*/
volatile uint8_t *getDDR()
{
return _DDR;
}
/**
Get the mode of the pin from the DDR register
@return mode of the pin (OUTPUT, INPUT, -1)
*/
uint8_t getMode()
{
uint8_t status = *_DDR;
if ((status & _offset) == _offset)
{
return OUTPUT;
}
else if ((status | _ioffset) == _ioffset)
{
return INPUT;
}
else
{
return -1;
}
}
/**
Get the state of the pin from the PORT register
@return state of the pin (HIGH, LOW, -1)
*/
uint8_t getState()
{
uint8_t status = *_PORT;
if ((status & _offset) == _offset)
{
return HIGH;
}
else if ((status | _ioffset) == _ioffset)
{
return LOW;
}
else
{
return -1;
}
}
/**
Get the value of the pin from the PIN register
@return value of the pin (HIGH, LOW, -1)
*/
uint8_t getValue()
{
uint8_t status = *_PIN;
if ((status & _offset) == _offset)
{
return HIGH;
}
else if ((status | _ioffset) == _ioffset)
{
return LOW;
}
else
{
return -1;
}
}
/**
Check the group to ensure all pins use the same registers
@return true if the pins in the group all use the same registers, false otherwise
*/
bool isValid()
{
return _valid;
}
// ################################# Setters #################################
// #################### Generic ####################
/**
Set the pin mode and pin state
@param mode the mode of the pin (OUTPUT, INPUT)
@param state the state of the pin (HIGH, LOW)
*/
void set(uint8_t mode, uint8_t state)
{
oldSREG = SREG;
cli();
if (mode == INPUT)
{
DDR_LOW;
}
else
{
DDR_HIGH;
}
if (state == LOW)
{
PORT_LOW;
}
else
{
PORT_HIGH;
}
SREG = oldSREG;
}
/**
Set the pin mode
@param mode the mode of the pin (OUTPUT, INPUT)
*/
void setMode(uint8_t mode)
{
oldSREG = SREG;
cli();
if (mode == INPUT)
{
DDR_LOW;
}
else
{
DDR_HIGH;
}
SREG = oldSREG;
}
/**
Set the pin state
@param state the state of the pin (HIGH, LOW)
*/
void setState(uint8_t state)
{
oldSREG = SREG;
cli();
if (state == LOW)
{
PORT_LOW;
}
else
{
PORT_HIGH;
}
SREG = oldSREG;
}
// #################### Input ####################
/**
Set the pin mode to input
*/
void setInput()
{
oldSREG = SREG;
cli();
DDR_LOW;
SREG = oldSREG;
}
/**
Set the pin pullup resistor to on
*/
void setPullupOn()
{
oldSREG = SREG;
cli();
PORT_HIGH;
SREG = oldSREG;
}
/**
Set the pin pullup resistor to off
*/
void setPullupOff()
{
oldSREG = SREG;
cli();
PORT_LOW;
SREG = oldSREG;
}
/**
Set the pin mode to input and the pin pullup resistor to on
*/
void setInputPullupOn()
{
oldSREG = SREG;
cli();
DDR_LOW;
PORT_HIGH;
SREG = oldSREG;
}
/**
Set the pin mode to input and the pin pullup resistor to off
*/
void setInputPullupOff()
{
oldSREG = SREG;
cli();
DDR_LOW;
PORT_LOW;
SREG = oldSREG;
}
// #################### Output ####################
/**
Set the pin mode to output
*/
void setOutput()
{
oldSREG = SREG;
cli();
DDR_HIGH;
SREG = oldSREG;
}
/**
Set the pin output to HIGH
*/
void setHigh()
{
oldSREG = SREG;
cli();
PORT_HIGH;
SREG = oldSREG;
}
/**
Set the pin output to LOW
*/
void setLow()
{
oldSREG = SREG;
cli();
PORT_LOW;
SREG = oldSREG;
}
/**
Set the pin mode to output and the pin output to HIGH
*/
void setOutputHigh()
{
oldSREG = SREG;
cli();
DDR_HIGH;
PORT_HIGH;
SREG = oldSREG;
}
/**
Set the pin mode to output and the pin output to LOW
*/
void setOutputLow()
{
oldSREG = SREG;
cli();
DDR_HIGH;
PORT_LOW;
SREG = oldSREG;
}
// ################################# Utilities #################################
// #################### Toggle ####################
/**
Toggle the pin mode (OUTPUT -> INPUT, INPUT -> OUTPUT)
*/
void toggleMode()
{
oldSREG = SREG;
cli();
DDR_TOGGLE;
SREG = oldSREG;
}
/**
Toggle the pin state (HIGH -> LOW, LOW -> HIGH)
*/
void toggleState()
{
oldSREG = SREG;
cli();
PORT_TOGGLE;
SREG = oldSREG;
}
private:
uint8_t _numbers[8];
uint8_t _offset;
uint8_t _ioffset;
bool _valid;
uint8_t oldSREG;
volatile uint8_t *_PIN;
volatile uint8_t *_PORT;
volatile uint8_t *_DDR;
};
@@ -0,0 +1,98 @@
#ifndef MACROS_H
#define MACROS_H
#include "../types.h"
// Macros for adding
#define INC_0 1
#define INC_1 2
#define INC_2 3
#define INC_3 4
#define INC_4 5
#define INC_5 6
#define INC_6 7
#define INC_7 8
#define INC_8 9
#define INCREMENT_(n) INC_ ##n
#define INCREMENT(n) INCREMENT_(n)
// Macros for subtracting
#define DEC_1 0
#define DEC_2 1
#define DEC_3 2
#define DEC_4 3
#define DEC_5 4
#define DEC_6 5
#define DEC_7 6
#define DEC_8 7
#define DEC_9 8
#define DECREMENT_(n) DEC_ ##n
#define DECREMENT(n) DECREMENT_(n)
// compiler - & C quirks
#define FORCE_INLINE __attribute__((always_inline)) inline
#define _UNUSED __attribute__((unused))
// fallback noop
#define NOOP do{} while(0)
//Option testing
#define _CAT(a, ...) a ## __VA_ARGS__
#define SWITCH_ENABLED_ 1
#define ENABLED(b) _CAT(SWITCH_ENABLED_, b)
// time
#define PENDING(NOW,SOON) ((long)(NOW-(SOON))<0)
#define ELAPSED(NOW,SOON) (!PENDING(NOW,SOON))
#define MMM_TO_MMS(MM_M) ((MM_M)/60.0f)
#define MMS_TO_MMM(MM_S) ((MM_S)*60.0f)
#define HOUR_MS ((millis_t)1000 * (millis_t)(60 * 60))
#define MIN_MS ((millis_t)1000 * (millis_t)(60))
#define SECS ((millis_t)1000)
// bit masks
#undef _BV
#define _BV(b) (1 << (b))
#define TEST(n,b) !!((n)&_BV(b))
#define SBI(n,b) (n |= _BV(b))
#define CBI(n,b) (n &= ~_BV(b))
#define SET_BIT_TO(N,B,TF) do{ if (TF) SBI(N,B); else CBI(N,B); }while(0)
#define _BV32(b) (1UL << (b))
#define TEST32(n,b) !!((n)&_BV32(b))
#define SBI32(n,b) (n |= _BV32(b))
#define CBI32(n,b) (n &= ~_BV32(b))
#define SIGN(a) ((a>0)-(a<0))
// math basics
#define WITHIN(V,L,H) ((V) >= (L) && (V) <= (H))
#define NUMERIC(a) WITHIN(a, '0', '9')
#define DECIMAL(a) (NUMERIC(a) || a == '.')
#define NUMERIC_SIGNED(a) (NUMERIC(a) || (a) == '-' || (a) == '+')
#define DECIMAL_SIGNED(a) (DECIMAL(a) || (a) == '-' || (a) == '+')
#define COUNT(a) (sizeof(a)/sizeof(*a))
#define ZERO(a) memset(a,0,sizeof(a))
#define COPY(a,b) memcpy(a,b,MIN(sizeof(a),sizeof(b)))
// #define M_PI 3.14159265358979323846f
#define RADIANS(d) ((d)*M_PI/180.0f)
#define DEGREES(r) ((r)*180.0f/M_PI)
#define CEILING(x,y) (((x) + (y) - 1) / (y))
// Macros for initializing arrays
#define ARRAY_6(v1, v2, v3, v4, v5, v6, ...) { v1, v2, v3, v4, v5, v6 }
#define ARRAY_5(v1, v2, v3, v4, v5, ...) { v1, v2, v3, v4, v5 }
#define ARRAY_4(v1, v2, v3, v4, ...) { v1, v2, v3, v4 }
#define ARRAY_3(v1, v2, v3, ...) { v1, v2, v3 }
#define ARRAY_2(v1, v2, ...) { v1, v2 }
#define ARRAY_1(v1, ...) { v1 }
#define _ARRAY_N(N, ...) ARRAY_ ##N(__VA_ARGS__)
#define ARRAY_N(N, ...) _ARRAY_N(N, __VA_ARGS__)
#define SPACE(A) " " << A << " "
#endif
@@ -0,0 +1,14 @@
#ifndef PPMATH_H
#define PPMATH_H
template <typename T>
T clamp(const T &value, const T &low, const T &high)
{
return value < low ? low : (value > high ? high : value);
}
#define RANGE(i, min, max) ((i > min) && (i < max)) ? true : false
#define NCLAMP(x, min, max) (x - min) / (max - min)
#endif
@@ -0,0 +1,136 @@
#ifndef TIMER_H
#define TIMER_H
#if defined(ARDUINO) && ARDUINO >= 100
#include <Arduino.h>
#else
#include <WProgram.h>
#endif
#include "macros.h"
#ifndef TIMER_MAX_TASKS
#define TIMER_MAX_TASKS 0x10
#endif
template <
size_t max_tasks = TIMER_MAX_TASKS, /* max allocated tasks */
unsigned long (*time_func)() = millis /* time function for timer */
>
class Timer
{
public:
typedef bool (*handler_t)(void *opaque); /* task handler func signature */
/* Calls handler with opaque as argument in delay units of time */
bool
in(unsigned long delay, handler_t h, void *opaque = NULL)
{
return add_task(time_func(), delay, h, opaque);
}
/* Calls handler with opaque as argument at time */
bool
at(unsigned long time, handler_t h, void *opaque = NULL)
{
const unsigned long now = time_func();
return add_task(now, time - now, h, opaque);
}
/* Calls handler with opaque as argument every interval units of time */
bool
every(unsigned long interval, handler_t h, void *opaque = NULL)
{
return add_task(time_func(), interval, h, opaque, interval);
}
/* Ticks the timer forward - call this function in loop() */
void
tick()
{
tick(time_func());
}
/* Ticks the timer forward - call this function in loop() */
inline void
tick(unsigned long t)
{
for (size_t i = 0; i < max_tasks; ++i)
{
struct task *const task = &tasks[i];
const unsigned long duration = t - task->start;
if (task->handler && duration >= task->expires)
{
task->repeat = task->handler(task->opaque) && task->repeat;
if (task->repeat)
task->start = t;
else
remove(task);
}else{
}
}
}
private:
struct task
{
handler_t handler; /* task handler callback func */
void *opaque; /* argument given to the callback handler */
unsigned long start,
expires, /* when the task expires */
repeat; /* repeat task */
} tasks[max_tasks];
inline void
remove(struct task *task)
{
task->handler = NULL;
task->opaque = NULL;
task->start = 0;
task->expires = 0;
task->repeat = 0;
}
inline struct task *
next_task_slot()
{
for (size_t i = 0; i < max_tasks; ++i)
{
struct task *const slot = &tasks[i];
if (slot->handler == NULL)
return slot;
}
return NULL;
}
inline struct task *
add_task(unsigned long start, unsigned long expires,
handler_t h, void *opaque, bool repeat = 0)
{
struct task *const slot = next_task_slot();
if (!slot){
return NULL;
}
slot->handler = h;
slot->opaque = opaque;
slot->start = start;
slot->expires = expires;
slot->repeat = repeat;
return slot;
}
};
/* create a timer with the default settings */
inline Timer<>
timer_create_default()
{
return Timer<>();
}
#endif
@@ -0,0 +1,80 @@
#ifndef POS3_ANALOG_H
#define POS3_ANALOG_H
#include <Arduino.h>
#include "../enums.h"
#include "../common/ppmath.h"
class Pos3Analog
{
public:
Pos3Analog(short _upPin, short _downPin) : upPin(_upPin), downPin(_downPin)
{
}
short setup()
{
pinMode(upPin, INPUT_PULLUP);
pinMode(downPin, INPUT_PULLUP);
last_switch = loop();
return 0;
}
short loop()
{
uchar newDirection = this->read();
if (newDirection != this->switch_pos)
{
this->last_switch = this->switch_pos;
}
this->switch_pos = newDirection;
return this->switch_pos;
}
short last_switch = -1; // Track last switch position
short switch_pos = -1; // Current switch position
short upPin;
short downPin;
private:
uchar read()
{
bool up = RANGE(analogRead(upPin), 240, 260);
bool down = RANGE(analogRead(downPin), 240, 260);
uchar newDirection = 0;
if (up)
{
newDirection = POS3_DIRECTION::UP;
}
if (down)
{
newDirection = POS3_DIRECTION::DOWN;
}
if (!up && !down)
{
newDirection = POS3_DIRECTION::MIDDLE;
}
if (up && down)
{
newDirection = POS3_DIRECTION::INVALID;
}
return newDirection;
}
bool changed()
{
return last_switch != switch_pos;
}
bool clear()
{
return last_switch = switch_pos;
}
};
#endif
@@ -0,0 +1,81 @@
#ifndef POS3_H
#define POS3_H
#include <Bounce2.h>
#include "../enums.h"
class Pos3
{
public:
Pos3(int _upPin, int _downPin) : upPin(_upPin), downPin(_downPin)
{
}
int setup()
{
this->debouncerUp = Bounce();
this->debouncerUp.attach(this->upPin, INPUT_PULLUP);
this->debouncerUp.interval(25);
this->debouncerDown = Bounce();
this->debouncerDown.attach(this->downPin, INPUT_PULLUP);
this->debouncerDown.interval(25);
return 0;
}
int loop()
{
int newDirection = this->read();
if (newDirection != this->switch_pos)
{
this->last_switch = this->switch_pos;
}
this->switch_pos = newDirection;
return this->switch_pos;
}
int last_switch = -1; // Track last switch position
int switch_pos = -1; // Current switch position
protected:
int upPin;
int downPin;
Bounce debouncerUp;
Bounce debouncerDown;
private:
int read()
{
this->debouncerUp.update();
this->debouncerDown.update();
bool up = this->debouncerUp.read() == 0 ? true : false;
bool down = this->debouncerDown.read() == 0 ? true : false;
int newDirection = 0;
if (up)
{
newDirection = POS3_DIRECTION::UP;
}
if (down)
{
newDirection = POS3_DIRECTION::DOWN;
}
if (!up && !down)
{
newDirection = POS3_DIRECTION::MIDDLE;
}
if (up && down)
{
newDirection = POS3_DIRECTION::INVALID;
}
return newDirection;
}
};
#endif
@@ -0,0 +1,42 @@
#ifndef TEMPERATURE_SENSOR_H
#define TEMPERATURE_SENSOR_H
#include <max6675.h>
#include "../config.h"
#include "../macros.h"
#include "../time.h"
class TemperatureSensor
{
public:
TemperatureSensor(short sck, short cs, short so, short _max, short _interval) : ktc(MAX6675(sck, cs, so)),
temperature(),
temperature_TS(millis()),
maxTemp(_max),
interval(_interval) {}
bool ok()
{
return temperature < maxTemp;
}
void loop()
{
if (millis() - temperature_TS > interval)
{
temperature_TS = millis();
temperature = ktc.readCelsius();
}
}
private:
MAX6675 ktc;
short temperature;
short maxTemp;
short interval;
millis_t temperature_TS;
};
#endif
@@ -0,0 +1,91 @@
#ifndef CONFIG_H
#define CONFIG_H
#include "enums.h"
#include "common/macros.h"
#include <Controllino.h>
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Core settings
//
#define LOOP_DELAY 500 // Our frame time, exluding delays in some places
#define BOOT_DELAY 1000 // Wait at least this amount in ms after boot before doing anything
// Please consider to set this to false for production - especially with the full feature set since this is requiring extra
// time for the serial communication and will affect the overall framerate/performance
// #define DEBUG true
#define DEBUG_INTERVAL 1000
#define DEBUG_BAUD_RATE 19200 // Serial port speed
#define RELAY_ON 0 // The relay bank's on value (eg: normally closed)
#define RELAY_OFF 255 // The relay bank's off value (eg: normally closed)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Machine settings
//
// #define USE_MEGA // On Arduino Uno we have only limited ports which are not enough to enable all features.
#define USE_CONTROLLINO
// #define HAS_AUTOREVERSE
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// General switches
// Reset button - uncomment to activate. This will unlock the fatal state in case of jamming or other problems.
//#define HAS_RESET
#define RESET_PIN 3
#define RESET_DELAY 1000 // Time to wait when reset has been hit or hold. This is good to give the system some time
#define RESET_FATAL true // Makes the reset button act as emergency button. User has to go into stop positon first to unlock it again otherwise it keeps spinning after the RESET_DELAY
#define RESET_INTERVAL 300 // Interval to read the NC reset button
#define RESET_NC true // Toggles the reset button type between NC and NO
// Operation Mode Switch
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Heating Cell/Partition
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Feedback
// Status LEDS (ok, error) - uncomment to activate
#define HAS_STATUS
#define STATUS_OK_PIN CONTROLLINO_D2
#define STATUS_ERROR_PIN CONTROLLINO_D3
#define FIRMWARE_VERSION 0.7
////////////////////////////////////////////////////////////////
//
// HMI Bridge
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// externals
//
// pull in internal constants
#include "constants.h"
// pull in internal configs
#include "config_adv.h"
// The user_config.h is initially added to the github repository but changes will be ignored via .gitignore. Please keep this file safe and possibly
// on a per tenant base stored. You can override parameters in this file by using #undef SOME_PARAMETER and then re-define again if needed, otherwise disable
// default features by using #undef FEATURE_OR_PARAMETER.
// This presents the possibilty to play with the code whilst staying in the loop with latest updates.
#include "user_config.h"
// At last we check all configs and spit compiler errors
#include "config_validator.h"
#endif
@@ -0,0 +1,153 @@
#ifndef known_16bit_timers_header_
#define known_16bit_timers_header_
// Wiring-S
//
#if defined(__AVR_ATmega644P__) && defined(WIRING)
#define TIMER1_A_PIN 5
#define TIMER1_B_PIN 4
#define TIMER1_ICP_PIN 6
// Teensy 2.0
//
#elif defined(__AVR_ATmega32U4__) && defined(CORE_TEENSY)
#define TIMER1_A_PIN 14
#define TIMER1_B_PIN 15
#define TIMER1_C_PIN 4
#define TIMER1_ICP_PIN 22
#define TIMER1_CLK_PIN 11
#define TIMER3_A_PIN 9
#define TIMER3_ICP_PIN 10
// Teensy++ 2.0
#elif defined(__AVR_AT90USB1286__) && defined(CORE_TEENSY)
#define TIMER1_A_PIN 25
#define TIMER1_B_PIN 26
#define TIMER1_C_PIN 27
#define TIMER1_ICP_PIN 4
#define TIMER1_CLK_PIN 6
#define TIMER3_A_PIN 16
#define TIMER3_B_PIN 15
#define TIMER3_C_PIN 14
#define TIMER3_ICP_PIN 17
#define TIMER3_CLK_PIN 13
// Teensy 3.0
//
#elif defined(__MK20DX128__)
#define TIMER1_A_PIN 3
#define TIMER1_B_PIN 4
#define TIMER1_ICP_PIN 4
// Teensy 3.1 / Teensy 3.2
//
#elif defined(__MK20DX256__)
#define TIMER1_A_PIN 3
#define TIMER1_B_PIN 4
#define TIMER1_ICP_PIN 4
#define TIMER3_A_PIN 32
#define TIMER3_B_PIN 25
#define TIMER3_ICP_PIN 32
// Teensy 3.5 / Teensy 3.6
//
#elif defined(__MK64FX512__) || defined(__MK66FX1M0__)
#define TIMER1_A_PIN 3
#define TIMER1_B_PIN 4
#define TIMER1_ICP_PIN 4
#define TIMER3_A_PIN 29
#define TIMER3_B_PIN 30
#define TIMER3_ICP_PIN 29
// Teensy-LC
//
#elif defined(__MKL26Z64__)
#define TIMER1_A_PIN 16
#define TIMER1_B_PIN 17
#define TIMER1_ICP_PIN 17
#define TIMER3_A_PIN 3
#define TIMER3_B_PIN 4
#define TIMER3_ICP_PIN 4
// Arduino Mega
//
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define TIMER1_A_PIN 11
#define TIMER1_B_PIN 12
#define TIMER1_C_PIN 13
#define TIMER3_A_PIN 5
#define TIMER3_B_PIN 2
#define TIMER3_C_PIN 3
#define TIMER4_A_PIN 6
#define TIMER4_B_PIN 7
#define TIMER4_C_PIN 8
#define TIMER4_ICP_PIN 49
#define TIMER5_A_PIN 46
#define TIMER5_B_PIN 45
#define TIMER5_C_PIN 44
#define TIMER3_ICP_PIN 48
#define TIMER3_CLK_PIN 47
// Arduino Leonardo, Yun, etc
//
#elif defined(__AVR_ATmega32U4__)
#define TIMER1_A_PIN 9
#define TIMER1_B_PIN 10
#define TIMER1_C_PIN 11
#define TIMER1_ICP_PIN 4
#define TIMER1_CLK_PIN 12
#define TIMER3_A_PIN 5
#define TIMER3_ICP_PIN 13
// Uno, Duemilanove, LilyPad, etc
//
#elif defined (__AVR_ATmega168__) || defined (__AVR_ATmega328P__)
#define TIMER1_A_PIN 9
#define TIMER1_B_PIN 10
#define TIMER1_ICP_PIN 8
#define TIMER1_CLK_PIN 5
// Sanguino
//
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
#define TIMER1_A_PIN 13
#define TIMER1_B_PIN 12
#define TIMER1_ICP_PIN 14
#define TIMER1_CLK_PIN 1
// Wildfire - Wicked Devices
//
#elif defined(__AVR_ATmega1284P__) && defined(WILDFIRE_VERSION) && WILDFIRE_VERSION >= 3
#define TIMER1_A_PIN 5 // PD5
#define TIMER1_B_PIN 8 // PD4
#define TIMER1_ICP_PIN 6 // PD6
#define TIMER1_CLK_PIN 23 // PB1
#define TIMER3_A_PIN 12 // PB6
#define TIMER3_B_PIN 13 // PB7
#define TIMER3_ICP_PIN 9 // PB5
#define TIMER3_CLK_PIN 0 // PD0
#elif defined(__AVR_ATmega1284P__) && defined(WILDFIRE_VERSION) && WILDFIRE_VERSION < 3
#define TIMER1_A_PIN 5 // PD5
#define TIMER1_B_PIN 4 // PD4
#define TIMER1_ICP_PIN 6 // PD6
#define TIMER1_CLK_PIN 15 // PB1
#define TIMER3_A_PIN 12 // PB6
#define TIMER3_B_PIN 13 // PB7
#define TIMER3_ICP_PIN 11 // PB5
#define TIMER3_CLK_PIN 0 // PD0
// Mighty-1284 - Maniacbug
//
#elif defined(__AVR_ATmega1284P__)
#define TIMER1_A_PIN 12 // PD5
#define TIMER1_B_PIN 13 // PD4
#define TIMER1_ICP_PIN 14 // PD6
#define TIMER1_CLK_PIN 1 // PB1
#define TIMER3_A_PIN 6 // PB6
#define TIMER3_B_PIN 7 // PB7
#define TIMER3_ICP_PIN 5 // PB5
#define TIMER3_CLK_PIN 8 // PD0
#endif
#endif
@@ -0,0 +1,21 @@
#ifndef CONFIG_ADV_H
#define CONFIG_ADV_H
// Error codes
//
#define E_MSG_OK "Ok"
// common operating failures
#define E_OK 0 //all good
#define E_STUCK 100 //Shredder stuck
// power failures
// sensor failures
////////////////////////////
//
// sub system failures
#endif
@@ -0,0 +1,7 @@
#ifndef CONFIG_VALIDATOR
#define CONFIG_VALIDATOR
#include "common/macros.h"
#endif
@@ -0,0 +1,19 @@
#ifndef CONSTANTS_H
#define CONSTANTS_H
#include "enums.h"
/////////////////////////////////////////////////////////////////////////
//
// Addons
//
#define CURRENT_SENSOR_STR "CurrentSensor"
#define ENCLOSURE_SENSOR_STR "EnclosureSensor"
#define POWER_STR "Power"
#define OPERATION_MODE_SWITCH_STR "OperationModeSwitch"
#define APP_STR "App"
#define STATUS_STR "Status LED"
#define MPID_CTRL_STR "Multi - PID Controller"
#endif
@@ -0,0 +1,89 @@
#ifndef ENUMS_H
#define ENUMS_H
enum PIN_TYPE
{
ANALOG,
DIGITAL
};
enum BOARD
{
UNO,
MEGA
};
enum PARTITION_STATE
{
OFF = 0,
HEATING = 1
AUTO_TUNING = 2,
AUTO = 3,
DISABLED = 4,
ERROR = 10
};
enum CONTROL_MODE
{
OP_PANEL = 1, // OLED & Keypad
EXTERN = 2 // RS485
};
enum RUN_MODE
{
PID = 0, // Normal PID mode
MANUAL = 1, // Debugging / Operator
TEST = 2, // Run remote tests
ERROR = 3
LOCKED = 4
};
enum ADDON_FLAGS
{
DEBUG = 1,
INFO = 2,
LOOP = 3,
DISABLED = 4,
SETUP = 5,
MAIN = 6,
STATE = 7
};
enum ADDONS
{
ENCLOSURE_SENSOR = 6,
DIP_SWITCH = 10,
POWER = 11,
OPERATION_MODE_SWITCH = 20,
SERIAL_BRIDGE = 23,
APP = 25,
MODBUS_BRIDGE = 26,
CURRENT_SENSOR = 32,
STATUS = 33,
MPIDCTRL = 34,
LAST = 64
};
enum POWER_CIRCUIT
{
POWER_1 = 0,
POWER_2 = 1,
POWER_3 = 1
};
enum OPERATION_MODE
{
OP_NONE = 0,
OP_NORMAL = 1,
OP_DEBUG = 2,
OP_SERVICE = 3,
OP_TEST
};
enum ERROR
{
ERROR_OK = 0,
ERROR_WARNING = 1,
ERROR_FATAL = 2
};
#endif
@@ -0,0 +1,14 @@
#ifndef FEATURES_H
#define FEATURES_H
#ifdef HAS_RESET
#include "reset.h"
#endif
#include "addons/CurrentSensor.h"
#ifdef HAS_STATUS
#include "addons/Status.h"
#endif
#endif
@@ -0,0 +1,12 @@
#include "app.h"
App app = App();
void setup(){
app.setup();
app.info();
Serial.println("------------------ Ready -------------------------------------- ");
}
void loop(){
app.loop();
}
@@ -0,0 +1,28 @@
{
"name": "@plastichub/pid-firmware",
"version": "0.1",
"description": "",
"main": "index.js",
"cid": 0,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/plastic-hub/firmware.git"
},
"keywords": [
"precious",
"plastic"
],
"author": "PlasticHUB",
"license": "GPL-3.0-or-later",
"bugs": {
"url": "https://github.com/plastic-hub/firmware/issues"
},
"homepage": "https://github.com/plastic-hub/firmware#readme",
"dependencies": {
"@xblox/fs": "^0.13.19",
"simple-git": "^1.131.0"
}
}
@@ -0,0 +1,93 @@
#include "ppmath_statistics.h"
Statistic::Statistic()
{
clear();
}
// resets all counters
void Statistic::clear()
{
_cnt = 0;
_sum = 0;
_min = 0;
_max = 0;
#ifdef STAT_USE_STDEV
_ssqdif = 0.0; // not _ssq but sum of square differences
// which is SUM(from i = 1 to N) of
// (f(i)-_ave_N)**2
#endif
}
// adds a new value to the data-set
void Statistic::add(const float value)
{
if (_cnt == 0)
{
_min = value;
_max = value;
}
else
{
if (value < _min)
_min = value;
else if (value > _max)
_max = value;
}
_sum += value;
_cnt++;
#ifdef STAT_USE_STDEV
if (_cnt > 1)
{
float _store = (_sum / _cnt - value);
_ssqdif = _ssqdif + _cnt * _store * _store / (_cnt - 1);
// ~10% faster but limits the amount of samples to 65K as _cnt*_cnt overflows
// float _store = _sum - _cnt * value;
// _ssqdif = _ssqdif + _store * _store / (_cnt*_cnt - _cnt);
}
#endif
}
// returns the average of the data-set added sofar
float Statistic::average() const
{
if (_cnt == 0)
return NAN; // original code returned 0
return _sum / _cnt;
}
// Population standard deviation = s = sqrt [ S ( Xi - )2 / N ]
// http://www.suite101.com/content/how-is-standard-deviation-used-a99084
#ifdef STAT_USE_STDEV
float Statistic::variance() const
{
if (_cnt == 0)
return NAN; // otherwise DIV0 error
return _ssqdif / _cnt;
}
float Statistic::mean() const
{
if (_cnt == 0)
return NAN; // otherwise DIV0 error
return this->sum() / _cnt;
}
float Statistic::pop_stdev() const
{
if (_cnt == 0)
return NAN; // otherwise DIV0 error
return sqrt(_ssqdif / _cnt);
}
float Statistic::unbiased_stdev() const
{
if (_cnt < 2)
return NAN; // otherwise DIV0 error
return sqrt(_ssqdif / (_cnt - 1));
}
#endif
// END OF FILE
@@ -0,0 +1,116 @@
#ifndef PPMATH_STATISTICS_H
#define PPMATH_STATISTICS_H
#include <Arduino.h>
#include <math.h>
#define STAT_USE_STDEV
#ifdef __cplusplus
// C++11 solution that is standards compliant. Return type is deduced automatically
template <class L, class R>
static inline constexpr auto MIN(const L lhs, const R rhs) -> decltype(lhs + rhs)
{
return lhs < rhs ? lhs : rhs;
}
template <class L, class R>
static inline constexpr auto MAX(const L lhs, const R rhs) -> decltype(lhs + rhs)
{
return lhs > rhs ? lhs : rhs;
}
template <class T>
static inline constexpr const T ABS(const T v)
{
return v >= 0 ? v : -v;
}
#else
// Using GCC extensions, but Travis GCC version does not like it and gives
// "error: statement-expressions are not allowed outside functions nor in template-argument lists"
#define MIN(a, b) \
({__typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
_a < _b ? _a : _b; })
#define MAX(a, b) \
({__typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
_a > _b ? _a : _b; })
#define ABS(a) \
({__typeof__(a) _a = (a); \
_a >= 0 ? _a : -_a; })
#endif
class Statistic
{
public:
Statistic(); // "switches on/off" stdev run time
void clear(); // "switches on/off" stdev run time
void add(const float);
// returns the number of values added
uint32_t count() const { return _cnt; }; // zero if empty
float sum() const { return _sum; }; // zero if empty
float minimum() const { return _min; }; // zero if empty
float maximum() const { return _max; }; // zero if empty
float average() const; // NAN if empty
float mean() const; // zero if empty
#ifdef STAT_USE_STDEV
float variance() const; // NAN if empty
float pop_stdev() const; // population stdev // NAN if empty
float unbiased_stdev() const; // NAN if empty
#endif
protected:
uint32_t _cnt;
float _sum;
float _min;
float _max;
#ifdef STAT_USE_STDEV
float _ssqdif; // sum of squares difference
#endif
};
/**
* Returns the kth q-quantile.
* @link http://en.wikipedia.org/wiki/Quantile#Quantiles_of_a_population
* ie: median is 1st 2-quantile
* ie: upper quartile is 3rd 4-quantile
* @return {Number} q-quantile of values.
*/
/*
const quantile = (arr: number[], i: number, n: number) => {
if (i === 0) return Math.min.apply(null, arr);
if (i === n) return Math.max.apply(null, arr);
let sorted = arr.slice(0);
sorted.sort((a, b) => a - b);
let index = sorted.length * i / n;
if (index % 1 === 0) {
return 0.5 * sorted[index - 1] + 0.5 * sorted[index];
}
return sorted[~~index];
};
export const median = (arr: number[]) => quantile(arr, 1, 2);
export const sum = (arr: number[]) => arr.reduce((a, b) => a + b, 0);
export const mean = (arr: number[]) => sum(arr) / arr.length;
// sqare errors along mean
const sdiff = (arr: number[], mean: number) => arr.map((v) =>
Math.pow(v - mean, 2)
);
export const standardDeviation = (arr: number[]) =>
Math.sqrt(mean(sdiff(arr, mean(arr))));
*/
#endif
@@ -0,0 +1,11 @@
#ifndef TYPES_H
#define TYPES_H
#include <stdint.h>
typedef unsigned long millis_t;
typedef unsigned short ushort;
typedef unsigned char uchar;
#endif
@@ -0,0 +1,4 @@
#ifndef USER_CONFIG_H
#define USER_CONFIG_H
#endif
@@ -0,0 +1,88 @@
/**
@file
CRC Computations
@defgroup util_crc16 "util/crc16.h": CRC Computations
@code#include "util/crc16.h"@endcode
This header file provides functions for calculating
cyclic redundancy checks (CRC) using common polynomials.
Modified by Doc Walker to be processor-independent (removed inline
assembler to allow it to compile on SAM3X8E processors).
@par References:
Jack Crenshaw's "Implementing CRCs" article in the January 1992 issue of @e
Embedded @e Systems @e Programming. This may be difficult to find, but it
explains CRC's in very clear and concise terms. Well worth the effort to
obtain a copy.
*/
/* Copyright (c) 2002, 2003, 2004 Marek Michalkiewicz
Copyright (c) 2005, 2007 Joerg Wunsch
Copyright (c) 2013 Dave Hylands
Copyright (c) 2013 Frederic Nadeau
Copyright (c) 2015 Doc Walker
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of the copyright holders nor the names of
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE. */
#ifndef _UTIL_CRC16_H_
#define _UTIL_CRC16_H_
/** @ingroup util_crc16
Processor-independent CRC-16 calculation.
Polynomial: x^16 + x^15 + x^2 + 1 (0xA001)<br>
Initial value: 0xFFFF
This CRC is normally used in disk-drive controllers.
@param uint16_t crc (0x0000..0xFFFF)
@param uint8_t a (0x00..0xFF)
@return calculated CRC (0x0000..0xFFFF)
*/
uint16_t crc16_update(uint16_t crc, uint8_t a);
/*{
int i;
crc ^= a;
for (i = 0; i < 8; ++i)
{
if (crc & 1)
crc = (crc >> 1) ^ 0xA001;
else
crc = (crc >> 1);
}
return crc;
}
*/
#endif /* _UTIL_CRC16_H_ */
@@ -0,0 +1,64 @@
/**
@file
Utility Functions for Manipulating Words
@defgroup util_word "util/word.h": Utility Functions for Manipulating Words
@code#include "util/word.h"@endcode
This header file provides utility functions for manipulating words.
*/
/*
word.h - Utility Functions for Manipulating Words
This file is part of ModbusMaster.
ModbusMaster is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ModbusMaster 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with ModbusMaster. If not, see <http://www.gnu.org/licenses/>.
Written by Doc Walker (Rx)
Copyright © 2009-2015 Doc Walker <4-20ma at wvfans dot net>
*/
#ifndef _UTIL_WORD_H_
#define _UTIL_WORD_H_
/** @ingroup util_word
Return low word of a 32-bit integer.
@param uint32_t ww (0x00000000..0xFFFFFFFF)
@return low word of input (0x0000..0xFFFF)
*/
static inline uint16_t lowWord(uint32_t ww)
{
return (uint16_t) ((ww) & 0xFFFF);
}
/** @ingroup util_word
Return high word of a 32-bit integer.
@param uint32_t ww (0x00000000..0xFFFFFFFF)
@return high word of input (0x0000..0xFFFF)
*/
static inline uint16_t highWord(uint32_t ww)
{
return (uint16_t) ((ww) >> 16);
}
#endif /* _UTIL_WORD_H_ */
@@ -0,0 +1,34 @@
const read = require('@xblox/fs/read');
const write = require('@xblox/fs/write');
const path = require('path');
const cwd = path.resolve('../../');
const pkgVersion = read.sync('package.json', 'json').version;
const cid = read.sync('package.json', 'json').cid;
async function status(workingDir) {
const git = require('simple-git/promise');
let statusSummary = null;
try {
statusSummary = await git(workingDir).log();
}
catch (e) {
// handle the error
}
return statusSummary;
}
status(cwd).then((status) => {
const version =
`#ifndef VERSION_H \n
#define VERSION_H \n
#define VERSION "${pkgVersion}|${status.latest.hash}"\n
#define CID "${cid}"\n
#endif`;
write.sync('./Version.h', version);
console.log(version);
}
);
@@ -0,0 +1,788 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@sindresorhus/df@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@sindresorhus/df/-/df-1.0.1.tgz#c69b66f52f6fcdd287c807df210305dbaf78500d"
integrity sha1-xptm9S9vzdKHyAffIQMF2694UA0=
"@sindresorhus/df@^2.1.0":
version "2.1.0"
resolved "https://registry.yarnpkg.com/@sindresorhus/df/-/df-2.1.0.tgz#d208cf27e06f0bb476d14d7deccd7d726e9aa389"
integrity sha1-0gjPJ+BvC7R20U197M19cm6ao4k=
dependencies:
execa "^0.2.2"
"@types/minimatch@^3.0.3":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
"@xblox/core@0.0.18":
version "0.0.18"
resolved "https://registry.yarnpkg.com/@xblox/core/-/core-0.0.18.tgz#6513807ba2982c6b274b3e3972bec312dfb2c8da"
integrity sha1-ZROAe6KYLGsnSz45cr7DEt+yyNo=
dependencies:
base-64 "^0.1.0"
jsonpath "^0.2.11"
qs "^6.4.0"
reflect-metadata "^0.1.10"
"@xblox/fs@^0.13.19":
version "0.13.19"
resolved "https://registry.yarnpkg.com/@xblox/fs/-/fs-0.13.19.tgz#7231ac9bc186a15a48d04a9c4d86c7ff651f8740"
integrity sha512-211yh3Zkm0AIMjNfhOhGzw+vTWH+O4zMivktjW0M+l5mJkyM2f92Pw/GBvxFAOWR2Fryn2NfCIF1GiQIRYdTEQ==
dependencies:
"@types/minimatch" "^3.0.3"
"@xblox/core" "0.0.18"
denodeify "^1.2.1"
errno "^0.1.4"
mime "^2.0.3"
minimatch "^3.0.4"
mkdirp "^0.5.1"
progress-stream "^1.2.0"
q "^1.4.1"
rimraf "^2.6.2"
throttle "^1.0.3"
trash "^4.0.1"
write-file-atomic "^1.3.1"
JSONSelect@0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/JSONSelect/-/JSONSelect-0.4.0.tgz#a08edcc67eb3fcbe99ed630855344a0cf282bb8d"
integrity sha1-oI7cxn6z/L6Z7WMIVTRKDPKCu40=
array-union@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39"
integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=
dependencies:
array-uniq "^1.0.1"
array-uniq@^1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
base-64@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/base-64/-/base-64-0.1.0.tgz#780a99c84e7d600260361511c4877613bf24f6bb"
integrity sha1-eAqZyE59YAJgNhURxId2E78k9rs=
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
dependencies:
balanced-match "^1.0.0"
concat-map "0.0.1"
cjson@~0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/cjson/-/cjson-0.2.1.tgz#73cd8aad65d9e1505f9af1744d3b79c1527682a5"
integrity sha1-c82KrWXZ4VBfmvF0TTt5wVJ2gqU=
colors@0.5.x:
version "0.5.1"
resolved "https://registry.yarnpkg.com/colors/-/colors-0.5.1.tgz#7d0023eaeb154e8ee9fce75dcb923d0ed1667774"
integrity sha1-fQAj6usVTo7p/Oddy5I9DtFmd3Q=
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
cross-spawn-async@^2.1.1:
version "2.2.5"
resolved "https://registry.yarnpkg.com/cross-spawn-async/-/cross-spawn-async-2.2.5.tgz#845ff0c0834a3ded9d160daca6d390906bb288cc"
integrity sha1-hF/wwINKPe2dFg2sptOQkGuyiMw=
dependencies:
lru-cache "^4.0.0"
which "^1.2.8"
cross-spawn@^6.0.0:
version "6.0.5"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
dependencies:
nice-try "^1.0.4"
path-key "^2.0.1"
semver "^5.5.0"
shebang-command "^1.2.0"
which "^1.2.9"
debug@2:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
dependencies:
ms "2.0.0"
debug@^4.0.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
dependencies:
ms "^2.1.1"
denodeify@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/denodeify/-/denodeify-1.2.1.tgz#3a36287f5034e699e7577901052c2e6c94251631"
integrity sha1-OjYof1A05pnnV3kBBSwubJQlFjE=
dir-glob@^2.0.0:
version "2.2.2"
resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4"
integrity sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==
dependencies:
path-type "^3.0.0"
ebnf-parser@~0.1.9:
version "0.1.10"
resolved "https://registry.yarnpkg.com/ebnf-parser/-/ebnf-parser-0.1.10.tgz#cd1f6ba477c5638c40c97ed9b572db5bab5d8331"
integrity sha1-zR9rpHfFY4xAyX7ZtXLbW6tdgzE=
errno@^0.1.4:
version "0.1.7"
resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618"
integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==
dependencies:
prr "~1.0.1"
escape-string-applescript@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/escape-string-applescript/-/escape-string-applescript-2.0.0.tgz#760bca838668e408fe5ee52ce42caf7cb46c5273"
integrity sha1-dgvKg4Zo5Aj+XuUs5CyvfLRsUnM=
escodegen@0.0.21:
version "0.0.21"
resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-0.0.21.tgz#53d652cfa1030388279458a5266c5ffc709c63c3"
integrity sha1-U9ZSz6EDA4gnlFilJmxf/HCcY8M=
dependencies:
esprima "~1.0.2"
estraverse "~0.0.4"
optionalDependencies:
source-map ">= 0.1.2"
escodegen@~0.0.24:
version "0.0.28"
resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-0.0.28.tgz#0e4ff1715f328775d6cab51ac44a406cd7abffd3"
integrity sha1-Dk/xcV8yh3XWyrUaxEpAbNer/9M=
dependencies:
esprima "~1.0.2"
estraverse "~1.3.0"
optionalDependencies:
source-map ">= 0.1.2"
esprima@1.0.x, esprima@~1.0.2:
version "1.0.4"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.0.4.tgz#9f557e08fc3b4d26ece9dd34f8fbf476b62585ad"
integrity sha1-n1V+CPw7TSbs6d00+Pv0drYlha0=
esprima@1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.2.2.tgz#76a0fd66fcfe154fd292667dc264019750b1657b"
integrity sha1-dqD9Zvz+FU/SkmZ9wmQBl1CxZXs=
estraverse@~0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-0.0.4.tgz#01a0932dfee574684a598af5a67c3bf9b6428db2"
integrity sha1-AaCTLf7ldGhKWYr1pnw7+bZCjbI=
estraverse@~1.3.0:
version "1.3.2"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.3.2.tgz#37c2b893ef13d723f276d878d60d8535152a6c42"
integrity sha1-N8K4k+8T1yPydth41g2FNRUqbEI=
execa@^0.10.0:
version "0.10.0"
resolved "https://registry.yarnpkg.com/execa/-/execa-0.10.0.tgz#ff456a8f53f90f8eccc71a96d11bdfc7f082cb50"
integrity sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==
dependencies:
cross-spawn "^6.0.0"
get-stream "^3.0.0"
is-stream "^1.1.0"
npm-run-path "^2.0.0"
p-finally "^1.0.0"
signal-exit "^3.0.0"
strip-eof "^1.0.0"
execa@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/execa/-/execa-0.2.2.tgz#e2ead472c2c31aad6f73f1ac956eef45e12320cb"
integrity sha1-4urUcsLDGq1vc/GslW7vReEjIMs=
dependencies:
cross-spawn-async "^2.1.1"
npm-run-path "^1.0.0"
object-assign "^4.0.1"
path-key "^1.0.0"
strip-eof "^1.0.0"
fs-extra@^0.30.0:
version "0.30.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0"
integrity sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=
dependencies:
graceful-fs "^4.1.2"
jsonfile "^2.1.0"
klaw "^1.0.0"
path-is-absolute "^1.0.0"
rimraf "^2.2.8"
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
get-stream@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=
glob@^7.1.2, glob@^7.1.3:
version "7.1.6"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.0.4"
once "^1.3.0"
path-is-absolute "^1.0.0"
globby@^7.1.1:
version "7.1.1"
resolved "https://registry.yarnpkg.com/globby/-/globby-7.1.1.tgz#fb2ccff9401f8600945dfada97440cca972b8680"
integrity sha1-+yzP+UAfhgCUXfral0QMypcrhoA=
dependencies:
array-union "^1.0.1"
dir-glob "^2.0.0"
glob "^7.1.2"
ignore "^3.3.5"
pify "^3.0.0"
slash "^1.0.0"
graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9:
version "4.2.4"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb"
integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==
ignore@^3.3.5:
version "3.3.10"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043"
integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==
imurmurhash@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
dependencies:
once "^1.3.0"
wrappy "1"
inherits@2, inherits@^2.0.3, inherits@~2.0.1:
version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
is-stream@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
isarray@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
jison-lex@0.2.x:
version "0.2.1"
resolved "https://registry.yarnpkg.com/jison-lex/-/jison-lex-0.2.1.tgz#ac4b815e8cce5132eb12b5dfcfe8d707b8844dfe"
integrity sha1-rEuBXozOUTLrErXfz+jXB7iETf4=
dependencies:
lex-parser "0.1.x"
nomnom "1.5.2"
jison@0.4.13:
version "0.4.13"
resolved "https://registry.yarnpkg.com/jison/-/jison-0.4.13.tgz#9041707d62241367f58834532b9f19c2c36fac78"
integrity sha1-kEFwfWIkE2f1iDRTK58ZwsNvrHg=
dependencies:
JSONSelect "0.4.0"
cjson "~0.2.1"
ebnf-parser "~0.1.9"
escodegen "0.0.21"
esprima "1.0.x"
jison-lex "0.2.x"
lex-parser "~0.1.3"
nomnom "1.5.2"
jsonfile@^2.1.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8"
integrity sha1-NzaitCi4e72gzIO1P6PWM6NcKug=
optionalDependencies:
graceful-fs "^4.1.6"
jsonpath@^0.2.11:
version "0.2.12"
resolved "https://registry.yarnpkg.com/jsonpath/-/jsonpath-0.2.12.tgz#5bf9d911fb4616c1e3370beceb9f0db24ae34cd2"
integrity sha1-W/nZEftGFsHjNwvs658NskrjTNI=
dependencies:
esprima "1.2.2"
jison "0.4.13"
static-eval "0.2.3"
underscore "1.7.0"
klaw@^1.0.0:
version "1.3.1"
resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439"
integrity sha1-QIhDO0azsbolnXh4XY6W9zugJDk=
optionalDependencies:
graceful-fs "^4.1.9"
lex-parser@0.1.x, lex-parser@~0.1.3:
version "0.1.4"
resolved "https://registry.yarnpkg.com/lex-parser/-/lex-parser-0.1.4.tgz#64c4f025f17fd53bfb45763faeb16f015a747550"
integrity sha1-ZMTwJfF/1Tv7RXY/rrFvAVp0dVA=
lru-cache@^4.0.0:
version "4.1.5"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd"
integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==
dependencies:
pseudomap "^1.0.2"
yallist "^2.1.2"
mime@^2.0.3:
version "2.4.5"
resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.5.tgz#d8de2ecb92982dedbb6541c9b6841d7f218ea009"
integrity sha512-3hQhEUF027BuxZjQA3s7rIv/7VCQPa27hN9u9g87sEkWaKwQPuXOkVKtOeiyUrnWqTDiOs8Ed2rwg733mB0R5w==
minimatch@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
dependencies:
brace-expansion "^1.1.7"
minimist@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
mkdirp@^0.5.1:
version "0.5.5"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
dependencies:
minimist "^1.2.5"
mount-point@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/mount-point/-/mount-point-3.0.0.tgz#665cb9edebe80d110e658db56c31d0aef51a8f97"
integrity sha1-Zly57evoDREOZY21bDHQrvUaj5c=
dependencies:
"@sindresorhus/df" "^1.0.1"
pify "^2.3.0"
pinkie-promise "^2.0.1"
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
ms@^2.1.1:
version "2.1.2"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
nice-try@^1.0.4:
version "1.0.5"
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
nomnom@1.5.2:
version "1.5.2"
resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.5.2.tgz#f4345448a853cfbd5c0d26320f2477ab0526fe2f"
integrity sha1-9DRUSKhTz71cDSYyDyR3qwUm/i8=
dependencies:
colors "0.5.x"
underscore "1.1.x"
npm-run-path@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-1.0.0.tgz#f5c32bf595fe81ae927daec52e82f8b000ac3c8f"
integrity sha1-9cMr9ZX+ga6Sfa7FLoL4sACsPI8=
dependencies:
path-key "^1.0.0"
npm-run-path@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=
dependencies:
path-key "^2.0.0"
object-assign@^4.0.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
object-keys@~0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336"
integrity sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=
once@^1.3.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
dependencies:
wrappy "1"
os-homedir@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M=
p-finally@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=
p-map@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b"
integrity sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==
p-try@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3"
integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=
path-is-absolute@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
path-key@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/path-key/-/path-key-1.0.0.tgz#5d53d578019646c0d68800db4e146e6bdc2ac7af"
integrity sha1-XVPVeAGWRsDWiADbThRua9wqx68=
path-key@^2.0.0, path-key@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=
path-type@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f"
integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==
dependencies:
pify "^3.0.0"
pify@^2.2.0, pify@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw=
pify@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176"
integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=
pinkie-promise@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o=
dependencies:
pinkie "^2.0.0"
pinkie@^2.0.0:
version "2.0.4"
resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA=
progress-stream@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/progress-stream/-/progress-stream-1.2.0.tgz#2cd3cfea33ba3a89c9c121ec3347abe9ab125f77"
integrity sha1-LNPP6jO6OonJwSHsM0er6asSX3c=
dependencies:
speedometer "~0.1.2"
through2 "~0.2.3"
prr@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476"
integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY=
pseudomap@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM=
q@^1.4.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=
qs@^6.4.0:
version "6.9.3"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.3.tgz#bfadcd296c2d549f1dffa560619132c977f5008e"
integrity sha512-EbZYNarm6138UKKq46tdx08Yo/q9ZhFoAXAI1meAFd2GtbRDhbZY2WQSICskT0c5q99aFzLG1D4nvTk9tqfXIw==
"readable-stream@>= 0.3.0":
version "3.6.0"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
dependencies:
inherits "^2.0.3"
string_decoder "^1.1.1"
util-deprecate "^1.0.1"
readable-stream@~1.1.9:
version "1.1.14"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9"
integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk=
dependencies:
core-util-is "~1.0.0"
inherits "~2.0.1"
isarray "0.0.1"
string_decoder "~0.10.x"
reflect-metadata@^0.1.10:
version "0.1.13"
resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08"
integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==
rimraf@^2.2.8, rimraf@^2.6.2:
version "2.7.1"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
dependencies:
glob "^7.1.3"
run-applescript@^3.0.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/run-applescript/-/run-applescript-3.2.0.tgz#73fb34ce85d3de8076d511ea767c30d4fdfc918b"
integrity sha512-Ep0RsvAjnRcBX1p5vogbaBdAGu/8j/ewpvGqnQYunnLd9SM0vWcPJewPKNnWFggf0hF0pwIgwV5XK7qQ7UZ8Qg==
dependencies:
execa "^0.10.0"
safe-buffer@~5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519"
integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==
semver@^5.5.0:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
shebang-command@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=
dependencies:
shebang-regex "^1.0.0"
shebang-regex@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=
signal-exit@^3.0.0:
version "3.0.3"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
simple-git@^1.131.0:
version "1.132.0"
resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-1.132.0.tgz#53ac4c5ec9e74e37c2fd461e23309f22fcdf09b1"
integrity sha512-xauHm1YqCTom1sC9eOjfq3/9RKiUA9iPnxBbrY2DdL8l4ADMu0jjM5l5lphQP5YWNqAL2aXC/OeuQ76vHtW5fg==
dependencies:
debug "^4.0.1"
slash@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=
slide@^1.1.5:
version "1.1.6"
resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707"
integrity sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=
"source-map@>= 0.1.2":
version "0.7.3"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==
speedometer@~0.1.2:
version "0.1.4"
resolved "https://registry.yarnpkg.com/speedometer/-/speedometer-0.1.4.tgz#9876dbd2a169d3115402d48e6ea6329c8816a50d"
integrity sha1-mHbb0qFp0xFUAtSObqYynIgWpQ0=
static-eval@0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/static-eval/-/static-eval-0.2.3.tgz#023f17ac9fee426ea788c12ea39206dc175f8b2a"
integrity sha1-Aj8XrJ/uQm6niMEuo5IG3Bdfiyo=
dependencies:
escodegen "~0.0.24"
"stream-parser@>= 0.0.2":
version "0.3.1"
resolved "https://registry.yarnpkg.com/stream-parser/-/stream-parser-0.3.1.tgz#1618548694420021a1182ff0af1911c129761773"
integrity sha1-FhhUhpRCACGhGC/wrxkRwSl2F3M=
dependencies:
debug "2"
string_decoder@^1.1.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
dependencies:
safe-buffer "~5.2.0"
string_decoder@~0.10.x:
version "0.10.31"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=
strip-eof@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=
throttle@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/throttle/-/throttle-1.0.3.tgz#8a32e4a15f1763d997948317c5ebe3ad8a41e4b7"
integrity sha1-ijLkoV8XY9mXlIMXxevjrYpB5Lc=
dependencies:
readable-stream ">= 0.3.0"
stream-parser ">= 0.0.2"
through2@~0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/through2/-/through2-0.2.3.tgz#eb3284da4ea311b6cc8ace3653748a52abf25a3f"
integrity sha1-6zKE2k6jEbbMis42U3SKUqvyWj8=
dependencies:
readable-stream "~1.1.9"
xtend "~2.1.1"
trash@^4.0.1:
version "4.3.0"
resolved "https://registry.yarnpkg.com/trash/-/trash-4.3.0.tgz#6ebeecdea4d666b06e389b47d135ea88e1de5075"
integrity sha512-f36TKwIaBiXm63xSrn8OTNghg5CYHBsFVJvcObMo76LRpgariuRi2CqXQHw1VzfeximD0igdGaonOG6N760BtQ==
dependencies:
escape-string-applescript "^2.0.0"
fs-extra "^0.30.0"
globby "^7.1.1"
p-map "^1.2.0"
p-try "^1.0.0"
pify "^3.0.0"
run-applescript "^3.0.0"
uuid "^3.1.0"
xdg-trashdir "^2.1.1"
underscore@1.1.x:
version "1.1.7"
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.1.7.tgz#40bab84bad19d230096e8d6ef628bff055d83db0"
integrity sha1-QLq4S60Z0jAJbo1u9ii/8FXYPbA=
underscore@1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.7.0.tgz#6bbaf0877500d36be34ecaa584e0db9fef035209"
integrity sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=
user-home@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f"
integrity sha1-nHC/2Babwdy/SGBODwS4tJzenp8=
dependencies:
os-homedir "^1.0.0"
util-deprecate@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
uuid@^3.1.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
which@^1.2.8, which@^1.2.9:
version "1.3.1"
resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
dependencies:
isexe "^2.0.0"
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
write-file-atomic@^1.3.1:
version "1.3.4"
resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f"
integrity sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8=
dependencies:
graceful-fs "^4.1.11"
imurmurhash "^0.1.4"
slide "^1.1.5"
xdg-basedir@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-2.0.0.tgz#edbc903cc385fc04523d966a335504b5504d1bd2"
integrity sha1-7byQPMOF/ARSPZZqM1UEtVBNG9I=
dependencies:
os-homedir "^1.0.0"
xdg-trashdir@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/xdg-trashdir/-/xdg-trashdir-2.1.1.tgz#59a60aaf8e6f9240c1daed9a0944b2f514c27d8e"
integrity sha512-KcVhPaOu2ZurYNHSRTf1+ZHORkTZGCQ+u0JHN17QixRISJq4pXOnjt/lQcehvtHL5QAKhSzKgyjrcNnPdkPBHA==
dependencies:
"@sindresorhus/df" "^2.1.0"
mount-point "^3.0.0"
pify "^2.2.0"
user-home "^2.0.0"
xdg-basedir "^2.0.0"
xtend@~2.1.1:
version "2.1.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.1.2.tgz#6efecc2a4dad8e6962c4901b337ce7ba87b5d28b"
integrity sha1-bv7MKk2tjmlixJAbM3znuoe10os=
dependencies:
object-keys "~0.4.0"
yallist@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=