First upload to repository

This commit is contained in:
2024-11-15 22:29:50 +01:00
parent 9252f8896b
commit 9bb6b8c99a
2620 changed files with 306264 additions and 0 deletions

3
main/CMakeLists.txt Normal file
View File

@@ -0,0 +1,3 @@
idf_component_register(SRCS "functions.c" "app_main.c"
INCLUDE_DIRS "include""${CMAKE_SOURCE_DIR}""."
REQUIRES ssd1306 driver esp_adc)

118
main/Kconfig.projbuild Normal file
View File

@@ -0,0 +1,118 @@
menu "DIY Power PCB Configuration"
orsource "$IDF_PATH/examples/common_components/env_caps/$IDF_TARGET/Kconfig.env_caps"
menu "ADC 1 configurations"
config U_SENSE_ADC
int "Voltage sensing ADC1 number"
default 5
help
ADC1 number of the Input-Voltage-Sensing pin
config I_SENSE_ADC
int "Current sensing ADC1 number"
default 7
help
ADC1 number of the Current-Sensing pin at the Shunt
config I_SENSE_U_V_W_ADC
string "Current sensing ADC1 numbers of U, V, W"
default "6, 3, 0"
help
ADC1 numbers of the current sensing pins at U,V and W. Write seperated by a comma. example:"34,29,36"
config TORQUE_ADC
int "Torque sensing ADC1 number"
default 4
help
GPIO numbers of the torque sensing pin"
endmenu
menu "Highside pin configurations (HIN)"
config HIN_U_V_W_GPIO
string "Highside GPIO pins (HIN U, V, W)"
default "26, 14, 13"
help
GPIO numbers of the Highside controling pins, seperate by comma!
config ENABLE_PWM_HIN
bool "Enable PWM for Highsides"
default y
help
Enable PWM on the Highside Switches, probably mendatory because of bootstrap capacitors
if ENABLE_PWM_HIN
config FREQ_PWM_HIN
int "frequency"
range 20000 60000
default 20000
help
The base Frequency of the PWM in Hz min: 20KHz max: 60KHz
config DUTY_PWM_HIN
int "duty cycle"
range 0 100
default 50
help
The inital duty-cycle
endif
endmenu
menu "Lowside pin configurations (LIN)"
config LIN_U_V_W_GPIO
string "Lowside GPIO pins (LIN U, V, W)"
default "25, 27, 12"
help
GPIO numbers of the Lowside controling pins, seperate by comma!
config ENABLE_PWM_LIN
bool "Enable PWM for Lowsides"
default n
help
Enable PWM on the Lowside Switches, probably not mendatory because of Highside PWM more important
if ENABLE_PWM_LIN
config FREQ_PWM_LIN
int "frequency"
range 20000 60000
default 20000
help
The base Frequency of the PWM in Hz min: 20KHz max: 60KHz
config DUTY_PWM_LIN
int "duty cycle"
range 0 100
default 50
help
The inital duty-cycle
endif
endmenu
menu "Hall Sensor pin configurations"
config HALL_A_B_C_GPIO
string "Hallsensor GPIO pins (A, B, C)"
default "4, 16, 17"
help
GPIO numbers of the pins connected to the Hallsensors, seperate by comma!
endmenu
menu "Input pin configurations"
config IN_ENCODER_GPIO
string "turning encoder(on board) GPIO pins: A, B, Button"
default "3, 2, 23"
help
GPIO numbers of the pins connected to A,B and the button of the encoder
config BUTTON_GPIO
int "button GPIO pin"
default 1
help
GPIO number of the pin connected to the button on the pcb
config EXT_ENCODER_GPIO
string "encoder(at motor) GPIO pins: Indx, Left, Right"
default "16, 18, 5"
help
GPIO numbers of the pins connected to the Logic connected to the encoder at the motor
config RFE_GPIO
int "RFE GPIO pin"
default 15
help
GPIO number of the pin connected to the RFE pin of the Bridge
endmenu
config BLINK_PERIOD
int "Blink period in ms"
range 10 3600000
default 1000
help
Define the blinking period in milliseconds.
endmenu

