├── .gitattributes ├── ADC ├── potenciometro_8266.py ├── potenciometro_pico.py └── temp_pico.py ├── Display7 ├── display7.py ├── display7_m.py ├── display7seg.py ├── display7seg2.py ├── mostrar.py ├── multiplexa.py └── prueba.py ├── ESP8266 └── esp8266-20210202-v1.14.bin ├── Entradas GPIO ├── Entradas.py └── ejemplo_led.py ├── IRQ ├── boton.py └── velocidad.py ├── LCD_I2C ├── LCD_Prueba.py └── lcd_i2c.py ├── Motor PaP └── Motor_PaP.py ├── Nivel └── Level.py ├── OLED ├── framebuf_utils.mpy ├── images.py ├── lib │ └── ssd1306.py ├── logo_raspberry.png ├── oled_ex1.py └── oled_ex2.py ├── PID_Level └── PID_Level.py ├── PWM ├── led.py └── motor_puente_h.py ├── RPI-PICO-I2C-LCD-main ├── README.md ├── Schematic.jpg ├── lcd_api.py ├── pico_i2c_lcd.py └── pico_i2c_lcd_test.py ├── Raspberry Pi Pico └── rp2-pico-20210227-unstable-v1.14-82-gcdaec0dca.uf2 ├── SDK └── SDK.py ├── Salidas GPIO ├── led.py └── main.py ├── Servo └── servomotor.py ├── Timer ├── led_timer.py ├── multiplexacion_timer.py ├── temp_2.py └── temporizador.py ├── UART └── Com_Uart.py └── thread └── multiplexacion.py /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /ADC/potenciometro_8266.py: -------------------------------------------------------------------------------- 1 | """ 2 | Programa de Ejemplo lectura ADC 3 | by: Sergio Andrés Castaño Giraldo 4 | https://controlautomaticoeducacion.com/ 5 | Canal de YouTube: https://www.youtube.com/c/SergioACastañoGiraldo 6 | """ 7 | 8 | from machine import ADC 9 | from utime import sleep 10 | 11 | 12 | def main(): 13 | #potenciometro = ADC(26) #Raspberry Pi Pico ADC0 14 | potenciometro = ADC(0) #NodeMCU8266v3 ADC0 15 | 16 | factor_10 = 3.3 / (1023) 17 | #factor_12 = 3.3 / (4095) 18 | factor_16 = 3.3 / (65535) 19 | 20 | while True: 21 | bits = potenciometro.read(); 22 | bits_16 = potenciometro.read_u16(); 23 | 24 | volts_10 = bits * factor_10 25 | #volts_12 = bits * factor_12 26 | volts_16 = bits_16 * factor_16 27 | 28 | print('\nValor en 10 bits: {}, y en volts: {}'.format(bits, volts_10)) 29 | print('Valor en 16 bits: {}, y en volts: {}'.format(bits_16, volts_16)) 30 | sleep(1) 31 | 32 | 33 | if __name__ == '__main__': 34 | main() 35 | -------------------------------------------------------------------------------- /ADC/potenciometro_pico.py: -------------------------------------------------------------------------------- 1 | """ 2 | Programa de Ejemplo lectura ADC 3 | by: Sergio Andrés Castaño Giraldo 4 | https://controlautomaticoeducacion.com/ 5 | Canal de YouTube: https://www.youtube.com/c/SergioACastañoGiraldo 6 | """ 7 | 8 | from machine import ADC 9 | from utime import sleep 10 | 11 | 12 | def main(): 13 | # True: Raspberry Pi Pico 14 | # False: NodeMCU ESP8266 15 | placa = False 16 | 17 | if placa: 18 | potenciometro = ADC(26) #Raspberry Pi Pico ADC0 19 | else: 20 | potenciometro = ADC(0) #NodeMCU8266v3 ADC0 21 | factor_10 = 3.3 / (1023) #Se puede leer con read() 22 | 23 | factor_16 = 3.3 / (65535) 24 | 25 | 26 | while True: 27 | 28 | if not placa: #NodeMCU ESP8266 29 | bits = potenciometro.read(); 30 | volts_10 = bits * factor_10 31 | print('\nValor en 10 bits: {}, y en volts: {}'.format(bits, volts_10)) 32 | 33 | bits_16 = potenciometro.read_u16(); 34 | volts_16 = bits_16 * factor_16 35 | 36 | 37 | print('Valor en 16 bits: {}, y en volts: {}'.format(bits_16, volts_16)) 38 | sleep(1) 39 | 40 | 41 | if __name__ == '__main__': 42 | main() 43 | -------------------------------------------------------------------------------- /ADC/temp_pico.py: -------------------------------------------------------------------------------- 1 | """ 2 | Programa de Ejemplo Sensor de Temperatura de la Pico 3 | by: Sergio Andrés Castaño Giraldo 4 | https://controlautomaticoeducacion.com/ 5 | Canal de YouTube: https://www.youtube.com/c/SergioACastañoGiraldo 6 | """ 7 | 8 | from machine import ADC 9 | from utime import sleep 10 | 11 | 12 | def main(): 13 | sensor_temp = ADC(4) #Sensor interno de temperatura 14 | factor_16 = 3.21 / (65535) 15 | 16 | while True: 17 | voltaje = sensor_temp.read_u16() * factor_16 18 | temperatura = 27 - (voltaje - 0.706)/0.001721 19 | print('La temperatura es: ',temperatura) 20 | sleep(2) 21 | 22 | 23 | if __name__ == '__main__': 24 | main() 25 | -------------------------------------------------------------------------------- /Display7/display7.py: -------------------------------------------------------------------------------- 1 | """ 2 | Display 7 Segmentos usando MicroPython 3 | by: Sergio Andres Castaño Giraldo 4 | Referencia: https://controlautomaticoeducacion.com/ 5 | """ 6 | from machine import Pin 7 | import utime 8 | 9 | 10 | def show(digito, display): 11 | """ 12 | Muestra el digito en el display 7 segmentos 13 | 14 | llamado de la función: 15 | show(digito, display) 16 | 17 | Parametros de entrada: 18 | digito -> Digito a mostrar 19 | display -> Lista con los pines del display (Pin.OUT) 20 | 21 | by: Sergio Andres Castaño Giraldo 22 | https://controlautomaticoeducacion.com/ 23 | """ 24 | #Tupla con los números de un display 7 segmentos catodo común 25 | catodo = (int('3f',16),int('06',16),int('5b',16),int('4f',16),int('66',16),int('6d',16),int('7d',16),int('07',16),int('7f',16),int('67',16)) 26 | 27 | bit = 1; 28 | for i in range(7): 29 | if (catodo[digito] & bit) == 0: 30 | display[i].off() 31 | else: 32 | display[i].on() 33 | bit = bit << 1 34 | 35 | 36 | def main(): 37 | 38 | #Configura los pines del display 7 segmentos 39 | display_pins = (19, 18, 13, 15, 14, 16, 17) #Raspberry Pi Pico 40 | #display_pins = (16, 5, 4, 0, 2, 14, 12) #NodeMCU8266 41 | display = list() 42 | for i in range(7): 43 | display.append( Pin( display_pins[i], Pin.OUT ) ) 44 | 45 | 46 | #Inicia las variables 47 | contador = 0 48 | sentido = True 49 | 50 | 51 | while True: 52 | #Muestra el valor del contador en el display 53 | show(contador, display) 54 | 55 | #Verifica si incrementa o decrementa el contador 56 | if sentido: 57 | contador += 1 58 | else: 59 | contador -= 1 60 | 61 | #Si contador es nueve coloque el sentido del contador a decrementar 62 | if contador == 9: 63 | sentido = False 64 | 65 | #Si contador es cero coloque el sentido del contador a incrementar 66 | if contador == 0: 67 | sentido = True 68 | 69 | #Esperar por 1 segundo 70 | utime.sleep(1) 71 | 72 | 73 | #Entry Point 74 | if __name__ == '__main__': 75 | main() -------------------------------------------------------------------------------- /Display7/display7_m.py: -------------------------------------------------------------------------------- 1 | """ 2 | Display 7 Segmentos usando MicroPython 3 | by: Sergio Andres Castaño Giraldo 4 | Referencia: https://controlautomaticoeducacion.com/ 5 | """ 6 | from machine import Pin 7 | import utime 8 | 9 | 10 | def show(digito, display): 11 | """ 12 | Muestra el digito en el display 7 segmentos 13 | 14 | llamado de la función: 15 | show(digito, display) 16 | 17 | Parametros de entrada: 18 | digito -> Digito a mostrar 19 | display -> Lista con los pines del display (Pin.OUT) 20 | 21 | by: Sergio Andres Castaño Giraldo 22 | https://controlautomaticoeducacion.com/ 23 | """ 24 | #Tupla con los números de un display 7 segmentos catodo común 25 | catodo = (int('3f',16),int('06',16),int('5b',16),int('4f',16),int('66',16),int('6d',16),int('7d',16),int('07',16),int('7f',16),int('67',16)) 26 | 27 | bit = 1; 28 | for segmento in display: 29 | if (catodo[digito] & bit) == 0: 30 | segmento.off() 31 | else: 32 | segmento.on() 33 | bit = bit << 1 34 | 35 | 36 | def main(): 37 | 38 | #Configura los pines del display 7 segmentos 39 | display_pins = (19, 18, 13, 15, 14, 16, 17) #Raspberry Pi Pico 40 | #display_pins = (16, 5, 4, 0, 2, 14, 12) #NodeMCU8266 41 | display = list() 42 | for GPIO in display_pins: 43 | display.append( Pin( GPIO, Pin.OUT ) ) 44 | 45 | 46 | #Inicia las variables 47 | contador = 0 48 | sentido = True 49 | 50 | 51 | while True: 52 | #Muestra el valor del contador en el display 53 | show(contador, display) 54 | 55 | #Verifica si incrementa o decrementa el contador 56 | if sentido: 57 | contador += 1 58 | else: 59 | contador -= 1 60 | 61 | #Si contador es nueve coloque el sentido del contador a decrementar 62 | if contador == 9: 63 | sentido = False 64 | 65 | #Si contador es cero coloque el sentido del contador a incrementar 66 | if contador == 0: 67 | sentido = True 68 | 69 | #Esperar por 1 segundo 70 | utime.sleep(1) 71 | 72 | 73 | #Entry Point 74 | if __name__ == '__main__': 75 | main() -------------------------------------------------------------------------------- /Display7/display7seg.py: -------------------------------------------------------------------------------- 1 | """ 2 | Clase de Display 7 Segmentos usando MicroPython 3 | by: Sergio Andres Castaño Giraldo 4 | Referencia: https://controlautomaticoeducacion.com/ 5 | """ 6 | 7 | from machine import Pin 8 | 9 | 10 | class Display: 11 | 12 | 13 | def __init__(self, Pins, kind = 'C'): 14 | self.kind = kind 15 | 16 | display = list() 17 | for i in range(7): 18 | display.append( Pin(Pins[i], Pin.OUT) ) 19 | 20 | #Tupla con las posiciones del display 21 | self.display = display 22 | 23 | 24 | 25 | def show(self, digit): 26 | bit = 1; 27 | 28 | #Display Cátodo Común 29 | if self.kind.upper() == 'C': 30 | numbers = (int('3f',16),int('06',16),int('5b',16),int('4f',16),int('66',16),int('6d',16),int('7d',16),int('07',16),int('7f',16),int('67',16)) 31 | #Display Ánodo Común 32 | elif self.kind.upper() == 'A': 33 | numbers = (int('40',16),int('79',16),int('24',16),int('30',16),int('19',16),int('12',16),int('02',16),int('78',16),int('00',16),int('18',16)) 34 | else: 35 | return 36 | 37 | for i in range(7): 38 | if (numbers[digit] & bit) == 0: 39 | self.display[i].off() 40 | else: 41 | self.display[i].on() 42 | bit = bit << 1 43 | 44 | 45 | -------------------------------------------------------------------------------- /Display7/display7seg2.py: -------------------------------------------------------------------------------- 1 | """ 2 | Clase de Display 7 Segmentos usando MicroPython 3 | by: Sergio Andres Castaño Giraldo 4 | Referencia: https://controlautomaticoeducacion.com/ 5 | """ 6 | 7 | from machine import Pin 8 | import utime 9 | 10 | class Display: 11 | 12 | 13 | def __init__(self, Pins, kind = 'C', transistor_pins = 1): 14 | self.kind = kind 15 | self.number_digit = len(transistor_pins) 16 | 17 | #Configura los pines del display como salida 18 | display = list() 19 | for i in range(7): 20 | display.append( Pin(Pins[i], Pin.OUT) ) 21 | 22 | #Configura los pines de los transistores como salida 23 | transistors = list() 24 | for i in range(self.number_digit): 25 | transistors.append( Pin(transistor_pins[i], Pin.OUT) ) 26 | 27 | #Tupla con las posiciones del display 28 | self.display = display 29 | 30 | #Tupla con las posiciones de los transistores 31 | self.transistors = transistors 32 | 33 | def show(self, digits): 34 | #Realiza la multiplexación 35 | for i in range( self.number_digit ): 36 | number = int((digits % 10 ** (i+1)) / 10 ** i) 37 | self._show_one_display(number) 38 | self.transistors[i].on() 39 | utime.sleep_ms(1) 40 | self.transistors[i].off() 41 | 42 | 43 | #Metodo provado para mostrar número en un solo display 44 | def _show_one_display(self, digit): 45 | bit = 1; 46 | 47 | #Display Cátodo Común 48 | if self.kind.upper() == 'C': 49 | numbers = (int('3f',16),int('06',16),int('5b',16),int('4f',16),int('66',16),int('6d',16),int('7d',16),int('07',16),int('7f',16),int('67',16)) 50 | #Display Ánodo Común 51 | elif self.kind.upper() == 'A': 52 | numbers = (int('40',16),int('79',16),int('24',16),int('30',16),int('19',16),int('12',16),int('02',16),int('78',16),int('00',16),int('18',16)) 53 | else: 54 | return 55 | 56 | for i in range(7): 57 | if (numbers[digit] & bit) == 0: 58 | self.display[i].off() 59 | else: 60 | self.display[i].on() 61 | bit = bit << 1 62 | 63 | 64 | -------------------------------------------------------------------------------- /Display7/mostrar.py: -------------------------------------------------------------------------------- 1 | from machine import Pin 2 | 3 | def show(digito, display): 4 | """ 5 | Muestra el digito en el display 7 segmentos 6 | 7 | llamado de la función: 8 | show(digito, display) 9 | 10 | Parametros de entrada: 11 | digito -> Digito a mostrar 12 | display -> Lista con los pines del display (Pin.OUT) 13 | 14 | by: Sergio Andres Castaño Giraldo 15 | https://controlautomaticoeducacion.com/ 16 | """ 17 | #Tupla con los números de un display 7 segmentos catodo común 18 | catodo = (int('3f',16),int('06',16),int('5b',16),int('4f',16),int('66',16),int('6d',16),int('7d',16),int('07',16),int('7f',16),int('67',16)) 19 | 20 | bit = 1; 21 | for i in range(7): 22 | if (catodo[digito] & bit) == 0: 23 | display[i].off() 24 | else: 25 | display[i].on() 26 | bit = bit << 1 -------------------------------------------------------------------------------- /Display7/multiplexa.py: -------------------------------------------------------------------------------- 1 | """ 2 | Display 7 Segmentos usando MicroPython 3 | Importación de nuestro propio módulo display7seg 4 | 5 | by: Sergio Andres Castaño Giraldo 6 | Referencia: https://controlautomaticoeducacion.com/ 7 | """ 8 | 9 | from machine import Pin 10 | import utime 11 | import display7seg 12 | 13 | def temporizacion(display7, contador): 14 | contret=50 #Cargue con 50 la variable CONTRET 15 | while (contret>0): #Mientras que la variable CONTRET sea mayor que cero 16 | display7.show(contador) #Llamar la rutina MOSTRAR 17 | contret -= 1 #Decremente la variable CONTRET 18 | 19 | def main(): 20 | 21 | #Raspberry Pi PICO (4 digitos) 22 | display_pins = (16, 18, 13, 14, 15, 17, 12) #(a, b, c, d, e, f, g) 23 | transistor_pins = (22, 21, 20, 19) 24 | 25 | #NodeMCU 8266v3 (2 Digitos) 26 | #display_pins = (16, 5, 4, 0, 2, 14, 12) 27 | #transistor_pins = (13, 15) 28 | 29 | display7 = display7seg.Display(display_pins,transistor_pins = transistor_pins ) 30 | 31 | #Inicia las variables 32 | contador = 0 33 | sentido = True 34 | 35 | 36 | while True: 37 | #Muestra el valor del contador en el display 38 | temporizacion(display7, contador) 39 | 40 | #Verifica si incrementa o decrementa el contador 41 | if sentido: 42 | contador += 1 43 | else: 44 | contador -= 1 45 | 46 | #Si contador es nueve coloque el sentido del contador a decrementar 47 | if contador == 9999: 48 | sentido = False 49 | 50 | #Si contador es cero coloque el sentido del contador a incrementar 51 | if contador == 0: 52 | sentido = True 53 | 54 | 55 | 56 | #Entry Point 57 | if __name__ == '__main__': 58 | main() -------------------------------------------------------------------------------- /Display7/prueba.py: -------------------------------------------------------------------------------- 1 | """ 2 | Display 7 Segmentos usando MicroPython 3 | Importación de nuestro propio módulo display7seg 4 | 5 | by: Sergio Andres Castaño Giraldo 6 | Referencia: https://controlautomaticoeducacion.com/ 7 | """ 8 | 9 | from machine import Pin 10 | import utime 11 | import display7seg 12 | 13 | 14 | 15 | def main(): 16 | #Configura los pines del display 7 segmentos 17 | display_pins = (19, 18, 13, 15, 14, 16, 17) #Raspberry Pi Pico 18 | #display_pins = (16, 5, 4, 0, 2, 14, 12) #NodeMCU8266 19 | 20 | display7 = display7seg.Display(display_pins) 21 | 22 | #Inicia las variables 23 | contador = 0 24 | sentido = True 25 | 26 | 27 | while True: 28 | #Muestra el valor del contador en el display 29 | #mostrar_display(numeros[contador], display) 30 | display7.show(contador) 31 | 32 | #Verifica si incrementa o decrementa el contador 33 | if sentido: 34 | contador += 1 35 | else: 36 | contador -= 1 37 | 38 | #Si contador es nueve coloque el sentido del contador a decrementar 39 | if contador == 9: 40 | sentido = False 41 | 42 | #Si contador es cero coloque el sentido del contador a incrementar 43 | if contador == 0: 44 | sentido = True 45 | 46 | #Esperar por 1 segundo 47 | utime.sleep(1) 48 | 49 | 50 | #Entry Point 51 | if __name__ == '__main__': 52 | main() -------------------------------------------------------------------------------- /ESP8266/esp8266-20210202-v1.14.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sergioacg/MicroPython/a80ab1c40cd3b396f3c6e35f6f4909e630dba745/ESP8266/esp8266-20210202-v1.14.bin -------------------------------------------------------------------------------- /Entradas GPIO/Entradas.py: -------------------------------------------------------------------------------- 1 | from machine import Pin 2 | import utime 3 | 4 | 5 | def main(): 6 | 7 | # Salidas Digitales GPIO Raspberry Pi Pico 8 | led_amarillo = Pin(20, Pin.OUT) 9 | led_azul = Pin(19, Pin.OUT) 10 | led_rojo = Pin(18, Pin.OUT) 11 | 12 | # Entradas Digitales GPIO Raspberry Pi Pico 13 | boton_izquierda = Pin(17, Pin.IN, Pin.PULL_UP) 14 | boton_derecha = Pin(16, Pin.IN) 15 | 16 | """ 17 | # Salidas Digitales GPIO NodeMCU 8266v3 18 | led_amarillo = Pin(16, Pin.OUT) 19 | led_azul = Pin(5, Pin.OUT) 20 | led_rojo = Pin(4, Pin.OUT) 21 | 22 | # Entradas Digitales GPIO NodeMCU 8266v3 23 | boton_izquierda = Pin(0, Pin.IN, Pin.PULL_UP) 24 | boton_derecha = Pin(2, Pin.IN) 25 | """ 26 | 27 | # Almaceno los leds en una lista 28 | leds = [led_amarillo, led_azul, led_rojo] 29 | 30 | #variables de desplazamiento 31 | izquierda = True 32 | derecha = False 33 | 34 | for led in leds: 35 | led.off() 36 | 37 | #Ciclo infinito 38 | while True: 39 | #Si presiona el botón de la izquierda 40 | if boton_izquierda.value() == 0: 41 | izquierda = True 42 | derecha = False 43 | 44 | #Si presiona el botón de la derecha 45 | if boton_derecha.value() == 1: 46 | izquierda = False 47 | derecha = True 48 | 49 | #Si presiona ambos botones 50 | if boton_izquierda.value() == 0 and boton_derecha.value() == 1 : 51 | izquierda = True 52 | derecha = True 53 | 54 | #Rotación de leds a la izquierda 55 | if izquierda and not derecha: 56 | for led in leds: 57 | led.on() 58 | utime.sleep_ms(100) 59 | led.off() 60 | utime.sleep_ms(100) 61 | 62 | #Rotación de leds a la derecha 63 | if not izquierda and derecha: 64 | for i in range(2,-1,-1): 65 | leds[i].on() 66 | utime.sleep_ms(100) 67 | leds[i].off() 68 | utime.sleep_ms(100) 69 | 70 | if izquierda and derecha: 71 | for led in leds: 72 | led.on() 73 | 74 | 75 | 76 | if __name__ == '__main__': 77 | main() 78 | -------------------------------------------------------------------------------- /Entradas GPIO/ejemplo_led.py: -------------------------------------------------------------------------------- 1 | from machine import Pin 2 | import utime 3 | 4 | boton = Pin(2, Pin.IN, Pin.PULL_UP) 5 | led = Pin(16, Pin.OUT) 6 | 7 | while True: 8 | if not boton(): 9 | led.on() 10 | else: 11 | led.off() -------------------------------------------------------------------------------- /IRQ/boton.py: -------------------------------------------------------------------------------- 1 | import machine 2 | import utime 3 | 4 | 5 | def interrupcion(pin): 6 | global contador 7 | contador += 1 8 | print(contador) 9 | 10 | 11 | 12 | contador = 0 13 | 14 | boton = machine.Pin(15, machine.Pin.IN, machine.Pin.PULL_UP) 15 | boton.irq(interrupcion, machine.Pin.IRQ_FALLING) 16 | -------------------------------------------------------------------------------- /IRQ/velocidad.py: -------------------------------------------------------------------------------- 1 | """ 2 | Programa de Ejemplo de PWM 3 | Control de Giro y Velocidad de un motor DC con Puente H 4 | 5 | by: Sergio Andrés Castaño Giraldo 6 | controlautomaticoeducacion.com 7 | Canal de YouTube: https://www.youtube.com/c/SergioACastañoGiraldo 8 | """ 9 | 10 | import machine 11 | import utime 12 | 13 | 14 | def encoder_handler(pin): 15 | global paso 16 | paso += 1 17 | 18 | 19 | 20 | def main(): 21 | global paso 22 | paso = 0 23 | 24 | #Placa -> Raspberry Pi Pico = True, ESP8266 = False 25 | placa= True 26 | 27 | 28 | frequency = 10000 #10Khz 29 | sentido = True #Sentido derecha 30 | 31 | if placa: 32 | potenciometro = machine.ADC(26) #Raspberry Pi Pico ADC0 33 | r_pwm = machine.PWM(machine.Pin(16)) #PWM derecha 34 | r_pwm.freq(frequency) 35 | l_pwm = machine.PWM(machine.Pin(17)) #PWM izquierda 36 | l_pwm.freq(frequency) 37 | boton = machine.Pin(15, machine.Pin.IN, machine.Pin.PULL_UP) 38 | encoder = machine.Pin(14, machine.Pin.IN) 39 | encoder.irq(trigger=machine.Pin.IRQ_FALLING, handler=encoder_handler) 40 | else: 41 | potenciometro = machine.ADC(0) #NodeMCU8266v3 ADC0 42 | r_pwm = machine.PWM(machine.Pin(4), frequency) #PWM derecha 43 | l_pwm = machine.PWM(machine.Pin(5), frequency) #PWM izquierda 44 | boton = machine.Pin(2, machine.Pin.IN, machine.Pin.PULL_UP) 45 | encoder = machine.Pin(14, machine.Pin.IN) 46 | encoder.irq(trigger=machine.Pin.IRQ_FALLING, handler=encoder_handler) 47 | 48 | timer_start = utime.ticks_ms() 49 | 50 | while True: 51 | #Pregunta por el boton 52 | if not boton(): 53 | utime.sleep_ms(200) #Anti-Rebote 54 | while not boton(): 55 | pass 56 | utime.sleep_ms(200) #Anti-Rebote 57 | sentido = not sentido 58 | 59 | 60 | #Aplica el PWM al motor 61 | if placa: 62 | velocidad = potenciometro.read_u16(); 63 | if sentido: 64 | r_pwm.duty_u16(velocidad) 65 | l_pwm.duty_u16(0) 66 | else: 67 | r_pwm.duty_u16(0) 68 | l_pwm.duty_u16(velocidad) 69 | else: 70 | velocidad = potenciometro.read(); 71 | if sentido: 72 | r_pwm.duty(velocidad) 73 | l_pwm.duty(0) 74 | else: 75 | r_pwm.duty(0) 76 | l_pwm.duty(velocidad) 77 | 78 | 79 | # Usando únicamnete Retardo 80 | utime.sleep_ms(1000) 81 | state = machine.disable_irq() 82 | rpm = paso * 60 / 2 83 | paso = 0 84 | print(rpm, 'RPM') 85 | machine.enable_irq(state) 86 | 87 | """ 88 | timer_elapsed = utime.ticks_diff(utime.ticks_ms(), timer_start) 89 | if timer_elapsed >= 1000: 90 | #Calculo de las RPM (2 aspas) 91 | state = machine.disable_irq() 92 | rpm = paso * 60 / 2 93 | paso = 0 94 | machine.enable_irq(state) 95 | timer_start = utime.ticks_ms() 96 | print(rpm, 'RPM') 97 | """ 98 | 99 | if __name__ == '__main__': 100 | main() -------------------------------------------------------------------------------- /LCD_I2C/LCD_Prueba.py: -------------------------------------------------------------------------------- 1 | import utime 2 | 3 | from machine import I2C 4 | from lcd_api import LcdApi 5 | from pico_i2c_lcd import I2cLcd 6 | 7 | I2C_ADDR = 0x27 8 | I2C_NUM_ROWS = 4 9 | I2C_NUM_COLS = 20 10 | 11 | i2c = I2C(0, sda=machine.Pin(0), scl=machine.Pin(1), freq=400000) 12 | lcd = I2cLcd(i2c, I2C_ADDR, I2C_NUM_ROWS, I2C_NUM_COLS) 13 | 14 | lcd.clear() 15 | lcd.move_to(5,0) 16 | lcd.putstr("Howdy") 17 | lcd.move_to(2,1) 18 | lcd.putstr("Tinkernerdz!") 19 | utime.sleep(2) -------------------------------------------------------------------------------- /LCD_I2C/lcd_i2c.py: -------------------------------------------------------------------------------- 1 | import utime 2 | from machine import I2C,Pin 3 | from lcd_api import LcdApi 4 | from pico_i2c_lcd import I2cLcd 5 | 6 | #Dirección del I2C y tamaño del LCD 7 | I2C_ADDR = 0x27 8 | I2C_NUM_ROWS = 2 9 | I2C_NUM_COLS = 16 10 | 11 | # Raspberry Pi Pico 12 | i2c = I2C(0, sda=Pin(0), scl=Pin(1), freq=400000) 13 | 14 | #Esp8266 15 | #i2c = I2C(sda=Pin(4), scl=Pin(5), freq=100000) 16 | 17 | #Configuración LCD 18 | lcd = I2cLcd(i2c, I2C_ADDR, I2C_NUM_ROWS, I2C_NUM_COLS) 19 | 20 | battery_0 = [0x0E, 21 | 0x1B, 22 | 0x11, 23 | 0x11, 24 | 0x11, 25 | 0x11, 26 | 0x11, 27 | 0x1F] 28 | battery_15 = [0x0E, 29 | 0x1B, 30 | 0x11, 31 | 0x11, 32 | 0x11, 33 | 0x11, 34 | 0x1F, 35 | 0x1F] 36 | battery_30 = [ 0x0E, 37 | 0x1B, 38 | 0x11, 39 | 0x11, 40 | 0x11, 41 | 0x1F, 42 | 0x1F, 43 | 0x1F] 44 | battery_45 = [0x0E, 45 | 0x1B, 46 | 0x11, 47 | 0x11, 48 | 0x1F, 49 | 0x1F, 50 | 0x1F, 51 | 0x1F] 52 | battery_60 = [0x0E, 53 | 0x1B, 54 | 0x11, 55 | 0x1F, 56 | 0x1F, 57 | 0x1F, 58 | 0x1F, 59 | 0x1F] 60 | battery_75 = [0x0E, 61 | 0x1B, 62 | 0x1F, 63 | 0x1F, 64 | 0x1F, 65 | 0x1F, 66 | 0x1F, 67 | 0x1F] 68 | battery_100 = [0x0E, 69 | 0x1F, 70 | 0x1F, 71 | 0x1F, 72 | 0x1F, 73 | 0x1F, 74 | 0x1F, 75 | 0x1F] 76 | 77 | 78 | def lcd_str(message, col, row): 79 | lcd.move_to(col, row) 80 | lcd.putstr(message) 81 | 82 | 83 | def main(): 84 | lcd.custom_char(0, bytearray(battery_0)) 85 | lcd.custom_char(1, bytearray(battery_15)) 86 | lcd.custom_char(2, bytearray(battery_30)) 87 | lcd.custom_char(3, bytearray(battery_45)) 88 | lcd.custom_char(4, bytearray(battery_60)) 89 | lcd.custom_char(5, bytearray(battery_75)) 90 | lcd.custom_char(6, bytearray(battery_100)) 91 | 92 | 93 | while True: 94 | lcd.clear() 95 | lcd_str("Battery:", 0, 0) 96 | lcd.move_to(0,1) 97 | for i in range(0,7): 98 | lcd.putchar(chr(i)) 99 | utime.sleep(3) 100 | 101 | lcd.clear() 102 | lcd.move_to(0,0) 103 | lcd.putstr("Suscribete a ") 104 | utime.sleep(1) 105 | lcd.move_to(0,1) 106 | lcd.putstr("Control ") 107 | utime.sleep(1) 108 | lcd_str("Automatico ", 0, 0) 109 | utime.sleep(1) 110 | lcd_str("Educacion ", 0, 1) 111 | utime.sleep(1) 112 | 113 | lcd.clear() 114 | lcd_str("Numeros en", 3,0) 115 | lcd_str("Esquinas", 4,1) 116 | utime.sleep(1) 117 | 118 | lcd_str("1", 0,0) 119 | utime.sleep(1) 120 | lcd_str("2", 15,0) 121 | utime.sleep(1) 122 | lcd_str("3", 0,1) 123 | utime.sleep(1) 124 | lcd_str("4", 15,1) 125 | utime.sleep(1) 126 | 127 | lcd.clear() 128 | lcd_str("Suscribete", 0, 0) 129 | lcd_str("Activa: CAMPANA", 0, 1) 130 | lcd.blink_cursor_on() 131 | utime.sleep(2) 132 | 133 | #Backspace 134 | for j in range(1, -1, -1): 135 | for i in range(15, -1, -1): 136 | lcd.move_to(i, j) 137 | lcd.putstr(' ') 138 | utime.sleep_ms(100) 139 | utime.sleep(1) 140 | lcd.hide_cursor() 141 | 142 | #BackLight 143 | lcd.clear() 144 | lcd.backlight_off() 145 | lcd_str("BackLight OFF", 0, 0) 146 | utime.sleep(3) 147 | 148 | lcd.clear() 149 | lcd.backlight_on() 150 | lcd_str("BackLight ON", 0, 0) 151 | utime.sleep(3) 152 | 153 | 154 | if __name__ == '__main__': 155 | main() -------------------------------------------------------------------------------- /Motor PaP/Motor_PaP.py: -------------------------------------------------------------------------------- 1 | """ 2 | Programa de Ejemplo de Motor Paso a Paso Unipolar 3 | by: Sergio Andrés Castaño Giraldo 4 | https://controlautomaticoeducacion.com/ 5 | Canal de YouTube: https://www.youtube.com/c/SergioACastañoGiraldo 6 | """ 7 | 8 | from machine import Pin 9 | import utime 10 | 11 | 12 | def envia_pasos(paso, tipo, bobinas): 13 | bit = 1; 14 | for i in range(4): 15 | if (tipo[paso] & bit) == 0: 16 | bobinas[i].off() 17 | else: 18 | bobinas[i].on() 19 | bit = bit << 1 20 | 21 | 22 | def main(): 23 | #Define los pines de los 4 botones Raspberry Pi PICO 24 | boton_horario = Pin(19, Pin.IN, Pin.PULL_UP) 25 | boton_antihorario = Pin(18, Pin.IN, Pin.PULL_UP) 26 | boton_velocidad = Pin(17, Pin.IN, Pin.PULL_UP) 27 | boton_pasos = Pin(16, Pin.IN, Pin.PULL_UP) 28 | 29 | #Define los pines del Motor PaP 30 | motor_pins = (13, 12, 11, 10) 31 | 32 | """ 33 | #Define los pines de los 4 botones NodeMCU8266 34 | boton_horario = Pin(5, Pin.IN, Pin.PULL_UP) 35 | boton_antihorario = Pin(4, Pin.IN, Pin.PULL_UP) 36 | boton_velocidad = Pin(0, Pin.IN, Pin.PULL_UP) 37 | boton_pasos = Pin(2, Pin.IN, Pin.PULL_UP) 38 | 39 | #Define los pines del Motor PaP 40 | motor_pins = (14, 12, 13, 15) 41 | """ 42 | 43 | #Configura las GPIO como Salidas 44 | bobinas = list() 45 | for i in motor_pins: 46 | bobinas.append( Pin(i, Pin.OUT) ) 47 | 48 | #Configura las secuencia de los pasos 49 | 50 | #Secuencia a 1 paso 51 | un_paso = ( int('1000',2), 52 | int('0100',2), 53 | int('0010',2), 54 | int('0001',2) ) 55 | #Secuencia a 2 pasos 56 | dos_pasos = ( int('1100',2), 57 | int('0110',2), 58 | int('0011',2), 59 | int('1001',2) ) 60 | #Secuencia a 1/2 paso 61 | medio_paso = ( int('1000',2), 62 | int('1100',2), 63 | int('0100',2), 64 | int('0110',2), 65 | int('0010',2), 66 | int('0011',2), 67 | int('0001',2), 68 | int('1001',2) ) 69 | 70 | #variables del programa 71 | sentido = True #True -> Horario, False -> Anti-Horario 72 | velocidad = (5, 10, 30, 100, 500) #Velocidades 73 | configuracion = 1 #Selecciona los pasos 74 | contador_pasos = 0 #cuenta del paso actual 75 | contador_velocidad = 0 76 | cantidad_pasos = 3 77 | 78 | while True: 79 | 80 | #Giro en Sentido Horario 81 | if not boton_horario.value(): 82 | utime.sleep_ms(100) #Anti-Rebote 83 | print('Sentido horario') 84 | sentido = True 85 | contador_pasos = -1 86 | 87 | #Giro en Sentido AntiHorario 88 | if not boton_antihorario.value(): 89 | utime.sleep_ms(100) #Anti-Rebote 90 | print('Sentido antihorario') 91 | sentido = False 92 | contador_pasos = cantidad_pasos 93 | 94 | #Cambio de la secuencia de pasos 95 | if not boton_pasos(): #Recordar que los objetos pin son invocables. 96 | utime.sleep_ms(100) #Anti-Rebote 97 | print('Cambio de secuencia de pasos') 98 | #esperar hasta soltar el boton 99 | while boton_pasos.value() == 0: 100 | pass 101 | utime.sleep_ms(100) #Anti-Rebote 102 | configuracion += 1 103 | if configuracion > 3: 104 | configuracion = 1 105 | 106 | if configuracion != 3 and contador_pasos > 3: 107 | contador_pasos = contador_pasos - 4 108 | 109 | 110 | #Cambio de la velocidad del motor 111 | if boton_velocidad.value() == 0: 112 | print('Cambio de velocidad') 113 | utime.sleep_ms(100) #Anti-Rebote 114 | #esperar hasta soltar el boton 115 | while boton_velocidad.value() == 0: 116 | pass 117 | utime.sleep_ms(100) #Anti-Rebote 118 | contador_velocidad += 1 119 | if contador_velocidad > 4: 120 | contador_velocidad = 0 121 | 122 | #************************************# 123 | #***** Logica de los Contadores ****# 124 | #************************************# 125 | if sentido: 126 | contador_pasos += 1 127 | if contador_pasos > cantidad_pasos: 128 | contador_pasos = 0 129 | else: 130 | contador_pasos -= 1 131 | if contador_pasos < 0: 132 | contador_pasos = cantidad_pasos 133 | 134 | #************************************# 135 | #***** Logica de los Contadores ****# 136 | #************************************# 137 | if configuracion == 1: 138 | envia_pasos(contador_pasos, un_paso, bobinas) 139 | cantidad_pasos = 3 140 | elif configuracion == 2: 141 | envia_pasos(contador_pasos, dos_pasos, bobinas) 142 | cantidad_pasos = 3 143 | else: 144 | envia_pasos(contador_pasos, medio_paso, bobinas) 145 | cantidad_pasos = 7 146 | 147 | # Velocidad 148 | utime.sleep_ms(velocidad[contador_velocidad]) 149 | 150 | 151 | #Entry Point 152 | if __name__ == '__main__': 153 | main() -------------------------------------------------------------------------------- /Nivel/Level.py: -------------------------------------------------------------------------------- 1 | """ 2 | Nivel de un Tanque 3 | 4 | by: Sergio Andrés Castaño Giraldo 5 | Sitio web: https://controlautomaticoeducacion.com/ 6 | Canal de YouTube: https://www.youtube.com/c/SergioACastañoGiraldo 7 | """ 8 | 9 | from machine import Pin, PWM, ADC, I2C, Timer 10 | from utime import sleep_ms 11 | from ssd1306 import SSD1306_I2C 12 | 13 | 14 | #OLED 15 | WIDTH = 128 16 | HEIGHT = 64 17 | #Configuración de PINES 18 | sensor = ADC(26) 19 | voltaje = ADC(27) 20 | potenciometro = ADC(28) 21 | pwm = PWM(Pin(20)) 22 | pwm.freq(40000) 23 | i2c = I2C(1, scl = Pin(19), sda = Pin(18), freq = 200000) 24 | 25 | #OLED 26 | oled = SSD1306_I2C(WIDTH, HEIGHT, i2c) 27 | 28 | #Global Variables 29 | t = 0 30 | y = [55, 55] 31 | x = [25, 25] 32 | level = 0 33 | 34 | 35 | 36 | def plot_time(yp, t, x, y, var = [0.0,18], vpts=[25, 16, 40], hpts = [25, 55, 112]): 37 | """" 38 | Graph function of the Cartesian plane in relation to time: 39 | by: Sergio Andres Castaño Giraldo 40 | 41 | plot_time(yp, t, x, y, var = [0.0,3.3], vpts=[25, 16, 40], hpts = [25, 55, 112]): 42 | 43 | yp: dependent variable 44 | t: time (used while the Cartesian plane is not complete) 45 | x: List of two positions of variable x, x[0] is the position in past x and x[1] position of current x. 46 | y: List of two positions of the variable y, y[0] is the position in y past and y[1] position of current x. 47 | var = [0.0,3.3]: Magnitude of the variable (default voltage) 48 | vpts = [25, 16, 40]: points on the vertical y axis. 49 | hpts = [25, 55, 112]: points on the vertical x axis. 50 | 51 | Example: 52 | #Global Variables 53 | t = 0 54 | y = [55, 55] 55 | x = [25, 25] 56 | #Function: 57 | volts = pot.read_u16 () * FACTOR 58 | t, x, y = plot_time (volts, t, x, y) 59 | sleep_ms (500) 60 | """ 61 | global dt 62 | #Axis 63 | oled.vline(vpts[0], vpts[1], vpts[2], 1) #x, y, h 64 | oled.hline(hpts[0], hpts[1], hpts[2], 1) #x, y, w 65 | oled.text(str(round(var[0],1)), vpts[0]-25, hpts[1]-5) 66 | oled.text(str(round(var[1],1)), vpts[0]-25, vpts[1]) 67 | #Level 68 | y[1] = int((yp-var[0])/(var[1]-var[0]) * (vpts[1]-hpts[1]) + hpts[1]) #Interpolation 69 | 70 | if t < hpts[2] - hpts[0]: 71 | x[1] = x[0]+1 72 | else: 73 | x[1] = hpts[2] 74 | 75 | #Plot the line 76 | oled.line(x[0],y[0],x[1],y[1],1) 77 | oled.show() 78 | 79 | #Update past values 80 | y[0] = y[1] 81 | x[0] = x[1] 82 | 83 | #If you have already reached the end of the graph then ... 84 | if t > hpts[2] - hpts[0]: 85 | #Erases the first few pixels of the graph and the y-axis. 86 | oled.fill_rect(vpts[0],vpts[1],2,vpts[2],0) 87 | #Clears the entire y-axis scale 88 | oled.fill_rect(vpts[0]-25, vpts[1],vpts[0],vpts[2]+5,0) 89 | #shifts the graph one pixel to the left 90 | oled.scroll(-1,0) 91 | #Axis 92 | oled.vline(vpts[0], vpts[1], vpts[2], 1) #x, y, h 93 | oled.hline(hpts[0], hpts[1], hpts[2], 1) #x, y, w 94 | oled.text(str(round(var[0],1)), vpts[0]-25, hpts[1]-5) 95 | oled.text(str(round(var[1],1)), vpts[0]-25, vpts[1]) 96 | else: 97 | t += 1 98 | 99 | return t,x,y 100 | 101 | 102 | 103 | def main(): 104 | global level, t, y, x 105 | 106 | #Sensor Presión 107 | tolP=0.4 # Ajusta la medida de presión 108 | rho = 1000 #Densidad del Agua 109 | g=9.8 #Gravedad 110 | factor_16 = 3.3 / (65535) 111 | 112 | while True: 113 | 114 | #Presión en Kpa según gráfica 4 del Datasheet 115 | level_sum = 0 116 | for i in range(200): 117 | Vout = sensor.read_u16() * factor_16 118 | Vs = voltaje.read_u16() * factor_16 119 | presion = ( Vout - 0.04*Vs ) / (0.09 * Vs) + tolP #kPa 120 | level_sum += ((presion*1000)/(rho*g))*100; #Medida de Nivel del tanque 121 | 122 | level_x = level_sum / 200 123 | level = 1.157 * level_x - 2.1208 124 | 125 | #print(level) 126 | 127 | t,x,y = plot_time(level,t,x,y) 128 | oled.fill_rect(0,0,128,15,0) 129 | oled.text("Lvl: ", 0, 0) 130 | oled.text(str(round(level,1)), 32, 0) 131 | oled.show() 132 | 133 | #Aplica el PWM al motor 134 | velocidad = int(potenciometro.read_u16()) 135 | pwm.duty_u16(velocidad) 136 | 137 | sleep_ms(100) 138 | 139 | 140 | if __name__ == '__main__': 141 | main() -------------------------------------------------------------------------------- /OLED/framebuf_utils.mpy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sergioacg/MicroPython/a80ab1c40cd3b396f3c6e35f6f4909e630dba745/OLED/framebuf_utils.mpy -------------------------------------------------------------------------------- /OLED/images.py: -------------------------------------------------------------------------------- 1 | 2 | logo = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 4 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 5 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 6 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 7 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 8 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x0f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 9 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xfc, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 10 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xfe, 0x7f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 11 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x1e, 0x78, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 12 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x30, 0x07, 0xe0, 0x08, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 13 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1c, 0x07, 0xc0, 0x38, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 14 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x87, 0x83, 0xc1, 0xe1, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 15 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x83, 0xc3, 0xc3, 0x81, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 16 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0xf3, 0xcf, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 17 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x7f, 0xfc, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 18 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x1f, 0xf8, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 19 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x1f, 0xf0, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 20 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x1f, 0xf8, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 21 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7f, 0xfe, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 22 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 23 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfc, 0x3f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 24 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x70, 0x0e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 25 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xe0, 0x07, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 26 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0xe0, 0x07, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 27 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xf0, 0x0f, 0xc7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 28 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xcf, 0xff, 0xff, 0xe7, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 29 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xdf, 0xff, 0xff, 0xf3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 30 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x0f, 0xf0, 0x7f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 31 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfc, 0x07, 0xe0, 0x3f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 32 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xfc, 0x03, 0xc0, 0x1f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 33 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x78, 0x03, 0xc0, 0x1f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 34 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x78, 0x03, 0xc0, 0x0c, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 35 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x70, 0x03, 0xc0, 0x0c, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 36 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x70, 0x03, 0xc0, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 37 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x70, 0x07, 0xe0, 0x0c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 38 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x78, 0x07, 0xf0, 0x1c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 39 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x78, 0x0f, 0xf8, 0x3e, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 40 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xfe, 0x3f, 0xfe, 0xfe, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 41 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xff, 0xf8, 0x1f, 0xfe, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 42 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 43 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xe0, 0x07, 0xe3, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 44 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x87, 0xe0, 0x07, 0xc1, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 45 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x83, 0xe0, 0x07, 0x81, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 46 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x81, 0xe0, 0x07, 0x81, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 47 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0xe0, 0x07, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 48 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0xf0, 0x0f, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 49 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0xf8, 0x1e, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 50 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x7f, 0xfe, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 51 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xfe, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 52 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xff, 0xff, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 53 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0x7f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 54 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xf0, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 55 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 56 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x0f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 57 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 58 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 59 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 60 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 61 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 62 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 63 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 64 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 65 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] -------------------------------------------------------------------------------- /OLED/lib/ssd1306.py: -------------------------------------------------------------------------------- 1 | # MicroPython SSD1306 OLED driver, I2C and SPI interfaces 2 | 3 | from micropython import const 4 | import framebuf 5 | 6 | 7 | # register definitions 8 | SET_CONTRAST = const(0x81) 9 | SET_ENTIRE_ON = const(0xA4) 10 | SET_NORM_INV = const(0xA6) 11 | SET_DISP = const(0xAE) 12 | SET_MEM_ADDR = const(0x20) 13 | SET_COL_ADDR = const(0x21) 14 | SET_PAGE_ADDR = const(0x22) 15 | SET_DISP_START_LINE = const(0x40) 16 | SET_SEG_REMAP = const(0xA0) 17 | SET_MUX_RATIO = const(0xA8) 18 | SET_COM_OUT_DIR = const(0xC0) 19 | SET_DISP_OFFSET = const(0xD3) 20 | SET_COM_PIN_CFG = const(0xDA) 21 | SET_DISP_CLK_DIV = const(0xD5) 22 | SET_PRECHARGE = const(0xD9) 23 | SET_VCOM_DESEL = const(0xDB) 24 | SET_CHARGE_PUMP = const(0x8D) 25 | 26 | # Subclassing FrameBuffer provides support for graphics primitives 27 | # http://docs.micropython.org/en/latest/pyboard/library/framebuf.html 28 | class SSD1306(framebuf.FrameBuffer): 29 | def __init__(self, width, height, external_vcc): 30 | self.width = width 31 | self.height = height 32 | self.external_vcc = external_vcc 33 | self.pages = self.height // 8 34 | self.buffer = bytearray(self.pages * self.width) 35 | super().__init__(self.buffer, self.width, self.height, framebuf.MONO_VLSB) 36 | self.init_display() 37 | 38 | def init_display(self): 39 | for cmd in ( 40 | SET_DISP | 0x00, # off 41 | # address setting 42 | SET_MEM_ADDR, 43 | 0x00, # horizontal 44 | # resolution and layout 45 | SET_DISP_START_LINE | 0x00, 46 | SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0 47 | SET_MUX_RATIO, 48 | self.height - 1, 49 | SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0 50 | SET_DISP_OFFSET, 51 | 0x00, 52 | SET_COM_PIN_CFG, 53 | 0x02 if self.width > 2 * self.height else 0x12, 54 | # timing and driving scheme 55 | SET_DISP_CLK_DIV, 56 | 0x80, 57 | SET_PRECHARGE, 58 | 0x22 if self.external_vcc else 0xF1, 59 | SET_VCOM_DESEL, 60 | 0x30, # 0.83*Vcc 61 | # display 62 | SET_CONTRAST, 63 | 0xFF, # maximum 64 | SET_ENTIRE_ON, # output follows RAM contents 65 | SET_NORM_INV, # not inverted 66 | # charge pump 67 | SET_CHARGE_PUMP, 68 | 0x10 if self.external_vcc else 0x14, 69 | SET_DISP | 0x01, 70 | ): # on 71 | self.write_cmd(cmd) 72 | self.fill(0) 73 | self.show() 74 | 75 | def poweroff(self): 76 | self.write_cmd(SET_DISP | 0x00) 77 | 78 | def poweron(self): 79 | self.write_cmd(SET_DISP | 0x01) 80 | 81 | def contrast(self, contrast): 82 | self.write_cmd(SET_CONTRAST) 83 | self.write_cmd(contrast) 84 | 85 | def invert(self, invert): 86 | self.write_cmd(SET_NORM_INV | (invert & 1)) 87 | 88 | def show(self): 89 | x0 = 0 90 | x1 = self.width - 1 91 | if self.width == 64: 92 | # displays with width of 64 pixels are shifted by 32 93 | x0 += 32 94 | x1 += 32 95 | self.write_cmd(SET_COL_ADDR) 96 | self.write_cmd(x0) 97 | self.write_cmd(x1) 98 | self.write_cmd(SET_PAGE_ADDR) 99 | self.write_cmd(0) 100 | self.write_cmd(self.pages - 1) 101 | self.write_data(self.buffer) 102 | 103 | 104 | class SSD1306_I2C(SSD1306): 105 | def __init__(self, width, height, i2c, addr=0x3C, external_vcc=False): 106 | self.i2c = i2c 107 | self.addr = addr 108 | self.temp = bytearray(2) 109 | self.write_list = [b"\x40", None] # Co=0, D/C#=1 110 | super().__init__(width, height, external_vcc) 111 | 112 | def write_cmd(self, cmd): 113 | self.temp[0] = 0x80 # Co=1, D/C#=0 114 | self.temp[1] = cmd 115 | self.i2c.writeto(self.addr, self.temp) 116 | 117 | def write_data(self, buf): 118 | self.write_list[1] = buf 119 | self.i2c.writevto(self.addr, self.write_list) 120 | 121 | 122 | class SSD1306_SPI(SSD1306): 123 | def __init__(self, width, height, spi, dc, res, cs, external_vcc=False): 124 | self.rate = 10 * 1024 * 1024 125 | dc.init(dc.OUT, value=0) 126 | res.init(res.OUT, value=0) 127 | cs.init(cs.OUT, value=1) 128 | self.spi = spi 129 | self.dc = dc 130 | self.res = res 131 | self.cs = cs 132 | import time 133 | 134 | self.res(1) 135 | time.sleep_ms(1) 136 | self.res(0) 137 | time.sleep_ms(10) 138 | self.res(1) 139 | super().__init__(width, height, external_vcc) 140 | 141 | def write_cmd(self, cmd): 142 | self.spi.init(baudrate=self.rate, polarity=0, phase=0) 143 | self.cs(1) 144 | self.dc(0) 145 | self.cs(0) 146 | self.spi.write(bytearray([cmd])) 147 | self.cs(1) 148 | 149 | def write_data(self, buf): 150 | self.spi.init(baudrate=self.rate, polarity=0, phase=0) 151 | self.cs(1) 152 | self.dc(1) 153 | self.cs(0) 154 | self.spi.write(buf) 155 | self.cs(1) 156 | -------------------------------------------------------------------------------- /OLED/logo_raspberry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sergioacg/MicroPython/a80ab1c40cd3b396f3c6e35f6f4909e630dba745/OLED/logo_raspberry.png -------------------------------------------------------------------------------- /OLED/oled_ex1.py: -------------------------------------------------------------------------------- 1 | from machine import Pin, I2C 2 | from utime import sleep_ms 3 | from ssd1306 import SSD1306_I2C 4 | import framebuf 5 | 6 | def open_icon(routh): 7 | doc = open(routh, "rb") 8 | doc.readline() 9 | xy = doc.readline() 10 | x = int(xy.split()[0]) 11 | y = int(xy.split()[1]) 12 | icon = bytearray(doc.read()) 13 | doc.close() 14 | return framebuf.FrameBuffer(icon, x, y, framebuf.MONO_HLSB) 15 | 16 | WIDTH = 128 17 | HEIGHT = 64 18 | 19 | i2c = I2C(1, scl = Pin(19), sda = Pin(18), freq = 200000) 20 | 21 | oled = SSD1306_I2C(WIDTH, HEIGHT, i2c) 22 | 23 | oled.fill(0) 24 | 25 | oled.text("Hello World", 0, 0) 26 | 27 | oled.show() 28 | 29 | sleep_ms(2000) 30 | 31 | oled.blit(open_icon("img/CAE.pbm"),35, 10) 32 | oled.show() 33 | 34 | 35 | -------------------------------------------------------------------------------- /OLED/oled_ex2.py: -------------------------------------------------------------------------------- 1 | """ 2 | OLED with MicroPython: Raspberry Pi Pico and ESP8266 3 | By: Sergio Andres Castaño Giraldo 4 | site: https://controlautomaticoeducacion.com/micropython/ 5 | GitHub: https://github.com/sergioacg/MicroPython 6 | 7 | Useful links: 8 | # https://docs.micropython.org/en/latest/library/framebuf.html 9 | # https://micropython-workshop.readthedocs.io/en/latest/pages/shields/oled.html 10 | # http://javl.github.io/image2cpp/ 11 | """ 12 | 13 | from machine import Pin, I2C, ADC 14 | from utime import sleep_ms 15 | from ssd1306 import SSD1306_I2C 16 | import framebuf 17 | from images import (logo) 18 | 19 | 20 | def plot_time(yp, t, x, y, var = [0.0,3.3], vpts=[25, 16, 40], hpts = [25, 55, 112]): 21 | """" 22 | Graph function of the Cartesian plane in relation to time: 23 | by: Sergio Andres Castaño Giraldo 24 | 25 | plot_time(yp, t, x, y, var = [0.0,3.3], vpts=[25, 16, 40], hpts = [25, 55, 112]): 26 | 27 | yp: dependent variable 28 | t: time (used while the Cartesian plane is not complete) 29 | x: List of two positions of variable x, x[0] is the position in past x and x[1] position of current x. 30 | y: List of two positions of the variable y, y[0] is the position in y past and y[1] position of current x. 31 | var = [0.0,3.3]: Magnitude of the variable (default voltage) 32 | vpts = [25, 16, 40]: points on the vertical y axis. 33 | hpts = [25, 55, 112]: points on the vertical x axis. 34 | 35 | Example: 36 | #Global Variables 37 | t = 0 38 | y = [55, 55] 39 | x = [25, 25] 40 | #Function: 41 | volts = pot.read_u16 () * FACTOR 42 | t, x, y = plot_time (volts, t, x, y) 43 | sleep_ms (500) 44 | """ 45 | #Axis 46 | oled.vline(vpts[0], vpts[1], vpts[2], 1) #x, y, h 47 | oled.hline(hpts[0], hpts[1], hpts[2], 1) #x, y, w 48 | oled.text(str(round(var[0],1)), vpts[0]-25, hpts[1]-5) 49 | oled.text(str(round(var[1],1)), vpts[0]-25, vpts[1]) 50 | #y - axis 51 | y[1] = int((yp-var[0])/(var[1]-var[0]) * (vpts[1]-hpts[1]) + hpts[1]) #Interpolation 52 | if t < hpts[2] - hpts[0]: 53 | x[1] = x[0]+1 54 | else: 55 | x[1] = hpts[2] 56 | 57 | #Plot the line 58 | oled.line(x[0],y[0],x[1],y[1],1) 59 | oled.show() 60 | 61 | #Update past values 62 | y[0] = y[1] 63 | x[0] = x[1] 64 | 65 | #If you have already reached the end of the graph then ... 66 | if t > hpts[2] - hpts[0]: 67 | #Erases the first few pixels of the graph and the y-axis. 68 | oled.fill_rect(vpts[0],vpts[1],2,vpts[2],0) 69 | #Clears the entire y-axis scale 70 | oled.fill_rect(vpts[0]-25, vpts[1],vpts[0],vpts[2]+5,0) 71 | #shifts the graph one pixel to the left 72 | oled.scroll(-1,0) 73 | #Axis 74 | oled.vline(vpts[0], vpts[1], vpts[2], 1) #x, y, h 75 | oled.hline(hpts[0], hpts[1], hpts[2], 1) #x, y, w 76 | oled.text(str(round(var[0],1)), vpts[0]-25, hpts[1]-5) 77 | oled.text(str(round(var[1],1)), vpts[0]-25, vpts[1]) 78 | else: 79 | t += 1 80 | 81 | return t,x,y 82 | 83 | 84 | 85 | 86 | if __name__ == '__main__': 87 | 88 | WIDTH = 128 89 | HEIGHT = 64 90 | FACTOR = 3.3 / (65535) 91 | 92 | PLACA = False #True: Raspberry Pi Pico, False: ESP8266 93 | 94 | if PLACA: 95 | i2c = I2C(1, scl = Pin(19), sda = Pin(18), freq = 200000) 96 | pot = ADC(26) 97 | else: 98 | i2c = I2C(scl = Pin(5), sda = Pin(4)) 99 | pot = ADC(0) 100 | 101 | oled = SSD1306_I2C(WIDTH, HEIGHT, i2c) 102 | 103 | 104 | buffer = bytearray(logo) 105 | 106 | fb = framebuf.FrameBuffer(buffer,WIDTH,HEIGHT,framebuf.MONO_HLSB) 107 | 108 | 109 | #Global Variables 110 | t = 0 111 | y = [55, 55] 112 | x = [25, 25] 113 | 114 | oled.fill(0) 115 | oled.text("Control", 35, 0) 116 | oled.text("Automatico", 20, 20) 117 | oled.text("Educacion", 25, 40) 118 | oled.show() 119 | sleep_ms(3000) 120 | 121 | #Image 122 | oled.fill(0) 123 | oled.blit(fb,0,0) 124 | oled.show() 125 | sleep_ms(3000) 126 | oled.fill(0) 127 | 128 | while True: 129 | volts = pot.read_u16() * FACTOR 130 | t,x,y = plot_time(volts,t,x,y) 131 | oled.fill_rect(0,0,120,15,0) 132 | oled.text("Volts: ", 0, 0) 133 | oled.text(str(round(volts,1)), 52, 0) 134 | oled.show() 135 | sleep_ms(100) 136 | 137 | 138 | -------------------------------------------------------------------------------- /PID_Level/PID_Level.py: -------------------------------------------------------------------------------- 1 | """ 2 | Control PID de Nivel 3 | 4 | by: Sergio Andrés Castaño Giraldo 5 | Sitio web: https://controlautomaticoeducacion.com/ 6 | Canal de YouTube: https://www.youtube.com/c/SergioACastañoGiraldo 7 | """ 8 | 9 | from machine import Pin, PWM, ADC, I2C, Timer 10 | from utime import sleep_ms 11 | from ssd1306 import SSD1306_I2C 12 | 13 | 14 | #OLED 15 | WIDTH = 128 16 | HEIGHT = 64 17 | #Configuración de PINES 18 | sensor = ADC(26) 19 | voltaje = ADC(27) 20 | potenciometro = ADC(28) 21 | pwm = PWM(Pin(20)) 22 | pwm.freq(40000) 23 | i2c = I2C(1, scl = Pin(19), sda = Pin(18), freq = 200000) 24 | 25 | #OLED 26 | oled = SSD1306_I2C(WIDTH, HEIGHT, i2c) 27 | 28 | #Global Variables 29 | t = 0 30 | z = [55, 55] 31 | y = [55, 55] 32 | x = [25, 25] 33 | level = 0 34 | dt = 1 35 | 36 | 37 | #Modelo del Sistema 38 | K=5 39 | tau=350 40 | theta=3 41 | Ts = 10; 42 | L = theta + Ts/2 43 | 44 | e = [0,0,0] #Vector de error 45 | u = [0,0] #Vector de Ley de Contr 46 | 47 | def update_past(v,kT): 48 | for i in range(1,kT,1): 49 | v[i-1]=v[i] 50 | return v 51 | 52 | def PID_Controller(u, e, q0, q1, q2): 53 | # Controle PID 54 | # e[2] = e(k) 55 | # e[1] = e(k-1) 56 | # e[0] = e(k-2) 57 | # u[0] = u(k-1) 58 | lu = u[0] + q0*e[2] + q1*e[1] + q2*e[0]; #Ley del controlador PID discreto 59 | 60 | # Anti - Windup 61 | if (lu >= 100.0): 62 | lu = 100.0 63 | 64 | if (lu <= 0.0): 65 | lu = 0.0 66 | 67 | return(lu) 68 | 69 | 70 | def temporizador(timer): 71 | global u, e, q0, q1, q2 72 | #Actualiza los vectores u y e 73 | u = update_past(u,len(u)); 74 | e= update_past(e,len(e)); 75 | 76 | #Calcula el error actual 77 | e[len(e)-1] = setpoint - level; 78 | #Calcula la Acción de Control PID 79 | u_end = PID_Controller(u, e, q0, q1, q2); #Max= 100, Min=0 80 | u[len(u)-1] = u_end 81 | velocidad = int(u[len(u)-1] * 65535 /100); 82 | #Aplica la acción de control en el PWM 83 | 84 | pwm.duty_u16(velocidad) 85 | 86 | 87 | def plot_time(yp, sp, t, x, y, var = [0.0,18], vpts=[25, 16, 40], hpts = [25, 55, 112]): 88 | """" 89 | Graph function of the Cartesian plane in relation to time: 90 | by: Sergio Andres Castaño Giraldo 91 | 92 | plot_time(yp, t, x, y, var = [0.0,3.3], vpts=[25, 16, 40], hpts = [25, 55, 112]): 93 | 94 | yp: dependent variable 95 | t: time (used while the Cartesian plane is not complete) 96 | x: List of two positions of variable x, x[0] is the position in past x and x[1] position of current x. 97 | y: List of two positions of the variable y, y[0] is the position in y past and y[1] position of current x. 98 | var = [0.0,3.3]: Magnitude of the variable (default voltage) 99 | vpts = [25, 16, 40]: points on the vertical y axis. 100 | hpts = [25, 55, 112]: points on the vertical x axis. 101 | 102 | Example: 103 | #Global Variables 104 | t = 0 105 | y = [55, 55] 106 | x = [25, 25] 107 | #Function: 108 | volts = pot.read_u16 () * FACTOR 109 | t, x, y = plot_time (volts, t, x, y) 110 | sleep_ms (500) 111 | """ 112 | global dt 113 | #Axis 114 | oled.vline(vpts[0], vpts[1], vpts[2], 1) #x, y, h 115 | oled.hline(hpts[0], hpts[1], hpts[2], 1) #x, y, w 116 | oled.text(str(round(var[0],1)), vpts[0]-25, hpts[1]-5) 117 | oled.text(str(round(var[1],1)), vpts[0]-25, vpts[1]) 118 | #Level 119 | y[1] = int((yp-var[0])/(var[1]-var[0]) * (vpts[1]-hpts[1]) + hpts[1]) #Interpolation 120 | #Set-Point 121 | z[1] = int((sp-var[0])/(var[1]-var[0]) * (vpts[1]-hpts[1]) + hpts[1]) #Interpolation 122 | 123 | if t < hpts[2] - hpts[0]: 124 | x[1] = x[0]+1 125 | else: 126 | x[1] = hpts[2] 127 | 128 | #Plot the line 129 | oled.line(x[0],y[0],x[1],y[1],1) 130 | oled.line(x[0],z[0],x[1],z[1], dt) 131 | dt ^= 1 #Dotted setpoint plot 132 | oled.show() 133 | 134 | #Update past values 135 | y[0] = y[1] 136 | x[0] = x[1] 137 | z[0] = z[1] 138 | 139 | #If you have already reached the end of the graph then ... 140 | if t > hpts[2] - hpts[0]: 141 | #Erases the first few pixels of the graph and the y-axis. 142 | oled.fill_rect(vpts[0],vpts[1],2,vpts[2],0) 143 | #Clears the entire y-axis scale 144 | oled.fill_rect(vpts[0]-25, vpts[1],vpts[0],vpts[2]+5,0) 145 | #shifts the graph one pixel to the left 146 | oled.scroll(-1,0) 147 | #Axis 148 | oled.vline(vpts[0], vpts[1], vpts[2], 1) #x, y, h 149 | oled.hline(hpts[0], hpts[1], hpts[2], 1) #x, y, w 150 | oled.text(str(round(var[0],1)), vpts[0]-25, hpts[1]-5) 151 | oled.text(str(round(var[1],1)), vpts[0]-25, vpts[1]) 152 | else: 153 | t += 1 154 | 155 | return t,x,y 156 | 157 | 158 | 159 | def main(): 160 | global level, t, y, x, setpoint, q0, q1, q2, u, e 161 | #Placa -> Raspberry Pi Pico = True, ESP8266 = False 162 | placa= True 163 | 164 | #Sensor Presión 165 | tolP=0.5 # Ajusta la medida de presión 166 | rho = 1000 #Densidad del Agua 167 | g=9.8 #Gravedad 168 | factor_16 = 3.3 / (65535) 169 | factor_sp = 18 / (65535) 170 | 171 | tim = Timer() 172 | tim.init(period= 10000, mode=Timer.PERIODIC, callback=temporizador) 173 | 174 | kp=(1.2*tau)/(K*L) 175 | ti=2*L 176 | td=0.5*L 177 | 178 | q0=kp*(1+Ts/(2*ti)+td/Ts) 179 | q1=-kp*(1-Ts/(2*ti)+(2*td)/Ts) 180 | q2=(kp*td)/Ts 181 | 182 | while True: 183 | 184 | #Presión en Kpa según gráfica 4 del Datasheet 185 | level_sum = 0 186 | for i in range(200): 187 | Vout = sensor.read_u16() * factor_16 188 | Vs = voltaje.read_u16() * factor_16 189 | presion = ( Vout - 0.04*Vs ) / (0.09 * Vs) + tolP #kPa 190 | level_sum += ((presion*1000)/(rho*g))*100; #Medida de Nivel del tanque 191 | 192 | level_x = level_sum / 200 193 | level = 1.157 * level_x - 2.1208 194 | #print(level) 195 | 196 | setpoint = potenciometro.read_u16() * factor_sp 197 | 198 | t,x,y = plot_time(level,setpoint,t,x,y) 199 | oled.fill_rect(0,0,128,15,0) 200 | oled.text("Lvl: ", 0, 0) 201 | oled.text(str(round(level,1)), 32, 0) 202 | oled.text("SP: ", 70, 0) 203 | oled.text(str(round(setpoint,1)), 95, 0) 204 | oled.show() 205 | 206 | sleep_ms(100) 207 | 208 | 209 | if __name__ == '__main__': 210 | main() -------------------------------------------------------------------------------- /PWM/led.py: -------------------------------------------------------------------------------- 1 | from machine import Pin, PWM 2 | from utime import sleep_ms 3 | 4 | frequency = 50 5 | led = PWM(Pin(14)) 6 | led.freq(frequency) 7 | 8 | while True: 9 | #for duty_cycle in range(0, 1024): 10 | #led.duty_ns(1500000) 11 | #sleep_ms(5) 12 | for pulso in range(500000,2500000,1000): 13 | led.duty_ns(pulso) 14 | sleep_ms(1) -------------------------------------------------------------------------------- /PWM/motor_puente_h.py: -------------------------------------------------------------------------------- 1 | """ 2 | Programa de Ejemplo de PWM 3 | Control de Giro y Velocidad de un motor DC con Puente H 4 | 5 | by: Sergio Andrés Castaño Giraldo 6 | Sitio web: https://controlautomaticoeducacion.com/ 7 | Canal de YouTube: https://www.youtube.com/c/SergioACastañoGiraldo 8 | """ 9 | 10 | from machine import Pin, PWM, ADC 11 | from utime import sleep_ms 12 | 13 | def main(): 14 | #Placa -> Raspberry Pi Pico = True, ESP8266 = False 15 | placa= True 16 | 17 | frequency = 10000 #10Khz 18 | sentido = True #Sentido derecha 19 | 20 | if placa: 21 | potenciometro = ADC(26) #Raspberry Pi Pico ADC0 22 | r_pwm = PWM(Pin(16)) #PWM derecha 23 | r_pwm.freq(frequency) 24 | l_pwm = PWM(Pin(17)) #PWM izquierda 25 | l_pwm.freq(frequency) 26 | boton = Pin(15, Pin.IN, Pin.PULL_UP) 27 | else: 28 | potenciometro = ADC(0) #NodeMCU8266v3 ADC0 29 | r_pwm = PWM(Pin(4), frequency) #PWM derecha 30 | l_pwm = PWM(Pin(5), frequency) #PWM izquierda 31 | boton = Pin(2, Pin.IN, Pin.PULL_UP) 32 | 33 | while True: 34 | #Pregunta por el boton 35 | if not boton(): 36 | sleep_ms(200) #Anti-Rebote 37 | while not boton(): 38 | pass 39 | sleep_ms(200) #Anti-Rebote 40 | sentido = not sentido 41 | 42 | 43 | #Aplica el PWM al motor 44 | if placa: 45 | velocidad = potenciometro.read_u16(); 46 | if sentido: 47 | r_pwm.duty_u16(velocidad) 48 | l_pwm.duty_u16(0) 49 | else: 50 | r_pwm.duty_u16(0) 51 | l_pwm.duty_u16(velocidad) 52 | else: 53 | velocidad = potenciometro.read(); 54 | if sentido: 55 | r_pwm.duty(velocidad) 56 | l_pwm.duty(0) 57 | else: 58 | r_pwm.duty(0) 59 | l_pwm.duty(velocidad) 60 | 61 | sleep_ms(5) 62 | 63 | 64 | if __name__ == '__main__': 65 | main() -------------------------------------------------------------------------------- /RPI-PICO-I2C-LCD-main/README.md: -------------------------------------------------------------------------------- 1 | # RPI-PICO-I2C-LCD 2 | This is a project which adapts code from another user to allow usage of the PCF8574 I2C lcd backpack for either 20x4 or 16x2 lcd screens. 3 | 4 | Credit: https://github.com/dhylands/python_lcd/tree/master/lcd mostly to Dave Hylands for the basic api and lcd driver code. 5 | 6 | Project: Check it out for a full step-by-setp guide on Instructables: https://www.instructables.com/RPI-Pico-I2C-LCD-Control/ 7 | 8 | This is code adaptded for micropython and the Raspberry Pi PICO specifically. 9 | 10 | Usage: 11 | - Download all 3 .py files included. 12 | - Open Thonny IDE with the 3 files 13 | - Make pin edits or setup changes (See below for options) 14 | - DO NOT EDIT FILE NAMES! 15 | - In Thonny, go to top menu File => Save Copy => Raspberry Pi Pico and save each file to the board with the same name as downloaded and with a .PY extension when saving it to the board. 16 | - Switch to the pico_i2c_lcd_test.py (this is the main file) and click run. This should be able to initalize the LCD display if settings are right. 17 | - If you get errors, see below for a known list of errors and their fixes 18 | - Wiring Diagram LCD_bb.jpg! Please look here for a fritzing diagram! 19 | 20 | Requirements: 21 | - 3.3 - 5V level translator. This is crucial to encure the lcd recieves the commands properly. I recommend this: https://www.adafruit.com/product/757 (Must be Bi-Directional) 22 | - PCF8574 I2C LCD backpack. (These are common to find) 23 | 24 | Setup Changes: 25 | - Make sure the top address is set correctly! 26 | Use this small program to scan for I2C devices: 27 | 28 | import machine 29 | sda=machine.Pin(0) 30 | scl=machine.Pin(1) 31 | i2c=machine.I2C(0,sda=sda, scl=scl, freq=400000) 32 | print(i2c.scan()) 33 | 34 | - Once you get an address through the console (REPL), this will be in decimal and not hex. You can convert the decimal to hex or simply put a decimal address in the setup. 35 | in my case, the decimal addr. was 39 which converts to 0x27 in hex. 36 | - Ensure that your SCL and SDA pins are selected properly in accordance with the Pico's pin table. These connect to the low voltage side of the translator with a 3.3V Reference from the board. The high voltage side gets a 5V reference from the VBUS pin of the Pico. 37 | - Finally, assure the I2C_NUM_ROWS and I2C_NUM_COLS are set properly! 38 | 39 | Functions / Usage: 40 | 41 | These are the python commands used in a program! (They can all be found in the lcd_api.py file with definitions to their functions) 42 | - lcd.putstr("Text goes here!") - Send a string of chars to the display IMPORTANT: Use this for printing a variable: lcd.putstr(str(Variable)) [Turns variable into string] 43 | - lcd.show_cursor() / lcd.hide_cursor() - Show / Hide the cursor of the lcd (White bar) 44 | - lcd.blink_cursor_on() / lcd.blink_cursor_off() - Turn on / Off the blinking cursor upon printing 45 | - lcd.backlight_on() / lcd.backlight_off() - Turn on / Off backlight of the LCD (Controlled by a small transistor on the backpack) 46 | - lcd.display_on() / lcd.display_off() - Turn on / Off the display (Not backlight but the entire chip) 47 | - lcd.clear() - Clear all chars or anything written to the display 48 | - lcd.move_to(Col, Row) - Move to position based on row and col values (Y, X) 49 | - lcd.custom_char(Num, bytearray([HEX chars]))) - Num can be any integer 0 - 8 (Writing to CGRAM locations) merely used for numbering. The HEX chars are simply made by using this link: https://maxpromer.github.io/LCD-Character-Creator/. It will provide a string of Hex charecters which can replace the "HEX chars" in the example command. 50 | 51 | Errors: 52 | 53 | OSERROR : 5 (This is quite a common error, 5 means I/O error. Check Your connections. This means codes can't be sent or recieved ensure SCL and SDA are properly connected through the level translator! 54 | 55 | Feel to leave comments or questions / issues and I will try to answer / resolve them as quick as possible! 56 | 57 | For people wondering how to use this code, Tinkernut on Youtube created a very nice guide + some more features! https://www.youtube.com/watch?v=B8Kr_3xHjqE&t 58 | 59 | 60 | -------------------------------------------------------------------------------- /RPI-PICO-I2C-LCD-main/Schematic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sergioacg/MicroPython/a80ab1c40cd3b396f3c6e35f6f4909e630dba745/RPI-PICO-I2C-LCD-main/Schematic.jpg -------------------------------------------------------------------------------- /RPI-PICO-I2C-LCD-main/lcd_api.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | class LcdApi: 4 | 5 | # Implements the API for talking with HD44780 compatible character LCDs. 6 | # This class only knows what commands to send to the LCD, and not how to get 7 | # them to the LCD. 8 | # 9 | # It is expected that a derived class will implement the hal_xxx functions. 10 | # 11 | # The following constant names were lifted from the avrlib lcd.h header file, 12 | # with bit numbers changed to bit masks. 13 | 14 | # HD44780 LCD controller command set 15 | LCD_CLR = 0x01 # DB0: clear display 16 | LCD_HOME = 0x02 # DB1: return to home position 17 | 18 | LCD_ENTRY_MODE = 0x04 # DB2: set entry mode 19 | LCD_ENTRY_INC = 0x02 # DB1: increment 20 | LCD_ENTRY_SHIFT = 0x01 # DB0: shift 21 | 22 | LCD_ON_CTRL = 0x08 # DB3: turn lcd/cursor on 23 | LCD_ON_DISPLAY = 0x04 # DB2: turn display on 24 | LCD_ON_CURSOR = 0x02 # DB1: turn cursor on 25 | LCD_ON_BLINK = 0x01 # DB0: blinking cursor 26 | 27 | LCD_MOVE = 0x10 # DB4: move cursor/display 28 | LCD_MOVE_DISP = 0x08 # DB3: move display (0-> move cursor) 29 | LCD_MOVE_RIGHT = 0x04 # DB2: move right (0-> left) 30 | 31 | LCD_FUNCTION = 0x20 # DB5: function set 32 | LCD_FUNCTION_8BIT = 0x10 # DB4: set 8BIT mode (0->4BIT mode) 33 | LCD_FUNCTION_2LINES = 0x08 # DB3: two lines (0->one line) 34 | LCD_FUNCTION_10DOTS = 0x04 # DB2: 5x10 font (0->5x7 font) 35 | LCD_FUNCTION_RESET = 0x30 # See "Initializing by Instruction" section 36 | 37 | LCD_CGRAM = 0x40 # DB6: set CG RAM address 38 | LCD_DDRAM = 0x80 # DB7: set DD RAM address 39 | 40 | LCD_RS_CMD = 0 41 | LCD_RS_DATA = 1 42 | 43 | LCD_RW_WRITE = 0 44 | LCD_RW_READ = 1 45 | 46 | def __init__(self, num_lines, num_columns): 47 | self.num_lines = num_lines 48 | if self.num_lines > 4: 49 | self.num_lines = 4 50 | self.num_columns = num_columns 51 | if self.num_columns > 40: 52 | self.num_columns = 40 53 | self.cursor_x = 0 54 | self.cursor_y = 0 55 | self.implied_newline = False 56 | self.backlight = True 57 | self.display_off() 58 | self.backlight_on() 59 | self.clear() 60 | self.hal_write_command(self.LCD_ENTRY_MODE | self.LCD_ENTRY_INC) 61 | self.hide_cursor() 62 | self.display_on() 63 | 64 | def clear(self): 65 | # Clears the LCD display and moves the cursor to the top left corner 66 | self.hal_write_command(self.LCD_CLR) 67 | self.hal_write_command(self.LCD_HOME) 68 | self.cursor_x = 0 69 | self.cursor_y = 0 70 | 71 | def show_cursor(self): 72 | # Causes the cursor to be made visible 73 | self.hal_write_command(self.LCD_ON_CTRL | self.LCD_ON_DISPLAY | 74 | self.LCD_ON_CURSOR) 75 | 76 | def hide_cursor(self): 77 | # Causes the cursor to be hidden 78 | self.hal_write_command(self.LCD_ON_CTRL | self.LCD_ON_DISPLAY) 79 | 80 | def blink_cursor_on(self): 81 | # Turns on the cursor, and makes it blink 82 | self.hal_write_command(self.LCD_ON_CTRL | self.LCD_ON_DISPLAY | 83 | self.LCD_ON_CURSOR | self.LCD_ON_BLINK) 84 | 85 | def blink_cursor_off(self): 86 | # Turns on the cursor, and makes it no blink (i.e. be solid) 87 | self.hal_write_command(self.LCD_ON_CTRL | self.LCD_ON_DISPLAY | 88 | self.LCD_ON_CURSOR) 89 | 90 | def display_on(self): 91 | # Turns on (i.e. unblanks) the LCD 92 | self.hal_write_command(self.LCD_ON_CTRL | self.LCD_ON_DISPLAY) 93 | 94 | def display_off(self): 95 | # Turns off (i.e. blanks) the LCD 96 | self.hal_write_command(self.LCD_ON_CTRL) 97 | 98 | def backlight_on(self): 99 | # Turns the backlight on. 100 | 101 | # This isn't really an LCD command, but some modules have backlight 102 | # controls, so this allows the hal to pass through the command. 103 | self.backlight = True 104 | self.hal_backlight_on() 105 | 106 | def backlight_off(self): 107 | # Turns the backlight off. 108 | 109 | # This isn't really an LCD command, but some modules have backlight 110 | # controls, so this allows the hal to pass through the command. 111 | self.backlight = False 112 | self.hal_backlight_off() 113 | 114 | def move_to(self, cursor_x, cursor_y): 115 | # Moves the cursor position to the indicated position. The cursor 116 | # position is zero based (i.e. cursor_x == 0 indicates first column). 117 | self.cursor_x = cursor_x 118 | self.cursor_y = cursor_y 119 | addr = cursor_x & 0x3f 120 | if cursor_y & 1: 121 | addr += 0x40 # Lines 1 & 3 add 0x40 122 | if cursor_y & 2: # Lines 2 & 3 add number of columns 123 | addr += self.num_columns 124 | self.hal_write_command(self.LCD_DDRAM | addr) 125 | 126 | def putchar(self, char): 127 | # Writes the indicated character to the LCD at the current cursor 128 | # position, and advances the cursor by one position. 129 | if char == '\n': 130 | if self.implied_newline: 131 | # self.implied_newline means we advanced due to a wraparound, 132 | # so if we get a newline right after that we ignore it. 133 | pass 134 | else: 135 | self.cursor_x = self.num_columns 136 | else: 137 | self.hal_write_data(ord(char)) 138 | self.cursor_x += 1 139 | if self.cursor_x >= self.num_columns: 140 | self.cursor_x = 0 141 | self.cursor_y += 1 142 | self.implied_newline = (char != '\n') 143 | if self.cursor_y >= self.num_lines: 144 | self.cursor_y = 0 145 | self.move_to(self.cursor_x, self.cursor_y) 146 | 147 | def putstr(self, string): 148 | # Write the indicated string to the LCD at the current cursor 149 | # position and advances the cursor position appropriately. 150 | for char in string: 151 | self.putchar(char) 152 | 153 | def custom_char(self, location, charmap): 154 | # Write a character to one of the 8 CGRAM locations, available 155 | # as chr(0) through chr(7). 156 | location &= 0x7 157 | self.hal_write_command(self.LCD_CGRAM | (location << 3)) 158 | self.hal_sleep_us(40) 159 | for i in range(8): 160 | self.hal_write_data(charmap[i]) 161 | self.hal_sleep_us(40) 162 | self.move_to(self.cursor_x, self.cursor_y) 163 | 164 | def hal_backlight_on(self): 165 | # Allows the hal layer to turn the backlight on. 166 | # If desired, a derived HAL class will implement this function. 167 | pass 168 | 169 | def hal_backlight_off(self): 170 | # Allows the hal layer to turn the backlight off. 171 | # If desired, a derived HAL class will implement this function. 172 | pass 173 | 174 | def hal_write_command(self, cmd): 175 | # Write a command to the LCD. 176 | # It is expected that a derived HAL class will implement this function. 177 | raise NotImplementedError 178 | 179 | def hal_write_data(self, data): 180 | # Write data to the LCD. 181 | # It is expected that a derived HAL class will implement this function. 182 | raise NotImplementedError 183 | 184 | def hal_sleep_us(self, usecs): 185 | # Sleep for some time (given in microseconds) 186 | time.sleep_us(usecs) 187 | -------------------------------------------------------------------------------- /RPI-PICO-I2C-LCD-main/pico_i2c_lcd.py: -------------------------------------------------------------------------------- 1 | import utime 2 | import gc 3 | 4 | from lcd_api import LcdApi 5 | from machine import I2C 6 | 7 | # PCF8574 pin definitions 8 | MASK_RS = 0x01 # P0 9 | MASK_RW = 0x02 # P1 10 | MASK_E = 0x04 # P2 11 | 12 | SHIFT_BACKLIGHT = 3 # P3 13 | SHIFT_DATA = 4 # P4-P7 14 | 15 | class I2cLcd(LcdApi): 16 | 17 | #Implements a HD44780 character LCD connected via PCF8574 on I2C 18 | 19 | def __init__(self, i2c, i2c_addr, num_lines, num_columns): 20 | self.i2c = i2c 21 | self.i2c_addr = i2c_addr 22 | self.i2c.writeto(self.i2c_addr, bytes([0])) 23 | utime.sleep_ms(20) # Allow LCD time to powerup 24 | # Send reset 3 times 25 | self.hal_write_init_nibble(self.LCD_FUNCTION_RESET) 26 | utime.sleep_ms(5) # Need to delay at least 4.1 msec 27 | self.hal_write_init_nibble(self.LCD_FUNCTION_RESET) 28 | utime.sleep_ms(1) 29 | self.hal_write_init_nibble(self.LCD_FUNCTION_RESET) 30 | utime.sleep_ms(1) 31 | # Put LCD into 4-bit mode 32 | self.hal_write_init_nibble(self.LCD_FUNCTION) 33 | utime.sleep_ms(1) 34 | LcdApi.__init__(self, num_lines, num_columns) 35 | cmd = self.LCD_FUNCTION 36 | if num_lines > 1: 37 | cmd |= self.LCD_FUNCTION_2LINES 38 | self.hal_write_command(cmd) 39 | gc.collect() 40 | 41 | def hal_write_init_nibble(self, nibble): 42 | # Writes an initialization nibble to the LCD. 43 | # This particular function is only used during initialization. 44 | byte = ((nibble >> 4) & 0x0f) << SHIFT_DATA 45 | self.i2c.writeto(self.i2c_addr, bytes([byte | MASK_E])) 46 | self.i2c.writeto(self.i2c_addr, bytes([byte])) 47 | gc.collect() 48 | 49 | def hal_backlight_on(self): 50 | # Allows the hal layer to turn the backlight on 51 | self.i2c.writeto(self.i2c_addr, bytes([1 << SHIFT_BACKLIGHT])) 52 | gc.collect() 53 | 54 | def hal_backlight_off(self): 55 | #Allows the hal layer to turn the backlight off 56 | self.i2c.writeto(self.i2c_addr, bytes([0])) 57 | gc.collect() 58 | 59 | def hal_write_command(self, cmd): 60 | # Write a command to the LCD. Data is latched on the falling edge of E. 61 | byte = ((self.backlight << SHIFT_BACKLIGHT) | 62 | (((cmd >> 4) & 0x0f) << SHIFT_DATA)) 63 | self.i2c.writeto(self.i2c_addr, bytes([byte | MASK_E])) 64 | self.i2c.writeto(self.i2c_addr, bytes([byte])) 65 | byte = ((self.backlight << SHIFT_BACKLIGHT) | 66 | ((cmd & 0x0f) << SHIFT_DATA)) 67 | self.i2c.writeto(self.i2c_addr, bytes([byte | MASK_E])) 68 | self.i2c.writeto(self.i2c_addr, bytes([byte])) 69 | if cmd <= 3: 70 | # The home and clear commands require a worst case delay of 4.1 msec 71 | utime.sleep_ms(5) 72 | gc.collect() 73 | 74 | def hal_write_data(self, data): 75 | # Write data to the LCD. Data is latched on the falling edge of E. 76 | byte = (MASK_RS | 77 | (self.backlight << SHIFT_BACKLIGHT) | 78 | (((data >> 4) & 0x0f) << SHIFT_DATA)) 79 | self.i2c.writeto(self.i2c_addr, bytes([byte | MASK_E])) 80 | self.i2c.writeto(self.i2c_addr, bytes([byte])) 81 | byte = (MASK_RS | 82 | (self.backlight << SHIFT_BACKLIGHT) | 83 | ((data & 0x0f) << SHIFT_DATA)) 84 | self.i2c.writeto(self.i2c_addr, bytes([byte | MASK_E])) 85 | self.i2c.writeto(self.i2c_addr, bytes([byte])) 86 | gc.collect() 87 | -------------------------------------------------------------------------------- /RPI-PICO-I2C-LCD-main/pico_i2c_lcd_test.py: -------------------------------------------------------------------------------- 1 | import utime 2 | 3 | import machine 4 | from machine import I2C 5 | from lcd_api import LcdApi 6 | from pico_i2c_lcd import I2cLcd 7 | 8 | I2C_ADDR = 0x27 9 | I2C_NUM_ROWS = 4 10 | I2C_NUM_COLS = 20 11 | 12 | def test_main(): 13 | #Test function for verifying basic functionality 14 | print("Running test_main") 15 | i2c = I2C(0, sda=machine.Pin(0), scl=machine.Pin(1), freq=400000) 16 | lcd = I2cLcd(i2c, I2C_ADDR, I2C_NUM_ROWS, I2C_NUM_COLS) 17 | lcd.putstr("It Works!") 18 | utime.sleep(2) 19 | lcd.clear() 20 | count = 0 21 | while True: 22 | lcd.clear() 23 | time = utime.localtime() 24 | lcd.putstr("{year:>04d}/{month:>02d}/{day:>02d} {HH:>02d}:{MM:>02d}:{SS:>02d}".format( 25 | year=time[0], month=time[1], day=time[2], 26 | HH=time[3], MM=time[4], SS=time[5])) 27 | if count % 10 == 0: 28 | print("Turning cursor on") 29 | lcd.show_cursor() 30 | if count % 10 == 1: 31 | print("Turning cursor off") 32 | lcd.hide_cursor() 33 | if count % 10 == 2: 34 | print("Turning blink cursor on") 35 | lcd.blink_cursor_on() 36 | if count % 10 == 3: 37 | print("Turning blink cursor off") 38 | lcd.blink_cursor_off() 39 | if count % 10 == 4: 40 | print("Turning backlight off") 41 | lcd.backlight_off() 42 | if count % 10 == 5: 43 | print("Turning backlight on") 44 | lcd.backlight_on() 45 | if count % 10 == 6: 46 | print("Turning display off") 47 | lcd.display_off() 48 | if count % 10 == 7: 49 | print("Turning display on") 50 | lcd.display_on() 51 | if count % 10 == 8: 52 | print("Filling display") 53 | lcd.clear() 54 | string = "" 55 | for x in range(32, 32+I2C_NUM_ROWS*I2C_NUM_COLS): 56 | string += chr(x) 57 | lcd.putstr(string) 58 | count += 1 59 | utime.sleep(2) 60 | 61 | #if __name__ == "__main__": 62 | test_main() 63 | -------------------------------------------------------------------------------- /Raspberry Pi Pico/rp2-pico-20210227-unstable-v1.14-82-gcdaec0dca.uf2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sergioacg/MicroPython/a80ab1c40cd3b396f3c6e35f6f4909e630dba745/Raspberry Pi Pico/rp2-pico-20210227-unstable-v1.14-82-gcdaec0dca.uf2 -------------------------------------------------------------------------------- /SDK/SDK.py: -------------------------------------------------------------------------------- 1 | import machine 2 | import utime 3 | 4 | 5 | i2c = machine.I2C(0, scl=machine.Pin(9), sda=machine.Pin(8), freq=200000) 6 | 7 | direccion = hex(i2c.scan()[0]) 8 | 9 | print('La dirección I2C es ', direccion) 10 | -------------------------------------------------------------------------------- /Salidas GPIO/led.py: -------------------------------------------------------------------------------- 1 | from machine import Pin 2 | import utime 3 | 4 | 5 | def main(): 6 | led = Pin(14, Pin.OUT) 7 | while True: 8 | led.value(1) 9 | utime.sleep_ms( 1000 ) 10 | led.value(0) 11 | utime.sleep_ms( 1000 ) 12 | 13 | 14 | if __name__ == '__main__': 15 | main() -------------------------------------------------------------------------------- /Salidas GPIO/main.py: -------------------------------------------------------------------------------- 1 | from machine import Pin 2 | import utime 3 | 4 | 5 | def main(): 6 | led = Pin(5, Pin.OUT) 7 | while True: 8 | #Prende y apaga por 1 segundo 9 | led.value(1) 10 | utime.sleep(1) 11 | led.value(0) 12 | utime.sleep(1) 13 | 14 | #Prende y Apaga por medio segundo 15 | led.on() 16 | utime.sleep_ms(500) 17 | led.off() 18 | utime.sleep_ms(500) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() -------------------------------------------------------------------------------- /Servo/servomotor.py: -------------------------------------------------------------------------------- 1 | from machine import Pin, PWM 2 | import utime 3 | 4 | 5 | def main(): 6 | #Configura el Servo de 180 7 | servo_180 = PWM(Pin(15)) 8 | servo_180.freq(50) 9 | 10 | #Configura el Servo de 360 11 | servo_360 = PWM(Pin(14)) 12 | servo_360.freq(50) 13 | 14 | while True: 15 | angulo = float(input('Ingrese un ángulo: ')) 16 | if angulo >= 0 and angulo <= 180: 17 | duty = int((12.346*angulo**2 + 7777.8*angulo + 700000)) 18 | servo_180.duty_16(duty) 19 | servo_360.duty_ns(duty) 20 | else: 21 | print('Digite un ángulo entre 0 y 180') 22 | 23 | 24 | if __name__ == '__main__': 25 | main() -------------------------------------------------------------------------------- /Timer/led_timer.py: -------------------------------------------------------------------------------- 1 | from machine import Pin, Timer 2 | 3 | led = Pin(25, Pin.OUT) 4 | led.value(0) 5 | 6 | timer = Timer() 7 | timer.init(period = 500, mode = Timer.PERIODIC, callback=lambda t:led.value(not led.value())) 8 | 9 | -------------------------------------------------------------------------------- /Timer/multiplexacion_timer.py: -------------------------------------------------------------------------------- 1 | """ 2 | USO DEL TIMER EN RASPBERRY PI PICO 3 | Display 7 Segmentos usando MicroPython 4 | Importación de nuestro propio módulo display7seg 5 | 6 | by: Sergio Andres Castaño Giraldo 7 | Referencia: https://controlautomaticoeducacion.com/ 8 | """ 9 | 10 | from machine import Pin, Timer 11 | import utime 12 | import display7seg 13 | 14 | 15 | def temporizador(timer): 16 | #Variables globales compartidas con el main 17 | global contador, sentido 18 | #Lógica de la interrupción 19 | if sentido: 20 | contador += 1 21 | else: 22 | contador -= 1 23 | 24 | 25 | def main(): 26 | global contador, sentido 27 | #Raspberry Pi PICO (4 digitos) 28 | display_pins = (16, 18, 13, 14, 15, 17, 12) #(a, b, c, d, e, f, g) 29 | transistor_pins = (22, 21, 20, 19) 30 | 31 | #NodeMCU 8266v3 (2 Digitos) 32 | #display_pins = (16, 5, 4, 0, 2, 14, 12) 33 | #transistor_pins = (13, 15) 34 | 35 | display7 = display7seg.Display(display_pins,transistor_pins = transistor_pins ) 36 | 37 | #Inicia las variables 38 | contador = 0 39 | sentido = True 40 | 41 | tim = Timer() 42 | tim.init(period= 500, mode=Timer.PERIODIC, callback=temporizador) 43 | 44 | while True: 45 | #Muestra el valor del contador en el display 46 | #temporizacion(display7, contador) 47 | display7.show(contador) #Llamar la rutina MOSTRAR 48 | 49 | 50 | #Si contador es nueve coloque el sentido del contador a decrementar 51 | if contador == 9999: 52 | sentido = False 53 | 54 | #Si contador es cero coloque el sentido del contador a incrementar 55 | if contador == 0: 56 | sentido = True 57 | 58 | 59 | 60 | #Entry Point 61 | if __name__ == '__main__': 62 | main() -------------------------------------------------------------------------------- /Timer/temp_2.py: -------------------------------------------------------------------------------- 1 | import machine 2 | 3 | interruptCounter = 0 4 | totalInterruptsCounter = 0 5 | 6 | timer = machine.Timer(0) 7 | 8 | def handleInterrupt(timer): 9 | global interruptCounter 10 | interruptCounter = interruptCounter+1 11 | 12 | timer.init(period=1000, mode=machine.Timer.PERIODIC, callback=handleInterrupt) 13 | lampara = machine.Pin(4, machine.Pin.OUT) 14 | 15 | while True: 16 | if interruptCounter>0: 17 | state = machine.disable_irq() 18 | interruptCounter = interruptCounter-1 19 | machine.enable_irq(state) 20 | lampara.toggle() 21 | 22 | totalInterruptsCounter = totalInterruptsCounter+1 23 | print("Interrupt has occurred: " + str(totalInterruptsCounter)) 24 | -------------------------------------------------------------------------------- /Timer/temporizador.py: -------------------------------------------------------------------------------- 1 | """ 2 | Programa de Ejemplo de PWM 3 | Control de Giro y Velocidad de un motor DC con Puente H 4 | 5 | by: Sergio Andrés Castaño Giraldo 6 | controlautomaticoeducacion.com 7 | Canal de YouTube: https://www.youtube.com/c/SergioACastañoGiraldo 8 | """ 9 | 10 | import machine 11 | import utime 12 | 13 | contador = 0 14 | 15 | def handle_timer(timer): 16 | global contador, lampara 17 | contador += 1 18 | lampara.value(not lampara.value()) 19 | 20 | 21 | 22 | def main(): 23 | global contador, lampara 24 | boton = machine.Pin(14, machine.Pin.IN, machine.Pin.PULL_UP) 25 | lampara = machine.Pin(4, machine.Pin.OUT) 26 | led = machine.Pin(5, machine.Pin.OUT) 27 | tim = machine.Timer(-1) 28 | tim.init(period=50, mode=machine.Timer.PERIODIC, callback=handle_timer) 29 | tiempo = 500 30 | while True: 31 | led.on() 32 | utime.sleep(3) 33 | led.off() 34 | utime.sleep(3) 35 | 36 | 37 | if __name__ == '__main__': 38 | main() 39 | -------------------------------------------------------------------------------- /UART/Com_Uart.py: -------------------------------------------------------------------------------- 1 | from machine import UART, Pin 2 | import time 3 | 4 | uart1 = UART(1, baudrate=9600, tx=Pin(4), rx=Pin(5)) 5 | 6 | uart0 = UART(0, baudrate=9600, tx=Pin(0), rx=Pin(1)) 7 | 8 | txData = b'hello world\n\r' 9 | uart1.write(txData) 10 | time.sleep(5) 11 | rxData = bytes() 12 | while uart1.any() > 0: 13 | rxData += uart1.read(1) 14 | 15 | print(rxData.decode('utf-8')) -------------------------------------------------------------------------------- /thread/multiplexacion.py: -------------------------------------------------------------------------------- 1 | """ 2 | USO DE LOS THREADS en la Raspberry Pi Pico 3 | Display 7 Segmentos usando MicroPython 4 | Importación de nuestro propio módulo display7seg 5 | 6 | by: Sergio Andres Castaño Giraldo 7 | Referencia: https://controlautomaticoeducacion.com/ 8 | """ 9 | 10 | from machine import Pin, Timer 11 | import utime 12 | import display7seg 13 | 14 | 15 | def temporizacion(display7, contador): 16 | contret=50 #Cargue con 50 la variable CONTRET 17 | while (contret>0): #Mientras que la variable CONTRET sea mayor que cero 18 | display7.show(contador) #Llamar la rutina MOSTRAR 19 | contret -= 1 #Decremente la variable CONTRET 20 | 21 | def temporizador(timer): 22 | #Variables globales compartidas con el main 23 | global contador, sentido 24 | #Lógica de la interrupción 25 | if sentido: 26 | contador += 1 27 | else: 28 | contador -= 1 29 | 30 | 31 | def main(): 32 | global contador, sentido 33 | #Raspberry Pi PICO (4 digitos) 34 | display_pins = (16, 18, 13, 14, 15, 17, 12) #(a, b, c, d, e, f, g) 35 | transistor_pins = (22, 21, 20, 19) 36 | 37 | #NodeMCU 8266v3 (2 Digitos) 38 | #display_pins = (16, 5, 4, 0, 2, 14, 12) 39 | #transistor_pins = (13, 15) 40 | 41 | display7 = display7seg.Display(display_pins,transistor_pins = transistor_pins ) 42 | 43 | #Inicia las variables 44 | contador = 0 45 | sentido = True 46 | 47 | tim = Timer() 48 | tim.init(period= 1000, mode=Timer.PERIODIC, callback=temporizador) 49 | 50 | while True: 51 | #Muestra el valor del contador en el display 52 | #temporizacion(display7, contador) 53 | display7.show(contador) #Llamar la rutina MOSTRAR 54 | 55 | 56 | 57 | #Si contador es nueve coloque el sentido del contador a decrementar 58 | if contador == 9999: 59 | sentido = False 60 | 61 | #Si contador es cero coloque el sentido del contador a incrementar 62 | if contador == 0: 63 | sentido = True 64 | 65 | 66 | 67 | #Entry Point 68 | if __name__ == '__main__': 69 | main() --------------------------------------------------------------------------------