001package com.pi4j.wiringpi; 002 003/* 004 * #%L 005 * ********************************************************************** 006 * ORGANIZATION : Pi4J 007 * PROJECT : Pi4J :: Java Library (Core) 008 * FILENAME : SoftPwm.java 009 * 010 * This file is part of the Pi4J project. More information about 011 * this project can be found here: https://www.pi4j.com/ 012 * ********************************************************************** 013 * %% 014 * Copyright (C) 2012 - 2021 Pi4J 015 * %% 016 * This program is free software: you can redistribute it and/or modify 017 * it under the terms of the GNU Lesser General Public License as 018 * published by the Free Software Foundation, either version 3 of the 019 * License, or (at your option) any later version. 020 * 021 * This program is distributed in the hope that it will be useful, 022 * but WITHOUT ANY WARRANTY; without even the implied warranty of 023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 024 * GNU General Lesser Public License for more details. 025 * 026 * You should have received a copy of the GNU General Lesser Public 027 * License along with this program. If not, see 028 * <http://www.gnu.org/licenses/lgpl-3.0.html>. 029 * #L% 030 */ 031 032 033import com.pi4j.util.NativeLibraryLoader; 034 035/** 036 * <p> 037 * WiringPi includes a software-driven PWM handler capable of outputting a PWM signal on any of the 038 * Raspberry Pi's GPIO pins. 039 * </p> 040 * 041 * <p> 042 * There are some limitations. To maintain a low CPU usage, the minimum pulse width is 100uS. That 043 * combined with the default suggested range of 100 gives a PWM frequency of 100Hz. You can lower 044 * the range to get a higher frequency, at the expense of resolution, or increase to get more 045 * resolution, but that will lower the frequency. If you change the pulse-width in the drive code, 046 * then be aware that at delays of less than 100uS wiringPi does it in a software loop, which means 047 * that CPU usage will rise dramatically, and controlling more than one pin will be almost 048 * impossible. 049 * </p> 050 * 051 * <p> 052 * Also note that while the routines run themselves at a higher and real-time priority, Linux can 053 * still affect the accuracy of the generated signal. 054 * </p> 055 * 056 * <p> 057 * However, within these limitations, control of a light/LED or a motor is very achievable. 058 * </p> 059 * 060 * <p> 061 * <b> You must initialize wiringPi with one of wiringPiSetup() or wiringPiSetupGpio() functions 062 * beforehand. wiringPiSetupSys() is not fast enough, so you must run your programs with sudo. </b> 063 * </p> 064 * 065 * <p> 066 * Before using the Pi4J library, you need to ensure that the Java VM in configured with access to 067 * the following system libraries: 068 * <ul> 069 * <li>pi4j</li> 070 * <li>wiringPi</li> 071 * <li>pthread</li> 072 * </ul> 073 * <blockquote> This library depends on the wiringPi native system library.</br> (developed by 074 * Gordon Henderson @ <a href="http://wiringpi.com/">http://wiringpi.com/</a>) 075 * </blockquote> 076 * </p> 077 * 078 * @see <a href="https://www.pi4j.com/">https://www.pi4j.com/</a> 079 * @see <a 080 * href="http://wiringpi.com/reference/software-pwm-library/">http://wiringpi.com/reference/software-pwm-library/</a> 081 * @author Robert Savage (<a 082 * href="http://www.savagehomeautomation.com">http://www.savagehomeautomation.com</a>) 083 */ 084public class SoftPwm { 085 086 // private constructor 087 private SoftPwm() { 088 // forbid object construction 089 } 090 091 static { 092 // Load the platform library 093 NativeLibraryLoader.load("libpi4j.so", "pi4j"); 094 } 095 096 /** 097 * <p>int softPwmCreate (int pin, int initialValue, int pwmRange);</p> 098 * 099 * <p> 100 * This creates a software controlled PWM pin. You can use any GPIO pin and the pin numbering 101 * will be that of the wiringPiSetup function you used. Use 100 for the pwmRange, then the value 102 * can be anything from 0 (off) to 100 (fully on) for the given pin. 103 * </p> 104 * 105 * @see <a 106 * href="http://wiringpi.com/reference/software-pwm-library/">http://wiringpi.com/reference/software-pwm-library/</a> 107 * 108 * @param pin The GPIO pin to use as a PWM pin. 109 * </p> 110 * @param value The value to initialize the PWM pin (between 0 <i>(off)</i> to 100 <i>(fully 111 * on)</i>) 112 * @param range The maximum range. Use 100 for the pwmRange. 113 * @return The return value is 0 for success. Anything else and you should check the global 114 * errno variable to see what went wrong. 115 */ 116 public static native int softPwmCreate(int pin, int value, int range); 117 118 /** 119 * <p>void softPwmWrite (int pin, int value);</p> 120 * 121 * <p> 122 * This updates the PWM value on the given pin. The value is checked to be in-range and pins 123 * that haven't previously been initialized via softPwmCreate will be silently ignored. 124 * </p> 125 * 126 * @see <a 127 * href="http://wiringpi.com/reference/software-pwm-library/">http://wiringpi.com/reference/software-pwm-library/</a> 128 * 129 * @param pin The GPIO pin to use as a PWM pin. 130 * @param value The value to initialize the PWM pin (between 0 <i>(off)</i> to 100 <i>(fully 131 * on)</i>) 132 */ 133 public static native void softPwmWrite(int pin, int value); 134 135 /** 136 /** 137 * <p>void softPwmStop (int pin);</p> 138 * 139 * <p> 140 * This stops the software emulated PWM driver/thread for the given pin. 141 * </p> 142 * 143 * @see <a 144 * href="http://wiringpi.com/reference/software-pwm-library/">http://wiringpi.com/reference/software-pwm-library/> * 145 * @param pin The GPIO pin to use as a PWM pin. 146 */ 147 public static native void softPwmStop(int pin); 148}