├── .gitignore ├── LICENSE ├── README.md ├── Makefile └── src ├── wiringPi-help.pd └── pdwiringPi.c /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Libraries 12 | *.lib 13 | *.a 14 | *.la 15 | *.lo 16 | 17 | # Shared objects (inc. Windows DLLs) 18 | *.dll 19 | *.so 20 | *.so.* 21 | *.dylib 22 | 23 | # Executables 24 | *.exe 25 | *.out 26 | *.app 27 | *.i*86 28 | *.x86_64 29 | *.hex 30 | 31 | # Python compiled objects 32 | *.pyc 33 | 34 | # Compiled Pd externals 35 | *.pd_linux 36 | 37 | # Build directory 38 | pdwiringPi/ 39 | 40 | # Other cruft 41 | .DS_Store 42 | *~ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, garthz 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of pdpython nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | pdwiringPi 2 | ========= 3 | 4 | This repository contains an 'external' (plugin) for [Pure 5 | Data](http://puredata.info) to communicate with hardware on a Raspberry Pi using 6 | the [wiringPi library](http://wiringpi.com). 7 | 8 | This code should be assumed to be alpha-quality, it has been minimally tested 9 | but is under active development. 10 | 11 | The main [wiringPi] object can act either as a generic wrapper for the library 12 | or can be bound to a specific I/O pin. In the pin-specific mode, a [bang] input 13 | will read the pin and a numeric input will change the pin state. In the generic 14 | mode, messages on the input are interpreted as function calls and are mapped to 15 | the supported library API calls. 16 | 17 | If pd is run as root (e.g. using sudo), then the object uses the direct hardware 18 | API which is faster and more versatile. Without root permission, the object 19 | falls back to the slower and less capable /sys/class/gpio interface. 20 | 21 | The object assumes that the wiringPi installation includes the 'gpio' program 22 | and will run it using system() if needed. 23 | 24 | Compiling 25 | --------- 26 | 27 | System requirements: make, a C compiler, a Pd installation, and wiringPi. 28 | 29 | A simple Makefile is provided for compiling directly on a Raspberry Pi: 30 | 31 | make 32 | 33 | Installation 34 | ------------ 35 | 36 | There are two files to be installed: 37 | 38 | 1. the loadable module: wiringPi.pd_linux 39 | 2. wiringPi-help.pd 40 | 41 | If compiled in-place, the build folder named pdwiringPi/ can simply be added to 42 | the pd load path. Or these files can be copied to an existing pd externals 43 | folder such as /usr/local/lib/pd-externals. 44 | 45 | 46 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # -*- mode: makefile; -*- 2 | # Makefile - build control for the pdwiringPi external for the Raspberry Pi. 3 | # Copyright (c) 2014, Garth Zeglin. All rights reserved. Provided under the terms of the BSD 3-clause license. 4 | 5 | # ---- user-customizable settings ---------------------------------- 6 | 7 | # Configure the include path for Pure Data. Under Debian or Ubuntu, the pd 8 | # include files can be found on the standard system include path. 9 | 10 | PD_INCLUDE_PATH=/usr/include 11 | 12 | # Configure to compile and link against the default WiringPi 13 | # system, assumed to be installed in /usr/local. 14 | 15 | WIRINGPI_CFLAGS := -I/usr/local/include 16 | WIRINGPI_LDFLAGS := -L/usr/local/lib -lwiringPi 17 | 18 | # ---- The following settings do not usually need to be changed ---- 19 | 20 | # Specify the extension to use for the loadable module. 21 | EXTERNALS_EXT = pd_linux 22 | 23 | # Specify a folder to hold the compiled binary Pd loadable modules. 24 | EXTERNALS_DIR = pdwiringPi 25 | 26 | # Specify the default targets to build. 27 | default: $(EXTERNALS_DIR) $(EXTERNALS_DIR)/wiringPi.$(EXTERNALS_EXT) $(EXTERNALS_DIR)/wiringPi-help.pd 28 | 29 | # Create the target folder if it doesn't exist. 30 | $(EXTERNALS_DIR): 31 | mkdir $(EXTERNALS_DIR) 32 | 33 | # Define the compile and link flags for producing a loadable module. 34 | MODULE_CFLAGS = -fPIC -shared -I$(PD_INCLUDE_PATH) 35 | 36 | # Build the loadable module 37 | $(EXTERNALS_DIR)/wiringPi.$(EXTERNALS_EXT): src/pdwiringPi.c 38 | $(CC) $(MODULE_CFLAGS) $^ -o $@ $(WIRINGPI_CFLAGS) $(WIRINGPI_LDFLAGS) 39 | 40 | # Copy over the help patch. 41 | $(EXTERNALS_DIR)/wiringPi-help.pd: src/wiringPi-help.pd 42 | cp $< $@ 43 | 44 | # Target to clean up the build folder. 45 | clean: $(EXTERNALS_DIR) 46 | -rm -r $(EXTERNALS_DIR)/* 47 | -------------------------------------------------------------------------------- /src/wiringPi-help.pd: -------------------------------------------------------------------------------- 1 | #N canvas 583 51 712 695 10; 2 | #X obj 543 674 wiringPi; 3 | #X obj 541 632 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 4 | -1 -1; 5 | #X obj 543 704 print; 6 | #X obj 20 253 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 7 | -1; 8 | #X obj 20 277 wiringPi pin 20 input; 9 | #X obj 394 303 wiringPi pin 21 output; 10 | #X obj 394 278 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 11 | 1; 12 | #X text 43 253 BCM 20 \, physical 38 \, wPi 28; 13 | #X text 411 277 BCM 21 \, physical 40 \, wPi 29; 14 | #X msg 23 413 digitalRead 20; 15 | #X msg 39 460 digitalWrite 21 1; 16 | #X msg 308 472 pwmWrite 18 513; 17 | #X msg 301 448 pinMode 18 pwm_output; 18 | #X msg 30 629 wpiPinToGpio 1; 19 | #X msg 38 653 physPinToGpio 12; 20 | #X msg 24 606 piBoardRev; 21 | #X obj 10 9 cnv 15 600 200 empty empty wiringPi 20 12 0 14 -204800 22 | -66577 0; 23 | #X text 112 40 Copyright (c) 2014 \, Garth Zeglin. Provided under the 24 | terms of the 3-clause BSD license.; 25 | #X text 112 10 External for wiringPi to interface to hardware I/O on 26 | a Raspberry Pi.; 27 | #X text 112 70 The wiringPi object can be specialized using optional 28 | creation arguments. The generic mode accepts messages related to the 29 | wiringPi API. The pin-specific mode associates an object with a specific 30 | pin.; 31 | #X text 112 126 If pd is running with root permissions \, the interface 32 | uses the fast direct hardware access. Without root permission \, the 33 | fallback path uses the slower and less capable /sys/class/gpio interface. 34 | ; 35 | #X text 18 217 Pin-specific input object. The pin numbering scheme 36 | follows the Broadcom GPIO numbers.; 37 | #X floatatom 26 307 5 0 0 0 - - -; 38 | #X obj 20 333 print input-20; 39 | #X text 114 186 Example physical pins are for a Raspberry Pi B+; 40 | #X text 389 258 Pin-specific output object.; 41 | #X obj 42 685 wiringPi; 42 | #X obj 42 712 print pi-info; 43 | #X text 4 586 Informational queries; 44 | #X text 27 760 still under development; 45 | #X text 21 388 Generic object accepting general I/O messages.; 46 | #X msg 31 436 pinMode 21 output; 47 | #X obj 47 505 wiringPi; 48 | #X obj 47 531 print general-IO; 49 | #X text 545 601 Disallowed; 50 | #X obj 564 632 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 51 | 1; 52 | #X floatatom 586 632 5 0 0 0 - - -; 53 | #X text 301 422 PWM mode only works on specific GPIO pins.; 54 | #X obj 480 449 hsl 128 15 0 1024 0 0 empty empty empty -2 -8 0 10 -262144 55 | -1 -1 0 1; 56 | #X obj 477 495 wiringPi pin 18 pwm_output; 57 | #X obj 311 498 wiringPi; 58 | #X text 339 515 generic version; 59 | #X text 493 516 pin-specific version; 60 | #X text 99 606 board revision number; 61 | #X text 133 630 GPIO pin corresponding to wiringPi pin convention; 62 | #X text 156 653 GPIO pin corresponding to physical pin number; 63 | #X text 488 478 BCM 18 \, physical 12 \, wPi 1; 64 | #X msg 45 482 digitalRead 21; 65 | #X text 310 537 (default PWM period measured at 3.4uSec on RPi B+) 66 | ; 67 | #X msg 52 809 spi_init 0 1e+06; 68 | #X obj 56 836 wiringPi; 69 | #X msg 44 784 load_spi_driver; 70 | #X connect 0 0 2 0; 71 | #X connect 1 0 0 0; 72 | #X connect 3 0 4 0; 73 | #X connect 4 0 22 0; 74 | #X connect 4 0 23 0; 75 | #X connect 6 0 5 0; 76 | #X connect 9 0 32 0; 77 | #X connect 10 0 32 0; 78 | #X connect 11 0 40 0; 79 | #X connect 12 0 40 0; 80 | #X connect 13 0 26 0; 81 | #X connect 14 0 26 0; 82 | #X connect 15 0 26 0; 83 | #X connect 26 0 27 0; 84 | #X connect 31 0 32 0; 85 | #X connect 32 0 33 0; 86 | #X connect 35 0 0 0; 87 | #X connect 36 0 0 0; 88 | #X connect 38 0 39 0; 89 | #X connect 47 0 32 0; 90 | #X connect 49 0 50 0; 91 | #X connect 51 0 50 0; 92 | -------------------------------------------------------------------------------- /src/pdwiringPi.c: -------------------------------------------------------------------------------- 1 | /// pdwiringPi.c : Pd external to communicate with hardware on a Raspberry Pi using wiringPi 2 | /// Copyright (c) 2014, Garth Zeglin. All rights reserved. Provided under the 3 | /// terms of the BSD 3-clause license. 4 | 5 | /****************************************************************/ 6 | // Links to related reference documentation: 7 | 8 | // Pd externals: http://pdstatic.iem.at/externals-HOWTO/node9.html 9 | // wiringPi: http://wiringpi.com 10 | 11 | /****************************************************************/ 12 | // import standard libc API 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | // Import the API for Pd externals. This is provided by the Pd installation, 19 | // and this may require manually configuring the Pd include path in the 20 | // Makefile. 21 | #include "m_pd.h" 22 | 23 | // Import the wiringPi API. 24 | #include 25 | #include 26 | 27 | /****************************************************************/ 28 | /// There is only one wiringPi interface, so the underlying 29 | /// hardware state is stored globally to be referenced by any 30 | /// wiringPi object. 31 | static int sys_mode = 0; ///< flag to indicate initialization with wiringPiSetupSys 32 | 33 | /****************************************************************/ 34 | /// Data structure to hold the state of a single Pd 'wiringPi' object. 35 | typedef struct pdwiringPi 36 | { 37 | t_object x_ob; ///< standard object header 38 | t_outlet *x_outlet; ///< the outlet is the port on which return values are transmitted 39 | 40 | int pin; ///< a non-negative pin number if initalized to control a single pin 41 | int mode; ///< pin mode value if initialized to control a single pin 42 | 43 | int spi_channel; ///< SPI channel number, or -1 if not in SPI mode 44 | int spi_speed; ///< SPI speed in Hz, or -1 if not in SPI mode 45 | int spi_fd; ///< SPI file descriptor, or -1 if not in SPI mode 46 | 47 | } t_pdwiringPi; 48 | 49 | static t_class *pdwiringPi_class; 50 | 51 | /****************************************************************/ 52 | // Utility functions. 53 | static int atom_matches( t_atom *atom, char *symbol ) 54 | { 55 | return ( (atom->a_type == A_SYMBOL) 56 | && !strcmp( atom->a_w.w_symbol->s_name, symbol ) ); 57 | } 58 | 59 | static inline int symbol_matches( t_symbol *sym, char *symbol ) 60 | { 61 | return !strcmp( sym->s_name, symbol ); 62 | } 63 | 64 | /****************************************************************/ 65 | // Map a symbol representing a pin mode to the numeric constant. 66 | static int atom_to_pin_mode( t_atom *s_mode ) 67 | { 68 | int value = INPUT; 69 | if ( atom_matches( s_mode, "output" )) value = OUTPUT; 70 | else if ( atom_matches( s_mode, "pwm_output" )) value = PWM_OUTPUT; 71 | else if ( atom_matches( s_mode, "gpio_clock" )) value = GPIO_CLOCK; 72 | else if ( atom_matches( s_mode, "input" )) value = INPUT; 73 | else post ("wiringPi: unrecognized pin mode symbol, assuming INPUT."); 74 | return value; 75 | } 76 | 77 | /****************************************************************/ 78 | // A bang is always interpreted as a type of read for pin-specific instances. 79 | static void pdwiringPi_bang( t_pdwiringPi *x ) 80 | { 81 | if ( x->pin >= 0 ) { 82 | int value = digitalRead( x->pin ); 83 | outlet_float( x->x_outlet, value ); 84 | return; 85 | 86 | } else { 87 | post("wiringPi: bang not allowed for non-pin-specific instances."); 88 | } 89 | } 90 | /****************************************************************/ 91 | // A float is always interpreted as a type of write for pin-specific instances. 92 | static void pdwiringPi_float( t_pdwiringPi *x, float value ) 93 | { 94 | // if a pin-specific instance 95 | if ( x->pin >= 0 ) { 96 | 97 | // pwm output mode 98 | if (x->mode == PWM_OUTPUT) { 99 | // "The Raspberry Pi has one on-board PWM pin, pin 1 (BMC_GPIO 18, Phys 12) 100 | // and the range is 0-1024." 101 | pwmWrite( x->pin, (int) value ); 102 | if (sys_mode) post("wiringPi: Warning, pwmWrite has no effect in Sys mode."); 103 | } 104 | // else assume it is a digital output 105 | else { 106 | digitalWrite( x->pin, (int) value ); 107 | } 108 | } else { 109 | post("wiringPi: float not allowed for non-pin-specific instances."); 110 | } 111 | } 112 | 113 | // still need to add SPI I/O 114 | // int wiringPiSPIDataRW (int channel, unsigned char *data, int len) ; 115 | 116 | /****************************************************************/ 117 | // Abstract the difference between the Sys and Gpio initialization modes. 118 | static void set_pin_mode( int pin, int mode ) 119 | { 120 | if (sys_mode) { 121 | if (mode == INPUT || mode == OUTPUT) { 122 | char *command; 123 | asprintf( &command, "gpio export %d %s", pin, (mode==INPUT) ? "in" : "out" ); 124 | post("wiringPi in Sys mode: running '%s'", command ); 125 | system(command); 126 | free(command); 127 | } else { 128 | post("wiringPi: error, cannot set mode %d on pin %d in Sys mode.", mode, pin ); 129 | } 130 | } else { 131 | pinMode( pin, mode ); 132 | } 133 | } 134 | 135 | /****************************************************************/ 136 | /// Process a list representing a function call or more elaborate I/O command. 137 | 138 | static void pdwiringPi_eval( t_pdwiringPi *x, t_symbol *selector, int argcount, t_atom *argvec ) 139 | { 140 | // post ("pdwiringPi_eval called with %d args, selector %s\n", argcount, selector->s_name ); 141 | 142 | if (x->pin >= 0) { 143 | post("wiringPi: general input not allowed for pin-specific instances."); 144 | return; 145 | } 146 | 147 | // test for a variety of function call forms 148 | if ( symbol_matches( selector, "digitalRead" ) && argcount == 1) { 149 | outlet_float( x->x_outlet, (float) digitalRead( atom_getint( &argvec[0] ))); 150 | return; 151 | 152 | } else if ( symbol_matches( selector, "digitalWrite" ) && argcount == 2) { 153 | digitalWrite( atom_getint(&argvec[0]), atom_getint(&argvec[1]) ); 154 | return; 155 | 156 | } else if ( symbol_matches( selector, "pwmWrite" ) && argcount == 2) { 157 | // "The Raspberry Pi has one on-board PWM pin, pin 1 (BMC_GPIO 18, Phys 12) 158 | // and the range is 0-1024." 159 | pwmWrite( atom_getint(&argvec[0]), atom_getint(&argvec[1]) ); 160 | if (sys_mode) post("wiringPi: Warning, pwmWrite has no effect in Sys mode."); 161 | return; 162 | 163 | } else if ( symbol_matches( selector, "pinMode" ) && argcount == 2) { 164 | int mode = atom_to_pin_mode( &argvec[1] ); 165 | set_pin_mode( atom_getint(&argvec[0]), mode ); 166 | return; 167 | 168 | } else if ( symbol_matches( selector, "wpiPinToGpio" ) && argcount == 1) { 169 | outlet_float( x->x_outlet, (float) wpiPinToGpio( atom_getint(&argvec[0]) )); 170 | return; 171 | 172 | } else if ( symbol_matches( selector, "physPinToGpio" ) && argcount == 1) { 173 | outlet_float( x->x_outlet, (float) physPinToGpio( atom_getint(&argvec[0]) )); 174 | return; 175 | 176 | } else if ( symbol_matches( selector, "piBoardRev" ) && argcount == 0) { 177 | outlet_float( x->x_outlet, (float) piBoardRev() ); 178 | return; 179 | 180 | } else if ( symbol_matches( selector, "load_spi_driver" ) && argcount == 0) { 181 | char *command = "gpio load spi"; 182 | post("wiringPi: running '%s' to make sure SPI drivers are loaded.", command ); 183 | system(command); 184 | return; 185 | 186 | } else if ( symbol_matches( selector, "spi_init" )) { 187 | // specialize an object instance to represent an SPI port 188 | // [ spi_init ] 189 | if (argcount == 2) { 190 | x->spi_channel = atom_getint( &argvec[0] ); 191 | x->spi_speed = atom_getint( &argvec[1] ); 192 | x->spi_fd = wiringPiSPISetup ( x->spi_channel, x->spi_speed); 193 | if (x->spi_fd == -1) { 194 | post("wiringPiSPISetup returned error %d.", errno ); 195 | } else { 196 | post("wiringPi: opened SPI channel %d at speed %d.", x->spi_channel, x->spi_speed); 197 | } 198 | } else { 199 | post("wiringPi error: spi_init requires channel and speed values."); 200 | } 201 | 202 | } else { 203 | post("wiringPi: unrecognized input for selector %s.", selector->s_name ); 204 | } 205 | } 206 | 207 | /****************************************************************/ 208 | /// Create an instance of a Pd 'wiringPi' object. 209 | /// 210 | /// The creation arguments are all optional and are interpreted as follows: 211 | /// [ wiringPi pin ] make instance pin-specific 212 | 213 | static void *pdwiringPi_new(t_symbol *selector, int argcount, t_atom *argvec) 214 | { 215 | t_pdwiringPi *x = (t_pdwiringPi *) pd_new(pdwiringPi_class); 216 | 217 | // initialize default values for a generic instance 218 | x->pin = -1; 219 | x->mode = 0; 220 | 221 | x->spi_channel = -1; 222 | x->spi_speed = -1; 223 | x->spi_fd = -1; 224 | 225 | if (argcount > 0) { 226 | // check the initial creation argument 227 | t_atom *arg0 = &argvec[0]; 228 | 229 | // define the object instance as 'pin-specific' representing a single pin 230 | if ( atom_matches( arg0, "pin" )) { 231 | // "Note that only wiringPi pin 1 (BCM_GPIO 18) supports PWM output and 232 | // only wiringPi pin 7 (BCM_GPIO 4) supports CLOCK output modes." 233 | 234 | if (argcount == 3 ) { 235 | x->pin = atom_getint( &argvec[1] ); 236 | x->mode = atom_to_pin_mode( &argvec[2] ); 237 | set_pin_mode( x->pin, x->mode ); 238 | // post("Initialized wiringPi object for pin %d in mode %d.", x->pin, x->mode ); 239 | 240 | } else { 241 | post("wiringPi: incorrect number of creation arguments for pin."); 242 | } 243 | } else { 244 | post("wiringPi: unrecognized creation arguments."); 245 | } 246 | } 247 | 248 | // create an outlet on which to return values 249 | x->x_outlet = outlet_new( &x->x_ob, NULL ); 250 | return (void *)x; 251 | } 252 | 253 | /****************************************************************/ 254 | /// Release an instance of a Pd 'wiringPi' object. 255 | static void pdwiringPi_free(t_pdwiringPi *x) 256 | { 257 | if (x) { 258 | outlet_free( x->x_outlet ); 259 | x->x_outlet = NULL; 260 | } 261 | } 262 | 263 | /****************************************************************/ 264 | /// Initialization entry point for the Pd 'wiringPi' external. This is 265 | /// automatically called by Pd after loading the dynamic module to initialize 266 | /// the class interface. 267 | void wiringPi_setup(void) 268 | { 269 | // specify "A_GIMME" as creation argument for both the creation 270 | // routine and the method (callback) for the "eval" message. 271 | 272 | pdwiringPi_class = class_new( gensym("wiringPi"), // t_symbol *name 273 | (t_newmethod) pdwiringPi_new, // t_newmethod newmethod 274 | (t_method) pdwiringPi_free, // t_method freemethod 275 | sizeof(t_pdwiringPi), // size_t size 276 | 0, // int flags 277 | A_GIMME, 0); // t_atomtype arg1, ... 278 | 279 | // instances specialized to specific pins can accept bangs and floats 280 | class_addbang ( pdwiringPi_class, pdwiringPi_bang ); // t_class *c, t_method fn 281 | class_addfloat( pdwiringPi_class, pdwiringPi_float ); // t_class *c, t_method fn 282 | 283 | // general inputs represent function calls and more elaborate I/O operations 284 | class_addanything( pdwiringPi_class, (t_method) pdwiringPi_eval ); // (t_class *c, t_method fn) 285 | 286 | // static initialization follows 287 | if (geteuid() == 0) { 288 | wiringPiSetupGpio(); 289 | sys_mode = 0; 290 | post("Initializing wiringPi in Gpio mode to use direct hardware access.\nUsing Broadcom GPIO pin numbering scheme."); 291 | 292 | } else { 293 | wiringPiSetupSys(); 294 | sys_mode = 1; 295 | post("Warning: initializing wiringPi in Sys mode to use /sys/class/gpio interface.\nFor a faster interface, relaunch pd as root.\nUsing Broadcom GPIO pin numbering scheme."); 296 | } 297 | 298 | } 299 | 300 | /****************************************************************/ 301 | --------------------------------------------------------------------------------