initial working build
This commit is contained in:
commit
20ba610b72
31 changed files with 3076 additions and 0 deletions
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
.pio
|
||||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.vscode/ipch
|
||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[submodule "lib/TFT_ILI9163C"]
|
||||
path = lib/TFT_ILI9163C
|
||||
url = https://github.com/sumotoy/TFT_ILI9163C.git
|
||||
10
.vscode/extensions.json
vendored
Normal file
10
.vscode/extensions.json
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"platformio.platformio-ide"
|
||||
],
|
||||
"unwantedRecommendations": [
|
||||
"ms-vscode.cpptools-extension-pack"
|
||||
]
|
||||
}
|
||||
39
include/README
Normal file
39
include/README
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
|
||||
This directory is intended for project header files.
|
||||
|
||||
A header file is a file containing C declarations and macro definitions
|
||||
to be shared between several project source files. You request the use of a
|
||||
header file in your project source file (C, C++, etc) located in `src` folder
|
||||
by including it, with the C preprocessing directive `#include'.
|
||||
|
||||
```src/main.c
|
||||
|
||||
#include "header.h"
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Including a header file produces the same results as copying the header file
|
||||
into each source file that needs it. Such copying would be time-consuming
|
||||
and error-prone. With a header file, the related declarations appear
|
||||
in only one place. If they need to be changed, they can be changed in one
|
||||
place, and programs that include the header file will automatically use the
|
||||
new version when next recompiled. The header file eliminates the labor of
|
||||
finding and changing all the copies as well as the risk that a failure to
|
||||
find one copy will result in inconsistencies within a program.
|
||||
|
||||
In C, the usual convention is to give header files names that end with `.h'.
|
||||
It is most portable to use only letters, digits, dashes, and underscores in
|
||||
header file names, and at most one dot.
|
||||
|
||||
Read more about using header files in official GCC documentation:
|
||||
|
||||
* Include Syntax
|
||||
* Include Operation
|
||||
* Once-Only Headers
|
||||
* Computed Includes
|
||||
|
||||
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
|
||||
224
lib/Arduino-PID-Library/PID_v1.cpp
Normal file
224
lib/Arduino-PID-Library/PID_v1.cpp
Normal file
|
|
@ -0,0 +1,224 @@
|
|||
/**********************************************************************************************
|
||||
* Arduino PID Library - Version 1.2.1
|
||||
* by Brett Beauregard <br3ttb@gmail.com> brettbeauregard.com
|
||||
*
|
||||
* This Library is licensed under the MIT License
|
||||
**********************************************************************************************/
|
||||
|
||||
#if ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
#include <PID_v1.h>
|
||||
|
||||
/*Constructor (...)*********************************************************
|
||||
* The parameters specified here are those for for which we can't set up
|
||||
* reliable defaults, so we need to have the user set them.
|
||||
***************************************************************************/
|
||||
PID::PID(double* Input, double* Output, double* Setpoint,
|
||||
double Kp, double Ki, double Kd, int POn, int ControllerDirection)
|
||||
{
|
||||
myOutput = Output;
|
||||
myInput = Input;
|
||||
mySetpoint = Setpoint;
|
||||
inAuto = false;
|
||||
|
||||
PID::SetOutputLimits(0, 255); //default output limit corresponds to
|
||||
//the arduino pwm limits
|
||||
|
||||
SampleTime = 100; //default Controller Sample Time is 0.1 seconds
|
||||
|
||||
PID::SetControllerDirection(ControllerDirection);
|
||||
PID::SetTunings(Kp, Ki, Kd, POn);
|
||||
|
||||
lastTime = millis()-SampleTime;
|
||||
}
|
||||
|
||||
/*Constructor (...)*********************************************************
|
||||
* To allow backwards compatability for v1.1, or for people that just want
|
||||
* to use Proportional on Error without explicitly saying so
|
||||
***************************************************************************/
|
||||
|
||||
PID::PID(double* Input, double* Output, double* Setpoint,
|
||||
double Kp, double Ki, double Kd, int ControllerDirection)
|
||||
:PID::PID(Input, Output, Setpoint, Kp, Ki, Kd, P_ON_E, ControllerDirection)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Compute() **********************************************************************
|
||||
* This, as they say, is where the magic happens. this function should be called
|
||||
* every time "void loop()" executes. the function will decide for itself whether a new
|
||||
* pid Output needs to be computed. returns true when the output is computed,
|
||||
* false when nothing has been done.
|
||||
**********************************************************************************/
|
||||
bool PID::Compute()
|
||||
{
|
||||
if(!inAuto) return false;
|
||||
unsigned long now = millis();
|
||||
unsigned long timeChange = (now - lastTime);
|
||||
if(timeChange>=SampleTime)
|
||||
{
|
||||
/*Compute all the working error variables*/
|
||||
double input = *myInput;
|
||||
double error = *mySetpoint - input;
|
||||
double dInput = (input - lastInput);
|
||||
outputSum+= (ki * error);
|
||||
|
||||
/*Add Proportional on Measurement, if P_ON_M is specified*/
|
||||
if(!pOnE) outputSum-= kp * dInput;
|
||||
|
||||
if(outputSum > outMax) outputSum= outMax;
|
||||
else if(outputSum < outMin) outputSum= outMin;
|
||||
|
||||
/*Add Proportional on Error, if P_ON_E is specified*/
|
||||
double output;
|
||||
if(pOnE) output = kp * error;
|
||||
else output = 0;
|
||||
|
||||
/*Compute Rest of PID Output*/
|
||||
output += outputSum - kd * dInput;
|
||||
|
||||
if(output > outMax) output = outMax;
|
||||
else if(output < outMin) output = outMin;
|
||||
*myOutput = output;
|
||||
|
||||
/*Remember some variables for next time*/
|
||||
lastInput = input;
|
||||
lastTime = now;
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
/* SetTunings(...)*************************************************************
|
||||
* This function allows the controller's dynamic performance to be adjusted.
|
||||
* it's called automatically from the constructor, but tunings can also
|
||||
* be adjusted on the fly during normal operation
|
||||
******************************************************************************/
|
||||
void PID::SetTunings(double Kp, double Ki, double Kd, int POn)
|
||||
{
|
||||
if (Kp<0 || Ki<0 || Kd<0) return;
|
||||
|
||||
pOn = POn;
|
||||
pOnE = POn == P_ON_E;
|
||||
|
||||
dispKp = Kp; dispKi = Ki; dispKd = Kd;
|
||||
|
||||
double SampleTimeInSec = ((double)SampleTime)/1000;
|
||||
kp = Kp;
|
||||
ki = Ki * SampleTimeInSec;
|
||||
kd = Kd / SampleTimeInSec;
|
||||
|
||||
if(controllerDirection ==REVERSE)
|
||||
{
|
||||
kp = (0 - kp);
|
||||
ki = (0 - ki);
|
||||
kd = (0 - kd);
|
||||
}
|
||||
}
|
||||
|
||||
/* SetTunings(...)*************************************************************
|
||||
* Set Tunings using the last-rembered POn setting
|
||||
******************************************************************************/
|
||||
void PID::SetTunings(double Kp, double Ki, double Kd){
|
||||
SetTunings(Kp, Ki, Kd, pOn);
|
||||
}
|
||||
|
||||
/* SetSampleTime(...) *********************************************************
|
||||
* sets the period, in Milliseconds, at which the calculation is performed
|
||||
******************************************************************************/
|
||||
void PID::SetSampleTime(int NewSampleTime)
|
||||
{
|
||||
if (NewSampleTime > 0)
|
||||
{
|
||||
double ratio = (double)NewSampleTime
|
||||
/ (double)SampleTime;
|
||||
ki *= ratio;
|
||||
kd /= ratio;
|
||||
SampleTime = (unsigned long)NewSampleTime;
|
||||
}
|
||||
}
|
||||
|
||||
/* SetOutputLimits(...)****************************************************
|
||||
* This function will be used far more often than SetInputLimits. while
|
||||
* the input to the controller will generally be in the 0-1023 range (which is
|
||||
* the default already,) the output will be a little different. maybe they'll
|
||||
* be doing a time window and will need 0-8000 or something. or maybe they'll
|
||||
* want to clamp it from 0-125. who knows. at any rate, that can all be done
|
||||
* here.
|
||||
**************************************************************************/
|
||||
void PID::SetOutputLimits(double Min, double Max)
|
||||
{
|
||||
if(Min >= Max) return;
|
||||
outMin = Min;
|
||||
outMax = Max;
|
||||
|
||||
if(inAuto)
|
||||
{
|
||||
if(*myOutput > outMax) *myOutput = outMax;
|
||||
else if(*myOutput < outMin) *myOutput = outMin;
|
||||
|
||||
if(outputSum > outMax) outputSum= outMax;
|
||||
else if(outputSum < outMin) outputSum= outMin;
|
||||
}
|
||||
}
|
||||
|
||||
/* SetMode(...)****************************************************************
|
||||
* Allows the controller Mode to be set to manual (0) or Automatic (non-zero)
|
||||
* when the transition from manual to auto occurs, the controller is
|
||||
* automatically initialized
|
||||
******************************************************************************/
|
||||
void PID::SetMode(int Mode)
|
||||
{
|
||||
bool newAuto = (Mode == AUTOMATIC);
|
||||
if(newAuto && !inAuto)
|
||||
{ /*we just went from manual to auto*/
|
||||
PID::Initialize();
|
||||
}
|
||||
inAuto = newAuto;
|
||||
}
|
||||
|
||||
/* Initialize()****************************************************************
|
||||
* does all the things that need to happen to ensure a bumpless transfer
|
||||
* from manual to automatic mode.
|
||||
******************************************************************************/
|
||||
void PID::Initialize()
|
||||
{
|
||||
outputSum = *myOutput;
|
||||
lastInput = *myInput;
|
||||
if(outputSum > outMax) outputSum = outMax;
|
||||
else if(outputSum < outMin) outputSum = outMin;
|
||||
}
|
||||
|
||||
/* SetControllerDirection(...)*************************************************
|
||||
* The PID will either be connected to a DIRECT acting process (+Output leads
|
||||
* to +Input) or a REVERSE acting process(+Output leads to -Input.) we need to
|
||||
* know which one, because otherwise we may increase the output when we should
|
||||
* be decreasing. This is called from the constructor.
|
||||
******************************************************************************/
|
||||
void PID::SetControllerDirection(int Direction)
|
||||
{
|
||||
if(inAuto && Direction !=controllerDirection)
|
||||
{
|
||||
kp = (0 - kp);
|
||||
ki = (0 - ki);
|
||||
kd = (0 - kd);
|
||||
}
|
||||
controllerDirection = Direction;
|
||||
}
|
||||
|
||||
/* Status Funcions*************************************************************
|
||||
* Just because you set the Kp=-1 doesn't mean it actually happened. these
|
||||
* functions query the internal state of the PID. they're here for display
|
||||
* purposes. this are the functions the PID Front-end uses for example
|
||||
******************************************************************************/
|
||||
double PID::GetKp(){ return dispKp; }
|
||||
double PID::GetKi(){ return dispKi;}
|
||||
double PID::GetKd(){ return dispKd;}
|
||||
int PID::GetMode(){ return inAuto ? AUTOMATIC : MANUAL;}
|
||||
int PID::GetDirection(){ return controllerDirection;}
|
||||
|
||||
90
lib/Arduino-PID-Library/PID_v1.h
Normal file
90
lib/Arduino-PID-Library/PID_v1.h
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
#ifndef PID_v1_h
|
||||
#define PID_v1_h
|
||||
#define LIBRARY_VERSION 1.2.1
|
||||
|
||||
class PID
|
||||
{
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//Constants used in some of the functions below
|
||||
#define AUTOMATIC 1
|
||||
#define MANUAL 0
|
||||
#define DIRECT 0
|
||||
#define REVERSE 1
|
||||
#define P_ON_M 0
|
||||
#define P_ON_E 1
|
||||
|
||||
//commonly used functions **************************************************************************
|
||||
PID(double*, double*, double*, // * constructor. links the PID to the Input, Output, and
|
||||
double, double, double, int, int);// Setpoint. Initial tuning parameters are also set here.
|
||||
// (overload for specifying proportional mode)
|
||||
|
||||
PID(double*, double*, double*, // * constructor. links the PID to the Input, Output, and
|
||||
double, double, double, int); // Setpoint. Initial tuning parameters are also set here
|
||||
|
||||
void SetMode(int Mode); // * sets PID to either Manual (0) or Auto (non-0)
|
||||
|
||||
bool Compute(); // * performs the PID calculation. it should be
|
||||
// called every time loop() cycles. ON/OFF and
|
||||
// calculation frequency can be set using SetMode
|
||||
// SetSampleTime respectively
|
||||
|
||||
void SetOutputLimits(double, double); // * clamps the output to a specific range. 0-255 by default, but
|
||||
// it's likely the user will want to change this depending on
|
||||
// the application
|
||||
|
||||
|
||||
|
||||
//available but not commonly used functions ********************************************************
|
||||
void SetTunings(double, double, // * While most users will set the tunings once in the
|
||||
double); // constructor, this function gives the user the option
|
||||
// of changing tunings during runtime for Adaptive control
|
||||
void SetTunings(double, double, // * overload for specifying proportional mode
|
||||
double, int);
|
||||
|
||||
void SetControllerDirection(int); // * Sets the Direction, or "Action" of the controller. DIRECT
|
||||
// means the output will increase when error is positive. REVERSE
|
||||
// means the opposite. it's very unlikely that this will be needed
|
||||
// once it is set in the constructor.
|
||||
void SetSampleTime(int); // * sets the frequency, in Milliseconds, with which
|
||||
// the PID calculation is performed. default is 100
|
||||
|
||||
|
||||
|
||||
//Display functions ****************************************************************
|
||||
double GetKp(); // These functions query the pid for interal values.
|
||||
double GetKi(); // they were created mainly for the pid front-end,
|
||||
double GetKd(); // where it's important to know what is actually
|
||||
int GetMode(); // inside the PID.
|
||||
int GetDirection(); //
|
||||
|
||||
private:
|
||||
void Initialize();
|
||||
|
||||
double dispKp; // * we'll hold on to the tuning parameters in user-entered
|
||||
double dispKi; // format for display purposes
|
||||
double dispKd; //
|
||||
|
||||
double kp; // * (P)roportional Tuning Parameter
|
||||
double ki; // * (I)ntegral Tuning Parameter
|
||||
double kd; // * (D)erivative Tuning Parameter
|
||||
|
||||
int controllerDirection;
|
||||
int pOn;
|
||||
|
||||
double *myInput; // * Pointers to the Input, Output, and Setpoint variables
|
||||
double *myOutput; // This creates a hard link between the variables and the
|
||||
double *mySetpoint; // PID, freeing the user from having to constantly tell us
|
||||
// what these values are. with pointers we'll just know.
|
||||
|
||||
unsigned long lastTime;
|
||||
double outputSum, lastInput;
|
||||
|
||||
unsigned long SampleTime;
|
||||
double outMin, outMax;
|
||||
bool inAuto, pOnE;
|
||||
};
|
||||
#endif
|
||||
|
||||
11
lib/Arduino-PID-Library/README.txt
Normal file
11
lib/Arduino-PID-Library/README.txt
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
***************************************************************
|
||||
* Arduino PID Library - Version 1.2.1
|
||||
* by Brett Beauregard <br3ttb@gmail.com> brettbeauregard.com
|
||||
*
|
||||
* This Library is licensed under the MIT License
|
||||
***************************************************************
|
||||
|
||||
- For an ultra-detailed explanation of why the code is the way it is, please visit:
|
||||
http://brettbeauregard.com/blog/2011/04/improving-the-beginners-pid-introduction/
|
||||
|
||||
- For function documentation see: http://playground.arduino.cc/Code/PIDLibrary
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/********************************************************
|
||||
* PID Adaptive Tuning Example
|
||||
* One of the benefits of the PID library is that you can
|
||||
* change the tuning parameters at any time. this can be
|
||||
* helpful if we want the controller to be agressive at some
|
||||
* times, and conservative at others. in the example below
|
||||
* we set the controller to use Conservative Tuning Parameters
|
||||
* when we're near setpoint and more agressive Tuning
|
||||
* Parameters when we're farther away.
|
||||
********************************************************/
|
||||
|
||||
#include <PID_v1.h>
|
||||
|
||||
#define PIN_INPUT 0
|
||||
#define PIN_OUTPUT 3
|
||||
|
||||
//Define Variables we'll be connecting to
|
||||
double Setpoint, Input, Output;
|
||||
|
||||
//Define the aggressive and conservative Tuning Parameters
|
||||
double aggKp=4, aggKi=0.2, aggKd=1;
|
||||
double consKp=1, consKi=0.05, consKd=0.25;
|
||||
|
||||
//Specify the links and initial tuning parameters
|
||||
PID myPID(&Input, &Output, &Setpoint, consKp, consKi, consKd, DIRECT);
|
||||
|
||||
void setup()
|
||||
{
|
||||
//initialize the variables we're linked to
|
||||
Input = analogRead(PIN_INPUT);
|
||||
Setpoint = 100;
|
||||
|
||||
//turn the PID on
|
||||
myPID.SetMode(AUTOMATIC);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
Input = analogRead(PIN_INPUT);
|
||||
|
||||
double gap = abs(Setpoint-Input); //distance away from setpoint
|
||||
if (gap < 10)
|
||||
{ //we're close to setpoint, use conservative tuning parameters
|
||||
myPID.SetTunings(consKp, consKi, consKd);
|
||||
}
|
||||
else
|
||||
{
|
||||
//we're far from setpoint, use aggressive tuning parameters
|
||||
myPID.SetTunings(aggKp, aggKi, aggKd);
|
||||
}
|
||||
|
||||
myPID.Compute();
|
||||
analogWrite(PIN_OUTPUT, Output);
|
||||
}
|
||||
|
||||
|
||||
35
lib/Arduino-PID-Library/examples/PID_Basic/PID_Basic.ino
Normal file
35
lib/Arduino-PID-Library/examples/PID_Basic/PID_Basic.ino
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/********************************************************
|
||||
* PID Basic Example
|
||||
* Reading analog input 0 to control analog PWM output 3
|
||||
********************************************************/
|
||||
|
||||
#include <PID_v1.h>
|
||||
|
||||
#define PIN_INPUT 0
|
||||
#define PIN_OUTPUT 3
|
||||
|
||||
//Define Variables we'll be connecting to
|
||||
double Setpoint, Input, Output;
|
||||
|
||||
//Specify the links and initial tuning parameters
|
||||
double Kp=2, Ki=5, Kd=1;
|
||||
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
|
||||
|
||||
void setup()
|
||||
{
|
||||
//initialize the variables we're linked to
|
||||
Input = analogRead(PIN_INPUT);
|
||||
Setpoint = 100;
|
||||
|
||||
//turn the PID on
|
||||
myPID.SetMode(AUTOMATIC);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
Input = analogRead(PIN_INPUT);
|
||||
myPID.Compute();
|
||||
analogWrite(PIN_OUTPUT, Output);
|
||||
}
|
||||
|
||||
|
||||
36
lib/Arduino-PID-Library/examples/PID_PonM/PID_PonM.ino
Normal file
36
lib/Arduino-PID-Library/examples/PID_PonM/PID_PonM.ino
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/********************************************************
|
||||
* PID Proportional on measurement Example
|
||||
* Setting the PID to use Proportional on measurement will
|
||||
* make the output move more smoothly when the setpoint
|
||||
* is changed. In addition, it can eliminate overshoot
|
||||
* in certain processes like sous-vides.
|
||||
********************************************************/
|
||||
|
||||
#include <PID_v1.h>
|
||||
|
||||
//Define Variables we'll be connecting to
|
||||
double Setpoint, Input, Output;
|
||||
|
||||
//Specify the links and initial tuning parameters
|
||||
PID myPID(&Input, &Output, &Setpoint,2,5,1,P_ON_M, DIRECT); //P_ON_M specifies that Proportional on Measurement be used
|
||||
//P_ON_E (Proportional on Error) is the default behavior
|
||||
|
||||
void setup()
|
||||
{
|
||||
//initialize the variables we're linked to
|
||||
Input = analogRead(0);
|
||||
Setpoint = 100;
|
||||
|
||||
//turn the PID on
|
||||
myPID.SetMode(AUTOMATIC);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
Input = analogRead(0);
|
||||
myPID.Compute();
|
||||
analogWrite(3,Output);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
/********************************************************
|
||||
* PID RelayOutput Example
|
||||
* Same as basic example, except that this time, the output
|
||||
* is going to a digital pin which (we presume) is controlling
|
||||
* a relay. the pid is designed to Output an analog value,
|
||||
* but the relay can only be On/Off.
|
||||
*
|
||||
* to connect them together we use "time proportioning
|
||||
* control" it's essentially a really slow version of PWM.
|
||||
* first we decide on a window size (5000mS say.) we then
|
||||
* set the pid to adjust its output between 0 and that window
|
||||
* size. lastly, we add some logic that translates the PID
|
||||
* output into "Relay On Time" with the remainder of the
|
||||
* window being "Relay Off Time"
|
||||
********************************************************/
|
||||
|
||||
#include <PID_v1.h>
|
||||
|
||||
#define PIN_INPUT 0
|
||||
#define RELAY_PIN 6
|
||||
|
||||
//Define Variables we'll be connecting to
|
||||
double Setpoint, Input, Output;
|
||||
|
||||
//Specify the links and initial tuning parameters
|
||||
double Kp=2, Ki=5, Kd=1;
|
||||
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
|
||||
|
||||
int WindowSize = 5000;
|
||||
unsigned long windowStartTime;
|
||||
|
||||
void setup()
|
||||
{
|
||||
windowStartTime = millis();
|
||||
|
||||
//initialize the variables we're linked to
|
||||
Setpoint = 100;
|
||||
|
||||
//tell the PID to range between 0 and the full window size
|
||||
myPID.SetOutputLimits(0, WindowSize);
|
||||
|
||||
//turn the PID on
|
||||
myPID.SetMode(AUTOMATIC);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
Input = analogRead(PIN_INPUT);
|
||||
myPID.Compute();
|
||||
|
||||
/************************************************
|
||||
* turn the output pin on/off based on pid output
|
||||
************************************************/
|
||||
if (millis() - windowStartTime > WindowSize)
|
||||
{ //time to shift the Relay Window
|
||||
windowStartTime += WindowSize;
|
||||
}
|
||||
if (Output < millis() - windowStartTime) digitalWrite(RELAY_PIN, HIGH);
|
||||
else digitalWrite(RELAY_PIN, LOW);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
36
lib/Arduino-PID-Library/keywords.txt
Normal file
36
lib/Arduino-PID-Library/keywords.txt
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#######################################
|
||||
# Syntax Coloring Map For PID Library
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
PID KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
SetMode KEYWORD2
|
||||
Compute KEYWORD2
|
||||
SetOutputLimits KEYWORD2
|
||||
SetTunings KEYWORD2
|
||||
SetControllerDirection KEYWORD2
|
||||
SetSampleTime KEYWORD2
|
||||
GetKp KEYWORD2
|
||||
GetKi KEYWORD2
|
||||
GetKd KEYWORD2
|
||||
GetMode KEYWORD2
|
||||
GetDirection KEYWORD2
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
|
||||
AUTOMATIC LITERAL1
|
||||
MANUAL LITERAL1
|
||||
DIRECT LITERAL1
|
||||
REVERSE LITERAL1
|
||||
P_ON_E LITERAL1
|
||||
P_ON_M LITERAL1
|
||||
19
lib/Arduino-PID-Library/library.json
Normal file
19
lib/Arduino-PID-Library/library.json
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"name": "PID",
|
||||
"keywords": "PID, controller, signal",
|
||||
"description": "A PID controller seeks to keep some input variable close to a desired setpoint by adjusting an output. The way in which it does this can be 'tuned' by adjusting three parameters (P,I,D).",
|
||||
"url": "http://playground.arduino.cc/Code/PIDLibrary",
|
||||
"include": "PID_v1",
|
||||
"authors":
|
||||
[
|
||||
{
|
||||
"name": "Brett Beauregard"
|
||||
}
|
||||
],
|
||||
"repository":
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/br3ttb/Arduino-PID-Library.git"
|
||||
},
|
||||
"frameworks": "arduino"
|
||||
}
|
||||
9
lib/Arduino-PID-Library/library.properties
Normal file
9
lib/Arduino-PID-Library/library.properties
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
name=PID
|
||||
version=1.2.1
|
||||
author=Brett Beauregard
|
||||
maintainer=Brett Beauregard
|
||||
sentence=PID controller
|
||||
paragraph=A PID controller seeks to keep some input variable close to a desired setpoint by adjusting an output. The way in which it does this can be 'tuned' by adjusting three parameters (P,I,D).
|
||||
category=Signal Input/Output
|
||||
url=http://playground.arduino.cc/Code/PIDLibrary
|
||||
architectures=*
|
||||
46
lib/README
Normal file
46
lib/README
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
|
||||
This directory is intended for project specific (private) libraries.
|
||||
PlatformIO will compile them to static libraries and link into executable file.
|
||||
|
||||
The source code of each library should be placed in a an own separate directory
|
||||
("lib/your_library_name/[here are source files]").
|
||||
|
||||
For example, see a structure of the following two libraries `Foo` and `Bar`:
|
||||
|
||||
|--lib
|
||||
| |
|
||||
| |--Bar
|
||||
| | |--docs
|
||||
| | |--examples
|
||||
| | |--src
|
||||
| | |- Bar.c
|
||||
| | |- Bar.h
|
||||
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||
| |
|
||||
| |--Foo
|
||||
| | |- Foo.c
|
||||
| | |- Foo.h
|
||||
| |
|
||||
| |- README --> THIS FILE
|
||||
|
|
||||
|- platformio.ini
|
||||
|--src
|
||||
|- main.c
|
||||
|
||||
and a contents of `src/main.c`:
|
||||
```
|
||||
#include <Foo.h>
|
||||
#include <Bar.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
PlatformIO Library Dependency Finder will find automatically dependent
|
||||
libraries scanning project source files.
|
||||
|
||||
More information about PlatformIO Library Dependency Finder
|
||||
- https://docs.platformio.org/page/librarymanager/ldf.html
|
||||
1
lib/TFT_ILI9163C
Submodule
1
lib/TFT_ILI9163C
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 9b2928a2dfd132d73f0edcd9dcb648f948b956fe
|
||||
33
lib/TimerOne/README.md
Normal file
33
lib/TimerOne/README.md
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#TimerOne Library#
|
||||
|
||||
Paul Stoffregen's modified TimerOne. This version provides 2 main benefits:
|
||||
|
||||
1: Optimized inline functions - much faster for the most common usage
|
||||
2: Support for more boards (including ATTiny85 except for the PWM functionality)
|
||||
|
||||
http://www.pjrc.com/teensy/td_libs_TimerOne.html
|
||||
|
||||
https://github.com/PaulStoffregen/TimerOne
|
||||
|
||||
Original code
|
||||
|
||||
http://playground.arduino.cc/Code/Timer1
|
||||
|
||||
Open Source License
|
||||
|
||||
TimerOne 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/
|
||||
|
||||
Paul Stoffregen forked this version from an early copy of TimerOne/TimerThree
|
||||
which was licensed "Creative Commons Attribution 3.0" and has maintained
|
||||
the original "CC BY 3.0 US" license terms.
|
||||
|
||||
Other, separately developed updates to TimerOne have been released by other
|
||||
authors under the GNU GPLv2 license. Multiple copies of this library, bearing
|
||||
the same name but distributed under different license terms, is unfortunately
|
||||
confusing. This copy, with nearly all the code redesigned as inline functions,
|
||||
is provided under the "CC BY 3.0 US" license terms.
|
||||
|
||||
59
lib/TimerOne/TimerOne.cpp
Normal file
59
lib/TimerOne/TimerOne.cpp
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* 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(TEENSYDUINO) && (defined(KINETISK) || defined(KINETISL))
|
||||
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();
|
||||
}
|
||||
#elif defined(__arm__) && defined(TEENSYDUINO) && defined(__IMXRT1062__)
|
||||
void TimerOne::isr(void)
|
||||
{
|
||||
FLEXPWM1_SM3STS = FLEXPWM_SMSTS_RF;
|
||||
Timer1.isrCallback();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void TimerOne::isrDefaultUnused()
|
||||
{
|
||||
}
|
||||
623
lib/TimerOne/TimerOne.h
Normal file
623
lib/TimerOne/TimerOne.h
Normal file
|
|
@ -0,0 +1,623 @@
|
|||
/*
|
||||
* 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__)
|
||||
|
||||
#if defined (__AVR_ATmega8__)
|
||||
//in some io definitions for older microcontrollers TIMSK is used instead of TIMSK1
|
||||
#define TIMSK1 TIMSK
|
||||
#endif
|
||||
|
||||
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/100000 * microseconds) / 20);
|
||||
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(TEENSYDUINO) && (defined(KINETISK) || defined(KINETISL))
|
||||
|
||||
#if defined(KINETISK)
|
||||
#define F_TIMER F_BUS
|
||||
#elif defined(KINETISL)
|
||||
#define F_TIMER (F_PLL/2)
|
||||
#endif
|
||||
|
||||
// Use only 15 bit resolution. From K66 reference manual, 45.5.7 page 1200:
|
||||
// The CPWM pulse width (duty cycle) is determined by 2 x (CnV - CNTIN) and the
|
||||
// period is determined by 2 x (MOD - CNTIN). See the following figure. MOD must be
|
||||
// kept in the range of 0x0001 to 0x7FFF because values outside this range can produce
|
||||
// ambiguous results.
|
||||
#undef TIMER1_RESOLUTION
|
||||
#define TIMER1_RESOLUTION 32768
|
||||
|
||||
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
|
||||
|
||||
#elif defined(__arm__) && defined(TEENSYDUINO) && defined(__IMXRT1062__)
|
||||
|
||||
public:
|
||||
//****************************
|
||||
// Configuration
|
||||
//****************************
|
||||
void initialize(unsigned long microseconds=1000000) __attribute__((always_inline)) {
|
||||
setPeriod(microseconds);
|
||||
}
|
||||
void setPeriod(unsigned long microseconds) __attribute__((always_inline)) {
|
||||
uint32_t period = (float)F_BUS_ACTUAL * (float)microseconds * 0.0000005f;
|
||||
uint32_t prescale = 0;
|
||||
while (period > 32767) {
|
||||
period = period >> 1;
|
||||
if (++prescale > 7) {
|
||||
prescale = 7; // when F_BUS is 150 MHz, longest
|
||||
period = 32767; // period is 55922 us (~17.9 Hz)
|
||||
break;
|
||||
}
|
||||
}
|
||||
//Serial.printf("setPeriod, period=%u, prescale=%u\n", period, prescale);
|
||||
FLEXPWM1_FCTRL0 |= FLEXPWM_FCTRL0_FLVL(8); // logic high = fault
|
||||
FLEXPWM1_FSTS0 = 0x0008; // clear fault status
|
||||
FLEXPWM1_MCTRL |= FLEXPWM_MCTRL_CLDOK(8);
|
||||
FLEXPWM1_SM3CTRL2 = FLEXPWM_SMCTRL2_INDEP;
|
||||
FLEXPWM1_SM3CTRL = FLEXPWM_SMCTRL_HALF | FLEXPWM_SMCTRL_PRSC(prescale);
|
||||
FLEXPWM1_SM3INIT = -period;
|
||||
FLEXPWM1_SM3VAL0 = 0;
|
||||
FLEXPWM1_SM3VAL1 = period;
|
||||
FLEXPWM1_SM3VAL2 = 0;
|
||||
FLEXPWM1_SM3VAL3 = 0;
|
||||
FLEXPWM1_SM3VAL4 = 0;
|
||||
FLEXPWM1_SM3VAL5 = 0;
|
||||
FLEXPWM1_MCTRL |= FLEXPWM_MCTRL_LDOK(8) | FLEXPWM_MCTRL_RUN(8);
|
||||
pwmPeriod = period;
|
||||
}
|
||||
//****************************
|
||||
// Run Control
|
||||
//****************************
|
||||
void start() __attribute__((always_inline)) {
|
||||
stop();
|
||||
// TODO: how to force counter back to zero?
|
||||
resume();
|
||||
}
|
||||
void stop() __attribute__((always_inline)) {
|
||||
FLEXPWM1_MCTRL &= ~FLEXPWM_MCTRL_RUN(8);
|
||||
}
|
||||
void restart() __attribute__((always_inline)) {
|
||||
start();
|
||||
}
|
||||
void resume() __attribute__((always_inline)) {
|
||||
FLEXPWM1_MCTRL |= FLEXPWM_MCTRL_RUN(8);
|
||||
}
|
||||
|
||||
//****************************
|
||||
// PWM outputs
|
||||
//****************************
|
||||
void setPwmDuty(char pin, unsigned int duty) __attribute__((always_inline)) {
|
||||
if (duty > 1023) duty = 1023;
|
||||
int dutyCycle = (pwmPeriod * duty) >> 10;
|
||||
//Serial.printf("setPwmDuty, period=%u\n", dutyCycle);
|
||||
if (pin == TIMER1_A_PIN) {
|
||||
FLEXPWM1_MCTRL |= FLEXPWM_MCTRL_CLDOK(8);
|
||||
FLEXPWM1_SM3VAL5 = dutyCycle;
|
||||
FLEXPWM1_SM3VAL4 = -dutyCycle;
|
||||
FLEXPWM1_MCTRL |= FLEXPWM_MCTRL_LDOK(8);
|
||||
} else if (pin == TIMER1_B_PIN) {
|
||||
FLEXPWM1_MCTRL |= FLEXPWM_MCTRL_CLDOK(8);
|
||||
FLEXPWM1_SM3VAL3 = dutyCycle;
|
||||
FLEXPWM1_SM3VAL2 = -dutyCycle;
|
||||
FLEXPWM1_MCTRL |= FLEXPWM_MCTRL_LDOK(8);
|
||||
}
|
||||
}
|
||||
void pwm(char pin, unsigned int duty) __attribute__((always_inline)) {
|
||||
setPwmDuty(pin, duty);
|
||||
if (pin == TIMER1_A_PIN) {
|
||||
FLEXPWM1_OUTEN |= FLEXPWM_OUTEN_PWMB_EN(8);
|
||||
IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_01 = 6; // pin 7 FLEXPWM1_PWM3_B
|
||||
} else if (pin == TIMER1_B_PIN) {
|
||||
FLEXPWM1_OUTEN |= FLEXPWM_OUTEN_PWMA_EN(8);
|
||||
IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_00 = 6; // pin 8 FLEXPWM1_PWM3_A
|
||||
}
|
||||
}
|
||||
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) {
|
||||
IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_01 = 5; // pin 7 FLEXPWM1_PWM3_B
|
||||
FLEXPWM1_OUTEN &= ~FLEXPWM_OUTEN_PWMB_EN(8);
|
||||
} else if (pin == TIMER1_B_PIN) {
|
||||
IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_00 = 5; // pin 8 FLEXPWM1_PWM3_A
|
||||
FLEXPWM1_OUTEN &= ~FLEXPWM_OUTEN_PWMA_EN(8);
|
||||
}
|
||||
}
|
||||
//****************************
|
||||
// Interrupt Function
|
||||
//****************************
|
||||
void attachInterrupt(void (*f)()) __attribute__((always_inline)) {
|
||||
isrCallback = f;
|
||||
attachInterruptVector(IRQ_FLEXPWM1_3, &isr);
|
||||
FLEXPWM1_SM3STS = FLEXPWM_SMSTS_RF;
|
||||
FLEXPWM1_SM3INTEN = FLEXPWM_SMINTEN_RIE;
|
||||
NVIC_ENABLE_IRQ(IRQ_FLEXPWM1_3);
|
||||
}
|
||||
void attachInterrupt(void (*f)(), unsigned long microseconds) __attribute__((always_inline)) {
|
||||
if(microseconds > 0) setPeriod(microseconds);
|
||||
attachInterrupt(f);
|
||||
}
|
||||
void detachInterrupt() __attribute__((always_inline)) {
|
||||
NVIC_DISABLE_IRQ(IRQ_FLEXPWM1_3);
|
||||
FLEXPWM1_SM3INTEN = 0;
|
||||
}
|
||||
static void isr(void);
|
||||
static void (*isrCallback)();
|
||||
static void isrDefaultUnused();
|
||||
|
||||
private:
|
||||
// properties
|
||||
static unsigned short pwmPeriod;
|
||||
static unsigned char clockSelectBits;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
extern TimerOne Timer1;
|
||||
|
||||
#endif
|
||||
|
||||
189
lib/TimerOne/config/known_16bit_timers.h
Normal file
189
lib/TimerOne/config/known_16bit_timers.h
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
#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
|
||||
|
||||
// Teensy 4.0
|
||||
//
|
||||
#elif defined(__IMXRT1062__)
|
||||
#define TIMER1_A_PIN 7
|
||||
#define TIMER1_B_PIN 8
|
||||
#define TIMER3_A_PIN 9
|
||||
#define TIMER3_B_PIN 6
|
||||
|
||||
// Arduino Mega
|
||||
//
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
#define TIMER1_A_PIN 11
|
||||
#define TIMER1_B_PIN 12
|
||||
#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__) || defined (__AVR_ATmega328__) || defined (__AVR_ATmega8__)
|
||||
#define TIMER1_A_PIN 9
|
||||
#define TIMER1_B_PIN 10
|
||||
#define TIMER1_ICP_PIN 8
|
||||
#define TIMER1_CLK_PIN 5
|
||||
|
||||
// Minicore generic
|
||||
//
|
||||
#elif defined(__AVR_ATmega48PB__) || defined(__AVR_ATmega88PB__) || defined(__AVR_ATmega168PB__)
|
||||
#define TIMER1_A_PIN 9
|
||||
#define TIMER1_B_PIN 10
|
||||
#define TIMER1_ICP_PIN 8
|
||||
#define TIMER1_CLK_PIN 5
|
||||
#elif defined(__AVR_ATmega328PB__)
|
||||
#define TIMER1_A_PIN 9
|
||||
#define TIMER1_B_PIN 10
|
||||
#define TIMER1_ICP_PIN 8
|
||||
#define TIMER1_CLK_PIN 5
|
||||
#define TIMER3_A_PIN 0
|
||||
#define TIMER3_B_PIN 2
|
||||
#define TIMER3_ICP_PIN 25
|
||||
#define TIMER3_CLK_PIN 26
|
||||
#define TIMER4_A_PIN 1
|
||||
#define TIMER4_B_PIN 2
|
||||
#define TIMER4_ICP_PIN 23
|
||||
#define TIMER4_CLK_PIN 24
|
||||
|
||||
// attiny167
|
||||
//
|
||||
#elif defined (__AVR_ATtiny167__)
|
||||
#define TIMER1_A_PIN 14
|
||||
#define TIMER1_B_PIN 11
|
||||
//#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__) || defined(__AVR_ATmega1284__)
|
||||
#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
|
||||
64
lib/TimerOne/docs/issue_template.md
Normal file
64
lib/TimerOne/docs/issue_template.md
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
Please use this form only to report code defects or bugs.
|
||||
|
||||
For any question, even questions directly pertaining to this code, post your question on the forums related to the board you are using.
|
||||
|
||||
Arduino: forum.arduino.cc
|
||||
Teensy: forum.pjrc.com
|
||||
ESP8266: www.esp8266.com
|
||||
ESP32: www.esp32.com
|
||||
Adafruit Feather/Metro/Trinket: forums.adafruit.com
|
||||
Particle Photon: community.particle.io
|
||||
|
||||
If you are experiencing trouble but not certain of the cause, or need help using this code, ask on the appropriate forum. This is not the place to ask for support or help, even directly related to this code. Only use this form you are certain you have discovered a defect in this code!
|
||||
|
||||
Please verify the problem occurs when using the very latest version, using the newest version of Arduino and any other related software.
|
||||
|
||||
|
||||
----------------------------- Remove above -----------------------------
|
||||
|
||||
|
||||
|
||||
### Description
|
||||
|
||||
Describe your problem.
|
||||
|
||||
|
||||
|
||||
### Steps To Reproduce Problem
|
||||
|
||||
Please give detailed instructions needed for anyone to attempt to reproduce the problem.
|
||||
|
||||
|
||||
|
||||
### Hardware & Software
|
||||
|
||||
Board
|
||||
Shields / modules used
|
||||
Arduino IDE version
|
||||
Teensyduino version (if using Teensy)
|
||||
Version info & package name (from Tools > Boards > Board Manager)
|
||||
Operating system & version
|
||||
Any other software or hardware?
|
||||
|
||||
|
||||
### Arduino Sketch
|
||||
|
||||
```cpp
|
||||
// Change the code below by your sketch (please try to give the smallest code which demonstrates the problem)
|
||||
#include <Arduino.h>
|
||||
|
||||
// libraries: give links/details so anyone can compile your code for the same result
|
||||
|
||||
void setup() {
|
||||
}
|
||||
|
||||
void loop() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Errors or Incorrect Output
|
||||
|
||||
If you see any errors or incorrect output, please show it here. Please use copy & paste to give an exact copy of the message. Details matter, so please show (not merely describe) the actual message or error exactly as it appears.
|
||||
|
||||
|
||||
19
lib/TimerOne/examples/ATTiny85/ATTiny85.ino
Normal file
19
lib/TimerOne/examples/ATTiny85/ATTiny85.ino
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#include <TimerOne.h>
|
||||
#define ledPin 4
|
||||
int ledState = LOW;
|
||||
|
||||
void setup() {
|
||||
pinMode(ledPin, OUTPUT);
|
||||
Timer1.initialize(500000); //The led will blink in a half second time interval
|
||||
Timer1.attachInterrupt(blinkLed);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
}
|
||||
|
||||
void blinkLed(){
|
||||
ledState = !ledState;
|
||||
digitalWrite(ledPin, ledState);
|
||||
}
|
||||
|
||||
|
||||
37
lib/TimerOne/examples/FanSpeed/FanSpeed.ino
Normal file
37
lib/TimerOne/examples/FanSpeed/FanSpeed.ino
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#include <TimerOne.h>
|
||||
|
||||
// This example creates a PWM signal with 25 kHz carrier.
|
||||
//
|
||||
// Arduino's analogWrite() gives you PWM output, but no control over the
|
||||
// carrier frequency. The default frequency is low, typically 490 or
|
||||
// 3920 Hz. Sometimes you may need a faster carrier frequency.
|
||||
//
|
||||
// The specification for 4-wire PWM fans recommends a 25 kHz frequency
|
||||
// and allows 21 to 28 kHz. The default from analogWrite() might work
|
||||
// with some fans, but to follow the specification we need 25 kHz.
|
||||
//
|
||||
// http://www.formfactors.org/developer/specs/REV1_2_Public.pdf
|
||||
//
|
||||
// Connect the PWM pin to the fan's control wire (usually blue). The
|
||||
// board's ground must be connected to the fan's ground, and the fan
|
||||
// needs +12 volt power from the computer or a separate power supply.
|
||||
|
||||
const int fanPin = 4;
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
Timer1.initialize(40); // 40 us = 25 kHz
|
||||
Serial.begin(9600);
|
||||
}
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
// slowly increase the PWM fan speed
|
||||
//
|
||||
for (float dutyCycle = 30.0; dutyCycle < 100.0; dutyCycle++) {
|
||||
Serial.print("PWM Fan, Duty Cycle = ");
|
||||
Serial.println(dutyCycle);
|
||||
Timer1.pwm(fanPin, (dutyCycle / 100) * 1023);
|
||||
delay(500);
|
||||
}
|
||||
}
|
||||
54
lib/TimerOne/examples/Interrupt/Interrupt.ino
Normal file
54
lib/TimerOne/examples/Interrupt/Interrupt.ino
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
#include <TimerOne.h>
|
||||
|
||||
// This example uses the timer interrupt to blink an LED
|
||||
// and also demonstrates how to share a variable between
|
||||
// the interrupt and the main program.
|
||||
|
||||
|
||||
const int led = LED_BUILTIN; // the pin with a LED
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
pinMode(led, OUTPUT);
|
||||
Timer1.initialize(150000);
|
||||
Timer1.attachInterrupt(blinkLED); // blinkLED to run every 0.15 seconds
|
||||
Serial.begin(9600);
|
||||
}
|
||||
|
||||
|
||||
// The interrupt will blink the LED, and keep
|
||||
// track of how many times it has blinked.
|
||||
int ledState = LOW;
|
||||
volatile unsigned long blinkCount = 0; // use volatile for shared variables
|
||||
|
||||
void blinkLED(void)
|
||||
{
|
||||
if (ledState == LOW) {
|
||||
ledState = HIGH;
|
||||
blinkCount = blinkCount + 1; // increase when LED turns on
|
||||
} else {
|
||||
ledState = LOW;
|
||||
}
|
||||
digitalWrite(led, ledState);
|
||||
}
|
||||
|
||||
|
||||
// The main program will print the blink count
|
||||
// to the Arduino Serial Monitor
|
||||
void loop(void)
|
||||
{
|
||||
unsigned long blinkCopy; // holds a copy of the blinkCount
|
||||
|
||||
// to read a variable which the interrupt code writes, we
|
||||
// must temporarily disable interrupts, to be sure it will
|
||||
// not change while we are reading. To minimize the time
|
||||
// with interrupts off, just quickly make a copy, and then
|
||||
// use the copy while allowing the interrupt to keep working.
|
||||
noInterrupts();
|
||||
blinkCopy = blinkCount;
|
||||
interrupts();
|
||||
|
||||
Serial.print("blinkCount = ");
|
||||
Serial.println(blinkCopy);
|
||||
delay(100);
|
||||
}
|
||||
14
lib/TimerOne/keywords.txt
Normal file
14
lib/TimerOne/keywords.txt
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
Timer1 KEYWORD2
|
||||
TimerOne KEYWORD1
|
||||
initialize KEYWORD2
|
||||
start KEYWORD2
|
||||
stop KEYWORD2
|
||||
restart KEYWORD2
|
||||
resume KEYWORD2
|
||||
pwm KEYWORD2
|
||||
disablePwm KEYWORD2
|
||||
attachInterrupt KEYWORD2
|
||||
detachInterrupt KEYWORD2
|
||||
setPeriod KEYWORD2
|
||||
setPwmDuty KEYWORD2
|
||||
isrCallback KEYWORD2
|
||||
16
lib/TimerOne/library.json
Normal file
16
lib/TimerOne/library.json
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"name": "TimerOne",
|
||||
"keywords": "timer",
|
||||
"description": "Allow to use the built-in Timer1",
|
||||
"repository":
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/PaulStoffregen/TimerOne.git"
|
||||
},
|
||||
"frameworks": "arduino",
|
||||
"platforms":
|
||||
[
|
||||
"atmelavr",
|
||||
"teensy"
|
||||
]
|
||||
}
|
||||
10
lib/TimerOne/library.properties
Normal file
10
lib/TimerOne/library.properties
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
name=TimerOne
|
||||
version=1.1
|
||||
author=Stoyko Dimitrov, Jesse Tane, Jérôme Despatis, Michael Polli, Dan Clemens, Paul Stoffregen
|
||||
maintainer=Paul Stoffregen
|
||||
sentence=Use hardware Timer1 for finer PWM control and/or running an periodic interrupt function
|
||||
paragraph=
|
||||
category=Timing
|
||||
url=http://playground.arduino.cc/Code/Timer1
|
||||
architectures=avr
|
||||
|
||||
22
platformio.ini
Normal file
22
platformio.ini
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[env:nanoatmega328]
|
||||
platform = atmelavr
|
||||
board = nanoatmega328
|
||||
framework = arduino
|
||||
lib_deps =
|
||||
adafruit/Adafruit BusIO@^1.14.1
|
||||
adafruit/Adafruit GFX Library@^1.11.3
|
||||
mbed-billycorgan123/TFT_ILI9163C@0.0.0+sha.f0799be044ff
|
||||
Adafruit ST7735 and ST7789 Library
|
||||
Wire
|
||||
lib_ignore =
|
||||
SD
|
||||
1046
src/Maiskolben_TFT.ino
Normal file
1046
src/Maiskolben_TFT.ino
Normal file
File diff suppressed because it is too large
Load diff
195
src/definitions.h
Normal file
195
src/definitions.h
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
#define VERSION "3.1"
|
||||
#define EE_VERSION 31
|
||||
#define EEPROM_CHECK 42
|
||||
|
||||
#define BAR_HEIGHT 4 //Should be no bigger than 5
|
||||
|
||||
/*
|
||||
TIPS ARE SPECIFIED FOR 450 DEGREE MAX
|
||||
If read 1023 on Analog in, the tip is turned off automatically
|
||||
*/
|
||||
#define TEMP_MAX 450
|
||||
#define TEMP_MIN 200
|
||||
#define TEMP_STBY 150
|
||||
#define TEMP_COLD 50// (adc_offset + 15)
|
||||
|
||||
#define SHUTOFF_ACTIVE
|
||||
#define BOOTHEAT_ACTIVE
|
||||
|
||||
#define STANDBY_TIMEOUT 240 // seconds without any significant temperature drop, if exceeded it will standby
|
||||
#define OFF_TIMEOUT 900 // seconds in standby before turning off
|
||||
|
||||
#define TEMP_RISE 0.1 //threshold temperature, that must be exceeded delta in given time:
|
||||
#define TEMP_UNDER_THRESHOLD 30 // x (TIME_COMPUTE_IN_MS + DELAY_BEFORE_MEASURE)
|
||||
#define THRES_MAX_DECEED 5 //max times the threshold temperature may be undercut by the current temperature
|
||||
|
||||
//Temperature in degree to rise at least in given time
|
||||
#define TEMP_MIN_RISE 1
|
||||
//Time in that the temperature must rise by the set temperature
|
||||
#define TEMP_RISE_TIME 5000 // increase from 1000ms to 5000ms to enshure proper heating
|
||||
|
||||
//#define OLD_PWM
|
||||
|
||||
// RX 0
|
||||
// TX 1
|
||||
#define SW_STBY 2
|
||||
#define HEATER_PWM 3
|
||||
#define SW_DOWN 4
|
||||
#define HEAT_LED 5
|
||||
#define SW_UP 6
|
||||
#define SW_T3 7
|
||||
#define SW_T2 8
|
||||
#define SW_T1 9
|
||||
#define TFT_CS 10 // Display Pin: 7 CS
|
||||
// MOSI 11 // Display Pin: 4 SDA
|
||||
#define POWER 12 //use MISO PULLUP as switch
|
||||
// SCK 13 // Display Pin: 3 SCK
|
||||
#define TEMP_SENSE A0
|
||||
#define STBY_NO A1 // Display Pin: 5 RES
|
||||
#define BAT_C3 A2
|
||||
#define BAT_C2 A3
|
||||
#define BAT_C1 A4
|
||||
#define TFT_DC A5 // Display Pin: 6 RS
|
||||
#ifdef PIN_A7
|
||||
#define CHARGEDET A6
|
||||
#define VIN A7
|
||||
#endif
|
||||
|
||||
#define kp 0.03
|
||||
#define ki 0.00001
|
||||
#define kd 0.0
|
||||
|
||||
#define TIME_COMPUTE_IN_MS 10
|
||||
#define TIME_MEASURE_VOLTAGE_IN_MS 200
|
||||
#define TIME_SW_POLL_IN_MS 10
|
||||
#define DELAY_BEFORE_MEASURE 10
|
||||
#define DELAY_MAIN_LOOP 10
|
||||
#define PID_SAMPLE_TIME 10
|
||||
|
||||
#define ADC_TO_TEMP_GAIN 0.54 //default value if no calibration is performed
|
||||
#define ADC_TO_TEMP_OFFSET 42.8 //default value if no calibration is performed
|
||||
|
||||
#define EEPROM_SET_T 8
|
||||
#define EEPROM_VERSION 10
|
||||
#define EEPROM_DISPLAY 11
|
||||
#define EEPROM_OPTIONS 12
|
||||
#define EEPROM_REVISION 13
|
||||
#define EEPROM_ADCTTG 14
|
||||
#define EEPROM_ADCOFF (EEPROM_ADCTTG + sizeof(float))
|
||||
|
||||
#define EEPROM_INSTALL 42
|
||||
#define REF_T1 275
|
||||
#define REF_T2 410
|
||||
#define DELTA_REF_T (REF_T2 - REF_T1)
|
||||
|
||||
|
||||
typedef enum POWER_SOURCE {
|
||||
NO_INIT,
|
||||
POWER_USB,
|
||||
POWER_CORD,
|
||||
POWER_LIPO,
|
||||
POWER_CHARGING
|
||||
} p_source;
|
||||
typedef enum ERROR_TYPE {
|
||||
NO_ERROR,
|
||||
EXCESSIVE_FALL,
|
||||
NOT_HEATING,
|
||||
NO_TIP,
|
||||
BATTERY_LOW,
|
||||
USB_ONLY
|
||||
} error_type;
|
||||
|
||||
const unsigned char power_cord [] PROGMEM = {
|
||||
0x00, 0x00, 0xC0,
|
||||
0x00, 0xFF, 0xC0,
|
||||
0x01, 0xFF, 0xDF,
|
||||
0x03, 0xFF, 0xDF,
|
||||
0xFB, 0xFF, 0xC0,
|
||||
0x03, 0xFF, 0xDF,
|
||||
0x01, 0xFF, 0xDF,
|
||||
0x00, 0xFF, 0xC0,
|
||||
0x00, 0x00, 0xC0
|
||||
};
|
||||
|
||||
const unsigned char maiskolben [] PROGMEM = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0xe0, 0x60, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xcf, 0xff, 0xa0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0xdc, 0xf7,
|
||||
0x18, 0x47, 0x89, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
|
||||
0x26, 0x78, 0xc6, 0x33, 0x9c, 0x7f, 0x0c, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x08, 0x23, 0x49, 0xe6, 0x1b, 0xff, 0xf8, 0x39, 0xd0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xc5, 0x31, 0xcf, 0xe7, 0x3f, 0xfe, 0x14, 0x21, 0x08,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x47, 0xf9, 0xff, 0xff, 0xcc,
|
||||
0x40, 0x08, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x4e,
|
||||
0x0f, 0xc1, 0x08, 0x04, 0x63, 0x00, 0x21, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x47, 0xe0, 0x0c, 0x01, 0x08, 0x07, 0xaf, 0x80, 0x60, 0x84, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x02, 0x0c, 0x01, 0x8c, 0xc7, 0xa4, 0x80, 0xe0, 0xf4,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x03, 0x0c, 0x60, 0x9f, 0xc7,
|
||||
0xf0, 0xf3, 0x33, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x83,
|
||||
0x0e, 0xe0, 0x77, 0x69, 0x9a, 0xf7, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0c, 0xfd, 0xb7, 0xb6, 0x67, 0x79, 0x9f, 0xfe, 0xee, 0x12, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xfc, 0xf3, 0xbe, 0xff, 0xfb, 0xff, 0xf8, 0x46, 0x12,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xcd, 0xcf, 0xbc, 0x63, 0x18, 0x6e,
|
||||
0x21, 0x80, 0x42, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x8c, 0xfe,
|
||||
0x08, 0x42, 0x08, 0x44, 0x21, 0x48, 0x42, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x06, 0x84, 0xe2, 0x1e, 0x4a, 0x18, 0x44, 0xe1, 0xc0, 0x63, 0x0f, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x63, 0x3c, 0x7b, 0x18, 0x6e, 0x60, 0x80, 0x31, 0x07,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x65, 0xec, 0x71, 0x08, 0x22,
|
||||
0x10, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x39,
|
||||
0x84, 0x21, 0x8c, 0x33, 0x10, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x08, 0x38, 0x84, 0x00, 0x08, 0x32, 0x10, 0x02, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x58, 0x10, 0x84, 0x00, 0x08, 0x20, 0x10, 0x03, 0xf1, 0x9f,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x70, 0x44, 0x60, 0x08, 0x23,
|
||||
0x30, 0xc4, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x00,
|
||||
0xc7, 0x1f, 0xff, 0xff, 0x1f, 0x84, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x08, 0xc0, 0x7f, 0x82, 0x10, 0x8c, 0x03, 0x08, 0x84, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x78, 0x82, 0x10, 0x88, 0x01, 0x08, 0x84, 0x10, 0x87,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7c, 0x28, 0x82, 0x18, 0xc8, 0x21,
|
||||
0x08, 0x82, 0x10, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfc, 0x28,
|
||||
0x42, 0x08, 0xc0, 0x21, 0x8c, 0x42, 0x10, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00,
|
||||
0x00, 0x3f, 0xfc, 0x18, 0x42, 0x08, 0xc4, 0x11, 0x8c, 0x42, 0x10, 0x83, 0x80, 0x00, 0x00, 0x00,
|
||||
0x7f, 0xff, 0xfe, 0x89, 0xfc, 0xff, 0x94, 0x0c, 0x42, 0x08, 0x44, 0x30, 0x88, 0x42, 0x10, 0x03,
|
||||
0x18, 0x00, 0x00, 0x00, 0x06, 0xff, 0xff, 0xff, 0xff, 0x00, 0x04, 0x0c, 0x62, 0x00, 0x04, 0x00,
|
||||
0x88, 0x42, 0x10, 0x03, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x04, 0x1c,
|
||||
0x20, 0x00, 0x88, 0x00, 0x88, 0x42, 0x10, 0xc7, 0x06, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x07, 0x80, 0x1c, 0x23, 0x10, 0xc8, 0x00, 0x8c, 0x43, 0x30, 0xf9, 0x01, 0xf0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x37, 0x9d, 0xbc, 0x30, 0xfe, 0xe7, 0x6f, 0x11,
|
||||
0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xce, 0x04, 0x4c, 0xe7, 0x9e, 0x2f,
|
||||
0x31, 0x8e, 0x64, 0x31, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xce, 0x23,
|
||||
0x8f, 0xe7, 0x1d, 0xc7, 0x31, 0x8c, 0x64, 0x11, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x02, 0x46, 0x30, 0xcf, 0xf6, 0x1c, 0xe6, 0x39, 0xcc, 0x64, 0x11, 0x00, 0x06, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x44, 0x38, 0xcc, 0x76, 0x18, 0xc2, 0x3d, 0x2c, 0x6c, 0x13,
|
||||
0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x44, 0x38, 0xcc, 0x66, 0x10, 0x86,
|
||||
0x31, 0x08, 0x48, 0x13, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x44, 0x38,
|
||||
0xc0, 0x44, 0x10, 0x84, 0x21, 0x00, 0x48, 0x12, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01, 0x40, 0x30, 0x80, 0x44, 0x01, 0x04, 0x20, 0x00, 0x48, 0x1e, 0x00, 0x01, 0x80, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x84, 0x44, 0x21, 0x04, 0x20, 0x0c, 0xfc, 0x26,
|
||||
0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x86, 0xcc, 0x21, 0x04,
|
||||
0x23, 0x0f, 0x8e, 0xc2, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00,
|
||||
0x8e, 0xff, 0xff, 0x0f, 0xfb, 0xf9, 0x84, 0x46, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x80, 0x71, 0xf0, 0x6c, 0x31, 0xc4, 0x40, 0x19, 0x00, 0x46, 0x00, 0x00, 0x30, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xb8, 0x30, 0x4c, 0x21, 0x04, 0x40, 0x11, 0x00, 0x46,
|
||||
0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x20, 0x20, 0x48, 0x20, 0x00,
|
||||
0x02, 0x11, 0x08, 0x44, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x28,
|
||||
0x20, 0x08, 0x02, 0x00, 0x80, 0x11, 0x08, 0x4c, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x22, 0x18, 0x20, 0x00, 0x02, 0x00, 0x80, 0x13, 0x1c, 0xd8, 0x00, 0x00, 0x03, 0x40,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x18, 0x20, 0x00, 0x42, 0x08, 0x84, 0x1d, 0xe6, 0x38,
|
||||
0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x18, 0x21, 0x1c, 0x7e, 0x0e,
|
||||
0x7f, 0x90, 0x44, 0x38, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x7c,
|
||||
0x7c, 0xcc, 0x31, 0x88, 0x42, 0x10, 0x44, 0x38, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x1e, 0x42, 0x10, 0x08, 0x21, 0x08, 0x42, 0x10, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x40, 0x00, 0x08, 0x20, 0x08, 0x62, 0x10, 0x8c, 0x70,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x08, 0x00, 0x08,
|
||||
0xc6, 0x21, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xd8,
|
||||
0x60, 0x08, 0x44, 0x3f, 0xff, 0xe7, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
11
test/README
Normal file
11
test/README
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
This directory is intended for PlatformIO Test Runner and project tests.
|
||||
|
||||
Unit Testing is a software testing method by which individual units of
|
||||
source code, sets of one or more MCU program modules together with associated
|
||||
control data, usage procedures, and operating procedures, are tested to
|
||||
determine whether they are fit for use. Unit testing finds problems early
|
||||
in the development cycle.
|
||||
|
||||
More information about PlatformIO Unit Testing:
|
||||
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html
|
||||
Loading…
Reference in a new issue