conn icon indicating copy to clipboard operation
conn copied to clipboard

Unable to read output pin state.

Open larsks opened this issue 5 months ago • 2 comments

Describe the bug

I am unable to successfully read the output state of a GPIO pin on a raspberry pi 3.

To Reproduce

Here's some sample code that reproduces the problem:

package main

import (
	"fmt"
	"log"
	"time"

	"periph.io/x/conn/v3/gpio"
	"periph.io/x/conn/v3/gpio/gpioreg"
	"periph.io/x/host/v3"
)

func main() {
	// Initialize periph
	if _, err := host.Init(); err != nil {
		log.Fatal(err)
	}

	// Get GPIO pin 23
	pin := gpioreg.ByName("23")
	if pin == nil {
		log.Fatal("Pin 23 not found")
	}

	// Set pin as output
	if err := pin.Out(gpio.Low); err != nil {
		log.Fatal(err)
	}

	// Set pin to high
	if err := pin.Out(gpio.High); err != nil {
		log.Fatal(err)
	}

	// Read value
	v := pin.Read()
	fmt.Printf("Set to high, read: %v\n", v)
	if v != gpio.High {
		log.Fatal("Expected high, got low")
	}

	time.Sleep(1 * time.Second)

	// Set pin to low
	if err := pin.Out(gpio.Low); err != nil {
		log.Fatal(err)
	}

	// Debug: check pin function
	fmt.Printf("Pin function: %s\n", pin.Function())

	// Read value
	v = pin.Read()
	fmt.Printf("Set to low, read: %v\n", v)
	
	// Try a small delay before reading
	time.Sleep(10 * time.Millisecond)
	v2 := pin.Read()
	fmt.Printf("After delay, read: %v\n", v2)
	
	if v != gpio.Low {
		log.Fatal("Expected low, got high")
	}

	time.Sleep(1 * time.Second)

	// Set pin to high again
	if err := pin.Out(gpio.High); err != nil {
		log.Fatal(err)
	}

	// Read value
	v = pin.Read()
	fmt.Printf("Set to high, read: %v\n", v)
	if v != gpio.High {
		log.Fatal("Expected high, got low")
	}

	fmt.Println("GPIO test completed successfully")
}

This fails with:

Set to high, read: High
Pin function: Out/High
Set to low, read: High
After delay, read: High
2025/07/18 13:49:26 Expected low, got high

On the other hand, the following Python code using the gpiod module works as expected:

import time
import gpiod

chip = gpiod.Chip('0')
switch = chip.get_line(23)
switch.request(consumer="testing", type=gpiod.LINE_REQ_DIR_OUT)

switch.set_value(1)
v = switch.get_value()
assert v == 1
time.sleep(1)

switch.set_value(0)
v = switch.get_value()
assert v == 0
time.sleep(1)

switch.set_value(1)
v = switch.get_value()
assert v == 1

This makes me believe the issue is with periph rather than with the hardware.

Expected behavior

I expect pin.Read() to accurately return the state of an output pin.

Platform (please complete the following information):

  • OS: Raspbian GNU/Linux 12 (bookworm)
  • Board: Raspberry Pi 3 Model B Rev 1.2

larsks avatar Jul 18 '25 17:07 larsks