arduino-0.12.2/0000755000000000000000000000000014777724260010203 5ustar00arduino-0.12.2/.hgignore0000644000000000000000000000142414777724260012007 0ustar00syntax: regexp # The recurrent (^|/) idiom in the regexps below should be understood # to mean "at any directory" while the ^ idiom means "from the # project's top-level directory". (^|/).*\.dvi$ (^|/).*\.pdf$ (^|/).*\.o$ (^|/).*\.log$ (^|/).*\.oct$ (^|/).*\.octlink$ (^|/)octave-core$ (^|/).*\.tar\.gz$ ## Our Makefile target ^release/ ## Files generated automatically by autoconf and the configure script (^|/)aclocal\.m4$ (^|/)configure$ (^|/)autom4te\.cache($|/) ^src/config\.log$ ^src/config\.h\.in$ ^src/config\.status$ ^src/Makefile$ # e.g. doc/faq/OctaveFAQ.info # doc/interpreter/octave.info-4 ^doc/.*\.info(-\d)?$ ^doc/\w*/stamp-vti$ ^doc/\w*/version\.texi$ # Emacs tools create these (^|/)TAGS$ (^|/)semantic.cache$ # Other text editors often create these (^|/)~.* arduino-0.12.2/COPYING0000644000000000000000000010451314777724260011242 0ustar00 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 . arduino-0.12.2/DESCRIPTION0000644000000000000000000000110414777724260011705 0ustar00Name: arduino Version: 0.12.2 Date: 2025-04-16 Author: John Donoghue Maintainer: John Donoghue Title: Octave Arduino Toolkit Description: Basic Octave implementation of the matlab arduino extension, allowing communication to a programmed arduino board to control its hardware. Categories: Arduino Toolkit Depends: octave (>= 4.0.0), instrument-control (>= 0.5.0) SystemRequirements: arduino-ide (>= 1.5) License: GPLv3+ Url: https://gnu-octave.github.io/octave-arduino/ Repository: https://github.com/gnu-octave/octave-arduino/ arduino-0.12.2/INDEX0000644000000000000000000000655414777724260011007 0ustar00arduino >> Arduino Toolkit General Functions arduinosetup isarduino listArduinoLibraries scanForArduinos Arduino Functions @arduino/checkI2CAddress @arduino/configurePin @arduino/configurePinResource @arduino/decrementResourceCount @arduino/delete @arduino/disp @arduino/getEndian @arduino/getI2CTerminals @arduino/getInterruptTerminals @arduino/getLEDTerminals @arduino/getMCU @arduino/getPWMTerminals @arduino/getPinAlias @arduino/getPinInfo @arduino/getPinsFromTerminals @arduino/getResourceCount @arduino/getResourceOwner @arduino/getSPITerminals @arduino/getServoTerminals @arduino/getSharedResourceProperty @arduino/getTerminalMode @arduino/getTerminalsFromPins @arduino/incrementResourceCount @arduino/isTerminalAnalog @arduino/isTerminalDigital @arduino/playTone @arduino/readAnalogPin @arduino/readDigitalPin @arduino/readVoltage @arduino/reset @arduino/sendCommand @arduino/setSharedResourceProperty @arduino/uptime @arduino/validatePin @arduino/version @arduino/writeDigitalPin @arduino/writePWMDutyCycle @arduino/writePWMVoltage @arduino/arduino Arduino I2C Functions scanI2Cbus @i2cdev/delete @i2cdev/disp @i2cdev/read @i2cdev/readRegister @i2cdev/subsref @i2cdev/write @i2cdev/writeRegister @i2cdev/i2cdev @device/delete @device/disp @device/read @device/readRegister @device/subsref @device/write @device/writeRegister Arduino Rotary Encoder Functions @rotaryEncoder/delete @rotaryEncoder/disp @rotaryEncoder/readCount @rotaryEncoder/readSpeed @rotaryEncoder/resetCount @rotaryEncoder/subsref @rotaryEncoder/rotaryEncoder Arduino Servo Functions @servo/delete @servo/disp @servo/readPosition @servo/subsref @servo/writePosition @servo/servo Arduino Shiftregister Functions @shiftRegister/delete @shiftRegister/disp @shiftRegister/read @shiftRegister/reset @shiftRegister/write @shiftRegister/subsref @shiftRegister/shiftRegister Arduino SPI Functions @spidev/delete @spidev/disp @spidev/subsref @spidev/writeRead @spidev/spidev @device/delete @device/disp @device/subsref @device/writeRead Arduino Serial Functions @device/delete @device/disp @device/flush @device/read @device/subsref @device/write @device/device Arduino Device Functions @device/delete @device/disp @device/flush @device/read @device/readRegister @device/subsref @device/write @device/writeRead @device/writeRegister @device/device Arduino Ultrasonic Functions @ultrasonic/delete @ultrasonic/disp @ultrasonic/subsref @ultrasonic/readDistance @ultrasonic/readEchoTime @ultrasonic/ultrasonic Arduino Addons addon arduinoioaddons.ExampleAddon.Echo arduinoioaddons.ExampleLCD.LCD arduinoioaddons.EEPRomAddon.EEPRom arduinoioaddons.RTCAddon.DS1307 arduinoioaddons.adafruit.motorshieldv2 arduinoioaddons.adafruit.dcmotorv2 arduinoioaddons.adafruit.stepper arduinoioaddons.SimpleStepper.SimpleStepper Arduino Sensors arduinosensor.DS1307 arduinosensor.MPC3002 arduinosensor.SI7021 arduinosensor.GUVAS12SD Arduino I/O package arduinoio.AddonBase arduinoio.FilePath arduinoio.LibFiles arduinoio.LibraryBase arduinoio.getBoardConfig Matlab Compatibility Classes matlabshared.addon.LibraryBase Sensors bme280 bno055 lis3dh lps22hb lsm6dso mpu6050 si7021 Test Functions arduino_bistsetup arduino-0.12.2/NEWS0000644000000000000000000001457514777724260010716 0ustar00Summary of important user-visible changes for arduino 0.12.2: ------------------------------------------------------------------- ** Added priortization of ports when scanning for arduinos. ** Updated search for arduino binary for ARDUINO_HOME env settings, and arduino-ide ** Bugfix: lsm6dso duplicate property name ** Minor doc updates Summary of important user-visible changes for arduino 0.12.1: ------------------------------------------------------------------- ** Bugfix for scanForArduinos to ensure release of serial port ** Use disp not display for object display functionality Summary of important user-visible changes for arduino 0.12.0: ------------------------------------------------------------------- ** Minor doc changes ** New Board Configurations: - Arduino Nano ESP32 ** Support for different communication baudrates ** Added additional scanForArduinos functionality ** expanded search for arduino binary Summary of important user-visible changes for arduino 0.11.0: ------------------------------------------------------------------- ** New board configurations: - Arduino Uno WIFI r4 - Arduino Uno Minima r4 ** Minor doc updates Summary of important user-visible changes for arduino 0.10.0: ------------------------------------------------------------------- ** New board configurations: - ESP32 Dev ** Doc corrections for using addons ** @arduino/arduino - added 'forcebuildon' input property Summary of important user-visible changes for arduino 0.9.1: ------------------------------------------------------------------- ** @arduino/playTone: fix bitshifted values (Bug #62538) ** Save/Restore arduinobinary to prefs arduino.arduino_binary. Summary of important user-visible changes for arduino 0.9.0: ------------------------------------------------------------------- ** @arduino/arduino - added ability to connection via ip address ** Core Libraries - added initial Wifi connectivity ** added sensors - bme280 - bno055 - lis3dh - lps22hb - lsm6dso - mpu6050 - si7021 ** added addons - SimpleStepper ** added QT docs Summary of important user-visible changes for arduino 0.8.0: ------------------------------------------------------------------- ** New board configurations: - Raspberry Pi Pico - Arduino Nano RP2040 Connect - Arduino MKR1000 ** New functions: - @arduino/getEndian ** @device/read and writeXXXXX: - only fix endian when host and device do not match ** updates for closer matlab code compatibility ** updates for octave 7 compatibility Summary of important user-visible changes for arduino 0.7.0: ------------------------------------------------------------------- ** New board configurations: - Arduino Due - Arduino MKRZero - Arduino Nano 33 BLE ** @arduino/arduino - added analogreference property - added matlab compatible property names - playTone duration bug fix ** New functions: - @arduino/getPinAlias ** Core Libraries: - provide basic debugPrint function - support multiple i2c device buses correctly - support differing spi device settings - use global error messages for common errors Summary of important user-visible changes for arduino 0.6.0: ------------------------------------------------------------------- ** New functions: - arduinoio.LibraryBase/sendCommand override ** Modified functions: - added debug mode to scanForArduinos ** spidev, i2c, servo, rotaryEncoder, ultrasonic, shiftRegister and device are now classdef objects ** minor function documentation updates ** minor updates to support octave 6 compatibility Summary of important user-visible changes for arduino 0.5.0: ------------------------------------------------------------------- ** Modified functions: - return fraction of time for rotaryEncoder.readCount (Bug #56377) ** New functions: - @arduino/getInterruptTerminals ** new classes - @ultrasonic - @device ** Depreciated - @spidev - use @device - @i2cdev - use @device ** New board configurations: - Arduino Pro Micro - Arduino Leonardo - Arduino Micro - Arduino Nano Every Summary of important user-visible changes for arduino 0.4.0: ------------------------------------------------------------------- ** New addons - adafruit.motorshieldv2 ** New functions: - @arduino/checkI2CAddress - arduino_bistsetup ** Modified functions: - added optional libtype specifier to listArduinoLibraries - bugfix to core subsref functions - updated property compare on core - attempt to use user arduino preferences as back up for arduino binary find - get full windows port for scanForArduinos, no case compare for board type ** minor function documentation updates ** Added sensors package: - arduinosensor.DS1307 - arduinosensor.MPC3002 - arduinosensor.SI7021 - arduinosensor.GUVAS12SD Summary of important user-visible changes for arduino 0.3.0: ------------------------------------------------------------------- ** added getLibName, setup and loop functions to LibraryBase ** Modified functions: - implemented playTone - added forcebuild property to arduino - @spidev/writeRead uses transaction based transfers - @spidev/spidev allow any CS pin to be used - @i2cdev/readRegister return data only ** New functions: - @rotationalEncoder - @arduino/getPinInfo - @arduino/uptime - @arduino/version - @arduino/getSharedResourceProperty - @arduino/setSharedResourceProperty - arduinoio.AddonBase - isarduino ** New addons - ExampleLCD.LCD - EEPRomAddon.EEPRom - RTCAddon.DS1307 ** minor function documentation updates ** New board configurations: - Arduino Pro/Pro Mini - Arduino Nano - Lilypad ** updated to arduinoaddons to query using metadata Summary of important user-visible changes for arduino 0.2.0: ------------------------------------------------------------------- ** update arduinosetup for windows arduino ide changes ** bug fixes for use with older versions of octave ** bug fix mode config in flash ** added initial support for additional board types: - ARM sparkfun SAMD21 dev board ** added manual Summary of important user-visible changes for arduino 0.1.0: ------------------------------------------------------------------- ** Initial release arduino-0.12.2/README.md0000644000000000000000000000646314777724260011473 0ustar00
Octave Arduino Toolkit
---------------------- --- Introduction ============ This is a basic implementation of the Matlab toolkit extension. It attempts to provide the same function calls as the Matlab toolkit, as well as additional functionality, **HOWEVER**, it is not binary compatible with matlab. (ie: you must program the arduino with the GNU octave code to commuicate with the octave arduino toolkit). Requirements ============ The arduino toolkit requires the [Arduino IDE](https://www.arduino.cc/en/software) for programming the arduino board, and the [instrument-control toolkit](https://octave.sourceforge.io/instrument-control/index.html) to communicate to the board. Installing ========== To install, run the octave package manager: 1. To install from source forge: `pkg install -forge arduino` 2. To install from a local tarball. `pkg install arduino-XXXXXXX.tar.gz` Where XXXXXXX is the version of the the downloaded tarball. Usage: ====== 1. Load the arduino package. `pkg load arduino` 2. If the arduino board is not programmed, program it with the arduino communication software. `arduinosetup` Additional libraries can be programmed with it. Use the listArduinoLibraries to retrieve a list of known libraries. 3. Open a connection to the arduino `a = arduino ()` **NOTE**: the board MUST be programmed before the ardino function call will be abele to open the board connection. 4. Use the arduino function calls to control arduino hardware. See the function list and examples directories. Expanding the known board types =============================== Currently the toolkit recognizes these boards: * due * esp32 dev * leonardo * lilypad * mega2560 * micro * mkrzero * mkr1000 * nano * nano every * nano 33 ble * nano rp2040 connect * nano esp32 * promini * promicro * raspberry pi pico * sparkfunsamd21 * uno minima r4 * uno wifi rev2 * uno wifi r4 * uno Additional boards can usually be added with minimal code changes. To add an additional board: 1. The arduino core library (code programmed to the arduino) must provide a board id that is unique and matches the config id. 2. The arduinoio.boardTypeString function must return the board name when provided the id. 3. A config_.m file must be present as arduinoio.config.config_, which describes the pin functionality for the board. A Matlab script in available in arduino toolkit sources that to create 90% of the config file based on the arduino_pins header file from the arduino ide. Adding additional addon libraries ================================= Addon libraries can be created using a similar interface as the Matlab toolkit, or use existing Matlab code with minor changes. Known limitations and bugs ========================== 1. Octave does not document classdef files, so documentation for the arduino class and arduinoio.LibraryBase is not created in the function reference, however is in the reference manual. 2. Octave has issues with displaying function help after the classdef constructor is called, and may not show the help for a given function. 3. Communication between the arduino and Octave occurs only during arduino function calls, so data may be lost if the arduino sends additional information that is not read fast enough. arduino-0.12.2/doc/0000755000000000000000000000000014777724260010750 5ustar00arduino-0.12.2/doc/arduino.css0000644000000000000000000000146114777724260013125 0ustar00pre.example, .header, .float-caption, hr { /* base00 ~ body text in light solarized theme */ color: #657b83; border-color: #657b83; } pre.example { /* base3 ~ background color in light solarized theme */ background-color: #fdf6e3; padding: 0.5em; } a { color: #268bd2; /* blue */ } a:visited { color: #d33682; /* magenta */ } table.cartouche1 { border: 1px solid #948473; background-color: #FFE3C6; width: 100%; } table.cartouche1 td, table.cartouche1 th { border: 1px solid #948473; padding: 4px 4px; } /* newer texinfo generation styles */ div.example { /* base00 ~ body text in light solarized theme */ color: #657b83; border-color: #657b83; } pre.example-preformatted { /* base3 ~ background color in light solarized theme */ background-color: #fdf6e3; padding: 0.5em; } arduino-0.12.2/doc/arduino.html0000644000000000000000000144116714777724260013315 0ustar00 Arduino Toolkit - a somewhat Matlab compatible arduino toolkit for GNU octave.

Introduction

The Arduino toolkit is a somewhat Matlab compatible arduino toolkit for GNU octave.

Table of Contents


1 Installing and loading

The Arduino toolkit must be installed and then loaded to be used.

It can be installed in GNU Octave directly from octave-forge, or can be installed in an off-line mode via a downloaded tarball.

NOTE

The toolkit requires the Arduino IDE in order to program Arduino devices.

NOTE

The toolkit has a dependency on the instrument-control package, so it must be installed in order to successfully install the Arduino toolkit

The toolkit must be then be loaded once per each GNU Octave session in order to use its functionality.

1.1 Online Direct install

With an internet connection available, the Arduino package can be installed from octave-forge using the following command within GNU Octave:

pkg install -forge arduino

The latest released version of the toolkit will be downloaded and installed.

1.2 Off-line install

With the arduino toolkit package already downloaded, and in the current directory when running GNU Octave, the package can be installed using the following command within GNU Octave:

pkg install arduino-0.12.2.tar.gz

1.3 Loading

Regardless of the method of installing the Arduino toolkit, in order to use its functions, the toolkit must be loaded using the pkg load command:

pkg load arduino

The toolkit must be loaded on each GNU Octave session.


2 Hardware setup

In order to use the arduino hardware with the toolkit, it must be programmed with special firmware.

2.1 Programming the Arduino

To program the hardware, using a default configuration, run the arduinosetup command:

arduinosetup

A temporary Arduino project will be created, with the Arduino toolkit files copied to it and the Arduino IDE will open.

Set the board type and port correctly for the connected Arduino and press the upload button on the IDE.

The sources will be compiled and then uploaded to the connected arduino board.

After successful upload the Arduino IDE should be closed.

NOTE

The arduino programming is not compatible with the Matlab arduino library, so must be programmed by the Octave Arduino toolkit to communicate to the arduino, even if it was previously used to work with Matlab.

NOTE

The toolkit requires the Arduino IDE in order to program the Arduino device.

The binary can set using the ’arduinobinary’ property when running setup.

For arduino IDEs before version 2, if the toolkit can not find the IDE, run the IDE manually, close it and retry programming the Arduino. Otherwise, use the ’arduino’ binary property.

2.2 Known Arduino Board Types

The board type must be known in order to successfully detect and connect to the Arduino board after programming.

Currently, known boards are:

  • Arduino Due
  • Arduino UNO
  • Arduino Mega 2560
  • Arduino Nano
  • Arduino Nano Every
  • Arduino Nano 33 BLE
  • Arduino Nano RP2040 Connect
  • Arduino Pro/Pro Mini
  • Arduino Pro Micro
  • Arduino Leonardo
  • Arduino Micro
  • Arduino MKR1000
  • Arduino MKRZero
  • Sparkfun SAMD21
  • Arduino Lilypad
  • Arduino UNO WiFi rev2

    NOTE

    The Arduino servo library code may require modifications to eliminate conflicts between servos and the tone library

  • Arduino UNO WiFi r4
  • Arduino UNO Minima r4
  • Raspberry Pi Pico
  • EPS32 Dev

Additional boards can be added easily, however require minor code changes.


3 Connecting to an arduino

To control an arduino device, a connection must be made to it by creating an arduino object.

3.1 Connecting to a single arduino

Assuming a single arduino device is connected to the computer, creating an arduino object with no arguments will find the connected arduino and connect to it:

ar = arduino()

3.2 Connecting to a specific arduino

Where multiple arduinos may be connected to the computer, a specific board can be connected by specifying the name of the port it is connected to:

ar = arduino("/dev/ttyACM0")

The port name will be operating system dependent.

3.3 Querying available arduinos

To list the ports of all programmed available arduinos, the scanForArduinos function can be used:

scanForArduinos

It will provide a list of all available boards it can find with the port they are connected to.

NOTE

The scanForArduinos function will only detect boards that have been programmed using the arduinosetup command


4 Basic Input and Output Overview

Basic input and output can be performed on a connected arduino device using by calling the read and write functions for a specific named pin on the arduino.

A list of available pins can get found from the pins property of the connected arduino object and are also displayed as part of the default shown properties:

ar = arduino();
% get the pin names
pins = ar.availablepins

Pin generally follow a naming scheme of D<number> for digital pins and A<number> for analog pins.

Digital pins can be used to read and write digital data, but can not read analog voltages. Analog pins can perform digital I/O as well as reading voltages.

4.1 Performing Digital I/O

A pin’s digital logic value can be true (1) or false (0) and can be set using the writeDigitalPin function.

The following example attempts to set the D2 pin of the connected arduino object "ar" to true, waits 5 seconds and then sets it to false:

writeDigitalPin (ar,  "d2", true);
pause 5
writeDigitalPin (ar,  "d2", false);

Using the readDigitalPin will read the current logic state of the pin.

value = readDigitalPin (ar,  "d2");

4.2 Performing Analog Input

For analog pins, the voltage level can be read using a analog to digital conversion and will return a voltage level between 0 and the boards voltage (nominally 5V):

value = readVoltage (ar,  "a0");

The raw digital value of the pin can also be read instead of a voltage, giving a value between 0 and 2^x where x is the number of bits used by the analog to digital converter.

value = readAnalogPin (ar,  "a0");

5 Protocol based I/O Overview

The arduino toolkit supports more complex I/O for SPI, I2C, Servo control and more.

5.1 SPI communication

SPI communication can be performed by creating a SPI device object and then calling the writeRead function:

spi = device (ar,  "spichipselectpin", "d2");

The function call expects a connected arduino object as the first argument, followed by the chip select pin of the SPI device.

After a device is created, a write to device followed by read can can be made using the writeRead function:

spi = device (ar,  "spichipselectpin", "d2");
data = writeRead (spi,  100);

5.2 I2C communication

I2C communication can be performed by creating an I2C device object for a specific I2C address.

The following example creates an I2C device that will communicate with a I2C device at address 100"

i2c = device (ar,  "i2caddress", 100);

After creating an I2C device, data can be read and written using read, write, readRegister and writeRegister. The data to send and receive will be device dependent.

5.3 Servo communication

Servo communication can be performed after creating a servo device object to operate on a PWM pin:

servoobj = servo(ar, "d9", "minpulseduration", 1.0e-3, ...
  "maxpulseduration", 2e-3);

The servo function expects the connected arduino object and the PWM pin that the servo is connected to. Optional properties can be specified to control the setup of device.

In the example, the min and max pulse width values are set.

Using the servo object the current position and be read or set with values ranging between 0 to 1, with 0 being the minimum pulse width and 1 being the maximum.

The following example sets the servo to its middle position.

servoobj = servo(ar, "d9", "minpulseduration", 1.0e-3, ...
  "maxpulseduration", 2e-3);

writePosition (servoobj, 0.5);

5.4 Shift Registers

A shift register can be controlled by creating a shiftRegister object:

registerobj = shiftRegister(ar, '74hc164', "d2", "d3");

The parameters required are dependent on the type of shift register created.

Once a register object has been created, it can be read and written to using the read and write functions.

5.5 Rotary Encoders

A rotary encoder can be created by creating a rotaryEncoder object.

encoder = rotaryEncoder(ar, "d2", "d3", 180);

Using the created object, the rotary encoder value and speed can be read.

5.6 Ultrasonic Sensors

An ultrasonic sensor can be read by creating an ultrasonic object.

sensor = ultrasonic(ar, "d9", "d10");

Using the created object, the sensor distance and echo time and be read.

5.7 Serial communication

Serial communication can be performed on devices that support multiple serial devices such as the leonardo and mega2560 boards. The communications port to Octave is reserved and can not be used as a user controlled communications port.

Serial communication can be performed by creating a serial device object and then calling the read and write functions:

ser = device (ar,  "serial", 1);

The function call expects a connected arduino object as the first argument, followed "serial" and serial id.

After a device is created, the device can be read and written:

ser = device (ar,  "serial", 1);
write(ser, "hello");
data = read(ser, 100);

6 Addons Overview

This chapter provides an overview of the arduino package addon functionality for adding additional addons to arduino.

6.1 Addon Introduction

Addons provide a way of adding additional functionality to the arduino toolkit that provides Matlab access directly to the arduino hardware.

Addons are implemented in two parts.

  1. code running on the arduino that implements the required functionality
  2. a octave wrapper class that provides the Matlab interface and communication to the code.

Both parts are required to create a plugin.

The arduino toolkit provides a number of pre-created addons. These can be seen using the following command:


listArduinoLibraries

The command will display all known arduino libraries (addons as well as core libraries), however addons typically use a "foldername/classname" for this naming.

See also: listArduinoLibraries.

6.2 Creating an addon

An addon requires at minimum 3 things:

  1. A addon package directory that will contain the addon files
  2. A Matlab file within that directory that is a subclass of arduinoio.LibraryBase
  3. A arduino source/header file that contains the arduino code to load, sub-classed for LibraryBase

So the addon directory structure at a minimum will be:


  +arduinoioaddons  (dir) [somewhere in the octave load path]
    +MyAddons (dir)
      MyAddon1.m 
      MyAddon1.h

6.2.1 Addon package directory

The addon architecture looks for plugins in the octave load path in a package directory called +arduinoioaddons

So this directory must be created somewhere within the paths that octave will check for functions.

In addition, the addon architecture expects plugins to be contained in a sub directory within the +arduinoioaddons folder. The subdirectory must begin with a ’+’.

Multiple plugin .m files can be within the same sub directory.

6.2.2 Addon package .m file

The Matlab interface file within the addon directory provides the Matlab interface for the arduino code as well as provides information about the addon.

Class inheritance and required properties

The interface file must be a subclass of arduinoio.LibraryBase and must contain some constant properties values that provide the information.

A minimum example of required is below:


classdef MyAddon1 < arduinoio.LibraryBase
  properties(Access = protected, Constant = true)
    LibraryName = 'MyAddons/MyAddon1';
    CppHeaderFile = fullfile(arduinoio.FilePath(mfilename('fullpath')), 'MyAddon1.h');
    CppClassName = 'MyAddon1';
  endproperties
  .
  .
  .
endclassdef

The following constant properties can be set within the addon:

LibraryName

(Required) The name of the addon. My convention this is usually the directoryname / theclassname

CppHeaderFile

(Required) The header file for the arduino code

CppSourceFile

(Optional) The source file (if any) for the arduino code

CppClassName

(Required) The classname used within the cppheaderfile for the arduino library

DependantLibraries

(Optional) Any additional addons or cores that are needed for this library to be used

ArduinoLibraryHeaderFiles

(Optional) Any additional header files that need to be included

Class constructor

The Matlab class constructor will be called from the addon function when creating a instance of the addon and should initialize at least two properties in inherited from arduinoio.LibraryBase:

  1. Parent should be set to the first input argument (the arduino class)
  2. Pins should be set to a list of pins that are used for the plugin

classdef MyAddon1 < arduinoio.LibraryBase
  .
  .
  methods
    function obj = MyAddon1(parentObj, varargin)
      obj.Parent = parentObj;
      # no pins being used
      obj.Pins = [];
      # send any command to the arduino during setup ?
    endfunction
    .
    .
  endmethods
endclassdef

Class functions

The class functions will usually communicate to the arduino and use the response for what is returned to the user.

By convention, the commands sent to the arduino are defined as constants in the class file but do not have to be.


classdef MyAddon1 < arduinoio.LibraryBase
  properties(Access = private, Constant = true)
    INIT_COMMAND = hex2dec('00');
    FUNC1_COMMAND = hex2dec('01');
  endproperties
  .
  .
  methods
    function obj = MyAddon1(parentObj, varargin)
      obj.Parent = parentObj;
      # no pins being used
      obj.Pins = [];
      # send any command to the arduino during setup ?
      sendCommand(obj.Parent, obj.LibraryName, obj.INIT_COMMAND, []);
    endfunction

    function retval = func1(obj)
       cmdID = obj.FUNC1_COMMAND;
       retval = sendCommand(obj.Parent, obj.LibraryName, cmdID, []);
    endfunction
    .
    .
  endmethods
endclassdef

NOTE

the sendCommand uses the objects parent for the arduino, the objects library name and the command id

See also: sendCommand.

6.2.3 Addon package header file

The header file should contain a class that matches the functionally and information of the matlab file and provides the ability to register the code on the arduino.

The following things should occur in the arduino class files:

  1. The class name within the file must be the same as the one set in the .m file CppClassName property.
  2. The libName variable must be the same as the LibraryName property.
  3. The constructor should call registerLibrary
  4. the commandHandler function to act on cmdID values that match the commands that will be sent from .m file and send data back using sendResponseMsg
  5. on receiving unknown cmdID values, the commandHandler should use sendUnknownCmdIDMsg

An example, matching the previous .m file code is below:


#include "LibraryBase.h"

#define MYADDON1_INIT  0x00
#define MYADDON1_FUNC1 0x01

class MyAddon1 : public LibraryBase
{
  uint8_t cnt;
public:
  MyAddon1(OctaveArduinoClass& a)
  {
    libName = "MyAddons/MyAddon1";
    a.registerLibrary(this);
  }
  void commandHandler(uint8_t cmdID, uint8_t* data, uint8_t datasz)
  {
    switch (cmdID)
      {
      case MYADDON1_INIT:
        {
          cnt = 0;
          sendResponseMsg(cmdID, 0,0);
          break;
        }
      case MYADDON1_FUNC1:
        {
          // func 1 is just returning a uint8 count of number of times called
          cnt ++;
          sendResponseMsg(cmdID, &cnt, 1);
          break;
        }
      default:
        {
          // notify of invalid cmd
          sendUnknownCmdIDMsg();
        }
      }
  }
}
;

The body of functions can be in the CppSourceFile file is it is defined or within the header file as illustrated above.

6.2.4 Verify octave can see the addon

Use the listArduinoLibaries command to verify that the new addon appears in the list of known libraries.

If it does not, ensure that the +arduinoioaddons directory is within one of the octave class paths, and that the directory structure and inheritance requirements have been met.

6.3 Using addons

6.3.1 Programming the arduino with the addon

To use a addon, the code must be programmed onto the arduino.

Using the libraries command, when creating a arduino object, the arduino can be reprogrammed if the library does not already exist on the arduino.


  ar = arduino([],[], 'libraries', 'MyAddons/MyAddon1', 'forcebuild', true)

The libraries property of the arduino object should list the libraries programmed on the arduino.

Alternatively, the library can be added using the libraries property and arduinosetup

See also: arduino, arduinosetup.

6.3.2 Creating a addon object

An object of the addon type can be created using the addon command.


  ar = arduino([],[], 'libraries', 'MyAddons/MyAddon1', 'forcebuild', true)
  obj = addon(ar, "MyAddons/MyAddon1");


7 Sensors Overview

There are two types of sensors available:

  1. Matlab compatible(ish) sensors for environment and IMU.
  2. Additional lightweight wrappers for some chips in a arduinosensor namespace.

7.1 Matlab Compatible Sensors

7.1.1 Overview

Matlab compatible functions are provided for a number of sensors, using a similar function naming as provided by the Matlab arduino package.

7.1.2 Available Sensors

The functions for each sensor is listed in the function reference, Sensors and provides for:

bme280

BME280 temperature, pressure and humidity sensor

bno005

BNO055 acceleration, angular velocity, orientation and magnetic field sensor

lis3dh

LIS3DH acceleration sensor

lps22hb

LPS22HB temperature and pressure sensor

lsm6dso

LSM6DSO acceleration, angular velocity sensor

mpu6050

MPU-6050 acceleration, angular velocity sensor

SI7021

SI7021 temperature and humidity sensor

7.2 Lightweight Arduino Sensors

7.2.1 Overview

Arduino sensors are a collection of lightweight wrappers around other underlying protocols for providing specific sensor functionality.

For instance a DS1307 chip communicates using I2C protocol and so a DS1307 class exists that provides the conversion/commands in order to communicate to the chip.

Using the class, providing the functionality is very easy:


a = arduino()
rtc = arduinosensor.DS1307(a)
# get and display rtc time as a date string
datestr(rtc.clock)

It is lightweight compared to the addon functionality, as it only requires a wrapper class rather than add on code, however it is limited to then using available addon and core codes rather than creating new ones.

Currently the are only a small number of sensors available, however this will be built upon in future versions.

7.2.2 Available Sensors

The functions for each sensor is listed in the function reference, Arduino Sensors and provides for:

DS1307

DS1307 RTC clock using i2c.

MPC3002

MPC3002 ADC using SPI

SI7021

SI7021 temperature and humidity sensor

GUVAS12SD

GUVAS12SD analog UV-B sensor


8 Examples

8.1 Blinking an LED

This example shows blinking the inbuilt LED on the Arduino board. Code is available by running:

edit examples/example_blink

Hardware setup

This example uses in the builtin LED, so requires only a connection of the Arduino board to computer for communication.

Create an Arduino object

ar = arduino ();

If you have more than one Arduino board connected, you may need to specify the port in order to connect to the correct device.

Query Device for pins connected to builtin LED

The pin connected to the Arduino UNO built in led if D13.

led_pin = "d13";

The connected pins can be queried programatically if desired.

pins = getLEDTerminals (ar);

Connected to a Arduino UNO would return a list pins containing only one item ’13’.

The terminal number can be converted to a pin using getPinsFromTerminals:

led_pin = getPinsFromTerminals (ar, pins{1});

Turn the LED off

Write a 0 value to the pin to turn it off.

writeDigitalPin (ar, led_pin, 0);

Turn the LED on

Write a 1 value to the pin to turn it on

writeDigitalPin (ar, led_pin, 1);

Add a while loop with a pause between the changes in the pin state to blink.

while true
  writeDigitalPin (ar, led_pin, 0);
  pause (0.5)
  writeDigitalPin (ar, led_pin, 1);
  pause (0.5)
endwhile

8.2 Using I2C to communicate with an EEPROM

This example shows using I2C to communicate with a EEPROM chip. Code is available by running:

edit examples/example_i2c_eeprom

Hardware setup

Using an Arduino UNO, the board should be configured with the following connections between the board and a 24XX256 EEPROM chip:

A4

Connected to pin 5 of EEPROM

A5

Connected to pin 6 of EEPROM

5V

Connected to pin 8 of EEPROM

GND

Connected to pin 1,2,3,4 of EEPROM

Create an Arduino object

ar = arduino ();

If you have more than one Arduino board connected, you may need to specify the port in order to connect to the correct device.

Query I2C pins

Display the I2C terminals of the board:

getI2CTerminals(ar)

Scan the arduino for the connected device

scanI2Cbus(ar)

The devices listed should contain 0x50, the address of the EEPROM chip.

Create an I2C object to communicate to the EEPROM

eeprom = device (ar, "i2caddress", 0x50)

Write data to the EEPROM

The EEPROM expects the first byte to be the page number, the second the offset, followed by data, so to write 1 2 3 4, starting address 0 (page 0, offset 0):

write(eeprom, [0 0 1 2 3 4])

Reading from the EEPROM

Reading from the EEPROM requires first writing the address to read from, in this case, if we want to read the 3, 4, this would be page 0, offset 2:

write(eeprom, [0 2])

Next read the 2 bytes:

data = read(eeprom, 2)

8.3 Using SPI to communicate with a mcp3002 10 bit ADC

This example shows using SPI to communicate with an mcp3002 10 bit ADC. Code is available by running:

edit examples/example_spi_mcp3002

Hardware setup

Using an Arduino UNO, the board should be configured with the following connections between the board and a mcp3002 chip:

D10

Connected to pin 1 (CS) of MCP3002

D11

Connected to pin 5 (DI) of MCP3002

D12

Connected to pin 6 (DO) of MCP3002

D13

Connected to pin 7 (CLK) MCP3002

VCC

Connected to pin 8 (VDD) MCP3002

GND

Connected to pin 4 (VSS) MCP3002

Analog input

Connected from pin 2 of the MCP3002 to a LOW (< 5V) voltage to measure

Create an Arduino object

ar = arduino ();

If you have more than one Arduino board connected, you may need to specify the port in order to connect to the correct device.

Create an SPI object to communicate to the MCP3002

adc = device(ar, "spichipselectpin", "d10")

The d10 is the chip select pin connected from the Arduino to the MCP3002.

Read the ADC

The MCP3002 expects specific commands in order to read a channel.

For illustration for the command to read chan 0 in single ended mode:

command (bits) in MSB mode to device:
[START SGL ODN MSBF X X X X] [ X X X X X X X X ] 
   1    1   0    1   1 1 1 1    1 1 1 1 1 1 1 1 
      [chan 0 ] MSB    
data back:
   X    X  X     X   X 0 D D    D D D D D D D D

D is a output data bit

X is a don’t care what value is input/output

The first byte contains the command and start of the data read back, the second bytes is written to clock out the rest of the ADC data.

In hex, this corresponds to 0xDF 0xFF,

data = writeRead(adc, [hex2dec("DF") hex2dec("FF")])

Of the data returned, the last 10 bits is the actual data, so convert data to a 16 bit value:

val = uint16(data(1))*256 + uint16(data(2))

Then bitand it to remove the non value parts, to get the ADC value:

val = bitand (val, hex2dec('3FF'))

To make the value correspond to a voltage it needs to be scaled as 0 will be 0 Volts, 1023 will be 5 Volts.

volts = double(val) * 5.0 / 1023.0;

9 Function Reference

The functions currently available in the Arduino toolkit are described below;


9.1 General Functions

9.1.1 arduinosetup

: retval = arduinosetup ()
: retval = arduinosetup (propertyname, propertyvalue)

Open the arduino config / programming tool to program the arduino hardware for usage with the Octave arduino functions.

arduinosetup will create a temporary project using the arduino IDE and allow compiling and programming of the code to an arduino.

Inputs

propertyname, propertyvalue - A sequence of property name/value pairs can be given to set defaults while programming.

Currently the following properties can be set:

libraries

The value should be the name of a library, or string array of libraries to program on the arduino board.

arduinobinary

The value should be the name/path of the arduino IDE binary for programming. If not specified, the function will use getpref preferences of arduino.arduino_binary, and if not found, the function will attempt to find the binary itself.

If provided, the value will be saved to preferences for future calls.

Outputs

retval - return 1 if arduino IDE returned without an error

See also: arduino, __arduino_binary__.

9.1.2 isarduino

: retval = isarduino (obj)

Check if input value is an arduino object

Function is essentially just a call of retval = isa(obj, "arduino");

Inputs

obj - The object to check

Outputs

retval is true, if obj is an arduino object, false otherwise.

See also: arduino.

9.1.3 listArduinoLibraries

: retval = listArduinoLibraries ()
: retval = listArduinoLibraries (libtypes)

Retrieve list of all known arduino library modules that are available.

Inputs

libtypes - optional specifier for type of libraries to list.

Options are:

all

List core and addons

core

List core only libraries

addons

List addons only

When no libtypes is specified, all libraries are shown.

Outputs

retval is an cell array of string library names that are available for programming to the arduino.

See also: arduino, arduinosetup.

9.1.4 scanForArduinos

: retval = scanForArduinos ()
: retval = scanForArduinos (maxCount)
: retval = scanForArduinos ("debug")
: retval = scanForArduinos (maxCount, type)
: retval = scanForArduinos (propertyname, propertvalue ...)

Scan system for programmed serial connected arduino boards.

scanForArduinos will scan the system for programmed arduino boards and return at most maxCount of them as a cell array in retval.

Inputs

maxCount - max number of arduino boards to detect. if maxCount is not specified, or is a less than 1, the function will return as many arduino boards as it can detect.

type - optional board type to match. If specified, the board type must match for the arduino to be added to the return list.

"debug" - if single input parameter is "debug", the scanForArduinos will display debug information as it scans all available ports for arduinos.

propertyname, propertyvalue - property name/value pairs to match search with.

’BaudRate’

Numeric BaudRate to use when trying to scan for arduinos.

’MaxCount’

Max number of arduinos to scan for.

’BoardType’

Boardtype to match.

’Debug’

Logical flag for debug mode.

Outputs

retval structure cell array of matching detected arduino boards.

Each cell value of the cell array will contain a structure with values of:

port

the serial port the arduino is connected to

board

the board type of the arduino

See also: arduino.


9.2 Arduino Functions

9.2.1 @arduino/arduino

: retval = arduino ()
: retval = arduino (port)
: retval = arduino (port, board)
: retval = arduino (port, board[, [propname, propvalue]*)
: retval = arduino (iaddress)
: retval = arduino (ipaddress, board)

Create a arduino object with a connection to an arduino board.

Inputs

port - full path of serial port to connect to. For Linux, usually /dev/ttySXXX, for windows COMXX.

board - name of board to connect (default is ’uno’).

propname, propvalue - property name and value pair for additional properties to pass to the creation of the arduino object.

Currently properties are ignored, with the exception of:

debug

true / false flag for whether setting debug (default false)

forcebuildon

true / false flag for whether to force show of the arduino IDE to rebuild the installed code on the arduino (default false)

baudrate (read only)

the communications baudrate to the board. (default 9600)

libraries

The libraries to be enabled on the arduino board. (default uses whatever is already installed)

if the arduino function is called without parameters, it will scan for the first available arduino it can find and connect to it.

Outputs

retval - a successfully connected arduino object.

Properties

The arduino object has the following public properties:

name

name assigned to the arduino object

debug

true / false flag for whether debug is turned on

forcebuildon

true / false flag for whether to force show of the arduino IDE to reprogram the arduino

port (read only)

the communications port the board is connected to.

baudrate (read only)

the communications baudrate to the board.

board (read only)

The name of the board type that the arduino connected to

libraries (read only)

The libraries currently programmed onto the board

availablepins

The pins available for use on the board

analogreference

The analog voltage reference

See also: scanForArduinos, arduinosetup.

9.2.2 @arduino/checkI2CAddress

: retval = checkI2CAddress (ar, address)
: retval = checkI2CAddress (ar, address, bus)

Check that an address of given address responds on the I2C bus

Inputs

ar - arduino object connected to a arduino board.

address - I2C address number to check

bus - bus number to check for I2C device, when multiple buses are available. If the bus is not specified, it will default to 0.

Outputs

retval - boolean value of true if address responds on the I2C bus

Example


 # create arduino connection.
 ar = arduino();
 # scan for devices on the I2C bus
 checkI2CAddress (ar)
 # output if a device using that address is attached
 ans =
   1
 

See also: arduino, scanI2Cbus.

9.2.3 @arduino/configurePin

: currmode = configurePin (ar, pin)
: configurePin (ar, pin, mode)

Set/Get pin mode for a specified pin on arduino connection.

configurePin (ar, pin) will get the current mode of the specified pin.

configurePin (ar, pin, mode) will attempt set the pin to the specified mode if the mode is unset.

Inputs

ar - the arduino object of the connection to an arduino board.

pin - string name of the pin to set/get the mode of.

mode - string mode to set the pin to.

Outputs

mode - string current mode of the pin.

Valid modes can be:

  • AnalogInput - Acquire analog signals from pin
  • DigitalInput - Acquire digital signals from pin
  • DigitalOutput - Generate digital signals from pin
  • I2C - Specify a pin to use with I2C protocol
  • Pullup - Specify pin to use a pullup switch
  • PWM - Specify pin to use a pulse width modulator
  • Servo - Specify pin to use a servo
  • SPI - Specify a pin to use with SPI protocol
  • Interrupt - Specify a pin to use for with interrupts
  • Reserved - Specify a pin to be reserved
  • Unset - Clears pin designation. The pin is no longer reserved and can be automatically set at the next operation.

See also: arduino.

9.2.4 @arduino/configurePinResource

: currmode = configurePinResource (ar, pin)
: configurePinResource (ar, pin, owner, mode)
: configurePinResource (ar, pin, owner, mode, force)

Set/Get pin mode for a specified pin on arduino connection.

configurePinResource (ar, pin) will get the current mode of the specified pin.

configurePinResource (ar, pin, owner, mode) will attempt set the pin to the specified mode and owner.

If the pin is already owned by another owner, the configure will fail unless the force option is used. If the mode is already set, configure will fail unless force is used.

Inputs

ar - the arduino object of the connection to an arduino board.

pin - string name of the pin to set/get the mode of.

mode - string mode to set the pin to.

owner - string name to use as the pin owner.

force - boolean to force mode change. If not set, it will be false.

Outputs

currmode - current string mode of the pin.

Valid modes can be:

  • AnalogInput - Acquire analog signals from pin
  • DigitalInput - Acquire digital signals from pin
  • DigitalOutput - Generate digital signals from pin
  • I2C - Specify a pin to use with I2C protocol
  • Pullup - Specify pin to use a pullup switch
  • PWM - Specify pin to use a pulse width modulator
  • Servo - Specify pin to use a servo
  • SPI - Specify a pin to use with SPI protocol
  • Interrupt - Specify a pin to use with interrupts
  • Reserved - Pin marked reserved, but not for of any particular mode
  • Unset - Clears pin designation. The pin is no longer reserved and can be automatically set at the next operation.

See also: arduino, configurePin.

9.2.5 @arduino/decrementResourceCount

: count = decrementResourceCount (ar, resource)

Decrement the count of a named resource by 1 and return the new count.

Inputs

ar - connected arduino object

resource - name of resource to decrement count.

Outputs

count = count of uses registered to resource.

See also: getResourceCount. incrementResourceCount.

9.2.6 @arduino/delete

: delete (dev)

Free resources of an arduino object.

Inputs

dev - object to free

See also: arduino.

9.2.7 @arduino/disp

: disp (ar)

Display the arduino object in a verbose way, showing the board and available pins.

Inputs

ar - the arduino object.

If the arduino object has debug mode set, additional information will be displayed.

See also: arduino.

9.2.8 @arduino/getEndian

: mcu = getEndian (ar)

Get the endian used by the connected arduino.

Inputs

ar - arduino object connected to a arduino board.

Outputs

endian - string representing the endian used by the arduino board.

’L’ means little endian, ’B’ means big endian

See also: arduino, getMCU.

9.2.9 @arduino/getI2CTerminals

: pinlist = getI2CTerminals (ar)
: pinlist = getI2CTerminals (ar, bus)

Get a cell list of pin Ids available are used for I2C mode.

Inputs

ar - the arduino object.

bus - optional bus number 0 or 1 for boards that support more than 1 bus.

Outputs

pinlist - cell list of pin numbers available for I2C use.

See also: arduino.

9.2.10 @arduino/getInterruptTerminals

: pinlist = getInterruptTerminals (ar)

Get a cell list of pin Ids available have interrupt functionality

Inputs

ar - the arduino object.

Outputs

pinlist - cell list of pin numbers available for interrupt use.

See also: arduino.

9.2.11 @arduino/getLEDTerminals

: pinlist = getLEDTerminals (ar)

Get a cell list of pin Ids available are connected natively to LEDs.

Inputs

ar - the arduino object.

Outputs

pinlist - cell list of pin numbers available for LED use.

See also: arduino.

9.2.12 @arduino/getMCU

: mcu = getMCU (ar)

Get the MCU used by the connected arduino.

Inputs

ar - arduino object connected to a arduino board.

Outputs

mcu - string representing the mcu used by the arduino board.

See also: arduino.

9.2.13 @arduino/getPWMTerminals

: pinlist = getPWMTerminals (ar)

Get a cell list of pin Ids available for PWM use.

Inputs

ar - the arduino object.

Outputs

pinlist - cell list of pin numbers available for PWM use.

See also: arduino.

9.2.14 @arduino/getPinAlias

: ouy = getPinAlias (ar, pin)

Get the pin actual pin name from a pin alias.

For example, the arduino Leonardo, pin "D4" is also "A6".

Inputs

ar - the connected arduino object.

pin - a pin name.

Outputs

out - alias pin name, or same as pin if the pin doesnt have any alias names.

See also: arduino, configurePinResource, getResourceOwner.

9.2.15 @arduino/getPinInfo

: pininfo = getPinInfo (ar, pin)
: pininfoarray = getPinInfo (ar, pinarray)

Get the pin information from the input pins values.

getPinInfo (ar, pin) will get information for a single pin.

getPinInfo (ar, pinarray) will get a cell array of pin information

Inputs

ar - the connected arduino object.

pin - a pin number or pin name.

pinarray - the array of pin numbers or names

The pininfo struct contains the following fields:

terminal

Terminal number of the pin

name

String name of the pin

owner

Current item owner of the pin

mode

Current configured mode for the pin

Outputs

pininfo - struct on pin information.

pininfolist - cell array of pin info

See also: arduino, configurePinResource, getResourceOwner.

9.2.16 @arduino/getPinsFromTerminals

: pinnames = getPinsFromTerminals (ar, terminals)

Get the pin names from the input terminal values.

Inputs

ar - the connected arduino object.

terminals - the numeric pin number, or array of pin numbers to get pin names.

Outputs

pinnames - the string names of each input pin. If terminals was a single value, the return will be a single string, otherwise it will return a cell array of each pin name.

See also: arduino, getTerminalsFromPins.

9.2.17 @arduino/getResourceCount

: count = getResourceCount (ar, resource)

Get the count of uses of a given resource.

Inputs

ar - connected arduino object

resource - name of resource to get count for.

Outputs

count = count of uses registered to resource.

See also: incrementResourceCount. decrementResourceCount.

9.2.18 @arduino/getResourceOwner

: owner = getResourceOwner (ar, terminal)

Get the owner of pin allocated previously by configurePinResource.

Inputs

ar - connected arduino object

terminal - terminal number to get owner of.

Outputs

owner = owner of the terminal pin, or "" if not owned.

See also: configurePinResource.

9.2.19 @arduino/getSPITerminals

: pinlist = getSPITerminals (ar)

Get a cell list of pin Ids available for SPI mode.

Inputs

ar - the arduino object.

Outputs

pinlist - cell list of pin numbers available for SPI use.

See also: arduino.

9.2.20 @arduino/getServoTerminals

: pinlist = getServoTerminals (ar)

Get a cell list of pin Ids available for servo use.

Inputs

ar - the arduino object.

Outputs

pinlist - cell list of pin numbers available for servo use.

See also: arduino, getPWMTerminals.

9.2.21 @arduino/getSharedResourceProperty

: count = getSharedResourceProperty (ar, resource, property)

Get the value of a property from a given resource.

Inputs

ar - connected arduino object

resource - name of resource to get property for.

property - name of property from the resource.

Outputs

propvalue - value of the property

See also: getResourceCount, setSharedResourceProperty.

9.2.22 @arduino/getTerminalMode

: mode = getTerminalMode (ar, terminal)

Get the mode of a pin allocated previously by configurePinResource.

Inputs

ar - connected arduino object

terminal - terminal number to get owner of.

Outputs

mode - mode of the terminal pin, or "not_set" if not owned.

See also: configurePinResource, getResourceOwner.

9.2.23 @arduino/getTerminalsFromPins

: pinnums = getTerminalsFromPins (ar, pins)

Get the terminal number for each pin.

Inputs

ar - connected arduino object

pins - single pin name or cell or vector array of pin names.

Outputs

pinnums - pin number of each named pin. If the input was a single string, returns a number. if the input pins was a vector or cell array, return a cell array of pin numbers corresponding to each input pin name.

See also: arduino, getPinsFromTerminals.

9.2.24 @arduino/incrementResourceCount

: count = incrementResourceCount (ar, resource)

Increment the count value of a named resource by 1 and return the new count

Inputs

ar - connected arduino object

resource - name of resource to increment count.

Outputs

count = count of uses registered to resource.

See also: getResourceCount. decrementResourceCount.

9.2.25 @arduino/isTerminalAnalog

: ret = isTerminalAnalog (obj, terminal)

Return true if pin is capable of analog input

Inputs

ar - the connected arduino object

terminal is a terminal number to check

Outputs

ret return 1 if terminal is a analog pin, 0 otherwise

9.2.26 @arduino/isTerminalDigital

: ret = isTerminalDigital(obj, terminal)

Return true if pin is capable of digital functions

Inputs

ar - the connected arduino object

terminal is a terminal number to check

Outputs

ret return 1 if terminal is a digital pin, 0 otherwise

9.2.27 @arduino/playTone

: playTone (ar, pin, freq, duration)

Play a tone of a given frequency on a specified pin.

Inputs

ar - connected arduino object

pin - digital pin to play tone on

freq - frequency in hertz to play between 0 and 32767Hz.

duration duration in seconds to play tone between 0 and 30 seconds

If duration is 0 or not specified, tone will continue to play until next tone is commanded. If frequency is 0, tone will stop playing

NOTE: use of playTone can interfere with PWM output.

9.2.28 @arduino/readAnalogPin

: value = readAnalogPin (ar, pin)

Read analog voltage of pin.

Inputs

ar - connected arduino object.

pin - string name of the pin to read.

Outputs

value - analog value of the pin

Example


 ar = arduino ();
 readAnalogPin(ar, "A4");
 ans =
     87
 

See also: arduino, readVoltage.

9.2.29 @arduino/readDigitalPin

: value = readDigitalPin (obj, pin)

Read digital value from a digital I/O pin.

Inputs

ar - connected arduino object.

pin - string name of the pin to read.

Outputs

value - the logical value (0, 1, true false) of the current pin state.

Example


 a = arduino ();
 pinvalue = readDigitalPin (a, 'D5');
 

See also: arduino, writeDigitalPin.

9.2.30 @arduino/readVoltage

: voltage = readVoltage (ar, pin)

Read analog voltage of a pin.

Inputs

ar - connected arduino.

pin - pin name or number to query for voltage

Outputs

voltage - scaled pin value as a voltage

Example


 ar = arduino ();
 readVoltage(ar, "A4");
 ans =
     1.401
 

See also: arduino, readAnalogPin.

9.2.31 @arduino/reset

: reset (ar)

Send reset command to arduino hardware to force a hardware reset.

Inputs

ar - connected arduino object.

See also: arduino.

9.2.32 @arduino/sendCommand

: outdata, outsize = sendCommand (ar, libname, commandid)
: outdata, outsize = sendCommand (ar, libname, commandid, data)
: outdata, outsize = sendCommand (ar, libname, commandid, data, timeout)

Send a command with option data to the connected arduino, waiting up to a specified number of seconds for a response.

Inputs

ar - connected arduino object.

libname - library sending the command. The name should match a programmed library of the arduino, or an error will be displayed.

commandid - integer value for the command being sent to the arduino.

data - optional data sent with the command.

timeout - optional timeout to wait for data

Outputs

outdata - data returned back from the arduino in response to command

outsize - size of data received

If the arduino fails to respond with a valid reply, sendCommand will error.

See also: arduino.

9.2.33 @arduino/setSharedResourceProperty

: setSharedResourceProperty (ar, resource, propname, propvalue)
: setSharedResourceProperty (ar, resource, propname, propvalue, ___)

Set property values for a given resource.

Inputs

ar - connected arduino object

resource - name of resource to get property for.

propname - name of property from the resource.

propvalue - value of property from the resource.

Multiple propname, propvalue pairs can be given.

Outputs

None

Example


 ar = arduino();
 setSharedResourceProperty(ar, "myresource", "myproperty", [1 2 3])
 

See also: getSharedResourceProperty.

9.2.34 @arduino/uptime

: sec = uptime (ar)

Get the number of seconds the arduino board has been running concurrently.

Inputs

ar - the arduino object of the connection to an arduino board.

Outputs

sec - the number seconds the board has been running. Note that the count will wrap around after approximately 50 days.

See also: arduino.

9.2.35 @arduino/validatePin

: validatePin (ar, pin, type)

Validate that the mode is allowed for specified pin

If the mode is not valid, and error will be thrown.

Inputs

ar - connected arduino object

pin - name of pin to query mode validity of

mode - mode to query

Known modes are:

  • ’I2C’
  • ’SPI’
  • ’PWM’
  • ’Servo’
  • ’analog’
  • ’digital’

See also: arduino, configurePin.

9.2.36 @arduino/version

: ver = version (ar)

Get version of library code installed on arduino board

Inputs

ar - the arduino object of the connection to an arduino board.

Outputs

ver - version string in format of X.Y.Z.

See also: arduino.

9.2.37 @arduino/writeDigitalPin

: writeDigitalPin (ar, pin, value)

Write digital value to a digital I/O pin.

Inputs

ar - connected arduino object.

pin - string name of the pin to write to.

value - the logical value (0, 1, true false) to write to the pin.

If pin was unconfigured before using, pin is set into digital mode.

Example


 a = arduino();
 writeDigitalPin(a,'D5',1);
 

See also: arduino, readDigitalPin.

9.2.38 @arduino/writePWMDutyCycle

: writePWMDutyCyle (ar, pin, value)

Set pin to output a square wave with a specified duty cycle.

Inputs

ar - connected arduino object

pin - pin to write to.

value - duty cycle value where 0 = off, 0.5 = 50% on, 1 = always on.

Example


 a = arduino();
 writePWMDutyCycle(a,'D5',0.5);
 

See also: arduino, writePWMVoltage.

9.2.39 @arduino/writePWMVoltage

: writePWMVoltage (ar, pin, voltage)

Emulate an approximate voltage out of a pin using PWM.

Inputs

ar - connected arduino object

pin - pin to write to.

voltage - voltage to emulate with PWM, between 0 - 5.0

Example


 a = arduino();
 writePWMVoltage(a,'D5',1.0);
 

See also: arduino, writePWMDutyCycle.


9.3 Arduino I2C Functions

9.3.1 @device/delete

: delete (dev)

Free resources of a device object.

Inputs

dev - object to free

See also: device.

9.3.2 @device/disp

: disp (dev)

Display device object.

Inputs

dev - device object to display

See also: device.

9.3.3 @device/read

: data = read (dev, numbytes)
: data = read (dev, numbytes, precision)

Read a specified number of bytes from a i2c or serial device object using optional precision for bytesize.

Inputs

dev - connected i2c or serial device opened using device

numbytes - number of bytes to read.

precision - Optional precision for the output data read data. Currently known precision values are uint8 (default), int8, uint16, int16

Outputs

data - data read from the device

See also: arduino, device.

9.3.4 @device/readRegister

: data = readRegister (dev, reg, numbytes)
: data = readRegister (dev, reg, numbytes, precision)

Read a specified number of bytes from a register of an i2cdev object using optional precision for bytesize.

Inputs

dev - connected i2c device opened using device

reg - registry value number

numbytes - number of bytes to read.

precision - Optional precision for the output data read data. Currently known precision values are uint8 (default), int8, uint16, int16

Output

data - data read from device.

See also: arduino, device.

9.3.5 @device/subsref

: val = subsref (dev, sub)

subref for device

See also: device.

9.3.6 @device/write

: write (dev, datain)
: write (dev, datain, precision)

Write data to a I2C or serial device object using optional precision for the data byte used for the data.

Inputs

dev - connected i2c or serial device opened using device

datain - data to write to device. Datasize should not exceed the constraints of the data type specified for the precision.

precision - Optional precision for the input write data. Currently known precision values are uint8 (default), int8, uint16, int16

See also: arduino, device, read.

9.3.7 @device/writeRegister

: writeRegister (dev, reg, datain)
: writeRegister (dev, dev, datain, precision)

Write data to i2c device object at a given registry position using optional precision for the data byte used for the data.

Inputs

dev - connected i2c device opened using device

reg - registry position to write to.

datain - data to write to device. Datasize should not exceed the constraints of the data type specified for the precision.

precision - Optional precision for the input write data. Currently known precision values are uint8 (default), int8, uint16, int16

See also: arduino, device, read.

9.3.8 @i2cdev/delete

: delete (dev)

Free resources of a i2cdev object.

Inputs

dev - object to free

See also: i2cdev.

9.3.9 @i2cdev/disp

: disp (dev)

Display i2cdev object.

Inputs

dev - i2cdev object

See also: i2cdev.

9.3.10 @i2cdev/i2cdev

: dev = i2cdev (ar, address)
: dev = i2cdev (ar, address, propname, propvalue)

i2cdev is depreciated and will be removed in a future version. Use device instead.

Create an i2cdev object to communicate to the i2c port on a connected arduino.

Inputs

ar - connected arduino object

address - address to use for device on I2C bus.

propname, propvalue - property name/value pair for values to pass to devices.

Currently known properties:

bus

bus number (when arduino board supports multiple I2C buses) with value of 0 or 1.

Outputs

dev - new created i2cdev object.

Properties

The i2cdev object has the following public properties:

parent

The parent (arduino) for this device

pins

pins used by this object

bus

bus used for created object

address

I2C address set for object

See also: arduino.

9.3.11 @i2cdev/read

: data = read (dev, numbytes)
: data = read (dev, numbytes, precision)

Read a specified number of bytes from a i2cdev object using optional precision for bytesize.

Inputs

dev - connected i2c device opened using i2cdev

numbytes - number of bytes to read.

precision - Optional precision for the output data read data. Currently known precision values are uint8 (default), int8, uint16, int16

Outputs

data - data read from i2cdevice

See also: arduino, i2cdev.

9.3.12 @i2cdev/readRegister

: data = readRegister (dev, reg, numbytes)
: data = readRegister (dev, reg, numbytes, precision)

Read a specified number of bytes from a register of an i2cdev object using optional precision for bytesize.

Inputs

dev - connected i2c device opened using i2cdev

reg - registry value number

numbytes - number of bytes to read.

precision - Optional precision for the output data read data. Currently known precision values are uint8 (default), int8, uint16, int16

Output

data - data read from device.

See also: arduino, i2cdev.

9.3.13 @i2cdev/subsref

: val = subsref (dev, sub)

subref for i2cdev

See also: i2cdev.

9.3.14 @i2cdev/write

: write (dev, datain)
: write (dev, datain, precision)

Write data to a i2cdev object using optional precision for the data byte used for the data.

Inputs

dev - connected i2c device opened using i2cdev

datain - data to write to device. Datasize should not exceed the constraints of the data type specified for the precision.

precision - Optional precision for the input write data. Currently known precision values are uint8 (default), int8, uint16, int16

See also: arduino, i2cdev, read.

9.3.15 @i2cdev/writeRegister

: writeRegister (dev, reg, datain)
: writeRegister (dev, dev, datain, precision)

Write data to i2cdev object at a given registry position using optional precision for the data byte used for the data.

Inputs

dev - connected i2c device opened using i2cdev

reg - registry position to write to.

datain - data to write to device. Datasize should not exceed the constraints of the data type specified for the precision.

precision - Optional precision for the input write data. Currently known precision values are uint8 (default), int8, uint16, int16

See also: arduino, i2cdev, read.

9.3.16 scanI2Cbus

: retval = scanI2Cbus (ar)
: retval = scanI2Cbus (ar, bus)

Scan arduino for devices on the I2C bus.

Inputs

ar - arduino object connected to a arduino board.

bus - bus number to scan I2C devices, when multiple buses are available. If the bus is not specified, it will default to 0.

Outputs

retval - cell array of addresses as strings in format of "0xXX".

Example


 # create arduino connection.
 ar = arduino();
 # scan for devices on the I2C bus
 scanI2Cbus (ar)
 # output is each detected i2c address as a string
 ans =
{
  [1,1] = 0x50
}
 

See also: arduino, i2cdev, checkI2CAddress.


9.4 Arduino Rotary Encoder Functions

9.4.1 @rotaryEncoder/delete

: delete (dev)

Free resources of a encoder object.

Inputs

dev - object to free

See also: rotartEncoder.

9.4.2 @rotaryEncoder/disp

: retval = disp (obj)

Display the rotary encoder object in a verbose way,

Inputs

obj - the arduino rotary encoder object created with rotaryEncoder

See also: rotaryEncoder.

9.4.3 @rotaryEncoder/readCount

: [count, time] = readCount (obj)
: [count, time] = readCount (obj, name, value)

read count value from the rotary encoder.

subsubheading Inputs obj - rotary encoder object created with rotaryEncoder call.

name, value - optional name,value pairs

Valid option name pairs currently are:

reset

Reset the count after reading (if true)

Outputs

count - returned count read from the encoder.

time - seconds since arduino started

See also: rotaryEncoder, resetCount.

9.4.4 @rotaryEncoder/readSpeed

: speed = readSpeed (obj)

read rotational speed from the rotary encoder.

Inputs

obj - rotary encoder object created with rotaryEncoder call.

Outputs

speed - returned speed in revolutions per minute read from the encoder.

See also: rotaryEncoder, resetCount.

9.4.5 @rotaryEncoder/resetCount

: reset (obj)
: reset (obj, cnt)

reset the rotary encoder count values

Inputs

obj - the rotaryEncoder object

cnt - optional count value to reset to

See also: rotaryEncoder, readCount.

9.4.6 @rotaryEncoder/rotaryEncoder

: obj = rotaryEncoder (ar, chanApin, chanBpin)
: obj = rotaryEncoder (ar, chanApin, chanBpin, ppr)

Create a rotaryEncoder object controlled by the input pins.

Inputs

ar - connected arduino object.

chanApin - pin used for channel A

chanBpin - pin used for channel B

ppr - count of encoder pulsed required for a full revolution of the encoder.

Outputs

obj - created rotary encoder object

Example

 a = arduino ();
 enc = rotaryEncoder(a, "d2", "d3", 180);

Properties

The rotaryEncoder object has the following public properties:

parent

The parent (arduino) for this device

pins

pins used by this object

ppr

Number of pulses used per rotation

See also: arduino.

9.4.7 @rotaryEncoder/subsref

: val = subsref (dev, sub)

subref for rotaryEncoder

See also: rotaryEncoder.


9.5 Arduino Servo Functions

9.5.1 @servo/delete

: delete (dev)

Free resources of a servo object.

Inputs

dev - object to free

See also: servo.

9.5.2 @servo/disp

: disp (dev)

Display servo object.

Inputs

dev - servo device to display

See also: servo.

9.5.3 @servo/readPosition

: position = readPosition (servo)

Read the position of a servo

Inputs

servo - servo object created from arduino.servo.

Outputs

position - value between 0 .. 1 for the current servo position, where 0 is the servo min position, 1 is the servo maximum position.

See also: servo, writePosition.

9.5.4 @servo/servo

: obj = servo (arduinoobj, pin)
: obj = servo (arduinoobj, pin, propertyname, propertyvalue)

Create a servo object using a specified pin on a arduino board.

Inputs

obj - servo object

arduinoobj - connected arduino object

propertyname, propertyvalue - name value pairs for properties to pass to the created servo object.

Current properties are:

minpulseduration

min PWM pulse value in seconds.

maxpulseduration

max PWM pulse value in seconds.

Outputs

obj - created servo object.

Example

 # create arduino connection
 ar = arduino();
 # create hobby servo (1 - 2 ms pulse range)
 servo = servo(ar, "d9", "minpulseduration", 1.0e-3, "maxpulseduration", 2e-3);
 # center the servo
 writePosition(servo, 0.5);

Properties

The servo object has the following public properties:

parent

The parent (arduino) for this device

pins

pins used by this object

minpulseduration

minpulseduration set for object

maxpulseduration

maxpulseduration set for object

See also: arduino, readPosition, writePosition.

9.5.5 @servo/subsref

: val = subsref (dev, sub)

subref for servo

See also: servo.

9.5.6 @servo/writePosition

: writePosition (servo, position)

Write the position to a servo.

Inputs

servo - servo object created from arduino.servo.

position - value between 0 .. 1 for the current servo position, where 0 is the servo min position, 1 is the servo maximum position.

See also: servo, readPosition.


9.6 Arduino Shiftregister Functions

9.6.1 @shiftRegister/delete

: delete (dev)

Free resources of a shiftRegister object.

Inputs

dev - object to free

See also: shiftRegister.

9.6.2 @shiftRegister/disp

: disp (register)

Display the register object in a verbose way,

Inputs

register - the arduino register object created with shiftRegister.

See also: shiftRegister.

9.6.3 @shiftRegister/read

: retval = read (register)
: retval = read (register, precision)

read a value from the shift register.

Inputs

register - shift register created from shiftRegister call.

precision - optional precision of the data, where precision can be a number in a multiple of 8 (ie: 8,16,32) or can be a named integer type: 8 of ’uint8’, ’uint16’, ’uint32’. The default precision is 8.

Outputs

retval - returned data read from the register.

See also: shiftRegister, write.

9.6.4 @shiftRegister/reset

: reset (register)

clear the shift register value.

Inputs

register - shift register created from shiftRegister call.

See also: shiftRegister, read, write.

9.6.5 @shiftRegister/shiftRegister

: register = shiftRegister (ar, shifttype, dataPin, clockPin ...)
: register = shiftRegister (ar,'74hc164', dataPin, clockPin, resetPin)
: register = shiftRegister (ar,'74hc165', dataPin, clockPin, loadPin, clockEnablePin)
: register = shiftRegister(ar,'74hc595', dataPin, clockPin, latchPin , resetPin)

Create shift register of a given type, controlled by the input pins.

Inputs

Common function parameter definition:

ar - connected arduino object.

shifttype - string name of the shift register type.

dataPin - pin used for data in/out of the device.

clockPin - pin used for clocking data on the shiftRegister.

Other variables are dependent on the shift register type:

’74hc164’

Additional inputs:

resetPin - optional pin for resetting the shift register.

’74hc165’

Additional inputs:

loadPin - load pin to the shift register. clockEnablePin - clock enable pin.

’74hc595’

Additional inputs:

latchPin - latching data to the shift register. resetPin - optional pin for resetting the shift register.

Outputs

register - register object

Properties

The shiftRegister object has the following public properties:

parent

The parent (arduino) for this device

pins

pins used by this object

model

model set for object

See also: arduino.

9.6.6 @shiftRegister/subsref

: val = subsref (dev, sub)

subref for shiftRegister

See also: shiftRegister.

9.6.7 @shiftRegister/write

: write (register, dataIn)
: write (register, dataIn, precision)

Write a value to the shift register.

Inputs

register - shift register created from shiftRegister call.

dataIn - data to clock into the shiftRegister.

precision - optional precision of the data, where precision can be a number in a multiple of 8 (ie: 8,16,32) or can be a named integer type of ’uint8’, ’uint16’, ’uint32’. The default precision is 8.

See also: shiftRegister, read.


9.7 Arduino SPI Functions

9.7.1 @device/delete

: delete (dev)

Free resources of a device object.

Inputs

dev - object to free

See also: device.

9.7.2 @device/disp

: disp (dev)

Display device object.

Inputs

dev - device object to display

See also: device.

9.7.3 @device/subsref

: val = subsref (dev, sub)

subref for device

See also: device.

9.7.4 @device/writeRead

: dataOut = readWrite (spi, dataIn)

Write uint8 data to spi device and return back clocked out response data of same size.

Inputs

spi - connected spi device on arduino

dataIn - uint8 sized data to send to spi device framed between SS frame.

Outputs

dataOut - uint8 data clocked out during send to dataIn.

See also: arduino, device.

9.7.5 @spidev/delete

: delete (dev)

Free resources of a spidev object.

Inputs

dev - spidev object to free

See also: spidev.

9.7.6 @spidev/disp

: disp (dev)

Display spidev object.

Inputs

dev - spidev object to display

See also: spidev.

9.7.7 @spidev/spidev

: dev = spidev (ar, cspin)
: dev = spidev (ar, cspin, propname, propvalue)

spidev is depreciated and will be removed in a future version. Use device instead.

Create an spidev object to communicate to the SPI port on a connected arduino.

Inputs

ar - connected arduino object

cspin - chip select pin for attached spi device.

propname, propvalue - property name/value pair for values to pass to devices.

Currently known properties:

bitrate

bit rate speed in Mbs

bitorder

’msbfirst’ or ’lsbfirst’

mode

SPI mode 0 - 3.

Outputs

dev - created spidev object

Properties

The spidev object has the following public properties:

parent

The parent (arduino) for this device

pins

pins used by this object

mode

mode used for created object

bitrate

Bitrate set for object

bitorder

Bitorder set for object

chipselectpin

Pin used for chipselect

See also: arduino, readWrite.

9.7.8 @spidev/subsref

: val = subsref (dev, sub)

subref for spidev

See also: spidev.

9.7.9 @spidev/writeRead

: dataOut = readWrite (spi, dataIn)

Write uint8 data to spi device and return back clocked out response data of same size.

Inputs

spi - connected spi device on arduino

dataIn - uint8 sized data to send to spi device framed between SS frame.

Outputs

dataOut - uint8 data clocked out during send to dataIn.

See also: arduino, spidev.


9.8 Arduino Serial Functions

9.8.1 @device/delete

: delete (dev)

Free resources of a device object.

Inputs

dev - object to free

See also: device.

9.8.2 @device/device

: dev = device (ar, 'I2CAddress', address)
: dev = device (ar, 'SPIChipSelectPin', pin)
: dev = device (ar, 'Serial', serialid)
: dev = device (..., propname, propvalue)

Create an i2c, spi or serial object to communicate on a connected arduino.

Inputs

ar - connected arduino object

propname, propvalue - property name/value pair for values to pass to devices.

A property of ’i2caddress’, ’spichipselectpin’ or ’serial’ must be specified to denote the device type to create.

i2caddress - address to use for device on I2C bus.

pin - pin to use for device SPI chip select.

serialid - Serial port id to use

Additional properties can also be specified for the device object

Currently known input I2C properties values:

bus

bus number (when arduino board supports multiple I2C buses) with value of 0 or 1.

noprobe

Do not probe the existence of device on creation if set to 1 (default 0)

bitrate

bit rate speed in Mbs - default 100000

Currently known input SPI properties values:

bitrate

bit rate speed in Mbs

bitorder

’msbfirst’ or ’lsbfirst’

spimode

SPI mode 0 - 3.

Currently known input Serial properties values:

baudrate

baudrate value (default 9600)

databits

number of databits (5,6,7,8) (default 8)

stopbits

number of stopbits (1,2) (default 1)

parity

parity of device (’odd’,’even’,’none’) (default ’none’)

Outputs

dev - new created device object.

Properties

The object has the following public properties:

parent

The parent (arduino) for this device

interface

The interface type for this device ("SPI" or "I2C" or "Serial")

In addition, depending on type, the object will have these properties:

I2C Properties

The object has the following public properties:

bus

bus used for created object

i2caddress

I2C address set for object

sclpin

the SCL pin of the device

sdapin

the SDA pin of the device

bitrate

bit rate for the i2c clock

SPI Properties

The object has the following public properties:

spimode

mode used for created object

bitrate

Bitrate set for object

bitorder

Bitorder set for object

spichipselectpin

Pin used for chipselect

mosipin

Pin used for mosi

misopin

Pin used for miso

sckpin

Pin used for sckpin

Serial Properties

The object has the following public properties:

id

serial port id

baudrate

baudrate

databits

number of databits (5,6,7,8)

stopbits

number of stopbits (1,2)

parity

parity of device (’odd’,’even’,’none’)

See also: arduino, i2cdev, spidev.

9.8.3 @device/disp

: disp (dev)

Display device object.

Inputs

dev - device object to display

See also: device.

9.8.4 @device/flush

: data = flush (dev)
: data = flush (dev, "input")
: data = flush (dev, "output")

Flush the serial port buffers

Inputs

dev - connected serial device opened using device

If an additional parameter is provided of "input" or "output", then only the input or output buffer will be flushed

Outputs

None

See also: arduino, device, read.

9.8.5 @device/read

: data = read (dev, numbytes)
: data = read (dev, numbytes, precision)

Read a specified number of bytes from a i2c or serial device object using optional precision for bytesize.

Inputs

dev - connected i2c or serial device opened using device

numbytes - number of bytes to read.

precision - Optional precision for the output data read data. Currently known precision values are uint8 (default), int8, uint16, int16

Outputs

data - data read from the device

See also: arduino, device.

9.8.6 @device/subsref

: val = subsref (dev, sub)

subref for device

See also: device.

9.8.7 @device/write

: write (dev, datain)
: write (dev, datain, precision)

Write data to a I2C or serial device object using optional precision for the data byte used for the data.

Inputs

dev - connected i2c or serial device opened using device

datain - data to write to device. Datasize should not exceed the constraints of the data type specified for the precision.

precision - Optional precision for the input write data. Currently known precision values are uint8 (default), int8, uint16, int16

See also: arduino, device, read.


9.9 Arduino Device Functions

9.9.1 @device/delete

: delete (dev)

Free resources of a device object.

Inputs

dev - object to free

See also: device.

9.9.2 @device/device

: dev = device (ar, 'I2CAddress', address)
: dev = device (ar, 'SPIChipSelectPin', pin)
: dev = device (ar, 'Serial', serialid)
: dev = device (..., propname, propvalue)

Create an i2c, spi or serial object to communicate on a connected arduino.

Inputs

ar - connected arduino object

propname, propvalue - property name/value pair for values to pass to devices.

A property of ’i2caddress’, ’spichipselectpin’ or ’serial’ must be specified to denote the device type to create.

i2caddress - address to use for device on I2C bus.

pin - pin to use for device SPI chip select.

serialid - Serial port id to use

Additional properties can also be specified for the device object

Currently known input I2C properties values:

bus

bus number (when arduino board supports multiple I2C buses) with value of 0 or 1.

noprobe

Do not probe the existence of device on creation if set to 1 (default 0)

bitrate

bit rate speed in Mbs - default 100000

Currently known input SPI properties values:

bitrate

bit rate speed in Mbs

bitorder

’msbfirst’ or ’lsbfirst’

spimode

SPI mode 0 - 3.

Currently known input Serial properties values:

baudrate

baudrate value (default 9600)

databits

number of databits (5,6,7,8) (default 8)

stopbits

number of stopbits (1,2) (default 1)

parity

parity of device (’odd’,’even’,’none’) (default ’none’)

Outputs

dev - new created device object.

Properties

The object has the following public properties:

parent

The parent (arduino) for this device

interface

The interface type for this device ("SPI" or "I2C" or "Serial")

In addition, depending on type, the object will have these properties:

I2C Properties

The object has the following public properties:

bus

bus used for created object

i2caddress

I2C address set for object

sclpin

the SCL pin of the device

sdapin

the SDA pin of the device

bitrate

bit rate for the i2c clock

SPI Properties

The object has the following public properties:

spimode

mode used for created object

bitrate

Bitrate set for object

bitorder

Bitorder set for object

spichipselectpin

Pin used for chipselect

mosipin

Pin used for mosi

misopin

Pin used for miso

sckpin

Pin used for sckpin

Serial Properties

The object has the following public properties:

id

serial port id

baudrate

baudrate

databits

number of databits (5,6,7,8)

stopbits

number of stopbits (1,2)

parity

parity of device (’odd’,’even’,’none’)

See also: arduino, i2cdev, spidev.

9.9.3 @device/disp

: disp (dev)

Display device object.

Inputs

dev - device object to display

See also: device.

9.9.4 @device/flush

: data = flush (dev)
: data = flush (dev, "input")
: data = flush (dev, "output")

Flush the serial port buffers

Inputs

dev - connected serial device opened using device

If an additional parameter is provided of "input" or "output", then only the input or output buffer will be flushed

Outputs

None

See also: arduino, device, read.

9.9.5 @device/read

: data = read (dev, numbytes)
: data = read (dev, numbytes, precision)

Read a specified number of bytes from a i2c or serial device object using optional precision for bytesize.

Inputs

dev - connected i2c or serial device opened using device

numbytes - number of bytes to read.

precision - Optional precision for the output data read data. Currently known precision values are uint8 (default), int8, uint16, int16

Outputs

data - data read from the device

See also: arduino, device.

9.9.6 @device/readRegister

: data = readRegister (dev, reg, numbytes)
: data = readRegister (dev, reg, numbytes, precision)

Read a specified number of bytes from a register of an i2cdev object using optional precision for bytesize.

Inputs

dev - connected i2c device opened using device

reg - registry value number

numbytes - number of bytes to read.

precision - Optional precision for the output data read data. Currently known precision values are uint8 (default), int8, uint16, int16

Output

data - data read from device.

See also: arduino, device.

9.9.7 @device/subsref

: val = subsref (dev, sub)

subref for device

See also: device.

9.9.8 @device/write

: write (dev, datain)
: write (dev, datain, precision)

Write data to a I2C or serial device object using optional precision for the data byte used for the data.

Inputs

dev - connected i2c or serial device opened using device

datain - data to write to device. Datasize should not exceed the constraints of the data type specified for the precision.

precision - Optional precision for the input write data. Currently known precision values are uint8 (default), int8, uint16, int16

See also: arduino, device, read.

9.9.9 @device/writeRead

: dataOut = readWrite (spi, dataIn)

Write uint8 data to spi device and return back clocked out response data of same size.

Inputs

spi - connected spi device on arduino

dataIn - uint8 sized data to send to spi device framed between SS frame.

Outputs

dataOut - uint8 data clocked out during send to dataIn.

See also: arduino, device.

9.9.10 @device/writeRegister

: writeRegister (dev, reg, datain)
: writeRegister (dev, dev, datain, precision)

Write data to i2c device object at a given registry position using optional precision for the data byte used for the data.

Inputs

dev - connected i2c device opened using device

reg - registry position to write to.

datain - data to write to device. Datasize should not exceed the constraints of the data type specified for the precision.

precision - Optional precision for the input write data. Currently known precision values are uint8 (default), int8, uint16, int16

See also: arduino, device, read.


9.10 Arduino Ultrasonic Functions

9.10.1 @ultrasonic/delete

: delete (dev)

Free resources of a ultrasonic object.

Inputs

dev - ultrasonic object to free

See also: ultrasonic.

9.10.2 @ultrasonic/disp

: disp (dev)

Display ultrasonic object.

Inputs

dev - ultrasonic object to display

See also: ultrasonic.

9.10.3 @ultrasonic/readDistance

: distance = readDistance (dev)

Read the distance from a ultrasonic device

Inputs

dev - connected ultrasonic device opened using ultrasonic

Outputs

distance - distance value in meters from the ultrasonic device, or Inf if out of sensor range

See also: arduino, ultrasonic.

9.10.4 @ultrasonic/readEchoTime

: time = readEchoTime (dev)

Measure the time for waves to reflect back to the ultrasonic device

Inputs

dev - connected ultrasonic device opened using ultrasonic()

Outputs

time - time in seconds, or Inf if out of sensor range

See also: arduino, ultrasonic.

9.10.5 @ultrasonic/subsref

: val = subsref (dev, sub)

subref for ultrasonic

See also: ultrasonic.

9.10.6 @ultrasonic/ultrasonic

: dev = ultrasonic (ar, triggerpin)
: dev = ultrasonic (ar, triggerpin, echopin)
: dev = ultrasonic (ar, triggerpin, echopin, propname, propvalue)

Create an ultrasonic object to communicate to a connected ultrasonic device

Inputs

ar - connected arduino object

triggerpin - trigger pin for attached device.

echopin - trigger pin for attached device.

propname, propvalue - property name/value pair for values to pass to devices.

Currently known properties:

outputformat

string designating number format for output (’double’)

Outputs

dev - created ultrasonic object

Properties

The ultrasonic object has the following public properties:

parent

The parent (arduino) for this device

pins

pins used by this object

triggerpin

trigger used for created object

echopin

Echo pin set for object

outputformat

Output format for the created object

See also: arduino, readDistance, readEchoTime.


9.11 Arduino Addons

9.11.1 addon

: retval = addon (ar, addonname)
: retval = addon (ar, addonname, varargs)

Create an addon object using the addon named class.

Inputs

ar - connected arduino object

addonname - the name of the addon to create. The addon name can be a user addon or an inbuilt addon, however must appear in the listArduinoLibraries output and have been programmed onto the arduino.

varargs - optional values that will be provided verbatim to the the addon class constructor.

Outputs

retval - cell array of string library names.

See also: arduino, arduinosetup, listArduinoLibraries.

9.11.2 arduinoioaddons.EEPRomAddon.EEPRom

: arduinoioaddons.EEPRomAddon.EEPRom

EEPROM addon for arduino

Allows read and write of uint8 data to the onboard arduino EEPROM.

Example

Assuming eeprom addon has been programmed into the Arduino:

 a = arduino ();
 e = addon (a, "eepromaddon/eeprom");
 write (e, 0, uint8("hello world"));
 str = uint8( read(e, 0, 11) )

See also: addon.

Properties

length - Size of the EEPROM.

Methods

: eeprom = EEPRom ()

Constructor to create EEPROM device.

Outputs

eeprom - created EEPROM device.

: erase ()

Erase all values in EEPROM (Effectively setting the 0xFF)

: write (address, uintdata)

Write data to EEPROM at the provided address.

Inputs

address - start address to write data to, should be an integer between 0 and the size of the EEPROM.

uintdata a value or array of uint8 data to write to EEPROM.

: data = read (address)
: data = read (address, count)

Read data from starting address of EEPROM.

Inputs

address - start address to read data from, should be an integer between 0 and the size of the EEPROM.

count - Number of uint8 values to read from the EEPROM (default is 1)

Outputs

data a value or array of uint8 data read from the EEPROM.

9.11.3 arduinoioaddons.ExampleAddon.Echo

: arduinoioaddons.ExampleAddon.Echo

Basic Example matlab/octave code to illustrate creating a user addon.

See also: addon.

Properties

Parent - the parent arduino object.

Pins - the pins allocated the addon.

Methods

: obj = Echo(arObj)

Constructor to create Echo addon

Inputs

arObj - the arduino parent object

Outputs

obj - created Echo object

: response = shout(text)

Send text to arduino and receive back the echoed reply

Inputs

text - text to send to arduino

Outputs

response - response from the arduino, which should be the same as the input text.

9.11.4 arduinoioaddons.ExampleLCD.LCD

: arduinoioaddons.LCDAddon.LCD

Basic Example octave addon for LCD

Allows basic manipulation of an LCD as a illustration of using the addon functionality.

Example

Assuming the arduino has been programmed with the lcd addon:

 a = arduino();
 lcd = addon(a, "examplelcd/lcd", "d8", "d9", "d4", "d5", "d6", "d7")
 clearLCD(lcd);
 printLCD(lcd, "Hello");
 # go to next line
 gotoLCD(lcd, 0, 1);
 printLCD(lcd, "World");

See also: addon.

Properties

Pins - the pins allocated the LCD display.

Methods

: lcd = LCD(arObj, rs, enable, d0, d1, d2, d3)

Constructor to create LCD device

Inputs

arObj - the arduino parent object

rs - the pin to use for the rs line.

enable - the pin to use for the enable line.

d0 - the pin to use for the d0 line.

d1 - the pin to use for the d1 line.

d2 - the pin to use for the d2 line.

d3 - the pin to use for the d3 line.

Outputs

lcd - created LCD object

: freeLCD()

Free the LCD

Should be called before discarding the LCD

Inputs

None.

Outputs

None.

: clearLCD()

Clear the LCD display and set the cursor position to the home position.

Inputs

None.

Outputs

None.

: printLCD(text)

Display text on LCD starting at the current cursor position.

Inputs

text - text to display on LCD

Outputs

None.

: gotoLCD(col, row)

Set the cursor position to row, col

Inputs

col - 0 indexed LCD column to position to.

row - 0 indexed LCD row to position to.

Outputs

None.

9.11.5 arduinoioaddons.RTCAddon.DS1307

: arduinoioaddons.RTCAddon.DS1307

DS1307 addon

See also: addon.

Properties

Parent - the parent arduino object.

Pins - the pins allocated the addon.

Methods

: obj = DS1307(arObj)
: obj = DS1307(arObj, propertyname, propertyvalue ....)

Constructor to create DS1307 addon

Inputs

arObj - the arduino parent object

propertyname, propertyvalue - optional property name, value pairs. Current known properties are:

address

I2C address of the DS1307 (default 0x68)

Outputs

obj - created DS1307 object

Example


 a = arduino()
 rtc = addon(a, "rtcaddon/ds1307")
 
: date = clock(dsObj)
: clock(dsObj, date)

Get/set the DS1307 clock

Inputs

dsObj - the ds1307 object

date - a date vector in same format as datevec and clock

Outputs

date - a date vector in same format as datevec and clock

Example


 a = arduino()
 rtc = addon(a, "rtcaddon/ds1307")
 # get and display rtc time as a date string
 datestr(rtc.clock)
 

See also: datevec.

: ctrl = control(dsObj)
: control(dsObj, ctrl)

Get/set the DS1307 clock

Inputs

dsObj - the ds1307 object

ctrl - a structure containing the control bit fields.

Outputs

ctrl - a structure containing the control bit fields.

Control structure fields are: Current properties are:

out

Out bit in the control register

sqwe

Square wave enable bit in control register

rs

The combined RS0, RS1 value

: YN = isstarted(dsObj)

Get whether the RTC clock is currently counting time

Inputs

dsObj - the ds1307 object

Outputs

YN - returns true if the RTC is counting

See also: start, stop.

: start(dsObj)

Start the RTC counting

Inputs

dsObj - the ds1307 object

Outputs

None

See also: datevec.

: stop(dsObj)

Stop the RTC counting

Inputs

dsObj - the ds1307 object

Outputs

None

See also: datevec.

9.11.6 arduinoioaddons.SimpleStepper.SimpleStepper

: arduinoioaddons.SimpleStepper

Stepper class for stepper control using ULN2003 and compatible drivers

Properties

Id

Id of the stepper (Read only)

Speed

Number of steps to do per second.

Status

Status of stepper (Read only). 0 = not moving, 1 = moving, 2 = rotating

Parent

the Arduino parent (read only)

Pins

the pins used for the stepper (read only)

Methods

: obj = SimpleStepper(aObj, pin1, pin2, pin3, pin4)
: obj = SimpleStepper(aObj, pin1, pin2, pin3, pin4, pin5)

Constructor to create a stepper object

Inputs

aObj - The arduino

pin1 - The first pin of the controller

pin2 - The second pin of the controller

pin3 - The third pin of the controller

pin4 - The fourth pin of the controller

pin5 - The fifth pin of the controller

Outputs

s - a simplestepper object

Example


 a = arduino()
 # create stepper object
 s = addon(a, "simplestepper/simplestepper", "d2", "d3", "d4", "d5")
 # start rotating left
 s.rotate(-1);
 

See also: addon.

: move(sObj, steps)

Move the motor the specified number of steps using the configured Speed.

Inputs

sObj - the stepper object

steps - the number of steps to move. steps less than 0 will be moving left.

Outputs

None

See also: rotate.

: rotate(sObj, dir)

Start steppermotor moving in the specified direction using the configured Speed.

Inputs

sObj - the stepper object

dir - Direction to move. -1 = left, 0 = stop, 1 = right.

Outputs

None

See also: move.

: release(sObj)

Release this stepper motor

Inputs

sObj - the stepper object

Outputs

None

9.11.7 arduinoioaddons.adafruit.dcmotorv2

: arduinoioaddons.adafruit.dcmotorv2

DC Motor class for dc motor control on the adafruit motor shield

See also: arduinoioaddons.adafruit.motorshieldv2.

Properties

Speed - The speed value set for the motor

Parent - The parent shield for object (read only)

MotorNumber - The motor number (read only) values 1-4

IsRunning - boolean for if the motor is started (read only)

Methods

: obj = dcmotorv2(mObj, mnum)
: obj = dcmotorv2(mObj, mnum, propertyname, propertyvalue ....)

Constructor to create dcmotor object

Inputs

mObj - the motor shield object

mnum - The motor number (1 - 4)

propertyname, propertyvalue - Optional property name/value pairs to pass to motor object.

Current known properties are:

Speed

Initial speed (default 0). Should be a value between -1 and 1.

Outputs

s - a dcmotorv2 object

Example


 a = arduino()
 ms = addon(a, "adafruit/motorshieldv2")
 mtr = dcmotor(ms, 1)
 
: start(dcObj)

Start the motor moving in previously set speed/direction

Inputs

dcObj - the dcmotor object

Outputs

None

See also: adafruit.motorshieldv2.

: stop(dcObj)

Stop the motor moving

Inputs

dcObj - the dcmotor object

Outputs

None

See also: adafruit.motorshieldv2.

9.11.8 arduinoioaddons.adafruit.motorshieldv2

: arduinoioaddons.adafruit.motorshieldv2

Adafruit motor shield addon

See also: addon.

Properties

Parent - the parent arduino object.

Pins - the pins allocated the addon.

I2CAddress - the i2c address used for accessing this shield.

PWMFrequency - the set PWM frequency for this shield.

Methods

: obj = motorshieldv2(arObj)
: obj = motorshieldv2(arObj, propertyname, propertyvalue ....)

Constructor to create motorshieldv2 addon object

Inputs

arObj - the arduino parent object

propertyname, propertyvalue - optional property name, value pairs. Current known properties are:

address

I2C address of the motor shield (default 0x60)

pwmfrequency

PWM Frequency to set on shield (default 1600)

Outputs

obj - created motorshieldv2 object

Example


 a = arduino()
 mtr = addon(a, "adafruit/motorshieldv2")
 
: s = servo(mObj, mtrnum)
: s = servo(mObj, mtrnum, propertyname, propertyvalue ...)

Create a servo object

Inputs

mObj - the motor shield object

mtrnum - The servo motor number, where 1 is servo on pin "d10" and 2 is a servo on pin "d9"

propertyname, propertyvalue - Optional property name/value pairs to pass to servo object.

Properties are the same as the base servo object.

Outputs

s - a servo object

Example


 a = arduino()
 ms = addon(a, "adafruit/motorshieldv2")
 # get servo 1 (servo on pin D10)
 s = ms.servo(1)
 

The function if the equivalent of calling the arduino.servo with the D9 or D10 pin has the input pin.

See also: servo.

: s = stepper(mObj, mtrnum, stepsperrev)
: s = stepper(mObj, mtrnum, stepsperrev, propertyname, propertyvalue ...)

Create a stepper motor object

Inputs

mObj - the motor shield object

mtrnum - The stepper motor number (1 or 2)

stepsperrev - Number of steps per revolution.

propertyname, propertyvalue - Optional property name/value pairs to pass to stepper object.

Outputs

s - a stepper object

: s = dcmotor(mObj, mtrnum)
: s = dcmotor(mObj, mtrnum, propertyname, propertyvalue ...)

Create a dcmotor motor object

Inputs

mObj - the motor shield object

mtrnum - The motor number (1 - 4)

propertyname, propertyvalue - Optional property name/value pairs to pass to motor object.

Outputs

s - a dcmotorv2 object

9.11.9 arduinoioaddons.adafruit.stepper

: arduinoioaddons.adafruit.stepper

Stepper class for stepper control on the adafruit motor shield

See also: arduinoioaddons.adafruit.motorshieldv2.

Properties

RPM

The rpm value set for the stepper motor

StepType

the StepType for the stepper (string) which can be "single", "double", "interleave" or "microstep"

StepsPerRevolution

the StepsPerRevoluion for the stepper (read only)

MotorNumber

the motor number for the stepper (read only) value will be 1 or 2.

Parent

the parent shield of this stepper (read only)

Methods

: obj = stepper(mObj, mnum, stepsperrev)
: obj = stepper(mObj, mnum, stepsperrev, propertyname, propertyvalue ....)

Constructor to create dcmotor object

Inputs

mObj - the motor shield object

mnum - The motor number (1 or 2)

stepsperrev - Number of steps per revolution.

propertyname, propertyvalue - Optional property name/value pairs to pass to motor object.

Current known properties are:

RPM

the RPM for the stepper (revolutions per minute)

StepType

the StepType for the stepper (string) which can be "single", "double", "interleave" or "microstep"

Outputs

s - a stepper object

Example


 a = arduino()
 ms = addon(a, "adafruit/motorshieldv2")
 mtr = stepper(ms, 1, 200)
 
: move(sObj, steps)

Move the motor moving in the specified steps using the configured RPM.

Inputs

sObj - the stepper object

Outputs

None

See also: adafruit.motorshieldv2.

: release(sObj)

Release this motor

Inputs

sObj - the stepper object

Outputs

None

See also: adafruit.motorshieldv2.


9.12 Arduino Sensors

9.12.1 arduinosensor.DS1307

: arduinosensor.DS1307

DS1307 realtime clock sensor

Methods

: obj = DS1307(arObj)
: obj = DS1307(arObj, propertyname, propertyvalue ....)

Constructor to create DS1307 sensor

Inputs

arObj - the arduino parent object

propertyname, propertyvalue - optional property name, value pairs. Current known properties are: Current properties are:

i2caddress

I2C address of the DS1307 (default 0x68)

Outputs

obj - created DS1307 object

Example


 a = arduino()
 rtc = arduinosensor.DS1307(a)
 
: date = clock(dsObj)
: clock(dsObj, date)

Get/set the DS1307 clock

Inputs

dsObj - the ds1307 object

date - a date vector in same format as datevec and clock

Outputs

date - a date vector in same format as datevec and clock

Example


 a = arduino()
 rtc = arduinosensor.DS1307(a)
 # get and display rtc time as a date string
 datestr(rtc.clock)
 

See also: datevec.

: ctrl = control(dsObj)
: control(dsObj, ctrl)

Get/set the DS1307 clock

Inputs

dsObj - the ds1307 object

ctrl - a structure containing the control bit fields.

Outputs

ctrl - a structure containing the control bit fields.

Control structure fields are: Current properties are:

out

Out bit in the control register

sqwe

Square wave enable bit in control register

rs

The combined RS0, RS1 value

: YN = isstarted(dsObj)

Get whether the RTC clock is currently counting time

Inputs

dsObj - the ds1307 object

Outputs

YN - returns true if the RTC is counting

See also: start, stop.

: start(dsObj)

Start the RTC counting

Inputs

dsObj - the ds1307 object

Outputs

None

See also: datevec.

: stop(dsObj)

Stop the RTC counting

Inputs

dsObj - the ds1307 object

Outputs

None

See also: datevec.

9.12.2 arduinosensor.GUVAS12SD

: arduinosensor.GUVAS12SD

A thin wrapper for the GUVAS12SD analog UV-B sensor

Methods

: obj = GUVAS12SD(arObj, pin)

Constructor to create GUVAS12SD sensor

Inputs

arObj - the arduino parent object

pin - the analog pin that the sensor is connected to

Outputs

obj - created GUVAS12SD object

Example


 a = arduino()
 # create sensor attached to pin a0.
 sensor = arduinosensor.GUVAS12SD(a, "a0")
 
: V = read(dsObj)

Read the voltage of the sensor

Inputs

dsObj - the GUVAS12SD object

Outputs

V - read voltage - effectively equivalent to readAnalogPin(arObj, pin).

Example


 a = arduino()
 s = arduinosensor.GUVAS12SD(a)
 # voltage
 volts = s.read
 

See also: arduinosensor.GUVAS12SD.

: Idx = readIndex(dsObj)

Read the UV index

Inputs

dsObj - the GUVAS12SD object

Outputs

Idx - the sensor reading as a UV index reading

: uA = readuA(dsObj)

Read the uA of the sensor

Inputs

dsObj - the GUVAS12SD object

Outputs

uA - the sensor reading as a uAmp value

9.12.3 arduinosensor.MPC3002

: arduinosensor.MPC3002

MCP3002 ADC sensor

Methods

: obj = MPC3002(arObj, selectPin)
: obj = MPC3002(arObj, selectPin, propertyname, propertyvalue ....)

Constructor to create MPC3002 sensor

Inputs

arObj - the arduino parent object

selectPin - the SPI cs select pin

propertyname, propertyvalue - optional property name, value pairs.

Current properties are:

referenceVoltage

Reference voltage for scaling the ADC inputs (default 5.0)

Outputs

obj - created MCP3002 object

Example


 a = arduino()
 sensor = arduinosensor.MPC3002(a, "d10")
 
: voltage = readVoltage(dsObj, chan)

Read the voltage from a channel

Inputs

dsObj - the MPC3002 object

chan - the channel to read (0 or 1)

Outputs

voltage - read voltage.

Example


 a = arduino()
 s = arduinosensor.MPC3002(a, "d10")
 volts = readVoltage(s, 0)
 

See also: arduinosensor.MPC3002.

9.12.4 arduinosensor.SI7021

: arduinosensor.SI7021

SI7021 temperature and humidity sensor

Methods

: obj = SI7021(arObj)
: obj = SI7021(arObj, propertyname, propertyvalue ....)

Constructor to create SI7021 sensor

Inputs

arObj - the arduino parent object

propertyname, propertyvalue - optional property name, value pairs. Current known properties are: Current properties are:

i2caddress

I2C address of the SI7021 (default 0x40)

Outputs

obj - created SI7020 object

Example


 a = arduino()
 sensor = arduinosensor.SI7021(a)
 
: C = temperature(dsObj)

Read the temperature

Inputs

dsObj - the si7021 object

Outputs

C - read temperature in deg C.

Example


 a = arduino()
 s = arduinosensor.SI7021(a)
 # get temp
 temp = s.temperature
 

See also: arduinosensor.SI7021.

: relH = humidity(dsObj)

Read the relative humidity

Inputs

dsObj - the si7021 object

Outputs

relH - relative humidity as a percentage (0 - 100.0)

: relH = info(dsObj)

Read the sensor info

Inputs

dsObj - the si7021 object

Outputs

inf - structure containing the sensor information.

Structure fields are:

version

Chip firmware version

id

sensor id1,id2 value

type

String for detected chip type


9.13 Arduino I/O package

9.13.1 arduinoio.AddonBase

: arduinoio.AddonBase

Base class used for arduino library sensors

See also: arduinoio.LibraryBase.

Properties

Base properties are expected to be inherited and overwritten in inherited classes. and are constant in order to query through the metaobject mechanism.

Parent - parent librarybase object

Methods

: ab = AddonBase ()

Constructor of base class

Outputs

The return value ab is an object of the arduinio.AddonBase class.

See also: arduino, addon.

: disp ()

Display the addon in a verbose way.

9.13.2 arduinoio.FilePath

: retval = arduinoio.FilePath (fullpathname)

Get the directory component of a pathname.

Inputs

fullpathname filepath to get directory component of.

Outputs

retval the directory part of the filename.

9.13.3 arduinoio.LibFiles

: filelist = arduinoio.LibFiles ()

Get the list of files used for the building arduino library

Outputs

filelist - string cell array of files for the arduino project

9.13.4 arduinoio.LibraryBase

: arduinoio.LibraryBase

Base class used for arduino library plugins

See also: arduino, listArduinoLibraries, addon.

Properties

Base properties are expected to be inherited and overwritten in inherited classes and are constant in order to query through the metaobject mechanism.

LibraryName - name of the addon library

DependentLibraries - array of dependent library names that must be included when installing this plugin.

CppHeaderFile - name (if any) of header file that will be included into the arduino project when adding this library.

CppSourceFile - name (if any) of source file that will be included into the arduino project when adding this library.

CppClassName - name of the cpp class for the addon library. project when adding this library.

Pins - pins allocated to the addon

Parent - parent arduino object.

Methods

: lb = LibraryBase ()

Constructor of base class

The constructor is usually not called but called indirectly from the addon function.

Outputs

The return value lb is an object of the arduinio.LibraryBase class.

See also: arduino, listArduinoLibraries, addon.

: disp ()

Display the addon in a verbose way.

9.13.5 arduinoio.getBoardConfig

: retval = arduinoio.getBoardConfig (boardname)

Return the configuration for a known arduino board type

Function is used to get the expected pin/board configuration for a named board type which is used to verify and identify the functionality of the board.

Inputs

boardname - name of board to get configuration of ie: "uno"

Outputs

retval configuration struct.


9.14 Matlab Compatibility Classes

9.14.1 matlabshared.addon.LibraryBase

: matlabshared.addon.LibraryBase

Compatability class used for arduino library plugins using matlabshared.addons.LibraryBase

See also: arduinoio.LibraryBase, arduino, listArduinoLibraries, addon.

Properties

Base properties are expected to be inherited and overwritten in inherited classes and are constant in order to query through the metaobject mechanism.

LibraryName - name of the addon library

DependentLibraries - array of dependent library names that must be included when installing this plugin.

CppHeaderFile - name (if any) of header file that will be included into the arduino project when adding this library.

CppSourceFile - name (if any) of source file that will be included into the arduino project when adding this library.

CppClassName - name of the cpp class for the addon library. project when adding this library.

Pins - pins allocated to the addon

Parent - parent arduino object.

Methods

: lb = LibraryBase ()

Constructor of base class

The constructor is usually not called but called indirectly from the addon function.

Outputs

The return value lb is an object of the matlabshare.addons.LibraryBase class.

See also: arduino, listArduinoLibraries, addon.

: disp ()

Display the addon in a verbose way.


9.15 Sensors

9.15.1 bme280

: bme280

BME280 pressure, temperature and humidity sensor

Methods

: obj = bme280(arObj)
: obj = bme280(arObj, propertyname, propertyvalue ....)

Constructor to create BME280 sensor

Inputs

arObj - the arduino parent object

propertyname, propertyvalue - optional property name, value pairs. Current known properties are: Current properties are:

I2CAddress

I2C address of the sensor (default 0x40)

Bus

I2C bus - 0 or 1 (default 0)

Outputs

obj - created object

Example


 a = arduino()
 sensor = bme280(a)
 
: [C, timestamp] = readTemperature(obj)

Read the temperature

Inputs

obj - the sensor object

Outputs

C - read temperature in deg C.

timestamp - timestamp when read

Example


 a = arduino()
 s = bme280(a)
 # get temp
 temp = s.readTemperature
 

See also: bme280.

: [relH, timestamp] = readHumidity(obj)

Read the relative humidity

Inputs

obj - the sensor object

Outputs

relH - relative humidity as a percentage (0 - 100.0)

timestamp - timestamp when read

: [P, timestamp] = readPressure(obj)

Read the pressure

Inputs

obj - the sensor object

Outputs

P - pressure reading from sensor.

timestamp - timestamp when read

: [readings, overrun] = read(obj)
: [P, H, C, timestamp, overrun] = read(obj)

Read the sensor data

Inputs

obj - the sensor object

Outputs

P - pressure reading from sensor.

H - humidity reading from sensor.

C - temperature reading from sensor.

timestamp - timestamp when read

overrun - overrun flag.

readings - table structure with fields for Timestamp, Pressure, Temperature and Humidity.

: inf = info(obj)

Read the sensor info

Inputs

obj - the sensor object

Outputs

inf - structure containing the sensor information.

Structure fields are:

Version

Chip firmware version

SensorId

sensor id value

Type

sensor type ’bme280’

Status

Status value read from sensor

: flush(obj)

Flush sensor data

Inputs

obj - the sensor object

Outputs

None

: release(obj)

Release the resources of the sensor

Inputs

obj - the sensor object

Outputs

None

9.15.2 bno055

: bno055

BNO055 9 axis orientation sensor

Methods

: obj = bno055(arObj)
: obj = bno055(arObj, propertyname, propertyvalue ....)

Constructor to create BME280 sensor

Inputs

arObj - the arduino parent object

propertyname, propertyvalue - optional property name, value pairs. Current known properties are: Current properties are:

I2CAddress

I2C address of the sensor (default 0x40)

Bus

I2C bus - 0 or 1 (default 0)

OperatingMode

Operating mode ’ndof’ or ’amg’

Outputs

obj - created object

Example


 a = arduino()
 sensor = bno055(a)
 
: [C, timestamp] = readTemperature(obj)

Read the temperature

Inputs

obj - the sensor object

Outputs

C - read temperature in deg C.

timestamp - timestamp when read

Example


 a = arduino()
 s = bno055(a)
 # get temp
 temp = s.readTemperature
 

See also: bno055.

: [readVal, timestamp] = readAcceleration(obj)

Read the acceleration rate

Inputs

obj - the sensor object

Outputs

readVal - the 3 acceleration values

timestamp - timestamp when read

: [readVal, timestamp] = readAngularVelocity(obj)

Read the angular velocity

Inputs

obj - the sensor object

Outputs

readVal - the 3 angular velocity values

timestamp - timestamp when read

: [readVal, timestamp] = readMagneticField(obj)

Read the magnetic field components

Inputs

obj - the sensor object

Outputs

readVal - the 3 magnetic field values

timestamp - timestamp when read

: [readVal, timestamp] = readOrientation(obj)

Read the oriientation components

Inputs

obj - the sensor object

Outputs

readVal - the 3 orientation values

timestamp - timestamp when read

: [readings, overrun] = read(obj)
: [accel, gyro, mag, timestamp, overrun] = read(obj)
: [accel, gyro, mag, orientation, timestamp, overrun] = read(obj)

Read the sensor data

Inputs

obj - the sensor object

Outputs

accel - acceleration reading from sensor.

gyro - angular acceleration reading from sensor.

mag - magnetic field reading from sensor.

orientation - orientation reading from sensor.

timestamp - timestamp when read

overrun - overrun flag.

readings - table structure with fields for Timestamp, Acceleration, AngularVelocity, MagneticField, Orientation.

: inf = readCalibrationStatus(obj)

Read the sensor calibration status

Inputs

obj - the sensor object

Outputs

status - structure containing the calibration information.

Structure fields are:

System

System calibrarion

Accelerometer

Accelerometer calibration status

Gyroscope

Gyroscope calibration status

Magnetometer

Magnetometer calibration status

Values for each will be either ’uncalibrated’, ’partial’ or ’full’.

: inf = info(obj)

Read the sensor info

Inputs

obj - the sensor object

Outputs

inf - structure containing the sensor information.

Structure fields are:

Version

Software firmware version

SensorId

sensor id value

Type

sensor type ’bno055’

: flush(obj)

Flush sensor data

Inputs

obj - the sensor object

Outputs

None

: release(obj)

Release the resources of the sensor

Inputs

obj - the sensor object

Outputs

None

9.15.3 lis3dh

: lis3dh

LIS3DH 3 degrees sensor

Methods

: obj = lis3dh(arObj)
: obj = lis3dh(arObj, propertyname, propertyvalue ....)

Constructor to create LIS3DH sensor

Inputs

arObj - the arduino parent object

propertyname, propertyvalue - optional property name, value pairs. Current known properties are: Current properties are:

I2CAddress

I2C address of the sensor (default 0x40)

Bus

I2C bus - 0 or 1 (default 0)

Outputs

obj - created object

Example


 a = arduino()
 sensor = lis3dh(a)
 
: [readVal, timestamp] = readAcceleration(obj)

Read the acceleration rate

Inputs

obj - the sensor object

Outputs

readVal - the 3 acceleration values

timestamp - timestamp when read

: [readings, overrun] = read(obj)
: [accel, timestamp, overrun] = read(obj)

Read the sensor data

Inputs

obj - the sensor object

Outputs

accel - acceleration reading from sensor.

timestamp - timestamp when read

overrun - overrun flag.

readings - table structure with fields for Timestamp, Acceleration.

: inf = info(obj)

Read the sensor info

Inputs

obj - the sensor object

Outputs

inf - structure containing the sensor information.

Structure fields are:

SensorId

sensor id value

Type

sensor type ’lis3dh’

Status

sensor status value

: flush(obj)

Flush sensor data

Inputs

obj - the sensor object

Outputs

None

: release(obj)

Release the resources of the sensor

Inputs

obj - the sensor object

Outputs

None

9.15.4 lps22hb

: lps22hb

LPS22HB absolute pressure and temperature sensor

Methods

: obj = lps22hb(arObj)
: obj = lps22hb(arObj, propertyname, propertyvalue ....)

Constructor to create LPS22HB sensor

Inputs

arObj - the arduino parent object

propertyname, propertyvalue - optional property name, value pairs. Current known properties are: Current properties are:

I2CAddress

I2C address of the sensor (default 0x5C)

Bus

I2C bus - 0 or 1 (default 0)

Outputs

obj - created object

Example


 a = arduino()
 sensor = lps22hb(a)
 
: [C, timestamp] = readTemperature(obj)

Read the temperature

Inputs

obj - the sensor object

Outputs

C - read temperature in deg C.

timestamp - timestamp when read

Example


 a = arduino()
 s = lps22hb(a)
 # get temp
 temp = s.readTemperature
 

See also: lps22hb.

: [P, timestamp] = readPressure(obj)

Read the pressure

Inputs

obj - the sensor object

Outputs

P - pressure reading from sensor.

timestamp - timestamp when read

: [readings, overrun] = read(obj)
: [P, C, timestamp, overrun] = read(obj)

Read the sensor data

Inputs

obj - the sensor object

Outputs

P - pressure reading from sensor.

C - temperature reading from sensor.

timestamp - timestamp when read

overrun - overrun flag.

readings - table structure with fields for Timestamp, Pressure, Temperature and Humidity.

: inf = info(obj)

Read the sensor info

Inputs

obj - the sensor object

Outputs

inf - structure containing the sensor information.

Structure fields are:

Version

Chip firmware version

SensorId

sensor id value

Type

sensor type ’lps22hb’

Status

Status value read from sensor

: flush(obj)

Flush sensor data

Inputs

obj - the sensor object

Outputs

None

: release(obj)

Release the resources of the sensor

Inputs

obj - the sensor object

Outputs

None

9.15.5 lsm6dso

: lsm6dso

LSM6DSO 6 degrees sensor

Methods

: obj = lsm6dso(arObj)
: obj = lsm6dso(arObj, propertyname, propertyvalue ....)

Constructor to create LSM6DSO sensor

Inputs

arObj - the arduino parent object

propertyname, propertyvalue - optional property name, value pairs. Current known properties are: Current properties are:

I2CAddress

I2C address of the sensor (default 0x40)

Bus

I2C bus - 0 or 1 (default 0)

Outputs

obj - created object

Example


 a = arduino()
 sensor = lsm6dso(a)
 
: [C, timestamp] = readTemperature(obj)

Read the temperature

Inputs

obj - the sensor object

Outputs

C - read temperature in deg C.

timestamp - timestamp when read

Example


 a = arduino()
 s = lsm6dso(a)
 # get temp
 temp = s.readTemperature
 

See also: lsm6dso.

: [readVal, timestamp] = readAcceleration(obj)

Read the acceleration rate

Inputs

obj - the sensor object

Outputs

readVal - the 3 acceleration values

timestamp - timestamp when read

: [readVal, timestamp] = readAngularVelocity(obj)

Read the angular velocity

Inputs

obj - the sensor object

Outputs

readVal - the 3 angular velocity values

timestamp - timestamp when read

: [readings, overrun] = read(obj)
: [accel, gyro, mag, timestamp, overrun] = read(obj)

Read the sensor data

Inputs

obj - the sensor object

Outputs

accel - acceleration reading from sensor.

gyro - angular acceleration reading from sensor.

timestamp - timestamp when read

overrun - overrun flag.

readings - table structure with fields for Timestamp, Acceleration, AngularVelocity.

: inf = info(obj)

Read the sensor info

Inputs

obj - the sensor object

Outputs

inf - structure containing the sensor information.

Structure fields are:

SensorId

sensor id value

Type

sensor type ’lsm6dso’

: flush(obj)

Flush sensor data

Inputs

obj - the sensor object

Outputs

None

: release(obj)

Release the resources of the sensor

Inputs

obj - the sensor object

Outputs

None

9.15.6 mpu6050

: mpu6050

MPU-6050 6 degrees sensor

Methods

: obj = mpu6050(arObj)
: obj = mpu6050(arObj, propertyname, propertyvalue ....)

Constructor to create MPU-6050 sensor

Inputs

arObj - the arduino parent object

propertyname, propertyvalue - optional property name, value pairs. Current known properties are: Current properties are:

I2CAddress

I2C address of the sensor (default 0x40)

Bus

I2C bus - 0 or 1 (default 0)

Outputs

obj - created object

Example


 a = arduino()
 sensor = mpu6050(a)
 
: [C, timestamp] = readTemperature(obj)

Read the temperature

Inputs

obj - the sensor object

Outputs

C - read temperature in deg C.

timestamp - timestamp when read

Example


 a = arduino()
 s = mpu6050(a)
 # get temp
 temp = s.readTemperature
 

See also: mpu6050.

: [readVal, timestamp] = readAcceleration(obj)

Read the acceleration rate

Inputs

obj - the sensor object

Outputs

readVal - the 3 acceleration values

timestamp - timestamp when read

: [readVal, timestamp] = readAngularVelocity(obj)

Read the angular velocity

Inputs

obj - the sensor object

Outputs

readVal - the 3 angular velocity values

timestamp - timestamp when read

: [readings, overrun] = read(obj)
: [accel, gyro, mag, timestamp, overrun] = read(obj)

Read the sensor data

Inputs

obj - the sensor object

Outputs

accel - acceleration reading from sensor.

gyro - angular acceleration reading from sensor.

timestamp - timestamp when read

overrun - overrun flag.

readings - table structure with fields for Timestamp, Acceleration, AngularVelocity.

: inf = info(obj)

Read the sensor info

Inputs

obj - the sensor object

Outputs

inf - structure containing the sensor information.

Structure fields are:

SensorId

sensor id value

Type

sensor type ’mpu6050’

: flush(obj)

Flush sensor data

Inputs

obj - the sensor object

Outputs

None

: release(obj)

Release the resources of the sensor

Inputs

obj - the sensor object

Outputs

None

9.15.7 si7021

: si7021

SI7021 temperature and humidity sensor

Methods

: obj = si7021(arObj)
: obj = si7021(arObj, propertyname, propertyvalue ....)

Constructor to create si7021 sensor

Inputs

arObj - the arduino parent object

propertyname, propertyvalue - optional property name, value pairs. Current known properties are: Current properties are:

I2Caddress

I2C address of the si7021 (default 0x40)

Bus

I2C bus (default 0)

Outputs

obj - created SI7020 object

Example


 a = arduino()
 sensor = si7021(a)
 
: [C, timestamp] = readTemperature(obj)

Read the temperature

Inputs

obj - the si7021 object

Outputs

C - read temperature in deg C.

timestamp - timestamp when read

Example


 a = arduino()
 s = si7021(a)
 # get temp
 temp = s.readTemperature()
 

See also: si7021.

: [relH, timestamp] = readHumidity(obj)

Read the relative humidity

Inputs

obj - the si7021 object

Outputs

relH - relative humidity as a percentage (0 - 100.0)

timestamp - timestamp when read

: [readings, overrun] = read(obj)
: [H, C, timestamp, overrun] = read(obj)

Read the sensor data

Inputs

obj - the si2071 sensor object

Outputs

H - humidity reading from sensor.

C - temperature reading from sensor.

timestamp - timestamp when read

overrun - overrun flag.

readings - table structure with fields for Timestamp, Temperature and Humidity.

: relH = info(dsObj)

Read the sensor info

Inputs

dsObj - the si7021 object

Outputs

inf - structure containing the sensor information.

Structure fields are:

Version

Chip firmware version

SensorDd

sensor id value

Type

String for detected chip type

: flush(obj)

Flush sensor data

Inputs

obj - the sensor object

Outputs

None

: release(obj)

Release the resources of the sensor

Inputs

obj - the sensor object

Outputs

None


9.16 Test Functions

9.16.1 arduino_bistsetup

: retval = arduino_bistsetup ()
: retval = arduino_bistsetup (propertyname, propertyvalue)

Install on an arduino the required core libraries to run the BIST tests

As part of the setup, the arduino IDE will be opened to allow programming the arduino board.

Inputs

propertyname, propertyvalue - A sequence of property name/value pairs can be given to set defaults while programming.

Currently the following properties can be set:

arduinobinary

The value should be the name/path of the arduino IDE binary for programming. If not specified, the function will attempt to find the binary itself.

debug

Set the debug flag when checking the arduino

Outputs

retval - return 1 if everything installed ok

See also: arduino, arduinosetup.


Appendix A GNU General Public License

Version 3, 29 June 2007
Copyright © 2007 Free Software Foundation, Inc. http://fsf.org/

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

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  6. 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:

    1. The work must carry prominent notices stating that you modified it, and giving a relevant date.
    2. 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”.
    3. 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.
    4. 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.

  7. 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:

    1. 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.
    2. 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.
    3. 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.
    4. 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.
    5. 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.

  8. 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:

    1. Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or
    2. 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
    3. 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
    4. Limiting the use for publicity purposes of names of licensors or authors of the material; or
    5. Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or
    6. 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.

  9. 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.

  10. 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.

  11. 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.

  12. 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.

  13. 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.

  14. 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.

  15. 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.

  16. 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.

  17. 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.

  18. 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.

one line to give the program's name and a brief idea of what it does.  
Copyright (C) year name of author

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 http://www.gnu.org/licenses/.

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:

program Copyright (C) year name of author 
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 http://www.gnu.org/licenses/.

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 http://www.gnu.org/philosophy/why-not-lgpl.html.


Index

Jump to:   A   B   C   D   E   F   G   H   I   K   L   M   O   P   Q   R   S   T   U   V   W  
Index EntrySection

A
addonArduino Addons
Addon IntroductionAddons Overview
Addon package .m fileAddons Overview
Addon package directoryAddons Overview
Addon package header fileAddons Overview
AddonBaseArduino I/O package
Addons OverviewAddons Overview
arduinoArduino Functions
Arduino AddonsArduino Addons
Arduino Device FunctionsArduino Device Functions
Arduino FunctionsArduino Functions
Arduino I/O packageArduino I/O package
Arduino I2C FunctionsArduino I2C Functions
Arduino Rotary Encoder FunctionsArduino Rotary Encoder Functions
Arduino SensorSensors Overview
Arduino SensorsArduino Sensors
Arduino Serial FunctionsArduino Serial Functions
Arduino Servo FunctionsArduino Servo Functions
Arduino Shiftregister FunctionsArduino Shiftregister Functions
Arduino SPI FunctionsArduino SPI Functions
Arduino Ultrasonic FunctionsArduino Ultrasonic Functions
arduino_bistsetupTest Functions
arduinosetupGeneral Functions
Available SensorsSensors Overview
Available SensorsSensors Overview

B
Basic Input and Output OverviewBasic Input and Output Overview
Blinking an LEDExamples
bme280Sensors
bno055Sensors

C
checkI2CAddressArduino Functions
configurePinArduino Functions
configurePinResourceArduino Functions
Connecting to a single arduinoConnecting to an arduino
Connecting to a specific arduinoConnecting to an arduino
Connecting to an arduinoConnecting to an arduino
copyrightCopying
Creating a addon objectAddons Overview
Creating an addonAddons Overview

D
dcmotorv2Arduino Addons
decrementResourceCountArduino Functions
deleteArduino Functions
deleteArduino I2C Functions
deleteArduino I2C Functions
deleteArduino Rotary Encoder Functions
deleteArduino Servo Functions
deleteArduino Shiftregister Functions
deleteArduino SPI Functions
deleteArduino SPI Functions
deleteArduino Serial Functions
deleteArduino Device Functions
deleteArduino Ultrasonic Functions
deviceArduino Serial Functions
deviceArduino Device Functions
dispArduino Functions
dispArduino I2C Functions
dispArduino I2C Functions
dispArduino Rotary Encoder Functions
dispArduino Servo Functions
dispArduino Shiftregister Functions
dispArduino SPI Functions
dispArduino SPI Functions
dispArduino Serial Functions
dispArduino Device Functions
dispArduino Ultrasonic Functions
DS1307Arduino Addons
DS1307Arduino Sensors

E
EchoArduino Addons
EEPRomArduino Addons
ExamplesExamples

F
FilePathArduino I/O package
flushArduino Serial Functions
flushArduino Device Functions
Function ReferenceFunction Reference

G
General FunctionsGeneral Functions
getBoardConfigArduino I/O package
getEndianArduino Functions
getI2CTerminalsArduino Functions
getInterruptTerminalsArduino Functions
getLEDTerminalsArduino Functions
getMCUArduino Functions
getPinAliasArduino Functions
getPinInfoArduino Functions
getPinsFromTerminalsArduino Functions
getPWMTerminalsArduino Functions
getResourceCountArduino Functions
getResourceOwnerArduino Functions
getServoTerminalsArduino Functions
getSharedResourcePropertyArduino Functions
getSPITerminalsArduino Functions
getTerminalModeArduino Functions
getTerminalsFromPinsArduino Functions
GUVAS12SDArduino Sensors

H
Hardware setupHardware setup

I
I2C communicationProtocol based I/O Overview
i2cdevArduino I2C Functions
incrementResourceCountArduino Functions
Installing and loadingInstalling and loading
isarduinoGeneral Functions
isTerminalAnalogArduino Functions
isTerminalDigitalArduino Functions

K
Known Arduino Board TypesHardware setup

L
LCDArduino Addons
LibFilesArduino I/O package
LibraryBaseArduino I/O package
LibraryBaseMatlab Compatibility Classes
lis3dhSensors
listArduinoLibrariesGeneral Functions
LoadingInstalling and loading
lps22hbSensors
lsm6dsoSensors

M
Matlab Compatibility ClassesMatlab Compatibility Classes
Matlab Compatible SensorSensors Overview
motorshieldv2Arduino Addons
MPC3002Arduino Sensors
mpu6050Sensors

O
Off-line installInstalling and loading
Online installInstalling and loading

P
Performing Analog InputBasic Input and Output Overview
Performing Digital I/OBasic Input and Output Overview
playToneArduino Functions
Programming the ArduinoHardware setup
Programming the arduino with the addonAddons Overview
Protocol based I/O OverviewProtocol based I/O Overview

Q
Querying available arduinosConnecting to an arduino

R
readArduino I2C Functions
readArduino I2C Functions
readArduino Shiftregister Functions
readArduino Serial Functions
readArduino Device Functions
readAnalogPinArduino Functions
readCountArduino Rotary Encoder Functions
readDigitalPinArduino Functions
readDistanceArduino Ultrasonic Functions
readEchoTimeArduino Ultrasonic Functions
readPositionArduino Servo Functions
readRegisterArduino I2C Functions
readRegisterArduino I2C Functions
readRegisterArduino Device Functions
readSpeedArduino Rotary Encoder Functions
readVoltageArduino Functions
resetArduino Functions
resetArduino Shiftregister Functions
resetCountArduino Rotary Encoder Functions
Rotary EncoderProtocol based I/O Overview
rotaryEncoderArduino Rotary Encoder Functions

S
scanForArduinosGeneral Functions
scanI2CbusArduino I2C Functions
sendCommandArduino Functions
SensorsSensors
Sensors OverviewSensors Overview
Serial communicationProtocol based I/O Overview
servoArduino Servo Functions
Servo communicationProtocol based I/O Overview
setSharedResourcePropertyArduino Functions
Shift RegistersProtocol based I/O Overview
shiftRegisterArduino Shiftregister Functions
SI7021Arduino Sensors
si7021Sensors
SimpleStepperArduino Addons
SPI communicationProtocol based I/O Overview
spidevArduino SPI Functions
stepperArduino Addons
subsrefArduino I2C Functions
subsrefArduino I2C Functions
subsrefArduino Rotary Encoder Functions
subsrefArduino Servo Functions
subsrefArduino Shiftregister Functions
subsrefArduino SPI Functions
subsrefArduino SPI Functions
subsrefArduino Serial Functions
subsrefArduino Device Functions
subsrefArduino Ultrasonic Functions

T
Test FunctionsTest Functions

U
ultrasonicArduino Ultrasonic Functions
Ultrasonic SensorsProtocol based I/O Overview
uptimeArduino Functions
Using AddonsAddons Overview
Using I2C to communicate with an EEPROMExamples
Using SPI to communicate with a mcp3002 10 bit ADCExamples

V
validatePinArduino Functions
Verify octave can see the addonAddons Overview
versionArduino Functions

W
warrantyCopying
writeArduino I2C Functions
writeArduino I2C Functions
writeArduino Shiftregister Functions
writeArduino Serial Functions
writeArduino Device Functions
writeDigitalPinArduino Functions
writePositionArduino Servo Functions
writePWMDutyCycleArduino Functions
writePWMVoltageArduino Functions
writeReadArduino SPI Functions
writeReadArduino SPI Functions
writeReadArduino Device Functions
writeRegisterArduino I2C Functions
writeRegisterArduino I2C Functions
writeRegisterArduino Device Functions

arduino-0.12.2/doc/arduino.pdf0000644000000000000000000142745514777724260013126 0ustar00%PDF-1.5 % 1 0 obj << /Length 587 /Filter /FlateDecode >> stream xmTM@+z&?tBL$d4*.<_fW_wիrc;`GUOV&ʮ[v6W7TvbuYt/N.5=S> stream xmTM@+z&?tBL0d4*.<̿~UfW_uvc;Z̫MfG} I]/ޭmޯo⣩0^'^x]fkn{EK{*ʇupg6;ލ$4;gZ8, M[TPRJGeWxmE7 "/7j;{Yʋ"1tm|oirI ɑc׺>[TқEnn#bBSEV嶭mzsg)gR133w xAb;aGL6K&0+}&"?(Ҧa/ c,!-f3*Ix {asIC%hS7}H=ŤIY(jŧ Z4{SO5Z ekxvKǬ@2a> stream xmSn0+$z"aKU^CvF^p=!94gB˥0pދ s#P~k@hZ+vQڦ(A,Rf5Ħq8>K_X NH3$Ǟ{<0*5c~Pʯ5W42^!0^#rqxƘE3x z)cgl1BҰ?Xq!NAWA*d1)iȧΰО 9璆NVfkVaUJ?%͚5ػbTW=ј52f&p2pjV^cHMcVYxLS7E=1j g endstream endobj 6 0 obj << /Length 333 /Filter /FlateDecode >> stream xڅN0E /Ee+RCB,B>D[CHcZ@Hؾ32+u,m 1vKI: X) gh+k<889wIF;E3 9n_BYռ.F6Oe|(A8aKvѱk٢ Z3"*ʹSf&װmWM&/GS~M~ܴY qU?ǓEi{Gxruw}4@(MW !Ƌ H*KyHqVi؅媌_Ӵ,#Ca_ endstream endobj 13 0 obj << /Length 622 /Filter /FlateDecode >> stream xڍSn0+tHE|#r* HAQ.]r~F p;;;fQ?yT7n&kT??Ge5LyNyVӌC뫼_+1-+\L}V&ɳ&Y;=k$J$ʴn(aU.AI-ecoFۼ&!*N-֨=EX5!꣒ fΞ1>nYl+rRݙ %?\c Ǻ2kZ ]1w7*}c$eHswx8LϴSPm WaP>jJIA:)B$k\Cw Fy׹M#=SwŶTu5> i5m@P퐰`AX|Pe(%"WuY \+F` jC&zo6na] m@k`&" )\]g1@&XitӘte@.WN5Qwx~[8%+50 iߣUមg;k/b <$7z m ൭?{ endstream endobj 19 0 obj << /Length 1072 /Filter /FlateDecode >> stream xڕVK6 ϯV1E(bXI&v 3_R'iSGQ<ǓJ$U-Y-d}xo"zzQNJbY! ʹzX>"IUd fEB%&qp]mX ϙ5G<ɸf\$ٓf% Δ@6<-M:|^f!"J7k;\ѬqEQfkXsXEoM9+n3W3޲Ex>.jѵ 3 mhk-[@[=̫`@HrkЩ@2]wG4mQ4h62al!w;bPi"y(v#)Pt ִt ĴO׆`XU8_M0 1@ rO9 3Y0o`\Ku6C8u.,uy+(FCeS0C2i ;bpt& wk^:Ya]v`Y:!;b3b!n/ lf -y $"ސs l5w6':ڶIb r;P裂WwwQPlDyOoQʊ@ K "P V'zcn&*ʀɰwv&sgƵixdeӍ[ ߂8-j~$6o'Zo B7wk(ŋԺ;iF"7HYD+|Pd">n+ }*3!avWm¼|eubm]0!$g98 34 K||I2\<,\E};޵ۯ?ҁ]ͯCHsyO(|+a'`)^2.u|ah7t41 vUXmlq ]ܿ%^>?O±+u>ބ/te+,)t`~7RLetm&cqBK ugRtm;f$.4,[IQ{ (oaJDh?{x endstream endobj 113 0 obj << /Length 3290 /Filter /FlateDecode >> stream xKs8a1/b9@??kF "F)+;žcXڤ!!a7FMgC$ꄳ&'\drx͡e(U.* a<ʢXf?wA>fNf{gw^3,'-*h0x<4 o}DM:å : &,'b805FSj0WA յ_mJeE2SmYk/.sZȞ'ȃ;Fp&BpԻs@Ai>_YB+(1W!k@+Ʉ/-uDLW|j(@I\(E-Am3cpWB}E9>ղBƒG(so\a͠ް#fzp  +^S5ҁ/m(c7+=|[xaz0I39nCk/J4d%|c0CB78`WʜQ҉x/֗PNzX> 9dэ4 (0c0F35b S|$x%1Ƒ#J;7 >Nw^!"'Rd6wD3F0ӡjW+GBYrBI.Mon{bs$0 |Izca X޴B.7ϲվ}^w 0/x |'N=4 _}F}oԓvjhC%i2GvSOfw^.Da(Qˊ5ID²nI$Mcp7uRI|io׆Gc0a9s4^x ӪDӘp8`PM$uRTBU!s#Ag.>r ʔr2dr<㌵1 D7xX v>Kcy{fHiۊ/:,wwsZBy9U@vx 5 ^xXM&JHrV79'Va-fuh=,B0&?B] "4,t&Lh1Xb@Ȫ$kd5-P!ր*Өڨ޹6DvRݳ s2 ΠıI  7O zX <&L[{Qgr4aM~;\u 7Hv7Ici+4ﷇvUfUC,s|6^ha(Aࠈnl/iaŏ(U&{ LjSFRcaYao@868Bk/0mSȶ3 4u&BiG,#PZk= ^3cWx}r^Urٍt!0B:n"&)wiHkTiHk`u5 znFkWHk/&>JyL'i\tޠ9̰ưu994)jVe4!vS1SFZ;38|Xog`U[{5t:!Ny晞*JgP U4UdRh5udP햟ݪ=mQG冟lmI8@dP{` HTY>ޮTޜ>hoI ;pcf4;0XȘ;[RUdN5^ # E=A4r0ŠI/QN#Kfܣ~,Z^k.fh,ce.7v>2'fNT$'XKoeǁ %&ArGhcut-Pm?|}~⪑YCWJs(d|D7)=5j-(Y&[X\B5o j.LX]Rde셄זi 9u 7b%;sվ ma7 ַ$MCc*!"k4 [{ctyTdV)qvy yX #ؐ^80r'ihBεnz3)IrMY+ f x6%ɛqO"D. ĻMK889FmPM$FmɷM#v-#fyߎ LykJe#07<0(cA#'D:RZ456>YGY7݇3;NvM1%=n8Ip ܂EN"%otWѼ.b-%S*TՍf֧> stream xMs6Uˆ2Yߟ?xRE*Y`ڲbC/輂_E !t3'l*O2g%BxT967'yUgEhK)]44_I/M[y[Fdž{ 6 i=X6'e%̘8N*j (9/o9cl_ʢixRі4ti%yo9h2`6'L݋T4.@g^)AXN*M*ot^IT[R|Swsڜmͱ?~2~;n0Z礩3Mcht,QdH2a^HF :)=d E!\ܲH!~/^xKx XtK yhTі8c uk/d.y&Nq 'Y3J(jUӺլ%EiY!҄GU璡iis!tȕe^҇:!G1rVn+Twk0+xu1-^de\/a "A rE"qZ" RQ'nWw})9 Ŏ!vJYPe[a/rzdT7*~/^*WCwgXƸ3mD9!81aMh`8q EN<*Bu \vۊqNH,^pewU$hK,H!V1SڕDpi,FBQ.BdPPA@1F6-WIK\yі(·rC[Tԉv0XB(1wX $g뙵jIiYk2,\q8͆8 2O>hY&P xx}ֆNࡢ-m %&ppj5e:N4>tbn_]@:F˟j:ʹ,r#mbbZ0O8؜i|2x˚Xc6kMqbn+dךAiMGv8$fX0C%래G#cԄL9L}qolTJ2i%E2RKJmk*[GRo(il)=cԴvPnܓZ2-#іN{'* CuDZS4!N#j 2V2}cLÏ6rƽn x_>[H3h \T%m\'\ +I}Q(xPsF1m &fLվ*#}'AsUpThK4Wp/ha@o8i|0+]0_ Xba0bez~zR_F痠u* RqH 1M:P*X"R1jBb-s׸]3ĮM$Z4N#X<5'(WV=FMP0}70ap6xa"apsSYÞhPNS4>lnO{"˓xU"UrGEMDᢁ}wهOy:627ց#8i|2vǨ ;\o6r8w#[`JbNE[-SxiTUCۊ׼oIN74CţܖjDHx54FM 3 ,I|iٜ$hK"jC qϿ&IzF#N!)m$edXQ JӫqseH|-s> stream xڽ[]\}_я΃vUa- Ib֫A^̈`U}%YstWe\r:bG59;.e<+.8zz;C=qxQgv1X\2ec.'zr1 sU](< P PKjuI:ȥ)  LnTQT p sF π͠*I2򢵲ˠ]r |EFBr/tWUZtHz*2 YP])xUxU+Q.ij*P*WiCT@vd$1U^)iS<*^)(dy\nJ؂Ixt[w _F&#K븅D[Ӑ(;!p:1 E# z*rD!Tz8 ?(#*~(0 d\PDRH3wR8KbP $d|ռ>Y+@L$׸Q")ݳgn~|<ӽ+J/wfzwܛ(JU|W;sЯoJ3'8E/-?o^O [^;"?K!Iҵ@pSzRi\={#M$ґ&La}yz^N•$RZ^IØ=Bp!G'[?~O%h$* B3ӋK+a,#/tpeyw{st>~Ӊ( $YZ Y㧟u#$/O89: ~R h(fM3kzy$ҳMx4G0jG(QQ$EI%)JR(IQ$EI%+JV(YQdEɊ%+JQ(EQE)R(JQ(UQTER*JU(UQ4Ei)JS(MQ4Ei+JW(]QtE+z$;S۵uXAO(z /#8$ y"2ʭ G9D䓌TdX>WQn"Q{PP#[-TFG)14:pk&y6P}4ʭ>ΣR̝==H%/~̉|d"JqP~RM"k }#^:ȹ!\F9DN! ɤk򒳨YtH#R'RB#4)@2E(D qIW:)jfQSE&r9nT3xX61iyO`a jp W`??ʗrljV)w/ ~,)9Հn2Oi8(G)N"1u]Bvb2#J*(7(%T Y H)r>K˅B(PG9J#*Տ8ʅJ(RGi"#FTt+WB"9rc "uD}U+(7(Ȃ0YmOhCDơ %0(0?B.#?z Q]<)JsPbb}iN`VPXhf 23`d~02C#F #3lad02c3F #3ad02C"F#3lbd>12S*F#3bd~12cʰ\cd12q9Ff#󎑙cd12AFf!#󐑙\dd622IFf%#󒑙ddv22?QFf)#󔑙Lel26STlqlqlqdxVm ϜlՐ' |Ldžģ۪ { /{zʗQ1is U6%xg2Ѷޯuu˾̉C&RY4C0 4ʭ|wF endstream endobj 356 0 obj << /Length 3484 /Filter /FlateDecode >> stream xMܶ<Dɜsrٺr3U]9&Ar Θ*kw3}  TtMWfO⻿Rsk|"_mzhUjm{y7ܝެonkM_Pn^1E-e ??]=X;wuڄ9j T1w/_ӇwOZ׽6J|%:R V7 *': aFo}kzekgl`z4dc fjS;ZZ공F}߃vAIh_–ZO?NrMWV( i"5}m 5}ߥpDf)Ñ4M#er0]+ѸD4jJHU(q|lrjg##vLii$Ʋcm Ra0fBƒ?dH: u\qۣ@4D`YwxBuІ&vZdr#OIc=tw3@l2YG4> cu+->VqnИxcHZal ŵE/u(M#ѕeu[J; ]çǸԮsJv|t'DJ 023ɐ9O4g=eCen Sv0%hnmۇ~P3 ;9:Njcoa9_j?@n+cu"M eYig{(YVED-KabSZc {Q>v#yt [Z;Hy3ƛ@s~uVoaZA h{u_> %e>:Hh3< ՅKɐY :ָ4]!ԍVL9Oއ{=E9?2sёPL:,1u-$M#єJ^Z=0Y5t8ߍsM䃩Lʒn ̃arUPHH l?;#4G$I'KPNjGG2)H!TyeR ZFkHfԶI`7j{iAY ~i1JHm<.T{@3A |4Nv70/q3GtinR6Ϡ̟љaT.C'M#彰1;S%h&L}zuMڱeӭ(씟)?];MrN(B1MT)|۰PJi1@,( GG 6:l2{E׵)֘4TYjf%jҴIZq=LR kzJk W/l"x4iymz0ր%jEMoхNKP"vVGG葮0[C]G{!ʰcKxL,{:iBg6|vk/iXDEz&:x"7Ǚ$p1nFotfnzaiTIBvT\G٠ 3ή$Y#+jUIyvxV`mQFvGG:)´q(LzS%knF2fK[.uxn1!9rL%" SУ$8NDf)u4MitIPz-mfV{bjҦgW ,S,CCr_eRaD/ˬ{ QC$栕!d.I L%{B%] rCjeI,c;}Yx9i`U׬F1HH ?>rHu)rLR=A j^ c QZ9,ke_Nh M r6:, endstream endobj 233 0 obj << /Type /ObjStm /N 100 /First 902 /Length 2178 /Filter /FlateDecode >> stream xڵ]\We|sX8 ,]$PݰZ֙:e$8SUkF}޷:۸ZBJHraRw iG.ƀLsZf-\ecoXQa݊TX2+a6dV)V^"DÓB"lPk1j%A@DyJ) ې봚@73Z:)阥wJWEm̊6[s!󤢵!3Ѱ-JVPW'VTegQ-BjcբˊՊ cB3APmK`+*GoGP3]am|ZiCIhT&~}i :U)[⿧-sݡ tYtV"2_Fe *PQ:B[_jvMoC D'Ag5VRiTo%kYNH¿{8Th{M$Qu]p"tC)իݿy)oN_>:E /~#N DhbOlU(hKtL NAjNuJƍHs120,m[ XJ]c &:l+#L3 ކ DകHBl]9 N[ٖfYVD}rgp&zg۴Dž:Ʈ4l0nDA_TLɜ}7ztxĊ'5-nAŶ?%=338+YbK6φغ9oyp=yxggpbm=䱛غR.{q9kXL4z2;egPbMqzi#fŠg{h D[e,`q閁g]cJY'،:21Fagr!hW/ Ҕ3щg#yHqs9σ338kWُpS"ёa5]\o`9Es938=kbuq51 &sgp&z'vܰ^b|38=kv w LmuI.{ggpb{T/u}¹'bio4vxNw D[k-| B7&.@!]WƁR`Lt: "^f ::uyokqWZqp/vp+D|^ߡN;v?M 7^Pr~]~{*ǟ/asmqžWo~VEǶ;ոIGH`^svJdSxz-]LS=ȯO뚪 7\opz 7]otzMכ7]orz-[\oru vO){*vO5k\wc@SkGG/z>ܘ\\]]]]]]]]]]O\O\O\O\O\O\O\O\O\Oz˄nOo+\1cS2> stream xڵM$5 +|K:K+$J\8`"{:e8LKuuD>;P|& sEF%6ˁ' !bsW7ģAi )~g/؆1juAyY[y')POgqǯӅ7tN-Hv"O^ XHAg ɬM]Zv7ZԿAT+v[ót.p7SR[~ST~gRwuU4ތzGKOHmԭ\@PwHf>2mҚw0H%ccb. RD/dq'Ę-qIfݍ1jnmb htM}nGǵAuì@u]O=1Ǵ>&dh]Uڼzuow?|_v_Io*۟?ЛZRϞ^:Z[L:>W ݿ|{OD?>iwŒ\)ߙZ72e.M έyrfjebv6o$"/k8fp&jgCVVsﰊdέZzbܽkrnL NX)[#DZ/k8fp&j'Ba,Y̹53Q38 fezs1d`I} @Gh[2 %r2>/|ҳ"̭yrfj&_;99fp&jgoE|Rh\έq1tOz/k8fp&jgbK]f mpɜ[385}NjCl[385۳7+Fa'X]x"̭pbc_Fcr4b[4<935szG"Kג˹53Q38{Rt"n-skgfp,<KkULܚHE"Dѣ qnL ΆvmG>L.ܒ'HM86dMh[2($)pGj9UD~k<52QLYd"/T|nprn͓3S38a^t?Ҙ7̹53Q38ac?jjXe ˹53Q38ꙟ"#< q˹53Q381 NvdqNOD]Ĺ53Q38}wVmk3r)bP&j R+9#yRnɠL<EckgEfp&j'2laF_?є8ək#|GAgU[385SEi@k(9skgfp"6QRyo"C̹53Q38aՋg.i'ԟ'HQƲ1B>1Qr/~^u/H`$;fO\ʭX2kvD{Ճ'R1O3S30Qa}x6Vl.*E853Q38Q汼LS9S-8dέڰ| #skgfp"cyh﹜[3855A!!ڂ\έY{ivz;(_>ы.NL<9_GP ~]D2QD^KkpE[LTa\V#|F1ÛW՝쉂 ϑ&T-EPU5A}=F>n7ڴ endstream endobj 479 0 obj << /Length 3769 /Filter /FlateDecode >> stream xMs6Y>" ˤI e`)`p/D/(A:Fçɀoo>BjgߝwLCOs^b`A*7lϞ|PV+/h1\o *Dҧ&Ji9nOۥhea$ DhG;Rښr: > HZ e*;QGi˫}YA8;PLE0IqQ]&B!j.D:R(0P; #y38:j[Bj2'[}<I4Nxd^5,Բ 8EyG"#x+,d]Tю((\O6K3IXi܇e+ERGKF I(HrV*4$I_4!$^lL#ov;S #]o"JU ϕT!eb>ƌkS&Xc!11=t 2F /4bbDB=$]((6b :`\\z6txgHrwf4ْ2~_̊i4IG4!^9ӇIMQG%. O9Evd!"|]L3pBneqnQ\752b뫅^5-$b䢐ю4|Wm+<| >kiP&W䞳&e/観)H5qeur9wԟL;jYJFv 6E R3h43/s_KqŗeՊ`6P#MQGĆnx}:k8z`Q.B0V,]tԌi$h4v-T>a -p8cش`!,U OY-KU/'Vn# A8M(5e)ݔAuLp ^m~ó{Ѧ-tXRE;Vܫg^4H?4!ܶ^50jA3Ir7ywqsij`լ9!0K k-y "LcJ"'Y#5$GG.:kV Qю0fi˘iFY߻' k qx˪ 9߇?{8]pX sPAhG4Za+~Sۢ¼\IЮi0%8u,;o^t&^¢]uW˲;+UwAiVi8?6Pߙ:Rz\sWFB=SVy]=ʜ9SXn9)+s\o FP$VW1RA3Y|9cK/_`. v='$7`,J޼)/˙ ?Dq}Nl+IplCO?UoP #mudc$lmYPGF]z,0bIG,%.h+ܝ 1Ҧ8ֻLgĕނ)hK,Ls?usn5st *щPh@B3Z 1Ҧ8M(']ꇞfpvp} :F2.hs--Oja4Dz}q #Ξk+2xy˃騙<qw=3x양NE;0uCOusZH.N.ʞ<8۪nC;Q尰ya ܻeH4!>̳Z~- 4ᡇrv_٩v_(ApfնLAC6 5 NSji&AGw}坳jZ-)u0n%40KHf-ņ%]xrZTx0+AӪfZ rc $* q{ciX+V(ջ_ W̯CLU ^ԻGK9w|aKT'_J&M'^IRS(Z16_^ڣf\$ÁÔpX Q̯X .᱑\`kX+Qlirt endstream endobj 372 0 obj << /Type /ObjStm /N 100 /First 915 /Length 2168 /Filter /FlateDecode >> stream xڵM$7+t^TP>`0׌/`ܞZBe= eIƜIR]UE KM2pI  %Y/RzRAQuFI 3](@ jiJ &5fˬ c[j|i;~VTu+*ԦŊʜPvkܐ֭;-sKԋpOpg>cOӺHSy==;\wpz 7\otzMכ7]oWS=i{:ӯw/^G| |q})z+K͊ǡW\:t>}#{m䆦>xeEdO*l1knΔqOgυg=-7{yyσ>2yqJl%c֧3+᳗2^mRtf\ ڳ hl#>>2Go% 2^\{m=\0Y #@ނVي>id sbS-$uMG̰ͅY$O =0Ȅ(I&&!:Z"j0JmH;H>ǥ#Bd#7 *=XkәϕdՖEz˘>sdQNg֓|:3|.dO/m2|cd%vOgυ-LmŰ/>{f0f]әs!G{.]FsZbBXڃ.AN̰y4oa-yn㾥>s%3|MNږ>[Acq;r=5Z ӦFͶ]޴u>>2'lo+^aXhLk}:3|.dO.y4{bNhd'td\ -!a@$k]:3\.dQgs+Ťp :DZ'"Z҃әϕյmC:^ܶ?6Zәs!3|fel+0OQ9s!3|CoHDY1hzt҂ kkۊIŬ;w562'zt mPyҊ pBrROI3σ>2Ui'0{-;#Ozy:pC!Fw>-L3kyW2':+oK&ϵZ cv;g b Su/6zйƳ/<.y'KoJmEq\̵2 G9p?Q6tf\> stream x[o0+|^|nHlbBCvEjKiƪI]vާvJ?4CplFՄW#wbB+] ¸|3:Q-;!I-F-Usz=:Lb)qL,5K5p +Pl)+L^jUib V"$Z+P-0{S[fhӘ*)lűQgf1BF /VǤn a2hw;(;b)~# CV=ZoMż̾^be& 08͜/+t8T{qNTGu[aAQ-petK.>|u.,Ye:wyI8faAj8sn4sCַD2>tba'd 8*U2,"Hb8viƠVlnm)GLFW}[Jݪd‹$¯_b~ŋq$5(R6JeZ endstream endobj 505 0 obj << /Type /ObjStm /N 100 /First 889 /Length 1608 /Filter /FlateDecode >> stream xڵW[OF~GP{ KiQnv˃Ip7v`IIH 2wnsfcic`RzgJ 7Xwhϙώ9)9B%i( R+L,fx`LL80Lx =AyL4(L  Ǥ 3ia#1qWx9V„4+(c>`UA2@2 09@/tă Jpf$&Z&%Х(IR$d`RrW:(Z6 XYl)4CB rb0pRRP r6Q_܉rT=nk[n1AH,Q%BNKa$FKD-=2L+@-JB#RE%h8a@hTVT^+TꕜJ"jhV)<Bj@b U9e5Pc<\T׀{C20;Ŗ'ǻeUUwIv1du3.c{$;/FMz$ƋԺ{RRle,X9{.cNL) &5posOᚰ:l6.swH8(u:L6+xƹ[3턳sǟhOH1tz9;.j:Fď-z:6=@,;kEXvvt̲׎]>w,.=U\AprgͨhcK2?`Rm5"Y@ޠ!9YdXh78 >b0ahq 7}.__.N$ƅ)yN)$uu˜r)vGR(.(EHq4opsBJWaM"rVs7przBMզNWPƭ yϹhs;\Ӊn48/ܱ=R㚓ƻ1Iw$%jk+{P[9]}4B .x6r%Zp ġL`=ct>7L/Aiܸ鴬՘i߽ؒ $ѣY+ZL6~XSތp %mzyIGvpf<+z-~)Me(L3'߁-VYvI+1 XSqWI9FɯyW}^Ng+tn=)Y7,}Y<:PKf(ͼ%uf[|Z_/XFкzTGWy[nZJ|ۻ8;!Q}{;QޕuVD^7ߔlYv׋]<ը$i5y[W}/_e 6u..\Rz=}%tM=V "-7~|b4[7߄JowRN͗9vh!z;]lI]\ϧv{yo~(yef!^F\BI\CT%2v smρU> stream xڕVn6+̬7n$H2bbdʐ=H_s^S63Ό&FE2(-˜qጄ ,XHF6Ř1L|nX-g%8XŔ5S838S^buLsnjLK$i%gI8d/BCַ˒f5x2xrΜ59 9U3,rJcưl#I@=Qm|^`ш`P,"Kڭn -G.YA$D*e. BcNo%QDPTƨܫAIάBP E;AMV#} 29|-#tk3& mNZd@ GeAЭpJ>T!yҢ40\K5B>Ahʱ0=r,@BH&m1@<بl]0a1h*[@Y2냁@G#jҘ# 9 \Nn^B~mZvzNH}b_N/Ul&o~Z8.c5]&1-3J7;~gy\&E5l3|..nn .۫_̏b-9yKCCLଛC H~BUr)^pE>2 ?fa > *'Ո*K!ʲ(GmC8*z endstream endobj 805 0 obj << /Type /ObjStm /N 100 /First 852 /Length 887 /Filter /FlateDecode >> stream xڕUnG+h8 #> Bkg+.SMRH͐́VUȑDR(ER(B,'Fbq &J*B=ր k$"/J>y3SW}B}>SP"JPe*bsvN L)3)ZL81PF#eԤ1G{3x1'1>J 煦LhR*gGvV(<2MHn211@Y̦ >, *(T`I[,)`yT*fAp`m8C/cR$l@nPjLvzD18AbIUrfo &. 69T88^>$f+E-n@X\\_!|QYH\ ,G 60%G3".b>.6fhp Rb7{&aDSJw?ͮ~n~{^?v>򁖿  D|xO?V8{ na;B]o[nnnuح6T|}粒i]Rv! 5mquP˧ԅNm!֫-|u7]a^϶e6xWo)=HjO O]W}p ͍$-ͬy^ VLnV2_+(9E9盹_kOm+r1-2&V}rBV'|=WFthJWrbX tz/SaiiK- endstream endobj 961 0 obj << /Type /ObjStm /N 100 /First 927 /Length 1014 /Filter /FlateDecode >> stream xڕVnF}Wc"A $a9} -6QJH*mgVBRK5`9s93 A)!#XrRa$%IE`RW{R VIZOФx6;p401D2PW1j2!Yz$d"'҉&(p䜼\H!%F>! i#MH@A1F 1JRp% 90 62烡Z9'͏[Rrh 44 gJ8kP=\TW+vo&YꤠW{\ًh.tƣd.ώe#0A vR,1Xtϯڬ,qπI2/9d2[9Ef&|˜CݕOUחm'68Ҕ,,@2O+}[tͮZ_nn9ro}okXb.3n}%lr G#|>}GOUp&'p)]|>$U]Dl[?F8Sh]4iZuB,談.<X6 endstream endobj 1162 0 obj << /Length 1520 /Filter /FlateDecode >> stream xڭXM6QbVZ$ R !AYHr_%S뤋YkfH7hDF&,&7moxykf74JyZD,Jަ>|qͫhH ʹWzfND \+t1E^:Ϫj_߮0 ^o(XE3ٕD8*6|$l:+hn) jRhgWԅ ý& P`,q0R{wlS"HD k ~ҹ  }|ao˼նmm5Emޖ/Bdش4B?wa7F\K{>k.9)e\s @U U t_O!k?WFEY䬓q?@ˈ_cXj ֚ x?|L<JqSn$O!֘h[is@178(#Vҍf21A,S&bG6.ǃț~#@)0<$<,4-?.lycX ,GsH!/_cpBƓ.ga$ M[;+]ܶ,1I}^v ԏb Gs#es"L:wEJFNBzИIV Wz:L8)S ';Rb.&Dle(ƚ-As071ݯ>ڦ,ǎ+ {8'˧ډc!/z}$ɩzvm-I*\aEvN}LX_f4 -`V@;uʗ0%D z[(_dtTy CŁ]lUv ӧ d<@ ({k!L [.anNQĪS4nuރ/DNGvUXf ']"|j _ZmEuPBUI*i+e[hM.k꺴Ѻt6OUh_@D NVt,L9cs8;mؑymT87ݲzEi+tC?<(t>Cd@S*†ۦ\5_#"e!C֗{eUfݠb)ĖvrpK ~OYrYz΅|§w@\R$IaūjTmԘ/tJQLm]s-Y֙c]RsYE{ a<|1YuG?R9&@xA<7ɤIdk|-0qn[+* 7#?|_ނ !,=Q%@ ZP0cv'o{=RrBTx*U)c& yL@xǧ7_Z?̅pm idqz/2& endstream endobj 1168 0 obj << /Length 1691 /Filter /FlateDecode >> stream xڽr6-L`֛8m8v4Zm6p::WO TT%r}isӯGp>|8z.Y3,.Hrlo rub(z"U}t*0)"Q 3;:b7ۙaޘ\%Qؚ K`.SfsyX7+ReaWQZt׆nJ_TҔ)ēۢv(SVt/(â5[$t6M}Y#n7Yyҡ8B14psHE͔AƸRNLex>Ҟp.+RNz2#YB^)š R 22'e]W}wE]GM_!@my%GzΫ/x>D L*Z:|)agdɛ;:P*<,;:-ʒVd`,wfbrR6hF'ҴY)УdhFΈ_PˀyWI頖߿=q7EXH Z1vや`pŅ 3\x:˺i@}m/ơU*0 ƴSsEuu5z@+R;X ۺoh Sɿכ<*8(kIw Ec 4eI2/V5"&zgnդs谽r5%c ArIHd,eHʗZ$,eZb+B,џTOv b:dYHYHQA2.jSG1&23'dzCy5fBe#o҉"as'-}:̋=w%V$*p㐜jEw 7ŒfPL#:&r-kEe<\jkVvT_C/_lrm=47mV|om[lk247*6avqKK+Wo2t@yi lx(mw-lNT2B{ɽ .M» xI+״k`4t8eDmЮ5w;_l πhY<`2"0,s/+X̣'$yL9t3ԙ7%WVåݼvC,C|LNG/pOl',8zၻ$]Ѷp_Ud]'m/{W{2vJklܘ뱦SK]`d(BNDuxۛ)sf4y6>=>~6SsQ)r@vuB6$*n )GOkND߸0> stream xڽU[O0~c"-lB2ijMKs%nJ}||s"?RҌ㌧(HknPX/Ǥq4x(%k)]C t}yc8GC!/*bEᤶb'LE#_ dKIJ3`)$$0"dԃ?2Bpn_׋2>;g4FHk UrXrjnBW#|?9 *d! eiS> ,`muXR K 8;BssLzoaNۀ~)Kvrj@?$Rчi[ZaH)y`WgVGcOj{-S݊h*S4Z}vF ۩p WuA1 -iܬI!ى4݅|VtySW-mbx*UmFKCS$͸Sm3+m8rht*~\׎e 0bՆ O[Qn ޓ4DK]~E|Y禞_U gn"xΆvr> stream xڭVKo6W{Z_Tt[@[lk=h-&VaI$' g(ˉ5"pHy|͐"ODVFPilio2uxh7V ZH~}oL$J##4+Yߺ>:zVdIVWZ /L26h4Q>~΢1,'/FZT0E|Թ=|r m|6]0*ASkF30V/̭60/߽V~'P1E>/n+抁t#}D-OOۊ\PܭX# HmkqgD䨛w 1-J yὬrZ+WYHܪV:$R endstream endobj 1178 0 obj << /Length 1507 /Filter /FlateDecode >> stream xڽXY6~_a,PT öHH_6(ܼ4-h Y2$ʛEYZk A!9{!g *qWJn1WZp\x3LezHj6 M/(0M/T^NT^DP &Es* U1iyۜ V?O:Tx-$(#h"9bY^8lnMśwsX=b*wus9húYi+r tp*"ekjLws,woMKǡN5XX)]Wm]QW,FxДmQ óʰ},*&٘ma9_[ ]ĢEN¼y LQǸ cV>]%a57ٖїǦ>rׇ3̓/2?p> ;;'o,Ĕm[yKzɊM$;M. s3]) }$V+lR~9z(( 2m?G*;椨#AB ,v9#u9I~pQ6z llM𙗻,9"6p,J"Ͻ=X>8ɀ(D0R㔅i֞BphƀoY/)YU/[̋}L F]*: ^M)ʲgY_ʔd(n a 8DT* )$aҙoIΎ H|^ δ)e9md18c`{l%q2:u5O8X>-4陫YR&9؇ H@Y^rx<~a5t_w $ oh2 pgNO,#P׎箟/4y'^Q|=q8LBiJb`a } endstream endobj 1182 0 obj << /Length 1700 /Filter /FlateDecode >> stream xX_o6 dϒ%pwۃj+l}"%۩{׻a(PKER#O, (INEy-_Vq~{,[8.2GzV?<oLfQ&긟^˅(")U)d8CY$ZӆDeow \!LdZ?+"#; $P]uT ECߵ!b:HD=K(qhBjk;CYЄ thTS Z"::+4q "ޒ-\ }ewjR;Fl"!$ Wi^fjLdŃ;MbGiLǫC]K 3;m0 9HdFӪ"nOM]] vQ紻?!m}8g& K`-w{0X7Kb%o眾zFTYq}B/rC\W6 G[jh]KjO Ʃjw:hH8`[$k;|Ia1~S&E`mx͎EDX3cE\<ftiw I>uJ->.aYfܱuGbj|Yd$SXEIʊ81⸗N׽7u8#(i1ⴷ[1:sңTV5~qRgtwCc΃f'жQ_ԉQDr(p Cg}4=@~7?06?@0:E6,qBg._}}mIYO _*us<?uQ>XDQ ˃z a9Ƒa1dctb> stream xڭVM6|"J$oClE95=0w@ 6Chჩp4HG2 * M9_oc4|y cMmij{~4BQe݅Q3FQZZvv*' z\:I~7R<~JY^EZ +R!(PeȽ55(iҶKZ ۘ{¥ Q+ R0u6Wڕ\BBjQx(Vq1Uh ~ 7)a W8i8V xџx-.Q^ L$d _kspysѼ; μGGdT -5 m%T>vFq-F<^T3g Yӣ2?8_L*S l'dsf QR:!ճHO,qw ,"QyNȞ+˩D♧HW: 0*XJv>+24X7#PCp"kk5(pY:n@G/uc>+6/5Ov;}w /n7_M€lxK Iӱ:9hLF.^g'Usj{ ZO$\i?O,yUҤ5X\NK m {m֐C_ZmBogwcWXN &'mO3txJSۡ+bZr:_j0s4ϺlX^n^`Dá-vk&;[J endstream endobj 1188 0 obj << /Length 1809 /Filter /FlateDecode >> stream xڕXK6WDFjFWn-R$(䠕kaeɑ(Ѷ&<:Z/ZezlU^DWmqqݾxGPawD*̋Iv/ۿ^%:QV}uuWQtЩ oMכ$ݮk&L:? u>\mt"a }MTk8ڞ Ǿ[Zgk3to4M\ʧ޺sa#a5w߰8gL {uB4R5>HyF<\ )a\f&!3Q]|3tu˩Mfsks#z!wwlQ-m閛u8ߖ]xVę1t )Iymh.;1 ` MqB́h^F(Qiǹ|x5A=>20M\Pv ,=JcWS؄#;اE/fGYOyu,vX ;Շg7!tr"Rϸ q'NH3|cJa [\ɀCsEJc8BG "s1|O5"ctr͂< $;]Xjr0iikNwe2 ".`hmoi{68뇑71 wt=x,2:gpRD.,&`Zq (bfA-;AO6ĝ03:Q eįhR.\@7E<{?%s*4JP* >Z)P.J| ~>5iDayuN5 >x\ P* _ʓ9g1pj:wb1^ڢ3B4קwC"\ݒ@-A +orS׏`%nA޳R_?+\+oC˗JjpdhXx\>PC3X׀K/'vpedwqiSG7o endstream endobj 1191 0 obj << /Length 1431 /Filter /FlateDecode >> stream xڭWo6_a`/2P$raHuŰE緶D,dId_;Xa>yfjvYfn"Kշ+Z9 0n&/WO_qbQlu(C(Z#z$I}ޤ);[Y M O_~> yC&_s_@Kz6xVCP;(2%D]B/Zݴb(!V Sr8Dj\S $K+w|Ӿ3w$_a=04%q]nTn2=3ד7J:K蚓G8ְ$d"OHZOޭ6UO40GaQҝ*?t'aTSm]>]I N$B)NmĐ@ùDO}AN9+'+ v8 &އB H3Y=XB=tcģ<J} _R0̌^}vvH~E;zk|h'e۾rʾJ N#ROx\~ܠC;?@1HxɲAȺ#w┶Y (RgUl.3ˢl* rL/ZEM^tw9R'@ 6]rJx̡mwf&كچ WX1ߑV$X!lE4ט% xG+BSzQUg%7>h>̷Q6κ}yT_~=D;?FZA"AB?^r mNM^b۪5.8B<7?nXc-Os}mKYܔ1UcIteX>l|Yh46Pph7Z:=QKZ> "683gڛ|Y(#GzMsc,[tQ]\Y")%ifB/Ȍc*N$eƺ>`7TnL=WUE ;nND5^Z8չ((*.|Vrƌ55G¸Wjvd۠;6})[_1`sx7D|kv[ؒ+PG@l"Ǎ{?3?mCP9B i4B\mo|7u, nOzjØGqc[W#^~_8['l:f2iPo۪,MqeN;<\CIcSt *{_3<3G-fy{ٍwP9;{q>{Y G<F W71.V-.8m>-NO'm3-tjIhSz׷]g/ endstream endobj 1195 0 obj << /Length 1338 /Filter /FlateDecode >> stream xڭWmo6_!`_d f74$kkާdɒ'wǣdQGx^G {XXF^= lsۏ'-Aq9ҼXz V7cS_n]gRJ釯KuBľi X(꧓7i%fk8ʅdQZ`S7*늺B`p%2L疜3V&`mkM/deڶAWocz0R,*`ꃊH=֖N0#JIVbgn?vP%IvPo YjۛM|_Tn6ސ9kLT>uS7ulҎc}SB L/oH!K "xa*,9ŒvA8-Qk*AG#{e:= &s) *ӖWۥƹ{S'}@DS^ﻙkRUwM:>8kl=0WE6Er(W4gNoBQu6)1εw ~ tpeOv]SC"MTfo`7ɻw?.߿?asc5U?:_]/çv?~߼p Z&"]ژ^߹hߧۢWO̓A8[ol77-*)[Xٌ9?п+஀lAoP-\B;9:$ChN]qnhv\+H?y>,xd0w>r4T! MeݴΞ}~],ٰ~3Ο3E%, qA;z=k`/QĒ(D0a2ރzJqKɯo.qi0Ta%{фj&cI¨^]diߙsK'iakh|#qd*> stream xڝVmo6_!d@!"!M.CaX蘋D"4+QMWHs!Vn$VVyi}k#b 4_-N_GEο4N}ʑ(+0èϚGDnFCD P>t@UwzM:C^n_&w(i0bzîO6s!{{*G~WҚA h+7<ŜSuFrS5En(pU[.uj`uh\#`heIE-vgFdWw/.:A锹 Vx |C]IUo:ž=׉Qe$ YUv]֖L佑YTQBh EQ=} 일=w!%kߡ3mĝge~ 'zxa K^Q0Q\A"u>'ogi- ҄LMON75񪑨_He07rt de܋sOr EV4JN4+*9_A\w_^\OWWK^g/=/i;2Ќ}??fU ` ?*aÅJ?)t ufrB-]QSq)cuW`~@~oZ&<MM'c ;~Bxnh]%9f W {<njOrA {i-)3h^ {?2ygSDva;3-dI'lov>):WZrsYmUTSvҵ?}JMYƯh %3f=/_N /Y}<lMBLWu|JØ.veȻ}- r:~q?GY/77 endstream endobj 1203 0 obj << /Length 1173 /Filter /FlateDecode >> stream xWKo6W,rPK5Eɦ$*J[hW7E[a$7o(U?bU^ap9yXWp0qsus+h-VԦZ}h8$IVU$їc@y,E"nmJVWTZUڜ̓m'&q(RA*N@4Covxj|C Q澐+0A0z`Nᚭe ?H3cHh)rZZ4mP`C4 (,x6#.H'M[S `n7VZWvj+htɒ86[W0!XnStezΠ ~pvra OY(_@.]eX{ߓ5 O`4I7lODa$.< sY'[wy,sUѥ3dLck5vg@c6hlTϖk@$Yd颠ۊ*Z(Gj13nI-򓫃%#08 pYР{m#&_v\{=bid&iX$WzV#kGɹ:݉ծM}@//p]yd\Ndx\ Ӽpo;reO$^4ne " eXՋ+_-xU endstream endobj 1208 0 obj << /Length 1677 /Filter /FlateDecode >> stream xڝWKoFW$gaJ.mKGpa{{0mS/#6=\;h,yJ7'BAb | rx]8{1m/0HW89t#ˏy&mr8d| /)(P\^}58P"%p\@oK!I኱DH%35Ћ(,^)ŮG|YR]_Lts5L^A'c2xxCK.^cǿn-(HȆ}lz}JqD,;-% ;NƕwV/z0Ham !f?~r? 3 XbQ U 5$AWcPr]ug " DEsXHaUnq̻Z?7 meRJ$2pJ/A?W̵He]<5 *ݨpS8y4^410+Ü/KC\* $L pkf2F3<TΎ};46{P؇6V*GnHBCka3^qTF+ y}hˀsT68ɊW62ʁVMzA.qz51cCƬe".NGz7.?&"Qk\:@*Hok [4)ε\\D;q58K*ܲTSKnwyy0̴)^`F-M[jk5#WO/0DhC |x=<2U-I<.)㐋0JgM1qS,>B|ݱL|)W5 '_wQ7۵X+y~Q5ŏެ|UG sdH|Kk_H "8!/KZ2u+UL4f Zw#k9r׌&T#WKÄQ̄m~sE3w޽ZzVx©=)> stream xڍS]o0}ϯfCd:ZUh_>0pk Ddڿ MF#mBBs9bH SISQOw3>H."oJ!h2%TQWؔtRb}8V87͡~DMwWDNYyf_wj%UOc@\RԎbEBADyD8>Eĥݖ?ƉgNݴr4V)Bձz6\!o!p SXpwfe:TӴqRkD4Ki,BߨrW EhߞNeЀܼ8suG۴d;6 +ٗk$S(ڊ1¹LABԠ`ߵ~f'[ hO#ܗA2iIYq O| 0۬ںLQ 4)<<.$cŎϝ/> stream xڵWYoF~ .Qjчvz[CSr(;3H[vd#as9ofv-~W$^1OyZxIVڣoߞ A0I^|瞈EElз?}-89_$,=l/} `xݥ!~O+8W|}n|`Qh?Vݸ `h^G 0gvd `C/)񝴖Y@a˕=`;2e,MUuTq/Vk̰[ɏj%=shL-Dhj9 E6>9{4Q`[mhϿ;^9G9FicrgcP֣. s,XPi֦B5Q0lTqM쎢YK -*]J;=W:LkhˆsjwRiTa[)Q-#> stream xڭWmo6_a تHQ/ΰYutܭ@[Dlɣ&zq) x & $ia2ɶ' -ޞ0+7@럣h,dZOZ0 t:".vQ5p'R#?n9|„;x ROQ̽uQހ3Ih*fv; זE&EۢYJ g%g<%u x2DjS.W(^!xWI^$q HpY; 9(Fa`~F\λktљpBEmY6x9O>*/)_Ͼ*ՖT7']!8$]HbڥU*Nڒ7%;SmQVD|?#fhqmVUb&Y*?LܴZ复3Ҷ6x +UUY1ԚV5F(U@!fC/Y\|ȣHj02#L0n}/ =R,:RqB_G*N_Nƚٌ™]?JckՍ7lδ)f? 8~?G:eH|~ZhaH,kX B퀜mY `UG,r )J!m-{.Qey`Ȕn,_:@{Zz/vsȔTmh߻Dɛm$ 9JoRn1 #gj@ҩEHynnfC2!JmgF2 mj0^|K!g)n"H]r-\J<6Sy̌pؒucFڷYyeYcd#{.lq> stream xڕXYs6~Tk1/QnHQ63fd`Plw 2c+p-v?MhꎦgGto[ގht (_^,`{h}fNF|wRyVt:~`z]&*e?t|պށ #l;bk>alo< BX-9MdAc\lcY<y 8 x9K xJ-фlFgIF|K~pXզu+L +LVm5VH`a`m[wj%AQ8-fpc<sD>Aց f@7EHF =Zүյif2GRr;'ܙ<3+٧yA.NBnMaϒ&})Fvp)_c{eZ]V6 ̒ȇE0qs5;úXcӚ+h*pBPBpNh-.i ~7vޘ}#(#hd,2–|wiKWoi<~>(05>-F_[E3, g9ϊ["K^*`j]',=i%s8p]rF{p:{sQ`̰(0 e텾>5H*2#n+x`0y~dtRۼu=R M. r(nȼKʻ 3\>!=x8P:-AiP31VXtRu NputM \}jG3NoZDR=LJڄR׮u΍Oq&msH`Ҋ#;AO@ mC7 x<6 sU=kDPj>:TU)ъ$2bM w if7rOeE;'8.6qxeҧ.Hc;$xM1J rٵsLGJ54,9ZV#F5fl2 'jB:v5 (jǷ4Lm> ÚVb湤˧h06Y4:/t>x4'SRD\/M<JDvo?zgFU됔#xQҢ0)X-[8:1V%3UNX$Eӷ o4~e{͖z9Ե0ąݤ>,kS1աNG:pQO*K [0ܪo2Q70mRFJtCQiiEe*esW3$EgFc:ŗ6>MU&s6D:iu6Œn83-ŨG$e𸉈qx> stream xڍSMo0 WL%i}v.ij)T@%8p&<;6pQ*PIvE5<9b4`>R3:c3a@qI$ XI4.Ebe27)?eh e*mƔ lmuY޶Ƹͮ""G"Rl n(G!nڴ?=B}t'C"xBw=`)xsYJ.876Rt$M8;aNЪk쉫nJ>VCR7xgKcf*^ք:qF8}c΄Y)r_)0"U=u:, [Ѕ(\)_f endstream endobj 1229 0 obj << /Length 1818 /Filter /FlateDecode >> stream xڽX_o8杻)+uMlqt:)͒8T7㱳6SU~36%˥ֻĭW >;~6.G;<{V'H ]n#Stw>żX|@I T*6;Lp"oTCd,-KH~U_,V5ٯ uA-H=kD4^-X<(q}T\VujO(vM_[:nꯕg7[ К }A:%R&Lr)DM[d*%`%2*N:;ct9+K3Ͽ5;p%cg㍩dT{@WQO*$" >'*>'ǒKUq'qDIwM9˝C+&yv)u ՛9!sT!GB_"c{?PALS,ufhuՖ].suna/^Cẕ-KmZw_A %lk !QQ'퐎Dg p3W kT55ZҒ5ew[wBdƬ-YΑu:l_oF-MPvw#76rƛzM 7G!!x?փ fT LQZt85&!e,$5gƄ0tzt2$T#3zW4`VD>}FYֲj;9a&WUJ/-9;9tS4@$C7f[UU<18WӸ~= ֶ}"glx$+M@ǜe91;uVP= :`8ጋ7Bn+K ֧ m&܍idc~ZN bxS"68 k䋥'sUGO8:LeJɠ pb1rMQp"/" x[a$P`}ciYWX<|rE2wbPckuи~+ЫQy2Gue;+ӛ}mGF&HI F?}I |R,ѭ۹$n}uJzr)K +%(".4XkFxJŽwn:^ f0"7 㩙ö VG盾 XqBh{t _XrG_K3V{1>Ӯ$Y|3^@ȋ ؘ 3:l|;?[@|CAFFU_Po۪3*R,aCzUg_\?rWpG18zRyqz /0OO%l~=胁9NǛt 377J{]>{eeb\ endstream endobj 1234 0 obj << /Length 1746 /Filter /FlateDecode >> stream xXY6~_aee`ň}hҤH@@>pmz- MwxI5" %q8=$^e *JJZ6ǫLWWҥ@zo^|3Te^|Vɛ8 [ҤzNɻuɒ uۨ|;f#))JHpN8^Q?[( n#\O3}s^*_laMD=AF WUoI!ړR]_$rS03bɮV d;C5NDWpeh šR 18~zC+:J*JD~!, MY ڇVp,8PC]g!1"RBpr'fec(v2HƪEW[^5uƊ;Ι]8}A&plpn0Z'<b1+8nuByUQ~{T%hQZf^ ʂU}wYǭz8u}'ljMKȴSغێuZ"b҆gBзQ&XΛ歗x:+3BM`hޭ+G˰4F''/>!̱`Xf<JbL|m p (te@a(~ӎ3D0ŵ#3i`k"8GVލ1># ` R͓<~}},qx80pƟ=&ӓUcX (.7Y0(#^1GjRTb$Y?omC?bqC9]FM4r3%[˝n-|4x\e8Z^ OT,Xt: fkV ~m?<لQ|ٛSSҘq*ML&hj#2> B2eUUHًg QSI=Gqs;` ,x <#$w1D / ޅ\ඃPZ^1B[ċ9 E0|3ʼny4HH(.xuYNG`꧓2SΘg|%rx0C-=瓊{g/623BŰQь|9#Ft"P wu(M ˼J:N}r:39'w>etNxsGŜsOXMAF=ReB:V,b/Ja3-F7jH(lW1l/u:L'7XaHX ,u1dSeF~qn&C_gw$Uըa 0o LbB9ܟaƶq*ryRQwT}#E7Spⰷ0T%SpErZObךCk _#=цޢj:`{Чn<wfFwyrS``qݴ5]eCL=c0ZU[)#fN~R v ^C{_oIa\/ iCEn729ιej6S̘|tZ&ߩVI$'`5!cṵL'BfFo;:T 3&aClMX:MbpN) f .$jB#~F4Mu?!s endstream endobj 1237 0 obj << /Length 1559 /Filter /FlateDecode >> stream xXn6}W[EKmݤH"E<V!K ];!,_4EPpxUMnTT$$лՆ>r#쭔,fwUG:? B/{HzoiM1Tmo"ګN5aęݯ'ov2LFHiQZa܌[_ơ^WU$̙{F tTl|Дf٤qCN/ ,29ӝne FeB~zsŁF+k|H& <d E£С5U\ĎG & _=7tMŠ\l L$aJ͉v,Oq *I'7j6/0 FL,J'3oBݪX(j9u|j^1[kG\xE4s2o̯:0`{rXX,L?֩%>HX{IvO;ꪼflKvP$Pv$[lc?u}ORݞ  yqqadt8ŷw|`p/.cČr'zI~uCDsT|z[jlWp}Ajٝa&ټ J"[p-VB0EUG΢m}MI[=teyE˲1QttQJ*p(xkQ d8{=] SLҽ>n4g׽e~e[irwຎ$z5 UcDZ||Z-Kn7rP! <JZP% 70WzJ> stream xY[OF~GŞZXD+R[\%*(v~gRj '3gΌ'B8Br}*f}jeAӧcGhPeʐ 0[8ȪL(x&%-WH & ђIͤ$&AũlStd*DA3M cv @ R1<3 r`!ֱ`),й9I$b4D)J%H"?fMQS4;zA8.9`10rA~ p$44౰0mL&$,ɵW3"$"FAaK"Ø4%L(#@!AI %ǔA v"Xes8Dܹ(a4Ѩ2*) D*hǜ@?ADik@(É,UG;`P "T\h!9(]HFۀ@KAKb("p"jQۨSˑ U ȧ>JXn'd\O^n-2x2y>^` H.Q~| Iǽ! |b9 ,6q ;2Ŗ{ErErj|rȐȍo!Yor}?Ƞx~A?P=_.o6X!)X!q HPH~ endstream endobj 1241 0 obj << /Length 1499 /Filter /FlateDecode >> stream xXK60Ћ CI^Z${kzZW,zl!EY^{ִ8~͓*e4$jvŧ7ʅ N${+<~;Uu_~>Cu9WP8xD0ԛlj#OjZUo:dic?yw?Ă_I_%%$BʇV(Z% ՚!WqJUH91fh5˂ٵrW~6X ~띢 % О4fxjqȲ:5.A1iH|mNN3X l|'zph:u=1gZ?+W%/ DL2Cn#kP0}C MwkyOA][(3D U?Y w5 7EѪC EIkoxZ?L'9i yil)2w/_($%H#rTsoK:uNxJPr5WzHSD0LR*<0W[e~ZX?pWVK2:>pճa'0|jR(\OmL}rjG^;w,@A}z1%f/̧CA0R7uGЅG g \ 4vא dHd;Ψ>x11k*cwrzXi?eK@S,uӻМL۞]`23j\G?{li_@7>ߚZnho0l_o ㄈ,$M-}^9L\3+ $oJ cى3=`K]Tzg/3",g>ǻ}cb~h+tT'~ y!%)~|#Z8tL ICd`%}Bffɜ9׬)4"$* T|q +ʞ*% S9Y“|z:\hjqmN=c|ߎl6y 5ԀG10g;E<-< 9m,%ך'*4ZeU )$Јl4E3get!B(H endstream endobj 1244 0 obj << /Length 1595 /Filter /FlateDecode >> stream xY[oF~GV c*5MȕZ>4} Xri3`X]7)RH^.Ù|̹$jeTvwu2'.t&$.Cm\,pAOxv|yvYΆE^o,:YQwpTh+|5Ǽ}+-֕Z83($F+/С1sLd5GNÙ}淟8Gbd;5t+ⶪL]V|7 Kj_གྷ0gkLY]wv2jj[ܦ93뷙g xu›z*tR6#7Ep\ AtpU_Ujt<=]ߕU!Vb ,`߸Lq&m9PI\}AF (mg%D_UZ>%GœrZ pio^*Ƈˍ]!}[eR`A&/Nt%1%|F_]UXj(tZUpMg9gD0i~ o '>G*` ̚WKR%cv$ Pvu3 StfKKTZ(ajOK^e]q3!g[m Ab\ۆ41ceA6;e.{l!1+up]UY2>Lz'h>vK,>$b$RVfX(EJo C"5|y>Hk`'-5AN#Nѓ=Z433gQ"dPo"g= CwqzC3: =o|? endstream endobj 1248 0 obj << /Length 1278 /Filter /FlateDecode >> stream xXKoFWH憻#@nrjzȕĖ">w;Kq)maV3|ʇ**;\i[釻W<&?|bE} ]SU|sOl\/'yz s+ wV6ʤqWףq_mSoC銬/S:RRt΍rp* \ŮJU0t{9)Z粮vCƎ*:z𜥨bkNI>,-o/jO*ntUe vȊ%$дTmv)\'&iEUc泺T]H ڌ pgЃUsc0"\O 5eȃ܀:pLԽ>@j;$B02hȢrA\hc2e4xW_Kh8a´)D`d" b[%|(Kك%I bBZ׌P*󱀑nA*v+F]2رB7F,mVCLU,vȄ\ɬ3i*'|dCt$¥jJb@<{&i#М1<1bXLk kcb`L7'k;hB"|_Ih [^QMb tI \);L#SAU"ipQ'bSa|yF|YJN*zYC=YхE>ha7wjcR>66t()TǧNbvҡx ،Ų͗u|Q[jLK.x 8}Yٔ4!GJ׃ak^l>o_t*xV|06Wy]Ku "g\Uj'<ߵ{. ŏcdxTMZM][d PBͣl$]`ہ3bН2 endstream endobj 1251 0 obj << /Length 1012 /Filter /FlateDecode >> stream xXn6}W1K P.lH7OI]Vw$kQ4jں %j8<3s8(eQq48Gû30L&7g/JQshs7uECqt's!$zgfەAF#&6]nK&|%Ro}7cn0M'SHa!Cߵ]>D MR]YgKL%.]S{pnY:7Qb;-DL83eg> stream xXYo6~XI,Ft(4m R8 郲˵Uh%CGI{$\;~3̐x?J*(hbޯݛ+l",ɟW/^s1;[z+xP< #Ji߄c{׷e}OۊVtIfM` ꯏR0v(f@5dJm"X3Dr{/FMU8X>4\4$F1! ڐ#0 #'ŽS:Y }YZi^csN w˺*8ؒESZs=[0!gTi!QJ¼j e줖dHGzEX9|Eu5qZpU`."9=#\oR 2sOWer[3!lzipFʂ)6ϷniGWis" %1&@)!~h;5C=ȓD!pL2M)tz'U6TֻDe4 r~`-9ÈA:-_ܢ%x/jʓp)+;Mҳ`5 V3n!.p\K3]$(IsŌ+@lgO8ߏ02N%tpG`02;07/2tIz 1+_$l SF$A$qxroXdfts:3RXsP\r [?̜)'Jt ꍨ&LjO;lv7S1){L<`-_ꦥ#'s1p lK Y[c>IжbY0U ŋ҂ ^k[/ΗɐڢoNF endstream endobj 1257 0 obj << /Length 1303 /Filter /FlateDecode >> stream xXKo6W9I@ĈGE:p/15=(ZZŮdP_(s$}0`h|34ANHQA}J[+lbl\3Inj ~WQiXbJYx4zhVmͣIV$vf2Cgzj[(Ep:IFazi+%AsFivI'ifu zSC?HMXɜ بq|^0^9QAP QEn_?D8lL]3Zs \+}e۱iƭ`m;w9ra2@(&D%"gQ2l,u`4q4ش֜ASvЉ6%"$[ Ѣ!I ֞,iX:S;@E dd^(I_nPU:)€%=7IT;H>5b ͧ9c`l fܒ LU Mh[^|keD]'٨vyUU/lESNr8U' & \ Ґ+ 9hMCoQM N.be)*QF*Pi^ix^, ( o\&IYeׯ&Bi[H(0VIQ?5yS6S,@j#E .SYg;NBA%PY0 ̆G&*҉!IQ?v6Jq81j| C:c_Y~a\2;:hξ2kEpp@N :}(⭅b"9+d>ȦssRݙ8y!'xY[ӹ'> @J}F3 \;dY`{EBM[ ~E% 2[ETf'L,w3- GivfdTܫsЩ\WӶ cӍ؜o3m\"Vݪs')O+/4kW"֛b9/nUXiHh+Bf:d6S,* ̫W2$,km7$sEW>g7yKvw{9Sh *q549vpFQY'XˬEήͶ4"Us>ۛ^!ӣ&_ h endstream endobj 1260 0 obj << /Length 1220 /Filter /FlateDecode >> stream xX[kH~ϯ$A4.e˦PM A'Y%%~hFF;NP(KvsOG"?4H32qX 7B$XM]-VCmeŌ0Ŝ"xUv*}NֲZ()NfŇ?cpA`nF|uYH >i&j۵p%5r:@8"<&6Zԫn]E$TuBe77غ.C\7/O\ʲ4ԝ_T,6OY7Ƥ#(Xm);epsui~t "-YbYL2h-FZ_E٨z@χzL FR9bFBoe{#LjQΠͺ&(փC_듩2kXj1pQå_T8}t &x A{0큆ajTc$9FC7Fx>O\?qt |2chqEwCꇢk٨^ʫZm!m_OmkKU^n3< ўL9Iv n..}^\ڦhl{FAa#7[HM#&e']),`o5,kq=¥ի|cXmX=h/(=Lu;O*6.L8hU#o6\NMOttֱ R!gFq-;xg`,5\$]A%tl+D]Q{nhz: nbt_ G > FbWct3qVwWskS{R\nTϜ xv(K{ f|\)-nG rm_0 ZW?غsCe|.8M5W/EÚU; c&w;@6R`1v%;5tl lRWBbl ?k =;~'+VpCL[o f]ܜ{AI`3NPBo 1x=zX2|m[K0-^n :TyC>B1gżr >ɺ6KLJ 7+@J0YcaQ> stream xX[o6}ϯD,/.l֡{Ym݃"ӎ:[(iA>$QfEjsIdU^0T|UnyX Wo9_J\z;jYNqq +xUEHs aߵ{H'W QƬa%W"`my}l[Qbcҭfhڣ; '9M ᨤԴ]9e5Y8v3 4muֿ4]-,;E$8!Q*)+`My;dbkojm*63nL<"Aqfc<ؑ(JJ>Vwr،S -;mʢNF<ޫUg^*3V]=ޮH~oPp($ĤlMM(l 423~ݚUuk)c4%^f@`1q]x!NnH:k[U*> >AXW:(t%{(3Vuд0[F|k%F[ ژnDwd-` 3JΩ f%U NG2%]$2rbCѤ P9s6סY|ic 1̢"L(/)`ZF1]Ʊ]bp˄I/eUwXAvsΨm+p> 5Yt,jB:"xXc\ f'lN3$M \^j5 j$'9ĺW橍)>mĬg_]K;.P9 OHZGp6[2Ћx)o8qѧܗ-q[qun U`q9XسhvE.3,JƛGUi_|G X0lC-ҝcAbVG7&?k!>+?5)(u ]O0 yQ- 1}c+_r޽ӯOww 6B0>}O-O; <V`> yX 2qe׸(}Txliaxd?}s~?;]v`{߃e~uԱ_T, endstream endobj 1267 0 obj << /Length 1120 /Filter /FlateDecode >> stream xWn6}W$ë.[趛mS"5ڇnhaKD'EB)hp̙CH X ius8^er8If 9 `˶idde-X7YkGXØ$(ӨCxcg(ͲUU3᭲"YYVm#-Dpl: `rF6Nvw_ү􇔖;MeMOȋbrWǮɁsD r4beDWU?!H МT78waAql\aۙMC0h&\V+mN&yPv G4 ;vdlSmmTm6ǀh@6!cY!Phf{_젡&di@$+_FZ]CwTdwX`h4)P$4+ڕ| OMK[vLiܽneSvGu&gN[@fN =ˁիN)΄G2GfOEn{J#p8𜳓\Y0'%䫏[LBBDvjuQ>u&[[l{xt[c@ 'Ř,)o,RY<3c)v}b.PY9V3~xM?)02{dC=wu Ci%ؾRG_J$ f%u.'sڽ՞3c^_Lm._! 9A˱@nG;^7n@<屃_]kVZ[B= Cu-ݩF6OarRg"^ 9= ?&] ? endstream endobj 1270 0 obj << /Length 1359 /Filter /FlateDecode >> stream xXKoFW9') 4 "p^JbK*Iq}IҔC 3߼gVPC dri]7?\ KHģ~}qu APպZ(8!D8EqNc[uת74ыq3Ao/ޭ' 3(y&RGnW(:8Q',wu]Wf[]] !P0J0.|B J*R~+0M @;!K(;"/ G0FPKPr\xB2p*} ͍Doym?8w/%2%`d3vgA1`>Й}ĈD3Wb]ۊrAb, I,1@I1LVYt$2IE3Eo~nYXچ??ǧlHlϙ |n̡䍳UHF,xsƒzV*Vû|hPQ&Pj~ 6̓6(f^,{yxi.zC_So%l!1P2* e2R  %OPrZJV\R*щKR a:AKu'YXVH+?s"V2 Ȳ;w6HܩX)e:.'Z)-NP$ƗUl w,TT|_x[Gvw+>riZl -Y~(d% i^$,4fZP}5~6I2e%[IYifdxV.zb(3`^H-=TlHf5%K v՟<]=qw0۟::S2ɸԖ4ixL Ǻ^:#Q!Dk6"2 LwܸOۈA<ыiO/.a[P2{W2[E=ho6j(ZckTr j'&V+'X[ӠQ Lj2f/c rBE3e-v9Q%-P{ .F8 d'se4芯SOA+E? eH|Ymtv_B{5G"үͽy94Ė w[Z7g_ endstream endobj 1273 0 obj << /Length 1328 /Filter /FlateDecode >> stream xXn6}Wy^uIQhnְ$!h[ŮJvC(su P,Qrf,ǂI*H*`>&0/gE M$8zAQьSUE)|woZ,"!D]DR"aW-۲kjOh/\pb\qE"ҏ<`PkP% ܌p""R1˛+Vy3fOzyv+X"#RWM Se4{z\өY 0b:(LKnƇq2}Z\)J8c/P3VSv:LӉoH$$< "[\3g]HǍD"H]7fHO 1w =ȭ3MyK AI"mT"l YBb!gIdbOuUe iW`EM#T0ijqތsCt {׮Į͓vL(qW2R19,}0zoq3xcA7XR},-XJd3vIrYZȳfDŽ?uܬP`L7""蜜\]1xkjSqcp3&7!S 3/];IED*\W~5_;d%$Ucy`U'oQgO(o/__>mP~̓2aePZW7(I[4 T~ŔP] {/?_ݦ-mEQ(u; q}P}>A* 'RRHUUonB,\E:K[9mu2Ojl쪪nr{jo8ZI,ԄXUNjGvɫ'LO@OxSB"G/0moD g"flU3˺3!`joM_(X @L.W\^a僌|`-1t3y_N1;-ઘp Mn.F"̜zڇY]"KLB3f=ߠlJs\CX8,6$VCDOpsĺ,?S&5N=P'ׇm[խk5n{<Ig^(U3]m1:eE~ŨPQ[ku)y墆N$V#ا1B9:OOvpWJ endstream endobj 1276 0 obj << /Length 1113 /Filter /FlateDecode >> stream xW[o6~ϯP ^%CaM[@Ѡ1vTv4ؒ'Kw(țuÀ!#S~xS/ I{nOg> V.'( ˾y쿸O1'σs $bQepZJ 4Q32{r9T ى:'Fn"!܄X;F(g7wʅ$F'gټUC@_~si fYf|.%(O V)3 zW> mUE93JM^ .G 0* X"CASD eĘx6F})ȍE{Ӳ=]:X)уPZM6zT1C 0B0Um sۃri/UZ= )Ӽ BCqsf XC˗VvaۦL~&ΈaQF+Jhm&,4KMWr[z$Uۜ?Otz0mp|7 (I('U^snϖeIGDOhQH1[>*յ`)d:+ CD%L CChΦ E@%Mΰ5#IdALwd.鲥{7c֧CVfy=BX@6)/֍!K9r~@ t֡sHt :hPb##KEQhb+u. T;cG(G<&ep줌^sa3EO :hvP٨Suwn0w 2/O7۵:`Db0C (T5[]L"~A9b3-ΠZ4px3-J!3]N͝^*]7uq/j=YO2!IY^"`)uKa1PzxI+Շ0 = rk:̀6,*nԝ Õ[B~ Mi徿WL2K;s ,KE  endstream endobj 1279 0 obj << /Length 1097 /Filter /FlateDecode >> stream xW[oF~ϯp2W`6j+URkY*,ɦg36:ժ[UØ9wi@) ҌCӠ\mHO(X\\IP(,VSQe>o;D127c@^cnMQ&KHaMokmw;.@494sydG,weU ~cE1ꤒZ/|^_6B4/ ȑmH6ģqaUk|o!! MF[3/-`л(aG V8!@@_9WNb*cJAIɌP rݔ#!SWɶfd1 9ObfLBqn7:mrU6Tn% gHO]:{S}oڲzGl8V]:)$ M*tFlUuUK-9g 9Xΰdz."IcWüN+tNc?g@C'䋏6荹٭#.c\clPgâK,J Ã#@T"v0Zt.惥Xrh+7[vmf8*> T%)5wاWK9;%<"Jpv$iOI͐F)tkS(/@EqjtзQ`,z F ;SgI30wlm0^392*Y'|gT?#d qgKޠioVednCY4NV4'؟:ˉO|9ʻ|y6‹_ 73QL> stream xXKo6W((P4Kl=(6u$Cp(Ytٴ( Xo(L.\\e w??/dw'oiTjKtvSn{ƉR**I]Ѯ^USH]صmmq"3nH˟N~7R3#B(/ Ȕqvw=(WLDd(?qeR0r&%koζUA[%,G*uU}MM?oh1$°LHBR hwW̢O3\qŰ!5=pȉt: u\Y~ⶵ˪èeXaWj|"h<؋WXiv=:We_R/8ɕv-%*o>Ѽ-qA'@ -]MTnveֻvW?rWv]@MoNJv.&8LY+s?*4sѝ<-`Ȏطn[j9ӻՠ) ZKl ᛅK$"g>Xor5ogDO L՜N 3Qb8R*bih#oWҾA.uaNs Z-F4iJ0 UPLtX2 e?P`\:#$zgSni'TOs&'yCavfdD zr#M]Y\Cp侄e eTB"BbANܰ U=IaߠhSPxqloa ^GRq= 0P ;"g(y{eܣB/e!@4;Ij?Fc!}́5THЫeB/K_臔]u֮ Mw>݈', g<lX"Dzkz@M}Lʊ< sCaA%s)Gxs4 zC؞/v Z!\ +t/)1LO 3Z.yCd5$UE=~Jw6+j⦧>-X?PŶim,)t+0ޫ!NB< ӽ7]aWsxcp1n7A%^Q7zB ,0U3b8X`X@H)CB-jOh|U}Fuz.% endstream endobj 1286 0 obj << /Length 1551 /Filter /FlateDecode >> stream xXKo6W(#Ph)i=(u$C!9IE$m"@LSo^*c,$jsveW?PA0$>9rER$]]o}U[ǜ8_Brhl6C6Vu٨u̲$-"p$R'ܜ(' e)Il˔EV` :{A]ۺwRRHɴd3A$V͂|0IDOLP* sBzX:$g:]RC;NݾʺYH* rtd\/nz8o㫍r1'QF ckŦmu1 sX0855, nbO Td3#=Aښslʀ#IےE[ Zs8j[CScXcmY4"^DEvUv`ꯍT)|6Yy6+ k(aDڭ{MvhrO7K^O=zySJ8N)"q*NΒG'!)~Ŧ ?)E` $qa&GP*?.jdٴ:>3RFnT^vZUCnqRr :b\̩r=IS*Z~Vr׷GŔˮ#S?O]lbӄ$az{ؾUjeJMVtCMXKd$,t)INm tZWa~7GX ~1=\nZN :$- (T,P Mb~0!+_VH^ lەOї\E#]ry%Wf ?&iv/8w6adDoza+I7\žx=% GResb*:K+UMoź%(}3i4Ow¬7ֽ+즑)vl{w;7.ϕVwvXBٺ1cVݟ^-]˵@8dfrG Ǧ0Y~ fZj_s:.6< &wpVPYbLOܵYLqIbaLrhͳ< o,bK s^wHo0IpD6%W6 endstream endobj 1289 0 obj << /Length 1229 /Filter /FlateDecode >> stream xXMo6WQ,FCR_ 5"prmkiɯHJVFlI&0R7ÙyMI&IKE)/a苛_.h,^zEYfPw.?u!]OWEWݑލ:FUqcy#ILn7 X|n3H,N}ג]6] a0{`p`\h<zz[-wjWK^p] ?U1 r n9kߚTZw4 wy:k~XVeo"x["&Ƶ3:2B~FaCXZ!{(1ofLʊLdK[a'!@z2Ki p6;a7~ߨx(_kqZ-,H'0&E)Wk"#&{qBD_ (q!W,'~i$L]nXs3LwjڛaƔ>k%rDq ) ksѕ1݇Ζ* >ckx`Taqܰ< 6;5([R Lyǔd.Slo|=L3xЏB[%Uމt1?ھJ[':%jGGZ[o/mE]UpNk6AUehި~x<696?O'jD*Cfp Z1xFK{{0&haFh}fZyE/McX:¸ w7Vg_UMx4aܒ̃{nåN' ߫CN}./!K1?#_0Mh9?:D;T:KԱTs}_P ߨ۲ ҙ`(xѨJTz. _{tbd::wC1$Wɠ8V0p&=>Ws/@,`//`CG)G)2Ypԇ՘7Q4>8dO=ߧu][> stream xX[o6~ϯ0 X&J !{)XuMIwxL*ꇠ6AyxܾcE?t!33&˻6 ;8cOXINk_jN5QC(\QQ_- GWjU-US9bY/gXpv"A ܌. '[9f()E?t@_7e4"o BP YĔ&~O.M|ԠHD$NJ8B+;d8 t>P,]QV$ ^]LA`l``Fe]UpŁRr@Ȑ>"Չ[Zcd|&a)|$ #Gx;'{S3rh˿Hʎ+]wvJnnY]SFT"p6rrD^bAδsBӸgIr$Bчl tE: B/EcmU⾚=c mZ^4l_{eL Ժ距. ̹KANa}&IԪ&1Gҡض#XPfG~q/*V N(uys8™Wlup"wa$NxMQ_/sqN$,җlD'IXIS;C9!D1<#E>2fgѾ٢\kajh CKe*zmԠ6>N]Ȓ0c!Ir!' =/j4{"L&eYJ/gQc|gr{Yȳ5- t,XױciEuI/nv8&-J=s8gcCRNRf ) @YpEBz)4Nh E=U .8mU:b&ldgP"+$>C6'&|9OdR`x 0M2n*Gw3wC(iϊZÔ.@0ѵV(w.fRHfN\Ca={:3Ih(Zv;)G SCߝ5:#pao@p~J 1fztv!Z5-K=Łf cȜuY|MV%=yiVB' p {(tD͜83fP3Wl.4ZffЃ-FmSU]ʾk_c/[5&%TWQ4CE՟\ endstream endobj 1295 0 obj << /Length 1269 /Filter /FlateDecode >> stream xXKo6W,Ћ%J 4u"^d*]K =A{/=vi{Hip|34^YUqwʼ[W'o.8_eqWWsUW:8^aD) 0baʂ.u!È8~99#葖:CsH 93A37Ug2/6歔,zY0/yYҹ{G׷UIyF"̱91kđ Š/ƈx?c'Q(D$E*ajp)YSiiQ2ЖCU7k R{6i;r )Ya(K$QLgѝ!%$xF80jQ MxpB `HSkV/lD\7LQ !%G"lv)@`#d"7LE!1~M@J1DqBV& +¾1_=0|9U/shev7Y W֮o/ʂ>]_y u(vkDD .@W4EYZa8˦]-{R*P*F8d1o#4a#|c|9B"}j 4%תYP;B'N7w7iVB ٣o@5=(b锌ds Ų̈́#_2?_RX-a"`,g(2ԗ$12ħ,E"N0h'E^i˫3` e~Saʹ>zw Ƅrh[y:"Bͩԁ*'p3sxA2W\ǹ 30ڷ N's> stream xXKo6W{˗D)Enlb[ۃlv}/Il"|8 0@@d eLֻ,>xA\ Lzuc$XVhzF1c,̯$e<M_֕Or'[YmdS<8kj4%Ih@€WRD) 7f;e &Jv B)V ÈpD&쇶y>/yCz"ԙMk5C/ݑbkV>~VBsfwiOZr'(QFIR=!ܝVa߹ԵlM-pމgexY/YW?=ltwnϙq9BF9C5^%0TSqg-}&VE<`ťnKߍK$Tp=ȶ/G%+:gN7v@*+صƥ_g וkM[;QHmEӁ9f} ue]7V>93G2R s >1NQl!DpP ֳ':nbɪt~]_UxFaՖFSh 뮕Q;g?<ΜD ɡֻ &YCK ^l$'>QJ5AwrAL2o?I endstream endobj 1301 0 obj << /Length 1203 /Filter /FlateDecode >> stream xXMo6W(oJ u]n`WZP ?wxhQ`"o<͌$Hh U!_.Hؗ|ǻ7oHF%.Ir['վ&ciy國mVthV}6 OoFݬtSer}w $8;nA㒎pDXpD"˅YNRyIԺPN.t&e`(0"hZouq!BP)sI7J<'3Dn{,pإ8q)!pEb\%O}tCnr9ixO~ԫ=G#9>-90HçQVN p 4`- ~7Pmj ac\b)IZZ9Jg3dΐ-_+F: m+gH,Q5xHjG땎e ; ㅰIhm&$wRwI|ADӞ.ʘ VG@@>hɽ-G3ϧ3+oǃT !/Um YmQupqcڝw2\CeQ#3\ʎdE _m. (,EZ7J߀DOmoj0kӽ?;cN#0"}zFG7h6gNwu.I܍$H|pP:OT|btpH7?L7{}\zf'ih}-\\J=,SϳB$xU֩|C"%rHܾn^S@cSnȠ)1svMvMN72wA|f\!Y_<._͇C@1[B&_M_8v}jD&Pղ`''4 60@Bdya6 ;iɲ&`A8>0wL G/Pb`.XWF|+:(n4+vjQSZu_`ph>`7@|*%RYPpwN\3^)}G=~VF_MK*y?l;L5v%/n|{n=v=S%;=&TTN|f endstream endobj 1305 0 obj << /Length 1252 /Filter /FlateDecode >> stream xڵWn6}W "uI@/K>}m:QaK.PCJl- 0% gPlEᏭRJdqy\+f"0˟W7wR%9jwֻ՟OũSMqa$ L}ʺ3"xP{ըjˆ4ÿ׿]}X%DHY_PW%BSߵ?.wwGWKIzF2 1^"XN$e 6ܪ9YPSێ jd#4Içx:(@ "y]cqD]U vc$EVuQI}-yS|ơNqA#slZգbt0;^4~\wjMm'*GӢ3wOy^Su[j/:xDa=>XTMg^5GNF,SU"؇,Z|)G>C5!$`=t; #yf8 drg?,vXN/dB 3 ].0ND}Q{DɥPzd8L;YAa4{a擌pKзv5T=c`'R8RD>yр=1I 6-I@<"4w\/{:=9;J0F"-%2 ]Df)rwC8PW8ޮpOb_(38sTTxpj$@v׊Ekuuk.o <#r:\]̹hhDFadF .V/,1D0'V.9~Rz}@u+ջVt; (i mRz я^<=O!,0U?B#i{D:ٮ TLB2{gAbp_|2̊5%;NEk#$Q~${8|݃ƝPov:5l }P4Mo*2n![FulNmzU! :W[Vԛ}!%B^=Ƕ6jeݔY endstream endobj 1308 0 obj << /Length 1402 /Filter /FlateDecode >> stream xYKoFWf @nRnMkP@R ; ť) AZ gvfvM< Q/Y䥻Wg<jVHRNov~ˁwj6C(yL "1ջ Ϡ NxI%|J "͏JٳF V{Vgޘۃ}+UJ8j1[UvcE6bgc`cC;r|'ʡ. Qu9{zkihu}cM֞FtI?YZD*izi.^~!iyΉsj8k:(cÍDOUg 9i\OCkˮTC^^f K*tB !4RaL%c$6۔v2@6+9NIL^ټc(\UŐHI$3I|J̥p3i|JTd'G0^><2 G8|1^Er*D6ݞѥ'(8Gt!=\1xr~՘=/8;jY Ϭz(g‡j6fv|$!wu}Ą?5tNrr$Gq3.se/鄾>[6+O!"t|j:/ u6u|yo(iִ0wӺH \}nuh՟:XP9 DګT)`]}׊YS+(T?{&: endstream endobj 1311 0 obj << /Length 1439 /Filter /FlateDecode >> stream xXo6 ~_qo\`i=l{pκ}}-ߏenȀ@*DVUWD|yN=pqz)(3/]+b`}-qWӭS!DR_Rzerl6C6Lt٘us?x?"JoD:jWg`g*v#/kˇQTv9X2.yK v_{3O9\ra}CU6pϫÚ%ǡwbIJYFr^gz3֍!9ɲ8!qm)08c|7L)p83}[Vܤ)p/\e*mv{&Cϖ,ʳ;uy؜:0HC7>K *.Y&.PvڃlIU]Q 6H0ذ˗3RGoԌb;| .W66bheF W$ŀB2u8 1$0rt-\Ɋ% X)Եf3Dyۮ"%Xb6}AH"p]/ڶ߁+_}e{y|OvM'jX ;U#O Svu?/5qXYԏp*==sȒpS2Vh o~ep .fr$*_$s?)}>zuѲyj(J̺ʓ[]7|l HH{/pU`6ׂjw`fܣLR v8TR91H~h!Slbf'JMvU Qh0 (qzHu։Y\%eW\- &|ėM5Z^}icDI2 و4O/:I k2ݝٱGhRs*ޠ9]Wf^!3)A |2}w68\&nׅ_2cw0ؙ{^>N$'ŰK 6<KīYqB|)jf% ]u0J߁ endstream endobj 1314 0 obj << /Length 931 /Filter /FlateDecode >> stream xWN0}+H8H^K%X!ҴKr_qƋ˥\J*x'3s` A*, oj1fQ̹"á./</Cqټ8$E QN (AIbSzs" 7 }c*_F$ll*,'mH$Iyɑf $y6AU t0V)GBJQ ~ Y2! Mefw[%xaYH_6(<@ꯛHwfLׂe}1TK;#*ße+04l#aagO"CA:c辶$ v]@pڍj_2*W>&xWěX(';wkWv4"!yKC ~!snٴbH?;\4#Wmի#7𾶏? K2#LԔ':)G<b}]a5Bp!oH $,)Z^Z+=]s\.bi^T?LH]/ei?:l&(+.?u/F!FZ4u ijྮd;m mm|b<& P#Ba|~be-f6Al6tMzQ||<g ]o6于RNؔ͝'I|Ы3ۓ.qK ^C*dw#ЩoRdb7W@X4B]܎ab:hPSC#-Tg鳮> stream xXMo6Wf hQ$@.\A+qJBl$CԒZi.g3ogpA^T<ϒ1P_z] e⊱'LJmm&;UQL ˷QL) SWm[>QIV4엻es2(y" 0A kM30-Q(fY,m"¡z.<# 4E8' bbm$Hz 42f?$,mMQ gFe6II Nu>F KcK(f:(iJUׂ=T{!Z{┕MVnau[Q\uZyl{me]\= <|;mvRimb~)(iPmͽQYA:1A2I$p0DSMˁZu|Tndx@M_*mImQ+m*xu +rt^P%c1jw[\.:Z+XO°ucD3[QY` &*'jd3OJWGg <]vǙ+ί=(qwCiZnLaB#DY{͕[3TkT_Q_ڑ{u [cr)ȴ߾`E6u:Ȭ~xUFHW4#iU=tY,#lG D*~)O ) (i8+U9b5SUBSD ]$ϢPxrǙ;.EբUW@t[! .9IE FIW:YN? gB7fdTlmu.L.+pqԨ]M'c**c*I*q|;@gXGٽr{{kYZ; Sst$jtoENDuJԮ'atJK& endstream endobj 1320 0 obj << /Length 1565 /Filter /FlateDecode >> stream xXY6~_7Kn"}kZ[2$y^2i9ej83曃&+ d%J L 6+2o^bE0*qIVP}5}Ҍ1/ӌsN zjN;UjfTLLٸ >S/}nAW#sݥ9‚[wKTi*H24ǶCɓ;5N?kKV-C`j*VDo5?zѨ/! qP0!ܜ!BX`'%CuQNP4` W]a$A0D%R6ƃP~V@"?T=k 2$1fterN '̬?Ƈ`:M!&T>@2i6L cP\A$ųg94F@ӈ.`wO `"A{Iu$҈(B<CNհdP$,vo͒b1tfseeF%c}ronzzvWbЂ͇4V#.e_X|/C$bDlE'1|&3Y0J#BfbNj؎c/,B]+{v#'[ ˥vP䋬ZZoxh]UҧC >K~Om@V뽽yTV>3GBM_ q^{܉gNt{W( TVB&.v.,Qd%2[]i}NrTSa~ht|pvL3ѧЙy\߂/\7s*`8CK4A0Nk;G.xsؾ73/ 2?3Q@ul,zp*++s|M5U%啂a j0M%ŅyGq~AMyol7/ +>TC;=yG ת־v4i֛5܅pg]w}Wvf6Ct[oEǢN=QPN /JQ endstream endobj 1324 0 obj << /Length 1117 /Filter /FlateDecode >> stream xWMoFW\HC/EOQznIx`v:aT|G$J+xUQ^bNb&o/y v͇ORz4$IPowB2W]lιm!i \;]?燼} 7?I"~E7f$H7U"Ja(?5U 7[䱌2Hcn^6?}g.ikɡ*jb.R轱 ?XwHY:l! aB-adg]"0?T(Q)˿j5޴̛CRJP,!/ qX럑Mt4M4c>=֊!bx~z\Áj &ބIk(lĻdxd0%# ï'7:-V(Q$ l42u嶂(Ag:]^jo(\{mnF[mZ#5e'2ac<Sgq 2PrFWS]T Y([_XĪp련ሯ.%= 0BYz)'TZONp.O0qvZ˖q?Aityx%n1x5jbbR2*+4_s~7Vg joYQbzΌ)#Kۢhi[Xzcmv6ڪm<|E@ |b4eKp:|*E߳֎v{oy eU(B-BkГK[$n1 q8pv85QHB3> stream xXKo6W9@!RM@nE:G_EYmZEpf|ð?"NIDX=Q3[\gɅ $;r(Iiw뱪|Kpv"H-(2\EUJ굮uːTA.컻p%8^܄/ PYsShJŃs0J_~LvMV1JQ]\4VAj,&p4R_-`+(F)H*&59M!% ĆIV|}kNDI!zյ_]qw?[C&9Ddl6A]N I[yAz]7?0=A3/ tl (MbRZ jڭK+()ʏv^{HBr9* AV/sŐ S2lqu +zˣdM%QɀH0؟/})J C$z1y9M.0L)*l0-$1y3W kLiCǪSG ]z͉͜CDXډS1 ԉ\mSI(C-+bwQ,'s>P(\ R<>Tڼ7K)&z)`8)Onfi4aua9Bٮ֫g4|q ?Φ Q\@:GP J,\vg(`<7zN(jƁtԈtP!2M=n%ʰoI֕Z#;34yZcWm(Qh<O ծ>N0+' lb;"gpDwAL?KT]T 8ogISy̬)+YUW{ kXQH<9>CgxK>2YɨNzB4-&Ê13u2?[hL6h#ιr0ogw p}hZ;w okg*gL.'рMo`SObRfϸsp_8N}W[/6EbTo h/ea$[Hmn%qڱVڍ86+J3,Ħk+b:=MvJhٱt Y2>C> Cz( endstream endobj 1330 0 obj << /Length 1687 /Filter /FlateDecode >> stream xXK6`1C@mS@ J$6CPmy=Ģ3oyP|_i҅dԫUV?WWLf?^xe+2-~^]?Tq"ʗqT t}wݚ8:(K?nv2eJ~^rn3AY)tyߛm3XɴN4﹈~W8߇>W?ce6(ܿC<'ljڼ1U{yB۪dGkl =j(Ċ+&U.$OY*B3q"z'ؙϞf'%zۜnӏV<(0KUCI& H|0-n`8 T8l1A&CQ%첝uD YM=,@ͭz=z uxMzچlG+}F|Cs(8X:}ʕ ]ǰiow/1lQx?d뒍]  $^>a }F9e"0,zǩRtqFǠ!gwmO36M͛''~Xfd\c(Mhˑ3$hO#:=7gmAw[GV,zfedIdvZ_*rv. =MtWDy8;?:!ݻNki0n׼iYnXe4qΩmHM!ZяX *(#O3f~;OW*#Oކ$3)>1B')f{ץbC4 xFz.(x's*[gq* tƯ9ٲ-q9GdYfoA{iwK~< j&%zDgZjDnD1{eۏq`兺a 6Yk&MAyBq0v{__.ۗ3yoo7 K|O¥`կ*z[.k"nz_{` endstream endobj 1333 0 obj << /Length 1118 /Filter /FlateDecode >> stream xWMo6WD,%J9vl|A5[G$yΈ8H<μTI̕{ g>vC]~sᓔ I&P8U׫s'w@Z?V">b(%]}~w.$R+:31('!EqDLP CS[B/DZfwk5;ܽ_UwuyfvAܮ绖)LƘA S?[7Ktf7sf6bLXX٪Nۣ^Q: @Bj0@a ~ eI +jUP{$r;a `^S,R:bc;Kk.3w3&yĄti)(Kq %qglP8؈w(g  s^D>ƝP% %XY] WU.*W}dQJ$a.YaܲqXB_41Y2 8$>&#p;}m~Y1ʷ endstream endobj 1238 0 obj << /Type /ObjStm /N 100 /First 945 /Length 1165 /Filter /FlateDecode >> stream xݚn[7 |[%^lE]/:c(P$C隆u-ǖ" -Q|,'P 1(&.d/R+q,Q)[AQ5p3T]Mjt;J6FW+U"sFgK|$40 -m$<|$BTkF)$$a-'R)n9E|JJ)niE m9e#rjS LوYś2q2'h _:0> a\lHYrlє|0j9c*ڤȄk yZN sbR% Ė ;d^ UdL d@EcXay 8bXj*0KH-YR,S`y}0"Jv)@\"N= 3`,^&oBVN_ X!ؓFi4fURGHjHKr+1GP-er*' {Y udԊ1-6B + 7TbzMWP -~7LKO/^:..hu qҗh:#(4>C#ӣy?6=Hzsw]KZ[y3xןkt\^~l7~JI~Z/t+,r#3-$9d{}:$CUl+KmXmt0Z=/Z1#2.3F$eGRgH<f[H$IG8RƑX88rOН#A8!:\M_xN#v8qr7Zl|&,p;=v{>[GmǑo~0q$6*q8*Ǒi$[\M:x>}?{svnigTVm9{q73:b~J9M*þaty"m9b(OGPva'tcɸD%E ,' r|0;~`D;H8ArܝofNTX:Ki]"y2dҸD%qoa?> stream xYKo6W,|ÇH  "=4[ӃjB I=(ui+j̓3 lEᏭbA6'Ԭ+B '?]:r(Tv u~ܤ6ס"Яa|DAWnڢ*M\ۼMyL$_qϗr%8^ _1A(؋&0"TFkTst(Iy!p [wlu 7]h+'T4]Ip)p͵vskKD$+#TPGTYyM4^Ń3Pekn,3Rr%=@3KM#;~XJ='4HN|.3XB>EbKH!7@ &ٗ⋯=-0O4KE$9;${յ98UyZB&9ĭVܸcʬqUuVTuk:(RQ^lgM*kw^ZAtMQ^=N4N$oo G``S@ɪ^GLecq Ip8? ä1\rwoiSk7k hֱ}XvQwFa,|#κΦ<͎`>92||]N0n 1ݒ-ŘK (D͛E3XK}oggP8d/0lPP2j`P4gF%6v Bk+3q[Wo,R6&kxniQi TVkMKkc#\O،4{ń.p F'&9+g㘢lf;"g?ˤLtj<g?KĮHE;)M\7+̢> stream xXKo6W(HZ@Ѵ[I=t{PlѮ#z$M}gEI4 |ٌd˔4-N^m33Y /'> 1c`Քrgtv[n{4M<\DGC諦]jUP8iVD"uo"DHI2Pŕa9L2B7"_ vzx\1},'Yj e_Z2 Ty&omU4kZ(bSne3 bR`随!! Qˡm> qF M@ )H>ED?/bpge8e 7# x. rc̦T&F3'O ![:}W&I¤;CsɈi K#*$$b!},MIFld4д@r$3wꗨկUV ZiH 2R 9搐c)zCXT`9amF&K.<-_DWcIf,͸7l^kB-N`\ϓ<hf厩9] ^yQa~./qZ yy&AOg,.G? 2+ۇB4k&5j?Ά7 ~q?-7̼l-lVb7]U/ NDjUͩ5kKcwenT'˞˪J,;u84X;\lb.֋B&TZO%^WU\ݶzvTrgoMӜ31_@^3yzNf|S.7C4:=hgҽ@gbFSw?5/F7";Ey! }!PI#Yg =CTf`YK`S9MuP7&JC)૫ uإ>LKS<70#{SǝVC;}UI%t$}2Ju8A@#sB!{ߣ)^nx Frz{;OGJ޲JxF|:i7)q;)?tϺׁ6Vk}43S6]eŃ% > i'LM}BުP״bv Bm%li5ЅKIǶUo<r>l1L1oR> stream xXn6}W,wI M",qm5kiAI6,u0`/\ΙF~h(8xgd5בpv & 7gJQsh]Bmw Dƙ@CSu']6)uIb3.R=͗f 0D ka|BbN28c4M{}L عXRmo۩л{S~*Cx 駦Y3b)Qtօ('c*{ g.$îd9wF;TM!h!U>U2UL1>v@Ůk_?LSn S?wu!c ,B& HRgrLIHqBTv)KD cb9CcfW^UD)Υdi4T$H)B*]  GkH4,ZA0Ptjw`ʑ`PvL%+.{X&TYAu4R\IeᩮN∂a`Æ1UQ`u VݿwגrcwUgCt)T,UyȞ'Pk0a)g@8Mnėܗw8i endstream endobj 1347 0 obj << /Length 1476 /Filter /FlateDecode >> stream xXK6-2qEIѢ@Էjec9,ڬ%(`8OKW ѕd+$OjwKj{X0X~'Ċ&H FA#mh0?RܹXÆ4y;n1  $YgpB9|d.{E9ҡsSArD K:n o6ՇƍIjg8?zYNBҸySZ%&wŔ ⒤ɼ/>3erZ..KUm~4Ej7ǰ[q1a:DSU:FF"F.,ix:Pp1Ђ1#n2C}+ˤ~Ns6CEO&J@]]ۭP-@඼moYD4w_0xom_\:SX1O-}b2Jl喀:ԟ]Q/=tkpT>s9N\JHYL\ / A0cqemlx!!nl'vqg v;9iq%t;?bϏJWE֭8|'t?c*i|ƬDtu.$ V[P /+k^-6`Ӕx#%nߖ]ldxӦ<)` Pf I 6`Q|zm/^qao)a38?l᭬=(祟SS"/H1>C$ZH _$p7_3310xTj? <%t]KQ8ZQU/ȗJȩ^,AñO0f?9Z5:73)31ަE]xzPV=.퐀\ctT1·o9;)||1 x#?[j+ jCQp6r!zbqhiLuC3O.#Siw{ϓڛ䄋Y5gBhPP+eUy.IhqA`4)|u vV qjTf'M 4Ơ5C^䋒$媫WjFڢZ"bʋʦ3uL\ > stream xXKo6W,|ER=8h4ceE{h%CI}уd@a+Q7o*VI*X*fwa\p @0IQjC_U?׭!H?޾eS'һFAqr)8 }7V\pJ"܌q"?Pqm/lhꎭnݵp,н NW1S*2ZUEGc#d<+Td(޿CwZ}\L/3 ȶj:/hSMmklQ M}Ex7(oV3D07hA0ٍM+cZb!ȴߢc NF owxu~hN &d[oly=|B$$SQz<y?'ͧP#eqv î^_^_kDA&!>5.$]|nڪOA:[`KV;;џ i)T,D[ʴ YEn}hG=HwJv  @ KL32^҇xSN.l!eB X)sfùiJ8!(II[o"@G OFC?'xC,Cxz KBۼKV8cV듯bk^l)BCc~2OtE;#9~sj^g"j]|~GL< oƶ!A[C~*z)lA߁$5x* ]}ߘ~N5ZY ;jlͪAe@yktj׭e8LTh}M@;*P2Qڰ~#,ӽֳ?vp1p3(pay& j6جє8pJQRi6g3?9ئ:0M@0ReR'T@]AgsBFH۬;04ǒYKJ4_JLj|]G 8c"Ө,GzߙRቚ#9LNEǓ \ h4Ӊz@Ho,py@=!`Ԥ`D<.16zLrX%҃`';ǒ98ϙEL>WJƧ=q S4IDyx:D9E~ftBbt`>Dl|y!UQo4aɻrC1uU1zK$inl/VYU{8ÿ'"i~s:.NV endstream endobj 1353 0 obj << /Length 1134 /Filter /FlateDecode >> stream xڵW]6}_/ nFґn{fdj_N؉'!JW;z+l|0go6W2AnԦptʬ0 )e[/Bݏ|;IDbͯW0hx!Rk nBZ$BN0G8>QZ$n( hk*du;~ȺbY>\5,Y DUӯ ,5lLbaB4˒J߬Ij#(e2UPAͭE+`Aֽ>y2݉ݐKat) 8*)a{^%Q!> KB.nVS_~? qPQ8SKؚBCt)AehxBPXh̄A n_A*m1EO <6Ca=Dj)V{f:#kF1%$ل+ˊBPS>ZI/ԧL% ؔ88kDƒe/rJ?=U2UPAj vrR@b7;]AN`W p^lY-m@T(bQVb,=ښv#ߚOJu;}y)qhoz`GS\/2S}&ƽ 8,(&˷ϧ^oYSC1m\zasfZ-ݙn&+P}EA 'b^BJ7NpE.뼰Q I$["Fe\*L~L^sEx/ _ھ.iNS:M4i|mKF<@ js,ⶫ9م^iУ4c3VH5 )m+?DWHHi!MNI#=u/nV(~-T 5债Eշusɋ\u.sMB6RJ]z[dۚ*vB$4%wЭ] atd>ق?V9 i endstream endobj 1356 0 obj << /Length 851 /Filter /FlateDecode >> stream xW]o0}ϯu4RmBć]cbdk*-{|q"D!"'}ZmO b|"?,9wF1\ZfwrlZY{>c̍{~pەiW [,S4ar\~Y|\n#puC*"D$4DrӵZÎO"27ϹhGL0()} hRכYq+}@n+8teڀ:OBP/Q760s06yiToטUUbߏ9.%2i`FL i(@g蟋|YoD[^5HkjcXma3a^fmaѿd-,f5v  [7]{if@ I+3 ՜c!(A"`*᪖Ǯ7H*%L;r’T߭t@3iRCj r%0ozM E1# GxVʹ'@ZȤ>TU&*:L~Iihnd;3|vѪ7jtmu$m=JϺ5ѓh b؞|n=&Fg._MJծPDШ΁A˻kD]^4yv/ | Q7CMW׉~J0d{I–SxLjmճ “C?jMpКya]/N7c㎮'FD5檕|ds@Z̥C/8 …lU5A" 7$;TzEof endstream endobj 1360 0 obj << /Length 1090 /Filter /FlateDecode >> stream xW]o8}ϯ@#ǟ*l[uUt}IH&0&Ɔ3Mj0=>h@*8*.H "&/^KPS`B#ZfN7a9G0Ba"оʻ̈@z]:"qdzL.Rg2&,;e1&RX)01CYS˪.(az|(*0+HDcAEa6|Bckh:,c,5yGsX 0(e8Ur. .5A_Z"ãl׾$TIF`syLKfnse@@ib5v`hP}v#svlϊCyaOmϐ߾7l>]9b<ƔS1-Ld*VP3gRwGqL0FAiIY[ἃվ\{0-:Fm"K7Y{sg)㣁7 F@ojԄ}l6,\aI /o~!%N=wݠ ڲ/,G$G~w/n;iL Vp[spf S:"'t|iQ3!s>"WEkV⤷6`ҝq˜oEM|t o #?TcWm82f;FwW6_>/tE&q|ʀ7ȱN4|IJ%)sєD'@eeM&! endstream endobj 1364 0 obj << /Length 986 /Filter /FlateDecode >> stream xWMo6W(+.?Ei^vECAD[GTEJd%8E 'DH$i$sr&gm RLO"\~+DD0*pAiM_ޕt2Mr.Iٺm WFiTR"p7# ^X}Vn&#BP!ʥ‚rwV0+;cB>wmcu{3dƇ=yԐ(%4CDP#JgBZCLGZ2|m(l^\)Q!Q|𕲯^Ny& K?۷<%O28J)tW>O͡&TPVD#1,T.(C +sV д)BSng;=pw[MΪA+~e[cվ2hOX}8xS/{й#> uٹH08t{W^3vnW22Y7n>uVnk4yXcW>K0@vՔ[b(G/DqTxs7vmBp1*ZWÈC"D\;dB)H0qJp]/9QN?R[U=eR F:sþ,NAwgTśE-1A5pU m}M>93'}FaL r]:| ͨofgXwD2MZro7Krr>*n+ƶ4S:Ƨ΀.+ Ss,xQK_'3D_+#Ù\7,L-[eV C;4NM[eUAWkE) I/ wx&}r0VٿΆkiߴzx}E]rM1f;1Ub@JGߏ endstream endobj 1367 0 obj << /Length 1199 /Filter /FlateDecode >> stream xXK66X1|R )R Xځ-6Hek CD g|3\@7Y-p rrz-oa,@0ErW̃?WD!abQ7uR[Y/4kQb%0N->/yl3L^nDx=\ȨT[Q ô! " Obma`ZK4˵Um]8hk8 }>AE7zM J.$~% l{xUesi?mЂb%c8Q"LS޾tr44VXHeҸm[<d^N~!!a)50qhvf:+_m κmt#Ƒrl&,wnu%\0){[@7iL&. M.c Rư' %_$RlLXav8A(~kwyK4Vc_h(DI~u?qj;"vI FD׽QRd^ɢReR-ް̣5es %uaqU)NrPt!*wux6@EwKS-P h̎cМOѲR- 6M$&kbRL}l >x9_xUTRPfE0gc]>717[h$i]F {C{}3azI~g!1^lkŕjk]8Nl ̫[]5>.θ#ݏ8I7Ec?p'qĘ]h H83 .ȴj;]IԛQ6JE;8㻫WV`ɭK'8Sn}UM+tK)gWz@S%J,ΪuvArҵ ,^SS؛tq5'jЊfS5Njm ݳ endstream endobj 1371 0 obj << /Length 1212 /Filter /FlateDecode >> stream xXKo8W(+vo=(++KDC2)ӆ.lr471 #AS,obu?7E Yo޼g,1*뭭j]_»]y_EҰxWyF]+ooy _E$"L7g0z%InNLQ x% C9X7qr#cT0F4F1 0Xzr,Ϥ x2yi8@Rp@,(L>h&;HG=cؾ]KG&6S (fD5'd=}5mWweUuʪc-PQ1}%&&QWp+ 2Nʦ )An;j 7P@w vSP6_tv5oQ,H׆_i%s])h/j~ MDk.3-u5Q6$"7sXƪeJ*^02|0I%N z^VeoVZhiKOS;@8b`O]@#P7%9(z`P8a0،z"qu/vz;˽c.{11R%a9%]j|CtIfH+׹1Dq6Kp>E9(bgꜙ蔙Ɗ~_WDcVx6 [[i:zUcS`PXgT%HL+! q3^SaFU/YAά ߽9aW*s'@S+uZ~jv>f?07'[;I }%8kp3KmgpJo'iJѲQG !h> stream xWKoFW9澸R#)R Ɂ%W]dP)2ւ!ofxYU\|[ 뛻p8ëf .WۼdF #x6LY0P5z‚r#;Y2,Hhy͛8W2d)& $ 93|N*]2ĉXE4F"yߙ+Ǫn><@P.1fwWeS+xn Mo++EsBSbis"XT@ %"5xwZm%< ڴ,>䃥Qȴ5[8wqRwY7zCd훐ߕUPCՌ[THYޕU'4W UB6 vz:[V,Pz$9 |!Rem dF8|# 00 GJd-2Hi廾2RMQMzE^WnIbPI!S9\i j]|fOz9 `" Χ*p2۪mG~ldYR!FT]'XpՏ:u8)bՆ Mɇn,;4F~E'yn"7S11 "Rm ٙejp[)5#Lg"x>ԓaHm"hZuwʧj8 p,ʫbk$<|e"֧?3?~q&v"cNy?`k4rKbTG? ɜԅmUV5_ endstream endobj 1377 0 obj << /Length 1309 /Filter /FlateDecode >> stream xXKo6Wً s^)ZM5öŖc-lɕd;Pc[ ~f83"Qc6)1 ڍw|y k)#FEj>oٮYil!d|=3"ޗJ7#*r_]7\)'2ka0"T qoWu(}vD"&xGnЭ&oqLf]%NB%]X >x/~S4s[_]8; RTnn6h-A >UD7 b,p|-$=mV5pޱh'9{ldqg&TԐJ*:JRJhܡ_#\ @uBm[+˪tk̖٪U)JG+%8N9?1NL8ݛ>tl%%~.ĎQ[Wںo )!Mowav)!T4TŮvy~.m>%I~!'&Fޜ2uvó LuPobU\rΧ똆mĶ{奈HN=g<''4h13wpcT'n|ͽ?{rp\ǷLju| $ZwI("J.DcJ.aX(X~\"-,h>s>$)$5&l)OpNzؕ0 %+D8#g:8(E7PD)=0${nVĿ9Um0wzcLqN]V NU?4cMrv*0 0d^ HG|T#<~6ky"Hyibn (/j "Hш*5_hxpٝS _>`U{^ޱdCۆ;iQbk32xu~+]O0^zȻfܢAE8Q'ÇEEY>8ýk&"RҗeQdzœR\SޗӦLX~G/ȤSPT8c|圞Sxϐ_΁<ÔnLţ?HbI bㄲ ~֖e%mlT(;p.ru&2fn:2Io7*Z̋-eb @r%Xκ1/g*'^qi Gp9)`+ݷ?k9 endstream endobj 1381 0 obj << /Length 1514 /Filter /FlateDecode >> stream xY[o6~ϯ0$;{Y5HAFm~7Th;źvP 飏K?PtJJ6}8 ՋWB,FbyB-׋߲z?4}^0Ʋe^p.Wyɳn5Nóݪ 2)?\7T 3z'tK aT",8AEAYz%beƢ)CfpN9tBC,T BP%xHHj~SehIP0vB^m%EJrͻ)dp&[]Q12 uv8t?@$MxJ"|S˧N:FF}vI*QBJ)QIw'@vo|u7}SM ZhA, eR{f-[gF,k2 f>A4޿pbGw28ѿXpJ>/ ?eVG=uUf9)V(J8xi0>+$q:Tٛn~zh5-,5`/ .<U*$s.[i{9$+S2B:4umWu}VŨDY(GqF谄CN[{S Mn FIqm To9t/+=Ώ4_#LgWwkms*(nuH*У}-Yѝ * S_HwtEÜ3n%4 K:Seڠ;k(ImLk-gJ\!%7a]M!!CJHL"T@jfYPɻSeǡZRFZ-f> stream xWr6+8Y3&'fM:뎣]#6]Ԑ}/P"$Qh7ǦD: _((ͱ*Ynp}L_he&ȟWIP Rd0Z?SM39*ޤK@}US'ݛӚziҌ)(O_.%X ~#]1:T'1»|mo;g+ё$ < GL.9 2xn](dfRg/v1i~)7۵ y.d*8JK􃿔##~7]bjj/W|hʾ4iʬW;/6`ZǸ% WF^(.dC&.2q4)SH+}~#P9"892ٛ# |6)h/d:Sή׀}q- :Ⱦ//ZRط~G9%XK)P(v ;lB׹=Ө6,PB8q۶~ˍ {xkW{3g*0mC1WzF!B/4ug~lm򳡁<:\s3[ rpz[aڝ&d9;yB<)Rzqg?S.It*hB֝˵vnt3ڣfj!!0YÛFV'v᠚E]d+NLrDͣ  'wZxƊ-ݚp1݄ݡNG\CٯG/>|^{i_Z`ؑ}=;^{o=' endstream endobj 1388 0 obj << /Length 969 /Filter /FlateDecode >> stream xWMo8W؋ T ?E^6ma $,=(2%PdQZOݢ+̛7|IDF2c(c2*g_:#.dbR`D)z_<;*aU¹/WU۸_;USUB%N8?^ $8;`nF#n"" )jCv4;Ƒ2JF2 tUӾ/q @(DmbTcZ^/TF\X$$`2?$0CJseEH8qf-M )74Pu%,sJn̞a;vI\ڥILH}:c =ͧn`)nDa'ayZ8/'2\.SLx`f\c m9'S&޻y{|P*bR]2/wĄqt?z0̝_DŽWc4O endstream endobj 1392 0 obj << /Length 945 /Filter /FlateDecode >> stream xWMo6WE, C&A 4썁Az7pDA6,hzȡAZy ?rhv_ȿ\/ōh7RF@IA 6.=:MrE !7ڣ܊^7$e9͊8Sɧ/7s$?i\""^Wer2Bߟl}hBN2v.lPz~OCo=5U룵IǽڃD8j6WDZ[sb{|1 .SP$;GyߚK@$J=֖GZkjd)dCH%'||#_RNv?>/@ih RSL!H:h|LTU&/B8?WOL &Ie^Bf2Z4Mob\xkPT wKڡߦ]i\}`d/Se"oՋPDL/_.ߋ\fPa.htL4_iI'>Y{t|rrD7&y٧צk7b?D7$w<@ =]Uyov;XhƼI@y,R{ȕY$@̬i. TK.u]jt @RokDn N .BIV̮}&nz{[ޅaR?7= endstream endobj 1395 0 obj << /Length 1101 /Filter /FlateDecode >> stream xWKo6WE"QzH`ͥۃjӉGr~ɢBwSt/Aa% I&6}d?n>'`:uu#Q SUMG|(j1Ie<,u+7jUUR"΋ogWr3F+F! x5\#"@'晅|Y׃q8D9M$y=O0d#Zt/n }g7kǏjY>iL)CX`BDgUn,ʸw彲[]W1argU{U]cMBbPDbW徾U1e3ܞ9up#'޿OrV^$2ĩa$$e)bͦUFoJ"N ɷjA,m%8?٣Ο " kڔN* nSoP3dV eƄ9JP95a=O]_n^^?B<͹6E*tΰǐrF#qϭM{`Yih!alq bD2q %ϱr{ _Ŷq(A@5i/!2$-LhsIhVP,6۰w?5ƨI )J~t_3ZJELJaLC(9L"Ӟs6[dIS#T/R2a'B;kNXNȳcyS4`dixS73vV[j?66(T ">RO5,=eVkA 6%P|, EڮݐD܄3dO7S&<45P60\^+3V endstream endobj 1398 0 obj << /Length 1025 /Filter /FlateDecode >> stream xW[o6~ϯ$˫HˌfȀEjekѵ;[2$*kH%¼le;CJ8N @l7pXm&r#$\߼c,ADz;ZW/j'OZYNIwYN)K2AӾ}S>jUQY9,ʔ7g 3( \D4ZsE7Qg^zYƻrLrAAd%Y~@P $sMVa@NRЦv.<k/  $'p᭕JmWȠGdpĐ;Щk)>C:7oۻ'1}m4^wN9siw,rVz)^2I+9?sjjs-FXz>:;7-`GE 0bFrjNFvz.w62^;lݨYX,M W|J'in>ud:lN|J"D=xQfohJv6'{]].RN['e0Y `fsշcy{_/C7σu"{*ɟ!IaJp x#Ux!M[>)lVj+vR;K3i +%ʀa_ endstream endobj 1401 0 obj << /Length 954 /Filter /FlateDecode >> stream xVMo6W*d $HZ 8{Kz`$Z鮴䮴% vq{$iB&%*Wdjw튆 YՋwR&4lP:`lqQyfBH.-jh"НkʤS$/_?nNK&G*RX.1"VyeXJSԁa#- yu<'x!jAlF9P>s;O+̱"0K $I41n8ar8Ns+B>U~FF.jX+/ H"okU^rQReq68'ϏmZWxW zǽ9~F)h`UHȴǦ..g zo.[?JٿΪ^[2[3B=Eyo'Pzm>BB<^ZL bsp㡩)3%&y^f2]bЀ/)+P=JSPwq\=>@=2@${n [ z8 +P;BĜɠJ?Tٴ)E K.$K)˿zx+OR`.vH=5mbbMT]%a7s-f_G)[swr4}7c4+Zs\?_Dr"$;^SkPKqצf@ٴZ7bϹk-0$.0 0UTYSK"vgta%ܩWui:oO t=HtU);(> stream xڭXKo6 WjղaͶE&±~$Ϳ/)JckFNbHLQ#)ob7E)ʔi=Z:ooы@1Zi|}e3KGmoCuFiM a)MM>TSaq." ptyd,镖Z sdS$gq&OCxQ#paxxW`qp{j0oFN4WFYM4Uv + `l»Q8˒%b݌G#Ҙk Kpj[a,T0 %5`*ކIg)V(RKTS1ApnV} ! r=V/"e2β '+d^%%b~n#UbuD, G59T@Aa:?G[U%+[>vE߭\痎.9Ūvq*_w[3s+55_MT͆8?%ݩ8 >NWFJOIcsAmɗ"Y/%_J+Pi. ]/qZ[5<{N[榅 V7ݽ!<9AjSȴU`]$Lpy,|o6a]=vY]W+ q cŝvnSWU'Wnt1~u&|tgFߒ%Wa#r@6aZ5 uwռw5Q h:F3hК9ee3Z'Š!.;heX4JZXy6v;>4EKq`ǔ`զh3MPRצSRS?닓I e!|Nh=94Gڹ _Od ŢGdtxkz<~* 6'_L%CaRZ2ѽٓX[{R:HF>5XQTK 57JMGcuȌ+Ǹ^Y v endstream endobj 1408 0 obj << /Length 1658 /Filter /FlateDecode >> stream xXK6W=@̈zhnh [ۃ,kΐC- L<>~3$߄TlLL"ncyi&on_ Y|s{tU6?oOePv' ]6)mM|TGթT۝H$R_NEH>R;|mHXGdRTB ,00#h" @č=I]é辪kfP5e=>mŊ>ƪ!饃Ar0OA 2ƕ8TUsg5ތj6,ķu?bX|1LX*CbaBϴG0(/DFvlŬMhdo$!q9:z4 J;b}1D5nAY : yYPf`YBڗ 6 R#>$lm&0voc`db A6d0߫*xp$sDZ l)hz'swX&rk[&IoY(kpo .,1@0n~rh40!({@n[ڬK%Q`؏дd2؏pUs:YǮ={G"YoE~8xы,r[#)QMПr,HTϰ <kV-s0'tD]3VXkQ̲h!m&+#1TpKBw$d ~yd.nE"16X}:SZ{M.F\VD#SX`BIAGoX AE g$Y.Mxu|!IƒA1MmU6S[*e. &b\dd[uq 9d N\;]pГęv?Iu9P_{'wz>̎:ݟs%WKH4:P^MnZ-jf55>j?km0[U};̫B'Ivu^{B O>^X*J0V=z8MVjV#2v T^L=6Nyo Lw21%, D]xcdCr}&XTz;θF}ށtD-R/,N=g &"lCqBåt7^(6X^Cv^~Y-̸е]nԓG"x.hZAl|Ds)>T hryÄ\8j K~GZst/]'5[[2&*g5W}:STɃ/Y@)ܛlʣ{khFNQ[&Li 躩[Gm4!%\xЛGـYg,cOOt+nϵ^׸uA'UagR| ʣW=1{@͗tՃRJAA{4N FfzPnRsՃyKe zFgBWZ|c\Oz/ 5_e endstream endobj 1411 0 obj << /Length 1362 /Filter /FlateDecode >> stream xWK6,V|HnMSl}Ks-:V*KIgȡlIi/]ca7# VT"h"j jiO1'`0&V,i0UW1kzݮ!I_)#fH2T+#ɓ>VW{ (q{<AKGksӥ`Ŭ;MS>dC sw "iw0jc/gw:"`n׿}^P/R*_`2d]5l{rB7Z4vUՉT %z4Иɩ fv*2fD>N)Wg>i2e^4Μ'y38 om}0/ 7m&sSbzCx' I½^ endstream endobj 1414 0 obj << /Length 959 /Filter /FlateDecode >> stream xX]o6}ϯ 8~T,heA淶*l)v#M%efN5@!BG{s%T@ .<\ׅ[t<6:B c-*1bU-6A !e)eJr/u7Zު{5~sش%g/ 3(yҀ>+pF+ :?{=fsm9XԈxpWլ)?xhj5^@FNoJ`QKRg1 ^?QUV\IōJ:v6ޏ^s;J מF n&- mF 4x!#9Js鼨e(exR%x3i2 n j1h|kvLfڎ%W]'qع@p Foʞo0>q9.J@KXjL1)'3 5H3\$[fS|:3qYI-ŬfgDf7v$M0{ *W>9?0@jK=(8`'A7IFD'-L̢6 } brߴgII`dnJD4|(ʏK9dof ;p ‹?Jr endstream endobj 1418 0 obj << /Length 1007 /Filter /FlateDecode >> stream xWK6-4b9t"6F.IZڒAQy EҖby=}coф&%*8*Y|LW4ȥ $oWIP RdC-=ݔ{"圣"BE.P߬l6@znVz2Elϫ˃q$_4JTB).d.0ӭ ^ec1$A;+LqQ}4Js`eI@SqV$SI.+R>n61X9K@"Iܼjbl?xOshD1x>*蕝# ^)z5&\Aٲn>@ q5ҕ-vƀOiyy#oKV(~>pQxw#m#tN?"݂),#gwt\c` JƦRE)Q N& 1+"qYNұ! LpHdĀa6nJ)T>g g4zwsɡhd`S9m;gtҖǖOp|6eeM( kiڤyv2Q>DvP]ۛڮ>-_1?Ԏ` aissႣZsPNcLwI-#Lگu̙uqpyHt.S8km7-PTus)ٕ;}2,rUJs?)E `) *N9$T{ߚr=s> stream xWMo@WXP[~DJ ppmʱ#3YGv٪B9޼ya K O v'tXm7 ^:a0 _,O)0J Zdy5 \'u\BxR,2UmjLݕk]rY EjLi\qEd:k5abrMHER5_ a .rK u1\H]:\|)hj1Ż=iSזݶ޼m| PeNr&S10F5lnOusAiۜO,O (}9EݾVT%`.@e+LPV ̑Ūue֨Ұ[7nESj/}B>='$Q$ XOWٮmÙD^ɦ˺J= 33R(H,)<ⴙ4F,b<ŒDZ;w@X0hfU1nV[ˋgv\1 }5b&"gf>ڡ+:5tܳe,1Й7^ʵGn? Q~½oE'VڠT8[}J235 b4P]euh䗊XYc$:4%{#B̓g~QVRB:cjw)s*0>;Ȝ*'$6z")s/eջ(9u,Q0"uQ髲pUvl$Etyl/x—Z`oM|.7 endstream endobj 1426 0 obj << /Length 1012 /Filter /FlateDecode >> stream xXo6~_G 85`] 0H}PQaK,H٢L5PtxHa(QR,޶n~ N.t"+!"Qs-SU}xt89I9UxeW5ԭK423|\ybg\Pg_t>hD€U tRu=؇(%I;Q,.NLjK3Ȧݽ+fWpyL':Ŋ?&B^q j]yA1Fv3um?u:-2"BTH`leﭤ̦lm;y9C9eHH6WiqFяg@UjUUwA{L!vjn?LG!EBnO)*b1bo{8dL8 ec6"a U?+f=2BOrāGzmyԢ.-u)뎺^hm0(L¦h!)R #)zFY}i"GXR?K ec;/Y!}2G2^|AeG'ﴠ]Dk+.g7SxhH') A[t0]=˶ؑ] [g\u@D9vRA2蟂eMy}>*D6=OADi'YysM "!sal޿;4K3V3q%:Q&yiLoѳ>oTMa4۵me׷sۑ }Zt`]$W4~c)1tW9Ή٫V_KV:8)ecSS/OIyx[[w`=Akn `˅WՋrԑejFE endstream endobj 1430 0 obj << /Length 863 /Filter /FlateDecode >> stream xVn0+tT,QK%M^dȒAQ -9Jb H͛yHÏ8uENvUn0Cߋ|!%8!b݇ZmWBz>cM.pQZ||\sؙLGtc0t0i0 7_v|Zm` 67J6j05gP<]e^nL ECy[]tRǷi4)ZR~`bUTv+TB1M;h>aCj}^2QYYpbmqPСc/A Ճ؅")jx*4ԥXUKߪR=2%ji-RcD 9C5(jhpLv!=Djd8պ eseLle٩=C"j;i6 =)r=g>ʙ5HvTI f endstream endobj 1433 0 obj << /Length 1170 /Filter /FlateDecode >> stream xXMoFWHf?=$nܦhzIrŕ%W"YRԇ"H Egξvh`OIRLnVA՛[!QST<,m(fOQ̹o#æ׫0Oxx\G18IC/߯ $8i}Wр0o& ne H 7 A %0 j@psdЄՎX"A\8`. d1!RCDT&t!۪Vd}mtu)]\ilŶD:DD}"|([[0.Uy*": tQ64Q) Mm6d1= =E}yr¡xeXn1dk fFAaؗUkޙojrSsqP'6X ,:" ^m(3Ǜfo" Kz6+kv_2v˅=ڇF^d!_9Xhk @kLڄ}mND@Uڋ$?6:IqIGܷ]pz~bbs6nZHP H*ljZN+488ॽfs. pqe}Q9t"432qڝ)wzѻ:3=T[v>k]eFǎ½9g 8tH8fUOм_^>}/X˓HǬ`rxr %stޓ'6=Yiy G1RwhzJFBHSTDHa7}(ԇO*utr$S9 H+{kZε:5D>kLCY'?4dJ(1v#m5L}ӯ ^Tf84IruAu]on'է)R$U/d`Hȃ5g/SS!yU/{\s7.:Nͺv]ùM~0+W觮}BlyL=;zZx/QA"O4Hy endstream endobj 1437 0 obj << /Length 999 /Filter /FlateDecode >> stream xWn6+ X>D=16E):]=T v"刱4u]4Y/}2(gQ^p\ x3*ysT5U Voǫ`>cӥQC'T06Q]X$ASLroO@YbIbby4uϫ%'#&\"Jq)Oh:ҙX: wf Fop`SU, %ғaN1giw2ǘNɫU z|*vI$,-a'fg%DS1t1SWvһHxE#c߹]59Uַ:}+򥓮sO;IQ/+VrD(&j4VyNw~ ),,L0KH1fpIiY265h.*0yEde bL2Ղ{ 2DD,w0kDj[hln}Yi0!ˊ631΋,wgBCU34 lQwlܷ D:CV',?I5[ +n=> stream xX]o8}﯈K"5wF 兪;oC:vfQ߯ۃ<̀( PU5^{MQR/ppA@,x'rv6˧3d!Q uzv겜YN)Kgf9mc~Cu:,Uc^28{xylqp0FəLgtNB5tE kL\Bcm+ypUfO쏪[}SB# %b^Uӷfc5*F wNPI,kkWЮKӦ?d,a o2[:)10V:UjS]5;e‹{ӵcbu6A&c}s1a;pX+pez-՟Qe(-Gt0d9sSg%>2}$P=*.|Fw9(j9Rt_39^EadJs9 SgjOڭԽ}܁:xM0 y7F֪ h`&yzI?9Ø%l,Al\L| (UfX(A/""L4$s uK*UPJyJayR 5R;KDCYC:3nM]n}DFЇW`!q.#|zX&{u&E HŽʱGL|ӄX 8&>gZYbܘOX(j!#?S.wnJGB\?j]5Kl$M w}7b}BEbn7=nT>j]E| /|.g\ZyێjJ~[|?ZusSF%&mӦQwyDO?a?qM% endstream endobj 1444 0 obj << /Length 1030 /Filter /FlateDecode >> stream xWMo6W X~ ĩ M ؋^׻ɮZjmQ}7ofސcd,9.L 2Տ 20&?\ P+RdB-wtF4㜣u@i]M/9S+UTi$)*T?.XLn1nY`*QimxH&GJ\po=('oՁV8ZgZt{/J@QKbGû̙7j^ y?=,͠=%4ԛv>FI]mm0`3*s\mAZ]̤[Zrt? AmOz2Zu@b IcQ+6M@AE/,7`=$1]"_W}:>dj3@)X^ÃgR8&#V.krP+!N> #ॳ#yrA9 >@sr9c*3Ԧ>Eͥx]V[UT3ƪmq Q\xW"N):ȱT^*ci~aCk'WPf,,hn{^ K+ tֿ(ߺ ?s=jw]1u_ʬ;d8u 4%Eڛ!S/ȃOo9żdǒ2 fŚ^!}[[ԥc^} ) FcÏD"> stream xՙn[7 |[(R\lEY/(ZcP$C -q%/RL)S )J1d) EiF%'Fo($$ za JE.E#FݪcaQqTndCtRkoI&^YքL qLni"fE*pdɛ&YJ%!> stream xXKk@WzS ІBjrIsP`FwV+^W8gJ  根 &\}.Føcq>$kZ> @JޚT)+&zv 0tlkSdզ06<7-ǃ՘֦#Rb+ҍ i YR H/!2t1R77UNm$\aIIS)M0@L*ArMu$s/7]\RyfN?nc*!U_^=6RtW{whdj`z|>loTֺkV]N51۠(P7cr٢\ $h hJfkB#G~-|CI'><>L&fa]B4G**)AQ֯ϰ:Ě:Ϫ?ΪoTUi[*% C$yS{2>F;y1^uJm# Km|YdŵY&`'I661kstq/!Oִ6VKl57< (&N;Z})X) kRW0f>b—Jg-p}9u{$5ͪ?~& endstream endobj 1453 0 obj << /Length 979 /Filter /FlateDecode >> stream xWKFf6Rqb2=QkwqF!R2+Xe#A"QPTPՇU^<|] #2+q,]ѧݮ:R%)4.$)c<~H m=V?aH%Z&)Y^OZrj GNp a29|eY8ٕ(YVu-gU1Km:Iq$86rznFu{˶ I] 䅍}Q]GsLvl*et$rUH`PaP!l!J N.P:7^.!ERcNK$܏9üچv^~}(*F|A0*i|ͺf5j*׽{kV ԟIActnE\狾rE1-@1C, }qiK[}6KDw>g< 9:te%ē x¡@Eckbk*kkojd֗?2,)#{K.xxEC\i2VFG#}8dНoإ^bffw$OGgQ̝}Ⱥw0ڵf˪H"@;`QX{m`I{Jݨjٻm&̞]0;-(pH|8̰O4C_cg>GjM9Urb:QA䰃LqCz^cp̮ ='HBǰk-ȥ^0L8oyKqz =(VyoLrs#@)ͫCjsnQ2w]kW:]sp#Iw7 -m endstream endobj 1456 0 obj << /Length 995 /Filter /FlateDecode >> stream xWMo8W D\~TZ]^ F/Iʒmw(RЍ"H͛7C&hX4ǚd 6qW]Poa| % M7K6Vwe;.8xfBH>f5]ܘfL@:Ox>8Lb)Lg't5K(Z:T&1Qnǡ!bI2pνa}N3)ѽ72fLKpg\ewuJQOF3l,pfeCu.ڮi!{nHu7Nkʭ)_ e5s*. +Դ\eޞ 9>ӌKgns6b)j양+n۷r= H~ؙeUv̓ UUVo u]GfS!-K$ٚr<#]H]dѢ=:=Aaqب;9{YQX L9OoCVG^jVl)h 3Cv\561s혻|̠Mq!% k9g鳳. s!Y 5[\0(Rʰۛ~d>} ‚Jlfߚ`2=c41GT|mI 1ء3~<\!`^IplXr?R0;D02u>Թmͭ{Xݑ Hǩ:옜3f,O&/gx au`fA8bSGOW ( 0ptFH5=wJYď .ҧ՛T6p998Ś3+WRbEٳ\BC7VjIT:%XXr/'< 2܀ɸ:n$%mvnx8K0GM隆 8^5uN?h_@! endstream endobj 1460 0 obj << /Length 954 /Filter /FlateDecode >> stream xWn8+DI3hbHn.~d葢?|m9qP"txK?I$")wWнm׉_ܾB`>AㆱAP%b|Jڨ},',7Pnu],""a%2't%Nt%HȨ}gݛip0ɑ`匧_4*5vъ.{o(fK9&B;rlZ~$IU5GB@9?z=T*}̰Lu՘:ɴ?f& U zW])wown?GQ@:v\~q+BL".5|t>;[ fs^>"q\xe3g/\][FoϽ.~{_^u?͹'L↿O gZ_\֨ӣs2sJr}ԣZ5C[.dl5BSO f endstream endobj 1464 0 obj << /Length 1068 /Filter /FlateDecode >> stream xWMo8W؋D,?E^j( =+kKDͿߡH٢$Nb,g̼yHDF2g(g2/?٥`,߬/^"" zj]E_նY#7 hj^wFn2ukT 9 Ls$`H$?!lFeSnøUdUC$$v%Hm [8oFֹACةKnv1OkҮ.-&hʉ]H]x4LR_Z+#l;H7dWC7O\6y'5X ,:otz' qa_OCd`f/)tAn;xN#?B[oηa7Ӗ`q$H(Z]r:i5E:qj0uRr&E q]U$!gTk8A]擏G%=Y4.Wc!m?> stream xXn8+Tn3LS 5iPd:VaK C,tAAs}^EPHHH$Q>nB.Նk"A36s:N5IJ7IJ)I*74UըPIY,_9 0J.d:ZЕ8B@Е 11QKwq(Ep $eC/'د]2n?=PQ̝@]OSğO& E0ľ~r_QUA=u)^ҸUV0J6l`<xoB>]vި7ãZiCpDhfx |Dv<<3t*q`nPzD`,w QZ CMCMlGDQ\tщUd6f׷s3Ft%;Q bpm|7:_gO5Vr^fsmpoSύj^f.cM?(-Kk~,Mh endstream endobj 1472 0 obj << /Length 1041 /Filter /FlateDecode >> stream xڽVK8 Whc޶Cmb;IĨcj匱T=d9"<ڭ֝kۭrZ`R돫ɹ ~ܒ&#%RBDf4]gpՄwȂ!0 $;R;K uۍ|@Y E"BKWc/^pI R<rO $Dl(G{k;bY$ %='+9eHm& 9 )&#s)csP/X`۠d$BlD^PqDEQl6NB F&w D7[(Kb31k˦-)2kmo 76ZՆHJGѻLoꍩL3d$'oQqzyg26H=KVu}@SRX!RQ;Ur6^t{:ݍARl>c[Ͼ Xlh?է::1~<ӥyTƓW0:HTN:ۺq[Go`o.k0V2\v0$%VE2se[tT,6SNh{ Tr5[dO{4~(  endstream endobj 1476 0 obj << /Length 3156 /Filter /FlateDecode >> stream xڍ]ܶݿbߢneQ'MFkEĽ%+m);_{r8 !9%OtWVY\e=Ih=7J_aOySI\'=vqpCgT=LJpRqy~uwT*x7>#-Gxn PGyE77q͉Ǔm`[ӏ}*긮nTQt,2nC,/sod&IJ#{Z#;2/ACilt<7 mQGM/˝'gIH=4a5rp #\eʙ9<5|6=qO;]9:Y `}HI]cLGgiz@O+F8iQE-ޢM$ w2xZo< q1MC!!0LG#mu( Ҧ} G7\ a XDxqM;ٖ@prcgFُH3 /77O1r0" #68Z?6Cxp$>{_g׸uDZS(r]ߒ<SxobQx&_xRV*3@Z[֩NbU$ۄC e,J!e?)6}a3H| `r 7_xB<-n[Z]J@|E^*:/mړ8O%*]\]0}E`9G4nTR,YBCJ /o G ze -K* %$ͨ¹RZBU9_ND%tي"*WO)|Ǚ_5.d2wmS.'\Quɟw5-$9yۀDdƔ2+UJd8; %buӄ3MM` >/0pnYzl3%`Z8fh#2#\⯢[ g>E0v8_ %(͐V$^-wHꥊNu Nq4 fp4gAy@PMi1ۙ<犪UZA%{UVseo`vLm7C؜H#ѦKУh`HFfcxkŚ{TԀE꺠\;S;ROu#G3}xx}Ng_!ʵp@qyOoז[0 q8GFz00KÞ7EɅ5Bai"i{>E:X =I< zoT6pqb5+Y6uӧ5@P"^ W?=vvNKro rZ WmDo+ D endstream endobj 1479 0 obj << /Length 3227 /Filter /FlateDecode >> stream xڍ˒۸K8U#o9qjmo'8$><|}Ю-4Fo*dMv()W>A w~*u;X[ë$7^!L~ %Oo>|IfBσf <0KS{AܘѴͰ7AO-Eq J0?r85 "cH]ЗA4I\\P[f*.ZBVj2':k5Wh^#qW6' Ü2r>gkd/@[ȝapJ/O>ڕ?%ZGh/zAKg4JBwj tɥ @6sJ=[_ u,5OOYgkwkDla륁w/q#(H+ WR bѫ[eQ  b~C6WژK< 2g erl0X|&?, 0.ıo+` oXnuu-uw{[JYI >Bo_Ѝy ek$5]7"RyW !hS'q`Mɖݥ[X^S ]kP84 ]?aLvù@)jaWEB~П"ۡD=3 !d 6 lYʁ#\|85 ̲I%%KU^ o3m] ł9[{s:lEɇ&RwI:s7/llyD4x(ڔdղwkS`sa0ڙ?$$+8G;u9aJ0ΖjT> stream xڍْ}b*/˩QxMrv<`(HB-gJIJ@Jb%wUzWٮΪ{t,'60`>iDب1lje:5ddHF 38}zdEȣ膶faCLmZʤ (oxEy3y ܊,jBx$fa(DNu>}(8^MV?ý3d~ūV[8Fs:VtN#^:\4@wsAd{Q ,Sf8 2wSOw[£z0O(0p /a@7-泈)Yޠ0+9#1a)_.`%LB+r/tX`,}k:C''{  ,b ^EN^K?e,3YyOnK@C$#ojd,fqCsawx4:+Mi62iS\gFWч2έ ^>Ds'-^';BE>?*#3F C#Y Z e6jK.#߁(@Fkn5DUDڐ9}"Qw>8)تKC k-68(CToDe=YWg)ѳ2@o5 h9&zݥqogcey DD*xfg]Q +!0v!8ɦxF+ƪihW'TX>[¥'.2DkK.a"H˽?.@tr]0ƴxِx oR?Ln"/'bKԙ;]p] 8A ]-POrDpÊ:CGǑ 4()u ~9&bg/ǡv d(2}25XDEV6r`GNW6$rrcX]ZV'[8`d`jn܄ .5̤}hV{bcfJk9ebI Sه2_ &0Vn Y5'mSL ?y y+H( T|"abƃAd{u=: bpi^;AyV(@\ي-ǔ܊F/w#YJ,ԎU!M.6P|N< .P2z6%"Gs+Qu)ݿ*1_|Ȥ^r$ȒLP<<2IM"#̵$7oGX4kD^p .'X*$2N:n{+oeCւ9 a sU ZtT uMw}./GWl8z.oW'WDÈU%+5 /< L/GqJi8YH L|*+L(2yq"0 <_l@E6VkB/2 `5ܺ5ǀN\֩:h@]'XM["n^bgU%BsF0)`oS nevd&+%xb잤ẹ|WdgKgK* 7q__u#WM "IsKM XִS 3P!^(>dDPʯ&n>w8 Eܖi2@9Gߏ DT7soYf̨`\)K/NyCB*Qb endstream endobj 1487 0 obj << /Length 3197 /Filter /FlateDecode >> stream xZK50ѳ%9'Lj °ׇ ΁#{:)Gs 4Y$Ud)nCSMJT{~߿d&UCڴޝbV'n}$zݾ(䛯bL׃ԟ構40:Mrw|w@U^C, E~* XE|[A4+\=}c#rMDetV I2_ Vn-5 d 8G]uo氣cbP [V|Ơ38>@%F0B͗ gFLwWB|QF\`8:r+3†e. pa_}V4b/2 ݩ48PpH x  2~Fo$8BHؗu0tφt#]ؾ8wGY ylB@S)M4Dn?FYF b8Ty8, x!!r'nc+rє}U!#ARJrH>~$X)@0ؚ;uR):޻(T[ C6=T>64խR.`q+8ϽժWOvppO"(C kS'&ւǐ8"x9t״Iuh;NMm7r"PKHVYoe;pI&8:[#WD^gy@VL`F|?,1yEwhE 5SCieL_:D`Pv2J%~G܍aMb-Ɔ+D<Me-@̠qiJ>kiwZ!8Nv:f1`I\!@gC`Q%+t },<ؠUlZP /trTeOa|e-o -7%0?q  Um4 A n>/-S<?5Zʶ8vQn~ m NYdžԐA2&c/QΜ.B*wDZtC=r7% )]m`Gw6PA H?Bl; n8Y]ᢵyUvmߎnE%˱%QrJ43[ôJ/e"ɢN806Ub+sCME^m节+ۄBN2H_{K*U\(v`^Kj+@UTԤ zx]o}N;21W\ xT&ld{nbL,8z()cօEdH8X@8Ѧ:$߭'=ۗV?@E[\)׾ Ǯc3I Nyዘ˦M=BA9LX %|%Rb3w2PQogɅ/jFVi2(˶gqf@$\/|5*gOWtU:J5~K|@ \eϭLM2~Cz<ؔg^ q ΀2&@Igqֺ9.0?c'+w* _1_ QEߐ pϻY,zgIf]do%3A  8eC6Jo Rr7C %(IG L u  $ G1/RqaEǮI; endstream endobj 1491 0 obj << /Length 3307 /Filter /FlateDecode >> stream xڍZYo~_!V o8O$6ÖqZdSY9ͯOU}0yzo. 1{[=Uw ].!m>?$I߽?;44=7`iX1_iPgY{C1ỷ1RQ[qC((\[v=\]z=`02^hƵ/Yv Wʎ?fx=d`];am5#& >Qe(vβqCAMc=5@(`|'4 !L{K,(DTaLuz`W]ZΦ[W|I9V' 3`ů0*Q4\.MMɑ$0pޚSހp|@Sh(-v;g;j7iTl|[(i+`W. ʩ09v+J3cO~( p-VryлTH:Lsfg "sH ?L`Е9#I94!vޅrHwqs4zVĞa?|%Y&Ur,J#RPS^1 *iS4g)؊XxYq_ö(iv!>j Pzy Edf;G]G/a:>n@{藳0V]W)* dH<*c~d7;8y#K?)6Q~T?RoD3}f}oxQ2*ub&2ZxNb_|q۶`Jq-ykL8_y-bXaCSk  i׀Z*m[D?xqwe ]sDH>CDb.ϾUAeVDMPk_ Ђ *xzsLz䒬KÅϦ>tzu$_ɦ^`o5nI2U%{ i󎬬!*mmԜWU嘧qkrd7$| `#\[D8ujuv8 s !CO gGA^F4#]iJ=v+2;Z;PF҂ϷdbJ57֜-?bekž҈@S!){Q {g@H# Jo,vINRU1iRvJ1V[n{O>Y.aY20T\Hp3ԈrBOs%/+޷bvKn/~/V|iKA{u*iFd%K$Fg% ˮѳѯPDh̎PIx\˺;,ih!1 Wn5V*+sMn;jE-Ŕ|YUC0.Q:mR?HPZ$ɛzeOW'誹3շz{s5:/hѦG 3m>^}e2]k;$Y% )O#[hl_7dϱg$/fȑUu ύ#a"[XxNoV%H8_by9]'hy"33A$!7%__]eF?^yI2Nq'6#uR.l(vui,JLڦˋ\azH-o7?ڣYz(@ Z A)/I ESԱi/(vGzk^wf\Q6+Uz=#pC{o FGIxT!t72o'B#_- endstream endobj 1496 0 obj << /Length 2975 /Filter /FlateDecode >> stream xڍَ}b' X)l>Mu0CCi"&5%Nb,0쪮Ҫ &hbCw}}O?(.ӇT?dtJz:>{xlwy1Ey?Of0Nێ ԡ6zSPW,~=yʲʑ+>J~G:lg;|;fjs3g&3lᝳ8xbW{7gIYDbF;պp^B?gKJsD=8k6o6p :qϽ-p;QzbJeap'On<4VmKp|P&o{'TA|;۲e{{mG:trd&F!;-'G˾:D$WO,HT/FgvVfFN{#p4)gM3= ]= x m&nSJɸW&K|b_ 'aOfrRW8u ;>s1 fpd(AJL1'g?p`5h0{{yY7;˭ #KVḛ&xx¿/j63W<~ RNwz~&[l{o2Ŋ!2 ,B+>hfހoK<rgN)^Tbf:r4zF ؐ Z] FZ0pAJq-CV0ΛOE 1,FCdGv*70/x![D(0g",:_9[cC D,QAxSWQDм?1B>!$:[1.C*gWU0s%GA( ߧJxA8&j %[Ъ]!6U,ɢl">A\JDz eل8NX?Zud5 JpN3C^wo m^UMA3(+Hsƫ{ʕJLև(TLqF UrGORt?VV"$ 7 jR;X)iLI\8rUmxLaY3%*ԭD6`eoqƒ)5֘SމW#D)0~]3g%ʻ;PZ+ YxsPɓ$QTءGv )='-bb VF4dt a#.UJ>K#Ew#׼2 NܞFYRIP8u|W;'Jۧ9 Eu e"bN0`lkeA7^kH)90Qλ+M-"LTc"ܓ'% lXُUrSdW/,.KusʼhC=H1pY6~oE@ P!(u{'FzҶd^%/ &*V1ĈB {h>TMb6@ıPr}w@I0 I=GBHZuũx\c11r˸՚@yʼnW­U%bHj}c=_DrDrz!-Kia)/uN7{-ܴϖtmXs@ӗzFm2I|940OkdFkY8 bCٌ{i{:GI|}7j5d>;]Ԋa"c0hed|D xlXtipfFa 8E0@R!Ȣ1+ d5B.dfZu; 谽Qp+0ѭZyK9ARMJ!fЗQjPec #qGY"B0̡$^Jk|ۼu`&'Yb_ɑrƃV)DIZwNIC=vaw1`Cݚ 5c|=Vsޗ='oi11]H9~CViN֙.2!_$E qWu b_mZw I=64'3|A;:*.p,r2ӄ\5F(Nąb*bUBA/(lrPadj9oG|Ey<VyKy Ip?vNɷQ.Bq%vMǿز.G{puin@y{ _Y endstream endobj 1500 0 obj << /Length 3371 /Filter /FlateDecode >> stream xڍr>_%tbndwjsHer%HB H [2F4 e7)e7U~S튇]Qw)A|x 7Dz҇:cLprwnSEO?3N7 4=5vtY]I]o~x *Tܽ#<->SfMطz\nv'>Hd_;8s7~1{{ÑqxCn6Y[^G3LmѶ['{" Wi?48s`3Mv_[x.ޓMCK,w3DKIo aG׷tUAApf8G'BDB;F"p%!Q˾Y pZ(= fHk3HHn=fH'W{&Ɲ~:`+텑U9ePKj=aԈ DXt=(y|,F1z/_R&W4Vo!lٹFM9ʐNm"nS@ fq'p#dpk w%Њ}_Hg$]83Ƃ-Cz&t3y^v*QM6nڝ̊Zwy[b.X}fNXΑ`"8+;@EFEpsZ7a +|omN~*%vW"sa uPt {V4Q= qu?2d dnpm<ΈE։.ۑf%P2I >ٿe*Bd v<"GWPgO@s߈Vi4!BlhWQv֒J,4<߾׳^D$~Hl1_v=G#4xmd0g﯈ʥWw^o׃mu* --4 )f JPzFgl6)!e7~=OA y60&mSNbZFG1#'k0Cqv9h7Lc,2&VC߮VwPJ 'lkH6a= ."#8۫gcɼ"yQ}?HN;8PZ3ʑ0 wm.9Y'iIBu2grr?XjgrbeFh)V4m#L.DfV  ]fq-onQIet\dip"a!j:eU$M!ұe q/,_Q\@Zu>i s)4+_1/a]m pr̍[yV"Ôb.j>,iI^^/,)dZMsJb,P%g('p djc>bBg QW#/q//xL)#PQ<#򲮆f5EG#su FGp.Txb3d5&f.poG ߐZaǼ\0\r`R@߀V=R`WCVEQ!-,G^kF\Ȥg Wwq ݰDͽBH'ߥoG;0\Zn.zs V82/vu1R6#-ca~j~!OXHr2Q~ѫ H|_1l'%'mKϰBD0/aH aryzEzw {boyw7МU:g=]$#J9?f@ś7#ѓf)7N 6$@gGtf)Ϡx#hy㘋^ !zLuƚ3lmlፐ㞷 0͹?+;Ў^;#oŮ9.% ՋsLMTy] tVc9RQy0DORVrPF M8g_hOP>SrOb*v!+ھ*/ 4> stream xڍZKsFWr T%)ܛ(dY%16{APDhI $\%N4zf{5f知YWYw3ƶg2x|WK^:?.Kl-.~~d^Y0 hy˺l`mU*ʺ+3ogw7 8(a^%8Gr5#=> y[=:Umos{Ni VF?AJRJyTpwECM=Ľ2-sjdy\r}le%<^qZE)Ԭ/tV~R4P0-[5uRڰùW71?C$i]g^[=oX (r~˙xZ`Q9"n߄E leot`xu~yzAv9P5XCŎ )$ՙU_״ v/ވ MhOᣜ~fF7Y˝_BY ~4?+Hɝk3YGCWeӤ86mmFjjԫgoͮ}3.X4lIH=\7KZv+ʺEMыƿljC~ ȤKt$O3g^a®>吴%H=,Ոdleav&Rj~8qF<ָ,~&WQ4!_D$4J!P $5*DLuq̞/'JOMњw:iNLtl[rT=底Hߪ-9JinBβdв&†zwKwYڐ:َ Z4HB6֦9,svp};$xD~/8$;$RiGLmr7f´BJ@ۊ_(XLwADIGn֏RLkfG24Pc> D} Qh7/b'%([%pDiaPib- seזB l6C ^24'aY7d@\ַ9|;Kyۛ E+ oI3eW SCJ6tujm-Ioc@ `]No يT~ؐWm-rTI4ŕԦ<?r/@A& #-z[ d;#FK8B_)'ID欌L'nweIqq,{RZ5[&i?D]q`؃Fڭ 101W$nf Cvc />;>vL/xD8$M): D ѓU[i.ѦEk,J\Z "v`Ktj06\#Q+w6E^n\ DxE(ˡg):,5\qC0?qQC)P&wӹNLNJT :'=ڥ %cj@[~|Y(C%px6@1&Nm&ic:B~'. {q\ɇ<@0"F \mw3єKoL"sXp |oڈe6'76KO` 'ǒ hk/X1!KCc]#y$c#q2Fzj}+Zç9Ir+PDZ k R41fj\+ 3M3񐽆h\ nrrR:QW:: ptBA' F3U-@XLoG(֙ԙLO,H=4E^ ~h}N9ܧ._ EaSr)dƺ,r ?hqw8W Se4ǥr^2MEG U/?^nhwl5Tm'KۘqGֶ]m,kTʝzw^mb}Sa֜qDiP=Mӑ#: 4R6kƄEr:P்M̵"Ɖ<ݛhjҊ&zuU5`h%TN'XiJ CIžٮJ%6_½0-4?A4܅D6aB\ƿirǚGm '(]79%K/v<ȣG?h]?>^//T>xxd~8"I7 %ypϠ"GZ0Bpww7M}in2כ{H'iA ~[F;' endstream endobj 1509 0 obj << /Length 2820 /Filter /FlateDecode >> stream xڵY[oH~?"'#%p;DIC!hghF '~YVꪯƺjßuճz};[7Kn@&yv{\YmsXWM]b}c߷n쾡uu81χ xPʣ[+ X^ Z\훷 :z-\8fN035<|M^2v0=EB[}c,|OdA 3ػHfosrLcY Cfrܗeٰw0.^5gT5<_F CoCnDi>=ZAF&;L/H# 3cQnNoȓG=(FyxO|PSpH@Dah9|ggEɞkݸm$b&֍e$f"11i8(絮Ne'{2ܳCP$ *+}7CgDk9)_Sfw\ӎSyq0|P{5s+?xS/ND*ȯ 0\gk/Sa!3;PiC\{~=Pv~3=Z Hi28G O0gYց')(H̥Yp4<6CiM!iOeNU%Fď6b_tNPt@Ngzx[74!+,Yg(-T{z?nNq㐭C*g™m4j6pAϚ.WM.\)/MA!rm۰sU4B1Cf~I{r.q8?@:XXUtϓ45M7O)0"N*q پ*B8ƉǛ= .ڦW߁Q^xojՐG}K>G׈—X [}EII + mpTK:'EJY0W+xvs}pdxӚ/O͗Nl)9 {WˡS̙l]SE)XΠrf[ﷷ|Of&zq{ikY۷>Zu2|F "{-B"6g]|8H| @T~CZa_Xy'lV!&m7W^Nu&<{KƝIvzN2%JE:ejW\l9N뻒ȇ'e^,zl|YS5GGSaapHkSnsC'5p endstream endobj 1516 0 obj << /Length 1323 /Filter /FlateDecode >> stream xڕVmo8 _Kv,[~bb-z)-CVߏy9b")>_&!$&YyM*\99j%I&, M˱E5ۻh+sq~\p^B5q6,i K 0 ??>/%Q$ԯw3Ы -n,ڊ[q$Q#灢썖v9r<شp@JI \?#*/Â=M-H#_ {)3-Y #K'd `p:6xdyȬUroFd&6x8Y|nMu6u'@0gea+IH-x~ 4Xj_. NtՈ`g,^s j'Mf#Wpkg|.AD%B -Z`$ J{KDB@ zYn-Ermo,y6xD͟yHi h|gHuhp!%ZX.$#y"x0;w_7B F}@~D øpnߐu (E:PF7hFC8l7 } ZڪE}9YuUV%RxcفtxE|dw^S+)WF&N{}2[ ?`VbB+u(*C|:э4#Ri7I4O"V?І5j-$y8Ep~;uv#OyАd+hbŎqTVr/ q\A\njڵpЗQ.E-d~2h`wpнp%%paN"+%gXVOZFԹ )XS) L;h\zR,elH@ ftԒD$ 靝.uo0NG:ͩC#I endstream endobj 1637 0 obj << /Length 5229 /Filter /FlateDecode >> stream x][۶~s k9qm}H ZJZ;1016n+7r>`*}VYRgͣt7o}s%zɻG߼(3&Mڨwi7n~ӹJR3!{gJ*rm~ ]&}ή"}QT3U=G%J6nhA`rhA W$` rU-|ivoZn7ދF)~oSAӏ\3M.C;MPi?}3AL8*%9GH8g Z%M'mʼJR]LCMA'aٴ7@KW)R2dd#<ǽĶk~dvi~>TPLN1N3Ew":`Rrm[f~XŐeIVSs"|jclonc0nc/1Ƞ9uKVEF68*aSґ dTƀ$z"PlQ5I]e<i?>}qQ緫6E'O\4oF+^L `_$:`:PR?MzpUxxA#_$3ȆxXDPf+ќ`#f!Rٟ1=of2kH/dÞ2|mW&0`"+;՜ c@Z +AH 2H8̊z-k6hi`ʒE" H#-MEPl)Dgpƀ%noG>H/d;Z09結q a%qdd|c_sȆeei]+&0UR'a5%E%l26֯_J3\xh19a_$3Ȇx>R:lmf he_pTΑz48M+EB+lh55DM}gӛ3+3n ӳ9_ћ3TɵgoJ`B>}~ ,-BVQN@F+^?LIC.`_$cLSU GH릜V9hu)SE u?k=2` UrWJR5}K!CjȔC0>LD?69WF ]~Z^#NJ%mJ:]٩'Vi \fyw?+TlkDU~:CA?2@^gE9vE@9 M^e^.V^;fg/Mr3E 8R0/a0Fe Kn|ӂ3ᚼFKwK\E "|Vd}A6"*`.-:JF"JןܿꯋxZK֊\H4BN2ؾ qT48|h )P堛v ieUN}0yz-2@K>dȶlx+ vӾ^60 .Ғˆ5^0-#D0 2FUf!yn׷p`v̻D3 Hd) EYMW =YR Aq)vE.lحύݏCګ,M3̰؅cq дӴ"W$2֢ٟ(ӺByg~&6>{4x䊄x7gC~Y\SH9}yhBW{[:2ñVxd/oA?\ن" B?g; u~ZVoayL%mjǿO~8@T<|8'6ù29r0 g_(+*W:]|^ y&: pu:Γٺ$L>G&uA:֕!ܺ$L>G&uA:ΕuKDAy<6y$ XW Tr0YC<8WF ]22X#y]lser,8#y]lse&:YE))rx*@?U4<*&Χ+l0/w9߿O>}# 2)߬oUM3[iC>"@7 )أg:l;rhwo{;̕U@z/;rDtaveF1Xװ˶q/½ݾk_,kvgFeS7NL{Jӈz>%2p1HOYSb_rpxtN ۀ`ŔOڤV\XIKdPI#nz9T5l7 $4<2NUzXW ]wON >s^Ǯ.MKiW\"F @seC/o^ F\wlwnsoU]cӻ'9tQA=1 _$amsR40 Tv=Y^ЧvwK$ q1V2@*d@TQ !;f[E+j~尳#yfOozZ=Ò^=zd*z̡wi77lIDyūՁID SG gpƫn6wՄN̙%CYĢطg$0#_$3Ȏ}36GXi=g.^- # D En^?10h̘wl]@ǫѐwD"!)(3)QxG*ol؅6^4̟.I _$ap`&r wy%gOODeoV&QE٩'tg\۬o f"|Yx|́H/dK~DBM??6ESw2@`@`_:JW4K`=NwE,^L .`_$z`*Dvw"=`Zwlnb7@sˆ"WdK.`mG\U ЪTE ٩~mڹk(^oΜ|[`)^5 !' qfFHfG47*XbW7@t :d *:pP36<~Jd6l 1-E iCC9/Z 4/̠tMfAJ*Y֦6MgZZ-V Er0Mu;ߴM ψ?`2JJ%": %2pHQ®D5 VM 楤t@@?SO&k:C M{8WE>vpGSoRڨ͍inWپ)8"E/qͅ \| mfVrE تBCjښ՗2"_?&+ӑ#XG2l짿f%Ya;<]̢zd(R`'&-Ŗtl2m=ߢxtw`_$"b(VMy l_0{0" ok/]0Nn+ zOPpK$ xax00?0/aV6$+tK0lw>=uMZyvio$N=j Twx@>O`W$%:ѥ͇_I$1QE3y5J`c\sF  %Lw`}(C;79%Ѐ꒚.m vZJQpDJ flXn};y9U$3P\ܢZAȃVTaOEZaG&V+C#ޅA? }?嗋m6RӪﺦ/+of"3 DV |b;_dA.B9O$f2;6Hh `&Y(D 9߭aWH]ȣ3RdHS`'8_[~j?H d('I1#ndӄI%!GBb``C[[novPIBwPhBT{q -t endstream endobj 1446 0 obj << /Type /ObjStm /N 100 /First 983 /Length 2080 /Filter /FlateDecode >> stream xZQo~(C ^) !IAҜ.Z o(9{2x~pV(k-rc-ٮHdFÐ,.x-D F d=t0 +j02YYp-ҍŻ*9ljA BV\l@լfODBɵ HpPYmXUp5sN0u@!f_dMs(:E@OA߻Y=AŁ(mptX]Z T鏏DVՇq_;]a-Q 6[ (!=85[@ݔi9!5ejZ8|QI fhYCW,3q]GY펒nxHy\k50bIĆ"rb}@AQ B\6IU%QVӅ*2d1^Y;$()=(݁Eu̾栜2JALvˈ= (="XI0vmװ2 >7G^5JW5-)雇)qHl+׳gV?X_OEzD]~xswcMx,Tßyٙdpg#ζ8ȰvW?^m޽\߄a|_}>[˛k5?[X_o>][_oϸO~%6[Dp2zWmmEE7q"4:EheLSyP=rX$8͈NjПDǻ]rL'Ӥ?AM`=Lw&H9t[nKM;_>N3-)~lht}|C^\=*?=xE/zzZ/fJY{ўҋf{џ֋N1ԋ><ʋhG,qYl/[V-s1S/>[_^6J;Zٞ o3IЇG>Z8G;2>/{LX8y|> stream x]oܸ6P}-8$>lJz]'ߡD#-g"9 #Όp8R,JUjUw?}<Kx=~(D5y#ή?`Q˳,\gZUANsK^] YdVЙҥY0B1YYS1f~zsw`IDQCL4#tȑs6%bN^?> XM?G|oQJw@v?2%b~S>q3za.η0]UnjNNw2T+%lK #mJ4n~m?.'Ӿ-WmV4#/,'F\RNFvDj\lj,:q/çߗKXl7T_ٟ!7I~A8lM/|ݐ]>6%Tw@MY<x#P#cARL6s|E]X|dE.O}Ҁ`!LK$%! ";9R`? )%=Ց-ZC)cAO'"  xK ;7eǻ`P-& cPږx!c=ǫJ24x"@&rl5e_b$n4C4LU #/e&s]SK0IVxCbHA5( xߘD1P y?Oq:s:ؑ,`[bh6쁴Qԅgc C&S;pB@S )ńdK E͆"y5M\F9p$J>pcK7^nWJ Ȕ60$\2T>-v-3p`QBȁB{qV䕬ؖ3SWVZ l̫6&XTc@::& Sb((vbvho(N̕YE5=xt F 6UKY>VHIwk:mѪ.b^; O@ "w-1|b4;>UfVVw޹$7]nt*tx4UJ*Ȗ0UJsyWo_ǯW=.97Fx27ƦİQX iVs0)\{<l:`jVȖZ1֔E`S.of1 }:XؿeA C,F#떺ߵ„zU䷃*/[%7Acd };!WMW}t'te {<AJq$LM.-a[=4y"AB$41&`ǟ0eU]U }<I`>Ҩtxޔ L اyT?t:TD (bO'" LoK]C`Lݱ{<IER=v SJ{4\._&4y"2 B}W2nomdمjޣ ™N/& ɂl! ّ oQSG`c8ɘƞy/^ODF9Ě/vE8ؖ0CYbۛho̬9KNYc>5a[;e@]̍W\D)PGt!$u3=u4Aݩ"J\9.nu=v>h#hs0Vj4{ ~2\o/  W W'iD@Ĭ:8'V UcT u"-@NDUG*CX`M+9a fU6,7@UϢ^}`nC*駄Q(i<AQ1eٽQ (i<RAkXɩ(_) endstream endobj 1641 0 obj << /Type /ObjStm /N 100 /First 1006 /Length 2295 /Filter /FlateDecode >> stream xڵ[W_8dUE;rI!"/ #n 35HmXEX3s )dr2#R U%v3jfph9!x?R-ytS*L~UhFˍWAJ Fv78վh97 jPUR4%x&Pj( !b*"ݞuDeS(^/jQsfq㙄ZxrjTтC I)bV0% Tͪ /8p- ̵zz/!e?b0:q , h, Ҳ#7 RYM,JDAKJPdV :b A1 x<ӠL- >8h$,׬3YƦ#RrgZnUBGF7g6ה}\ѠxHbS@S%iwǻ菤B? ڀ?殑g%~.(/r`603fgilsٴ1ERчWNp?__?9 O/'tYE-6bj&.zN/uo·>3=6h5fSO46ipV|gN^JɱuJMmST81v8=d dKgqR-#&>'I)s>c G[T64}k- ';gS Iv)9I眮|{uTH~nRȺnpګؖϙYlAkSp-.b)y=>IlvnwuN=2Ilvs:gBN*Cy 9$%dZSm>Mt7w8Epm=P>eQ dwK2zPmʙ b^ۜzg)NJݯM) H৔R'6%$JyYno$$yX[+gC9Q;ĭB[7@$Ά<ΉVl>$r*b) Xo 47QΌ+JiXN u+'Fm|,gA(ϪXN`Jޕ+lՃdgF,2;$r&Kɕ-ķ9ug툥,ǩBlۡ~{[ -W[A)%WN5yCM䂴d,XZ"r%[E*j\nRm{83/W~[^Nq;t+8eB!zs|ġZB[W\}Dż*QF\Ie5)Ȼzl%!uY5 yFrZ]BޥKK-do'ڈ/۝ؐe^J=ȹ,#Ȫ6=Wh.R1c`BL0Fwrq. q;%d^u4qs ٜC8#i[DJP&\N&^C y kIĈZd:m,%絝L D)N#vۇ7O/ r;bKϟ=§pzM8%|ch~g<>|[l[4<q<+g{׏?~nD*6?F#_?.pXQ rQ/F?US7 'NNNʎ̎̎̎̎̎̎̎,,,,,,,,,,9rs͑#7Gn9rwݑ#wG;rw~A֔nō!n GΎ9;rvّ#gGΎ&SC> stream xڍT]6,!"CIǀ ݍt7 1HH74HRJ H Jt|>}k֚k9{ku!tC$Jڊ@!0!Er@=H7pPQhNBi#PI$BB;"=%`@[tzr(!=N(2? p+('+zE0DBPvB%}}}^HOGYn>/0zA=}_t? r^xC$ y#C -;폳>_+W"`0tu08 U@`7_``{ 0xQ^^pįAwYA uCyڟ2 A_ɺ!}0Wnpo_.h_ qFWtE@0(0 ң /dd{"L u8pRl߁_1&a8w1$;WU5<$nG6iaҥ\3ܢmc2/5sO;u,s2f:Y (z78PY[[lVa]{C)z9c n&B?Z#vgd"oa|Ku{ływF\S}L[#),x?jh+/!:L&QH#{t%#cP5nnO³vX1@k`Fԙ~Kn݂?E''Vq[a<|2z+**ˎJ{Qgg1/j[di2c'a*kiFov7A%lgS>lQwOqIK6$3? p*%j=ʷ8dxr,q:i)tz;:!.Ӷ`u1wρ/1Ԡf(ehoP|i,sֱ؏墯ܓ-(ܟv)2H Pb lMY0#|!׻s7@U>3=5jQhzŅLnU`k|&wzx^5$ 4aA/r/nsU xH9Qo?'QNW]mzۄ|Vw1~(EOR(%P]^S;q1 ه9B_Z1ļ澾UQ2LI_`,do|( wN4(|9/ 3e8YM} 46ly-.i~!zd9z;eMFمށJwͷ?(jÕ៞k*r=M窬/t!:=R`Z!Lwrl>so/g-|s/1BK@ithVJoSMH7Ay(~ uGNwF',iD4o$aFxcݱi 9U9|U͏g1Gpi%xi9ۙ,>KסVQlr txx2o)o퓂weh0ovۥ]3DhN,u6jHkn/-QCؘ[73'LXRK/4;$ĈIJaQl9Z_:fB8:`EkY[qXswB2$O$^>J~)ǟ,o7ט3ϟ g8Iۛ>- Mʅ=@O\deC#",[3vaa][G䟦/\;•eMYf-Vzff_Du"ZF g_+,̊wK%;nTy,⛽GFDu;O B`'/tS^ zT}]:zMFݲ'q8 07FcO=m;\<.|Yp!q̒;KS̔AI{8O$F+Nj UoNG EQ8~=Nqe0uFȄFgh,@6wq=!D'ן2.MU[ʩ!ڨ2wФ'Bjy-7UE&#sg[Ijs5lΜ%Ez=E}~6@%'7S֦[fȩsuo; ;< }g Fuis.C0gQmM$X*hΈ4e}3²fՒ mA/nw߬ʝKb6/sq={{#YVD^F㆏a3҄e*@MnO,j^xM 2=0Vͯ=^t>?j=ªX[Ȱ=a,\φN]&?s LGaCE[ M̌7aB7`:e͸hzܷu9l$&z9DZ@d35tx(d!Ηdv,4&N/S$?幯p"XfȦxe M<`a嗏 atjiH(>(lFkq?~"PBz"|| .?h(%i{HA#\`^dӺoﶄJcg-H&쌠 'K8B \yx^;OŽw|N=r^4{$| f✑݉A|uA1ݑ*^VˆXgn-xa%PK&M.b54sg\#,6 GN>[m f)r CcgTcɵWzR"M296QvIx%m}Gl|<{ɏx>rMX IɘeCvVOr`&"{"NQUW Q>-Yf-*ioc3&#y~4TJQfQZˉH-G;,B'$S2ᬚ'mQJAB+3RѶvNߎw^ߢyj9є["h.r?1ڡ$&{(hUvvWʁs~{e|vj"^fxYJk&7Ƥ͟;t2ꓖ4\P Zztzl@1Ufku̪}b r.rQ:98weME2D.rJwڷ >$ \:؆;v,NԴlFʻ בJёuꄁu9vLY<&;⩅*F tsZNyRof_qRg r0UeQstIhR1by {ZF -s^m HSx([DMɆҖG;K)7#>)K 2'ľ:/q.U%MZ?H"Oˉ ײybLx]CR|94+jd*/NƅzEO|0E1} ]iR4d5S/=EA|AxZ r)̇R2) n@gZã]\a4KB\;~X!Zx1s[-NnI})XL-l=|V<6uWOHښhCjXmӾ&(.r;~1w, p\Ȭy!\]z}~P@Y YpCEݗޘq ݫ0g>Xa\Gj?:IcJk7 &9= D[$z-SFâh0 0.8\LO bn&WVGX8q@%NV&O !}5MD/Ɨ(ťdw{?6-~U. W9h\Wzb9]is4Bq++t{khgFO޲N5YIM<=)\bAO?_\ZǙPj]4r1(ɣa pagG\n=,+Z{=l΀_Cvc&xמpRNK'=N{@noz* /\yIk٪[:XY>%e1.LU# ybAlֻR\CT^*٣q+Q~eTe/OHLTvf28_;bk-|R3IuDVK<>h*zqgSq21ب&jϕÉXuQCo#K9R*YbI7UW0H*jTw '߇3Fe`!Je0P1p2~Jno+0}w\\84|\Ω>-'>\+לu@a61&iRBa&]N4zӺC3Ͻ5B*Ean -b#69w4*)Jœ9={TQ$Uשm`@ͩC}h+eR&E .:*BF%X.eRbeZ :!ip첊ܢm5& 7UdLk%e:j7;mǐ?SSVE<\;) why2džIF%jiϒQdKaqhOo:̭f\*%>o8j o7|0$!fEW 뎽I/OTQdj&,ZDm=Ǘ->jf8`s/ 5ZX". T}>`X]zMUk}vX[[&Uwt]wS-<\"`_y KjnPNJN~,HA"*[<^jsД+ږVm-7i*_5[bCre4rOW$_1[' 2Wګ5X5]@u^ÖĆ5-9ҳo%wM/,!mK۬5ĬUzvd}M Hz1&j"I)-@^Dűbkq}A!\dG͕poV7l5WSgF̂ߝ H~,>}ut/]i2-$u6ozdYσoԤQ L?ckeỀ@*8OGxy<+z(%FS[(Luc`oZ=3z3*C;Qv;|#@{w5']oMfEM2n(HQ3 զ3a^g5vQ C ,,Gfu)(E%}w`^ !=uSN n Kr}ZV%2ktW{!PWh8]%ԧ9W h:i%Afi‹Ecm; 8ޤ.rB̹#]n/ՐUw}p G z6Z]ݶ%1YS66̎Zr~(f&f8~˻DսǮB k'g2Wr<._m/-Չz#ş_64H{a7=umvm;x.ٺwacf+ݽ{r$of endstream endobj 1745 0 obj << /Length1 2349 /Length2 18091 /Length3 0 /Length 19461 /Filter /FlateDecode >> stream xڌP[ ݝи{pw nKp ,3gfr{*g~kvW7$J ¦@ {;Ff^ +B9<ގN@#Ld(ooqX8yYx<1wY2v@gx Q{O'Ks :y 6p l t41XmA+TM,.Łݝ֙\nbP:܀R(#<@oXA.v@'hu@hp+ݿLLm<-f6@ =/C#g{1_ԍ#Př *-/~bN@P=vvAfvfang  HGftp033sq_ y:dK `Jciv6r\\>T/gaZv@1h,=:̠c0Wz3c-fSѐwU{8 ,63(Y_i;3{tAueA Pit]ff//]WF$\mlGodkio P纺@4 vTۘ_hm[FKg K\A*;[uX4]&֠ԓRAKۙ؛5e#''#OxfP+rpY@h W]@.Pr>3{'v$o `L7 3Ib0IA&? $d ?Eq@\ "n?EqQ@\T ?Eq@\4 x@:?U4r6@&Em>? 8LP.f /w۟x, l2wuGt? (BvPq,<,@? ? ? ,B*aT@jA!r5(?j9c? (!?R;N"lclElcrpc;AT@P[? (6 W/߱0qur=0uΑ=@ Ҽ _UMpC0; Ůf S2L"MeFӝpPʶ8eW:x//q*Sµ>}yu`S"ѕY)OңW]JNYi(oE9ƙs. D(w3Y2qt>'Qlяs^?Xq>ܢNQz$,xȄF7 9Wt.LllOƘ(oQ ڨfugrM;+wb{Ef8 [*~|K-qvwߧEVno#K I;:7jO&ȌY,H OhW[ DMAZVtz!*86 Z{ਸ਼hZN鶃} cUͭI8)b.4S<>(?)< )^wnd+¡i/Sҥg!R_Q*&dbb,ely]ጣם2؜ D)jxC'Nx?~$!n 6j[uYӥW_nÿԑNnnj*0PkL+f4!C ]:wȇ*5ޗ"tD{zowo9D)m V): ZDN/t+F66Cuu0{ӎsn['kWbny~s1a ģ; 7:-_?s1ClZ- d{38M C&"H%9\sPٚ*zH<}PD_LpêcumCB}RvOu^ӝ !}aWN˻P?SS-$wU!0h& s ?ScB-Mw;\`ēL\~Spi_d{Cp5`tRm:h׷6 1ɗ4Ĵ*+Rg5e+rr|\ .kY~<SrC};\C/B7R!cjoʼn)M+־lQn}`Bl'ENN*X)拉 |ի<(S\5oNmFyǘƛI6!\F8QD~] ^ FbC .,{|BN _^ʷBl\] }͗'I2 nb6 :-6rq<̩:无vD6A,4-PLf*+g A\#OxuglC 5~>)<{)T+Ih:tG貎FTY=Lܖu/K6M  Z >@o5Mee xcD +]ix:l%+H!=6.e&3Piث 8tbT-ESډ/ٕ1-;,}uP lOUȉf^>g{c9x0i>"3HCZėͮښu`3E] sN)Kw O3ұגN7U?jBW@ 1ȴ' ]k\X%D z(9l8(l_R,Κ9.[Ốӵ'&{È !V@Mw_,8ݽQL*|GQD ai#8 /$ݔGū=%3@ #QkyA(3f18b+gU}G t7j$ uGV&ЗgV8RqL#M5*6.`7{b**(-qY\Tw*g$_ACc~N*" *6K!FPBBDYD<̼6=_MZsoNƌ{x|ARI5LI\E|*rT\ٍd.GX"N:}l}:_ry|gzn<.#~SD}&MEωN>"Mʲ4Kc`!bmetD|` 'r1_~ޑ9@rvF!+i{#fiLP-ʚ)Vlmfc+N~Y߮\Uʚ=Y` PmH L2$Vwaԙ6y9c?@Bt &)EۂTey~&gvm&1T$6`:>j`4F%rwێs-A)Չ=[8 {,}AoAwWݥ4aŜ؜>"$#N Y!]$|A@/ CTr') Wh ^}-~JjժU H$sN .\]8r6>Xlֈ0kAkY8.7l>f:c>ƆQ%h~qڕ=23L(%x͡#fs|4Z脠P8T{2 Vb~^0Kôţ1}iq~ h֚Oc+okz @Ec9!꬗Q{g:\~z58DF.Ş՗SNouWlx/Yk>ٲĬ- t\M/- :±% RMog# shX~!';E|~;})ߪhЕpU?$B91E= -@EZ!]Fef®AsN"C S5ճosvZ۱dR:7$0KtD-#s~ e8 vzجnx Xܲs|m9[3zY,#~Ivd:W{ sn\#B8M7['th2$ٰW#rM}YeAU7(S*͎E/}L`|jI*?fM޶~3Sʳo<ӧOA>4`m86t>>v4j_3v*01װ9oWV.( 2mAN률*#Ih/a;Q=xl?GiIIYXOJP12JؾԂ<[kn[擄AP4aZPkJ(XݠYV݄9kⰏIޮn^rى1:Ww]r$5S:yf-u^7;8U)UeNN k"(aյ(-ƾr.*v_?mjV/>Ă#{IV,^_= TI E8%_E? jcF7kUg5[ llK08_-틃Kͦhx[R^Sw] N/ƛk-@ ?$L#)nR;^i&[biQ9궭o ̰=-ڞZë15n;JU;'-/h,e{'i~I7ӑ*Y e0Տ ]t5t*L>*rv_LrNu٬?N6"j$8̡)&gp 9(Q4IݖO6Ҷ?l-p6/͂n8{ 5HoJ0{nͯiyeuz ңm?\QBhTׯHy?>R?.ի%(J 0=-Rw~yw)h#ʳk@_Hr4R T6឴{$O1( )oys W7?=VH}[3 w]]%A;oKm䌻}җ|4m#,$(GmЍQWS󰩦$gE' q&;dA Y>6*j;Ҹp:t&1/xȊ}v$_u1vKp&mbpg?AF96(<[>Ľŏ_$u~rjM8O 0_+ܜ79oZbb Zw2mQ&ٲXo.a>;#%Er@`5}5$a3hD*^@Р沗xK_Cضh\AO!ds!IWV.g)Xa~:UhCdd|{_/\1aɅİb)n޵5 V" sɵ)#Bup֪D`KZD>=QA@#Ĉ4$(i{<ن{U}MqqjP3C _߆őkv"~jt\nlj6>pJ +3VsiLrN'?x .Ȧ]$4# \pG&a)5o-cacFӯ<9O,s+Yy< Šw2.J3?Q،x1fwrz/f{T|zrG#lS!>!$~};m/E!)B _sQx`"Efcp{Fǘ##0.X  -lHx^nSP*9g`쓦Ied`lK0_ N, myBZDj05fNDI+xq 9ɔ Vu+]O+Fs͓aC\bW֋:͹OɡKjO^ġM/V74Jυ&-]`Bl n:}FªoAieh+֫Owy4rRVZgmmWWf#oXAH0K}tn;C^#!rryv.s5ˡ6^@f a\LϦw! `ԇS_5]acvcr~cXi]2Mgu.=jfwĜ%j{+,[T=_?:7Y&Z k.vx(QT^5VhcAQ&B",X_%i8r:aw5С=-/䳳T(_ Od]Ak,ʎmibXʻRIWD5:}v8.Wa]ߔ0Ŋdv/O Frp[ AhNu ȇ|xW݉um|9!˜Yqn_KzFltI.`]v3B)R>m<͍d{ ֔'q( b/'K^~.ޏ%#,^IVa`t:8oY@`$Wn3V:\9JKl[:x^tDŽ`W}V`]O[;F&buc׹H*墆P_bu#Yf҂oo%biD$OE ;hsrV=̵eDB&kOc4p~A15 !%U-9e'B&be-zSz'w$B!|o;&]Ood:oIwڧ=TZ8VBa*`: 챥~>o,GW,I~ߧy!Ҕ9dYQ˱TշYh؍\ȶ_ZيtY5wUN!5["De?ɤIJrmS_SP8BXz2΃Gm%_׈igYHF/ޤTU<ʚYYaڼ~y <>kM "_.}32NK[0(C1Tڴ3Q@hn!;{jOrbtۊĭ"@q[zp1tIW:~ƔwΊYՐkr^qb~ʇn+JZ)Rkwʶ@4V>Vda#6` r&*fD!y no#6[`J$|S_Zqn$.Gxbt`QG2$&殂QǚDiϕ8*|\jsM<}7$Yok^KzvjHRHcmUޫ{~wg[6ME 4ӏj9fd=Q! MqL&0,o8. \#ϙ lXtY ZH*DmjxT/KFaϻ1Q:[zGJ O.X󘸦[.Bw۔̮vQ!QEá];V,^HaagWqo^/ rqmLxmCsA{yi-W޺dXqAV2!5#r,#rn-Չ{i1"{*I!q3=N*ZjS鏒ZA`cO X!RfD QS0< ^`-z *"Y-(mlC*pXqPS?A~I/_%DQ)E ;4e9)Py]5wQBLTQ%7=KVMOmUMu?Ai3\r|?VWjmR'0>I|x6j nӀ*(TێY(>i.Y/"sjY\(ޞj3 Ǩ[Albͥśz: Rq1knt.GUj >䑤O1&VoXȸ&k%8jED$-3}x0e'j&W_MN/Җ*4<-ÏF5fQr4s'iYvz _d/9}*!76qZkO>6]Y;L3-#ɸy  A#RC݁c} GRxb /E}?T/;ZF Z;Ob~ 9Q1#ar#P&96Dkv7Z[mf|2:W50]Ut J% Uo;[)%|[(T3/"4¹1l@ EӯYtٷC?ݬcjҿ$ygqkPiCoj`l FK29=ƒ<P7SVɃG@A'ֵ0HW䓔TIFNDZ]RPrV 76Wl믡)>hW yr.%QZd)aͅE6;XrL e=n;r[oSҡ1?) n4"V_9-MI'xmN2 cЙbZHz)+Tp'xJ@!1(I8&{le_iL5C8^|n c?Q v)y$95WTJ D{W7\ơv.^7}CƮU/'BA̯SxWƧ>.9zۍ;O#g8Tďr5YKC;GLvVoϪsԁO12A2l[S /LK*:8 ëȘ/&K?Tg ^ S}0)MـVGM4.6 ca|[n:負= X= hs$9Zv-O32N% ?7"q|6 VwňܝB?.ozI?~׬IݐJG'b24)HcvV1vEvh:9$ͰI;'mcR#oJ|JmC(3jijʅv%}k3lƬ \N/Fw78)쇝,aovdžEw@m :詢̊B <5Lf6_ӴrHC0}&m'EF|B~lXUlqݝw_ U8f$ImLZaCy=;;YDR_Ԝi =}L |Y+3D-9ۄcm׸Uje ~јWK!Ӊ}diּMDgGT6R1hZ$a#ī[+eaiρ)gW6Nd4*\guƺb^gE@7uаއ:SypC<+%LKۖy1-emNVlMU즓xoƃhۣҐtO,5?N|J> '곥)͛RSeSe:U#~\ҾQ/ ghp ґUcM=U;5VڟFӨx=JbiHDMfXɇOu7,̄MXo l(_RBjziMpcItb J?nJ@D BLRC -ֆF(7{画S/HEqwyFx?|ScՂ֒KcSVV 8ı.8}[c*&Z2S7 8 "|񏢭T&]㿚-xhje Bl1rmOi{_|^t_ݡv'dQ:nn7UN׾丯h]8,`pwZCuB5Ml, ُ#.Y^Mf[ɹ=~ f*HIo^j80}P@KC# ^7[IݬK mkɛaC*FSkWA#r&+]ս͇=Am|8Rh#; tD,@D-aFvq$3_Y+lQ9b^q&XKb<+XI/eB}CE\_IEyiձ o͏-D{CQ,LR!|kO5sQcG>_ ml EI|d@_-7HQ8,& :C]&=nc," D,o3if2->ִ>KW.FLz`7ףW PFb2+(*J)h9n4 Q hNțLSnpb 3I\N4L8!A"yo^y~a7`ĺzwM9jaB {][>4oӧgHU@~ْ_i4zIaY/WDt:nb!noO) >0 '_¶N)8BIv; _s-FJ~JvHZU>5,S:ԅdB-3fZ2}ާ̗`U89n.l()OQ~!n#`q,TL?ޣ^fZ7(Ff܅3vߢRb02Vu-/X8"ǀTgްjW%ƃم=t>Rֱ+X'ѽrʌa*߂t{%瀋a.g/oQW'ˁ-%s$,Jq''nsw5IYF9llO;-P5cB'}O١KA1 HBk(bOX֪<";~L $Kؾ3"'BP;Z>zNgn "@YJ_8?sq΋=YYl[-`Ը4Lb||ȝ_[3"8B_lpɥrg`(o KVk l MŰ0?iУ+E֛eĭraKh!4-k9Z-zW@ĘޖQeK6`*Soqb츘sIWc+o %ki}}|Pi9WX[K}]/rB"VK]=e {U0Z zkG=j!W\.'Ga FJ?t3r9޶%9c%rG!,S:>{ow`T+qY]hY<^C-SOڒp;9 m΁W l]c^- .gQ UjͩN6xFR|/AףI1=1K;X#{@0qZs75eIW[9ͥ#[EY[/kǥvL"j.d2ߏμLg@}7a)n CN~ࡵ> ܃oW2_oѠpPK_5\9ѲcC"vS 95Gs5\GHx[0Ұ_4+G,p_^O'~3@9{gA/@w1Zv3&^I'_A̔gML3ck@b=6" #+oͧa)獽9aᦼD+c~#^S-ȜT8$Чg;r؏*|h|g۰H VߢF$4 Y?"qo|nr!d::2NpmKiɻlE>o8Y^=W;~0 -="%BE+^@6g"'\)CCM1!3nt z PU FyfL*}k *`.G? 2x,dus k\0}xy(fޱRqO[)])w_0Z%-m 97Ɂ8<;?аIq ܗ<ϖNȀʘA+ Z>9K!l첉QVX>Y[{L # "2"GojԢqln>Cn)# !D/tO,b$5P"ATMX˹Ii;kˏ/Zf\ !M|J2!4G }#Ҍ.^s%.OGb֏MVhQɕ,1L5%)aց#'lÓ`A:A;rd\/%3t::cǹYi6gTuEPlLJ ì|= @^i:5Z+aKqd)yW|gsD)Dz1vWdkxkQ,6qRu=J:t{GBQa$2x6 > g+#*1+37eXՃf 4xTKgvBkKZ#-\Js. ͳ s)# ;\%w6wWLVp=˷~KTAJMդϮ4JRLT>wyj(C=1i8%:VSw$}I2V*6?Irbd!Ӳ6ؤhG\X ,@Tc>U%\~I#ah]' Xƾ.`>f}BZa Hg'd*pld OÙ ?4(#]e^o$H:Uf)TC}_^ wvkL;%(NdK9-QeVj;-.F(#g`EI?i18EB2U|_ %MJ^?@pBw[G5 Fu#yj]]a}2YxM7+Q Iuݴ07IWR+K.(yXiIKM8 :~A2 ]4QA:Qg#0`0tOH¬3,ފfM=*11*]eavE@k(]?> /hs2?錣4Zǜm@d7 7}RV0:ǁLR6wuޱW3FSCIra%2^)Ь#`*ܩ( (e8tJO s#:!\gHEi)~ :o4=4>]±-Ϭi}gYucKEc7Q;>pfc tF|[@0YߚZIBeQBHiXOK_'R,S#g&}WT!*&^Sc :l:g^4Ջo dܽQoam席W=]0TZ~H>Tt'[q;HX;;>;ۄFo:mwƨ3 #S{!1+iC)@ endstream endobj 1747 0 obj << /Length1 1398 /Length2 5888 /Length3 0 /Length 6843 /Filter /FlateDecode >> stream xڍwT6 RDJD`Ih"^U@IP )7*(U@t"EEEus]Y+yg3}DH 8!0HA 1aHm, tB]`1 XR|K@0@Ujp,[ q<P> [܁Jp  A 8G+!#4AAp?B:phiOOOa+Vqz"p@c8À-!? o    Gb .H$dh poo } BQht#\@u]aNA΁, \ v!@u%# P  c.=!\ru#qXy} Jwo?uF<>K$ ;Z pskT8Hꖘ{AEzῌs5?4 'C ?,a~>i0; G'e1/%@?0tɚ0 oik i_FeeGHL($*AR[?B_-= x^E]>?ԅyt+JG(+"uw_v߀qExA# ZpwoBX%B`qao= 8o֛/  7Da_6–A ,M,apy. K:ԐP|D%$  I}5~("D.@B~@{p>h )0\Gl;CH˿C(LSupA,fQ.axIg`Nmnٳ}j8j8W8b.&q4=HV.]"2dmT9tpU1DvH~k{eI.#m/qMv;L|r}mΩ#z띦dp;W(NMMU|:Ϝbtz;+s|[K[7xo9&G ʩHTvIC|>ּ# zvXhOw-wzrK__x؇7UL&ɷg52j!j)b*_4};9"H»{>xӼVeI(d }4~f7&XM-4*Z麰[`*+÷J|@(% ~$Y6{8FTh'm7H Q}? NеxgWė${򺨈'~7h*NǛz}Zo- ܗ%.(8 ]}D7h-qtNSNHK-%r·~s`eΔajqfw]ͼ`a?y'Wf5=uA_pb&Lt3ZEوwI[V9\&k۵6ej?ڶ:={y7hjrJ^}J#ICH?z} x"7_^EoϷ+jqI|z2CMa=~+x?.>;B"nL~~{)04I7rE]hzcgrŞ,2 v@ߝۋ}EGL.՚~E}3LY]π7mD(#W^11zm[y+` 8k1WH`8"p!gPdaO|Ln-&텇T}W:UV;Fx^c~VxZe$2Z_,SQ? 7JS"Œ-gSowe?iލA_Wg :NSAcg3Ւ>xa\pѳjJޢ2Ff*hշ2*Dk<ꖼQ!E L1ȯ-6;!tKrJA3q1"< ֍} ӽk~;ٖ 'FyQwuc[ęTe,\L5zçpә1A_k`u +)pF'%Qc X*,rXgH;u|"WQkGb^nހjO"5GSvI ?Vy;Kʯ6yJb]LJМmP!G/3$$ג?=`Z@^ҞYXQlrgmVBnD3_hab؍$2J8aڗ338(3&t<3F]Ck*+&z{c1It×/-tӢ#Ku]j5kkw+Fz\@d)ڤn(Y[9n/G&FWc+ږL$K|f>Rxf"H~DA=45pQB;܋\MXo_V)ۙ*3ǚ2܎Rk".0pLMS^a $Ia/8yM+2Z@*a+s^mF mwܹ=zj7g([f Z˻L1dUOǛ,HСdyAJzKh(ic $U̼{-ǶSr/Ȍ:}: w6D?~ر ynK69i@CqgUjP0|9mR֢(+Ei1 /Wf2BjC,! vf$*~MlEMp ,c-pP܊ZbEsyLMt/|)|up`fTbcχ'~kB?X[_lvIQ&"BLcy˷YG+ [ {R \[ĮT׎n.nr>?hju:#QH9WbiX.JZhVpi2/܀SO >Ɇ&%L8,̑ %2s?~MPJ.=fAH5$`UƳfPRIŐK#7d.=xU{ȞsRA{^\m5Kg5TEx NAu?&u2U:[C393֌ |(%hqX+ƧfOJ݂Hms1JTe fR=]X~4!Zឋs"H`{@8.!.1xU:A7K,Dg'դ[=ՠT 9rZk=$3ڜ_%t,IѬɼ3%jb.ڸX(v[gT]FY[(G옊`N8*6:[zk\J];t?sU֊$39;>|g;VY=Te7 2N %_ivM}ݫRtSU-(t)Fq=vʆ9r,ݤĤq8+R}ydvI9M9Le3.jL=xeAVsE8.U\+JNp{cWz%nP(/zu9˴I8d|9.ҨIE6+]rg ')CXQ-xߧ~܌'aNʓR ! UI_űY>VMh#w(o9KӲ)@@ nK!a,S4X"ϊ˯F'DXwooj90a{` L/L9I`5U-зݼe{/xQez_n7<4mtonzC A9*6's&lxE+T եSkz.޿8U%ha誹ȶuF ~@[ϥLnsIz-qeqCѫ\<^3e~F9_\4 t8Driج}5o$*'?x"T1UsH-~^+%U{p#Ywq&aP⤉%ŲvTh4avgja`6]\+3ݏGwsKt4ljnvEA=d-[StjZ~^fZP3#mq7%-N&FCAx,6fD_ZI>_׊(fF'Q ԋ=|O{xJ_uN+3s0j?oՠjO޳* 2]Z d+_?xD9\WT"ܱeuWKXaC>OSzx'H0%/ ~Ƞ7W gUxkWB=p:6hn?9G$9%jJ tn[(k:b\a1=RZ߭մ)y xe+,t;c"[d4im35DcF5AH%DQtD!|  =Nݔ#0z#qЦ-//hrC~6~;G5ֺFMzIBg#WOU˙i.&?pg6сJV-Lt8<\]p_Ĭos&,yxVF Gͼ/ 9Xh%k?R+3y5;)y0\A=)d-*D/RdL}T16SI"wV$Av3/QQ | 嚟\8ҊA+}hPnչ[|2}u^c(h>H\I-uff[`9£xUCαw6z5tz0#Kiֲx̯0H38MxmL}Gv endstream endobj 1749 0 obj << /Length1 1398 /Length2 5888 /Length3 0 /Length 6843 /Filter /FlateDecode >> stream xڍuT6("LABa0$[mlAD@;%$DAB:D3~{}?};NV=C~E(FAB a0mp>aH4J!c``ަ hPĥABB@a!!h4P삄h ༏vt ߏ@.7$%%+ !`PC!`{!K9J h \!0,  ;&!C-{$CQP4T:PZ|? ODHԯ`0vpܑ(8ij p|@0 Ǣ`0lj TU qX,猂?YvppXvEy}E?ǀ:; N0u? ń$%D$Ł0' Y ivǀy#ma'00o Hh#Q0g1H7~ , QXPMOQȔq*)݀" $$,?x;bQh|~w.HG!'A rt !1! _!7dwloH{?x," -*;j\?3Hs4~egZk4v/DiўvI f&YwT<kGjDY icx G_ + Ʀm1gj 0DxQt_Tո8(/AZ(iF5,]= 'u%/ &5 d Uy6FOl2:T -_ܛ 7"BPpgt<xGBeRIGЕnlx%l_lq Շ_Yoz.Z\f@n"1b+;4Ij!#] .te& <2?ċB\ITj#$>嗚 7 4U[\ݦROi͌%ZzZT9u+^Br4)O=_?LfԢ]c#UF f}d?f|/s/sU{@Rcs+aU:h;\,iX RRl%ux1d"%qMꒆ|KYff$e7Qk.a+;z TL;߮QVz<D,2N|Ns=:l4`Pxo-Wb.;hi+> ?ɅŶSp.wnCe`aPJ^!M$S|{1K gwY2\ =̀|0Be= ~BFǤY 0GFBџŖLUT}N^4\aAT|~40l3ЗNe n]/a& ,^/+z`[,;_`Dy鲅]sp'JUfԂ)Ʊ'oP^&!`#qNOMUyI+PNqahN23Agc߭]'>)ҧ:Msͣc`D%Lu%K:Z$nD N=^$cUE ^q6Ǝ]9k-! >iV@ے U9](WR(o|@"Δ9K̼k7׾L8>׏ayi0Bڍ OEgKׁTS$< .~us%Ucݝ1Uѵ_t J,j ]⃒p7j]@bpTEFN_t$` gaI 7r׍0oܸeaA5YyPA})~iw6s|_+3<||/Z. !3td#d=?pKTXX-G5L7vp*rP٩NY ┪ůjvONF)_p!*&|Ua\[QV oτE\xAGrUvB=t+bŭHvDfhc_,!B=e>dj?nWɻ\ZKk"g%w f[0^ň|Su_? (51zkEWa|f m-8R JڴR3áDb[.ʖE?hkoAXc\fV^,Ztm^qMY{籨|# $ *߭SR3a20Oh{n7}ѨD$q$)Ԃ;G/9 Rڻ^ *}<9[fsL^`-iwmf,'<@{ +VvF,(*Cdg),VcW 8>S) Gp`VO*>&%Omot g_ra:#2"Ɨ 97cKTܣqa^={rÛ iPJ6F[Zիb&WU=B}k--_= .HF,`ZzWMWK'bV[IK_ica9 ,Jh~$3^Õh֧}RY(3q]Laբ0:wR]@g Dŭ37AZhx*l?T "Q\]|!hΖkAҍM$C$Q>A%~bvs#>bR_7T̿xEǾ6 tk@Ԉ1:cm$i9MU}-@3?nx{W8M H4, CY<V('^u}gw2MlT>8=z]0lFڒZR)-gB(V6ne-1NL{c#lc^ ogeծ~Й;d<ܩfp/#°y=܇Krɝe#cMZ_)GbNrZxYr@zNM_L*o\/iPa T+L,iNUuz6~ ,כX_*YU-\&,X9u{ՋYta)L|@!v3~4Y];-=TLڿ ȭ~)&{%m}܄4dTs*˶A[B=ǯ$ AONwew\rm_v?=yyU?3o$jHI6#d4d]+$?R}Oе`; ԓNp)},츅UG߃NiN3TW$]5Yjcij|ahZ蟅9 lH&n&H } MxHzRk^i>p?qu y*~=/Uѻ2_R˘aG쬶MF6/OnK?}" Q|NeiG4OپASUxtI^¶5fh"s7*=|fJ AȸJ(/BOrgh 55ɌjބI>e,<60)_aU.K/v=PX1,42z3>o$@*~K7}2SxP8ý5ɝmh1>mǫܖ_gy$Y_o(hJ/ȼ=ʢ S ^Y(N6oY~qZZ+"׊ ;"]Pn)lP֒I6djgǼ`̜Yߒ9e!17 xA?PU+ٍDv/G?߰?_j_율u++<3 ϕ-'2ᡟE/ʌTD3mc* &|T-Hyt(u1 6~LnY!O$q׹Z}ngydjDLK~dK$ߘݙP +sXIL|9*_ttV5> stream xڍtT. C "0twH0  13C HKJ*tt#t ){׺wZ|{gww?+g (a(^>@AKKM $P#䯛@B0P@@@(O0#@@ PB@TEP H'jkW ..w:@ A0eqœ9`(\v(?; GJs?CQv$ r``EmP q8B jgX]oBPd wr<0[ QCy@0_@# + w xH0B!FUsJ0kBO1g0;aYՙuq)`\$BP0x7t rc&r;l0C@|6E" Q+-F7揍Y>0b'C/k8?S4P3cp8WPD1/>, m\5 ]=e n?i1r3ysw⿪X )::sa/ZWFZp` }Z-5鿣j(F r0[ yP2b Ep0. qd 1!1jC^/?Pֿ'(B @$c,F(L 3 f13f7p_~"Ss @< ` 8Q}EPI;ڐ$^҉ P3"T҈r~zڌFt3my^J*O#^f [f#xcF :' L]Xw#nXvsPx߫蘊wSUnnn-KӤe7Yy5XAw/s):p5,,Q;UC$νRO_eݶu}(JG„Fs/2?mPyYܒݶ*\N8>Cnw̨$T{';[=l(@!0"QJ?`u2/X^HC բ#f".o ywU\ @4eڟvASe|[)\'F3wbqdNF}֠5,(#NUl`vk,mьH0Zݻ_0+>ʬN@Pف'ooRWHͲhE'B yߘk붲jrճ8Lo6e7:=)hrhԧ'0, 7͔aqݶQ.:2*H%A yoEVd+xEG Ive lyEis蒥ƍ8D'nLv>9QPFF}BI =`b[U|(?LJP=TtM )0y y7{KjnyzCPfEg NC )vFϕQ;݅[ =M ԛN9vy"V`̖#,Z&8E}冷QO -VE\ȮX{8ͪ7MSgtǡd (5&twmx X'+JɣC dY;ƹm@F!7 wy)Fy~ d!$gdNZXPW܏؞BLƷSy:Dvjqc/I/}D`wֱc$;=X7\]8%At| >;5m Q??-z+}R*^pzmx̳!xEVm2ӊR5hZ`]0C8BXKwSP=ͣ6BROLVYEnkD z>rLIsTKX i|OXIz&lCڷgXOʂg'[CCs& w?aIܧ  WEM:&49R#;~WI8aF J*סsncij?UKCJn;.ѭ wga˕Yw.${enj+ɣgnMȖ 76\*=*Aky_cKӟG|#p*GpiK/pIB6˾&g7q1 ̗~z\| ;$.ĵ2TXl+Tk6K ʉظI#P7m\~ycOLmAߢ=>*˝'![0@OS@yLgJ^uBt|P_=BM6ơ:FO{%sQ1݋1U3׃C]%yTR~S˩|بjEwߜxA"FNXJU,)1s9 K( cdBMo[U &6,?PqkhpnuWo62m0z0Et(8MfK75sY |{P+ڴƂNu &՗v Ui27qd{s/^W 侲O,jgaLX~)2e$`yL;oX/*ŦnZT,_"F[|8W&4DIa3Sz.4nr2cx'oٝ¿r<:q+.h$8*T7؜|+R<_ 00oĮ?*-zvSmȃ1^tStw"V?H_ϔs_ &?YSL 9ڇ;RP)39 JH&l7_y_=tK -Ȓ,u~kpShRWk5!)Fm_pʩmTHX]oQ(`ŝl?I~ H/LY 0͓OC}d D4M/jֲv씮bblsy`/hWT~W_~0o"K㳮qx3Ch5_k_+sjWЂ|~^FkdnB˝x\|m goWLHf(Q!X2rqjZAߧrM~91"XZ)"'즶(Ir.P9 .6M?%G"[!VɕҒHNow oR_@7|xj(AٔyZbE ._:tϯc/r+/m6ﬕ)[rShwXWKr*wraƛ(USYʟRg0Pe~꿀JGtb7 ˞X1y&pMO6txɄtͶ\ȥ$i48Nja7gURՇލ7qO<ˎ,f(rc`\6|i86`>r%XU0$r| ]Jeq;M6%ړe$ 5'R~%gxiT4b޴?aG\DGpVȉ@ݧxͥ^O"H$g@K3aO}DL=|OA/5*wv?JToD~2Y" N{Ps7>̹JPַ7Ӊt-B`3/NAv⁧9=?{KPe|sL3rwz(\ >'˖O+JÜ 6 .'v䰐*Ԫ͓Koݸ=revy>.$|N2r!"b~JGJtcD]0@z <7+SOX-۴өbuz[M]I&$O.NGQem㸻b>L7JV%kqT.p|׹J4tfI-i|Л J?'`U+5ܥ2(#Oqeͥ9i7ȑ&CN}Q;cj.g"Vj-eUNok@] o<țY㼏-xɾzBh0[XA7ND_Bv5> |{1H$)QKkZ2u60ҽ#?Sh-`KYTQ@݃z>/Te J6JuUR_])Үb;ùC׻[Gb܊3]nGo9 Tw4hUAF깞;džKYjYf5o"AVΟ%/FU%W$\7Fs/W{sܨ/i$p˖&N~ee/և5_(6t%Ӝ WUzMq:w4qFf_p"9ұRVh5/霃I9UMu1}JOT^#LOi KiPex Ċ'3:Ӟfj˭^L!ŏ'kwؽ6d-e&߭DjiUR$R}.C*V&#»'ϻj?NbZ2&(3炟z+G)QDf󺈓PM?=pYvGW~Dbloe(Qg"CVVɖK0]k+M|*_i)f4ljPF6Z Od9bB]b[fx23JtI3&ckIq.=ot3z\7~0-sޘiBfp.LMa+i}4> stream xڌP\i"![wwwh <@.A7VST^G޽ *2%Ua3;3 #3/@T^̊HEr#F::ly0u;eb`;y;[5 `ef#/@dgD=A4КXxx:LmΖ@pFSck)LLnnn6Nvton gK 4*`l2FD*%o#XLN`[3#*-Pm,[?0_@9zl- k @QB-엡dml61@BX` .LANN _%2  ?1#v'kekf0ٚ*ŞI,B-:8x@ԒWx5{_J_bp^vsp@o9pvtz{/BdaL&@ -`1o # =efgk2Hk ]:;w;3kɸ d Ҷvق?Ʈ,?X vh/3)U߆_jڿ?jc?uqy;1< b lkaoAN wm[YlJvN_x4G>ZV[x%R')mM~1VN"x`bE3_K `bsyM$K70F\&߈$E\&߈$~#6o`\d#0E7sQ\E`.JoF`.johF`.ZE7 8o%8omhlj?bWWk/3/$$666&? 8%wpd`aژ;Yᗏ no60?bo fK;8/s;? ,ٱghao ,#?3@6Y6`W[C7bObet?q0Kc{E \윁f&[yטt NvrڀlL .pN. g #p ? x@03?V8'T/8ד|u4E3 |_|[!Lư5njK3kα5\<]ykN q+y'M cTƷgpzGs{Ԅ?<9|nltp~y-^S0izKyS'Cz$UI931Swɫ RzDH USƏGbT4ys={g+pBXZoi!Sі>Sn/@S k=fSxBtA64Ae]WH&z6"v_>ªn7Sf)6+^O ir;ə, ;d`y'TyyDC;nϏm|mmyU߮kPf$(m9겛%bs,[~6 ߃c2X0OΖC܍`<]g]?͗MfGKiME $h9W)lPm~;u?MPԧRRE*$7F_ຳbWb̯Ҭ[YxI4TE䘶q90EӅsVnҬʼڑh)jJ~!HRѭKiy e"+Nsz"Q}(cS~[fAˍs:)"ASi\ E)̘dӒ.Mw _X o2eW"Q"D;tѯU@oN NT0ppZ$"[w[^߾3AT,GQSzr ȼCb{O|^Kl8|Y?B&^`)2*6ss& 8dNݪ꽬ĭZCRLgkZkyKd S SCzkOw,>o<y y/NVGNfSl_{tÕNɥ{F?-vD .pUk ⡔=S ZZsz@ DI(֞"l(U,,7)wu6NL Vu{6,+4$SSX*o* у\7ӽq}əEإ8 ^xQ=Gu-\{$$ZB!O&#Ge掏.h!^cq7(p1AftϏDٺshۅ…xcB@8]SJ;t?sG~| M ųMLdU^byJٞBFGPJlmRQnb3!Bn1+p Xk{ZX|Hյ<·#/h+o{7z01yk%PDō4-W[cG$Z|)[ؚoxfxu"x!i6JIP5x&I`S 5Y0=)'Y5O0ܖzyL^r30hv_b7(PDS$xSR95P\~RRV.UO<}똗د}Ճyn%B VDT>x8 hBQA[u|IHm-n}̴MCӦ\0S:r\If5AMBXZ@%+Qpj`bisd$W`~"};=%F)VgMrӻAS,!i$x2QQp/\SxFM_mf\[U '$3Jqj9~W ֘}RjwG<= ]H D<3>] N6B_4_wiAqO &,Y͑!rmI h ye@%YۉL"&1ևI}D^Z?._1 h~'aNoAd MMcqvMJ|.-KH)-O+LEqXe;e?b%zyIU(y9Cm<@a{;5 UD UDܫ 3gx8 _l/`a~n*E%-|`z3Elw| FI_9H +R:,[ڌ?8Mt&4k1vѿUqYXA6!l OuiwyL|p4Wίd* ce/J4/?ځvvZN%V !fgf'*};QK pJ7xkڳZJx-&{Y.H'`e0UƉrvHuﶞBX,u8Pv>$4VD,ծixy!C;ai}B?UXwtúʟ,>:>{s䕴%Hx^E*Ն 2NKx#P? &>8m b6ctyy֨Ubټu7uB9׊s`4gQ}_`)u LW@W[nL4Dzl=ƥdgXd90 MF埧Cט̽VR6%Kwh&I4՟kk# &g#j= Wz.o7j7f]5u""\1?G2*qPEǙPl)^W?da_ӰO{v5Q F3c^>XC}|]$۪y̺P<ˆ/O:y7bok?kyhmVa{\HxthmEC?vOx~Zm)ds&6Won}M6N ̅?h\J:6[Obh;]]FEΛA/bёbѭ7.n>ʣ;Y#?[MXrb N1@w=С/ 4mK{4bvZ$1b꣝nMڑ-O%:#';ݣ=,m־sv>H#[!(JICvks3{?fa閏lOt#94&!Dbxz uG>ѬK޲ vlrkA"ϋAp#R{qY#QM!UQBRۀSwס^7_ L̃[" =/,-~o~vOԺXj(. oq.Ū^(GvW19]UjхMޗ/c\tRP K>3:?]9m=XHk]~1)J^}zǜ?,H@g_#k"#}^h 19]do!mM(9]T ԴC)_G wS Fio|%p4$8aH>059tA-!) +rBfb|MؕxOǯii)"2=\=xcX?nZp.9TRΗ8%o>0f 7z;O7H|UbzQ\&9_{ƒhҔM)>]7A?ZjpcR|9N%vXwׯhm[?NkEC{@]H * ӫTP>q9F.{$4+qձ\_Bd9 n(!Vo8[Eg 3@d)DGA{LI)RX9y}SnY{( W0Ž#2Z=C8֗ھ@I!Ti4Ni$=kG |78z^'lg.sAWJ+t!ܨRN-0Æ&yWS5/bX9!6;١04 }A /< ]|9t;[nF3,ϼxʦS$jT~̴nYlLb5I)9<!,);aee2oeI?@"k,GG"&=(..wh8 hJMZpд(628k;bWmyiHv % v;,"v#ḴK3?5c"(S7"{$ސ9SX,; 3Ky[J?ʄ%iqq~ΎI)quioj0TI ` ]ϠĀ?cWn^ن4X#>飘2˷w$݃Iyc{zys_S28U4++)(>i*r3$ "-Q9/O51l7hv6`fPFD(L&I}$>'RH)ь~ifw{g#6)Z/Ŧl8v.(5 B]O(py% !,d׈$(7--ǘe;@Wi:Mϗsn"b ^_y frmKˤ^@,$"b)phC66P4=5nMU0^5FMԾ'+{u;D%7YU.% 搙3.Nfuʗ8ZOVv}4ޡ 6S/FS,0S]&C ;4qQ;\\Xڲ+|DUcG#Yn;6"BX$qXIC<vjeOޕ!׏Ao:0|(h )*:|~nI(_DU =O`YfJvw0p%~_%ao4؋v.Ih\2ۑ$hQH#`yԟ cE\)|5.dB#U&ͥ89ŀI1ER2R݀L|~-_gcEeBI.z?to+~]dლ|('eb:Q~} D$%X,+C.0(`vL* 熚;~0ae'YmmY̤>U0B *}~“9xq2M$ybH\5nE62a-c%Ne[mT>1\W-OR _|nzg?..l¢^$chN9ԛА~Uz5"3P jzv7}TޠBt\H%hQ+}3?9hEi%ԿǾ-ʦHA8Uc8S_ =ۿړSl昷<=6u7R3j=IUh;ƒmrAIax., _?0:=s"^ I;5%}m.ް``EX3_~;GjVķxF-(/t}qTt==aHpKAVta5}i8JG6-pNvn#違;˾QĢVe9 +H]oAɽlH4NUbh*z~\`p.Kش$i5aOOKPOIʘ柞jvf2lB;|uk`Zyߦ v#kzE q p'FFov|֋r٥2s̠kmq "Ϋ(J})C >pHt@G^䤏KBU-(W\u6k~dāϨ0 dUz6&gU%ӕiUA3AeٲGoÁO4$0]wE*W*RE솹S_^7`/K)X^:&w]y,[" u~yQS q{ b53gIEO,/#$ZY& 9*$ U6W^}9˘{VR"i\+כY,'d-a' wޕe aR fym pC)5*.9z$! "npH;ν{$cL}(Qp)y9?b Lٛᴿ~u,H.A"7R"<^$6v_=KPXoɓG?m6@ܑ * jputY;tZTzLb;#یLp!Z?>Ǭ[SY{VkqI0?j9q)y+@km7غeQvʈFd6p'z3SF.UQqT3rYr&\ b:J l,,u]:@g4.wQu7}LYծ3=N8W@⽯׉\RGo8,'vbyqb1%GwE'>q; ?Cn+W絟Н;QU0{IGvjHdnc+hT< 5ߛc3+̩v<;oMDۄ pJִI5s3u?tm)ՉP,Y &Sg80|HyI~Uj~wi~/sө:=$>0 Q\_u$=\pO>kw[?Æ-E+4F*zη4k`m[ x|\Q 0T-@fE?7Z7H{yFq%@(5ཛ̭thȲőxkDB=B1m찮ɪUEڂ.=;45\Ym/$_Ϗ3uWw#,-$0ypy Ѻj~>+/j24`B&|.=uJvZ_1۝Cl`J(iIV!J%6"U Ui|WX>rY4}KvBTL|H 'M6V`>ڮvOELϤ(]`V$uG֮M8h(UC9gM5%58)N!.U|b~{W" +V6WZ.Ş }2JކhGsyOdh1zގ:Z Xka`w=6N߹PG>Qabb &>5i%+D,24i:bPKE>YEm '`gW ~uF x;QmQgyih}X0j>75_,x ^gP^ QU;XTIVkj'sg S{%HPɍ`D#)X97x%`CAE͝C2Eu )۾'@?6 Χ<;ݪ Wb$ ^ il!6?A(_Lę¼_4:LQjI(MlTCa0Ka1Qj$_A{x[rF=I$qtKŒ'XשeXq\: mU跟Y&W_)ޠjtTuS/-Tbv+=q H;6nWh'W߭L:ԁHM;)2M/#Ͼ v?p莝$8ZaU`SႹ.L<|D8~DlVav))X3(! 3n[dL⚊6?NkbUTe +#jz@h\ѠY\ƪx.]Ge՗u|O+ga-HrݬT '(@^Xi줗 53Ob"_h]&WDgq?j~=_oK ;4J +hM(W xާ^pHR K޳Ua{T5zH(Xt$pz(X+s\? g^dj2ZyVw.'qxu y)Zݺ2wK@HGDmڑȷ11mV"GoLxI*}'hvS6%5\Д sZq#z!` Z<Kx rTePVqUdk)( UHdݑeϽ<(|!$! q"-tđmԥ~íU{Cg2j?ӝ_yP]iM9W@^Ykt\0iLE wn[i6uA^#@$&\a+Uo<~̡{WUtwy H#r? S4]au471Y_j:F5fȎpSŘnntP߮5p" V0UR;25rg&7?MVp}%|Rl#&ҎK..cC 3µ  ;g1*_!ga5ja1Z>[pY$ה:G5թVUmJlP2gM&ubwW- P|Uv}*`Kņhr Җu|PDzv (Ƈ䯇E\:ՙ0 SEal5B*>7E$qnP,BPu7/;-3yݙBbaa51wbJ٬:qe$o{!\NyargiNt/t '5ֲ;QKR:4wETK首d*~.xOq.A;C_y:%Zgbm 铹eY3o uJNJOu3X-KP@W`<.`8{~mD:wJ#u`[Pb4_L硹AF(2dtL,%~s$/jn9%L%q>bnK'k>ӗO5-.6WaK\'[^>1=->k`z^LqyխZn6:Z7 hl$|)F"a+M_R;\ W?ZIv*IAʕZR$ x/[!g@ ZO\2rh\] ^3p} "K偆< <ғ&F62'[ud '@U?ʹVCC3-,<28F&@i|<LW520a_p8Ɍ|ErlSV@S;}>׵1suɯo.MݡѩO!]`1ER.5V&%WL$IOA9loH)Bri38r,Tf*2Jʧ6Iw;Wsw+nd7 ]vAC6eo[M|gW]s Zo,<+Xk$ ="RIbZioxZz LF ߤp>12FmIZ51VhM`Kty#&CWÝ-s!NXI QrV0ƠA!ʄAĒQ4|oR]g!]O\fpP1)替kV!X;nc6,-U n)'Rw;23~V̈́u_3*_9SH?|03I.Sp;qnHj<ǤFAAC2)yҹH# 7A?)D DϋNmB##p?θT]B@P7>m-a:=BU@YlBnִDU}hjrBmߙ"قg7r]8swO44ӚD^Qc?>'wj`fzp~*E)Xvl*Ey[P i[!_`Y.蠽A *I;bt&3-wsA"sf:4q^ xLˏH\+ay Q?4&¾o=I8,QB,V\:.{M`ϨN?~l)h4m^P~:Ξfm2-w/.(k ?~zr|1|Z~ In['LWMbE Br>vl\=4ISn+ȃgޤ # m5!h!9va{=z,3&c[E: "IMQnAۇ /EÕ^u}\P s)U dn m=-!|pjMY<25NBK1u $<| h L )Y#S;sGFL)$7o Q?󄣯EtC-sȩ|e)49mk(Ѓ̍ƻYBL5P[04, NO -[G"c?@m EFC ko&ٚUbغ'Ǜzq:KLTچ[D:sSM 9 +KESiEr'ؤX j?g'!+PV{dBZћnM4eZ%x&lFӓyLgÁ׀(ze_e.5s cymf,n,6X(vmAhȚ۠[RWcf[6O^׳(C杲5î45%ixEl#VP&PזiaRvᅨ+mm~m08qo[;] [As #&vɩ2.a$5._>K_ bb_v2jW&`|*i0E%,w|N#>P!/cq>1r8E uѽ/i L[p0 (L5XRz;DtԫabwE~dk XM}|ر&l#ͼ @MG]`BδhG 8Oono6Nu}#[0Νb 7[+L!˻3+MCbuV|I,fvDYG ܤ&p恾]# }Q 3(3)K

l#lgxn;GdR@aZpnllx愈w:%QՇcפ}|$6~ٶ#*|2VoE7{ {[@|jsW@2}<C?+ #G` E0䉏Id{RN~EeJ7(#N'HeڵcaΤn}HdsW5-uȏ df:"G(bЌlR]b`-+Q~S9 9 &*<=ҫU2l*jÆ$A9"rGpnWAo!- ay+ C(zRJtolB@%\\/72}|aEvx_7PMu17a}gGIj%t8,2h![}0o럃6Vr@2sL$KM/*brG/oj#)Uw2Q18]y!9ݹ}}RqxAt_HM\vf9pTi~;Q!kD$|,Lpr|W'/f pҲB89 vLQG$p9FӳR U۳v|Uh}z6o񑇿j`yNɦ@ @<3K5Q1Pp8wͤZY`%O)Z9836+FLbuN'WBD ݵqE"jP77!^?0łq^,Q _(/YNé Y0ȤIO)JV$!%ŽcyɛYk{ΡRKGWڵzʞS꼕2'."iIca>3L>Qp!ibL Ȳ0cHiѯg$`Wَ%z (Q%1N|H $V(|P%B ˨Td=%[XNWbZ]CS벃 *9j5ګAnˡngI<' =S0la(QXȧץsD%rO R RiZj~xC4/Q>hw 9ƹo8j.qská,TccvIǨNxxz{_s5L!g޻p,wg4a$RL&6L]`1vҒm@93D8(@vawM.p;50 17r*G֕(Fy;&"=!;1}fzDL9"L:0iX#tu U?4P殘ċ|X,YօuYkM|ԞffcfYM{4;X:>񯷖J&&d?Fӭkm}e֊UH8UK&j1y8:yB$H]pF^v\tϾRyR{1+MzخJT%@ \1f}Y#sX\3n3*o#ǮztDZI2]1yY+E-'~6*l&rSm<$}(Ȣ~ꔧގr#U'w'Uk]uB[rApՏ'''25  0*{Jn֟F<\sVl uDpZFDov,R[ q,yoj}VEUYz/Cw27O@vkk@HȈȨ g]W=&|x]\oqgk9u0M*}vbMz }5wuY4 Ĭ?NĦ,*W)0a@ s ip 9]bx{h׷% g$̠g|G! W;pǤ^ ~,ˑhZޖ؈d@` 7y, r@?,ϔ:~w.2B‘aD eU kn<6ߋ?P;jl#b;$;R}Y9B\!|F)N^l7\'fNy%$\/Mv F1ae3'Z;\fO2C| `蹦kG=97[y~`WF;]PiZ(Q7"Gwr슰)> .%Ѥ*cUDe ,Ar/讉Mj99)^*=VyR8 #x4c4rnf߲i*cC.@|(,:swEJjB{q$Nfn#gbDh[.FlU<%lQ'{֐UC ?3E<78tф!5eLL|u,bfbP(hk6KPD#fe3D}is;SE=JjOiv6Jl}RIAܺ~W uiC{I1K RX˪` )Llv κӏ F }?Kn\p8ٜScwv0\T#ȠT)s N3CpҼ=hz&+Ϣ7!d%J8s|m5r7ܝA|d+:%ܣ˧Iyεηym_NLaՅ㗉 9df; tx}dRf*gW/VeF1L+H{22܃yL\#Q+>؊ h6 9J% pҍڜ4҃aY`AZ?A"uiZOCID@ʣ3]@U>D>%uncxpUj?WCbFQLGR"+ sG4IkVo [LPd-i,OeH~utBġ@ t\&3Iy] އ,A1Қw;J}ua#OMe R`_>P,I&ojD]Ӌ^ѣVR^Ԭ1anvMA1%> KQ5KX'B ތ=vJvΑ'/XtYݧho}3W?e"nV^\Rfq .9q!r?]ٷo3B$\T49fM3N9j־4xj?Xp`}z3Z(QFdIQ_1̀UN* ecJN55])DHl4:{cdXrKI:f[.FÃӫ / c]y1I10]is]EHQM@6Ȕs̭XxŐYV 'N cbupN]7ݎAQ!xki+p; =_$Xï1q7*?ZxDu2ot?wVp+R9cAY.o .j>nܣO(g@MploHz8n]Boز jB.NR AǵG~ 0o*q kDJrz0mnt Nr.l͛R?(tݴG->k&Җʸ`~8>Su m䏒i{`m2*Z&I)3.HDUoݵ!nTbtK}g͢\9='k/+ iGo -27ާ˫}mT3ٶE)K(! 5\ޒE ^=`Wd(¦=[Lz(t)Be:5~fY(s3+#*͠9&H{F~4(lh]srgro~53 /?)w3jiTo(#MI<p>R~fbY@R2Ƌe%sBH!TV#JOUw3^3wxna0隹3#oƺ5Wd 2J3\yY#o28#O*fjS,>Rzqd{- &46q]d՘Hi{U6%Uv+K%vcohERe^ΐ% ,ALLքE팸Ic.Q_-VQs YbRgxǝ÷$hCPm[5/ߜn\j ^MuJIέz:^9$>{9 Bbv&4=`mR09\MhBқף>-գd φ[FgHHhm^_2EJ endstream endobj 1755 0 obj << /Length1 2281 /Length2 18843 /Length3 0 /Length 20184 /Filter /FlateDecode >> stream xڌP\w'4ݥ%Xp5܂Cp\gf9罪{*Xް *2uFQ G3#+ @\Q†HErCEwin`1EG`caAG>st"R;:y^@kN`f[ jt:Mݬ`vuGsvsscfd2wertcxܬj@WW%S{߉1!R4A-XM3׺]͉43msljQs WL,KcqrLv}5=d^fNJԼ]>S17tEG埠|-Vp̑#<e.C#a"DqIMЉYf}j.<~q d^i\˷TG*5Sσڗk\\]Hy!28wwhn LwQpNfGXOq1]Mu·}' V\xͮJ*3u ؽ>9]Z}VvkUBzLHXXN1D;pLa H^E~n (ee#F\AC m} "!M9_$Ks }PkzV>͸;8S_cn6Ȫ95)x0M|iZۏHJV=CI KnhuA}T!Ku%Mpa ^Voj͗8G4A Դ}H㴺L̸zZ~ܢ3p-ې;ڰf8ɕ52F៚~_5B0l~{=nwg ӹ]5*w6fŅFagG hfHdm݃V ;Jm-:M~٧$ۦ [?IXzb}BMl/8 anCP #bÊG|6"pԸNңbܸiU.d#VɵT˛# LfN@mn@Ftk%b< *k )y=+@džϺ~XJv&ȱy^AzHCc0V?̾0׆5&͡n{Λ_G.Y̹W%~q# аŭm #w{~R^rUtU/[NaCPL>8"v~w{ jEGn*Ay|4qi=7Gzz$pU *a8E?HCTa)?:{m@}d "*/'gS_zVo6q3獒{R\8jY2ԼVpB+ ڴ~Yi%lRt炭qWJ?CDbZ UkX5 :BC4j2yAYi?@ $c9!fdxA8+>n7BɊQit!afP'ybNc ^+biy4]3qK¬AWwUc,Z DU3 B01slpQ҈U8Q!;=Yz|떉#0cMdT-ki#*t"%KR!{5 $\ _yEPr@׏]-*$@$4jG<{TBOZJgACѡ7v7Pmr.c^o2G`WȤڗ- hoG|@.<̩YúVKǭ5_o\Z[m&7ޙ5:ح%zr2vktNj,U`u[",4p㙢rQIF^U׿ 9Ʉ,Ұ '$&*:$!W""(}3Mv2DThipN 657c]Bx6Nf S|9zx= Kb""ujdLGpHyr iM$R2~4w&r''kizYfkZ4ЛaHW3vD7ˆJ! S]*nuo$_ǘ7afp %{744O,W6 :$QѦ~Ww}Z7NS*QfzJ;aArc+ewЏے%# a4|ǖ_MPsˇi?ݼ_익LZ, i"K*y%6A5-Jz䜤 _$UN>xVdAWj,E 1CQנ gJTP3+"9 I-c+uMnɮ /iHD8&YiEp(Noe3A7w8obC8 wk@pBy;IEF2آ PPj:|xI̲A\q9/ 0H,B x8Q"gOI̧7ս%'GЏ,[ Oi\Ż倴59||Z;?z2y"W׮\~zêX-#5![ GgJЮV}^S|@ǵX4a  fdD2 3CqYט,3nk68k]F(>ײpn:8 otNYꏳ£@- v:X?^;.eEm7]& fbf`I(HJOQƐy`(^^K4XC9_zo5(L^>4(QvXCbel6E'1c2,E/#VwҠ}Gk&H򮸾]/i&"T3`ĤD~N9HV\W~…`Aa{_Y$V{NKdt ŭ'p`DΏxkP-{#ã>r'<>OeJC̣ߴ {ydyF0LySK?+Bh00cؓmOVY޴%2.~á}QR"  Ϻkb3Uthw?wdz px|I5Uu{%۪֯İ A:|(.^8|$${)ZK}/W}I> (X{w))wKbP63); Vw)ā-jt"]/Wy xFHW@0vstKҫa]N;%{bz1Yλq[EIZIb 0E[_xjwܽgeN:.O"yfKm!s7,e t@hw^_ծGh<W~'hj4n T3~ \Ђ81;S`z `0|?NznDKiJ.s-Ɠ:aaZP+&ٹHp7 ;!htTo uyC5|#+G= L2\@vr6S2"Erx=6.MB-홌5@F:GvdKڸʚ#z:cfvo-ۥBy1hQ)uo#99jʝ^I6x{pZU7XxQ6dGbI08f*亗cQ*G`B!ϝvYkh(W3dO(G-m}٦؟*߿ RϽR( iB"ո=ۭ#hsѸP|g*Q_ %dpU[-ŝ;&x[pS)?G7\b nCU5+KHTƷ!з8ćʾm [a6yְ tZmmg:Cf0ʦM 99JQM%綃rh tUsZuo%L1RF۰.|{dv˃"= >B ҠT#2Qy f2{o5^_Ch.QKdGR SMN\Ij:嘮Ö0{O |o OTΡYY6OiSr5L7l=}9Sܥ.9E"2V 2zz)EߴJB7VJ}]<򪮍1r U^}Jt_Nb FC7 ]<)z+{=^ Yޖ@#>% YԒd4T(!:H2-`uf|qEiRW `WH55Z_]@e?g/܍yn[s' t]67 sYb!A*ƖrBF%V')Hp٬vg?5gcM]p_ ݬun;.u/bAgxVq3FK鼣X&6Lxɼa ׾cBrA@%lKBvN?~v/@a%4`"i;7OR8=:z#Ie ,Hx2|?LK=mY'5]V]meF*;js\BhɄÊx.d-n(+{ɴpq]J5+L 2fR[WpL i?%yRK)kwU(kZ#^!5Rn𕔕mY7[C1gwHf{=ىp ]rOʬƳyBS&J_r*!|$^Ԓ+dK&ttu iȨRp!ZoU ;4Itܗ(Os>0WVD)|Q0w<G}AjW /N!Pd$vᗤ dG^hLv-)*-~k&6ضDܭ.v!e x7d߱X?QRZU?ۘ㪀g{Rq2}5eh-,G I0,{lMV) ꬧g'X_B)c}&l ';Vy%K|r7Fv{4vgi#~C^NjU=B3i{׸6]>1ѩ/i~zh%%vRz --zJ38 wۑlyWߵ2ztSfj6Fz6RX~Pn#l 樫c\#mR8Q[4YF(nJom'J[1*ߵE $B2UzK,w6o\yzyӘZ:Ū,?: >|_ys-UI.8T.hҩ kg1IDQV|;ioy5TK~=_0QDL-\Q[˄e1Uz&jxe+?i4`/Lv1[e >8^L? 2`( +}?ZOX|͉X˔ !oY/2ґZ)I.ZԿs3w`aŪ^4i7M{śeqsLXjo)7?p b/T`L3J-T3 B*QW4JQ$RgU'H X#{d5)rU;Iz 嶱l4h{?6mL3?rMg~*jчhZ4/Y!u-e9SɛTLe|6±ֶJVTRua#"BdQɋ;0jM"9&*?J=4R1WηuW4  ٥mfŔeI`ͷ~ُLQHM~t A\Jh|PE _|K*/ZƮH+ӑmWn`1񿦒TG_j\j(0@vQō(9^ASL .x֚/1=1A$)8t^Ħ;]Ѯ7шw.wѝΥk+oɁˁ0(m4zm)" uwH joZͺ5y~{,$#iOyOfJ5L+* Wr'"aơNږy4BXozfxǠ {L:w\l/Zc:Sbntٗg-sW+ZwL Vp Xtsyq!J'!;hv.A6A|kTCeK;6@t l~"$P+!wow!Dp9LO>PH^n%G;Q_Ɋ+iJn3;!<6M"A<F"4ZO֧*@ew֬U}[+d?dS,x<4 Ύ-uYNL ?ٴqbk?X)~kFFEW=p39%pCԇ: +AG.>GU%XL̮.V^ǝY`^wVϻ,L wq!2=;~\%8IliwMN#J\vfƙMS¡$]e tsV!QV$y=lE"%79c*e}+mUyou-{|̎|qדt?_L| )E`],LL+[57I0,k݅ KC {"EI6y4iz&D.O`yS᤼BGӘ`^]s^\{ʝA+WPM ZuqROVuSsG_>DLI"r,x.|]gIxFlۂQi(;hOb, ) }&Qc3xl;dj{|ޥ- k!f߇,F^)OuP5; ~SI%~]g~r4-.I+c`uX]-qr;q05QSHH C]c[o{BPj/I/Tǽ(:QbP}ә$s%qiݻF#mvsOBF!^t Biϋtw[|ڳrZE%<-_#9]bkO#Pelz 걐hF5Phy5\`W"hc5G҂ZpL^:nO,mÇDeT˽-j7v&˂>| u0IFzmbU=Pm6^ߑL&"?O Ogns_)r˒5u2ֶyGm*KgTEs,| Dt.&J R+$ݯo]gڥ sE bz5ltn&1 _!{ȡg úsecWJv#PKf_za2y˖M{q^,K&ED TRuħ_H!=\@/u@\S3Z#5o~wB20 qyWS9C[1ׅ\ݤw]VgWE SQy-t}7[O2 FƢA?C~v{&^n d]X7DoXx];MmxH3r[ @6o [9)5g8", "[Cf)+24jzH֠6#ƃyR`! %1QЩ+<-?DV0Çmh&:jYE{0;7.>@ K ҥ.7OMP乬a [FX3O~uצHy+,Rdͤ*4&Xdti O*|SXoBVr7H%-/v!" Ҿ6a/W-<xz%Gą3g~YbجB;'d 9gg{R+jr*c̿vy KEC쁑Zί'N/~><-TR\1fdL&u{n2$Mbua(ߖ^#11YBHG*yW)a?% )mLz UD`5u*=n>4={f*rL25昽l8#sJ: )-!0g[('̫"xu70R|s@\bD5L%+jR K4߾AsG kk(.q*vև À@}Ń0BR6pm>!Ç+[ qD?ڿiiaFrT41& 9 {Rf'' .MLxNa zVJA% G؄ !sO%pk"aXtm8G:eM A`!Ý 2rS1ׅ(ATG[G.Q>3"O+Mt3$xq^ͫVKtQԖ'1 0 y,ang˽i!d5 / 6a\7Q؀*}j}F)ӟ@kL1C @YXw5YbgG, #=W|nU,b$id7^?vmoJV/<@7*E[j`W[[)|}h^.aUC -dKU1>d_&/h-!X.v@\5,*+?Dg*< \Y&L#5AB9@YY0hqqԈjp;N ېSm𔓦/`rg=ɲ<2/\YMB&6̈́nЫ1Tsf;ҵ,9֌&Wz=$ۗvճnO h_+ц E8>[^#zHr"W no5 YƓD^4 n*=yj(uɨPHq."6_ ̮0xU*U(Rj:^ێ{#w kf"a%s |Ջ]Uv0[sz0GEh98/C,^uE֯ehT}Z?FD {l4b; GaL30l⮺1Kiȥʚ0㪇y!p?D4Ŕ-- 6=FAe>fwf\*C#Q~w(0vPකaʄИw`:K׎9+JeUyNSv*]]jHJ'H}:F(ݚv_I2b{s[l$V_v -\ҽH+@dݧă=1[ *obZ7"\[pJGЅ(zeso!`A,֊|7u&h cckk~[AovX!$`xId/cO^!.KPᮆpI}f`q2FWr&։2G^)17F?_"a?"n茉9U7C0c/A^h1x kM̡PE϶J]5~#BuxRG(VdXw.HK_ګy V"Op|]e.hTw-2+h7%ڻ @!+3,=U!lm}{/krcq&q A<2߭'l`%ۏ]=i>iOTS^p rMg{RU_ľ`^c[ }q4sɜTa߂*3b/\wt_+B"hw2PE(uC0>kf0_Ux( 4 tΝ07@ ]py{j0lp .@m~WIV!Qrt\J-V6?MA/jcA+ā_7C$ȍeax|cŽo& Lf&"22jS֚+Cw#*+מvz^,:4YKf֮Oqae<߼+;CLzt_1͠N ~ȋYHJapfۑ)?FKSvg7msP6V&G#qCCs nm`6{LDeNf-l͂?R# 1#8 ;tZfA[oSC#UJ,{⣫Tt /trCqrK%ͽ# B:.'UL~W< W$IrjGLnl%~Y (]FI`-ΞPOr;R|#Rd&l_YC6H:`|)H3H;3#2 a ȘpwڮI Fq2pSDOmظO n &BηNAF\:@q]u0u.aqĺZ@ʕYzW<5Wĸ 0TϦNrФQMh>+p9Fh B$#_tLrv`qsiq'8/8QWzK$AsN%V(sX,zoEij .9#t"1abRf=:0G̳x¹6(PTE ` Py;! u8ݦ ~|}j Rct`tdtپX̴ ($(FI.L\U,ޤA9:=LQ#%P~cT&aCٲY)`gl@Ez2ɽV;DE..$颀|m|.3hr6<+bFNpǏGx׳5'ԴPvT/#Scׇ#_R¶ 2铗4L~$;L{nC1VJ8f^Mm|0?~1Ig9M%"t~1ݩNBrv |sn!"xCo& sJ븏`>Yu"u+JU ?xVJog)Җ &*gry R^Gd%Md@@=4kȧa;U}%;,*qi.B;y\ hȳR}3ǵwiB/T#Y?z;1̽JAR9a` tՒ)35eל&ª"(e 1ԭm>qd&*:3]k df e,9xD>rD7v|, kcS`тΨnNH ʉ QRbu6*W<'֙xORՍqkW9񕆣C뮨-̣6죀7M@-\: n9P{#"])$Or3~_0+˳}!L/N\?^ Wm9:cG'XN@M#"6݁Zh6ݝU7ϡAy2}ȸR ]YfύBj2 0;rR O\φRzvM!=t AE}r<}Fxc`'%Л.Y$QUr ,'~ ,%4pbM }?ǎwÜEjOOā1a1Q_hE|ͤ Lbek` ʑ5uv{LO; G9LBj _ĿPw1lVٚUisHq5Ee%_Yq@Kfn8dq]3feTkÎ^WDu(^mJ$W3fQhm Y2t]ayF-}#SlLz,B~ñdQ/{ګ،nKl @qV}l:ŤAYȋg &QZkC~DJsB0 b[5Eh:Qnj6w4GiRڈe?OB^wEwd 4 :8(U.gG P!: r:NT5/@?5 |q1vkdynw(GO ouVd׏@:²]_=@@3*^h>='SZmk Q͔HDqX$RFxo;9E l{#ci7z,)nw4dimI s[N`_8O:*;>#..:,1k! 87{4ϔZg4w @ GH0F>%QRjFŵjQ**A?o3{}%-Nlu v/ff< i\4R59Tј+jcɉs;1 endstream endobj 1757 0 obj << /Length1 2134 /Length2 17074 /Length3 0 /Length 18345 /Filter /FlateDecode >> stream xڌPݶ!kpkp;www \9U[TAsct]MJL+hlkqec*02HIU̝G tp4KCh&b(kkr02ٸٹL h1p17lmp¶vfNq@aD `d9@`nd`5p2ZD42( 3'';.zzWWW:kG:[S>J@ tp) g` Oitp3s mM\ +s#㇉1,)[Y 4lc#sZظۘḼy1:'7'?V.V J &0?99999[S#?n>YXhO~"@}wZغxSWs{gt> =fdFOw;࿄,igk0(mnh898=ocd9 6p,M`bh?F??0c[+?:bzQe9e_ @`ddb\xo? /[I[اI?=@o_r PitmV__&/3s ?rks+h|t~̂UU{teW*d1 6MIesG1s7ٿ_7+s?7-#}̘M3%~+jcdkϬ1  >XCi tW/ll>L%zLl9W6V?K&6b !h;^1%3^}DCdG?AA}DPCG?A}/q~ Gt?i_baΊ/dM?d_de]#uvC/o~_Q_Q_Q_Q_e)C#Q#K#˿j`/OmG&N|~~X=Pk>,}c@neֈ;Ȣ.Fϕ`q&Fm_P1@ rY{gSfKuLK-H.̕vH=OO2L?4mM1/[](hyZ~W]B7!MFGBcsp0#ufuT wJ~qР7p,PFfޗ1$j#U-J`8I܋yKk`5#Z@Z줠leyj"=.8bp rOHi͐m\ս; {U<*/yn!>bz\Sr"*3(;J`1-Ґ{SNV) pF8 SϏ$g[{+A~:Ú6okJ'{@5jmW g{fS燋uʱ[ys`A PoVNC %l6+H,mvvE\,ʖV9޾\<Dcu(pCv 6Cs:^<Ga{;?">b[]_D8Tatr<Ǐ8|'x5vzv [qGyڠ쥩&͌ϤK=yU2;9,hR]$ŸF] Z40A^mq>ǖRP)F:X9PzCwhz]K\^&*-H¢ݡf#'5(Ǒ}.. V6t:6'3~+_T'Ubб^Kb=nȦ\8ͤjD8bΖtr4#<xC3}Μ:aA%{x!y(],B4Tl¦)[G$a>@Q}waB$,ko>*јTBb#z3>K?~3jvojτKm;@:^(2 |f5pw~v7Kmz%ͪc0RNE7P(1K%<ɮ9菋2+-Qž̢9z9P8dړ'1,PB>cӘ7XV"߸3iDېL-ۆ >%hK^@ؼ"/Lo-G]mBo7cl)_1Zr>{TL>rDa`Ы Ū} Z8-e$A"mFΓ?O97q?/yڨ ȎKV&]HU<&kA=+62Ԧ%^6)mQsϭ[qՑMڵ>> JJVGAJ.N),{|WɄ=,+?F<RGqЎlqɶ#kntS 0 m B4Z^o  8崃0Y@`Y7}lхf1DWI:)8OR5rdY-KP)mzWPQX\0jnUlB7N焠,f?P xq&ln9t#;eqF Dl8fѫpZa56ZR< Os"T-~&qb+NHavY]w@U(̉.( p@t=6c>\U6ټLii6w!<|/"IԚ;ˋ<c>-Q̤֩s<=lIvOشD\u#O+ jg H0-w$4 W1mRZozI"!˱J' )Ӥp5tCfGt64>=cVj/yx2_U( tlr-yxs0o9t䪀Df|PE 1[6ĻALI_KE@m!i}DP,9 Lْ e*A4*M[qyO dA=(.Hw׀w涊SsH%(=M ҿ9gObL w^8?4 i= K489 N'l3f);mpM^`*{*$#+ {95jutΒ2Z: |oEӴC}2:Nyg CL*O[՜3nkh6XqYN ELG~50vuE 7[h$DZ+$q_&%<)2?ގc4#0̈́=UZZ ̀0.:5}CHx K:ՙ[xbT!:mk 2ʖxzҹY(j;?$:❽Z罉^>~2VԄ^)N\(}w8]bM+arĸoޙJͶ2Gç֜YnEn;=.9:;[{ZǶՒ;X_֝ +R.h+Jjj)vr*q)͚u:a6ƮG$PEM:|UL>DU+&k'3zct%!z ̨ <_6C-CM.gOnl?-^PYk!C;yR#Npe3N.ijV|g9 [9+b#[4ur+ְ2zv/~r /&ugdiU߂k̽X | s`pJ$}LlDgT߱sRI-nʣZISq#)0ç,{z&Syu#x|_<:D~d|=1cǚt W &v<18n\!2@k]˧)I$:ldO6@WjGޱļ_2}jņ?;&nHa%JssU8b8N{ӧ8M4_fQ$>z)k6u@S+sttd q3%k{Q@}WѦtnwi}RZ 5f|"]|ߜڄlct5*ՔO3_kUUu<ҙ㯰o+=nUn5B"Mtmچb'܉PQ-X@88R"W?wbN_lͰG*2vvr c_UD9" "Nڭdv@23H@~to!jx䗭3m2e@u5-riyӄVaɁR+Ni7Ѵ4.Cu$_yCY$oa睷nZs8'4SNpρ H^4܇ ffD֮r (Q/v% 1 ϰRINyQU3DW=dW uD>.(w|]D,~Ft_{-rU@t_}/7¸&?"0c`9'gxy|ؐ@5Rݛr0JˁZ6>`iV/1 >?^02*uс7JXqucKjlib% hԢ}9SLݙVɅCk;`|(F>w&tQ[% 7fL]4{"BlO5NLJ?3 ph9wҢ!U-= XfhO;gFX$*Nd)sl=_[bTt3cxz.01 ,m c!5> N[OYOəv޷oyֈah(sc )m:8' Sʍi۹X84dI[4~U09{DQ]S%eJig͊NjZ]#>Q+֬p=Nw8C7hqsBZ6.[ Ćs[<*傡hX`[B~v8osh:29MUÏԀA ȊDFۼar1 &Ny{NbRcڲ5"&SʏEk.J~(DN'cu&APyl#toIGjv1"D(FBiR~!p5 ~ m0&:0:!{;Fnla2ث™"vRm| W>a,ˆo`|fo]un_܊ qT#xNpMD@W O9NrRԮ] J-ĉs$ (^ [a Vv(랙ʲ$rpG6]B5=Wli1K?E@";GК[F7HHz.oq: UQIyh_c/p ĕtpC19SD2zHifkfr[ți뵖' },fSnz􂛃CQIrbv_GQ,D|S*Az)|gEqȡ|GÄb9F]iJHxΌyu施lUUN=~›[,K B2uafC!v+ܾ,Tdr<#4FE HN>[';f]ؼmn*xB[edU^#"nֻՎݳwi+U[=XN_)6wQ2^m=b y%ࣾ_lƐV_.9?@@\C{-]r&VJWI=LݯE٪{m'|:DA\Ex($g4l`8@ԃΉ]uabpfPOi=?E!C ZLPtS\޹ f&٢8Zrq!@>9zx;L@NR+5(Cf:a5tίmw[$;qTU5԰*pf* l&')&VD7=yA![g8}5wA*yψ>?CEW] viqK{Y2jcA:(X>o7@b'/fD(Mrl3]Uw[ؗ2$jJ8|I!j䐟#H^mWpdM`: \Fgu"DLtVGO#oM K# qI?KIbIfV겁} qv-7XpWqnU*.۔wƺh|H,U+Wж~$KnxgbTO45VauPv֩wvi$˗Cw ݤąN f4tg% P#U]):fDJmFbm H/Tc#L;GwDX{+!+)lQ5@UXAU,+/,^v,ԜՇy㹚]kհnt *~4q{M2 9^2Z'.wAOhH@ŊU3 duyVߌԈu E V(do})'s1Pԉ[P{Y[qBƮ`|`[iȶXZ鷩/=sȮ_p<oEOjTIxGQ ɨžp"P8#wT}W9(1h>dJƇX@̽@iL<+ӟ٦KZ΃wݘ˄ o1S&vʙ#tƄӓIʆA7KO5]{-SEnlT5vBbE)zؾQwgxllPM˚p\徥ҥce0X{W-4*#G2M9[V S wzb' aTBo_&藓Aw% @aLp.Pt f7ݑ&; uŮ{LR q&s@*(]h3D0w#_;wcI)wgC ښvK)*mRcke ^х.XvU};jO^Sח6SčtQ<gq~w:<?FZۼ1*U&nIV -.ҿZL-ɋXbq`B=k2WP}NsyVɫ^)Xhe@Ѯi3~`25bŦVoڈ*vǢgPTύ-'S3`-: WZ]U,]Db}]=Z"MDМӫJk.a)W*y*ESl?|PmX.;Ȳc=ޤ[ 2ҡb/t׷(KV*~}[ADx@&rԥH2Y*'DW~Ns#kNɅoyYqYUcn@VmD@c?ezT71zJ54 181RO~kJy%REֳ*ݨϳ1Y8ze|t_ϾN9^yz /r!sg'Z{oSb#m,~֔P?N#V8uXIV(3J$>NIzg#]E-Ŧh)'V{Ꚙ_YL'L"<ä(6Gl?͒NvrQqb}v*D_ۣ1IBj"B 1IL;I`}E7b%?"HBaҟuHQԣohjOߎ~ @rI$bi)'qzۜH+ *{b/2fzrX3)~嚷ۛu֡<~b,|&{c AMEA&^T*0Q|;>x$2b#2IOuQ_OP .;N} =m.L4lJ"'f5xF/2u .842I0֙ 凔g>´br@\J0F r+UC){#q1̥5LW;j#n:CαjQVTY͜1g1 pYME6U M X^3u!U0ET NU |"f-Qش )b[Am2߄rT+\.\i3h[S͑d'Zg`_A:~U:QLps,_tqD^H/wWN:ܯ*'4o|f:+J0Z# {:*c * B%&BrQB^֡>QiS*Ejix"RA=@?Y]L _'e|׎#Ԭ tXN(𐗛BNޒHeb!{BY/uЊ|dE@Q@FZ(U58Y{+Q 鏗Ҵ#o^BF;%))7D77g?ϰSu$n,xDv*6m4Ylmf^Yϝ !2 o5/f5hH2Y> pnA\UyC1[tD0Io$D]xeFUYqhtĨiqx/>@!yԒܪwHqzrtc4A} s"#.'/cV[@C`DbKsj1! *WPZաVEwC*5Y@Ձ a§%wI9hݺZVb')LB1l> 9J1c/٭hѴk@`L;FsWdZ?[W<}r y̒s5 WÏ!Ro;(8AOAʄeudꏻ*/J$ RYD} z!=kDI5y5o!W_^ڭ w? $dm|5Fg!: 3@v_L5 Te]e&x@/jB #hh?gI &"${`zA1?8F'd?a7D;}9}XXk*)kf5O4?lY6=:wXCo^0hS\k) _}R_-VxPUkM1cKtc.y2MPUi-(=jue4\oی c/cb$atWk t|]ssyţ4jsN)*mDoA~)_Q;f<%GQfY8X5Y7/te?R`t tpd#oTURV8O`Õ1AEbE/4vi3Kmz|6A79.q]4!O!a0"̏)(nm}Y襂lpkG&_+>aXy|qXwO\i*K:W{=)ŜH~1 BY'372uʮ;C Dɣ`g'# +QIW[:A.1t/t!?w)>؋[2RSN't@7@{-$O@\ak#TaU,SX~yo.N죤'T-xri*U_`fAFl_1N+e/} | Q+zGROv#'n}D۝IZyO+a˘_nfU[1jf[°t7DC$(Mg=RF^d~IzWNٕE܆3 :$z)ְġ/7F1ŝ%5X8k/z͎D X (z҉m}׻Z`hoꠎ?&h5P.a4 ;F6ۮ mqϬsa's}H&\LL^gkS=>4 aH=B=YG$w˓}{;Z7kSV-{ͺǧ-bC M4}4ˑQBsJS"gUpͯ#,\|)D2ӵK6S'ytG<#i5 7ۮ@g}5z#lT/7*tvڝ bh!#3w9x nUb_֛lN :b,N*9NL*(Z5ڷN iO:ګ"S ='U'Vb#r} Uø -['oS#*E$AU!4?:;өs+h+kYf1 K)05rqc`,!@7R\^V⻟/vo_-8/k81HRk%O%r#x/&ЮkFƂ傂$ **t))껪 굈ն܏Ŭ,~]? Y+ !*>pa:,}i6$MOOdz9Z,OX z؍xi&'ęg2wrbdb3gǹJ  Lo̖bD@3 BL }B2̾iT3U>{'匹녜r jԱT9Dm8r19%Jְ9? rJ;*7,z^no5Hʲ-| {aI|@Q.`r u?:NY`HS$65p4VMv!pfCl{mO҂+$|,nWkco9%"Wh$H&p\8 JXjh)RY * y~vj.}=( İ$黍EI-Isb~[m@<1=R|tu> '창42.Lr@y2)btj?M6NU =X_ec5G*bp+*.tn^)Oٖ}~\p䱃nY_P!KH۔{| F8:QiVcx'E4LMyfZUX QFe#~[;z׳L+ Sr4$uf>a+OMO ZnO+UCF쁵/l̩X$&+wV6e\ע9֞*jr8p% Lg}[J@y;i)Q`NƵǛaI( Sht|nSKPbii0܂rNrNY#a2f)K}TII`Z-E`9gJU>HYfT>a @*fswСjf#%n AI4c]y9S )]q~pt5ܞ,hBY_0KNH! t0 n㠡-J昑!Q+lxaÀ-LXWUvkzo;f%8xz\z*AMCCyH-hS$#ɰ(Hg̤^٘\"zͶrAgiPPG43, rQ͍?38IzmaqsMH)RIj9->aۀlDHP14еB3)I/~teJ>B[ڥ/ fMЊ t³O4m8B~% ]įԭ܋2w-e |>^I-:4UFyO`|wɸΥ]`%t$N>tG2B}r[wъ,B!>u 5`@ 7qҵTp bEjQʮN˽9Z#cA i7 [(_Xy{NFն_W"֘P'D#Y&_˛f"*-lcxX41;ZsgM6}ây5T \bVUH*rcIH*| qWf:e^nW#ʄj 㸒LrI,x[n/ol Jo+YaSFPx`"MV~fcv㞐[4ǵ1<o9d]O%v6jC}-:W{˜ܡʠb#^+_>$3/A<YyOgBsb]o>QȮU_k˘"-U#KePgp.c.L13_AŸ 1G\RW"dkebO tcSl$?,^pܸ)c,7>RA8\v7']=&dȎ|fKbՖk$jܩu ̭ En2 />q^PbZ57 DJF4g!CJf%]ۃ^$HZ<(v"k^L&]0QM yAe @clTmm|Rg#nb/f޳rٸf]a]̉ pDCվ!32EVMLu.M/@D)0SVemW aZ nxѲkQBPt͘d;!fK53dp>BG'gKzXXvub n^ՐI0bNƁIxì`-c5gm8n?u2{ӂÜ?"_qyScs| N k.M9 6 j5n#0X[lBbL: VkJ @MMK֌ 4KӾ5iV( Zz]opY]: C!PCKJ= <# oI4n@bt: đG endstream endobj 1759 0 obj << /Length1 2061 /Length2 12731 /Length3 0 /Length 13975 /Filter /FlateDecode >> stream xڍeT[@p n wݵw'[p. w.!圙9̽?b-gzW^P*0`['Ff^* 3Bd mAP:88^D^]igk G/@d cHm"`;wN6p:LlrFN@M*`RPprebruue4qd; \ANe#h K6@8F _&` 2:9ۚTd v@9ˁ0%ldb3uٚ@@,=/G#kGkBJWVhsrdtY4-fk*:9"U(hzLূ/`(e@H2tW6b fE7adߙ` _Z%\]2;! ¿P] ,BwRn 8&ϝ^IE)ٹ ~CJ7s?*Ur49-I}11$߁ɖ#>Dd^#|@2H:nG3Nߠ^q6: €z hϴNu;1qUv#-Y^oS.zڿzw+݃&YJ4='}]*ǣ MCߟMK+HQа@ _UYNN%![{ ^JFa*Mw`L(Mu⛮<i&s3k,2Ϣ_G.گ1c{Qŝ,AWAcEFi`};~EZ]_O@[@@EUƃփ2ȋ?-u;RXZaDcT=vbXPЏcMutkW*vqZ՛'Bwas8M7(wRz`$4n+&F< \FkS:;QOHˆiB 0v=18N \^$WyBsW6?B0I%jkS+ȱ|H.QHĖ:nEj'cDѻSҟ\sĸ0#/rUHGر[M-}gܕ:d#$ί K$Pldi dTnK-^0PD^vW^ ޗ.J/`~7yI XdY*|#")t*N{g"#(1UtB0C񹴇mah#y?SY͈EGԑP̋ںzUO<'A$ҊFv~ɋoq)4a>O^C⃛6AaOtzn:T'Ue׾05̎H?: Cq>y'u<X2 - ߷of0.|5\s(BQ *}z9jHlȻ wF.R.㚴FƄSs`юfjiBX+Q FӠةFՑq3PY'IP{l8ӷyM(Ӝ|6G- X)umSũ4c9Mp/!3dFw|u[w c(4[t?ͷ[6^DS0ֵdG1 \ebv2iQ?UnVɐ>;ZUK`ܷfᙆy~[' \Z^栋90Bֆ搤w^tnwb=XuEWveK$6lE|rb;KcK:(Oek.5\i|t6֧_1{hn^=4ؒn%{j ^u AnO ' :(?e$ +gOPFs5(F`ɶzL# !>;-9=uH &r' !\p;o ZޖZyL1Md ;Y\܉#*,i*FW4ZI->Te%W2S/Ct-[c]`s~yŭfӛ,Q^Q LI˙|k. v;3@AFՃ-y-N!aķ[! -|SB!0SP6f~e Vs .?Cp_κVUO'Q|V gbb6|V:ޱS}>JaǤdHP] Ah4$VeN^>@ؐ\g04Qߡ `V6~v9o%ꠛƕm@~ ct)/ z Z߯jzŖQ6r' H[G0qY<ẅN(WVΕ1ٹ3(-H2]VӍ"הuvX@G<eF.,=ָM , 4C|4Ƒ_^Dϡ1&Ȥ(.SCT[?u3v]*OR c&W5 m5vPE ȎH>P!X㫲XKD:(Gn٢t|vasѾ5ơ__ASV"D^nƼ(M ^Q::`h{x\ ^rg0bu߸s*s?^_Ե53  ]Žr@G w "uk#x!dZ_F\`O- 1ptB -UjSgCbpkK-.ɵiT5r1 S溘_ ?:iod!7uiE>s}˅Hob8 d"πPq4GΑ#k諓 EЧ墚܅sjusE.+4p!kX#rO.Ro`3\=ENڏ:5 u+8)IxCȷW7NX,,_t/ RqX4Rv,,m|`yLS*^^ȯ Oyb=Qiݬ3<,fAMDZX7m[Χ9#7+TϨu Va(jc>IR<=Φ1DeM'giotM LSyl1O !)\>9_:< gD.Ӓ BkLx05fuἲ0QYϚ x24s|L8zXVy^,߆:$1ͭFg;R=nWtr4ȷHL͓6%VONۙ:8"Ɯ5NX]vJҨ\^k z0[xP#B K ƕ8_ ;OMyZyGz ži"Sp O)bh>| #@B @g)L*uQ:򱛨`,xXs!|COŕfR壒uE;C wVeҩ g]sWo;`)1}xFD0T5k$Rי06dNAjwP!_atIc 5''Q3̣cveKǾ` h?0m\T9R3U cy!)GϮ-/2`z!n~1` tB Z5t.o~:C8X n@||Jeߟ-cMM(X|ĊB4"q"8huWIJ*XR6ͯL=aI!<_cV(X8\7e F^]*gR[d t2jqy<&D 1&l!3(#"sZ0\T&d&&7ORFw>R&މIV(ܟύ [P[7Md U%x.TԈѵU!vL!S(8Y)>khq|f[NL tֱvWhFv_c搳ܛ  踚{ŵU.w z1a>)U~ЦҝuxI?eIETRc4 ޓ@}Za8:krDbj=\#S PEl%M"&ӊk,55+}fV)3/GRC@L dateDŽ{l3hGНy^%nJ`YH8-NiclYG%YIB-j{v sh R?'s88 y t? ̮ _l#pLJAұ)ųxBŔ̝ !8Oܫ#=ܔ/O@C-}_&_|;LLU?6\~䞸k3>};)QliVZ2}KV<ӊD[m3 _^?ɪm~6 Z;t_Ng@+~'1gIO٨Lج4Zu-\6+~$hJfQOO%ܶ!ފ2̉Վ*l^?CS z^t Pל1@.(L Π{^ƛ0 ȶQ{Hj\2\!x(IA "ek7 kpg~,2׾ԀᨻێDb[)pcV&Qo<&A$\'rt*òrp)qxJzz{$+~zM)åLj\[LnNP"&ƕ=ղ(8~ dz@EV%{5\G3>t|zjiH~;8 Ekӥ32DȂmsm|s&86AُX;޵29(BLgӳeŝB`4yfiKbd Hm6SA.TEw4[[굤uDG1.,UG6GIZxyڟw~\T6=%QG[4rӯ{}rXIl8^&z$3ZRD3EQNZruс;YgU#ֹ1<'Oj^ez\j{ܿ4 LC/#V5e:&8 6MRW'-~^ܑŕщE|8SVJi#eeVUsKircJMOY:>z%:\It!'O Un.n!H% A!ˁZ{P ן JD0 =U ) e_̹f}cC%QĹJEr!rI%>3+y2"wℌ^ ̢o@fIosҿZ͠Qҁh;& ~MvTC]Fn=Eٿ:W9v'}>MX `7jWMQLƬ#q12[גЦ{OIZw %zI22#5󒢑GrΪEʗY5aѥKHE%VMb|a,cgAG2+AЏGeУHһ=TuFѲIs.ve~ª*-p sRŻ| u$q~i_p6z{̫ j-6;Tӿ&l|x9fga>&cJ#h{%CȮ2&˶>`ʼQsV,1 ĉ/wZgO>Vj>tpϽ56%񮆱 C&_cʥD,zp3MxȻٚ&[oAv #EdD-2ðN7s9F-L[ᬢuU 5:1izFf "4~{x:@yS,FBi&6S܇6'ǔwӑ3JT}:[ݫQw':?kΡN9+THQ0bi$ S?vm* #ſ ONj(,fv@("1ŘM'uh~(x %zC%dn>$bVXpd45fApݸ(N,o|՘#U"aM)'s-vMG^#O^QC٭l(y+Pjސ4guVأLT)f{=;Ҥ+ D7͓ӽ@FU ݅:ٯ;C%opfsoxd?:yCm~w ϱ& HHT,J@?8hɧG,HVL,4 ~59a1Հ&xW1W<$ϧ w7zTɣ }{G7.7SEiHg)i?L v8k܈0sBt}6~D22:?>χi(&Ū_t,/u&`T_!L,L=b4SW]QF :Ѝstl/ =MDV"N#4zq,[59舨eFY S>nw5 k^SѰnB!b,q+ R.Nڔ+.H)^0+`8,f^l*t)>)E-}ˆݻI̓pG ŪK<-1,EVM憭ah}K۬Xl9x ][̳#  MZ5I0qg. #-CSOٚ]Į{LEۻ636(lN 0|ւ$ "eZ*Š! $d ?BW~ ^IL㘜.qt 30Q]'S->I!2WqL53p%3>B7 DY"λþ" WB '/r+>hA% 3w4yˢ'B_,󜓷,Rxt,ՉE#:]#⼇r-Pr?[:;JKuY$"Ta>da][Irwˀ0]hlxBNCcɩ1<[>q9lH`wϲ@ৌ4Ѭ̍ '7(xq-azvҏ]q ẹ{=ҔՌ1t}xd=[ǘY#ޚ' ]T3^Ab2=+1,5ptl^HhMmх7CdA',l6=n$8%X ))V3AfoRZ5$X!^.JlJ\:X-x}t B Ԝ6M~Aջ+2 ޥ6 :A7SiAA 4=p6up5=ϻpr\\.~9xصV+KfTݦfW9ig$g,\Vh94I,uN#'<˴:s/d^$8 H>Ehkjuoq#'S:q.Ӱ( I.iz!F. 9Ѥ~XLƗC~İ3G \O(f&30-0Ӭz2,!#͹uH7RR]d+QrXyb_mP5M/|(1m t|*莶gLدLd:Lx'fv5`r' "B:bV'&w C5_h=N1Mv|ꁞK /u_ƍ@U5@8[Y;<yH h3Ƣ}&?%$ܟ#g ɧ>&@B/@h޲ܒD$KbBxhEH<-~IϓcY,NͺY]b&'Fsgmc0n7k,] ? !|,Z @%mmU(:A Pr9|zQc Õ N=\;fSuo5c/[ zײƘ XTV|Cw*qxD\I k8Fh3.6el'!Tguq DЏQt8=+o'ބ {xZT˝1#I&K>JumGXB;yAHb`ONVɅi9F T v8yVd92OjpM齸Ei"s[߂jU+>/SN&l+[jsG9Qл= ݺHq+|rGHOպ]2yodv(DQg2{TB JkͮDaj"0 4.c8C3wmPJJh ,hmg G5Ggy$5v-Q|i $D c>,H̚Do{v3?rR+-6̮ J%|x3TZe˶[<7y^6*P2CaP'>q  ÁZ3r3Nxjzt+~;ݾ/Q8~#%w?Xg]ٲk(wg&aC);};{$h;Dz!/| zmLw_M|QH;-Tsv=V6!u5d| &GO,9%J}j^8+R7{K~Y7j pcmA{i@jx">d:5'l#~4֔ꖒ4QVڽ{n}e^'ZoIA{;?E sr=k[0s3/XU{A,Y8_sMy;pP^I%̌8?bͻHz{ \V#e}j%T#*DR^%{]Si4DA%zCg]RiuaEf_*=;/["4YGfȏ-UTr.8 Yڱ󍬕:l4eMQ̪3u̘:O&֎%#)=>9z2Q0G=ÌvQ%̱P:9k+>'6/Fx'ҧt)R..P ;..KB1n;J;1JzmpTh W#U;<0GOHOQR@_lq5>Ԙ dN:";80=˾g" P[&ZlU}gfQ)Ge!~Yf 5+PRɈkZ3Z7w|{Quvwo'psJ$NIDl 5h!L%}ķq--s{(_G2Ê6 A۩fF;9ʺ1F;)UXŨ>qn^!5[(j6@Ъ׮АH>D`i(4%PWӐ"c2o?Ja͡a%^&2*( >dZD=hQĎHJ';K6`4+m|y|uMYwQᨮkӔP.$v1wϾN`b qVU[)k9MtwwX7 0Í,3c'bRt{6[J揃:5jO4}Ђ.8k'\U*ƿOKƛؔ#pDC=9߲K?MԘOCâDZռCA+wSx:3[~@<bEzӦ*lv111N6K˺nH)S`T k`#Hn^Sl.v BA~Ww:58cA|gXZj.fE~:YSiaKK 5ݫz3 }]JOpXxvI.5z}.`~%"1^m|d}ߧ=Tcwvm<H 31Q 2O.s:>z>m +[GJ QAYMʶ:^ä4 Y=؟kE<_͵'e"(Xr5z@ 5a7e]5)u1 y))iZݏB>jGl!%WCAd7ߌ ‹K8Es'(TCA loM~Ҩ8@>ه=[05E n@x&٪xIA63^h]$N?8(^ p""MRJGsQs3ذRkV[FΧps'O_iFfi0B/SDŠv"MF+5_hDhZ1-crr ]ے̀jGELl5G<~=vc|nέDJzGWThӄm[^OBͰ?6B\ ,҇v3v3'( lJ1ٞgc`ヮm\Lq4uGCEKjYVSr&*)b_SEpʵ#1\D P3˛UVuXF>IY endstream endobj 1761 0 obj << /Length1 1401 /Length2 6058 /Length3 0 /Length 7007 /Filter /FlateDecode >> stream xڍwT[6R"C7 tw03 ] ҩH(%] " %!)~csZ߷fg}]{_^aa㑵@0$?/H /$¢E@B<P8L?0eS#Q@ 8 Pt~ ~Q =$T0EupD rܿYW 4HG+-ЃB!H`rD"$y^47 E: bBƋ;Bzp{7 .P[ A<Tu@OEr~?ODPد`- { RRE 0'삀^` :P ̇!~Am"N !x?Sz@lQpapo_+{(vn|0'DEeA H $@#n_Nf np75$jA#^ OǿWx @0k{@}3~7 0࿎OIDX;>??# Qaq i?mG Mu;&E\A [ԃ_!?;Rtqg `WH4()j\ *H0J 07P@촡H[|m74( G@-?_>lQE_.J=.P\Qz1 #Q!j@L@@?]_Um==PN/fZkKojn+TrV)Kͳ{~5IO0s͌rveړ%#4;gC>Y!s)ʹH4Ş%=hjDZ"k3L3$NרּUSM(:e1wb5bscE|1Xx n 90cjkX/b9YXŚFi}xp2 ZHTE-͵8o1!G0g<-Nx}:lI Ec&sXsA$qV]66Ϊ3okb.YnCZSh9iMX{#+= O"pRMG4sAIz [&^-pz^&3c\сi'%m=oD+Ek{UZ\]K-b4'0Xz#ᬉS:Qqˋ Png "eS?)<%C2M@GH-]D)מjZF!&gNHݑkN4dRyd2M扅}Yk 1tmb#Mp Gգ9L Ӹ^䉁ØifԇGz%`l恼GL{?u~dٷZ* C}Ce0#O\鶲LGnKRMz~9ei#涡hϟ|sa>9ݡզFǖִ` r6el:&cВeS @%ӱiGHC b/VD~"J]VM$Q& XsWc ?J#OYj1ۯM:'u+Ew"&LBs 0ݰ>$+jDk֡))O*ɮZb19+CoDXF̽GsV߰  }Gjd"L^WW/.Zi!M9΅Md[֮@&sb}ApP9ۊM,IΕSsKJ;w!\#-)%tipFT'݃@f & %^n›W.rv>K]7$e%: :fSnTQ}i֎L˱kz]#7{A" l81`ڗޏ >&~ʄۡei*PZqՠ*Ey F(A>+ufj\i{[ ,ьk;GS'AG)] 'ҶW2Ԫ'(l- {wf4 ǁ$1_N a*`XwMa4!d8dGZ 'mu&G% 9Np6~jR\剏˜Jh^Sp&S*>_#%ӼタJM[@(L3Mhcă;?#&$O3yj!XPoᡘC[Fi7 ~bʩ>ogNwvqi'N/45)PpeXQ~Gbwؔ1g?ZGQ'K~.YNab>#|Xͤ᲎o79WbqנGVv$uW?sqY|uRȑOq!k܈x~?gd!U#y)QzU679/^(K88-sAYav¾^5`QnW-eAh?G%.]S _⁋9sn' ?=s(o@␡GeicK48H!eg3n.is5A2{ֱ]S_6S צ\E̫Xg#|_s-21g Qf^&O>O6B2׵ȺXp<Qj$]ښY$k'?tWtymшP4==v|8Zgq1~y.5m/pUxl: YEd 䪆1kr0F mUϢJٻ>ŕ80AC͝a,*}lU0SX&\Tss#-={,^cR22y;} 7toQ%ـ]ڶ0TŜ Ux1)vCF MǘN2H'ȻdșK2NNSMI-gq "8hwTge OZ 7!yBC&̸,lǗwW"mJ7uY*_2 V#H%#- u~1_rb*s roF@cU\? *07NҶC,f[ŕ !+E]Ŧ@mXFuvOG>b۫\[-a#ݶG.gx;Ǜ7SKU)q|\K:͏/c:Q$HI{w?dzjltoc~=pt>p)UD,~Qg4&H'xPnk1~D!t:j8tśΪJ;tAcP ƴ=}<6O ܌~w%d1w{oƮMf̤FyUX+Zyn|2ηı4δA%ޑ1!Q_DH^K$]ْ]> ZWW͎ ż^ ,!c(<` 5 GnEΌ:S7CS™R%<ܵK.{˲0 zx޻ "i"h{fޣ-hT I>oȝ9jSōdcX~Uk?of-v£1~90?Y.y$Q̟Btz~1ó?Ljڬ;Yݸ2 y@6g`6Bo `geblK շjvL[̤8rܼe OV3꺣bs5Jwdvc2B7*6ψ Hj{);zByt^_^NA9H~CȳQXe.KΕ!ogaAf+^*h(>; X2 i?9RϺc;`v0A|{{P ޣב}@,T_RZ Z[frr*RG {5; &_&;?.`O^j㠻Y3|0V]Md[S>]k$iQ4/.[Ե[rkbWe=%-YfP0`?ꏚ̜ީc~YDH]5 TYȑʪ3Bo#NQyH]^i[[\dٔ>q]P>>UtD0%FM4K' a`t|I3_w^x:|,=s^޵E]ӎɵ V3'hgG6LtvbigoUn *ޤ;ȾFzG=h"Ic2QؖȜ 56N[LŎ:Go karj.t"MޜcqTZ7u|b2KЗ;mC^I|>HUxҌ}Q%󈔗Ӿʨ-zc%\+KKa52&ɷN#̟E<UB}1T*/5 >6#pvw5Lso}Pp;W5T?ox|8 _#`#,C'GlGa]%зa^ͅ:L#&fRcR[ cGL\u+'aNzoEk#z-n;X HDm@Kc3(R"ҍγqKXW$E˯ˈq̂>vqrTX5zSFZ}ՙ endstream endobj 1763 0 obj << /Length1 1406 /Length2 6162 /Length3 0 /Length 7128 /Filter /FlateDecode >> stream xڍx4\ڶFAA c3:kD{DoQDI$z'B|}9oZ{sݞ,F v[*Jt, PD&`g7`w$;B۔A(4PhzB"!1)!q)  J DKAP;@ ؕ>PG߷.07@HRRw8@₮F0G ()pwxAQC  r5;0Bأ@!p$:nq4z +_ѿAῃA`0P-F@p_@ @ǃ$B _3 JfG! ~ u#:^pWP1<\MP7_6 @o>f ~W=z H"C#VnHiO7thB\&#(;_YWwG0o?@a>!@U@kP3@.@jP;/t_xTzC( #_Ot_>M.ZC#~MXT rw UiMfB3VH h#4?& AEhf׿xC tz/ϣ+ }Q(~xYjSnϗEL]y? ^NSCa+~?v0!ӣ I[b[r&^lRx݉|( pѣ)vnc>`a[E Y<"#w00| ;Wln9./]@Z*W%w8i*1G (zTJ[X|tA[ GR'#uYܞ#lDwj٫0Ά2E`yLܺ7:ӈs mX'"_&^<~($l*RQL:lox @AN1|Oeœ9~]POmj*8#kVb{2S1Tˆ;>7~:0/[SMkI1ٜ&Fm piRb 2Wb#/dBeR%O>LR6؉']c:@PZ+]NMhvWE<ş&6O?wyҰgP5nraCƛMo3 !5ְ"XEchR?Ue?H߽gľ;`W ?$"U:A~؄QDDY}#LNk`ےis YݥY/Ek-/(DU⇧Ozb|]{O7CtZp,G4Xόh_ ܩj)CxORnqv{!..t TRw3[1O~pgUoja: bR͵=,)]X>p1x Byl2e8vaeKco~dʎOlef)o\_E s*, ~%ofHӉq~uuYOfg #oIt3Lbq|7,Eܝ˦ӏm!slM$`Mn5k,o@Dǘ{ uF_S<1 D2e>x?dWe׎OQX EMM>eȂߺ.\?閅`;#;`̭Rl|4]eY|#=EÒ3Io<{lJp I&wY \ow'ПwK=Lտ9$LCGݠ*M<8Hvʙ:0 \ʶUSce,y|M{6\dKSM{8{_8+{?w4D.t!t~xE@Xb3q8r2&[[}Ǔ\S<\޹` ԾѶ[6:#׏䦸'9ge(B;Zs*l Pκf ovU|U K\opkqfZxpuֆ;F ~Svs+UUXs EOf}' yLoSTq_/`%o V1Roñ!Y JG)- E=iMˈ)A0KhX ^K<,DĥY)˲R2ъ1_GhhH"Oak5qlLZBm''n.\(a1"+v me6 to☆I>X S0b i8WT8-VÁ4jWݢAef}æjn7/+Aivg|1T$WjU }wi18N!d(O5i@{6=3^$P4/U06ĢBCoVVFN߅# ܷ{gwfSz3>hkn}V^[H!<,rHly韍viضI̖~pՔMlL~/Wda S\dF^W n aQ2¤y@o-4ajk +БX?dchO3Q/_S|cs0(Rf@K ہJA+u S+9@~^86$"E{]u+f~Q( _p{=~0L¼fy~^ SdaĞ+}oW剝0p/,L\|3@s5&JmL5iU$7I`Qx]3\R8ƁD+<+A+c}Lt57[ )`⪠O|8]v2MKtb/npfdcq'j-(^갅1>se]spԹGstCraUDA@mO%jWj&#*יٙv5ؾ9M ,MhtWfAd/ضTǷ_0'uNJ`Q KoSǻ)pъ~0ӕrn yyC}fd| ~z@?|$/W&B˝;b4j?Dy{%R#[k.s?*7y^zjrڦ5[>e VpC鳴$ɹ,4ba_I?0.UŪ:PrZ_W耡d-1 6i GtrGx>-2m!=g gjZuOt-5l}oo~0{|}Ь&g۸$!xJt @Mq灤[G[]'ZrtE⟕Y}2$dN'1_ SdN]bN/!-b\ӄ:3x$3iuh LuzVkT{m>8֣A`|dqCWZ3&&nouҗRz<;Nui &e7q1Ox?jLiY+&eߖwCVs,#^WbzKOsPÁdkeudEMUocL!Yf}6?M3΋URswX3}K*:_$uI|c^"7}(W  $t}@t8^?Ͷ317HB,2ඡe'DBӽ/?9C6߶ UQ`&9<%5; XxyI+!kaO& |lqe `tޯ@+S#刜hc׳%mt`@.^9A(y䶆ꦔ\*e>Do O$bYBO\6ҹsؼ3c1u Us$vNs"&QvT*v~}VG.-#iQy>H;p8ɒV['}ɵ*ndŘc} {q'Ҋze"߻xԅz۰ؚV4nlp!?'``{8$_@mg:HP|TM-& ,bۃڶ*lL^bzk,sjh5$j,#B7{Fz~~^KE]艮oyLDcXE'Y?O~wp) Wve9dvVC( o~|5)ïyTCF)MZ KЫ %^!l ~0M*i'6S{gxYڼA5lC%Yv4¿Q16I jc],~3U-݄JnO{F 㡏 kc;򗶼zVjOb^Gb毕Hh#佬M3{,l ~dM Yy{`M/sQ'!ga[پ>I3l3v ;dp|d6d/7}ݴ^~Ы.=K;xh+^co=/|occF(֌sN!*"?hz_ZϼJ=פR7{)LjXSO6>sADZu[n6\9,W6CgNV{a<| XP4[v] oY 7xd@D/x. KqSֶf|ڴ2xMwrPc#s;$yb.=a}Ky~NǷ1"ѡAPpSkL?JMљ,O6 EͽKf%20k}w}:xGG Raqq~~"~gKf[QƊjL`HL*)P+xC/>ӽt_W՗`J[P{b oq똱 =NΤa4/ed=ɼFK{ys*~ب]"?~yPS'ߝCO_I{i0b}C;DI 7nAk^nm4x){V3/9rEN(3ڏE?|sAcg3+UӈGKB!MS`9~_@gKKVX$D8X0HG1%RG )Y灀3/)bL#m(]KltV凐xWӇJ9fZ"/!8 kDKeC.U ̅iv qЋm ”Ҧc\^Y+4Ĥ>tRYx9i" '6)Kvk3gVӥ&+iIFi+^Ûe'z[ ـW7't(mHXXؑ?J^4Un8j:/ݥUçJ)L%g7ȧyHb8$:J)rO=g. ?yՎ gfJ-h endstream endobj 1765 0 obj << /Length1 1481 /Length2 8465 /Length3 0 /Length 9458 /Filter /FlateDecode >> stream xڍtT6 1tt 1)")"(t}߷Y7}γ3. "xyDrz*<~n>,ff= /; AEs6y⁨;xDyDyx|<<""D  @ñ`.n;{>Zج""B2`75 P!;Z0k)Q ӓ 熹Isyܽ_# @mlaԇB\*sLXفAa>a@Ѓ `b ~<;DX5`@ ?ܿ A~߿]=(u7e48n0// O'zXg-:D*U`{@K\0B7~OM忳?);9E? gߌ#@0 ]u *4@+#Wxm kT]9A`-y/ÐY;>"iqf?UZl~3 pH06`?b0CG- Ŋߦ?w@@^@@r^`k)XCehE '!>ܞG r132m?b.Wv x͗bDfm9F$vj|?T[[M,6vd:_=O9]Ofl+ԗdɍ2I!,̏,\*[!3>Ѣ?Dq2OpgFz#v`yC [ISK6+XȑF]r jw*2XŞ~Md-()Q"P|5Xqgh%BU?s=xrxZ>g:q48l@NÈ N|elfzk]`<g{J"lԁk`++Qpb* 6{ec5BսJ*,ȱ۬G5JR$fZF` G! 4fU(>7?!)NaO+l㣱K]cͭ9ä?%FV?_~ZYUqʔTub`:|v.#>Oϊ ,*r+h?禈~`T(Ĵ":ZN؈D;S[se*].5Շ4H%Tiցv$b]JT$D<&lLCۓFTO _cwfŨAtBFc(i>=حzɧȻ0ǚT\ZAO%gK`-*qn9@s43Ͼ\+q{sPxQMVa:$Or~AL&6IOi8*c/\\э:0q''q l3O2gc^,N(*. C)4479ovzUXt^4!C]r!\Y$QNRZUh;%0p^4Rrp#}G]o6T 4gl5b:r]):2G=@;a.E;@qYG/@}y}ꕓx^gnU^-1YIo0NrSjOnTLu#[gnUj|Kao#̈́s>}٬U8:>4Bl1S$ Un6 P/#9#L@[ԽWg Tn"l Cz_, 3Ť4kVW 4w|~g;ĉߐl u B|LD7vdOrlXY637EYg t5p)u/?՘~ '#7iTԮJLT"?Zณ\@!-4d Q9^Q9uɔ9- P4D/">:+'w,4Rbpao TdgW;S~vb#"o^=}S&)bEgn3ӗ;n Xy^ʨ4!UeFiHq՗mMO*2$mī]Y;-).>g岴",]dKTP  +"NF:?mu_4 'ڋ:<<ΐnM!H}ɏ0 XrN5OL*|bɴKf&hE47yU8<;tJ/_D&VKC|œ# RYSz.K-@p[sw+jvƼ͸y/#s^ln"7#Di^k[RpqK",zJ@R렪eOwN Gr&첏;mܵl%~RC-3*~/zSO+.49hN-R_"h X-=D]3_ÕU U} ?n^V7ɐZY!J,|߬)ō^㟎(zLaK QPwO2 qKp\ҷ97*ܐ}|q-\^w)'`6ϬEԮ| TENV]3L.^Я,K$iOc&>~PD uLXmG{caDU۞CdP4*B07o\s} Zr]"t_ulژo^c/(j[=f$r2[L=l"»2°|a7z]Gv`KKwQIh˕pj>n/1{^/SZ/$L̳h^yצ#Ek ރSƥ%yʙ@>p yv;SnTL >j2:̧%6#~W5rF|Adm2?ꩋKƖ6;j R4HJl|C R֬nJ.?eJ틞U+ء(C8- LHư(F'>].,@H7՗iC VXzj*4$胸CQwO5?08oudZTrLPV @-XUX\ HF%Z0"O Q#C NEx$qݥDJ@y+jdy^5X[[MhwxH2m60r:Pyg╀5aBjgZ񬡞]Velٍ 䒯cp2lCyZ':)7eFa а~@Svt}֯G( ܕ{rzmz 0p'ޑqKm Iɟ߇sx.>❂Ւ=EW)tH;&7L` 0:dBjic,%LgOj{ӇNZe/ k1]ށ4Sdo^5!F >+GqOڛ@PD7qe@dc\8V\L[Y?N;y.*jNxFyO|-w#g3B1Mb=Yر=1)o#^uWsHϢaϓ_zV ߞm¡BVՓ87٫sh R[=Yo@54UViUFdb[nDWƋ%֩_ZlzxzR[ c-wLTꄐP*V|=K+& vR6rrfD<˙JcYQpN=Rr(ʄ+Cz aV`Jq%QT__bʜMFYݯ_G͉  gE)K1:3a^[tvtNn#T?[Pl!`3Pt?a32,N&Id>&u}vIeKO-n`fkGa˅6?:fWT#XۧBQ!4ԓ^\vvŜ"J>Vi* &G?,o~f CȋjցW}Uޣإl#B%[$PSSewχToz3%#3;r'ѝ}9g4~O9Ήxl]s/)G6J)(Xwiȓ,M@ባ롵(e&D2ϒTMSΕ\OdgY5Rm?!",XZ*KM׃S2%3[(l=$,oh )7k&2}7|FȚ]^OR ¬ͩ\^5-ĜՐ:hZZcFyq8@ 6{%fVk6j5` ? tPt lO}τgB*\j~eMiCo%;2 SókU^&f%is1l ovb<ĝ wEa#hL,+]{Y*%̻_Y 4tW'ϺQ?@|MKo 銢Fk\qa#8L}kݬ B~.i.m\A&JWZ0dXB1Cuu*մ YocdpeI^ιv,ܥ%KA\='j+ [` /l>Vс k4g SF9,8;S =\Ňڹa}Ȋt0P;¥܇3 Ra(3G ѕ~:eMi<$8$!!1U~,:\ς({+o zTin{qjJ%vWjYJ>Tr)Md  ޙH/ԹmN;ր%^lP@1LH4qL4(sI#'v>cAjz=R$܌,6LCՏ'o˗E_+6liy٩%'rsALۈT(!{f's2R:oB~k&uz?rˉĹBިSC_'{1~wDpfߵ-G[cy x5bRRh|ʭmÆ[4g׃_ ΐG'TA7OޜhPV Xw 1(D`{(F>=Z dzX(wL>O )gJRݩRQ ceWϳFyOF;&3F׮f D{1kx7{q~(Ծ|CŤdhx/qyi'TtѸ_Y`W8 S~>bɉ]-_$l䴔Jʵ4}g鈤cO^~ X3ç`h:œFt{́M/_$X첊%}vshkiݨOvnF Oe245"ռQi$%46}94+v?3ڎIߏFEE|)ZnW/ixXy΁,rJ;)"x%fŮ #$gF6,AS Ҡ18~8V-V&ʬ{s'zIrhVu>m)+!%j= s/>M|vMZ^NAM1ܗ'[//*ں4W8|h;) f% IԒwߔ]HyF+Y8V_l7Qz#EeڤT%fœ8iah>#-7i+zE> stream xڌPY w Npwww.A!x =ޢ i{>gfQ*2ٛ%\Xyjj,ff6FffVDJJ5 rDJ 3ގ Q' X&f6ȸX,,\Vff;Č@fyFR daK[S _a[ ob 3TMA@xohlhd!@CpXT@'7Wc[?1"R,A+T]܍d sڙ`v@holljjo`l lE 9Fz/Ccg{1lW ae1s6u983:l~+ xDmmv.Έ9MZٻyanrtJc!Y]l#aj@\\dAv6v\\*YXf S d;:X 4 e Ͽffog-fRVTQW""ov+ o%c?Y)mgn;Y*/a:?Ao,{po3)f_7# Wo6ۂl< x`M5< j.Yw!A [kl@v@%{gЯt2KL~ +'Io4=jb `nkK99L¿D#No`LbI_ `XL+I7b0IF`>'~#0⿈̧T~#0o`RժF`v̮ٵ~#0li/b[:g 29+gg%18ɿ\)h33bkyp1"0 Mw^F8]\opn ?bRۻ:6u4'j;mXz:X@@pV@>Z+;cNp6&n7|2DzOS۹ښ:+-H |3N/p` megG}L6r%=v:ظ.,}Bc%w^6%faG ] 8^ߴ`@[ Mq߅.*e\,tx]pp=`ο8;>!GpP? G9#y?緩x#]b_@)✽)_Um׻„ ;)w4Si\Qi3םnW^ - ÛWgh37Ә/$2tG1l:?gV+X; (t@_cNQy{EbaX# =ՕcqZmc AFQ5ru:Og.!`w0 6܉L-^{"̵kǵ^ú8+M"bOapDWܝ>V5=VGm'ihX(kyZM ht$ԗwُsGuRe݉Hli#!j Q3e|=gh44"EҰjcpx74-4MaewW# VsofNNL>CvKIƻbaϲ3ж67+T+xQMygOWOd \Mb !'Z%%"!ZjU[pkէu->ZN5caע﹑.vfSHY3W#wOY;_u]& ,GgZ^E~1LѬ(Ns^J[>u_#g9XCwc_6XquQ |Ġ! Qct 2)qPs%E|"[jT? AO~` CfrEw#n0AC4-kg.;SQNM\^^S,D4MigQ-eYn͙bpgAyg7ɖˈR;b>[rsx^PbnqD:'Q$~K]7[;^ L{9"ܬc%-i?2 xS c:Ce(*DjDt >Ռ%[AatS\0|#65Tl%7Dן?ouVߪTs<_ A2@s(P[Vz: YO )aT-74yW,Bo ]G~\,uQ{Tcmr45m$Yj4ijl %z^}HU6IVT!N AY\j=ڄ6e% UcFWyj e,n~D0- R$pWӑT=?׽5e>zhYM-NN*hݘ6p{ۓcz33 .!v_G}\y<"GcHV ҈;-l/hL'CmSqÐ8|'.g1S/UV٦ Ɉɪ#} #@1>ww[^ XxG1⦁9$.3&h(Fxc?޶-h@lDZ_{4Y)¯' 0F| }0/20!0K -}Xbp˖z\@sd*];D~:W&ZڒY90ڔW$,gp18nx? h}1m՘ٞ:xFi"KpbZfj`u>~ .^EF]63'ffndT"G1+F؉fI>(2/^LMR:i 1q:᱐ֽ0zn5h(0[< 48 ~nuRy/˞γ$adO>Xc3%N5'ÜdBSuP\D]!$͞PDZ#=́O9WBoƴ37o:WԏLޏ4—CP7Aa}Q@LgW_ _\ G΅)vy}$3kx^0ɧTK`7HI_d熐q>#eDÞ8N2vgI^āZH b ġL ~7øeBWxgBy:lWZ\`=T"#/l_} VR5 B/V'q9 j1SF Oo*_Uc+ Eo?>kS%@/a? A>a1F7II$kao8sAobjcYi}_gmrq=Q!?Jvs\yW/ޝi)y:<2̘Q˲FdD~9, 7ꯤ6pތ" MD6(pe"=1>8,9z"hΔ5|ڃDk;Tw;Fs: 9q emEpjPS6p "0nI^ڊ>Upb0۵k! >Gi2&S !fARƫCU3+m#^y^Hܓd };LI *5kt+ ,DWoy6O3'>R88v] ྯ08_6H3wJ䴯j mh\pJT[}$+M:ns$n/μ qK{D6 97]R˴SC /Y@!kԛr"L-}g/Aޝ cM4v|:'"w2jR8%ߛp`MNx?0}W(ɥ'Xƣ.{~pZh;#.N8!ICA3[WxcWެ]` IsESDuE-REUǶUKt׳ΥhRS.6dε5Gҹ:YeXpMGPNۛM&۪-lbN?shWN P9a(^o1+pt5jAk>)7jݗ&y2iGguz3A/O31|sܶQ{L.z-ׄ^?L ML^@, 2tynIOW}R)/$,9b(8 OKxGpW8bK* 6Zo.k8^6evzyN ~%oYu |U< gT3imaWBWOȮr@v;**J}X.fM?'vƹ{w5B/W*x(݈iGS=7x`S9b,gW#ntW[(Qs =UV {‚  ~OMpi#*I;nM(L0a*'qR嶎dޠ.N` 7q$BCt6jd φnN˸y ?åeY[0y~V:Vg=V(&w@Ֆ N>}+z4Jd TI,(e\1w¯nf E1hC Em෕lv`('#f9(:֫WH7":c H5Eθ]`.rITZl(|*AG̎gmSN[Ruin^{}Ags8Q`mj`u1r71\\V(QѫkodNUEvuF~Нy1'e(b!&! ;$}fF)sB&B^賈]o4m+Yд3 PvM3Qn tg*hh!o͡ckMT]<'oX[`qX8}6zNEꖅ>87V tjq\1++e-nЖh:֬5JzQ7GF%{F2"Ė3XȤ|Cr{&IEMeӥwԃZ`K蚍Wiw|#qVN}_ z?g/= S5\i0< %N(.VvGuF& 2]vZ{q.߄6rQ-mx?0y(@ZnMOI:nw4prmaECW;#M/ +Л2VelE欈 lч 3Nƾil۵s,z_Ⱦ;AǘgbrXBrS吱whn`t{?v:U=yd*Ϩ~CYIKcp*d\@_3{ی@3t{&M7:C鑊Y?gZ:[vTk8Ɠo|"_.2t}flL]ۆ"pR+ ]*& ׸<Ǻ ؓm- 1\7 =fY[[zsO"*P) Ư!ǽ8TJ_ꩤ1?({61gߋ7P^`fJ>wOƭSj,zZ:k}o´'@ Y;3u6SBǹ‰.S.M0ͺ-U ʖW"MeōS@eX|#cxs@8x&"g<@^.k׶e E0lؽNrvV Ҝ[x >{'5aOArOl/it^F`KFӟP~ -B>6O:|;pٽ{(GHBVtfOEThkay [Ns4t; XdK Ԟ$'q]|T{AFվ?{]^BTEg΁Lj|~e_uĜdApQQWwԬtܲƲ&ps9L!~SYϧt&WAA,M$T7*Wv5.O}~GG}S[vVj|01owл͉Z}n4IO]ђl@1-RV&ɰm뽋1{ǹϝ/fX6!;̵6 ה<Ч۟]wU_o|Ӈ\y3yߡ_ߩe̽ƫqۚ( 5W0o0vg^3T^{5߱tQΗAUf|S?VD~&&t fڏ`*{i#Ӭq#@fٲkL"J[Y^HBᐷzJ^f~nU^v]a:*g_oKKb3nXEc\LDc{A0U'(C5nsbu0L K+WNRgb*ڗ+ӽlC]} В̞@"ĄqA'Nˆu5ʐߓBS9@Njjzɸ[A-D dB|̠k!5)dEԃ]܋z$=!n:$cKӒRRDϵf2'$|z_Tet>MWcT0ZTb=xVsؗWW28`?Nqp\FCW=bDv^8iBw2~M9լ{Dt!{"+aŸ̺@E3caDb\Cep8?kRlҬLob ILi!\C-o¸w6,m:Ǖ%s& /P|}C,?N%j&F*]\zKX"gYSŹSuiRXr'V/Xgq7ܐuu,]EPF(:>N(XP}lUӕ 8!×br =,Yb\qCh_,A'T*I*]LLyԲ;ʆVZQ#*T!oTi('}]yW1(JoM $IT(2+Y>yZOuZ*C7i-E K?rt<~|l{.(մeHJ)zt?_{B4*m=dRux(M_~\,9wK$e6flH?w0^Uԙ}V7ݺс!^Y!+u2y+0y& kR~_  XJkSl}-;C"(AkLe%GYSS"ZQo*W0}BMb^Ũy]p.40:{mrezns 㻥@MҵiZdWBl込W 7CH׌ OPhP7l[jwl$3iƣA 0cnҔ"eÁ!ӡ,3叻&^nZxՋ~W@Fs1OXV*m~70ѝuE= )o$-[S*`~lI S6F$g;5Bי$G'7yUo|kmꀩg ii=OtU % /eOtj*yߑ4X7cvO0얙čV< p8k (\4j6ʇNN[0,*˦##G;k4q#M-Ve+s_i[N 9{Pz^Ty ՚QAK0%ugKXk͎/8F ˫,nR*rX佣O}zaPP!h*#:,kW~ s?&L$+ǴUv*s{ lW&t l@B9kƼ:tݶelm*gh.Wj v' + e~]6f?5_% pdyS"uXUӱZ`s84Q\~uQ; X=Ґc4)0}> K%9", Gn[0 FAok޾;(W!7ߡ+Ea;6|u2H_deX;<_kZ~6> W*ëVKӋMSW"y;u_} ;gě<>@)^"-EXt"% Z$E9רּ9{}l|U\Ę/BS$Iۻπ-Aԭ-(~(!N?%Bäml[!,cN2k|Vy$#UbE8ƷRS 7 X"Ƿ Ø/ZdZL:j+=,n2{Zz%2E.B *!4AI V/-n;5 6&eIDQ#՘}[ *@O|NrrSRt~WT?{j BUAs/54'\j7c.%LH5 {\AI'MLPb.Lj#4XI32Egg p!=Wg(r^p&̂cNRZ%i'Ǖ}$  /fv[}Ha~Ӻ\;ly;Wäo{+H3n[dV3),Pv79}ɂxhg܀Kz5,)EM3QIPZ_xEP.8u3 c$~\4p?hW ac9*Wѝ+bFf .lw.̣>>2Sr$E#o<` D + mڜ?J19׸Oc^6PvEuJ= T;5Q?odS!U{qZ[mZI-ʵ__b`γ /g rA}9U> s !BȬoQ113ڄ2ř^x;/QIU#1[km JxcS"lp u,!"&nMx4ZJX{֩0wj4<\Gժn1p*['eF}WÌ\ӉQ[ȄEM*1g#u@i_A4Ȼ?9%]F`ԊZ?0c>KMƹ⠉e?.9/ _]LCf!'mX["!R|XZǨ?a; {GLOYֽw@bVN5<%=FlNT%uDTa$ͮ-`P[%$6W*9P[}dp< f7_1PbӐ/m!@xoqa2FH&O4wڀI}ӻ}kNJz=ގк//~i%8?-PI|ٵv-.ӏnCg /tŋgD?IJ G&}YIVxX_qN*k Q \4Ͼ4A7 MwSJ?  APUR /j^5G*kbIoF+g2pJ|H=i3QP5x߰~Z'QQ u[7MXӕԔd}#5t+:@yFqRgW⎩k'1?? VQKTU + 0qN H#fNQ\ye -Nid;e=RuSCf0?lcv]K쭑lg2bvmrv(+U1 7S<9ʂM}9z@G=3x4tB x:a=EmR(D]vd?'?9)V\3,B4qiŒ,$v=ù,$LHmIo}蔅nԡ[춈&6K|ג/ y4r7S##rD&kch +Kc0X֪r,iM+w!oӚf+L=O XvHCBnb@*4›ٜoh84![ZjE~?Ÿ$aI\*K$)#Q0:w[ =qGqMA 5ȼ1g0D8K!`O&bki% f(q̚t`Zܜ;&z ˞R 1,^WI̮A#Եs% WDکKΰaql#uxV̂ 2=@kfP Rl[Yg\IHޕʝL>S#$o]H5W^W;hkO s8̝JhSMg7 cT)qjRYd0Q{ 3Rᶊ_rlK+E*h*֌X˃>VPLExZKhGERn)C(IZ*,ފUf8{aDN XY?= (ɿFSҌ9a϶\ Q’S| X9:w&>åzqGC+ԕ󆝖5mu-llsKFMs-۰؈ǵ2D2 PPQ Sb5ʕi[κLIU6^Tٿ"0=65OTZh!!+*":5̩29El-7%>Axׯ4SJS&9&iF I@:ş"|-қ}/7a\'e{AAt ?h@L8#]*rkeT@ .xcwgQEIy;(|ku&VSlZVĀDOZ~Y#SQ3&չ/pY5|W_Zǜ>*0=Ķ.:25s.{*}_7}w9cH%khQȖλS񋯖︱DiZ}NϷj0 ''|_DF(0rl6Qeq>%3` !,.xH,f5R+5o7X%8ӇN!)$vE?-yƙJ8vcwPFޟ# 6k2idrFK_Hpγ m0Df"HC'Jb!DK vi]r]*TMsϏ@4MQdI`ڏ[LPsSrw)riJ&bjف|&@o'[._>=o 9x%9\>CxmUTLoGĨQ=:ꇈחb o2)Zr0RL α0N5R?H%xC=4`]&seYI(fG %A81o4GCΥĢ%I`rgˎn, +>,2BbN"0zPV-/r/(u3SsI&1csRvp;<@A)L}.ܵ@IP smAy)x@NjldjcûfQǃi,) nW1?Egj'즜i(Md׎Ik4Ç0g;0ƴk\痲IGP|4Z֫<~r_lx'D65j1Pf}B$ b niɐkLI)^3KѦV3RL@EdKbnK\ xPkpنm-@kOd0ro0 Q1Dqd~m!DP!nޭ%!ka6 AFUsNpGT ZOSzԅ9Yp1>QtGbCw濇֏ZeRNLxL*\ljyO_E!ģ|HYۧ!ui/2GkmtB*\]qǥ!?mWxH[*K߬ygxr#yäE[ⵗ\2q *v;.49<5拣RF&Pofcui$:Bn▤$U̝AeA}Q8t!%dodC)X6dapd%/K"=4TjC ~^pu}gpɴ^Aŧ5侲yN[̫n9ǀ=?,zl|>&Pq I 쭷wE2cW^ -5>3l`<<_()["7~(ER38&:ְ^B <[mԹqWyټYi3aF$y`%n! Ww/8=Sn5.K_L "m4Fu^c@h)v=jfly .DJ _%lNT1EIZ6_aZ,- Ѯq\UyK+}ByPbY@l*<}rOjGs W8錽~d㸢@ S.sgw&j9OK?H Kbzz#6WҐ!/h:1xC0k&$׺yY/,X>} NAScc.d1kKۇ,@eB+F/fQ]l( w?))VZАJOS`13|CmW01n|.1L~Ŷe{TgY'~(MrI`k&Q^x8 vl WԲ^)v˾8{޺`FXPe U93O[hb(H,ȚS4 HN8VvGv9#* Hf:lxS0ڋ> :e8M"1`A ?JF7+-Z9q~P^hV.b5tׇ{x4ͱJX/&԰I@`fףqiQYx>(8݀S05HႽ/,ލmw,{y\oΌޣ—/7FLJ! װ+y SΏQX˫%R^ LW:ZSp˦v!][z̴uEq؁ʖ>%&5ۅbO&i2YjeN0Xw=yj38>Op=گ}V/{ ]މ#:߼'u { tsb2 ; *rw(' 3O 8:ûe 6 ЛKs/zsd 629D:OGj p:R|ujm;+Z"Kߥ] ?wjǶ8ay[Hq MTref;-*ؚ'yB1Ac>ZƍH`3k.|kQjei];4r/jjd%zQlEku-BSɠ솚AɮgBdN,yẺ/ξUƆ#^_nQ#(G ug"n陒Yo:IЦ!Céj!^t1J'AcOAtFq@5%P d9fk"? <1Z6M,qm{a ER7v[6W/֥%j$ZގoH kvT4 3f( m-t֧ `amVL6vpdf= ܏5m5-% -r*F<9bt[$qU*@easS݄^!HXZ+, ZBPatt;BJĸ|d#M R[;kL>xgw"|yȅd/UI *ra Ɏ)/6Ҕ4p>c\1TKtZT+GJ(D-u͖+Ҷ^C": Ot)Z`t q&[É΀bOz7 ꏛjNTf/Ѝr2l!, `R`bE]WqnHTT=ϝ{>c߈:~nQXkf"ٺ0F-W2~/=t^ȳ=ٵzGfaBF?g3P[.=ϵ['$8}kOA8p_7ҏh"i⚎o-~7iQ6I=U)]ePqժ**y*QL *XցKyJ`wM2H@)R)h"zǴ*'&^#'GG ˫dulN7# (D|ڄش_JX[y/JfDK$/gcH _[iWx3&Ȩ" Ҁu_{77"*Q|BWT~lstGt0UTQ[IEVFo9E-gX\ÔEwU^ ՃRů[vjS˺Ԋ>U.-FŜǀ N6>x͐ꏉׁrExGF{}<Q69ھҨVpsPTwm3Gn`ъouz7uJ]t3g R$jLKPBCk^.,>HΰV}rz۹Ef6dRI 񍈪 TdWĭ2"n4呡 #3H]+ۖ7au~䤘c,) vSٟsiErfُ3M},Z& #02 N 3̮G\28ŞdDH%|Q٬KcP7,XՋٶkdbpf˭"һ h 'tVgՀJ?&s5@m񳒸M#.MSp|ɏ)ըBa}v&H.Lnj{4P& ׈IimƼ?E>sPu~%X=]=h2rkW}|' Γ8~Ui@WJ9{H[L8bM5{5b1$<-; PP3׳$Oh8K*&]$ `ȍc@k<"0xq5́+qm-ȗj@Qje`l)32@/}yUpH >7)O(#1]I\ܨFp &_REք6rh09՜Ky(~QًR+I3l'g: _[xjli2f6Ke7z^ Y.U9l^@T0[vw<< lUOU(`_5B1Ϣ*髟[?0eĖHؕSkXTUxz^h+z34g(E{q@ y5`c9;;@w ^/x=CZ=kzmTOv0cȧ79Zͅ([,9 endstream endobj 1769 0 obj << /Length1 2127 /Length2 13081 /Length3 0 /Length 14352 /Filter /FlateDecode >> stream xڍT܊wwŊ;)Nޗ#kX 3{f'@C,ndq3 $ll,ll(44Z wb ,/IW;D&eSv<vv^66 \R +2 @ tCtrqغC!Β;@ 4mM'K翖uww`eb1wtcqrgxm@7' GsG_lAn5ݽ]d A<auu!ZBHk,=\!yAF?S Dd)fAԋywBxfW7kbܐ mikeg-)]~OIӻ](KS'K7!b{v U)tP+ƽ$bjb"2kiZ_tE |6z%p񹄕 k"cE4o3@! :sƉSq| NђT)UGc>RS~WFU~+< QwS^j}SSc]O3r3Qp'!LHU^*1 Xg ^ƧSerN 6,&؉\%T2UV%+Kmv,rUz?yFEW)A! H`.ɇYݛnCQ2R{wPӳ6CHh#ޕ:ʶsJԜj0+'x3|0skz(xDw2 H 5@=Y=nJm&ӷ^ژzsu1|n8(E@vWވ: Cx.(h2*8>(pp/QzSz_&҄ώWn * A+<~tONZ hEÙÞ:՟MZ̶vsp}H MGcCޤS6MJ ҍ'*[hc99mbry9r;KʏcD $`lD{AK O2L+LxEXqc/7.c) vꊿ50!TB銊_E֗#\FeӡI謽x+pgi'v B C/u2Hs+.qTvhOGʣYp,.+bď yov§`|-]sY-cZ{\F$b6U|]$Զ։eMKgShW>ޟ7&v QHlaEs֡- &'IFAkl_Zy )\({J$Dgo1W=?aysyBB?x1ӦW`~VcF3#R7ͪdoAPI7 (>c/ d gHÐ0Vrhks'`k" .ǺTⱽ ;6 *Oˋ8$[)Q?7't]U˧|W`1>qIeav<-TzdR/|prm5 Rٛk6"48y_dp;"1%h!ɕcܡe߇r*HQY| ֥Ŏz`יj0 ҈-Fډģ/I&7ٗZW=Q=Ro>Eᯇ>rwb^c2:/Ry>>T%s[)-T35P'87`/fڕ jpPH wjE2˖:zDxAgDZH Ǚ20lj^V Y&~S?RxfV(g;K &S'?\x7s̖n74RFY=\t eOjVa0g2Kj}@I{N#w4OT9ds/'x!ľ^AUnyRip|MWGϾ| m:obD@ &vAUS]YTϲjmk+&\F'uQI>8,ݕCU{W ElT7 IqXu[k)Y pgjZtEn}`F Gy"M߬e៰U3Ljh29aoP,v NT2sj߁Qc<#Tc&]zγ7u4pg O&!"^xΙ&OЄ {}p5ػP1$(B\i9K+7bF_NZCW'p0ս;.~)Z0ޑΓy@M%m'v",}d$n8kSJ-=Zu{RRgOE5\b'Y1TD5ӳU+%4r_U95 k } 4R-J ƈ'4F0ɷھftj'`)&w~OqB=Ŋ}gjkG1ѲYyE1HZy3GX J8e1m9z=UbZ)3>џLܟ~9dyBTtA~:S76hT =Y|ëHc28gUr^Y$Rn :*E=K/_TM#3c`L&,{iHȓ_lDDk}?1r:'Ο3`22`Z.t1vG~##5[vjY"6Nѕi8ԇ]'|b֩!aM@͔w66t3s&H5 v'.YT ~uqW*ޚ(٧l=Gٶx"Lv'1j]yYq:A쩝5xL{i%+vP2?üĽ5vu^7ԅƲ+ij5o!V7ZP^nr`v?^ _CKu(xͻog"0Yz4@Yc4SCpf 1NJ]*ollwΗ?h$e1wh^ E(ߝ/{#`:IV9B#lR|/y{|*ʫPF!'P%DޠR8'BU;sU7ӖX-mݠ@]V B[" h5JzAFfg발|M9}5% -F6xP:LSɔ4UdJa\eߪ< \SΏ>n)Dynt&1#Pa'Het!(oi!K&u`'TkY]!lex@nCk 0n9s74Acv`DSBBCP%pEGVT?6]5II h,.㨯x0֕ KOVOY!V>lSo!I'_w HdWIOKH/1GBoaBQF~ߋMC6 'CЀ}[]ʙ{Ϛ=dr[\50.N|\Ni{.ZFy5-ȯ;?rZi6Üu`vT zM·^`ҿs4?Sx_u*++ϢuyH,w*U<iH yP||&WJ0֖Vbb/yHnO{̿5ۜcż[&XS]0-?{⾭ޟgjAbh9 ]PД ?QY`++m耦JwJBXj"*#Ao}bcaw0O+)/9U-,y$jx4w?oywYxG_w skY}iz4z4L1Q4Ҕ:$;&C_RݤduimI*uA֜6etMo ;O J 5LNy1ZiA4BǏ^xP v"kQdi֌c(9Ҹ_xE4Olae{߸/͌q[f VJx޿[iWZA_D֋r%~@`jٮ @{c`Ơ\G*RrUݭ&jt ϔ5MpݫWE|zk9f(#_|dj޾y8&v?~90're0TOwVR!f%'>gbɶ!Nin~ʃ0^>kCg:2Ӻ꽧a=^7S* D5l̘͍3,^',.EiEф:(+b3=KI}4e7\*]ٝ]ozjѹȲj5f ܧVEXBYlUd4f{,peqRRfҴJA!hFttLՙ]v3pX$;ٍ (,(T02-v{-RV!r 5sroVFH7ewݬ4IgGO&V-Zܨb܋VǦUsq*8ڄ*^w)stZS`mASp7u˼kOS(c-IF@0(RKVߊIE~JAEuM( ]TəL>Fjvް'͚_i;؀ۧuUK%:ZĨ)g:͡x; [^e5)7ErW~| [(35aX>]l5zEӇ(n Dコ{BRk|L={.]nN|nIKqiʒwܲ(7-1Uoj//FrV*nȺ4l'<|o\\>5Hn/vÚYZmPlNs2(WSחES99BUѳhE^sZO>U&X &Y/*3bɬDuE.Q0`d)sa_ʡ(/ÖbXx<4t[,hCp8:待nz!{OcE5 8 չ˰_y 6J0 i+ y*ƏL+sl̷1lW"Mi1)9CHQQVNC]76oƋ7 V]5ȞL&+,R@cq"AiGk9:,҅?v&6X(St8dnEy.Ҽ#ݺ~'V!1DϻYv;EDNk^9b$S`E*n,RLRʷ/ڙ78faR)m(MJt} $Ykng[rK`)棗1Kx4 *#/y cTdڐ$sYJD/A+aiP 훸Ѥu#W!M=8|I,Ņ7L ݟu26YrtĒf] |y}W(kqtE3?aE,lʛW:_pX:g3v:ϵQ^&4>qP "`Xl֯S_@фAW9#TAH~y/ぴQ@'Tfnq}y29ToJҵ z+q`=B]kރ g tJP6;-NNLl~iAo\>^~PݜdmWRԒxE`pǽ2+Y9c,3lB;eW.PxNA94(Q5,!ztwƷVB{OJy%(?T%2א`xPlx\ˈ>b(b740}ֱ׳6vw 'Ė{ջ}L1ǤK-R >̈(׻) @"F;\. ݚ}_oF-wƱCOl>JL+}TD?W a+&Dy,dHe5N2SCxDz wt՟NsE4$g}UWsqK`|;Kr:/Y/A8!ya;!ܷ3d-Ab$TʉG> xu⫓&c(X4kpꔯ JIQ8Ø Ŝ-A۳o~Q"40k'+C#]7J8AY9Fqk%'j6~ ﬋6MFi5>˛ǪΧTny6|LCd |Οm*k6=<</*jG8^9>)VnZz<:^!Vy;Ej;2lwW%g s[>Ln5#ـB/` ;^S=&+'Ce= CN~"aFsx{i.WVLlonp4&:3H"v&ahlÛ+}5 #P$-~hu瘘[ߧC淹{vQipuBQouqJ>BAlLDDAc `iro= 4."Ug+R8/ϟ#zX+J봜9c bGƤm5vsn1m0:$wP!ʝvrxK'RT4:WE…od (hz)vPn%tkOTŖ{5uI drA5f#er8\>r97JQ{ ;^[J`aROݎ.{{E?dԁHm"и:ކzS=S){}B 5#f~.~Oj kK8d8A{Şo?ƛaيCCl\NBZE9t /B"af E"\ CmQtmmm;(E`>I"].hKڥ/w[/UL5֙l˻ uqW7zUÖ.p.w 4dCOWpAUmz)IFpjNHc|N@P%5Z(.v JO|ԉ;] "VFZAEx* .o u ,6_i{;Tp= e럏4jƗa(,Cn~7mUhA>k\t$Z쇃8FW,tHj F63a>vcf'>$>n+^&.B#{6-W "X碆9-k ͹^\kX_!b\27to40v_ٳG߱ G%NGu"i) MZmjw/z;Ak(,?s/OG̔f{-ʴMA.A_Dѩ6/DY.]mZh];eᑫsmY3'HdmǪlO&P&[79Q"|:9Ѵ2}ep036lueHomhݥ7(u Smb7hP2bĢnS))vKe'na]լ"1.$Aܢ9!۰YXAԑ Q]4 ,o|[VSESkp ܽF ?(}Ԋ) Jj2H '`7Di$߹Qm*@ZGw[y ]>YBd)A4S,9~ a꩞/c(4oGW6S=n%R6d֚#c7EDTLٽ}|xF:W7g0:{s3D0pDy \1܎rZN/H\9~agM*irx`/Eذ²7'TZ|\]}c*јN}q)EhfA`[1vTo)Dps>M5MJu2 V{C׳Y֘ȭ+ko6Ym+@Eg׽+m tn͑ɠ|w_&FU~. /$KLFmCb Ӗe1nWD7 w0FWU)X" HXxJ@y3&.SxKXKmK'^`R76/Ʌ]47 Cү\˺c^BMXE2`:&-fb}O19R(omb-NUW`p2mE1ޫ7kڳcEDR{,(=rfVKVLL8[Yn ]{,+ ٪4SZfdR5O8+ߞɒ~9bIM~F*k'§wk!Ő`Nh,1= Lz(R+ G z݂~.u%0txn*/gD.5dz+"R6Md,?>^@KUVzjaR|xwj˯b{cXU>i\5e C ݿCG;ȭB>F%dTtJdMrKY=khR?WdpMi 7$JhGN  Q9} ~8g˧*!tKZSkV CvI}}gA7;*fۣqk6o׿+nD E,ж)%Rd g5נcZby7ٕJy[w[ .NC_ +/I,?m-Z΀5ojuUV,c2.Kɕ}˨Mazӫ[jmˎĉ\ɝWzSV8+6 |N->NITţ/!|z0r? z;N7gțq81pO]卞r~I ~ endstream endobj 1771 0 obj << /Length1 1380 /Length2 1234 /Length3 0 /Length 2088 /Filter /FlateDecode >> stream xڍSiXi<:ʥ$E A4iIcYPpEqpTEtEPDFpe8 ~ު-"'pʉ Wǁ șagd.RTbK0E0EsEU2q7>g63> C U2| bpxَp-GIL @SRTNQ "BvP |6;>>˕,1J P%JQŰ׷P0 (T8.,z o>'pC0,rk1<H0 BXr0艰LIdp M0TkQ)&1d)1M> =i?%r }}D[Éx< D`/5*T(&ƀ-px]PXfV$1AA(nM$(b$(a5 (R&&|@01bX g dͨB 1 hrVRC\- 5uLJЀ'Zl=!׾#qpP+x!.!ުq}\'f8 Z(`9ą7?]J&3PrL#ш hPSɿ )^ o4ŨOihFbpiӭ%fm&"8mmsu3;+r w-Ml#=JղgMQK%aÑbciC0n5za˻FS:N~鵪sNm+q~ŞEʼntUdpĢ#Nbv|*=Sc$I}ç3ra72f*8 k}sV}Tد+*<>{${\l\mUƸ*&+96zCѼY'TۨD2[ENVƭ6sn3k-lo\- (>;:1nn33t;ЦO ߸{%DXTFOA-"NSBvUʯbz>>ض&ЫɅ-'أJ;̐h#f>|sƒH!٪[{9p߳6)-GW6%,h,c4l{Үs?75nmxq>an7XI,o?nq+fA72 YՈŚZR_,%O%y,à5^Z|\/M֝l;=[VO>low!/j&FXq+ܸ2&lFt453SbV^{{z>e}stc9~h8"cm9eM^GD_2aO ;,96y~m&^٥kˤR:Cl}`ٶtkHo1 bkkỊ;Y^I!D(.(lն}?ڈ  endstream endobj 1727 0 obj << /Type /ObjStm /N 100 /First 1005 /Length 3659 /Filter /FlateDecode >> stream x\[s9~ϯNMѺߪJBH&4%ۙovnQEZҧstn: L0bRZhaxXfЊc֧\TT ,@Ȣ> P46tUytс`<^XA8%M^Ӽ MQĄ#StA0%FX9(rT,0,H TiϴRY"J,Q0FY@(ii.ĸhs1#gFJ0Yz!`qPbA5LaDZ墆P"jFfN#"b-̱/`HsPSZ9A0'ua.FlZѤ' %!F(ŰZMxAT kj5I#`>eV a*Zf\ymX:Y%ɕQDzJ@$RN稍+ɺ7$hE4Zc0TzbO,{ !tKbm+CZI't#$mh46tKÄFՠ*gm4ADX_M*Ihw?d|2.Ez>O>]9c,xǟ *T`W򦰂H@}v6㧌ߝM/!1N6!ꍘV dak1],qaZQ76rGj;u,Dg7+T7XSYADn4z H Mo0-_1ŮPk%]A&T[9[X!Su#dZ~KUH, 쵐j(H! #@ _` m! #I]"f) a:E,VqKGL țPLzE/17 t 5LPgL`M=iՍ Gj z8G1mtED` Ax zXe}0"dox"d@"=5Cat-&?ka"B-qzWHHsJ i!d 6bh m) s@1l]aMو5Ci!ؿsY^g͐;! bF~ŌsNei%ηm´C9B02MD)jyƁ18K65lm0hBd`kFk|5T0@r w|uaTL Eru=@۩!1ƴƹYO$- 7H(!ot?oUs>i [BT ]Yow*܈T8]@|F0l0+߹ sװ5f;7bƁDƬEhP5 ܬGt2FBat҉|f ]>xkҕ ѕM]umox+)~x[a6݄9PbyswkI9f0+|e_rruqw<,Tp[!w?FWU̮ё0?MOK,Gw?+,X.7{m̀ Eϥv:.(L'8kj&犆fZU0wLKȝB&$sI)8C[\|jrK5Ϙ&}Je :KK-yWҸo~o,>jwC7T %5b:IK9_Hч93 {} \R"u\D1?}W?|\Э=Y]'.JO3y_T%hFy#OrqQ_Ӌ鄗O1 po]S2f9O'AĿj=[ 9 `[UZvyB߆$H>8V$߉ Bۑ!'gIq=E\_Q=&(rΎEO5SQ$.5Zb/=) Z-de#ϧu(/ߑ:].*SlѬ$T˰bDkK.wo/R!MOm{n̶rWVh[<n\Aax_, EaLv1v+tzrl?=f!ɲĆߧV]y5 yy|ȳ>V*2iӟ'\$=6TJq&(q1sYŸeK26r[9pW+#/=v?^g`s[9gLJO"36+}LT8OHk W5__gme>:z|IX3TzB< VhR>ɣ#mv[vXl( K|4yGvuOU S6LlMǢ|#\w}|[,qaUpjTcm̪j #V>gIzWIowo8j}*j7ѿYo|Gٕ|]VnW'Grxr9d*-EfV,!)#(Q\΍je-ZAhJ~<ɨzwsWltx5m ε+R"H+ZMj\[Q#zhY_@[%]p ^}? ïoȃʃ앇J? endstream endobj 1773 0 obj << /Type /ObjStm /N 100 /First 966 /Length 2186 /Filter /FlateDecode >> stream xڭYo$ ~߿BAaJ~; \|4-p-9}Eߗg$v˙}pld8k,fȆ5$KOhDks&h䕐!5oiCIPM,)O HnI 7 ˁ'^eZ'PHb! 0cx;Bv JRb $- GdH8.i#V0HXѠOd0NxPb7䔥*g!KjH$XɈy/nY!MJ:o-g(d]D^C1k bM;$ Y? )sB!bN;Gb*MyMJzsr%@P Gْ$e5e%At3G&"lw0YD 93 3;,(.m 33R*0s E y+.W"d"p~ѻL5*a/&)"KYb.7&_$/rfM5J(gRL J=eZ͒lXHB&51d%@*cn嗛5g7g<]m^1goxss7nfRF/zϿ?"t{5v᫯^[ȣkT4HԒ` EsۿNzܫbg38_~u7WC^!&mK~߃>m> _V>pc)ݟr觻*;PF,Fԥ'݊!Jt <N łF<ʩnyD)FI۝lbkHHJu+Q*nA#Rܕk\R.j*"QD-<#Be\5t *T<$"]JOJI`ԥ2CKOj@- ԲEKEZeAZeAZdOnAΫQ$%nAȧPi5DZ\IO"hPI)eA V.1x@5 GT >q958;i~Em0?9?I>=_˅s:\o}d/CK?4m97 wH?}zcF9#so&ӥRͻ.r]?nRO@[C\dz qgi b,1z}?jZEU;c}K06zPpZe@0=j>:K- Hto0Tt {`mV:\*$]+2ĶJo*֭ ܪן_m\?=}j**Vg;,v<bXQbBm{vXvKG*^it UxxEHt9< T?D!PjCmz]zTMı"Z(]GhZJ w0CC@l= U a4Ec 8#Wx0W}@E6E32f^ֲ3{ĕkTzZ ՂZ`#m{U_@:HHu@׶  ڄKa\- 6BJm~O㭤p3SQBi ֯q쟭c7\c53B73xvG; 6 q;=hzexnv0$y#i 6mWϺݸ^{AЦŸ8ZΛ+t8XG/"wb4)2(r7'vXx pLXtqXW/;,Z*4Xa5|<*CZv}8q)XҴxe2n0Iv~$]XR&^դtyzTMJ(˧=uX$xV1 endstream endobj 1780 0 obj << /Type /ObjStm /N 100 /First 884 /Length 1794 /Filter /FlateDecode >> stream x}͊7z`I)0)>pOi{Kf__?ijRjE~ҨZzWI{ `2wb?(h\D}&=HlaV);`NbT>0maNEFT,NEt*RmabEx,HhlmC}2l1,)IДǰ V~Z Rk ,dxD`DS[B44gUU,aDbј Zh̀+rm%C wK@%8`X Oΰ V(N )[p<yB=f2|g($mZ('} ZZjw?Zu0Ѳ/-\n5uj6Iw->=_<̟>O| ߦX]z$99\vMnuH'qZy\ZmFТLn8hDkV ZgVϵNkά˺tԮ0ζ^z5&rr$_! zoC5K16Z ĥC]ZT5"ׂT\k\N1VAw<^axե'K򗓓ȖjYKH^œjQv-jO+E \x-ʴ^n8h%Z5ݺPk +'jW[9=yZ.)9=uHɓժA+O5;-j>2ZSg5]fU+48g5]fE+jj곚.ڪy6On m͡zmsp9dۼ;}}-=p3s߶ܷ}ϸo}r=9떑ޜ:6"k:pc 8#:\=|k8I'4]&:f&˄$Lhi\ jf&˄j;,ل&>2-Za^l^DeEAeZZպeWViZi2jqJ2q-jϲ+E ]ojL˹-,A+㞝{r2ٹ-{vy=9㞜{rO{θ'瞶S2ɹ-{rq=){r{̸Gc3ѹ-nj{pa=1{r{ȸ6-=p~&}}xMMp&śś-M77i[śdooҶ܇7./ޤmp]É_Ir_-ާ7NoR-:u} gT <^VྶL] Zw(-pw?)~g08fWǬs\OyNyd?uu:uussݢA+:^P;&9I坫ӕUy\x^S/m :߽ێK/?W.ZSg7^nby$~˔B9hǖӳ_9!cv6Y(b61zpq:gx_KJN> endobj 1781 0 obj << /Type /ObjStm /N 64 /First 592 /Length 2106 /Filter /FlateDecode >> stream xڕYK7Wh\GUqęӮQgViJLT7Lorl;)6)k}zeCOZXɆF3dC*U\^[*LHH|W8F*…3@r&ŠR||"'S@ dLLZ lBM"e2YF29cVdK&G&Б =e&<-DKސ䔍C%ߡr̍$!MqERRHJʡሤβd T IVF\IE%T`!ydMINDMKMyDZoY"SZRjK4 NIQy`d8fySXyuDĻyܲJ4?teL FS$ݱ#9D_c 1ƚuSH;dDZ#_kBPƊJ?"hĤ+81Qc_n1[eu1nhhDtaXr22et p GHhC RUSv:R*v5&K0M cc4,FO3ˍR\ͺ.c\\+1.暞ʫ\0沋t˷r]<%ѮY+c<ڥ"%f 3$kUV>Ӓ|`8[E9$U*y3-iWLJD ,\3O `Y3ca)·!.j _t9d⻯ӮaEo<o=]iP}y20Dv֢=Nȕ+އvMnky}a;olwstcx8/ݩLvdu0N<j̨+7_zh .$ ?˿0ND(4^Dn]("7]MTK:yVDH;Cp\tO1"""9"Dy$_qDE͖/$}OSnn;8~'Wrm]OW-=ϧn~=?Cߝԛ7#ը|Ge^Ozw$IVQ6 VI endstream endobj 1813 0 obj << /Type /XRef /Index [0 1814] /Size 1814 /W [1 3 1] /Root 1811 0 R /Info 1812 0 R /ID [ ] /Length 4208 /Filter /FlateDecode >> stream x%[lY{;Ď$v'N8qĉq.ͱ8ΥFUQⴈV#GBh%@G>0U Bŵ, -ERZ@ PioļO7{YkEQEmE(Gq5To|h苴y36آimk-&]-jmv+J(_G>Vmt 8A8 A8NS 8 9p "e0Qpqp L nIpw=pL`̀Y<s1xXK`U;xx @EojTKPߥ|p\#* i}^8h@ x*`Nv -s 0'`N9s 0'`N9s 0'`N9s 0'`N9s 0'`N9s 0'`N9s 0'`N9s 0'`N9sC0'`N9s 0'`N9)@ 0'`N ymQ5;(VESQ+F tIph(rه#`  @vfVmt 8A8 A8NS 8 9p "e0Qpqp L nIpw=pL`̀Y<s1xXK`UO;xx ꮙcd ;Yܢw%Cʰ!0 UU xXC!C9r8p!C9r8p!C9r8p!C9r8p!C9r8p!C9r8p!C9r8p!C9r8p!C9r8p!C9r8p!C9r8p!C{`h 7 *P@ ` ` )`]{kl I:@78N~p\`\]0f-_  $,@ $,@ $,mGtEq pP)a uEjXmqE -ziѶ@8*r`\{8MK .3lӧx1HKp D/b@K /(k]4iu#H@qV7 Mw@㴺% ZqQܢ(6Fwi5ZĥO+LcmDxH+EQ1GwSA'ZbﰂXKrl+k)+6hV ځ?M$?UC'?Au>@:*"{tg|d"gP2|@d"g3C?" Y,dL @7GK 2#HF 2?"ȱ)#gDF rDƯA,d Y3>DD~@d"' @ Tz? B~J'DrTgOT9N"tC"$Y@T(~r]FuM*< !*iF rD9@\Iw\޿aZR)ZsJZM.m hy-RV*S5BwR1HSLY8K ͽB,єXpm|+;?y?UP*NQS&Ur78 zAEokc=Qe|Eo.Z?eѯZi>zoV?hѯ6. v\(vZϫYFavLZk|qZ,,gE_'Ejym`٢8vY7tYnM߭]4=/bjh ڈ|/췾mܿJEɰ TGt(7~oVTZ/ZƟwUnjJ 6tT=ҍ _VcLzfM &O\ T_*?aM^1d5!o YM`jCVb?CVӟCVӢVIm5u_G endstream endobj startxref 400824 %%EOF arduino-0.12.2/doc/arduino.qch0000644000000000000000000045000014777724260013105 0ustar00SQLite format 3@ %.v  oA $ 3 ? oX''qtableMetaDataTableMetaDataTableCREATE TABLE MetaDataTable(Name Text, Value BLOB )t ##/tableFolderTableFolderTableCREATE TABLE FolderTable(Id INTEGER PRIMARY KEY, Name Text, NamespaceID INTEGER )| ''7tableFileNameTableFileNameTable CREATE TABLE FileNameTable (FolderId INTEGER, Name TEXT, FileId INTEGER, Title TEXT )t ++tableFileFilterTableFileFilterTable CREATE TABLE FileFilterTable (FilterAttributeId INTEGER, FileId INTEGER )f '' tableFileDataTableFileDataTable CREATE TABLE FileDataTable (Id INTEGER PRIMARY KEY, Data BLOB ) 77#tableFileAttributeSetTableFileAttributeSetTable CREATE TABLE FileAttributeSetTable (Id INTEGER, FilterAttributeId INTEGER )33/tableContentsFilterTableContentsFilterTable CREATE TABLE ContentsFilterTable (FilterAttributeId INTEGER, ContentsId INTEGER ){''5tableContentsTableContentsTableCREATE TABLE ContentsTable (Id INTEGER PRIMARY KEY, NamespaceId INTEGER, Data BLOB )x--#tableIndexFilterTableIndexFilterTableCREATE TABLE IndexFilterTable (FilterAttributeId INTEGER, IndexId INTEGER ) !! tableIndexTableIndexTableCREATE TABLE IndexTable (Id INTEGER PRIMARY KEY, Name TEXT, Identifier TEXT, NamespaceId INTEGER, FileId INTEGER, Anchor TEXT )h##tableFilterTableFilterTableCREATE TABLE FilterTable (NameId INTEGER, FilterAttributeId INTEGER )l++tableFilterNameTableFilterNameTableCREATE TABLE FilterNameTable (Id INTEGER PRIMARY KEY, Name TEXT ){55tableFilterAttributeTableFilterAttributeTableCREATE TABLE FilterAttributeTable (Id INTEGER PRIMARY KEY, Name TEXT )h)) tableNamespaceTableNamespaceTableCREATE TABLE NamespaceTable (Id INTEGER PRIMARY KEY,Name TEXT ) =octave.community.arduino   %$#B  XX arduino.htmlArduino Toolkit - a somewhat Matlab compatible arduino toolkit for GNU octave. ManualFarduino.html#Installing-and-loading01 Installing and loadingDarduino.html#Online-Direct-install21.1 Online Direct installBarduino.html#Off_002dline-install(1.2 Off-line install(arduino.html#Loading1.3 Loading6arduino.html#Hardware-setup 2 Hardware setupHarduino.html#Programming-the-Arduino62.1 Programming the ArduinoLarduino.html#Known-Arduino-Board-Types:2.2 Known Arduino Board TypesJarduino.html#Connecting-to-an-arduino43 Connecting to an arduinoVarduino.html#Connecting-to-a-single-arduinoD3.1 Connecting to a single arduinoZarduino.html#Connecting-to-a-specific-arduinoH3.2 Connecting to a specific arduinoParduino.html#Querying-available-arduinos>3.3 Querying available arduinosXarduino.html#Basic-Input-and-Output-OverviewB4 Basic Input and Output OverviewNarduino.html#Performing-Digital-I_002fO44.1 Performing Digital I/OHarduino.html#Performing-Analog-Input64.2 Performing Analog InputXarduino.html#Protocol-based-I_002fO-Overview:5 Protocol based I/O Overview<arduino.html#SPI-communication*5.1 SPI communication<arduino.html#I2C-communication*5.2 I2C communication@arduino.html#Servo-communication.5.3 Servo communication8arduino.html#Shift-Registers&5.4 Shift Registers8arduino.html#Rotary-Encoders&5.5 Rotary Encoders>arduino.html#Ultrasonic-Sensors,5.6 Ultrasonic SensorsBarduino.html#Serial-communication05.7 Serial communication8arduino.html#Addons-Overview"6 Addons Overview>arduino.html#Addon-Introduction,6.1 Addon Introduction<arduino.html#Creating-an-addon*6.2 Creating an addonHarduino.html#Addon-package-directory:6.2.1 Addon package directoryLarduino.html#Addon-package-_002em-file66.2.2 Addon package .m fileLarduino.html#Addon-package-header-file>6.2.3 Addon package header fileXarduino.html#Verify-octave-can-see-the-addonJ6.2.4 Verify octave ca    L1xRAn0#^P@Hñ*pMbձ#@(-}YT*qw43;;:V7|1NGPH$gZ 0#c-!4?Rg!(+VKf'q؊jxڤUDkȴd&8y^s5s4z@@ w0΅*S^x:׽:D+,$85+IY ,X+ 53-8FdR7ټGoUY=>?Ǫ$Mcc(ړq(Ia hAR2b߱QIcЦf?So`Bwxw80 |Ύ$WuɌ8͡H"5|̙@/";=9۱HU( B=^ۋ{-w{!]܊fk>v2"W;?A+1<`-bc ?'˽ޯW|^?^XaI<^nI\?`l,KbvmŞ5cv\Y;8DX4!'c_P=o-=Gvb75ܺwfAD_ ^ȣ m> p;Yr?4w(Y!ɝ,//pi}.Xa|pxnZ -ly-B>j{tsrM|][47淯.> NW)X@`T(< r\Ntϱl,aYE=`#AFri㘇U1ns=C1EsvhYkϥ޹{6Nrσpi O9x0n^7t|i ZY6-,(rgbgRa@~?y!8X $+119^ ˣl.@i_1K+4%cOύ F66{'3oƒ+Pb#bY=-8V5yP0>Cb^ ދYଙgw/2qYQr/Vso?Zcb57W~ND;8Xz/VggD3qqT:zLd{'xN8XL2P촯ދKɑ۽c/<셅x@b)4mSgcV,^Xf9Lr;ԹBx8f+&^/<|q48eR˳pU)EoS&A?̾j(QJل' l=7apZ%L{Tgi/YJr<:*Qgk5u|>]Q0X˚MY|)- AwW Kp6;Y1,\+nsތGt8c"ZMxFAtoFy%UmΦ) j aɹJbo|{C\5raMPR&lyҽsc\\MqyCX=)Һ<-/4ޟ':G, EzѬp$f |cAug/jrq8!Od Ag" ƨܽKB~x  %wmLa1FQSnxK$;?ĭ(ŮYs<WJ4A:|xAurMR3_kUd a0՛-_M.suZ^̶E$HA.dG(ɬWؽyuY/-a460lŇM(@<1 __|/׵o% zmpqsϵ6!&vUh3xlFЏva?,Bf-PmJ'J >C Bt\՞3-!c Z6eH}l֤l F +䎤Mx7bVah [`*Gy8պH-ae cA \pPa5-Jj7$K>!4]ܮ1#VmLHi=b{tvM|dkB!Ѥ)F>9\5"o  7̖&`!V )#} "?^lUOގΪ#9W/[jA0:̈7^`|ގ kBU{6PWTǭm(Y%DA){s+h5hMJj/a_m& ŋ0B75@- Lp2k۫|k4d[ꈧl[yB1U "UFV=`0UV"J!U|  J\}&)*N{3U``C&p=4w G, l@P!<\UШ:V6PlOLMhNlW| y4XzWE"=O\Z7g тVHB+\i ]~JYp䔲UXЄNPxC:T:{̫,1o<#هM7-)`rvgˍ:ĞEU! ۶Ѡ*H\4C+),bCMU[bBy)WQ9,BoJdQ<2O dGs8鿶CLPDTNJz%eM~"p;s/5hhGg58l4yl#F-ش{ID P*72V@XGm.?$aw!ѫ' [zKU-l\-Qz%:DV7Kt" .ikL& j-VnlZK}]eLI'ҢIJ ;r՛!ie 7}LK-G,jl#%7DZB@lE{Q:1n/-@˪jK8L [^Ī.9\d-p);q4# HLM𵖄±B6 W/sk9y>݆MC$ [#rJ-,9w6'Ʉe>j۠IP{TcY!9#Bq|sq?\\APoNarr ޽H qy;N*q+jO吓mn n]mW+`O*1-a}hebcčc/8'|B͇i[4hri{ZѼ-Q (|^fT4u-R(>4ˋG]U,|E -]Ͽ|v< 6z7~}s)C*`y,6{{u2+0^n *[Ҭlhoe. l2"_Mzn0T +^T F޸3.*^8MWMVނ@FpxI/0D L#CA.Ϥ s=7^.5 PUl2lDVĎ#{ԑffsDz8fz!6-jRw$}':d-tp(~RF?7tII]` i{h2Y>o䐉ߛzNHo刉zYQJUz9f&`؟O&Gqi|<6h>s0U-"n2՛WeOTd湐澶/3Vw6<_xd`a-4Bj>J@{/>g l eu`-/$^X;&uWzV PYIel*&pa #܁ts3Β;ƋUyV\fP"jaௗ{g 2f{K9Z)5f0Xĭy~/ |޵ŜxZKvf嫡R(_\Ʊp%#isIuVI"H<zvڵnSV1?ډj~O~ <[@/T傢>gX`. 57C~"'pr>gaRœX=3?L<16:\] WzӦpkU*ڀXK9rfO<|p#`tr\rxDתiXT:TU)8un2A\\nBJD0"bV(fR|3-UYV~zx,69:_dJW𔽺t~|廛p$!݄Mkw ߲k z 7%\ϻhT0y ?ݞ__N]oB_. dT0]0ugKk-E,$I cܖk },RG\v]& *pX{iYjpn\vڄN_n^l.[2un=9$MnA&$^쮴*(Bgj>5h'd|-JZri #dסt9$8^_\IniGAEy=6ZG1_{x3leP˸.CT֌PG/՗Yzx{qg5SG$g@gJ"Vap:Y4H1ssuEΈ| _^JI^./,\lvNxE֢3϶إZujk6T*L d 6/]<"YĐ&rAL9l*+4&\;ytF<^X98=vԫ̪*~tur~'Lp rbP4iGmt M5$;~"2Aڔ] )p rl*IEg4-:N`=fL0Bkoxkv󳖌6֨dr25J,=$nBp –,gw=:0)0>=3s#4k`1[PBU.Uo aFVP7| 6mҸGs2%+:h-p{sՇ }A35W9ARh(G xC0m}RFQ m^c6jP58]gV fLrK Ygh wq1b۴ =zWLE'9Z a+X_()̖nP7cu@SЌVeRl?Z}ƣQj[CzKi0\J`RWlk)sUݤDn‛{AiqK804_duؒW܉]+$MZPu,W\Ogz' ģ]bܽOmb<,N./|y2 Lad^^[qK\$DsS,EW#>p8I\Z N`ZKР^!h AK1VeLCv%.S . 2EH3a0m*Wds%ei}fH:\DypӭV" 3v,bqŌ<;4)U:X،KHKMcFghI&;E/"tnZpiH%}6J1@ƲkĖLl 4e*vzLQ#ЖGpaj8Z\Y0r@[H2MH?L-DXiP!oBƥ&:o2youO(S? v z* ^23 4% ٹ.%JƧQ*(Sf2 o3Z5:]2z5Y]wF4C_glq'* :θ q2 GFy"`PRrTD!p=MD^-뢹 D$iSTJDԍl%B=GPX2(R葸` YT./|%L&Șt*Rӯ:C4jy1SY\IܜGnFqȆ* yAֈQ^A7 "F\H E9VT@ ].]28pڳR_Mz^}-A`;]!F!6fzBP)R ]hLI3xC`UԖ#rgQڊ#@Lrt)(<~-Aƻʹ ¥beDZA:O@S]f! Af搵[b6ŵsp oxAD (Yl%wn:^iZ| u XOȥ)W:R we!E)z\x7Hx=O J`kUFxܫ{rYWדp n :bnWbhibGilZ"[&Bw祼S`tuD be;UT-sыiȸncK a=^o ӟ %JfA3zF n aȐ@ pA!˃R6І")68 (,L߷YؾoQt-DM \Yw뵐Y$K}( Hfv\Oa\jߋa y`^ S}TFQ̉SDlʄUtJ?rHgS0'D\ nB|{9:xTx)ݐXA"=sU%IZ=MrC/$fh_c"ĆKLF< *dw}NDZͫ TT9 yTɠn]8Z}$`$q L>If r".F=XjXe 2OXTP\L50@{ʃ`ʼnq9+"ђ<,ya`7 jKS o /Yg>^w" `սd@BlvZd^2}g2_ f {:=S"dT;z sߑqu;GkvɹL34Li4{q9{:'X K=^O5\pZ0n_3#`!49BDצ D[TʛRꗔ5wߝ3_? @zjd^hPc2CT%KX vYDap9wS)n~S:h)<׷1a8֐>@ B)G|[mfI bx`a#BDnZ[1a11ҥri 钽d yp{H*1?t1.l2&e׿~tASCӓN>wA@}Ay|oyo3{\_cҏk} FR2V\V< "Y%όFRuAmRK< eVóC=C5̡^S=n_G-ciBLVz_E.E%j(*IގŚG$&KNB) VtcYnG6CPD[aG4'jaZYw EWE?+r&- " NϴuWw<`)@Ìn@f076#aШAM{zfٟ<}'NGe*xVUMhbi@ L_ǥrttj ȝIĽ Ӿ'g_^i6)FG;hݸGGv|V2~pXǘ~C|KM"i-W?0 #HJCiӲ܇)h1vNf~%b[#*zpg+/Sk9Πr_Vmj/GXgzYȭO +|p+`2jЕ ^W$q5k133t~5%<ۥ"^ _R)q J**a4orD+܍DVyl@; ҊyIt> jՊ[:IIx/{:$N1oiq?#s(p#9W D "m"):T{VtaS'4]˒g}yFx.*\OZ&jmoY\WYM e7n=naʚӐib#|O΂춁o*SLqS07TEU1G̱qɝZ~}w+>n6%|'rKT_|$ɸx Ne2>L'$5-ؽ[Q|1)Z1j7uQZ-}@^YeW WfX1T%]e6y~,̈́ qK]t-6]pxju5\qMD]lጛ`˄M!YǛHR6 UFg'0q o8`^][饔-^ݽCt:EG)/ʲLEo95=<4 l`Br2ĚD)[n4]8C؄Ξ[ܦ"wzf):2l[ JOY) &L}W]]aKi,%Iwmn$؉y}OQ<_Ri {<pU] xjr:H@AJWz;::BrWs/xgAr?TҺyl*7W˿J-on'>-U'YRQJ]j]|CU!=ʍbvћTtgk ӾWPaZv[.>&E"4͔.M 1!j̖= 1EdX;<0J$=")"'ae2!T kQf1aK,|NilHHnH!! 8>7f~3. cʬ6(i4hn5^_wo۵al ֳޟ0#&K9@{z0(MQ=TqҺiH70n/꣡+,_&"&A~O&w쥛棖WʗƦZ7Vgj$n!Re)p -rKw,YQyM0dUF#ubDVhW)r9'v8GȐw/2`&wb3t4dvB|//ć7W/~>On/SσK7̶gW$lLrgDX"~\'zd#?l AKo^]߼s ̈QfX.b- h@AAmgq%O5(C_s_pAm2ӭ/$,H-ͻץD6a>s~⩇5PՒjRd⚚;?r]nMK5q]gՙV2[d Q.:_'G:)Oj)`-HeÍ<./OKO՟X܁<5S`|M-UaA& UT Q ǵTqTVx|5P (p5-M(T'jAS!_Ꚛd ?u5% QBF'HEcgAk]= q?]%0iïl+QZgo%e T!)n2tv rnl7[  wĄL em>x&<:"LxKl¦*S 3G}Aˈ}ۈ$RAX"ҵAj o U户+"b?ރEhʹD%ܜ3tMI8Ek`癓'pv( ^v0 fn<8(]$T(Egl<,`n6CtF[_lQౝj{$T[I:xAKd`OtуMZUeM7/.6?_^}Q>d?ޖ}.dT$Dj&+2ly PۣzTq7~@LV}btB(T74?IhZ߆r5xR9.(c|am-(1H9Xm]ma*X RT~ i>22|㊊RC}#SdPiNڇioZo߽gy^M^_cڹ1?ڟ" 71 XO6bԯe#v.<]RfBQzvc5k'2!c?l2C4 MFBIbՉr%MOHIKН|=AuWЙ&n?  ġ9i>_fϯ_;QRUE}˱7Vk|^R5C+Dt~!M-DՃy΀jSnP> g?O'ϊE`Г8,{:i/x , {맩*_Ws'BQԉUDĕ[KɈdȶn^[|zoP283RALX|VY9`{ gE{gD$g.fLJ8>+mZeǺ+I䁇}v$@m@>3> QEM"`%a#QCyku<2 ;3  *?HHFl6 G?j#6u4w#eZ0aa}@뻽B:{dm@Cm0b_d\TT [Wjr n "Ȫ"&(S0F:rndcGQ@dq`=hA)J&Ҍx@:Ģh/Än D}6n(G=4cn[/ע" +wZX8".~=KP_P/*mi3x>SVg &ӓW+@HILh dueQQ,j0JWA.VDZT%ߠ*@/ep[T*p'mp#MiK逗^9)'[tX+XB*BY׳,ӌH&,K}<^XCi^_.Y(}+[P"zi}B5Bb>KQC1 SxbCn*z(GMjTҋ2#O$];7BL ea$lhKJ =Q&tAkg-9Rrc8^7F}ywCCNR3bKHAr>IllVK]{5UF[Q;LH%r蒖 Mou0qs cVVh-9*}&HX2I67!#`a@8X1rqLJaչEh%;+!.~mdġk{Ϗ==.ZE{I?˽_ /M-y7g-6k2KiZқӪگ ~L<#/2qE`^yU`PpcA'D]fxz6e ח&;T4*2+x_\[E(/-| 7EG*c4kA@ҫ_Etx4!i"SQtrFDy3iD)d{($~+T6jjuF=vAyWu̒_?aVe-e}.L" Ndx"-Ňcˤߋ,<2?x~OU@(_8Tib $V)‡ '~ zD dkhHl=:05(p(0tLrr2^zu9pFWuWJ;&Pձa1cN$pLR2:~c`MTEUqرHTgV@rp,w,1EL}#&PSFY8n o`zer@0PHH:sMz5QYWJ)KR|G(1*͍;6JX|Ժi.J4nr73y!*iT+]V&EVg(eKZ"&|Dީ/ 3qsi>)v!"k!N8Xi" VV5 )7\2f.1˝yu&/Ã44%ӣȯ*CTBq֠XQ:i#W$ۢPv0Kr)Z8[&^쮰|z$QRjRXFQsUn|NodC e?0$sdfa+Sz&{e2‡"(#a('+VԂCB[jZ# r#Vvil2̍[Q9NwT۩T:$&Cu@ ޥTヿp<2ږ" /!-L 8(u jf4[$0uz0z,Eďx=P z8Zh[daF#Tѧ&.T27IFq}tl3^b 1DdȬ~㱨JH9p{&kc@y d$iZ"sCohRηW V$ysx:Mg7%+K;𵨬}u'҉a<)>}Pqo7WՃQA]1d~<U+F8k,+ޫ/>tּPnΧ:LT@%yC/a7M}_҉^Ԥ2R5㟺FDܨ\LGf\&g"WNjW2@njߎ,ߎ,,+`>:],Eטѵ"4W~$\KknTbJ(=^hSᦸΏ7ZDMvJ-U/%BbKN|n.5Rfk6#7 'MԇFCRiZsTc8E9M&sEJVi ԩ%V[%r&# 1؎ c]P@&B@Oqݕ_xi-+s.J{y)| Ue?fFBns4kn O,uѪ.C;V,s,P{ɬu}ezPH즉Gk^<:i*4s=YD:?+q 7)۫/Pud-aW/ P@A25OcX5.Hl:cG!5 (TbQ)oĿPƇ~qn=jމ&aîֲ^zE?7V]umdu]vW 1s4;X/4ؽ)Ш*HKF&O3˕2LNԔ5&-*K,12׌u \ diU1Suǎjc-yZ sc˄)3s7л- .5K){ʳ<7^75\ՒjL[.ԔOtyuYwh;YzO`Yy sz{5/e3 @dL[7.jaNEx};YrTcߵCFi[[uQn"XFZ^7\:?lL<'ٙy/ךp,ۆE4[}urAlZK=ڴe'>jn$FL S!(%\CE^A`hVnq}cټoNǯDC!@<>?-~ҫle9ɂ:A$E(JŌʰ1t xtN!hW{9M&w"]GY4-+`wq` jhT@T,OtJ~OaqpC S}(չKN6!C}[wH(vu6x! v՗p2v6S+JH03{Bo#dbAXY[Fdav"PF6!œ"D~L@mwd2ƥ*ԕ9O(Ƣ$Z A Jn!Nٹ5Tm$mvԐAvP/8l{7H"o dEZt#˸p0 @@'dm3P;`DpY>jLdfc Et/noeLbF؉@л|&i"BzNW {0'z5WtN5?m2PYFOa f!4u|QOЬyle.;r*VZEZE7+G?SK+лUNm+c$<Z›)J9dLϤ YCɨZRFWJ \̴NR]SV*d6D&NďeM2Ex ;Ojyb%w??F<1T6iP_o%/4؝ .n*eJev-oɇfC:p8P9Ba`qR 䤦6%FQJ+unGyHzE_Qqhe1BQz T+nn*s;[$]}}U*qO[ez{+?GN;U5&D5sK&u-t#)(ѡagl 4r0;>wP%QfksDz'Z&2 팘sDto[@%Eg"N]_3q!.ǨH FON a\%r$oXEKU|ZUP\Si0k?+Z VṄ-u499΅Vo:WRpvz!d~\ j }GT:/_c򿗾t^o g 5]K@ 5(QgNw/hґR6lgl8_Qqaɟsmj $[IN" )2Dθ~ď]c+׾\Z#k}hH,5b_i?V)3D0=fr㔠©N(ZBJZ@k/VͺC$[Nt=4wHZuغ Y[y)h܁E-g`ݕu 73l߾e ͇62c'e%3xv&NYP=7U]3IFT=>ҩ#D i%ZiC>:xXjTkSH8/8~>̈e_"\Ћb+w-ed,+VOyLFeV}wy`C<3&D䆢#S~ /%\lɡ5\OHŲ˩fn6(v8=!z!4T:Xd[(IKnpCh*oup4^RZݎR7OǺï n\\G}炈+5OMi@jϡZwݧ+`. f)y/tDJ'sY@d.2w[9[%sPt.XXjoAK ="9Yg% N,Rg=iQEYմ ֘6`; n7?҇Jˢ-sҊ܅r %neQٌa-+2 Р5mC䧒8v.\Bb#2 vSVg:7ABB8{*BvjƿH6q}ŞxL,)LwtNlBc*I#ND^ uoA;T m&ln ;MhIN-؂'e7EkD39]}ɝgM^ A_\ykՒͳg*9pobL LnMY1 Ti19A!V N=fVa]Z1T:1ZJV/)BFUފFׂ}TIگk1/ X? Rd,8ኙ=-GgB/U^Hv^D~t#!12xN7>H$(.tp~^Z,Nxɮ&L|q3%aPb:޵9 L{<7}q@ GjT}ch!~_!^<HjdRF܅Bȼ.!0 :Ѫ&)ѪѪ#.ÞZb3$\U_*ó4b N5Umu.-Ϛ3bxn@Ƀ;uKR6Bb{onT sNlF\pWsOhʑV JG} j]v1+&=+WMV"XBW-lKqaD8B[^O_ :$}ϭċNyc5>ntR'Idg:w+߉Lբf"?ԍuXؑt ݗ&a m)2,)5܇mvEi6 3 ɷM`vq<ڇ G# LdPW=#w$ dV!Ǣd9m쎗lYINJq+."jW+v A24%huϜ?-x"Bp-Iow<tǍv:54"b c1E.x6šqԓ^2z5JHѲ+E@*Q۽jSkZi)V 3:φQ!݋%VEj*\X_P3'69vq' C SŶړ./ G6=BЁn/ ՝ )5B5} ꨆ3UI1#giPGtAQ@tjcߍ?8!8R8އrX4z7bG *F3=PeIe ذ>DNݏbnrjH)]JX@]aLeXJsxv7* o TI00 ͒RymdEP"`RYEX6y}sy$BSC*yg$2Yτ((YFl)SbY\wU,26uTw9,l(zO)5 b̶Jfkץʂ3@1&N9ՑPzZX5}q]̫#cjN'j@ tqifX}ĞN=ú; vpT#BŌ0P)X@m,d}gv~Bn]={"_aP䛿6`sہjy̍je-Gu}iN_O4^in|in{B}|725;8j~ocyE4\qE?vI4Zvv@"&$ YڴK뾃ӗkǍ`)vy 0{<.a D;v]*om-Ap9pQgjIfUi2ISǁQӼ W!C@[ "r=9H]lJ+PF*ָ&18ily C ԉ[p<d#32W}WQ]f6WfԚMa9s4I  at#-{;t!Dk*c]ln-Dw5}!)ᶮ.]ۆ<+;,qÐ8屘 Re{7'hvfHLK><$g^pq@-_C16W .ٚ׻y8r]@ujƟf_}]BS;kyn-76DYhJX'[A*9AT9eoTQMTV%,  1H*MSl*N_uozz*_951)HU4d e<ڋyh-խ !3_\n+X }>Z#KZp̎畾҇.UwͶ ;뼲& t&dRXˆ&TK]ڙ i+Ȃ/,[-]?yZ֩RP U~d/U4 }jfÚ^_bֶ؏;~X"sΝY555'3Sl]^i;B8E/]yI?-{Wo`;zN9Nmd7>ϫ@WKNknŪب .In .Rw͕vn# `\vys֥Qn|[[7 4oov&5>pO}Ԃ˚Owax?ݚL9a)^튵Vq#Yl*YL?ԍ_׵`Fԟ"7ahOEdF[X9c֧ojZ,6q@X!+wq#)Е{Kzt g^ZeT dVNW1U|Z[;PQzD+x+zAw;#,JAj&'e3$- k 1OIG"Sa.h-B мCP'@MHRi 6, $hGЦD/dhf :KsEW]5H[Yke19V֋`6 ؄-#AxݷBe|n-LUV> ԸFjرGã퍣R!|nh Yc9nmo2sm6ζٵsevWivՎZOopj5?K~2iCaAeL"8VDu HdV'?[;XX&kvQ%]vzVenyɼ5/ADpː./Cڦyۘx0qw_7\%Ʌ/K@,im/KB^LukDeC2,DvS&cv1v|8_`O|N^edLT!΄!㪥h~&8S5 s$KN}/!=ƌ3'ӞTN9;e.LUb~N1ߓL$EOcXd i7b.'MQ19^d N%w+m-#1QM712%`Dܠ,=nK)rR#)ҊUaa'Ռ{e\W+ Ka Na4W&|jaic:~ךޅ)S#t(`LF6'4G; /mGS{#}(iSi}*ZH]d4QR] n|E\B.Wak]k ] W :aR>G q7eqcxp JQfkH4x c"=aam@2taSI͆9yq;e0ٹ\lU̧ɳǍ!$1՝Q[ ) ~#^(L1 _0): (.;j>U\j3)|]}] *vOxӂfc0OztaP:Nuz/863: S϶*iGLNii&kM_uulɓ U+%F>tzh/Hs}}tEIbW(M;Zj櫤'C檕_vHinHd^sHͶH]z (H(Ocףѳ]tBڍmSkךugek.2AUBaٻ0kMm}:ĥMqt ?wf' I}и$Y_uI\ VnmM;_PQ6G+W 2wWM,܁;y?9ߴIV5DA3Pej>h̀N|p{KO2װ3D']Ĕծzyǂ!Zhft/UOTV`~}6M #>vgpun u֬m\ Ar&aOYށҌ=uǖW Y}GIyӡ:5{*r1 Je \:6~})Z3z %՜v $䍓C+f" z'EGk,~^r.Lq1g94{5j8TDzd{X=ز\iGo6 # M܂Eg%ii]~ơڕMܘN%p\Ϣ̍k {2p?/7fmݛ+و tT.'u zYsEgG=,rW dE#=?R{?՟Ҧ ^̋.unc4 j4U=vbVǺd#k+~jc{&`Jεo-5Avcg,dw-ixrL8Ļ2Q|&U{ivֺ1Oκ5i`ѯ=5=AAOiԑcĨqBEEj &hqbntEΜ(ױ/#R"Eu%\n%p8܉M0a$FI"A)6g7_vS&IR]wb ǍVazɛisLioDFYcB3*,)j7|D\)\YUx3n|ْ7ER)F눾S1rZBn$h(ZVc k;T|8K"ྙE \6yrVmۻ?}|V~e t<}jEyknD_[w|\7s!"S w\K yFo.\ȿs!Bͅw!?< 7ߜȿf'ronk#|s$Hڑ|I#y7xtwom52z~\ɻSW]'ɻ9w}oL^#޿3ku&t0|Ι1_3c|s&Ιy$ߜɻr&?;&T&_{udm;ʻjNR%9N2kY;${թSS Y|EjxO HQ2%Q7|I,@ї܌]hq[qB$bʳLlX-%+ b%+5*M>W9ML68HS 8&J8)Te L0L _L3`~\,{&C? 5%4}ͯWE/9> ~]r>ը6mu9Kֹ2bVORFdEɺZm3;9+Ul7d*xT;:Q| iã u)*/mq߿i,(ݙR^4=?H.|ˇL[VNpRMǺ /XK^|>s>XcESʌ'ȆCAbAĂ.̀.r3cd0:8Q$lql!弻f<55ȧdiIԍ/ՊXE3y&a^\v>!CX$v N؃YY$E,P ٽn?z/cW8ͻkf޽?mӱ{dŔ CY>`xRȝF:˖1a-LCMm[&E(ެ~aܡF~L"+[:/d_g2Ź,oq nb><4R i\㣊+eM^U<~]؛7˯]Ui@51ESE?PBC_a8TdJojLqdbPSk܋^+ (ba$)LoFTĀ:܋n0%Aq0gX/{f3J XXwDU֙]+^ ]2De9 VGPۗD}|E|A}={TG;[G[SU}OhŕYli=6V,&ӾϏu- x4!|M t򻀸C>a/3j$&.=p:O-C*UNTi1&f~w-яՓW~}r_] 1(d[jyn *P_& ?+S=ǚlFl8:76E[*c9R=Q8[%DٰU" {B ?9L ..n-΋Qjjj.8Mf p`ly*0!%)h 6#pM+![1+ZP۵O9}p$x[!p"?3֑snT60VoXr*oDHC˛9B}Рw7zZbDHb_A$8ix(˧JeL@*|Ly`@1 ^y -Vhkk(=XCEV/%?yrhZqŽ)NmZdT,D6 hE(~)s!XV~~ DV"Q&.8RdTL:}>F F4EP+~b_e6-B!)~frxȧˇ <ãiEV=( msOsweXyk0eϗg|Ɍ}-`<;e3Y7O|9{R/^.1? ] @K}|o8 =NhƵz0ŵjK**{ף4[E*U˷J.pS>>*}~_|T|\AF#@Mz0a)֏n/ A~y a+yWTjhXМ7U_:hRbiYnlzWXqGk>NZBi o%Z;5`{55gԪ1)4LNKS/Ԏb/b/qb/qXh^T8o-rMp4m>=6jmY7Z+s\{pկ܀iP~ժ(7òE0$~/1htbH)k`h̗ns+g_%,V02/'-Zfu7e)7٬umjUډhl3hE6VH\P7 fd&VM+ /EO?٣)ɻ4[F!KŞiSɍl}[rZ c Xz%35{8-CpSGc._#[SFcW=rڔ;fav -xi8UdcO3nmNL;<F /۶ Y_-g~%ym.659γ_܉[u UqEȑ=sz; 8E#wƩKR/,lФܿPvxr8IEǽRw ߭]Sޯs]IRgī/1BbE'r2$UWL=OE36Zr|r]pXybģmXS8)h$ĩs0I.xMMm^(Lc2&4ZX{aVc |&'0h8d P7 fNv D^2kuud- =Ѩ3(Q6=sY}Jɠ/Tn텖d,Iލ]je>)jkSO#?k '3œޝ⹯Ҿ"/mOúBl,E?kz|mtHDCÞ I! I >8o" wm0_5N4pōm mEm›mpP߼?.~/ a9r'MKtW34Hm!"߰Ae]^ 2ACbIN '5O:(<ӄD( FoKXCͳgQ*/ hOe%c!Di\(ѓ>ľ@CQ*{d%jI)-G2я"f U-zeT}Q1Q?LPTE`O.~<,Ni ǣi +cDlVOq-Z4+qrwO%Aa=>q.ՃM!>f ؔ)x=vZ1{%/~Fab g׸bkU/g+L. 0!/!\ #r6Op<&mkD`/oe1@(H7y3d075s![Źa6F-4CR?g yxtU@ɤȲzi<;uGoR\w3qN k=Ω0F^,^VstØJ7kᆵ&بj*!g _\>ε* IMI Ԗ+6L>,{}_j90>N6k@kU&j2cqMgVhu%]f~r. !kFQ$%*sz@:jIe8`*3#`Ќ2AC^ N*o½„@5ƒInK|"*ȾhSPM%Șnpdl_*aOcYO}(QowEkf a}?%> 3]6.e ({l`p `pF0VO~%T+x-grݱ0+zf C%;0憙ֺLɵ.y7 ݽ`@~i7"K,c4U~Ze%1hsS LH+->`ɪ2*ag$k8K}C*?DOUleIïmYղ38L SYqhkVgw|!s>zcDm2!c͝:q%^J{ %f*~KjK.Niܜb֚vm⼽{0z6dͰP#`Aǝ5%xPSVJ죿h 41lf@u*`QSR]؛!Uu_ߍ#WܪΨc ^Ze-)MT@RR[8E?46ƥZɶ q݋_n6FےQ2{kcHgYwWUb\K0KUhtN͙ͦ鉳?mbZ!% 6Pxpm~'e_NI )򠱼zȕf+3&fr&gΕNNuoeGHκ9coE퀻\}k`<:ޣ||T|=kOyxl:v/=Cf[^'4rS˷~D m-#lU^LŘrǓ]߄H-uu3:B[wδjmx)׶O$&W͋nRv*j[\o^c*T+1yKAfeٓ@}9͹6fh B̢P MwC#Y=mگd^߫*kY0տǭ[P[6S&-11yi'd ·=_MߗC/p9w ݴݜɫo"U%@,秣EFqnLgβUD,?3u /?4^[j؛G3^94cW[R~>г"B~P4ֹ guJop}CS_Fo\||w8K Ѯyڍe )hW%Kzݺ6𻱌!Y%5Tyqb! EJC:~~W=9T?r$2\(ZT<i?>Q ~2vW636TyRsФǰL1F٭}6ˎ7/$]EvU;h'f#`2pJ7-Juio'C.$Wgm}3%(QswWDVKW(y'M(Vˍ铬[55`^CדX)7bH 7B1S50=?P`|Wj:Rc`,`|\4{..,y9,* JݓwZnp\~αYP1Y* ^ڔa` ~΢uhs 2(qQ^ߵAպ ZÝwV*(A臋X-\"iLJ&? 00q cF™Eϟ6Fꉚ+9WCz*L3fqs!YA)2aR.'S:*_7~OpgPTPrrw0$ Lz3}TQj|f:WyijîHkWlGyoZ|04-tq\%eS>LHQ*Ot3B,oQѭWxj\6a~v*-n׽Su*;B/hGV|ViMmM0˓ޅv^h71C$j1 ح_my7jumݪ>`6Z|RR.U@D 4{Fni2ӝGNt zWgiFk:@'Hs%dn, ew}iSZ^{AC>B]l+˘*Y)3٫w.KܮKb)@}AK'YtS1ۉac!rO_v/Ue7|/xB_4]\8*m4o<^1ūbf"fΫauqoz/nvq%ZZz&2>ruqqO !{#Uk)9_GM wfcrh8"z9_5ެ/fsjLz9_z9_<'fY"D[Pb͑(qbF No(ÓTWô$h)d5hEZ9RN x0d ٟXp[[⦩8+L#Ygj~s͖#6׉iwBhG5#5/Wnm+oيX&W6͒z feq:Io7 2Aɳv8D(BL686' f̲ 'Lre*'S9ӞQ!=]{:?̑4[i,snY8އN<O:4zP-qkj%V M2y#pJBnYȏjThpvY}9ɃޙK^FPN#ǁ?Y?e*Ӓ;bZxYҟgL[ 6SF_JcnJjP L'&k< _du֏jhp*0U5+F{@ځfq аChL@efH|򧟈(R'!FCf8 p2 z!~!\+dRKOnǫ+j1Fc - MrXýDhw7"׸uj$34q)!a1Umܩ@Qvɲ]uRKs{SZ͈XmphHa"P$Mf1|WA.=T,RWRK≛)W8%"71cR>-d`CݼRZp;Wh8hʛ7f 9|~Ú+Wn8nJ],YZey wqGǍF:40us<i{rRA쉵\0 g@{iD:Q^;D\kv˙Ĵghp͛ 9X)XX&as+VV\tq69a LB#arp|/܃BMCg!Idi^Z+ ?6:$r6wHYuzkaCfj+~'?Oix!o56]~]V 8ش+OT%@$+s8vUR,aenw_Ym燕’7Yx*BM_!VJy_`5dp ki?kX)~}~cEEgcb + 俯7kH^k8 pjjX2pu|~##j4@ޜg1*SAg)|S0L:b Gk)\sL+qulZLx1k߬.@R*l+JSe{սܚ|qUBAalw"/򮺽.jbeW;y_wö/~6DCgU ǕF2bRL.#oR JAkfYB kٔǕݏ*Mİx:\ix7p PWk#A,O {cXaEaEgSXV?yǬa7Ob}X nvpKP݂>g^/o2E4lL4`Vke zBY4Yj*^{ K dj$|U0GU ˧y<){g9g[V9#S- _zeР& B}O?qJ~71H |?T%i;M2͆Bhs~! ]% M =KHLx10T8OBW;+4!\ 4Q`"~ls5C'd0DS;ĮxTX8Jҏ֠7b(Ӿ^G{T쁋NOQ*r-a4-:.&燤s~[=*#0J/h5VysTi,ž{B=xa8>m1HVw6O*+\*Y4L;(?Oq U,m |}*L)?)N?&1P|q,tp)>DhkG'PUs07-yto0߰Q%VJGͨ/Qz ȉ`GcN?MvI ", |}߅+Tܕ?}Т/rin /GZMY#WF@/R9:+BJKf/DO&}C$JAa,we@-,<4K ,Gbe1΋(%44 !>leE0UGI`~ =:U=9NRoO&H `xX &OL䧉(:'2a403QO)߄:r8 0$jሗP! .Bfi?1e$$-FQ?xVpJɿ`LihO=g*g&'\Q/SӗO4u3Y6ߧez ?nHj(ij߶L"Vh ٬(FEYztb+6P)t+S7 Ӯ%2IDi&r'ĕ$TRB Ӌ0X?fES1Ԯ}\qU 6Q]?Q⹮\ F"s}=ЦL l1/Q,8ܚ:$shrM9+i.z(,IP%CL9P.c16"5TbF[fH  qz~,qeTŃD$8UW|A=[TUF~9Iߝ7oL(8C}[`9x+^Oi X8@= 5>[2{Yj[C`bP@o/(#~<ĊyU.d$ }vAtOg54Dٖ@|VWRCk:}@ #@)*0'h<8 U%`1Ezʊ DW}EcDu ɓЍCN"f+G6@qXK@'$$UFp8HNY  VJr^榨[9~O)K0nT' F H R vcg%P+Ӭg υw}d9\%ʌtWv& S!5ċPY ZNhSs\20jLH"a+$BzU*8=`ьtr$^se2&K[KwsFaR9VE磫%C><'.exMyй9oȿ&XdD*nV;qg'\fʃu-ƯHYFѻD 2nкY4 JI~/%̫Ejٖ-0(H5a =m&ʔei00L 0 [Ș5 q!ݾ~ [ 1'QqwBMLE9[`9 `ŏ2G!ҝaz hk=9Dl.!H)CNz8r)WyZNi_Q2G=Gݺkѹ( L+ё& DXǯ&' ITz/~eR|N+.@?9S>SDa1CY}cs쒏2UVC$#jxɴ,uy΅$rpb(2|dn:{ >7`W7-~.Of)@9 F_:$-ڷL-AĈI & Q|,%Pɢq(~HaCFYbT'2d"UT-Oz瀜!c&V*p_#qY@dl]!PY>l;*)i+B`@Oc&`c r9DE!p==*~O#Nt?h\GwF LS^^OB_8!<@)BC`Qnj gGa,3'UA@V,â 4sMI$yӾ-4$'_=Ji/O|MURD t@W44@Y|4ODR [(?OUla j dnYAc-My>YP v79ai~^ 2UAG@ T|{gܞ5I[:n5JyKc~ gߕ^<3VNP3A>)96=ЅQ9Q1rEVRV ?׍xC~ǜ"Qxoo{zVBEtt\, 0 J|ȔwQNtߊDO C(IZ o:cRޝ:8? dgKƎ-AXeZ+,Wy pg|,(h:oRq8CB/ziJ"o҅0>G~yKނ@AP8 ŞS蹐AP4 CJ`{,=br"DWd SrXZ;)8gEĜգ9ր(ki_N;`7h;[seW38Zpz]7n]DS8e>"2,`d*vkta?cŁu;.HZShbYT1 w>!GK)E< AW@(19K3ɺfja pBm#L[>!Ynb8r*}V.=+)4)LoaTM.blv2FvʼnнTU9>j uBb2MQb>wŭ1q:2XBwCF?k>pHE nuH=ƱzȢj$<j,{N(?bAKqmA/Hq"̸E;?wGӧZ}-J,<);Yf@x>B'Pޣ"뉞) J.'бS ֜0l%Ghpv!06+EHo9+Dʖ39y]mRߑ {2% ra MʢҬ~AgEJz%!}']Q#5{,n1h8 gɆb%gO3άyĸA (b0QHU}Z+rh,i#zжrTyא(Ku" $AdBcAL~f0,d(Qk[]f!QTaVA`D zP`|ezA)FSv~ )=tr ۔sУR,raDp8%1"ϙ eAdn? Kv EC =q\5Xt I65h` zN 8MCR²CyQ0@1gfJ/U8;Ap@WgĭbG.b]qx1hlA@7P'P@4<@H*Ql M壞PA&nphD6g3Jb`&*cPYB?v 0-]2<;U+ Ni&$x)}h?e7z M<Bz 2&VU5!P*@  b n4bA3Ԕ1qDSd:DF1T`e;U+6j||Cؾu>]8ibs5poU=/pHYPU'p9fE Xx.B$iA$S:FD%FJgIl*ζ4!J.A[@[g<쬎3!Zs[uDWp\%/hcę-E?!!e+Dt\ΰ}IfZ(Ĩ1^'yh$o!TVadĎi^ߑ֝2@@!$Kf5--#জ1!qgk27pҡ|o hwS;Fo9D*qf֡JF|('#w4'N~WMY"EQ%Տzi=0@=|0! 廉; 0(E J4jg3F{N -4[AJ~`( c%e@ت>)hÅzM9h)O& q*uWdJ_xP6 5J1k Jj!#2o*&xJÀ $]IE*۾uȔTs8e<!aDfKk"1#+ԩdLfqg[dE(MeYME(Rzi;tO@2s60 Bp7آ.ZȰ_ݨc3G UBV*G*[dlUJ"Xdxajܑɏ9YBE.`/{|N?Q/8ܐ +H>L\lW76g+3q0rteQ y2)#ؾ޵F&w<À7T',1iyPת^I+X1/vfeP(b$CEpX1:CH[qJ7(&:PIOg> 1F7ƲzCr&&Iq7'yTD91;o^axP3RpPj sȵUZ$|'V;}逹L9 Vs0f Bs)za E.Bf̳&V}@U"fjA\mсX@AF%$-_(UtXi8U,%?mN,k``BBQo2b`SnJf[Փ,Ivd*hpKrHxM f8, (_hR $on:`[4}{Hؠe')b}apA\Q;d\G)+|cigKb3VMZX $d)^3X:f!|X@q/O?BiAhn N:Z_DUNf&DD.ZT35(&y,ǖX>9T*K(k3@q-3iBfY1S8J,x<5I[F='_}&EDPa+pqSpU<ɋS}Aacαt6toYXQǔÊYD]BI &"xp* BHWocG)I C~C1N##)xREVǦ"i;l(l\ 4`dpXy_J>A}鑵.̪^ qf9dbPHs1 ̄Tw T0 U(Ktp.MxT0I /`3ӱw3ԍ (MUr{,qL*5)J;G[-cثM  1{nR\{y EGWK$iL@\{-٥ڕףɽk`Hn(.1/crCt[5 UynP ޏYs<4 w8Œ6lJy]"{ a6!ZMZ9n+Ze=*8߶U CPM3Y =pqL!aLjiQ]7v#AyVa𫮽HJtZT0ZL.8/SuF_PZlNItP 3<(fX8 ڌCDK҃;PtP5):`X66 sL-PmKp]8|;7|<HDlSȾXRhwc?rܭߡT()1G- L[̤!hE!U ?15p!\*iP12 /MDʊ.Qhc\1`{/lxXCn x16~ qRE!ֹthM#tF<B@"uf~BOQWp+Ԡ{shzh˩!.Ig<"z2kUL% vZ،.ss\Rig]V: 3 {!;QUb]7)jbWO*؛$^#Mލ]h레B (?@mӣ LOj{k&Qf k]Uh`ƦOlV]6a OJxpsɣT4Ntc4ԑ9g7:#}aA68wpY&n%p0׌9SxK0W@aKRlp\`UC?M74 %ANKP=bJü'%ϔfV?Zgoe~~"̠b*N}rF@b]neuԐrRv }-+^_Naaߡc&\v6v^a5r$FnlӜ\݊)rJɜ&n?ұ*Tv[a-ʅ)jl"t4GԈ bh91cptxv(8 ٘0ˏ좱Xg͎`anQҰRKy?h Hi" tL,jT=ճ0zqw!:F8;~S|_/wW-p/A^]u.? qy.ﳋŵt/)й?:??:|}p\_pnEq{zйq|_c2w܋ν?:_o=8/OyK\tы87wsu{ٹ8o-ۃyp.;WM {g4n;?j/{G用8vyz'n_ yйw{=vrn/]^]@_6{$Wy 7. ]8_.:/Z8vusty)/.Ow;g8w;qsA+7c}p..|)׷(,w88?:[qK _?ŏ7և9~}azN->>|3B\vp<78]ONo9E?./N/[t:0}5>ԍ8w{hۃ^oȉךn;{o?{poDΝYTN x7ٷ́7.5ЋswnvLrڹvW@F^`ȉJo[E;&vhžދ{%ss9xذo\1x?d,^8L4FdP`(D yC?&$ Ӧ@{sjci8n!*(NDN`OiO*9n>o|iW_ zqM 2 ~w sF]h?,n_6SX g݃Nŵz'kM㫬Фyί<׈ٞE<{횤`|}S!Q$:Xc,w#}S#6ܿŪxhdgp8chg}0l@?ɀ0r'桤p.춵*bKacK'ւ. A .y +=@хz)ˍ7bfL#vDod;cUz=D4Rߟ NOptޗDxV<:2/؎*¹(N1AWJO3oCV(Dx dET5r y#BHQw-яU;4ݻ0ۍwndگ'%cu;y gBP>$\}fJA 91 zhl?WwI82vbRkWBM_abX4,-DqPtd7.. R&oz ~O`wNXv.Rex@.H)2Ə[T''!81T_:Hی#M9Jh 'ⅸF=1 a|Dd'삌F?B7Q0FHK~To nuÅ:iv@#rK.}f Xw}1_rL|#G(0e LSiʱk/V|rJ9f+:I% 1bU"GyMqLH*h$BG#);9čk6gyf !j xr8'I*:@c%jzþDI4=G0J0r]`/u? }dvfڄ cz'-G;''(0HUv ڥXAwT8iIÿidHd]?=NN@#nnpvGNwN~{sƝE~n3lFϱfF/m 6FFhѯf`f'6fF/m jlFof6fFmolFaߚm;6F`?*};8Zq*HPI.'qL(B]ϋޫ8q|0|taeOu߀vJ2 +9]H?8gxko\ iӿ@hpZz^0/-^QIvNy mw  08NM }37R;P6v5Mw+ɢYB lS{VXQ[5_8rR'SP^3 `H5Oئ~0vU!(Dݦ+:wNB ܒNNVC9AX, ?);kpAFΉs+Er~>ΠPI[tz*PB8X } &`I8l0a"lM.p&126åd7FL‡'c{d=0&SS Ž(Y{ r-0Yp&]O8 {J `7G?7CԺtC !6D/"i  vcc{bM'5"zJk>[/̠g@؁Ƽn?9b..n CXb^ ?P2迶 smyAk;1u;5}砿yɛ&v;P7rず*;C I G^/C"ͣJ;g\{.A"/(gôDEy "Rpum~뇧/i#"Mu$_hP cnQ?JX_l)%N$9TqfAv͊_m9}+Omk#"-#SZ+"E*baNǷ;'~݁j_eAy6gAb<Ⱥ61!؄@ /g!9Puy6ȍ6^klYvv_`?p=sBoaohI*^;Z{yy{ifb"O4AT"vˇ~? ljՓ3aa0zMt׶FCZOB? i)4]\-A$yw!迶~IaI^\4\t[ އU_EW6LZ'^%g~*0KUn}-Varp@KcÜȻځyMȘ-jb=c0{ǭPnnvNavwslف-!7h[\T@9xu%'MX"*]U1gǀk?j;eV"] (PοJrjDE."-+Aw;]̕71 ن *R[CmEn Ǽ2_;pSc2_GxΉQ5m4Uiہ>q UOpSX9WYԷ'>f L4%[\IMb9?^7h8hh#mM:&}sl ;j5_&5ɽ&cc-I)MEu><4ƭ{l5%Nȷo NHfVp${SfnvAo#0E4 Eޠo j速 ~R]XJ:yj,!e(y^5D(2{O4͠T,'~*NϖM |OtavwQ;rSڮ ۉRv= P$Jm]jǓehee.zs=zVpn"`C\DaSD%27D \/}E(nߑhquhalu+ gK_l)w hB9& YXq۪  Z9Rg1盇d$^QwN8:?`(oa7&(n(>d,[W;'wON=rݸH6z596zlE~F46lllFle^aW6z4-6zlFlw]c6>47l[~F7lGEdwt8ﺑ7o 8q$"n see the addon2arduino.html#Using-addons 6.3 Using addonsfarduino.html#Programming-the-arduino-with-the-addonX6.3.1 Programming the arduino with the addonHarduino.html#Creating-a-addon-object:6.3.2 Creating a addon object:arduino.html#Sensors-Overview$7 Sensors OverviewLarduino.html#Matlab-Compatible-Sensors:7.1 Matlab Compatible Sensors*arduino.html#Overview7.1.1 Overview<arduino.html#Available-Sensors.7.1.2 Available SensorsParduino.html#Lightweight-Arduino-Sensors>7.2 Lightweight Arduino Sensors.arduino.html#Overview-17.2.1 Overview@arduino.html#Available-Sensors-1.7.2.2 Available Sensors*arduino.html#Examples8 Examples8arduino.html#Blinking-an-LED&8.1 Blinking an LEDharduino.html#Using-I2C-to-communicate-with-an-EEPROMV8.2 Using I2C to communicate with an EEPROM~arduino.html#Using-SPI-to-communicate-with-a-mcp3002-10-bit-ADCl8.3 Using SPI to communicate with a mcp3002 10 bit ADC>arduino.html#Function-Reference(9 Function Reference<arduino.html#General-Functions*9.1 General Functions2arduino.html#arduinosetup$9.1.1 arduinosetup,arduino.html#isarduino9.1.2 isarduinoBarduino.html#listArduinoLibraries49.1.3 listArduinoLibraries8arduino.html#scanForArduinos*9.1.4 scanForArduinos<arduino.html#Arduino-Functions*9.2 Arduino FunctionsParduino.html#g_t_0040arduino_002farduino,9.2.1 @arduino/arduino`arduino.html#g_t_0040arduino_002fcheckI2CAddress<9.2.2 @arduino/checkI2CAddressZarduino.html#g_t_0040arduino_002fconfigurePin69.2.3 @arduino/configurePinjarduino.html#g_t_0040arduino_002fconfigurePinResourceF9.2.4 @arduino/configurePinResourcenarduino.html#g_t_0040arduino_002fdecrementResourceCountJ9.2.5 @arduino/decrementResourceCountNarduino.html#g_t_0040arduino_002fdelete*9.2.6 @arduino/deleteJarduino.html#g_t_0040arduino_002fdisp&9.2.7 @arduino/dispTarduino.html#g_t_0040arduino_002fgetEndian09.2.8 @arduino/getEndian`arduino.html#g_t_0040arduino_002fgetI2CTerminals<9.2.9 @arduino/getI2CTerminalslarduino.html#g_t_0040arduino_002fgetInterruptTerminalsJ9.2.10 @arduino/getInterruptTerminals`arduino.html#g_t_0040arduino_002fgetLEDTerminals>9.2.11 @arduino/getLEDTerminalsNarduino.html#g_t_0040arduino_002fgetMCU,9.2.12 @arduino/getMCU`arduino.html#g_t_0040arduino_002fgetPWMTerminals>9.2.13 @arduino/getPWMTerminalsXarduino.html#g_t_0040arduino_002fgetPinAlias69.2.14 @arduino/getPinAliasVarduino.html#g_t_0040arduino_002fgetPinInfo49.2.15 @arduino/getPinInfojarduino.html#g_t_0040arduino_002fgetPinsFromTerminalsH9.2.16 @arduino/getPinsFromTerminalsbarduino.html#g_t_0040arduino_002fgetResourceCount@9.2.17 @arduino/getResourceCountbarduino.html#g_t_0040arduino_002fgetResourceOwner@9.2.18 @arduino/getResourceOwner`arduino.html#g_t_0040arduino_002fgetSPITerminals>9.2.19 @arduino/getSPITerminalsdarduino.html#g_t_0040arduino_002fgetServoTerminalsB9.2.20 @arduino/getServoTerminalstarduino.html#g_t_0040arduino_002fgetSharedResourcePropertyR9.2.21 @arduino/getSharedResourceProperty`arduino.html#g_t_0040arduino_002fgetTerminalMode>9.2.22 @arduino/getTerminalModejarduino.html#g_t_0040arduino_002fgetTerminalsFromPinsH9.2.23 @arduino/getTerminalsFromPinsnarduino.html#g_t_0040arduino_002fincrementResourceCountL9.2.24 @arduino/incrementResourceCountbarduino.html#g_t_0040arduino_002fisTerminalAnalog@9.2.25 @arduino/isTerminalAnalogdarduino.html#g_t_0040arduino_002fisTerminalDigitalB9.2.26 @arduino/isTerminalDigitalRarduino.html#g_t_0040arduino_002fplayTone09.2.27 @arduino/playTone\arduino.html#g_t_0040arduino_002freadAnalogPin:9.2.28 @arduino/readAnalogPin^arduino.html#g_t_0040arduino_002freadDigitalPin<9.2.29 @arduino/readDigitalPinXarduino.html#g_t_0040arduino_002freadVoltage69.2.30 @arduino/readVoltageLarduino.html#g_t_0040arduino_002freset*9.2.31 @arduino/resetXarduino.html#g_t_0040arduino_002fsendCommand69.2.32 @arduino/sendCommandtarduino.html#g_t_0040arduino_002fsetSharedResourcePropertyR9.2.33 @arduino/setSharedResourceProperty Narduino.html#g_t_0040arduino_002fuptime,9.2.34 @arduino/uptimeXarduino.html#g_t_0040arduino_002fvalidatePin69.2.35 @arduino/validatePinParduino.html#g_t_0040arduino_002fversion.9.2.36 @arduino/version`arduino.html#g_t_0040arduino_002fwriteDigitalPin>9.2.37 @arduino/writeDigitalPindarduino.html#g_t_0040arduino_002fwritePWMDutyCycleB9.2.38 @arduino/writePWMDutyCycle`arduino.html#g_t_0040arduino_002fwritePWMVoltage>9.2.39 @arduino/writePWMVoltageDarduino.html#Arduino-I2C-Functions29.3 Arduino I2C FunctionsLarduino.html#g_t_0040device_002fdelete(9.3.1 @device/deleteHarduino.html#g_t_0040device_002fdisp$9.3.2 @device/dispHarduino.html#g_t_0040device_002fread$9.3.3 @device/readXarduino.html#g_t_0040device_002freadRegister49.3.4 @device/readRegisterNarduino.html#g_t_0040device_002fsubsref*9.3.5 @device/subsrefJarduino.html#g_t_0040device_002fwrite&9.3.6 @device/writeZarduino.html#g_t_0040device_002fwriteRegister69.3.7 @device/writeRegisterLarduino.html#g_t_0040i2cdev_002fdelete(9.3.8 @i2cdev/deleteHarduino.html#g_t_0040i2cdev_002fdisp$9.3.9 @i2cdev/dispLarduino.html#g_t_0040i2cdev_002fi2cdev*9.3.10 @i2cdev/i2cdevHarduino.html#g_t_0040i2cdev_002fread&9.3.11 @i2cdev/readXarduino.html#g_t_0040i2cdev_002freadRegister69.3.12 @i2cdev/readRegisterNarduino.html#g_t_0040i2cdev_002fsubsref,9.3.13 @i2cdev/subsrefJarduino.html#g_t_0040i2cdev_002fwrite(9.3.14 @i2cdev/writeZarduino.html#g_t_0040i2cdev_002fwriteRegister89.3.15 @i2cdev/writeRegister.arduino.html#scanI2Cbus"9.3.16 scanI2CbusZarduino.html#Arduino-Rotary-Encoder-FunctionsH9.4 Arduino Rotary Encoder FunctionsZarduino.html#g_t_0040rotaryEncoder_002fdelete69.4.1 @rotaryEncoder/deleteVarduino.html#g_t_0040rotaryEncoder_002fdisp29.4.2 @rotaryEncoder/disp`arduino.html#g_t_0040rotaryEncoder_002freadCount<9.4.3 @rotaryEncoder/readCount`arduino.html#g_t_0040rotaryEncoder_002freadSpeed<9.4.4 @rotaryEncoder/readSpeedbarduino.html#g_t_0040rotaryEncoder_002fresetCount!>9.4.5 @rotaryEncoder/resetCountharduino.html#g_t_0040rotaryEncoder_002frotaryEncoderD9.4.6 @rotaryEncoder/rotaryEncoder\arduino.html#g_t_0040rotaryEncoder_002fsubsref89.4.7 @rotaryEncoder/subsrefHarduino.html#Arduino-Servo-Functions69.5 Arduino Servo FunctionsJarduino.html#g_t_0040servo_002fdelete&9.5.1 @servo/deleteFarduino.html#g_t_0040servo_002fdisp"9.5.2 @servo/dispVarduino.html#g_t_0040servo_002freadPosition29.5.3 @servo/readPositionHarduino.html#g_t_0040servo_002fservo$9.5.4 @servo/servoLarduino.html#g_t_0040servo_002fsubsref(9.5.5 @servo/subsrefXarduino.html#g_t_0040servo_002fwritePosition49.5.6 @servo/writePositionXarduino.html#Arduino-Shiftregister-FunctionsF9.6 Arduino Shiftregister FunctionsZarduino.html#g_t_0040shiftRegister_002fdelete69.6.1 @shiftRegister/deleteVarduino.html#g_t_0040shiftRegister_002fdisp29.6.2 @shiftRegister/dispVarduino.html#g_t_0040shiftRegister_002fread29.6.3 @shiftRegister/readXarduino.html#g_t_0040shiftRegister_002freset49.6.4 @shiftRegister/resetharduino.html#g_t_0040shiftRegister_002fshiftRegisterD9.6.5 @shiftRegister/shiftRegister\arduino.html#g_t_0040shiftRegister_002fsubsref89.6.6 @shiftRegister/subsrefXarduino.html#g_t_0040shiftRegister_002fwrite49.6.7 @shiftRegister/writeDarduino.html#Arduino-SPI-Functions29.7 Arduino SPI FunctionsParduino.html#g_t_0040device_002fdelete-1(9.7.1 @device/deleteLarduino.html#g_t_0040device_002fdisp-1$9.7.2 @device/dispRarduino.html#g_t_0040device_002fsubsref-1*9.7.3 @device/subsrefRarduino.html#g_t_0040device_002fwriteRead.9.7.4 @device/writeReadLarduino.html#g_t_0040spidev_002fdelete(9.7.5 @spidev/deleteHarduino.html#g_t_0040spidev_002fdisp$9.7.6 @spidev/dispLarduino.html#g_t_0040spidev_002fspidev(9.7.7 @spidev/spidevNarduino.html#g_t_0040spidev_002fsubsref*9.7.8 @spidev/subsrefRarduino.html#g_t_0040spidev_002fwriteRead.9.7.9 @spidev/writeReadJarduino.html#Arduino-Serial-Functions89.8 Arduino Serial FunctionsParduino.html#g"_t_0040device_002fdelete-2(9.8.1 @device/deleteLarduino.html#g_t_0040device_002fdevice(9.8.2 @device/deviceLarduino.html#g_t_0040device_002fdisp-2$9.8.3 @device/dispJarduino.html#g_t_0040device_002fflush&9.8.4 @device/flushLarduino.html#g_t_0040device_002fread-1$9.8.5 @device/readRarduino.html#g_t_0040device_002fsubsref-2*9.8.6 @device/subsrefNarduino.html#g_t_0040device_002fwrite-1&9.8.7 @device/writeJarduino.html#Arduino-Device-Functions89.9 Arduino Device FunctionsParduino.html#g_t_0040device_002fdelete-3(9.9.1 @device/deleteParduino.html#g_t_0040device_002fdevice-1(9.9.2 @device/deviceLarduino.html#g_t_0040device_002fdisp-3$9.9.3 @device/dispNarduino.html#g_t_0040device_002fflush-1&9.9.4 @device/flushLarduino.html#g_t_0040device_002fread-2$9.9.5 @device/read\arduino.html#g_t_0040device_002freadRegister-149.9.6 @device/readRegisterRarduino.html#g_t_0040device_002fsubsref-3*9.9.7 @device/subsrefNarduino.html#g_t_0040device_002fwrite-2&9.9.8 @device/writeVarduino.html#g_t_0040device_002fwriteRead-1.9.9.9 @device/writeRead^arduino.html#g_t_0040device_002fwriteRegister-189.9.10 @device/writeRegisterRarduino.html#Arduino-Ultrasonic-FunctionsB9.10 Arduino Ultrasonic FunctionsTarduino.html#g_t_0040ultrasonic_002fdelete29.10.1 @ultrasonic/deleteParduino.html#g_t_0040ultrasonic_002fdisp.9.10.2 @ultrasonic/disp`arduino.html#g_t_0040ultrasonic_002freadDistance>9.10.3 @ultrasonic/readDistance`arduino.html#g_t_0040ultrasonic_002freadEchoTime>9.10.4 @ultrasonic/readEchoTimeVarduino.html#g_t_0040ultrasonic_002fsubsref49.10.5 @ultrasonic/subsref\arduino.html#g_t_0040ultrasonic_002fultrasonic:9.10.6 @ultrasonic/ultrasonic6arduino.html#Arduino-Addons&9.11 Arduino Addons$arduino.html#addon9.11.1 addonnarduino.html#arduinoioaddons_002eEEPRomAddon_002eEEPRomR9.11.2 arduinoioaddons.EEPRomAddon.EEPRomlarduino.html#arduinoioaddons_002eExampleAddon_002eEchoP9.11.3 arduinoioaddons.ExampleAddon.Echofarduino.html#arduinoioaddons_002eExampleLCD_002eLCDJ9.11.4 arduinoioaddons.ExampleLCD.LCDharduino.html#arduinoioaddons_002eRTCAddon_002eDS1307L9.11.5 arduinoioaddons.RTCAddon.DS1307arduino.html#arduinoioaddons_002eSimpleStepper_002eSimpleStepperd9.11.6 arduinoioaddons.SimpleStepper.SimpleSteppernarduino.html#arduinoioaddons_002eadafruit_002edcmotorv2R9.11.7 arduinoioaddons.adafruit.dcmotorv2varduino.html#arduinoioaddons_002eadafruit_002emotorshieldv2Z9.11.8 arduinoioaddons.adafruit.motorshieldv2jarduino.html#arduinoioaddons_002eadafruit_002estepperN9.11.9 arduinoioaddons.adafruit.stepper8arduino.html#Arduino-Sensors(9.12 Arduino SensorsJarduino.html#arduinosensor_002eDS130769.12.1 arduinosensor.DS1307Parduino.html#arduinosensor_002eGUVAS12SD<9.12.2 arduinosensor.GUVAS12SDLarduino.html#arduinosensor_002eMPC300289.12.3 arduinosensor.MPC3002Jarduino.html#arduinosensor_002eSI702169.12.4 arduinosensor.SI7021Harduino.html#Arduino-I_002fO-package09.13 Arduino I/O packageHarduino.html#arduinoio_002eAddonBase49.13.1 arduinoio.AddonBaseFarduino.html#arduinoio_002eFilePath29.13.2 arduinoio.FilePathFarduino.html#arduinoio_002eLibFiles29.13.3 arduinoio.LibFilesLarduino.html#arduinoio_002eLibraryBase89.13.4 arduinoio.LibraryBaseRarduino.html#arduinoio_002egetBoardConfig>9.13.5 arduinoio.getBoardConfigRarduino.html#Matlab-Compatibility-ClassesB9.14 Matlab Compatibility Classesfarduino.html#matlabshared_002eaddon_002eLibraryBaseJ9.14.1 matlabshared.addon.LibraryBase(arduino.html#Sensors9.15 Sensors&arduino.html#bme2809.15.1 bme280&arduino.html#bno0559.15.2 bno055&arduino.html#lis3dh9.15.3 lis3dh(arduino.html#lps22hb9.15.4 lps22hb(arduino.html#lsm6dso9.15.5 lsm6dso(arduino.html#mpu60509.15.6 mpu6050&arduino.html#si70219.15.7 si70216arduino.html#Test-Functions&9.16 Test FunctionsDarduino.html#arduino_005fbistsetup09.16.1 arduino_bistsetup(arduino.html#CopyingJAppendix A GNU General Public License$arduino.html#Index Index BT ~d8 ~ V ! N `  R Fs*=Z#b1h+h#[(\+1B+ A@i2cdev/subsrefg_t_0040i2cdev_002fsubsref;A5 K@i2cdev/readRegisterg_t_0040i2cdev_002freadRegister+@% ;@i2cdev/readg_t_0040i2cdev_002fread/?) ?@i2cdev/i2cdevg_t_0040i2cdev_002fi2cdev+>% ;@i2cdev/dispg_t_0040i2cdev_002fdisp/=) ?@i2cdev/deleteg_t_0040i2cdev_002fdelete=<7 M@device/writeRegisterg_t_0040device_002fwriteRegister-;' =@device/writeg_t_0040device_002fwrite1:+ A@device/subsrefg_t_0040device_002fsubsref;95 K@device/readRegisterg_t_0040device_002freadRegister+8% ;@device/readg_t_0040device_002fread+7% ;@device/dispg_t_0040device_002fdisp/6) ?@device/deleteg_t_0040device_002fdeleteC5= S@arduino/writePWMVoltageg_t_0040arduino_002fwritePWMVoltageG4A W@arduino/writePWMDutyCycleg_t_0040arduino_002fwritePWMDutyCycleC3= S@arduino/writeDigitalPing_t_0040arduino_002fwriteDigitalPin32- C@arduino/versiong_t_0040arduino_002fversion;15 K@arduino/validatePing_t_0040arduino_002fvalidatePin10+ A@arduino/uptimeg_t_0040arduino_002fuptimeW/Q g@arduino/setSharedResourcePropertyg_t_0040arduino_002fsetSharedResourceProperty;.5 K@arduino/sendCommandg_t_0040arduino_002fsendCommand/-) ?@arduino/resetg_t_0040arduino_002freset;,5 K@arduino/readVoltageg_t_0040arduino_002freadVoltageA+; Q@arduino/readDigitalPing_t_0040arduino_002freadDigitalPin?*9 O@arduino/readAnalogPing_t_0040arduino_002freadAnalogPin5)/ E@arduino/playToneg_t_0040arduino_002fplayToneG(A W@arduino/isTerminalDigitalg_t_0040arduino_002fisTerminalDigitalE'? U@arduino/isTerminalAnalogg_t_0040arduino_002fisTerminalAnalogQ&K a@arduino/incrementResourceCountg_t_0040arduino_002fincrementResourceCountM%G ]@arduino/getTerminalsFromPinsg_t_0040arduino_002fgetTerminalsFromPinsC$= S@arduino/getTerminalModeg_t_0040arduino_002fgetTerminalModeW#Q g@arduino/getSharedResourcePropertyg_t_0040arduino_002fgetSharedResourcePropertyG"A W@arduino/getServoTerminalsg_t_0040arduino_002fgetServoTerminalsC!= S@arduino/getSPITerminalsg_t_0040arduino_002fgetSPITerminalsE ? U@arduino/getResourceOwnerg_t_0040arduino_002fgetResourceOwnerE? U@arduino/getResourceCountg_t_0040arduino_002fgetResourceCountMG ]@arduino/getPinsFromTerminalsg_t_0040arduino_002fgetPinsFromTerminals93 I@arduino/getPinInfog_t_0040arduino_002fgetPinInfo;5 K@arduino/getPinAliasg_t_0040arduino_002fgetPinAliasC= S@arduino/getPWMTerminalsg_t_0040arduino_002fgetPWMTerminals1+ A@arduino/getMCUg_t_0040arduino_002fgetMCUC= S@arduino/getLEDTerminalsg_t_0040arduino_002fgetLEDTerminalsOI _@arduino/getInterruptTerminalsg_t_0040arduino_002fgetInterruptTerminalsC= S@arduino/getI2CTerminalsg_t_0040arduino_002fgetI2CTerminals71 G@arduino/getEndiang_t_0040arduino_002fgetEndian-' =@arduino/dispg_t_0040arduino_002fdisp1+ A@arduino/deleteg_t_0040arduino_002fdeleteQK a@arduino/decrementResourceCountg_t_0040arduino_002fdecrementResourceCountMG ]@arduino/configurePinResourceg_t_0040arduino_002fconfigurePinResource=7 M@arduino/configurePing_t_0040arduino_002fconfigurePinC= S@arduino/checkI2CAddressg_t_0040arduino_002fcheckI2CAddress3- C@arduino/arduinog_t_0040arduino_002farduino&+ +scanForArduinosscanForArduinos0 5 5listArduinoLibrarieslistArduinoLibraries  isarduinoisarduino % %arduinosetuparduinosetup, / 3Available SensorsAvailable-Sensors-1  !OverviewOverview-1*/ /Available SensorsAvailable-Sensors OverviewOverview6; ;Creating a addon objectCreating-a-addon-objectTY YProgramming the arduino with the addonProgramming-the-arduino-with-the-addonFK KVerify octave can see the addonVerify-octave-can-see-the-addon:? ?Addon package header fileAddon-package-header-file67 ?Addon package .m fileAddon-package-_002em-file6; ;Addon package directoryAddon-package-directory Ct5p) l A  k , y , { L  Q T%]*\'|CIJD;67 ?arduinosensor.MPC3002arduinosensor_002eMPC3002:; Carduinosensor.GUVAS12SDarduinosensor_002eGUVAS12SD45 =arduinosensor.DS1307arduinosensor_002eDS1307PM ]arduinoioaddons.adafruit.stepperarduinoioaddons_002eadafruit_002estepper\Y iarduinoioaddons.adafruit.motorshieldv2arduinoioaddons_002eadafruit_002emotorshieldv2TQ aarduinoioaddons.adafruit.dcmotorv2arduinoioaddons_002eadafruit_002edcmotorv2fc sarduinoioaddons.SimpleStepper.SimpleStepperarduinoioaddons_002eSimpleStepper_002eSimpleStepperN~K [arduinoioaddons.RTCAddon.DS1307arduinoioaddons_002eRTCAddon_002eDS1307L}I Yarduinoioaddons.ExampleLCD.LCDarduinoioaddons_002eExampleLCD_002eLCDR|O _arduinoioaddons.ExampleAddon.Echoarduinoioaddons_002eExampleAddon_002eEchoT{Q aarduinoioaddons.EEPRomAddon.EEPRomarduinoioaddons_002eEEPRomAddon_002eEEPRomz addonaddon?y9 O@ultrasonic/ultrasonicg_t_0040ultrasonic_002fultrasonic9x3 I@ultrasonic/subsrefg_t_0040ultrasonic_002fsubsrefCw= S@ultrasonic/readEchoTimeg_t_0040ultrasonic_002freadEchoTimeCv= S@ultrasonic/readDistanceg_t_0040ultrasonic_002freadDistance3u- C@ultrasonic/dispg_t_0040ultrasonic_002fdisp7t1 G@ultrasonic/deleteg_t_0040ultrasonic_002fdelete?s7 Q@device/writeRegisterg_t_0040device_002fwriteRegister-17r/ I@device/writeReadg_t_0040device_002fwriteRead-1/q' A@device/writeg_t_0040device_002fwrite-23p+ E@device/subsrefg_t_0040device_002fsubsref-3=o5 O@device/readRegisterg_t_0040device_002freadRegister-1-n% ?@device/readg_t_0040device_002fread-2/m' A@device/flushg_t_0040device_002fflush-1-l% ?@device/dispg_t_0040device_002fdisp-31k) C@device/deviceg_t_0040device_002fdevice-11j) C@device/deleteg_t_0040device_002fdelete-3/i' A@device/writeg_t_0040device_002fwrite-13h+ E@device/subsrefg_t_0040device_002fsubsref-2-g% ?@device/readg_t_0040device_002fread-1-f' =@device/flushg_t_0040device_002fflush-e% ?@device/dispg_t_0040device_002fdisp-2/d) ?@device/deviceg_t_0040device_002fdevice1c) C@device/deleteg_t_0040device_002fdelete-25b/ E@spidev/writeReadg_t_0040spidev_002fwriteRead1a+ A@spidev/subsrefg_t_0040spidev_002fsubsref/`) ?@spidev/spidevg_t_0040spidev_002fspidev+_% ;@spidev/dispg_t_0040spidev_002fdisp/^) ?@spidev/deleteg_t_0040spidev_002fdelete5]/ E@device/writeReadg_t_0040device_002fwriteRead3\+ E@device/subsrefg_t_0040device_002fsubsref-1-[% ?@device/dispg_t_0040device_002fdisp-11Z) C@device/deleteg_t_0040device_002fdelete-1;Y5 K@shiftRegister/writeg_t_0040shiftRegister_002fwrite?X9 O@shiftRegister/subsrefg_t_0040shiftRegister_002fsubsrefKWE [@shiftRegister/shiftRegisterg_t_0040shiftRegister_002fshiftRegister;V5 K@shiftRegister/resetg_t_0040shiftRegister_002freset9U3 I@shiftRegister/readg_t_0040shiftRegister_002fread9T3 I@shiftRegister/dispg_t_0040shiftRegister_002fdisp=S7 M@shiftRegister/deleteg_t_0040shiftRegister_002fdelete;R5 K@servo/writePositiong_t_0040servo_002fwritePosition/Q) ?@servo/subsrefg_t_0040servo_002fsubsref+P% ;@servo/servog_t_0040servo_002fservo9O3 I@servo/readPositiong_t_0040servo_002freadPosition)N# 9@servo/dispg_t_0040servo_002fdisp-M' =@servo/deleteg_t_0040servo_002fdelete?L9 O@rotaryEncoder/subsrefg_t_0040rotaryEncoder_002fsubsrefKKE [@rotaryEncoder/rotaryEncoderg_t_0040rotaryEncoder_002frotaryEncoderEJ? U@rotaryEncoder/resetCountg_t_0040rotaryEncoder_002fresetCountCI= S@rotaryEncoder/readSpeedg_t_0040rotaryEncoder_002freadSpeedCH= S@rotaryEncoder/readCountg_t_0040rotaryEncoder_002freadCount9G3 I@rotaryEncoder/dispg_t_0040rotaryEncoder_002fdisp=F7 M@rotaryEncoder/deleteg_t_0040rotaryEncoder_002fdeleteE! !scanI2CbusscanI2Cbus=D7 M@i2cdev/writeRegisterg_t_0040i2cdev_002fwriteRegister-C' =@i2cdev/writeg_t_0040i2cdev_002fwrite  a.gP9" ./ 7arduino_bistsetuparduino_005fbistsetup si7021si7021 mpu6050mpu6050 lsm6dsolsm6dso lps22hblps22hb lis3dhlis3dh bno055bno055  bme280bme280L I Ymatlabshared.addon.LibraryBasematlabshared_002eaddon_002eLibraryBase< = Earduinoio.getBoardConfigarduinoio_002egetBoardConfig6 7 ?arduinoio.LibraryBasearduinoio_002eLibraryBase0 1 9arduinoio.LibFilesarduinoio_002eLibFiles01 9arduinoio.FilePatharduinoio_002eFilePath23 ;arduinoio.AddonBasearduinoio_002eAddonBase45 =arduinosensor.SI7021arduinosensor_002eSI7021arduino-0.12.2/doc/arduino.qhc0000644000000000000000000040000014777724260013100 0ustar00SQLite format 3@ # #.v $  w h z H"f| b''tableVersionFilterVersionFilterCREATE TABLE VersionFilter (Version TEXT, FilterId INTEGER)n++tableComponentFilterComponentFilterCREATE TABLE ComponentFilter (ComponentName TEXT, FilterId INTEGER)u--tableComponentMappingComponentMappingCREATE TABLE ComponentMapping (ComponentId INTEGER, NamespaceId INTEGER)q))tableComponentTableComponentTableCREATE TABLE ComponentTable (ComponentId INTEGER PRIMARY KEY, Name TEXT)VtableFilterFilterCREATE TABLE Filter (FilterId INTEGER PRIMARY KEY, Name TEXT)b%%tableVersionTableVersionTableCREATE TABLE VersionTable (NamespaceId INTEGER, Version TEXT)))mtableTimeStampTableTimeStampTableCREATE TABLE TimeStampTable (NamespaceId INTEGER, FolderId INTEGER, FilePath TEXT, Size INTEGER, TimeStamp TEXT)551tableOptimizedFilterTableOptimizedFilterTableCREATE TABLE OptimizedFilterTable (NamespaceId INTEGER, FilterAttributeId INTEGER)(77otableFileAttributeSetTableFileAttributeSetTableCREATE TABLE FileAttributeSetTable (NamespaceId INTEGER, FilterAttributeSetId INTEGER, FilterAttributeId INTEGER) 33/tableContentsFilterTableContentsFilterTableCREATE TABLE ContentsFilterTable (FilterAttributeId INTEGER, ContentsId INTEGER )w --!tableIndexFilterTableIndexFilterTable CREATE TABLE IndexFilterTable (FilterAttributeId INTEGER, IndexId INTEGER)s ++tableFileFilterTableFileFilterTable CREATE TABLE FileFilterTable (FilterAttributeId INTEGER, FileId INTEGER)z ''3tableContentsTableContentsTable CREATE TABLE ContentsTable (Id INTEGER PRIMARY KEY, NamespaceId INTEGER, Data BLOB) !! tableIndexTableIndexTable CREATE TABLE IndexTable (Id INTEGER PRIMARY KEY, Name TEXT, Identifier TEXT, NamespaceId INTEGER, FileId INTEGER, Anchor TEXT)''MtableFileNameTableFileNameTable CREATE TABLE FileNameTable (FolderId INTEGER, Name TEXT, FileId INTEGER PRIMARY KEY, Title TEXT)e'' tableSettingsTableSettingsTableCREATE TABLE SettingsTable (Key TEXT PRIMARY KEY, Value BLOB )9M'indexsqlite_autoindex_SettingsTable_1SettingsTableh##tableFilterTableFilterTableCREATE TABLE FilterTable (NameId INTEGER, FilterAttributeId INTEGER )l++tableFilterNameTableFilterNameTableCREATE TABLE FilterNameTable (Id INTEGER PRIMARY KEY, Name TEXT ){55tableFilterAttributeTableFilterAttributeTableCREATE TABLE FilterAttributeTable (Id INTEGER PRIMARY KEY, Name TEXT )u##1tableFolderTableFolderTableCREATE TABLE FolderTable (Id INTEGER PRIMARY KEY, NamespaceId INTEGER, Name TEXT )x))+tableNamespaceTableNamespaceTableCREATE TABLE NamespaceTable (Id INTEGER PRIMARY KEY, Name TEXT, FilePath TEXT ) '=#octave.community.arduinoarduino.qch  doc    #{fS>#9FullTextSearchFallback%CreationTimeg) HideAddressBar- EnableAddressBarA EnableDocumentationManager; HideFilterFunctionality? EnableFilterFunctionality*-;LastRegisterTime2025-04-16T08:56:27.093 ?Z~?k9FullTextSearchFallback%CreationTime)HideAddressBar-EnableAddressBarAEnableDocumentationManager;HideFilterFunctionality?EnableFilterFunctionality- LastRegisterTime  ##arduino.cssarduino.css` %)arduino.htmlArduino Toolkit - a somewhat Matlab compatible arduino toolkit for GNU octave.C XX arduino.htmlArduino Toolkit - a somewhat Matlab compatible arduino toolkit for GNU octave. ManualFarduino.html#Installing-and-loading01 Installing and loadingDarduino.html#Online-Direct-install21.1 Online Direct installBarduino.html#Off_002dline-install(1.2 Off-line install(arduino.html#Loading1.3 Loading6arduino.html#Hardware-setup 2 Hardware setupHarduino.html#Programming-the-Arduino62.1 Programming the ArduinoLarduino.html#Known-Arduino-Board-Types:2.2 Known Arduino Board TypesJarduino.html#Connecting-to-an-arduino43 Connecting to an arduinoVarduino.html#Connecting-to-a-single-arduinoD3.1 Connecting to a single arduinoZarduino.html#Connecting-to-a-specific-arduinoH3.2 Connecting to a specific arduinoParduino.html#Querying-available-arduinos>3.3 Querying available arduinosXarduino.html#Basic-Input-and-Output-OverviewB4 Basic Input and Output OverviewNarduino.html#Performing-Digital-I_002fO44.1 Performing Digital I/OHarduino.html#Performing-Analog-Input64.2 Performing Analog InputXarduino.html#Protocol-based-I_002fO-Overview:5 Protocol based I/O Overview<arduino.html#SPI-communication*5.1 SPI communication<arduino.html#I2C-communication*5.2 I2C communication@arduino.html#Servo-communication.5.3 Servo communication8arduino.html#Shift-Registers&5.4 Shift Registers8arduino.html#Rotary-Encoders&5.5 Rotary Encoders>arduino.html#Ultrasonic-Sensors,5.6 Ultrasonic SensorsBarduino.html#Serial-communication05.7 Serial communication8arduino.html#Addons-Overview"6 Addons Overview>arduino.html#Addon-Introduction,6.1 Addon Introduction<arduino.html#Creating-an-addon*6.2 Creating an addonHarduino.html#Addon-package-directory:6.2.1 Addon package directoryLarduino.html#Addon-package-_002em-file66.2.2 Addon package .m fileLarduino.html#Addon-package-header-file>6.2.3 Addon package header fileXarduino.html#Verify-octave-can-see-the-addonJ6.2.4 Verify octave ca      ' #3arduino.qchP2025-04-16T08:56:27   doc    CWk@% d 0 `  v 2 l ( d LbL ^"\(X(b4j>,C' =@i2cdev/writeg_t_0040i2cdev_002fwrite0B+ A@i2cdev/subsrefg_t_0040i2cdev_002fsubsref:A5 K@i2cdev/readRegisterg_t_0040i2cdev_002freadRegister*@% ;@i2cdev/readg_t_0040i2cdev_002fread.?) ?@i2cdev/i2cdevg_t_0040i2cdev_002fi2cdev*>% ;@i2cdev/dispg_t_0040i2cdev_002fdisp.=) ?@i2cdev/deleteg_t_0040i2cdev_002fdelete<<7 M@device/writeRegisterg_t_0040device_002fwriteRegister,;' =@device/writeg_t_0040device_002fwrite0:+ A@device/subsrefg_t_0040device_002fsubsref:95 K@device/readRegisterg_t_0040device_002freadRegister*8% ;@device/readg_t_0040device_002fread*7% ;@device/dispg_t_0040device_002fdisp.6) ?@device/deleteg_t_0040device_002fdeleteB5= S@arduino/writePWMVoltageg_t_0040arduino_002fwritePWMVoltageF4A W@arduino/writePWMDutyCycleg_t_0040arduino_002fwritePWMDutyCycleB3= S@arduino/writeDigitalPing_t_0040arduino_002fwriteDigitalPin22- C@arduino/versiong_t_0040arduino_002fversion:15 K@arduino/validatePing_t_0040arduino_002fvalidatePin00+ A@arduino/uptimeg_t_0040arduino_002fuptimeV/Q g@arduino/setSharedResourcePropertyg_t_0040arduino_002fsetSharedResourceProperty:.5 K@arduino/sendCommandg_t_0040arduino_002fsendCommand.-) ?@arduino/resetg_t_0040arduino_002freset:,5 K@arduino/readVoltageg_t_0040arduino_002freadVoltage@+; Q@arduino/readDigitalPing_t_0040arduino_002freadDigitalPin>*9 O@arduino/readAnalogPing_t_0040arduino_002freadAnalogPin4)/ E@arduino/playToneg_t_0040arduino_002fplayToneF(A W@arduino/isTerminalDigitalg_t_0040arduino_002fisTerminalDigitalD'? U@arduino/isTerminalAnalogg_t_0040arduino_002fisTerminalAnalogP&K a@arduino/incrementResourceCountg_t_0040arduino_002fincrementResourceCountL%G ]@arduino/getTerminalsFromPinsg_t_0040arduino_002fgetTerminalsFromPinsB$= S@arduino/getTerminalModeg_t_0040arduino_002fgetTerminalModeV#Q g@arduino/getSharedResourcePropertyg_t_0040arduino_002fgetSharedResourcePropertyF"A W@arduino/getServoTerminalsg_t_0040arduino_002fgetServoTerminalsB!= S@arduino/getSPITerminalsg_t_0040arduino_002fgetSPITerminalsD ? U@arduino/getResourceOwnerg_t_0040arduino_002fgetResourceOwnerD? U@arduino/getResourceCountg_t_0040arduino_002fgetResourceCountLG ]@arduino/getPinsFromTerminalsg_t_0040arduino_002fgetPinsFromTerminals83 I@arduino/getPinInfog_t_0040arduino_002fgetPinInfo:5 K@arduino/getPinAliasg_t_0040arduino_002fgetPinAliasB= S@arduino/getPWMTerminalsg_t_0040arduino_002fgetPWMTerminals0+ A@arduino/getMCUg_t_0040arduino_002fgetMCUB= S@arduino/getLEDTerminalsg_t_0040arduino_002fgetLEDTerminalsNI _@arduino/getInterruptTerminalsg_t_0040arduino_002fgetInterruptTerminalsB= S@arduino/getI2CTerminalsg_t_0040arduino_002fgetI2CTerminals61 G@arduino/getEndiang_t_0040arduino_002fgetEndian,' =@arduino/dispg_t_0040arduino_002fdisp0+ A@arduino/deleteg_t_0040arduino_002fdeletePK a@arduino/decrementResourceCountg_t_0040arduino_002fdecrementResourceCountLG ]@arduino/configurePinResourceg_t_0040arduino_002fconfigurePinResource<7 M@arduino/configurePing_t_0040arduino_002fconfigurePinB= S@arduino/checkI2CAddressg_t_0040arduino_002fcheckI2CAddress2- C@arduino/arduinog_t_0040arduino_002farduino%+ +scanForArduinosscanForArduinos/ 5 5listArduinoLibrarieslistArduinoLibraries  isarduinoisarduino % %arduinosetuparduinosetup+ / 3Available SensorsAvailable-Sensors-1  !OverviewOverview-1)/ /Available SensorsAvailable-Sensors OverviewOverview5; ;Creating a addon objectCreating-a-addon-objectSY YProgramming the arduino with the addonProgramming-the-arduino-with-the-addonEK KVerify octave can see the addonVerify-octave-can-see-the-addon9? ?Addon package header fileAddon-package-header-file57 ?Addon package .m fileAddon-package-_002em-file5; ;Addon package directoryAddon-package-directory Dg-_ { A  k 1 o / _ ) k 5 wIS#So+mZeYs713 ;arduinoio.AddonBasearduinoio_002eAddonBase35 =arduinosensor.SI7021arduinosensor_002eSI702157 ?arduinosensor.MPC3002arduinosensor_002eMPC30029; Carduinosensor.GUVAS12SDarduinosensor_002eGUVAS12SD35 =arduinosensor.DS1307arduinosensor_002eDS1307OM ]arduinoioaddons.adafruit.stepperarduinoioaddons_002eadafruit_002estepper[Y iarduinoioaddons.adafruit.motorshieldv2arduinoioaddons_002eadafruit_002emotorshieldv2SQ aarduinoioaddons.adafruit.dcmotorv2arduinoioaddons_002eadafruit_002edcmotorv2ec sarduinoioaddons.SimpleStepper.SimpleStepperarduinoioaddons_002eSimpleStepper_002eSimpleStepperM~K [arduinoioaddons.RTCAddon.DS1307arduinoioaddons_002eRTCAddon_002eDS1307K}I Yarduinoioaddons.ExampleLCD.LCDarduinoioaddons_002eExampleLCD_002eLCDQ|O _arduinoioaddons.ExampleAddon.Echoarduinoioaddons_002eExampleAddon_002eEchoS{Q aarduinoioaddons.EEPRomAddon.EEPRomarduinoioaddons_002eEEPRomAddon_002eEEPRomz addonaddon>y9 O@ultrasonic/ultrasonicg_t_0040ultrasonic_002fultrasonic8x3 I@ultrasonic/subsrefg_t_0040ultrasonic_002fsubsrefBw= S@ultrasonic/readEchoTimeg_t_0040ultrasonic_002freadEchoTimeBv= S@ultrasonic/readDistanceg_t_0040ultrasonic_002freadDistance2u- C@ultrasonic/dispg_t_0040ultrasonic_002fdisp6t1 G@ultrasonic/deleteg_t_0040ultrasonic_002fdelete>s7 Q@device/writeRegisterg_t_0040device_002fwriteRegister-16r/ I@device/writeReadg_t_0040device_002fwriteRead-1.q' A@device/writeg_t_0040device_002fwrite-22p+ E@device/subsrefg_t_0040device_002fsubsref-3X9 O@shiftRegister/subsrefg_t_0040shiftRegister_002fsubsrefJWE [@shiftRegister/shiftRegisterg_t_0040shiftRegister_002fshiftRegister:V5 K@shiftRegister/resetg_t_0040shiftRegister_002freset8U3 I@shiftRegister/readg_t_0040shiftRegister_002fread8T3 I@shiftRegister/dispg_t_0040shiftRegister_002fdispL9 O@rotaryEncoder/subsrefg_t_0040rotaryEncoder_002fsubsrefJKE [@rotaryEncoder/rotaryEncoderg_t_0040rotaryEncoder_002frotaryEncoderDJ? U@rotaryEncoder/resetCountg_t_0040rotaryEncoder_002fresetCountBI= S@rotaryEncoder/readSpeedg_t_0040rotaryEncoder_002freadSpeedBH= S@rotaryEncoder/readCountg_t_0040rotaryEncoder_002freadCount8G3 I@rotaryEncoder/dispg_t_0040rotaryEncoder_002fdisp7.2 Lightweight Arduino Sensors.arduino.html#Overview-17.2.1 Overview@arduino.html#Available-Sensors-1.7.2.2 Available Sensors*arduino.html#Examples8 Examples8arduino.html#Blinking-an-LED&8.1 Blinking an LEDharduino.html#Using-I2C-to-communicate-with-an-EEPROMV8.2 Using I2C to communicate with an EEPROM~arduino.html#Using-SPI-to-communicate-with-a-mcp3002-10-bit-ADCl8.3 Using SPI to communicate with a mcp3002 10 bit ADC>arduino.html#Function-Reference(9 Function Reference<arduino.html#General-Functions*9.1 General Functions2arduino.html#arduinosetup$9.1.1 arduinosetup,arduino.html#isarduino9.1.2 isarduinoBarduino.html#listArduinoLibraries49.1.3 listArduinoLibraries8arduino.html#scanForArduinos*9.1.4 scanForArduinos<arduino.html#Arduino-Functions*9.2 Arduino FunctionsParduino.html#g_t_0040arduino_002farduino,9.2.1 @arduino/arduino`arduino.html#g_t_0040arduino_002fcheckI2CAddress<9.2.2 @arduino/checkI2CAddressZarduino.html#g_t_0040arduino_002fconfigurePin69.2.3 @arduino/configurePinjarduino.html#g_t_0040arduino_002fconfigurePinResourceF9.2.4 @arduino/configurePinResourcenarduino.html#g_t_0040arduino_002fdecrementResourceCountJ9.2.5 @arduino/decrementResourceCountNarduino.html#g_t_0040arduino_002fdelete*9.2.6 @arduino/deleteJarduino.html#g_t_0040arduino_002fdisp&9.2.7 @arduino/dispTarduino.html#g_t_0040arduino_002fgetEndian09.2.8 @arduino/getEndian`arduino.html#g_t_0040arduino_002fgetI2CTerminals<9.2.9 @arduino/getI2CTerminalslarduino.html#g_t_0040arduino_002fgetInterruptTerminalsJ9.2.10 @arduino/getInterruptTerminals`arduino.html#g_t_0040arduino_002fgetLEDTerminals>9.2.11 @arduino/getLEDTerminalsNarduino.html#g_t_0040arduino_002fgetMCU,9.2.12 @arduino/getMCU`arduino.html#g_t_0040arduino_002fgetPWMTerminals>9.2.13 @arduino/getPWMTerminalsXarduino.html#g_t_0040arduino_002fgetPinAlias69.2.14 @arduino/getPinAliasVarduino.html#g_t_0040arduino_002fgetPinInfo49.2.15 @arduino/getPinInfojarduino.html#g_t_0040arduino_002fgetPinsFromTerminalsH9.2.16 @arduino/getPinsFromTerminalsbarduino.html#g_t_0040arduino_002fgetResourceCount@9.2.17 @arduino/getResourceCountbarduino.html#g_t_0040arduino_002fgetResourceOwner@9.2.18 @arduino/getResourceOwner`arduino.html#g_t_0040arduino_002fgetSPITerminals>9.2.19 @arduino/getSPITerminalsdarduino.html#g_t_0040arduino_002fgetServoTerminalsB9.2.20 @arduino/getServoTerminalstarduino.html#g_t_0040arduino_002fgetSharedResourcePropertyR9.2.21 @arduino/getSharedResourceProperty`arduino.html#g_t_0040arduino_002fgetTerminalMode>9.2.22 @arduino/getTerminalModejarduino.html#g_t_0040arduino_002fgetTerminalsFromPinsH9.2.23 @arduino/getTerminalsFromPinsnarduino.html#g_t_0040arduino_002fincrementResourceCountL9.2.24 @arduino/incrementResourceCountbarduino.html#g_t_0040arduino_002fisTerminalAnalog@9.2.25 @arduino/isTerminalAnalogdarduino.html#g_t_0040arduino_002fisTerminalDigitalB9.2.26 @arduino/isTerminalDigitalRarduino.html#g_t_0040arduino_002fplayTone09.2.27 @arduino/playTone\arduino.html#g_t_0040arduino_002freadAnalogPin:9.2.28 @arduino/readAnalogPin^arduino.html#g_t_0040arduino_002freadDigitalPin<9.2.29 @arduino/readDigitalPinXarduino.html#g_t_0040arduino_002freadVoltage69.2.30 @arduino/readVoltageLarduino.html#g_t_0040arduino_002freset*9.2.31 @arduino/resetXarduino.html#g_t_0040arduino_002fsendCommand69.2.32 @arduino/sendCommandtarduino.html#g_t_0040arduino_002fsetSharedResourcePropertyR9.2.33 @arduino/setSharedResourcePropertyNarduino.html#g_t_0040arduino_002fuptime,9.2.34 @arduino/uptimeXarduino.html#g_t_0040arduino_002fvalidatePin69.2.35 @arduino/validatePinParduino.html#g_t_0040arduino_002fversion.9.2.36 @arduino/version`arduino.html#g_t_0040arduino_002fwriteDigitalPin>9.2.37 @arduino/writeDigitalPindarduino.html#g_t_0040arduino_002fwritePWMDutyCycleB9.2.38 @arduino/writePWMDutyCycle`arduino.html#g_t_0040arduino_002fwritePWMVoltage>9.2.39 @arduino/writePWMVoltageDarduino.html#Arduino-I2C-Functions29.3 Arduino I2C FunctionsLarduino.html#g_t_0040device_002fdelete(9.3.1 @device/deleteHarduino.html#g_t_0040device_002fdisp$9.3.2 @device/dispHarduino.html#g_t_0040device_002fread$9.3.3 @device/readXarduino.html#g_t_0040device_002freadRegister49.3.4 @device/readRegisterNarduino.html#g_t_0040device_002fsubsref*9.3.5 @device/subsrefJarduino.html#g_t_0040device_002fwrite&9.3.6 @device/writeZarduino.html#g_t_0040device_002fwriteRegister69.3.7 @device/writeRegisterLarduino.html#g_t_0040i2cdev_002fdelete(9.3.8 @i2cdev/deleteHarduino.html#g_t_0040i2cdev_002fdisp$9.3.9 @i2cdev/dispLarduino.html#g_t_0040i2cdev_002fi2cdev*9.3.10 @i2cdev/i2cdevHarduino.html#g_t_0040i2cdev_002fread&9.3.11 @i2cdev/readXarduino.html#g_t_0040i2cdev_002freadRegister69.3.12 @i2cdev/readRegisterNarduino.html#g_t_0040i2cdev_002fsubsref,9.3.13 @i2cdev/subsrefJarduino.html#g_t_0040i2cdev_002fwrite(9.3.14 @i2cdev/writeZarduino.html#g_t_0040i2cdev_002fwriteRegister89.3.15 @i2cdev/writeRegister.arduino.html#scanI2Cbus"9.3.16 scanI2CbusZarduino.html#Arduino-Rotary-Encoder-FunctionsH9.4 Arduino Rotary Encoder FunctionsZarduino.html#g_t_0040rotaryEncoder_002fdelete69.4.1 @rotaryEncoder/deleteVarduino.html#g_t_0040rotaryEncoder_002fdisp29.4.2 @rotaryEncoder/disp`arduino.html#g_t_0040rotaryEncoder_002freadCount<9.4.3 @rotaryEncoder/readCount`arduino.html#g_t_0040rotaryEncoder_002freadSpeed<9.4.4 @rotaryEncoder/readSpeedbarduino.html#g_t_0040rotaryEncoder_002fresetCount>9.4.5 @rotaryEncoder/resetCountharduino.html#g_t_0040rotaryEncoder_002frotaryEncoderD9.4.6 @rotaryEncoder/rotaryEncoder\arduino.html#g_t_0040rotaryEncoder_002fsubsref89.4.7 @rotaryEncoder/subsrefHarduino.html#Arduino-Servo-Functions69.5 Arduino Servo FunctionsJarduino.html#g_t_0040servo_002fdelete&9.5.1 @servo/deleteFarduino.html#g_t_0040servo_002fdisp"9.5.2 @servo/dispVarduino.html#g_t_0040servo_002freadPosition29.5.3 @servo/readPositionHarduino.html#g_t_0040servo_002fservo$9.5.4 @servo/servoLarduino.html#g_t_0040servo_002fsubsref(9.5.5 @servo/subsrefXarduino.html#g_t_0040servo_002fwritePosition49.5.6 @servo/writePositionXarduino.html#Arduino-Shiftregister-FunctionsF9.6 Arduino Shiftregister FunctionsZarduino.html#g_t_0040shiftRegister_002fdelete69.6.1 @shiftRegister/deleteVarduino.html#g_t_0040shiftRegister_002fdisp29.6.2 @shiftRegister/dispVarduino.html#g_t_0040shiftRegister_002fread29.6.3 @shiftRegister/readXarduino.html#g_t_0040shiftRegister_002freset49.6.4 @shiftRegister/resetharduino.html#g_t_0040shiftRegister_002fshiftRegisterD9.6.5 @shiftRegister/shiftRegister\arduino.html#g_t_0040shiftRegister_002fsubsref89.6.6 @shiftRegister/subsrefXarduino.html#g_t_0040shiftRegister_002fwrite49.6.7 @shiftRegister/writeDarduino.html#Arduino-SPI-Functions29.7 Arduino SPI FunctionsParduino.html#g_t_0040device_002fdelete-1(9.7.1 @device/deleteLarduino.html#g_t_0040device_002fdisp-1$9.7.2 @device/dispRarduino.html#g_t_0040device_002fsubsref-1*9.7.3 @device/subsrefRarduino.html#g_t_0040device_002fwriteRead.9.7.4 @device/writeReadLarduino.html#g_t_0040spidev_002fdelete(9.7.5 @spidev/deleteHarduino.html#g_t_0040spidev_002fdisp$9.7.6 @spidev/dispLarduino.html#g_t_0040spidev_002fspidev(9.7.7 @spidev/spidevNarduino.html#g_t_0040spidev_002fsubsref*9.7.8 @spidev/subsrefRarduino.html#g_t_0040spidev_002fwriteRead.9.7.9 @spidev/writeReadJarduino.html#Arduino-Serial-Functions89.8 Arduino Serial FunctionsParduino.html#g _t_0040device_002fdelete-2(9.8.1 @device/deleteLarduino.html#g_t_0040device_002fdevice(9.8.2 @device/deviceLarduino.html#g_t_0040device_002fdisp-2$9.8.3 @device/dispJarduino.html#g_t_0040device_002fflush&9.8.4 @device/flushLarduino.html#g_t_0040device_002fread-1$9.8.5 @device/readRarduino.html#g_t_0040device_002fsubsref-2*9.8.6 @device/subsrefNarduino.html#g_t_0040device_002fwrite-1&9.8.7 @device/writeJarduino.html#Arduino-Device-Functions89.9 Arduino Device FunctionsParduino.html#g_t_0040device_002fdelete-3(9.9.1 @device/deleteParduino.html#g_t_0040device_002fdevice-1(9.9.2 @device/deviceLarduino.html#g_t_0040device_002fdisp-3$9.9.3 @device/dispNarduino.html#g_t_0040device_002fflush-1&9.9.4 @device/flushLarduino.html#g_t_0040device_002fread-2$9.9.5 @device/read\arduino.html#g_t_0040device_002freadRegister-149.9.6 @device/readRegisterRarduino.html#g_t_0040device_002fsubsref-3*9.9.7 @device/subsrefNarduino.html#g_t_0040device_002fwrite-2&9.9.8 @device/writeVarduino.html#g_t_0040device_002fwriteRead-1.9.9.9 @device/writeRead^arduino.html#g_t_0040device_002fwriteRegister-189.9.10 @device/writeRegisterRarduino.html#Arduino-Ultrasonic-FunctionsB9.10 Arduino Ultrasonic FunctionsTarduino.html#g_t_0040ultrasonic_002fdelete29.10.1 @ultrasonic/deleteParduino.html#g_t_0040ultrasonic_002fdisp.9.10.2 @ultrasonic/disp`arduino.html#g_t_0040ultrasonic_002freadDistance>9.10.3 @ultrasonic/readDistance`arduino.html#g_t_0040ultrasonic_002freadEchoTime>9.10.4 @ultrasonic/readEchoTimeVarduino.html#g_t_0040ultrasonic_002fsubsref49.10.5 @ultrasonic/subsref\arduino.html#g_t_0040ultrasonic_002fultrasonic:9.10.6 @ultrasonic/ultrasonic6arduino.html#Arduino-Addons&9.11 Arduino Addons$arduino.html#addon9.11.1 addonnarduino.html#arduinoioaddons_002eEEPRomAddon_002eEEPRomR9.11.2 arduinoioaddons.EEPRomAddon.EEPRomlarduino.html#arduinoioaddons_002eExampleAddon_002eEchoP9.11.3 arduinoioaddons.ExampleAddon.Echofarduino.html#arduinoioaddons_002eExampleLCD_002eLCDJ9.11.4 arduinoioaddons.ExampleLCD.LCDharduino.html#arduinoioaddons_002eRTCAddon_002eDS1307L9.11.5 arduinoioaddons.RTCAddon.DS1307arduino.html#arduinoioaddons_002eSimpleStepper_002eSimpleStepperd9.11.6 arduinoioaddons.SimpleStepper.SimpleSteppernarduino.html#arduinoioaddons_002eadafruit_002edcmotorv2R9.11.7 arduinoioaddons.adafruit.dcmotorv2varduino.html#arduinoioaddons_002eadafruit_002emotorshieldv2Z9.11.8 arduinoioaddons.adafruit.motorshieldv2jarduino.html#arduinoioaddons_002eadafruit_002estepperN9.11.9 arduinoioaddons.adafruit.stepper8arduino.html#Arduino-Sensors(9.12 Arduino SensorsJarduino.html#arduinosensor_002eDS130769.12.1 arduinosensor.DS1307Parduino.html#arduinosensor_002eGUVAS12SD<9.12.2 arduinosensor.GUVAS12SDLarduino.html#arduinosensor_002eMPC300289.12.3 arduinosensor.MPC3002Jarduino.html#arduinosensor_002eSI702169.12.4 arduinosensor.SI7021Harduino.html#Arduino-I_002fO-package09.13 Arduino I/O packageHarduino.html#arduinoio_002eAddonBase49.13.1 arduinoio.AddonBaseFarduino.html#arduinoio_002eFilePath29.13.2 arduinoio.FilePathFarduino.html#arduinoio_002eLibFiles29.13.3 arduinoio.LibFilesLarduino.html#arduinoio_002eLibraryBase89.13.4 arduinoio.LibraryBaseRarduino.html#arduinoio_002egetBoardConfig>9.13.5 arduinoio.getBoardConfigRarduino.html#Matlab-Compatibility-ClassesB9.14 Matlab Compatibility Classesfarduino.html#matlabshared_002eaddon_002eLibraryBaseJ9.14.1 matlabshared.addon.LibraryBase(arduino.html#Sensors9.15 Sensors&arduino.html#bme2809.15.1 bme280&arduino.html#bno0559.15.2 bno055&arduino.html#lis3dh9.15.3 lis3dh(arduino.html#lps22hb9.15.4 lps22hb(arduino.html#lsm6dso9.15.5 lsm6dso(arduino.html#mpu60509.15.6 mpu6050&arduino.html#si70219.15.7 si70216arduino.html#Test-Functions&9.16 Test FunctionsDarduino.html#arduino_005fbistsetup09.16.1 arduino_bistsetup(arduino.html#CopyingJAppendix A GNU General Public License$arduino.html#Index Indexarduino-0.12.2/doc/arduino.texi0000644000000000000000000007627214777724260013322 0ustar00\input texinfo @c -*-texinfo-*- @c Copyright (c) 2018-2024, John Donoghue @c Octave Arduino - a somewhat Matlab compatible Arduino toolkit for GNU octave. @c For manually generating the documentation use @c LANGUAGE=en makeinfo --html --no-split arduino.texi @c %*** Start of HEADER @setfilename arduino.info @settitle Arduino Toolkit - a somewhat Matlab compatible arduino toolkit for GNU octave. @afourpaper @paragraphindent 0 @finalout @set COPYRIGHT_DATE 2018-2024 @c @afourwide @c %*** End of the HEADER @include version.texi @include macros.texi @macro boxnote {args} @cartouche @strong{NOTE} \args\ @end cartouche @end macro @c %*** Start of TITLEPAGE @titlepage @title Arduino Toolkit @value{VERSION} @subtitle a somewhat MATLAB compatible Arduino toolkit for @acronym{GNU} Octave. @author John Donoghue @page @vskip 0pt plus 1filll Copyright @copyright{} @value{COPYRIGHT_DATE} John Donoghue Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the same conditions as for modified versions. @page @heading Distribution The @acronym{GNU} Octave arduino package is @dfn{free} software. Free software is a matter of the users' freedom to run, copy, distribute, study, change and improve the software. This means that everyone is free to use it and free to redistribute it on certain conditions. The @acronym{GNU} Octave arduino package is not, however, in the public domain. It is copyrighted and there are restrictions on its distribution, but the restrictions are designed to ensure that others will have the same freedom to use and redistribute Octave that you have. The precise conditions can be found in the @acronym{GNU} General Public License that comes with the @acronym{GNU} Octave arduino package and that also appears in @ref{Copying}. To download a copy of the @acronym{GNU} Octave arduino package, please visit @url{https://github.com/gnu-octave/octave-arduino/releases}. @end titlepage @c %*** End of TITLEPAGE @c %*** Start of BODY @dircategory Math @direntry * Arduino for Octave: (arduino). Arduino Toolbox for Octave @end direntry @contents @ifnottex @node Top @top Introduction The Arduino toolkit is a somewhat Matlab compatible arduino toolkit for GNU octave. @end ifnottex @menu * Installing and loading:: Installing and loading the Arduino toolkit * Hardware setup:: Setting up the Arduino hardware * Connecting to an arduino:: Making a connection to an arduino device * Basic Input and Output Overview:: Performing basic I/O * Protocol based I/O Overview:: Performing protocol based I/O * Addons Overview:: Arduino Addons * Sensors Overview:: Sensors * Examples:: Examples using the Arduino toolkit * Function Reference:: Arduino toolkit functions * Copying:: Copying * Index:: Index @end menu @c ------------------------------------------------------------------------- @node Installing and loading @chapter Installing and loading @cindex Installing and loading The Arduino toolkit must be installed and then loaded to be used. It can be installed in @acronym{GNU} Octave directly from octave-forge, or can be installed in an off-line mode via a downloaded tarball. @boxnote{The toolkit requires the @url{https://www.arduino.cc/en/software, Arduino IDE} in order to program Arduino devices.} @boxnote{The toolkit has a dependency on the instrument-control package, so it must be installed in order to successfully install the Arduino toolkit} The toolkit must be then be loaded once per each @acronym{GNU} Octave session in order to use its functionality. @section Online Direct install @cindex Online install With an internet connection available, the Arduino package can be installed from octave-forge using the following command within @acronym{GNU} Octave: @example pkg install -forge arduino @end example The latest released version of the toolkit will be downloaded and installed. @section Off-line install @cindex Off-line install With the arduino toolkit package already downloaded, and in the current directory when running @acronym{GNU} Octave, the package can be installed using the following command within @acronym{GNU} Octave: @example pkg install arduino-@value{VERSION}.tar.gz @end example @section Loading @cindex Loading Regardless of the method of installing the Arduino toolkit, in order to use its functions, the toolkit must be loaded using the pkg load command: @example pkg load arduino @end example The toolkit must be loaded on each @acronym{GNU} Octave session. @c ------------------------------------------------------------------------- @node Hardware setup @chapter Hardware setup @cindex Hardware setup In order to use the arduino hardware with the toolkit, it must be programmed with special firmware. @section Programming the Arduino @cindex Programming the Arduino To program the hardware, using a default configuration, run the arduinosetup command: @example arduinosetup @end example A temporary Arduino project will be created, with the Arduino toolkit files copied to it and the Arduino IDE will open. Set the board type and port correctly for the connected Arduino and press the upload button on the IDE. The sources will be compiled and then uploaded to the connected arduino board. After successful upload the Arduino IDE should be closed. @boxnote{The arduino programming is not compatible with the Matlab arduino library, so must be programmed by the Octave Arduino toolkit to communicate to the arduino, even if it was previously used to work with Matlab.} @boxnote{The toolkit requires the @url{https://www.arduino.cc/en/software, Arduino IDE} in order to program the Arduino device. The binary can set using the 'arduinobinary' property when running setup. For arduino IDEs before version 2, if the toolkit can not find the IDE, run the IDE manually, close it and retry programming the Arduino. Otherwise, use the 'arduino' binary property.} @section Known Arduino Board Types @cindex Known Arduino Board Types The board type must be known in order to successfully detect and connect to the Arduino board after programming. Currently, known boards are: @itemize @bullet @item Arduino Due @item Arduino UNO @item Arduino Mega 2560 @item Arduino Nano @item Arduino Nano Every @item Arduino Nano 33 BLE @item Arduino Nano RP2040 Connect @item Arduino Pro/Pro Mini @item Arduino Pro Micro @item Arduino Leonardo @item Arduino Micro @item Arduino MKR1000 @item Arduino MKRZero @item Sparkfun SAMD21 @item Arduino Lilypad @item Arduino UNO WiFi rev2 @boxnote{The Arduino servo library code may require modifications to eliminate conflicts between servos and the tone library} @item Arduino UNO WiFi r4 @item Arduino UNO Minima r4 @item Raspberry Pi Pico @item EPS32 Dev @end itemize Additional boards can be added easily, however require minor code changes. @c ------------------------------------------------------------------------- @node Connecting to an arduino @chapter Connecting to an arduino @cindex Connecting to an arduino To control an arduino device, a connection must be made to it by creating an arduino object. @section Connecting to a single arduino @cindex Connecting to a single arduino Assuming a single arduino device is connected to the computer, creating an arduino object with no arguments will find the connected arduino and connect to it: @example ar = arduino() @end example @section Connecting to a specific arduino @cindex Connecting to a specific arduino Where multiple arduinos may be connected to the computer, a specific board can be connected by specifying the name of the port it is connected to: @example ar = arduino("/dev/ttyACM0") @end example The port name will be operating system dependent. @section Querying available arduinos @cindex Querying available arduinos To list the ports of all @emph{programmed} available arduinos, the scanForArduinos function can be used: @example scanForArduinos @end example It will provide a list of all available boards it can find with the port they are connected to. @boxnote{The scanForArduinos function will only detect boards that have been programmed using the arduinosetup command} @c ------------------------------------------------------------------------- @node Basic Input and Output Overview @chapter Basic Input and Output Overview @cindex Basic Input and Output Overview Basic input and output can be performed on a connected arduino device using by calling the read and write functions for a specific named pin on the arduino. A list of available pins can get found from the pins property of the connected arduino object and are also displayed as part of the default shown properties: @example ar = arduino(); % get the pin names pins = ar.availablepins @end example Pin generally follow a naming scheme of D for digital pins and A for analog pins. Digital pins can be used to read and write digital data, but can not read analog voltages. Analog pins can perform digital I/O as well as reading voltages. @section Performing Digital I/O @cindex Performing Digital I/O A pin's digital logic value can be true (1) or false (0) and can be set using the writeDigitalPin function. The following example attempts to set the D2 pin of the connected arduino object "ar" to true, waits 5 seconds and then sets it to false: @example writeDigitalPin (ar, "d2", true); pause 5 writeDigitalPin (ar, "d2", false); @end example Using the readDigitalPin will read the current logic state of the pin. @example value = readDigitalPin (ar, "d2"); @end example @section Performing Analog Input @cindex Performing Analog Input For analog pins, the voltage level can be read using a analog to digital conversion and will return a voltage level between 0 and the boards voltage (nominally 5V): @example value = readVoltage (ar, "a0"); @end example The raw digital value of the pin can also be read instead of a voltage, giving a value between 0 and 2^x where x is the number of bits used by the analog to digital converter. @example value = readAnalogPin (ar, "a0"); @end example @c ------------------------------------------------------------------------- @node Protocol based I/O Overview @chapter Protocol based I/O Overview @cindex Protocol based I/O Overview The arduino toolkit supports more complex I/O for SPI, I2C, Servo control and more. @section SPI communication @cindex SPI communication SPI communication can be performed by creating a SPI device object and then calling the writeRead function: @example spi = device (ar, "spichipselectpin", "d2"); @end example The function call expects a connected arduino object as the first argument, followed by the chip select pin of the SPI device. After a device is created, a write to device followed by read can can be made using the writeRead function: @example spi = device (ar, "spichipselectpin", "d2"); data = writeRead (spi, 100); @end example @section I2C communication @cindex I2C communication I2C communication can be performed by creating an I2C device object for a specific I2C address. The following example creates an I2C device that will communicate with a I2C device at address 100" @example i2c = device (ar, "i2caddress", 100); @end example After creating an I2C device, data can be read and written using read, write, readRegister and writeRegister. The data to send and receive will be device dependent. @section Servo communication @cindex Servo communication Servo communication can be performed after creating a servo device object to operate on a PWM pin: @example servoobj = servo(ar, "d9", "minpulseduration", 1.0e-3, ... "maxpulseduration", 2e-3); @end example The servo function expects the connected arduino object and the PWM pin that the servo is connected to. Optional properties can be specified to control the setup of device. In the example, the min and max pulse width values are set. Using the servo object the current position and be read or set with values ranging between 0 to 1, with 0 being the minimum pulse width and 1 being the maximum. The following example sets the servo to its middle position. @example servoobj = servo(ar, "d9", "minpulseduration", 1.0e-3, ... "maxpulseduration", 2e-3); writePosition (servoobj, 0.5); @end example @section Shift Registers @cindex Shift Registers A shift register can be controlled by creating a shiftRegister object: @example registerobj = shiftRegister(ar, '74hc164', "d2", "d3"); @end example The parameters required are dependent on the type of shift register created. Once a register object has been created, it can be read and written to using the read and write functions. @section Rotary Encoders @cindex Rotary Encoder A rotary encoder can be created by creating a rotaryEncoder object. @example encoder = rotaryEncoder(ar, "d2", "d3", 180); @end example Using the created object, the rotary encoder value and speed can be read. @section Ultrasonic Sensors @cindex Ultrasonic Sensors An ultrasonic sensor can be read by creating an ultrasonic object. @example sensor = ultrasonic(ar, "d9", "d10"); @end example Using the created object, the sensor distance and echo time and be read. @section Serial communication @cindex Serial communication Serial communication can be performed on devices that support multiple serial devices such as the leonardo and mega2560 boards. The communications port to Octave is reserved and can not be used as a user controlled communications port. Serial communication can be performed by creating a serial device object and then calling the read and write functions: @example ser = device (ar, "serial", 1); @end example The function call expects a connected arduino object as the first argument, followed "serial" and serial id. After a device is created, the device can be read and written: @example ser = device (ar, "serial", 1); write(ser, "hello"); data = read(ser, 100); @end example @c ------------------------------------------------------------------------- @node Addons Overview @chapter Addons Overview @cindex Addons Overview This chapter provides an overview of the arduino package addon functionality for adding additional addons to arduino. @section Addon Introduction @cindex Addon Introduction Addons provide a way of adding additional functionality to the arduino toolkit that provides Matlab access directly to the arduino hardware. Addons are implemented in two parts. @enumerate @item code running on the arduino that implements the required functionality @item a octave wrapper class that provides the Matlab interface and communication to the code. @end enumerate Both parts are required to create a plugin. The arduino toolkit provides a number of pre-created addons. These can be seen using the following command: @example @code { listArduinoLibraries } @end example The command will display all known arduino libraries (addons as well as core libraries), however addons typically use a "foldername/classname" for this naming. @xseealso{listArduinoLibraries} @section Creating an addon @cindex Creating an addon An addon requires at minimum 3 things: @enumerate @item A addon package directory that will contain the addon files @item A Matlab file within that directory that is a subclass of arduinoio.LibraryBase @item A arduino source/header file that contains the arduino code to load, sub-classed for LibraryBase @end enumerate So the addon directory structure at a minimum will be: @example @code { +arduinoioaddons (dir) [somewhere in the octave load path] +MyAddons (dir) MyAddon1.m MyAddon1.h } @end example @subsection Addon package directory @cindex Addon package directory The addon architecture looks for plugins in the octave load path in a package directory called +arduinoioaddons So this directory must be created somewhere within the paths that octave will check for functions. In addition, the addon architecture expects plugins to be contained in a sub directory within the +arduinoioaddons folder. The subdirectory must begin with a '+'. Multiple plugin .m files can be within the same sub directory. @subsection Addon package .m file @cindex Addon package .m file The Matlab interface file within the addon directory provides the Matlab interface for the arduino code as well as provides information about the addon. @subsubheading Class inheritance and required properties The interface file must be a subclass of arduinoio.LibraryBase and must contain some constant properties values that provide the information. A minimum example of required is below: @example @code { classdef MyAddon1 < arduinoio.LibraryBase properties(Access = protected, Constant = true) LibraryName = 'MyAddons/MyAddon1'; CppHeaderFile = fullfile(arduinoio.FilePath(mfilename('fullpath')), 'MyAddon1.h'); CppClassName = 'MyAddon1'; endproperties . . . endclassdef } @end example The following constant properties can be set within the addon: @table @asis @item LibraryName (Required) The name of the addon. My convention this is usually the directoryname / theclassname @item CppHeaderFile (Required) The header file for the arduino code @item CppSourceFile (Optional) The source file (if any) for the arduino code @item CppClassName (Required) The classname used within the cppheaderfile for the arduino library @item DependantLibraries (Optional) Any additional addons or cores that are needed for this library to be used @item ArduinoLibraryHeaderFiles (Optional) Any additional header files that need to be included @end table @subsubheading Class constructor The Matlab class constructor will be called from the addon function when creating a instance of the addon and should initialize at least two properties in inherited from arduinoio.LibraryBase: @enumerate @item Parent should be set to the first input argument (the arduino class) @item Pins should be set to a list of pins that are used for the plugin @end enumerate @example @code { classdef MyAddon1 < arduinoio.LibraryBase . . methods function obj = MyAddon1(parentObj, varargin) obj.Parent = parentObj; # no pins being used obj.Pins = []; # send any command to the arduino during setup ? endfunction . . endmethods endclassdef } @end example @subsubheading Class functions The class functions will usually communicate to the arduino and use the response for what is returned to the user. By convention, the commands sent to the arduino are defined as constants in the class file but do not have to be. @example @code { classdef MyAddon1 < arduinoio.LibraryBase properties(Access = private, Constant = true) INIT_COMMAND = hex2dec('00'); FUNC1_COMMAND = hex2dec('01'); endproperties . . methods function obj = MyAddon1(parentObj, varargin) obj.Parent = parentObj; # no pins being used obj.Pins = []; # send any command to the arduino during setup ? sendCommand(obj.Parent, obj.LibraryName, obj.INIT_COMMAND, []); endfunction function retval = func1(obj) cmdID = obj.FUNC1_COMMAND; retval = sendCommand(obj.Parent, obj.LibraryName, cmdID, []); endfunction . . endmethods endclassdef } @end example @boxnote{the sendCommand uses the objects parent for the arduino, the objects library name and the command id} @xseealso{sendCommand} @subsection Addon package header file @cindex Addon package header file The header file should contain a class that matches the functionally and information of the matlab file and provides the ability to register the code on the arduino. The following things should occur in the arduino class files: @enumerate @item The class name within the file must be the same as the one set in the .m file CppClassName property. @item The libName variable must be the same as the LibraryName property. @item The constructor should call registerLibrary @item the commandHandler function to act on cmdID values that match the commands that will be sent from .m file and send data back using sendResponseMsg @item on receiving unknown cmdID values, the commandHandler should use sendUnknownCmdIDMsg @end enumerate An example, matching the previous .m file code is below: @example @code { #include "LibraryBase.h" #define MYADDON1_INIT 0x00 #define MYADDON1_FUNC1 0x01 class MyAddon1 : public LibraryBase @{ uint8_t cnt; public: MyAddon1(OctaveArduinoClass& a) @{ libName = "MyAddons/MyAddon1"; a.registerLibrary(this); @} void commandHandler(uint8_t cmdID, uint8_t* data, uint8_t datasz) @{ switch (cmdID) @{ case MYADDON1_INIT: @{ cnt = 0; sendResponseMsg(cmdID, 0,0); break; @} case MYADDON1_FUNC1: @{ // func 1 is just returning a uint8 count of number of times called cnt ++; sendResponseMsg(cmdID, &cnt, 1); break; @} default: @{ // notify of invalid cmd sendUnknownCmdIDMsg(); @} @} @} @} }; @end example The body of functions can be in the CppSourceFile file is it is defined or within the header file as illustrated above. @subsection Verify octave can see the addon @cindex Verify octave can see the addon Use the listArduinoLibaries command to verify that the new addon appears in the list of known libraries. If it does not, ensure that the +arduinoioaddons directory is within one of the octave class paths, and that the directory structure and inheritance requirements have been met. @section Using addons @cindex Using Addons @subsection Programming the arduino with the addon @cindex Programming the arduino with the addon To use a addon, the code must be programmed onto the arduino. Using the libraries command, when creating a arduino object, the arduino can be reprogrammed if the library does not already exist on the arduino. @example @code { ar = arduino([],[], 'libraries', 'MyAddons/MyAddon1', 'forcebuild', true) } @end example The libraries property of the arduino object should list the libraries programmed on the arduino. Alternatively, the library can be added using the libraries property and arduinosetup @xseealso{arduino, arduinosetup} @subsection Creating a addon object @cindex Creating a addon object An object of the addon type can be created using the addon command. @example @code { ar = arduino([],[], 'libraries', 'MyAddons/MyAddon1', 'forcebuild', true) obj = addon(ar, "MyAddons/MyAddon1"); } @end example @c ------------------------------------------------------------------------- @node Sensors Overview @chapter Sensors Overview @cindex Sensors Overview There are two types of sensors available: @enumerate @item Matlab compatible(ish) sensors for environment and IMU. @item Additional lightweight wrappers for some chips in a arduinosensor namespace. @end enumerate @section Matlab Compatible Sensors @cindex Matlab Compatible Sensor @subsection Overview Matlab compatible functions are provided for a number of sensors, using a similar function naming as provided by the Matlab arduino package. @subsection Available Sensors @cindex Available Sensors The functions for each sensor is listed in the function reference, @ref{Sensors} and provides for: @table @asis @item bme280 BME280 temperature, pressure and humidity sensor @item bno005 BNO055 acceleration, angular velocity, orientation and magnetic field sensor @item lis3dh LIS3DH acceleration sensor @item lps22hb LPS22HB temperature and pressure sensor @item lsm6dso LSM6DSO acceleration, angular velocity sensor @item mpu6050 MPU-6050 acceleration, angular velocity sensor @item SI7021 SI7021 temperature and humidity sensor @end table @section Lightweight Arduino Sensors @cindex Arduino Sensor @subsection Overview Arduino sensors are a collection of lightweight wrappers around other underlying protocols for providing specific sensor functionality. For instance a DS1307 chip communicates using I2C protocol and so a DS1307 class exists that provides the conversion/commands in order to communicate to the chip. Using the class, providing the functionality is very easy: @example @code { a = arduino() rtc = arduinosensor.DS1307(a) # get and display rtc time as a date string datestr(rtc.clock) } @end example It is lightweight compared to the addon functionality, as it only requires a wrapper class rather than add on code, however it is limited to then using available addon and core codes rather than creating new ones. Currently the are only a small number of sensors available, however this will be built upon in future versions. @subsection Available Sensors @cindex Available Sensors The functions for each sensor is listed in the function reference, @ref{Arduino Sensors} and provides for: @table @asis @item DS1307 DS1307 RTC clock using i2c. @item MPC3002 MPC3002 ADC using SPI @item SI7021 SI7021 temperature and humidity sensor @item GUVAS12SD GUVAS12SD analog UV-B sensor @end table @c ------------------------------------------------------------------------- @node Examples @chapter Examples @cindex Examples @section Blinking an LED @cindex Blinking an LED This example shows blinking the inbuilt LED on the Arduino board. Code is available by running: @example edit examples/example_blink @end example @heading Hardware setup This example uses in the builtin LED, so requires only a connection of the Arduino board to computer for communication. @heading Create an Arduino object @example ar = arduino (); @end example If you have more than one Arduino board connected, you may need to specify the port in order to connect to the correct device. @heading Query Device for pins connected to builtin LED The pin connected to the Arduino UNO built in led if D13. @example led_pin = "d13"; @end example The connected pins can be queried programatically if desired. @example pins = getLEDTerminals (ar); @end example Connected to a Arduino UNO would return a list pins containing only one item '13'. The terminal number can be converted to a pin using getPinsFromTerminals: @example led_pin = getPinsFromTerminals (ar, pins@{1@}); @end example @heading Turn the LED off Write a 0 value to the pin to turn it off. @example writeDigitalPin (ar, led_pin, 0); @end example @heading Turn the LED on Write a 1 value to the pin to turn it on @example writeDigitalPin (ar, led_pin, 1); @end example @heading Making the LED blink Add a while loop with a pause between the changes in the pin state to blink. @example while true writeDigitalPin (ar, led_pin, 0); pause (0.5) writeDigitalPin (ar, led_pin, 1); pause (0.5) endwhile @end example @section Using I2C to communicate with an EEPROM @cindex Using I2C to communicate with an EEPROM This example shows using I2C to communicate with a EEPROM chip. Code is available by running: @example edit examples/example_i2c_eeprom @end example @heading Hardware setup Using an Arduino UNO, the board should be configured with the following connections between the board and a 24XX256 EEPROM chip: @table @asis @item A4 Connected to pin 5 of EEPROM @item A5 Connected to pin 6 of EEPROM @item 5V Connected to pin 8 of EEPROM @item GND Connected to pin 1,2,3,4 of EEPROM @end table @heading Create an Arduino object @example ar = arduino (); @end example If you have more than one Arduino board connected, you may need to specify the port in order to connect to the correct device. @heading Query I2C pins Display the I2C terminals of the board: @example getI2CTerminals(ar) @end example @heading Scan the arduino for the connected device @example scanI2Cbus(ar) @end example The devices listed should contain 0x50, the address of the EEPROM chip. @heading Create an I2C object to communicate to the EEPROM @example eeprom = device (ar, "i2caddress", 0x50) @end example @heading Write data to the EEPROM The EEPROM expects the first byte to be the page number, the second the offset, followed by data, so to write 1 2 3 4, starting address 0 (page 0, offset 0): @example write(eeprom, [0 0 1 2 3 4]) @end example @heading Reading from the EEPROM Reading from the EEPROM requires first writing the address to read from, in this case, if we want to read the 3, 4, this would be page 0, offset 2: @example write(eeprom, [0 2]) @end example Next read the 2 bytes: @example data = read(eeprom, 2) @end example @c ------------------------------------------------------------------------- @section Using SPI to communicate with a mcp3002 10 bit ADC @cindex Using SPI to communicate with a mcp3002 10 bit ADC This example shows using SPI to communicate with an mcp3002 10 bit ADC. Code is available by running: @example edit examples/example_spi_mcp3002 @end example @heading Hardware setup Using an Arduino UNO, the board should be configured with the following connections between the board and a mcp3002 chip: @table @asis @item D10 Connected to pin 1 (CS) of MCP3002 @item D11 Connected to pin 5 (DI) of MCP3002 @item D12 Connected to pin 6 (DO) of MCP3002 @item D13 Connected to pin 7 (CLK) MCP3002 @item VCC Connected to pin 8 (VDD) MCP3002 @item GND Connected to pin 4 (VSS) MCP3002 @item Analog input Connected from pin 2 of the MCP3002 to a LOW (< 5V) voltage to measure @end table @heading Create an Arduino object @example ar = arduino (); @end example If you have more than one Arduino board connected, you may need to specify the port in order to connect to the correct device. @heading Create an SPI object to communicate to the MCP3002 @example adc = device(ar, "spichipselectpin", "d10") @end example The d10 is the chip select pin connected from the Arduino to the MCP3002. @heading Read the ADC The MCP3002 expects specific commands in order to read a channel. For illustration for the command to read chan 0 in single ended mode: @example command (bits) in MSB mode to device: [START SGL ODN MSBF X X X X] [ X X X X X X X X ] 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 [chan 0 ] MSB data back: X X X X X 0 D D D D D D D D D D @end example D is a output data bit X is a don't care what value is input/output The first byte contains the command and start of the data read back, the second bytes is written to clock out the rest of the ADC data. In hex, this corresponds to 0xDF 0xFF, @example data = writeRead(adc, [hex2dec("DF") hex2dec("FF")]) @end example Of the data returned, the last 10 bits is the actual data, so convert data to a 16 bit value: @example val = uint16(data(1))*256 + uint16(data(2)) @end example Then bitand it to remove the non value parts, to get the ADC value: @example val = bitand (val, hex2dec('3FF')) @end example To make the value correspond to a voltage it needs to be scaled as 0 will be 0 Volts, 1023 will be 5 Volts. @example volts = double(val) * 5.0 / 1023.0; @end example @c ------------------------------------------------------------------------- @node Function Reference @chapter Function Reference @cindex Function Reference The functions currently available in the Arduino toolkit are described below; @include functions.texi @c ------------------------------------------------------------------------- @include gpl.texi @c ------------------------------------------------------------------------- @node Index @unnumbered Index @printindex cp @bye arduino-0.12.2/doc/functions.texi0000644000000000000000000037703514777724260013672 0ustar00@c --------------------------------------------------- @node General Functions @section General Functions @cindex General Functions @c General Functions arduinosetup @c ----------------------------------------- @subsection arduinosetup @cindex arduinosetup @deftypefn {} {@var{retval} =} arduinosetup () @deftypefnx {} {@var{retval} =} arduinosetup (@var{propertyname}, @var{propertyvalue}) Open the arduino config / programming tool to program the arduino hardware for usage with the Octave arduino functions. arduinosetup will create a temporary project using the arduino IDE and allow compiling and programming of the code to an arduino. @subsubheading Inputs @var{propertyname}, @var{propertyvalue} - A sequence of property name/value pairs can be given to set defaults while programming. Currently the following properties can be set: @table @asis @item libraries The value should be the name of a library, or string array of libraries to program on the arduino board. @item arduinobinary The value should be the name/path of the arduino IDE binary for programming. If not specified, the function will use getpref preferences of arduino.arduino_binary, and if not found, the function will attempt to find the binary itself. If provided, the value will be saved to preferences for future calls. @end table @subsubheading Outputs @var{retval} - return 1 if arduino IDE returned without an error @xseealso{arduino, __arduino_binary__} @end deftypefn @c General Functions isarduino @c ----------------------------------------- @subsection isarduino @cindex isarduino @deftypefn {} {@var{retval} =} isarduino (@var{obj}) Check if input value is an arduino object Function is essentially just a call of @code { retval = isa(obj, "arduino"); } @subsubheading Inputs @var{obj} - The object to check @subsubheading Outputs @var{retval} is true, if obj is an arduino object, false otherwise. @xseealso{arduino} @end deftypefn @c General Functions listArduinoLibraries @c ----------------------------------------- @subsection listArduinoLibraries @cindex listArduinoLibraries @deftypefn {} {@var{retval} =} listArduinoLibraries () @deftypefnx {} {@var{retval} =} listArduinoLibraries (@var{libtypes}) Retrieve list of all known arduino library modules that are available. @subsubheading Inputs @var{libtypes} - optional specifier for type of libraries to list. Options are: @table @asis @item all List core and addons @item core List core only libraries @item addons List addons only @end table When no libtypes is specified, all libraries are shown. @subsubheading Outputs @var{retval} is an cell array of string library names that are available for programming to the arduino. @xseealso{arduino, arduinosetup} @end deftypefn @c General Functions scanForArduinos @c ----------------------------------------- @subsection scanForArduinos @cindex scanForArduinos @deftypefn {} {@var{retval} =} scanForArduinos () @deftypefnx {} {@var{retval} =} scanForArduinos (@var{maxCount}) @deftypefnx {} {@var{retval} =} scanForArduinos (@var{"debug"}) @deftypefnx {} {@var{retval} =} scanForArduinos (@var{maxCount}, @var{type}) @deftypefnx {} {@var{retval} =} scanForArduinos (@var{propertyname}, @var{propertvalue} ...) Scan system for programmed serial connected arduino boards. scanForArduinos will scan the system for programmed arduino boards and return at most @var{maxCount} of them as a cell array in @var{retval}. @subsubheading Inputs @var{maxCount} - max number of arduino boards to detect. if @var{maxCount} is not specified, or is a less than 1, the function will return as many arduino boards as it can detect. @var{type} - optional board type to match. If specified, the board type must match for the arduino to be added to the return list. @var{"debug"} - if single input parameter is "debug", the scanForArduinos will display debug information as it scans all available ports for arduinos. @var{propertyname}, @var{propertyvalue} - property name/value pairs to match search with. @table @asis @item 'BaudRate' Numeric BaudRate to use when trying to scan for arduinos. @item 'MaxCount' Max number of arduinos to scan for. @item 'BoardType' Boardtype to match. @item 'Debug' Logical flag for debug mode. @end table @subsubheading Outputs @var{retval} structure cell array of matching detected arduino boards. Each cell value of the cell array will contain a structure with values of: @table @asis @item port the serial port the arduino is connected to @item board the board type of the arduino @end table @xseealso{arduino} @end deftypefn @c --------------------------------------------------- @node Arduino Functions @section Arduino Functions @cindex Arduino Functions @c Arduino Functions @arduino/arduino @c ----------------------------------------- @subsection @@arduino/arduino @cindex arduino @deftypefn {} {@var{retval} =} arduino () @deftypefnx {} {@var{retval} =} arduino (@var{port}) @deftypefnx {} {@var{retval} =} arduino (@var{port}, @var{board}) @deftypefnx {} {@var{retval} =} arduino (@var{port}, @var{board}[, [@var{propname}, @var{propvalue}]*) @deftypefnx {} {@var{retval} =} arduino (@var{iaddress}) @deftypefnx {} {@var{retval} =} arduino (@var{ipaddress}, @var{board}) Create a arduino object with a connection to an arduino board. @subsubheading Inputs @var{port} - full path of serial port to connect to. For Linux, usually /dev/ttySXXX, for windows COMXX. @var{board} - name of board to connect (default is 'uno'). @var{propname}, @var{propvalue} - property name and value pair for additional properties to pass to the creation of the arduino object. Currently properties are ignored, with the exception of: @table @asis @item debug true / false flag for whether setting debug (default false) @item forcebuildon true / false flag for whether to force show of the arduino IDE to rebuild the installed code on the arduino (default false) @item baudrate (read only) the communications baudrate to the board. (default 9600) @item libraries The libraries to be enabled on the arduino board. (default uses whatever is already installed) @end table if the arduino function is called without parameters, it will scan for the first available arduino it can find and connect to it. @subsubheading Outputs @var{retval} - a successfully connected arduino object. @subsubheading Properties The arduino object has the following public properties: @table @asis @item name name assigned to the arduino object @item debug true / false flag for whether debug is turned on @item forcebuildon true / false flag for whether to force show of the arduino IDE to reprogram the arduino @item port (read only) the communications port the board is connected to. @item baudrate (read only) the communications baudrate to the board. @item board (read only) The name of the board type that the arduino connected to @item libraries (read only) The libraries currently programmed onto the board @item availablepins The pins available for use on the board @item analogreference The analog voltage reference @end table @xseealso{scanForArduinos, arduinosetup} @end deftypefn @c Arduino Functions @arduino/checkI2CAddress @c ----------------------------------------- @subsection @@arduino/checkI2CAddress @cindex checkI2CAddress @deftypefn {} {@var{retval} =} checkI2CAddress (@var{ar}, @var{address}) @deftypefnx {} {@var{retval} =} checkI2CAddress (@var{ar}, @var{address}, @var{bus}) Check that an address of given address responds on the I2C bus @subsubheading Inputs @var{ar} - arduino object connected to a arduino board. @var{address} - I2C address number to check @var{bus} - bus number to check for I2C device, when multiple buses are available. If the bus is not specified, it will default to 0. @subsubheading Outputs @var{retval} - boolean value of true if address responds on the I2C bus @subsubheading Example @example @code { # create arduino connection. ar = arduino(); # scan for devices on the I2C bus checkI2CAddress (ar) # output if a device using that address is attached ans = 1 } @end example @xseealso{arduino, scanI2Cbus} @end deftypefn @c Arduino Functions @arduino/configurePin @c ----------------------------------------- @subsection @@arduino/configurePin @cindex configurePin @deftypefn {} {@var{currmode} =} configurePin (@var{ar}, @var{pin}) @deftypefnx {} {} configurePin (@var{ar}, @var{pin}, @var{mode}) Set/Get pin mode for a specified pin on arduino connection. configurePin (@var{ar}, @var{pin}) will get the current mode of the specified pin. configurePin (@var{ar}, @var{pin}, @var{mode}) will attempt set the pin to the specified mode if the mode is unset. @subsubheading Inputs @var{ar} - the arduino object of the connection to an arduino board. @var{pin} - string name of the pin to set/get the mode of. @var{mode} - string mode to set the pin to. @subsubheading Outputs @var{mode} - string current mode of the pin. Valid modes can be: @itemize @bullet @item AnalogInput - Acquire analog signals from pin @item DigitalInput - Acquire digital signals from pin @item DigitalOutput - Generate digital signals from pin @item I2C - Specify a pin to use with I2C protocol @item Pullup - Specify pin to use a pullup switch @item PWM - Specify pin to use a pulse width modulator @item Servo - Specify pin to use a servo @item SPI - Specify a pin to use with SPI protocol @item Interrupt - Specify a pin to use for with interrupts @item Reserved - Specify a pin to be reserved @item Unset - Clears pin designation. The pin is no longer reserved and can be automatically set at the next operation. @end itemize @xseealso{arduino} @end deftypefn @c Arduino Functions @arduino/configurePinResource @c ----------------------------------------- @subsection @@arduino/configurePinResource @cindex configurePinResource @deftypefn {} {@var{currmode} =} configurePinResource (@var{ar}, @var{pin}) @deftypefnx {} {} configurePinResource (@var{ar}, @var{pin}, @var{owner}, @var{mode}) @deftypefnx {} {} configurePinResource (@var{ar}, @var{pin}, @var{owner}, @var{mode}, @var{force}) Set/Get pin mode for a specified pin on arduino connection. configurePinResource (@var{ar}, @var{pin}) will get the current mode of the specified pin. configurePinResource (@var{ar}, @var{pin}, @var{owner}, @var{mode}) will attempt set the pin to the specified mode and owner. If the pin is already owned by another owner, the configure will fail unless the force option is used. If the mode is already set, configure will fail unless force is used. @subsubheading Inputs @var{ar} - the arduino object of the connection to an arduino board. @var{pin} - string name of the pin to set/get the mode of. @var{mode} - string mode to set the pin to. @var{owner} - string name to use as the pin owner. @var{force} - boolean to force mode change. If not set, it will be false. @subsubheading Outputs @var{currmode} - current string mode of the pin. Valid modes can be: @itemize @bullet @item AnalogInput - Acquire analog signals from pin @item DigitalInput - Acquire digital signals from pin @item DigitalOutput - Generate digital signals from pin @item I2C - Specify a pin to use with I2C protocol @item Pullup - Specify pin to use a pullup switch @item PWM - Specify pin to use a pulse width modulator @item Servo - Specify pin to use a servo @item SPI - Specify a pin to use with SPI protocol @item Interrupt - Specify a pin to use with interrupts @item Reserved - Pin marked reserved, but not for of any particular mode @item Unset - Clears pin designation. The pin is no longer reserved and can be automatically set at the next operation. @end itemize @xseealso{arduino, configurePin} @end deftypefn @c Arduino Functions @arduino/decrementResourceCount @c ----------------------------------------- @subsection @@arduino/decrementResourceCount @cindex decrementResourceCount @deftypefn {} {@var{count} =} decrementResourceCount (@var{ar}, @var{resource}) Decrement the count of a named resource by 1 and return the new count. @subsubheading Inputs @var{ar} - connected arduino object @var{resource} - name of resource to decrement count. @subsubheading Outputs @var{count} = count of uses registered to resource. @xseealso{getResourceCount. incrementResourceCount} @end deftypefn @c Arduino Functions @arduino/delete @c ----------------------------------------- @subsection @@arduino/delete @cindex delete @deftypefn {} {} delete (@var{dev}) Free resources of an arduino object. @subsubheading Inputs @var{dev} - object to free @xseealso{arduino} @end deftypefn @c Arduino Functions @arduino/disp @c ----------------------------------------- @subsection @@arduino/disp @cindex disp @deftypefn {} {} disp (@var{ar}) Display the arduino object in a verbose way, showing the board and available pins. @subsubheading Inputs @var{ar} - the arduino object. If the arduino object has debug mode set, additional information will be displayed. @xseealso{arduino} @end deftypefn @c Arduino Functions @arduino/getEndian @c ----------------------------------------- @subsection @@arduino/getEndian @cindex getEndian @deftypefn {} {@var{mcu} =} getEndian (@var{ar}) Get the endian used by the connected arduino. @subsubheading Inputs @var{ar} - arduino object connected to a arduino board. @subsubheading Outputs @var{endian} - string representing the endian used by the arduino board. 'L' means little endian, 'B' means big endian @xseealso{arduino, getMCU} @end deftypefn @c Arduino Functions @arduino/getI2CTerminals @c ----------------------------------------- @subsection @@arduino/getI2CTerminals @cindex getI2CTerminals @deftypefn {} {@var{pinlist} =} getI2CTerminals (@var{ar}) @deftypefnx {} {@var{pinlist} =} getI2CTerminals (@var{ar}, @var{bus}) Get a cell list of pin Ids available are used for I2C mode. @subsubheading Inputs @var{ar} - the arduino object. @var{bus} - optional bus number 0 or 1 for boards that support more than 1 bus. @subsubheading Outputs @var{pinlist} - cell list of pin numbers available for I2C use. @xseealso{arduino} @end deftypefn @c Arduino Functions @arduino/getInterruptTerminals @c ----------------------------------------- @subsection @@arduino/getInterruptTerminals @cindex getInterruptTerminals @deftypefn {} {@var{pinlist} =} getInterruptTerminals (@var{ar}) Get a cell list of pin Ids available have interrupt functionality @subsubheading Inputs @var{ar} - the arduino object. @subsubheading Outputs @var{pinlist} - cell list of pin numbers available for interrupt use. @xseealso{arduino} @end deftypefn @c Arduino Functions @arduino/getLEDTerminals @c ----------------------------------------- @subsection @@arduino/getLEDTerminals @cindex getLEDTerminals @deftypefn {} {@var{pinlist} =} getLEDTerminals (@var{ar}) Get a cell list of pin Ids available are connected natively to LEDs. @subsubheading Inputs @var{ar} - the arduino object. @subsubheading Outputs @var{pinlist} - cell list of pin numbers available for LED use. @xseealso{arduino} @end deftypefn @c Arduino Functions @arduino/getMCU @c ----------------------------------------- @subsection @@arduino/getMCU @cindex getMCU @deftypefn {} {@var{mcu} =} getMCU (@var{ar}) Get the MCU used by the connected arduino. @subsubheading Inputs @var{ar} - arduino object connected to a arduino board. @subsubheading Outputs @var{mcu} - string representing the mcu used by the arduino board. @xseealso{arduino} @end deftypefn @c Arduino Functions @arduino/getPWMTerminals @c ----------------------------------------- @subsection @@arduino/getPWMTerminals @cindex getPWMTerminals @deftypefn {} {@var{pinlist} =} getPWMTerminals (@var{ar}) Get a cell list of pin Ids available for PWM use. @subsubheading Inputs @var{ar} - the arduino object. @subsubheading Outputs @var{pinlist} - cell list of pin numbers available for PWM use. @xseealso{arduino} @end deftypefn @c Arduino Functions @arduino/getPinAlias @c ----------------------------------------- @subsection @@arduino/getPinAlias @cindex getPinAlias @deftypefn {} {@var{ouy} =} getPinAlias (@var{ar}, @var{pin}) Get the pin actual pin name from a pin alias. For example, the arduino Leonardo, pin "D4" is also "A6". @subsubheading Inputs @var{ar} - the connected arduino object. @var{pin} - a pin name. @subsubheading Outputs @var{out} - alias pin name, or same as @var{pin} if the pin doesnt have any alias names. @xseealso{arduino, configurePinResource, getResourceOwner} @end deftypefn @c Arduino Functions @arduino/getPinInfo @c ----------------------------------------- @subsection @@arduino/getPinInfo @cindex getPinInfo @deftypefn {} {@var{pininfo} =} getPinInfo (@var{ar}, @var{pin}) @deftypefnx {} {@var{pininfoarray} =} getPinInfo (@var{ar}, @var{pinarray}) Get the pin information from the input pins values. getPinInfo (@var{ar}, @var{pin}) will get information for a single pin. getPinInfo (@var{ar}, @var{pinarray}) will get a cell array of pin information @subsubheading Inputs @var{ar} - the connected arduino object. @var{pin} - a pin number or pin name. @var{pinarray} - the array of pin numbers or names The pininfo struct contains the following fields: @table @asis @item terminal Terminal number of the pin @item name String name of the pin @item owner Current item owner of the pin @item mode Current configured mode for the pin @end table @subsubheading Outputs @var{pininfo} - struct on pin information. @var{pininfolist} - cell array of pin info @xseealso{arduino, configurePinResource, getResourceOwner} @end deftypefn @c Arduino Functions @arduino/getPinsFromTerminals @c ----------------------------------------- @subsection @@arduino/getPinsFromTerminals @cindex getPinsFromTerminals @deftypefn {} {@var{pinnames} =} getPinsFromTerminals (@var{ar}, @var{terminals}) Get the pin names from the input terminal values. @subsubheading Inputs @var{ar} - the connected arduino object. @var{terminals} - the numeric pin number, or array of pin numbers to get pin names. @subsubheading Outputs @var{pinnames} - the string names of each input pin. If terminals was a single value, the return will be a single string, otherwise it will return a cell array of each pin name. @xseealso{arduino, getTerminalsFromPins} @end deftypefn @c Arduino Functions @arduino/getResourceCount @c ----------------------------------------- @subsection @@arduino/getResourceCount @cindex getResourceCount @deftypefn {} {@var{count} =} getResourceCount (@var{ar}, @var{resource}) Get the count of uses of a given resource. @subsubheading Inputs @var{ar} - connected arduino object @var{resource} - name of resource to get count for. @subsubheading Outputs @var{count} = count of uses registered to resource. @xseealso{incrementResourceCount. decrementResourceCount} @end deftypefn @c Arduino Functions @arduino/getResourceOwner @c ----------------------------------------- @subsection @@arduino/getResourceOwner @cindex getResourceOwner @deftypefn {} {@var{owner} =} getResourceOwner (@var{ar}, @var{terminal}) Get the owner of pin allocated previously by configurePinResource. @subsubheading Inputs @var{ar} - connected arduino object @var{terminal} - terminal number to get owner of. @subsubheading Outputs @var{owner} = owner of the terminal pin, or "" if not owned. @xseealso{configurePinResource} @end deftypefn @c Arduino Functions @arduino/getSPITerminals @c ----------------------------------------- @subsection @@arduino/getSPITerminals @cindex getSPITerminals @deftypefn {} {@var{pinlist} =} getSPITerminals (@var{ar}) Get a cell list of pin Ids available for SPI mode. @subsubheading Inputs @var{ar} - the arduino object. @subsubheading Outputs @var{pinlist} - cell list of pin numbers available for SPI use. @xseealso{arduino} @end deftypefn @c Arduino Functions @arduino/getServoTerminals @c ----------------------------------------- @subsection @@arduino/getServoTerminals @cindex getServoTerminals @deftypefn {} {@var{pinlist} =} getServoTerminals (@var{ar}) Get a cell list of pin Ids available for servo use. @subsubheading Inputs @var{ar} - the arduino object. @subsubheading Outputs @var{pinlist} - cell list of pin numbers available for servo use. @xseealso{arduino, getPWMTerminals} @end deftypefn @c Arduino Functions @arduino/getSharedResourceProperty @c ----------------------------------------- @subsection @@arduino/getSharedResourceProperty @cindex getSharedResourceProperty @deftypefn {} {@var{count} =} getSharedResourceProperty (@var{ar}, @var{resource}, @var{property}) Get the value of a property from a given resource. @subsubheading Inputs @var{ar} - connected arduino object @var{resource} - name of resource to get property for. @var{property} - name of property from the resource. @subsubheading Outputs @var{propvalue} - value of the property @xseealso{getResourceCount, setSharedResourceProperty} @end deftypefn @c Arduino Functions @arduino/getTerminalMode @c ----------------------------------------- @subsection @@arduino/getTerminalMode @cindex getTerminalMode @deftypefn {} {@var{mode} =} getTerminalMode (@var{ar}, @var{terminal}) Get the mode of a pin allocated previously by configurePinResource. @subsubheading Inputs @var{ar} - connected arduino object @var{terminal} - terminal number to get owner of. @subsubheading Outputs @var{mode} - mode of the terminal pin, or "not_set" if not owned. @xseealso{configurePinResource, getResourceOwner} @end deftypefn @c Arduino Functions @arduino/getTerminalsFromPins @c ----------------------------------------- @subsection @@arduino/getTerminalsFromPins @cindex getTerminalsFromPins @deftypefn {} {@var{pinnums} =} getTerminalsFromPins (@var{ar}, @var{pins}) Get the terminal number for each pin. @subsubheading Inputs @var{ar} - connected arduino object @var{pins} - single pin name or cell or vector array of pin names. @subsubheading Outputs @var{pinnums} - pin number of each named pin. If the input was a single string, returns a number. if the input pins was a vector or cell array, return a cell array of pin numbers corresponding to each input pin name. @xseealso{arduino, getPinsFromTerminals} @end deftypefn @c Arduino Functions @arduino/incrementResourceCount @c ----------------------------------------- @subsection @@arduino/incrementResourceCount @cindex incrementResourceCount @deftypefn {} {@var{count} =} incrementResourceCount (@var{ar}, @var{resource}) Increment the count value of a named resource by 1 and return the new count @subsubheading Inputs @var{ar} - connected arduino object @var{resource} - name of resource to increment count. @subsubheading Outputs @var{count} = count of uses registered to resource. @xseealso{getResourceCount. decrementResourceCount} @end deftypefn @c Arduino Functions @arduino/isTerminalAnalog @c ----------------------------------------- @subsection @@arduino/isTerminalAnalog @cindex isTerminalAnalog @deftypefn {} {@var{ret} = } isTerminalAnalog (@var{obj}, @var{terminal}) Return true if pin is capable of analog input @subsubheading Inputs @var{ar} - the connected arduino object @var{terminal} is a terminal number to check @subsubheading Outputs @var{ret} return 1 if terminal is a analog pin, 0 otherwise @end deftypefn @c Arduino Functions @arduino/isTerminalDigital @c ----------------------------------------- @subsection @@arduino/isTerminalDigital @cindex isTerminalDigital @deftypefn {} {@var{ret} = } isTerminalDigital(@var{obj}, @var{terminal}) Return true if pin is capable of digital functions @subsubheading Inputs @var{ar} - the connected arduino object @var{terminal} is a terminal number to check @subsubheading Outputs @var{ret} return 1 if terminal is a digital pin, 0 otherwise @end deftypefn @c Arduino Functions @arduino/playTone @c ----------------------------------------- @subsection @@arduino/playTone @cindex playTone @deftypefn {} {} playTone (@var{ar}, @var{pin}, @var{freq}, @var{duration}) Play a tone of a given frequency on a specified pin. @subsubheading Inputs @var{ar} - connected arduino object @var{pin} - digital pin to play tone on @var{freq} - frequency in hertz to play between 0 and 32767Hz. @var{duration} duration in seconds to play tone between 0 and 30 seconds If duration is 0 or not specified, tone will continue to play until next tone is commanded. If frequency is 0, tone will stop playing @strong{NOTE:} use of playTone can interfere with PWM output. @end deftypefn @c Arduino Functions @arduino/readAnalogPin @c ----------------------------------------- @subsection @@arduino/readAnalogPin @cindex readAnalogPin @deftypefn {} {@var{value} =} readAnalogPin (@var{ar}, @var{pin}) Read analog voltage of @var{pin}. @subsubheading Inputs @var{ar} - connected arduino object. @var{pin} - string name of the pin to read. @subsubheading Outputs @var{value} - analog value of the pin @subsubheading Example @example @code{ ar = arduino (); readAnalogPin(ar, "A4"); ans = 87 } @end example @xseealso{arduino, readVoltage} @end deftypefn @c Arduino Functions @arduino/readDigitalPin @c ----------------------------------------- @subsection @@arduino/readDigitalPin @cindex readDigitalPin @deftypefn {} {@var{value} =} readDigitalPin (@var{obj}, @var{pin}) Read digital value from a digital I/O pin. @subsubheading Inputs @var{ar} - connected arduino object. @var{pin} - string name of the pin to read. @subsubheading Outputs @var{value} - the logical value (0, 1, true false) of the current pin state. @subsubheading Example @example @code{ a = arduino (); pinvalue = readDigitalPin (a, 'D5'); } @end example @xseealso{arduino, writeDigitalPin} @end deftypefn @c Arduino Functions @arduino/readVoltage @c ----------------------------------------- @subsection @@arduino/readVoltage @cindex readVoltage @deftypefn {} {@var{voltage} =} readVoltage (@var{ar}, @var{pin}) Read analog voltage of a pin. @subsubheading Inputs @var{ar} - connected arduino. @var{pin} - pin name or number to query for voltage @subsubheading Outputs @var{voltage} - scaled pin value as a voltage @subsubheading Example @example @code{ ar = arduino (); readVoltage(ar, "A4"); ans = 1.401 } @end example @xseealso{arduino, readAnalogPin} @end deftypefn @c Arduino Functions @arduino/reset @c ----------------------------------------- @subsection @@arduino/reset @cindex reset @deftypefn {} {} reset (@var{ar}) Send reset command to arduino hardware to force a hardware reset. @subsubheading Inputs @var{ar} - connected arduino object. @xseealso{arduino} @end deftypefn @c Arduino Functions @arduino/sendCommand @c ----------------------------------------- @subsection @@arduino/sendCommand @cindex sendCommand @deftypefn {} {@var{outdata, outsize} =} sendCommand (@var{ar}, @var{libname}, @var{commandid}) @deftypefnx {} {@var{outdata, outsize} =} sendCommand (@var{ar}, @var{libname}, @var{commandid}, @var{data}) @deftypefnx {} {@var{outdata, outsize} =} sendCommand (@var{ar}, @var{libname}, @var{commandid}, @var{data}, @var{timeout}) Send a command with option data to the connected arduino, waiting up to a specified number of seconds for a response. @subsubheading Inputs @var{ar} - connected arduino object. @var{libname} - library sending the command. The name should match a programmed library of the arduino, or an error will be displayed. @var{commandid} - integer value for the command being sent to the arduino. @var{data} - optional data sent with the command. @var{timeout} - optional timeout to wait for data @subsubheading Outputs @var{outdata} - data returned back from the arduino in response to command @var{outsize} - size of data received If the arduino fails to respond with a valid reply, sendCommand will error. @xseealso{arduino} @end deftypefn @c Arduino Functions @arduino/setSharedResourceProperty @c ----------------------------------------- @subsection @@arduino/setSharedResourceProperty @cindex setSharedResourceProperty @deftypefn {} {} setSharedResourceProperty (@var{ar}, @var{resource}, @var{propname}, @var{propvalue}) @deftypefnx {} {} setSharedResourceProperty (@var{ar}, @var{resource}, @var{propname}, @var{propvalue}, ___) Set property values for a given resource. @subsubheading Inputs @var{ar} - connected arduino object @var{resource} - name of resource to get property for. @var{propname} - name of property from the resource. @var{propvalue} - value of property from the resource. Multiple @var{propname}, @var{propvalue} pairs can be given. @subsubheading Outputs None @subsubheading Example @example @code{ ar = arduino(); setSharedResourceProperty(ar, "myresource", "myproperty", [1 2 3]) } @end example @xseealso{getSharedResourceProperty} @end deftypefn @c Arduino Functions @arduino/uptime @c ----------------------------------------- @subsection @@arduino/uptime @cindex uptime @deftypefn {} {@var{sec} =} uptime (@var{ar}) Get the number of seconds the arduino board has been running concurrently. @subsubheading Inputs @var{ar} - the arduino object of the connection to an arduino board. @subsubheading Outputs @var{sec} - the number seconds the board has been running. Note that the count will wrap around after approximately 50 days. @xseealso{arduino} @end deftypefn @c Arduino Functions @arduino/validatePin @c ----------------------------------------- @subsection @@arduino/validatePin @cindex validatePin @deftypefn {} {} validatePin (@var{ar}, @var{pin}, @var{type}) Validate that the mode is allowed for specified pin If the mode is not valid, and error will be thrown. @subsubheading Inputs @var{ar} - connected arduino object @var{pin} - name of pin to query mode validity of @var{mode} - mode to query Known modes are: @itemize @bullet @item 'I2C' @item 'SPI' @item 'PWM' @item 'Servo' @item 'analog' @item 'digital' @end itemize @xseealso{arduino, configurePin} @end deftypefn @c Arduino Functions @arduino/version @c ----------------------------------------- @subsection @@arduino/version @cindex version @deftypefn {} {@var{ver} =} version (@var{ar}) Get version of library code installed on arduino board @subsubheading Inputs @var{ar} - the arduino object of the connection to an arduino board. @subsubheading Outputs @var{ver} - version string in format of X.Y.Z. @xseealso{arduino} @end deftypefn @c Arduino Functions @arduino/writeDigitalPin @c ----------------------------------------- @subsection @@arduino/writeDigitalPin @cindex writeDigitalPin @deftypefn {} {} writeDigitalPin (@var{ar}, @var{pin}, @var{value}) Write digital value to a digital I/O pin. @subsubheading Inputs @var{ar} - connected arduino object. @var{pin} - string name of the pin to write to. @var{value} - the logical value (0, 1, true false) to write to the pin. If pin was unconfigured before using, pin is set into digital mode. @subsubheading Example @example @code{ a = arduino(); writeDigitalPin(a,'D5',1); } @end example @xseealso{arduino, readDigitalPin} @end deftypefn @c Arduino Functions @arduino/writePWMDutyCycle @c ----------------------------------------- @subsection @@arduino/writePWMDutyCycle @cindex writePWMDutyCycle @deftypefn {} {} writePWMDutyCyle (@var{ar}, @var{pin}, @var{value}) Set pin to output a square wave with a specified duty cycle. @subsubheading Inputs @var{ar} - connected arduino object @var{pin} - pin to write to. @var{value} - duty cycle value where 0 = off, 0.5 = 50% on, 1 = always on. @subsubheading Example @example @code{ a = arduino(); writePWMDutyCycle(a,'D5',0.5); } @end example @xseealso{arduino, writePWMVoltage} @end deftypefn @c Arduino Functions @arduino/writePWMVoltage @c ----------------------------------------- @subsection @@arduino/writePWMVoltage @cindex writePWMVoltage @deftypefn {} {} writePWMVoltage (@var{ar}, @var{pin}, @var{voltage}) Emulate an approximate voltage out of a pin using PWM. @subsubheading Inputs @var{ar} - connected arduino object @var{pin} - pin to write to. @var{voltage} - voltage to emulate with PWM, between 0 - 5.0 @subsubheading Example @example @code{ a = arduino(); writePWMVoltage(a,'D5',1.0); } @end example @xseealso{arduino, writePWMDutyCycle} @end deftypefn @c --------------------------------------------------- @node Arduino I2C Functions @section Arduino I2C Functions @cindex Arduino I2C Functions @c Arduino I2C Functions @device/delete @c ----------------------------------------- @subsection @@device/delete @cindex delete @deftypefn {} {} delete (@var{dev}) Free resources of a device object. @subsubheading Inputs @var{dev} - object to free @xseealso{device} @end deftypefn @c Arduino I2C Functions @device/disp @c ----------------------------------------- @subsection @@device/disp @cindex disp @deftypefn {} {} disp (@var{dev}) Display device object. @subsubheading Inputs @var{dev} - device object to display @xseealso{device} @end deftypefn @c Arduino I2C Functions @device/read @c ----------------------------------------- @subsection @@device/read @cindex read @deftypefn {} {@var{data} =} read (@var{dev}, @var{numbytes}) @deftypefnx {} {@var{data} =} read (@var{dev}, @var{numbytes}, @var{precision}) Read a specified number of bytes from a i2c or serial device object using optional precision for bytesize. @subsubheading Inputs @var{dev} - connected i2c or serial device opened using device @var{numbytes} - number of bytes to read. @var{precision} - Optional precision for the output data read data. Currently known precision values are uint8 (default), int8, uint16, int16 @subsubheading Outputs @var{data} - data read from the device @xseealso{arduino, device} @end deftypefn @c Arduino I2C Functions @device/readRegister @c ----------------------------------------- @subsection @@device/readRegister @cindex readRegister @deftypefn {} {@var{data} =} readRegister (@var{dev}, @var{reg}, @var{numbytes}) @deftypefnx {} {@var{data} =} readRegister (@var{dev}, @var{reg}, @var{numbytes}, @var{precision}) Read a specified number of bytes from a register of an i2cdev object using optional precision for bytesize. @subsubheading Inputs @var{dev} - connected i2c device opened using device @var{reg} - registry value number @var{numbytes} - number of bytes to read. @var{precision} - Optional precision for the output data read data. Currently known precision values are uint8 (default), int8, uint16, int16 @subsubheading Output @var{data} - data read from device. @xseealso{arduino, device} @end deftypefn @c Arduino I2C Functions @device/subsref @c ----------------------------------------- @subsection @@device/subsref @cindex subsref @deftypefn {} {@var{val} = } subsref (@var{dev}, @var{sub}) subref for device @xseealso{device} @end deftypefn @c Arduino I2C Functions @device/write @c ----------------------------------------- @subsection @@device/write @cindex write @deftypefn {} {} write (@var{dev}, @var{datain}) @deftypefnx {} {} write (@var{dev}, @var{datain}, @var{precision}) Write data to a I2C or serial device object using optional precision for the data byte used for the data. @subsubheading Inputs @var{dev} - connected i2c or serial device opened using device @var{datain} - data to write to device. Datasize should not exceed the constraints of the data type specified for the precision. @var{precision} - Optional precision for the input write data. Currently known precision values are uint8 (default), int8, uint16, int16 @xseealso{arduino, device, read} @end deftypefn @c Arduino I2C Functions @device/writeRegister @c ----------------------------------------- @subsection @@device/writeRegister @cindex writeRegister @deftypefn {} {} writeRegister (@var{dev}, @var{reg}, @var{datain}) @deftypefnx {} {} writeRegister (@var{dev}, @var{dev}, @var{datain}, @var{precision}) Write data to i2c device object at a given registry position using optional precision for the data byte used for the data. @subsubheading Inputs @var{dev} - connected i2c device opened using device @var{reg} - registry position to write to. @var{datain} - data to write to device. Datasize should not exceed the constraints of the data type specified for the precision. @var{precision} - Optional precision for the input write data. Currently known precision values are uint8 (default), int8, uint16, int16 @xseealso{arduino, device, read} @end deftypefn @c Arduino I2C Functions @i2cdev/delete @c ----------------------------------------- @subsection @@i2cdev/delete @cindex delete @deftypefn {} {} delete (@var{dev}) Free resources of a i2cdev object. @subsubheading Inputs @var{dev} - object to free @xseealso{i2cdev} @end deftypefn @c Arduino I2C Functions @i2cdev/disp @c ----------------------------------------- @subsection @@i2cdev/disp @cindex disp @deftypefn {} {} disp (@var{dev}) Display i2cdev object. @subsubheading Inputs @var{dev} - i2cdev object @xseealso{i2cdev} @end deftypefn @c Arduino I2C Functions @i2cdev/i2cdev @c ----------------------------------------- @subsection @@i2cdev/i2cdev @cindex i2cdev @deftypefn {} {@var{dev} =} i2cdev (@var{ar}, @var{address}) @deftypefnx {} {@var{dev} =} i2cdev (@var{ar}, @var{address}, @var{propname}, @var{propvalue}) @code{i2cdev} is depreciated and will be removed in a future version. Use @code{device} instead. Create an i2cdev object to communicate to the i2c port on a connected arduino. @subsubheading Inputs @var{ar} - connected arduino object @var{address} - address to use for device on I2C bus. @var{propname}, @var{propvalue} - property name/value pair for values to pass to devices. Currently known properties: @table @asis @item bus bus number (when arduino board supports multiple I2C buses) with value of 0 or 1. @end table @subsubheading Outputs @var{dev} - new created i2cdev object. @subsubheading Properties The i2cdev object has the following public properties: @table @asis @item parent The parent (arduino) for this device @item pins pins used by this object @item bus bus used for created object @item address I2C address set for object @end table @xseealso{arduino} @end deftypefn @c Arduino I2C Functions @i2cdev/read @c ----------------------------------------- @subsection @@i2cdev/read @cindex read @deftypefn {} {@var{data} =} read (@var{dev}, @var{numbytes}) @deftypefnx {} {@var{data} =} read (@var{dev}, @var{numbytes}, @var{precision}) Read a specified number of bytes from a i2cdev object using optional precision for bytesize. @subsubheading Inputs @var{dev} - connected i2c device opened using i2cdev @var{numbytes} - number of bytes to read. @var{precision} - Optional precision for the output data read data. Currently known precision values are uint8 (default), int8, uint16, int16 @subsubheading Outputs @var{data} - data read from i2cdevice @xseealso{arduino, i2cdev} @end deftypefn @c Arduino I2C Functions @i2cdev/readRegister @c ----------------------------------------- @subsection @@i2cdev/readRegister @cindex readRegister @deftypefn {} {@var{data} =} readRegister (@var{dev}, @var{reg}, @var{numbytes}) @deftypefnx {} {@var{data} =} readRegister (@var{dev}, @var{reg}, @var{numbytes}, @var{precision}) Read a specified number of bytes from a register of an i2cdev object using optional precision for bytesize. @subsubheading Inputs @var{dev} - connected i2c device opened using i2cdev @var{reg} - registry value number @var{numbytes} - number of bytes to read. @var{precision} - Optional precision for the output data read data. Currently known precision values are uint8 (default), int8, uint16, int16 @subsubheading Output @var{data} - data read from device. @xseealso{arduino, i2cdev} @end deftypefn @c Arduino I2C Functions @i2cdev/subsref @c ----------------------------------------- @subsection @@i2cdev/subsref @cindex subsref @deftypefn {} {@var{val} = } subsref (@var{dev}, @var{sub}) subref for i2cdev @xseealso{i2cdev} @end deftypefn @c Arduino I2C Functions @i2cdev/write @c ----------------------------------------- @subsection @@i2cdev/write @cindex write @deftypefn {} {} write (@var{dev}, @var{datain}) @deftypefnx {} {} write (@var{dev}, @var{datain}, @var{precision}) Write data to a i2cdev object using optional precision for the data byte used for the data. @subsubheading Inputs @var{dev} - connected i2c device opened using i2cdev @var{datain} - data to write to device. Datasize should not exceed the constraints of the data type specified for the precision. @var{precision} - Optional precision for the input write data. Currently known precision values are uint8 (default), int8, uint16, int16 @xseealso{arduino, i2cdev, read} @end deftypefn @c Arduino I2C Functions @i2cdev/writeRegister @c ----------------------------------------- @subsection @@i2cdev/writeRegister @cindex writeRegister @deftypefn {} {} writeRegister (@var{dev}, @var{reg}, @var{datain}) @deftypefnx {} {} writeRegister (@var{dev}, @var{dev}, @var{datain}, @var{precision}) Write data to i2cdev object at a given registry position using optional precision for the data byte used for the data. @subsubheading Inputs @var{dev} - connected i2c device opened using i2cdev @var{reg} - registry position to write to. @var{datain} - data to write to device. Datasize should not exceed the constraints of the data type specified for the precision. @var{precision} - Optional precision for the input write data. Currently known precision values are uint8 (default), int8, uint16, int16 @xseealso{arduino, i2cdev, read} @end deftypefn @c Arduino I2C Functions scanI2Cbus @c ----------------------------------------- @subsection scanI2Cbus @cindex scanI2Cbus @deftypefn {} {@var{retval} =} scanI2Cbus (@var{ar}) @deftypefnx {} {@var{retval} =} scanI2Cbus (@var{ar}, @var{bus}) Scan arduino for devices on the I2C bus. @subsubheading Inputs @var{ar} - arduino object connected to a arduino board. @var{bus} - bus number to scan I2C devices, when multiple buses are available. If the bus is not specified, it will default to 0. @subsubheading Outputs @var{retval} - cell array of addresses as strings in format of "0xXX". @subsubheading Example @example @code { # create arduino connection. ar = arduino(); # scan for devices on the I2C bus scanI2Cbus (ar) # output is each detected i2c address as a string ans = @{ [1,1] = 0x50 @} } @end example @xseealso{arduino, i2cdev, checkI2CAddress} @end deftypefn @c --------------------------------------------------- @node Arduino Rotary Encoder Functions @section Arduino Rotary Encoder Functions @cindex Arduino Rotary Encoder Functions @c Arduino Rotary Encoder Functions @rotaryEncoder/delete @c ----------------------------------------- @subsection @@rotaryEncoder/delete @cindex delete @deftypefn {} {} delete (@var{dev}) Free resources of a encoder object. @subsubheading Inputs @var{dev} - object to free @xseealso{rotartEncoder} @end deftypefn @c Arduino Rotary Encoder Functions @rotaryEncoder/disp @c ----------------------------------------- @subsection @@rotaryEncoder/disp @cindex disp @deftypefn {} {@var{retval} =} disp (@var{obj}) Display the rotary encoder object in a verbose way, @subsubheading Inputs @var{obj} - the arduino rotary encoder object created with rotaryEncoder @xseealso{rotaryEncoder} @end deftypefn @c Arduino Rotary Encoder Functions @rotaryEncoder/readCount @c ----------------------------------------- @subsection @@rotaryEncoder/readCount @cindex readCount @deftypefn {} {[@var{count}, @var{time}] =} readCount (@var{obj}) @deftypefnx {} {[@var{count}, @var{time}] =} readCount (@var{obj}, @var{name}, @var{value}) read count value from the rotary encoder. subsubheading Inputs @var{obj} - rotary encoder object created with rotaryEncoder call. @var{name}, @var{value} - optional name,value pairs Valid option name pairs currently are: @table @asis @item reset Reset the count after reading (if true) @end table @subsubheading Outputs @var{count} - returned count read from the encoder. @var{time} - seconds since arduino started @xseealso{rotaryEncoder, resetCount} @end deftypefn @c Arduino Rotary Encoder Functions @rotaryEncoder/readSpeed @c ----------------------------------------- @subsection @@rotaryEncoder/readSpeed @cindex readSpeed @deftypefn {} {@var{speed} =} readSpeed (@var{obj}) read rotational speed from the rotary encoder. @subsubheading Inputs @var{obj} - rotary encoder object created with rotaryEncoder call. @subsubheading Outputs @var{speed} - returned speed in revolutions per minute read from the encoder. @xseealso{rotaryEncoder, resetCount} @end deftypefn @c Arduino Rotary Encoder Functions @rotaryEncoder/resetCount @c ----------------------------------------- @subsection @@rotaryEncoder/resetCount @cindex resetCount @deftypefn {} reset (@var{obj}) @deftypefnx {} reset (@var{obj}, @var{cnt}) reset the rotary encoder count values @subsubheading Inputs @var{obj} - the rotaryEncoder object @var{cnt} - optional count value to reset to @xseealso{rotaryEncoder, readCount} @end deftypefn @c Arduino Rotary Encoder Functions @rotaryEncoder/rotaryEncoder @c ----------------------------------------- @subsection @@rotaryEncoder/rotaryEncoder @cindex rotaryEncoder @deftypefn {} {@var{obj} =} rotaryEncoder (@var{ar}, @var{chanApin}, @var{chanBpin}) @deftypefnx {} {@var{obj} =} rotaryEncoder (@var{ar}, @var{chanApin}, @var{chanBpin}, @var{ppr}) Create a rotaryEncoder object controlled by the input pins. @subsubheading Inputs @var{ar} - connected arduino object. @var{chanApin} - pin used for channel A @var{chanBpin} - pin used for channel B @var{ppr} - count of encoder pulsed required for a full revolution of the encoder. @subsubheading Outputs @var{obj} - created rotary encoder object @subsubheading Example @example a = arduino (); enc = rotaryEncoder(a, "d2", "d3", 180); @end example @subsubheading Properties The rotaryEncoder object has the following public properties: @table @asis @item parent The parent (arduino) for this device @item pins pins used by this object @item ppr Number of pulses used per rotation @end table @xseealso{arduino} @end deftypefn @c Arduino Rotary Encoder Functions @rotaryEncoder/subsref @c ----------------------------------------- @subsection @@rotaryEncoder/subsref @cindex subsref @deftypefn {} {@var{val} = } subsref (@var{dev}, @var{sub}) subref for rotaryEncoder @xseealso{rotaryEncoder} @end deftypefn @c --------------------------------------------------- @node Arduino Servo Functions @section Arduino Servo Functions @cindex Arduino Servo Functions @c Arduino Servo Functions @servo/delete @c ----------------------------------------- @subsection @@servo/delete @cindex delete @deftypefn {} {} delete (@var{dev}) Free resources of a servo object. @subsubheading Inputs @var{dev} - object to free @xseealso{servo} @end deftypefn @c Arduino Servo Functions @servo/disp @c ----------------------------------------- @subsection @@servo/disp @cindex disp @deftypefn {} {} disp (@var{dev}) Display servo object. @subsubheading Inputs @var{dev} - servo device to display @xseealso{servo} @end deftypefn @c Arduino Servo Functions @servo/readPosition @c ----------------------------------------- @subsection @@servo/readPosition @cindex readPosition @deftypefn {} {@var{position} = } readPosition (@var{servo}) Read the position of a servo @subsubheading Inputs @var{servo} - servo object created from arduino.servo. @subsubheading Outputs @var{position} - value between 0 .. 1 for the current servo position, where 0 is the servo min position, 1 is the servo maximum position. @xseealso{servo, writePosition} @end deftypefn @c Arduino Servo Functions @servo/servo @c ----------------------------------------- @subsection @@servo/servo @cindex servo @deftypefn {} {@var{obj} = } servo (@var{arduinoobj}, @var{pin}) @deftypefnx {} {@var{obj} = } servo (@var{arduinoobj}, @var{pin}, @var{propertyname}, @var{propertyvalue}) Create a servo object using a specified pin on a arduino board. @subsubheading Inputs @var{obj} - servo object @var{arduinoobj} - connected arduino object @var{propertyname}, @var{propertyvalue} - name value pairs for properties to pass to the created servo object. Current properties are: @table @asis @item minpulseduration min PWM pulse value in seconds. @item maxpulseduration max PWM pulse value in seconds. @end table @subsubheading Outputs @var{obj} - created servo object. @subsubheading Example @example # create arduino connection ar = arduino(); # create hobby servo (1 - 2 ms pulse range) servo = servo(ar, "d9", "minpulseduration", 1.0e-3, "maxpulseduration", 2e-3); # center the servo writePosition(servo, 0.5); @end example @subsubheading Properties The servo object has the following public properties: @table @asis @item parent The parent (arduino) for this device @item pins pins used by this object @item minpulseduration minpulseduration set for object @item maxpulseduration maxpulseduration set for object @end table @xseealso{arduino, readPosition, writePosition} @end deftypefn @c Arduino Servo Functions @servo/subsref @c ----------------------------------------- @subsection @@servo/subsref @cindex subsref @deftypefn {} {@var{val} = } subsref (@var{dev}, @var{sub}) subref for servo @xseealso{servo} @end deftypefn @c Arduino Servo Functions @servo/writePosition @c ----------------------------------------- @subsection @@servo/writePosition @cindex writePosition @deftypefn {} {} writePosition (@var{servo}, @var{position}) Write the position to a servo. @subsubheading Inputs @var{servo} - servo object created from arduino.servo. @var{position} - value between 0 .. 1 for the current servo position, where 0 is the servo min position, 1 is the servo maximum position. @xseealso{servo, readPosition} @end deftypefn @c --------------------------------------------------- @node Arduino Shiftregister Functions @section Arduino Shiftregister Functions @cindex Arduino Shiftregister Functions @c Arduino Shiftregister Functions @shiftRegister/delete @c ----------------------------------------- @subsection @@shiftRegister/delete @cindex delete @deftypefn {} {} delete (@var{dev}) Free resources of a shiftRegister object. @subsubheading Inputs @var{dev} - object to free @xseealso{shiftRegister} @end deftypefn @c Arduino Shiftregister Functions @shiftRegister/disp @c ----------------------------------------- @subsection @@shiftRegister/disp @cindex disp @deftypefn {} {} disp (@var{register}) Display the register object in a verbose way, @subsubheading Inputs @var{register} - the arduino register object created with shiftRegister. @xseealso{shiftRegister} @end deftypefn @c Arduino Shiftregister Functions @shiftRegister/read @c ----------------------------------------- @subsection @@shiftRegister/read @cindex read @deftypefn {} {@var{retval} =} read (@var{register}) @deftypefnx {} {@var{retval} =} read (@var{register}, @var{precision}) read a value from the shift register. @subsubheading Inputs @var{register} - shift register created from shiftRegister call. @var{precision} - optional precision of the data, where precision can be a number in a multiple of 8 (ie: 8,16,32) or can be a named integer type: 8 of 'uint8', 'uint16', 'uint32'. The default precision is 8. @subsubheading Outputs @var{retval} - returned data read from the register. @xseealso{shiftRegister, write} @end deftypefn @c Arduino Shiftregister Functions @shiftRegister/reset @c ----------------------------------------- @subsection @@shiftRegister/reset @cindex reset @deftypefn {} reset (@var{register}) clear the shift register value. @subsubheading Inputs @var{register} - shift register created from shiftRegister call. @xseealso{shiftRegister, read, write} @end deftypefn @c Arduino Shiftregister Functions @shiftRegister/shiftRegister @c ----------------------------------------- @subsection @@shiftRegister/shiftRegister @cindex shiftRegister @deftypefn {} {@var{register} =} shiftRegister (@var{ar}, @var{shifttype}, @var{dataPin}, @var{clockPin} ...) @deftypefnx {} {@var{register} =} shiftRegister (@var{ar},'74hc164', @var{dataPin}, @var{clockPin}, @var{resetPin}) @deftypefnx {} {@var{register} =} shiftRegister (@var{ar},'74hc165', @var{dataPin}, @var{clockPin}, @var{loadPin}, @var{clockEnablePin}) @deftypefnx {} {@var{register} =} shiftRegister(@var{ar},'74hc595', @var{dataPin}, @var{clockPin}, @var{latchPin} , @var{resetPin}) Create shift register of a given type, controlled by the input pins. @subsubheading Inputs Common function parameter definition: @var{ar} - connected arduino object. @var{shifttype} - string name of the shift register type. @var{dataPin} - pin used for data in/out of the device. @var{clockPin} - pin used for clocking data on the shiftRegister. Other variables are dependent on the shift register type: @table @asis @item '74hc164' Additional inputs: @var{resetPin} - optional pin for resetting the shift register. @item '74hc165' Additional inputs: @var{loadPin} - load pin to the shift register. @var{clockEnablePin} - clock enable pin. @item '74hc595' Additional inputs: @var{latchPin} - latching data to the shift register. @var{resetPin} - optional pin for resetting the shift register. @end table @subsubheading Outputs @var{register} - register object @subsubheading Properties The shiftRegister object has the following public properties: @table @asis @item parent The parent (arduino) for this device @item pins pins used by this object @item model model set for object @end table @xseealso{arduino} @end deftypefn @c Arduino Shiftregister Functions @shiftRegister/subsref @c ----------------------------------------- @subsection @@shiftRegister/subsref @cindex subsref @deftypefn {} {@var{val} = } subsref (@var{dev}, @var{sub}) subref for shiftRegister @xseealso{shiftRegister} @end deftypefn @c Arduino Shiftregister Functions @shiftRegister/write @c ----------------------------------------- @subsection @@shiftRegister/write @cindex write @deftypefn {} write (@var{register}, @var{dataIn}) @deftypefnx {} write (@var{register}, @var{dataIn}, @var{precision}) Write a value to the shift register. @subsubheading Inputs @var{register} - shift register created from shiftRegister call. @var{dataIn} - data to clock into the shiftRegister. @var{precision} - optional precision of the data, where precision can be a number in a multiple of 8 (ie: 8,16,32) or can be a named integer type of 'uint8', 'uint16', 'uint32'. The default precision is 8. @xseealso{shiftRegister, read} @end deftypefn @c --------------------------------------------------- @node Arduino SPI Functions @section Arduino SPI Functions @cindex Arduino SPI Functions @c Arduino SPI Functions @device/delete @c ----------------------------------------- @subsection @@device/delete @cindex delete @deftypefn {} {} delete (@var{dev}) Free resources of a device object. @subsubheading Inputs @var{dev} - object to free @xseealso{device} @end deftypefn @c Arduino SPI Functions @device/disp @c ----------------------------------------- @subsection @@device/disp @cindex disp @deftypefn {} {} disp (@var{dev}) Display device object. @subsubheading Inputs @var{dev} - device object to display @xseealso{device} @end deftypefn @c Arduino SPI Functions @device/subsref @c ----------------------------------------- @subsection @@device/subsref @cindex subsref @deftypefn {} {@var{val} = } subsref (@var{dev}, @var{sub}) subref for device @xseealso{device} @end deftypefn @c Arduino SPI Functions @device/writeRead @c ----------------------------------------- @subsection @@device/writeRead @cindex writeRead @deftypefn {} {@var{dataOut} =} readWrite (@var{spi}, @var{dataIn}) Write uint8 data to spi device and return back clocked out response data of same size. @subsubheading Inputs @var{spi} - connected spi device on arduino @var{dataIn} - uint8 sized data to send to spi device framed between SS frame. @subsubheading Outputs @var{dataOut} - uint8 data clocked out during send to dataIn. @xseealso{arduino, device} @end deftypefn @c Arduino SPI Functions @spidev/delete @c ----------------------------------------- @subsection @@spidev/delete @cindex delete @deftypefn {} {} delete (@var{dev}) Free resources of a spidev object. @subsubheading Inputs @var{dev} - spidev object to free @xseealso{spidev} @end deftypefn @c Arduino SPI Functions @spidev/disp @c ----------------------------------------- @subsection @@spidev/disp @cindex disp @deftypefn {} {} disp (@var{dev}) Display spidev object. @subsubheading Inputs @var{dev} - spidev object to display @xseealso{spidev} @end deftypefn @c Arduino SPI Functions @spidev/spidev @c ----------------------------------------- @subsection @@spidev/spidev @cindex spidev @deftypefn {} {@var{dev} =} spidev (@var{ar}, @var{cspin}) @deftypefnx {} {@var{dev} =} spidev (@var{ar}, @var{cspin}, @var{propname}, @var{propvalue}) @code{spidev} is depreciated and will be removed in a future version. Use @code{device} instead. Create an spidev object to communicate to the SPI port on a connected arduino. @subsubheading Inputs @var{ar} - connected arduino object @var{cspin} - chip select pin for attached spi device. @var{propname}, @var{propvalue} - property name/value pair for values to pass to devices. Currently known properties: @table @asis @item bitrate bit rate speed in Mbs @item bitorder 'msbfirst' or 'lsbfirst' @item mode SPI mode 0 - 3. @end table @subsubheading Outputs @var{dev} - created spidev object @subsubheading Properties The spidev object has the following public properties: @table @asis @item parent The parent (arduino) for this device @item pins pins used by this object @item mode mode used for created object @item bitrate Bitrate set for object @item bitorder Bitorder set for object @item chipselectpin Pin used for chipselect @end table @xseealso{arduino, readWrite} @end deftypefn @c Arduino SPI Functions @spidev/subsref @c ----------------------------------------- @subsection @@spidev/subsref @cindex subsref @deftypefn {} {@var{val} = } subsref (@var{dev}, @var{sub}) subref for spidev @xseealso{spidev} @end deftypefn @c Arduino SPI Functions @spidev/writeRead @c ----------------------------------------- @subsection @@spidev/writeRead @cindex writeRead @deftypefn {} {@var{dataOut} =} readWrite (@var{spi}, @var{dataIn}) Write uint8 data to spi device and return back clocked out response data of same size. @subsubheading Inputs @var{spi} - connected spi device on arduino @var{dataIn} - uint8 sized data to send to spi device framed between SS frame. @subsubheading Outputs @var{dataOut} - uint8 data clocked out during send to dataIn. @xseealso{arduino, spidev} @end deftypefn @c --------------------------------------------------- @node Arduino Serial Functions @section Arduino Serial Functions @cindex Arduino Serial Functions @c Arduino Serial Functions @device/delete @c ----------------------------------------- @subsection @@device/delete @cindex delete @deftypefn {} {} delete (@var{dev}) Free resources of a device object. @subsubheading Inputs @var{dev} - object to free @xseealso{device} @end deftypefn @c Arduino Serial Functions @device/device @c ----------------------------------------- @subsection @@device/device @cindex device @deftypefn {} {@var{dev} =} device (@var{ar}, 'I2CAddress', @var{address}) @deftypefnx {} {@var{dev} =} device (@var{ar}, 'SPIChipSelectPin', @var{pin}) @deftypefnx {} {@var{dev} =} device (@var{ar}, 'Serial', @var{serialid}) @deftypefnx {} {@var{dev} =} device (..., @var{propname}, @var{propvalue}) Create an i2c, spi or serial object to communicate on a connected arduino. @subsubheading Inputs @var{ar} - connected arduino object @var{propname}, @var{propvalue} - property name/value pair for values to pass to devices. A property of 'i2caddress', 'spichipselectpin' or 'serial' must be specified to denote the device type to create. @var{i2caddress} - address to use for device on I2C bus. @var{pin} - pin to use for device SPI chip select. @var{serialid} - Serial port id to use Additional properties can also be specified for the device object Currently known input I2C properties values: @table @asis @item bus bus number (when arduino board supports multiple I2C buses) with value of 0 or 1. @item noprobe Do not probe the existence of device on creation if set to 1 (default 0) @item bitrate bit rate speed in Mbs - default 100000 @end table Currently known input SPI properties values: @table @asis @item bitrate bit rate speed in Mbs @item bitorder 'msbfirst' or 'lsbfirst' @item spimode SPI mode 0 - 3. @end table Currently known input Serial properties values: @table @asis @item baudrate baudrate value (default 9600) @item databits number of databits (5,6,7,8) (default 8) @item stopbits number of stopbits (1,2) (default 1) @item parity parity of device ('odd','even','none') (default 'none') @end table @subsubheading Outputs @var{dev} - new created device object. @subsubheading Properties The object has the following public properties: @table @asis @item parent The parent (arduino) for this device @item interface The interface type for this device ("SPI" or "I2C" or "Serial") @end table In addition, depending on type, the object will have these properties: @subsubheading I2C Properties The object has the following public properties: @table @asis @item bus bus used for created object @item i2caddress I2C address set for object @item sclpin the SCL pin of the device @item sdapin the SDA pin of the device @item bitrate bit rate for the i2c clock @end table @subsubheading SPI Properties The object has the following public properties: @table @asis @item spimode mode used for created object @item bitrate Bitrate set for object @item bitorder Bitorder set for object @item spichipselectpin Pin used for chipselect @item mosipin Pin used for mosi @item misopin Pin used for miso @item sckpin Pin used for sckpin @end table @subsubheading Serial Properties The object has the following public properties: @table @asis @item id serial port id @item baudrate baudrate @item databits number of databits (5,6,7,8) @item stopbits number of stopbits (1,2) @item parity parity of device ('odd','even','none') @end table @xseealso{arduino, i2cdev, spidev} @end deftypefn @c Arduino Serial Functions @device/disp @c ----------------------------------------- @subsection @@device/disp @cindex disp @deftypefn {} {} disp (@var{dev}) Display device object. @subsubheading Inputs @var{dev} - device object to display @xseealso{device} @end deftypefn @c Arduino Serial Functions @device/flush @c ----------------------------------------- @subsection @@device/flush @cindex flush @deftypefn {} {@var{data} =} flush (@var{dev}) @deftypefnx {} {@var{data} =} flush (@var{dev}, "input") @deftypefnx {} {@var{data} =} flush (@var{dev}, "output") Flush the serial port buffers @subsubheading Inputs @var{dev} - connected serial device opened using device If an additional parameter is provided of "input" or "output", then only the input or output buffer will be flushed @subsubheading Outputs None @xseealso{arduino, device, read} @end deftypefn @c Arduino Serial Functions @device/read @c ----------------------------------------- @subsection @@device/read @cindex read @deftypefn {} {@var{data} =} read (@var{dev}, @var{numbytes}) @deftypefnx {} {@var{data} =} read (@var{dev}, @var{numbytes}, @var{precision}) Read a specified number of bytes from a i2c or serial device object using optional precision for bytesize. @subsubheading Inputs @var{dev} - connected i2c or serial device opened using device @var{numbytes} - number of bytes to read. @var{precision} - Optional precision for the output data read data. Currently known precision values are uint8 (default), int8, uint16, int16 @subsubheading Outputs @var{data} - data read from the device @xseealso{arduino, device} @end deftypefn @c Arduino Serial Functions @device/subsref @c ----------------------------------------- @subsection @@device/subsref @cindex subsref @deftypefn {} {@var{val} = } subsref (@var{dev}, @var{sub}) subref for device @xseealso{device} @end deftypefn @c Arduino Serial Functions @device/write @c ----------------------------------------- @subsection @@device/write @cindex write @deftypefn {} {} write (@var{dev}, @var{datain}) @deftypefnx {} {} write (@var{dev}, @var{datain}, @var{precision}) Write data to a I2C or serial device object using optional precision for the data byte used for the data. @subsubheading Inputs @var{dev} - connected i2c or serial device opened using device @var{datain} - data to write to device. Datasize should not exceed the constraints of the data type specified for the precision. @var{precision} - Optional precision for the input write data. Currently known precision values are uint8 (default), int8, uint16, int16 @xseealso{arduino, device, read} @end deftypefn @c --------------------------------------------------- @node Arduino Device Functions @section Arduino Device Functions @cindex Arduino Device Functions @c Arduino Device Functions @device/delete @c ----------------------------------------- @subsection @@device/delete @cindex delete @deftypefn {} {} delete (@var{dev}) Free resources of a device object. @subsubheading Inputs @var{dev} - object to free @xseealso{device} @end deftypefn @c Arduino Device Functions @device/device @c ----------------------------------------- @subsection @@device/device @cindex device @deftypefn {} {@var{dev} =} device (@var{ar}, 'I2CAddress', @var{address}) @deftypefnx {} {@var{dev} =} device (@var{ar}, 'SPIChipSelectPin', @var{pin}) @deftypefnx {} {@var{dev} =} device (@var{ar}, 'Serial', @var{serialid}) @deftypefnx {} {@var{dev} =} device (..., @var{propname}, @var{propvalue}) Create an i2c, spi or serial object to communicate on a connected arduino. @subsubheading Inputs @var{ar} - connected arduino object @var{propname}, @var{propvalue} - property name/value pair for values to pass to devices. A property of 'i2caddress', 'spichipselectpin' or 'serial' must be specified to denote the device type to create. @var{i2caddress} - address to use for device on I2C bus. @var{pin} - pin to use for device SPI chip select. @var{serialid} - Serial port id to use Additional properties can also be specified for the device object Currently known input I2C properties values: @table @asis @item bus bus number (when arduino board supports multiple I2C buses) with value of 0 or 1. @item noprobe Do not probe the existence of device on creation if set to 1 (default 0) @item bitrate bit rate speed in Mbs - default 100000 @end table Currently known input SPI properties values: @table @asis @item bitrate bit rate speed in Mbs @item bitorder 'msbfirst' or 'lsbfirst' @item spimode SPI mode 0 - 3. @end table Currently known input Serial properties values: @table @asis @item baudrate baudrate value (default 9600) @item databits number of databits (5,6,7,8) (default 8) @item stopbits number of stopbits (1,2) (default 1) @item parity parity of device ('odd','even','none') (default 'none') @end table @subsubheading Outputs @var{dev} - new created device object. @subsubheading Properties The object has the following public properties: @table @asis @item parent The parent (arduino) for this device @item interface The interface type for this device ("SPI" or "I2C" or "Serial") @end table In addition, depending on type, the object will have these properties: @subsubheading I2C Properties The object has the following public properties: @table @asis @item bus bus used for created object @item i2caddress I2C address set for object @item sclpin the SCL pin of the device @item sdapin the SDA pin of the device @item bitrate bit rate for the i2c clock @end table @subsubheading SPI Properties The object has the following public properties: @table @asis @item spimode mode used for created object @item bitrate Bitrate set for object @item bitorder Bitorder set for object @item spichipselectpin Pin used for chipselect @item mosipin Pin used for mosi @item misopin Pin used for miso @item sckpin Pin used for sckpin @end table @subsubheading Serial Properties The object has the following public properties: @table @asis @item id serial port id @item baudrate baudrate @item databits number of databits (5,6,7,8) @item stopbits number of stopbits (1,2) @item parity parity of device ('odd','even','none') @end table @xseealso{arduino, i2cdev, spidev} @end deftypefn @c Arduino Device Functions @device/disp @c ----------------------------------------- @subsection @@device/disp @cindex disp @deftypefn {} {} disp (@var{dev}) Display device object. @subsubheading Inputs @var{dev} - device object to display @xseealso{device} @end deftypefn @c Arduino Device Functions @device/flush @c ----------------------------------------- @subsection @@device/flush @cindex flush @deftypefn {} {@var{data} =} flush (@var{dev}) @deftypefnx {} {@var{data} =} flush (@var{dev}, "input") @deftypefnx {} {@var{data} =} flush (@var{dev}, "output") Flush the serial port buffers @subsubheading Inputs @var{dev} - connected serial device opened using device If an additional parameter is provided of "input" or "output", then only the input or output buffer will be flushed @subsubheading Outputs None @xseealso{arduino, device, read} @end deftypefn @c Arduino Device Functions @device/read @c ----------------------------------------- @subsection @@device/read @cindex read @deftypefn {} {@var{data} =} read (@var{dev}, @var{numbytes}) @deftypefnx {} {@var{data} =} read (@var{dev}, @var{numbytes}, @var{precision}) Read a specified number of bytes from a i2c or serial device object using optional precision for bytesize. @subsubheading Inputs @var{dev} - connected i2c or serial device opened using device @var{numbytes} - number of bytes to read. @var{precision} - Optional precision for the output data read data. Currently known precision values are uint8 (default), int8, uint16, int16 @subsubheading Outputs @var{data} - data read from the device @xseealso{arduino, device} @end deftypefn @c Arduino Device Functions @device/readRegister @c ----------------------------------------- @subsection @@device/readRegister @cindex readRegister @deftypefn {} {@var{data} =} readRegister (@var{dev}, @var{reg}, @var{numbytes}) @deftypefnx {} {@var{data} =} readRegister (@var{dev}, @var{reg}, @var{numbytes}, @var{precision}) Read a specified number of bytes from a register of an i2cdev object using optional precision for bytesize. @subsubheading Inputs @var{dev} - connected i2c device opened using device @var{reg} - registry value number @var{numbytes} - number of bytes to read. @var{precision} - Optional precision for the output data read data. Currently known precision values are uint8 (default), int8, uint16, int16 @subsubheading Output @var{data} - data read from device. @xseealso{arduino, device} @end deftypefn @c Arduino Device Functions @device/subsref @c ----------------------------------------- @subsection @@device/subsref @cindex subsref @deftypefn {} {@var{val} = } subsref (@var{dev}, @var{sub}) subref for device @xseealso{device} @end deftypefn @c Arduino Device Functions @device/write @c ----------------------------------------- @subsection @@device/write @cindex write @deftypefn {} {} write (@var{dev}, @var{datain}) @deftypefnx {} {} write (@var{dev}, @var{datain}, @var{precision}) Write data to a I2C or serial device object using optional precision for the data byte used for the data. @subsubheading Inputs @var{dev} - connected i2c or serial device opened using device @var{datain} - data to write to device. Datasize should not exceed the constraints of the data type specified for the precision. @var{precision} - Optional precision for the input write data. Currently known precision values are uint8 (default), int8, uint16, int16 @xseealso{arduino, device, read} @end deftypefn @c Arduino Device Functions @device/writeRead @c ----------------------------------------- @subsection @@device/writeRead @cindex writeRead @deftypefn {} {@var{dataOut} =} readWrite (@var{spi}, @var{dataIn}) Write uint8 data to spi device and return back clocked out response data of same size. @subsubheading Inputs @var{spi} - connected spi device on arduino @var{dataIn} - uint8 sized data to send to spi device framed between SS frame. @subsubheading Outputs @var{dataOut} - uint8 data clocked out during send to dataIn. @xseealso{arduino, device} @end deftypefn @c Arduino Device Functions @device/writeRegister @c ----------------------------------------- @subsection @@device/writeRegister @cindex writeRegister @deftypefn {} {} writeRegister (@var{dev}, @var{reg}, @var{datain}) @deftypefnx {} {} writeRegister (@var{dev}, @var{dev}, @var{datain}, @var{precision}) Write data to i2c device object at a given registry position using optional precision for the data byte used for the data. @subsubheading Inputs @var{dev} - connected i2c device opened using device @var{reg} - registry position to write to. @var{datain} - data to write to device. Datasize should not exceed the constraints of the data type specified for the precision. @var{precision} - Optional precision for the input write data. Currently known precision values are uint8 (default), int8, uint16, int16 @xseealso{arduino, device, read} @end deftypefn @c --------------------------------------------------- @node Arduino Ultrasonic Functions @section Arduino Ultrasonic Functions @cindex Arduino Ultrasonic Functions @c Arduino Ultrasonic Functions @ultrasonic/delete @c ----------------------------------------- @subsection @@ultrasonic/delete @cindex delete @deftypefn {} {} delete (@var{dev}) Free resources of a ultrasonic object. @subsubheading Inputs @var{dev} - ultrasonic object to free @xseealso{ultrasonic} @end deftypefn @c Arduino Ultrasonic Functions @ultrasonic/disp @c ----------------------------------------- @subsection @@ultrasonic/disp @cindex disp @deftypefn {} {} disp (@var{dev}) Display ultrasonic object. @subsubheading Inputs @var{dev} - ultrasonic object to display @xseealso{ultrasonic} @end deftypefn @c Arduino Ultrasonic Functions @ultrasonic/readDistance @c ----------------------------------------- @subsection @@ultrasonic/readDistance @cindex readDistance @deftypefn {} {@var{distance} =} readDistance (@var{dev}) Read the distance from a ultrasonic device @subsubheading Inputs @var{dev} - connected ultrasonic device opened using ultrasonic @subsubheading Outputs @var{distance} - distance value in meters from the ultrasonic device, or Inf if out of sensor range @xseealso{arduino, ultrasonic} @end deftypefn @c Arduino Ultrasonic Functions @ultrasonic/readEchoTime @c ----------------------------------------- @subsection @@ultrasonic/readEchoTime @cindex readEchoTime @deftypefn {} {@var{time} =} readEchoTime (@var{dev}) Measure the time for waves to reflect back to the ultrasonic device @subsubheading Inputs @var{dev} - connected ultrasonic device opened using ultrasonic() @subsubheading Outputs @var{time} - time in seconds, or Inf if out of sensor range @xseealso{arduino, ultrasonic} @end deftypefn @c Arduino Ultrasonic Functions @ultrasonic/subsref @c ----------------------------------------- @subsection @@ultrasonic/subsref @cindex subsref @deftypefn {} {@var{val} = } subsref (@var{dev}, @var{sub}) subref for ultrasonic @xseealso{ultrasonic} @end deftypefn @c Arduino Ultrasonic Functions @ultrasonic/ultrasonic @c ----------------------------------------- @subsection @@ultrasonic/ultrasonic @cindex ultrasonic @deftypefn {} {@var{dev} =} ultrasonic (@var{ar}, @var{triggerpin}) @deftypefnx {} {@var{dev} =} ultrasonic (@var{ar}, @var{triggerpin}, @var{echopin}) @deftypefnx {} {@var{dev} =} ultrasonic (@var{ar}, @var{triggerpin}, @var{echopin}, @var{propname}, @var{propvalue}) Create an ultrasonic object to communicate to a connected ultrasonic device @subsubheading Inputs @var{ar} - connected arduino object @var{triggerpin} - trigger pin for attached device. @var{echopin} - trigger pin for attached device. @var{propname}, @var{propvalue} - property name/value pair for values to pass to devices. Currently known properties: @table @asis @item outputformat string designating number format for output ('double') @end table @subsubheading Outputs @var{dev} - created ultrasonic object @subsubheading Properties The ultrasonic object has the following public properties: @table @asis @item parent The parent (arduino) for this device @item pins pins used by this object @item triggerpin trigger used for created object @item echopin Echo pin set for object @item outputformat Output format for the created object @end table @xseealso{arduino, readDistance, readEchoTime} @end deftypefn @c --------------------------------------------------- @node Arduino Addons @section Arduino Addons @cindex Arduino Addons @c Arduino Addons addon @c ----------------------------------------- @subsection addon @cindex addon @deftypefn {} {@var{retval} =} addon (@var{ar}, @var{addonname}) @deftypefnx {} {@var{retval} =} addon (@var{ar}, @var{addonname}, varargs) Create an addon object using the addon named class. @subsubheading Inputs @var{ar} - connected arduino object @var{addonname} - the name of the addon to create. The addon name can be a user addon or an inbuilt addon, however must appear in the listArduinoLibraries output and have been programmed onto the arduino. @var{varargs} - optional values that will be provided verbatim to the the addon class constructor. @subsubheading Outputs @var{retval} - cell array of string library names. @xseealso{arduino, arduinosetup, listArduinoLibraries} @end deftypefn @c Arduino Addons arduinoioaddons.EEPRomAddon.EEPRom @c ----------------------------------------- @subsection arduinoioaddons.EEPRomAddon.EEPRom @cindex EEPRom @deftypefn {} {} arduinoioaddons.EEPRomAddon.EEPRom EEPROM addon for arduino Allows read and write of uint8 data to the onboard arduino EEPROM. @subsubheading Example Assuming eeprom addon has been programmed into the Arduino: @example a = arduino (); e = addon (a, "eepromaddon/eeprom"); write (e, 0, uint8("hello world")); str = uint8( read(e, 0, 11) ) @end example @xseealso{addon} @end deftypefn @subsubheading Properties @var{length} - Size of the EEPROM. @subheading Methods @deftypefn {} {@var{eeprom} =} EEPRom () Constructor to create EEPROM device. @subsubheading Outputs @var{eeprom} - created EEPROM device. @end deftypefn @deftypefn {} {} erase () Erase all values in EEPROM (Effectively setting the 0xFF) @end deftypefn @deftypefn {} {} write (@var{address}, @var{uintdata}) Write data to EEPROM at the provided address. @subsubheading Inputs @var{address} - start address to write data to, should be an integer between 0 and the size of the EEPROM. @var{uintdata} a value or array of uint8 data to write to EEPROM. @end deftypefn @deftypefn {} {@var{data} =} read (@var{address}) @deftypefnx {} {@var{data} =} read (@var{address}, @var{count}) Read data from starting address of EEPROM. @subsubheading Inputs @var{address} - start address to read data from, should be an integer between 0 and the size of the EEPROM. @var{count} - Number of uint8 values to read from the EEPROM (default is 1) @subsubheading Outputs @var{data} a value or array of uint8 data read from the EEPROM. @end deftypefn @c Arduino Addons arduinoioaddons.ExampleAddon.Echo @c ----------------------------------------- @subsection arduinoioaddons.ExampleAddon.Echo @cindex Echo @deftypefn {} {} arduinoioaddons.ExampleAddon.Echo Basic Example matlab/octave code to illustrate creating a user addon. @xseealso{addon} @end deftypefn @subsubheading Properties @var{Parent} - the parent arduino object. @var{Pins} - the pins allocated the addon. @subheading Methods @deftypefn {} {@var{obj} =} Echo(arObj) Constructor to create Echo addon @subsubheading Inputs @var{arObj} - the arduino parent object @subsubheading Outputs @var{obj} - created Echo object @end deftypefn @deftypefn {} {@var{response} = } shout(@var{text}) Send text to arduino and receive back the echoed reply @subsubheading Inputs @var{text} - text to send to arduino @subsubheading Outputs @var{response} - response from the arduino, which should be the same as the input text. @end deftypefn @c Arduino Addons arduinoioaddons.ExampleLCD.LCD @c ----------------------------------------- @subsection arduinoioaddons.ExampleLCD.LCD @cindex LCD @deftypefn {} {} arduinoioaddons.LCDAddon.LCD Basic Example octave addon for LCD Allows basic manipulation of an LCD as a illustration of using the addon functionality. @subsubheading Example Assuming the arduino has been programmed with the lcd addon: @example a = arduino(); lcd = addon(a, "examplelcd/lcd", "d8", "d9", "d4", "d5", "d6", "d7") clearLCD(lcd); printLCD(lcd, "Hello"); # go to next line gotoLCD(lcd, 0, 1); printLCD(lcd, "World"); @end example @xseealso{addon} @end deftypefn @subsubheading Properties @var{Pins} - the pins allocated the LCD display. @subheading Methods @deftypefn {} {@var{lcd} =} LCD(arObj, rs, enable, d0, d1, d2, d3) Constructor to create LCD device @subsubheading Inputs @var{arObj} - the arduino parent object @var{rs} - the pin to use for the rs line. @var{enable} - the pin to use for the enable line. @var{d0} - the pin to use for the d0 line. @var{d1} - the pin to use for the d1 line. @var{d2} - the pin to use for the d2 line. @var{d3} - the pin to use for the d3 line. @subsubheading Outputs @var{lcd} - created LCD object @end deftypefn @deftypefn {} {} freeLCD() Free the LCD Should be called before discarding the LCD @subsubheading Inputs None. @subsubheading Outputs None. @end deftypefn @deftypefn {} {} clearLCD() Clear the LCD display and set the cursor position to the home position. @subsubheading Inputs None. @subsubheading Outputs None. @end deftypefn @deftypefn {} {} printLCD(@var{text}) Display text on LCD starting at the current cursor position. @subsubheading Inputs @var{text} - text to display on LCD @subsubheading Outputs None. @end deftypefn @deftypefn {} {} gotoLCD(@var{col}, @var{row}) Set the cursor position to row, col @subsubheading Inputs @var{col} - 0 indexed LCD column to position to. @var{row} - 0 indexed LCD row to position to. @subsubheading Outputs None. @end deftypefn @c Arduino Addons arduinoioaddons.RTCAddon.DS1307 @c ----------------------------------------- @subsection arduinoioaddons.RTCAddon.DS1307 @cindex DS1307 @deftypefn {} {} arduinoioaddons.RTCAddon.DS1307 DS1307 addon @xseealso{addon} @end deftypefn @subsubheading Properties @var{Parent} - the parent arduino object. @var{Pins} - the pins allocated the addon. @subheading Methods @deftypefn {} {@var{obj} =} DS1307(@var{arObj}) @deftypefnx {} {@var{obj} =} DS1307(@var{arObj}, @var{propertyname, propertyvalue} ....) Constructor to create DS1307 addon @subsubheading Inputs @var{arObj} - the arduino parent object @var{propertyname, propertyvalue} - optional property name, value pairs. Current known properties are: @table @asis @item address I2C address of the DS1307 (default 0x68) @end table @subsubheading Outputs @var{obj} - created DS1307 object @subsubheading Example @example @code { a = arduino() rtc = addon(a, "rtcaddon/ds1307") } @end example @end deftypefn @deftypefn {} {@var{date} =} clock(@var{dsObj}) @deftypefnx {} {} clock(@var{dsObj}, @var{date}) Get/set the DS1307 clock @subsubheading Inputs @var{dsObj} - the ds1307 object @var{date} - a date vector in same format as datevec and clock @subsubheading Outputs @var{date} - a date vector in same format as datevec and clock @subsubheading Example @example @code { a = arduino() rtc = addon(a, "rtcaddon/ds1307") # get and display rtc time as a date string datestr(rtc.clock) } @end example @xseealso{datevec} @end deftypefn @deftypefn {} {@var{ctrl} =} control(@var{dsObj}) @deftypefnx {} {} control(@var{dsObj}, @var{ctrl}) Get/set the DS1307 clock @subsubheading Inputs @var{dsObj} - the ds1307 object @var{ctrl} - a structure containing the control bit fields. @subsubheading Outputs @var{ctrl} - a structure containing the control bit fields. Control structure fields are: Current properties are: @table @asis @item out Out bit in the control register @item sqwe Square wave enable bit in control register @item rs The combined RS0, RS1 value @end table @end deftypefn @deftypefn {} {@var{YN} =} isstarted(@var{dsObj}) Get whether the RTC clock is currently counting time @subsubheading Inputs @var{dsObj} - the ds1307 object @subsubheading Outputs @var{YN} - returns true if the RTC is counting @xseealso{start, stop} @end deftypefn @deftypefn {} {} start(@var{dsObj}) Start the RTC counting @subsubheading Inputs @var{dsObj} - the ds1307 object @subsubheading Outputs None @xseealso{datevec} @end deftypefn @deftypefn {} {} stop(@var{dsObj}) Stop the RTC counting @subsubheading Inputs @var{dsObj} - the ds1307 object @subsubheading Outputs None @xseealso{datevec} @end deftypefn @c Arduino Addons arduinoioaddons.SimpleStepper.SimpleStepper @c ----------------------------------------- @subsection arduinoioaddons.SimpleStepper.SimpleStepper @cindex SimpleStepper @deftypefn {} {} arduinoioaddons.SimpleStepper Stepper class for stepper control using ULN2003 and compatible drivers @end deftypefn @subsubheading Properties @table @asis @item @var{Id} Id of the stepper (Read only) @item @var{Speed} Number of steps to do per second. @item Status Status of stepper (Read only). 0 = not moving, 1 = moving, 2 = rotating @item Parent the Arduino parent (read only) @item Pins the pins used for the stepper (read only) @end table @subheading Methods @deftypefn {} {@var{obj} =} SimpleStepper(@var{aObj}, @var{pin1}, @var{pin2}, @var{pin3}, @var{pin4}) @deftypefnx {} {@var{obj} =} SimpleStepper(@var{aObj}, @var{pin1}, @var{pin2}, @var{pin3}, @var{pin4}, @var{pin5}) Constructor to create a stepper object @subsubheading Inputs @var{aObj} - The arduino @var{pin1} - The first pin of the controller @var{pin2} - The second pin of the controller @var{pin3} - The third pin of the controller @var{pin4} - The fourth pin of the controller @var{pin5} - The fifth pin of the controller @subsubheading Outputs @var{s} - a simplestepper object @subsubheading Example @example @code { a = arduino() # create stepper object s = addon(a, "simplestepper/simplestepper", "d2", "d3", "d4", "d5") # start rotating left s.rotate(-1); } @end example @xseealso{addon} @end deftypefn @deftypefn {} {} move(@var{sObj}, @var{steps}) Move the motor the specified number of steps using the configured Speed. @subsubheading Inputs @var{sObj} - the stepper object @var{steps} - the number of steps to move. steps less than 0 will be moving left. @subsubheading Outputs None @xseealso{rotate} @end deftypefn @deftypefn {} {} rotate(@var{sObj}, @var{dir}) Start steppermotor moving in the specified direction using the configured Speed. @subsubheading Inputs @var{sObj} - the stepper object @var{dir} - Direction to move. -1 = left, 0 = stop, 1 = right. @subsubheading Outputs None @xseealso{move} @end deftypefn @deftypefn {} {} release(@var{sObj}) Release this stepper motor @subsubheading Inputs @var{sObj} - the stepper object @subsubheading Outputs None @end deftypefn @c Arduino Addons arduinoioaddons.adafruit.dcmotorv2 @c ----------------------------------------- @subsection arduinoioaddons.adafruit.dcmotorv2 @cindex dcmotorv2 @deftypefn {} {} arduinoioaddons.adafruit.dcmotorv2 DC Motor class for dc motor control on the adafruit motor shield @xseealso{arduinoioaddons.adafruit.motorshieldv2} @end deftypefn @subsubheading Properties @var{Speed} - The speed value set for the motor @var{Parent} - The parent shield for object (read only) @var{MotorNumber} - The motor number (read only) values 1-4 @var{IsRunning} - boolean for if the motor is started (read only) @subheading Methods @deftypefn {} {@var{obj} =} dcmotorv2(@var{mObj}, @var{mnum}) @deftypefnx {} {@var{obj} =} dcmotorv2(@var{mObj}, @var{mnum}, @var{propertyname, propertyvalue} ....) Constructor to create dcmotor object @subsubheading Inputs @var{mObj} - the motor shield object @var{mnum} - The motor number (1 - 4) @var{propertyname, propertyvalue} - Optional property name/value pairs to pass to motor object. Current known properties are: @table @asis @item Speed Initial speed (default 0). Should be a value between -1 and 1. @end table @subsubheading Outputs @var{s} - a dcmotorv2 object @subsubheading Example @example @code { a = arduino() ms = addon(a, "adafruit/motorshieldv2") mtr = dcmotor(ms, 1) } @end example @end deftypefn @deftypefn {} {} start(@var{dcObj}) Start the motor moving in previously set speed/direction @subsubheading Inputs @var{dcObj} - the dcmotor object @subsubheading Outputs None @xseealso{adafruit.motorshieldv2} @end deftypefn @deftypefn {} {} stop(@var{dcObj}) Stop the motor moving @subsubheading Inputs @var{dcObj} - the dcmotor object @subsubheading Outputs None @xseealso{adafruit.motorshieldv2} @end deftypefn @c Arduino Addons arduinoioaddons.adafruit.motorshieldv2 @c ----------------------------------------- @subsection arduinoioaddons.adafruit.motorshieldv2 @cindex motorshieldv2 @deftypefn {} {} arduinoioaddons.adafruit.motorshieldv2 Adafruit motor shield addon @xseealso{addon} @end deftypefn @subsubheading Properties @var{Parent} - the parent arduino object. @var{Pins} - the pins allocated the addon. @var{I2CAddress} - the i2c address used for accessing this shield. @var{PWMFrequency} - the set PWM frequency for this shield. @subheading Methods @deftypefn {} {@var{obj} =} motorshieldv2(@var{arObj}) @deftypefnx {} {@var{obj} =} motorshieldv2(@var{arObj}, @var{propertyname, propertyvalue} ....) Constructor to create motorshieldv2 addon object @subsubheading Inputs @var{arObj} - the arduino parent object @var{propertyname, propertyvalue} - optional property name, value pairs. Current known properties are: @table @asis @item address I2C address of the motor shield (default 0x60) @item pwmfrequency PWM Frequency to set on shield (default 1600) @end table @subsubheading Outputs @var{obj} - created motorshieldv2 object @subsubheading Example @example @code { a = arduino() mtr = addon(a, "adafruit/motorshieldv2") } @end example @end deftypefn @deftypefn {} {@var{s} =} servo(@var{mObj}, @var{mtrnum}) @deftypefnx {} {@var{s} =} servo(@var{mObj}, @var{mtrnum}, @var{propertyname}, @var{propertyvalue} ...) Create a servo object @subsubheading Inputs @var{mObj} - the motor shield object @var{mtrnum} - The servo motor number, where 1 is servo on pin "d10" and 2 is a servo on pin "d9" @var{propertyname}, @var{propertyvalue} - Optional property name/value pairs to pass to servo object. Properties are the same as the base servo object. @subsubheading Outputs @var{s} - a servo object @subsubheading Example @example @code { a = arduino() ms = addon(a, "adafruit/motorshieldv2") # get servo 1 (servo on pin D10) s = ms.servo(1) } @end example The function if the equivalent of calling the arduino.servo with the D9 or D10 pin has the input pin. @xseealso{servo} @end deftypefn @deftypefn {} {@var{s} =} stepper(@var{mObj}, @var{mtrnum}, @var{stepsperrev}) @deftypefnx {} {@var{s} =} stepper(@var{mObj}, @var{mtrnum}, @var{stepsperrev}, @var{propertyname}, @var{propertyvalue} ...) Create a stepper motor object @subsubheading Inputs @var{mObj} - the motor shield object @var{mtrnum} - The stepper motor number (1 or 2) @var{stepsperrev} - Number of steps per revolution. @var{propertyname}, @var{propertyvalue} - Optional property name/value pairs to pass to stepper object. @subsubheading Outputs @var{s} - a stepper object @end deftypefn @deftypefn {} {@var{s} =} dcmotor(@var{mObj}, @var{mtrnum}) @deftypefnx {} {@var{s} =} dcmotor(@var{mObj}, @var{mtrnum}, @var{propertyname}, @var{propertyvalue} ...) Create a dcmotor motor object @subsubheading Inputs @var{mObj} - the motor shield object @var{mtrnum} - The motor number (1 - 4) @var{propertyname}, @var{propertyvalue} - Optional property name/value pairs to pass to motor object. @subsubheading Outputs @var{s} - a dcmotorv2 object @end deftypefn @c Arduino Addons arduinoioaddons.adafruit.stepper @c ----------------------------------------- @subsection arduinoioaddons.adafruit.stepper @cindex stepper @deftypefn {} {} arduinoioaddons.adafruit.stepper Stepper class for stepper control on the adafruit motor shield @xseealso{arduinoioaddons.adafruit.motorshieldv2} @end deftypefn @subsubheading Properties @table @asis @item @var{RPM} The rpm value set for the stepper motor @item StepType the StepType for the stepper (string) which can be "single", "double", "interleave" or "microstep" @item StepsPerRevolution the StepsPerRevoluion for the stepper (read only) @item MotorNumber the motor number for the stepper (read only) value will be 1 or 2. @item Parent the parent shield of this stepper (read only) @end table @subheading Methods @deftypefn {} {@var{obj} =} stepper(@var{mObj}, @var{mnum}, @var{stepsperrev}) @deftypefnx {} {@var{obj} =} stepper(@var{mObj}, @var{mnum}, @var{stepsperrev}, @var{propertyname, propertyvalue} ....) Constructor to create dcmotor object @subsubheading Inputs @var{mObj} - the motor shield object @var{mnum} - The motor number (1 or 2) @var{stepsperrev} - Number of steps per revolution. @var{propertyname, propertyvalue} - Optional property name/value pairs to pass to motor object. Current known properties are: @table @asis @item RPM the RPM for the stepper (revolutions per minute) @item StepType the StepType for the stepper (string) which can be "single", "double", "interleave" or "microstep" @end table @subsubheading Outputs @var{s} - a stepper object @subsubheading Example @example @code { a = arduino() ms = addon(a, "adafruit/motorshieldv2") mtr = stepper(ms, 1, 200) } @end example @end deftypefn @deftypefn {} {} move(@var{sObj}, @var{steps}) Move the motor moving in the specified steps using the configured RPM. @subsubheading Inputs @var{sObj} - the stepper object @subsubheading Outputs None @xseealso{adafruit.motorshieldv2} @end deftypefn @deftypefn {} {} release(@var{sObj}) Release this motor @subsubheading Inputs @var{sObj} - the stepper object @subsubheading Outputs None @xseealso{adafruit.motorshieldv2} @end deftypefn @c --------------------------------------------------- @node Arduino Sensors @section Arduino Sensors @cindex Arduino Sensors @c Arduino Sensors arduinosensor.DS1307 @c ----------------------------------------- @subsection arduinosensor.DS1307 @cindex DS1307 @deftypefn {} {} arduinosensor.DS1307 DS1307 realtime clock sensor @end deftypefn @subheading Methods @deftypefn {} {@var{obj} =} DS1307(@var{arObj}) @deftypefnx {} {@var{obj} =} DS1307(@var{arObj}, @var{propertyname, propertyvalue} ....) Constructor to create DS1307 sensor @subsubheading Inputs @var{arObj} - the arduino parent object @var{propertyname, propertyvalue} - optional property name, value pairs. Current known properties are: Current properties are: @table @asis @item i2caddress I2C address of the DS1307 (default 0x68) @end table @subsubheading Outputs @var{obj} - created DS1307 object @subsubheading Example @example @code { a = arduino() rtc = arduinosensor.DS1307(a) } @end example @end deftypefn @deftypefn {} {@var{date} =} clock(@var{dsObj}) @deftypefnx {} {} clock(@var{dsObj}, @var{date}) Get/set the DS1307 clock @subsubheading Inputs @var{dsObj} - the ds1307 object @var{date} - a date vector in same format as datevec and clock @subsubheading Outputs @var{date} - a date vector in same format as datevec and clock @subsubheading Example @example @code { a = arduino() rtc = arduinosensor.DS1307(a) # get and display rtc time as a date string datestr(rtc.clock) } @end example @xseealso{datevec} @end deftypefn @deftypefn {} {@var{ctrl} =} control(@var{dsObj}) @deftypefnx {} {} control(@var{dsObj}, @var{ctrl}) Get/set the DS1307 clock @subsubheading Inputs @var{dsObj} - the ds1307 object @var{ctrl} - a structure containing the control bit fields. @subsubheading Outputs @var{ctrl} - a structure containing the control bit fields. Control structure fields are: Current properties are: @table @asis @item out Out bit in the control register @item sqwe Square wave enable bit in control register @item rs The combined RS0, RS1 value @end table @end deftypefn @deftypefn {} {@var{YN} =} isstarted(@var{dsObj}) Get whether the RTC clock is currently counting time @subsubheading Inputs @var{dsObj} - the ds1307 object @subsubheading Outputs @var{YN} - returns true if the RTC is counting @xseealso{start, stop} @end deftypefn @deftypefn {} {} start(@var{dsObj}) Start the RTC counting @subsubheading Inputs @var{dsObj} - the ds1307 object @subsubheading Outputs None @xseealso{datevec} @end deftypefn @deftypefn {} {} stop(@var{dsObj}) Stop the RTC counting @subsubheading Inputs @var{dsObj} - the ds1307 object @subsubheading Outputs None @xseealso{datevec} @end deftypefn @c Arduino Sensors arduinosensor.GUVAS12SD @c ----------------------------------------- @subsection arduinosensor.GUVAS12SD @cindex GUVAS12SD @deftypefn {} {} arduinosensor.GUVAS12SD A thin wrapper for the GUVAS12SD analog UV-B sensor @end deftypefn @subheading Methods @deftypefn {} {@var{obj} =} GUVAS12SD(@var{arObj}, @var{pin}) Constructor to create GUVAS12SD sensor @subsubheading Inputs @var{arObj} - the arduino parent object @var{pin} - the analog pin that the sensor is connected to @subsubheading Outputs @var{obj} - created GUVAS12SD object @subsubheading Example @example @code { a = arduino() # create sensor attached to pin a0. sensor = arduinosensor.GUVAS12SD(a, "a0") } @end example @end deftypefn @deftypefn {} {@var{V} =} read(@var{dsObj}) Read the voltage of the sensor @subsubheading Inputs @var{dsObj} - the GUVAS12SD object @subsubheading Outputs @var{V} - read voltage - effectively equivalent to readAnalogPin(arObj, pin). @subsubheading Example @example @code { a = arduino() s = arduinosensor.GUVAS12SD(a) # voltage volts = s.read } @end example @xseealso{arduinosensor.GUVAS12SD} @end deftypefn @deftypefn {} {@var{Idx} =} readIndex(@var{dsObj}) Read the UV index @subsubheading Inputs @var{dsObj} - the GUVAS12SD object @subsubheading Outputs @var{Idx} - the sensor reading as a UV index reading @end deftypefn @deftypefn {} {@var{uA} =} readuA(@var{dsObj}) Read the uA of the sensor @subsubheading Inputs @var{dsObj} - the GUVAS12SD object @subsubheading Outputs @var{uA} - the sensor reading as a uAmp value @end deftypefn @c Arduino Sensors arduinosensor.MPC3002 @c ----------------------------------------- @subsection arduinosensor.MPC3002 @cindex MPC3002 @deftypefn {} {} arduinosensor.MPC3002 MCP3002 ADC sensor @end deftypefn @subheading Methods @deftypefn {} {@var{obj} =} MPC3002(@var{arObj}, @var{selectPin}) @deftypefnx {} {@var{obj} =} MPC3002(@var{arObj}, @var{selectPin}, @var{propertyname, propertyvalue} ....) Constructor to create MPC3002 sensor @subsubheading Inputs @var{arObj} - the arduino parent object @var{selectPin} - the SPI cs select pin @var{propertyname, propertyvalue} - optional property name, value pairs. Current properties are: @table @asis @item referenceVoltage Reference voltage for scaling the ADC inputs (default 5.0) @end table @subsubheading Outputs @var{obj} - created MCP3002 object @subsubheading Example @example @code { a = arduino() sensor = arduinosensor.MPC3002(a, "d10") } @end example @end deftypefn @deftypefn {} {@var{voltage} =} readVoltage(@var{dsObj}, @var{chan}) Read the voltage from a channel @subsubheading Inputs @var{dsObj} - the MPC3002 object @var{chan} - the channel to read (0 or 1) @subsubheading Outputs @var{voltage} - read voltage. @subsubheading Example @example @code { a = arduino() s = arduinosensor.MPC3002(a, "d10") volts = readVoltage(s, 0) } @end example @xseealso{arduinosensor.MPC3002} @end deftypefn @c Arduino Sensors arduinosensor.SI7021 @c ----------------------------------------- @subsection arduinosensor.SI7021 @cindex SI7021 @deftypefn {} {} arduinosensor.SI7021 SI7021 temperature and humidity sensor @end deftypefn @subheading Methods @deftypefn {} {@var{obj} =} SI7021(@var{arObj}) @deftypefnx {} {@var{obj} =} SI7021(@var{arObj}, @var{propertyname, propertyvalue} ....) Constructor to create SI7021 sensor @subsubheading Inputs @var{arObj} - the arduino parent object @var{propertyname, propertyvalue} - optional property name, value pairs. Current known properties are: Current properties are: @table @asis @item i2caddress I2C address of the SI7021 (default 0x40) @end table @subsubheading Outputs @var{obj} - created SI7020 object @subsubheading Example @example @code { a = arduino() sensor = arduinosensor.SI7021(a) } @end example @end deftypefn @deftypefn {} {@var{C} =} temperature(@var{dsObj}) Read the temperature @subsubheading Inputs @var{dsObj} - the si7021 object @subsubheading Outputs @var{C} - read temperature in deg C. @subsubheading Example @example @code { a = arduino() s = arduinosensor.SI7021(a) # get temp temp = s.temperature } @end example @xseealso{arduinosensor.SI7021} @end deftypefn @deftypefn {} {@var{relH} =} humidity(@var{dsObj}) Read the relative humidity @subsubheading Inputs @var{dsObj} - the si7021 object @subsubheading Outputs @var{relH} - relative humidity as a percentage (0 - 100.0) @end deftypefn @deftypefn {} {@var{relH} =} info(@var{dsObj}) Read the sensor info @subsubheading Inputs @var{dsObj} - the si7021 object @subsubheading Outputs @var{inf} - structure containing the sensor information. Structure fields are: @table @asis @item version Chip firmware version @item id sensor id1,id2 value @item type String for detected chip type @end table @end deftypefn @c --------------------------------------------------- @node Arduino I/O package @section Arduino I/O package @cindex Arduino I/O package @c Arduino I/O package arduinoio.AddonBase @c ----------------------------------------- @subsection arduinoio.AddonBase @cindex AddonBase @deftypefn {} {} arduinoio.AddonBase Base class used for arduino library sensors @xseealso{arduinoio.LibraryBase} @end deftypefn @subheading Properties Base properties are expected to be inherited and overwritten in inherited classes. and are constant in order to query through the metaobject mechanism. @var{Parent} - parent librarybase object @subheading Methods @deftypefn {} {@var{ab} =} AddonBase () Constructor of base class @subsubheading Outputs The return value @var{ab} is an object of the arduinio.AddonBase class. @xseealso{arduino, addon} @end deftypefn @deftypefn {} {} disp () Display the addon in a verbose way. @end deftypefn @c Arduino I/O package arduinoio.FilePath @c ----------------------------------------- @subsection arduinoio.FilePath @cindex FilePath @deftypefn {} {@var{retval} =} arduinoio.FilePath (@var{fullpathname}) Get the directory component of a pathname. @subsubheading Inputs @var{fullpathname} filepath to get directory component of. @subsubheading Outputs @var{retval} the directory part of the filename. @end deftypefn @c Arduino I/O package arduinoio.LibFiles @c ----------------------------------------- @subsection arduinoio.LibFiles @cindex LibFiles @deftypefn {} {@var{filelist} =} arduinoio.LibFiles () Get the list of files used for the building arduino library @subsubheading Outputs @var{filelist} - string cell array of files for the arduino project @end deftypefn @c Arduino I/O package arduinoio.LibraryBase @c ----------------------------------------- @subsection arduinoio.LibraryBase @cindex LibraryBase @deftypefn {} {} arduinoio.LibraryBase Base class used for arduino library plugins @xseealso{arduino, listArduinoLibraries, addon} @end deftypefn @subheading Properties Base properties are expected to be inherited and overwritten in inherited classes and are constant in order to query through the metaobject mechanism. @var{LibraryName} - name of the addon library @var{DependentLibraries} - array of dependent library names that must be included when installing this plugin. @var{CppHeaderFile} - name (if any) of header file that will be included into the arduino project when adding this library. @var{CppSourceFile} - name (if any) of source file that will be included into the arduino project when adding this library. @var{CppClassName} - name of the cpp class for the addon library. project when adding this library. @var{Pins} - pins allocated to the addon @var{Parent} - parent arduino object. @subheading Methods @deftypefn {} {@var{lb} =} LibraryBase () Constructor of base class The constructor is usually not called but called indirectly from the addon function. @subsubheading Outputs The return value @var{lb} is an object of the arduinio.LibraryBase class. @xseealso{arduino, listArduinoLibraries, addon} @end deftypefn @deftypefn {} {} disp () Display the addon in a verbose way. @end deftypefn @c Arduino I/O package arduinoio.getBoardConfig @c ----------------------------------------- @subsection arduinoio.getBoardConfig @cindex getBoardConfig @deftypefn {} {@var{retval} =} arduinoio.getBoardConfig (@var{boardname}) Return the configuration for a known arduino board type Function is used to get the expected pin/board configuration for a named board type which is used to verify and identify the functionality of the board. @subsubheading Inputs @var{boardname} - name of board to get configuration of ie: "uno" @subsubheading Outputs @var{retval} configuration struct. @end deftypefn @c --------------------------------------------------- @node Matlab Compatibility Classes @section Matlab Compatibility Classes @cindex Matlab Compatibility Classes @c Matlab Compatibility Classes matlabshared.addon.LibraryBase @c ----------------------------------------- @subsection matlabshared.addon.LibraryBase @cindex LibraryBase @deftypefn {} {} matlabshared.addon.LibraryBase Compatability class used for arduino library plugins using matlabshared.addons.LibraryBase @xseealso{arduinoio.LibraryBase, arduino, listArduinoLibraries, addon} @end deftypefn @subheading Properties Base properties are expected to be inherited and overwritten in inherited classes and are constant in order to query through the metaobject mechanism. @var{LibraryName} - name of the addon library @var{DependentLibraries} - array of dependent library names that must be included when installing this plugin. @var{CppHeaderFile} - name (if any) of header file that will be included into the arduino project when adding this library. @var{CppSourceFile} - name (if any) of source file that will be included into the arduino project when adding this library. @var{CppClassName} - name of the cpp class for the addon library. project when adding this library. @var{Pins} - pins allocated to the addon @var{Parent} - parent arduino object. @subheading Methods @deftypefn {} {@var{lb} =} LibraryBase () Constructor of base class The constructor is usually not called but called indirectly from the addon function. @subsubheading Outputs The return value @var{lb} is an object of the matlabshare.addons.LibraryBase class. @xseealso{arduino, listArduinoLibraries, addon} @end deftypefn @deftypefn {} {} disp () Display the addon in a verbose way. @end deftypefn @c --------------------------------------------------- @node Sensors @section Sensors @cindex Sensors @c Sensors bme280 @c ----------------------------------------- @subsection bme280 @cindex bme280 @deftypefn {} {} bme280 BME280 pressure, temperature and humidity sensor @end deftypefn @subheading Methods @deftypefn {} {@var{obj} =} bme280(@var{arObj}) @deftypefnx {} {@var{obj} =} bme280(@var{arObj}, @var{propertyname, propertyvalue} ....) Constructor to create BME280 sensor @subsubheading Inputs @var{arObj} - the arduino parent object @var{propertyname, propertyvalue} - optional property name, value pairs. Current known properties are: Current properties are: @table @asis @item I2CAddress I2C address of the sensor (default 0x40) @item Bus I2C bus - 0 or 1 (default 0) @end table @subsubheading Outputs @var{obj} - created object @subsubheading Example @example @code { a = arduino() sensor = bme280(a) } @end example @end deftypefn @deftypefn {} {[@var{C}, @var{timestamp}] =} readTemperature(@var{obj}) Read the temperature @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs @var{C} - read temperature in deg C. @var{timestamp} - timestamp when read @subsubheading Example @example @code { a = arduino() s = bme280(a) # get temp temp = s.readTemperature } @end example @xseealso{bme280} @end deftypefn @deftypefn {} {[@var{relH}, @var{timestamp}] =} readHumidity(@var{obj}) Read the relative humidity @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs @var{relH} - relative humidity as a percentage (0 - 100.0) @var{timestamp} - timestamp when read @end deftypefn @deftypefn {} {[@var{P}, @var{timestamp}] =} readPressure(@var{obj}) Read the pressure @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs @var{P} - pressure reading from sensor. @var{timestamp} - timestamp when read @end deftypefn @deftypefn {} {[@var{readings}, @var{overrun}] =} read(@var{obj}) @deftypefnx {} {[@var{P}, @var{H}, @var{C}, @var{timestamp}, @var{overrun}] =} read(@var{obj}) Read the sensor data @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs @var{P} - pressure reading from sensor. @var{H} - humidity reading from sensor. @var{C} - temperature reading from sensor. @var{timestamp} - timestamp when read @var{overrun} - overrun flag. @var{readings} - table structure with fields for Timestamp, Pressure, Temperature and Humidity. @end deftypefn @deftypefn {} {@var{inf} =} info(@var{obj}) Read the sensor info @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs @var{inf} - structure containing the sensor information. Structure fields are: @table @asis @item Version Chip firmware version @item SensorId sensor id value @item Type sensor type 'bme280' @item Status Status value read from sensor @end table @end deftypefn @deftypefn {} {} flush(@var{obj}) Flush sensor data @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs None @end deftypefn @deftypefn {} {} release(@var{obj}) Release the resources of the sensor @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs None @end deftypefn @c Sensors bno055 @c ----------------------------------------- @subsection bno055 @cindex bno055 @deftypefn {} {} bno055 BNO055 9 axis orientation sensor @end deftypefn @subheading Methods @deftypefn {} {@var{obj} =} bno055(@var{arObj}) @deftypefnx {} {@var{obj} =} bno055(@var{arObj}, @var{propertyname, propertyvalue} ....) Constructor to create BME280 sensor @subsubheading Inputs @var{arObj} - the arduino parent object @var{propertyname, propertyvalue} - optional property name, value pairs. Current known properties are: Current properties are: @table @asis @item I2CAddress I2C address of the sensor (default 0x40) @item Bus I2C bus - 0 or 1 (default 0) @item OperatingMode Operating mode 'ndof' or 'amg' @end table @subsubheading Outputs @var{obj} - created object @subsubheading Example @example @code { a = arduino() sensor = bno055(a) } @end example @end deftypefn @deftypefn {} {[@var{C}, @var{timestamp}] =} readTemperature(@var{obj}) Read the temperature @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs @var{C} - read temperature in deg C. @var{timestamp} - timestamp when read @subsubheading Example @example @code { a = arduino() s = bno055(a) # get temp temp = s.readTemperature } @end example @xseealso{bno055} @end deftypefn @deftypefn {} {[@var{readVal}, @var{timestamp}] =} readAcceleration(@var{obj}) Read the acceleration rate @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs @var{readVal} - the 3 acceleration values @var{timestamp} - timestamp when read @end deftypefn @deftypefn {} {[@var{readVal}, @var{timestamp}] =} readAngularVelocity(@var{obj}) Read the angular velocity @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs @var{readVal} - the 3 angular velocity values @var{timestamp} - timestamp when read @end deftypefn @deftypefn {} {[@var{readVal}, @var{timestamp}] =} readMagneticField(@var{obj}) Read the magnetic field components @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs @var{readVal} - the 3 magnetic field values @var{timestamp} - timestamp when read @end deftypefn @deftypefn {} {[@var{readVal}, @var{timestamp}] =} readOrientation(@var{obj}) Read the oriientation components @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs @var{readVal} - the 3 orientation values @var{timestamp} - timestamp when read @end deftypefn @deftypefn {} {[@var{readings}, @var{overrun}] =} read(@var{obj}) @deftypefnx {} {[@var{accel}, @var{gyro}, @var{mag}, @var{timestamp}, @var{overrun}] =} read(@var{obj}) @deftypefnx {} {[@var{accel}, @var{gyro}, @var{mag}, @var{orientation}, @var{timestamp}, @var{overrun}] =} read(@var{obj}) Read the sensor data @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs @var{accel} - acceleration reading from sensor. @var{gyro} - angular acceleration reading from sensor. @var{mag} - magnetic field reading from sensor. @var{orientation} - orientation reading from sensor. @var{timestamp} - timestamp when read @var{overrun} - overrun flag. @var{readings} - table structure with fields for Timestamp, Acceleration, AngularVelocity, MagneticField, Orientation. @end deftypefn @deftypefn {} {@var{inf} =} readCalibrationStatus(@var{obj}) Read the sensor calibration status @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs @var{status} - structure containing the calibration information. Structure fields are: @table @asis @item System System calibrarion @item Accelerometer Accelerometer calibration status @item Gyroscope Gyroscope calibration status @item Magnetometer Magnetometer calibration status @end table Values for each will be either 'uncalibrated', 'partial' or 'full'. @end deftypefn @deftypefn {} {@var{inf} =} info(@var{obj}) Read the sensor info @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs @var{inf} - structure containing the sensor information. Structure fields are: @table @asis @item Version Software firmware version @item SensorId sensor id value @item Type sensor type 'bno055' @end table @end deftypefn @deftypefn {} {} flush(@var{obj}) Flush sensor data @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs None @end deftypefn @deftypefn {} {} release(@var{obj}) Release the resources of the sensor @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs None @end deftypefn @c Sensors lis3dh @c ----------------------------------------- @subsection lis3dh @cindex lis3dh @deftypefn {} {} lis3dh LIS3DH 3 degrees sensor @end deftypefn @subheading Methods @deftypefn {} {@var{obj} =} lis3dh(@var{arObj}) @deftypefnx {} {@var{obj} =} lis3dh(@var{arObj}, @var{propertyname, propertyvalue} ....) Constructor to create LIS3DH sensor @subsubheading Inputs @var{arObj} - the arduino parent object @var{propertyname, propertyvalue} - optional property name, value pairs. Current known properties are: Current properties are: @table @asis @item I2CAddress I2C address of the sensor (default 0x40) @item Bus I2C bus - 0 or 1 (default 0) @end table @subsubheading Outputs @var{obj} - created object @subsubheading Example @example @code { a = arduino() sensor = lis3dh(a) } @end example @end deftypefn @deftypefn {} {[@var{readVal}, @var{timestamp}] =} readAcceleration(@var{obj}) Read the acceleration rate @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs @var{readVal} - the 3 acceleration values @var{timestamp} - timestamp when read @end deftypefn @deftypefn {} {[@var{readings}, @var{overrun}] =} read(@var{obj}) @deftypefnx {} {[@var{accel}, @var{timestamp}, @var{overrun}] =} read(@var{obj}) Read the sensor data @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs @var{accel} - acceleration reading from sensor. @var{timestamp} - timestamp when read @var{overrun} - overrun flag. @var{readings} - table structure with fields for Timestamp, Acceleration. @end deftypefn @deftypefn {} {@var{inf} =} info(@var{obj}) Read the sensor info @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs @var{inf} - structure containing the sensor information. Structure fields are: @table @asis @item SensorId sensor id value @item Type sensor type 'lis3dh' @item Status sensor status value @end table @end deftypefn @deftypefn {} {} flush(@var{obj}) Flush sensor data @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs None @end deftypefn @deftypefn {} {} release(@var{obj}) Release the resources of the sensor @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs None @end deftypefn @c Sensors lps22hb @c ----------------------------------------- @subsection lps22hb @cindex lps22hb @deftypefn {} {} lps22hb LPS22HB absolute pressure and temperature sensor @end deftypefn @subheading Methods @deftypefn {} {@var{obj} =} lps22hb(@var{arObj}) @deftypefnx {} {@var{obj} =} lps22hb(@var{arObj}, @var{propertyname, propertyvalue} ....) Constructor to create LPS22HB sensor @subsubheading Inputs @var{arObj} - the arduino parent object @var{propertyname, propertyvalue} - optional property name, value pairs. Current known properties are: Current properties are: @table @asis @item I2CAddress I2C address of the sensor (default 0x5C) @item Bus I2C bus - 0 or 1 (default 0) @end table @subsubheading Outputs @var{obj} - created object @subsubheading Example @example @code { a = arduino() sensor = lps22hb(a) } @end example @end deftypefn @deftypefn {} {[@var{C}, @var{timestamp}] =} readTemperature(@var{obj}) Read the temperature @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs @var{C} - read temperature in deg C. @var{timestamp} - timestamp when read @subsubheading Example @example @code { a = arduino() s = lps22hb(a) # get temp temp = s.readTemperature } @end example @xseealso{lps22hb} @end deftypefn @deftypefn {} {[@var{P}, @var{timestamp}] =} readPressure(@var{obj}) Read the pressure @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs @var{P} - pressure reading from sensor. @var{timestamp} - timestamp when read @end deftypefn @deftypefn {} {[@var{readings}, @var{overrun}] =} read(@var{obj}) @deftypefnx {} {[@var{P}, @var{C}, @var{timestamp}, @var{overrun}] =} read(@var{obj}) Read the sensor data @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs @var{P} - pressure reading from sensor. @var{C} - temperature reading from sensor. @var{timestamp} - timestamp when read @var{overrun} - overrun flag. @var{readings} - table structure with fields for Timestamp, Pressure, Temperature and Humidity. @end deftypefn @deftypefn {} {@var{inf} =} info(@var{obj}) Read the sensor info @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs @var{inf} - structure containing the sensor information. Structure fields are: @table @asis @item Version Chip firmware version @item SensorId sensor id value @item Type sensor type 'lps22hb' @item Status Status value read from sensor @end table @end deftypefn @deftypefn {} {} flush(@var{obj}) Flush sensor data @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs None @end deftypefn @deftypefn {} {} release(@var{obj}) Release the resources of the sensor @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs None @end deftypefn @c Sensors lsm6dso @c ----------------------------------------- @subsection lsm6dso @cindex lsm6dso @deftypefn {} {} lsm6dso LSM6DSO 6 degrees sensor @end deftypefn @subheading Methods @deftypefn {} {@var{obj} =} lsm6dso(@var{arObj}) @deftypefnx {} {@var{obj} =} lsm6dso(@var{arObj}, @var{propertyname, propertyvalue} ....) Constructor to create LSM6DSO sensor @subsubheading Inputs @var{arObj} - the arduino parent object @var{propertyname, propertyvalue} - optional property name, value pairs. Current known properties are: Current properties are: @table @asis @item I2CAddress I2C address of the sensor (default 0x40) @item Bus I2C bus - 0 or 1 (default 0) @end table @subsubheading Outputs @var{obj} - created object @subsubheading Example @example @code { a = arduino() sensor = lsm6dso(a) } @end example @end deftypefn @deftypefn {} {[@var{C}, @var{timestamp}] =} readTemperature(@var{obj}) Read the temperature @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs @var{C} - read temperature in deg C. @var{timestamp} - timestamp when read @subsubheading Example @example @code { a = arduino() s = lsm6dso(a) # get temp temp = s.readTemperature } @end example @xseealso{lsm6dso} @end deftypefn @deftypefn {} {[@var{readVal}, @var{timestamp}] =} readAcceleration(@var{obj}) Read the acceleration rate @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs @var{readVal} - the 3 acceleration values @var{timestamp} - timestamp when read @end deftypefn @deftypefn {} {[@var{readVal}, @var{timestamp}] =} readAngularVelocity(@var{obj}) Read the angular velocity @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs @var{readVal} - the 3 angular velocity values @var{timestamp} - timestamp when read @end deftypefn @deftypefn {} {[@var{readings}, @var{overrun}] =} read(@var{obj}) @deftypefnx {} {[@var{accel}, @var{gyro}, @var{mag}, @var{timestamp}, @var{overrun}] =} read(@var{obj}) Read the sensor data @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs @var{accel} - acceleration reading from sensor. @var{gyro} - angular acceleration reading from sensor. @var{timestamp} - timestamp when read @var{overrun} - overrun flag. @var{readings} - table structure with fields for Timestamp, Acceleration, AngularVelocity. @end deftypefn @deftypefn {} {@var{inf} =} info(@var{obj}) Read the sensor info @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs @var{inf} - structure containing the sensor information. Structure fields are: @table @asis @item SensorId sensor id value @item Type sensor type 'lsm6dso' @end table @end deftypefn @deftypefn {} {} flush(@var{obj}) Flush sensor data @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs None @end deftypefn @deftypefn {} {} release(@var{obj}) Release the resources of the sensor @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs None @end deftypefn @c Sensors mpu6050 @c ----------------------------------------- @subsection mpu6050 @cindex mpu6050 @deftypefn {} {} mpu6050 MPU-6050 6 degrees sensor @end deftypefn @subheading Methods @deftypefn {} {@var{obj} =} mpu6050(@var{arObj}) @deftypefnx {} {@var{obj} =} mpu6050(@var{arObj}, @var{propertyname, propertyvalue} ....) Constructor to create MPU-6050 sensor @subsubheading Inputs @var{arObj} - the arduino parent object @var{propertyname, propertyvalue} - optional property name, value pairs. Current known properties are: Current properties are: @table @asis @item I2CAddress I2C address of the sensor (default 0x40) @item Bus I2C bus - 0 or 1 (default 0) @end table @subsubheading Outputs @var{obj} - created object @subsubheading Example @example @code { a = arduino() sensor = mpu6050(a) } @end example @end deftypefn @deftypefn {} {[@var{C}, @var{timestamp}] =} readTemperature(@var{obj}) Read the temperature @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs @var{C} - read temperature in deg C. @var{timestamp} - timestamp when read @subsubheading Example @example @code { a = arduino() s = mpu6050(a) # get temp temp = s.readTemperature } @end example @xseealso{mpu6050} @end deftypefn @deftypefn {} {[@var{readVal}, @var{timestamp}] =} readAcceleration(@var{obj}) Read the acceleration rate @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs @var{readVal} - the 3 acceleration values @var{timestamp} - timestamp when read @end deftypefn @deftypefn {} {[@var{readVal}, @var{timestamp}] =} readAngularVelocity(@var{obj}) Read the angular velocity @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs @var{readVal} - the 3 angular velocity values @var{timestamp} - timestamp when read @end deftypefn @deftypefn {} {[@var{readings}, @var{overrun}] =} read(@var{obj}) @deftypefnx {} {[@var{accel}, @var{gyro}, @var{mag}, @var{timestamp}, @var{overrun}] =} read(@var{obj}) Read the sensor data @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs @var{accel} - acceleration reading from sensor. @var{gyro} - angular acceleration reading from sensor. @var{timestamp} - timestamp when read @var{overrun} - overrun flag. @var{readings} - table structure with fields for Timestamp, Acceleration, AngularVelocity. @end deftypefn @deftypefn {} {@var{inf} =} info(@var{obj}) Read the sensor info @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs @var{inf} - structure containing the sensor information. Structure fields are: @table @asis @item SensorId sensor id value @item Type sensor type 'mpu6050' @end table @end deftypefn @deftypefn {} {} flush(@var{obj}) Flush sensor data @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs None @end deftypefn @deftypefn {} {} release(@var{obj}) Release the resources of the sensor @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs None @end deftypefn @c Sensors si7021 @c ----------------------------------------- @subsection si7021 @cindex si7021 @deftypefn {} {} si7021 SI7021 temperature and humidity sensor @end deftypefn @subheading Methods @deftypefn {} {@var{obj} =} si7021(@var{arObj}) @deftypefnx {} {@var{obj} =} si7021(@var{arObj}, @var{propertyname, propertyvalue} ....) Constructor to create si7021 sensor @subsubheading Inputs @var{arObj} - the arduino parent object @var{propertyname, propertyvalue} - optional property name, value pairs. Current known properties are: Current properties are: @table @asis @item I2Caddress I2C address of the si7021 (default 0x40) @item Bus I2C bus (default 0) @end table @subsubheading Outputs @var{obj} - created SI7020 object @subsubheading Example @example @code { a = arduino() sensor = si7021(a) } @end example @end deftypefn @deftypefn {} {[@var{C}, @var{timestamp}] =} readTemperature(@var{obj}) Read the temperature @subsubheading Inputs @var{obj} - the si7021 object @subsubheading Outputs @var{C} - read temperature in deg C. @var{timestamp} - timestamp when read @subsubheading Example @example @code { a = arduino() s = si7021(a) # get temp temp = s.readTemperature() } @end example @xseealso{si7021} @end deftypefn @deftypefn {} {[@var{relH}, @var{timestamp}] =} readHumidity(@var{obj}) Read the relative humidity @subsubheading Inputs @var{obj} - the si7021 object @subsubheading Outputs @var{relH} - relative humidity as a percentage (0 - 100.0) @var{timestamp} - timestamp when read @end deftypefn @deftypefn {} {[@var{readings}, @var{overrun}] =} read(@var{obj}) @deftypefnx {} {[@var{H}, @var{C}, @var{timestamp}, @var{overrun}] =} read(@var{obj}) Read the sensor data @subsubheading Inputs @var{obj} - the si2071 sensor object @subsubheading Outputs @var{H} - humidity reading from sensor. @var{C} - temperature reading from sensor. @var{timestamp} - timestamp when read @var{overrun} - overrun flag. @var{readings} - table structure with fields for Timestamp, Temperature and Humidity. @end deftypefn @deftypefn {} {@var{relH} =} info(@var{dsObj}) Read the sensor info @subsubheading Inputs @var{dsObj} - the si7021 object @subsubheading Outputs @var{inf} - structure containing the sensor information. Structure fields are: @table @asis @item Version Chip firmware version @item SensorDd sensor id value @item Type String for detected chip type @end table @end deftypefn @deftypefn {} {} flush(@var{obj}) Flush sensor data @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs None @end deftypefn @deftypefn {} {} release(@var{obj}) Release the resources of the sensor @subsubheading Inputs @var{obj} - the sensor object @subsubheading Outputs None @end deftypefn @c --------------------------------------------------- @node Test Functions @section Test Functions @cindex Test Functions @c Test Functions arduino_bistsetup @c ----------------------------------------- @subsection arduino_bistsetup @cindex arduino_bistsetup @deftypefn {} {@var{retval} =} arduino_bistsetup () @deftypefnx {} {@var{retval} =} arduino_bistsetup (@var{propertyname}, @var{propertyvalue}) Install on an arduino the required core libraries to run the BIST tests As part of the setup, the arduino IDE will be opened to allow programming the arduino board. @subsubheading Inputs @var{propertyname}, @var{propertyvalue} - A sequence of property name/value pairs can be given to set defaults while programming. Currently the following properties can be set: @table @asis @item arduinobinary The value should be the name/path of the arduino IDE binary for programming. If not specified, the function will attempt to find the binary itself. @item debug Set the debug flag when checking the arduino @end table @subsubheading Outputs @var{retval} - return 1 if everything installed ok @xseealso{arduino, arduinosetup} @end deftypefn arduino-0.12.2/doc/gpl.texi0000644000000000000000000010433014777724260012426 0ustar00@node Copying @appendix GNU General Public License @cindex warranty @cindex copyright @center Version 3, 29 June 2007 @display Copyright @copyright{} 2007 Free Software Foundation, Inc. @url{http://fsf.org/} Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @end display @heading 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. @heading TERMS AND CONDITIONS @enumerate 0 @item 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. @item 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. @item 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. @item 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. @item 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. @item 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: @enumerate a @item The work must carry prominent notices stating that you modified it, and giving a relevant date. @item 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''. @item 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. @item 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. @end enumerate 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. @item 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: @enumerate a @item 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. @item 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. @item 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. @item 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. @item 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. @end enumerate 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. @item 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: @enumerate a @item Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or @item 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 @item 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 @item Limiting the use for publicity purposes of names of licensors or authors of the material; or @item Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or @item 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. @end enumerate 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. @item 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. @item 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. @item 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. @item 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. @item 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. @item 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. @item 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. @item 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. @item 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. @item 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 enumerate @heading END OF TERMS AND CONDITIONS @heading 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. @smallexample @var{one line to give the program's name and a brief idea of what it does.} Copyright (C) @var{year} @var{name of author} 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 @url{http://www.gnu.org/licenses/}. @end smallexample 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: @smallexample @var{program} Copyright (C) @var{year} @var{name of author} This program comes with ABSOLUTELY NO WARRANTY; for details type @samp{show w}. This is free software, and you are welcome to redistribute it under certain conditions; type @samp{show c} for details. @end smallexample The hypothetical commands @samp{show w} and @samp{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 @url{http://www.gnu.org/licenses/}. 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 @url{http://www.gnu.org/philosophy/why-not-lgpl.html}. arduino-0.12.2/doc/macros.texi0000644000000000000000000000624114777724260013132 0ustar00@c Copyright (C) 2012-2019 John W. Eaton @c @c This file is part of Octave. @c @c Octave is free software: you can redistribute it and/or modify it @c under the terms of the GNU General Public License as published by @c the Free Software Foundation, either version 3 of the License, or @c (at your option) any later version. @c @c Octave is distributed in the hope that it will be useful, but @c WITHOUT ANY WARRANTY; without even the implied warranty of @c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @c GNU General Public License for more details. @c @c You should have received a copy of the GNU General Public License @c along with Octave; see the file COPYING. If not, see @c . @c The following macro marks words that aspell should ignore during @c spellchecking. Within Texinfo it has no effect as it merely replaces @c the macro call with the argument itself. @macro nospell {arg} \arg\ @end macro @c The following macro works around the Info/plain text expansion of @code{XXX} @c which is `XXX'. This looks particularly bad when the macro body is @c single or double-quoted text, such as a property value `"position"' @ifinfo @macro qcode{arg} \arg\ @end macro @end ifinfo @ifnotinfo @macro qcode{arg} @code{\arg\} @end macro @end ifnotinfo @c The following macro is used for the on-line help system, but we don't @c want lots of `See also: foo, bar, and baz' strings cluttering the @c printed manual (that information should be in the supporting text for @c each group of functions and variables). @c @c Implementation Note: @c For TeX, @vskip produces a nice separation. @c For Texinfo, '@sp 1' should work, but in practice produces ugly results @c for HTML. We use a simple blank line to produce the correct @c behavior. @c @c We use @xseealso now because Texinfo introduced its own @seealso @c command. But instead of modifying all source files, we'll have the @c munge-texi script convert @seealso to @xseealso. @macro xseealso {args} @iftex @vskip 2pt @end iftex @ifnottex @end ifnottex @ifnotinfo @noindent @strong{See also:} \args\. @end ifnotinfo @ifinfo @noindent See also: \args\. @end ifinfo @end macro @c The following macro works around a situation where the Info/plain text @c expansion of the @code{XXX} macro is `XXX'. The use of the apostrophe @c can be confusing if the code segment itself ends with a transpose operator. @ifinfo @macro tcode{arg} \arg\ @end macro @end ifinfo @ifnotinfo @macro tcode{arg} @code{\arg\} @end macro @end ifnotinfo @c FIXME: someday, when Texinfo 5.X is standard, we might replace this with @c @backslashchar, which is a new addition to Texinfo. @macro xbackslashchar \\ @end macro @c These may be useful for all, not just for octave.texi. @tex \ifx\rgbDarkRed\thisisundefined \def\rgbDarkRed{0.50 0.09 0.12} \fi \ifx\linkcolor\thisisundefined \relax \else \global\def\linkcolor{\rgbDarkRed} \fi \ifx\urlcolor\thisisundefined \relax \else \global\def\urlcolor{\rgbDarkRed} \fi \ifx\urefurlonlylinktrue\thisisundefined \relax \else \global\urefurlonlylinktrue \fi @end tex @c Make the apostrophe in code examples cut-and-paste friendly. @codequoteundirected on arduino-0.12.2/doc/mkfuncdocs.py0000755000000000000000000002766114777724260013475 0ustar00#!/usr/bin/python3 ## Copyright 2018-2024 John Donoghue ## ## 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 ## . ## mkfuncdocs v1.0.8 ## mkfuncdocs.py will attempt to extract the help texts from functions in src ## dirs, extracting only those that are in the specifed INDEX file and output them ## to stdout in texi format ## ## It will extract from both .m and the help text for DEFUN_DLD help in .cc/.cpp ## files. ## ## It attempts to find the help text for each function in a file within the src search ## folders that match in order: [ functionname.m functionname.cc functionname.cpp ## functionname_withoutprefix.cc functionname_withoutprefix.cpp ] ## ## Usage: ## mkfundocs.py options INDEXfile ## Options can be 0 or more of: ## --verbose : Turn on verbose mode ## --src-dir=xxxxx : Add dir xxxxx to the dirs searched for the function file. ## If no directories are provided, it will default to looking in the ## 'inst' directory. ## --ignore=xxxxx : dont attempt to generate help for function xxxxx. ## --funcprefix=xxxxx : remove xxxxx from the function name when searching for matching ## source file. ## --allowscan : if can not find function, attemp to scan .cc,cpp,cxx files for match ## ## --standalone : generate a texinfo file expected to be used with being included in ## another document file. import sys import os import re import tempfile import shutil import fnmatch import subprocess import glob import calendar; import time; class Group: name = "Functions" functions = [] def __init__ (self, name=""): if name: self.name = name self.functions = [] class Index: name = "" groups = [] def texify_line(line): # convert any special chars in a line to texinfo format # currently just used for group formatting ? line = line.replace("@", "@@") line = line.replace("{", "@{") line = line.replace("}", "@}") line = line.replace(",", "@comma{}") return line def find_defun_line_in_file(filename, fnname): linecnt = 0 defun_line=re.compile(r"^DEFUN_DLD\s*\(\s*{}".format(fnname)) with open(filename, 'rt') as f: for line in f: if re.match(defun_line, line): return linecnt linecnt = linecnt + 1 return -1 def find_function_line_in_file(filename, fnname): linecnt = 0 func = False defun_line=re.compile(r"^\s*function \s*") with open(filename, 'rt') as f: for line in f: if func == True: x = line.strip() if x.startswith("## -*- texinfo -*-"): return linecnt else: func = False if re.match(defun_line, line): if line.find("=") != -1: x = line.split("=") x = x[-1] else: x = line.replace("function ", "") x = x.split("(") x = x[0].strip() if x == fnname: func = True linecnt = linecnt + 1 return -1 def read_m_file(filename, skip=0): help = [] inhelp = False havehelp = False; with open(filename, 'rt') as f: for line in f: line = line.lstrip() if skip > 0: skip = skip - 1 elif not havehelp: if havehelp == False and inhelp == False and line.startswith('##'): if "texinfo" in line: inhelp = True elif inhelp == True: if not line.startswith('##'): inhelp = False havehelp = True else: if line.startswith("## @"): line = line[3:] else: line = line[2:] help.append (line.rstrip()); return help def read_cc_file(filename, skip=0): help = [] inhelp = False havehelp = False; with open(filename, 'rt') as f: for line in f: line = line.lstrip() if skip > 0: skip = skip - 1 elif not havehelp: if havehelp == False and inhelp == False: if "texinfo" in line: inhelp = True elif inhelp == True: line = line.rstrip() if len(line) > 0 and line[-1] == '\\': line = line[:-1] line = line.rstrip() line = line.replace("\\n", "\n") line = line.replace("\\\"", "\"") if len(line) > 0 and line[-1] == '\n': line = line[:-1] # endif a texinfo line elif line.endswith('")'): line = line[:-2] if line.startswith('{'): inhelp = False havehelp = True else: help.append (line); return help def read_help (filename, skip=0): help = [] if filename[-2:] == ".m": help = read_m_file(filename, skip) else: help = read_cc_file(filename, skip) return help def read_index (filename, ignore): index = Index () with open(filename, 'rt') as f: lines = f.read().splitlines() #print ("read", lines) first = True category = Group() for l in lines: if l.startswith("#"): pass elif first: index.name = l; first = False elif l.startswith(" "): l = l.strip() # may be multiple functions here funcs = l.split() for f in funcs: if f not in ignore: category.functions.append(f); else: # new category name if len(category.functions) > 0: index.groups.append(category) category = Group(l.strip()) # left over category ? if len(category.functions) > 0: index.groups.append(category) return index; def find_class_file(fname, paths): for f in paths: # class constructor ? name = f + "/@" + fname + "/" + fname + ".m" if os.path.isfile(name): return name, 0 # perhaps classname.func format ? x = fname.split(".") if len(x) > 0: zname = x.pop() cname = ".".join(x) name = f + "/" + cname + ".m" if os.path.isfile(name): idx = find_function_line_in_file(name, zname) if idx >= 0: return name, idx name = f + "/@" + cname + "/" + zname + ".m" if os.path.isfile(name): return name, 0 return None, -1 def find_func_file(fname, paths, prefix, scanfiles=False): for f in paths: name = f + "/" + fname + ".m" if os.path.isfile(name): return name, 0 # class constructor ? name = f + "/@" + fname + "/" + fname + ".m" if os.path.isfile(name): return name, 0 name = f + "/" + fname + ".cc" if os.path.isfile(name): return name, 0 name = f + "/" + fname + ".cpp" if os.path.isfile(name): return name, 0 # if have a prefix, remove and try if prefix and fname.startswith(prefix): fname = fname[len(prefix):] name = f + "/" + fname + ".cc" if os.path.isfile(name): return name, 0 name = f + "/" + fname + ".cpp" if os.path.isfile(name): return name, 0 # if here, we still dont have a file match # if allowed to scan files, do that if scanfiles: #sys.stderr.write("Warning: Scaning for {}\n".format(fname)) for f in paths: files = list(f + "/" + a for a in os.listdir(f)) cc_files = fnmatch.filter(files, "*.cc") cpp_files = fnmatch.filter(files, "*.cpp") cxx_files = fnmatch.filter(files, "*.cxx") for fn in cc_files + cpp_files + cxx_files: line = find_defun_line_in_file(fn, fname) if line >= 0: #sys.stderr.write("Warning: Found function for {} in {} at {}\n".format(fname, fn, line)) return fn, line return None, -1 def display_standalone_header(): # make a file that doesnt need to be included in a texinfo file to # be valid print("@c mkfuncdocs output for a standalone function list") print("@include macros.texi") print("@ifnottex") print("@node Top") print("@top Function Documentation") print("Function documentation extracted from texinfo source in octave source files.") print("@contents") print("@end ifnottex") print("@node Function Reference") print("@chapter Function Reference") print("@cindex Function Reference") def display_standalone_footer(): print("@bye") def display_func(name, ref, help): print ("@c -----------------------------------------") print ("@subsection {}".format(name)) print ("@cindex {}".format(ref)) for l in help: print ("{}".format(l)) def process (args): options = { "verbose": False, "srcdir": [], "funcprefix": "", "ignore": [], "standalone": False, "allowscan": False } indexfile = "" for a in args: #print ("{}".format(a)) c=a.split("=") key=c[0] if len(c) > 1: val=c[1] else: val="" if key == "--verbose": options["verbose"] = True; if key == "--standalone": options["standalone"] = True; elif key == "--allowscan": options["allowscan"] = True; elif key == "--src-dir": if val: options["srcdir"].append(val); elif key == "--ignore": if val: options["ignore"].append(val); elif key == "--func-prefix": if val: options["funcprefix"] = val; elif val == "": if indexfile == "": indexfile = key if indexfile == "": raise Exception("No index filename") if len(options["srcdir"]) == 0: options["srcdir"].append("inst") #print "options=", options if options['standalone']: display_standalone_header() idx = read_index(indexfile, options["ignore"]) for g in idx.groups: #print ("************ {}".format(g.name)) g_name = texify_line(g.name) print ("@c ---------------------------------------------------") print ("@node {}".format(g_name)) print ("@section {}".format(g_name)) print ("@cindex {}".format(g_name)) for f in sorted(g.functions): print ("@c {} {}".format(g_name, f)) h = "" filename = "" path = "" if "@" in f: #print ("class func") path = f name = "@" + f ref = f.split("/")[-1] filename, lineno = find_func_file(path, options["srcdir"], options["funcprefix"]) elif "." in f: path = f ref = f.split(".")[-1] name = f.split(".")[-1] filename, lineno = find_class_file(path, options["srcdir"]) if not filename: parts = f.split('.') cnt = 0 path = "" for p in parts: if cnt < len(parts)-1: path = path + "/+" else: path = path + "/" path = path + p cnt = cnt + 1 name = f; ref = parts[-1] filename, lineno = find_func_file(path, options["srcdir"], options["funcprefix"]) elif "/" in f: path = f name = f ref = f.split("/")[-1] filename, lineno = find_func_file(path, options["srcdir"], options["funcprefix"]) else: path = f name = f ref = f filename, lineno = find_func_file(path, options["srcdir"], options["funcprefix"], options['allowscan']) if not filename: sys.stderr.write("Warning: Cant find source file for {}\n".format(f)) else: h = read_help (filename, lineno) if h: display_func (name, ref, h) if options['standalone']: display_standalone_footer() def show_usage(): print (sys.argv[0], "[options] indexfile") if __name__ == "__main__": if len(sys.argv) > 1: status = process(sys.argv[1:]) sys.exit(status) else: show_usage() arduino-0.12.2/doc/mkqhcp.py0000755000000000000000000001331314777724260012611 0ustar00#!/usr/bin/python3 ## mkqhcp.py ## Version 1.0.4 ## Copyright 2022-2023 John Donoghue ## ## 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 ## . import sys import os import re def process(name): with open(name + ".qhcp", 'wt') as f: f.write ('\n') f.write ('\n') f.write (' \n') f.write (' \n') f.write (' \n') f.write (' {0}.qhp\n'.format(name)) f.write (' {0}.qch\n'.format(name)) f.write (' \n') f.write (' \n') f.write (' \n') f.write (' {0}.qch\n'.format(name)) f.write (' \n') f.write (' \n') f.write ('\n') title = name pat_match = re.compile(r".*(?P<title>[^<]+).*") with open(name + ".html", 'rt') as fin: # find html for line in fin: line = line.strip() e = pat_match.match(line) if e: title = e.group("title") break # section h2_match = re.compile(r'.*

]*>(?P[^<]+)</h2>.*') # appendix h2a_match = re.compile(r'.*<h2 class="appendix"[^>]*>(?P<title>[^<]+)</h2>.*') # index h2i_match = re.compile(r'.*<h2 class="unnumbered"[^>]*>(?P<title>[^<]+)</h2>.*') h3_match = re.compile(r'.*<h3 class="section"[^>]*>(?P<title>[^<]+)</h3>.*') h4_match = re.compile(r'.*<h4 class="subsection"[^>]*>(?P<title>[^<]+)</h4>.*') tag_match1 = re.compile(r'.*<span id="(?P<tag>[^"]+)"[^>]*></span>.*') #tag_match2 = re.compile(r'.*<div class="[sub]*section" id="(?P<tag>[^"]+)"[^>]*>.*') tag_match2 = re.compile(r'.*<div class="[sub]*section[^"]*" id="(?P<tag>[^"]+)"[^>]*>.*') tag_match3 = re.compile(r'.*<div class="chapter-level-extent" id="(?P<tag>[^"]+)"[^>]*>.*') tag_match4 = re.compile(r'.*<div class="appendix-level-extent" id="(?P<tag>[^"]+)"[^>]*>.*') tag_match5 = re.compile(r'.*<div class="unnumbered-level-extent" id="(?P<tag>[^"]+)"[^>]*>.*') index_match = re.compile(r'.*<h4 class="subsection"[^>]*>[\d\.\s]*(?P<name>[^<]+)</h4>.*') tag = "top" has_h2 = False has_h3 = False #pat_match = re.compile(r'.*<span id="(?P<tag>[^"])"></span>(?P<title>[.]+)$') with open(name + ".html", 'rt') as fin: with open(name + ".qhp", 'wt') as f: f.write('<?xml version="1.0" encoding="UTF-8"?>\n') f.write('<QtHelpProject version="1.0">\n') f.write(' <namespace>octave.community.{}</namespace>\n'.format(name)) f.write(' <virtualFolder>doc</virtualFolder>\n') f.write(' <filterSection>\n') f.write(' <toc>\n') f.write(' <section title="{} Manual" ref="{}.html">\n'.format(title, name)) # chapters here for line in fin: line = line.strip() e = tag_match1.match(line) if not e: e = tag_match2.match(line) if not e: e = tag_match3.match(line) if not e: e = tag_match4.match(line) if not e: e = tag_match5.match(line) if e: tag = e.group("tag") e = h2_match.match(line) if not e: e = h2a_match.match(line) if not e: e = h2i_match.match(line) if e: if has_h3: f.write(' </section>\n') has_h3 = False if has_h2: f.write(' </section>\n') has_h2 = True f.write(' <section title="{}" ref="{}.html#{}">\n'.format(e.group("title"), name, tag)) e = h3_match.match(line) if e: if has_h3: f.write(' </section>\n') has_h3 = True f.write(' <section title="{}" ref="{}.html#{}">\n'.format(e.group("title"), name, tag)) e = h4_match.match(line) if e: f.write(' <section title="{}" ref="{}.html#{}"></section>\n'.format(e.group("title"), name, tag)) if has_h3: f.write(' </section>\n') if has_h2: f.write(' </section>\n') f.write(' </section>\n') f.write(' </toc>\n') f.write(' <keywords>\n') fin.seek(0) for line in fin: line = line.strip() e = tag_match1.match(line) if not e: e = tag_match2.match(line) if e: tag = e.group("tag") e = index_match.match(line) if e: f.write(' <keyword name="{}" ref="{}.html#{}"></keyword>\n'.format(e.group("name"), name, tag)) f.write(' </keywords>\n') f.write(' <files>\n') f.write(' <file>{}.html</file>\n'.format(name)) f.write(' <file>{}.css</file>\n'.format(name)) f.write(' </files>\n') f.write(' </filterSection>\n') f.write('</QtHelpProject>\n') def show_usage(): print (sys.argv[0], "projname") if __name__ == "__main__": if len(sys.argv) > 1: status = process(sys.argv[1]) sys.exit(status) else: show_usage() ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/doc/version.texi���������������������������������������������������������������������0000644�0000000�0000000�00000000135�14777724260�013327� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������@c autogenerated from Makefile @set VERSION 0.12.2 @set PACKAGE arduino @set DATE 2025-04-16 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/��������������������������������������������������������������������������������0000755�0000000�0000000�00000000000�14777724260�011160� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/���������������������������������������������������������������������0000755�0000000�0000000�00000000000�14777724260�013224� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/+config/�������������������������������������������������������������0000755�0000000�0000000�00000000000�14777724260�014544� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/+config/config_due.m�������������������������������������������������0000644�0000000�0000000�00000020622�14777724260�017026� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2021 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} config_due (@var{initdata}) ## Private function for setting allowed modes of due board pins ## @end deftypefn function retval = config_due (initdata) retval = {}; # default board info - must be provided # will be filled in on connection. retval.board = ''; retval.baudrate = 9600; retval.mcu = 'cortex-m3'; retval.voltref = 3.3; retval.libs = {}; retval.port = ''; # info expected to be provided by config. retval.description = 'Arduino Due Board'; # pin config retval.pins = {}; retval.pins{end+1} = arduinoio.config.pin_info('D0', 0, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D1', 1, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D2', 2, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D3', 3, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D4', 4, { 'digital', 'pwm', 'interrupt' }); # D87 retval.pins{end+1} = arduinoio.config.pin_info('D5', 5, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D6', 6, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D7', 7, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D8', 8, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D9', 9, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D10', 10, { 'digital', 'pwm', 'interrupt' }); # D77 retval.pins{end+1} = arduinoio.config.pin_info('D11', 11, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D12', 12, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D13', 13, { 'digital', 'pwm' 'led_13', 'led', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D14', 14, { 'digital', 'uart3_tx', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D15', 15, { 'digital', 'uart3_rx', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D16', 16, { 'digital', 'uart2_tx', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D17', 17, { 'digital', 'uart2_rx', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D18', 18, { 'digital', 'uart1_tx', 'interrupt'}); retval.pins{end+1} = arduinoio.config.pin_info('D19', 19, { 'digital', 'uart1_tx', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D20', 20, { 'digital', 'i2c0_sda', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D21', 21, { 'digital', 'i2c0_scl', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D22', 22, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D23', 23, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D24', 24, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D25', 25, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D26', 26, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D27', 27, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D28', 28, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D29', 29, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D30', 30, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D31', 31, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D32', 32, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D33', 33, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D34', 34, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D35', 35, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D36', 36, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D37', 37, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D38', 38, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D39', 39, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D40', 40, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D41', 41, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D42', 42, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D43', 43, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D44', 44, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D45', 45, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D46', 46, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D47', 47, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D48', 48, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D49', 49, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D50', 50, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D51', 51, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D52', 52, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D53', 53, { 'digital', 'interrupt' }); # analogs retval.pins{end+1} = arduinoio.config.pin_info('A0', 54, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A1', 55, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A2', 56, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A3', 57, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A4', 58, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A5', 59, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A6', 60, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A7', 61, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A8', 62, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A9', 63, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A10', 64, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A11', 65, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('D66', 66, { 'digital' }); # DAC0 retval.pins{end+1} = arduinoio.config.pin_info('D67', 67, { 'digital' }); # DAC1 retval.pins{end+1} = arduinoio.config.pin_info('D68', 68, { 'digital' }); # CANRX retval.pins{end+1} = arduinoio.config.pin_info('D69', 69, { 'digital' }); # CANTX retval.pins{end+1} = arduinoio.config.pin_info('D70', 70, { 'digital', 'i2c1_sda' }); retval.pins{end+1} = arduinoio.config.pin_info('D71', 71, { 'digital', 'i2c1_scl' }); retval.pins{end+1} = arduinoio.config.pin_info('D72', 72, { 'digital', 'led_rxl' }); retval.pins{end+1} = arduinoio.config.pin_info('D73', 73, { 'digital', 'led_txl' }); retval.pins{end+1} = arduinoio.config.pin_info('D74', 74, { 'digital', 'spi_miso' }); retval.pins{end+1} = arduinoio.config.pin_info('D75', 75, { 'digital', 'spi_mosi' }); retval.pins{end+1} = arduinoio.config.pin_info('D76', 76, { 'digital', 'spi_sck' }); retval.pins{end+1} = arduinoio.config.pin_info('D77', 77, { 'digital', 'spi_ss' }); #retval.pins{end+1} = arduinoio.config.pin_info('D78', 78, { 'digital', 'spi_ss3' }); #retval.pins{end+1} = arduinoio.config.pin_info('D86', 86, { 'digital', 'spi_ss2' }); #retval.pins{end+1} = arduinoio.config.pin_info('D87', 87, { 'digital', 'spi_ss1' }); endfunction ��������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/+config/config_esp32_dev.m�������������������������������������������0000644�0000000�0000000�00000015360�14777724260�020046� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2021 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} config_esp32_dev (@var{initdata}) ## Private function for setting allowed modes of esp board pins ## @end deftypefn # configuration generated from esp32/2.0.2/variants/esp32/pins_arduino.h function retval = config_esp32_dev (initdata) retval = {}; # default board info - must be provided # will be filled in on connection. retval.board = ''; retval.baudrate = 9600; retval.mcu = 'eps32'; retval.voltref = 0; retval.libs = {}; retval.port = ''; # info expected to be provided by config. retval.description = 'ESP32 Dev Module'; # pin config retval.pins = {}; retval.pins{end+1} = arduinoio.config.pin_info('D0', 0, { 'digital', 'pwm', 'interrupt', 'analog' }, {'a11'}); retval.pins{end+1} = arduinoio.config.pin_info('D1', 1, { 'digital', 'pwm', 'uart0_tx', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D2', 2, { 'digital', 'pwm', 'interrupt', 'led', 'analog' }, {'a12'}); retval.pins{end+1} = arduinoio.config.pin_info('D3', 3, { 'digital', 'pwm', 'uart0_rx', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D4', 4, { 'digital', 'pwm', 'interrupt', 'analog' }, {'a4'}); retval.pins{end+1} = arduinoio.config.pin_info('D5', 5, { 'digital', 'pwm', 'interrupt', 'spi_ss' }); # dont use #retval.pins{end+1} = arduinoio.config.pin_info('D6', 6, { 'digital', 'pwm', 'interrupt' }); #retval.pins{end+1} = arduinoio.config.pin_info('D7', 7, { 'digital', 'pwm', 'interrupt' }); #retval.pins{end+1} = arduinoio.config.pin_info('D8', 8, { 'digital', 'pwm', 'interrupt' }); #retval.pins{end+1} = arduinoio.config.pin_info('D9', 9, { 'digital', 'pwm', 'interrupt' }); #retval.pins{end+1} = arduinoio.config.pin_info('D10', 10, { 'digital', 'pwm', 'interrupt' }); #retval.pins{end+1} = arduinoio.config.pin_info('D11', 11, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D12', 12, { 'digital', 'pwm', 'interrupt', 'analog' }, {'a15'}); retval.pins{end+1} = arduinoio.config.pin_info('D13', 13, { 'digital', 'pwm', 'interrupt', 'analog' }, {'a14'}); retval.pins{end+1} = arduinoio.config.pin_info('D14', 14, { 'digital', 'pwm', 'interrupt', 'analog' }, {'a16'}); retval.pins{end+1} = arduinoio.config.pin_info('D15', 15, { 'digital', 'pwm', 'interrupt', 'analog' }, {'a13'}); retval.pins{end+1} = arduinoio.config.pin_info('D16', 16, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D17', 17, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D18', 18, { 'digital', 'pwm', 'interrupt', 'spi_sck' }); retval.pins{end+1} = arduinoio.config.pin_info('D19', 19, { 'digital', 'pwm', 'interrupt', 'spi_miso' }); #retval.pins{end+1} = arduinoio.config.pin_info('D20', 20, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D21', 21, { 'digital', 'pwm', 'interrupt', 'i2c_sda' }); retval.pins{end+1} = arduinoio.config.pin_info('D22', 22, { 'digital', 'pwm', 'interrupt', 'i2c_scl' }); retval.pins{end+1} = arduinoio.config.pin_info('D23', 23, { 'digital', 'pwm', 'interrupt', 'spi_mosi' }); #retval.pins{end+1} = arduinoio.config.pin_info('D24', 24, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D25', 25, { 'digital', 'pwm', 'interrupt', 'analog' }, {'a18'}); retval.pins{end+1} = arduinoio.config.pin_info('D26', 26, { 'digital', 'pwm', 'interrupt', 'analog' }, {'a19'}); retval.pins{end+1} = arduinoio.config.pin_info('D27', 27, { 'digital', 'pwm', 'interrupt', 'analog' }, {'a17'}); #retval.pins{end+1} = arduinoio.config.pin_info('D28', 28, { 'digital', 'pwm', 'interrupt' }); #retval.pins{end+1} = arduinoio.config.pin_info('D29', 29, { 'digital', 'pwm', 'interrupt' }); #retval.pins{end+1} = arduinoio.config.pin_info('D30', 30, { 'digital', 'pwm', 'interrupt' }); #retval.pins{end+1} = arduinoio.config.pin_info('D31', 31, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D32', 32, { 'digital', 'pwm', 'interrupt', 'analog' }, {'a4'}); retval.pins{end+1} = arduinoio.config.pin_info('D33', 33, { 'digital', 'pwm', 'interrupt', 'anolog' }, {'a5'}); retval.pins{end+1} = arduinoio.config.pin_info('D34', 34, { 'digital', 'analog' }, {'a6'}); retval.pins{end+1} = arduinoio.config.pin_info('D35', 35, { 'digital', 'analog' }, {'a7'}); retval.pins{end+1} = arduinoio.config.pin_info('D36', 36, { 'digital', 'analog' }, {'a0'}); retval.pins{end+1} = arduinoio.config.pin_info('D37', 37, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D38', 38, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D39', 39, { 'digital', 'analog' }, {'a3'}); %{ analog are in the digital pins retval.pins{end+1} = arduinoio.config.pin_info('A0', 40, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A1', 41, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A2', 42, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A3', 43, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A4', 44, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A5', 45, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A6', 46, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A7', 47, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A8', 48, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A9', 49, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A10', 50, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A11', 51, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A12', 52, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A13', 53, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A14', 54, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A15', 55, { 'digital', 'analog' }); %} endfunction ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/+config/config_leonardo.m��������������������������������������������0000644�0000000�0000000�00000006745�14777724260�020066� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} config_leonardo (@var{initdata}) ## Private function for setting allowed modes of leonardo board pins ## @end deftypefn function retval = config_leonardo (initdata) retval = {}; # default board info - must be provided # will be filled in on connection. retval.board = 'leonardo'; retval.baudrate = 9600; retval.mcu = ''; retval.voltref = 0; retval.libs = {}; retval.port = ''; # info expected to be provided by config. retval.description = 'Arduino Leonardo Board'; # pin config retval.pins = {}; retval.pins{end+1} = arduinoio.config.pin_info('D0', 0, { 'digital', 'uart1_rx' }); retval.pins{end+1} = arduinoio.config.pin_info('D1', 1, { 'digital', 'uart1_tx' }); retval.pins{end+1} = arduinoio.config.pin_info('D2', 2, { 'digital', 'i2c_sda', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D3', 3, { 'digital', 'i2c_scl', 'interrupt', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D4', 4, { 'digital' }, {"A6"}); # share A6 retval.pins{end+1} = arduinoio.config.pin_info('D5', 5, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D6', 6, { 'digital', 'pwm' }, {"A7"}); # share A7 retval.pins{end+1} = arduinoio.config.pin_info('D7', 7, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D8', 8, { 'digital' }, {"A8"}); # share A8 retval.pins{end+1} = arduinoio.config.pin_info('D9', 9, { 'digital', 'pwm' }, {"A9"}); # share A9 retval.pins{end+1} = arduinoio.config.pin_info('D10', 10, { 'digital', 'pwm' }, {"A10"}); # share A10 retval.pins{end+1} = arduinoio.config.pin_info('D11', 11, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D12', 12, { 'digital' }, {"A11"}); retval.pins{end+1} = arduinoio.config.pin_info('D13', 13, { 'digital', 'led', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D14', 14, { 'digital', 'spi_miso' }); retval.pins{end+1} = arduinoio.config.pin_info('D15', 15, { 'digital', 'spi_sck' }); retval.pins{end+1} = arduinoio.config.pin_info('D16', 16, { 'digital', 'spi_mosi' }); retval.pins{end+1} = arduinoio.config.pin_info('D17', 17, { 'digital', 'spi_ss', 'led' }); retval.pins{end+1} = arduinoio.config.pin_info('A0', 18, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A1', 19, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A2', 20, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A3', 21, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A4', 22, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A5', 23, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('D30', 30, { 'digital', 'led' }); endfunction ���������������������������arduino-0.12.2/inst/+arduinoio/+config/config_lilypad.m���������������������������������������������0000644�0000000�0000000�00000004160�14777724260�017706� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# configuration generated from /usr/share/arduino/hardware/arduino/avr/variants/standard/pins_arduino.h function retval = config_lilypad (initdata) retval = {}; # default board info - must be provided # will be filled in on connection. retval.board = ''; retval.baudrate = 9600; retval.mcu = ''; retval.voltref = 0; retval.libs = {}; retval.port = ''; # info expected to be provided by config. retval.description = 'lilypad arduino'; # pin config retval.pins = {}; retval.pins{end+1} = arduinoio.config.pin_info('D0', 0, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D1', 1, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D2', 2, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D3', 3, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D4', 4, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D5', 5, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D6', 6, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D7', 7, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D8', 8, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D9', 9, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D10', 10, { 'digital', 'spi_ss' }); retval.pins{end+1} = arduinoio.config.pin_info('D11', 11, { 'digital', 'spi_mosi' }); retval.pins{end+1} = arduinoio.config.pin_info('D12', 12, { 'digital', 'spi_miso' }); retval.pins{end+1} = arduinoio.config.pin_info('D13', 13, { 'digital', 'spi_sck', 'led' }); retval.pins{end+1} = arduinoio.config.pin_info('A0', 14, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A1', 15, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A2', 16, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A3', 17, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A4', 18, { 'digital', 'i2c_sda', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A5', 19, { 'digital', 'i2c_scl', 'analog' }); endfunction ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/+config/config_mega2560.m��������������������������������������������0000644�0000000�0000000�00000015667�14777724260�017514� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} config_mega (@var{initdata}) ## Private function for setting allowed modes of mega board pins ## @end deftypefn function retval = config_mega2560 (initdata) retval = []; # default board info - must be provided # will be filled in on connection. retval.board = ''; retval.baudrate = 9600; retval.mcu = ''; retval.voltref = 0; retval.libs = {}; retval.port = ''; # info expected to be provided by config. retval.description = 'Arduino Mega2560/1260 Board'; # pin config retval.pins = {}; retval.pins{end+1} = arduinoio.config.pin_info('D0', 0, { 'digital', 'uart' }); retval.pins{end+1} = arduinoio.config.pin_info('D1', 1, { 'digital', 'uart' }); retval.pins{end+1} = arduinoio.config.pin_info('D2', 2, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D3', 3, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D4', 4, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D5', 5, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D6', 6, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D7', 7, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D8', 8, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D9', 9, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D10', 10, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D11', 11, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D12', 12, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D13', 13, { 'digital', 'led', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D14', 14, { 'digital', 'uart3_tx' }); retval.pins{end+1} = arduinoio.config.pin_info('D15', 15, { 'digital', 'uart3_rx' }); retval.pins{end+1} = arduinoio.config.pin_info('D16', 16, { 'digital', 'uart2_tx' }); retval.pins{end+1} = arduinoio.config.pin_info('D17', 17, { 'digital', 'uart2_rx' }); retval.pins{end+1} = arduinoio.config.pin_info('D18', 18, { 'digital', 'uart1_tx', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D19', 19, { 'digital', 'uart1_rx', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D20', 20, { 'digital', 'i2c_sda', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D21', 21, { 'digital', 'i2c_scl', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D22', 22, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D23', 23, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D24', 24, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D25', 25, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D26', 26, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D27', 27, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D28', 28, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D29', 29, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D30', 30, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D31', 31, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D32', 32, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D33', 33, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D34', 34, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D35', 35, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D36', 36, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D37', 37, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D38', 38, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D39', 39, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D40', 40, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D41', 41, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D42', 42, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D43', 43, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D44', 44, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D45', 45, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D46', 46, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D47', 47, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D48', 48, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D49', 49, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D50', 50, { 'digital', 'spi_miso' }); retval.pins{end+1} = arduinoio.config.pin_info('D51', 51, { 'digital', 'spi_mosi' }); retval.pins{end+1} = arduinoio.config.pin_info('D52', 52, { 'digital', 'spi_sck' }); retval.pins{end+1} = arduinoio.config.pin_info('D53', 53, { 'digital', 'spi_ss' }); retval.pins{end+1} = arduinoio.config.pin_info('A0', 54, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A1', 55, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A2', 56, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A3', 57, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A4', 58, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A5', 59, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A6', 60, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A7', 61, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A8', 62, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A9', 63, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A10', 64, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A11', 65, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A12', 66, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A13', 67, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A14', 68, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A15', 69, { 'digital', 'analog' }); endfunction �������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/+config/config_micro.m�����������������������������������������������0000644�0000000�0000000�00000006571�14777724260�017371� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} config_micro (@var{initdata}) ## Private function for setting allowed modes of micro board pins ## @end deftypefn function retval = config_micro (initdata) retval = {}; # default board info - must be provided # will be filled in on connection. retval.board = 'micro'; retval.baudrate = 9600; retval.mcu = ''; retval.voltref = 0; retval.libs = {}; retval.port = ''; # info expected to be provided by config. retval.description = 'Arduino Micro Board'; # pin config retval.pins = {}; retval.pins{end+1} = arduinoio.config.pin_info('D0', 0, { 'digital', 'uart1_rx' }); retval.pins{end+1} = arduinoio.config.pin_info('D1', 1, { 'digital', 'uart1_tx' }); retval.pins{end+1} = arduinoio.config.pin_info('D2', 2, { 'digital', 'i2c_sda', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D3', 3, { 'digital', 'i2c_scl', 'interrupt', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D4', 4, { 'digital' }, {"A6"}); # share A6 retval.pins{end+1} = arduinoio.config.pin_info('D5', 5, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D6', 6, { 'digital', 'pwm' }, {"A7"}); # share A7 retval.pins{end+1} = arduinoio.config.pin_info('D7', 7, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D8', 8, { 'digital' }, {"A8"}); # share A8 retval.pins{end+1} = arduinoio.config.pin_info('D9', 9, { 'digital', 'pwm' }, {"A9"}); # share A9 retval.pins{end+1} = arduinoio.config.pin_info('D10', 10, { 'digital', 'pwm' }, {"A10"}); # share A10 retval.pins{end+1} = arduinoio.config.pin_info('D11', 11, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D12', 12, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D13', 13, { 'digital', 'led', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D14', 14, { 'digital', 'spi_miso' }); retval.pins{end+1} = arduinoio.config.pin_info('D15', 15, { 'digital', 'spi_sck' }); retval.pins{end+1} = arduinoio.config.pin_info('D16', 16, { 'digital', 'spi_mosi' }); retval.pins{end+1} = arduinoio.config.pin_info('D17', 17, { 'digital', 'spi_ss', 'led' }); retval.pins{end+1} = arduinoio.config.pin_info('A0', 18, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A1', 19, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A2', 20, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A3', 21, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A4', 22, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A5', 23, { 'digital', 'analog' }); endfunction ���������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/+config/config_mkr1000.m���������������������������������������������0000644�0000000�0000000�00000005777�14777724260�017361� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# configuration generated from arduino/hardware/samd/1.8.11/variants/mkr1000/variant.h function retval = config_mkr1000 (initdata) retval = {}; # default board info - must be provided # will be filled in on connection. retval.board = ''; retval.baudrate = 9600; retval.mcu = 'cortex-m0plus'; retval.voltref = 3.3; retval.libs = {}; retval.port = ''; # info expected to be provided by config. retval.description = 'MKR 1000 Board'; # pin config retval.pins = {}; retval.pins{end+1} = arduinoio.config.pin_info('D0', 0, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D1', 1, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D2', 2, { 'digital', 'i2s_sck', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D3', 3, { 'digital', 'i2s_fs', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D4', 4, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D5', 5, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D6', 6, { 'digital', 'led', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D7', 7, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D8', 8, { 'digital', 'spi_mosi', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D9', 9, { 'digital', 'spi_sck' }); retval.pins{end+1} = arduinoio.config.pin_info('D10', 10, { 'digital', 'spi_miso', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D11', 11, { 'digital', 'i2c_sda' }); retval.pins{end+1} = arduinoio.config.pin_info('D12', 12, { 'digital', 'i2c_scl' }); retval.pins{end+1} = arduinoio.config.pin_info('D13', 13, { 'digital', 'uart1_rx' }); retval.pins{end+1} = arduinoio.config.pin_info('D14', 14, { 'digital', 'uart1_tx' }); retval.pins{end+1} = arduinoio.config.pin_info('A0', 15, { 'digital', 'analog', 'dac0' }, {"D15"}); retval.pins{end+1} = arduinoio.config.pin_info('A1', 16, { 'digital', 'analog', 'interrupt' }, {"D16"}); retval.pins{end+1} = arduinoio.config.pin_info('A2', 17, { 'digital', 'analog', 'interrupt' }, {"D17"}); retval.pins{end+1} = arduinoio.config.pin_info('A3', 18, { 'digital', 'analog', 'pwm' }, {"D18"}); retval.pins{end+1} = arduinoio.config.pin_info('A4', 19, { 'digital', 'analog', 'pwm' }, {"D19"}); retval.pins{end+1} = arduinoio.config.pin_info('A5', 20, { 'digital', 'analog' }, {"D20"}); retval.pins{end+1} = arduinoio.config.pin_info('A6', 21, { 'digital', 'analog' }, {"D21"}); retval.pins{end+1} = arduinoio.config.pin_info('D24', 24, { 'digital', 'spi_ss' }); # SPI connected to WINC1501B retval.pins{end+1} = arduinoio.config.pin_info('D26', 26, { 'digital', 'spi1_mosi' }); retval.pins{end+1} = arduinoio.config.pin_info('D27', 27, { 'digital', 'spi1_sck' }); retval.pins{end+1} = arduinoio.config.pin_info('D28', 28, { 'digital', 'spi1_ss' }); retval.pins{end+1} = arduinoio.config.pin_info('D29', 29, { 'digital', 'spi1_miso' }); endfunction �arduino-0.12.2/inst/+arduinoio/+config/config_mkrzero.m���������������������������������������������0000644�0000000�0000000�00000007236�14777724260�017750� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} config_mkrzero (@var{initdata}) ## Private function for setting allowed modes of mkrzero board pins ## @end deftypefn # configuration generated from mkrzero/variant.h function retval = config_mkrzero (initdata) retval = {}; # default board info - must be provided # will be filled in on connection. retval.board = ''; retval.baudrate = 9600; retval.mcu = 'cortex-m0plus'; retval.voltref = 3.3; retval.libs = {}; retval.port = ''; # info expected to be provided by config. retval.description = 'MKR Zero Board'; # pin config retval.pins = {}; retval.pins{end+1} = arduinoio.config.pin_info('D0', 0, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D1', 1, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D2', 2, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D3', 3, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D4', 4, { 'digital', 'pwm', 'spi0_ss' }); retval.pins{end+1} = arduinoio.config.pin_info('D5', 5, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D6', 6, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D7', 7, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D8', 8, { 'digital', 'pwm', 'spi0_mosi' }); retval.pins{end+1} = arduinoio.config.pin_info('D9', 9, { 'digital', 'spi0_sck' }); retval.pins{end+1} = arduinoio.config.pin_info('D10', 10, { 'digital', 'pwm', 'spi0_miso' }); retval.pins{end+1} = arduinoio.config.pin_info('D11', 11, { 'digital', 'i2c_sda' }); retval.pins{end+1} = arduinoio.config.pin_info('D12', 12, { 'digital', 'pwm', 'i2c_scl' }); retval.pins{end+1} = arduinoio.config.pin_info('D13', 13, { 'digital', 'uart1_rx' }); retval.pins{end+1} = arduinoio.config.pin_info('D14', 14, { 'digital', 'uart1_tx' }); retval.pins{end+1} = arduinoio.config.pin_info('A0', 15, { 'digital', 'analog' }, {"D15"}); retval.pins{end+1} = arduinoio.config.pin_info('A1', 16, { 'digital', 'analog' }, {"D16"}); retval.pins{end+1} = arduinoio.config.pin_info('A2', 17, { 'digital', 'analog' }, {"D17"}); retval.pins{end+1} = arduinoio.config.pin_info('A3', 18, { 'digital', 'analog' }, {"D18"}); retval.pins{end+1} = arduinoio.config.pin_info('A4', 19, { 'digital', 'analog' }, {"D19"}); retval.pins{end+1} = arduinoio.config.pin_info('A5', 20, { 'digital', 'analog' }, {"D20"}); retval.pins{end+1} = arduinoio.config.pin_info('A6', 21, { 'digital', 'analog' }, {"D21"}); retval.pins{end+1} = arduinoio.config.pin_info('D26', 26, { 'digital', 'spi1_mosi' }); retval.pins{end+1} = arduinoio.config.pin_info('D27', 27, { 'digital', 'spi1_sck' }); retval.pins{end+1} = arduinoio.config.pin_info('D28', 28, { 'digital', 'spi1_ss' }); retval.pins{end+1} = arduinoio.config.pin_info('D29', 29, { 'digital', 'spi1_miso' }); retval.pins{end+1} = arduinoio.config.pin_info('D32', 32, { 'digital', 'led' }); endfunction ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/+config/config_nano.m������������������������������������������������0000644�0000000�0000000�00000006310�14777724260�017202� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} config_uno (@var{initdata}) ## Private function for setting allowed modes of uno board pins ## @end deftypefn # configuration generated from /usr/share/arduino/hardware/arduino/avr/variants/standard/pins_arduino.h function retval = config_nano (initdata) retval = []; # default board info - must be provided # will be filled in on connection retval.board = "nano"; retval.baudrate = 9600; retval.mcu = ''; retval.voltref = 50; retval.libs = {}; retval.port = ""; # info expected to be provided by config. retval.description = 'Arduino Nano Board'; # pin config retval.pins = {}; retval.pins{end+1} = arduinoio.config.pin_info("D0", 0, { 'digital' , 'uart'}); retval.pins{end+1} = arduinoio.config.pin_info("D1", 1, { 'digital' , 'uart'}); retval.pins{end+1} = arduinoio.config.pin_info("D2", 2, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info("D3", 3, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info("D4", 4, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info("D5", 5, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info("D6", 6, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info("D7", 7, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info("D8", 8, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info("D9", 9, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info("D10", 10, { 'digital', 'pwm', 'spi0_ss' }); retval.pins{end+1} = arduinoio.config.pin_info("D11", 11, { 'digital', 'pwm', 'spi0_mosi' }); retval.pins{end+1} = arduinoio.config.pin_info("D12", 12, { 'digital', 'pwm', 'spi0_miso' }); retval.pins{end+1} = arduinoio.config.pin_info("D13", 13, { 'digital', 'pwm', 'spi0_sck', 'led' }); retval.pins{end+1} = arduinoio.config.pin_info("A0", 14, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info("A1", 15, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info("A2", 16, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info("A3", 17, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info("A4", 18, { 'digital', 'analog', 'i2c_sda' }); retval.pins{end+1} = arduinoio.config.pin_info("A5", 19, { 'digital', 'analog', 'i2c_scl' }); retval.pins{end+1} = arduinoio.config.pin_info("A6", 20, { 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info("A7", 21, { 'analog' }); endfunction ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/+config/config_nano_33_ble.m�����������������������������������������0000644�0000000�0000000�00000006047�14777724260�020340� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# configuration generated from ARDUINO_NANO33BLE/pins_arduino.h function retval = config_nano_33_ble (initdata) retval = {}; # default board info - must be provided # will be filled in on connection. retval.board = 'nano_33_ble'; retval.baudrate = 9600; retval.mcu = 'nRF52840'; retval.voltref = 0; retval.libs = {}; retval.port = ''; # info expected to be provided by config. retval.description = 'Arduino Nano 33 BLE'; # pin config retval.pins = {}; retval.pins{end+1} = arduinoio.config.pin_info('D0', 0, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D1', 1, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D2', 2, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D3', 3, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D4', 4, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D5', 5, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D6', 6, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D7', 7, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D8', 8, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D9', 9, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D10', 10, { 'digital', 'spi_ss', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D11', 11, { 'digital', 'spi_mosi', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D12', 12, { 'digital', 'spi_miso', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D13', 13, { 'digital', 'led', 'spi_sck', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('A0', 14, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A1', 15, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A2', 16, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A3', 17, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A4', 18, { 'digital', 'analog', 'i2c0_sda' }); retval.pins{end+1} = arduinoio.config.pin_info('A5', 19, { 'digital', 'analog', 'i2c0_scl' }); retval.pins{end+1} = arduinoio.config.pin_info('A6', 20, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A7', 21, { 'digital', 'analog' }); # I/O tp on board chips retval.pins{end+1} = arduinoio.config.pin_info('D26', 26, { 'interrupt' }); # APDS int retval.pins{end+1} = arduinoio.config.pin_info('D27', 27, { 'digital' }); # PDM pwr retval.pins{end+1} = arduinoio.config.pin_info('D28', 28, { 'digital' }); # PDM clk retval.pins{end+1} = arduinoio.config.pin_info('D29', 29, { 'digital' }); # PDM din retval.pins{end+1} = arduinoio.config.pin_info('D30', 30, { 'i2c1_sda' }); retval.pins{end+1} = arduinoio.config.pin_info('D31', 31, { 'i2c1_scl' }); retval.pins{end+1} = arduinoio.config.pin_info('D32', 32, { 'digital' }); # enable i2c pullup retval.pins{end+1} = arduinoio.config.pin_info('D33', 33, { 'digital' }); # enable i2c 3.3v endfunction �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/+config/config_nano_esp32.m������������������������������������������0000644�0000000�0000000�00000007033�14777724260�020221� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2023 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} config_nano_esp32 (@var{initdata}) ## Private function for setting allowed modes of nano esp32 board pins ## @end deftypefn function retval = config_nano_esp32 (initdata) retval = []; # default board info - must be provided # will be filled in on connection retval.board = "nano_esp32"; retval.baudrate = 9600; retval.mcu = ''; retval.voltref = 33; retval.libs = {}; retval.port = ""; # info expected to be provided by config. retval.description = 'Arduino Nano ESP32 Board'; # pin config retval.pins = {}; retval.pins{end+1} = arduinoio.config.pin_info("D0", 0, { 'digital' , 'uart_rx'}); retval.pins{end+1} = arduinoio.config.pin_info("D1", 1, { 'digital' , 'uart_tx'}); retval.pins{end+1} = arduinoio.config.pin_info("D2", 2, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info("D3", 3, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info("D4", 4, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info("D5", 5, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info("D6", 6, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info("D7", 7, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info("D8", 8, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info("D9", 9, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info("D10", 10, { 'digital', 'pwm', 'spi0_ss', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info("D11", 11, { 'digital', 'pwm', 'spi0_mosi', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info("D12", 12, { 'digital', 'pwm', 'spi0_miso', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info("D13", 13, { 'digital', 'pwm', 'spi0_sck', 'led', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info("D14", 14, { 'digital', 'pwm', 'led_r', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info("D15", 15, { 'digital', 'pwm', 'led_g', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info("D16", 16, { 'digital', 'pwm', 'led_b', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info("A0", 17, { 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info("A1", 18, { 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info("A2", 19, { 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info("A3", 20, { 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info("A4", 21, { 'digital', 'analog', 'i2c_sda' }); retval.pins{end+1} = arduinoio.config.pin_info("A5", 22, { 'digital', 'analog', 'i2c_scl' }); retval.pins{end+1} = arduinoio.config.pin_info("A6", 23, { 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info("A7", 24, { 'analog' }); endfunction �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/+config/config_nano_every.m������������������������������������������0000644�0000000�0000000�00000006204�14777724260�020416� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} config_every (@var{initdata}) ## Private function for setting allowed modes of nano_every board pins ## @end deftypefn function retval = config_nano_every (initdata) retval = []; # default board info - must be provided # will be filled in on connection retval.board = "nano_every"; retval.baudrate = 9600; retval.mcu = ''; retval.voltref = 50; retval.libs = {}; retval.port = ""; # info expected to be provided by config. retval.description = 'Arduino Nano Every Board'; # pin config retval.pins = {}; retval.pins{end+1} = arduinoio.config.pin_info("D0", 0, { 'digital' , 'uart1_tx'}); retval.pins{end+1} = arduinoio.config.pin_info("D1", 1, { 'digital' , 'uart1_rx'}); retval.pins{end+1} = arduinoio.config.pin_info("D2", 2, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info("D3", 3, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info("D4", 4, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info("D5", 5, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info("D6", 6, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info("D7", 7, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info("D8", 8, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info("D9", 9, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info("D10", 10, { 'digital', 'pwm', 'spi0_ss' }); retval.pins{end+1} = arduinoio.config.pin_info("D11", 11, { 'digital', 'spi0_mosi' }); retval.pins{end+1} = arduinoio.config.pin_info("D12", 12, { 'digital', 'spi0_miso' }); retval.pins{end+1} = arduinoio.config.pin_info("D13", 13, { 'digital', 'spi0_sck', 'led' }); retval.pins{end+1} = arduinoio.config.pin_info("A0", 14, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info("A1", 15, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info("A2", 16, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info("A3", 17, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info("A4", 18, { 'digital', 'analog', 'i2c_sda' }); retval.pins{end+1} = arduinoio.config.pin_info("A5", 19, { 'digital', 'analog', 'i2c_scl' }); retval.pins{end+1} = arduinoio.config.pin_info("A6", 20, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info("A7", 21, { 'digital', 'analog' }); endfunction ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/+config/config_nano_rp2040_connect.m���������������������������������0000644�0000000�0000000�00000006506�14777724260�021731� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# configuration generated from mbed_nano/2.4.1/variants/NANO_RP2040_CONNECT/pins_arduino.h function retval = config_nano_rp2040_connect (initdata) retval = {}; # default board info - must be provided # will be filled in on connection. retval.board = ''; retval.baudrate = 9600; retval.mcu = 'cortex-m0plus'; retval.voltref = 0; retval.libs = {}; retval.port = ''; # info expected to be provided by config. retval.description = 'Arduino Nano RP2040 Connect'; # pin config retval.pins = {}; retval.pins{end+1} = arduinoio.config.pin_info('D0', 0, { 'digital', 'uart_tx' }); retval.pins{end+1} = arduinoio.config.pin_info('D1', 1, { 'digital', 'uart_rx' }); retval.pins{end+1} = arduinoio.config.pin_info('D2', 2, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D3', 3, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D4', 4, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D5', 5, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D6', 6, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D7', 7, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D8', 8, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D9', 9, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D10', 10, { 'digital', 'spi_ss', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D11', 11, { 'digital', 'spi_mosi', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D12', 12, { 'digital', 'spi_miso', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D13', 13, { 'digital', 'led', 'spi_sck', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('A0', 14, { 'digital', 'analog', 'pwm', 'interrupt' }, {'D14'}); retval.pins{end+1} = arduinoio.config.pin_info('A1', 15, { 'digital', 'analog', 'pwm', 'interrupt' }, {'D15'}); retval.pins{end+1} = arduinoio.config.pin_info('A2', 16, { 'digital', 'analog', 'pwm', 'interrupt' }, {'D16'}); retval.pins{end+1} = arduinoio.config.pin_info('A3', 17, { 'digital', 'analog', 'pwm', 'interrupt' }, {'D17'}); retval.pins{end+1} = arduinoio.config.pin_info('D18', 18, { 'digital', 'i2c_sda', 'analog' }, {'A4'}); retval.pins{end+1} = arduinoio.config.pin_info('D19', 19, { 'digital', 'i2c_scl', 'analog' }, {'A5'}); retval.pins{end+1} = arduinoio.config.pin_info('A6', 20, { 'analog' }, {'D20'}); retval.pins{end+1} = arduinoio.config.pin_info('A7', 21, { 'analog' }, {'D21'}); #retval.pins{end+1} = arduinoio.config.pin_info('D22', 22, { 'digital', 'pdm_din', 'pwm', 'interrupt' }); #retval.pins{end+1} = arduinoio.config.pin_info('D23', 23, { 'digital', 'pdm_clk', 'pwm', 'interrupt' }); #retval.pins{end+1} = arduinoio.config.pin_info('D24', 24, { 'digital' }); #retval.pins{end+1} = arduinoio.config.pin_info('D25', 25, { 'digital' }); #retval.pins{end+1} = arduinoio.config.pin_info('D26', 26, { 'digital' }); #retval.pins{end+1} = arduinoio.config.pin_info('D27', 27, { 'digital' }); #retval.pins{end+1} = arduinoio.config.pin_info('D28', 28, { 'digital' }); #retval.pins{end+1} = arduinoio.config.pin_info('D29', 29, { 'digital' }); endfunction ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/+config/config_promicro.m��������������������������������������������0000644�0000000�0000000�00000007070�14777724260�020105� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019-2021 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} config_promicro (@var{initdata}) ## Private function for setting allowed modes of promicro board pins ## @end deftypefn function retval = config_promicro (initdata) retval = {}; # default board info - must be provided # will be filled in on connection. retval.board = 'promicro'; retval.baudrate = 9600; retval.mcu = ''; retval.voltref = 0; retval.libs = {}; retval.port = ''; # info expected to be provided by config. retval.description = 'Arduino Pro Micro Board'; # pin config retval.pins = {}; retval.pins{end+1} = arduinoio.config.pin_info('D0', 0, { 'digital', 'uart1_rx' }); retval.pins{end+1} = arduinoio.config.pin_info('D1', 1, { 'digital', 'uart1_tx' }); retval.pins{end+1} = arduinoio.config.pin_info('D2', 2, { 'digital', 'i2c_sda', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D3', 3, { 'digital', 'i2c_scl', 'interrupt', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D4', 4, { 'digital' }, {"A6"}); # share A6 retval.pins{end+1} = arduinoio.config.pin_info('D5', 5, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D6', 6, { 'digital', 'pwm' }, {"A7"}); # share A7 retval.pins{end+1} = arduinoio.config.pin_info('D7', 7, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D8', 8, { 'digital' }, {"A8"}); # share A8 retval.pins{end+1} = arduinoio.config.pin_info('D9', 9, { 'digital', 'pwm' }, {"A9"}); # share A9 retval.pins{end+1} = arduinoio.config.pin_info('D10', 10, { 'digital', 'pwm' }, {"A10"}); # share A10 # retval.pins{end+1} = arduinoio.config.pin_info('D11', 11, { 'digital', 'pwm' }); # retval.pins{end+1} = arduinoio.config.pin_info('D12', 12, { 'digital' }); # retval.pins{end+1} = arduinoio.config.pin_info('D13', 13, { 'digital', 'led', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D14', 14, { 'digital', 'spi_miso' }); retval.pins{end+1} = arduinoio.config.pin_info('D15', 15, { 'digital', 'spi_sck' }); retval.pins{end+1} = arduinoio.config.pin_info('D16', 16, { 'digital', 'spi_mosi' }); retval.pins{end+1} = arduinoio.config.pin_info('D17', 17, { 'digital', 'spi_ss', 'led' }); retval.pins{end+1} = arduinoio.config.pin_info('A0', 18, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A1', 19, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A2', 20, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A3', 21, { 'digital', 'analog' }); # retval.pins{end+1} = arduinoio.config.pin_info('A4', 22, { 'digital', 'analog' }); # retval.pins{end+1} = arduinoio.config.pin_info('A5', 23, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('D24', 24, { 'digital' }); # A6 retval.pins{end+1} = arduinoio.config.pin_info('D30', 30, { 'digital', 'led' }); endfunction ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/+config/config_promini.m���������������������������������������������0000644�0000000�0000000�00000006656�14777724260�017741� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} config_promini (@var{initdata}) ## Private function for setting allowed modes of promini board pins ## @end deftypefn function retval = config_promini (initdata) retval = []; # default board info - must be provided # will be filled in on connection retval.board = "promini"; retval.baudrate = 9600; retval.mcu = ''; retval.voltref = 0; retval.libs = {}; retval.port = ""; # info expected to be provided by config. retval.description = 'Arduino Pro/Pro Mini Board'; # pin config retval.pins = {}; #0=D0 RX retval.pins{end+1} = arduinoio.config.pin_info("D0", 0, { 'digital' , 'uart'}); #1=D1 TX retval.pins{end+1} = arduinoio.config.pin_info("D1", 1, { 'digital' , 'uart'}); #2=D2 retval.pins{end+1} = arduinoio.config.pin_info("D2", 2, { 'digital', 'interrupt' }); #3=D3 PWM retval.pins{end+1} = arduinoio.config.pin_info("D3", 3, { 'digital', 'pwm', 'interrupt' }); #4=D4 retval.pins{end+1} = arduinoio.config.pin_info("D4", 4, { 'digital' }); #5=D5 PWM retval.pins{end+1} = arduinoio.config.pin_info("D5", 5, { 'digital', 'pwm' }); #6=D6 PWM retval.pins{end+1} = arduinoio.config.pin_info("D6", 6, { 'digital', 'pwm' }); #7=D7 retval.pins{end+1} = arduinoio.config.pin_info("D7", 7, { 'digital' }); #8=D8 retval.pins{end+1} = arduinoio.config.pin_info("D8", 8, { 'digital' }); #9=D9 PWM retval.pins{end+1} = arduinoio.config.pin_info("D9", 9, { 'digital', 'pwm' }); #10=D10 PWM SS retval.pins{end+1} = arduinoio.config.pin_info("D10", 10, { 'digital', 'pwm', 'spi0_ss' }); #11=D11 PWM MOSI retval.pins{end+1} = arduinoio.config.pin_info("D11", 11, { 'digital', 'pwm', 'spi0_mosi' }); #12=D12 MISO retval.pins{end+1} = arduinoio.config.pin_info("D12", 12, { 'digital', 'pwm', 'spi0_miso' }); #13=D13 SCK LED retval.pins{end+1} = arduinoio.config.pin_info("D13", 13, { 'digital', 'pwm', 'spi0_sck', 'led' }); #14=D14 A0 retval.pins{end+1} = arduinoio.config.pin_info("A0", 14, { 'digital', 'analog' }); #15=D15 A1 retval.pins{end+1} = arduinoio.config.pin_info("A1", 15, { 'digital', 'analog' }); #16=D16 A2 retval.pins{end+1} = arduinoio.config.pin_info("A2", 16, { 'digital', 'analog' }); #17=D17 A3 retval.pins{end+1} = arduinoio.config.pin_info("A3", 17, { 'digital', 'analog' }); #18=D18 A4 I2C_SDA retval.pins{end+1} = arduinoio.config.pin_info("A4", 18, { 'digital', 'analog', 'i2c_sda' }); #19=D19 A5 I2C_SCL retval.pins{end+1} = arduinoio.config.pin_info("A5", 19, { 'digital', 'analog', 'i2c_scl' }); #20=D20 A6 retval.pins{end+1} = arduinoio.config.pin_info("A6", 20, { 'digital', 'analog' }); #21=D21 A7 retval.pins{end+1} = arduinoio.config.pin_info("A7", 21, { 'digital', 'analog' }); endfunction ����������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/+config/config_raspi_pico.m������������������������������������������0000644�0000000�0000000�00000005522�14777724260�020403� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# raspi pico 2040 # configuration generated from mbed_rp2040/2.2.0/variants/RASPBERRY_PI_PICO/pins_arduino.h function retval = config_raspi_pico (initdata) retval = {}; # default board info - must be provided # will be filled in on connection. retval.board = ''; retval.baudrate = 9600; retval.mcu = 'cortex-m0plus'; retval.voltref = 0; retval.libs = {}; retval.port = ''; # info expected to be provided by config. retval.description = 'Raspberry Pi Pico'; # pin config retval.pins = {}; retval.pins{end+1} = arduinoio.config.pin_info('D0', 0, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D1', 1, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D2', 2, { 'digital', 'spi_sck' }); retval.pins{end+1} = arduinoio.config.pin_info('D3', 3, { 'digital', 'spi_mosi' }); retval.pins{end+1} = arduinoio.config.pin_info('D4', 4, { 'digital', 'spi_miso' }); retval.pins{end+1} = arduinoio.config.pin_info('D5', 5, { 'digital', 'spi_ss' }); retval.pins{end+1} = arduinoio.config.pin_info('D6', 6, { 'digital', 'i2c_sda' }); retval.pins{end+1} = arduinoio.config.pin_info('D7', 7, { 'digital', 'i2c_scl' }); retval.pins{end+1} = arduinoio.config.pin_info('D8', 8, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D9', 9, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D10', 10, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D11', 11, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D12', 12, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D13', 13, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D14', 14, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D15', 15, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D16', 16, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D17', 17, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D18', 18, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D19', 19, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D20', 20, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D21', 21, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D22', 22, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D23', 23, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D24', 24, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D25', 25, { 'digital','led' }); retval.pins{end+1} = arduinoio.config.pin_info('A0', 26, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A1', 27, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A2', 28, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A3', 29, { 'digital', 'analog' }); endfunction ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/+config/config_sparkfunsamd21.m��������������������������������������0000644�0000000�0000000�00000007247�14777724260�021122� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} config_sparkfunsamd21 (@var{initdata}) ## Private function for setting allowed modes of sparkfun samd21 mini/dev board pins ## @end deftypefn function retval = config_sparkfunsamd21 (initdata) retval = {}; # default board info - must be provided # will be filled in on connection. retval.board = ''; retval.baudrate = 9600; retval.mcu = 'samd21'; retval.voltref = 3.3; retval.libs = {}; retval.port = ''; # info expected to be provided by config. retval.description = 'Sparkfun SAMD21 Dev/Mini Board'; # pin config retval.pins = {}; retval.pins{end+1} = arduinoio.config.pin_info('D0', 0, { 'digital', 'i2s_fs', 'uart', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D1', 1, { 'digital', 'i2s_sck', 'uart', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D2', 2, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D3', 3, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D4', 4, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D5', 5, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D6', 6, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D7', 7, { 'digital', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D8', 8, { 'digital', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D9', 9, { 'digital', 'i2s_sd', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D10', 10, { 'digital', 'spi_ss', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D11', 11, { 'digital', 'spi_mosi', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D12', 12, { 'digital', 'spi_miso', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D13', 13, { 'digital', 'led_13', 'spi_sck', 'pwm', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('A0', 14, { 'digital', 'analog', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('A1', 15, { 'digital', 'analog', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('A2', 16, { 'digital', 'analog', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('A3', 17, { 'digital', 'analog', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('A4', 18, { 'digital', 'analog', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('A5', 19, { 'digital', 'analog', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D20', 20, { 'digital', 'i2c_sda', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D21', 21, { 'digital', 'i2c_scl', 'interrupt' }); # pins 22-24 ?? retval.pins{end+1} = arduinoio.config.pin_info('D25', 25, { 'digital', 'led_rxl', 'interrupt' }); retval.pins{end+1} = arduinoio.config.pin_info('D26', 26, { 'digital', 'led_txl', 'interrupt' }); endfunction ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/+config/config_uno.m�������������������������������������������������0000644�0000000�0000000�00000006400�14777724260�017050� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} config_uno (@var{initdata}) ## Private function for setting allowed modes of uno board pins ## @end deftypefn function retval = config_uno (initdata) retval = []; # default board info - must be provided # will be filled in on connection retval.board = "uno"; retval.baudrate = 9600; retval.mcu = ''; retval.voltref = 0; retval.libs = {}; retval.port = ""; # info expected to be provided by config. retval.description = 'Arduino Uno R3 Board'; # pin config retval.pins = {}; #0=D0 RX retval.pins{end+1} = arduinoio.config.pin_info("D0", 0, { 'digital' , 'uart'}); #1=D1 TX retval.pins{end+1} = arduinoio.config.pin_info("D1", 1, { 'digital' , 'uart'}); #2=D2 retval.pins{end+1} = arduinoio.config.pin_info("D2", 2, { 'digital', 'interrupt' }); #3=D3 PWM retval.pins{end+1} = arduinoio.config.pin_info("D3", 3, { 'digital', 'pwm', 'interrupt' }); #4=D4 retval.pins{end+1} = arduinoio.config.pin_info("D4", 4, { 'digital' }); #5=D5 PWM retval.pins{end+1} = arduinoio.config.pin_info("D5", 5, { 'digital', 'pwm' }); #6=D6 PWM retval.pins{end+1} = arduinoio.config.pin_info("D6", 6, { 'digital', 'pwm' }); #7=D7 retval.pins{end+1} = arduinoio.config.pin_info("D7", 7, { 'digital' }); #8=D8 retval.pins{end+1} = arduinoio.config.pin_info("D8", 8, { 'digital' }); #9=D9 PWM retval.pins{end+1} = arduinoio.config.pin_info("D9", 9, { 'digital', 'pwm' }); #10=D10 PWM SS retval.pins{end+1} = arduinoio.config.pin_info("D10", 10, { 'digital', 'pwm', 'spi0_ss' }); #11=D11 PWM MOSI retval.pins{end+1} = arduinoio.config.pin_info("D11", 11, { 'digital', 'pwm', 'spi0_mosi' }); #12=D12 MISO retval.pins{end+1} = arduinoio.config.pin_info("D12", 12, { 'digital', 'pwm', 'spi0_miso' }); #13=D13 SCK LED retval.pins{end+1} = arduinoio.config.pin_info("D13", 13, { 'digital', 'pwm', 'spi0_sck', 'led' }); #14=D14 A0 retval.pins{end+1} = arduinoio.config.pin_info("A0", 14, { 'digital', 'analog' }); #15=D15 A1 retval.pins{end+1} = arduinoio.config.pin_info("A1", 15, { 'digital', 'analog' }); #16=D16 A2 retval.pins{end+1} = arduinoio.config.pin_info("A2", 16, { 'digital', 'analog' }); #17=D17 A3 retval.pins{end+1} = arduinoio.config.pin_info("A3", 17, { 'digital', 'analog' }); #18=D18 A4 I2C_SDA retval.pins{end+1} = arduinoio.config.pin_info("A4", 18, { 'digital', 'analog', 'i2c_sda' }); #19=D19 A5 I2C_SCL retval.pins{end+1} = arduinoio.config.pin_info("A5", 19, { 'digital', 'analog', 'i2c_scl' }); # additionals ? #20=D20 A6 #21=D21 A7 endfunction ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/+config/config_uno_minima_r4.m���������������������������������������0000644�0000000�0000000�00000004254�14777724260�021014� 0����������������������������������������������������������������������������������������������������ustar�00������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� function retval = config_uno_minima_r4 (initdata) retval = {}; retval.board = 'uno_minima_r4'; retval.baudrate = 9600; retval.mcu = ''; retval.voltref = 0; retval.libs = {}; retval.port = ''; # info expected to be provided by config. retval.description = 'Arduino Uno Minima R4 Board'; # pin config retval.pins = {}; retval.pins{end+1} = arduinoio.config.pin_info('D0', 0, { 'digital', 'uart_rx' }); retval.pins{end+1} = arduinoio.config.pin_info('D1', 1, { 'digital', 'uart_tx' }); retval.pins{end+1} = arduinoio.config.pin_info('D2', 2, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D3', 3, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D4', 4, { 'digital', 'can0_tx' }); retval.pins{end+1} = arduinoio.config.pin_info('D5', 5, { 'digital', 'can0_rx', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D6', 6, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D7', 7, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D8', 8, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D9', 9, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D10', 10, { 'digital', 'spi_ss', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D11', 11, { 'digital', 'spi_mosi', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D12', 12, { 'digital', 'spi_miso' }); retval.pins{end+1} = arduinoio.config.pin_info('D13', 13, { 'digital', 'led', 'spi_sck' }); retval.pins{end+1} = arduinoio.config.pin_info('A0', 14, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A1', 15, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A2', 16, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A3', 17, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A4', 18, { 'digital', 'analog', 'i2c_sda' }); retval.pins{end+1} = arduinoio.config.pin_info('A5', 19, { 'digital', 'analog' 'i2c_scl' }); retval.pins{end+1} = arduinoio.config.pin_info('D20', 20, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D21', 21, { 'digital' }); endfunction ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/+config/config_uno_wifi_r2.m�����������������������������������������0000644�0000000�0000000�00000010612�14777724260�020471� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} config_uno_wifi_r2 (@var{initdata}) ## Private function for setting allowed modes of uno board pins ## @end deftypefn function retval = config_uno_wifi_r2 (initdata) retval = []; # default board info - must be provided # will be filled in on connection retval.board = "uno_wifi_r2"; retval.baudrate = 9600; retval.mcu = ''; retval.voltref = 0; retval.libs = {}; retval.port = ""; # info expected to be provided by config. retval.description = 'Arduino Uno WIFI R2 Board'; # pin config retval.pins = {}; #0=D0 RX retval.pins{end+1} = arduinoio.config.pin_info("D0", 0, { 'digital' , 'uart'}); #1=D1 TX retval.pins{end+1} = arduinoio.config.pin_info("D1", 1, { 'digital' , 'uart'}); #2=D2 retval.pins{end+1} = arduinoio.config.pin_info("D2", 2, { 'digital', 'interrupt' }); #3=D3 PWM retval.pins{end+1} = arduinoio.config.pin_info("D3", 3, { 'digital', 'pwm', 'interrupt' }); #4=D4 retval.pins{end+1} = arduinoio.config.pin_info("D4", 4, { 'digital', 'interrupt' }); #5=D5 PWM retval.pins{end+1} = arduinoio.config.pin_info("D5", 5, { 'digital', 'pwm', 'interrupt' }); #6=D6 PWM retval.pins{end+1} = arduinoio.config.pin_info("D6", 6, { 'digital', 'pwm', 'interrupt' }); #7=D7 retval.pins{end+1} = arduinoio.config.pin_info("D7", 7, { 'digital', 'interrupt' }); #8=D8 retval.pins{end+1} = arduinoio.config.pin_info("D8", 8, { 'digital', 'interrupt' }); #9=D9 PWM retval.pins{end+1} = arduinoio.config.pin_info("D9", 9, { 'digital', 'pwm', 'interrupt' }); #10=D10 PWM SS retval.pins{end+1} = arduinoio.config.pin_info("D10", 10, { 'digital', 'pwm', 'interrupt' }); #11=D11 retval.pins{end+1} = arduinoio.config.pin_info("D11", 11, { 'digital', 'interrupt' }); #12=D12 retval.pins{end+1} = arduinoio.config.pin_info("D12", 12, { 'digital', 'interrupt' }); #13=D13 retval.pins{end+1} = arduinoio.config.pin_info("D13", 13, { 'digital', 'interrupt' }); #14=D14 A0 retval.pins{end+1} = arduinoio.config.pin_info("A0", 14, { 'digital', 'analog', 'interrupt' }, {"D14"}); #15=D15 A1 retval.pins{end+1} = arduinoio.config.pin_info("A1", 15, { 'digital', 'analog', 'interrupt' }, {"D15"}); #16=D16 A2 retval.pins{end+1} = arduinoio.config.pin_info("A2", 16, { 'digital', 'analog', 'interrupt' }, {"D16"}); #17=D17 A3 retval.pins{end+1} = arduinoio.config.pin_info("A3", 17, { 'digital', 'analog', 'interrupt' }, {"D17"}); #18=D18 A4 I2C_SDA retval.pins{end+1} = arduinoio.config.pin_info("A4", 18, { 'digital', 'analog', 'interrupt' }, {"D18"}); #19=D19 A5 I2C_SCL retval.pins{end+1} = arduinoio.config.pin_info("A5", 19, { 'digital', 'analog', 'interrupt' }, {"D19"}); # additionals ? #20=D20 retval.pins{end+1} = arduinoio.config.pin_info("D20", 20, { 'i2c_sda' }); #21=D21 retval.pins{end+1} = arduinoio.config.pin_info("D21", 21, { 'i2c_scl' }); retval.pins{end+1} = arduinoio.config.pin_info("D22", 22, { 'digital', 'spi0_ss' }); #25=D25 retval.pins{end+1} = arduinoio.config.pin_info("D25", 25, { 'digital', 'led' }); #26=D26 #retval.pins{end+1} = arduinoio.config.pin_info("D26", 26, { 'digital'}); #30=D30 retval.pins{end+1} = arduinoio.config.pin_info("D30", 30, { 'digital', 'imu_ss'}); #32=D32 retval.pins{end+1} = arduinoio.config.pin_info("D32", 32, { 'digital', 'spi0_mosi' }); #33=D33 retval.pins{end+1} = arduinoio.config.pin_info("D33", 33, { 'digital', 'spi0_miso' }); #34=D34 retval.pins{end+1} = arduinoio.config.pin_info("D34", 34, { 'digital', 'spi0_sck' }); #35=D35 retval.pins{end+1} = arduinoio.config.pin_info("D35", 35, { 'digital', 'wifi_ss' }); #39=D39 retval.pins{end+1} = arduinoio.config.pin_info("D39", 39, { 'digital' }); endfunction ����������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/+config/config_uno_wifi_r4.m�����������������������������������������0000644�0000000�0000000�00000007000�14777724260�020470� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2023 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} config_uno_wifi_r4 (@var{initdata}) ## Private function for setting allowed modes of uno board pins ## @end deftypefn function retval = config_uno_wifi_r4 (initdata) retval = {}; retval.board = 'uno_wifi_r4'; retval.mcu = 'Renesis RA4M1'; retval.baudrate = 9600; retval.voltref = 0; retval.libs = {}; retval.port = ''; # info expected to be provided by config. retval.description = 'Arduino Uno WIFI R4 Board'; # pin config retval.pins = {}; retval.pins{end+1} = arduinoio.config.pin_info('D0', 0, { 'digital', 'uart2_tx' }); retval.pins{end+1} = arduinoio.config.pin_info('D1', 1, { 'digital', 'uart2_rx' }); retval.pins{end+1} = arduinoio.config.pin_info('D2', 2, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D3', 3, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D4', 4, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D5', 5, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D6', 6, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D7', 7, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D8', 8, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D9', 9, { 'digital', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D10', 10, { 'digital', 'spi_ss', 'can0_tx', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D11', 11, { 'digital', 'spi_mosi', 'pwm' }); retval.pins{end+1} = arduinoio.config.pin_info('D12', 12, { 'digital', 'spi_miso' }); retval.pins{end+1} = arduinoio.config.pin_info('D13', 13, { 'digital', 'led', 'spi_sck', 'can0_rx' }); retval.pins{end+1} = arduinoio.config.pin_info('A0', 14, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A1', 15, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A2', 16, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A3', 17, { 'digital', 'analog' }); retval.pins{end+1} = arduinoio.config.pin_info('A4', 18, { 'digital', 'analog', 'i2c_sda' }); retval.pins{end+1} = arduinoio.config.pin_info('A5', 19, { 'digital', 'analog', 'i2c_scl' }); retval.pins{end+1} = arduinoio.config.pin_info('D20', 20, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D21', 21, { 'digital' }); retval.pins{end+1} = arduinoio.config.pin_info('D22', 22, { 'uart1_tx' }); retval.pins{end+1} = arduinoio.config.pin_info('D23', 23, { 'uart1_rx' }); retval.pins{end+1} = arduinoio.config.pin_info('D24', 24, { 'uart3_tx' }); retval.pins{end+1} = arduinoio.config.pin_info('D25', 25, { 'uart3_rx' }); retval.pins{end+1} = arduinoio.config.pin_info('D26', 26, { 'i2c1_scl' }); retval.pins{end+1} = arduinoio.config.pin_info('D27', 27, { 'i2c1_sda' }); endfunction arduino-0.12.2/inst/+arduinoio/+config/pin_info.m���������������������������������������������������0000644�0000000�0000000�00000001744�14777724260�016531� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. see ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{value} =} pin_info (@var{name}) ## Private function ## @end deftypefn function retval = pin_info (name, id, modes, alt) retval = []; if (nargin < 4) alt = {}; endif retval.name = lower(name); retval.id = id; retval.modes = lower(modes); retval.owner = ""; retval.mode = "unset"; retval.altnames = lower(alt); endfunction ����������������������������arduino-0.12.2/inst/+arduinoio/AddonBase.m����������������������������������������������������������0000644�0000000�0000000�00000003504�14777724260�015224� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. classdef AddonBase < handle ## -*- texinfo -*- ## @deftypefn {} {} arduinoio.AddonBase ## Base class used for arduino library sensors ## ## @seealso{arduinoio.LibraryBase} ## @end deftypefn ## ## @subheading Properties ## Base properties are expected to be inherited and overwritten in inherited classes. ## and are constant in order to query through the metaobject mechanism. ## ## @var{Parent} - parent librarybase object ## ## @subheading Methods ## @deftypefn {} {@var{ab} =} AddonBase () ## Constructor of base class ## ## @subsubheading Outputs ## The return value @var{ab} is an object of the arduinio.AddonBase class. ## ## @seealso{arduino, addon} ## @end deftypefn ## ## @deftypefn {} {} disp () ## Display the addon in a verbose way. ## @end deftypefn # properties that may be overridden in # subclasses properties (GetAccess = public, SetAccess = protected) Parent = {}; endproperties methods (Access=public) # display the base class properties function disp(this) printf(" addon %s\n", class(this)); endfunction endmethods endclassdef ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/FilePath.m�����������������������������������������������������������0000644�0000000�0000000�00000002156�14777724260�015102� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} arduinoio.FilePath (@var{fullpathname}) ## Get the directory component of a pathname. ## ## @subsubheading Inputs ## @var{fullpathname} filepath to get directory component of. ## ## @subsubheading Outputs ## @var{retval} the directory part of the filename. ## @end deftypefn function path = FilePath(fullpathname) path = fileparts(fullpathname); endfunction ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/LibFiles.m�����������������������������������������������������������0000644�0000000�0000000�00000002340�14777724260�015072� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{filelist} =} arduinoio.LibFiles () ## Get the list of files used for the building arduino library ## @subsubheading Outputs ## @var{filelist} - string cell array of files for the arduino project ## @end deftypefn function files = LibFiles() files = {}; script = mfilename('fullpath'); [path,~] = fileparts(script); filelist = dir(fullfile(path, "lib", "*.*")); for i=1:numel(filelist) files{end+1} = fullfile(fullfile(path, "lib"), filelist(i).name); endfor endfunction ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/LibraryBase.m��������������������������������������������������������0000644�0000000�0000000�00000010151�14777724260�015577� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018-2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. classdef LibraryBase < handle ## -*- texinfo -*- ## @deftypefn {} {} arduinoio.LibraryBase ## Base class used for arduino library plugins ## ## @seealso{arduino, listArduinoLibraries, addon} ## @end deftypefn ## ## @subheading Properties ## Base properties are expected to be inherited and overwritten in ## inherited classes and are constant in order to query through the ## metaobject mechanism. ## ## @var{LibraryName} - name of the addon library ## ## @var{DependentLibraries} - array of dependent library names that ## must be included when installing this plugin. ## ## @var{CppHeaderFile} - name (if any) of header file that will be ## included into the arduino project when adding this library. ## ## @var{CppSourceFile} - name (if any) of source file that will be ## included into the arduino project when adding this library. ## ## @var{CppClassName} - name of the cpp class for the addon library. ## project when adding this library. ## ## @var{Pins} - pins allocated to the addon ## ## @var{Parent} - parent arduino object. ## ## @subheading Methods ## @deftypefn {} {@var{lb} =} LibraryBase () ## Constructor of base class ## ## The constructor is usually not called but called indirectly ## from the addon function. ## ## @subsubheading Outputs ## The return value @var{lb} is an object of the arduinio.LibraryBase class. ## ## @seealso{arduino, listArduinoLibraries, addon} ## @end deftypefn ## ## @deftypefn {} {} disp () ## Display the addon in a verbose way. ## @end deftypefn # properties that may be overridden in # subclasses properties (Access = protected) LibraryName = "<none set>"; DependentLibraries = {}; ArduinoLibraryHeaderFiles = {}; CppHeaderFile = ""; CppSourceFile = ""; CppClassName = ""; endproperties properties (GetAccess = public, SetAccess = protected) Parent = {}; Pins = []; endproperties methods (Static) function info = AddonInfo(fullclassname) info = {}; info.libraryname = ""; info.dependentlibraries = ""; info.cppheaderfile = ""; info.cppsourcefile = ""; info.cppclassname = ""; info.arduinolibraryheaderfiles = ""; data = meta.class.fromName(fullclassname); for ic = 1:numel(data.Properties) p = data.Properties{ic}; if p.Constant pname = lower(p.Name); pvalue = p.DefaultValue; if isfield(info, pname) info.(pname) = pvalue; endif endif endfor info.classname = data.Name; endfunction endmethods methods (Access=public) # display the base class properties function disp(this) printf(" %s with properties\n", class(this)); if numel(this.Pins) == 0 printf(" Pins = {}\n"); else printf(" Pins = {\n"); for i=1:numel(this.Pins) if isnumeric(this.Pins{i}) printf(" %d\n", this.Pins{i}); else printf(" %s\n", this.Pins{i}); endif endfor printf(" }\n"); endif endfunction # overrides of arduino that matlab documentation indirectly # seems to indicate in the examples function [dataout, datasize] = sendCommand(this, varargin) [dataout, datasize] = sendCommand(this.Parent, varargin{:}) endfunction endmethods endclassdef �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/boardTypeString.m����������������������������������������������������0000644�0000000�0000000�00000004160�14777724260�016523� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018-2021 John Donoghue <john.donoghue@ieee.org> ## ## 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. see ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} __boardTypeString__ (@var{type}) ## Helper function to set convert board id to a (lowercase) string ## @end deftypefn function retval = boardTypeString (id) if nargin != 1 error ('expected id'); endif if ~isnumeric (id) error ('expected id as a number'); endif if ischar (id) id = int (id); endif switch (id) case 0 retval = "uno"; case 1 retval = "mega2560"; case 2 retval = "nano"; case 5 retval = "uno_wifi_r2"; case 6 retval = "nano_every"; case 10 retval = "lilypad"; case 20 retval = "promini"; case 21 retval = "promicro"; case 22 retval = "leonardo"; case 23 retval = "micro"; #case 40 # retval = "zero"; case 41 retval = "sparkfunsamd21"; case 45 retval = "due"; case 50 retval = "mkrzero"; case 51 retval = "mkr1000"; case 60 retval = "nano_33_ble"; case 100 retval = "raspi_pico"; case 101 retval = "nano_rp2040_connect"; case 102 retval = "nano_esp32"; case 111 retval = "esp32_dev"; case 112 retval = "uno_wifi_r4"; case 113 retval = "uno_minima_r4"; otherwise retval = "unknown"; endswitch endfunction %!test %! assert(arduinoio.boardTypeString (0), "uno") %! assert(arduinoio.boardTypeString (1), "mega2560") %! assert(arduinoio.boardTypeString (10), "lilypad") %! assert(arduinoio.boardTypeString (-1), "unknown") ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/getBoardConfig.m�����������������������������������������������������0000644�0000000�0000000�00000002720�14777724260�016260� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} arduinoio.getBoardConfig (@var{boardname}) ## Return the configuration for a known arduino board type ## ## Function is used to get the expected pin/board configuration for a named board type ## which is used to verify and identify the functionality of the board. ## ## @subsubheading Inputs ## @var{boardname} - name of board to get configuration of ie: "uno" ## ## @subsubheading Outputs ## @var{retval} configuration struct. ## @end deftypefn function config = getBoardConfig (board) if strcmp(board, "unknown") error ("unknown board found type"); endif config = eval(sprintf("arduinoio.config.config_%s", board)); endfunction %!test %! c = arduinoio.getBoardConfig("uno"); %! assert(c.board, "uno"); ������������������������������������������������arduino-0.12.2/inst/+arduinoio/lib/�����������������������������������������������������������������0000755�0000000�0000000�00000000000�14777724260�013772� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/lib/LibraryBase.cpp��������������������������������������������������0000644�0000000�0000000�00000022521�14777724260�016677� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Octave arduino base library * Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> * * 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 <https://www.gnu.org/licenses/>. */ #include "LibraryBase.h" #include <stdarg.h> #include "settings.h" #define ARDUINO_SOH 0xA5 #define STATE_SOH 0 #define STATE_EXT 1 #define STATE_CMD 2 #define STATE_SIZE 3 #define STATE_DATA 4 #define STATE_EOM 5 #if defined(OCTAVE_USE_WIFI_COMMS) # if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_RENESAS) #include <WiFi.h> # else #include <WiFiNINA.h> # endif char wifi_ssid[] = WIFI_SECRET_SSID; // your network SSID (name) char wifi_pass[] = WIFI_SECRET_PASS; int wifi_status = WL_IDLE_STATUS; WiFiServer wifiServer(WIFI_PORT); WiFiClient wifi_client; #endif #ifndef ARDUINO_BAUDRATE # define ARDUINO_BAUDRATE 9600 #endif // some standard(ish) error messages used throughout the addons const char ERRORMSG_INVALID_NUMBER_OF_ARGS[] PROGMEM = "Invalid number of args"; const char ERRORMSG_UNIMPLEMENTED[] PROGMEM = "Unimplemented feature"; const char ERRORMSG_INVALID_ARGS[] PROGMEM = "Invalid args"; const char ERRORMSG_INVALID_MODE[] PROGMEM = "Invalid mode"; const char ERRORMSG_INVALID_PIN[] PROGMEM = "Invalid pin"; const char ERRORMSG_INVALID_DEVICE[] PROGMEM = "Invalid device id"; static const char ERRORMSG_UNKNOWN_CMDID[] PROGMEM = "Unknown cmdID"; const char * OctaveLibraryBase::getLibraryName () const { return libName.c_str (); } void OctaveLibraryBase::setup () { } void OctaveLibraryBase::loop () { } void OctaveLibraryBase::commandHandler(byte cmdID, byte* inputs, unsigned int payload_size) { commandHandler((uint8_t)cmdID, (uint8_t*)inputs, (uint8_t)payload_size); } void OctaveLibraryBase::commandHandler(uint8_t cmdID, uint8_t* inputs, uint8_t payload_size) { sendErrorMsg_P(ERRORMSG_UNIMPLEMENTED); } void OctaveLibraryBase::sendResponseMsg (uint8_t cmdID, const uint8_t *data, uint8_t sz) { #if defined(OCTAVE_USE_WIFI_COMMS) if(wifi_status == 1) { wifi_client.write ((uint8_t)ARDUINO_SOH); wifi_client.write ((uint8_t)id); wifi_client.write (cmdID); wifi_client.write (sz); if(sz) { wifi_client.write (data, sz); } } #else OCTAVE_COMMS_PORT.write ((uint8_t)ARDUINO_SOH); OCTAVE_COMMS_PORT.write ((uint8_t)id); OCTAVE_COMMS_PORT.write (cmdID); OCTAVE_COMMS_PORT.write (sz); if(sz) { OCTAVE_COMMS_PORT.write (data, sz); } // flush appears to lockup port in some devices //OCTAVE_COMMS_PORT.flush (); #endif } void OctaveLibraryBase::sendWaitMsg () { sendResponseMsg (ARDUINO_WAIT, NULL, 0); } void OctaveLibraryBase::sendErrorMsg (const char *err) { // work out len to max 200 int len = 0; while(err[len] != '\0' && len < 200) len++; sendResponseMsg (ARDUINO_ERROR, (uint8_t *)err, len); } void OctaveLibraryBase::debugPrint (const char *err, ...) { char buffer[201]; va_list args; va_start (args, err); vsnprintf (buffer,200,err, args); va_end (args); // work out len to max 200 int len = 0; while(buffer[len] != '\0' && len < 200) len++; sendResponseMsg (ARDUINO_DEBUG, (uint8_t *)buffer, len); } void OctaveLibraryBase::sendResponseMsg_P (uint8_t cmdID, const uint8_t *data PROGMEM, uint8_t sz) { char tmp[256]; for (int i=0;i<sz;i++) { tmp[i] = pgm_read_byte_near (data+i); } sendResponseMsg (cmdID, (uint8_t *)tmp, sz); } void OctaveLibraryBase::sendErrorMsg_P (const char *err PROGMEM) { // work out len to max 200 char tmp[200]; int ch; int len = 0; ch = pgm_read_byte_near (err); while (ch != '\0' && len < 200) { tmp[len] = ch; len ++; ch = pgm_read_byte_near(err+len); } sendResponseMsg (ARDUINO_ERROR, (uint8_t *)tmp, len); } void OctaveLibraryBase::sendUnknownCmdIDMsg () { sendErrorMsg_P (ERRORMSG_UNKNOWN_CMDID); } void OctaveLibraryBase::sendInvalidNumArgsMsg () { sendErrorMsg_P (ERRORMSG_INVALID_NUMBER_OF_ARGS); } OctaveArduinoClass::OctaveArduinoClass () { for (int i=0;i<MAX_ARDUINO_LIBS;i++) libs[i] = 0; libcount = 0; msg_state = STATE_SOH; } const char * OctaveArduinoClass::getLibName (uint8_t idx) const { if (idx < libcount) { return libs[idx]->libName.c_str (); } return ""; } uint8_t OctaveArduinoClass::registerLibrary (LibraryBase *lib) { if (libcount < MAX_ARDUINO_LIBS) { lib->id = libcount; libs[libcount] = lib; libcount ++; return libcount-1; } return 255; } uint8_t OctaveArduinoClass::processMessage (uint8_t libid, uint8_t cmd, uint8_t *data, uint8_t sz) { if (libid >= MAX_ARDUINO_LIBS || libs[libid] == 0) { if(libcount > 0) libs[0]->sendErrorMsg_P(ERRORMSG_UNIMPLEMENTED); } else { libs[libid]->commandHandler((byte)cmd, (byte *)data, (unsigned int)sz); return 1; } return 0; } #if defined(WIFI_STATIC_IP) static int get_ip_parts(const char *str, uint8_t parts[4]) { uint8_t i = 0; uint8_t o = 0; while(str[i] != '\0') { if(str[i] == '.') { o ++; if(o < 4) parts[o] = 0; } if(str[i] >= '0' && str[i] <= '9') { if(o < 4) parts[o] = parts[o]*10 + (str[i] - '0'); } i++; } return o; } static IPAddress make_ip_address(const char *str) { uint8_t parts[4]; get_ip_parts(str, parts); return IPAddress(parts[0], parts[1], parts[2], parts[3]); } static IPAddress make_gateway_address(const char *str) { uint8_t parts[4]; get_ip_parts(str, parts); return IPAddress(parts[0], parts[1], parts[2], 1); } #endif void OctaveArduinoClass::init () { OCTAVE_COMMS_PORT.begin (ARDUINO_BAUDRATE); #if defined(OCTAVE_USE_WIFI_COMMS) #ifdef ARDUINO_ARCH_ESP32 WiFi.begin(wifi_ssid, wifi_pass); #endif while(!OCTAVE_COMMS_PORT) {} #if defined(WIFI_STATIC_IP) #ifdef ARDUINO_ARCH_ESP32 WiFi.config(make_ip_address(WIFI_STATIC_IP), make_gateway_address(WIFI_STATIC_IP), IPAddress(255, 255, 0, 0)); #else WiFi.config(make_ip_address(WIFI_STATIC_IP)); #endif #endif while (wifi_status != WL_CONNECTED) { OCTAVE_COMMS_PORT.println("Attempting to connect to nework..."); ///Serial.println(ssid); // Connect to WPA/WPA2 network. Change this line if using open or WEP network: wifi_status = WiFi.begin(wifi_ssid, wifi_pass); // wait 5 seconds for connection: delay(5000); } // show some info about our connection OCTAVE_COMMS_PORT.println("Connected to network"); OCTAVE_COMMS_PORT.print("SSID: "); OCTAVE_COMMS_PORT.println(WiFi.SSID()); // print your WiFi shield's IP address: IPAddress ip = WiFi.localIP(); OCTAVE_COMMS_PORT.print("IP Address: "); OCTAVE_COMMS_PORT.println(ip); // print the received signal strength: long rssi = WiFi.RSSI(); OCTAVE_COMMS_PORT.print("signal strength (RSSI):"); OCTAVE_COMMS_PORT.print(rssi); OCTAVE_COMMS_PORT.println(" dBm"); wifi_status = 0; wifiServer.begin(); #endif for (int i=0; i<libcount; i++) { libs[i]->setup (); } } void OctaveArduinoClass::runLoop() { int ch; #if defined(OCTAVE_USE_WIFI_COMMS) WiFiClient client = wifiServer.available(); if(client.connected()) { //wifi_client = wifiServer.available(); wifi_client = client; if(wifi_status == 0) { OCTAVE_COMMS_PORT.println("Connected"); wifi_status = 1; } } else if(wifi_status == 1 && !wifi_client.connected()) { OCTAVE_COMMS_PORT.println("Disconnected"); wifi_status = 0; } while(wifi_status == 1 && wifi_client.available()) { ch = wifi_client.read(); #else if (OCTAVE_COMMS_PORT.available()) { ch = OCTAVE_COMMS_PORT.read(); #endif switch (msg_state) { case STATE_SOH: msg_hdr[STATE_SOH] = ch; if (ch == ARDUINO_SOH) msg_state = STATE_EXT; break; case STATE_EXT: msg_hdr[STATE_EXT] = ch; msg_state = STATE_CMD; break; case STATE_CMD: msg_hdr[STATE_CMD] = ch; msg_state = STATE_SIZE; break; case STATE_SIZE: msg_hdr[STATE_SIZE] = ch; msg_datapos = 0; if (ch > 0) msg_state = STATE_DATA; else msg_state = STATE_EOM; break; case STATE_DATA: if (msg_datapos < sizeof(msg_data)) msg_data[msg_datapos] = ch; msg_datapos ++; if (msg_datapos == msg_hdr[STATE_SIZE]) msg_state = STATE_EOM; break; default: msg_state = STATE_SOH; break; } if(msg_state == STATE_EOM) { msg_state = STATE_SOH; processMessage (msg_hdr[STATE_EXT], msg_hdr[STATE_CMD], msg_data, msg_hdr[STATE_SIZE]); } } for (int i=0; i<libcount; i++) { libs[i]->loop(); } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/lib/LibraryBase.h����������������������������������������������������0000644�0000000�0000000�00000005750�14777724260�016351� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Octave arduino library interface * Copyright (C) 2018-2022 John Donoghue <john.donoghue@ieee.org> * * 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 <https://www.gnu.org/licenses/>. */ #ifndef OCTAVE_LIBRARY_BASE_H #define OCTAVE_LIBRARY_BASE_H #include <Arduino.h> #define VERSION_MAJOR 0 #define VERSION_MINOR 12 #define VERSION_PATCH 2 #if defined(ARDUINO_SAM_DUE) # define OCTAVE_COMMS_PORT SERIAL_PORT_MONITOR #elif defined(SERIAL_PORT_USBVIRTUAL) // sparkfun samed21 dev/mini # define OCTAVE_COMMS_PORT SERIAL_PORT_USBVIRTUAL #elif defined(SERIAL_PORT_MONITOR) # define OCTAVE_COMMS_PORT SERIAL_PORT_MONITOR #else # define OCTAVE_COMMS_PORT Serial #endif class OctaveLibraryBase { public: String libName; int id; virtual void commandHandler(uint8_t cmdID, uint8_t* inputs, uint8_t payload_size); // matlab compatability virtual void commandHandler(byte cmdID, byte* inputs, unsigned int payload_size); virtual void setup(); virtual void loop(); const char * getLibraryName() const; #define ARDUINO_ERROR 255 #define ARDUINO_WAIT 254 #define ARDUINO_DEBUG 253 void sendResponseMsg(uint8_t cmdID, const uint8_t *data, uint8_t sz); void sendResponseMsg_P(uint8_t cmdID, const uint8_t *data PROGMEM, uint8_t sz); void sendErrorMsg(const char *msg); void sendErrorMsg_P(const char *msg PROGMEM); void sendUnknownCmdIDMsg(); void sendInvalidNumArgsMsg(); void sendWaitMsg(); void debugPrint(const char *, ...); }; typedef OctaveLibraryBase LibraryBase; class OctaveArduinoClass { uint8_t msg_state; uint8_t msg_datapos; uint8_t msg_hdr[4]; uint8_t msg_data[256]; #define MAX_ARDUINO_LIBS 20 int libcount; OctaveLibraryBase *libs[MAX_ARDUINO_LIBS]; public: OctaveArduinoClass(); uint8_t registerLibrary(LibraryBase *lib); int getLibCount() const { return libcount; } const char * getLibName(uint8_t idx) const; void init(); void runLoop(); private: uint8_t processMessage(uint8_t libid, uint8_t cmd, uint8_t *data, uint8_t sz); }; // for matlab compatability typedef OctaveArduinoClass MWArduinoClass; // error strings extern const char ERRORMSG_INVALID_NUMBER_OF_ARGS[] PROGMEM; extern const char ERRORMSG_INVALID_ARGS[] PROGMEM; extern const char ERRORMSG_INVALID_MODE[] PROGMEM; extern const char ERRORMSG_INVALID_PIN[] PROGMEM; extern const char ERRORMSG_UNIMPLEMENTED[] PROGMEM; extern const char ERRORMSG_INVALID_DEVICE[] PROGMEM; #endif // OCTAVE_LIBRARY_BASE_H ������������������������arduino-0.12.2/inst/+arduinoio/lib/OctaveCoreLibrary.cpp��������������������������������������������0000644�0000000�0000000�00000024053�14777724260�020061� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Octave arduino core interface * Copyright (C) 2018-2019 John Donoghue <john.donoghue@ieee.org> * * 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 <https://www.gnu.org/licenses/>. */ #include "settings.h" #include "OctaveCoreLibrary.h" #if defined(ARDUINO_ARCH_ESP32) && ! defined(ARDUINO_NANO_ESP32) // contains analogWrite #include <ESP32Servo.h> #endif #define ARDUINO_RESET 0 #define ARDUINO_INIT 1 #define ARDUINO_CONFIGPIN 2 #define ARDUINO_DIGITAL 3 #define ARDUINO_ANALOG 4 #define ARDUINO_PWM 5 #define ARDUINO_PLAYTONE 6 #define ARDUINO_GETLIB 8 #define ARDUINO_VERSION 20 #define ARDUINO_UPTIME 21 // endian flag #define ARDUINO_LITTLEENDIAN 0x00 #define ARDUINO_BIGENDIAN 0x80 #define ARDUINO_ENDIAN ARDUINO_LITTLEENDIAN // TODO: how know what board we are ??? //compiler provides something like: // -DF_CPU=16000000L -DARDUINO=10805 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR // freq ide ver board arch #if defined(ARDUINO_AVR_UNO) #define BOARD_ID 0 #elif defined(ARDUINO_AVR_MEGA2560) #define BOARD_ID 1 #elif defined(ARDUINO_AVR_NANO) #define BOARD_ID 2 #elif defined(ARDUINO_AVR_UNO_WIFI_REV2) #define BOARD_ID 5 #elif defined(ARDUINO_AVR_NANO_EVERY) #define BOARD_ID 6 #elif defined(ARDUINO_AVR_LILYPAD) #define BOARD_ID 10 #elif defined(ARDUINO_AVR_PRO) #define BOARD_ID 20 #elif defined(ARDUINO_AVR_PROMICRO) #define BOARD_ID 21 #elif defined(ARDUINO_AVR_LEONARDO) #define BOARD_ID 22 #elif defined(ARDUINO_AVR_MICRO) #define BOARD_ID 23 #elif defined(ARDUINO_SAMD_ZERO) // sparkfun samed21 dev/mini #if USB_VID == 0x1B4F && USB_PID == 0x8D21 #define BOARD_ID 41 #else // Arduino Zero #define BOARD_ID 40 #endif #elif defined(ARDUINO_SAM_DUE) #define BOARD_ID 45 #define NUM_TOTAL_PINS PINS_COUNT #elif defined(ARDUINO_SAMD_MKRZERO) #define BOARD_ID 50 #define NUM_TOTAL_PINS 33 #elif defined(ARDUINO_SAMD_MKR1000) #define BOARD_ID 51 #define NUM_TOTAL_PINS 30 #elif defined(ARDUINO_ARDUINO_NANO33BLE) #define BOARD_ID 60 #define NUM_TOTAL_PINS 34 #elif defined(ARDUINO_RASPBERRY_PI_PICO) #define BOARD_ID 100 #ifndef ARDUINO_ARCH_MBED #error "Expected mbed architechture" #endif #elif defined(ARDUINO_NANO_RP2040_CONNECT) #define BOARD_ID 101 #define BOARD_VOLTAGE 33 #ifndef ARDUINO_ARCH_MBED #error "Expected mbed architechture" #endif #elif defined(ARDUINO_NANO_ESP32) #define BOARD_ID 102 #define BOARD_VOLTAGE 33 #elif defined(ARDUINO_ESP32_DEV) #define BOARD_ID 111 #define BOARD_VOLTAGE 33 #elif defined(ARDUINO_UNOR4_WIFI) #define BOARD_ID 112 #elif defined(ARDUINO_UNOR4_MINIMA) #define BOARD_ID 113 #else #error "Unknown board type" #endif // board voltage = actualV*10 #ifndef BOARD_VOLTAGE #if defined(ARDUINO_ARCH_SAMD) || defined (ARDUINO_ARCH_NRF52840) || defined (ARDUINO_ARCH_SAM) || defined (ARDUINO_ARCH_RP2040) #define BOARD_VOLTAGE 33 #elif defined(ARDUINO_AVR_PRO) || defined(ARDUINO_AVR_PROMICRO) #if F_CPU == 8000000L #define BOARD_VOLTAGE 33 #else #define BOARD_VOLTAGE 50 #endif #else #define BOARD_VOLTAGE 50 #endif #endif static const int8_t map_config_mode[] PROGMEM = { INPUT, // unset INPUT, // analoginput INPUT, // dig in OUTPUT, // dig out INPUT_PULLUP, // pullup INPUT_PULLUP, //-1, // i2c TODO: ?? OUTPUT, // pwm OUTPUT, // servo OUTPUT, // spi TODO ? INPUT, // interrupt -1, // reserved }; int get_mode(uint8_t m) { if (m < sizeof (map_config_mode)) { return pgm_read_byte_near (map_config_mode + m); } return INPUT; } #define pinToAnalog(a) (a < A0 ? 0 : a-A0) #ifndef NUM_TOTAL_PINS #define NUM_TOTAL_PINS NUM_DIGITAL_PINS #endif //#ifdef UNO_WIFI_REV2_328MODE // #error ("Uno wifi firmware must be compiled without a 328 emultaion enabled") //#endif static uint8_t pinconfig[NUM_TOTAL_PINS]; #if defined (ARDUINO_ARCH_AVR) || defined (ARDUINO_ARCH_MEGAAVR) #include <avr/wdt.h> void reset () { wdt_enable (WDTO_1S); while(1) {} } #elif defined (ARDUINO_ARCH_SAMD) || defined (ARDUINO_ARCH_NRF52840) || defined (ARDUINO_ARCH_SAM) || defined (ARDUINO_ARCH_RP2040) || defined(ARDUINO_ARCH_RENESAS) void reset () { // processor software reset NVIC_SystemReset (); } #elif defined (ARDUINO_ARCH_ESP32) void reset () { ESP.restart (); } #else #error("Unimplemented architecture for reset") #endif OctaveCoreLibrary::OctaveCoreLibrary (OctaveArduinoClass &oc) : occlass (oc) { libName = "Core"; oc.registerLibrary (this); // set pins as not set for(unsigned int i = 0; i<NUM_TOTAL_PINS; i++) { pinconfig[i] = 0xff; } } void OctaveCoreLibrary::commandHandler (uint8_t cmdID, uint8_t* data, uint8_t datasz) { int val; switch (cmdID) { case ARDUINO_RESET: sendResponseMsg (cmdID, 0, 0); reset (); break; case ARDUINO_INIT: // ** NOTE ** DO NOT use debugPrint in the init routine #if defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_MEGAAVR) data[0] = SIGNATURE_0; data[1] = SIGNATURE_1; data[2] = SIGNATURE_2; #elif defined (ARDUINO_ARCH_SAMD) || defined (ARDUINO_ARCH_NRF52840) || defined (ARDUINO_ARCH_SAM) // allow the config file to supply the mcu data[0] = 0; data[1] = 0; data[2] = 0; #else data[0] = 0; data[1] = 0; data[2] = 0; #endif data[3] = BOARD_ID; data[4] = BOARD_VOLTAGE; data[5] = occlass.getLibCount (); // flags // if anything is big endian, 0x80 data[6] = ARDUINO_ENDIAN | 0; sendResponseMsg (cmdID, data, 7); break; case ARDUINO_GETLIB: { if(datasz != 1) { sendInvalidNumArgsMsg (); } else { // lib idx // populate data[1]... with lib name datasz = 0; const char * name = occlass.getLibName (data[0]); while (name[datasz] != '\0' && datasz < 254) { data[datasz+1] = name[datasz]; datasz++; } sendResponseMsg (cmdID, data, datasz+1); } break; } case ARDUINO_CONFIGPIN: if (datasz == 1 && data[0] < NUM_TOTAL_PINS) { data[1] = pinconfig[data[0]]; // TODO: get mode somehow ???? sendResponseMsg (cmdID, data, 2); } else if (datasz == 2 && data[1] >= sizeof(map_config_mode)) { sendErrorMsg_P (ERRORMSG_INVALID_MODE); } else if (datasz >= 1 && data[0] >= NUM_TOTAL_PINS) { sendErrorMsg_P (ERRORMSG_INVALID_PIN); } else if (datasz == 2 && data[0] < NUM_TOTAL_PINS && data[1] < sizeof(map_config_mode)) { int mode = get_mode (data[1]); pinconfig[data[0]] = data[1]; if (mode != -1) { pinMode (data[0], mode); } sendResponseMsg (cmdID, data, 0); } else { sendInvalidNumArgsMsg (); } break; case ARDUINO_DIGITAL: if (datasz == 1) { val = digitalRead (data[0]); if (val == HIGH) data[1] = 1; else data[1] = 0; sendResponseMsg (cmdID, data, 2); } else if (datasz == 2) { digitalWrite (data[0], data[1] ? HIGH : LOW); sendResponseMsg (cmdID, data, 0); } else { sendInvalidNumArgsMsg (); } break; case ARDUINO_ANALOG: if (datasz == 1) { val = analogRead (pinToAnalog(data[0])); data[1] = (val>>8)&0xff; data[2] = (val)&0xff; sendResponseMsg (cmdID, data, 3); } else { sendInvalidNumArgsMsg (); } break; case ARDUINO_PWM: if (datasz == 2) { analogWrite (data[0], data[1]); sendResponseMsg (cmdID, data, 0); } else { sendInvalidNumArgsMsg (); } break; case ARDUINO_PLAYTONE: if (datasz == 5) { #if defined(ARDUINO_SAM_DUE) sendErrorMsg_P (ERRORMSG_UNIMPLEMENTED); #else // 0 = pin // 1 = freqh // 2 = freql (hz) // 3 = durh // 4 = durl (10ths of second) unsigned long duration = (((unsigned long)(data[3]))<<8 | data[4]) * 100; unsigned int freq = (((unsigned int)(data[1]))<<8 | data[2]); if (freq == 0) noTone (data[0]); else tone (data[0], freq, duration); sendResponseMsg (cmdID, data, 0); #endif } else { sendInvalidNumArgsMsg (); } break; case ARDUINO_VERSION: { data[0] = VERSION_MAJOR; data[1] = VERSION_MINOR; data[2] = VERSION_PATCH; sendResponseMsg (cmdID, data, 3); } break; case ARDUINO_UPTIME: { unsigned long t = millis (); data[0] = (t>>24)&0xff; data[1] = (t>>16)&0xff; data[2] = (t>>8)&0xff; data[3] = (t>>0)&0xff; sendResponseMsg (cmdID, data, 4); } break; default: sendUnknownCmdIDMsg (); break; } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/lib/OctaveCoreLibrary.h����������������������������������������������0000644�0000000�0000000�00000001741�14777724260�017525� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Octave arduino core interface * Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> * * 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 <https://www.gnu.org/licenses/>. */ #include "LibraryBase.h" class OctaveCoreLibrary : public LibraryBase { OctaveArduinoClass &occlass; public: OctaveCoreLibrary(OctaveArduinoClass &oc); void commandHandler(uint8_t cmdID, uint8_t* inputs, uint8_t payload_size); }; �������������������������������arduino-0.12.2/inst/+arduinoio/lib/OctaveI2CLibrary.cpp���������������������������������������������0000644�0000000�0000000�00000027046�14777724260�017553� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Octave arduino i2c interface * Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> * * 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 <https://www.gnu.org/licenses/>. */ #include "settings.h" #include "OctaveI2CLibrary.h" #define ARDUINO_SCANI2C 0 #define ARDUINO_CONFIGI2C 1 // replaces below as diff data format //#define ARDUINO_WRITEI2C 2 //#define ARDUINO_READI2C 3 //#define ARDUINO_WRITEI2CREG 4 //#define ARDUINO_READI2CREG 5 // new ids as new data #define ARDUINO_WRITEI2C 6 #define ARDUINO_READI2C 7 #define ARDUINO_WRITEI2CREG 8 #define ARDUINO_READI2CREG 9 #ifdef USE_I2C #include <Wire.h> static uint8_t i2c_enabled[2] = { false, false }; static uint8_t i2c_address = 0; #if !defined(WIRE_INTERFACES_COUNT) # if defined(ARDUINO_ARDUINO_NANO33BLE) # define WIRE_INTERFACES_COUNT 2 # else # if defined(WIRE_HOWMANY) # define WIRE_INTERFACES_COUNT WIRE_HOWMANY # else # define WIRE_INTERFACES_COUNT 1 # endif # endif #endif #if !defined(ARDUINO_ARCH_ESP32) #define I2C_SUPPORTS_ENDCALL 1 #endif #endif OctaveI2CLibrary::OctaveI2CLibrary (OctaveArduinoClass &oc) { libName = "I2C"; oc.registerLibrary (this); } void OctaveI2CLibrary::commandHandler (uint8_t cmdID, uint8_t* data, uint8_t datasz) { switch (cmdID) { #ifdef USE_I2C case ARDUINO_WRITEI2C: case ARDUINO_WRITEI2CREG: { if (datasz < 3 || datasz > 32) { // bus // address // data sendInvalidNumArgsMsg (); } else { if (data[0] >= WIRE_INTERFACES_COUNT || data[0] > 1) { sendErrorMsg_P (ERRORMSG_INVALID_DEVICE); return; } if (data[0] == 0) { Wire.beginTransmission (data[1]); // should be i2c_address byte c; for(c=2;c<datasz;c++) Wire.write (data[c]); Wire.endTransmission (); } #if WIRE_INTERFACES_COUNT > 1 if (data[0] == 1) { Wire1.beginTransmission (data[1]); // should be i2c_address byte c; for(c=2;c<datasz;c++) Wire1.write (data[c]); Wire1.endTransmission (); } #endif data[1] = 1; sendResponseMsg (cmdID,data, 2); } break; } case ARDUINO_READI2C: { if (datasz != 3) { // bus // address // numbytes sendInvalidNumArgsMsg (); } else { if (data[0] >= WIRE_INTERFACES_COUNT || data[0] > 1) { sendErrorMsg_P (ERRORMSG_INVALID_DEVICE); return; } if (data[0] == 0) { Wire.requestFrom (data[1], (size_t)data[2]); byte c = 0; byte l = data[2]; if (l > 5) sendWaitMsg (); datasz = 1; for (c=0;c<=l;c++) { if (Wire.available ()) { data[datasz] = Wire.read (); datasz ++; } } } #if WIRE_INTERFACES_COUNT > 1 if (data[0] == 1) { Wire1.requestFrom (data[1], (size_t)data[2]); byte c = 0; byte l = data[2]; if (l > 5) sendWaitMsg (); datasz = 1; for (c=0;c<=l;c++) { if (Wire1.available ()) { data[datasz] = Wire1.read (); datasz ++; } } } #endif sendResponseMsg (cmdID,data, datasz); } break; } case ARDUINO_READI2CREG: { if (datasz < 5) { // bus // address // regsz // reg // numbytes sendInvalidNumArgsMsg (); } else if (datasz != data[2]+4) { sendInvalidNumArgsMsg (); } else { if (data[0] >= WIRE_INTERFACES_COUNT || data[0] > 1) { sendErrorMsg_P (ERRORMSG_INVALID_DEVICE); return; } if (data[0] == 0) { Wire.beginTransmission (data[1]); byte c = 0; for (c=0;c<data[2];c++) { Wire.write (data[3+c]); } Wire.endTransmission (false); byte l = data[3+data[2]]; Wire.requestFrom (data[1], (size_t)l); if(l > 5) sendWaitMsg (); datasz = 2; for (c=0;c<=l;c++) { if (Wire.available ()) { data[datasz] = Wire.read (); datasz ++; } } } #if WIRE_INTERFACES_COUNT > 1 if (data[0] == 1) { Wire1.beginTransmission (data[1]); byte c = 0; for (c=0;c<data[2];c++) { Wire1.write (data[3+c]); } Wire1.endTransmission (false); byte l = data[3+data[2]]; Wire1.requestFrom (data[1], (size_t)l); if(l > 5) sendWaitMsg (); datasz = 2; for (c=0;c<=l;c++) { if (Wire1.available ()) { data[datasz] = Wire1.read (); datasz ++; } } } #endif sendResponseMsg (cmdID,data, datasz); } break; } case ARDUINO_SCANI2C: { if (datasz != 2) { sendInvalidNumArgsMsg (); } else { byte error = 1; // bus 0 // address if (data[0] >= WIRE_INTERFACES_COUNT || data[0] > 1) { sendErrorMsg_P (ERRORMSG_INVALID_DEVICE); return; } if (!i2c_enabled[data[0]]) { if(data[0] == 0) Wire.begin (); #if WIRE_INTERFACES_COUNT > 1 if(data[0] == 1) Wire1.begin (); #endif } if (data[0] == 0) { Wire.beginTransmission (data[1]); error = Wire.endTransmission (); } #if WIRE_INTERFACES_COUNT > 1 if (data[0] == 1) { Wire1.beginTransmission (data[1]); error = Wire1.endTransmission (); } #endif if (error == 0) data[2] = 1; else data[2] = 0; if (!i2c_enabled[data[0]]) { #if defined (I2C_SUPPORTS_ENDCALL) if(data[0] == 0) Wire.end (); # if WIRE_INTERFACES_COUNT > 1 if(data[0] == 1) Wire1.end (); # endif #endif } sendResponseMsg (cmdID, data, 3); } break; } case ARDUINO_CONFIGI2C: { if (datasz == 2 || datasz == 3 || datasz == 5) { // i2c bus 0 // enable 1 // i2caddress (optional) // bitratehi // birtarelo if (data[0] >= WIRE_INTERFACES_COUNT || data[0] > 1) { sendErrorMsg_P (ERRORMSG_INVALID_DEVICE); return; } // enable if (data[1] == 1) { i2c_enabled[data[0]] = 1; if (data[0] == 0) { // TODO: i dont think need any more as setting i2c as pullup inputs before making it i2c #if defined(ARDUINO_AVR_NANO_EVERY) || defined (ARDUINO_NANO_RP2040_CONNECT) // arduino every A4,A5 pin is connected to 2 pins each on the micro controller // so need ensure that the non I2C pins are pulled hi so doesnt effect the i2c pins pinMode(18, INPUT_PULLUP); pinMode(19, INPUT_PULLUP); #endif } if (datasz>= 3) i2c_address = data[2]; else i2c_address = 0; if (data[0] == 0) { if (i2c_address > 0) Wire.begin (i2c_address); else Wire.begin (); if (datasz == 5) { int32_t bitrate = (((uint32_t)data[3])<<8) | ((uint32_t)data[4]); Wire.setClock (bitrate*1000L); } } #if WIRE_INTERFACES_COUNT > 1 if (data[0] == 1) { if (i2c_address > 0) Wire1.begin (i2c_address); else Wire1.begin (); if (datasz == 5) { int32_t bitrate = (((uint32_t)data[3])<<8) | ((uint32_t)data[4]); Wire1.setClock (bitrate*1000L); } } #endif } else { // disable #if defined (I2C_SUPPORTS_ENDCALL) if (data[0] == 0) Wire.end (); # if WIRE_INTERFACES_COUNT > 1 if (data[0] == 1) Wire1.end (); # endif #endif i2c_enabled[data[0]] = 0; } sendResponseMsg (cmdID, data, datasz); } else if (datasz == 1) { // query config of device // i2c id // enable // address if (data[0] >= WIRE_INTERFACES_COUNT || data[0] > 1) { sendErrorMsg_P (ERRORMSG_INVALID_DEVICE); return; } data[1] = i2c_enabled[data[0]]; data[2] = i2c_address; sendResponseMsg (cmdID,data, 3); } else { sendInvalidNumArgsMsg (); } break; } #endif default: sendUnknownCmdIDMsg (); break; } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/lib/OctaveI2CLibrary.h�����������������������������������������������0000644�0000000�0000000�00000001677�14777724260�017222� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Octave arduino i2c interface * Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> * * 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 <https://www.gnu.org/licenses/>. */ #include "LibraryBase.h" class OctaveI2CLibrary : public LibraryBase { public: OctaveI2CLibrary(OctaveArduinoClass &oc); void commandHandler(uint8_t cmdID, uint8_t* inputs, uint8_t payload_size); }; �����������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/lib/OctaveRotaryEncoderLibrary.cpp�����������������������������������0000644�0000000�0000000�00000015362�14777724260�021754� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Octave arduino encoder interface * Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> * * 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 <https://www.gnu.org/licenses/>. */ #include "settings.h" #include "OctaveRotaryEncoderLibrary.h" #define ARDUINO_RESET_ENCODER 0 #define ARDUINO_CONFIG_ENCODER 1 #define ARDUINO_READPOS_ENCODER 2 #define ARDUINO_READSPEED_ENCODER 3 #ifdef USE_ROTARYENCODER static const char ERRORMSG_CANT_READ[] PROGMEM = "Max encoder reached"; static int8_t enc_states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0}; #define MAX_ROTARYENCODERS 8 class RotaryEncoder { #define USED 1 #define POLL 2 public: uint8_t flags; uint8_t pins[2]; int16_t cnt; int16_t oldcnt; uint16_t speed; uint8_t state; RotaryEncoder(); uint8_t init (uint8_t p1, uint8_t p2); uint8_t free() { flags = 0; return 0;} uint16_t readCount (); uint16_t readSpeed (); uint8_t resetCount (uint8_t h=0, uint8_t l=0); void poll (); void process (unsigned long diff); }; RotaryEncoder::RotaryEncoder () { flags = 0; } uint8_t RotaryEncoder::init (uint8_t p1, uint8_t p2) { flags = USED | POLL; state = 0; cnt = 0; oldcnt = 0; pins[0] = p1; pins[1] = p2; pinMode (pins[0], INPUT); digitalWrite (pins[0], HIGH); pinMode (pins[1], INPUT); digitalWrite (pins[1], HIGH); return 0; } uint16_t RotaryEncoder::readCount () { return cnt; } uint16_t RotaryEncoder::readSpeed () { return speed; } uint8_t RotaryEncoder::resetCount (uint8_t h, uint8_t l) { uint16_t v= ((uint16_t)h)<<8 | l; cnt = (int16_t)v; oldcnt = cnt; return 0; } void RotaryEncoder::poll () { // get curr state and prev state - gives 16 possible outcomes // wheich can then do a lookup table for detection state = (state<<2) | (digitalRead(pins[1]) ? 2 : 0) | (digitalRead(pins[0]) ? 1 : 0); int8_t dir = enc_states[state&0xf]; if(dir < 0 && cnt > -32000) cnt += dir; if(dir > 0 && cnt < 32000) cnt += dir; } void RotaryEncoder::process (unsigned long t) { //input millis long s = ((cnt - oldcnt) * 1000) / t; if(s < 0) s = -s; if(s > 32000) s = 32000; if(s != 0) speed = s; else if(speed > 0) speed --; oldcnt = cnt; } static RotaryEncoder encoders[MAX_ROTARYENCODERS]; RotaryEncoder * getRotaryEncoder (uint8_t id) { uint8_t i; RotaryEncoder * unused = 0; for (i=0;i<MAX_ROTARYENCODERS;i++) { if (encoders[i].flags) { if (encoders[i].pins[0] == id) return &encoders[i]; } else if (!unused) { unused = &encoders[i]; } } return unused; } #endif OctaveRotaryEncoderLibrary::OctaveRotaryEncoderLibrary (OctaveArduinoClass &oc) { libName = "RotaryEncoder"; oc.registerLibrary (this); } void OctaveRotaryEncoderLibrary::commandHandler (uint8_t cmdID, uint8_t* data, uint8_t datasz) { switch (cmdID) { #ifdef USE_ROTARYENCODER case ARDUINO_CONFIG_ENCODER: { // 0 = id/pina // 1 - enable/alloc // 2 = pinb RotaryEncoder * reg = getRotaryEncoder (data[0]); if (reg) { // alloc if (data[1] == 1 && datasz == 3) { reg->init(data[0], data[2]); sendResponseMsg (cmdID, data, 2); } // free else if (data[1] == 0 && reg->flags && datasz == 2) { reg->free (); sendResponseMsg (cmdID, data, 2); } else { sendErrorMsg_P (ERRORMSG_INVALID_ARGS); } } else { sendErrorMsg_P (ERRORMSG_INVALID_ARGS); } break; } case ARDUINO_RESET_ENCODER: { // 0 = id (currently using the datapin id) RotaryEncoder * reg = getRotaryEncoder(data[0]); if(reg && reg->flags) { data[1] = reg->resetCount (data[1], data[2]); sendResponseMsg (cmdID,data, 2); } else { sendErrorMsg_P (ERRORMSG_INVALID_ARGS); } break; } case ARDUINO_READPOS_ENCODER: { // 0 = id // 1 = reset flag RotaryEncoder * reg = getRotaryEncoder (data[0]); if(reg && reg->flags && datasz == 2) { uint16_t v = reg->readCount (); if (data[1] == 1) reg->resetCount(); data[1] = (v>>8)&0xff; data[2] = (v)&0xff; unsigned long t = millis (); data[3] = (t>>24)&0xff; data[4] = (t>>16)&0xff; data[5] = (t>>8)&0xff; data[6] = (t)&0xff; datasz = 7; sendResponseMsg (cmdID, data, datasz); } else { sendErrorMsg_P (ERRORMSG_INVALID_ARGS); } break; } case ARDUINO_READSPEED_ENCODER: { // 0 = id RotaryEncoder * reg = getRotaryEncoder (data[0]); if(reg && reg->flags && datasz == 1) { uint16_t v = reg->readSpeed (); datasz = 3; data[1] = (v>>8)&0xff; data[2] = (v)&0xff; sendResponseMsg (cmdID, data, datasz); } else { sendErrorMsg_P (ERRORMSG_INVALID_ARGS); } break; } #endif default: sendUnknownCmdIDMsg (); break; } } void OctaveRotaryEncoderLibrary::loop () { #ifdef USE_ROTARYENCODER static unsigned long speedtime = 0; unsigned long newtime; // any thing that needs poll for (int i=0; i<MAX_ROTARYENCODERS; i++) { RotaryEncoder *enc = &encoders[i]; if(enc->flags & POLL) { enc->poll(); } } // do any periodic processing newtime = millis(); if (speedtime < newtime) { unsigned long diff = (newtime - speedtime); if (diff > 50) { speedtime = newtime; for (int i=0; i<MAX_ROTARYENCODERS; i++) { RotaryEncoder *enc = &encoders[i]; if (enc->flags) enc->process(diff); } } } else if (speedtime > newtime) { speedtime = newtime; } #endif } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/lib/OctaveRotaryEncoderLibrary.h�������������������������������������0000644�0000000�0000000�00000001767�14777724260�021425� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Octave arduino shift register interface * Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> * * 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 <https://www.gnu.org/licenses/>. */ #include "LibraryBase.h" class OctaveRotaryEncoderLibrary : public LibraryBase { public: OctaveRotaryEncoderLibrary(OctaveArduinoClass &oc); void commandHandler(uint8_t cmdID, uint8_t* inputs, uint8_t payload_size); virtual void loop(); }; ���������arduino-0.12.2/inst/+arduinoio/lib/OctaveSPILibrary.cpp���������������������������������������������0000644�0000000�0000000�00000011407�14777724260�017623� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Octave arduino spi interface * Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> * * 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 <https://www.gnu.org/licenses/>. */ #include "settings.h" #include "OctaveSPILibrary.h" #define ARDUINO_CONFIGSPI 1 #define ARDUINO_READ_WRITE_SPI 2 #ifdef USE_SPI #include <SPI.h> class SPIDevice { #define USED 1 #define ENABLED 2 public: uint8_t flags; uint8_t cspin; uint8_t bitorder; uint8_t mode; SPIDevice(); uint8_t init(uint8_t id, uint8_t mode, uint8_t order); uint8_t free(); void set_cs(uint8_t state); int transfer(uint8_t *data, int sz); SPISettings settings(); }; SPIDevice::SPIDevice () { flags = 0; } uint8_t SPIDevice::init (uint8_t id, uint8_t spi_mode, uint8_t spi_bitorder) { flags = USED|ENABLED; cspin = id; if (spi_mode == 0) mode = SPI_MODE0; else if (spi_mode == 1) mode = SPI_MODE1; else if (spi_mode == 2) mode = SPI_MODE2; else if (spi_mode == 3) mode = SPI_MODE3; else mode = SPI_MODE0; bitorder = spi_bitorder; return 0; } uint8_t SPIDevice::free () { flags = 0; return 0; } void SPIDevice::set_cs(uint8_t state) { digitalWrite (cspin, state); } SPISettings SPIDevice::settings() { return SPISettings(4000000, bitorder==0 ? MSBFIRST : LSBFIRST , mode); } int SPIDevice::transfer (uint8_t *data, int sz) { SPI.transfer (data, sz); return 0; } #define MAX_SPI_DEVICES 5 static SPIDevice spidevs[MAX_SPI_DEVICES]; SPIDevice * getSPI (uint8_t id) { uint8_t i; SPIDevice * unused = 0; for (i=0; i<MAX_SPI_DEVICES; i++) { if (spidevs[i].flags & USED) { if (spidevs[i].cspin == id) return &spidevs[i]; } else if (!unused) { unused = &spidevs[i]; } } return unused; } #endif OctaveSPILibrary::OctaveSPILibrary (OctaveArduinoClass &oc) { libName = "SPI"; oc.registerLibrary (this); } void OctaveSPILibrary::commandHandler (uint8_t cmdID, uint8_t* data, uint8_t datasz) { switch (cmdID) { #ifdef USE_SPI case ARDUINO_CONFIGSPI: { if (datasz == 4) { // spi id 0 (cs pin) // enable 1 // mode ? 2 // byte order 3 // TODO: bit rate SPIDevice * dev = getSPI (data[0]); if(dev == 0) { sendErrorMsg_P (ERRORMSG_INVALID_DEVICE); return; } if (data[1] == 1) { // cspin mode bitorder dev->init(data[0], data[2], data[3]); // TODO: first call only ? SPI.begin (); dev->set_cs(HIGH); } else { // TODO: last call only // SPI.end (); dev->free(); } sendResponseMsg (cmdID,data, 2); } else if(datasz == 1) { SPIDevice * dev = getSPI (data[0]); if(dev == 0 || (dev->flags&USED)==0) { sendErrorMsg_P (ERRORMSG_INVALID_DEVICE); return; } // TODO: last call only // SPI.end (); dev->free(); } else { sendInvalidNumArgsMsg (); } break; } case ARDUINO_READ_WRITE_SPI: if (datasz >= 2) { SPIDevice * dev = getSPI (data[0]); if(dev == 0 || (dev->flags&USED)==0) { sendErrorMsg_P (ERRORMSG_INVALID_DEVICE); return; } // begin transaction SPI.beginTransaction (dev->settings()); // set CS low dev->set_cs(LOW); delay (1); // transfer the bytes dev->transfer(&data[1], datasz-1); // set CS hi dev->set_cs(HIGH); delay (1); // endtransaction SPI.endTransaction (); sendResponseMsg (cmdID, data, datasz); } else { sendInvalidNumArgsMsg (); } break; #endif default: sendUnknownCmdIDMsg (); break; } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/lib/OctaveSPILibrary.h�����������������������������������������������0000644�0000000�0000000�00000001677�14777724260�017300� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Octave arduino spi interface * Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> * * 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 <https://www.gnu.org/licenses/>. */ #include "LibraryBase.h" class OctaveSPILibrary : public LibraryBase { public: OctaveSPILibrary(OctaveArduinoClass &oc); void commandHandler(uint8_t cmdID, uint8_t* inputs, uint8_t payload_size); }; �����������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/lib/OctaveSerialLibrary.cpp������������������������������������������0000644�0000000�0000000�00000020470�14777724260�020407� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Octave arduino serial interface * Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> * * 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 <https://www.gnu.org/licenses/>. */ #include "settings.h" #include "OctaveSerialLibrary.h" #define ARDUINO_CONFIGSERIAL 1 #define ARDUINO_WRITESERIAL 2 #define ARDUINO_READSERIAL 3 #define ARDUINO_STATSERIAL 4 #ifdef USE_SERIAL #if defined(ARDUINO_AVR_NANO_EVERY) # ifndef SERIAL_PORT_HARDWARE_OPEN # define SERIAL_PORT_HARDWARE_OPEN SERIAL_PORT_HARDWARE # endif #endif #ifndef SERIAL_PORT_HARDWARE_OPEN #error "This device does not support the serial octave serial interface" #endif #if defined(ARDUINO_SAM_DUE) static USARTClass * serial[] = { #else static HardwareSerial * serial[] = { #endif #ifdef SERIAL_PORT_HARDWARE_OPEN1 0, #endif #ifdef SERIAL_PORT_HARDWARE_OPEN2 0, #endif #ifdef SERIAL_PORT_HARDWARE_OPEN3 0, #endif 0 }; #define NUM_SERIAL_PORTS (sizeof(serial)/sizeof(HardwareSerial*)) #endif OctaveSerialLibrary::OctaveSerialLibrary (OctaveArduinoClass &oc) { libName = "Serial"; oc.registerLibrary (this); } void OctaveSerialLibrary::setup () { #ifdef USE_SERIAL serial[0] = &SERIAL_PORT_HARDWARE_OPEN; #ifdef SERIAL_PORT_HARDWARE_OPEN1 serial[1] = &SERIAL_PORT_HARDWARE_OPEN1; #endif #ifdef SERIAL_PORT_HARDWARE_OPEN2 serial[2] = &SERIAL_PORT_HARDWARE_OPEN2; #endif #ifdef SERIAL_PORT_HARDWARE_OPEN3 serial[3] = &SERIAL_PORT_HARDWARE_OPEN3; #endif #endif OctaveLibraryBase::setup (); } void OctaveSerialLibrary::commandHandler (uint8_t cmdID, uint8_t* data, uint8_t datasz) { switch (cmdID) { #ifdef USE_SERIAL case ARDUINO_WRITESERIAL: { if (datasz < 2 || datasz > 32) { // id // data sendInvalidNumArgsMsg (); } else if (data[0] < 1 || data[0] > NUM_SERIAL_PORTS) { sendErrorMsg_P (ERRORMSG_INVALID_DEVICE); } else { uint8_t id = data[0]-1; serial[id]->write (&data[1], datasz-1); data[1] = 1; sendResponseMsg (cmdID, data, 2); } break; } case ARDUINO_READSERIAL: { if (datasz != 3) { // port // numbytes // timeout in 10th of second sendInvalidNumArgsMsg (); } else if (data[0] < 1 || data[0] > NUM_SERIAL_PORTS) { sendErrorMsg_P (ERRORMSG_INVALID_DEVICE); } else { uint8_t id = data[0]-1; uint8_t timeout = data[2]; byte c = 0; byte l = data[1]; // if have a timeout, try wait that time for enough data before returning if (timeout > 0) { sendWaitMsg (); unsigned long t = millis(); unsigned long e = t + timeout * 100; // 10th of a seconf to millis while (e > t && serial[id]->available() < l) { t = millis(); } } datasz = 1; for (c=0; c<l; c++) { if (serial[id]->available ()) { data[datasz] = serial[id]->read (); datasz ++; } } sendResponseMsg(cmdID,data, datasz); } break; } case ARDUINO_STATSERIAL: { if (datasz != 1) { // port sendInvalidNumArgsMsg (); } else if (data[0] < 1 || data[0] > NUM_SERIAL_PORTS) { sendErrorMsg_P (ERRORMSG_INVALID_DEVICE); } else { uint8_t id = data[0]-1; data[1] = serial[id]->available (); sendResponseMsg (cmdID, data, 2); } break; } case ARDUINO_CONFIGSERIAL: { if (datasz > 0 && (data[0] < 1 || data[0] > NUM_SERIAL_PORTS)) { sendErrorMsg_P(ERRORMSG_INVALID_DEVICE); } // enable else if (datasz == 9 && data[1] == 1) { uint8_t id = data[0]-1; // data[1] = enable uint32_t baud = ((uint32_t)data[2]<<24) | ((uint32_t)data[3]<<16) | ((uint32_t)data[4]<<8) | data[5]; #if defined(ARDUINO_SAM_DUE) || defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_SAMD_MKR1000) uint32_t conf = 0; #else uint8_t conf = 0; #endif // data[6] = databits // data[7] = stopbits // data[8] = parity if (data[8] == 2) // parity even { if (data[7] == 1) { switch (data[6]) { case 5: conf = SERIAL_5E1; break; case 6: conf = SERIAL_6E1; break; case 7: conf = SERIAL_7E1; break; default: conf = SERIAL_8E1; break; } } else // 2 stop bits { switch (data[6]) { case 5: conf = SERIAL_5E2; break; case 6: conf = SERIAL_6E2; break; case 7: conf = SERIAL_7E2; break; default: conf = SERIAL_8E2; break; } } } else if (data[8] == 1) // parity odd { if (data[7] == 1) { switch (data[6]) { case 5: conf = SERIAL_5O1; break; case 6: conf = SERIAL_6O1; break; case 7: conf = SERIAL_7O1; break; default: conf = SERIAL_8O1; break; } } else // 2 stop bits { switch (data[6]) { case 5: conf = SERIAL_5O2; break; case 6: conf = SERIAL_6O2; break; case 7: conf = SERIAL_7O2; break; default: conf = SERIAL_8O2; break; } } } else // parity none { if (data[7] == 1) { switch (data[6]) { case 5: conf = SERIAL_5N1; break; case 6: conf = SERIAL_6N1; break; case 7: conf = SERIAL_7N1; break; default: conf = SERIAL_8N1; break; } } else // 2 stop bits { switch (data[6]) { case 5: conf = SERIAL_5N2; break; case 6: conf = SERIAL_6N2; break; case 7: conf = SERIAL_7N2; break; default: conf = SERIAL_8N2; break; } } } #if defined(ARDUINO_SAM_DUE) serial[id]->begin (baud, (USARTClass::USARTModes)conf); #else serial[id]->begin (baud, conf); #endif sendResponseMsg (cmdID, data, 2); } // disable else if (datasz == 2 && data[1] == 0) { uint8_t id = data[0]-1; serial[id]->end (); sendResponseMsg (cmdID, data, 2); } else { sendInvalidNumArgsMsg (); } break; } #endif default: sendUnknownCmdIDMsg(); break; } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/lib/OctaveSerialLibrary.h��������������������������������������������0000644�0000000�0000000�00000001731�14777724260�020053� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Octave arduino serial interface * Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> * * 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 <https://www.gnu.org/licenses/>. */ #include "LibraryBase.h" class OctaveSerialLibrary : public LibraryBase { public: OctaveSerialLibrary(OctaveArduinoClass &oc); void setup(); void commandHandler(uint8_t cmdID, uint8_t* inputs, uint8_t payload_size); }; ���������������������������������������arduino-0.12.2/inst/+arduinoio/lib/OctaveServoLibrary.cpp�������������������������������������������0000644�0000000�0000000�00000004673�14777724260�020275� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Octave arduino servo interface * Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> * * 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 <https://www.gnu.org/licenses/>. */ #include "settings.h" #include "OctaveServoLibrary.h" #define ARDUINO_SERVO 0 #define ARDUINO_CONFIG_SERVO 1 #ifdef USE_SERVO // NOTE: if cant fint servo.h, you probally dont have the Servo library installed // go to Sketch -> Include Library -> Manage Libraries, and select 'Servo' // For ESP boards, it bwill need to be ESP32Servo # if defined(ARDUINO_ARCH_ESP32) #include <ESP32Servo.h> # else #include <Servo.h> # endif Servo servo[NUM_DIGITAL_PINS]; uint16_t servo_pos[NUM_DIGITAL_PINS]; #endif OctaveServoLibrary::OctaveServoLibrary (OctaveArduinoClass &oc) { libName = "Servo"; oc.registerLibrary (this); } void OctaveServoLibrary::commandHandler (uint8_t cmdID, uint8_t* data, uint8_t datasz) { switch (cmdID) { #ifdef USE_SERVO case ARDUINO_SERVO: if (datasz == 1) { uint16_t ms = servo_pos[data[0]]; data[1] = (ms>>8); data[2] = (ms&0xff); sendResponseMsg (cmdID, data, 3); } else if (datasz == 3) { uint16_t ms = ((int)data[1]<<8) | ((int)data[2]); servo_pos[data[0]] = ms; servo[data[0]].writeMicroseconds (ms); sendResponseMsg (cmdID, data, 1); } else { sendInvalidNumArgsMsg (); } break; case ARDUINO_CONFIG_SERVO: if (datasz > 0) { // pin // conf stuff ... ? servo[data[0]].attach (data[0]); sendResponseMsg (cmdID, data, 1); } else { sendInvalidNumArgsMsg (); } break; #endif default: sendUnknownCmdIDMsg (); break; } } ���������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/lib/OctaveServoLibrary.h���������������������������������������������0000644�0000000�0000000�00000001705�14777724260�017733� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Octave arduino servo interface * Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> * * 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 <https://www.gnu.org/licenses/>. */ #include "LibraryBase.h" class OctaveServoLibrary : public LibraryBase { public: OctaveServoLibrary(OctaveArduinoClass &oc); void commandHandler(uint8_t cmdID, uint8_t* inputs, uint8_t payload_size); }; �����������������������������������������������������������arduino-0.12.2/inst/+arduinoio/lib/OctaveShiftRegisterLibrary.cpp�����������������������������������0000644�0000000�0000000�00000025063�14777724260�021755� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Octave arduino shift register interface * Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> * * 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 <https://www.gnu.org/licenses/>. */ #include "settings.h" #include "OctaveShiftRegisterLibrary.h" #define ARDUINO_RESET_SHIFTREG 0 #define ARDUINO_CONFIG_SHIFTREG 1 #define ARDUINO_WRITE_SHIFTREG 2 #define ARDUINO_READ_SHIFTREG 3 #define TYPE_74HC164 0 // input p2s #define TYPE_74HC165 1 // output s2p #define TYPE_74HC595 2 #define SER_74HC595_DATA 0 #define SER_74HC595_CLK 1 #define SER_74HC595_LATCH 2 #define SER_74HC595_RESET 3 #define SER_74HC165_DATA 0 #define SER_74HC165_CLK 1 #define SER_74HC165_LOAD 2 #define SER_74HC165_CLOCKEN 3 #define SER_74HC164_DATA 0 #define SER_74HC164_CLK 1 #define SER_74HC164_RESET 2 static const char ERRORMSG_CANT_READ[] PROGMEM = "This register cant not read"; static const char ERRORMSG_CANT_WRITE[] PROGMEM = "This register can not write"; #ifdef USE_SHIFTREG #define MAX_SHIFT_REGISTERS 8 class ShiftRegister { public: uint8_t used; uint8_t type; uint8_t pins[6]; ShiftRegister (); bool canread (); bool canwrite (); uint8_t init (); uint8_t csenable (bool en); uint8_t latch (); uint8_t read (); uint8_t free () { used = 0; return 0;} uint8_t write (uint8_t); uint8_t reset (); }; ShiftRegister::ShiftRegister () { used = 0; } bool ShiftRegister::canread () { return (type == TYPE_74HC165); } bool ShiftRegister::canwrite () { return (type == TYPE_74HC164 || type == TYPE_74HC595); } uint8_t ShiftRegister::init () { // depends on type of what need do if (type == TYPE_74HC164) { pinMode (pins[SER_74HC164_DATA], OUTPUT); pinMode (pins[SER_74HC164_CLK], OUTPUT); // have reset pin if (used > SER_74HC164_RESET) { pinMode (pins[SER_74HC164_RESET], OUTPUT); digitalWrite (pins[SER_74HC164_RESET], LOW); } digitalWrite (pins[SER_74HC595_CLK], LOW); if (used > SER_74HC164_RESET) { // have reset pin - so unset clr digitalWrite (pins[SER_74HC164_RESET], HIGH); } } if (type == TYPE_74HC165) { // serial data is input pinMode (pins[SER_74HC165_DATA], INPUT); // init with clock and load high pinMode (pins[SER_74HC165_CLK], OUTPUT); pinMode (pins[SER_74HC165_LOAD], OUTPUT); digitalWrite (pins[SER_74HC165_CLK], HIGH); digitalWrite (pins[SER_74HC165_LOAD], HIGH); } if (type == TYPE_74HC595) { pinMode (pins[SER_74HC595_DATA], OUTPUT); pinMode (pins[SER_74HC595_CLK], OUTPUT); // clk pinMode (pins[SER_74HC595_LATCH], OUTPUT); // latch // have reset pin if (used > SER_74HC595_RESET) { pinMode (pins[SER_74HC595_RESET], OUTPUT); // reset (optional) digitalWrite (pins[SER_74HC595_RESET], LOW); } // clock start high digitalWrite (pins[SER_74HC595_CLK], LOW); // latch digitalWrite (pins[SER_74HC595_LATCH], LOW); // have reset pin - so unset clr if (used > SER_74HC595_RESET) { digitalWrite (pins[SER_74HC595_RESET], HIGH); } } return 0; } uint8_t ShiftRegister::csenable (bool en) { if (type == TYPE_74HC164) { // nothing to do } else if (type == TYPE_74HC165) { // enable the clock with clockenalepin digitalWrite (pins[SER_74HC165_CLOCKEN], en ? LOW : HIGH); } else if (type == TYPE_74HC595) { // nothing to do } return 0; } uint8_t ShiftRegister::latch () { if (type == TYPE_74HC164) { // no latch } else if (type == TYPE_74HC165) { // trigger loading, by toggle on loadpin digitalWrite (pins[SER_74HC165_LOAD], LOW); delayMicroseconds (5); digitalWrite (pins[SER_74HC165_LOAD], HIGH); delayMicroseconds (5); } else if (type == TYPE_74HC595) { // latches on rising edge digitalWrite (pins[SER_74HC595_LATCH], HIGH); delayMicroseconds (5); digitalWrite (pins[SER_74HC595_LATCH], LOW); delayMicroseconds (5); } return 0; } uint8_t ShiftRegister::read () { uint8_t val = 0; if (type == TYPE_74HC165) { val = shiftIn(pins[SER_74HC165_DATA], pins[SER_74HC165_CLK], MSBFIRST); } return val; } uint8_t ShiftRegister::write (uint8_t d) { if (type == TYPE_74HC595) { shiftOut (pins[SER_74HC595_DATA], pins[SER_74HC595_CLK], MSBFIRST, d); return 1; } if (type == TYPE_74HC164) { shiftOut (pins[SER_74HC164_DATA], pins[SER_74HC164_CLK], MSBFIRST, d); return 1; } return 0; } uint8_t ShiftRegister::reset () { if (type == TYPE_74HC595) { // have reset pin - so unset clr if (used > SER_74HC595_RESET) { digitalWrite (pins[SER_74HC595_RESET], LOW); delayMicroseconds (5); digitalWrite (pins[SER_74HC595_RESET], HIGH); delayMicroseconds (5); return 1; } } else if (type == TYPE_74HC164) { if (used > SER_74HC164_RESET) { digitalWrite (pins[SER_74HC164_RESET], LOW); delayMicroseconds (5); digitalWrite (pins[SER_74HC164_RESET], HIGH); delayMicroseconds (5); return 1; } } return 0; } static ShiftRegister shiftregs[MAX_SHIFT_REGISTERS]; ShiftRegister * getShiftRegister (uint8_t id) { uint8_t i; ShiftRegister * unused = 0; for (i=0; i<MAX_SHIFT_REGISTERS; i++) { if (shiftregs[i].used > 0) { if (shiftregs[i].pins[0] == id) return &shiftregs[i]; } else if (!unused) { unused = &shiftregs[i]; } } return unused; } #endif OctaveShiftRegisterLibrary::OctaveShiftRegisterLibrary(OctaveArduinoClass &oc) { libName = "ShiftRegister"; oc.registerLibrary (this); } void OctaveShiftRegisterLibrary::commandHandler (uint8_t cmdID, uint8_t* data, uint8_t datasz) { switch (cmdID) { #ifdef USE_SHIFTREG case ARDUINO_CONFIG_SHIFTREG: { // 0 = id/datapin // 1 - enable/alloc // [ 2 = type // 3 = pins [] // 4 ... ] ShiftRegister * reg = getShiftRegister (data[0]); if (reg) { // alloc if (data[1] == 1 && datasz >= 4) { // data = DATAPIN E T CLK PIN? PIN? ... // // DATAPIN (doubles as ID) // E = enable (1 vs 0) ie: alloc/free // T = type 0 = 74HC164, ... // CLK clock pin // otherpins // pins used = pins defined reg->used = datasz - 2; // 1st pin is the register id reg->pins[0] = data[0]; reg->type = data[2]; byte c = 0; for (c=0; c<reg->used-1; c++) { reg->pins[c+1] = data[3+c]; } reg->init (); sendResponseMsg (cmdID, data, 2); } // free else if (data[1] == 0 && reg->used > 0 && datasz == 2) { reg->used = 0; reg->free (); sendResponseMsg (cmdID, data, 2); } else { sendErrorMsg_P (ERRORMSG_INVALID_ARGS); } } else { sendErrorMsg_P (ERRORMSG_INVALID_ARGS); } break; } case ARDUINO_RESET_SHIFTREG: { // 0 = id (currently using the datapin id) ShiftRegister * reg = getShiftRegister (data[0]); if (reg && reg->used > 0) { data[1] = reg->reset (); sendResponseMsg (cmdID, data, 2); } else { sendErrorMsg_P (ERRORMSG_INVALID_ARGS); } break; } case ARDUINO_WRITE_SHIFTREG: { // 0 = id // byte 0 // [byte1....] ShiftRegister * reg = getShiftRegister(data[0]); if (reg && reg->used > 0 && datasz >= 2) { if (reg->canwrite()) { reg->csenable (true); byte c = 0; for (c=1; c<datasz; c++) { reg->write (data[c]); } // num bytes wrote data[1] = datasz-1; datasz = 2; reg->latch (); reg->csenable (false); sendResponseMsg (cmdID, data, datasz); } else { // chip cant do write sendErrorMsg_P (ERRORMSG_CANT_WRITE); } } else { sendErrorMsg_P (ERRORMSG_INVALID_ARGS); } break; } case ARDUINO_READ_SHIFTREG: { // 0 = id // 1 = numbytes ShiftRegister * reg = getShiftRegister (data[0]); if (reg && reg->used > 0 && datasz == 2) { if (reg->canread ()) { reg->csenable (true); reg->latch (); byte c = 0; datasz = data[1]; for (c=1; c<datasz; c++) { data[c] = reg->read (); } reg->csenable (false); sendResponseMsg (cmdID, data, datasz); } else { // cant read sendErrorMsg_P( ERRORMSG_CANT_READ); } } else { sendErrorMsg_P (ERRORMSG_INVALID_ARGS); } break; } #endif default: sendUnknownCmdIDMsg (); break; } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoio/lib/OctaveShiftRegisterLibrary.h�������������������������������������0000644�0000000�0000000�00000001736�14777724260�021423� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Octave arduino shift register interface * Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> * * 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 <https://www.gnu.org/licenses/>. */ #include "LibraryBase.h" class OctaveShiftRegisterLibrary : public LibraryBase { public: OctaveShiftRegisterLibrary(OctaveArduinoClass &oc); void commandHandler(uint8_t cmdID, uint8_t* inputs, uint8_t payload_size); }; ����������������������������������arduino-0.12.2/inst/+arduinoio/lib/OctaveUltrasonicLibrary.cpp��������������������������������������0000644�0000000�0000000�00000010771�14777724260�021316� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Octave arduino ultrasonic interface * Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> * * 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 <https://www.gnu.org/licenses/>. */ #include "settings.h" #include "OctaveUltrasonicLibrary.h" #define ARDUINO_CONFIG_ULTRASONIC 1 #define ARDUINO_READ_ULTRASONIC 2 static const char ERRORMSG_CANT_READ[] PROGMEM = "Max ultrasonics reached"; #ifdef USE_ULTRASONIC #define MAX_ULTRASONICS 4 class Ultrasonic { #define USED 1 public: uint8_t flags; uint8_t pins[2]; uint8_t state; Ultrasonic (); uint8_t init (uint8_t p1, uint8_t p2); uint8_t free () { flags = 0; return 0;} uint32_t read (); }; Ultrasonic::Ultrasonic () { flags = 0; } uint8_t Ultrasonic::init (uint8_t p1, uint8_t p2=0xff) { flags = USED; pins[0] = p1; pins[1] = p2; if(p1 == p2) pins[1] = 0xff; pinMode (pins[0], OUTPUT); digitalWrite (pins[0], LOW); if (pins[1] != 0xff) { pinMode (pins[1], INPUT); digitalWrite (pins[1], LOW); } return 0; } uint32_t Ultrasonic::read () { uint32_t duration; digitalWrite (pins[0], LOW); delayMicroseconds (5); // Sets the trigPin on HIGH state for 10 micro seconds digitalWrite (pins[0], HIGH); delayMicroseconds (10); digitalWrite (pins[0], LOW); if (pins[1] == 0xff) { pinMode (pins[0], INPUT); duration = pulseIn(pins[0], HIGH, 250); pinMode (pins[0], OUTPUT); } else { // Reads the echoPin, returns the sound wave travel time in microseconds duration = pulseIn (pins[1], HIGH); //, 250); } return duration; } static Ultrasonic ultrasonics[MAX_ULTRASONICS]; Ultrasonic * getUltrasonic (uint8_t id) { uint8_t i; Ultrasonic * unused = 0; for (i=0; i<MAX_ULTRASONICS; i++) { if (ultrasonics[i].flags) { if (ultrasonics[i].pins[0] == id) return &ultrasonics[i]; } else if (!unused) { unused = &ultrasonics[i]; } } return unused; } #endif OctaveUltrasonicLibrary::OctaveUltrasonicLibrary (OctaveArduinoClass &oc) { libName = "Ultrasonic"; oc.registerLibrary (this); } void OctaveUltrasonicLibrary::commandHandler (uint8_t cmdID, uint8_t* data, uint8_t datasz) { switch (cmdID) { #ifdef USE_ULTRASONIC case ARDUINO_CONFIG_ULTRASONIC: { // 0 = id/triggerpin // 1 - enable/alloc // 2 = echo pin (optional) Ultrasonic * reg = getUltrasonic (data[0]); if (reg) { // alloc if (data[1] == 1 && datasz == 2) { reg->init (data[0]); sendResponseMsg (cmdID,data, 2); } else if(data[1] == 1 && datasz == 3) { reg->init (data[0], data[2]); sendResponseMsg (cmdID,data, 2); } // free else if (data[1] == 0 && reg->flags && datasz == 2) { reg->free (); sendResponseMsg(cmdID,data, 2); } else { sendErrorMsg_P (ERRORMSG_INVALID_ARGS); } } else { sendErrorMsg_P (ERRORMSG_INVALID_ARGS); } break; } case ARDUINO_READ_ULTRASONIC: { // 0 = id Ultrasonic * reg = getUltrasonic (data[0]); if (reg && datasz == 1) { uint32_t v = reg->read (); data[1] = (v>>24)&0xff; data[2] = (v>>16)&0xff; data[3] = (v>>8)&0xff; data[4] = (v)&0xff; datasz = 5; sendResponseMsg (cmdID, data, datasz); } else { sendErrorMsg_P (ERRORMSG_INVALID_ARGS); } break; } #endif default: sendUnknownCmdIDMsg (); break; } } �������arduino-0.12.2/inst/+arduinoio/lib/OctaveUltrasonicLibrary.h����������������������������������������0000644�0000000�0000000�00000001730�14777724260�020756� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Octave arduino shift register interface * Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> * * 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 <https://www.gnu.org/licenses/>. */ #include "LibraryBase.h" class OctaveUltrasonicLibrary : public LibraryBase { public: OctaveUltrasonicLibrary(OctaveArduinoClass &oc); void commandHandler(uint8_t cmdID, uint8_t* inputs, uint8_t payload_size); }; ����������������������������������������arduino-0.12.2/inst/+arduinoio/lib/octave.ino�������������������������������������������������������0000644�0000000�0000000�00000004112�14777724260�015760� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Octave arduino interface * Copyright (C) 2018-2023 John Donoghue <john.donoghue@ieee.org> * * 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 <https://www.gnu.org/licenses/>. */ #include "settings.h" #include "LibraryBase.h" // lib manager / processing static OctaveArduinoClass octavearduino; // include the base library #include "OctaveCoreLibrary.h" OctaveCoreLibrary lib0(octavearduino); #ifdef USE_I2C #include "OctaveI2CLibrary.h" OctaveI2CLibrary lib1(octavearduino); #endif #ifdef USE_SPI #include "OctaveSPILibrary.h" OctaveSPILibrary lib2(octavearduino); #endif #ifdef USE_SERVO #include "OctaveServoLibrary.h" OctaveServoLibrary lib3(octavearduino); #endif #ifdef USE_SHIFTREG #include "OctaveShiftRegisterLibrary.h" OctaveShiftRegisterLibrary lib4(octavearduino); #endif #ifdef USE_ROTARYENCODER #include "OctaveRotaryEncoderLibrary.h" OctaveRotaryEncoderLibrary lib5(octavearduino); #endif #ifdef USE_ULTRASONIC #include "OctaveUltrasonicLibrary.h" OctaveUltrasonicLibrary lib6(octavearduino); #endif #ifdef USE_SERIAL #include "OctaveSerialLibrary.h" OctaveSerialLibrary lib7(octavearduino); #endif // additional addons included from generated addons.h file #include "addons.h" void setup() { #if defined(ARDUINO_ARCH_AVR) // clear watchdog // clear all flags MCUSR = 0; /* Write logical one to WDCE and WDE */ /* Keep old prescaler setting to prevent unintentional time-out */ WDTCSR |= _BV(WDCE) | _BV(WDE); WDTCSR = 0; #endif octavearduino.init(); } void loop() { octavearduino.runLoop(); } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoioaddons/���������������������������������������������������������������0000755�0000000�0000000�00000000000�14777724260�014415� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoioaddons/+EEPRomAddon/��������������������������������������������������0000755�0000000�0000000�00000000000�14777724260�016525� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoioaddons/+EEPRomAddon/EEPRom.m������������������������������������������0000644�0000000�0000000�00000013007�14777724260�017773� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018-2020 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. classdef EEPRom < arduinoio.LibraryBase ## -*- texinfo -*- ## @deftypefn {} {} arduinoioaddons.EEPRomAddon.EEPRom ## EEPROM addon for arduino ## ## Allows read and write of uint8 data to the onboard arduino EEPROM. ## ## @subsubheading Example ## Assuming eeprom addon has been programmed into the Arduino: ## @example ## a = arduino (); ## e = addon (a, "eepromaddon/eeprom"); ## write (e, 0, uint8("hello world")); ## str = uint8( read(e, 0, 11) ) ## @end example ## ## @seealso{addon} ## @end deftypefn ## ## @subsubheading Properties ## @var{length} - Size of the EEPROM. ## ## @subheading Methods ## @deftypefn {} {@var{eeprom} =} EEPRom () ## Constructor to create EEPROM device. ## @subsubheading Outputs ## @var{eeprom} - created EEPROM device. ## @end deftypefn ## ## @deftypefn {} {} erase () ## Erase all values in EEPROM (Effectively setting the 0xFF) ## @end deftypefn ## ## @deftypefn {} {} write (@var{address}, @var{uintdata}) ## Write data to EEPROM at the provided address. ## @subsubheading Inputs ## @var{address} - start address to write data to, should be an ## integer between 0 and the size of the EEPROM. ## ## @var{uintdata} a value or array of uint8 data to write to EEPROM. ## @end deftypefn ## ## @deftypefn {} {@var{data} =} read (@var{address}) ## @deftypefnx {} {@var{data} =} read (@var{address}, @var{count}) ## Read data from starting address of EEPROM. ## @subsubheading Inputs ## @var{address} - start address to read data from, should be an ## integer between 0 and the size of the EEPROM. ## ## @var{count} - Number of uint8 values to read from the EEPROM (default is 1) ## ## @subsubheading Outputs ## @var{data} a value or array of uint8 data read from the EEPROM. ## @end deftypefn properties(Access = private) len = 0; endproperties # commands properties(Access = private, Constant = true) INIT_COMMAND = hex2dec('00'); ERASE_COMMAND = hex2dec('01'); READ_COMMAND = hex2dec('02'); WRITE_COMMAND = hex2dec('03'); endproperties properties(Access = protected, Constant = true) LibraryName = 'EEPRomAddon/EEPRom'; DependentLibraries = {}; #ArduinoLibraryHeaderFiles = {}; CppHeaderFile = fullfile(arduinoio.FilePath(mfilename('fullpath')), 'EEPRomAddon.h'); CppClassName = 'EEPRom'; endproperties methods # constructor function obj = EEPRom(parentObj) obj.Parent = parentObj; if nargin != 1 error ("EEPRom: expected arduino parent as only argument"); endif obj.Pins = {}; data = sendCommand(obj.Parent, obj.LibraryName, obj.INIT_COMMAND, []); length = uint16(data(1))*256 + uint16(data(2)) obj.len = length; endfunction function len = length (obj) len = obj.len; endfunction function erase(obj) cmdID = obj.ERASE_COMMAND; sendCommand(obj.Parent, obj.LibraryName, cmdID, []); endfunction function value = read(obj, address, num) cmdID = obj.READ_COMMAND; if nargin != 2 && nargin != 3 error ("EEPRom: expected address and optional number of bytes"); endif if nargin == 2 num = 1; endif if ! isnumeric(address) || address < 0 || address >= obj.len || mod(address, 1) != 0 error ("EEProm: expected address to be between 0 and %d", obj.len); endif if ! isnumeric(num) || num < 0 || num > 128 || mod(num, 1) != 0 error ("EEProm: num expected to be integer between 0 and %d", 128); endif if address + num > obj.len error ("EEPRom: address + num (%d) is out of EEPRom bounds of %d\n", (address+num), obj.len); endif intval = uint16(address); datain = [ bitshift(intval,-8) bitand(intval, 255) num]; dataout = sendCommand(obj.Parent, obj.LibraryName, cmdID, datain); value = dataout; endfunction function write(obj, address, value) cmdID = obj.WRITE_COMMAND; if nargin != 3 error ("EEPRom: expected address and value"); endif if ! isnumeric(address) || address < 0 || address >= obj.len || mod(address, 1) != 0 error ("expected address to be between 0 and %d", obj.len); endif num = numel(value); if num < 0 || num > 128 error ("EEProm: value size expected to be between 0 and %d", 128); endif if (address + num > obj.len) error ("EEPRom: address + numel(value) (%d) is out of EEPRom bounds of %d\n", (address+num), obj.len); endif intval = uint16(address); datain = [ bitshift(intval,-8) bitand(intval, 255) value]; sendCommand(obj.Parent, obj.LibraryName, cmdID, datain); endfunction function disp (obj) printf(" %s with properties\n", class(obj)); printf(" length = %d\n", obj.len); endfunction endmethods endclassdef �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoioaddons/+EEPRomAddon/EEPRomAddon.h�������������������������������������0000644�0000000�0000000�00000004341�14777724260�020735� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> * * 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 * <https://www.gnu.org/licenses/>. */ #include "LibraryBase.h" #include <EEPROM.h> // arduino liquid crystal library #define EEPROM_INIT 0x00 #define EEPROM_ERASE 0x01 #define EEPROM_READ 0x02 #define EEPROM_WRITE 0x03 class EEPRom : public LibraryBase { public: EEPRom(OctaveArduinoClass& a) { libName = "EEPRomAddon/EEProm"; a.registerLibrary(this); } void commandHandler(uint8_t cmdId, uint8_t* data, uint8_t datasz) { switch(cmdId) { case EEPROM_INIT: { uint16_t sz = EEPROM.length(); data[0] = (sz>>8)&0xff; data[1] = (sz)&0xff; sendResponseMsg(cmdId, data, 2); break; } case EEPROM_ERASE: { for (int a=0;a<EEPROM.length();a++) { EEPROM.update(a, 0xff); } sendResponseMsg(cmdId, 0, 0); break; } case EEPROM_READ: { if(datasz == 3) { datasz = data[2]; uint16_t addr = (uint16_t(data[0])<<8) | data[1]; for(int i=0;i<datasz;i++) { data[i] = EEPROM.read(addr+i); } sendResponseMsg(cmdId, data, datasz); } else { sendInvalidNumArgsMsg(); } break; } case EEPROM_WRITE: { if(datasz >= 3) { uint16_t addr = (uint16_t(data[0])<<8) | data[1]; datasz = datasz-2; for(int i=0;i<datasz;i++) { EEPROM.update(addr+i, data[i+2]); } data[0] = datasz; sendResponseMsg(cmdId, data, 1); } else { sendInvalidNumArgsMsg(); } break; } default: { // notify of invalid cmd sendUnknownCmdIDMsg(); } break; } } }; �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoioaddons/+ExampleAddon/�������������������������������������������������0000755�0000000�0000000�00000000000�14777724260�017031� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoioaddons/+ExampleAddon/Echo.m�������������������������������������������0000644�0000000�0000000�00000005020�14777724260�020062� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018-2020 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. classdef Echo < arduinoio.LibraryBase ## -*- texinfo -*- ## @deftypefn {} {} arduinoioaddons.ExampleAddon.Echo ## Basic Example matlab/octave code to illustrate creating ## a user addon. ## ## @seealso{addon} ## @end deftypefn ## ## @subsubheading Properties ## @var{Parent} - the parent arduino object. ## ## @var{Pins} - the pins allocated the addon. ## ## @subheading Methods ## @deftypefn {} {@var{obj} =} Echo(arObj) ## Constructor to create Echo addon ## @subsubheading Inputs ## @var{arObj} - the arduino parent object ## ## @subsubheading Outputs ## @var{obj} - created Echo object ## @end deftypefn ## ## @deftypefn {} {@var{response} = } shout(@var{text}) ## Send text to arduino and receive back the echoed reply ## ## @subsubheading Inputs ## @var{text} - text to send to arduino ## ## @subsubheading Outputs ## @var{response} - response from the arduino, which should be the same as ## the input text. ## @end deftypefn # commands properties(Access = private, Constant = true) ECHO_COMMAND = hex2dec('01'); endproperties properties(Access = protected, Constant = true) LibraryName = 'ExampleAddon/Echo'; DependentLibraries = {}; ArduinoLibraryHeaderFiles = {}; CppHeaderFile = fullfile(arduinoio.FilePath(mfilename('fullpath')), 'src', 'Echo.h'); CppClassName = 'Echo'; endproperties methods # constructor function obj = Echo(parentObj) obj.Parent = parentObj; obj.Pins = []; endfunction # function addon can do function out = shout(obj, val) cmdID = obj.ECHO_COMMAND; inputs = [uint8(val)]; output = sendCommand(obj.Parent, obj.LibraryName, cmdID, inputs); # data is just an echo of what we sent out = char(output); endfunction endmethods endclassdef ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoioaddons/+ExampleAddon/src/���������������������������������������������0000755�0000000�0000000�00000000000�14777724260�017620� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoioaddons/+ExampleAddon/src/Echo.h���������������������������������������0000644�0000000�0000000�00000002500�14777724260�020644� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> * * 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 * <https://www.gnu.org/licenses/>. */ #include "LibraryBase.h" const char MSG_NEEDS_VALUE[] PROGMEM = "Needs a value to echo"; class Echo : public LibraryBase { public: Echo(OctaveArduinoClass& a) { libName = "ExampleAddon/Echo"; a.registerLibrary(this); } void commandHandler(uint8_t cmdID, uint8_t* data, uint8_t datasz) { switch (cmdID) { case 0x01: { if(datasz == 0) sendErrorMsg_P(MSG_NEEDS_VALUE); else sendResponseMsg(cmdID, data, datasz); break; } default: { // notify of invalid cmd sendUnknownCmdIDMsg(); } } } }; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoioaddons/+ExampleLCD/���������������������������������������������������0000755�0000000�0000000�00000000000�14777724260�016406� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoioaddons/+ExampleLCD/LCD.m����������������������������������������������0000644�0000000�0000000�00000015137�14777724260�017175� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018-2020 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. classdef LCD < arduinoio.LibraryBase ## -*- texinfo -*- ## @deftypefn {} {} arduinoioaddons.LCDAddon.LCD ## Basic Example octave addon for LCD ## ## Allows basic manipulation of an LCD as a illustration of using ## the addon functionality. ## @subsubheading Example ## Assuming the arduino has been programmed with the lcd addon: ## @example ## a = arduino(); ## lcd = addon(a, "examplelcd/lcd", "d8", "d9", "d4", "d5", "d6", "d7") ## clearLCD(lcd); ## printLCD(lcd, "Hello"); ## # go to next line ## gotoLCD(lcd, 0, 1); ## printLCD(lcd, "World"); ## @end example ## @seealso{addon} ## @end deftypefn ## ## @subsubheading Properties ## @var{Pins} - the pins allocated the LCD display. ## ## @subheading Methods ## @deftypefn {} {@var{lcd} =} LCD(arObj, rs, enable, d0, d1, d2, d3) ## Constructor to create LCD device ## @subsubheading Inputs ## @var{arObj} - the arduino parent object ## ## @var{rs} - the pin to use for the rs line. ## ## @var{enable} - the pin to use for the enable line. ## ## @var{d0} - the pin to use for the d0 line. ## ## @var{d1} - the pin to use for the d1 line. ## ## @var{d2} - the pin to use for the d2 line. ## ## @var{d3} - the pin to use for the d3 line. ## ## @subsubheading Outputs ## @var{lcd} - created LCD object ## @end deftypefn ## ## @deftypefn {} {} freeLCD() ## Free the LCD ## ## Should be called before discarding the LCD ## @subsubheading Inputs ## None. ## ## @subsubheading Outputs ## None. ## @end deftypefn ## ## @deftypefn {} {} clearLCD() ## Clear the LCD display and set the cursor position to the home position. ## ## @subsubheading Inputs ## None. ## ## @subsubheading Outputs ## None. ## @end deftypefn ## ## @deftypefn {} {} printLCD(@var{text}) ## Display text on LCD starting at the current cursor position. ## ## @subsubheading Inputs ## @var{text} - text to display on LCD ## ## @subsubheading Outputs ## None. ## @end deftypefn ## ## @deftypefn {} {} gotoLCD(@var{col}, @var{row}) ## Set the cursor position to row, col ## ## @subsubheading Inputs ## @var{col} - 0 indexed LCD column to position to. ## ## @var{row} - 0 indexed LCD row to position to. ## ## @subsubheading Outputs ## None. ## @end deftypefn # commands properties(Access = private, Constant = true) INIT_COMMAND = hex2dec('00'); FREE_COMMAND = hex2dec('01'); CLEAR_COMMAND = hex2dec('02'); PRINT_COMMAND = hex2dec('03'); SETCURSOR_COMMAND = hex2dec('04'); endproperties properties(Access = protected, Constant = true) LibraryName = 'ExampleLCD/LCD'; DependentLibraries = {}; ArduinoLibraryHeaderFiles = { 'LiquidCrystal/LiquidCrystal.h' }; CppHeaderFile = fullfile(arduinoio.FilePath(mfilename('fullpath')), 'LCDAddon.h'); CppClassName = 'LCD'; endproperties properties(Access=private) ResourceOwner = 'ExampleLCD/LCDAddon'; endproperties methods # constructor function obj = LCD(parentObj, rs, enable, d0, d1, d2, d3) obj.Parent = parentObj; if nargin < 7 error ("LCD: expected input pins rs, enable, d0, d1, d2, d3"); endif # our LCD code only allows 1 lcd at a time count = getResourceCount(obj.Parent, obj.ResourceOwner); if count > 0 error ("ExampleLCD/LCDAddon: can have only one LCD at a time"); endif obj.Pins = {}; data = []; pindata = getPinInfo(obj.Parent, {rs enable d0 d1 d2 d3}); try for p = 1:numel(pindata) pin = pindata{p}; configurePin(obj.Parent, pin.name, "digitaloutput") obj.Pins{end+1} = pin.name; data = [data pin.terminal]; endfor catch # catch any errors and restore pins for p = 1:numel(pindata) pin = pindata{p}; configurePinResource(obj.Parent, pin.name, pin.owner, pin.mode, true) configurePin(obj.Parent, pin.name, pin.mode) endfor rethrow (lasterror); end_try_catch sendCommand(obj.Parent, obj.LibraryName, obj.INIT_COMMAND, data); incrementResourceCount(obj.Parent,obj.ResourceOwner); endfunction function freeLCD(obj) if nargin != 1 warning ("LCD: unexpected additional arguments being ignored"); endif if isobject(obj.Parent) cmdID = obj.FREE_COMMAND; sendCommand(obj.Parent, obj.LibraryName, cmdID); decrementResourceCount(obj.Parent,obj.ResourceOwner); obj.Parent = []; endif endfunction function printLCD(obj, text) if nargin < 2 || !ischar(text) error ("LCD: expected text to display"); endif if nargin != 2 warning ("LCD: unexpected additional arguments being ignored"); endif cmdID = obj.PRINT_COMMAND; sendCommand(obj.Parent, obj.LibraryName, cmdID, [uint8(text) 0]); endfunction function clearLCD(obj) if nargin != 1 warning ("LCD: unexpected additional arguments being ignored"); endif cmdID = obj.CLEAR_COMMAND; sendCommand(obj.Parent, obj.LibraryName, cmdID); endfunction function gotoLCD(obj, col, row) if nargin < 3 error ("LCD: col and row"); endif if nargin != 3 warning ("LCD: unexpected additional arguments being ignored"); endif if !isnumeric(col) || col < 0 || mod(col,1) != 0 error ("LCD: expected col as a numeric integer value"); endif if !isnumeric(row) || row < 0 || mod(row,1) != 0 error ("LCD: expected row as a numeric integer value"); endif cmdID = obj.SETCURSOR_COMMAND; sendCommand(obj.Parent, obj.LibraryName, cmdID, [col row]); endfunction function delete(obj) try ar = obj.Parent; if isobject(ar) freeLCD(obj); endif catch err # do nothing # warning("caught error %s", err.message) end_try_catch endfunction endmethods endclassdef ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoioaddons/+ExampleLCD/LCDAddon.h�����������������������������������������0000644�0000000�0000000�00000005537�14777724260�020141� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> * * 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 * <https://www.gnu.org/licenses/>. */ #include "LibraryBase.h" #include <LiquidCrystal.h> // arduino liquid crystal library static const char LCD_MSG_ALREADY_INITIALIZED[] PROGMEM = "Already initialized"; static const char LCD_MSG_NOT_INITIALIZED[] PROGMEM = "LCD not initialized"; #define LCD_INIT 0x00 #define LCD_FREE 0x01 #define LCD_CLEAR 0x02 #define LCD_PRINT 0x03 #define LCD_SETCURSOR 0x04 class LCD : public LibraryBase { private: LiquidCrystal *lcd; public: LCD(OctaveArduinoClass& a) { libName = "ExampleLCD/LCD"; a.registerLibrary(this); } void setup() { lcd = 0; } void commandHandler(uint8_t cmdId, uint8_t* data, uint8_t datasz) { switch(cmdId) { case LCD_INIT: { // 0 - 5 = pins to use if (lcd) { sendErrorMsg_P(LCD_MSG_ALREADY_INITIALIZED); } else if(datasz != 6) { sendInvalidNumArgsMsg(); } else { // rs enable, d0, d1, d2, d3 lcd = new LiquidCrystal(data[0], data[1], data[2], data[3], data[4], data[5]); lcd->begin(16, 2); lcd->clear(); sendResponseMsg(cmdId, data, 1); } break; } case LCD_FREE: { if (!lcd) { sendErrorMsg_P(LCD_MSG_NOT_INITIALIZED); } else { delete lcd; lcd = 0; sendResponseMsg(cmdId, 0, 0); } break; } case LCD_CLEAR: { if (!lcd) { sendErrorMsg_P(LCD_MSG_NOT_INITIALIZED); } else { lcd->clear(); sendResponseMsg(cmdId, 0, 0); } break; } case LCD_PRINT: { if (!lcd) { sendErrorMsg_P(LCD_MSG_NOT_INITIALIZED); } else if(datasz > 0) { lcd->print((const char *)data); sendResponseMsg(cmdId, 0, 0); } else { sendInvalidNumArgsMsg(); } break; } case LCD_SETCURSOR: { if (!lcd) { sendErrorMsg_P(LCD_MSG_NOT_INITIALIZED); } else if(datasz == 2) { lcd->setCursor(data[0], data[1]); sendResponseMsg(cmdId, 0, 0); } else { sendInvalidNumArgsMsg(); } break; } default: { // notify of invalid cmd sendUnknownCmdIDMsg(); } break; } } }; �����������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoioaddons/+RTCAddon/�����������������������������������������������������0000755�0000000�0000000�00000000000�14777724260�016066� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoioaddons/+RTCAddon/DS1307.m���������������������������������������������0000644�0000000�0000000�00000017402�14777724260�017071� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018-2020 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. classdef DS1307 < arduinoio.LibraryBase ## -*- texinfo -*- ## @deftypefn {} {} arduinoioaddons.RTCAddon.DS1307 ## DS1307 addon ## ## @seealso{addon} ## @end deftypefn ## ## @subsubheading Properties ## @var{Parent} - the parent arduino object. ## ## @var{Pins} - the pins allocated the addon. ## ## @subheading Methods ## @deftypefn {} {@var{obj} =} DS1307(@var{arObj}) ## @deftypefnx {} {@var{obj} =} DS1307(@var{arObj}, @var{propertyname, propertyvalue} ....) ## Constructor to create DS1307 addon ## @subsubheading Inputs ## @var{arObj} - the arduino parent object ## ## @var{propertyname, propertyvalue} - optional property name, value pairs. ## Current known properties are: ## @table @asis ## @item address ## I2C address of the DS1307 (default 0x68) ## @end table ## ## @subsubheading Outputs ## @var{obj} - created DS1307 object ## ## @subsubheading Example ## @example ## @code { ## a = arduino() ## rtc = addon(a, "rtcaddon/ds1307") ## } ## @end example ## @end deftypefn ## ## @deftypefn {} {@var{date} =} clock(@var{dsObj}) ## @deftypefnx {} {} clock(@var{dsObj}, @var{date}) ## Get/set the DS1307 clock ## ## @subsubheading Inputs ## @var{dsObj} - the ds1307 object ## ## @var{date} - a date vector in same format as datevec and clock ## ## @subsubheading Outputs ## @var{date} - a date vector in same format as datevec and clock ## ## @subsubheading Example ## @example ## @code { ## a = arduino() ## rtc = addon(a, "rtcaddon/ds1307") ## # get and display rtc time as a date string ## datestr(rtc.clock) ## } ## @end example ## @seealso{datevec} ## @end deftypefn ## ## @deftypefn {} {@var{ctrl} =} control(@var{dsObj}) ## @deftypefnx {} {} control(@var{dsObj}, @var{ctrl}) ## Get/set the DS1307 clock ## ## @subsubheading Inputs ## @var{dsObj} - the ds1307 object ## ## @var{ctrl} - a structure containing the control bit fields. ## ## @subsubheading Outputs ## @var{ctrl} - a structure containing the control bit fields. ## ## Control structure fields are: ## Current properties are: ## @table @asis ## @item out ## Out bit in the control register ## @item sqwe ## Square wave enable bit in control register ## @item rs ## The combined RS0, RS1 value ## @end table ## ## @end deftypefn ## ## @deftypefn {} {@var{YN} =} isstarted(@var{dsObj}) ## Get whether the RTC clock is currently counting time ## ## @subsubheading Inputs ## @var{dsObj} - the ds1307 object ## ## @subsubheading Outputs ## @var{YN} - returns true if the RTC is counting ## ## @seealso{start, stop} ## @end deftypefn ## ## @deftypefn {} {} start(@var{dsObj}) ## Start the RTC counting ## ## @subsubheading Inputs ## @var{dsObj} - the ds1307 object ## ## @subsubheading Outputs ## None ## ## @seealso{datevec} ## @end deftypefn ## ## @deftypefn {} {} stop(@var{dsObj}) ## Stop the RTC counting ## ## @subsubheading Inputs ## @var{dsObj} - the ds1307 object ## ## @subsubheading Outputs ## None ## ## @seealso{datevec} ## @end deftypefn # commands properties(Access = private, Constant = true) INIT_COMMAND = hex2dec('00'); endproperties properties(Access = protected, Constant = true) LibraryName = 'RTCAddon/DS1307'; DependentLibraries = { "i2c" }; ArduinoLibraryHeaderFiles = {}; CppHeaderFile = fullfile(arduinoio.FilePath(mfilename('fullpath')), 'DS1307Addon.h'); CppClassName = 'DS1307Addon'; endproperties properties(Access = private) i2c; address; bcd2dec = @(v) bitshift(v, -4)*10 + bitand(v, 0xf); dec2bcd = @(v) bitshift(floor(v/10), 4) + bitand(mod(v,10), 0xf); endproperties methods # constructor function obj = DS1307(parentObj, varargin) # parse args p = inputParser(CaseSensitive=false, FunctionName='RTCAddon/DS1307'); p.addParameter('Address', 0x68, @isnumeric); p.parse(varargin{:}); # do we have the address ? address = p.Results.Address; i2caddresses = scanI2Cbus(parentObj); idx = find(cellfun ( @(x) strcmp(x, sprintf("0x%02X", address)), i2caddresses)); if isempty(idx) error('RTCAddon/DS1307: matching i2c address found on bus'); endif obj.Parent = parentObj; obj.address = p.Results.Address; obj.i2c = device(parentObj, "i2caddress", obj.address); obj.Pins = obj.i2c.Pins; # our arduino part isn't needed as we are really just using the i2c, but # we have to have the arduino part for lib detections, so lets # send a message to it on init anyway in case sometime in the future # we end up having it do something data = sendCommand(obj.Parent, obj.LibraryName, obj.INIT_COMMAND, []); endfunction function c = clock (obj, settime) if nargin == 2 # set time wd = weekday(datenum(settime)); writeRegister(obj.i2c, 0, ... [obj.dec2bcd(floor(settime(6))), obj.dec2bcd(settime(5)), (obj.dec2bcd(settime(4))), ... wd, obj.dec2bcd(settime(3)), obj.dec2bcd(settime(2)), obj.dec2bcd(mod(settime(1),100))] ... ); else # get time data = readRegister(obj.i2c, 0, 7); secs = double(obj.bcd2dec(bitand(data(1), 0x7f))); mins = double(obj.bcd2dec(data(2))); if bitand(data(3), 0x40) != 0 # 12 hr pm = bitand(data(3), 0x20); hrs = double(obj.bcd2dec(bitand(data(3), 0x2f))); if pm hrs = double(hrs + 12); endif else hrs = double(obj.bcd2dec(bitand(data(3), 0x3f))); endif wday = double(data(4)); day = double(obj.bcd2dec(data(5))); month = double(obj.bcd2dec(data(6))); year = 2000.0 + double(obj.bcd2dec(data(7))); c = double([year, month, day, hrs, mins, secs]); endif endfunction function start(obj) data = readRegister(obj.i2c, 0, 1); data = bitset(data, 8, 0); writeRegister(obj.i2c, 0, data); endfunction function stop(obj) data = readRegister(obj.i2c, 0, 1); data = bitset(data, 8, 1); writeRegister(obj.i2c, 0, data); endfunction function val = isstarted(obj) data = readRegister(obj.i2c, 0, 1); val = bitget(data, 8) == 0; endfunction function bits = control(obj, setbits) if nargin == 1 data = readRegister(obj.i2c, 7, 1); bits = {}; bits.out = bitget(data, 8); bits.sqwe = bitget(data, 5); bits.rs = bitand(data, 0x03); else data = 0; data = bitand(setbits.rs, 0x3); if setbits.out data = data + 0x80; endif if setbits.sqwe data = data + 0x10; endif writeRegister(obj.i2c, 7, data); endif endfunction function disp(this) printf(" %s with properties\n", class(this)); printf(" Address = 0x%X\n", this.address); # show i2c pins as the pins printf(" Pins = {\n"); for i=1:numel(this.Pins) printf(" %s\n", this.Pins{i}); endfor printf(" }\n"); endfunction endmethods endclassdef ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoioaddons/+RTCAddon/DS1307Addon.h����������������������������������������0000644�0000000�0000000�00000002342�14777724260�020027� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> * * 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 * <https://www.gnu.org/licenses/>. */ #include "LibraryBase.h" #define DS1307_INIT 0x00 class DS1307Addon : public LibraryBase { public: DS1307Addon(OctaveArduinoClass& a) { libName = "RTCAddon/DS1307"; a.registerLibrary(this); } void commandHandler(uint8_t cmdId, uint8_t* data, uint8_t datasz) { switch(cmdId) { case DS1307_INIT: { sendResponseMsg(cmdId, data, 1); break; } default: { // notify of invalid cmd sendUnknownCmdIDMsg(); } break; } } }; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoioaddons/+SimpleStepper/������������������������������������������������0000755�0000000�0000000�00000000000�14777724260�017264� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoioaddons/+SimpleStepper/SimpleStepper.m���������������������������������0000644�0000000�0000000�00000022166�14777724260�022245� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. classdef SimpleStepper < arduinoio.LibraryBase ## -*- texinfo -*- ## @deftypefn {} {} arduinoioaddons.SimpleStepper ## Stepper class for stepper control using ULN2003 and compatible drivers ## @end deftypefn ## ## @subsubheading Properties ## @table @asis ## @item @var{Id} ## Id of the stepper (Read only) ## @item @var{Speed} ## Number of steps to do per second. ## @item Status ## Status of stepper (Read only). ## 0 = not moving, 1 = moving, 2 = rotating ## @item Parent ## the Arduino parent (read only) ## @item Pins ## the pins used for the stepper (read only) ## @end table ## ## @subheading Methods ## @deftypefn {} {@var{obj} =} SimpleStepper(@var{aObj}, @var{pin1}, @var{pin2}, @var{pin3}, @var{pin4}) ## @deftypefnx {} {@var{obj} =} SimpleStepper(@var{aObj}, @var{pin1}, @var{pin2}, @var{pin3}, @var{pin4}, @var{pin5}) ## Constructor to create a stepper object ## @subsubheading Inputs ## @var{aObj} - The arduino ## ## @var{pin1} - The first pin of the controller ## ## @var{pin2} - The second pin of the controller ## ## @var{pin3} - The third pin of the controller ## ## @var{pin4} - The fourth pin of the controller ## ## @var{pin5} - The fifth pin of the controller ## ## @subsubheading Outputs ## @var{s} - a simplestepper object ## ## @subsubheading Example ## @example ## @code { ## a = arduino() ## # create stepper object ## s = addon(a, "simplestepper/simplestepper", "d2", "d3", "d4", "d5") ## # start rotating left ## s.rotate(-1); ## } ## @end example ## ## @seealso{addon} ## @end deftypefn ## ## @deftypefn {} {} move(@var{sObj}, @var{steps}) ## Move the motor the specified number of steps using the configured Speed. ## ## @subsubheading Inputs ## @var{sObj} - the stepper object ## ## @var{steps} - the number of steps to move. steps less than 0 will be moving left. ## ## @subsubheading Outputs ## None ## ## @seealso{rotate} ## @end deftypefn ## ## @deftypefn {} {} rotate(@var{sObj}, @var{dir}) ## Start steppermotor moving in the specified direction using the configured Speed. ## ## @subsubheading Inputs ## @var{sObj} - the stepper object ## ## @var{dir} - Direction to move. -1 = left, 0 = stop, 1 = right. ## ## @subsubheading Outputs ## None ## ## @seealso{move} ## @end deftypefn ## ## @deftypefn {} {} release(@var{sObj}) ## Release this stepper motor ## ## @subsubheading Inputs ## @var{sObj} - the stepper object ## ## @subsubheading Outputs ## None ## ## @end deftypefn properties(Access = public) Speed = 1; # num secs per tick endproperties properties(GetAccess = public, SetAccess = private) Id = 0; # Id of the object Status = 0; # Status 0,1,2 Pins = []; # pins allocated to this stepper endproperties properties(Access = private) # pin info of pins used by this object PinInfo = []; # var for scope of cleanupduring release cleanup; endproperties properties(Access = protected, Constant = true) # addon properties LibraryName = 'SimpleStepper/SimpleStepper'; CppHeaderFile = fullfile(arduinoio.FilePath(mfilename('fullpath')), 'src', 'SimpleStepperAddon.h'); CppSourceFile = fullfile(arduinoio.FilePath(mfilename('fullpath')), 'src', 'SimpleStepperAddon.cpp'); CppClassName = 'SimpleStepperAddon'; endproperties properties(Access = private, Constant = true) # command will send to the arduino INIT_COMMAND = 0x00; MOVE_COMMAND = 0x01; ROTATE_COMMAND = 0x02; TICKSPERSTEP_COMMAND = 0x03; STATUS_COMMAND = 0x04; RELEASE_COMMAND = 0x10; STATE_COMMAND = 0x20; endproperties methods function obj = SimpleStepper(parentObj, varargin) if (!isa (parentObj, "arduino")) error("expects arduino object"); endif obj.Parent = parentObj; obj.PinInfo = []; # pins follow tmp_pins = {}; for i = 1:length(varargin) validatePin(obj.Parent, varargin{1}, 'digital') tmp_pins{end+1} = getPinInfo(obj.Parent, varargin{i}); endfor if length(tmp_pins) < 4 || length(tmp_pins) > 5 error("expected 4 or 5 pins"); endif obj.PinInfo = tmp_pins; try data = []; for i = 1:length(tmp_pins) configurePin(obj.Parent, tmp_pins{i}.name, "digitaloutput") configurePinResource (obj.Parent, tmp_pins{i}.name, obj.LibraryName, "digitaloutput", true); data(end+1) = tmp_pins{i}.terminal; endfor # use smallest num for id obj.Id = min(data); #obj.Parent.debug =1; [tmp, sz] = sendCommand(obj.Parent, obj.LibraryName, obj.INIT_COMMAND, uint8([obj.Id data])); catch for i=1:numel(tmp_pins) configurePinResource(obj.Parent, tmp_pins{i}.name, tmp_pins{i}.owner, tmp_pins{i}.mode, true) configurePin(obj.Parent, tmp_pins{i}.name, tmp_pins{i}.mode) endfor rethrow (lasterror); end_try_catch obj.cleanup = onCleanup (@() sendCommand(obj.Parent, obj.LibraryName, obj.RELEASE_COMMAND, [obj.Id])); endfunction function release(obj) obj.cleanup = []; # called from cleanup sendCommand(obj.Parent, obj.RELEASE_COMMAND,[obj.Id]); for i=1:numel(obj.PinInfo) configurePinResource(obj.Parent, obj.PinInfo{i}.name, obj.PinInfo{i}.owner, obj.PinInfo{i}.mode, true) configurePin(obj.Parent, obj.PinInfo{i}.name, obj.PinInfo{i}.mode) endfor endfunction function move(obj, steps) cmdID = obj.MOVE_COMMAND; intval = int32(steps); data = [ bitand(bitshift(intval,-24), 255) bitand(bitshift(intval,-16),255) bitand(bitshift(intval,-8),255) bitand(intval, 255)]; sendCommand(obj.Parent, obj.LibraryName, cmdID, [obj.Id data]); endfunction function rotate(obj, dir) cmdID = obj.ROTATE_COMMAND; if dir < -1 || dir > 1 error ("Expected dir to be -1, 0 or 1."); endif dir = typecast(int8(dir), "uint8"); sendCommand(obj.Parent, obj.LibraryName, cmdID, uint8([obj.Id dir])); endfunction function disp(this) printf(" %s with properties\n", class(this)); printf(" Speed = %f\n", this.Speed); printf(" Status = %d\n", this.Status); printf(" Pins = {\n"); for i=1:numel(this.PinInfo) printf(" %s\n", this.PinInfo{i}.name); endfor printf(" }\n"); endfunction endmethods methods (Hidden = true) function retval = state(obj) cmdID = obj.STATE_COMMAND; data = sendCommand(obj.Parent, obj.LibraryName, cmdID, uint8([obj.Id])); retval = {}; retval.Id = data(1); retval.NumPins = double(data(2)); retval.Pins = []; retval.Pins(1) = double(data(3)); retval.Pins(2) = double(data(4)); retval.Pins(3) = double(data(5)); retval.Pins(4) = double(data(6)); retval.Pins(5) = double(data(7)); retval.Status = data(8); retval.Direction = double(typecast(data(9), 'int8')); val = bitshift(uint32(data(10)), 24) + bitshift(uint32(data(11)), 16) + bitshift(uint32(data(12)), 8) + uint32(data(13)); retval.StepsToDo = val; val = bitshift(uint32(data(14)), 24) + bitshift(uint32(data(15)), 16) + bitshift(uint32(data(16)), 8) + uint32(data(17)); retval.TicksPerStep = val; val = bitshift(uint32(data(18)), 24) + bitshift(uint32(data(19)), 16) + bitshift(uint32(data(20)), 8) + uint32(data(21)); retval.LastStepTick = val; endfunction function status = get.Status(obj) cmdID = obj.STATUS_COMMAND; data = sendCommand(obj.Parent, obj.LibraryName, cmdID, [obj.Id]); status = data(2); endfunction function set.Speed(obj, speedval) cmdID = obj.TICKSPERSTEP_COMMAND; if speedval == 0 ticks = 0; elseif(speedval < 0) error ("speed should be number of steps per second"); else ticks = 1000000/speedval; endif intval = uint32(ticks) data = [ bitand(bitshift(intval,-24), 255) bitand(bitshift(intval,-16),255) bitand(bitshift(intval,-8),255) bitand(intval, 255)]; sendCommand(obj.Parent, obj.LibraryName, cmdID, [obj.Id data]); obj.Speed = speedval; endfunction function pins = get.Pins(obj) pins = {}; for i=1:numel (obj.PinInfo) pins{end+1} = obj.PinInfo{i}.name; endfor endfunction endmethods endclassdef ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoioaddons/+SimpleStepper/src/��������������������������������������������0000755�0000000�0000000�00000000000�14777724260�020053� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoioaddons/+SimpleStepper/src/SimpleStepperAddon.cpp����������������������0000644�0000000�0000000�00000032214�14777724260�024323� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> * * 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 * <https://www.gnu.org/licenses/>. */ #include "SimpleStepperAddon.h" class AddonStepper { public: uint8_t id; uint8_t curr_step; int8_t direction; uint8_t num_pins; uint8_t pins[5]; unsigned long steps_to_do; unsigned long ticksperstep; unsigned long laststeptick; AddonStepper() { num_pins=0; id=0;} uint8_t status() const { uint8_t s = 0; if (num_pins) { if (direction) s = 2; if (steps_to_do) s = 1; } return s; } unsigned getStepsLeft() const { return steps_to_do; } void setTicksPerStep(unsigned long ticks) { if(ticks == 0) { direction = 0; steps_to_do = 0; } else { ticksperstep = ticks; } } unsigned long getTicksPerStep() const { return ticksperstep; } bool attach(uint8_t id, uint8_t pin1, uint8_t pin2, uint8_t pin3, uint8_t pin4) { detach(); this->id = id; num_pins = 4; pins[0] = pin1; pins[1] = pin2; pins[2] = pin3; pins[3] = pin4; pinMode(pins[0], OUTPUT); pinMode(pins[1], OUTPUT); pinMode(pins[2], OUTPUT); pinMode(pins[3], OUTPUT); direction = 0; laststeptick = 0; curr_step = 0; ticksperstep = 1000000L; steps_to_do = 0; return true; } bool attach(uint8_t id, uint8_t pin1, uint8_t pin2, uint8_t pin3, uint8_t pin4, uint8_t pin5) { detach(); this->id = id; num_pins = 5; pins[0] = pin1; pins[1] = pin2; pins[2] = pin3; pins[3] = pin4; pins[4] = pin5; pinMode(pins[0], OUTPUT); pinMode(pins[1], OUTPUT); pinMode(pins[2], OUTPUT); pinMode(pins[3], OUTPUT); pinMode(pins[4], OUTPUT); direction = 0; laststeptick = 0; curr_step = 0; ticksperstep = 1000000L; steps_to_do = 0; return true; } void detach() { if (num_pins) { digitalWrite(pins[0], LOW); digitalWrite(pins[1], LOW); digitalWrite(pins[2], LOW); digitalWrite(pins[3], LOW); if (num_pins > 4) digitalWrite(pins[4], LOW); } num_pins = 0; } void move(long steps) { direction = 0; steps_to_do = abs(steps); if (steps < 0) { direction = -1; } else { direction = 1; } } void rotate(int8_t dir) { steps_to_do = 0; direction = dir; } void poll() { if (num_pins) { unsigned long now = micros(); if (now - laststeptick >= ticksperstep) { laststeptick = now; if (direction > 0) { curr_step ++; } else if (direction < 0) { if (curr_step == 0) { // dependant on num pins if (num_pins == 4) curr_step = 4; else curr_step = 10; } curr_step --; } else { // no change in step num } // mod based on num pins if (num_pins == 4) { curr_step = curr_step % 4; step4(curr_step); } if (num_pins == 5) { curr_step = curr_step % 10; step5(curr_step); } // moving X steps if (direction != 0 && steps_to_do) { steps_to_do --; if (steps_to_do == 0) direction = 0; } } } } void step5(int step) { // 5 pin switch(step) { case 0: // 01101 digitalWrite(pins[0], LOW); digitalWrite(pins[1], HIGH); digitalWrite(pins[2], HIGH); digitalWrite(pins[3], LOW); digitalWrite(pins[4], HIGH); break; case 1: // 01001 digitalWrite(pins[0], LOW); digitalWrite(pins[1], HIGH); digitalWrite(pins[2], LOW); digitalWrite(pins[3], LOW); digitalWrite(pins[4], HIGH); break; case 2: // 01011 digitalWrite(pins[0], LOW); digitalWrite(pins[1], HIGH); digitalWrite(pins[2], LOW); digitalWrite(pins[3], HIGH); digitalWrite(pins[4], HIGH); break; case 3: // 01010 digitalWrite(pins[0], LOW); digitalWrite(pins[1], HIGH); digitalWrite(pins[2], LOW); digitalWrite(pins[3], HIGH); digitalWrite(pins[4], LOW); break; case 4: // 11010 digitalWrite(pins[0], HIGH); digitalWrite(pins[1], HIGH); digitalWrite(pins[2], LOW); digitalWrite(pins[3], HIGH); digitalWrite(pins[4], LOW); break; case 5: // 10010 digitalWrite(pins[0], HIGH); digitalWrite(pins[1], LOW); digitalWrite(pins[2], LOW); digitalWrite(pins[3], HIGH); digitalWrite(pins[4], LOW); break; case 6: // 10110 digitalWrite(pins[0], HIGH); digitalWrite(pins[1], LOW); digitalWrite(pins[2], HIGH); digitalWrite(pins[3], HIGH); digitalWrite(pins[4], LOW); break; case 7: // 10100 digitalWrite(pins[0], HIGH); digitalWrite(pins[1], LOW); digitalWrite(pins[2], HIGH); digitalWrite(pins[3], LOW); digitalWrite(pins[4], LOW); break; case 8: // 10101 digitalWrite(pins[0], HIGH); digitalWrite(pins[1], LOW); digitalWrite(pins[2], HIGH); digitalWrite(pins[3], LOW); digitalWrite(pins[4], HIGH); break; case 9: // 00101 digitalWrite(pins[0], LOW); digitalWrite(pins[1], LOW); digitalWrite(pins[2], HIGH); digitalWrite(pins[3], LOW); digitalWrite(pins[4], HIGH); break; } } void step4(int step) { // 4 pin switch(step) { case 0: // 1010 digitalWrite(pins[0], HIGH); digitalWrite(pins[1], LOW); digitalWrite(pins[2], HIGH); digitalWrite(pins[3], LOW); break; case 1: // 0110 digitalWrite(pins[0], LOW); digitalWrite(pins[1], HIGH); digitalWrite(pins[2], HIGH); digitalWrite(pins[3], LOW); break; case 2: //0101 digitalWrite(pins[0], LOW); digitalWrite(pins[1], HIGH); digitalWrite(pins[2], LOW); digitalWrite(pins[3], HIGH); break; case 3: //1001 digitalWrite(pins[0], HIGH); digitalWrite(pins[1], LOW); digitalWrite(pins[2], LOW); digitalWrite(pins[3], HIGH); break; } } }; #ifndef MAX_SIMPLESTEPPERS # define MAX_SIMPLESTEPPERS 4 #endif static AddonStepper steppers[MAX_SIMPLESTEPPERS]; static AddonStepper * getStepper (uint8_t id) { uint8_t i; AddonStepper * unused = 0; for (i=0;i<MAX_SIMPLESTEPPERS;i++) { if (steppers[i].num_pins) { if (steppers[i].id == id) return &steppers[i]; } else if (!unused) { unused = &steppers[i]; } } return unused; } #define SIMPLESTEPPERADDON_INIT 0x00 #define SIMPLESTEPPERADDON_MOVE 0x01 #define SIMPLESTEPPERADDON_ROTATE 0x02 #define SIMPLESTEPPERADDON_TICKSPERSTEP 0x03 #define SIMPLESTEPPERADDON_STATUS 0x04 #define SIMPLESTEPPERADDON_RELEASE 0x10 #define SIMPLESTEPPERADDON_STATE 0x20 SimpleStepperAddon::SimpleStepperAddon(OctaveArduinoClass& a) { libName = "SimpleStepper/SimpleStepper"; a.registerLibrary(this); } void SimpleStepperAddon::commandHandler(uint8_t cmdID, uint8_t* data, uint8_t datasz) { switch (cmdID) { case SIMPLESTEPPERADDON_INIT: { AddonStepper * stepper = getStepper (data[0]); // id + X pins if(stepper && datasz == 5) { stepper->attach(data[0], data[1], data[2], data[3], data[4]); sendResponseMsg(cmdID, data, 1); } else if(stepper && datasz == 6) { stepper->attach(data[0], data[1], data[2], data[3], data[4], data[5]); sendResponseMsg(cmdID, data, 1); } else { // really should be a run out resources error sendErrorMsg_P (ERRORMSG_INVALID_ARGS); } break; } case SIMPLESTEPPERADDON_RELEASE: { AddonStepper * stepper = getStepper (data[0]); if(stepper && datasz == 1) { stepper->detach(); sendResponseMsg(cmdID, data, 1); } else { sendErrorMsg_P (ERRORMSG_INVALID_ARGS); } break; } case SIMPLESTEPPERADDON_MOVE: { AddonStepper * stepper = getStepper (data[0]); if (stepper && datasz == 5) { long steps = ((long)data[1] << 24) | ((long)data[2] << 16) | ((long)data[3] << 8) | (long)data[4]; stepper->move(steps); sendResponseMsg(cmdID, data, 1); } else { sendErrorMsg_P (ERRORMSG_INVALID_ARGS); } break; } case SIMPLESTEPPERADDON_ROTATE: { AddonStepper * stepper = getStepper (data[0]); if (stepper && datasz == 2) { stepper->rotate((int8_t)data[1]); sendResponseMsg(cmdID, data, 1); } else { sendErrorMsg_P (ERRORMSG_INVALID_ARGS); } break; } case SIMPLESTEPPERADDON_TICKSPERSTEP: { AddonStepper * stepper = getStepper (data[0]); if (stepper && datasz == 5) { unsigned long ticks = ( (unsigned long)data[1] << 24) | ((unsigned long)data[2] << 16) | ((unsigned long)data[3] << 8) | (unsigned long)data[4]; stepper->setTicksPerStep(ticks); sendResponseMsg(cmdID, data, 1); } else if(stepper && datasz == 1) { unsigned long t = stepper->getTicksPerStep(); data[1] = (t>>24)&0xff; data[2] = (t>>16)&0xff; data[3] = (t>>8)&0xff; data[4] = (t)&0xff; datasz = 5; sendResponseMsg (cmdID, data, datasz); } else { sendErrorMsg_P (ERRORMSG_INVALID_ARGS); } break; } case SIMPLESTEPPERADDON_STATUS: { AddonStepper * stepper = getStepper (data[0]); if (stepper && datasz == 1) { data[1] = stepper->status(); sendResponseMsg (cmdID, data, 2); } else { sendErrorMsg_P (ERRORMSG_INVALID_ARGS); } break; } case SIMPLESTEPPERADDON_STATE: { AddonStepper * stepper = getStepper (data[0]); if (stepper && datasz == 1) { data[1] = stepper->num_pins; data[2] = stepper->pins[0]; data[3] = stepper->pins[1]; data[4] = stepper->pins[2]; data[5] = stepper->pins[3]; data[6] = stepper->pins[4]; data[7] = stepper->status(); data[8] = stepper->direction; unsigned long t = stepper->steps_to_do; data[9] = (t>>24)&0xff; data[10] = (t>>16)&0xff; data[11] = (t>>8)&0xff; data[12] = (t)&0xff; t = stepper->ticksperstep; data[13] = (t>>24)&0xff; data[14] = (t>>16)&0xff; data[15] = (t>>8)&0xff; data[16] = (t)&0xff; t = stepper->laststeptick; data[17] = (t>>24)&0xff; data[18] = (t>>16)&0xff; data[19] = (t>>8)&0xff; data[20] = (t)&0xff; sendResponseMsg (cmdID, data, 21); } else { sendErrorMsg_P (ERRORMSG_INVALID_ARGS); } break; } default: { // notify of invalid cmd sendUnknownCmdIDMsg(); } } } void SimpleStepperAddon::loop() { for (int i = 0;i<MAX_SIMPLESTEPPERS;i++) { steppers[i].poll(); } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoioaddons/+SimpleStepper/src/SimpleStepperAddon.h������������������������0000644�0000000�0000000�00000001662�14777724260�023773� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> * * 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 * <https://www.gnu.org/licenses/>. */ #include "LibraryBase.h" class SimpleStepperAddon : public LibraryBase { public: SimpleStepperAddon(OctaveArduinoClass& a); void commandHandler(uint8_t cmdID, uint8_t* data, uint8_t datasz); virtual void loop(); }; ������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoioaddons/+adafruit/�����������������������������������������������������0000755�0000000�0000000�00000000000�14777724260�016267� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoioaddons/+adafruit/dcmotorv2.m������������������������������������������0000644�0000000�0000000�00000012000�14777724260�020355� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018-2020 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. classdef dcmotorv2 < arduinoio.AddonBase ## -*- texinfo -*- ## @deftypefn {} {} arduinoioaddons.adafruit.dcmotorv2 ## DC Motor class for dc motor control on the adafruit motor shield ## ## @seealso{arduinoioaddons.adafruit.motorshieldv2} ## @end deftypefn ## ## @subsubheading Properties ## @var{Speed} - The speed value set for the motor ## ## @var{Parent} - The parent shield for object (read only) ## ## @var{MotorNumber} - The motor number (read only) values 1-4 ## ## @var{IsRunning} - boolean for if the motor is started (read only) ## ## @subheading Methods ## @deftypefn {} {@var{obj} =} dcmotorv2(@var{mObj}, @var{mnum}) ## @deftypefnx {} {@var{obj} =} dcmotorv2(@var{mObj}, @var{mnum}, @var{propertyname, propertyvalue} ....) ## Constructor to create dcmotor object ## @subsubheading Inputs ## @var{mObj} - the motor shield object ## ## @var{mnum} - The motor number (1 - 4) ## ## @var{propertyname, propertyvalue} - Optional property name/value ## pairs to pass to motor object. ## ## Current known properties are: ## @table @asis ## @item Speed ## Initial speed (default 0). Should be a value between -1 and 1. ## @end table ## ## @subsubheading Outputs ## @var{s} - a dcmotorv2 object ## ## @subsubheading Example ## @example ## @code { ## a = arduino() ## ms = addon(a, "adafruit/motorshieldv2") ## mtr = dcmotor(ms, 1) ## } ## @end example ## @end deftypefn ## ## @deftypefn {} {} start(@var{dcObj}) ## Start the motor moving in previously set speed/direction ## ## @subsubheading Inputs ## @var{dcObj} - the dcmotor object ## ## @subsubheading Outputs ## None ## ## @seealso{adafruit.motorshieldv2} ## @end deftypefn ## ## @deftypefn {} {} stop(@var{dcObj}) ## Stop the motor moving ## ## @subsubheading Inputs ## @var{dcObj} - the dcmotor object ## ## @subsubheading Outputs ## None ## ## @seealso{adafruit.motorshieldv2} ## @end deftypefn properties(Access = private, Constant = true) INIT_COMMAND = hex2dec('20'); FREE_COMMAND = hex2dec('21'); START_COMMAND = hex2dec('22'); STOP_COMMAND = hex2dec('23'); endproperties properties(Access = private) cleanup; endproperties properties(GetAccess = public, SetAccess = private) MotorNumber; IsRunning = false; endproperties properties(Access = public) Speed = 0; endproperties methods function this = dcmotorv2(shield, mnum, varargin) validate_shield = @(x) isa(x, "arduinoioaddons.adafruit.motorshieldv2"); validate_mtrnum = @(x) (isnumeric(x) && isscalar(x) && (x >= 1 && x <= 4)); validate_speed = @(x) (isnumeric(x) && (x <= 1 && x >= -1)); p = inputParser(CaseSensitive=false, FunctionName='adafruit/dcmotorv2'); p.addRequired('shield',validate_shield); p.addRequired('mnum',validate_mtrnum); p.addParameter('Speed', 0, validate_speed); p.parse(shield, mnum, varargin{:}); this.Parent = p.Results.shield; this.MotorNumber = p.Results.mnum; this.Speed = p.Results.Speed; sendCommand(this.Parent, this.INIT_COMMAND,[this.MotorNumber-1]); this.cleanup = onCleanup (@() sendCommand(this.Parent, this.FREE_COMMAND, [this.MotorNumber-1])); endfunction function start(this) if this.Speed < 0 direction = 0; speed = -this.Speed*255; else direction = 1; speed = this.Speed*255; endif sendCommand(this.Parent,this.START_COMMAND,[this.MotorNumber-1, direction, speed]); this.IsRunning = true; endfunction function stop(this) sendCommand(this.Parent,this.STOP_COMMAND,[this.MotorNumber-1]); this.IsRunning = false; endfunction function set.Speed(this, newspeed) # check speed -1 .. 0 ... 1 if !isnumeric(newspeed) || newspeed < -1 || newspeed > 1 error("Speed should be between -1 .. 1"); endif this.Speed = newspeed; if this.IsRunning start(this); endif endfunction function disp(this) printf(" %s with properties\n", class(this)); printf(" MotorNumber = %d\n", this.MotorNumber); printf(" Speed = %d\n", this.Speed); printf(" IsRunning = %d\n", this.IsRunning); endfunction endmethods endclassdef arduino-0.12.2/inst/+arduinoioaddons/+adafruit/motorshieldv2.h��������������������������������������0000644�0000000�0000000�00000016437�14777724260�021254� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> * * 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 * <https://www.gnu.org/licenses/>. */ #include "LibraryBase.h" #define MTRV2_INIT 0x00 #define MTRV2_FREE 0x01 #define MTRV2_INIT_STEPPER 0x10 #define MTRV2_FREE_STEPPER 0x11 #define MTRV2_MOVE_STEPPER 0x12 #define MTRV2_RELEASE_STEPPER 0x13 #define MTRV2_INIT_DCMOTOR 0x20 #define MTRV2_FREE_DCMOTOR 0x21 #define MTRV2_START_DCMOTOR 0x22 #define MTRV2_STOP_DCMOTOR 0x23 // must add the adatfruit morotrshieldv2 library to arduino for this to compile #include <Adafruit_MotorShield.h> // Create the motor shield object with the default I2C address //Adafruit_MotorShield AFMS = Adafruit_MotorShield(); // Or, create it with a different I2C address (say for stacking) // Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x61); // Select which 'port' M1, M2, M3 or M4. In this case, M1 //Adafruit_DCMotor *myMotor = AFMS.getMotor(0); class MotorShieldV2Addon : public LibraryBase { Adafruit_MotorShield *AFMS; Adafruit_StepperMotor *stepperMotor[2]; Adafruit_DCMotor *dcMotor[4]; public: MotorShieldV2Addon(OctaveArduinoClass& a) { libName = "adafruit/MotorShieldV2"; a.registerLibrary(this); } void init() { byte i; AFMS = 0; for (i=0;i<2;i++) { stepperMotor[i] = 0; } for (i=0;i<4;i++) { dcMotor[i] = 0; } // AFMS.getStepper(200, 2); // myMotor->setSpeed(10); // 10 rpm // myMotor->step(100, FORWARD, SINGLE); // // Adafruit_DCMotor *myMotor = AFMS.getMotor(1); // // turn on motor M1 //myMotor->setSpeed(200); //myMotor->run(RELEASE); // // servo1.attach(10); } void commandHandler(uint8_t cmdId, uint8_t* data, uint8_t datasz) { switch(cmdId) { case MTRV2_INIT: { // send in the address // (currently) we only support a single control board if(datasz != 3) { sendInvalidNumArgsMsg(); } else { // TODO: pwm speed as well AFMS = new Adafruit_MotorShield(data[0]); uint16_t freq = data[1]; freq = (freq<<8)|data[2]; AFMS->begin(freq); // input freq sendResponseMsg(cmdId, data, 1); } break; } case MTRV2_FREE: { if(AFMS) { //AFMS->release(); delete AFMS; AFMS = 0; } sendResponseMsg(cmdId, data, 1); break; } case MTRV2_INIT_DCMOTOR: { // 0 = shieldid (spiaddress) // 1 = motor num if(datasz != 2) { sendInvalidNumArgsMsg(); } else if(data[1] > 3) { // TODO invalid value sendInvalidNumArgsMsg(); } else if(AFMS) { dcMotor[data[1]] = AFMS->getMotor(data[1]+1); if(dcMotor[data[1]]) { dcMotor[data[1]]->setSpeed(0); dcMotor[data[1]]->run(FORWARD); dcMotor[data[1]]->run(RELEASE); sendResponseMsg(cmdId, data, 2); } else { sendInvalidNumArgsMsg(); } } else { sendInvalidNumArgsMsg(); } break; } case MTRV2_FREE_DCMOTOR: { // 0 = shieldid (spiaddress) // 1 = motor num if(datasz != 2) { sendInvalidNumArgsMsg(); } else if(data[1] > 3) { // TODO invalid value sendInvalidNumArgsMsg(); } else { if(dcMotor[data[1]]) { //dcMotor[data[1]]->run(RELEASE); dcMotor[data[1]]->setSpeed(0); dcMotor[data[1]]->run(RELEASE); dcMotor[data[1]] = 0; } sendResponseMsg(cmdId, data, 2); } break; } case MTRV2_STOP_DCMOTOR: { // 0 = shieldid (spiaddress) // 1 = motor num if(datasz != 2) { sendInvalidNumArgsMsg(); } else if(data[1] > 3) { // TODO invalid value sendInvalidNumArgsMsg(); } else { if(dcMotor[data[1]]) { dcMotor[data[1]]->setSpeed(0); dcMotor[data[1]]->run(RELEASE); } sendResponseMsg(cmdId, data, 2); } break; } case MTRV2_START_DCMOTOR: { // 0 = shieldid (spiaddress) // 1 = motor num // 2 = dir 1=forwrf, else reverse // 3 = speed (0..255) if(datasz != 4) { sendInvalidNumArgsMsg(); } else if(data[1] > 3) { // TODO invalid value sendInvalidNumArgsMsg(); } else { if(dcMotor[data[1]]) { dcMotor[data[1]]->setSpeed(data[3]); dcMotor[data[1]]->run((data[2] == 1) ? FORWARD : BACKWARD); sendResponseMsg(cmdId, data, 2); } else { sendInvalidNumArgsMsg(); } } break; } case MTRV2_INIT_STEPPER: { // 0 = shieldid (spiaddress) // 1 = motor num // 2,3 = stepsprerev if(datasz != 4) { sendInvalidNumArgsMsg(); } else if(data[1] > 1) { // TODO invalid value sendInvalidNumArgsMsg(); } else if(AFMS) { uint16_t cnt = data[2]; cnt = (cnt<<8)|data[3]; stepperMotor[data[1]] = AFMS->getStepper(cnt, data[1]+1); if(stepperMotor[data[1]]) { sendResponseMsg(cmdId, data, 2); } else { sendInvalidNumArgsMsg(); } } else { sendInvalidNumArgsMsg(); } break; } case MTRV2_FREE_STEPPER: { // 0 = shieldid (spiaddress) // 1 = motor num if(datasz != 2) { sendInvalidNumArgsMsg(); } else if(data[1] > 1) { // TODO invalid value sendInvalidNumArgsMsg(); } else { if(stepperMotor[data[1]]) { //dcMotor[data[1]]->run(RELEASE); stepperMotor[data[1]]->release(); stepperMotor[data[1]] = 0; } sendResponseMsg(cmdId, data, 2); } break; } case MTRV2_RELEASE_STEPPER: { // 0 = shieldid (spiaddress) // 1 = motor num if(datasz != 2) { sendInvalidNumArgsMsg(); } else if(data[1] > 1) { // TODO invalid value sendInvalidNumArgsMsg(); } else { if(stepperMotor[data[1]]) { stepperMotor[data[1]]->release(); } sendResponseMsg(cmdId, data, 2); } break; } case MTRV2_MOVE_STEPPER: { // 0 = shieldid (spiaddress) // 1 = motor num // 2 = dir 1=forward, else reverse // 3,4 uint16 rpm // 5,6 steps // 7 steptype if(datasz != 8) { sendInvalidNumArgsMsg(); } else if(data[1] > 1) { // TODO invalid value sendInvalidNumArgsMsg(); } else { if(stepperMotor[data[1]]) { uint16_t rpm = data[3]; rpm = rpm<<8 | data[4]; uint16_t steps = data[5]; steps = steps<<8 | data[6]; uint8_t style = data[7]; style = SINGLE; if(style == 1) style = DOUBLE; if(style == 2) style = INTERLEAVE; if(style == 3) style = MICROSTEP; stepperMotor[data[1]]->setSpeed(rpm); sendWaitMsg(); stepperMotor[data[1]]->step(steps, (data[2] == 1) ? FORWARD : BACKWARD, style); sendResponseMsg(cmdId, data, 2); } else { sendInvalidNumArgsMsg(); } } break; } default: { // notify of invalid cmd sendUnknownCmdIDMsg(); } break; } } }; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoioaddons/+adafruit/motorshieldv2.m��������������������������������������0000644�0000000�0000000�00000016314�14777724260�021253� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018-2020 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. classdef motorshieldv2 < arduinoio.LibraryBase ## -*- texinfo -*- ## @deftypefn {} {} arduinoioaddons.adafruit.motorshieldv2 ## Adafruit motor shield addon ## ## @seealso{addon} ## @end deftypefn ## ## @subsubheading Properties ## @var{Parent} - the parent arduino object. ## ## @var{Pins} - the pins allocated the addon. ## ## @var{I2CAddress} - the i2c address used for accessing this shield. ## ## @var{PWMFrequency} - the set PWM frequency for this shield. ## ## @subheading Methods ## @deftypefn {} {@var{obj} =} motorshieldv2(@var{arObj}) ## @deftypefnx {} {@var{obj} =} motorshieldv2(@var{arObj}, @var{propertyname, propertyvalue} ....) ## Constructor to create motorshieldv2 addon object ## @subsubheading Inputs ## @var{arObj} - the arduino parent object ## ## @var{propertyname, propertyvalue} - optional property name, value pairs. ## Current known properties are: ## @table @asis ## @item address ## I2C address of the motor shield (default 0x60) ## @item pwmfrequency ## PWM Frequency to set on shield (default 1600) ## @end table ## ## @subsubheading Outputs ## @var{obj} - created motorshieldv2 object ## ## @subsubheading Example ## @example ## @code { ## a = arduino() ## mtr = addon(a, "adafruit/motorshieldv2") ## } ## @end example ## @end deftypefn ## ## @deftypefn {} {@var{s} =} servo(@var{mObj}, @var{mtrnum}) ## @deftypefnx {} {@var{s} =} servo(@var{mObj}, @var{mtrnum}, @var{propertyname}, @var{propertyvalue} ...) ## Create a servo object ## ## @subsubheading Inputs ## @var{mObj} - the motor shield object ## ## @var{mtrnum} - The servo motor number, where 1 is servo on ## pin "d10" and 2 is a servo on pin "d9" ## ## @var{propertyname}, @var{propertyvalue} - Optional property ## name/value pairs to pass to servo object. ## ## Properties are the same as the base servo object. ## ## @subsubheading Outputs ## @var{s} - a servo object ## ## @subsubheading Example ## @example ## @code { ## a = arduino() ## ms = addon(a, "adafruit/motorshieldv2") ## # get servo 1 (servo on pin D10) ## s = ms.servo(1) ## } ## @end example ## ## The function if the equivalent of calling the arduino.servo with ## the D9 or D10 pin has the input pin. ## ## @seealso{servo} ## @end deftypefn ## ## @deftypefn {} {@var{s} =} stepper(@var{mObj}, @var{mtrnum}, @var{stepsperrev}) ## @deftypefnx {} {@var{s} =} stepper(@var{mObj}, @var{mtrnum}, @var{stepsperrev}, @var{propertyname}, @var{propertyvalue} ...) ## Create a stepper motor object ## ## @subsubheading Inputs ## @var{mObj} - the motor shield object ## ## @var{mtrnum} - The stepper motor number (1 or 2) ## ## @var{stepsperrev} - Number of steps per revolution. ## ## @var{propertyname}, @var{propertyvalue} - Optional property ## name/value pairs to pass to stepper object. ## ## @subsubheading Outputs ## @var{s} - a stepper object ## ## @end deftypefn ## ## @deftypefn {} {@var{s} =} dcmotor(@var{mObj}, @var{mtrnum}) ## @deftypefnx {} {@var{s} =} dcmotor(@var{mObj}, @var{mtrnum}, @var{propertyname}, @var{propertyvalue} ...) ## Create a dcmotor motor object ## ## @subsubheading Inputs ## @var{mObj} - the motor shield object ## ## @var{mtrnum} - The motor number (1 - 4) ## ## @var{propertyname}, @var{propertyvalue} - Optional property ## name/value pairs to pass to motor object. ## ## @subsubheading Outputs ## @var{s} - a dcmotorv2 object ## ## @end deftypefn # commands properties(Access = private, Constant = true) INIT_COMMAND = hex2dec('00'); FREE_COMMAND = hex2dec('01'); endproperties properties(Access = protected, Constant = true) LibraryName = 'adafruit/MotorShieldV2'; DependentLibraries = { "i2c", "servo" }; ArduinoLibraryHeaderFiles = {}; CppHeaderFile = fullfile(arduinoio.FilePath(mfilename('fullpath')), 'motorshieldv2.h'); CppClassName = 'MotorShieldV2Addon'; endproperties properties(Access = private) i2c; cleanup; endproperties properties(GetAccess = public, SetAccess = private) PWMFrequency; I2CAddress; endproperties methods # constructor function obj = motorshieldv2(parentObj, varargin) # parse args p = inputParser(CaseSensitive=false, FunctionName='adafruit/MotorShieldV2'); p.addParameter('I2CAddress', 0x60, @isnumeric); p.addParameter('PWMFrequency', 1600, @isnumeric); p.parse(varargin{:}); obj.Parent = parentObj; obj.I2CAddress = p.Results.I2CAddress; obj.i2c = device(parentObj, "i2caddress", p.Results.I2CAddress); obj.Pins = obj.i2c.Pins; obj.PWMFrequency = p.Results.PWMFrequency; intval = uint16(obj.PWMFrequency); freq = [ bitshift(intval,-8) bitand(intval, 255)]; data = sendCommand(obj.Parent, obj.LibraryName, obj.INIT_COMMAND, [p.Results.I2CAddress freq]); obj.cleanup = onCleanup (@() sendCommand(obj.Parent, obj.LibraryName, obj.FREE_COMMAND, [p.Results.I2CAddress])); endfunction function s = servo (obj, mnum, varargin) if nargin < 2 error ("Expected shield and mnum") endif pinval = []; if mnum == 1 pinval = "d10"; elseif mnum == 2 pinval = "d9"; else error ("Invalid servo motor number - (should be 1 or 2)") endif s = servo(obj.Parent, pinval, varargin{:}); endfunction function s = stepper (obj, mnum, stepsperrev, varargin) if nargin < 3 error ("Expected shield and mnum and stepsperrev") endif s = arduinoioaddons.adafruit.stepper(obj, mnum, stepsperrev, varargin{:}); endfunction function m = dcmotor (obj, mnum, varargin) if nargin < 2 error ("Expected shield and mnum") endif m = arduinoioaddons.adafruit.dcmotorv2(obj, mnum, varargin{:}); endfunction function disp(this) printf(" %s with properties\n", class(this)); printf(" I2CAddress = %d (0x%X)\n", this.i2c.i2caddress, this.i2c.i2caddress); # show i2c pins as the pins printf(" Pins = {\n"); for i=1:numel(this.Pins) printf(" %s\n", this.Pins{i}); endfor printf(" }\n"); printf(" PWMFrequency = %d\n", this.PWMFrequency); endfunction endmethods methods (Access = public) function data = sendCommand(obj, commandid, data) [data,~] = sendCommand(obj.Parent, obj.LibraryName, commandid, [obj.i2c.i2caddress data]); endfunction endmethods endclassdef ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinoioaddons/+adafruit/stepper.m��������������������������������������������0000644�0000000�0000000�00000015452�14777724260�020136� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. classdef stepper < arduinoio.AddonBase ## -*- texinfo -*- ## @deftypefn {} {} arduinoioaddons.adafruit.stepper ## Stepper class for stepper control on the adafruit motor shield ## ## @seealso{arduinoioaddons.adafruit.motorshieldv2} ## @end deftypefn ## ## @subsubheading Properties ## @table @asis ## @item @var{RPM} ## The rpm value set for the stepper motor ## @item StepType ## the StepType for the stepper (string) which can be "single", ## "double", "interleave" or "microstep" ## @item StepsPerRevolution ## the StepsPerRevoluion for the stepper (read only) ## @item MotorNumber ## the motor number for the stepper (read only) value will be 1 or 2. ## @item Parent ## the parent shield of this stepper (read only) ## @end table ## ## @subheading Methods ## @deftypefn {} {@var{obj} =} stepper(@var{mObj}, @var{mnum}, @var{stepsperrev}) ## @deftypefnx {} {@var{obj} =} stepper(@var{mObj}, @var{mnum}, @var{stepsperrev}, @var{propertyname, propertyvalue} ....) ## Constructor to create dcmotor object ## @subsubheading Inputs ## @var{mObj} - the motor shield object ## ## @var{mnum} - The motor number (1 or 2) ## ## @var{stepsperrev} - Number of steps per revolution. ## ## @var{propertyname, propertyvalue} - Optional property ## name/value pairs to pass to motor object. ## ## Current known properties are: ## @table @asis ## @item RPM ## the RPM for the stepper (revolutions per minute) ## @item StepType ## the StepType for the stepper (string) which can be ## "single", "double", "interleave" or "microstep" ## @end table ## ## @subsubheading Outputs ## @var{s} - a stepper object ## ## @subsubheading Example ## @example ## @code { ## a = arduino() ## ms = addon(a, "adafruit/motorshieldv2") ## mtr = stepper(ms, 1, 200) ## } ## @end example ## @end deftypefn ## ## @deftypefn {} {} move(@var{sObj}, @var{steps}) ## Move the motor moving in the specified steps using the configured RPM. ## ## @subsubheading Inputs ## @var{sObj} - the stepper object ## ## @subsubheading Outputs ## None ## ## @seealso{adafruit.motorshieldv2} ## @end deftypefn ## ## @deftypefn {} {} release(@var{sObj}) ## Release this motor ## ## @subsubheading Inputs ## @var{sObj} - the stepper object ## ## @subsubheading Outputs ## None ## ## @seealso{adafruit.motorshieldv2} ## @end deftypefn properties(Access = private, Constant = true) INIT_COMMAND = hex2dec('10'); FREE_COMMAND = hex2dec('11'); MOVE_COMMAND = hex2dec('12'); RELEASE_COMMAND = hex2dec('13'); endproperties properties(Access = private) cleanup; endproperties properties(GetAccess = public, SetAccess = private) MotorNumber; StepsPerRevolution = 0; endproperties properties(Access = public) RPM = 0; StepType = "single"; endproperties methods function this = stepper(shield, mnum, stepsperrev, varargin) ## if nargin < 3 ## error ("Expected shield, mnum and stepsperrev") ## endif ## ## if ~isa(shield, "arduinoioaddons.adafruit.motorshieldv2") ## error("Expected shield to be a motorshieldv2 object"); ## endif ## ## # check num is a number ## if mnum != 1 && mnum != 2 ## error("Expected motor number to be 1 or 2"); ## endif p = inputParser(CaseSensitive=false, FunctionName='adafruit/stepper'); validate_shield = @(x) isa(x, "arduinoioaddons.adafruit.motorshieldv2"); validate_mtrnum = @(x) (isnumeric(x) && isscalar(x) && (x ==1 || x ==2)); validate_steps = @(x) (isnumeric(x) && isscalar(x) && (x > 0)); validate_rpm = @(x) (isnumeric(x) && isscalar(x) && (x > 0)); p.addRequired('shield',validate_shield); p.addRequired('mnum',validate_mtrnum); p.addRequired('stepsperrev',validate_steps); p.addParameter('RPM', 0, validate_rpm); p.addParameter('StepType', "single", @(x) any(validatestring(x,{"single", "double", "interleave", "microstep"}))); p.parse(shield, mnum, stepsperrev, varargin{:}); this.Parent = p.Results.shield; this.MotorNumber = p.Results.mnum; this.StepsPerRevolution = p.Results.stepsperrev; this.RPM = p.Results.RPM; this.StepType = p.Results.StepType; intval = uint16(stepsperrev); steps = [ bitshift(intval,-8) bitand(intval, 255)]; sendCommand(this.Parent, this.INIT_COMMAND,[this.MotorNumber-1 steps]); this.cleanup = onCleanup (@() sendCommand(this.Parent, this.FREE_COMMAND, [this.MotorNumber-1 steps])); endfunction function move(this, steps) if steps < 0 direction = 0; steps = -steps; else direction = 1; endif intval = uint16(steps); steps = [ bitshift(intval,-8) bitand(intval, 255)]; intval = uint16(this.RPM); rpm = [ bitshift(intval,-8) bitand(intval, 255)]; steptype = 0; switch lower(this.StepType) case "single" steptype = 0; case "double" steptype = 1; case "interleave" steptype = 2; case "microstep" steptype = 3; endswitch sendCommand(this.Parent,this.MOVE_COMMAND,[this.MotorNumber-1, direction, rpm, steps, steptype]); endfunction function release(this) sendCommand(this.Parent,this.RELEASE_COMMAND,[this.MotorNumber-1]); endfunction function set.RPM(this, newrpm) # check rpm if !isnumeric(newrpm) || newrpm < 0 error("RPM should be a positive number"); endif this.RPM = newrpm; endfunction function set.StepType(this, val) validate_val = validatestring (val, {"single", "double", "interleave", "microstep"}); this.StepType = val; endfunction function disp(this) printf(" %s with properties\n", class(this)); printf(" MotorNumber = %d\n", this.MotorNumber); printf(" RPM = %d\n", this.RPM); printf(" StepsPerRevolution = %d\n", this.StepsPerRevolution); printf(" StepType = %s\n", this.StepType); endfunction endmethods endclassdef ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinosensor/�����������������������������������������������������������������0000755�0000000�0000000�00000000000�14777724260�014126� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinosensor/DS1307.m���������������������������������������������������������0000644�0000000�0000000�00000016034�14777724260�015131� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019-2020 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. classdef DS1307 < handle ## -*- texinfo -*- ## @deftypefn {} {} arduinosensor.DS1307 ## DS1307 realtime clock sensor ## @end deftypefn ## ## @subheading Methods ## @deftypefn {} {@var{obj} =} DS1307(@var{arObj}) ## @deftypefnx {} {@var{obj} =} DS1307(@var{arObj}, @var{propertyname, propertyvalue} ....) ## Constructor to create DS1307 sensor ## @subsubheading Inputs ## @var{arObj} - the arduino parent object ## ## @var{propertyname, propertyvalue} - optional property name, value pairs. ## Current known properties are: ## Current properties are: ## @table @asis ## @item i2caddress ## I2C address of the DS1307 (default 0x68) ## @end table ## ## @subsubheading Outputs ## @var{obj} - created DS1307 object ## ## @subsubheading Example ## @example ## @code { ## a = arduino() ## rtc = arduinosensor.DS1307(a) ## } ## @end example ## @end deftypefn ## ## @deftypefn {} {@var{date} =} clock(@var{dsObj}) ## @deftypefnx {} {} clock(@var{dsObj}, @var{date}) ## Get/set the DS1307 clock ## ## @subsubheading Inputs ## @var{dsObj} - the ds1307 object ## ## @var{date} - a date vector in same format as datevec and clock ## ## @subsubheading Outputs ## @var{date} - a date vector in same format as datevec and clock ## ## @subsubheading Example ## @example ## @code { ## a = arduino() ## rtc = arduinosensor.DS1307(a) ## # get and display rtc time as a date string ## datestr(rtc.clock) ## } ## @end example ## @seealso{datevec} ## @end deftypefn ## ## @deftypefn {} {@var{ctrl} =} control(@var{dsObj}) ## @deftypefnx {} {} control(@var{dsObj}, @var{ctrl}) ## Get/set the DS1307 clock ## ## @subsubheading Inputs ## @var{dsObj} - the ds1307 object ## ## @var{ctrl} - a structure containing the control bit fields. ## ## @subsubheading Outputs ## @var{ctrl} - a structure containing the control bit fields. ## ## Control structure fields are: ## Current properties are: ## @table @asis ## @item out ## Out bit in the control register ## @item sqwe ## Square wave enable bit in control register ## @item rs ## The combined RS0, RS1 value ## @end table ## ## @end deftypefn ## ## @deftypefn {} {@var{YN} =} isstarted(@var{dsObj}) ## Get whether the RTC clock is currently counting time ## ## @subsubheading Inputs ## @var{dsObj} - the ds1307 object ## ## @subsubheading Outputs ## @var{YN} - returns true if the RTC is counting ## ## @seealso{start, stop} ## @end deftypefn ## ## @deftypefn {} {} start(@var{dsObj}) ## Start the RTC counting ## ## @subsubheading Inputs ## @var{dsObj} - the ds1307 object ## ## @subsubheading Outputs ## None ## ## @seealso{datevec} ## @end deftypefn ## ## @deftypefn {} {} stop(@var{dsObj}) ## Stop the RTC counting ## ## @subsubheading Inputs ## @var{dsObj} - the ds1307 object ## ## @subsubheading Outputs ## None ## ## @seealso{datevec} ## @end deftypefn properties(Access = private) i2c; bcd2dec = @(v) bitshift(v, -4)*10 + bitand(v, 0xf); dec2bcd = @(v) bitshift(floor(v/10), 4) + bitand(mod(v,10), 0xf); endproperties methods # constructor function this = DS1307(parentObj, varargin) if nargin < 1 || ! isarduino(parentObj) error('arduinosensor.DS1307: expected arduino object as first parameter'); endif # parse args p = inputParser(CaseSensitive=false, FunctionName='arduinosensor.DS1307'); p.addParameter('I2CAddress', 0x68, @isnumeric); p.parse(varargin{:}); # do we have the address ? address = p.Results.I2CAddress; i2caddresses = scanI2Cbus(parentObj); idx = find(cellfun ( @(x) strcmp(x, sprintf("0x%02X", address)), i2caddresses)); if isempty(idx) error('arduinosensor.DS1307: no matching i2c address found on bus'); endif this.i2c = device(parentObj, "i2caddress", p.Results.I2CAddress); endfunction function c = clock (this, settime) if nargin == 2 # set time wd = weekday(datenum(settime)); writeRegister(this.i2c, 0, ... [this.dec2bcd(floor(settime(6))), this.dec2bcd(settime(5)), (this.dec2bcd(settime(4))), ... wd, this.dec2bcd(settime(3)), this.dec2bcd(settime(2)), this.dec2bcd(mod(settime(1),100))] ... ); else # get time data = readRegister(this.i2c, 0, 7); secs = double(this.bcd2dec(bitand(data(1), 0x7f))); mins = double(this.bcd2dec(data(2))); if bitand(data(3), 0x40) != 0 # 12 hr pm = bitand(data(3), 0x20); hrs = double(this.bcd2dec(bitand(data(3), 0x2f))); if pm hrs = double(hrs + 12); endif else hrs = double(this.bcd2dec(bitand(data(3), 0x3f))); endif wday = double(data(4)); day = double(this.bcd2dec(data(5))); month = double(this.bcd2dec(data(6))); year = 2000.0 + double(this.bcd2dec(data(7))); c = double([year, month, day, hrs, mins, secs]); endif endfunction function start(this) data = readRegister(this.i2c, 0, 1); data = bitset(data, 8, 0); writeRegister(this.i2c, 0, data); endfunction function stop(this) data = readRegister(this.i2c, 0, 1); data = bitset(data, 8, 1); writeRegister(this.i2c, 0, data); endfunction function val = isstarted(this) data = readRegister(this.i2c, 0, 1); val = bitget(data, 8) == 0; endfunction function bits = control(this, setbits) if nargin == 1 data = readRegister(this.i2c, 7, 1); bits = {}; bits.out = bitget(data, 8); bits.sqwe = bitget(data, 5); bits.rs = bitand(data, 0x03); else data = 0; data = bitand(setbits.rs, 0x3); if setbits.out data = data + 0x80; endif if setbits.sqwe data = data + 0x10; endif writeRegister(this.i2c, 7, data); endif endfunction function disp(this) printf(" %s with properties\n", class(this)); if isobject(this.i2c) printf(" I2C Address = 0x%X\n", this.i2c.i2caddress); else printf(" Not connected"); endif endfunction function delete(this) try if isobject(this.i2c) delete(this.i2c); this.i2c = []; endif catch # do nothing end_try_catch endfunction endmethods endclassdef ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinosensor/GUVAS12SD.m������������������������������������������������������0000644�0000000�0000000�00000007374�14777724260�015576� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019-2020 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. classdef GUVAS12SD < handle ## -*- texinfo -*- ## @deftypefn {} {} arduinosensor.GUVAS12SD ## A thin wrapper for the GUVAS12SD analog UV-B sensor ## @end deftypefn ## ## @subheading Methods ## @deftypefn {} {@var{obj} =} GUVAS12SD(@var{arObj}, @var{pin}) ## Constructor to create GUVAS12SD sensor ## @subsubheading Inputs ## @var{arObj} - the arduino parent object ## ## @var{pin} - the analog pin that the sensor is connected to ## ## @subsubheading Outputs ## @var{obj} - created GUVAS12SD object ## ## @subsubheading Example ## @example ## @code { ## a = arduino() ## # create sensor attached to pin a0. ## sensor = arduinosensor.GUVAS12SD(a, "a0") ## } ## @end example ## @end deftypefn ## ## @deftypefn {} {@var{V} =} read(@var{dsObj}) ## Read the voltage of the sensor ## ## @subsubheading Inputs ## @var{dsObj} - the GUVAS12SD object ## ## @subsubheading Outputs ## @var{V} - read voltage - effectively equivalent to ## readAnalogPin(arObj, pin). ## ## @subsubheading Example ## @example ## @code { ## a = arduino() ## s = arduinosensor.GUVAS12SD(a) ## # voltage ## volts = s.read ## } ## @end example ## @seealso{arduinosensor.GUVAS12SD} ## @end deftypefn ## ## @deftypefn {} {@var{Idx} =} readIndex(@var{dsObj}) ## Read the UV index ## ## @subsubheading Inputs ## @var{dsObj} - the GUVAS12SD object ## ## @subsubheading Outputs ## @var{Idx} - the sensor reading as a UV index reading ## @end deftypefn ## ## @deftypefn {} {@var{uA} =} readuA(@var{dsObj}) ## Read the uA of the sensor ## ## @subsubheading Inputs ## @var{dsObj} - the GUVAS12SD object ## ## @subsubheading Outputs ## @var{uA} - the sensor reading as a uAmp value ## @end deftypefn properties(Access = private, constant = true) SCALE_UAMPS = 4.1; SCALE_INDEX = 0.1; endproperties properties(GetAccess = public, SetAccess = private) Pin; Parent; endproperties methods # constructor function this = GUVAS12SD(parentObj, pin, varargin) if nargin < 2 error('arduinosensor.GUVAS12SD: expected arduino and pin object parameters'); endif if ! isarduino(parentObj) error('arduinosensor.GUVAS12SD: expected arduino object as first parameter'); endif # check is an analog pin validatePin(parentObj, pin, "analog"); # lookup/use name for pin (in the case where a terminal num was given instead of a pin number) this.Pin = getPinInfo(parentObj, pin).name; this.Parent = parentObj; endfunction function val = read (this) # Vo = 4.3 * diodeuA # UV index = Vo/0.1 val = readAnalogPin(this.Parent, this.Pin); endfunction function val = readIndex (this) val = read(this)/this.SCALE_INDEX; endfunction function val = readuA (this) val = read(this)/this.SCALE_UAMPS; endfunction function disp(this) printf(" %s with properties\n", class(this)); printf(" Pin = %s\n", this.Pin); endfunction endmethods endclassdef ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinosensor/MPC3002.m��������������������������������������������������������0000644�0000000�0000000�00000010215�14777724260�015227� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019-2020 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. classdef MPC3002 < handle ## -*- texinfo -*- ## @deftypefn {} {} arduinosensor.MPC3002 ## MCP3002 ADC sensor ## @end deftypefn ## ## @subheading Methods ## @deftypefn {} {@var{obj} =} MPC3002(@var{arObj}, @var{selectPin}) ## @deftypefnx {} {@var{obj} =} MPC3002(@var{arObj}, @var{selectPin}, @var{propertyname, propertyvalue} ....) ## Constructor to create MPC3002 sensor ## @subsubheading Inputs ## @var{arObj} - the arduino parent object ## ## @var{selectPin} - the SPI cs select pin ## ## @var{propertyname, propertyvalue} - optional property name, value pairs. ## ## Current properties are: ## @table @asis ## @item referenceVoltage ## Reference voltage for scaling the ADC inputs (default 5.0) ## @end table ## ## @subsubheading Outputs ## @var{obj} - created MCP3002 object ## ## @subsubheading Example ## @example ## @code { ## a = arduino() ## sensor = arduinosensor.MPC3002(a, "d10") ## } ## @end example ## @end deftypefn ## ## @deftypefn {} {@var{voltage} =} readVoltage(@var{dsObj}, @var{chan}) ## Read the voltage from a channel ## ## @subsubheading Inputs ## @var{dsObj} - the MPC3002 object ## ## @var{chan} - the channel to read (0 or 1) ## ## @subsubheading Outputs ## @var{voltage} - read voltage. ## ## @subsubheading Example ## @example ## @code { ## a = arduino() ## s = arduinosensor.MPC3002(a, "d10") ## volts = readVoltage(s, 0) ## } ## @end example ## @seealso{arduinosensor.MPC3002} ## @end deftypefn properties(Access = private, constant = true) VERSION = "0.0.1"; CHAN_0_READ = [ hex2dec("DF") hex2dec("FF") ]; CHAN_1_READ = [ hex2dec("EF") hex2dec("FF") ]; endproperties properties(Access = private) spi = []; reference_voltage = 5.0; endproperties methods # constructor function this = MPC3002(parentObj, selectpin, varargin) if nargin < 2 || ! isarduino(parentObj) error('arduinosensor.MPC3002: expected arduino object as first parameter, followed by a select pin'); endif # parse args p = inputParser(CaseSensitive=false, FunctionName='arduinosensor.MPC3002'); p.addParameter('referenceVoltage', 5.0, @isnumeric); p.parse(varargin{:}); this.spi = device(parentObj, "spichipselectpin", selectpin); this.reference_voltage = p.Results.referenceVoltage; # initial read v = writeRead(this.spi, this.CHAN_1_READ); endfunction function volts = readVoltage(this, chan) if nargin < 2 || !isnumeric(chan) || (chan != 1 && chan != 0) error('arduinosensor.MPC3002 read: expected channel number 0 or 1'); endif if chan == 0 cmd = this.CHAN_0_READ; else cmd = this.CHAN_1_READ; endif v = writeRead(this.spi, cmd); adc = bitand (uint16(v(1))*256 + uint16(v(2)), hex2dec('3FF')); volts = double(adc) * this.reference_voltage / 1023.0; endfunction function disp(this) printf(" %s with properties\n", class(this)); printf(" reference voltage = %f\n", this.reference_voltage); if isobject(this.spi) printf(" SPI cs = %s\n", this.spi.spichipselectpin); else printf(" Not connected"); endif endfunction function delete(this) try if isobject(this.spi) delete(this.spi); this.spi = []; endif catch # do nothing end_try_catch endfunction endmethods endclassdef �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+arduinosensor/SI7021.m���������������������������������������������������������0000644�0000000�0000000�00000013577�14777724260�015146� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019-2020 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. classdef SI7021 < handle ## -*- texinfo -*- ## @deftypefn {} {} arduinosensor.SI7021 ## SI7021 temperature and humidity sensor ## @end deftypefn ## ## @subheading Methods ## @deftypefn {} {@var{obj} =} SI7021(@var{arObj}) ## @deftypefnx {} {@var{obj} =} SI7021(@var{arObj}, @var{propertyname, propertyvalue} ....) ## Constructor to create SI7021 sensor ## @subsubheading Inputs ## @var{arObj} - the arduino parent object ## ## @var{propertyname, propertyvalue} - optional property name, value pairs. ## Current known properties are: ## Current properties are: ## @table @asis ## @item i2caddress ## I2C address of the SI7021 (default 0x40) ## @end table ## ## @subsubheading Outputs ## @var{obj} - created SI7020 object ## ## @subsubheading Example ## @example ## @code { ## a = arduino() ## sensor = arduinosensor.SI7021(a) ## } ## @end example ## @end deftypefn ## ## @deftypefn {} {@var{C} =} temperature(@var{dsObj}) ## Read the temperature ## ## @subsubheading Inputs ## @var{dsObj} - the si7021 object ## ## @subsubheading Outputs ## @var{C} - read temperature in deg C. ## ## @subsubheading Example ## @example ## @code { ## a = arduino() ## s = arduinosensor.SI7021(a) ## # get temp ## temp = s.temperature ## } ## @end example ## @seealso{arduinosensor.SI7021} ## @end deftypefn ## ## @deftypefn {} {@var{relH} =} humidity(@var{dsObj}) ## Read the relative humidity ## ## @subsubheading Inputs ## @var{dsObj} - the si7021 object ## ## @subsubheading Outputs ## @var{relH} - relative humidity as a percentage (0 - 100.0) ## @end deftypefn ## ## @deftypefn {} {@var{relH} =} info(@var{dsObj}) ## Read the sensor info ## ## @subsubheading Inputs ## @var{dsObj} - the si7021 object ## ## @subsubheading Outputs ## @var{inf} - structure containing the sensor information. ## ## Structure fields are: ## @table @asis ## @item version ## Chip firmware version ## @item id ## sensor id1,id2 value ## @item type ## String for detected chip type ## @end table ## ## @end deftypefn properties(Access = private, constant = true) SENSOR_ID_1 = [ hex2dec("FA") hex2dec("F0") ]; SENSOR_ID_2 = [ hex2dec("FC") hex2dec("C9") ]; SENSOR_VERSION = [ hex2dec("84") hex2dec("B8") ]; TEMP_MEASURE_NOHOLD = hex2dec("F3"); HUMIDITY_MEASURE_NOHOLD = hex2dec("F5"); endproperties properties(Access = private) i2c; endproperties methods # constructor function this = SI7021(parentObj, varargin) if nargin < 1 || ! isarduino(parentObj) error('arduinosensor.SI7021: expected arduino object as first parameter'); endif # parse args p = inputParser(CaseSensitive=false, FunctionName='arduinosensor.SI7021'); p.addParameter('I2CAddress', 0x40, @isnumeric); p.parse(varargin{:}); # do we have the address ? address = p.Results.I2CAddress; i2caddresses = scanI2Cbus(parentObj); idx = find(cellfun ( @(x) strcmp(x, sprintf("0x%02X", address)), i2caddresses)); if isempty(idx) error('arduinosensor.SI7021: no matching i2c address found on bus'); endif this.i2c = device(parentObj, "i2caddress", p.Results.I2CAddress); endfunction function inf = info (this) write (this.i2c, this.SENSOR_ID_1); id1 = read(this.i2c, 1); write (this.i2c, this.SENSOR_ID_2); id2 = read(this.i2c, 1); if id2 == hex2dec("15") type = "Si7021"; elseif id2 == hex2dec("14") type = "Si7020"; elseif id2 == hex2dec("0D") type = "Si7013"; elseif id2 == hex2dec("32") type = "HTU21D"; else type = "Unknown"; endif write (this.i2c, this.SENSOR_VERSION); ver = read(this.i2c, 1); if ver == hex2dec("FF") ver = 1.0; else ver = double(ver)/10.0; endif inf = {}; inf.version = ver; inf.type = type; inf.id = int32(id1)*256 + int32(id2); endfunction function C = temperature (this) % write command to get temp write (this.i2c, uint8([this.TEMP_MEASURE_NOHOLD])); pause (0.02); data = read (this.i2c, 3); value = uint16(data(1))*256 + uint16(data(2)); value = bitand (value, hex2dec("FFFC")); temp_Code = double(value); C = (175.72*temp_Code/65536)-46.85; # F = (C * 1.8) + 32.0; endfunction function H = humidity(this) write (this.i2c, uint8([this.HUMIDITY_MEASURE_NOHOLD])); pause (0.02); data = read (this.i2c, 3); value = uint16(data(1))*256 + uint16(data(2)); value = bitand (value, hex2dec("FFFC")); humidity_Code = double(value); H = (125.0*humidity_Code/65536)-6; endfunction function disp(this) printf(" %s with properties\n", class(this)); if isobject(this.i2c) printf(" I2C Address = 0x%X\n", this.i2c.i2caddress); else printf(" Not connected"); endif endfunction function delete(this) try if isobject(this.i2c) delete(this.i2c); this.i2c = []; endif catch # do nothing end_try_catch endfunction endmethods endclassdef ���������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+matlabshared/������������������������������������������������������������������0000755�0000000�0000000�00000000000�14777724260�013662� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+matlabshared/+addon/�����������������������������������������������������������0000755�0000000�0000000�00000000000�14777724260�015022� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/+matlabshared/+addon/LibraryBase.m����������������������������������������������0000644�0000000�0000000�00000004770�14777724260�017407� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2021 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. classdef LibraryBase < arduinoio.LibraryBase ## -*- texinfo -*- ## @deftypefn {} {} matlabshared.addon.LibraryBase ## Compatability class used for arduino library plugins using ## matlabshared.addons.LibraryBase ## ## @seealso{arduinoio.LibraryBase, arduino, listArduinoLibraries, addon} ## @end deftypefn ## ## @subheading Properties ## Base properties are expected to be inherited and overwritten in ## inherited classes and are constant in order to query through the ## metaobject mechanism. ## ## @var{LibraryName} - name of the addon library ## ## @var{DependentLibraries} - array of dependent library names that ## must be included when installing this plugin. ## ## @var{CppHeaderFile} - name (if any) of header file that will be ## included into the arduino project when adding this library. ## ## @var{CppSourceFile} - name (if any) of source file that will be ## included into the arduino project when adding this library. ## ## @var{CppClassName} - name of the cpp class for the addon library. ## project when adding this library. ## ## @var{Pins} - pins allocated to the addon ## ## @var{Parent} - parent arduino object. ## ## @subheading Methods ## @deftypefn {} {@var{lb} =} LibraryBase () ## Constructor of base class ## ## The constructor is usually not called but called indirectly ## from the addon function. ## ## @subsubheading Outputs ## The return value @var{lb} is an object of the ## matlabshare.addons.LibraryBase class. ## ## @seealso{arduino, listArduinoLibraries, addon} ## @end deftypefn ## ## @deftypefn {} {} disp () ## Display the addon in a verbose way. ## @end deftypefn methods (Access=public) function this = LibraryBase () # nothing to do endfunction endmethods endclassdef ��������arduino-0.12.2/inst/@arduino/�����������������������������������������������������������������������0000755�0000000�0000000�00000000000�14777724260�012721� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/__freeArduino__.m������������������������������������������������������0000644�0000000�0000000�00000001617�14777724260�016143� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. see ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} __freeArduino__ (@var{obj}) ## Private function ## @end deftypefn function retval = __freeArduino__ (obj, port, board) if isobject (obj.connected) fclose(obj.connected); obj.connected = false; endif retval = obj; endfunction �����������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/__initArduino__.m������������������������������������������������������0000644�0000000�0000000�00000007750�14777724260�016171� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018-2022 John Donoghue <john.donoghue@ieee.org> ## ## 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. see ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} __initArduino__ (@var{obj}, @var{port}, @var{board}, @var{scan_only}) ## Private function ## @end deftypefn function retval = __initArduino__ (obj, port, board, scan_only) % send command and get back reponse ARDUINO_INIT = 1; ARDUINO_GETLIB = 8; ok = false; if !isempty(port) || !ischar(port) # port maybe ip address ? if !isempty(regexp(port, "^[0-9]+.[0-9]+.[0-9]+.[0-9]+$")) obj.connected = tcp (port, 9500, 10); else obj.connected = serialport (port, 'BaudRate', obj.BaudRate, 'Timeout', .2); endif # need wait for arduino to potentially startup pause(2); # clear any data in buffers set(obj.connected, "timeout", 0.1); data = fread(obj.connected,100); while length(data) >= 100 data = fread(obj.connected,100); if obj.debug printf("flushing %d bytes of data\n", length(data)); endif endwhile [dataout, status] = __sendCommand__(obj, 0, ARDUINO_INIT); if status != 0 error ("__initArduino__: failed valid response err=%d - %s", status, char(dataout)); endif % uno r3 - atmega32 1E 95 0F sig = (uint32(dataout(1))*256*256) + (uint32(dataout(2))*256) + uint32(dataout(3)); % work out mcu switch sig case 0 mcu = ""; case { hex2dec("1E9502"), hex2dec("009502") } mcu = "atmega32"; case { hex2dec("1E950F"), hex2dec("00950F") } mcu = "atmega328p"; case { hex2dec("1E9514"), hex2dec("009514") } mcu = "atmega328pu"; case hex2dec("1E9801") mcu= "atmega2560"; case hex2dec("1E9703") mcu = "atmega1280"; case hex2dec("1E9702") mcu = "atmega128"; case hex2dec("1E9587") mcu = "atmega32u4"; case hex2dec("1E9651") mcu = "atmega4809"; otherwise mcu = sprintf("unknown_mcu(%X)", sig); endswitch boardtype = arduinoio.boardTypeString(dataout(4)); voltref = double(dataout(5))/10.0; numlib = uint8(dataout(6)); flags = 0; if length(dataout) > 6 flags = dataout(7); endif % check board against config info if ~isempty(board) && !strcmpi(board, boardtype) warning("connected %s arduino does not match requested board type %s", boardtype, board) endif obj.config = arduinoio.getBoardConfig(boardtype); # update values that could change obj.config.port = port; obj.config.baudrate = obj.BaudRate; obj.config.board = boardtype; obj.config.voltref = voltref; obj.config.flags = flags; if isa(obj.connected, "octave_tcp") obj.config.port = 9500; obj.config.deviceaddress = port; endif if ! isempty(mcu) obj.config.mcu = mcu; elseif isempty(obj.config.mcu) obj.config.mcu = "unknown"; endif obj.config.libs = {}; # query libs if ! scan_only for libid = 0:numlib-1 [dataout, status] = __sendCommand__(obj, 0, ARDUINO_GETLIB, [libid]); if status != 0 error ("__initArduino__: failed get lib %d err=%d - %s", libid, status, char(dataout)); else lib = {}; lib.id = libid; lib.name = lower(char(dataout(2:end))); obj.config.libs{end+1} = lib; endif endfor endif else error ("__initArduino__: expected a valid port"); endif retval = obj; endfunction ������������������������arduino-0.12.2/inst/@arduino/arduino.m��������������������������������������������������������������0000644�0000000�0000000�00000036530�14777724260�014547� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018-2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. classdef arduino < handle ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} arduino () ## @deftypefnx {} {@var{retval} =} arduino (@var{port}) ## @deftypefnx {} {@var{retval} =} arduino (@var{port}, @var{board}) ## @deftypefnx {} {@var{retval} =} arduino (@var{port}, @var{board}[, [@var{propname}, @var{propvalue}]*) ## @deftypefnx {} {@var{retval} =} arduino (@var{iaddress}) ## @deftypefnx {} {@var{retval} =} arduino (@var{ipaddress}, @var{board}) ## Create a arduino object with a connection to an arduino board. ## ## @subsubheading Inputs ## @var{port} - full path of serial port to connect to. For Linux, ## usually /dev/ttySXXX, for windows COMXX. ## ## @var{board} - name of board to connect (default is 'uno'). ## ## @var{propname}, @var{propvalue} - property name and value pair ## for additional properties to pass to the creation of the ## arduino object. ## ## Currently properties are ignored, with the exception of: ## @table @asis ## @item debug ## true / false flag for whether setting debug (default false) ## @item forcebuildon ## true / false flag for whether to force show of the arduino IDE to ## rebuild the installed code on the arduino (default false) ## @item baudrate (read only) ## the communications baudrate to the board. (default 9600) ## @item libraries ## The libraries to be enabled on the arduino board. (default uses whatever is already installed) ## @end table ## ## if the arduino function is called without parameters, it will scan ## for the first available arduino it can find and connect to it. ## ## @subsubheading Outputs ## @var{retval} - a successfully connected arduino object. ## ## @subsubheading Properties ## The arduino object has the following public properties: ## @table @asis ## @item name ## name assigned to the arduino object ## @item debug ## true / false flag for whether debug is turned on ## @item forcebuildon ## true / false flag for whether to force show of the arduino IDE to ## reprogram the arduino ## @item port (read only) ## the communications port the board is connected to. ## @item baudrate (read only) ## the communications baudrate to the board. ## @item board (read only) ## The name of the board type that the arduino connected to ## @item libraries (read only) ## The libraries currently programmed onto the board ## @item availablepins ## The pins available for use on the board ## @item analogreference ## The analog voltage reference ## @end table ## @seealso{scanForArduinos, arduinosetup} ## @end deftypefn properties (Access = private) config = {}; resources = {}; connected = false; endproperties properties (Access = public) name = ""; debug = false; endproperties # matlab compatible properties properties (SetAccess = private) AvailablePins = []; Libraries = []; AnalogReference = 5.0; Board = ""; Port = ""; BaudRate = 9600; endproperties properties (SetAccess = private, Hidden = true) DeviceAddress = ""; endproperties methods (Access = public) function this = arduino (varargin) if (nargin == 0) arduinos = scanForArduinos (1); if isempty (arduinos) error ("arduino: No arduinos found on serial scan"); endif this.name = "arduino"; c = arduinoio.getBoardConfig(arduinos{1}.board); this.BaudRate = c.baudrate; this = __initArduino__ (this, arduinos{1}.port, arduinos{1}.board, 0); elseif (nargin == 1) arg0 = varargin{1}; if (isa (arg0, "arduino")) # copy this.config = arg0.config; this.resources = arg0.resources; this.name = arg0.name; this.connected = arg0.connected; elseif ischar(arg0) # port given this.name = "arduino"; this.connected = false; this = __initArduino__ (this, arg0, "", 0); else error ("arduino: port must be a string"); endif else # at least port, board [optional property pairs] port = varargin{1}; board = varargin{2}; if isempty (port) arduinos = scanForArduinos (1, board); if isempty (arduinos) error ("arduino: No matching arduinos found on serial scan"); endif port = arduinos{1}.port; board = arduinos{1}.board; c = arduinoio.getBoardConfig(arduinos{1}.board); this.BaudRate = c.baudrate; elseif !ischar (port) error ("arduino: port must be a string"); endif if !ischar (board) error ("arduino: board must be a string"); endif if mod (nargin, 2) != 0 error ("arduino: expected property name, value pairs"); endif if !iscellstr (varargin (3:2:nargin)) error ("arduino: expected property names to be strings"); endif this.name = ["arduino " board]; requiredlibs = {}; forcebuild = false; forcebuildon = false; scan_only = false; for i = 3:2:nargin propname = tolower (varargin{i}); propvalue = varargin{i+1}; #printf("%s = %s\n", propname, propvalue); if strcmp (propname,"debug") if propvalue this.debug = 1; endif endif if strcmp (propname,"_scan_only") # internal property scan_only = propvalue; endif if strcmp (propname,"libraries") if ischar (propvalue) requiredlibs{end+1} = propvalue; elseif iscellstr (propvalue) requiredlibs = propvalue; else error ("arduino: expect libraries value to be a libraryname or cellarray of library names"); endif endif if strcmp (propname,"forcebuildon") if islogical (propvalue) || (isnumeric(propvalue) && (propvalue == 1 || propvalue == 0)) forcebuildon = propvalue; else error ("arduino: expect forcebuildon to be true or false"); endif endif if strcmp (propname,"baudrate") if !isnumeric(propvalue) error ("arduino: expect baudrate to be numeric"); else this.BaudRate = int32(propvalue); if this.BaudRate < 1200 error ("arduino: Invalid baudrate"); endif endif endif # older option that probally should remove if strcmp (propname,"forcebuild") if islogical (propvalue) || (isnumeric(propvalue) && (propvalue == 1 || propvalue == 0)) forcebuild = propvalue; else error ("arduino: expect forcebuild to be true or false"); endif endif endfor this = __initArduino__ (this, port, board, scan_only); # check have requested libs reprogram = false; if forcebuildon reprogram = true; elseif ! scan_only availablelibs = listArduinoLibraries (); for i = 1:numel (requiredlibs) lib = requiredlibs{i}; id = this.get_lib (lib); if id < 0 idx = find( cellfun(@(x) strcmpi(x, lib), availablelibs), 1); if isempty (idx) error ('arduino: unknown library "%s"', lib); elseif forcebuild warning ('arduino: not configured with library "%s" - will need to reprogram', lib); reprogram = true; else error ('arduino: not configured with library "%s" - please rerun arduinosetup with library, or set forcebuild', lib); endif endif endfor endif if reprogram printf("starting reprogram process ....\n") # free arduino resources, reprom and then reinit this = __freeArduino__(this); if !arduinosetup ('libraries', requiredlibs, 'baudrate', this.BaudRate) error ("arduinosetup returned a failure, so did not reprogram") endif this = __initArduino__ (this, port, board, 0); endif endif endfunction endmethods methods (Hidden = true) # helper functions function set_debug (this, d) this.debug = d; endfunction function d = get_debug (this) this = this.debug; endfunction # helper functions that get/set values in the private config function m = get_mcu (this) m = this.config.mcu; endfunction function m = get_flags (this) m = this.config.flags; endfunction function m = get_endian (this) if bitand(this.config.flags, 0x80) != 0 m = "B"; else m = "L"; endif endfunction function id = get_lib (this, name) idx = find( cellfun(@(x) strcmpi(x.name, name), this.config.libs), 1); if isempty (idx) id = -1; else id = this.config.libs{idx}.id; endif endfunction function set_pin (this, pin, info) if ischar(pin) idx = find (cellfun(@(x) strcmpi (x.name, pin), this.config.pins), 1); else idx = find (cellfun(@(x) (x.d == pin), this.config.pins), 1); endif if isempty (idx) error ("arduino: unknown pin"); endif this.config.pins{idx} = info; endfunction function info = get_pin (this, pin) if ischar(pin) idx = find (cellfun(@(x) strcmpi (x.name, pin), this.config.pins), 1); else idx = find (cellfun(@(x) (x.id == pin), this.config.pins), 1); endif if isempty (idx) error (["arduino: unknown pin " pin]); endif info = this.config.pins{idx}; endfunction function info = get_altpin (this, pin) idx = find (cellfun(@(x) (sum(strcmpi (x.altnames, pin))>0), this.config.pins), 1); if !isempty (idx) info = this.config.pins{idx}; else info = {}; endif endfunction function retval = get_group(this,type) retval = {}; for i = 1:numel (this.config.pins) pininfo = this.config.pins{i}; idx = find (cellfun(@(x) strncmpi (x, type, length (type)), pininfo.modes), 1); if !isempty(idx) values = strsplit (pininfo.modes{idx}, "_"); info = {}; info.name = pininfo.name; info.func = values{2}; info.mode = pininfo.mode; info.owner = pininfo.owner; retval{end+1}= info; endif endfor endfunction function retval = get_pingroup(this, pin, type) retval = {}; pininfo = this.get_pin(pin); idx = find (cellfun(@(x) strncmpi(x, type, length(type)), pininfo.modes), 1); if !isempty (idx) # possibly this will be in format of # type[XX]_YY where XX is a number ir: spi0, spi1 etc, ## _YY will be the pinfunction ie: scl, miso etc values = strsplit (pininfo.modes{idx}, "_"); type = values{1}; for i = 1:numel (this.config.pins) pininfo = this.config.pins{i}; idx = find (cellfun(@(x) strncmpi(x, type, length (type)), pininfo.modes), 1); if !isempty(idx) values = strsplit(pininfo.modes{idx}, "_"); info = {}; info.name = pininfo.name; info.func = values{2}; info.mode = pininfo.mode; info.owner = pininfo.owner; retval{end+1}= info; endif endfor endif endfunction function ref = analogreference(this) ref = this.config.voltref; endfunction function pins = availablepins(this) pins = {}; for i=1:numel (this.config.pins) pins{end+1} = this.config.pins{i}.name; endfor endfunction function libs = libraries(this) libs = {}; for i=1:numel (this.config.libs) if ! strcmpi(this.config.libs{i}.name, "core") libs{end+1} = this.config.libs{i}.name; endif endfor endfunction function p = port(this) p = this.config.port; endfunction function b = board(this) b = this.config.board; endfunction function set_resource (this, resource, res) resource = tolower (resource); # make sure noone tries to change the name used for searching res.name = resource; idx = find (cellfun(@(x) strcmp(x.name, resource), this.resources), 1); if isempty (idx) this.resources{end+1} = res; else this.resources{idx} = res; endif endfunction function res = get_resource (this, resource) resource = tolower(resource); idx = find (cellfun(@(x) strcmp(x.name, resource), this.resources), 1); if isempty (idx) # none currently res = {}; res.name = resource; res.count = 0; res.owner = ""; res.props = struct(); else res = this.resources{idx}; endif endfunction function v = board_voltage (this) v = this.config.voltref; endfunction function v = get.AvailablePins (this) v = availablepins(this); endfunction function v = get.Libraries (this) v = libraries(this); endfunction function v = get.AnalogReference (this) v = this.config.voltref; endfunction function v = get.Board (this) v = this.config.board; endfunction function v = get.Port (this) v = this.config.port; endfunction function v = get.DeviceAddress (this) v = this.config.deviceaddress; endfunction endmethods endclassdef %!shared arduinos %! arduinos = scanForArduinos(1); %!assert(numel(arduinos), 1); %!test %! ar = arduino(); %! assert(!isempty(ar)); %! assert(ar.port, arduinos{1}.port); %! assert(ar.board, arduinos{1}.board); %! assert(numel(ar.availablepins) > 0); %!test %! ar = arduino(arduinos{1}.port); %! assert(!isempty(ar)); %! assert(ar.port, arduinos{1}.port); %! assert(ar.board, arduinos{1}.board); %!test %! ar = arduino(arduinos{1}.port, arduinos{1}.board); %! assert(!isempty(ar)); %! assert(isa(ar, "arduino")) %! assert(ar.port, arduinos{1}.port); %! assert(ar.board, arduinos{1}.board); %!test %! ar = arduino(); %! # verify have compiled support for functions we will be testing %! assert(!isempty(find(cellfun(@(x) strcmpi(x, "spi"), ar.libraries()), 1))) %! assert(!isempty(find(cellfun(@(x) strcmpi(x, "i2c"), ar.libraries()), 1))) %! assert(!isempty(find(cellfun(@(x) strcmpi(x, "servo"), ar.libraries()), 1))) %! assert(!isempty(find(cellfun(@(x) strcmpi(x, "shiftregister"), ar.libraries()), 1))) %! assert(!isempty(find(cellfun(@(x) strcmpi(x, "rotaryencoder"), ar.libraries()), 1))) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/checkI2CAddress.m������������������������������������������������������0000644�0000000�0000000�00000004703�14777724260�015764� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} checkI2CAddress (@var{ar}, @var{address}) ## @deftypefnx {} {@var{retval} =} checkI2CAddress (@var{ar}, @var{address}, @var{bus}) ## Check that an address of given address responds on the I2C bus ## ## @subsubheading Inputs ## @var{ar} - arduino object connected to a arduino board. ## ## @var{address} - I2C address number to check ## ## @var{bus} - bus number to check for I2C device, when multiple buses are available. ## If the bus is not specified, it will default to 0. ## ## @subsubheading Outputs ## @var{retval} - boolean value of true if address responds on the I2C bus ## ## @subsubheading Example ## @example ## @code { ## # create arduino connection. ## ar = arduino(); ## # scan for devices on the I2C bus ## checkI2CAddress (ar) ## # output if a device using that address is attached ## ans = ## 1 ## } ## @end example ## ## @seealso{arduino, scanI2Cbus} ## @end deftypefn function ret = checkI2CAddress (ar, address, bus) persistent ARDUINO_I2C_SCAN = 0; ret = false; if nargin < 2 || nargin > 3 print_usage (); endif if nargin == 2 bus = 0; elseif !isnumeric (bus) || bus < 0 || bus > 1 error ('checkI2CAddress: expected bus to be numeric and 0 or 1'); endif if (!isa (ar, "arduino")) error ("checkI2CAddress: expects arduino object as 1st argument"); endif if !isnumeric (address) || address < 1 || address > 127 error ('checkI2CAddress: expected address to be numeric 1 > address <= 127'); endif # TODO: configure SPI pins if not already done?? [tmp, sz] = sendCommand (ar, "i2c", ARDUINO_I2C_SCAN, [bus address]); if tmp(3) == 1 ret = true; endif endfunction %!test %! ar = arduino(); %! assert(!isempty(ar)); %! checkI2CAddress(ar, 12); �������������������������������������������������������������arduino-0.12.2/inst/@arduino/configurePin.m���������������������������������������������������������0000644�0000000�0000000�00000010146�14777724260�015531� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{currmode} =} configurePin (@var{ar}, @var{pin}) ## @deftypefnx {} {} configurePin (@var{ar}, @var{pin}, @var{mode}) ## Set/Get pin mode for a specified pin on arduino connection. ## ## configurePin (@var{ar}, @var{pin}) will get the current mode of the specified pin. ## ## configurePin (@var{ar}, @var{pin}, @var{mode}) will attempt set the pin to the specified ## mode if the mode is unset. ## ## @subsubheading Inputs ## @var{ar} - the arduino object of the connection to an arduino board. ## ## @var{pin} - string name of the pin to set/get the mode of. ## ## @var{mode} - string mode to set the pin to. ## ## @subsubheading Outputs ## @var{mode} - string current mode of the pin. ## ## Valid modes can be: ## @itemize @bullet ## @item AnalogInput ## - Acquire analog signals from pin ## @item DigitalInput ## - Acquire digital signals from pin ## @item DigitalOutput ## - Generate digital signals from pin ## @item I2C ## - Specify a pin to use with I2C protocol ## @item Pullup ## - Specify pin to use a pullup switch ## @item PWM ## - Specify pin to use a pulse width modulator ## @item Servo ## - Specify pin to use a servo ## @item SPI ## - Specify a pin to use with SPI protocol ## @item Interrupt ## - Specify a pin to use for with interrupts ## @item Reserved ## - Specify a pin to be reserved ## @item Unset ## - Clears pin designation. The pin is no longer reserved and can be automatically ## set at the next operation. ## @end itemize ## ## @seealso{arduino} ## ## @end deftypefn function retval = configurePin (obj, pin, mode) persistent ARDUINO_CONFIGPIN = 2; if nargin != 2 && nargin != 3 error ("@arduino.configurePin: expected pin name and value"); endif if !ischar (pin) && !isnumeric (pin) error ("@arduino.configurePin: expected pin name as string"); endif pininfo = obj.get_pin (pin); if nargin == 3 % set mode if !ischar (mode) error ("@arduino.configurePin: expected pin mode as string"); endif mode = tolower (mode); [pinstate, pinmode] = pinStateMode (mode); if strcmp (pinmode,"spi") # check special case of when pin is miso, make it an input idx = find (cellfun(@(x) ~isempty (strfind (x, "_miso")), pininfo.modes), 1); if !isempty (idx) pinstate = 2; endif endif % valid setting for this pin ? if !strcmpi (mode, "unset") && !strcmp(mode, "reserved") validatePin (obj, pin, pinmode); else pinmode = getResourceOwner (obj, pin); endif % own this pin configurePinResource (obj, pin, pinmode, mode); # send config command to arduino datain = uint8 ([pininfo.id pinstate]); [dataout, status] = __sendCommand__ (obj, 0, ARDUINO_CONFIGPIN, datain); if status != 0 error ("@arduino.configurePin: failed to set pin state err=%d - %s", status, char(dataout)); endif else % get mode ? datain = uint8 ([pininfo.id]); [dataout, status] = __sendCommand__ (obj, 0, ARDUINO_CONFIGPIN, datain); if status != 0 error ("@arduino.configurePin: failed to set pin state err=%d - %s", status, char(dataout)); endif retval = pinStateMode (dataout(2)); endif endfunction %!test %! ar = arduino(); %! assert(!isempty(ar)); %! configurePin(ar, "d2", "digitaloutput"); %! assert(configurePin(ar, "d2"), "digitaloutput"); %! configurePin(ar, "d2", "unset"); %! assert(configurePin(ar, "d2"), "unset"); ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/configurePinResource.m�������������������������������������������������0000644�0000000�0000000�00000010104�14777724260�017233� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018-2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{currmode} =} configurePinResource (@var{ar}, @var{pin}) ## @deftypefnx {} {} configurePinResource (@var{ar}, @var{pin}, @var{owner}, @var{mode}) ## @deftypefnx {} {} configurePinResource (@var{ar}, @var{pin}, @var{owner}, @var{mode}, @var{force}) ## Set/Get pin mode for a specified pin on arduino connection. ## ## configurePinResource (@var{ar}, @var{pin}) will get the current mode of the specified pin. ## ## configurePinResource (@var{ar}, @var{pin}, @var{owner}, @var{mode}) will attempt set the pin to the specified ## mode and owner. ## ## If the pin is already owned by another owner, the configure will fail unless the force option is used. ## If the mode is already set, configure will fail unless force is used. ## ## @subsubheading Inputs ## @var{ar} - the arduino object of the connection to an arduino board. ## ## @var{pin} - string name of the pin to set/get the mode of. ## ## @var{mode} - string mode to set the pin to. ## ## @var{owner} - string name to use as the pin owner. ## ## @var{force} - boolean to force mode change. If not set, it will be false. ## ## @subsubheading Outputs ## @var{currmode} - current string mode of the pin. ## ## Valid modes can be: ## @itemize @bullet ## @item AnalogInput ## - Acquire analog signals from pin ## @item DigitalInput ## - Acquire digital signals from pin ## @item DigitalOutput ## - Generate digital signals from pin ## @item I2C ## - Specify a pin to use with I2C protocol ## @item Pullup ## - Specify pin to use a pullup switch ## @item PWM ## - Specify pin to use a pulse width modulator ## @item Servo ## - Specify pin to use a servo ## @item SPI ## - Specify a pin to use with SPI protocol ## @item Interrupt ## - Specify a pin to use with interrupts ## @item Reserved ## - Pin marked reserved, but not for of any particular mode ## @item Unset ## - Clears pin designation. The pin is no longer reserved and can be automatically ## set at the next operation. ## @end itemize ## ## @seealso{arduino, configurePin} ## @end deftypefn function retval = configurePinResource (obj, pin, owner, mode, forceconfig) if nargin != 2 && nargin != 4 && nargin != 5 error ('@arduino.configurePinResource: invalid number of arduments supplied'); endif if !ischar(pin) error ("@arduino.configurePinResource: expected pin name as string"); endif pininfo = obj.get_pin (pin); if nargin == 2 % return current mode retval = pininfo.mode; else if nargin == 4 forceconfig = false; endif if !isempty (pininfo.owner) && !strcmpi (pininfo.owner, owner) && !forceconfig error ("@arduino.configurePinResource: pin already owned"); endif if !strcmpi (pininfo.mode, "unset") && !strcmpi (pininfo.mode, mode) && !forceconfig && !strcmpi (mode, "unset") error ("@arduino.configurePinResource: pin mode already set"); endif if (strcmpi (mode, "unset")) owner = ""; endif pininfo.owner = owner; pininfo.mode = mode; obj.set_pin (pin, pininfo); endif endfunction %!shared ar %! ar = arduino(); %!test %! configurePinResource(ar, "d2", "test", "digitaloutput"); %! assert(getResourceOwner(ar,"d2"), "test") %! assert(getTerminalMode(ar, "d2"), "digitaloutput"); %!test %! configurePinResource(ar, "a0", "test1", "analoginput"); %! assert(getResourceOwner(ar,"a0"), "test1") %! assert(getTerminalMode(ar, "a0"), "analoginput"); ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/decrementResourceCount.m�����������������������������������������������0000644�0000000�0000000�00000003403�14777724260�017566� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{count} =} decrementResourceCount (@var{ar}, @var{resource}) ## Decrement the count of a named resource by 1 and return the ## new count. ## ## @subsubheading Inputs ## @var{ar} - connected arduino object ## ## @var{resource} - name of resource to decrement count. ## ## @subsubheading Outputs ## @var{count} = count of uses registered to resource. ## ## @seealso{getResourceCount. incrementResourceCount} ## @end deftypefn function retval = decrementResourceCount (ar, resource) if nargin != 2 print_usage (); endif if !ischar (resource) error ("@arduino.decrementResourceCount: expects resource name"); endif resinfo = ar.get_resource (resource); if resinfo.count == 0 error ("@arduino.decrementResourceCount: resource count is 0"); endif resinfo.count --; ar.set_resource (resource, resinfo); retval = resinfo.count; endfunction %!test %! ar = arduino(); %! assert(!isempty(ar)); %! assert(getResourceCount(ar,"notusedname"), 0); %! assert(incrementResourceCount(ar,"notusedname"), 1); %! assert(getResourceCount(ar,"notusedname"), 1); %! assert(decrementResourceCount(ar,"notusedname"), 0); %! assert(getResourceCount(ar,"notusedname"), 0); �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/delete.m���������������������������������������������������������������0000644�0000000�0000000�00000001555�14777724260�014347� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} delete (@var{dev}) ## Free resources of an arduino object. ## ## @subsubheading Inputs ## @var{dev} - object to free ## ## @seealso{arduino} ## @end deftypefn function delete(this) try this.connected = false; catch # do nothing end_try_catch endfunction ���������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/disp.m�����������������������������������������������������������������0000644�0000000�0000000�00000004750�14777724260�014044� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} disp (@var{ar}) ## Display the arduino object in a verbose way, showing the board and available pins. ## ## @subsubheading Inputs ## @var{ar} - the arduino object. ## ## If the arduino object has debug mode set, additional information will be displayed. ## ## @seealso{arduino} ## @end deftypefn function disp (ar) if isobject(ar.connected) printf (" arduino object with fields of: \n"); if isa(ar.connected, "octave_tcp") printf (" deviceaddress = ") disp (ar.config.deviceaddress); endif printf (" port = ") disp (ar.config.port); printf (" board = ") disp (ar.config.board); printf (" libraries = {\n") libs = ar.libraries (); for i=1:numel (libs) printf (" %s\n", libs{i}); endfor printf(" }\n"); # group pins where can nextpin = ""; startpin = {}; endpin = {}; printf (" availablepins = {\n") for i=1:numel (ar.config.pins) pin = ar.config.pins{i}; if !strcmpi(nextpin, pin.name) if !isempty(endpin) printf (" %s - %s\n", startpin.name, endpin.name); elseif !isempty(startpin) printf (" %s\n", startpin.name); endif startpin = pin; endpin = {}; else if isempty(startpin) startpin = pin; else endpin = pin; endif endif parts = sscanf(pin.name, "%c %d"); nextpin = sprintf("%c%d", char(parts(1)), parts(2)+1); endfor if !isempty(endpin) printf (" %s - %s\n", startpin.name, endpin.name); elseif !isempty(startpin) printf (" %s\n", startpin.name); endif printf(" }\n"); else printf (" arduino object disconnected\n"); endif if ar.debug printf (" config = \n"); disp (ar.config); endif endfunction ������������������������arduino-0.12.2/inst/@arduino/getEndian.m������������������������������������������������������������0000644�0000000�0000000�00000002264�14777724260�015001� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2021 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{mcu} =} getEndian (@var{ar}) ## Get the endian used by the connected arduino. ## ## @subsubheading Inputs ## @var{ar} - arduino object connected to a arduino board. ## ## @subsubheading Outputs ## @var{endian} - string representing the endian used by the arduino board. ## ## 'L' means little endian, ## 'B' means big endian ## ## @seealso{arduino, getMCU} ## @end deftypefn function retval = getEndian (obj) retval = obj.get_endian (); endfunction %!test %! ar = arduino (); %! assert (!isempty (ar)); %! mcu = getEndian (ar); %! assert (ischar (mcu)) %! assert (mcu, ar.get_endian ()) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/getI2CTerminals.m������������������������������������������������������0000644�0000000�0000000�00000003016�14777724260�016033� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{pinlist} =} getI2CTerminals (@var{ar}) ## @deftypefnx {} {@var{pinlist} =} getI2CTerminals (@var{ar}, @var{bus}) ## Get a cell list of pin Ids available are used for I2C mode. ## ## @subsubheading Inputs ## @var{ar} - the arduino object. ## ## @var{bus} - optional bus number 0 or 1 for boards that support more than 1 bus. ## ## @subsubheading Outputs ## @var{pinlist} - cell list of pin numbers available for I2C use. ## ## @seealso{arduino} ## @end deftypefn function retval = getI2CTerminals (obj, bus) if nargin < 1 || nargin > 2 print_usage() endif if nargin < 2 bus = 0; endif retval = getTypeTerminals(obj, sprintf("i2c%d", bus)); if isempty(retval) && bus == 0 retval = getTypeTerminals(obj, "i2c"); endif endfunction %!test %! ar = arduino(); %! assert(!isempty(ar)); %! terms = getI2CTerminals(ar); %! assert (numel(terms) > 0) %! # should be pairs of i2c pins %! assert (mod(numel(terms),2), 0) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/getInterruptTerminals.m������������������������������������������������0000644�0000000�0000000�00000002263�14777724260�017455� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{pinlist} =} getInterruptTerminals (@var{ar}) ## Get a cell list of pin Ids available have interrupt functionality ## ## @subsubheading Inputs ## @var{ar} - the arduino object. ## ## @subsubheading Outputs ## @var{pinlist} - cell list of pin numbers available for interrupt use. ## ## @seealso{arduino} ## @end deftypefn function retval = getInterruptTerminals (obj) if nargin != 1 print_usage () endif retval = getTypeTerminals (obj, "interrupt"); endfunction %!test %! ar = arduino(); %! assert(!isempty(ar)); %! terms = getInterruptTerminals(ar); %! assert(!isempty(terms)); ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/getLEDTerminals.m������������������������������������������������������0000644�0000000�0000000�00000002174�14777724260�016066� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{pinlist} =} getLEDTerminals (@var{ar}) ## Get a cell list of pin Ids available are connected natively to LEDs. ## ## @subsubheading Inputs ## @var{ar} - the arduino object. ## ## @subsubheading Outputs ## @var{pinlist} - cell list of pin numbers available for LED use. ## ## @seealso{arduino} ## @end deftypefn function retval = getLEDTerminals (obj) if nargin != 1 print_usage () endif retval = getTypeTerminals (obj, "led"); endfunction %!test %! ar = arduino(); %! assert(!isempty(ar)); %! terms = getLEDTerminals(ar); ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/getMCU.m���������������������������������������������������������������0000644�0000000�0000000�00000002135�14777724260�014224� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{mcu} =} getMCU (@var{ar}) ## Get the MCU used by the connected arduino. ## ## @subsubheading Inputs ## @var{ar} - arduino object connected to a arduino board. ## ## @subsubheading Outputs ## @var{mcu} - string representing the mcu used by the arduino board. ## ## @seealso{arduino} ## @end deftypefn function retval = getMCU (obj) retval = obj.get_mcu (); endfunction %!test %! ar = arduino (); %! assert (!isempty (ar)); %! mcu = getMCU (ar); %! assert (ischar (mcu)) %! assert (mcu, ar.get_mcu ()) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/getPWMTerminals.m������������������������������������������������������0000644�0000000�0000000�00000002204�14777724260�016117� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{pinlist} =} getPWMTerminals (@var{ar}) ## Get a cell list of pin Ids available for PWM use. ## ## @subsubheading Inputs ## @var{ar} - the arduino object. ## ## @subsubheading Outputs ## @var{pinlist} - cell list of pin numbers available for PWM use. ## ## @seealso{arduino} ## @end deftypefn function retval = getPWMTerminals(obj) if nargin != 1 print_usage() endif retval = getTypeTerminals(obj, "pwm"); endfunction %!test %! ar = arduino(); %! assert(!isempty(ar)); %! terms = getPWMTerminals(ar); %! assert (numel(terms) > 0) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/getPinAlias.m����������������������������������������������������������0000644�0000000�0000000�00000002631�14777724260�015301� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2021 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{ouy} =} getPinAlias (@var{ar}, @var{pin}) ## Get the pin actual pin name from a pin alias. ## ## For example, the arduino Leonardo, pin "D4" is also "A6". ## ## @subsubheading Inputs ## @var{ar} - the connected arduino object. ## ## @var{pin} - a pin name. ## ## @subsubheading Outputs ## @var{out} - alias pin name, or same as @var{pin} if the pin doesnt have any alias names. ## ## @seealso{arduino, configurePinResource, getResourceOwner} ## @end deftypefn function retval = getPinAlias (obj, pin) if nargin != 2 print_usage () endif if !ischar(pin) error ("Expected pin name") endif p = obj.get_altpin(pin); if isempty(p) p = obj.get_pin(pin); endif retval = p.name; endfunction %!test %! ar = arduino(); %! pin = getPinAlias(ar, "D0"); %! assert (toupper (pin), "D0"); %! clear a �������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/getPinInfo.m�����������������������������������������������������������0000644�0000000�0000000�00000007110�14777724260�015140� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{pininfo} =} getPinInfo (@var{ar}, @var{pin}) ## @deftypefnx {} {@var{pininfoarray} =} getPinInfo (@var{ar}, @var{pinarray}) ## Get the pin information from the input pins values. ## ## getPinInfo (@var{ar}, @var{pin}) will get information for a single pin. ## ## getPinInfo (@var{ar}, @var{pinarray}) will get a cell array of pin information ## ## @subsubheading Inputs ## @var{ar} - the connected arduino object. ## ## @var{pin} - a pin number or pin name. ## ## @var{pinarray} - the array of pin numbers or names ## ## The pininfo struct contains the following fields: ## @table @asis ## @item terminal ## Terminal number of the pin ## @item name ## String name of the pin ## @item owner ## Current item owner of the pin ## @item mode ## Current configured mode for the pin ## @end table ## ## @subsubheading Outputs ## @var{pininfo} - struct on pin information. ## ## @var{pininfolist} - cell array of pin info ## ## @seealso{arduino, configurePinResource, getResourceOwner} ## @end deftypefn function retval = getPinInfo (obj, pins) if nargin != 2 print_usage () endif if iscell (pins) retval = {}; for i=1:numel (pins) p = obj.get_pin(pins{i}); inf = {}; inf.name = p.name; inf.terminal = p.id; inf.owner = p.owner; inf.mode = p.mode; retval{end+1} = inf; endfor elseif ischar(pins) p = obj.get_pin(pins); inf = {}; inf.name = p.name; inf.terminal = p.id; inf.owner = p.owner; inf.mode = p.mode; retval = inf; elseif isvector (pins) && numel (pins) == 1 p = obj.get_pin(pins); inf = {}; inf.name = p.name; inf.terminal = p.id; inf.owner = p.owner; inf.mode = p.mode; retval = inf; elseif isvector (pins) retval = {}; for i=1:numel (pins) p = obj.get_pin(pins(i)); inf = {}; inf.name = p.name; inf.terminal = p.id; inf.owner = p.owner; inf.mode = p.mode; retval{end+1} = inf; endfor elseif isnumeric (pins) p = obj.get_pin(pins); inf = {}; inf.name = p.name; inf.terminal = p.id; inf.owner = p.owner; inf.mode = p.mode; retval = inf; else error ("@arduino.getPinInfo: expected pins a array of numbers or names"); endif endfunction %!shared ar %! ar = arduino(); %!test %! info = getPinInfo(ar, 0); %! # terminal 0 is alwars D0 ? %! assert (isstruct (info)); %! assert (!iscell (info)); %! assert (toupper (info.name), "D0"); %! assert (info.terminal, 0); %!test %! info = getPinInfo(ar, "d0"); %! # terminal 0 is alwars D0 ? %! assert (isstruct (info)); %! assert (!iscell (info)); %! assert (toupper (info.name), "D0"); %! assert (info.terminal, 0); %!test %! info = getPinInfo(ar, [0 2]); %! assert(numel(info), 2); %! assert(iscell(info)); %! assert (toupper (info{1}.name), "D0"); %! assert (toupper (info{2}.name), "D2"); %!test %! info = getPinInfo(ar, {"d4", 5}); %! assert(numel(info), 2); %! assert(iscell(info)); %! assert (toupper (info{1}.name), "D4"); %! assert (toupper (info{2}.name), "D5"); ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/getPinsFromTerminals.m�������������������������������������������������0000644�0000000�0000000�00000004265�14777724260�017222� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{pinnames} =} getPinsFromTerminals (@var{ar}, @var{terminals}) ## Get the pin names from the input terminal values. ## ## @subsubheading Inputs ## @var{ar} - the connected arduino object. ## ## @var{terminals} - the numeric pin number, or array of pin numbers to get pin names. ## ## @subsubheading Outputs ## @var{pinnames} - the string names of each input pin. If terminals was a single value, the return ## will be a single string, otherwise it will return a cell array of each pin name. ## ## @seealso{arduino, getTerminalsFromPins} ## @end deftypefn function retval = getPinsFromTerminals (obj, terminals) if nargin != 2 print_usage () endif if iscell (terminals) retval = {}; for i=1:numel (terminals) retval{end+1} = obj.get_pin (terminals{i}).name; endfor elseif isvector (terminals) && numel (terminals) == 1 retval = obj.get_pin (terminals).name; elseif isvector (terminals) retval = {}; for i=1:numel (terminals) retval{end+1} = obj.get_pin (terminals(i)).name; endfor elseif isnumeric (terminals) retval = obj.get_pin (terminals).name; else error ("@arduino.getPinsFromTerminals: expected terminals as vector"); endif endfunction %!shared ar %! ar = arduino(); %!assert(!isempty(ar)); %!test %! terms = getPinsFromTerminals(ar, 0); %! # terminal 0 is alwars D0 ? %! assert(ischar(terms)); %! assert(toupper(terms), "D0"); %!test %! terms = getPinsFromTerminals(ar, [0 2]); %! assert(numel(terms), 2); %! assert(iscell(terms)); %! assert(ischar(terms{1})); %! assert(toupper(terms{1}), "D0"); %! assert(toupper(terms{2}), "D2"); �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/getResourceCount.m�����������������������������������������������������0000644�0000000�0000000�00000002531�14777724260�016400� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{count} =} getResourceCount (@var{ar}, @var{resource}) ## Get the count of uses of a given resource. ## ## @subsubheading Inputs ## @var{ar} - connected arduino object ## ## @var{resource} - name of resource to get count for. ## ## @subsubheading Outputs ## @var{count} = count of uses registered to resource. ## ## @seealso{incrementResourceCount. decrementResourceCount} ## @end deftypefn function retval = getResourceCount (ar, resource) if nargin != 2 print_usage (); endif if !ischar(resource) error ("getResourceCount: expects resource name"); endif resinfo = ar.get_resource(resource); retval = resinfo.count; endfunction %!test %! ar = arduino(); %! assert(!isempty(ar)); %! assert(getResourceCount(ar,"notusedname"), 0); �����������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/getResourceOwner.m�����������������������������������������������������0000644�0000000�0000000�00000002765�14777724260�016413� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{owner} =} getResourceOwner (@var{ar}, @var{terminal}) ## Get the owner of pin allocated previously by configurePinResource. ## ## @subsubheading Inputs ## @var{ar} - connected arduino object ## ## @var{terminal} - terminal number to get owner of. ## ## @subsubheading Outputs ## @var{owner} = owner of the terminal pin, or "" if not owned. ## ## @seealso{configurePinResource} ## @end deftypefn function retval = getResourceOwner (obj, terminal) if nargin != 2 print_usage (); endif # note: matlab expects a number only - we will use either if or pin name if !ischar(terminal) && !isnumeric(terminal) error ("getResourceOwner: expects terminal id or pin name"); endif pininfo = obj.get_pin(terminal); retval = pininfo.owner; endfunction %!test %! ar = arduino(); %! assert(!isempty(ar)); %! configurePin(ar, "d2", "digitaloutput"); %! assert(getResourceOwner(ar,"d2"), "digital"); �����������arduino-0.12.2/inst/@arduino/getSPITerminals.m������������������������������������������������������0000644�0000000�0000000�00000002023�14777724260�016106� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{pinlist} =} getSPITerminals (@var{ar}) ## Get a cell list of pin Ids available for SPI mode. ## ## @subsubheading Inputs ## @var{ar} - the arduino object. ## ## @subsubheading Outputs ## @var{pinlist} - cell list of pin numbers available for SPI use. ## ## @seealso{arduino} ## @end deftypefn function retval = getSPITerminals(obj) if nargin != 1 print_usage() endif retval = getTypeTerminals(obj, "spi"); endfunction �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/getServoTerminals.m����������������������������������������������������0000644�0000000�0000000�00000002053�14777724260�016554� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{pinlist} =} getServoTerminals (@var{ar}) ## Get a cell list of pin Ids available for servo use. ## ## @subsubheading Inputs ## @var{ar} - the arduino object. ## ## @subsubheading Outputs ## @var{pinlist} - cell list of pin numbers available for servo use. ## ## @seealso{arduino, getPWMTerminals} ## @end deftypefn function retval = getServoTerminals(obj) if nargin != 1 print_usage() endif retval = getTypeTerminals(obj, "pwm"); endfunction �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/getSharedResourceProperty.m��������������������������������������������0000644�0000000�0000000�00000003230�14777724260�020260� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{count} =} getSharedResourceProperty (@var{ar}, @var{resource}, @var{property}) ## Get the value of a property from a given resource. ## ## @subsubheading Inputs ## @var{ar} - connected arduino object ## ## @var{resource} - name of resource to get property for. ## ## @var{property} - name of property from the resource. ## ## @subsubheading Outputs ## @var{propvalue} - value of the property ## ## @seealso{getResourceCount, setSharedResourceProperty} ## @end deftypefn function retval = getSharedResourceProperty (ar, resource, propname) if nargin != 3 print_usage (); endif if !ischar(resource) error ("getSharedResourceProperty: expects resource name"); endif if !ischar(propname) error ("getSharedResourceProperty: expects resource property name"); endif resinfo = ar.get_resource(resource); retval = resinfo.props.(tolower(propname)); endfunction %!test %! ar = arduino(); %! assert(!isempty(ar)); %! setSharedResourceProperty(ar, "notusedname", "propname", 16); %! assert(getSharedResourceProperty(ar,"notusedname", "propname"), 16); ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/getTerminalMode.m������������������������������������������������������0000644�0000000�0000000�00000002703�14777724260�016161� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{mode} =} getTerminalMode (@var{ar}, @var{terminal}) ## Get the mode of a pin allocated previously by configurePinResource. ## ## @subsubheading Inputs ## @var{ar} - connected arduino object ## ## @var{terminal} - terminal number to get owner of. ## ## @subsubheading Outputs ## @var{mode} - mode of the terminal pin, or "not_set" if not owned. ## ## @seealso{configurePinResource, getResourceOwner} ## @end deftypefn function retval = getTerminalMode (obj, terminal) if nargin != 2 print_usage () endif pininfo = obj.get_pin (terminal); retval = pininfo.mode; endfunction %!test %! ar = arduino(); %! assert(!isempty(ar)); %! term = getTerminalsFromPins(ar, "d2"); %! configurePin(ar, "d2", "digitaloutput"); %! assert(getTerminalMode(ar, term), "digitaloutput"); %! configurePin(ar, "d2", "unset"); %! assert(getTerminalMode(ar, term), "unset"); �������������������������������������������������������������arduino-0.12.2/inst/@arduino/getTerminalsFromPins.m�������������������������������������������������0000644�0000000�0000000�00000003171�14777724260�017215� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{pinnums} =} getTerminalsFromPins (@var{ar}, @var{pins}) ## Get the terminal number for each pin. ## ## @subsubheading Inputs ## @var{ar} - connected arduino object ## ## @var{pins} - single pin name or cell or vector array of pin names. ## ## @subsubheading Outputs ## @var{pinnums} - pin number of each named pin. If the input was a single string, returns a number. ## if the input pins was a vector or cell array, return a cell array of pin numbers corresponding ## to each input pin name. ## ## @seealso{arduino, getPinsFromTerminals} ## @end deftypefn function retval = getTerminalsFromPins(obj, pins) if nargin != 2 print_usage() endif if iscell (pins) retval = {}; for i=1:numel(pins) retval{end+1} = obj.get_pin(pins{i}).id; endfor elseif ischar(pins) retval = obj.get_pin(pins).id; elseif isvector (pins) retval = {}; for i=1:numel(pins) retval{end+1} = obj.get_pin(pins(i)).id; endfor else error ("getTerminalFromPins: expected pins as cell or string"); endif endfunction �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/incrementResourceCount.m�����������������������������������������������0000644�0000000�0000000�00000003153�14777724260�017606� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{count} =} incrementResourceCount (@var{ar}, @var{resource}) ## Increment the count value of a named resource by 1 and return the ## new count ## ## @subsubheading Inputs ## @var{ar} - connected arduino object ## ## @var{resource} - name of resource to increment count. ## ## @subsubheading Outputs ## @var{count} = count of uses registered to resource. ## ## @seealso{getResourceCount. decrementResourceCount} ## @end deftypefn function retval = incrementResourceCount (ar, resource) if nargin != 2 print_usage (); endif if !ischar (resource) error ("@arduino.getResourceCount: expects resource name"); endif resinfo = ar.get_resource (resource); resinfo.count ++; ar.set_resource (resource, resinfo); retval = resinfo.count; endfunction %!test %! ar = arduino(); %! assert(!isempty(ar)); %! assert(getResourceCount(ar,"notusedname"), 0); %! assert(incrementResourceCount(ar,"notusedname"), 1); %! assert(getResourceCount(ar,"notusedname"), 1); %! assert(incrementResourceCount(ar,"notusedname"), 2); ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/isTerminalAnalog.m�����������������������������������������������������0000644�0000000�0000000�00000003326�14777724260�016334� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{ret} = } isTerminalAnalog (@var{obj}, @var{terminal}) ## Return true if pin is capable of analog input ## ## @subsubheading Inputs ## @var{ar} - the connected arduino object ## ## @var{terminal} is a terminal number to check ## ## @subsubheading Outputs ## @var{ret} return 1 if terminal is a analog pin, 0 otherwise ## ## @end deftypefn function retvalue = isTerminalAnalog (obj, terminal) if nargin != 2 error ('@arduino.isTerminalAnalog: expected single terminal value'); endif pininfo = obj.get_pin (terminal); idx = find (cellfun(@(x) strcmpi (x, "analog"), pininfo.modes), 1); if isempty (idx) retvalue = false; else retvalue = true; endif endfunction %!shared ar %! ar = arduino(); %!assert(isTerminalAnalog(ar,"d0"), false); %!assert(isTerminalAnalog(ar,"a0"), true); %!assert(isTerminalAnalog(ar,getTerminalsFromPins(ar, "a0")), true); %!error <undefined> isTerminalAnalog() %!error <expected single terminal value> isTerminalAnalog(ar) # octave 7 returns: # function called with too many inputs # octave 6 returns: expected single terminal value %!error isTerminalAnalog(ar, "d1", 1) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/isTerminalDigital.m����������������������������������������������������0000644�0000000�0000000�00000003422�14777724260�016505� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{ret} = } isTerminalDigital(@var{obj}, @var{terminal}) ## Return true if pin is capable of digital functions ## ## @subsubheading Inputs ## @var{ar} - the connected arduino object ## ## @var{terminal} is a terminal number to check ## ## @subsubheading Outputs ## @var{ret} return 1 if terminal is a digital pin, 0 otherwise ## @end deftypefn function retvalue = isTerminalDigital (obj, terminal) if nargin != 2 error ('@arduino.isTerminalDigital: expected single terminal value'); endif pininfo = obj.get_pin (terminal); idx = find (cellfun(@(x) strcmpi (x, "digital"), pininfo.modes), 1); if isempty (idx) retvalue = false; else retvalue = true; endif endfunction %!shared ar %! ar = arduino(); %!assert(isTerminalDigital(ar,"d0"), true); %!assert(isTerminalDigital(ar,getTerminalsFromPins(ar, "d0")), true); %!assert(isTerminalDigital(ar,"a0"), true); %!error <undefined> isTerminalDigital() %!error <expected single terminal value> isTerminalDigital(ar) # octave 7 returns: # function called with too many inputs # octave 6 returns: expected single terminal value %!error isTerminalDigital(ar, "d1", 1) %!error <unknown pin> isTerminalDigital(ar, -1) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/playTone.m�������������������������������������������������������������0000644�0000000�0000000�00000005551�14777724260�014700� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018-2021 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} playTone (@var{ar}, @var{pin}, @var{freq}, @var{duration}) ## Play a tone of a given frequency on a specified pin. ## ## @subsubheading Inputs ## @var{ar} - connected arduino object ## ## @var{pin} - digital pin to play tone on ## ## @var{freq} - frequency in hertz to play between 0 and 32767Hz. ## ## @var{duration} duration in seconds to play tone between 0 and 30 seconds ## ## If duration is 0 or not specified, tone will continue to play until next tone is commanded. ## If frequency is 0, tone will stop playing ## ## @strong{NOTE:} use of playTone can interfere with PWM output. ## @end deftypefn function playTone (obj, pin, freq, duration) ARDUINO_PLAYTONE = 6; if nargin < 3 error ("@arduino.playTone: expected pin name and frequency"); endif if nargin < 4 duration = 0; endif if !ischar(pin) && !isnumeric(pin) error ("@arduino.playTone: expected pin name as string"); endif if (!isnumeric(freq) || freq < 0 || freq > 32767) error ("@arduino.playTone: expected freq between 0 .. 32767"); endif if (!isnumeric(duration) || duration < 0 || duration > 30) error ("@arduino.playTone: expected duration between 0 .. 30"); endif pininfo = obj.get_pin(pin); # first use ? if strcmp(pininfo.mode, "unset") configurePin(obj, pin, "digitaloutput") else [pinstate, pinmode] = pinStateMode(pininfo.mode); if !strcmp(pinmode, "digital") error ("@arduino.playTone: pin is in an incompatable mode"); endif endif freq = uint16(freq); freqh = bitshift (freq, -8); freql = bitand(freq, hex2dec('FF')); duration = uint16(duration*10); durh = bitshift (duration, -8); durl = bitand(duration, hex2dec('FF')); datain = uint8([pininfo.id freqh freql durh durl]); [dataout, status] = __sendCommand__ (obj, 0, ARDUINO_PLAYTONE, datain); if status != 0 error ("@arduino.playTone: failed to set tone err=%d - %s", status, char(dataout)); endif endfunction %!shared ar %! ar = arduino(); %!test %! if !strcmp(ar.Board, "due") %! playTone(ar,"d2", 0, 0); %! playTone(ar,"d2", 220, 1); %! playTone(ar, "d2", 0); %! else %! # due doesnt have playTone %! endif %!error <undefined> playTone() %!error <expected pin name and frequency> playTone(ar) %!error <unknown pin nopin> playTone(ar, "nopin", 220) �������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/private/���������������������������������������������������������������0000755�0000000�0000000�00000000000�14777724260�014373� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/private/__digitalPin__.m�����������������������������������������������0000644�0000000�0000000�00000003320�14777724260�017427� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. see ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} __digitalPin__ (@var{obj}) ## Private function ## @end deftypefn function retval = __digitalPin__(obj, pin, value) ARDUINO_DIGITAL = 3; retval = 0; if !ischar(pin) && !isnumeric(pin) error ("@arduino.digitalPin: expected pin name as string"); endif pininfo = obj.get_pin(pin); if nargin == 2 mode = "digitalinput"; datain = uint8([pininfo.id]); elseif nargin == 3 mode = "digitaloutput"; if value val = 1; else val = 0; endif datain = uint8([pininfo.id val]); endif # first use ? if strcmp(pininfo.mode, "unset") configurePin(obj, pin, mode) else [pinstate, pinmode] = pinStateMode(pininfo.mode); if !strcmp(pinmode, "digital") error ("digitalPin: pin is in incompatable mode"); endif endif [dataout, status] = __sendCommand__ (obj, 0, ARDUINO_DIGITAL, datain); if status != 0 error ("digitalPin: failed to set/get pin state err=%d", status); endif if nargin == 2 if dataout(2) != 0 retval = 1; else retval = 0; endif endif endfunction ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/private/__recvResponse__.m���������������������������������������������0000644�0000000�0000000�00000005673�14777724260�020036� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2021-2022 John Donoghue <john.donoghue@ieee.org> ## ## 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. see ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} __recvResponse__ (@var{obj}, @var{lib}, @var{cmd}, @var{timeout}) ## Private function ## @end deftypefn function [dataOut, errcode] = __recvResponse__ (dev, libid, cmd, timeout, debug) dataOut = []; errcode = 0; set(dev, "timeout", timeout); # TODO: current serial doesnt have a way to know if any data is awaiting # so try read what we need first without waiting ? # read in initial part [tmpdataOut, tmpdataSize] = fread (dev, 4); if (debug) printf("<< "); printf("%d ", tmpdataOut); printf("\n"); endif if tmpdataSize < 4 errcode = 1; dataOut = "Undersized packet header"; elseif tmpdataOut(1) != hex2dec("A5") || tmpdataOut(2) != libid || (tmpdataOut(3) != cmd && tmpdataOut(3) < 253) errcode = 2; dataOut = "Malformed packet header"; elseif (tmpdataOut(3) == 254) # got a wait for response value - length is expected to be 0 if (debug) printf("* wait for response\n"); endif set(dev, "timeout", -1); [tmpdataOut, tmpdataSize] = fread (dev, 4); if (debug) printf("<< "); printf("%d ", tmpdataOut); printf("\n"); endif if tmpdataSize < 4 errcode = 1; dataOut = "Undersized packet header"; elseif tmpdataOut(1) != hex2dec("A5") || tmpdataOut(2) != libid || (tmpdataOut(3) != cmd && tmpdataOut(3) != 255) errcode = 2; dataOut = "Malformed packet header"; endif endif if(errcode == 0) expectlen = tmpdataOut(4); if expectlen > 0 [dataOut, tmpdataSize] = fread (dev, expectlen); if (debug) printf("<< "); printf("%d ", dataOut); printf("\n"); endif else tmpdataSize = 0; endif if tmpdataSize != expectlen errcode = 3; dataOut = "Malformed packet body"; elseif tmpdataOut(3) == 255 # valid packet, but was coz we got an error errcode = 10; if expectlen == 0 dataOut = "Recieved error status";; else dataOut = char(dataOut); endif elseif tmpdataOut(3) == 253 # valid but was a debug message if debug s = char(dataOut); printf("DEBUG: %s\n", s); endif [dataOut, errcode] = __recvResponse__ (dev, libid, cmd, timeout, debug); else errcode = 0; # all is good endif endif endfunction ���������������������������������������������������������������������arduino-0.12.2/inst/@arduino/private/__sendCommand__.m����������������������������������������������0000644�0000000�0000000�00000003675�14777724260�017610� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018-2022 John Donoghue <john.donoghue@ieee.org> ## ## 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. see ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} __sendCommand__ (@var{obj}, @var{cmd}, @var{data}, @var{timeout}) ## Private function ## @end deftypefn ## Author: jdonoghue <jdonoghue@JYRW4S1> ## Created: 2018-05-15 function [dataOut, errcode] = __sendCommand__ (obj, libid, cmd, data, timeout) if nargin < 3 error ("@arduino.__sendCommand__: expected command"); endif % send command and get back reponse if !isa(obj.connected, "octave_serialport") && !isa(obj.connected, "octave_tcp") error ("@arduino.__sendCommand__: not connected to a arduino"); endif % connected yet ? % simple procol here, each field is a byte % sends A5 EXT CMD datasize [data,,,] % currently ext is 0 - may use later to identify module to send to ? % A5 00 00 00 = reset % A5 00 01 00 = req board info dataOut = []; errcode = 0; if (nargin < 4) data = []; endif if (nargin < 5) timeout = 0.5; endif if iscell(data) data = cell2mat(data); endif hdr = uint8([ hex2dec("A5") libid cmd numel(data)]); set(obj.connected, "timeout", timeout); len = fwrite(obj.connected, [hdr data]); if (obj.debug) printf(">> "); printf("%d ", [hdr data]); printf("\n"); endif [dataOut, errcode] = __recvResponse__ (obj.connected, libid, cmd, timeout, obj.debug); endfunction �������������������������������������������������������������������arduino-0.12.2/inst/@arduino/private/getTypeTerminals.m���������������������������������������������0000644�0000000�0000000�00000002175�14777724260�020056� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. see ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} getTypeTerminals (@var{ar}, @var{ar}) # Private function ## @end deftypefn function retval = getTypeTerminals(obj, type) if nargin != 2 print_usage() endif retval = {}; for i=1:numel(obj.config.pins) pininfo = obj.config.pins{i}; # strncmp do can patch spi from spiX_XX etc idx = find( cellfun(@(x) strncmpi(x, type, length(type)), pininfo.modes), 1); if !isempty(idx) retval{end+1}=pininfo.id; endif endfor endfunction ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/private/pinStateMode.m�������������������������������������������������0000644�0000000�0000000�00000004427�14777724260�017154� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018-2019 John Donoghue <john.donoghue@ieee.org> ## ## 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. see ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{value} =} pinStateMode (@var{pinStateVal}) ## Private function ## @end deftypefn function [pstate, pmode] = pinStateMode (pinStateVal) if ischar(pinStateVal) switch (tolower(pinStateVal)) case "unset" pstate = 0; pmode="none"; case "analoginput" pstate = 1; pmode = "analog"; case "digitalinput" pstate = 2; pmode="digital"; case "digitaloutput" pstate = 3; pmode="digital"; case "pullup" pstate = 4; pmode = "digital"; case "i2c" pstate = 5; pmode = "i2c"; case "pwm" pstate = 6; pmode="pwm"; case "servo" pstate = 7; pmode="pwm"; case "spi" pstate = 3; pmode="spi"; % for now just setting as output case "interrupt" pstate = 2; pmode="interrupt"; % for now just setting as input case "reserved" pstate = 10; pmode="reserved"; otherwise error ("unknown pin state %s", pinStateVal); endswitch else switch (pinStateVal) case 1 pstate = "analoginput"; pmode="analog"; case 2 pstate = "digitalinput"; pmode="digital"; case 3 pstate = "digitaloutput"; pmode="digital"; case 4 pstate = "pullup"; pmode="digital"; case 5 pstate = "i2c"; pmode="i2c"; case 6 pstate = "pwm"; pmode="pwm"; case 7 pstate = "servo"; pmode="pwm"; case 8 pstate = "spi"; pmode="spi"; case 9 pstate = "interrupt"; pmode="interrupt"; case 10 pstate = "reserved"; pmode="reserved"; otherwise pstate = "unset"; pmode=""; endswitch endif endfunction �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/readAnalogPin.m��������������������������������������������������������0000644�0000000�0000000�00000004622�14777724260�015607� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{value} =} readAnalogPin (@var{ar}, @var{pin}) ## Read analog voltage of @var{pin}. ## ## @subsubheading Inputs ## @var{ar} - connected arduino object. ## ## @var{pin} - string name of the pin to read. ## ## @subsubheading Outputs ## @var{value} - analog value of the pin ## ## @subsubheading Example ## @example ## @code{ ## ar = arduino (); ## readAnalogPin(ar, "A4"); ## ans = ## 87 ## } ## @end example ## @seealso{arduino, readVoltage} ## @end deftypefn function value = readAnalogPin (obj, pin) ARDUINO_ANALOG = 4; if nargin != 2 error ("@arduino.readAnalogPin: expected pin name and value"); endif if !ischar(pin) error ("@arduino.readAnalogPin: expected pin name as string"); endif pininfo = obj.get_pin(pin); # first use ? if strcmp(pininfo.mode, "unset") configurePin(obj, pin, "analoginput") else [pinstate, pinmode] = pinStateMode(pininfo.mode); if !strcmp(pinmode, "analog") error ("readAnalogPin: pin is in incompatable mode"); endif endif datain = uint8([pininfo.id]); [dataout, status] = __sendCommand__ (obj, 0, ARDUINO_ANALOG, datain); if status != 0 error ("readVoltage: failed to set pin state err=%d - %s", status, char(dataout)); endif value = (uint16(dataout(2))*256 + uint16(dataout(3))); endfunction %!shared ar %! ar = arduino(); %!test %! readAnalogPin(ar,"a0"); %! readAnalogPin(ar,"a1"); %! readAnalogPin(ar,"a2"); %! readAnalogPin(ar,"a3"); %! readAnalogPin(ar,"a4"); %! readAnalogPin(ar,"a5"); %!error <invalid mode> readAnalogPin(ar,"d2"); %!error <undefined> readAnalogPin() %!error <expected pin name> readAnalogPin(ar) # octave 7 returns: # function called with too many inputs # octave 6 returns: expected pin name %!error readAnalogPin(ar, "a0", 2) %!error <unknown pin nopin> readAnalogPin(ar, "nopin") ��������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/readDigitalPin.m�������������������������������������������������������0000644�0000000�0000000�00000003431�14777724260�015760� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{value} =} readDigitalPin (@var{obj}, @var{pin}) ## Read digital value from a digital I/O pin. ## ## @subsubheading Inputs ## @var{ar} - connected arduino object. ## ## @var{pin} - string name of the pin to read. ## ## @subsubheading Outputs ## @var{value} - the logical value (0, 1, true false) of the current pin state. ## ## @subsubheading Example ## @example ## @code{ ## a = arduino (); ## pinvalue = readDigitalPin (a, 'D5'); ## } ## @end example ## ## @seealso{arduino, writeDigitalPin} ## @end deftypefn function retval = readDigitalPin (obj, pin) if nargin != 2 error ("@arduino.readDigitalPin: expected pin name"); endif if !ischar(pin) && !isnumeric(pin) error ("@arduino.readDigitalPin: expected pin name as string"); endif retval = __digitalPin__(obj, pin); endfunction %!shared ar %! ar = arduino(); %!test %! readDigitalPin(ar,"d2"); %! assert(readDigitalPin(ar,"d2"), readDigitalPin(ar,2)); %!error <undefined> readDigitalPin() %!error <expected pin name> readDigitalPin(ar) # octave 7 returns: # function called with too many inputs # octave 6 returns: expected pin name %!error readDigitalPin(ar, "d2", 2) %!error <unknown pin nopin> readDigitalPin(ar, "nopin") ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/readVoltage.m����������������������������������������������������������0000644�0000000�0000000�00000003716�14777724260�015343� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{voltage} =} readVoltage (@var{ar}, @var{pin}) ## Read analog voltage of a pin. ## ## @subsubheading Inputs ## @var{ar} - connected arduino. ## ## @var{pin} - pin name or number to query for voltage ## ## @subsubheading Outputs ## @var{voltage} - scaled pin value as a voltage ## ## @subsubheading Example ## @example ## @code{ ## ar = arduino (); ## readVoltage(ar, "A4"); ## ans = ## 1.401 ## } ## @end example ## @seealso{arduino, readAnalogPin} ## @end deftypefn function voltage = readVoltage (ar, pin) if nargin != 2 error ("@arduino.readVoltage: expected pin name and value"); endif if !ischar(pin) error ("@arduino.readVoltage: expected pin name as string"); endif voltage = double(readAnalogPin(ar,pin)) * (ar.board_voltage() / 1023.0); endfunction %!shared ar %! ar = arduino(); %!test %! readVoltage(ar,"a0"); %! readVoltage(ar,"a1"); %! readVoltage(ar,"a2"); %! readVoltage(ar,"a3"); %! readVoltage(ar,"a4"); %! readVoltage(ar,"a5"); %! val = readVoltage(ar,"a0"); %! assert(isnumeric(val)); %! assert(val <= 5.0); %! assert(val >= 0); %!error <invalid mode> readVoltage(ar,"d2"); %!error <undefined> readVoltage() %!error <expected pin name> readVoltage(ar) # octave 7 returns: # function called with too many inputs # octave 6 returns: expected pin name %!error readVoltage(ar, "a0", 2) %!error <unknown pin nopin> readVoltage(ar, "nopin") ��������������������������������������������������arduino-0.12.2/inst/@arduino/reset.m����������������������������������������������������������������0000644�0000000�0000000�00000002352�14777724260�014223� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {} reset (@var{ar}) ## Send reset command to arduino hardware to force a hardware reset. ## ## @subsubheading Inputs ## @var{ar} - connected arduino object. ## ## @seealso{arduino} ## @end deftypefn function reset (ar) ARDUINO_RESET = 0; if nargin != 1 error ("@arduino.reset: expected arduiono object only"); endif [dataout, status] = __sendCommand__ (ar, 0, ARDUINO_RESET, [], 0); endfunction %!test %! ar = arduino(); %! assert(!isempty(ar)); %! reset(ar); %! pause(1); ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/sendCommand.m����������������������������������������������������������0000644�0000000�0000000�00000005753�14777724260�015341� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018-2020 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{outdata, outsize} =} sendCommand (@var{ar}, @var{libname}, @var{commandid}) ## @deftypefnx {} {@var{outdata, outsize} =} sendCommand (@var{ar}, @var{libname}, @var{commandid}, @var{data}) ## @deftypefnx {} {@var{outdata, outsize} =} sendCommand (@var{ar}, @var{libname}, @var{commandid}, @var{data}, @var{timeout}) ## Send a command with option data to the connected arduino, waiting up to a specified number of seconds ## for a response. ## ## @subsubheading Inputs ## @var{ar} - connected arduino object. ## ## @var{libname} - library sending the command. The name should match a programmed ## library of the arduino, or an error will be displayed. ## ## @var{commandid} - integer value for the command being sent to the arduino. ## ## @var{data} - optional data sent with the command. ## ## @var{timeout} - optional timeout to wait for data ## ## @subsubheading Outputs ## @var{outdata} - data returned back from the arduino in response to command ## ## @var{outsize} - size of data received ## ## If the arduino fails to respond with a valid reply, sendCommand will error. ## ## @seealso{arduino} ## @end deftypefn function [dataOut,payloadSize] = sendCommand (obj, libname, commandid, data, timeout) if nargin < 3 error ('sendCommand: missing expected arguments of libname, commandid'); endif if (isempty(libname)) libid = 0; else libid = obj.get_lib(libname); if libid == -1 error ("sendCommand: unknown or unprogrammed library '%s'.", libname); endif endif if ! isnumeric (commandid) error ('sendCommand: command id should be a number'); endif if (nargin < 4) data = []; endif if (nargin < 5) timeout = 5; endif [dataOut, status] = __sendCommand__ (obj, libid, commandid, data, timeout); if status != 0 error ("sendCommand: failed err=%d: msg=%s", status, char(dataOut)); endif payloadSize = numel(dataOut); endfunction %!shared ar %! ar = arduino(); %!error <undefined> sendCommand(); %!error <missing expected arguments> sendCommand(ar); %!error <missing expected arguments> sendCommand(ar, ""); %!error <command id should be a number> sendCommand(ar, "", "str"); %!test %! % valid config pin msg %! assert(numel(sendCommand(ar, "", 2, [2])) > 0); # valid packet, but unknown id %!error <Unknown cmdID> sendCommand(ar, "", 255, [2 2]); # query config pin without the data %!error <Invalid number of args> sendCommand(ar, "", 2); ���������������������arduino-0.12.2/inst/@arduino/setSharedResourceProperty.m��������������������������������������������0000644�0000000�0000000�00000004741�14777724260�020304� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} setSharedResourceProperty (@var{ar}, @var{resource}, @var{propname}, @var{propvalue}) ## @deftypefnx {} {} setSharedResourceProperty (@var{ar}, @var{resource}, @var{propname}, @var{propvalue}, ___) ## Set property values for a given resource. ## ## @subsubheading Inputs ## @var{ar} - connected arduino object ## ## @var{resource} - name of resource to get property for. ## ## @var{propname} - name of property from the resource. ## ## @var{propvalue} - value of property from the resource. ## ## Multiple @var{propname}, @var{propvalue} pairs can be given. ## ## @subsubheading Outputs ## None ## ## @subsubheading Example ## @example ## @code{ ## ar = arduino(); ## setSharedResourceProperty(ar, "myresource", "myproperty", [1 2 3]) ## } ## @end example ## ## @seealso{getSharedResourceProperty} ## @end deftypefn function setSharedResourceProperty (varargin) if nargin < 4 print_usage (); endif if mod(nargin, 2) != 0 error ("{getSharedResourceProperty: expected property name, value pairs"); endif if !iscellstr (varargin(3:2:nargin)) error ("{getSharedResourceProperty: expected property names to be strings"); endif ar = varargin{1}; resource = varargin{2}; if !ischar(resource) error ("getSharedResourceProperty: expects resource name"); endif resinfo = ar.get_resource(resource); for i = 3:2:nargin propname = tolower(varargin{i}); propvalue = varargin{i+1}; resinfo.props.(propname) = propvalue; endfor ar.set_resource(resource, resinfo); endfunction %!test %! ar = arduino(); %! assert(!isempty(ar)); %! setSharedResourceProperty(ar, "notusedname", "propname1", 16); %! setSharedResourceProperty(ar, "notusedname", "propname2", 32); %! assert(getSharedResourceProperty(ar,"notusedname", "propname1"), 16); %! setSharedResourceProperty(ar, "notusedname", "propname1", []); %! assert(getSharedResourceProperty(ar,"notusedname", "propname1"), []); �������������������������������arduino-0.12.2/inst/@arduino/uptime.m���������������������������������������������������������������0000644�0000000�0000000�00000003403�14777724260�014402� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{sec} =} uptime (@var{ar}) ## Get the number of seconds the arduino board has been running concurrently. ## ## ## @subsubheading Inputs ## @var{ar} - the arduino object of the connection to an arduino board. ## ## @subsubheading Outputs ## @var{sec} - the number seconds the board has been running. Note that the count will wrap around after ## approximately 50 days. ## ## @seealso{arduino} ## ## @end deftypefn function retval = uptime (obj) persistent ARDUINO_UPTIME = 21; if nargin != 1 error ("@arduino.version expects no arguments"); endif [dataout, status] = __sendCommand__ (obj, 0, ARDUINO_UPTIME, []); if status != 0 error ("@arduino.uptime: failed err=%d - %s", status, char(dataout)); else value = uint32(dataout(1))*256*256*256 + uint32(dataout(2))*256*256 + uint32(dataout(3))*256 + uint32(dataout(4)); retval = double(value)/1000.0; endif endfunction %!test %! ar = arduino(); %! assert(!isempty(ar)); %! t1 = uptime(ar); %! pause (1); %! t2 = uptime(ar); %! assert(t1 < t2); �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/validatePin.m����������������������������������������������������������0000644�0000000�0000000�00000004113�14777724260�015336� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} validatePin (@var{ar}, @var{pin}, @var{type}) ## Validate that the mode is allowed for specified pin ## ## If the mode is not valid, and error will be thrown. ## ## @subsubheading Inputs ## @var{ar} - connected arduino object ## ## @var{pin} - name of pin to query mode validity of ## ## @var{mode} - mode to query ## ## Known modes are: ## @itemize @bullet ## @item 'I2C' ## @item 'SPI' ## @item 'PWM' ## @item 'Servo' ## @item 'analog' ## @item 'digital' ## ## @end itemize ## ## @seealso{arduino, configurePin} ## @end deftypefn function validatePin (obj, pin, type) if nargin < 3 error ("@arduino.validatePin: expected pin name and type"); endif if !ischar(pin) || !ischar(type) error ("@arduino.validatePin: expected pin name and type as string"); endif pininfo = obj.get_pin(pin); # use type length, so can find spiX_XXXX etc when looking for SPI idx = find( cellfun(@(x) strncmpi(x, type, length(type)), pininfo.modes), 1); # check with mode allowed to that pin # if isnt, error if isempty(idx) error ("@arduino.validatePin: invalid mode for this pin"); endif endfunction %!shared ar %! ar = arduino(); %!test %! validatePin(ar, "d1", "digital"); %! validatePin(ar, "a0", "digital"); %! validatePin(ar, "a0", "analog"); %!error <invalid mode> validatePin(ar,"d1", "analog"); %!error <undefined> validatePin() %!error <expected pin> validatePin(ar) %!error <expected pin> validatePin(ar, "d1") %!error <unknown pin> validatePin(ar, "xd1", "digital") �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/version.m��������������������������������������������������������������0000644�0000000�0000000�00000003043�14777724260�014564� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{ver} =} version (@var{ar}) ## Get version of library code installed on arduino board ## ## @subsubheading Inputs ## @var{ar} - the arduino object of the connection to an arduino board. ## ## @subsubheading Outputs ## @var{ver} - version string in format of X.Y.Z. ## ## @seealso{arduino} ## ## @end deftypefn function retval = version (obj) persistent ARDUINO_VERSION = 20; if nargin != 1 error ("@arduino.version expects no arguments"); endif [dataout, status] = __sendCommand__ (obj, 0, ARDUINO_VERSION, []); if status != 0 error ("@arduino.version: failed err=%d - %s", status, char(dataout)); else retval = sprintf("%d.%d.%d", dataout(1), dataout(2), dataout(3)); endif endfunction %!test %! ar = arduino(); %! assert(!isempty(ar)); %! assert(~isempty(version(ar))); ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/writeDigitalPin.m������������������������������������������������������0000644�0000000�0000000�00000004131�14777724260�016175� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} writeDigitalPin (@var{ar}, @var{pin}, @var{value}) ## Write digital value to a digital I/O pin. ## ## @subsubheading Inputs ## @var{ar} - connected arduino object. ## ## @var{pin} - string name of the pin to write to. ## ## @var{value} - the logical value (0, 1, true false) to write to the pin. ## ## If pin was unconfigured before using, pin is set into digital mode. ## ## @subsubheading Example ## @example ## @code{ ## a = arduino(); ## writeDigitalPin(a,'D5',1); ## } ## @end example ## ## @seealso{arduino, readDigitalPin} ## ## @end deftypefn function writeDigitalPin (obj, pin, value) if nargin != 3 error ("@arduino.writeDigitalPin: expected pin name and value"); endif if !ischar(pin) && !isnumeric(pin) error ("@arduino.writeDigitalPin: expected pin name as string"); endif if (!isnumeric(value) && !islogical(value)) || (value != 1 && value != 0) error ("@arduino.writeDigitalPin: expected value as logical or 0 or 1"); endif __digitalPin__(obj,pin,value); endfunction %!shared ar %! ar = arduino(); %!test %! writeDigitalPin(ar,"d2", 1); %! writeDigitalPin(ar,"d2", 0); %! writeDigitalPin(ar,"d2", false); %! writeDigitalPin(ar,"d2", true); %! writeDigitalPin(ar,2, true); %!error <undefined> writeDigitalPin() %!error <expected pin name and value> writeDigitalPin(ar) # octave 7 returns: # function called with too many inputs # octave 6 returns: expected pin name and value %!error writeDigitalPin(ar, "d2", 1, 1) %!error <unknown pin nopin> writeDigitalPin(ar, "nopin", 1) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/writePWMDutyCycle.m����������������������������������������������������0000644�0000000�0000000�00000005054�14777724260�016447� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} writePWMDutyCyle (@var{ar}, @var{pin}, @var{value}) ## Set pin to output a square wave with a specified duty cycle. ## ## @subsubheading Inputs ## @var{ar} - connected arduino object ## ## @var{pin} - pin to write to. ## ## @var{value} - duty cycle value where 0 = off, 0.5 = 50% on, 1 = always on. ## ## @subsubheading Example ## @example ## @code{ ## a = arduino(); ## writePWMDutyCycle(a,'D5',0.5); ## } ## @end example ## ## @seealso{arduino, writePWMVoltage} ## ## @end deftypefn function writePWMDutyCycle (obj, pin, value) ARDUINO_PWM = 5; if nargin < 3 error ("@arduino.writePWMDutyCycle: expected pin name and value"); endif if !ischar(pin) && !isnumeric(pin) error ("@arduino.writePWMDutyCycle: expected pin name as string"); endif if (!isnumeric(value) || value > 1.0 || value < 0) error ("@arduino.writePWMDutyCycle: expected value between 0 .. 1"); endif pininfo = obj.get_pin(pin); # first use ? if strcmp(pininfo.mode, "unset") configurePin(obj, pin, "pwm") else [pinstate, pinmode] = pinStateMode(pininfo.mode); if !strcmp(pinmode, "pwm") error ("@arduino.PWMDutyCycle: pin is in incompatable mode"); endif endif val = 255*value; datain = uint8([pininfo.id val]); [dataout, status] = __sendCommand__ (obj, 0, ARDUINO_PWM, datain); if status != 0 error ("@arduino.writePWMDutyCycle: failed to set pin state err=%d - %s", status, char(dataout)); endif endfunction %!shared ar, pwmpin %! ar = arduino(); %! pwmpin = getPinsFromTerminals(ar, getPWMTerminals(ar)){1}; %!test %! writePWMDutyCycle(ar, pwmpin, 0.5); %!error <undefined> writePWMDutyCycle(); %!error <expected> writePWMDutyCycle(ar) %!error <expected pin> writePWMDutyCycle(ar, pwmpin) %!error <unknown pin> writePWMDutyCycle(ar, "xd1", 1) %!error <expected value between> writePWMDutyCycle(ar, pwmpin, -1) %!error <expected value between> writePWMDutyCycle(ar, pwmpin, 1.1) %!test %! writePWMDutyCycle(ar, pwmpin, 0.0); ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@arduino/writePWMVoltage.m������������������������������������������������������0000644�0000000�0000000�00000004112�14777724260�016135� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} writePWMVoltage (@var{ar}, @var{pin}, @var{voltage}) ## Emulate an approximate voltage out of a pin using PWM. ## ## @subsubheading Inputs ## @var{ar} - connected arduino object ## ## @var{pin} - pin to write to. ## ## @var{voltage} - voltage to emulate with PWM, between 0 - 5.0 ## ## @subsubheading Example ## @example ## @code{ ## a = arduino(); ## writePWMVoltage(a,'D5',1.0); ## } ## @end example ## ## @seealso{arduino, writePWMDutyCycle} ## @end deftypefn function writePWMVoltage (obj, pin, value) if nargin < 3 error ("@arduino.writePWMVoltage: expected pin name and value"); endif # TODO: need look at board type for what voltage range is allowed # and convert maxvolts = obj.board_voltage(); if !isnumeric(value) || value < 0 || value > maxvolts error('writePWMVoltage: value must be between 0 and %f', maxvolts); endif # assuming here for now 0 .. 5V is linear to 0 - 100% pwm val = value/maxvolts; writePWMDutyCycle(obj, pin, val); endfunction %!shared ar, pwmpin %! ar = arduino(); %! pwmpin = getPinsFromTerminals(ar, getPWMTerminals(ar)){1}; %!test %! writePWMVoltage(ar, pwmpin, ar.AnalogReference); %!error <undefined> writePWMVoltage(); %!error <expected> writePWMVoltage(ar) %!error <expected pin> writePWMVoltage(ar, pwmpin) %!error <unknown pin> writePWMVoltage(ar, "xd1", 1) %!error <value must be between> writePWMVoltage(ar, pwmpin, -1) %!error <value must be between> writePWMVoltage(ar, pwmpin, 5.1) %!test %! writePWMVoltage(ar, pwmpin, 0.0); ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@device/������������������������������������������������������������������������0000755�0000000�0000000�00000000000�14777724260�012517� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@device/delete.m����������������������������������������������������������������0000644�0000000�0000000�00000004344�14777724260�014144� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} delete (@var{dev}) ## Free resources of a device object. ## ## @subsubheading Inputs ## @var{dev} - object to free ## ## @seealso{device} ## @end deftypefn function delete(this) try ar = this.parent; resource = this.resourceowner; pins = this.pins; if !isempty(ar) if strcmp(resource, "i2c") cleanupI2Cdevice(ar, resource, pins) elseif strcmp(resource, "spi") cleanupSPIdevice(ar, resource, pins) elseif strcmp(resource, "serial") cleanupSerialdevice(ar, resource, pins) endif this.parent = []; endif catch # do nothing end_try_catch endfunction # private clean up allocated pins function cleanupI2Cdevice(ar, resource, pins) # currently doing nothing x = resource; endfunction function cleanupSerialdevice(ar, resource, pins) # currently doing nothing x = resource; endfunction # private clean up allocated pins function cleanupSPIdevice(ar, resource, pins) for i=1:numel(pins) pin = pins{i}; if strcmp(tolower(pin.func), "cs") configurePinResource(ar, pin.name, pin.owner, pin.mode, true); configurePin(ar, pin.name, pin.mode); endif endfor # clean up the spi port if not used? count = getResourceCount(ar, resource); if count > 0 count = decrementResourceCount(ar, resource); if count == 0 # last user, so free pins (except ss that we already did) pins = getSharedResourceProperty(ar, resource, "pins"); for i=1:numel(pins) pin = pins{i}; configurePinResource(ar, pin.name, pin.owner, pin.mode, true); configurePin(ar, pin.name, pin.mode); endfor endif endif endfunction ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@device/device.m����������������������������������������������������������������0000644�0000000�0000000�00000043444�14777724260�014145� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019-2020 John Donoghue <john.donoghue@ieee.org> ## ## 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. classdef device < handle ## -*- texinfo -*- ## @deftypefn {} {@var{dev} =} device (@var{ar}, 'I2CAddress', @var{address}) ## @deftypefnx {} {@var{dev} =} device (@var{ar}, 'SPIChipSelectPin', @var{pin}) ## @deftypefnx {} {@var{dev} =} device (@var{ar}, 'Serial', @var{serialid}) ## @deftypefnx {} {@var{dev} =} device (..., @var{propname}, @var{propvalue}) ## Create an i2c, spi or serial object to communicate on a connected arduino. ## ## @subsubheading Inputs ## @var{ar} - connected arduino object ## ## @var{propname}, @var{propvalue} - property name/value pair for values to pass to devices. ## ## A property of 'i2caddress', 'spichipselectpin' or 'serial' must be specified to denote the device type to create. ## ## @var{i2caddress} - address to use for device on I2C bus. ## ## @var{pin} - pin to use for device SPI chip select. ## ## @var{serialid} - Serial port id to use ## ## Additional properties can also be specified for the device object ## ## Currently known input I2C properties values: ## @table @asis ## @item bus ## bus number (when arduino board supports multiple I2C buses) ## with value of 0 or 1. ## @item noprobe ## Do not probe the existence of device on creation if set to 1 (default 0) ## @item bitrate ## bit rate speed in Mbs - default 100000 ## @end table ## ## ## ## Currently known input SPI properties values: ## @table @asis ## @item bitrate ## bit rate speed in Mbs ## @item bitorder ## 'msbfirst' or 'lsbfirst' ## @item spimode ## SPI mode 0 - 3. ## @end table ## ## ## ## Currently known input Serial properties values: ## @table @asis ## @item baudrate ## baudrate value (default 9600) ## @item databits ## number of databits (5,6,7,8) (default 8) ## @item stopbits ## number of stopbits (1,2) (default 1) ## @item parity ## parity of device ('odd','even','none') (default 'none') ## @end table ## ## ## @subsubheading Outputs ## @var{dev} - new created device object. ## ## @subsubheading Properties ## The object has the following public properties: ## @table @asis ## @item parent ## The parent (arduino) for this device ## @item interface ## The interface type for this device ("SPI" or "I2C" or "Serial") ## @end table ## ## In addition, depending on type, the object will have these properties: ## ## @subsubheading I2C Properties ## The object has the following public properties: ## @table @asis ## @item bus ## bus used for created object ## @item i2caddress ## I2C address set for object ## @item sclpin ## the SCL pin of the device ## @item sdapin ## the SDA pin of the device ## @item bitrate ## bit rate for the i2c clock ## @end table ## ## @subsubheading SPI Properties ## The object has the following public properties: ## @table @asis ## @item spimode ## mode used for created object ## @item bitrate ## Bitrate set for object ## @item bitorder ## Bitorder set for object ## @item spichipselectpin ## Pin used for chipselect ## @item mosipin ## Pin used for mosi ## @item misopin ## Pin used for miso ## @item sckpin ## Pin used for sckpin ## @end table ## ## @subsubheading Serial Properties ## The object has the following public properties: ## @table @asis ## @item id ## serial port id ## @item baudrate ## baudrate ## @item databits ## number of databits (5,6,7,8) ## @item stopbits ## number of stopbits (1,2) ## @item parity ## parity of device ('odd','even','none') ## @end table ## ## @seealso{arduino, i2cdev, spidev} ## @end deftypefn properties (Access = private) parent = []; id = []; devinfo = {}; pins = {}; interface = ""; resourceowner = ""; endproperties methods (Access = public) function this = device(varargin) persistent ARDUINO_I2C_CONFIG = 1; persistent ARDUINO_SPI_CONFIG = 1; persistent ARDUINO_SERIAL_CONFIG = 1; if nargin < 3 error("expects arduino object and properties"); endif #this.parent = varargin{1}; has_add_param = true; try p = inputParser(); p.addParameter("test", 1); catch has_add_param = false; end_try_catch # parse args p = inputParser(); p.CaseSensitive = false; p.FunctionName = 'device'; p.KeepUnmatched = true; p.addRequired('ar', @isarduino); if has_add_param p.addParameter('I2CAddress', -1, @isnumeric); p.addParameter('SPIChipSelectPin', ""); p.addParameter('Serial', ""); else p.addParamValue('I2CAddress', -1, @isnumeric); p.addParamValue('SPIChipSelectPin', ""); p.addParamValue('Serial', ""); endif p.parse(varargin{:}); this.parent = p.Results.ar; # NOTE: dont use fields of our object in the function handle or we will # never be unreferenced # pin_type = @(x) !isempty(getPinInfo(p.Results.ar, x)); pin_type = @(x) (isnumeric(x) || (ischar(x) && !isempty(regexp(x, "[aAdD]\\d+")))); if p.Results.I2CAddress != -1 && isempty(p.Results.SPIChipSelectPin) && isempty(p.Results.Serial) this.interface = "I2C"; bus_type = @(x) (isnumeric(x) && x >= 0 && x <= 1); bool_type = @(x) ((isnumeric(x) && (x ==0 || x == 1)) || islogical(x)); i2caddr = p.Results.I2CAddress; p = inputParser(); p.FunctionName = 'device'; p.CaseSensitive = false; p.addRequired('ar', @isarduino); if has_add_param p.addParameter('I2CAddress', "", @isnumeric); p.addParameter('Bus', 0, bus_type); p.addParameter('BitRate', 100000, @isnumeric); p.addParameter('NoProbe', 0, bool_type); else p.addParamValue('I2CAddress', i2caddr, @isnumeric); p.addParamValue('Bus', 0, bus_type); p.addParamValue('BitRate', 100000, @isnumeric); p.addParamValue('NoProbe', 0, bool_type); endif p.parse(varargin{:}); this.id = p.Results.Bus; this.devinfo.address = p.Results.I2CAddress; this.devinfo.bus = p.Results.Bus; this.devinfo.bitrate = p.Results.BitRate; this.resourceowner = "i2c"; this.pins = this.parent.get_group(["i2c" num2str(this.devinfo.bus) "_"]); if isempty(this.pins) && this.devinfo.bus == 0 this.pins = this.parent.get_group("i2c_"); endif if numel(this.pins) != 2 error("expected 2 I2C pins but only have %d", numel(this.pins) ) endif # check a device is attached if p.Results.NoProbe == false && !checkI2CAddress(this.parent, this.devinfo.address, this.devinfo.bus) error ("I2c address did not respond to probe of address"); endif # set pins try for i=1:2 configurePin(this.parent, this.pins{i}.name, "i2c") endfor bitrate = uint16(this.devinfo.bitrate/1000); bitrate = [ bitand(bitshift(bitrate,-8), 255), bitand(bitrate, 255)]; # 0 = master mode, which all we currently support in our arduino toolkit [tmp, sz] = sendCommand(this.parent, "i2c", ARDUINO_I2C_CONFIG, [this.devinfo.bus 1 0 bitrate]); catch for i=1:2 configurePinResource(this.parent, this.pins{i}.name, this.pins{i}.owner, this.pins{i}.mode, true) configurePin(this.parent, this.pins{i}.name, this.pins{i}.mode) endfor rethrow (lasterror) end_try_catch # this.cleanup = onCleanup (@() cleanupI2Cdevice (this.parent, this.resourceowner, this.pins)); elseif p.Results.I2CAddress == -1 && !isempty(p.Results.SPIChipSelectPin) && isempty(p.Results.Serial) this.interface = "SPI"; bitorder_type = @(x) (ischar(x) && any(strcmp(lower(x), {"msbfirst", "lsbfirst"}))); mode_type = @(x) (isnumeric(x) && x >= 0 && x <= 3); cspin = p.Results.SPIChipSelectPin; p = inputParser(); p.FunctionName = 'device'; p.CaseSensitive = false; p.addRequired('ar', @isarduino); if has_add_param p.addParameter('SPIChipSelectPin', "", pin_type); p.addParameter('SPIMode', 0, mode_type); p.addParameter('BitRate', 4000000, @isnumeric); p.addParameter('BitOrder', "msbfirst", bitorder_type); else p.addParamValue('SPIChipSelectPin', cspin, pin_type); p.addParamValue('SPIMode', 0, mode_type); p.addParamValue('BitRate', 4000000, @isnumeric); p.addParamValue('BitOrder', "msbfirst", bitorder_type); endif p.parse(varargin{:}); this.devinfo.chipselectpin = p.Results.SPIChipSelectPin; this.devinfo.mode = p.Results.SPIMode; this.devinfo.bitrate = p.Results.BitRate; this.devinfo.bitorder = tolower(p.Results.BitOrder); this.resourceowner = "spi"; isfirst = getResourceCount(this.parent,"spi") == 0; # check if is valid CS pin that can use as output validatePin(this.parent, this.devinfo.chipselectpin, 'digital') if strcmp(getResourceOwner(this.parent, this.devinfo.chipselectpin), this.resourceowner) error ("pin %s is already in use by SPI", this.devinfo.chipselectpin) endif if isfirst terms = getSPITerminals(this.parent); tmp_pins = this.parent.get_pingroup(terms{1}, "SPI"); if numel(tmp_pins) != 4 error ("expected 4 SPI pins but only have %d", numel(tmp_pins)) endif setSharedResourceProperty(this.parent, this.resourceowner, "pins", tmp_pins); endif tmp_pins = getSharedResourceProperty(this.parent, this.resourceowner, "pins"); cs_is_ss = false; cspin = getPinInfo(this.parent, this.devinfo.chipselectpin); cspin.func = "cs"; for i=1:4 # verify cs pin is either SS pin, or a not a spi pin if strcmp(tolower(tmp_pins{i}.func), "ss") if strcmpi(tmp_pins{i}.name, cspin.name) cs_is_ss = true; endif else # check not trying to set CS to a spi pin if strcmpi(tmp_pins{i}.name, cspin.name) error ("can not set cspin to a SPI function pin"); endif endif endfor if !cs_is_ss tmp_pins{end+1} = cspin; endif this.pins = tmp_pins; this.id = cspin.terminal; try for i=1:numel(tmp_pins) if isfirst if strcmp(tolower(tmp_pins{i}.func), "ss") || strcmp(tolower(tmp_pins{i}.func), "cs") configurePin(this.parent, tmp_pins{i}.name, "digitaloutput") configurePinResource (this.parent, tmp_pins{i}.name, "spi", "digitaloutput", true); else configurePin(this.parent, tmp_pins{i}.name, "spi") endif else # only allocate cs pin if not first device if strcmp(tolower(tmp_pins{i}.func), "cs") configurePin(this.parent, tmp_pins{i}.name, "digitaloutput") configurePinResource (this.parent, tmp_pins{i}.name, "spi", "digitaloutput", true); endif endif endfor bitorder = 0; if strcmp(this.devinfo.bitorder, 'lsbfirst') bitorder = 1; endif [tmp, sz] = sendCommand(this.parent, this.resourceowner, ARDUINO_SPI_CONFIG, [this.id 1 this.devinfo.mode bitorder]); incrementResourceCount(this.parent, this.resourceowner); catch for i=1:numel(tmp_pins) if strcmp(tolower(tmp_pins{i}.func), "cs") || isfirst configurePinResource(this.parent, tmp_pins{i}.name, tmp_pins{i}.owner, tmp_pins{i}.mode, true) configurePin(this.parent, tmp_pins{i}.name, tmp_pins{i}.mode) endif endfor rethrow (lasterror); end_try_catch # set clean up function # this.cleanup = onCleanup (@() cleanupSPIdevice (this.parent, this.resourceowner, cspin)); elseif p.Results.I2CAddress == -1 && isempty(p.Results.SPIChipSelectPin) && !isempty(p.Results.Serial) this.interface = "Serial"; this.resourceowner = "serial"; parity_type = @(x) (ischar(x) && any(strcmp(lower(x), {"none", "odd", "even"}))); databits_type = @(x) (isnumeric(x) && x >= 5 && x <= 8); stopbits_type = @(x) (isnumeric(x) && x >= 1 && x <= 2); baudrate_type = @(x) (isnumeric(x) && x >= 300 && x <= 115200); p = inputParser(); p.FunctionName = 'device'; p.CaseSensitive = false; p.addRequired('ar', @isarduino); if has_add_param p.addParameter('Serial', -1, @isnumeric); p.addParameter('BaudRate', 9600, baudrate_type); p.addParameter('DataBits', 8, databits_type); p.addParameter('StopBits', 1, stopbits_type); p.addParameter('Parity', "none", parity_type); else p.addParamValue('Serial', -1, @isnumeric); p.addParamValue('BaudRate', 9600, baudrate_type); p.addParamValue('DataBits', 8, databits_type); p.addParamValue('StopBits', 1, stopbits_type); p.addParamValue('Parity', "none", parity_type); endif p.parse(varargin{:}); this.devinfo.id = p.Results.Serial; this.devinfo.baudrate = p.Results.BaudRate; this.devinfo.databits = p.Results.DataBits; this.devinfo.stopbits = p.Results.StopBits; this.devinfo.parity = p.Results.Parity; this.devinfo.timeout = 1.0; this.id = p.Results.Serial; name = ["uart" num2str(this.id) "_"]; this.pins = this.parent.get_group(name); if numel(this.pins) == 0 error("Not a known serial number '%d'", this.id) endif if numel(this.pins) != 2 error("expected 2 Serial pins but only have %d", numel(this.pins) ) endif # set pins try for i=1:2 configurePin(this.parent, this.pins{i}.name, "reserved") endfor baudrate = uint32(this.devinfo.baudrate); baudin = [ bitand(bitshift(baudrate,-24), 255) bitand(bitshift(baudrate,-16), 255), bitand(bitshift(baudrate,-8), 255), bitand(baudrate, 255)]; parity = 0; if strcmpi(this.devinfo.parity, "odd") parity = 1; elseif strcmpi(this.devinfo.parity, "even") parity = 2; endif [tmp, sz] = sendCommand(this.parent, "serial", ARDUINO_SERIAL_CONFIG, [this.id 1 baudin this.devinfo.databits this.devinfo.stopbits parity]); catch for i=1:2 configurePinResource(this.parent, this.pins{i}.name, this.pins{i}.owner, this.pins{i}.mode, true) configurePin(this.parent, this.pins{i}.name, this.pins{i}.mode) endfor rethrow (lasterror) end_try_catch # set clean up function # this.cleanup = onCleanup (@() cleanupSerialdevice (this.parent, this.resourceowner, {})); else error ('device expected I2CAddress, SPIChipSelectPin or Serial property'); endif endfunction endmethods endclassdef %!shared arduinos %! arduinos = scanForArduinos(1); %!assert(numel(arduinos), 1); %!test %! ar = arduino(); %! assert(!isempty(ar)); %! pins = getI2CTerminals(ar); %! # check pins not allocated %! for i=1:numel(pins) %! p = pins{i}; %! assert(configurePin(ar, p), "unset") %! endfor %! i2c = device(ar, 'i2caddress', 10, "noprobe", 1); %! assert(!isempty(i2c)); %! assert(i2c.interface, "I2C"); %! assert(i2c.i2caddress, 10); %! # check pins allocated %! for i=1:numel(pins) %! p = pins{i}; %! assert(!strcmpi(configurePin(ar, p), "unset")) %! endfor %! delete(i2c); %! # TODO check pins unallocated when we have implemented a free of shared spi bus %! # for i=1:numel(pins) %! # p = pins{i}; %! # assert(configurePin(ar, p), "unset") %! # endfor %! delete(ar) %!test %! ar = arduino(); %! assert(!isempty(ar)); %! %! spipins = getSPITerminals(ar); %! assert (numel(spipins), 4); %! %! # validate SPI pins not allocated %! assert(configurePin(ar, "d10"), "unset") %! assert(configurePin(ar, spipins{1}), "unset") %! assert(configurePin(ar, spipins{2}), "unset") %! assert(configurePin(ar, spipins{3}), "unset") %! assert(configurePin(ar, spipins{4}), "unset") %! %! spi = device(ar, "spichipselectpin", "d10"); %! assert(!isempty(spi)); %! assert(spi.spichipselectpin, "d10"); %! assert(spi.interface, "SPI"); %! %! # validate SPI pins allocated %! assert(configurePin(ar, "d10"), "digitaloutput") %! #assert(configurePin(ar, spipins{1}), 'digitaloutput') ## ss %! #assert(configurePin(ar, spipins{2}), 'digitaloutput') ## mosi %! #assert(configurePin(ar, spipins{3}), 'digitalinput') ## miso %! #assert(configurePin(ar, spipins{4}), 'digitaloutput') ## sck %! %! delete(spi); %! %! # check now pins unset %! assert(configurePin(ar, "d10"), "unset") %! assert(configurePin(ar, spipins{1}), "unset") %! assert(configurePin(ar, spipins{2}), "unset") %! assert(configurePin(ar, spipins{3}), "unset") %! assert(configurePin(ar, spipins{4}), "unset") %! delete(ar) %!test %! ar = arduino(); %! spi = device(ar, "spichipselectpin", "d10"); %! fail ('device(ar, "spichipselectpin", "d10");', 'pin d10 is already in use') %! spi2 = device(ar, "spichipselectpin", "d5"); %! delete(spi); %! delete(spi2); %! delete(ar) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@device/disp.m������������������������������������������������������������������0000644�0000000�0000000�00000004031�14777724260�013632� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} disp (@var{dev}) ## Display device object. ## ## @subsubheading Inputs ## @var{dev} - device object to display ## ## @seealso{device} ## @end deftypefn function disp (this) printf (" device object with fields of: \n\n"); printf (" interface = %s\n", this.interface); if strcmp(this.interface, "SPI") printf ("spichipselectpin = %s\n", this.devinfo.chipselectpin); for i=1:numel(this.pins) if ! any(strcmp(this.pins{i}.func,{"ss", "cs"})) printf("%16s = %s\n", [ this.pins{i}.func "pin"], this.pins{i}.name) endif endfor printf (" spimode = %d\n", this.devinfo.mode); printf (" bitorder = %s\n", this.devinfo.bitorder); printf (" bitrate = %d\n", this.devinfo.bitrate); elseif strcmp(this.interface, "Serial") printf (" serialport = %d\n", this.devinfo.id); printf (" baudrate = %d\n", this.devinfo.baudrate); for i=1:2 printf("%16s = %s\n", [ this.pins{i}.func "pin"], this.pins{i}.name) endfor elseif strcmp(this.interface, "I2C") printf (" i2caddress = %d (0x%02X)\n", this.devinfo.address, this.devinfo.address); printf (" bus = %d\n", this.devinfo.bus); printf (" bitrate = %d\n", this.devinfo.bitrate); for i=1:2 printf("%16s = %s\n", [ this.pins{i}.func "pin"], this.pins{i}.name) endfor % Mode, Bitrate, Bitorder else % should never happen endif printf("\n"); endfunction �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@device/flush.m�����������������������������������������������������������������0000644�0000000�0000000�00000003320�14777724260�014014� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{data} =} flush (@var{dev}) ## @deftypefnx {} {@var{data} =} flush (@var{dev}, "input") ## @deftypefnx {} {@var{data} =} flush (@var{dev}, "output") ## Flush the serial port buffers ## ## @subsubheading Inputs ## @var{dev} - connected serial device opened using device ## ## If an additional parameter is provided of "input" or "output", ## then only the input or output buffer will be flushed ## ## @subsubheading Outputs ## None ## ## @seealso{arduino, device, read} ## @end deftypefn function flush (dev, buffer) if nargin < 2 buffer = "all"; endif if !strcmp(dev.interface, "Serial") error("@device.flush: not a Serial device"); endif if !ischar (buffer) error("@device.flush: expected flushtype to be a string"); endif if strcmp(buffer, "all") || strcmp(buffer, "input") # flush input by reading all pending data sz = 32; while sz >= 32 tmp = read(dev, 32); sz = length(tmp); endwhile elseif strcmp(buffer, "output") # nothing to do as we dont have any pending output buffer else error("@device.flush: invalid flushbyte '%s'", buffer); endif endfunction ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@device/private/����������������������������������������������������������������0000755�0000000�0000000�00000000000�14777724260�014171� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@device/private/__getBytesAvailable__.m�����������������������������������������0000644�0000000�0000000�00000001760�14777724260�020536� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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. see ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} __getBytesAvailable__ (@var{obj}) ## Private function to get bytes available from serial port ## @end deftypefn function out = __getBytesAvailable__ (obj) persistent ARDUINO_SERIAL_STAT = 4; out = 0; ar = obj.parent; [tmp, sz] = sendCommand (ar, "serial", ARDUINO_SERIAL_STAT, [obj.devinfo.id]); out = uint16(tmp(2)); endfunction ����������������arduino-0.12.2/inst/@device/read.m������������������������������������������������������������������0000644�0000000�0000000�00000005665�14777724260�013624� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019-2021 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{data} =} read (@var{dev}, @var{numbytes}) ## @deftypefnx {} {@var{data} =} read (@var{dev}, @var{numbytes}, @var{precision}) ## Read a specified number of bytes from a i2c or serial device object ## using optional precision for bytesize. ## ## @subsubheading Inputs ## @var{dev} - connected i2c or serial device opened using device ## ## @var{numbytes} - number of bytes to read. ## ## @var{precision} - Optional precision for the output data read data. ## Currently known precision values are uint8 (default), int8, uint16, int16 ## ## @subsubheading Outputs ## @var{data} - data read from the device ## ## @seealso{arduino, device} ## @end deftypefn function out = read (dev, numbytes, precision) persistent ARDUINO_I2C_READ = 7; persistent ARDUINO_SERIAL_READ = 3; persistent endian; if isempty(endian) [~, ~, endian] = computer (); endif if nargin < 2 || nargin > 3 print_usage (); endif if ~isnumeric (numbytes) error("@i2c.read: expected numbytes to be a number"); endif if !strcmp(dev.interface, "I2C") && !strcmp(dev.interface, "Serial") error("@device.read: not a I2C or Serial device"); endif if nargin == 3 if !ischar (precision) error("@device.read: expected presision to be a string"); endif precision = tolower (precision); if !strcmp (precision, "uint8") && !strcmp (precision, "int8") && !strcmp (precision, "uint16") && !strcmp(precision, "int16") error ("@device.read: expected pression to be (u)int8 or (u)int16 string"); endif else precision = 'uint8'; endif datasize = 1; if (strcmp (precision,'uint16') || strcmp (precision,'int16')) datasize = 2; endif % read request if strcmp(dev.interface, "I2C") [tmp, sz] = sendCommand (dev.parent, "i2c", ARDUINO_I2C_READ, [dev.devinfo.bus dev.devinfo.address numbytes*datasize]); else [tmp, sz] = sendCommand (dev.parent, "serial", ARDUINO_SERIAL_READ, [dev.devinfo.id numbytes*datasize dev.devinfo.timeout*10]); endif # skip address and return the data out = typecast (uint8(tmp(2:end)), precision); if (strcmp (precision,'uint16') || strcmp (precision,'int16')) sz = sz/2; if (endian != getEndian(dev.parent)) out = swapbytes (out); endif else if (strcmp (precision, 'int8')) out = int8(tmp(2:end)) else out = tmp(2:end); endif endif endfunction ���������������������������������������������������������������������������arduino-0.12.2/inst/@device/readRegister.m����������������������������������������������������������0000644�0000000�0000000�00000006543�14777724260�015325� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{data} =} readRegister (@var{dev}, @var{reg}, @var{numbytes}) ## @deftypefnx {} {@var{data} =} readRegister (@var{dev}, @var{reg}, @var{numbytes}, @var{precision}) ## Read a specified number of bytes from a register of an i2cdev object ## using optional precision for bytesize. ## ## @subsubheading Inputs ## @var{dev} - connected i2c device opened using device ## ## @var{reg} - registry value number ## ## @var{numbytes} - number of bytes to read. ## ## @var{precision} - Optional precision for the output data read data. ## Currently known precision values are uint8 (default), int8, uint16, int16 ## ## @subsubheading Output ## @var{data} - data read from device. ## ## @seealso{arduino, device} ## @end deftypefn function out = readRegister(dev, reg, numbytes, precision) persistent endian; if isempty(endian) [~, ~, endian] = computer (); endif persistent ARDUINO_I2C_READREG = 9; if nargin < 3 || nargin > 4 print_usage (); endif if !strcmp(dev.interface, "I2C") error("@device.readRegister: not a I2C device"); endif if ~isnumeric (reg) error ("@device.readRegister: expected reg to be a number"); endif if ~isnumeric (numbytes) error ("@device.readRegister: expected numbytes to be a number"); endif if nargin == 4 if !ischar (precision) error ("@device.readRegister: expected presision to be a string"); endif precision = tolower (precision); if !strcmp (precision, "uint8") && !strcmp (precision, "int8") && !strcmp (precision, "uint16") && !strcmp(precision, "int16") error ("@device.readRegister: expected pression to be (u)int8 or (u)int16 string"); endif else precision = 'uint8'; endif if (strcmp (precision,'uint16')) reg = uint16(reg); if (endian != getEndian(dev.parent)) reg = swapbytes (reg); endif reg = typecast (reg, 'uint8'); regsz = 2; elseif (strcmp (precision,'int16')) reg = int16(reg); if (endian != getEndian(dev.parent)) reg = swabytes (reg); endif reg = typecast (reg, 'uint8'); regsz = 2; else if (strcmp (precision, 'int8')) reg = typecast (int8(reg), 'uint8'); else reg = typecast (uint8(reg), 'uint8'); endif regsz = 1; endif % read reg [tmp, sz] = sendCommand (dev.parent, "i2c", ARDUINO_I2C_READREG, [dev.devinfo.bus dev.devinfo.address regsz reg numbytes*regsz]); # skip address and and regsz and return the data out = tmp(3:end); % convert the outputs if (strcmp (precision,'uint16') || strcmp (precision,'int16')) sz = sz/2; out = typecast (out, precision); if (endian != getEndian(dev.parent)) out = swapbytes (out); endif else if (strcmp (precision, 'int8')) out = int8(out); else out = uint8(out); endif endif endfunction �������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@device/subsasgn.m��������������������������������������������������������������0000644�0000000�0000000�00000002543�14777724260�014526� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{val} = } subsasgn (@var{dev}, @var{sub}) ## subsasgn for device ## ## @seealso{device} ## @end deftypefn function this = subsasgn (this, s, val) if isempty(s) error ("device.subsasgn missing index"); endif if strcmp(this.interface, "Serial") if s(1).type == "." fld = tolower(s(1).subs); switch (fld) case "timeout" if !isnumeric(val) || val < 0 || val > 8 error ("expected numeric time out between 0 to 8 seconds", fld); endif this.devinfo.timeout = val; otherwise error ("device.subsasgn invalid or readonly property '%s'", fld); endswitch else error("unimplemented device.subsasgn type"); endif else error("unimplemented device.subsasgn device"); endif endfunction �������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@device/subsref.m���������������������������������������������������������������0000644�0000000�0000000�00000007607�14777724260�014360� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{val} = } subsref (@var{dev}, @var{sub}) ## subref for device ## ## @seealso{device} ## @end deftypefn function val = subsref (this, s) if isempty(s) error ("device.subsref missing index"); endif if strcmp(this.interface, "SPI") if s(1).type == "." fld = tolower(s(1).subs); switch (fld) case "pins" val = {}; for i = 1:numel(this.pins) val{end+1} = this.pins{i}.name; endfor case "interface" val = this.interface; case "parent" val = this.parent; case "spimode" val = this.devinfo.mode; case "bitrate" val = this.devinfo.bitrate; case "bitorder" val = this.devinfo.bitorder; case "spichipselectpin" val = this.devinfo.chipselectpin; case "misopin" val = get_func_pin(this.pins, "miso"); case "mosipin" val = get_func_pin(this.pins, "mosi"); case "sckpin" val = get_func_pin(this.pins, "sck"); otherwise error ("device.subsref invalid property '%s'", fld); endswitch else error("unimplemented device.subsref type"); endif elseif strcmp(this.interface, "Serial") if s(1).type == "." fld = tolower(s(1).subs); switch (fld) case "pins" val = {}; for i = 1:numel(this.pins) val{end+1} = this.pins{i}.name; endfor case "interface" val = this.interface; case "parent" val = this.parent; case "baudrate" val = this.devinfo.baudrate; case "databits" val = this.devinfo.databits; case "stopbits" val = this.devinfo.stopbits; case "parity" val = this.devinfo.parity; case "timeout" val = this.devinfo.timeout; case "numbytesavailable" val = __getBytesAvailable__(this); case "serialport" val = this.devinfo.id; otherwise error ("device.subsref invalid property '%s'", fld); endswitch else error("unimplemented device.subsref type"); endif else # I2C if s(1).type == "." fld = tolower(s(1).subs); switch (fld) case "pins" val = {}; for i = 1:numel(this.pins) val{end+1} = this.pins{i}.name; endfor case "interface" val = this.interface; case "parent" val = this.parent; case "bus" val = this.devinfo.bus; case "i2caddress" val = this.devinfo.address; case "bitrate" val = this.devinfo.bitrate; case "sdapin" val = get_func_pin(this.pins, "sda"); case "sclpin" val = get_func_pin(this.pins, "scl"); otherwise error ("device.subsref invalid property '%s'", fld); endswitch else error("unimplemented device.subsref type"); endif endif if (numel (s) > 1) val = subsref (val, s(2:end)); endif endfunction function val = get_func_pin(pins, func) val = []; for i=1:numel(pins) pin = pins{i}; if strcmp(pin.func, func) val = pin.name; endif endfor endfunction %!test %! ar = arduino(); %! spi = device (ar, "spichipselectpin", "d10"); %! assert (spi.spichipselectpin, "d10") %! assert (isarduino(spi.parent)) %! assert (ar.port, spi.parent.port) %! assert (spi.spimode, 0) %! assert (spi.bitorder, "msbfirst") %! assert (spi.interface, "SPI") %! assert (numel(spi.pins) >= 4) %! fail ("spi.invalid") %! delete(spi) �������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@device/write.m�����������������������������������������������������������������0000644�0000000�0000000�00000005563�14777724260�014040� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019-2021 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} write (@var{dev}, @var{datain}) ## @deftypefnx {} {} write (@var{dev}, @var{datain}, @var{precision}) ## Write data to a I2C or serial device object ## using optional precision for the data byte used for the data. ## ## @subsubheading Inputs ## @var{dev} - connected i2c or serial device opened using device ## ## @var{datain} - data to write to device. Datasize should not exceed the constraints ## of the data type specified for the precision. ## ## @var{precision} - Optional precision for the input write data. ## Currently known precision values are uint8 (default), int8, uint16, int16 ## ## @seealso{arduino, device, read} ## @end deftypefn function write (dev, datain, precision) persistent endian; if isempty(endian) [~, ~, endian] = computer (); endif persistent ARDUINO_I2C_WRITE = 6; persistent ARDUINO_SERIAL_WRITE = 2; if nargin < 2 || nargin > 3 print_usage (); endif if !strcmp(dev.interface, "I2C") && !strcmp(dev.interface, "Serial") error("@device.write: not a I2C or Serial device"); endif if nargin == 3 if !ischar (precision) error ("@device.write: expected presision to be a atring"); endif precision = tolower (precision); if !strcmp (precision, "uint8") && !strcmp (precision, "int8") && !strcmp (precision, "uint16") && !strcmp(precision, "int16") error ("@device.write: expected pression to be (u)int8 or (u)int16 string"); endif else precision = 'uint8'; endif if (strcmp (precision,'uint16')) datain = uint16(datain); if (endian != getEndian(dev.parent)) datain = swapbytes (datain); endif datain = typecast (datain, 'uint8'); elseif (strcmp (precision,'int16')) datain = int16(datain); if (endian != getEndian(dev.parent)) datain = swapbytes (datain); endif datain = typecast (datain, 'uint8'); else if (strcmp (precision, 'int8')) datain = typecast (int8(datain), 'uint8'); else datain = typecast (uint8(datain), 'uint8'); endif endif % write request if strcmp(dev.interface, "I2C") [tmp, sz] = sendCommand (dev.parent, "i2c", ARDUINO_I2C_WRITE, [dev.devinfo.bus dev.devinfo.address datain]); else [tmp, sz] = sendCommand (dev.parent, "serial", ARDUINO_SERIAL_WRITE, [dev.devinfo.id datain]); endif endfunction ���������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@device/writeRead.m�������������������������������������������������������������0000644�0000000�0000000�00000003734�14777724260�014632� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{dataOut} =} readWrite (@var{spi}, @var{dataIn}) ## Write uint8 data to spi device and return ## back clocked out response data of same size. ## ## @subsubheading Inputs ## @var{spi} - connected spi device on arduino ## ## @var{dataIn} - uint8 sized data to send to spi device framed between SS frame. ## ## @subsubheading Outputs ## @var{dataOut} - uint8 data clocked out during send to dataIn. ## ## @seealso{arduino, device} ## @end deftypefn function dataOut = writeRead (this, dataIn) dataOut = []; persistent ARDUINO_SPI_READ_WRITE = 2; if nargin < 2 error ("@device.writeRead: expected dataIn"); endif if !strcmp(this.interface, "SPI") error("@device.writeRead: not a SPI device"); endif [tmp, sz] = sendCommand (this.parent, this.resourceowner, ARDUINO_SPI_READ_WRITE, [this.id uint8(dataIn)]); if sz > 0 dataOut = tmp(2:end); endif endfunction %!shared arduinos %! arduinos = scanForArduinos(1); %!assert(numel(arduinos), 1); %!test %! ar = arduino(); %! assert(!isempty(ar)); %! spi = device(ar, "SPIChipSelectPin", "d10"); %! assert(!isempty(spi)); %! data = writeRead(spi, 1); %! assert(numel(data), 1); %! delete(spi) %! delete(ar) %!test %! ar = arduino(); %! assert(!isempty(ar)); %! spi = device(ar, "SPIChipSelectPin", "d10"); %! assert(!isempty(spi)); %! data = writeRead(spi, [1 1 1]); %! assert(numel(data), 3); %! delete(spi) %! delete(ar) ������������������������������������arduino-0.12.2/inst/@device/writeRegister.m���������������������������������������������������������0000644�0000000�0000000�00000006214�14777724260�015537� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} writeRegister (@var{dev}, @var{reg}, @var{datain}) ## @deftypefnx {} {} writeRegister (@var{dev}, @var{dev}, @var{datain}, @var{precision}) ## Write data to i2c device object at a given registry position ## using optional precision for the data byte used for the data. ## ## @subsubheading Inputs ## @var{dev} - connected i2c device opened using device ## ## @var{reg} - registry position to write to. ## ## @var{datain} - data to write to device. Datasize should not exceed the constraints ## of the data type specified for the precision. ## ## @var{precision} - Optional precision for the input write data. ## Currently known precision values are uint8 (default), int8, uint16, int16 ## ## @seealso{arduino, device, read} ## @end deftypefn function writeRegister (dev, reg, datain, precision) persistent endian; if isempty (endian) [~, ~, endian] = computer (); endif persistent ARDUINO_I2C_WRITEREG = 8; if nargin < 3 || nargin > 4 print_usage (); endif if !strcmp(dev.interface, "I2C") error("@device.writeRegister: not a I2C device"); endif if ~isnumeric (reg) error("@device.writeRegister: expected reg to be a number"); endif if nargin == 4 if !ischar (precision) error ("@device.writeRegister: expected precision to be a string"); endif precision = tolower (precision); if !strcmp (precision, "uint8") && !strcmp (precision, "int8") && !strcmp (precision, "uint16") && !strcmp(precision, "int16") error("@device.writeRegister: expected pression to be (u)int8 or (u)int16 string"); endif else precision = 'uint8'; endif % todo convert reg, data in to correct format if (strcmp (precision,'uint16')) reg = uint16 (reg); datain = uint16 (datain); if (endian != getEndian(dev.parent)) reg = swapbytes (reg); datain = swapbytes (datain); endif reg = typecast (reg, 'uint8'); datain = typecast (datain, 'uint8'); elseif (strcmp (precision,'int16')) reg = uint16 (reg); datain = int16 (datain); if (endian != getEndian(dev.parent)) reg = swabytes (reg); datain = swapbytes (datain); endif reg = typecast (reg, 'uint8'); datain = typecast (datain, 'uint8'); else if (strcmp (precision, 'int8')) reg = typecast (int8(reg), 'uint8'); datain = typecast (int8(datain), 'uint8'); else reg = typecast (uint8(reg), 'uint8'); datain = typecast (uint8(datain), 'uint8'); endif endif sendCommand (dev.parent, "i2c", ARDUINO_I2C_WRITEREG, [dev.devinfo.bus dev.devinfo.address reg datain]); endfunction ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@i2cdev/������������������������������������������������������������������������0000755�0000000�0000000�00000000000�14777724260�012434� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@i2cdev/delete.m����������������������������������������������������������������0000644�0000000�0000000�00000001472�14777724260�014060� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} delete (@var{dev}) ## Free resources of a i2cdev object. ## ## @subsubheading Inputs ## @var{dev} - object to free ## ## @seealso{i2cdev} ## @end deftypefn function delete(this) # currently does nothing endfunction ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@i2cdev/disp.m������������������������������������������������������������������0000644�0000000�0000000�00000002225�14777724260�013552� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} disp (@var{dev}) ## Display i2cdev object. ## ## @subsubheading Inputs ## @var{dev} - i2cdev object ## ## @seealso{i2cdev} ## @end deftypefn function disp (p) printf (" arduino i2cdev object with fields of: \n\n"); printf (" address = %d (0x%02X)\n", p.address, p.address); printf (" bus = %d\n", p.bus); printf (" bitorder = %s\n", p.bitorder); printf (" pins = "); for i=1:2 printf("%s(%s) ", p.pins{i}.name, p.pins{i}.func) endfor printf("\n"); % Mode, Bitrate, Bitorder printf ("\n"); endfunction ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@i2cdev/i2cdev.m����������������������������������������������������������������0000644�0000000�0000000�00000012777�14777724260�014004� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018-2020 John Donoghue <john.donoghue@ieee.org> ## ## 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. classdef i2cdev < handle ## -*- texinfo -*- ## @deftypefn {} {@var{dev} =} i2cdev (@var{ar}, @var{address}) ## @deftypefnx {} {@var{dev} =} i2cdev (@var{ar}, @var{address}, @var{propname}, @var{propvalue}) ## ## @code{i2cdev} is depreciated and will be removed in a future version. ## Use @code{device} instead. ## ## Create an i2cdev object to communicate to the i2c port on a connected arduino. ## ## @subsubheading Inputs ## @var{ar} - connected arduino object ## ## @var{address} - address to use for device on I2C bus. ## ## @var{propname}, @var{propvalue} - property name/value pair for values to pass to devices. ## ## Currently known properties: ## @table @asis ## @item bus ## bus number (when arduino board supports multiple I2C buses) ## with value of 0 or 1. ## @end table ## ## @subsubheading Outputs ## @var{dev} - new created i2cdev object. ## ## @subsubheading Properties ## The i2cdev object has the following public properties: ## @table @asis ## @item parent ## The parent (arduino) for this device ## @item pins ## pins used by this object ## @item bus ## bus used for created object ## @item address ## I2C address set for object ## @end table ## ## @seealso{arduino} ## @end deftypefn properties (Access = private) address = 0; arduinoobj = []; bus = 0; bitorder = ""; pins = {}; endproperties methods (Access = public) function p = i2cdev(varargin) ARDUINO_I2C_CONFIG = 1; persistent warned = false; if (! warned) warned = true; warning ("Octave:deprecated-function", "spidev is obsolete and will be removed from a future version of arduino, please use 'device' instead"); endif if nargin < 2 error("expects arduino object and address"); endif ar = varargin{1}; address = varargin{2}; bus = 0; bitorder = 'msbfirst'; if !isnumeric(address) || address < 0 || address > 255 error("expected address between 0 .. 255"); endif if mod(nargin, 2) != 0 error ("i2cdev: expected property name, value pairs"); endif if !iscellstr (varargin(3:2:nargin)) error ("i2cdev: expected property names to be strings"); endif for i = 3:2:nargin propname = tolower(varargin{i}); propvalue = varargin{i+1}; # printf("%s = %s\n", propname, propvalue); if strcmp (propname, "bus") if !isnumeric(propvalue) || propvalue < 0 error("bus should be a positive number") endif bus = propvalue; elseif strcmp (propname, "bitorder") if !ischar(propvalue) error("bitorder should be a 'lsbfirst' or 'msbfirst'"); endif propvalue = tolower(propvalue); if propvalue != 'lsbfirst' && propvalue != 'msbfirst' error("bitorder should be a 'lsbfirst' or 'msbfirst'"); endif bitorder = propvalue; endif endfor if (!isa (ar, "arduino")) error("expects arduino object"); endif p.address = address; p.arduinoobj = ar; p.bus = bus; p.bitorder = bitorder; % TODO on calling setup with the CS pin, returns back the other pins that we then setup as used ? % sendCommand # there only ever one port ??? with CS able to be completely independant ?? p.pins = ar.get_group(["i2c" num2str(bus) "_"]); if isempty(p.pins) && bus == 0 p.pins = ar.get_group("i2c_"); endif if numel(p.pins) != 2 error("expected 2 I2C pins but only have %d", numel(p.pins) ) endif # set pins try for i=1:2 configurePin(ar, p.pins{i}.name, "i2c") endfor # TODO: bitrate, order etc bitorder = 0; [tmp, sz] = sendCommand(p.arduinoobj, "i2c", ARDUINO_I2C_CONFIG, [bus 1]); catch for i=1:2 configurePinResource(ar, p.pins{i}.name, p.pins{i}.owner, p.pins{i}.mode, true) configurePin(ar, p.pins{i}.name, p.pins{i}.mode) endfor rethrow (lasterror) end_try_catch endfunction endmethods endclassdef %!shared arduinos %! arduinos = scanForArduinos(1); %!assert(numel(arduinos), 1); %!test %! ar = arduino(); %! assert(!isempty(ar)); %! pins = getI2CTerminals(ar); %! # TODO check pins unallocated when we have implemented a free of shared spi bus %! # check pins not allocated %! #for i=1:numel(pins) %! # p = pins{i}; %! # assert(configurePin(ar, p), "unset") %! #endfor %! i2c = i2cdev(ar, 10); %! assert(!isempty(i2c)); %! assert(i2c.address, 10); %! assert(i2c.bitorder, 'msbfirst'); %! # check pins allocated %! for i=1:numel(pins) %! p = pins{i}; %! assert(strcmpi(configurePin(ar, p), "i2c")) %! endfor %! delete(i2c) %! # TODO check pins unallocated when we have implemented a free of shared spi bus %! #for i=1:numel(pins) %! # p = pins{i}; %! # assert(configurePin(ar, p), "unset") %! #endfor �arduino-0.12.2/inst/@i2cdev/read.m������������������������������������������������������������������0000644�0000000�0000000�00000005151�14777724260�013527� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{data} =} read (@var{dev}, @var{numbytes}) ## @deftypefnx {} {@var{data} =} read (@var{dev}, @var{numbytes}, @var{precision}) ## Read a specified number of bytes from a i2cdev object ## using optional precision for bytesize. ## ## @subsubheading Inputs ## @var{dev} - connected i2c device opened using i2cdev ## ## @var{numbytes} - number of bytes to read. ## ## @var{precision} - Optional precision for the output data read data. ## Currently known precision values are uint8 (default), int8, uint16, int16 ## ## @subsubheading Outputs ## @var{data} - data read from i2cdevice ## ## @seealso{arduino, i2cdev} ## @end deftypefn function out = read (dev, numbytes, precision) persistent ARDUINO_I2C_READ = 7; persistent endian; if isempty(endian) [~, ~, endian] = computer (); endif if nargin < 2 || nargin > 3 print_usage (); endif if ~isnumeric (numbytes) error("@i2c.read: expected numbytes to be a number"); endif if nargin == 3 if !ischar (precision) error("@i2c.read: expected presision to be a string"); endif precision = tolower (precision); if !strcmp (precision, "uint8") && !strcmp (precision, "int8") && !strcmp (precision, "uint16") && !strcmp(precision, "int16") error ("@i2c.read: expected pression to be (u)int8 or (u)int16 string"); endif else precision = 'uint8'; endif datasize = 1; if (strcmp (precision,'uint16') || strcmp (precision,'int16')) datasize = 2; endif % read request [tmp, sz] = sendCommand (dev.arduinoobj, "i2c", ARDUINO_I2C_READ, [dev.bus dev.address numbytes*datasize]); # skip address and return the data out = typecast (uint8(tmp(2:end)), precision); if (strcmp (precision,'uint16') || strcmp (precision,'int16')) sz = sz/2; if (endian == 'L' && strcmp (dev.bitorder,'msbfirst')) || (endian == 'B' && strcmp (dev.bitorder, 'lsbfirst')) out = swapbytes (out); endif else if (strcmp (precision, 'int8')) out = int8(tmp(2:end)) else out = tmp(2:end); endif endif endfunction �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@i2cdev/readRegister.m����������������������������������������������������������0000644�0000000�0000000�00000006710�14777724260�015236� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{data} =} readRegister (@var{dev}, @var{reg}, @var{numbytes}) ## @deftypefnx {} {@var{data} =} readRegister (@var{dev}, @var{reg}, @var{numbytes}, @var{precision}) ## Read a specified number of bytes from a register of an i2cdev object ## using optional precision for bytesize. ## ## @subsubheading Inputs ## @var{dev} - connected i2c device opened using i2cdev ## ## @var{reg} - registry value number ## ## @var{numbytes} - number of bytes to read. ## ## @var{precision} - Optional precision for the output data read data. ## Currently known precision values are uint8 (default), int8, uint16, int16 ## ## @subsubheading Output ## @var{data} - data read from device. ## ## @seealso{arduino, i2cdev} ## @end deftypefn function out = readRegister(dev, reg, numbytes, precision) persistent endian; if isempty(endian) [~, ~, endian] = computer (); endif persistent ARDUINO_I2C_READREG = 9; if nargin < 3 || nargin > 4 print_usage (); endif if ~isnumeric (reg) error ("@i2c.readRegister: expected reg to be a number"); endif if ~isnumeric (numbytes) error ("@i2c.readRegister: expected numbytes to be a number"); endif if nargin == 4 if !ischar (precision) error ("@i2c.readRegister: expected presision to be a string"); endif precision = tolower (precision); if !strcmp (precision, "uint8") && !strcmp (precision, "int8") && !strcmp (precision, "uint16") && !strcmp(precision, "int16") error ("@i2c.readRegister: expected pression to be (u)int8 or (u)int16 string"); endif else precision = 'uint8'; endif if (strcmp (precision,'uint16')) reg = uint16(reg); if (endian == 'L' && strcmp (dev.bitorder,'msbfirst')) || (endian == 'B' && strcmp (dev.bitorder, 'lsbfirst')) reg = swapbytes (reg); endif reg = typecast (reg, 'uint8'); regsz = 2; elseif (strcmp (precision,'int16')) reg = int16(reg); if (endian == 'L' && strcmp (dev.bitorder,'msbfirst')) || (endian == 'B' && strcmp (dev.bitorder, 'lsbfirst')) reg = swabytes (reg); endif reg = typecast (reg, 'uint8'); regsz = 2; else if (strcmp (precision, 'int8')) reg = typecast (int8(reg), 'uint8'); else reg = typecast (uint8(reg), 'uint8'); endif regsz = 1; endif % read reg [tmp, sz] = sendCommand (dev.arduinoobj, "i2c", ARDUINO_I2C_READREG, [dev.bus dev.address regsz reg numbytes*regsz]); # skip address and and regsz and return the data out = tmp(3:end); % convert the outputs if (strcmp (precision,'uint16') || strcmp (precision,'int16')) sz = sz/2; out = typecast (out, precision); if (endian == 'L' && strcmp (dev.bitorder,'msbfirst')) || (endian == 'B' && strcmp (dev.bitorder, 'lsbfirst')) out = swapbytes (out); endif else if (strcmp (precision, 'int8')) out = int8(out); else out = uint8(out); endif endif endfunction ��������������������������������������������������������arduino-0.12.2/inst/@i2cdev/subsref.m���������������������������������������������������������������0000644�0000000�0000000�00000002671�14777724260�014271� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{val} = } subsref (@var{dev}, @var{sub}) ## subref for i2cdev ## ## @seealso{i2cdev} ## @end deftypefn function val = subsref (p, s) if isempty(s) error ("i2cdev.subsref missing index"); endif if s(1).type == "." fld = tolower(s(1).subs); switch (fld) case "pins" val = {}; for i = 1:numel(p.pins) val{end+1} = p.pins{i}.name; endfor case "parent" val = p.arduinoobj; case "bus" val = p.bus; case "address" val = p.address; case "bitorder" val = p.bitorder; otherwise error ("i2cdev.subsref invalid property '%s'", fld); endswitch else error("unimplemented i2cdev.subsref type"); endif endfunction %!test %! ar = arduino(); %! i2c = i2cdev (ar, 0x22); %! assert (isarduino(i2c.parent)) %! assert (i2c.address, 0x22) %! assert (numel(i2c.pins) == 2) %! fail ("i2c.invalid") �����������������������������������������������������������������������arduino-0.12.2/inst/@i2cdev/write.m�����������������������������������������������������������������0000644�0000000�0000000�00000005224�14777724260�013747� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} write (@var{dev}, @var{datain}) ## @deftypefnx {} {} write (@var{dev}, @var{datain}, @var{precision}) ## Write data to a i2cdev object ## using optional precision for the data byte used for the data. ## ## @subsubheading Inputs ## @var{dev} - connected i2c device opened using i2cdev ## ## @var{datain} - data to write to device. Datasize should not exceed the constraints ## of the data type specified for the precision. ## ## @var{precision} - Optional precision for the input write data. ## Currently known precision values are uint8 (default), int8, uint16, int16 ## ## @seealso{arduino, i2cdev, read} ## @end deftypefn function write (dev, datain, precision) persistent endian; if isempty(endian) [~, ~, endian] = computer (); endif persistent ARDUINO_I2C_WRITE = 6; if nargin < 2 || nargin > 3 print_usage (); endif if nargin == 3 if !ischar (precision) error ("@i2c.write: expected presision to be a atring"); endif precision = tolower (precision); if !strcmp (precision, "uint8") && !strcmp (precision, "int8") && !strcmp (precision, "uint16") && !strcmp(precision, "int16") error ("@i2c.write: expected pression to be (u)int8 or (u)int16 string"); endif else precision = 'uint8'; endif if (strcmp (precision,'uint16')) datain = uint16(datain); if (endian == 'L' && strcmp (dev.bitorder,'msbfirst')) || (endian == 'B' && strcmp (dev.bitorder, 'lsbfirst')) datain = swapbytes (datain); endif datain = typecast (datain, 'uint8'); elseif (strcmp (precision,'int16')) datain = int16(datain); if (endian == 'L' && strcmp (dev.bitorder,'msbfirst')) || (endian == 'B' && strcmp (dev.bitorder, 'lsbfirst')) datain = swapbytes (datain); endif datain = typecast (datain, 'uint8'); else if (strcmp (precision, 'int8')) datain = typecast (int8(datain), 'uint8'); else datain = typecast (uint8(datain), 'uint8'); endif endif % write request [tmp, sz] = sendCommand (dev.arduinoobj, "i2c", ARDUINO_I2C_WRITE, [dev.bus dev.address datain]); endfunction ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@i2cdev/writeRegister.m���������������������������������������������������������0000644�0000000�0000000�00000006244�14777724260�015457� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} writeRegister (@var{dev}, @var{reg}, @var{datain}) ## @deftypefnx {} {} writeRegister (@var{dev}, @var{dev}, @var{datain}, @var{precision}) ## Write data to i2cdev object at a given registry position ## using optional precision for the data byte used for the data. ## ## @subsubheading Inputs ## @var{dev} - connected i2c device opened using i2cdev ## ## @var{reg} - registry position to write to. ## ## @var{datain} - data to write to device. Datasize should not exceed the constraints ## of the data type specified for the precision. ## ## @var{precision} - Optional precision for the input write data. ## Currently known precision values are uint8 (default), int8, uint16, int16 ## ## @seealso{arduino, i2cdev, read} ## @end deftypefn function writeRegister (dev, reg, datain, precision) persistent endian; if isempty (endian) [~, ~, endian] = computer (); endif persistent ARDUINO_I2C_WRITEREG = 8; if nargin < 3 || nargin > 4 print_usage (); endif if ~isnumeric (reg) error("@i2c.writeRegister: expected reg to be a number"); endif if nargin == 4 if !ischar (precision) error ("@i2c.writeRegister: expected precision to be a string"); endif precision = tolower (precision); if !strcmp (precision, "uint8") && !strcmp (precision, "int8") && !strcmp (precision, "uint16") && !strcmp(precision, "int16") error("@i2c.writeRegister: expected pression to be (u)int8 or (u)int16 string"); endif else precision = 'uint8'; endif % todo convert reg, data in to correct format if (strcmp (precision,'uint16')) reg = uint16 (reg); datain = uint16 (datain); if (endian == 'L' && strcmp (dev.bitorder,'msbfirst')) || (endian == 'B' && strcmp (dev.bitorder, 'lsbfirst')) reg = swapbytes (reg); datain = swapbytes (datain); endif reg = typecast (reg, 'uint8'); datain = typecast (datain, 'uint8'); elseif (strcmp (precision,'int16')) reg = uint16 (reg); datain = int16 (datain); if (endian == 'L' && strcmp (dev.bitorder,'msbfirst')) || (endian == 'B' && strcmp(dev.bitorder, 'lsbfirst')) reg = swabytes (reg); datain = swapbytes (datain); endif reg = typecast (reg, 'uint8'); datain = typecast (datain, 'uint8'); else if (strcmp (precision, 'int8')) reg = typecast (int8(reg), 'uint8'); datain = typecast (int8(datain), 'uint8'); else reg = typecast (uint8(reg), 'uint8'); datain = typecast (uint8(datain), 'uint8'); endif endif sendCommand (dev.arduinoobj, "i2c", ARDUINO_I2C_WRITEREG, [dev.bus dev.address reg datain]); endfunction ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@rotaryEncoder/�����������������������������������������������������������������0000755�0000000�0000000�00000000000�14777724260�014100� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@rotaryEncoder/delete.m���������������������������������������������������������0000644�0000000�0000000�00000002264�14777724260�015524� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} delete (@var{dev}) ## Free resources of a encoder object. ## ## @subsubheading Inputs ## @var{dev} - object to free ## ## @seealso{rotartEncoder} ## @end deftypefn function delete(this) try ar = this.parent; name = this.resourceowner; pins = this.pins;; if !isempty(ar) decrementResourceCount(ar, name); for i=1:numel(pins) pin = pins{i}; configurePinResource(ar, pin.name, pin.owner, pin.mode, true) configurePin(ar, pin.name, pin.mode) endfor this.parent = []; endif catch # do nothing end_try_catch endfunction ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@rotaryEncoder/disp.m�����������������������������������������������������������0000644�0000000�0000000�00000002127�14777724260�015217� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} disp (@var{obj}) ## Display the rotary encoder object in a verbose way, ## ## @subsubheading Inputs ## @var{obj} - the arduino rotary encoder object created with rotaryEncoder ## ## @seealso{rotaryEncoder} ## @end deftypefn function retval = disp (obj) printf (" arduino rotary object with fields of: \n"); printf (" pulsesperrevolution = ") disp(obj.ppr); for i=1:numel(obj.pins) pin = obj.pins{i}; printf (" %s = %s\n", pin.func, pin.name) endfor endfunction �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@rotaryEncoder/readCount.m������������������������������������������������������0000644�0000000�0000000�00000005013�14777724260�016201� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {[@var{count}, @var{time}] =} readCount (@var{obj}) ## @deftypefnx {} {[@var{count}, @var{time}] =} readCount (@var{obj}, @var{name}, @var{value}) ## read count value from the rotary encoder. ## ## subsubheading Inputs ## @var{obj} - rotary encoder object created with rotaryEncoder call. ## ## @var{name}, @var{value} - optional name,value pairs ## ## Valid option name pairs currently are: ## @table @asis ## @item reset ## Reset the count after reading (if true) ## @end table ## ## @subsubheading Outputs ## @var{count} - returned count read from the encoder. ## ## @var{time} - seconds since arduino started ## ## @seealso{rotaryEncoder, resetCount} ## @end deftypefn function [value, time] = readCount(obj, reset, resetvalue) persistent ARDUINO_ROTARYENCODER_READCOUNT = 2; if nargin != 1 && nargin != 3 error ("arduino: expected rotaryencoder object and optional property name, value pairs"); endif if nargin != 3 reset = "reset"; resetvalue = false; endif if !strcmpi (reset, "reset") error ("arduino: expected property name of 'reset'"); endif if !(isnumeric(resetvalue) || islogical(resetvalue)) || (resetvalue != 0 && resetvalue != 1) error ("arduino: expected resetvalue of 0 or 1"); endif # attempt to clock out precision bits [tmp, sz] = sendCommand(obj.parent, "rotaryencoder", ARDUINO_ROTARYENCODER_READCOUNT, [obj.id resetvalue]); value = typecast(uint16(tmp(2))*256 + uint16(tmp(3)), 'int16'); time = uint32(tmp(4))*(256*256*256) + uint32(tmp(5))*(256*256) + uint32(tmp(6))*256 + uint32(tmp(7)); time = double(time)/1000.0; endfunction %!test %! ar = arduino (); %! e = rotaryEncoder(ar, "d2","d3"); %! readCount(e); %! readCount(e, "reset", 0); %! readCount(e, "reset", 1); %! readCount(e, "reset", true); %! delete(e) %!error readCount(); ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@rotaryEncoder/readSpeed.m������������������������������������������������������0000644�0000000�0000000�00000003155�14777724260�016156� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{speed} =} readSpeed (@var{obj}) ## read rotational speed from the rotary encoder. ## ## @subsubheading Inputs ## @var{obj} - rotary encoder object created with rotaryEncoder call. ## ## @subsubheading Outputs ## @var{speed} - returned speed in revolutions per minute read from the encoder. ## ## @seealso{rotaryEncoder, resetCount} ## @end deftypefn function value = readSpeed(obj, varargin) persistent ARDUINO_ROTARYENCODER_READSPEED = 3; # attempt to clock out precision bits [tmp, sz] = sendCommand(obj.parent, "rotaryencoder", ARDUINO_ROTARYENCODER_READSPEED, [obj.id]); value = typecast(uint16(tmp(2))*256 + uint16(tmp(3)), 'int16'); value = (double(value)/1000.0)*60; # cnts per min if obj.ppr > 0 value = value / obj.ppr; else value = 0; endif endfunction %!test %! ar = arduino (); %! e = rotaryEncoder(ar, "d2","d3"); %! readSpeed(e); %! delete(e) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@rotaryEncoder/resetCount.m�����������������������������������������������������0000644�0000000�0000000�00000003052�14777724260�016411� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} reset (@var{obj}) ## @deftypefnx {} reset (@var{obj}, @var{cnt}) ## reset the rotary encoder count values ## ## @subsubheading Inputs ## @var{obj} - the rotaryEncoder object ## ## @var{cnt} - optional count value to reset to ## ## @seealso{rotaryEncoder, readCount} ## @end deftypefn function resetCount(obj, cnt) persistent ARDUINO_ROTARYENCODER_RESETCOUNT = 0; if nargin < 2 cnt = 0; endif if cnt < -32000 || cnt > 32000 error ("@rotaryEncoder.resetCount: reset count out of supported range"); endif cnt = uint16(cnt); [tmp, sz] = sendCommand(obj.parent, "rotaryencoder", ARDUINO_ROTARYENCODER_RESETCOUNT, [obj.id bitand(bitshift(cnt, -8),255) bitand(cnt,255)]); endfunction %!test %! ar = arduino (); %! e = rotaryEncoder(ar, "d2","d3"); %! resetCount(e); %! resetCount(e, 10); %! delete(e); ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@rotaryEncoder/rotaryEncoder.m��������������������������������������������������0000644�0000000�0000000�00000011142�14777724260�017075� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018-2020 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. classdef rotaryEncoder < handle ## -*- texinfo -*- ## @deftypefn {} {@var{obj} =} rotaryEncoder (@var{ar}, @var{chanApin}, @var{chanBpin}) ## @deftypefnx {} {@var{obj} =} rotaryEncoder (@var{ar}, @var{chanApin}, @var{chanBpin}, @var{ppr}) ## Create a rotaryEncoder object controlled by the input pins. ## ## @subsubheading Inputs ## @var{ar} - connected arduino object. ## ## @var{chanApin} - pin used for channel A ## ## @var{chanBpin} - pin used for channel B ## ## @var{ppr} - count of encoder pulsed required for a full revolution of the encoder. ## ## @subsubheading Outputs ## @var{obj} - created rotary encoder object ## ## @subsubheading Example ## @example ## a = arduino (); ## enc = rotaryEncoder(a, "d2", "d3", 180); ## @end example ## ## @subsubheading Properties ## The rotaryEncoder object has the following public properties: ## @table @asis ## @item parent ## The parent (arduino) for this device ## @item pins ## pins used by this object ## @item ppr ## Number of pulses used per rotation ## @end table ## ## @seealso{arduino} ## @end deftypefn properties (Access = private) parent = []; id = 0; pins = {}; ppr = []; resourceowner = []; endproperties methods (Access = public) function p = rotaryEncoder(ar, pinA, pinB, ppr) persistent ARDUINO_ROTARYENCODER_CONFIG = 1; if (nargin == 1 && isa (ar, "rotaryEncoder")) register = ar; # Copy constructor elseif nargin < 3 error ('rotaryEncoder: Expected pinA and pinB'); else p.parent = ar; pins = {}; pins{end+1} = ar.get_pin(pinA); pins{end}.func = "channela"; # pin used also to address this obj p.id = pins{1}.id; pins{end+1} = ar.get_pin(pinB); pins{end}.func = "channelb"; if nargin < 4 ppr = []; endif if isempty(ppr) ppr = 0; endif if ! isnumeric(ppr) || ppr < 0 error('rotaryEncoder: ppr should be a positive number') endif # verify pins support digital i/o for i = 1:numel(pins) pin = pins{i}.name; validatePin(ar, pin, "digital"); endfor p.pins = pins; p.ppr = ppr; name = sprintf("encoder-%d", p.id); p.resourceowner = name; count = getResourceCount(ar,name); if count > 0 error ("@rotaryEncoder.rotaryEncoder: already in use"); endif try for i=1:numel(pins) pin = pins{i}.name; configurePin(ar, pin, "pullup"); endfor [tmp, sz] = sendCommand(ar, "rotaryencoder", ARDUINO_ROTARYENCODER_CONFIG, [p.id 1 pins{2}.id]); incrementResourceCount(ar, name); catch # on error, restore pin state for i=1:numel(pins) pin = pins{i}; configurePinResource(ar, pin.name, pin.owner, pin.mode, true) configurePin(ar, pin.name, pin.mode) endfor rethrow (lasterror); end_try_catch # set clean up function # p.cleanup = onCleanup (@() cleanupEncoder (ar, name, pins)); endif endfunction endmethods endclassdef %!shared ar %! ar = arduino(); %!test %! assert (configurePin(ar, "d2"), "unset") %! assert (configurePin(ar, "d3"), "unset") %! enc = rotaryEncoder(ar, "d2", "d3"); %! assert (isa (enc, "rotaryEncoder")) %! assert (!strcmpi(configurePin(ar, "d2"), "unset")) %! assert (!strcmpi(configurePin(ar, "d3"), "unset")) %! delete (enc) %! assert (configurePin(ar, "d2"), "unset") %! assert (configurePin(ar, "d3"), "unset") %!test %! enc = rotaryEncoder(ar, "d2", "d3", 100); %! assert (isa (enc, "rotaryEncoder")) %! delete (enc) %!test %! enc = rotaryEncoder(ar, "d2", "d3"); %! fail ('rotaryEncoder(ar, "d2", "d3");', "already in use"); %! delete (enc) %!error rotaryEncoder(ar); %!error rotaryEncoder(ar, "d2"); ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@rotaryEncoder/subsref.m��������������������������������������������������������0000644�0000000�0000000�00000002774�14777724260�015741� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{val} = } subsref (@var{dev}, @var{sub}) ## subref for rotaryEncoder ## ## @seealso{rotaryEncoder} ## @end deftypefn function val = subsref (p, s) if isempty(s) error ("rotaryEncoder.subsref missing index"); endif if s(1).type == "." fld = tolower(s(1).subs); switch (fld) case "pins" val = {}; for i = 1:numel(p.pins) val{end+1} = p.pins{i}.name; endfor case "parent" val = p.parent; case "ppr" val = p.ppr; otherwise error ("rotaryEncoder.subsref invalid property '%s'", fld); endswitch else error("unimplemented rotaryEncoder.subsref type"); endif if (numel (s) > 1) val = subsref (val, s(2:end)); endif endfunction %!test %! ar = arduino(); %! r = rotaryEncoder (ar, "d2", "d3", 100); %! assert (isarduino(r.parent)) %! assert (ar.port, r.parent.port) %! assert (r.ppr, 100) %! assert (numel(r.pins) == 2) %! fail ("r.invalid") %! delete(r) ����arduino-0.12.2/inst/@servo/�������������������������������������������������������������������������0000755�0000000�0000000�00000000000�14777724260�012416� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@servo/delete.m�����������������������������������������������������������������0000644�0000000�0000000�00000002151�14777724260�014035� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} delete (@var{dev}) ## Free resources of a servo object. ## ## @subsubheading Inputs ## @var{dev} - object to free ## ## @seealso{servo} ## @end deftypefn function delete(this) try ar = this.arduinoobj; pins = this.pins; if !isempty(ar) for i=1:numel(pins) pin = pins{i}; configurePinResource(ar, pin.name, pin.owner, pin.mode, true); configurePin(ar, pin.name, pin.mode); endfor this.arduinoobj = []; endif catch # do nothing end_try_catch endfunction �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@servo/disp.m�������������������������������������������������������������������0000644�0000000�0000000�00000002021�14777724260�013526� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} disp (@var{dev}) ## Display servo object. ## ## @subsubheading Inputs ## @var{dev} - servo device to display ## ## @seealso{servo} ## @end deftypefn function disp (this) printf (" arduino servo object with fields of: \n\n"); printf (" pins = %s\n", this.pins{1}.name ); printf (" minpulseduration = %f\n", this.minpulseduration); printf (" maxpulseduration = %f\n", this.maxpulseduration); endfunction ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@servo/private/�����������������������������������������������������������������0000755�0000000�0000000�00000000000�14777724260�014070� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@servo/private/__servoPosition__.m����������������������������������������������0000644�0000000�0000000�00000003217�14777724260�017730� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. see ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} __servoPosition__ (@var{obj}, @var{value}) ## Private function to get/set servo position ## @end deftypefn function out = __servoPosition__ (obj, value) persistent ARDUINO_SERVO_POSITION = 0; out = 0; ar = obj.arduinoobj; pininfo = obj.pins{1}; diff = obj.maxpulseduration - obj.minpulseduration; assert (diff >= 0); if nargin == 2 if !isnumeric (value) || value < 0 || value > 1.0 error("@servo.writePosition: value must be between 0 and 1"); endif # convert 0 - 1 to min - max pulse value = obj.minpulseduration + (diff*value); intval = uint16(value*1e6); datain = [ bitshift(intval,-8) bitand(intval, 255)]; [tmp, sz] = sendCommand (ar, "servo", ARDUINO_SERVO_POSITION, [pininfo.terminal datain]); else [tmp, sz] = sendCommand (ar, "servo", ARDUINO_SERVO_POSITION, [pininfo.terminal]); value = uint16(tmp(2))*256 + uint16(tmp(3)); value = double(value)/1e6; value = value - obj.minpulseduration; out = value/diff; endif endfunction ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@servo/readPosition.m�����������������������������������������������������������0000644�0000000�0000000�00000002524�14777724260�015237� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{position} = } readPosition (@var{servo}) ## Read the position of a servo ## ## @subsubheading Inputs ## @var{servo} - servo object created from arduino.servo. ## ## @subsubheading Outputs ## @var{position} - value between 0 .. 1 for the current servo position, ## where 0 is the servo min position, 1 is the servo maximum position. ## ## @seealso{servo, writePosition} ## @end deftypefn function value = readPosition (obj) value = __servoPosition__(obj); endfunction %!shared ar %! ar = arduino(); %!test %! s = servo(ar, "d9", "minpulseduration", 1.0e-3, "maxpulseduration", 2e-3); %! writePosition(s, 1); %! assert(readPosition(s), 1); %! writePosition(s, 0); %! assert(readPosition(s), 0); %! delete(s); %!error <undefined> readPosition(); ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@servo/servo.m������������������������������������������������������������������0000644�0000000�0000000�00000010772�14777724260�013741� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018-2020 John Donoghue <john.donoghue@ieee.org> ## ## 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. classdef servo < handle ## -*- texinfo -*- ## @deftypefn {} {@var{obj} = } servo (@var{arduinoobj}, @var{pin}) ## @deftypefnx {} {@var{obj} = } servo (@var{arduinoobj}, @var{pin}, @var{propertyname}, @var{propertyvalue}) ## Create a servo object using a specified pin on a arduino board. ## ## @subsubheading Inputs ## @var{obj} - servo object ## ## @var{arduinoobj} - connected arduino object ## ## @var{propertyname}, @var{propertyvalue} - name value pairs for properties to pass ## to the created servo object. ## ## Current properties are: ## @table @asis ## @item minpulseduration ## min PWM pulse value in seconds. ## @item maxpulseduration ## max PWM pulse value in seconds. ## @end table ## ## @subsubheading Outputs ## @var{obj} - created servo object. ## ## @subsubheading Example ## @example ## # create arduino connection ## ar = arduino(); ## # create hobby servo (1 - 2 ms pulse range) ## servo = servo(ar, "d9", "minpulseduration", 1.0e-3, "maxpulseduration", 2e-3); ## # center the servo ## writePosition(servo, 0.5); ## @end example ## ## @subsubheading Properties ## The servo object has the following public properties: ## @table @asis ## @item parent ## The parent (arduino) for this device ## @item pins ## pins used by this object ## @item minpulseduration ## minpulseduration set for object ## @item maxpulseduration ## maxpulseduration set for object ## @end table ## ## @seealso{arduino, readPosition, writePosition} ## @end deftypefn properties (Access = private) arduinoobj = []; minpulseduration = 5.44e-04; maxpulseduration = 2.40e-03; pins = {}; endproperties methods (Access = public) function this = servo(varargin) persistent ARDUINO_SERVO_CONFIG = 1; if nargin < 2 error("expects arduino object and servo pin"); endif ar = varargin{1}; pin = varargin{2}; this.arduinoobj = []; this.minpulseduration = 5.44e-04; this.maxpulseduration = 2.40e-03; this.pins = {}; if mod (nargin, 2) != 0 error ("servo: expected property name, value pairs"); endif if !iscellstr (varargin(3:2:nargin)) error ("servo: expected property names to be strings"); endif for i = 3:2:nargin propname = tolower (varargin{i}); propvalue = varargin{i+1}; #printf("%s = %s\n", propname, propvalue); if strcmp(propname, "minpulseduration") if !isnumeric (propvalue) error ("servo: minpulseduration should be a number"); endif this.minpulseduration = propvalue; elseif strcmp(propname, "maxpulseduration") if !isnumeric (propvalue) error ("servo: maxpulseduration should be a number"); endif this.maxpulseduration = propvalue; endif endfor if (!isa (ar, "arduino")) error ("servo: expects arduino object"); endif pininfo = getPinInfo (ar, pin); this.arduinoobj = ar; validatePin (ar, pin, 'pwm'); configurePin (ar, pin, "pwm"); this.pins{end+1} = pininfo; sendCommand (ar, "servo", ARDUINO_SERVO_CONFIG, [pininfo.terminal]); # set clean up function # this.cleanup = onCleanup (@() cleanupServo (ar, pininfo)); endfunction endmethods endclassdef %!shared ar %! ar = arduino(); %!test %! assert(configurePin(ar, "d9"), "unset") %! s = servo(ar, "d9"); %! assert(!isempty(s)); %! assert(isa(s, "servo")); %! assert(configurePin(ar, "d9"), "pwm") %! delete(s) %! assert(configurePin(ar, "d9"), "unset") %!error <expects arduino object and servo pin> servo(); %!error <expects arduino object and servo pin> servo(ar); %! s = servo(ar, "d9", "minpulseduration", 1.0e-3, "maxpulseduration", 2e-3); %! assert(!isempty(s)); %! assert(s.minpulseduration, 1.0e-3); %! assert(s.maxpulseduration, 2.0e-3); %! delete(s) ������arduino-0.12.2/inst/@servo/subsref.m����������������������������������������������������������������0000644�0000000�0000000�00000003154�14777724260�014250� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{val} = } subsref (@var{dev}, @var{sub}) ## subref for servo ## ## @seealso{servo} ## @end deftypefn function val = subsref (p, s) if isempty(s) error ("servo.subsref missing index"); endif if s(1).type == "." fld = tolower(s(1).subs); switch (fld) case "pins" val = {}; for i = 1:numel(p.pins) val{end+1} = p.pins{i}; endfor case "parent" val = p.arduinoobj; case "minpulseduration" val = p.minpulseduration; case "maxpulseduration" val = p.maxpulseduration; case "parent" val = p.arduinoobj; otherwise error ("servo.subsref invalid property '%s'", fld); endswitch else error("unimplemented servo.subsref type"); endif if (numel (s) > 1) val = subsref (val, s(2:end)); endif endfunction %!test %! ar = arduino(); %! s = servo (ar, "d9"); %! assert (isarduino(s.parent)) %! assert (ar.port, s.parent.port) %! assert(s.minpulseduration > 0); %! assert(s.maxpulseduration > 0); %! assert (numel(s.pins) == 1) %! fail ("s.invalid") %! delete(s); ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@servo/writePosition.m����������������������������������������������������������0000644�0000000�0000000�00000002700�14777724260�015452� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} writePosition (@var{servo}, @var{position}) ## Write the position to a servo. ## ## @subsubheading Inputs ## @var{servo} - servo object created from arduino.servo. ## ## @var{position} - value between 0 .. 1 for the current servo position, ## where 0 is the servo min position, 1 is the servo maximum position. ## ## @seealso{servo, readPosition} ## @end deftypefn function writePosition (obj, value) if nargin != 2 error ("@servo.writePosition: expected value"); endif __servoPosition__(obj, value); endfunction %!shared ar, s %! ar = arduino(); %! s = servo(ar, "d9", "minpulseduration", 1.0e-3, "maxpulseduration", 2e-3); %!test %! writePosition(s, 1); %! assert(readPosition(s), 1); %! writePosition(s, 0); %! assert(readPosition(s), 0); %!error <undefined> writePosition(); %! error <expected value> writePosition(s); %!test %! delete(s); ����������������������������������������������������������������arduino-0.12.2/inst/@shiftRegister/�����������������������������������������������������������������0000755�0000000�0000000�00000000000�14777724260�014102� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@shiftRegister/delete.m���������������������������������������������������������0000644�0000000�0000000�00000002272�14777724260�015525� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} delete (@var{dev}) ## Free resources of a shiftRegister object. ## ## @subsubheading Inputs ## @var{dev} - object to free ## ## @seealso{shiftRegister} ## @end deftypefn function delete(this) try ar = this.parent; name = this.resourceowner; pins = this.pins; if ~isempty(ar) decrementResourceCount(ar, name); for i=1:numel(pins) pin = pins{i}; configurePinResource(ar, pin.name, pin.owner, pin.mode, true); configurePin(ar, pin.name, pin.mode); endfor this.parent = []; endif catch # do nothing end_try_catch endfunction ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@shiftRegister/disp.m�����������������������������������������������������������0000644�0000000�0000000�00000002117�14777724260�015220� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} disp (@var{register}) ## Display the register object in a verbose way, ## ## @subsubheading Inputs ## @var{register} - the arduino register object created with shiftRegister. ## ## @seealso{shiftRegister} ## @end deftypefn function disp (register) printf (" arduino shift register object with fields of: \n"); printf (" model = ") disp(register.model); for i=1:numel(register.pins) pin = register.pins{i}; printf (" %s = %s\n", pin.func, pin.name) endfor endfunction �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@shiftRegister/read.m�����������������������������������������������������������0000644�0000000�0000000�00000004614�14777724260�015200� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} read (@var{register}) ## @deftypefnx {} {@var{retval} =} read (@var{register}, @var{precision}) ## read a value from the shift register. ## ## @subsubheading Inputs ## @var{register} - shift register created from shiftRegister call. ## ## @var{precision} - optional precision of the data, where precision can be a ## number in a multiple of 8 (ie: 8,16,32) or can be a named integer type: 8 ## of 'uint8', 'uint16', 'uint32'. The default precision is 8. ## ## @subsubheading Outputs ## @var{retval} - returned data read from the register. ## ## @seealso{shiftRegister, write} ## @end deftypefn function out = read(register, precision) persistent ARDUINO_SHIFTREG_READ = 3; persistent endian; if isempty(endian) [~, ~, endian] = computer (); endif if nargin < 1 || nargin > 2 print_usage (); endif if nargin == 2 if ischar(precision) precision = tolower(precision); switch(precision) case "uint8" precision = 8; case "uint16" precision = 16; case "uint32" precision = 32; otherwise error ("unknown precsison value '%s'", precision) endswitch elseif isscalar(precision) if precision <= 0 || mod(precision, 8) != 0 error ("precision should be positive number that is a muiltiple of 8"); endif endif else precision = 8; endif # attempt to clock out precision bits [tmp, sz] = sendCommand(register.parent, "shiftregister", ARDUINO_SHIFTREG_READ, [register.id precision]); out = typecast(uint8(tmp(2:end)), ['uint' num2str(precision)]); if (endian == 'L') out = swapbytes (out); endif endfunction ��������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@shiftRegister/reset.m����������������������������������������������������������0000644�0000000�0000000�00000002244�14777724260�015404� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} reset (@var{register}) ## clear the shift register value. ## ## @subsubheading Inputs ## @var{register} - shift register created from shiftRegister call. ## ## @seealso{shiftRegister, read, write} ## @end deftypefn function reset(register) persistent ARDUINO_SHIFTREG_RESET = 0; # TODO: see if we have a reset pin ? [tmp, sz] = sendCommand(register.parent, "shiftregister", ARDUINO_SHIFTREG_RESET, [register.id]); endfunction ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@shiftRegister/shiftRegister.m��������������������������������������������������0000644�0000000�0000000�00000014620�14777724260�017105� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018-2020 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. classdef shiftRegister < handle ## -*- texinfo -*- ## @deftypefn {} {@var{register} =} shiftRegister (@var{ar}, @var{shifttype}, @var{dataPin}, @var{clockPin} ...) ## @deftypefnx {} {@var{register} =} shiftRegister (@var{ar},'74hc164', @var{dataPin}, @var{clockPin}, @var{resetPin}) ## @deftypefnx {} {@var{register} =} shiftRegister (@var{ar},'74hc165', @var{dataPin}, @var{clockPin}, @var{loadPin}, @var{clockEnablePin}) ## @deftypefnx {} {@var{register} =} shiftRegister(@var{ar},'74hc595', @var{dataPin}, @var{clockPin}, @var{latchPin} , @var{resetPin}) ## Create shift register of a given type, controlled by the input pins. ## ## @subsubheading Inputs ## Common function parameter definition: ## ## @var{ar} - connected arduino object. ## ## @var{shifttype} - string name of the shift register type. ## ## @var{dataPin} - pin used for data in/out of the device. ## ## @var{clockPin} - pin used for clocking data on the shiftRegister. ## ## ## Other variables are dependent on the shift register type: ## @table @asis ## @item '74hc164' ## Additional inputs: ## ## @var{resetPin} - optional pin for resetting the shift register. ## ## @item '74hc165' ## Additional inputs: ## ## @var{loadPin} - load pin to the shift register. ## @var{clockEnablePin} - clock enable pin. ## ## @item '74hc595' ## Additional inputs: ## ## @var{latchPin} - latching data to the shift register. ## @var{resetPin} - optional pin for resetting the shift register. ## ## @end table ## ## @subsubheading Outputs ## @var{register} - register object ## ## @subsubheading Properties ## The shiftRegister object has the following public properties: ## @table @asis ## @item parent ## The parent (arduino) for this device ## @item pins ## pins used by this object ## @item model ## model set for object ## @end table ## ## @seealso{arduino} ## @end deftypefn properties (Access = private) parent = []; model = "none"; datapin = ""; clockpin = ""; id = 0; pins = {}; resourceowner = ""; endproperties methods (Access = public) function p = shiftRegister(ar,type,dataPin,clockPin, varargin) persistent ARDUINO_SHIFTREG_CONFIG = 1; if (nargin == 1 && isa (ar, "shiftRegister")) register = ar; # Copy constructor elseif nargin < 4 error ('Expected type, dataPin and clockPin'); else p.parent = ar; p.model = toupper(type); p.datapin = dataPin; p.clockpin = clockPin; p.id = 0; pins = {}; pins{end+1} = ar.get_pin(dataPin); pins{end}.func = "datapin"; # datapin used also to address this register p.id = pins{1}.id; name = ["shiftregister_" pins{1}.name]; p.resourceowner = name; count = getResourceCount(ar, name); if count > 0 error ("@shiftRegister.shiftRegister: already have a shift register using this pin"); endif pins{end+1} = ar.get_pin(clockPin); pins{end}.func = "clockpin"; init_data = []; switch (p.model) case '74HC164' init_data = [0 pins{2}.id]; case '74HC165' init_data = [1 pins{2}.id]; if nargin != 6 error('74HC165 expects loadPin and clockEnablePin'); endif pins{end+1} = ar.get_pin(varargin{1}); pins{end}.func = "loadpin"; pins{end+1} = ar.get_pin(varargin{2}); pins{end}.func = "clockenablepin"; init_data = [ init_data pins{3}.id pins{4}.id ]; case '74HC595' init_data = [2 pins{2}.id]; if nargin != 5 && nargin != 6 error('74HC595 expects latchPin and optional resetPin'); endif pins{end+1} = ar.get_pin(varargin{1}); pins{end}.func = "latchpin"; init_data = [ init_data pins{end}.id ]; # optional reset if nargin == 6 pins{end+1} = ar.get_pin(varargin{2}); pins{end}.func = "resetpin"; init_data = [ init_data pins{end}.id ]; endif otherwise error ("Unknown shiftRegister type '%s'", p.model); endswitch # verify pins support digital i/o for i = 1:numel(pins) pin = pins{i}.name; validatePin(ar, pin, "digital"); endfor p.pins = pins; # TODO: save old modes and set them via force if we fail trying to alloc the whole group try for i=1:numel(pins) pin = pins{i}.name; configurePin(ar, pin, "digitaloutput"); endfor [tmp, sz] = sendCommand(ar, "shiftregister", ARDUINO_SHIFTREG_CONFIG, [p.id 1 init_data]); incrementResourceCount(ar, name); catch # restore pin state for i=1:numel(pins) pin = pins{i}; configurePinResource(ar, pin.name, pin.owner, pin.mode, true) configurePin(ar, pin.name, pin.mode) endfor rethrow (lasterror); end_try_catch #p.cleanup = onCleanup (@() cleanupShiftRegister (ar, name, pins)); endif endfunction endmethods endclassdef %!shared ar %! ar = arduino(); %!test %! # validate pins not allocated %! assert(configurePin(ar, "d2"), "unset"); %! assert(configurePin(ar, "d3"), "unset"); %! %! register = shiftRegister(ar, '74hc164', "d2", "d3"); %! assert (isa (register, "shiftRegister")) %! %! #pins allocated ? %! assert(configurePin(ar, "d2"), "digitaloutput"); %! assert(configurePin(ar, "d3"), "digitaloutput"); %! %! #free %! delete(register) %! assert(configurePin(ar, "d2"), "unset"); %! assert(configurePin(ar, "d3"), "unset"); ����������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@shiftRegister/subsref.m��������������������������������������������������������0000644�0000000�0000000�00000003016�14777724260�015731� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{val} = } subsref (@var{dev}, @var{sub}) ## subref for shiftRegister ## ## @seealso{shiftRegister} ## @end deftypefn function val = subsref (p, s) if isempty(s) error ("shiftRegister.subsref missing index"); endif if s(1).type == "." fld = tolower(s(1).subs); switch (fld) case "pins" val = {}; for i = 1:numel(p.pins) val{end+1} = p.pins{i}.name; endfor case "parent" val = p.parent; case "model" val = p.model; otherwise error ("shiftRegister.subsref invalid property '%s'", fld); endswitch else error("unimplemented shiftRegister.subsref type"); endif if (numel (s) > 1) val = subsref (val, s(2:end)); endif endfunction %!test %! ar = arduino(); %! r = shiftRegister(ar, '74hc164', "d2", "d3"); %! assert (isarduino(r.parent)) %! assert (ar.port, r.parent.port) %! assert (r.model, "74HC164") %! assert (numel(r.pins) == 2) %! fail ("r.invalid") %! delete(r); ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@shiftRegister/write.m����������������������������������������������������������0000644�0000000�0000000�00000005120�14777724260�015410� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} write (@var{register}, @var{dataIn}) ## @deftypefnx {} write (@var{register}, @var{dataIn}, @var{precision}) ## Write a value to the shift register. ## ## @subsubheading Inputs ## @var{register} - shift register created from shiftRegister call. ## ## @var{dataIn} - data to clock into the shiftRegister. ## ## @var{precision} - optional precision of the data, where precision can be a ## number in a multiple of 8 (ie: 8,16,32) or can be a named integer type ## of 'uint8', 'uint16', 'uint32'. The default precision is 8. ## ## @seealso{shiftRegister, read} ## @end deftypefn function write(register, dataIn, precision) persistent ARDUINO_SHIFTREG_WRITE = 2; persistent endian; if isempty(endian) [~, ~, endian] = computer (); endif if nargin < 2 || nargin > 3 print_usage (); endif if nargin == 3 if ischar(precision) precision = tolower(precision); switch(precision) case "uint8" precision = 8; case "uint16" precision = 16; case "uint32" precision = 32; otherwise error ("unknown precsison value '%s'", precision) endswitch elseif isscalar(precision) if precision <= 0 || mod(precision, 8) != 0 error ("precision should be positive number that is a muiltiple of 8"); endif endif else precision = 8; endif switch (precision) case 8 dataIn = uint8(dataIn); case 16 dataIn = uint16(dataIn); if (endian == 'L') dataIn = swapbytes (dataIn); endif dataIn = typecast(dataIn, 'uint8'); case 32 dataIn = uint32(dataIn); if (endian == 'L') dataIn = swapbytes (dataIn); endif dataIn = typecast(dataIn, 'uint8'); endswitch [tmp, sz] = sendCommand(register.parent, "shiftregister", ARDUINO_SHIFTREG_WRITE, [register.id dataIn]); endfunction ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@spidev/������������������������������������������������������������������������0000755�0000000�0000000�00000000000�14777724260�012552� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@spidev/delete.m����������������������������������������������������������������0000644�0000000�0000000�00000003355�14777724260�014200� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} delete (@var{dev}) ## Free resources of a spidev object. ## ## @subsubheading Inputs ## @var{dev} - spidev object to free ## ## @seealso{spidev} ## @end deftypefn function delete(this) try ar = this.parent; resource = this.resourceowner; if !isempty(ar) pins = this.pins; for i=1:numel(pins) pin = pins{i}; if strcmp(tolower(pin.func), "cs") configurePinResource(ar, pin.name, pin.owner, pin.mode, true); configurePin(ar, pin.name, pin.mode); endif endfor # clean up the spi port if not used? count = getResourceCount(ar, resource); if count > 0 count = decrementResourceCount(ar, resource); if count == 0 # last user, so free pins (except ss that we already did) pins = getSharedResourceProperty(ar, resource, "pins"); for i=1:numel(pins) pin = pins{i}; configurePinResource(ar, pin.name, pin.owner, pin.mode, true); configurePin(ar, pin.name, pin.mode); endfor endif endif this.parent = []; endif catch # do nothing end_try_catch endfunction �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@spidev/disp.m������������������������������������������������������������������0000644�0000000�0000000�00000002313�14777724260�013666� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} disp (@var{dev}) ## Display spidev object. ## ## @subsubheading Inputs ## @var{dev} - spidev object to display ## ## @seealso{spidev} ## @end deftypefn function disp (this) printf (" arduino spidev object with fields of: \n\n"); printf (" chipselectpin = %s\n", this.chipselectpin); printf (" mode = %d\n", this.mode); printf (" bitorder = %s\n", this.bitorder); printf (" bitrate = %d\n", this.bitrate); printf (" pins = "); for i=1:numel(this.pins) printf("%s(%s) ", this.pins{i}.name, this.pins{i}.func) endfor printf("\n"); printf("\n"); endfunction ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@spidev/spidev.m����������������������������������������������������������������0000644�0000000�0000000�00000017777�14777724260�014245� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018-2020 John Donoghue <john.donoghue@ieee.org> ## ## 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. classdef spidev < handle ## -*- texinfo -*- ## @deftypefn {} {@var{dev} =} spidev (@var{ar}, @var{cspin}) ## @deftypefnx {} {@var{dev} =} spidev (@var{ar}, @var{cspin}, @var{propname}, @var{propvalue}) ## ## @code{spidev} is depreciated and will be removed in a future version. ## Use @code{device} instead. ## ## Create an spidev object to communicate to the SPI port on a connected arduino. ## ## @subsubheading Inputs ## @var{ar} - connected arduino object ## ## @var{cspin} - chip select pin for attached spi device. ## ## @var{propname}, @var{propvalue} - property name/value pair for values to pass to devices. ## ## Currently known properties: ## @table @asis ## @item bitrate ## bit rate speed in Mbs ## @item bitorder ## 'msbfirst' or 'lsbfirst' ## @item mode ## SPI mode 0 - 3. ## @end table ## ## @subsubheading Outputs ## @var{dev} - created spidev object ## ## @subsubheading Properties ## The spidev object has the following public properties: ## @table @asis ## @item parent ## The parent (arduino) for this device ## @item pins ## pins used by this object ## @item mode ## mode used for created object ## @item bitrate ## Bitrate set for object ## @item bitorder ## Bitorder set for object ## @item chipselectpin ## Pin used for chipselect ## @end table ## ## @seealso{arduino, readWrite} ## @end deftypefn properties (Access = private) id = []; chipselectpin = ""; mode = 0; bitrate = 4000000; bitorder = 'msbfirst'; parent = []; resourceowner = "spi"; pins = {}; endproperties methods (Access = public) function this = spidev (varargin) ARDUINO_SPI_CONFIG = 1; persistent warned = false; if (! warned) warned = true; warning ("Octave:deprecated-function", "spidev is obsolete and will be removed from a future version of arduino, please use 'device' instead"); endif if nargin < 2 error ("spidev: expects arduino object and chipselect pin"); endif ar = varargin{1}; cspin = varargin{2}; if mod(nargin, 2) != 0 error ("spidev: expected property name, value pairs"); endif if !iscellstr (varargin(3:2:nargin)) error ("spidev: expected property names to be strings"); endif isfirst = getResourceCount(ar,"spi") == 0; for i = 3:2:nargin propname = tolower(varargin{i}); propvalue = varargin{i+1}; % printf("%s = %s\n", propname, propvalue); if strcmp (propname, "bitrate") if !isnumeric (propvalue) error("bitrate should be a number") endif this.bitrate = propvalue; elseif strcmp (propname, "mode") if !isnumeric (propvalue) || propvalue < 0 || propvalue > 3 error("mode should be a number betwwen 0 - 3"); endif this.mode = propvalue; elseif strcmp (propname, "bitorder") if !ischar(propvalue) error("bitorder should be a string"); endif this.bitorder = tolower(propvalue); if this.bitorder != "msbfirst" && this.bitorder != "lsbfirst" error("bitorder should be 'msbfirst' or 'lsbfirst'"); endif endif endfor if (!isa (ar, "arduino")) error("expects arduino object"); endif this.chipselectpin = cspin; this.parent = ar; this.resourceowner = "spi"; # check if is valid CS pin that can use as output validatePin(ar, cspin, 'digital') if strcmp(getResourceOwner(ar, cspin), this.resourceowner) error ("pin %s is already in use by SPI", cspin) endif if isfirst terms = getSPITerminals(ar); tmp_pins = ar.get_pingroup(terms{1}, "SPI"); if numel(tmp_pins) != 4 error ("expected 4 SPI pins but only have %d", numel(tmp_pins)) endif setSharedResourceProperty(ar, this.resourceowner, "pins", tmp_pins); endif tmp_pins = getSharedResourceProperty(ar, this.resourceowner, "pins"); cs_is_ss = false; cspin = getPinInfo(ar, cspin); cspin.func = "cs"; for i=1:4 # verify cs pin is either SS pin, or a not a spi pin if strcmp(tolower(tmp_pins{i}.func), "ss") if strcmpi(tmp_pins{i}.name, cspin.name) cs_is_ss = true; endif else # check not trying to set CS to a spi pin if strcmpi(tmp_pins{i}.name, cspin.name) error ("can not set cspin to a SPI function pin"); endif endif endfor if !cs_is_ss tmp_pins{end+1} = cspin; endif this.pins = tmp_pins; this.id = cspin.terminal; try for i=1:numel(tmp_pins) if isfirst if strcmp(tolower(tmp_pins{i}.func), "ss") || strcmp(tolower(tmp_pins{i}.func), "cs") configurePin(ar, tmp_pins{i}.name, "digitaloutput") configurePinResource (ar, tmp_pins{i}.name, "spi", "digitaloutput", true); else configurePin(ar, tmp_pins{i}.name, "spi") endif else # only allocate cs pin if not first device if strcmp(tolower(tmp_pins{i}.func), "cs") configurePin(ar, tmp_pins{i}.name, "digitaloutput") configurePinResource (ar, tmp_pins{i}.name, "spi", "digitaloutput", true); endif endif endfor bitorder = 0; if strcmp(this.bitorder, 'lsbfirst') bitorder = 1; endif [tmp, sz] = sendCommand(this.parent, this.resourceowner, ARDUINO_SPI_CONFIG, [this.id 1 this.mode bitorder]); incrementResourceCount(ar, this.resourceowner); catch for i=1:numel(tmp_pins) if strcmp(tolower(tmp_pins{i}.func), "cs") || isfirst configurePinResource(ar, tmp_pins{i}.name, tmp_pins{i}.owner, tmp_pins{i}.mode, true) configurePin(ar, tmp_pins{i}.name, tmp_pins{i}.mode) endif endfor rethrow (lasterror); end_try_catch endfunction endmethods endclassdef %!shared arduinos %! arduinos = scanForArduinos(1); %!assert(numel(arduinos), 1); %!test %! ar = arduino(); %! assert(!isempty(ar)); %! %! spipins = getSPITerminals(ar); %! assert (numel(spipins), 4); %! %! # validate SPI pins not allocated %! assert(configurePin(ar, "d10"), "unset") %! assert(configurePin(ar, spipins{1}), "unset") %! assert(configurePin(ar, spipins{2}), "unset") %! assert(configurePin(ar, spipins{3}), "unset") %! assert(configurePin(ar, spipins{4}), "unset") %! %! spi = spidev(ar, "d10"); %! assert(!isempty(spi)); %! assert(spi.chipselectpin, "d10"); %! %! # validate SPI pins allocated %! assert(configurePin(ar, "d10"), "digitaloutput") %! #assert(configurePin(ar, spipins{1}), 'digitaloutput') ## ss %! #assert(configurePin(ar, spipins{2}), 'digitaloutput') ## mosi %! #assert(configurePin(ar, spipins{3}), 'digitalinput') ## miso %! #assert(configurePin(ar, spipins{4}), 'digitaloutput') ## sck %! %! delete(spi); %! %! # check now pins unset %! assert(configurePin(ar, "d10"), "unset") %! assert(configurePin(ar, spipins{1}), "unset") %! assert(configurePin(ar, spipins{2}), "unset") %! assert(configurePin(ar, spipins{3}), "unset") %! assert(configurePin(ar, spipins{4}), "unset") %!test %! ar = arduino(); %! spi = spidev(ar, "d10"); %! fail ('spidev(ar, "d10");', 'pin d10 is already in use') %! spi2 = spidev(ar, "d5"); %! delete(spi); %! delete(spi2); �arduino-0.12.2/inst/@spidev/subsref.m���������������������������������������������������������������0000644�0000000�0000000�00000003256�14777724260�014407� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{val} = } subsref (@var{dev}, @var{sub}) ## subref for spidev ## ## @seealso{spidev} ## @end deftypefn function val = subsref (this, s) if isempty(s) error ("spidev.subsref missing index"); endif if s(1).type == "." fld = tolower(s(1).subs); switch (fld) case "pins" val = {}; for i = 1:numel(this.pins) val{end+1} = this.pins{i}.name; endfor case "parent" val = this.parent; case "mode" val = this.mode; case "bitrate" val = this.bitrate; case "bitorder" val = this.bitorder; case "chipselectpin" val = this.chipselectpin; otherwise error ("spidev.subsref invalid property '%s'", fld); endswitch else error("unimplemented spidev.subsref type"); endif if (numel (s) > 1) val = subsref (val, s(2:end)); endif endfunction %!test %! ar = arduino(); %! spi = spidev (ar, "d10"); %! assert (spi.chipselectpin, "d10") %! assert (isarduino(spi.parent)) %! assert (ar.port, spi.parent.port) %! assert (spi.mode, 0) %! assert (spi.bitorder, "msbfirst") %! assert (numel(spi.pins) >= 4) %! fail ("spi.invalid") ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@spidev/writeRead.m�������������������������������������������������������������0000644�0000000�0000000�00000003433�14777724260�014661� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{dataOut} =} readWrite (@var{spi}, @var{dataIn}) ## Write uint8 data to spi device and return ## back clocked out response data of same size. ## ## @subsubheading Inputs ## @var{spi} - connected spi device on arduino ## ## @var{dataIn} - uint8 sized data to send to spi device framed between SS frame. ## ## @subsubheading Outputs ## @var{dataOut} - uint8 data clocked out during send to dataIn. ## ## @seealso{arduino, spidev} ## @end deftypefn function dataOut = writeRead (this, dataIn) dataOut = []; persistent ARDUINO_SPI_READ_WRITE = 2; if nargin < 2 error ("@spidev.writeRead: expected dataIn"); endif [tmp, sz] = sendCommand (this.parent, this.resourceowner, ARDUINO_SPI_READ_WRITE, [this.id uint8(dataIn)]); if sz > 0 dataOut = tmp(2:end); endif endfunction %!shared arduinos %! arduinos = scanForArduinos(1); %!assert(numel(arduinos), 1); %!test %! ar = arduino(); %! assert(!isempty(ar)); %! spi = spidev(ar, "d10"); %! assert(!isempty(spi)); %! data = writeRead(spi, 1); %! assert(numel(data), 1); %!test %! ar = arduino(); %! assert(!isempty(ar)); %! spi = spidev(ar, "d10"); %! assert(!isempty(spi)); %! data = writeRead(spi, [1 1 1]); %! assert(numel(data), 3); �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@ultrasonic/��������������������������������������������������������������������0000755�0000000�0000000�00000000000�14777724260�013443� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@ultrasonic/delete.m������������������������������������������������������������0000644�0000000�0000000�00000002233�14777724260�015063� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} delete (@var{dev}) ## Free resources of a ultrasonic object. ## ## @subsubheading Inputs ## @var{dev} - ultrasonic object to free ## ## @seealso{ultrasonic} ## @end deftypefn function delete(this) try ar = this.parent; resource = this.resourceowner; pins = this.pins; if ! isempty(ar) for i=1:numel(pins) pin = pins{i}; configurePinResource(ar, pin.name, pin.owner, pin.mode, true); configurePin(ar, pin.name, pin.mode); endfor this.parent = []; endif catch # do nothing end_try_catch endfunction ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@ultrasonic/disp.m��������������������������������������������������������������0000644�0000000�0000000�00000002000�14777724260�014550� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} disp (@var{dev}) ## Display ultrasonic object. ## ## @subsubheading Inputs ## @var{dev} - ultrasonic object to display ## ## @seealso{ultrasonic} ## @end deftypefn function disp (this) printf (" arduino ultrasonic object with fields of: \n\n"); printf (" triggerpin = %s\n", this.pins{1}.name); if numel(this.pins) > 1 printf (" echopin = %s\n", this.pins{2}.name); endif printf("\n"); endfunction arduino-0.12.2/inst/@ultrasonic/readDistance.m������������������������������������������������������0000644�0000000�0000000�00000003150�14777724260�016206� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{distance} =} readDistance (@var{dev}) ## Read the distance from a ultrasonic device ## ## @subsubheading Inputs ## @var{dev} - connected ultrasonic device opened using ultrasonic ## ## @subsubheading Outputs ## @var{distance} - distance value in meters from the ultrasonic device, or Inf if out of sensor range ## ## @seealso{arduino, ultrasonic} ## @end deftypefn function out = readDistance (dev) persistent ARDUINO_ULTRASONIC_READ = 2; persistent endian; if isempty(endian) [~, ~, endian] = computer (); endif if nargin != 1 print_usage (); endif [tmp, sz] = sendCommand (dev.parent, "ultrasonic", ARDUINO_ULTRASONIC_READ, [dev.id]); value = uint32(tmp(2))*(256*256*256) + uint32(tmp(3))*(256*256) + uint32(tmp(4))*256 + uint32(tmp(5)); if value == 0 || value == 0xffffffff out = Inf; else out = double(value)*0.0344/2/100; % meters endif endfunction %!test %! ar = arduino(); %! x = ultrasonic(ar, "d9"); %! v = readDistance(x); %!error <'readDistance' undefined> readDistance() ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@ultrasonic/readEchoTime.m������������������������������������������������������0000644�0000000�0000000�00000003172�14777724260�016155� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{time} =} readEchoTime (@var{dev}) ## Measure the time for waves to reflect back to the ultrasonic device ## ## @subsubheading Inputs ## @var{dev} - connected ultrasonic device opened using ultrasonic() ## ## @subsubheading Outputs ## @var{time} - time in seconds, or Inf if out of sensor range ## ## @seealso{arduino, ultrasonic} ## @end deftypefn function out = readEchoTime (dev) persistent ARDUINO_ULTRASONIC_READ = 2; if nargin != 1 print_usage (); endif precision = dev.outputformat; [tmp, sz] = sendCommand (dev.parent, "ultrasonic", ARDUINO_ULTRASONIC_READ, [dev.id]); value = uint32(tmp(2))*(256*256*256) + uint32(tmp(3))*(256*256) + uint32(tmp(4))*256 + uint32(tmp(5)); if value == 0 || value == 0xffffffff out = Inf; else # seconds out = double(value)/1000000.0; endif # TODO precision can be double or duration - currently octave doesnt know duration endfunction %!test %! ar = arduino(); %! x = ultrasonic(ar, "d9"); %! v = readEchoTime(x); %!error <'readEchoTime' undefined> readEchoTime() ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@ultrasonic/subsref.m�����������������������������������������������������������0000644�0000000�0000000�00000003170�14777724260�015273� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{val} = } subsref (@var{dev}, @var{sub}) ## subref for ultrasonic ## ## @seealso{ultrasonic} ## @end deftypefn function val = subsref (p, s) if isempty(s) error ("ultrasonic.subsref missing index"); endif if s(1).type == "." fld = tolower(s(1).subs); switch (fld) case "pins" val = {}; for i = 1:numel(p.pins) val{end+1} = p.pins{i}.name; endfor case "outputformat" val = p.outputformat; case "parent" val = p.parent; case "triggerpin" val = p.pins{1}.name; case "echopin" if numel(p.pins) > 1 val = p.pins{2}.name; else val = []; endif otherwise error ("ultrasonic.subsref invalid property '%s'", fld); endswitch else error("unimplemented ultrasonic.subsref type"); endif if (numel (s) > 1) val = subsref (val, s(2:end)); endif endfunction %!test %! ar = arduino(); %! x = ultrasonic (ar, "d2", "d3"); %! assert (isarduino(x.parent)) %! assert (x.triggerpin, "d2") %! assert (x.echopin, "d3") %! assert (numel(x.pins) == 2) %! fail ("x.invalid") ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/@ultrasonic/ultrasonic.m��������������������������������������������������������0000644�0000000�0000000�00000012513�14777724260�016006� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019-2020 John Donoghue <john.donoghue@ieee.org> ## ## 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. classdef ultrasonic < handle ## -*- texinfo -*- ## @deftypefn {} {@var{dev} =} ultrasonic (@var{ar}, @var{triggerpin}) ## @deftypefnx {} {@var{dev} =} ultrasonic (@var{ar}, @var{triggerpin}, @var{echopin}) ## @deftypefnx {} {@var{dev} =} ultrasonic (@var{ar}, @var{triggerpin}, @var{echopin}, @var{propname}, @var{propvalue}) ## Create an ultrasonic object to communicate to a connected ultrasonic device ## ## @subsubheading Inputs ## @var{ar} - connected arduino object ## ## @var{triggerpin} - trigger pin for attached device. ## ## @var{echopin} - trigger pin for attached device. ## ## @var{propname}, @var{propvalue} - property name/value pair for values to pass to devices. ## ## Currently known properties: ## @table @asis ## @item outputformat ## string designating number format for output ('double') ## @end table ## ## @subsubheading Outputs ## @var{dev} - created ultrasonic object ## ## @subsubheading Properties ## The ultrasonic object has the following public properties: ## @table @asis ## @item parent ## The parent (arduino) for this device ## @item pins ## pins used by this object ## @item triggerpin ## trigger used for created object ## @item echopin ## Echo pin set for object ## @item outputformat ## Output format for the created object ## @end table ## ## @seealso{arduino, readDistance, readEchoTime} ## @end deftypefn properties (Access = private) id = []; pins = {}; outputformat = "double"; parent = []; resourceowner = "ultrasonic"; endproperties methods (Access = public) function this = ultrasonic (varargin) ARDUINO_ULTRASONIC_CONFIG = 1; if nargin < 2 error ("expects arduino object and triggerpin pin"); endif ar = varargin{1}; triggerpin = varargin{2}; echopin = []; if nargin > 2 echopin = varargin{3}; endif if nargin > 3 && mod(nargin-3, 2) != 0 error ("arduino: expected property name, value pairs"); endif if !iscellstr (varargin(4:2:nargin)) error ("arduino: expected property names to be strings"); endif this.id = []; this.pins = {}; this.outputformat = "double"; for i = 4:2:nargin propname = tolower(varargin{i}); propvalue = varargin{i+1}; % printf("%s = %s\n", propname, propvalue); if strcmp (propname, "outputformat") if !ischar(propvalue) error("outputformat should be a string"); endif this.outputformat = tolower(propvalue); # NOTE:currently outputformat is ignored endif endfor if (!isa (ar, "arduino")) error("expects arduino object"); endif this.parent = ar; this.resourceowner = "ultrasonic"; tmp_pins = {}; validatePin(ar, triggerpin, 'digital') tmp_pins{end+1} = getPinInfo(ar, triggerpin); if !isempty(echopin) validatePin(ar, echopin, 'digital') tmp_pins{end+1} = getPinInfo(ar, echopin); endif this.pins = tmp_pins; this.id = tmp_pins{1}.terminal; try configurePin(ar, tmp_pins{1}.name, "digitaloutput") configurePinResource (ar, tmp_pins{1}.name, this.resourceowner, "digitaloutput", true); if numel(tmp_pins) > 1 configurePin(ar, tmp_pins{2}.name, "digitaloutput") configurePinResource (ar, tmp_pins{2}.name, this.resourceowner, "digitalinput", true); endif if numel(tmp_pins) > 1 [tmp, sz] = sendCommand(this.parent, this.resourceowner, ARDUINO_ULTRASONIC_CONFIG, [this.id 1 tmp_pins{2}.terminal]); else [tmp, sz] = sendCommand(this.parent, this.resourceowner, ARDUINO_ULTRASONIC_CONFIG, [this.id 1]); endif catch for i=1:numel(tmp_pins) configurePinResource(ar, tmp_pins{i}.name, tmp_pins{i}.owner, tmp_pins{i}.mode, true) configurePin(ar, tmp_pins{i}.name, tmp_pins{i}.mode) endfor rethrow (lasterror); end_try_catch # # set clean up function # this.cleanup = onCleanup (@() cleanupUltrasonic (ar, this.resourceowner, tmp_pins)); endfunction endmethods endclassdef %!shared arduinos %! arduinos = scanForArduinos(1); %!assert(numel(arduinos), 1); %!test %! ar = arduino(); %! assert(!isempty(ar)); %! %! x = ultrasonic(ar, "d9"); %! assert(!isempty(x)); %! assert(isa(x, "ultrasonic")) %!test %! ar = arduino(); %! x = ultrasonic(ar, "d9", "d10"); %! assert(!isempty(x)); %!test %! ar = arduino(); %! fail ('ultrasonic();', 'expects arduino object and triggerpin pin') %! fail ('ultrasonic(ar);', 'expects arduino object and triggerpin pin') %! fail ('ultrasonic(ar, "hello");', 'arduino: unknown pin hello') �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/__load_arduino__.m��������������������������������������������������������������0000644�0000000�0000000�00000003431�14777724260�014573� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2023 John Donoghue ## ## 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 ## <http:##www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {} __load_arduino__ () ## Undocumented internal function of arduino package. ## @end deftypefn ## PKG_ADD: __load_arduino__ () function __load_arduino__ () if exist ("isfolder") == 0 if (isdir (fullfile (fileparts (mfilename ("fullpath")), "sensors"))) addpath (fullfile (fileparts (mfilename ("fullpath")), "sensors")); endif else if (isfolder (fullfile (fileparts (mfilename ("fullpath")), "sensors"))) addpath (fullfile (fileparts (mfilename ("fullpath")), "sensors")); endif endif # on package load, attempt to load docs try pkg_dir = fileparts (fullfile (mfilename ("fullpath"))); doc_file = fullfile (pkg_dir, "doc", "arduino.qch"); doc_file = strrep (doc_file, '\', '/'); if exist(doc_file, "file") if exist("__event_manager_register_documentation__") __event_manager_register_documentation__ (doc_file); elseif exist("__event_manager_register_doc__") __event_manager_register_doc__ (doc_file); endif endif catch # do nothing end_try_catch endfunction ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/__unload_arduino__.m������������������������������������������������������������0000644�0000000�0000000�00000003451�14777724260�015140� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2023 John Donoghue ## ## 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 ## <http:##www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {} __unload_arduino__ () ## Undocumented internal function of arduino package. ## @end deftypefn ## PKG_DEL: __unload_arduino__ () function __unload_arduino__ () if exist ("isfolder") == 0 if (isdir (fullfile (fileparts (mfilename ("fullpath")), "sensors"))) rmpath (fullfile (fileparts (mfilename ("fullpath")), "sensors")); endif else if (isfolder (fullfile (fileparts (mfilename ("fullpath")), "sensors"))) rmpath (fullfile (fileparts (mfilename ("fullpath")), "sensors")); endif endif # on package unload, attempt to unload docs try pkg_dir = fileparts (fullfile (mfilename ("fullpath"))); doc_file = fullfile (pkg_dir, "doc", "arduino.qch"); doc_file = strrep (doc_file, '\', '/'); if exist(doc_file, "file") if exist("__event_manager_unregister_documentation__") __event_manager_unregister_documentation__ (doc_file); elseif exist("__event_manager_unregister_doc__") __event_manager_unregister_doc__ (doc_file); endif endif catch # do nothing end_try_catch endfunction �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/addon.m�������������������������������������������������������������������������0000644�0000000�0000000�00000006050�14777724260�012424� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} addon (@var{ar}, @var{addonname}) ## @deftypefnx {} {@var{retval} =} addon (@var{ar}, @var{addonname}, varargs) ## Create an addon object using the addon named class. ## ## @subsubheading Inputs ## @var{ar} - connected arduino object ## ## @var{addonname} - the name of the addon to create. The addon name can be a user ## addon or an inbuilt addon, however must appear in the listArduinoLibraries ## output and have been programmed onto the arduino. ## ## @var{varargs} - optional values that will be provided verbatim to the ## the addon class constructor. ## ## @subsubheading Outputs ## @var{retval} - cell array of string library names. ## ## @seealso{arduino, arduinosetup, listArduinoLibraries} ## @end deftypefn function retval = addon (ar, addonname, varargin) if (! isa (ar, "arduino")) error("addon: expected first arguiment to be a arduino object"); endif # verify arduino has the plugin name p = ar.get_lib (addonname); if p == -1 error ("addon: arduino has not been programmed with a plugin named '%s'\n", addonname); endif availlibs = listArduinoLibraries (); addonlibs = __addons__ (); # get addonin for the requested library idx = find (cellfun(@(x) strcmpi(x.libraryname, addonname), addonlibs), 1); if isempty (idx) #if not found, was an inbuilt one ? # verify can find the lib and get/make constructor of it idx = find (cellfun(@(x) strcmpi(x, addonname), availlibs), 1); if isempty (idx) error ("addon: unknown library '%s'", addonname); endif # a known normal addon like spi if strcmpi (addonname, "spi") lib = "spidev"; elseif strcmpi (addonname, "i2c") lib = "i2cdev"; elseif strcmpi (addonname, "servo") lib = "servo"; elseif strcmpi (addonname, "shiftregister") lib = "shiftRegister"; elseif strcmpi (addonname, "rotaryencoder") lib = "rotaryEncoder"; else error ("addon: unknown builtin library '%s'", addonname); endif else # user addon constructor lib = addonlibs{idx}.classname; endif # get constructor function handle constructor = str2func (lib); # create object retval = constructor (ar, varargin{:}); endfunction %!test %! a = arduino(); %! # do equivalent of s = i2cdev(a, 10); %! s = addon(a, "i2c", 10); %! assert(class(s), "i2cdev"); ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/arduino_bistsetup.m�������������������������������������������������������������0000644�0000000�0000000�00000007046�14777724260�015110� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019-2020 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} arduino_bistsetup () ## @deftypefnx {} {@var{retval} =} arduino_bistsetup (@var{propertyname}, @var{propertyvalue}) ## Install on an arduino the required core libraries to run the BIST tests ## ## As part of the setup, the arduino IDE will be opened to allow programming ## the arduino board. ## ## @subsubheading Inputs ## ## @var{propertyname}, @var{propertyvalue} - A sequence of property name/value pairs can be given ## to set defaults while programming. ## ## Currently the following properties can be set: ## @table @asis ## @item arduinobinary ## The value should be the name/path of the arduino IDE binary for programming. If not specified, ## the function will attempt to find the binary itself. ## @item debug ## Set the debug flag when checking the arduino ## @end table ## ## @subsubheading Outputs ## @var{retval} - return 1 if everything installed ok ## ## @seealso{arduino, arduinosetup} ## @end deftypefn function retval = arduino_bistsetup (varargin) retval = 0; if mod (nargin, 2) != 0 error ("arduinosetup: expected property name, value pairs"); endif if !iscellstr (varargin(1:2:nargin)) error ("arduinosetup: expected property names to be strings"); endif arduinobinary = {}; debug = false; for i = 1:2:nargin propname = tolower (varargin{i}); propvalue = varargin{i+1}; if strcmp (propname, "arduinobinary") arduinobinary = propvalue; elseif strcmp (propname, "debug") debug = propvalue; elseif warning ("arduino_bistsetup: unknown property '%s', ignoring it", propname); endif endfor printf ("** Installing core libraries on arduino - please press upload in the IDE, and after completion, close the IDE\n"); fflush(stdout); libs = { "I2C", "servo", "SPI", "ShiftRegister", "RotaryEncoder", "Ultrasonic" }; if ! arduinosetup ('libraries', libs, varargin{:}) error ("Failed to program the arduino"); endif unwind_protect printf ("** Checking for any arduinos\n"); fflush(stdout); ars = scanForArduinos(); printf ("Found %d\n", numel(ars)); printf ("** Checking can open an UNO arduino\n"); fflush(stdout); ar = arduino ([], "uno", 'debug', debug); if ! isarduino(ar) error ('Couldnt load find an arduino UNO board') endif printf ("** Checking arduino version\n"); fflush(stdout); p = pkg('list', 'arduino'); if isempty(p) error ('No arduino package found'); endif ver = p{1}.version; if ! strcmp(ver, version(ar)) error ('Arduino version did not match %s : %s', ver, version(ar)); endif printf ('Arduino has been programmed and is ready for BIST testing\n'); printf ("run: __run_test_suite__({'%s'}, {})\n", p{1}.dir); fflush(stdout); ret = 1; unwind_protect_cleanup clear ar; end_unwind_protect endfunction ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/arduinosetup.m������������������������������������������������������������������0000644�0000000�0000000�00000021214�14777724260�014060� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018-2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} arduinosetup () ## @deftypefnx {} {@var{retval} =} arduinosetup (@var{propertyname}, @var{propertyvalue}) ## Open the arduino config / programming tool to program the arduino hardware for usage with ## the Octave arduino functions. ## ## arduinosetup will create a temporary project using the arduino IDE and allow ## compiling and programming of the code to an arduino. ## ## @subsubheading Inputs ## ## @var{propertyname}, @var{propertyvalue} - A sequence of property name/value pairs can be given ## to set defaults while programming. ## ## Currently the following properties can be set: ## @table @asis ## @item libraries ## The value should be the name of a library, or string array of libraries to program on the ## arduino board. ## @item arduinobinary ## The value should be the name/path of the arduino IDE binary for programming. If not specified, ## the function will use getpref preferences of arduino.arduino_binary, and if not found, the ## function will attempt to find the binary itself. ## ## If provided, the value will be saved to preferences for future calls. ## @end table ## ## @subsubheading Outputs ## @var{retval} - return 1 if arduino IDE returned without an error ## ## @seealso{arduino, __arduino_binary__} ## @end deftypefn function retval = arduinosetup (varargin) retval = 0; if mod (nargin, 2) != 0 error ("arduinosetup: expected property name, value pairs"); endif if !iscellstr (varargin(1:2:nargin)) error ("arduinosetup: expected property names to be strings"); endif libs = {}; arduinobinary = {}; debug = false; baudrate = []; def_baudrate = 9600; for i = 1:2:nargin propname = tolower (varargin{i}); propvalue = varargin{i+1}; if strcmp (propname, "libraries") if iscell (propvalue) libs = propvalue; elseif ischar (propvalue) libs{end+1} = propvalue; else error ("arduinosetup Expected libraries to be a cellarray or string"); endif elseif strcmp (propname, "arduinobinary") arduinobinary = propvalue; elseif strcmp (propname, "baudrate") baudrate = int32(propvalue); elseif strcmp (propname, "debug") debug = propvalue; elseif warning ("arduinosetup: unknown property '%s', ignoring it", propname); endif endfor if isempty(libs) # default libs if not are provided libs{end+1} = "SPI"; libs{end+1} = "I2C"; libs{end+1} = "Servo"; libs{end+1} = "ShiftRegister"; endif # we have the libs ? availlibs = listArduinoLibraries (); addonlibs = __addons__ (); # for any addons, check the dependancies and add it we need to for i = 1:numel(libs) idx = find (cellfun(@(x) strcmpi(x.libraryname, libs{i}), addonlibs), 1); if !isempty(idx) lib = addonlibs{idx}; for n = 1:numel(lib.dependentlibraries) addlib = lib.dependentlibraries{n}; idx = find (cellfun(@(x) strcmpi(x, addlib), libs), 1); if isempty(idx) libs{end+1} = addlib; if (debug) printf("arduinosetup: adding %s as a dependency\n", addlib); endif endif endfor endif endfor builtinlibs = {}; for i = 1:numel(libs) idx = find (cellfun(@(x) strcmpi(x.libraryname, libs{i}), addonlibs), 1); if isempty(idx) idx = find (cellfun(@(x) strcmpi(x, libs{i}), availlibs), 1); if isempty (idx) error ("arduinosetup: unknown library '%s'", libs{i}); elseif (debug) printf("arduinosetup: using builtin lib %s\n", libs{i}); endif builtinlibs{end+1} = libs{i}; libs{i} = []; else if (debug) printf("arduinosetup: using addon lib %s\n", libs{i}); endif libs{i} = addonlibs{idx}; endif endfor libfiles = arduinoio.LibFiles(); if isempty (libfiles) error ("arduinosetup: couldn't find library files"); endif # make a temp folder and create a arduino project in it tmpdir = tempname (); mkdir (tmpdir); unwind_protect mkdir (fullfile (tmpdir, "octave")); # copy all the libfiles copyfile (libfiles, fullfile (tmpdir, "octave")); fd = fopen (fullfile (tmpdir, "octave", "settings.h"), "w+t"); fprintf (fd, "// generated from arduinosetup for buildin library configuration\n"); fprintf (fd, "\n"); fprintf (fd, "// override target voltage (x10) by uncommenting and providing a value\n"); fprintf (fd, "//#define BOARD_VOLTAGE 50\n"); fprintf (fd, "\n"); fprintf (fd, "// override baudrate by providing a value\n"); if !isempty(baudrate) fprintf (fd, "#define ARDUINO_BAUDRATE %d\n", baudrate); else fprintf (fd, "//#define ARDUINO_BAUDRATE %d\n", def_baudrate); endif fprintf (fd, "\n"); fprintf (fd, "// builtin library support\n"); idx = find (cellfun(@(x) strcmpi(x, "SPI"), builtinlibs), 1); if !isempty(idx) fprintf (fd, "#define USE_SPI\n"); else fprintf (fd, "//#define USE_SPI\n"); endif idx = find (cellfun(@(x) strcmpi(x, "I2C"), builtinlibs), 1); if !isempty(idx) fprintf (fd, "#define USE_I2C\n"); else fprintf (fd, "//#define USE_I2C\n"); endif idx = find (cellfun(@(x) strcmpi(x, "Servo"), builtinlibs), 1); if !isempty(idx) fprintf (fd, "#define USE_SERVO\n"); else fprintf (fd, "//#define USE_SERVO\n"); endif idx = find (cellfun(@(x) strcmpi(x, "ShiftRegister"), builtinlibs), 1); if !isempty(idx) fprintf (fd, "#define USE_SHIFTREG\n"); else fprintf (fd, "//#define USE_SHIFTREG\n"); endif idx = find (cellfun(@(x) strcmpi(x, "RotaryEncoder"), builtinlibs), 1); if !isempty(idx) fprintf (fd, "#define USE_ROTARYENCODER\n"); else fprintf (fd, "//#define USE_ROTARYENCODER\n"); endif idx = find (cellfun(@(x) strcmpi(x, "Ultrasonic"), builtinlibs), 1); if !isempty(idx) fprintf (fd, "#define USE_ULTRASONIC\n"); else fprintf (fd, "//#define USE_ULTRASONIC\n"); endif idx = find (cellfun(@(x) strcmpi(x, "Serial"), builtinlibs), 1); if !isempty(idx) fprintf (fd, "#define USE_SERIAL\n"); else fprintf (fd, "//#define USE_SERIAL\n"); endif # if able to do network, add network settings here fprintf (fd, "//#define OCTAVE_USE_WIFI_COMMS\n"); fprintf (fd, "#ifdef OCTAVE_USE_WIFI_COMMS\n"); fprintf (fd, " // Provide these settings for network use\n"); fprintf (fd, "# define WIFI_SECRET_SSID \"\"\n"); fprintf (fd, "# define WIFI_SECRET_PASS \"\"\n"); fprintf (fd, "# define WIFI_PORT 9500\n"); fprintf (fd, " //uncomment and define if using static IP\n"); fprintf (fd, "//# define WIFI_STATIC_IP \"192.168.0.10\"\n"); fprintf (fd, "#endif"); fclose (fd); # requested additional libs fd = fopen (fullfile (tmpdir, "octave", "addons.h"), "w+t"); fprintf(fd, "// generated from arduinosetup for addon library addidtions\n"); for i = 1:numel (libs) l = libs{i}; if !isempty (l) if !isempty (l.cppheaderfile) copyfile (l.cppheaderfile, fullfile(tmpdir, "octave")); [d,f,e] = fileparts (l.cppheaderfile); fprintf (fd, '#include "%s%s"\n', f,e); if !isempty (l.cppclassname) fprintf (fd, "%s addon%d(octavearduino);\n", l.cppclassname, i); endif endif if !isempty (l.cppsourcefile) copyfile (l.cppsourcefile, fullfile(tmpdir, "octave")); endif endif endfor fclose(fd); # start the arduino ide if isempty (arduinobinary) arduinobinary = __arduino_binary__ (); else arduinobinary = __arduino_binary__ (arduinobinary); endif filename = fullfile (tmpdir, "octave", "octave.ino"); cmdline = sprintf ("\"%s\" \"%s\"", arduinobinary, filename); printf ("Running %s\n", cmdline); [status, ~] = system (cmdline); retval = (status == 0); unwind_protect_cleanup confirm_recursive_rmdir (false, "local"); rmdir(tmpdir, "s"); end_unwind_protect endfunction ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/examples/�����������������������������������������������������������������������0000755�0000000�0000000�00000000000�14777724260�012776� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/examples/example_blink.m��������������������������������������������������������0000644�0000000�0000000�00000002066�14777724260�015772� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. % blink the LED on D13 pkg load instrument-control a = arduino(); leds = getLEDTerminals(a); led = getPinsFromTerminals(a, leds{1}); unwind_protect printf("starting to blink...\n"); while (true) writeDigitalPin(a, led, 0); pause(0.5); writeDigitalPin(a, led, 1); pause(0.5); endwhile unwind_protect_cleanup clear a end_unwind_protect ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/examples/example_i2c_eeprom.m���������������������������������������������������0000644�0000000�0000000�00000005362�14777724260�016721� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. % example using the arduino i2c % to communicate to a 24XX256 EEPROM chip connected to an uno % % Connection of arduino to EEPROM as follows: % Arduino 24XX256 eeprom (pin) % A4 - 5 % A5 - 6 % 5V - 8 % GND - 1,2,3,4 pkg load instrument-control eeprom_address = 0x50; data = "this is eeprom data"; # open the arduino a = arduino() unwind_protect [~, ~, endian] = computer (); printf("i2c terminals\n") getI2CTerminals(a) printf("i2c devices attached\n") devs = scanI2Cbus(a) idx = find(devs = eeprom_address); if isempty(idx) warning ('no EEPROM device found at address') endif printf("opening i2c...\n"); # oldstyle # i2c = i2cdev(a, eeprom_address) # new style i2c = device(a, "i2caddress", eeprom_address) printf("writing i2c...\n"); # write data to address 0x0000 write(i2c, [0 0 uint8(data)]); # read from address 0x0008, which should now be 'eeprom' write(i2c, uint8([0 8])); val = read(i2c, 6); printf("reading from 0x0008 = expecting 'eeprom', and got '%s'\n", char(val)) # demo read/write register val = readRegister(i2c, 0, 2, 'uint16'); expected = [typecast(data(1:2),'uint16'),typecast(data(3:4), 'uint16')]; # since default to msb, result will be swapped if we are low endian if endian == 'L' expected = swapbytes(expected); endif printf("reading as reg from 0x0000 = expecting %X %X, and got '%X %X'\n", expected(1), expected(2), val(1), val(2)) # 2nd page write(i2c, [1 0 0 1 0 2 0 3 0 4]); # read from address 0 of page # 0 1 0 2 write(i2c, uint8([1 0])); valu = read(i2c, 4); # read as register from address 0 of page 1 # 1 2 val = readRegister(i2c, 256, 2, 'uint16') # 2 3 valx = readRegister(i2c, 258, 2, 'uint16') # 0 2 0 3 write(i2c, uint8([1 2])); valux = read(i2c, 4) # write page 1, address 2 - 4 writeRegister(i2c, 258, [8 9], 'uint16') # 0 8 0 9 write(i2c, uint8([1 2])); valux = read(i2c, 4) # 8 9 valx = readRegister(i2c, 258, 2, 'uint16') clear i2c unwind_protect_cleanup clear a end_unwind_protect ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/examples/example_i2c_tempsensor.m�����������������������������������������������0000644�0000000�0000000�00000006366�14777724260�017636� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. % example using the arduino i2c to communicate to a Si7021 via a % sparkfun SparkFun Humidity and Temperature Sensor Breakout board % https://www.sparkfun.com/products/13763 % % Conection of arduino to breakout board as follows: % Arduino breakoutboard (pin) (name depending on rev of board) % A4 - 3 (DA or SDA) % A5 - 4 (CL or SCL) % 3V3 - 2 (+ or 3V3) % GND - 1 (- or GND) temp_address = 0x40; # open the arduino a = arduino () unwind_protect printf ("i2c terminals\n") getI2CTerminals (a) printf ("i2c devices attached\n") devs = scanI2Cbus (a) idx = find (devs = temp_address); if isempty (idx) warning ('no Si7021 device found at address') endif printf ("opening i2c...\n"); #old style #i2c = i2cdev (a, temp_address) # new style i2c = device (a, "i2caddress", temp_address) SENSOR_ID_1 = [ hex2dec("FA") hex2dec("F0") ]; SENSOR_ID_2 = [ hex2dec("FC") hex2dec("C9") ]; printf ("query device...\n"); write (i2c, SENSOR_ID_1); id1 = read(i2c, 1); write (i2c, SENSOR_ID_2); id2 = read(i2c, 1); printf ("Sensor ID: %02X%02X\n", id1, id2) printf ("Sensor Type: "); if id2 == hex2dec("15") printf ("Si7021\n"); elseif id2 == hex2dec("14") printf ("Si7020\n"); elseif id2 == hex2dec("0D") printf ("Si7013\n"); elseif id2 == hex2dec("32") printf ("HTU21D\n"); else error ("unknown sensor type of %d found", id2); endif SENSOR_VERSION = [ hex2dec("84") hex2dec("B8") ]; write (i2c, SENSOR_VERSION); ver = read(i2c, 1); printf ("F/W Version: "); if ver == hex2dec("FF") printf ("Version: 1.0\n"); elseif ver == hex2dec("20") printf ("Version: 2.0\n"); else printf ("Version: %f\n", double(ver)/10.0); endif TEMP_MEASURE_NOHOLD = hex2dec("F3"); HUMIDITY_MEASURE_NOHOLD = hex2dec("F5"); % write command to get temp write (i2c, uint8([TEMP_MEASURE_NOHOLD])); pause (0.02); data = read (i2c, 3); value = uint16(data(1))*256 + uint16(data(2)); value = bitand (value, hex2dec("FFFC")); temp_Code = double(value); C = (175.72*temp_Code/65536)-46.85; F = (C * 1.8) +32.0; printf ("temperature read %f C (%f F)\n", C, F); % write command to get rel humidity write (i2c, uint8([HUMIDITY_MEASURE_NOHOLD])); pause (0.02); data = read (i2c, 3); value = uint16(data(1))*256 + uint16(data(2)); value = bitand (value, hex2dec("FFFC")); humidity_Code = double(value); humidity = (125.0*humidity_Code/65536)-6; printf ("relative humidity read %f %%\n", humidity); clear i2c unwind_protect_cleanup clear a end_unwind_protect ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/examples/example_i2c_tempsensor_plot.m������������������������������������������0000644�0000000�0000000�00000010001�14777724260�020651� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. % example using the arduino i2c to communicate to a Si7021 via a % sparkfun SparkFun Humidity and Temperature Sensor Breakout board % https://www.sparkfun.com/products/13763 % % Connection of arduino to breakout board as follows: % Arduino breakoutboard (pin) (name depending on rev of board) % A4 - 3 (DA or SDA) % A5 - 4 (CL or SCL) % 3V3 - 2 (+ or 3V3) % GND - 1 (- or GND) pkg load instrument-control temp_address = 0x40; # open the arduino a = arduino(); unwind_protect % check if can find sensor devs = scanI2Cbus(a); idx = find(devs = temp_address); if isempty(idx) warning ('no Si7021 device found at address') endif # old style #i2c = i2cdev(a, temp_address); # new style i2c = device(a, "i2caddress", temp_address); SENSOR_ID_1 = [ hex2dec("FA") hex2dec("F0") ]; SENSOR_ID_2 = [ hex2dec("FC") hex2dec("C9") ]; write(i2c, SENSOR_ID_1); id1 = read(i2c, 1); write(i2c, SENSOR_ID_2); id2 = read(i2c, 1); printf("Device info ...\n"); printf (" Sensor ID: %02X%02X\n", id1, id2) printf (" Sensor Type: "); if id2 == hex2dec("15") printf("Si7021\n"); elseif id2 == hex2dec("14") printf("Si7020\n"); elseif id2 == hex2dec("0D") printf("Si7013\n"); elseif id2 == hex2dec("32") printf("HTU21D\n"); else error("unknown sensor type of %d found", id2); endif SENSOR_VERSION = [ hex2dec("84") hex2dec("B8") ]; write(i2c, SENSOR_VERSION); ver = read(i2c, 1); printf(" F/W Version: "); if ver == hex2dec("FF") printf("Version: 1.0\n"); elseif ver == hex2dec("20") printf("Version: 2.0\n"); else printf("Version: %f\n", double(ver)/10.0); endif sample_time = 1; history_size = 600; f = figure(); temp_data = zeros(1, history_size); hum_data = zeros(1, history_size); ax1 = subplot(2,1,1); tp = plot(ax1, temp_data); set(tp,'linewidth', 2, 'linestyle', '-', 'color', 'r'); title(ax1, "Temperature"); ylim(ax1, [0 40.0]); xlim(ax1, [1 history_size]); ylabel(ax1, "deg C"); xlabel(ax1, "history"); grid on; ax2 = subplot(2,1,2); hp = plot(ax2, hum_data); set(hp,'linewidth', 2, 'linestyle', '-', 'color', 'b'); title(ax2,"Relative Humidity"); ylim(ax2,[0 100.0]); xlim(ax2,[1 history_size]); ylabel(ax2,"%"); xlabel(ax2,"history"); grid on; TEMP_MEASURE_NOHOLD = hex2dec("F3"); HUMIDITY_MEASURE_NOHOLD = hex2dec("F5"); while(true) % write command to get temp write(i2c, uint8([TEMP_MEASURE_NOHOLD])); pause(0.02); data = read(i2c, 3); value = uint16(data(1))*256 + uint16(data(2)); value = bitand(value, hex2dec("FFFC")); temp_Code = double(value); C = (175.72*temp_Code/65536)-46.85; temp_data(2:history_size) = temp_data(1:history_size-1); temp_data(1) = C; set(tp,'ydata',temp_data); drawnow; % write command to get rel humidity write(i2c, uint8([HUMIDITY_MEASURE_NOHOLD])); pause(0.02); data = read(i2c, 3); value = uint16(data(1))*256 + uint16(data(2)); value = bitand(value, hex2dec("FFFC")); humidity_Code = double(value); humidity = (125.0*humidity_Code/65536)-6; hum_data(2:history_size) = hum_data(1:history_size-1); hum_data(1) = humidity; set(hp,'ydata',hum_data); drawnow; pause(sample_time); endwhile clear i2c unwind_protect_cleanup clear a end_unwind_protect �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/examples/example_lcd_plugin.m���������������������������������������������������0000644�0000000�0000000�00000002500�14777724260�017004� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. # test LCD plugin using the Arduini LinkSprite16x2 LCD LCD Keypad shield # get arduino a = arduino(); # check have the lcd addon programmed havelcd = sum(index(a.libraries, 'examplelcd/lcd')) > 0; if !havelcd error ('no LCD addon found - install it with arduinosetup'); endif # create lcd object lcd = addon(a, "examplelcd/lcd", "d8", "d9", "d4", "d5", "d6", "d7") # loop, displaying date and time on LCD while(true) gotoLCD(lcd, 0, 0); printLCD(lcd, datestr (date, "dd mmm yyyy")); t = localtime(time); gotoLCD(lcd, 0, 1); printLCD(lcd, sprintf("%02d:%02d:%02d", t.hour, t.min, t.sec)) pause(1); endwhile ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/examples/example_shiftreg_595.m�������������������������������������������������0000644�0000000�0000000�00000002515�14777724260�017107� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. # example using a 74HC595 shift register # breakout board https://www.sparkfun.com/products/10680 # arduino shiftRegister (sparkfun breakout) # d2 14 io (ser_in) # d3 11 clk (clock) # d4 12 latch (l_clk) # d5 10 reset (/reset) # 5V 16 vcc (Vcc) # gnd 8 gnd (Gnd) # gnd 13 oe (oe) a = arduino("","", 'Libraries', { "ShiftRegister" }) reg = shiftRegister(a, '74HC595', 'd2', 'd3', 'd4', 'd5'); reset(reg); val = uint8(1) while(true) write(reg, val); pause(1); val = val + uint8(1) endwhile �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/examples/example_spi_mcp3002.m��������������������������������������������������0000644�0000000�0000000�00000004151�14777724260�016627� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. % test program for octave - arduino - mcp3002 10 bit ADC (spi) sel_pin = "d10" # Assuming connections of # Arduino MCP3002 # D10 - 1 (CS) # D11 - 5 (DI) # D12 - 6 (DO) # D13 - 7 (CLK) # VCC - 8 (VDD) # GND - 4 (VSS) # 2 (CH0) - chan 0 input # 3 (CH1) - chan 1 input unwind_protect ar = arduino(); # talk to the mpc3002 via spi - SS = D10 on uno # set msb mode #spi = spidev(ar, "d10") spi = device(ar, "spichipselectpin", sel_pin) # command (bits) in MSB mode to device # [START SGL ODN MSBF X X X X] [ X X X X X X X X ] # 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 # [chan 0 ] MSB # data back # X X X X X 0 D D D D D D D D D D printf("reading ADC @ 1 Hz...\n"); # skip first reading v = writeRead(spi, [ hex2dec("DF") hex2dec("FF") ]); while (true) pause(1); # chan 0 v = writeRead(spi, [ hex2dec("DF") hex2dec("FF") ]); adc = bitand (uint16(v(1))*256 + uint16(v(2)), hex2dec('3FF')); volts = double(adc) * 5.0 / 1023.0; printf("ch0 = 0x%04X (adc) %f (volts)\n", adc, volts) # chan 1 v = writeRead(spi, [ hex2dec("EF") hex2dec("FF") ]); adc = bitand (uint16(v(1))*256 + uint16(v(2)), hex2dec('3FF')); volts = double(adc) * 5.0 / 1023.0; printf("ch1 = 0x%04X (adc) %f (volts)\n", adc, volts) endwhile unwind_protect_cleanup clear ar end_unwind_protect �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/examples/example_sweep_servo.m��������������������������������������������������0000644�0000000�0000000�00000002576�14777724260�017242� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. % example control servo on D9 % scans servo between min - max position a = arduino(); unwind_protect # hobby servo with puslses between 1ms - 2 ms s = servo (a, 'd9', 'MinPulseDuration', 1e-3, 'MaxPulseDuration', 2e-3) # go mid position writePosition (s, .5); # loop, slowly going between min - max pos speed = 0.02; pauseval = .05; printf ("scanning ...\n"); while (true) pos = readPosition (s); pos = pos + speed; if(pos > 1) pos = 1; speed = -speed; endif if(pos < 0) pos = 0; speed = -speed; endif writePosition (s, pos); pause (pauseval); endwhile unwind_protect_cleanup clear a end_unwind_protect ����������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/isarduino.m���������������������������������������������������������������������0000644�0000000�0000000�00000002647�14777724260�013344� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} isarduino (@var{obj}) ## Check if input value is an arduino object ## ## Function is essentially just a call of ## @code { ## retval = isa(obj, "arduino"); ## } ## ## @subsubheading Inputs ## @var{obj} - The object to check ## ## @subsubheading Outputs ## @var{retval} is true, if obj is an arduino object, false otherwise. ## ## @seealso{arduino} ## @end deftypefn function retval = isarduino (obj) retval = false; if nargin > 0 && isa(obj, "arduino") retval = true; endif endfunction %!test %! a = arduino(); %! assert(isarduino(a), true) %!assert(isarduino(0), false) %!assert(isarduino({}), false) %!assert(isarduino([]), false) %!assert(isarduino(), false) �����������������������������������������������������������������������������������������arduino-0.12.2/inst/listArduinoLibraries.m����������������������������������������������������������0000644�0000000�0000000�00000005573�14777724260�015502� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} listArduinoLibraries () ## @deftypefnx {} {@var{retval} =} listArduinoLibraries (@var{libtypes}) ## Retrieve list of all known arduino library modules that are available. ## ## @subsubheading Inputs ## @var{libtypes} - optional specifier for type of libraries to list. ## ## Options are: ## @table @asis ## @item all ## List core and addons ## @item core ## List core only libraries ## @item addons ## List addons only ## @end table ## When no libtypes is specified, all libraries are shown. ## ## @subsubheading Outputs ## @var{retval} is an cell array of string library names that are ## available for programming to the arduino. ## ## @seealso{arduino, arduinosetup} ## @end deftypefn function retval = listArduinoLibraries (libtypes) retval = {}; if nargin == 0 libtypes = "all"; elseif ! ischar(libtypes) error ("Expected libtypes to be a string") endif if ! (strcmpi(libtypes, "all") || strcmpi(libtypes, "addons") || strcmpi(libtypes, "core")) error ("Invalid libtypes value '%s'", libtypes) endif # hardcoded libraries if strcmpi(libtypes, "all") || strcmpi(libtypes, "core") retval{end+1} = 'I2C'; retval{end+1} = 'Servo'; retval{end+1} = 'SPI'; retval{end+1} = 'ShiftRegister'; retval{end+1} = 'RotaryEncoder'; retval{end+1} = 'Ultrasonic'; retval{end+1} = 'Serial'; endif # add ons if strcmpi(libtypes, "all") || strcmpi(libtypes, "addons") addonfiles = __addons__ (); for i = 1:numel (addonfiles) retval{end+1} = addonfiles{i}.libraryname; endfor endif endfunction %!test %! libs = listArduinoLibraries (); %! assert (!isempty (libs)) %! assert (! isempty (find(strcmp(libs, 'SPI')))); %! assert (isempty (find(strcmp(libs, 'unknown')))); %!test %! deflibs = listArduinoLibraries (); %! alllibs = listArduinoLibraries ("all"); %! corelibs = listArduinoLibraries ("core"); %! addonlibs = listArduinoLibraries ("addons"); %! assert(numel(alllibs) == (numel(corelibs) + numel(addonlibs))) %! assert(numel(alllibs) == numel(deflibs)) %!error <Expected libtypes to be a string> listArduinoLibraries(1) %!error <Invalid libtypes value> listArduinoLibraries("invalid") �������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/private/������������������������������������������������������������������������0000755�0000000�0000000�00000000000�14777724260�012632� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/private/__addons__.m������������������������������������������������������������0000644�0000000�0000000�00000007401�14777724260�015056� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018-2022 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} __addons__ () ## Private function to get information aabout all user ## plugins ## @end deftypefn function addonfiles = __addons__ () addonfiles = {}; addonpathfix = fileparts (mfilename ('fullpath')); # how can we look for +arduinioaddons in the load path # genpath and dir_in_loadpath wont do it, so have to do it the hard way loadpaths = strsplit (path (), pathsep); addondirs = {}; for i = 1:numel (loadpaths) checkpath = fullfile (loadpaths{i}, "+arduinoioaddons"); if exist (checkpath, "dir") addondirs{end+1} = checkpath; endif endfor # we expect <+arduinoioaddons>/+AddonFolderName/<Addonname.m> for i=1:numel (addondirs) files = dir (addondirs{i}); for j = 1:numel (files) if files(j).isdir && files(j).name(1) != '.' searchname = fullfile (addondirs{i}, files(j).name, "*.m"); f1 = files (j).name; if f1(1) == "+" f1 = f1(2:end); endif files2 = dir (searchname); folder = fileparts(searchname); for k = 1:numel (files2) finfo = {}; [d2,f2,e2] = fileparts (files2(k).name); classname = sprintf ("arduinoioaddons.%s.%s", f1, f2); if is_arduino_addon_class(classname) z = eval(sprintf ("%s.AddonInfo('%s')", classname, classname)); z.scriptfile = fullfile (folder, files2(k).name); # set absolute filenames if not if !is_absolute_filename(z.cppheaderfile) z.cppheaderfile = fullfile(folder, z.cppheaderfile); endif if !is_absolute_filename(z.cppsourcefile) z.cppsourcefile = fullfile(folder, z.cppsourcefile); endif # paths are wrong in octave < 6.0 as mfilename isnt giving us a # correct path from within the class so for now, fixing here z.cppheaderfile = strrep (z.cppheaderfile, addonpathfix, folder); z.cppsourcefile = strrep (z.cppsourcefile, addonpathfix, folder); addonfiles{end+1} = z; endif endfor endif endfor endfor endfunction function retval = is_arduino_addon_class(classname) try classinfo = meta.class.fromName(classname); if !isempty(classinfo) # base class should have AddonInfo inhirected from arduinoio.LibraryBase idx = find( cellfun(@(x) strcmpi(x.Name, "AddonInfo"), classinfo.Methods), 1); if !isempty(idx) if size(classinfo.SuperClassList) > 0 idx = find( cellfun(@(x) strcmpi(x.Name, "arduinoio.LibraryBase"), classinfo.SuperClassList), 1); retval = !isempty(idx); if retval == false idx = cellfun(@(x) (is_arduino_addon_class(x.Name) == true), classinfo.SuperClassList); retval = !isempty(idx); endif else retval = false; endif else retval = false; endif else retval = false; endif catch retval = false; #warning ("addon: Ignoring %s", lasterror.message) end_try_catch endfunction ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/private/__arduino_binary__.m����������������������������������������������������0000644�0000000�0000000�00000011517�14777724260�016616� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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. see ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} __arduino__binary__ (}) ## @deftypefnx {} {@var{retval} =} __arduino__binary__ (@var{newpath}) ## Private function to set arduino path ## @seealso{arduinosetup} ## @end deftypefn function retval = __arduino_binary__ (newarduinopath) persistent arduino_binary = ""; if nargin == 0 if isempty(arduino_binary) arduino_binary = find_arduino_binary (); endif else % trying to set the path ? arduino_binary = newarduinopath; setpref('arduino', 'arduino_binary', arduino_binary); endif retval = arduino_binary; endfunction function arduino_binary = find_arduino_binary () # use arduino_debug.exe in windoze ? binary_name = {"arduino", "arduino-ide"}; arduino_binary = ""; have_prefs = false; binary = getpref("arduino", "arduino_binary", ""); if !isempty(binary) have_prefs = true; t = file_in_path (getenv ("PATH"), binary); if !isempty(t) arduino_binary = t; endif endif if (isunix ()) binaries = {}' for idx=1:numel(binary_name) binaries{end+1} = binary_name{idx}; binaries{end+1} = strcat (binary_name{idx}, ".exe"); endfor else binaries = {}' for idx=1:numel(binary_name) binaries{end+1} = strcat (binary_name{idx}, ".exe"); endfor endif # do we have a ARDUINO_HOME ? if isempty (arduino_binary) if isenv("ARDUINO_HOME") n=0; while (n < numel (binaries) && isempty (arduino_binary)) arduino_binary = file_in_path (getenv ("ARDUINO_HOME"), binaries{++n}); endwhile endif endif # can we find in path n = 0; while (n < numel (binaries) && isempty (arduino_binary)) arduino_binary = file_in_path (getenv ("PATH"), binaries{++n}); endwhile % if a pc, and have the winqueryreg function, try find the path if isempty(arduino_binary) && ispc () if exist('winqueryreg') == 5 try arduino_binary = winqueryreg("HKLM", 'SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\arduino.exe'); end_try_catch if isempty(arduino_binary) # try win32 registry try arduino_binary = fullfile(winqueryreg("HKLM", 'SOFTWARE\WOW6432Node\Arduino', 'install_dir'), 'arduino.exe'); end_try_catch endif endif if isempty(arduino_binary) trypath = "C:\\Program Files (x86)\\Arduino\\arduino.exe"; if exist (trypath, "file") arduino_binary = trypath; endif endif if isempty(arduino_binary) trypath = fullfile (getenv ("LOCALAPPDATA"), "Programs", "Arduino IDE", "Arduino IDE.exe"); if exist (trypath, "file") arduino_binary = trypath; endif endif if isempty(arduino_binary) trypath = fullfile (getenv ("PROGRAMFILES"), "Arduino IDE", "Arduino IDE.exe"); if exist (trypath, "file") arduino_binary = trypath; endif endif endif % look for arduino prefs file if isempty (arduino_binary) if ispc () prefsfile = fullfile (getenv ("LOCALAPPDATA"), "Arduino15", "preferences.txt"); else prefsfile = fullfile (getenv ("HOME"), ".arduino15", "preferences.txt"); endif fd = fopen (prefsfile, "rt"); if fd != -1 try trypaths = {}; while ! feof (fd) l = fgetl (fd); str = regexp (l, "last\.ide\.(?<version>\\d.*)\.hardwarepath=(?<path>.*)$", "names"); if ! isempty (str) trypaths{end+1} = str; endif endwhile if !isempty (trypaths) % sort so will try newest ver first [~, sortidx] = sort(arrayfun( @(x) x{1}.version, trypaths, 'uniformoutput', false), 'descend'); for idx = 1:length(sortidx) if isempty (arduino_binary) [trypath,~,~] = fileparts (trypaths{idx}.path); n = 0; while (n < numel (binaries) && isempty (arduino_binary)) arduino_binary = file_in_path (trypath, binaries{++n}); endwhile endif endfor endif end_try_catch fclose (fd); endif endif if isempty(arduino_binary) error ("__arduino_binary__: can not find the arduino binary"); elseif !have_prefs setpref('arduino', 'arduino_binary', arduino_binary); endif endfunction ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/private/__arduino_serialportlist__.m��������������������������������������������0000644�0000000�0000000�00000005356�14777724260�020416� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# get a possible port list for the arduino function list = __arduino_serialportlist__(debug_flag=0) ports = serialportlist (); if ismac() list = {}; for i = 1:numel(ports) port_lower = lower(ports{i}); # Skip Bluetooth ports and other unlikely ports if strfind(port_lower, "bluetooth") || ... strfind(port_lower, "airpods") || ... strfind(port_lower, "phone") || ... strfind(port_lower, "console") || ... strfind(port_lower, "debug") || ... strfind(port_lower, "irda") || ... strfind(port_lower, "virtual") if debug_flag printf("* skipping unlikely port: %s\n", ports{i}); endif else list{end+1} = ports{i}; endif endfor elseif isunix() && !ispc() list = port_sort(ports, @unix_port_compare); elseif !isunix() && ispc() list = port_sort(ports, @win32_port_compare); else list = ports; endif endfunction function res = c_strcmp(s1, s2) res = 0; l1 = length(s1); l2 = length(s2); l = min(l1, l2); if l == 0 res = l1 - l2; else idx = find(s1(1:l) != s2(1:l), 1); if isempty(idx) res = l1 - l2; else res = s1(idx) - s2(idx); endif endif endfunction function res = unix_port_compare(s1, s2) # we want to priortise non /dev/ttySXXX ports s1_p = strncmp(s1, "/dev/ttyS", 9); s2_p = strncmp(s2, "/dev/ttyS", 9); if s1_p && !s2_p res = 1; elseif !s1_p && s2_p res = -1; elseif s1_p && s2_p # sort numerically s1_p = sscanf(s1, "/dev/ttyS%d"); s2_p = sscanf(s2, "/dev/ttyS%d"); res = s1_p - s2_p; else res = c_strcmp(s1, s2); endif endfunction function res = win32_port_compare(s1, s2) # we want to priortise comports - assuming # that comports more likely to arduinos # will be towards end of the list s1_p = strncmp(s1, "COM", 3); s2_p = strncmp(s2, "COM", 3); if s1_p && s2_p # sort numerically s1_p = sscanf(s1, "COM%d"); s2_p = sscanf(s2, "COM%d"); # reverse order res = s2_p - s1_p; else res = c_strcmp(s2, s1); endif endfunction function slist = port_sort(ulist, sort_method=@c_strcmp) # crappy bubble sort for now sorted = false; max_try = length(ulist) * length(ulist); while sorted == false && max_try > 0 sorted = true; for idx=1:length(ulist)-1 cmp = sort_method(ulist{idx}, ulist{idx+1}); #printf(" '%s' '%s' %d\n", ulist{idx}, ulist{idx+1}, cmp); #cmp = all(ulist{idx} < ulist{idx+1}) if cmp > 0 t = ulist{idx}; ulist{idx} = ulist{idx+1}; ulist{idx+1} = t; sorted = false; endif # fail safe in case we get given some function that means we can never sort max_try = max_try - 1; endfor endwhile slist = ulist; endfunction ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/scanForArduinos.m���������������������������������������������������������������0000644�0000000�0000000�00000014016�14777724260�014440� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018-2025 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} scanForArduinos () ## @deftypefnx {} {@var{retval} =} scanForArduinos (@var{maxCount}) ## @deftypefnx {} {@var{retval} =} scanForArduinos (@var{"debug"}) ## @deftypefnx {} {@var{retval} =} scanForArduinos (@var{maxCount}, @var{type}) ## @deftypefnx {} {@var{retval} =} scanForArduinos (@var{propertyname}, @var{propertvalue} ...) ## Scan system for programmed serial connected arduino boards. ## ## scanForArduinos will scan the system for programmed arduino boards ## and return at most @var{maxCount} of them as a cell array ## in @var{retval}. ## ## @subsubheading Inputs ## @var{maxCount} - max number of arduino boards to detect. ## if @var{maxCount} is not specified, or is a less than 1, the ## function will return as many arduino boards as it can detect. ## ## @var{type} - optional board type to match. If specified, the board ## type must match for the arduino to be added to the return list. ## ## @var{"debug"} - if single input parameter is "debug", the ## scanForArduinos will display debug information as it scans ## all available ports for arduinos. ## ## @var{propertyname}, @var{propertyvalue} - property name/value pairs to match search with. ## @table @asis ## @item 'BaudRate' ## Numeric BaudRate to use when trying to scan for arduinos. ## @item 'MaxCount' ## Max number of arduinos to scan for. ## @item 'BoardType' ## Boardtype to match. ## @item 'Debug' ## Logical flag for debug mode. ## @end table ## ## @subsubheading Outputs ## @var{retval} structure cell array of matching detected arduino boards. ## ## Each cell value of the cell array will contain a structure with values of: ## @table @asis ## @item port ## the serial port the arduino is connected to ## @item board ## the board type of the arduino ## @end table ## ## @seealso{arduino} ## @end deftypefn function arduinos = scanForArduinos (varargin) # maxCount, typestr arduinos = {}; debug_flag = false; maxCount = 0; typestr = ""; baudrate = []; if nargin == 1 typestr = ""; if ischar(varargin{1}) if strcmp(varargin{1}, "debug") debug_flag = 1; else error ("scanForArduinos: invalid argument"); endif elseif isnumeric(varargin{1}) maxCount = int32(varargin{1}); else error ("scanForArduinos: invalid argument"); endif elseif nargin == 2 && isnumeric(varargin{1}) && ischar(varargin{2}) # maxCount and boardtype maxCount = int32(varargin{1}); typestr = varargin{2}; elseif nargin >= 2 # properties if mod (nargin, 2) != 0 error ("scanForArduins: expected property name, value pairs"); endif if !iscellstr (varargin (1:2:nargin)) error ("scanForArduinos: expected property names to be strings"); endif for i = 1:2:nargin propname = tolower (varargin{i}); propvalue = varargin{i+1}; if strcmp (propname,"debug") if propvalue debug_flag = 1; else debug_flag = 0; endif endif if strcmp (propname,"boardtype") boardstr = propvalue; endif if strcmp (propname,"baudrate") baudrate = propvalue; endif if strcmp (propname,"maxcount") maxCount = propvalue; endif endfor endif if ! isnumeric (maxCount) || maxCount < 0 error ("scanForArduinos expected maxCount to be a number"); endif if ! ischar (typestr) && !isempty (typestr) error ("scanForArduinos expected typestr to be a board type"); elseif ischar (typestr) typestr = tolower (typestr); else typestr = ""; endif if isempty(baudrate) baudrate = 9600; if !isempty(typestr) # get default baudrate for baud try c = arduinoio.getBoardConfig(typestr); baudrate = c.baudrate; catch err error ("scanForArduinos: unknown board type"); end_try_catch endif endif if ! isnumeric (baudrate) || baudrate < 1200 error ("scanForArduinos expected baudrate to be a number >= 1200"); endif # get list of serial ports to try ports = __arduino_serialportlist__ (debug_flag); for i = 1:numel (ports) try s = {}; unwind_protect portname = ports{i}; if debug_flag printf("* trying comport %s\n", portname); endif s = arduino(portname, "", "Debug", debug_flag, "BaudRate", baudrate, "_scan_only", 1); if isempty (typestr) || strcmpi(s.board, typestr) info = {}; info.port = portname; info.board = s.board; arduinos{end+1} = info; if debug_flag printf(" ** found board %s\n", info.board); endif if numel (arduinos) == maxCount break; endif endif unwind_protect_cleanup if !isempty (s) delete(s); endif end_unwind_protect catch err % do nothing if debug_flag printf(" ** %s\n", err.message); endif end_try_catch endfor endfunction %!test %! # assuming that to test, we have at least one board available %! arduinos = scanForArduinos(1); %! assert(numel(arduinos), 1); %! assert(!isempty(arduinos{1}.port)) %! assert(!isempty(arduinos{1}.board)) %!test %! a = scanForArduinos("BaudRate", 115200, "BoardType", "Uno"); %!error <scanForArduinos: unknown board type> scanForArduinos(1, "madeuparduinoname"); ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/scanI2Cbus.m��������������������������������������������������������������������0000644�0000000�0000000�00000004321�14777724260�013272� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018-2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} scanI2Cbus (@var{ar}) ## @deftypefnx {} {@var{retval} =} scanI2Cbus (@var{ar}, @var{bus}) ## Scan arduino for devices on the I2C bus. ## ## @subsubheading Inputs ## @var{ar} - arduino object connected to a arduino board. ## ## @var{bus} - bus number to scan I2C devices, when multiple buses are available. ## If the bus is not specified, it will default to 0. ## ## @subsubheading Outputs ## @var{retval} - cell array of addresses as strings in format of "0xXX". ## ## @subsubheading Example ## @example ## @code { ## # create arduino connection. ## ar = arduino(); ## # scan for devices on the I2C bus ## scanI2Cbus (ar) ## # output is each detected i2c address as a string ## ans = ## @{ ## [1,1] = 0x50 ## @} ## } ## @end example ## ## @seealso{arduino, i2cdev, checkI2CAddress} ## @end deftypefn function addr = scanI2Cbus (ar, bus) addr = {}; if nargin < 1 || nargin > 2 print_usage (); endif if nargin == 1 bus = 0; elseif !isnumeric (bus) || bus < 0 || bus > 1 error ('scanI2Cbus: expected bus to be numeric and 0 or 1'); endif if (!isa (ar, "arduino")) error ("scanI2Cbus: expects arduino object as 1st argument"); endif # TODO: configure SPI pins if not already done?? # scan each address, and add any found to cell array for i = 3:126 if checkI2CAddress (ar, i, bus) addr{end+1} = [ "0x" dec2hex(i, 2) ]; endif endfor endfunction %!test %! ar = arduino(); %! assert(!isempty(ar)); %! scanI2Cbus(ar); ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/sensors/������������������������������������������������������������������������0000755�0000000�0000000�00000000000�14777724260�012654� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/sensors/bme280.m����������������������������������������������������������������0000644�0000000�0000000�00000036660�14777724260�014042� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> ## ## Conversion routines based on code from the BME280 datasheet ## revision 1.6, Document number BST-BME280-DS002-15. ## ## 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 ## <https://www.gnu.org/licenses/>. classdef bme280 < handle ## -*- texinfo -*- ## @deftypefn {} {} bme280 ## BME280 pressure, temperature and humidity sensor ## @end deftypefn ## ## @subheading Methods ## @deftypefn {} {@var{obj} =} bme280(@var{arObj}) ## @deftypefnx {} {@var{obj} =} bme280(@var{arObj}, @var{propertyname, propertyvalue} ....) ## Constructor to create BME280 sensor ## @subsubheading Inputs ## @var{arObj} - the arduino parent object ## ## @var{propertyname, propertyvalue} - optional property name, value pairs. ## Current known properties are: ## Current properties are: ## @table @asis ## @item I2CAddress ## I2C address of the sensor (default 0x40) ## @item Bus ## I2C bus - 0 or 1 (default 0) ## @end table ## ## @subsubheading Outputs ## @var{obj} - created object ## ## @subsubheading Example ## @example ## @code { ## a = arduino() ## sensor = bme280(a) ## } ## @end example ## @end deftypefn ## ## @deftypefn {} {[@var{C}, @var{timestamp}] =} readTemperature(@var{obj}) ## Read the temperature ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## @var{C} - read temperature in deg C. ## ## @var{timestamp} - timestamp when read ## ## @subsubheading Example ## @example ## @code { ## a = arduino() ## s = bme280(a) ## # get temp ## temp = s.readTemperature ## } ## @end example ## @seealso{bme280} ## @end deftypefn ## ## @deftypefn {} {[@var{relH}, @var{timestamp}] =} readHumidity(@var{obj}) ## Read the relative humidity ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## @var{relH} - relative humidity as a percentage (0 - 100.0) ## ## @var{timestamp} - timestamp when read ## @end deftypefn ## ## @deftypefn {} {[@var{P}, @var{timestamp}] =} readPressure(@var{obj}) ## Read the pressure ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## @var{P} - pressure reading from sensor. ## ## @var{timestamp} - timestamp when read ## @end deftypefn ## ## @deftypefn {} {[@var{readings}, @var{overrun}] =} read(@var{obj}) ## @deftypefnx {} {[@var{P}, @var{H}, @var{C}, @var{timestamp}, @var{overrun}] =} read(@var{obj}) ## Read the sensor data ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## @var{P} - pressure reading from sensor. ## ## @var{H} - humidity reading from sensor. ## ## @var{C} - temperature reading from sensor. ## ## @var{timestamp} - timestamp when read ## ## @var{overrun} - overrun flag. ## ## @var{readings} - table structure with fields for Timestamp, Pressure, Temperature and Humidity. ## @end deftypefn ## ## @deftypefn {} {@var{inf} =} info(@var{obj}) ## Read the sensor info ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## @var{inf} - structure containing the sensor information. ## ## Structure fields are: ## @table @asis ## @item Version ## Chip firmware version ## @item SensorId ## sensor id value ## @item Type ## sensor type 'bme280' ## @item Status ## Status value read from sensor ## @end table ## ## @end deftypefn ## ## @deftypefn {} {} flush(@var{obj}) ## Flush sensor data ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## None ## @end deftypefn ## ## @deftypefn {} {} release(@var{obj}) ## Release the resources of the sensor ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## None ## @end deftypefn properties(Access = private, constant = true) BME280_REG_DIG_T1 = 0x88; BME280_REG_DIG_T2 = 0x8A; BME280_REG_DIG_T3 = 0x8C; BME280_REG_DIG_P1 = 0x8E; BME280_REG_DIG_P2 = 0x90; BME280_REG_DIG_P3 = 0x92; BME280_REG_DIG_P4 = 0x94; BME280_REG_DIG_P5 = 0x96; BME280_REG_DIG_P6 = 0x98; BME280_REG_DIG_P7 = 0x9A; BME280_REG_DIG_P8 = 0x9C; BME280_REG_DIG_P9 = 0x9E; BME280_REG_DIG_H1 = 0xA1; BME280_REG_DIG_H2 = 0xE1; BME280_REG_DIG_H3 = 0xE3; BME280_REG_DIG_H4 = 0xE4; BME280_REG_DIG_H5 = 0xE5; BME280_REG_DIG_H6 = 0xE7; BME280_REG_CHIPID = 0xD0; BME280_REG_VERSION = 0xD1; BME280_REG_SOFTRESET = 0xE0; BME280_REG_CAL26 = 0xE1; BME280_REG_CONTROLHUMID = 0xF2; BME280_REG_STATUS = 0XF3; BME280_REG_CONTROL = 0xF4; BME280_REG_CONFIG = 0xF5; BME280_REG_PRESSUREDATA = 0xF7; BME280_REG_TEMPDATA = 0xFA; BME280_REG_HUMIDDATA = 0xF; BME280_REG_DATA = 0xF7; endproperties properties(Access = private) i2c; caldata = {}; endproperties # matlab compatible properties properties (SetAccess = private) I2CAddress = ""; Bus = 0; endproperties methods # constructor function this = bme280(parentObj, varargin) if nargin < 1 || ! isarduino(parentObj) error('Expected arduino object as first parameter'); endif # parse args p = inputParser(CaseSensitive=false, FunctionName='arduinosensor.SI7021'); p.addParameter('I2CAddress', 0x77, @isnumeric); p.addParameter('Bus', 0, @isnumeric); p.parse(varargin{:}); # do we have the address ? address = p.Results.I2CAddress; bus = p.Results.Bus; #i2caddresses = scanI2Cbus(parentObj, bus); #idx = find(cellfun ( @(x) strcmp(x, sprintf("0x%02X", address)), i2caddresses)); #if isempty(idx) # error('No matching i2c address found on bus'); #endif this.i2c = device(parentObj, "i2caddress", p.Results.I2CAddress, 'Bus', bus); # init id = this.readRegisterU8(this.BME280_REG_CHIPID); if id < hex2dec("56") || id > hex2dec("60") error ("Invalid id '%X' read for sensor", id) endif # wait while chip is reading status = 1; while bitand(status, 1) == 1 pause(.1); status = this.readRegisterU8(this.BME280_REG_STATUS); endwhile this.caldata.t_fine = []; this.caldata.T1 = this.readRegisterU16(this.BME280_REG_DIG_T1); this.caldata.T2 = this.readRegisterS16(this.BME280_REG_DIG_T2); this.caldata.T3 = this.readRegisterS16(this.BME280_REG_DIG_T3); this.caldata.P1 = this.readRegisterU16(this.BME280_REG_DIG_P1); this.caldata.P2 = this.readRegisterS16(this.BME280_REG_DIG_P2); this.caldata.P3 = this.readRegisterS16(this.BME280_REG_DIG_P3); this.caldata.P4 = this.readRegisterS16(this.BME280_REG_DIG_P4); this.caldata.P5 = this.readRegisterS16(this.BME280_REG_DIG_P5); this.caldata.P6 = this.readRegisterS16(this.BME280_REG_DIG_P6); this.caldata.P7 = this.readRegisterS16(this.BME280_REG_DIG_P7); this.caldata.P8 = this.readRegisterS16(this.BME280_REG_DIG_P8); this.caldata.P9 = this.readRegisterS16(this.BME280_REG_DIG_P9); this.caldata.H1 = this.readRegisterU8(this.BME280_REG_DIG_H1); this.caldata.H2 = this.readRegisterU16(this.BME280_REG_DIG_H2); this.caldata.H3 = this.readRegisterU8(this.BME280_REG_DIG_H3); a = this.readRegisterU8(this.BME280_REG_DIG_H4); b = this.readRegisterU8(this.BME280_REG_DIG_H4+1); this.caldata.H4 = uint16(a)*16 + bitand(uint16(b), uint16(0x0f)); a = this.readRegisterU8(this.BME280_REG_DIG_H5); b = this.readRegisterU8(this.BME280_REG_DIG_H5+1); this.caldata.H5 = uint16(b*16) + bitshift(uint16(a), -4); this.caldata.H6 = this.readRegisterS8(this.BME280_REG_DIG_H6); # ensure in sleep mode this.writeRegister(this.BME280_REG_CONTROL, uint8([0])); # start sensors # sample rate 1 this.writeRegister(this.BME280_REG_CONTROLHUMID, uint8([0x01])); this.writeRegister(this.BME280_REG_CONFIG, uint8([0xE1])); # 101 101 11 this.writeRegister(this.BME280_REG_CONTROL, uint8([0xB7])); endfunction function inf = info (this) inf = {}; inf.Type = "bme280"; inf.SensorId = this.readRegisterU8(this.BME280_REG_CHIPID); inf.Version = this.readRegisterU8(this.BME280_REG_VERSION); inf.Status = this.readRegisterU8(this.BME280_REG_STATUS); endfunction function [C, timestamp] = readTemperature (this) data = readData(this); value = bitshift(int32(data(4)), 12) + bitshift(int32(data(5)), 4) + bitshift(int32(data(6)), -4); timestamp = time(); C = calcTemperature(this, value); endfunction function [H, timestamp] = readHumidity(this) data = readData(this); if isempty(this.caldata.t_fine) value = bitshift(int32(data(4)), 12) + bitshift(int32(data(5)), 4) + bitshift(int32(data(6)), -4); calcTemperature(this, value); endif value = bitshift(int32(data(7)), 8) + int32(data(8)); timestamp = time(); H = calcHumidity(this, value); endfunction function [P, timestamp] = readPressure(this) data = readData(this); if isempty(this.caldata.t_fine) value = bitshift(int32(data(4)), 12) + bitshift(int32(data(5)), 4) + bitshift(int32(data(6)), -4); calcTemperature(this, value); endif value = bitshift(int32(data(1)), 12) + bitshift(int32(data(2)), 4) + bitshift(int32(data(3)), -4); timestamp = time(); P = calcPressure(this, value); endfunction function varargout = read(this) data = readData(this); timestamp = time(); value = bitshift(int32(data(4)), 12) + bitshift(int32(data(5)), 4) + bitshift(int32(data(6)), -4); C = calcTemperature(this, value); value = bitshift(int32(data(7)), 8) + int32(data(8)); H = calcHumidity(this, value); value = bitshift(int32(data(1)), 12) + bitshift(int32(data(2)), 4) + bitshift(int32(data(3)), -4); P = calcPressure(this, value); if nargout <= 2 varargout{1} = struct('Time', timestamp, 'Temperature', C, 'Pressure', P, 'Humidity', H); if nargout > 1 varargout{2} = 0; # no overrun endif else if nargout > 0 varargout{1} = P; endif if nargout > 1 varargout{2} = H; endif if nargout > 2 varargout{3} = C; endif if nargout > 3 varargout{4} = timestamp; endif if nargout > 4 varargout{5} = 0; # overrun endif endif endfunction function flush(this) # flush currenly does nothing endfunction function disp(this) printf(" %s with properties\n", class(this)); if isobject(this.i2c) printf(" I2CAddress: %d ('0x%s')\n", this.i2c.i2caddress, num2hex(this.i2c.i2caddress)); printf(" Bus: %d\n", this.i2c.bus); else printf(" Not connected"); endif endfunction function release(this) if isobject(this.i2c) delete(this.i2c); this.i2c = []; endif endfunction function delete(this) try if isobject(this.i2c) delete(this.i2c); this.i2c = []; endif catch # do nothing end_try_catch endfunction endmethods methods (Hidden = true) function v = get.I2CAddress (this) v = sprintf("0x%02X", this.i2c.I2CAddress); endfunction function v = get.Bus (this) v = this.i2c.Bus; endfunction endmethods methods (Access = private) function C = calcTemperature(this, value) var1 = bitshift((bitshift(int32(value), -3) - bitshift(int32(this.caldata.T1), 1)) * int32(this.caldata.T2), -11); var2 = (bitshift(int32(value), -4) - int32(this.caldata.T1)); var2 = bitshift( (bitshift(var2*var2, -12) * int32(this.caldata.T3)), -14); this.caldata.t_fine = var1 + var2; T = bitshift(this.caldata.t_fine * 5 + 128, -8); C = single(T)/100.0; endfunction function H = calcHumidity(this, value) var1 = int32(this.caldata.t_fine) - 76800; a = bitshift(value, 14) - bitshift(int32(this.caldata.H4), 20) - (int32(this.caldata.H5) * var1); a = bitshift(a + 16384, -15); b = bitshift(var1 * int32(this.caldata.H6), -10) * (bitshift(var1 * int32(this.caldata.H3), -11) + 32768); b = bitshift(b, -10) + 2097152 * int32(this.caldata.H2) + 8192; b = bitshift(b, -14); var1 = a * b; a = bitshift(bitshift(var1, -15) * bitshift(var1, -15), -7); var1 = var1 - bitshift(a * int32(this.caldata.H1), -4); if var1 < 0 var1 = 0; elseif var1 > 419430400 var1 = 419430400; endif H = single(bitshift(var1, -12)) / 1024.0; endfunction function P = calcPressure(this, value) var1 = int64(this.caldata.t_fine) - 128000; var2 = var1 * var1 * int64(this.caldata.P6); var2 = int64(var2) + bitshift(var1 * int64(this.caldata.P5), 17); var2 = var2 + bitshift(int64(this.caldata.P4), 35); var1 = bitshift(var1 * var1 * int64(this.caldata.P3), -8) + bitshift(var1 * int64(this.caldata.P2), 12); var1 = bitshift((bitshift(int64(1), 47) +var1) * int64(this.caldata.P1), -33); if (var1 != 0) P = 1048576 - value; P = ((bitshift(int64(P), 31) - var2)*3125)/var1; var1 = bitshift(int64(this.caldata.P9) * bitshift(P, -13) * bitshift(P, -13), -25); var2 = bitshift(int64(this.caldata.P8) * P, -19); P = bitshift(P + var1 + var2, -8) + bitshift(int64(this.caldata.P7), 4); else P = 0; endif P = single(P) / 256.0; endfunction function data = readRegister(this, reg, sz) data = readRegister(this.i2c, reg, sz); endfunction function writeRegister(this, reg, data) writeRegister(this.i2c, reg, data); endfunction # read the data function data = readData(this) m = 1; while m == 1 status = this.readRegisterU8 (this.BME280_REG_STATUS); m = bitand(bitshift(status, -3), 1); if m == 1 pause(.1); endif endwhile data = readRegister(this, this.BME280_REG_DATA, 8); endfunction function value = readRegisterU16(this, reg) data = readRegister(this, reg, 2); value = uint16(data(2))*256 + uint16(data(1)); endfunction function value = readRegisterS16(this, reg) data = readRegister(this, reg, 2); value = uint16(data(2))*256 + uint16(data(1)); value = typecast(value, 'int16'); endfunction function value = readRegisterU8(this, reg) data = readRegister(this, reg, 1); value = uint8(data(1)); endfunction function value = readRegisterS8(this, reg) data = readRegister(this, reg, 1); value = uint8(data(1)); value = typecast(value, 'int8'); endfunction endmethods endclassdef %!error <Expected arduino object as first parameter> bme280(1); ��������������������������������������������������������������������������������arduino-0.12.2/inst/sensors/bno055.m����������������������������������������������������������������0000644�0000000�0000000�00000055000�14777724260�014042� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. classdef bno055 < handle ## -*- texinfo -*- ## @deftypefn {} {} bno055 ## BNO055 9 axis orientation sensor ## @end deftypefn ## ## @subheading Methods ## @deftypefn {} {@var{obj} =} bno055(@var{arObj}) ## @deftypefnx {} {@var{obj} =} bno055(@var{arObj}, @var{propertyname, propertyvalue} ....) ## Constructor to create BME280 sensor ## @subsubheading Inputs ## @var{arObj} - the arduino parent object ## ## @var{propertyname, propertyvalue} - optional property name, value pairs. ## Current known properties are: ## Current properties are: ## @table @asis ## @item I2CAddress ## I2C address of the sensor (default 0x40) ## @item Bus ## I2C bus - 0 or 1 (default 0) ## @item OperatingMode ## Operating mode 'ndof' or 'amg' ## @end table ## ## @subsubheading Outputs ## @var{obj} - created object ## ## @subsubheading Example ## @example ## @code { ## a = arduino() ## sensor = bno055(a) ## } ## @end example ## @end deftypefn ## ## @deftypefn {} {[@var{C}, @var{timestamp}] =} readTemperature(@var{obj}) ## Read the temperature ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## @var{C} - read temperature in deg C. ## ## @var{timestamp} - timestamp when read ## ## @subsubheading Example ## @example ## @code { ## a = arduino() ## s = bno055(a) ## # get temp ## temp = s.readTemperature ## } ## @end example ## @seealso{bno055} ## @end deftypefn ## ## @deftypefn {} {[@var{readVal}, @var{timestamp}] =} readAcceleration(@var{obj}) ## Read the acceleration rate ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## @var{readVal} - the 3 acceleration values ## ## @var{timestamp} - timestamp when read ## @end deftypefn ## ## @deftypefn {} {[@var{readVal}, @var{timestamp}] =} readAngularVelocity(@var{obj}) ## Read the angular velocity ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## @var{readVal} - the 3 angular velocity values ## ## @var{timestamp} - timestamp when read ## @end deftypefn ## ## @deftypefn {} {[@var{readVal}, @var{timestamp}] =} readMagneticField(@var{obj}) ## Read the magnetic field components ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## @var{readVal} - the 3 magnetic field values ## ## @var{timestamp} - timestamp when read ## @end deftypefn ## ## @deftypefn {} {[@var{readVal}, @var{timestamp}] =} readOrientation(@var{obj}) ## Read the oriientation components ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## @var{readVal} - the 3 orientation values ## ## @var{timestamp} - timestamp when read ## @end deftypefn ## ## @deftypefn {} {[@var{readings}, @var{overrun}] =} read(@var{obj}) ## @deftypefnx {} {[@var{accel}, @var{gyro}, @var{mag}, @var{timestamp}, @var{overrun}] =} read(@var{obj}) ## @deftypefnx {} {[@var{accel}, @var{gyro}, @var{mag}, @var{orientation}, @var{timestamp}, @var{overrun}] =} read(@var{obj}) ## Read the sensor data ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## @var{accel} - acceleration reading from sensor. ## ## @var{gyro} - angular acceleration reading from sensor. ## ## @var{mag} - magnetic field reading from sensor. ## ## @var{orientation} - orientation reading from sensor. ## ## @var{timestamp} - timestamp when read ## ## @var{overrun} - overrun flag. ## ## @var{readings} - table structure with fields for Timestamp, Acceleration, AngularVelocity, MagneticField, Orientation. ## @end deftypefn ## ## @deftypefn {} {@var{inf} =} readCalibrationStatus(@var{obj}) ## Read the sensor calibration status ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## @var{status} - structure containing the calibration information. ## ## Structure fields are: ## @table @asis ## @item System ## System calibrarion ## @item Accelerometer ## Accelerometer calibration status ## @item Gyroscope ## Gyroscope calibration status ## @item Magnetometer ## Magnetometer calibration status ## @end table ## ## Values for each will be either 'uncalibrated', 'partial' or 'full'. ## ## @end deftypefn ## ## @deftypefn {} {@var{inf} =} info(@var{obj}) ## Read the sensor info ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## @var{inf} - structure containing the sensor information. ## ## Structure fields are: ## @table @asis ## @item Version ## Software firmware version ## @item SensorId ## sensor id value ## @item Type ## sensor type 'bno055' ## @end table ## ## @end deftypefn ## ## @deftypefn {} {} flush(@var{obj}) ## Flush sensor data ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## None ## @end deftypefn ## ## @deftypefn {} {} release(@var{obj}) ## Release the resources of the sensor ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## None ## @end deftypefn properties(Access = private, constant = true) # page 0 BNO055_REG_CHIP_ID = 0x00; # 0xA0 BNO055 CHIP ID BNO055_REG_ACC_ID = 0x01; # 0xFB ACC chip ID BNO055_REG_MAG_ID = 0x02; # 0x32 MAG chip ID BNO055_REG_GYR_ID = 0x03; # 0x0F GYRO chip ID BNO055_REG_SW_REV_ID = 0x04; BNO055_REG_SW_REV_ID_L = 0x04; # SB 0x118 SW Revision ID <7:0> BNO055_REG_SW_REV_ID_M = 0x05; # SB 0x037 SW Revision ID <15:8> BNO055_REG_BL_REV_ID = 0x06; # 0x15 Bootloader Version BNO055_REG_PAGE_ID = 0x07; # 0x00 Page ID BNO055_REG_ACC_DATA_X = 0x08; BNO055_REG_ACC_DATA_X_LSB = 0x08; # 0x00 Acceleration Data X <7:0> BNO055_REG_ACC_DATA_X_MSB = 0x09; # 0x00 Acceleration Data X <15:8> BNO055_REG_ACC_DATA_Y = 0x0A; BNO055_REG_ACC_DATA_Y_LSB = 0x0A; # 0x00 Acceleration Data Y <7:0> BNO055_REG_ACC_DATA_Y_MSB = 0x0B; # 0x00 Acceleration Data Y <15:8> BNO055_REG_ACC_DATA_Z = 0x0C; BNO055_REG_ACC_DATA_Z_LSB = 0x0C; # 0x00 Acceleration Data Z <7:0> BNO055_REG_ACC_DATA_Z_MSB = 0x0D; # 0x00 Acceleration Data Z <15:8> BNO055_REG_MAG_DATA_X = 0x0E; BNO055_REG_MAG_DATA_X_LSB = 0x0E; # 0x00 Magnetometer Data X <7:0> BNO055_REG_MAG_DATA_X_MSB = 0x0F; # 0x00 Magnetometer Data X <15:8> BNO055_REG_MAG_DATA_Y = 0x10; BNO055_REG_MAG_DATA_Y_LSB = 0x10; # 0x00 Magnetometer Data Y <7:0> BNO055_REG_MAG_DATA_Y_MSB = 0x11; # 0x00 Magnetometer Data Y <15:8> BNO055_REG_MAG_DATA_Z = 0x12; BNO055_REG_MAG_DATA_Z_LSB = 0x12; # 0x00 Magnetometer Data Z <7:0> BNO055_REG_MAG_DATA_Z_MSB = 0x13; # 0x00 Magnetometer Data Z <15:8> BNO055_REG_GYR_DATA_X = 0x14; BNO055_REG_GYR_DATA_X_LSB = 0x14; # 0x00 Gyroscope Data X <7:0> BNO055_REG_GYR_DATA_X_MSB = 0x15; # 0x00 Gyroscope Data X <15:8> BNO055_REG_GYR_DATA_Y = 0x16; BNO055_REG_GYR_DATA_Y_LSB = 0x16; # 0x00 Gyroscope Data Y <7:0> BNO055_REG_GYR_DATA_Y_MSB = 0x17; # 0x00 Gyroscope Data Y <15:8> BNO055_REG_GYR_DATA_Z = 0x18; BNO055_REG_GYR_DATA_Z_LSB = 0x18; # 0x00 Gyroscope Data Z <7:0> BNO055_REG_GYR_DATA_Z_MSB = 0x19; # 0x00 Gyroscope Data Z <15:8> BNO055_REG_EUL_HEADING = 0x1A; BNO055_REG_EUL_HEADING_LSB = 0x1A; # 0x00 Heading Data <7:0> BNO055_REG_EUL_HEADING_MSB = 0x1B; # 0x00 Heading Data <15:8> BNO055_REG_EUL_ROLL = 0x1C; BNO055_REG_EUL_ROLL_LSB = 0x1C; # 0x00 Roll Data <7:0> BNO055_REG_EUL_ROLL_MSB = 0x1D; # 0x00 Roll Data <15:8> BNO055_REG_EUL_PITCH = 0x1E; BNO055_REG_EUL_PITCH_LSB = 0x1E; # 0x00 Pitch Data <7:0> BNO055_REG_EUL_PITCH_MSB = 0x1F; # 0x00 Pitch Data <15:8> BNO055_REG_QUA_DATA_W = 0x20; BNO055_REG_QUA_DATA_W_LSB = 0x20; # 0x00 Quaternion w Data <7:0> BNO055_REG_QUA_DATA_W_MSB = 0x21; # 0x00 Quaternion w Data <15:8> BNO055_REG_QUA_DATA_X = 0x22; BNO055_REG_QUA_DATA_X_LSB = 0x22; # 0x00 Quaternion x Data <7:0> BNO055_REG_QUA_DATA_X_MSB = 0x23; # 0x00 Quaternion x Data <15:8> BNO055_REG_QUA_DATA_Y = 0x24; BNO055_REG_QUA_DATA_Y_LSB = 0x24; # 0x00 Quaternion y Data <7:0> BNO055_REG_QUA_DATA_Y_MSB = 0x25; # 0x00 Quaternion y Data <15:8> BNO055_REG_QUA_DATA_Z = 0x26; BNO055_REG_QUA_DATA_Z_LSB = 0x26; # 0x00 Quaternion z Data <7:0> BNO055_REG_QUA_DATA_Z_MSB = 0x17; # 0x00 Quaternion z Data <15:8> BNO055_REG_LIA_DATA_X = 0x28; BNO055_REG_LIA_DATA_X_LSB = 0x28; # 0x00 Linear Acceleration Data X <7:0> BNO055_REG_LIA_DATA_X_MBS = 0x29; # 0x00 Linear Acceleration Data X <15:8> BNO055_REG_LIA_DATA_Y = 0x2A; BNO055_REG_LIA_DATA_Y_LSB = 0x2A; # 0x00 Linear Acceleration Data Y <7:0> BNO055_REG_LIA_DATA_Y_MBS = 0x2B; # 0x00 Linear Acceleration Data Y <15:8> BNO055_REG_LIA_DATA_Z = 0x2C; BNO055_REG_LIA_DATA_Z_LSB = 0x2C; # 0x00 Linear Acceleration Data Z <7:0> BNO055_REG_LIA_DATA_Z_MBS = 0x2D; # 0x00 Linear Acceleration Data Z <15:8> BNO055_REG_GRV_DATA_X = 0x2E; BNO055_REG_GRV_DATA_X_LSB = 0x2E; # 0x00 Gravity Vector Data X <7:0> BNO055_REG_GRV_DATA_X_MSB = 0x2F; # 0x00 Gravity Vector Data X <15:8> BNO055_REG_GRV_DATA_Y = 0x30; BNO055_REG_GRV_DATA_Y_LSB = 0x30; # 0x00 Gravity Vector Data Y <7:0> BNO055_REG_GRV_DATA_Y_MSB = 0x31; # 0x00 Gravity Vector Data Y <15:8> BNO055_REG_GRV_DATA_Z = 0x32; BNO055_REG_GRV_DATA_Z_LSB = 0x32; # 0x00 Gravity Vector Data Z <7:0> BNO055_REG_GRV_DATA_Z_MSB = 0x33; # 0x00 Gravity Vector Data Z <15:8> BNO055_REG_TEMP = 0x34; # 0x00 Temperature BNO055_REG_CALIB_STAT = 0x35; # 0x00 SYS Calib Status 0:3 GYR Calib Status 0:3 ACC Calib Status 0:3 MAG Calib Status 0:3 BNO055_REG_ST_RESULT = 0x36; # 0x0F ST_MCU ST_GYR ST_MAG ST_ACC BNO055_REG_INT_STA = 0x37; # 0x00 ACC_N M ACC_A M ACC_HI GH_G GYR_DR DY6 GYR_HIG H_RATE GYRO_A M MAG_DR DY6 ACC_BS X_DRDY6 BNO055_REG_SYS_CLK_STATUS = 0x38; # 0x00 ST_MAI N_CLK BNO055_REG_SYS_STATUS = 0x39; # 0x00 System Status Code BNO055_REG_SYS_ERR = 0x3A; # 0x00 System Error Code BNO055_REG_UNIT_SEL = 0x3B; # 0x80 ORI_Android_Windows TEMP_Unit EUL_Unit GYR_Unit ACC_Unit BNO055_REG_Reserved = 0x3C; BNO055_REG_OPR_MODE = 0x3D; # 0x10 Operation Mode <3:0> BNO055_REG_PWR_MODE = 0x3E; # 0x00 Power Mode <1:0> BNO055_REG_SYS_TRIGGER = 0x3F; # 0x00 CLK_S EL RST_IN T RST_S YS Self_Test BNO055_REG_TEMP_SOURCE = 0x40; # 0x00 TEMP_Source <1:0> BNO055_REG_AXIS_MAP_CONFIG = 0x41; # 0x24 Remapped Z axis value Remapped Y axis value Remapped X axis value BNO055_REG_AXIS_MAP_SIGN = 0x42; # 0x00 Remapped X axis sign Remapped Y axis sign Remapped Z axis sign BNO055_REG_SIC_MATRIX_LSB0 = 0x43; # 0x00 SIC_MATRIX_LSB0 BNO055_REG_SIC_MATRIX_MSB0 = 0x44; # 0x40 SIC_MATRIX_MSB0 BNO055_REG_SIC_MATRIX_LSB1 = 0x45; # 0x00 SIC_MATRIX_LSB1 BNO055_REG_SIC_MATRIX_MSB1 = 0x46; # 0x00 SIC_MATRIX_MSB1 BNO055_REG_SIC_MATRIX_LSB2 = 0x47; # 0x00 SIC_MATRIX_LSB2 BNO055_REG_SIC_MATRIX_MSB2 = 0x48; # 0x00 SIC_MATRIX_MSB2 BNO055_REG_SIC_MATRIX_LSB3 = 0x49; # 0x00 SIC_MATRIX_LSB3 BNO055_REG_SIC_MATRIX_MSB3 = 0x4A; # 0x00 SIC_MATRIX_MSB3 BNO055_REG_SIC_MATRIX_LSB4 = 0x4B; # 0x00 SIC_MATRIX_LSB4 BNO055_REG_SIC_MATRIX_MSB4 = 0x4C; # 0x40 SIC_MATRIX_MSB4 BNO055_REG_SIC_MATRIX_LSB5 = 0x4D; # 0x00 SIC_MATRIX_LSB5 BNO055_REG_SIC_MATRIX_MSB5 = 0x4E; # 0x00 SIC_MATRIX_MSB5 BNO055_REG_SIC_MATRIX_LSB6 = 0x4F; # 0x00 SIC_MATRIX_LSB6 BNO055_REG_SIC_MATRIX_MSB6 = 0x50; # 0x00 SIC_MATRIX_MSB6 BNO055_REG_SIC_MATRIX_LSB7 = 0x51; # 0x00 SIC_MATRIX_LSB7 BNO055_REG_SIC_MATRIX_MSB7 = 0x52; # 0x00 SIC_MATRIX_MSB7 BNO055_REG_SIC_MATRIX_LSB8 = 0x53; # 0x00 SIC_MATRIX_LSB8 BNO055_REG_SIC_MATRIX_MSB8 = 0x54; # 0x40 SIC_MATRIX_MSB8 BNO055_REG_ACC_OFFSET_X_LSB = 0x55; # 0x00 Accelerometer Offset X <7:0> BNO055_REG_ACC_OFFSET_X_MSB = 0x56; # 0x00 Accelerometer Offset X <15:8> BNO055_REG_ACC_OFFSET_Y_LSB = 0x57; # 0x00 Accelerometer Offset Y <7:0> BNO055_REG_ACC_OFFSET_Y_MSB = 0x58; # 0x00 Accelerometer Offset Y <15:8> BNO055_REG_ACC_OFFSET_Z_LSB = 0x59; # 0x00 Accelerometer Offset Z <7:0> BNO055_REG_ACC_OFFSET_Z_MSB = 0x5A; # 0x00 Accelerometer Offset Z <15:8> BNO055_REG_MAG_OFFSET_X_LSB = 0x5B; # 0x00 Magnetometer Offset X <7:0> BNO055_REG_MAG_OFFSET_X_MSB = 0x5C; # 0x00 Magnetometer Offset X <15:8> BNO055_REG_MAG_OFFSET_Y_LSB = 0x5D; # 0x00 Magnetometer Offset Y <7:0> BNO055_REG_MAG_OFFSET_Y_MSB = 0x5E; # 0x00 Magnetometer Offset Y <15:8> BNO055_REG_MAG_OFFSET_Z_LSB = 0x5F; # 0x00 Magnetometer Offset Z <7:0> BNO055_REG_MAG_OFFSET_Z_MSB = 0x60; # 0x00 Magnetometer Offset Z <15:8> BNO055_REG_GYR_OFFSET_X_LSB = 0x61; # 0x00 Gyroscope Offset X <7:0> BNO055_REG_GYR_OFFSET_X_MSB = 0x62; # 0x00 Gyroscope Offset X <15:8> BNO055_REG_GYR_OFFSET_Y_LSB = 0x63; # 0x00 Gyroscope Offset Y <7:0> BNO055_REG_GYR_OFFSET_Y_MSB = 0x64; # 0x00 Gyroscope Offset Y <15:8> BNO055_REG_GYR_OFFSET_Z_LSB = 0x65; # 0x00 Gyroscope Offset Z <7:0> BNO055_REG_GYR_OFFSET_Z_MSB = 0x66; # 0x00 Gyroscope Offset Z <15:8> BNO055_REG_ACC_RADIUS_LSB = 0x67; # 0x00 Accelerometer Radius BNO055_REG_ACC_RADIUS_MSB = 0x68; # 0x00 Accelerometer Radius BNO055_REG_MAG_RADIUS_LSB = 0x69; # 0xE0 Magnetometer Radius BNO055_REG_MAG_RADIUS_MSB = 0x6A; # 0x01 Magnetometer Radius endproperties properties(Access = private) i2c; caldata = {}; endproperties # matlab compatible properties properties (SetAccess = private) I2CAddress = ""; Bus = 0; endproperties properties (Access = public) OperatingMode = 'ndof'; endproperties methods # constructor function this = bno055(parentObj, varargin) if nargin < 1 || ! isarduino(parentObj) error('Expected arduino object as first parameter'); endif # parse args p = inputParser(CaseSensitive=false, FunctionName='arduinosensor.SI7021'); p.addParameter('I2CAddress', 0x29, @isnumeric); # matlab default is 0x28 p.addParameter('Bus', 0, @isnumeric); p.addParameter('OperatingMode', 'ndof', @ischar); # ndof or amg p.parse(varargin{:}); # do we have the address ? address = p.Results.I2CAddress; bus = p.Results.Bus; # Operating mode 'ndof' or 'amg' switch p.Results.OperatingMode case 'ndof' this.OperatingMode = p.Results.OperatingMode; case 'amg' this.OperatingMode = p.Results.OperatingMode; otherwise error ("Invalid operating mode"); endswitch this.i2c = device(parentObj, "i2caddress", p.Results.I2CAddress, 'Bus', bus); # verify what talking to id = this.readRegisterU8(this.BNO055_REG_CHIP_ID); if id != 0xA0 pause(1); id = this.readRegisterU8(this.BNO055_REG_CHIP_ID); endif if id != 0xA0 error ("Invalid id '%X' read for sensor", id) endif # init modes this.writeRegister(this.BNO055_REG_OPR_MODE, 0); # set into condig mode # reset this.writeRegister(this.BNO055_REG_SYS_TRIGGER, 0x20); pause(.5); id = this.readRegisterU8(this.BNO055_REG_CHIP_ID); while id != 0xA0 pause(.1); id = this.readRegisterU8(this.BNO055_REG_CHIP_ID); endwhile # normal power mode this.writeRegister(this.BNO055_REG_PWR_MODE, 0); # page 0 this.writeRegister(this.BNO055_REG_PAGE_ID, 0); this.writeRegister(this.BNO055_REG_SYS_TRIGGER, 0x00); pause(.1); if strcmp(this.OperatingMode, "ndof") # NDOF mode this.writeRegister(this.BNO055_REG_OPR_MODE, 0x0C); else # amg this.writeRegister(this.BNO055_REG_OPR_MODE, 0x07); endif pause(.2); endfunction function inf = info (this) inf = {}; inf.Type = "bno055"; inf.SensorId = this.readRegisterU8(this.BNO055_REG_CHIP_ID); inf.AccelId = this.readRegisterU8(this.BNO055_REG_ACC_ID); inf.MagId = this.readRegisterU8(this.BNO055_REG_MAG_ID); inf.GyroId = this.readRegisterU8(this.BNO055_REG_GYR_ID); inf.BootloaderRev = this.readRegisterU8(this.BNO055_REG_BL_REV_ID); inf.Version = this.readRegisterU16(this.BNO055_REG_SW_REV_ID); endfunction function [status, timestamp] = readCalibrationStatus (this) data = single(this.readRegisterU8(this.BNO055_REG_CALIB_STAT)); timestamp = time(); mcal = this.calStatusString (bitand(data, 3)); gcal = this.calStatusString (bitand(bitshift(data, -4), 3)); acal = this.calStatusString (bitand(bitshift(data, -2), 3)); scal = this.calStatusString (bitand(bitshift(data, -6), 3)); status = struct('System', scal, 'Accelerometer', acal, 'Gyroscope', gcal, 'Magnetometer', mcal); endfunction function [C, timestamp] = readTemperature (this) timestamp = time(); C = single(this.readRegisterS8(this.BNO055_REG_TEMP)); endfunction function [readVal, timestamp] = readOrientation (this) data = this.readRegister(this.BNO055_REG_EUL_HEADING, 6); timestamp = time(); azm = typecast(uint16(data(2))*256 + uint16(data(1)), 'int16'); pitch = typecast(uint16(data(4))*256 + uint16(data(3)), 'int16'); roll = typecast(uint16(data(6))*256 + uint16(data(5)), 'int16'); readVal = deg2rad(single([azm pitch, roll])/16.0); endfunction function [readVal, timestamp] = readMagneticField (this) data = this.readRegister(this.BNO055_REG_MAG_DATA_X, 6); timestamp = time(); x = typecast(uint16(data(2))*256 + uint16(data(1)), 'int16'); y = typecast(uint16(data(4))*256 + uint16(data(3)), 'int16'); z = typecast(uint16(data(6))*256 + uint16(data(5)), 'int16'); readVal = single([x y z])/16.0; endfunction function [readVal, timestamp] = readAcceleration (this) data = this.readRegister(this.BNO055_REG_ACC_DATA_X, 6); timestamp = time(); x = typecast(uint16(data(2))*256 + uint16(data(1)), 'int16'); y = typecast(uint16(data(4))*256 + uint16(data(3)), 'int16'); z = typecast(uint16(data(6))*256 + uint16(data(5)), 'int16'); readVal = single([x y z])/100.0; endfunction function [readVal, timestamp] = readAngularVelocity (this) data = this.readRegister(this.BNO055_REG_GYR_DATA_X, 6); timestamp = time(); x = typecast(uint16(data(2))*256 + uint16(data(1)), 'int16'); y = typecast(uint16(data(4))*256 + uint16(data(3)), 'int16'); z = typecast(uint16(data(6))*256 + uint16(data(5)), 'int16'); readVal = single([x y z])/16.0; endfunction function varargout = read(this) data = readData(this); timestamp = time(); accel = this.readAcceleration(); avel = this.readAngularVelocity(); mag = this.readMagneticField(); orien = this.readOrientation(); if nargout <= 2 varargout{1} = struct('Time', timestamp, 'Acceleration', accel, 'AngularVelocity', avel, 'MagneticField', mag, 'Orientation', orien); if nargout > 1 varargout{2} = 0; # no overrun endif else if nargout > 0 varargout{1} = accel; endif if nargout > 1 varargout{2} = avel; endif if nargout > 2 varargout{3} = mag; endif if nargout == 5 varargout{4} = timestamp; varargout{5} = 0; # overrun else if nargout > 3 varargout{4} = orien; endif if nargout > 4 varargout{5} = timestamp; endif if nargout > 5 varargout{6} = 0; # overrun endif endif endif endfunction function flush(this) # flush currenly does nothing endfunction function disp(this) printf(" %s with properties\n", class(this)); printf(" OperatingMode: %s\n", this.OperatingMode); if isobject(this.i2c) printf(" I2CAddress: %d ('0x%s')\n", this.i2c.i2caddress, num2hex(this.i2c.i2caddress)); printf(" Bus: %d\n", this.i2c.bus); else printf(" Not connected"); endif endfunction function release(this) if isobject(this.i2c) delete(this.i2c); this.i2c = []; endif endfunction function delete(this) try if isobject(this.i2c) delete(this.i2c); this.i2c = []; endif catch # do nothing end_try_catch endfunction endmethods methods (Hidden = true) function v = get.I2CAddress (this) v = sprintf("0x%02X", this.i2c.I2CAddress); endfunction function v = get.Bus (this) v = this.i2c.Bus; endfunction endmethods methods (Access = private) function status = calStatusString(this, val) switch val case {1, 2} status = "partial" ; case 3 status = "full" ; otherwise status = "uncalibrated" ; endswitch endfunction function data = readRegister(this, reg, sz) data = readRegister(this.i2c, reg, sz); endfunction function writeRegister(this, reg, data) writeRegister(this.i2c, reg, data); endfunction function value = readRegisterU16(this, reg) data = readRegister(this, reg, 2); value = uint16(data(2))*256 + uint16(data(1)); endfunction function value = readRegisterS16(this, reg) data = readRegister(this, reg, 2); value = uint16(data(2))*256 + uint16(data(1)); value = typecast(value, 'int16'); endfunction function value = readRegisterU8(this, reg) data = readRegister(this, reg, 1); value = uint8(data(1)); endfunction function value = readRegisterS8(this, reg) data = readRegister(this, reg, 1); value = uint8(data(1)); value = typecast(value, 'int8'); endfunction endmethods endclassdef %!error <Expected arduino object as first parameter> bno055(1); arduino-0.12.2/inst/sensors/lis3dh.m����������������������������������������������������������������0000644�0000000�0000000�00000021430�14777724260�014220� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. classdef lis3dh < handle ## -*- texinfo -*- ## @deftypefn {} {} lis3dh ## LIS3DH 3 degrees sensor ## @end deftypefn ## ## @subheading Methods ## @deftypefn {} {@var{obj} =} lis3dh(@var{arObj}) ## @deftypefnx {} {@var{obj} =} lis3dh(@var{arObj}, @var{propertyname, propertyvalue} ....) ## Constructor to create LIS3DH sensor ## @subsubheading Inputs ## @var{arObj} - the arduino parent object ## ## @var{propertyname, propertyvalue} - optional property name, value pairs. ## Current known properties are: ## Current properties are: ## @table @asis ## @item I2CAddress ## I2C address of the sensor (default 0x40) ## @item Bus ## I2C bus - 0 or 1 (default 0) ## @end table ## ## @subsubheading Outputs ## @var{obj} - created object ## ## @subsubheading Example ## @example ## @code { ## a = arduino() ## sensor = lis3dh(a) ## } ## @end example ## @end deftypefn ## ## @deftypefn {} {[@var{readVal}, @var{timestamp}] =} readAcceleration(@var{obj}) ## Read the acceleration rate ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## @var{readVal} - the 3 acceleration values ## ## @var{timestamp} - timestamp when read ## @end deftypefn ## ## @deftypefn {} {[@var{readings}, @var{overrun}] =} read(@var{obj}) ## @deftypefnx {} {[@var{accel}, @var{timestamp}, @var{overrun}] =} read(@var{obj}) ## Read the sensor data ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## @var{accel} - acceleration reading from sensor. ## ## @var{timestamp} - timestamp when read ## ## @var{overrun} - overrun flag. ## ## @var{readings} - table structure with fields for Timestamp, Acceleration. ## @end deftypefn ## ## @deftypefn {} {@var{inf} =} info(@var{obj}) ## Read the sensor info ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## @var{inf} - structure containing the sensor information. ## ## Structure fields are: ## @table @asis ## @item SensorId ## sensor id value ## @item Type ## sensor type 'lis3dh' ## @item Status ## sensor status value ## @end table ## ## @end deftypefn ## ## @deftypefn {} {} flush(@var{obj}) ## Flush sensor data ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## None ## @end deftypefn ## ## @deftypefn {} {} release(@var{obj}) ## Release the resources of the sensor ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## None ## @end deftypefn properties(Access = private, constant = true) # Reserved (do not modify) 00 - 06 Reserved LIS3DH_REG_STATUS_REG_AUX = 0x07; LIS3DH_REG_OUT_ADC1_L = 0x08; LIS3DH_REG_OUT_ADC1_H = 0x09; LIS3DH_REG_OUT_ADC2_L = 0x0A; LIS3DH_REG_OUT_ADC2_H = 0x0B; LIS3DH_REG_OUT_ADC3_L = 0x0C; LIS3DH_REG_OUT_ADC3_H = 0x0D; # Reserved (do not modify) 0E; LIS3DH_REG_WHO_AM_I = 0x0F; # Reserved (do not modify) 10; LIS3DH_REG_CTRL_REG0 = 0x1E; LIS3DH_REG_TEMP_CFG_REG = 0x1F; LIS3DH_REG_CTRL_REG1 = 0x20; LIS3DH_REG_CTRL_REG2 = 0x21; LIS3DH_REG_CTRL_REG3 = 0x22; LIS3DH_REG_CTRL_REG4 = 0x23; LIS3DH_REG_CTRL_REG5 = 0x24; LIS3DH_REG_CTRL_REG6 = 0x25; LIS3DH_REG_REFERENCE = 0x26; LIS3DH_REG_STATUS_REG = 0x27; LIS3DH_REG_OUT_X_L = 0x28; LIS3DH_REG_OUT_X_H = 0x29; LIS3DH_REG_OUT_Y_L = 0x2A; LIS3DH_REG_OUT_Y_H = 0x2B; LIS3DH_REG_OUT_Z_L = 0x2C; LIS3DH_REG_OUT_Z_H = 0x2D; LIS3DH_REG_FIFO_CTRL_REG = 0x2E; LIS3DH_REG_FIFO_SRC_REG = 0x2F; LIS3DH_REG_INT1_CFG = 0x30; LIS3DH_REG_INT1_SRC = 0x31; LIS3DH_REG_INT1_THS = 0x32; LIS3DH_REG_INT1_DURATION = 0x33; LIS3DH_REG_INT2_CFG = 0x34; LIS3DH_REG_INT2_SRC = 0x35; LIS3DH_REG_INT2_THS = 0x36; LIS3DH_REG_INT2_DURATION = 0x37; LIS3DH_REG_CLICK_CFG = 0x38; LIS3DH_REG_CLICK_SRC = 0x39; LIS3DH_REG_CLICK_THS = 0x3A; LIS3DH_REG_TIME_LIMIT = 0x3B; LIS3DH_REG_TIME_LATENCY = 0x3C; LIS3DH_REG_TIME_WINDOW = 0x3D; LIS3DH_REG_ACT_THS = 0x3E; LIS3DH_REG_ACT_DUR = 0x3F; endproperties properties(Access = private) i2c; endproperties # matlab compatible properties properties (SetAccess = private) I2CAddress = ""; Bus = 0; endproperties methods # constructor function this = lis3dh(parentObj, varargin) if nargin < 1 || ! isarduino(parentObj) error('Expected arduino object as first parameter'); endif # parse args p = inputParser(CaseSensitive=false, FunctionName='arduinosensor.SI7021'); p.addParameter('I2CAddress', 0x18, @isnumeric); p.addParameter('Bus', 0, @isnumeric); p.parse(varargin{:}); # do we have the address ? address = p.Results.I2CAddress; bus = p.Results.Bus; this.i2c = device(parentObj, "i2caddress", p.Results.I2CAddress, 'Bus', bus); # verify what talking to pause(.1); id = this.readRegisterU8(this.LIS3DH_REG_WHO_AM_I); if id != 0x33 pause(.1); id = this.readRegisterU8(this.LIS3DH_REG_WHO_AM_I); endif if id != 0x33 error ("Invalid id '%X' read for sensor", id) endif # set up device # 400 Mhz, normal mode, all axis enabled this.writeRegister(this.LIS3DH_REG_CTRL_REG1, 0x77); # bdu enabled, little endian, scale 2g, hires this.writeRegister(this.LIS3DH_REG_CTRL_REG4, 0x88); endfunction function inf = info (this) inf = {}; inf.Type = "lis3dh"; inf.SensorId = this.readRegisterU8(this.LIS3DH_REG_WHO_AM_I); inf.Status = this.readRegisterU8(this.LSM6DSO_REG_STATUS_REG); endfunction function [readVal, timestamp] = readAcceleration (this) data = this.readRegister(bitor(this.LIS3DH_REG_OUT_X_L, 0x80), 6); timestamp = time(); x = typecast(uint16(data(2))*256 + uint16(data(1)), 'int16'); y = typecast(uint16(data(4))*256 + uint16(data(3)), 'int16'); z = typecast(uint16(data(6))*256 + uint16(data(5)), 'int16'); readVal = single([x y z]) * 2.0 / 32768.0; endfunction function varargout = read(this) data = readData(this); timestamp = time(); accel = this.readAcceleration(); if nargout <= 2 varargout{1} = struct('Time', timestamp, 'Acceleration', accel); if nargout > 1 varargout{2} = 0; # no overrun endif else if nargout > 0 varargout{1} = accel; endif if nargout > 1 varargout{2} = timestamp; endif if nargout > 2 varargout{3} = 0; # overrun endif endif endfunction function flush(this) # flush currenly does nothing endfunction function disp(this) printf(" %s with properties\n", class(this)); if isobject(this.i2c) printf(" I2CAddress: %d ('0x%s')\n", this.i2c.i2caddress, num2hex(this.i2c.i2caddress)); printf(" Bus: %d\n", this.i2c.bus); else printf(" Not connected"); endif endfunction function release(this) if isobject(this.i2c) delete(this.i2c); this.i2c = []; endif endfunction function delete(this) try if isobject(this.i2c) delete(this.i2c); this.i2c = []; endif catch # do nothing end_try_catch endfunction endmethods methods (Hidden = true) function v = get.I2CAddress (this) v = sprintf("0x%02X", this.i2c.I2CAddress); endfunction function v = get.Bus (this) v = this.i2c.Bus; endfunction endmethods methods (Access = private) function data = readRegister(this, reg, sz) data = readRegister(this.i2c, reg, sz); endfunction function writeRegister(this, reg, data) writeRegister(this.i2c, reg, data); endfunction function value = readRegisterU8(this, reg) data = readRegister(this, reg, 1); value = uint8(data(1)); endfunction endmethods endclassdef %!error <Expected arduino object as first parameter> lis3dh(1); ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/sensors/lps22hb.m���������������������������������������������������������������0000644�0000000�0000000�00000027052�14777724260�014314� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> ## ## Conversion routines based on code from LPS22HB datasheet ## DocID027083 Rev 6 ## ## 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 ## <https://www.gnu.org/licenses/>. classdef lps22hb < handle ## -*- texinfo -*- ## @deftypefn {} {} lps22hb ## LPS22HB absolute pressure and temperature sensor ## @end deftypefn ## ## @subheading Methods ## @deftypefn {} {@var{obj} =} lps22hb(@var{arObj}) ## @deftypefnx {} {@var{obj} =} lps22hb(@var{arObj}, @var{propertyname, propertyvalue} ....) ## Constructor to create LPS22HB sensor ## @subsubheading Inputs ## @var{arObj} - the arduino parent object ## ## @var{propertyname, propertyvalue} - optional property name, value pairs. ## Current known properties are: ## Current properties are: ## @table @asis ## @item I2CAddress ## I2C address of the sensor (default 0x5C) ## @item Bus ## I2C bus - 0 or 1 (default 0) ## @end table ## ## @subsubheading Outputs ## @var{obj} - created object ## ## @subsubheading Example ## @example ## @code { ## a = arduino() ## sensor = lps22hb(a) ## } ## @end example ## @end deftypefn ## ## @deftypefn {} {[@var{C}, @var{timestamp}] =} readTemperature(@var{obj}) ## Read the temperature ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## @var{C} - read temperature in deg C. ## ## @var{timestamp} - timestamp when read ## ## @subsubheading Example ## @example ## @code { ## a = arduino() ## s = lps22hb(a) ## # get temp ## temp = s.readTemperature ## } ## @end example ## @seealso{lps22hb} ## @end deftypefn ## ## @deftypefn {} {[@var{P}, @var{timestamp}] =} readPressure(@var{obj}) ## Read the pressure ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## @var{P} - pressure reading from sensor. ## ## @var{timestamp} - timestamp when read ## @end deftypefn ## ## @deftypefn {} {[@var{readings}, @var{overrun}] =} read(@var{obj}) ## @deftypefnx {} {[@var{P}, @var{C}, @var{timestamp}, @var{overrun}] =} read(@var{obj}) ## Read the sensor data ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## @var{P} - pressure reading from sensor. ## ## @var{C} - temperature reading from sensor. ## ## @var{timestamp} - timestamp when read ## ## @var{overrun} - overrun flag. ## ## @var{readings} - table structure with fields for Timestamp, Pressure, Temperature and Humidity. ## @end deftypefn ## ## @deftypefn {} {@var{inf} =} info(@var{obj}) ## Read the sensor info ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## @var{inf} - structure containing the sensor information. ## ## Structure fields are: ## @table @asis ## @item Version ## Chip firmware version ## @item SensorId ## sensor id value ## @item Type ## sensor type 'lps22hb' ## @item Status ## Status value read from sensor ## @end table ## ## @end deftypefn ## ## @deftypefn {} {} flush(@var{obj}) ## Flush sensor data ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## None ## @end deftypefn ## ## @deftypefn {} {} release(@var{obj}) ## Release the resources of the sensor ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## None ## @end deftypefn properties(Access = private, constant = true) LPS22_DEFAULT_ADDRESS = 0x5D; LPS22_CHIP_ID = 0xB1; LPS22_REG_INTERRUPT_CFG = 0; # Interrupt register LPS22_REG_THS_P_L = 0x0C; # Pressure threshold registers LPS22_REG_THS_P_H = 0x0D; #LPS22_REG_Reserved = 0E; # Reserved LPS22_REG_WHO_AM_I = 0x0F; # Who am I LPS22_REG_CTRL_REG1 = 0x10; # Control registers LPS22_REG_CTRL_REG2 = 0x11; LPS22_REG_CTRL_REG3 = 0x12; #LPS22_REG_Reserved = 0x13; # Reserved LPS22_REG_FIFO_CTRL = 0x14; # FIFO configuration register LPS22_REG_REF_P_XL = 0x15; # Reference pressure registers LPS22_REG_REF_P_L = 0x16; LPS22_REG_REF_P_H = 0x17; LPS22_REG_RPDS_L = 0x18; # Pressure offset registers LPS22_REG_RPDS_H = 0x19; LPS22_REG_RES_CONF = 0x1A; # Resolution register #LPS22_REG_Reserved = 0x1B; # Reserved LPS22_REG_INT_SOURCE = 0x25; # Interrupt register LPS22_REG_FIFO_STATUS = 0x26; # FIFO status register LPS22_REG_STATUS = 0x27; # Status register LPS22_REG_PRESS_OUT_XL = 0x28; # Pressure output registers LPS22_REG_PRESS_OUT_L = 0x29; LPS22_REG_PRESS_OUT_H = 0x2A; LPS22_REG_TEMP_OUT_L = 0x2B; # Temperature output registers LPS22_REG_TEMP_OUT_H = 0x2C; #LPS22_REG_Reserved = 0x2D; # Reserved LPS22_REG_LPFP_RES = 0x33; # Filter reset register endproperties properties(Access = private) i2c; caldata = {}; endproperties # matlab compatible properties properties (SetAccess = private) I2CAddress = ""; Bus = 0; SampleRate = 1; endproperties methods # constructor function this = lps22hb(parentObj, varargin) if nargin < 1 || ! isarduino(parentObj) error('Expected arduino object as first parameter'); endif # parse args p = inputParser(CaseSensitive=false, FunctionName='lps22hb'); p.addParameter('I2CAddress', this.LPS22_DEFAULT_ADDRESS, @isnumeric); p.addParameter('Bus', 0, @isnumeric); p.addParameter('SampleRate', 10, @isnumeric); p.parse(varargin{:}); # do we have the address ? address = p.Results.I2CAddress; bus = p.Results.Bus; this.SampleRate = int32(p.Results.SampleRate); regrate = 1; switch this.SampleRate case 1 regrate = 1; case 10 regrate = 2; case 25 regrate = 3; case 50 regrate = 4; case 75 regrate = 5; otherwise error("Unsupported samplerate - known values 1, 10, 25, 50, 75"); endswitch #i2caddresses = scanI2Cbus(parentObj, bus); #idx = find(cellfun ( @(x) strcmp(x, sprintf("0x%02X", address)), i2caddresses)); #if isempty(idx) # error('No matching i2c address found on bus'); #endif this.i2c = device(parentObj, "i2caddress", p.Results.I2CAddress, 'Bus', bus); pause(.1); # init id = this.readRegisterU8(this.LPS22_REG_WHO_AM_I); if id != this.LPS22_CHIP_ID pause(.2); id = this.readRegisterU8(this.LPS22_REG_WHO_AM_I); endif if id != this.LPS22_CHIP_ID error ("Invalid id '%X' read for sensor", id) endif # reset states this.writeRegister(this.LPS22_REG_CTRL_REG2, 0x04); # wait while chip is resetting status = this.readRegisterU8(this.LPS22_REG_CTRL_REG2); while bitand(status, 4) == 4 pause(.1); status = this.readRegisterU8(this.LPS22_REG_CTRL_REG2); endwhile # set data rate reg = this.readRegisterU8(this.LPS22_REG_CTRL_REG1); reg = bitand(reg, 0x8F); reg = bitor(reg, bitshift(regrate, 4)); this.writeRegister(this.LPS22_REG_CTRL_REG1, reg); endfunction function inf = info (this) inf = {}; inf.Type = "lps22hb"; inf.SensorId = this.LPS22_CHIP_ID; inf.Version = 0; inf.Status = this.readRegisterU8(this.LPS22_REG_STATUS); endfunction function [C, timestamp] = readTemperature (this) data = readData(this); value = bitshift(uint16(data(6)), 8) + uint16(data(5)); timestamp = time(); C = calcTemperature(this, value); endfunction function [P, timestamp] = readPressure(this) data = readData(this); value = bitshift(int32(data(4)), 16) + bitshift(int32(data(3)), 8) + int32(data(2)); timestamp = time(); P = calcPressure(this, value); endfunction function varargout = read(this) data = readData(this); timestamp = time(); value = bitshift(uint16(data(6)), 8) + uint16(data(5)); C = calcTemperature(this, value); value = bitshift(int32(data(4)), 16) + bitshift(int32(data(3)), 8) + int32(data(2)); P = calcPressure(this, value); overrun = bitand(data(1), 0x30) != 0; if nargout <= 2 varargout{1} = struct('Time', timestamp, 'Temperature', C, 'Pressure', P); if nargout > 1 varargout{2} = overrun; endif else if nargout > 0 varargout{1} = P; endif if nargout > 1 varargout{2} = C; endif if nargout > 2 varargout{3} = timestamp; endif if nargout > 3 varargout{4} = overrun; endif endif endfunction function flush(this) # flush currenly does nothing endfunction function disp(this) printf(" %s with properties\n", class(this)); if isobject(this.i2c) printf(" I2CAddress: %d ('0x%s')\n", this.i2c.i2caddress, num2hex(this.i2c.i2caddress)); printf(" Bus: %d\n", this.i2c.bus); printf(" SampleRate: %d\n", this.SampleRate); else printf(" Not connected"); endif endfunction function release(this) if isobject(this.i2c) delete(this.i2c); this.i2c = []; endif endfunction function delete(this) try if isobject(this.i2c) delete(this.i2c); this.i2c = []; endif catch # do nothing end_try_catch endfunction endmethods methods (Hidden = true) function v = get.I2CAddress (this) v = sprintf("0x%02X", this.i2c.I2CAddress); endfunction function v = get.Bus (this) v = this.i2c.Bus; endfunction endmethods methods (Access = private) function C = calcTemperature(this, value) if bitand(value, 0x8000) var1 = double(value) - double(0xFFFF); else var1 = double(value); endif C = var1 / 100.0; endfunction function P = calcPressure(this, value) if bitand(value, int32(0x800000)) var1 = double(value) - double(0xFFFFFF); else var1 = double(value); endif P = var1 / 4096.0; endfunction function data = readRegister(this, reg, sz) data = readRegister(this.i2c, reg, sz); endfunction function writeRegister(this, reg, data) writeRegister(this.i2c, reg, data); endfunction # read the data function data = readData(this) # wait for data m = 0; while m == 0 status = this.readRegisterU8 (this.LPS22_REG_STATUS); m = bitand(status, 0x03); if m != 0 pause(.1); endif endwhile # 1 status, 3 pres, 2 temp data = readRegister(this, this.LPS22_REG_STATUS, 6); endfunction function value = readRegisterU8(this, reg) data = readRegister(this, reg, 1); value = uint8(data(1)); endfunction endmethods endclassdef %!error <Expected arduino object as first parameter> lps22hb(1); ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/sensors/lsm6dso.m���������������������������������������������������������������0000644�0000000�0000000�00000035560�14777724260�014432� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. classdef lsm6dso < handle ## -*- texinfo -*- ## @deftypefn {} {} lsm6dso ## LSM6DSO 6 degrees sensor ## @end deftypefn ## ## @subheading Methods ## @deftypefn {} {@var{obj} =} lsm6dso(@var{arObj}) ## @deftypefnx {} {@var{obj} =} lsm6dso(@var{arObj}, @var{propertyname, propertyvalue} ....) ## Constructor to create LSM6DSO sensor ## @subsubheading Inputs ## @var{arObj} - the arduino parent object ## ## @var{propertyname, propertyvalue} - optional property name, value pairs. ## Current known properties are: ## Current properties are: ## @table @asis ## @item I2CAddress ## I2C address of the sensor (default 0x40) ## @item Bus ## I2C bus - 0 or 1 (default 0) ## @end table ## ## @subsubheading Outputs ## @var{obj} - created object ## ## @subsubheading Example ## @example ## @code { ## a = arduino() ## sensor = lsm6dso(a) ## } ## @end example ## @end deftypefn ## ## @deftypefn {} {[@var{C}, @var{timestamp}] =} readTemperature(@var{obj}) ## Read the temperature ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## @var{C} - read temperature in deg C. ## ## @var{timestamp} - timestamp when read ## ## @subsubheading Example ## @example ## @code { ## a = arduino() ## s = lsm6dso(a) ## # get temp ## temp = s.readTemperature ## } ## @end example ## @seealso{lsm6dso} ## @end deftypefn ## ## @deftypefn {} {[@var{readVal}, @var{timestamp}] =} readAcceleration(@var{obj}) ## Read the acceleration rate ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## @var{readVal} - the 3 acceleration values ## ## @var{timestamp} - timestamp when read ## @end deftypefn ## ## @deftypefn {} {[@var{readVal}, @var{timestamp}] =} readAngularVelocity(@var{obj}) ## Read the angular velocity ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## @var{readVal} - the 3 angular velocity values ## ## @var{timestamp} - timestamp when read ## @end deftypefn ## ## @deftypefn {} {[@var{readings}, @var{overrun}] =} read(@var{obj}) ## @deftypefnx {} {[@var{accel}, @var{gyro}, @var{mag}, @var{timestamp}, @var{overrun}] =} read(@var{obj}) ## Read the sensor data ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## @var{accel} - acceleration reading from sensor. ## ## @var{gyro} - angular acceleration reading from sensor. ## ## @var{timestamp} - timestamp when read ## ## @var{overrun} - overrun flag. ## ## @var{readings} - table structure with fields for Timestamp, Acceleration, AngularVelocity. ## @end deftypefn ## ## @deftypefn {} {@var{inf} =} info(@var{obj}) ## Read the sensor info ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## @var{inf} - structure containing the sensor information. ## ## Structure fields are: ## @table @asis ## @item SensorId ## sensor id value ## @item Type ## sensor type 'lsm6dso' ## @end table ## ## @end deftypefn ## ## @deftypefn {} {} flush(@var{obj}) ## Flush sensor data ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## None ## @end deftypefn ## ## @deftypefn {} {} release(@var{obj}) ## Release the resources of the sensor ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## None ## @end deftypefn properties(Access = private, constant = true) LSM6DSO_REG_FUNC_CFG_ACCESS = 0x01; # RW 01 00000001 00000000 LSM6DSO_REG_PIN_CTRL = 0x02; # RW 02 00000010 00111111 #LSM6DSO_REG_RESERVED - 03-06 LSM6DSO_REG_FIFO_CTRL1 = 0x07; # RW 07 00000111 00000000 LSM6DSO_REG_FIFO_CTRL2 = 0x08; # RW 08 00001000 00000000 LSM6DSO_REG_FIFO_CTRL3 = 0x09; # RW 09 00001001 00000000 LSM6DSO_REG_FIFO_CTRL4 = 0x0A; # RW 0A 00001010 00000000 LSM6DSO_REG_COUNTER_BDR_REG1 = 0x0B; # RW 0B 00001011 00000000 LSM6DSO_REG_COUNTER_BDR_REG2 = 0x0C; # RW 0C 00001100 00000000 LSM6DSO_REG_INT1_CTRL = 0x0D; # RW 0D 00001101 00000000 LSM6DSO_REG_INT2_CTRL = 0x0E; # RW 0E 00001110 00000000 LSM6DSO_REG_WHO_AM_I = 0x0F; # R 0F 00001111 01101100 R (SPI2) LSM6DSO_REG_CTRL1_XL = 0x10; # RW 10 00010000 00000000 R (SPI2) LSM6DSO_REG_CTRL2_G = 0x11; # RW 11 00010001 00000000 R (SPI2) LSM6DSO_REG_CTRL3_C = 0x12; # RW 12 00010010 00000100 R (SPI2) LSM6DSO_REG_CTRL4_C = 0x13; # RW 13 00010011 00000000 R (SPI2) LSM6DSO_REG_CTRL5_C = 0x14; # RW 14 00010100 00000000 R (SPI2) LSM6DSO_REG_CTRL6_C = 0x15; # RW 15 00010101 00000000 R (SPI2) LSM6DSO_REG_CTRL7_G = 0x16; # RW 16 00010110 00000000 R (SPI2) LSM6DSO_REG_CTRL8_XL = 0x17; # RW 17 0001 0111 00000000 R (SPI2) LSM6DSO_REG_CTRL9_XL = 0x18; # RW 18 00011000 11100000 R (SPI2) LSM6DSO_REG_CTRL10_C = 0x19; # RW 19 00011001 00000000 R (SPI2) LSM6DSO_REG_ALL_INT_SRC = 0x1A; # R 1A 00011010 output LSM6DSO_REG_WAKE_UP_SRC = 0x1B; # R 1B 00011011 output LSM6DSO_REG_TAP_SRC = 0x1C; # R 1C 00011100 output LSM6DSO_REG_D6D_SRC = 0x1D; # R 1D 00011101 output LSM6DSO_REG_STATUS_REG = 0x1E; # (1) / STATUS_SPIAux(2) R 1E 00011110 output # LSM6DSO_REG_RESERVED - 1F 00011111 LSM6DSO_REG_OUT_TEMP_L = 0x20; # R 20 00100000 output LSM6DSO_REG_OUT_TEMP_H = 0x21; # R 21 00100001 output LSM6DSO_REG_OUTX_L_G = 0x22; # R 22 00100010 output LSM6DSO_REG_OUTX_H_G = 0x23; # R 23 00100011 output LSM6DSO_REG_OUTY_L_G = 0x24; # R 24 00100100 outpu LSM6DSO_REG_OUTY_H_G = 0x25; # R 25 00100101 output LSM6DSO_REG_OUTZ_L_G = 0x26; # R 26 00100110 output LSM6DSO_REG_OUTZ_H_G = 0x27; # R 27 00100111 output LSM6DSO_REG_OUTX_L_A = 0x28; # R 28 00101000 output LSM6DSO_REG_OUTX_H_A = 0x29; # R 29 00101001 output LSM6DSO_REG_OUTY_L_A = 0x2A; # R 2A 00101010 output LSM6DSO_REG_OUTY_H_A = 0x2B; # R 2B 00101011 output LSM6DSO_REG_OUTZ_L_A = 0x2C; # R 2C 00101100 output LSM6DSO_REG_OUTZ_H_A = 0x2D; # R 2D 00101101 output #LSM6DSO_REG_RESERVED - 2E-34 LSM6DSO_REG_EMB_FUNC_STATUS_MAINPAGE = 0x35; # R 35 00110101 output LSM6DSO_REG_FSM_STATUS_A_MAINPAGE = 0x36; # R 36 00110110 output LSM6DSO_REG_FSM_STATUS_B_MAINPAGE = 0x37; # R 37 00110111 output # LSM6DSO_REG_RESERVED - 38 LSM6DSO_REG_STATUS_MASTER_MAINPAGE = 0x39; # R 39 00111001 output LSM6DSO_REG_FIFO_STATUS1 = 0x3A; # R 3A 00111010 output LSM6DSO_REG_FIFO_STATUS2 = 0x3B; # R 3B 00111011 output #LSM6DSO_REG_RESERVED - 3C-3F LSM6DSO_REG_TIMESTAMP0 = 0x40; # R 40 01000000 output R (SPI2) LSM6DSO_REG_TIMESTAMP1 = 0x41; # R 41 01000001 output R (SPI2) LSM6DSO_REG_TIMESTAMP2 = 0x42; # R 42 01000010 output R (SPI2) LSM6DSO_REG_TIMESTAMP3 = 0x43; # R 43 01000011 output R (SPI2) #LSM6DSO_REG_RESERVED - 44-55 LSM6DSO_REG_TAP_CFG0 = 0x56; # RW 56 01010110 00000000 LSM6DSO_REG_TAP_CFG1 = 0x57; # RW 57 01010111 00000000 LSM6DSO_REG_TAP_CFG2 = 0x58; # RW 58 01011000 00000000 LSM6DSO_REG_TAP_THS_6D = 0x59; # RW 59 01011001 00000000 LSM6DSO_REG_INT_DUR2 = 0x5A; # RW 5A 01011010 00000000 LSM6DSO_REG_WAKE_UP_THS = 0x5B; # RW 5B 01011011 00000000 LSM6DSO_REG_WAKE_UP_DUR = 0x5C; # RW 5C 01011100 00000000 LSM6DSO_REG_FREE_FALL = 0x5D; # RW 5D 01011101 00000000 LSM6DSO_REG_MD1_CFG = 0x5E; # RW 5E 01011110 00000000 LSM6DSO_REG_MD2_CFG = 0x5F; # RW 5F 01011111 00000000 # LSM6DSO_REG_RESERVED - 60-61 00000000 LSM6DSO_REG_I3C_BUS_AVB = 0x62; # RW 62 01100010 00000000 LSM6DSO_REG_INTERNAL_FREQ_FINE = 0x63; # R 63 01100011 output # LSM6DSO_REG_RESERVED - 64-6E LSM6DSO_REG_INT_OIS = 0x6F; # R 6F 01101111 00000000 RW (SPI2) LSM6DSO_REG_CTRL1_OIS = 0x70; # R 70 01110000 00000000 RW (SPI2) LSM6DSO_REG_CTRL2_OIS = 0x71; # R 71 01110001 00000000 RW (SPI2) LSM6DSO_REG_CTRL3_OIS = 0x72; # R 72 01110010 00000000 RW (SPI2) LSM6DSO_REG_X_OFS_USR = 0x73; # RW 73 01110011 00000000 LSM6DSO_REG_Y_OFS_USR = 0x74; # RW 74 01110100 00000000 LSM6DSO_REG_Z_OFS_USR = 0x75; # RW 75 01110101 00000000 #LSM6DSO_REG_RESERVED - 76-77 LSM6DSO_REG_FIFO_DATA_OUT_TAG = 0x78; # R 78 01111000 output LSM6DSO_REG_FIFO_DATA_OUT_X_L = 0x79; # R 79 01111001 output LSM6DSO_REG_FIFO_DATA_OUT_X_H = 0x7A; # R 7A 01111010 output LSM6DSO_REG_FIFO_DATA_OUT_Y_L = 0x7B; # R 7B 01111011 output LSM6DSO_REG_FIFO_DATA_OUT_Y_H = 0x7C; # R 7C 01111100 output LSM6DSO_REG_FIFO_DATA_OUT_Z_L = 0x7D; # R 7D 01111101 output LSM6DSO_REG_FIFO_DATA_OUT_Z_H = 0x7E; # R 7E 01111110 output endproperties properties(Access = private) i2c; caldata = {}; endproperties # matlab compatible properties properties (SetAccess = private) I2CAddress = ""; Bus = 0; endproperties methods # constructor function this = lsm6dso(parentObj, varargin) if nargin < 1 || ! isarduino(parentObj) error('Expected arduino object as first parameter'); endif # parse args p = inputParser(CaseSensitive=false, FunctionName='arduinosensor.SI7021'); p.addParameter('I2CAddress', 0x6A, @isnumeric); # matlab default is 0x28 p.addParameter('Bus', 0, @isnumeric); p.parse(varargin{:}); # do we have the address ? address = p.Results.I2CAddress; bus = p.Results.Bus; this.i2c = device(parentObj, "i2caddress", p.Results.I2CAddress, 'Bus', bus); # verify what talking to pause(.1); id = this.readRegisterU8(this.LSM6DSO_REG_WHO_AM_I); if id != 0x6C error ("Invalid id '%X' read for sensor", id) endif # set up device # set the gyroscope control register to work at 104 Hz, 2000 dps and in bypass mode this.writeRegister(this.LSM6DSO_REG_CTRL2_G, 0x4C); # Set the Accelerometer control register to work at 104 Hz, 4 g,and in bypass mode and enable ODR/4 lowpass filter this.writeRegister(this.LSM6DSO_REG_CTRL1_XL, 0x4A); # set gyroscope power mode to high performance and bandwidth to 16 MHz this.writeRegister(this.LSM6DSO_REG_CTRL7_G, 0x00); # Set the ODR config register to ODR/4 this.writeRegister(this.LSM6DSO_REG_CTRL8_XL, 0x09); endfunction function inf = info (this) inf = {}; inf.Type = "lsm6dso"; inf.SensorId = this.readRegisterU8(this.LSM6DSO_REG_WHO_AM_I); inf.Status = this.readRegisterU8(this.LSM6DSO_REG_STATUS_REG); endfunction function [C, timestamp] = readTemperature (this) value = this.readRegisterS16(this.LSM6DSO_REG_OUT_TEMP_L); timestamp = time(); C = single(value)/256.0 + 25.0; endfunction function [readVal, timestamp] = readAcceleration (this) data = this.readRegister(this.LSM6DSO_REG_OUTX_L_A, 6); timestamp = time(); x = typecast(uint16(data(2))*256 + uint16(data(1)), 'int16'); y = typecast(uint16(data(4))*256 + uint16(data(3)), 'int16'); z = typecast(uint16(data(6))*256 + uint16(data(5)), 'int16'); # 4g scale readVal = single([x y z]) * 4.0 / 32768.0; endfunction function [readVal, timestamp] = readAngularVelocity (this) data = this.readRegister(this.LSM6DSO_REG_OUTX_L_G, 6); timestamp = time(); x = typecast(uint16(data(2))*256 + uint16(data(1)), 'int16'); y = typecast(uint16(data(4))*256 + uint16(data(3)), 'int16'); z = typecast(uint16(data(6))*256 + uint16(data(5)), 'int16'); # range 2000 readVal = single([x y z]) * 2000.0 / 32768.0; endfunction function varargout = read(this) data = readData(this); timestamp = time(); accel = this.readAcceleration(); avel = this.readAngularVelocity(); temp = this.readTemperature(); if nargout <= 2 varargout{1} = struct('Time', timestamp, 'Acceleration', accel, 'AngularVelocity', avel, 'Temperature', temp); if nargout > 1 varargout{2} = 0; # no overrun endif else if nargout > 0 varargout{1} = accel; endif if nargout > 1 varargout{2} = avel; endif if nargout > 2 varargout{3} = temp; endif if nargout > 3 varargout{4} = timestamp; endif if nargout > 4 varargout{5} = 0; # overrun endif endif endfunction function flush(this) # flush currenly does nothing endfunction function disp(this) printf(" %s with properties\n", class(this)); if isobject(this.i2c) printf(" I2CAddress: %d ('0x%s')\n", this.i2c.i2caddress, num2hex(this.i2c.i2caddress)); printf(" Bus: %d\n", this.i2c.bus); else printf(" Not connected"); endif endfunction function release(this) if isobject(this.i2c) delete(this.i2c); this.i2c = []; endif endfunction function delete(this) try if isobject(this.i2c) delete(this.i2c); this.i2c = []; endif catch # do nothing end_try_catch endfunction endmethods methods (Hidden = true) function v = get.I2CAddress (this) v = sprintf("0x%02X", this.i2c.I2CAddress); endfunction function v = get.Bus (this) v = this.i2c.Bus; endfunction endmethods methods (Access = private) function data = readRegister(this, reg, sz) data = readRegister(this.i2c, reg, sz); endfunction function writeRegister(this, reg, data) writeRegister(this.i2c, reg, data); endfunction function value = readRegisterU16(this, reg) data = readRegister(this, reg, 2); value = uint16(data(2))*256 + uint16(data(1)); endfunction function value = readRegisterS16(this, reg) data = readRegister(this, reg, 2); value = uint16(data(2))*256 + uint16(data(1)); value = typecast(value, 'int16'); endfunction function value = readRegisterU8(this, reg) data = readRegister(this, reg, 1); value = uint8(data(1)); endfunction function value = readRegisterS8(this, reg) data = readRegister(this, reg, 1); value = uint8(data(1)); value = typecast(value, 'int8'); endfunction endmethods endclassdef %!error <Expected arduino object as first parameter> lsm6dso(1); ������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/sensors/mpu6050.m���������������������������������������������������������������0000644�0000000�0000000�00000033274�14777724260�014157� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. classdef mpu6050 < handle ## -*- texinfo -*- ## @deftypefn {} {} mpu6050 ## MPU-6050 6 degrees sensor ## @end deftypefn ## ## @subheading Methods ## @deftypefn {} {@var{obj} =} mpu6050(@var{arObj}) ## @deftypefnx {} {@var{obj} =} mpu6050(@var{arObj}, @var{propertyname, propertyvalue} ....) ## Constructor to create MPU-6050 sensor ## @subsubheading Inputs ## @var{arObj} - the arduino parent object ## ## @var{propertyname, propertyvalue} - optional property name, value pairs. ## Current known properties are: ## Current properties are: ## @table @asis ## @item I2CAddress ## I2C address of the sensor (default 0x40) ## @item Bus ## I2C bus - 0 or 1 (default 0) ## @end table ## ## @subsubheading Outputs ## @var{obj} - created object ## ## @subsubheading Example ## @example ## @code { ## a = arduino() ## sensor = mpu6050(a) ## } ## @end example ## @end deftypefn ## ## @deftypefn {} {[@var{C}, @var{timestamp}] =} readTemperature(@var{obj}) ## Read the temperature ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## @var{C} - read temperature in deg C. ## ## @var{timestamp} - timestamp when read ## ## @subsubheading Example ## @example ## @code { ## a = arduino() ## s = mpu6050(a) ## # get temp ## temp = s.readTemperature ## } ## @end example ## @seealso{mpu6050} ## @end deftypefn ## ## @deftypefn {} {[@var{readVal}, @var{timestamp}] =} readAcceleration(@var{obj}) ## Read the acceleration rate ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## @var{readVal} - the 3 acceleration values ## ## @var{timestamp} - timestamp when read ## @end deftypefn ## ## @deftypefn {} {[@var{readVal}, @var{timestamp}] =} readAngularVelocity(@var{obj}) ## Read the angular velocity ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## @var{readVal} - the 3 angular velocity values ## ## @var{timestamp} - timestamp when read ## @end deftypefn ## ## @deftypefn {} {[@var{readings}, @var{overrun}] =} read(@var{obj}) ## @deftypefnx {} {[@var{accel}, @var{gyro}, @var{mag}, @var{timestamp}, @var{overrun}] =} read(@var{obj}) ## Read the sensor data ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## @var{accel} - acceleration reading from sensor. ## ## @var{gyro} - angular acceleration reading from sensor. ## ## @var{timestamp} - timestamp when read ## ## @var{overrun} - overrun flag. ## ## @var{readings} - table structure with fields for Timestamp, Acceleration, AngularVelocity. ## @end deftypefn ## ## @deftypefn {} {@var{inf} =} info(@var{obj}) ## Read the sensor info ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## @var{inf} - structure containing the sensor information. ## ## Structure fields are: ## @table @asis ## @item SensorId ## sensor id value ## @item Type ## sensor type 'mpu6050' ## @end table ## ## @end deftypefn ## ## @deftypefn {} {} flush(@var{obj}) ## Flush sensor data ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## None ## @end deftypefn ## ## @deftypefn {} {} release(@var{obj}) ## Release the resources of the sensor ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## None ## @end deftypefn properties(Access = private, constant = true) MPU6050_REG_XG_OFFS_TC = 0x00; MPU6050_REG_YG_OFFS_TC = 0x01; MPU6050_REG_ZG_OFFS_TC = 0x02; MPU6050_REG_X_FINE_GAIN = 0x03; MPU6050_REG_Y_FINE_GAIN = 0x04; MPU6050_REG_Z_FINE_GAIN = 0x05; MPU6050_REG_XA_OFFS_H = 0x06; MPU6050_REG_XA_OFFS_L_TC= 0x07; MPU6050_REG_YA_OFFS_H = 0x08; MPU6050_REG_YA_OFFS_L_TC= 0x09; MPU6050_REG_ZA_OFFS_H = 0x0A; MPU6050_REG_ZA_OFFS_L_TC= 0x0B; MPU6050_REG_SELF_TEST_X = 0x0D; MPU6050_REG_SELF_TEST_Y = 0x0E; MPU6050_REG_SELF_TEST_Z = 0x0F; MPU6050_REG_SELF_TEST_A = 0x10; MPU6050_REG_XG_OFFS_USRH= 0x13; MPU6050_REG_XG_OFFS_USRL= 0x14; MPU6050_REG_YG_OFFS_USRH= 0x15; MPU6050_REG_YG_OFFS_USRL= 0x16; MPU6050_REG_ZG_OFFS_USRH= 0x17; MPU6050_REG_ZG_OFFS_USRL= 0x18; MPU6050_REG_SMPLRT_DIV = 0x19; MPU6050_REG_CONFIG = 0x1A; MPU6050_REG_GYRO_CONFIG = 0x1B; MPU6050_REG_ACCEL_CONFIG= 0x1C; MPU6050_REG_FF_THR = 0x1D; MPU6050_REG_FF_DUR = 0x1E; MPU6050_REG_MOT_THR = 0x1F; MPU6050_REG_MOT_DUR = 0x20; MPU6050_REG_ZRMOT_THR = 0x21; MPU6050_REG_ZRMOT_DUR = 0x22; MPU6050_REG_FIFO_EN = 0x23; MPU6050_REG_I2C_MST_CTRL= 0x24; MPU6050_REG_I2C_SLV0_ADDR= 0x25; MPU6050_REG_I2C_SLV0_REG= 0x26; MPU6050_REG_I2C_SLV0_CTRL= 0x27; MPU6050_REG_I2C_SLV1_ADDR= 0x28; MPU6050_REG_I2C_SLV1_REG= 0x29; MPU6050_REG_I2C_SLV1_CTRL= 0x2A; MPU6050_REG_I2C_SLV2_ADDR= 0x2B; MPU6050_REG_I2C_SLV2_REG= 0x2C; MPU6050_REG_I2C_SLV2_CTRL= 0x2D; MPU6050_REG_I2C_SLV3_ADDR= 0x2E; MPU6050_REG_I2C_SLV3_REG= 0x2F; MPU6050_REG_I2C_SLV3_CTRL= 0x30; MPU6050_REG_I2C_SLV4_ADDR= 0x31; MPU6050_REG_I2C_SLV4_REG= 0x32; MPU6050_REG_I2C_SLV4_DO = 0x33; MPU6050_REG_I2C_SLV4_CTRL= 0x34; MPU6050_REG_I2C_SLV4_DI = 0x35; MPU6050_REG_I2C_MST_STATUS= 36; MPU6050_REG_INT_PIN_CFG = 0x37; MPU6050_REG_INT_ENABLE = 0x38; MPU6050_REG_DMP_INT_STATUS= 0x39; MPU6050_REG_INT_STATUS = 0x3A; MPU6050_REG_ACCEL_XOUT_H= 0x3B; MPU6050_REG_ACCEL_XOUT_L= 0x3C; MPU6050_REG_ACCEL_YOUT_H= 0x3D; MPU6050_REG_ACCEL_YOUT_L= 0x3E; MPU6050_REG_ACCEL_ZOUT_H= 0x3F; MPU6050_REG_ACCEL_ZOUT_L= 0x40; MPU6050_REG_TEMP_OUT_H = 0x41; MPU6050_REG_TEMP_OUT_L = 0x42; MPU6050_REG_GYRO_XOUT_H = 0x43; MPU6050_REG_GYRO_XOUT_L = 0x44; MPU6050_REG_GYRO_YOUT_H = 0x45; MPU6050_REG_GYRO_YOUT_L = 0x46; MPU6050_REG_GYRO_ZOUT_H = 0x47; MPU6050_REG_GYRO_ZOUT_L = 0x48; MPU6050_REG_EXT_SENS_DATA_00 = 0x49; MPU6050_REG_EXT_SENS_DATA_01 = 0x4A; MPU6050_REG_EXT_SENS_DATA_02 = 0x4B; MPU6050_REG_EXT_SENS_DATA_03 = 0x4C; MPU6050_REG_EXT_SENS_DATA_04 = 0x4D; MPU6050_REG_EXT_SENS_DATA_05 = 0x4E; MPU6050_REG_EXT_SENS_DATA_06 = 0x4F; MPU6050_REG_EXT_SENS_DATA_07 = 0x50; MPU6050_REG_EXT_SENS_DATA_08 = 0x51; MPU6050_REG_EXT_SENS_DATA_09 = 0x52; MPU6050_REG_EXT_SENS_DATA_10 = 0x53; MPU6050_REG_EXT_SENS_DATA_11 = 0x54; MPU6050_REG_EXT_SENS_DATA_12 = 0x55; MPU6050_REG_EXT_SENS_DATA_13 = 0x56; MPU6050_REG_EXT_SENS_DATA_14 = 0x57; MPU6050_REG_EXT_SENS_DATA_15 = 0x58; MPU6050_REG_EXT_SENS_DATA_16 = 0x59; MPU6050_REG_EXT_SENS_DATA_17 = 0x5A; MPU6050_REG_EXT_SENS_DATA_18 = 0x5B; MPU6050_REG_EXT_SENS_DATA_19 = 0x5C; MPU6050_REG_EXT_SENS_DATA_20 = 0x5D; MPU6050_REG_EXT_SENS_DATA_21 = 0x5E; MPU6050_REG_EXT_SENS_DATA_22 = 0x5F; MPU6050_REG_EXT_SENS_DATA_23 = 0x60; MPU6050_REG_MOT_DETECT_STATUS= 0x61; MPU6050_REG_I2C_SLV0_DO = 0x63; MPU6050_REG_I2C_SLV1_DO = 0x64; MPU6050_REG_I2C_SLV2_DO = 0x65; MPU6050_REG_I2C_SLV3_DO = 0x66; MPU6050_REG_I2C_MST_DELAY_CTRL= 0x67; MPU6050_REG_SIGNAL_PATH_RESET= 0x68; MPU6050_REG_MOT_DETECT_CTRL= 0x69; MPU6050_REG_USER_CTRL = 0x6A; MPU6050_REG_PWR_MGMT_1 = 0x6B; MPU6050_REG_PWR_MGMT_2 = 0x6C; MPU6050_REG_BANK_SEL = 0x6D; MPU6050_REG_MEM_START_ADDR = 0x6E; MPU6050_REG_MEM_R_W = 0x6F; MPU6050_REG_DMP_CFG_1 = 0x70; MPU6050_REG_DMP_CFG_2 = 0x71; MPU6050_REG_FIFO_COUNTH = 0x72; MPU6050_REG_FIFO_COUNTL = 0x73; MPU6050_REG_FIFO_R_W = 0x74; MPU6050_REG_WHO_AM_I = 0x75; endproperties properties(Access = private) i2c; caldata = {}; endproperties # matlab compatible properties properties (SetAccess = private) I2CAddress = ""; Bus = 0; endproperties methods # constructor function this = mpu6050(parentObj, varargin) if nargin < 1 || ! isarduino(parentObj) error('Expected arduino object as first parameter'); endif # parse args p = inputParser(CaseSensitive=false, FunctionName='arduinosensor.SI7021'); p.addParameter('I2CAddress', 0x68, @isnumeric); # matlab default is 0x28 p.addParameter('Bus', 0, @isnumeric); p.parse(varargin{:}); # do we have the address ? address = p.Results.I2CAddress; bus = p.Results.Bus; this.i2c = device(parentObj, "i2caddress", p.Results.I2CAddress, 'Bus', bus); # verify what talking to id = this.readRegisterU8(this.MPU6050_REG_WHO_AM_I) pause(.1) id = this.readRegisterU8(this.MPU6050_REG_WHO_AM_I) if id != 0x68 && id != 0x69 error ("Invalid id '%X' read for sensor", id) endif # init # set gyro 250deg/s this.writeRegister(this.MPU6050_REG_GYRO_CONFIG, 0x00); # set accel scale to 2g this.writeRegister(this.MPU6050_REG_ACCEL_CONFIG, 0x00); # set awake, use gyro x pll clock this.writeRegister(this.MPU6050_REG_PWR_MGMT_1, 0x01); endfunction function inf = info (this) inf = {}; inf.Type = "mpu6050"; inf.SensorId = this.readRegisterU8(this.MPU6050_REG_WHO_AM_I); #inf.Status = this.readRegisterU8(this.BNO055_REG_ACC_ID); endfunction function [C, timestamp] = readTemperature (this) timestamp = time(); C = single(this.readRegisterS16(this.MPU6050_REG_TEMP_OUT_H)) / 340.0 + 36.53; endfunction function [readVal, timestamp] = readAcceleration (this) data = this.readRegister(this.MPU6050_RA_ACCEL_XOUT_H, 6); timestamp = time(); x = typecast(uint16(data(1))*256 + uint16(data(2)), 'int16'); y = typecast(uint16(data(3))*256 + uint16(data(4)), 'int16'); z = typecast(uint16(data(5))*256 + uint16(data(6)), 'int16'); # 2g scale readVal = single([x y z])/16384.0; endfunction function [readVal, timestamp] = readAngularVelocity (this) data = this.readRegister(this.MPU6050_REG_GYRO_XOUT_H, 6); timestamp = time(); x = typecast(uint16(data(2))*256 + uint16(data(1)), 'int16'); y = typecast(uint16(data(4))*256 + uint16(data(3)), 'int16'); z = typecast(uint16(data(6))*256 + uint16(data(4)), 'int16'); # 250 deg/s range readVal = single([x y z])/131.0; endfunction function varargout = read(this) data = readData(this); timestamp = time(); accel = this.readAcceleration(); avel = this.readAngularVelocity(); if nargout <= 2 varargout{1} = struct('Time', timestamp, 'Acceleration', accel, 'AngularVelocity', avel); if nargout > 1 varargout{2} = 0; # no overrun endif else if nargout > 0 varargout{1} = accel; endif if nargout > 1 varargout{2} = avel; endif if nargout > 2 varargout{3} = timestamp; endif if nargout > 3 varargout{4} = 0; # overrun endif endif endfunction function flush(this) # flush currenly does nothing endfunction function disp(this) printf(" %s with properties\n", class(this)); if isobject(this.i2c) printf(" I2CAddress: %d ('0x%s')\n", this.i2c.i2caddress, num2hex(this.i2c.i2caddress)); printf(" Bus: %d\n", this.i2c.bus); else printf(" Not connected"); endif endfunction function release(this) if isobject(this.i2c) delete(this.i2c); this.i2c = []; endif endfunction function delete(this) try if isobject(this.i2c) delete(this.i2c); this.i2c = []; endif catch # do nothing end_try_catch endfunction endmethods methods (Hidden = true) function v = get.I2CAddress (this) v = sprintf("0x%02X", this.i2c.I2CAddress); endfunction function v = get.Bus (this) v = this.i2c.Bus; endfunction endmethods methods (Access = private) function data = readRegister(this, reg, sz) data = readRegister(this.i2c, reg, sz); endfunction function writeRegister(this, reg, data) writeRegister(this.i2c, reg, data); endfunction function value = readRegisterU16(this, reg) data = readRegister(this, reg, 2); value = uint16(data(1))*256 + uint16(data(2)); endfunction function value = readRegisterS16(this, reg) data = readRegister(this, reg, 2); value = uint16(data(1))*256 + uint16(data(2)); value = typecast(value, 'int16'); endfunction function value = readRegisterU8(this, reg) data = readRegister(this, reg, 1); value = uint8(data(1)); endfunction function value = readRegisterS8(this, reg) data = readRegister(this, reg, 1); value = uint8(data(1)); value = typecast(value, 'int8'); endfunction endmethods endclassdef %!error <Expected arduino object as first parameter> mpu6050(1); ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/inst/sensors/si7021.m����������������������������������������������������������������0000644�0000000�0000000�00000020031�14777724260�013753� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019-2022 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. classdef si7021 < handle ## -*- texinfo -*- ## @deftypefn {} {} si7021 ## SI7021 temperature and humidity sensor ## @end deftypefn ## ## @subheading Methods ## @deftypefn {} {@var{obj} =} si7021(@var{arObj}) ## @deftypefnx {} {@var{obj} =} si7021(@var{arObj}, @var{propertyname, propertyvalue} ....) ## Constructor to create si7021 sensor ## @subsubheading Inputs ## @var{arObj} - the arduino parent object ## ## @var{propertyname, propertyvalue} - optional property name, value pairs. ## Current known properties are: ## Current properties are: ## @table @asis ## @item I2Caddress ## I2C address of the si7021 (default 0x40) ## @item Bus ## I2C bus (default 0) ## @end table ## ## @subsubheading Outputs ## @var{obj} - created SI7020 object ## ## @subsubheading Example ## @example ## @code { ## a = arduino() ## sensor = si7021(a) ## } ## @end example ## @end deftypefn ## ## @deftypefn {} {[@var{C}, @var{timestamp}] =} readTemperature(@var{obj}) ## Read the temperature ## ## @subsubheading Inputs ## @var{obj} - the si7021 object ## ## @subsubheading Outputs ## @var{C} - read temperature in deg C. ## ## @var{timestamp} - timestamp when read ## ## @subsubheading Example ## @example ## @code { ## a = arduino() ## s = si7021(a) ## # get temp ## temp = s.readTemperature() ## } ## @end example ## @seealso{si7021} ## @end deftypefn ## ## @deftypefn {} {[@var{relH}, @var{timestamp}] =} readHumidity(@var{obj}) ## Read the relative humidity ## ## @subsubheading Inputs ## @var{obj} - the si7021 object ## ## @subsubheading Outputs ## @var{relH} - relative humidity as a percentage (0 - 100.0) ## ## @var{timestamp} - timestamp when read ## @end deftypefn ## ## @deftypefn {} {[@var{readings}, @var{overrun}] =} read(@var{obj}) ## @deftypefnx {} {[@var{H}, @var{C}, @var{timestamp}, @var{overrun}] =} read(@var{obj}) ## Read the sensor data ## ## @subsubheading Inputs ## @var{obj} - the si2071 sensor object ## ## @subsubheading Outputs ## @var{H} - humidity reading from sensor. ## ## @var{C} - temperature reading from sensor. ## ## @var{timestamp} - timestamp when read ## ## @var{overrun} - overrun flag. ## ## @var{readings} - table structure with fields for Timestamp, Temperature and Humidity. ## @end deftypefn ## ## @deftypefn {} {@var{relH} =} info(@var{dsObj}) ## Read the sensor info ## ## @subsubheading Inputs ## @var{dsObj} - the si7021 object ## ## @subsubheading Outputs ## @var{inf} - structure containing the sensor information. ## ## Structure fields are: ## @table @asis ## @item Version ## Chip firmware version ## @item SensorDd ## sensor id value ## @item Type ## String for detected chip type ## @end table ## ## @end deftypefn ## ## @deftypefn {} {} flush(@var{obj}) ## Flush sensor data ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## None ## @end deftypefn ## ## @deftypefn {} {} release(@var{obj}) ## Release the resources of the sensor ## ## @subsubheading Inputs ## @var{obj} - the sensor object ## ## @subsubheading Outputs ## None ## @end deftypefn properties(Access = private, constant = true) SI7021_CHIPID_1 = [ 0xFA 0xF0 ]; SI7021_CHIPID_2 = [ 0xFC 0xC9 ]; SI7021_VERSION = [ 0x84 0xB8 ]; SI7021_TEMP_MEASURE_NOHOLD = 0xF3; SI7021_HUMIDITY_MEASURE_NOHOLD = 0xF5; endproperties properties(Access = private) i2c; endproperties methods # constructor function this = si7021(parentObj, varargin) if nargin < 1 || ! isarduino(parentObj) error('Expected arduino object as first parameter'); endif # parse args p = inputParser(CaseSensitive=false, FunctionName='arduinosensor.si7021'); p.addParameter('I2CAddress', 0x40, @isnumeric); p.addParameter('Bus', 0, @isnumeric); p.parse(varargin{:}); # do we have the address ? address = p.Results.I2CAddress; bus = p.Results.Bus; #i2caddresses = scanI2Cbus(parentObj); #idx = find(cellfun ( @(x) strcmp(x, sprintf("0x%02X", address)), i2caddresses)); #if isempty(idx) # error('No matching i2c address found on bus'); #endif this.i2c = device(parentObj, "i2caddress", p.Results.I2CAddress, 'bus', bus); endfunction function inf = info (this) write (this.i2c, this.SI7021_CHIPID_1); id1 = read(this.i2c, 1); write (this.i2c, this.SI7021_CHIPID_2); id2 = read(this.i2c, 1); if id2 == hex2dec("15") type = "Si7021"; elseif id2 == hex2dec("14") type = "Si7020"; elseif id2 == hex2dec("0D") type = "Si7013"; elseif id2 == hex2dec("32") type = "HTU21D"; else type = "Unknown"; endif write (this.i2c, this.SI7021_VERSION); ver = read(this.i2c, 1); if ver == hex2dec("FF") ver = 1.0; else ver = double(ver)/10.0; endif inf = {}; inf.Version = ver; inf.Type = type; inf.Sensor = int32(id1)*256 + int32(id2); endfunction function [C, timestamp] = readTemperature (this) % write command to get temp write (this.i2c, uint8([this.SI7021_TEMP_MEASURE_NOHOLD])); timestamp = time(); pause (0.02); data = read (this.i2c, 3); value = uint16(data(1))*256 + uint16(data(2)); value = bitand (value, hex2dec("FFFC")); temp = double(value); C = (175.72*temp/65536)-46.85; endfunction function [H, timestamp] = readHumidity(this) write (this.i2c, uint8([this.SI7021_HUMIDITY_MEASURE_NOHOLD])); timestamp = time(); pause (0.02); data = read (this.i2c, 3); value = uint16(data(1))*256 + uint16(data(2)); value = bitand (value, hex2dec("FFFC")); humidity = double(value); H = (125.0*humidity/65536)-6; endfunction function varargout = read(this) timestamp = time(); C = readTemperature(this); H = readHumidity(this); if nargout <= 2 varargout{1} = struct('Time', timestamp, 'Temperature', C, 'Humidity', H); if nargout > 1 varargout{2} = 0; # no overrun endif else if nargout > 0 varargout{1} = H; endif if nargout > 1 varargout{2} = C; endif if nargout > 2 varargout{3} = timestamp; endif if nargout > 3 varargout{4} = 0; # overrun endif endif endfunction function flush(this) # flush currenly does nothing endfunction function disp(this) printf(" %s with properties\n", class(this)); if isobject(this.i2c) printf(" I2CAddress: %d ('0x%s')\n", this.i2c.i2caddress, num2hex(this.i2c.i2caddress)); printf(" Bus: %d\n", this.i2c.bus); else printf(" Not connected"); endif endfunction function release(this) if isobject(this.i2c) delete(this.i2c); this.i2c = []; endif endfunction function delete(this) try if isobject(this.i2c) delete(this.i2c); this.i2c = []; endif catch # do nothing end_try_catch endfunction endmethods endclassdef %!error <Expected arduino object as first parameter> si7021(1); �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/octave-arduino.metainfo.xml����������������������������������������������������������0000644�0000000�0000000�00000002254�14777724260�015451� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?> <!-- Copyright 2016 Colin B. Macdonald Copyright 2018 John Donoghue Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without any warranty. --> <component type="addon"> <id>octave-arduino</id> <extends>www.octave.org-octave.desktop</extends> <name>Arduino Toolkit</name> <summary>Octave to Arduino interface toolkit</summary> <description> <p>Basic Octave implementation of the matlab arduino extension, allowing communication to a programmed arduino board to control its hardware.</p> </description> <keywords> <keyword>arduino</keyword> <keyword>communication</keyword> </keywords> <url type="homepage">http://octave.sourceforge.net/arduino</url> <url type="bugtracker">https://savannah.gnu.org/bugs/?func=additem&group=octave</url> <project_license>GPL-3.0+</project_license> <developer_name>Octave-Forge Community</developer_name> <update_contact>octave-maintainers@gnu.org</update_contact> <metadata_license>FSFAP</metadata_license> </component> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/test/��������������������������������������������������������������������������������0000755�0000000�0000000�00000000000�14777724260�011162� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/test/make_conf.m���������������������������������������������������������������������0000644�0000000�0000000�00000013510�14777724260�013262� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. #Usage: octave --eval "make_conf('/usr/share/arduino/hardware/arduino/avr/variants/mega/pins_arduino.h')" function retval = make_conf (header_file) if nargin != 1 error ('Expected single input argument of header filename') endif pins = {}; ispwm = {}; isalong = {}; num_digital_pins = 0; num_analog_pins = 0; fd = fopen (header_file, "rt"); while !feof(fd) l = fgetl(fd); [t, m] = regexp(l, '#define\s+(\w+)\s+([^\s]+)$', 'tokens', 'match'); if !isempty(t) toks = t(1){1}; if numel(toks) == 2 if strcmpi(toks{1}, "NUM_DIGITAL_PINS") cnt = strrep(toks{2}, "u", ""); num_digital_pins = str2num(cnt); elseif strcmpi(toks{1}, "NUM_ANALOG_INPUTS") cnt = strrep(toks{2}, "u", ""); num_analog_pins = str2num(cnt); else idx = index(toks{1}, "PIN_"); if idx > 0 name = tolower(strtrim(toks{1}(idx+4:end))); # id have other crap in it ? id = strrep(toks{2}, "u", ""); id = str2num(id); if !isempty(id) # we have pin already ? idx = find (cellfun(@(x) (x.id == id), pins), 1); if isempty(idx) p = []; p.id = id; p.name = sprintf("D%d", id); p.modes = { 'digital' }; pins{end+1} = p; idx = numel(pins); endif if name(1) == 'a' pins{idx}.name = toupper(name); pins{idx}.modes{end+1} = "analog"; elseif strncmp(name, "wire_", 5) pins{idx}.modes{end+1} = ["i2c" name(5:end)]; elseif strncmp(name, "pin_led_", 8) pins{idx}.modes{end+1} = ["led"]; else pins{idx}.modes{end+1} = name; endif endif elseif strcmp(toks{1}, "LED_BUILTIN") id = str2num(toks{2}); if !isempty(id) idx = find (cellfun(@(x) (x.id == id), pins), 1); if isempty(idx) p = {}; p.id = id; p.name = sprintf("D%d", id); p.modes = { 'digital' }; pins{end+1} = p; idx = numel(pins); endif pins{idx}.modes{end+1} = "led"; endif endif endif endif endif [t, m] = regexp(l, '#define\s+digitalPinHasPWM\((\w+)\)\s+(.*)$', 'tokens', 'match'); if ! isempty(t) toks = t(1){1}; if numel(toks) == 2 ispwm.var = toks{1}; testv = strrep(toks{2}, "u", ""); ispwm.test = testv; ispwm = {}; endif endif [t, m] = regexp(l, '#define\s+analogInputToDigitalPin\((\w+)\)\s+(.*)$', 'tokens', 'match'); if ! isempty(t) toks = t(1){1}; if numel(toks) == 2 isanalog.var = toks{1}; testv = strrep(toks{2}, "u", ""); # simple expect analog after digital testv = sprintf("(p + %d)", num_digital_pins); isanalog.test = testv; #isanalog={}; endif endif endwhile fclose(fd); #num_digital_pins #num_analog_pins # fill in any missing digitals for i=0:num_analog_pins-1 name = sprintf("A%d", i); idx = find (cellfun(@(x) (strcmpi(x.name,name)), pins), 1); if isempty(idx) t = sprintf("%s=%i; id=(%s);", isanalog.var, i, isanalog.test); eval(t); if id >= 0 p = {}; p.id = id; p.name = sprintf("A%d", i); p.modes = { 'digital', 'analog' }; pins{end+1} = p; idx = numel(pins); endif endif endfor # fill in any missing digitals for i=0:num_digital_pins-1 idx = find (cellfun(@(x) (x.id == i), pins), 1); if isempty(idx) p = {}; p.id = i; p.name = sprintf("D%d", i); p.modes = { 'digital' }; pins{end+1} = p; idx = numel(pins); endif if !isempty(ispwm) t = sprintf("%s=%i; pwm=(%s);", ispwm.var, i, ispwm.test); eval(t); if pwm pins{idx}.modes{end+1} = "pwm"; endif endif endfor # sort by pin num (id) [tmp ind]=sort(cellfun(@(x) (x.id), pins)); # output file printf ("# configuration generated from %s\n", header_file) printf("function retval = config_XXX (initdata)\n"); printf(" retval = {};\n"); printf("\n"); printf(" # default board info - must be provided\n"); printf(" # will be filled in on connection.\n"); printf(" retval.board = '';\n"); printf(" retval.baudrate = 9600;\n"); printf(" retval.mcu = '';\n"); printf(" retval.voltref = 0;\n"); printf(" retval.libs = {};\n"); printf(" retval.port = '';\n"); printf("\n"); printf(" # info expected to be provided by config.\n"); printf(" retval.description = 'a board description';\n"); printf("\n"); printf(" # pin config\n"); printf(" retval.pins = {};\n"); for i = 1:numel(ind) p = pins{ind(i)}; modes = [ "'" p.modes{1} "'"]; for m = 2:numel(p.modes) modes = [ modes ", '" p.modes{m} "'" ]; endfor printf(" retval.pins{end+1} = arduinoio.config.pin_info('%s', %d, { %s });\n", p.name, p.id, modes); endfor printf("endfunction\n"); endfunction ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/test/test_exampleplugin.m������������������������������������������������������������0000644�0000000�0000000�00000001522�14777724260�015251� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. #arduinosetup ('libraries', 'ExampleAddon/Echo') a = arduino(); b = addon(a, "ExampleAddon/Echo") b.shout("Hello") b.shout("World") ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������arduino-0.12.2/test/test_jig.m����������������������������������������������������������������������0000644�0000000�0000000�00000023541�14777724260�013155� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 ## <https://www.gnu.org/licenses/>. % test_jig % expects a arduino uno to be connected via serial port % with test connections as folows: % arduino - 24XX256 EEPROM chip (i2c) % arduino - mcp3002 10 bit ADC (spi) % arduino - hobby servo % % Connection of arduino to test jig as follows: % Arduino % 24XX256 eeprom % A4 - 5 % A5 - 6 % 5V - 8 % GND - 1,2,3,4 % % Arduino MCP3002 % D10 - 1 (CS) % D11 - 5 (DI) % D12 - 6 (DO) % D13 - 7 (CLK) % VCC - 8 (VDD) % GND - 4 (VSS) % VCC 2 (CH0) - chan 0 input % D2 3 (CH1) - chan 1 input % Servo % Arduino Servo % d9 - signal % VCC - power % gnd - gnd % I/O % Arduino Arduino % A3 - D3 % D4 - D5 % D7 - Not connected % D6 - +10UF cap - GND % A0 - D6 pkg load instrument-control [~, ~, endian] = computer (); unwind_protect printf("1. opening arduino\n"); a = arduino(); if isempty(a) printf("** open failied **\n") endif assert(~isempty(a)) printf("2. I2C tests with EEPROM\n"); eeprom_address = 0x50; printf("* i2c terminals\n") terms = getI2CTerminals(a); if isempty(terms) printf("** getI2CTerminals failed **\n") endif printf("* i2c devices attached\n") devs = scanI2Cbus(a); idx = find(devs = eeprom_address); if isempty(idx) error ('scanI2bus failed - skipping eeprom tests') else printf("* opening i2c...\n"); #i2c = i2cdev(a, eeprom_address); i2c = device(a, "i2caddress", eeprom_address); if isempty(i2c) printf("** i2cdev failed **\n") endif printf("* writing i2c bytes...\n"); # write data to address 0x0000 write(i2c, [0 0 0 1 2 3 4 5 6 7 8 9 10]); # read from address 0x0000, which should now be 0 1 2 3 4 5 6 7 printf("* reading i2c 0000 bytes...\n"); write(i2c, uint8([0 0])); val = read(i2c, 8); if val != uint8([0 1 2 3 4 5 6 7]) printf("byte read/write failed!\n"); endif printf("* reading i2c 0002 bytes...\n"); write(i2c, uint8([0 2])); val = read(i2c, 8); if val != uint8([2 3 4 5 6 7 9 10]) printf("byte read/write failed!\n"); endif printf("* reading i2c 0002 uint16...\n"); write(i2c, uint16([2]), 'uint16'); val = read(i2c, 4, 'uint16'); expected = typecast(uint8([2 3 4 5 6 7 8 9]), 'uint16'); if endian == 'L' expected = swapbytes(expected); endif if val != expected printf("uint16 read failed!\n"); endif printf("* reading i2c 0000 uint16 as register...\n"); val = readRegister(i2c, 0, 2, 'uint16'); expected = typecast(uint8([0 1 2 3]), 'uint16'); if endian == 'L' expected = swapbytes(expected); endif if val != expected printf("read reg16 failed!\n"); endif printf("* reading i2c 0001 uint16 as register...\n"); val = readRegister(i2c, 1, 2, 'uint16'); expected = typecast(uint8([1 2 3 4]), 'uint16'); if endian == 'L' expected = swapbytes(expected); endif if val != expected printf("read reg16 failed!\n"); endif printf("* writing i2c uint16 reg...\n"); writeRegister(i2c, 258, [8 9], 'uint16') printf("* reading i2c 0102 bytes...\n"); write(i2c, uint8([1 2])); val = read(i2c, 4); if val != uint8([0 8 0 9]) printf("byte read/write failed!\n"); endif printf("* reading i2c 0102 uint16 as register...\n"); val = readRegister(i2c, 258, 2, 'uint16'); expected = [8 9]; if val != expected printf("read reg16 failed!\n"); endif clear i2c; endif printf("3. SPI tests with ADC\n"); printf("* opening spi...\n"); #spi = spidev(a, "d10"); spi = device(a, "spichipselectpin", "d10"); if isempty(spi) printf("** spi failed **\n") endif # chan0 printf("* reading spi chan 0...\n"); val = writeRead(spi, [ hex2dec("DF") hex2dec("FF") ]); val = writeRead(spi, [ hex2dec("DF") hex2dec("FF") ]); adc = bitand (uint16(val(1))*256 + uint16(val(2)), hex2dec('3FF')); volts = double(adc) * 5.0 / 1023.0; if volts < 4.5 || volts > 5.0 printf("unexpected voltage ch0 = 0x%04X (adc) %f (volts)\n", adc, volts) endif # chan 1 printf("* reading spi chan 1 low...\n"); writeDigitalPin(a, "d2", 0); val = writeRead(spi, [ hex2dec("EF") hex2dec("FF") ]); adc = bitand (uint16(val(1))*256 + uint16(val(2)), hex2dec('3FF')); volts = double(adc) * 5.0 / 1023.0; if volts > 0.5 printf("unexpected voltage ch1 = 0x%04X (adc) %f (volts)\n", adc, volts) endif printf("* reading spi chan 1 high...\n"); writeDigitalPin(a, "d2", 1); val = writeRead(spi, [ hex2dec("EF") hex2dec("FF") ]); adc = bitand (uint16(val(1))*256 + uint16(val(2)), hex2dec('3FF')); volts = double(adc) * 5.0 / 1023.0; if volts < 4.5 printf("unexpected voltage ch1 = 0x%04X (adc) %f (volts)\n", adc, volts) endif # other SPI tests ?? clear spi printf("4. Digital I/O\n"); printf("* reading analog high to d3...\n"); writeDigitalPin(a, "a3", 1); pause(1); val = readDigitalPin(a, "d3"); if val != 1 printf("unexpected 33 value %d\n", val); endif val = readDigitalPin(a, "a3"); if val != 1 printf("unexpected A3 value %d\n", val); endif printf("* reading analog low to d3...\n"); writeDigitalPin(a, "a3", 0); pause(1); val = readDigitalPin(a, "d3"); if val != 0 printf("unexpected D3 value %d\n", val); endif val = readDigitalPin(a, "a3"); if val != 0 printf("unexpected A3 value %d\n", val); endif printf("* reading digital low to d4...\n"); writeDigitalPin(a, "d4", 0); pause(1); val = readDigitalPin(a, "d4"); if val != 0 printf("unexpected d4 value %d\n", val); endif val = readDigitalPin(a, "d5"); if val != 0 printf("unexpected d5 value %d\n", val); endif printf("* reading digital high to d4...\n"); writeDigitalPin(a, "d4", 1); pause(1); val = readDigitalPin(a, "d4"); if val != 1 printf("unexpected d4 value %d\n", val); endif val = readDigitalPin(a, "d5"); if val != 1 printf("unexpected d5 value %d\n", val); endif printf("5. Analog input\n"); configurePin(a, "d3", "unset"); writeDigitalPin(a, "d3", 0); configurePin(a, "a3", "unset"); pause(1); printf("* reading analog low a3...\n"); val = readAnalogPin(a, "a3"); if val > 200 printf("unexpected a3 value %d\n", val); endif val = readVoltage(a, "a3"); if val > 0.5 printf("unexpected a3 value %f\n", val); endif printf("* reading analog high a3...\n"); writeDigitalPin(a, "d3", 1); pause(1); val = readAnalogPin(a, "a3"); if val < 1000 printf("unexpected a3 value %d\n", val); endif val = readVoltage(a, "a3"); if val < 4.5 printf("unexpected a3 value %f\n", val); endif printf("6. Pullup I/O\n"); printf("* pullup d7...\n"); configurePin(a, "d7", "pullup"); val = readDigitalPin(a, "d7"); if val != 1 printf("unexpected d7 value %d\n", val); endif # analog output /PWM printf("7. Analog Output\n"); printf("* pwm duty cycle 0...\n"); writePWMDutyCycle(a, "d6", 0); pause(1); val = readVoltage(a, "a0"); if val > 0.1 printf("unexpected a0 value %f\n", val); endif printf("* pwm duty cycle 1...\n"); writePWMDutyCycle(a, "d6", 1); pause(1); val = readVoltage(a, "a0"); if val < 4.5 printf("unexpected a0 value %f\n", val); endif printf("* pwm duty cycle 0.5...\n"); writePWMDutyCycle(a, "d6", 0.5); pause(1); val = readVoltage(a, "a0"); if val < 2.0 || val > 3.0 printf("unexpected a0 value %f\n", val); endif printf("* pwm voltage 0...\n"); writePWMVoltage(a, "d6", 0.0); pause(1); val = readVoltage(a, "a0"); if val > 0.2 printf("unexpected a0 value %f\n", val); endif printf("* pwm voltage 5...\n"); writePWMVoltage(a, "d6", 5.0); pause(1); val = readVoltage(a, "a0"); if val < 4.5 printf("unexpected a0 value %f\n", val); endif printf("* pwm voltage 3...\n"); writePWMVoltage(a, "d6", 3.0); pause(1); val = readVoltage(a, "a0"); if val < 2.4 || val > 4.0 printf("unexpected a0 value %f\n", val); endif # TODO: servo printf("8. Servo\n"); printf("* create servo...\n"); s = servo(a, "d9", 'MinPulseDuration', 1e-3, 'MaxPulseDuration', 2e-3); if isempty(s) printf("** servo failied **\n") endif printf("* go min pos...\n"); writePosition(s, 0); val = readPosition(s); if val != 0 printf("invalid position %f\n", val); endif printf("* scan pos...\n"); for pos = [0:.01:1] writePosition(s, pos); pause(0.02); endfor printf("* go max pos...\n"); writePosition(s, 1); val = readPosition(s); if val != 1 printf("invalid position %f - expected %f\n", val, 1); endif printf("9. LEDS\n"); printf("* get pins...\n"); leds = getPinsFromTerminals(a, getLEDTerminals(a)); if isempty(leds) printf("no LED pins"); endif printf("* set leds 0\n"); for i = [1:1:numel(leds)] pin = leds{i}; configurePin(a, pin, "unset"); writeDigitalPin(a, pin, 0) endfor pause(2); printf("* set leds 1\n"); for i = [1:1:numel(leds)] pin = leds{i}; writeDigitalPin(a, pin, 1) endfor pause(2); printf("* set leds 0\n"); for i = [1:1:numel(leds)] pin = leds{i}; writeDigitalPin(a, pin, 0) endfor unwind_protect_cleanup clear a end_unwind_protect ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������