Files
2026-06-25 19:32:06 +02:00

387 lines
36 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en-us" dir="ltr" itemscope itemtype="http://schema.org/Article" data-r-output-format="html">
<head>
<meta charset="utf-8">
<meta name="viewport" content="height=device-height, width=device-width, initial-scale=1.0, minimum-scale=1.0">
<meta name="generator" content="Hugo 0.161.1">
<meta name="generator" content="Relearn 8.2.0+220806ce3ced8264fbdd693f77f28216a8a1b6ae">
<meta name="description" content="In this guide, we are using periph.io, a library for peripheral I/O in Go, to set one of the Raspberry Pis General Purpose I/O (GPIO) pins to a logical high (3.3V) or low (0V) signal.
periph.io supports the Raspberry Pi 3, Raspberry Pi Zero 2W and Raspberry Pi 4, starting with version v3.6.4.
Connect GPIO pins based on pinout To verify the code is doing what we expect, lets connect a multimeter as per pinout.xyzs pinout:">
<meta name="author" content="">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Controlling a GPIO input/output pin :: gokrazy">
<meta name="twitter:description" content="In this guide, we are using periph.io, a library for peripheral I/O in Go, to set one of the Raspberry Pis General Purpose I/O (GPIO) pins to a logical high (3.3V) or low (0V) signal.
periph.io supports the Raspberry Pi 3, Raspberry Pi Zero 2W and Raspberry Pi 4, starting with version v3.6.4.
Connect GPIO pins based on pinout To verify the code is doing what we expect, lets connect a multimeter as per pinout.xyzs pinout:">
<meta property="og:url" content="https://gokrazy.org/development/gpio/index.html">
<meta property="og:site_name" content="gokrazy">
<meta property="og:title" content="Controlling a GPIO input/output pin :: gokrazy">
<meta property="og:description" content="In this guide, we are using periph.io, a library for peripheral I/O in Go, to set one of the Raspberry Pis General Purpose I/O (GPIO) pins to a logical high (3.3V) or low (0V) signal.
periph.io supports the Raspberry Pi 3, Raspberry Pi Zero 2W and Raspberry Pi 4, starting with version v3.6.4.
Connect GPIO pins based on pinout To verify the code is doing what we expect, lets connect a multimeter as per pinout.xyzs pinout:">
<meta property="og:locale" content="en_us">
<meta property="og:type" content="article">
<meta property="article:section" content="Package development">
<meta itemprop="name" content="Controlling a GPIO input/output pin :: gokrazy">
<meta itemprop="description" content="In this guide, we are using periph.io, a library for peripheral I/O in Go, to set one of the Raspberry Pis General Purpose I/O (GPIO) pins to a logical high (3.3V) or low (0V) signal.
periph.io supports the Raspberry Pi 3, Raspberry Pi Zero 2W and Raspberry Pi 4, starting with version v3.6.4.
Connect GPIO pins based on pinout To verify the code is doing what we expect, lets connect a multimeter as per pinout.xyzs pinout:">
<meta itemprop="wordCount" content="640">
<title>Controlling a GPIO input/output pin :: gokrazy</title>
<link href="/images/favicon.png?1782408721" rel="icon" type="image/png">
<link href="/css/auto-complete/auto-complete.min.css?1782408721" rel="stylesheet">
<script src="/js/auto-complete/auto-complete.min.js?1782408721" defer></script>
<script src="/js/search-lunr.min.js?1782408721" defer></script>
<script src="/js/search.min.js?1782408721" defer></script>
<script>
window.relearn = window.relearn || {};
window.relearn.index_js_url="/searchindex.en.js?1782408721";
</script>
<script src="/js/lunr/lunr.min.js?1782408721" defer></script>
<script src="/js/lunr/lunr.stemmer.support.min.js?1782408721" defer></script>
<script src="/js/lunr/lunr.multi.min.js?1782408721" defer></script>
<script src="/js/lunr/lunr.en.min.js?1782408721" defer></script>
<script>
window.relearn = window.relearn || {};
window.relearn.contentLangs=['en'];
</script>
<link href="/fonts/fontawesome/css/fontawesome-all.min.css?1782408721" rel="stylesheet" media="print" onload="this.media='all';this.onload=null;"><noscript><link href="/fonts/fontawesome/css/fontawesome-all.min.css?1782408721" rel="stylesheet"></noscript>
<link href="/css/perfect-scrollbar/perfect-scrollbar.min.css?1782408721" rel="stylesheet">
<link href="/css/theme.min.css?1782408721" rel="stylesheet">
<link href="/css/format-html.min.css?1782408721" rel="stylesheet" id="R-format-style">
<script>
window.relearn = window.relearn || {};
// configuration
window.relearn.min = `.min`;
window.relearn.path='\/development\/gpio\/index.html';
window.relearn.relBasePath='..\/..';
window.relearn.relBaseUri='..\/..';
window.relearn.absBaseUri='https:\/\/gokrazy.org';
window.relearn.disableInlineCopyToClipboard=true;
window.relearn.enableBlockCodeWrap=true;
// legal
window.relearn.getItem = (s,n) => {return s.getItem(n)};
window.relearn.setItem = (s,n,v) => {return s.setItem(n,v)};
window.relearn.removeItem = (s,n) => {return s.removeItem(n)};
// translations
window.T_Copy_to_clipboard = `Copy text to clipboard`;
window.T_Copied_to_clipboard = `Text copied to clipboard!`;
window.T_Link_copied_to_clipboard = `Link copied to clipboard!`;
window.T_Reset_view = `Reset view`;
window.T_View_reset = `View reset!`;
window.T_No_results_found = `No results found for "{0}"`;
window.T_N_results_found = `{1} results found for "{0}"`;
window.T_Browser_unsupported_feature = `This browser doesn't support this feature`;
// variant stuff
window.relearn.themevariants = [ 'auto' ];
window.relearn.customvariantname = "my-custom-variant";
window.relearn.changeVariant = function(variant) {
var oldVariant = document.documentElement.dataset.rThemeVariant;
window.relearn.setItem(window.localStorage, window.relearn.absBaseUri + "/variant", variant);
document.documentElement.dataset.rThemeVariant = variant;
if (oldVariant != variant) {
document.dispatchEvent( new CustomEvent('themeVariantLoaded', { detail: { variant, oldVariant } }) );
window.relearn.markVariant();
}
}
window.relearn.markVariant = function() {
var variant = window.relearn.getItem(window.localStorage, window.relearn.absBaseUri + "/variant");
document.querySelectorAll(".R-variantswitcher select").forEach((select) => {select.value = variant;});
}
window.relearn.initVariant = function() {
var variant = window.relearn.getItem(window.localStorage, window.relearn.absBaseUri + "/variant") ?? "";
if( variant == window.relearn.customvariantname ){
}else if( !variant || !window.relearn.themevariants.includes(variant) ){
variant = window.relearn.themevariants[0];
window.relearn.setItem(window.localStorage, window.relearn.absBaseUri + "/variant", variant);
}
document.documentElement.dataset.rThemeVariant = variant;
}
window.relearn.initVariant();
window.relearn.markVariant();
</script>
</head>
<body class="mobile-support html" data-url="/development/gpio/index.html">
<div id="R-body" class="default-animation">
<div id="R-body-overlay"></div>
<nav id="R-topbar">
<div class="topbar-wrapper">
<div class="topbar-sidebar-divider"></div>
<div class="topbar-area topbar-area-start" data-area="start">
<div class="topbar-button topbar-button-sidebar" data-content-empty="disable" data-width-s="show" data-width-m="hide" data-width-l="hide">
<span class="btn cstyle button link noborder notitle interactive"><button onclick="toggleNav()" type="button" title="Menu (CTRL&#43;ALT&#43;n)"><i class="fa-fw fas fa-bars"></i></button></span>
</div>
<div class="topbar-button topbar-button-toc" data-content-empty="hide" data-width-s="show" data-width-m="show" data-width-l="show">
<span class="btn cstyle button link noborder notitle interactive"><button onclick="toggleTopbarFlyout(this)" type="button" title="Table of Contents (CTRL&#43;ALT&#43;t)"><i class="fa-fw fas fa-list-alt"></i></button></span>
<div class="topbar-content">
<div class="topbar-content-wrapper">
<nav class="TableOfContents">
<ul>
<li><a href="#connect-gpio-pins-based-on-pinout">Connect GPIO pins based on pinout</a></li>
<li><a href="#setting-an-output-pin-signal">Setting an output pin signal</a></li>
<li><a href="#setting-up-an-input-pin">Setting up an input pin</a></li>
</ul>
</nav>
</div>
</div>
</div>
</div>
<ol class="topbar-breadcrumbs breadcrumbs highlightable" itemscope itemtype="http://schema.org/BreadcrumbList"><li itemscope itemtype="https://schema.org/ListItem" itemprop="itemListElement" class=""><a itemprop="item" href="/index.html"><span itemprop="name">gokrazy Go appliances</span></a><meta itemprop="position" content="1">&nbsp;>&nbsp;</li><li itemscope itemtype="https://schema.org/ListItem" itemprop="itemListElement" class=""><a itemprop="item" href="/development/index.html"><span itemprop="name">Package development</span></a><meta itemprop="position" content="2">&nbsp;>&nbsp;</li><li itemscope itemtype="https://schema.org/ListItem" itemprop="itemListElement" class=""><span itemprop="name">Controlling a GPIO input/output pin</span><meta itemprop="position" content="3"></li>
</ol>
<div class="topbar-area topbar-area-end" data-area="end">
<div class="topbar-button topbar-button-edit" data-content-empty="disable" data-width-s="area-more" data-width-m="show" data-width-l="show">
<span class="btn cstyle button link noborder notitle interactive"><a href="https://github.com/gokrazy/gokrazy/tree/master/website/content/development/gpio.md" rel="external" title="Edit (CTRL+ALT+w)"><i class="fa-fw fas fa-pen"></i></a></span>
</div>
<div class="topbar-button topbar-button-more" data-content-empty="hide" data-width-s="show" data-width-m="show" data-width-l="show">
<span class="btn cstyle button link noborder notitle interactive"><button onclick="toggleTopbarFlyout(this)" type="button" title="More"><i class="fa-fw fas fa-ellipsis-v"></i></button></span>
<div class="topbar-content">
<div class="topbar-content-wrapper">
<div class="topbar-area topbar-area-more" data-area="more">
</div>
</div>
</div>
</div>
</div>
</div>
</nav>
<div id="R-main-overlay"></div>
<main id="R-body-inner" class="highlightable development" tabindex="-1">
<div class="flex-block-wrapper">
<article class="default">
<header class="headline">
</header>
<h1 id="controlling-a-gpio-inputoutput-pin">Controlling a GPIO input/output pin</h1>
<p>In this guide, we are using <a href="https://periph.io/" rel="external">periph.io</a>, a library for
peripheral I/O in Go, to set one of the Raspberry Pis General Purpose I/O
(GPIO) pins to a logical high (3.3V) or low (0V) signal.</p>
<p>periph.io supports the Raspberry Pi 3, Raspberry Pi Zero 2W and Raspberry Pi 4, starting with version
<code>v3.6.4</code>.</p>
<h2 id="connect-gpio-pins-based-on-pinout">Connect GPIO pins based on pinout<span class="btn cstyle anchor copyanchor scrollanchor link noborder notitle interactive"><button type="button" title="Copy link to clipboard"><i class="fa-fw fas fa-link fa-lg"></i></button></span></h2>
<p>To verify the code is doing what we expect, lets connect a multimeter as per
<a href="https://pinout.xyz" rel="external">pinout.xyz</a>s pinout:</p>
<p><a href="#R-image-20b9bd57d8debe146b5cd890f0862bff" class="lightbox-link"><img class="lazy lightbox figure-image" loading="lazy" src="/img/raspberry-pi-pinout.png" style="height: auto;width: auto;"></a>
<a href="javascript:history.back();" class="lightbox-back" id="R-image-20b9bd57d8debe146b5cd890f0862bff"><img class="lazy lightbox lightbox-image" loading="lazy" src="/img/raspberry-pi-pinout.png"></a></p>
<ul>
<li>pin number 18 (signal <code>BCM24</code>, labeled <code>24</code> in the pinout above)</li>
<li>pin number 20 (signal <code>GND</code>)</li>
</ul>
<p>We need to set the multimeter to “Voltage measurement, DC (direct current)”.</p>
<h2 id="setting-an-output-pin-signal">Setting an output pin signal<span class="btn cstyle anchor copyanchor scrollanchor link noborder notitle interactive"><button type="button" title="Copy link to clipboard"><i class="fa-fw fas fa-link fa-lg"></i></button></span></h2>
<p>To set the pin high and low, alternatingly, with a 5 second frequency, we will
be using the <code>hello-gpio</code> program, which is a slightly modified version of the
example at <a href="https://periph.io/device/led/" rel="external">periph.io/device/led</a>:</p>
<div class="highlight actionbar-wrapper wrap-code" dir="auto"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#f92672">package</span> <span style="color:#a6e22e">main</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> (
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;log&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;time&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;periph.io/x/conn/v3/gpio&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">host</span> <span style="color:#e6db74">&#34;periph.io/x/host/v3&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;periph.io/x/host/v3/rpi&#34;</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">doGPIO</span>() <span style="color:#66d9ef">error</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">log</span>.<span style="color:#a6e22e">Printf</span>(<span style="color:#e6db74">&#34;Loading periph.io drivers&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#75715e">// Load periph.io drivers:</span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">host</span>.<span style="color:#a6e22e">Init</span>(); <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">err</span>
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">log</span>.<span style="color:#a6e22e">Printf</span>(<span style="color:#e6db74">&#34;Toggling GPIO forever&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">t</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">time</span>.<span style="color:#a6e22e">NewTicker</span>(<span style="color:#ae81ff">5</span> <span style="color:#f92672">*</span> <span style="color:#a6e22e">time</span>.<span style="color:#a6e22e">Second</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">for</span> <span style="color:#a6e22e">l</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">gpio</span>.<span style="color:#a6e22e">Low</span>; ; <span style="color:#a6e22e">l</span> = !<span style="color:#a6e22e">l</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">log</span>.<span style="color:#a6e22e">Printf</span>(<span style="color:#e6db74">&#34;setting GPIO pin number 18 (signal BCM24) to %v&#34;</span>, <span style="color:#a6e22e">l</span>)
</span></span><span style="display:flex;"><span> <span style="color:#75715e">// Lookup a pin by its location on the board:</span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">rpi</span>.<span style="color:#a6e22e">P1_18</span>.<span style="color:#a6e22e">Out</span>(<span style="color:#a6e22e">l</span>); <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">err</span>
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> <span style="color:#f92672">&lt;-</span><span style="color:#a6e22e">t</span>.<span style="color:#a6e22e">C</span>
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">doGPIO</span>(); <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">log</span>.<span style="color:#a6e22e">Fatal</span>(<span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>}</span></span></code></pre></div>
<p>You have two options to run this program on your Raspberry Pi:</p>
<ol>
<li>Use <code>gok run</code> to temporarily run this program on a running gokrazy instance.</li>
<li>Use <code>gok add</code> to permanently include this program in your gokrazy instance:</li>
</ol>
<div class="highlight actionbar-wrapper wrap-code" dir="auto"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># From the hello-gpio directory, run:</span>
</span></span><span style="display:flex;"><span>gok add .
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Then, deploy as usual:</span>
</span></span><span style="display:flex;"><span>gok update</span></span></code></pre></div>
<p>At this point, we should be able to see the high/low signal on the multimeter,
alternating between 3.3V (high) and 0V (low) every 5 seconds:</p>
<p><a href="/img/2020-06-15-gpio.jpg"><img src="/img/2020-06-15-gpio.thumb.jpg" srcset="/img/2020-06-15-gpio.thumb.2x.jpg 2x,/img/2020-06-15-gpio.thumb.3x.jpg 3x" width="700" style="border: 1px solid grey; margin-bottom: 2em; margin-top: 1em"></a></p>
<h2 id="setting-up-an-input-pin">Setting up an input pin<span class="btn cstyle anchor copyanchor scrollanchor link noborder notitle interactive"><button type="button" title="Copy link to clipboard"><i class="fa-fw fas fa-link fa-lg"></i></button></span></h2>
<p>To setup a Pin as an input and to act on change to High level, such as a button,
we must poll the Pin periodically because <a href="http://periph.io/" rel="external">periph.ios</a> edge
detection, which examples like the
<a href="https://periph.io/device/button/" rel="external">periph.io/device/button example</a> rely on,
<a href="https://github.com/gokrazy/gokrazy/issues/233" rel="external">is not available on gokrazy</a>.</p>
<p>The below example configures a single Pin for Input and uses Go channels to
signal level changes that can be acted on. Keep in mind that shortening the
polling interval will increase CPU usage.</p>
<div class="highlight actionbar-wrapper wrap-code" dir="auto"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#f92672">package</span> <span style="color:#a6e22e">main</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> (
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;log&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;time&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;periph.io/x/conn/v3/gpio&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;periph.io/x/conn/v3/gpio/gpioreg&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">host</span> <span style="color:#e6db74">&#34;periph.io/x/host/v3&#34;</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">type</span> <span style="color:#a6e22e">pinLevelMessage</span> <span style="color:#66d9ef">struct</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">State</span> <span style="color:#a6e22e">gpio</span>.<span style="color:#a6e22e">Level</span>
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">Reset</span> <span style="color:#a6e22e">gpio</span>.<span style="color:#a6e22e">Level</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">setupGPIOInput</span>(<span style="color:#a6e22e">pinName</span> <span style="color:#66d9ef">string</span>, <span style="color:#a6e22e">levelChan</span> <span style="color:#66d9ef">chan</span> <span style="color:#a6e22e">pinLevelMessage</span>) (<span style="color:#a6e22e">gpio</span>.<span style="color:#a6e22e">PinIO</span>, <span style="color:#66d9ef">error</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">log</span>.<span style="color:#a6e22e">Printf</span>(<span style="color:#e6db74">&#34;Loading periph.io drivers&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">host</span>.<span style="color:#a6e22e">Init</span>(); <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>, <span style="color:#a6e22e">err</span>
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#75715e">// Find Pin by name</span>
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">p</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">gpioreg</span>.<span style="color:#a6e22e">ByName</span>(<span style="color:#a6e22e">pinName</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#75715e">// Configure Pin for input, configure pull as needed</span>
</span></span><span style="display:flex;"><span> <span style="color:#75715e">// Edge mode is currently not supported</span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">p</span>.<span style="color:#a6e22e">In</span>(<span style="color:#a6e22e">gpio</span>.<span style="color:#a6e22e">PullNoChange</span>, <span style="color:#a6e22e">gpio</span>.<span style="color:#a6e22e">NoEdge</span>); <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>, <span style="color:#a6e22e">err</span>
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#75715e">// Setup Input signalling</span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">go</span> <span style="color:#66d9ef">func</span>() {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">lastLevel</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">p</span>.<span style="color:#a6e22e">Read</span>()
</span></span><span style="display:flex;"><span> <span style="color:#75715e">// How often to poll levels, 100-150ms is fairly responsive unless</span>
</span></span><span style="display:flex;"><span> <span style="color:#75715e">// button presses are very fast.</span>
</span></span><span style="display:flex;"><span> <span style="color:#75715e">// Shortening the polling interval &lt;100ms significantly increases</span>
</span></span><span style="display:flex;"><span> <span style="color:#75715e">// CPU load.</span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">for</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">time</span>.<span style="color:#a6e22e">Tick</span>(<span style="color:#ae81ff">100</span> <span style="color:#f92672">*</span> <span style="color:#a6e22e">time</span>.<span style="color:#a6e22e">Millisecond</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">currentLevel</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">p</span>.<span style="color:#a6e22e">Read</span>()
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">log</span>.<span style="color:#a6e22e">Printf</span>(<span style="color:#e6db74">&#34;level: %v&#34;</span>, <span style="color:#a6e22e">currentLevel</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">currentLevel</span> <span style="color:#f92672">!=</span> <span style="color:#a6e22e">lastLevel</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">levelChan</span> <span style="color:#f92672">&lt;-</span> <span style="color:#a6e22e">pinLevelMessage</span>{<span style="color:#a6e22e">State</span>: <span style="color:#a6e22e">currentLevel</span>, <span style="color:#a6e22e">Reset</span>: !<span style="color:#a6e22e">currentLevel</span>}
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">lastLevel</span> = <span style="color:#a6e22e">currentLevel</span>
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> }()
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">p</span>, <span style="color:#66d9ef">nil</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span> <span style="color:#75715e">// Channel for communicating Pin levels</span>
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">levelChan</span> <span style="color:#f92672">:=</span> make(<span style="color:#66d9ef">chan</span> <span style="color:#a6e22e">pinLevelMessage</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">p</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">setupGPIOInput</span>(<span style="color:#e6db74">&#34;GPIO4&#34;</span>, <span style="color:#a6e22e">levelChan</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">log</span>.<span style="color:#a6e22e">Fatal</span>(<span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#75715e">// Main loop, act on level changes</span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">for</span> {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">select</span> {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">case</span> <span style="color:#a6e22e">msg</span> <span style="color:#f92672">:=</span> <span style="color:#f92672">&lt;-</span><span style="color:#a6e22e">levelChan</span>:
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">msg</span>.<span style="color:#a6e22e">State</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">log</span>.<span style="color:#a6e22e">Printf</span>(<span style="color:#e6db74">&#34;Pin %s is High, processing high state tasks&#34;</span>, <span style="color:#a6e22e">p</span>.<span style="color:#a6e22e">Name</span>())
</span></span><span style="display:flex;"><span> <span style="color:#75715e">// Process high state tasks</span>
</span></span><span style="display:flex;"><span> } <span style="color:#66d9ef">else</span> <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">msg</span>.<span style="color:#a6e22e">Reset</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">log</span>.<span style="color:#a6e22e">Printf</span>(<span style="color:#e6db74">&#34;Pin %s is Low, resetting to wait for high state&#34;</span>, <span style="color:#a6e22e">p</span>.<span style="color:#a6e22e">Name</span>())
</span></span><span style="display:flex;"><span> <span style="color:#75715e">// Process resetting logic, if any</span>
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">default</span>:
</span></span><span style="display:flex;"><span> <span style="color:#75715e">// Any other ongoing tasks</span>
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>}</span></span></code></pre></div>
<footer class="footline">
</footer>
</article>
</div>
</main>
</div>
<aside id="R-sidebar" class="default-animation">
<div id="R-header-topbar" class="default-animation"></div>
<div id="R-header-wrapper" class="default-animation">
<div id="R-header" class="default-animation">
<img src="/logo.svg" width="100%" alt="gokrazy logo" title="gokrazy logo">
</div>
<search><form action="/search/index.html" method="get">
<div class="searchbox default-animation">
<button class="search-detail" type="submit" title="Search (CTRL+ALT+f)"><i class="fas fa-search"></i></button>
<label class="a11y-only" for="R-search-by">Search</label>
<input data-search-input id="R-search-by" name="search-by" class="search-by" type="search" placeholder="Search...">
<button class="search-clear" type="button" data-search-clear="" title="Clear search"><i class="fas fa-times" title="Clear search"></i></button>
</div>
</form></search>
</div>
<div id="R-homelinks" class="default-animation homelinks">
<div class="R-menu-divider default-animation">
<hr class="padding">
</div>
<div class="R-sidebarmenu R-shortcutmenu-homelinks">
<ul class="space collapsible-menu">
<li class="" data-nav-url="/index.html"><a class="padding" href="/index.html"><i class="fa-fw fas fa-home"></i> Home</a></li>
</ul>
</div>
<div class="R-menu-divider default-animation">
<hr class="padding">
</div>
<div class="R-sidebarmenu R-shortcutmenu-headercontrols">
<ul class="">
</ul>
</div>
<div class="R-menu-divider default-animation">
<hr class="padding">
</div>
</div>
<div id="R-content-wrapper" class="highlightable">
<div class="R-sidebarmenu R-shortcutmenu-main">
<ul class="enlarge morespace collapsible-menu">
<li class="" data-nav-url="/quickstart/index.html"><a class="padding" href="/quickstart/index.html"><b>1. </b>Quickstart</a></li>
<li class="" data-nav-url="/platforms/index.html"><a class="padding" href="/platforms/index.html"><b>2. </b>Supported platforms</a></li>
<li class="" data-nav-url="/userguide/index.html"><a class="padding" href="/userguide/index.html"><b>3. </b>Configuration</a><ul id="R-subsections-74b4df3a3d9365853f09e9f1dfe7bbba" class="collapsible-menu"></ul></li>
<li class="" data-nav-url="/packages/index.html"><a class="padding" href="/packages/index.html"><b>4. </b>Available packages</a><ul id="R-subsections-bdf1e8ce92aa8ff6883c617f10480430" class="collapsible-menu"></ul></li>
<li class="parent " data-nav-url="/development/index.html"><a class="padding" href="/development/index.html"><b>5. </b>Package development</a><ul id="R-subsections-54b0ce3c97b111c8cd4d107325fd580c" class="collapsible-menu">
<li class="" data-nav-url="/development/process-interface/index.html"><a class="padding" href="/development/process-interface/index.html">Process interface / requirements</a></li>
<li class="active " data-nav-url="/development/gpio/index.html"><a class="padding" href="/development/gpio/index.html">Controlling a GPIO input/output pin</a></li>
<li class="" data-nav-url="/development/modules/index.html"><a class="padding" href="/development/modules/index.html">Working with Go modules</a></li>
<li class="" data-nav-url="/development/buildtags/index.html"><a class="padding" href="/development/buildtags/index.html">The gokrazy Go build tag</a></li>
<li class="" data-nav-url="/development/non-go/index.html"><a class="padding" href="/development/non-go/index.html">Non-Go Prototyping</a></li></ul></li>
</ul>
</div>
<div class="R-sidebarmenu R-shortcutmenu-shortcuts">
<div class="nav-title padding">More</div>
<ul class="space collapsible-menu">
<li class="" data-nav-url="https://github.com/gokrazy/gokrazy"><a class="padding" href="https://github.com/gokrazy/gokrazy" rel="external"><i class='fab fa-github'></i> GitHub repo</a></li>
</ul>
</div>
<div id="R-footer-margin"></div>
<div class="R-menu-divider default-animation">
<hr class="padding">
</div>
<div class="R-sidebarmenu R-shortcutmenu-footercontrols">
<ul class="">
</ul>
</div>
<div id="R-footer"><p>Built with <a href="https://github.com/McShelby/hugo-theme-relearn" title="love"><i class="fas fa-heart"></i></a> by <a href="https://gohugo.io/">Hugo</a></p></div>
</div>
</aside>
<script src="/js/perfect-scrollbar/perfect-scrollbar.min.js?1782408721" defer></script>
<script src="/js/theme.min.js?1782408721" defer></script>
<div id="toast-container" role="status" aria-live="polite" aria-atomic="false"></div>
</body>
</html>