2024-11-23 01:32 PM
The ADC buffer is not being written to I would like it to zero all values less than 5 to eliminate noise. My project is a DTMF detector. I need it to pass through audio when no DTMF tone is detected and execute a command when there is one found. Also please assist with the pass-through function that is not working either
#include "main.h"
#include <math.h>
#include <stdio.h>/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
char message5[40] = {'\0'};
static void MX_GPIO_Init(void); Audio and voice
static void MX_DMA_Init(void);
static void MX_USART2_UART_Init(void);
static void MX_TIM6_Init(void);
static void MX_ADC_Init(void);
static void MX_DAC_Init(void);
int main(void)
{
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_USART2_UART_Init();
MX_TIM6_Init();
MX_ADC_Init();
MX_DAC_Init();
/* USER CODE BEGIN 2 */
memset(adc_buffer, 0, sizeof(adc_buffer));
HAL_ADC_Start_DMA(&hadc, (uint32_t * ) adc_buffer, BLOCK_SIZE);
HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, (uint32_t *) dac_buffer, BLOCK_SIZE, DAC_ALIGN_12B_R);
HAL_TIM_Base_Start(&htim6);
while (1)
{
if (dataReady){
dataReady = 0;
for (int i = 0; i < BLOCK_SIZE; i++) {
if (adc_buffer[i] < NOISE_THRESHOLD) {
char debug_msg[50];
snprintf(debug_msg, sizeof(debug_msg), "Zeroing ADC[%d]: %u\r\n", i, adc_buffer[i]);
HAL_UART_Transmit(&huart2, (uint8_t*)debug_msg, strlen(debug_msg), HAL_MAX_DELAY);
adc_buffer[i] = 0; //
}
}
print_adc_values();
strcpy(message5, "callback \n \r");
HAL_UART_Transmit(&huart2,(uint8_t*)message5,sizeof(message5),100);
char tone = detect_tone((short*) ADCptr, BLOCK_SIZE); //if i ru into problems add + BLOCK_SIZE back
if (tone == '\0') {
for (int i = 0; i < BLOCK_SIZE; i++) {
DACptr[i] = ADCptr[i];
}
} else {
execute_command(tone);
for (int i = 0; i < BLOCK_SIZE; i++) {
DACptr[i] = 0; // Silence output
}
}
}
}
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL6;
RCC_OscInitStruct.PLL.PLLDIV = RCC_PLL_DIV3;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
{
Error_Handler();
}
}
static void MX_ADC_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
hadc.Instance = ADC1;
hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc.Init.EOCSelection = ADC_EOC_SEQ_CONV;
hadc.Init.LowPowerAutoWait = ADC_AUTOWAIT_DISABLE;
hadc.Init.LowPowerAutoPowerOff = ADC_AUTOPOWEROFF_DISABLE;
hadc.Init.ChannelsBank = ADC_CHANNELS_BANK_A;
hadc.Init.ContinuousConvMode = ENABLE;
hadc.Init.NbrOfConversion = 1;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T6_TRGO;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
hadc.Init.DMAContinuousRequests = ENABLE;
if (HAL_ADC_Init(&hadc) != HAL_OK)
{
Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_13;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_4CYCLES;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
static void MX_DAC_Init(void)
{
DAC_ChannelConfTypeDef sConfig = {0};
hdac.Instance = DAC;
if (HAL_DAC_Init(&hdac) != HAL_OK)
{
Error_Handler();
}
sConfig.DAC_Trigger = DAC_TRIGGER_T6_TRGO;
sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
if (HAL_DAC_ConfigChannel(&hdac, &sConfig, DAC_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
}
static void MX_TIM6_Init(void)
{
TIM_MasterConfigTypeDef sMasterConfig = {0};
htim6.Instance = TIM6;
htim6.Init.Prescaler = 0;
htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
htim6.Init.Period = 3999;
htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
}
static void MX_USART2_UART_Init(void)
{
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART2_Init 2 */
/* USER CODE END USART2_Init 2 */
}
static void MX_DMA_Init(void)
{
__HAL_RCC_DMA1_CLK_ENABLE();
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
/* DMA1_Channel2_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel2_IRQn);
}
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitStruct.Pin = B1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct);
}
void print_adc_values(void) {
char uart_message[50];
for (int i = 0; i < BLOCK_SIZE; i++) {
snprintf(uart_message, sizeof(uart_message), "ADC Value [%d]: %u\r\n", i, adc_buffer[i]);
HAL_UART_Transmit(&huart2, (uint8_t*)uart_message, strlen(uart_message), HAL_MAX_DELAY);
}
}
/* USER CODE BEGIN 4 */
double goertzel(const short* samples, int num_samples, double target_freq, double sample_rate) {
// Implementation of the Goertzel algorithm
double k = (int)(0.5 + ((num_samples * target_freq) / sample_rate));
double omega = (2.0 * PI * k) / num_samples;
double cosine = cos(omega);
double coeff = 2.0 * cosine;
double q0 = 0.0, q1 = 0.0, q2 = 0.0;
for (int i = 0; i < num_samples; i++) {
q0 = coeff * q1 - q2 + samples[i];
q2 = q1;
q1 = q0;
}
return q1 * q1 + q2 * q2 - q1 * q2 * coeff;
}
char detect_tone(const short* samples, int num_samples) {
strcpy(message5, "tone \n \r");
HAL_UART_Transmit(&huart2,(uint8_t*)message5,sizeof(message5),100);
double power[8];
double max_low_power = 0.0;
double max_high_power = 0.0;
int max_low_index = -1;
int max_high_index = -1;
// Compute power for each DTMF frequency
for (int i = 0; i < num_freqs; i++)
{
power[i] = goertzel(samples, num_samples, dtmf_freqs[i], SAMPLE_RATE);
if (i < 4)
{
// Low frequency group
if (power[i] > max_low_power)
{
max_low_power = power[i];
max_low_index = i;
}
}
else
{
// High frequency group
if (power[i] > max_high_power)
{
max_high_power = power[i];
max_high_index = i - 4;
}
}
}
// Validate detected tone
if (max_low_index != -1 && max_high_index != -1)
{
return dtmf_keys[max_low_index][max_high_index];
}
return '\0'; // No valid tone detected
}
void execute_command(char tone) {
char message[40] = {'\0'};
switch (tone) {
case 'A':
strcpy(message, "antennas deployed \n \r");
HAL_UART_Transmit(&huart2,(uint8_t*)message,sizeof(message),100);
// UART to terminal "deploy antenna"
break;
case 'B':
char message2[40] = {'\0'};
strcpy(message2, "power savings mode activated \n \r");
HAL_UART_Transmit(&huart2,(uint8_t*)message2,sizeof(message),100);
//UART to terminal "power"
break;
case '5':
char message4[40] = {'\0'};
strcpy(message4, "TEST \n \r");
HAL_UART_Transmit(&huart2,(uint8_t*)message4,sizeof(message),100);
// Handle other cases
break;
default:
char message3[40] = {'\0'};
strcpy(message3, "DTMF tone detected. no command \n \r");
HAL_UART_Transmit(&huart2,(uint8_t*)message3,sizeof(message),100);
char uart_message[50];
snprintf(uart_message, sizeof(uart_message), "Detected tone: %c\r\n", tone);
HAL_UART_Transmit(&huart2, (uint8_t*)uart_message, strlen(uart_message), 100);
break;
}
// Implement actions based on the detected tone
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)//keep
{
dataReady = 1;
}
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */