Showing preview only (4,412K chars total). Download the full file or copy to clipboard to get everything.
Repository: SolidSoils/Arduino
Branch: master
Commit: 984f578267df
Files: 514
Total size: 4.1 MB
Directory structure:
gitextract_0siuikil/
├── .gitattributes
├── .gitignore
├── Documentation/
│ └── Documentation.shfbproj
├── LICENSE.md
├── README.md
├── Solid.Arduino/
│ ├── ArduinoSession.cs
│ ├── EnhancedSerialConnection.cs
│ ├── EnhancedSerialPort.cs
│ ├── Firmata/
│ │ ├── AnalogPinMapping.cs
│ │ ├── AnalogState.cs
│ │ ├── AnalogStateTracker.cs
│ │ ├── BoardAnalogMapping.cs
│ │ ├── BoardCapability.cs
│ │ ├── ByteArrayExtensions.cs
│ │ ├── DigitalPortState.cs
│ │ ├── DigitalStateTracker.cs
│ │ ├── FirmataMessage.cs
│ │ ├── FirmataMessageEventArgs.cs
│ │ ├── FirmataMessageEventArgs_.cs
│ │ ├── Firmware.cs
│ │ ├── IFirmataProtocol.cs
│ │ ├── PinCapability.cs
│ │ ├── PinState.cs
│ │ ├── ProtocolVersion.cs
│ │ ├── Servo/
│ │ │ └── IServoProtocol.cs
│ │ ├── StringData.cs
│ │ └── SysExCommand.cs
│ ├── I2c/
│ │ ├── I2cEventArgs.cs
│ │ ├── I2cReply.cs
│ │ ├── I2cReplyTracker.cs
│ │ └── II2cProtocol.cs
│ ├── ISerialConnection.cs
│ ├── IStringProtocol.cs
│ ├── Messages.Designer.cs
│ ├── Messages.resx
│ ├── ObservableEventTracker.cs
│ ├── ReceivedStringTracker.cs
│ ├── SerialBaudRate.cs
│ ├── SerialConnection.cs
│ ├── SerialPortFixer.cs
│ ├── Solid.Arduino.csproj
│ ├── Solid.Arduino.xml
│ ├── StringEventArgs.cs
│ └── StringExtensions.cs
├── Solid.Arduino.IntegrationTest/
│ ├── HC06-Bluetooth.ino
│ ├── SerialConnectionTester.cs
│ ├── SerialReply.ino
│ ├── SocketConnectionTester.cs
│ └── Solid.Arduino.IntegrationTest.csproj
├── Solid.Arduino.Run/
│ ├── Program.cs
│ └── Solid.Arduino.Run.csproj
├── Solid.Arduino.Test/
│ ├── ArduinoSessionTester.cs
│ ├── ByteArrayExtensionsTester.cs
│ ├── DigitalPortStateTester.cs
│ ├── EnhancedSerialConnectionTester.cs
│ ├── ExceptionMonitor.cs
│ ├── I2cProtocolTester.cs
│ ├── IFirmataProtocolTester.cs
│ ├── IServoProtocolTester.cs
│ ├── IStringProtocolTester.cs
│ ├── MockSerialConnection.cs
│ ├── ObservableArduinoSessionTester.cs
│ ├── SerialConnectionTester.cs
│ ├── Solid.Arduino.Test.csproj
│ └── StringExtensionsTester.cs
├── Solid.Arduino.sln
├── _config.yml
└── docs/
├── SearchHelp.aspx
├── SearchHelp.inc.php
├── SearchHelp.php
├── Solid.Arduino.xml
├── SolidSoils4Arduino.chm
├── Web.Config
├── WebKI.xml
├── WebTOC.xml
├── fti/
│ ├── FTI_100.json
│ ├── FTI_101.json
│ ├── FTI_102.json
│ ├── FTI_103.json
│ ├── FTI_104.json
│ ├── FTI_105.json
│ ├── FTI_108.json
│ ├── FTI_109.json
│ ├── FTI_110.json
│ ├── FTI_111.json
│ ├── FTI_112.json
│ ├── FTI_113.json
│ ├── FTI_114.json
│ ├── FTI_115.json
│ ├── FTI_116.json
│ ├── FTI_117.json
│ ├── FTI_118.json
│ ├── FTI_119.json
│ ├── FTI_97.json
│ ├── FTI_98.json
│ ├── FTI_99.json
│ └── FTI_Files.json
├── html/
│ ├── 0010e8c6-eb36-7d91-486f-57a208faeca8.htm
│ ├── 002fd01e-b970-b699-d1ab-402342ab2dec.htm
│ ├── 00b485cd-b70e-e463-f9aa-ba11cee21ff7.htm
│ ├── 00e5bd9e-f9ab-5194-8375-b9fbf1f0161e.htm
│ ├── 012dd994-5a18-29df-21ef-6f6e228030c9.htm
│ ├── 01aaeb2a-fd21-bbd7-2dc2-9e6597c264d4.htm
│ ├── 03dc5f50-ca95-43b1-418c-d8465fb55383.htm
│ ├── 04428aca-6102-c5fd-3222-18c2e545b0e8.htm
│ ├── 0456bfc8-b008-c8a3-77ad-0bfefc1310cb.htm
│ ├── 05b14b65-ca9d-7ff2-68b7-f70d7cfcc100.htm
│ ├── 05b5327f-d814-405f-e2bd-e56a351a861e.htm
│ ├── 07dc3d59-f60a-0e42-9042-3bb4ac8f9137.htm
│ ├── 08af42a6-bb1e-b13e-b90d-ac47e8583dd9.htm
│ ├── 0cace141-f273-7ad7-d632-31e0ff0815fb.htm
│ ├── 0cc5ebbb-9d0b-0d4e-0b8a-59b7c490f7bd.htm
│ ├── 0cd4e1e3-e5af-40f1-dc97-f2f08fb64119.htm
│ ├── 0ce955e9-de04-3300-073d-2932518e0070.htm
│ ├── 0db70497-3543-ccc9-2141-40d1fd170c64.htm
│ ├── 0e0528df-22b4-60f2-8cc6-9c7e3d140d01.htm
│ ├── 0ea9cbae-1535-ba11-3134-4520d69334f0.htm
│ ├── 0eb18a1c-9837-d7d9-6e0d-f201303effe6.htm
│ ├── 0f03b0e7-a914-e46b-c2d6-e0bed40eac37.htm
│ ├── 10dde3c8-66dc-d300-0d82-de410352094d.htm
│ ├── 11348d42-72bd-635f-c392-da90b6c27daa.htm
│ ├── 119049c4-1ba0-964e-94c7-cfc08e55a37a.htm
│ ├── 12415ea1-5b04-0b26-d464-d851efbbce73.htm
│ ├── 1251dc84-c748-62a3-d876-c92c0cab97c6.htm
│ ├── 1685f037-3a5d-6004-7e2c-c72f2c403fed.htm
│ ├── 17a49847-9f5e-41b4-a84a-1bb15979af70.htm
│ ├── 17eed47b-8bf5-ea44-13cd-722e37bb68c9.htm
│ ├── 183523fa-f6c5-0635-d6ba-336781e21c95.htm
│ ├── 1a181c03-5d41-d3a2-e280-049cad8d349a.htm
│ ├── 1c02d293-4876-a918-1b8e-c84637cd0860.htm
│ ├── 1c2dd961-3134-4b2a-ab4d-c8025ab4cfe1.htm
│ ├── 1cd0d237-552e-0958-a3ef-7dec5153ffa3.htm
│ ├── 1e2164e0-907c-a688-2f86-07d7ba8e85ae.htm
│ ├── 1f020e05-4452-f270-4785-162fd272270d.htm
│ ├── 1fa615e5-a5c8-2d2c-fa47-0e38434c27c8.htm
│ ├── 209690c4-2404-13af-d697-d0889345d94e.htm
│ ├── 21bb8dd6-fb5d-9c2d-ffca-f536c5533d6a.htm
│ ├── 2387accb-7f3f-aff7-0482-b5a6bc2fdaee.htm
│ ├── 2396779a-20f5-49b8-2a1b-ad7d188cde76.htm
│ ├── 23a2c9b4-3a0c-9075-c87f-a4fc4d89c978.htm
│ ├── 24763d00-2f5b-09be-8ace-29f24895ed1b.htm
│ ├── 25858b6c-f545-022f-1421-1980e7d2f9ec.htm
│ ├── 26b1753d-4f47-ecdb-98fb-1c150eb3ca88.htm
│ ├── 280d4128-f443-8cf2-6a53-33e6e7eb5e4e.htm
│ ├── 29676853-5f19-d961-917d-d2a3b1005bc2.htm
│ ├── 2bd00801-6ea4-9aeb-869f-6be672f4b934.htm
│ ├── 2c665003-8e12-9549-f318-997e33c1766b.htm
│ ├── 2cf2e931-e0e8-d47d-aaa6-73cc82ef2e55.htm
│ ├── 2e643178-1fcf-6971-d9c1-921734b7c710.htm
│ ├── 2f361478-0a2b-cf8c-c0b5-c347820086fe.htm
│ ├── 30b16045-d369-9612-cb2a-2f396b746a9d.htm
│ ├── 3198d1e7-848f-41e3-6b13-1e23f6eaaadd.htm
│ ├── 32c1b709-03cf-fa67-24d3-12552bab13dd.htm
│ ├── 335a34f6-a012-4732-1fea-87527cebbecd.htm
│ ├── 3370b8dd-d792-b2c8-df67-f542ff674ba9.htm
│ ├── 34435006-8185-e827-453f-bcf4043b59e3.htm
│ ├── 35350d0e-6fa0-0a27-7b7d-57a59840cdea.htm
│ ├── 35d22925-210f-956e-92b6-12c95fedddaa.htm
│ ├── 3695c805-d9b7-b3e6-32be-183a64f8873a.htm
│ ├── 36b30020-3a33-da99-478f-3806990dcf90.htm
│ ├── 36d82773-9fd2-223a-44bd-acbc25407dda.htm
│ ├── 36e366e7-eeb4-cfe5-dc07-3978cb22ce94.htm
│ ├── 3840dfdb-97e9-882b-796e-9ad6e28ea2a1.htm
│ ├── 3a2ac349-bf62-313a-9f20-4c7c3932b60a.htm
│ ├── 3a4802af-ada6-81eb-0d1a-ca7c114653cf.htm
│ ├── 3a711afe-a630-a052-9ad9-87bd4345613b.htm
│ ├── 3bcf8a5b-b062-5af3-2db8-15cf583f2f31.htm
│ ├── 3cfbfb3e-5b55-59d8-2a64-d298cca31bde.htm
│ ├── 3d0a9909-c581-51c4-1343-950e2653b152.htm
│ ├── 3d50005b-be1d-3245-76c1-a4e60bcd5c18.htm
│ ├── 3e9fb5e9-92dc-8797-9059-3f3a27da6673.htm
│ ├── 3eeb99eb-b6d7-85a1-0001-29f3c220b63a.htm
│ ├── 3f24f883-ede8-64a4-fdd9-f73ddadc6c6c.htm
│ ├── 407075b2-2a77-655b-0bb4-fb45ded42876.htm
│ ├── 40d05494-2f3b-10bd-1fdb-485097690ee9.htm
│ ├── 42b47bc8-9e23-e9db-a8db-1972173530f1.htm
│ ├── 43733aea-c265-b3e4-c53b-17a82b3360b0.htm
│ ├── 43e2abd9-863a-2f7e-aabc-f0c145bb4d29.htm
│ ├── 449f192e-e39e-4f35-d4bd-fd8fd14ef6ad.htm
│ ├── 4622e83d-5f7a-6c28-8838-b7bda56a96fd.htm
│ ├── 473706ce-6549-acda-7330-ee8597293463.htm
│ ├── 48a1f3a8-4ebd-f887-9042-461476ec06e1.htm
│ ├── 4a772778-1995-b7b1-fec3-19dda6d127f9.htm
│ ├── 4b09c588-2b2a-300c-db9d-4567209dba1d.htm
│ ├── 4b854918-3dfc-0e52-8333-edc9d7d419fb.htm
│ ├── 4be8895c-9e74-2785-cce2-fc78782aa936.htm
│ ├── 4c9c15c4-eda9-59d4-8a15-8d789489f0aa.htm
│ ├── 4ec15f56-5d16-3f8b-7f74-a535d3698537.htm
│ ├── 4fc6a36d-12cb-113e-4379-c04f55226882.htm
│ ├── 505b8bcb-2c04-8a59-85ee-f86d7a81133c.htm
│ ├── 50af8943-91c9-96fc-307d-423c066c5933.htm
│ ├── 51289ed1-279a-240e-f276-9147c12f6217.htm
│ ├── 524203d1-c389-0f63-fa4a-616459b7b0e2.htm
│ ├── 52906872-565e-78c6-6f2c-cfd646f7e3d4.htm
│ ├── 542fd7a2-0004-6425-e123-87277c6662cc.htm
│ ├── 5560f824-7c26-030f-a351-7a43f48d3616.htm
│ ├── 55aa38a0-1f7a-ec22-10d8-8bae26960810.htm
│ ├── 55c86eb1-5578-8ae0-dd84-5582fa070efe.htm
│ ├── 569db704-90d1-483e-ace7-0ccba57549c5.htm
│ ├── 56d39bd9-c75f-545e-3b10-d8bc999931d1.htm
│ ├── 580f8ee8-6e40-6d26-8290-6b7b75def84f.htm
│ ├── 5a3e57ca-2a41-36d6-d0a8-f413e253efc6.htm
│ ├── 5a68ef5b-372d-e6ea-0c35-79d60143c238.htm
│ ├── 5a9a83eb-057c-1b58-f5ca-4c8149729116.htm
│ ├── 5d246b79-ab99-fb9d-d02f-6af063d1fa6c.htm
│ ├── 5da15ad8-5869-11b4-3347-2390a0333c45.htm
│ ├── 60dd3c0d-a640-05d4-db8d-c2637f7f2b39.htm
│ ├── 60de7d10-c386-9961-e219-777be8815603.htm
│ ├── 6192a41b-b08d-c9b4-3907-2b945d8fcf80.htm
│ ├── 62d13dd3-f1d7-9949-5659-a07a902efa91.htm
│ ├── 63516731-32a5-c7a6-6170-f8a002200d8c.htm
│ ├── 65ff277a-8063-787e-af75-87fa326a97b7.htm
│ ├── 66d7d0c0-44ca-0d27-5596-1957f0c526a4.htm
│ ├── 66ebce33-e458-872b-5952-866144b9ada0.htm
│ ├── 66f3d7c2-96b2-9c5e-65be-7d2071ec8f9b.htm
│ ├── 6871db6c-e61a-84b5-0ca6-4c240f90fde0.htm
│ ├── 68b42756-a237-c7e8-a3f7-267ca18734b8.htm
│ ├── 69e1e3a3-9710-3929-5a04-6ee7a1e68c3a.htm
│ ├── 6a12da48-72f2-3808-70bd-2c02bfde97d7.htm
│ ├── 6a423ec2-dfae-7237-31d4-736018091ea0.htm
│ ├── 6b3d5d48-0b4d-3b8d-e13f-9648aa1e9723.htm
│ ├── 6bc5ef18-fb9b-7465-3576-f2fcc3b30b44.htm
│ ├── 6bdc660a-cd9d-455a-7908-b6d762c1d8af.htm
│ ├── 6c5bac35-ce3a-6988-f1ab-557b5c8c89ef.htm
│ ├── 6cb87d56-cba5-8b38-17aa-047743f53227.htm
│ ├── 6cd07b17-b3e8-55c6-ec51-b4294f445a2d.htm
│ ├── 6d15bb99-b68e-873c-6c87-e374f6ded979.htm
│ ├── 6d552a41-b41f-9fab-d4ce-41d17f28dfc1.htm
│ ├── 6df4dbc0-c70e-59f8-73ff-a15849692f52.htm
│ ├── 6e591dea-0a75-7d0f-6de5-09ca0069e873.htm
│ ├── 6fa948b9-48cd-ec3b-47c3-b25d3b1a85dc.htm
│ ├── 6ff6011b-6cc8-7f93-8265-dbc3a1df4666.htm
│ ├── 700edc62-50ef-619d-5d88-1907d15ce4ab.htm
│ ├── 70512b72-78fb-5a4a-8fbd-8c01ff72fb9e.htm
│ ├── 70740235-9698-52af-7cd1-614f7550f80b.htm
│ ├── 712af620-4f36-ce65-1d71-1af90ef6e16a.htm
│ ├── 72c4ea1b-c375-10ed-d9f6-9f5bba287781.htm
│ ├── 72f7cd86-5a81-b6fb-50cb-a849074a1f87.htm
│ ├── 747853e5-c5f4-7ae4-6956-be594e9df208.htm
│ ├── 7619d119-9fb4-a181-7523-07273f09e83b.htm
│ ├── 76f722a5-1f41-3369-469a-50225dc7f079.htm
│ ├── 7a82d399-3fe1-048e-ecb1-00b55cbfaba0.htm
│ ├── 7b2ad63d-78ca-4a9b-7bf8-2a3619d8ae78.htm
│ ├── 7c606b90-720d-be95-c43d-4a18e8cb2ccc.htm
│ ├── 7cb762fd-74b7-2119-6570-82592544a596.htm
│ ├── 7fbb1bc0-5346-9adb-23ca-afde8a1cda88.htm
│ ├── 8164731e-9412-adab-9432-1fa0a03aa01d.htm
│ ├── 82864edc-a8c0-fb1e-c8d2-f70b564a089f.htm
│ ├── 82a6b8d0-f606-38df-3050-7192e8c47e61.htm
│ ├── 830f17c7-c111-019a-9c23-522994fd13a3.htm
│ ├── 87c96f49-ef19-0f8c-a88d-27cb504c1ffa.htm
│ ├── 8b6e7069-faa8-05a2-21cd-e6bee8fa1578.htm
│ ├── 8c1d05f9-9974-d9ee-4b69-cbd727d46d5f.htm
│ ├── 8cbb0e35-0dba-781e-d204-2a9d4ea3c191.htm
│ ├── 8ce35937-c031-c897-3338-d93fc03adfaa.htm
│ ├── 8dbe1dc8-266a-4668-ee8a-1fd53d220651.htm
│ ├── 8e596088-4f9e-1214-eb48-e8369d8d3277.htm
│ ├── 90348614-3a75-cec2-bea4-b5847353f958.htm
│ ├── 9196cfe1-64f6-4623-a1c0-a941ecd8c7c7.htm
│ ├── 92bd2ded-5ae5-cfc1-8eb7-f68e747845ca.htm
│ ├── 98ce7e9b-a9d6-7c3f-04f1-2da2a06944e6.htm
│ ├── 990ca6d1-4785-c37c-0a9d-5db6af732336.htm
│ ├── 9c1284e9-e336-1648-c7a6-e2d50005ccb3.htm
│ ├── 9d307145-50e5-2464-e284-b13666d1b1eb.htm
│ ├── 9d6a2465-15ed-a5da-5353-5e0073c7e9a1.htm
│ ├── 9e51c12b-d4aa-b3dc-5578-3081a2bb752f.htm
│ ├── 9eccbac6-fe16-acb8-6b8c-643606251dda.htm
│ ├── 9eda75cf-38c6-c8fd-826b-0d151e3dfc8b.htm
│ ├── 9eea4668-107b-8de8-59e3-22aa6c969ea0.htm
│ ├── 9f48a138-2814-e12f-3ec6-bcb2fc457a47.htm
│ ├── 9fdf1328-d5a8-08a6-692e-00088ef146b7.htm
│ ├── GeneralError.htm
│ ├── PageNotFound.htm
│ ├── a04d813f-23c5-6fc3-bc98-55d2c67527cf.htm
│ ├── a14876ac-b585-07c6-75dd-a0b2c5ce64fe.htm
│ ├── a2213ce7-3ec9-981b-062f-5b90e71d9ef0.htm
│ ├── a24a6f37-2514-e037-21c6-52cf6f7da1ce.htm
│ ├── a322471f-ebc5-8cdb-40f4-a9fa07e0e64f.htm
│ ├── a357a146-da10-d1c5-6dbe-293d4072e351.htm
│ ├── a53a9e81-536d-aec6-959d-32e03a3a7888.htm
│ ├── a5aa12b2-f49e-5944-919e-f689fca5e38c.htm
│ ├── a6c005fe-f1fb-c257-4693-5dd2ccf4a508.htm
│ ├── a761b35c-6058-6fce-044e-7204c140e2f9.htm
│ ├── a7c3cac8-d32c-cfa4-b82d-a575dbbff983.htm
│ ├── a814f7b1-656c-0782-6d3f-be715b415a1d.htm
│ ├── a82bbc27-df2a-11fe-7060-d460e274a7fd.htm
│ ├── a8b5fb3d-a1eb-e372-c1a5-228efd902dd6.htm
│ ├── ab95f6d2-30cf-24bf-a427-621540e1cc36.htm
│ ├── acc5321a-11b6-194d-9978-a32b2a7ec2a3.htm
│ ├── ad6eda66-4832-2efc-b3c0-55e7c8ef7ba4.htm
│ ├── ae1ba7d3-433e-fd72-3f50-1a8ec37aa5f4.htm
│ ├── ae47b3db-c68e-3be4-8385-2321b8963662.htm
│ ├── af48914f-fe94-9752-7573-db5edf2b7fd9.htm
│ ├── af66df3c-8f61-d237-0415-a240644ebb01.htm
│ ├── b22cca88-7580-d134-a7be-c45c7d9c8be2.htm
│ ├── b35dd5f1-998f-89d6-dad2-e05be835d949.htm
│ ├── b45c02d5-d804-8090-5057-0b3e3cbc19a0.htm
│ ├── b5ad6c4c-2609-706b-f56b-547ace8e1dee.htm
│ ├── b64f5e5c-6d8a-0177-8932-f59e1971c505.htm
│ ├── b68dd438-ddc6-b2f7-4a92-8396c448faf5.htm
│ ├── b74ea0f2-07f1-a01d-83c7-d8830d90e57d.htm
│ ├── b82a5fcb-a39d-b771-11ed-ae23c755838f.htm
│ ├── b8f2dc6f-68a0-31f3-6a5b-55042ad516ed.htm
│ ├── ba11da02-35ff-5b18-068e-812d1f92f7df.htm
│ ├── bb27603a-6a4d-9e7c-1cc2-a08ee8ef4109.htm
│ ├── bb8ee71c-0808-feda-2e0a-4b05fc986980.htm
│ ├── bcbabe45-8718-bce0-5974-bae720038d00.htm
│ ├── bcee4a6a-47c8-e1cb-621c-2f876839efd6.htm
│ ├── bd23b31c-aa0c-ec47-793e-36bb05f1ac59.htm
│ ├── be39b34a-20e0-0491-49a7-5a456eef0133.htm
│ ├── be43753c-2f1b-03df-9e55-56be16980d27.htm
│ ├── bf222e0f-2117-7a4d-78cb-0a8e02803aa8.htm
│ ├── c0168d33-3fbb-d636-6455-d1e6d811596e.htm
│ ├── c0169464-5e8c-4c99-0d22-2997afa6d642.htm
│ ├── c016e57d-a1aa-1502-b266-eac555320bd8.htm
│ ├── c1885039-892e-e2b5-0fa0-96da02a925c3.htm
│ ├── c1bf57a5-40dc-a8d6-1e15-b48884f5892b.htm
│ ├── c231898c-c0fd-8636-cd01-91e62005ca68.htm
│ ├── c3c646da-8314-4fd5-f46e-5f8fd1d5730b.htm
│ ├── c482d8a0-7998-bb79-5e92-1376e076a5de.htm
│ ├── c4d800a5-a5de-dc32-6725-c24ca5b6b07f.htm
│ ├── c6965049-109b-ccc8-ab08-add00fa5fe2d.htm
│ ├── c7bdc16d-4098-6768-85e3-0b449ad30c1f.htm
│ ├── c7cb67b3-109d-5722-69ed-5ac3b5fdbc0e.htm
│ ├── c7f31e4f-9f61-353e-7a50-70a068be8196.htm
│ ├── c88283e6-8a6d-e7e4-3a38-9c343e31d7cf.htm
│ ├── ca00d61b-80d6-3c26-6474-e9592a8cd67b.htm
│ ├── cab481d4-3500-53ac-365e-cbf3f4131689.htm
│ ├── cac50def-a782-0642-1a3e-e95e2679c778.htm
│ ├── cad99045-36ff-2d40-f881-6d9616efe8f0.htm
│ ├── cc033925-07e6-b137-a60c-6ffb2f4afb99.htm
│ ├── ce05c987-6053-fb21-59f1-0c83c611e513.htm
│ ├── cf70a8e1-e4eb-2183-4c35-df109d3d7818.htm
│ ├── cf75ec9d-e7a8-37cb-f0f2-4bf4f0279cd5.htm
│ ├── cfafcb67-8636-fcae-c56c-aad4f2241248.htm
│ ├── d1d06fd1-3384-00fc-2611-25539b67b954.htm
│ ├── d1f00718-36e3-c0a5-bf63-061a713f4bd2.htm
│ ├── d1faec22-b4a8-57d4-8509-fc1e35b530b0.htm
│ ├── d205b57d-0a11-6b7d-ceab-edfecfd42975.htm
│ ├── d28eb91b-bf62-51fa-e18e-c4a417be7337.htm
│ ├── d298d81b-b8d3-69e1-1d56-b27dd784823e.htm
│ ├── d2d31ad9-8abb-b53a-7417-7720b259e979.htm
│ ├── d47ffb57-0449-9050-402b-fd4b77b8ce85.htm
│ ├── d574222f-0884-4d82-406d-598e7e49b9ca.htm
│ ├── d5b7f09a-bd5a-8bfd-17c4-218040fe6a3e.htm
│ ├── d6753490-3f4c-d5df-cc50-3cd0a2fbb98e.htm
│ ├── d7e6400a-af87-1003-be8a-a9effb1b622a.htm
│ ├── d806a0fd-cda7-50ff-ec75-63821e97ea83.htm
│ ├── d896819b-a4b3-fafe-2a40-ad78fd8303c4.htm
│ ├── d8f33960-4595-c5e9-ce95-7e4193308d98.htm
│ ├── da17a595-dd19-6c94-c319-ba92780ff1b1.htm
│ ├── dafbf808-d45b-fe61-dfe2-6d1930d50f81.htm
│ ├── db417185-54cd-7eef-2cf0-cb2d7474cff2.htm
│ ├── dc621830-82ae-2687-3604-92d7fefcbc76.htm
│ ├── dd9bc9ad-239f-96e9-955d-5d82260ce525.htm
│ ├── dea5e843-06a7-db5d-8213-d6778ec8243d.htm
│ ├── deaf5148-850e-a69d-5c63-5a1a7264006c.htm
│ ├── deb6bbbc-361f-e1fa-1a28-944836557e27.htm
│ ├── df0364a4-478b-4057-055f-90c0cdf91e0c.htm
│ ├── dffc6c6c-da1a-0e05-486a-66c89481c970.htm
│ ├── e0096895-6dd0-6b06-703d-ccd773068601.htm
│ ├── e100ef8b-93b9-5cb8-5f77-ba3c6992a598.htm
│ ├── e10b3718-42ae-bdb7-e8c5-8fda7d054d52.htm
│ ├── e159fcbc-2053-31ec-dcaa-c3583d88b072.htm
│ ├── e1637911-8e22-f5a6-46a8-f22a852f09b0.htm
│ ├── e2c9ceb2-6c34-7bb9-f1d7-041270a1088f.htm
│ ├── e3237dff-8b9e-7ddf-ff84-7c62943af619.htm
│ ├── e32ad933-56c4-059c-fcf5-99ea235b80b6.htm
│ ├── e3624fc2-b4fb-895d-3b74-40390ea3994d.htm
│ ├── e4216de2-ac9b-991f-ff65-6465c0dca53d.htm
│ ├── e5ea2b24-4ddf-bc82-32fe-c787c3e974b8.htm
│ ├── e65a4995-c3ff-c6e1-ee8b-b5d5c2b3f7b2.htm
│ ├── e6bd7820-438b-49a9-5605-ed00a5e9caea.htm
│ ├── e75af7f2-45fb-5ecf-4f9e-41e596e9f453.htm
│ ├── e82cd517-dc93-1d39-8d56-50744a6a3193.htm
│ ├── e8c9a889-19bc-c8cd-34c1-6912de66612c.htm
│ ├── eb1339b7-b6a8-a213-53c8-70fdd94961fc.htm
│ ├── ebf2f037-d888-6733-6882-3faf1f3e6952.htm
│ ├── ec6875fc-d3d0-99bd-0300-cbe303b3ab73.htm
│ ├── ecad3166-5f2c-2fd8-b94c-de688c02211e.htm
│ ├── ecf46ad6-5296-888e-e4ab-149e15fc50e3.htm
│ ├── ed3c9749-6890-8dc7-f108-7da5fb5ebcaa.htm
│ ├── ed8f32fc-eda4-0426-1a15-4eeb15460ec8.htm
│ ├── edd086d3-b73e-a9c8-583a-728b34baf2b4.htm
│ ├── f0277d7f-20e7-7d21-7723-eff6a7d07f49.htm
│ ├── f0983913-5110-b3fc-40ac-31e1d74e3e11.htm
│ ├── f0ad8da5-0e56-8c1e-74a0-29953ad98f99.htm
│ ├── f2343bf9-88ac-78c3-a6fe-965b78aeaafe.htm
│ ├── f322eee0-b2a6-0288-20a1-9379975c4ccd.htm
│ ├── f3a69b92-0354-52fc-b2c3-8f442702ea51.htm
│ ├── f3b51430-f6ad-bc63-f4a8-1afd7b7c2a85.htm
│ ├── f5861e12-17f7-6986-f198-a79101b9a107.htm
│ ├── f677cae4-0b7e-0f2f-a248-5fa2f0281327.htm
│ ├── fa14ff3e-0df7-c3fa-7383-e4e0f123567a.htm
│ ├── fbb61933-2aad-26b0-f4ef-a12c45469c8f.htm
│ ├── fc3e09de-f376-65f7-47b1-60c2511a5acd.htm
│ ├── fcc98eb4-51e1-b53e-5338-964284c91981.htm
│ ├── fccc0a99-97e3-0285-7073-e3b2d3aa43cf.htm
│ ├── fdfbef58-1137-cab4-864a-66bcdc536cab.htm
│ ├── fea98ee5-d17a-e9c6-54f5-db262d481cd4.htm
│ └── fecece2f-667b-dda0-f43c-d33ef4c15171.htm
├── index.html
├── scripts/
│ ├── branding-Website.js
│ └── branding.js
├── search.html
├── styles/
│ ├── branding-Help1.css
│ ├── branding-HelpViewer.css
│ ├── branding-Website.css
│ ├── branding-cs-CZ.css
│ ├── branding-de-DE.css
│ ├── branding-en-US.css
│ ├── branding-es-ES.css
│ ├── branding-fr-FR.css
│ ├── branding-it-IT.css
│ ├── branding-ja-JP.css
│ ├── branding-ko-KR.css
│ ├── branding-pl-PL.css
│ ├── branding-pt-BR.css
│ ├── branding-ru-RU.css
│ ├── branding-tr-TR.css
│ ├── branding-zh-CN.css
│ ├── branding-zh-TW.css
│ └── branding.css
└── toc/
├── 0456bfc8-b008-c8a3-77ad-0bfefc1310cb.xml
├── 05b14b65-ca9d-7ff2-68b7-f70d7cfcc100.xml
├── 0ea9cbae-1535-ba11-3134-4520d69334f0.xml
├── 0f03b0e7-a914-e46b-c2d6-e0bed40eac37.xml
├── 10dde3c8-66dc-d300-0d82-de410352094d.xml
├── 11348d42-72bd-635f-c392-da90b6c27daa.xml
├── 1685f037-3a5d-6004-7e2c-c72f2c403fed.xml
├── 17a49847-9f5e-41b4-a84a-1bb15979af70.xml
├── 1c02d293-4876-a918-1b8e-c84637cd0860.xml
├── 25858b6c-f545-022f-1421-1980e7d2f9ec.xml
├── 280d4128-f443-8cf2-6a53-33e6e7eb5e4e.xml
├── 29676853-5f19-d961-917d-d2a3b1005bc2.xml
├── 2c665003-8e12-9549-f318-997e33c1766b.xml
├── 2cf2e931-e0e8-d47d-aaa6-73cc82ef2e55.xml
├── 2e643178-1fcf-6971-d9c1-921734b7c710.xml
├── 2f361478-0a2b-cf8c-c0b5-c347820086fe.xml
├── 3198d1e7-848f-41e3-6b13-1e23f6eaaadd.xml
├── 32c1b709-03cf-fa67-24d3-12552bab13dd.xml
├── 335a34f6-a012-4732-1fea-87527cebbecd.xml
├── 34435006-8185-e827-453f-bcf4043b59e3.xml
├── 35d22925-210f-956e-92b6-12c95fedddaa.xml
├── 3a2ac349-bf62-313a-9f20-4c7c3932b60a.xml
├── 3a711afe-a630-a052-9ad9-87bd4345613b.xml
├── 3d0a9909-c581-51c4-1343-950e2653b152.xml
├── 3eeb99eb-b6d7-85a1-0001-29f3c220b63a.xml
├── 407075b2-2a77-655b-0bb4-fb45ded42876.xml
├── 40d05494-2f3b-10bd-1fdb-485097690ee9.xml
├── 449f192e-e39e-4f35-d4bd-fd8fd14ef6ad.xml
├── 473706ce-6549-acda-7330-ee8597293463.xml
├── 48a1f3a8-4ebd-f887-9042-461476ec06e1.xml
├── 4b854918-3dfc-0e52-8333-edc9d7d419fb.xml
├── 505b8bcb-2c04-8a59-85ee-f86d7a81133c.xml
├── 55c86eb1-5578-8ae0-dd84-5582fa070efe.xml
├── 60dd3c0d-a640-05d4-db8d-c2637f7f2b39.xml
├── 6871db6c-e61a-84b5-0ca6-4c240f90fde0.xml
├── 68b42756-a237-c7e8-a3f7-267ca18734b8.xml
├── 6b3d5d48-0b4d-3b8d-e13f-9648aa1e9723.xml
├── 6cd07b17-b3e8-55c6-ec51-b4294f445a2d.xml
├── 6df4dbc0-c70e-59f8-73ff-a15849692f52.xml
├── 70740235-9698-52af-7cd1-614f7550f80b.xml
├── 712af620-4f36-ce65-1d71-1af90ef6e16a.xml
├── 7fbb1bc0-5346-9adb-23ca-afde8a1cda88.xml
├── 8164731e-9412-adab-9432-1fa0a03aa01d.xml
├── 82a6b8d0-f606-38df-3050-7192e8c47e61.xml
├── 830f17c7-c111-019a-9c23-522994fd13a3.xml
├── 8e596088-4f9e-1214-eb48-e8369d8d3277.xml
├── 90348614-3a75-cec2-bea4-b5847353f958.xml
├── 990ca6d1-4785-c37c-0a9d-5db6af732336.xml
├── 9d307145-50e5-2464-e284-b13666d1b1eb.xml
├── 9eda75cf-38c6-c8fd-826b-0d151e3dfc8b.xml
├── 9eea4668-107b-8de8-59e3-22aa6c969ea0.xml
├── a2213ce7-3ec9-981b-062f-5b90e71d9ef0.xml
├── a357a146-da10-d1c5-6dbe-293d4072e351.xml
├── a6c005fe-f1fb-c257-4693-5dd2ccf4a508.xml
├── ad6eda66-4832-2efc-b3c0-55e7c8ef7ba4.xml
├── af66df3c-8f61-d237-0415-a240644ebb01.xml
├── b22cca88-7580-d134-a7be-c45c7d9c8be2.xml
├── b45c02d5-d804-8090-5057-0b3e3cbc19a0.xml
├── b5ad6c4c-2609-706b-f56b-547ace8e1dee.xml
├── b82a5fcb-a39d-b771-11ed-ae23c755838f.xml
├── ba11da02-35ff-5b18-068e-812d1f92f7df.xml
├── bb27603a-6a4d-9e7c-1cc2-a08ee8ef4109.xml
├── bcbabe45-8718-bce0-5974-bae720038d00.xml
├── bcee4a6a-47c8-e1cb-621c-2f876839efd6.xml
├── bd23b31c-aa0c-ec47-793e-36bb05f1ac59.xml
├── be43753c-2f1b-03df-9e55-56be16980d27.xml
├── bf222e0f-2117-7a4d-78cb-0a8e02803aa8.xml
├── c0168d33-3fbb-d636-6455-d1e6d811596e.xml
├── c231898c-c0fd-8636-cd01-91e62005ca68.xml
├── c7cb67b3-109d-5722-69ed-5ac3b5fdbc0e.xml
├── c88283e6-8a6d-e7e4-3a38-9c343e31d7cf.xml
├── cac50def-a782-0642-1a3e-e95e2679c778.xml
├── cad99045-36ff-2d40-f881-6d9616efe8f0.xml
├── d205b57d-0a11-6b7d-ceab-edfecfd42975.xml
├── d28eb91b-bf62-51fa-e18e-c4a417be7337.xml
├── d2d31ad9-8abb-b53a-7417-7720b259e979.xml
├── deb6bbbc-361f-e1fa-1a28-944836557e27.xml
├── dffc6c6c-da1a-0e05-486a-66c89481c970.xml
├── e10b3718-42ae-bdb7-e8c5-8fda7d054d52.xml
├── e2c9ceb2-6c34-7bb9-f1d7-041270a1088f.xml
├── e5ea2b24-4ddf-bc82-32fe-c787c3e974b8.xml
├── e65a4995-c3ff-c6e1-ee8b-b5d5c2b3f7b2.xml
├── e82cd517-dc93-1d39-8d56-50744a6a3193.xml
├── ed3c9749-6890-8dc7-f108-7da5fb5ebcaa.xml
├── f0983913-5110-b3fc-40ac-31e1d74e3e11.xml
├── f322eee0-b2a6-0288-20a1-9379975c4ccd.xml
├── f3a69b92-0354-52fc-b2c3-8f442702ea51.xml
├── f3b51430-f6ad-bc63-f4a8-1afd7b7c2a85.xml
├── fa14ff3e-0df7-c3fa-7383-e4e0f123567a.xml
├── fc3e09de-f376-65f7-47b1-60c2511a5acd.xml
└── roottoc.xml
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain
================================================
FILE: .gitignore
================================================
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
x64/
build/
[Bb]in/
[Oo]bj/
# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
!packages/*/build/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.Publish.xml
# NuGet Packages Directory
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
#packages/
# Windows Azure Build Output
csx
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.[Pp]ublish.xml
*.pfx
*.publishsettings
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
#LightSwitch generated files
GeneratedArtifacts/
_Pvt_Extensions/
ModelManifest.xml
# =========================
# Windows detritus
# =========================
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Mac desktop service store files
.DS_Store
/.vs
================================================
FILE: Documentation/Documentation.shfbproj
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="14.0">
<PropertyGroup>
<!-- The configuration and platform will be used to determine which
assemblies to include from solution and project documentation
sources -->
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>721253fb-22d4-4db6-8c7e-5f90118f52d5</ProjectGuid>
<SHFBSchemaVersion>2017.9.26.0</SHFBSchemaVersion>
<!-- AssemblyName, Name, and RootNamespace are not used by SHFB but Visual
Studio adds them anyway -->
<AssemblyName>Documentation</AssemblyName>
<RootNamespace>Documentation</RootNamespace>
<Name>Documentation</Name>
<!-- SHFB properties -->
<FrameworkVersion>.NET Framework 4.8</FrameworkVersion>
<OutputPath>..\docs\</OutputPath>
<HtmlHelpName>SolidSoils4Arduino</HtmlHelpName>
<Language>en-US</Language>
<DocumentationSources>
<DocumentationSource sourceFile="..\Solid.Arduino\Solid.Arduino.csproj" />
</DocumentationSources>
<SyntaxFilters>C#</SyntaxFilters>
<SdkLinkTarget>Blank</SdkLinkTarget>
<RootNamespaceContainer>False</RootNamespaceContainer>
<PresentationStyle>VS2013</PresentationStyle>
<Preliminary>True</Preliminary>
<NamingMethod>Guid</NamingMethod>
<HelpTitle>Solid Soils .NET Library for Arduino Serial Port Communication</HelpTitle>
<FooterText>Solid Soils Solutions</FooterText>
<FeedbackEMailLinkText>Solid Soils Solutions.</FeedbackEMailLinkText>
<FeedbackEMailAddress>info%40solidsoils.nl</FeedbackEMailAddress>
<CopyrightText>%28C%29 2013 - 2017 Henk van Boeijen</CopyrightText>
<ContentPlacement>AboveNamespaces</ContentPlacement>
<CatalogName>VisualStudio12</CatalogName>
<TocParentId>-1</TocParentId>
<TocParentVersion>100</TocParentVersion>
<TopicVersion>100</TopicVersion>
<TocOrder>-1</TocOrder>
<ProductTitle>SolidSoils4Arduino</ProductTitle>
<VendorName>Solid Soils Solutions</VendorName>
<MSHelpViewerSdkLinkType>Msdn</MSHelpViewerSdkLinkType>
<CatalogVersion>100</CatalogVersion>
<CatalogProductId>VS</CatalogProductId>
<VisibleItems>Attributes, ExplicitInterfaceImplementations, InheritedMembers, Protected, EditorBrowsableNever, NonBrowsable</VisibleItems>
<ComponentConfigurations>
<ComponentConfig id="Code Block Component" enabled="True">
<component id="Code Block Component" type="SandcastleBuilder.Components.CodeBlockComponent" assembly="{@SHFBFolder}SandcastleBuilder.Components.dll">
<basePath value="{@HtmlEncProjectFolder}" />
<outputPaths>{@HelpFormatOutputPaths}</outputPaths>
<allowMissingSource value="false" />
<removeRegionMarkers value="false" />
<colorizer syntaxFile="{@SHFBFolder}PresentationStyles\Colorizer\highlight.xml" styleFile="{@SHFBFolder}PresentationStyles\Colorizer\highlight.xsl" stylesheet="{@SHFBFolder}PresentationStyles\Colorizer\highlight.css" scriptFile="{@SHFBFolder}PresentationStyles\Colorizer\highlight.js" language="cs" tabSize="0" numberLines="true" outlining="false" keepSeeTags="false" defaultTitle="true" />
</component>
</ComponentConfig>
<ComponentConfig id="API Token Resolution" enabled="True">
<component id="API Token Resolution">{@TokenFiles}
<replace elements="/*//token" item="string(.)" /></component>
</ComponentConfig>
<ComponentConfig id="IntelliSense Component" enabled="True">
<component id="IntelliSense Component">
<!-- Output options (optional)
Attributes:
Include namespaces (false by default)
Namespaces comments filename ("Namespaces" if not specified or empty)
Output folder (current folder if not specified or empty) -->
<output includeNamespaces="false" namespacesFile="Namespaces" folder="{@OutputFolder}" />
</component>
</ComponentConfig>
</ComponentConfigurations>
<NamespaceSummaries>
<NamespaceSummaryItem name="(global)" isDocumented="False" />
<NamespaceSummaryItem name="Solid.Arduino" isDocumented="True">This is the root namespace of the SolidSoils4Arduino library.</NamespaceSummaryItem>
<NamespaceSummaryItem name="Solid.Arduino.Firmata" isDocumented="True">This namespace contains types related to the Firmata protocol.</NamespaceSummaryItem>
<NamespaceSummaryItem name="Solid.Arduino.Firmata.Servo" isDocumented="True">This namespace contains types related to the servo extension of the Firmata protocol.</NamespaceSummaryItem>
<NamespaceSummaryItem name="Solid.Arduino.I2c" isDocumented="False">This namespace contains types related to the I2C protocol.</NamespaceSummaryItem>
<NamespaceSummaryItem name="Solid.Arduino.I2C" isDocumented="True">This namespace contains types related to the I2C protocol.</NamespaceSummaryItem>
</NamespaceSummaries>
<ApiFilter />
<HelpAttributes />
<PlugInConfigurations />
<BuildLogFile />
<HtmlHelp1xCompilerPath />
<HtmlHelp2xCompilerPath />
<WorkingPath />
<ComponentPath />
<MaximumGroupParts>3</MaximumGroupParts>
<NamespaceGrouping>False</NamespaceGrouping>
<BuildAssemblerVerbosity>OnlyWarningsAndErrors</BuildAssemblerVerbosity>
<HelpFileFormat>HtmlHelp1, Website</HelpFileFormat>
<IndentHtml>False</IndentHtml>
<KeepLogFile>True</KeepLogFile>
<DisableCodeBlockComponent>False</DisableCodeBlockComponent>
<CppCommentsFixup>False</CppCommentsFixup>
<CleanIntermediates>True</CleanIntermediates>
<ProjectSummary>SolidSoils4Arduino is a client library targeting .NET 4.5 and above that provides an easy way to interact with the Arduino. The library implements a few communication protocols, the first of which is the Firmata protocol. It aims to make communication with Arduino boards in MS .NET projects easier through a comprehensive and consistent set of methods and events.
The library supports the following protocols:
1. Serial %28ASCII%29 messaging protocol
2. Firmata protocol
3. I2C protocol %28as it has become part of Firmata%29
The protocols mentioned can be used simultaneously. The library brokers all incoming message types and directs them to the proper requestors %28synchronous as well as asynchronous%29 and events.</ProjectSummary>
<TransformComponentArguments>
<Argument Key="logoFile" Value="SolidSoilsLogo.jpg" />
<Argument Key="logoHeight" Value="" />
<Argument Key="logoWidth" Value="" />
<Argument Key="logoAltText" Value="Solid Soils Solutions" />
<Argument Key="logoPlacement" Value="left" />
<Argument Key="logoAlignment" Value="left" />
<Argument Key="maxVersionParts" Value="" />
<Argument Key="defaultLanguage" Value="cs" />
<Argument Key="includeEnumValues" Value="true" />
<Argument Key="baseSourceCodeUrl" Value="" />
<Argument Key="requestExampleUrl" Value="" />
</TransformComponentArguments>
<SaveComponentCacheCapacity>100</SaveComponentCacheCapacity>
<HelpFileVersion>1.0.0.0</HelpFileVersion>
<MissingTags>Summary, Parameter, Returns, AutoDocumentCtors, Namespace, TypeParameter</MissingTags>
<WarnOnMissingSourceContext>False</WarnOnMissingSourceContext>
</PropertyGroup>
<!-- There are no properties for these groups. AnyCPU needs to appear in
order for Visual Studio to perform the build. The others are optional
common platform types that may appear. -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|Win32' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|Win32' ">
</PropertyGroup>
<ItemGroup>
<Content Include="icons\SolidSoilsLogo.jpg">
<ImageId>SolidSoilsLogo</ImageId>
<AlternateText>Solid Soils Logo</AlternateText>
</Content>
</ItemGroup>
<ItemGroup>
<Folder Include="icons" />
</ItemGroup>
<!-- Import the SHFB build targets -->
<Import Project="$(SHFBROOT)\SandcastleHelpFileBuilder.targets" />
</Project>
================================================
FILE: LICENSE.md
================================================
####Copyright (c) 2013 - 2015, Henk van Boeijen <info@solidsoils.nl>
#####All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================
FILE: README.md
================================================
# SolidSoils4Arduino
SolidSoils4Arduino is a client library built on .NET Standard 2.1. It offers an easy way to interact with Arduino boards.
The library implements the main communication protocols, the first of which is the Firmata protocol.
It aims to make communication with Arduino boards in MS .NET projects easier
through a comprehensive and consistent set of methods and events.
The library supports the following protocols:
1. Serial (ASCII) messaging
2. Firmata
3. I2C (as it has become part of Firmata)
All protocols can be mixed. The library brokers all incoming message types
and directs them to the appropriate requestors (synchronous as well as asynchronous).
Currently [Standard Firmata 2.6](https://github.com/firmata/protocol/blob/master/protocol.md) is supported.
(Extra capabilities of Standard Firmata Plus and Configurable Firmata are currently not supported by this client library.)
Technology: C#/Microsoft .NET Standard 2.1
Dependencies: none
### Downloads
The library is available as a [NuGet package](https://www.nuget.org/packages/SolidSoils.Arduino.Client/#).
### API Documentation
See [reference documentation](https://solidsoils.github.io/Arduino/index.html).
## Getting started
#### Setup your Arduino with StandardFirmata
1. [Download the Arduino IDE](https://www.arduino.cc/en/main/software) and install it.
2. Connect your Arduino board to your computer using an USB cable.
3. Start the Arduino IDE and navigate to File > Examples > Firmata > StandardFirmata.
4. Upload the sketch.
#### Basic test (C#)
Preparation
- Your Arduino is setup with the StandardFirmata sketch (see above).
- An LED is connected to pin 10 of your Arduino.
Further steps
1. Open Visual Studio and create a new C# console program project.
2. Add NuGet package [SolidSoils.Arduino.Client](https://www.nuget.org/packages/SolidSoils.Arduino.Client/).
3. In Program.cs put the following code:
```csharp
using System;
using Solid.Arduino.Firmata;
namespace Demo
{
class Program
{
static void Main(string[] args)
{
ISerialConnection connection = GetConnection();
if (connection != null)
using (var session = new ArduinoSession(connection))
PerformBasicTest(session);
Console.WriteLine("Press a key");
Console.ReadKey(true);
}
private static ISerialConnection GetConnection()
{
Console.WriteLine("Searching Arduino connection...");
ISerialConnection connection = EnhancedSerialConnection.Find();
if (connection == null)
Console.WriteLine("No connection found. Make shure your Arduino board is attached to a USB port.");
else
Console.WriteLine($"Connected to port {connection.PortName} at {connection.BaudRate} baud.");
return connection;
}
private static void PerformBasicTest(IFirmataProtocol session)
{
var firmware = session.GetFirmware();
Console.WriteLine($"Firmware: {firmware.Name} version {firmware.MajorVersion}.{firmware.MinorVersion}");
var protocolVersion = session.GetProtocolVersion();
Console.WriteLine($"Firmata protocol version {protocolVersion.Major}.{protocolVersion.Minor}");
session.SetDigitalPinMode(10, PinMode.DigitalOutput);
session.SetDigitalPin(10, true);
Console.WriteLine("Command sent: Light on (pin 10)");
Console.WriteLine("Press a key");
Console.ReadKey(true);
session.SetDigitalPin(10, false);
Console.WriteLine("Command sent: Light off");
}
}
}
```
#### Display board capabilities
Preparation
- Your Arduino is setup with the StandardFirmata sketch (see above).
- In this example the Arduino is connected to COM3 at 57600 baud. Modify as needed.
Further steps
1. Open Visual Studio and create a new C# console program project.
2. Add NuGet package [SolidSoils.Arduino.Client](https://www.nuget.org/packages/SolidSoils.Arduino.Client/).
3. In Program.cs put the following code:
```csharp
using System;
using Solid.Arduino.Firmata;
namespace Demo
{
class Program
{
static void Main(string[] args)
{
DisplayPortCapabilities();
Console.WriteLine("Press a key");
Console.ReadKey(true);
}
private static void DisplayPortCapabilities()
{
using (var session = new ArduinoSession(new EnhancedSerialConnection("COM3", SerialBaudRate.Bps_57600)))
{
BoardCapability cap = session.GetBoardCapability();
Console.WriteLine();
Console.WriteLine("Board Capability:");
foreach (var pin in cap.Pins)
{
Console.WriteLine("Pin {0}: Input: {1}, Output: {2}, Analog: {3}, Analog-Res: {4}, PWM: {5}, PWM-Res: {6}, Servo: {7}, Servo-Res: {8}, Serial: {9}, Encoder: {10}, Input-pullup: {11}",
pin.PinNumber,
pin.DigitalInput,
pin.DigitalOutput,
pin.Analog,
pin.AnalogResolution,
pin.Pwm,
pin.PwmResolution,
pin.Servo,
pin.ServoResolution,
pin.Serial,
pin.Encoder,
pin.InputPullup);
}
}
}
}
}
```
## Current status
**v1.0.0**
## Milestones
1. Firmata protocol implemented, unit- and integration-tested.
2. I2C protocol implemented and unit-tested.
3. Serial ASCII protocol implemented and unit-tested.
4. API fully documented.
5. IObservable methods implemented (to be unittested).
6. Mono support added.
7. NuGet package published.
## License
[BSD-2 license](https://github.com/SolidSoils/Arduino/blob/master/LICENSE.md)
## Contributing
If you discover a bug or would like to propose a new feature,
please open a new [issue](https://github.com/solidsoils/arduino/issues?sort=created&state=open).
To contribute, fork this respository and create a new topic branch for the bug,
feature or other existing issue you are addressing. Submit the pull request against the *master* branch.
If you would like to contribute but don't have a specific bugfix or new feature to contribute,
you can take on an existing issue. Add a comment to
the issue to express your intent to begin work and/or to get any additional information about the issue.
Please, test your contributed code thoroughly. In your pull request, describe tests performed to ensure
that no existing code is broken and that any changes maintain backwards compatibility with the existing API.
================================================
FILE: Solid.Arduino/ArduinoSession.cs
================================================
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Solid.Arduino.Firmata;
using Solid.Arduino.Firmata.Servo;
using Solid.Arduino.I2C;
namespace Solid.Arduino
{
/// <summary>
/// Represents an active layer for serial communication with an Arduino board.
/// </summary>
/// <remarks>
/// This class supports a few common protocols used for communicating with Arduino boards.
/// The protocols can be used simultaneous and independently of each other.
/// </remarks>
/// <seealso href="http://arduino.cc">Official Arduino website</seealso>
/// <seealso href="https://github.com/SolidSoils/Arduino">SolidSoils4Arduino project on GitHub</seealso>
/// <example>
/// <code language="C#">
/// var connection = new SerialConnection("COM3", SerialBaudRate.Bps_57600);
/// var session = new ArduinoSession(connection, timeOut: 250);
/// // Cast to interface done, just for the sake of this demo.
/// IFirmataProtocol firmata = (IFirmataProtocol)session;
///
/// Firmware firm = firmata.GetFirmware();
/// Console.WriteLine("Firmware: {0} {1}.{2}", firm.Name, firm.MajorVersion, firm.MinorVersion);
///
/// ProtocolVersion version = firmata.GetProtocolVersion();
/// Console.WriteLine("Protocol version: {0}.{1}", version.Major, version.Minor);
///
/// BoardCapability caps = firmata.GetBoardCapability();
/// Console.WriteLine("Board Capabilities:");
///
/// foreach (var pincap in caps.PinCapabilities)
/// {
/// Console.WriteLine("Pin {0}: Input: {1}, Output: {2}, Analog: {3}, Analog-Res: {4}, PWM: {5}, PWM-Res: {6}, Servo: {7}, Servo-Res: {8}",
/// pincap.PinNumber,
/// pincap.DigitalInput,
/// pincap.DigitalOutput,
/// pincap.Analog,
/// pincap.AnalogResolution,
/// pincap.Pwm,
/// pincap.PwmResolution,
/// pincap.Servo,
/// pincap.ServoResolution);
/// }
///
/// Console.WriteLine();
/// Console.ReadLine();
/// </code>
/// </example>
public class ArduinoSession : IFirmataProtocol, IServoProtocol, II2CProtocol, IStringProtocol, IDisposable
{
#region Private types
private delegate void ProcessMessageHandler(byte messageByte);
private enum MessageHeader
{
AnalogState = 0xE0, // 224
DigitalState = 0x90, // 144
SystemExtension = 0xF0,
ProtocolVersion = 0xF9
}
private enum StringReadMode {
ReadLine,
ReadToTerminator,
ReadBlock
}
private class StringRequest
{
private readonly StringReadMode _mode;
private readonly int _blockLength;
private readonly char _terminator;
public static StringRequest CreateReadLineRequest()
{
return new StringRequest(StringReadMode.ReadLine, '\\', 0);
}
public static StringRequest CreateReadRequest(int blockLength)
{
return new StringRequest(StringReadMode.ReadBlock, '\\', blockLength);
}
public static StringRequest CreateReadRequest(char terminator)
{
return new StringRequest(StringReadMode.ReadToTerminator, terminator, 0);
}
private StringRequest(StringReadMode mode, char terminator, int blockLength)
{
_mode = mode;
_blockLength = blockLength;
_terminator = terminator;
}
public char Terminator => _terminator;
public int BlockLength => _blockLength;
public StringReadMode Mode => _mode;
}
#endregion
private const byte AnalogMessage = 0xE0;
private const byte DigitalMessage = 0x90;
private const byte SysExStart = 0xF0;
private const byte SysExEnd = 0xF7;
private const int Buffersize = 2048;
private const int MaxQueuelength = 100;
private readonly ISerialConnection _connection;
private readonly bool _gotOpenConnection;
private readonly LinkedList<FirmataMessage> _receivedMessageList = new LinkedList<FirmataMessage>();
private readonly Queue<string> _receivedStringQueue = new Queue<string>();
private ConcurrentQueue<FirmataMessage> _awaitedMessagesQueue = new ConcurrentQueue<FirmataMessage>();
private ConcurrentQueue<StringRequest> _awaitedStringsQueue = new ConcurrentQueue<StringRequest>();
private StringRequest _currentStringRequest;
private int _messageTimeout = -1;
private ProcessMessageHandler _processMessage;
private int _messageBufferIndex, _stringBufferIndex;
private readonly byte[] _messageBuffer = new byte[Buffersize];
private readonly char[] _stringBuffer = new char[Buffersize];
/// <summary>
/// Initializes a new instance of the <see cref="ArduinoSession"/> class.
/// </summary>
/// <param name="connection">The serial port connection</param>
/// <exception cref="System.ArgumentNullException">connection</exception>
public ArduinoSession(ISerialConnection connection)
{
_connection = connection ?? throw new ArgumentNullException(nameof(connection));
_gotOpenConnection = connection.IsOpen;
if (!connection.IsOpen)
connection.Open();
_connection.DataReceived += SerialDataReceived;
}
/// <summary>
/// Initializes a new instance of the <see cref="ArduinoSession"/> class.
/// </summary>
/// <param name="connection">The serial port connection</param>
/// <param name="timeOut">The response time out in milliseconds</param>
/// <exception cref="System.ArgumentNullException">connection</exception>
/// <exception cref="System.ArgumentOutOfRangeException">timeOut</exception>
public ArduinoSession(ISerialConnection connection, int timeOut)
: this(connection)
{
if (timeOut < SerialPort.InfiniteTimeout)
throw new ArgumentOutOfRangeException(nameof(timeOut));
_messageTimeout = timeOut;
}
/// <summary>
/// Gets or sets the number of milliseconds before a time-out occurs when a read operation does not finish.
/// </summary>
/// <remarks>
/// The default is a <see cref="SerialPort.InfiniteTimeout"/> value (-1).
/// </remarks>
public int TimeOut
{
get => _messageTimeout;
set
{
if (value < SerialPort.InfiniteTimeout)
throw new ArgumentOutOfRangeException();
_messageTimeout = value;
}
}
/// <summary>
/// Closes and reopens the underlying connection and clears all buffers and queues.
/// </summary>
public void Clear()
{
lock (_receivedMessageList)
{
_connection.Close();
_receivedMessageList.Clear();
_processMessage = null;
_awaitedMessagesQueue = new ConcurrentQueue<FirmataMessage>();
_awaitedStringsQueue = new ConcurrentQueue<StringRequest>();
_connection.Open();
}
}
#region IStringProtocol
/// <inheritdoc cref="IStringProtocol.StringReceived"/>
public event StringReceivedHandler StringReceived;
/// <inheritdoc cref="IStringProtocol.CreateReceivedStringMonitor"/>
public IObservable<string> CreateReceivedStringMonitor()
{
return new ReceivedStringTracker(this);
}
/// <inheritdoc cref="IStringProtocol.NewLine"/>
/// <remarks>
/// The value of this property is mapped to the <see cref="ISerialConnection.NewLine"/> property of the
/// connection the <see cref="ArduinoSession"/> instance is relying on.
/// </remarks>
public string NewLine
{
get => _connection.NewLine;
set => _connection.NewLine = value;
}
/// <inheritdoc cref="IStringProtocol.Write"/>
public void Write(string value)
{
if (!string.IsNullOrEmpty(value))
_connection.Write(value);
}
/// <inheritdoc cref="IStringProtocol.WriteLine"/>
public void WriteLine(string value)
{
_connection.WriteLine(value);
}
/// <inheritdoc cref="IStringProtocol.ReadLine"/>
public string ReadLine()
{
return GetStringFromQueue(StringRequest.CreateReadLineRequest());
}
/// <inheritdoc cref="IStringProtocol.ReadLineAsync"/>
public async Task<string> ReadLineAsync()
{
return await Task.Run(() => GetStringFromQueue(StringRequest.CreateReadLineRequest()));
}
/// <inheritdoc cref="IStringProtocol.Read"/>
public string Read(int length = 1)
{
if (length < 0)
throw new ArgumentOutOfRangeException(nameof(length), Messages.ArgumentEx_PositiveValue);
return GetStringFromQueue(StringRequest.CreateReadRequest(length));
}
/// <inheritdoc cref="IStringProtocol.ReadAsync"/>
public async Task<string> ReadAsync(int length = 1)
{
if (length < 0)
throw new ArgumentOutOfRangeException(nameof(length), Messages.ArgumentEx_PositiveValue);
return await Task.Run(() => GetStringFromQueue(StringRequest.CreateReadRequest(length)));
}
/// <inheritdoc cref="IStringProtocol.ReadTo"/>
public string ReadTo(char terminator = char.MinValue)
{
return GetStringFromQueue(StringRequest.CreateReadRequest(terminator));
}
/// <inheritdoc cref="IStringProtocol.ReadToAsync"/>
public async Task<string> ReadToAsync(char terminator = char.MinValue)
{
return await Task.Run(() => GetStringFromQueue(StringRequest.CreateReadRequest(terminator)));
}
#endregion
#region IFirmataProtocol
/// <inheritdoc cref="IFirmataProtocol.MessageReceived"/>
public event MessageReceivedHandler MessageReceived;
/// <inheritdoc cref="IFirmataProtocol.AnalogStateReceived"/>
public event AnalogStateReceivedHandler AnalogStateReceived;
/// <inheritdoc cref="IFirmataProtocol.DigitalStateReceived"/>
public event DigitalStateReceivedHandler DigitalStateReceived;
/// <inheritdoc cref="IFirmataProtocol.CreateDigitalStateMonitor()"/>
public IObservable<DigitalPortState> CreateDigitalStateMonitor()
{
return new DigitalStateTracker(this);
}
/// <inheritdoc cref="IFirmataProtocol.CreateDigitalStateMonitor(int)"/>
public IObservable<DigitalPortState> CreateDigitalStateMonitor(int port)
{
if (port < 0 || port > 15)
throw new ArgumentOutOfRangeException(nameof(port), Messages.ArgumentEx_PortRange0_15);
return new DigitalStateTracker(this, port);
}
/// <inheritdoc cref="IFirmataProtocol.CreateAnalogStateMonitor()"/>
public IObservable<AnalogState> CreateAnalogStateMonitor()
{
return new AnalogStateTracker(this);
}
/// <inheritdoc cref="IFirmataProtocol.CreateAnalogStateMonitor(int)"/>
public IObservable<AnalogState> CreateAnalogStateMonitor(int channel)
{
if (channel < 0 || channel > 15)
throw new ArgumentOutOfRangeException(nameof(channel), Messages.ArgumentEx_ChannelRange0_15);
return new AnalogStateTracker(this, channel);
}
/// <inheritdoc cref="IFirmataProtocol.ResetBoard"/>
public void ResetBoard()
{
_connection.Write(new [] { (byte)0xFF }, 0, 1);
}
/// <inheritdoc cref="IFirmataProtocol.SetDigitalPin(int,long)"/>
public void SetDigitalPin(int pinNumber, long value)
{
if (pinNumber < 0 || pinNumber > 127)
throw new ArgumentOutOfRangeException(nameof(pinNumber), Messages.ArgumentEx_PinRange0_127);
if (value < 0)
throw new ArgumentOutOfRangeException(nameof(value), Messages.ArgumentEx_NoNegativeValue);
byte[] message;
if (pinNumber < 16 && value < 0x4000)
{
// Send value in a conventional Analog Message.
message = new[] {
(byte)(AnalogMessage | pinNumber),
(byte)(value & 0x7F),
(byte)((value >> 7) & 0x7F)
};
_connection.Write(message, 0, 3);
return;
}
// Send long value in an Extended Analog Message.
message = new byte[14];
message[0] = SysExStart;
message[1] = 0x6F;
message[2] = (byte)pinNumber;
int index = 3;
do
{
message[index] = (byte)(value & 0x7F);
value >>= 7;
index++;
} while (value > 0 || index < 5);
message[index] = SysExEnd;
_connection.Write(message, 0, index + 1);
}
/// <inheritdoc cref="IFirmataProtocol.SetDigitalPin(int,bool)"/>
public void SetDigitalPin(int pinNumber, bool value)
{
if (pinNumber < 0 || pinNumber > 127)
throw new ArgumentOutOfRangeException(nameof(pinNumber), Messages.ArgumentEx_PinRange0_127);
_connection.Write(new[] { (byte)0xF5, (byte)pinNumber, (byte)(value ? 1 : 0) }, 0, 3);
}
/// <inheritdoc cref="IFirmataProtocol.SetAnalogReportMode"/>
public void SetAnalogReportMode(int channel, bool enable)
{
if (channel < 0 || channel > 15)
throw new ArgumentOutOfRangeException(nameof(channel), Messages.ArgumentEx_ChannelRange0_15);
_connection.Write(new[] { (byte)(0xC0 | channel), (byte)(enable ? 1 : 0) }, 0, 2);
}
/// <inheritdoc cref="IFirmataProtocol.SetDigitalPort"/>
public void SetDigitalPort(int portNumber, int pins)
{
if (portNumber < 0 || portNumber > 15)
throw new ArgumentOutOfRangeException(nameof(portNumber), Messages.ArgumentEx_PortRange0_15);
if (pins < 0 || pins > 0xFF)
throw new ArgumentOutOfRangeException(nameof(pins), Messages.ArgumentEx_ValueRange0_255);
_connection.Write(new[] { (byte)(DigitalMessage | portNumber), (byte)(pins & 0x7F), (byte)((pins >> 7) & 0x03) }, 0, 3);
}
/// <inheritdoc cref="IFirmataProtocol.SetDigitalReportMode"/>
public void SetDigitalReportMode(int portNumber, bool enable)
{
if (portNumber < 0 || portNumber > 15)
throw new ArgumentOutOfRangeException(nameof(portNumber), Messages.ArgumentEx_PortRange0_15);
_connection.Write(new[] { (byte)(0xD0 | portNumber), (byte)(enable ? 1 : 0) }, 0, 2);
}
/// <inheritdoc cref="IFirmataProtocol.SetDigitalPinMode"/>
public void SetDigitalPinMode(int pinNumber, PinMode mode)
{
if (pinNumber < 0 || pinNumber > 127)
throw new ArgumentOutOfRangeException(nameof(pinNumber), Messages.ArgumentEx_PinRange0_127);
_connection.Write(new byte[] { 0xF4, (byte)pinNumber, (byte)mode }, 0, 3);
}
/// <inheritdoc cref="IFirmataProtocol.SetSamplingInterval"/>
public void SetSamplingInterval(int milliseconds)
{
if (milliseconds < 0 || milliseconds > 0x3FFF)
throw new ArgumentOutOfRangeException(nameof(milliseconds), Messages.ArgumentEx_SamplingInterval);
var command = new[]
{
SysExStart,
(byte)0x7A,
(byte)(milliseconds & 0x7F),
(byte)((milliseconds >> 7) & 0x7F),
SysExEnd
};
_connection.Write(command, 0, 5);
}
/// <inheritdoc cref="IFirmataProtocol.SendStringData"/>
public void SendStringData(string data)
{
if (data == null)
data = string.Empty;
byte[] command = new byte[data.Length * 2 + 3];
command[0] = SysExStart;
command[1] = 0x71;
for (int x = 0; x < data.Length; x++)
{
short c = Convert.ToInt16(data[x]);
command[x * 2 + 2] = (byte)(c & 0x7F);
command[x * 2 + 3] = (byte)((c >> 7) & 0x7F);
}
command[command.Length - 1] = SysExEnd;
_connection.Write(command, 0, command.Length);
}
/// <inheritdoc cref="IFirmataProtocol.RequestFirmware"/>
public void RequestFirmware()
{
SendSysExCommand(0x79);
}
/// <inheritdoc cref="IFirmataProtocol.GetFirmware"/>
public Firmware GetFirmware()
{
RequestFirmware();
return (Firmware)((FirmataMessage)GetMessageFromQueue(new FirmataMessage(MessageType.FirmwareResponse))).Value;
}
/// <inheritdoc cref="IFirmataProtocol.GetFirmwareAsync"/>
public async Task<Firmware> GetFirmwareAsync()
{
RequestFirmware();
return await Task.Run(() =>
(Firmware)((FirmataMessage)GetMessageFromQueue(new FirmataMessage(MessageType.FirmwareResponse))).Value);
}
/// <inheritdoc cref="IFirmataProtocol.RequestProtocolVersion"/>
public void RequestProtocolVersion()
{
_connection.Write(new byte[] { 0xF9 }, 0, 1);
}
/// <inheritdoc cref="IFirmataProtocol.GetProtocolVersion"/>
public ProtocolVersion GetProtocolVersion()
{
RequestProtocolVersion();
return (ProtocolVersion)((FirmataMessage)GetMessageFromQueue(new FirmataMessage(MessageType.ProtocolVersion))).Value;
}
/// <inheritdoc cref="IFirmataProtocol.GetProtocolVersionAsync"/>
public async Task<ProtocolVersion> GetProtocolVersionAsync()
{
RequestProtocolVersion();
return await Task.Run(() =>
(ProtocolVersion)((FirmataMessage)GetMessageFromQueue(new FirmataMessage(MessageType.ProtocolVersion))).Value);
}
/// <inheritdoc cref="IFirmataProtocol.RequestBoardCapability"/>
public void RequestBoardCapability()
{
SendSysExCommand(0x6B);
}
/// <inheritdoc cref="IFirmataProtocol.GetBoardCapability"/>
public BoardCapability GetBoardCapability()
{
RequestBoardCapability();
return (BoardCapability)((FirmataMessage) GetMessageFromQueue(new FirmataMessage(MessageType.CapabilityResponse))).Value;
}
/// <inheritdoc cref="IFirmataProtocol.GetBoardCapabilityAsync"/>
public async Task<BoardCapability> GetBoardCapabilityAsync()
{
RequestBoardCapability();
return await Task.Run(() =>
(BoardCapability)((FirmataMessage)GetMessageFromQueue(new FirmataMessage(MessageType.CapabilityResponse))).Value);
}
/// <inheritdoc cref="IFirmataProtocol.RequestBoardAnalogMapping"/>
public void RequestBoardAnalogMapping()
{
SendSysExCommand(0x69);
}
/// <inheritdoc cref="IFirmataProtocol.GetBoardAnalogMapping"/>
public BoardAnalogMapping GetBoardAnalogMapping()
{
RequestBoardAnalogMapping();
return (BoardAnalogMapping)((FirmataMessage)GetMessageFromQueue(new FirmataMessage(MessageType.AnalogMappingResponse))).Value;
}
/// <inheritdoc cref="IFirmataProtocol.GetBoardAnalogMappingAsync"/>
public async Task<BoardAnalogMapping> GetBoardAnalogMappingAsync()
{
RequestBoardAnalogMapping();
return await Task.Run(() =>
(BoardAnalogMapping)((FirmataMessage)GetMessageFromQueue(new FirmataMessage(MessageType.AnalogMappingResponse))).Value);
}
/// <inheritdoc cref="IFirmataProtocol.RequestPinState"/>
public void RequestPinState(int pinNumber)
{
if (pinNumber < 0 || pinNumber > 127)
throw new ArgumentOutOfRangeException(nameof(pinNumber), Messages.ArgumentEx_PinRange0_127);
var command = new[]
{
SysExStart,
(byte)0x6D,
(byte)pinNumber,
SysExEnd
};
_connection.Write(command, 0, 4);
}
/// <inheritdoc cref="IFirmataProtocol.GetPinState"/>
public PinState GetPinState(int pinNumber)
{
RequestPinState(pinNumber);
return (PinState)((FirmataMessage)GetMessageFromQueue(new FirmataMessage(MessageType.PinStateResponse))).Value;
}
/// <inheritdoc cref="IFirmataProtocol.GetPinStateAsync"/>
public async Task<PinState> GetPinStateAsync(int pinNumber)
{
RequestPinState(pinNumber);
return await Task.Run
(
() =>
(PinState)((FirmataMessage)GetMessageFromQueue(new FirmataMessage(MessageType.PinStateResponse))).Value
);
}
#endregion
#region IServoProtocol
/// <inheritdoc cref="IServoProtocol.ConfigureServo"/>
public void ConfigureServo(int pinNumber, int minPulse, int maxPulse)
{
if (pinNumber < 0 || pinNumber > 127)
throw new ArgumentOutOfRangeException(nameof(pinNumber), Messages.ArgumentEx_PinRange0_127);
if (minPulse < 0 || minPulse > 0x3FFF)
throw new ArgumentOutOfRangeException(nameof(minPulse), Messages.ArgumentEx_MinPulseWidth);
if (maxPulse < 0 || maxPulse > 0x3FFF)
throw new ArgumentOutOfRangeException(nameof(maxPulse), Messages.ArgumentEx_MaxPulseWidth);
if (minPulse > maxPulse)
throw new ArgumentException(Messages.ArgumentEx_MinMaxPulse);
var command = new[]
{
SysExStart,
(byte)0x70,
(byte)pinNumber,
(byte)(minPulse & 0x7F),
(byte)((minPulse >> 7) & 0x7F),
(byte)(maxPulse & 0x7F),
(byte)((maxPulse >> 7) & 0x7F),
SysExEnd
};
_connection.Write(command, 0, 8);
}
#endregion
#region II2cProtocol
/// <inheritdoc cref="II2CProtocol.I2CReplyReceived"/>
public event I2CReplyReceivedHandler I2CReplyReceived;
/// <inheritdoc cref="II2CProtocol.CreateI2CReplyMonitor"/>
public IObservable<I2CReply> CreateI2CReplyMonitor()
{
return new I2CReplyTracker(this);
}
/// <inheritdoc cref="II2CProtocol.SetI2CReadInterval"/>
public void SetI2CReadInterval(int microseconds)
{
if (microseconds < 0 || microseconds > 0x3FFF)
throw new ArgumentOutOfRangeException(nameof(microseconds), Messages.ArgumentEx_I2cInterval);
var command = new []
{
SysExStart,
(byte)0x78,
(byte)(microseconds & 0x7F),
(byte)((microseconds >> 7) & 0x7F),
SysExEnd
};
_connection.Write(command, 0, 5);
}
/// <inheritdoc cref="II2CProtocol.WriteI2C"/>
public void WriteI2C(int slaveAddress, params byte[] data)
{
if (slaveAddress < 0 || slaveAddress > 0x3FF)
throw new ArgumentOutOfRangeException(nameof(slaveAddress), Messages.ArgumentEx_I2cAddressRange);
byte[] command = new byte[data.Length * 2 + 5];
command[0] = SysExStart;
command[1] = 0x76;
command[2] = (byte)(slaveAddress & 0x7F);
command[3] = (byte)(slaveAddress < 0x80 ? 0 : ((slaveAddress >> 7) & 0x07) | 0x20);
for (int x = 0; x < data.Length; x++)
{
command[x * 2 + 4] = (byte)(data[x] & 0x7F);
command[x * 2 + 5] = (byte)((data[x] >> 7) & 0x7F);
}
command[command.Length - 1] = SysExEnd;
_connection.Write(command, 0, command.Length);
}
/// <inheritdoc cref="II2CProtocol.ReadI2COnce(int,int)"/>
public void ReadI2COnce(int slaveAddress, int bytesToRead)
{
I2CRead(false, slaveAddress, -1, bytesToRead);
}
/// <inheritdoc cref="II2CProtocol.GetI2CReply(int,int)"/>
public I2CReply GetI2CReply(int slaveAddress, int bytesToRead)
{
ReadI2COnce(slaveAddress, bytesToRead);
_awaitedMessagesQueue.Enqueue(new FirmataMessage(MessageType.I2CReply));
return (I2CReply)((FirmataMessage)GetMessageFromQueue(new FirmataMessage(MessageType.I2CReply))).Value;
}
/// <inheritdoc cref="II2CProtocol.GetI2CReplyAsync(int,int)"/>
public async Task<I2CReply> GetI2CReplyAsync(int slaveAddress, int bytesToRead)
{
ReadI2COnce(slaveAddress, bytesToRead);
_awaitedMessagesQueue.Enqueue(new FirmataMessage(MessageType.I2CReply));
return await Task.Run(() =>
(I2CReply)((FirmataMessage)GetMessageFromQueue(new FirmataMessage(MessageType.I2CReply))).Value);
}
/// <inheritdoc cref="II2CProtocol.ReadI2COnce(int,int,int)"/>
public void ReadI2COnce(int slaveAddress, int slaveRegister, int bytesToRead)
{
I2CSlaveRead(false, slaveAddress, slaveRegister, bytesToRead);
}
/// <inheritdoc cref="II2CProtocol.GetI2CReply(int,int,int)"/>
public I2CReply GetI2CReply(int slaveAddress, int slaveRegister, int bytesToRead)
{
ReadI2COnce(slaveAddress, slaveRegister, bytesToRead);
_awaitedMessagesQueue.Enqueue(new FirmataMessage(MessageType.I2CReply));
return (I2CReply)((FirmataMessage)GetMessageFromQueue(new FirmataMessage(MessageType.I2CReply))).Value;
}
/// <inheritdoc cref="II2CProtocol.GetI2CReplyAsync(int,int,int)"/>
public async Task<I2CReply> GetI2CReplyAsync(int slaveAddress, int slaveRegister, int bytesToRead)
{
ReadI2COnce(slaveAddress, slaveRegister, bytesToRead);
_awaitedMessagesQueue.Enqueue(new FirmataMessage(MessageType.I2CReply));
return await Task.Run(() =>
(I2CReply)((FirmataMessage)GetMessageFromQueue(new FirmataMessage(MessageType.I2CReply))).Value);
}
/// <inheritdoc cref="II2CProtocol.ReadI2CContinuous(int,int)"/>
public void ReadI2CContinuous(int slaveAddress, int bytesToRead)
{
I2CRead(true, slaveAddress, -1, bytesToRead);
}
/// <inheritdoc cref="II2CProtocol.ReadI2CContinuous(int,int,int)"/>
public void ReadI2CContinuous(int slaveAddress, int slaveRegister, int bytesToRead)
{
I2CSlaveRead(true, slaveAddress, slaveRegister, bytesToRead);
}
/// <inheritdoc cref="II2CProtocol.StopI2CReading"/>
/// <remarks>
/// <para>
/// Please note:
/// The Firmata specification states that the I2C_READ_STOP message
/// should only stop the specified query. However, the current Firmata.h implementation
/// stops all registered queries.
/// </para>
/// </remarks>
public void StopI2CReading()
{
byte[] command = new byte[5];
command[0] = SysExStart;
command[1] = 0x76;
command[2] = 0x00;
command[3] = 0x18;
command[4] = SysExEnd;
_connection.Write(command, 0, command.Length);
}
#endregion
#region IDisposable
/// <summary>
/// Closes the underlying connection.
/// </summary>
public void Dispose()
{
if (!_gotOpenConnection)
_connection.Close();
GC.SuppressFinalize(this);
}
#endregion
#region Private Methods
private void WriteMessageByte(byte dataByte)
{
if (_messageBufferIndex == Buffersize)
throw new OverflowException(Messages.OverflowEx_CmdBufferFull);
_messageBuffer[_messageBufferIndex] = dataByte;
_messageBufferIndex++;
}
private string GetStringFromQueue(StringRequest request)
{
_awaitedStringsQueue.Enqueue(request);
bool lockTaken = false;
try
{
Monitor.TryEnter(_receivedStringQueue, _messageTimeout, ref lockTaken);
while (lockTaken)
{
if (_receivedStringQueue.Count > 0)
{
string message = _receivedStringQueue.Dequeue();
Monitor.PulseAll(_receivedStringQueue);
return message;
}
lockTaken = Monitor.Wait(_receivedStringQueue, _messageTimeout);
}
throw new TimeoutException(string.Format(Messages.TimeoutEx_WaitStringRequest, request.Mode));
}
finally
{
if (lockTaken)
{
Monitor.Exit(_receivedStringQueue);
}
}
}
private object GetMessageFromQueue(FirmataMessage awaitedMessage)
{
_awaitedMessagesQueue.Enqueue(awaitedMessage);
bool lockTaken = false;
try
{
Monitor.TryEnter(_receivedMessageList, _messageTimeout, ref lockTaken);
while (lockTaken)
{
if (_receivedMessageList.Count > 0)
{
FirmataMessage message = _receivedMessageList.FirstOrDefault(m => m.Type == awaitedMessage.Type);
if (message != null)
{
_receivedMessageList.Remove(message);
Monitor.PulseAll(_receivedMessageList);
return message;
}
}
lockTaken = Monitor.Wait(_receivedMessageList, _messageTimeout);
}
throw new TimeoutException(string.Format(Messages.TimeoutEx_WaitMessage, awaitedMessage.Type));
}
finally
{
if (lockTaken)
{
Monitor.Exit(_receivedMessageList);
}
}
}
private void SendSysExCommand(byte command)
{
var message = new[]
{
SysExStart,
command,
SysExEnd
};
_connection.Write(message, 0, 3);
}
private void I2CSlaveRead(bool continuous, int slaveAddress, int slaveRegister = -1, int bytesToRead = 0)
{
if (slaveRegister < 0 || slaveRegister > 0x3FFF)
throw new ArgumentOutOfRangeException(nameof(slaveRegister), Messages.ArgumentEx_ValueRange0_16383);
I2CRead(continuous, slaveAddress, slaveRegister, bytesToRead);
}
private void I2CRead(bool continuous, int slaveAddress, int slaveRegister = -1, int bytesToRead = 0)
{
if (slaveAddress < 0 || slaveAddress > 0x3FF)
throw new ArgumentOutOfRangeException(nameof(slaveAddress), Messages.ArgumentEx_I2cAddressRange);
if (bytesToRead < 0 || bytesToRead > 0x3FFF)
throw new ArgumentOutOfRangeException(nameof(bytesToRead), Messages.ArgumentEx_ValueRange0_16383);
byte[] command = new byte[(slaveRegister == -1 ? 7 : 9)];
command[0] = SysExStart;
command[1] = 0x76;
command[2] = (byte)(slaveAddress & 0x7F);
command[3] = (byte)(((slaveAddress >> 7) & 0x07) | (slaveAddress < 128 ? (continuous ? 0x10 : 0x08) : (continuous ? 0x30 : 0x28)));
if (slaveRegister != -1)
{
command[4] = (byte)(slaveRegister & 0x7F);
command[5] = (byte)(slaveRegister >> 7);
command[6] = (byte)(bytesToRead & 0x7F);
command[7] = (byte)(bytesToRead >> 7);
}
else
{
command[4] = (byte)(bytesToRead & 0x7F);
command[5] = (byte)(bytesToRead >> 7);
}
command[command.Length - 1] = SysExEnd;
_connection.Write(command, 0, command.Length);
}
/// <summary>
/// Event handler processing data bytes received on the serial port.
/// </summary>
private void SerialDataReceived(object sender, SerialDataReceivedEventArgs e)
{
while (_connection.IsOpen && _connection.BytesToRead > 0)
{
var serialByte = (byte)_connection.ReadByte();
#if TRACE
if (_messageBufferIndex > 0 && _messageBufferIndex % 8 == 0)
Debug.WriteLine(string.Empty);
Debug.Write(string.Format("{0:x2} ", serialByte));
#endif
if (_processMessage != null)
{
_processMessage(serialByte);
}
else
{
if ((serialByte & 0x80) != 0)
{
// Process Firmata command byte.
ProcessCommand(serialByte);
}
else
{
// Process ASCII character.
ProcessAsciiString(serialByte);
}
}
}
}
private void ProcessAsciiString(int serialByte)
{
if (_stringBufferIndex == Buffersize)
throw new OverflowException(Messages.OverflowEx_StringBufferFull);
char c = Convert.ToChar(serialByte);
_stringBuffer[_stringBufferIndex] = c;
_stringBufferIndex++;
if (_currentStringRequest == null)
{
if (!_awaitedStringsQueue.TryDequeue(out _currentStringRequest))
{
// No pending Read/ReadLine/ReadTo requests.
// Handle StringReceived event.
if (c == _connection.NewLine[_connection.NewLine.Length - 1]
|| serialByte == 0x1A
|| serialByte == 0x00) // NewLine, EOF or terminating 0-byte?
{
StringReceived?.Invoke(this, new StringEventArgs(new string(_stringBuffer, 0, _stringBufferIndex - 1)));
_stringBufferIndex = 0;
}
return;
}
}
switch (_currentStringRequest.Mode)
{
case StringReadMode.ReadLine:
if (c == _connection.NewLine[0] || serialByte == 0x1A)
EnqueueReceivedString(new string(_stringBuffer, 0, _stringBufferIndex - 1));
else if (c == '\n') // Ignore linefeed, just in case cr+lf pair was expected.
_stringBufferIndex--;
break;
case StringReadMode.ReadBlock:
if (_stringBufferIndex == _currentStringRequest.BlockLength)
EnqueueReceivedString(new string(_stringBuffer, 0, _stringBufferIndex));
break;
case StringReadMode.ReadToTerminator:
if (c == _currentStringRequest.Terminator)
EnqueueReceivedString(new string(_stringBuffer, 0, _stringBufferIndex - 1));
break;
}
}
private void EnqueueReceivedString(string value)
{
bool lockTaken = false;
try
{
Monitor.TryEnter(_receivedStringQueue, _messageTimeout, ref lockTaken);
if (!lockTaken)
throw new TimeoutException();
if (_receivedStringQueue.Count >= MaxQueuelength)
throw new OverflowException(Messages.OverflowEx_StringBufferFull);
_receivedStringQueue.Enqueue(value);
Monitor.PulseAll(_receivedStringQueue);
_currentStringRequest = null;
_stringBufferIndex = 0;
}
finally
{
if (lockTaken)
Monitor.Exit(_receivedStringQueue);
}
}
private void ProcessCommand(byte serialByte)
{
_messageBuffer[0] = serialByte;
_messageBufferIndex = 1;
MessageHeader header = (MessageHeader)(serialByte & 0xF0);
switch (header)
{
case MessageHeader.AnalogState:
_processMessage = ProcessAnalogStateMessage;
return;
case MessageHeader.DigitalState:
_processMessage = ProcessDigitalStateMessage;
return;
case MessageHeader.SystemExtension:
header = (MessageHeader)serialByte;
switch (header)
{
case MessageHeader.SystemExtension:
_processMessage = ProcessSysExMessage;
return;
case MessageHeader.ProtocolVersion:
_processMessage = ProcessProtocolVersionMessage;
return;
//case MessageHeader.SetPinMode:
//case MessageHeader.SystemReset:
default:
// 0xF? command not supported.
break;
}
break;
default:
// Command not supported.
break;
}
// Ignore unexpected command.
_messageBuffer[0] = 0;
_messageBufferIndex = 0;
}
private void ProcessAnalogStateMessage(byte messageByte)
{
if (_messageBufferIndex < 2)
{
WriteMessageByte(messageByte);
}
else
{
var currentState = new AnalogState
{
Channel = _messageBuffer[0] & 0x0F,
Level = (_messageBuffer[1] | (messageByte << 7))
};
_processMessage = null;
MessageReceived?.Invoke(this, new FirmataMessageEventArgs(new FirmataMessage(currentState, MessageType.AnalogState)));
AnalogStateReceived?.Invoke(this, new FirmataEventArgs<AnalogState>(currentState));
}
}
private void ProcessDigitalStateMessage(byte messageByte)
{
if (_messageBufferIndex < 2)
{
WriteMessageByte(messageByte);
}
else
{
var currentState = new DigitalPortState
{
Port = _messageBuffer[0] & 0x0F,
Pins = _messageBuffer[1] | (messageByte << 7)
};
_processMessage = null;
MessageReceived?.Invoke(this, new FirmataMessageEventArgs(new FirmataMessage(currentState, MessageType.DigitalPortState)));
DigitalStateReceived?.Invoke(this, new FirmataEventArgs<DigitalPortState>(currentState));
}
}
private void ProcessProtocolVersionMessage(byte messageByte)
{
if (_messageBufferIndex < 2)
{
WriteMessageByte(messageByte);
}
else
{
var version = new ProtocolVersion
{
Major = _messageBuffer[1],
Minor = messageByte
};
DeliverMessage(new FirmataMessage(version, MessageType.ProtocolVersion));
}
}
private void ProcessSysExMessage(byte messageByte)
{
if (messageByte != SysExEnd)
{
WriteMessageByte(messageByte);
return;
}
switch ((SysExCommand)_messageBuffer[1])
{
case SysExCommand.AnalogMappingResponse:
DeliverMessage(CreateAnalogMappingResponse());
return;
case SysExCommand.CapabilityResponse:
DeliverMessage(CreateCapabilityResponse());
return;
case SysExCommand.PinStateResponse:
DeliverMessage(CreatePinStateResponse());
return;
case SysExCommand.StringData:
DeliverMessage(CreateStringDataMessage());
return;
case SysExCommand.I2cReply:
DeliverMessage(CreateI2CReply());
return;
case SysExCommand.ReportFirmware:
DeliverMessage(CreateFirmwareResponse());
return;
default: // Unknown or unsupported message
throw new NotSupportedException(string.Format(Messages.NotSupportedResponse, _messageBuffer[1]));
}
}
private void DeliverMessage(FirmataMessage message)
{
_processMessage = null;
lock (_receivedMessageList)
{
if (_receivedMessageList.Count >= MaxQueuelength)
throw new OverflowException(Messages.OverflowEx_MsgBufferFull);
// Remove all unprocessed and timed-out messages.
while (_receivedMessageList.Count > 0 &&
((DateTime.UtcNow - _receivedMessageList.First.Value.Time).TotalMilliseconds > TimeOut))
{
_receivedMessageList.RemoveFirst();
}
_receivedMessageList.AddLast(message);
Monitor.PulseAll(_receivedMessageList);
}
if (MessageReceived != null && message.Type != MessageType.I2CReply)
MessageReceived(this, new FirmataMessageEventArgs(message));
}
private FirmataMessage CreateI2CReply()
{
var reply = new I2CReply
{
Address = _messageBuffer[2] | (_messageBuffer[3] << 7),
Register = _messageBuffer[4] | (_messageBuffer[5] << 7)
};
var data = new byte[(_messageBufferIndex - 5) / 2];
for (int x = 0; x < data.Length; x++)
{
data[x] = (byte)(_messageBuffer[x * 2 + 6] | _messageBuffer[x * 2 + 7] << 7);
}
reply.Data = data;
I2CReplyReceived?.Invoke(this, new I2CEventArgs(reply));
return new FirmataMessage(reply, MessageType.I2CReply);
}
private FirmataMessage CreatePinStateResponse()
{
if (_messageBufferIndex < 5)
throw new InvalidOperationException(Messages.InvalidOpEx_PinNotSupported);
int value = 0;
for (int x = _messageBufferIndex - 1; x > 3; x--)
{
value = (value << 7) | _messageBuffer[x];
}
var pinState = new PinState
{
PinNumber = _messageBuffer[2],
Mode = (PinMode)_messageBuffer[3],
Value = value
};
return new FirmataMessage(pinState, MessageType.PinStateResponse);
}
private FirmataMessage CreateAnalogMappingResponse()
{
var pins = new List<AnalogPinMapping>(8);
for (int x = 2; x < _messageBufferIndex; x++)
{
if (_messageBuffer[x] != 0x7F)
{
pins.Add
(
new AnalogPinMapping
{
PinNumber = x - 2,
Channel = _messageBuffer[x]
}
);
}
}
var board = new BoardAnalogMapping { PinMappings = pins.ToArray() };
return new FirmataMessage(board, MessageType.AnalogMappingResponse);
}
private FirmataMessage CreateCapabilityResponse()
{
var pins = new List<PinCapability>(12);
int pinIndex = 0;
int x = 2;
while (x < _messageBufferIndex)
{
if (_messageBuffer[x] != 127)
{
var capability = new PinCapability { PinNumber = pinIndex };
while (x < _messageBufferIndex && _messageBuffer[x] != 127)
{
PinMode pinMode = (PinMode)_messageBuffer[x];
switch (pinMode)
{
case PinMode.AnalogInput:
capability.Analog = true;
capability.AnalogResolution = _messageBuffer[x + 1];
break;
case PinMode.DigitalInput:
capability.DigitalInput = true;
break;
case PinMode.DigitalOutput:
capability.DigitalOutput = true;
break;
case PinMode.PwmOutput:
capability.Pwm = true;
capability.PwmResolution = _messageBuffer[x + 1];
break;
case PinMode.ServoControl:
capability.Servo = true;
capability.ServoResolution = _messageBuffer[x + 1];
break;
case PinMode.I2C:
capability.I2C = true;
break;
case PinMode.OneWire:
capability.OneWire = true;
break;
case PinMode.StepperControl:
capability.StepperControl = true;
capability.MaxStepNumber = _messageBuffer[x + 1];
break;
case PinMode.Encoder:
capability.Encoder = true;
break;
case PinMode.Serial:
capability.Serial = true;
break;
case PinMode.InputPullup:
capability.InputPullup = true;
break;
default:
throw new NotImplementedException();
}
x += 2;
}
pins.Add(capability);
}
pinIndex++;
x++;
}
return new FirmataMessage(new BoardCapability { Pins = pins.ToArray() }, MessageType.CapabilityResponse);
}
private FirmataMessage CreateStringDataMessage()
{
var builder = new StringBuilder(_messageBufferIndex >> 1);
for (int x = 2; x < _messageBufferIndex; x += 2)
{
builder.Append((char)(_messageBuffer[x] | (_messageBuffer[x + 1] << 7)));
}
var stringData = new StringData
{
Text = builder.ToString()
};
return new FirmataMessage(stringData, MessageType.StringData);
}
private FirmataMessage CreateFirmwareResponse()
{
var firmware = new Firmware
{
MajorVersion = _messageBuffer[2],
MinorVersion = _messageBuffer[3]
};
var builder = new StringBuilder(_messageBufferIndex);
for (int x = 4; x < _messageBufferIndex; x += 2 )
{
builder.Append((char)(_messageBuffer[x] | (_messageBuffer[x + 1] << 7)));
}
firmware.Name = builder.ToString();
return new FirmataMessage(firmware, MessageType.FirmwareResponse);
}
#endregion
}
}
================================================
FILE: Solid.Arduino/EnhancedSerialConnection.cs
================================================
using System.IO.Ports;
using System.Linq;
namespace Solid.Arduino
{
/// <summary>
/// Represents a serial port connection, supporting Mono.
/// </summary>
/// <seealso href="http://www.mono-project.com/">The official Mono project site</seealso>
/// <inheritdoc />
public class EnhancedSerialConnection : EnhancedSerialPort, ISerialConnection
{
/// <summary>
/// Initializes a new instance of <see cref="EnhancedSerialConnection"/> class using the highest serial port available at 115,200 bits per second.
/// </summary>
public EnhancedSerialConnection()
: base(GetLastPortName(), (int)SerialBaudRate.Bps_115200)
{
ReadTimeout = 100;
WriteTimeout = 100;
}
/// <summary>
/// Initializes a new instance of <see cref="EnhancedSerialConnection"/> class on the given serial port and at the given baud rate.
/// </summary>
/// <param name="portName">The port name (e.g. 'COM3')</param>
/// <param name="baudRate">The baud rate</param>
public EnhancedSerialConnection(string portName, SerialBaudRate baudRate)
: base(portName, (int)baudRate)
{
ReadTimeout = 100;
WriteTimeout = 100;
}
/// <inheritdoc cref="SerialConnection.Find()"/>
public static ISerialConnection Find()
{
return SerialConnection.Find();
}
/// <inheritdoc cref="SerialConnection.Find(string, string)"/>
public static ISerialConnection Find(string query, string expectedReply)
{
return SerialConnection.Find(query, expectedReply);
}
/// <inheritdoc cref="SerialPort.Close"/>
public new void Close()
{
if (IsOpen)
{
BaseStream.Flush();
DiscardInBuffer();
base.Close();
}
}
private static string GetLastPortName() => GetPortNames()
.Where(p => p.StartsWith(@"/dev/ttyUSB") || p.StartsWith(@"/dev/ttyAMA") || p.StartsWith(@"/dev/ttyACM") || p.StartsWith("COM"))
.OrderByDescending(p => p)
.FirstOrDefault();
}
}
================================================
FILE: Solid.Arduino/EnhancedSerialPort.cs
================================================
// /*
// Copyright 2013 Antanas Veiverys antanas.veiverys.com
//
// Refactored 2014 by Henk van Boeijen.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// */
//
using System;
using System.IO.Ports;
using System.ComponentModel;
using System.IO;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Threading;
namespace Solid.Arduino
{
/// <summary>
/// Represents a system serial port, supporting .NET and Mono.
/// </summary>
/// <remarks>
/// This class is a workaround for Mono's <see cref="SerialPort"/> implementation of event <see cref="OnDataReceived"/>.
/// <para>
/// Copyright 2013 Antanas Veiverys <seealso href="https://antanas.veiverys.com">antanas.veiverys.com</seealso>
/// </para>
/// </remarks>
/// <inheritdoc cref="SerialPort" />
public class EnhancedSerialPort : SerialPort
{
[DllImport("MonoPosixHelper", SetLastError = true)]
private static extern bool poll_serial(int fd, out int error, int timeout);
[DllImport("libc")]
private static extern IntPtr strerror(int errnum);
#region Private Fields
// Private member access through reflection.
private int _fdStreamField;
private FieldInfo _disposedFieldInfo;
private object _dataReceived;
#endregion
#region Constructors
/// <inheritdoc cref="SerialPort()"/>
public EnhancedSerialPort()
{
}
/// <inheritdoc cref="SerialPort(IContainer)"/>
public EnhancedSerialPort(IContainer container)
: base(container)
{
}
/// <inheritdoc cref="SerialPort(string)"/>
public EnhancedSerialPort(string portName)
: this(portName, 9600, Parity.None, 8, StopBits.One)
{
}
/// <inheritdoc cref="SerialPort(string,int)"/>
public EnhancedSerialPort(string portName, int baudRate)
: this(portName, baudRate, Parity.None, 8, StopBits.One)
{
}
/// <inheritdoc cref="SerialPort(string,int,Parity)"/>
public EnhancedSerialPort(string portName, int baudRate, Parity parity)
: this(portName, baudRate, parity, 8, StopBits.One)
{
}
/// <inheritdoc cref="SerialPort(string,int,Parity,int)"/>
public EnhancedSerialPort(string portName, int baudRate, Parity parity, int dataBits)
: this(portName, baudRate, parity, dataBits, StopBits.One)
{
}
/// <inheritdoc cref="SerialPort(string,int,Parity,int,StopBits)"/>
public EnhancedSerialPort(string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits)
: base(GetInitializedPortName(portName), baudRate, parity, dataBits, stopBits)
{
}
private static string GetInitializedPortName(string portName)
{
if (IsWindows)
SerialPortFixer.Initialize(portName);
return portName;
}
#endregion
#region Public Methods
/// <inheritdoc cref="SerialPort.Open"/>
public new void Open()
{
base.Open();
if (IsWindows) return;
FieldInfo fieldInfo = BaseStream.GetType().GetField("fd", BindingFlags.Instance | BindingFlags.NonPublic);
if (fieldInfo != null)
{
_fdStreamField = (int) fieldInfo.GetValue(BaseStream);
_disposedFieldInfo = BaseStream.GetType()
.GetField("disposed", BindingFlags.Instance | BindingFlags.NonPublic);
fieldInfo = typeof (SerialPort).GetField("data_received", BindingFlags.Instance | BindingFlags.NonPublic);
if (fieldInfo != null)
_dataReceived = fieldInfo.GetValue(this);
}
new Thread(EventThreadFunction).Start();
}
#endregion
#region Private Methods
private static bool IsWindows
{
get
{
PlatformID id = Environment.OSVersion.Platform;
return id == PlatformID.Win32Windows || id == PlatformID.Win32NT; // WinCE not supported
}
}
private void EventThreadFunction()
{
do
{
try
{
var stream = BaseStream;
if (stream == null)
{
return;
}
if (Poll(stream))
{
OnDataReceived(null);
}
}
catch
{
return;
}
}
while (IsOpen);
}
private void OnDataReceived(SerialDataReceivedEventArgs args)
{
((SerialDataReceivedEventHandler)Events[_dataReceived])?.Invoke(this, args);
}
private bool Poll(Stream stream)
{
CheckDisposed(stream);
if (IsOpen == false)
{
throw new InvalidOperationException("Port is closed.");
}
bool pollResult = poll_serial(_fdStreamField, out int error, ReadTimeout);
if (error != -1)
return pollResult;
int errnum = Marshal.GetLastWin32Error();
string errorMessage = Marshal.PtrToStringAnsi(strerror(errnum));
throw new IOException(errorMessage);
}
private void CheckDisposed(Stream stream)
{
bool disposed = (bool)_disposedFieldInfo.GetValue(stream);
if (disposed)
{
throw new ObjectDisposedException(stream.GetType().FullName);
}
}
#endregion
}
}
================================================
FILE: Solid.Arduino/Firmata/AnalogPinMapping.cs
================================================
namespace Solid.Arduino.Firmata
{
/// <summary>
/// Represents a mapping between a MIDI channel and a physical pin number.
/// </summary>
public sealed class AnalogPinMapping
{
/// <summary>
/// Gets the MIDI channel number (0 - 15).
/// </summary>
public int Channel { get; internal set; }
/// <summary>
/// Gets the board's pin number (0 - 127).
/// </summary>
public int PinNumber { get; internal set; }
}
}
================================================
FILE: Solid.Arduino/Firmata/AnalogState.cs
================================================
namespace Solid.Arduino.Firmata
{
/// <summary>
/// Represents the analog level read from or set to an analog pin.
/// </summary>
public sealed class AnalogState
{
/// <summary>
/// Gets the MIDI channel number (0 - 15).
/// </summary>
/// <remarks>
/// The mapping of analog pins to channel numbers can be retrieved using the <see cref="IFirmataProtocol.GetBoardAnalogMapping"/> method.
/// </remarks>
public int Channel { get; internal set; }
/// <summary>
/// Gets the analog level.
/// </summary>
public long Level { get; internal set; }
}
}
================================================
FILE: Solid.Arduino/Firmata/AnalogStateTracker.cs
================================================
namespace Solid.Arduino.Firmata
{
internal class AnalogStateTracker : ObservableEventTracker<IFirmataProtocol, AnalogState>
{
private readonly int _channel;
internal AnalogStateTracker(IFirmataProtocol source, int channel = -1)
: base(source)
{
_channel = channel;
TrackingSource.AnalogStateReceived += Firmata_AnalogStateReceived;
}
public override void Dispose()
{
if (!IsDisposed)
{
TrackingSource.AnalogStateReceived -= Firmata_AnalogStateReceived;
base.Dispose();
}
}
void Firmata_AnalogStateReceived(object parSender, FirmataEventArgs<AnalogState> parEventArgs)
{
if (_channel >= 0 && _channel != parEventArgs.Value.Channel)
return;
Observers.ForEach(o => o.OnNext(parEventArgs.Value));
}
}
}
================================================
FILE: Solid.Arduino/Firmata/BoardAnalogMapping.cs
================================================
namespace Solid.Arduino.Firmata
{
/// <summary>
/// Represents a summary of mappings between MIDI channels and physical pin numbers.
/// </summary>
public sealed class BoardAnalogMapping
{
/// <summary>
/// Gets the channel mapping array of the board's analog pins.
/// </summary>
public AnalogPinMapping[] PinMappings { get; internal set; }
}
}
================================================
FILE: Solid.Arduino/Firmata/BoardCapability.cs
================================================
namespace Solid.Arduino.Firmata
{
/// <summary>
/// Represents a summary of pinmode capabilities supported by an Arduino board.
/// </summary>
public sealed class BoardCapability
{
/// <summary>
/// Gets the capability array of the board's pins.
/// </summary>
public PinCapability[] Pins { get; internal set; }
}
}
================================================
FILE: Solid.Arduino/Firmata/ByteArrayExtensions.cs
================================================
using System;
namespace Solid.Arduino.Firmata
{
/// <summary>
/// Provides extension methods for <see cref="byte"/> arrays.
/// </summary>
public static class ByteArrayExtensions
{
/// <summary>
/// Converts a <see cref="byte"/> array holding binary coded digits to a readable string.
/// </summary>
/// <param name="data">The binary coded digit bytes</param>
/// <param name="isLittleEndian">Value indicating if the first nibble contains the least significant part</param>
/// <returns>A string containing numeric data</returns>
/// <exception cref="ArgumentException">The array contains one or more non-BCD bytes.</exception>
public static string ConvertBinaryCodedDecimalToString(this byte[] data, bool isLittleEndian = false)
{
if (data is null)
throw new ArgumentNullException(nameof(data));
if (data.Length == 0)
return string.Empty;
char[] chars = new char[data.Length * 2];
int charIndex = 0;
if (isLittleEndian)
{
for (int x = data.Length - 1; x >= 0; x--)
{
chars[charIndex++] = ConvertToChar(data[x] & 0x0F);
chars[charIndex++] = ConvertToChar(data[x] >> 4);
}
}
else
{
for (int x = 0; x < data.Length; x++)
{
chars[charIndex++] = ConvertToChar(data[x] >> 4);
chars[charIndex++] = ConvertToChar(data[x] & 0x0F);
}
}
return new string(chars);
}
private static char ConvertToChar(int code)
{
if (code > 9)
throw new ArgumentException(Messages.ArgumentEx_CannotConvertBcd);
return Convert.ToChar(code | 0x30);
}
}
}
================================================
FILE: Solid.Arduino/Firmata/DigitalPortState.cs
================================================
using System;
namespace Solid.Arduino.Firmata
{
/// <summary>
/// Represents the pin states of a digital port.
/// </summary>
public sealed class DigitalPortState
{
/// <summary>
/// Gets the digital port number.
/// </summary>
public int Port { get; internal set; }
/// <summary>
/// Gets the bit-pattern value of the digital port.
/// </summary>
public int Pins { get; internal set; }
/// <summary>
/// Gets a value indicating if a pin is set (1 or 'high').
/// </summary>
/// <param name="pin">The 0-based pin number</param>
/// <returns><c>true</c> when the pin has a binary 1 value, otherwise <c>false</c></returns>
public bool IsSet(int pin)
{
if (pin < 0 || pin > 7)
throw new ArgumentOutOfRangeException(nameof(pin), Messages.ArgumentEx_PinRange0_7);
return (Pins & 1 << pin) > 0;
}
}
}
================================================
FILE: Solid.Arduino/Firmata/DigitalStateTracker.cs
================================================
namespace Solid.Arduino.Firmata
{
internal class DigitalStateTracker : ObservableEventTracker<IFirmataProtocol, DigitalPortState>
{
private readonly int _port;
internal DigitalStateTracker(IFirmataProtocol source, int port = -1)
: base(source)
{
_port = port;
TrackingSource.DigitalStateReceived += Firmata_DigitalStateReceived;
}
public override void Dispose()
{
if (!IsDisposed)
{
TrackingSource.DigitalStateReceived -= Firmata_DigitalStateReceived;
base.Dispose();
}
}
void Firmata_DigitalStateReceived(object parSender, FirmataEventArgs<DigitalPortState> parEventArgs)
{
if (_port >= 0 && _port != parEventArgs.Value.Port)
return;
Observers.ForEach(o => o.OnNext(parEventArgs.Value));
}
}
}
================================================
FILE: Solid.Arduino/Firmata/FirmataMessage.cs
================================================
using System;
namespace Solid.Arduino.Firmata
{
/// <summary>
/// Represents a Firmata message received from an Arduino or Arduino compatible system.
/// </summary>
public sealed class FirmataMessage
{
private readonly MessageType _type;
private readonly object _value;
private readonly DateTime _time;
/// <summary>
/// Initializes a new <see cref="FirmataMessage"/> instance.
/// </summary>
/// <param name="type">The type of message to be created.</param>
internal FirmataMessage(MessageType type)
: this(null, type, DateTime.UtcNow) { }
/// <summary>
/// Initializes a new <see cref="FirmataMessage"/> instance.
/// </summary>
/// <param name="value"></param>
/// <param name="type"></param>
internal FirmataMessage(object value, MessageType type)
: this(value, type, DateTime.UtcNow) { }
/// <summary>
/// Initializes a new <see cref="FirmataMessage"/> instance.
/// </summary>
/// <param name="value"></param>
/// <param name="type"></param>
/// <param name="time"></param>
internal FirmataMessage(object value, MessageType type, DateTime time)
{
_value = value;
_type = type;
_time = time;
}
/// <summary>
/// Gets the specific value delivered by the message.
/// </summary>
public object Value => _value;
/// <summary>
/// Gets the type enumeration of the message.
/// </summary>
public MessageType Type => _type;
/// <summary>
/// Gets the time of the delivered message.
/// </summary>
public DateTime Time => _time;
}
/// <summary>
/// Indicates the type of a Firmata Message.
/// </summary>
public enum MessageType
{
AnalogState,
DigitalPortState,
ProtocolVersion,
FirmwareResponse,
CapabilityResponse,
AnalogMappingResponse,
PinStateResponse,
StringData,
I2CReply
}
}
================================================
FILE: Solid.Arduino/Firmata/FirmataMessageEventArgs.cs
================================================
using System;
namespace Solid.Arduino.Firmata
{
/// <summary>
/// Event arguments passed to a <see cref="MessageReceivedHandler"/> type event.
/// </summary>
/// <see cref="MessageReceivedHandler"/>
public sealed class FirmataMessageEventArgs : EventArgs
{
private readonly FirmataMessage _value;
internal FirmataMessageEventArgs(FirmataMessage value)
{
_value = value;
}
/// <summary>
/// Gets the received message.
/// </summary>
public FirmataMessage Value => _value;
}
}
================================================
FILE: Solid.Arduino/Firmata/FirmataMessageEventArgs_.cs
================================================
using System;
namespace Solid.Arduino.Firmata
{
/// <summary>
/// Contains event data for a <see cref="AnalogStateReceivedHandler"/> and <see cref="DigitalStateReceivedHandler"/> type events.
/// </summary>
/// <typeparam name="T">Type of the event data</typeparam>
/// <remarks>
/// This class is primarily implemented by the <see cref="IFirmataProtocol.AnalogStateReceived"/> and <see cref="IFirmataProtocol.DigitalStateReceived"/> events.
/// </remarks>
/// <seealso cref="AnalogStateReceivedHandler"/>
/// <seealso cref="DigitalStateReceivedHandler"/>
public sealed class FirmataEventArgs<T> : EventArgs
where T : class
{
private readonly T _value;
internal FirmataEventArgs(T value)
{
_value = value;
}
/// <summary>
/// Gets the received message.
/// </summary>
public T Value => _value;
}
}
================================================
FILE: Solid.Arduino/Firmata/Firmware.cs
================================================
namespace Solid.Arduino.Firmata
{
/// <summary>
/// Identifies the Arduino board's firmware.
/// </summary>
public sealed class Firmware
{
/// <summary>
/// Gets the major version number.
/// </summary>
public int MajorVersion { get; internal set; }
/// <summary>
/// Gets the minor version number.
/// </summary>
public int MinorVersion { get; internal set; }
/// <summary>
/// Gets the name of the board's firmware.
/// </summary>
public string Name { get; internal set; }
}
}
================================================
FILE: Solid.Arduino/Firmata/IFirmataProtocol.cs
================================================
using System;
using System.Threading.Tasks;
namespace Solid.Arduino.Firmata
{
/// <summary>
/// Signature of event handlers capable of processing Firmata messages.
/// </summary>
/// <param name="sender">The object raising the event</param>
/// <param name="eventArgs">Event arguments holding a <see cref="FirmataMessage"/></param>
public delegate void MessageReceivedHandler(object sender, FirmataMessageEventArgs eventArgs);
/// <summary>
/// Signature of event handlers capable of processing analog I/O messages.
/// </summary>
/// <param name="sender">The object raising the event</param>
/// <param name="eventArgs">Event arguments holding a <see cref="AnalogState"/></param>
public delegate void AnalogStateReceivedHandler(object sender, FirmataEventArgs<AnalogState> eventArgs);
/// <summary>
/// Signature of event handlers capable of processing digital I/O messages.
/// </summary>
/// <param name="sender">The object raising the event</param>
/// <param name="eventArgs">Event arguments holding a <see cref="DigitalPortState"/></param>
public delegate void DigitalStateReceivedHandler(object sender, FirmataEventArgs<DigitalPortState> eventArgs);
/// <summary>
/// The modes a pin can be in or can be set to.
/// </summary>
public enum PinMode
{
Undefined = -1,
DigitalInput = 0,
DigitalOutput = 1,
AnalogInput = 2,
PwmOutput = 3,
ServoControl = 4,
I2C = 6,
OneWire = 7,
StepperControl = 8,
Encoder = 9,
Serial = 10,
InputPullup = 11
}
/// <summary>
/// Defines a comprehensive set of members supporting the Firmata Protocol.
/// Currently version 2.3 is supported.
/// </summary>
/// <seealso href="https://github.com/firmata/arduino">Firmata project on GitHub</seealso>
/// <seealso href="https://github.com/firmata/protocol">Firmata protocol details</seealso>
/// <seealso href="http://arduino.cc/en/reference/firmata">Firmata reference for Arduino</seealso>
public interface IFirmataProtocol
{
/// <summary>
/// Event, raised for every SysEx (0xF0) and ProtocolVersion (0xF9) message not handled by an <see cref="IFirmataProtocol"/>'s Get method.
/// </summary>
/// <remarks>
/// When e.g. method <see cref="RequestBoardCapability"/> is invoked, the party system's response message raises this event.
/// However, when method <see cref="GetBoardCapability"/> or <see cref="GetBoardCapabilityAsync"/> is invoked, the response is returned
/// to the respective method and event <see cref="MessageReceived"/> is not raised.
///
/// This event is not raised for either analog or digital I/O messages.
/// </remarks>
event MessageReceivedHandler MessageReceived;
/// <summary>
/// Event, raised when an analog state message (command 0xE0) is received.
/// </summary>
/// <remarks>
/// The frequency at which analog state messages are being sent by the party system can be set with method <see cref="SetSamplingInterval"/>.
/// </remarks>
event AnalogStateReceivedHandler AnalogStateReceived;
/// <summary>
/// Event, raised when a digital I/O message (command 0x90) is received.
/// </summary>
/// <remarks>
/// Please note that the StandardFirmata implementation for Arduino only sends updates of digital port states if necessary.
/// When none of a port's digital input pins have changed state since a previous polling cycle, no Firmata.sendDigitalPort message
/// is sent.
/// <para>
/// Also, calling method <see cref="SetDigitalReportMode"/> does not guarantee this event will receive a (first) Firmata.sendDigitalPort message.
/// Use method <see cref="GetPinState"/> or <see cref="GetPinStateAsync"/> inquiring the current pin states.
/// </para>
/// </remarks>
event DigitalStateReceivedHandler DigitalStateReceived;
/// <summary>
/// Creates an observable object tracking <see cref="AnalogState"/> messages.
/// </summary>
/// <returns>An <see cref="IObservable{AnalogState}"/> interface</returns>
IObservable<AnalogState> CreateAnalogStateMonitor();
/// <summary>
/// Creates an observable object tracking <see cref="AnalogState" /> messages for a specific channel.
/// </summary>
/// <param name="channel">The channel to track</param>
/// <returns>
/// An <see cref="IObservable{AnalogState}" /> interface
/// </returns>
IObservable<AnalogState> CreateAnalogStateMonitor(int channel);
/// <summary>
/// Creates an observable object tracking <see cref="DigitalPortState"/> messages.
/// </summary>
/// <returns>An <see cref="IObservable{DigitalPortState}"/> interface</returns>
IObservable<DigitalPortState> CreateDigitalStateMonitor();
/// <summary>
/// Creates an observable object tracking <see cref="DigitalPortState" /> messages for a specific port.
/// </summary>
/// <param name="port">The port to track</param>
/// <returns>
/// An <see cref="IObservable{DigitalPortState}" /> interface
/// </returns>
IObservable<DigitalPortState> CreateDigitalStateMonitor(int port);
/// <summary>
/// Sends a message string.
/// </summary>
/// <param name="data">The message string</param>
void SendStringData(string data);
/// <summary>
/// Enables or disables analog sampling reporting.
/// </summary>
/// <param name="channel">The channel attached to the analog pin</param>
/// <param name="enable"><c>True</c> if enabled, otherwise <c>false</c></param>
/// <remarks>
/// When enabled, the party system is expected to return analog I/O messages (0xE0)
/// for the given channel. The frequency at which these messages are returned can
/// be controlled by method <see cref="SetSamplingInterval"/>.
/// </remarks>
void SetAnalogReportMode(int channel, bool enable);
/// <summary>
/// Sets the digital output pins of a given port LOW or HIGH.
/// </summary>
/// <param name="portNumber">The 0-based port number</param>
/// <param name="pins">Binary value for the port's pins (0 to 7)</param>
/// <remarks>
/// A binary 1 sets the digital output pin HIGH (+5 or +3.3 volts).
/// A binary 0 sets the digital output pin LOW.
/// <para>
/// The Arduino operates with 8-bit ports, so only bits 0 to 7 of the pins parameter are mapped.
/// Higher bits are ignored.
/// </para>
/// <example>
/// For port 0 bit 2 maps to the Arduino Uno's pin 2.
/// For port 1 bit 2 maps to pin 10.
///
/// The complete mapping of port 1 of the Arduino Uno looks like this:
/// <list type="">
/// <item>bit 0: pin 8</item>
/// <item>bit 1: pin 9</item>
/// <item>bit 2: pin 10</item>
/// <item>bit 3: pin 11</item>
/// <item>bit 4: pin 12</item>
/// <item>bit 5: pin 13</item>
/// <item>bit 6: not mapped</item>
/// <item>bit 7: not mapped</item>
/// </list>
/// </example>
/// </remarks>
void SetDigitalPort(int portNumber, int pins);
/// <summary>
/// Enables or disables digital input pin reporting for the given port.
/// </summary>
/// <param name="portNumber">The number of the port</param>
/// <param name="enable"><c>true</c> if enabled, otherwise <c>false</c></param>
/// <remarks>
/// When enabled, the party system is expected to return digital I/O messages (0x90)
/// for the given port.
/// <para>
/// Note: as for Firmata version 2.3 digital I/O messages are only returned when
/// at least one digital input pin's state has changed from high to low or vice versa.
/// </para>
/// </remarks>
void SetDigitalReportMode(int portNumber, bool enable);
/// <summary>
/// Sets a pin's mode (digital input/digital output/analog/PWM/servo etc.).
/// </summary>
/// <param name="pinNumber">The number of the pin</param>
/// <param name="mode">The pin's mode</param>
void SetDigitalPinMode(int pinNumber, PinMode mode);
/// <summary>
/// Sets the frequency at which analog samples must be reported.
/// </summary>
/// <param name="milliseconds">The sampling interval in milliseconds</param>
void SetSamplingInterval(int milliseconds);
/// <summary>
/// Sets an analog value on a PWM or Servo enabled analog output pin.
/// </summary>
/// <param name="pinNumber">The pin number.</param>
/// <param name="value">The value</param>
void SetDigitalPin(int pinNumber, long value);
/// <summary>
/// Sets a HI or LO value on a digital output pin.
/// </summary>
/// <param name="pinNumber">The pin number</param>
/// <param name="value">The value (<c>false</c> = Low, <c>true</c> = High)</param>
void SetDigitalPin(int pinNumber, bool value);
/// <summary>
/// Sends a reset message to the party system.
/// </summary>
void ResetBoard();
/// <summary>
/// Requests the party system to send a protocol version message.
/// </summary>
/// <remarks>
/// The party system is expected to return a single protocol version message (0xF9).
/// This message triggers the <see cref="MessageReceived"/> event. The protocol version
/// is passed in the <see cref="FirmataMessageEventArgs"/> in a <see cref="ProtocolVersion"/> object.
/// </remarks>
void RequestProtocolVersion();
/// <summary>
/// Gets the protocol version implemented on the party system.
/// </summary>
/// <returns>The implemented protocol version</returns>
ProtocolVersion GetProtocolVersion();
/// <summary>
/// Asynchronously gets the protocol version implemented on the party system.
/// </summary>
/// <returns>The implemented protocol version</returns>
Task<ProtocolVersion> GetProtocolVersionAsync();
/// <summary>
/// Requests the party system to send a firmware message.
/// </summary>
/// <remarks>
/// The party system is expected to return a single SYSEX REPORT_FIRMWARE message.
/// This message triggers the <see cref="MessageReceived"/> event. The firmware signature
/// is passed in the <see cref="FirmataMessageEventArgs"/> in a <see cref="Firmware"/> object.
/// </remarks>
void RequestFirmware();
/// <summary>
/// Gets the firmware signature of the party system.
/// </summary>
/// <returns>The firmware signature</returns>
Firmware GetFirmware();
/// <summary>
/// Asynchronously gets the firmware signature of the party system.
/// </summary>
/// <returns>The firmware signature</returns>
Task<Firmware> GetFirmwareAsync();
/// <summary>
/// Requests the party system to send a summary of its capabilities.
/// </summary>
/// <remarks>
/// The party system is expected to return a single SYSEX CAPABILITY_RESPONSE message.
/// This message triggers the <see cref="MessageReceived"/> event. The capabilities
/// are passed in the <see cref="FirmataMessageEventArgs"/> in a <see cref="BoardCapability"/> object.
/// </remarks>
void RequestBoardCapability();
/// <summary>
/// Gets a summary of the party system's capabilities.
/// </summary>
/// <returns>The system's capabilities</returns>
BoardCapability GetBoardCapability();
/// <summary>
/// Asynchronously gets a summary of the party system's capabilities.
/// </summary>
/// <returns>The system's capabilities</returns>
Task<BoardCapability> GetBoardCapabilityAsync();
/// <summary>
/// Requests the party system to send the channel-to-pin mappings of its analog lines.
/// </summary>
/// <remarks>
/// The party system is expected to return a single SYSEX ANALOG_MAPPING_RESPONSE message.
/// This message triggers the <see cref="MessageReceived"/> event. The analog mappings are
/// passed in the <see cref="FirmataMessageEventArgs"/> in a <see cref="BoardAnalogMapping"/> object.
/// </remarks>
void RequestBoardAnalogMapping();
/// <summary>
/// Gets the channel-to-pin mappings of the party system's analog lines.
/// </summary>
/// <returns>The channel-to-pin mappings</returns>
BoardAnalogMapping GetBoardAnalogMapping();
/// <summary>
/// Asynchronously gets the channel-to-pin mappings of the party system's analog lines.
/// </summary>
/// <returns>The channel-to-pin mappings</returns>
Task<BoardAnalogMapping> GetBoardAnalogMappingAsync();
/// <summary>
/// Requests the party system to send the state of a given pin.
/// </summary>
/// <param name="pinNumber">The pin number</param>
/// <remarks>
/// The party system is expected to return a single SYSEX PINSTATE_RESPONSE message.
/// This message triggers the <see cref="MessageReceived"/> event. The pin state
/// is passed in the <see cref="FirmataMessageEventArgs"/> in a <see cref="PinState"/> object.
/// </remarks>
void RequestPinState(int pinNumber);
/// <summary>
/// Gets a pin's mode (digital input/output, analog etc.) and actual value.
/// </summary>
/// <param name="pinNumber">The pin number</param>
/// <returns>The pin's state</returns>
PinState GetPinState(int pinNumber);
/// <summary>
/// Asynchronously gets a pin's mode (digital input/output, analog etc.) and actual value.
/// </summary>
/// <param name="pinNumber">The pin number</param>
/// <returns>The pin's state</returns>
Task<PinState> GetPinStateAsync(int pinNumber);
}
}
================================================
FILE: Solid.Arduino/Firmata/PinCapability.cs
================================================
namespace Solid.Arduino.Firmata
{
/// <summary>
/// Contains information about the capabilities of a pin.
/// </summary>
public sealed class PinCapability
{
/// <summary>
/// Gets the 0-based number of the pin.
/// </summary>
public int PinNumber { get; internal set; }
/// <summary>
/// Gets a value indicating if the pin can be in digital input mode.
/// </summary>
public bool DigitalInput { get; internal set; }
/// <summary>
/// Gets a value indicating if the pin can be in digital output mode.
/// </summary>
public bool DigitalOutput { get; internal set; }
/// <summary>
/// Gets a value indicating if it is an analog pin.
/// </summary>
public bool Analog { get; internal set; }
/// <summary>
/// Gets a value indicating if the pin supports pulse width modulation.
/// </summary>
public bool Pwm { get; internal set; }
/// <summary>
/// Gets a value indicating if the pin supports servo motor control.
/// </summary>
public bool Servo { get; internal set; }
/// <summary>
/// Gets the bit resolution for analog pins.
/// </summary>
public int AnalogResolution { get; internal set; }
/// <summary>
/// Gets the bit resolution for PWM enabled pins.
/// </summary>
public int PwmResolution { get; internal set; }
/// <summary>
/// Gets the bit resolution for servo enabled pins.
/// </summary>
public int ServoResolution { get; internal set; }
/// <summary>
/// Gets a value indicating if it is an I2c pin.
/// </summary>
public bool I2C { get; internal set; }
/// <summary>
/// Gets a value indicating if it is an OneWire pin.
/// </summary>
public bool OneWire { get; internal set; }
/// <summary>
/// Gets a value indicating if it is a Stepper Control pin.
/// </summary>
public bool StepperControl { get; internal set; }
/// <summary>
/// Gets a value indicating if it is an encoder pin.
/// </summary>
public bool Encoder { get; internal set; }
/// <summary>
/// Gets a value indicating if it is a serial pin.
/// </summary>
public bool Serial { get; internal set; }
/// <summary>
/// Gets a value indicating if it is an input pullup pin.
/// </summary>
public bool InputPullup { get; internal set; }
/// <summary>
/// Gets the maximum number of steps if it is a Stepper Control pin.
/// </summary>
public int MaxStepNumber { get; internal set; }
}
}
================================================
FILE: Solid.Arduino/Firmata/PinState.cs
================================================
namespace Solid.Arduino.Firmata
{
/// <summary>
/// Contains information about a pin's state.
/// </summary>
public sealed class PinState
{
/// <summary>
/// The 0-based pin number
/// </summary>
public int PinNumber { get; internal set; }
/// <summary>
/// Gets pin's operating mode.
/// </summary>
public PinMode Mode { get; internal set; }
/// <summary>
/// Gets the value of the pin.
/// </summary>
/// <remarks>
/// For analog pins the value is 0 or a positive number. For digital pins a low is represented by 0 and a high is respresented by 1.
/// </remarks>
public long Value { get; internal set; }
}
}
================================================
FILE: Solid.Arduino/Firmata/ProtocolVersion.cs
================================================
namespace Solid.Arduino.Firmata
{
/// <summary>
/// Represents the Firmata communication protocol version.
/// </summary>
public sealed class ProtocolVersion
{
/// <summary>
/// Gets or sets the major version number.
/// </summary>
public int Major { get; set; }
/// <summary>
/// Gets or sets the minor version number.
/// </summary>
public int Minor { get; set; }
}
}
================================================
FILE: Solid.Arduino/Firmata/Servo/IServoProtocol.cs
================================================
namespace Solid.Arduino.Firmata.Servo
{
/// <summary>
/// Defines Servo control related members of the Firmata protocol.
/// </summary>
/// <remarks>
/// This interface is separated from the <see cref="IFirmataProtocol"/> interface, in order to
/// protect the latter against feature bloat.
/// </remarks>
public interface IServoProtocol
{
/// <summary>
/// Configures the minimum and maximum pulse length for a servo pin.
/// </summary>
/// <param name="pinNumber">The pin number</param>
/// <param name="minPulse">Minimum pulse length</param>
/// <param name="maxPulse">Maximum pulse length</param>
void ConfigureServo(int pinNumber, int minPulse, int maxPulse);
}
}
================================================
FILE: Solid.Arduino/Firmata/StringData.cs
================================================
namespace Solid.Arduino.Firmata
{
/// <summary>
/// Represents a string exchanged with the Firmata SYSEX STRING_DATA command.
/// </summary>
public sealed class StringData
{
/// <summary>
/// Gets or sets the string.
/// </summary>
public string Text { get; set; }
}
}
================================================
FILE: Solid.Arduino/Firmata/SysExCommand.cs
================================================
namespace Solid.Arduino.Firmata
{
/// <summary>
/// SysEx message command bytes
/// </summary>
public enum SysExCommand: byte
{
/// <summary>
/// User defined ID 0x01
/// </summary>
UserDefined_0x01 = 0x01,
/// <summary>
/// User defined ID 0x02
/// </summary>
UserDefined_0x02 = 0x02,
/// <summary>
/// User defined ID 0x03
/// </summary>
UserDefined_0x03 = 0x03,
/// <summary>
/// User defined ID 0x04
/// </summary>
UserDefined_0x04 = 0x04,
/// <summary>
/// User defined ID 0x05
/// </summary>
UserDefined_0x05 = 0x05,
/// <summary>
/// User defined ID 0x06
/// </summary>
UserDefined_0x06 = 0x06,
/// <summary>
/// User defined ID 0x07
/// </summary>
UserDefined_0x07 = 0x07,
/// <summary>
/// User defined ID 0x08
/// </summary>
UserDefined_0x08 = 0x08,
/// <summary>
/// User defined ID 0x09
/// </summary>
UserDefined_0x09 = 0x09,
/// <summary>
/// User defined ID 0x0A
/// </summary>
UserDefined_0x0A = 0x0A,
/// <summary>
/// User defined ID 0x0B
/// </summary>
UserDefined_0x0B = 0x0B,
/// <summary>
/// User defined ID 0x0C
/// </summary>
UserDefined_0x0C = 0x0C,
/// <summary>
/// User defined ID 0x0D
/// </summary>
UserDefined_0x0D = 0x0D,
/// <summary>
/// User defined ID 0x0E
/// </summary>
UserDefined_0x0E = 0x0E,
/// <summary>
/// User defined ID 0x0F
/// </summary>
UserDefined_0x0F = 0x0F,
/// <summary>
/// Analog mapping query
/// </summary>
AnalogMappingQuery = 0x69,
/// <summary>
/// Analog mapping response
/// </summary>
AnalogMappingResponse = 0x6A,
/// <summary>
/// Capability query
/// </summary>
CapabilityQuery = 0x6B,
/// <summary>
/// Capability response
/// </summary>
CapabilityResponse = 0x6C,
/// <summary>
/// Pin state query
/// </summary>
PinStateQuery = 0x6D,
/// <summary>
/// Pin state response
/// </summary>
PinStateResponse = 0x6E,
/// <summary>
/// Extended analog
/// </summary>
ExtendedAnalog = 0x6F,
/// <summary>
/// String data
/// </summary>
StringData = 0x71,
/// <summary>
/// I2C request
/// </summary>
I2cRequest = 0x76,
/// <summary>
/// I2C reply
/// </summary>
I2cReply = 0x77,
/// <summary>
/// Report firmware
/// </summary>
ReportFirmware = 0x79,
/// <summary>
/// Sampling interval
/// </summary>
SamplingInterval = 0x7A,
/// <summary>
/// SysEx not-realtime
/// </summary>
SysExNonRealtime = 0x7E,
/// <summary>
/// SysEx realtime
/// </summary>
SysExRealtime = 0x7F,
}
}
================================================
FILE: Solid.Arduino/I2c/I2cEventArgs.cs
================================================
using System;
namespace Solid.Arduino.I2C
{
/// <summary>
/// Event arguments passed to a <see cref="I2CReplyReceivedHandler"/> type event.
/// </summary>
public class I2CEventArgs : EventArgs
{
private readonly I2CReply _value;
internal I2CEventArgs(I2CReply value)
{
_value = value;
}
/// <summary>
/// Gets the I2C message value being received.
/// </summary>
public I2CReply Value => _value;
}
}
================================================
FILE: Solid.Arduino/I2c/I2cReply.cs
================================================
namespace Solid.Arduino.I2C
{
/// <summary>
/// Container for an I2C message
/// </summary>
public struct I2CReply
{
/// <summary>
/// Gets or sets the memory address.
/// </summary>
public int Address { get; set; }
/// <summary>
/// Gets or sets the register number.
/// </summary>
public int Register { get; set; }
/// <summary>
/// Gets or sets the binary data.
/// </summary>
public byte[] Data { get; set; }
}
}
================================================
FILE: Solid.Arduino/I2c/I2cReplyTracker.cs
================================================
namespace Solid.Arduino.I2C
{
internal class I2CReplyTracker : ObservableEventTracker<II2CProtocol, I2CReply>
{
internal I2CReplyTracker(II2CProtocol ii2C): base(ii2C)
{
TrackingSource.I2CReplyReceived += I2CReplyReceived;
}
public override void Dispose()
{
if (!IsDisposed)
{
TrackingSource.I2CReplyReceived -= I2CReplyReceived;
base.Dispose();
}
}
private void I2CReplyReceived(object parSender, I2CEventArgs parEventArgs)
{
Observers.ForEach(o => o.OnNext(parEventArgs.Value));
}
}
}
================================================
FILE: Solid.Arduino/I2c/II2cProtocol.cs
================================================
using System;
using System.Threading.Tasks;
using Solid.Arduino.Firmata;
namespace Solid.Arduino.I2C
{
/// <summary>
/// Signature of event handlers capable of processing I2C_REPLY messages.
/// </summary>
/// <param name="sender">The object raising the event</param>
/// <param name="eventArgs">Event arguments holding an <see cref="I2CReply"/></param>
public delegate void I2CReplyReceivedHandler(object sender, I2CEventArgs eventArgs);
/// <summary>
/// Defines a comprehensive set of members supporting the I2C Protocol.
/// </summary>
/// <seealso href="http://www.i2c-bus.org/">I2C bus website by telos Systementwicklung GmbH</seealso>
/// <seealso href="http://www.arduino.cc/en/Reference/Wire">Arduino Wire reference</seealso>
/// <seealso href="http://playground.arduino.cc/Main/I2cScanner">I2C Scanner sample sketch for Arduino</seealso>
public interface II2CProtocol
{
/// <summary>
/// Event, raised for every SYSEX I2C message not handled by an <see cref="II2CProtocol"/>'s Get method.
/// </summary>
/// <remarks>
/// When e.g. methods <see cref="ReadI2COnce(int,int)"/> and <see cref="ReadI2CContinuous(int,int)"/> are invoked,
/// the party system's response messages raise this event.
/// However, when method <see cref="GetI2CReply(int,int)"/> or <see cref="GetI2CReplyAsync(int,int)"/> is invoked,
/// the response received is returned to the method that issued the command and event <see cref="I2CReplyReceived"/> is not raised.
/// </remarks>
event I2CReplyReceivedHandler I2CReplyReceived;
/// <summary>
/// Creates an observable object tracking <see cref="I2CReply"/> messages.
/// </summary>
/// <returns>An <see cref="IObservable{I2cReply}"/> interface</returns>
IObservable<I2CReply> CreateI2CReplyMonitor();
/// <summary>
/// Sets the frequency at which data is read in the continuous mode.
/// </summary>
/// <param name="microseconds">The interval, expressed in microseconds</param>
void SetI2CReadInterval(int microseconds);
/// <summary>
/// Writes an arbitrary array of bytes to the given memory address.
/// </summary>
/// <param name="slaveAddress">The slave's target address</param>
/// <param name="data">The data array</param>
void WriteI2C(int slaveAddress, params byte[] data);
/// <summary>
/// Requests the party system to send bytes read from the given memory address.
/// </summary>
/// <param name="slaveAddress">The slave's memory address</param>
/// <param name="bytesToRead">Number of bytes to read</param>
/// <remarks>
/// The party system is expected to return a single I2C_REPLY message.
/// This message triggers the <see cref="I2CReplyReceived"/> event. The data
/// are passed in the <see cref="FirmataEventArgs{T}"/> in an <see cref="I2CReply"/> object.
/// </remarks>
void ReadI2COnce(int slaveAddress, int bytesToRead);
/// <summary>
/// Requests the party system to send bytes read from the given memory address and register.
/// </summary>
/// <param name="slaveAddress">The slave's memory address</param>
/// <param name="slaveRegister">The slave's register</param>
/// <param name="bytesToRead">Number of bytes to read</param>
void ReadI2COnce(int slaveAddress, int slaveRegister, int bytesToRead);
/// <summary>
/// Requests the party system to repeatedly send bytes read from the given memory address.
/// </summary>
/// <param name="slaveAddress">The slave's address</param>
/// <param name="bytesToRead">Number of bytes to read</param>
/// <remarks>
/// The party system is expected to return a continuous stream of I2C_REPLY messages at
/// an interval which can be set using the <see cref="SetI2CReadInterval"/> method.
/// Received I2C_REPLY messages trigger the <see cref="I2CReplyReceived"/> event. The data
/// are served in the <see cref="I2CEventArgs"/>'s Value property as an <see cref="I2CReply"/> object.
/// <para>
/// The party system can be stopped sending I2C_REPLY messages by issuing a <see cref="StopI2CReading"/> command.
/// </para>
/// </remarks>
void ReadI2CContinuous(int slaveAddress, int bytesToRead);
/// <summary>
/// Requests the party system to repeatedly send bytes read from the given memory address and register.
/// </summary>
/// <param name="slaveAddress">The slave's memory address</param>
/// <param name="slaveRegister">The slave's register</param>
/// <param name="bytesToRead">Number of bytes to read</param>
void ReadI2CContinuous(int slaveAddress, int slaveRegister, int bytesToRead);
/// <summary>
/// Commands the party system to stop sending I2C_REPLY messages.
/// </summary>
void StopI2CReading();
/// <summary>
/// Gets byte data from the party system, read from the given memory address.
/// </summary>
/// <param name="slaveAddress">The slave's memory address</param>
/// <param name="bytesToRead">Number of bytes to read</param>
/// <returns>An <see cref="I2CReply"/> object holding the data read</returns>
I2CReply GetI2CReply(int slaveAddress, int bytesToRead);
/// <summary>
/// Asynchronously gets byte data from the party system, read from the given memory address.
/// </summary>
/// <param name="slaveAddress">The slave's memory address</param>
/// <param name="bytesToRead">Number of bytes to read</param>
/// <returns>An awaitable <see cref="Task{I2cReply}"/> holding the data read</returns>
Task<I2CReply> GetI2CReplyAsync(int slaveAddress, int bytesToRead);
/// <summary>
/// Gets byte data from the party system, read from the given memory address and register.
/// </summary>
/// <param name="slaveAddress">The slave's memory address and register</param>
/// <param name="slaveRegister">The slave's register</param>
/// <param name="bytesToRead">Number of bytes to read</param>
/// <returns>An <see cref="I2CReply"/> object holding the data read</returns>
I2CReply GetI2CReply(int slaveAddress, int slaveRegister, int bytesToRead);
/// <summary>
/// Asynchronously gets byte data from the party system, read from the given memory address and register.
/// </summary>
/// <param name="slaveAddress">The slave's memory address</param>
/// <param name="slaveRegister">The slave's register</param>
/// <param name="bytesToRead">Number of bytes to read</param>
/// <returns>An awaitable <see cref="Task{I2cReply}"/> holding the data read</returns>
Task<I2CReply> GetI2CReplyAsync(int slaveAddress, int slaveRegister, int bytesToRead);
}
}
================================================
FILE: Solid.Arduino/ISerialConnection.cs
================================================
using System;
using System.IO.Ports;
namespace Solid.Arduino
{
/// <summary>
/// Defines a serial port connection.
/// </summary>
/// <seealso href="http://arduino.cc/en/Reference/Serial">Serial reference for Arduino</seealso>
public interface ISerialConnection: IDisposable
{
/// <summary>
/// Represents the method that will handle the data received event of a <see cref="ISerialConnection"/> object.
/// </summary>
event SerialDataReceivedEventHandler DataReceived;
/// <inheritdoc cref="SerialPort.BaudRate"/>
int BaudRate { get; set; }
/// <inheritdoc cref="SerialPort.PortName"/>
string PortName { get; set; }
/// <summary>
/// Gets a value indicating the open or closed status of the <see cref="ISerialConnection"/> object.
/// </summary>
bool IsOpen { get; }
/// <summary>
/// Gets or sets the value used to interpret the end of strings received and sent
/// using <see cref="IStringProtocol.ReadLine"/> and <see cref="IStringProtocol.WriteLine"/> methods.
/// </summary>
/// <remarks>
/// The default is a line feed, (<see cref="Environment.NewLine"/>).
/// </remarks>
string NewLine { get; set; }
/// <summary>
/// Gets the number of bytes of data in the receive buffer.
/// </summary>
int BytesToRead { get; }
/// <summary>
/// Opens the connection.
/// </summary>
void Open();
/// <summary>
/// Closes the connection.
/// </summary>
void Close();
/// <summary>
/// Reads a byte from the underlying serial input data stream.
/// </summary>
/// <returns>A byte value</returns>
int ReadByte();
/// <summary>
/// Writes a string to the serial output data stream.
/// </summary>
/// <param name="text">A string to be written</param>
void Write(string text);
/// <summary>
/// Writes a specified number of bytes to the serial output stream using data from a byte array.
/// </summary>
/// <param name="buffer">The byte array that contains the data to write</param>
/// <param name="offset">The zero-based byte offset in the array at which to begin copying bytes</param>
/// <param name="count">The number of bytes to write</param>
void Write(byte[] buffer, int offset, int count);
/// <summary>
/// Writes the specified string and the <see cref="SerialPort.NewLine"/> value to the serial output stream.
/// </summary>
/// <param name="text">The string to write</param>
void WriteLine(string text);
}
}
================================================
FILE: Solid.Arduino/IStringProtocol.cs
================================================
using System;
using System.IO.Ports;
using System.Threading.Tasks;
namespace Solid.Arduino
{
/// <summary>
/// Signature of event handlers capable of processing received strings.
/// </summary>
/// <param name="sender">The object raising the event</param>
/// <param name="eventArgs">Event arguments holding a <see cref="string"/> message</param>
public delegate void StringReceivedHandler(object sender, StringEventArgs eventArgs);
/// <summary>
/// Defines members for sending and receiving ASCII string messages.
/// </summary>
public interface IStringProtocol
{
/// <summary>
/// Event, raised for every ASCII stringmessage not handled by an <see cref="IStringProtocol"/>'s
/// Read, ReadAsync, ReadLine, ReadLineAsync, ReadTo or ReadToAsync method
/// </summary>
/// <remarks>
/// Any spontaneous received string message, terminated with a newline or eof character raises this event.
/// </remarks>
event StringReceivedHandler StringReceived;
/// <summary>
/// Creates an observable object tracking received ASCII <see cref="string"/> messages.
/// </summary>
/// <returns>An <see cref="IObservable{String}"/> interface</returns>
IObservable<string> CreateReceivedStringMonitor();
/// <summary>
/// Gets or sets the value used to interpret the end of strings received and sent.
/// </summary>
string NewLine { get; set; }
/// <summary>
/// Writes a string to the serial output data stream.
/// </summary>
/// <param name="value">A string to be written</param>
void Write(string value = null);
/// <summary>
/// Writes the specified string and the <see cref="SerialPort.NewLine"/> value to the serial output stream.
/// </summary>
/// <param name="value">The string to write</param>
void WriteLine(string value = null);
/// <summary>
/// Reads a string up to the next <see cref="NewLine"/> character.
/// </summary>
/// <returns>The string read</returns>
string ReadLine();
/// <summary>
/// Reads a string asynchronous up to the next <see cref="NewLine"/> character.
/// </summary>
/// <returns>An awaitable <see cref="Task{String}"/> returning the string read</returns>
Task<string> ReadLineAsync();
/// <summary>
/// Reads a specified number of characters.
/// </summary>
/// <param name="length">The number of characters to be read (default is 1)</param>
/// <returns>The string read</returns>
string Read(int length = 1);
/// <summary>
/// Reads a specified number of characters asynchronous.
/// </summary>
/// <param name="length">The number of characters to be read (default is 1)</param>
/// <returns>An awaitable <see cref="Task{String}"/> returning the string read</returns>
Task<string> ReadAsync(int length = 1);
/// <summary>
/// Reads a string up to the first terminating character.
/// </summary>
/// <param name="terminator">The character identifying the end of the string</param>
/// <returns>The string read</returns>
string ReadTo(char terminator);
/// <summary>
/// Reads a string asynchronous up to the first terminating character.
/// </summary>
/// <param name="terminator">The character identifying the end of the string</param>
/// <returns>An awaitable <see cref="Task{String}"/> returning the string read</returns>
Task<string> ReadToAsync(char terminator);
}
}
================================================
FILE: Solid.Arduino/Messages.Designer.cs
================================================
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Solid.Arduino {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Messages {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Messages() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Solid.Arduino.Messages", typeof(Messages).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to Cannot convert non-BCD data..
/// </summary>
internal static string ArgumentEx_CannotConvertBcd {
get {
return ResourceManager.GetString("ArgumentEx_CannotConvertBcd", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Channel number must be between 0 and 15..
/// </summary>
internal static string ArgumentEx_ChannelRange0_15 {
get {
return ResourceManager.GetString("ArgumentEx_ChannelRange0_15", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to String must contain digits only..
/// </summary>
internal static string ArgumentEx_DigitStringOnly {
get {
return ResourceManager.GetString("ArgumentEx_DigitStringOnly", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Address must be between 0 and 1,023..
/// </summary>
internal static string ArgumentEx_I2cAddressRange {
get {
return ResourceManager.GetString("ArgumentEx_I2cAddressRange", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Interval must be between 0 and 16,383 milliseconds..
/// </summary>
internal static string ArgumentEx_I2cInterval {
get {
return ResourceManager.GetString("ArgumentEx_I2cInterval", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Maximum pulse width must be between 0 and 16,383 milliseconds..
/// </summary>
internal static string ArgumentEx_MaxPulseWidth {
get {
return ResourceManager.GetString("ArgumentEx_MaxPulseWidth", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Minimum pulse width is greater than maximum pulse width..
/// </summary>
internal static string ArgumentEx_MinMaxPulse {
get {
return ResourceManager.GetString("ArgumentEx_MinMaxPulse", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Minimum pulse width must be between 0 and 16,383 milliseconds..
/// </summary>
internal static string ArgumentEx_MinPulseWidth {
get {
return ResourceManager.GetString("ArgumentEx_MinPulseWidth", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Value cannot be negative..
/// </summary>
internal static string ArgumentEx_NoNegativeValue {
get {
return ResourceManager.GetString("ArgumentEx_NoNegativeValue", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to String argument can not be null or empty..
/// </summary>
internal static string ArgumentEx_NotNullOrEmpty {
get {
return ResourceManager.GetString("ArgumentEx_NotNullOrEmpty", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Pin number must be between 0 and 127..
/// </summary>
internal static string ArgumentEx_PinRange0_127 {
get {
return ResourceManager.GetString("ArgumentEx_PinRange0_127", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Pin must be between 0 and 7..
/// </summary>
internal static string ArgumentEx_PinRange0_7 {
get {
return ResourceManager.GetString("ArgumentEx_PinRange0_7", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Port number must be between 0 and 15..
/// </summary>
internal static string ArgumentEx_PortRange0_15 {
get {
return ResourceManager.GetString("ArgumentEx_PortRange0_15", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Value must be greater than zero..
/// </summary>
internal static string ArgumentEx_PositiveValue {
get {
return ResourceManager.GetString("ArgumentEx_PositiveValue", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Sampling interval must be between 0 and 16,383 milliseconds..
/// </summary>
internal static string ArgumentEx_SamplingInterval {
get {
return ResourceManager.GetString("ArgumentEx_SamplingInterval", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Value must be between 0 and 16,383..
/// </summary>
internal static string ArgumentEx_ValueRange0_16383 {
get {
return ResourceManager.GetString("ArgumentEx_ValueRange0_16383", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Value must be betwen 0 and 255..
/// </summary>
internal static string ArgumentEx_ValueRange0_255 {
get {
return ResourceManager.GetString("ArgumentEx_ValueRange0_255", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Pin is not supported..
/// </summary>
internal static string InvalidOpEx_PinNotSupported {
get {
return ResourceManager.GetString("InvalidOpEx_PinNotSupported", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Invalid serial port.
/// </summary>
internal static string InvalidSerialPort {
get {
return ResourceManager.GetString("InvalidSerialPort", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Commandbyte 0x{0:X} is not implemented..
/// </summary>
internal static string NotImplementedEx_Command {
get {
return ResourceManager.GetString("NotImplementedEx_Command", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Response message code 0x{0:X} is not supported..
/// </summary>
internal static string NotSupportedResponse {
get {
return ResourceManager.GetString("NotSupportedResponse", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The command parsing buffer is full..
/// </summary>
internal static string OverflowEx_CmdBufferFull {
get {
return ResourceManager.GetString("OverflowEx_CmdBufferFull", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Received message queue is full..
/// </summary>
internal static string OverflowEx_MsgBufferFull {
get {
return ResourceManager.GetString("OverflowEx_MsgBufferFull", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The received strings buffer is full..
/// </summary>
internal static string OverflowEx_StringBufferFull {
get {
return ResourceManager.GetString("OverflowEx_StringBufferFull", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Wait condition for {0} message timed out..
/// </summary>
internal static string TimeoutEx_WaitMessage {
get {
return ResourceManager.GetString("TimeoutEx_WaitMessage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Wait condition for string read in {0} mode timed out..
/// </summary>
internal static string TimeoutEx_WaitStringRequest {
get {
return ResourceManager.GetString("TimeoutEx_WaitStringRequest", resourceCulture);
}
}
}
}
================================================
FILE: Solid.Arduino/Messages.resx
================================================
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ArgumentEx_CannotConvertBcd" xml:space="preserve">
<value>Cannot convert non-BCD data.</value>
</data>
<data name="ArgumentEx_ChannelRange0_15" xml:space="preserve">
<value>Channel number must be between 0 and 15.</value>
</data>
<data name="ArgumentEx_DigitStringOnly" xml:space="preserve">
<value>String must contain digits only.</value>
</data>
<data name="ArgumentEx_I2cAddressRange" xml:space="preserve">
<value>Address must be between 0 and 1,023.</value>
</data>
<data name="ArgumentEx_I2cInterval" xml:space="preserve">
<value>Interval must be between 0 and 16,383 milliseconds.</value>
</data>
<data name="ArgumentEx_MaxPulseWidth" xml:space="preserve">
<value>Maximum pulse width must be between 0 and 16,383 milliseconds.</value>
</data>
<data name="ArgumentEx_MinMaxPulse" xml:space="preserve">
<value>Minimum pulse width is greater than maximum pulse width.</value>
</data>
<data name="ArgumentEx_MinPulseWidth" xml:space="preserve">
<value>Minimum pulse width must be between 0 and 16,383 milliseconds.</value>
</data>
<data name="ArgumentEx_NoNegativeValue" xml:space="preserve">
<value>Value cannot be negative.</value>
</data>
<data name="ArgumentEx_NotNullOrEmpty" xml:space="preserve">
<value>String argument can not be null or empty.</value>
</data>
<data name="ArgumentEx_PinRange0_127" xml:space="preserve">
<value>Pin number must be between 0 and 127.</value>
</data>
<data name="ArgumentEx_PinRange0_7" xml:space="preserve">
<value>Pin must be between 0 and 7.</value>
</data>
<data name="ArgumentEx_PortRange0_15" xml:space="preserve">
<value>Port number must be between 0 and 15.</value>
</data>
<data name="ArgumentEx_PositiveValue" xml:space="preserve">
<value>Value must be greater than zero.</value>
</data>
<data name="ArgumentEx_SamplingInterval" xml:space="preserve">
<value>Sampling interval must be between 0 and 16,383 milliseconds.</value>
</data>
<data name="ArgumentEx_ValueRange0_16383" xml:space="preserve">
<value>Value must be between 0 and 16,383.</value>
</data>
<data name="ArgumentEx_ValueRange0_255" xml:space="preserve">
<value>Value must be betwen 0 and 255.</value>
</data>
<data name="InvalidOpEx_PinNotSupported" xml:space="preserve">
<value>Pin is not supported.</value>
</data>
<data name="InvalidSerialPort" xml:space="preserve">
<value>Invalid serial port</value>
</data>
<data name="NotImplementedEx_Command" xml:space="preserve">
<value>Commandbyte 0x{0:X} is not implemented.</value>
</data>
<data name="NotSupportedResponse" xml:space="preserve">
<value>Response message code 0x{0:X} is not supported.</value>
</data>
<data name="OverflowEx_CmdBufferFull" xml:space="preserve">
<value>The command parsing buffer is full.</value>
</data>
<data name="OverflowEx_MsgBufferFull" xml:space="preserve">
<value>Received message queue is full.</value>
</data>
<data name="OverflowEx_StringBufferFull" xml:space="preserve">
<value>The received strings buffer is full.</value>
</data>
<data name="TimeoutEx_WaitMessage" xml:space="preserve">
<value>Wait condition for {0} message timed out.</value>
</data>
<data name="TimeoutEx_WaitStringRequest" xml:space="preserve">
<value>Wait condition for string read in {0} mode timed out.</value>
</data>
</root>
================================================
FILE: Solid.Arduino/ObservableEventTracker.cs
================================================
using System;
using System.Collections.Generic;
namespace Solid.Arduino
{
internal abstract class ObservableEventTracker<TSource, TTracked> : IObservable<TTracked>, IDisposable
{
#region Protected Fields
protected readonly TSource TrackingSource;
protected readonly List<IObserver<TTracked>> Observers = new List<IObserver<TTracked>>();
protected bool IsDisposed = false;
#endregion
#region Constructors
internal ObservableEventTracker(TSource trackingSource)
{
TrackingSource = trackingSource;
}
#endregion
#region Public Methods
public IDisposable Subscribe(IObserver<TTracked> observer)
{
Observers.Add(observer);
return this;
}
public virtual void Dispose()
{
if (!IsDisposed)
{
foreach (IObserver<TTracked> observer in Observers)
observer.OnCompleted();
GC.SuppressFinalize(this);
IsDisposed = true;
}
}
#endregion
}
}
================================================
FILE: Solid.Arduino/ReceivedStringTracker.cs
================================================
namespace Solid.Arduino
{
internal class ReceivedStringTracker : ObservableEventTracker<IStringProtocol, string>
{
#region Constructors
internal ReceivedStringTracker(IStringProtocol source)
: base(source)
{
TrackingSource.StringReceived += TrackingSource_StringReceived;
}
#endregion
#region Public Methods
public override void Dispose()
{
if (!IsDisposed)
{
TrackingSource.StringReceived -= TrackingSource_StringReceived;
base.Dispose();
}
}
#endregion
#region Private Methods
void TrackingSource_StringReceived(object parSender, StringEventArgs parEventArgs)
{
Observers.ForEach(o => o.OnNext(parEventArgs.Text));
}
#endregion
}
}
================================================
FILE: Solid.Arduino/SerialBaudRate.cs
================================================
namespace Solid.Arduino
{
/// <summary>
/// Enumeration of common baud rates, supported by Arduino boards
/// </summary>
public enum SerialBaudRate
{
Bps_300 = 300,
Bps_600 = 600,
Bps_1200 = 1200,
Bps_2400 = 2400,
Bps_4800 = 4800,
Bps_9600 = 9600,
Bps_14400 = 14400,
Bps_19200 = 19200,
Bps_28800 = 28800,
Bps_31250 = 31250,
Bps_38400 = 38400,
Bps_57600 = 57600,
Bps_115200 = 115200
}
}
================================================
FILE: Solid.Arduino/SerialConnection.cs
================================================
using System;
using System.Diagnostics;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Threading;
using Solid.Arduino.Firmata;
namespace Solid.Arduino
{
/// <summary>
/// Represents a serial port connection.
/// </summary>
/// <inheritdoc cref="ISerialConnection" />
public class SerialConnection : SerialPort, ISerialConnection
{
private static readonly SerialBaudRate[] PopularBaudRates =
{
SerialBaudRate.Bps_9600,
SerialBaudRate.Bps_57600,
SerialBaudRate.Bps_115200
};
private static readonly SerialBaudRate[] OtherBaudRates =
{
SerialBaudRate.Bps_28800,
SerialBaudRate.Bps_14400,
SerialBaudRate.Bps_38400,
SerialBaudRate.Bps_31250,
SerialBaudRate.Bps_4800,
SerialBaudRate.Bps_2400
};
private bool _isDisposed;
/// <summary>
/// Initializes a new instance of <see cref="SerialConnection"/> class using the highest COM-port available at 115,200 bits per second.
/// </summary>
public SerialConnection()
: base(GetHighestComPortName(), (int) SerialBaudRate.Bps_115200)
{
ReadTimeout = 100;
WriteTimeout = 100;
}
/// <summary>
/// Initializes a new instance of <see cref="SerialConnection"/> class on the given serial port and at the given baud rate.
/// </summary>
/// <param name="portName">The port name (e.g. 'COM3')</param>
/// <param name="baudRate">The baud rate</param>
public SerialConnection(string portName, SerialBaudRate baudRate)
: base(portName, (int) baudRate)
{
ReadTimeout = 100;
WriteTimeout = 100;
}
/// <inheritdoc cref="SerialPort" />
public new void Open()
{
if (IsOpen)
return;
try
{
base.Open();
}
catch (UnauthorizedAccessException)
{
// Connection closure has probably not yet been finalized.
// Wait 250 ms and try again once.
Thread.Sleep(250);
base.Open();
}
}
/// <inheritdoc cref="SerialPort.Close"/>
public new void Close()
{
if (!IsOpen)
return;
Thread.Sleep(250);
BaseStream.Flush();
DiscardInBuffer();
BaseStream.Close();
base.Close();
}
/// <inheritdoc cref="SerialPort.Dispose"/>
public new void Dispose()
{
if (_isDisposed)
return;
_isDisposed = true;
BaseStream.Dispose();
GC.SuppressFinalize(BaseStream);
base.Dispose();
GC.SuppressFinalize(this);
}
/// <inheritdoc cref="ISerialConnection.Write(string)" />
/// <inheritdoc cref="ISerialConnection.Write(byte[],int,int)" />
/// <summary>
/// Finds a serial connection to a device supporting the Firmata protocol.
/// </summary>
/// <returns>A <see cref="ISerialConnection"/> instance or <c>null</c> if no connection is found</returns>
/// <remarks>
/// <para>
/// This method searches all available serial ports until it finds a working serial connection.
/// For every available serial port an attempt is made to open a connection at a range of common baudrates.
/// The connection is tested by issueing an <see cref="IFirmataProtocol.GetFirmware()"/> command.
/// (I.e. a Firmata SysEx Firmware query (0xF0 0x79 0xF7).)
/// </para>
/// <para>
/// The connected device is expected to respond by sending the version number of the supported protocol.
/// When a major version of 2 or higher is received, the connection is regarded to be valid.
/// </para>
/// </remarks>
/// <seealso cref="IFirmataProtocol"/>
/// <seealso href="http://www.firmata.org/wiki/Protocol#Query_Firmware_Name_and_Version">Query Firmware Name and Version</seealso>
public static ISerialConnection Find()
{
bool isAvailableFunc(ArduinoSession session)
{
Firmware firmware = session.GetFirmware();
return firmware.MajorVersion >= 2;
}
string[] portNames = GetPortNames();
ISerialConnection connection = FindConnection(isAvailableFunc, portNames, PopularBaudRates);
return connection ?? FindConnection(isAvailableFunc, portNames, OtherBaudRates);
}
/// <summary>
/// Finds a serial connection to a device supporting plain serial communications.
/// </summary>
/// <param name="query">The query text used to inquire the connection</param>
/// <param name="expectedReply">The reply text the connected device is expected to respond with</param>
/// <returns>A <see cref="ISerialConnection"/> instance or <c>null</c> if no connection is found</returns>
/// <remarks>
/// <para>
/// This method searches all available serial ports until it finds a working serial connection.
/// For every available serial port an attempt is made to open a connection at a range of common baudrates.
/// The connection is tested by sending the query string passed to this method.
/// </para>
/// <para>
/// The connected device is expected to respond by sending the reply string passed to this method.
/// When the string received is equal to the expected reply string, the connection is regarded to be valid.
/// </para>
/// </remarks>
/// <example>
/// The Arduino sketch below can be used to demonstrate this method.
/// Upload the sketch to your Arduino device.
/// <code lang="Arduino Sketch">
/// char query[] = "Hello?";
/// char reply[] = "Arduino!";
///
/// void setup()
/// {
/// Serial.begin(9600);
/// while (!Serial) {}
/// }
///
/// void loop()
/// {
/// if (Serial.find(query))
/// {
/// Serial.println(reply);
/// }
/// else
/// {
/// Serial.println("Listening...");
/// Serial.flush();
/// }
///
/// delay(25);
/// }
/// </code>
/// </example>
/// <seealso cref="IStringProtocol"/>
public static ISerialConnection Find(string query, string expectedReply)
{
if (string.IsNullOrEmpty(query))
throw new ArgumentException(Messages.ArgumentEx_NotNullOrEmpty, nameof(query));
if (string.IsNullOrEmpty(expectedReply))
throw new ArgumentException(Messages.ArgumentEx_NotNullOrEmpty, nameof(expectedReply));
bool isAvailableFunc(ArduinoSession session)
{
session.Write(query);
return session.Read(expectedReply.Length) == expectedReply;
}
string[] portNames = GetPortNames();
ISerialConnection connection = FindConnection(isAvailableFunc, portNames, PopularBaudRates);
return connection ?? FindConnection(isAvailableFunc, portNames, OtherBaudRates);
}
private static string GetHighestComPortName()
{
return GetPortNames().Where(n => n.StartsWith("COM")).OrderByDescending(n => n).FirstOrDefault();
}
private static ISerialConnection FindConnection(Func<ArduinoSession, bool> isDeviceAvailable, string[] portNames, SerialBaudRate[] baudRates)
{
bool found = false;
for (int x = portNames.Length - 1; x >= 0; x--)
{
foreach (SerialBaudRate rate in baudRates)
{
try
{
using (var connection = new EnhancedSerialConnection(portNames[x], rate))
{
using (var session = new ArduinoSession(connection, 100))
{
#if TRACE
Debug.WriteLine("{0}:{1}; ", portNames[x], (int)rate);
#endif
if (isDeviceAvailable(session))
found = true;
}
}
if (found)
return new EnhancedSerialConnection(portNames[x], rate);
}
catch (UnauthorizedAccessException)
{
// Port is not available.
#if TRACE
Debug.WriteLine("{0} NOT AVAILABLE; ", portNames[x]);
#endif
break;
}
catch (TimeoutException)
{
// Baudrate or protocol error.
}
catch (IOException ex)
{
#if TRACE
Debug.WriteLine($"HResult 0x{ex.HResult:X} - {ex.Message}");
#endif
}
}
}
return null;
}
}
}
================================================
FILE: Solid.Arduino/SerialPortFixer.cs
================================================
// Copyright 2010-2014 Zach Saw
// Refactored 2017 Henk van Boeijen
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.Win32.SafeHandles;
namespace Solid.Arduino
{
/// <summary>
/// SerialPort IOException Workaround
/// </summary>
/// <seealso href="http://zachsaw.blogspot.nl/2010/07/serialport-ioexception-workaround-in-c.html"/>
internal static class SerialPortFixer
{
[StructLayout(LayoutKind.Sequential)]
private struct Comstat
{
public readonly uint Flags;
public readonly uint cbInQue;
public readonly uint cbOutQue;
}
[StructLayout(LayoutKind.Sequential)]
private struct Dcb
{
public readonly uint DCBlength;
public readonly uint BaudRate;
public uint Flags;
public readonly ushort wReserved;
public readonly ushort XonLim;
public readonly ushort XoffLim;
public readonly byte ByteSize;
public readonly byte Parity;
public readonly byte StopBits;
public readonly byte XonChar;
public readonly byte XoffChar;
public readonly byte ErrorChar;
public readonly byte EofChar;
public readonly byte EvtChar;
public readonly ushort wReserved1;
}
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern int FormatMessage(int dwFlags, HandleRef lpSource, int dwMessageId, int dwLanguageId, StringBuilder lpBuffer, int nSize, IntPtr arguments);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern bool GetCommState(SafeFileHandle hFile, ref Dcb lpDcb);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern bool SetCommState(SafeFileHandle hFile, ref Dcb lpDcb);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern bool ClearCommError(SafeFileHandle hFile, ref int lpErrors, ref Comstat lpStat);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern SafeFileHandle CreateFile(string lpFileName, int dwDesiredAccess, int dwShareMode, IntPtr securityAttrs, int dwCreationDisposition, int dwFlagsAndAttributes, IntPtr hTemplateFile);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern int GetFileType(SafeFileHandle hFile);
private const int DcbFlagAbortOnError = 14;
private const int CommStateRetries = 10;
public static void Initialize(string portName)
{
const int dwFlagsAndAttributes = 0x40000000;
const int dwAccess = unchecked((int)0xC0000000);
if ((portName == null) || !portName.StartsWith("COM", StringComparison.OrdinalIgnoreCase))
throw new ArgumentException(Messages.InvalidSerialPort, nameof(portName));
SafeFileHandle fileHandle = CreateFile(@"\\.\" + portName, dwAccess, 0, IntPtr.Zero, 3, dwFlagsAndAttributes, IntPtr.Zero);
if (fileHandle.IsInvalid)
ThrowIoException();
try
{
int fileType = GetFileType(fileHandle);
if ((fileType != 2) && (fileType != 0))
throw new ArgumentException(Messages.InvalidSerialPort, nameof(portName));
var dcb = new Dcb();
MarshalCommState(fileHandle, () => GetCommState(fileHandle, ref dcb));
dcb.Flags &= ~(1u << DcbFlagAbortOnError);
MarshalCommState(fileHandle, () => SetCommState(fileHandle, ref dcb));
}
finally
{
fileHandle.Close();
}
}
private static void MarshalCommState(SafeFileHandle handle, Func<bool> performCommState)
{
int commErrors = 0;
var comStat = new Comstat();
for (int i = 0; i < CommStateRetries; i++)
{
if (!ClearCommError(handle, ref commErrors, ref comStat))
ThrowIoException();
if (performCommState())
return;
if (i == CommStateRetries - 1)
ThrowIoException();
}
}
private static void ThrowIoException()
{
int errorCode = Marshal.GetLastWin32Error();
var lpBuffer = new StringBuilder(0x200);
string errorMessage = (FormatMessage(0x3200, new HandleRef(null, IntPtr.Zero), errorCode, 0, lpBuffer, lpBuffer.Capacity, IntPtr.Zero) != 0)
? lpBuffer.ToString()
: $"0x{errorCode:X} - Unknown error";
throw new IOException(errorMessage, (int)(0x80070000 | (uint)errorCode));
}
}
}
================================================
FILE: Solid.Arduino/Solid.Arduino.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<PackageId>SolidSoils.Arduino.Client</PackageId>
<Authors>Henk van Boeijen</Authors>
<Company>Solid Soils Solutions</Company>
<Description>Client library built on .NET Standard 2.1, providing an easy way to interact with Arduino boards.
The library implements the serial ASCII, Firmata and I2C protocols, which can be used simultaneously.</Description>
<Copyright>Copyright 2013-2021 Solid Soils Solutions</Copyright>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<PackageProjectUrl>https://github.com/SolidSoils/Arduino</PackageProjectUrl>
<PackageTags>Arduino Firmata I2C serial</PackageTags>
<PackageReleaseNotes>Upgrade to .NET Standard 2.1
Documentation fix & cleanup
Upgrade to .NET Standard 2.0
Fixed compatibility with Firmata 2.6</PackageReleaseNotes>
<RepositoryUrl>https://github.com/SolidSoils/Arduino</RepositoryUrl>
<PackageIconUrl>https://secure.gravatar.com/avatar/112117ab5b25236518383750d7c82b27</PackageIconUrl>
<Product>SolidSoils4Arduino</Product>
<ProductName>Solid Soils for Arduino</ProductName>
<ProductVersion>1.1.1</ProductVersion>
<PackageLicenseExpression>BSD-2-Clause</PackageLicenseExpression>
<AssemblyVersion>1.1.1.0</AssemblyVersion>
<FileVersion>1.1.1.0</FileVersion>
<Version>1.1.1</Version>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DocumentationFile>C:\Data\Git\Arduino\Solid.Arduino\Solid.Arduino.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DocumentationFile>D:\Data\repos\Arduino\Solid.Arduino\Solid.Arduino.xml</DocumentationFile>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.IO.Ports" Version="5.0.1" />
</ItemGroup>
<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
<_Parameter1>Solid.Arduino.Test</_Parameter1>
</AssemblyAttribute>
</ItemGroup>
<ItemGroup>
<Compile Update="Messages.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Messages.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Messages.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Messages.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
</Project>
================================================
FILE: Solid.Arduino/Solid.Arduino.xml
================================================
<?xml version="1.0"?>
<doc>
<assembly>
<name>Solid.Arduino</name>
</assembly>
<members>
<member name="T:Solid.Arduino.ArduinoSession">
<summary>
Represents an active layer for serial communication with an Arduino board.
</summary>
<remarks>
This class supports a few common protocols used for communicating with Arduino boards.
The protocols can be used simultaneous and independently of each other.
</remarks>
<seealso href="http://arduino.cc">Official Arduino website</seealso>
<seealso href="https://github.com/SolidSoils/Arduino">SolidSoils4Arduino project on GitHub</seealso>
<example>
<code language="C#">
var connection = new SerialConnection("COM3", SerialBaudRate.Bps_57600);
var session = new ArduinoSession(connection, timeOut: 250);
// Cast to interface done, just for the sake of this demo.
IFirmataProtocol firmata = (IFirmataProtocol)session;
Firmware firm = firmata.GetFirmware();
Console.WriteLine("Firmware: {0} {1}.{2}", firm.Name, firm.MajorVersion, firm.MinorVersion);
ProtocolVersion version = firmata.GetProtocolVersion();
Console.WriteLine("Protocol version: {0}.{1}", version.Major, version.Minor);
BoardCapability caps = firmata.GetBoardCapability();
Console.WriteLine("Board Capabilities:");
foreach (var pincap in caps.PinCapabilities)
{
Console.WriteLine("Pin {0}: Input: {1}, Output: {2}, Analog: {3}, Analog-Res: {4}, PWM: {5}, PWM-Res: {6}, Servo: {7}, Servo-Res: {8}",
pincap.PinNumber,
pincap.DigitalInput,
pincap.DigitalOutput,
pincap.Analog,
pincap.AnalogResolution,
pincap.Pwm,
pincap.PwmResolution,
pincap.Servo,
pincap.ServoResolution);
}
Console.WriteLine();
Console.ReadLine();
</code>
</example>
</member>
<member name="M:Solid.Arduino.ArduinoSession.#ctor(Solid.Arduino.ISerialConnection)">
<summary>
Initializes a new instance of the <see cref="T:Solid.Arduino.ArduinoSession"/> class.
</summary>
<param name="connection">The serial port connection</param>
<exception cref="T:System.ArgumentNullException">connection</exception>
</member>
<member name="M:Solid.Arduino.ArduinoSession.#ctor(Solid.Arduino.ISerialConnection,System.Int32)">
<summary>
Initializes a new instance of the <see cref="T:Solid.Arduino.ArduinoSession"/> class.
</summary>
<param name="connection">The serial port connection</param>
<param name="timeOut">The response time out in milliseconds</param>
<exception cref="T:System.ArgumentNullException">connection</exception>
<exception cref="T:System.ArgumentOutOfRangeException">timeOut</exception>
</member>
<member name="P:Solid.Arduino.ArduinoSession.TimeOut">
<summary>
Gets or sets the number of milliseconds before a time-out occurs when a read operation does not finish.
</summary>
<remarks>
The default is a <see cref="F:System.IO.Ports.SerialPort.InfiniteTimeout"/> value (-1).
</remarks>
</member>
<member name="M:Solid.Arduino.ArduinoSession.Clear">
<summary>
Closes and reopens the underlying connection and clears all buffers and queues.
</summary>
</member>
<member name="E:Solid.Arduino.ArduinoSession.StringReceived">
<inheritdoc cref="E:Solid.Arduino.IStringProtocol.StringReceived"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.CreateReceivedStringMonitor">
<inheritdoc cref="M:Solid.Arduino.IStringProtocol.CreateReceivedStringMonitor"/>
</member>
<member name="P:Solid.Arduino.ArduinoSession.NewLine">
<inheritdoc cref="P:Solid.Arduino.IStringProtocol.NewLine"/>
<remarks>
The value of this property is mapped to the <see cref="P:Solid.Arduino.ISerialConnection.NewLine"/> property of the
connection the <see cref="T:Solid.Arduino.ArduinoSession"/> instance is relying on.
</remarks>
</member>
<member name="M:Solid.Arduino.ArduinoSession.Write(System.String)">
<inheritdoc cref="M:Solid.Arduino.IStringProtocol.Write(System.String)"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.WriteLine(System.String)">
<inheritdoc cref="M:Solid.Arduino.IStringProtocol.WriteLine(System.String)"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.ReadLine">
<inheritdoc cref="M:Solid.Arduino.IStringProtocol.ReadLine"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.ReadLineAsync">
<inheritdoc cref="M:Solid.Arduino.IStringProtocol.ReadLineAsync"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.Read(System.Int32)">
<inheritdoc cref="M:Solid.Arduino.IStringProtocol.Read(System.Int32)"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.ReadAsync(System.Int32)">
<inheritdoc cref="M:Solid.Arduino.IStringProtocol.ReadAsync(System.Int32)"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.ReadTo(System.Char)">
<inheritdoc cref="M:Solid.Arduino.IStringProtocol.ReadTo(System.Char)"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.ReadToAsync(System.Char)">
<inheritdoc cref="M:Solid.Arduino.IStringProtocol.ReadToAsync(System.Char)"/>
</member>
<member name="E:Solid.Arduino.ArduinoSession.MessageReceived">
<inheritdoc cref="E:Solid.Arduino.Firmata.IFirmataProtocol.MessageReceived"/>
</member>
<member name="E:Solid.Arduino.ArduinoSession.AnalogStateReceived">
<inheritdoc cref="E:Solid.Arduino.Firmata.IFirmataProtocol.AnalogStateReceived"/>
</member>
<member name="E:Solid.Arduino.ArduinoSession.DigitalStateReceived">
<inheritdoc cref="E:Solid.Arduino.Firmata.IFirmataProtocol.DigitalStateReceived"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.CreateDigitalStateMonitor">
<inheritdoc cref="M:Solid.Arduino.Firmata.IFirmataProtocol.CreateDigitalStateMonitor"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.CreateDigitalStateMonitor(System.Int32)">
<inheritdoc cref="M:Solid.Arduino.Firmata.IFirmataProtocol.CreateDigitalStateMonitor(System.Int32)"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.CreateAnalogStateMonitor">
<inheritdoc cref="M:Solid.Arduino.Firmata.IFirmataProtocol.CreateAnalogStateMonitor"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.CreateAnalogStateMonitor(System.Int32)">
<inheritdoc cref="M:Solid.Arduino.Firmata.IFirmataProtocol.CreateAnalogStateMonitor(System.Int32)"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.ResetBoard">
<inheritdoc cref="M:Solid.Arduino.Firmata.IFirmataProtocol.ResetBoard"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.SetDigitalPin(System.Int32,System.Int64)">
<inheritdoc cref="M:Solid.Arduino.Firmata.IFirmataProtocol.SetDigitalPin(System.Int32,System.Int64)"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.SetDigitalPin(System.Int32,System.Boolean)">
<inheritdoc cref="M:Solid.Arduino.Firmata.IFirmataProtocol.SetDigitalPin(System.Int32,System.Boolean)"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.SetAnalogReportMode(System.Int32,System.Boolean)">
<inheritdoc cref="M:Solid.Arduino.Firmata.IFirmataProtocol.SetAnalogReportMode(System.Int32,System.Boolean)"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.SetDigitalPort(System.Int32,System.Int32)">
<inheritdoc cref="M:Solid.Arduino.Firmata.IFirmataProtocol.SetDigitalPort(System.Int32,System.Int32)"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.SetDigitalReportMode(System.Int32,System.Boolean)">
<inheritdoc cref="M:Solid.Arduino.Firmata.IFirmataProtocol.SetDigitalReportMode(System.Int32,System.Boolean)"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.SetDigitalPinMode(System.Int32,Solid.Arduino.Firmata.PinMode)">
<inheritdoc cref="M:Solid.Arduino.Firmata.IFirmataProtocol.SetDigitalPinMode(System.Int32,Solid.Arduino.Firmata.PinMode)"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.SetSamplingInterval(System.Int32)">
<inheritdoc cref="M:Solid.Arduino.Firmata.IFirmataProtocol.SetSamplingInterval(System.Int32)"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.SendStringData(System.String)">
<inheritdoc cref="M:Solid.Arduino.Firmata.IFirmataProtocol.SendStringData(System.String)"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.RequestFirmware">
<inheritdoc cref="M:Solid.Arduino.Firmata.IFirmataProtocol.RequestFirmware"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.GetFirmware">
<inheritdoc cref="M:Solid.Arduino.Firmata.IFirmataProtocol.GetFirmware"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.GetFirmwareAsync">
<inheritdoc cref="M:Solid.Arduino.Firmata.IFirmataProtocol.GetFirmwareAsync"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.RequestProtocolVersion">
<inheritdoc cref="M:Solid.Arduino.Firmata.IFirmataProtocol.RequestProtocolVersion"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.GetProtocolVersion">
<inheritdoc cref="M:Solid.Arduino.Firmata.IFirmataProtocol.GetProtocolVersion"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.GetProtocolVersionAsync">
<inheritdoc cref="M:Solid.Arduino.Firmata.IFirmataProtocol.GetProtocolVersionAsync"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.RequestBoardCapability">
<inheritdoc cref="M:Solid.Arduino.Firmata.IFirmataProtocol.RequestBoardCapability"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.GetBoardCapability">
<inheritdoc cref="M:Solid.Arduino.Firmata.IFirmataProtocol.GetBoardCapability"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.GetBoardCapabilityAsync">
<inheritdoc cref="M:Solid.Arduino.Firmata.IFirmataProtocol.GetBoardCapabilityAsync"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.RequestBoardAnalogMapping">
<inheritdoc cref="M:Solid.Arduino.Firmata.IFirmataProtocol.RequestBoardAnalogMapping"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.GetBoardAnalogMapping">
<inheritdoc cref="M:Solid.Arduino.Firmata.IFirmataProtocol.GetBoardAnalogMapping"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.GetBoardAnalogMappingAsync">
<inheritdoc cref="M:Solid.Arduino.Firmata.IFirmataProtocol.GetBoardAnalogMappingAsync"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.RequestPinState(System.Int32)">
<inheritdoc cref="M:Solid.Arduino.Firmata.IFirmataProtocol.RequestPinState(System.Int32)"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.GetPinState(System.Int32)">
<inheritdoc cref="M:Solid.Arduino.Firmata.IFirmataProtocol.GetPinState(System.Int32)"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.GetPinStateAsync(System.Int32)">
<inheritdoc cref="M:Solid.Arduino.Firmata.IFirmataProtocol.GetPinStateAsync(System.Int32)"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.ConfigureServo(System.Int32,System.Int32,System.Int32)">
<inheritdoc cref="M:Solid.Arduino.Firmata.Servo.IServoProtocol.ConfigureServo(System.Int32,System.Int32,System.Int32)"/>
</member>
<member name="E:Solid.Arduino.ArduinoSession.I2CReplyReceived">
<inheritdoc cref="E:Solid.Arduino.I2C.II2CProtocol.I2CReplyReceived"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.CreateI2CReplyMonitor">
<inheritdoc cref="M:Solid.Arduino.I2C.II2CProtocol.CreateI2CReplyMonitor"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.SetI2CReadInterval(System.Int32)">
<inheritdoc cref="M:Solid.Arduino.I2C.II2CProtocol.SetI2CReadInterval(System.Int32)"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.WriteI2C(System.Int32,System.Byte[])">
<inheritdoc cref="M:Solid.Arduino.I2C.II2CProtocol.WriteI2C(System.Int32,System.Byte[])"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.ReadI2COnce(System.Int32,System.Int32)">
<inheritdoc cref="M:Solid.Arduino.I2C.II2CProtocol.ReadI2COnce(System.Int32,System.Int32)"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.GetI2CReply(System.Int32,System.Int32)">
<inheritdoc cref="M:Solid.Arduino.I2C.II2CProtocol.GetI2CReply(System.Int32,System.Int32)"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.GetI2CReplyAsync(System.Int32,System.Int32)">
<inheritdoc cref="M:Solid.Arduino.I2C.II2CProtocol.GetI2CReplyAsync(System.Int32,System.Int32)"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.ReadI2COnce(System.Int32,System.Int32,System.Int32)">
<inheritdoc cref="M:Solid.Arduino.I2C.II2CProtocol.ReadI2COnce(System.Int32,System.Int32,System.Int32)"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.GetI2CReply(System.Int32,System.Int32,System.Int32)">
<inheritdoc cref="M:Solid.Arduino.I2C.II2CProtocol.GetI2CReply(System.Int32,System.Int32,System.Int32)"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.GetI2CReplyAsync(System.Int32,System.Int32,System.Int32)">
<inheritdoc cref="M:Solid.Arduino.I2C.II2CProtocol.GetI2CReplyAsync(System.Int32,System.Int32,System.Int32)"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.ReadI2CContinuous(System.Int32,System.Int32)">
<inheritdoc cref="M:Solid.Arduino.I2C.II2CProtocol.ReadI2CContinuous(System.Int32,System.Int32)"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.ReadI2CContinuous(System.Int32,System.Int32,System.Int32)">
<inheritdoc cref="M:Solid.Arduino.I2C.II2CProtocol.ReadI2CContinuous(System.Int32,System.Int32,System.Int32)"/>
</member>
<member name="M:Solid.Arduino.ArduinoSession.StopI2CReading">
<inheritdoc cref="M:Solid.Arduino.I2C.II2CProtocol.StopI2CReading"/>
<remarks>
<para>
Please note:
The Firmata specification states that the I2C_READ_STOP message
should only stop the specified query. However, the current Firmata.h implementation
stops all registered queries.
</para>
</remarks>
</member>
<member name="M:Solid.Arduino.ArduinoSession.Dispose">
<summary>
Closes the underlying connection.
</summary>
</member>
<member name="M:Solid.Arduino.ArduinoSession.SerialDataReceived(System.Object,System.IO.Ports.SerialDataReceivedEventArgs)">
<summary>
Event handler processing data bytes received on the serial port.
</summary>
</member>
<member name="T:Solid.Arduino.EnhancedSerialConnection">
<summary>
Represents a serial port connection, supporting Mono.
</summary>
<seealso href="http://www.mono-project.com/">The official Mono project site</seealso>
<inheritdoc />
</member>
<member name="M:Solid.Arduino.EnhancedSerialConnection.#ctor">
<summary>
Initializes a new instance of <see cref="T:Solid.Arduino.EnhancedSerialConnection"/> class using the highest serial port available at 115,200 bits per second.
</summary>
</member>
<member name="M:Solid.Arduino.EnhancedSerialConnection.#ctor(System.String,Solid.Arduino.SerialBaudRate)">
<summary>
Initializes a new instance of <see cref="T:Solid.Arduino.EnhancedSerialConnection"/> class on the given serial port and at the given baud rate.
</summary>
<param name="portName">The port name (e.g. 'COM3')</param>
<param name="baudRate">The baud rate</param>
</member>
<member name="M:Solid.Arduino.EnhancedSerialConnection.Find">
<inheritdoc cref="M:Solid.Arduino.SerialConnection.Find"/>
</member>
<member name="M:Solid.Arduino.EnhancedSerialConnection.Find(System.String,System.String)">
<inheritdoc cref="M:Solid.Arduino.SerialConnection.Find(System.String,System.String)"/>
</member>
<member name="M:Solid.Arduino.EnhancedSerialConnection.Close">
<inheritdoc cref="M:System.IO.Ports.SerialPort.Close"/>
</member>
<member name="T:Solid.Arduino.EnhancedSerialPort">
<summary>
Represents a system serial port, supporting .NET and Mono.
</summary>
<remarks>
This class is a workaround for Mono's <see cref="T:System.IO.Ports.SerialPort"/> implementation of event <see cref="M:Solid.Arduino.EnhancedSerialPort.OnDataReceived(System.IO.Ports.SerialDataReceivedEventArgs)"/>.
<para>
Copyright 2013 Antanas Veiverys <seealso href="https://antanas.veiverys.com">antanas.veiverys.com</seealso>
</para>
</remarks>
<inheritdoc cref="T:System.IO.Ports.SerialPort" />
</member>
<member name="M:Solid.Arduino.EnhancedSerialPort.#ctor">
<inheritdoc cref="M:System.IO.Ports.SerialPort.#ctor"/>
</member>
<member name="M:Solid.Arduino.EnhancedSerialPort.#ctor(System.ComponentModel.IContainer)">
<inheritdoc cref="M:System.IO.Ports.SerialPort.#ctor(System.ComponentModel.IContainer)"/>
</member>
<member name="M:Solid.Arduino.EnhancedSerialPort.#ctor(System.String)">
<inheritdoc cref="M:System.IO.Ports.SerialPort.#ctor(System.String)"/>
</member>
<member name="M:Solid.Arduino.EnhancedSerialPort.#ctor(System.String,System.Int32)">
<inheritdoc cref="M:System.IO.Ports.SerialPort.#ctor(System.String,System.Int32)"/>
</member>
<member name="M:Solid.Arduino.EnhancedSerialPort.#ctor(System.String,System.Int32,System.IO.Ports.Parity)">
<inheritdoc cref="M:System.IO.Ports.SerialPort.#ctor(System.String,System.Int32,System.IO.Ports.Parity)"/>
</member>
<member name="M:Solid.Arduino.EnhancedSerialPort.#ctor(System.String,System.Int32,System.IO.Ports.Parity,System.Int32)">
<inheritdoc cref="M:System.IO.Ports.SerialPort.#ctor(System.String,System.Int32,System.IO.Ports.Parity,System.Int32)"/>
</member>
<member name="M:Solid.Arduino.EnhancedSerialPort.#ctor(System.String,System.Int32,System.IO.Ports.Parity,System.Int32,System.IO.Ports.StopBits)">
<inheritdoc cref="M:System.IO.Ports.SerialPort.#ctor(System.String,System.Int32,System.IO.Ports.Parity,System.Int32,System.IO.Ports.StopBits)"/>
</member>
<member name="M:Solid.Arduino.EnhancedSerialPort.Open">
<inheritdoc cref="M:System.IO.Ports.SerialPort.Open"/>
</member>
<member name="T:Solid.Arduino.Firmata.AnalogPinMapping">
<summary>
Represents a mapping between a MIDI channel and a physical pin number.
</summary>
</member>
<member name="P:Solid.Arduino.Firmata.AnalogPinMapping.Channel">
<summary>
Gets the MIDI channel number (0 - 15).
</summary>
</member>
<member name="P:Solid.Arduino.Firmata.AnalogPinMapping.PinNumber">
<summary>
Gets the board's pin number (0 - 127).
</summary>
</member>
<member name="T:Solid.Arduino.Firmata.AnalogState">
<summary>
Represents the analog level read from or set to an analog pin.
</summary>
</member>
<member name="P:Solid.Arduino.Firmata.AnalogState.Channel">
<summary>
Gets the MIDI channel number (0 - 15).
</summary>
<remarks>
The mapping of analog pins to channel numbers can be retrieved using the <see cref="M:Solid.Arduino.Firmata.IFirmataProtocol.GetBoardAnalogMapping"/> method.
</remarks>
</member>
<member name="P:Solid.Arduino.Firmata.AnalogState.Level">
<summary>
Gets the analog level.
</summary>
</member>
<member name="T:Solid.Arduino.Firmata.BoardAnalogMapping">
<summary>
Represents a summary of mappings between MIDI channels and physical pin numbers.
</summary>
</member>
<member name="P:Solid.Arduino.Firmata.BoardAnalogMapping.PinMappings">
<summary>
Gets the channel mapping array of the board's analog pins.
</summary>
</member>
<member name="T:Solid.Arduino.Firmata.BoardCapability">
<summary>
Represents a summary of pinmode capabilities supported by an Arduino board.
</summary>
</member>
<member name="P:Solid.Arduino.Firmata.BoardCapability.Pins">
<summary>
Gets the capability array of the board's pins.
</summary>
</member>
<member name="T:Solid.Arduino.Firmata.ByteArrayExtensions">
<summary>
Provides extension methods for <see cref="T:System.Byte"/> arrays.
</summary>
</member>
<member name="M:Solid.Arduino.Firmata.ByteArrayExtensions.ConvertBinaryCodedDecimalToString(System.Byte[],System.Boolean)">
<summary>
Converts a <see cref="T:System.Byte"/> array holding binary coded digits to a readable string.
</summary>
<param name="data">The binary coded digit bytes</param>
<param name="isLittleEndian">Value indicating if the first nibble contains the least significant part</param>
<returns>A string containing numeric data</returns>
<exception cref="T:System.ArgumentException">The array contains one or more non-BCD bytes.</exception>
</member>
<member name="T:Solid.Arduino.Firmata.DigitalPor
gitextract_0siuikil/
├── .gitattributes
├── .gitignore
├── Documentation/
│ └── Documentation.shfbproj
├── LICENSE.md
├── README.md
├── Solid.Arduino/
│ ├── ArduinoSession.cs
│ ├── EnhancedSerialConnection.cs
│ ├── EnhancedSerialPort.cs
│ ├── Firmata/
│ │ ├── AnalogPinMapping.cs
│ │ ├── AnalogState.cs
│ │ ├── AnalogStateTracker.cs
│ │ ├── BoardAnalogMapping.cs
│ │ ├── BoardCapability.cs
│ │ ├── ByteArrayExtensions.cs
│ │ ├── DigitalPortState.cs
│ │ ├── DigitalStateTracker.cs
│ │ ├── FirmataMessage.cs
│ │ ├── FirmataMessageEventArgs.cs
│ │ ├── FirmataMessageEventArgs_.cs
│ │ ├── Firmware.cs
│ │ ├── IFirmataProtocol.cs
│ │ ├── PinCapability.cs
│ │ ├── PinState.cs
│ │ ├── ProtocolVersion.cs
│ │ ├── Servo/
│ │ │ └── IServoProtocol.cs
│ │ ├── StringData.cs
│ │ └── SysExCommand.cs
│ ├── I2c/
│ │ ├── I2cEventArgs.cs
│ │ ├── I2cReply.cs
│ │ ├── I2cReplyTracker.cs
│ │ └── II2cProtocol.cs
│ ├── ISerialConnection.cs
│ ├── IStringProtocol.cs
│ ├── Messages.Designer.cs
│ ├── Messages.resx
│ ├── ObservableEventTracker.cs
│ ├── ReceivedStringTracker.cs
│ ├── SerialBaudRate.cs
│ ├── SerialConnection.cs
│ ├── SerialPortFixer.cs
│ ├── Solid.Arduino.csproj
│ ├── Solid.Arduino.xml
│ ├── StringEventArgs.cs
│ └── StringExtensions.cs
├── Solid.Arduino.IntegrationTest/
│ ├── HC06-Bluetooth.ino
│ ├── SerialConnectionTester.cs
│ ├── SerialReply.ino
│ ├── SocketConnectionTester.cs
│ └── Solid.Arduino.IntegrationTest.csproj
├── Solid.Arduino.Run/
│ ├── Program.cs
│ └── Solid.Arduino.Run.csproj
├── Solid.Arduino.Test/
│ ├── ArduinoSessionTester.cs
│ ├── ByteArrayExtensionsTester.cs
│ ├── DigitalPortStateTester.cs
│ ├── EnhancedSerialConnectionTester.cs
│ ├── ExceptionMonitor.cs
│ ├── I2cProtocolTester.cs
│ ├── IFirmataProtocolTester.cs
│ ├── IServoProtocolTester.cs
│ ├── IStringProtocolTester.cs
│ ├── MockSerialConnection.cs
│ ├── ObservableArduinoSessionTester.cs
│ ├── SerialConnectionTester.cs
│ ├── Solid.Arduino.Test.csproj
│ └── StringExtensionsTester.cs
├── Solid.Arduino.sln
├── _config.yml
└── docs/
├── SearchHelp.aspx
├── SearchHelp.inc.php
├── SearchHelp.php
├── Solid.Arduino.xml
├── SolidSoils4Arduino.chm
├── Web.Config
├── WebKI.xml
├── WebTOC.xml
├── fti/
│ ├── FTI_100.json
│ ├── FTI_101.json
│ ├── FTI_102.json
│ ├── FTI_103.json
│ ├── FTI_104.json
│ ├── FTI_105.json
│ ├── FTI_108.json
│ ├── FTI_109.json
│ ├── FTI_110.json
│ ├── FTI_111.json
│ ├── FTI_112.json
│ ├── FTI_113.json
│ ├── FTI_114.json
│ ├── FTI_115.json
│ ├── FTI_116.json
│ ├── FTI_117.json
│ ├── FTI_118.json
│ ├── FTI_119.json
│ ├── FTI_97.json
│ ├── FTI_98.json
│ ├── FTI_99.json
│ └── FTI_Files.json
├── html/
│ ├── 0010e8c6-eb36-7d91-486f-57a208faeca8.htm
│ ├── 002fd01e-b970-b699-d1ab-402342ab2dec.htm
│ ├── 00b485cd-b70e-e463-f9aa-ba11cee21ff7.htm
│ ├── 00e5bd9e-f9ab-5194-8375-b9fbf1f0161e.htm
│ ├── 012dd994-5a18-29df-21ef-6f6e228030c9.htm
│ ├── 01aaeb2a-fd21-bbd7-2dc2-9e6597c264d4.htm
│ ├── 03dc5f50-ca95-43b1-418c-d8465fb55383.htm
│ ├── 04428aca-6102-c5fd-3222-18c2e545b0e8.htm
│ ├── 0456bfc8-b008-c8a3-77ad-0bfefc1310cb.htm
│ ├── 05b14b65-ca9d-7ff2-68b7-f70d7cfcc100.htm
│ ├── 05b5327f-d814-405f-e2bd-e56a351a861e.htm
│ ├── 07dc3d59-f60a-0e42-9042-3bb4ac8f9137.htm
│ ├── 08af42a6-bb1e-b13e-b90d-ac47e8583dd9.htm
│ ├── 0cace141-f273-7ad7-d632-31e0ff0815fb.htm
│ ├── 0cc5ebbb-9d0b-0d4e-0b8a-59b7c490f7bd.htm
│ ├── 0cd4e1e3-e5af-40f1-dc97-f2f08fb64119.htm
│ ├── 0ce955e9-de04-3300-073d-2932518e0070.htm
│ ├── 0db70497-3543-ccc9-2141-40d1fd170c64.htm
│ ├── 0e0528df-22b4-60f2-8cc6-9c7e3d140d01.htm
│ ├── 0ea9cbae-1535-ba11-3134-4520d69334f0.htm
│ ├── 0eb18a1c-9837-d7d9-6e0d-f201303effe6.htm
│ ├── 0f03b0e7-a914-e46b-c2d6-e0bed40eac37.htm
│ ├── 10dde3c8-66dc-d300-0d82-de410352094d.htm
│ ├── 11348d42-72bd-635f-c392-da90b6c27daa.htm
│ ├── 119049c4-1ba0-964e-94c7-cfc08e55a37a.htm
│ ├── 12415ea1-5b04-0b26-d464-d851efbbce73.htm
│ ├── 1251dc84-c748-62a3-d876-c92c0cab97c6.htm
│ ├── 1685f037-3a5d-6004-7e2c-c72f2c403fed.htm
│ ├── 17a49847-9f5e-41b4-a84a-1bb15979af70.htm
│ ├── 17eed47b-8bf5-ea44-13cd-722e37bb68c9.htm
│ ├── 183523fa-f6c5-0635-d6ba-336781e21c95.htm
│ ├── 1a181c03-5d41-d3a2-e280-049cad8d349a.htm
│ ├── 1c02d293-4876-a918-1b8e-c84637cd0860.htm
│ ├── 1c2dd961-3134-4b2a-ab4d-c8025ab4cfe1.htm
│ ├── 1cd0d237-552e-0958-a3ef-7dec5153ffa3.htm
│ ├── 1e2164e0-907c-a688-2f86-07d7ba8e85ae.htm
│ ├── 1f020e05-4452-f270-4785-162fd272270d.htm
│ ├── 1fa615e5-a5c8-2d2c-fa47-0e38434c27c8.htm
│ ├── 209690c4-2404-13af-d697-d0889345d94e.htm
│ ├── 21bb8dd6-fb5d-9c2d-ffca-f536c5533d6a.htm
│ ├── 2387accb-7f3f-aff7-0482-b5a6bc2fdaee.htm
│ ├── 2396779a-20f5-49b8-2a1b-ad7d188cde76.htm
│ ├── 23a2c9b4-3a0c-9075-c87f-a4fc4d89c978.htm
│ ├── 24763d00-2f5b-09be-8ace-29f24895ed1b.htm
│ ├── 25858b6c-f545-022f-1421-1980e7d2f9ec.htm
│ ├── 26b1753d-4f47-ecdb-98fb-1c150eb3ca88.htm
│ ├── 280d4128-f443-8cf2-6a53-33e6e7eb5e4e.htm
│ ├── 29676853-5f19-d961-917d-d2a3b1005bc2.htm
│ ├── 2bd00801-6ea4-9aeb-869f-6be672f4b934.htm
│ ├── 2c665003-8e12-9549-f318-997e33c1766b.htm
│ ├── 2cf2e931-e0e8-d47d-aaa6-73cc82ef2e55.htm
│ ├── 2e643178-1fcf-6971-d9c1-921734b7c710.htm
│ ├── 2f361478-0a2b-cf8c-c0b5-c347820086fe.htm
│ ├── 30b16045-d369-9612-cb2a-2f396b746a9d.htm
│ ├── 3198d1e7-848f-41e3-6b13-1e23f6eaaadd.htm
│ ├── 32c1b709-03cf-fa67-24d3-12552bab13dd.htm
│ ├── 335a34f6-a012-4732-1fea-87527cebbecd.htm
│ ├── 3370b8dd-d792-b2c8-df67-f542ff674ba9.htm
│ ├── 34435006-8185-e827-453f-bcf4043b59e3.htm
│ ├── 35350d0e-6fa0-0a27-7b7d-57a59840cdea.htm
│ ├── 35d22925-210f-956e-92b6-12c95fedddaa.htm
│ ├── 3695c805-d9b7-b3e6-32be-183a64f8873a.htm
│ ├── 36b30020-3a33-da99-478f-3806990dcf90.htm
│ ├── 36d82773-9fd2-223a-44bd-acbc25407dda.htm
│ ├── 36e366e7-eeb4-cfe5-dc07-3978cb22ce94.htm
│ ├── 3840dfdb-97e9-882b-796e-9ad6e28ea2a1.htm
│ ├── 3a2ac349-bf62-313a-9f20-4c7c3932b60a.htm
│ ├── 3a4802af-ada6-81eb-0d1a-ca7c114653cf.htm
│ ├── 3a711afe-a630-a052-9ad9-87bd4345613b.htm
│ ├── 3bcf8a5b-b062-5af3-2db8-15cf583f2f31.htm
│ ├── 3cfbfb3e-5b55-59d8-2a64-d298cca31bde.htm
│ ├── 3d0a9909-c581-51c4-1343-950e2653b152.htm
│ ├── 3d50005b-be1d-3245-76c1-a4e60bcd5c18.htm
│ ├── 3e9fb5e9-92dc-8797-9059-3f3a27da6673.htm
│ ├── 3eeb99eb-b6d7-85a1-0001-29f3c220b63a.htm
│ ├── 3f24f883-ede8-64a4-fdd9-f73ddadc6c6c.htm
│ ├── 407075b2-2a77-655b-0bb4-fb45ded42876.htm
│ ├── 40d05494-2f3b-10bd-1fdb-485097690ee9.htm
│ ├── 42b47bc8-9e23-e9db-a8db-1972173530f1.htm
│ ├── 43733aea-c265-b3e4-c53b-17a82b3360b0.htm
│ ├── 43e2abd9-863a-2f7e-aabc-f0c145bb4d29.htm
│ ├── 449f192e-e39e-4f35-d4bd-fd8fd14ef6ad.htm
│ ├── 4622e83d-5f7a-6c28-8838-b7bda56a96fd.htm
│ ├── 473706ce-6549-acda-7330-ee8597293463.htm
│ ├── 48a1f3a8-4ebd-f887-9042-461476ec06e1.htm
│ ├── 4a772778-1995-b7b1-fec3-19dda6d127f9.htm
│ ├── 4b09c588-2b2a-300c-db9d-4567209dba1d.htm
│ ├── 4b854918-3dfc-0e52-8333-edc9d7d419fb.htm
│ ├── 4be8895c-9e74-2785-cce2-fc78782aa936.htm
│ ├── 4c9c15c4-eda9-59d4-8a15-8d789489f0aa.htm
│ ├── 4ec15f56-5d16-3f8b-7f74-a535d3698537.htm
│ ├── 4fc6a36d-12cb-113e-4379-c04f55226882.htm
│ ├── 505b8bcb-2c04-8a59-85ee-f86d7a81133c.htm
│ ├── 50af8943-91c9-96fc-307d-423c066c5933.htm
│ ├── 51289ed1-279a-240e-f276-9147c12f6217.htm
│ ├── 524203d1-c389-0f63-fa4a-616459b7b0e2.htm
│ ├── 52906872-565e-78c6-6f2c-cfd646f7e3d4.htm
│ ├── 542fd7a2-0004-6425-e123-87277c6662cc.htm
│ ├── 5560f824-7c26-030f-a351-7a43f48d3616.htm
│ ├── 55aa38a0-1f7a-ec22-10d8-8bae26960810.htm
│ ├── 55c86eb1-5578-8ae0-dd84-5582fa070efe.htm
│ ├── 569db704-90d1-483e-ace7-0ccba57549c5.htm
│ ├── 56d39bd9-c75f-545e-3b10-d8bc999931d1.htm
│ ├── 580f8ee8-6e40-6d26-8290-6b7b75def84f.htm
│ ├── 5a3e57ca-2a41-36d6-d0a8-f413e253efc6.htm
│ ├── 5a68ef5b-372d-e6ea-0c35-79d60143c238.htm
│ ├── 5a9a83eb-057c-1b58-f5ca-4c8149729116.htm
│ ├── 5d246b79-ab99-fb9d-d02f-6af063d1fa6c.htm
│ ├── 5da15ad8-5869-11b4-3347-2390a0333c45.htm
│ ├── 60dd3c0d-a640-05d4-db8d-c2637f7f2b39.htm
│ ├── 60de7d10-c386-9961-e219-777be8815603.htm
│ ├── 6192a41b-b08d-c9b4-3907-2b945d8fcf80.htm
│ ├── 62d13dd3-f1d7-9949-5659-a07a902efa91.htm
│ ├── 63516731-32a5-c7a6-6170-f8a002200d8c.htm
│ ├── 65ff277a-8063-787e-af75-87fa326a97b7.htm
│ ├── 66d7d0c0-44ca-0d27-5596-1957f0c526a4.htm
│ ├── 66ebce33-e458-872b-5952-866144b9ada0.htm
│ ├── 66f3d7c2-96b2-9c5e-65be-7d2071ec8f9b.htm
│ ├── 6871db6c-e61a-84b5-0ca6-4c240f90fde0.htm
│ ├── 68b42756-a237-c7e8-a3f7-267ca18734b8.htm
│ ├── 69e1e3a3-9710-3929-5a04-6ee7a1e68c3a.htm
│ ├── 6a12da48-72f2-3808-70bd-2c02bfde97d7.htm
│ ├── 6a423ec2-dfae-7237-31d4-736018091ea0.htm
│ ├── 6b3d5d48-0b4d-3b8d-e13f-9648aa1e9723.htm
│ ├── 6bc5ef18-fb9b-7465-3576-f2fcc3b30b44.htm
│ ├── 6bdc660a-cd9d-455a-7908-b6d762c1d8af.htm
│ ├── 6c5bac35-ce3a-6988-f1ab-557b5c8c89ef.htm
│ ├── 6cb87d56-cba5-8b38-17aa-047743f53227.htm
│ ├── 6cd07b17-b3e8-55c6-ec51-b4294f445a2d.htm
│ ├── 6d15bb99-b68e-873c-6c87-e374f6ded979.htm
│ ├── 6d552a41-b41f-9fab-d4ce-41d17f28dfc1.htm
│ ├── 6df4dbc0-c70e-59f8-73ff-a15849692f52.htm
│ ├── 6e591dea-0a75-7d0f-6de5-09ca0069e873.htm
│ ├── 6fa948b9-48cd-ec3b-47c3-b25d3b1a85dc.htm
│ ├── 6ff6011b-6cc8-7f93-8265-dbc3a1df4666.htm
│ ├── 700edc62-50ef-619d-5d88-1907d15ce4ab.htm
│ ├── 70512b72-78fb-5a4a-8fbd-8c01ff72fb9e.htm
│ ├── 70740235-9698-52af-7cd1-614f7550f80b.htm
│ ├── 712af620-4f36-ce65-1d71-1af90ef6e16a.htm
│ ├── 72c4ea1b-c375-10ed-d9f6-9f5bba287781.htm
│ ├── 72f7cd86-5a81-b6fb-50cb-a849074a1f87.htm
│ ├── 747853e5-c5f4-7ae4-6956-be594e9df208.htm
│ ├── 7619d119-9fb4-a181-7523-07273f09e83b.htm
│ ├── 76f722a5-1f41-3369-469a-50225dc7f079.htm
│ ├── 7a82d399-3fe1-048e-ecb1-00b55cbfaba0.htm
│ ├── 7b2ad63d-78ca-4a9b-7bf8-2a3619d8ae78.htm
│ ├── 7c606b90-720d-be95-c43d-4a18e8cb2ccc.htm
│ ├── 7cb762fd-74b7-2119-6570-82592544a596.htm
│ ├── 7fbb1bc0-5346-9adb-23ca-afde8a1cda88.htm
│ ├── 8164731e-9412-adab-9432-1fa0a03aa01d.htm
│ ├── 82864edc-a8c0-fb1e-c8d2-f70b564a089f.htm
│ ├── 82a6b8d0-f606-38df-3050-7192e8c47e61.htm
│ ├── 830f17c7-c111-019a-9c23-522994fd13a3.htm
│ ├── 87c96f49-ef19-0f8c-a88d-27cb504c1ffa.htm
│ ├── 8b6e7069-faa8-05a2-21cd-e6bee8fa1578.htm
│ ├── 8c1d05f9-9974-d9ee-4b69-cbd727d46d5f.htm
│ ├── 8cbb0e35-0dba-781e-d204-2a9d4ea3c191.htm
│ ├── 8ce35937-c031-c897-3338-d93fc03adfaa.htm
│ ├── 8dbe1dc8-266a-4668-ee8a-1fd53d220651.htm
│ ├── 8e596088-4f9e-1214-eb48-e8369d8d3277.htm
│ ├── 90348614-3a75-cec2-bea4-b5847353f958.htm
│ ├── 9196cfe1-64f6-4623-a1c0-a941ecd8c7c7.htm
│ ├── 92bd2ded-5ae5-cfc1-8eb7-f68e747845ca.htm
│ ├── 98ce7e9b-a9d6-7c3f-04f1-2da2a06944e6.htm
│ ├── 990ca6d1-4785-c37c-0a9d-5db6af732336.htm
│ ├── 9c1284e9-e336-1648-c7a6-e2d50005ccb3.htm
│ ├── 9d307145-50e5-2464-e284-b13666d1b1eb.htm
│ ├── 9d6a2465-15ed-a5da-5353-5e0073c7e9a1.htm
│ ├── 9e51c12b-d4aa-b3dc-5578-3081a2bb752f.htm
│ ├── 9eccbac6-fe16-acb8-6b8c-643606251dda.htm
│ ├── 9eda75cf-38c6-c8fd-826b-0d151e3dfc8b.htm
│ ├── 9eea4668-107b-8de8-59e3-22aa6c969ea0.htm
│ ├── 9f48a138-2814-e12f-3ec6-bcb2fc457a47.htm
│ ├── 9fdf1328-d5a8-08a6-692e-00088ef146b7.htm
│ ├── GeneralError.htm
│ ├── PageNotFound.htm
│ ├── a04d813f-23c5-6fc3-bc98-55d2c67527cf.htm
│ ├── a14876ac-b585-07c6-75dd-a0b2c5ce64fe.htm
│ ├── a2213ce7-3ec9-981b-062f-5b90e71d9ef0.htm
│ ├── a24a6f37-2514-e037-21c6-52cf6f7da1ce.htm
│ ├── a322471f-ebc5-8cdb-40f4-a9fa07e0e64f.htm
│ ├── a357a146-da10-d1c5-6dbe-293d4072e351.htm
│ ├── a53a9e81-536d-aec6-959d-32e03a3a7888.htm
│ ├── a5aa12b2-f49e-5944-919e-f689fca5e38c.htm
│ ├── a6c005fe-f1fb-c257-4693-5dd2ccf4a508.htm
│ ├── a761b35c-6058-6fce-044e-7204c140e2f9.htm
│ ├── a7c3cac8-d32c-cfa4-b82d-a575dbbff983.htm
│ ├── a814f7b1-656c-0782-6d3f-be715b415a1d.htm
│ ├── a82bbc27-df2a-11fe-7060-d460e274a7fd.htm
│ ├── a8b5fb3d-a1eb-e372-c1a5-228efd902dd6.htm
│ ├── ab95f6d2-30cf-24bf-a427-621540e1cc36.htm
│ ├── acc5321a-11b6-194d-9978-a32b2a7ec2a3.htm
│ ├── ad6eda66-4832-2efc-b3c0-55e7c8ef7ba4.htm
│ ├── ae1ba7d3-433e-fd72-3f50-1a8ec37aa5f4.htm
│ ├── ae47b3db-c68e-3be4-8385-2321b8963662.htm
│ ├── af48914f-fe94-9752-7573-db5edf2b7fd9.htm
│ ├── af66df3c-8f61-d237-0415-a240644ebb01.htm
│ ├── b22cca88-7580-d134-a7be-c45c7d9c8be2.htm
│ ├── b35dd5f1-998f-89d6-dad2-e05be835d949.htm
│ ├── b45c02d5-d804-8090-5057-0b3e3cbc19a0.htm
│ ├── b5ad6c4c-2609-706b-f56b-547ace8e1dee.htm
│ ├── b64f5e5c-6d8a-0177-8932-f59e1971c505.htm
│ ├── b68dd438-ddc6-b2f7-4a92-8396c448faf5.htm
│ ├── b74ea0f2-07f1-a01d-83c7-d8830d90e57d.htm
│ ├── b82a5fcb-a39d-b771-11ed-ae23c755838f.htm
│ ├── b8f2dc6f-68a0-31f3-6a5b-55042ad516ed.htm
│ ├── ba11da02-35ff-5b18-068e-812d1f92f7df.htm
│ ├── bb27603a-6a4d-9e7c-1cc2-a08ee8ef4109.htm
│ ├── bb8ee71c-0808-feda-2e0a-4b05fc986980.htm
│ ├── bcbabe45-8718-bce0-5974-bae720038d00.htm
│ ├── bcee4a6a-47c8-e1cb-621c-2f876839efd6.htm
│ ├── bd23b31c-aa0c-ec47-793e-36bb05f1ac59.htm
│ ├── be39b34a-20e0-0491-49a7-5a456eef0133.htm
│ ├── be43753c-2f1b-03df-9e55-56be16980d27.htm
│ ├── bf222e0f-2117-7a4d-78cb-0a8e02803aa8.htm
│ ├── c0168d33-3fbb-d636-6455-d1e6d811596e.htm
│ ├── c0169464-5e8c-4c99-0d22-2997afa6d642.htm
│ ├── c016e57d-a1aa-1502-b266-eac555320bd8.htm
│ ├── c1885039-892e-e2b5-0fa0-96da02a925c3.htm
│ ├── c1bf57a5-40dc-a8d6-1e15-b48884f5892b.htm
│ ├── c231898c-c0fd-8636-cd01-91e62005ca68.htm
│ ├── c3c646da-8314-4fd5-f46e-5f8fd1d5730b.htm
│ ├── c482d8a0-7998-bb79-5e92-1376e076a5de.htm
│ ├── c4d800a5-a5de-dc32-6725-c24ca5b6b07f.htm
│ ├── c6965049-109b-ccc8-ab08-add00fa5fe2d.htm
│ ├── c7bdc16d-4098-6768-85e3-0b449ad30c1f.htm
│ ├── c7cb67b3-109d-5722-69ed-5ac3b5fdbc0e.htm
│ ├── c7f31e4f-9f61-353e-7a50-70a068be8196.htm
│ ├── c88283e6-8a6d-e7e4-3a38-9c343e31d7cf.htm
│ ├── ca00d61b-80d6-3c26-6474-e9592a8cd67b.htm
│ ├── cab481d4-3500-53ac-365e-cbf3f4131689.htm
│ ├── cac50def-a782-0642-1a3e-e95e2679c778.htm
│ ├── cad99045-36ff-2d40-f881-6d9616efe8f0.htm
│ ├── cc033925-07e6-b137-a60c-6ffb2f4afb99.htm
│ ├── ce05c987-6053-fb21-59f1-0c83c611e513.htm
│ ├── cf70a8e1-e4eb-2183-4c35-df109d3d7818.htm
│ ├── cf75ec9d-e7a8-37cb-f0f2-4bf4f0279cd5.htm
│ ├── cfafcb67-8636-fcae-c56c-aad4f2241248.htm
│ ├── d1d06fd1-3384-00fc-2611-25539b67b954.htm
│ ├── d1f00718-36e3-c0a5-bf63-061a713f4bd2.htm
│ ├── d1faec22-b4a8-57d4-8509-fc1e35b530b0.htm
│ ├── d205b57d-0a11-6b7d-ceab-edfecfd42975.htm
│ ├── d28eb91b-bf62-51fa-e18e-c4a417be7337.htm
│ ├── d298d81b-b8d3-69e1-1d56-b27dd784823e.htm
│ ├── d2d31ad9-8abb-b53a-7417-7720b259e979.htm
│ ├── d47ffb57-0449-9050-402b-fd4b77b8ce85.htm
│ ├── d574222f-0884-4d82-406d-598e7e49b9ca.htm
│ ├── d5b7f09a-bd5a-8bfd-17c4-218040fe6a3e.htm
│ ├── d6753490-3f4c-d5df-cc50-3cd0a2fbb98e.htm
│ ├── d7e6400a-af87-1003-be8a-a9effb1b622a.htm
│ ├── d806a0fd-cda7-50ff-ec75-63821e97ea83.htm
│ ├── d896819b-a4b3-fafe-2a40-ad78fd8303c4.htm
│ ├── d8f33960-4595-c5e9-ce95-7e4193308d98.htm
│ ├── da17a595-dd19-6c94-c319-ba92780ff1b1.htm
│ ├── dafbf808-d45b-fe61-dfe2-6d1930d50f81.htm
│ ├── db417185-54cd-7eef-2cf0-cb2d7474cff2.htm
│ ├── dc621830-82ae-2687-3604-92d7fefcbc76.htm
│ ├── dd9bc9ad-239f-96e9-955d-5d82260ce525.htm
│ ├── dea5e843-06a7-db5d-8213-d6778ec8243d.htm
│ ├── deaf5148-850e-a69d-5c63-5a1a7264006c.htm
│ ├── deb6bbbc-361f-e1fa-1a28-944836557e27.htm
│ ├── df0364a4-478b-4057-055f-90c0cdf91e0c.htm
│ ├── dffc6c6c-da1a-0e05-486a-66c89481c970.htm
│ ├── e0096895-6dd0-6b06-703d-ccd773068601.htm
│ ├── e100ef8b-93b9-5cb8-5f77-ba3c6992a598.htm
│ ├── e10b3718-42ae-bdb7-e8c5-8fda7d054d52.htm
│ ├── e159fcbc-2053-31ec-dcaa-c3583d88b072.htm
│ ├── e1637911-8e22-f5a6-46a8-f22a852f09b0.htm
│ ├── e2c9ceb2-6c34-7bb9-f1d7-041270a1088f.htm
│ ├── e3237dff-8b9e-7ddf-ff84-7c62943af619.htm
│ ├── e32ad933-56c4-059c-fcf5-99ea235b80b6.htm
│ ├── e3624fc2-b4fb-895d-3b74-40390ea3994d.htm
│ ├── e4216de2-ac9b-991f-ff65-6465c0dca53d.htm
│ ├── e5ea2b24-4ddf-bc82-32fe-c787c3e974b8.htm
│ ├── e65a4995-c3ff-c6e1-ee8b-b5d5c2b3f7b2.htm
│ ├── e6bd7820-438b-49a9-5605-ed00a5e9caea.htm
│ ├── e75af7f2-45fb-5ecf-4f9e-41e596e9f453.htm
│ ├── e82cd517-dc93-1d39-8d56-50744a6a3193.htm
│ ├── e8c9a889-19bc-c8cd-34c1-6912de66612c.htm
│ ├── eb1339b7-b6a8-a213-53c8-70fdd94961fc.htm
│ ├── ebf2f037-d888-6733-6882-3faf1f3e6952.htm
│ ├── ec6875fc-d3d0-99bd-0300-cbe303b3ab73.htm
│ ├── ecad3166-5f2c-2fd8-b94c-de688c02211e.htm
│ ├── ecf46ad6-5296-888e-e4ab-149e15fc50e3.htm
│ ├── ed3c9749-6890-8dc7-f108-7da5fb5ebcaa.htm
│ ├── ed8f32fc-eda4-0426-1a15-4eeb15460ec8.htm
│ ├── edd086d3-b73e-a9c8-583a-728b34baf2b4.htm
│ ├── f0277d7f-20e7-7d21-7723-eff6a7d07f49.htm
│ ├── f0983913-5110-b3fc-40ac-31e1d74e3e11.htm
│ ├── f0ad8da5-0e56-8c1e-74a0-29953ad98f99.htm
│ ├── f2343bf9-88ac-78c3-a6fe-965b78aeaafe.htm
│ ├── f322eee0-b2a6-0288-20a1-9379975c4ccd.htm
│ ├── f3a69b92-0354-52fc-b2c3-8f442702ea51.htm
│ ├── f3b51430-f6ad-bc63-f4a8-1afd7b7c2a85.htm
│ ├── f5861e12-17f7-6986-f198-a79101b9a107.htm
│ ├── f677cae4-0b7e-0f2f-a248-5fa2f0281327.htm
│ ├── fa14ff3e-0df7-c3fa-7383-e4e0f123567a.htm
│ ├── fbb61933-2aad-26b0-f4ef-a12c45469c8f.htm
│ ├── fc3e09de-f376-65f7-47b1-60c2511a5acd.htm
│ ├── fcc98eb4-51e1-b53e-5338-964284c91981.htm
│ ├── fccc0a99-97e3-0285-7073-e3b2d3aa43cf.htm
│ ├── fdfbef58-1137-cab4-864a-66bcdc536cab.htm
│ ├── fea98ee5-d17a-e9c6-54f5-db262d481cd4.htm
│ └── fecece2f-667b-dda0-f43c-d33ef4c15171.htm
├── index.html
├── scripts/
│ ├── branding-Website.js
│ └── branding.js
├── search.html
├── styles/
│ ├── branding-Help1.css
│ ├── branding-HelpViewer.css
│ ├── branding-Website.css
│ ├── branding-cs-CZ.css
│ ├── branding-de-DE.css
│ ├── branding-en-US.css
│ ├── branding-es-ES.css
│ ├── branding-fr-FR.css
│ ├── branding-it-IT.css
│ ├── branding-ja-JP.css
│ ├── branding-ko-KR.css
│ ├── branding-pl-PL.css
│ ├── branding-pt-BR.css
│ ├── branding-ru-RU.css
│ ├── branding-tr-TR.css
│ ├── branding-zh-CN.css
│ ├── branding-zh-TW.css
│ └── branding.css
└── toc/
├── 0456bfc8-b008-c8a3-77ad-0bfefc1310cb.xml
├── 05b14b65-ca9d-7ff2-68b7-f70d7cfcc100.xml
├── 0ea9cbae-1535-ba11-3134-4520d69334f0.xml
├── 0f03b0e7-a914-e46b-c2d6-e0bed40eac37.xml
├── 10dde3c8-66dc-d300-0d82-de410352094d.xml
├── 11348d42-72bd-635f-c392-da90b6c27daa.xml
├── 1685f037-3a5d-6004-7e2c-c72f2c403fed.xml
├── 17a49847-9f5e-41b4-a84a-1bb15979af70.xml
├── 1c02d293-4876-a918-1b8e-c84637cd0860.xml
├── 25858b6c-f545-022f-1421-1980e7d2f9ec.xml
├── 280d4128-f443-8cf2-6a53-33e6e7eb5e4e.xml
├── 29676853-5f19-d961-917d-d2a3b1005bc2.xml
├── 2c665003-8e12-9549-f318-997e33c1766b.xml
├── 2cf2e931-e0e8-d47d-aaa6-73cc82ef2e55.xml
├── 2e643178-1fcf-6971-d9c1-921734b7c710.xml
├── 2f361478-0a2b-cf8c-c0b5-c347820086fe.xml
├── 3198d1e7-848f-41e3-6b13-1e23f6eaaadd.xml
├── 32c1b709-03cf-fa67-24d3-12552bab13dd.xml
├── 335a34f6-a012-4732-1fea-87527cebbecd.xml
├── 34435006-8185-e827-453f-bcf4043b59e3.xml
├── 35d22925-210f-956e-92b6-12c95fedddaa.xml
├── 3a2ac349-bf62-313a-9f20-4c7c3932b60a.xml
├── 3a711afe-a630-a052-9ad9-87bd4345613b.xml
├── 3d0a9909-c581-51c4-1343-950e2653b152.xml
├── 3eeb99eb-b6d7-85a1-0001-29f3c220b63a.xml
├── 407075b2-2a77-655b-0bb4-fb45ded42876.xml
├── 40d05494-2f3b-10bd-1fdb-485097690ee9.xml
├── 449f192e-e39e-4f35-d4bd-fd8fd14ef6ad.xml
├── 473706ce-6549-acda-7330-ee8597293463.xml
├── 48a1f3a8-4ebd-f887-9042-461476ec06e1.xml
├── 4b854918-3dfc-0e52-8333-edc9d7d419fb.xml
├── 505b8bcb-2c04-8a59-85ee-f86d7a81133c.xml
├── 55c86eb1-5578-8ae0-dd84-5582fa070efe.xml
├── 60dd3c0d-a640-05d4-db8d-c2637f7f2b39.xml
├── 6871db6c-e61a-84b5-0ca6-4c240f90fde0.xml
├── 68b42756-a237-c7e8-a3f7-267ca18734b8.xml
├── 6b3d5d48-0b4d-3b8d-e13f-9648aa1e9723.xml
├── 6cd07b17-b3e8-55c6-ec51-b4294f445a2d.xml
├── 6df4dbc0-c70e-59f8-73ff-a15849692f52.xml
├── 70740235-9698-52af-7cd1-614f7550f80b.xml
├── 712af620-4f36-ce65-1d71-1af90ef6e16a.xml
├── 7fbb1bc0-5346-9adb-23ca-afde8a1cda88.xml
├── 8164731e-9412-adab-9432-1fa0a03aa01d.xml
├── 82a6b8d0-f606-38df-3050-7192e8c47e61.xml
├── 830f17c7-c111-019a-9c23-522994fd13a3.xml
├── 8e596088-4f9e-1214-eb48-e8369d8d3277.xml
├── 90348614-3a75-cec2-bea4-b5847353f958.xml
├── 990ca6d1-4785-c37c-0a9d-5db6af732336.xml
├── 9d307145-50e5-2464-e284-b13666d1b1eb.xml
├── 9eda75cf-38c6-c8fd-826b-0d151e3dfc8b.xml
├── 9eea4668-107b-8de8-59e3-22aa6c969ea0.xml
├── a2213ce7-3ec9-981b-062f-5b90e71d9ef0.xml
├── a357a146-da10-d1c5-6dbe-293d4072e351.xml
├── a6c005fe-f1fb-c257-4693-5dd2ccf4a508.xml
├── ad6eda66-4832-2efc-b3c0-55e7c8ef7ba4.xml
├── af66df3c-8f61-d237-0415-a240644ebb01.xml
├── b22cca88-7580-d134-a7be-c45c7d9c8be2.xml
├── b45c02d5-d804-8090-5057-0b3e3cbc19a0.xml
├── b5ad6c4c-2609-706b-f56b-547ace8e1dee.xml
├── b82a5fcb-a39d-b771-11ed-ae23c755838f.xml
├── ba11da02-35ff-5b18-068e-812d1f92f7df.xml
├── bb27603a-6a4d-9e7c-1cc2-a08ee8ef4109.xml
├── bcbabe45-8718-bce0-5974-bae720038d00.xml
├── bcee4a6a-47c8-e1cb-621c-2f876839efd6.xml
├── bd23b31c-aa0c-ec47-793e-36bb05f1ac59.xml
├── be43753c-2f1b-03df-9e55-56be16980d27.xml
├── bf222e0f-2117-7a4d-78cb-0a8e02803aa8.xml
├── c0168d33-3fbb-d636-6455-d1e6d811596e.xml
├── c231898c-c0fd-8636-cd01-91e62005ca68.xml
├── c7cb67b3-109d-5722-69ed-5ac3b5fdbc0e.xml
├── c88283e6-8a6d-e7e4-3a38-9c343e31d7cf.xml
├── cac50def-a782-0642-1a3e-e95e2679c778.xml
├── cad99045-36ff-2d40-f881-6d9616efe8f0.xml
├── d205b57d-0a11-6b7d-ceab-edfecfd42975.xml
├── d28eb91b-bf62-51fa-e18e-c4a417be7337.xml
├── d2d31ad9-8abb-b53a-7417-7720b259e979.xml
├── deb6bbbc-361f-e1fa-1a28-944836557e27.xml
├── dffc6c6c-da1a-0e05-486a-66c89481c970.xml
├── e10b3718-42ae-bdb7-e8c5-8fda7d054d52.xml
├── e2c9ceb2-6c34-7bb9-f1d7-041270a1088f.xml
├── e5ea2b24-4ddf-bc82-32fe-c787c3e974b8.xml
├── e65a4995-c3ff-c6e1-ee8b-b5d5c2b3f7b2.xml
├── e82cd517-dc93-1d39-8d56-50744a6a3193.xml
├── ed3c9749-6890-8dc7-f108-7da5fb5ebcaa.xml
├── f0983913-5110-b3fc-40ac-31e1d74e3e11.xml
├── f322eee0-b2a6-0288-20a1-9379975c4ccd.xml
├── f3a69b92-0354-52fc-b2c3-8f442702ea51.xml
├── f3b51430-f6ad-bc63-f4a8-1afd7b7c2a85.xml
├── fa14ff3e-0df7-c3fa-7383-e4e0f123567a.xml
├── fc3e09de-f376-65f7-47b1-60c2511a5acd.xml
└── roottoc.xml
SYMBOL INDEX (506 symbols across 55 files)
FILE: Solid.Arduino.IntegrationTest/SerialConnectionTester.cs
class SerialConnectionTester (line 9) | [TestClass]
method FindSerialConnection_FirmataEnabled (line 18) | [TestMethod]
method FindSerialConnection_Serial (line 40) | [TestMethod]
FILE: Solid.Arduino.IntegrationTest/SocketConnectionTester.cs
class SocketConnectionTester (line 10) | [TestClass]
method TestMethod1 (line 53) | [TestMethod]
FILE: Solid.Arduino.Run/Program.cs
class Program (line 10) | class Program
method Main (line 12) | static void Main(string[] args)
method GetConnection (line 25) | private static ISerialConnection GetConnection()
method PerformBasicTest (line 38) | private static void PerformBasicTest(IFirmataProtocol session)
method DisplayPortCapabilities (line 55) | private static void DisplayPortCapabilities()
method TimeTest (line 87) | private void TimeTest()
method Session_OnMessageReceived (line 104) | void Session_OnMessageReceived(object sender, FirmataMessageEventArgs ...
method SimpelTest (line 122) | static void SimpelTest(ISerialConnection connection)
method Session_OnDigitalStateReceived (line 230) | static void Session_OnDigitalStateReceived(object sender, FirmataEvent...
method Session_OnAnalogStateReceived (line 235) | static void Session_OnAnalogStateReceived(object sender, FirmataEventA...
FILE: Solid.Arduino.Test/ArduinoSessionTester.cs
class ArduinoSessionTester (line 10) | [TestClass]
method CreateSessionWithClosedConnection (line 16) | [TestMethod]
method ArduinoSession_Constructor_NullArgument (line 25) | [ExpectedException(typeof(ArgumentNullException))]
method CreateSessionWithOpenConnection (line 31) | [TestMethod]
method ClearSession (line 40) | [TestMethod]
method TimeOutReached (line 49) | [TestMethod]
method TimeOut_GetAndSet (line 58) | [TestMethod]
method TimeOut_SetNegative (line 68) | [TestMethod]
method Dispose (line 77) | [TestMethod]
method Dispose_OnOpenConnection (line 85) | [TestMethod]
method session_OnMessageReceived (line 94) | private void session_OnMessageReceived(object par_Sender, FirmataMessa...
FILE: Solid.Arduino.Test/ByteArrayExtensionsTester.cs
class ByteArrayExtensionsTester (line 10) | [TestClass]
method ConvertBinaryCodedDecimalToString_NullData (line 53) | [TestMethod]
method ConvertBinaryCodedDecimalToString_NonDigitBytes (line 61) | [TestMethod]
method ConvertBinaryCodedDecimalToString_LeastSignificantNotDigit (line 69) | [TestMethod]
method ConvertBinaryCodedDecimalToString_MostSignificantNotDigit (line 77) | [TestMethod]
method ConvertBinaryCodedDecimalToString_NoData (line 85) | [TestMethod]
method ConvertBinaryCodedDecimalToString_1Byte (line 92) | [TestMethod]
method ConvertBinaryCodedDecimalToString_AllDigits (line 103) | [TestMethod]
method ConvertBinaryCodedDecimalToString_AllDigits_LittleEndian (line 114) | [TestMethod]
FILE: Solid.Arduino.Test/DigitalPortStateTester.cs
class DigitalPortStateTester (line 11) | [TestClass]
method DigitalPortStateTester (line 14) | public DigitalPortStateTester()
method IsHigh_Pins_Is0 (line 59) | [TestMethod]
method IsHigh_Pins_Is255 (line 73) | [TestMethod]
method IsHigh_Pin_Argument_IsNegative (line 87) | [TestMethod]
method IsHigh_Pin_Argument_Is8 (line 95) | [TestMethod]
FILE: Solid.Arduino.Test/EnhancedSerialConnectionTester.cs
class EnhancedSerialConnectionTester (line 7) | [TestClass]
method EnhancedSerialConnection_Constructor_WithoutParameters (line 10) | [TestMethod]
method EnhancedSerialConnection_Constructor_WithParameters (line 25) | [TestMethod]
method EnhancedSerialConnection_OpenAndClose (line 37) | [TestMethod]
method EnhancedSerialConnection_OpenAndDoubleClose (line 48) | [TestMethod]
method AreSerialPortsAvailable (line 60) | private static bool AreSerialPortsAvailable()
FILE: Solid.Arduino.Test/ExceptionMonitor.cs
class ExceptionMonitor (line 7) | class ExceptionMonitor
method Setup (line 9) | public void Setup()
method FirstChanceHandler (line 18) | static void FirstChanceHandler(object o, FirstChanceExceptionEventArgs e)
FILE: Solid.Arduino.Test/I2cProtocolTester.cs
class I2CProtocolTester (line 11) | [TestClass]
method SetI2CReadInterval_Interval_IsNegative (line 16) | [TestMethod]
method SetI2CReadInterval_Interval_Is0x4000 (line 27) | [TestMethod]
method SetI2CReadInterval_Interval_Is0 (line 38) | [TestMethod]
method SetI2CReadInterval_Interval_Is0x3FFF (line 48) | [TestMethod]
method WriteI2C_SlaveAddress_Parameter_Is0 (line 58) | [TestMethod]
method WriteI2C_SlaveAddress_Parameter_Is0x3FF (line 68) | [TestMethod]
method WriteI2C_SlaveAddress_Parameter_Is127 (line 78) | [TestMethod]
method WriteI2C_SlaveAddress_Parameter_IsNegative (line 88) | [TestMethod]
method WriteI2C_SlaveAddress_Parameter_Is0x400 (line 99) | [TestMethod]
method WriteI2C_Data_Parameter_IsNull (line 110) | [TestMethod]
method ReadI2COnce_SlaveAddress_Parameter_IsNegative (line 120) | [TestMethod]
method ReadI2COnce_SlaveAddress_Parameter_Is0x400 (line 131) | [TestMethod]
method ReadI2COnce_BytesToRead_Parameter_IsNegative (line 142) | [TestMethod]
method ReadI2COnce_BytesToRead_Parameter_Is0x4000 (line 153) | [TestMethod]
method ReadI2COnce_SlaveRegister_Parameter_IsNegative (line 164) | [TestMethod]
method ReadI2COnce_SlaveRegister_Parameter_Is0x4000 (line 175) | [TestMethod]
method ReadI2COnce_MinimumParameters (line 186) | [TestMethod]
method ReadI2COnce_MaximumParameters (line 196) | [TestMethod]
method ReadI2COnce_MinimumParameters_WithSlaveRegister (line 206) | [TestMethod]
method ReadI2COnce_MaximumParameters_WithSlaveRegister (line 216) | [TestMethod]
method ReadI2CContinous (line 226) | [TestMethod]
method ReadI2CContinous_WithSlaveRegister (line 236) | [TestMethod]
method GetI2CReply (line 246) | [TestMethod]
method GetI2CReply_BytesToRead_Parameter_Is0 (line 263) | [TestMethod]
method GetI2CReply_WithSlaveRegister (line 277) | [TestMethod]
method GetI2CReplyAsync (line 292) | [TestMethod]
method GetI2CReplyAsync_WithSlaveRegister (line 308) | [TestMethod]
method I2CReplyReceived (line 324) | [TestMethod]
method StopI2CReading (line 348) | [TestMethod]
method CreateFirmataSession (line 358) | private II2CProtocol CreateFirmataSession(ISerialConnection connection...
FILE: Solid.Arduino.Test/IFirmataProtocolTester.cs
class IFirmataProtocolTester (line 10) | [TestClass]
method ResetBoard (line 15) | [TestMethod]
method GetProtocolVersion (line 32) | [TestMethod]
method GetProtocolVersionAsync (line 45) | [TestMethod]
method RequestProtocolVersion (line 59) | [TestMethod]
method GetFirmware (line 77) | [TestMethod]
method GetFirmwareAsync (line 98) | [TestMethod]
method RequestFirmware (line 118) | [TestMethod]
method GetBoardCapability (line 143) | [TestMethod]
method GetBoardCapabilityAsync (line 171) | [TestMethod]
method RequestBoardCapability (line 218) | [TestMethod]
method GetBoardAnalogMapping (line 258) | [TestMethod]
method GetBoardAnalogMappingAsync (line 289) | [TestMethod]
method RequestBoardAnalogMapping (line 316) | [TestMethod]
method GetPinState_NegativePinNumber_Argument (line 337) | [TestMethod]
method GetPinState_PinNumber_Argument_Is128 (line 352) | [TestMethod]
method GetPinState_PinNumber_Argument_Is0 (line 367) | [TestMethod]
method GetPinState_PinNumber_Argument_Is127_Returned_Pin0 (line 385) | [TestMethod]
method GetPinState_PinNumber_Argument_Is127 (line 403) | [TestMethod]
method GetPinStateAsync (line 421) | [TestMethod]
method RequestPinState (line 439) | [TestMethod]
method SetDigitalPinMode_PinNumber_Negative (line 461) | [TestMethod]
method SetDigitalPinMode_PinNumber_Is128 (line 472) | [TestMethod]
method SetDigitalPinMode_SetPin0ToDigitalOutput (line 483) | [TestMethod]
method SetDigitalPinMode_SetPin127ToAnalog (line 493) | [TestMethod]
method SetDigitalPin_PinNumber_Argument_IsNegative (line 503) | [TestMethod]
method SetDigitalPin_PinNumber_Argument_Is128 (line 514) | [TestMethod]
method SetDigitalPin_Level_Argument_IsNegative (line 525) | [TestMethod]
method SetDigitalPin_Level_PinNumber_Argument_Is0 (line 536) | [TestMethod]
method SetDigitalPin_Level_Is0_PinNumber_Argument_Is16 (line 546) | [TestMethod]
method SetDigitalPin_Level_PinNumber_Argument_Is15 (line 556) | [TestMethod]
method SetDigitalPin_Level_PinNumber_Argument_Is0_Level_Argument_Is0x3FFF (line 566) | [TestMethod]
method SetDigitalPin_Level_PinNumber_Argument_Is0_Level_Argument_Is0x4000 (line 576) | [TestMethod]
method SetDigitalPin_Level_PinNumber_Argument_Is0_Level_Argument_Is0xFFFF (line 586) | [TestMethod]
method SetDigitalPort_PortNumber_Argument_IsNegative (line 596) | [TestMethod]
method SetDigitalPort_PortNumber_Argument_Is128 (line 607) | [TestMethod]
method SetDigitalPort_Pins_Argument_IsNegative (line 618) | [TestMethod]
method SetDigitalPort_Pins_Argument_Is256 (line 629) | [TestMethod]
method SetDigitalPort_PortNumber_Is0_Pins_Is0 (line 640) | [TestMethod]
method SetDigitalPort_PortNumber_Is15_Pins_Is255 (line 650) | [TestMethod]
method SetDigitalReportMode_PortNumber_IsNegative (line 660) | [TestMethod]
method SetDigitalReportMode_PortNumber_Is16 (line 671) | [TestMethod]
method SetDigitalReportMode_PortNumber_Is1_Enable (line 682) | [TestMethod]
method SetDigitalReportMode_PortNumber_Is0_Disable (line 692) | [TestMethod]
method SetAnalogReportMode_Channel_IsNegative (line 702) | [TestMethod]
method SetAnalogReportMode_Channel_Is16 (line 713) | [TestMethod]
method SetAnalogReportMode_Channel_Is0_Enable (line 724) | [TestMethod]
method SetAnalogReportMode_Channel_Is15_Disable (line 734) | [TestMethod]
method SetSamplingInterval_Interval_IsNegative (line 744) | [TestMethod]
method SetSamplingInterval_Interval_Is0x4000 (line 755) | [TestMethod]
method SetSamplingInterval_Interval_Is0 (line 766) | [TestMethod]
method SetSamplingInterval_Interval_Is0x3FFF (line 776) | [TestMethod]
method AnalogStateReceived_MinValues (line 786) | [TestMethod]
method AnalogStateReceived_MaxValues (line 810) | [TestMethod]
method AnalogStateReceived_Channel_LsbMsbOrder (line 834) | [TestMethod]
method DigitalStateReceived_MinValues (line 858) | [TestMethod]
method DigitalStateReceived_MaxValues (line 882) | [TestMethod]
method SendStringData (line 906) | [TestMethod]
method SendStringData_NullString (line 918) | [TestMethod]
method Receive_StringDataMessage (line 928) | [TestMethod]
method TimedoutResponse (line 950) | public void TimedoutResponse()
method MixedOrderResponses (line 960) | [TestMethod]
method CreateFirmataSession (line 983) | private IFirmataProtocol CreateFirmataSession(ISerialConnection connec...
FILE: Solid.Arduino.Test/IServoProtocolTester.cs
class IServoProtocolTester (line 11) | [TestClass]
method ConfigureServo_PinNumber_IsNegative (line 16) | [TestMethod]
method ConfigureServo_PinNumber_Is128 (line 27) | [TestMethod]
method ConfigureServo_MinPulse_IsNegative (line 38) | [TestMethod]
method ConfigureServo_MinPulse_Is0x4000 (line 49) | [TestMethod]
method ConfigureServo_MaxPulse_Is0x4000 (line 60) | [TestMethod]
method ConfigureServo_MaxPulse_IsNegative (line 71) | [TestMethod]
method ConfigureServo_MinPulse_GT_MaxPulse (line 82) | [TestMethod]
method ConfigureServo_MinPulse_EQ_MaxPulse (line 93) | [TestMethod]
method ConfigureServo (line 103) | [TestMethod]
method CreateServoSession (line 113) | private IServoProtocol CreateServoSession(ISerialConnection connection...
FILE: Solid.Arduino.Test/IStringProtocolTester.cs
class IStringProtocolTester (line 12) | [TestClass]
method Write (line 55) | [TestMethod]
method Write_NoArgument (line 64) | [TestMethod]
method Write_NullString (line 72) | [TestMethod]
method Write_EmptyString (line 80) | [TestMethod]
method WriteLine (line 88) | [TestMethod]
method WriteLine_NoArgument (line 97) | [TestMethod]
method WriteLine_NullString (line 106) | [TestMethod]
method WriteLine_EmptyString (line 115) | [TestMethod]
method WriteLine_CarriageReturnAsNewLine (line 124) | [TestMethod]
method Read_OneCharacter (line 134) | [TestMethod]
method StringReceived (line 153) | public void StringReceived()
method ReceivedStringBufferOverflow (line 169) | [TestMethod]
method RequestBufferOverflow (line 188) | public async Task RequestBufferOverflow()
method Read_StringBlock (line 210) | [TestMethod]
method Read_WithTimeout (line 230) | public async Task Read_WithTimeout()
method Read_NegativeLength (line 245) | [TestMethod]
method ReadLine (line 263) | [TestMethod]
method ReadLine_EmptyString (line 281) | [TestMethod]
method ReadLine_CarriageReturn (line 299) | [TestMethod]
method ReadLine_CarriageReturnPlusLinefeed (line 319) | [TestMethod]
method ReadTo (line 341) | [TestMethod]
method ReadTo_EmptyString (line 359) | [TestMethod]
method ReadAsync_NoParameters (line 377) | [TestMethod]
method ReadAsync_4Characters (line 390) | [TestMethod]
method ReadAsync_Length_IsNegative (line 403) | [TestMethod]
method ReadLineAsync (line 416) | [TestMethod]
method ReadToAsync (line 429) | [TestMethod]
method CreateSerialSession (line 442) | private IStringProtocol CreateSerialSession(ISerialConnection connecti...
method Read (line 469) | private async Task<string> Read()
FILE: Solid.Arduino.Test/MockSerialConnection.cs
class MockSerialConnection (line 11) | internal class MockSerialConnection: ISerialConnection
method Open (line 65) | public void Open()
method Close (line 73) | public void Close()
method ReadByte (line 78) | public int ReadByte()
method Write (line 93) | public void Write(string text)
method Write (line 107) | public void Write(byte[] buffer, int offset, int count)
method WriteLine (line 128) | public void WriteLine(string text)
method Dispose (line 139) | public void Dispose()
method EnqueueResponse (line 148) | public void EnqueueResponse(params byte[] data)
method EnqueueRequest (line 154) | public void EnqueueRequest(params byte[] request)
method EnqueueRequestAndResponse (line 159) | public void EnqueueRequestAndResponse(byte[] request, params byte[] re...
method EnqueueStringResponse (line 170) | public void EnqueueStringResponse(string data)
method EnqueueStringRequest (line 176) | public void EnqueueStringRequest(string data)
method HandleStringResponse (line 181) | public void HandleStringResponse(string response, Action handler)
method MockReceiveDelayed (line 205) | public void MockReceiveDelayed(string data)
method AssertEqualToExpectedRequestByte (line 220) | private void AssertEqualToExpectedRequestByte(byte p)
method ReceiveData (line 244) | private void ReceiveData(byte[] response)
FILE: Solid.Arduino.Test/ObservableArduinoSessionTester.cs
class ObservableArduinoSessionTester (line 5) | [TestClass]
method TestMethod1 (line 8) | [TestMethod]
FILE: Solid.Arduino.Test/SerialConnectionTester.cs
class SerialConnectionTester (line 7) | [TestClass]
method SerialConnection_Constructor_WithoutParameters (line 10) | [TestMethod]
method SerialConnection_Constructor_WithParameters (line 25) | [TestMethod]
method SerialConnection_OpenAndClose (line 34) | [TestMethod]
method SerialConnection_OpenAndDoubleClose (line 45) | [TestMethod]
method AreSerialPortsAvailable (line 57) | private static bool AreSerialPortsAvailable()
FILE: Solid.Arduino.Test/StringExtensionsTester.cs
class StringExtensionsTester (line 7) | [TestClass]
method ToBinaryCodedDecimal (line 10) | [TestMethod]
method ToBinaryCodedDecimal_AllDigits (line 18) | [TestMethod]
method ToBinaryCodedDecimal_AllDigits_LittleEndian (line 30) | [TestMethod]
method ToBinaryCodedDecimal_OneDigit (line 42) | [TestMethod]
method ToBinaryCodedDecimal_LittleEndian (line 50) | [TestMethod]
method ToBinaryCodedDecimal_NullString (line 58) | [TestMethod]
method ToBinaryCodedDecimal_AlphaNumeric (line 66) | [TestMethod]
method ToBinaryCodedDecimal_EmptyString (line 74) | [TestMethod]
method To14BitIso_NullString (line 81) | [TestMethod]
method To14BitIso_EmptyString (line 90) | [TestMethod]
method To14BitIso_SingleCharacter (line 97) | [TestMethod]
method To14BitIso_3Characters (line 106) | [TestMethod]
FILE: Solid.Arduino/ArduinoSession.cs
class ArduinoSession (line 60) | public class ArduinoSession : IFirmataProtocol, IServoProtocol, II2CProt...
type MessageHeader (line 66) | private enum MessageHeader
type StringReadMode (line 74) | private enum StringReadMode {
class StringRequest (line 80) | private class StringRequest
method CreateReadLineRequest (line 86) | public static StringRequest CreateReadLineRequest()
method CreateReadRequest (line 91) | public static StringRequest CreateReadRequest(int blockLength)
method CreateReadRequest (line 96) | public static StringRequest CreateReadRequest(char terminator)
method StringRequest (line 101) | private StringRequest(StringReadMode mode, char terminator, int bloc...
method ArduinoSession (line 142) | public ArduinoSession(ISerialConnection connection)
method ArduinoSession (line 160) | public ArduinoSession(ISerialConnection connection, int timeOut)
method Clear (line 190) | public void Clear()
method CreateReceivedStringMonitor (line 209) | public IObservable<string> CreateReceivedStringMonitor()
method Write (line 226) | public void Write(string value)
method WriteLine (line 233) | public void WriteLine(string value)
method ReadLine (line 239) | public string ReadLine()
method ReadLineAsync (line 245) | public async Task<string> ReadLineAsync()
method Read (line 251) | public string Read(int length = 1)
method ReadAsync (line 260) | public async Task<string> ReadAsync(int length = 1)
method ReadTo (line 269) | public string ReadTo(char terminator = char.MinValue)
method ReadToAsync (line 275) | public async Task<string> ReadToAsync(char terminator = char.MinValue)
method CreateDigitalStateMonitor (line 292) | public IObservable<DigitalPortState> CreateDigitalStateMonitor()
method CreateDigitalStateMonitor (line 298) | public IObservable<DigitalPortState> CreateDigitalStateMonitor(int port)
method CreateAnalogStateMonitor (line 307) | public IObservable<AnalogState> CreateAnalogStateMonitor()
method CreateAnalogStateMonitor (line 313) | public IObservable<AnalogState> CreateAnalogStateMonitor(int channel)
method ResetBoard (line 322) | public void ResetBoard()
method SetDigitalPin (line 328) | public void SetDigitalPin(int pinNumber, long value)
method SetDigitalPin (line 369) | public void SetDigitalPin(int pinNumber, bool value)
method SetAnalogReportMode (line 378) | public void SetAnalogReportMode(int channel, bool enable)
method SetDigitalPort (line 387) | public void SetDigitalPort(int portNumber, int pins)
method SetDigitalReportMode (line 399) | public void SetDigitalReportMode(int portNumber, bool enable)
method SetDigitalPinMode (line 408) | public void SetDigitalPinMode(int pinNumber, PinMode mode)
method SetSamplingInterval (line 417) | public void SetSamplingInterval(int milliseconds)
method SendStringData (line 434) | public void SendStringData(string data)
method RequestFirmware (line 456) | public void RequestFirmware()
method GetFirmware (line 462) | public Firmware GetFirmware()
method GetFirmwareAsync (line 469) | public async Task<Firmware> GetFirmwareAsync()
method RequestProtocolVersion (line 477) | public void RequestProtocolVersion()
method GetProtocolVersion (line 483) | public ProtocolVersion GetProtocolVersion()
method GetProtocolVersionAsync (line 490) | public async Task<ProtocolVersion> GetProtocolVersionAsync()
method RequestBoardCapability (line 498) | public void RequestBoardCapability()
method GetBoardCapability (line 504) | public BoardCapability GetBoardCapability()
method GetBoardCapabilityAsync (line 511) | public async Task<BoardCapability> GetBoardCapabilityAsync()
method RequestBoardAnalogMapping (line 519) | public void RequestBoardAnalogMapping()
method GetBoardAnalogMapping (line 525) | public BoardAnalogMapping GetBoardAnalogMapping()
method GetBoardAnalogMappingAsync (line 532) | public async Task<BoardAnalogMapping> GetBoardAnalogMappingAsync()
method RequestPinState (line 540) | public void RequestPinState(int pinNumber)
method GetPinState (line 556) | public PinState GetPinState(int pinNumber)
method GetPinStateAsync (line 563) | public async Task<PinState> GetPinStateAsync(int pinNumber)
method ConfigureServo (line 578) | public void ConfigureServo(int pinNumber, int minPulse, int maxPulse)
method CreateI2CReplyMonitor (line 614) | public IObservable<I2CReply> CreateI2CReplyMonitor()
method SetI2CReadInterval (line 620) | public void SetI2CReadInterval(int microseconds)
method WriteI2C (line 637) | public void WriteI2C(int slaveAddress, params byte[] data)
method ReadI2COnce (line 660) | public void ReadI2COnce(int slaveAddress, int bytesToRead)
method GetI2CReply (line 666) | public I2CReply GetI2CReply(int slaveAddress, int bytesToRead)
method GetI2CReplyAsync (line 675) | public async Task<I2CReply> GetI2CReplyAsync(int slaveAddress, int byt...
method ReadI2COnce (line 685) | public void ReadI2COnce(int slaveAddress, int slaveRegister, int bytes...
method GetI2CReply (line 691) | public I2CReply GetI2CReply(int slaveAddress, int slaveRegister, int b...
method GetI2CReplyAsync (line 700) | public async Task<I2CReply> GetI2CReplyAsync(int slaveAddress, int sla...
method ReadI2CContinuous (line 710) | public void ReadI2CContinuous(int slaveAddress, int bytesToRead)
method ReadI2CContinuous (line 716) | public void ReadI2CContinuous(int slaveAddress, int slaveRegister, int...
method StopI2CReading (line 730) | public void StopI2CReading()
method Dispose (line 749) | public void Dispose()
method WriteMessageByte (line 761) | private void WriteMessageByte(byte dataByte)
method GetStringFromQueue (line 770) | private string GetStringFromQueue(StringRequest request)
method GetMessageFromQueue (line 802) | private object GetMessageFromQueue(FirmataMessage awaitedMessage)
method SendSysExCommand (line 839) | private void SendSysExCommand(byte command)
method I2CSlaveRead (line 850) | private void I2CSlaveRead(bool continuous, int slaveAddress, int slave...
method I2CRead (line 858) | private void I2CRead(bool continuous, int slaveAddress, int slaveRegis...
method SerialDataReceived (line 893) | private void SerialDataReceived(object sender, SerialDataReceivedEvent...
method ProcessAsciiString (line 926) | private void ProcessAsciiString(int serialByte)
method EnqueueReceivedString (line 974) | private void EnqueueReceivedString(string value)
method ProcessCommand (line 1000) | private void ProcessCommand(byte serialByte)
method ProcessAnalogStateMessage (line 1048) | private void ProcessAnalogStateMessage(byte messageByte)
method ProcessDigitalStateMessage (line 1068) | private void ProcessDigitalStateMessage(byte messageByte)
method ProcessProtocolVersionMessage (line 1088) | private void ProcessProtocolVersionMessage(byte messageByte)
method ProcessSysExMessage (line 1105) | private void ProcessSysExMessage(byte messageByte)
method DeliverMessage (line 1145) | private void DeliverMessage(FirmataMessage message)
method CreateI2CReply (line 1169) | private FirmataMessage CreateI2CReply()
method CreatePinStateResponse (line 1189) | private FirmataMessage CreatePinStateResponse()
method CreateAnalogMappingResponse (line 1210) | private FirmataMessage CreateAnalogMappingResponse()
method CreateCapabilityResponse (line 1233) | private FirmataMessage CreateCapabilityResponse()
method CreateStringDataMessage (line 1316) | private FirmataMessage CreateStringDataMessage()
method CreateFirmwareResponse (line 1333) | private FirmataMessage CreateFirmwareResponse()
FILE: Solid.Arduino/EnhancedSerialConnection.cs
class EnhancedSerialConnection (line 11) | public class EnhancedSerialConnection : EnhancedSerialPort, ISerialConne...
method EnhancedSerialConnection (line 16) | public EnhancedSerialConnection()
method EnhancedSerialConnection (line 28) | public EnhancedSerialConnection(string portName, SerialBaudRate baudRate)
method Find (line 36) | public static ISerialConnection Find()
method Find (line 42) | public static ISerialConnection Find(string query, string expectedReply)
method Close (line 48) | public new void Close()
method GetLastPortName (line 58) | private static string GetLastPortName() => GetPortNames()
FILE: Solid.Arduino/EnhancedSerialPort.cs
class EnhancedSerialPort (line 40) | public class EnhancedSerialPort : SerialPort
method poll_serial (line 43) | [DllImport("MonoPosixHelper", SetLastError = true)]
method strerror (line 46) | [DllImport("libc")]
method EnhancedSerialPort (line 61) | public EnhancedSerialPort()
method EnhancedSerialPort (line 66) | public EnhancedSerialPort(IContainer container)
method EnhancedSerialPort (line 72) | public EnhancedSerialPort(string portName)
method EnhancedSerialPort (line 78) | public EnhancedSerialPort(string portName, int baudRate)
method EnhancedSerialPort (line 84) | public EnhancedSerialPort(string portName, int baudRate, Parity parity)
method EnhancedSerialPort (line 90) | public EnhancedSerialPort(string portName, int baudRate, Parity parity...
method EnhancedSerialPort (line 96) | public EnhancedSerialPort(string portName, int baudRate, Parity parity...
method GetInitializedPortName (line 101) | private static string GetInitializedPortName(string portName)
method Open (line 114) | public new void Open()
method EventThreadFunction (line 149) | private void EventThreadFunction()
method OnDataReceived (line 174) | private void OnDataReceived(SerialDataReceivedEventArgs args)
method Poll (line 179) | private bool Poll(Stream stream)
method CheckDisposed (line 199) | private void CheckDisposed(Stream stream)
FILE: Solid.Arduino/Firmata/AnalogPinMapping.cs
class AnalogPinMapping (line 6) | public sealed class AnalogPinMapping
FILE: Solid.Arduino/Firmata/AnalogState.cs
class AnalogState (line 6) | public sealed class AnalogState
FILE: Solid.Arduino/Firmata/AnalogStateTracker.cs
class AnalogStateTracker (line 3) | internal class AnalogStateTracker : ObservableEventTracker<IFirmataProto...
method AnalogStateTracker (line 7) | internal AnalogStateTracker(IFirmataProtocol source, int channel = -1)
method Dispose (line 14) | public override void Dispose()
method Firmata_AnalogStateReceived (line 23) | void Firmata_AnalogStateReceived(object parSender, FirmataEventArgs<An...
FILE: Solid.Arduino/Firmata/BoardAnalogMapping.cs
class BoardAnalogMapping (line 6) | public sealed class BoardAnalogMapping
FILE: Solid.Arduino/Firmata/BoardCapability.cs
class BoardCapability (line 6) | public sealed class BoardCapability
FILE: Solid.Arduino/Firmata/ByteArrayExtensions.cs
class ByteArrayExtensions (line 8) | public static class ByteArrayExtensions
method ConvertBinaryCodedDecimalToString (line 17) | public static string ConvertBinaryCodedDecimalToString(this byte[] dat...
method ConvertToChar (line 48) | private static char ConvertToChar(int code)
FILE: Solid.Arduino/Firmata/DigitalPortState.cs
class DigitalPortState (line 8) | public sealed class DigitalPortState
method IsSet (line 25) | public bool IsSet(int pin)
FILE: Solid.Arduino/Firmata/DigitalStateTracker.cs
class DigitalStateTracker (line 3) | internal class DigitalStateTracker : ObservableEventTracker<IFirmataProt...
method DigitalStateTracker (line 7) | internal DigitalStateTracker(IFirmataProtocol source, int port = -1)
method Dispose (line 14) | public override void Dispose()
method Firmata_DigitalStateReceived (line 23) | void Firmata_DigitalStateReceived(object parSender, FirmataEventArgs<D...
FILE: Solid.Arduino/Firmata/FirmataMessage.cs
class FirmataMessage (line 8) | public sealed class FirmataMessage
method FirmataMessage (line 18) | internal FirmataMessage(MessageType type)
method FirmataMessage (line 26) | internal FirmataMessage(object value, MessageType type)
method FirmataMessage (line 35) | internal FirmataMessage(object value, MessageType type, DateTime time)
type MessageType (line 61) | public enum MessageType
FILE: Solid.Arduino/Firmata/FirmataMessageEventArgs.cs
class FirmataMessageEventArgs (line 9) | public sealed class FirmataMessageEventArgs : EventArgs
method FirmataMessageEventArgs (line 14) | internal FirmataMessageEventArgs(FirmataMessage value)
FILE: Solid.Arduino/Firmata/FirmataMessageEventArgs_.cs
class FirmataEventArgs (line 14) | public sealed class FirmataEventArgs<T> : EventArgs
method FirmataEventArgs (line 19) | internal FirmataEventArgs(T value)
FILE: Solid.Arduino/Firmata/Firmware.cs
class Firmware (line 6) | public sealed class Firmware
FILE: Solid.Arduino/Firmata/IFirmataProtocol.cs
type PinMode (line 30) | public enum PinMode
type IFirmataProtocol (line 53) | public interface IFirmataProtocol
method CreateAnalogStateMonitor (line 93) | IObservable<AnalogState> CreateAnalogStateMonitor();
method CreateAnalogStateMonitor (line 102) | IObservable<AnalogState> CreateAnalogStateMonitor(int channel);
method CreateDigitalStateMonitor (line 108) | IObservable<DigitalPortState> CreateDigitalStateMonitor();
method CreateDigitalStateMonitor (line 117) | IObservable<DigitalPortState> CreateDigitalStateMonitor(int port);
method SendStringData (line 123) | void SendStringData(string data);
method SetAnalogReportMode (line 135) | void SetAnalogReportMode(int channel, bool enable);
method SetDigitalPort (line 166) | void SetDigitalPort(int portNumber, int pins);
method SetDigitalReportMode (line 181) | void SetDigitalReportMode(int portNumber, bool enable);
method SetDigitalPinMode (line 188) | void SetDigitalPinMode(int pinNumber, PinMode mode);
method SetSamplingInterval (line 194) | void SetSamplingInterval(int milliseconds);
method SetDigitalPin (line 201) | void SetDigitalPin(int pinNumber, long value);
method SetDigitalPin (line 208) | void SetDigitalPin(int pinNumber, bool value);
method ResetBoard (line 213) | void ResetBoard();
method RequestProtocolVersion (line 223) | void RequestProtocolVersion();
method GetProtocolVersion (line 229) | ProtocolVersion GetProtocolVersion();
method GetProtocolVersionAsync (line 235) | Task<ProtocolVersion> GetProtocolVersionAsync();
method RequestFirmware (line 245) | void RequestFirmware();
method GetFirmware (line 251) | Firmware GetFirmware();
method GetFirmwareAsync (line 257) | Task<Firmware> GetFirmwareAsync();
method RequestBoardCapability (line 267) | void RequestBoardCapability();
method GetBoardCapability (line 273) | BoardCapability GetBoardCapability();
method GetBoardCapabilityAsync (line 279) | Task<BoardCapability> GetBoardCapabilityAsync();
method RequestBoardAnalogMapping (line 289) | void RequestBoardAnalogMapping();
method GetBoardAnalogMapping (line 295) | BoardAnalogMapping GetBoardAnalogMapping();
method GetBoardAnalogMappingAsync (line 301) | Task<BoardAnalogMapping> GetBoardAnalogMappingAsync();
method RequestPinState (line 312) | void RequestPinState(int pinNumber);
method GetPinState (line 319) | PinState GetPinState(int pinNumber);
method GetPinStateAsync (line 326) | Task<PinState> GetPinStateAsync(int pinNumber);
FILE: Solid.Arduino/Firmata/PinCapability.cs
class PinCapability (line 6) | public sealed class PinCapability
FILE: Solid.Arduino/Firmata/PinState.cs
class PinState (line 6) | public sealed class PinState
FILE: Solid.Arduino/Firmata/ProtocolVersion.cs
class ProtocolVersion (line 6) | public sealed class ProtocolVersion
FILE: Solid.Arduino/Firmata/Servo/IServoProtocol.cs
type IServoProtocol (line 10) | public interface IServoProtocol
method ConfigureServo (line 18) | void ConfigureServo(int pinNumber, int minPulse, int maxPulse);
FILE: Solid.Arduino/Firmata/StringData.cs
class StringData (line 6) | public sealed class StringData
FILE: Solid.Arduino/Firmata/SysExCommand.cs
type SysExCommand (line 6) | public enum SysExCommand: byte
FILE: Solid.Arduino/I2c/I2cEventArgs.cs
class I2CEventArgs (line 8) | public class I2CEventArgs : EventArgs
method I2CEventArgs (line 12) | internal I2CEventArgs(I2CReply value)
FILE: Solid.Arduino/I2c/I2cReply.cs
type I2CReply (line 6) | public struct I2CReply
FILE: Solid.Arduino/I2c/I2cReplyTracker.cs
class I2CReplyTracker (line 3) | internal class I2CReplyTracker : ObservableEventTracker<II2CProtocol, I2...
method I2CReplyTracker (line 5) | internal I2CReplyTracker(II2CProtocol ii2C): base(ii2C)
method Dispose (line 10) | public override void Dispose()
method I2CReplyReceived (line 19) | private void I2CReplyReceived(object parSender, I2CEventArgs parEventA...
FILE: Solid.Arduino/I2c/II2cProtocol.cs
type II2CProtocol (line 20) | public interface II2CProtocol
method CreateI2CReplyMonitor (line 37) | IObservable<I2CReply> CreateI2CReplyMonitor();
method SetI2CReadInterval (line 43) | void SetI2CReadInterval(int microseconds);
method WriteI2C (line 50) | void WriteI2C(int slaveAddress, params byte[] data);
method ReadI2COnce (line 62) | void ReadI2COnce(int slaveAddress, int bytesToRead);
method ReadI2COnce (line 70) | void ReadI2COnce(int slaveAddress, int slaveRegister, int bytesToRead);
method ReadI2CContinuous (line 86) | void ReadI2CContinuous(int slaveAddress, int bytesToRead);
method ReadI2CContinuous (line 94) | void ReadI2CContinuous(int slaveAddress, int slaveRegister, int bytesT...
method StopI2CReading (line 99) | void StopI2CReading();
method GetI2CReply (line 107) | I2CReply GetI2CReply(int slaveAddress, int bytesToRead);
method GetI2CReplyAsync (line 115) | Task<I2CReply> GetI2CReplyAsync(int slaveAddress, int bytesToRead);
method GetI2CReply (line 124) | I2CReply GetI2CReply(int slaveAddress, int slaveRegister, int bytesToR...
method GetI2CReplyAsync (line 133) | Task<I2CReply> GetI2CReplyAsync(int slaveAddress, int slaveRegister, i...
FILE: Solid.Arduino/ISerialConnection.cs
type ISerialConnection (line 10) | public interface ISerialConnection: IDisposable
method Open (line 45) | void Open();
method Close (line 50) | void Close();
method ReadByte (line 56) | int ReadByte();
method Write (line 62) | void Write(string text);
method Write (line 70) | void Write(byte[] buffer, int offset, int count);
method WriteLine (line 76) | void WriteLine(string text);
FILE: Solid.Arduino/IStringProtocol.cs
type IStringProtocol (line 17) | public interface IStringProtocol
method CreateReceivedStringMonitor (line 32) | IObservable<string> CreateReceivedStringMonitor();
method Write (line 43) | void Write(string value = null);
method WriteLine (line 49) | void WriteLine(string value = null);
method ReadLine (line 55) | string ReadLine();
method ReadLineAsync (line 61) | Task<string> ReadLineAsync();
method Read (line 68) | string Read(int length = 1);
method ReadAsync (line 75) | Task<string> ReadAsync(int length = 1);
method ReadTo (line 82) | string ReadTo(char terminator);
method ReadToAsync (line 89) | Task<string> ReadToAsync(char terminator);
FILE: Solid.Arduino/Messages.Designer.cs
class Messages (line 22) | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resource...
method Messages (line 31) | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Mic...
FILE: Solid.Arduino/ObservableEventTracker.cs
class ObservableEventTracker (line 6) | internal abstract class ObservableEventTracker<TSource, TTracked> : IObs...
method ObservableEventTracker (line 18) | internal ObservableEventTracker(TSource trackingSource)
method Subscribe (line 27) | public IDisposable Subscribe(IObserver<TTracked> observer)
method Dispose (line 33) | public virtual void Dispose()
FILE: Solid.Arduino/ReceivedStringTracker.cs
class ReceivedStringTracker (line 3) | internal class ReceivedStringTracker : ObservableEventTracker<IStringPro...
method ReceivedStringTracker (line 7) | internal ReceivedStringTracker(IStringProtocol source)
method Dispose (line 17) | public override void Dispose()
method TrackingSource_StringReceived (line 30) | void TrackingSource_StringReceived(object parSender, StringEventArgs p...
FILE: Solid.Arduino/SerialBaudRate.cs
type SerialBaudRate (line 6) | public enum SerialBaudRate
FILE: Solid.Arduino/SerialConnection.cs
class SerialConnection (line 16) | public class SerialConnection : SerialPort, ISerialConnection
method SerialConnection (line 40) | public SerialConnection()
method SerialConnection (line 52) | public SerialConnection(string portName, SerialBaudRate baudRate)
method Open (line 60) | public new void Open()
method Close (line 79) | public new void Close()
method Dispose (line 92) | public new void Dispose()
method Find (line 125) | public static ISerialConnection Find()
method Find (line 185) | public static ISerialConnection Find(string query, string expectedReply)
method GetHighestComPortName (line 204) | private static string GetHighestComPortName()
method FindConnection (line 209) | private static ISerialConnection FindConnection(Func<ArduinoSession, b...
FILE: Solid.Arduino/SerialPortFixer.cs
class SerialPortFixer (line 28) | internal static class SerialPortFixer
type Comstat (line 30) | [StructLayout(LayoutKind.Sequential)]
type Dcb (line 38) | [StructLayout(LayoutKind.Sequential)]
method FormatMessage (line 58) | [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = t...
method GetCommState (line 61) | [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = t...
method SetCommState (line 64) | [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = t...
method ClearCommError (line 67) | [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = t...
method CreateFile (line 70) | [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = t...
method GetFileType (line 73) | [DllImport("kernel32.dll", SetLastError = true)]
method Initialize (line 79) | public static void Initialize(string portName)
method MarshalCommState (line 110) | private static void MarshalCommState(SafeFileHandle handle, Func<bool>...
method ThrowIoException (line 128) | private static void ThrowIoException()
FILE: Solid.Arduino/StringEventArgs.cs
class StringEventArgs (line 8) | public class StringEventArgs
method StringEventArgs (line 12) | internal StringEventArgs(string text)
FILE: Solid.Arduino/StringExtensions.cs
class StringExtensions (line 9) | public static class StringExtensions
method ToBinaryCodedDecimal (line 20) | public static byte[] ToBinaryCodedDecimal(this string o, bool isLittle...
method To14BitIso (line 67) | public static byte[] To14BitIso(this string o)
FILE: docs/SearchHelp.inc.php
class Ranking (line 4) | class Ranking
method __construct (line 10) | function __construct($file, $title, $rank)
function ParseKeywords (line 24) | function ParseKeywords($keywords)
function Search (line 53) | function Search($keywords, $fileInfo, $wordDictionary, $sortByTitle)
function cmprank (line 163) | function cmprank($x, $y)
function cmprankbytitle (line 168) | function cmprankbytitle($x, $y)
FILE: docs/scripts/branding-Website.js
function InitializeToc (line 31) | function InitializeToc()
function SetNavHeight (line 38) | function SetNavHeight()
function OnIncreaseToc (line 50) | function OnIncreaseToc()
function OnResetToc (line 65) | function OnResetToc()
function ResizeToc (line 74) | function ResizeToc()
function Toggle (line 101) | function Toggle(item)
function HtmlEncode (line 137) | function HtmlEncode(value)
function BuildChildren (line 145) | function BuildChildren(tocDiv, data)
function Collapse (line 242) | function Collapse(tocDiv)
function Expand (line 263) | function Expand(tocDiv)
function OnMouseDown (line 300) | function OnMouseDown(event)
function OnMouseMove (line 308) | function OnMouseMove(event)
function OnMouseUp (line 316) | function OnMouseUp(event)
function TransferToSearchPage (line 327) | function TransferToSearchPage()
function OnSearchPageLoad (line 336) | function OnSearchPageLoad()
function PerformSearch (line 355) | function PerformSearch()
function DetermineSearchMethod (line 465) | function DetermineSearchMethod()
function ParseKeywords (line 502) | function ParseKeywords(keywords)
function SearchForKeywords (line 525) | function SearchForKeywords(keywords, fileInfo, wordDictionary, sortByTitle)
FILE: docs/scripts/branding.js
function OnLoad (line 52) | function OnLoad(defaultLanguage)
function InitializeToc (line 114) | function InitializeToc()
function UpdateLST (line 121) | function UpdateLST(language)
function GetCookie (line 205) | function GetCookie(cookieName, defaultValue)
function SetCookie (line 240) | function SetCookie(name, value)
function AddLanguageSpecificTextSet (line 268) | function AddLanguageSpecificTextSet(lstId)
function AddLanguageTabSet (line 278) | function AddLanguageTabSet(tabSetId)
function ChangeTab (line 320) | function ChangeTab(tabSetId, language, snippetIdx, snippetCount)
function SetCurrentLanguage (line 354) | function SetCurrentLanguage(tabSetId, language, tabCount)
function SetActiveTab (line 397) | function SetActiveTab(tabSetId, tabIndex, tabCount)
function CopyToClipboard (line 432) | function CopyToClipboard(tabSetId)
function SectionExpandCollapse (line 508) | function SectionExpandCollapse(togglePrefix)
function SectionExpandCollapse_CheckKey (line 527) | function SectionExpandCollapse_CheckKey(togglePrefix, eventArgs)
Condensed preview — 514 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (4,550K chars).
[
{
"path": ".gitattributes",
"chars": 2518,
"preview": "###############################################################################\n# Set default behavior to automatically "
},
{
"path": ".gitignore",
"chars": 2238,
"preview": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User"
},
{
"path": "Documentation/Documentation.shfbproj",
"chars": 8815,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/ms"
},
{
"path": "LICENSE.md",
"chars": 1333,
"preview": "####Copyright (c) 2013 - 2015, Henk van Boeijen <info@solidsoils.nl>\n\n#####All rights reserved.\n\nRedistribution and use "
},
{
"path": "README.md",
"chars": 6826,
"preview": "# SolidSoils4Arduino\n\nSolidSoils4Arduino is a client library built on .NET Standard 2.1. It offers an easy way to intera"
},
{
"path": "Solid.Arduino/ArduinoSession.cs",
"chars": 49728,
"preview": "using System;\nusing System.Collections.Concurrent;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing Sy"
},
{
"path": "Solid.Arduino/EnhancedSerialConnection.cs",
"chars": 2240,
"preview": "using System.IO.Ports;\nusing System.Linq;\n\nnamespace Solid.Arduino\n{\n /// <summary>\n /// Represents a serial port"
},
{
"path": "Solid.Arduino/EnhancedSerialPort.cs",
"chars": 6356,
"preview": "// /*\n// Copyright 2013 Antanas Veiverys antanas.veiverys.com\n//\n// Refactored 2014 by Henk van Boeijen.\n//\n// Licensed"
},
{
"path": "Solid.Arduino/Firmata/AnalogPinMapping.cs",
"chars": 501,
"preview": "namespace Solid.Arduino.Firmata\n{\n /// <summary>\n /// Represents a mapping between a MIDI channel and a physical "
},
{
"path": "Solid.Arduino/Firmata/AnalogState.cs",
"chars": 660,
"preview": "namespace Solid.Arduino.Firmata\n{\n /// <summary>\n /// Represents the analog level read from or set to an analog p"
},
{
"path": "Solid.Arduino/Firmata/AnalogStateTracker.cs",
"chars": 940,
"preview": "namespace Solid.Arduino.Firmata\n{\n internal class AnalogStateTracker : ObservableEventTracker<IFirmataProtocol, Anal"
},
{
"path": "Solid.Arduino/Firmata/BoardAnalogMapping.cs",
"chars": 403,
"preview": "namespace Solid.Arduino.Firmata\n{\n /// <summary>\n /// Represents a summary of mappings between MIDI channels and "
},
{
"path": "Solid.Arduino/Firmata/BoardCapability.cs",
"chars": 373,
"preview": "namespace Solid.Arduino.Firmata\n{\n /// <summary>\n /// Represents a summary of pinmode capabilities supported by a"
},
{
"path": "Solid.Arduino/Firmata/ByteArrayExtensions.cs",
"chars": 1940,
"preview": "using System;\n\nnamespace Solid.Arduino.Firmata\n{\n /// <summary>\n /// Provides extension methods for <see cref=\"by"
},
{
"path": "Solid.Arduino/Firmata/DigitalPortState.cs",
"chars": 992,
"preview": "using System;\n\nnamespace Solid.Arduino.Firmata\n{\n /// <summary>\n /// Represents the pin states of a digital port."
},
{
"path": "Solid.Arduino/Firmata/DigitalStateTracker.cs",
"chars": 936,
"preview": "namespace Solid.Arduino.Firmata\n{\n internal class DigitalStateTracker : ObservableEventTracker<IFirmataProtocol, Dig"
},
{
"path": "Solid.Arduino/Firmata/FirmataMessage.cs",
"chars": 2149,
"preview": "using System;\n\nnamespace Solid.Arduino.Firmata\n{\n /// <summary>\n /// Represents a Firmata message received from a"
},
{
"path": "Solid.Arduino/Firmata/FirmataMessageEventArgs.cs",
"chars": 584,
"preview": "using System;\n\nnamespace Solid.Arduino.Firmata\n{\n /// <summary>\n /// Event arguments passed to a <see cref=\"Messa"
},
{
"path": "Solid.Arduino/Firmata/FirmataMessageEventArgs_.cs",
"chars": 934,
"preview": "using System;\n\nnamespace Solid.Arduino.Firmata\n{\n /// <summary>\n /// Contains event data for a <see cref=\"AnalogS"
},
{
"path": "Solid.Arduino/Firmata/Firmware.cs",
"chars": 602,
"preview": "namespace Solid.Arduino.Firmata\n{\n /// <summary>\n /// Identifies the Arduino board's firmware.\n /// </summary>"
},
{
"path": "Solid.Arduino/Firmata/IFirmataProtocol.cs",
"chars": 14646,
"preview": "using System;\nusing System.Threading.Tasks;\n\nnamespace Solid.Arduino.Firmata\n{\n /// <summary>\n /// Signature of e"
},
{
"path": "Solid.Arduino/Firmata/PinCapability.cs",
"chars": 2813,
"preview": "namespace Solid.Arduino.Firmata\n{\n /// <summary>\n /// Contains information about the capabilities of a pin.\n /"
},
{
"path": "Solid.Arduino/Firmata/PinState.cs",
"chars": 757,
"preview": "namespace Solid.Arduino.Firmata\n{\n /// <summary>\n /// Contains information about a pin's state.\n /// </summary"
},
{
"path": "Solid.Arduino/Firmata/ProtocolVersion.cs",
"chars": 460,
"preview": "namespace Solid.Arduino.Firmata\n{\n /// <summary>\n /// Represents the Firmata communication protocol version.\n "
},
{
"path": "Solid.Arduino/Firmata/Servo/IServoProtocol.cs",
"chars": 767,
"preview": "namespace Solid.Arduino.Firmata.Servo\n{\n /// <summary>\n /// Defines Servo control related members of the Firmata "
},
{
"path": "Solid.Arduino/Firmata/StringData.cs",
"chars": 326,
"preview": "namespace Solid.Arduino.Firmata\n{\n /// <summary>\n /// Represents a string exchanged with the Firmata SYSEX STRING"
},
{
"path": "Solid.Arduino/Firmata/SysExCommand.cs",
"chars": 3323,
"preview": "namespace Solid.Arduino.Firmata\n{\n /// <summary>\n /// SysEx message command bytes\n /// </summary>\n public e"
},
{
"path": "Solid.Arduino/I2c/I2cEventArgs.cs",
"chars": 504,
"preview": "using System;\n\nnamespace Solid.Arduino.I2C\n{\n /// <summary>\n /// Event arguments passed to a <see cref=\"I2CReplyR"
},
{
"path": "Solid.Arduino/I2c/I2cReply.cs",
"chars": 540,
"preview": "namespace Solid.Arduino.I2C\n{\n /// <summary>\n /// Container for an I2C message\n /// </summary>\n public stru"
},
{
"path": "Solid.Arduino/I2c/I2cReplyTracker.cs",
"chars": 666,
"preview": "namespace Solid.Arduino.I2C\n{\n internal class I2CReplyTracker : ObservableEventTracker<II2CProtocol, I2CReply>\n {"
},
{
"path": "Solid.Arduino/I2c/II2cProtocol.cs",
"chars": 7138,
"preview": "using System;\nusing System.Threading.Tasks;\nusing Solid.Arduino.Firmata;\n\nnamespace Solid.Arduino.I2C\n{\n /// <summar"
},
{
"path": "Solid.Arduino/ISerialConnection.cs",
"chars": 2782,
"preview": "using System;\nusing System.IO.Ports;\n\nnamespace Solid.Arduino\n{\n /// <summary>\n /// Defines a serial port connect"
},
{
"path": "Solid.Arduino/IStringProtocol.cs",
"chars": 3743,
"preview": "using System;\nusing System.IO.Ports;\nusing System.Threading.Tasks;\n\nnamespace Solid.Arduino\n{\n /// <summary>\n ///"
},
{
"path": "Solid.Arduino/Messages.Designer.cs",
"chars": 11705,
"preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n// This code w"
},
{
"path": "Solid.Arduino/Messages.resx",
"chars": 9114,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n <!-- \n Microsoft ResX Schema \n \n Version 2.0\n \n The prim"
},
{
"path": "Solid.Arduino/ObservableEventTracker.cs",
"chars": 1133,
"preview": "using System;\nusing System.Collections.Generic;\n\nnamespace Solid.Arduino\n{\n internal abstract class ObservableEventT"
},
{
"path": "Solid.Arduino/ReceivedStringTracker.cs",
"chars": 879,
"preview": "namespace Solid.Arduino\n{\n internal class ReceivedStringTracker : ObservableEventTracker<IStringProtocol, string>\n "
},
{
"path": "Solid.Arduino/SerialBaudRate.cs",
"chars": 513,
"preview": "namespace Solid.Arduino\n{\n /// <summary>\n /// Enumeration of common baud rates, supported by Arduino boards\n //"
},
{
"path": "Solid.Arduino/SerialConnection.cs",
"chars": 9465,
"preview": "using System;\nusing System.Diagnostics;\nusing System.IO;\nusing System.IO.Ports;\nusing System.Linq;\nusing System.Threadi"
},
{
"path": "Solid.Arduino/SerialPortFixer.cs",
"chars": 5558,
"preview": "// Copyright 2010-2014 Zach Saw\n// Refactored 2017 Henk van Boeijen\n// \n// Licensed under the Apache License, Version 2"
},
{
"path": "Solid.Arduino/Solid.Arduino.csproj",
"chars": 2650,
"preview": "<Project Sdk=\"Microsoft.NET.Sdk\">\n <PropertyGroup>\n <TargetFramework>netstandard2.1</TargetFramework>\n <PackageI"
},
{
"path": "Solid.Arduino/Solid.Arduino.xml",
"chars": 88747,
"preview": "<?xml version=\"1.0\"?>\n<doc>\n <assembly>\n <name>Solid.Arduino</name>\n </assembly>\n <members>\n <mem"
},
{
"path": "Solid.Arduino/StringEventArgs.cs",
"chars": 556,
"preview": "namespace Solid.Arduino\n{\n /// <summary>\n /// Event arguments passed to a <see cref=\"StringReceivedHandler\"/> typ"
},
{
"path": "Solid.Arduino/StringExtensions.cs",
"chars": 3076,
"preview": "using System;\nusing System.Linq;\n\nnamespace Solid.Arduino\n{\n /// <summary>\n /// Provides extension methods for <s"
},
{
"path": "Solid.Arduino.IntegrationTest/HC06-Bluetooth.ino",
"chars": 2140,
"preview": "/*\n\tThe HC-06 is a slave-only Bluetooth module.\n\tIt can only be programmed through its serial connection.\n\tThis sketch "
},
{
"path": "Solid.Arduino.IntegrationTest/SerialConnectionTester.cs",
"chars": 1664,
"preview": "using System.IO.Ports;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\n\nnamespace Solid.Arduino.IntegrationTest\n{\n "
},
{
"path": "Solid.Arduino.IntegrationTest/SerialReply.ino",
"chars": 646,
"preview": "/*\n This example is intended to demonstrate the SolidSoils4Arduino library's\n SerialConnection.FindSerialConnection"
},
{
"path": "Solid.Arduino.IntegrationTest/SocketConnectionTester.cs",
"chars": 2076,
"preview": "using System.Net;\nusing System.Net.Sockets;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\n\nnamespace Solid.Arduin"
},
{
"path": "Solid.Arduino.IntegrationTest/Solid.Arduino.IntegrationTest.csproj",
"chars": 598,
"preview": "<Project Sdk=\"Microsoft.NET.Sdk\">\n <PropertyGroup>\n <TargetFramework>netcoreapp3.1</TargetFramework>\n <IsPackabl"
},
{
"path": "Solid.Arduino.Run/Program.cs",
"chars": 9134,
"preview": "using System;\nusing System.Threading;\n\nusing Solid.Arduino.Firmata;\nusing Solid.Arduino.I2C;\nusing System.Linq;\n\nnamesp"
},
{
"path": "Solid.Arduino.Run/Solid.Arduino.Run.csproj",
"chars": 272,
"preview": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n <PropertyGroup>\n <TargetFramework>netcoreapp3.1</TargetFramework>\n <OutputTy"
},
{
"path": "Solid.Arduino.Test/ArduinoSessionTester.cs",
"chars": 2924,
"preview": "using System;\nusing System.Collections.Generic;\n\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\n\nusing Solid.Ardui"
},
{
"path": "Solid.Arduino.Test/ByteArrayExtensionsTester.cs",
"chars": 3828,
"preview": "using System;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\nusing Solid.Arduino.Firmata;\n\nnamespace Solid.Arduino"
},
{
"path": "Solid.Arduino.Test/DigitalPortStateTester.cs",
"chars": 3309,
"preview": "using System;\n\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\nusing Solid.Arduino.Firmata;\n\nnamespace Solid.Arduin"
},
{
"path": "Solid.Arduino.Test/EnhancedSerialConnectionTester.cs",
"chars": 1958,
"preview": "using System;\nusing System.IO.Ports;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\n\nnamespace Solid.Arduino.Test\n"
},
{
"path": "Solid.Arduino.Test/ExceptionMonitor.cs",
"chars": 1026,
"preview": "using System;\nusing System.Runtime.ExceptionServices;\nusing System.Reflection;\n\nnamespace Solid.Arduino.Test\n{\n clas"
},
{
"path": "Solid.Arduino.Test/I2cProtocolTester.cs",
"chars": 13775,
"preview": "using System;\nusing System.Collections.Generic;\n\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\n\nusing Solid.Ardui"
},
{
"path": "Solid.Arduino.Test/IFirmataProtocolTester.cs",
"chars": 39454,
"preview": "using System;\nusing System.Collections.Generic;\n\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\n\nusing Solid.Ardui"
},
{
"path": "Solid.Arduino.Test/IServoProtocolTester.cs",
"chars": 4525,
"preview": "using System;\nusing System.Collections.Generic;\n\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\n\nusing Solid.Ardui"
},
{
"path": "Solid.Arduino.Test/IStringProtocolTester.cs",
"chars": 13937,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.V"
},
{
"path": "Solid.Arduino.Test/MockSerialConnection.cs",
"chars": 7877,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.IO.Ports;\nusing System.Reflection;\nusing System.Text;\nusin"
},
{
"path": "Solid.Arduino.Test/ObservableArduinoSessionTester.cs",
"chars": 376,
"preview": "using Microsoft.VisualStudio.TestTools.UnitTesting;\n\nnamespace Solid.Arduino.Test\n{\n [TestClass]\n public class Ob"
},
{
"path": "Solid.Arduino.Test/SerialConnectionTester.cs",
"chars": 1817,
"preview": "using System;\nusing System.IO.Ports;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\n\nnamespace Solid.Arduino.Test\n"
},
{
"path": "Solid.Arduino.Test/Solid.Arduino.Test.csproj",
"chars": 591,
"preview": "<Project Sdk=\"Microsoft.NET.Sdk\">\n <PropertyGroup>\n <TargetFramework>netcoreapp3.1</TargetFramework>\n <IsPackabl"
},
{
"path": "Solid.Arduino.Test/StringExtensionsTester.cs",
"chars": 3602,
"preview": "using System;\n\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\n\nnamespace Solid.Arduino.Test\n{\n [TestClass]\n "
},
{
"path": "Solid.Arduino.sln",
"chars": 3316,
"preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 16\nVisualStudioVersion = 16.0.3001"
},
{
"path": "_config.yml",
"chars": 27,
"preview": "theme: jekyll-theme-minimal"
},
{
"path": "docs/SearchHelp.aspx",
"chars": 8075,
"preview": "<%@ Page Language=\"C#\" EnableViewState=\"False\" %>\n\n<script runat=\"server\">\n//=========================================="
},
{
"path": "docs/SearchHelp.inc.php",
"chars": 4444,
"preview": "<?\n// Contributed to the Sandcastle Help File Builder project by Thomas Levesque\n\nclass Ranking\n{\n public $filename;"
},
{
"path": "docs/SearchHelp.php",
"chars": 1509,
"preview": "<?\n// Contributed to the Sandcastle Help File Builder project by Thomas Levesque\n\ninclude(\"SearchHelp.inc.php\");\n\n $"
},
{
"path": "docs/Solid.Arduino.xml",
"chars": 153982,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<doc>\n <assembly>\n <name>Solid.Arduino</name>\n </assembly>\n <members>\n "
},
{
"path": "docs/Web.Config",
"chars": 1283,
"preview": "<?xml version=\"1.0\"?>\n<configuration xmlns=\"http://schemas.microsoft.com/.NetConfiguration/v2.0\">\n\t<system.web>\n\t\t<custo"
},
{
"path": "docs/WebKI.xml",
"chars": 61120,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<HelpKI>\n <HelpKINode Title=\"Address property\" Url=\"html/7a82d399-3fe1-048e-ecb"
},
{
"path": "docs/WebTOC.xml",
"chars": 38596,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<HelpTOC>\n\n <HelpTOCNode Id=\"233f1feb-2c43-4a48-a104-8a3d32dbbc13\" Title=\"Solid"
},
{
"path": "docs/fti/FTI_100.json",
"chars": 6148,
"preview": "{\"dispose\":[2752516,4259841,8323076,9502721,15335425,19791873],\"digitalstatereceived\":[589825,3473409,3866625,11010051,1"
},
{
"path": "docs/fti/FTI_101.json",
"chars": 1522,
"preview": "{\"enhancedserialconnection\":[3997700,4194310,4325377,5832713,5898245,7798787,8650753,10092546,11927559,13107202,15204356"
},
{
"path": "docs/fti/FTI_102.json",
"chars": 1994,
"preview": "{\"firmatamessageeventargs\":[4784131,4980738,10158083,12713985,13041669],\"firmataeventargs\":[10616834,11206658,12189699,1"
},
{
"path": "docs/fti/FTI_103.json",
"chars": 1024,
"preview": "{\"getprotocolversion\":[327684,3473409,7274501,9502721,15073281,19791873],\"getprotocolversionasync\":[3473409,6684676,9502"
},
{
"path": "docs/fti/FTI_104.json",
"chars": 2673,
"preview": "{\"henk\":[131073,196609,262145,327681,458753,393217,524289,589825,655361,720897,786433,851969,917505,983041,1048577,11141"
},
{
"path": "docs/fti/FTI_105.json",
"chars": 6605,
"preview": "{\"isopen\":[5636097,9175043,10485761],\"isset\":[1572865,13369345,15597573],\"int32\":[262156,851974,917505,983041,1048577,12"
},
{
"path": "docs/fti/FTI_108.json",
"chars": 2993,
"preview": "{\"long\":[851969,6291457,6356993,8060929],\"list\":[1245185,1703937,3080193,3342337,4194305,4587521,9109505,10092545,113377"
},
{
"path": "docs/fti/FTI_109.json",
"chars": 4736,
"preview": "{\"minpulse\":[14680067,18350083],\"members\":[589825,655361,1507329,1572865,1900545,2097153,2162689,2359297,3145729,3276801"
},
{
"path": "docs/fti/FTI_110.json",
"chars": 5446,
"preview": "{\"new\":[1441793,3604481,3735553,4194306,5832706,5898241,7733249,8650759,9109511,9437185,10420225,11337730,11927553,12255"
},
{
"path": "docs/fti/FTI_111.json",
"chars": 1154,
"preview": "{\"overload\":[196609,262145,851969,1245185,1376257,1441793,1703937,2621441,3080193,3342337,3604481,3735553,3932161,399769"
},
{
"path": "docs/fti/FTI_112.json",
"chars": 10189,
"preview": "{\"pinstate\":[2031619,6356995,9568259,9764866,11599875,12517378,12713985,14352386,14548994,18546692],\"property\":[131074,7"
},
{
"path": "docs/fti/FTI_113.json",
"chars": 29,
"preview": "{\"query\":[18677763,19922947]}"
},
{
"path": "docs/fti/FTI_114.json",
"chars": 4870,
"preview": "{\"readbyte\":[1507329,4259841,5636097,5832705,7798785,10682372,12779525,15335425,16711685],\"readtoasync\":[4653057,8978433"
},
{
"path": "docs/fti/FTI_115.json",
"chars": 23634,
"preview": "{\"send\":[131073,196609,262145,327681,458753,393217,524289,589825,655361,720897,786433,851969,917505,983041,1048577,11141"
},
{
"path": "docs/fti/FTI_116.json",
"chars": 6054,
"preview": "{\"to14bitiso\":[3801089,14024705,16777221],\"top\":[589825,655361,1245185,1507329,1572865,1703937,1900545,2097153,2162689,3"
},
{
"path": "docs/fti/FTI_117.json",
"chars": 75,
"preview": "{\"url\":[19202049],\"undefined\":[8912897],\"usage\":[720897,16777217,19267585]}"
},
{
"path": "docs/fti/FTI_118.json",
"chars": 6498,
"preview": "{\"visual\":[720898,16777218,19267586],\"van\":[131073,196609,262145,327681,458753,393217,524289,589825,655361,720897,786433"
},
{
"path": "docs/fti/FTI_119.json",
"chars": 410,
"preview": "{\"write\":[262151,1507330,4259842,4653057,5636098,5832706,7667716,7798786,8978433,9502721,10092547,11075589,13959174,1533"
},
{
"path": "docs/fti/FTI_97.json",
"chars": 5829,
"preview": "{\"assembly\":[131073,196609,262145,327681,393217,458753,524289,655361,720897,786433,851969,917505,983041,1048577,1114113,"
},
{
"path": "docs/fti/FTI_98.json",
"chars": 4031,
"preview": "{\"bps_300\":[10551297],\"bps_600\":[10551297],\"boardanalogmapping\":[458754,1310722,1900547,2424835,12713985,13303812,141557"
},
{
"path": "docs/fti/FTI_99.json",
"chars": 12412,
"preview": "{\"comments\":[131073,196609,262145,327681,458753,393217,524289,589825,655361,720897,786433,851969,917505,983041,1048577,1"
},
{
"path": "docs/fti/FTI_Files.json",
"chars": 30018,
"preview": "[\"Solid Soils .NET Library for Arduino Serial Port Communication - Redirect\\u0000index.html\\u000018\",\"Solid Soils .NET L"
},
{
"path": "docs/html/0010e8c6-eb36-7d91-486f-57a208faeca8.htm",
"chars": 9188,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/002fd01e-b970-b699-d1ab-402342ab2dec.htm",
"chars": 10680,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/00b485cd-b70e-e463-f9aa-ba11cee21ff7.htm",
"chars": 11511,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/00e5bd9e-f9ab-5194-8375-b9fbf1f0161e.htm",
"chars": 9087,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/012dd994-5a18-29df-21ef-6f6e228030c9.htm",
"chars": 19462,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/01aaeb2a-fd21-bbd7-2dc2-9e6597c264d4.htm",
"chars": 14267,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/03dc5f50-ca95-43b1-418c-d8465fb55383.htm",
"chars": 14229,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/04428aca-6102-c5fd-3222-18c2e545b0e8.htm",
"chars": 19371,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/0456bfc8-b008-c8a3-77ad-0bfefc1310cb.htm",
"chars": 8118,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/05b14b65-ca9d-7ff2-68b7-f70d7cfcc100.htm",
"chars": 7682,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/05b5327f-d814-405f-e2bd-e56a351a861e.htm",
"chars": 10942,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/07dc3d59-f60a-0e42-9042-3bb4ac8f9137.htm",
"chars": 9869,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/08af42a6-bb1e-b13e-b90d-ac47e8583dd9.htm",
"chars": 11511,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/0cace141-f273-7ad7-d632-31e0ff0815fb.htm",
"chars": 11526,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/0cc5ebbb-9d0b-0d4e-0b8a-59b7c490f7bd.htm",
"chars": 13985,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/0cd4e1e3-e5af-40f1-dc97-f2f08fb64119.htm",
"chars": 9027,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/0ce955e9-de04-3300-073d-2932518e0070.htm",
"chars": 8313,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/0db70497-3543-ccc9-2141-40d1fd170c64.htm",
"chars": 19501,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/0e0528df-22b4-60f2-8cc6-9c7e3d140d01.htm",
"chars": 14578,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/0ea9cbae-1535-ba11-3134-4520d69334f0.htm",
"chars": 7831,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/0eb18a1c-9837-d7d9-6e0d-f201303effe6.htm",
"chars": 9965,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/0f03b0e7-a914-e46b-c2d6-e0bed40eac37.htm",
"chars": 6752,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/10dde3c8-66dc-d300-0d82-de410352094d.htm",
"chars": 9006,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/11348d42-72bd-635f-c392-da90b6c27daa.htm",
"chars": 7747,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/119049c4-1ba0-964e-94c7-cfc08e55a37a.htm",
"chars": 11586,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/12415ea1-5b04-0b26-d464-d851efbbce73.htm",
"chars": 9601,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/1251dc84-c748-62a3-d876-c92c0cab97c6.htm",
"chars": 8414,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/1685f037-3a5d-6004-7e2c-c72f2c403fed.htm",
"chars": 6932,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/17a49847-9f5e-41b4-a84a-1bb15979af70.htm",
"chars": 6823,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/17eed47b-8bf5-ea44-13cd-722e37bb68c9.htm",
"chars": 11491,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/183523fa-f6c5-0635-d6ba-336781e21c95.htm",
"chars": 9327,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/1a181c03-5d41-d3a2-e280-049cad8d349a.htm",
"chars": 8352,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/1c02d293-4876-a918-1b8e-c84637cd0860.htm",
"chars": 8329,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/1c2dd961-3134-4b2a-ab4d-c8025ab4cfe1.htm",
"chars": 13895,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/1cd0d237-552e-0958-a3ef-7dec5153ffa3.htm",
"chars": 8403,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/1e2164e0-907c-a688-2f86-07d7ba8e85ae.htm",
"chars": 15891,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/1f020e05-4452-f270-4785-162fd272270d.htm",
"chars": 9672,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/1fa615e5-a5c8-2d2c-fa47-0e38434c27c8.htm",
"chars": 19960,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/209690c4-2404-13af-d697-d0889345d94e.htm",
"chars": 19737,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/21bb8dd6-fb5d-9c2d-ffca-f536c5533d6a.htm",
"chars": 9910,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/2387accb-7f3f-aff7-0482-b5a6bc2fdaee.htm",
"chars": 8517,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/2396779a-20f5-49b8-2a1b-ad7d188cde76.htm",
"chars": 20406,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/23a2c9b4-3a0c-9075-c87f-a4fc4d89c978.htm",
"chars": 14594,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/24763d00-2f5b-09be-8ace-29f24895ed1b.htm",
"chars": 9718,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/25858b6c-f545-022f-1421-1980e7d2f9ec.htm",
"chars": 8561,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/26b1753d-4f47-ecdb-98fb-1c150eb3ca88.htm",
"chars": 19386,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/280d4128-f443-8cf2-6a53-33e6e7eb5e4e.htm",
"chars": 7206,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/29676853-5f19-d961-917d-d2a3b1005bc2.htm",
"chars": 8084,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/2bd00801-6ea4-9aeb-869f-6be672f4b934.htm",
"chars": 8935,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/2c665003-8e12-9549-f318-997e33c1766b.htm",
"chars": 8160,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/2cf2e931-e0e8-d47d-aaa6-73cc82ef2e55.htm",
"chars": 7990,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/2e643178-1fcf-6971-d9c1-921734b7c710.htm",
"chars": 15796,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/2f361478-0a2b-cf8c-c0b5-c347820086fe.htm",
"chars": 6713,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/30b16045-d369-9612-cb2a-2f396b746a9d.htm",
"chars": 9890,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/3198d1e7-848f-41e3-6b13-1e23f6eaaadd.htm",
"chars": 8349,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/32c1b709-03cf-fa67-24d3-12552bab13dd.htm",
"chars": 8494,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/335a34f6-a012-4732-1fea-87527cebbecd.htm",
"chars": 12200,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/3370b8dd-d792-b2c8-df67-f542ff674ba9.htm",
"chars": 9889,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/34435006-8185-e827-453f-bcf4043b59e3.htm",
"chars": 9272,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/35350d0e-6fa0-0a27-7b7d-57a59840cdea.htm",
"chars": 8507,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/35d22925-210f-956e-92b6-12c95fedddaa.htm",
"chars": 8062,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/3695c805-d9b7-b3e6-32be-183a64f8873a.htm",
"chars": 8742,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/36b30020-3a33-da99-478f-3806990dcf90.htm",
"chars": 9981,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/36d82773-9fd2-223a-44bd-acbc25407dda.htm",
"chars": 9521,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/36e366e7-eeb4-cfe5-dc07-3978cb22ce94.htm",
"chars": 9682,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/3840dfdb-97e9-882b-796e-9ad6e28ea2a1.htm",
"chars": 18625,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/3a2ac349-bf62-313a-9f20-4c7c3932b60a.htm",
"chars": 11819,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/3a4802af-ada6-81eb-0d1a-ca7c114653cf.htm",
"chars": 8337,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/3a711afe-a630-a052-9ad9-87bd4345613b.htm",
"chars": 7833,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/3bcf8a5b-b062-5af3-2db8-15cf583f2f31.htm",
"chars": 14675,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/3cfbfb3e-5b55-59d8-2a64-d298cca31bde.htm",
"chars": 13525,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/3d0a9909-c581-51c4-1343-950e2653b152.htm",
"chars": 6710,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/3d50005b-be1d-3245-76c1-a4e60bcd5c18.htm",
"chars": 9268,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/3e9fb5e9-92dc-8797-9059-3f3a27da6673.htm",
"chars": 8111,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/3eeb99eb-b6d7-85a1-0001-29f3c220b63a.htm",
"chars": 8454,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/3f24f883-ede8-64a4-fdd9-f73ddadc6c6c.htm",
"chars": 8419,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/407075b2-2a77-655b-0bb4-fb45ded42876.htm",
"chars": 10211,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/40d05494-2f3b-10bd-1fdb-485097690ee9.htm",
"chars": 7559,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/42b47bc8-9e23-e9db-a8db-1972173530f1.htm",
"chars": 8317,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/43733aea-c265-b3e4-c53b-17a82b3360b0.htm",
"chars": 20078,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/43e2abd9-863a-2f7e-aabc-f0c145bb4d29.htm",
"chars": 10589,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/449f192e-e39e-4f35-d4bd-fd8fd14ef6ad.htm",
"chars": 6789,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/4622e83d-5f7a-6c28-8838-b7bda56a96fd.htm",
"chars": 8271,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/473706ce-6549-acda-7330-ee8597293463.htm",
"chars": 12352,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/48a1f3a8-4ebd-f887-9042-461476ec06e1.htm",
"chars": 15678,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/4a772778-1995-b7b1-fec3-19dda6d127f9.htm",
"chars": 10393,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/4b09c588-2b2a-300c-db9d-4567209dba1d.htm",
"chars": 9664,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/4b854918-3dfc-0e52-8333-edc9d7d419fb.htm",
"chars": 6741,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/4be8895c-9e74-2785-cce2-fc78782aa936.htm",
"chars": 8741,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/4c9c15c4-eda9-59d4-8a15-8d789489f0aa.htm",
"chars": 10447,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/4ec15f56-5d16-3f8b-7f74-a535d3698537.htm",
"chars": 7838,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/4fc6a36d-12cb-113e-4379-c04f55226882.htm",
"chars": 19133,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/505b8bcb-2c04-8a59-85ee-f86d7a81133c.htm",
"chars": 5789,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/50af8943-91c9-96fc-307d-423c066c5933.htm",
"chars": 8423,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/51289ed1-279a-240e-f276-9147c12f6217.htm",
"chars": 8409,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/524203d1-c389-0f63-fa4a-616459b7b0e2.htm",
"chars": 10737,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/52906872-565e-78c6-6f2c-cfd646f7e3d4.htm",
"chars": 10346,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/542fd7a2-0004-6425-e123-87277c6662cc.htm",
"chars": 9666,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/5560f824-7c26-030f-a351-7a43f48d3616.htm",
"chars": 9605,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/55aa38a0-1f7a-ec22-10d8-8bae26960810.htm",
"chars": 19902,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/55c86eb1-5578-8ae0-dd84-5582fa070efe.htm",
"chars": 6728,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/569db704-90d1-483e-ace7-0ccba57549c5.htm",
"chars": 10609,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/56d39bd9-c75f-545e-3b10-d8bc999931d1.htm",
"chars": 14759,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
},
{
"path": "docs/html/580f8ee8-6e40-6d26-8290-6b7b75def84f.htm",
"chars": 19995,
"preview": "<html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" /><link rel=\"shortcut icon\" href=\"../icons/favicon.ico"
}
]
// ... and 314 more files (download for full content)
About this extraction
This page contains the full source code of the SolidSoils/Arduino GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 514 files (4.1 MB), approximately 1.1M tokens, and a symbol index with 506 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.