Elektronische_Last/Source/ElektronischeLast.cpp

147 lines
3.8 KiB
C++

/*
* ElektronischeLast.cpp
*
* Created on: Jun 23, 2023
* Author: Carst
*/
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cinttypes>
#include <stm32g0xx.h>
#include "STM32G071KBT6.hpp"
#include "LED.hpp"
#include "DAC.hpp"
#include "ADC.hpp"
#include "serial.hpp"
#include "PID.h"
#include "FanControl.hpp"
#include "CLI.h"
using namespace ElektronischeLast;
uint16_t set_solltrom (CLI_OutFunction pfvOutFunction, char *acCommands[], uint16_t u16ArgCount);
uint16_t set_dutyCyle (CLI_OutFunction pfvOutFunction, char *acCommands[], uint16_t u16ArgCount);
uint16_t ist_werte(CLI_OutFunction pfvOutFunction, char *acCommands[], uint16_t u16ArgCount);
static CLI_Command_t commands[] =
{
{ "isoll", "Zielstrom für Last", set_solltrom },
{ "ist", "Zeige Istwerte an [-r für wiederholende Anzeige]", ist_werte },
{ "fan", "Setze Tastverhältnis für Lüfter", set_dutyCyle },
};
static std::uint32_t i_soll = 0U;
static PIDController pid =
{
.Kp = 0.75f,
.Ki = 10.0f,
.Kd = 0.0f,
.limMin = 0.0f,
.limMax = 4095.0f,
.limMinInt = 0.0f,
.limMaxInt = 2048.0f,
.T = 0.001f,
};
static uint32_t dac_value;
static uint32_t strom;
static uint32_t spannung;
static uint32_t temperatur;
int main (void)
{
__enable_irq();
serial_init();
CLI_Init(commands, sizeof(commands)/sizeof(commands[0]));
LED led = LED(500U);
iDAC dac = iDAC();
iADC adc = iADC();
FanControl fan = FanControl();
std::uint32_t last_tick = systick;
printf("\r\nElektronische Last\r\n");
printf("- Initialisierung erfolgreich\r\n");
PIDController_Init(&pid);
while(1)
{
led.blink();
if(last_tick != systick)
{
last_tick = systick;
dac_value = (uint32_t)PIDController_Update(&pid, i_soll, adc.get_current());
dac.write(iDAC::CHANNEL_1, dac_value);
fan.run(adc.get_temperature());
strom = adc.get_current();
spannung = adc.get_voltage();
temperatur = adc.get_temperature();
serial_cyclic();
}
}
}
/**
* @brief Callback Function for Command Line
* @param [in] pfvOutFunction Function to Print Data to Output
* @param [in] acCommands array with char pointers to the different arguments
* @param [in] u16ArgCount number of Arguments
* @return 0 = don't recall, 1 = call again
*/
uint16_t set_solltrom(CLI_OutFunction pfvOutFunction, char *acCommands[], uint16_t u16ArgCount)
{
char buf[40];
uint32_t cur = i_soll;
int32_t pos = snprintf(buf, sizeof(buf), "\r\nAktueller Soll-Strom: %" PRIu32, cur);
if(u16ArgCount == 1U)
{
uint32_t in = strtoul(acCommands[0], NULL, 10);
snprintf(&buf[pos], sizeof(buf) - pos, " Neu: %" PRIu32, in);
i_soll = in;
}
pfvOutFunction(buf);
return 0;
}
uint16_t ist_werte(CLI_OutFunction pfvOutFunction, char *acCommands[], uint16_t u16ArgCount)
{
static uint32_t last_call = 0U;
uint16_t recall = 0U;
if(u16ArgCount == 1U)
{
recall = (acCommands[0][0] == '-' && acCommands[0][1] == 'r' && acCommands[0][2] == '\0');
}
if(((recall == 1U) && ((int32_t)(systick - last_call) > 999)) || recall == 0U)
{
char buffer[64];
snprintf(buffer, sizeof(buffer), "\rI: %5" PRIu32 " U: %5" PRIu32 " T: %5" PRIu32, strom, spannung, temperatur);
pfvOutFunction(buffer);
last_call = systick;
}
return recall;
}
uint16_t set_dutyCyle (CLI_OutFunction pfvOutFunction, char *acCommands[], uint16_t u16ArgCount)
{
char buf[40];
if(u16ArgCount == 1U)
{
uint32_t in = strtoul(acCommands[0], NULL, 10);
snprintf(buf, sizeof(buf), "\r\nNeu: %" PRIu32, in);
FanControl_SetDuty(in);
}
else
{
snprintf(buf, sizeof(buf), "\r\nMissing Argument Dutycycle!");
}
pfvOutFunction(buf);
return 0;
}