88
main/app_main.c Normal file
View File

@@ -0,0 +1,88 @@
/*
This is the first try of a Test-Software for the DIY Power PCB by Fabian Zaske
*/
#include "functions.h"
const char *TAG = "Main_test";
void app_main(void)
{
uint32_t Torque = 0;
uint32_t Voltage_IN = 0;
int32_t Current_U = 0;
int32_t Current_V = 0;
int32_t Current_W = 0;
char display_message[50]; // Puffer für die Nachricht
ESP_LOGI(TAG, "Test");
configure_GPIO_dir(TAG);
adc_oneshot_unit_handle_t adc1_handle = configure_ADC1(TAG);
//SSD1306_t *dev_pt = configure_OLED(TAG);
set_PWM_Timer();
set_PWM();
int i =0;
//gpio_set_level(CONFIG_HIN_V_GPIO, 1);
while (1) {
// ssd1306_clear_screen(dev_pt, false);
// Die Anzeige der OLED mit der richtigen Nachricht
Torque = get_torque(adc1_handle);
Voltage_IN = get_voltage_in(adc1_handle);
Current_U = get_current_ASC712(adc1_handle,CONFIG_I_SENSE_U_ADC);
Current_V = get_current_ASC712(adc1_handle,CONFIG_I_SENSE_U_ADC);
Current_W = get_current_ASC712(adc1_handle,CONFIG_I_SENSE_U_ADC);
if (Voltage_IN >= 20000){
//ssd1306_display_text(dev_pt, 1, "Bridge=ON", 10, false);
switch (i)
{
case 0:
V_U_start();
break;
case 1:
V_W_start();
break;
case 2:
U_W_start();
break;
case 3:
U_V_start();
break;
case 4:
W_V_start();
break;
case 5:
W_U_start();
i=0;
break;
default:
pwmStopAll();
break;
}
}else{
//ssd1306_display_text(dev_pt, 1, "Bridge=OFF", 10, false);
pwmStopAll();
}
snprintf(display_message, sizeof(display_message), "Torque: %lu", Torque);
// ssd1306_display_text(dev_pt, 2, display_message, 11, false);
snprintf(display_message, sizeof(display_message), "Voltage: %lu",Voltage_IN);
// ssd1306_display_text(dev_pt, 4, display_message, strlen(display_message), false);
snprintf(display_message, sizeof(display_message), "U: %ldmA",Current_U);
// ssd1306_display_text(dev_pt, 5, display_message, strlen(display_message), false);
snprintf(display_message, sizeof(display_message), "V: %ldmA",Current_V);
// ssd1306_display_text(dev_pt, 6, display_message, strlen(display_message), false);
snprintf(display_message, sizeof(display_message), "W: %ldmA",Current_W);
// ssd1306_display_text(dev_pt, 7, display_message, strlen(display_message), false);
//gpio_set_level(CONFIG_RFE_GPIO,0);
vTaskDelay(500 / portTICK_PERIOD_MS); // Verzögerung für die Task-Schleife
i++;
}
}

298
main/functions.c Normal file
View File

