001/* 002 * $Rev: 1005 $: Revision of last commit 003 * $Author: tgutwin $: Author of last commit 004 * $Date: 2015-10-05 12:44:37 -0700 (Mon, 05 Oct 2015) $: Date of last commit 005 * $URL: svn://svn.webarts.bc.ca/open/trunk/projects/WebARTS/raspberry/ca/bc/webarts/raspberry/GpioCycler.java $ 006 * 007 * Written by Tom Gutwin 008 * Copyright (C) 2015 Tom B. Gutwin, North Vancouver BC Canada 009 * 010 * This program is free software; you can redistribute it and/or modify 011 * it under the terms of the GNU General Public License as published by 012 * the Free Software Foundation; either version 3of the License, or 013 * (at your option) any later version. 014 * 015 * This program is distributed in the hope that it will be useful, 016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 018 * GNU General Public License for more details. 019 * 020 * You should have received a copy of the GNU General Public License 021 * along with this program; If not, see <http://www.gnu.org/licenses/>. 022 */ 023 024package ca.bc.webarts.raspberry; 025 026import com.pi4j.io.gpio.GpioController; 027import com.pi4j.io.gpio.GpioFactory; 028import com.pi4j.io.gpio.GpioPinDigitalOutput; 029import com.pi4j.io.gpio.Pin; 030import com.pi4j.io.gpio.PinState; 031import com.pi4j.io.gpio.RaspiPin; 032import com.pi4j.system.SystemInfo; 033 034import ca.bc.webarts.widgets.Util; 035/** 036 * This code demonstrates cycling Raspberry Pi GPIO pins on and off sequentially as an example of how to 037 * perform simple state control of a GPIO pin on the Raspberry Pi. 038 * 039 * It uses the <a href="http://www.pi4j.com">Pi4J library</a>. 040 * 041 * @author <a href="http://red.webarts.bc.ca/roller/tom/en_CA/">Tom Gutwin</a> 042 */ 043public class GpioCycler 044{ 045 /** Class constant for a PI board type A. **/ 046 public static final short BOARD_TYPE_A = 0; 047 /** Class constant for a PI board type A+. **/ 048 public static final short BOARD_TYPE_APLUS = 1; 049 /** Class constant for a PI board type B. **/ 050 public static final short BOARD_TYPE_B = 2; 051 /** Class constant for a PI board type B2. **/ 052 public static final short BOARD_TYPE_B2 = 3; 053 /** Class constant for a PI board type B+. **/ 054 public static final short BOARD_TYPE_BPLUS = 4; 055 /** Class constant for a PI board type Pi2. **/ 056 public static final short BOARD_TYPE_2 = 5; 057 /** Class constant for its DEFAULT PI board type = BOARD_TYPE_2. **/ 058 public static final short DEFAULT_BOARD_TYPE = BOARD_TYPE_2; 059 060 /** The DEFAULT time in milliSeconds the cycle loop should run. **/ 061 public static final int DEFAULT_LOOP_TIME_MS = 20000; 062 063 /** The DEFAULT time in milliSeconds the GPIO will go HIGH. **/ 064 public static final short DEFAULT_CYCLE_TIME_MS = 100; 065 066 /** The DEFAULT time in milliSeconds the <b>next</b> GPIO pin will come on before the previous 067 * one goes LOW. Its the overlap time. **/ 068 public static final short DEFAULT_OVERLAP_TIME_MS = 0; 069 070 /** The default set of pins for a Raspberry Pi Model A or B board that will be controlled. Defaults to all pins. **/ 071 public static final short [] DEFAULT_PIAB_PINS = {0,1,2,3,4,5,6,7,8,9, 072 10,11,12,13,14,15,16}; 073 /** The default set of pins for a Raspberry Pi Model B Plus board that will be controlled. Defaults to all pins. **/ 074 public static final short [] DEFAULT_PIBPLUS_PINS= {0,1,2,3,4,5,6,7,8,9, 075 10,11,12,13,14,15,16, 076 21,22,23,24,25,26,27,28,29}; 077 /** The default set of pins for a Raspberry Pi 2 Model B board that will be controlled. Defaults to all pins. **/ 078 public static final short [] DEFAULT_PI2_PINS = DEFAULT_PIBPLUS_PINS; 079 public static final short [] DEFAULT_PINS = DEFAULT_PI2_PINS; 080 081 /** The default set of pins that will be used / enabled [0-11 are enabled]. **/ 082 public static final boolean [] DEFAULT_ENABLED_PINS = {true,true,true,true,true,true,true,true,true,true,true,true, 083 false,false,false,false,false,false,false,false, 084 false,false,false,false,false,false,false,false,false}; 085 086 /** The default pin to start the cycle from. **/ 087 public static final short DEFAULT_START_PIN = DEFAULT_PINS[0]; 088 /** The default pin to end the cycle from. **/ 089 public static final short DEFAULT_END_PIN = DEFAULT_PINS[DEFAULT_PINS.length-1]; 090 091 /** Default pin state is LOW. **/ 092 public static final PinState DEFAULT_PINSTATE = PinState.LOW; 093 094 095 /** Class var specifying the active board type - it starts as the DEFAULT_BOARD_TYPE. **/ 096 private short boardType = DEFAULT_BOARD_TYPE; 097 /** The time that the whole thing should run/looping back and forth - use -1 to go forever **/ 098 private int loopTime = DEFAULT_LOOP_TIME_MS; 099 /** The duty cycle time in ms that the GPIO will cycle ON. **/ 100 private short cycleTime = DEFAULT_CYCLE_TIME_MS; 101 /** The time in ms that the next GPIO will come ON before the previous one is OFF - 102 * it can be a negative number to specify a delAY. **/ 103 private short overlapTime = DEFAULT_OVERLAP_TIME_MS; 104 /** pins represents the GPIO pin numbers on the board. **/ 105 private short[] pins = DEFAULT_PINS; 106 107 /** The pins that are enabled.**/ 108 private boolean[] enabledPins = DEFAULT_ENABLED_PINS; 109 110 /** The gpioPin number associated with the first enabled GPIO pin that is 1st used in the cycle - zero based. **/ 111 private short startPin = DEFAULT_START_PIN; 112 /** The gpioPin number associated with the last enabled GPIO pin that is LAST used in the cycle - zero based. **/ 113 private short endPin = DEFAULT_END_PIN; 114 /** The usable GPIO pins that will be used by this class - it does NOT get init until provisionPins is called. **/ 115 private GpioPinDigitalOutput[] gpioPins = new GpioPinDigitalOutput[pins.length]; 116 117 /** supervisor class flag to save re-provisioning. **/ 118 private boolean allPinsProvisioned = false; 119 120 /** gpio controller used by all methods in this class. **/ 121 private final GpioController gpio = GpioFactory.getInstance(); 122 123 124 /** constructor **/ 125 public GpioCycler() 126 { 127 try 128 { 129 SystemInfo.BoardType bt = SystemInfo.getBoardType(); 130 if(bt.equals(SystemInfo.BoardType.Model2B_Rev1)) boardType = BOARD_TYPE_2; 131 else if(bt.equals(SystemInfo.BoardType.ModelB_Plus_Rev1)) boardType = BOARD_TYPE_BPLUS; 132 else if(bt.equals(SystemInfo.BoardType.ModelB_Rev2)) boardType = BOARD_TYPE_B; 133 else if(bt.equals(SystemInfo.BoardType.ModelB_Rev1)) boardType = BOARD_TYPE_B2; 134 else if(bt.equals(SystemInfo.BoardType.ModelA_Plus_Rev1)) boardType = BOARD_TYPE_APLUS; 135 else if(bt.equals(SystemInfo.BoardType.ModelA_Rev1)) boardType = BOARD_TYPE_A; 136 else boardType = DEFAULT_BOARD_TYPE; 137 } 138 catch (java.io.IOException ioEx) 139 { 140 boardType = DEFAULT_BOARD_TYPE; 141 } 142 catch (java.lang.InterruptedException iEx) 143 { 144 boardType = DEFAULT_BOARD_TYPE; 145 } 146 } 147 148 149 /** Stop all GPIO activity/threads by shutting down the GPIO controller. 150 * This method will forcefully shutdown all GPIO monitoring threads and scheduled tasks. 151 **/ 152 public void shutdown() 153 { 154 // stop all GPIO activity/threads by shutting down the GPIO controller 155 // (this method will forcefully shutdown all GPIO monitoring threads and scheduled tasks) 156 gpio.shutdown(); 157 158 } 159 160 161 /** 162 * Sets the 3 timing paramets based on optional commandline parameters - passed to this method in args[]. 163 * 164 * @param args is the commandline args array 165 **/ 166 protected void parseCommandlineParms(String [] args) 167 { 168 if (args!=null && args.length >0) 169 { 170 System.out.println(" > Override loopTime="+args[0]); 171 loopTime = Short.parseShort(args[0]); 172 } 173 if (args!=null && args.length >1) 174 { 175 System.out.println(" > Override duty cycleTime="+args[1]); 176 cycleTime = Short.parseShort(args[1]); 177 } 178 if (args!=null && args.length >2) 179 { 180 System.out.println(" > Override overlapTime="+args[2]); 181 overlapTime = Short.parseShort(args[2]); 182 } 183 } 184 185 186 /** Cycles ALL gpio pins on / off 2 times for 500ms each. **/ 187 public void flashAllPins() { flashAllPins((short)2, (short)500); } 188 189 190 /** Cycles ALL gpio pins on / off numFlashes times with a duty time of flashTimeMS . **/ 191 public void flashAllPins(short numFlashes, short flashTimeMS) 192 { 193 if (!allPinsProvisioned) provisionPins(true); 194 //enableAllPin(); 195 for (short flashNum = 0;flashNum<numFlashes;flashNum++) 196 { 197 for (short i=0; i< pins.length; i++) gpioPins[i].low(); 198 sleep(flashTimeMS); 199 System.out.print("ON..."); 200 for (short i=0; i< pins.length; i++) gpioPins[i].high(); 201 sleep(flashTimeMS); 202 System.out.println("OFF"); 203 for (short i=0; i< pins.length; i++) gpioPins[i].low(); 204 sleep(flashTimeMS); 205 } 206 } 207 208 209 /** figures out, sets the class Var endPin, and returns the array ref for the last ENABLED GPIO pin. **/ 210 private int lastEnabledPinRef() 211 { 212 int lastEnabledPinRef = 0; 213 int i=0; 214 for (i=0; i< pins.length; i++) 215 { 216 if(enabledPins[i] && gpioPins[i]!=null) 217 { 218 lastEnabledPinRef = i; 219 } 220 } 221 setEndPin(pins[lastEnabledPinRef]); 222 return lastEnabledPinRef; 223 } 224 225 226 /** figures out, sets the class Var startPin, and returns the array ref for the FIRST ENABLED GPIO pin. **/ 227 private int firstEnabledPinRef() 228 { 229 int firstEnabledPinRef = 0; 230 int i=0; 231 for (i=0; i< pins.length; i++) 232 { 233 if(enabledPins[i] && gpioPins[i]!=null) 234 { 235 firstEnabledPinRef = i; 236 break; 237 } 238 } 239 setStartPin(pins[firstEnabledPinRef]); 240 return firstEnabledPinRef; 241 } 242 243 244 /** Run the Cycling of te GPIO pins that have been defined, for the Class set loopTime (which defaults to DEFAULT_LOOP_TIME_MS if not set). **/ 245 public void cycle(){ cycle(loopTime);} 246 247 248 /** Run the Cycling of te GPIO pins that have been defined. 249 * @param loopTime is the length of time in ms to run the loop. 250 **/ 251 public void cycle(int loopTime) 252 { 253 System.out.print("["); 254 for (short i=0; i< pins.length; i++) if(enabledPins[i]) System.out.print(pins[i]+((i<pins.length-1)?",":"")); 255 System.out.println("]"); 256 System.out.print(" ... "); 257 if(overlapTime<0) delayCycle(loopTime); 258 else overlapCycle(loopTime); 259 System.out.println("...done!"); 260 } 261 262 263 /** This is the method that actually cyles the GPIO states - when overlapTime is positive - the LEDs overlap their ON, 264 * for the Class set loopTime (which defaults to DEFAULT_LOOP_TIME_MS if not set). **/ 265 public void overlapCycle(){ overlapCycle(loopTime);} 266 267 268 /** This is the method that actually cyles the GPIO states - when overlapTime is positive - the LEDs overlap their ON. 269 * @param loopTime is the length of time in ms to run the loop. 270 **/ 271 public void overlapCycle(int loopTime) 272 { 273 int runTime = 0; 274 short currDelay = 0; 275 int lastEnabledPinRef = lastEnabledPinRef(); 276 int firstEnabledPinRef = firstEnabledPinRef(); 277 System.out.println(" overlapping: dutyCycleTime="+(cycleTime)+"ms overlapTime="+(overlapTime)+"ms"); 278 279 if(enabledPins[firstEnabledPinRef] && gpioPins[firstEnabledPinRef]!=null) 280 { 281 gpioPins[firstEnabledPinRef].high(); 282 currDelay = (short)(overlapTime); 283 sleep(currDelay); 284 runTime+=currDelay; 285 } 286 while(loopTime==-1 || runTime<loopTime) 287 { 288 // loop through the GPIO cycling 289 for (short i=(short)firstEnabledPinRef; i< (short)lastEnabledPinRef; i++) 290 { 291 if(enabledPins[i] && gpioPins[i]!=null) 292 { 293 currDelay = (short)(cycleTime-(2*overlapTime)); 294 sleep(currDelay); 295 runTime+=currDelay; 296 if(enabledPins[i+1] && gpioPins[i+1]!=null) gpioPins[i+1].high(); 297 298 currDelay = (short)(overlapTime); 299 sleep(currDelay); 300 runTime+=currDelay; 301 gpioPins[i].low(); 302 } 303 } 304 305 // Bounce at the end of the loop and go back 306 for (short i=(short)lastEnabledPinRef; i>(short)firstEnabledPinRef; i--) 307 { 308 if(enabledPins[i] && gpioPins[i]!=null) 309 { 310 currDelay = (short)(cycleTime-(2*overlapTime)); 311 sleep(currDelay); 312 runTime+=currDelay; 313 if(enabledPins[i-1] && gpioPins[i-1]!=null) gpioPins[i-1].high(); 314 315 currDelay = (short)(overlapTime); 316 sleep(currDelay); 317 runTime+=currDelay; 318 gpioPins[i].low(); 319 } 320 } 321 322 } // while loop 323 gpioPins[firstEnabledPinRef].low(); 324 System.out.println(" Completed in:"+ runTime +"ms"); 325 326 } 327 328 329 /** This is the method that actually cyles the GPIO states - used when overlapTime is negative - there is a gap between the LEDs, 330 * for the Class set loopTime (which defaults to DEFAULT_LOOP_TIME_MS if not set). **/ 331 public void delayCycle(){ delayCycle(loopTime);} 332 333 334 /** This is the method that actually cyles the GPIO states - used when overlapTime is negative - there is a gap between the LEDs. 335 * @param loopTime is the length of time in ms to run the loop. 336 **/ 337 public void delayCycle(int loopTime) 338 { 339 int runTime = 0; 340 short currDelay = 0; 341 int lastEnabledPinRef = lastEnabledPinRef(); 342 int firstEnabledPinRef = firstEnabledPinRef(); 343 System.out.println(" delay "+(-1*overlapTime)); 344 while(loopTime==-1 || runTime<loopTime) 345 { 346 // fill in GPIO cycling 347 for (short i=(short)firstEnabledPinRef; i<= (short)lastEnabledPinRef; i++) 348 { 349 if(enabledPins[i] && gpioPins[i]!=null) 350 { 351 gpioPins[i].high(); 352 currDelay = (short)cycleTime; 353 this.sleep(currDelay); 354 runTime+=currDelay; 355 356 gpioPins[i].low(); 357 currDelay = (short)(-1*overlapTime); 358 this.sleep(currDelay); 359 runTime+=currDelay; 360 } 361 } 362 // Bounce at the end of the loop 363 currDelay = (short)(overlapTime); 364 this.sleep(currDelay); 365 runTime+=currDelay; 366 if(enabledPins[lastEnabledPinRef] && gpioPins[lastEnabledPinRef]!=null)gpioPins[lastEnabledPinRef].low(); 367 368 for (short i=(short)(lastEnabledPinRef-1); i>=firstEnabledPinRef; i--) 369 { 370 if(enabledPins[i] && gpioPins[i]!=null) 371 { 372 gpioPins[i].high(); 373 currDelay = cycleTime; 374 this.sleep(currDelay); 375 runTime+=currDelay; 376 377 gpioPins[i].low(); 378 currDelay = (short)(-1*overlapTime); 379 this.sleep(currDelay); 380 runTime+=currDelay; 381 } 382 } 383 currDelay = (short)(-1*overlapTime); 384 this.sleep(currDelay); 385 runTime+=currDelay; 386 } // while loop 387 388 } 389 390 /** Mark a pin as DISABLED - it sets the class var that keeps track of which GPIO pins are enabled; 'enabledPins' to false. 391 * If the passed var 'pin' is NOT one of the available pins for the connected board, this method simply/silently does nothing. 392 * @param pin is the GPIO pin number to disable 393 **/ 394 public void disablePin(short pin) 395 { 396 for (short i=0; i< pins.length; i++) 397 { 398 if(pins[i]==pin) 399 { 400 enabledPins[i] = false; 401 break; 402 } 403 } 404 } 405 406 407 /** Mark a pin as ENABLED - it sets the class var that keeps track of which GPIO pins are enabled; 'enabledPins' to true. 408 * If the passed var 'pin' is NOT one of the available pins for the connected board, this method simply/silently does nothing. 409 * @param pin is the GPIO pin number to enable 410 **/ 411 public void enablePin(short pin) 412 { 413 for (short i=0; i< pins.length; i++) 414 { 415 if(pins[i]==pin) 416 { 417 enabledPins[i] = true; 418 break; 419 } 420 } 421 } 422 423 424 /** Mark all available pins for the active boardType as ENABLED - it sets the class var that keeps track of 425 * which GPIO pins are enabled; 'enabledPins' to true. **/ 426 public void enableAllPin() 427 { 428 for (short i=0; i< pins.length; i++) 429 { 430 enabledPins[i] = true; 431 } 432 } 433 434 435 /** 436 * Set the boardType to use, must be one of the Class constants BOARD_TYPE_*. 437 * 438 * @param boardType is the value to set this class field to. 439 * 440 * @return short - The value boardType if successful ELSE -1. 441 **/ 442 public short setBoardType(short boardType) 443 { 444 short retVal = -1; 445 446 if( boardType>=0 && boardType<=BOARD_TYPE_2) 447 { 448 this.boardType = boardType; 449 retVal = boardType; 450 } 451 return retVal; 452 } // setBoardType Method 453 454 455 /** 456 * Get Method for class field 'boardType'. 457 * 458 * @return short - The boardType being used; will be one of the Class constants BOARD_TYPE_*. 459 * 460 **/ 461 public short getBoardType() 462 { 463 return boardType; 464 } // getBoardType Method 465 466 467 468 /** 469 * Set Method for class field 'startPin'. 470 * 471 * @param pin is the value to set this class field to. 472 * 473 **/ 474 public void setStartPin(short pin) 475 { 476 this.startPin = pin; 477 } // setStartPin Method 478 479 480 /** 481 * Get Method for class field 'startPin'. 482 * 483 * @return short - The value the class field 'startPin'. 484 * 485 **/ 486 public short getStartPin() 487 { 488 return startPin; 489 } // getStartPin Method 490 491 492 /** 493 * Set Method for class field 'endPin'. 494 * 495 * @param pin is the value to set this class field to. 496 * 497 **/ 498 public void setEndPin(short pin) 499 { 500 this.endPin = pin; 501 } // setEndPin Method 502 503 504 /** 505 * Get Method for class field 'endPin'. 506 * 507 * @return short - The value the class field 'endPin'. 508 * 509 **/ 510 public short getEndPin() 511 { 512 return endPin; 513 } // getEndPin Method 514 515 516 /** 517 * Set Method for class field 'cycleTime'. 518 * 519 * @param cycleTime is the value to set this class field to. 520 * 521 **/ 522 public void setCycleTime(short cycleTime) 523 { 524 this.cycleTime = cycleTime; 525 } // setCycleTime Method 526 527 528 /** 529 * Get Method for class field 'cycleTime'. 530 * 531 * @return short - The value the class field 'cycleTime'. 532 * 533 **/ 534 public short getCycleTime() 535 { 536 return cycleTime; 537 } // getCycleTime Method 538 539 540 /** 541 * Set Method for class field 'overlapTime'. 542 * 543 * @param overlapTime is the value to set this class field to. 544 * 545 **/ 546 public void setOverlapTime(short overlapTime) 547 { 548 this.overlapTime = overlapTime; 549 } // setOverlapTime Method 550 551 552 /** 553 * Get Method for class field 'overlapTime'. 554 * 555 * @return short - The value the class field 'overlapTime'. 556 * 557 **/ 558 public short getOverlapTime() 559 { 560 return overlapTime; 561 } // getOverlapTime Method 562 563 564 /** 565 * Set Method for class field 'pins' that represents the GPIO pin numbers on the board. 566 * 567 * @param short[] is the value to set this class field pinsto. 568 * 569 **/ 570 public void setPins(short[] pins) 571 { 572 this.pins = pins; 573 } // setPins Method 574 575 576 /** 577 * Get Method for class field '[]'. 578 * 579 * @return short - The value the class field '[]'. 580 * 581 **/ 582 public short[] getPins() 583 { 584 return pins; 585 } // getPins[] Method 586 587 588 private short getEnabledPinCount() 589 { 590 short pinCount = 0; 591 for (short i=0; i< pins.length; i++) if(enabledPins[i]) pinCount++; 592 return pinCount; 593 } 594 595 596 /** RaspiPINS have names of the form 'GPIO 4' or 'GPIO 12'. 597 * @param pin is the Pi4j (wiringPI) pin number. 598 **/ 599 private Pin getRaspiPin(short pin) 600 { 601 Pin retVal = null; 602 String pinName = "GPIO "; 603 /* 604 if(pin>0 && pin<10) 605 { 606 pinName += "0"+pin; 607 retVal = RaspiPin.getPinByName(pinName); 608 } 609 else if(pin>9) 610 */ 611 // { 612 pinName += ""+pin; 613 retVal = RaspiPin.getPinByName(pinName); 614 // } 615 return retVal; 616 } 617 618 619 /** provisions and returns a Gpio Outpout Pin with the DEFAULT state. **/ 620 private GpioPinDigitalOutput provisionOutputPin(short pin) 621 { 622 return provisionOutputPin(pin, DEFAULT_PINSTATE); 623 } 624 625 626 /** provisions and returns a Gpio Outpout Pin. **/ 627 private GpioPinDigitalOutput provisionOutputPin(short pin, PinState pinState) 628 { 629 GpioPinDigitalOutput gpioPin = null; 630 if( pin>=pins[0] && pin<=pins[pins.length-1]) 631 { 632 gpioPin = gpio.provisionDigitalOutputPin(getRaspiPin(pin), DEFAULT_PINSTATE); 633 } 634 return gpioPin; 635 } 636 637 638 /** provisions ALL enabled pins and puts them in the class var gpioPins. **/ 639 private GpioPinDigitalOutput[] provisionPins(){return provisionPins(false);} 640 641 642 /** provisions (according to passed flag) pins and puts them in the class var gpioPins. 643 * 644 * @param boolean controls if all pins are provisioned for only those that are enabled in enabledPins class var. 645 * 646 **/ 647 private GpioPinDigitalOutput[] provisionPins(boolean doAll) 648 { 649 if(!allPinsProvisioned) 650 { 651 System.out.print("["); 652 for (short i=0; i< pins.length; i++) 653 { 654 if(doAll || enabledPins[i]) 655 { 656 System.out.print(pins[i]+((i<pins.length-1)?",":"")); 657 gpioPins[i] = provisionOutputPin(pins[i]); 658 } 659 } 660 } 661 System.out.println("]"); 662 allPinsProvisioned = (allPinsProvisioned || doAll); 663 return gpioPins; 664 } 665 666 667 /** The main entrance to this class. 668 *<pre> 669 *-------------------------------------------------------------------------------- 670 * Java Raspberry PI - GpioCycler 671 * Copyright (C) 2015 - Tom B. Gutwin 672 *-------------------------------------------------------------------------------- 673 *Syntax: 674 *java ca.bc.webarts.raspberry.GpioCycler [loopTime [dutyCycleTime [overlapTime]]] 675 * where the 3 OPTIONAL parameters are: 676 * loopTime time in milliSeconds to run the looping (default=DEFAULT_LOOP_TIME_MS ms) 677 * (default=DEFAULT_LOOP_TIME_MS ms) 678 * dutyCycleTime time in milliSeconds the GPIOs stays in the 'ON' state 679 * (default=DEFAULT_CYCLE_TIME_MS ms) 680 * overlapTime time in milliSeconds the next/following GPIO will turn 681 * 'ON' before the previous GPIO turns 'OFF' 682 * (default=DEFAULT_OVERLAP_TIME_MS ms) 683 * </pre> 684 **/ 685 public static void main(String [] args) throws InterruptedException 686 { 687 GpioCycler instance = new GpioCycler(); 688 if (args==null || args.length == 0) 689 { 690 System.out.println("--------------------------------------------------------------------------------"); 691 System.out.println(" Java Raspberry PI - GpioCycler "); 692 System.out.println(" Copyright (C) 2015 - Tom B. Gutwin "); 693 System.out.println("--------------------------------------------------------------------------------"); 694 System.out.println("Syntax:"); 695 System.out.println("java ca.bc.webarts.raspberry.GpioCycler [loopTime [dutyCycleTime [overlapTime]]]"); 696 System.out.println(" where the 3 OPTIONAL parameters are:"); 697 System.out.println(" loopTime time in milliSeconds to run the looping (default="+DEFAULT_LOOP_TIME_MS+"ms)"); 698 System.out.println(" (default="+DEFAULT_LOOP_TIME_MS+"ms)"); 699 System.out.println(" dutyCycleTime time in milliSeconds the GPIOs stays in the 'ON' state "); 700 System.out.println(" (default="+DEFAULT_CYCLE_TIME_MS+"ms)"); 701 System.out.println(" overlapTime time in milliSeconds the next/following GPIO will turn"); 702 System.out.println(" 'ON' before the previous GPIO turns 'OFF' "); 703 System.out.println(" (default="+DEFAULT_OVERLAP_TIME_MS+"ms)"); 704 System.out.println("--------------------------------------------------------------------------------"); 705 } 706 //else 707 { 708 instance.parseCommandlineParms(args); 709 System.out.println("<Provisioning All GPIO pins>"); 710 instance.provisionPins(true); 711 712 System.out.println("<TESTING All GPIO pins>"); 713 instance.flashAllPins(); 714 System.out.println("<Cycling GPIO pins>"); 715 instance.cycle(); 716 } 717 718 instance.shutdown(); 719 720 } 721 722 /** 723 * A method to simply abstract the Try/Catch required to put the current 724 * thread to sleep for the specified time in ms. 725 * 726 * @param waitTime the sleep time in milli seconds (ms). 727 * @return boolean value specifying if the sleep completed (true) or was interupted (false). 728 */ 729 public static boolean sleep(long waitTime) 730 { 731 boolean retVal = true; 732 if (waitTime<0) 733 retVal=false; 734 else 735 { 736 /* 737 * BLOCK for the spec'd time 738 */ 739 try 740 { 741 Thread.sleep(waitTime); 742 } 743 catch (InterruptedException iex) 744 { 745 retVal = false; 746 } 747 } 748 return retVal; 749 } 750 751 752 753}