diff --git a/.gitattributes b/.gitattributes
deleted file mode 100644
index dfe0770..0000000
--- a/.gitattributes
+++ /dev/null
@@ -1,2 +0,0 @@
-# Auto detect text files and perform LF normalization
-* text=auto
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..f288702
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index fc915b6..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2018 AlexGyver
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/README.md b/README.md
index fe5e06a..89a6e72 100644
--- a/README.md
+++ b/README.md
@@ -1,275 +1,77 @@
-
-# Светомузыка на Arduino и WS2812b
-* [Описание проекта](#chapter-0)
-* [Папки проекта](#chapter-1)
-* [Схемы подключения](#chapter-2)
-* [Материалы и компоненты](#chapter-3)
-* [Как скачать и прошить](#chapter-4)
-* [FAQ](#chapter-5)
-* [Полезная информация](#chapter-6)
-[](https://www.youtube.com/channel/UCgtAOyEQdAyjvm9ATCi_Aig?sub_confirmation=1)
-
-Версии прошивки
-* 15.03.2018, colorMusic_v1.1:
- * Добавлена плавность режиму цветомузыки по частотам! Настройка SMOOTH_STEP
- * Добавлен режим стробоскопа с целой кучей настроек!
-* 16.03.2018 colorMusic_v2.0:
- * Добавлено управление с ИК пульта! Купить пульт можно по этой ссылке, цена вопроса 50р
- * 7 режим - Режим подсветки
- * 8 режим - Режим бегущих частот
- * 9 режим - Анализатор спектра (Версия 2.1)
- * У некоторых режимов появились подрежимы
- * Возможна работа БЕЗ потенциометра. Читайте ниже в инструкции по эксплуатации
-* 18.03.2018 colorMusic_v2.2:
- * Настройки сохраняются в память (энергонезависимую)
-* 19.03.2018 colorMusic_v2.3:
- * Улучшена производительность, почищен мусор
- * В 7 режиме радугу можно остановить и пустить вспять
-* 15.05.2018 colorMusic_v2.6:
- * Изменена библиотека ИК пульта, пульт работает без глюков
-* 28.09.2018 colorMusic_v2.7 (by Евгений Зятьков):
- * Настройка пульта внесена в скетч, тип пульта настраивается в IR_RCT
- * Добавлена поддержка Arduino Mega и Pro Micro
- * Исправлены мелкие баги
-
-
-## Описание проекта
-Крутейшая свето- цветомузыка на Arduino и адресной светодиодной ленте WS2812b
-Управление:
-- Однократное нажатие кнопки: смена режима
-- Удержание кнопки: калибровка нижнего порога шума
-
-Режимы работы (переключаются кнопкой):
-- VU meter (столбик громкости): от зелёного к красному
-- VU meter (столбик громкости): плавно бегущая радуга
-- Светомузыка по частотам: 5 полос симметрично
-- Светомузыка по частотам: 3 полосы
-- Светомузыка по частотам: 1 полоса
-- Стробоскоп (Версия 2.0)
-- Подсветка (Версия 2.0)
-- Бегущие частоты (Версия 2.0)
-- Анализатор спектра (Версия 2.1)
-
-Особенности:
-- Плавная анимация (можно настроить)
-- Автонастройка по громкости (можно настроить)
-- Фильтр нижнего шума (можно настроить)
-- Автокалибровка шума при запуске (можно настроить)
-- Поддержка стерео и моно звука (можно настроить)
-- Поддержка ИК пульта (Версия 2.0)
-- Лента не гаснет полностью (Версия 2.0)
-- Настройки сохраняются в памяти (Версия 2.2)
-- Подробности в видео: https://youtu.be/nu31By9Phdc
-
-
-## Папки
-**ВНИМАНИЕ! Если это твой первый опыт работы с Arduino, читай [инструкцию](#chapter-4)**
-- **libraries** - библиотеки проекта. Заменить имеющиеся версии
-- **firmware** - прошивка для Arduino, нужный в папке открыть в Arduino IDE ([инструкция](#chapter-4))
-- **schemes** - схемы подключения
-
-
-## Схемы
-### Обычная
-
-### С микрофоном
-
-
-
-## Материалы и компоненты
-### Ссылки оставлены на магазины, с которых я закупаюсь уже не один год
-* Arduino NANO 328p – искать
-* https://ali.ski/tI7blh
-* https://ali.ski/O4yTxb
-* https://ali.ski/6_rFIS
-* https://ali.ski/gb92E-
-* Giant4 (Россия)
-* Адресная лента
-* https://ali.ski/crrqi1
-* https://ali.ski/2I3be
-* Купить в РФ, 60 свет/метр, 30 свет/метр
-* Black PCB / White PCB – цвет подложки ленты, чёрная / белая. В видео была чёрная
-* 1m/5m – длина ленты в метрах (чтобы заказать 2 метра, берите два заказа 1m, очевидно)
-* 30/60/74/96/100/144 – количество светодиодов на 1 метр ленты. В видео использовалась лента 60 диодов на метр
-* IP30 лента без влагозащиты (как на видео)
-* IP65 лента покрыта силиконом
-* IP67 лента полностью в силиконовом коробе
-* Постфикс ECO – лента чуть более низкого качества, меньше меди, на длинной ленте будет сильно проседать яркость
-* Лента как на видео: Black PCB 5m 60 IP30
-* Понижайка для автомобиля https://ali.ski/W8cC2
-* БП 5V Али искать (минимум 3A на каждые 100 LED)
-* https://ali.ski/DItEG
-* https://ali.ski/t3YFfU
-* Адаптер питания 5.5х2.1 https://ali.ski/C6YFu
-* Аудио гнездо https://ali.ski/RLsI0
-* Разветвитель наушников https://ali.ski/REM6Pg
-* ИК пульт (для версии 2.0 WAVGAT) https://ali.ski/uQJ7x
-* Звук через микрофон
-* Микрофон модуль https://ali.ski/QTC0S
-* Звук по FM радио
-* Передатчик FM http://ali.ski/29sic http://ali.ski/lklMs
-* Передатчик “сделай сам” http://ali.ski/YsmHW http://ali.ski/wmNkEX
-* Приёмник FM из видео http://ali.ski/VsnK0 http://ali.ski/uVp3_
-* Понижайка 3.3V http://ali.ski/ftSy1x http://ali.ski/acDEN
-* Приёмник “сделай сам” http://ali.ski/26e_Jh
-* Звук по Bluetooth
-* Передатчик Bluetooth http://ali.ski/_94Dig
-* Приёмник “свисток” http://ali.ski/Rkuyvl
-* Ещё приёмник http://ali.ski/QyigGj
-* Кнопки, конденсаторы и крутилки ищите в любых магазинах для радиолюбителей, так как у китайцев можно купить только мешок 50 штук!
-* Алик
-* Куча резисторов https://ali.ski/TAN2C
-* Куча кнопок https://ali.ski/VFH0N
-* Куча конденсаторов https://ali.ski/WNToC
-* Куча потенциометров (можно обойтись без него! Читайте инструкцию) http://ali.ski/fAJrzc
-* Куча конденсаторов для микрофона http://ali.ski/eqALT
-* ЧипДип (Россия)
-* Резистор https://www.chipdip.ru/product0/27226
-* Кнопка https://www.chipdip.ru/product/tyco-2-1825910-7-fsm14jh
-* Конденсатор 10нф https://www.chipdip.ru/product0/42179
-* Конденсатор для микрофона https://www.chipdip.ru/product0/9000261766
-* Потенциометр (можно обойтись без него! Читайте инструкцию) https://www.chipdip.ru/product/r-0901n-b20k
-
-## Вам скорее всего пригодится
-* [Всё для пайки (паяльники и примочки)](http://alexgyver.ru/all-for-soldering/)
-* [Недорогие инструменты](http://alexgyver.ru/my_instruments/)
-* [Все существующие модули и сенсоры Arduino](http://alexgyver.ru/arduino_shop/)
-* [Электронные компоненты](http://alexgyver.ru/electronics/)
-* [Аккумуляторы и зарядные модули](http://alexgyver.ru/18650/)
-
-
-## Как скачать и прошить
-* [Первые шаги с Arduino](http://alexgyver.ru/arduino-first/) - ультра подробная статья по началу работы с Ардуино, ознакомиться первым делом!
-* Скачать архив с проектом
-> На главной странице проекта (где ты читаешь этот текст) вверху справа зелёная кнопка **Clone or download**, вот её жми, там будет **Download ZIP**
-* Установить библиотеки в
-`C:\Program Files (x86)\Arduino\libraries\` (Windows x64)
-`C:\Program Files\Arduino\libraries\` (Windows x86)
-* Подключить Ардуино к компьютеру
-* Запустить файл прошивки (который имеет расширение .ino)
-* Настроить IDE (COM порт, модель Arduino, как в статье выше)
-* Настроить что нужно по проекту
-* Нажать загрузить
-* Пользоваться
-
-
-### Управление с ИК пульта:
-* Цифры (1 - 9) активируют режимы
-* Цифра 0: калибровка шума
-* Звёздочка (*): включить/выключить систему
-* Решётка (#): смена подрежима
-* Кнопка ОК: переключение между локальными и глобальными настройками)
-* Глобальные настройки (горит светодиод на плате):
- * Влево/вправо: яркость
-* Локальные настройки (у каждого режима свои):
- * 1 - Шкала громкости (градиент)
- * Стрелки ← →: плавность анимации
- * 2 - Шкала громкости (радуга)
- * Стрелки ← →: плавность анимации
- * Стрелки ↑ ↓: скорость радуги
- * 3 - Цветомузыка (5 полос)
- * Стрелки ← →: плавность анимации
- * Стрелки ↑ ↓: чувствительность
- * 4 - Цветомузыка (3 полосы)
- * Стрелки ← →: плавность анимации
- * Стрелки ↑ ↓: чувствительность
- * 5 - Цветомузыка (1 полоса)
- * Стрелки ← →: плавность анимации
- * Стрелки ↑ ↓: чувствительность
- * Подрежимы #: 3 частоты / низкие / средние / высокие
- * 6 - Стробоскоп
- * Стрелки ← →: плавность вспышек
- * Стрелки ↑ ↓: частота вспышек
- * 7 - Цветная подсветка
- * Стрелки ← →: цвет
- * Стрелки ↑ ↓: насыщенность
- * 8 - “Бегущие частоты”
- * Стрелки ← →: скорость
- * Стрелки ↑ ↓: чувствительность
- * Подрежимы #: 3 частоты / низкие / средние / высокие
- * 9 - Анализатор спектра
- * Стрелки ← →: шаг цвета
- * Стрелки ↑ ↓: цвет
-
-### НАСТРОЙКА НИЖНЕГО ПОРОГА ШУМА (строки 65-71)
-- Ручная: выключаем AUTO_LOW_PASS и EEPROM_LOW_PASS, настраиваем LOW_PASS и SPEKTR_LOW_PASS вручную
-- При запуске: включаем AUTO_LOW_PASS. При подаче питания музыка должна стоять на паузе!
-- По кнопке: при удерживании кнопки 1 секунду настраивается нижний порог шума (музыку на паузу!)
-- Из памяти (ЛУЧШИЙ ВАРИАНТ): выключаем AUTO_LOW_PASS и включаем EEPROM_LOW_PASS
- * Включаем систему
- * Ставим музыку на паузу
- * Удерживаем кнопку 1 секунду
- * Значения шумов будут записаны в память и САМИ загружаться при последующем запуске! Всё!
-
-## Настройки в коде
- // лента
- #define NUM_LEDS 120 // количество светодиодов
- #define BRIGHTNESS 230 // яркость (0 - 255)
-
- // пины
- #define SOUND_R A2 // аналоговый пин вход аудио, правый канал
- #define SOUND_L A1 // аналоговый пин вход аудио, левый канал
- #define SOUND_R_FREQ A3 // аналоговый пин вход аудио для режима с частотами (через кондер)
- #define BTN_PIN 3 // кнопка переключения режимов (PIN --- КНОПКА --- GND)
- #define LED_PIN 12 // пин DI светодиодной ленты
- #define POT_GND A0 // пин земля для потенциометра
-
- // настройки радуги
- #define RAINBOW_SPEED 6 // скорость движения радуги (чем меньше число, тем быстрее радуга)
- #define RAINBOW_STEP 6 // шаг изменения цвета радуги
-
- // отрисовка
- #define MODE 0 // режим при запуске
- #define MAIN_LOOP 5 // период основного цикла отрисовки (по умолчанию 5)
- #define SMOOTH 0.5 // коэффициент плавности анимации VU (по умолчанию 0.5)
- #define SMOOTH_FREQ 0.8 // коэффициент плавности анимации частот (по умолчанию 0.8)
- #define MAX_COEF 1.8 // коэффициент громкости (максимальное равно срднему * этот коэф) (по умолчанию 1.8)
- #define MAX_COEF_FREQ 1.2 // коэффициент порога для "вспышки" цветомузыки (по умолчанию 1.5)
-
- // сигнал
- #define MONO 1 // 1 - только один канал (ПРАВЫЙ!!!!! SOUND_R!!!!!), 0 - два канала
- #define EXP 1.4 // степень усиления сигнала (для более "резкой" работы) (по умолчанию 1.4)
-
- // нижний порог шумов
- int LOW_PASS = 100; // нижний порог шумов режим VU, ручная настройка
- int SPEKTR_LOW_PASS = 40; // нижний порог шумов режим спектра, ручная настройка
- #define AUTO_LOW_PASS 0 // разрешить настройку нижнего порога шумов при запуске (по умолч. 0)
- #define EEPROM_LOW_PASS 1 // порог шумов хранится в энергонезависимой памяти (по умолч. 1)
- #define LOW_PASS_ADD 13 // "добавочная" величина к нижнему порогу, для надёжности (режим VU)
- #define LOW_PASS_FREQ_ADD 3 // "добавочная" величина к нижнему порогу, для надёжности (режим частот)
-
- // режим цветомузыки
- #define LOW_COLOR RED // цвет низких частот
- #define MID_COLOR GREEN // цвет средних
- #define HIGH_COLOR YELLOW // цвет высоких
-
-
-## FAQ
-### Основные вопросы
-В: Как скачать с этого грёбаного сайта?
-О: На главной странице проекта (где ты читаешь этот текст) вверху справа зелёная кнопка **Clone or download**, вот её жми, там будет **Download ZIP**
-
-В: Скачался какой то файл .zip, куда его теперь?
-О: Это архив. Можно открыть стандартными средствами Windows, но думаю у всех на компьютере установлен WinRAR, архив нужно правой кнопкой и извлечь.
-
-В: Я совсем новичок! Что мне делать с Ардуиной, где взять все программы?
-О: Читай и смотри видос http://alexgyver.ru/arduino-first/
-
-В: Компьютер никак не реагирует на подключение Ардуины!
-О: Возможно у тебя зарядный USB кабель, а нужен именно data-кабель, по которому можно данные передавать
-
-В: Ошибка! Скетч не компилируется!
-О: Путь к скетчу не должен содержать кириллицу. Положи его в корень диска.
-
-В: Сколько стоит?
-О: Ничего не продаю.
-
-### Вопросы по этому проекту
-
-
-## Полезная информация
-* [Мой сайт](http://alexgyver.ru/)
-* [Основной YouTube канал](https://www.youtube.com/channel/UCgtAOyEQdAyjvm9ATCi_Aig?sub_confirmation=1)
-* [YouTube канал про Arduino](https://www.youtube.com/channel/UC4axiS76D784-ofoTdo5zOA?sub_confirmation=1)
-* [Мои видеоуроки по пайке](https://www.youtube.com/playlist?list=PLOT_HeyBraBuMIwfSYu7kCKXxQGsUKcqR)
-* [Мои видеоуроки по Arduino](http://alexgyver.ru/arduino_lessons/)
\ No newline at end of file
+## ColorMusic
+
+It is Alex Gyver project: [ColorMusic](https://github.com/AlexGyver/ColorMusic).
+Almost everything is made by him. I just fixed some bugs and made little improvements.
+Find differences in [history.md](https://github.com/x3mEr/ColorMusic/blob/master/history.md)
+
+*A lot of useful information (different schemes, components, explanation, videos) could be found [here](https://alexgyver.ru/colormusic/).*
+
+
+## About
+
+ColorMusic (individually addressable LED strip WS2812b) is driven by Arduino Nano v3.0 with ATmega328P.
+
+**Features:**
+- animation smoothness can be set up;
+- auto or manual setting of lower noise threshold;
+- auto volume adjustment;
+- support of stereo and mono input;
+- support of several popular IR remotes + one customizable;
+- all settings are stored in EEPROM;
+- support of usual tactile and touch buttons;
+- 9 effects:
+ 0. VU meter: classical volume bar;
+ 1. VU meter: smoothly running rainbow;
+ 2. Colormusic by frequencies: 5 symmetrical bars (high-middle-low-middle-high);
+ 3. Colormusic by frequencies: 3 bars (high-middle-low);
+ 4. Colormusic by frequencies: 1 bar (the colors of the frequencies overlap each other);
+ 5. Stroboscope with frequencies: 25 Hz (1500 BPM - trance music x10), 20 Hz (1200 BPM - dance music x10), 15 Hz (900 BPM), 10 Hz (600 BPM) and 5 Hz (300 BPM);
+ 6. Backlight. This mode has 3 sub modes (could be programmed in advance or switched with IR remote):
+ 1. constant color;
+ 2. changing color;
+ 3. running rainbow;
+ 7. Running frequencies;
+ 8. Spectrum Analyzer.
+
+
+## Controls
+
+Alex Gyver described IR remote control in detail.
+Here I'll describe control with just one button.
+Because we don't have `+` and `-` buttons, our single button changes setting cyclically: once the setting reaches upper limit it drops to the lower limit.
+
+**Almighty button:**
+
+- **Hold button**: switches modes;
+- **Single press**: imitates IR remote button "right" (see table below);
+- **Double press**: imitates IR remote button "up" (see table below);
+- **Triple press**: increase brightness;
+- **Press five times** to calibrate the noise thresholds.
+
+| Mode | Single press | Double press |
+| --------------------------|-------------------------------|---------------|
+| 0) classical VU meter | animation smoothness | - |
+| 1) rainbow VU meter | animation smoothness | rainbow running speed |
+| 2) 5 symmetrical bars | animation smoothness | sensitivity |
+| 3) 3 bars | animation smoothness | sensitivity |
+| 4) 1 bar | animation smoothness | sensitivity |
+| 5) stroboscope | light flash smoothness | frequency |
+| 6-1) backlight constant color | color | saturation |
+| 6-2) backlight changing color | speed of color change | saturation |
+| 6-3) backlight running rainbow | speed of rainbow | rainbow step (width) |
+| 7) Running frequencies | speed of running frequencies | sensitivity |
+| 8) Spectrum Analyzer | color step (width of one color cell) | starting (central) color |
+
+
+## Setting of lower noise threshold
+- Manual: `AUTO_LOW_PASS = 0`, `EEPROM_LOW_PASS = 0`, set up `LOW_PASS` and `SPEKTR_LOW_PASS`;
+- Automatically: `AUTO_LOW_PASS = 1`. While turning the colormusic on, music should be silenced;
+- Reset with button: press the button five times (music should be silenced);
+- (the best choice) From EEPROM: `AUTO_LOW_PASS = 0` and `EEPROM_LOW_PASS = 1`. Then
+ * turn the colormusic on;
+ * silence the music;
+ * press the button five times;
+ * the noise values will be written to the EEPROM and automatically read at every colormusic start up.
+
+## Problems
+- [x] It is highly recommended to use 10kOhm - 45kOhm resistor between pin A2 and GND in schemes with microphone (see `schemes` folder).
\ No newline at end of file
diff --git a/firmware/colorMusic_v2.10/colorMusic_v2.10.ino b/colorMusic/colorMusic.ino
similarity index 65%
rename from firmware/colorMusic_v2.10/colorMusic_v2.10.ino
rename to colorMusic/colorMusic.ino
index 8cc0913..9e379a8 100644
--- a/firmware/colorMusic_v2.10/colorMusic_v2.10.ino
+++ b/colorMusic/colorMusic.ino
@@ -11,105 +11,107 @@
*/
/*
- Версия 2.10
- Исправлен глюк с большим количеством светодиодов на МЕГЕ
+ Основано на версии AlexGyver Technologies 2.10
+ Версия 1.1.1
*/
+#define VERSION "1.1.1"
+// ***************************** SETTINGS *****************************
-
-// ***************************** НАСТРОЙКИ *****************************
-
-// ----- настройка ИК пульта
-#define REMOTE_TYPE 1 // 0 - без пульта, 1 - пульт от WAVGAT, 2 - пульт от KEYES, 3 - кастомный пульт
+// ----- IR remote settings
+#define REMOTE_TYPE 0 // 0 - без пульта, 1 - пульт от WAVGAT, 2 - пульт от KEYES, 3 - кастомный пульт
// система может работать С ЛЮБЫМ ИК ПУЛЬТОМ (практически). Коды для своего пульта можно задать начиная со строки 160 в прошивке. Коды пультов определяются скетчем IRtest_2.0, читай инструкцию
-// ----- настройки параметров
-#define KEEP_SETTINGS 1 // хранить ВСЕ настройки в энергонезависимой памяти
-#define KEEP_STATE 1 // сохранять в памяти состояние вкл/выкл системы (с пульта)
-#define RESET_SETTINGS 0 // сброс настроек в EEPROM памяти (поставить 1, прошиться, поставить обратно 0, прошиться. Всё)
-#define SETTINGS_LOG 0 // вывод всех настроек из EEPROM в порт при запуске
+// ----- parameters
+#define KEEP_SETTINGS 1 // save all settings in EEPROM
+#define KEEP_STATE 1 // save on/off state in EEPROM (on/off feature is available only via IR remote)
+#define RESET_SETTINGS 0 // to reset settings in EEPROM (set to 1, upload firmware, set back to 0 and upload firmware once again)
+#define SETTINGS_LOG 1 // print to Serial all settings in EEPROM at start up
-// ----- настройки ленты
-#define NUM_LEDS 60 // количество светодиодов (данная версия поддерживает до 410 штук)
-#define CURRENT_LIMIT 3000 // лимит по току в МИЛЛИАМПЕРАХ, автоматически управляет яркостью (пожалей свой блок питания!) 0 - выключить лимит
-byte BRIGHTNESS = 200; // яркость по умолчанию (0 - 255)
+// ----- LED strip
+#define NUM_LEDS 120 // LEDs quantity (max 410)
+#define COLOR_ORDER GRB // LEDs color order in strip. If colors are wrong - change the order. Try RGB, RBG, GRB, GBR, BRG, BGR
+#define CURRENT_LIMIT 2000 // current limit in mA, "FastLED" library automatically controls the brightness. 0 - turn the limit off
+byte BRIGHTNESS = 200; // BRIGHTNESS (0 - 255)
+byte EMPTY_BRIGHT = 40; // brightness of empty (not flashing) LEDs (0 - 255)
// ----- пины подключения
-#define SOUND_R A2 // аналоговый пин вход аудио, правый канал
-#define SOUND_L A1 // аналоговый пин вход аудио, левый канал
-#define SOUND_R_FREQ A3 // аналоговый пин вход аудио для режима с частотами (через кондер)
-#define BTN_PIN 3 // кнопка переключения режимов (PIN --- КНОПКА --- GND)
-
-#if defined(__AVR_ATmega32U4__) // Пины для Arduino Pro Micro (смотри схему для Pro Micro на странице проекта!!!)
-#define MLED_PIN 17 // пин светодиода режимов на ProMicro, т.к. обычный не выведен.
+#define SOUND_R A2 // analog audio in, right channel
+#define SOUND_L A1 // analog audio in, left channel
+#define SOUND_R_FREQ A3 // analog audio in for modes with frequencies (modes 2, 3, 4, 7, 8)
+#define BTN_PIN 3 // button (PIN --- КНОПКА --- GND)
+#define BTN_IS_TOUCH 1 // 0 - usual tactile button, 1 - touch button, e. g. TTP223 - in this case 'A' jumper should be opened - button outputs logical "1" when touched
+
+#if defined(__AVR_ATmega32U4__) // pins for Arduino Pro Micro (смотри схему для Pro Micro на странице проекта!!!)
+#define MLED_PIN 17 // пин светодиода режимов на ProMicro, т.к. обычный не выведен.
#define MLED_ON LOW
-#define LED_PIN 9 // пин DI светодиодной ленты на ProMicro, т.к. обычный не выведен.
-#else // Пины для других плат Arduino (по умолчанию)
-#define MLED_PIN 13 // пин светодиода режимов
+#define LED_PIN 9 // пин DI светодиодной ленты на ProMicro, т.к. обычный не выведен.
+#else // Пины для других плат Arduino (по умолчанию)
+#define MLED_PIN 13 // пин светодиода режимов
#define MLED_ON HIGH
-#define LED_PIN 12 // пин DI светодиодной ленты
+#define LED_PIN 12 // пин DI светодиодной ленты
#endif
-#define POT_GND A0 // пин земля для потенциометра
-#define IR_PIN 2 // пин ИК приёмника
-
-// ----- настройки радуги
-float RAINBOW_STEP = 5.00; // шаг изменения цвета радуги
-
-// ----- отрисовка
-#define MODE 0 // режим при запуске
-#define MAIN_LOOP 5 // период основного цикла отрисовки (по умолчанию 5)
-
-// ----- сигнал
-#define MONO 1 // 1 - только один канал (ПРАВЫЙ!!!!! SOUND_R!!!!!), 0 - два канала
-#define EXP 1.4 // степень усиления сигнала (для более "резкой" работы) (по умолчанию 1.4)
-#define POTENT 0 // 1 - используем потенциометр, 0 - используется внутренний источник опорного напряжения 1.1 В
-byte EMPTY_BRIGHT = 30; // яркость "не горящих" светодиодов (0 - 255)
-#define EMPTY_COLOR HUE_PURPLE // цвет "не горящих" светодиодов. Будет чёрный, если яркость 0
-
-// ----- нижний порог шумов
-uint16_t LOW_PASS = 100; // нижний порог шумов режим VU, ручная настройка
-uint16_t SPEKTR_LOW_PASS = 40; // нижний порог шумов режим спектра, ручная настройка
-#define AUTO_LOW_PASS 0 // разрешить настройку нижнего порога шумов при запуске (по умолч. 0)
-#define EEPROM_LOW_PASS 1 // порог шумов хранится в энергонезависимой памяти (по умолч. 1)
-#define LOW_PASS_ADD 13 // "добавочная" величина к нижнему порогу, для надёжности (режим VU)
-#define LOW_PASS_FREQ_ADD 3 // "добавочная" величина к нижнему порогу, для надёжности (режим частот)
-
-// ----- режим шкала громкости
-float SMOOTH = 0.3; // коэффициент плавности анимации VU (по умолчанию 0.5)
-#define MAX_COEF 1.8 // коэффициент громкости (максимальное равно срднему * этот коэф) (по умолчанию 1.8)
-
-// ----- режим цветомузыки
-float SMOOTH_FREQ = 0.8; // коэффициент плавности анимации частот (по умолчанию 0.8)
-float MAX_COEF_FREQ = 1.2; // коэффициент порога для "вспышки" цветомузыки (по умолчанию 1.5)
-#define SMOOTH_STEP 20 // шаг уменьшения яркости в режиме цветомузыки (чем больше, тем быстрее гаснет)
-#define LOW_COLOR HUE_RED // цвет низких частот
-#define MID_COLOR HUE_GREEN // цвет средних
-#define HIGH_COLOR HUE_YELLOW // цвет высоких
-
-// ----- режим стробоскопа
-uint16_t STROBE_PERIOD = 140; // период вспышек, миллисекунды
-#define STROBE_DUTY 20 // скважность вспышек (1 - 99) - отношение времени вспышки ко времени темноты
-#define STROBE_COLOR HUE_YELLOW // цвет стробоскопа
-#define STROBE_SAT 0 // насыщенность. Если 0 - цвет будет БЕЛЫЙ при любом цвете (0 - 255)
-byte STROBE_SMOOTH = 200; // скорость нарастания/угасания вспышки (0 - 255)
-
-// ----- режим подсветки
-byte LIGHT_COLOR = 0; // начальный цвет подсветки
-byte LIGHT_SAT = 255; // начальная насыщенность подсветки
-byte COLOR_SPEED = 100;
-int RAINBOW_PERIOD = 1;
-float RAINBOW_STEP_2 = 0.5;
-
-// ----- режим бегущих частот
+#define POT_GND A0 // ground pin for potentiometer
+#define IR_PIN 2 // pin for IR Receiver
+
+// ----- mode 1 - rainbow
+float RAINBOW_STEP = 5.00; // rainbow color change step - width of rainbow
+
+// ----- animation
+#define MODE 0 // initial mode
+#define MAIN_LOOP 5 // period of main draw cycle ("animation" rootine)
+
+// ----- audio signal
+#define MONO 1 // 1 - only right channel (SOUND_R), 0 - two channels
+#define EXP 1.4 // signal gain (for more strident animation) (default 1.4)
+#define POTENT 1 // 1 - use potentiometer, 0 - use intrenal reference of 1.1 V
+#define EMPTY_COLOR HUE_PURPLE // color of empty (not flashing) LEDs. Black if EMPTY_BRIGHT = 0
+
+// ----- lower noise threshold
+uint16_t LOW_PASS = 100; // lower noise threshold in VU modes (modes 0 and 1), manual
+uint16_t SPEKTR_LOW_PASS = 40; // lower noise threshold in frequencies modes (modes 2, 3, 4, 7, 8), manual
+#define AUTO_LOW_PASS 0 // no EEPROM, do automatic setting of lower noise threshold every time at start up (default 0), so the colormusic should be turned on without music
+#define EEPROM_LOW_PASS 1 // allow use EEPROM to save and load lower noise threshold (default 1)
+#define LOW_PASS_ADD 13 // additional value to the lower threshold, for reliability (VU modes)
+#define LOW_PASS_FREQ_ADD 3 // additional value to the lower threshold, for reliability (frequencies modes)
+
+// ----- VU modes (#0 and 1)
+float SMOOTH = 0.2; // VU animation smoothness coefficient (default 0.5)
+#define MAX_COEF 1.8 // loudness coefficient (max loudness = average loudness * MAX_COEF) (default 1.8)
+
+// ----- frequencies modes (#2, 3, 4, 7, 8)
+float SMOOTH_FREQ = 0.3; // frequencies animation smoothness coefficient (default 0.8)
+float MAX_COEF_FREQ = 1.2; // threshold coefficient for colormusic to generate the flash (default 1.5)
+#define SMOOTH_STEP 20 // step of brightness decreasing (more value - faster attenuation of light), i.e. fade rate
+#define LOW_COLOR HUE_RED // color of low frequencies
+#define MID_COLOR HUE_YELLOW // color of middle frequencies
+#define HIGH_COLOR HUE_AQUA // color of middle frequencies
+
+// ----- stroboscope mode (#5)
+uint16_t STROBE_PERIOD = 40; // period of stroboscope flashes, ms //Trance: 140-145 BPM, dance: 120 BPM
+uint8_t STROBE_BPM = 150; // beats per minute. Further, STROBE_PERIOD is calculated using this value
+#define STROBE_DUTY 20 // flash duty ratio (1 - 99) - ratio of "LED on" time to "LED off" time
+#define STROBE_COLOR HUE_RED // stroboscope color
+#define STROBE_SAT 0 // saturation. If 0 - the color will be WHITE for any STROBE_COLOR (0 - 255)
+byte STROBE_SMOOTH = 200; // flash rise/fade rate (0 - 255). Should be enough for high frequenies
+
+// ----- backlight mode (#6 - is divided into 3 sub modes)
+byte LIGHT_COLOR = 0; // mode #6-1: backlight color
+byte LIGHT_SAT = 255; // mode #6-1: backlight color saturation
+byte COLOR_SPEED = 100; // mode #6-2: effect speed
+int RAINBOW_PERIOD = 1; // mode #6-3: rainbow speed
+float RAINBOW_STEP_2 = 0.5; // mode #6-3: rainbow color change step - width of rainbow
+
+// ----- traveling frequencies mode (#7)
byte RUNNING_SPEED = 11;
-// ----- режим анализатора спектра
+// ----- spectrum analyzer mode (#8)
byte HUE_START = 0;
byte HUE_STEP = 5;
#define LIGHT_SMOOTH 2
/*
- Цвета для HSV
+ Colors in HSV
HUE_RED
HUE_ORANGE
HUE_YELLOW
@@ -120,7 +122,7 @@ byte HUE_STEP = 5;
HUE_PINK
*/
-// ----- КНОПКИ ПУЛЬТА WAVGAT -----
+// ----- codes of WAVGAT IR remote buttons -----
#if REMOTE_TYPE == 1
#define BUTT_UP 0xF39EEBAD
#define BUTT_DOWN 0xC089F6AD
@@ -141,7 +143,7 @@ byte HUE_STEP = 5;
#define BUTT_HASH 0x151CD6AD
#endif
-// ----- КНОПКИ ПУЛЬТА KEYES -----
+// ----- codes of KEYES IR remote buttons -----
#if REMOTE_TYPE == 2
#define BUTT_UP 0xE51CA6AD
#define BUTT_DOWN 0xD22353AD
@@ -162,7 +164,7 @@ byte HUE_STEP = 5;
#define BUTT_HASH 0x38379AD
#endif
-// ----- КНОПКИ СВОЕГО ПУЛЬТА -----
+// ----- codes of yours IR remote buttons -----
#if REMOTE_TYPE == 3
#define BUTT_UP 0xE51CA6AD
#define BUTT_DOWN 0xD22353AD
@@ -184,15 +186,15 @@ byte HUE_STEP = 5;
#endif
-// ------------------------------ ДЛЯ РАЗРАБОТЧИКОВ --------------------------------
-#define MODE_AMOUNT 9 // количество режимов
+// ------------------------------ FOR DEVELOPERS --------------------------------
+#define MODE_AMOUNT 9 // modes quantity
-#define STRIPE NUM_LEDS / 5
-float freq_to_stripe = NUM_LEDS / 40; // /2 так как симметрия, и /20 так как 20 частот
+#define STRIP NUM_LEDS / 5
+float freq_to_strip = NUM_LEDS / 40; // /2 because of symmetry, and /20 because of 20 frequencies
-#define FHT_N 64 // ширина спектра х2
+#define FHT_N 64 // spectrum width х2
#define LOG_OUT 1
-#include // преобразование Хартли
+#include // Hartley transform
#include
@@ -201,7 +203,11 @@ float freq_to_stripe = NUM_LEDS / 40; // /2 так как симметрия, и
CRGB leds[NUM_LEDS];
#include "GyverButton.h"
-GButton butt1(BTN_PIN);
+#if BTN_IS_TOUCH == 0 // usual tact button //D3 - butt1 - GND
+ GButton butt1(BTN_PIN);
+#else // e.g. TTP223 - 'A' jumper is opened - outputs logical "1" when pressed
+ GButton butt1(BTN_PIN, LOW_PULL, NORM_OPEN);
+#endif
#include "IRLremote.h"
CHashIR IRLremote;
@@ -237,10 +243,10 @@ float colorMusic_f[3], colorMusic_aver[3];
boolean colorMusicFlash[3], strobeUp_flag, strobeDwn_flag;
byte this_mode = MODE;
int thisBright[3], strobe_bright = 0;
-unsigned int light_time = STROBE_PERIOD * STROBE_DUTY / 100;
+//unsigned int light_time = STROBE_PERIOD * STROBE_DUTY / 100;
volatile boolean ir_flag;
boolean settings_mode, ONstate = true;
-int8_t freq_strobe_mode, light_mode;
+int8_t freq_strobe_mode = 0, light_mode = 2; //rainbow
int freq_max;
float freq_max_f, rainbow_steps;
int freq_f[32];
@@ -252,8 +258,21 @@ boolean running_flag[3], eeprom_flag;
// ------------------------------ ДЛЯ РАЗРАБОТЧИКОВ --------------------------------
void setup() {
- Serial.begin(9600);
- FastLED.addLeds(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
+ Serial.begin(115200);
+ if (RESET_SETTINGS) EEPROM.write(1, 0); // сброс флага настроек
+ // в 1 ячейке хранится число 100. Если нет - значит это первый запуск системы
+ if (KEEP_SETTINGS) {
+ eeprom_timer = millis();
+ eeprom_flag = false;
+ if (EEPROM.read(1) != 100) {
+ //Serial.println(F("First start"));
+ EEPROM.write(1, 100);
+ updateEEPROM();
+ } else {
+ readEEPROM();
+ }
+ }
+ FastLED.addLeds(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
if (CURRENT_LIMIT > 0) FastLED.setMaxPowerInVoltsAndMilliamps(5, CURRENT_LIMIT);
FastLED.setBrightness(BRIGHTNESS);
@@ -266,9 +285,12 @@ void setup() {
pinMode(POT_GND, OUTPUT);
digitalWrite(POT_GND, LOW);
- butt1.setTimeout(900);
+ butt1.setTimeout(800);
+ butt1.setStepTimeout(100);
+#if REMOTE_TYPE != 0
IRLremote.begin(IR_PIN);
+#endif
// для увеличения точности уменьшаем опорное напряжение,
// выставив EXTERNAL и подключив Aref к выходу 3.3V на плате через делитель
@@ -283,7 +305,7 @@ void setup() {
#endif
// жуткая магия, меняем частоту оцифровки до 18 кГц
- // команды на ебучем ассемблере, даже не спрашивайте, как это работает
+ // команды на *** ассемблере, даже не спрашивайте, как это работает
// поднимаем частоту опроса аналогового порта до 38.4 кГц, по теореме
// Котельникова (Найквиста) частота дискретизации будет 19.2 кГц
// http://yaab-arduino.blogspot.ru/2015/02/fast-sampling-from-analog-input.html
@@ -291,27 +313,11 @@ void setup() {
cbi(ADCSRA, ADPS1);
sbi(ADCSRA, ADPS0);
- if (RESET_SETTINGS) EEPROM.write(100, 0); // сброс флага настроек
-
if (AUTO_LOW_PASS && !EEPROM_LOW_PASS) { // если разрешена автонастройка нижнего порога шумов
autoLowPass();
}
- if (EEPROM_LOW_PASS) { // восстановить значения шумов из памяти
- LOW_PASS = EEPROM.readInt(70);
- SPEKTR_LOW_PASS = EEPROM.readInt(72);
- }
-
- // в 100 ячейке хранится число 100. Если нет - значит это первый запуск системы
- if (KEEP_SETTINGS) {
- if (EEPROM.read(100) != 100) {
- //Serial.println(F("First start"));
- EEPROM.write(100, 100);
- updateEEPROM();
- } else {
- readEEPROM();
- }
- }
+Serial.print(F("VERSION = ")); Serial.println(VERSION);
#if (SETTINGS_LOG == 1)
Serial.print(F("this_mode = ")); Serial.println(this_mode);
Serial.print(F("freq_strobe_mode = ")); Serial.println(freq_strobe_mode);
@@ -330,18 +336,25 @@ void setup() {
Serial.print(F("RAINBOW_PERIOD = ")); Serial.println(RAINBOW_PERIOD);
Serial.print(F("RUNNING_SPEED = ")); Serial.println(RUNNING_SPEED);
Serial.print(F("HUE_STEP = ")); Serial.println(HUE_STEP);
+ Serial.print(F("BRIGHTNESS = ")); Serial.println(BRIGHTNESS);
Serial.print(F("EMPTY_BRIGHT = ")); Serial.println(EMPTY_BRIGHT);
Serial.print(F("ONstate = ")); Serial.println(ONstate);
#endif
}
+unsigned int light_time = STROBE_PERIOD * STROBE_DUTY / 100; //should be defined only after STROBE_PERIOD has been initialised
+
void loop() {
buttonTick(); // опрос и обработка кнопки
#if REMOTE_TYPE != 0
remoteTick(); // опрос ИК пульта
#endif
+
mainLoop(); // главный цикл обработки и отрисовки
+
+#if KEEP_SETTINGS
eepromTick(); // проверка не пора ли сохранить настройки
+#endif
}
void mainLoop() {
@@ -455,7 +468,7 @@ void mainLoop() {
}
animation();
}
- if (this_mode == 5) {
+ if (this_mode == 5) { //STROBE
if ((long)millis() - strobe_timer > STROBE_PERIOD) {
strobe_timer = millis();
strobeUp_flag = true;
@@ -483,14 +496,19 @@ void mainLoop() {
}
animation();
}
- if (this_mode == 6) animation();
+ if (this_mode == 6) animation(); //light independent from music
- if (!IRLremote.receiving()) // если на ИК приёмник не приходит сигнал (без этого НЕ РАБОТАЕТ!)
- FastLED.show(); // отправить значения на ленту
+#if REMOTE_TYPE != 0
+ if (!IRLremote.receiving()) // если на ИК приёмник не приходит сигнал (без этого НЕ РАБОТАЕТ!)
+ FastLED.show(); // отправить значения на ленту
+#else
+ FastLED.show(); // отправить значения на ленту
+#endif
- if (this_mode != 7) // 7 режиму не нужна очистка!!!
- FastLED.clear(); // очистить массив пикселей
- main_timer = millis(); // сбросить таймер
+ if (this_mode != 7) // 7 режиму не нужна очистка!!!
+ FastLED.clear(); // очистить массив пикселей
+
+ main_timer = millis(); // сбросить таймер
}
}
}
@@ -498,7 +516,7 @@ void mainLoop() {
void animation() {
// согласно режиму
switch (this_mode) {
- case 0:
+ case 0: //VU meter (столбик громкости): от зелёного к красному
count = 0;
for (int i = (MAX_CH - 1); i > ((MAX_CH - 1) - Rlenght); i--) {
leds[i] = ColorFromPalette(myPal, (count * index)); // заливка по палитре " от зелёного к красному"
@@ -517,7 +535,7 @@ void animation() {
leds[i] = this_dark;
}
break;
- case 1:
+ case 1: //VU meter (столбик громкости): плавно бегущая радуга
if (millis() - rainbow_timer > 30) {
rainbow_timer = millis();
hue = floor((float)hue + RAINBOW_STEP);
@@ -540,23 +558,23 @@ void animation() {
leds[i] = this_dark;
}
break;
- case 2:
+ case 2: //Светомузыка по частотам: 5 полос
for (int i = 0; i < NUM_LEDS; i++) {
- if (i < STRIPE) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (i < STRIPE * 2) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < STRIPE * 3) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else if (i < STRIPE * 4) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < STRIPE * 5) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
+ if (i < STRIP) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
+ else if (i < STRIP * 2) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
+ else if (i < STRIP * 3) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
+ else if (i < STRIP * 4) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
+ else if (i < STRIP * 5) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
}
break;
- case 3:
+ case 3: //Светомузыка по частотам: 3 полосы
for (int i = 0; i < NUM_LEDS; i++) {
if (i < NUM_LEDS / 3) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
else if (i < NUM_LEDS * 2 / 3) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
else if (i < NUM_LEDS) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
}
break;
- case 4:
+ case 4: //Светомузыка по частотам: 1 полоса, цвета накладываются друг на друга: бас, сверху, если есть, средние, затем высокие при наличии
switch (freq_strobe_mode) {
case 0:
if (colorMusicFlash[2]) HIGHS();
@@ -578,24 +596,24 @@ void animation() {
break;
}
break;
- case 5:
+ case 5: //strobe
if (strobe_bright > 0)
for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(STROBE_COLOR, STROBE_SAT, strobe_bright);
else
for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
break;
- case 6:
- switch (light_mode) {
+ case 6: //light independent from music
+ switch (light_mode) { //constant light
case 0: for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(LIGHT_COLOR, LIGHT_SAT, 255);
break;
- case 1:
+ case 1: //smooth color changing
if (millis() - color_timer > COLOR_SPEED) {
color_timer = millis();
if (++this_color > 255) this_color = 0;
}
for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(this_color, LIGHT_SAT, 255);
break;
- case 2:
+ case 2: //rainbow
if (millis() - rainbow_timer > 30) {
rainbow_timer = millis();
this_color += RAINBOW_PERIOD;
@@ -645,7 +663,7 @@ void animation() {
case 8:
byte HUEindex = HUE_START;
for (int i = 0; i < NUM_LEDS / 2; i++) {
- byte this_bright = map(freq_f[(int)floor((NUM_LEDS / 2 - i) / freq_to_stripe)], 0, freq_max_f, 0, 255);
+ byte this_bright = map(freq_f[(int)floor((NUM_LEDS / 2 - i) / freq_to_strip)], 0, freq_max_f, 0, 255);
this_bright = constrain(this_bright, 0, 255);
leds[i] = CHSV(HUEindex, 255, this_bright);
leds[NUM_LEDS - i - 1] = leds[i];
@@ -894,7 +912,7 @@ void autoLowPass() {
SPEKTR_LOW_PASS = thisMax + LOW_PASS_FREQ_ADD; // нижний порог как максимум тишины
if (EEPROM_LOW_PASS && !AUTO_LOW_PASS) {
EEPROM.updateInt(70, LOW_PASS);
- EEPROM.updateInt(72, SPEKTR_LOW_PASS);
+ EEPROM.updateInt(74, SPEKTR_LOW_PASS);
}
}
@@ -911,10 +929,132 @@ void analyzeAudio() {
void buttonTick() {
butt1.tick(); // обязательная функция отработки. Должна постоянно опрашиваться
- if (butt1.isSingle()) // если единичное нажатие
- if (++this_mode >= MODE_AMOUNT) this_mode = 0; // изменить режим
-
- if (butt1.isHolded()) { // кнопка удержана
+ if (butt1.isHolded()){ //кнопка удержана - изменить режим
+ //Serial.println("HoldedPress");
+ eeprom_timer = millis();
+ eeprom_flag = true;
+ if (++this_mode >= MODE_AMOUNT) this_mode = 0;
+ }
+ if (butt1.isSingle()){ //аналог нажатия на пульте кновки "вправо" - регулировка плавности или скорости анимации
+ //Serial.println("SinglePress");
+ eeprom_timer = millis();
+ eeprom_flag = true;
+ switch (this_mode) {
+ case 0:
+ case 1:
+ if (SMOOTH+0.05 > 0.5) SMOOTH = 0.05;
+ else SMOOTH += 0.05;
+ Serial.print(F("SMOOTH = ")); Serial.println(SMOOTH);
+ break;
+ case 2:
+ case 3:
+ case 4:
+ if (SMOOTH_FREQ+0.05 > 1) SMOOTH_FREQ = 0.05;
+ else SMOOTH_FREQ += 0.05;
+ Serial.print(F("SMOOTH_FREQ = ")); Serial.println(SMOOTH_FREQ);
+ break;
+ case 5:
+ if (STROBE_SMOOTH+20 > 255) STROBE_SMOOTH = 0;
+ else STROBE_SMOOTH += 20;
+ Serial.print(F("STROBE_SMOOTH = ")); Serial.println(STROBE_SMOOTH);
+ break;
+ case 6:
+ switch (light_mode) {
+ case 0:
+ if (LIGHT_COLOR+10 > 255) LIGHT_COLOR = 0;
+ else LIGHT_COLOR += 10;
+ Serial.print(F("LIGHT_COLOR = ")); Serial.println(LIGHT_COLOR);
+ break;
+ case 1:
+ if (COLOR_SPEED+10 > 255) COLOR_SPEED = 0;
+ else COLOR_SPEED += 10;
+ Serial.print(F("COLOR_SPEED = ")); Serial.println(COLOR_SPEED);
+ break;
+ case 2:
+ if (RAINBOW_PERIOD+2 > 14) RAINBOW_PERIOD = -14;
+ else RAINBOW_PERIOD += 2; // !!!!! БЫЛО 1 - ПРОВЕРИТЬ !!!!!
+ Serial.print(F("RAINBOW_PERIOD = ")); Serial.println(RAINBOW_PERIOD);
+ break;
+ }
+ break;
+ case 7:
+ if (RUNNING_SPEED*2 > 255) RUNNING_SPEED = 3;//1;
+ else RUNNING_SPEED *=2;//+= 10;
+ Serial.print(F("RUNNING_SPEED = ")); Serial.println(RUNNING_SPEED);
+ break;
+ case 8:
+ if (HUE_STEP*2 > 255) HUE_STEP = 1;
+ else HUE_STEP *= 2; //+20; // !!!!! БЫЛО 1 - ПРОВЕРИТЬ !!!!!
+ Serial.print(F("HUE_STEP = ")); Serial.println(HUE_STEP);
+ break;
+ }
+ //break;
+ } //isSingle
+ if (butt1.isDouble()){ //аналог нажатия на пульте кновки "вверх" - регулировка чувствительности, или насыщенности, или шага радуги
+ //Serial.println("DoublePress");
+ eeprom_timer = millis();
+ eeprom_flag = true;
+ switch (this_mode) {
+ case 0:
+ break;
+ case 1:
+ if (RAINBOW_STEP+0.5 > 20) RAINBOW_STEP = 0.5;
+ else RAINBOW_STEP += 0.5;
+ Serial.print(F("RAINBOW_STEP = ")); Serial.println(RAINBOW_STEP);
+ break;
+ case 2:
+ case 3:
+ case 4:
+ if (MAX_COEF_FREQ+0.4 > 5) MAX_COEF_FREQ = 0;
+ else MAX_COEF_FREQ += 0.2;
+ Serial.print(F("MAX_COEF_FREQ = ")); Serial.println(MAX_COEF_FREQ);
+ break;
+ case 5: //1500BPM-25Hz-40ms 1200BPM-20Hz-50ms 900BPM-15Hz-67ms 600BPM-10Hz-100ms 300BPM-5Hz-200ms
+ if (STROBE_BPM+30 > 150) STROBE_BPM = 30;
+ else STROBE_BPM += 30;
+ STROBE_PERIOD = 1./(STROBE_BPM/6)*1000; // надо делить на 60, но частоту умножаю на 10, чтобы уменьшить операции делю на 6
+ Serial.print(F("STROBE_BPM = ")); Serial.println(STROBE_BPM);
+ Serial.print(F("STROBE_PERIOD = ")); Serial.println(STROBE_PERIOD);
+ break;
+ case 6:
+ switch (light_mode) {
+ case 0:
+ //if (LIGHT_SAT+20 > 255) LIGHT_SAT = 0;
+ //else LIGHT_SAT += 20;
+ //break;
+ case 1:
+ if (LIGHT_SAT+20 > 255) LIGHT_SAT = 0;
+ else LIGHT_SAT += 20;
+ Serial.print(F("LIGHT_SAT = ")); Serial.println(LIGHT_SAT);
+ break;
+ case 2:
+ if (RAINBOW_STEP_2+1 > 8) RAINBOW_STEP_2 = 0.5;
+ else RAINBOW_STEP_2 += 1;
+ Serial.print(F("RAINBOW_STEP_2 = ")); Serial.println(RAINBOW_STEP_2);
+ break;
+ }
+ break;
+ case 7:
+ if (MAX_COEF_FREQ+0.4 > 5) MAX_COEF_FREQ = 0.0;
+ else MAX_COEF_FREQ += 0.4;
+ Serial.print(F("MAX_COEF_FREQ = ")); Serial.println(MAX_COEF_FREQ);
+ break;
+ case 8:
+ if (HUE_START+20 > 255) HUE_START = 0;
+ else HUE_START += 20;
+ Serial.print(F("HUE_START = ")); Serial.println(HUE_START);
+ break;
+ }
+ } //isDouble()
+ if (butt1.isTriple()){
+ //Serial.println("TripplePress");
+ if (BRIGHTNESS+40 > 255) BRIGHTNESS = 40;
+ else BRIGHTNESS += 40;
+ FastLED.setBrightness(BRIGHTNESS);
+ Serial.print(F("BRIGHTNESS = ")); Serial.println(BRIGHTNESS);
+ }
+ if (butt1.hasClicks() && butt1.getClicks() == 5) { //пять нажатий для калибровки уровня шума. Обязательно в самом конце, т. к. 'getClicks()' method resets count of clicks
+ //Serial.println("FifthPress");
fullLowPass();
}
}
@@ -930,52 +1070,58 @@ void fullLowPass() {
digitalWrite(MLED_PIN, !MLED_ON); // выключить светодиод
}
void updateEEPROM() {
- EEPROM.updateByte(1, this_mode);
- EEPROM.updateByte(2, freq_strobe_mode);
- EEPROM.updateByte(3, light_mode);
- EEPROM.updateInt(4, RAINBOW_STEP);
- EEPROM.updateFloat(8, MAX_COEF_FREQ);
- EEPROM.updateInt(12, STROBE_PERIOD);
- EEPROM.updateInt(16, LIGHT_SAT);
- EEPROM.updateFloat(20, RAINBOW_STEP_2);
- EEPROM.updateInt(24, HUE_START);
- EEPROM.updateFloat(28, SMOOTH);
- EEPROM.updateFloat(32, SMOOTH_FREQ);
- EEPROM.updateInt(36, STROBE_SMOOTH);
- EEPROM.updateInt(40, LIGHT_COLOR);
- EEPROM.updateInt(44, COLOR_SPEED);
- EEPROM.updateInt(48, RAINBOW_PERIOD);
- EEPROM.updateInt(52, RUNNING_SPEED);
- EEPROM.updateInt(56, HUE_STEP);
- EEPROM.updateInt(60, EMPTY_BRIGHT);
- if (KEEP_STATE) EEPROM.updateByte(64, ONstate);
+ EEPROM.updateByte(2, this_mode);
+ EEPROM.updateByte(3, freq_strobe_mode);
+ EEPROM.updateByte(4, light_mode);
+ EEPROM.updateFloat(5, RAINBOW_STEP);
+ EEPROM.updateFloat(9, MAX_COEF_FREQ);
+ EEPROM.updateInt(13, STROBE_BPM);
+ EEPROM.updateByte(17, LIGHT_SAT);
+ EEPROM.updateFloat(18, RAINBOW_STEP_2);
+ EEPROM.updateByte(22, HUE_START);
+ EEPROM.updateFloat(23, SMOOTH);
+ EEPROM.updateFloat(27, SMOOTH_FREQ);
+ EEPROM.updateByte(31, STROBE_SMOOTH);
+ EEPROM.updateByte(32, LIGHT_COLOR);
+ EEPROM.updateByte(33, COLOR_SPEED);
+ EEPROM.updateInt(34, RAINBOW_PERIOD);
+ EEPROM.updateByte(38, RUNNING_SPEED);
+ EEPROM.updateByte(39, HUE_STEP);
+ EEPROM.updateByte(40, BRIGHTNESS);
+ EEPROM.updateByte(41, EMPTY_BRIGHT);
+ if (KEEP_STATE) EEPROM.updateByte(42, ONstate);
}
void readEEPROM() {
- this_mode = EEPROM.readByte(1);
- freq_strobe_mode = EEPROM.readByte(2);
- light_mode = EEPROM.readByte(3);
- RAINBOW_STEP = EEPROM.readInt(4);
- MAX_COEF_FREQ = EEPROM.readFloat(8);
- STROBE_PERIOD = EEPROM.readInt(12);
- LIGHT_SAT = EEPROM.readInt(16);
- RAINBOW_STEP_2 = EEPROM.readFloat(20);
- HUE_START = EEPROM.readInt(24);
- SMOOTH = EEPROM.readFloat(28);
- SMOOTH_FREQ = EEPROM.readFloat(32);
- STROBE_SMOOTH = EEPROM.readInt(36);
- LIGHT_COLOR = EEPROM.readInt(40);
- COLOR_SPEED = EEPROM.readInt(44);
- RAINBOW_PERIOD = EEPROM.readInt(48);
- RUNNING_SPEED = EEPROM.readInt(52);
- HUE_STEP = EEPROM.readInt(56);
- EMPTY_BRIGHT = EEPROM.readInt(60);
- if (KEEP_STATE) ONstate = EEPROM.readByte(64);
+ this_mode = EEPROM.readByte(2);
+ freq_strobe_mode = EEPROM.readByte(3);
+ light_mode = EEPROM.readByte(4);
+ RAINBOW_STEP = EEPROM.readFloat(5);
+ MAX_COEF_FREQ = EEPROM.readFloat(9);
+ STROBE_BPM = EEPROM.readInt(13);
+ STROBE_PERIOD = 1./(STROBE_BPM/6)*1000;
+ LIGHT_SAT = EEPROM.readByte(17);
+ RAINBOW_STEP_2 = EEPROM.readFloat(18);
+ HUE_START = EEPROM.readByte(22);
+ SMOOTH = EEPROM.readFloat(23);
+ SMOOTH_FREQ = EEPROM.readFloat(27);
+ STROBE_SMOOTH = EEPROM.readByte(31);
+ LIGHT_COLOR = EEPROM.readByte(32);
+ COLOR_SPEED = EEPROM.readByte(33);
+ RAINBOW_PERIOD = EEPROM.readInt(34);
+ RUNNING_SPEED = EEPROM.readByte(38);
+ HUE_STEP = EEPROM.readByte(39);
+ BRIGHTNESS = EEPROM.readByte(40);
+ EMPTY_BRIGHT = EEPROM.readByte(41);
+ if (KEEP_STATE) ONstate = EEPROM.readByte(42);
+ if (EEPROM_LOW_PASS) { // восстановить значения шумов из памяти
+ LOW_PASS = EEPROM.readInt(70);
+ SPEKTR_LOW_PASS = EEPROM.readInt(74);
+ }
}
void eepromTick() {
- if (eeprom_flag)
- if (millis() - eeprom_timer > 30000) { // 30 секунд после последнего нажатия с пульта
- eeprom_flag = false;
- eeprom_timer = millis();
- updateEEPROM();
- }
+ if ((eeprom_flag) && (millis() - eeprom_timer > 10000)) { // 10 секунд после последнего нажатия с пульта
+ eeprom_flag = false;
+ eeprom_timer = millis();
+ updateEEPROM();
+ }
}
diff --git a/firmware/IRtest_2.0/IRtest_2.0.ino b/firmware/IRtest_2.0/IRtest_2.0.ino
deleted file mode 100644
index 0d8ad00..0000000
--- a/firmware/IRtest_2.0/IRtest_2.0.ino
+++ /dev/null
@@ -1,20 +0,0 @@
-#include "IRLremote.h"
-#define pinIR 2
-CHashIR IRLremote;
-
-void setup() {
- Serial.begin(9600);
- Serial.println(F("Startup"));
- if (!IRLremote.begin(pinIR))
- Serial.println(F("You did not choose a valid pin."));
-}
-
-void loop() {
- if (IRLremote.available()) {
- auto data = IRLremote.read();
- if (data.command != 292984781) {
- Serial.print("0x");
- Serial.println(data.command, HEX);
- }
- }
-}
diff --git a/firmware/Old versions/IR_test/IR_test.ino b/firmware/Old versions/IR_test/IR_test.ino
deleted file mode 100644
index 1f585da..0000000
--- a/firmware/Old versions/IR_test/IR_test.ino
+++ /dev/null
@@ -1,16 +0,0 @@
-#include "IRremote.h"
-IRrecv irrecv(2); // указываем вывод, к которому подключен приемник
-decode_results results;
-
-void setup() {
- Serial.begin(9600); // выставляем скорость COM порта
- irrecv.enableIRIn(); // запускаем прием
-}
-
-void loop() {
- if ( irrecv.decode( &results )) { // если данные пришли
- Serial.print("0x");
- Serial.println(results.value, HEX);
- irrecv.resume(); // принимаем следующую команду
- }
-}
diff --git a/firmware/Old versions/colorMusic/colorMusic.ino b/firmware/Old versions/colorMusic/colorMusic.ino
deleted file mode 100644
index 199bbc1..0000000
--- a/firmware/Old versions/colorMusic/colorMusic.ino
+++ /dev/null
@@ -1,411 +0,0 @@
-/*
- Крутейшая свето-цветомузыка на Arduino и адресной светодиодной ленте WS2812b
- Управление:
- - Однократное нажатие кнопки: смена режима
- - Удержание кнопки: калибровка нижнего порога шума
- Режимы работы (переключаются кнопкой):
- - VU meter (столбик громкости): от зелёного к красному
- - VU meter (столбик громкости): плавно бегущая радуга
- - Светомузыка по частотам: 5 полос симметрично
- - Светомузыка по частотам: 3 полосы
- - Светомузыка по частотам: 1 полоса
- Особенности:
- - Плавная анимация (можно настроить)
- - Автонастройка по громкости (можно настроить)
- - Фильтр нижнего шума (можно настроить)
- - Автокалибровка шума при запуске (можно настроить)
- - Поддержка стерео и моно звука (можно настроить)
-
- НАСТРОЙКА НИЖНЕГО ПОРОГА ШУМА (строки 65-71)
- - Ручная: выключаем AUTO_LOW_PASS и EEPROM_LOW_PASS, настраиваем LOW_PASS и SPEKTR_LOW_PASS вручную
- - При запуске: включаем AUTO_LOW_PASS. При подаче питания музыка должна стоять на паузе!
- - По кнопке: при удерживании кнопки 1 секунду настраивается нижний порог шума (музыку на паузу!)
- - Из памяти (ЛУЧШИЙ ВАРИАНТ): выключаем AUTO_LOW_PASS и включаем EEPROM_LOW_PASS
- - Включаем систему
- - Ставим музыку на паузу
- - Удерживаем кнопку 1 секунду
- Значения шумов будут записаны в память и САМИ загружаться при последующем запуске! Всё!
-
- **************************************************
- Разработано: AlexGyver
- Страница проекта: http://alexgyver.ru/colormusic/
- GitHub: https://github.com/AlexGyver/ColorMusic
-*/
-
-// --------------------------- НАСТРОЙКИ ---------------------------
-// лента
-#define NUM_LEDS 60 // количество светодиодов
-#define BRIGHTNESS 230 // яркость (0 - 255)
-
-// пины
-#define SOUND_R A2 // аналоговый пин вход аудио, правый канал
-#define SOUND_L A1 // аналоговый пин вход аудио, левый канал
-#define SOUND_R_FREQ A3 // аналоговый пин вход аудио для режима с частотами (через кондер)
-#define BTN_PIN 3 // кнопка переключения режимов (PIN --- КНОПКА --- GND)
-#define LED_PIN 12 // пин DI светодиодной ленты
-#define POT_GND A0 // пин земля для потенциометра
-
-// настройки радуги
-#define RAINBOW_SPEED 6 // скорость движения радуги (чем меньше число, тем быстрее радуга)
-#define RAINBOW_STEP 6 // шаг изменения цвета радуги
-
-// отрисовка
-#define MODE 0 // режим при запуске
-#define MAIN_LOOP 5 // период основного цикла отрисовки (по умолчанию 5)
-#define SMOOTH 0.5 // коэффициент плавности анимации VU (по умолчанию 0.5)
-#define SMOOTH_FREQ 0.8 // коэффициент плавности анимации частот (по умолчанию 0.8)
-#define MAX_COEF 1.8 // коэффициент громкости (максимальное равно срднему * этот коэф) (по умолчанию 1.8)
-#define MAX_COEF_FREQ 1.2 // коэффициент порога для "вспышки" цветомузыки (по умолчанию 1.5)
-
-// сигнал
-#define MONO 1 // 1 - только один канал (ПРАВЫЙ!!!!! SOUND_R!!!!!), 0 - два канала
-#define EXP 1.4 // степень усиления сигнала (для более "резкой" работы) (по умолчанию 1.4)
-#define POTENT 1 // 1 - используем потенциометр, 0 - используется внутренний источник опорного напряжения 1.1 В
-
-// нижний порог шумов
-int LOW_PASS = 100; // нижний порог шумов режим VU, ручная настройка
-int SPEKTR_LOW_PASS = 40; // нижний порог шумов режим спектра, ручная настройка
-#define AUTO_LOW_PASS 0 // разрешить настройку нижнего порога шумов при запуске (по умолч. 0)
-#define EEPROM_LOW_PASS 1 // порог шумов хранится в энергонезависимой памяти (по умолч. 1)
-#define LOW_PASS_ADD 13 // "добавочная" величина к нижнему порогу, для надёжности (режим VU)
-#define LOW_PASS_FREQ_ADD 3 // "добавочная" величина к нижнему порогу, для надёжности (режим частот)
-
-// режим цветомузыки
-#define LOW_COLOR RED // цвет низких частот
-#define MID_COLOR GREEN // цвет средних
-#define HIGH_COLOR YELLOW // цвет высоких
-// --------------------------- НАСТРОЙКИ ---------------------------
-
-/*
- Как работает алгоритм:
- - Режим громкости
- - Делается 100 измерений напряжения на АЦП
- - Ищется максимальное
- - Фильтруется по нижнему порогу шумов
- - Возводится в степень для большей "резкости" анимации
- - Фильтруется "бегущим средним"
- - Ищется "средняя" громкость за несколько секунд (тоже бегущее среднее, но очень медленное)
- - Ищем "максимальную громкость шкалы", как среднюю * некоторый коэффициент
- - Преобразуем сигнал в количество горящих светодиодов
- - Включаются светодиоды согласно режиму отрисовки
-
- - Режим цветомузыки:
- - Преобразование Хартли (разбивка на спектр частот)
- - Фильтрация по нижнему порогу шумов
- - Поиск максимального значения в трёх диапазонах (низкие, средние, высокие)
- - Расчёт "средней громкости" (медленное бегущее среднее)
- - Если текущий сигнал больше среднего * коэффициент - включаем светодиоды
- - Итого имеем массив colorMusicFlash, в котором три ячейки 1 или 0, вкл или выкл
- - Включаем отрезки светодиодов согласно массиву
-*/
-
-// --------------------- ДЛЯ РАЗРАБОТЧИКОВ ---------------------
-// цвета
-#define BLUE 0x0000FF
-#define RED 0xFF0000
-#define GREEN 0x00ff00
-#define CYAN 0x00FFFF
-#define MAGENTA 0xFF00FF
-#define YELLOW 0xFFFF00
-#define WHITE 0xFFFFFF
-#define BLACK 0x000000
-
-#define STRIPE NUM_LEDS / 5
-
-#define FHT_N 64 // ширина спектра х2
-#define LOG_OUT 1
-#include // преобразование Хартли
-#include
-
-#include "FastLED.h"
-CRGB leds[NUM_LEDS];
-
-#include "GyverButton.h"
-GButton butt1(BTN_PIN);
-
-// градиент-палитра от зелёного к красному
-DEFINE_GRADIENT_PALETTE(soundlevel_gp) {
- 0, 0, 255, 0, // green
- 100, 255, 255, 0, // yellow
- 150, 255, 100, 0, // orange
- 200, 255, 50, 0, // red
- 255, 255, 0, 0 // red
-};
-CRGBPalette32 myPal = soundlevel_gp;
-
-byte Rlenght, Llenght;
-float RsoundLevel, RsoundLevel_f;
-float LsoundLevel, LsoundLevel_f;
-
-float averageLevel = 50;
-int maxLevel = 100;
-byte MAX_CH = NUM_LEDS / 2;
-int hue;
-unsigned long main_timer, hue_timer;
-float averK = 0.006, k = SMOOTH, k_freq = SMOOTH_FREQ;
-byte count;
-float index = (float)255 / MAX_CH; // коэффициент перевода для палитры
-boolean lowFlag;
-byte low_pass;
-int RcurrentLevel, LcurrentLevel;
-int colorMusic[3];
-float colorMusic_f[3], colorMusic_aver[3];
-boolean colorMusicFlash[3];
-byte this_mode = MODE;
-
-#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
-#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
-// --------------------- ДЛЯ РАЗРАБОТЧИКОВ ---------------------
-
-void setup() {
- Serial.begin(9600);
- FastLED.addLeds(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
- FastLED.setBrightness(BRIGHTNESS);
-
- pinMode(13, OUTPUT);
- digitalWrite(13, LOW);
-
- pinMode(POT_GND, OUTPUT);
- digitalWrite(POT_GND, LOW);
- butt1.setTimeout(900);
-
- // для увеличения точности уменьшаем опорное напряжение,
- // выставив EXTERNAL и подключив Aref к выходу 3.3V на плате через делитель
- // GND ---[10-20 кОм] --- REF --- [10 кОм] --- 3V3
- // в данной схеме GND берётся из А0 для удобства подключения
- if (POTENT) analogReference(EXTERNAL);
- else analogReference(INTERNAL);
-
- // жуткая магия, меняем частоту оцифровки до 18 кГц
- // команды на ебучем ассемблере, даже не спрашивайте, как это работает
- sbi(ADCSRA, ADPS2);
- cbi(ADCSRA, ADPS1);
- sbi(ADCSRA, ADPS0);
-
- if (AUTO_LOW_PASS && !EEPROM_LOW_PASS) { // если разрешена автонастройка нижнего порога шумов
- autoLowPass();
- }
- if (EEPROM_LOW_PASS) { // восстановить значения шумов из памяти
- LOW_PASS = EEPROM.readInt(0);
- SPEKTR_LOW_PASS = EEPROM.readInt(2);
- }
-}
-
-void loop() {
- butt1.tick(); // обязательная функция отработки. Должна постоянно опрашиваться
- if (butt1.isSingle()) // если единичное нажатие
- if (++this_mode > 4) this_mode = 0; // изменить режим
-
- if (butt1.isHolded()) { // кнопка удержана
- digitalWrite(13, HIGH); // включить светодиод 13 пин
- FastLED.setBrightness(0); // погасить ленту
- FastLED.clear(); // очистить массив пикселей
- FastLED.show(); // отправить значения на ленту
- delay(500); // подождать чутка
- autoLowPass(); // измерить шумы
- delay(500); // подождать
- FastLED.setBrightness(BRIGHTNESS); // вернуть яркость
- digitalWrite(13, LOW); // выключить светодиод
- }
-
- // кольцевое изменение положения радуги по таймеру
- if (millis() - hue_timer > RAINBOW_SPEED) {
- if (++hue >= 255) hue = 0;
- hue_timer = millis();
- }
-
- // главный цикл отрисовки
- if (millis() - main_timer > MAIN_LOOP) {
- // сбрасываем значения
- RsoundLevel = 0;
- LsoundLevel = 0;
-
- // перваые два режима - громкость (VU meter)
- if (this_mode == 0 || this_mode == 1) {
- for (byte i = 0; i < 100; i ++) { // делаем 100 измерений
- RcurrentLevel = analogRead(SOUND_R); // с правого
- if (!MONO) LcurrentLevel = analogRead(SOUND_L); // и левого каналов
-
- if (RsoundLevel < RcurrentLevel) RsoundLevel = RcurrentLevel; // ищем максимальное
- if (!MONO) if (LsoundLevel < LcurrentLevel) LsoundLevel = LcurrentLevel; // ищем максимальное
- }
-
- // фильтруем по нижнему порогу шумов
- RsoundLevel = map(RsoundLevel, LOW_PASS, 1023, 0, 500);
- if (!MONO)LsoundLevel = map(LsoundLevel, LOW_PASS, 1023, 0, 500);
-
- // ограничиваем диапазон
- RsoundLevel = constrain(RsoundLevel, 0, 500);
- if (!MONO)LsoundLevel = constrain(LsoundLevel, 0, 500);
-
- // возводим в степень (для большей чёткости работы)
- RsoundLevel = pow(RsoundLevel, EXP);
- if (!MONO)LsoundLevel = pow(LsoundLevel, EXP);
-
- // фильтр
- RsoundLevel_f = RsoundLevel * k + RsoundLevel_f * (1 - k);
- if (!MONO)LsoundLevel_f = LsoundLevel * k + LsoundLevel_f * (1 - k);
-
- if (MONO) LsoundLevel_f = RsoundLevel_f; // если моно, то левый = правому
-
- // если значение выше порога - начинаем самое интересное
- if (RsoundLevel_f > 15 && LsoundLevel_f > 15) {
-
- // расчёт общей средней громкости с обоих каналов, фильтрация.
- // Фильтр очень медленный, сделано специально для автогромкости
- averageLevel = (float)(RsoundLevel_f + LsoundLevel_f) / 2 * averK + averageLevel * (1 - averK);
-
- // принимаем максимальную громкость шкалы как среднюю, умноженную на некоторый коэффициент MAX_COEF
- maxLevel = (float)averageLevel * MAX_COEF;
-
- // преобразуем сигнал в длину ленты (где MAX_CH это половина количества светодиодов)
- Rlenght = map(RsoundLevel_f, 0, maxLevel, 0, MAX_CH);
- Llenght = map(LsoundLevel_f, 0, maxLevel, 0, MAX_CH);
-
- // ограничиваем до макс. числа светодиодов
- Rlenght = constrain(Rlenght, 0, MAX_CH);
- Llenght = constrain(Llenght, 0, MAX_CH);
-
- animation(); // отрисовать
- }
- }
-
- // 3-5 режим - цветомузыка
- if (this_mode == 2 || this_mode == 3 || this_mode == 4) {
- analyzeAudio();
- colorMusic[0] = 0;
- colorMusic[1] = 0;
- colorMusic[2] = 0;
- // низкие частоты, выборка с 3 по 5 тон
- for (byte i = 3; i < 6; i++) {
- if (fht_log_out[i] > SPEKTR_LOW_PASS) {
- if (fht_log_out[i] > colorMusic[0]) colorMusic[0] = fht_log_out[i];
- }
- }
- // средние частоты, выборка с 6 по 10 тон
- for (byte i = 6; i < 11; i++) {
- if (fht_log_out[i] > SPEKTR_LOW_PASS) {
- if (fht_log_out[i] > colorMusic[1]) colorMusic[1] = fht_log_out[i];
- }
- }
- // высокие частоты, выборка с 11 по 30 тон
- for (byte i = 11; i < 31; i++) {
- if (fht_log_out[i] > SPEKTR_LOW_PASS) {
- if (fht_log_out[i] > colorMusic[2]) colorMusic[2] = fht_log_out[i];
- }
- }
- for (byte i = 0; i < 3; i++) {
- colorMusic_aver[i] = colorMusic[i] * averK + colorMusic_aver[i] * (1 - averK); // общая фильтрация
- colorMusic_f[i] = colorMusic[i] * k_freq + colorMusic_f[i] * (1 - k_freq); // локальная
- if (colorMusic_f[i] > ((float)colorMusic_aver[i] * MAX_COEF_FREQ))
- colorMusicFlash[i] = 1;
- else
- colorMusicFlash[i] = 0;
- }
- animation();
- }
-
- FastLED.show(); // отправить значения на ленту
- FastLED.clear(); // очистить массив пикселей
- main_timer = millis(); // сбросить таймер
- }
-}
-
-void animation() {
- // согласно режиму
- switch (this_mode) {
- case 0:
- count = 0;
- for (int i = (MAX_CH - 1); i > ((MAX_CH - 1) - Rlenght); i--) {
- leds[i] = ColorFromPalette(myPal, (count * index)); // заливка по палитре " от зелёного к красному"
- count++;
- }
- count = 0;
- for (int i = (MAX_CH); i < (MAX_CH + Llenght); i++ ) {
- leds[i] = ColorFromPalette(myPal, (count * index)); // заливка по палитре " от зелёного к красному"
- count++;
- }
- break;
- case 1:
- count = 0;
- for (int i = (MAX_CH - 1); i > ((MAX_CH - 1) - Rlenght); i--) {
- leds[i] = ColorFromPalette(RainbowColors_p, (count * index) / 2 - hue); // заливка по палитре радуга
- count++;
- }
- count = 0;
- for (int i = (MAX_CH); i < (MAX_CH + Llenght); i++ ) {
- leds[i] = ColorFromPalette(RainbowColors_p, (count * index) / 2 - hue); // заливка по палитре радуга
- count++;
- }
- break;
- case 2:
- for (int i = 0; i < NUM_LEDS; i++) {
- if (i < STRIPE) leds[i] = colorMusicFlash[2] * HIGH_COLOR;
- else if (i < STRIPE * 2) leds[i] = colorMusicFlash[1] * MID_COLOR;
- else if (i < STRIPE * 3) leds[i] = colorMusicFlash[0] * LOW_COLOR;
- else if (i < STRIPE * 4) leds[i] = colorMusicFlash[1] * MID_COLOR;
- else if (i < STRIPE * 5) leds[i] = colorMusicFlash[2] * HIGH_COLOR;
- }
- break;
- case 3:
- for (int i = 0; i < NUM_LEDS; i++) {
- if (i < NUM_LEDS / 3) leds[i] = colorMusicFlash[2] * HIGH_COLOR;
- else if (i < NUM_LEDS * 2 / 3) leds[i] = colorMusicFlash[1] * MID_COLOR;
- else if (i < NUM_LEDS) leds[i] = colorMusicFlash[0] * LOW_COLOR;
- }
- break;
- case 4:
- uint32_t this_color;
- if (colorMusicFlash[2]) this_color = HIGH_COLOR;
- else if (colorMusicFlash[1]) this_color = MID_COLOR;
- else if (colorMusicFlash[0]) this_color = LOW_COLOR;
- else this_color = BLACK;
- for (int i = 0; i < NUM_LEDS; i++) {
- leds[i] = this_color;
- }
- break;
- }
-}
-
-void autoLowPass() {
- // для режима VU
- delay(10); // ждём инициализации АЦП
- int thisMax = 0; // максимум
- int thisLevel;
- for (byte i = 0; i < 200; i++) {
- thisLevel = analogRead(SOUND_R); // делаем 200 измерений
- if (thisLevel > thisMax) // ищем максимумы
- thisMax = thisLevel; // запоминаем
- delay(4); // ждём 4мс
- }
- LOW_PASS = thisMax + LOW_PASS_ADD; // нижний порог как максимум тишины + некая величина
-
- // для режима спектра
- thisMax = 0;
- for (byte i = 0; i < 100; i++) { // делаем 100 измерений
- analyzeAudio(); // разбить в спектр
- for (byte j = 2; j < 32; j++) { // первые 2 канала - хлам
- thisLevel = fht_log_out[j];
- if (thisLevel > thisMax) // ищем максимумы
- thisMax = thisLevel; // запоминаем
- }
- delay(4); // ждём 4мс
- }
- SPEKTR_LOW_PASS = thisMax + LOW_PASS_FREQ_ADD; // нижний порог как максимум тишины
-
- if (EEPROM_LOW_PASS && !AUTO_LOW_PASS) {
- EEPROM.updateInt(0, LOW_PASS);
- EEPROM.updateInt(2, SPEKTR_LOW_PASS);
- }
-}
-
-void analyzeAudio() {
- for (int i = 0 ; i < FHT_N ; i++) {
- int sample = analogRead(SOUND_R_FREQ);
- fht_input[i] = sample; // put real data into bins
- }
- fht_window(); // window the data for better frequency response
- fht_reorder(); // reorder the data before doing the fht
- fht_run(); // process the data in the fht
- fht_mag_log(); // take the output of the fht
-}
diff --git a/firmware/Old versions/colorMusic_v1.1/colorMusic_v1.1.ino b/firmware/Old versions/colorMusic_v1.1/colorMusic_v1.1.ino
deleted file mode 100644
index 7fc226f..0000000
--- a/firmware/Old versions/colorMusic_v1.1/colorMusic_v1.1.ino
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- Крутейшая свето-цветомузыка на Arduino и адресной светодиодной ленте WS2812b
- Управление:
- - Однократное нажатие кнопки: смена режима
- - Удержание кнопки: калибровка нижнего порога шума
- Режимы работы (переключаются кнопкой):
- - VU meter (столбик громкости): от зелёного к красному
- - VU meter (столбик громкости): плавно бегущая радуга
- - Светомузыка по частотам: 5 полос симметрично
- - Светомузыка по частотам: 3 полосы
- - Светомузыка по частотам: 1 полоса
- Особенности:
- - Плавная анимация (можно настроить)
- - Автонастройка по громкости (можно настроить)
- - Фильтр нижнего шума (можно настроить)
- - Автокалибровка шума при запуске (можно настроить)
- - Поддержка стерео и моно звука (можно настроить)
-
- НАСТРОЙКА НИЖНЕГО ПОРОГА ШУМА (строки 65-71)
- - Ручная: выключаем AUTO_LOW_PASS и EEPROM_LOW_PASS, настраиваем LOW_PASS и SPEKTR_LOW_PASS вручную
- - При запуске: включаем AUTO_LOW_PASS. При подаче питания музыка должна стоять на паузе!
- - По кнопке: при удерживании кнопки 1 секунду настраивается нижний порог шума (музыку на паузу!)
- - Из памяти (ЛУЧШИЙ ВАРИАНТ): выключаем AUTO_LOW_PASS и включаем EEPROM_LOW_PASS
- - Включаем систему
- - Ставим музыку на паузу
- - Удерживаем кнопку 1 секунду
- Значения шумов будут записаны в память и САМИ загружаться при последующем запуске! Всё!
-
- **************************************************
- Разработано: AlexGyver
- Страница проекта: http://alexgyver.ru/colormusic/
- GitHub: https://github.com/AlexGyver/ColorMusic
-*/
-
-// --------------------------- НАСТРОЙКИ ---------------------------
-// лента
-#define NUM_LEDS 60 // количество светодиодов
-#define BRIGHTNESS 200 // яркость (0 - 255)
-
-// пины
-#define SOUND_R A2 // аналоговый пин вход аудио, правый канал
-#define SOUND_L A1 // аналоговый пин вход аудио, левый канал
-#define SOUND_R_FREQ A3 // аналоговый пин вход аудио для режима с частотами (через кондер)
-#define BTN_PIN 3 // кнопка переключения режимов (PIN --- КНОПКА --- GND)
-#define LED_PIN 12 // пин DI светодиодной ленты
-#define POT_GND A0 // пин земля для потенциометра
-
-// настройки радуги
-#define RAINBOW_SPEED 6 // скорость движения радуги (чем меньше число, тем быстрее радуга)
-#define RAINBOW_STEP 6 // шаг изменения цвета радуги
-
-// отрисовка
-#define MODE 0 // режим при запуске
-#define MAIN_LOOP 5 // период основного цикла отрисовки (по умолчанию 5)
-#define SMOOTH 0.5 // коэффициент плавности анимации VU (по умолчанию 0.5)
-#define SMOOTH_FREQ 0.8 // коэффициент плавности анимации частот (по умолчанию 0.8)
-#define MAX_COEF 1.8 // коэффициент громкости (максимальное равно срднему * этот коэф) (по умолчанию 1.8)
-#define MAX_COEF_FREQ 1.2 // коэффициент порога для "вспышки" цветомузыки (по умолчанию 1.5)
-
-// сигнал
-#define MONO 1 // 1 - только один канал (ПРАВЫЙ!!!!! SOUND_R!!!!!), 0 - два канала
-#define EXP 1.4 // степень усиления сигнала (для более "резкой" работы) (по умолчанию 1.4)
-#define POTENT 1 // 1 - используем потенциометр, 0 - используется внутренний источник опорного напряжения 1.1 В
-
-// нижний порог шумов
-int LOW_PASS = 100; // нижний порог шумов режим VU, ручная настройка
-int SPEKTR_LOW_PASS = 40; // нижний порог шумов режим спектра, ручная настройка
-#define AUTO_LOW_PASS 0 // разрешить настройку нижнего порога шумов при запуске (по умолч. 0)
-#define EEPROM_LOW_PASS 1 // порог шумов хранится в энергонезависимой памяти (по умолч. 1)
-#define LOW_PASS_ADD 13 // "добавочная" величина к нижнему порогу, для надёжности (режим VU)
-#define LOW_PASS_FREQ_ADD 3 // "добавочная" величина к нижнему порогу, для надёжности (режим частот)
-
-// режим цветомузыки
-#define SMOOTH_STEP 20 // шаг уменьшения яркости в режиме цветомузыки (чем больше, тем быстрее гаснет)
-#define LOW_COLOR HUE_RED // цвет низких частот
-#define MID_COLOR HUE_GREEN // цвет средних
-#define HIGH_COLOR HUE_YELLOW // цвет высоких
-
-// режим стробоскопа
-#define STROBE_PERIOD 100 // период вспышек, миллисекунды
-#define STROBE_DUTY 30 // скважность вспышек (1 - 99) - отношение времени вспышки ко времени темноты
-#define STROBE_COLOR HUE_YELLOW // цвет стробоскопа
-#define STROBE_SAT 0 // насыщенность. Если 0 - цвет будет БЕЛЫЙ при любом цвете (0 - 255)
-#define STROBE_SMOOTH 100 // скорость нарастания/угасания вспышки (0 - 255)
-
-/*
- Цвета для HSV
- HUE_RED
- HUE_ORANGE
- HUE_YELLOW
- HUE_GREEN
- HUE_AQUA
- HUE_BLUE
- HUE_PURPLE
- HUE_PINK
-*/
-// --------------------------- НАСТРОЙКИ ---------------------------
-
-// --------------------- ДЛЯ РАЗРАБОТЧИКОВ ---------------------
-#define MODE_AMOUNT 6 // количество режимов
-
-// цвета (устаревшие)
-#define BLUE 0x0000FF
-#define RED 0xFF0000
-#define GREEN 0x00ff00
-#define CYAN 0x00FFFF
-#define MAGENTA 0xFF00FF
-#define YELLOW 0xFFFF00
-#define WHITE 0xFFFFFF
-#define BLACK 0x000000
-
-#define STRIPE NUM_LEDS / 5
-
-#define FHT_N 64 // ширина спектра х2
-#define LOG_OUT 1
-#include // преобразование Хартли
-#include
-
-#include "FastLED.h"
-CRGB leds[NUM_LEDS];
-
-#include "GyverButton.h"
-GButton butt1(BTN_PIN);
-
-// градиент-палитра от зелёного к красному
-DEFINE_GRADIENT_PALETTE(soundlevel_gp) {
- 0, 0, 255, 0, // green
- 100, 255, 255, 0, // yellow
- 150, 255, 100, 0, // orange
- 200, 255, 50, 0, // red
- 255, 255, 0, 0 // red
-};
-CRGBPalette32 myPal = soundlevel_gp;
-
-byte Rlenght, Llenght;
-float RsoundLevel, RsoundLevel_f;
-float LsoundLevel, LsoundLevel_f;
-
-float averageLevel = 50;
-int maxLevel = 100;
-byte MAX_CH = NUM_LEDS / 2;
-int hue;
-unsigned long main_timer, hue_timer, strobe_timer;
-float averK = 0.006, k = SMOOTH, k_freq = SMOOTH_FREQ;
-byte count;
-float index = (float)255 / MAX_CH; // коэффициент перевода для палитры
-boolean lowFlag;
-byte low_pass;
-int RcurrentLevel, LcurrentLevel;
-int colorMusic[3];
-float colorMusic_f[3], colorMusic_aver[3];
-boolean colorMusicFlash[3], strobeUp_flag, strobeDwn_flag;
-byte this_mode = MODE;
-int thisBright[3], strobe_bright = 0;
-unsigned int light_time = STROBE_PERIOD * STROBE_DUTY / 100;
-
-#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
-#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
-// --------------------- ДЛЯ РАЗРАБОТЧИКОВ ---------------------
-
-void setup() {
- Serial.begin(9600);
- FastLED.addLeds(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
- FastLED.setBrightness(BRIGHTNESS);
-
- pinMode(13, OUTPUT);
- digitalWrite(13, LOW);
-
- pinMode(POT_GND, OUTPUT);
- digitalWrite(POT_GND, LOW);
- butt1.setTimeout(900);
-
- // для увеличения точности уменьшаем опорное напряжение,
- // выставив EXTERNAL и подключив Aref к выходу 3.3V на плате через делитель
- // GND ---[10-20 кОм] --- REF --- [10 кОм] --- 3V3
- // в данной схеме GND берётся из А0 для удобства подключения
- if (POTENT) analogReference(EXTERNAL);
- else analogReference(INTERNAL);
-
- // жуткая магия, меняем частоту оцифровки до 18 кГц
- // команды на ебучем ассемблере, даже не спрашивайте, как это работает
- sbi(ADCSRA, ADPS2);
- cbi(ADCSRA, ADPS1);
- sbi(ADCSRA, ADPS0);
-
- if (AUTO_LOW_PASS && !EEPROM_LOW_PASS) { // если разрешена автонастройка нижнего порога шумов
- autoLowPass();
- }
- if (EEPROM_LOW_PASS) { // восстановить значения шумов из памяти
- LOW_PASS = EEPROM.readInt(0);
- SPEKTR_LOW_PASS = EEPROM.readInt(2);
- }
-}
-
-void loop() {
- butt1.tick(); // обязательная функция отработки. Должна постоянно опрашиваться
- if (butt1.isSingle()) // если единичное нажатие
- if (++this_mode >= MODE_AMOUNT) this_mode = 0; // изменить режим
-
- if (butt1.isHolded()) { // кнопка удержана
- digitalWrite(13, HIGH); // включить светодиод 13 пин
- FastLED.setBrightness(0); // погасить ленту
- FastLED.clear(); // очистить массив пикселей
- FastLED.show(); // отправить значения на ленту
- delay(500); // подождать чутка
- autoLowPass(); // измерить шумы
- delay(500); // подождать
- FastLED.setBrightness(BRIGHTNESS); // вернуть яркость
- digitalWrite(13, LOW); // выключить светодиод
- }
-
- // кольцевое изменение положения радуги по таймеру
- if (millis() - hue_timer > RAINBOW_SPEED) {
- if (++hue >= 255) hue = 0;
- hue_timer = millis();
- }
-
- // главный цикл отрисовки
- if (millis() - main_timer > MAIN_LOOP) {
- // сбрасываем значения
- RsoundLevel = 0;
- LsoundLevel = 0;
-
- // перваые два режима - громкость (VU meter)
- if (this_mode == 0 || this_mode == 1) {
- for (byte i = 0; i < 100; i ++) { // делаем 100 измерений
- RcurrentLevel = analogRead(SOUND_R); // с правого
- if (!MONO) LcurrentLevel = analogRead(SOUND_L); // и левого каналов
-
- if (RsoundLevel < RcurrentLevel) RsoundLevel = RcurrentLevel; // ищем максимальное
- if (!MONO) if (LsoundLevel < LcurrentLevel) LsoundLevel = LcurrentLevel; // ищем максимальное
- }
-
- // фильтруем по нижнему порогу шумов
- RsoundLevel = map(RsoundLevel, LOW_PASS, 1023, 0, 500);
- if (!MONO)LsoundLevel = map(LsoundLevel, LOW_PASS, 1023, 0, 500);
-
- // ограничиваем диапазон
- RsoundLevel = constrain(RsoundLevel, 0, 500);
- if (!MONO)LsoundLevel = constrain(LsoundLevel, 0, 500);
-
- // возводим в степень (для большей чёткости работы)
- RsoundLevel = pow(RsoundLevel, EXP);
- if (!MONO)LsoundLevel = pow(LsoundLevel, EXP);
-
- // фильтр
- RsoundLevel_f = RsoundLevel * k + RsoundLevel_f * (1 - k);
- if (!MONO)LsoundLevel_f = LsoundLevel * k + LsoundLevel_f * (1 - k);
-
- if (MONO) LsoundLevel_f = RsoundLevel_f; // если моно, то левый = правому
-
- // если значение выше порога - начинаем самое интересное
- if (RsoundLevel_f > 15 && LsoundLevel_f > 15) {
-
- // расчёт общей средней громкости с обоих каналов, фильтрация.
- // Фильтр очень медленный, сделано специально для автогромкости
- averageLevel = (float)(RsoundLevel_f + LsoundLevel_f) / 2 * averK + averageLevel * (1 - averK);
-
- // принимаем максимальную громкость шкалы как среднюю, умноженную на некоторый коэффициент MAX_COEF
- maxLevel = (float)averageLevel * MAX_COEF;
-
- // преобразуем сигнал в длину ленты (где MAX_CH это половина количества светодиодов)
- Rlenght = map(RsoundLevel_f, 0, maxLevel, 0, MAX_CH);
- Llenght = map(LsoundLevel_f, 0, maxLevel, 0, MAX_CH);
-
- // ограничиваем до макс. числа светодиодов
- Rlenght = constrain(Rlenght, 0, MAX_CH);
- Llenght = constrain(Llenght, 0, MAX_CH);
-
- animation(); // отрисовать
- }
- }
-
- // 3-5 режим - цветомузыка
- if (this_mode == 2 || this_mode == 3 || this_mode == 4) {
- analyzeAudio();
- colorMusic[0] = 0;
- colorMusic[1] = 0;
- colorMusic[2] = 0;
- // низкие частоты, выборка с 3 по 5 тон
- for (byte i = 3; i < 6; i++) {
- if (fht_log_out[i] > SPEKTR_LOW_PASS) {
- if (fht_log_out[i] > colorMusic[0]) colorMusic[0] = fht_log_out[i];
- }
- }
- // средние частоты, выборка с 6 по 10 тон
- for (byte i = 6; i < 11; i++) {
- if (fht_log_out[i] > SPEKTR_LOW_PASS) {
- if (fht_log_out[i] > colorMusic[1]) colorMusic[1] = fht_log_out[i];
- }
- }
- // высокие частоты, выборка с 11 по 30 тон
- for (byte i = 11; i < 31; i++) {
- if (fht_log_out[i] > SPEKTR_LOW_PASS) {
- if (fht_log_out[i] > colorMusic[2]) colorMusic[2] = fht_log_out[i];
- }
- }
- for (byte i = 0; i < 3; i++) {
- colorMusic_aver[i] = colorMusic[i] * averK + colorMusic_aver[i] * (1 - averK); // общая фильтрация
- colorMusic_f[i] = colorMusic[i] * k_freq + colorMusic_f[i] * (1 - k_freq); // локальная
- if (colorMusic_f[i] > ((float)colorMusic_aver[i] * MAX_COEF_FREQ)) {
- thisBright[i] = 255;
- colorMusicFlash[i] = 1;
- } else colorMusicFlash[i] = 0;
- if (thisBright[i] >= 0) thisBright[i] -= SMOOTH_STEP;
- if (thisBright[i] < 0) thisBright[i] = 0;
- }
- animation();
- }
- if (this_mode == 5) {
- if ((long)millis() - strobe_timer > STROBE_PERIOD) {
- strobe_timer = millis();
- strobeUp_flag = true;
- strobeDwn_flag = false;
- }
- if ((long)millis() - strobe_timer > light_time) {
- strobeDwn_flag = true;
- }
- if (strobeUp_flag) { // если настало время пыхнуть
- if (strobe_bright < 255) // если яркость не максимальная
- strobe_bright += STROBE_SMOOTH; // увелчить
- if (strobe_bright > 255) { // если пробили макс. яркость
- strobe_bright = 255; // оставить максимум
- strobeUp_flag = false; // флаг опустить
- }
- }
-
- if (strobeDwn_flag) { // гаснем
- if (strobe_bright > 0) // если яркость не минимальная
- strobe_bright -= STROBE_SMOOTH; // уменьшить
- if (strobe_bright < 0) { // если пробили мин. яркость
- strobeDwn_flag = false;
- strobe_bright = 0; // оставить 0
- }
- }
- animation();
- }
-
- FastLED.show(); // отправить значения на ленту
- FastLED.clear(); // очистить массив пикселей
- main_timer = millis(); // сбросить таймер
- }
-}
-
-void animation() {
- // согласно режиму
- switch (this_mode) {
- case 0:
- count = 0;
- for (int i = (MAX_CH - 1); i > ((MAX_CH - 1) - Rlenght); i--) {
- leds[i] = ColorFromPalette(myPal, (count * index)); // заливка по палитре " от зелёного к красному"
- count++;
- }
- count = 0;
- for (int i = (MAX_CH); i < (MAX_CH + Llenght); i++ ) {
- leds[i] = ColorFromPalette(myPal, (count * index)); // заливка по палитре " от зелёного к красному"
- count++;
- }
- break;
- case 1:
- count = 0;
- for (int i = (MAX_CH - 1); i > ((MAX_CH - 1) - Rlenght); i--) {
- leds[i] = ColorFromPalette(RainbowColors_p, (count * index) / 2 - hue); // заливка по палитре радуга
- count++;
- }
- count = 0;
- for (int i = (MAX_CH); i < (MAX_CH + Llenght); i++ ) {
- leds[i] = ColorFromPalette(RainbowColors_p, (count * index) / 2 - hue); // заливка по палитре радуга
- count++;
- }
- break;
- case 2:
- for (int i = 0; i < NUM_LEDS; i++) {
- if (i < STRIPE) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (i < STRIPE * 2) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < STRIPE * 3) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else if (i < STRIPE * 4) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < STRIPE * 5) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- }
- break;
- case 3:
- for (int i = 0; i < NUM_LEDS; i++) {
- if (i < NUM_LEDS / 3) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (i < NUM_LEDS * 2 / 3) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < NUM_LEDS) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
- }
- break;
- case 4:
- if (colorMusicFlash[2]) for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (colorMusicFlash[1]) for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (colorMusicFlash[0]) for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else for (int i = 0; i < NUM_LEDS; i++) leds[i] = BLACK;
- break;
- case 5:
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(STROBE_COLOR, STROBE_SAT, strobe_bright);
- break;
- }
-}
-
-void autoLowPass() {
- // для режима VU
- delay(10); // ждём инициализации АЦП
- int thisMax = 0; // максимум
- int thisLevel;
- for (byte i = 0; i < 200; i++) {
- thisLevel = analogRead(SOUND_R); // делаем 200 измерений
- if (thisLevel > thisMax) // ищем максимумы
- thisMax = thisLevel; // запоминаем
- delay(4); // ждём 4мс
- }
- LOW_PASS = thisMax + LOW_PASS_ADD; // нижний порог как максимум тишины + некая величина
-
- // для режима спектра
- thisMax = 0;
- for (byte i = 0; i < 100; i++) { // делаем 100 измерений
- analyzeAudio(); // разбить в спектр
- for (byte j = 2; j < 32; j++) { // первые 2 канала - хлам
- thisLevel = fht_log_out[j];
- if (thisLevel > thisMax) // ищем максимумы
- thisMax = thisLevel; // запоминаем
- }
- delay(4); // ждём 4мс
- }
- SPEKTR_LOW_PASS = thisMax + LOW_PASS_FREQ_ADD; // нижний порог как максимум тишины
-
- if (EEPROM_LOW_PASS && !AUTO_LOW_PASS) {
- EEPROM.updateInt(0, LOW_PASS);
- EEPROM.updateInt(2, SPEKTR_LOW_PASS);
- }
-}
-
-void analyzeAudio() {
- for (int i = 0 ; i < FHT_N ; i++) {
- int sample = analogRead(SOUND_R_FREQ);
- fht_input[i] = sample; // put real data into bins
- }
- fht_window(); // window the data for better frequency response
- fht_reorder(); // reorder the data before doing the fht
- fht_run(); // process the data in the fht
- fht_mag_log(); // take the output of the fht
-}
diff --git a/firmware/Old versions/colorMusic_v2.3_KEYES/colorMusic_v2.3_KEYES.ino b/firmware/Old versions/colorMusic_v2.3_KEYES/colorMusic_v2.3_KEYES.ino
deleted file mode 100644
index b18db05..0000000
--- a/firmware/Old versions/colorMusic_v2.3_KEYES/colorMusic_v2.3_KEYES.ino
+++ /dev/null
@@ -1,947 +0,0 @@
-/*
- Крутейшая свето-цветомузыка на Arduino и адресной светодиодной ленте WS2812b.
- Данная версия поддерживает до 350 светодиодов!!!
- Управление:
- - Однократное нажатие кнопки: смена режима
- - Удержание кнопки: калибровка нижнего порога шума
- Режимы работы (переключаются кнопкой):
- - VU meter (столбик громкости): от зелёного к красному
- - VU meter (столбик громкости): плавно бегущая радуга
- - Светомузыка по частотам: 5 полос симметрично
- - Светомузыка по частотам: 3 полосы
- - Светомузыка по частотам: 1 полоса
- - Стробоскоп
- - (2.0) Подсветка
- - (2.0) Бегущие частоты
- - (2.1) анализатор спектра
- Особенности:
- - Плавная анимация (можно настроить)
- - Автонастройка по громкости (можно настроить)
- - Фильтр нижнего шума (можно настроить)
- - Автокалибровка шума при запуске (можно настроить)
- - Поддержка стерео и моно звука (можно настроить)
- - (2.0) в режиме частот лента не гаснет полностью (EMPTY_BRIGHT)
- - (2.1) все настройки сохраняются в памяти и не сбрасываются при перезагрузке
- - Сохранение настроек происходит при выключении кнопкой звёздочка (*)
- - А также через 30 секунд после последнего нажатия на любую кнопку ИК пульта
-
- НАСТРОЙКА НИЖНЕГО ПОРОГА ШУМА (строки 65-71)
- - Включаем систему
- - Ставим музыку на паузу
- - Удерживаем кнопку 1 секунду ИЛИ жмём кнопку 0 на пульте
- Значения шумов будут записаны в память и САМИ загружаться при последующем запуске! Всё!
-
- Пульт:
- - Цифры (1 - 9) активируют режимы
- - Цифра 0: калибровка шума
- - Звёздочка (*): включить/выключить систему
- - Кнопка ОК: переключение между локальными и глобальными настройками)
- - Решётка (#): смена подрежима
- - Глобальные настройки (горит светодиод на плате):
- + Стрелки ← →: общая яркость горящих светодиодов
- + Стрелки ↑ ↓: яркость "не горящих" светодиодов
- - Локальные настройки (у каждого режима свои):
- 1 - Шкала громкости (градиент)
- Стрелки ← →: плавность анимации
- 2 - Шкала громкости (радуга)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: скорость радуги
- 3 - Цветомузыка (5 полос)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- 4 - Цветомузыка (3 полосы)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- 5 - Цветомузыка (1 полоса)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- Подрежимы #: 3 частоты / низкие / средние / высокие
- 6 - Стробоскоп
- Стрелки ← →: плавность вспышек
- Стрелки ↑ ↓: частота вспышек
- 7 - Цветная подсветка
- Подрежимы #:
- Постоянный: стрелки ← →: цвет, стрелки ↑ ↓: насыщенность
- Плавная смена: стрелки ← →: скорость, стрелки ↑ ↓: насыщенность
- Бегущая радуга: стрелки ← →: скорость, стрелки ↑ ↓: шаг радуги
- 8 - “Бегущие частоты”
- Стрелки ← →: скорость
- Стрелки ↑ ↓: чувствительность
- Подрежимы #: 3 частоты / низкие / средние / высокие
- 9 - Анализатор спектра
- Стрелки ← →: шаг цвета
- Стрелки ↑ ↓: цвет
- **************************************************
- Разработано: AlexGyver
- Страница проекта: http://alexgyver.ru/colormusic/
- GitHub: https://github.com/AlexGyver/ColorMusic
-*/
-
-// --------------------------- НАСТРОЙКИ ---------------------------
-#define KEEP_SETTINGS 1 // хранить ВСЕ натсройки в памяти
-// лента
-#define NUM_LEDS 120 // количество светодиодов
-byte BRIGHTNESS = 200; // яркость (0 - 255)
-
-// пины
-#define SOUND_R A2 // аналоговый пин вход аудио, правый канал
-#define SOUND_L A1 // аналоговый пин вход аудио, левый канал
-#define SOUND_R_FREQ A3 // аналоговый пин вход аудио для режима с частотами (через кондер)
-#define BTN_PIN 3 // кнопка переключения режимов (PIN --- КНОПКА --- GND)
-#define LED_PIN 12 // пин DI светодиодной ленты
-#define POT_GND A0 // пин земля для потенциометра
-#define IR_PIN 2 // ИК приёмник
-
-// настройки радуги
-float RAINBOW_STEP = 5.5; // шаг изменения цвета радуги
-
-// отрисовка
-#define MODE 0 // режим при запуске
-#define MAIN_LOOP 5 // период основного цикла отрисовки (по умолчанию 5)
-
-// сигнал
-#define MONO 1 // 1 - только один канал (ПРАВЫЙ!!!!! SOUND_R!!!!!), 0 - два канала
-#define EXP 1.4 // степень усиления сигнала (для более "резкой" работы) (по умолчанию 1.4)
-#define POTENT 1 // 1 - используем потенциометр, 0 - используется внутренний источник опорного напряжения 1.1 В
-byte EMPTY_BRIGHT = 30; // яркость "не горящих" светодиодов (0 - 255)
-#define EMPTY_COLOR HUE_PURPLE // цвет "не горящих" светодиодов. Будет чёрный, если яркость 0
-
-// нижний порог шумов
-byte LOW_PASS = 100; // нижний порог шумов режим VU, ручная настройка
-byte SPEKTR_LOW_PASS = 40; // нижний порог шумов режим спектра, ручная настройка
-#define AUTO_LOW_PASS 0 // разрешить настройку нижнего порога шумов при запуске (по умолч. 0)
-#define EEPROM_LOW_PASS 1 // порог шумов хранится в энергонезависимой памяти (по умолч. 1)
-#define LOW_PASS_ADD 13 // "добавочная" величина к нижнему порогу, для надёжности (режим VU)
-#define LOW_PASS_FREQ_ADD 3 // "добавочная" величина к нижнему порогу, для надёжности (режим частот)
-
-// шкала громкости
-float SMOOTH = 0.5; // коэффициент плавности анимации VU (по умолчанию 0.5)
-#define MAX_COEF 1.8 // коэффициент громкости (максимальное равно срднему * этот коэф) (по умолчанию 1.8)
-
-// режим цветомузыки
-float SMOOTH_FREQ = 0.8; // коэффициент плавности анимации частот (по умолчанию 0.8)
-float MAX_COEF_FREQ = 1.2; // коэффициент порога для "вспышки" цветомузыки (по умолчанию 1.5)
-#define SMOOTH_STEP 20 // шаг уменьшения яркости в режиме цветомузыки (чем больше, тем быстрее гаснет)
-#define LOW_COLOR HUE_RED // цвет низких частот
-#define MID_COLOR HUE_GREEN // цвет средних
-#define HIGH_COLOR HUE_YELLOW // цвет высоких
-
-// режим стробоскопа
-int STROBE_PERIOD = 100; // период вспышек, миллисекунды
-#define STROBE_DUTY 20 // скважность вспышек (1 - 99) - отношение времени вспышки ко времени темноты
-#define STROBE_COLOR HUE_YELLOW // цвет стробоскопа
-#define STROBE_SAT 0 // насыщенность. Если 0 - цвет будет БЕЛЫЙ при любом цвете (0 - 255)
-byte STROBE_SMOOTH = 100; // скорость нарастания/угасания вспышки (0 - 255)
-
-// режим подсветки
-byte LIGHT_COLOR = 0; // начальный цвет подсветки
-byte LIGHT_SAT = 200; // начальная насыщенность подсветки
-byte COLOR_SPEED = 100;
-int RAINBOW_PERIOD = 3;
-float RAINBOW_STEP_2 = 5.5;
-
-// режим бегущих частот
-byte RUNNING_SPEED = 60;
-
-// режим анализатора спектра
-byte HUE_START = 0;
-byte HUE_STEP = 5;
-#define LIGHT_SMOOTH 2
-
-/*
- Цвета для HSV
- HUE_RED
- HUE_ORANGE
- HUE_YELLOW
- HUE_GREEN
- HUE_AQUA
- HUE_BLUE
- HUE_PURPLE
- HUE_PINK
-*/
-// --------------------------- НАСТРОЙКИ ---------------------------
-
-// ----- КНОПКИ ПУЛЬТА -----
-#define BUTT_UP 0xFF629D
-#define BUTT_DOWN 0xFFA857
-#define BUTT_LEFT 0xFF22DD
-#define BUTT_RIGHT 0xFFC23D
-#define BUTT_OK 0xFF02FD
-#define BUTT_1 0xFF6897
-#define BUTT_2 0xFF9867
-#define BUTT_3 0xFFB04F
-#define BUTT_4 0xFF30CF
-#define BUTT_5 0xFF18E7
-#define BUTT_6 0xFF7A85
-#define BUTT_7 0xFF10EF
-#define BUTT_8 0xFF38C7
-#define BUTT_9 0xFF5AA5
-#define BUTT_0 0xFF4AB5
-#define BUTT_STAR 0xFF42BD
-#define BUTT_HASH 0xFF52AD
-// ----- КНОПКИ ПУЛЬТА -----
-
-// ------------------------------ ДЛЯ РАЗРАБОТЧИКОВ --------------------------------
-#define MODE_AMOUNT 9 // количество режимов
-
-// цвета (устаревшие)
-#define BLUE 0x0000FF
-#define RED 0xFF0000
-#define GREEN 0x00ff00
-#define CYAN 0x00FFFF
-#define MAGENTA 0xFF00FF
-#define YELLOW 0xFFFF00
-#define WHITE 0xFFFFFF
-#define BLACK 0x000000
-
-#define STRIPE NUM_LEDS / 5
-float freq_to_stripe = NUM_LEDS / 40; // /2 так как симметрия, и /20 так как 20 частот
-
-#define FHT_N 64 // ширина спектра х2
-#define LOG_OUT 1
-#include // преобразование Хартли
-
-#include
-
-#define FASTLED_ALLOW_INTERRUPTS 1
-#include "FastLED.h"
-CRGB leds[NUM_LEDS];
-
-#include "GyverButton.h"
-GButton butt1(BTN_PIN);
-
-#include "IRremote.h"
-IRrecv irrecv(IR_PIN);
-decode_results results;
-
-// градиент-палитра от зелёного к красному
-DEFINE_GRADIENT_PALETTE(soundlevel_gp) {
- 0, 0, 255, 0, // green
- 100, 255, 255, 0, // yellow
- 150, 255, 100, 0, // orange
- 200, 255, 50, 0, // red
- 255, 255, 0, 0 // red
-};
-CRGBPalette32 myPal = soundlevel_gp;
-
-byte Rlenght, Llenght;
-float RsoundLevel, RsoundLevel_f;
-float LsoundLevel, LsoundLevel_f;
-
-float averageLevel = 50;
-int maxLevel = 100;
-byte MAX_CH = NUM_LEDS / 2;
-int hue;
-unsigned long main_timer, hue_timer, strobe_timer, running_timer, color_timer, rainbow_timer, eeprom_timer;
-float averK = 0.006;
-byte count;
-float index = (float)255 / MAX_CH; // коэффициент перевода для палитры
-boolean lowFlag;
-byte low_pass;
-int RcurrentLevel, LcurrentLevel;
-int colorMusic[3];
-float colorMusic_f[3], colorMusic_aver[3];
-boolean colorMusicFlash[3], strobeUp_flag, strobeDwn_flag;
-byte this_mode = MODE;
-int thisBright[3], strobe_bright = 0;
-unsigned int light_time = STROBE_PERIOD * STROBE_DUTY / 100;
-volatile boolean ir_flag;
-boolean settings_mode, ONstate = true;
-int8_t freq_strobe_mode, light_mode;
-int freq_max;
-float freq_max_f, rainbow_steps;
-int freq_f[32];
-int this_color;
-boolean running_flag[3], eeprom_flag;
-
-#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
-#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
-// ------------------------------ ДЛЯ РАЗРАБОТЧИКОВ --------------------------------
-
-void setup() {
- Serial.begin(9600);
- FastLED.addLeds(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
- FastLED.setBrightness(BRIGHTNESS);
-
- pinMode(13, OUTPUT);
- digitalWrite(13, LOW);
-
- pinMode(POT_GND, OUTPUT);
- digitalWrite(POT_GND, LOW);
- butt1.setTimeout(900);
-
- irrecv.enableIRIn(); // запускаем прием
- attachInterrupt(0, checkIR, RISING);
-
- // для увеличения точности уменьшаем опорное напряжение,
- // выставив EXTERNAL и подключив Aref к выходу 3.3V на плате через делитель
- // GND ---[10-20 кОм] --- REF --- [10 кОм] --- 3V3
- // в данной схеме GND берётся из А0 для удобства подключения
- if (POTENT) analogReference(EXTERNAL);
- else analogReference(INTERNAL);
-
- // жуткая магия, меняем частоту оцифровки до 18 кГц
- // команды на ебучем ассемблере, даже не спрашивайте, как это работает
- sbi(ADCSRA, ADPS2);
- cbi(ADCSRA, ADPS1);
- sbi(ADCSRA, ADPS0);
-
- if (AUTO_LOW_PASS && !EEPROM_LOW_PASS) { // если разрешена автонастройка нижнего порога шумов
- autoLowPass();
- }
- if (EEPROM_LOW_PASS) { // восстановить значения шумов из памяти
- LOW_PASS = EEPROM.readInt(70);
- SPEKTR_LOW_PASS = EEPROM.readInt(72);
- }
-
- // в 100 ячейке хранится число 100. Если нет - значит это первый запуск системы
- if (KEEP_SETTINGS) {
- if (EEPROM.read(100) != 100) {
- //Serial.println(F("First start"));
- EEPROM.write(100, 100);
- updateEEPROM();
- } else {
- readEEPROM();
- }
- }
-}
-
-void loop() {
- buttonTick(); // опрос и обработка кнопки
- remoteTick(); // опрос ИК пульта
- mainLoop(); // главный цикл обработки и отрисовки
- eepromTick(); // проверка не пора ли сохранить настройки
-}
-
-void mainLoop() {
- // главный цикл отрисовки
- if (ONstate) {
- if (millis() - main_timer > MAIN_LOOP) {
- // сбрасываем значения
- RsoundLevel = 0;
- LsoundLevel = 0;
-
- // перваые два режима - громкость (VU meter)
- if (this_mode == 0 || this_mode == 1) {
- for (byte i = 0; i < 100; i ++) { // делаем 100 измерений
- RcurrentLevel = analogRead(SOUND_R); // с правого
- if (!MONO) LcurrentLevel = analogRead(SOUND_L); // и левого каналов
-
- if (RsoundLevel < RcurrentLevel) RsoundLevel = RcurrentLevel; // ищем максимальное
- if (!MONO) if (LsoundLevel < LcurrentLevel) LsoundLevel = LcurrentLevel; // ищем максимальное
- }
-
- // фильтруем по нижнему порогу шумов
- RsoundLevel = map(RsoundLevel, LOW_PASS, 1023, 0, 500);
- if (!MONO)LsoundLevel = map(LsoundLevel, LOW_PASS, 1023, 0, 500);
-
- // ограничиваем диапазон
- RsoundLevel = constrain(RsoundLevel, 0, 500);
- if (!MONO)LsoundLevel = constrain(LsoundLevel, 0, 500);
-
- // возводим в степень (для большей чёткости работы)
- RsoundLevel = pow(RsoundLevel, EXP);
- if (!MONO)LsoundLevel = pow(LsoundLevel, EXP);
-
- // фильтр
- RsoundLevel_f = RsoundLevel * SMOOTH + RsoundLevel_f * (1 - SMOOTH);
- if (!MONO)LsoundLevel_f = LsoundLevel * SMOOTH + LsoundLevel_f * (1 - SMOOTH);
-
- if (MONO) LsoundLevel_f = RsoundLevel_f; // если моно, то левый = правому
-
- // заливаем "подложку", если яркость достаточная
- if (EMPTY_BRIGHT > 5) {
- for (int i = 0; i < NUM_LEDS; i++)
- leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- }
-
- // если значение выше порога - начинаем самое интересное
- if (RsoundLevel_f > 15 && LsoundLevel_f > 15) {
-
- // расчёт общей средней громкости с обоих каналов, фильтрация.
- // Фильтр очень медленный, сделано специально для автогромкости
- averageLevel = (float)(RsoundLevel_f + LsoundLevel_f) / 2 * averK + averageLevel * (1 - averK);
-
- // принимаем максимальную громкость шкалы как среднюю, умноженную на некоторый коэффициент MAX_COEF
- maxLevel = (float)averageLevel * MAX_COEF;
-
- // преобразуем сигнал в длину ленты (где MAX_CH это половина количества светодиодов)
- Rlenght = map(RsoundLevel_f, 0, maxLevel, 0, MAX_CH);
- Llenght = map(LsoundLevel_f, 0, maxLevel, 0, MAX_CH);
-
- // ограничиваем до макс. числа светодиодов
- Rlenght = constrain(Rlenght, 0, MAX_CH);
- Llenght = constrain(Llenght, 0, MAX_CH);
-
- animation(); // отрисовать
- }
- }
-
- // 3-5 режим - цветомузыка
- if (this_mode == 2 || this_mode == 3 || this_mode == 4 || this_mode == 7 || this_mode == 8) {
- analyzeAudio();
- colorMusic[0] = 0;
- colorMusic[1] = 0;
- colorMusic[2] = 0;
- for (int i = 0 ; i < 32 ; i++) {
- if (fht_log_out[i] < SPEKTR_LOW_PASS) fht_log_out[i] = 0;
- }
- // низкие частоты, выборка со 2 по 5 тон (0 и 1 зашумленные!)
- for (byte i = 2; i < 6; i++) {
- if (fht_log_out[i] > colorMusic[0]) colorMusic[0] = fht_log_out[i];
- }
- // средние частоты, выборка с 6 по 10 тон
- for (byte i = 6; i < 11; i++) {
- if (fht_log_out[i] > colorMusic[1]) colorMusic[1] = fht_log_out[i];
- }
- // высокие частоты, выборка с 11 по 31 тон
- for (byte i = 11; i < 32; i++) {
- if (fht_log_out[i] > colorMusic[2]) colorMusic[2] = fht_log_out[i];
- }
- freq_max = 0;
- for (byte i = 0; i < 30; i++) {
- if (fht_log_out[i + 2] > freq_max) freq_max = fht_log_out[i + 2];
- if (freq_max < 5) freq_max = 5;
-
- if (freq_f[i] < fht_log_out[i + 2]) freq_f[i] = fht_log_out[i + 2];
- if (freq_f[i] > 0) freq_f[i] -= LIGHT_SMOOTH;
- else freq_f[i] = 0;
- }
- freq_max_f = freq_max * averK + freq_max_f * (1 - averK);
- for (byte i = 0; i < 3; i++) {
- colorMusic_aver[i] = colorMusic[i] * averK + colorMusic_aver[i] * (1 - averK); // общая фильтрация
- colorMusic_f[i] = colorMusic[i] * SMOOTH_FREQ + colorMusic_f[i] * (1 - SMOOTH_FREQ); // локальная
- if (colorMusic_f[i] > ((float)colorMusic_aver[i] * MAX_COEF_FREQ)) {
- thisBright[i] = 255;
- colorMusicFlash[i] = true;
- running_flag[i] = true;
- } else colorMusicFlash[i] = false;
- if (thisBright[i] >= 0) thisBright[i] -= SMOOTH_STEP;
- if (thisBright[i] < EMPTY_BRIGHT) {
- thisBright[i] = EMPTY_BRIGHT;
- running_flag[i] = false;
- }
- }
- animation();
- }
- if (this_mode == 5) {
- if ((long)millis() - strobe_timer > STROBE_PERIOD) {
- strobe_timer = millis();
- strobeUp_flag = true;
- strobeDwn_flag = false;
- }
- if ((long)millis() - strobe_timer > light_time) {
- strobeDwn_flag = true;
- }
- if (strobeUp_flag) { // если настало время пыхнуть
- if (strobe_bright < 255) // если яркость не максимальная
- strobe_bright += STROBE_SMOOTH; // увелчить
- if (strobe_bright > 255) { // если пробили макс. яркость
- strobe_bright = 255; // оставить максимум
- strobeUp_flag = false; // флаг опустить
- }
- }
-
- if (strobeDwn_flag) { // гаснем
- if (strobe_bright > 0) // если яркость не минимальная
- strobe_bright -= STROBE_SMOOTH; // уменьшить
- if (strobe_bright < 0) { // если пробили мин. яркость
- strobeDwn_flag = false;
- strobe_bright = 0; // оставить 0
- }
- }
- animation();
- }
- if (this_mode == 6) animation();
-
- if (irrecv.isIdle()) // если на ИК приёмник не приходит сигнал (без этого НЕ РАБОТАЕТ!)
- FastLED.show(); // отправить значения на ленту
-
- if (this_mode != 7) // 7 режиму не нужна очистка!!!
- FastLED.clear(); // очистить массив пикселей
- main_timer = millis(); // сбросить таймер
- }
- }
-}
-
-void animation() {
- // согласно режиму
- switch (this_mode) {
- case 0:
- count = 0;
- for (int i = (MAX_CH - 1); i > ((MAX_CH - 1) - Rlenght); i--) {
- leds[i] = ColorFromPalette(myPal, (count * index)); // заливка по палитре " от зелёного к красному"
- count++;
- }
- count = 0;
- for (int i = (MAX_CH); i < (MAX_CH + Llenght); i++ ) {
- leds[i] = ColorFromPalette(myPal, (count * index)); // заливка по палитре " от зелёного к красному"
- count++;
- }
- if (EMPTY_BRIGHT > 0) {
- for (int i = ((MAX_CH - 1) - Rlenght); i > 0; i--)
- leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- for (int i = MAX_CH + Llenght; i < NUM_LEDS; i++)
- leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- }
- break;
- case 1:
- if (millis() - rainbow_timer > 30) {
- rainbow_timer = millis();
- hue = floor((float)hue + RAINBOW_STEP);
- }
- count = 0;
- for (int i = (MAX_CH - 1); i > ((MAX_CH - 1) - Rlenght); i--) {
- leds[i] = ColorFromPalette(RainbowColors_p, (count * index) / 2 - hue); // заливка по палитре радуга
- count++;
- }
- count = 0;
- for (int i = (MAX_CH); i < (MAX_CH + Llenght); i++ ) {
- leds[i] = ColorFromPalette(RainbowColors_p, (count * index) / 2 - hue); // заливка по палитре радуга
- count++;
- }
- if (EMPTY_BRIGHT > 0) {
- for (int i = ((MAX_CH - 1) - Rlenght); i > 0; i--)
- leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- for (int i = MAX_CH + Llenght; i < NUM_LEDS; i++)
- leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- }
- break;
- case 2:
- for (int i = 0; i < NUM_LEDS; i++) {
- if (i < STRIPE) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (i < STRIPE * 2) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < STRIPE * 3) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else if (i < STRIPE * 4) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < STRIPE * 5) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- }
- break;
- case 3:
- for (int i = 0; i < NUM_LEDS; i++) {
- if (i < NUM_LEDS / 3) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (i < NUM_LEDS * 2 / 3) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < NUM_LEDS) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
- }
- break;
- case 4:
- switch (freq_strobe_mode) {
- case 0:
- if (colorMusicFlash[2]) HIGHS();
- else if (colorMusicFlash[1]) MIDS();
- else if (colorMusicFlash[0]) LOWS();
- else SILENCE();
- break;
- case 1:
- if (colorMusicFlash[2]) HIGHS();
- else SILENCE();
- break;
- case 2:
- if (colorMusicFlash[1]) MIDS();
- else SILENCE();
- break;
- case 3:
- if (colorMusicFlash[0]) LOWS();
- else SILENCE();
- break;
- }
- break;
- case 5:
- if (strobe_bright > 0)
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(STROBE_COLOR, STROBE_SAT, strobe_bright);
- else
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 6:
- switch (light_mode) {
- case 0: for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(LIGHT_COLOR, LIGHT_SAT, 255);
- break;
- case 1:
- if (millis() - color_timer > COLOR_SPEED) {
- color_timer = millis();
- if (++this_color > 255) this_color = 0;
- }
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(this_color, LIGHT_SAT, 255);
- break;
- case 2:
- if (millis() - rainbow_timer > 30) {
- rainbow_timer = millis();
- this_color += RAINBOW_PERIOD;
- if (this_color > 255) this_color = 0;
- if (this_color < 0) this_color = 255;
- }
- rainbow_steps = this_color;
- for (int i = 0; i < NUM_LEDS; i++) {
- leds[i] = CHSV((int)floor(rainbow_steps), 255, 255);
- rainbow_steps += RAINBOW_STEP_2;
- if (rainbow_steps > 255) rainbow_steps = 0;
- if (rainbow_steps < 0) rainbow_steps = 255;
- }
- break;
- }
- break;
- case 7:
- switch (freq_strobe_mode) {
- case 0:
- if (running_flag[2]) leds[NUM_LEDS / 2] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (running_flag[1]) leds[NUM_LEDS / 2] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (running_flag[0]) leds[NUM_LEDS / 2] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 1:
- if (running_flag[2]) leds[NUM_LEDS / 2] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 2:
- if (running_flag[1]) leds[NUM_LEDS / 2] = CHSV(MID_COLOR, 255, thisBright[1]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 3:
- if (running_flag[0]) leds[NUM_LEDS / 2] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- }
- leds[(NUM_LEDS / 2) - 1] = leds[NUM_LEDS / 2];
- if (millis() - running_timer > RUNNING_SPEED) {
- running_timer = millis();
- for (byte i = 0; i < NUM_LEDS / 2 - 1; i++) {
- leds[i] = leds[i + 1];
- leds[NUM_LEDS - i - 1] = leds[i];
- }
- }
- break;
- case 8:
- byte HUEindex = HUE_START;
- for (byte i = 0; i < NUM_LEDS / 2; i++) {
- byte this_bright = map(freq_f[(int)floor((NUM_LEDS / 2 - i) / freq_to_stripe)], 0, freq_max_f, 0, 255);
- this_bright = constrain(this_bright, 0, 255);
- leds[i] = CHSV(HUEindex, 255, this_bright);
- leds[NUM_LEDS - i - 1] = leds[i];
- HUEindex += HUE_STEP;
- if (HUEindex > 255) HUEindex = 0;
- }
- break;
- }
-}
-
-void HIGHS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
-}
-void MIDS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
-}
-void LOWS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
-}
-void SILENCE() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
-}
-
-// вспомогательная функция, изменяет величину value на шаг incr в пределах minimum.. maximum
-int smartIncr(int value, int incr_step, int mininmum, int maximum) {
- int val_buf = value + incr_step;
- val_buf = constrain(val_buf, mininmum, maximum);
- return val_buf;
-}
-
-float smartIncrFloat(float value, float incr_step, float mininmum, float maximum) {
- float val_buf = value + incr_step;
- val_buf = constrain(val_buf, mininmum, maximum);
- return val_buf;
-}
-
-void remoteTick() {
- if (ir_flag) { // если данные пришли
- eeprom_timer = millis();
- eeprom_flag = true;
- switch (results.value) {
- // режимы
- case BUTT_1: this_mode = 0;
- break;
- case BUTT_2: this_mode = 1;
- break;
- case BUTT_3: this_mode = 2;
- break;
- case BUTT_4: this_mode = 3;
- break;
- case BUTT_5: this_mode = 4;
- break;
- case BUTT_6: this_mode = 5;
- break;
- case BUTT_7: this_mode = 6;
- break;
- case BUTT_8: this_mode = 7;
- break;
- case BUTT_9: this_mode = 8;
- break;
- case BUTT_0: fullLowPass();
- break;
- case BUTT_STAR: ONstate = !ONstate; FastLED.clear(); FastLED.show(); updateEEPROM();
- break;
- case BUTT_HASH:
- switch (this_mode) {
- case 4:
- case 7: if (++freq_strobe_mode > 3) freq_strobe_mode = 0;
- break;
- case 6: if (++light_mode > 2) light_mode = 0;
- break;
- }
- break;
- case BUTT_OK: settings_mode = !settings_mode; digitalWrite(13, settings_mode);
- break;
- case BUTT_UP:
- if (settings_mode) {
- // ВВЕРХ общие настройки
- EMPTY_BRIGHT = smartIncr(EMPTY_BRIGHT, 5, 0, 255);
- } else {
- switch (this_mode) {
- case 0:
- break;
- case 1: RAINBOW_STEP = smartIncrFloat(RAINBOW_STEP, 0.5, 0.5, 20);
- break;
- case 2:
- case 3:
- case 4: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, 0.1, 0, 5);
- break;
- case 5: STROBE_PERIOD = smartIncr(STROBE_PERIOD, 20, 1, 1000);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_SAT = smartIncr(LIGHT_SAT, 20, 0, 255);
- break;
- case 1: LIGHT_SAT = smartIncr(LIGHT_SAT, 20, 0, 255);
- break;
- case 2: RAINBOW_STEP_2 = smartIncrFloat(RAINBOW_STEP_2, 0.5, 0.5, 10);
- break;
- }
- break;
- case 7: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, 0.1, 0.0, 10);
- break;
- case 8: HUE_START = smartIncr(HUE_START, 10, 0, 255);
- break;
- }
- }
- break;
- case BUTT_DOWN:
- if (settings_mode) {
- // ВНИЗ общие настройки
- EMPTY_BRIGHT = smartIncr(EMPTY_BRIGHT, -5, 0, 255);
- } else {
- switch (this_mode) {
- case 0:
- break;
- case 1: RAINBOW_STEP = smartIncrFloat(RAINBOW_STEP, -0.5, 0.5, 20);
- break;
- case 2:
- case 3:
- case 4: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, -0.1, 0, 5);
- break;
- case 5: STROBE_PERIOD = smartIncr(STROBE_PERIOD, -20, 1, 1000);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_SAT = smartIncr(LIGHT_SAT, -20, 0, 255);
- break;
- case 1: LIGHT_SAT = smartIncr(LIGHT_SAT, -20, 0, 255);
- break;
- case 2: RAINBOW_STEP_2 = smartIncrFloat(RAINBOW_STEP_2, -0.5, 0.5, 10);
- break;
- }
- break;
- case 7: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, -0.1, 0.0, 10);
- break;
- case 8: HUE_START = smartIncr(HUE_START, -10, 0, 255);
- break;
- }
- }
- break;
- case BUTT_LEFT:
- if (settings_mode) {
- // ВЛЕВО общие настройки
- BRIGHTNESS = smartIncr(BRIGHTNESS, -20, 0, 255);
- FastLED.setBrightness(BRIGHTNESS);
- } else {
- switch (this_mode) {
- case 0:
- case 1: SMOOTH = smartIncrFloat(SMOOTH, -0.05, 0.05, 1);
- break;
- case 2:
- case 3:
- case 4: SMOOTH_FREQ = smartIncrFloat(SMOOTH_FREQ, -0.05, 0.05, 1);
- break;
- case 5: STROBE_SMOOTH = smartIncr(STROBE_SMOOTH, -20, 0, 255);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_COLOR = smartIncr(LIGHT_COLOR, -10, 0, 255);
- break;
- case 1: COLOR_SPEED = smartIncr(COLOR_SPEED, -10, 0, 255);
- break;
- case 2: RAINBOW_PERIOD = smartIncr(RAINBOW_PERIOD, -1, -20, 20);
- break;
- }
- break;
- case 7: RUNNING_SPEED = smartIncr(RUNNING_SPEED, -10, 1, 255);
- break;
- case 8: HUE_STEP = smartIncr(HUE_STEP, -1, 1, 255);
- break;
- }
- }
- break;
- case BUTT_RIGHT:
- if (settings_mode) {
- // ВПРАВО общие настройки
- BRIGHTNESS = smartIncr(BRIGHTNESS, 20, 0, 255);
- FastLED.setBrightness(BRIGHTNESS);
- } else {
- switch (this_mode) {
- case 0:
- case 1: SMOOTH = smartIncrFloat(SMOOTH, 0.05, 0.05, 1);
- break;
- case 2:
- case 3:
- case 4: SMOOTH_FREQ = smartIncrFloat(SMOOTH_FREQ, 0.05, 0.05, 1);
- break;
- case 5: STROBE_SMOOTH = smartIncr(STROBE_SMOOTH, 20, 0, 255);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_COLOR = smartIncr(LIGHT_COLOR, 10, 0, 255);
- break;
- case 1: COLOR_SPEED = smartIncr(COLOR_SPEED, 10, 0, 255);
- break;
- case 2: RAINBOW_PERIOD = smartIncr(RAINBOW_PERIOD, 1, -20, 20);
- break;
- }
- break;
- case 7: RUNNING_SPEED = smartIncr(RUNNING_SPEED, 10, 1, 255);
- break;
- case 8: HUE_STEP = smartIncr(HUE_STEP, 1, 1, 255);
- break;
- }
- }
- break;
- default: eeprom_flag = false; // если не распознали кнопку, не обновляем настройки!
- break;
- }
- ir_flag = false;
- }
-}
-
-void checkIR() {
- while (irrecv.decode(&results)) {
- ir_flag = true;
- irrecv.resume();
- }
-}
-
-void autoLowPass() {
- // для режима VU
- delay(10); // ждём инициализации АЦП
- int thisMax = 0; // максимум
- int thisLevel;
- for (byte i = 0; i < 200; i++) {
- thisLevel = analogRead(SOUND_R); // делаем 200 измерений
- if (thisLevel > thisMax) // ищем максимумы
- thisMax = thisLevel; // запоминаем
- delay(4); // ждём 4мс
- }
- LOW_PASS = thisMax + LOW_PASS_ADD; // нижний порог как максимум тишины + некая величина
-
- // для режима спектра
- thisMax = 0;
- for (byte i = 0; i < 100; i++) { // делаем 100 измерений
- analyzeAudio(); // разбить в спектр
- for (byte j = 2; j < 32; j++) { // первые 2 канала - хлам
- thisLevel = fht_log_out[j];
- if (thisLevel > thisMax) // ищем максимумы
- thisMax = thisLevel; // запоминаем
- }
- delay(4); // ждём 4мс
- }
- SPEKTR_LOW_PASS = thisMax + LOW_PASS_FREQ_ADD; // нижний порог как максимум тишины
-
- if (EEPROM_LOW_PASS && !AUTO_LOW_PASS) {
- EEPROM.updateInt(70, LOW_PASS);
- EEPROM.updateInt(72, SPEKTR_LOW_PASS);
- }
-}
-
-void analyzeAudio() {
- for (int i = 0 ; i < FHT_N ; i++) {
- int sample = analogRead(SOUND_R_FREQ);
- fht_input[i] = sample; // put real data into bins
- }
- fht_window(); // window the data for better frequency response
- fht_reorder(); // reorder the data before doing the fht
- fht_run(); // process the data in the fht
- fht_mag_log(); // take the output of the fht
-}
-
-void buttonTick() {
- butt1.tick(); // обязательная функция отработки. Должна постоянно опрашиваться
- if (butt1.isSingle()) // если единичное нажатие
- if (++this_mode >= MODE_AMOUNT) this_mode = 0; // изменить режим
-
- if (butt1.isHolded()) { // кнопка удержана
- fullLowPass();
- }
-}
-void fullLowPass() {
- digitalWrite(13, HIGH); // включить светодиод 13 пин
- FastLED.setBrightness(0); // погасить ленту
- FastLED.clear(); // очистить массив пикселей
- FastLED.show(); // отправить значения на ленту
- delay(500); // подождать чутка
- autoLowPass(); // измерить шумы
- delay(500); // подождать
- FastLED.setBrightness(BRIGHTNESS); // вернуть яркость
- digitalWrite(13, LOW); // выключить светодиод
-}
-void updateEEPROM() {
- EEPROM.updateByte(1, this_mode);
- EEPROM.updateByte(2, freq_strobe_mode);
- EEPROM.updateByte(3, light_mode);
- EEPROM.updateInt(4, RAINBOW_STEP);
- EEPROM.updateFloat(8, MAX_COEF_FREQ);
- EEPROM.updateInt(12, STROBE_PERIOD);
- EEPROM.updateInt(16, LIGHT_SAT);
- EEPROM.updateFloat(20, RAINBOW_STEP_2);
- EEPROM.updateInt(24, HUE_START);
- EEPROM.updateFloat(28, SMOOTH);
- EEPROM.updateFloat(32, SMOOTH_FREQ);
- EEPROM.updateInt(36, STROBE_SMOOTH);
- EEPROM.updateInt(40, LIGHT_COLOR);
- EEPROM.updateInt(44, COLOR_SPEED);
- EEPROM.updateInt(48, RAINBOW_PERIOD);
- EEPROM.updateInt(52, RUNNING_SPEED);
- EEPROM.updateInt(56, HUE_STEP);
- EEPROM.updateInt(60, EMPTY_BRIGHT);
-}
-void readEEPROM() {
- this_mode = EEPROM.readByte(1);
- freq_strobe_mode = EEPROM.readByte(2);
- light_mode = EEPROM.readByte(3);
- RAINBOW_STEP = EEPROM.readInt(4);
- MAX_COEF_FREQ = EEPROM.readFloat(8);
- STROBE_PERIOD = EEPROM.readInt(12);
- LIGHT_SAT = EEPROM.readInt(16);
- RAINBOW_STEP_2 = EEPROM.readFloat(20);
- HUE_START = EEPROM.readInt(24);
- SMOOTH = EEPROM.readFloat(28);
- SMOOTH_FREQ = EEPROM.readFloat(32);
- STROBE_SMOOTH = EEPROM.readInt(36);
- LIGHT_COLOR = EEPROM.readInt(40);
- COLOR_SPEED = EEPROM.readInt(44);
- RAINBOW_PERIOD = EEPROM.readInt(48);
- RUNNING_SPEED = EEPROM.readInt(52);
- HUE_STEP = EEPROM.readInt(56);
- EMPTY_BRIGHT = EEPROM.readInt(60);
-}
-void eepromTick() {
- if (eeprom_flag)
- if (millis() - eeprom_timer > 30000) { // 30 секунд после последнего нажатия с пульта
- eeprom_flag = false;
- eeprom_timer = millis();
- updateEEPROM();
- }
-}
diff --git a/firmware/Old versions/colorMusic_v2.3_WAVGAT/colorMusic_v2.3_WAVGAT.ino b/firmware/Old versions/colorMusic_v2.3_WAVGAT/colorMusic_v2.3_WAVGAT.ino
deleted file mode 100644
index 0c1f7f4..0000000
--- a/firmware/Old versions/colorMusic_v2.3_WAVGAT/colorMusic_v2.3_WAVGAT.ino
+++ /dev/null
@@ -1,947 +0,0 @@
-/*
- Крутейшая свето-цветомузыка на Arduino и адресной светодиодной ленте WS2812b.
- Данная версия поддерживает до 350 светодиодов!!!
- Управление:
- - Однократное нажатие кнопки: смена режима
- - Удержание кнопки: калибровка нижнего порога шума
- Режимы работы (переключаются кнопкой):
- - VU meter (столбик громкости): от зелёного к красному
- - VU meter (столбик громкости): плавно бегущая радуга
- - Светомузыка по частотам: 5 полос симметрично
- - Светомузыка по частотам: 3 полосы
- - Светомузыка по частотам: 1 полоса
- - Стробоскоп
- - (2.0) Подсветка
- - (2.0) Бегущие частоты
- - (2.1) анализатор спектра
- Особенности:
- - Плавная анимация (можно настроить)
- - Автонастройка по громкости (можно настроить)
- - Фильтр нижнего шума (можно настроить)
- - Автокалибровка шума при запуске (можно настроить)
- - Поддержка стерео и моно звука (можно настроить)
- - (2.0) в режиме частот лента не гаснет полностью (EMPTY_BRIGHT)
- - (2.1) все настройки сохраняются в памяти и не сбрасываются при перезагрузке
- - Сохранение настроек происходит при выключении кнопкой звёздочка (*)
- - А также через 30 секунд после последнего нажатия на любую кнопку ИК пульта
-
- НАСТРОЙКА НИЖНЕГО ПОРОГА ШУМА (строки 65-71)
- - Включаем систему
- - Ставим музыку на паузу
- - Удерживаем кнопку 1 секунду ИЛИ жмём кнопку 0 на пульте
- Значения шумов будут записаны в память и САМИ загружаться при последующем запуске! Всё!
-
- Пульт:
- - Цифры (1 - 9) активируют режимы
- - Цифра 0: калибровка шума
- - Звёздочка (*): включить/выключить систему
- - Кнопка ОК: переключение между локальными и глобальными настройками)
- - Решётка (#): смена подрежима
- - Глобальные настройки (горит светодиод на плате):
- + Стрелки ← →: общая яркость горящих светодиодов
- + Стрелки ↑ ↓: яркость "не горящих" светодиодов
- - Локальные настройки (у каждого режима свои):
- 1 - Шкала громкости (градиент)
- Стрелки ← →: плавность анимации
- 2 - Шкала громкости (радуга)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: скорость радуги
- 3 - Цветомузыка (5 полос)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- 4 - Цветомузыка (3 полосы)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- 5 - Цветомузыка (1 полоса)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- Подрежимы #: 3 частоты / низкие / средние / высокие
- 6 - Стробоскоп
- Стрелки ← →: плавность вспышек
- Стрелки ↑ ↓: частота вспышек
- 7 - Цветная подсветка
- Подрежимы #:
- Постоянный: стрелки ← →: цвет, стрелки ↑ ↓: насыщенность
- Плавная смена: стрелки ← →: скорость, стрелки ↑ ↓: насыщенность
- Бегущая радуга: стрелки ← →: скорость, стрелки ↑ ↓: шаг радуги
- 8 - “Бегущие частоты”
- Стрелки ← →: скорость
- Стрелки ↑ ↓: чувствительность
- Подрежимы #: 3 частоты / низкие / средние / высокие
- 9 - Анализатор спектра
- Стрелки ← →: шаг цвета
- Стрелки ↑ ↓: цвет
- **************************************************
- Разработано: AlexGyver
- Страница проекта: http://alexgyver.ru/colormusic/
- GitHub: https://github.com/AlexGyver/ColorMusic
-*/
-
-// --------------------------- НАСТРОЙКИ ---------------------------
-#define KEEP_SETTINGS 1 // хранить ВСЕ натсройки в памяти
-// лента
-#define NUM_LEDS 120 // количество светодиодов
-byte BRIGHTNESS = 200; // яркость (0 - 255)
-
-// пины
-#define SOUND_R A2 // аналоговый пин вход аудио, правый канал
-#define SOUND_L A1 // аналоговый пин вход аудио, левый канал
-#define SOUND_R_FREQ A3 // аналоговый пин вход аудио для режима с частотами (через кондер)
-#define BTN_PIN 3 // кнопка переключения режимов (PIN --- КНОПКА --- GND)
-#define LED_PIN 12 // пин DI светодиодной ленты
-#define POT_GND A0 // пин земля для потенциометра
-#define IR_PIN 2 // ИК приёмник
-
-// настройки радуги
-float RAINBOW_STEP = 5.5; // шаг изменения цвета радуги
-
-// отрисовка
-#define MODE 0 // режим при запуске
-#define MAIN_LOOP 5 // период основного цикла отрисовки (по умолчанию 5)
-
-// сигнал
-#define MONO 1 // 1 - только один канал (ПРАВЫЙ!!!!! SOUND_R!!!!!), 0 - два канала
-#define EXP 1.4 // степень усиления сигнала (для более "резкой" работы) (по умолчанию 1.4)
-#define POTENT 1 // 1 - используем потенциометр, 0 - используется внутренний источник опорного напряжения 1.1 В
-byte EMPTY_BRIGHT = 30; // яркость "не горящих" светодиодов (0 - 255)
-#define EMPTY_COLOR HUE_PURPLE // цвет "не горящих" светодиодов. Будет чёрный, если яркость 0
-
-// нижний порог шумов
-byte LOW_PASS = 100; // нижний порог шумов режим VU, ручная настройка
-byte SPEKTR_LOW_PASS = 40; // нижний порог шумов режим спектра, ручная настройка
-#define AUTO_LOW_PASS 0 // разрешить настройку нижнего порога шумов при запуске (по умолч. 0)
-#define EEPROM_LOW_PASS 1 // порог шумов хранится в энергонезависимой памяти (по умолч. 1)
-#define LOW_PASS_ADD 13 // "добавочная" величина к нижнему порогу, для надёжности (режим VU)
-#define LOW_PASS_FREQ_ADD 3 // "добавочная" величина к нижнему порогу, для надёжности (режим частот)
-
-// шкала громкости
-float SMOOTH = 0.5; // коэффициент плавности анимации VU (по умолчанию 0.5)
-#define MAX_COEF 1.8 // коэффициент громкости (максимальное равно срднему * этот коэф) (по умолчанию 1.8)
-
-// режим цветомузыки
-float SMOOTH_FREQ = 0.8; // коэффициент плавности анимации частот (по умолчанию 0.8)
-float MAX_COEF_FREQ = 1.2; // коэффициент порога для "вспышки" цветомузыки (по умолчанию 1.5)
-#define SMOOTH_STEP 20 // шаг уменьшения яркости в режиме цветомузыки (чем больше, тем быстрее гаснет)
-#define LOW_COLOR HUE_RED // цвет низких частот
-#define MID_COLOR HUE_GREEN // цвет средних
-#define HIGH_COLOR HUE_YELLOW // цвет высоких
-
-// режим стробоскопа
-int STROBE_PERIOD = 100; // период вспышек, миллисекунды
-#define STROBE_DUTY 20 // скважность вспышек (1 - 99) - отношение времени вспышки ко времени темноты
-#define STROBE_COLOR HUE_YELLOW // цвет стробоскопа
-#define STROBE_SAT 0 // насыщенность. Если 0 - цвет будет БЕЛЫЙ при любом цвете (0 - 255)
-byte STROBE_SMOOTH = 100; // скорость нарастания/угасания вспышки (0 - 255)
-
-// режим подсветки
-byte LIGHT_COLOR = 0; // начальный цвет подсветки
-byte LIGHT_SAT = 200; // начальная насыщенность подсветки
-byte COLOR_SPEED = 100;
-int RAINBOW_PERIOD = 3;
-float RAINBOW_STEP_2 = 5.5;
-
-// режим бегущих частот
-byte RUNNING_SPEED = 60;
-
-// режим анализатора спектра
-byte HUE_START = 0;
-byte HUE_STEP = 5;
-#define LIGHT_SMOOTH 2
-
-/*
- Цвета для HSV
- HUE_RED
- HUE_ORANGE
- HUE_YELLOW
- HUE_GREEN
- HUE_AQUA
- HUE_BLUE
- HUE_PURPLE
- HUE_PINK
-*/
-// --------------------------- НАСТРОЙКИ ---------------------------
-
-// —-— КНОПКИ ПУЛЬТА —-—
-#define BUTT_UP 0xFF18E7
-#define BUTT_DOWN 0xFF4AB5
-#define BUTT_LEFT 0xFF10EF
-#define BUTT_RIGHT 0xFF5AA5
-#define BUTT_OK 0xFF38C7
-#define BUTT_1 0xFFA25D
-#define BUTT_2 0xFF629D
-#define BUTT_3 0xFFE21D
-#define BUTT_4 0xFF22DD
-#define BUTT_5 0xFF02FD
-#define BUTT_6 0xFFC23D
-#define BUTT_7 0xFFE01F
-#define BUTT_8 0xFFA857
-#define BUTT_9 0xFF906F
-#define BUTT_0 0xFF9867
-#define BUTT_STAR 0xFF6897
-#define BUTT_HASH 0xFFB04F
-// —-— КНОПКИ ПУЛЬТА —---
-
-// ------------------------------ ДЛЯ РАЗРАБОТЧИКОВ --------------------------------
-#define MODE_AMOUNT 9 // количество режимов
-
-// цвета (устаревшие)
-#define BLUE 0x0000FF
-#define RED 0xFF0000
-#define GREEN 0x00ff00
-#define CYAN 0x00FFFF
-#define MAGENTA 0xFF00FF
-#define YELLOW 0xFFFF00
-#define WHITE 0xFFFFFF
-#define BLACK 0x000000
-
-#define STRIPE NUM_LEDS / 5
-float freq_to_stripe = NUM_LEDS / 40; // /2 так как симметрия, и /20 так как 20 частот
-
-#define FHT_N 64 // ширина спектра х2
-#define LOG_OUT 1
-#include // преобразование Хартли
-
-#include
-
-#define FASTLED_ALLOW_INTERRUPTS 1
-#include "FastLED.h"
-CRGB leds[NUM_LEDS];
-
-#include "GyverButton.h"
-GButton butt1(BTN_PIN);
-
-#include "IRremote.h"
-IRrecv irrecv(IR_PIN);
-decode_results results;
-
-// градиент-палитра от зелёного к красному
-DEFINE_GRADIENT_PALETTE(soundlevel_gp) {
- 0, 0, 255, 0, // green
- 100, 255, 255, 0, // yellow
- 150, 255, 100, 0, // orange
- 200, 255, 50, 0, // red
- 255, 255, 0, 0 // red
-};
-CRGBPalette32 myPal = soundlevel_gp;
-
-byte Rlenght, Llenght;
-float RsoundLevel, RsoundLevel_f;
-float LsoundLevel, LsoundLevel_f;
-
-float averageLevel = 50;
-int maxLevel = 100;
-byte MAX_CH = NUM_LEDS / 2;
-int hue;
-unsigned long main_timer, hue_timer, strobe_timer, running_timer, color_timer, rainbow_timer, eeprom_timer;
-float averK = 0.006;
-byte count;
-float index = (float)255 / MAX_CH; // коэффициент перевода для палитры
-boolean lowFlag;
-byte low_pass;
-int RcurrentLevel, LcurrentLevel;
-int colorMusic[3];
-float colorMusic_f[3], colorMusic_aver[3];
-boolean colorMusicFlash[3], strobeUp_flag, strobeDwn_flag;
-byte this_mode = MODE;
-int thisBright[3], strobe_bright = 0;
-unsigned int light_time = STROBE_PERIOD * STROBE_DUTY / 100;
-volatile boolean ir_flag;
-boolean settings_mode, ONstate = true;
-int8_t freq_strobe_mode, light_mode;
-int freq_max;
-float freq_max_f, rainbow_steps;
-int freq_f[32];
-int this_color;
-boolean running_flag[3], eeprom_flag;
-
-#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
-#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
-// ------------------------------ ДЛЯ РАЗРАБОТЧИКОВ --------------------------------
-
-void setup() {
- Serial.begin(9600);
- FastLED.addLeds(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
- FastLED.setBrightness(BRIGHTNESS);
-
- pinMode(13, OUTPUT);
- digitalWrite(13, LOW);
-
- pinMode(POT_GND, OUTPUT);
- digitalWrite(POT_GND, LOW);
- butt1.setTimeout(900);
-
- irrecv.enableIRIn(); // запускаем прием
- attachInterrupt(0, checkIR, RISING);
-
- // для увеличения точности уменьшаем опорное напряжение,
- // выставив EXTERNAL и подключив Aref к выходу 3.3V на плате через делитель
- // GND ---[10-20 кОм] --- REF --- [10 кОм] --- 3V3
- // в данной схеме GND берётся из А0 для удобства подключения
- if (POTENT) analogReference(EXTERNAL);
- else analogReference(INTERNAL);
-
- // жуткая магия, меняем частоту оцифровки до 18 кГц
- // команды на ебучем ассемблере, даже не спрашивайте, как это работает
- sbi(ADCSRA, ADPS2);
- cbi(ADCSRA, ADPS1);
- sbi(ADCSRA, ADPS0);
-
- if (AUTO_LOW_PASS && !EEPROM_LOW_PASS) { // если разрешена автонастройка нижнего порога шумов
- autoLowPass();
- }
- if (EEPROM_LOW_PASS) { // восстановить значения шумов из памяти
- LOW_PASS = EEPROM.readInt(70);
- SPEKTR_LOW_PASS = EEPROM.readInt(72);
- }
-
- // в 100 ячейке хранится число 100. Если нет - значит это первый запуск системы
- if (KEEP_SETTINGS) {
- if (EEPROM.read(100) != 100) {
- //Serial.println(F("First start"));
- EEPROM.write(100, 100);
- updateEEPROM();
- } else {
- readEEPROM();
- }
- }
-}
-
-void loop() {
- buttonTick(); // опрос и обработка кнопки
- remoteTick(); // опрос ИК пульта
- mainLoop(); // главный цикл обработки и отрисовки
- eepromTick(); // проверка не пора ли сохранить настройки
-}
-
-void mainLoop() {
- // главный цикл отрисовки
- if (ONstate) {
- if (millis() - main_timer > MAIN_LOOP) {
- // сбрасываем значения
- RsoundLevel = 0;
- LsoundLevel = 0;
-
- // перваые два режима - громкость (VU meter)
- if (this_mode == 0 || this_mode == 1) {
- for (byte i = 0; i < 100; i ++) { // делаем 100 измерений
- RcurrentLevel = analogRead(SOUND_R); // с правого
- if (!MONO) LcurrentLevel = analogRead(SOUND_L); // и левого каналов
-
- if (RsoundLevel < RcurrentLevel) RsoundLevel = RcurrentLevel; // ищем максимальное
- if (!MONO) if (LsoundLevel < LcurrentLevel) LsoundLevel = LcurrentLevel; // ищем максимальное
- }
-
- // фильтруем по нижнему порогу шумов
- RsoundLevel = map(RsoundLevel, LOW_PASS, 1023, 0, 500);
- if (!MONO)LsoundLevel = map(LsoundLevel, LOW_PASS, 1023, 0, 500);
-
- // ограничиваем диапазон
- RsoundLevel = constrain(RsoundLevel, 0, 500);
- if (!MONO)LsoundLevel = constrain(LsoundLevel, 0, 500);
-
- // возводим в степень (для большей чёткости работы)
- RsoundLevel = pow(RsoundLevel, EXP);
- if (!MONO)LsoundLevel = pow(LsoundLevel, EXP);
-
- // фильтр
- RsoundLevel_f = RsoundLevel * SMOOTH + RsoundLevel_f * (1 - SMOOTH);
- if (!MONO)LsoundLevel_f = LsoundLevel * SMOOTH + LsoundLevel_f * (1 - SMOOTH);
-
- if (MONO) LsoundLevel_f = RsoundLevel_f; // если моно, то левый = правому
-
- // заливаем "подложку", если яркость достаточная
- if (EMPTY_BRIGHT > 5) {
- for (int i = 0; i < NUM_LEDS; i++)
- leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- }
-
- // если значение выше порога - начинаем самое интересное
- if (RsoundLevel_f > 15 && LsoundLevel_f > 15) {
-
- // расчёт общей средней громкости с обоих каналов, фильтрация.
- // Фильтр очень медленный, сделано специально для автогромкости
- averageLevel = (float)(RsoundLevel_f + LsoundLevel_f) / 2 * averK + averageLevel * (1 - averK);
-
- // принимаем максимальную громкость шкалы как среднюю, умноженную на некоторый коэффициент MAX_COEF
- maxLevel = (float)averageLevel * MAX_COEF;
-
- // преобразуем сигнал в длину ленты (где MAX_CH это половина количества светодиодов)
- Rlenght = map(RsoundLevel_f, 0, maxLevel, 0, MAX_CH);
- Llenght = map(LsoundLevel_f, 0, maxLevel, 0, MAX_CH);
-
- // ограничиваем до макс. числа светодиодов
- Rlenght = constrain(Rlenght, 0, MAX_CH);
- Llenght = constrain(Llenght, 0, MAX_CH);
-
- animation(); // отрисовать
- }
- }
-
- // 3-5 режим - цветомузыка
- if (this_mode == 2 || this_mode == 3 || this_mode == 4 || this_mode == 7 || this_mode == 8) {
- analyzeAudio();
- colorMusic[0] = 0;
- colorMusic[1] = 0;
- colorMusic[2] = 0;
- for (int i = 0 ; i < 32 ; i++) {
- if (fht_log_out[i] < SPEKTR_LOW_PASS) fht_log_out[i] = 0;
- }
- // низкие частоты, выборка со 2 по 5 тон (0 и 1 зашумленные!)
- for (byte i = 2; i < 6; i++) {
- if (fht_log_out[i] > colorMusic[0]) colorMusic[0] = fht_log_out[i];
- }
- // средние частоты, выборка с 6 по 10 тон
- for (byte i = 6; i < 11; i++) {
- if (fht_log_out[i] > colorMusic[1]) colorMusic[1] = fht_log_out[i];
- }
- // высокие частоты, выборка с 11 по 31 тон
- for (byte i = 11; i < 32; i++) {
- if (fht_log_out[i] > colorMusic[2]) colorMusic[2] = fht_log_out[i];
- }
- freq_max = 0;
- for (byte i = 0; i < 30; i++) {
- if (fht_log_out[i + 2] > freq_max) freq_max = fht_log_out[i + 2];
- if (freq_max < 5) freq_max = 5;
-
- if (freq_f[i] < fht_log_out[i + 2]) freq_f[i] = fht_log_out[i + 2];
- if (freq_f[i] > 0) freq_f[i] -= LIGHT_SMOOTH;
- else freq_f[i] = 0;
- }
- freq_max_f = freq_max * averK + freq_max_f * (1 - averK);
- for (byte i = 0; i < 3; i++) {
- colorMusic_aver[i] = colorMusic[i] * averK + colorMusic_aver[i] * (1 - averK); // общая фильтрация
- colorMusic_f[i] = colorMusic[i] * SMOOTH_FREQ + colorMusic_f[i] * (1 - SMOOTH_FREQ); // локальная
- if (colorMusic_f[i] > ((float)colorMusic_aver[i] * MAX_COEF_FREQ)) {
- thisBright[i] = 255;
- colorMusicFlash[i] = true;
- running_flag[i] = true;
- } else colorMusicFlash[i] = false;
- if (thisBright[i] >= 0) thisBright[i] -= SMOOTH_STEP;
- if (thisBright[i] < EMPTY_BRIGHT) {
- thisBright[i] = EMPTY_BRIGHT;
- running_flag[i] = false;
- }
- }
- animation();
- }
- if (this_mode == 5) {
- if ((long)millis() - strobe_timer > STROBE_PERIOD) {
- strobe_timer = millis();
- strobeUp_flag = true;
- strobeDwn_flag = false;
- }
- if ((long)millis() - strobe_timer > light_time) {
- strobeDwn_flag = true;
- }
- if (strobeUp_flag) { // если настало время пыхнуть
- if (strobe_bright < 255) // если яркость не максимальная
- strobe_bright += STROBE_SMOOTH; // увелчить
- if (strobe_bright > 255) { // если пробили макс. яркость
- strobe_bright = 255; // оставить максимум
- strobeUp_flag = false; // флаг опустить
- }
- }
-
- if (strobeDwn_flag) { // гаснем
- if (strobe_bright > 0) // если яркость не минимальная
- strobe_bright -= STROBE_SMOOTH; // уменьшить
- if (strobe_bright < 0) { // если пробили мин. яркость
- strobeDwn_flag = false;
- strobe_bright = 0; // оставить 0
- }
- }
- animation();
- }
- if (this_mode == 6) animation();
-
- if (irrecv.isIdle()) // если на ИК приёмник не приходит сигнал (без этого НЕ РАБОТАЕТ!)
- FastLED.show(); // отправить значения на ленту
-
- if (this_mode != 7) // 7 режиму не нужна очистка!!!
- FastLED.clear(); // очистить массив пикселей
- main_timer = millis(); // сбросить таймер
- }
- }
-}
-
-void animation() {
- // согласно режиму
- switch (this_mode) {
- case 0:
- count = 0;
- for (int i = (MAX_CH - 1); i > ((MAX_CH - 1) - Rlenght); i--) {
- leds[i] = ColorFromPalette(myPal, (count * index)); // заливка по палитре " от зелёного к красному"
- count++;
- }
- count = 0;
- for (int i = (MAX_CH); i < (MAX_CH + Llenght); i++ ) {
- leds[i] = ColorFromPalette(myPal, (count * index)); // заливка по палитре " от зелёного к красному"
- count++;
- }
- if (EMPTY_BRIGHT > 0) {
- for (int i = ((MAX_CH - 1) - Rlenght); i > 0; i--)
- leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- for (int i = MAX_CH + Llenght; i < NUM_LEDS; i++)
- leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- }
- break;
- case 1:
- if (millis() - rainbow_timer > 30) {
- rainbow_timer = millis();
- hue = floor((float)hue + RAINBOW_STEP);
- }
- count = 0;
- for (int i = (MAX_CH - 1); i > ((MAX_CH - 1) - Rlenght); i--) {
- leds[i] = ColorFromPalette(RainbowColors_p, (count * index) / 2 - hue); // заливка по палитре радуга
- count++;
- }
- count = 0;
- for (int i = (MAX_CH); i < (MAX_CH + Llenght); i++ ) {
- leds[i] = ColorFromPalette(RainbowColors_p, (count * index) / 2 - hue); // заливка по палитре радуга
- count++;
- }
- if (EMPTY_BRIGHT > 0) {
- for (int i = ((MAX_CH - 1) - Rlenght); i > 0; i--)
- leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- for (int i = MAX_CH + Llenght; i < NUM_LEDS; i++)
- leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- }
- break;
- case 2:
- for (int i = 0; i < NUM_LEDS; i++) {
- if (i < STRIPE) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (i < STRIPE * 2) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < STRIPE * 3) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else if (i < STRIPE * 4) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < STRIPE * 5) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- }
- break;
- case 3:
- for (int i = 0; i < NUM_LEDS; i++) {
- if (i < NUM_LEDS / 3) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (i < NUM_LEDS * 2 / 3) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < NUM_LEDS) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
- }
- break;
- case 4:
- switch (freq_strobe_mode) {
- case 0:
- if (colorMusicFlash[2]) HIGHS();
- else if (colorMusicFlash[1]) MIDS();
- else if (colorMusicFlash[0]) LOWS();
- else SILENCE();
- break;
- case 1:
- if (colorMusicFlash[2]) HIGHS();
- else SILENCE();
- break;
- case 2:
- if (colorMusicFlash[1]) MIDS();
- else SILENCE();
- break;
- case 3:
- if (colorMusicFlash[0]) LOWS();
- else SILENCE();
- break;
- }
- break;
- case 5:
- if (strobe_bright > 0)
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(STROBE_COLOR, STROBE_SAT, strobe_bright);
- else
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 6:
- switch (light_mode) {
- case 0: for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(LIGHT_COLOR, LIGHT_SAT, 255);
- break;
- case 1:
- if (millis() - color_timer > COLOR_SPEED) {
- color_timer = millis();
- if (++this_color > 255) this_color = 0;
- }
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(this_color, LIGHT_SAT, 255);
- break;
- case 2:
- if (millis() - rainbow_timer > 30) {
- rainbow_timer = millis();
- this_color += RAINBOW_PERIOD;
- if (this_color > 255) this_color = 0;
- if (this_color < 0) this_color = 255;
- }
- rainbow_steps = this_color;
- for (int i = 0; i < NUM_LEDS; i++) {
- leds[i] = CHSV((int)floor(rainbow_steps), 255, 255);
- rainbow_steps += RAINBOW_STEP_2;
- if (rainbow_steps > 255) rainbow_steps = 0;
- if (rainbow_steps < 0) rainbow_steps = 255;
- }
- break;
- }
- break;
- case 7:
- switch (freq_strobe_mode) {
- case 0:
- if (running_flag[2]) leds[NUM_LEDS / 2] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (running_flag[1]) leds[NUM_LEDS / 2] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (running_flag[0]) leds[NUM_LEDS / 2] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 1:
- if (running_flag[2]) leds[NUM_LEDS / 2] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 2:
- if (running_flag[1]) leds[NUM_LEDS / 2] = CHSV(MID_COLOR, 255, thisBright[1]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 3:
- if (running_flag[0]) leds[NUM_LEDS / 2] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- }
- leds[(NUM_LEDS / 2) - 1] = leds[NUM_LEDS / 2];
- if (millis() - running_timer > RUNNING_SPEED) {
- running_timer = millis();
- for (byte i = 0; i < NUM_LEDS / 2 - 1; i++) {
- leds[i] = leds[i + 1];
- leds[NUM_LEDS - i - 1] = leds[i];
- }
- }
- break;
- case 8:
- byte HUEindex = HUE_START;
- for (byte i = 0; i < NUM_LEDS / 2; i++) {
- byte this_bright = map(freq_f[(int)floor((NUM_LEDS / 2 - i) / freq_to_stripe)], 0, freq_max_f, 0, 255);
- this_bright = constrain(this_bright, 0, 255);
- leds[i] = CHSV(HUEindex, 255, this_bright);
- leds[NUM_LEDS - i - 1] = leds[i];
- HUEindex += HUE_STEP;
- if (HUEindex > 255) HUEindex = 0;
- }
- break;
- }
-}
-
-void HIGHS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
-}
-void MIDS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
-}
-void LOWS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
-}
-void SILENCE() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
-}
-
-// вспомогательная функция, изменяет величину value на шаг incr в пределах minimum.. maximum
-int smartIncr(int value, int incr_step, int mininmum, int maximum) {
- int val_buf = value + incr_step;
- val_buf = constrain(val_buf, mininmum, maximum);
- return val_buf;
-}
-
-float smartIncrFloat(float value, float incr_step, float mininmum, float maximum) {
- float val_buf = value + incr_step;
- val_buf = constrain(val_buf, mininmum, maximum);
- return val_buf;
-}
-
-void remoteTick() {
- if (ir_flag) { // если данные пришли
- eeprom_timer = millis();
- eeprom_flag = true;
- switch (results.value) {
- // режимы
- case BUTT_1: this_mode = 0;
- break;
- case BUTT_2: this_mode = 1;
- break;
- case BUTT_3: this_mode = 2;
- break;
- case BUTT_4: this_mode = 3;
- break;
- case BUTT_5: this_mode = 4;
- break;
- case BUTT_6: this_mode = 5;
- break;
- case BUTT_7: this_mode = 6;
- break;
- case BUTT_8: this_mode = 7;
- break;
- case BUTT_9: this_mode = 8;
- break;
- case BUTT_0: fullLowPass();
- break;
- case BUTT_STAR: ONstate = !ONstate; FastLED.clear(); FastLED.show(); updateEEPROM();
- break;
- case BUTT_HASH:
- switch (this_mode) {
- case 4:
- case 7: if (++freq_strobe_mode > 3) freq_strobe_mode = 0;
- break;
- case 6: if (++light_mode > 2) light_mode = 0;
- break;
- }
- break;
- case BUTT_OK: settings_mode = !settings_mode; digitalWrite(13, settings_mode);
- break;
- case BUTT_UP:
- if (settings_mode) {
- // ВВЕРХ общие настройки
- EMPTY_BRIGHT = smartIncr(EMPTY_BRIGHT, 5, 0, 255);
- } else {
- switch (this_mode) {
- case 0:
- break;
- case 1: RAINBOW_STEP = smartIncrFloat(RAINBOW_STEP, 0.5, 0.5, 20);
- break;
- case 2:
- case 3:
- case 4: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, 0.1, 0, 5);
- break;
- case 5: STROBE_PERIOD = smartIncr(STROBE_PERIOD, 20, 1, 1000);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_SAT = smartIncr(LIGHT_SAT, 20, 0, 255);
- break;
- case 1: LIGHT_SAT = smartIncr(LIGHT_SAT, 20, 0, 255);
- break;
- case 2: RAINBOW_STEP_2 = smartIncrFloat(RAINBOW_STEP_2, 0.5, 0.5, 10);
- break;
- }
- break;
- case 7: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, 0.1, 0.0, 10);
- break;
- case 8: HUE_START = smartIncr(HUE_START, 10, 0, 255);
- break;
- }
- }
- break;
- case BUTT_DOWN:
- if (settings_mode) {
- // ВНИЗ общие настройки
- EMPTY_BRIGHT = smartIncr(EMPTY_BRIGHT, -5, 0, 255);
- } else {
- switch (this_mode) {
- case 0:
- break;
- case 1: RAINBOW_STEP = smartIncrFloat(RAINBOW_STEP, -0.5, 0.5, 20);
- break;
- case 2:
- case 3:
- case 4: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, -0.1, 0, 5);
- break;
- case 5: STROBE_PERIOD = smartIncr(STROBE_PERIOD, -20, 1, 1000);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_SAT = smartIncr(LIGHT_SAT, -20, 0, 255);
- break;
- case 1: LIGHT_SAT = smartIncr(LIGHT_SAT, -20, 0, 255);
- break;
- case 2: RAINBOW_STEP_2 = smartIncrFloat(RAINBOW_STEP_2, -0.5, 0.5, 10);
- break;
- }
- break;
- case 7: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, -0.1, 0.0, 10);
- break;
- case 8: HUE_START = smartIncr(HUE_START, -10, 0, 255);
- break;
- }
- }
- break;
- case BUTT_LEFT:
- if (settings_mode) {
- // ВЛЕВО общие настройки
- BRIGHTNESS = smartIncr(BRIGHTNESS, -20, 0, 255);
- FastLED.setBrightness(BRIGHTNESS);
- } else {
- switch (this_mode) {
- case 0:
- case 1: SMOOTH = smartIncrFloat(SMOOTH, -0.05, 0.05, 1);
- break;
- case 2:
- case 3:
- case 4: SMOOTH_FREQ = smartIncrFloat(SMOOTH_FREQ, -0.05, 0.05, 1);
- break;
- case 5: STROBE_SMOOTH = smartIncr(STROBE_SMOOTH, -20, 0, 255);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_COLOR = smartIncr(LIGHT_COLOR, -10, 0, 255);
- break;
- case 1: COLOR_SPEED = smartIncr(COLOR_SPEED, -10, 0, 255);
- break;
- case 2: RAINBOW_PERIOD = smartIncr(RAINBOW_PERIOD, -1, -20, 20);
- break;
- }
- break;
- case 7: RUNNING_SPEED = smartIncr(RUNNING_SPEED, -10, 1, 255);
- break;
- case 8: HUE_STEP = smartIncr(HUE_STEP, -1, 1, 255);
- break;
- }
- }
- break;
- case BUTT_RIGHT:
- if (settings_mode) {
- // ВПРАВО общие настройки
- BRIGHTNESS = smartIncr(BRIGHTNESS, 20, 0, 255);
- FastLED.setBrightness(BRIGHTNESS);
- } else {
- switch (this_mode) {
- case 0:
- case 1: SMOOTH = smartIncrFloat(SMOOTH, 0.05, 0.05, 1);
- break;
- case 2:
- case 3:
- case 4: SMOOTH_FREQ = smartIncrFloat(SMOOTH_FREQ, 0.05, 0.05, 1);
- break;
- case 5: STROBE_SMOOTH = smartIncr(STROBE_SMOOTH, 20, 0, 255);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_COLOR = smartIncr(LIGHT_COLOR, 10, 0, 255);
- break;
- case 1: COLOR_SPEED = smartIncr(COLOR_SPEED, 10, 0, 255);
- break;
- case 2: RAINBOW_PERIOD = smartIncr(RAINBOW_PERIOD, 1, -20, 20);
- break;
- }
- break;
- case 7: RUNNING_SPEED = smartIncr(RUNNING_SPEED, 10, 1, 255);
- break;
- case 8: HUE_STEP = smartIncr(HUE_STEP, 1, 1, 255);
- break;
- }
- }
- break;
- default: eeprom_flag = false; // если не распознали кнопку, не обновляем настройки!
- break;
- }
- ir_flag = false;
- }
-}
-
-void checkIR() {
- while (irrecv.decode(&results)) {
- ir_flag = true;
- irrecv.resume();
- }
-}
-
-void autoLowPass() {
- // для режима VU
- delay(10); // ждём инициализации АЦП
- int thisMax = 0; // максимум
- int thisLevel;
- for (byte i = 0; i < 200; i++) {
- thisLevel = analogRead(SOUND_R); // делаем 200 измерений
- if (thisLevel > thisMax) // ищем максимумы
- thisMax = thisLevel; // запоминаем
- delay(4); // ждём 4мс
- }
- LOW_PASS = thisMax + LOW_PASS_ADD; // нижний порог как максимум тишины + некая величина
-
- // для режима спектра
- thisMax = 0;
- for (byte i = 0; i < 100; i++) { // делаем 100 измерений
- analyzeAudio(); // разбить в спектр
- for (byte j = 2; j < 32; j++) { // первые 2 канала - хлам
- thisLevel = fht_log_out[j];
- if (thisLevel > thisMax) // ищем максимумы
- thisMax = thisLevel; // запоминаем
- }
- delay(4); // ждём 4мс
- }
- SPEKTR_LOW_PASS = thisMax + LOW_PASS_FREQ_ADD; // нижний порог как максимум тишины
-
- if (EEPROM_LOW_PASS && !AUTO_LOW_PASS) {
- EEPROM.updateInt(70, LOW_PASS);
- EEPROM.updateInt(72, SPEKTR_LOW_PASS);
- }
-}
-
-void analyzeAudio() {
- for (int i = 0 ; i < FHT_N ; i++) {
- int sample = analogRead(SOUND_R_FREQ);
- fht_input[i] = sample; // put real data into bins
- }
- fht_window(); // window the data for better frequency response
- fht_reorder(); // reorder the data before doing the fht
- fht_run(); // process the data in the fht
- fht_mag_log(); // take the output of the fht
-}
-
-void buttonTick() {
- butt1.tick(); // обязательная функция отработки. Должна постоянно опрашиваться
- if (butt1.isSingle()) // если единичное нажатие
- if (++this_mode >= MODE_AMOUNT) this_mode = 0; // изменить режим
-
- if (butt1.isHolded()) { // кнопка удержана
- fullLowPass();
- }
-}
-void fullLowPass() {
- digitalWrite(13, HIGH); // включить светодиод 13 пин
- FastLED.setBrightness(0); // погасить ленту
- FastLED.clear(); // очистить массив пикселей
- FastLED.show(); // отправить значения на ленту
- delay(500); // подождать чутка
- autoLowPass(); // измерить шумы
- delay(500); // подождать
- FastLED.setBrightness(BRIGHTNESS); // вернуть яркость
- digitalWrite(13, LOW); // выключить светодиод
-}
-void updateEEPROM() {
- EEPROM.updateByte(1, this_mode);
- EEPROM.updateByte(2, freq_strobe_mode);
- EEPROM.updateByte(3, light_mode);
- EEPROM.updateInt(4, RAINBOW_STEP);
- EEPROM.updateFloat(8, MAX_COEF_FREQ);
- EEPROM.updateInt(12, STROBE_PERIOD);
- EEPROM.updateInt(16, LIGHT_SAT);
- EEPROM.updateFloat(20, RAINBOW_STEP_2);
- EEPROM.updateInt(24, HUE_START);
- EEPROM.updateFloat(28, SMOOTH);
- EEPROM.updateFloat(32, SMOOTH_FREQ);
- EEPROM.updateInt(36, STROBE_SMOOTH);
- EEPROM.updateInt(40, LIGHT_COLOR);
- EEPROM.updateInt(44, COLOR_SPEED);
- EEPROM.updateInt(48, RAINBOW_PERIOD);
- EEPROM.updateInt(52, RUNNING_SPEED);
- EEPROM.updateInt(56, HUE_STEP);
- EEPROM.updateInt(60, EMPTY_BRIGHT);
-}
-void readEEPROM() {
- this_mode = EEPROM.readByte(1);
- freq_strobe_mode = EEPROM.readByte(2);
- light_mode = EEPROM.readByte(3);
- RAINBOW_STEP = EEPROM.readInt(4);
- MAX_COEF_FREQ = EEPROM.readFloat(8);
- STROBE_PERIOD = EEPROM.readInt(12);
- LIGHT_SAT = EEPROM.readInt(16);
- RAINBOW_STEP_2 = EEPROM.readFloat(20);
- HUE_START = EEPROM.readInt(24);
- SMOOTH = EEPROM.readFloat(28);
- SMOOTH_FREQ = EEPROM.readFloat(32);
- STROBE_SMOOTH = EEPROM.readInt(36);
- LIGHT_COLOR = EEPROM.readInt(40);
- COLOR_SPEED = EEPROM.readInt(44);
- RAINBOW_PERIOD = EEPROM.readInt(48);
- RUNNING_SPEED = EEPROM.readInt(52);
- HUE_STEP = EEPROM.readInt(56);
- EMPTY_BRIGHT = EEPROM.readInt(60);
-}
-void eepromTick() {
- if (eeprom_flag)
- if (millis() - eeprom_timer > 30000) { // 30 секунд после последнего нажатия с пульта
- eeprom_flag = false;
- eeprom_timer = millis();
- updateEEPROM();
- }
-}
diff --git a/firmware/Old versions/colorMusic_v2.4_KEYES/colorMusic_v2.4_KEYES.ino b/firmware/Old versions/colorMusic_v2.4_KEYES/colorMusic_v2.4_KEYES.ino
deleted file mode 100644
index 8552f39..0000000
--- a/firmware/Old versions/colorMusic_v2.4_KEYES/colorMusic_v2.4_KEYES.ino
+++ /dev/null
@@ -1,952 +0,0 @@
-/*
- Крутейшая свето-цветомузыка на Arduino и адресной светодиодной ленте WS2812b.
- Данная версия поддерживает до 350 светодиодов!!!
- Управление:
- - Однократное нажатие кнопки: смена режима
- - Удержание кнопки: калибровка нижнего порога шума
- Режимы работы (переключаются кнопкой):
- - VU meter (столбик громкости): от зелёного к красному
- - VU meter (столбик громкости): плавно бегущая радуга
- - Светомузыка по частотам: 5 полос симметрично
- - Светомузыка по частотам: 3 полосы
- - Светомузыка по частотам: 1 полоса
- - Стробоскоп
- - (2.0) Подсветка
- - (2.0) Бегущие частоты
- - (2.1) анализатор спектра
- Особенности:
- - Плавная анимация (можно настроить)
- - Автонастройка по громкости (можно настроить)
- - Фильтр нижнего шума (можно настроить)
- - Автокалибровка шума при запуске (можно настроить)
- - Поддержка стерео и моно звука (можно настроить)
- - (2.0) в режиме частот лента не гаснет полностью (EMPTY_BRIGHT)
- - (2.1) все настройки сохраняются в памяти и не сбрасываются при перезагрузке
- - Сохранение настроек происходит при выключении кнопкой звёздочка (*)
- - А также через 30 секунд после последнего нажатия на любую кнопку ИК пульта
-
- НАСТРОЙКА НИЖНЕГО ПОРОГА ШУМА (строки 65-71)
- - Включаем систему
- - Ставим музыку на паузу
- - Удерживаем кнопку 1 секунду ИЛИ жмём кнопку 0 на пульте
- Значения шумов будут записаны в память и САМИ загружаться при последующем запуске! Всё!
-
- Пульт:
- - Цифры (1 - 9) активируют режимы
- - Цифра 0: калибровка шума
- - Звёздочка (*): включить/выключить систему
- - Кнопка ОК: переключение между локальными и глобальными настройками)
- - Решётка (#): смена подрежима
- - Глобальные настройки (горит светодиод на плате):
- + Стрелки ← →: общая яркость горящих светодиодов
- + Стрелки ↑ ↓: яркость "не горящих" светодиодов
- - Локальные настройки (у каждого режима свои):
- 1 - Шкала громкости (градиент)
- Стрелки ← →: плавность анимации
- 2 - Шкала громкости (радуга)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: скорость радуги
- 3 - Цветомузыка (5 полос)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- 4 - Цветомузыка (3 полосы)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- 5 - Цветомузыка (1 полоса)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- Подрежимы #: 3 частоты / низкие / средние / высокие
- 6 - Стробоскоп
- Стрелки ← →: плавность вспышек
- Стрелки ↑ ↓: частота вспышек
- 7 - Цветная подсветка
- Подрежимы #:
- Постоянный: стрелки ← →: цвет, стрелки ↑ ↓: насыщенность
- Плавная смена: стрелки ← →: скорость, стрелки ↑ ↓: насыщенность
- Бегущая радуга: стрелки ← →: скорость, стрелки ↑ ↓: шаг радуги
- 8 - “Бегущие частоты”
- Стрелки ← →: скорость
- Стрелки ↑ ↓: чувствительность
- Подрежимы #: 3 частоты / низкие / средние / высокие
- 9 - Анализатор спектра
- Стрелки ← →: шаг цвета
- Стрелки ↑ ↓: цвет
- **************************************************
- Разработано: AlexGyver
- Страница проекта: http://alexgyver.ru/colormusic/
- GitHub: https://github.com/AlexGyver/ColorMusic
-*/
-
-// --------------------------- НАСТРОЙКИ ---------------------------
-#define KEEP_SETTINGS 1 // хранить ВСЕ настройки в памяти
-#define RESET_SETTINGS 0 // сброс настроек в памяти.
-// поставить 1. Прошиться. Поставить обратно 0. Прошиться. Всё.
-
-// лента
-#define NUM_LEDS 310 // количество светодиодов
-byte BRIGHTNESS = 200; // яркость (0 - 255)
-
-// пины
-#define SOUND_R A2 // аналоговый пин вход аудио, правый канал
-#define SOUND_L A1 // аналоговый пин вход аудио, левый канал
-#define SOUND_R_FREQ A3 // аналоговый пин вход аудио для режима с частотами (через кондер)
-#define BTN_PIN 3 // кнопка переключения режимов (PIN --- КНОПКА --- GND)
-#define LED_PIN 12 // пин DI светодиодной ленты
-#define POT_GND A0 // пин земля для потенциометра
-#define IR_PIN 2 // ИК приёмник
-
-// настройки радуги
-float RAINBOW_STEP = 5.5; // шаг изменения цвета радуги
-
-// отрисовка
-#define MODE 0 // режим при запуске
-#define MAIN_LOOP 5 // период основного цикла отрисовки (по умолчанию 5)
-
-// сигнал
-#define MONO 1 // 1 - только один канал (ПРАВЫЙ!!!!! SOUND_R!!!!!), 0 - два канала
-#define EXP 1.4 // степень усиления сигнала (для более "резкой" работы) (по умолчанию 1.4)
-#define POTENT 1 // 1 - используем потенциометр, 0 - используется внутренний источник опорного напряжения 1.1 В
-byte EMPTY_BRIGHT = 30; // яркость "не горящих" светодиодов (0 - 255)
-#define EMPTY_COLOR HUE_PURPLE // цвет "не горящих" светодиодов. Будет чёрный, если яркость 0
-
-// нижний порог шумов
-byte LOW_PASS = 100; // нижний порог шумов режим VU, ручная настройка
-byte SPEKTR_LOW_PASS = 40; // нижний порог шумов режим спектра, ручная настройка
-#define AUTO_LOW_PASS 0 // разрешить настройку нижнего порога шумов при запуске (по умолч. 0)
-#define EEPROM_LOW_PASS 1 // порог шумов хранится в энергонезависимой памяти (по умолч. 1)
-#define LOW_PASS_ADD 13 // "добавочная" величина к нижнему порогу, для надёжности (режим VU)
-#define LOW_PASS_FREQ_ADD 3 // "добавочная" величина к нижнему порогу, для надёжности (режим частот)
-
-// шкала громкости
-float SMOOTH = 0.5; // коэффициент плавности анимации VU (по умолчанию 0.5)
-#define MAX_COEF 1.8 // коэффициент громкости (максимальное равно срднему * этот коэф) (по умолчанию 1.8)
-
-// режим цветомузыки
-float SMOOTH_FREQ = 0.8; // коэффициент плавности анимации частот (по умолчанию 0.8)
-float MAX_COEF_FREQ = 1.2; // коэффициент порога для "вспышки" цветомузыки (по умолчанию 1.5)
-#define SMOOTH_STEP 20 // шаг уменьшения яркости в режиме цветомузыки (чем больше, тем быстрее гаснет)
-#define LOW_COLOR HUE_RED // цвет низких частот
-#define MID_COLOR HUE_GREEN // цвет средних
-#define HIGH_COLOR HUE_YELLOW // цвет высоких
-
-// режим стробоскопа
-int STROBE_PERIOD = 100; // период вспышек, миллисекунды
-#define STROBE_DUTY 20 // скважность вспышек (1 - 99) - отношение времени вспышки ко времени темноты
-#define STROBE_COLOR HUE_YELLOW // цвет стробоскопа
-#define STROBE_SAT 0 // насыщенность. Если 0 - цвет будет БЕЛЫЙ при любом цвете (0 - 255)
-byte STROBE_SMOOTH = 100; // скорость нарастания/угасания вспышки (0 - 255)
-
-// режим подсветки
-byte LIGHT_COLOR = 0; // начальный цвет подсветки
-byte LIGHT_SAT = 200; // начальная насыщенность подсветки
-byte COLOR_SPEED = 100;
-int RAINBOW_PERIOD = 3;
-float RAINBOW_STEP_2 = 5.5;
-
-// режим бегущих частот
-byte RUNNING_SPEED = 60;
-
-// режим анализатора спектра
-byte HUE_START = 0;
-byte HUE_STEP = 5;
-#define LIGHT_SMOOTH 2
-
-/*
- Цвета для HSV
- HUE_RED
- HUE_ORANGE
- HUE_YELLOW
- HUE_GREEN
- HUE_AQUA
- HUE_BLUE
- HUE_PURPLE
- HUE_PINK
-*/
-// --------------------------- НАСТРОЙКИ ---------------------------
-
-// ----- КНОПКИ ПУЛЬТА -----
-#define BUTT_UP 0xFF629D
-#define BUTT_DOWN 0xFFA857
-#define BUTT_LEFT 0xFF22DD
-#define BUTT_RIGHT 0xFFC23D
-#define BUTT_OK 0xFF02FD
-#define BUTT_1 0xFF6897
-#define BUTT_2 0xFF9867
-#define BUTT_3 0xFFB04F
-#define BUTT_4 0xFF30CF
-#define BUTT_5 0xFF18E7
-#define BUTT_6 0xFF7A85
-#define BUTT_7 0xFF10EF
-#define BUTT_8 0xFF38C7
-#define BUTT_9 0xFF5AA5
-#define BUTT_0 0xFF4AB5
-#define BUTT_STAR 0xFF42BD
-#define BUTT_HASH 0xFF52AD
-// ----- КНОПКИ ПУЛЬТА -----
-
-// ------------------------------ ДЛЯ РАЗРАБОТЧИКОВ --------------------------------
-#define MODE_AMOUNT 9 // количество режимов
-
-// цвета (устаревшие)
-#define BLUE 0x0000FF
-#define RED 0xFF0000
-#define GREEN 0x00ff00
-#define CYAN 0x00FFFF
-#define MAGENTA 0xFF00FF
-#define YELLOW 0xFFFF00
-#define WHITE 0xFFFFFF
-#define BLACK 0x000000
-
-#define STRIPE NUM_LEDS / 5
-float freq_to_stripe = NUM_LEDS / 40; // /2 так как симметрия, и /20 так как 20 частот
-
-#define FHT_N 64 // ширина спектра х2
-#define LOG_OUT 1
-#include // преобразование Хартли
-
-#include
-
-#define FASTLED_ALLOW_INTERRUPTS 1
-#include "FastLED.h"
-CRGB leds[NUM_LEDS];
-
-#include "GyverButton.h"
-GButton butt1(BTN_PIN);
-
-#include "IRremote.h"
-IRrecv irrecv(IR_PIN);
-decode_results results;
-
-// градиент-палитра от зелёного к красному
-DEFINE_GRADIENT_PALETTE(soundlevel_gp) {
- 0, 0, 255, 0, // green
- 100, 255, 255, 0, // yellow
- 150, 255, 100, 0, // orange
- 200, 255, 50, 0, // red
- 255, 255, 0, 0 // red
-};
-CRGBPalette32 myPal = soundlevel_gp;
-
-byte Rlenght, Llenght;
-float RsoundLevel, RsoundLevel_f;
-float LsoundLevel, LsoundLevel_f;
-
-float averageLevel = 50;
-int maxLevel = 100;
-byte MAX_CH = NUM_LEDS / 2;
-int hue;
-unsigned long main_timer, hue_timer, strobe_timer, running_timer, color_timer, rainbow_timer, eeprom_timer;
-float averK = 0.006;
-byte count;
-float index = (float)255 / MAX_CH; // коэффициент перевода для палитры
-boolean lowFlag;
-byte low_pass;
-int RcurrentLevel, LcurrentLevel;
-int colorMusic[3];
-float colorMusic_f[3], colorMusic_aver[3];
-boolean colorMusicFlash[3], strobeUp_flag, strobeDwn_flag;
-byte this_mode = MODE;
-int thisBright[3], strobe_bright = 0;
-unsigned int light_time = STROBE_PERIOD * STROBE_DUTY / 100;
-volatile boolean ir_flag;
-boolean settings_mode, ONstate = true;
-int8_t freq_strobe_mode, light_mode;
-int freq_max;
-float freq_max_f, rainbow_steps;
-int freq_f[32];
-int this_color;
-boolean running_flag[3], eeprom_flag;
-
-#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
-#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
-// ------------------------------ ДЛЯ РАЗРАБОТЧИКОВ --------------------------------
-
-void setup() {
- Serial.begin(9600);
- FastLED.addLeds(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
- FastLED.setBrightness(BRIGHTNESS);
-
- pinMode(13, OUTPUT);
- digitalWrite(13, LOW);
-
- pinMode(POT_GND, OUTPUT);
- digitalWrite(POT_GND, LOW);
- butt1.setTimeout(900);
-
- irrecv.enableIRIn(); // запускаем прием
- attachInterrupt(0, checkIR, RISING);
-
- // для увеличения точности уменьшаем опорное напряжение,
- // выставив EXTERNAL и подключив Aref к выходу 3.3V на плате через делитель
- // GND ---[10-20 кОм] --- REF --- [10 кОм] --- 3V3
- // в данной схеме GND берётся из А0 для удобства подключения
- if (POTENT) analogReference(EXTERNAL);
- else analogReference(INTERNAL);
-
- // жуткая магия, меняем частоту оцифровки до 18 кГц
- // команды на ебучем ассемблере, даже не спрашивайте, как это работает
- sbi(ADCSRA, ADPS2);
- cbi(ADCSRA, ADPS1);
- sbi(ADCSRA, ADPS0);
-
- if (RESET_SETTINGS) EEPROM.write(100, 0); // сброс флага настроек
-
- if (AUTO_LOW_PASS && !EEPROM_LOW_PASS) { // если разрешена автонастройка нижнего порога шумов
- autoLowPass();
- }
- if (EEPROM_LOW_PASS) { // восстановить значения шумов из памяти
- LOW_PASS = EEPROM.readInt(70);
- SPEKTR_LOW_PASS = EEPROM.readInt(72);
- }
-
- // в 100 ячейке хранится число 100. Если нет - значит это первый запуск системы
- if (KEEP_SETTINGS) {
- if (EEPROM.read(100) != 100) {
- //Serial.println(F("First start"));
- EEPROM.write(100, 100);
- updateEEPROM();
- } else {
- readEEPROM();
- }
- }
-}
-
-void loop() {
- buttonTick(); // опрос и обработка кнопки
- remoteTick(); // опрос ИК пульта
- mainLoop(); // главный цикл обработки и отрисовки
- eepromTick(); // проверка не пора ли сохранить настройки
-}
-
-void mainLoop() {
- // главный цикл отрисовки
- if (ONstate) {
- if (millis() - main_timer > MAIN_LOOP) {
- // сбрасываем значения
- RsoundLevel = 0;
- LsoundLevel = 0;
-
- // перваые два режима - громкость (VU meter)
- if (this_mode == 0 || this_mode == 1) {
- for (byte i = 0; i < 100; i ++) { // делаем 100 измерений
- RcurrentLevel = analogRead(SOUND_R); // с правого
- if (!MONO) LcurrentLevel = analogRead(SOUND_L); // и левого каналов
-
- if (RsoundLevel < RcurrentLevel) RsoundLevel = RcurrentLevel; // ищем максимальное
- if (!MONO) if (LsoundLevel < LcurrentLevel) LsoundLevel = LcurrentLevel; // ищем максимальное
- }
-
- // фильтруем по нижнему порогу шумов
- RsoundLevel = map(RsoundLevel, LOW_PASS, 1023, 0, 500);
- if (!MONO)LsoundLevel = map(LsoundLevel, LOW_PASS, 1023, 0, 500);
-
- // ограничиваем диапазон
- RsoundLevel = constrain(RsoundLevel, 0, 500);
- if (!MONO)LsoundLevel = constrain(LsoundLevel, 0, 500);
-
- // возводим в степень (для большей чёткости работы)
- RsoundLevel = pow(RsoundLevel, EXP);
- if (!MONO)LsoundLevel = pow(LsoundLevel, EXP);
-
- // фильтр
- RsoundLevel_f = RsoundLevel * SMOOTH + RsoundLevel_f * (1 - SMOOTH);
- if (!MONO)LsoundLevel_f = LsoundLevel * SMOOTH + LsoundLevel_f * (1 - SMOOTH);
-
- if (MONO) LsoundLevel_f = RsoundLevel_f; // если моно, то левый = правому
-
- // заливаем "подложку", если яркость достаточная
- if (EMPTY_BRIGHT > 5) {
- for (int i = 0; i < NUM_LEDS; i++)
- leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- }
-
- // если значение выше порога - начинаем самое интересное
- if (RsoundLevel_f > 15 && LsoundLevel_f > 15) {
-
- // расчёт общей средней громкости с обоих каналов, фильтрация.
- // Фильтр очень медленный, сделано специально для автогромкости
- averageLevel = (float)(RsoundLevel_f + LsoundLevel_f) / 2 * averK + averageLevel * (1 - averK);
-
- // принимаем максимальную громкость шкалы как среднюю, умноженную на некоторый коэффициент MAX_COEF
- maxLevel = (float)averageLevel * MAX_COEF;
-
- // преобразуем сигнал в длину ленты (где MAX_CH это половина количества светодиодов)
- Rlenght = map(RsoundLevel_f, 0, maxLevel, 0, MAX_CH);
- Llenght = map(LsoundLevel_f, 0, maxLevel, 0, MAX_CH);
-
- // ограничиваем до макс. числа светодиодов
- Rlenght = constrain(Rlenght, 0, MAX_CH);
- Llenght = constrain(Llenght, 0, MAX_CH);
-
- animation(); // отрисовать
- }
- }
-
- // 3-5 режим - цветомузыка
- if (this_mode == 2 || this_mode == 3 || this_mode == 4 || this_mode == 7 || this_mode == 8) {
- analyzeAudio();
- colorMusic[0] = 0;
- colorMusic[1] = 0;
- colorMusic[2] = 0;
- for (int i = 0 ; i < 32 ; i++) {
- if (fht_log_out[i] < SPEKTR_LOW_PASS) fht_log_out[i] = 0;
- }
- // низкие частоты, выборка со 2 по 5 тон (0 и 1 зашумленные!)
- for (byte i = 2; i < 6; i++) {
- if (fht_log_out[i] > colorMusic[0]) colorMusic[0] = fht_log_out[i];
- }
- // средние частоты, выборка с 6 по 10 тон
- for (byte i = 6; i < 11; i++) {
- if (fht_log_out[i] > colorMusic[1]) colorMusic[1] = fht_log_out[i];
- }
- // высокие частоты, выборка с 11 по 31 тон
- for (byte i = 11; i < 32; i++) {
- if (fht_log_out[i] > colorMusic[2]) colorMusic[2] = fht_log_out[i];
- }
- freq_max = 0;
- for (byte i = 0; i < 30; i++) {
- if (fht_log_out[i + 2] > freq_max) freq_max = fht_log_out[i + 2];
- if (freq_max < 5) freq_max = 5;
-
- if (freq_f[i] < fht_log_out[i + 2]) freq_f[i] = fht_log_out[i + 2];
- if (freq_f[i] > 0) freq_f[i] -= LIGHT_SMOOTH;
- else freq_f[i] = 0;
- }
- freq_max_f = freq_max * averK + freq_max_f * (1 - averK);
- for (byte i = 0; i < 3; i++) {
- colorMusic_aver[i] = colorMusic[i] * averK + colorMusic_aver[i] * (1 - averK); // общая фильтрация
- colorMusic_f[i] = colorMusic[i] * SMOOTH_FREQ + colorMusic_f[i] * (1 - SMOOTH_FREQ); // локальная
- if (colorMusic_f[i] > ((float)colorMusic_aver[i] * MAX_COEF_FREQ)) {
- thisBright[i] = 255;
- colorMusicFlash[i] = true;
- running_flag[i] = true;
- } else colorMusicFlash[i] = false;
- if (thisBright[i] >= 0) thisBright[i] -= SMOOTH_STEP;
- if (thisBright[i] < EMPTY_BRIGHT) {
- thisBright[i] = EMPTY_BRIGHT;
- running_flag[i] = false;
- }
- }
- animation();
- }
- if (this_mode == 5) {
- if ((long)millis() - strobe_timer > STROBE_PERIOD) {
- strobe_timer = millis();
- strobeUp_flag = true;
- strobeDwn_flag = false;
- }
- if ((long)millis() - strobe_timer > light_time) {
- strobeDwn_flag = true;
- }
- if (strobeUp_flag) { // если настало время пыхнуть
- if (strobe_bright < 255) // если яркость не максимальная
- strobe_bright += STROBE_SMOOTH; // увелчить
- if (strobe_bright > 255) { // если пробили макс. яркость
- strobe_bright = 255; // оставить максимум
- strobeUp_flag = false; // флаг опустить
- }
- }
-
- if (strobeDwn_flag) { // гаснем
- if (strobe_bright > 0) // если яркость не минимальная
- strobe_bright -= STROBE_SMOOTH; // уменьшить
- if (strobe_bright < 0) { // если пробили мин. яркость
- strobeDwn_flag = false;
- strobe_bright = 0; // оставить 0
- }
- }
- animation();
- }
- if (this_mode == 6) animation();
-
- if (irrecv.isIdle()) // если на ИК приёмник не приходит сигнал (без этого НЕ РАБОТАЕТ!)
- FastLED.show(); // отправить значения на ленту
-
- if (this_mode != 7) // 7 режиму не нужна очистка!!!
- FastLED.clear(); // очистить массив пикселей
- main_timer = millis(); // сбросить таймер
- }
- }
-}
-
-void animation() {
- // согласно режиму
- switch (this_mode) {
- case 0:
- count = 0;
- for (int i = (MAX_CH - 1); i > ((MAX_CH - 1) - Rlenght); i--) {
- leds[i] = ColorFromPalette(myPal, (count * index)); // заливка по палитре " от зелёного к красному"
- count++;
- }
- count = 0;
- for (int i = (MAX_CH); i < (MAX_CH + Llenght); i++ ) {
- leds[i] = ColorFromPalette(myPal, (count * index)); // заливка по палитре " от зелёного к красному"
- count++;
- }
- if (EMPTY_BRIGHT > 0) {
- for (int i = ((MAX_CH - 1) - Rlenght); i > 0; i--)
- leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- for (int i = MAX_CH + Llenght; i < NUM_LEDS; i++)
- leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- }
- break;
- case 1:
- if (millis() - rainbow_timer > 30) {
- rainbow_timer = millis();
- hue = floor((float)hue + RAINBOW_STEP);
- }
- count = 0;
- for (int i = (MAX_CH - 1); i > ((MAX_CH - 1) - Rlenght); i--) {
- leds[i] = ColorFromPalette(RainbowColors_p, (count * index) / 2 - hue); // заливка по палитре радуга
- count++;
- }
- count = 0;
- for (int i = (MAX_CH); i < (MAX_CH + Llenght); i++ ) {
- leds[i] = ColorFromPalette(RainbowColors_p, (count * index) / 2 - hue); // заливка по палитре радуга
- count++;
- }
- if (EMPTY_BRIGHT > 0) {
- for (int i = ((MAX_CH - 1) - Rlenght); i > 0; i--)
- leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- for (int i = MAX_CH + Llenght; i < NUM_LEDS; i++)
- leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- }
- break;
- case 2:
- for (int i = 0; i < NUM_LEDS; i++) {
- if (i < STRIPE) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (i < STRIPE * 2) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < STRIPE * 3) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else if (i < STRIPE * 4) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < STRIPE * 5) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- }
- break;
- case 3:
- for (int i = 0; i < NUM_LEDS; i++) {
- if (i < NUM_LEDS / 3) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (i < NUM_LEDS * 2 / 3) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < NUM_LEDS) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
- }
- break;
- case 4:
- switch (freq_strobe_mode) {
- case 0:
- if (colorMusicFlash[2]) HIGHS();
- else if (colorMusicFlash[1]) MIDS();
- else if (colorMusicFlash[0]) LOWS();
- else SILENCE();
- break;
- case 1:
- if (colorMusicFlash[2]) HIGHS();
- else SILENCE();
- break;
- case 2:
- if (colorMusicFlash[1]) MIDS();
- else SILENCE();
- break;
- case 3:
- if (colorMusicFlash[0]) LOWS();
- else SILENCE();
- break;
- }
- break;
- case 5:
- if (strobe_bright > 0)
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(STROBE_COLOR, STROBE_SAT, strobe_bright);
- else
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 6:
- switch (light_mode) {
- case 0: for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(LIGHT_COLOR, LIGHT_SAT, 255);
- break;
- case 1:
- if (millis() - color_timer > COLOR_SPEED) {
- color_timer = millis();
- if (++this_color > 255) this_color = 0;
- }
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(this_color, LIGHT_SAT, 255);
- break;
- case 2:
- if (millis() - rainbow_timer > 30) {
- rainbow_timer = millis();
- this_color += RAINBOW_PERIOD;
- if (this_color > 255) this_color = 0;
- if (this_color < 0) this_color = 255;
- }
- rainbow_steps = this_color;
- for (int i = 0; i < NUM_LEDS; i++) {
- leds[i] = CHSV((int)floor(rainbow_steps), 255, 255);
- rainbow_steps += RAINBOW_STEP_2;
- if (rainbow_steps > 255) rainbow_steps = 0;
- if (rainbow_steps < 0) rainbow_steps = 255;
- }
- break;
- }
- break;
- case 7:
- switch (freq_strobe_mode) {
- case 0:
- if (running_flag[2]) leds[NUM_LEDS / 2] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (running_flag[1]) leds[NUM_LEDS / 2] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (running_flag[0]) leds[NUM_LEDS / 2] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 1:
- if (running_flag[2]) leds[NUM_LEDS / 2] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 2:
- if (running_flag[1]) leds[NUM_LEDS / 2] = CHSV(MID_COLOR, 255, thisBright[1]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 3:
- if (running_flag[0]) leds[NUM_LEDS / 2] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- }
- leds[(NUM_LEDS / 2) - 1] = leds[NUM_LEDS / 2];
- if (millis() - running_timer > RUNNING_SPEED) {
- running_timer = millis();
- for (byte i = 0; i < NUM_LEDS / 2 - 1; i++) {
- leds[i] = leds[i + 1];
- leds[NUM_LEDS - i - 1] = leds[i];
- }
- }
- break;
- case 8:
- byte HUEindex = HUE_START;
- for (byte i = 0; i < NUM_LEDS / 2; i++) {
- byte this_bright = map(freq_f[(int)floor((NUM_LEDS / 2 - i) / freq_to_stripe)], 0, freq_max_f, 0, 255);
- this_bright = constrain(this_bright, 0, 255);
- leds[i] = CHSV(HUEindex, 255, this_bright);
- leds[NUM_LEDS - i - 1] = leds[i];
- HUEindex += HUE_STEP;
- if (HUEindex > 255) HUEindex = 0;
- }
- break;
- }
-}
-
-void HIGHS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
-}
-void MIDS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
-}
-void LOWS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
-}
-void SILENCE() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
-}
-
-// вспомогательная функция, изменяет величину value на шаг incr в пределах minimum.. maximum
-int smartIncr(int value, int incr_step, int mininmum, int maximum) {
- int val_buf = value + incr_step;
- val_buf = constrain(val_buf, mininmum, maximum);
- return val_buf;
-}
-
-float smartIncrFloat(float value, float incr_step, float mininmum, float maximum) {
- float val_buf = value + incr_step;
- val_buf = constrain(val_buf, mininmum, maximum);
- return val_buf;
-}
-
-void remoteTick() {
- if (ir_flag) { // если данные пришли
- eeprom_timer = millis();
- eeprom_flag = true;
- switch (results.value) {
- // режимы
- case BUTT_1: this_mode = 0;
- break;
- case BUTT_2: this_mode = 1;
- break;
- case BUTT_3: this_mode = 2;
- break;
- case BUTT_4: this_mode = 3;
- break;
- case BUTT_5: this_mode = 4;
- break;
- case BUTT_6: this_mode = 5;
- break;
- case BUTT_7: this_mode = 6;
- break;
- case BUTT_8: this_mode = 7;
- break;
- case BUTT_9: this_mode = 8;
- break;
- case BUTT_0: fullLowPass();
- break;
- case BUTT_STAR: ONstate = !ONstate; FastLED.clear(); FastLED.show(); updateEEPROM();
- break;
- case BUTT_HASH:
- switch (this_mode) {
- case 4:
- case 7: if (++freq_strobe_mode > 3) freq_strobe_mode = 0;
- break;
- case 6: if (++light_mode > 2) light_mode = 0;
- break;
- }
- break;
- case BUTT_OK: settings_mode = !settings_mode; digitalWrite(13, settings_mode);
- break;
- case BUTT_UP:
- if (settings_mode) {
- // ВВЕРХ общие настройки
- EMPTY_BRIGHT = smartIncr(EMPTY_BRIGHT, 5, 0, 255);
- } else {
- switch (this_mode) {
- case 0:
- break;
- case 1: RAINBOW_STEP = smartIncrFloat(RAINBOW_STEP, 0.5, 0.5, 20);
- break;
- case 2:
- case 3:
- case 4: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, 0.1, 0, 5);
- break;
- case 5: STROBE_PERIOD = smartIncr(STROBE_PERIOD, 20, 1, 1000);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_SAT = smartIncr(LIGHT_SAT, 20, 0, 255);
- break;
- case 1: LIGHT_SAT = smartIncr(LIGHT_SAT, 20, 0, 255);
- break;
- case 2: RAINBOW_STEP_2 = smartIncrFloat(RAINBOW_STEP_2, 0.5, 0.5, 10);
- break;
- }
- break;
- case 7: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, 0.1, 0.0, 10);
- break;
- case 8: HUE_START = smartIncr(HUE_START, 10, 0, 255);
- break;
- }
- }
- break;
- case BUTT_DOWN:
- if (settings_mode) {
- // ВНИЗ общие настройки
- EMPTY_BRIGHT = smartIncr(EMPTY_BRIGHT, -5, 0, 255);
- } else {
- switch (this_mode) {
- case 0:
- break;
- case 1: RAINBOW_STEP = smartIncrFloat(RAINBOW_STEP, -0.5, 0.5, 20);
- break;
- case 2:
- case 3:
- case 4: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, -0.1, 0, 5);
- break;
- case 5: STROBE_PERIOD = smartIncr(STROBE_PERIOD, -20, 1, 1000);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_SAT = smartIncr(LIGHT_SAT, -20, 0, 255);
- break;
- case 1: LIGHT_SAT = smartIncr(LIGHT_SAT, -20, 0, 255);
- break;
- case 2: RAINBOW_STEP_2 = smartIncrFloat(RAINBOW_STEP_2, -0.5, 0.5, 10);
- break;
- }
- break;
- case 7: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, -0.1, 0.0, 10);
- break;
- case 8: HUE_START = smartIncr(HUE_START, -10, 0, 255);
- break;
- }
- }
- break;
- case BUTT_LEFT:
- if (settings_mode) {
- // ВЛЕВО общие настройки
- BRIGHTNESS = smartIncr(BRIGHTNESS, -20, 0, 255);
- FastLED.setBrightness(BRIGHTNESS);
- } else {
- switch (this_mode) {
- case 0:
- case 1: SMOOTH = smartIncrFloat(SMOOTH, -0.05, 0.05, 1);
- break;
- case 2:
- case 3:
- case 4: SMOOTH_FREQ = smartIncrFloat(SMOOTH_FREQ, -0.05, 0.05, 1);
- break;
- case 5: STROBE_SMOOTH = smartIncr(STROBE_SMOOTH, -20, 0, 255);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_COLOR = smartIncr(LIGHT_COLOR, -10, 0, 255);
- break;
- case 1: COLOR_SPEED = smartIncr(COLOR_SPEED, -10, 0, 255);
- break;
- case 2: RAINBOW_PERIOD = smartIncr(RAINBOW_PERIOD, -1, -20, 20);
- break;
- }
- break;
- case 7: RUNNING_SPEED = smartIncr(RUNNING_SPEED, -10, 1, 255);
- break;
- case 8: HUE_STEP = smartIncr(HUE_STEP, -1, 1, 255);
- break;
- }
- }
- break;
- case BUTT_RIGHT:
- if (settings_mode) {
- // ВПРАВО общие настройки
- BRIGHTNESS = smartIncr(BRIGHTNESS, 20, 0, 255);
- FastLED.setBrightness(BRIGHTNESS);
- } else {
- switch (this_mode) {
- case 0:
- case 1: SMOOTH = smartIncrFloat(SMOOTH, 0.05, 0.05, 1);
- break;
- case 2:
- case 3:
- case 4: SMOOTH_FREQ = smartIncrFloat(SMOOTH_FREQ, 0.05, 0.05, 1);
- break;
- case 5: STROBE_SMOOTH = smartIncr(STROBE_SMOOTH, 20, 0, 255);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_COLOR = smartIncr(LIGHT_COLOR, 10, 0, 255);
- break;
- case 1: COLOR_SPEED = smartIncr(COLOR_SPEED, 10, 0, 255);
- break;
- case 2: RAINBOW_PERIOD = smartIncr(RAINBOW_PERIOD, 1, -20, 20);
- break;
- }
- break;
- case 7: RUNNING_SPEED = smartIncr(RUNNING_SPEED, 10, 1, 255);
- break;
- case 8: HUE_STEP = smartIncr(HUE_STEP, 1, 1, 255);
- break;
- }
- }
- break;
- default: eeprom_flag = false; // если не распознали кнопку, не обновляем настройки!
- break;
- }
- ir_flag = false;
- }
-}
-
-void checkIR() {
- while (irrecv.decode(&results)) {
- ir_flag = true;
- irrecv.resume();
- }
-}
-
-void autoLowPass() {
- // для режима VU
- delay(10); // ждём инициализации АЦП
- int thisMax = 0; // максимум
- int thisLevel;
- for (byte i = 0; i < 200; i++) {
- thisLevel = analogRead(SOUND_R); // делаем 200 измерений
- if (thisLevel > thisMax) // ищем максимумы
- thisMax = thisLevel; // запоминаем
- delay(4); // ждём 4мс
- }
- LOW_PASS = thisMax + LOW_PASS_ADD; // нижний порог как максимум тишины + некая величина
-
- // для режима спектра
- thisMax = 0;
- for (byte i = 0; i < 100; i++) { // делаем 100 измерений
- analyzeAudio(); // разбить в спектр
- for (byte j = 2; j < 32; j++) { // первые 2 канала - хлам
- thisLevel = fht_log_out[j];
- if (thisLevel > thisMax) // ищем максимумы
- thisMax = thisLevel; // запоминаем
- }
- delay(4); // ждём 4мс
- }
- SPEKTR_LOW_PASS = thisMax + LOW_PASS_FREQ_ADD; // нижний порог как максимум тишины
-
- if (EEPROM_LOW_PASS && !AUTO_LOW_PASS) {
- EEPROM.updateInt(70, LOW_PASS);
- EEPROM.updateInt(72, SPEKTR_LOW_PASS);
- }
-}
-
-void analyzeAudio() {
- for (int i = 0 ; i < FHT_N ; i++) {
- int sample = analogRead(SOUND_R_FREQ);
- fht_input[i] = sample; // put real data into bins
- }
- fht_window(); // window the data for better frequency response
- fht_reorder(); // reorder the data before doing the fht
- fht_run(); // process the data in the fht
- fht_mag_log(); // take the output of the fht
-}
-
-void buttonTick() {
- butt1.tick(); // обязательная функция отработки. Должна постоянно опрашиваться
- if (butt1.isSingle()) // если единичное нажатие
- if (++this_mode >= MODE_AMOUNT) this_mode = 0; // изменить режим
-
- if (butt1.isHolded()) { // кнопка удержана
- fullLowPass();
- }
-}
-void fullLowPass() {
- digitalWrite(13, HIGH); // включить светодиод 13 пин
- FastLED.setBrightness(0); // погасить ленту
- FastLED.clear(); // очистить массив пикселей
- FastLED.show(); // отправить значения на ленту
- delay(500); // подождать чутка
- autoLowPass(); // измерить шумы
- delay(500); // подождать
- FastLED.setBrightness(BRIGHTNESS); // вернуть яркость
- digitalWrite(13, LOW); // выключить светодиод
-}
-void updateEEPROM() {
- EEPROM.updateByte(1, this_mode);
- EEPROM.updateByte(2, freq_strobe_mode);
- EEPROM.updateByte(3, light_mode);
- EEPROM.updateInt(4, RAINBOW_STEP);
- EEPROM.updateFloat(8, MAX_COEF_FREQ);
- EEPROM.updateInt(12, STROBE_PERIOD);
- EEPROM.updateInt(16, LIGHT_SAT);
- EEPROM.updateFloat(20, RAINBOW_STEP_2);
- EEPROM.updateInt(24, HUE_START);
- EEPROM.updateFloat(28, SMOOTH);
- EEPROM.updateFloat(32, SMOOTH_FREQ);
- EEPROM.updateInt(36, STROBE_SMOOTH);
- EEPROM.updateInt(40, LIGHT_COLOR);
- EEPROM.updateInt(44, COLOR_SPEED);
- EEPROM.updateInt(48, RAINBOW_PERIOD);
- EEPROM.updateInt(52, RUNNING_SPEED);
- EEPROM.updateInt(56, HUE_STEP);
- EEPROM.updateInt(60, EMPTY_BRIGHT);
-}
-void readEEPROM() {
- this_mode = EEPROM.readByte(1);
- freq_strobe_mode = EEPROM.readByte(2);
- light_mode = EEPROM.readByte(3);
- RAINBOW_STEP = EEPROM.readInt(4);
- MAX_COEF_FREQ = EEPROM.readFloat(8);
- STROBE_PERIOD = EEPROM.readInt(12);
- LIGHT_SAT = EEPROM.readInt(16);
- RAINBOW_STEP_2 = EEPROM.readFloat(20);
- HUE_START = EEPROM.readInt(24);
- SMOOTH = EEPROM.readFloat(28);
- SMOOTH_FREQ = EEPROM.readFloat(32);
- STROBE_SMOOTH = EEPROM.readInt(36);
- LIGHT_COLOR = EEPROM.readInt(40);
- COLOR_SPEED = EEPROM.readInt(44);
- RAINBOW_PERIOD = EEPROM.readInt(48);
- RUNNING_SPEED = EEPROM.readInt(52);
- HUE_STEP = EEPROM.readInt(56);
- EMPTY_BRIGHT = EEPROM.readInt(60);
-}
-void eepromTick() {
- if (eeprom_flag)
- if (millis() - eeprom_timer > 30000) { // 30 секунд после последнего нажатия с пульта
- eeprom_flag = false;
- eeprom_timer = millis();
- updateEEPROM();
- }
-}
diff --git a/firmware/Old versions/colorMusic_v2.4_WAVGAT/colorMusic_v2.4_WAVGAT.ino b/firmware/Old versions/colorMusic_v2.4_WAVGAT/colorMusic_v2.4_WAVGAT.ino
deleted file mode 100644
index c391e2e..0000000
--- a/firmware/Old versions/colorMusic_v2.4_WAVGAT/colorMusic_v2.4_WAVGAT.ino
+++ /dev/null
@@ -1,952 +0,0 @@
-/*
- Крутейшая свето-цветомузыка на Arduino и адресной светодиодной ленте WS2812b.
- Данная версия поддерживает до 350 светодиодов!!!
- Управление:
- - Однократное нажатие кнопки: смена режима
- - Удержание кнопки: калибровка нижнего порога шума
- Режимы работы (переключаются кнопкой):
- - VU meter (столбик громкости): от зелёного к красному
- - VU meter (столбик громкости): плавно бегущая радуга
- - Светомузыка по частотам: 5 полос симметрично
- - Светомузыка по частотам: 3 полосы
- - Светомузыка по частотам: 1 полоса
- - Стробоскоп
- - (2.0) Подсветка
- - (2.0) Бегущие частоты
- - (2.1) анализатор спектра
- Особенности:
- - Плавная анимация (можно настроить)
- - Автонастройка по громкости (можно настроить)
- - Фильтр нижнего шума (можно настроить)
- - Автокалибровка шума при запуске (можно настроить)
- - Поддержка стерео и моно звука (можно настроить)
- - (2.0) в режиме частот лента не гаснет полностью (EMPTY_BRIGHT)
- - (2.1) все настройки сохраняются в памяти и не сбрасываются при перезагрузке
- - Сохранение настроек происходит при выключении кнопкой звёздочка (*)
- - А также через 30 секунд после последнего нажатия на любую кнопку ИК пульта
-
- НАСТРОЙКА НИЖНЕГО ПОРОГА ШУМА (строки 65-71)
- - Включаем систему
- - Ставим музыку на паузу
- - Удерживаем кнопку 1 секунду ИЛИ жмём кнопку 0 на пульте
- Значения шумов будут записаны в память и САМИ загружаться при последующем запуске! Всё!
-
- Пульт:
- - Цифры (1 - 9) активируют режимы
- - Цифра 0: калибровка шума
- - Звёздочка (*): включить/выключить систему
- - Кнопка ОК: переключение между локальными и глобальными настройками)
- - Решётка (#): смена подрежима
- - Глобальные настройки (горит светодиод на плате):
- + Стрелки ← →: общая яркость горящих светодиодов
- + Стрелки ↑ ↓: яркость "не горящих" светодиодов
- - Локальные настройки (у каждого режима свои):
- 1 - Шкала громкости (градиент)
- Стрелки ← →: плавность анимации
- 2 - Шкала громкости (радуга)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: скорость радуги
- 3 - Цветомузыка (5 полос)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- 4 - Цветомузыка (3 полосы)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- 5 - Цветомузыка (1 полоса)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- Подрежимы #: 3 частоты / низкие / средние / высокие
- 6 - Стробоскоп
- Стрелки ← →: плавность вспышек
- Стрелки ↑ ↓: частота вспышек
- 7 - Цветная подсветка
- Подрежимы #:
- Постоянный: стрелки ← →: цвет, стрелки ↑ ↓: насыщенность
- Плавная смена: стрелки ← →: скорость, стрелки ↑ ↓: насыщенность
- Бегущая радуга: стрелки ← →: скорость, стрелки ↑ ↓: шаг радуги
- 8 - “Бегущие частоты”
- Стрелки ← →: скорость
- Стрелки ↑ ↓: чувствительность
- Подрежимы #: 3 частоты / низкие / средние / высокие
- 9 - Анализатор спектра
- Стрелки ← →: шаг цвета
- Стрелки ↑ ↓: цвет
- **************************************************
- Разработано: AlexGyver
- Страница проекта: http://alexgyver.ru/colormusic/
- GitHub: https://github.com/AlexGyver/ColorMusic
-*/
-
-// --------------------------- НАСТРОЙКИ ---------------------------
-#define KEEP_SETTINGS 1 // хранить ВСЕ настройки в памяти
-#define RESET_SETTINGS 0 // сброс настроек в памяти.
-// поставить 1. Прошиться. Поставить обратно 0. Прошиться. Всё.
-
-// лента
-#define NUM_LEDS 120 // количество светодиодов
-byte BRIGHTNESS = 200; // яркость (0 - 255)
-
-// пины
-#define SOUND_R A2 // аналоговый пин вход аудио, правый канал
-#define SOUND_L A1 // аналоговый пин вход аудио, левый канал
-#define SOUND_R_FREQ A3 // аналоговый пин вход аудио для режима с частотами (через кондер)
-#define BTN_PIN 3 // кнопка переключения режимов (PIN --- КНОПКА --- GND)
-#define LED_PIN 12 // пин DI светодиодной ленты
-#define POT_GND A0 // пин земля для потенциометра
-#define IR_PIN 2 // ИК приёмник
-
-// настройки радуги
-float RAINBOW_STEP = 5.5; // шаг изменения цвета радуги
-
-// отрисовка
-#define MODE 0 // режим при запуске
-#define MAIN_LOOP 5 // период основного цикла отрисовки (по умолчанию 5)
-
-// сигнал
-#define MONO 1 // 1 - только один канал (ПРАВЫЙ!!!!! SOUND_R!!!!!), 0 - два канала
-#define EXP 1.4 // степень усиления сигнала (для более "резкой" работы) (по умолчанию 1.4)
-#define POTENT 1 // 1 - используем потенциометр, 0 - используется внутренний источник опорного напряжения 1.1 В
-byte EMPTY_BRIGHT = 30; // яркость "не горящих" светодиодов (0 - 255)
-#define EMPTY_COLOR HUE_PURPLE // цвет "не горящих" светодиодов. Будет чёрный, если яркость 0
-
-// нижний порог шумов
-byte LOW_PASS = 100; // нижний порог шумов режим VU, ручная настройка
-byte SPEKTR_LOW_PASS = 40; // нижний порог шумов режим спектра, ручная настройка
-#define AUTO_LOW_PASS 0 // разрешить настройку нижнего порога шумов при запуске (по умолч. 0)
-#define EEPROM_LOW_PASS 1 // порог шумов хранится в энергонезависимой памяти (по умолч. 1)
-#define LOW_PASS_ADD 13 // "добавочная" величина к нижнему порогу, для надёжности (режим VU)
-#define LOW_PASS_FREQ_ADD 3 // "добавочная" величина к нижнему порогу, для надёжности (режим частот)
-
-// шкала громкости
-float SMOOTH = 0.5; // коэффициент плавности анимации VU (по умолчанию 0.5)
-#define MAX_COEF 1.8 // коэффициент громкости (максимальное равно срднему * этот коэф) (по умолчанию 1.8)
-
-// режим цветомузыки
-float SMOOTH_FREQ = 0.8; // коэффициент плавности анимации частот (по умолчанию 0.8)
-float MAX_COEF_FREQ = 1.2; // коэффициент порога для "вспышки" цветомузыки (по умолчанию 1.5)
-#define SMOOTH_STEP 20 // шаг уменьшения яркости в режиме цветомузыки (чем больше, тем быстрее гаснет)
-#define LOW_COLOR HUE_RED // цвет низких частот
-#define MID_COLOR HUE_GREEN // цвет средних
-#define HIGH_COLOR HUE_YELLOW // цвет высоких
-
-// режим стробоскопа
-int STROBE_PERIOD = 100; // период вспышек, миллисекунды
-#define STROBE_DUTY 20 // скважность вспышек (1 - 99) - отношение времени вспышки ко времени темноты
-#define STROBE_COLOR HUE_YELLOW // цвет стробоскопа
-#define STROBE_SAT 0 // насыщенность. Если 0 - цвет будет БЕЛЫЙ при любом цвете (0 - 255)
-byte STROBE_SMOOTH = 100; // скорость нарастания/угасания вспышки (0 - 255)
-
-// режим подсветки
-byte LIGHT_COLOR = 0; // начальный цвет подсветки
-byte LIGHT_SAT = 200; // начальная насыщенность подсветки
-byte COLOR_SPEED = 100;
-int RAINBOW_PERIOD = 3;
-float RAINBOW_STEP_2 = 5.5;
-
-// режим бегущих частот
-byte RUNNING_SPEED = 60;
-
-// режим анализатора спектра
-byte HUE_START = 0;
-byte HUE_STEP = 5;
-#define LIGHT_SMOOTH 2
-
-/*
- Цвета для HSV
- HUE_RED
- HUE_ORANGE
- HUE_YELLOW
- HUE_GREEN
- HUE_AQUA
- HUE_BLUE
- HUE_PURPLE
- HUE_PINK
-*/
-// --------------------------- НАСТРОЙКИ ---------------------------
-
-// —-— КНОПКИ ПУЛЬТА —-—
-#define BUTT_UP 0xFF18E7
-#define BUTT_DOWN 0xFF4AB5
-#define BUTT_LEFT 0xFF10EF
-#define BUTT_RIGHT 0xFF5AA5
-#define BUTT_OK 0xFF38C7
-#define BUTT_1 0xFFA25D
-#define BUTT_2 0xFF629D
-#define BUTT_3 0xFFE21D
-#define BUTT_4 0xFF22DD
-#define BUTT_5 0xFF02FD
-#define BUTT_6 0xFFC23D
-#define BUTT_7 0xFFE01F
-#define BUTT_8 0xFFA857
-#define BUTT_9 0xFF906F
-#define BUTT_0 0xFF9867
-#define BUTT_STAR 0xFF6897
-#define BUTT_HASH 0xFFB04F
-// —-— КНОПКИ ПУЛЬТА —---
-
-// ------------------------------ ДЛЯ РАЗРАБОТЧИКОВ --------------------------------
-#define MODE_AMOUNT 9 // количество режимов
-
-// цвета (устаревшие)
-#define BLUE 0x0000FF
-#define RED 0xFF0000
-#define GREEN 0x00ff00
-#define CYAN 0x00FFFF
-#define MAGENTA 0xFF00FF
-#define YELLOW 0xFFFF00
-#define WHITE 0xFFFFFF
-#define BLACK 0x000000
-
-#define STRIPE NUM_LEDS / 5
-float freq_to_stripe = NUM_LEDS / 40; // /2 так как симметрия, и /20 так как 20 частот
-
-#define FHT_N 64 // ширина спектра х2
-#define LOG_OUT 1
-#include // преобразование Хартли
-
-#include
-
-#define FASTLED_ALLOW_INTERRUPTS 1
-#include "FastLED.h"
-CRGB leds[NUM_LEDS];
-
-#include "GyverButton.h"
-GButton butt1(BTN_PIN);
-
-#include "IRremote.h"
-IRrecv irrecv(IR_PIN);
-decode_results results;
-
-// градиент-палитра от зелёного к красному
-DEFINE_GRADIENT_PALETTE(soundlevel_gp) {
- 0, 0, 255, 0, // green
- 100, 255, 255, 0, // yellow
- 150, 255, 100, 0, // orange
- 200, 255, 50, 0, // red
- 255, 255, 0, 0 // red
-};
-CRGBPalette32 myPal = soundlevel_gp;
-
-byte Rlenght, Llenght;
-float RsoundLevel, RsoundLevel_f;
-float LsoundLevel, LsoundLevel_f;
-
-float averageLevel = 50;
-int maxLevel = 100;
-byte MAX_CH = NUM_LEDS / 2;
-int hue;
-unsigned long main_timer, hue_timer, strobe_timer, running_timer, color_timer, rainbow_timer, eeprom_timer;
-float averK = 0.006;
-byte count;
-float index = (float)255 / MAX_CH; // коэффициент перевода для палитры
-boolean lowFlag;
-byte low_pass;
-int RcurrentLevel, LcurrentLevel;
-int colorMusic[3];
-float colorMusic_f[3], colorMusic_aver[3];
-boolean colorMusicFlash[3], strobeUp_flag, strobeDwn_flag;
-byte this_mode = MODE;
-int thisBright[3], strobe_bright = 0;
-unsigned int light_time = STROBE_PERIOD * STROBE_DUTY / 100;
-volatile boolean ir_flag;
-boolean settings_mode, ONstate = true;
-int8_t freq_strobe_mode, light_mode;
-int freq_max;
-float freq_max_f, rainbow_steps;
-int freq_f[32];
-int this_color;
-boolean running_flag[3], eeprom_flag;
-
-#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
-#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
-// ------------------------------ ДЛЯ РАЗРАБОТЧИКОВ --------------------------------
-
-void setup() {
- Serial.begin(9600);
- FastLED.addLeds(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
- FastLED.setBrightness(BRIGHTNESS);
-
- pinMode(13, OUTPUT);
- digitalWrite(13, LOW);
-
- pinMode(POT_GND, OUTPUT);
- digitalWrite(POT_GND, LOW);
- butt1.setTimeout(900);
-
- irrecv.enableIRIn(); // запускаем прием
- attachInterrupt(0, checkIR, RISING);
-
- // для увеличения точности уменьшаем опорное напряжение,
- // выставив EXTERNAL и подключив Aref к выходу 3.3V на плате через делитель
- // GND ---[10-20 кОм] --- REF --- [10 кОм] --- 3V3
- // в данной схеме GND берётся из А0 для удобства подключения
- if (POTENT) analogReference(EXTERNAL);
- else analogReference(INTERNAL);
-
- // жуткая магия, меняем частоту оцифровки до 18 кГц
- // команды на ебучем ассемблере, даже не спрашивайте, как это работает
- sbi(ADCSRA, ADPS2);
- cbi(ADCSRA, ADPS1);
- sbi(ADCSRA, ADPS0);
-
- if (RESET_SETTINGS) EEPROM.write(100, 0); // сброс флага настроек
-
- if (AUTO_LOW_PASS && !EEPROM_LOW_PASS) { // если разрешена автонастройка нижнего порога шумов
- autoLowPass();
- }
- if (EEPROM_LOW_PASS) { // восстановить значения шумов из памяти
- LOW_PASS = EEPROM.readInt(70);
- SPEKTR_LOW_PASS = EEPROM.readInt(72);
- }
-
- // в 100 ячейке хранится число 100. Если нет - значит это первый запуск системы
- if (KEEP_SETTINGS) {
- if (EEPROM.read(100) != 100) {
- //Serial.println(F("First start"));
- EEPROM.write(100, 100);
- updateEEPROM();
- } else {
- readEEPROM();
- }
- }
-}
-
-void loop() {
- buttonTick(); // опрос и обработка кнопки
- remoteTick(); // опрос ИК пульта
- mainLoop(); // главный цикл обработки и отрисовки
- eepromTick(); // проверка не пора ли сохранить настройки
-}
-
-void mainLoop() {
- // главный цикл отрисовки
- if (ONstate) {
- if (millis() - main_timer > MAIN_LOOP) {
- // сбрасываем значения
- RsoundLevel = 0;
- LsoundLevel = 0;
-
- // перваые два режима - громкость (VU meter)
- if (this_mode == 0 || this_mode == 1) {
- for (byte i = 0; i < 100; i ++) { // делаем 100 измерений
- RcurrentLevel = analogRead(SOUND_R); // с правого
- if (!MONO) LcurrentLevel = analogRead(SOUND_L); // и левого каналов
-
- if (RsoundLevel < RcurrentLevel) RsoundLevel = RcurrentLevel; // ищем максимальное
- if (!MONO) if (LsoundLevel < LcurrentLevel) LsoundLevel = LcurrentLevel; // ищем максимальное
- }
-
- // фильтруем по нижнему порогу шумов
- RsoundLevel = map(RsoundLevel, LOW_PASS, 1023, 0, 500);
- if (!MONO)LsoundLevel = map(LsoundLevel, LOW_PASS, 1023, 0, 500);
-
- // ограничиваем диапазон
- RsoundLevel = constrain(RsoundLevel, 0, 500);
- if (!MONO)LsoundLevel = constrain(LsoundLevel, 0, 500);
-
- // возводим в степень (для большей чёткости работы)
- RsoundLevel = pow(RsoundLevel, EXP);
- if (!MONO)LsoundLevel = pow(LsoundLevel, EXP);
-
- // фильтр
- RsoundLevel_f = RsoundLevel * SMOOTH + RsoundLevel_f * (1 - SMOOTH);
- if (!MONO)LsoundLevel_f = LsoundLevel * SMOOTH + LsoundLevel_f * (1 - SMOOTH);
-
- if (MONO) LsoundLevel_f = RsoundLevel_f; // если моно, то левый = правому
-
- // заливаем "подложку", если яркость достаточная
- if (EMPTY_BRIGHT > 5) {
- for (int i = 0; i < NUM_LEDS; i++)
- leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- }
-
- // если значение выше порога - начинаем самое интересное
- if (RsoundLevel_f > 15 && LsoundLevel_f > 15) {
-
- // расчёт общей средней громкости с обоих каналов, фильтрация.
- // Фильтр очень медленный, сделано специально для автогромкости
- averageLevel = (float)(RsoundLevel_f + LsoundLevel_f) / 2 * averK + averageLevel * (1 - averK);
-
- // принимаем максимальную громкость шкалы как среднюю, умноженную на некоторый коэффициент MAX_COEF
- maxLevel = (float)averageLevel * MAX_COEF;
-
- // преобразуем сигнал в длину ленты (где MAX_CH это половина количества светодиодов)
- Rlenght = map(RsoundLevel_f, 0, maxLevel, 0, MAX_CH);
- Llenght = map(LsoundLevel_f, 0, maxLevel, 0, MAX_CH);
-
- // ограничиваем до макс. числа светодиодов
- Rlenght = constrain(Rlenght, 0, MAX_CH);
- Llenght = constrain(Llenght, 0, MAX_CH);
-
- animation(); // отрисовать
- }
- }
-
- // 3-5 режим - цветомузыка
- if (this_mode == 2 || this_mode == 3 || this_mode == 4 || this_mode == 7 || this_mode == 8) {
- analyzeAudio();
- colorMusic[0] = 0;
- colorMusic[1] = 0;
- colorMusic[2] = 0;
- for (int i = 0 ; i < 32 ; i++) {
- if (fht_log_out[i] < SPEKTR_LOW_PASS) fht_log_out[i] = 0;
- }
- // низкие частоты, выборка со 2 по 5 тон (0 и 1 зашумленные!)
- for (byte i = 2; i < 6; i++) {
- if (fht_log_out[i] > colorMusic[0]) colorMusic[0] = fht_log_out[i];
- }
- // средние частоты, выборка с 6 по 10 тон
- for (byte i = 6; i < 11; i++) {
- if (fht_log_out[i] > colorMusic[1]) colorMusic[1] = fht_log_out[i];
- }
- // высокие частоты, выборка с 11 по 31 тон
- for (byte i = 11; i < 32; i++) {
- if (fht_log_out[i] > colorMusic[2]) colorMusic[2] = fht_log_out[i];
- }
- freq_max = 0;
- for (byte i = 0; i < 30; i++) {
- if (fht_log_out[i + 2] > freq_max) freq_max = fht_log_out[i + 2];
- if (freq_max < 5) freq_max = 5;
-
- if (freq_f[i] < fht_log_out[i + 2]) freq_f[i] = fht_log_out[i + 2];
- if (freq_f[i] > 0) freq_f[i] -= LIGHT_SMOOTH;
- else freq_f[i] = 0;
- }
- freq_max_f = freq_max * averK + freq_max_f * (1 - averK);
- for (byte i = 0; i < 3; i++) {
- colorMusic_aver[i] = colorMusic[i] * averK + colorMusic_aver[i] * (1 - averK); // общая фильтрация
- colorMusic_f[i] = colorMusic[i] * SMOOTH_FREQ + colorMusic_f[i] * (1 - SMOOTH_FREQ); // локальная
- if (colorMusic_f[i] > ((float)colorMusic_aver[i] * MAX_COEF_FREQ)) {
- thisBright[i] = 255;
- colorMusicFlash[i] = true;
- running_flag[i] = true;
- } else colorMusicFlash[i] = false;
- if (thisBright[i] >= 0) thisBright[i] -= SMOOTH_STEP;
- if (thisBright[i] < EMPTY_BRIGHT) {
- thisBright[i] = EMPTY_BRIGHT;
- running_flag[i] = false;
- }
- }
- animation();
- }
- if (this_mode == 5) {
- if ((long)millis() - strobe_timer > STROBE_PERIOD) {
- strobe_timer = millis();
- strobeUp_flag = true;
- strobeDwn_flag = false;
- }
- if ((long)millis() - strobe_timer > light_time) {
- strobeDwn_flag = true;
- }
- if (strobeUp_flag) { // если настало время пыхнуть
- if (strobe_bright < 255) // если яркость не максимальная
- strobe_bright += STROBE_SMOOTH; // увелчить
- if (strobe_bright > 255) { // если пробили макс. яркость
- strobe_bright = 255; // оставить максимум
- strobeUp_flag = false; // флаг опустить
- }
- }
-
- if (strobeDwn_flag) { // гаснем
- if (strobe_bright > 0) // если яркость не минимальная
- strobe_bright -= STROBE_SMOOTH; // уменьшить
- if (strobe_bright < 0) { // если пробили мин. яркость
- strobeDwn_flag = false;
- strobe_bright = 0; // оставить 0
- }
- }
- animation();
- }
- if (this_mode == 6) animation();
-
- if (irrecv.isIdle()) // если на ИК приёмник не приходит сигнал (без этого НЕ РАБОТАЕТ!)
- FastLED.show(); // отправить значения на ленту
-
- if (this_mode != 7) // 7 режиму не нужна очистка!!!
- FastLED.clear(); // очистить массив пикселей
- main_timer = millis(); // сбросить таймер
- }
- }
-}
-
-void animation() {
- // согласно режиму
- switch (this_mode) {
- case 0:
- count = 0;
- for (int i = (MAX_CH - 1); i > ((MAX_CH - 1) - Rlenght); i--) {
- leds[i] = ColorFromPalette(myPal, (count * index)); // заливка по палитре " от зелёного к красному"
- count++;
- }
- count = 0;
- for (int i = (MAX_CH); i < (MAX_CH + Llenght); i++ ) {
- leds[i] = ColorFromPalette(myPal, (count * index)); // заливка по палитре " от зелёного к красному"
- count++;
- }
- if (EMPTY_BRIGHT > 0) {
- for (int i = ((MAX_CH - 1) - Rlenght); i > 0; i--)
- leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- for (int i = MAX_CH + Llenght; i < NUM_LEDS; i++)
- leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- }
- break;
- case 1:
- if (millis() - rainbow_timer > 30) {
- rainbow_timer = millis();
- hue = floor((float)hue + RAINBOW_STEP);
- }
- count = 0;
- for (int i = (MAX_CH - 1); i > ((MAX_CH - 1) - Rlenght); i--) {
- leds[i] = ColorFromPalette(RainbowColors_p, (count * index) / 2 - hue); // заливка по палитре радуга
- count++;
- }
- count = 0;
- for (int i = (MAX_CH); i < (MAX_CH + Llenght); i++ ) {
- leds[i] = ColorFromPalette(RainbowColors_p, (count * index) / 2 - hue); // заливка по палитре радуга
- count++;
- }
- if (EMPTY_BRIGHT > 0) {
- for (int i = ((MAX_CH - 1) - Rlenght); i > 0; i--)
- leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- for (int i = MAX_CH + Llenght; i < NUM_LEDS; i++)
- leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- }
- break;
- case 2:
- for (int i = 0; i < NUM_LEDS; i++) {
- if (i < STRIPE) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (i < STRIPE * 2) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < STRIPE * 3) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else if (i < STRIPE * 4) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < STRIPE * 5) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- }
- break;
- case 3:
- for (int i = 0; i < NUM_LEDS; i++) {
- if (i < NUM_LEDS / 3) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (i < NUM_LEDS * 2 / 3) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < NUM_LEDS) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
- }
- break;
- case 4:
- switch (freq_strobe_mode) {
- case 0:
- if (colorMusicFlash[2]) HIGHS();
- else if (colorMusicFlash[1]) MIDS();
- else if (colorMusicFlash[0]) LOWS();
- else SILENCE();
- break;
- case 1:
- if (colorMusicFlash[2]) HIGHS();
- else SILENCE();
- break;
- case 2:
- if (colorMusicFlash[1]) MIDS();
- else SILENCE();
- break;
- case 3:
- if (colorMusicFlash[0]) LOWS();
- else SILENCE();
- break;
- }
- break;
- case 5:
- if (strobe_bright > 0)
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(STROBE_COLOR, STROBE_SAT, strobe_bright);
- else
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 6:
- switch (light_mode) {
- case 0: for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(LIGHT_COLOR, LIGHT_SAT, 255);
- break;
- case 1:
- if (millis() - color_timer > COLOR_SPEED) {
- color_timer = millis();
- if (++this_color > 255) this_color = 0;
- }
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(this_color, LIGHT_SAT, 255);
- break;
- case 2:
- if (millis() - rainbow_timer > 30) {
- rainbow_timer = millis();
- this_color += RAINBOW_PERIOD;
- if (this_color > 255) this_color = 0;
- if (this_color < 0) this_color = 255;
- }
- rainbow_steps = this_color;
- for (int i = 0; i < NUM_LEDS; i++) {
- leds[i] = CHSV((int)floor(rainbow_steps), 255, 255);
- rainbow_steps += RAINBOW_STEP_2;
- if (rainbow_steps > 255) rainbow_steps = 0;
- if (rainbow_steps < 0) rainbow_steps = 255;
- }
- break;
- }
- break;
- case 7:
- switch (freq_strobe_mode) {
- case 0:
- if (running_flag[2]) leds[NUM_LEDS / 2] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (running_flag[1]) leds[NUM_LEDS / 2] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (running_flag[0]) leds[NUM_LEDS / 2] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 1:
- if (running_flag[2]) leds[NUM_LEDS / 2] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 2:
- if (running_flag[1]) leds[NUM_LEDS / 2] = CHSV(MID_COLOR, 255, thisBright[1]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 3:
- if (running_flag[0]) leds[NUM_LEDS / 2] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- }
- leds[(NUM_LEDS / 2) - 1] = leds[NUM_LEDS / 2];
- if (millis() - running_timer > RUNNING_SPEED) {
- running_timer = millis();
- for (byte i = 0; i < NUM_LEDS / 2 - 1; i++) {
- leds[i] = leds[i + 1];
- leds[NUM_LEDS - i - 1] = leds[i];
- }
- }
- break;
- case 8:
- byte HUEindex = HUE_START;
- for (byte i = 0; i < NUM_LEDS / 2; i++) {
- byte this_bright = map(freq_f[(int)floor((NUM_LEDS / 2 - i) / freq_to_stripe)], 0, freq_max_f, 0, 255);
- this_bright = constrain(this_bright, 0, 255);
- leds[i] = CHSV(HUEindex, 255, this_bright);
- leds[NUM_LEDS - i - 1] = leds[i];
- HUEindex += HUE_STEP;
- if (HUEindex > 255) HUEindex = 0;
- }
- break;
- }
-}
-
-void HIGHS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
-}
-void MIDS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
-}
-void LOWS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
-}
-void SILENCE() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
-}
-
-// вспомогательная функция, изменяет величину value на шаг incr в пределах minimum.. maximum
-int smartIncr(int value, int incr_step, int mininmum, int maximum) {
- int val_buf = value + incr_step;
- val_buf = constrain(val_buf, mininmum, maximum);
- return val_buf;
-}
-
-float smartIncrFloat(float value, float incr_step, float mininmum, float maximum) {
- float val_buf = value + incr_step;
- val_buf = constrain(val_buf, mininmum, maximum);
- return val_buf;
-}
-
-void remoteTick() {
- if (ir_flag) { // если данные пришли
- eeprom_timer = millis();
- eeprom_flag = true;
- switch (results.value) {
- // режимы
- case BUTT_1: this_mode = 0;
- break;
- case BUTT_2: this_mode = 1;
- break;
- case BUTT_3: this_mode = 2;
- break;
- case BUTT_4: this_mode = 3;
- break;
- case BUTT_5: this_mode = 4;
- break;
- case BUTT_6: this_mode = 5;
- break;
- case BUTT_7: this_mode = 6;
- break;
- case BUTT_8: this_mode = 7;
- break;
- case BUTT_9: this_mode = 8;
- break;
- case BUTT_0: fullLowPass();
- break;
- case BUTT_STAR: ONstate = !ONstate; FastLED.clear(); FastLED.show(); updateEEPROM();
- break;
- case BUTT_HASH:
- switch (this_mode) {
- case 4:
- case 7: if (++freq_strobe_mode > 3) freq_strobe_mode = 0;
- break;
- case 6: if (++light_mode > 2) light_mode = 0;
- break;
- }
- break;
- case BUTT_OK: settings_mode = !settings_mode; digitalWrite(13, settings_mode);
- break;
- case BUTT_UP:
- if (settings_mode) {
- // ВВЕРХ общие настройки
- EMPTY_BRIGHT = smartIncr(EMPTY_BRIGHT, 5, 0, 255);
- } else {
- switch (this_mode) {
- case 0:
- break;
- case 1: RAINBOW_STEP = smartIncrFloat(RAINBOW_STEP, 0.5, 0.5, 20);
- break;
- case 2:
- case 3:
- case 4: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, 0.1, 0, 5);
- break;
- case 5: STROBE_PERIOD = smartIncr(STROBE_PERIOD, 20, 1, 1000);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_SAT = smartIncr(LIGHT_SAT, 20, 0, 255);
- break;
- case 1: LIGHT_SAT = smartIncr(LIGHT_SAT, 20, 0, 255);
- break;
- case 2: RAINBOW_STEP_2 = smartIncrFloat(RAINBOW_STEP_2, 0.5, 0.5, 10);
- break;
- }
- break;
- case 7: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, 0.1, 0.0, 10);
- break;
- case 8: HUE_START = smartIncr(HUE_START, 10, 0, 255);
- break;
- }
- }
- break;
- case BUTT_DOWN:
- if (settings_mode) {
- // ВНИЗ общие настройки
- EMPTY_BRIGHT = smartIncr(EMPTY_BRIGHT, -5, 0, 255);
- } else {
- switch (this_mode) {
- case 0:
- break;
- case 1: RAINBOW_STEP = smartIncrFloat(RAINBOW_STEP, -0.5, 0.5, 20);
- break;
- case 2:
- case 3:
- case 4: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, -0.1, 0, 5);
- break;
- case 5: STROBE_PERIOD = smartIncr(STROBE_PERIOD, -20, 1, 1000);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_SAT = smartIncr(LIGHT_SAT, -20, 0, 255);
- break;
- case 1: LIGHT_SAT = smartIncr(LIGHT_SAT, -20, 0, 255);
- break;
- case 2: RAINBOW_STEP_2 = smartIncrFloat(RAINBOW_STEP_2, -0.5, 0.5, 10);
- break;
- }
- break;
- case 7: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, -0.1, 0.0, 10);
- break;
- case 8: HUE_START = smartIncr(HUE_START, -10, 0, 255);
- break;
- }
- }
- break;
- case BUTT_LEFT:
- if (settings_mode) {
- // ВЛЕВО общие настройки
- BRIGHTNESS = smartIncr(BRIGHTNESS, -20, 0, 255);
- FastLED.setBrightness(BRIGHTNESS);
- } else {
- switch (this_mode) {
- case 0:
- case 1: SMOOTH = smartIncrFloat(SMOOTH, -0.05, 0.05, 1);
- break;
- case 2:
- case 3:
- case 4: SMOOTH_FREQ = smartIncrFloat(SMOOTH_FREQ, -0.05, 0.05, 1);
- break;
- case 5: STROBE_SMOOTH = smartIncr(STROBE_SMOOTH, -20, 0, 255);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_COLOR = smartIncr(LIGHT_COLOR, -10, 0, 255);
- break;
- case 1: COLOR_SPEED = smartIncr(COLOR_SPEED, -10, 0, 255);
- break;
- case 2: RAINBOW_PERIOD = smartIncr(RAINBOW_PERIOD, -1, -20, 20);
- break;
- }
- break;
- case 7: RUNNING_SPEED = smartIncr(RUNNING_SPEED, -10, 1, 255);
- break;
- case 8: HUE_STEP = smartIncr(HUE_STEP, -1, 1, 255);
- break;
- }
- }
- break;
- case BUTT_RIGHT:
- if (settings_mode) {
- // ВПРАВО общие настройки
- BRIGHTNESS = smartIncr(BRIGHTNESS, 20, 0, 255);
- FastLED.setBrightness(BRIGHTNESS);
- } else {
- switch (this_mode) {
- case 0:
- case 1: SMOOTH = smartIncrFloat(SMOOTH, 0.05, 0.05, 1);
- break;
- case 2:
- case 3:
- case 4: SMOOTH_FREQ = smartIncrFloat(SMOOTH_FREQ, 0.05, 0.05, 1);
- break;
- case 5: STROBE_SMOOTH = smartIncr(STROBE_SMOOTH, 20, 0, 255);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_COLOR = smartIncr(LIGHT_COLOR, 10, 0, 255);
- break;
- case 1: COLOR_SPEED = smartIncr(COLOR_SPEED, 10, 0, 255);
- break;
- case 2: RAINBOW_PERIOD = smartIncr(RAINBOW_PERIOD, 1, -20, 20);
- break;
- }
- break;
- case 7: RUNNING_SPEED = smartIncr(RUNNING_SPEED, 10, 1, 255);
- break;
- case 8: HUE_STEP = smartIncr(HUE_STEP, 1, 1, 255);
- break;
- }
- }
- break;
- default: eeprom_flag = false; // если не распознали кнопку, не обновляем настройки!
- break;
- }
- ir_flag = false;
- }
-}
-
-void checkIR() {
- while (irrecv.decode(&results)) {
- ir_flag = true;
- irrecv.resume();
- }
-}
-
-void autoLowPass() {
- // для режима VU
- delay(10); // ждём инициализации АЦП
- int thisMax = 0; // максимум
- int thisLevel;
- for (byte i = 0; i < 200; i++) {
- thisLevel = analogRead(SOUND_R); // делаем 200 измерений
- if (thisLevel > thisMax) // ищем максимумы
- thisMax = thisLevel; // запоминаем
- delay(4); // ждём 4мс
- }
- LOW_PASS = thisMax + LOW_PASS_ADD; // нижний порог как максимум тишины + некая величина
-
- // для режима спектра
- thisMax = 0;
- for (byte i = 0; i < 100; i++) { // делаем 100 измерений
- analyzeAudio(); // разбить в спектр
- for (byte j = 2; j < 32; j++) { // первые 2 канала - хлам
- thisLevel = fht_log_out[j];
- if (thisLevel > thisMax) // ищем максимумы
- thisMax = thisLevel; // запоминаем
- }
- delay(4); // ждём 4мс
- }
- SPEKTR_LOW_PASS = thisMax + LOW_PASS_FREQ_ADD; // нижний порог как максимум тишины
-
- if (EEPROM_LOW_PASS && !AUTO_LOW_PASS) {
- EEPROM.updateInt(70, LOW_PASS);
- EEPROM.updateInt(72, SPEKTR_LOW_PASS);
- }
-}
-
-void analyzeAudio() {
- for (int i = 0 ; i < FHT_N ; i++) {
- int sample = analogRead(SOUND_R_FREQ);
- fht_input[i] = sample; // put real data into bins
- }
- fht_window(); // window the data for better frequency response
- fht_reorder(); // reorder the data before doing the fht
- fht_run(); // process the data in the fht
- fht_mag_log(); // take the output of the fht
-}
-
-void buttonTick() {
- butt1.tick(); // обязательная функция отработки. Должна постоянно опрашиваться
- if (butt1.isSingle()) // если единичное нажатие
- if (++this_mode >= MODE_AMOUNT) this_mode = 0; // изменить режим
-
- if (butt1.isHolded()) { // кнопка удержана
- fullLowPass();
- }
-}
-void fullLowPass() {
- digitalWrite(13, HIGH); // включить светодиод 13 пин
- FastLED.setBrightness(0); // погасить ленту
- FastLED.clear(); // очистить массив пикселей
- FastLED.show(); // отправить значения на ленту
- delay(500); // подождать чутка
- autoLowPass(); // измерить шумы
- delay(500); // подождать
- FastLED.setBrightness(BRIGHTNESS); // вернуть яркость
- digitalWrite(13, LOW); // выключить светодиод
-}
-void updateEEPROM() {
- EEPROM.updateByte(1, this_mode);
- EEPROM.updateByte(2, freq_strobe_mode);
- EEPROM.updateByte(3, light_mode);
- EEPROM.updateInt(4, RAINBOW_STEP);
- EEPROM.updateFloat(8, MAX_COEF_FREQ);
- EEPROM.updateInt(12, STROBE_PERIOD);
- EEPROM.updateInt(16, LIGHT_SAT);
- EEPROM.updateFloat(20, RAINBOW_STEP_2);
- EEPROM.updateInt(24, HUE_START);
- EEPROM.updateFloat(28, SMOOTH);
- EEPROM.updateFloat(32, SMOOTH_FREQ);
- EEPROM.updateInt(36, STROBE_SMOOTH);
- EEPROM.updateInt(40, LIGHT_COLOR);
- EEPROM.updateInt(44, COLOR_SPEED);
- EEPROM.updateInt(48, RAINBOW_PERIOD);
- EEPROM.updateInt(52, RUNNING_SPEED);
- EEPROM.updateInt(56, HUE_STEP);
- EEPROM.updateInt(60, EMPTY_BRIGHT);
-}
-void readEEPROM() {
- this_mode = EEPROM.readByte(1);
- freq_strobe_mode = EEPROM.readByte(2);
- light_mode = EEPROM.readByte(3);
- RAINBOW_STEP = EEPROM.readInt(4);
- MAX_COEF_FREQ = EEPROM.readFloat(8);
- STROBE_PERIOD = EEPROM.readInt(12);
- LIGHT_SAT = EEPROM.readInt(16);
- RAINBOW_STEP_2 = EEPROM.readFloat(20);
- HUE_START = EEPROM.readInt(24);
- SMOOTH = EEPROM.readFloat(28);
- SMOOTH_FREQ = EEPROM.readFloat(32);
- STROBE_SMOOTH = EEPROM.readInt(36);
- LIGHT_COLOR = EEPROM.readInt(40);
- COLOR_SPEED = EEPROM.readInt(44);
- RAINBOW_PERIOD = EEPROM.readInt(48);
- RUNNING_SPEED = EEPROM.readInt(52);
- HUE_STEP = EEPROM.readInt(56);
- EMPTY_BRIGHT = EEPROM.readInt(60);
-}
-void eepromTick() {
- if (eeprom_flag)
- if (millis() - eeprom_timer > 30000) { // 30 секунд после последнего нажатия с пульта
- eeprom_flag = false;
- eeprom_timer = millis();
- updateEEPROM();
- }
-}
diff --git a/firmware/Old versions/colorMusic_v2.5_KEYES/colorMusic_v2.5_KEYES.ino b/firmware/Old versions/colorMusic_v2.5_KEYES/colorMusic_v2.5_KEYES.ino
deleted file mode 100644
index 5ffd3d2..0000000
--- a/firmware/Old versions/colorMusic_v2.5_KEYES/colorMusic_v2.5_KEYES.ino
+++ /dev/null
@@ -1,997 +0,0 @@
-/*
- Версия 2.5 использует библиотеки Adafruit_NeoPixel и IRLremote вместо FastLED и IRremote
- Библиотеки идут в архиве с проектом! https://alexgyver.ru/colormusic/
- Крутейшая свето-цветомузыка на Arduino и адресной светодиодной ленте WS2812b.
- Данная версия поддерживает около 410 светодиодов!
- Версия для ИК пульта KEYES
- Управление:
- - Однократное нажатие кнопки: смена режима
- - Удержание кнопки: калибровка нижнего порога шума
- Режимы работы (переключаются кнопкой):
- - VU meter (столбик громкости): от зелёного к красному
- - VU meter (столбик громкости): плавно бегущая радуга
- - Светомузыка по частотам: 5 полос симметрично
- - Светомузыка по частотам: 3 полосы
- - Светомузыка по частотам: 1 полоса
- - Стробоскоп
- - Подсветка
- - Бегущие частоты
- - Анализатор спектра
- Особенности:
- - Плавная анимация (можно настроить)
- - Автонастройка по громкости (можно настроить)
- - Фильтр нижнего шума (можно настроить)
- - Автокалибровка шума при запуске (можно настроить)
- - Поддержка стерео и моно звука (можно настроить)
- - В режиме частот лента не гаснет полностью (EMPTY_BRIGHT)
- - Все настройки сохраняются в памяти и не сбрасываются при перезагрузке
- - Сохранение настроек происходит при выключении кнопкой звёздочка (*)
- - А также через 30 секунд после последнего нажатия на любую кнопку ИК пульта
-
- НАСТРОЙКА НИЖНЕГО ПОРОГА ШУМА (строки 65-71)
- - Включаем систему
- - Ставим музыку на паузу
- - Удерживаем кнопку 1 секунду ИЛИ жмём кнопку 0 на пульте
- Значения шумов будут записаны в память и САМИ загружаться при последующем запуске! Всё!
-
- Пульт:
- - Цифры (1 - 9) активируют режимы
- - Цифра 0: калибровка шума
- - Звёздочка (*): включить/выключить систему
- - Кнопка ОК: переключение между локальными и глобальными настройками)
- - Решётка (#): смена подрежима
- - Глобальные настройки (горит светодиод на плате):
- + Стрелки ← →: общая яркость горящих светодиодов
- + Стрелки ↑ ↓: яркость "не горящих" светодиодов
- - Локальные настройки (у каждого режима свои):
- 1 - Шкала громкости (градиент)
- Стрелки ← →: плавность анимации
- 2 - Шкала громкости (радуга)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: скорость радуги
- 3 - Цветомузыка (5 полос)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- 4 - Цветомузыка (3 полосы)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- 5 - Цветомузыка (1 полоса)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- Подрежимы #: 3 частоты / низкие / средние / высокие
- 6 - Стробоскоп
- Стрелки ← →: плавность вспышек
- Стрелки ↑ ↓: частота вспышек
- 7 - Цветная подсветка
- Подрежимы #:
- Постоянный: стрелки ← →: цвет, стрелки ↑ ↓: насыщенность
- Плавная смена: стрелки ← →: скорость, стрелки ↑ ↓: насыщенность
- Бегущая радуга: стрелки ← →: скорость, стрелки ↑ ↓: шаг радуги
- 8 - “Бегущие частоты”
- Стрелки ← →: скорость
- Стрелки ↑ ↓: чувствительность
- Подрежимы #: 3 частоты / низкие / средние / высокие
- 9 - Анализатор спектра
- Стрелки ← →: шаг цвета
- Стрелки ↑ ↓: цвет
- **************************************************
- Разработано: AlexGyver
- Страница проекта: http://alexgyver.ru/colormusic/
- GitHub: https://github.com/AlexGyver/ColorMusic
-*/
-
-// --------------------------- НАСТРОЙКИ ---------------------------
-#define KEEP_SETTINGS 1 // хранить ВСЕ настройки в памяти
-#define RESET_SETTINGS 0 // сброс настроек в памяти.
-// поставить 1. Прошиться. Поставить обратно 0. Прошиться. Всё.
-
-// лента
-#define NUM_LEDS 310 // количество светодиодов
-byte BRIGHTNESS = 200; // яркость (0 - 255)
-
-// пины
-#define SOUND_R A2 // аналоговый пин вход аудио, правый канал
-#define SOUND_L A1 // аналоговый пин вход аудио, левый канал
-#define SOUND_R_FREQ A3 // аналоговый пин вход аудио для режима с частотами (через кондер)
-#define BTN_PIN 3 // кнопка переключения режимов (PIN --- КНОПКА --- GND)
-#define LED_PIN 12 // пин DI светодиодной ленты
-#define POT_GND A0 // пин земля для потенциометра
-#define IR_PIN 2 // ИК приёмник
-
-// настройки радуги
-float RAINBOW_STEP = 5.5; // шаг изменения цвета радуги
-
-// отрисовка
-#define MODE 0 // режим при запуске
-#define MAIN_LOOP 5 // период основного цикла отрисовки (по умолчанию 5)
-
-// сигнал
-#define MONO 1 // 1 - только один канал (ПРАВЫЙ!!!!! SOUND_R!!!!!), 0 - два канала
-#define EXP 1.4 // степень усиления сигнала (для более "резкой" работы) (по умолчанию 1.4)
-#define POTENT 1 // 1 - используем потенциометр, 0 - используется внутренний источник опорного напряжения 1.1 В
-byte EMPTY_BRIGHT = 30; // яркость "не горящих" светодиодов (0 - 255)
-#define EMPTY_COLOR HUE_PURPLE // цвет "не горящих" светодиодов. Будет чёрный, если яркость 0
-
-// нижний порог шумов
-byte LOW_PASS = 100; // нижний порог шумов режим VU, ручная настройка
-byte SPEKTR_LOW_PASS = 40; // нижний порог шумов режим спектра, ручная настройка
-#define AUTO_LOW_PASS 0 // разрешить настройку нижнего порога шумов при запуске (по умолч. 0)
-#define EEPROM_LOW_PASS 1 // порог шумов хранится в энергонезависимой памяти (по умолч. 1)
-#define LOW_PASS_ADD 13 // "добавочная" величина к нижнему порогу, для надёжности (режим VU)
-#define LOW_PASS_FREQ_ADD 3 // "добавочная" величина к нижнему порогу, для надёжности (режим частот)
-
-// шкала громкости
-float SMOOTH = 0.5; // коэффициент плавности анимации VU (по умолчанию 0.5)
-#define MAX_COEF 1.8 // коэффициент громкости (максимальное равно срднему * этот коэф) (по умолчанию 1.8)
-
-// режим цветомузыки
-float SMOOTH_FREQ = 0.8; // коэффициент плавности анимации частот (по умолчанию 0.8)
-float MAX_COEF_FREQ = 1.2; // коэффициент порога для "вспышки" цветомузыки (по умолчанию 1.5)
-#define SMOOTH_STEP 20 // шаг уменьшения яркости в режиме цветомузыки (чем больше, тем быстрее гаснет)
-#define LOW_COLOR HUE_RED // цвет низких частот
-#define MID_COLOR HUE_GREEN // цвет средних
-#define HIGH_COLOR HUE_YELLOW // цвет высоких
-
-// режим стробоскопа
-int STROBE_PERIOD = 100; // период вспышек, миллисекунды
-#define STROBE_DUTY 20 // скважность вспышек (1 - 99) - отношение времени вспышки ко времени темноты
-#define STROBE_COLOR HUE_YELLOW // цвет стробоскопа
-#define STROBE_SAT 0 // насыщенность. Если 0 - цвет будет БЕЛЫЙ при любом цвете (0 - 255)
-byte STROBE_SMOOTH = 100; // скорость нарастания/угасания вспышки (0 - 255)
-
-// режим подсветки
-byte LIGHT_COLOR = 0; // начальный цвет подсветки
-byte LIGHT_SAT = 200; // начальная насыщенность подсветки
-byte COLOR_SPEED = 100;
-int RAINBOW_PERIOD = 3;
-float RAINBOW_STEP_2 = 5.5;
-
-// режим бегущих частот
-byte RUNNING_SPEED = 60;
-
-// режим анализатора спектра
-byte HUE_START = 0;
-byte HUE_STEP = 5;
-#define LIGHT_SMOOTH 2
-
-/*
- Цвета для HSV
- HUE_RED
- HUE_ORANGE
- HUE_YELLOW
- HUE_GREEN
- HUE_AQUA
- HUE_BLUE
- HUE_PURPLE
- HUE_PINK
-*/
-// --------------------------- НАСТРОЙКИ ---------------------------
-
-// ----- КНОПКИ ПУЛЬТА -----
-#define BUTT_UP 0xE51CA6AD
-#define BUTT_DOWN 0xD22353AD
-#define BUTT_LEFT 0x517068AD
-#define BUTT_RIGHT 0xAC2A56AD
-#define BUTT_OK 0x1B92DDAD
-#define BUTT_1 0x68E456AD
-#define BUTT_2 0xF08A26AD
-#define BUTT_3 0x151CD6AD
-#define BUTT_4 0x18319BAD
-#define BUTT_5 0xF39EEBAD
-#define BUTT_6 0x4AABDFAD
-#define BUTT_7 0xE25410AD
-#define BUTT_8 0x297C76AD
-#define BUTT_9 0x14CE54AD
-#define BUTT_0 0xC089F6AD
-#define BUTT_STAR 0xAF3F1BAD
-#define BUTT_HASH 0x38379AD
-// ----- КНОПКИ ПУЛЬТА -----
-
-// ------------------------------ ДЛЯ РАЗРАБОТЧИКОВ --------------------------------
-#define MODE_AMOUNT 9 // количество режимов
-
-// цвета HSV
-#define HUE_RED 0
-#define HUE_ORANGE 12
-#define HUE_YELLOW 44
-#define HUE_GREEN 85
-#define HUE_AQUA 128
-#define HUE_BLUE 171
-#define HUE_PURPLE 213
-#define HUE_PINK 244
-
-#define STRIPE NUM_LEDS / 5
-float freq_to_stripe = NUM_LEDS / 40; // /2 так как симметрия, и /20 так как 20 частот
-
-#define FHT_N 64 // ширина спектра х2
-#define LOG_OUT 1
-#include // преобразование Хартли
-
-#include
-
-#include "Adafruit_NeoPixel.h"
-Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
-
-#include "GyverButton.h"
-GButton butt1(BTN_PIN);
-
-#include "IRLremote.h"
-CHashIR IRLremote;
-uint32_t IRdata;
-
-byte Rlenght, Llenght;
-float RsoundLevel, RsoundLevel_f;
-float LsoundLevel, LsoundLevel_f;
-
-float averageLevel = 50;
-int maxLevel = 100;
-byte MAX_CH = NUM_LEDS / 2;
-int hue;
-unsigned long main_timer, hue_timer, strobe_timer, running_timer, color_timer, rainbow_timer, eeprom_timer;
-float averK = 0.006;
-byte count;
-float index = (float)(HUE_GREEN - HUE_RED) / MAX_CH; // коэффициент перевода для палитры зеленый-красный
-float index2 = (float)255 / MAX_CH; // коэффициент перевода для радуги
-boolean lowFlag;
-byte low_pass;
-int RcurrentLevel, LcurrentLevel;
-int colorMusic[3];
-float colorMusic_f[3], colorMusic_aver[3];
-boolean colorMusicFlash[3], strobeUp_flag, strobeDwn_flag;
-byte this_mode = MODE;
-int thisBright[3], strobe_bright = 0;
-unsigned int light_time = STROBE_PERIOD * STROBE_DUTY / 100;
-volatile boolean ir_flag;
-boolean settings_mode, ONstate = true;
-int8_t freq_strobe_mode, light_mode;
-int freq_max;
-float freq_max_f, rainbow_steps;
-int freq_f[32];
-int this_color;
-boolean running_flag[3], eeprom_flag;
-
-#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
-#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
-// ------------------------------ ДЛЯ РАЗРАБОТЧИКОВ --------------------------------
-
-void setup() {
- Serial.begin(9600);
-
- strip.begin();
- strip.setBrightness(BRIGHTNESS);
-
- pinMode(13, OUTPUT);
- digitalWrite(13, LOW);
-
- pinMode(POT_GND, OUTPUT);
- digitalWrite(POT_GND, LOW);
- butt1.setTimeout(900);
-
- IRLremote.begin(IR_PIN);
-
- // для увеличения точности уменьшаем опорное напряжение,
- // выставив EXTERNAL и подключив Aref к выходу 3.3V на плате через делитель
- // GND ---[10-20 кОм] --- REF --- [10 кОм] --- 3V3
- // в данной схеме GND берётся из А0 для удобства подключения
- if (POTENT) analogReference(EXTERNAL);
- else analogReference(INTERNAL);
-
- // жуткая магия, меняем частоту оцифровки до 18 кГц
- // команды на ебучем ассемблере, даже не спрашивайте, как это работает
- sbi(ADCSRA, ADPS2);
- cbi(ADCSRA, ADPS1);
- sbi(ADCSRA, ADPS0);
-
- if (RESET_SETTINGS) EEPROM.write(100, 0); // сброс флага настроек
-
- if (AUTO_LOW_PASS && !EEPROM_LOW_PASS) { // если разрешена автонастройка нижнего порога шумов
- autoLowPass();
- }
- if (EEPROM_LOW_PASS) { // восстановить значения шумов из памяти
- LOW_PASS = EEPROM.readInt(70);
- SPEKTR_LOW_PASS = EEPROM.readInt(72);
- }
-
- // в 100 ячейке хранится число 100. Если нет - значит это первый запуск системы
- if (KEEP_SETTINGS) {
- if (EEPROM.read(100) != 100) {
- //Serial.println(F("First start"));
- EEPROM.write(100, 100);
- updateEEPROM();
- } else {
- readEEPROM();
- }
- }
-}
-
-void loop() {
- buttonTick(); // опрос и обработка кнопки
- remoteTick(); // опрос ИК пульта
- mainLoop(); // главный цикл обработки и отрисовки
- eepromTick(); // проверка не пора ли сохранить настройки
-}
-
-void mainLoop() {
- // главный цикл отрисовки
- if (ONstate) {
- if (millis() - main_timer > MAIN_LOOP) {
- // сбрасываем значения
- RsoundLevel = 0;
- LsoundLevel = 0;
-
- // перваые два режима - громкость (VU meter)
- if (this_mode == 0 || this_mode == 1) {
- for (byte i = 0; i < 100; i ++) { // делаем 100 измерений
- RcurrentLevel = analogRead(SOUND_R); // с правого
- if (!MONO) LcurrentLevel = analogRead(SOUND_L); // и левого каналов
-
- if (RsoundLevel < RcurrentLevel) RsoundLevel = RcurrentLevel; // ищем максимальное
- if (!MONO) if (LsoundLevel < LcurrentLevel) LsoundLevel = LcurrentLevel; // ищем максимальное
- }
-
- // фильтруем по нижнему порогу шумов
- RsoundLevel = map(RsoundLevel, LOW_PASS, 1023, 0, 500);
- if (!MONO)LsoundLevel = map(LsoundLevel, LOW_PASS, 1023, 0, 500);
-
- // ограничиваем диапазон
- RsoundLevel = constrain(RsoundLevel, 0, 500);
- if (!MONO)LsoundLevel = constrain(LsoundLevel, 0, 500);
-
- // возводим в степень (для большей чёткости работы)
- RsoundLevel = pow(RsoundLevel, EXP);
- if (!MONO)LsoundLevel = pow(LsoundLevel, EXP);
-
- // фильтр
- RsoundLevel_f = RsoundLevel * SMOOTH + RsoundLevel_f * (1 - SMOOTH);
- if (!MONO)LsoundLevel_f = LsoundLevel * SMOOTH + LsoundLevel_f * (1 - SMOOTH);
-
- if (MONO) LsoundLevel_f = RsoundLevel_f; // если моно, то левый = правому
-
- // заливаем "подложку", если яркость достаточная
- if (EMPTY_BRIGHT > 5) {
- for (int i = 0; i < NUM_LEDS; i++)
- setPixelHSV(i, EMPTY_COLOR, 255, EMPTY_BRIGHT);
- }
-
- // если значение выше порога - начинаем самое интересное
- if (RsoundLevel_f > 15 && LsoundLevel_f > 15) {
-
- // расчёт общей средней громкости с обоих каналов, фильтрация.
- // Фильтр очень медленный, сделано специально для автогромкости
- averageLevel = (float)(RsoundLevel_f + LsoundLevel_f) / 2 * averK + averageLevel * (1 - averK);
-
- // принимаем максимальную громкость шкалы как среднюю, умноженную на некоторый коэффициент MAX_COEF
- maxLevel = (float)averageLevel * MAX_COEF;
-
- // преобразуем сигнал в длину ленты (где MAX_CH это половина количества светодиодов)
- Rlenght = map(RsoundLevel_f, 0, maxLevel, 0, MAX_CH);
- Llenght = map(LsoundLevel_f, 0, maxLevel, 0, MAX_CH);
-
- // ограничиваем до макс. числа светодиодов
- Rlenght = constrain(Rlenght, 0, MAX_CH);
- Llenght = constrain(Llenght, 0, MAX_CH);
-
- animation(); // отрисовать
- }
- }
-
- // 3-5 режим - цветомузыка
- if (this_mode == 2 || this_mode == 3 || this_mode == 4 || this_mode == 7 || this_mode == 8) {
- analyzeAudio();
- colorMusic[0] = 0;
- colorMusic[1] = 0;
- colorMusic[2] = 0;
- for (int i = 0 ; i < 32 ; i++) {
- if (fht_log_out[i] < SPEKTR_LOW_PASS) fht_log_out[i] = 0;
- }
- // низкие частоты, выборка со 2 по 5 тон (0 и 1 зашумленные!)
- for (byte i = 2; i < 6; i++) {
- if (fht_log_out[i] > colorMusic[0]) colorMusic[0] = fht_log_out[i];
- }
- // средние частоты, выборка с 6 по 10 тон
- for (byte i = 6; i < 11; i++) {
- if (fht_log_out[i] > colorMusic[1]) colorMusic[1] = fht_log_out[i];
- }
- // высокие частоты, выборка с 11 по 31 тон
- for (byte i = 11; i < 32; i++) {
- if (fht_log_out[i] > colorMusic[2]) colorMusic[2] = fht_log_out[i];
- }
- freq_max = 0;
- for (byte i = 0; i < 30; i++) {
- if (fht_log_out[i + 2] > freq_max) freq_max = fht_log_out[i + 2];
- if (freq_max < 5) freq_max = 5;
-
- if (freq_f[i] < fht_log_out[i + 2]) freq_f[i] = fht_log_out[i + 2];
- if (freq_f[i] > 0) freq_f[i] -= LIGHT_SMOOTH;
- else freq_f[i] = 0;
- }
- freq_max_f = freq_max * averK + freq_max_f * (1 - averK);
- for (byte i = 0; i < 3; i++) {
- colorMusic_aver[i] = colorMusic[i] * averK + colorMusic_aver[i] * (1 - averK); // общая фильтрация
- colorMusic_f[i] = colorMusic[i] * SMOOTH_FREQ + colorMusic_f[i] * (1 - SMOOTH_FREQ); // локальная
- if (colorMusic_f[i] > ((float)colorMusic_aver[i] * MAX_COEF_FREQ)) {
- thisBright[i] = 255;
- colorMusicFlash[i] = true;
- running_flag[i] = true;
- } else colorMusicFlash[i] = false;
- if (thisBright[i] >= 0) thisBright[i] -= SMOOTH_STEP;
- if (thisBright[i] < EMPTY_BRIGHT) {
- thisBright[i] = EMPTY_BRIGHT;
- running_flag[i] = false;
- }
- }
- animation();
- }
- if (this_mode == 5) {
- if ((long)millis() - strobe_timer > STROBE_PERIOD) {
- strobe_timer = millis();
- strobeUp_flag = true;
- strobeDwn_flag = false;
- }
- if ((long)millis() - strobe_timer > light_time) {
- strobeDwn_flag = true;
- }
- if (strobeUp_flag) { // если настало время пыхнуть
- if (strobe_bright < 255) // если яркость не максимальная
- strobe_bright += STROBE_SMOOTH; // увелчить
- if (strobe_bright > 255) { // если пробили макс. яркость
- strobe_bright = 255; // оставить максимум
- strobeUp_flag = false; // флаг опустить
- }
- }
-
- if (strobeDwn_flag) { // гаснем
- if (strobe_bright > 0) // если яркость не минимальная
- strobe_bright -= STROBE_SMOOTH; // уменьшить
- if (strobe_bright < 0) { // если пробили мин. яркость
- strobeDwn_flag = false;
- strobe_bright = 0; // оставить 0
- }
- }
- animation();
- }
- if (this_mode == 6) animation();
-
- if (!IRLremote.receiving()) // если на ИК приёмник не приходит сигнал (без этого НЕ РАБОТАЕТ!)
- strip.show(); // отправить значения на ленту
-
- if (this_mode != 7) // 7 режиму не нужна очистка!!!
- strip.clear(); // очистить массив пикселей
- main_timer = millis(); // сбросить таймер
- }
- }
-}
-
-void animation() {
- // согласно режиму
- switch (this_mode) {
- case 0:
- count = 0;
- for (int i = (MAX_CH - 1); i > ((MAX_CH - 1) - Rlenght); i--) {
- setPixelHSV(i, HUE_GREEN - count * index, 255, 255);
- count++;
- }
- count = 0;
- for (int i = (MAX_CH); i < (MAX_CH + Llenght); i++ ) {
- setPixelHSV(i, HUE_GREEN - count * index, 255, 255);
- count++;
- }
- if (EMPTY_BRIGHT > 0) {
- for (int i = ((MAX_CH - 1) - Rlenght); i > 0; i--)
- setPixelHSV(i, EMPTY_COLOR, 255, EMPTY_BRIGHT);
- for (int i = MAX_CH + Llenght; i < NUM_LEDS; i++)
- setPixelHSV(i, EMPTY_COLOR, 255, EMPTY_BRIGHT);
- }
- break;
- case 1:
- if (millis() - rainbow_timer > 35) {
- rainbow_timer = millis();
- hue = floor((float)hue + RAINBOW_STEP);
- if (hue > 255) hue = 0;
- }
- count = 0;
- for (int i = (MAX_CH - 1); i > ((MAX_CH - 1) - Rlenght); i--) {
- setPixelHSV(i, (count * index) / 2 - hue, 255, 255);
- count++;
- }
- count = 0;
- for (int i = (MAX_CH); i < (MAX_CH + Llenght); i++ ) {
- setPixelHSV(i, (count * index) / 2 - hue, 255, 255);
- count++;
- }
- if (EMPTY_BRIGHT > 0) {
- for (int i = ((MAX_CH - 1) - Rlenght); i > 0; i--)
- setPixelHSV(i, EMPTY_COLOR, 255, EMPTY_BRIGHT);
- for (int i = MAX_CH + Llenght; i < NUM_LEDS; i++)
- setPixelHSV(i, EMPTY_COLOR, 255, EMPTY_BRIGHT);
- }
- break;
- case 2:
- for (int i = 0; i < NUM_LEDS; i++) {
- if (i < STRIPE) setPixelHSV(i, HIGH_COLOR, 255, thisBright[2]);
- else if (i < STRIPE * 2) setPixelHSV(i, MID_COLOR, 255, thisBright[1]);
- else if (i < STRIPE * 3) setPixelHSV(i, LOW_COLOR, 255, thisBright[0]);
- else if (i < STRIPE * 4) setPixelHSV(i, MID_COLOR, 255, thisBright[1]);
- else if (i < STRIPE * 5) setPixelHSV(i, HIGH_COLOR, 255, thisBright[2]);
- }
- break;
- case 3:
- for (int i = 0; i < NUM_LEDS; i++) {
- if (i < NUM_LEDS / 3) setPixelHSV(i, HIGH_COLOR, 255, thisBright[2]);
- else if (i < NUM_LEDS * 2 / 3) setPixelHSV(i, MID_COLOR, 255, thisBright[1]);
- else if (i < NUM_LEDS) setPixelHSV(i, LOW_COLOR, 255, thisBright[0]);
- }
- break;
- case 4:
- switch (freq_strobe_mode) {
- case 0:
- if (colorMusicFlash[2]) HIGHS();
- else if (colorMusicFlash[1]) MIDS();
- else if (colorMusicFlash[0]) LOWS();
- else SILENCE();
- break;
- case 1:
- if (colorMusicFlash[2]) HIGHS();
- else SILENCE();
- break;
- case 2:
- if (colorMusicFlash[1]) MIDS();
- else SILENCE();
- break;
- case 3:
- if (colorMusicFlash[0]) LOWS();
- else SILENCE();
- break;
- }
- break;
- case 5:
- if (strobe_bright > 0) {
- setPixelHSV(0, STROBE_COLOR, STROBE_SAT, strobe_bright);
- uint32_t new_color = strip.getPixelColor(0);
- for (int i = 1; i < NUM_LEDS; i++) strip.setPixelColor(i, new_color);
- } else {
- setPixelHSV(0, EMPTY_COLOR, 255, EMPTY_BRIGHT);
- uint32_t new_color = strip.getPixelColor(0);
- for (int i = 1; i < NUM_LEDS; i++) strip.setPixelColor(i, new_color);
- }
- break;
- case 6:
- switch (light_mode) {
- case 0: for (int i = 0; i < NUM_LEDS; i++) setPixelHSV(i, LIGHT_COLOR, LIGHT_SAT, 255);
- break;
- case 1:
- if (millis() - color_timer > COLOR_SPEED) {
- color_timer = millis();
- if (++this_color > 255) this_color = 0;
- }
- for (int i = 0; i < NUM_LEDS; i++) setPixelHSV(i, this_color, LIGHT_SAT, 255);
- break;
- case 2:
- if (millis() - rainbow_timer > 35) {
- rainbow_timer = millis();
- this_color += RAINBOW_PERIOD;
- if (this_color > 255) this_color = 0;
- if (this_color < 0) this_color = 255;
- }
- rainbow_steps = this_color;
- for (int i = 0; i < NUM_LEDS; i++) {
- setPixelHSV(i, (int)floor(rainbow_steps), 255, 255);
- rainbow_steps += RAINBOW_STEP_2;
- if (rainbow_steps > 255) rainbow_steps = 0;
- if (rainbow_steps < 0) rainbow_steps = 255;
- }
- break;
- }
- break;
- case 7:
- switch (freq_strobe_mode) {
- case 0:
- if (running_flag[2]) setPixelHSV(NUM_LEDS / 2, HIGH_COLOR, 255, thisBright[2]);
- else if (running_flag[1]) setPixelHSV(NUM_LEDS / 2, MID_COLOR, 255, thisBright[1]);
- else if (running_flag[0]) setPixelHSV(NUM_LEDS / 2, LOW_COLOR, 255, thisBright[0]);
- else setPixelHSV(NUM_LEDS / 2, EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 1:
- if (running_flag[2]) setPixelHSV(NUM_LEDS / 2, HIGH_COLOR, 255, thisBright[2]);
- else setPixelHSV(NUM_LEDS / 2, EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 2:
- if (running_flag[1]) setPixelHSV(NUM_LEDS / 2, MID_COLOR, 255, thisBright[1]);
- else setPixelHSV(NUM_LEDS / 2, EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 3:
- if (running_flag[0]) setPixelHSV(NUM_LEDS / 2, LOW_COLOR, 255, thisBright[0]);
- else setPixelHSV(NUM_LEDS / 2, EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- }
- strip.setPixelColor((NUM_LEDS / 2) - 1, strip.getPixelColor(NUM_LEDS / 2));
- if (millis() - running_timer > RUNNING_SPEED) {
- running_timer = millis();
- for (byte i = 0; i < NUM_LEDS / 2 - 1; i++) {
- strip.setPixelColor(i, strip.getPixelColor(i + 1));
- strip.setPixelColor(NUM_LEDS - i - 1, strip.getPixelColor(i));
- }
- }
- break;
- case 8:
- byte HUEindex = HUE_START;
- for (byte i = 0; i < NUM_LEDS / 2; i++) {
- byte this_bright = map(freq_f[(int)floor((NUM_LEDS / 2 - i) / freq_to_stripe)], 0, freq_max_f, 0, 255);
- this_bright = constrain(this_bright, 0, 255);
- setPixelHSV(i, HUEindex, 255, this_bright);
- setPixelHSV(NUM_LEDS - i - 1, HUEindex, 255, this_bright);
- HUEindex += HUE_STEP;
- if (HUEindex > 255) HUEindex = 0;
- }
- break;
- }
-}
-
-void HIGHS() {
- for (int i = 0; i < NUM_LEDS; i++) setPixelHSV(i, HIGH_COLOR, 255, thisBright[2]);
-}
-void MIDS() {
- for (int i = 0; i < NUM_LEDS; i++) setPixelHSV(i, MID_COLOR, 255, thisBright[1]);
-}
-void LOWS() {
- for (int i = 0; i < NUM_LEDS; i++) setPixelHSV(i, LOW_COLOR, 255, thisBright[0]);
-}
-void SILENCE() {
- for (int i = 0; i < NUM_LEDS; i++) setPixelHSV(i, EMPTY_COLOR, 255, EMPTY_BRIGHT);
-}
-
-// вспомогательная функция, изменяет величину value на шаг incr в пределах minimum.. maximum
-int smartIncr(int value, int incr_step, int mininmum, int maximum) {
- int val_buf = value + incr_step;
- val_buf = constrain(val_buf, mininmum, maximum);
- //Serial.println(val_buf);
- return val_buf;
-}
-
-float smartIncrFloat(float value, float incr_step, float mininmum, float maximum) {
- float val_buf = value + incr_step;
- val_buf = constrain(val_buf, mininmum, maximum);
- //Serial.println(val_buf);
- return val_buf;
-}
-
-void remoteTick() {
- if (IRLremote.available()) {
- auto data = IRLremote.read();
- IRdata = data.command;
- ir_flag = true;
- }
-
- if (ir_flag) { // если данные пришли
- eeprom_timer = millis();
- eeprom_flag = true;
- switch (IRdata) {
- // режимы
- case BUTT_1: this_mode = 0;
- break;
- case BUTT_2: this_mode = 1;
- break;
- case BUTT_3: this_mode = 2;
- break;
- case BUTT_4: this_mode = 3;
- break;
- case BUTT_5: this_mode = 4;
- break;
- case BUTT_6: this_mode = 5;
- break;
- case BUTT_7: this_mode = 6;
- break;
- case BUTT_8: this_mode = 7;
- break;
- case BUTT_9: this_mode = 8;
- break;
- case BUTT_0: fullLowPass();
- break;
- case BUTT_STAR: ONstate = !ONstate; strip.clear(); strip.show(); updateEEPROM();
- break;
- case BUTT_HASH:
- switch (this_mode) {
- case 4:
- case 7: if (++freq_strobe_mode > 3) freq_strobe_mode = 0;
- break;
- case 6: if (++light_mode > 2) light_mode = 0;
- break;
- }
- break;
- case BUTT_OK: settings_mode = !settings_mode; digitalWrite(13, settings_mode);
- break;
- case BUTT_UP:
- if (settings_mode) {
- // ВВЕРХ общие настройки
- EMPTY_BRIGHT = smartIncr(EMPTY_BRIGHT, 5, 0, 255);
- } else {
- switch (this_mode) {
- case 0:
- break;
- case 1: RAINBOW_STEP = smartIncrFloat(RAINBOW_STEP, 0.5, 0.5, 20);
- break;
- case 2:
- case 3:
- case 4: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, 0.1, 0, 5);
- break;
- case 5: STROBE_PERIOD = smartIncr(STROBE_PERIOD, 20, 1, 1000);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_SAT = smartIncr(LIGHT_SAT, 20, 0, 255);
- break;
- case 1: LIGHT_SAT = smartIncr(LIGHT_SAT, 20, 0, 255);
- break;
- case 2: RAINBOW_STEP_2 = smartIncrFloat(RAINBOW_STEP_2, 0.5, 0.5, 10);
- break;
- }
- break;
- case 7: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, 0.1, 0.0, 10);
- break;
- case 8: HUE_START = smartIncr(HUE_START, 10, 0, 255);
- break;
- }
- }
- break;
- case BUTT_DOWN:
- if (settings_mode) {
- // ВНИЗ общие настройки
- EMPTY_BRIGHT = smartIncr(EMPTY_BRIGHT, -5, 0, 255);
- } else {
- switch (this_mode) {
- case 0:
- break;
- case 1: RAINBOW_STEP = smartIncrFloat(RAINBOW_STEP, -0.5, 0.5, 20);
- break;
- case 2:
- case 3:
- case 4: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, -0.1, 0, 5);
- break;
- case 5: STROBE_PERIOD = smartIncr(STROBE_PERIOD, -20, 1, 1000);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_SAT = smartIncr(LIGHT_SAT, -20, 0, 255);
- break;
- case 1: LIGHT_SAT = smartIncr(LIGHT_SAT, -20, 0, 255);
- break;
- case 2: RAINBOW_STEP_2 = smartIncrFloat(RAINBOW_STEP_2, -0.5, 0.5, 10);
- break;
- }
- break;
- case 7: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, -0.1, 0.0, 10);
- break;
- case 8: HUE_START = smartIncr(HUE_START, -10, 0, 255);
- break;
- }
- }
- break;
- case BUTT_LEFT:
- if (settings_mode) {
- // ВЛЕВО общие настройки
- BRIGHTNESS = smartIncr(BRIGHTNESS, -20, 0, 255);
- strip.setBrightness(BRIGHTNESS);
- } else {
- switch (this_mode) {
- case 0:
- case 1: SMOOTH = smartIncrFloat(SMOOTH, -0.05, 0.05, 1);
- break;
- case 2:
- case 3:
- case 4: SMOOTH_FREQ = smartIncrFloat(SMOOTH_FREQ, -0.05, 0.05, 1);
- break;
- case 5: STROBE_SMOOTH = smartIncr(STROBE_SMOOTH, -20, 0, 255);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_COLOR = smartIncr(LIGHT_COLOR, -10, 0, 255);
- break;
- case 1: COLOR_SPEED = smartIncr(COLOR_SPEED, -10, 0, 255);
- break;
- case 2: RAINBOW_PERIOD = smartIncr(RAINBOW_PERIOD, -1, -20, 20);
- break;
- }
- break;
- case 7: RUNNING_SPEED = smartIncr(RUNNING_SPEED, -10, 1, 255);
- break;
- case 8: HUE_STEP = smartIncr(HUE_STEP, -1, 1, 255);
- break;
- }
- }
- break;
- case BUTT_RIGHT:
- if (settings_mode) {
- // ВПРАВО общие настройки
- BRIGHTNESS = smartIncr(BRIGHTNESS, 20, 0, 255);
- strip.setBrightness(BRIGHTNESS);
- } else {
- switch (this_mode) {
- case 0:
- case 1: SMOOTH = smartIncrFloat(SMOOTH, 0.05, 0.05, 1);
- break;
- case 2:
- case 3:
- case 4: SMOOTH_FREQ = smartIncrFloat(SMOOTH_FREQ, 0.05, 0.05, 1);
- break;
- case 5: STROBE_SMOOTH = smartIncr(STROBE_SMOOTH, 20, 0, 255);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_COLOR = smartIncr(LIGHT_COLOR, 10, 0, 255);
- break;
- case 1: COLOR_SPEED = smartIncr(COLOR_SPEED, 10, 0, 255);
- break;
- case 2: RAINBOW_PERIOD = smartIncr(RAINBOW_PERIOD, 1, -20, 20);
- break;
- }
- break;
- case 7: RUNNING_SPEED = smartIncr(RUNNING_SPEED, 10, 1, 255);
- break;
- case 8: HUE_STEP = smartIncr(HUE_STEP, 1, 1, 255);
- break;
- }
- }
- break;
- default: eeprom_flag = false; // если не распознали кнопку, не обновляем настройки!
- break;
- }
- ir_flag = false;
- }
-}
-
-void autoLowPass() {
- // для режима VU
- delay(10); // ждём инициализации АЦП
- int thisMax = 0; // максимум
- int thisLevel;
- for (byte i = 0; i < 200; i++) {
- thisLevel = analogRead(SOUND_R); // делаем 200 измерений
- if (thisLevel > thisMax) // ищем максимумы
- thisMax = thisLevel; // запоминаем
- delay(4); // ждём 4мс
- }
- LOW_PASS = thisMax + LOW_PASS_ADD; // нижний порог как максимум тишины + некая величина
-
- // для режима спектра
- thisMax = 0;
- for (byte i = 0; i < 100; i++) { // делаем 100 измерений
- analyzeAudio(); // разбить в спектр
- for (byte j = 2; j < 32; j++) { // первые 2 канала - хлам
- thisLevel = fht_log_out[j];
- if (thisLevel > thisMax) // ищем максимумы
- thisMax = thisLevel; // запоминаем
- }
- delay(4); // ждём 4мс
- }
- SPEKTR_LOW_PASS = thisMax + LOW_PASS_FREQ_ADD; // нижний порог как максимум тишины
-
- if (EEPROM_LOW_PASS && !AUTO_LOW_PASS) {
- EEPROM.updateInt(70, LOW_PASS);
- EEPROM.updateInt(72, SPEKTR_LOW_PASS);
- }
-}
-
-void analyzeAudio() {
- for (int i = 0 ; i < FHT_N ; i++) {
- int sample = analogRead(SOUND_R_FREQ);
- fht_input[i] = sample; // put real data into bins
- }
- fht_window(); // window the data for better frequency response
- fht_reorder(); // reorder the data before doing the fht
- fht_run(); // process the data in the fht
- fht_mag_log(); // take the output of the fht
-}
-
-void buttonTick() {
- butt1.tick(); // обязательная функция отработки. Должна постоянно опрашиваться
- if (butt1.isSingle()) // если единичное нажатие
- if (++this_mode >= MODE_AMOUNT) this_mode = 0; // изменить режим
-
- if (butt1.isHolded()) { // кнопка удержана
- fullLowPass();
- }
-}
-void fullLowPass() {
- digitalWrite(13, HIGH); // включить светодиод 13 пин
- strip.setBrightness(0); // погасить ленту
- strip.clear(); // очистить массив пикселей
- strip.show(); // отправить значения на ленту
- delay(500); // подождать чутка
- autoLowPass(); // измерить шумы
- delay(500); // подождать
- strip.setBrightness(BRIGHTNESS); // вернуть яркость
- digitalWrite(13, LOW); // выключить светодиод
-}
-void updateEEPROM() {
- EEPROM.updateByte(1, this_mode);
- EEPROM.updateByte(2, freq_strobe_mode);
- EEPROM.updateByte(3, light_mode);
- EEPROM.updateInt(4, RAINBOW_STEP);
- EEPROM.updateFloat(8, MAX_COEF_FREQ);
- EEPROM.updateInt(12, STROBE_PERIOD);
- EEPROM.updateInt(16, LIGHT_SAT);
- EEPROM.updateFloat(20, RAINBOW_STEP_2);
- EEPROM.updateInt(24, HUE_START);
- EEPROM.updateFloat(28, SMOOTH);
- EEPROM.updateFloat(32, SMOOTH_FREQ);
- EEPROM.updateInt(36, STROBE_SMOOTH);
- EEPROM.updateInt(40, LIGHT_COLOR);
- EEPROM.updateInt(44, COLOR_SPEED);
- EEPROM.updateInt(48, RAINBOW_PERIOD);
- EEPROM.updateInt(52, RUNNING_SPEED);
- EEPROM.updateInt(56, HUE_STEP);
- EEPROM.updateInt(60, EMPTY_BRIGHT);
-}
-void readEEPROM() {
- this_mode = EEPROM.readByte(1);
- freq_strobe_mode = EEPROM.readByte(2);
- light_mode = EEPROM.readByte(3);
- RAINBOW_STEP = EEPROM.readInt(4);
- MAX_COEF_FREQ = EEPROM.readFloat(8);
- STROBE_PERIOD = EEPROM.readInt(12);
- LIGHT_SAT = EEPROM.readInt(16);
- RAINBOW_STEP_2 = EEPROM.readFloat(20);
- HUE_START = EEPROM.readInt(24);
- SMOOTH = EEPROM.readFloat(28);
- SMOOTH_FREQ = EEPROM.readFloat(32);
- STROBE_SMOOTH = EEPROM.readInt(36);
- LIGHT_COLOR = EEPROM.readInt(40);
- COLOR_SPEED = EEPROM.readInt(44);
- RAINBOW_PERIOD = EEPROM.readInt(48);
- RUNNING_SPEED = EEPROM.readInt(52);
- HUE_STEP = EEPROM.readInt(56);
- EMPTY_BRIGHT = EEPROM.readInt(60);
-}
-void eepromTick() {
- if (eeprom_flag)
- if (millis() - eeprom_timer > 30000) { // 30 секунд после последнего нажатия с пульта
- eeprom_flag = false;
- eeprom_timer = millis();
- updateEEPROM();
- }
-}
-/*
- void setPixelHSV(uint16_t pix, uint8_t h, uint8_t s, uint8_t v) {
- float r, g, b;
-
- float H = (float)h / 255;
- float S = (float)s / 255;
- float V = (float)v / 255;
-
- int i = int(H * 6);
- float f = H * 6 - i;
- float p = V * (1 - S);
- float q = V * (1 - f * S);
- float t = V * (1 - (1 - f) * S);
-
- switch (i % 6) {
- case 0: r = V, g = t, b = p; break;
- case 1: r = q, g = V, b = p; break;
- case 2: r = p, g = V, b = t; break;
- case 3: r = p, g = q, b = V; break;
- case 4: r = t, g = p, b = V; break;
- case 5: r = V, g = p, b = q; break;
- }
- r *= 255;
- g *= 255;
- b *= 255;
- strip.setPixelColor(pix, r, g, b);
- }
-*/
-void setPixelHSV(uint16_t pix, uint8_t hue, uint8_t sat, uint8_t val) {
- byte h = ((24 * hue / 17) / 60) % 6;
- byte vmin = (long)val - val * sat / 255;
- byte a = (long)val * sat / 255 * (hue * 24 / 17 % 60) / 60;
- byte vinc = vmin + a;
- byte vdec = val - a;
- byte r, g, b;
- switch (h) {
- case 0: r = val; g = vinc; b = vmin; break;
- case 1: r = vdec; g = val; b = vmin; break;
- case 2: r = vmin; g = val; b = vinc; break;
- case 3: r = vmin; g = vdec; b = val; break;
- case 4: r = vinc; g = vmin; b = val; break;
- case 5: r = val; g = vmin; b = vdec; break;
- }
- strip.setPixelColor(pix, r, g, b);
-}
diff --git a/firmware/Old versions/colorMusic_v2.5_WAVGAT/colorMusic_v2.5_WAVGAT.ino b/firmware/Old versions/colorMusic_v2.5_WAVGAT/colorMusic_v2.5_WAVGAT.ino
deleted file mode 100644
index 6480f0b..0000000
--- a/firmware/Old versions/colorMusic_v2.5_WAVGAT/colorMusic_v2.5_WAVGAT.ino
+++ /dev/null
@@ -1,997 +0,0 @@
-/*
- Версия 2.5 использует библиотеки Adafruit_NeoPixel и IRLremote вместо FastLED и IRremote
- Библиотеки идут в архиве с проектом! https://alexgyver.ru/colormusic/
- Крутейшая свето-цветомузыка на Arduino и адресной светодиодной ленте WS2812b.
- Данная версия поддерживает около 410 светодиодов!
- Версия для ИК пульта WAVGAT
- Управление:
- - Однократное нажатие кнопки: смена режима
- - Удержание кнопки: калибровка нижнего порога шума
- Режимы работы (переключаются кнопкой):
- - VU meter (столбик громкости): от зелёного к красному
- - VU meter (столбик громкости): плавно бегущая радуга
- - Светомузыка по частотам: 5 полос симметрично
- - Светомузыка по частотам: 3 полосы
- - Светомузыка по частотам: 1 полоса
- - Стробоскоп
- - Подсветка
- - Бегущие частоты
- - Анализатор спектра
- Особенности:
- - Плавная анимация (можно настроить)
- - Автонастройка по громкости (можно настроить)
- - Фильтр нижнего шума (можно настроить)
- - Автокалибровка шума при запуске (можно настроить)
- - Поддержка стерео и моно звука (можно настроить)
- - В режиме частот лента не гаснет полностью (EMPTY_BRIGHT)
- - Все настройки сохраняются в памяти и не сбрасываются при перезагрузке
- - Сохранение настроек происходит при выключении кнопкой звёздочка (*)
- - А также через 30 секунд после последнего нажатия на любую кнопку ИК пульта
-
- НАСТРОЙКА НИЖНЕГО ПОРОГА ШУМА (строки 65-71)
- - Включаем систему
- - Ставим музыку на паузу
- - Удерживаем кнопку 1 секунду ИЛИ жмём кнопку 0 на пульте
- Значения шумов будут записаны в память и САМИ загружаться при последующем запуске! Всё!
-
- Пульт:
- - Цифры (1 - 9) активируют режимы
- - Цифра 0: калибровка шума
- - Звёздочка (*): включить/выключить систему
- - Кнопка ОК: переключение между локальными и глобальными настройками)
- - Решётка (#): смена подрежима
- - Глобальные настройки (горит светодиод на плате):
- + Стрелки ← →: общая яркость горящих светодиодов
- + Стрелки ↑ ↓: яркость "не горящих" светодиодов
- - Локальные настройки (у каждого режима свои):
- 1 - Шкала громкости (градиент)
- Стрелки ← →: плавность анимации
- 2 - Шкала громкости (радуга)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: скорость радуги
- 3 - Цветомузыка (5 полос)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- 4 - Цветомузыка (3 полосы)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- 5 - Цветомузыка (1 полоса)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- Подрежимы #: 3 частоты / низкие / средние / высокие
- 6 - Стробоскоп
- Стрелки ← →: плавность вспышек
- Стрелки ↑ ↓: частота вспышек
- 7 - Цветная подсветка
- Подрежимы #:
- Постоянный: стрелки ← →: цвет, стрелки ↑ ↓: насыщенность
- Плавная смена: стрелки ← →: скорость, стрелки ↑ ↓: насыщенность
- Бегущая радуга: стрелки ← →: скорость, стрелки ↑ ↓: шаг радуги
- 8 - “Бегущие частоты”
- Стрелки ← →: скорость
- Стрелки ↑ ↓: чувствительность
- Подрежимы #: 3 частоты / низкие / средние / высокие
- 9 - Анализатор спектра
- Стрелки ← →: шаг цвета
- Стрелки ↑ ↓: цвет
- **************************************************
- Разработано: AlexGyver
- Страница проекта: http://alexgyver.ru/colormusic/
- GitHub: https://github.com/AlexGyver/ColorMusic
-*/
-
-// --------------------------- НАСТРОЙКИ ---------------------------
-#define KEEP_SETTINGS 1 // хранить ВСЕ настройки в памяти
-#define RESET_SETTINGS 0 // сброс настроек в памяти.
-// поставить 1. Прошиться. Поставить обратно 0. Прошиться. Всё.
-
-// лента
-#define NUM_LEDS 60 // количество светодиодов
-byte BRIGHTNESS = 200; // яркость (0 - 255)
-
-// пины
-#define SOUND_R A2 // аналоговый пин вход аудио, правый канал
-#define SOUND_L A1 // аналоговый пин вход аудио, левый канал
-#define SOUND_R_FREQ A3 // аналоговый пин вход аудио для режима с частотами (через кондер)
-#define BTN_PIN 3 // кнопка переключения режимов (PIN --- КНОПКА --- GND)
-#define LED_PIN 12 // пин DI светодиодной ленты
-#define POT_GND A0 // пин земля для потенциометра
-#define IR_PIN 2 // ИК приёмник
-
-// настройки радуги
-float RAINBOW_STEP = 5.5; // шаг изменения цвета радуги
-
-// отрисовка
-#define MODE 0 // режим при запуске
-#define MAIN_LOOP 5 // период основного цикла отрисовки (по умолчанию 5)
-
-// сигнал
-#define MONO 1 // 1 - только один канал (ПРАВЫЙ!!!!! SOUND_R!!!!!), 0 - два канала
-#define EXP 1.4 // степень усиления сигнала (для более "резкой" работы) (по умолчанию 1.4)
-#define POTENT 1 // 1 - используем потенциометр, 0 - используется внутренний источник опорного напряжения 1.1 В
-byte EMPTY_BRIGHT = 30; // яркость "не горящих" светодиодов (0 - 255)
-#define EMPTY_COLOR HUE_PURPLE // цвет "не горящих" светодиодов. Будет чёрный, если яркость 0
-
-// нижний порог шумов
-byte LOW_PASS = 100; // нижний порог шумов режим VU, ручная настройка
-byte SPEKTR_LOW_PASS = 40; // нижний порог шумов режим спектра, ручная настройка
-#define AUTO_LOW_PASS 0 // разрешить настройку нижнего порога шумов при запуске (по умолч. 0)
-#define EEPROM_LOW_PASS 1 // порог шумов хранится в энергонезависимой памяти (по умолч. 1)
-#define LOW_PASS_ADD 13 // "добавочная" величина к нижнему порогу, для надёжности (режим VU)
-#define LOW_PASS_FREQ_ADD 3 // "добавочная" величина к нижнему порогу, для надёжности (режим частот)
-
-// шкала громкости
-float SMOOTH = 0.5; // коэффициент плавности анимации VU (по умолчанию 0.5)
-#define MAX_COEF 1.8 // коэффициент громкости (максимальное равно срднему * этот коэф) (по умолчанию 1.8)
-
-// режим цветомузыки
-float SMOOTH_FREQ = 0.8; // коэффициент плавности анимации частот (по умолчанию 0.8)
-float MAX_COEF_FREQ = 1.2; // коэффициент порога для "вспышки" цветомузыки (по умолчанию 1.5)
-#define SMOOTH_STEP 20 // шаг уменьшения яркости в режиме цветомузыки (чем больше, тем быстрее гаснет)
-#define LOW_COLOR HUE_RED // цвет низких частот
-#define MID_COLOR HUE_GREEN // цвет средних
-#define HIGH_COLOR HUE_YELLOW // цвет высоких
-
-// режим стробоскопа
-int STROBE_PERIOD = 100; // период вспышек, миллисекунды
-#define STROBE_DUTY 20 // скважность вспышек (1 - 99) - отношение времени вспышки ко времени темноты
-#define STROBE_COLOR HUE_YELLOW // цвет стробоскопа
-#define STROBE_SAT 0 // насыщенность. Если 0 - цвет будет БЕЛЫЙ при любом цвете (0 - 255)
-byte STROBE_SMOOTH = 100; // скорость нарастания/угасания вспышки (0 - 255)
-
-// режим подсветки
-byte LIGHT_COLOR = 0; // начальный цвет подсветки
-byte LIGHT_SAT = 200; // начальная насыщенность подсветки
-byte COLOR_SPEED = 100;
-int RAINBOW_PERIOD = 3;
-float RAINBOW_STEP_2 = 5.5;
-
-// режим бегущих частот
-byte RUNNING_SPEED = 60;
-
-// режим анализатора спектра
-byte HUE_START = 0;
-byte HUE_STEP = 5;
-#define LIGHT_SMOOTH 2
-
-/*
- Цвета для HSV
- HUE_RED
- HUE_ORANGE
- HUE_YELLOW
- HUE_GREEN
- HUE_AQUA
- HUE_BLUE
- HUE_PURPLE
- HUE_PINK
-*/
-// --------------------------- НАСТРОЙКИ ---------------------------
-
-// ----- КНОПКИ ПУЛЬТА -----
-#define BUTT_UP 0xF39EEBAD
-#define BUTT_DOWN 0xC089F6AD
-#define BUTT_LEFT 0xE25410AD
-#define BUTT_RIGHT 0x14CE54AD
-#define BUTT_OK 0x297C76AD
-#define BUTT_1 0x4E5BA3AD
-#define BUTT_2 0xE51CA6AD
-#define BUTT_3 0xE207E1AD
-#define BUTT_4 0x517068AD
-#define BUTT_5 0x1B92DDAD
-#define BUTT_6 0xAC2A56AD
-#define BUTT_7 0x5484B6AD
-#define BUTT_8 0xD22353AD
-#define BUTT_9 0xDF3F4BAD
-#define BUTT_0 0xF08A26AD
-#define BUTT_STAR 0x68E456AD
-#define BUTT_HASH 0x151CD6AD
-// ----- КНОПКИ ПУЛЬТА -----
-
-// ------------------------------ ДЛЯ РАЗРАБОТЧИКОВ --------------------------------
-#define MODE_AMOUNT 9 // количество режимов
-
-// цвета HSV
-#define HUE_RED 0
-#define HUE_ORANGE 12
-#define HUE_YELLOW 44
-#define HUE_GREEN 85
-#define HUE_AQUA 128
-#define HUE_BLUE 171
-#define HUE_PURPLE 213
-#define HUE_PINK 244
-
-#define STRIPE NUM_LEDS / 5
-float freq_to_stripe = NUM_LEDS / 40; // /2 так как симметрия, и /20 так как 20 частот
-
-#define FHT_N 64 // ширина спектра х2
-#define LOG_OUT 1
-#include // преобразование Хартли
-
-#include
-
-#include "Adafruit_NeoPixel.h"
-Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
-
-#include "GyverButton.h"
-GButton butt1(BTN_PIN);
-
-#include "IRLremote.h"
-CHashIR IRLremote;
-uint32_t IRdata;
-
-byte Rlenght, Llenght;
-float RsoundLevel, RsoundLevel_f;
-float LsoundLevel, LsoundLevel_f;
-
-float averageLevel = 50;
-int maxLevel = 100;
-byte MAX_CH = NUM_LEDS / 2;
-int hue;
-unsigned long main_timer, hue_timer, strobe_timer, running_timer, color_timer, rainbow_timer, eeprom_timer;
-float averK = 0.006;
-byte count;
-float index = (float)(HUE_GREEN - HUE_RED) / MAX_CH; // коэффициент перевода для палитры зеленый-красный
-float index2 = (float)255 / MAX_CH; // коэффициент перевода для радуги
-boolean lowFlag;
-byte low_pass;
-int RcurrentLevel, LcurrentLevel;
-int colorMusic[3];
-float colorMusic_f[3], colorMusic_aver[3];
-boolean colorMusicFlash[3], strobeUp_flag, strobeDwn_flag;
-byte this_mode = MODE;
-int thisBright[3], strobe_bright = 0;
-unsigned int light_time = STROBE_PERIOD * STROBE_DUTY / 100;
-volatile boolean ir_flag;
-boolean settings_mode, ONstate = true;
-int8_t freq_strobe_mode, light_mode;
-int freq_max;
-float freq_max_f, rainbow_steps;
-int freq_f[32];
-int this_color;
-boolean running_flag[3], eeprom_flag;
-
-#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
-#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
-// ------------------------------ ДЛЯ РАЗРАБОТЧИКОВ --------------------------------
-
-void setup() {
- Serial.begin(9600);
-
- strip.begin();
- strip.setBrightness(BRIGHTNESS);
-
- pinMode(13, OUTPUT);
- digitalWrite(13, LOW);
-
- pinMode(POT_GND, OUTPUT);
- digitalWrite(POT_GND, LOW);
- butt1.setTimeout(900);
-
- IRLremote.begin(IR_PIN);
-
- // для увеличения точности уменьшаем опорное напряжение,
- // выставив EXTERNAL и подключив Aref к выходу 3.3V на плате через делитель
- // GND ---[10-20 кОм] --- REF --- [10 кОм] --- 3V3
- // в данной схеме GND берётся из А0 для удобства подключения
- if (POTENT) analogReference(EXTERNAL);
- else analogReference(INTERNAL);
-
- // жуткая магия, меняем частоту оцифровки до 18 кГц
- // команды на ебучем ассемблере, даже не спрашивайте, как это работает
- sbi(ADCSRA, ADPS2);
- cbi(ADCSRA, ADPS1);
- sbi(ADCSRA, ADPS0);
-
- if (RESET_SETTINGS) EEPROM.write(100, 0); // сброс флага настроек
-
- if (AUTO_LOW_PASS && !EEPROM_LOW_PASS) { // если разрешена автонастройка нижнего порога шумов
- autoLowPass();
- }
- if (EEPROM_LOW_PASS) { // восстановить значения шумов из памяти
- LOW_PASS = EEPROM.readInt(70);
- SPEKTR_LOW_PASS = EEPROM.readInt(72);
- }
-
- // в 100 ячейке хранится число 100. Если нет - значит это первый запуск системы
- if (KEEP_SETTINGS) {
- if (EEPROM.read(100) != 100) {
- //Serial.println(F("First start"));
- EEPROM.write(100, 100);
- updateEEPROM();
- } else {
- readEEPROM();
- }
- }
-}
-
-void loop() {
- buttonTick(); // опрос и обработка кнопки
- remoteTick(); // опрос ИК пульта
- mainLoop(); // главный цикл обработки и отрисовки
- eepromTick(); // проверка не пора ли сохранить настройки
-}
-
-void mainLoop() {
- // главный цикл отрисовки
- if (ONstate) {
- if (millis() - main_timer > MAIN_LOOP) {
- // сбрасываем значения
- RsoundLevel = 0;
- LsoundLevel = 0;
-
- // перваые два режима - громкость (VU meter)
- if (this_mode == 0 || this_mode == 1) {
- for (byte i = 0; i < 100; i ++) { // делаем 100 измерений
- RcurrentLevel = analogRead(SOUND_R); // с правого
- if (!MONO) LcurrentLevel = analogRead(SOUND_L); // и левого каналов
-
- if (RsoundLevel < RcurrentLevel) RsoundLevel = RcurrentLevel; // ищем максимальное
- if (!MONO) if (LsoundLevel < LcurrentLevel) LsoundLevel = LcurrentLevel; // ищем максимальное
- }
-
- // фильтруем по нижнему порогу шумов
- RsoundLevel = map(RsoundLevel, LOW_PASS, 1023, 0, 500);
- if (!MONO)LsoundLevel = map(LsoundLevel, LOW_PASS, 1023, 0, 500);
-
- // ограничиваем диапазон
- RsoundLevel = constrain(RsoundLevel, 0, 500);
- if (!MONO)LsoundLevel = constrain(LsoundLevel, 0, 500);
-
- // возводим в степень (для большей чёткости работы)
- RsoundLevel = pow(RsoundLevel, EXP);
- if (!MONO)LsoundLevel = pow(LsoundLevel, EXP);
-
- // фильтр
- RsoundLevel_f = RsoundLevel * SMOOTH + RsoundLevel_f * (1 - SMOOTH);
- if (!MONO)LsoundLevel_f = LsoundLevel * SMOOTH + LsoundLevel_f * (1 - SMOOTH);
-
- if (MONO) LsoundLevel_f = RsoundLevel_f; // если моно, то левый = правому
-
- // заливаем "подложку", если яркость достаточная
- if (EMPTY_BRIGHT > 5) {
- for (int i = 0; i < NUM_LEDS; i++)
- setPixelHSV(i, EMPTY_COLOR, 255, EMPTY_BRIGHT);
- }
-
- // если значение выше порога - начинаем самое интересное
- if (RsoundLevel_f > 15 && LsoundLevel_f > 15) {
-
- // расчёт общей средней громкости с обоих каналов, фильтрация.
- // Фильтр очень медленный, сделано специально для автогромкости
- averageLevel = (float)(RsoundLevel_f + LsoundLevel_f) / 2 * averK + averageLevel * (1 - averK);
-
- // принимаем максимальную громкость шкалы как среднюю, умноженную на некоторый коэффициент MAX_COEF
- maxLevel = (float)averageLevel * MAX_COEF;
-
- // преобразуем сигнал в длину ленты (где MAX_CH это половина количества светодиодов)
- Rlenght = map(RsoundLevel_f, 0, maxLevel, 0, MAX_CH);
- Llenght = map(LsoundLevel_f, 0, maxLevel, 0, MAX_CH);
-
- // ограничиваем до макс. числа светодиодов
- Rlenght = constrain(Rlenght, 0, MAX_CH);
- Llenght = constrain(Llenght, 0, MAX_CH);
-
- animation(); // отрисовать
- }
- }
-
- // 3-5 режим - цветомузыка
- if (this_mode == 2 || this_mode == 3 || this_mode == 4 || this_mode == 7 || this_mode == 8) {
- analyzeAudio();
- colorMusic[0] = 0;
- colorMusic[1] = 0;
- colorMusic[2] = 0;
- for (int i = 0 ; i < 32 ; i++) {
- if (fht_log_out[i] < SPEKTR_LOW_PASS) fht_log_out[i] = 0;
- }
- // низкие частоты, выборка со 2 по 5 тон (0 и 1 зашумленные!)
- for (byte i = 2; i < 6; i++) {
- if (fht_log_out[i] > colorMusic[0]) colorMusic[0] = fht_log_out[i];
- }
- // средние частоты, выборка с 6 по 10 тон
- for (byte i = 6; i < 11; i++) {
- if (fht_log_out[i] > colorMusic[1]) colorMusic[1] = fht_log_out[i];
- }
- // высокие частоты, выборка с 11 по 31 тон
- for (byte i = 11; i < 32; i++) {
- if (fht_log_out[i] > colorMusic[2]) colorMusic[2] = fht_log_out[i];
- }
- freq_max = 0;
- for (byte i = 0; i < 30; i++) {
- if (fht_log_out[i + 2] > freq_max) freq_max = fht_log_out[i + 2];
- if (freq_max < 5) freq_max = 5;
-
- if (freq_f[i] < fht_log_out[i + 2]) freq_f[i] = fht_log_out[i + 2];
- if (freq_f[i] > 0) freq_f[i] -= LIGHT_SMOOTH;
- else freq_f[i] = 0;
- }
- freq_max_f = freq_max * averK + freq_max_f * (1 - averK);
- for (byte i = 0; i < 3; i++) {
- colorMusic_aver[i] = colorMusic[i] * averK + colorMusic_aver[i] * (1 - averK); // общая фильтрация
- colorMusic_f[i] = colorMusic[i] * SMOOTH_FREQ + colorMusic_f[i] * (1 - SMOOTH_FREQ); // локальная
- if (colorMusic_f[i] > ((float)colorMusic_aver[i] * MAX_COEF_FREQ)) {
- thisBright[i] = 255;
- colorMusicFlash[i] = true;
- running_flag[i] = true;
- } else colorMusicFlash[i] = false;
- if (thisBright[i] >= 0) thisBright[i] -= SMOOTH_STEP;
- if (thisBright[i] < EMPTY_BRIGHT) {
- thisBright[i] = EMPTY_BRIGHT;
- running_flag[i] = false;
- }
- }
- animation();
- }
- if (this_mode == 5) {
- if ((long)millis() - strobe_timer > STROBE_PERIOD) {
- strobe_timer = millis();
- strobeUp_flag = true;
- strobeDwn_flag = false;
- }
- if ((long)millis() - strobe_timer > light_time) {
- strobeDwn_flag = true;
- }
- if (strobeUp_flag) { // если настало время пыхнуть
- if (strobe_bright < 255) // если яркость не максимальная
- strobe_bright += STROBE_SMOOTH; // увелчить
- if (strobe_bright > 255) { // если пробили макс. яркость
- strobe_bright = 255; // оставить максимум
- strobeUp_flag = false; // флаг опустить
- }
- }
-
- if (strobeDwn_flag) { // гаснем
- if (strobe_bright > 0) // если яркость не минимальная
- strobe_bright -= STROBE_SMOOTH; // уменьшить
- if (strobe_bright < 0) { // если пробили мин. яркость
- strobeDwn_flag = false;
- strobe_bright = 0; // оставить 0
- }
- }
- animation();
- }
- if (this_mode == 6) animation();
-
- if (!IRLremote.receiving()) // если на ИК приёмник не приходит сигнал (без этого НЕ РАБОТАЕТ!)
- strip.show(); // отправить значения на ленту
-
- if (this_mode != 7) // 7 режиму не нужна очистка!!!
- strip.clear(); // очистить массив пикселей
- main_timer = millis(); // сбросить таймер
- }
- }
-}
-
-void animation() {
- // согласно режиму
- switch (this_mode) {
- case 0:
- count = 0;
- for (int i = (MAX_CH - 1); i > ((MAX_CH - 1) - Rlenght); i--) {
- setPixelHSV(i, HUE_GREEN - count * index, 255, 255);
- count++;
- }
- count = 0;
- for (int i = (MAX_CH); i < (MAX_CH + Llenght); i++ ) {
- setPixelHSV(i, HUE_GREEN - count * index, 255, 255);
- count++;
- }
- if (EMPTY_BRIGHT > 0) {
- for (int i = ((MAX_CH - 1) - Rlenght); i > 0; i--)
- setPixelHSV(i, EMPTY_COLOR, 255, EMPTY_BRIGHT);
- for (int i = MAX_CH + Llenght; i < NUM_LEDS; i++)
- setPixelHSV(i, EMPTY_COLOR, 255, EMPTY_BRIGHT);
- }
- break;
- case 1:
- if (millis() - rainbow_timer > 35) {
- rainbow_timer = millis();
- hue = floor((float)hue + RAINBOW_STEP);
- if (hue > 255) hue = 0;
- }
- count = 0;
- for (int i = (MAX_CH - 1); i > ((MAX_CH - 1) - Rlenght); i--) {
- setPixelHSV(i, (count * index) / 2 - hue, 255, 255);
- count++;
- }
- count = 0;
- for (int i = (MAX_CH); i < (MAX_CH + Llenght); i++ ) {
- setPixelHSV(i, (count * index) / 2 - hue, 255, 255);
- count++;
- }
- if (EMPTY_BRIGHT > 0) {
- for (int i = ((MAX_CH - 1) - Rlenght); i > 0; i--)
- setPixelHSV(i, EMPTY_COLOR, 255, EMPTY_BRIGHT);
- for (int i = MAX_CH + Llenght; i < NUM_LEDS; i++)
- setPixelHSV(i, EMPTY_COLOR, 255, EMPTY_BRIGHT);
- }
- break;
- case 2:
- for (int i = 0; i < NUM_LEDS; i++) {
- if (i < STRIPE) setPixelHSV(i, HIGH_COLOR, 255, thisBright[2]);
- else if (i < STRIPE * 2) setPixelHSV(i, MID_COLOR, 255, thisBright[1]);
- else if (i < STRIPE * 3) setPixelHSV(i, LOW_COLOR, 255, thisBright[0]);
- else if (i < STRIPE * 4) setPixelHSV(i, MID_COLOR, 255, thisBright[1]);
- else if (i < STRIPE * 5) setPixelHSV(i, HIGH_COLOR, 255, thisBright[2]);
- }
- break;
- case 3:
- for (int i = 0; i < NUM_LEDS; i++) {
- if (i < NUM_LEDS / 3) setPixelHSV(i, HIGH_COLOR, 255, thisBright[2]);
- else if (i < NUM_LEDS * 2 / 3) setPixelHSV(i, MID_COLOR, 255, thisBright[1]);
- else if (i < NUM_LEDS) setPixelHSV(i, LOW_COLOR, 255, thisBright[0]);
- }
- break;
- case 4:
- switch (freq_strobe_mode) {
- case 0:
- if (colorMusicFlash[2]) HIGHS();
- else if (colorMusicFlash[1]) MIDS();
- else if (colorMusicFlash[0]) LOWS();
- else SILENCE();
- break;
- case 1:
- if (colorMusicFlash[2]) HIGHS();
- else SILENCE();
- break;
- case 2:
- if (colorMusicFlash[1]) MIDS();
- else SILENCE();
- break;
- case 3:
- if (colorMusicFlash[0]) LOWS();
- else SILENCE();
- break;
- }
- break;
- case 5:
- if (strobe_bright > 0) {
- setPixelHSV(0, STROBE_COLOR, STROBE_SAT, strobe_bright);
- uint32_t new_color = strip.getPixelColor(0);
- for (int i = 1; i < NUM_LEDS; i++) strip.setPixelColor(i, new_color);
- } else {
- setPixelHSV(0, EMPTY_COLOR, 255, EMPTY_BRIGHT);
- uint32_t new_color = strip.getPixelColor(0);
- for (int i = 1; i < NUM_LEDS; i++) strip.setPixelColor(i, new_color);
- }
- break;
- case 6:
- switch (light_mode) {
- case 0: for (int i = 0; i < NUM_LEDS; i++) setPixelHSV(i, LIGHT_COLOR, LIGHT_SAT, 255);
- break;
- case 1:
- if (millis() - color_timer > COLOR_SPEED) {
- color_timer = millis();
- if (++this_color > 255) this_color = 0;
- }
- for (int i = 0; i < NUM_LEDS; i++) setPixelHSV(i, this_color, LIGHT_SAT, 255);
- break;
- case 2:
- if (millis() - rainbow_timer > 35) {
- rainbow_timer = millis();
- this_color += RAINBOW_PERIOD;
- if (this_color > 255) this_color = 0;
- if (this_color < 0) this_color = 255;
- }
- rainbow_steps = this_color;
- for (int i = 0; i < NUM_LEDS; i++) {
- setPixelHSV(i, (int)floor(rainbow_steps), 255, 255);
- rainbow_steps += RAINBOW_STEP_2;
- if (rainbow_steps > 255) rainbow_steps = 0;
- if (rainbow_steps < 0) rainbow_steps = 255;
- }
- break;
- }
- break;
- case 7:
- switch (freq_strobe_mode) {
- case 0:
- if (running_flag[2]) setPixelHSV(NUM_LEDS / 2, HIGH_COLOR, 255, thisBright[2]);
- else if (running_flag[1]) setPixelHSV(NUM_LEDS / 2, MID_COLOR, 255, thisBright[1]);
- else if (running_flag[0]) setPixelHSV(NUM_LEDS / 2, LOW_COLOR, 255, thisBright[0]);
- else setPixelHSV(NUM_LEDS / 2, EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 1:
- if (running_flag[2]) setPixelHSV(NUM_LEDS / 2, HIGH_COLOR, 255, thisBright[2]);
- else setPixelHSV(NUM_LEDS / 2, EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 2:
- if (running_flag[1]) setPixelHSV(NUM_LEDS / 2, MID_COLOR, 255, thisBright[1]);
- else setPixelHSV(NUM_LEDS / 2, EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 3:
- if (running_flag[0]) setPixelHSV(NUM_LEDS / 2, LOW_COLOR, 255, thisBright[0]);
- else setPixelHSV(NUM_LEDS / 2, EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- }
- strip.setPixelColor((NUM_LEDS / 2) - 1, strip.getPixelColor(NUM_LEDS / 2));
- if (millis() - running_timer > RUNNING_SPEED) {
- running_timer = millis();
- for (byte i = 0; i < NUM_LEDS / 2 - 1; i++) {
- strip.setPixelColor(i, strip.getPixelColor(i + 1));
- strip.setPixelColor(NUM_LEDS - i - 1, strip.getPixelColor(i));
- }
- }
- break;
- case 8:
- byte HUEindex = HUE_START;
- for (byte i = 0; i < NUM_LEDS / 2; i++) {
- byte this_bright = map(freq_f[(int)floor((NUM_LEDS / 2 - i) / freq_to_stripe)], 0, freq_max_f, 0, 255);
- this_bright = constrain(this_bright, 0, 255);
- setPixelHSV(i, HUEindex, 255, this_bright);
- setPixelHSV(NUM_LEDS - i - 1, HUEindex, 255, this_bright);
- HUEindex += HUE_STEP;
- if (HUEindex > 255) HUEindex = 0;
- }
- break;
- }
-}
-
-void HIGHS() {
- for (int i = 0; i < NUM_LEDS; i++) setPixelHSV(i, HIGH_COLOR, 255, thisBright[2]);
-}
-void MIDS() {
- for (int i = 0; i < NUM_LEDS; i++) setPixelHSV(i, MID_COLOR, 255, thisBright[1]);
-}
-void LOWS() {
- for (int i = 0; i < NUM_LEDS; i++) setPixelHSV(i, LOW_COLOR, 255, thisBright[0]);
-}
-void SILENCE() {
- for (int i = 0; i < NUM_LEDS; i++) setPixelHSV(i, EMPTY_COLOR, 255, EMPTY_BRIGHT);
-}
-
-// вспомогательная функция, изменяет величину value на шаг incr в пределах minimum.. maximum
-int smartIncr(int value, int incr_step, int mininmum, int maximum) {
- int val_buf = value + incr_step;
- val_buf = constrain(val_buf, mininmum, maximum);
- //Serial.println(val_buf);
- return val_buf;
-}
-
-float smartIncrFloat(float value, float incr_step, float mininmum, float maximum) {
- float val_buf = value + incr_step;
- val_buf = constrain(val_buf, mininmum, maximum);
- //Serial.println(val_buf);
- return val_buf;
-}
-
-void remoteTick() {
- if (IRLremote.available()) {
- auto data = IRLremote.read();
- IRdata = data.command;
- ir_flag = true;
- }
-
- if (ir_flag) { // если данные пришли
- eeprom_timer = millis();
- eeprom_flag = true;
- switch (IRdata) {
- // режимы
- case BUTT_1: this_mode = 0;
- break;
- case BUTT_2: this_mode = 1;
- break;
- case BUTT_3: this_mode = 2;
- break;
- case BUTT_4: this_mode = 3;
- break;
- case BUTT_5: this_mode = 4;
- break;
- case BUTT_6: this_mode = 5;
- break;
- case BUTT_7: this_mode = 6;
- break;
- case BUTT_8: this_mode = 7;
- break;
- case BUTT_9: this_mode = 8;
- break;
- case BUTT_0: fullLowPass();
- break;
- case BUTT_STAR: ONstate = !ONstate; strip.clear(); strip.show(); updateEEPROM();
- break;
- case BUTT_HASH:
- switch (this_mode) {
- case 4:
- case 7: if (++freq_strobe_mode > 3) freq_strobe_mode = 0;
- break;
- case 6: if (++light_mode > 2) light_mode = 0;
- break;
- }
- break;
- case BUTT_OK: settings_mode = !settings_mode; digitalWrite(13, settings_mode);
- break;
- case BUTT_UP:
- if (settings_mode) {
- // ВВЕРХ общие настройки
- EMPTY_BRIGHT = smartIncr(EMPTY_BRIGHT, 5, 0, 255);
- } else {
- switch (this_mode) {
- case 0:
- break;
- case 1: RAINBOW_STEP = smartIncrFloat(RAINBOW_STEP, 0.5, 0.5, 20);
- break;
- case 2:
- case 3:
- case 4: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, 0.1, 0, 5);
- break;
- case 5: STROBE_PERIOD = smartIncr(STROBE_PERIOD, 20, 1, 1000);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_SAT = smartIncr(LIGHT_SAT, 20, 0, 255);
- break;
- case 1: LIGHT_SAT = smartIncr(LIGHT_SAT, 20, 0, 255);
- break;
- case 2: RAINBOW_STEP_2 = smartIncrFloat(RAINBOW_STEP_2, 0.5, 0.5, 10);
- break;
- }
- break;
- case 7: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, 0.1, 0.0, 10);
- break;
- case 8: HUE_START = smartIncr(HUE_START, 10, 0, 255);
- break;
- }
- }
- break;
- case BUTT_DOWN:
- if (settings_mode) {
- // ВНИЗ общие настройки
- EMPTY_BRIGHT = smartIncr(EMPTY_BRIGHT, -5, 0, 255);
- } else {
- switch (this_mode) {
- case 0:
- break;
- case 1: RAINBOW_STEP = smartIncrFloat(RAINBOW_STEP, -0.5, 0.5, 20);
- break;
- case 2:
- case 3:
- case 4: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, -0.1, 0, 5);
- break;
- case 5: STROBE_PERIOD = smartIncr(STROBE_PERIOD, -20, 1, 1000);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_SAT = smartIncr(LIGHT_SAT, -20, 0, 255);
- break;
- case 1: LIGHT_SAT = smartIncr(LIGHT_SAT, -20, 0, 255);
- break;
- case 2: RAINBOW_STEP_2 = smartIncrFloat(RAINBOW_STEP_2, -0.5, 0.5, 10);
- break;
- }
- break;
- case 7: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, -0.1, 0.0, 10);
- break;
- case 8: HUE_START = smartIncr(HUE_START, -10, 0, 255);
- break;
- }
- }
- break;
- case BUTT_LEFT:
- if (settings_mode) {
- // ВЛЕВО общие настройки
- BRIGHTNESS = smartIncr(BRIGHTNESS, -20, 0, 255);
- strip.setBrightness(BRIGHTNESS);
- } else {
- switch (this_mode) {
- case 0:
- case 1: SMOOTH = smartIncrFloat(SMOOTH, -0.05, 0.05, 1);
- break;
- case 2:
- case 3:
- case 4: SMOOTH_FREQ = smartIncrFloat(SMOOTH_FREQ, -0.05, 0.05, 1);
- break;
- case 5: STROBE_SMOOTH = smartIncr(STROBE_SMOOTH, -20, 0, 255);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_COLOR = smartIncr(LIGHT_COLOR, -10, 0, 255);
- break;
- case 1: COLOR_SPEED = smartIncr(COLOR_SPEED, -10, 0, 255);
- break;
- case 2: RAINBOW_PERIOD = smartIncr(RAINBOW_PERIOD, -1, -20, 20);
- break;
- }
- break;
- case 7: RUNNING_SPEED = smartIncr(RUNNING_SPEED, -10, 1, 255);
- break;
- case 8: HUE_STEP = smartIncr(HUE_STEP, -1, 1, 255);
- break;
- }
- }
- break;
- case BUTT_RIGHT:
- if (settings_mode) {
- // ВПРАВО общие настройки
- BRIGHTNESS = smartIncr(BRIGHTNESS, 20, 0, 255);
- strip.setBrightness(BRIGHTNESS);
- } else {
- switch (this_mode) {
- case 0:
- case 1: SMOOTH = smartIncrFloat(SMOOTH, 0.05, 0.05, 1);
- break;
- case 2:
- case 3:
- case 4: SMOOTH_FREQ = smartIncrFloat(SMOOTH_FREQ, 0.05, 0.05, 1);
- break;
- case 5: STROBE_SMOOTH = smartIncr(STROBE_SMOOTH, 20, 0, 255);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_COLOR = smartIncr(LIGHT_COLOR, 10, 0, 255);
- break;
- case 1: COLOR_SPEED = smartIncr(COLOR_SPEED, 10, 0, 255);
- break;
- case 2: RAINBOW_PERIOD = smartIncr(RAINBOW_PERIOD, 1, -20, 20);
- break;
- }
- break;
- case 7: RUNNING_SPEED = smartIncr(RUNNING_SPEED, 10, 1, 255);
- break;
- case 8: HUE_STEP = smartIncr(HUE_STEP, 1, 1, 255);
- break;
- }
- }
- break;
- default: eeprom_flag = false; // если не распознали кнопку, не обновляем настройки!
- break;
- }
- ir_flag = false;
- }
-}
-
-void autoLowPass() {
- // для режима VU
- delay(10); // ждём инициализации АЦП
- int thisMax = 0; // максимум
- int thisLevel;
- for (byte i = 0; i < 200; i++) {
- thisLevel = analogRead(SOUND_R); // делаем 200 измерений
- if (thisLevel > thisMax) // ищем максимумы
- thisMax = thisLevel; // запоминаем
- delay(4); // ждём 4мс
- }
- LOW_PASS = thisMax + LOW_PASS_ADD; // нижний порог как максимум тишины + некая величина
-
- // для режима спектра
- thisMax = 0;
- for (byte i = 0; i < 100; i++) { // делаем 100 измерений
- analyzeAudio(); // разбить в спектр
- for (byte j = 2; j < 32; j++) { // первые 2 канала - хлам
- thisLevel = fht_log_out[j];
- if (thisLevel > thisMax) // ищем максимумы
- thisMax = thisLevel; // запоминаем
- }
- delay(4); // ждём 4мс
- }
- SPEKTR_LOW_PASS = thisMax + LOW_PASS_FREQ_ADD; // нижний порог как максимум тишины
-
- if (EEPROM_LOW_PASS && !AUTO_LOW_PASS) {
- EEPROM.updateInt(70, LOW_PASS);
- EEPROM.updateInt(72, SPEKTR_LOW_PASS);
- }
-}
-
-void analyzeAudio() {
- for (int i = 0 ; i < FHT_N ; i++) {
- int sample = analogRead(SOUND_R_FREQ);
- fht_input[i] = sample; // put real data into bins
- }
- fht_window(); // window the data for better frequency response
- fht_reorder(); // reorder the data before doing the fht
- fht_run(); // process the data in the fht
- fht_mag_log(); // take the output of the fht
-}
-
-void buttonTick() {
- butt1.tick(); // обязательная функция отработки. Должна постоянно опрашиваться
- if (butt1.isSingle()) // если единичное нажатие
- if (++this_mode >= MODE_AMOUNT) this_mode = 0; // изменить режим
-
- if (butt1.isHolded()) { // кнопка удержана
- fullLowPass();
- }
-}
-void fullLowPass() {
- digitalWrite(13, HIGH); // включить светодиод 13 пин
- strip.setBrightness(0); // погасить ленту
- strip.clear(); // очистить массив пикселей
- strip.show(); // отправить значения на ленту
- delay(500); // подождать чутка
- autoLowPass(); // измерить шумы
- delay(500); // подождать
- strip.setBrightness(BRIGHTNESS); // вернуть яркость
- digitalWrite(13, LOW); // выключить светодиод
-}
-void updateEEPROM() {
- EEPROM.updateByte(1, this_mode);
- EEPROM.updateByte(2, freq_strobe_mode);
- EEPROM.updateByte(3, light_mode);
- EEPROM.updateInt(4, RAINBOW_STEP);
- EEPROM.updateFloat(8, MAX_COEF_FREQ);
- EEPROM.updateInt(12, STROBE_PERIOD);
- EEPROM.updateInt(16, LIGHT_SAT);
- EEPROM.updateFloat(20, RAINBOW_STEP_2);
- EEPROM.updateInt(24, HUE_START);
- EEPROM.updateFloat(28, SMOOTH);
- EEPROM.updateFloat(32, SMOOTH_FREQ);
- EEPROM.updateInt(36, STROBE_SMOOTH);
- EEPROM.updateInt(40, LIGHT_COLOR);
- EEPROM.updateInt(44, COLOR_SPEED);
- EEPROM.updateInt(48, RAINBOW_PERIOD);
- EEPROM.updateInt(52, RUNNING_SPEED);
- EEPROM.updateInt(56, HUE_STEP);
- EEPROM.updateInt(60, EMPTY_BRIGHT);
-}
-void readEEPROM() {
- this_mode = EEPROM.readByte(1);
- freq_strobe_mode = EEPROM.readByte(2);
- light_mode = EEPROM.readByte(3);
- RAINBOW_STEP = EEPROM.readInt(4);
- MAX_COEF_FREQ = EEPROM.readFloat(8);
- STROBE_PERIOD = EEPROM.readInt(12);
- LIGHT_SAT = EEPROM.readInt(16);
- RAINBOW_STEP_2 = EEPROM.readFloat(20);
- HUE_START = EEPROM.readInt(24);
- SMOOTH = EEPROM.readFloat(28);
- SMOOTH_FREQ = EEPROM.readFloat(32);
- STROBE_SMOOTH = EEPROM.readInt(36);
- LIGHT_COLOR = EEPROM.readInt(40);
- COLOR_SPEED = EEPROM.readInt(44);
- RAINBOW_PERIOD = EEPROM.readInt(48);
- RUNNING_SPEED = EEPROM.readInt(52);
- HUE_STEP = EEPROM.readInt(56);
- EMPTY_BRIGHT = EEPROM.readInt(60);
-}
-void eepromTick() {
- if (eeprom_flag)
- if (millis() - eeprom_timer > 30000) { // 30 секунд после последнего нажатия с пульта
- eeprom_flag = false;
- eeprom_timer = millis();
- updateEEPROM();
- }
-}
-/*
- void setPixelHSV(uint16_t pix, uint8_t h, uint8_t s, uint8_t v) {
- float r, g, b;
-
- float H = (float)h / 255;
- float S = (float)s / 255;
- float V = (float)v / 255;
-
- int i = int(H * 6);
- float f = H * 6 - i;
- float p = V * (1 - S);
- float q = V * (1 - f * S);
- float t = V * (1 - (1 - f) * S);
-
- switch (i % 6) {
- case 0: r = V, g = t, b = p; break;
- case 1: r = q, g = V, b = p; break;
- case 2: r = p, g = V, b = t; break;
- case 3: r = p, g = q, b = V; break;
- case 4: r = t, g = p, b = V; break;
- case 5: r = V, g = p, b = q; break;
- }
- r *= 255;
- g *= 255;
- b *= 255;
- strip.setPixelColor(pix, r, g, b);
- }
-*/
-void setPixelHSV(uint16_t pix, uint8_t hue, uint8_t sat, uint8_t val) {
- byte h = ((24 * hue / 17) / 60) % 6;
- byte vmin = (long)val - val * sat / 255;
- byte a = (long)val * sat / 255 * (hue * 24 / 17 % 60) / 60;
- byte vinc = vmin + a;
- byte vdec = val - a;
- byte r, g, b;
- switch (h) {
- case 0: r = val; g = vinc; b = vmin; break;
- case 1: r = vdec; g = val; b = vmin; break;
- case 2: r = vmin; g = val; b = vinc; break;
- case 3: r = vmin; g = vdec; b = val; break;
- case 4: r = vinc; g = vmin; b = val; break;
- case 5: r = val; g = vmin; b = vdec; break;
- }
- strip.setPixelColor(pix, r, g, b);
-}
diff --git a/firmware/Old versions/colorMusic_v2.6.1_KEYES/colorMusic_v2.6.1_KEYES.ino b/firmware/Old versions/colorMusic_v2.6.1_KEYES/colorMusic_v2.6.1_KEYES.ino
deleted file mode 100644
index ae539a5..0000000
--- a/firmware/Old versions/colorMusic_v2.6.1_KEYES/colorMusic_v2.6.1_KEYES.ino
+++ /dev/null
@@ -1,944 +0,0 @@
-/*
- Версия 2.6 использует библиотеки FastLED и IRLremote!
- Библиотеки идут в архиве с проектом! https://alexgyver.ru/colormusic/
- Крутейшая свето-цветомузыка на Arduino и адресной светодиодной ленте WS2812b.
- Данная версия поддерживает около 410 светодиодов!
- Версия для ИК пульта KEYES
- Управление:
- - Однократное нажатие кнопки: смена режима
- - Удержание кнопки: калибровка нижнего порога шума
- Режимы работы (переключаются кнопкой):
- - VU meter (столбик громкости): от зелёного к красному
- - VU meter (столбик громкости): плавно бегущая радуга
- - Светомузыка по частотам: 5 полос симметрично
- - Светомузыка по частотам: 3 полосы
- - Светомузыка по частотам: 1 полоса
- - Стробоскоп
- - (2.0) Подсветка
- - (2.0) Бегущие частоты
- - (2.1) анализатор спектра
- Особенности:
- - Плавная анимация (можно настроить)
- - Автонастройка по громкости (можно настроить)
- - Фильтр нижнего шума (можно настроить)
- - Автокалибровка шума при запуске (можно настроить)
- - Поддержка стерео и моно звука (можно настроить)
- - (2.0) в режиме частот лента не гаснет полностью (EMPTY_BRIGHT)
- - (2.1) все настройки сохраняются в памяти и не сбрасываются при перезагрузке
- - Сохранение настроек происходит при выключении кнопкой звёздочка (*)
- - А также через 30 секунд после последнего нажатия на любую кнопку ИК пульта
-
- НАСТРОЙКА НИЖНЕГО ПОРОГА ШУМА (строки 65-71)
- - Включаем систему
- - Ставим музыку на паузу
- - Удерживаем кнопку 1 секунду ИЛИ жмём кнопку 0 на пульте
- Значения шумов будут записаны в память и САМИ загружаться при последующем запуске! Всё!
-
- Пульт:
- - Цифры (1 - 9) активируют режимы
- - Цифра 0: калибровка шума
- - Звёздочка (*): включить/выключить систему
- - Кнопка ОК: переключение между локальными и глобальными настройками)
- - Решётка (#): смена подрежима
- - Глобальные настройки (горит светодиод на плате):
- + Стрелки ← →: общая яркость горящих светодиодов
- + Стрелки ↑ ↓: яркость "не горящих" светодиодов
- - Локальные настройки (у каждого режима свои):
- 1 - Шкала громкости (градиент)
- Стрелки ← →: плавность анимации
- 2 - Шкала громкости (радуга)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: скорость радуги
- 3 - Цветомузыка (5 полос)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- 4 - Цветомузыка (3 полосы)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- 5 - Цветомузыка (1 полоса)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- Подрежимы #: 3 частоты / низкие / средние / высокие
- 6 - Стробоскоп
- Стрелки ← →: плавность вспышек
- Стрелки ↑ ↓: частота вспышек
- 7 - Цветная подсветка
- Подрежимы #:
- Постоянный: стрелки ← →: цвет, стрелки ↑ ↓: насыщенность
- Плавная смена: стрелки ← →: скорость, стрелки ↑ ↓: насыщенность
- Бегущая радуга: стрелки ← →: скорость, стрелки ↑ ↓: шаг радуги
- 8 - “Бегущие частоты”
- Стрелки ← →: скорость
- Стрелки ↑ ↓: чувствительность
- Подрежимы #: 3 частоты / низкие / средние / высокие
- 9 - Анализатор спектра
- Стрелки ← →: шаг цвета
- Стрелки ↑ ↓: цвет
- **************************************************
- Разработано: AlexGyver
- Страница проекта: http://alexgyver.ru/colormusic/
- GitHub: https://github.com/AlexGyver/ColorMusic
-*/
-
-// --------------------------- НАСТРОЙКИ ---------------------------
-#define KEEP_SETTINGS 1 // хранить ВСЕ настройки в памяти
-#define RESET_SETTINGS 0 // сброс настроек в памяти.
-// поставить 1. Прошиться. Поставить обратно 0. Прошиться. Всё.
-
-// лента
-#define NUM_LEDS 60 // количество светодиодов
-byte BRIGHTNESS = 200; // яркость (0 - 255)
-
-// пины
-#define SOUND_R A2 // аналоговый пин вход аудио, правый канал
-#define SOUND_L A1 // аналоговый пин вход аудио, левый канал
-#define SOUND_R_FREQ A3 // аналоговый пин вход аудио для режима с частотами (через кондер)
-#define BTN_PIN 3 // кнопка переключения режимов (PIN --- КНОПКА --- GND)
-#define LED_PIN 12 // пин DI светодиодной ленты
-#define POT_GND A0 // пин земля для потенциометра
-#define IR_PIN 2 // ИК приёмник
-
-// настройки радуги
-float RAINBOW_STEP = 5.5; // шаг изменения цвета радуги
-
-// отрисовка
-#define MODE 0 // режим при запуске
-#define MAIN_LOOP 5 // период основного цикла отрисовки (по умолчанию 5)
-
-// сигнал
-#define MONO 1 // 1 - только один канал (ПРАВЫЙ!!!!! SOUND_R!!!!!), 0 - два канала
-#define EXP 1.4 // степень усиления сигнала (для более "резкой" работы) (по умолчанию 1.4)
-#define POTENT 1 // 1 - используем потенциометр, 0 - используется внутренний источник опорного напряжения 1.1 В
-byte EMPTY_BRIGHT = 30; // яркость "не горящих" светодиодов (0 - 255)
-#define EMPTY_COLOR HUE_PURPLE // цвет "не горящих" светодиодов. Будет чёрный, если яркость 0
-
-// нижний порог шумов
-uint16_t LOW_PASS = 100; // нижний порог шумов режим VU, ручная настройка
-uint16_t SPEKTR_LOW_PASS = 40; // нижний порог шумов режим спектра, ручная настройка
-#define AUTO_LOW_PASS 0 // разрешить настройку нижнего порога шумов при запуске (по умолч. 0)
-#define EEPROM_LOW_PASS 1 // порог шумов хранится в энергонезависимой памяти (по умолч. 1)
-#define LOW_PASS_ADD 13 // "добавочная" величина к нижнему порогу, для надёжности (режим VU)
-#define LOW_PASS_FREQ_ADD 3 // "добавочная" величина к нижнему порогу, для надёжности (режим частот)
-
-// шкала громкости
-float SMOOTH = 0.5; // коэффициент плавности анимации VU (по умолчанию 0.5)
-#define MAX_COEF 1.8 // коэффициент громкости (максимальное равно срднему * этот коэф) (по умолчанию 1.8)
-
-// режим цветомузыки
-float SMOOTH_FREQ = 0.8; // коэффициент плавности анимации частот (по умолчанию 0.8)
-float MAX_COEF_FREQ = 1.2; // коэффициент порога для "вспышки" цветомузыки (по умолчанию 1.5)
-#define SMOOTH_STEP 20 // шаг уменьшения яркости в режиме цветомузыки (чем больше, тем быстрее гаснет)
-#define LOW_COLOR HUE_RED // цвет низких частот
-#define MID_COLOR HUE_GREEN // цвет средних
-#define HIGH_COLOR HUE_YELLOW // цвет высоких
-
-// режим стробоскопа
-int STROBE_PERIOD = 100; // период вспышек, миллисекунды
-#define STROBE_DUTY 20 // скважность вспышек (1 - 99) - отношение времени вспышки ко времени темноты
-#define STROBE_COLOR HUE_YELLOW // цвет стробоскопа
-#define STROBE_SAT 0 // насыщенность. Если 0 - цвет будет БЕЛЫЙ при любом цвете (0 - 255)
-byte STROBE_SMOOTH = 100; // скорость нарастания/угасания вспышки (0 - 255)
-
-// режим подсветки
-byte LIGHT_COLOR = 0; // начальный цвет подсветки
-byte LIGHT_SAT = 200; // начальная насыщенность подсветки
-byte COLOR_SPEED = 100;
-int RAINBOW_PERIOD = 3;
-float RAINBOW_STEP_2 = 5.5;
-
-// режим бегущих частот
-byte RUNNING_SPEED = 60;
-
-// режим анализатора спектра
-byte HUE_START = 0;
-byte HUE_STEP = 5;
-#define LIGHT_SMOOTH 2
-
-/*
- Цвета для HSV
- HUE_RED
- HUE_ORANGE
- HUE_YELLOW
- HUE_GREEN
- HUE_AQUA
- HUE_BLUE
- HUE_PURPLE
- HUE_PINK
-*/
-// --------------------------- НАСТРОЙКИ ---------------------------
-
-// ----- КНОПКИ ПУЛЬТА -----
-#define BUTT_UP 0xE51CA6AD
-#define BUTT_DOWN 0xD22353AD
-#define BUTT_LEFT 0x517068AD
-#define BUTT_RIGHT 0xAC2A56AD
-#define BUTT_OK 0x1B92DDAD
-#define BUTT_1 0x68E456AD
-#define BUTT_2 0xF08A26AD
-#define BUTT_3 0x151CD6AD
-#define BUTT_4 0x18319BAD
-#define BUTT_5 0xF39EEBAD
-#define BUTT_6 0x4AABDFAD
-#define BUTT_7 0xE25410AD
-#define BUTT_8 0x297C76AD
-#define BUTT_9 0x14CE54AD
-#define BUTT_0 0xC089F6AD
-#define BUTT_STAR 0xAF3F1BAD
-#define BUTT_HASH 0x38379AD
-// ----- КНОПКИ ПУЛЬТА -----
-
-// ------------------------------ ДЛЯ РАЗРАБОТЧИКОВ --------------------------------
-#define MODE_AMOUNT 9 // количество режимов
-
-#define STRIPE NUM_LEDS / 5
-float freq_to_stripe = NUM_LEDS / 40; // /2 так как симметрия, и /20 так как 20 частот
-
-#define FHT_N 64 // ширина спектра х2
-#define LOG_OUT 1
-#include // преобразование Хартли
-
-#include
-
-#define FASTLED_ALLOW_INTERRUPTS 1
-#include "FastLED.h"
-CRGB leds[NUM_LEDS];
-
-#include "GyverButton.h"
-GButton butt1(BTN_PIN);
-
-#include "IRLremote.h"
-CHashIR IRLremote;
-uint32_t IRdata;
-
-// градиент-палитра от зелёного к красному
-DEFINE_GRADIENT_PALETTE(soundlevel_gp) {
- 0, 0, 255, 0, // green
- 100, 255, 255, 0, // yellow
- 150, 255, 100, 0, // orange
- 200, 255, 50, 0, // red
- 255, 255, 0, 0 // red
-};
-CRGBPalette32 myPal = soundlevel_gp;
-
-byte Rlenght, Llenght;
-float RsoundLevel, RsoundLevel_f;
-float LsoundLevel, LsoundLevel_f;
-
-float averageLevel = 50;
-int maxLevel = 100;
-byte MAX_CH = NUM_LEDS / 2;
-int hue;
-unsigned long main_timer, hue_timer, strobe_timer, running_timer, color_timer, rainbow_timer, eeprom_timer;
-float averK = 0.006;
-byte count;
-float index = (float)255 / MAX_CH; // коэффициент перевода для палитры
-boolean lowFlag;
-byte low_pass;
-int RcurrentLevel, LcurrentLevel;
-int colorMusic[3];
-float colorMusic_f[3], colorMusic_aver[3];
-boolean colorMusicFlash[3], strobeUp_flag, strobeDwn_flag;
-byte this_mode = MODE;
-int thisBright[3], strobe_bright = 0;
-unsigned int light_time = STROBE_PERIOD * STROBE_DUTY / 100;
-volatile boolean ir_flag;
-boolean settings_mode, ONstate = true;
-int8_t freq_strobe_mode, light_mode;
-int freq_max;
-float freq_max_f, rainbow_steps;
-int freq_f[32];
-int this_color;
-boolean running_flag[3], eeprom_flag;
-
-#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
-#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
-// ------------------------------ ДЛЯ РАЗРАБОТЧИКОВ --------------------------------
-
-void setup() {
- Serial.begin(9600);
- FastLED.addLeds(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
- FastLED.setBrightness(BRIGHTNESS);
-
- pinMode(13, OUTPUT);
- digitalWrite(13, LOW);
-
- pinMode(POT_GND, OUTPUT);
- digitalWrite(POT_GND, LOW);
- butt1.setTimeout(900);
-
- IRLremote.begin(IR_PIN);
-
- // для увеличения точности уменьшаем опорное напряжение,
- // выставив EXTERNAL и подключив Aref к выходу 3.3V на плате через делитель
- // GND ---[10-20 кОм] --- REF --- [10 кОм] --- 3V3
- // в данной схеме GND берётся из А0 для удобства подключения
- if (POTENT) analogReference(EXTERNAL);
- else analogReference(INTERNAL);
-
- // жуткая магия, меняем частоту оцифровки до 18 кГц
- // команды на ебучем ассемблере, даже не спрашивайте, как это работает
- sbi(ADCSRA, ADPS2);
- cbi(ADCSRA, ADPS1);
- sbi(ADCSRA, ADPS0);
-
- if (RESET_SETTINGS) EEPROM.write(100, 0); // сброс флага настроек
-
- if (AUTO_LOW_PASS && !EEPROM_LOW_PASS) { // если разрешена автонастройка нижнего порога шумов
- autoLowPass();
- }
- if (EEPROM_LOW_PASS) { // восстановить значения шумов из памяти
- LOW_PASS = EEPROM.readInt(70);
- SPEKTR_LOW_PASS = EEPROM.readInt(72);
- }
-
- // в 100 ячейке хранится число 100. Если нет - значит это первый запуск системы
- if (KEEP_SETTINGS) {
- if (EEPROM.read(100) != 100) {
- //Serial.println(F("First start"));
- EEPROM.write(100, 100);
- updateEEPROM();
- } else {
- readEEPROM();
- }
- }
-}
-
-void loop() {
- buttonTick(); // опрос и обработка кнопки
- remoteTick(); // опрос ИК пульта
- mainLoop(); // главный цикл обработки и отрисовки
- eepromTick(); // проверка не пора ли сохранить настройки
-}
-
-void mainLoop() {
- // главный цикл отрисовки
- if (ONstate) {
- if (millis() - main_timer > MAIN_LOOP) {
- // сбрасываем значения
- RsoundLevel = 0;
- LsoundLevel = 0;
-
- // перваые два режима - громкость (VU meter)
- if (this_mode == 0 || this_mode == 1) {
- for (byte i = 0; i < 100; i ++) { // делаем 100 измерений
- RcurrentLevel = analogRead(SOUND_R); // с правого
- if (!MONO) LcurrentLevel = analogRead(SOUND_L); // и левого каналов
-
- if (RsoundLevel < RcurrentLevel) RsoundLevel = RcurrentLevel; // ищем максимальное
- if (!MONO) if (LsoundLevel < LcurrentLevel) LsoundLevel = LcurrentLevel; // ищем максимальное
- }
-
- // фильтруем по нижнему порогу шумов
- RsoundLevel = map(RsoundLevel, LOW_PASS, 1023, 0, 500);
- if (!MONO)LsoundLevel = map(LsoundLevel, LOW_PASS, 1023, 0, 500);
-
- // ограничиваем диапазон
- RsoundLevel = constrain(RsoundLevel, 0, 500);
- if (!MONO)LsoundLevel = constrain(LsoundLevel, 0, 500);
-
- // возводим в степень (для большей чёткости работы)
- RsoundLevel = pow(RsoundLevel, EXP);
- if (!MONO)LsoundLevel = pow(LsoundLevel, EXP);
-
- // фильтр
- RsoundLevel_f = RsoundLevel * SMOOTH + RsoundLevel_f * (1 - SMOOTH);
- if (!MONO)LsoundLevel_f = LsoundLevel * SMOOTH + LsoundLevel_f * (1 - SMOOTH);
-
- if (MONO) LsoundLevel_f = RsoundLevel_f; // если моно, то левый = правому
-
- // заливаем "подложку", если яркость достаточная
- if (EMPTY_BRIGHT > 5) {
- for (int i = 0; i < NUM_LEDS; i++)
- leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- }
-
- // если значение выше порога - начинаем самое интересное
- if (RsoundLevel_f > 15 && LsoundLevel_f > 15) {
-
- // расчёт общей средней громкости с обоих каналов, фильтрация.
- // Фильтр очень медленный, сделано специально для автогромкости
- averageLevel = (float)(RsoundLevel_f + LsoundLevel_f) / 2 * averK + averageLevel * (1 - averK);
-
- // принимаем максимальную громкость шкалы как среднюю, умноженную на некоторый коэффициент MAX_COEF
- maxLevel = (float)averageLevel * MAX_COEF;
-
- // преобразуем сигнал в длину ленты (где MAX_CH это половина количества светодиодов)
- Rlenght = map(RsoundLevel_f, 0, maxLevel, 0, MAX_CH);
- Llenght = map(LsoundLevel_f, 0, maxLevel, 0, MAX_CH);
-
- // ограничиваем до макс. числа светодиодов
- Rlenght = constrain(Rlenght, 0, MAX_CH);
- Llenght = constrain(Llenght, 0, MAX_CH);
-
- animation(); // отрисовать
- }
- }
-
- // 3-5 режим - цветомузыка
- if (this_mode == 2 || this_mode == 3 || this_mode == 4 || this_mode == 7 || this_mode == 8) {
- analyzeAudio();
- colorMusic[0] = 0;
- colorMusic[1] = 0;
- colorMusic[2] = 0;
- for (int i = 0 ; i < 32 ; i++) {
- if (fht_log_out[i] < SPEKTR_LOW_PASS) fht_log_out[i] = 0;
- }
- // низкие частоты, выборка со 2 по 5 тон (0 и 1 зашумленные!)
- for (byte i = 2; i < 6; i++) {
- if (fht_log_out[i] > colorMusic[0]) colorMusic[0] = fht_log_out[i];
- }
- // средние частоты, выборка с 6 по 10 тон
- for (byte i = 6; i < 11; i++) {
- if (fht_log_out[i] > colorMusic[1]) colorMusic[1] = fht_log_out[i];
- }
- // высокие частоты, выборка с 11 по 31 тон
- for (byte i = 11; i < 32; i++) {
- if (fht_log_out[i] > colorMusic[2]) colorMusic[2] = fht_log_out[i];
- }
- freq_max = 0;
- for (byte i = 0; i < 30; i++) {
- if (fht_log_out[i + 2] > freq_max) freq_max = fht_log_out[i + 2];
- if (freq_max < 5) freq_max = 5;
-
- if (freq_f[i] < fht_log_out[i + 2]) freq_f[i] = fht_log_out[i + 2];
- if (freq_f[i] > 0) freq_f[i] -= LIGHT_SMOOTH;
- else freq_f[i] = 0;
- }
- freq_max_f = freq_max * averK + freq_max_f * (1 - averK);
- for (byte i = 0; i < 3; i++) {
- colorMusic_aver[i] = colorMusic[i] * averK + colorMusic_aver[i] * (1 - averK); // общая фильтрация
- colorMusic_f[i] = colorMusic[i] * SMOOTH_FREQ + colorMusic_f[i] * (1 - SMOOTH_FREQ); // локальная
- if (colorMusic_f[i] > ((float)colorMusic_aver[i] * MAX_COEF_FREQ)) {
- thisBright[i] = 255;
- colorMusicFlash[i] = true;
- running_flag[i] = true;
- } else colorMusicFlash[i] = false;
- if (thisBright[i] >= 0) thisBright[i] -= SMOOTH_STEP;
- if (thisBright[i] < EMPTY_BRIGHT) {
- thisBright[i] = EMPTY_BRIGHT;
- running_flag[i] = false;
- }
- }
- animation();
- }
- if (this_mode == 5) {
- if ((long)millis() - strobe_timer > STROBE_PERIOD) {
- strobe_timer = millis();
- strobeUp_flag = true;
- strobeDwn_flag = false;
- }
- if ((long)millis() - strobe_timer > light_time) {
- strobeDwn_flag = true;
- }
- if (strobeUp_flag) { // если настало время пыхнуть
- if (strobe_bright < 255) // если яркость не максимальная
- strobe_bright += STROBE_SMOOTH; // увелчить
- if (strobe_bright > 255) { // если пробили макс. яркость
- strobe_bright = 255; // оставить максимум
- strobeUp_flag = false; // флаг опустить
- }
- }
-
- if (strobeDwn_flag) { // гаснем
- if (strobe_bright > 0) // если яркость не минимальная
- strobe_bright -= STROBE_SMOOTH; // уменьшить
- if (strobe_bright < 0) { // если пробили мин. яркость
- strobeDwn_flag = false;
- strobe_bright = 0; // оставить 0
- }
- }
- animation();
- }
- if (this_mode == 6) animation();
-
- if (!IRLremote.receiving()) // если на ИК приёмник не приходит сигнал (без этого НЕ РАБОТАЕТ!)
- FastLED.show(); // отправить значения на ленту
-
- if (this_mode != 7) // 7 режиму не нужна очистка!!!
- FastLED.clear(); // очистить массив пикселей
- main_timer = millis(); // сбросить таймер
- }
- }
-}
-
-void animation() {
- // согласно режиму
- switch (this_mode) {
- case 0:
- count = 0;
- for (int i = (MAX_CH - 1); i > ((MAX_CH - 1) - Rlenght); i--) {
- leds[i] = ColorFromPalette(myPal, (count * index)); // заливка по палитре " от зелёного к красному"
- count++;
- }
- count = 0;
- for (int i = (MAX_CH); i < (MAX_CH + Llenght); i++ ) {
- leds[i] = ColorFromPalette(myPal, (count * index)); // заливка по палитре " от зелёного к красному"
- count++;
- }
- if (EMPTY_BRIGHT > 0) {
- CHSV this_dark = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- for (int i = ((MAX_CH - 1) - Rlenght); i > 0; i--)
- leds[i] = this_dark;
- for (int i = MAX_CH + Llenght; i < NUM_LEDS; i++)
- leds[i] = this_dark;
- }
- break;
- case 1:
- if (millis() - rainbow_timer > 30) {
- rainbow_timer = millis();
- hue = floor((float)hue + RAINBOW_STEP);
- }
- count = 0;
- for (int i = (MAX_CH - 1); i > ((MAX_CH - 1) - Rlenght); i--) {
- leds[i] = ColorFromPalette(RainbowColors_p, (count * index) / 2 - hue); // заливка по палитре радуга
- count++;
- }
- count = 0;
- for (int i = (MAX_CH); i < (MAX_CH + Llenght); i++ ) {
- leds[i] = ColorFromPalette(RainbowColors_p, (count * index) / 2 - hue); // заливка по палитре радуга
- count++;
- }
- if (EMPTY_BRIGHT > 0) {
- CHSV this_dark = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- for (int i = ((MAX_CH - 1) - Rlenght); i > 0; i--)
- leds[i] = this_dark;
- for (int i = MAX_CH + Llenght; i < NUM_LEDS; i++)
- leds[i] = this_dark;
- }
- break;
- case 2:
- for (int i = 0; i < NUM_LEDS; i++) {
- if (i < STRIPE) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (i < STRIPE * 2) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < STRIPE * 3) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else if (i < STRIPE * 4) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < STRIPE * 5) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- }
- break;
- case 3:
- for (int i = 0; i < NUM_LEDS; i++) {
- if (i < NUM_LEDS / 3) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (i < NUM_LEDS * 2 / 3) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < NUM_LEDS) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
- }
- break;
- case 4:
- switch (freq_strobe_mode) {
- case 0:
- if (colorMusicFlash[2]) HIGHS();
- else if (colorMusicFlash[1]) MIDS();
- else if (colorMusicFlash[0]) LOWS();
- else SILENCE();
- break;
- case 1:
- if (colorMusicFlash[2]) HIGHS();
- else SILENCE();
- break;
- case 2:
- if (colorMusicFlash[1]) MIDS();
- else SILENCE();
- break;
- case 3:
- if (colorMusicFlash[0]) LOWS();
- else SILENCE();
- break;
- }
- break;
- case 5:
- if (strobe_bright > 0)
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(STROBE_COLOR, STROBE_SAT, strobe_bright);
- else
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 6:
- switch (light_mode) {
- case 0: for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(LIGHT_COLOR, LIGHT_SAT, 255);
- break;
- case 1:
- if (millis() - color_timer > COLOR_SPEED) {
- color_timer = millis();
- if (++this_color > 255) this_color = 0;
- }
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(this_color, LIGHT_SAT, 255);
- break;
- case 2:
- if (millis() - rainbow_timer > 30) {
- rainbow_timer = millis();
- this_color += RAINBOW_PERIOD;
- if (this_color > 255) this_color = 0;
- if (this_color < 0) this_color = 255;
- }
- rainbow_steps = this_color;
- for (int i = 0; i < NUM_LEDS; i++) {
- leds[i] = CHSV((int)floor(rainbow_steps), 255, 255);
- rainbow_steps += RAINBOW_STEP_2;
- if (rainbow_steps > 255) rainbow_steps = 0;
- if (rainbow_steps < 0) rainbow_steps = 255;
- }
- break;
- }
- break;
- case 7:
- switch (freq_strobe_mode) {
- case 0:
- if (running_flag[2]) leds[NUM_LEDS / 2] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (running_flag[1]) leds[NUM_LEDS / 2] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (running_flag[0]) leds[NUM_LEDS / 2] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 1:
- if (running_flag[2]) leds[NUM_LEDS / 2] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 2:
- if (running_flag[1]) leds[NUM_LEDS / 2] = CHSV(MID_COLOR, 255, thisBright[1]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 3:
- if (running_flag[0]) leds[NUM_LEDS / 2] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- }
- leds[(NUM_LEDS / 2) - 1] = leds[NUM_LEDS / 2];
- if (millis() - running_timer > RUNNING_SPEED) {
- running_timer = millis();
- for (byte i = 0; i < NUM_LEDS / 2 - 1; i++) {
- leds[i] = leds[i + 1];
- leds[NUM_LEDS - i - 1] = leds[i];
- }
- }
- break;
- case 8:
- byte HUEindex = HUE_START;
- for (byte i = 0; i < NUM_LEDS / 2; i++) {
- byte this_bright = map(freq_f[(int)floor((NUM_LEDS / 2 - i) / freq_to_stripe)], 0, freq_max_f, 0, 255);
- this_bright = constrain(this_bright, 0, 255);
- leds[i] = CHSV(HUEindex, 255, this_bright);
- leds[NUM_LEDS - i - 1] = leds[i];
- HUEindex += HUE_STEP;
- if (HUEindex > 255) HUEindex = 0;
- }
- break;
- }
-}
-
-void HIGHS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
-}
-void MIDS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
-}
-void LOWS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
-}
-void SILENCE() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
-}
-
-// вспомогательная функция, изменяет величину value на шаг incr в пределах minimum.. maximum
-int smartIncr(int value, int incr_step, int mininmum, int maximum) {
- int val_buf = value + incr_step;
- val_buf = constrain(val_buf, mininmum, maximum);
- return val_buf;
-}
-
-float smartIncrFloat(float value, float incr_step, float mininmum, float maximum) {
- float val_buf = value + incr_step;
- val_buf = constrain(val_buf, mininmum, maximum);
- return val_buf;
-}
-
-void remoteTick() {
- if (IRLremote.available()) {
- auto data = IRLremote.read();
- IRdata = data.command;
- ir_flag = true;
- }
- if (ir_flag) { // если данные пришли
- eeprom_timer = millis();
- eeprom_flag = true;
- switch (IRdata) {
- // режимы
- case BUTT_1: this_mode = 0;
- break;
- case BUTT_2: this_mode = 1;
- break;
- case BUTT_3: this_mode = 2;
- break;
- case BUTT_4: this_mode = 3;
- break;
- case BUTT_5: this_mode = 4;
- break;
- case BUTT_6: this_mode = 5;
- break;
- case BUTT_7: this_mode = 6;
- break;
- case BUTT_8: this_mode = 7;
- break;
- case BUTT_9: this_mode = 8;
- break;
- case BUTT_0: fullLowPass();
- break;
- case BUTT_STAR: ONstate = !ONstate; FastLED.clear(); FastLED.show(); updateEEPROM();
- break;
- case BUTT_HASH:
- switch (this_mode) {
- case 4:
- case 7: if (++freq_strobe_mode > 3) freq_strobe_mode = 0;
- break;
- case 6: if (++light_mode > 2) light_mode = 0;
- break;
- }
- break;
- case BUTT_OK: settings_mode = !settings_mode; digitalWrite(13, settings_mode);
- break;
- case BUTT_UP:
- if (settings_mode) {
- // ВВЕРХ общие настройки
- EMPTY_BRIGHT = smartIncr(EMPTY_BRIGHT, 5, 0, 255);
- } else {
- switch (this_mode) {
- case 0:
- break;
- case 1: RAINBOW_STEP = smartIncrFloat(RAINBOW_STEP, 0.5, 0.5, 20);
- break;
- case 2:
- case 3:
- case 4: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, 0.1, 0, 5);
- break;
- case 5: STROBE_PERIOD = smartIncr(STROBE_PERIOD, 20, 1, 1000);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_SAT = smartIncr(LIGHT_SAT, 20, 0, 255);
- break;
- case 1: LIGHT_SAT = smartIncr(LIGHT_SAT, 20, 0, 255);
- break;
- case 2: RAINBOW_STEP_2 = smartIncrFloat(RAINBOW_STEP_2, 0.5, 0.5, 10);
- break;
- }
- break;
- case 7: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, 0.1, 0.0, 10);
- break;
- case 8: HUE_START = smartIncr(HUE_START, 10, 0, 255);
- break;
- }
- }
- break;
- case BUTT_DOWN:
- if (settings_mode) {
- // ВНИЗ общие настройки
- EMPTY_BRIGHT = smartIncr(EMPTY_BRIGHT, -5, 0, 255);
- } else {
- switch (this_mode) {
- case 0:
- break;
- case 1: RAINBOW_STEP = smartIncrFloat(RAINBOW_STEP, -0.5, 0.5, 20);
- break;
- case 2:
- case 3:
- case 4: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, -0.1, 0, 5);
- break;
- case 5: STROBE_PERIOD = smartIncr(STROBE_PERIOD, -20, 1, 1000);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_SAT = smartIncr(LIGHT_SAT, -20, 0, 255);
- break;
- case 1: LIGHT_SAT = smartIncr(LIGHT_SAT, -20, 0, 255);
- break;
- case 2: RAINBOW_STEP_2 = smartIncrFloat(RAINBOW_STEP_2, -0.5, 0.5, 10);
- break;
- }
- break;
- case 7: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, -0.1, 0.0, 10);
- break;
- case 8: HUE_START = smartIncr(HUE_START, -10, 0, 255);
- break;
- }
- }
- break;
- case BUTT_LEFT:
- if (settings_mode) {
- // ВЛЕВО общие настройки
- BRIGHTNESS = smartIncr(BRIGHTNESS, -20, 0, 255);
- FastLED.setBrightness(BRIGHTNESS);
- } else {
- switch (this_mode) {
- case 0:
- case 1: SMOOTH = smartIncrFloat(SMOOTH, -0.05, 0.05, 1);
- break;
- case 2:
- case 3:
- case 4: SMOOTH_FREQ = smartIncrFloat(SMOOTH_FREQ, -0.05, 0.05, 1);
- break;
- case 5: STROBE_SMOOTH = smartIncr(STROBE_SMOOTH, -20, 0, 255);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_COLOR = smartIncr(LIGHT_COLOR, -10, 0, 255);
- break;
- case 1: COLOR_SPEED = smartIncr(COLOR_SPEED, -10, 0, 255);
- break;
- case 2: RAINBOW_PERIOD = smartIncr(RAINBOW_PERIOD, -1, -20, 20);
- break;
- }
- break;
- case 7: RUNNING_SPEED = smartIncr(RUNNING_SPEED, -10, 1, 255);
- break;
- case 8: HUE_STEP = smartIncr(HUE_STEP, -1, 1, 255);
- break;
- }
- }
- break;
- case BUTT_RIGHT:
- if (settings_mode) {
- // ВПРАВО общие настройки
- BRIGHTNESS = smartIncr(BRIGHTNESS, 20, 0, 255);
- FastLED.setBrightness(BRIGHTNESS);
- } else {
- switch (this_mode) {
- case 0:
- case 1: SMOOTH = smartIncrFloat(SMOOTH, 0.05, 0.05, 1);
- break;
- case 2:
- case 3:
- case 4: SMOOTH_FREQ = smartIncrFloat(SMOOTH_FREQ, 0.05, 0.05, 1);
- break;
- case 5: STROBE_SMOOTH = smartIncr(STROBE_SMOOTH, 20, 0, 255);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_COLOR = smartIncr(LIGHT_COLOR, 10, 0, 255);
- break;
- case 1: COLOR_SPEED = smartIncr(COLOR_SPEED, 10, 0, 255);
- break;
- case 2: RAINBOW_PERIOD = smartIncr(RAINBOW_PERIOD, 1, -20, 20);
- break;
- }
- break;
- case 7: RUNNING_SPEED = smartIncr(RUNNING_SPEED, 10, 1, 255);
- break;
- case 8: HUE_STEP = smartIncr(HUE_STEP, 1, 1, 255);
- break;
- }
- }
- break;
- default: eeprom_flag = false; // если не распознали кнопку, не обновляем настройки!
- break;
- }
- ir_flag = false;
- }
-}
-
-void autoLowPass() {
- // для режима VU
- delay(10); // ждём инициализации АЦП
- int thisMax = 0; // максимум
- int thisLevel;
- for (byte i = 0; i < 200; i++) {
- thisLevel = analogRead(SOUND_R); // делаем 200 измерений
- if (thisLevel > thisMax) // ищем максимумы
- thisMax = thisLevel; // запоминаем
- delay(4); // ждём 4мс
- }
- LOW_PASS = thisMax + LOW_PASS_ADD; // нижний порог как максимум тишины + некая величина
-
- // для режима спектра
- thisMax = 0;
- for (byte i = 0; i < 100; i++) { // делаем 100 измерений
- analyzeAudio(); // разбить в спектр
- for (byte j = 2; j < 32; j++) { // первые 2 канала - хлам
- thisLevel = fht_log_out[j];
- if (thisLevel > thisMax) // ищем максимумы
- thisMax = thisLevel; // запоминаем
- }
- delay(4); // ждём 4мс
- }
- SPEKTR_LOW_PASS = thisMax + LOW_PASS_FREQ_ADD; // нижний порог как максимум тишины
-
- if (EEPROM_LOW_PASS && !AUTO_LOW_PASS) {
- EEPROM.updateInt(70, LOW_PASS);
- EEPROM.updateInt(72, SPEKTR_LOW_PASS);
- }
-}
-
-void analyzeAudio() {
- for (int i = 0 ; i < FHT_N ; i++) {
- int sample = analogRead(SOUND_R_FREQ);
- fht_input[i] = sample; // put real data into bins
- }
- fht_window(); // window the data for better frequency response
- fht_reorder(); // reorder the data before doing the fht
- fht_run(); // process the data in the fht
- fht_mag_log(); // take the output of the fht
-}
-
-void buttonTick() {
- butt1.tick(); // обязательная функция отработки. Должна постоянно опрашиваться
- if (butt1.isSingle()) // если единичное нажатие
- if (++this_mode >= MODE_AMOUNT) this_mode = 0; // изменить режим
-
- if (butt1.isHolded()) { // кнопка удержана
- fullLowPass();
- }
-}
-void fullLowPass() {
- digitalWrite(13, HIGH); // включить светодиод 13 пин
- FastLED.setBrightness(0); // погасить ленту
- FastLED.clear(); // очистить массив пикселей
- FastLED.show(); // отправить значения на ленту
- delay(500); // подождать чутка
- autoLowPass(); // измерить шумы
- delay(500); // подождать
- FastLED.setBrightness(BRIGHTNESS); // вернуть яркость
- digitalWrite(13, LOW); // выключить светодиод
-}
-void updateEEPROM() {
- EEPROM.updateByte(1, this_mode);
- EEPROM.updateByte(2, freq_strobe_mode);
- EEPROM.updateByte(3, light_mode);
- EEPROM.updateInt(4, RAINBOW_STEP);
- EEPROM.updateFloat(8, MAX_COEF_FREQ);
- EEPROM.updateInt(12, STROBE_PERIOD);
- EEPROM.updateInt(16, LIGHT_SAT);
- EEPROM.updateFloat(20, RAINBOW_STEP_2);
- EEPROM.updateInt(24, HUE_START);
- EEPROM.updateFloat(28, SMOOTH);
- EEPROM.updateFloat(32, SMOOTH_FREQ);
- EEPROM.updateInt(36, STROBE_SMOOTH);
- EEPROM.updateInt(40, LIGHT_COLOR);
- EEPROM.updateInt(44, COLOR_SPEED);
- EEPROM.updateInt(48, RAINBOW_PERIOD);
- EEPROM.updateInt(52, RUNNING_SPEED);
- EEPROM.updateInt(56, HUE_STEP);
- EEPROM.updateInt(60, EMPTY_BRIGHT);
-}
-void readEEPROM() {
- this_mode = EEPROM.readByte(1);
- freq_strobe_mode = EEPROM.readByte(2);
- light_mode = EEPROM.readByte(3);
- RAINBOW_STEP = EEPROM.readInt(4);
- MAX_COEF_FREQ = EEPROM.readFloat(8);
- STROBE_PERIOD = EEPROM.readInt(12);
- LIGHT_SAT = EEPROM.readInt(16);
- RAINBOW_STEP_2 = EEPROM.readFloat(20);
- HUE_START = EEPROM.readInt(24);
- SMOOTH = EEPROM.readFloat(28);
- SMOOTH_FREQ = EEPROM.readFloat(32);
- STROBE_SMOOTH = EEPROM.readInt(36);
- LIGHT_COLOR = EEPROM.readInt(40);
- COLOR_SPEED = EEPROM.readInt(44);
- RAINBOW_PERIOD = EEPROM.readInt(48);
- RUNNING_SPEED = EEPROM.readInt(52);
- HUE_STEP = EEPROM.readInt(56);
- EMPTY_BRIGHT = EEPROM.readInt(60);
-}
-void eepromTick() {
- if (eeprom_flag)
- if (millis() - eeprom_timer > 30000) { // 30 секунд после последнего нажатия с пульта
- eeprom_flag = false;
- eeprom_timer = millis();
- updateEEPROM();
- }
-}
diff --git a/firmware/Old versions/colorMusic_v2.6.1_WAVGAT/colorMusic_v2.6.1_WAVGAT.ino b/firmware/Old versions/colorMusic_v2.6.1_WAVGAT/colorMusic_v2.6.1_WAVGAT.ino
deleted file mode 100644
index 26c6f96..0000000
--- a/firmware/Old versions/colorMusic_v2.6.1_WAVGAT/colorMusic_v2.6.1_WAVGAT.ino
+++ /dev/null
@@ -1,944 +0,0 @@
-/*
- Версия 2.6 использует библиотеки FastLED и IRLremote!
- Библиотеки идут в архиве с проектом! https://alexgyver.ru/colormusic/
- Крутейшая свето-цветомузыка на Arduino и адресной светодиодной ленте WS2812b.
- Данная версия поддерживает около 410 светодиодов!
- Версия для ИК пульта WAVGAT
- Управление:
- - Однократное нажатие кнопки: смена режима
- - Удержание кнопки: калибровка нижнего порога шума
- Режимы работы (переключаются кнопкой):
- - VU meter (столбик громкости): от зелёного к красному
- - VU meter (столбик громкости): плавно бегущая радуга
- - Светомузыка по частотам: 5 полос симметрично
- - Светомузыка по частотам: 3 полосы
- - Светомузыка по частотам: 1 полоса
- - Стробоскоп
- - (2.0) Подсветка
- - (2.0) Бегущие частоты
- - (2.1) анализатор спектра
- Особенности:
- - Плавная анимация (можно настроить)
- - Автонастройка по громкости (можно настроить)
- - Фильтр нижнего шума (можно настроить)
- - Автокалибровка шума при запуске (можно настроить)
- - Поддержка стерео и моно звука (можно настроить)
- - (2.0) в режиме частот лента не гаснет полностью (EMPTY_BRIGHT)
- - (2.1) все настройки сохраняются в памяти и не сбрасываются при перезагрузке
- - Сохранение настроек происходит при выключении кнопкой звёздочка (*)
- - А также через 30 секунд после последнего нажатия на любую кнопку ИК пульта
-
- НАСТРОЙКА НИЖНЕГО ПОРОГА ШУМА (строки 65-71)
- - Включаем систему
- - Ставим музыку на паузу
- - Удерживаем кнопку 1 секунду ИЛИ жмём кнопку 0 на пульте
- Значения шумов будут записаны в память и САМИ загружаться при последующем запуске! Всё!
-
- Пульт:
- - Цифры (1 - 9) активируют режимы
- - Цифра 0: калибровка шума
- - Звёздочка (*): включить/выключить систему
- - Кнопка ОК: переключение между локальными и глобальными настройками)
- - Решётка (#): смена подрежима
- - Глобальные настройки (горит светодиод на плате):
- + Стрелки ← →: общая яркость горящих светодиодов
- + Стрелки ↑ ↓: яркость "не горящих" светодиодов
- - Локальные настройки (у каждого режима свои):
- 1 - Шкала громкости (градиент)
- Стрелки ← →: плавность анимации
- 2 - Шкала громкости (радуга)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: скорость радуги
- 3 - Цветомузыка (5 полос)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- 4 - Цветомузыка (3 полосы)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- 5 - Цветомузыка (1 полоса)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- Подрежимы #: 3 частоты / низкие / средние / высокие
- 6 - Стробоскоп
- Стрелки ← →: плавность вспышек
- Стрелки ↑ ↓: частота вспышек
- 7 - Цветная подсветка
- Подрежимы #:
- Постоянный: стрелки ← →: цвет, стрелки ↑ ↓: насыщенность
- Плавная смена: стрелки ← →: скорость, стрелки ↑ ↓: насыщенность
- Бегущая радуга: стрелки ← →: скорость, стрелки ↑ ↓: шаг радуги
- 8 - “Бегущие частоты”
- Стрелки ← →: скорость
- Стрелки ↑ ↓: чувствительность
- Подрежимы #: 3 частоты / низкие / средние / высокие
- 9 - Анализатор спектра
- Стрелки ← →: шаг цвета
- Стрелки ↑ ↓: цвет
- **************************************************
- Разработано: AlexGyver
- Страница проекта: http://alexgyver.ru/colormusic/
- GitHub: https://github.com/AlexGyver/ColorMusic
-*/
-
-// --------------------------- НАСТРОЙКИ ---------------------------
-#define KEEP_SETTINGS 1 // хранить ВСЕ настройки в памяти
-#define RESET_SETTINGS 0 // сброс настроек в памяти.
-// поставить 1. Прошиться. Поставить обратно 0. Прошиться. Всё.
-
-// лента
-#define NUM_LEDS 60 // количество светодиодов
-byte BRIGHTNESS = 200; // яркость (0 - 255)
-
-// пины
-#define SOUND_R A2 // аналоговый пин вход аудио, правый канал
-#define SOUND_L A1 // аналоговый пин вход аудио, левый канал
-#define SOUND_R_FREQ A3 // аналоговый пин вход аудио для режима с частотами (через кондер)
-#define BTN_PIN 3 // кнопка переключения режимов (PIN --- КНОПКА --- GND)
-#define LED_PIN 12 // пин DI светодиодной ленты
-#define POT_GND A0 // пин земля для потенциометра
-#define IR_PIN 2 // ИК приёмник
-
-// настройки радуги
-float RAINBOW_STEP = 5.5; // шаг изменения цвета радуги
-
-// отрисовка
-#define MODE 0 // режим при запуске
-#define MAIN_LOOP 5 // период основного цикла отрисовки (по умолчанию 5)
-
-// сигнал
-#define MONO 1 // 1 - только один канал (ПРАВЫЙ!!!!! SOUND_R!!!!!), 0 - два канала
-#define EXP 1.4 // степень усиления сигнала (для более "резкой" работы) (по умолчанию 1.4)
-#define POTENT 1 // 1 - используем потенциометр, 0 - используется внутренний источник опорного напряжения 1.1 В
-byte EMPTY_BRIGHT = 30; // яркость "не горящих" светодиодов (0 - 255)
-#define EMPTY_COLOR HUE_PURPLE // цвет "не горящих" светодиодов. Будет чёрный, если яркость 0
-
-// нижний порог шумов
-uint16_t LOW_PASS = 100; // нижний порог шумов режим VU, ручная настройка
-uint16_t SPEKTR_LOW_PASS = 40; // нижний порог шумов режим спектра, ручная настройка
-#define AUTO_LOW_PASS 0 // разрешить настройку нижнего порога шумов при запуске (по умолч. 0)
-#define EEPROM_LOW_PASS 1 // порог шумов хранится в энергонезависимой памяти (по умолч. 1)
-#define LOW_PASS_ADD 13 // "добавочная" величина к нижнему порогу, для надёжности (режим VU)
-#define LOW_PASS_FREQ_ADD 3 // "добавочная" величина к нижнему порогу, для надёжности (режим частот)
-
-// шкала громкости
-float SMOOTH = 0.5; // коэффициент плавности анимации VU (по умолчанию 0.5)
-#define MAX_COEF 1.8 // коэффициент громкости (максимальное равно срднему * этот коэф) (по умолчанию 1.8)
-
-// режим цветомузыки
-float SMOOTH_FREQ = 0.8; // коэффициент плавности анимации частот (по умолчанию 0.8)
-float MAX_COEF_FREQ = 1.2; // коэффициент порога для "вспышки" цветомузыки (по умолчанию 1.5)
-#define SMOOTH_STEP 20 // шаг уменьшения яркости в режиме цветомузыки (чем больше, тем быстрее гаснет)
-#define LOW_COLOR HUE_RED // цвет низких частот
-#define MID_COLOR HUE_GREEN // цвет средних
-#define HIGH_COLOR HUE_YELLOW // цвет высоких
-
-// режим стробоскопа
-int STROBE_PERIOD = 100; // период вспышек, миллисекунды
-#define STROBE_DUTY 20 // скважность вспышек (1 - 99) - отношение времени вспышки ко времени темноты
-#define STROBE_COLOR HUE_YELLOW // цвет стробоскопа
-#define STROBE_SAT 0 // насыщенность. Если 0 - цвет будет БЕЛЫЙ при любом цвете (0 - 255)
-byte STROBE_SMOOTH = 100; // скорость нарастания/угасания вспышки (0 - 255)
-
-// режим подсветки
-byte LIGHT_COLOR = 0; // начальный цвет подсветки
-byte LIGHT_SAT = 200; // начальная насыщенность подсветки
-byte COLOR_SPEED = 100;
-int RAINBOW_PERIOD = 3;
-float RAINBOW_STEP_2 = 5.5;
-
-// режим бегущих частот
-byte RUNNING_SPEED = 60;
-
-// режим анализатора спектра
-byte HUE_START = 0;
-byte HUE_STEP = 5;
-#define LIGHT_SMOOTH 2
-
-/*
- Цвета для HSV
- HUE_RED
- HUE_ORANGE
- HUE_YELLOW
- HUE_GREEN
- HUE_AQUA
- HUE_BLUE
- HUE_PURPLE
- HUE_PINK
-*/
-// --------------------------- НАСТРОЙКИ ---------------------------
-
-// ----- КНОПКИ ПУЛЬТА -----
-#define BUTT_UP 0xF39EEBAD
-#define BUTT_DOWN 0xC089F6AD
-#define BUTT_LEFT 0xE25410AD
-#define BUTT_RIGHT 0x14CE54AD
-#define BUTT_OK 0x297C76AD
-#define BUTT_1 0x4E5BA3AD
-#define BUTT_2 0xE51CA6AD
-#define BUTT_3 0xE207E1AD
-#define BUTT_4 0x517068AD
-#define BUTT_5 0x1B92DDAD
-#define BUTT_6 0xAC2A56AD
-#define BUTT_7 0x5484B6AD
-#define BUTT_8 0xD22353AD
-#define BUTT_9 0xDF3F4BAD
-#define BUTT_0 0xF08A26AD
-#define BUTT_STAR 0x68E456AD
-#define BUTT_HASH 0x151CD6AD
-// ----- КНОПКИ ПУЛЬТА -----
-
-// ------------------------------ ДЛЯ РАЗРАБОТЧИКОВ --------------------------------
-#define MODE_AMOUNT 9 // количество режимов
-
-#define STRIPE NUM_LEDS / 5
-float freq_to_stripe = NUM_LEDS / 40; // /2 так как симметрия, и /20 так как 20 частот
-
-#define FHT_N 64 // ширина спектра х2
-#define LOG_OUT 1
-#include // преобразование Хартли
-
-#include
-
-#define FASTLED_ALLOW_INTERRUPTS 1
-#include "FastLED.h"
-CRGB leds[NUM_LEDS];
-
-#include "GyverButton.h"
-GButton butt1(BTN_PIN);
-
-#include "IRLremote.h"
-CHashIR IRLremote;
-uint32_t IRdata;
-
-// градиент-палитра от зелёного к красному
-DEFINE_GRADIENT_PALETTE(soundlevel_gp) {
- 0, 0, 255, 0, // green
- 100, 255, 255, 0, // yellow
- 150, 255, 100, 0, // orange
- 200, 255, 50, 0, // red
- 255, 255, 0, 0 // red
-};
-CRGBPalette32 myPal = soundlevel_gp;
-
-byte Rlenght, Llenght;
-float RsoundLevel, RsoundLevel_f;
-float LsoundLevel, LsoundLevel_f;
-
-float averageLevel = 50;
-int maxLevel = 100;
-byte MAX_CH = NUM_LEDS / 2;
-int hue;
-unsigned long main_timer, hue_timer, strobe_timer, running_timer, color_timer, rainbow_timer, eeprom_timer;
-float averK = 0.006;
-byte count;
-float index = (float)255 / MAX_CH; // коэффициент перевода для палитры
-boolean lowFlag;
-byte low_pass;
-int RcurrentLevel, LcurrentLevel;
-int colorMusic[3];
-float colorMusic_f[3], colorMusic_aver[3];
-boolean colorMusicFlash[3], strobeUp_flag, strobeDwn_flag;
-byte this_mode = MODE;
-int thisBright[3], strobe_bright = 0;
-unsigned int light_time = STROBE_PERIOD * STROBE_DUTY / 100;
-volatile boolean ir_flag;
-boolean settings_mode, ONstate = true;
-int8_t freq_strobe_mode, light_mode;
-int freq_max;
-float freq_max_f, rainbow_steps;
-int freq_f[32];
-int this_color;
-boolean running_flag[3], eeprom_flag;
-
-#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
-#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
-// ------------------------------ ДЛЯ РАЗРАБОТЧИКОВ --------------------------------
-
-void setup() {
- Serial.begin(9600);
- FastLED.addLeds(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
- FastLED.setBrightness(BRIGHTNESS);
-
- pinMode(13, OUTPUT);
- digitalWrite(13, LOW);
-
- pinMode(POT_GND, OUTPUT);
- digitalWrite(POT_GND, LOW);
- butt1.setTimeout(900);
-
- IRLremote.begin(IR_PIN);
-
- // для увеличения точности уменьшаем опорное напряжение,
- // выставив EXTERNAL и подключив Aref к выходу 3.3V на плате через делитель
- // GND ---[10-20 кОм] --- REF --- [10 кОм] --- 3V3
- // в данной схеме GND берётся из А0 для удобства подключения
- if (POTENT) analogReference(EXTERNAL);
- else analogReference(INTERNAL);
-
- // жуткая магия, меняем частоту оцифровки до 18 кГц
- // команды на ебучем ассемблере, даже не спрашивайте, как это работает
- sbi(ADCSRA, ADPS2);
- cbi(ADCSRA, ADPS1);
- sbi(ADCSRA, ADPS0);
-
- if (RESET_SETTINGS) EEPROM.write(100, 0); // сброс флага настроек
-
- if (AUTO_LOW_PASS && !EEPROM_LOW_PASS) { // если разрешена автонастройка нижнего порога шумов
- autoLowPass();
- }
- if (EEPROM_LOW_PASS) { // восстановить значения шумов из памяти
- LOW_PASS = EEPROM.readInt(70);
- SPEKTR_LOW_PASS = EEPROM.readInt(72);
- }
-
- // в 100 ячейке хранится число 100. Если нет - значит это первый запуск системы
- if (KEEP_SETTINGS) {
- if (EEPROM.read(100) != 100) {
- //Serial.println(F("First start"));
- EEPROM.write(100, 100);
- updateEEPROM();
- } else {
- readEEPROM();
- }
- }
-}
-
-void loop() {
- buttonTick(); // опрос и обработка кнопки
- remoteTick(); // опрос ИК пульта
- mainLoop(); // главный цикл обработки и отрисовки
- eepromTick(); // проверка не пора ли сохранить настройки
-}
-
-void mainLoop() {
- // главный цикл отрисовки
- if (ONstate) {
- if (millis() - main_timer > MAIN_LOOP) {
- // сбрасываем значения
- RsoundLevel = 0;
- LsoundLevel = 0;
-
- // перваые два режима - громкость (VU meter)
- if (this_mode == 0 || this_mode == 1) {
- for (byte i = 0; i < 100; i ++) { // делаем 100 измерений
- RcurrentLevel = analogRead(SOUND_R); // с правого
- if (!MONO) LcurrentLevel = analogRead(SOUND_L); // и левого каналов
-
- if (RsoundLevel < RcurrentLevel) RsoundLevel = RcurrentLevel; // ищем максимальное
- if (!MONO) if (LsoundLevel < LcurrentLevel) LsoundLevel = LcurrentLevel; // ищем максимальное
- }
-
- // фильтруем по нижнему порогу шумов
- RsoundLevel = map(RsoundLevel, LOW_PASS, 1023, 0, 500);
- if (!MONO)LsoundLevel = map(LsoundLevel, LOW_PASS, 1023, 0, 500);
-
- // ограничиваем диапазон
- RsoundLevel = constrain(RsoundLevel, 0, 500);
- if (!MONO)LsoundLevel = constrain(LsoundLevel, 0, 500);
-
- // возводим в степень (для большей чёткости работы)
- RsoundLevel = pow(RsoundLevel, EXP);
- if (!MONO)LsoundLevel = pow(LsoundLevel, EXP);
-
- // фильтр
- RsoundLevel_f = RsoundLevel * SMOOTH + RsoundLevel_f * (1 - SMOOTH);
- if (!MONO)LsoundLevel_f = LsoundLevel * SMOOTH + LsoundLevel_f * (1 - SMOOTH);
-
- if (MONO) LsoundLevel_f = RsoundLevel_f; // если моно, то левый = правому
-
- // заливаем "подложку", если яркость достаточная
- if (EMPTY_BRIGHT > 5) {
- for (int i = 0; i < NUM_LEDS; i++)
- leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- }
-
- // если значение выше порога - начинаем самое интересное
- if (RsoundLevel_f > 15 && LsoundLevel_f > 15) {
-
- // расчёт общей средней громкости с обоих каналов, фильтрация.
- // Фильтр очень медленный, сделано специально для автогромкости
- averageLevel = (float)(RsoundLevel_f + LsoundLevel_f) / 2 * averK + averageLevel * (1 - averK);
-
- // принимаем максимальную громкость шкалы как среднюю, умноженную на некоторый коэффициент MAX_COEF
- maxLevel = (float)averageLevel * MAX_COEF;
-
- // преобразуем сигнал в длину ленты (где MAX_CH это половина количества светодиодов)
- Rlenght = map(RsoundLevel_f, 0, maxLevel, 0, MAX_CH);
- Llenght = map(LsoundLevel_f, 0, maxLevel, 0, MAX_CH);
-
- // ограничиваем до макс. числа светодиодов
- Rlenght = constrain(Rlenght, 0, MAX_CH);
- Llenght = constrain(Llenght, 0, MAX_CH);
-
- animation(); // отрисовать
- }
- }
-
- // 3-5 режим - цветомузыка
- if (this_mode == 2 || this_mode == 3 || this_mode == 4 || this_mode == 7 || this_mode == 8) {
- analyzeAudio();
- colorMusic[0] = 0;
- colorMusic[1] = 0;
- colorMusic[2] = 0;
- for (int i = 0 ; i < 32 ; i++) {
- if (fht_log_out[i] < SPEKTR_LOW_PASS) fht_log_out[i] = 0;
- }
- // низкие частоты, выборка со 2 по 5 тон (0 и 1 зашумленные!)
- for (byte i = 2; i < 6; i++) {
- if (fht_log_out[i] > colorMusic[0]) colorMusic[0] = fht_log_out[i];
- }
- // средние частоты, выборка с 6 по 10 тон
- for (byte i = 6; i < 11; i++) {
- if (fht_log_out[i] > colorMusic[1]) colorMusic[1] = fht_log_out[i];
- }
- // высокие частоты, выборка с 11 по 31 тон
- for (byte i = 11; i < 32; i++) {
- if (fht_log_out[i] > colorMusic[2]) colorMusic[2] = fht_log_out[i];
- }
- freq_max = 0;
- for (byte i = 0; i < 30; i++) {
- if (fht_log_out[i + 2] > freq_max) freq_max = fht_log_out[i + 2];
- if (freq_max < 5) freq_max = 5;
-
- if (freq_f[i] < fht_log_out[i + 2]) freq_f[i] = fht_log_out[i + 2];
- if (freq_f[i] > 0) freq_f[i] -= LIGHT_SMOOTH;
- else freq_f[i] = 0;
- }
- freq_max_f = freq_max * averK + freq_max_f * (1 - averK);
- for (byte i = 0; i < 3; i++) {
- colorMusic_aver[i] = colorMusic[i] * averK + colorMusic_aver[i] * (1 - averK); // общая фильтрация
- colorMusic_f[i] = colorMusic[i] * SMOOTH_FREQ + colorMusic_f[i] * (1 - SMOOTH_FREQ); // локальная
- if (colorMusic_f[i] > ((float)colorMusic_aver[i] * MAX_COEF_FREQ)) {
- thisBright[i] = 255;
- colorMusicFlash[i] = true;
- running_flag[i] = true;
- } else colorMusicFlash[i] = false;
- if (thisBright[i] >= 0) thisBright[i] -= SMOOTH_STEP;
- if (thisBright[i] < EMPTY_BRIGHT) {
- thisBright[i] = EMPTY_BRIGHT;
- running_flag[i] = false;
- }
- }
- animation();
- }
- if (this_mode == 5) {
- if ((long)millis() - strobe_timer > STROBE_PERIOD) {
- strobe_timer = millis();
- strobeUp_flag = true;
- strobeDwn_flag = false;
- }
- if ((long)millis() - strobe_timer > light_time) {
- strobeDwn_flag = true;
- }
- if (strobeUp_flag) { // если настало время пыхнуть
- if (strobe_bright < 255) // если яркость не максимальная
- strobe_bright += STROBE_SMOOTH; // увелчить
- if (strobe_bright > 255) { // если пробили макс. яркость
- strobe_bright = 255; // оставить максимум
- strobeUp_flag = false; // флаг опустить
- }
- }
-
- if (strobeDwn_flag) { // гаснем
- if (strobe_bright > 0) // если яркость не минимальная
- strobe_bright -= STROBE_SMOOTH; // уменьшить
- if (strobe_bright < 0) { // если пробили мин. яркость
- strobeDwn_flag = false;
- strobe_bright = 0; // оставить 0
- }
- }
- animation();
- }
- if (this_mode == 6) animation();
-
- if (!IRLremote.receiving()) // если на ИК приёмник не приходит сигнал (без этого НЕ РАБОТАЕТ!)
- FastLED.show(); // отправить значения на ленту
-
- if (this_mode != 7) // 7 режиму не нужна очистка!!!
- FastLED.clear(); // очистить массив пикселей
- main_timer = millis(); // сбросить таймер
- }
- }
-}
-
-void animation() {
- // согласно режиму
- switch (this_mode) {
- case 0:
- count = 0;
- for (int i = (MAX_CH - 1); i > ((MAX_CH - 1) - Rlenght); i--) {
- leds[i] = ColorFromPalette(myPal, (count * index)); // заливка по палитре " от зелёного к красному"
- count++;
- }
- count = 0;
- for (int i = (MAX_CH); i < (MAX_CH + Llenght); i++ ) {
- leds[i] = ColorFromPalette(myPal, (count * index)); // заливка по палитре " от зелёного к красному"
- count++;
- }
- if (EMPTY_BRIGHT > 0) {
- CHSV this_dark = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- for (int i = ((MAX_CH - 1) - Rlenght); i > 0; i--)
- leds[i] = this_dark;
- for (int i = MAX_CH + Llenght; i < NUM_LEDS; i++)
- leds[i] = this_dark;
- }
- break;
- case 1:
- if (millis() - rainbow_timer > 30) {
- rainbow_timer = millis();
- hue = floor((float)hue + RAINBOW_STEP);
- }
- count = 0;
- for (int i = (MAX_CH - 1); i > ((MAX_CH - 1) - Rlenght); i--) {
- leds[i] = ColorFromPalette(RainbowColors_p, (count * index) / 2 - hue); // заливка по палитре радуга
- count++;
- }
- count = 0;
- for (int i = (MAX_CH); i < (MAX_CH + Llenght); i++ ) {
- leds[i] = ColorFromPalette(RainbowColors_p, (count * index) / 2 - hue); // заливка по палитре радуга
- count++;
- }
- if (EMPTY_BRIGHT > 0) {
- CHSV this_dark = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- for (int i = ((MAX_CH - 1) - Rlenght); i > 0; i--)
- leds[i] = this_dark;
- for (int i = MAX_CH + Llenght; i < NUM_LEDS; i++)
- leds[i] = this_dark;
- }
- break;
- case 2:
- for (int i = 0; i < NUM_LEDS; i++) {
- if (i < STRIPE) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (i < STRIPE * 2) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < STRIPE * 3) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else if (i < STRIPE * 4) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < STRIPE * 5) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- }
- break;
- case 3:
- for (int i = 0; i < NUM_LEDS; i++) {
- if (i < NUM_LEDS / 3) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (i < NUM_LEDS * 2 / 3) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < NUM_LEDS) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
- }
- break;
- case 4:
- switch (freq_strobe_mode) {
- case 0:
- if (colorMusicFlash[2]) HIGHS();
- else if (colorMusicFlash[1]) MIDS();
- else if (colorMusicFlash[0]) LOWS();
- else SILENCE();
- break;
- case 1:
- if (colorMusicFlash[2]) HIGHS();
- else SILENCE();
- break;
- case 2:
- if (colorMusicFlash[1]) MIDS();
- else SILENCE();
- break;
- case 3:
- if (colorMusicFlash[0]) LOWS();
- else SILENCE();
- break;
- }
- break;
- case 5:
- if (strobe_bright > 0)
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(STROBE_COLOR, STROBE_SAT, strobe_bright);
- else
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 6:
- switch (light_mode) {
- case 0: for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(LIGHT_COLOR, LIGHT_SAT, 255);
- break;
- case 1:
- if (millis() - color_timer > COLOR_SPEED) {
- color_timer = millis();
- if (++this_color > 255) this_color = 0;
- }
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(this_color, LIGHT_SAT, 255);
- break;
- case 2:
- if (millis() - rainbow_timer > 30) {
- rainbow_timer = millis();
- this_color += RAINBOW_PERIOD;
- if (this_color > 255) this_color = 0;
- if (this_color < 0) this_color = 255;
- }
- rainbow_steps = this_color;
- for (int i = 0; i < NUM_LEDS; i++) {
- leds[i] = CHSV((int)floor(rainbow_steps), 255, 255);
- rainbow_steps += RAINBOW_STEP_2;
- if (rainbow_steps > 255) rainbow_steps = 0;
- if (rainbow_steps < 0) rainbow_steps = 255;
- }
- break;
- }
- break;
- case 7:
- switch (freq_strobe_mode) {
- case 0:
- if (running_flag[2]) leds[NUM_LEDS / 2] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (running_flag[1]) leds[NUM_LEDS / 2] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (running_flag[0]) leds[NUM_LEDS / 2] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 1:
- if (running_flag[2]) leds[NUM_LEDS / 2] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 2:
- if (running_flag[1]) leds[NUM_LEDS / 2] = CHSV(MID_COLOR, 255, thisBright[1]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 3:
- if (running_flag[0]) leds[NUM_LEDS / 2] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- }
- leds[(NUM_LEDS / 2) - 1] = leds[NUM_LEDS / 2];
- if (millis() - running_timer > RUNNING_SPEED) {
- running_timer = millis();
- for (byte i = 0; i < NUM_LEDS / 2 - 1; i++) {
- leds[i] = leds[i + 1];
- leds[NUM_LEDS - i - 1] = leds[i];
- }
- }
- break;
- case 8:
- byte HUEindex = HUE_START;
- for (byte i = 0; i < NUM_LEDS / 2; i++) {
- byte this_bright = map(freq_f[(int)floor((NUM_LEDS / 2 - i) / freq_to_stripe)], 0, freq_max_f, 0, 255);
- this_bright = constrain(this_bright, 0, 255);
- leds[i] = CHSV(HUEindex, 255, this_bright);
- leds[NUM_LEDS - i - 1] = leds[i];
- HUEindex += HUE_STEP;
- if (HUEindex > 255) HUEindex = 0;
- }
- break;
- }
-}
-
-void HIGHS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
-}
-void MIDS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
-}
-void LOWS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
-}
-void SILENCE() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
-}
-
-// вспомогательная функция, изменяет величину value на шаг incr в пределах minimum.. maximum
-int smartIncr(int value, int incr_step, int mininmum, int maximum) {
- int val_buf = value + incr_step;
- val_buf = constrain(val_buf, mininmum, maximum);
- return val_buf;
-}
-
-float smartIncrFloat(float value, float incr_step, float mininmum, float maximum) {
- float val_buf = value + incr_step;
- val_buf = constrain(val_buf, mininmum, maximum);
- return val_buf;
-}
-
-void remoteTick() {
- if (IRLremote.available()) {
- auto data = IRLremote.read();
- IRdata = data.command;
- ir_flag = true;
- }
- if (ir_flag) { // если данные пришли
- eeprom_timer = millis();
- eeprom_flag = true;
- switch (IRdata) {
- // режимы
- case BUTT_1: this_mode = 0;
- break;
- case BUTT_2: this_mode = 1;
- break;
- case BUTT_3: this_mode = 2;
- break;
- case BUTT_4: this_mode = 3;
- break;
- case BUTT_5: this_mode = 4;
- break;
- case BUTT_6: this_mode = 5;
- break;
- case BUTT_7: this_mode = 6;
- break;
- case BUTT_8: this_mode = 7;
- break;
- case BUTT_9: this_mode = 8;
- break;
- case BUTT_0: fullLowPass();
- break;
- case BUTT_STAR: ONstate = !ONstate; FastLED.clear(); FastLED.show(); updateEEPROM();
- break;
- case BUTT_HASH:
- switch (this_mode) {
- case 4:
- case 7: if (++freq_strobe_mode > 3) freq_strobe_mode = 0;
- break;
- case 6: if (++light_mode > 2) light_mode = 0;
- break;
- }
- break;
- case BUTT_OK: settings_mode = !settings_mode; digitalWrite(13, settings_mode);
- break;
- case BUTT_UP:
- if (settings_mode) {
- // ВВЕРХ общие настройки
- EMPTY_BRIGHT = smartIncr(EMPTY_BRIGHT, 5, 0, 255);
- } else {
- switch (this_mode) {
- case 0:
- break;
- case 1: RAINBOW_STEP = smartIncrFloat(RAINBOW_STEP, 0.5, 0.5, 20);
- break;
- case 2:
- case 3:
- case 4: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, 0.1, 0, 5);
- break;
- case 5: STROBE_PERIOD = smartIncr(STROBE_PERIOD, 20, 1, 1000);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_SAT = smartIncr(LIGHT_SAT, 20, 0, 255);
- break;
- case 1: LIGHT_SAT = smartIncr(LIGHT_SAT, 20, 0, 255);
- break;
- case 2: RAINBOW_STEP_2 = smartIncrFloat(RAINBOW_STEP_2, 0.5, 0.5, 10);
- break;
- }
- break;
- case 7: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, 0.1, 0.0, 10);
- break;
- case 8: HUE_START = smartIncr(HUE_START, 10, 0, 255);
- break;
- }
- }
- break;
- case BUTT_DOWN:
- if (settings_mode) {
- // ВНИЗ общие настройки
- EMPTY_BRIGHT = smartIncr(EMPTY_BRIGHT, -5, 0, 255);
- } else {
- switch (this_mode) {
- case 0:
- break;
- case 1: RAINBOW_STEP = smartIncrFloat(RAINBOW_STEP, -0.5, 0.5, 20);
- break;
- case 2:
- case 3:
- case 4: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, -0.1, 0, 5);
- break;
- case 5: STROBE_PERIOD = smartIncr(STROBE_PERIOD, -20, 1, 1000);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_SAT = smartIncr(LIGHT_SAT, -20, 0, 255);
- break;
- case 1: LIGHT_SAT = smartIncr(LIGHT_SAT, -20, 0, 255);
- break;
- case 2: RAINBOW_STEP_2 = smartIncrFloat(RAINBOW_STEP_2, -0.5, 0.5, 10);
- break;
- }
- break;
- case 7: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, -0.1, 0.0, 10);
- break;
- case 8: HUE_START = smartIncr(HUE_START, -10, 0, 255);
- break;
- }
- }
- break;
- case BUTT_LEFT:
- if (settings_mode) {
- // ВЛЕВО общие настройки
- BRIGHTNESS = smartIncr(BRIGHTNESS, -20, 0, 255);
- FastLED.setBrightness(BRIGHTNESS);
- } else {
- switch (this_mode) {
- case 0:
- case 1: SMOOTH = smartIncrFloat(SMOOTH, -0.05, 0.05, 1);
- break;
- case 2:
- case 3:
- case 4: SMOOTH_FREQ = smartIncrFloat(SMOOTH_FREQ, -0.05, 0.05, 1);
- break;
- case 5: STROBE_SMOOTH = smartIncr(STROBE_SMOOTH, -20, 0, 255);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_COLOR = smartIncr(LIGHT_COLOR, -10, 0, 255);
- break;
- case 1: COLOR_SPEED = smartIncr(COLOR_SPEED, -10, 0, 255);
- break;
- case 2: RAINBOW_PERIOD = smartIncr(RAINBOW_PERIOD, -1, -20, 20);
- break;
- }
- break;
- case 7: RUNNING_SPEED = smartIncr(RUNNING_SPEED, -10, 1, 255);
- break;
- case 8: HUE_STEP = smartIncr(HUE_STEP, -1, 1, 255);
- break;
- }
- }
- break;
- case BUTT_RIGHT:
- if (settings_mode) {
- // ВПРАВО общие настройки
- BRIGHTNESS = smartIncr(BRIGHTNESS, 20, 0, 255);
- FastLED.setBrightness(BRIGHTNESS);
- } else {
- switch (this_mode) {
- case 0:
- case 1: SMOOTH = smartIncrFloat(SMOOTH, 0.05, 0.05, 1);
- break;
- case 2:
- case 3:
- case 4: SMOOTH_FREQ = smartIncrFloat(SMOOTH_FREQ, 0.05, 0.05, 1);
- break;
- case 5: STROBE_SMOOTH = smartIncr(STROBE_SMOOTH, 20, 0, 255);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_COLOR = smartIncr(LIGHT_COLOR, 10, 0, 255);
- break;
- case 1: COLOR_SPEED = smartIncr(COLOR_SPEED, 10, 0, 255);
- break;
- case 2: RAINBOW_PERIOD = smartIncr(RAINBOW_PERIOD, 1, -20, 20);
- break;
- }
- break;
- case 7: RUNNING_SPEED = smartIncr(RUNNING_SPEED, 10, 1, 255);
- break;
- case 8: HUE_STEP = smartIncr(HUE_STEP, 1, 1, 255);
- break;
- }
- }
- break;
- default: eeprom_flag = false; // если не распознали кнопку, не обновляем настройки!
- break;
- }
- ir_flag = false;
- }
-}
-
-void autoLowPass() {
- // для режима VU
- delay(10); // ждём инициализации АЦП
- int thisMax = 0; // максимум
- int thisLevel;
- for (byte i = 0; i < 200; i++) {
- thisLevel = analogRead(SOUND_R); // делаем 200 измерений
- if (thisLevel > thisMax) // ищем максимумы
- thisMax = thisLevel; // запоминаем
- delay(4); // ждём 4мс
- }
- LOW_PASS = thisMax + LOW_PASS_ADD; // нижний порог как максимум тишины + некая величина
-
- // для режима спектра
- thisMax = 0;
- for (byte i = 0; i < 100; i++) { // делаем 100 измерений
- analyzeAudio(); // разбить в спектр
- for (byte j = 2; j < 32; j++) { // первые 2 канала - хлам
- thisLevel = fht_log_out[j];
- if (thisLevel > thisMax) // ищем максимумы
- thisMax = thisLevel; // запоминаем
- }
- delay(4); // ждём 4мс
- }
- SPEKTR_LOW_PASS = thisMax + LOW_PASS_FREQ_ADD; // нижний порог как максимум тишины
-
- if (EEPROM_LOW_PASS && !AUTO_LOW_PASS) {
- EEPROM.updateInt(70, LOW_PASS);
- EEPROM.updateInt(72, SPEKTR_LOW_PASS);
- }
-}
-
-void analyzeAudio() {
- for (int i = 0 ; i < FHT_N ; i++) {
- int sample = analogRead(SOUND_R_FREQ);
- fht_input[i] = sample; // put real data into bins
- }
- fht_window(); // window the data for better frequency response
- fht_reorder(); // reorder the data before doing the fht
- fht_run(); // process the data in the fht
- fht_mag_log(); // take the output of the fht
-}
-
-void buttonTick() {
- butt1.tick(); // обязательная функция отработки. Должна постоянно опрашиваться
- if (butt1.isSingle()) // если единичное нажатие
- if (++this_mode >= MODE_AMOUNT) this_mode = 0; // изменить режим
-
- if (butt1.isHolded()) { // кнопка удержана
- fullLowPass();
- }
-}
-void fullLowPass() {
- digitalWrite(13, HIGH); // включить светодиод 13 пин
- FastLED.setBrightness(0); // погасить ленту
- FastLED.clear(); // очистить массив пикселей
- FastLED.show(); // отправить значения на ленту
- delay(500); // подождать чутка
- autoLowPass(); // измерить шумы
- delay(500); // подождать
- FastLED.setBrightness(BRIGHTNESS); // вернуть яркость
- digitalWrite(13, LOW); // выключить светодиод
-}
-void updateEEPROM() {
- EEPROM.updateByte(1, this_mode);
- EEPROM.updateByte(2, freq_strobe_mode);
- EEPROM.updateByte(3, light_mode);
- EEPROM.updateInt(4, RAINBOW_STEP);
- EEPROM.updateFloat(8, MAX_COEF_FREQ);
- EEPROM.updateInt(12, STROBE_PERIOD);
- EEPROM.updateInt(16, LIGHT_SAT);
- EEPROM.updateFloat(20, RAINBOW_STEP_2);
- EEPROM.updateInt(24, HUE_START);
- EEPROM.updateFloat(28, SMOOTH);
- EEPROM.updateFloat(32, SMOOTH_FREQ);
- EEPROM.updateInt(36, STROBE_SMOOTH);
- EEPROM.updateInt(40, LIGHT_COLOR);
- EEPROM.updateInt(44, COLOR_SPEED);
- EEPROM.updateInt(48, RAINBOW_PERIOD);
- EEPROM.updateInt(52, RUNNING_SPEED);
- EEPROM.updateInt(56, HUE_STEP);
- EEPROM.updateInt(60, EMPTY_BRIGHT);
-}
-void readEEPROM() {
- this_mode = EEPROM.readByte(1);
- freq_strobe_mode = EEPROM.readByte(2);
- light_mode = EEPROM.readByte(3);
- RAINBOW_STEP = EEPROM.readInt(4);
- MAX_COEF_FREQ = EEPROM.readFloat(8);
- STROBE_PERIOD = EEPROM.readInt(12);
- LIGHT_SAT = EEPROM.readInt(16);
- RAINBOW_STEP_2 = EEPROM.readFloat(20);
- HUE_START = EEPROM.readInt(24);
- SMOOTH = EEPROM.readFloat(28);
- SMOOTH_FREQ = EEPROM.readFloat(32);
- STROBE_SMOOTH = EEPROM.readInt(36);
- LIGHT_COLOR = EEPROM.readInt(40);
- COLOR_SPEED = EEPROM.readInt(44);
- RAINBOW_PERIOD = EEPROM.readInt(48);
- RUNNING_SPEED = EEPROM.readInt(52);
- HUE_STEP = EEPROM.readInt(56);
- EMPTY_BRIGHT = EEPROM.readInt(60);
-}
-void eepromTick() {
- if (eeprom_flag)
- if (millis() - eeprom_timer > 30000) { // 30 секунд после последнего нажатия с пульта
- eeprom_flag = false;
- eeprom_timer = millis();
- updateEEPROM();
- }
-}
diff --git a/firmware/Old versions/colorMusic_v2.6.2_KEYES/colorMusic_v2.6.2_KEYES.ino b/firmware/Old versions/colorMusic_v2.6.2_KEYES/colorMusic_v2.6.2_KEYES.ino
deleted file mode 100644
index 11ea27c..0000000
--- a/firmware/Old versions/colorMusic_v2.6.2_KEYES/colorMusic_v2.6.2_KEYES.ino
+++ /dev/null
@@ -1,952 +0,0 @@
-/*
- Версия 2.6 использует библиотеки FastLED и IRLremote!
- Библиотеки идут в архиве с проектом! https://alexgyver.ru/colormusic/
- Крутейшая свето-цветомузыка на Arduino и адресной светодиодной ленте WS2812b.
- Данная версия поддерживает около 410 светодиодов!
- Версия для ИК пульта KEYES
- Управление:
- - Однократное нажатие кнопки: смена режима
- - Удержание кнопки: калибровка нижнего порога шума
- Режимы работы (переключаются кнопкой):
- - VU meter (столбик громкости): от зелёного к красному
- - VU meter (столбик громкости): плавно бегущая радуга
- - Светомузыка по частотам: 5 полос симметрично
- - Светомузыка по частотам: 3 полосы
- - Светомузыка по частотам: 1 полоса
- - Стробоскоп
- - (2.0) Подсветка
- - (2.0) Бегущие частоты
- - (2.1) анализатор спектра
- Особенности:
- - Плавная анимация (можно настроить)
- - Автонастройка по громкости (можно настроить)
- - Фильтр нижнего шума (можно настроить)
- - Автокалибровка шума при запуске (можно настроить)
- - Поддержка стерео и моно звука (можно настроить)
- - (2.0) в режиме частот лента не гаснет полностью (EMPTY_BRIGHT)
- - (2.1) все настройки сохраняются в памяти и не сбрасываются при перезагрузке
- - Сохранение настроек происходит при выключении кнопкой звёздочка (*)
- - А также через 30 секунд после последнего нажатия на любую кнопку ИК пульта
-
- НАСТРОЙКА НИЖНЕГО ПОРОГА ШУМА (строки 65-71)
- - Включаем систему
- - Ставим музыку на паузу
- - Удерживаем кнопку 1 секунду ИЛИ жмём кнопку 0 на пульте
- Значения шумов будут записаны в память и САМИ загружаться при последующем запуске! Всё!
-
- Пульт:
- - Цифры (1 - 9) активируют режимы
- - Цифра 0: калибровка шума
- - Звёздочка (*): включить/выключить систему
- - Кнопка ОК: переключение между локальными и глобальными настройками)
- - Решётка (#): смена подрежима
- - Глобальные настройки (горит светодиод на плате):
- + Стрелки ← →: общая яркость горящих светодиодов
- + Стрелки ↑ ↓: яркость "не горящих" светодиодов
- - Локальные настройки (у каждого режима свои):
- 1 - Шкала громкости (градиент)
- Стрелки ← →: плавность анимации
- 2 - Шкала громкости (радуга)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: скорость радуги
- 3 - Цветомузыка (5 полос)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- 4 - Цветомузыка (3 полосы)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- 5 - Цветомузыка (1 полоса)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- Подрежимы #: 3 частоты / низкие / средние / высокие
- 6 - Стробоскоп
- Стрелки ← →: плавность вспышек
- Стрелки ↑ ↓: частота вспышек
- 7 - Цветная подсветка
- Подрежимы #:
- Постоянный: стрелки ← →: цвет, стрелки ↑ ↓: насыщенность
- Плавная смена: стрелки ← →: скорость, стрелки ↑ ↓: насыщенность
- Бегущая радуга: стрелки ← →: скорость, стрелки ↑ ↓: шаг радуги
- 8 - “Бегущие частоты”
- Стрелки ← →: скорость
- Стрелки ↑ ↓: чувствительность
- Подрежимы #: 3 частоты / низкие / средние / высокие
- 9 - Анализатор спектра
- Стрелки ← →: шаг цвета
- Стрелки ↑ ↓: цвет
- **************************************************
- Разработано: AlexGyver
- Страница проекта: http://alexgyver.ru/colormusic/
- GitHub: https://github.com/AlexGyver/ColorMusic
-*/
-
-// --------------------------- НАСТРОЙКИ ---------------------------
-#define KEEP_SETTINGS 1 // хранить ВСЕ настройки в памяти
-#define KEEP_STATE 1 // сохранять в памяти состояние вкл/выкл (с пульта)
-#define RESET_SETTINGS 0 // сброс настроек в памяти
-// поставить 1. Прошиться. Поставить обратно 0. Прошиться. Всё.
-
-// лента
-#define NUM_LEDS 60 // количество светодиодов
-byte BRIGHTNESS = 200; // яркость (0 - 255)
-
-// пины
-#define SOUND_R A2 // аналоговый пин вход аудио, правый канал
-#define SOUND_L A1 // аналоговый пин вход аудио, левый канал
-#define SOUND_R_FREQ A3 // аналоговый пин вход аудио для режима с частотами (через кондер)
-#define BTN_PIN 3 // кнопка переключения режимов (PIN --- КНОПКА --- GND)
-#define LED_PIN 12 // пин DI светодиодной ленты
-#define POT_GND A0 // пин земля для потенциометра
-#define IR_PIN 2 // ИК приёмник
-
-// настройки радуги
-float RAINBOW_STEP = 5.5; // шаг изменения цвета радуги
-
-// отрисовка
-#define MODE 0 // режим при запуске
-#define MAIN_LOOP 5 // период основного цикла отрисовки (по умолчанию 5)
-
-// сигнал
-#define MONO 1 // 1 - только один канал (ПРАВЫЙ!!!!! SOUND_R!!!!!), 0 - два канала
-#define EXP 1.4 // степень усиления сигнала (для более "резкой" работы) (по умолчанию 1.4)
-#define POTENT 1 // 1 - используем потенциометр, 0 - используется внутренний источник опорного напряжения 1.1 В
-byte EMPTY_BRIGHT = 30; // яркость "не горящих" светодиодов (0 - 255)
-#define EMPTY_COLOR HUE_PURPLE // цвет "не горящих" светодиодов. Будет чёрный, если яркость 0
-
-// нижний порог шумов
-uint16_t LOW_PASS = 100; // нижний порог шумов режим VU, ручная настройка
-uint16_t SPEKTR_LOW_PASS = 40; // нижний порог шумов режим спектра, ручная настройка
-#define AUTO_LOW_PASS 0 // разрешить настройку нижнего порога шумов при запуске (по умолч. 0)
-#define EEPROM_LOW_PASS 1 // порог шумов хранится в энергонезависимой памяти (по умолч. 1)
-#define LOW_PASS_ADD 13 // "добавочная" величина к нижнему порогу, для надёжности (режим VU)
-#define LOW_PASS_FREQ_ADD 3 // "добавочная" величина к нижнему порогу, для надёжности (режим частот)
-
-// шкала громкости
-float SMOOTH = 0.5; // коэффициент плавности анимации VU (по умолчанию 0.5)
-#define MAX_COEF 1.8 // коэффициент громкости (максимальное равно срднему * этот коэф) (по умолчанию 1.8)
-
-// режим цветомузыки
-float SMOOTH_FREQ = 0.8; // коэффициент плавности анимации частот (по умолчанию 0.8)
-float MAX_COEF_FREQ = 1.2; // коэффициент порога для "вспышки" цветомузыки (по умолчанию 1.5)
-#define SMOOTH_STEP 20 // шаг уменьшения яркости в режиме цветомузыки (чем больше, тем быстрее гаснет)
-#define LOW_COLOR HUE_RED // цвет низких частот
-#define MID_COLOR HUE_GREEN // цвет средних
-#define HIGH_COLOR HUE_YELLOW // цвет высоких
-
-// режим стробоскопа
-uint16_t STROBE_PERIOD = 100; // период вспышек, миллисекунды
-#define STROBE_DUTY 20 // скважность вспышек (1 - 99) - отношение времени вспышки ко времени темноты
-#define STROBE_COLOR HUE_YELLOW // цвет стробоскопа
-#define STROBE_SAT 0 // насыщенность. Если 0 - цвет будет БЕЛЫЙ при любом цвете (0 - 255)
-byte STROBE_SMOOTH = 100; // скорость нарастания/угасания вспышки (0 - 255)
-
-// режим подсветки
-byte LIGHT_COLOR = 0; // начальный цвет подсветки
-byte LIGHT_SAT = 200; // начальная насыщенность подсветки
-byte COLOR_SPEED = 100;
-int RAINBOW_PERIOD = 3;
-float RAINBOW_STEP_2 = 5.5;
-
-// режим бегущих частот
-byte RUNNING_SPEED = 60;
-
-// режим анализатора спектра
-byte HUE_START = 0;
-byte HUE_STEP = 5;
-#define LIGHT_SMOOTH 2
-
-/*
- Цвета для HSV
- HUE_RED
- HUE_ORANGE
- HUE_YELLOW
- HUE_GREEN
- HUE_AQUA
- HUE_BLUE
- HUE_PURPLE
- HUE_PINK
-*/
-// --------------------------- НАСТРОЙКИ ---------------------------
-
-// ----- КНОПКИ ПУЛЬТА -----
-#define BUTT_UP 0xE51CA6AD
-#define BUTT_DOWN 0xD22353AD
-#define BUTT_LEFT 0x517068AD
-#define BUTT_RIGHT 0xAC2A56AD
-#define BUTT_OK 0x1B92DDAD
-#define BUTT_1 0x68E456AD
-#define BUTT_2 0xF08A26AD
-#define BUTT_3 0x151CD6AD
-#define BUTT_4 0x18319BAD
-#define BUTT_5 0xF39EEBAD
-#define BUTT_6 0x4AABDFAD
-#define BUTT_7 0xE25410AD
-#define BUTT_8 0x297C76AD
-#define BUTT_9 0x14CE54AD
-#define BUTT_0 0xC089F6AD
-#define BUTT_STAR 0xAF3F1BAD
-#define BUTT_HASH 0x38379AD
-// ----- КНОПКИ ПУЛЬТА -----
-
-// ------------------------------ ДЛЯ РАЗРАБОТЧИКОВ --------------------------------
-#define MODE_AMOUNT 9 // количество режимов
-
-#define STRIPE NUM_LEDS / 5
-float freq_to_stripe = NUM_LEDS / 40; // /2 так как симметрия, и /20 так как 20 частот
-
-#define FHT_N 64 // ширина спектра х2
-#define LOG_OUT 1
-#include // преобразование Хартли
-
-#include
-
-#define FASTLED_ALLOW_INTERRUPTS 1
-#include "FastLED.h"
-CRGB leds[NUM_LEDS];
-
-#include "GyverButton.h"
-GButton butt1(BTN_PIN);
-
-#include "IRLremote.h"
-CHashIR IRLremote;
-uint32_t IRdata;
-
-// градиент-палитра от зелёного к красному
-DEFINE_GRADIENT_PALETTE(soundlevel_gp) {
- 0, 0, 255, 0, // green
- 100, 255, 255, 0, // yellow
- 150, 255, 100, 0, // orange
- 200, 255, 50, 0, // red
- 255, 255, 0, 0 // red
-};
-CRGBPalette32 myPal = soundlevel_gp;
-
-byte Rlenght, Llenght;
-float RsoundLevel, RsoundLevel_f;
-float LsoundLevel, LsoundLevel_f;
-
-float averageLevel = 50;
-int maxLevel = 100;
-byte MAX_CH = NUM_LEDS / 2;
-int hue;
-unsigned long main_timer, hue_timer, strobe_timer, running_timer, color_timer, rainbow_timer, eeprom_timer;
-float averK = 0.006;
-byte count;
-float index = (float)255 / MAX_CH; // коэффициент перевода для палитры
-boolean lowFlag;
-byte low_pass;
-int RcurrentLevel, LcurrentLevel;
-int colorMusic[3];
-float colorMusic_f[3], colorMusic_aver[3];
-boolean colorMusicFlash[3], strobeUp_flag, strobeDwn_flag;
-byte this_mode = MODE;
-int thisBright[3], strobe_bright = 0;
-unsigned int light_time = STROBE_PERIOD * STROBE_DUTY / 100;
-volatile boolean ir_flag;
-boolean settings_mode, ONstate = true;
-int8_t freq_strobe_mode, light_mode;
-int freq_max;
-float freq_max_f, rainbow_steps;
-int freq_f[32];
-int this_color;
-boolean running_flag[3], eeprom_flag;
-
-#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
-#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
-// ------------------------------ ДЛЯ РАЗРАБОТЧИКОВ --------------------------------
-
-void setup() {
- Serial.begin(9600);
- FastLED.addLeds(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
- FastLED.setBrightness(BRIGHTNESS);
-
- pinMode(13, OUTPUT);
- digitalWrite(13, LOW);
-
- pinMode(POT_GND, OUTPUT);
- digitalWrite(POT_GND, LOW);
- butt1.setTimeout(900);
-
- IRLremote.begin(IR_PIN);
-
- // для увеличения точности уменьшаем опорное напряжение,
- // выставив EXTERNAL и подключив Aref к выходу 3.3V на плате через делитель
- // GND ---[10-20 кОм] --- REF --- [10 кОм] --- 3V3
- // в данной схеме GND берётся из А0 для удобства подключения
- if (POTENT) analogReference(EXTERNAL);
- else
-#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
- analogReference(INTERNAL1V1);
-#else
- analogReference(INTERNAL);
-#endif
-
- // жуткая магия, меняем частоту оцифровки до 18 кГц
- // команды на ебучем ассемблере, даже не спрашивайте, как это работает
- sbi(ADCSRA, ADPS2);
- cbi(ADCSRA, ADPS1);
- sbi(ADCSRA, ADPS0);
-
- if (RESET_SETTINGS) EEPROM.write(100, 0); // сброс флага настроек
-
- if (AUTO_LOW_PASS && !EEPROM_LOW_PASS) { // если разрешена автонастройка нижнего порога шумов
- autoLowPass();
- }
- if (EEPROM_LOW_PASS) { // восстановить значения шумов из памяти
- LOW_PASS = EEPROM.readInt(70);
- SPEKTR_LOW_PASS = EEPROM.readInt(72);
- }
-
- // в 100 ячейке хранится число 100. Если нет - значит это первый запуск системы
- if (KEEP_SETTINGS) {
- if (EEPROM.read(100) != 100) {
- //Serial.println(F("First start"));
- EEPROM.write(100, 100);
- updateEEPROM();
- } else {
- readEEPROM();
- }
- }
-}
-
-void loop() {
- buttonTick(); // опрос и обработка кнопки
- remoteTick(); // опрос ИК пульта
- mainLoop(); // главный цикл обработки и отрисовки
- eepromTick(); // проверка не пора ли сохранить настройки
-}
-
-void mainLoop() {
- // главный цикл отрисовки
- if (ONstate) {
- if (millis() - main_timer > MAIN_LOOP) {
- // сбрасываем значения
- RsoundLevel = 0;
- LsoundLevel = 0;
-
- // перваые два режима - громкость (VU meter)
- if (this_mode == 0 || this_mode == 1) {
- for (byte i = 0; i < 100; i ++) { // делаем 100 измерений
- RcurrentLevel = analogRead(SOUND_R); // с правого
- if (!MONO) LcurrentLevel = analogRead(SOUND_L); // и левого каналов
-
- if (RsoundLevel < RcurrentLevel) RsoundLevel = RcurrentLevel; // ищем максимальное
- if (!MONO) if (LsoundLevel < LcurrentLevel) LsoundLevel = LcurrentLevel; // ищем максимальное
- }
-
- // фильтруем по нижнему порогу шумов
- RsoundLevel = map(RsoundLevel, LOW_PASS, 1023, 0, 500);
- if (!MONO)LsoundLevel = map(LsoundLevel, LOW_PASS, 1023, 0, 500);
-
- // ограничиваем диапазон
- RsoundLevel = constrain(RsoundLevel, 0, 500);
- if (!MONO)LsoundLevel = constrain(LsoundLevel, 0, 500);
-
- // возводим в степень (для большей чёткости работы)
- RsoundLevel = pow(RsoundLevel, EXP);
- if (!MONO)LsoundLevel = pow(LsoundLevel, EXP);
-
- // фильтр
- RsoundLevel_f = RsoundLevel * SMOOTH + RsoundLevel_f * (1 - SMOOTH);
- if (!MONO)LsoundLevel_f = LsoundLevel * SMOOTH + LsoundLevel_f * (1 - SMOOTH);
-
- if (MONO) LsoundLevel_f = RsoundLevel_f; // если моно, то левый = правому
-
- // заливаем "подложку", если яркость достаточная
- if (EMPTY_BRIGHT > 5) {
- for (int i = 0; i < NUM_LEDS; i++)
- leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- }
-
- // если значение выше порога - начинаем самое интересное
- if (RsoundLevel_f > 15 && LsoundLevel_f > 15) {
-
- // расчёт общей средней громкости с обоих каналов, фильтрация.
- // Фильтр очень медленный, сделано специально для автогромкости
- averageLevel = (float)(RsoundLevel_f + LsoundLevel_f) / 2 * averK + averageLevel * (1 - averK);
-
- // принимаем максимальную громкость шкалы как среднюю, умноженную на некоторый коэффициент MAX_COEF
- maxLevel = (float)averageLevel * MAX_COEF;
-
- // преобразуем сигнал в длину ленты (где MAX_CH это половина количества светодиодов)
- Rlenght = map(RsoundLevel_f, 0, maxLevel, 0, MAX_CH);
- Llenght = map(LsoundLevel_f, 0, maxLevel, 0, MAX_CH);
-
- // ограничиваем до макс. числа светодиодов
- Rlenght = constrain(Rlenght, 0, MAX_CH);
- Llenght = constrain(Llenght, 0, MAX_CH);
-
- animation(); // отрисовать
- }
- }
-
- // 3-5 режим - цветомузыка
- if (this_mode == 2 || this_mode == 3 || this_mode == 4 || this_mode == 7 || this_mode == 8) {
- analyzeAudio();
- colorMusic[0] = 0;
- colorMusic[1] = 0;
- colorMusic[2] = 0;
- for (int i = 0 ; i < 32 ; i++) {
- if (fht_log_out[i] < SPEKTR_LOW_PASS) fht_log_out[i] = 0;
- }
- // низкие частоты, выборка со 2 по 5 тон (0 и 1 зашумленные!)
- for (byte i = 2; i < 6; i++) {
- if (fht_log_out[i] > colorMusic[0]) colorMusic[0] = fht_log_out[i];
- }
- // средние частоты, выборка с 6 по 10 тон
- for (byte i = 6; i < 11; i++) {
- if (fht_log_out[i] > colorMusic[1]) colorMusic[1] = fht_log_out[i];
- }
- // высокие частоты, выборка с 11 по 31 тон
- for (byte i = 11; i < 32; i++) {
- if (fht_log_out[i] > colorMusic[2]) colorMusic[2] = fht_log_out[i];
- }
- freq_max = 0;
- for (byte i = 0; i < 30; i++) {
- if (fht_log_out[i + 2] > freq_max) freq_max = fht_log_out[i + 2];
- if (freq_max < 5) freq_max = 5;
-
- if (freq_f[i] < fht_log_out[i + 2]) freq_f[i] = fht_log_out[i + 2];
- if (freq_f[i] > 0) freq_f[i] -= LIGHT_SMOOTH;
- else freq_f[i] = 0;
- }
- freq_max_f = freq_max * averK + freq_max_f * (1 - averK);
- for (byte i = 0; i < 3; i++) {
- colorMusic_aver[i] = colorMusic[i] * averK + colorMusic_aver[i] * (1 - averK); // общая фильтрация
- colorMusic_f[i] = colorMusic[i] * SMOOTH_FREQ + colorMusic_f[i] * (1 - SMOOTH_FREQ); // локальная
- if (colorMusic_f[i] > ((float)colorMusic_aver[i] * MAX_COEF_FREQ)) {
- thisBright[i] = 255;
- colorMusicFlash[i] = true;
- running_flag[i] = true;
- } else colorMusicFlash[i] = false;
- if (thisBright[i] >= 0) thisBright[i] -= SMOOTH_STEP;
- if (thisBright[i] < EMPTY_BRIGHT) {
- thisBright[i] = EMPTY_BRIGHT;
- running_flag[i] = false;
- }
- }
- animation();
- }
- if (this_mode == 5) {
- if ((long)millis() - strobe_timer > STROBE_PERIOD) {
- strobe_timer = millis();
- strobeUp_flag = true;
- strobeDwn_flag = false;
- }
- if ((long)millis() - strobe_timer > light_time) {
- strobeDwn_flag = true;
- }
- if (strobeUp_flag) { // если настало время пыхнуть
- if (strobe_bright < 255) // если яркость не максимальная
- strobe_bright += STROBE_SMOOTH; // увелчить
- if (strobe_bright > 255) { // если пробили макс. яркость
- strobe_bright = 255; // оставить максимум
- strobeUp_flag = false; // флаг опустить
- }
- }
-
- if (strobeDwn_flag) { // гаснем
- if (strobe_bright > 0) // если яркость не минимальная
- strobe_bright -= STROBE_SMOOTH; // уменьшить
- if (strobe_bright < 0) { // если пробили мин. яркость
- strobeDwn_flag = false;
- strobe_bright = 0; // оставить 0
- }
- }
- animation();
- }
- if (this_mode == 6) animation();
-
- if (!IRLremote.receiving()) // если на ИК приёмник не приходит сигнал (без этого НЕ РАБОТАЕТ!)
- FastLED.show(); // отправить значения на ленту
-
- if (this_mode != 7) // 7 режиму не нужна очистка!!!
- FastLED.clear(); // очистить массив пикселей
- main_timer = millis(); // сбросить таймер
- }
- }
-}
-
-void animation() {
- // согласно режиму
- switch (this_mode) {
- case 0:
- count = 0;
- for (int i = (MAX_CH - 1); i > ((MAX_CH - 1) - Rlenght); i--) {
- leds[i] = ColorFromPalette(myPal, (count * index)); // заливка по палитре " от зелёного к красному"
- count++;
- }
- count = 0;
- for (int i = (MAX_CH); i < (MAX_CH + Llenght); i++ ) {
- leds[i] = ColorFromPalette(myPal, (count * index)); // заливка по палитре " от зелёного к красному"
- count++;
- }
- if (EMPTY_BRIGHT > 0) {
- CHSV this_dark = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- for (int i = ((MAX_CH - 1) - Rlenght); i > 0; i--)
- leds[i] = this_dark;
- for (int i = MAX_CH + Llenght; i < NUM_LEDS; i++)
- leds[i] = this_dark;
- }
- break;
- case 1:
- if (millis() - rainbow_timer > 30) {
- rainbow_timer = millis();
- hue = floor((float)hue + RAINBOW_STEP);
- }
- count = 0;
- for (int i = (MAX_CH - 1); i > ((MAX_CH - 1) - Rlenght); i--) {
- leds[i] = ColorFromPalette(RainbowColors_p, (count * index) / 2 - hue); // заливка по палитре радуга
- count++;
- }
- count = 0;
- for (int i = (MAX_CH); i < (MAX_CH + Llenght); i++ ) {
- leds[i] = ColorFromPalette(RainbowColors_p, (count * index) / 2 - hue); // заливка по палитре радуга
- count++;
- }
- if (EMPTY_BRIGHT > 0) {
- CHSV this_dark = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- for (int i = ((MAX_CH - 1) - Rlenght); i > 0; i--)
- leds[i] = this_dark;
- for (int i = MAX_CH + Llenght; i < NUM_LEDS; i++)
- leds[i] = this_dark;
- }
- break;
- case 2:
- for (int i = 0; i < NUM_LEDS; i++) {
- if (i < STRIPE) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (i < STRIPE * 2) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < STRIPE * 3) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else if (i < STRIPE * 4) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < STRIPE * 5) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- }
- break;
- case 3:
- for (int i = 0; i < NUM_LEDS; i++) {
- if (i < NUM_LEDS / 3) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (i < NUM_LEDS * 2 / 3) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < NUM_LEDS) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
- }
- break;
- case 4:
- switch (freq_strobe_mode) {
- case 0:
- if (colorMusicFlash[2]) HIGHS();
- else if (colorMusicFlash[1]) MIDS();
- else if (colorMusicFlash[0]) LOWS();
- else SILENCE();
- break;
- case 1:
- if (colorMusicFlash[2]) HIGHS();
- else SILENCE();
- break;
- case 2:
- if (colorMusicFlash[1]) MIDS();
- else SILENCE();
- break;
- case 3:
- if (colorMusicFlash[0]) LOWS();
- else SILENCE();
- break;
- }
- break;
- case 5:
- if (strobe_bright > 0)
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(STROBE_COLOR, STROBE_SAT, strobe_bright);
- else
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 6:
- switch (light_mode) {
- case 0: for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(LIGHT_COLOR, LIGHT_SAT, 255);
- break;
- case 1:
- if (millis() - color_timer > COLOR_SPEED) {
- color_timer = millis();
- if (++this_color > 255) this_color = 0;
- }
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(this_color, LIGHT_SAT, 255);
- break;
- case 2:
- if (millis() - rainbow_timer > 30) {
- rainbow_timer = millis();
- this_color += RAINBOW_PERIOD;
- if (this_color > 255) this_color = 0;
- if (this_color < 0) this_color = 255;
- }
- rainbow_steps = this_color;
- for (int i = 0; i < NUM_LEDS; i++) {
- leds[i] = CHSV((int)floor(rainbow_steps), 255, 255);
- rainbow_steps += RAINBOW_STEP_2;
- if (rainbow_steps > 255) rainbow_steps = 0;
- if (rainbow_steps < 0) rainbow_steps = 255;
- }
- break;
- }
- break;
- case 7:
- switch (freq_strobe_mode) {
- case 0:
- if (running_flag[2]) leds[NUM_LEDS / 2] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (running_flag[1]) leds[NUM_LEDS / 2] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (running_flag[0]) leds[NUM_LEDS / 2] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 1:
- if (running_flag[2]) leds[NUM_LEDS / 2] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 2:
- if (running_flag[1]) leds[NUM_LEDS / 2] = CHSV(MID_COLOR, 255, thisBright[1]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 3:
- if (running_flag[0]) leds[NUM_LEDS / 2] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- }
- leds[(NUM_LEDS / 2) - 1] = leds[NUM_LEDS / 2];
- if (millis() - running_timer > RUNNING_SPEED) {
- running_timer = millis();
- for (byte i = 0; i < NUM_LEDS / 2 - 1; i++) {
- leds[i] = leds[i + 1];
- leds[NUM_LEDS - i - 1] = leds[i];
- }
- }
- break;
- case 8:
- byte HUEindex = HUE_START;
- for (byte i = 0; i < NUM_LEDS / 2; i++) {
- byte this_bright = map(freq_f[(int)floor((NUM_LEDS / 2 - i) / freq_to_stripe)], 0, freq_max_f, 0, 255);
- this_bright = constrain(this_bright, 0, 255);
- leds[i] = CHSV(HUEindex, 255, this_bright);
- leds[NUM_LEDS - i - 1] = leds[i];
- HUEindex += HUE_STEP;
- if (HUEindex > 255) HUEindex = 0;
- }
- break;
- }
-}
-
-void HIGHS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
-}
-void MIDS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
-}
-void LOWS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
-}
-void SILENCE() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
-}
-
-// вспомогательная функция, изменяет величину value на шаг incr в пределах minimum.. maximum
-int smartIncr(int value, int incr_step, int mininmum, int maximum) {
- int val_buf = value + incr_step;
- val_buf = constrain(val_buf, mininmum, maximum);
- return val_buf;
-}
-
-float smartIncrFloat(float value, float incr_step, float mininmum, float maximum) {
- float val_buf = value + incr_step;
- val_buf = constrain(val_buf, mininmum, maximum);
- return val_buf;
-}
-
-void remoteTick() {
- if (IRLremote.available()) {
- auto data = IRLremote.read();
- IRdata = data.command;
- ir_flag = true;
- }
- if (ir_flag) { // если данные пришли
- eeprom_timer = millis();
- eeprom_flag = true;
- switch (IRdata) {
- // режимы
- case BUTT_1: this_mode = 0;
- break;
- case BUTT_2: this_mode = 1;
- break;
- case BUTT_3: this_mode = 2;
- break;
- case BUTT_4: this_mode = 3;
- break;
- case BUTT_5: this_mode = 4;
- break;
- case BUTT_6: this_mode = 5;
- break;
- case BUTT_7: this_mode = 6;
- break;
- case BUTT_8: this_mode = 7;
- break;
- case BUTT_9: this_mode = 8;
- break;
- case BUTT_0: fullLowPass();
- break;
- case BUTT_STAR: ONstate = !ONstate; FastLED.clear(); FastLED.show(); updateEEPROM();
- break;
- case BUTT_HASH:
- switch (this_mode) {
- case 4:
- case 7: if (++freq_strobe_mode > 3) freq_strobe_mode = 0;
- break;
- case 6: if (++light_mode > 2) light_mode = 0;
- break;
- }
- break;
- case BUTT_OK: settings_mode = !settings_mode; digitalWrite(13, settings_mode);
- break;
- case BUTT_UP:
- if (settings_mode) {
- // ВВЕРХ общие настройки
- EMPTY_BRIGHT = smartIncr(EMPTY_BRIGHT, 5, 0, 255);
- } else {
- switch (this_mode) {
- case 0:
- break;
- case 1: RAINBOW_STEP = smartIncrFloat(RAINBOW_STEP, 0.5, 0.5, 20);
- break;
- case 2:
- case 3:
- case 4: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, 0.1, 0, 5);
- break;
- case 5: STROBE_PERIOD = smartIncr(STROBE_PERIOD, 20, 1, 1000);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_SAT = smartIncr(LIGHT_SAT, 20, 0, 255);
- break;
- case 1: LIGHT_SAT = smartIncr(LIGHT_SAT, 20, 0, 255);
- break;
- case 2: RAINBOW_STEP_2 = smartIncrFloat(RAINBOW_STEP_2, 0.5, 0.5, 10);
- break;
- }
- break;
- case 7: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, 0.1, 0.0, 10);
- break;
- case 8: HUE_START = smartIncr(HUE_START, 10, 0, 255);
- break;
- }
- }
- break;
- case BUTT_DOWN:
- if (settings_mode) {
- // ВНИЗ общие настройки
- EMPTY_BRIGHT = smartIncr(EMPTY_BRIGHT, -5, 0, 255);
- } else {
- switch (this_mode) {
- case 0:
- break;
- case 1: RAINBOW_STEP = smartIncrFloat(RAINBOW_STEP, -0.5, 0.5, 20);
- break;
- case 2:
- case 3:
- case 4: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, -0.1, 0, 5);
- break;
- case 5: STROBE_PERIOD = smartIncr(STROBE_PERIOD, -20, 1, 1000);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_SAT = smartIncr(LIGHT_SAT, -20, 0, 255);
- break;
- case 1: LIGHT_SAT = smartIncr(LIGHT_SAT, -20, 0, 255);
- break;
- case 2: RAINBOW_STEP_2 = smartIncrFloat(RAINBOW_STEP_2, -0.5, 0.5, 10);
- break;
- }
- break;
- case 7: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, -0.1, 0.0, 10);
- break;
- case 8: HUE_START = smartIncr(HUE_START, -10, 0, 255);
- break;
- }
- }
- break;
- case BUTT_LEFT:
- if (settings_mode) {
- // ВЛЕВО общие настройки
- BRIGHTNESS = smartIncr(BRIGHTNESS, -20, 0, 255);
- FastLED.setBrightness(BRIGHTNESS);
- } else {
- switch (this_mode) {
- case 0:
- case 1: SMOOTH = smartIncrFloat(SMOOTH, -0.05, 0.05, 1);
- break;
- case 2:
- case 3:
- case 4: SMOOTH_FREQ = smartIncrFloat(SMOOTH_FREQ, -0.05, 0.05, 1);
- break;
- case 5: STROBE_SMOOTH = smartIncr(STROBE_SMOOTH, -20, 0, 255);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_COLOR = smartIncr(LIGHT_COLOR, -10, 0, 255);
- break;
- case 1: COLOR_SPEED = smartIncr(COLOR_SPEED, -10, 0, 255);
- break;
- case 2: RAINBOW_PERIOD = smartIncr(RAINBOW_PERIOD, -1, -20, 20);
- break;
- }
- break;
- case 7: RUNNING_SPEED = smartIncr(RUNNING_SPEED, -10, 1, 255);
- break;
- case 8: HUE_STEP = smartIncr(HUE_STEP, -1, 1, 255);
- break;
- }
- }
- break;
- case BUTT_RIGHT:
- if (settings_mode) {
- // ВПРАВО общие настройки
- BRIGHTNESS = smartIncr(BRIGHTNESS, 20, 0, 255);
- FastLED.setBrightness(BRIGHTNESS);
- } else {
- switch (this_mode) {
- case 0:
- case 1: SMOOTH = smartIncrFloat(SMOOTH, 0.05, 0.05, 1);
- break;
- case 2:
- case 3:
- case 4: SMOOTH_FREQ = smartIncrFloat(SMOOTH_FREQ, 0.05, 0.05, 1);
- break;
- case 5: STROBE_SMOOTH = smartIncr(STROBE_SMOOTH, 20, 0, 255);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_COLOR = smartIncr(LIGHT_COLOR, 10, 0, 255);
- break;
- case 1: COLOR_SPEED = smartIncr(COLOR_SPEED, 10, 0, 255);
- break;
- case 2: RAINBOW_PERIOD = smartIncr(RAINBOW_PERIOD, 1, -20, 20);
- break;
- }
- break;
- case 7: RUNNING_SPEED = smartIncr(RUNNING_SPEED, 10, 1, 255);
- break;
- case 8: HUE_STEP = smartIncr(HUE_STEP, 1, 1, 255);
- break;
- }
- }
- break;
- default: eeprom_flag = false; // если не распознали кнопку, не обновляем настройки!
- break;
- }
- ir_flag = false;
- }
-}
-
-void autoLowPass() {
- // для режима VU
- delay(10); // ждём инициализации АЦП
- int thisMax = 0; // максимум
- int thisLevel;
- for (byte i = 0; i < 200; i++) {
- thisLevel = analogRead(SOUND_R); // делаем 200 измерений
- if (thisLevel > thisMax) // ищем максимумы
- thisMax = thisLevel; // запоминаем
- delay(4); // ждём 4мс
- }
- LOW_PASS = thisMax + LOW_PASS_ADD; // нижний порог как максимум тишины + некая величина
-
- // для режима спектра
- thisMax = 0;
- for (byte i = 0; i < 100; i++) { // делаем 100 измерений
- analyzeAudio(); // разбить в спектр
- for (byte j = 2; j < 32; j++) { // первые 2 канала - хлам
- thisLevel = fht_log_out[j];
- if (thisLevel > thisMax) // ищем максимумы
- thisMax = thisLevel; // запоминаем
- }
- delay(4); // ждём 4мс
- }
- SPEKTR_LOW_PASS = thisMax + LOW_PASS_FREQ_ADD; // нижний порог как максимум тишины
-
- if (EEPROM_LOW_PASS && !AUTO_LOW_PASS) {
- EEPROM.updateInt(70, LOW_PASS);
- EEPROM.updateInt(72, SPEKTR_LOW_PASS);
- }
-}
-
-void analyzeAudio() {
- for (int i = 0 ; i < FHT_N ; i++) {
- int sample = analogRead(SOUND_R_FREQ);
- fht_input[i] = sample; // put real data into bins
- }
- fht_window(); // window the data for better frequency response
- fht_reorder(); // reorder the data before doing the fht
- fht_run(); // process the data in the fht
- fht_mag_log(); // take the output of the fht
-}
-
-void buttonTick() {
- butt1.tick(); // обязательная функция отработки. Должна постоянно опрашиваться
- if (butt1.isSingle()) // если единичное нажатие
- if (++this_mode >= MODE_AMOUNT) this_mode = 0; // изменить режим
-
- if (butt1.isHolded()) { // кнопка удержана
- fullLowPass();
- }
-}
-void fullLowPass() {
- digitalWrite(13, HIGH); // включить светодиод 13 пин
- FastLED.setBrightness(0); // погасить ленту
- FastLED.clear(); // очистить массив пикселей
- FastLED.show(); // отправить значения на ленту
- delay(500); // подождать чутка
- autoLowPass(); // измерить шумы
- delay(500); // подождать
- FastLED.setBrightness(BRIGHTNESS); // вернуть яркость
- digitalWrite(13, LOW); // выключить светодиод
-}
-void updateEEPROM() {
- EEPROM.updateByte(1, this_mode);
- EEPROM.updateByte(2, freq_strobe_mode);
- EEPROM.updateByte(3, light_mode);
- EEPROM.updateInt(4, RAINBOW_STEP);
- EEPROM.updateFloat(8, MAX_COEF_FREQ);
- EEPROM.updateInt(12, STROBE_PERIOD);
- EEPROM.updateInt(16, LIGHT_SAT);
- EEPROM.updateFloat(20, RAINBOW_STEP_2);
- EEPROM.updateInt(24, HUE_START);
- EEPROM.updateFloat(28, SMOOTH);
- EEPROM.updateFloat(32, SMOOTH_FREQ);
- EEPROM.updateInt(36, STROBE_SMOOTH);
- EEPROM.updateInt(40, LIGHT_COLOR);
- EEPROM.updateInt(44, COLOR_SPEED);
- EEPROM.updateInt(48, RAINBOW_PERIOD);
- EEPROM.updateInt(52, RUNNING_SPEED);
- EEPROM.updateInt(56, HUE_STEP);
- EEPROM.updateInt(60, EMPTY_BRIGHT);
- if (KEEP_STATE) EEPROM.updateByte(64, ONstate);
-}
-void readEEPROM() {
- this_mode = EEPROM.readByte(1);
- freq_strobe_mode = EEPROM.readByte(2);
- light_mode = EEPROM.readByte(3);
- RAINBOW_STEP = EEPROM.readInt(4);
- MAX_COEF_FREQ = EEPROM.readFloat(8);
- STROBE_PERIOD = EEPROM.readInt(12);
- LIGHT_SAT = EEPROM.readInt(16);
- RAINBOW_STEP_2 = EEPROM.readFloat(20);
- HUE_START = EEPROM.readInt(24);
- SMOOTH = EEPROM.readFloat(28);
- SMOOTH_FREQ = EEPROM.readFloat(32);
- STROBE_SMOOTH = EEPROM.readInt(36);
- LIGHT_COLOR = EEPROM.readInt(40);
- COLOR_SPEED = EEPROM.readInt(44);
- RAINBOW_PERIOD = EEPROM.readInt(48);
- RUNNING_SPEED = EEPROM.readInt(52);
- HUE_STEP = EEPROM.readInt(56);
- EMPTY_BRIGHT = EEPROM.readInt(60);
- if (KEEP_STATE) ONstate = EEPROM.readByte(64);
-}
-void eepromTick() {
- if (eeprom_flag)
- if (millis() - eeprom_timer > 30000) { // 30 секунд после последнего нажатия с пульта
- eeprom_flag = false;
- eeprom_timer = millis();
- updateEEPROM();
- }
-}
diff --git a/firmware/Old versions/colorMusic_v2.6.2_WAVGAT/colorMusic_v2.6.2_WAVGAT.ino b/firmware/Old versions/colorMusic_v2.6.2_WAVGAT/colorMusic_v2.6.2_WAVGAT.ino
deleted file mode 100644
index cff0be5..0000000
--- a/firmware/Old versions/colorMusic_v2.6.2_WAVGAT/colorMusic_v2.6.2_WAVGAT.ino
+++ /dev/null
@@ -1,995 +0,0 @@
-/*
- Версия 2.6 использует библиотеки FastLED и IRLremote!
- Библиотеки идут в архиве с проектом! https://alexgyver.ru/colormusic/
- Крутейшая свето-цветомузыка на Arduino и адресной светодиодной ленте WS2812b.
- Данная версия поддерживает около 410 светодиодов!
- Версия ИК пульта задаётся в IR_RCT.
- Управление:
- - Однократное нажатие кнопки: смена режима
- - Удержание кнопки: калибровка нижнего порога шума
- Режимы работы (переключаются кнопкой):
- - VU meter (столбик громкости): от зелёного к красному
- - VU meter (столбик громкости): плавно бегущая радуга
- - Светомузыка по частотам: 5 полос симметрично
- - Светомузыка по частотам: 3 полосы
- - Светомузыка по частотам: 1 полоса
- - Стробоскоп
- - (2.0) Подсветка
- - (2.0) Бегущие частоты
- - (2.1) анализатор спектра
- Особенности:
- - Плавная анимация (можно настроить)
- - Автонастройка по громкости (можно настроить)
- - Фильтр нижнего шума (можно настроить)
- - Автокалибровка шума при запуске (можно настроить)
- - Поддержка стерео и моно звука (можно настроить)
- - (2.0) в режиме частот лента не гаснет полностью (EMPTY_BRIGHT)
- - (2.1) все настройки сохраняются в памяти и не сбрасываются при перезагрузке
- - Сохранение настроек происходит при выключении кнопкой звёздочка (*)
- - А также через 30 секунд после последнего нажатия на любую кнопку ИК пульта
-
- НАСТРОЙКА НИЖНЕГО ПОРОГА ШУМА (строки 65-71)
- - Включаем систему
- - Ставим музыку на паузу
- - Удерживаем кнопку 1 секунду ИЛИ жмём кнопку 0 на пульте
- Значения шумов будут записаны в память и САМИ загружаться при последующем запуске! Всё!
-
- Пульт:
- - Цифры (1 - 9) активируют режимы
- - Цифра 0: калибровка шума
- - Звёздочка (*): включить/выключить систему
- - Кнопка ОК: переключение между локальными и глобальными настройками)
- - Решётка (#): смена подрежима
- - Глобальные настройки (горит светодиод на плате):
- + Стрелки ← →: общая яркость горящих светодиодов
- + Стрелки ↑ ↓: яркость "не горящих" светодиодов
- - Локальные настройки (у каждого режима свои):
- 1 - Шкала громкости (градиент)
- Стрелки ← →: плавность анимации
- 2 - Шкала громкости (радуга)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: скорость радуги
- 3 - Цветомузыка (5 полос)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- 4 - Цветомузыка (3 полосы)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- 5 - Цветомузыка (1 полоса)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- Подрежимы #: 3 частоты / низкие / средние / высокие
- 6 - Стробоскоп
- Стрелки ← →: плавность вспышек
- Стрелки ↑ ↓: частота вспышек
- 7 - Цветная подсветка
- Подрежимы #:
- Постоянный: стрелки ← →: цвет, стрелки ↑ ↓: насыщенность
- Плавная смена: стрелки ← →: скорость, стрелки ↑ ↓: насыщенность
- Бегущая радуга: стрелки ← →: скорость, стрелки ↑ ↓: шаг радуги
- 8 - “Бегущие частоты”
- Стрелки ← →: скорость
- Стрелки ↑ ↓: чувствительность
- Подрежимы #: 3 частоты / низкие / средние / высокие
- 9 - Анализатор спектра
- Стрелки ← →: шаг цвета
- Стрелки ↑ ↓: цвет
- **************************************************
- Разработано: AlexGyver
- Страница проекта: http://alexgyver.ru/colormusic/
- GitHub: https://github.com/AlexGyver/ColorMusic
-*/
-
-// --------------------------- НАСТРОЙКИ ---------------------------
-#define KEEP_SETTINGS 1 // хранить ВСЕ настройки в памяти
-#define KEEP_STATE 1 // сохранять в памяти состояние вкл/выкл (с пульта)
-#define RESET_SETTINGS 0 // сброс настроек в памяти
-// поставить 1. Прошиться. Поставить обратно 0. Прошиться. Всё.
-
-// лента
-#define NUM_LEDS 10 // количество светодиодов
-byte BRIGHTNESS = 200; // яркость (0 - 255)
-
-// пины
-#define SOUND_R A2 // аналоговый пин вход аудио, правый канал
-#define SOUND_L A1 // аналоговый пин вход аудио, левый канал
-#define SOUND_R_FREQ A3 // аналоговый пин вход аудио для режима с частотами (через кондер)
-#define BTN_PIN 3 // кнопка переключения режимов (PIN --- КНОПКА --- GND)
-#if defined(__AVR_ATmega32U4__) // Пины для Arduino Pro Micro
-#define MLED_PIN 17 // пин светодиода режимов на ProMicro, т.к. обычный не выведен.
-#define MLED_ON LOW
-#define LED_PIN 9 // пин DI светодиодной ленты на ProMicro, т.к. обычный не выведен.
-#else // Пины для других плат Arduino (по умолчанию)
-#define MLED_PIN 13 // пин светодиода режимов
-#define MLED_ON HIGH
-#define LED_PIN 12 // пин DI светодиодной ленты
-#endif
-#define POT_GND A0 // пин земля для потенциометра
-#define IR_RCT 1 // тип ИК пульта 0 - без пульта, 1-WAVGAT, 2-KEYES
-#define IR_PIN 2 // пин ИК приёмника
-
-// настройки радуги
-float RAINBOW_STEP = 5.5; // шаг изменения цвета радуги
-
-// отрисовка
-#define MODE 0 // режим при запуске
-#define MAIN_LOOP 5 // период основного цикла отрисовки (по умолчанию 5)
-
-// сигнал
-#define MONO 1 // 1 - только один канал (ПРАВЫЙ!!!!! SOUND_R!!!!!), 0 - два канала
-#define EXP 1.4 // степень усиления сигнала (для более "резкой" работы) (по умолчанию 1.4)
-#define POTENT 0 // 1 - используем потенциометр, 0 - используется внутренний источник опорного напряжения 1.1 В
-byte EMPTY_BRIGHT = 30; // яркость "не горящих" светодиодов (0 - 255)
-#define EMPTY_COLOR HUE_PURPLE // цвет "не горящих" светодиодов. Будет чёрный, если яркость 0
-
-// нижний порог шумов
-uint16_t LOW_PASS = 100; // нижний порог шумов режим VU, ручная настройка
-uint16_t SPEKTR_LOW_PASS = 40; // нижний порог шумов режим спектра, ручная настройка
-#define AUTO_LOW_PASS 0 // разрешить настройку нижнего порога шумов при запуске (по умолч. 0)
-#define EEPROM_LOW_PASS 1 // порог шумов хранится в энергонезависимой памяти (по умолч. 1)
-#define LOW_PASS_ADD 13 // "добавочная" величина к нижнему порогу, для надёжности (режим VU)
-#define LOW_PASS_FREQ_ADD 3 // "добавочная" величина к нижнему порогу, для надёжности (режим частот)
-
-// шкала громкости
-float SMOOTH = 0.5; // коэффициент плавности анимации VU (по умолчанию 0.5)
-#define MAX_COEF 1.8 // коэффициент громкости (максимальное равно срднему * этот коэф) (по умолчанию 1.8)
-
-// режим цветомузыки
-float SMOOTH_FREQ = 0.8; // коэффициент плавности анимации частот (по умолчанию 0.8)
-float MAX_COEF_FREQ = 1.2; // коэффициент порога для "вспышки" цветомузыки (по умолчанию 1.5)
-#define SMOOTH_STEP 20 // шаг уменьшения яркости в режиме цветомузыки (чем больше, тем быстрее гаснет)
-#define LOW_COLOR HUE_RED // цвет низких частот
-#define MID_COLOR HUE_GREEN // цвет средних
-#define HIGH_COLOR HUE_YELLOW // цвет высоких
-
-// режим стробоскопа
-uint16_t STROBE_PERIOD = 100; // период вспышек, миллисекунды
-#define STROBE_DUTY 20 // скважность вспышек (1 - 99) - отношение времени вспышки ко времени темноты
-#define STROBE_COLOR HUE_YELLOW // цвет стробоскопа
-#define STROBE_SAT 0 // насыщенность. Если 0 - цвет будет БЕЛЫЙ при любом цвете (0 - 255)
-byte STROBE_SMOOTH = 100; // скорость нарастания/угасания вспышки (0 - 255)
-
-// режим подсветки
-byte LIGHT_COLOR = 0; // начальный цвет подсветки
-byte LIGHT_SAT = 200; // начальная насыщенность подсветки
-byte COLOR_SPEED = 100;
-int RAINBOW_PERIOD = 3;
-float RAINBOW_STEP_2 = 5.5;
-
-// режим бегущих частот
-byte RUNNING_SPEED = 60;
-
-// режим анализатора спектра
-byte HUE_START = 0;
-byte HUE_STEP = 5;
-#define LIGHT_SMOOTH 2
-
-/*
- Цвета для HSV
- HUE_RED
- HUE_ORANGE
- HUE_YELLOW
- HUE_GREEN
- HUE_AQUA
- HUE_BLUE
- HUE_PURPLE
- HUE_PINK
-*/
-// --------------------------- НАСТРОЙКИ ---------------------------
-
-// ----- КНОПКИ ПУЛЬТА WAVGAT -----
-#if IR_RCT == 1
-#define BUTT_UP 0xF39EEBAD
-#define BUTT_DOWN 0xC089F6AD
-#define BUTT_LEFT 0xE25410AD
-#define BUTT_RIGHT 0x14CE54AD
-#define BUTT_OK 0x297C76AD
-#define BUTT_1 0x4E5BA3AD
-#define BUTT_2 0xE51CA6AD
-#define BUTT_3 0xE207E1AD
-#define BUTT_4 0x517068AD
-#define BUTT_5 0x1B92DDAD
-#define BUTT_6 0xAC2A56AD
-#define BUTT_7 0x5484B6AD
-#define BUTT_8 0xD22353AD
-#define BUTT_9 0xDF3F4BAD
-#define BUTT_0 0xF08A26AD
-#define BUTT_STAR 0x68E456AD
-#define BUTT_HASH 0x151CD6AD
-#endif
-// ----- КНОПКИ ПУЛЬТА WAVGAT -----
-
-// ----- КНОПКИ ПУЛЬТА KEYES -----
-#if IR_RCT == 2
-#define BUTT_UP 0xE51CA6AD
-#define BUTT_DOWN 0xD22353AD
-#define BUTT_LEFT 0x517068AD
-#define BUTT_RIGHT 0xAC2A56AD
-#define BUTT_OK 0x1B92DDAD
-#define BUTT_1 0x68E456AD
-#define BUTT_2 0xF08A26AD
-#define BUTT_3 0x151CD6AD
-#define BUTT_4 0x18319BAD
-#define BUTT_5 0xF39EEBAD
-#define BUTT_6 0x4AABDFAD
-#define BUTT_7 0xE25410AD
-#define BUTT_8 0x297C76AD
-#define BUTT_9 0x14CE54AD
-#define BUTT_0 0xC089F6AD
-#define BUTT_STAR 0xAF3F1BAD
-#define BUTT_HASH 0x38379AD
-#endif
-// ----- КНОПКИ ПУЛЬТА KEYES -----
-
-// ------------------------------ ДЛЯ РАЗРАБОТЧИКОВ --------------------------------
-#define MODE_AMOUNT 9 // количество режимов
-
-#define STRIPE NUM_LEDS / 5
-float freq_to_stripe = NUM_LEDS / 40; // /2 так как симметрия, и /20 так как 20 частот
-
-#define FHT_N 64 // ширина спектра х2
-#define LOG_OUT 1
-#include // преобразование Хартли
-
-#include
-
-#define FASTLED_ALLOW_INTERRUPTS 1
-#include "FastLED.h"
-CRGB leds[NUM_LEDS];
-
-#include "GyverButton.h"
-GButton butt1(BTN_PIN);
-
-#include "IRLremote.h"
-CHashIR IRLremote;
-uint32_t IRdata;
-
-// градиент-палитра от зелёного к красному
-DEFINE_GRADIENT_PALETTE(soundlevel_gp) {
- 0, 0, 255, 0, // green
- 100, 255, 255, 0, // yellow
- 150, 255, 100, 0, // orange
- 200, 255, 50, 0, // red
- 255, 255, 0, 0 // red
-};
-CRGBPalette32 myPal = soundlevel_gp;
-
-byte Rlenght, Llenght;
-float RsoundLevel, RsoundLevel_f;
-float LsoundLevel, LsoundLevel_f;
-
-float averageLevel = 50;
-int maxLevel = 100;
-byte MAX_CH = NUM_LEDS / 2;
-int hue;
-unsigned long main_timer, hue_timer, strobe_timer, running_timer, color_timer, rainbow_timer, eeprom_timer;
-float averK = 0.006;
-byte count;
-float index = (float)255 / MAX_CH; // коэффициент перевода для палитры
-boolean lowFlag;
-byte low_pass;
-int RcurrentLevel, LcurrentLevel;
-int colorMusic[3];
-float colorMusic_f[3], colorMusic_aver[3];
-boolean colorMusicFlash[3], strobeUp_flag, strobeDwn_flag;
-byte this_mode = MODE;
-int thisBright[3], strobe_bright = 0;
-unsigned int light_time = STROBE_PERIOD * STROBE_DUTY / 100;
-volatile boolean ir_flag;
-boolean settings_mode, ONstate = true;
-int8_t freq_strobe_mode, light_mode;
-int freq_max;
-float freq_max_f, rainbow_steps;
-int freq_f[32];
-int this_color;
-boolean running_flag[3], eeprom_flag;
-
-#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
-#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
-// ------------------------------ ДЛЯ РАЗРАБОТЧИКОВ --------------------------------
-
-void setup() {
- Serial.begin(9600);
- FastLED.addLeds(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
- FastLED.setBrightness(BRIGHTNESS);
-
- #if defined(__AVR_ATmega32U4__) //Выключение светодиодов на Pro Micro
- TXLED1; //на ProMicro выключим и TXLED
- delay (1000); //При питании по usb от компьютера нужна задержка перед выключением RXLED. Если питать от БП, то можно убрать эту строку.
- #endif
- pinMode(MLED_PIN, OUTPUT); //Режим пина для светодиода режима на выход
- digitalWrite(MLED_PIN, !MLED_ON); //Выключение светодиода режима
-
- pinMode(POT_GND, OUTPUT);
- digitalWrite(POT_GND, LOW);
- butt1.setTimeout(900);
-
- IRLremote.begin(IR_PIN);
-
- // для увеличения точности уменьшаем опорное напряжение,
- // выставив EXTERNAL и подключив Aref к выходу 3.3V на плате через делитель
- // GND ---[10-20 кОм] --- REF --- [10 кОм] --- 3V3
- // в данной схеме GND берётся из А0 для удобства подключения
- if (POTENT) analogReference(EXTERNAL);
- else
-#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
- analogReference(INTERNAL1V1);
-#else
- analogReference(INTERNAL);
-#endif
-
- // жуткая магия, меняем частоту оцифровки до 18 кГц
- // команды на ебучем ассемблере, даже не спрашивайте, как это работает
- // поднимаем частоту опроса аналогового порта до 38.4 кГц, по теореме
- // Котельникова (Найквиста) частота дискретизации будет 19.2 кГц
- // http://yaab-arduino.blogspot.ru/2015/02/fast-sampling-from-analog-input.html
- sbi(ADCSRA, ADPS2);
- cbi(ADCSRA, ADPS1);
- sbi(ADCSRA, ADPS0);
-
- if (RESET_SETTINGS) EEPROM.write(100, 0); // сброс флага настроек
-
- if (AUTO_LOW_PASS && !EEPROM_LOW_PASS) { // если разрешена автонастройка нижнего порога шумов
- autoLowPass();
- }
- if (EEPROM_LOW_PASS) { // восстановить значения шумов из памяти
- LOW_PASS = EEPROM.readInt(70);
- SPEKTR_LOW_PASS = EEPROM.readInt(72);
- }
-
- // в 100 ячейке хранится число 100. Если нет - значит это первый запуск системы
- if (KEEP_SETTINGS) {
- if (EEPROM.read(100) != 100) {
- //Serial.println(F("First start"));
- EEPROM.write(100, 100);
- updateEEPROM();
- } else {
- readEEPROM();
- }
- }
-}
-
-void loop() {
- buttonTick(); // опрос и обработка кнопки
-#if IR_RCT != 0
- remoteTick(); // опрос ИК пульта
-#endif
- mainLoop(); // главный цикл обработки и отрисовки
- eepromTick(); // проверка не пора ли сохранить настройки
-}
-
-void mainLoop() {
- // главный цикл отрисовки
- if (ONstate) {
- if (millis() - main_timer > MAIN_LOOP) {
- // сбрасываем значения
- RsoundLevel = 0;
- LsoundLevel = 0;
-
- // перваые два режима - громкость (VU meter)
- if (this_mode == 0 || this_mode == 1) {
- for (byte i = 0; i < 100; i ++) { // делаем 100 измерений
- RcurrentLevel = analogRead(SOUND_R); // с правого
- if (!MONO) LcurrentLevel = analogRead(SOUND_L); // и левого каналов
-
- if (RsoundLevel < RcurrentLevel) RsoundLevel = RcurrentLevel; // ищем максимальное
- if (!MONO) if (LsoundLevel < LcurrentLevel) LsoundLevel = LcurrentLevel; // ищем максимальное
- }
-
- // фильтруем по нижнему порогу шумов
- RsoundLevel = map(RsoundLevel, LOW_PASS, 1023, 0, 500);
- if (!MONO)LsoundLevel = map(LsoundLevel, LOW_PASS, 1023, 0, 500);
-
- // ограничиваем диапазон
- RsoundLevel = constrain(RsoundLevel, 0, 500);
- if (!MONO)LsoundLevel = constrain(LsoundLevel, 0, 500);
-
- // возводим в степень (для большей чёткости работы)
- RsoundLevel = pow(RsoundLevel, EXP);
- if (!MONO)LsoundLevel = pow(LsoundLevel, EXP);
-
- // фильтр
- RsoundLevel_f = RsoundLevel * SMOOTH + RsoundLevel_f * (1 - SMOOTH);
- if (!MONO)LsoundLevel_f = LsoundLevel * SMOOTH + LsoundLevel_f * (1 - SMOOTH);
-
- if (MONO) LsoundLevel_f = RsoundLevel_f; // если моно, то левый = правому
-
- // заливаем "подложку", если яркость достаточная
- if (EMPTY_BRIGHT > 5) {
- for (int i = 0; i < NUM_LEDS; i++)
- leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- }
-
- // если значение выше порога - начинаем самое интересное
- if (RsoundLevel_f > 15 && LsoundLevel_f > 15) {
-
- // расчёт общей средней громкости с обоих каналов, фильтрация.
- // Фильтр очень медленный, сделано специально для автогромкости
- averageLevel = (float)(RsoundLevel_f + LsoundLevel_f) / 2 * averK + averageLevel * (1 - averK);
-
- // принимаем максимальную громкость шкалы как среднюю, умноженную на некоторый коэффициент MAX_COEF
- maxLevel = (float)averageLevel * MAX_COEF;
-
- // преобразуем сигнал в длину ленты (где MAX_CH это половина количества светодиодов)
- Rlenght = map(RsoundLevel_f, 0, maxLevel, 0, MAX_CH);
- Llenght = map(LsoundLevel_f, 0, maxLevel, 0, MAX_CH);
-
- // ограничиваем до макс. числа светодиодов
- Rlenght = constrain(Rlenght, 0, MAX_CH);
- Llenght = constrain(Llenght, 0, MAX_CH);
-
- animation(); // отрисовать
- }
- }
-
- // 3-5 режим - цветомузыка
- if (this_mode == 2 || this_mode == 3 || this_mode == 4 || this_mode == 7 || this_mode == 8) {
- analyzeAudio();
- colorMusic[0] = 0;
- colorMusic[1] = 0;
- colorMusic[2] = 0;
- for (int i = 0 ; i < 32 ; i++) {
- if (fht_log_out[i] < SPEKTR_LOW_PASS) fht_log_out[i] = 0;
- }
- // низкие частоты, выборка со 2 по 5 тон (0 и 1 зашумленные!)
- for (byte i = 2; i < 6; i++) {
- if (fht_log_out[i] > colorMusic[0]) colorMusic[0] = fht_log_out[i];
- }
- // средние частоты, выборка с 6 по 10 тон
- for (byte i = 6; i < 11; i++) {
- if (fht_log_out[i] > colorMusic[1]) colorMusic[1] = fht_log_out[i];
- }
- // высокие частоты, выборка с 11 по 31 тон
- for (byte i = 11; i < 32; i++) {
- if (fht_log_out[i] > colorMusic[2]) colorMusic[2] = fht_log_out[i];
- }
- freq_max = 0;
- for (byte i = 0; i < 30; i++) {
- if (fht_log_out[i + 2] > freq_max) freq_max = fht_log_out[i + 2];
- if (freq_max < 5) freq_max = 5;
-
- if (freq_f[i] < fht_log_out[i + 2]) freq_f[i] = fht_log_out[i + 2];
- if (freq_f[i] > 0) freq_f[i] -= LIGHT_SMOOTH;
- else freq_f[i] = 0;
- }
- freq_max_f = freq_max * averK + freq_max_f * (1 - averK);
- for (byte i = 0; i < 3; i++) {
- colorMusic_aver[i] = colorMusic[i] * averK + colorMusic_aver[i] * (1 - averK); // общая фильтрация
- colorMusic_f[i] = colorMusic[i] * SMOOTH_FREQ + colorMusic_f[i] * (1 - SMOOTH_FREQ); // локальная
- if (colorMusic_f[i] > ((float)colorMusic_aver[i] * MAX_COEF_FREQ)) {
- thisBright[i] = 255;
- colorMusicFlash[i] = true;
- running_flag[i] = true;
- } else colorMusicFlash[i] = false;
- if (thisBright[i] >= 0) thisBright[i] -= SMOOTH_STEP;
- if (thisBright[i] < EMPTY_BRIGHT) {
- thisBright[i] = EMPTY_BRIGHT;
- running_flag[i] = false;
- }
- }
- animation();
- }
- if (this_mode == 5) {
- if ((long)millis() - strobe_timer > STROBE_PERIOD) {
- strobe_timer = millis();
- strobeUp_flag = true;
- strobeDwn_flag = false;
- }
- if ((long)millis() - strobe_timer > light_time) {
- strobeDwn_flag = true;
- }
- if (strobeUp_flag) { // если настало время пыхнуть
- if (strobe_bright < 255) // если яркость не максимальная
- strobe_bright += STROBE_SMOOTH; // увелчить
- if (strobe_bright > 255) { // если пробили макс. яркость
- strobe_bright = 255; // оставить максимум
- strobeUp_flag = false; // флаг опустить
- }
- }
-
- if (strobeDwn_flag) { // гаснем
- if (strobe_bright > 0) // если яркость не минимальная
- strobe_bright -= STROBE_SMOOTH; // уменьшить
- if (strobe_bright < 0) { // если пробили мин. яркость
- strobeDwn_flag = false;
- strobe_bright = 0; // оставить 0
- }
- }
- animation();
- }
- if (this_mode == 6) animation();
-
- if (!IRLremote.receiving()) // если на ИК приёмник не приходит сигнал (без этого НЕ РАБОТАЕТ!)
- FastLED.show(); // отправить значения на ленту
-
- if (this_mode != 7) // 7 режиму не нужна очистка!!!
- FastLED.clear(); // очистить массив пикселей
- main_timer = millis(); // сбросить таймер
- }
- }
-}
-
-void animation() {
- // согласно режиму
- switch (this_mode) {
- case 0:
- count = 0;
- for (int i = (MAX_CH - 1); i > ((MAX_CH - 1) - Rlenght); i--) {
- leds[i] = ColorFromPalette(myPal, (count * index)); // заливка по палитре " от зелёного к красному"
- count++;
- }
- count = 0;
- for (int i = (MAX_CH); i < (MAX_CH + Llenght); i++ ) {
- leds[i] = ColorFromPalette(myPal, (count * index)); // заливка по палитре " от зелёного к красному"
- count++;
- }
- if (EMPTY_BRIGHT > 0) {
- CHSV this_dark = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- for (int i = ((MAX_CH - 1) - Rlenght); i > 0; i--)
- leds[i] = this_dark;
- for (int i = MAX_CH + Llenght; i < NUM_LEDS; i++)
- leds[i] = this_dark;
- }
- break;
- case 1:
- if (millis() - rainbow_timer > 30) {
- rainbow_timer = millis();
- hue = floor((float)hue + RAINBOW_STEP);
- }
- count = 0;
- for (int i = (MAX_CH - 1); i > ((MAX_CH - 1) - Rlenght); i--) {
- leds[i] = ColorFromPalette(RainbowColors_p, (count * index) / 2 - hue); // заливка по палитре радуга
- count++;
- }
- count = 0;
- for (int i = (MAX_CH); i < (MAX_CH + Llenght); i++ ) {
- leds[i] = ColorFromPalette(RainbowColors_p, (count * index) / 2 - hue); // заливка по палитре радуга
- count++;
- }
- if (EMPTY_BRIGHT > 0) {
- CHSV this_dark = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- for (int i = ((MAX_CH - 1) - Rlenght); i > 0; i--)
- leds[i] = this_dark;
- for (int i = MAX_CH + Llenght; i < NUM_LEDS; i++)
- leds[i] = this_dark;
- }
- break;
- case 2:
- for (int i = 0; i < NUM_LEDS; i++) {
- if (i < STRIPE) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (i < STRIPE * 2) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < STRIPE * 3) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else if (i < STRIPE * 4) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < STRIPE * 5) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- }
- break;
- case 3:
- for (int i = 0; i < NUM_LEDS; i++) {
- if (i < NUM_LEDS / 3) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (i < NUM_LEDS * 2 / 3) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < NUM_LEDS) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
- }
- break;
- case 4:
- switch (freq_strobe_mode) {
- case 0:
- if (colorMusicFlash[2]) HIGHS();
- else if (colorMusicFlash[1]) MIDS();
- else if (colorMusicFlash[0]) LOWS();
- else SILENCE();
- break;
- case 1:
- if (colorMusicFlash[2]) HIGHS();
- else SILENCE();
- break;
- case 2:
- if (colorMusicFlash[1]) MIDS();
- else SILENCE();
- break;
- case 3:
- if (colorMusicFlash[0]) LOWS();
- else SILENCE();
- break;
- }
- break;
- case 5:
- if (strobe_bright > 0)
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(STROBE_COLOR, STROBE_SAT, strobe_bright);
- else
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 6:
- switch (light_mode) {
- case 0: for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(LIGHT_COLOR, LIGHT_SAT, 255);
- break;
- case 1:
- if (millis() - color_timer > COLOR_SPEED) {
- color_timer = millis();
- if (++this_color > 255) this_color = 0;
- }
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(this_color, LIGHT_SAT, 255);
- break;
- case 2:
- if (millis() - rainbow_timer > 30) {
- rainbow_timer = millis();
- this_color += RAINBOW_PERIOD;
- if (this_color > 255) this_color = 0;
- if (this_color < 0) this_color = 255;
- }
- rainbow_steps = this_color;
- for (int i = 0; i < NUM_LEDS; i++) {
- leds[i] = CHSV((int)floor(rainbow_steps), 255, 255);
- rainbow_steps += RAINBOW_STEP_2;
- if (rainbow_steps > 255) rainbow_steps = 0;
- if (rainbow_steps < 0) rainbow_steps = 255;
- }
- break;
- }
- break;
- case 7:
- switch (freq_strobe_mode) {
- case 0:
- if (running_flag[2]) leds[NUM_LEDS / 2] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (running_flag[1]) leds[NUM_LEDS / 2] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (running_flag[0]) leds[NUM_LEDS / 2] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 1:
- if (running_flag[2]) leds[NUM_LEDS / 2] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 2:
- if (running_flag[1]) leds[NUM_LEDS / 2] = CHSV(MID_COLOR, 255, thisBright[1]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 3:
- if (running_flag[0]) leds[NUM_LEDS / 2] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- }
- leds[(NUM_LEDS / 2) - 1] = leds[NUM_LEDS / 2];
- if (millis() - running_timer > RUNNING_SPEED) {
- running_timer = millis();
- for (byte i = 0; i < NUM_LEDS / 2 - 1; i++) {
- leds[i] = leds[i + 1];
- leds[NUM_LEDS - i - 1] = leds[i];
- }
- }
- break;
- case 8:
- byte HUEindex = HUE_START;
- for (byte i = 0; i < NUM_LEDS / 2; i++) {
- byte this_bright = map(freq_f[(int)floor((NUM_LEDS / 2 - i) / freq_to_stripe)], 0, freq_max_f, 0, 255);
- this_bright = constrain(this_bright, 0, 255);
- leds[i] = CHSV(HUEindex, 255, this_bright);
- leds[NUM_LEDS - i - 1] = leds[i];
- HUEindex += HUE_STEP;
- if (HUEindex > 255) HUEindex = 0;
- }
- break;
- }
-}
-
-void HIGHS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
-}
-void MIDS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
-}
-void LOWS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
-}
-void SILENCE() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
-}
-
-// вспомогательная функция, изменяет величину value на шаг incr в пределах minimum.. maximum
-int smartIncr(int value, int incr_step, int mininmum, int maximum) {
- int val_buf = value + incr_step;
- val_buf = constrain(val_buf, mininmum, maximum);
- return val_buf;
-}
-
-float smartIncrFloat(float value, float incr_step, float mininmum, float maximum) {
- float val_buf = value + incr_step;
- val_buf = constrain(val_buf, mininmum, maximum);
- return val_buf;
-}
-
-#if IR_RCT != 0
-void remoteTick() {
- if (IRLremote.available()) {
- auto data = IRLremote.read();
- IRdata = data.command;
- ir_flag = true;
- }
- if (ir_flag) { // если данные пришли
- eeprom_timer = millis();
- eeprom_flag = true;
- switch (IRdata) {
- // режимы
- case BUTT_1: this_mode = 0;
- break;
- case BUTT_2: this_mode = 1;
- break;
- case BUTT_3: this_mode = 2;
- break;
- case BUTT_4: this_mode = 3;
- break;
- case BUTT_5: this_mode = 4;
- break;
- case BUTT_6: this_mode = 5;
- break;
- case BUTT_7: this_mode = 6;
- break;
- case BUTT_8: this_mode = 7;
- break;
- case BUTT_9: this_mode = 8;
- break;
- case BUTT_0: fullLowPass();
- break;
- case BUTT_STAR: ONstate = !ONstate; FastLED.clear(); FastLED.show(); updateEEPROM();
- break;
- case BUTT_HASH:
- switch (this_mode) {
- case 4:
- case 7: if (++freq_strobe_mode > 3) freq_strobe_mode = 0;
- break;
- case 6: if (++light_mode > 2) light_mode = 0;
- break;
- }
- break;
- case BUTT_OK: digitalWrite(MLED_PIN, settings_mode ^ MLED_ON); settings_mode = !settings_mode;
- break;
- case BUTT_UP:
- if (settings_mode) {
- // ВВЕРХ общие настройки
- EMPTY_BRIGHT = smartIncr(EMPTY_BRIGHT, 5, 0, 255);
- } else {
- switch (this_mode) {
- case 0:
- break;
- case 1: RAINBOW_STEP = smartIncrFloat(RAINBOW_STEP, 0.5, 0.5, 20);
- break;
- case 2:
- case 3:
- case 4: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, 0.1, 0, 5);
- break;
- case 5: STROBE_PERIOD = smartIncr(STROBE_PERIOD, 20, 1, 1000);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_SAT = smartIncr(LIGHT_SAT, 20, 0, 255);
- break;
- case 1: LIGHT_SAT = smartIncr(LIGHT_SAT, 20, 0, 255);
- break;
- case 2: RAINBOW_STEP_2 = smartIncrFloat(RAINBOW_STEP_2, 0.5, 0.5, 10);
- break;
- }
- break;
- case 7: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, 0.1, 0.0, 10);
- break;
- case 8: HUE_START = smartIncr(HUE_START, 10, 0, 255);
- break;
- }
- }
- break;
- case BUTT_DOWN:
- if (settings_mode) {
- // ВНИЗ общие настройки
- EMPTY_BRIGHT = smartIncr(EMPTY_BRIGHT, -5, 0, 255);
- } else {
- switch (this_mode) {
- case 0:
- break;
- case 1: RAINBOW_STEP = smartIncrFloat(RAINBOW_STEP, -0.5, 0.5, 20);
- break;
- case 2:
- case 3:
- case 4: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, -0.1, 0, 5);
- break;
- case 5: STROBE_PERIOD = smartIncr(STROBE_PERIOD, -20, 1, 1000);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_SAT = smartIncr(LIGHT_SAT, -20, 0, 255);
- break;
- case 1: LIGHT_SAT = smartIncr(LIGHT_SAT, -20, 0, 255);
- break;
- case 2: RAINBOW_STEP_2 = smartIncrFloat(RAINBOW_STEP_2, -0.5, 0.5, 10);
- break;
- }
- break;
- case 7: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, -0.1, 0.0, 10);
- break;
- case 8: HUE_START = smartIncr(HUE_START, -10, 0, 255);
- break;
- }
- }
- break;
- case BUTT_LEFT:
- if (settings_mode) {
- // ВЛЕВО общие настройки
- BRIGHTNESS = smartIncr(BRIGHTNESS, -20, 0, 255);
- FastLED.setBrightness(BRIGHTNESS);
- } else {
- switch (this_mode) {
- case 0:
- case 1: SMOOTH = smartIncrFloat(SMOOTH, -0.05, 0.05, 1);
- break;
- case 2:
- case 3:
- case 4: SMOOTH_FREQ = smartIncrFloat(SMOOTH_FREQ, -0.05, 0.05, 1);
- break;
- case 5: STROBE_SMOOTH = smartIncr(STROBE_SMOOTH, -20, 0, 255);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_COLOR = smartIncr(LIGHT_COLOR, -10, 0, 255);
- break;
- case 1: COLOR_SPEED = smartIncr(COLOR_SPEED, -10, 0, 255);
- break;
- case 2: RAINBOW_PERIOD = smartIncr(RAINBOW_PERIOD, -1, -20, 20);
- break;
- }
- break;
- case 7: RUNNING_SPEED = smartIncr(RUNNING_SPEED, -10, 1, 255);
- break;
- case 8: HUE_STEP = smartIncr(HUE_STEP, -1, 1, 255);
- break;
- }
- }
- break;
- case BUTT_RIGHT:
- if (settings_mode) {
- // ВПРАВО общие настройки
- BRIGHTNESS = smartIncr(BRIGHTNESS, 20, 0, 255);
- FastLED.setBrightness(BRIGHTNESS);
- } else {
- switch (this_mode) {
- case 0:
- case 1: SMOOTH = smartIncrFloat(SMOOTH, 0.05, 0.05, 1);
- break;
- case 2:
- case 3:
- case 4: SMOOTH_FREQ = smartIncrFloat(SMOOTH_FREQ, 0.05, 0.05, 1);
- break;
- case 5: STROBE_SMOOTH = smartIncr(STROBE_SMOOTH, 20, 0, 255);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_COLOR = smartIncr(LIGHT_COLOR, 10, 0, 255);
- break;
- case 1: COLOR_SPEED = smartIncr(COLOR_SPEED, 10, 0, 255);
- break;
- case 2: RAINBOW_PERIOD = smartIncr(RAINBOW_PERIOD, 1, -20, 20);
- break;
- }
- break;
- case 7: RUNNING_SPEED = smartIncr(RUNNING_SPEED, 10, 1, 255);
- break;
- case 8: HUE_STEP = smartIncr(HUE_STEP, 1, 1, 255);
- break;
- }
- }
- break;
- default: eeprom_flag = false; // если не распознали кнопку, не обновляем настройки!
- break;
- }
- ir_flag = false;
- }
-}
-#endif
-
-void autoLowPass() {
- // для режима VU
- delay(10); // ждём инициализации АЦП
- int thisMax = 0; // максимум
- int thisLevel;
- for (byte i = 0; i < 200; i++) {
- thisLevel = analogRead(SOUND_R); // делаем 200 измерений
- if (thisLevel > thisMax) // ищем максимумы
- thisMax = thisLevel; // запоминаем
- delay(4); // ждём 4мс
- }
- LOW_PASS = thisMax + LOW_PASS_ADD; // нижний порог как максимум тишины + некая величина
-
- // для режима спектра
- thisMax = 0;
- for (byte i = 0; i < 100; i++) { // делаем 100 измерений
- analyzeAudio(); // разбить в спектр
- for (byte j = 2; j < 32; j++) { // первые 2 канала - хлам
- thisLevel = fht_log_out[j];
- if (thisLevel > thisMax) // ищем максимумы
- thisMax = thisLevel; // запоминаем
- }
- delay(4); // ждём 4мс
- }
- SPEKTR_LOW_PASS = thisMax + LOW_PASS_FREQ_ADD; // нижний порог как максимум тишины
- if (EEPROM_LOW_PASS && !AUTO_LOW_PASS) {
- EEPROM.updateInt(70, LOW_PASS);
- EEPROM.updateInt(72, SPEKTR_LOW_PASS);
- }
-}
-
-void analyzeAudio() {
- for (int i = 0 ; i < FHT_N ; i++) {
- int sample = analogRead(SOUND_R_FREQ);
- fht_input[i] = sample; // put real data into bins
- }
- fht_window(); // window the data for better frequency response
- fht_reorder(); // reorder the data before doing the fht
- fht_run(); // process the data in the fht
- fht_mag_log(); // take the output of the fht
-}
-
-void buttonTick() {
- butt1.tick(); // обязательная функция отработки. Должна постоянно опрашиваться
- if (butt1.isSingle()) // если единичное нажатие
- if (++this_mode >= MODE_AMOUNT) this_mode = 0; // изменить режим
-
- if (butt1.isHolded()) { // кнопка удержана
- fullLowPass();
- }
-}
-void fullLowPass() {
- digitalWrite(MLED_PIN, MLED_ON); // включить светодиод
- FastLED.setBrightness(0); // погасить ленту
- FastLED.clear(); // очистить массив пикселей
- FastLED.show(); // отправить значения на ленту
- delay(500); // подождать чутка
- autoLowPass(); // измерить шумы
- delay(500); // подождать
- FastLED.setBrightness(BRIGHTNESS); // вернуть яркость
- digitalWrite(MLED_PIN, !MLED_ON); // выключить светодиод
-}
-void updateEEPROM() {
- EEPROM.updateByte(1, this_mode);
- EEPROM.updateByte(2, freq_strobe_mode);
- EEPROM.updateByte(3, light_mode);
- EEPROM.updateInt(4, RAINBOW_STEP);
- EEPROM.updateFloat(8, MAX_COEF_FREQ);
- EEPROM.updateInt(12, STROBE_PERIOD);
- EEPROM.updateInt(16, LIGHT_SAT);
- EEPROM.updateFloat(20, RAINBOW_STEP_2);
- EEPROM.updateInt(24, HUE_START);
- EEPROM.updateFloat(28, SMOOTH);
- EEPROM.updateFloat(32, SMOOTH_FREQ);
- EEPROM.updateInt(36, STROBE_SMOOTH);
- EEPROM.updateInt(40, LIGHT_COLOR);
- EEPROM.updateInt(44, COLOR_SPEED);
- EEPROM.updateInt(48, RAINBOW_PERIOD);
- EEPROM.updateInt(52, RUNNING_SPEED);
- EEPROM.updateInt(56, HUE_STEP);
- EEPROM.updateInt(60, EMPTY_BRIGHT);
- if (KEEP_STATE) EEPROM.updateByte(64, ONstate);
-}
-void readEEPROM() {
- this_mode = EEPROM.readByte(1);
- freq_strobe_mode = EEPROM.readByte(2);
- light_mode = EEPROM.readByte(3);
- RAINBOW_STEP = EEPROM.readInt(4);
- MAX_COEF_FREQ = EEPROM.readFloat(8);
- STROBE_PERIOD = EEPROM.readInt(12);
- LIGHT_SAT = EEPROM.readInt(16);
- RAINBOW_STEP_2 = EEPROM.readFloat(20);
- HUE_START = EEPROM.readInt(24);
- SMOOTH = EEPROM.readFloat(28);
- SMOOTH_FREQ = EEPROM.readFloat(32);
- STROBE_SMOOTH = EEPROM.readInt(36);
- LIGHT_COLOR = EEPROM.readInt(40);
- COLOR_SPEED = EEPROM.readInt(44);
- RAINBOW_PERIOD = EEPROM.readInt(48);
- RUNNING_SPEED = EEPROM.readInt(52);
- HUE_STEP = EEPROM.readInt(56);
- EMPTY_BRIGHT = EEPROM.readInt(60);
- if (KEEP_STATE) ONstate = EEPROM.readByte(64);
-}
-void eepromTick() {
- if (eeprom_flag)
- if (millis() - eeprom_timer > 30000) { // 30 секунд после последнего нажатия с пульта
- eeprom_flag = false;
- eeprom_timer = millis();
- updateEEPROM();
- }
-}
diff --git a/firmware/Old versions/colorMusic_v2.7/colorMusic_v2.7.ino b/firmware/Old versions/colorMusic_v2.7/colorMusic_v2.7.ino
deleted file mode 100644
index dbd1566..0000000
--- a/firmware/Old versions/colorMusic_v2.7/colorMusic_v2.7.ino
+++ /dev/null
@@ -1,996 +0,0 @@
-/*
- Версия 2.7 использует библиотеки FastLED и IRLremote!
- Библиотеки идут в архиве с проектом! https://alexgyver.ru/colormusic/
- Крутейшая свето-цветомузыка на Arduino и адресной светодиодной ленте WS2812b.
- Данная версия поддерживает около 410 светодиодов!
- Версия ИК пульта задаётся в IR_RCT!
-
- Управление:
- - Однократное нажатие кнопки: смена режима
- - Удержание кнопки: калибровка нижнего порога шума
- Режимы работы (переключаются кнопкой):
- - VU meter (столбик громкости): от зелёного к красному
- - VU meter (столбик громкости): плавно бегущая радуга
- - Светомузыка по частотам: 5 полос симметрично
- - Светомузыка по частотам: 3 полосы
- - Светомузыка по частотам: 1 полоса
- - Стробоскоп
- - (2.0) Подсветка
- - (2.0) Бегущие частоты
- - (2.1) анализатор спектра
- Особенности:
- - Плавная анимация (можно настроить)
- - Автонастройка по громкости (можно настроить)
- - Фильтр нижнего шума (можно настроить)
- - Автокалибровка шума при запуске (можно настроить)
- - Поддержка стерео и моно звука (можно настроить)
- - (2.0) в режиме частот лента не гаснет полностью (EMPTY_BRIGHT)
- - (2.1) все настройки сохраняются в памяти и не сбрасываются при перезагрузке
- - Сохранение настроек происходит при выключении кнопкой звёздочка (*)
- - А также через 30 секунд после последнего нажатия на любую кнопку ИК пульта
-
- НАСТРОЙКА НИЖНЕГО ПОРОГА ШУМА (строки 65-71)
- - Включаем систему
- - Ставим музыку на паузу
- - Удерживаем кнопку 1 секунду ИЛИ жмём кнопку 0 на пульте
- Значения шумов будут записаны в память и САМИ загружаться при последующем запуске! Всё!
-
- Пульт:
- - Цифры (1 - 9) активируют режимы
- - Цифра 0: калибровка шума
- - Звёздочка (*): включить/выключить систему
- - Кнопка ОК: переключение между локальными и глобальными настройками)
- - Решётка (#): смена подрежима
- - Глобальные настройки (горит светодиод на плате):
- + Стрелки ← →: общая яркость горящих светодиодов
- + Стрелки ↑ ↓: яркость "не горящих" светодиодов
- - Локальные настройки (у каждого режима свои):
- 1 - Шкала громкости (градиент)
- Стрелки ← →: плавность анимации
- 2 - Шкала громкости (радуга)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: скорость радуги
- 3 - Цветомузыка (5 полос)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- 4 - Цветомузыка (3 полосы)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- 5 - Цветомузыка (1 полоса)
- Стрелки ← →: плавность анимации
- Стрелки ↑ ↓: чувствительность
- Подрежимы #: 3 частоты / низкие / средние / высокие
- 6 - Стробоскоп
- Стрелки ← →: плавность вспышек
- Стрелки ↑ ↓: частота вспышек
- 7 - Цветная подсветка
- Подрежимы #:
- Постоянный: стрелки ← →: цвет, стрелки ↑ ↓: насыщенность
- Плавная смена: стрелки ← →: скорость, стрелки ↑ ↓: насыщенность
- Бегущая радуга: стрелки ← →: скорость, стрелки ↑ ↓: шаг радуги
- 8 - “Бегущие частоты”
- Стрелки ← →: скорость
- Стрелки ↑ ↓: чувствительность
- Подрежимы #: 3 частоты / низкие / средние / высокие
- 9 - Анализатор спектра
- Стрелки ← →: шаг цвета
- Стрелки ↑ ↓: цвет
- **************************************************
- Разработано: AlexGyver
- Страница проекта: http://alexgyver.ru/colormusic/
- GitHub: https://github.com/AlexGyver/ColorMusic
-*/
-
-// --------------------------- НАСТРОЙКИ ---------------------------
-#define KEEP_SETTINGS 1 // хранить ВСЕ настройки в памяти
-#define KEEP_STATE 1 // сохранять в памяти состояние вкл/выкл (с пульта)
-#define RESET_SETTINGS 0 // сброс настроек в памяти
-// поставить 1. Прошиться. Поставить обратно 0. Прошиться. Всё.
-
-// лента
-#define NUM_LEDS 10 // количество светодиодов
-byte BRIGHTNESS = 200; // яркость (0 - 255)
-
-// пины
-#define SOUND_R A2 // аналоговый пин вход аудио, правый канал
-#define SOUND_L A1 // аналоговый пин вход аудио, левый канал
-#define SOUND_R_FREQ A3 // аналоговый пин вход аудио для режима с частотами (через кондер)
-#define BTN_PIN 3 // кнопка переключения режимов (PIN --- КНОПКА --- GND)
-#if defined(__AVR_ATmega32U4__) // Пины для Arduino Pro Micro
-#define MLED_PIN 17 // пин светодиода режимов на ProMicro, т.к. обычный не выведен.
-#define MLED_ON LOW
-#define LED_PIN 9 // пин DI светодиодной ленты на ProMicro, т.к. обычный не выведен.
-#else // Пины для других плат Arduino (по умолчанию)
-#define MLED_PIN 13 // пин светодиода режимов
-#define MLED_ON HIGH
-#define LED_PIN 12 // пин DI светодиодной ленты
-#endif
-#define POT_GND A0 // пин земля для потенциометра
-#define IR_RCT 1 // тип ИК пульта 0 - без пульта, 1-WAVGAT, 2-KEYES
-#define IR_PIN 2 // пин ИК приёмника
-
-// настройки радуги
-float RAINBOW_STEP = 5.5; // шаг изменения цвета радуги
-
-// отрисовка
-#define MODE 0 // режим при запуске
-#define MAIN_LOOP 5 // период основного цикла отрисовки (по умолчанию 5)
-
-// сигнал
-#define MONO 1 // 1 - только один канал (ПРАВЫЙ!!!!! SOUND_R!!!!!), 0 - два канала
-#define EXP 1.4 // степень усиления сигнала (для более "резкой" работы) (по умолчанию 1.4)
-#define POTENT 0 // 1 - используем потенциометр, 0 - используется внутренний источник опорного напряжения 1.1 В
-byte EMPTY_BRIGHT = 30; // яркость "не горящих" светодиодов (0 - 255)
-#define EMPTY_COLOR HUE_PURPLE // цвет "не горящих" светодиодов. Будет чёрный, если яркость 0
-
-// нижний порог шумов
-uint16_t LOW_PASS = 100; // нижний порог шумов режим VU, ручная настройка
-uint16_t SPEKTR_LOW_PASS = 40; // нижний порог шумов режим спектра, ручная настройка
-#define AUTO_LOW_PASS 0 // разрешить настройку нижнего порога шумов при запуске (по умолч. 0)
-#define EEPROM_LOW_PASS 1 // порог шумов хранится в энергонезависимой памяти (по умолч. 1)
-#define LOW_PASS_ADD 13 // "добавочная" величина к нижнему порогу, для надёжности (режим VU)
-#define LOW_PASS_FREQ_ADD 3 // "добавочная" величина к нижнему порогу, для надёжности (режим частот)
-
-// шкала громкости
-float SMOOTH = 0.5; // коэффициент плавности анимации VU (по умолчанию 0.5)
-#define MAX_COEF 1.8 // коэффициент громкости (максимальное равно срднему * этот коэф) (по умолчанию 1.8)
-
-// режим цветомузыки
-float SMOOTH_FREQ = 0.8; // коэффициент плавности анимации частот (по умолчанию 0.8)
-float MAX_COEF_FREQ = 1.2; // коэффициент порога для "вспышки" цветомузыки (по умолчанию 1.5)
-#define SMOOTH_STEP 20 // шаг уменьшения яркости в режиме цветомузыки (чем больше, тем быстрее гаснет)
-#define LOW_COLOR HUE_RED // цвет низких частот
-#define MID_COLOR HUE_GREEN // цвет средних
-#define HIGH_COLOR HUE_YELLOW // цвет высоких
-
-// режим стробоскопа
-uint16_t STROBE_PERIOD = 100; // период вспышек, миллисекунды
-#define STROBE_DUTY 20 // скважность вспышек (1 - 99) - отношение времени вспышки ко времени темноты
-#define STROBE_COLOR HUE_YELLOW // цвет стробоскопа
-#define STROBE_SAT 0 // насыщенность. Если 0 - цвет будет БЕЛЫЙ при любом цвете (0 - 255)
-byte STROBE_SMOOTH = 100; // скорость нарастания/угасания вспышки (0 - 255)
-
-// режим подсветки
-byte LIGHT_COLOR = 0; // начальный цвет подсветки
-byte LIGHT_SAT = 200; // начальная насыщенность подсветки
-byte COLOR_SPEED = 100;
-int RAINBOW_PERIOD = 3;
-float RAINBOW_STEP_2 = 5.5;
-
-// режим бегущих частот
-byte RUNNING_SPEED = 60;
-
-// режим анализатора спектра
-byte HUE_START = 0;
-byte HUE_STEP = 5;
-#define LIGHT_SMOOTH 2
-
-/*
- Цвета для HSV
- HUE_RED
- HUE_ORANGE
- HUE_YELLOW
- HUE_GREEN
- HUE_AQUA
- HUE_BLUE
- HUE_PURPLE
- HUE_PINK
-*/
-// --------------------------- НАСТРОЙКИ ---------------------------
-
-// ----- КНОПКИ ПУЛЬТА WAVGAT -----
-#if IR_RCT == 1
-#define BUTT_UP 0xF39EEBAD
-#define BUTT_DOWN 0xC089F6AD
-#define BUTT_LEFT 0xE25410AD
-#define BUTT_RIGHT 0x14CE54AD
-#define BUTT_OK 0x297C76AD
-#define BUTT_1 0x4E5BA3AD
-#define BUTT_2 0xE51CA6AD
-#define BUTT_3 0xE207E1AD
-#define BUTT_4 0x517068AD
-#define BUTT_5 0x1B92DDAD
-#define BUTT_6 0xAC2A56AD
-#define BUTT_7 0x5484B6AD
-#define BUTT_8 0xD22353AD
-#define BUTT_9 0xDF3F4BAD
-#define BUTT_0 0xF08A26AD
-#define BUTT_STAR 0x68E456AD
-#define BUTT_HASH 0x151CD6AD
-#endif
-// ----- КНОПКИ ПУЛЬТА WAVGAT -----
-
-// ----- КНОПКИ ПУЛЬТА KEYES -----
-#if IR_RCT == 2
-#define BUTT_UP 0xE51CA6AD
-#define BUTT_DOWN 0xD22353AD
-#define BUTT_LEFT 0x517068AD
-#define BUTT_RIGHT 0xAC2A56AD
-#define BUTT_OK 0x1B92DDAD
-#define BUTT_1 0x68E456AD
-#define BUTT_2 0xF08A26AD
-#define BUTT_3 0x151CD6AD
-#define BUTT_4 0x18319BAD
-#define BUTT_5 0xF39EEBAD
-#define BUTT_6 0x4AABDFAD
-#define BUTT_7 0xE25410AD
-#define BUTT_8 0x297C76AD
-#define BUTT_9 0x14CE54AD
-#define BUTT_0 0xC089F6AD
-#define BUTT_STAR 0xAF3F1BAD
-#define BUTT_HASH 0x38379AD
-#endif
-// ----- КНОПКИ ПУЛЬТА KEYES -----
-
-// ------------------------------ ДЛЯ РАЗРАБОТЧИКОВ --------------------------------
-#define MODE_AMOUNT 9 // количество режимов
-
-#define STRIPE NUM_LEDS / 5
-float freq_to_stripe = NUM_LEDS / 40; // /2 так как симметрия, и /20 так как 20 частот
-
-#define FHT_N 64 // ширина спектра х2
-#define LOG_OUT 1
-#include // преобразование Хартли
-
-#include
-
-#define FASTLED_ALLOW_INTERRUPTS 1
-#include "FastLED.h"
-CRGB leds[NUM_LEDS];
-
-#include "GyverButton.h"
-GButton butt1(BTN_PIN);
-
-#include "IRLremote.h"
-CHashIR IRLremote;
-uint32_t IRdata;
-
-// градиент-палитра от зелёного к красному
-DEFINE_GRADIENT_PALETTE(soundlevel_gp) {
- 0, 0, 255, 0, // green
- 100, 255, 255, 0, // yellow
- 150, 255, 100, 0, // orange
- 200, 255, 50, 0, // red
- 255, 255, 0, 0 // red
-};
-CRGBPalette32 myPal = soundlevel_gp;
-
-byte Rlenght, Llenght;
-float RsoundLevel, RsoundLevel_f;
-float LsoundLevel, LsoundLevel_f;
-
-float averageLevel = 50;
-int maxLevel = 100;
-byte MAX_CH = NUM_LEDS / 2;
-int hue;
-unsigned long main_timer, hue_timer, strobe_timer, running_timer, color_timer, rainbow_timer, eeprom_timer;
-float averK = 0.006;
-byte count;
-float index = (float)255 / MAX_CH; // коэффициент перевода для палитры
-boolean lowFlag;
-byte low_pass;
-int RcurrentLevel, LcurrentLevel;
-int colorMusic[3];
-float colorMusic_f[3], colorMusic_aver[3];
-boolean colorMusicFlash[3], strobeUp_flag, strobeDwn_flag;
-byte this_mode = MODE;
-int thisBright[3], strobe_bright = 0;
-unsigned int light_time = STROBE_PERIOD * STROBE_DUTY / 100;
-volatile boolean ir_flag;
-boolean settings_mode, ONstate = true;
-int8_t freq_strobe_mode, light_mode;
-int freq_max;
-float freq_max_f, rainbow_steps;
-int freq_f[32];
-int this_color;
-boolean running_flag[3], eeprom_flag;
-
-#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
-#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
-// ------------------------------ ДЛЯ РАЗРАБОТЧИКОВ --------------------------------
-
-void setup() {
- Serial.begin(9600);
- FastLED.addLeds(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
- FastLED.setBrightness(BRIGHTNESS);
-
- #if defined(__AVR_ATmega32U4__) //Выключение светодиодов на Pro Micro
- TXLED1; //на ProMicro выключим и TXLED
- delay (1000); //При питании по usb от компьютера нужна задержка перед выключением RXLED. Если питать от БП, то можно убрать эту строку.
- #endif
- pinMode(MLED_PIN, OUTPUT); //Режим пина для светодиода режима на выход
- digitalWrite(MLED_PIN, !MLED_ON); //Выключение светодиода режима
-
- pinMode(POT_GND, OUTPUT);
- digitalWrite(POT_GND, LOW);
- butt1.setTimeout(900);
-
- IRLremote.begin(IR_PIN);
-
- // для увеличения точности уменьшаем опорное напряжение,
- // выставив EXTERNAL и подключив Aref к выходу 3.3V на плате через делитель
- // GND ---[10-20 кОм] --- REF --- [10 кОм] --- 3V3
- // в данной схеме GND берётся из А0 для удобства подключения
- if (POTENT) analogReference(EXTERNAL);
- else
-#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
- analogReference(INTERNAL1V1);
-#else
- analogReference(INTERNAL);
-#endif
-
- // жуткая магия, меняем частоту оцифровки до 18 кГц
- // команды на ебучем ассемблере, даже не спрашивайте, как это работает
- // поднимаем частоту опроса аналогового порта до 38.4 кГц, по теореме
- // Котельникова (Найквиста) частота дискретизации будет 19.2 кГц
- // http://yaab-arduino.blogspot.ru/2015/02/fast-sampling-from-analog-input.html
- sbi(ADCSRA, ADPS2);
- cbi(ADCSRA, ADPS1);
- sbi(ADCSRA, ADPS0);
-
- if (RESET_SETTINGS) EEPROM.write(100, 0); // сброс флага настроек
-
- if (AUTO_LOW_PASS && !EEPROM_LOW_PASS) { // если разрешена автонастройка нижнего порога шумов
- autoLowPass();
- }
- if (EEPROM_LOW_PASS) { // восстановить значения шумов из памяти
- LOW_PASS = EEPROM.readInt(70);
- SPEKTR_LOW_PASS = EEPROM.readInt(72);
- }
-
- // в 100 ячейке хранится число 100. Если нет - значит это первый запуск системы
- if (KEEP_SETTINGS) {
- if (EEPROM.read(100) != 100) {
- //Serial.println(F("First start"));
- EEPROM.write(100, 100);
- updateEEPROM();
- } else {
- readEEPROM();
- }
- }
-}
-
-void loop() {
- buttonTick(); // опрос и обработка кнопки
-#if IR_RCT != 0
- remoteTick(); // опрос ИК пульта
-#endif
- mainLoop(); // главный цикл обработки и отрисовки
- eepromTick(); // проверка не пора ли сохранить настройки
-}
-
-void mainLoop() {
- // главный цикл отрисовки
- if (ONstate) {
- if (millis() - main_timer > MAIN_LOOP) {
- // сбрасываем значения
- RsoundLevel = 0;
- LsoundLevel = 0;
-
- // перваые два режима - громкость (VU meter)
- if (this_mode == 0 || this_mode == 1) {
- for (byte i = 0; i < 100; i ++) { // делаем 100 измерений
- RcurrentLevel = analogRead(SOUND_R); // с правого
- if (!MONO) LcurrentLevel = analogRead(SOUND_L); // и левого каналов
-
- if (RsoundLevel < RcurrentLevel) RsoundLevel = RcurrentLevel; // ищем максимальное
- if (!MONO) if (LsoundLevel < LcurrentLevel) LsoundLevel = LcurrentLevel; // ищем максимальное
- }
-
- // фильтруем по нижнему порогу шумов
- RsoundLevel = map(RsoundLevel, LOW_PASS, 1023, 0, 500);
- if (!MONO)LsoundLevel = map(LsoundLevel, LOW_PASS, 1023, 0, 500);
-
- // ограничиваем диапазон
- RsoundLevel = constrain(RsoundLevel, 0, 500);
- if (!MONO)LsoundLevel = constrain(LsoundLevel, 0, 500);
-
- // возводим в степень (для большей чёткости работы)
- RsoundLevel = pow(RsoundLevel, EXP);
- if (!MONO)LsoundLevel = pow(LsoundLevel, EXP);
-
- // фильтр
- RsoundLevel_f = RsoundLevel * SMOOTH + RsoundLevel_f * (1 - SMOOTH);
- if (!MONO)LsoundLevel_f = LsoundLevel * SMOOTH + LsoundLevel_f * (1 - SMOOTH);
-
- if (MONO) LsoundLevel_f = RsoundLevel_f; // если моно, то левый = правому
-
- // заливаем "подложку", если яркость достаточная
- if (EMPTY_BRIGHT > 5) {
- for (int i = 0; i < NUM_LEDS; i++)
- leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- }
-
- // если значение выше порога - начинаем самое интересное
- if (RsoundLevel_f > 15 && LsoundLevel_f > 15) {
-
- // расчёт общей средней громкости с обоих каналов, фильтрация.
- // Фильтр очень медленный, сделано специально для автогромкости
- averageLevel = (float)(RsoundLevel_f + LsoundLevel_f) / 2 * averK + averageLevel * (1 - averK);
-
- // принимаем максимальную громкость шкалы как среднюю, умноженную на некоторый коэффициент MAX_COEF
- maxLevel = (float)averageLevel * MAX_COEF;
-
- // преобразуем сигнал в длину ленты (где MAX_CH это половина количества светодиодов)
- Rlenght = map(RsoundLevel_f, 0, maxLevel, 0, MAX_CH);
- Llenght = map(LsoundLevel_f, 0, maxLevel, 0, MAX_CH);
-
- // ограничиваем до макс. числа светодиодов
- Rlenght = constrain(Rlenght, 0, MAX_CH);
- Llenght = constrain(Llenght, 0, MAX_CH);
-
- animation(); // отрисовать
- }
- }
-
- // 3-5 режим - цветомузыка
- if (this_mode == 2 || this_mode == 3 || this_mode == 4 || this_mode == 7 || this_mode == 8) {
- analyzeAudio();
- colorMusic[0] = 0;
- colorMusic[1] = 0;
- colorMusic[2] = 0;
- for (int i = 0 ; i < 32 ; i++) {
- if (fht_log_out[i] < SPEKTR_LOW_PASS) fht_log_out[i] = 0;
- }
- // низкие частоты, выборка со 2 по 5 тон (0 и 1 зашумленные!)
- for (byte i = 2; i < 6; i++) {
- if (fht_log_out[i] > colorMusic[0]) colorMusic[0] = fht_log_out[i];
- }
- // средние частоты, выборка с 6 по 10 тон
- for (byte i = 6; i < 11; i++) {
- if (fht_log_out[i] > colorMusic[1]) colorMusic[1] = fht_log_out[i];
- }
- // высокие частоты, выборка с 11 по 31 тон
- for (byte i = 11; i < 32; i++) {
- if (fht_log_out[i] > colorMusic[2]) colorMusic[2] = fht_log_out[i];
- }
- freq_max = 0;
- for (byte i = 0; i < 30; i++) {
- if (fht_log_out[i + 2] > freq_max) freq_max = fht_log_out[i + 2];
- if (freq_max < 5) freq_max = 5;
-
- if (freq_f[i] < fht_log_out[i + 2]) freq_f[i] = fht_log_out[i + 2];
- if (freq_f[i] > 0) freq_f[i] -= LIGHT_SMOOTH;
- else freq_f[i] = 0;
- }
- freq_max_f = freq_max * averK + freq_max_f * (1 - averK);
- for (byte i = 0; i < 3; i++) {
- colorMusic_aver[i] = colorMusic[i] * averK + colorMusic_aver[i] * (1 - averK); // общая фильтрация
- colorMusic_f[i] = colorMusic[i] * SMOOTH_FREQ + colorMusic_f[i] * (1 - SMOOTH_FREQ); // локальная
- if (colorMusic_f[i] > ((float)colorMusic_aver[i] * MAX_COEF_FREQ)) {
- thisBright[i] = 255;
- colorMusicFlash[i] = true;
- running_flag[i] = true;
- } else colorMusicFlash[i] = false;
- if (thisBright[i] >= 0) thisBright[i] -= SMOOTH_STEP;
- if (thisBright[i] < EMPTY_BRIGHT) {
- thisBright[i] = EMPTY_BRIGHT;
- running_flag[i] = false;
- }
- }
- animation();
- }
- if (this_mode == 5) {
- if ((long)millis() - strobe_timer > STROBE_PERIOD) {
- strobe_timer = millis();
- strobeUp_flag = true;
- strobeDwn_flag = false;
- }
- if ((long)millis() - strobe_timer > light_time) {
- strobeDwn_flag = true;
- }
- if (strobeUp_flag) { // если настало время пыхнуть
- if (strobe_bright < 255) // если яркость не максимальная
- strobe_bright += STROBE_SMOOTH; // увелчить
- if (strobe_bright > 255) { // если пробили макс. яркость
- strobe_bright = 255; // оставить максимум
- strobeUp_flag = false; // флаг опустить
- }
- }
-
- if (strobeDwn_flag) { // гаснем
- if (strobe_bright > 0) // если яркость не минимальная
- strobe_bright -= STROBE_SMOOTH; // уменьшить
- if (strobe_bright < 0) { // если пробили мин. яркость
- strobeDwn_flag = false;
- strobe_bright = 0; // оставить 0
- }
- }
- animation();
- }
- if (this_mode == 6) animation();
-
- if (!IRLremote.receiving()) // если на ИК приёмник не приходит сигнал (без этого НЕ РАБОТАЕТ!)
- FastLED.show(); // отправить значения на ленту
-
- if (this_mode != 7) // 7 режиму не нужна очистка!!!
- FastLED.clear(); // очистить массив пикселей
- main_timer = millis(); // сбросить таймер
- }
- }
-}
-
-void animation() {
- // согласно режиму
- switch (this_mode) {
- case 0:
- count = 0;
- for (int i = (MAX_CH - 1); i > ((MAX_CH - 1) - Rlenght); i--) {
- leds[i] = ColorFromPalette(myPal, (count * index)); // заливка по палитре " от зелёного к красному"
- count++;
- }
- count = 0;
- for (int i = (MAX_CH); i < (MAX_CH + Llenght); i++ ) {
- leds[i] = ColorFromPalette(myPal, (count * index)); // заливка по палитре " от зелёного к красному"
- count++;
- }
- if (EMPTY_BRIGHT > 0) {
- CHSV this_dark = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- for (int i = ((MAX_CH - 1) - Rlenght); i > 0; i--)
- leds[i] = this_dark;
- for (int i = MAX_CH + Llenght; i < NUM_LEDS; i++)
- leds[i] = this_dark;
- }
- break;
- case 1:
- if (millis() - rainbow_timer > 30) {
- rainbow_timer = millis();
- hue = floor((float)hue + RAINBOW_STEP);
- }
- count = 0;
- for (int i = (MAX_CH - 1); i > ((MAX_CH - 1) - Rlenght); i--) {
- leds[i] = ColorFromPalette(RainbowColors_p, (count * index) / 2 - hue); // заливка по палитре радуга
- count++;
- }
- count = 0;
- for (int i = (MAX_CH); i < (MAX_CH + Llenght); i++ ) {
- leds[i] = ColorFromPalette(RainbowColors_p, (count * index) / 2 - hue); // заливка по палитре радуга
- count++;
- }
- if (EMPTY_BRIGHT > 0) {
- CHSV this_dark = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- for (int i = ((MAX_CH - 1) - Rlenght); i > 0; i--)
- leds[i] = this_dark;
- for (int i = MAX_CH + Llenght; i < NUM_LEDS; i++)
- leds[i] = this_dark;
- }
- break;
- case 2:
- for (int i = 0; i < NUM_LEDS; i++) {
- if (i < STRIPE) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (i < STRIPE * 2) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < STRIPE * 3) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else if (i < STRIPE * 4) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < STRIPE * 5) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- }
- break;
- case 3:
- for (int i = 0; i < NUM_LEDS; i++) {
- if (i < NUM_LEDS / 3) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (i < NUM_LEDS * 2 / 3) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < NUM_LEDS) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
- }
- break;
- case 4:
- switch (freq_strobe_mode) {
- case 0:
- if (colorMusicFlash[2]) HIGHS();
- else if (colorMusicFlash[1]) MIDS();
- else if (colorMusicFlash[0]) LOWS();
- else SILENCE();
- break;
- case 1:
- if (colorMusicFlash[2]) HIGHS();
- else SILENCE();
- break;
- case 2:
- if (colorMusicFlash[1]) MIDS();
- else SILENCE();
- break;
- case 3:
- if (colorMusicFlash[0]) LOWS();
- else SILENCE();
- break;
- }
- break;
- case 5:
- if (strobe_bright > 0)
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(STROBE_COLOR, STROBE_SAT, strobe_bright);
- else
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 6:
- switch (light_mode) {
- case 0: for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(LIGHT_COLOR, LIGHT_SAT, 255);
- break;
- case 1:
- if (millis() - color_timer > COLOR_SPEED) {
- color_timer = millis();
- if (++this_color > 255) this_color = 0;
- }
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(this_color, LIGHT_SAT, 255);
- break;
- case 2:
- if (millis() - rainbow_timer > 30) {
- rainbow_timer = millis();
- this_color += RAINBOW_PERIOD;
- if (this_color > 255) this_color = 0;
- if (this_color < 0) this_color = 255;
- }
- rainbow_steps = this_color;
- for (int i = 0; i < NUM_LEDS; i++) {
- leds[i] = CHSV((int)floor(rainbow_steps), 255, 255);
- rainbow_steps += RAINBOW_STEP_2;
- if (rainbow_steps > 255) rainbow_steps = 0;
- if (rainbow_steps < 0) rainbow_steps = 255;
- }
- break;
- }
- break;
- case 7:
- switch (freq_strobe_mode) {
- case 0:
- if (running_flag[2]) leds[NUM_LEDS / 2] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (running_flag[1]) leds[NUM_LEDS / 2] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (running_flag[0]) leds[NUM_LEDS / 2] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 1:
- if (running_flag[2]) leds[NUM_LEDS / 2] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 2:
- if (running_flag[1]) leds[NUM_LEDS / 2] = CHSV(MID_COLOR, 255, thisBright[1]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 3:
- if (running_flag[0]) leds[NUM_LEDS / 2] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- }
- leds[(NUM_LEDS / 2) - 1] = leds[NUM_LEDS / 2];
- if (millis() - running_timer > RUNNING_SPEED) {
- running_timer = millis();
- for (byte i = 0; i < NUM_LEDS / 2 - 1; i++) {
- leds[i] = leds[i + 1];
- leds[NUM_LEDS - i - 1] = leds[i];
- }
- }
- break;
- case 8:
- byte HUEindex = HUE_START;
- for (byte i = 0; i < NUM_LEDS / 2; i++) {
- byte this_bright = map(freq_f[(int)floor((NUM_LEDS / 2 - i) / freq_to_stripe)], 0, freq_max_f, 0, 255);
- this_bright = constrain(this_bright, 0, 255);
- leds[i] = CHSV(HUEindex, 255, this_bright);
- leds[NUM_LEDS - i - 1] = leds[i];
- HUEindex += HUE_STEP;
- if (HUEindex > 255) HUEindex = 0;
- }
- break;
- }
-}
-
-void HIGHS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
-}
-void MIDS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
-}
-void LOWS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
-}
-void SILENCE() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
-}
-
-// вспомогательная функция, изменяет величину value на шаг incr в пределах minimum.. maximum
-int smartIncr(int value, int incr_step, int mininmum, int maximum) {
- int val_buf = value + incr_step;
- val_buf = constrain(val_buf, mininmum, maximum);
- return val_buf;
-}
-
-float smartIncrFloat(float value, float incr_step, float mininmum, float maximum) {
- float val_buf = value + incr_step;
- val_buf = constrain(val_buf, mininmum, maximum);
- return val_buf;
-}
-
-#if IR_RCT != 0
-void remoteTick() {
- if (IRLremote.available()) {
- auto data = IRLremote.read();
- IRdata = data.command;
- ir_flag = true;
- }
- if (ir_flag) { // если данные пришли
- eeprom_timer = millis();
- eeprom_flag = true;
- switch (IRdata) {
- // режимы
- case BUTT_1: this_mode = 0;
- break;
- case BUTT_2: this_mode = 1;
- break;
- case BUTT_3: this_mode = 2;
- break;
- case BUTT_4: this_mode = 3;
- break;
- case BUTT_5: this_mode = 4;
- break;
- case BUTT_6: this_mode = 5;
- break;
- case BUTT_7: this_mode = 6;
- break;
- case BUTT_8: this_mode = 7;
- break;
- case BUTT_9: this_mode = 8;
- break;
- case BUTT_0: fullLowPass();
- break;
- case BUTT_STAR: ONstate = !ONstate; FastLED.clear(); FastLED.show(); updateEEPROM();
- break;
- case BUTT_HASH:
- switch (this_mode) {
- case 4:
- case 7: if (++freq_strobe_mode > 3) freq_strobe_mode = 0;
- break;
- case 6: if (++light_mode > 2) light_mode = 0;
- break;
- }
- break;
- case BUTT_OK: digitalWrite(MLED_PIN, settings_mode ^ MLED_ON); settings_mode = !settings_mode;
- break;
- case BUTT_UP:
- if (settings_mode) {
- // ВВЕРХ общие настройки
- EMPTY_BRIGHT = smartIncr(EMPTY_BRIGHT, 5, 0, 255);
- } else {
- switch (this_mode) {
- case 0:
- break;
- case 1: RAINBOW_STEP = smartIncrFloat(RAINBOW_STEP, 0.5, 0.5, 20);
- break;
- case 2:
- case 3:
- case 4: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, 0.1, 0, 5);
- break;
- case 5: STROBE_PERIOD = smartIncr(STROBE_PERIOD, 20, 1, 1000);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_SAT = smartIncr(LIGHT_SAT, 20, 0, 255);
- break;
- case 1: LIGHT_SAT = smartIncr(LIGHT_SAT, 20, 0, 255);
- break;
- case 2: RAINBOW_STEP_2 = smartIncrFloat(RAINBOW_STEP_2, 0.5, 0.5, 10);
- break;
- }
- break;
- case 7: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, 0.1, 0.0, 10);
- break;
- case 8: HUE_START = smartIncr(HUE_START, 10, 0, 255);
- break;
- }
- }
- break;
- case BUTT_DOWN:
- if (settings_mode) {
- // ВНИЗ общие настройки
- EMPTY_BRIGHT = smartIncr(EMPTY_BRIGHT, -5, 0, 255);
- } else {
- switch (this_mode) {
- case 0:
- break;
- case 1: RAINBOW_STEP = smartIncrFloat(RAINBOW_STEP, -0.5, 0.5, 20);
- break;
- case 2:
- case 3:
- case 4: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, -0.1, 0, 5);
- break;
- case 5: STROBE_PERIOD = smartIncr(STROBE_PERIOD, -20, 1, 1000);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_SAT = smartIncr(LIGHT_SAT, -20, 0, 255);
- break;
- case 1: LIGHT_SAT = smartIncr(LIGHT_SAT, -20, 0, 255);
- break;
- case 2: RAINBOW_STEP_2 = smartIncrFloat(RAINBOW_STEP_2, -0.5, 0.5, 10);
- break;
- }
- break;
- case 7: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, -0.1, 0.0, 10);
- break;
- case 8: HUE_START = smartIncr(HUE_START, -10, 0, 255);
- break;
- }
- }
- break;
- case BUTT_LEFT:
- if (settings_mode) {
- // ВЛЕВО общие настройки
- BRIGHTNESS = smartIncr(BRIGHTNESS, -20, 0, 255);
- FastLED.setBrightness(BRIGHTNESS);
- } else {
- switch (this_mode) {
- case 0:
- case 1: SMOOTH = smartIncrFloat(SMOOTH, -0.05, 0.05, 1);
- break;
- case 2:
- case 3:
- case 4: SMOOTH_FREQ = smartIncrFloat(SMOOTH_FREQ, -0.05, 0.05, 1);
- break;
- case 5: STROBE_SMOOTH = smartIncr(STROBE_SMOOTH, -20, 0, 255);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_COLOR = smartIncr(LIGHT_COLOR, -10, 0, 255);
- break;
- case 1: COLOR_SPEED = smartIncr(COLOR_SPEED, -10, 0, 255);
- break;
- case 2: RAINBOW_PERIOD = smartIncr(RAINBOW_PERIOD, -1, -20, 20);
- break;
- }
- break;
- case 7: RUNNING_SPEED = smartIncr(RUNNING_SPEED, -10, 1, 255);
- break;
- case 8: HUE_STEP = smartIncr(HUE_STEP, -1, 1, 255);
- break;
- }
- }
- break;
- case BUTT_RIGHT:
- if (settings_mode) {
- // ВПРАВО общие настройки
- BRIGHTNESS = smartIncr(BRIGHTNESS, 20, 0, 255);
- FastLED.setBrightness(BRIGHTNESS);
- } else {
- switch (this_mode) {
- case 0:
- case 1: SMOOTH = smartIncrFloat(SMOOTH, 0.05, 0.05, 1);
- break;
- case 2:
- case 3:
- case 4: SMOOTH_FREQ = smartIncrFloat(SMOOTH_FREQ, 0.05, 0.05, 1);
- break;
- case 5: STROBE_SMOOTH = smartIncr(STROBE_SMOOTH, 20, 0, 255);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_COLOR = smartIncr(LIGHT_COLOR, 10, 0, 255);
- break;
- case 1: COLOR_SPEED = smartIncr(COLOR_SPEED, 10, 0, 255);
- break;
- case 2: RAINBOW_PERIOD = smartIncr(RAINBOW_PERIOD, 1, -20, 20);
- break;
- }
- break;
- case 7: RUNNING_SPEED = smartIncr(RUNNING_SPEED, 10, 1, 255);
- break;
- case 8: HUE_STEP = smartIncr(HUE_STEP, 1, 1, 255);
- break;
- }
- }
- break;
- default: eeprom_flag = false; // если не распознали кнопку, не обновляем настройки!
- break;
- }
- ir_flag = false;
- }
-}
-#endif
-
-void autoLowPass() {
- // для режима VU
- delay(10); // ждём инициализации АЦП
- int thisMax = 0; // максимум
- int thisLevel;
- for (byte i = 0; i < 200; i++) {
- thisLevel = analogRead(SOUND_R); // делаем 200 измерений
- if (thisLevel > thisMax) // ищем максимумы
- thisMax = thisLevel; // запоминаем
- delay(4); // ждём 4мс
- }
- LOW_PASS = thisMax + LOW_PASS_ADD; // нижний порог как максимум тишины + некая величина
-
- // для режима спектра
- thisMax = 0;
- for (byte i = 0; i < 100; i++) { // делаем 100 измерений
- analyzeAudio(); // разбить в спектр
- for (byte j = 2; j < 32; j++) { // первые 2 канала - хлам
- thisLevel = fht_log_out[j];
- if (thisLevel > thisMax) // ищем максимумы
- thisMax = thisLevel; // запоминаем
- }
- delay(4); // ждём 4мс
- }
- SPEKTR_LOW_PASS = thisMax + LOW_PASS_FREQ_ADD; // нижний порог как максимум тишины
- if (EEPROM_LOW_PASS && !AUTO_LOW_PASS) {
- EEPROM.updateInt(70, LOW_PASS);
- EEPROM.updateInt(72, SPEKTR_LOW_PASS);
- }
-}
-
-void analyzeAudio() {
- for (int i = 0 ; i < FHT_N ; i++) {
- int sample = analogRead(SOUND_R_FREQ);
- fht_input[i] = sample; // put real data into bins
- }
- fht_window(); // window the data for better frequency response
- fht_reorder(); // reorder the data before doing the fht
- fht_run(); // process the data in the fht
- fht_mag_log(); // take the output of the fht
-}
-
-void buttonTick() {
- butt1.tick(); // обязательная функция отработки. Должна постоянно опрашиваться
- if (butt1.isSingle()) // если единичное нажатие
- if (++this_mode >= MODE_AMOUNT) this_mode = 0; // изменить режим
-
- if (butt1.isHolded()) { // кнопка удержана
- fullLowPass();
- }
-}
-void fullLowPass() {
- digitalWrite(MLED_PIN, MLED_ON); // включить светодиод
- FastLED.setBrightness(0); // погасить ленту
- FastLED.clear(); // очистить массив пикселей
- FastLED.show(); // отправить значения на ленту
- delay(500); // подождать чутка
- autoLowPass(); // измерить шумы
- delay(500); // подождать
- FastLED.setBrightness(BRIGHTNESS); // вернуть яркость
- digitalWrite(MLED_PIN, !MLED_ON); // выключить светодиод
-}
-void updateEEPROM() {
- EEPROM.updateByte(1, this_mode);
- EEPROM.updateByte(2, freq_strobe_mode);
- EEPROM.updateByte(3, light_mode);
- EEPROM.updateInt(4, RAINBOW_STEP);
- EEPROM.updateFloat(8, MAX_COEF_FREQ);
- EEPROM.updateInt(12, STROBE_PERIOD);
- EEPROM.updateInt(16, LIGHT_SAT);
- EEPROM.updateFloat(20, RAINBOW_STEP_2);
- EEPROM.updateInt(24, HUE_START);
- EEPROM.updateFloat(28, SMOOTH);
- EEPROM.updateFloat(32, SMOOTH_FREQ);
- EEPROM.updateInt(36, STROBE_SMOOTH);
- EEPROM.updateInt(40, LIGHT_COLOR);
- EEPROM.updateInt(44, COLOR_SPEED);
- EEPROM.updateInt(48, RAINBOW_PERIOD);
- EEPROM.updateInt(52, RUNNING_SPEED);
- EEPROM.updateInt(56, HUE_STEP);
- EEPROM.updateInt(60, EMPTY_BRIGHT);
- if (KEEP_STATE) EEPROM.updateByte(64, ONstate);
-}
-void readEEPROM() {
- this_mode = EEPROM.readByte(1);
- freq_strobe_mode = EEPROM.readByte(2);
- light_mode = EEPROM.readByte(3);
- RAINBOW_STEP = EEPROM.readInt(4);
- MAX_COEF_FREQ = EEPROM.readFloat(8);
- STROBE_PERIOD = EEPROM.readInt(12);
- LIGHT_SAT = EEPROM.readInt(16);
- RAINBOW_STEP_2 = EEPROM.readFloat(20);
- HUE_START = EEPROM.readInt(24);
- SMOOTH = EEPROM.readFloat(28);
- SMOOTH_FREQ = EEPROM.readFloat(32);
- STROBE_SMOOTH = EEPROM.readInt(36);
- LIGHT_COLOR = EEPROM.readInt(40);
- COLOR_SPEED = EEPROM.readInt(44);
- RAINBOW_PERIOD = EEPROM.readInt(48);
- RUNNING_SPEED = EEPROM.readInt(52);
- HUE_STEP = EEPROM.readInt(56);
- EMPTY_BRIGHT = EEPROM.readInt(60);
- if (KEEP_STATE) ONstate = EEPROM.readByte(64);
-}
-void eepromTick() {
- if (eeprom_flag)
- if (millis() - eeprom_timer > 30000) { // 30 секунд после последнего нажатия с пульта
- eeprom_flag = false;
- eeprom_timer = millis();
- updateEEPROM();
- }
-}
diff --git a/firmware/Old versions/colorMusic_v2.8/colorMusic_v2.8.ino b/firmware/Old versions/colorMusic_v2.8/colorMusic_v2.8.ino
deleted file mode 100644
index 3d36637..0000000
--- a/firmware/Old versions/colorMusic_v2.8/colorMusic_v2.8.ino
+++ /dev/null
@@ -1,953 +0,0 @@
-/*
- Скетч к проекту "Светомузыка на Arduino"
- Версия 2.8
- Страница проекта (схемы, описания): https://alexgyver.ru/colormusic/
- Исходники на GitHub: https://github.com/AlexGyver/ColorMusic
- Нравится, как написан код? Поддержи автора! https://alexgyver.ru/support_alex/
- Автор: AlexGyver Technologies, 2018
- https://AlexGyver.ru/
-
- Как откалибровать уровень шума и как пользоваться пультом
- расписано на странице проекта! https://alexgyver.ru/colormusic/
-*/
-
-// ***************************** НАСТРОЙКИ *****************************
-
-// ----- настройка ИК пульта
-#define REMOTE_TYPE 1 // 0 - без пульта, 1 - пульт от WAVGAT, 2 - пульт от KEYES, 3 - кастомный пульт
-// система может работать С ЛЮБЫМ ИК ПУЛЬТОМ (практически). Коды для своего пульта можно задать начиная со строки 160 в прошивке. Коды пультов определяются скетчем IRtest_2.0, читай инструкцию
-
-// ----- настройки параметров
-#define KEEP_SETTINGS 1 // хранить ВСЕ настройки в энергонезависимой памяти
-#define KEEP_STATE 1 // сохранять в памяти состояние вкл/выкл системы (с пульта)
-#define RESET_SETTINGS 0 // сброс настроек в EEPROM памяти (поставить 1, прошиться, поставить обратно 0, прошиться. Всё)
-
-// ----- настройки ленты
-#define NUM_LEDS 60 // количество светодиодов (данная версия поддерживает до 410 штук)
-#define CURRENT_LIMIT 3000 // лимит по току в МИЛЛИАМПЕРАХ, автоматически управляет яркостью (пожалей свой блок питания!) 0 - выключить лимит
-byte BRIGHTNESS = 200; // яркость по умолчанию (0 - 255)
-
-// ----- пины подключения
-#define SOUND_R A2 // аналоговый пин вход аудио, правый канал
-#define SOUND_L A1 // аналоговый пин вход аудио, левый канал
-#define SOUND_R_FREQ A3 // аналоговый пин вход аудио для режима с частотами (через кондер)
-#define BTN_PIN 3 // кнопка переключения режимов (PIN --- КНОПКА --- GND)
-
-#if defined(__AVR_ATmega32U4__) // Пины для Arduino Pro Micro (смотри схему для Pro Micro на странице проекта!!!)
-#define MLED_PIN 17 // пин светодиода режимов на ProMicro, т.к. обычный не выведен.
-#define MLED_ON LOW
-#define LED_PIN 9 // пин DI светодиодной ленты на ProMicro, т.к. обычный не выведен.
-#else // Пины для других плат Arduino (по умолчанию)
-#define MLED_PIN 13 // пин светодиода режимов
-#define MLED_ON HIGH
-#define LED_PIN 12 // пин DI светодиодной ленты
-#endif
-
-#define POT_GND A0 // пин земля для потенциометра
-#define IR_PIN 2 // пин ИК приёмника
-
-// ----- настройки радуги
-float RAINBOW_STEP = 5.5; // шаг изменения цвета радуги
-
-// ----- отрисовка
-#define MODE 0 // режим при запуске
-#define MAIN_LOOP 5 // период основного цикла отрисовки (по умолчанию 5)
-
-// ----- сигнал
-#define MONO 1 // 1 - только один канал (ПРАВЫЙ!!!!! SOUND_R!!!!!), 0 - два канала
-#define EXP 1.4 // степень усиления сигнала (для более "резкой" работы) (по умолчанию 1.4)
-#define POTENT 0 // 1 - используем потенциометр, 0 - используется внутренний источник опорного напряжения 1.1 В
-byte EMPTY_BRIGHT = 30; // яркость "не горящих" светодиодов (0 - 255)
-#define EMPTY_COLOR HUE_PURPLE // цвет "не горящих" светодиодов. Будет чёрный, если яркость 0
-
-// ----- нижний порог шумов
-uint16_t LOW_PASS = 100; // нижний порог шумов режим VU, ручная настройка
-uint16_t SPEKTR_LOW_PASS = 40; // нижний порог шумов режим спектра, ручная настройка
-#define AUTO_LOW_PASS 0 // разрешить настройку нижнего порога шумов при запуске (по умолч. 0)
-#define EEPROM_LOW_PASS 1 // порог шумов хранится в энергонезависимой памяти (по умолч. 1)
-#define LOW_PASS_ADD 13 // "добавочная" величина к нижнему порогу, для надёжности (режим VU)
-#define LOW_PASS_FREQ_ADD 3 // "добавочная" величина к нижнему порогу, для надёжности (режим частот)
-
-// ----- режим шкала громкости
-float SMOOTH = 0.5; // коэффициент плавности анимации VU (по умолчанию 0.5)
-#define MAX_COEF 1.8 // коэффициент громкости (максимальное равно срднему * этот коэф) (по умолчанию 1.8)
-
-// ----- режим цветомузыки
-float SMOOTH_FREQ = 0.8; // коэффициент плавности анимации частот (по умолчанию 0.8)
-float MAX_COEF_FREQ = 1.2; // коэффициент порога для "вспышки" цветомузыки (по умолчанию 1.5)
-#define SMOOTH_STEP 20 // шаг уменьшения яркости в режиме цветомузыки (чем больше, тем быстрее гаснет)
-#define LOW_COLOR HUE_RED // цвет низких частот
-#define MID_COLOR HUE_GREEN // цвет средних
-#define HIGH_COLOR HUE_YELLOW // цвет высоких
-
-// ----- режим стробоскопа
-uint16_t STROBE_PERIOD = 100; // период вспышек, миллисекунды
-#define STROBE_DUTY 20 // скважность вспышек (1 - 99) - отношение времени вспышки ко времени темноты
-#define STROBE_COLOR HUE_YELLOW // цвет стробоскопа
-#define STROBE_SAT 0 // насыщенность. Если 0 - цвет будет БЕЛЫЙ при любом цвете (0 - 255)
-byte STROBE_SMOOTH = 100; // скорость нарастания/угасания вспышки (0 - 255)
-
-// ----- режим подсветки
-byte LIGHT_COLOR = 0; // начальный цвет подсветки
-byte LIGHT_SAT = 200; // начальная насыщенность подсветки
-byte COLOR_SPEED = 100;
-int RAINBOW_PERIOD = 3;
-float RAINBOW_STEP_2 = 5.5;
-
-// ----- режим бегущих частот
-byte RUNNING_SPEED = 60;
-
-// ----- режим анализатора спектра
-byte HUE_START = 0;
-byte HUE_STEP = 5;
-#define LIGHT_SMOOTH 2
-
-/*
- Цвета для HSV
- HUE_RED
- HUE_ORANGE
- HUE_YELLOW
- HUE_GREEN
- HUE_AQUA
- HUE_BLUE
- HUE_PURPLE
- HUE_PINK
-*/
-
-// ----- КНОПКИ ПУЛЬТА WAVGAT -----
-#if REMOTE_TYPE == 1
-#define BUTT_UP 0xF39EEBAD
-#define BUTT_DOWN 0xC089F6AD
-#define BUTT_LEFT 0xE25410AD
-#define BUTT_RIGHT 0x14CE54AD
-#define BUTT_OK 0x297C76AD
-#define BUTT_1 0x4E5BA3AD
-#define BUTT_2 0xE51CA6AD
-#define BUTT_3 0xE207E1AD
-#define BUTT_4 0x517068AD
-#define BUTT_5 0x1B92DDAD
-#define BUTT_6 0xAC2A56AD
-#define BUTT_7 0x5484B6AD
-#define BUTT_8 0xD22353AD
-#define BUTT_9 0xDF3F4BAD
-#define BUTT_0 0xF08A26AD
-#define BUTT_STAR 0x68E456AD
-#define BUTT_HASH 0x151CD6AD
-#endif
-
-// ----- КНОПКИ ПУЛЬТА KEYES -----
-#if REMOTE_TYPE == 2
-#define BUTT_UP 0xE51CA6AD
-#define BUTT_DOWN 0xD22353AD
-#define BUTT_LEFT 0x517068AD
-#define BUTT_RIGHT 0xAC2A56AD
-#define BUTT_OK 0x1B92DDAD
-#define BUTT_1 0x68E456AD
-#define BUTT_2 0xF08A26AD
-#define BUTT_3 0x151CD6AD
-#define BUTT_4 0x18319BAD
-#define BUTT_5 0xF39EEBAD
-#define BUTT_6 0x4AABDFAD
-#define BUTT_7 0xE25410AD
-#define BUTT_8 0x297C76AD
-#define BUTT_9 0x14CE54AD
-#define BUTT_0 0xC089F6AD
-#define BUTT_STAR 0xAF3F1BAD
-#define BUTT_HASH 0x38379AD
-#endif
-
-// ----- КНОПКИ СВОЕГО ПУЛЬТА -----
-#if REMOTE_TYPE == 3
-#define BUTT_UP 0xE51CA6AD
-#define BUTT_DOWN 0xD22353AD
-#define BUTT_LEFT 0x517068AD
-#define BUTT_RIGHT 0xAC2A56AD
-#define BUTT_OK 0x1B92DDAD
-#define BUTT_1 0x68E456AD
-#define BUTT_2 0xF08A26AD
-#define BUTT_3 0x151CD6AD
-#define BUTT_4 0x18319BAD
-#define BUTT_5 0xF39EEBAD
-#define BUTT_6 0x4AABDFAD
-#define BUTT_7 0xE25410AD
-#define BUTT_8 0x297C76AD
-#define BUTT_9 0x14CE54AD
-#define BUTT_0 0xC089F6AD
-#define BUTT_STAR 0xAF3F1BAD // *
-#define BUTT_HASH 0x38379AD // #
-#endif
-
-
-// ------------------------------ ДЛЯ РАЗРАБОТЧИКОВ --------------------------------
-#define MODE_AMOUNT 9 // количество режимов
-
-#define STRIPE NUM_LEDS / 5
-float freq_to_stripe = NUM_LEDS / 40; // /2 так как симметрия, и /20 так как 20 частот
-
-#define FHT_N 64 // ширина спектра х2
-#define LOG_OUT 1
-#include // преобразование Хартли
-
-#include
-
-#define FASTLED_ALLOW_INTERRUPTS 1
-#include "FastLED.h"
-CRGB leds[NUM_LEDS];
-
-#include "GyverButton.h"
-GButton butt1(BTN_PIN);
-
-#include "IRLremote.h"
-CHashIR IRLremote;
-uint32_t IRdata;
-
-// градиент-палитра от зелёного к красному
-DEFINE_GRADIENT_PALETTE(soundlevel_gp) {
- 0, 0, 255, 0, // green
- 100, 255, 255, 0, // yellow
- 150, 255, 100, 0, // orange
- 200, 255, 50, 0, // red
- 255, 255, 0, 0 // red
-};
-CRGBPalette32 myPal = soundlevel_gp;
-
-byte Rlenght, Llenght;
-float RsoundLevel, RsoundLevel_f;
-float LsoundLevel, LsoundLevel_f;
-
-float averageLevel = 50;
-int maxLevel = 100;
-byte MAX_CH = NUM_LEDS / 2;
-int hue;
-unsigned long main_timer, hue_timer, strobe_timer, running_timer, color_timer, rainbow_timer, eeprom_timer;
-float averK = 0.006;
-byte count;
-float index = (float)255 / MAX_CH; // коэффициент перевода для палитры
-boolean lowFlag;
-byte low_pass;
-int RcurrentLevel, LcurrentLevel;
-int colorMusic[3];
-float colorMusic_f[3], colorMusic_aver[3];
-boolean colorMusicFlash[3], strobeUp_flag, strobeDwn_flag;
-byte this_mode = MODE;
-int thisBright[3], strobe_bright = 0;
-unsigned int light_time = STROBE_PERIOD * STROBE_DUTY / 100;
-volatile boolean ir_flag;
-boolean settings_mode, ONstate = true;
-int8_t freq_strobe_mode, light_mode;
-int freq_max;
-float freq_max_f, rainbow_steps;
-int freq_f[32];
-int this_color;
-boolean running_flag[3], eeprom_flag;
-
-#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
-#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
-// ------------------------------ ДЛЯ РАЗРАБОТЧИКОВ --------------------------------
-
-void setup() {
- Serial.begin(9600);
- FastLED.addLeds(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
- if (CURRENT_LIMIT > 0) FastLED.setMaxPowerInVoltsAndMilliamps(5, CURRENT_LIMIT);
- FastLED.setBrightness(BRIGHTNESS);
-
- #if defined(__AVR_ATmega32U4__) //Выключение светодиодов на Pro Micro
- TXLED1; //на ProMicro выключим и TXLED
- delay (1000); //При питании по usb от компьютера нужна задержка перед выключением RXLED. Если питать от БП, то можно убрать эту строку.
- #endif
- pinMode(MLED_PIN, OUTPUT); //Режим пина для светодиода режима на выход
- digitalWrite(MLED_PIN, !MLED_ON); //Выключение светодиода режима
-
- pinMode(POT_GND, OUTPUT);
- digitalWrite(POT_GND, LOW);
- butt1.setTimeout(900);
-
- IRLremote.begin(IR_PIN);
-
- // для увеличения точности уменьшаем опорное напряжение,
- // выставив EXTERNAL и подключив Aref к выходу 3.3V на плате через делитель
- // GND ---[10-20 кОм] --- REF --- [10 кОм] --- 3V3
- // в данной схеме GND берётся из А0 для удобства подключения
- if (POTENT) analogReference(EXTERNAL);
- else
-#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
- analogReference(INTERNAL1V1);
-#else
- analogReference(INTERNAL);
-#endif
-
- // жуткая магия, меняем частоту оцифровки до 18 кГц
- // команды на ебучем ассемблере, даже не спрашивайте, как это работает
- // поднимаем частоту опроса аналогового порта до 38.4 кГц, по теореме
- // Котельникова (Найквиста) частота дискретизации будет 19.2 кГц
- // http://yaab-arduino.blogspot.ru/2015/02/fast-sampling-from-analog-input.html
- sbi(ADCSRA, ADPS2);
- cbi(ADCSRA, ADPS1);
- sbi(ADCSRA, ADPS0);
-
- if (RESET_SETTINGS) EEPROM.write(100, 0); // сброс флага настроек
-
- if (AUTO_LOW_PASS && !EEPROM_LOW_PASS) { // если разрешена автонастройка нижнего порога шумов
- autoLowPass();
- }
- if (EEPROM_LOW_PASS) { // восстановить значения шумов из памяти
- LOW_PASS = EEPROM.readInt(70);
- SPEKTR_LOW_PASS = EEPROM.readInt(72);
- }
-
- // в 100 ячейке хранится число 100. Если нет - значит это первый запуск системы
- if (KEEP_SETTINGS) {
- if (EEPROM.read(100) != 100) {
- //Serial.println(F("First start"));
- EEPROM.write(100, 100);
- updateEEPROM();
- } else {
- readEEPROM();
- }
- }
-}
-
-void loop() {
- buttonTick(); // опрос и обработка кнопки
-#if REMOTE_TYPE != 0
- remoteTick(); // опрос ИК пульта
-#endif
- mainLoop(); // главный цикл обработки и отрисовки
- eepromTick(); // проверка не пора ли сохранить настройки
-}
-
-void mainLoop() {
- // главный цикл отрисовки
- if (ONstate) {
- if (millis() - main_timer > MAIN_LOOP) {
- // сбрасываем значения
- RsoundLevel = 0;
- LsoundLevel = 0;
-
- // перваые два режима - громкость (VU meter)
- if (this_mode == 0 || this_mode == 1) {
- for (byte i = 0; i < 100; i ++) { // делаем 100 измерений
- RcurrentLevel = analogRead(SOUND_R); // с правого
- if (!MONO) LcurrentLevel = analogRead(SOUND_L); // и левого каналов
-
- if (RsoundLevel < RcurrentLevel) RsoundLevel = RcurrentLevel; // ищем максимальное
- if (!MONO) if (LsoundLevel < LcurrentLevel) LsoundLevel = LcurrentLevel; // ищем максимальное
- }
-
- // фильтруем по нижнему порогу шумов
- RsoundLevel = map(RsoundLevel, LOW_PASS, 1023, 0, 500);
- if (!MONO)LsoundLevel = map(LsoundLevel, LOW_PASS, 1023, 0, 500);
-
- // ограничиваем диапазон
- RsoundLevel = constrain(RsoundLevel, 0, 500);
- if (!MONO)LsoundLevel = constrain(LsoundLevel, 0, 500);
-
- // возводим в степень (для большей чёткости работы)
- RsoundLevel = pow(RsoundLevel, EXP);
- if (!MONO)LsoundLevel = pow(LsoundLevel, EXP);
-
- // фильтр
- RsoundLevel_f = RsoundLevel * SMOOTH + RsoundLevel_f * (1 - SMOOTH);
- if (!MONO)LsoundLevel_f = LsoundLevel * SMOOTH + LsoundLevel_f * (1 - SMOOTH);
-
- if (MONO) LsoundLevel_f = RsoundLevel_f; // если моно, то левый = правому
-
- // заливаем "подложку", если яркость достаточная
- if (EMPTY_BRIGHT > 5) {
- for (int i = 0; i < NUM_LEDS; i++)
- leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- }
-
- // если значение выше порога - начинаем самое интересное
- if (RsoundLevel_f > 15 && LsoundLevel_f > 15) {
-
- // расчёт общей средней громкости с обоих каналов, фильтрация.
- // Фильтр очень медленный, сделано специально для автогромкости
- averageLevel = (float)(RsoundLevel_f + LsoundLevel_f) / 2 * averK + averageLevel * (1 - averK);
-
- // принимаем максимальную громкость шкалы как среднюю, умноженную на некоторый коэффициент MAX_COEF
- maxLevel = (float)averageLevel * MAX_COEF;
-
- // преобразуем сигнал в длину ленты (где MAX_CH это половина количества светодиодов)
- Rlenght = map(RsoundLevel_f, 0, maxLevel, 0, MAX_CH);
- Llenght = map(LsoundLevel_f, 0, maxLevel, 0, MAX_CH);
-
- // ограничиваем до макс. числа светодиодов
- Rlenght = constrain(Rlenght, 0, MAX_CH);
- Llenght = constrain(Llenght, 0, MAX_CH);
-
- animation(); // отрисовать
- }
- }
-
- // 3-5 режим - цветомузыка
- if (this_mode == 2 || this_mode == 3 || this_mode == 4 || this_mode == 7 || this_mode == 8) {
- analyzeAudio();
- colorMusic[0] = 0;
- colorMusic[1] = 0;
- colorMusic[2] = 0;
- for (int i = 0 ; i < 32 ; i++) {
- if (fht_log_out[i] < SPEKTR_LOW_PASS) fht_log_out[i] = 0;
- }
- // низкие частоты, выборка со 2 по 5 тон (0 и 1 зашумленные!)
- for (byte i = 2; i < 6; i++) {
- if (fht_log_out[i] > colorMusic[0]) colorMusic[0] = fht_log_out[i];
- }
- // средние частоты, выборка с 6 по 10 тон
- for (byte i = 6; i < 11; i++) {
- if (fht_log_out[i] > colorMusic[1]) colorMusic[1] = fht_log_out[i];
- }
- // высокие частоты, выборка с 11 по 31 тон
- for (byte i = 11; i < 32; i++) {
- if (fht_log_out[i] > colorMusic[2]) colorMusic[2] = fht_log_out[i];
- }
- freq_max = 0;
- for (byte i = 0; i < 30; i++) {
- if (fht_log_out[i + 2] > freq_max) freq_max = fht_log_out[i + 2];
- if (freq_max < 5) freq_max = 5;
-
- if (freq_f[i] < fht_log_out[i + 2]) freq_f[i] = fht_log_out[i + 2];
- if (freq_f[i] > 0) freq_f[i] -= LIGHT_SMOOTH;
- else freq_f[i] = 0;
- }
- freq_max_f = freq_max * averK + freq_max_f * (1 - averK);
- for (byte i = 0; i < 3; i++) {
- colorMusic_aver[i] = colorMusic[i] * averK + colorMusic_aver[i] * (1 - averK); // общая фильтрация
- colorMusic_f[i] = colorMusic[i] * SMOOTH_FREQ + colorMusic_f[i] * (1 - SMOOTH_FREQ); // локальная
- if (colorMusic_f[i] > ((float)colorMusic_aver[i] * MAX_COEF_FREQ)) {
- thisBright[i] = 255;
- colorMusicFlash[i] = true;
- running_flag[i] = true;
- } else colorMusicFlash[i] = false;
- if (thisBright[i] >= 0) thisBright[i] -= SMOOTH_STEP;
- if (thisBright[i] < EMPTY_BRIGHT) {
- thisBright[i] = EMPTY_BRIGHT;
- running_flag[i] = false;
- }
- }
- animation();
- }
- if (this_mode == 5) {
- if ((long)millis() - strobe_timer > STROBE_PERIOD) {
- strobe_timer = millis();
- strobeUp_flag = true;
- strobeDwn_flag = false;
- }
- if ((long)millis() - strobe_timer > light_time) {
- strobeDwn_flag = true;
- }
- if (strobeUp_flag) { // если настало время пыхнуть
- if (strobe_bright < 255) // если яркость не максимальная
- strobe_bright += STROBE_SMOOTH; // увелчить
- if (strobe_bright > 255) { // если пробили макс. яркость
- strobe_bright = 255; // оставить максимум
- strobeUp_flag = false; // флаг опустить
- }
- }
-
- if (strobeDwn_flag) { // гаснем
- if (strobe_bright > 0) // если яркость не минимальная
- strobe_bright -= STROBE_SMOOTH; // уменьшить
- if (strobe_bright < 0) { // если пробили мин. яркость
- strobeDwn_flag = false;
- strobe_bright = 0; // оставить 0
- }
- }
- animation();
- }
- if (this_mode == 6) animation();
-
- if (!IRLremote.receiving()) // если на ИК приёмник не приходит сигнал (без этого НЕ РАБОТАЕТ!)
- FastLED.show(); // отправить значения на ленту
-
- if (this_mode != 7) // 7 режиму не нужна очистка!!!
- FastLED.clear(); // очистить массив пикселей
- main_timer = millis(); // сбросить таймер
- }
- }
-}
-
-void animation() {
- // согласно режиму
- switch (this_mode) {
- case 0:
- count = 0;
- for (int i = (MAX_CH - 1); i > ((MAX_CH - 1) - Rlenght); i--) {
- leds[i] = ColorFromPalette(myPal, (count * index)); // заливка по палитре " от зелёного к красному"
- count++;
- }
- count = 0;
- for (int i = (MAX_CH); i < (MAX_CH + Llenght); i++ ) {
- leds[i] = ColorFromPalette(myPal, (count * index)); // заливка по палитре " от зелёного к красному"
- count++;
- }
- if (EMPTY_BRIGHT > 0) {
- CHSV this_dark = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- for (int i = ((MAX_CH - 1) - Rlenght); i > 0; i--)
- leds[i] = this_dark;
- for (int i = MAX_CH + Llenght; i < NUM_LEDS; i++)
- leds[i] = this_dark;
- }
- break;
- case 1:
- if (millis() - rainbow_timer > 30) {
- rainbow_timer = millis();
- hue = floor((float)hue + RAINBOW_STEP);
- }
- count = 0;
- for (int i = (MAX_CH - 1); i > ((MAX_CH - 1) - Rlenght); i--) {
- leds[i] = ColorFromPalette(RainbowColors_p, (count * index) / 2 - hue); // заливка по палитре радуга
- count++;
- }
- count = 0;
- for (int i = (MAX_CH); i < (MAX_CH + Llenght); i++ ) {
- leds[i] = ColorFromPalette(RainbowColors_p, (count * index) / 2 - hue); // заливка по палитре радуга
- count++;
- }
- if (EMPTY_BRIGHT > 0) {
- CHSV this_dark = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- for (int i = ((MAX_CH - 1) - Rlenght); i > 0; i--)
- leds[i] = this_dark;
- for (int i = MAX_CH + Llenght; i < NUM_LEDS; i++)
- leds[i] = this_dark;
- }
- break;
- case 2:
- for (int i = 0; i < NUM_LEDS; i++) {
- if (i < STRIPE) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (i < STRIPE * 2) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < STRIPE * 3) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else if (i < STRIPE * 4) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < STRIPE * 5) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- }
- break;
- case 3:
- for (int i = 0; i < NUM_LEDS; i++) {
- if (i < NUM_LEDS / 3) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (i < NUM_LEDS * 2 / 3) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < NUM_LEDS) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
- }
- break;
- case 4:
- switch (freq_strobe_mode) {
- case 0:
- if (colorMusicFlash[2]) HIGHS();
- else if (colorMusicFlash[1]) MIDS();
- else if (colorMusicFlash[0]) LOWS();
- else SILENCE();
- break;
- case 1:
- if (colorMusicFlash[2]) HIGHS();
- else SILENCE();
- break;
- case 2:
- if (colorMusicFlash[1]) MIDS();
- else SILENCE();
- break;
- case 3:
- if (colorMusicFlash[0]) LOWS();
- else SILENCE();
- break;
- }
- break;
- case 5:
- if (strobe_bright > 0)
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(STROBE_COLOR, STROBE_SAT, strobe_bright);
- else
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 6:
- switch (light_mode) {
- case 0: for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(LIGHT_COLOR, LIGHT_SAT, 255);
- break;
- case 1:
- if (millis() - color_timer > COLOR_SPEED) {
- color_timer = millis();
- if (++this_color > 255) this_color = 0;
- }
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(this_color, LIGHT_SAT, 255);
- break;
- case 2:
- if (millis() - rainbow_timer > 30) {
- rainbow_timer = millis();
- this_color += RAINBOW_PERIOD;
- if (this_color > 255) this_color = 0;
- if (this_color < 0) this_color = 255;
- }
- rainbow_steps = this_color;
- for (int i = 0; i < NUM_LEDS; i++) {
- leds[i] = CHSV((int)floor(rainbow_steps), 255, 255);
- rainbow_steps += RAINBOW_STEP_2;
- if (rainbow_steps > 255) rainbow_steps = 0;
- if (rainbow_steps < 0) rainbow_steps = 255;
- }
- break;
- }
- break;
- case 7:
- switch (freq_strobe_mode) {
- case 0:
- if (running_flag[2]) leds[NUM_LEDS / 2] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (running_flag[1]) leds[NUM_LEDS / 2] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (running_flag[0]) leds[NUM_LEDS / 2] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 1:
- if (running_flag[2]) leds[NUM_LEDS / 2] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 2:
- if (running_flag[1]) leds[NUM_LEDS / 2] = CHSV(MID_COLOR, 255, thisBright[1]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 3:
- if (running_flag[0]) leds[NUM_LEDS / 2] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- }
- leds[(NUM_LEDS / 2) - 1] = leds[NUM_LEDS / 2];
- if (millis() - running_timer > RUNNING_SPEED) {
- running_timer = millis();
- for (byte i = 0; i < NUM_LEDS / 2 - 1; i++) {
- leds[i] = leds[i + 1];
- leds[NUM_LEDS - i - 1] = leds[i];
- }
- }
- break;
- case 8:
- byte HUEindex = HUE_START;
- for (byte i = 0; i < NUM_LEDS / 2; i++) {
- byte this_bright = map(freq_f[(int)floor((NUM_LEDS / 2 - i) / freq_to_stripe)], 0, freq_max_f, 0, 255);
- this_bright = constrain(this_bright, 0, 255);
- leds[i] = CHSV(HUEindex, 255, this_bright);
- leds[NUM_LEDS - i - 1] = leds[i];
- HUEindex += HUE_STEP;
- if (HUEindex > 255) HUEindex = 0;
- }
- break;
- }
-}
-
-void HIGHS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
-}
-void MIDS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
-}
-void LOWS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
-}
-void SILENCE() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
-}
-
-// вспомогательная функция, изменяет величину value на шаг incr в пределах minimum.. maximum
-int smartIncr(int value, int incr_step, int mininmum, int maximum) {
- int val_buf = value + incr_step;
- val_buf = constrain(val_buf, mininmum, maximum);
- return val_buf;
-}
-
-float smartIncrFloat(float value, float incr_step, float mininmum, float maximum) {
- float val_buf = value + incr_step;
- val_buf = constrain(val_buf, mininmum, maximum);
- return val_buf;
-}
-
-#if REMOTE_TYPE != 0
-void remoteTick() {
- if (IRLremote.available()) {
- auto data = IRLremote.read();
- IRdata = data.command;
- ir_flag = true;
- }
- if (ir_flag) { // если данные пришли
- eeprom_timer = millis();
- eeprom_flag = true;
- switch (IRdata) {
- // режимы
- case BUTT_1: this_mode = 0;
- break;
- case BUTT_2: this_mode = 1;
- break;
- case BUTT_3: this_mode = 2;
- break;
- case BUTT_4: this_mode = 3;
- break;
- case BUTT_5: this_mode = 4;
- break;
- case BUTT_6: this_mode = 5;
- break;
- case BUTT_7: this_mode = 6;
- break;
- case BUTT_8: this_mode = 7;
- break;
- case BUTT_9: this_mode = 8;
- break;
- case BUTT_0: fullLowPass();
- break;
- case BUTT_STAR: ONstate = !ONstate; FastLED.clear(); FastLED.show(); updateEEPROM();
- break;
- case BUTT_HASH:
- switch (this_mode) {
- case 4:
- case 7: if (++freq_strobe_mode > 3) freq_strobe_mode = 0;
- break;
- case 6: if (++light_mode > 2) light_mode = 0;
- break;
- }
- break;
- case BUTT_OK: digitalWrite(MLED_PIN, settings_mode ^ MLED_ON); settings_mode = !settings_mode;
- break;
- case BUTT_UP:
- if (settings_mode) {
- // ВВЕРХ общие настройки
- EMPTY_BRIGHT = smartIncr(EMPTY_BRIGHT, 5, 0, 255);
- } else {
- switch (this_mode) {
- case 0:
- break;
- case 1: RAINBOW_STEP = smartIncrFloat(RAINBOW_STEP, 0.5, 0.5, 20);
- break;
- case 2:
- case 3:
- case 4: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, 0.1, 0, 5);
- break;
- case 5: STROBE_PERIOD = smartIncr(STROBE_PERIOD, 20, 1, 1000);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_SAT = smartIncr(LIGHT_SAT, 20, 0, 255);
- break;
- case 1: LIGHT_SAT = smartIncr(LIGHT_SAT, 20, 0, 255);
- break;
- case 2: RAINBOW_STEP_2 = smartIncrFloat(RAINBOW_STEP_2, 0.5, 0.5, 10);
- break;
- }
- break;
- case 7: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, 0.1, 0.0, 10);
- break;
- case 8: HUE_START = smartIncr(HUE_START, 10, 0, 255);
- break;
- }
- }
- break;
- case BUTT_DOWN:
- if (settings_mode) {
- // ВНИЗ общие настройки
- EMPTY_BRIGHT = smartIncr(EMPTY_BRIGHT, -5, 0, 255);
- } else {
- switch (this_mode) {
- case 0:
- break;
- case 1: RAINBOW_STEP = smartIncrFloat(RAINBOW_STEP, -0.5, 0.5, 20);
- break;
- case 2:
- case 3:
- case 4: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, -0.1, 0, 5);
- break;
- case 5: STROBE_PERIOD = smartIncr(STROBE_PERIOD, -20, 1, 1000);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_SAT = smartIncr(LIGHT_SAT, -20, 0, 255);
- break;
- case 1: LIGHT_SAT = smartIncr(LIGHT_SAT, -20, 0, 255);
- break;
- case 2: RAINBOW_STEP_2 = smartIncrFloat(RAINBOW_STEP_2, -0.5, 0.5, 10);
- break;
- }
- break;
- case 7: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, -0.1, 0.0, 10);
- break;
- case 8: HUE_START = smartIncr(HUE_START, -10, 0, 255);
- break;
- }
- }
- break;
- case BUTT_LEFT:
- if (settings_mode) {
- // ВЛЕВО общие настройки
- BRIGHTNESS = smartIncr(BRIGHTNESS, -20, 0, 255);
- FastLED.setBrightness(BRIGHTNESS);
- } else {
- switch (this_mode) {
- case 0:
- case 1: SMOOTH = smartIncrFloat(SMOOTH, -0.05, 0.05, 1);
- break;
- case 2:
- case 3:
- case 4: SMOOTH_FREQ = smartIncrFloat(SMOOTH_FREQ, -0.05, 0.05, 1);
- break;
- case 5: STROBE_SMOOTH = smartIncr(STROBE_SMOOTH, -20, 0, 255);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_COLOR = smartIncr(LIGHT_COLOR, -10, 0, 255);
- break;
- case 1: COLOR_SPEED = smartIncr(COLOR_SPEED, -10, 0, 255);
- break;
- case 2: RAINBOW_PERIOD = smartIncr(RAINBOW_PERIOD, -1, -20, 20);
- break;
- }
- break;
- case 7: RUNNING_SPEED = smartIncr(RUNNING_SPEED, -10, 1, 255);
- break;
- case 8: HUE_STEP = smartIncr(HUE_STEP, -1, 1, 255);
- break;
- }
- }
- break;
- case BUTT_RIGHT:
- if (settings_mode) {
- // ВПРАВО общие настройки
- BRIGHTNESS = smartIncr(BRIGHTNESS, 20, 0, 255);
- FastLED.setBrightness(BRIGHTNESS);
- } else {
- switch (this_mode) {
- case 0:
- case 1: SMOOTH = smartIncrFloat(SMOOTH, 0.05, 0.05, 1);
- break;
- case 2:
- case 3:
- case 4: SMOOTH_FREQ = smartIncrFloat(SMOOTH_FREQ, 0.05, 0.05, 1);
- break;
- case 5: STROBE_SMOOTH = smartIncr(STROBE_SMOOTH, 20, 0, 255);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_COLOR = smartIncr(LIGHT_COLOR, 10, 0, 255);
- break;
- case 1: COLOR_SPEED = smartIncr(COLOR_SPEED, 10, 0, 255);
- break;
- case 2: RAINBOW_PERIOD = smartIncr(RAINBOW_PERIOD, 1, -20, 20);
- break;
- }
- break;
- case 7: RUNNING_SPEED = smartIncr(RUNNING_SPEED, 10, 1, 255);
- break;
- case 8: HUE_STEP = smartIncr(HUE_STEP, 1, 1, 255);
- break;
- }
- }
- break;
- default: eeprom_flag = false; // если не распознали кнопку, не обновляем настройки!
- break;
- }
- ir_flag = false;
- }
-}
-#endif
-
-void autoLowPass() {
- // для режима VU
- delay(10); // ждём инициализации АЦП
- int thisMax = 0; // максимум
- int thisLevel;
- for (byte i = 0; i < 200; i++) {
- thisLevel = analogRead(SOUND_R); // делаем 200 измерений
- if (thisLevel > thisMax) // ищем максимумы
- thisMax = thisLevel; // запоминаем
- delay(4); // ждём 4мс
- }
- LOW_PASS = thisMax + LOW_PASS_ADD; // нижний порог как максимум тишины + некая величина
-
- // для режима спектра
- thisMax = 0;
- for (byte i = 0; i < 100; i++) { // делаем 100 измерений
- analyzeAudio(); // разбить в спектр
- for (byte j = 2; j < 32; j++) { // первые 2 канала - хлам
- thisLevel = fht_log_out[j];
- if (thisLevel > thisMax) // ищем максимумы
- thisMax = thisLevel; // запоминаем
- }
- delay(4); // ждём 4мс
- }
- SPEKTR_LOW_PASS = thisMax + LOW_PASS_FREQ_ADD; // нижний порог как максимум тишины
- if (EEPROM_LOW_PASS && !AUTO_LOW_PASS) {
- EEPROM.updateInt(70, LOW_PASS);
- EEPROM.updateInt(72, SPEKTR_LOW_PASS);
- }
-}
-
-void analyzeAudio() {
- for (int i = 0 ; i < FHT_N ; i++) {
- int sample = analogRead(SOUND_R_FREQ);
- fht_input[i] = sample; // put real data into bins
- }
- fht_window(); // window the data for better frequency response
- fht_reorder(); // reorder the data before doing the fht
- fht_run(); // process the data in the fht
- fht_mag_log(); // take the output of the fht
-}
-
-void buttonTick() {
- butt1.tick(); // обязательная функция отработки. Должна постоянно опрашиваться
- if (butt1.isSingle()) // если единичное нажатие
- if (++this_mode >= MODE_AMOUNT) this_mode = 0; // изменить режим
-
- if (butt1.isHolded()) { // кнопка удержана
- fullLowPass();
- }
-}
-void fullLowPass() {
- digitalWrite(MLED_PIN, MLED_ON); // включить светодиод
- FastLED.setBrightness(0); // погасить ленту
- FastLED.clear(); // очистить массив пикселей
- FastLED.show(); // отправить значения на ленту
- delay(500); // подождать чутка
- autoLowPass(); // измерить шумы
- delay(500); // подождать
- FastLED.setBrightness(BRIGHTNESS); // вернуть яркость
- digitalWrite(MLED_PIN, !MLED_ON); // выключить светодиод
-}
-void updateEEPROM() {
- EEPROM.updateByte(1, this_mode);
- EEPROM.updateByte(2, freq_strobe_mode);
- EEPROM.updateByte(3, light_mode);
- EEPROM.updateInt(4, RAINBOW_STEP);
- EEPROM.updateFloat(8, MAX_COEF_FREQ);
- EEPROM.updateInt(12, STROBE_PERIOD);
- EEPROM.updateInt(16, LIGHT_SAT);
- EEPROM.updateFloat(20, RAINBOW_STEP_2);
- EEPROM.updateInt(24, HUE_START);
- EEPROM.updateFloat(28, SMOOTH);
- EEPROM.updateFloat(32, SMOOTH_FREQ);
- EEPROM.updateInt(36, STROBE_SMOOTH);
- EEPROM.updateInt(40, LIGHT_COLOR);
- EEPROM.updateInt(44, COLOR_SPEED);
- EEPROM.updateInt(48, RAINBOW_PERIOD);
- EEPROM.updateInt(52, RUNNING_SPEED);
- EEPROM.updateInt(56, HUE_STEP);
- EEPROM.updateInt(60, EMPTY_BRIGHT);
- if (KEEP_STATE) EEPROM.updateByte(64, ONstate);
-}
-void readEEPROM() {
- this_mode = EEPROM.readByte(1);
- freq_strobe_mode = EEPROM.readByte(2);
- light_mode = EEPROM.readByte(3);
- RAINBOW_STEP = EEPROM.readInt(4);
- MAX_COEF_FREQ = EEPROM.readFloat(8);
- STROBE_PERIOD = EEPROM.readInt(12);
- LIGHT_SAT = EEPROM.readInt(16);
- RAINBOW_STEP_2 = EEPROM.readFloat(20);
- HUE_START = EEPROM.readInt(24);
- SMOOTH = EEPROM.readFloat(28);
- SMOOTH_FREQ = EEPROM.readFloat(32);
- STROBE_SMOOTH = EEPROM.readInt(36);
- LIGHT_COLOR = EEPROM.readInt(40);
- COLOR_SPEED = EEPROM.readInt(44);
- RAINBOW_PERIOD = EEPROM.readInt(48);
- RUNNING_SPEED = EEPROM.readInt(52);
- HUE_STEP = EEPROM.readInt(56);
- EMPTY_BRIGHT = EEPROM.readInt(60);
- if (KEEP_STATE) ONstate = EEPROM.readByte(64);
-}
-void eepromTick() {
- if (eeprom_flag)
- if (millis() - eeprom_timer > 30000) { // 30 секунд после последнего нажатия с пульта
- eeprom_flag = false;
- eeprom_timer = millis();
- updateEEPROM();
- }
-}
diff --git a/firmware/Old versions/colorMusic_v2.9/colorMusic_v2.9.ino b/firmware/Old versions/colorMusic_v2.9/colorMusic_v2.9.ino
deleted file mode 100644
index cb429a5..0000000
--- a/firmware/Old versions/colorMusic_v2.9/colorMusic_v2.9.ino
+++ /dev/null
@@ -1,981 +0,0 @@
-/*
- Скетч к проекту "Светомузыка на Arduino"
- Страница проекта (схемы, описания): https://alexgyver.ru/colormusic/
- Исходники на GitHub: https://github.com/AlexGyver/ColorMusic
- Нравится, как написан код? Поддержи автора! https://alexgyver.ru/support_alex/
- Автор: AlexGyver Technologies, 2018
- https://AlexGyver.ru/
-
- Как откалибровать уровень шума и как пользоваться пультом
- расписано на странице проекта! https://alexgyver.ru/colormusic/
-*/
-
-/*
- Версия 2.10
- Исправлен глюк с большим количеством светодиодов на МЕГЕ
-*/
-
-
-// ***************************** НАСТРОЙКИ *****************************
-
-// ----- настройка ИК пульта
-#define REMOTE_TYPE 1 // 0 - без пульта, 1 - пульт от WAVGAT, 2 - пульт от KEYES, 3 - кастомный пульт
-// система может работать С ЛЮБЫМ ИК ПУЛЬТОМ (практически). Коды для своего пульта можно задать начиная со строки 160 в прошивке. Коды пультов определяются скетчем IRtest_2.0, читай инструкцию
-
-// ----- настройки параметров
-#define KEEP_SETTINGS 1 // хранить ВСЕ настройки в энергонезависимой памяти
-#define KEEP_STATE 1 // сохранять в памяти состояние вкл/выкл системы (с пульта)
-#define RESET_SETTINGS 0 // сброс настроек в EEPROM памяти (поставить 1, прошиться, поставить обратно 0, прошиться. Всё)
-#define SETTINGS_LOG 0 // вывод всех настроек из EEPROM в порт при запуске
-
-// ----- настройки ленты
-#define NUM_LEDS 60 // количество светодиодов (данная версия поддерживает до 410 штук)
-#define CURRENT_LIMIT 3000 // лимит по току в МИЛЛИАМПЕРАХ, автоматически управляет яркостью (пожалей свой блок питания!) 0 - выключить лимит
-byte BRIGHTNESS = 200; // яркость по умолчанию (0 - 255)
-
-// ----- пины подключения
-#define SOUND_R A2 // аналоговый пин вход аудио, правый канал
-#define SOUND_L A1 // аналоговый пин вход аудио, левый канал
-#define SOUND_R_FREQ A3 // аналоговый пин вход аудио для режима с частотами (через кондер)
-#define BTN_PIN 3 // кнопка переключения режимов (PIN --- КНОПКА --- GND)
-
-#if defined(__AVR_ATmega32U4__) // Пины для Arduino Pro Micro (смотри схему для Pro Micro на странице проекта!!!)
-#define MLED_PIN 17 // пин светодиода режимов на ProMicro, т.к. обычный не выведен.
-#define MLED_ON LOW
-#define LED_PIN 9 // пин DI светодиодной ленты на ProMicro, т.к. обычный не выведен.
-#else // Пины для других плат Arduino (по умолчанию)
-#define MLED_PIN 13 // пин светодиода режимов
-#define MLED_ON HIGH
-#define LED_PIN 12 // пин DI светодиодной ленты
-#endif
-
-#define POT_GND A0 // пин земля для потенциометра
-#define IR_PIN 2 // пин ИК приёмника
-
-// ----- настройки радуги
-float RAINBOW_STEP = 5.00; // шаг изменения цвета радуги
-
-// ----- отрисовка
-#define MODE 0 // режим при запуске
-#define MAIN_LOOP 5 // период основного цикла отрисовки (по умолчанию 5)
-
-// ----- сигнал
-#define MONO 1 // 1 - только один канал (ПРАВЫЙ!!!!! SOUND_R!!!!!), 0 - два канала
-#define EXP 1.4 // степень усиления сигнала (для более "резкой" работы) (по умолчанию 1.4)
-#define POTENT 0 // 1 - используем потенциометр, 0 - используется внутренний источник опорного напряжения 1.1 В
-byte EMPTY_BRIGHT = 30; // яркость "не горящих" светодиодов (0 - 255)
-#define EMPTY_COLOR HUE_PURPLE // цвет "не горящих" светодиодов. Будет чёрный, если яркость 0
-
-// ----- нижний порог шумов
-uint16_t LOW_PASS = 100; // нижний порог шумов режим VU, ручная настройка
-uint16_t SPEKTR_LOW_PASS = 40; // нижний порог шумов режим спектра, ручная настройка
-#define AUTO_LOW_PASS 0 // разрешить настройку нижнего порога шумов при запуске (по умолч. 0)
-#define EEPROM_LOW_PASS 1 // порог шумов хранится в энергонезависимой памяти (по умолч. 1)
-#define LOW_PASS_ADD 13 // "добавочная" величина к нижнему порогу, для надёжности (режим VU)
-#define LOW_PASS_FREQ_ADD 3 // "добавочная" величина к нижнему порогу, для надёжности (режим частот)
-
-// ----- режим шкала громкости
-float SMOOTH = 0.3; // коэффициент плавности анимации VU (по умолчанию 0.5)
-#define MAX_COEF 1.8 // коэффициент громкости (максимальное равно срднему * этот коэф) (по умолчанию 1.8)
-
-// ----- режим цветомузыки
-float SMOOTH_FREQ = 0.8; // коэффициент плавности анимации частот (по умолчанию 0.8)
-float MAX_COEF_FREQ = 1.2; // коэффициент порога для "вспышки" цветомузыки (по умолчанию 1.5)
-#define SMOOTH_STEP 20 // шаг уменьшения яркости в режиме цветомузыки (чем больше, тем быстрее гаснет)
-#define LOW_COLOR HUE_RED // цвет низких частот
-#define MID_COLOR HUE_GREEN // цвет средних
-#define HIGH_COLOR HUE_YELLOW // цвет высоких
-
-// ----- режим стробоскопа
-uint16_t STROBE_PERIOD = 140; // период вспышек, миллисекунды
-#define STROBE_DUTY 20 // скважность вспышек (1 - 99) - отношение времени вспышки ко времени темноты
-#define STROBE_COLOR HUE_YELLOW // цвет стробоскопа
-#define STROBE_SAT 0 // насыщенность. Если 0 - цвет будет БЕЛЫЙ при любом цвете (0 - 255)
-byte STROBE_SMOOTH = 200; // скорость нарастания/угасания вспышки (0 - 255)
-
-// ----- режим подсветки
-byte LIGHT_COLOR = 0; // начальный цвет подсветки
-byte LIGHT_SAT = 255; // начальная насыщенность подсветки
-byte COLOR_SPEED = 100;
-int RAINBOW_PERIOD = 1;
-float RAINBOW_STEP_2 = 0.5;
-
-// ----- режим бегущих частот
-byte RUNNING_SPEED = 11;
-
-// ----- режим анализатора спектра
-byte HUE_START = 0;
-byte HUE_STEP = 5;
-#define LIGHT_SMOOTH 2
-
-/*
- Цвета для HSV
- HUE_RED
- HUE_ORANGE
- HUE_YELLOW
- HUE_GREEN
- HUE_AQUA
- HUE_BLUE
- HUE_PURPLE
- HUE_PINK
-*/
-
-// ----- КНОПКИ ПУЛЬТА WAVGAT -----
-#if REMOTE_TYPE == 1
-#define BUTT_UP 0xF39EEBAD
-#define BUTT_DOWN 0xC089F6AD
-#define BUTT_LEFT 0xE25410AD
-#define BUTT_RIGHT 0x14CE54AD
-#define BUTT_OK 0x297C76AD
-#define BUTT_1 0x4E5BA3AD
-#define BUTT_2 0xE51CA6AD
-#define BUTT_3 0xE207E1AD
-#define BUTT_4 0x517068AD
-#define BUTT_5 0x1B92DDAD
-#define BUTT_6 0xAC2A56AD
-#define BUTT_7 0x5484B6AD
-#define BUTT_8 0xD22353AD
-#define BUTT_9 0xDF3F4BAD
-#define BUTT_0 0xF08A26AD
-#define BUTT_STAR 0x68E456AD
-#define BUTT_HASH 0x151CD6AD
-#endif
-
-// ----- КНОПКИ ПУЛЬТА KEYES -----
-#if REMOTE_TYPE == 2
-#define BUTT_UP 0xE51CA6AD
-#define BUTT_DOWN 0xD22353AD
-#define BUTT_LEFT 0x517068AD
-#define BUTT_RIGHT 0xAC2A56AD
-#define BUTT_OK 0x1B92DDAD
-#define BUTT_1 0x68E456AD
-#define BUTT_2 0xF08A26AD
-#define BUTT_3 0x151CD6AD
-#define BUTT_4 0x18319BAD
-#define BUTT_5 0xF39EEBAD
-#define BUTT_6 0x4AABDFAD
-#define BUTT_7 0xE25410AD
-#define BUTT_8 0x297C76AD
-#define BUTT_9 0x14CE54AD
-#define BUTT_0 0xC089F6AD
-#define BUTT_STAR 0xAF3F1BAD
-#define BUTT_HASH 0x38379AD
-#endif
-
-// ----- КНОПКИ СВОЕГО ПУЛЬТА -----
-#if REMOTE_TYPE == 3
-#define BUTT_UP 0xE51CA6AD
-#define BUTT_DOWN 0xD22353AD
-#define BUTT_LEFT 0x517068AD
-#define BUTT_RIGHT 0xAC2A56AD
-#define BUTT_OK 0x1B92DDAD
-#define BUTT_1 0x68E456AD
-#define BUTT_2 0xF08A26AD
-#define BUTT_3 0x151CD6AD
-#define BUTT_4 0x18319BAD
-#define BUTT_5 0xF39EEBAD
-#define BUTT_6 0x4AABDFAD
-#define BUTT_7 0xE25410AD
-#define BUTT_8 0x297C76AD
-#define BUTT_9 0x14CE54AD
-#define BUTT_0 0xC089F6AD
-#define BUTT_STAR 0xAF3F1BAD // *
-#define BUTT_HASH 0x38379AD // #
-#endif
-
-
-// ------------------------------ ДЛЯ РАЗРАБОТЧИКОВ --------------------------------
-#define MODE_AMOUNT 9 // количество режимов
-
-#define STRIPE NUM_LEDS / 5
-float freq_to_stripe = NUM_LEDS / 40; // /2 так как симметрия, и /20 так как 20 частот
-
-#define FHT_N 64 // ширина спектра х2
-#define LOG_OUT 1
-#include // преобразование Хартли
-
-#include
-
-#define FASTLED_ALLOW_INTERRUPTS 1
-#include "FastLED.h"
-CRGB leds[NUM_LEDS];
-
-#include "GyverButton.h"
-GButton butt1(BTN_PIN);
-
-#include "IRLremote.h"
-CHashIR IRLremote;
-uint32_t IRdata;
-
-// градиент-палитра от зелёного к красному
-DEFINE_GRADIENT_PALETTE(soundlevel_gp) {
- 0, 0, 255, 0, // green
- 100, 255, 255, 0, // yellow
- 150, 255, 100, 0, // orange
- 200, 255, 50, 0, // red
- 255, 255, 0, 0 // red
-};
-CRGBPalette32 myPal = soundlevel_gp;
-
-byte Rlenght, Llenght;
-float RsoundLevel, RsoundLevel_f;
-float LsoundLevel, LsoundLevel_f;
-
-float averageLevel = 50;
-int maxLevel = 100;
-byte MAX_CH = NUM_LEDS / 2;
-int hue;
-unsigned long main_timer, hue_timer, strobe_timer, running_timer, color_timer, rainbow_timer, eeprom_timer;
-float averK = 0.006;
-byte count;
-float index = (float)255 / MAX_CH; // коэффициент перевода для палитры
-boolean lowFlag;
-byte low_pass;
-int RcurrentLevel, LcurrentLevel;
-int colorMusic[3];
-float colorMusic_f[3], colorMusic_aver[3];
-boolean colorMusicFlash[3], strobeUp_flag, strobeDwn_flag;
-byte this_mode = MODE;
-int thisBright[3], strobe_bright = 0;
-unsigned int light_time = STROBE_PERIOD * STROBE_DUTY / 100;
-volatile boolean ir_flag;
-boolean settings_mode, ONstate = true;
-int8_t freq_strobe_mode, light_mode;
-int freq_max;
-float freq_max_f, rainbow_steps;
-int freq_f[32];
-int this_color;
-boolean running_flag[3], eeprom_flag;
-
-#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
-#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
-// ------------------------------ ДЛЯ РАЗРАБОТЧИКОВ --------------------------------
-
-void setup() {
- Serial.begin(9600);
- FastLED.addLeds(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
- if (CURRENT_LIMIT > 0) FastLED.setMaxPowerInVoltsAndMilliamps(5, CURRENT_LIMIT);
- FastLED.setBrightness(BRIGHTNESS);
-
-#if defined(__AVR_ATmega32U4__) //Выключение светодиодов на Pro Micro
- TXLED1; //на ProMicro выключим и TXLED
- delay (1000); //При питании по usb от компьютера нужна задержка перед выключением RXLED. Если питать от БП, то можно убрать эту строку.
-#endif
- pinMode(MLED_PIN, OUTPUT); //Режим пина для светодиода режима на выход
- digitalWrite(MLED_PIN, !MLED_ON); //Выключение светодиода режима
-
- pinMode(POT_GND, OUTPUT);
- digitalWrite(POT_GND, LOW);
- butt1.setTimeout(900);
-
- IRLremote.begin(IR_PIN);
-
- // для увеличения точности уменьшаем опорное напряжение,
- // выставив EXTERNAL и подключив Aref к выходу 3.3V на плате через делитель
- // GND ---[10-20 кОм] --- REF --- [10 кОм] --- 3V3
- // в данной схеме GND берётся из А0 для удобства подключения
- if (POTENT) analogReference(EXTERNAL);
- else
-#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
- analogReference(INTERNAL1V1);
-#else
- analogReference(INTERNAL);
-#endif
-
- // жуткая магия, меняем частоту оцифровки до 18 кГц
- // команды на ебучем ассемблере, даже не спрашивайте, как это работает
- // поднимаем частоту опроса аналогового порта до 38.4 кГц, по теореме
- // Котельникова (Найквиста) частота дискретизации будет 19.2 кГц
- // http://yaab-arduino.blogspot.ru/2015/02/fast-sampling-from-analog-input.html
- sbi(ADCSRA, ADPS2);
- cbi(ADCSRA, ADPS1);
- sbi(ADCSRA, ADPS0);
-
- if (RESET_SETTINGS) EEPROM.write(100, 0); // сброс флага настроек
-
- if (AUTO_LOW_PASS && !EEPROM_LOW_PASS) { // если разрешена автонастройка нижнего порога шумов
- autoLowPass();
- }
- if (EEPROM_LOW_PASS) { // восстановить значения шумов из памяти
- LOW_PASS = EEPROM.readInt(70);
- SPEKTR_LOW_PASS = EEPROM.readInt(72);
- }
-
- // в 100 ячейке хранится число 100. Если нет - значит это первый запуск системы
- if (KEEP_SETTINGS) {
- if (EEPROM.read(100) != 100) {
- //Serial.println(F("First start"));
- EEPROM.write(100, 100);
- updateEEPROM();
- } else {
- readEEPROM();
- }
- }
-
-#if (SETTINGS_LOG == 1)
- Serial.print(F("this_mode = ")); Serial.println(this_mode);
- Serial.print(F("freq_strobe_mode = ")); Serial.println(freq_strobe_mode);
- Serial.print(F("light_mode = ")); Serial.println(light_mode);
- Serial.print(F("RAINBOW_STEP = ")); Serial.println(RAINBOW_STEP);
- Serial.print(F("MAX_COEF_FREQ = ")); Serial.println(MAX_COEF_FREQ);
- Serial.print(F("STROBE_PERIOD = ")); Serial.println(STROBE_PERIOD);
- Serial.print(F("LIGHT_SAT = ")); Serial.println(LIGHT_SAT);
- Serial.print(F("RAINBOW_STEP_2 = ")); Serial.println(RAINBOW_STEP_2);
- Serial.print(F("HUE_START = ")); Serial.println(HUE_START);
- Serial.print(F("SMOOTH = ")); Serial.println(SMOOTH);
- Serial.print(F("SMOOTH_FREQ = ")); Serial.println(SMOOTH_FREQ);
- Serial.print(F("STROBE_SMOOTH = ")); Serial.println(STROBE_SMOOTH);
- Serial.print(F("LIGHT_COLOR = ")); Serial.println(LIGHT_COLOR);
- Serial.print(F("COLOR_SPEED = ")); Serial.println(COLOR_SPEED);
- Serial.print(F("RAINBOW_PERIOD = ")); Serial.println(RAINBOW_PERIOD);
- Serial.print(F("RUNNING_SPEED = ")); Serial.println(RUNNING_SPEED);
- Serial.print(F("HUE_STEP = ")); Serial.println(HUE_STEP);
- Serial.print(F("EMPTY_BRIGHT = ")); Serial.println(EMPTY_BRIGHT);
- Serial.print(F("ONstate = ")); Serial.println(ONstate);
-#endif
-}
-
-void loop() {
- buttonTick(); // опрос и обработка кнопки
-#if REMOTE_TYPE != 0
- remoteTick(); // опрос ИК пульта
-#endif
- mainLoop(); // главный цикл обработки и отрисовки
- eepromTick(); // проверка не пора ли сохранить настройки
-}
-
-void mainLoop() {
- // главный цикл отрисовки
- if (ONstate) {
- if (millis() - main_timer > MAIN_LOOP) {
- // сбрасываем значения
- RsoundLevel = 0;
- LsoundLevel = 0;
-
- // перваые два режима - громкость (VU meter)
- if (this_mode == 0 || this_mode == 1) {
- for (byte i = 0; i < 100; i ++) { // делаем 100 измерений
- RcurrentLevel = analogRead(SOUND_R); // с правого
- if (!MONO) LcurrentLevel = analogRead(SOUND_L); // и левого каналов
-
- if (RsoundLevel < RcurrentLevel) RsoundLevel = RcurrentLevel; // ищем максимальное
- if (!MONO) if (LsoundLevel < LcurrentLevel) LsoundLevel = LcurrentLevel; // ищем максимальное
- }
-
- // фильтруем по нижнему порогу шумов
- RsoundLevel = map(RsoundLevel, LOW_PASS, 1023, 0, 500);
- if (!MONO)LsoundLevel = map(LsoundLevel, LOW_PASS, 1023, 0, 500);
-
- // ограничиваем диапазон
- RsoundLevel = constrain(RsoundLevel, 0, 500);
- if (!MONO)LsoundLevel = constrain(LsoundLevel, 0, 500);
-
- // возводим в степень (для большей чёткости работы)
- RsoundLevel = pow(RsoundLevel, EXP);
- if (!MONO)LsoundLevel = pow(LsoundLevel, EXP);
-
- // фильтр
- RsoundLevel_f = RsoundLevel * SMOOTH + RsoundLevel_f * (1 - SMOOTH);
- if (!MONO)LsoundLevel_f = LsoundLevel * SMOOTH + LsoundLevel_f * (1 - SMOOTH);
-
- if (MONO) LsoundLevel_f = RsoundLevel_f; // если моно, то левый = правому
-
- // заливаем "подложку", если яркость достаточная
- if (EMPTY_BRIGHT > 5) {
- for (int i = 0; i < NUM_LEDS; i++)
- leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- }
-
- // если значение выше порога - начинаем самое интересное
- if (RsoundLevel_f > 15 && LsoundLevel_f > 15) {
-
- // расчёт общей средней громкости с обоих каналов, фильтрация.
- // Фильтр очень медленный, сделано специально для автогромкости
- averageLevel = (float)(RsoundLevel_f + LsoundLevel_f) / 2 * averK + averageLevel * (1 - averK);
-
- // принимаем максимальную громкость шкалы как среднюю, умноженную на некоторый коэффициент MAX_COEF
- maxLevel = (float)averageLevel * MAX_COEF;
-
- // преобразуем сигнал в длину ленты (где MAX_CH это половина количества светодиодов)
- Rlenght = map(RsoundLevel_f, 0, maxLevel, 0, MAX_CH);
- Llenght = map(LsoundLevel_f, 0, maxLevel, 0, MAX_CH);
-
- // ограничиваем до макс. числа светодиодов
- Rlenght = constrain(Rlenght, 0, MAX_CH);
- Llenght = constrain(Llenght, 0, MAX_CH);
-
- animation(); // отрисовать
- }
- }
-
- // 3-5 режим - цветомузыка
- if (this_mode == 2 || this_mode == 3 || this_mode == 4 || this_mode == 7 || this_mode == 8) {
- analyzeAudio();
- colorMusic[0] = 0;
- colorMusic[1] = 0;
- colorMusic[2] = 0;
- for (int i = 0 ; i < 32 ; i++) {
- if (fht_log_out[i] < SPEKTR_LOW_PASS) fht_log_out[i] = 0;
- }
- // низкие частоты, выборка со 2 по 5 тон (0 и 1 зашумленные!)
- for (byte i = 2; i < 6; i++) {
- if (fht_log_out[i] > colorMusic[0]) colorMusic[0] = fht_log_out[i];
- }
- // средние частоты, выборка с 6 по 10 тон
- for (byte i = 6; i < 11; i++) {
- if (fht_log_out[i] > colorMusic[1]) colorMusic[1] = fht_log_out[i];
- }
- // высокие частоты, выборка с 11 по 31 тон
- for (byte i = 11; i < 32; i++) {
- if (fht_log_out[i] > colorMusic[2]) colorMusic[2] = fht_log_out[i];
- }
- freq_max = 0;
- for (byte i = 0; i < 30; i++) {
- if (fht_log_out[i + 2] > freq_max) freq_max = fht_log_out[i + 2];
- if (freq_max < 5) freq_max = 5;
-
- if (freq_f[i] < fht_log_out[i + 2]) freq_f[i] = fht_log_out[i + 2];
- if (freq_f[i] > 0) freq_f[i] -= LIGHT_SMOOTH;
- else freq_f[i] = 0;
- }
- freq_max_f = freq_max * averK + freq_max_f * (1 - averK);
- for (byte i = 0; i < 3; i++) {
- colorMusic_aver[i] = colorMusic[i] * averK + colorMusic_aver[i] * (1 - averK); // общая фильтрация
- colorMusic_f[i] = colorMusic[i] * SMOOTH_FREQ + colorMusic_f[i] * (1 - SMOOTH_FREQ); // локальная
- if (colorMusic_f[i] > ((float)colorMusic_aver[i] * MAX_COEF_FREQ)) {
- thisBright[i] = 255;
- colorMusicFlash[i] = true;
- running_flag[i] = true;
- } else colorMusicFlash[i] = false;
- if (thisBright[i] >= 0) thisBright[i] -= SMOOTH_STEP;
- if (thisBright[i] < EMPTY_BRIGHT) {
- thisBright[i] = EMPTY_BRIGHT;
- running_flag[i] = false;
- }
- }
- animation();
- }
- if (this_mode == 5) {
- if ((long)millis() - strobe_timer > STROBE_PERIOD) {
- strobe_timer = millis();
- strobeUp_flag = true;
- strobeDwn_flag = false;
- }
- if ((long)millis() - strobe_timer > light_time) {
- strobeDwn_flag = true;
- }
- if (strobeUp_flag) { // если настало время пыхнуть
- if (strobe_bright < 255) // если яркость не максимальная
- strobe_bright += STROBE_SMOOTH; // увелчить
- if (strobe_bright > 255) { // если пробили макс. яркость
- strobe_bright = 255; // оставить максимум
- strobeUp_flag = false; // флаг опустить
- }
- }
-
- if (strobeDwn_flag) { // гаснем
- if (strobe_bright > 0) // если яркость не минимальная
- strobe_bright -= STROBE_SMOOTH; // уменьшить
- if (strobe_bright < 0) { // если пробили мин. яркость
- strobeDwn_flag = false;
- strobe_bright = 0; // оставить 0
- }
- }
- animation();
- }
- if (this_mode == 6) animation();
-
- if (!IRLremote.receiving()) // если на ИК приёмник не приходит сигнал (без этого НЕ РАБОТАЕТ!)
- FastLED.show(); // отправить значения на ленту
-
- if (this_mode != 7) // 7 режиму не нужна очистка!!!
- FastLED.clear(); // очистить массив пикселей
- main_timer = millis(); // сбросить таймер
- }
- }
-}
-
-void animation() {
- // согласно режиму
- switch (this_mode) {
- case 0:
- count = 0;
- for (int i = (MAX_CH - 1); i > ((MAX_CH - 1) - Rlenght); i--) {
- leds[i] = ColorFromPalette(myPal, (count * index)); // заливка по палитре " от зелёного к красному"
- count++;
- }
- count = 0;
- for (int i = (MAX_CH); i < (MAX_CH + Llenght); i++ ) {
- leds[i] = ColorFromPalette(myPal, (count * index)); // заливка по палитре " от зелёного к красному"
- count++;
- }
- if (EMPTY_BRIGHT > 0) {
- CHSV this_dark = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- for (int i = ((MAX_CH - 1) - Rlenght); i > 0; i--)
- leds[i] = this_dark;
- for (int i = MAX_CH + Llenght; i < NUM_LEDS; i++)
- leds[i] = this_dark;
- }
- break;
- case 1:
- if (millis() - rainbow_timer > 30) {
- rainbow_timer = millis();
- hue = floor((float)hue + RAINBOW_STEP);
- }
- count = 0;
- for (int i = (MAX_CH - 1); i > ((MAX_CH - 1) - Rlenght); i--) {
- leds[i] = ColorFromPalette(RainbowColors_p, (count * index) / 2 - hue); // заливка по палитре радуга
- count++;
- }
- count = 0;
- for (int i = (MAX_CH); i < (MAX_CH + Llenght); i++ ) {
- leds[i] = ColorFromPalette(RainbowColors_p, (count * index) / 2 - hue); // заливка по палитре радуга
- count++;
- }
- if (EMPTY_BRIGHT > 0) {
- CHSV this_dark = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- for (int i = ((MAX_CH - 1) - Rlenght); i > 0; i--)
- leds[i] = this_dark;
- for (int i = MAX_CH + Llenght; i < NUM_LEDS; i++)
- leds[i] = this_dark;
- }
- break;
- case 2:
- for (int i = 0; i < NUM_LEDS; i++) {
- if (i < STRIPE) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (i < STRIPE * 2) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < STRIPE * 3) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else if (i < STRIPE * 4) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < STRIPE * 5) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- }
- break;
- case 3:
- for (int i = 0; i < NUM_LEDS; i++) {
- if (i < NUM_LEDS / 3) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (i < NUM_LEDS * 2 / 3) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (i < NUM_LEDS) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
- }
- break;
- case 4:
- switch (freq_strobe_mode) {
- case 0:
- if (colorMusicFlash[2]) HIGHS();
- else if (colorMusicFlash[1]) MIDS();
- else if (colorMusicFlash[0]) LOWS();
- else SILENCE();
- break;
- case 1:
- if (colorMusicFlash[2]) HIGHS();
- else SILENCE();
- break;
- case 2:
- if (colorMusicFlash[1]) MIDS();
- else SILENCE();
- break;
- case 3:
- if (colorMusicFlash[0]) LOWS();
- else SILENCE();
- break;
- }
- break;
- case 5:
- if (strobe_bright > 0)
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(STROBE_COLOR, STROBE_SAT, strobe_bright);
- else
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 6:
- switch (light_mode) {
- case 0: for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(LIGHT_COLOR, LIGHT_SAT, 255);
- break;
- case 1:
- if (millis() - color_timer > COLOR_SPEED) {
- color_timer = millis();
- if (++this_color > 255) this_color = 0;
- }
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(this_color, LIGHT_SAT, 255);
- break;
- case 2:
- if (millis() - rainbow_timer > 30) {
- rainbow_timer = millis();
- this_color += RAINBOW_PERIOD;
- if (this_color > 255) this_color = 0;
- if (this_color < 0) this_color = 255;
- }
- rainbow_steps = this_color;
- for (int i = 0; i < NUM_LEDS; i++) {
- leds[i] = CHSV((int)floor(rainbow_steps), 255, 255);
- rainbow_steps += RAINBOW_STEP_2;
- if (rainbow_steps > 255) rainbow_steps = 0;
- if (rainbow_steps < 0) rainbow_steps = 255;
- }
- break;
- }
- break;
- case 7:
- switch (freq_strobe_mode) {
- case 0:
- if (running_flag[2]) leds[NUM_LEDS / 2] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else if (running_flag[1]) leds[NUM_LEDS / 2] = CHSV(MID_COLOR, 255, thisBright[1]);
- else if (running_flag[0]) leds[NUM_LEDS / 2] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 1:
- if (running_flag[2]) leds[NUM_LEDS / 2] = CHSV(HIGH_COLOR, 255, thisBright[2]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 2:
- if (running_flag[1]) leds[NUM_LEDS / 2] = CHSV(MID_COLOR, 255, thisBright[1]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- case 3:
- if (running_flag[0]) leds[NUM_LEDS / 2] = CHSV(LOW_COLOR, 255, thisBright[0]);
- else leds[NUM_LEDS / 2] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
- break;
- }
- leds[(NUM_LEDS / 2) - 1] = leds[NUM_LEDS / 2];
- if (millis() - running_timer > RUNNING_SPEED) {
- running_timer = millis();
- for (byte i = 0; i < NUM_LEDS / 2 - 1; i++) {
- leds[i] = leds[i + 1];
- leds[NUM_LEDS - i - 1] = leds[i];
- }
- }
- break;
- case 8:
- byte HUEindex = HUE_START;
- for (byte i = 0; i < NUM_LEDS / 2; i++) {
- byte this_bright = map(freq_f[(int)floor((NUM_LEDS / 2 - i) / freq_to_stripe)], 0, freq_max_f, 0, 255);
- this_bright = constrain(this_bright, 0, 255);
- leds[i] = CHSV(HUEindex, 255, this_bright);
- leds[NUM_LEDS - i - 1] = leds[i];
- HUEindex += HUE_STEP;
- if (HUEindex > 255) HUEindex = 0;
- }
- break;
- }
-}
-
-void HIGHS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(HIGH_COLOR, 255, thisBright[2]);
-}
-void MIDS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(MID_COLOR, 255, thisBright[1]);
-}
-void LOWS() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(LOW_COLOR, 255, thisBright[0]);
-}
-void SILENCE() {
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(EMPTY_COLOR, 255, EMPTY_BRIGHT);
-}
-
-// вспомогательная функция, изменяет величину value на шаг incr в пределах minimum.. maximum
-int smartIncr(int value, int incr_step, int mininmum, int maximum) {
- int val_buf = value + incr_step;
- val_buf = constrain(val_buf, mininmum, maximum);
- return val_buf;
-}
-
-float smartIncrFloat(float value, float incr_step, float mininmum, float maximum) {
- float val_buf = value + incr_step;
- val_buf = constrain(val_buf, mininmum, maximum);
- return val_buf;
-}
-
-#if REMOTE_TYPE != 0
-void remoteTick() {
- if (IRLremote.available()) {
- auto data = IRLremote.read();
- IRdata = data.command;
- ir_flag = true;
- }
- if (ir_flag) { // если данные пришли
- eeprom_timer = millis();
- eeprom_flag = true;
- switch (IRdata) {
- // режимы
- case BUTT_1: this_mode = 0;
- break;
- case BUTT_2: this_mode = 1;
- break;
- case BUTT_3: this_mode = 2;
- break;
- case BUTT_4: this_mode = 3;
- break;
- case BUTT_5: this_mode = 4;
- break;
- case BUTT_6: this_mode = 5;
- break;
- case BUTT_7: this_mode = 6;
- break;
- case BUTT_8: this_mode = 7;
- break;
- case BUTT_9: this_mode = 8;
- break;
- case BUTT_0: fullLowPass();
- break;
- case BUTT_STAR: ONstate = !ONstate; FastLED.clear(); FastLED.show(); updateEEPROM();
- break;
- case BUTT_HASH:
- switch (this_mode) {
- case 4:
- case 7: if (++freq_strobe_mode > 3) freq_strobe_mode = 0;
- break;
- case 6: if (++light_mode > 2) light_mode = 0;
- break;
- }
- break;
- case BUTT_OK: digitalWrite(MLED_PIN, settings_mode ^ MLED_ON); settings_mode = !settings_mode;
- break;
- case BUTT_UP:
- if (settings_mode) {
- // ВВЕРХ общие настройки
- EMPTY_BRIGHT = smartIncr(EMPTY_BRIGHT, 5, 0, 255);
- } else {
- switch (this_mode) {
- case 0:
- break;
- case 1: RAINBOW_STEP = smartIncrFloat(RAINBOW_STEP, 0.5, 0.5, 20);
- break;
- case 2:
- case 3:
- case 4: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, 0.1, 0, 5);
- break;
- case 5: STROBE_PERIOD = smartIncr(STROBE_PERIOD, 20, 1, 1000);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_SAT = smartIncr(LIGHT_SAT, 20, 0, 255);
- break;
- case 1: LIGHT_SAT = smartIncr(LIGHT_SAT, 20, 0, 255);
- break;
- case 2: RAINBOW_STEP_2 = smartIncrFloat(RAINBOW_STEP_2, 0.5, 0.5, 10);
- break;
- }
- break;
- case 7: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, 0.1, 0.0, 10);
- break;
- case 8: HUE_START = smartIncr(HUE_START, 10, 0, 255);
- break;
- }
- }
- break;
- case BUTT_DOWN:
- if (settings_mode) {
- // ВНИЗ общие настройки
- EMPTY_BRIGHT = smartIncr(EMPTY_BRIGHT, -5, 0, 255);
- } else {
- switch (this_mode) {
- case 0:
- break;
- case 1: RAINBOW_STEP = smartIncrFloat(RAINBOW_STEP, -0.5, 0.5, 20);
- break;
- case 2:
- case 3:
- case 4: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, -0.1, 0, 5);
- break;
- case 5: STROBE_PERIOD = smartIncr(STROBE_PERIOD, -20, 1, 1000);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_SAT = smartIncr(LIGHT_SAT, -20, 0, 255);
- break;
- case 1: LIGHT_SAT = smartIncr(LIGHT_SAT, -20, 0, 255);
- break;
- case 2: RAINBOW_STEP_2 = smartIncrFloat(RAINBOW_STEP_2, -0.5, 0.5, 10);
- break;
- }
- break;
- case 7: MAX_COEF_FREQ = smartIncrFloat(MAX_COEF_FREQ, -0.1, 0.0, 10);
- break;
- case 8: HUE_START = smartIncr(HUE_START, -10, 0, 255);
- break;
- }
- }
- break;
- case BUTT_LEFT:
- if (settings_mode) {
- // ВЛЕВО общие настройки
- BRIGHTNESS = smartIncr(BRIGHTNESS, -20, 0, 255);
- FastLED.setBrightness(BRIGHTNESS);
- } else {
- switch (this_mode) {
- case 0:
- case 1: SMOOTH = smartIncrFloat(SMOOTH, -0.05, 0.05, 1);
- break;
- case 2:
- case 3:
- case 4: SMOOTH_FREQ = smartIncrFloat(SMOOTH_FREQ, -0.05, 0.05, 1);
- break;
- case 5: STROBE_SMOOTH = smartIncr(STROBE_SMOOTH, -20, 0, 255);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_COLOR = smartIncr(LIGHT_COLOR, -10, 0, 255);
- break;
- case 1: COLOR_SPEED = smartIncr(COLOR_SPEED, -10, 0, 255);
- break;
- case 2: RAINBOW_PERIOD = smartIncr(RAINBOW_PERIOD, -1, -20, 20);
- break;
- }
- break;
- case 7: RUNNING_SPEED = smartIncr(RUNNING_SPEED, -10, 1, 255);
- break;
- case 8: HUE_STEP = smartIncr(HUE_STEP, -1, 1, 255);
- break;
- }
- }
- break;
- case BUTT_RIGHT:
- if (settings_mode) {
- // ВПРАВО общие настройки
- BRIGHTNESS = smartIncr(BRIGHTNESS, 20, 0, 255);
- FastLED.setBrightness(BRIGHTNESS);
- } else {
- switch (this_mode) {
- case 0:
- case 1: SMOOTH = smartIncrFloat(SMOOTH, 0.05, 0.05, 1);
- break;
- case 2:
- case 3:
- case 4: SMOOTH_FREQ = smartIncrFloat(SMOOTH_FREQ, 0.05, 0.05, 1);
- break;
- case 5: STROBE_SMOOTH = smartIncr(STROBE_SMOOTH, 20, 0, 255);
- break;
- case 6:
- switch (light_mode) {
- case 0: LIGHT_COLOR = smartIncr(LIGHT_COLOR, 10, 0, 255);
- break;
- case 1: COLOR_SPEED = smartIncr(COLOR_SPEED, 10, 0, 255);
- break;
- case 2: RAINBOW_PERIOD = smartIncr(RAINBOW_PERIOD, 1, -20, 20);
- break;
- }
- break;
- case 7: RUNNING_SPEED = smartIncr(RUNNING_SPEED, 10, 1, 255);
- break;
- case 8: HUE_STEP = smartIncr(HUE_STEP, 1, 1, 255);
- break;
- }
- }
- break;
- default: eeprom_flag = false; // если не распознали кнопку, не обновляем настройки!
- break;
- }
- ir_flag = false;
- }
-}
-#endif
-
-void autoLowPass() {
- // для режима VU
- delay(10); // ждём инициализации АЦП
- int thisMax = 0; // максимум
- int thisLevel;
- for (byte i = 0; i < 200; i++) {
- thisLevel = analogRead(SOUND_R); // делаем 200 измерений
- if (thisLevel > thisMax) // ищем максимумы
- thisMax = thisLevel; // запоминаем
- delay(4); // ждём 4мс
- }
- LOW_PASS = thisMax + LOW_PASS_ADD; // нижний порог как максимум тишины + некая величина
-
- // для режима спектра
- thisMax = 0;
- for (byte i = 0; i < 100; i++) { // делаем 100 измерений
- analyzeAudio(); // разбить в спектр
- for (byte j = 2; j < 32; j++) { // первые 2 канала - хлам
- thisLevel = fht_log_out[j];
- if (thisLevel > thisMax) // ищем максимумы
- thisMax = thisLevel; // запоминаем
- }
- delay(4); // ждём 4мс
- }
- SPEKTR_LOW_PASS = thisMax + LOW_PASS_FREQ_ADD; // нижний порог как максимум тишины
- if (EEPROM_LOW_PASS && !AUTO_LOW_PASS) {
- EEPROM.updateInt(70, LOW_PASS);
- EEPROM.updateInt(72, SPEKTR_LOW_PASS);
- }
-}
-
-void analyzeAudio() {
- for (int i = 0 ; i < FHT_N ; i++) {
- int sample = analogRead(SOUND_R_FREQ);
- fht_input[i] = sample; // put real data into bins
- }
- fht_window(); // window the data for better frequency response
- fht_reorder(); // reorder the data before doing the fht
- fht_run(); // process the data in the fht
- fht_mag_log(); // take the output of the fht
-}
-
-void buttonTick() {
- butt1.tick(); // обязательная функция отработки. Должна постоянно опрашиваться
- if (butt1.isSingle()) // если единичное нажатие
- if (++this_mode >= MODE_AMOUNT) this_mode = 0; // изменить режим
-
- if (butt1.isHolded()) { // кнопка удержана
- fullLowPass();
- }
-}
-void fullLowPass() {
- digitalWrite(MLED_PIN, MLED_ON); // включить светодиод
- FastLED.setBrightness(0); // погасить ленту
- FastLED.clear(); // очистить массив пикселей
- FastLED.show(); // отправить значения на ленту
- delay(500); // подождать чутка
- autoLowPass(); // измерить шумы
- delay(500); // подождать
- FastLED.setBrightness(BRIGHTNESS); // вернуть яркость
- digitalWrite(MLED_PIN, !MLED_ON); // выключить светодиод
-}
-void updateEEPROM() {
- EEPROM.updateByte(1, this_mode);
- EEPROM.updateByte(2, freq_strobe_mode);
- EEPROM.updateByte(3, light_mode);
- EEPROM.updateInt(4, RAINBOW_STEP);
- EEPROM.updateFloat(8, MAX_COEF_FREQ);
- EEPROM.updateInt(12, STROBE_PERIOD);
- EEPROM.updateInt(16, LIGHT_SAT);
- EEPROM.updateFloat(20, RAINBOW_STEP_2);
- EEPROM.updateInt(24, HUE_START);
- EEPROM.updateFloat(28, SMOOTH);
- EEPROM.updateFloat(32, SMOOTH_FREQ);
- EEPROM.updateInt(36, STROBE_SMOOTH);
- EEPROM.updateInt(40, LIGHT_COLOR);
- EEPROM.updateInt(44, COLOR_SPEED);
- EEPROM.updateInt(48, RAINBOW_PERIOD);
- EEPROM.updateInt(52, RUNNING_SPEED);
- EEPROM.updateInt(56, HUE_STEP);
- EEPROM.updateInt(60, EMPTY_BRIGHT);
- if (KEEP_STATE) EEPROM.updateByte(64, ONstate);
-}
-void readEEPROM() {
- this_mode = EEPROM.readByte(1);
- freq_strobe_mode = EEPROM.readByte(2);
- light_mode = EEPROM.readByte(3);
- RAINBOW_STEP = EEPROM.readInt(4);
- MAX_COEF_FREQ = EEPROM.readFloat(8);
- STROBE_PERIOD = EEPROM.readInt(12);
- LIGHT_SAT = EEPROM.readInt(16);
- RAINBOW_STEP_2 = EEPROM.readFloat(20);
- HUE_START = EEPROM.readInt(24);
- SMOOTH = EEPROM.readFloat(28);
- SMOOTH_FREQ = EEPROM.readFloat(32);
- STROBE_SMOOTH = EEPROM.readInt(36);
- LIGHT_COLOR = EEPROM.readInt(40);
- COLOR_SPEED = EEPROM.readInt(44);
- RAINBOW_PERIOD = EEPROM.readInt(48);
- RUNNING_SPEED = EEPROM.readInt(52);
- HUE_STEP = EEPROM.readInt(56);
- EMPTY_BRIGHT = EEPROM.readInt(60);
- if (KEEP_STATE) ONstate = EEPROM.readByte(64);
-}
-void eepromTick() {
- if (eeprom_flag)
- if (millis() - eeprom_timer > 30000) { // 30 секунд после последнего нажатия с пульта
- eeprom_flag = false;
- eeprom_timer = millis();
- updateEEPROM();
- }
-}
diff --git a/history.md b/history.md
new file mode 100644
index 0000000..199c934
--- /dev/null
+++ b/history.md
@@ -0,0 +1,25 @@
+**2020.11.05**
+
+- version: 1.1.1
+- add: BRIGHTNESS is stored in EEPROM now and loaded at colormusic start up (if `EEPROM_LOW_PASS 1`);
+- upd: EEPROM optimised - correct data types are stored and read;
+- fix: `LOW_PASS` and `SPEKTR_LOW_PASS` had wrong sizes in EEPROM. Now they occupy 4 bytes each, so are compatible with SAMD chips integer data type size.
+
+**2020.11.04**
+
+- version: 1.1.0
+- fix: variable `light_time` is initialised properly - after `STROBE_PERIOD` initialisation.
+- add: now settings could be changed with the only one button (it's a madness). No need for a remote control. Variables' limits and changing steps are different for IR remote and button. It is made for convenient usage.
+- upd: button behaviour
+- upd: variables' limits and changing steps have been changed so that it is more convenient to adjust them with one button.
+- upd: stroboscope now has a specific set of frequencies:
+ 25 Hz (1500 BPM - trance music x10), 20 Hz (1200 BPM - dance music x10), 15 Hz (900 BPM), 10 Hz (600 BPM) and 5 Hz (300 BPM).
+- upd: some comments were translated.
+
+**2020.06.18**
+
+Regarding the Gyver's version 2.10
+- version: 1.0.0
+- fix: despite `define KEEP_SETTINGS 0`, EEPROM was updated from procedure `loop()`.
+- fix: variables eeprom_flag and eeprom_timer were not defined. With no remote controls (#if REMOTE_TYPE != 0) they remained undefined.
+- add: update `this_mode` in EEPROM after changing it by the button, not only IR remote.
\ No newline at end of file
diff --git a/libraries/Adafruit_NeoPixel-master/.github/ISSUE_TEMPLATE.md b/libraries/Adafruit_NeoPixel/.github/ISSUE_TEMPLATE.md
similarity index 100%
rename from libraries/Adafruit_NeoPixel-master/.github/ISSUE_TEMPLATE.md
rename to libraries/Adafruit_NeoPixel/.github/ISSUE_TEMPLATE.md
diff --git a/libraries/Adafruit_NeoPixel-master/.github/PULL_REQUEST_TEMPLATE.md b/libraries/Adafruit_NeoPixel/.github/PULL_REQUEST_TEMPLATE.md
similarity index 100%
rename from libraries/Adafruit_NeoPixel-master/.github/PULL_REQUEST_TEMPLATE.md
rename to libraries/Adafruit_NeoPixel/.github/PULL_REQUEST_TEMPLATE.md
diff --git a/libraries/Adafruit_NeoPixel-master/.travis.yml b/libraries/Adafruit_NeoPixel/.travis.yml
similarity index 100%
rename from libraries/Adafruit_NeoPixel-master/.travis.yml
rename to libraries/Adafruit_NeoPixel/.travis.yml
diff --git a/libraries/Adafruit_NeoPixel-master/Adafruit_NeoPixel.cpp b/libraries/Adafruit_NeoPixel/Adafruit_NeoPixel.cpp
similarity index 100%
rename from libraries/Adafruit_NeoPixel-master/Adafruit_NeoPixel.cpp
rename to libraries/Adafruit_NeoPixel/Adafruit_NeoPixel.cpp
diff --git a/libraries/Adafruit_NeoPixel-master/Adafruit_NeoPixel.h b/libraries/Adafruit_NeoPixel/Adafruit_NeoPixel.h
similarity index 100%
rename from libraries/Adafruit_NeoPixel-master/Adafruit_NeoPixel.h
rename to libraries/Adafruit_NeoPixel/Adafruit_NeoPixel.h
diff --git a/libraries/Adafruit_NeoPixel-master/COPYING b/libraries/Adafruit_NeoPixel/COPYING
similarity index 100%
rename from libraries/Adafruit_NeoPixel-master/COPYING
rename to libraries/Adafruit_NeoPixel/COPYING
diff --git a/libraries/Adafruit_NeoPixel-master/README.md b/libraries/Adafruit_NeoPixel/README.md
similarity index 100%
rename from libraries/Adafruit_NeoPixel-master/README.md
rename to libraries/Adafruit_NeoPixel/README.md
diff --git a/libraries/Adafruit_NeoPixel-master/esp8266.c b/libraries/Adafruit_NeoPixel/esp8266.c
similarity index 100%
rename from libraries/Adafruit_NeoPixel-master/esp8266.c
rename to libraries/Adafruit_NeoPixel/esp8266.c
diff --git a/libraries/Adafruit_NeoPixel-master/examples/RGBWstrandtest/.esp8266.test.skip b/libraries/Adafruit_NeoPixel/examples/RGBWstrandtest/.esp8266.test.skip
similarity index 100%
rename from libraries/Adafruit_NeoPixel-master/examples/RGBWstrandtest/.esp8266.test.skip
rename to libraries/Adafruit_NeoPixel/examples/RGBWstrandtest/.esp8266.test.skip
diff --git a/libraries/Adafruit_NeoPixel-master/examples/RGBWstrandtest/.trinket.test.skip b/libraries/Adafruit_NeoPixel/examples/RGBWstrandtest/.trinket.test.skip
similarity index 100%
rename from libraries/Adafruit_NeoPixel-master/examples/RGBWstrandtest/.trinket.test.skip
rename to libraries/Adafruit_NeoPixel/examples/RGBWstrandtest/.trinket.test.skip
diff --git a/libraries/Adafruit_NeoPixel-master/examples/RGBWstrandtest/RGBWstrandtest.ino b/libraries/Adafruit_NeoPixel/examples/RGBWstrandtest/RGBWstrandtest.ino
similarity index 100%
rename from libraries/Adafruit_NeoPixel-master/examples/RGBWstrandtest/RGBWstrandtest.ino
rename to libraries/Adafruit_NeoPixel/examples/RGBWstrandtest/RGBWstrandtest.ino
diff --git a/libraries/Adafruit_NeoPixel-master/examples/StrandtestBLE/.test.skip b/libraries/Adafruit_NeoPixel/examples/StrandtestBLE/.test.skip
similarity index 100%
rename from libraries/Adafruit_NeoPixel-master/examples/StrandtestBLE/.test.skip
rename to libraries/Adafruit_NeoPixel/examples/StrandtestBLE/.test.skip
diff --git a/libraries/Adafruit_NeoPixel-master/examples/StrandtestBLE/BLESerial.cpp b/libraries/Adafruit_NeoPixel/examples/StrandtestBLE/BLESerial.cpp
similarity index 100%
rename from libraries/Adafruit_NeoPixel-master/examples/StrandtestBLE/BLESerial.cpp
rename to libraries/Adafruit_NeoPixel/examples/StrandtestBLE/BLESerial.cpp
diff --git a/libraries/Adafruit_NeoPixel-master/examples/StrandtestBLE/BLESerial.h b/libraries/Adafruit_NeoPixel/examples/StrandtestBLE/BLESerial.h
similarity index 100%
rename from libraries/Adafruit_NeoPixel-master/examples/StrandtestBLE/BLESerial.h
rename to libraries/Adafruit_NeoPixel/examples/StrandtestBLE/BLESerial.h
diff --git a/libraries/Adafruit_NeoPixel-master/examples/StrandtestBLE/StrandtestBLE.ino b/libraries/Adafruit_NeoPixel/examples/StrandtestBLE/StrandtestBLE.ino
similarity index 100%
rename from libraries/Adafruit_NeoPixel-master/examples/StrandtestBLE/StrandtestBLE.ino
rename to libraries/Adafruit_NeoPixel/examples/StrandtestBLE/StrandtestBLE.ino
diff --git a/libraries/Adafruit_NeoPixel-master/examples/buttoncycler/.esp8266.test.skip b/libraries/Adafruit_NeoPixel/examples/buttoncycler/.esp8266.test.skip
similarity index 100%
rename from libraries/Adafruit_NeoPixel-master/examples/buttoncycler/.esp8266.test.skip
rename to libraries/Adafruit_NeoPixel/examples/buttoncycler/.esp8266.test.skip
diff --git a/libraries/Adafruit_NeoPixel-master/examples/buttoncycler/buttoncycler.ino b/libraries/Adafruit_NeoPixel/examples/buttoncycler/buttoncycler.ino
similarity index 100%
rename from libraries/Adafruit_NeoPixel-master/examples/buttoncycler/buttoncycler.ino
rename to libraries/Adafruit_NeoPixel/examples/buttoncycler/buttoncycler.ino
diff --git a/libraries/Adafruit_NeoPixel-master/examples/simple/.esp8266.test.skip b/libraries/Adafruit_NeoPixel/examples/simple/.esp8266.test.skip
similarity index 100%
rename from libraries/Adafruit_NeoPixel-master/examples/simple/.esp8266.test.skip
rename to libraries/Adafruit_NeoPixel/examples/simple/.esp8266.test.skip
diff --git a/libraries/Adafruit_NeoPixel-master/examples/simple/simple.ino b/libraries/Adafruit_NeoPixel/examples/simple/simple.ino
similarity index 100%
rename from libraries/Adafruit_NeoPixel-master/examples/simple/simple.ino
rename to libraries/Adafruit_NeoPixel/examples/simple/simple.ino
diff --git a/libraries/Adafruit_NeoPixel-master/examples/strandtest/.esp8266.test.skip b/libraries/Adafruit_NeoPixel/examples/strandtest/.esp8266.test.skip
similarity index 100%
rename from libraries/Adafruit_NeoPixel-master/examples/strandtest/.esp8266.test.skip
rename to libraries/Adafruit_NeoPixel/examples/strandtest/.esp8266.test.skip
diff --git a/libraries/Adafruit_NeoPixel-master/examples/strandtest/strandtest.ino b/libraries/Adafruit_NeoPixel/examples/strandtest/strandtest.ino
similarity index 100%
rename from libraries/Adafruit_NeoPixel-master/examples/strandtest/strandtest.ino
rename to libraries/Adafruit_NeoPixel/examples/strandtest/strandtest.ino
diff --git a/libraries/Adafruit_NeoPixel-master/keywords.txt b/libraries/Adafruit_NeoPixel/keywords.txt
similarity index 100%
rename from libraries/Adafruit_NeoPixel-master/keywords.txt
rename to libraries/Adafruit_NeoPixel/keywords.txt
diff --git a/libraries/Adafruit_NeoPixel-master/library.properties b/libraries/Adafruit_NeoPixel/library.properties
similarity index 100%
rename from libraries/Adafruit_NeoPixel-master/library.properties
rename to libraries/Adafruit_NeoPixel/library.properties
diff --git a/libraries/FastLED-master/.gitignore b/libraries/FastLED/.gitignore
similarity index 100%
rename from libraries/FastLED-master/.gitignore
rename to libraries/FastLED/.gitignore
diff --git a/libraries/FastLED-master/FastLED.cpp b/libraries/FastLED/FastLED.cpp
similarity index 100%
rename from libraries/FastLED-master/FastLED.cpp
rename to libraries/FastLED/FastLED.cpp
diff --git a/libraries/FastLED-master/FastLED.h b/libraries/FastLED/FastLED.h
similarity index 100%
rename from libraries/FastLED-master/FastLED.h
rename to libraries/FastLED/FastLED.h
diff --git a/libraries/FastLED-master/LICENSE b/libraries/FastLED/LICENSE
similarity index 100%
rename from libraries/FastLED-master/LICENSE
rename to libraries/FastLED/LICENSE
diff --git a/libraries/FastLED-master/PORTING.md b/libraries/FastLED/PORTING.md
similarity index 100%
rename from libraries/FastLED-master/PORTING.md
rename to libraries/FastLED/PORTING.md
diff --git a/libraries/FastLED-master/README.md b/libraries/FastLED/README.md
similarity index 100%
rename from libraries/FastLED-master/README.md
rename to libraries/FastLED/README.md
diff --git a/libraries/FastLED-master/bitswap.cpp b/libraries/FastLED/bitswap.cpp
similarity index 100%
rename from libraries/FastLED-master/bitswap.cpp
rename to libraries/FastLED/bitswap.cpp
diff --git a/libraries/FastLED-master/bitswap.h b/libraries/FastLED/bitswap.h
similarity index 100%
rename from libraries/FastLED-master/bitswap.h
rename to libraries/FastLED/bitswap.h
diff --git a/libraries/FastLED-master/chipsets.h b/libraries/FastLED/chipsets.h
similarity index 100%
rename from libraries/FastLED-master/chipsets.h
rename to libraries/FastLED/chipsets.h
diff --git a/libraries/FastLED-master/color.h b/libraries/FastLED/color.h
similarity index 100%
rename from libraries/FastLED-master/color.h
rename to libraries/FastLED/color.h
diff --git a/libraries/FastLED-master/colorpalettes.cpp b/libraries/FastLED/colorpalettes.cpp
similarity index 100%
rename from libraries/FastLED-master/colorpalettes.cpp
rename to libraries/FastLED/colorpalettes.cpp
diff --git a/libraries/FastLED-master/colorpalettes.h b/libraries/FastLED/colorpalettes.h
similarity index 100%
rename from libraries/FastLED-master/colorpalettes.h
rename to libraries/FastLED/colorpalettes.h
diff --git a/libraries/FastLED-master/colorutils.cpp b/libraries/FastLED/colorutils.cpp
similarity index 100%
rename from libraries/FastLED-master/colorutils.cpp
rename to libraries/FastLED/colorutils.cpp
diff --git a/libraries/FastLED-master/colorutils.h b/libraries/FastLED/colorutils.h
similarity index 100%
rename from libraries/FastLED-master/colorutils.h
rename to libraries/FastLED/colorutils.h
diff --git a/libraries/FastLED-master/controller.h b/libraries/FastLED/controller.h
similarity index 100%
rename from libraries/FastLED-master/controller.h
rename to libraries/FastLED/controller.h
diff --git a/libraries/FastLED-master/cpp_compat.h b/libraries/FastLED/cpp_compat.h
similarity index 100%
rename from libraries/FastLED-master/cpp_compat.h
rename to libraries/FastLED/cpp_compat.h
diff --git a/libraries/FastLED-master/dmx.h b/libraries/FastLED/dmx.h
similarity index 100%
rename from libraries/FastLED-master/dmx.h
rename to libraries/FastLED/dmx.h
diff --git a/libraries/FastLED-master/docs/Doxyfile b/libraries/FastLED/docs/Doxyfile
similarity index 100%
rename from libraries/FastLED-master/docs/Doxyfile
rename to libraries/FastLED/docs/Doxyfile
diff --git a/libraries/FastLED-master/docs/mainpage.dox b/libraries/FastLED/docs/mainpage.dox
similarity index 100%
rename from libraries/FastLED-master/docs/mainpage.dox
rename to libraries/FastLED/docs/mainpage.dox
diff --git a/libraries/FastLED-master/examples/AnalogOutput/AnalogOutput.ino b/libraries/FastLED/examples/AnalogOutput/AnalogOutput.ino
similarity index 100%
rename from libraries/FastLED-master/examples/AnalogOutput/AnalogOutput.ino
rename to libraries/FastLED/examples/AnalogOutput/AnalogOutput.ino
diff --git a/libraries/FastLED-master/examples/Blink/Blink.ino b/libraries/FastLED/examples/Blink/Blink.ino
similarity index 100%
rename from libraries/FastLED-master/examples/Blink/Blink.ino
rename to libraries/FastLED/examples/Blink/Blink.ino
diff --git a/libraries/FastLED-master/examples/ColorPalette/ColorPalette.ino b/libraries/FastLED/examples/ColorPalette/ColorPalette.ino
similarity index 100%
rename from libraries/FastLED-master/examples/ColorPalette/ColorPalette.ino
rename to libraries/FastLED/examples/ColorPalette/ColorPalette.ino
diff --git a/libraries/FastLED-master/examples/ColorTemperature/ColorTemperature.ino b/libraries/FastLED/examples/ColorTemperature/ColorTemperature.ino
similarity index 100%
rename from libraries/FastLED-master/examples/ColorTemperature/ColorTemperature.ino
rename to libraries/FastLED/examples/ColorTemperature/ColorTemperature.ino
diff --git a/libraries/FastLED-master/examples/Cylon/Cylon.ino b/libraries/FastLED/examples/Cylon/Cylon.ino
similarity index 100%
rename from libraries/FastLED-master/examples/Cylon/Cylon.ino
rename to libraries/FastLED/examples/Cylon/Cylon.ino
diff --git a/libraries/FastLED-master/examples/DemoReel100/DemoReel100.ino b/libraries/FastLED/examples/DemoReel100/DemoReel100.ino
similarity index 100%
rename from libraries/FastLED-master/examples/DemoReel100/DemoReel100.ino
rename to libraries/FastLED/examples/DemoReel100/DemoReel100.ino
diff --git a/libraries/FastLED-master/examples/DemoReelESP32/DemoReelESP32.ino b/libraries/FastLED/examples/DemoReelESP32/DemoReelESP32.ino
similarity index 100%
rename from libraries/FastLED-master/examples/DemoReelESP32/DemoReelESP32.ino
rename to libraries/FastLED/examples/DemoReelESP32/DemoReelESP32.ino
diff --git a/libraries/FastLED-master/examples/Fire2012/Fire2012.ino b/libraries/FastLED/examples/Fire2012/Fire2012.ino
similarity index 100%
rename from libraries/FastLED-master/examples/Fire2012/Fire2012.ino
rename to libraries/FastLED/examples/Fire2012/Fire2012.ino
diff --git a/libraries/FastLED-master/examples/Fire2012WithPalette/Fire2012WithPalette.ino b/libraries/FastLED/examples/Fire2012WithPalette/Fire2012WithPalette.ino
similarity index 100%
rename from libraries/FastLED-master/examples/Fire2012WithPalette/Fire2012WithPalette.ino
rename to libraries/FastLED/examples/Fire2012WithPalette/Fire2012WithPalette.ino
diff --git a/libraries/FastLED-master/examples/FirstLight/FirstLight.ino b/libraries/FastLED/examples/FirstLight/FirstLight.ino
similarity index 100%
rename from libraries/FastLED-master/examples/FirstLight/FirstLight.ino
rename to libraries/FastLED/examples/FirstLight/FirstLight.ino
diff --git a/libraries/FastLED-master/examples/Multiple/ArrayOfLedArrays/ArrayOfLedArrays.ino b/libraries/FastLED/examples/Multiple/ArrayOfLedArrays/ArrayOfLedArrays.ino
similarity index 100%
rename from libraries/FastLED-master/examples/Multiple/ArrayOfLedArrays/ArrayOfLedArrays.ino
rename to libraries/FastLED/examples/Multiple/ArrayOfLedArrays/ArrayOfLedArrays.ino
diff --git a/libraries/FastLED-master/examples/Multiple/MirroringSample/MirroringSample.ino b/libraries/FastLED/examples/Multiple/MirroringSample/MirroringSample.ino
similarity index 100%
rename from libraries/FastLED-master/examples/Multiple/MirroringSample/MirroringSample.ino
rename to libraries/FastLED/examples/Multiple/MirroringSample/MirroringSample.ino
diff --git a/libraries/FastLED-master/examples/Multiple/MultiArrays/MultiArrays.ino b/libraries/FastLED/examples/Multiple/MultiArrays/MultiArrays.ino
similarity index 100%
rename from libraries/FastLED-master/examples/Multiple/MultiArrays/MultiArrays.ino
rename to libraries/FastLED/examples/Multiple/MultiArrays/MultiArrays.ino
diff --git a/libraries/FastLED-master/examples/Multiple/MultipleStripsInOneArray/MultipleStripsInOneArray.ino b/libraries/FastLED/examples/Multiple/MultipleStripsInOneArray/MultipleStripsInOneArray.ino
similarity index 100%
rename from libraries/FastLED-master/examples/Multiple/MultipleStripsInOneArray/MultipleStripsInOneArray.ino
rename to libraries/FastLED/examples/Multiple/MultipleStripsInOneArray/MultipleStripsInOneArray.ino
diff --git a/libraries/FastLED-master/examples/Multiple/OctoWS2811Demo/OctoWS2811Demo.ino b/libraries/FastLED/examples/Multiple/OctoWS2811Demo/OctoWS2811Demo.ino
similarity index 100%
rename from libraries/FastLED-master/examples/Multiple/OctoWS2811Demo/OctoWS2811Demo.ino
rename to libraries/FastLED/examples/Multiple/OctoWS2811Demo/OctoWS2811Demo.ino
diff --git a/libraries/FastLED-master/examples/Multiple/ParallelOutputDemo/ParallelOutputDemo.ino b/libraries/FastLED/examples/Multiple/ParallelOutputDemo/ParallelOutputDemo.ino
similarity index 100%
rename from libraries/FastLED-master/examples/Multiple/ParallelOutputDemo/ParallelOutputDemo.ino
rename to libraries/FastLED/examples/Multiple/ParallelOutputDemo/ParallelOutputDemo.ino
diff --git a/libraries/FastLED-master/examples/Noise/Noise.ino b/libraries/FastLED/examples/Noise/Noise.ino
similarity index 100%
rename from libraries/FastLED-master/examples/Noise/Noise.ino
rename to libraries/FastLED/examples/Noise/Noise.ino
diff --git a/libraries/FastLED-master/examples/NoisePlayground/NoisePlayground.ino b/libraries/FastLED/examples/NoisePlayground/NoisePlayground.ino
similarity index 100%
rename from libraries/FastLED-master/examples/NoisePlayground/NoisePlayground.ino
rename to libraries/FastLED/examples/NoisePlayground/NoisePlayground.ino
diff --git a/libraries/FastLED-master/examples/NoisePlusPalette/NoisePlusPalette.ino b/libraries/FastLED/examples/NoisePlusPalette/NoisePlusPalette.ino
similarity index 100%
rename from libraries/FastLED-master/examples/NoisePlusPalette/NoisePlusPalette.ino
rename to libraries/FastLED/examples/NoisePlusPalette/NoisePlusPalette.ino
diff --git a/libraries/FastLED-master/examples/Pintest/Pintest.ino b/libraries/FastLED/examples/Pintest/Pintest.ino
similarity index 100%
rename from libraries/FastLED-master/examples/Pintest/Pintest.ino
rename to libraries/FastLED/examples/Pintest/Pintest.ino
diff --git a/libraries/FastLED-master/examples/Ports/PJRCSpectrumAnalyzer/PJRCSpectrumAnalyzer.ino b/libraries/FastLED/examples/Ports/PJRCSpectrumAnalyzer/PJRCSpectrumAnalyzer.ino
similarity index 100%
rename from libraries/FastLED-master/examples/Ports/PJRCSpectrumAnalyzer/PJRCSpectrumAnalyzer.ino
rename to libraries/FastLED/examples/Ports/PJRCSpectrumAnalyzer/PJRCSpectrumAnalyzer.ino
diff --git a/libraries/FastLED-master/examples/RGBCalibrate/RGBCalibrate.ino b/libraries/FastLED/examples/RGBCalibrate/RGBCalibrate.ino
similarity index 100%
rename from libraries/FastLED-master/examples/RGBCalibrate/RGBCalibrate.ino
rename to libraries/FastLED/examples/RGBCalibrate/RGBCalibrate.ino
diff --git a/libraries/FastLED-master/examples/RGBSetDemo/RGBSetDemo.ino b/libraries/FastLED/examples/RGBSetDemo/RGBSetDemo.ino
similarity index 100%
rename from libraries/FastLED-master/examples/RGBSetDemo/RGBSetDemo.ino
rename to libraries/FastLED/examples/RGBSetDemo/RGBSetDemo.ino
diff --git a/libraries/FastLED-master/examples/SmartMatrix/SmartMatrix.ino b/libraries/FastLED/examples/SmartMatrix/SmartMatrix.ino
similarity index 100%
rename from libraries/FastLED-master/examples/SmartMatrix/SmartMatrix.ino
rename to libraries/FastLED/examples/SmartMatrix/SmartMatrix.ino
diff --git a/libraries/FastLED-master/examples/XYMatrix/XYMatrix.ino b/libraries/FastLED/examples/XYMatrix/XYMatrix.ino
similarity index 100%
rename from libraries/FastLED-master/examples/XYMatrix/XYMatrix.ino
rename to libraries/FastLED/examples/XYMatrix/XYMatrix.ino
diff --git a/libraries/FastLED-master/extras/AppleII.s65 b/libraries/FastLED/extras/AppleII.s65
similarity index 100%
rename from libraries/FastLED-master/extras/AppleII.s65
rename to libraries/FastLED/extras/AppleII.s65
diff --git a/libraries/FastLED-master/extras/FastLED6502.s65 b/libraries/FastLED/extras/FastLED6502.s65
similarity index 100%
rename from libraries/FastLED-master/extras/FastLED6502.s65
rename to libraries/FastLED/extras/FastLED6502.s65
diff --git a/libraries/FastLED-master/extras/RainbowDemo.bin.zip b/libraries/FastLED/extras/RainbowDemo.bin.zip
similarity index 100%
rename from libraries/FastLED-master/extras/RainbowDemo.bin.zip
rename to libraries/FastLED/extras/RainbowDemo.bin.zip
diff --git a/libraries/FastLED-master/extras/RainbowDemo.s65 b/libraries/FastLED/extras/RainbowDemo.s65
similarity index 100%
rename from libraries/FastLED-master/extras/RainbowDemo.s65
rename to libraries/FastLED/extras/RainbowDemo.s65
diff --git a/libraries/FastLED-master/fastled_config.h b/libraries/FastLED/fastled_config.h
similarity index 100%
rename from libraries/FastLED-master/fastled_config.h
rename to libraries/FastLED/fastled_config.h
diff --git a/libraries/FastLED-master/fastled_delay.h b/libraries/FastLED/fastled_delay.h
similarity index 100%
rename from libraries/FastLED-master/fastled_delay.h
rename to libraries/FastLED/fastled_delay.h
diff --git a/libraries/FastLED-master/fastled_progmem.h b/libraries/FastLED/fastled_progmem.h
similarity index 100%
rename from libraries/FastLED-master/fastled_progmem.h
rename to libraries/FastLED/fastled_progmem.h
diff --git a/libraries/FastLED-master/fastpin.h b/libraries/FastLED/fastpin.h
similarity index 100%
rename from libraries/FastLED-master/fastpin.h
rename to libraries/FastLED/fastpin.h
diff --git a/libraries/FastLED-master/fastspi.h b/libraries/FastLED/fastspi.h
similarity index 100%
rename from libraries/FastLED-master/fastspi.h
rename to libraries/FastLED/fastspi.h
diff --git a/libraries/FastLED-master/fastspi_bitbang.h b/libraries/FastLED/fastspi_bitbang.h
similarity index 100%
rename from libraries/FastLED-master/fastspi_bitbang.h
rename to libraries/FastLED/fastspi_bitbang.h
diff --git a/libraries/FastLED-master/fastspi_dma.h b/libraries/FastLED/fastspi_dma.h
similarity index 100%
rename from libraries/FastLED-master/fastspi_dma.h
rename to libraries/FastLED/fastspi_dma.h
diff --git a/libraries/FastLED-master/fastspi_nop.h b/libraries/FastLED/fastspi_nop.h
similarity index 100%
rename from libraries/FastLED-master/fastspi_nop.h
rename to libraries/FastLED/fastspi_nop.h
diff --git a/libraries/FastLED-master/fastspi_ref.h b/libraries/FastLED/fastspi_ref.h
similarity index 100%
rename from libraries/FastLED-master/fastspi_ref.h
rename to libraries/FastLED/fastspi_ref.h
diff --git a/libraries/FastLED-master/fastspi_types.h b/libraries/FastLED/fastspi_types.h
similarity index 100%
rename from libraries/FastLED-master/fastspi_types.h
rename to libraries/FastLED/fastspi_types.h
diff --git a/libraries/FastLED-master/hsv2rgb.cpp b/libraries/FastLED/hsv2rgb.cpp
similarity index 100%
rename from libraries/FastLED-master/hsv2rgb.cpp
rename to libraries/FastLED/hsv2rgb.cpp
diff --git a/libraries/FastLED-master/hsv2rgb.h b/libraries/FastLED/hsv2rgb.h
similarity index 100%
rename from libraries/FastLED-master/hsv2rgb.h
rename to libraries/FastLED/hsv2rgb.h
diff --git a/libraries/FastLED-master/keywords.txt b/libraries/FastLED/keywords.txt
similarity index 100%
rename from libraries/FastLED-master/keywords.txt
rename to libraries/FastLED/keywords.txt
diff --git a/libraries/FastLED-master/led_sysdefs.h b/libraries/FastLED/led_sysdefs.h
similarity index 100%
rename from libraries/FastLED-master/led_sysdefs.h
rename to libraries/FastLED/led_sysdefs.h
diff --git a/libraries/FastLED-master/lib8tion.cpp b/libraries/FastLED/lib8tion.cpp
similarity index 100%
rename from libraries/FastLED-master/lib8tion.cpp
rename to libraries/FastLED/lib8tion.cpp
diff --git a/libraries/FastLED-master/lib8tion.h b/libraries/FastLED/lib8tion.h
similarity index 100%
rename from libraries/FastLED-master/lib8tion.h
rename to libraries/FastLED/lib8tion.h
diff --git a/libraries/FastLED-master/lib8tion/math8.h b/libraries/FastLED/lib8tion/math8.h
similarity index 100%
rename from libraries/FastLED-master/lib8tion/math8.h
rename to libraries/FastLED/lib8tion/math8.h
diff --git a/libraries/FastLED-master/lib8tion/random8.h b/libraries/FastLED/lib8tion/random8.h
similarity index 100%
rename from libraries/FastLED-master/lib8tion/random8.h
rename to libraries/FastLED/lib8tion/random8.h
diff --git a/libraries/FastLED-master/lib8tion/scale8.h b/libraries/FastLED/lib8tion/scale8.h
similarity index 100%
rename from libraries/FastLED-master/lib8tion/scale8.h
rename to libraries/FastLED/lib8tion/scale8.h
diff --git a/libraries/FastLED-master/lib8tion/trig8.h b/libraries/FastLED/lib8tion/trig8.h
similarity index 100%
rename from libraries/FastLED-master/lib8tion/trig8.h
rename to libraries/FastLED/lib8tion/trig8.h
diff --git a/libraries/FastLED-master/library.json b/libraries/FastLED/library.json
similarity index 100%
rename from libraries/FastLED-master/library.json
rename to libraries/FastLED/library.json
diff --git a/libraries/FastLED-master/library.properties b/libraries/FastLED/library.properties
similarity index 100%
rename from libraries/FastLED-master/library.properties
rename to libraries/FastLED/library.properties
diff --git a/libraries/FastLED-master/noise.cpp b/libraries/FastLED/noise.cpp
similarity index 100%
rename from libraries/FastLED-master/noise.cpp
rename to libraries/FastLED/noise.cpp
diff --git a/libraries/FastLED-master/noise.h b/libraries/FastLED/noise.h
similarity index 100%
rename from libraries/FastLED-master/noise.h
rename to libraries/FastLED/noise.h
diff --git a/libraries/FastLED-master/pixelset.h b/libraries/FastLED/pixelset.h
similarity index 100%
rename from libraries/FastLED-master/pixelset.h
rename to libraries/FastLED/pixelset.h
diff --git a/libraries/FastLED-master/pixeltypes.h b/libraries/FastLED/pixeltypes.h
similarity index 100%
rename from libraries/FastLED-master/pixeltypes.h
rename to libraries/FastLED/pixeltypes.h
diff --git a/libraries/FastLED-master/platforms.h b/libraries/FastLED/platforms.h
similarity index 100%
rename from libraries/FastLED-master/platforms.h
rename to libraries/FastLED/platforms.h
diff --git a/libraries/FastLED-master/platforms/arm/common/m0clockless.h b/libraries/FastLED/platforms/arm/common/m0clockless.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/common/m0clockless.h
rename to libraries/FastLED/platforms/arm/common/m0clockless.h
diff --git a/libraries/FastLED-master/platforms/arm/d21/clockless_arm_d21.h b/libraries/FastLED/platforms/arm/d21/clockless_arm_d21.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/d21/clockless_arm_d21.h
rename to libraries/FastLED/platforms/arm/d21/clockless_arm_d21.h
diff --git a/libraries/FastLED-master/platforms/arm/d21/fastled_arm_d21.h b/libraries/FastLED/platforms/arm/d21/fastled_arm_d21.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/d21/fastled_arm_d21.h
rename to libraries/FastLED/platforms/arm/d21/fastled_arm_d21.h
diff --git a/libraries/FastLED-master/platforms/arm/d21/fastpin_arm_d21.h b/libraries/FastLED/platforms/arm/d21/fastpin_arm_d21.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/d21/fastpin_arm_d21.h
rename to libraries/FastLED/platforms/arm/d21/fastpin_arm_d21.h
diff --git a/libraries/FastLED-master/platforms/arm/d21/led_sysdefs_arm_d21.h b/libraries/FastLED/platforms/arm/d21/led_sysdefs_arm_d21.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/d21/led_sysdefs_arm_d21.h
rename to libraries/FastLED/platforms/arm/d21/led_sysdefs_arm_d21.h
diff --git a/libraries/FastLED-master/platforms/arm/k20/clockless_arm_k20.h b/libraries/FastLED/platforms/arm/k20/clockless_arm_k20.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/k20/clockless_arm_k20.h
rename to libraries/FastLED/platforms/arm/k20/clockless_arm_k20.h
diff --git a/libraries/FastLED-master/platforms/arm/k20/clockless_block_arm_k20.h b/libraries/FastLED/platforms/arm/k20/clockless_block_arm_k20.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/k20/clockless_block_arm_k20.h
rename to libraries/FastLED/platforms/arm/k20/clockless_block_arm_k20.h
diff --git a/libraries/FastLED-master/platforms/arm/k20/fastled_arm_k20.h b/libraries/FastLED/platforms/arm/k20/fastled_arm_k20.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/k20/fastled_arm_k20.h
rename to libraries/FastLED/platforms/arm/k20/fastled_arm_k20.h
diff --git a/libraries/FastLED-master/platforms/arm/k20/fastpin_arm_k20.h b/libraries/FastLED/platforms/arm/k20/fastpin_arm_k20.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/k20/fastpin_arm_k20.h
rename to libraries/FastLED/platforms/arm/k20/fastpin_arm_k20.h
diff --git a/libraries/FastLED-master/platforms/arm/k20/fastspi_arm_k20.h b/libraries/FastLED/platforms/arm/k20/fastspi_arm_k20.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/k20/fastspi_arm_k20.h
rename to libraries/FastLED/platforms/arm/k20/fastspi_arm_k20.h
diff --git a/libraries/FastLED-master/platforms/arm/k20/led_sysdefs_arm_k20.h b/libraries/FastLED/platforms/arm/k20/led_sysdefs_arm_k20.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/k20/led_sysdefs_arm_k20.h
rename to libraries/FastLED/platforms/arm/k20/led_sysdefs_arm_k20.h
diff --git a/libraries/FastLED-master/platforms/arm/k20/octows2811_controller.h b/libraries/FastLED/platforms/arm/k20/octows2811_controller.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/k20/octows2811_controller.h
rename to libraries/FastLED/platforms/arm/k20/octows2811_controller.h
diff --git a/libraries/FastLED-master/platforms/arm/k20/smartmatrix_t3.h b/libraries/FastLED/platforms/arm/k20/smartmatrix_t3.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/k20/smartmatrix_t3.h
rename to libraries/FastLED/platforms/arm/k20/smartmatrix_t3.h
diff --git a/libraries/FastLED-master/platforms/arm/k20/ws2812serial_controller.h b/libraries/FastLED/platforms/arm/k20/ws2812serial_controller.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/k20/ws2812serial_controller.h
rename to libraries/FastLED/platforms/arm/k20/ws2812serial_controller.h
diff --git a/libraries/FastLED-master/platforms/arm/k66/clockless_arm_k66.h b/libraries/FastLED/platforms/arm/k66/clockless_arm_k66.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/k66/clockless_arm_k66.h
rename to libraries/FastLED/platforms/arm/k66/clockless_arm_k66.h
diff --git a/libraries/FastLED-master/platforms/arm/k66/clockless_block_arm_k66.h b/libraries/FastLED/platforms/arm/k66/clockless_block_arm_k66.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/k66/clockless_block_arm_k66.h
rename to libraries/FastLED/platforms/arm/k66/clockless_block_arm_k66.h
diff --git a/libraries/FastLED-master/platforms/arm/k66/fastled_arm_k66.h b/libraries/FastLED/platforms/arm/k66/fastled_arm_k66.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/k66/fastled_arm_k66.h
rename to libraries/FastLED/platforms/arm/k66/fastled_arm_k66.h
diff --git a/libraries/FastLED-master/platforms/arm/k66/fastpin_arm_k66.h b/libraries/FastLED/platforms/arm/k66/fastpin_arm_k66.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/k66/fastpin_arm_k66.h
rename to libraries/FastLED/platforms/arm/k66/fastpin_arm_k66.h
diff --git a/libraries/FastLED-master/platforms/arm/k66/fastspi_arm_k66.h b/libraries/FastLED/platforms/arm/k66/fastspi_arm_k66.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/k66/fastspi_arm_k66.h
rename to libraries/FastLED/platforms/arm/k66/fastspi_arm_k66.h
diff --git a/libraries/FastLED-master/platforms/arm/k66/led_sysdefs_arm_k66.h b/libraries/FastLED/platforms/arm/k66/led_sysdefs_arm_k66.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/k66/led_sysdefs_arm_k66.h
rename to libraries/FastLED/platforms/arm/k66/led_sysdefs_arm_k66.h
diff --git a/libraries/FastLED-master/platforms/arm/kl26/clockless_arm_kl26.h b/libraries/FastLED/platforms/arm/kl26/clockless_arm_kl26.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/kl26/clockless_arm_kl26.h
rename to libraries/FastLED/platforms/arm/kl26/clockless_arm_kl26.h
diff --git a/libraries/FastLED-master/platforms/arm/kl26/fastled_arm_kl26.h b/libraries/FastLED/platforms/arm/kl26/fastled_arm_kl26.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/kl26/fastled_arm_kl26.h
rename to libraries/FastLED/platforms/arm/kl26/fastled_arm_kl26.h
diff --git a/libraries/FastLED-master/platforms/arm/kl26/fastpin_arm_kl26.h b/libraries/FastLED/platforms/arm/kl26/fastpin_arm_kl26.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/kl26/fastpin_arm_kl26.h
rename to libraries/FastLED/platforms/arm/kl26/fastpin_arm_kl26.h
diff --git a/libraries/FastLED-master/platforms/arm/kl26/fastspi_arm_kl26.h b/libraries/FastLED/platforms/arm/kl26/fastspi_arm_kl26.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/kl26/fastspi_arm_kl26.h
rename to libraries/FastLED/platforms/arm/kl26/fastspi_arm_kl26.h
diff --git a/libraries/FastLED-master/platforms/arm/kl26/led_sysdefs_arm_kl26.h b/libraries/FastLED/platforms/arm/kl26/led_sysdefs_arm_kl26.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/kl26/led_sysdefs_arm_kl26.h
rename to libraries/FastLED/platforms/arm/kl26/led_sysdefs_arm_kl26.h
diff --git a/libraries/FastLED-master/platforms/arm/nrf51/clockless_arm_nrf51.h b/libraries/FastLED/platforms/arm/nrf51/clockless_arm_nrf51.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/nrf51/clockless_arm_nrf51.h
rename to libraries/FastLED/platforms/arm/nrf51/clockless_arm_nrf51.h
diff --git a/libraries/FastLED-master/platforms/arm/nrf51/fastled_arm_nrf51.h b/libraries/FastLED/platforms/arm/nrf51/fastled_arm_nrf51.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/nrf51/fastled_arm_nrf51.h
rename to libraries/FastLED/platforms/arm/nrf51/fastled_arm_nrf51.h
diff --git a/libraries/FastLED-master/platforms/arm/nrf51/fastpin_arm_nrf51.h b/libraries/FastLED/platforms/arm/nrf51/fastpin_arm_nrf51.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/nrf51/fastpin_arm_nrf51.h
rename to libraries/FastLED/platforms/arm/nrf51/fastpin_arm_nrf51.h
diff --git a/libraries/FastLED-master/platforms/arm/nrf51/fastspi_arm_nrf51.h b/libraries/FastLED/platforms/arm/nrf51/fastspi_arm_nrf51.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/nrf51/fastspi_arm_nrf51.h
rename to libraries/FastLED/platforms/arm/nrf51/fastspi_arm_nrf51.h
diff --git a/libraries/FastLED-master/platforms/arm/nrf51/led_sysdefs_arm_nrf51.h b/libraries/FastLED/platforms/arm/nrf51/led_sysdefs_arm_nrf51.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/nrf51/led_sysdefs_arm_nrf51.h
rename to libraries/FastLED/platforms/arm/nrf51/led_sysdefs_arm_nrf51.h
diff --git a/libraries/FastLED-master/platforms/arm/sam/clockless_arm_sam.h b/libraries/FastLED/platforms/arm/sam/clockless_arm_sam.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/sam/clockless_arm_sam.h
rename to libraries/FastLED/platforms/arm/sam/clockless_arm_sam.h
diff --git a/libraries/FastLED-master/platforms/arm/sam/clockless_block_arm_sam.h b/libraries/FastLED/platforms/arm/sam/clockless_block_arm_sam.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/sam/clockless_block_arm_sam.h
rename to libraries/FastLED/platforms/arm/sam/clockless_block_arm_sam.h
diff --git a/libraries/FastLED-master/platforms/arm/sam/fastled_arm_sam.h b/libraries/FastLED/platforms/arm/sam/fastled_arm_sam.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/sam/fastled_arm_sam.h
rename to libraries/FastLED/platforms/arm/sam/fastled_arm_sam.h
diff --git a/libraries/FastLED-master/platforms/arm/sam/fastpin_arm_sam.h b/libraries/FastLED/platforms/arm/sam/fastpin_arm_sam.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/sam/fastpin_arm_sam.h
rename to libraries/FastLED/platforms/arm/sam/fastpin_arm_sam.h
diff --git a/libraries/FastLED-master/platforms/arm/sam/fastspi_arm_sam.h b/libraries/FastLED/platforms/arm/sam/fastspi_arm_sam.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/sam/fastspi_arm_sam.h
rename to libraries/FastLED/platforms/arm/sam/fastspi_arm_sam.h
diff --git a/libraries/FastLED-master/platforms/arm/sam/led_sysdefs_arm_sam.h b/libraries/FastLED/platforms/arm/sam/led_sysdefs_arm_sam.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/sam/led_sysdefs_arm_sam.h
rename to libraries/FastLED/platforms/arm/sam/led_sysdefs_arm_sam.h
diff --git a/libraries/FastLED-master/platforms/arm/stm32/clockless_arm_stm32.h b/libraries/FastLED/platforms/arm/stm32/clockless_arm_stm32.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/stm32/clockless_arm_stm32.h
rename to libraries/FastLED/platforms/arm/stm32/clockless_arm_stm32.h
diff --git a/libraries/FastLED-master/platforms/arm/stm32/fastled_arm_stm32.h b/libraries/FastLED/platforms/arm/stm32/fastled_arm_stm32.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/stm32/fastled_arm_stm32.h
rename to libraries/FastLED/platforms/arm/stm32/fastled_arm_stm32.h
diff --git a/libraries/FastLED-master/platforms/arm/stm32/fastpin_arm_stm32.h b/libraries/FastLED/platforms/arm/stm32/fastpin_arm_stm32.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/stm32/fastpin_arm_stm32.h
rename to libraries/FastLED/platforms/arm/stm32/fastpin_arm_stm32.h
diff --git a/libraries/FastLED-master/platforms/arm/stm32/led_sysdefs_arm_stm32.h b/libraries/FastLED/platforms/arm/stm32/led_sysdefs_arm_stm32.h
similarity index 100%
rename from libraries/FastLED-master/platforms/arm/stm32/led_sysdefs_arm_stm32.h
rename to libraries/FastLED/platforms/arm/stm32/led_sysdefs_arm_stm32.h
diff --git a/libraries/FastLED-master/platforms/avr/clockless_trinket.h b/libraries/FastLED/platforms/avr/clockless_trinket.h
similarity index 100%
rename from libraries/FastLED-master/platforms/avr/clockless_trinket.h
rename to libraries/FastLED/platforms/avr/clockless_trinket.h
diff --git a/libraries/FastLED-master/platforms/avr/fastled_avr.h b/libraries/FastLED/platforms/avr/fastled_avr.h
similarity index 100%
rename from libraries/FastLED-master/platforms/avr/fastled_avr.h
rename to libraries/FastLED/platforms/avr/fastled_avr.h
diff --git a/libraries/FastLED-master/platforms/avr/fastpin_avr.h b/libraries/FastLED/platforms/avr/fastpin_avr.h
similarity index 100%
rename from libraries/FastLED-master/platforms/avr/fastpin_avr.h
rename to libraries/FastLED/platforms/avr/fastpin_avr.h
diff --git a/libraries/FastLED-master/platforms/avr/fastspi_avr.h b/libraries/FastLED/platforms/avr/fastspi_avr.h
similarity index 100%
rename from libraries/FastLED-master/platforms/avr/fastspi_avr.h
rename to libraries/FastLED/platforms/avr/fastspi_avr.h
diff --git a/libraries/FastLED-master/platforms/avr/led_sysdefs_avr.h b/libraries/FastLED/platforms/avr/led_sysdefs_avr.h
similarity index 100%
rename from libraries/FastLED-master/platforms/avr/led_sysdefs_avr.h
rename to libraries/FastLED/platforms/avr/led_sysdefs_avr.h
diff --git a/libraries/FastLED-master/platforms/esp/32/clockless_block_esp32.h b/libraries/FastLED/platforms/esp/32/clockless_block_esp32.h
similarity index 100%
rename from libraries/FastLED-master/platforms/esp/32/clockless_block_esp32.h
rename to libraries/FastLED/platforms/esp/32/clockless_block_esp32.h
diff --git a/libraries/FastLED-master/platforms/esp/32/clockless_esp32.h b/libraries/FastLED/platforms/esp/32/clockless_esp32.h
similarity index 100%
rename from libraries/FastLED-master/platforms/esp/32/clockless_esp32.h
rename to libraries/FastLED/platforms/esp/32/clockless_esp32.h
diff --git a/libraries/FastLED-master/platforms/esp/32/fastled_esp32.h b/libraries/FastLED/platforms/esp/32/fastled_esp32.h
similarity index 100%
rename from libraries/FastLED-master/platforms/esp/32/fastled_esp32.h
rename to libraries/FastLED/platforms/esp/32/fastled_esp32.h
diff --git a/libraries/FastLED-master/platforms/esp/32/fastpin_esp32.h b/libraries/FastLED/platforms/esp/32/fastpin_esp32.h
similarity index 100%
rename from libraries/FastLED-master/platforms/esp/32/fastpin_esp32.h
rename to libraries/FastLED/platforms/esp/32/fastpin_esp32.h
diff --git a/libraries/FastLED-master/platforms/esp/32/led_sysdefs_esp32.h b/libraries/FastLED/platforms/esp/32/led_sysdefs_esp32.h
similarity index 100%
rename from libraries/FastLED-master/platforms/esp/32/led_sysdefs_esp32.h
rename to libraries/FastLED/platforms/esp/32/led_sysdefs_esp32.h
diff --git a/libraries/FastLED-master/platforms/esp/8266/clockless_block_esp8266.h b/libraries/FastLED/platforms/esp/8266/clockless_block_esp8266.h
similarity index 100%
rename from libraries/FastLED-master/platforms/esp/8266/clockless_block_esp8266.h
rename to libraries/FastLED/platforms/esp/8266/clockless_block_esp8266.h
diff --git a/libraries/FastLED-master/platforms/esp/8266/clockless_esp8266.h b/libraries/FastLED/platforms/esp/8266/clockless_esp8266.h
similarity index 100%
rename from libraries/FastLED-master/platforms/esp/8266/clockless_esp8266.h
rename to libraries/FastLED/platforms/esp/8266/clockless_esp8266.h
diff --git a/libraries/FastLED-master/platforms/esp/8266/fastled_esp8266.h b/libraries/FastLED/platforms/esp/8266/fastled_esp8266.h
similarity index 100%
rename from libraries/FastLED-master/platforms/esp/8266/fastled_esp8266.h
rename to libraries/FastLED/platforms/esp/8266/fastled_esp8266.h
diff --git a/libraries/FastLED-master/platforms/esp/8266/fastpin_esp8266.h b/libraries/FastLED/platforms/esp/8266/fastpin_esp8266.h
similarity index 100%
rename from libraries/FastLED-master/platforms/esp/8266/fastpin_esp8266.h
rename to libraries/FastLED/platforms/esp/8266/fastpin_esp8266.h
diff --git a/libraries/FastLED-master/platforms/esp/8266/led_sysdefs_esp8266.h b/libraries/FastLED/platforms/esp/8266/led_sysdefs_esp8266.h
similarity index 100%
rename from libraries/FastLED-master/platforms/esp/8266/led_sysdefs_esp8266.h
rename to libraries/FastLED/platforms/esp/8266/led_sysdefs_esp8266.h
diff --git a/libraries/FastLED-master/power_mgt.cpp b/libraries/FastLED/power_mgt.cpp
similarity index 100%
rename from libraries/FastLED-master/power_mgt.cpp
rename to libraries/FastLED/power_mgt.cpp
diff --git a/libraries/FastLED-master/power_mgt.h b/libraries/FastLED/power_mgt.h
similarity index 100%
rename from libraries/FastLED-master/power_mgt.h
rename to libraries/FastLED/power_mgt.h
diff --git a/libraries/FastLED-master/preview_changes.txt b/libraries/FastLED/preview_changes.txt
similarity index 100%
rename from libraries/FastLED-master/preview_changes.txt
rename to libraries/FastLED/preview_changes.txt
diff --git a/libraries/FastLED-master/release_notes.md b/libraries/FastLED/release_notes.md
similarity index 100%
rename from libraries/FastLED-master/release_notes.md
rename to libraries/FastLED/release_notes.md
diff --git a/libraries/FastLED-master/wiring.cpp b/libraries/FastLED/wiring.cpp
similarity index 100%
rename from libraries/FastLED-master/wiring.cpp
rename to libraries/FastLED/wiring.cpp
diff --git a/libraries/IRLremote-master/Readme.md b/libraries/IRLremote/Readme.md
similarity index 100%
rename from libraries/IRLremote-master/Readme.md
rename to libraries/IRLremote/Readme.md
diff --git a/libraries/IRLremote-master/dev/Interpreting Decoded IR Signals (v2.43).htm b/libraries/IRLremote/dev/Interpreting Decoded IR Signals (v2.43).htm
similarity index 100%
rename from libraries/IRLremote-master/dev/Interpreting Decoded IR Signals (v2.43).htm
rename to libraries/IRLremote/dev/Interpreting Decoded IR Signals (v2.43).htm
diff --git a/libraries/IRLremote-master/examples/Convert_Old_Nec/Convert_Old_Nec.ino b/libraries/IRLremote/examples/Convert_Old_Nec/Convert_Old_Nec.ino
similarity index 100%
rename from libraries/IRLremote-master/examples/Convert_Old_Nec/Convert_Old_Nec.ino
rename to libraries/IRLremote/examples/Convert_Old_Nec/Convert_Old_Nec.ino
diff --git a/libraries/IRLremote-master/examples/NecAPI/NecAPI.ino b/libraries/IRLremote/examples/NecAPI/NecAPI.ino
similarity index 100%
rename from libraries/IRLremote-master/examples/NecAPI/NecAPI.ino
rename to libraries/IRLremote/examples/NecAPI/NecAPI.ino
diff --git a/libraries/IRLremote-master/examples/Receive/Receive.ino b/libraries/IRLremote/examples/Receive/Receive.ino
similarity index 100%
rename from libraries/IRLremote-master/examples/Receive/Receive.ino
rename to libraries/IRLremote/examples/Receive/Receive.ino
diff --git a/libraries/IRLremote-master/examples/Receive_Raw/Receive_Raw.ino b/libraries/IRLremote/examples/Receive_Raw/Receive_Raw.ino
similarity index 100%
rename from libraries/IRLremote-master/examples/Receive_Raw/Receive_Raw.ino
rename to libraries/IRLremote/examples/Receive_Raw/Receive_Raw.ino
diff --git a/libraries/IRLremote-master/examples/Send_Button/Send_Button.ino b/libraries/IRLremote/examples/Send_Button/Send_Button.ino
similarity index 100%
rename from libraries/IRLremote-master/examples/Send_Button/Send_Button.ino
rename to libraries/IRLremote/examples/Send_Button/Send_Button.ino
diff --git a/libraries/IRLremote-master/examples/Send_Serial/Send_Serial.ino b/libraries/IRLremote/examples/Send_Serial/Send_Serial.ino
similarity index 100%
rename from libraries/IRLremote-master/examples/Send_Serial/Send_Serial.ino
rename to libraries/IRLremote/examples/Send_Serial/Send_Serial.ino
diff --git a/libraries/IRLremote-master/examples/Transceive/Transceive.ino b/libraries/IRLremote/examples/Transceive/Transceive.ino
similarity index 100%
rename from libraries/IRLremote-master/examples/Transceive/Transceive.ino
rename to libraries/IRLremote/examples/Transceive/Transceive.ino
diff --git a/libraries/IRLremote-master/extra/old/IRL_Hash.hpp b/libraries/IRLremote/extra/old/IRL_Hash.hpp
similarity index 100%
rename from libraries/IRLremote-master/extra/old/IRL_Hash.hpp
rename to libraries/IRLremote/extra/old/IRL_Hash.hpp
diff --git a/libraries/IRLremote-master/extra/old/IRL_RawIR.hpp b/libraries/IRLremote/extra/old/IRL_RawIR.hpp
similarity index 100%
rename from libraries/IRLremote-master/extra/old/IRL_RawIR.hpp
rename to libraries/IRLremote/extra/old/IRL_RawIR.hpp
diff --git a/libraries/IRLremote-master/extra/old/IRL_Sony.hpp b/libraries/IRLremote/extra/old/IRL_Sony.hpp
similarity index 100%
rename from libraries/IRLremote-master/extra/old/IRL_Sony.hpp
rename to libraries/IRLremote/extra/old/IRL_Sony.hpp
diff --git a/libraries/IRLremote-master/extra/old/IRLremote.cpp b/libraries/IRLremote/extra/old/IRLremote.cpp
similarity index 100%
rename from libraries/IRLremote-master/extra/old/IRLremote.cpp
rename to libraries/IRLremote/extra/old/IRLremote.cpp
diff --git a/libraries/IRLremote-master/extra/old/IRLremoteReceive.hpp b/libraries/IRLremote/extra/old/IRLremoteReceive.hpp
similarity index 100%
rename from libraries/IRLremote-master/extra/old/IRLremoteReceive.hpp
rename to libraries/IRLremote/extra/old/IRLremoteReceive.hpp
diff --git a/libraries/IRLremote-master/extra/old/IRLremoteTransmit.hpp b/libraries/IRLremote/extra/old/IRLremoteTransmit.hpp
similarity index 100%
rename from libraries/IRLremote-master/extra/old/IRLremoteTransmit.hpp
rename to libraries/IRLremote/extra/old/IRLremoteTransmit.hpp
diff --git a/libraries/IRLremote-master/header.jpg b/libraries/IRLremote/header.jpg
similarity index 100%
rename from libraries/IRLremote-master/header.jpg
rename to libraries/IRLremote/header.jpg
diff --git a/libraries/IRLremote-master/keywords.txt b/libraries/IRLremote/keywords.txt
similarity index 100%
rename from libraries/IRLremote-master/keywords.txt
rename to libraries/IRLremote/keywords.txt
diff --git a/libraries/IRLremote-master/library.properties b/libraries/IRLremote/library.properties
similarity index 100%
rename from libraries/IRLremote-master/library.properties
rename to libraries/IRLremote/library.properties
diff --git a/libraries/IRLremote-master/src/IRL_Decode.h b/libraries/IRLremote/src/IRL_Decode.h
similarity index 100%
rename from libraries/IRLremote-master/src/IRL_Decode.h
rename to libraries/IRLremote/src/IRL_Decode.h
diff --git a/libraries/IRLremote-master/src/IRL_Hash.h b/libraries/IRLremote/src/IRL_Hash.h
similarity index 100%
rename from libraries/IRLremote-master/src/IRL_Hash.h
rename to libraries/IRLremote/src/IRL_Hash.h
diff --git a/libraries/IRLremote-master/src/IRL_Keycodes.h b/libraries/IRLremote/src/IRL_Keycodes.h
similarity index 100%
rename from libraries/IRLremote-master/src/IRL_Keycodes.h
rename to libraries/IRLremote/src/IRL_Keycodes.h
diff --git a/libraries/IRLremote-master/src/IRL_Nec.h b/libraries/IRLremote/src/IRL_Nec.h
similarity index 100%
rename from libraries/IRLremote-master/src/IRL_Nec.h
rename to libraries/IRLremote/src/IRL_Nec.h
diff --git a/libraries/IRLremote-master/src/IRL_NecAPI.h b/libraries/IRLremote/src/IRL_NecAPI.h
similarity index 100%
rename from libraries/IRLremote-master/src/IRL_NecAPI.h
rename to libraries/IRLremote/src/IRL_NecAPI.h
diff --git a/libraries/IRLremote-master/src/IRL_Panasonic.h b/libraries/IRLremote/src/IRL_Panasonic.h
similarity index 100%
rename from libraries/IRLremote-master/src/IRL_Panasonic.h
rename to libraries/IRLremote/src/IRL_Panasonic.h
diff --git a/libraries/IRLremote-master/src/IRL_Platform.h b/libraries/IRLremote/src/IRL_Platform.h
similarity index 100%
rename from libraries/IRLremote-master/src/IRL_Platform.h
rename to libraries/IRLremote/src/IRL_Platform.h
diff --git a/libraries/IRLremote-master/src/IRL_Protocol.h b/libraries/IRLremote/src/IRL_Protocol.h
similarity index 100%
rename from libraries/IRLremote-master/src/IRL_Protocol.h
rename to libraries/IRLremote/src/IRL_Protocol.h
diff --git a/libraries/IRLremote-master/src/IRL_Receive.h b/libraries/IRLremote/src/IRL_Receive.h
similarity index 100%
rename from libraries/IRLremote-master/src/IRL_Receive.h
rename to libraries/IRLremote/src/IRL_Receive.h
diff --git a/libraries/IRLremote-master/src/IRL_Time.h b/libraries/IRLremote/src/IRL_Time.h
similarity index 100%
rename from libraries/IRLremote-master/src/IRL_Time.h
rename to libraries/IRLremote/src/IRL_Time.h
diff --git a/libraries/IRLremote-master/src/IRLremote.cpp b/libraries/IRLremote/src/IRLremote.cpp
similarity index 100%
rename from libraries/IRLremote-master/src/IRLremote.cpp
rename to libraries/IRLremote/src/IRLremote.cpp
diff --git a/libraries/IRLremote-master/src/IRLremote.h b/libraries/IRLremote/src/IRLremote.h
similarity index 100%
rename from libraries/IRLremote-master/src/IRLremote.h
rename to libraries/IRLremote/src/IRLremote.h
diff --git a/proj_img.jpg b/proj_img.jpg
deleted file mode 100644
index 9bc5866..0000000
Binary files a/proj_img.jpg and /dev/null differ
diff --git a/schemes/scheme3.jpg b/schemes/scheme3.jpg
index 8497e99..497f52b 100644
Binary files a/schemes/scheme3.jpg and b/schemes/scheme3.jpg differ
diff --git a/schemes/scheme4.jpg b/schemes/scheme4.jpg
index 940c7ac..b470df8 100644
Binary files a/schemes/scheme4.jpg and b/schemes/scheme4.jpg differ
diff --git a/schemes/scheme5.jpg b/schemes/scheme5.jpg
index f3cc2f4..c2770af 100644
Binary files a/schemes/scheme5.jpg and b/schemes/scheme5.jpg differ