{"id":15197072,"url":"https://github.com/unosquare/raspberryio","last_synced_at":"2025-10-02T13:30:51.966Z","repository":{"id":52416992,"uuid":"74280949","full_name":"unosquare/raspberryio","owner":"unosquare","description":"The Raspberry Pi's IO Functionality in an easy-to-use API for Mono/.NET/C#","archived":true,"fork":false,"pushed_at":"2022-08-09T19:58:57.000Z","size":10274,"stargazers_count":676,"open_issues_count":0,"forks_count":105,"subscribers_count":47,"default_branch":"master","last_synced_at":"2025-08-31T13:29:01.161Z","etag":null,"topics":["camera","captured-images","dotnet","dotnetcore","gpio-pins","i2c-bus","mono","peripherals","raspberry","raspberry-pi","raspberry-pi-3","raspberry-pi-camera","raspberry-pi-gpio","resistor","scl","sda","spi-channel"],"latest_commit_sha":null,"homepage":"https://unosquare.github.io/raspberryio","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/unosquare.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-11-20T14:47:41.000Z","updated_at":"2025-05-13T15:49:12.000Z","dependencies_parsed_at":"2022-09-03T07:40:14.804Z","dependency_job_id":null,"html_url":"https://github.com/unosquare/raspberryio","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/unosquare/raspberryio","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unosquare%2Fraspberryio","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unosquare%2Fraspberryio/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unosquare%2Fraspberryio/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unosquare%2Fraspberryio/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/unosquare","download_url":"https://codeload.github.com/unosquare/raspberryio/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unosquare%2Fraspberryio/sbom","scorecard":{"id":910817,"data":{"date":"2025-08-11","repo":{"name":"github.com/unosquare/raspberryio","commit":"47db45e6e4956be7b1b64d89aa3cff0e4897df90"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.9,"checks":[{"name":"Code-Review","score":6,"reason":"Found 10/16 approved changesets -- score normalized to 6","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"project is archived","details":["Warn: Repository is archived."],"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/codeql-analysis.yml:1","Warn: no topLevel permission defined: .github/workflows/netcore.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/unosquare/raspberryio/codeql-analysis.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:41: update your workflow using https://app.stepsecurity.io/secureworkflow/unosquare/raspberryio/codeql-analysis.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:52: update your workflow using https://app.stepsecurity.io/secureworkflow/unosquare/raspberryio/codeql-analysis.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:66: update your workflow using https://app.stepsecurity.io/secureworkflow/unosquare/raspberryio/codeql-analysis.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/netcore.yml:11: update your workflow using https://app.stepsecurity.io/secureworkflow/unosquare/raspberryio/netcore.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/netcore.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/unosquare/raspberryio/netcore.yml/master?enable=pin","Info:   0 out of   6 GitHub-owned GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":9,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"SAST","score":7,"reason":"SAST tool detected but not run on all commits","details":["Info: SAST configuration detected: CodeQL","Warn: 0 commits out of 24 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}}]},"last_synced_at":"2025-08-24T19:05:16.313Z","repository_id":52416992,"created_at":"2025-08-24T19:05:16.313Z","updated_at":"2025-08-24T19:05:16.313Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":277311255,"owners_count":25796890,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-27T02:00:08.978Z","response_time":73,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["camera","captured-images","dotnet","dotnetcore","gpio-pins","i2c-bus","mono","peripherals","raspberry","raspberry-pi","raspberry-pi-3","raspberry-pi-camera","raspberry-pi-gpio","resistor","scl","sda","spi-channel"],"created_at":"2024-09-28T00:41:00.411Z","updated_at":"2025-10-02T13:30:51.400Z","avatar_url":"https://github.com/unosquare.png","language":"C#","readme":"** THIS REPO HAS BEEN ARCHIVED **\n\n[![NuGet](https://img.shields.io/nuget/dt/Unosquare.Raspberry.IO.svg)](https://www.nuget.org/packages/Unosquare.Raspberry.IO)\n[![Analytics](https://ga-beacon.appspot.com/UA-8535255-2/unosquare/raspberryio/)](https://github.com/igrigorik/ga-beacon)\n[![Build status](https://ci.appveyor.com/api/projects/status/ufr4k5y96phtafqj/branch/master?svg=true)](https://ci.appveyor.com/project/geoperez/raspberryio/branch/master)\n[![Build Status](https://travis-ci.org/unosquare/raspberryio.svg?branch=master)](https://travis-ci.org/unosquare/raspberryio)\n\n# \u003cimg src=\"https://github.com/unosquare/raspberryio/raw/master/logos/raspberryio-logo-32.png\"\u003e\u003c/img\u003e RaspberryIO - *Pi's hardware access from .NET*\n\n**WE ARE LOOKING FOR A NEW HOME FOR THIS PROJECT. APPLY AT:** https://adoptoposs.org/p/9f5b74b9-04f2-42b6-891f-c5294c9ef1c5\n\n:star: *Please star this project if you find it useful!*\n\nThe Raspberry Pi's IO Functionality in an easy-to-use API for .NET (Mono/.NET Core). Our mission is to make .NET a first-class citizen in the Python-centric community of Raspberry Pi developers.\n\n Table of contents\n=================\n  * [Features](#features)\n    * [Peripherals](#peripherals)\n  * [Breaking changes](#breaking-changes)\n    * [Version \u0026ge; 0.18.0](#version--0180)\n  * [Installation](#installation)\n  * [Running the latest version of Mono](#running-the-latest-version-of-mono)\n    * [For Debian Stretch](#for-debian-stretch)\n  * [Running .NET Core 3.1](#running-net-core-31)\n  * [Usage](#usage)\n    * [Run the app on the raspberry](#run-the-app-on-the-raspberry)\n  * [Obtaining Board and System Information](#obtaining-board-and-system-information)\n  * [Using the GPIO Pins](#using-the-gpio-pins)\n    * [Pin Information](#pin-information)\n    * [Digital Read and Write](#digital-read-and-write)\n    * [Hardware PWM](#hardware-pwm)\n    * [Software PWM](#software-pwm)\n    * [Tone Generation](#tone-generation)\n    * [Interrupts and Callbacks](#interrupts-and-callbacks)\n  * [Using the SPI Bus](#using-the-spi-bus)\n  * [I2C to connect ICs](#i2c-to-connect-ics)\n  * [Timing and Threading](#timing-and-threading)\n    * [Timing](#timing)\n    * [Threading](#threading)\n  * [Serial Ports (UART)](#serial-ports-uart)\n  * [The Camera Module](#the-camera-module)\n    * [Capturing Images](#capturing-images)\n    * [Capturing Video](#capturing-video)\n  * [Audio settings](#audio-settings)\n  * [Handy Notes](#handy-notes)\n  * [Related Projects and Nugets](#related-projects-and-nugets)\n  \n## Features\n\nThis library enables developers to use the various Raspberry Pi's hardware modules:\n\n* ```Pi.Camera``` Provides access to the official Raspberry Pi Camera module.\n* ```Pi.Info``` Provides information on this Raspberry Pi's CPU and form factor.\n* ```Pi.Gpio``` Provides access to the Raspberry Pi's GPIO as a collection of GPIO Pins.\n* ```Pi.Spi``` Provides access to the 2-channel SPI bus.\n* ```Pi.I2c``` Provides access to the functionality of the I2C bus.\n* ```Pi.Timing``` Provides access to The PI's Timing and threading API.\n\n### Peripherals\n\nWe offer an additional package with helpful classes to use peripherals, many of them are from pull requests from our contributors. The current set of peripherals supported are:\n\n* Infrared Sensor HX-1838\n* Led Strip APA-102C\n* NFC/RFID Controller MFRC-522\n* DHT family digital relative humidity and temperature sensors:\n  * DHT11\n  * DHT12\n  * DHT21 / AM-2301\n  * DHT22 / AM-2302\n* OLED Display SSD-1306\n* Generic Button connected to GPIO\n* GY-521 MPU6050 Accelerometer\n* Ultrasonic Sensor HC-SR04\n* ADS1015 and ADS1115 I2C Analog-to-Digital Converter devices\n\n## Breaking changes\n\n### Version \u0026gt; 0.24.0\n\nThis version requires .NET core 3.0 to build and run. \n\n### Version \u0026ge; 0.18.0\n\nIn the beginning, RaspberryIO was built around WiringPi library and all our classes, properties, enums, etc. was based on those ones used in WiringPi too.\n\nNow, we are working on a more general version of RaspberryIO (Abstractions) that, could use any core library (WiringPi, PiGpio or even new ones). So, it was necessary to change certain properties and enums for more general ones.\n\n#### Pinout numbering system\n\nA breaking change in this new general version is the pinout numbering system. As we already explained above, RaspberryIO was using the WiringPi pinout numbering system, but now it uses the **[BCM pinout numbering system](https://pinout.xyz/#)**. \n\n_**Note:**_ The pin numbers are totally different in both systems, so we recommend you to double check carefully the physical pins where you connect any device.\n\n## Installation\n\nInstall basic Raspberry.IO package:\n[![NuGet version](https://badge.fury.io/nu/Unosquare.Raspberry.IO.svg)](https://badge.fury.io/nu/Unosquare.Raspberry.IO)\n\n```\nPM\u003e Install-Package Unosquare.Raspberry.IO\n```\n\nIf you want to implement your own provider for RaspberryIO, you must use the following package to implement all the `Pi` providers:\n[![NuGet version](https://badge.fury.io/nu/Unosquare.wiringpi.svg)](https://badge.fury.io/nu/Unosquare.wiringpi)\n\n```\nPM\u003e Install-Package Unosquare.WiringPi\n```\n\n_**Note:**_ For now, we have fully implemented the [WiringPi](https://www.nuget.org/packages/Unosquare.wiringpi) library and we are working in the [PiGpio](https://github.com/unosquare/pigpio-dotnet/) implementation.\n\n_**Note:**_ The latest development builds require .NET core 3.0 to build and run. You should upgrade to the latest Version of Visual Studio first. \n\nInstall Raspberry.IO Peripherals package (Optional):\n[![NuGet version](https://badge.fury.io/nu/Unosquare.RaspberryIO.Peripherals.svg)](https://badge.fury.io/nu/Unosquare.RaspberryIO.Peripherals)\n```\nPM\u003e Install-Package Unosquare.RaspberryIO.Peripherals\n```\n\n## Running the latest version of Mono\nIt is recommended that you install the latest available release of Mono because what is available in the Raspbian repo is quite old (3.X). These commands were tested using Raspbian Stretch. The version of Mono that is installed at the time of this writing is:\n``` \nMono JIT compiler version 5.20.1.19 (tarball Thu Apr 11 19:13 UTC 2019)\n```\n\nThe commands to get Mono installed are the following:\n\n### For Debian Stretch\n\n```\nsudo apt install apt-transport-https dirmngr gnupg ca-certificates\nsudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF\necho \"deb https://download.mono-project.com/repo/debian stable-raspbianstretch main\" | sudo tee /etc/apt/sources.list.d/mono-official-stable.list\nsudo apt update\nsudo apt-get install mono-complete\n```\n\nNow, verify your version of Mono by running ```mono --version```. Version 4.6 and above should be good enough.\n\n## Running .NET Core 3.1\n\nThis project can also run in .NET Core. To install .Net Core 3.1 sdk please execute the following commands:\n\n```\n$ sudo apt-get -y update\n$ sudo apt-get -y install libunwind8 gettext\n$ wget https://download.visualstudio.microsoft.com/download/pr/67766a96-eb8c-4cd2-bca4-ea63d2cc115c/7bf13840aa2ed88793b7315d5e0d74e6/dotnet-sdk-3.1.100-linux-arm.tar.gz\n$ sudo mkdir -p /usr/share/dotnet\n$ sudo tar -xvf dotnet-sdk-3.1.100-linux-arm.tar.gz -C /usr/share/dotnet\n$ sudo ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet\n```\n\nIf you want to install just the runtime, use the following commands:\n\n```\n$ sudo apt-get -y update\n$ sudo apt-get -y install libunwind8 gettext\n$ wget https://download.visualstudio.microsoft.com/download/pr/60d21925-7f8f-4004-9afe-aebd041d2d4a/0db2946738642d7f88f71f7800522e8c/dotnet-runtime-3.1.0-linux-arm.tar.gz\n$ sudo mkdir -p /usr/share/dotnet\n$ sudo tar -xvf dotnet-runtime-3.1.0-linux-arm.tar.gz -C /usr/share/dotnet\n$ sudo ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet\n```\n\nNow, verify your version of .Net Core by running ```dotnet --info```. \nVisit https://aka.ms/dotnet-download (or https://dotnet.microsoft.com/download/dotnet-core/3.1) to check for newer versions of the .Net Core runtime (or SDK). The Raspberry Pi running the default Raspbian OS needs the versions named \"Linux ARM32\". \n\n## Usage\n\nBefore start using RaspberryIO, you must initialize **Pi** class (bootstrapping process) with the valid Abstractions implementation, in order to let **Pi** know what implementation is going to use:\n\n```csharp\n Pi.Init\u003cBootstrapWiringPi\u003e();\n```\n\n**_Note:_** This sample code uses the [wiringpi-dotnet](https://github.com/unosquare/wiringpi-dotnet/) implementation, you can use this implementation adding the [Unosquare.WiringPi](https://www.nuget.org/packages/Unosquare.wiringpi) nuget package to your project.\n\n### Run the app on the raspberry\n\n#### Deploy using dotnet-sshdeploy\n- You need to publish the project and you can accomplish this by using [dotnet-sshdeploy](https://github.com/unosquare/sshdeploy) but first, you must edit these properties inside the csproj file in order to establish an ssh connection with your raspberry\n\n``` xml\n\u003cSshDeployHost\u003e172.16.17.54\u003c/SshDeployHost\u003e\n\u003cSshDeployTargetPath\u003e/home/pi/Playground\u003c/SshDeployTargetPath\u003e\n\u003cSshDeployUsername\u003epi\u003c/SshDeployUsername\u003e\n\u003cSshDeployPassword\u003eraspberry\u003c/SshDeployPassword\u003e\n```\n\n- Install dotnet-sshdeploy as a global tool by running \n```\n$ dotnet tool install -g dotnet-sshdeploy\n```\n\n- Execute `dotnet-sshdeploy push` in the same folder where Unosquare.RaspberryIO.Playground.csproj resides and if everything executes correctly you should see an output like this:\n\n```\nSSH Deployment Tool [Version 0.3.1.0]\n(c)2015 - 2017 Unosquare SA de CV. All Rights Reserved.\nFor additional help, please visit https://github.com/unosquare/sshdeploy\nDeploying...\n    Configuration   Debug\n    Framework       dotnetcore2.2\n    Source Path     C:\\raspberryio\\src\\Unosquare.RaspberryIO.Playground\\bin\\Debug\\dotnetcore2.2\\publish\n    Excluded Files  .ready|.vshost.exe|.vshost.exe.config\n    Target Address  172.16.17.54:22\n    Username        pi\n    Target Path     /home/pi/Playground\n    Clean Target    NO\n    Pre Deployment  \n    Post Deployment \nConnecting to host 172.16.17.54:22 via SSH.\nConnecting to host 172.16.17.54:22 via SFTP.\n\n    Target Path '/home/pi/Playground' does not exist. -- Will attempt to create.\n    Target Path '/home/pi/Playground' created successfully.\n    Cleaning Target Path '/home/pi/Playground'\n\n    Deploying 8 files.\n    Finished deployment in 1.25 seconds.\nCompleted.\n```\n\n* **The default TargetFramework is** `net461` **but you can change this by either modifying the RuntimeIdentifier property inside the csproj file or supplying it as a parameter like this** `dotnet-sshdeploy push -f netcoreapp2.2`. **More information about dotnet-sshdeploy see [this](https://github.com/unosquare/sshdeploy)**\n\n#### Deploy using Visual Studio \"Publish\" and WinSCP\n\nAlternatively, you can use Visual Studio's Publish feature and a SCP (SSH Copy) application such as WinSCP or FileZilla. This uses the example project from this library: \n\n- Right click on \"Unosquare.RaspberryIO.Playground\" and select \"Publish...\"\n- Select the publish profile you want to use (debug or release) and click on \"Publish\" on the right. \n- Wait for the project to build and note the output path\n- Open WinSCP, ensure you can connect to your raspberry\n- Navigate to the output folder noted above on your local computer\n- Select \"Commands -\u003e Keep remote folder current\", check the local and remote folder entries in the dialog and choose \"In new Window\" from the \"Start\" button. \n- Answer \"Yes\" to start an initial synchronisation. WinSCP will now automatically update the files on your Pi whenever you click the \"Publish\" button in Visual Studio. Note though that just building will _not_ update the publish folder. \n\n#### Run the project\n\n  - Using Mono:\n    \n    First of all, you need to give permissions to run the project by running the next command on your target folder:\n    \n    ```\n        ubuntu@ubuntu:~/publish$ sudo chmod u+x *\n    ```\n    \n    Or you just can add the **SshDeployExecutePermission** tag in your project's csproj file:\n\n    ```\n        \u003cSshDeployExecutePermission\u003etrue\u003c/SshDeployExecutePermission\u003e\n    ```\n    \n    Or use the appropriate command line argument:\n\n    ```\n        dotnet-sshdeploy push ... -x true\n    ```\n\n    Then you can run your project:\n\n    ```\n     ubuntu@ubuntu:~/publish$ ./Unosquare.RaspberryIO.Playground\n    ```\n\n  - Using .Net Core\n \n    ```\n      ubuntu@ubuntu:~/publish$ dotnet Unosquare.RaspberryIO.Playground.dll\n    ```\n    or \n    \n    ```\n      ubuntu@ubuntu:~/publish$ chmod +x Unosquare.RaspberryIO.Playground\n      ubuntu@ubuntu:~/publish$ ./Unosquare.RaspberryIO.Playground\n    ```\n    (the first line only needs to be executed once or after an update, since copying may not automatically set the execute bit)\n\n    **_Note_**: Depending on the underlying library, you may need to use root user privileges to run the app.\n\n## Obtaining Board and System Information\n```RaspberryIO``` contains useful utilities to obtain information about the board it is running on. You can simply call the ```Pi.Info.ToString()``` method to obtain a dump of all system properties as a single ```string```, or you can use the individual properties such as Installed RAM, Processor Count, Raspberry Pi Version, Serial Number, etc. There's not a lot more to this.\n\n## Using the GPIO Pins\nPin reference for the B plus (B+) - Header P1\n\n| BCM |  Name    | Mode | V   | L      | R      | V   | Mode | Name    |  BCM |\n| --- | -------- | ---- | --- | ------ | ------ | --- | ---- | ------- | ---- |\n|     |     3.3v |      |     | **01** | **02** |     |      | 5v      |      |\n|   2 |    SDA.1 | ALT0 | 1   | **03** | **04** |     |      | 5V      |      |\n|   3 |    SCL.1 | ALT0 | 1   | **05** | **06** |     |      | GND     |      |\n|   4 |  GPIO. 7 |   IN | 1   | **07** | **08** | 1   | ALT0 | TxD     |  14  |\n|     |      GND |      |     | **09** | **10** | 1   | ALT0 | RxD     |  15  |\n|  17 |  GPIO. 0 |   IN | 0   | **11** | **12** | 0   | IN   | GPIO. 1 |  18  |\n|  27 |  GPIO. 2 |   IN | 0   | **13** | **14** |     |      | GND     |      |\n|  22 |  GPIO. 3 |   IN | 0   | **15** | **16** | 0   | IN   | GPIO. 4 |  23  |\n|     |     3.3v |      |     | **17** | **18** | 0   | IN   | GPIO. 5 |  24  |\n|  10 |     MOSI |   IN | 0   | **19** | **20** |     |      | GND     |      |\n|   9 |     MISO |   IN | 0   | **21** | **22** | 0   | IN   | GPIO. 6 |  25  |\n|  11 |     SCLK |   IN | 0   | **23** | **24** | 1   | IN   | CE0     |  8   |\n|     |      GND |      |     | **25** | **26** | 1   | IN   | CE1     |  7   |\n|   0 |    SDA.0 |   IN | 1   | **27** | **28** | 1   | IN   | SCL.0   |  1   |\n|   5 |  GPIO.21 |   IN | 1   | **29** | **30** |     |      | GND     |      |\n|   6 |  GPIO.22 |   IN | 1   | **31** | **32** | 0   | IN   | GPIO.26 |  12  |\n|  13 |  GPIO.23 |   IN | 0   | **33** | **34** |     |      | GND     |      |\n|  19 |  GPIO.24 |   IN | 0   | **35** | **36** | 0   | IN   | GPIO.27 |  16  |\n|  26 |  GPIO.25 |   IN | 0   | **37** | **38** | 0   | IN   | GPIO.28 |  20  |\n|     |      GND |      |     | **39** | **40** | 0   | IN   | GPIO.29 |  21  |\n\nThe above diagram shows the pins of GPIO Header P1. There is an additional GPIO header on the Pi called P5. [More info available here](http://www.raspberrypi-spy.co.uk/2012/09/raspberry-pi-p5-header/)\n\nIn order to access the pins, use ```Pi.Gpio```. The pins can have multiple behaviors and fortunately ```Pi.Gpio``` can be iterated, addressed by index, addressed by BCM pin number and provides the pins as publicly accessible properties.\n\nHere is an example of addressing the pins in all the various ways:\n\n```csharp\npublic static void TestLedBlinking()\n{\n    // Get a reference to the pin you need to use.\n    // Both methods below are equivalent\n    var blinkingPin = Pi.Gpio[17];\n    blinkingPin = Pi.Gpio[BcmPin.Gpio17];\n\n    // Configure the pin as an output\n    blinkingPin.PinMode = GpioPinDriveMode.Output;\n\n    // perform writes to the pin by toggling the isOn variable\n    var isOn = false;\n    for (var i = 0; i \u003c 20; i++)\n    {\n        isOn = !isOn;\n        blinkingPin.Write(isOn);\n        System.Threading.Thread.Sleep(500);\n    }\n}\n```\n\n### Pin Information\nAll pins have handy properties and methods that you can use to drive them. For example, you can examine the ```Capabilities``` property to find out which features are available on the pin. You can also use the ```PinMode``` property to get or set the operating mode of the pin. Please note that the value of the ```PinMode``` property is by default set to _Input_ and it will return the last mode you set the property to.\n\n### Digital Read and Write\nIt is very easy to read and write values to the pins. In general, it is a 2-step process.\n- Set the pin mode\n- Read or write the bit value\n\nReading the value of a pin example:\n```csharp\nPi.Gpio.Pin27.PinMode = GpioPinDriveMode.Input;\n// The below lines are reoughly equivalent\nvar isOn = Pi.Gpio.Pin27.Read(); // Reads as a boolean\nvar pinValue = Pi.Gpio.Pin27.ReadValue(); // Reads as a GpioPinValue\n```\n\nWriting to a pin example\n```csharp\nPi.Gpio.Pin27.PinMode = GpioPinDriveMode.Output;\n// The below lines are reoughly equivalent\nPi.Gpio.Pin27.Write(true); // Writes a boolean\nPi.Gpio.Pin27.Write(GpioPinValue.High); // Writes a pin value\n```\n\n\n### Hardware PWM\nSimple code for led dimming:\n\n```csharp\n   var pin = (GpioPin)Pi.Gpio[BcmPin.Gpio24];\n   pin.PinMode = GpioPinDriveMode.PwmOutput;\n   pin.PwmMode = PwmMode.Balanced;\n   pin.PwmClockDivisor = 2; \n   while (true)\n   {\n      for (var x = 0; x \u003c= 100; x++)\n      {\n         pin.PwmRegister = (int)pin.PwmRange / 100 * x;\n         Thread.Sleep(10);\n      }\n\n      for (var x = 0; x \u003c= 100; x++)\n      {\n         pin.PwmRegister = (int)pin.PwmRange - ((int)pin.PwmRange / 100 * x);\n         Thread.Sleep(10);\n      }\n   }\n```\n\n**PwmRange** is the maximun value of the pulse width, than means 100% of pulse width. Changing this value allows you to have a more fine or coarse control of the pulse width (default 1024).\n\n**PwmRegister** is the current pulse width. Changing this value allows you to change the current pulse width and thus the duty cycle.\n\n**Duty Cycle** is equals to **PwmRegister** divide by **PwmRange**. Assuming a **PwmRange** value of 1024 (default), we have:\n\n| PwmRegister | Duty Cycle | \n| :---: | :---: |\n| 0 | 0% |\n| 256 | 25% |\n| 512 | 50% |\n| 768 | 75% |\n| 1024 | 100% |\n\n**_Note:_** Hardware PWM can be used only in GPIO12, GPIO13, GPIO18 and GPIO19.\n\n### Software PWM\nSimple code for led dimming:\n\n```csharp\n   var range = 100;\n   var pin = (GpioPin)Pi.Gpio[BcmPin.Gpio24];\n   pin.PinMode = GpioPinDriveMode.Output;\n   pin.StartSoftPwm(0, range);\n   \n   while (true)\n   {\n      for (var x = 0; x \u003c= 100; x++)\n      {\n         pin.SoftPwmValue = range / 100 * x;\n         Thread.Sleep(10);\n      }\n\n      for (var x = 0; x \u003c= 100; x++)\n      {\n         pin.SoftPwmValue = range - (range / 100 * x);\n         Thread.Sleep(10);\n      }\n   }\n```\n\n**SoftPwmRange** is the range of the pulse width, than means 100% of pulse width (We notice better performance using a range value of 100).\n\n**SoftPwmValue** is the current pulse width. Changing this value allows you to change the current pulse width and thus the duty cycle.\n\n**_Note:_** Software PWM can be used in any GPIO.\n\n### Tone Generation\nYou can emit tones by using SoftToneFrequency. Example:\n\n```csharp\n// Get a reference to the pin\nvar passiveBuzzer = (GpioPin)Pi.Gpio[BcmPin.Gpio24];\n// Set the frequency to Alto Do (523Hz)\npassiveBuzzer.SoftToneFrequency = 523\n// Wait 1 second\nSystem.Threading.Thread.Sleep(1000);\n// And stop\npassiveBuzzer.SoftToneFrequency = 0;\n```\n\n### Interrupts and Callbacks\nRegister an Interrupt Callback example:\n\n```csharp\nusing System;\nusing Unosquare.RaspberryIO;\nusing Unosquare.RaspberryIO.Gpio;\n\nclass Program\n{\n  // Define the implementation of the delegate;\n  static void ISRCallback()\n  {\n     Console.WriteLine(\"Pin Activated...\");         \n  }\n\n  static void Main(string[] args)\n  {\n        Console.WriteLine(\"Gpio Interrupts\");\n        var pin = Pi.Gpio.Pin24;\n        pin.PinMode = GpioPinDriveMode.Input;\n        pin.RegisterInterruptCallback(EdgeDetection.FallingEdge, ISRCallback);\n        Console.ReadKey();\n  }\n}\n```\n\n## Using the SPI Bus\nI really liked the following description from [Neil's Log Book](http://nrqm.ca/nrf24l01/serial-peripheral-interface/): _The SPI (Serial Peripheral Interface) protocol behaves like a ring buffer so that whenever the master sends a byte to the slave, the slave sends a byte back to the master. The slave can use this behavior to return a status byte, a response to a previous byte, or null data (the master may choose to read the returned byte or ignore it). The bus operates on a 4-wire interface._\n\n```RaspberryIO``` provides easy access to the 2 SPI channels available on the Raspberry. The functionality depends on ```Wiring Pi```'s SPI library. Please note that you may need to issue the command ```gpio load spi``` before starting your application (or as a ```System.Diagnostics.Process``` when your application starts) if the SPI kernel drivers have not been loaded.\n\nIn order to use an SPI channel you **MUST** always set the ```Channel0Frequency``` or ```Channel1Frequency``` (depending on the channel you want to use) before calling the ```SendReceive``` method. If the property is not set beforehand the SPI channel will fail initialization. See an example below: \n\nExample of using the SPI Bus\n```csharp\nPi.Spi.Channel0Frequency = SpiChannel.MinFrequency;\nvar request = System.Text.Encoding.ASCII.GetBytes(\"HELLO!\");\nvar response = Pi.Spi.Channel0.SendReceive(request);\n```\n\n**_Note_**: In order to enable the second SPI channel (SPI1) you need to add `dtoverlay=spi1-1cs` to the config file.\n\n## I2C to connect ICs\nThe Inter IC Bus (I2C) is a cousin of the SPI bus but it is somewhat more complex and it does not work as a ring buffer like the SPI bus. It also connects all of its slave devices in series and depends on 2 lines only. There is a nice tutorial on setting up and using the I2C bus at [Robot Electronics](http://www.robot-electronics.co.uk/i2c-tutorial). From their site: _The physical bus is just two wires, called SCL and SDA. SCL is the clock line. It is used to synchronize all data transfers over the I2C bus. SDA is the data line. The SCL \u0026 SDA lines are connected to all devices on the I2C bus. There needs to be a third wire which is just the ground or 0 volts. There may also be a 5volt wire is power is being distributed to the devices. Both SCL and SDA lines are \"open drain\" drivers. What this means is that the chip can drive its output low, but it cannot drive it high. For the line to be able to go high you must provide pull-up resistors to the 5v supply. There should be a resistor from the SCL line to the 5v line and another from the SDA line to the 5v line. You only need one set of pull-up resistors for the whole I2C bus, not for each device._\n\n```RaspberryIO``` provides easy access to the I2C bus available on the Raspberry. Please note that you may need to issue the command ```gpio load i2c``` before starting your application (or as a ```System.Diagnostics.Process``` when your application starts) if the I2C kernel drivers have not been loaded. The default baud rate is 100Kbps. If you wish to initialize the bus at a different baud rate you may issue, for example, ```gpio load i2c 200```. This will load the bus at 200kbps.\n\nIn order to detect I2C devices, you could use the ```i2cdetect``` system command. Just remember that on a Rev 1 Raspberry Pi it's device 0, and on a Rev. 2 it's device 1. e.g.\n```\ni2cdetect -y 0 # Rev 1\ni2cdetect -y 1 # Rev 2\n```\n\nExample of using the I2C Bus:\n\n```csharp\n// Register a device on the bus\nvar myDevice = Pi.I2C.AddDevice(0x20);\n\n// Simple Write and Read (there are algo register read and write methods)\nmyDevice.Write(0x44);\nvar response = myDevice.Read();\n\n// List registered devices on the I2C Bus\nforeach (var device in Pi.I2C.Devices)\n{\n    Console.WriteLine($\"Registered I2C Device: {device.DeviceId}\");\n}\n```\n\n## Timing and Threading\n\n### Timing\n\nSystem calls to provide various timing and sleeping functions.\n\nGetting the number of microseconds or milliseconds since system boot:\n\n```csharp\n// Getting the number of microseconds since system boot.\nvar micros = Pi.Timing.Microseconds;\n\n// Getting the number of milliseconds since system boot.\nvar millis = Pi.Timing.Milliseconds;\n```\n\nPausing program execution for a certain number of microseconds or milliseconds.\n\n```csharp\n// Pausing program execution for 50 microseconds.\nPi.Timing.SleepMicroseconds(50);\n\n// Pausing program execution for 100 milliseconds.\nPi.Timing.SleepMilliseconds(100);\n```\n\n### Threading\n\nAllows the creation of a thread which is another function in your program that runs concurrently with your main program. An example may be to have this function wait for an interrupt while your program carries on doing other tasks. The thread can indicate an event, or action by using global variables to communicate back to the main program, or other threads.\n\nBasic thread creation:\n\n```csharp\n    static void Main()\n    {\n        ...\n        Pi.Threading.StartThread(ThreadWorker);\n        ...\n    }\n\n    private void ThreadWorker()\n    {\n        // Thread body\n    }\n```\n\nPassing data to a thread:\n\n\n```csharp\n    \n    static void Main()\n    {\n        ...\n        var threadName = \"Thread 1\";\n        var namePointer = (IntPtr)Marshal.StringToHGlobalAnsi(threadName);\n        var threadHandle = Pi.Threading.StartThreadEx(ThreadWorker, namePointer);\n        ...\n\n        Pi.Threading.StopThreadEx(threadHandle);\n        ...\n    }\n\n    private void ThreadWorker(IntPtr state)\n    {\n        var threadName = Marshal.PtrToStringAnsi(state);\n\n        // Thread body\n    }\n```\n\n_**Note**_: Not all underlying libraries support all methods for creating threads. WiringPi, for example, does only support basic thread creation.\n\n\n## Serial Ports (UART)\nWhere is the serial port API? Well, it is something we will most likely add in the future. For now, you can simply use the built-in ```SerialPort``` class the .NET framework provides.\n\n## The Camera Module\nThe ```Pi.Camera``` module uses ```raspivid``` and ```raspistill``` to access the camera so they must be installed in order for your program to work properly. ```raspistill``` arguments are specified in an instance of the ```CameraStillSettings``` class, while the ```raspivid``` arguments are specified in an instance of the ```CameraVideoSettings``` class. \n\n### Capturing Images\nThe ```Pi.Camera.CaptureImage*``` methods simply return an array of bytes containing the captured image. There are synchronous and asynchronous flavors of these methods so you can use the familiar ```async``` and ```await``` pattern to capture your images. All ```raspistill``` arguments (except for those that control user interaction such as ```-k```) are available via the ```CameraStillSettings```. To start, create a new instance of the ```CameraStillSettings``` class and pass it on to your choice of the ```Pi.Camera.CaptureImage*``` methods. There are shortcut methods available that simply take a JPEG image at the given Width and Height. By default, the shortcut methods set the JPEG quality at 90%.\n\nExample using a shortcut method:\n```csharp\nstatic void TestCaptureImage()\n{\n    var pictureBytes = Pi.Camera.CaptureImageJpeg(640, 480);\n    var targetPath = \"/home/pi/picture.jpg\";\n    if (File.Exists(targetPath))\n        File.Delete(targetPath);\n\n    File.WriteAllBytes(targetPath, pictureBytes);\n    Console.WriteLine($\"Took picture -- Byte count: {pictureBytes.Length}\");\n}\n```\n\nExample using a CaptureImage method:\n```csharp\nstatic byte[] TestCaptureImage()\n{\n    var settings = new CameraStillSettings\n    {\n        CaptureWidth = 640,\n        CaptureHeight = 480,\n        CaptureJpegQuality = 90,\n        CaptureTimeoutMilliseconds = 300\n    };\n\n    return CaptureImage(settings);\n}\n```\n\n### Capturing Video\nCapturing video streams is somewhat different but it is still very easy to do. The concept behind it is to _Open_ a video stream providing your own callback. When opening the stream ```Raspberry IO``` will spawn a separate thread and will not block the execution of your code, but it will continually call your callback method containing the bytes that are being read from the camera until the _Close_ method is called or until the timeout is reached.\n\nExample of capturing a stream of H.264 video\n```csharp\nstatic void TestCaptureVideo()\n{\n    // Setup our working variables\n    var videoByteCount = 0;\n    var videoEventCount = 0;\n    var startTime = DateTime.UtcNow;\n\n    // Configure video settings\n    var videoSettings = new CameraVideoSettings()\n    {\n        CaptureTimeoutMilliseconds = 0,\n        CaptureDisplayPreview = false,\n        ImageFlipVertically = true,\n        CaptureExposure = CameraExposureMode.Night,\n        CaptureWidth = 1920,\n        CaptureHeight = 1080\n    };\n\n    try\n    {\n        // Start the video recording\n        Pi.Camera.OpenVideoStream(videoSettings,\n            onDataCallback: (data) =\u003e { videoByteCount += data.Length; videoEventCount++; },\n            onExitCallback: null);\n\n        // Wait for user interaction\n        startTime = DateTime.UtcNow;\n        Console.WriteLine(\"Press any key to stop reading the video stream . . .\");\n        Console.ReadKey(true);\n    }\n    catch (Exception ex)\n    {\n        Console.WriteLine($\"{ex.GetType()}: {ex.Message}\");\n    }\n    finally\n    {\n        // Always close the video stream to ensure raspivid quits\n        Pi.Camera.CloseVideoStream();\n\n        // Output the stats\n        var megaBytesReceived = (videoByteCount / (1024f * 1024f)).ToString(\"0.000\");\n        var recordedSeconds = DateTime.UtcNow.Subtract(startTime).TotalSeconds.ToString(\"0.000\");\n        Console.WriteLine($\"Capture Stopped. Received {megaBytesReceived} Mbytes in {videoEventCount} callbacks in {recordedSeconds} seconds\");\n    }            \n}\n```\n\n## Audio settings\n\nBasic audio settings have been implemented in RaspberryIO:\n\n- Set a specific volume level percentage.\n- Set a specific volume level in decibels (dB)\n- Mute an audio device.\n- Consult audio device settings.\n\nUsers set an audio card, an audio device and an audio command to perform an audio action. Example of audio tasks:\n\n```csharp\nawait Pi.PiVolumeControl.SetVolumePercentage(85);\n\nawait Pi.PiVolumeControl.SetVolumeByDecibels(-1.00f);\n```\n\nThe code above sets the volume level in two different formats: Percentage or Decibels.\nThe first method sets the volume on percentage (0% - 100%) and the second sets the volume level on decibels(dB) (-101.32dB - 4.00dB).\n\nUsers can consult the current audio settings by using the method GetState.\nAn example is shown below:\n\n```csharp\nvar currentState = await Pi.Audio.GetState();\nConsole.WriteLine(currentState);\n```\n\nThe same result can be achieved by setting the volume level to 0% or -9999.99dB.\n\n## Handy Notes\n\nIn order to setup Wi-Fi, run: `sudo nano /etc/wpa_supplicant/wpa_supplicant.conf`\n\nA good file should look like this:\n```\ncountry=US\nctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev\nupdate_config=1\n\nnetwork={\n    ssid=\"your_real_wifi_ssid\"\n    scan_ssid=1\n    psk=\"your_real_password\"\n}\n```\n\nAnd then restart the services as follows:\n```\nsudo systemctl daemon-reload\nsudo systemctl restart dhcpcd\n```\n\nYou can also configure most boot options by running: `sudo raspi-config`\n\n## Related Projects and Nugets\n| Name | Author | Description |\n| ---- | ------ | ----------- |\n| [WiringPi.net](https://github.com/unosquare/wiringpi-dotnet) | [Unosquare](https://github.com/unosquare) | Provides complete managed access to the popular wiringpi C library |\n| [PiGpio.net](https://github.com/unosquare/pigpio-dotnet) | [Unosquare](https://github.com/unosquare) | Provides complete managed access to the popular pigpio C library |\n| [Raspberry Abstractions](https://www.nuget.org/packages/Unosquare.Raspberry.Abstractions) | [Unosquare](https://www.nuget.org/profiles/Unosquare) | Allows you to implement your own provider for RaspberryIO. |\n| [Raspberry# IO](https://github.com/raspberry-sharp/raspberry-sharp-io) | [raspberry-sharp](https://github.com/raspberry-sharp) | Raspberry# IO is a .NET/Mono IO Library for Raspberry Pi. This project is an initiative of the [Raspberry#](http://www.raspberry-sharp.org/) Community. |\n| [WiringPi.Net](https://github.com/danriches/WiringPi.Net) | [Daniel Riches](https://github.com/danriches) | A simple C# wrapper for Gordon's WiringPi library. |\n| [PiSharp](https://github.com/andycb/PiSharp) |[Andy Bradford](https://github.com/andycb) | Pi# is a library to expose the GPIO functionality of the Raspberry Pi computer to the C# and Visual Basic.Net languages |\n","funding_links":[],"categories":["raspberry-pi"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funosquare%2Fraspberryio","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Funosquare%2Fraspberryio","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funosquare%2Fraspberryio/lists"}