cancel
Showing results for 
Search instead for 
Did you mean: 

TouchGFX + CubeIDE Project (Gaussmetr/Oscillocope)

Thadeus
Associate

Post edited by ST moderator to be inline with the community rules especially with the code sharing. In next time please use </> button to paste your code. Please read this post: How to insert source code

Hello,

I am working on a project using the STM32F429I-DISC1 board. This project is part of my part-time job and will also serve as my university thesis. I’ve been working on it for about a month, but I’ve run into some issues I can’t solve.

My goal is to make the board function somewhat like an oscilloscope (Gaussmeter) — it doesn’t need to be perfectly precise.
I’m sampling at 10 kHz and storing samples in a buffer of size 168 (since 10,000 / 60 ≈ 167.6). Every handleTickEvent() (which runs at 60 Hz), I send this buffer to a DynamicGraph.

The problem is that it doesn’t behave correctly.
In a previous version, I plotted one point per tick, which naturally skipped some samples but still displayed the sine wave correctly on the DynamicGraph, and the computed values were accurate.

In this new version, I’m trying to buffer 168 samples and then plot them in a for loop, but the results are inconsistent:

  • sometimes nothing is drawn,

  • sometimes the same Y value repeats for many X values, and calculated values Peak and Mean are stucked

  • and only around 130 Hz does it start resembling a sine wave.

I would really appreciate any help.
The main goal is to buffer the ADC samples and display them correctly on the graph. I need at least a 4 kHz sampling frequency.

main.c

#define ADC_BUFFER 168

__IO uint16_t rawValues[ADC_BUFFER];

__IO uint16_t voltages[ADC_BUFFER];



volatile bool halfReady = false;

volatile bool fullReady = false;



void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef *hadc)

{

for (uint16_t i = 0; i < ADC_BUFFER/2; i++)

{

voltages[i] = rawValues[i] * 3300 / 4095;

}

}



void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)

{

for (uint16_t i = ADC_BUFFER/2; i < ADC_BUFFER; i++)

{

voltages[i] = rawValues[i] * 3300 / 4095;

}

}





//ADC1 and Timer1

HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);

HAL_ADC_Start_DMA(&hadc1, (uint32_t *)rawValues, ADC_BUFFER);





Screen1View.cpp





#include <gui/screen1_screen/Screen1View.hpp>





#include <cmath> // sin() a M_PI

#include <cstdlib> // rand()



#ifdef SIMULATOR

#include <cstdint>

#else

#include "stm32f4xx_hal.h"

#endif



constexpr int ADC_BUFFER = 168;

#ifndef SIMULATOR

extern __IO uint16_t voltages[ADC_BUFFER];

#endif





Screen1View::Screen1View()

{



}



void Screen1View::setupScreen()

{

Screen1ViewBase::setupScreen();



textArea1.setWildcard(textArea1Buffer);

textArea2.setWildcard(textArea2Buffer);

}



void Screen1View::tearDownScreen()

{

Screen1ViewBase::tearDownScreen();

}



void Screen1View::handleTickEvent()

{

#ifdef SIMULATOR

static float phase = 0.0f;

const float step = 2.0f * M_PI / 100.0f;

const float amplitude = 1650.0f;

const float offset = 1650.0f;



for (uint16_t i = 0; i < 100; i++)

{

uint16_t value = static_cast<uint16_t>(offset + amplitude * sin(phase));

modelListener->UpdateGraph1(value);

phase += step;

if (phase >= 2.0f * M_PI)

phase -= 2.0f * M_PI;

}

#else



float sum = 0.0f;

float peak = -1000000.0f;



for (uint16_t i = 0; i < ADC_BUFFER; i++)

{

dynamicGraph1.addDataPoint(voltages[i]);



if (voltages[i] > peak)

peak = voltages[i];



sum += voltages[i];



}



float mean = sum / ADC_BUFFER;



Unicode::snprintfFloat(textArea2Buffer, TEXTAREA2_SIZE, "%6.2f", mean);

textArea2.resizeToCurrentText();

textArea2.invalidate();



Unicode::snprintfFloat(textArea1Buffer, TEXTAREA1_SIZE, "%6.2f", peak);

textArea1.resizeToCurrentText();

textArea1.invalidate();

#endif

}

Maybe I am doing something wrong. I checked a lot of other threads and I saw a lot of videos but its always just simple tasks not buffering frequencies like that. But I think it shouldnt be that hard to do. I must be missing something important.

0 REPLIES 0