http://chiselapp.com/user/schelte/repository/piio%|%piio%|% by [Schelte Bron] is a library for accessing a couple of the I/O possibilities of the [Raspberry Pi]. The library supports both http://en.wikipedia.org/wiki/GPIO%|%gpio%|% and http://en.wikipedia.org/wiki/I2c%|%i2c%|%. [dzach] 2016-9-5 Looks interesting. I have compiled the library for a Raspberry Pi 3, but have not been able to produce positive results. What is the naming convention for the pins? There seem to exist a number of them. E.g. if I want to use physical pin 11 (pin number on the connector) as an output, should I say: piio function 11 output piio output 11 1 in order to turn on pin#11 ? Could you please post a simple "Hello world" example (e.g. blink)? Thanks! [crshults] 2016-10-01 Take a look at the note on this page: http://elinux.org/RPi_GPIO_Code_Samples "Note: For Raspberry Pi 2, change BCM2708_PERI_BASE to 0x3F000000 for the code to work." [dzach] Thanks for the link! [sbron] 2017-02-05 The library uses the GPIO pin numbering. That way you can also address pins that are not on P1, like P5. It also resolves issues with pins that have changed between hardware revisions, like P1 pin 3 and 5. The image below shows the mapping. So P1 pin 11 is GPIO 17. [http://raspi.tv/wp-content/uploads/2014/07/Raspberry-Pi-GPIO-pinouts-1024x703.png] (Image by http://raspi.tv/2014/rpi-gpio-quick-reference-updated-for-raspberry-pi-b%|%RasPi.TV%|%) ------ A very simple blink example might look like this (LED + resistor connected between P1 pin 39 and 40): ====== package require piio piio function 21 output proc blink {{state 1}} { piio output 21 $state after 500 [list blink [expr {!$state}]] } blink vwait forever ====== ------ [crshults] 2017-02-02 In gpio.c, change "/dev/mem" to "/dev/gpiomem" and you can use the library as a non super user. Your user just has to be in the gpio group. [sbron] 2017-02-05 The latest version will use /dev/gpiomem if available, and fall back to /dev/mem if not. [vh] 2017-03-30 Thanks to a morse code script elsewhere in this wiki, here is a morse code blinky example. ====== # A tcl script to flash morse code on an LED on a Raspberry Pi 3 B+ # 30 March 2017 # Wiring setup: 5mm diameter LED in series with a 330 ohm resistor wired from gpio16 (pin36) to ground (pin34) # morse-code code from: http://wiki.tcl.tk/3371 # turn "on" a gpio pin which has previously been set to output mode proc flash {gpio n} { piio output $gpio 1 pause $n piio output $gpio 0 pause 1 } # A simple pause while running the event loop, in terms of basic time units proc pause n { global t after [expr {$t * $n}] set ok 1 vwait ok } set MORSE_CODE { "!" "---." "\"" ".-..-." "$" "...-..-" "'" ".----." "(" "-.--." ")" "-.--.-" "+" ".-.-." "," "--..--" "-" "-....-" "." ".-.-.-" "/" "-..-." ":" "---..." ";" "-.-.-." "=" "-...-" "?" "..--.." "@" ".--.-." "[" "-.--." "]" "-.--.-" "_" "..--.-" "0" "-----" "1" ".----" "2" "..---" "3" "...--" "4" "....-" "5" "....." "6" "-...." "7" "--..." "8" "---.." "9" "----." "A" ".-" "B" "-..." "C" "-.-." "D" "-.." "E" "." "F" "..-." "G" "--." "H" "...." "I" ".." "J" ".---" "K" "-.-" "L" ".-.." "M" "--" "N" "-." "O" "---" "P" ".--." "Q" "--.-" "R" ".-." "S" "..." "T" "-" "U" "..-" "V" "...-" "W" ".--" "X" "-..-" "Y" "-.--" "Z" "--.." } # The code to translate text to morse code and play it proc morse {gpio str wpm} { global t MORSE_CODE set t [expr {1200 / $wpm}] # Backslash and space are special cases in various ways set map {"\\" {} " " {[pause 4]}} # Append each item in the code to the map, with an inter-letter pause after foreach {from to} $MORSE_CODE {lappend map $from "$to\[pause 3\]"} # Convert to dots and dashes set s [string map $map [string toupper $str]] puts "Morse string: $s" # Play the dots and dashes by substituting commands for them (dash displays for 4 times longer than a dot) # Pauses between flashes has relative length 1 (same length as a dot flash), pause at end of letter = 4 ,pause between words=8 puts "commands to be executed:[string map { "." "[flash $gpio 1]" "-" "[flash $gpio 4]" } $s]" subst [string map { "." "[flash $gpio 1]" "-" "[flash $gpio 4]" } $s] return } # This script requires the piio package (http://chiselapp.com/user/schelte/repository/piio/wiki?name=piio) # You will have to download and follow the instructions to compile before using this package package require piio # prepare the gpio for output set gpio 16 piio function $gpio output set words_per_minute 5 # Translate a text message to morse code flashes morse $gpio "Hello World" $words_per_minute ====== [vh] 15 Apr 2017 - I2C Example: I bought a SenseHat (https://www.raspberrypi.org/products/sense-hat/) from the same place I bought my Raspberry Pi. It has a collection of sensors that communicate over I2C (among other things). This gave me a chance to to experiment and learn how to work the software part of i2c before having to worry about the hardware. The following script iterates over all the available I2C busses, device addresses and device registers to dump out any data it finds. ====== # i2c_dump.tcl # A script to iterate over all i2c busses, addresses and registers in sequence and dump their contents to stdout # vh, 12 Apr 2017 set result [package require piio] puts "package piio loaded: $result" proc scan_i2cbus {bus_low {bus_high ""}} { if {$bus_high == ""} {set bus_high $bus_low} # Iterate over the busses (specified by user) for {set bus $bus_low} {$bus<=$bus_high} {incr bus} { puts "working on bus: $bus" # check all the addresses from zero to 256 for {set address 0} {$address < 256} {incr address} { scan_i2caddress $bus $address } } puts "Scan finished." return } proc scan_i2caddress {bus address} { # puts "working on bus: $bus, address=$address" # if we can get a handle to this address, also search for registers if {![catch {set i2c_h [twowire twowire $bus $address]} err ]} { # puts "found device at address=$address (handle=$i2c_h)" # Check all registers from 0 to 255 for {set register 0} {$register <=256} {incr register} { if {![catch {set value [twowire readregbyte $i2c_h $register]} err ]} { if {$value > 0} { puts "bus=$bus, address=[format %3d $address] (0x[format %2.2X $address]), register=[format %3d $register] (0x[format %2.2X $register]), data byte = [format %4d $value] = 0x[format %2.2X $value] = [format %08b $value]" } else { # We didn't find any data at that register # puts "no data at register value $register (no error)" } } else { # We didn't find any data at that register #puts "no data at register value $register (err=$err)" } } close $i2c_h } return } puts "Scanning all busses, addresses and registers..." scan_i2cbus 0 1 puts "--------------------------" # Scan only one specific address # set bus 1 # set address 92; aka 0x5c # puts "Scanning the bus#$bus, address $address" # scan_i2caddress $bus $address puts "done." ====== ------ <>Hardware