Pico Led Controller 1.0.3
A project to control LEDs using Raspberry Pi Pico W
led_controller.c
Go to the documentation of this file.
1 #include "led_controller.h"
2 
3 #include <stdio.h>
4 #include <stdlib.h>
5 
6 #include "urgb.h"
7 #include "hsv.h"
8 #include "ws2812b.h"
9 #include "light_state.h"
10 #include "wifi_credentials.h"
11 #include "generated/ws2812.pio.h"
12 
13 #include "lwipopts.h"
14 #include "lwip/apps/httpd.h"
15 #include "ssi.h"
16 #include "cgi.h"
17 #include "ntp.h"
18 
19 volatile bool light_state_toggle_request = false;
20 volatile bool light_mode_toggle_request = false;
21 volatile bool stop_flag = false;
22 volatile uint64_t last_press_time = 0;
23 
25 {
27  printf("Connecting to Wi-Fi...\n");
28  while (cyw43_arch_wifi_connect_timeout_ms(WIFI_SSID, WIFI_PASSWORD, CYW43_AUTH_WPA2_AES_PSK, 10000) != 0)
29  printf("Attempting to connect...\n");
30  printf("Connected!\n");
31  extern cyw43_t cyw43_state;
32  uint32_t ip_addr = cyw43_state.netif[CYW43_ITF_STA].ip_addr.addr;
33  printf("IP Address: %lu.%lu.%lu.%lu\n", ip_addr & 0xFF, (ip_addr >> 8) & 0xFF, (ip_addr >> 16) & 0xFF, ip_addr >> 24);
35 }
36 
37 void gpio_button_irq_handler(uint gpio, uint32_t events)
38 {
39  uint64_t current_time = time_us_64();
40  if (current_time - last_press_time >= DEBOUNCE_TIME_US)
41  {
42  last_press_time = current_time;
43  switch (gpio)
44  {
45  case LIGHT_TOGGLE_PIN:
47  break;
48  case MODE_BUTTON_PIN:
50  if (!light_state.state)
52  break;
53  case STOP_BUTTON_PIN:
54  stop_flag = true;
55  break;
56  default:
57  break;
58  }
59  }
60 }
61 
62 enum init_result_t init()
63 {
64  if (!stdio_init_all())
65  {
66  printf("Stdio init failed");
67  return STDIO_INIT_FAILURE;
68  }
69 
70  // GPIO setup - LED
71  gpio_init(CYW43_WL_GPIO_LED_PIN);
72  gpio_set_dir(CYW43_WL_GPIO_LED_PIN, GPIO_OUT);
73  gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
74 
75  // GPIO setup - buttons
76  gpio_init(LIGHT_TOGGLE_PIN);
77  gpio_set_dir(LIGHT_TOGGLE_PIN, GPIO_IN);
78  gpio_pull_up(LIGHT_TOGGLE_PIN);
79 
80  gpio_init(MODE_BUTTON_PIN);
81  gpio_set_dir(MODE_BUTTON_PIN, GPIO_IN);
82  gpio_pull_up(MODE_BUTTON_PIN);
83 
84  gpio_init(STOP_BUTTON_PIN);
85  gpio_set_dir(STOP_BUTTON_PIN, GPIO_IN);
86  gpio_pull_up(STOP_BUTTON_PIN);
87 
88  // GPIO setup - interrupts
89  gpio_set_irq_enabled_with_callback(LIGHT_TOGGLE_PIN, GPIO_IRQ_EDGE_FALL, true, &gpio_button_irq_handler);
90  gpio_set_irq_enabled_with_callback(MODE_BUTTON_PIN, GPIO_IRQ_EDGE_FALL, true, &gpio_button_irq_handler);
91  gpio_set_irq_enabled_with_callback(STOP_BUTTON_PIN, GPIO_IRQ_EDGE_FALL, true, &gpio_button_irq_handler);
92 
93  // Wi-Fi setup
94  if (cyw43_arch_init())
95  {
96  printf("Wi-Fi init failed");
97  return WIFI_INIT_FAILURE;
98  }
99  cyw43_wifi_pm(&cyw43_state, cyw43_pm_value(CYW43_NO_POWERSAVE_MODE, 20, 1, 1, 1));
100  cyw43_arch_enable_sta_mode();
101  connect_to_wifi();
102  httpd_init();
103  ssi_init();
104  cgi_init();
105  ntp_update_time();
107 
108  // PIO setup - WS2812B
109  PIO pio = pio0;
110  int sm = 0;
111  uint offset = pio_add_program(pio, &ws2812_program);
112  ws2812_program_init(pio, sm, offset, WS2812_PIN, 800000, IS_RGBW);
113  printf("WS2812 LED Control, using pin %d\n", WS2812_PIN);
114 
116  return INIT_SUCCESS;
117 }
118 
119 void run_loop()
120 {
121  uint16_t base_hue = 0;
122  uint8_t speed_factor_wheel = 4;
123  uint8_t speed_factor_cycle = 1;
124  uint8_t speed_factor_breathing = 3;
125  uint8_t density_factor = 3;
126  uint8_t breathing_brightness = 15;
127  bool breathing_up = true;
128  while (true) // [ ] Remove bug - cannot change mode after multiple changes
129  { // [ ] Add restart button from web interface
131  {
134  }
136  {
139  }
140  if (stop_flag)
141  {
143  break;
144  }
145  switch (light_state.light_mode)
146  {
147  case MODE_RAINBOW_WHEEL:
148  if (light_state.state)
149  apply_rainbow_wheel_effect(NUM_PIXELS, &base_hue, &speed_factor_wheel, &density_factor, &light_state.brightness);
150  break;
151  case MODE_RAINBOW_CYCLE:
152  if (light_state.state)
153  apply_rainbow_cycle_effect(NUM_PIXELS, &base_hue, &speed_factor_cycle, &light_state.brightness);
154  break;
155  case MODE_BREATHING:
156  if (light_state.state)
157  {
158  uint32_t current_color = get_current_color();
159  apply_breathing_effect(NUM_PIXELS, &speed_factor_breathing, &current_color, &light_state.brightness, &breathing_brightness, &breathing_up);
160  }
161  break;
162  case MODE_FLASHING:
163  if (light_state.state)
164  {
165  uint32_t current_color = get_current_color();
166  apply_flashing_effect(NUM_PIXELS, &current_color);
167  }
168  break;
169  // [ ] Implement the rest of dynamic modes
170  default:
171  break;
172  }
173  sleep_ms(40);
174  }
175 }
void cgi_init()
Initialize CGI handlers.
Definition: cgi.c:289
volatile bool light_state_toggle_request
volatile bool light_mode_toggle_request
void gpio_button_irq_handler(uint gpio, uint32_t events)
GPIO button interrupt handler.
volatile bool stop_flag
void connect_to_wifi()
Connect to WiFi.
volatile uint64_t last_press_time
void run_loop()
Run loop.
enum init_result_t init()
Init.
#define DEBOUNCE_TIME_US
#define MODE_BUTTON_PIN
#define IS_RGBW
#define LIGHT_TOGGLE_PIN
init_result_t
Init result enum.
@ STDIO_INIT_FAILURE
@ WIFI_INIT_FAILURE
@ INIT_SUCCESS
#define STOP_BUTTON_PIN
#define WS2812_PIN
uint32_t get_current_color()
Get current color.
Definition: light_state.c:116
void toggle_light_state()
Toggle light state.
Definition: light_state.c:10
#define NUM_PIXELS
Definition: light_state.h:4
void toggle_light_mode()
Toggle light mode.
Definition: light_state.c:19
@ MODE_RAINBOW_CYCLE
Definition: light_state.h:20
@ MODE_FLASHING
Definition: light_state.h:23
@ MODE_BREATHING
Definition: light_state.h:22
@ MODE_RAINBOW_WHEEL
Definition: light_state.h:19
volatile struct light_state_t light_state
Light state.
Definition: light_state.c:8
void ntp_update_time(void)
NTP update time.
Definition: ntp.c:123
void ssi_init()
SSI init.
Definition: ssi.c:138
uint8_t brightness
Definition: light_state.h:59
enum light_modes light_mode
Definition: light_state.h:61
void apply_flashing_effect(uint32_t len, uint32_t *color)
Apply flashing effect.
Definition: ws2812b.c:214
void apply_breathing_effect(uint32_t len, uint8_t *speed_factor, uint32_t *color, volatile uint8_t *base_brightness, uint8_t *brightness, bool *breathing_up)
Apply breathing effect.
Definition: ws2812b.c:184
void turn_off_all(uint32_t len)
Turn off all leds.
Definition: ws2812b.c:23
void apply_rainbow_wheel_effect(uint32_t len, uint16_t *base_hue, uint8_t *speed_factor, uint8_t *density_factor, volatile uint8_t *brightness)
Apply rainbow wheel effect.
Definition: ws2812b.c:160
void apply_rainbow_cycle_effect(uint32_t len, uint16_t *hue, uint8_t *speed_factor, volatile uint8_t *brightness)
Apply rainbow cycle effect.
Definition: ws2812b.c:174