gergelytakacs / automationshield Goto Github PK
View Code? Open in Web Editor NEWArduino library and MATLAB/Simulink API for the AutomationShield Arduino expansion boards for control engineering education.
License: Other
Arduino library and MATLAB/Simulink API for the AutomationShield Arduino expansion boards for control engineering education.
License: Other
Current notes:
Done
(23-24.4.2018)
External libraries have been included by the GIT submodules functionality. Compilation is problematic, because the libraries use includes without a path, therefore if compiled from the root directory of AutomationShield, it fails.
Can the CPATH
or similar environment variables used to direct the preprocessor to find these?
Project finish: 15.05.2018, 14:00. Exams, Tue, 10:00 starting from 22.05.2018 (mistakes in book up to 20.05.2018, 12 PM)
Make sure that when the user initializes sampling time for the sampler function, the variable can be used elsewhere, eg. In the PID function.
Redesign of the PID functionality to increase usability and scalability. This is, in essence a continuation of #13 .
@rkoplinger suggested (in person) to move PID functionality in its own class. This, I have initially rejected for I have thought that having something like AutomationShield.pid()
would simplify the use of the library from the end users perspective. Then came all the versions for absolute and incremental inputs, then the discrepancies between the tuning constants (Kp, Ki, Kd or Kp Ti Td) and of course saturation, integration windup and all that. @rkoplinger was right, so I have changed my mind.
I think that the PID functionality needs to be redesigned for these reasons. Here are some ideas (not necessarily instructions) how to change it:
PIDClass
(constructed as PID
)PID.tuningKp()
and PID.tuningKi
... (Can you do PID.tuning.Kp()
? that would be even better)PID.beginAbsolute()
(Again, can it be PID.begin.absolute()`) and counterparts.PID.windup(float hi, float low)
)PID.compute(float error)
or something like that.These are just ideas, please contribute.
Finish PCB and parts list ASAP
This issue describes the common tasks needed for an efficient start of a thesis work. This issue is meant for bachelor's theses aimed at the AutomationShield project.
Every thesis work is a bit different, so is every student. Do not forget that you are doing this to learn, so you can eventually say (maybe on your CV) that you know
Arduino's constrain function is for integers, we need the same for floats.
Put an empty .development
in the root folder in order to edit the examples and while working. Don't itegrate the file into the Gi repo!
Please stick to the Arduino API style guide that can be found here when writing the shield API's.
Namely:
begin()
to initialize a library instance, usually with some settings. Use end() to stop it.read()
to read inputs, and write() to write to outputs, e.g. digitalRead()
, analogWrite()
, etc.According to this the AutomationShield library will use:
begin()
to initialize the board.
sensorRead()
to read the outputs "y",
referenceRead()
to read reference "r" (if there is one) and
actuatorWrite()
to send input ''u".
calibration()
to perform optional calibration tasks before moving into the loop.
bool _wasCalibrated
is a Boolean flag to read calibration status.
All boards should use these basic functions so that the library remains consistent. Determine which type of input/output will be likely most used by the user and use those in these functions. If you want to use more types of sensor readings (voltage, physical units etc.) then it is suggested to get creative based on this. Such as
sensorReadVoltage()
to read the outputs "y" in V,sensorReadCelsius()
to read the outputs "y" in degrees Celsius, etc.Pins locations for the inputs and outputs should be stored as #define
tokens. Use all capitals and begin the token with the name of the device, continue with an underscore, variable symbol of the quantity and the word pin. So, for example the output pin of the Opto shield will be OPTO_YPIN
. Other examples of these tokens are:
#define OPTO_RPIN 0 // Potentiometer runner (Reference, r)
#define OPTO_YPIN 1 // LDR (Sensor)
#define OPTO_YAUX 2 // Auxiliary LDR
#define OPTO_UPIN 3 // LED (Actuator)
Header files for hardware API are named after the hardware, contain capitals. For example for the Magneto device the full name will be MagnetoShield, thus the API for the device will be initialized in the MagnetoShield.h
header not magnetoshield.h
. Similarly, the API will have the class, methods and other things in the MagnetoShield.cpp
source file.
The API for the particular hardware will use the common header AutomationShield.h
, which in turn will load other basic headers such as Sampling.h
and PID.h
. Thus, in the end, the user should just load the particular header in the example file, such as MagnetoShield.h
.
The header (*.h
) should just contain forward declarations of programming entities (e.g. void function()
) but not the actual functions, these go into the source (*.cpp
)
For naming functions use camel case, not snake case. Avoid underscores, if possible. Thus, you should use - myAwesomeFunction()
, instead of my_awesome_function()
. This is a thing of preference and consistence.
3.3 V compatibilty
begin()
method: analogReference(EXTERNAL)
. See more here.MATLAB
If you want to include experimental measurements, use the following naming conventions for the mat
files:
C_
- from controlID_
- from identificationC_PID_3000us.mat
.myFile.mat
will work on Windows if you refer to it with lower case myfile.mat
, it won't on Linux (e.g. when testing CI).clc
and clear
use startScript
in the beginning, otherwise the continuous integration will fail, since the clear
command clears those variables needed for CI. (startScript
defines some exceptions for clear
).CI_Test
. You can test its existence with exist()
to run CI specific parts of your code.CI_Test
, which will limit solver iterations, optimization runtime, etc. (this is really specific to your application).*.mat
file. For example modeling runs, but the model is saved and loaded in control examples. Don't just assume that a variable exists in the workspace.Library file and folder structure
Printing to serial
The primary point of any example is to output dynamic measurements to the plotter or for logging. Therefore any kind of diagnostic data is subject to conditional compilation, enabled by flags of the user. This functionality inside the header and cpp files is realized by the
AutomationShield.serialPrint("Message");
method. Please DO NOT USE the regular Serial.print()
function inside header and realization files.
Shield releases
#define SHIELDRELEASE n
to distinguish between different versions. The n
should represent release order of specific version.ATSAMD Compatibility
Serial
works without changes. The board does not reset upon accessing serial link, unlike in the case of AVR. Push reset button manually.analogRead
works without changes (but tolerates only 3.3 V!). Unless changed, the resolution is still 10bit. So by default 1023 level is 3.3 V.ARDUINO_ARCH_SAMD
and not ARDUINO_ARCH_SAM
. So the following example works#if defined(ARDUINO_ARCH_AVR)
// AVR-specific code
#elif defined(ARDUINO_ARCH_SAMD)
// SAM-specific code
#else
// generic, non-platform specific code
#endif
or to a more C standard
#ifdef ARDUINO_ARCH_AVR
// AVR-specific code
#elif ARDUINO_ARCH_SAMD
// SAM-specific code
#else
// generic, non-platform specific code
#endif
in this case of course you may employ #ifndef
etc. preprocessor directives.
You may consult this tutorial for a decent start on C preprocessor basics for the Arduino IDE.
Others
Serial
and do not use Serial
within the source code, only in examples..h
) and implementation (.cpp
) file. Since the IDE tries to build every implementation file in the library, this will cache the Servo library, which will then conflict with other AS devices. The solution is, in this case, just use a header file - it will not be included anywhere else but the examples.Useful Arduino API environment variables
VARIANT_MCK
Clock speed in Hz for ATSAMD, does not seem to work for AVRJust for fun
TIME_WASTED_HERE
that shall express the time in hours wasted in finding bugs. :) (Thanks @AnnaVargova)Not very well documented!
@Gabor7697 has found out that the LED in the OptoShield is too bright, causing resolution and calibratin issues. At 5/255 analogWrite levels the sensor ouput is 900/1023; reducing resolution. Moreover according to him:
All of the solutions above should be possibly tested.
@Gabor7697's calculations on a possible change in the LDR voltage divider.
The feedback process (because of the bad ranging) is not very nice, looks something like this:
Design the clamp. The clamp holds the beam.
It needs an evaluation of the current needs of the SMA wire.
There could be a function solving differential equations with a single input and a single output.
This would be excellent for trying control without the actual hardware, representing the hardware as models and possibly serve as a basis for further functions, like tf()
in Matlab.
The function could:
u
,a
and b
y
y = difference(u, a, b);
Some challenges:
Difference.begin(a,b);
y=Difference.compute(u);
Others
sizeof()
then divide by type size in bytesThis issue details the style guide and practices for writing the AutomationShield Wiki. The current best practices are seen in the HeatShield Wiki.
We will need to perform matrix computations to calcualte LQ gain and to implement other "modern" control methods. For this floating point matrix algebra needs to be implemented on the Arduino, which raises questions of memory efficiency (ROM, RAM) and computational efficiency (time). It is a question whether we should implement
To test solutions, a standard test program for matrix computations should be created, this should include matrix-matrix multiplication, matrix-vector multiplication, transposition and inverse. The standard test program should evaluate memory efficiency (RAM, ROM; e.g. by consulting compiler output relative to a known reference, like an empty program) and timing (e.g. by using micros()
).
A good motivation to have our own routines would be to have control over the methods and to use application-specific requirements to make them more efficient, e.g. a module that implements "control theory" specific matrix algebra.
Opto.sensorRead should be in percents as well.
The reason is, that the Arduino SerialPlotter will not play nicely with values that are an order of magnitude different. Eg. If input runs to 100, you wont see anything on the screen from output.
This of course means, a calibration function is needed.
Create Wiki entries for the PID function
The Sampling Wiki needs improvement.
Old and new shields should have a self-test function that tests hardware capability and gives diagnostics data.
Tibor updated the scheme for the opto Wiki. Please also
Add (fill) the component table in the Opto wiki.
Comment and document the Sampling functionality to Wiki.
There should be an error handler function that can be turned off. Say there is a #define at the beginning and if it is true, the error handler is called, otherwise not. the message could be passed to the error function, which then starts an infinite loop... We could also say that LED13 on the 'duino will be an error led.
The readme.md should be brief and simple. Nobody reads it anyways. A longer description for the library should be inlcuded in the Wiki instead.
If we start to replicate the same ideas and thoughts in both, it will be a nightmare to maintain it.
The readme should tell how to isntall and where to find more info, that's about it. (Maybe verison number, authors etc.) but no detailed description of functions etc.
Please include all hardware design ideas and "bugs" that can be improved upon in the next revision. Provide ideas for upcoming work.
Create a step( )
function that will drive the inputs to the floating point input u
, and list the input-output in a CSV format to the serial port.
Include the Keywords for Arduino IDE for all your functions.
Ideas to be implemented in the next iteration of the MagnetoShield
@TiborKonkoly please fill out the table with the components required to make an OptoShield
Implement and use an anti-windup function for the integral component. Have a stand alone-function for this. Use function overloading to differentiate between versions with and without anti-windup
Create various versions of the PID function with or without anti-windup etc. by function overloading
Find a good name for the heating thingy. HeatShield? HotShield? etc?
Tagline: "Burning your fingers has never been so easy. Introducing the HotShield" :)
The Optical.begin
method should also initialize the auxiliary LED and LDR pins.
Select baseline pid implementation, this case "PID1". that shall be the basis from further on and renamed to "pid"
Current naming scheme is pid() for the absolute and pidInc() for the incremental version. There are now two competing versions for the absolute, these need to be unified. Anyone with a better idea for naming the pid() functions (mainly differentiating them) let us know here.
A future release of the Opto hardware could include another weaker LED, mounted at the middle of the tube and acting as a disturbance signal.
Find a cheap piezoceramic film transducer that can be used in (relatively) low cost shields.
This sticky issue and the post summarizes some hardware design practices for the AutomationShield devices. The current list is quite randomly organized, make sure you read it all. Please comment any other ideas that are generically valid.
Creed
The creed of an AutomationShield hardware device are, that it shall be
Generic notes
Programming Port
when using the device. No applications for the Native Port
.3.3V Compatibility
Make the shield 3.3 V compatible at all cost: New shields and updates to old shields (especially those with fast dynamics) should be made 3.3 V compatible. Here are some concepts to consider:
AREF
pin doesn't change anything, device still takes internal reference though. This has been tested on the Zero / Due / Uno without issues.Find a good name for the ball blower thingy. Inspire by the existing naming scheme Opto and Moto
Create a universal step() function for all shields.
It's impossible to reverse engineer this : https://github.com/adafruit/Adafruit_VL53L0X/tree/master/src
The keywords file needs your specific keywords for Arduino IDE.
Please include all hardware design ideas and "bugs" that can be improved upon in the next revision. Provide ideas for upcoming work.
The name of the shield is Opto not Optical, this may be confusing to others.
How to get high voltage on the board? Look for ways to step-up the 12 V source. DC-DC converters? Would that be possible?
Todo:
Done:
17.04.2018
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.