Skip to content

Commit 8a86643

Browse files
authored
add dc motor and servomotor examples to components page (#9)
1 parent d26a5e2 commit 8a86643

1 file changed

Lines changed: 149 additions & 0 deletions

File tree

modules/atomvm/pages/components.adoc

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,80 @@ y tengan una buena velocidad. Son ideales para las ruedas que dan movimiento al
1111

1212
=== Guía de Conexiones
1313

14+
Para controlar un motor DC con una ESP32 y un driver L298N, se requiere de una fuente de alimentación externa para el motor, ya que la ESP32 no puede suministrar la corriente necesaria. El L298N actúa como un "puente H" que permite a la ESP32 controlar tanto la dirección como la velocidad del motor.
15+
16+
* **Conexión a la ESP32**:
17+
* `ESP32 GND` -> `L298N GND` (es importante que compartan tierra)
18+
* `ESP32 GPIO26` -> `L298N IN1`
19+
* `ESP32 GPIO27` -> `L298N IN2`
20+
* `ESP32 GPIO25` -> `L298N ENA` (si se va a usar PWM)
21+
22+
* **Conexión de la Fuente de Alimentación Externa**:
23+
* `Fuente Externa Positivo (+) ` -> `L298N V12`
24+
* `Fuente Externa Negativo (-) ` -> `L298N GND`
25+
26+
* **Conexión del Motor DC**:
27+
* `Motor Terminal 1` -> `L298N OUT1`
28+
* `Motor Terminal 2` -> `L298N OUT2`
29+
30+
**Notas sobre el pin `ENA` y el control de velocidad (PWM):**
31+
32+
* El módulo L298N suele venir con un jumper de plástico preinstalado en el pin `ENA` (y `ENB`).
33+
* Si este jumper está puesto, el motor estará siempre habilitado a máxima potencia y no podrás controlar su velocidad mediante software.
34+
* Para poder controlar la velocidad del motor con la ESP32, se debe retirar el jumper del pin `ENA` y conectar un pin GPIO de la ESP32 (como `GPIO25`) a `ENA`.
35+
* La ESP32 enviará una señal PWM (Pulse Width Modulation) a este pin `ENA`. El PWM permite simular un voltaje variable controlando el "tiempo de encendido" de la señal, lo que a su vez controla la velocidad efectiva del motor. En AtomVM, esto se gestiona mediante el módulo `LEDC`.
36+
1437
=== Código de Ejemplo
1538

39+
[source, elixir]
40+
----
41+
defmodule MotorTest do
42+
@left_motor_pin_1 26
43+
@left_motor_pin_2 27
44+
45+
def start() do
46+
:gpio.set_pin_mode(@left_motor_pin_1, :output)
47+
:gpio.set_pin_mode(@left_motor_pin_2, :output)
48+
49+
:io.format('Setup de motor finalizado~n')
50+
51+
loop()
52+
end
53+
54+
defp loop() do
55+
:io.format('Moviendo hacia adelante~n')
56+
set_motor_direction(:forward)
57+
Process.sleep(3000)
58+
59+
:io.format('Deteniendo motor~n')
60+
set_motor_direction(:stop)
61+
Process.sleep(2000)
62+
63+
:io.format('Moviendo hacia atrás~n')
64+
set_motor_direction(:reverse)
65+
Process.sleep(3000)
66+
67+
loop()
68+
end
69+
70+
defp set_motor_direction(direction) do
71+
case direction do
72+
:forward ->
73+
:gpio.digital_write(@left_motor_pin_1, :high)
74+
:gpio.digital_write(@left_motor_pin_2, :low)
75+
:reverse ->
76+
:gpio.digital_write(@left_motor_pin_1, :low)
77+
:gpio.digital_write(@left_motor_pin_2, :high)
78+
:stop ->
79+
:gpio.digital_write(@left_motor_pin_1, :low)
80+
:gpio.digital_write(@left_motor_pin_2, :low)
81+
_ ->
82+
:io.format('Dirección de motor inválida: ~p~n', [direction])
83+
end
84+
end
85+
end
86+
----
87+
1688
=== Ejemplo de Funcionamiento
1789

1890
== Servomotor
@@ -22,8 +94,85 @@ En este caso se utilizará un https://mcielectronics.cl/shop/product/micro-servo
2294

2395
=== Guía de Conexiones
2496

97+
Para conectar un servomotor SG90 a la ESP32:
98+
99+
* **Pines del servomotor SG90**:
100+
* `Cable Rojo`: VCC
101+
* `Cable Marrón`: GND
102+
* `Cable Naranja`: Señal PWM
103+
104+
* **Conexión a la ESP32**:
105+
* `VCC` (Servo) -> `ESP32 3v3`
106+
* `GND` (Servo) -> `ESP32 GND`
107+
* `Signal` (Servo) -> `ESP32 GPIO` (Ej: `GPIO13`)
108+
25109
=== Código de Ejemplo
26110

111+
[source, elixir]
112+
----
113+
defmodule ServoTest do
114+
@servomotor_pin 13
115+
@servo_pwm_channel 0 # canal LEDC a usar para el servo
116+
@servo_pwm_timer 0 # timer LEDC a usar para el servo
117+
118+
@servo_pwm_freq 50 # servos usan 50Hz
119+
@servo_pwm_resolution 10 # 10 bits de resolución (0-1023)
120+
121+
# valores de duty cycle para ángulos comunes del SG90
122+
# calculados para 10 bits de resolución (máx 1023) y 50Hz (periodo 20ms):
123+
# 1ms (0 grados) -> (1/20) * 1023 = ~51
124+
# 1.5ms (90 grados) -> (1.5/20) * 1023 = ~77
125+
# 2ms (180 grados) -> (2/20) * 1023 = ~102
126+
@duty_0_degrees 51
127+
@duty_90_degrees 77
128+
@duty_180_degrees 100
129+
130+
def start() do
131+
set_up_servo()
132+
133+
:io.format('Servo setup finished. Starting movement sequence...~n')
134+
135+
set_servo_angle(@duty_0_degrees)
136+
Process.sleep(1500)
137+
138+
set_servo_angle(@duty_90_degrees)
139+
Process.sleep(1500)
140+
141+
set_servo_angle(@duty_180_degrees)
142+
Process.sleep(1500)
143+
144+
:io.format('Movement sequence completed. Entering infinite sleep.~n')
145+
:timer.sleep(:infinity)
146+
end
147+
148+
defp set_up_servo() do
149+
:ok =
150+
LEDC.timer_config(
151+
duty_resolution: @servo_pwm_resolution,
152+
freq_hz: @servo_pwm_freq,
153+
speed_mode: LEDC.high_speed_mode(),
154+
timer_num: @servo_pwm_timer
155+
)
156+
157+
:ok =
158+
LEDC.channel_config(
159+
channel: @servo_pwm_channel,
160+
duty: @duty_90_degrees, # iniciar el servo en una posición central
161+
gpio_num: @servomotor_pin,
162+
speed_mode: LEDC.high_speed_mode(),
163+
hpoint: 0,
164+
timer_sel: @servo_pwm_timer
165+
)
166+
end
167+
168+
defp set_servo_angle(duty_cycle_value) do
169+
:io.format('Setting servo duty to: ~p~n', [duty_cycle_value])
170+
:ok = LEDC.set_duty(LEDC.high_speed_mode(), @servo_pwm_channel, duty_cycle_value)
171+
:ok = LEDC.update_duty(LEDC.high_speed_mode(), @servo_pwm_channel)
172+
end
173+
end
174+
----
175+
27176
=== Ejemplo de Funcionamiento
28177

29178
== Evitar Obstáculos

0 commit comments

Comments
 (0)