@@ -0,0 +1,298 @@
#include "functions.h"
adc_cali_handle_t cali_handle= NULL;
void configure_GPIO_dir(const char *TAG)
{
/* reset every used GPIO-pin */
gpio_reset_pin(CONFIG_HIN_U_GPIO);
gpio_reset_pin(CONFIG_HIN_V_GPIO);
gpio_reset_pin(CONFIG_HIN_W_GPIO);
gpio_reset_pin(CONFIG_LIN_U_GPIO);
gpio_reset_pin(CONFIG_LIN_V_GPIO);
gpio_reset_pin(CONFIG_LIN_W_GPIO);
gpio_reset_pin(CONFIG_HALL_A_GPIO);
gpio_reset_pin(CONFIG_HALL_B_GPIO);
gpio_reset_pin(CONFIG_HALL_C_GPIO);
//gpio_reset_pin(CONFIG_IN_ENC_A_GPIO);
gpio_reset_pin(CONFIG_IN_ENC_B_GPIO);
gpio_reset_pin(CONFIG_IN_ENC_BUT_GPIO);
//gpio_reset_pin(CONFIG_BUTTON_GPIO);
gpio_reset_pin(CONFIG_EXT_ENC_LEFT_GPIO);
gpio_reset_pin(CONFIG_EXT_ENC_RIGHT_GPIO);
gpio_reset_pin(CONFIG_RFE_GPIO);
/* Set the GPIO as a push/pull output */
gpio_set_direction(CONFIG_HIN_U_GPIO, GPIO_MODE_OUTPUT);
gpio_set_direction(CONFIG_HIN_V_GPIO, GPIO_MODE_OUTPUT);
gpio_set_direction(CONFIG_HIN_W_GPIO, GPIO_MODE_OUTPUT);
gpio_set_direction(CONFIG_LIN_U_GPIO, GPIO_MODE_OUTPUT);
gpio_set_direction(CONFIG_LIN_V_GPIO, GPIO_MODE_OUTPUT);
gpio_set_direction(CONFIG_LIN_W_GPIO, GPIO_MODE_OUTPUT);
gpio_set_direction(CONFIG_HALL_A_GPIO, GPIO_MODE_INPUT);
gpio_set_direction(CONFIG_HALL_B_GPIO, GPIO_MODE_INPUT);
gpio_set_direction(CONFIG_HALL_C_GPIO, GPIO_MODE_INPUT);
//gpio_set_direction(CONFIG_IN_ENC_A_GPIO, GPIO_MODE_INPUT);
gpio_set_direction(CONFIG_IN_ENC_B_GPIO, GPIO_MODE_INPUT);
gpio_set_direction(CONFIG_IN_ENC_BUT_GPIO, GPIO_MODE_INPUT);
//gpio_set_direction(CONFIG_BUTTON_GPIO, GPIO_MODE_INPUT);
gpio_set_direction(CONFIG_EXT_ENC_LEFT_GPIO, GPIO_MODE_INPUT);
gpio_set_direction(CONFIG_EXT_ENC_RIGHT_GPIO, GPIO_MODE_INPUT);
gpio_set_direction(CONFIG_RFE_GPIO, GPIO_MODE_OUTPUT);
ESP_LOGI(TAG, "GPIO dirs configured for DIY power PCB");
}
// Globale Variable für die Kalibrierung
adc_oneshot_unit_handle_t configure_ADC1()
{
adc_oneshot_unit_handle_t adc1_handle;
// ADC1 Initialisierung
adc_oneshot_unit_init_cfg_t init_config = {
.unit_id = ADC_UNIT_1,
.ulp_mode = ADC_ULP_MODE_DISABLE,
};
ESP_ERROR_CHECK(adc_oneshot_new_unit(&init_config, &adc1_handle));
// Kanal-Konfiguration
adc_oneshot_chan_cfg_t config = {
.bitwidth = ADC_BITWIDTH_DEFAULT,
.atten = ADC_ATTEN_DB_12,
};
ESP_ERROR_CHECK(adc_oneshot_config_channel(adc1_handle, CONFIG_TORQUE_ADC, &config));
ESP_ERROR_CHECK(adc_oneshot_config_channel(adc1_handle, CONFIG_U_SENSE_ADC, &config));
ESP_ERROR_CHECK(adc_oneshot_config_channel(adc1_handle, CONFIG_I_SENSE_U_ADC, &config));
ESP_ERROR_CHECK(adc_oneshot_config_channel(adc1_handle, CONFIG_I_SENSE_V_ADC, &config));
ESP_ERROR_CHECK(adc_oneshot_config_channel(adc1_handle, CONFIG_I_SENSE_W_ADC, &config));
// Kalibrierung initialisieren
adc_cali_line_fitting_config_t cali_config = {
.atten = ADC_ATTEN_DB_12,
.bitwidth = ADC_BITWIDTH_DEFAULT,
};
esp_err_t ret = adc_cali_create_scheme_line_fitting(&cali_config, &cali_handle);
if (ret == ESP_OK) {
ESP_LOGI("ADC", "ADC-Kalibrierung erfolgreich initialisiert");
} else {
ESP_LOGW("ADC", "ADC-Kalibrierung nicht möglich, Rohwerte werden verwendet");
cali_handle = NULL; // Keine Kalibrierung verfügbar
}
return adc1_handle;
}
uint32_t read_voltage(adc_oneshot_unit_handle_t adc1_handle, int channel) {
int adc_raw = 0;
int voltage_calibrated = 0; // Verwende int für die Kalibrierungsfunktion
uint32_t voltage = 0; // Konvertiere später zu uint32_t
// ADC-Rohwert lesen
ESP_ERROR_CHECK(adc_oneshot_read(adc1_handle, channel, &adc_raw));
// Kalibrierung anwenden, falls verfügbar
if (cali_handle) {
ESP_ERROR_CHECK(adc_cali_raw_to_voltage(cali_handle, adc_raw, &voltage_calibrated));
voltage = (uint32_t) voltage_calibrated; // Konvertiere zu uint32_t
} else {
voltage = adc_raw; // Fallback auf Rohwert
}
return voltage;
}
// Funktion zur Umrechnung in spezifische Spannung
uint32_t get_voltage_in(adc_oneshot_unit_handle_t adc1_handle)
{
uint32_t adc_voltage = read_voltage(adc1_handle, CONFIG_U_SENSE_ADC);
ESP_LOGI("ADC", "ADC%d:voltage:%ld", CONFIG_U_SENSE_ADC, adc_voltage);
// Beispielhafte Umrechnung; Wert an eigene Anwendung anpassen
uint32_t voltage_in = adc_voltage / 0.0909;
return voltage_in;
}
int32_t get_current_ASC712(adc_oneshot_unit_handle_t adc1_handle, int ADC_pin)
{
int32_t adc_voltage = read_voltage(adc1_handle,ADC_pin);
int32_t current = (adc_voltage -2500)*5.405;
ESP_LOGI("ADC", "ADC%d:voltage:%ldcurrent%ld", ADC_pin, adc_voltage, current);
return current;
}
uint32_t get_torque(adc_oneshot_unit_handle_t adc1_handle)
{
uint32_t adc_voltage =read_voltage(adc1_handle,CONFIG_TORQUE_ADC);
uint32_t torque = adc_voltage/33;
return torque;
}
SSD1306_t *configure_OLED(const char *TAG)
{
static SSD1306_t dev;
//int center, top, bottom;
//char lineChar[20];
i2c_master_init(&dev, CONFIG_SDA_GPIO, CONFIG_SCL_GPIO, CONFIG_RESET_GPIO);
ESP_LOGI(TAG, "Panel is 128x64");
ssd1306_init(&dev, 128, 64);
ssd1306_clear_screen(&dev, false);
ssd1306_contrast(&dev, 0xff);
ssd1306_display_text_x3(&dev, 0, "Hello", 5, false);
vTaskDelay(2000 / portTICK_PERIOD_MS);
ssd1306_clear_screen(&dev, false);
return &dev;
}
void set_PWM_Timer()
{
ledc_timer_config_t ledc_timer = {
.speed_mode = LEDC_HIGH_SPEED_MODE,
.timer_num = LEDC_TIMER_0,
.duty_resolution = LEDC_TIMER_10_BIT,
.freq_hz = CONFIG_FREQ_PWM_HIN,
.clk_cfg = LEDC_AUTO_CLK
};
esp_err_t err = ledc_timer_config(&ledc_timer);
if (err != ESP_OK) {
printf("Fehler beim Konfigurieren des LEDC-Timers: %s\n", esp_err_to_name(err));
return;
}
}
void set_PWM()
{
ledc_channel_config_t ledc_channel_HIN_U =
{
.speed_mode = LEDC_HIGH_SPEED_MODE, // Gleicher Modus wie beim Timer
.channel = LEDC_CHANNEL_0, // Kanal 0 verwenden
.timer_sel = LEDC_TIMER_0, // Timer 0 zuweisen
.intr_type = LEDC_INTR_DISABLE, // Keine Interrupts
.gpio_num = CONFIG_HIN_U_GPIO,
.duty = 0, //
.hpoint = 0 // Start des PWM-Signals
};
ledc_channel_config(&ledc_channel_HIN_U); // Kanal konfigurieren
ledc_channel_config_t ledc_channel_HIN_V =
{
.speed_mode = LEDC_HIGH_SPEED_MODE, // Gleicher Modus wie beim Timer
.channel = LEDC_CHANNEL_1, // Kanal 0 verwenden
.timer_sel = LEDC_TIMER_0, // Timer 0 zuweisen
.intr_type = LEDC_INTR_DISABLE, // Keine Interrupts
.gpio_num = CONFIG_HIN_V_GPIO,
.duty = 0, //
.hpoint = 0 // Start des PWM-Signals
};
ledc_channel_config(&ledc_channel_HIN_V); // Kanal konfigurieren
ledc_channel_config_t ledc_channel_HIN_W =
{
.speed_mode = LEDC_HIGH_SPEED_MODE, // Gleicher Modus wie beim Timer
.channel = LEDC_CHANNEL_2, // Kanal 0 verwenden
.timer_sel = LEDC_TIMER_0, // Timer 0 zuweisen
.intr_type = LEDC_INTR_DISABLE, // Keine Interrupts
.gpio_num = CONFIG_HIN_W_GPIO,
.duty = 0, //
.hpoint = 0 // Start des PWM-Signals
};
ledc_channel_config(&ledc_channel_HIN_W); // Kanal konfigurieren
}
void pwmStart(int PWM_CH, int Duty){
ledc_set_duty(LEDC_HIGH_SPEED_MODE,PWM_CH, Duty);
ledc_update_duty(LEDC_HIGH_SPEED_MODE,PWM_CH);
}
void pwmStop(int PWM_CH){
ledc_stop(LEDC_HIGH_SPEED_MODE, PWM_CH, 0);
}
void pwmStopAll(){
ledc_stop(LEDC_HIGH_SPEED_MODE, HIN_U_CH, 0);
ledc_stop(LEDC_HIGH_SPEED_MODE, HIN_V_CH, 0);
ledc_stop(LEDC_HIGH_SPEED_MODE, HIN_W_CH, 0);
gpio_set_level(CONFIG_LIN_U_GPIO, 0);
gpio_set_level(CONFIG_LIN_V_GPIO, 0);
gpio_set_level(CONFIG_LIN_W_GPIO, 0);
}
void U_V_start()
{
//HIN_V und LIN_U abschalten
pwmStop(HIN_V_CH);
gpio_set_level(CONFIG_LIN_U_GPIO, 0);
//HIN_U und LIN_V einschalten
pwmStart(HIN_U_CH, 512);
gpio_set_level(CONFIG_LIN_V_GPIO, 1);
}
void V_U_start()
{
//HIN_U und LIN_V abschalten
pwmStop(HIN_U_CH);
gpio_set_level(CONFIG_LIN_V_GPIO, 0);
//HIN_V und LIN_U einschalten
pwmStart(HIN_V_CH, 512);
gpio_set_level(CONFIG_LIN_U_GPIO, 1);
}
void U_W_start()
{
//HIN_W und LIN_U abschalten
pwmStop(HIN_W_CH);
gpio_set_level(CONFIG_LIN_U_GPIO, 0);
//HIN_U und LIN_V einschalten
pwmStart(HIN_W_CH, 512);
gpio_set_level(CONFIG_LIN_V_GPIO, 1);
}
void W_U_start()
{
//HIN_U und LIN_W abschalten
pwmStop(HIN_U_CH);
gpio_set_level(CONFIG_LIN_W_GPIO, 0);
//HIN_U und LIN_V einschalten
pwmStart(HIN_W_CH, 512);
gpio_set_level(CONFIG_LIN_U_GPIO, 1);
}
void V_W_start()
{
//HIN_U und LIN_W abschalten
pwmStop(HIN_W_CH);
gpio_set_level(CONFIG_LIN_V_GPIO, 0);
//HIN_U und LIN_V einschalten
pwmStart(HIN_V_CH, 512);
gpio_set_level(CONFIG_LIN_W_GPIO, 1);
}
void W_V_start()
{
//HIN_U und LIN_W abschalten
pwmStop(HIN_V_CH);
gpio_set_level(CONFIG_LIN_W_GPIO, 0);
//HIN_U und LIN_V einschalten
pwmStart(HIN_W_CH, 512);
gpio_set_level(CONFIG_LIN_V_GPIO, 1);
}
//Ausgelagert in Preprocessing python program, generate_pins_header.py
void parse_3pins(const char *TAG, const char *pin_string, int *pins) {
int pin_count = 0; // Jetzt ein Integer, keine Null-Pointer-Dereferenzierung
char *token;
char *pin_list = strdup(pin_string); // Kopie der String-Option
token = strtok(pin_list, ",");
while (token != NULL && pin_count < 3) { // maximal 3 Pins
pins[pin_count] = atoi(token); // Umwandlung in Integer
pin_count++;
token = strtok(NULL, ",");
}
free(pin_list); // Speicher freigeben
}

