Compare commits
	
		
			6 commits
		
	
	
		
			vienna_wtf
			...
			developmen
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | c57f25af03 | ||
|  | 1bdfc64972 | ||
|  | e43c72e925 | ||
|  | 732834ce24 | ||
|  | bcb877887e | ||
|  | 8275050dee | 
					 6 changed files with 166 additions and 24 deletions
				
			
		|  | @ -13,7 +13,6 @@ steps: | |||
|       - idf.py build | ||||
|   release: | ||||
|     image: woodpeckerci/plugin-release | ||||
|     secrets: [ ACCESS_TOKEN ] | ||||
|     when: | ||||
|       - event: tag | ||||
|     settings: | ||||
|  |  | |||
|  | @ -12,6 +12,7 @@ extern uint8_t running; | |||
| 
 | ||||
| void pumps_run(); | ||||
| void pumps_stop(); | ||||
| uint8_t pumps_io_init(); | ||||
| uint8_t pumps_init(); | ||||
| 
 | ||||
| uint8_t pumps_set_duration(uint8_t idx, uint8_t time); | ||||
|  |  | |||
|  | @ -138,8 +138,7 @@ static const struct ble_gatt_svc_def service_defs[] = { | |||
|   { 0 } // no more services
 | ||||
| }; | ||||
| 
 | ||||
