#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "stdlib.h"
// Define pins
const uint8_t dataPin = 4;
const uint8_t latchPin = 3;
const uint8_t clockPin = 2;
const uint8_t ENC_A = 10;
const uint8_t ENC_B = 11;
const uint8_t ENC_SW = 12;
// Define bit strings
char* bitString = "10000000";
char* prevString;
char* savedString;
char* ledEnabled;
int LEDs = 8;
void NextLED() {
printf("CW\n");
char tmpChar = bitString[LEDs-1];
char tmpRes[9];
for (int i = 0; i < LEDs-1; i++) {
tmpRes[i+1] = bitString[i];
}
tmpRes[0] = tmpChar;
tmpRes[LEDs] = '\0';
//printf("%s\n", tmpRes);
strcpy(bitString, tmpRes);
Update(bitString);
}
void PrevLED() {
printf("CCW\n");
char tmpChar = bitString[0];
char tmpRes[9];
for (int i = 0; i < LEDs-1; i++) {
tmpRes[i] = bitString[i+1];
}
tmpRes[LEDs-1] = tmpChar;
tmpRes[LEDs] = '\0';
//printf("%s\n", tmpRes);
strcpy(bitString, tmpRes);
Update(bitString);
}
void ToggleLED() {
//printf("Toggle LEDs");
ledEnabled = !ledEnabled;
if(ledEnabled) {
savedString = bitString;
bitString = "00000000";
} else {
bitString = savedString;
}
Update(bitString);
}
// Function to read the encoder data from the rotary switch encoder
void encoder_callback(uint gpio, uint32_t events) {
uint32_t gpio_state = 0;
gpio_state = (gpio_get_all() >> 10) & 0b0111; // get all GPIO them mask out all but bits 10, 11, 12
// This will need to change to match which GPIO pins are being used.
static bool ccw_fall = 0; //bool used when falling edge is triggered
static bool cw_fall = 0;
static bool sw_fall = 0;
uint8_t enc_value = 0;
enc_value = (gpio_state & 0x03);
//printf("enc_value = 0b%02b\n", enc_value);
printf("gpio_get_all = 0b%02b\n", (gpio_get_all() >> 10) & 0b0111);
if(gpio == ENC_A) {
if ((!cw_fall) && (enc_value == 0b10)) // cw_fall is set to TRUE when phase A interrupt is triggered
cw_fall = 1;
if ((ccw_fall) && (enc_value == 0b00)) { // if ccw_fall is already set to true from a previous B phase trigger, the ccw event will be triggered
cw_fall = 0;
ccw_fall = 0;
//do something here
PrevLED();
}
}
if(gpio == ENC_B) {
if ((!ccw_fall) && (enc_value == 0b01)) //ccw leading edge is true
ccw_fall = 1;
if ((cw_fall) && (enc_value == 0b00)) { //cw trigger
cw_fall = 0;
ccw_fall = 0;
//do something here
NextLED();
}
}
if (gpio == ENC_SW) {
ToggleLED();
}
}
// Function to shift data into the 74HC595 register
void Update(const char* data) {
// Start data sending
gpio_put(latchPin, 0);
gpio_put(clockPin, 0);
gpio_put(latchPin, 1);
// Load data in reverse order
for (int i = 0; i < 8; i++) {
gpio_put(clockPin, 0);
uint8_t val = (data[i] == '1') ? 1 : 0;
gpio_put(dataPin, val); // Check if the bit is '1'
gpio_put(clockPin, 1);
}
// Store data on register
gpio_put(latchPin, 0);
gpio_put(latchPin, 1);
}
int main() {
stdio_init_all();
// Initialize GPIO pins
gpio_init(dataPin);
gpio_init(latchPin);
gpio_init(clockPin);
gpio_init(ENC_SW);
gpio_init(ENC_B);
gpio_init(ENC_A);
// Set GPIO pin directions
gpio_set_dir(dataPin, GPIO_OUT);
gpio_set_dir(latchPin, GPIO_OUT);
gpio_set_dir(clockPin, GPIO_OUT);
gpio_set_dir(ENC_A, GPIO_IN);
gpio_set_dir(ENC_B, GPIO_IN);
gpio_set_dir(ENC_SW, GPIO_IN);
// disable pulls?
gpio_disable_pulls(ENC_A);
gpio_disable_pulls(ENC_B);
gpio_disable_pulls(ENC_SW);
// GPIO irq
gpio_set_irq_enabled_with_callback(ENC_SW, GPIO_IRQ_EDGE_FALL, true, &encoder_callback);
gpio_set_irq_enabled(ENC_A, GPIO_IRQ_EDGE_FALL, true);
gpio_set_irq_enabled(ENC_B, GPIO_IRQ_EDGE_FALL, true);
// Call the Update function
Update(bitString);
while (1) {
sleep_ms(1000);
}
}