/*Projeto de Ian Périgo aluno de TSI da UERN e FIC Embarcatech IFRN
https://www.linkedin.com/in/ianperigo/
https://github.com/IanPerigoUERN
https://github.com/IanPerigoVianna
Bibliotecas do SSD1306, ws2818b e código do teste do display retirados do repositório
Oficial BitDogLab: https://github.com/BitDogLab/BitDogLab-C/blob/main/display_oled/display_oled.c
*/
/*166- https://www.ti.com/lit/ds/symlink/sn74hc166.pdf*/
/*https://docs.wokwi.com/pt-BR/parts/wokwi-74hc165*/
/*Datasheet https://www.ti.com/lit/ds/symlink/sn74hc165-ep.pdf?HQS=dis-dk-null-digikeymode-dsf-pf-null-wwe&ts=1748975820690&ref_url=https%253A%252F%252Fwww.ti.com%252Fgeneral%252Fdocs%252Fsuppproductinfo.tsp%253FdistId%253D10%2526gotoUrl%253Dhttps%253A%252F%252Fwww.ti.com%252Flit%252Fgpn%252Fsn74hc165-ep */
/*Um pino de Load - conectado ao pino GP28 da BitDogLab;
Um pino de CLK - conectado ao pino GP17 da BitDogLab;
Um pino de Saída Serial - conectado ao pino GP16 da BitDogLab
*/
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
// Define LED pins based on your initial comment
#define RED_LED_PIN 13
#define GREEN_LED_PIN 11 // Corrected from your comment (Green before Blue)
#define BLUE_LED_PIN 12
// Define Shift Register pins based on your initial comment
// For a parallel-in serial-out shift register like 74HC165:
// - Load pin (PL on 74HC165) is connected to PICO_LOAD_PIN
// - Clock pin (CP on 74HC165) is connected to PICO_CLK_PIN
// - Serial Data Output (Q7 or QH on 74HC165) is connected to PICO_DATA_IN_PIN
#define PICO_LOAD_PIN 28 // GP28 - Parallel Load (PL)
#define PICO_CLK_PIN 17 // GP17 - Clock (CLK)
#define PICO_DATA_IN_PIN 16 // GP16 - Serial Data Input (Data from Shift Register)
#define NUM_DIP_SWITCHES 8 // We are reading 8 bits from the DIP switch
// Function to initialize GPIO pins
void setup_gpios() {
// Initialize LED pins as outputs
gpio_init(RED_LED_PIN);
gpio_set_dir(RED_LED_PIN, GPIO_OUT);
gpio_put(RED_LED_PIN, 0); // Start with LED off
gpio_init(GREEN_LED_PIN);
gpio_set_dir(GREEN_LED_PIN, GPIO_OUT);
gpio_put(GREEN_LED_PIN, 0); // Start with LED off
gpio_init(BLUE_LED_PIN);
gpio_set_dir(BLUE_LED_PIN, GPIO_OUT);
gpio_put(BLUE_LED_PIN, 0); // Start with LED off
// Initialize Shift Register control pins
gpio_init(PICO_LOAD_PIN);
gpio_set_dir(PICO_LOAD_PIN, GPIO_OUT);
gpio_put(PICO_LOAD_PIN, 1); // PL is often active low, so keep it high initially
gpio_init(PICO_CLK_PIN);
gpio_set_dir(PICO_CLK_PIN, GPIO_OUT);
gpio_put(PICO_CLK_PIN, 0); // Clock initially low
gpio_init(PICO_DATA_IN_PIN);
gpio_set_dir(PICO_DATA_IN_PIN, GPIO_IN);
// No pull-up/down needed here as it's driven by the shift register
}
// Function to read the state of the DIP switches from the shift register
uint8_t read_dip_switches() {
uint8_t dip_data = 0;
// 1. Pulse the Load pin (PL) LOW then HIGH to capture the parallel data
// from DIP switches into the shift register.
gpio_put(PICO_LOAD_PIN, 0);
sleep_us(5); // Small delay to ensure the load pulse is registered
gpio_put(PICO_LOAD_PIN, 1);
sleep_us(5);
// 2. Read the 8 bits out serially
// Most shift registers like 74HC165 will output MSB first from Q7/QH.
// We clock the data out by pulsing the CLK pin.
// Data is typically valid before the rising edge or after the falling edge of the clock.
// The provided Arduino example reads, then clocks. Let's follow that.
// 74HC165 shifts on the LOW-to-HIGH clock transition. Data should be stable and read when CLK is LOW.
for (int i = 0; i < NUM_DIP_SWITCHES; i++) {
// Shift current data one bit to the left to make space for the new bit
dip_data = dip_data << 1;
// Read the current bit from the shift register's serial output
// Ensure clock is low before reading if register changes output on rising edge
gpio_put(PICO_CLK_PIN, 0); // Not strictly necessary if clock cycle starts low
sleep_us(2); // Allow data line to settle
if (gpio_get(PICO_DATA_IN_PIN)) {
dip_data |= 0x01; // Set the LSB if the input is high
}
// Pulse the Clock pin (HIGH then LOW) to shift the next bit into the serial output position
gpio_put(PICO_CLK_PIN, 1);
sleep_us(2); // Clock pulse width
gpio_put(PICO_CLK_PIN, 0);
sleep_us(2); // Clock low time
}
return dip_data;
}
int main() {
// Initialize stdio for printf capabilities (e.g., over USB CDC)
stdio_init_all();
// Setup GPIO pins
setup_gpios();
printf("DIP Switch RGB LED Controller Started!\n");
printf("GP%d (Red), GP%d (Green), GP%d (Blue)\n", RED_LED_PIN, GREEN_LED_PIN, BLUE_LED_PIN);
printf("Shift Register: Load=GP%d, CLK=GP%d, DataIn=GP%d\n", PICO_LOAD_PIN, PICO_CLK_PIN, PICO_DATA_IN_PIN);
uint8_t previous_dip_state = 0; // To detect changes
while (1) {
uint8_t current_dip_state = read_dip_switches();
if (current_dip_state != previous_dip_state) {
printf("DIP Switch State: ");
for (int i = 7; i >= 0; i--) {
printf("%d", (current_dip_state >> i) & 1);
}
printf(" (0x%02X)\n", current_dip_state);
// Control RGB LED based on the first 3 bits of the DIP switch
// Bit 0 (LSB, or DIP switch 1 if wired that way) -> RED
// Bit 1 -> GREEN
// Bit 2 -> BLUE
// Set Red LED state (using switch 1, which corresponds to bit 0)
if ((current_dip_state & (1 << 0))) { // Check if bit 0 is set
gpio_put(RED_LED_PIN, 1); // Turn RED LED ON
} else {
gpio_put(RED_LED_PIN, 0); // Turn RED LED OFF
}
// Set Green LED state (using switch 2, which corresponds to bit 1)
if ((current_dip_state & (1 << 1))) { // Check if bit 1 is set
gpio_put(GREEN_LED_PIN, 1); // Turn GREEN LED ON
} else {
gpio_put(GREEN_LED_PIN, 0); // Turn GREEN LED OFF
}
// Set Blue LED state (using switch 3, which corresponds to bit 2)
if ((current_dip_state & (1 << 2))) { // Check if bit 2 is set
gpio_put(BLUE_LED_PIN, 1); // Turn BLUE LED ON
} else {
gpio_put(BLUE_LED_PIN, 0); // Turn BLUE LED OFF
}
previous_dip_state = current_dip_state;
}
sleep_ms(100); // Read DIP switches every 100ms
}
return 0; // Should not be reached
}