| static int gatt_svr_chr_write(struct os_mbuf *om, uint16_t min_len, uint16_t max_len, | ||||
|     void *dst, uint16_t *len) { | ||||
| static int gatt_svr_chr_write(struct os_mbuf *om, uint16_t min_len, uint16_t max_len, void *dst, uint16_t *len) { | ||||
|   uint16_t om_len; | ||||
|   int rc; | ||||
| 
 | ||||
|  | @ -159,6 +158,7 @@ static int gatt_svr_chr_write(struct os_mbuf *om, uint16_t min_len, uint16_t max | |||
| static int svc_access_system(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg) { | ||||
|   uint16_t uuid16 = ble_uuid_u16(ctxt->chr->uuid); | ||||
|   uint8_t value = 0; | ||||
|   uint16_t vlen = 0; | ||||
| 
 | ||||
|   ESP_LOGI(TAG, "0x%02X access: %d", uuid16, ctxt->op); | ||||
| 
 | ||||
|  | @ -168,9 +168,11 @@ static int svc_access_system(uint16_t conn_handle, uint16_t attr_handle, struct | |||
|         ctxt->om, | ||||
|         sizeof value, | ||||
|         sizeof value, | ||||
|         &value, NULL | ||||
|         &value, &vlen | ||||
|         ); | ||||
| 
 | ||||
|     ESP_LOGI(TAG, "value (%d): %d", vlen, value); | ||||
| 
 | ||||
|     switch(uuid16) { | ||||
|       case BAROS_CHAR_POUR: | ||||
|         if(value == 1) { | ||||
|  |  | |||
|  | @ -54,6 +54,9 @@ void led_init() { | |||
| } | ||||
| 
 | ||||
| void app_main(void) { | ||||
|   // init pump IO immediately to limit run away pumps in case power is on
 | ||||
|   pumps_io_init(); | ||||
| 
 | ||||
|   esp_err_t err = nvs_flash_init(); | ||||
| 
 | ||||
|   if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) { | ||||
|  | @ -77,6 +80,7 @@ void app_main(void) { | |||
|   sprintf(name, "%s-%02X", TAG, mac[5]); | ||||
| 
 | ||||
|   uint8_t tank_levels[] = { 100, 100, 100, 100 }; | ||||
|   uint16_t pump_ramp_ms[] = { 500, 500, 500, 500 }; | ||||
| 
 | ||||
|   cfglr_handle_t cfglr_handle = { | ||||
|     .namespace = "configulator", | ||||
|  | @ -84,10 +88,11 @@ void app_main(void) { | |||
|     .elements = { | ||||
|       CFGLR_ELEMENT_U8("armed", 1, CFGLR_SIGNALER_IDF_EVENT()), | ||||
|       CFGLR_ELEMENT_U8("monitor", 0, CFGLR_SIGNALER_IDF_EVENT()), | ||||
|       CFGLR_ELEMENT_U8("pour_button", 21, CFGLR_SIGNALER_IDF_EVENT()), | ||||
|       CFGLR_ELEMENT_U8("pour_button", 19, CFGLR_SIGNALER_IDF_EVENT()), | ||||
|       CFGLR_ELEMENT_STR("device_name", 32, name, CFGLR_SIGNALER_IDF_EVENT()), | ||||
|       CFGLR_ELEMENT_BIN("tank_levels", 4, tank_levels, 4, CFGLR_SIGNALER_IDF_EVENT()), | ||||
|       CFGLR_ELEMENT_BIN("pump_pins", 4, pump_gpio_map, 4, CFGLR_SIGNALER_IDF_EVENT()), | ||||
|       CFGLR_ELEMENT_BIN("pump_ramp_ms", sizeof(uint16_t) * 4, pump_ramp_ms, sizeof(uint16_t) * 4, CFGLR_SIGNALER_IDF_EVENT()), | ||||
|       { NULL }, | ||||
|     }, | ||||
|   }; | ||||
|  |  | |||
							
								
								
									
										167
									
								
								main/pumps.c
									
										
									
									
									
								
							
							
						
						
									
										167
									
								
								main/pumps.c
									
										
									
									
									
								
							|  | @ -1,8 +1,10 @@ | |||
| #include "string.h" | ||||
| #include "freertos/FreeRTOS.h" | ||||
| #include "freertos/timers.h" | ||||
| #include "freertos/queue.h" | ||||
| #include "esp_log.h" | ||||
| #include "driver/gpio.h" | ||||
| #include "driver/ledc.h" | ||||
| #include "nvs_flash.h" | ||||
| 
 | ||||
| #include "main.h" | ||||
|  | @ -12,12 +14,42 @@ | |||
| 
 | ||||
| uint8_t running = 0; | ||||
| 
 | ||||
| typedef enum { | ||||
|   PUMP_STATE_IDLE = 0, | ||||
|   PUMP_STATE_RAMPING_UP, | ||||
|   PUMP_STATE_RUNNING, | ||||
|   PUMP_STATE_RAMPING_DOWN, | ||||
| } pump_states_e; | ||||
| 
 | ||||
| TimerHandle_t pump_timers[PUMPS]; | ||||
| QueueHandle_t pump_step_queue; | ||||
| 
 | ||||
| static pump_states_e pump_states[PUMPS] = { PUMP_STATE_IDLE }; | ||||
| static uint8_t pumps_duration[PUMPS] = {0}; | ||||
| static uint8_t pumps_enabled[PUMPS] = {0}; | ||||
| static uint8_t pumps_running[PUMPS] = {0}; | ||||
| static uint8_t safety = 1; | ||||
| 
 | ||||
| #define RAMP_UP_TIME            (500) | ||||
| #define RAMP_DOWN_TIME          (250) | ||||
| 
 | ||||
| #define LEDC_HS_TIMER           LEDC_TIMER_0 | ||||
| #define LEDC_HS_MODE            LEDC_HIGH_SPEED_MODE | ||||
| #define LEDC_LS_TIMER           LEDC_TIMER_1 | ||||
| #define LEDC_LS_MODE            LEDC_LOW_SPEED_MODE | ||||
| 
 | ||||
| #define LEDC_CONFIG(CHANNEL_NO, GPIO) (ledc_channel_config_t){\ | ||||
|   .channel = CHANNEL_NO,\ | ||||
|   .duty = 0,\ | ||||
|   .gpio_num = GPIO,\ | ||||
|   .speed_mode = LEDC_LOW_SPEED_MODE,\ | ||||
|   .hpoint = 0,\ | ||||
|   .timer_sel = LEDC_TIMER_1,\ | ||||
|   .flags.output_invert = 0,\ | ||||
| } | ||||
| 
 | ||||
| ledc_channel_config_t ledc_motor_channels[4] = {}; | ||||
| 
 | ||||
| void pumps_update_config() { | ||||
|   ESP_LOGI(TAG, "writing config"); | ||||
| 
 | ||||
|  | @ -47,7 +79,7 @@ uint8_t pumps_set_enabled(uint8_t idx, uint8_t value) { | |||
| 
 | ||||
|   value = (value ? 1 : 0); | ||||
| 
 | ||||
|   ESP_LOGD(TAG, "gpio: %d value: %d", io, value); | ||||
|   ESP_LOGI(TAG, "gpio: %d value: %d", io, value); | ||||
|   // invert IO
 | ||||
|   if(safety) | ||||
|     gpio_set_level(io, value); | ||||
|  | @ -79,9 +111,7 @@ void pump_timer_done(TimerHandle_t timer) { | |||
|   uint8_t idx = (pcTimerGetName(timer) - 0x48); | ||||
|   ESP_LOGD(TAG, "pump done: %d", idx); | ||||
| 
 | ||||
|   running--; | ||||
| 
 | ||||
|   pumps_set_enabled(idx, 0); | ||||
|   xQueueSend(pump_step_queue, &idx, portMAX_DELAY); | ||||
| } | ||||
| 
 | ||||
| void pumps_stop() { | ||||
|  | @ -89,8 +119,6 @@ void pumps_stop() { | |||
|     if(pump_timers[i] != NULL) { | ||||
|       pump_disable(i); | ||||
|       xTimerStop(pump_timers[i], 0); | ||||
| 
 | ||||
|       i++; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | @ -98,25 +126,80 @@ void pumps_stop() { | |||
| void pumps_run() { | ||||
|   if(running > 0) return; | ||||
| 
 | ||||
|   ESP_LOGI(TAG, "Running pumps"); | ||||
| 
 | ||||
|   for(uint8_t i = 0; i < PUMPS; i++) { | ||||
|     if(pumps_duration[i] == 0) continue; | ||||
|     //if(pumps_duration[i] == 0 || pumps_enabled[i] != 1) continue;
 | ||||
| 
 | ||||
|     if(pump_states[i] != PUMP_STATE_IDLE) { | ||||
|       ESP_LOGW(TAG, "Attempting to start pump in non-IDLE state. idx: %d state: %d", i, pump_states[i]); | ||||
|     } | ||||
| 
 | ||||
|     ledc_set_fade_with_time(ledc_motor_channels[i].speed_mode, ledc_motor_channels[i].channel, 8192, RAMP_UP_TIME); | ||||
|     ledc_fade_start(ledc_motor_channels[i].speed_mode, ledc_motor_channels[i].channel, LEDC_FADE_NO_WAIT); | ||||
| 
 | ||||
|     pump_states[i] = PUMP_STATE_RAMPING_UP; | ||||
| 
 | ||||
|     running++; | ||||
| 
 | ||||
|     pump_timers[i] = xTimerCreate((const char *)(0x48 + i), (pumps_duration[i] * 250 / portTICK_PERIOD_MS), pdFALSE, (void*)0, pump_timer_done); | ||||
| 
 | ||||
|     xTimerStart(pump_timers[i], 0); | ||||
| 
 | ||||
|     pumps_set_enabled(i, 1); | ||||
|     ESP_LOGI(TAG, "Pump %d started", i); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| uint8_t pumps_init() { | ||||
| void pump_step_task() { | ||||
|   uint8_t idx; | ||||
|   BaseType_t awoke = pdFALSE; | ||||
| 
 | ||||
|   ESP_LOGI(TAG, "Starting pump stepping task"); | ||||
| 
 | ||||
|   while(xQueueReceive(pump_step_queue, &idx, &awoke)) { | ||||
|     ESP_LOGI(TAG, "step %d complete for %d", pump_states[idx], idx); | ||||
| 
 | ||||
|     if(pump_states[idx] == PUMP_STATE_RAMPING_UP) { | ||||
|       uint16_t pump_time = pumps_duration[idx] * 250 - (RAMP_UP_TIME + RAMP_DOWN_TIME) / 2; | ||||
| 
 | ||||
|       if(RAMP_UP_TIME + RAMP_DOWN_TIME / 2 > pumps_duration[idx] * 250) { | ||||
|         ESP_LOGW(TAG, "Pump %d total ramp time great that duration, running for 1 Tick", idx); | ||||
| 
 | ||||
|         pump_time = 10; | ||||
|       } | ||||
| 
 | ||||
|       ESP_LOGI(TAG, "Running pump %d for %dms", idx, pump_time); | ||||
| 
 | ||||
|       xTimerChangePeriod(pump_timers[idx], pump_time / portTICK_PERIOD_MS, portMAX_DELAY); | ||||
|       xTimerStart(pump_timers[idx], portMAX_DELAY); | ||||
| 
 | ||||
|       pump_states[idx] = PUMP_STATE_RUNNING; | ||||
| 
 | ||||
|       continue; | ||||
|     } else if(pump_states[idx] == PUMP_STATE_RUNNING) { | ||||
|       ledc_set_fade_with_time(ledc_motor_channels[idx].speed_mode, ledc_motor_channels[idx].channel, 0, RAMP_UP_TIME); | ||||
|       ledc_fade_start(ledc_motor_channels[idx].speed_mode, ledc_motor_channels[idx].channel, LEDC_FADE_NO_WAIT); | ||||
| 
 | ||||
|       pump_states[idx] = PUMP_STATE_RAMPING_DOWN; | ||||
|       continue; | ||||
|     } else if(pump_states[idx] == PUMP_STATE_RAMPING_DOWN) { | ||||
|       ESP_LOGI(TAG, "Pump cycles complete: %d", idx); | ||||
|       pump_states[idx] = PUMP_STATE_IDLE; | ||||
| 
 | ||||
|       running--; | ||||
|     } else { | ||||
|       ESP_LOGE(TAG, "Pump step fired with unknown state: %d", pump_states[idx]); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| static IRAM_ATTR bool ledc_fade_end_event(const ledc_cb_param_t *param, void *parg) { | ||||
|   BaseType_t awoke = pdFALSE; | ||||
| 
 | ||||
|   xQueueSendFromISR(pump_step_queue, parg, &awoke); | ||||
| 
 | ||||
|   return (awoke == pdTRUE); | ||||
| } | ||||
| 
 | ||||
| uint8_t pumps_io_init() { | ||||
|   gpio_config_t io_conf; | ||||
| 
 | ||||
|   // put the output high before initializing
 | ||||
|   // to prevent relays from clacking
 | ||||
|   for(uint8_t i = 0 ; i < 4; i++) { | ||||
|   for(uint8_t i = 0 ; i < PUMPS; i++) { | ||||
|     gpio_set_level(pump_gpio_map[i], 0); | ||||
|   } | ||||
| 
 | ||||
|  | @ -125,12 +208,18 @@ uint8_t pumps_init() { | |||
|   io_conf.pin_bit_mask = GPIO_PUMP_PIN_SEL; | ||||
|   io_conf.pull_down_en = 1; | ||||
|   io_conf.pull_up_en = 0; | ||||
|   gpio_config(&io_conf); | ||||
| 
 | ||||
|   return gpio_config(&io_conf); | ||||
| } | ||||
| 
 | ||||
| uint8_t pumps_init() { | ||||
|   // zero out pump enabled, duration
 | ||||
|   memset(&pumps_enabled, 0, sizeof(uint8_t) * PUMPS); | ||||
|   memset(&pumps_duration, 5, sizeof(uint8_t) * PUMPS); | ||||
| 
 | ||||
|   // this should neve go above 4, but just in case?
 | ||||
|   pump_step_queue = xQueueCreate(PUMPS * 4, sizeof(uint8_t)); | ||||
| 
 | ||||
|   size_t size = sizeof(uint8_t) * PUMPS; | ||||
|   if(!nvs_get_blob(config_handle, "pumps_duration", &pumps_duration, &size)) { | ||||
|     ESP_LOGI(TAG, "Initializing pumps config"); | ||||
|  | @ -138,8 +227,50 @@ uint8_t pumps_init() { | |||
|     nvs_set_blob(config_handle, "pumps_duration", &pumps_duration, size); | ||||
|   }; | ||||
| 
 | ||||
|   ledc_timer_config_t ledc_timer = { | ||||
|     .duty_resolution = LEDC_TIMER_13_BIT, // resolution of PWM duty
 | ||||
|     .freq_hz = 4000,                      // frequency of PWM signal
 | ||||
|     .speed_mode = LEDC_LS_MODE,           // timer mode
 | ||||
|     .timer_num = LEDC_LS_TIMER,            // timer index
 | ||||
|     .clk_cfg = LEDC_AUTO_CLK,              // Auto select the source clock
 | ||||
|   }; | ||||
| 
 | ||||
|   ledc_timer_config(&ledc_timer); | ||||
| 
 | ||||
|   ledc_timer.speed_mode = LEDC_HS_MODE; | ||||
|   ledc_timer.timer_num = LEDC_HS_TIMER; | ||||
| 
 | ||||
|   ledc_timer_config(&ledc_timer); | ||||
| 
 | ||||
|   for(uint8_t i = 0; i < PUMPS; i++) { | ||||
|     gpio_set_level(pump_gpio_map[i], 0); | ||||
| 
 | ||||
|     pump_timers[i] = xTimerCreate((const char *)(0x48 + i), 1, pdFALSE, (void*)0, pump_timer_done); | ||||
|   } | ||||
| 
 | ||||
|   for(uint8_t i = 0; i < PUMPS; i++) { | ||||
|     ledc_motor_channels[i] = LEDC_CONFIG(i, pump_gpio_map[i]); | ||||
|     ledc_channel_config(&ledc_motor_channels[i]); | ||||
|   } | ||||
| 
 | ||||
|   ledc_cbs_t callbacks = { | ||||
|     .fade_cb = ledc_fade_end_event | ||||
|   }; | ||||
| 
 | ||||
|   ledc_fade_func_install(0); | ||||
| 
 | ||||
|   uint8_t *idx; | ||||
| 
 | ||||
|   for(uint8_t i = 0; i < PUMPS; i++) { | ||||
|     idx = malloc(1); | ||||
|     memcpy(idx, &i, 1); | ||||
|     ledc_cb_register(ledc_motor_channels[i].speed_mode, ledc_motor_channels[i].channel, &callbacks, idx); | ||||
|   } | ||||
| 
 | ||||
|   ESP_LOGI(TAG, "pumps_enabled: %d %d %d %d", pumps_enabled[0], pumps_enabled[1], pumps_enabled[2], pumps_enabled[3]); | ||||
|   ESP_LOGI(TAG, "pumps_duration: %d %d %d %d", pumps_duration[0], pumps_duration[1], pumps_duration[2], pumps_duration[3]); | ||||
| 
 | ||||
|   xTaskCreate(pump_step_task, "ramp", 4024, NULL, tskIDLE_PRIORITY + 4, NULL); | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
|  |  | |||
|  | @ -2,12 +2,14 @@ | |||
| #include "freertos/task.h" | ||||
| #include "freertos/queue.h" | ||||
| #include "driver/gpio.h" | ||||
| #include "esp_log.h" | ||||
| 
 | ||||
| #include "main.h" | ||||
| #include "pumps.h" | ||||
| #include "ble.h" | ||||
| 
 | ||||
| #define GPIO_USER_BUTTON      (19) | ||||
| #define TAG "user_btn" | ||||
| 
 | ||||
| static void IRAM_ATTR gpio_isr_handler(void* arg) { | ||||
|   uint32_t gpio_num = (uint32_t) arg; | ||||
|  | @ -27,7 +29,7 @@ static void gpio_task(void* arg) { | |||
|       if(level == last_level) continue; | ||||
|       last_level = level; | ||||
| 
 | ||||
|       printf("GPIO[%ld] intr, val: %d\n", io_num, level); | ||||
|       ESP_LOGI(TAG, "GPIO[%ld] intr, val: %d\n", io_num, level); | ||||
| 
 | ||||
|       if(state == 0) | ||||
|         vTaskDelay(10 / portTICK_PERIOD_MS); | ||||
|  | @ -42,6 +44,8 @@ static void gpio_task(void* arg) { | |||
| } | ||||
| 
 | ||||
| void user_button_init() { | ||||
|   ESP_LOGI(TAG, "user_button_init"); | ||||
| 
 | ||||
|   gpio_config_t io_conf; | ||||
| 
 | ||||
|   io_conf.intr_type = GPIO_INTR_ANYEDGE; | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue