Alumnos: __Pablo Córdoba____________
__________________________
__________________________
__________________________
Fecha de presentación: 17 /04 /2024
Calificación: ________________ Fecha: __ /__ /____
Firma del docente: __________________
Materiales
Para el ejercicio se usará, además de las placas de desarrollo Raspberry Pi Pico y/o Raspberry Pi Pico W,
LED’s, presets o potenciómetros, pulsadores, resistencias necesarias y un protoboard donde conectar
todo.
Informe
Para la entrega del informe (en formato electrónico) se pide:
• Archivo editado con la carátula debidamente completada con los integrantes del grupo.
• Foto o escaneo de esta hoja firmada con el visto del docente cuando corrobora que lo implementado
funciona como se pidió.
• Un diagrama o circuito eléctrico del armado donde se especifiquen valores de componentes y
terminales utilizados en las placas de desarrollo.
• El código implementado para la solución y una breve descripción de lo que hace cada parte.
Enunciado
El siguiente puntos debe estar resuelto aplicando, cuando sea pertinente, interrupciones de GPIO, demora
anti-rebote por software y utilizando el systick para medir los tiempos necesarios. Es conveniente armar el
sistema completo para luego poder desarrollar el punto pedido.
1. Se pide elaborar un sistema que al recibir por UART (115200, 8N1) el valor de la entrada
analógica de la placa 1 cambie la intensidad del brillo del LED de la placa 2 y esta última deberá
enviarle por UART a la placa 1 el porcentaje de brillo que deberá ser visualizado por algún
método (leds, display 7 segmentos, display LCD…).
Visto: __________________
2 de 8
Condiciones
En grupos de 3 o 4 alumnos deberán realizar el sigu íente trabajo, la entrega del informe se realizará
individualmente en formato digital por la plataforma TEAMS o por el Campus Virtual según sea habilitado.
Materiales
Para el ejercicio se usará, además de las placas de desarrollo Raspberry Pi Pico y/o Raspberry Pi Pico W,
LED's, presets o potenciómetros, pulsadores, resistencias necesarias y un protoboard donde conectar todo.
Informe
Para la entrega del informe (en formato electrónico) se pide:
• Archivo editado con la carátula debidamente completada con los integrantes del grupo.
• Foto o escaneo de esta hoja firmada con el visto del docente cuando corrobora que lo implementado
funciona como se pidió.
• Un diagrama o circuito eléctrico del armado donde se especifiquen valores de componentes y
terminales utilizados en las placas de desarrollo.
• El código implementado para la solución y una breve descripción de lo que hace cada parte.
Enunciado
El siguiente puntos debe estar resuelto aplicando, cuando sea pertinente, interrupciones de GPIO, demora
anti-rebote por software y utilizando el systick para medir los tiempos necesarios. Es conveniente armar el
sistema completo para luego poder desarrollar el punto pedido.
l. Se pide elaborar un sistema que al recibir por UART (115200, SN 1) el valor de la entrada
analógica de la placa 1 cambie la intensidad del brillo del LED de la placa 2 y esta última deberá
enviarle por UART a la placa 1 el porcentaje de brillo que deberá ser visualizado p r algún
método (leds, display 7 segmentos, display LCD ... ).
2 de 5
Esquema eléctrico
3 de 8
Código:
Pico 1:
#include <stdio.h>
#include "pico/stdlib.h"
#include "stdlib.h"
#include "systick.h"
#include "hardware/adc.h"
#include "hardware/pwm.h"
#include "hardware/uart.h"
#include "string.h"
#define lcd_rs_pin 16 // Declaracion de constantes
#define lcd_en_pin 17
#define lcd_d4_pin 18
#define lcd_d5_pin 19
#define lcd_d6_pin 20
#define lcd_d7_pin 21
#define pot_pin 26
#define led_pwm 25
#define ADC_CH0 0
#define cant_muestras 5
#define UART_ID uart0
#define BAUD_RATE 115200
#define UART_TX_PIN 0
#define UART_RX_PIN 1
uint32_t frec_adc; // Declaracion de Variables
uint32_t frec_lcd;
uint32_t frec_uart;
uint16_t resu_adc = 0;
uint16_t cont_muestras = 0;
uint16_t cuentas = 0;
uint8_t dato_rx[] = {0,0,0};
uint8_t dato_tx[] = {'I',0,0,'F'};
uint16_t dato_16 = 0;
char cuentas_char[10] ={0};
void lcd_port(int a); // Funciones para el manejo del LCD 20x2 a 4 bit
void lcd_cmd(int com);
void lcd_putchar(char a);
void lcd_putstr(char a[]);
void lcd_move_to(int col, int row);
int escalado(int a);
int main(){
gpio_init(lcd_rs_pin); // Configura los pines para el manejo del LCD
gpio_set_dir(lcd_rs_pin, GPIO_OUT);
gpio_init(lcd_en_pin);
gpio_set_dir(lcd_en_pin, GPIO_OUT);
gpio_init(lcd_d4_pin);
gpio_set_dir(lcd_d4_pin, GPIO_OUT);
gpio_init(lcd_d5_pin);
gpio_set_dir(lcd_d5_pin, GPIO_OUT);
gpio_init(lcd_d6_pin);
gpio_set_dir(lcd_d6_pin, GPIO_OUT);
gpio_init(lcd_d7_pin);
gpio_set_dir(lcd_d7_pin, GPIO_OUT);
stdio_init_all(); // Inicializa librerias
init_systick();
adc_init(); // Inicializa el Puerto ADC
adc_gpio_init(pot_pin);
adc_select_input(ADC_CH0);
uart_init(UART_ID, BAUD_RATE); // Inicializa el puerto UART en 115200 8N1
uart_set_hw_flow(UART_ID, false, false);
uart_set_format(UART_ID, 8, 1, UART_PARITY_NONE);
gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART);
gpio_set_function(UART_RX_PIN, GPIO_FUNC_UART);
frec_adc = get_systick(); // Asigna valores de systick para definir el periodo de ejecicion de cada funcion
frec_lcd = get_systick();
frec_uart = get_systick();
4 de 8
lcd_port(0x00); // Inicializa el LCD
sleep_us(20000);
lcd_cmd(0x03);
sleep_us(5000);
lcd_cmd(0x03);
sleep_us(11000);
lcd_cmd(0x03);
lcd_cmd(0x02);
lcd_cmd(0x02);
lcd_cmd(0x08);
lcd_cmd(0x00);
lcd_cmd(0x0C);
lcd_cmd(0x00);
lcd_cmd(0x06);
lcd_cmd(0x00);
lcd_cmd(0x01);
sleep_us(5000);
lcd_putstr("Intensidad:");
while(1){
if(frec_adc <= get_systick()){ // Lee el valor del ADC cada 5 ms
frec_adc += 5;
resu_adc = resu_adc + adc_read();
cont_muestras++;
if(cont_muestras == cant_muestras){ // Filtro del valor ADC. toma 5 valores y los promedia
resu_adc = resu_adc / cant_muestras;
cuentas = resu_adc;
resu_adc = 0;
cont_muestras = 0;
}
}
if(frec_uart <= get_systick()){ // Genera TX y RX del UART cada 10 ms
frec_uart += 10;
dato_tx[1] = cuentas & 0x00ff; // Pasa el Valor de la variable Cuentas de 16 bit al vector
dato_tx[2] = (cuentas & 0xff00) >> 8; // dato_tx a 2 valores de 8 bit
for(int i = 0; i <=3; i++){
uart_putc(UART_ID,dato_tx[i]); // Envia el vector por la UART
}
//printf("Inicio = %c, Dato tx 1 = %i, Dato tx 2 = %i, Fin = %c \r\n",dato_tx[0], dato_tx[1], dato_tx[2], dato_tx[3]);
if(uart_is_readable(UART_ID)){ // si existen datos en Buffer lee UART
dato_rx[0] = uart_getc(UART_ID);
if(dato_rx[0] == 'I'){ // Si el dato leido es I lee datos restantes
dato_rx[1] = uart_getc(UART_ID);
dato_rx[2] = uart_getc(UART_ID);
dato_rx[3] = uart_getc(UART_ID);
if(dato_rx[3] == 'F'){
dato_16 = (dato_rx[2] << 8) | dato_rx[1];
printf("Inicio = %c, Dato tx 1 = %i, Dato tx 2 = %i, Fin = %c, Dato 16 = %i, \r\n",dato_tx[0], dato_tx[1], dato_tx[2], dato_tx[3],
dato_16);
}
}
}
if(frec_lcd <= get_systick()){ // Actualiza el LCD cada 100 ms Con el Valor recibido de la UART
frec_lcd += 100;
lcd_putstr(" ");
lcd_move_to(11,0);
utoa(escalado(dato_16),cuentas_char,10);
lcd_putstr(cuentas_char);
lcd_putchar('%');
lcd_move_to(11,0);
5 de 8
}
}
}
/* Funciones para el manejo de datos con el LCD*/
void lcd_port(int a){ // Maneja el puerto con el dato a enviar al LCD
if(a & 1){
gpio_put(lcd_d4_pin,true);
}else{
gpio_put(lcd_d4_pin,false);
}
if(a & 2){
gpio_put(lcd_d5_pin,true);
}else{
gpio_put(lcd_d5_pin,false);
}
if(a & 4){
gpio_put(lcd_d6_pin,true);
}else{
gpio_put(lcd_d6_pin,false);
}
if(a & 8){
gpio_put(lcd_d7_pin,true);
}else{
gpio_put(lcd_d7_pin,false);
}
return;
}
void lcd_cmd(int com){ // Maneja el PIN RS del LCD
gpio_put(lcd_rs_pin,false);
lcd_port(com);
gpio_put(lcd_en_pin,true);
sleep_us(4000);
gpio_put(lcd_en_pin,false);
return;
}
void lcd_putchar(char a){ // Funcion para enviar un caracter al LCD
//printf("%i\r\n",a);
int temp = a & 0x0f;
int y = a & 0xf0;
gpio_put(lcd_rs_pin,true);
y = y >> 4;
lcd_port(y);
gpio_put(lcd_en_pin,true);
sleep_us(40);
gpio_put(lcd_en_pin,false);
lcd_port(temp);
gpio_put(lcd_en_pin,true);
sleep_us(40);
gpio_put(lcd_en_pin,false);
sleep_us(40);
return;
}
void lcd_putstr(char a[]){ // Funcion para enviar una cadena al LCD
int i=0;
while(a[i] != '\0'){
lcd_putchar(a[i]);
i++;
}
return;
}
void lcd_move_to(int col, int row){ // Funcion para posicionar el cursor en el LCD
if (row == 0){
6 de 8
int temp = 0x80 + col;
int z = temp >> 4;
int y = temp & 0x0f;
lcd_cmd(z);
lcd_cmd(y);
} else if ( row == 1){
int temp = 0xc0 + col;
int z = temp >> 4;
int y = temp & 0x0f;
lcd_cmd(z);
lcd_cmd(y);
}
return;
}
int escalado(int a){ // Funcion para el escalado del recibido del UART a % para mostrar en el LCD
float result = 0.02456;
int salida;
result = a * result;
salida = result;
return salida;
Pico 2:
#include <stdio.h>
#include "pico/stdlib.h"
#include "stdlib.h"
#include "systick.h"
#include "hardware/uart.h"
#include "hardware/pwm.h"
#include "string.h"
#define led_pwm 25 // Declaracion de constantes
#define UART_ID uart0
#define BAUD_RATE 115200
#define UART_TX_PIN 0
#define UART_RX_PIN 1
uint32_t frec_uart; // Declaracion de Variables
uint8_t dato_rx[4] = {0,0,0,0};
uint16_t dato_16;
int main(){
stdio_init_all(); // Inicializa librerias
init_systick();
uart_init(UART_ID, BAUD_RATE); // Inicializa el UART
uart_set_hw_flow(UART_ID, false, false);
uart_set_format(UART_ID, 8, 1, UART_PARITY_NONE);
gpio_set_function(led_pwm,GPIO_FUNC_PWM);
uint slice = pwm_gpio_to_slice_num(led_pwm);
uint chan = pwm_gpio_to_channel(led_pwm);
pwm_set_clkdiv_int_frac(slice,15,4);
pwm_set_wrap(slice,4095);
pwm_set_enabled(slice,true);
gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART);
gpio_set_function(UART_RX_PIN, GPIO_FUNC_UART);
frec_uart = get_systick();
while(1){
if(frec_uart <= get_systick()){ // Envia cada 10 ms datos por UART
frec_uart += 10;
7 de 8
for(int i = 0; i <=3; i++){
uart_putc(UART_ID,dato_rx[i]); // Envia el vector por la UART
}
if(uart_is_readable(UART_ID)){ // si existen datos en Buffer lee UART
dato_rx[0] = uart_getc(UART_ID);
if(dato_rx[0] == 'I'){ // Si el dato leido es I, lee datos restantes
dato_rx[1] = uart_getc(UART_ID);
dato_rx[2] = uart_getc(UART_ID);
dato_rx[3] = uart_getc(UART_ID);
if(dato_rx[3] == 'F'){ // Si el último dato Leído es F, considera la cadena como valida y realiza conversión
dato_16 = (dato_rx[2] << 8) | dato_rx[1];
pwm_set_chan_level(slice,chan,(uint16_t)dato_16);
//printf("Dato 0 = %c, Dato 1 = %i, Dato 2 = %i, Dato 3 = %c, Dato_16 = %i
\r\n",dato_rx[0],dato_rx[1],dato_rx[2],dato_rx[3],dato_16);
}
}
}
}
8 de 8