diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 730663e..971f746 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -1,6 +1,6 @@ -# The following lines of boilerplate have to be in your project's -# CMakeLists in this exact order for cmake to work correctly -cmake_minimum_required(VERSION 3.5) - -include($ENV{IDF_PATH}/tools/cmake/project.cmake) +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(e28-cluster) \ No newline at end of file diff --git a/code/Makefile b/code/Makefile index 509705c..ced6ee2 100644 --- a/code/Makefile +++ b/code/Makefile @@ -1,9 +1,9 @@ -# -# This is a project Makefile. It is assumed the directory this Makefile resides in is a -# project subdirectory. -# - -PROJECT_NAME := e28-cluster - -include $(IDF_PATH)/make/project.mk - +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := e28-cluster + +include $(IDF_PATH)/make/project.mk + diff --git a/code/main/CMakeLists.txt b/code/main/CMakeLists.txt index f838e47..271d752 100644 --- a/code/main/CMakeLists.txt +++ b/code/main/CMakeLists.txt @@ -1,5 +1,6 @@ -idf_component_register(SRCS "main.c" - "fuel_gauge.c" - "temp_gauge.c" - "speedometer_gauge.c" - INCLUDE_DIRS ".") +idf_component_register(SRCS "main.c" + "fuel_gauge.c" + "temp_gauge.c" + "speedometer_gauge.c" + "tachometer_gauge.c" + INCLUDE_DIRS ".") diff --git a/code/main/component.mk b/code/main/component.mk index 0b9d758..dfe125b 100644 --- a/code/main/component.mk +++ b/code/main/component.mk @@ -1,5 +1,5 @@ -# -# "main" pseudo-component makefile. -# -# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) - +# +# "main" pseudo-component makefile. +# +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) + diff --git a/code/main/fuel_gauge.c b/code/main/fuel_gauge.c index a709d62..95f2ea3 100644 --- a/code/main/fuel_gauge.c +++ b/code/main/fuel_gauge.c @@ -1,80 +1,80 @@ -#include "esp_err.h" -#include "esp_log.h" - -#include -#include - -static dac_channel_t fuel_gauge_channel = -1; -static gpio_num_t low_fuel_indicator_pin = -1; - -/** - * Setup the temperature gauge output. - * - * @param gauge dac output pin - * @param low_fuel_indicator output pin - */ -void setup_fuel_gauge(dac_channel_t gauge, gpio_num_t low_fuel_indicator) { - if(gauge != -1) { - esp_err_t error = dac_output_enable(gauge); - if(error == ESP_OK) { - fuel_gauge_channel = gauge; - } - } - - if(low_fuel_indicator != -1 && - ( - low_fuel_indicator < GPIO_NUM_34 || // pins 34 - 39 on esp32 are - low_fuel_indicator > GPIO_NUM_39 // input only - )) { - gpio_config_t config = { - .pin_bit_mask = low_fuel_indicator, - .mode = GPIO_MODE_OUTPUT, - .pull_up_en = GPIO_PULLUP_DISABLE, - .pull_down_en = GPIO_PULLDOWN_ENABLE, - .intr_type = GPIO_INTR_DISABLE - }; - esp_err_t error = gpio_config(&config); - if(error == ESP_OK) { - low_fuel_indicator_pin = low_fuel_indicator; - } - - } -} - -/** - * Set the position of the fuel gauge in terms of % full - * - * @param percent_full for the gauge to point to - */ -void write_to_fuel_gauge(int percent_full) { - if(fuel_gauge_channel == -1) { - ESP_LOGE("write_to_fuel_gauge", "Fuel gauge not yet initialized, please call setup_fuel_gauge first."); - } else { - int voltage = 70 + ((percent_full * 80) / 100); - voltage &= 255; - ESP_LOGI("FUEL VOLTAGE", "[V: %d, F: %d]", voltage, percent_full); - dac_output_voltage(fuel_gauge_channel, voltage); - } -} - -/** - * Turns the low fuel indicator light on if it's hooked up. - */ -void enable_low_fuel_indicator() { - if(low_fuel_indicator_pin == -1) { - ESP_LOGE("enable_low_fuel_indicator", "low fuel indicator not yet initialized, please call setup_fuel_gauge first."); - } else { - gpio_set_level(low_fuel_indicator_pin, 1); - } -} - -/** - * Turns the low fuel indicator light off if it's hooked up. - */ -void disable_low_fuel_indicator() { - if(low_fuel_indicator_pin == -1) { - ESP_LOGE("enable_low_fuel_indicator", "low fuel indicator not yet initialized, please call setup_fuel_gauge first."); - } else { - gpio_set_level(low_fuel_indicator_pin, 0); - } +#include "esp_err.h" +#include "esp_log.h" + +#include +#include + +static dac_channel_t fuel_gauge_channel = -1; +static gpio_num_t low_fuel_indicator_pin = -1; + +/** + * Setup the temperature gauge output. + * + * @param gauge dac output pin + * @param low_fuel_indicator output pin + */ +void setup_fuel_gauge(dac_channel_t gauge, gpio_num_t low_fuel_indicator) { + if(gauge != -1) { + esp_err_t error = dac_output_enable(gauge); + if(error == ESP_OK) { + fuel_gauge_channel = gauge; + } + } + + if(low_fuel_indicator != -1 && + ( + low_fuel_indicator < GPIO_NUM_34 || // pins 34 - 39 on esp32 are + low_fuel_indicator > GPIO_NUM_39 // input only + )) { + gpio_config_t config = { + .pin_bit_mask = low_fuel_indicator, + .mode = GPIO_MODE_OUTPUT, + .pull_up_en = GPIO_PULLUP_DISABLE, + .pull_down_en = GPIO_PULLDOWN_ENABLE, + .intr_type = GPIO_INTR_DISABLE + }; + esp_err_t error = gpio_config(&config); + if(error == ESP_OK) { + low_fuel_indicator_pin = low_fuel_indicator; + } + + } +} + +/** + * Set the position of the fuel gauge in terms of % full + * + * @param percent_full for the gauge to point to + */ +void write_to_fuel_gauge(int percent_full) { + if(fuel_gauge_channel == -1) { + ESP_LOGE("write_to_fuel_gauge", "Fuel gauge not yet initialized, please call setup_fuel_gauge first."); + } else { + int voltage = 70 + ((percent_full * 80) / 100); + voltage &= 255; + ESP_LOGI("FUEL VOLTAGE", "[V: %d, F: %d]", voltage, percent_full); + dac_output_voltage(fuel_gauge_channel, voltage); + } +} + +/** + * Turns the low fuel indicator light on if it's hooked up. + */ +void enable_low_fuel_indicator() { + if(low_fuel_indicator_pin == -1) { + ESP_LOGE("enable_low_fuel_indicator", "low fuel indicator not yet initialized, please call setup_fuel_gauge first."); + } else { + gpio_set_level(low_fuel_indicator_pin, 1); + } +} + +/** + * Turns the low fuel indicator light off if it's hooked up. + */ +void disable_low_fuel_indicator() { + if(low_fuel_indicator_pin == -1) { + ESP_LOGE("enable_low_fuel_indicator", "low fuel indicator not yet initialized, please call setup_fuel_gauge first."); + } else { + gpio_set_level(low_fuel_indicator_pin, 0); + } } \ No newline at end of file diff --git a/code/main/main.c b/code/main/main.c index 21e1d21..b53d93f 100644 --- a/code/main/main.c +++ b/code/main/main.c @@ -1,128 +1,134 @@ -/* Hello World Example - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "fuel_gauge.c" -#include "temp_gauge.c" -#include "speedometer_gauge.c" - -/* --------------------- Definitions and static variables ------------------ */ -//Example Configuration -#define NO_OF_ITERS 3 -#define RX_TASK_PRIO 9 -#define TX_GPIO_NUM 21 -#define RX_GPIO_NUM 22 -#define EXAMPLE_TAG "CAN Listen Only" - -#define ID_ENGINE_SPEED_TEMP 0x35B -#define ID_VEHICLE_SPEED 0x29B - -#define GPIO_OUTPUT_IO_0 18 - -static const can_filter_config_t can_filter_config = CAN_FILTER_CONFIG_ACCEPT_ALL(); -static const can_timing_config_t can_timing_config = CAN_TIMING_CONFIG_500KBITS(); -//Set TX queue length to 0 due to listen only mode -static const can_general_config_t can_general_config = {.mode = CAN_MODE_NORMAL, - .tx_io = TX_GPIO_NUM, .rx_io = RX_GPIO_NUM, - .clkout_io = CAN_IO_UNUSED, .bus_off_io = CAN_IO_UNUSED, - .tx_queue_len = 10, .rx_queue_len = 10, - .alerts_enabled = CAN_ALERT_NONE, - .clkout_divider = 0}; - -static void can_configure() { - //Install and start CAN driver - ESP_ERROR_CHECK(can_driver_install(&can_general_config, &can_timing_config, &can_filter_config)); - ESP_LOGI(EXAMPLE_TAG, "Driver installed"); - ESP_ERROR_CHECK(can_start()); - ESP_LOGI(EXAMPLE_TAG, "Driver started"); -} - -static void output_configure() { - setup_temp_gauge(DAC_CHANNEL_1); - setup_fuel_gauge(DAC_CHANNEL_2, -1); -} - - -static void can_receive_task(void *arg) { - - while(true) { - can_message_t rx_msg; - can_receive(&rx_msg, portMAX_DELAY); - ESP_LOGI("CAN_MSG", "ID: %2x", rx_msg.identifier); - if (rx_msg.identifier == ID_ENGINE_SPEED_TEMP) { - //int rpm = ((rx_msg.data[0] / 255) * 100) + ((rx_msg.data[1] / 16) * 1000); - ESP_LOGI("CAN_0x35B", "[%2x, %2x, %2x, %2x, %2x, %2x, %2x, %2x]", - rx_msg.data[7], rx_msg.data[6], rx_msg.data[5], rx_msg.data[4], - rx_msg.data[3], rx_msg.data[2], rx_msg.data[1], rx_msg.data[0]); - write_to_fuel_gauge(rx_msg.data[0]); - write_to_temp_gauge(rx_msg.data[2]); - } - - if (rx_msg.identifier == ID_VEHICLE_SPEED) { - ESP_LOGI("CAN_0x29B", "[%2x, %2x, %2x, %2x, %2x, %2x, %2x, %2x]", - rx_msg.data[7], rx_msg.data[6], rx_msg.data[5], rx_msg.data[4], - rx_msg.data[3], rx_msg.data[2], rx_msg.data[1], rx_msg.data[0]); - ESP_LOGI(EXAMPLE_TAG, "Received slave ping response"); - } - - vTaskDelay(pdMS_TO_TICKS(100)); - } - -} - -void app_main(void) -{ - printf("Hello world!\n"); - - /* Print chip information */ - esp_chip_info_t chip_info; - esp_chip_info(&chip_info); - printf("This is ESP32 chip with %d CPU cores, WiFi%s%s, ", - chip_info.cores, - (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "", - (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : ""); - - printf("silicon revision %d, ", chip_info.revision); - - printf("%dMB %s flash\n", spi_flash_get_chip_size() / (1024 * 1024), - (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external"); - - can_configure(); - output_configure(); - - setup_speedometer_gauge(GPIO_NUM_4); - - - xTaskCreate(can_receive_task, "CAN_rx", 4096, NULL, RX_TASK_PRIO, NULL); - - - write_to_speedometer(3); - - - for (uint32_t i = 120; i >= 1; i--) { - printf("Restarting in %d seconds...\n", i); - vTaskDelay(1000 / portTICK_PERIOD_MS); - - write_to_speedometer(i); - } - printf("Restarting now.\n"); - fflush(stdout); - esp_restart(); -} +/* Hello World Example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fuel_gauge.c" +#include "temp_gauge.c" +#include "speedometer_gauge.c" +#include "tachometer_gauge.c" + +/* --------------------- Definitions and static variables ------------------ */ +//Example Configuration +#define NO_OF_ITERS 3 +#define RX_TASK_PRIO 9 +#define TX_GPIO_NUM 21 +#define RX_GPIO_NUM 22 +#define EXAMPLE_TAG "CAN Listen Only" + +#define ID_ENGINE_SPEED_TEMP 0x35B +#define ID_VEHICLE_SPEED 0x29B + +#define GPIO_OUTPUT_IO_0 18 + +static const can_filter_config_t can_filter_config = CAN_FILTER_CONFIG_ACCEPT_ALL(); +static const can_timing_config_t can_timing_config = CAN_TIMING_CONFIG_500KBITS(); +//Set TX queue length to 0 due to listen only mode +static const can_general_config_t can_general_config = {.mode = CAN_MODE_NORMAL, + .tx_io = TX_GPIO_NUM, .rx_io = RX_GPIO_NUM, + .clkout_io = CAN_IO_UNUSED, .bus_off_io = CAN_IO_UNUSED, + .tx_queue_len = 10, .rx_queue_len = 10, + .alerts_enabled = CAN_ALERT_NONE, + .clkout_divider = 0}; + +static void can_configure() { + //Install and start CAN driver + ESP_ERROR_CHECK(can_driver_install(&can_general_config, &can_timing_config, &can_filter_config)); + ESP_LOGI(EXAMPLE_TAG, "Driver installed"); + ESP_ERROR_CHECK(can_start()); + ESP_LOGI(EXAMPLE_TAG, "Driver started"); +} + +static void output_configure() { + setup_temp_gauge(DAC_CHANNEL_1); + setup_fuel_gauge(DAC_CHANNEL_2, -1); +} + + +static void can_receive_task(void *arg) { + + while(true) { + can_message_t rx_msg; + can_receive(&rx_msg, portMAX_DELAY); + ESP_LOGI("CAN_MSG", "ID: %2x", rx_msg.identifier); + if (rx_msg.identifier == ID_ENGINE_SPEED_TEMP) { + //int rpm = ((rx_msg.data[0] / 255) * 100) + ((rx_msg.data[1] / 16) * 1000); + ESP_LOGI("CAN_0x35B", "[%2x, %2x, %2x, %2x, %2x, %2x, %2x, %2x]", + rx_msg.data[7], rx_msg.data[6], rx_msg.data[5], rx_msg.data[4], + rx_msg.data[3], rx_msg.data[2], rx_msg.data[1], rx_msg.data[0]); + write_to_fuel_gauge(rx_msg.data[0]); + write_to_temp_gauge(rx_msg.data[2]); + } + + if (rx_msg.identifier == ID_VEHICLE_SPEED) { + ESP_LOGI("CAN_0x29B", "[%2x, %2x, %2x, %2x, %2x, %2x, %2x, %2x]", + rx_msg.data[7], rx_msg.data[6], rx_msg.data[5], rx_msg.data[4], + rx_msg.data[3], rx_msg.data[2], rx_msg.data[1], rx_msg.data[0]); + ESP_LOGI(EXAMPLE_TAG, "Received slave ping response"); + } + + vTaskDelay(pdMS_TO_TICKS(100)); + } + +} + +void app_main(void) +{ + printf("Hello world!\n"); + + /* Print chip information */ + esp_chip_info_t chip_info; + esp_chip_info(&chip_info); + printf("This is ESP32 chip with %d CPU cores, WiFi%s%s, ", + chip_info.cores, + (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "", + (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : ""); + + printf("silicon revision %d, ", chip_info.revision); + + printf("%dMB %s flash\n", spi_flash_get_chip_size() / (1024 * 1024), + (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external"); + + can_configure(); + + output_configure(); + setup_speedometer_gauge(GPIO_NUM_4); + setup_tachometer_gauge(GPIO_NUM_5); + + + xTaskCreate(can_receive_task, "CAN_rx", 4096, NULL, RX_TASK_PRIO, NULL); + + + write_to_speedometer(3); + + + for (uint32_t i = 120; i >= 1; i--) { + printf("Restarting in %d seconds...\n", i); + vTaskDelay(1000 / portTICK_PERIOD_MS); + + write_to_fuel_gauge(i % 100); + write_to_temp_gauge(i + 100); + + write_to_speedometer(i); + write_to_tachometer(i << 4); + } + printf("Restarting now.\n"); + fflush(stdout); + esp_restart(); +} diff --git a/code/main/speedometer_gauge.c b/code/main/speedometer_gauge.c index 88bb1f0..761029c 100644 --- a/code/main/speedometer_gauge.c +++ b/code/main/speedometer_gauge.c @@ -6,9 +6,9 @@ #include #include -#define LEDC_LS_TIMER LEDC_TIMER_1 -#define LEDC_LS_MODE LEDC_LOW_SPEED_MODE -#define LEDC_LS_CH2_CHANNEL LEDC_CHANNEL_2 +#define SPEEDO_LS_TIMER LEDC_TIMER_1 +#define SPEEDO_LS_MODE LEDC_LOW_SPEED_MODE +#define SPEEDO_LS_CH1_CHANNEL LEDC_CHANNEL_1 /* * Prepare and set configuration of timers @@ -17,25 +17,25 @@ ledc_timer_config_t speedometer_timer_config = { .duty_resolution = LEDC_TIMER_10_BIT, // resolution of PWM duty .freq_hz = 2, // frequency of PWM signal - .speed_mode = LEDC_LS_MODE, // timer mode - .timer_num = LEDC_LS_TIMER, // timer index + .speed_mode = SPEEDO_LS_MODE, // timer mode + .timer_num = SPEEDO_LS_TIMER, // timer index .clk_cfg = LEDC_AUTO_CLK, // Auto select the source clock }; -ledc_channel_config_t ledc_channel = { - .channel = LEDC_LS_CH2_CHANNEL, +ledc_channel_config_t speedo_channel = { + .channel = SPEEDO_LS_CH1_CHANNEL, .duty = 0, .gpio_num = -1, - .speed_mode = LEDC_LS_MODE, + .speed_mode = SPEEDO_LS_MODE, .hpoint = 0, - .timer_sel = LEDC_LS_TIMER + .timer_sel = SPEEDO_LS_TIMER }; void setup_speedometer_gauge(gpio_num_t guage_output_pin) { - ledc_channel.gpio_num = guage_output_pin; + speedo_channel.gpio_num = guage_output_pin; ledc_timer_config(&speedometer_timer_config); - ledc_channel_config(&ledc_channel); + ledc_channel_config(&speedo_channel); } /** @@ -44,12 +44,12 @@ void setup_speedometer_gauge(gpio_num_t guage_output_pin) { void write_to_speedometer(uint32_t speed) { ESP_LOGI("write_to_speedometer", "[%d mph]", speed); if(speed == 0) { - ledc_set_duty(LEDC_LS_MODE, ledc_channel.channel, 0); - ledc_update_duty(LEDC_LS_MODE, ledc_channel.channel); + ledc_set_duty(SPEEDO_LS_MODE, speedo_channel.channel, 0); + ledc_update_duty(SPEEDO_LS_MODE, speedo_channel.channel); } else { - ledc_set_duty(LEDC_LS_MODE, ledc_channel.channel, 512); - ledc_update_duty(LEDC_LS_MODE, ledc_channel.channel); - esp_err_t error = ledc_set_freq(LEDC_LS_MODE, LEDC_LS_TIMER, speed << 1); + ledc_set_duty(SPEEDO_LS_MODE, speedo_channel.channel, 512); + ledc_update_duty(SPEEDO_LS_MODE, speedo_channel.channel); + esp_err_t error = ledc_set_freq(SPEEDO_LS_MODE, SPEEDO_LS_TIMER, speed << 1); if(error != ESP_OK) { ESP_LOGE("write_to_speedometer", "Error setting speed to: [%d mph]", speed); diff --git a/code/main/tachometer_gauge.c b/code/main/tachometer_gauge.c new file mode 100644 index 0000000..17bf817 --- /dev/null +++ b/code/main/tachometer_gauge.c @@ -0,0 +1,58 @@ +#include "esp_err.h" +#include "esp_log.h" + +#include +#include +#include +#include + +#define TACH_LS_TIMER LEDC_TIMER_2 +#define TACH_LS_MODE LEDC_LOW_SPEED_MODE +#define TACH_LS_CH2_CHANNEL LEDC_CHANNEL_2 + +/* + * Prepare and set configuration of timers + * that will be used by LED Controller + */ +ledc_timer_config_t tachometer_timer_config = { + .duty_resolution = LEDC_TIMER_10_BIT, // resolution of PWM duty + .freq_hz = 1, // frequency of PWM signal + .speed_mode = TACH_LS_MODE, // timer mode + .timer_num = TACH_LS_TIMER, // timer index + .clk_cfg = LEDC_AUTO_CLK, // Auto select the source clock +}; + +ledc_channel_config_t tachometer_ledc_channel = { + .channel = TACH_LS_CH2_CHANNEL, + .duty = 0, + .gpio_num = -1, + .speed_mode = TACH_LS_MODE, + .hpoint = 0, + .timer_sel = TACH_LS_TIMER + }; + +void setup_tachometer_gauge(gpio_num_t guage_output_pin) { + tachometer_ledc_channel.gpio_num = guage_output_pin; + + ledc_timer_config(&tachometer_timer_config); + ledc_channel_config(&tachometer_ledc_channel); +} + +/** + * Write to the tachometer in MPH + */ +void write_to_tachometer(uint32_t rpm) { + ESP_LOGI("write_to_tachometer", "[%d mph]", rpm); + if(rpm == 0) { + ledc_set_duty(TACH_LS_MODE, tachometer_ledc_channel.channel, 0); + ledc_update_duty(TACH_LS_MODE, tachometer_ledc_channel.channel); + } else { + ledc_set_duty(TACH_LS_MODE, tachometer_ledc_channel.channel, 512); + ledc_update_duty(TACH_LS_MODE, tachometer_ledc_channel.channel); + esp_err_t error = ledc_set_freq(TACH_LS_MODE, TACH_LS_TIMER, rpm >> 4); + + if(error != ESP_OK) { + ESP_LOGE("write_to_tachometer", "Error setting rpm to: [%d rpm]", rpm); + } + } +} \ No newline at end of file