3
main/idf_component.yml Normal file
View File

@@ -0,0 +1,3 @@
# idf_component.yml ohne dependencies
target: esp32
version: "1.0.0"

45
main/include/functions.h Normal file
View File

@@ -0,0 +1,45 @@
// functions.h
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "sdkconfig.h"
#include "driver/ledc.h"
#include <string.h>
#include <stdlib.h>
#include "parsed_pins.h"
#include "esp_adc/adc_cali.h"
#include "esp_adc/adc_cali_scheme.h"
#include "ssd1306.h"
#include "esp_adc/adc_oneshot.h"
#define HIN_U_CH 0
#define HIN_V_CH 1
#define HIN_W_CH 2
#ifndef MY_COMPONENT_H
#define MY_COMPONENT_H
extern adc_cali_handle_t cali_handle;
// Deklaration der Funktion, die in my_component.c implementiert ist
void configure_GPIO_dir(const char *TAG);
adc_oneshot_unit_handle_t configure_ADC1();
uint32_t read_voltage(adc_oneshot_unit_handle_t adc1_handle, int channel);
uint32_t get_voltage_in(adc_oneshot_unit_handle_t adc1_handle);
uint32_t get_torque(adc_oneshot_unit_handle_t adc1_handle);
int32_t get_current_ASC712(adc_oneshot_unit_handle_t adc1_handle, int ADC_pin);
void set_PWM_Timer();
void set_PWM();
void pwmStart(int PWM_CH,int Duty);
void pwmStop(int PWM_CH);
void pwmStopAll();
void U_V_start();
void V_U_start();
void U_W_start();
void W_U_start();
void V_W_start();
void W_V_start();
void parse_3pins(const char *TAG, const char *pin_string, int *pins);
SSD1306_t *configure_OLED(const char *TAG);
#endif // MY_COMPONENT_H