n128

Arduino - Elevador código

Jun 26th, 2025
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.66 KB | None | 0 0
  1. #include <Servo.h>
  2.  
  3. // Servo
  4. #define SERVO_PIN 13
  5. // Controladores de piso
  6. #define BTN_0 9
  7. #define BTN_1 10
  8. #define BTN_2 11
  9. #define BTN_3 12
  10. // Sensor de distancia
  11. #define TRIG_PIN 8
  12. #define ECHO_PIN 7
  13. // Display de 7 segmentos
  14. #define A 2
  15. #define B 3
  16. #define C 4
  17. #define D 5
  18. #define E 6
  19. #define G A5
  20. #define F A4
  21. // Auxiliares
  22. #define ALTURA 87
  23. #define ALTURA_POR_PISO (long)(ALTURA/4)
  24. #define TOLERANCIA_PORCENTUAL 5
  25.  
  26. /* Tipos de datos definidos para el problema */
  27.  
  28. // Rotador: Tipo que representa el servo de rotación continua.
  29. typedef struct {
  30. // Objeto servo.
  31. Servo obj;
  32. // Dirección en la que gira el servo.
  33. int direccion;
  34. } Rotador;
  35.  
  36. Rotador rotador_inicializar();
  37. uint8_t rotador_attach(int pin);
  38. // Cambia la dirección del servo. Por ejemplo: 0, 45, 90 (detener), 135, 180.
  39. void rotador_set_dir(int direccion);
  40. // Cambia la dirección del servo según su atributo "direccion".
  41. void rotador_write();
  42. // Cambia el atributo "direccion" e invoca a `rotador_write`.
  43. void rotador_write_dir(int direccion);
  44.  
  45. // Sensor: Tipo que representa al sensor de distancia.
  46. typedef struct {
  47. // Última distancia calculada.
  48. long int d;
  49. // Tiempo del último pulso.
  50. long int t;
  51. } Sensor;
  52.  
  53. Sensor sensor_inicializar();
  54. // Obtiene la última distancia registrada por el sensor.
  55. // La distancia inicial, cuando todavía no se hizo ningún cálculo, es de -1.
  56. long int sensor_distancia();
  57. // Calcula la distancia al suelo medida en cm.
  58. long int sensor_calcular_distancia();
  59.  
  60. // Elevador: Tipo que representa el comportamiento del elevador y sus estados.
  61. typedef struct {
  62. short piso_actual;
  63. short piso_destino;
  64. } Elevador;
  65.  
  66. Elevador elevador_inicializar();
  67. // Escucha si se pulsó algún botón y modifica el estado interno según sea necesario.
  68. void elevador_escuchar();
  69. // Mueve el elevador en función de sus estados internos de `piso_actual` y `piso_destino`.
  70. // En caso de que la distancia de movimiento sea 0, entonces no realiza acción alguna.
  71. void elevador_mover();
  72.  
  73. // Funciones del display
  74. void display_dibujar(int n);
  75. void display_limpiar();
  76.  
  77. /* Estados y objetos de uso global para el programa en ejecución */
  78.  
  79. int debug = 1;
  80.  
  81. Rotador rotador;
  82. Sensor sensor;
  83. Elevador elevador;
  84.  
  85. // Representaciones de los valores para el display de 7 segmentos.
  86. int display_figuras[4][7] = {
  87. {A, B, C, D, E, G, 0},
  88. {B, C, 0, 0, 0, 0, 0},
  89. {A, B, F, E, D, 0, 0},
  90. {A, B, C, D, F, 0, 0}
  91. };
  92.  
  93. void setup()
  94. {
  95. if (debug != 0) {
  96. Serial.begin(9600);
  97. }
  98.  
  99. rotador = rotador_inicializar();
  100. rotador_attach(SERVO_PIN);
  101. rotador_write(); // El rotador inicia detenido (direccion = 90).
  102.  
  103. sensor = sensor_inicializar();
  104. pinMode(TRIG_PIN, OUTPUT);
  105. pinMode(ECHO_PIN, INPUT);
  106.  
  107. elevador = elevador_inicializar();
  108.  
  109. pinMode(BTN_0, INPUT);
  110. pinMode(BTN_1, INPUT);
  111. pinMode(BTN_2, INPUT);
  112. pinMode(BTN_3, INPUT);
  113.  
  114. pinMode(A, OUTPUT);
  115. pinMode(B, OUTPUT);
  116. pinMode(C, OUTPUT);
  117. pinMode(D, OUTPUT);
  118. pinMode(E, OUTPUT);
  119. pinMode(F, OUTPUT);
  120. pinMode(G, OUTPUT);
  121. }
  122.  
  123. void loop()
  124. {
  125. display_limpiar();
  126. if (elevador.piso_destino != elevador.piso_actual) {
  127. display_dibujar(elevador.piso_destino);
  128. } else {
  129. display_dibujar(elevador.piso_actual);
  130. }
  131.  
  132. elevador_escuchar();
  133. elevador_mover();
  134. delay(100);
  135. }
  136.  
  137. // Display
  138. void display_dibujar(int n) {
  139. for (int i = 0; i < 7; i++) {
  140. if (display_figuras[n][i] != 0) {
  141. digitalWrite(display_figuras[n][i], HIGH);
  142. }
  143. }
  144. }
  145.  
  146. void display_limpiar() {
  147. digitalWrite(A, LOW);
  148. digitalWrite(B, LOW);
  149. digitalWrite(C, LOW);
  150. digitalWrite(D, LOW);
  151. digitalWrite(E, LOW);
  152. digitalWrite(F, LOW);
  153. digitalWrite(G, LOW);
  154. }
  155.  
  156. // Elevador
  157. Elevador elevador_inicializar()
  158. {
  159. Elevador e;
  160. e.piso_actual = 0;
  161. e.piso_destino = 0;
  162. return e;
  163. }
  164.  
  165. void elevador_mover()
  166. {
  167. short actual = elevador.piso_actual;
  168. short destino = elevador.piso_destino;
  169.  
  170. int distancia = abs((int)(destino) - (int)(actual));
  171. int direccion_rotador = 0;
  172.  
  173. if (actual > destino) {
  174. direccion_rotador = -1;
  175. } else {
  176. if (actual < destino) {
  177. direccion_rotador = 1;
  178. }
  179. }
  180.  
  181. // Salida prematura, ya que no se puede cambiar de piso.
  182. if (direccion_rotador == 0) {
  183. rotador_write_dir(90);
  184. return;
  185. }
  186.  
  187. long int altura_destino_cm;
  188. if (direccion_rotador > 0) {
  189. altura_destino_cm = ALTURA - ALTURA_POR_PISO*destino;
  190. rotador_set_dir(110);
  191. } else {
  192. altura_destino_cm = ALTURA + ALTURA_POR_PISO*destino;
  193. rotador_set_dir(67);
  194. }
  195.  
  196. long int distancia_actual_cm = sensor_calcular_distancia();
  197. long int tolerancia = ALTURA_POR_PISO*TOLERANCIA_PORCENTUAL/100;
  198. long int cota_superior = (long int)(altura_destino_cm + tolerancia);
  199. long int cota_inferior = (long int)(altura_destino_cm - tolerancia);
  200.  
  201. if (debug != 0) {
  202. Serial.print("Actual: "); Serial.print(distancia_actual_cm); Serial.print("cm");
  203. Serial.print(" | Destino: "); Serial.print(altura_destino_cm); Serial.print("cm");
  204. Serial.print(" | ["); Serial.print(cota_inferior); Serial.print(", "); Serial.print(cota_superior); Serial.println("]");
  205. delay(100);
  206. }
  207.  
  208. if (distancia_actual_cm >= cota_inferior && distancia_actual_cm <= cota_superior) {
  209. rotador_set_dir(90);
  210. elevador.piso_actual = destino;
  211.  
  212. if (debug != 0) {
  213. Serial.print(">>> Llegada al piso: ");
  214. Serial.println(elevador.piso_actual);
  215. }
  216. }
  217.  
  218. rotador_write();
  219. }
  220.  
  221. void elevador_escuchar()
  222. {
  223. int btn0 = digitalRead(BTN_0);
  224. int btn1 = digitalRead(BTN_1);
  225. int btn2 = digitalRead(BTN_2);
  226. int btn3 = digitalRead(BTN_3);
  227.  
  228. if (btn0 == HIGH) {
  229. elevador.piso_destino = 0;
  230. }
  231. if (btn1 == HIGH) {
  232. elevador.piso_destino = 1;
  233. }
  234. if (btn2 == HIGH) {
  235. elevador.piso_destino = 2;
  236. }
  237. if (btn3 == HIGH) {
  238. elevador.piso_destino = 3;
  239. }
  240. }
  241.  
  242. // Sensor
  243. Sensor sensor_inicializar() {
  244. Sensor s;
  245. s.t = 0;
  246. s.d = -1;
  247. }
  248.  
  249. long int sensor_distancia() {
  250. return sensor.d;
  251. }
  252.  
  253. long int sensor_calcular_distancia()
  254. {
  255. digitalWrite(TRIG_PIN, LOW);
  256. delayMicroseconds(2);
  257. digitalWrite(TRIG_PIN, HIGH);
  258. delayMicroseconds(10);
  259. digitalWrite(TRIG_PIN, LOW);
  260.  
  261. sensor.t = pulseIn(ECHO_PIN, 1);
  262. sensor.d = sensor.t / 59;
  263.  
  264. return sensor.d;
  265. }
  266.  
  267. // Rotador
  268. Rotador rotador_inicializar()
  269. {
  270. Rotador r;
  271. r.obj = {};
  272. r.direccion = 90;
  273. return r;
  274. }
  275.  
  276. uint8_t rotador_attach(int pin)
  277. {
  278. return rotador.obj.attach(pin);
  279. }
  280.  
  281. void rotador_set_dir(int direccion)
  282. {
  283. rotador.direccion = direccion;
  284. }
  285.  
  286. void rotador_write()
  287. {
  288. rotador.obj.write(rotador.direccion);
  289. }
  290.  
  291. void rotador_write_dir(int direccion)
  292. {
  293. rotador_set_dir(direccion);
  294. rotador_write();
  295. }
Advertisement
Add Comment
Please, Sign In to add comment