Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 5054

Compute Module • How to Properly Initialize and Use PWM on GPIO 18 in Python?

$
0
0
Hi,

I am working on controlling a laser diode using PWM on GPIO 18 of a Raspberry Pi. My setup includes the following:

1. Device Tree Configuration:
I have configured PWM in `/boot/config.txt` as follows:
```txt
dtoverlay=pwm-2chan,pin=18,func=2
```

2. GPIO 18 Initial State:
Before running the program, the command `raspi-gpio get 18` outputs:
```txt
GPIO 18: level=0 alt=5 func=PWM0
```
This confirms that GPIO 18 is correctly set to `ALT5` (PWM mode).

3. Python Program:
Below is my Python code for testing PWM functionality:

```python
import RPi.GPIO as GPIO
import time

# Set GPIO pins
RELAY_PIN = 26 # Control laser switch
PWM_PIN = 18 # Control PWM brightness
PWM_FREQUENCY = 2000 # Set PWM frequency (Hz)

def setup_gpio():
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)

# Print the state of GPIO 18 before initialization
print("Before PWM setup:", GPIO.gpio_function(PWM_PIN)) # Check GPIO function state

# Set laser switch pin
GPIO.setup(RELAY_PIN, GPIO.OUT)
GPIO.output(RELAY_PIN, False) # Initial state is OFF

# Directly initialize PWM
global pwm
pwm = GPIO.PWM(PWM_PIN, PWM_FREQUENCY)
pwm.start(0) # Initial duty cycle is 0

# Print the state of GPIO 18 after initialization
print("After PWM setup:", GPIO.gpio_function(PWM_PIN)) # Check GPIO function state

def toggle_laser(state):
GPIO.output(RELAY_PIN, state)
if state:
print("Laser is ON")
else:
print("Laser is OFF")

def set_laser_brightness(duty_cycle):
if 0 <= duty_cycle <= 100:
pwm.ChangeDutyCycle(duty_cycle)
print(f"Laser brightness set to {duty_cycle}%")
else:
print("Invalid duty cycle. Please provide a value between 0 and 100.")

def main():
setup_gpio()
try:
while True:
# Turn on laser
toggle_laser(True)
set_laser_brightness(80) # Set brightness to 80%
time.sleep(20) # Keep laser ON for 20 seconds

# Turn off laser
set_laser_brightness(0) # Set brightness to 0 (OFF)
toggle_laser(False)
time.sleep(3) # Keep laser OFF for 3 seconds
except KeyboardInterrupt:
print("Exiting program.")
finally:
pwm.stop()
GPIO.cleanup([RELAY_PIN]) # Only clean up laser switch pin, keep PWM_PIN

if __name__ == "__main__":
main()
```

4. The Issue:
- When I run the program, I encounter the following error:
```
RuntimeError: You must setup() the GPIO channel as an output first
```
- If I add `GPIO.setup(PWM_PIN, GPIO.OUT)` before initializing PWM, GPIO 18 gets reconfigured to a regular output mode (`OUTPUT`), and PWM functionality is lost.

5. What I Need Help With:
- How can I properly initialize and use PWM on GPIO 18 without overwriting its `ALT5` (PWM) mode?
- Is there a way to avoid the `RuntimeError` without resetting GPIO 18's configuration?

Any guidance would be greatly appreciated. Thank you!

Statistics: Posted by dgy411852 — Fri Jan 03, 2025 10:49 pm — Replies 1 — Views 12



Viewing all articles
Browse latest Browse all 5054

Trending Articles