STM32 Arduino BI Металлоискатель
Привет друзья
Я начал писать свой собственный код для металлоискателя, основанный на STM32 Arduino коде работает правильно, отображение VDI на последовательном порту это нормально, но кто нибудь может посоветовать, как добавить в код функцию отладки GEB (Ground Balanc) ?
Вот мой код, спасибо заранее за все советы.
#include <STM32ADC.h>
STM32ADC myADC(ADC1);
uint8 RxPin = PA6;
const int TxPin = PA4;
const int maxSamples = 1;
uint16_t dataPoints[maxSamples];
#define SerialMode Serial
uint8_t TxPhase = 0; //TxPhase adjust 0-16
int32_t frequency = 10000; // Frequency(Hz)
int prescaler = 4;
double freq;
const uint16_t numSamplesToAverage = 128;
const double radiansToDegrees = 180.0/3.1415927;
int32_t bins[16];
int32_t calib[16];
volatile int32_t averages[16];
int VDI = 0;
int Calibrate = 1;
uint16_t numSamples = 0;
volatile uint32_t ticks = 0;
int interruptCounter = 0;
volatile uint8_t lastctr;
volatile uint16_t misses = 0;
uint8_t ctr = 0;
int32_t input_average;
volatile bool sampleReady = false;
const int32_t RXsin[] = {0, 49, 91, 118, 128, 118, 91, 49, 0, -49, -91, -118, -128, -118, -91, -49};
const int32_t RXcos[] = {-128, -118, -91, -49, 0, 49, 91, 118, 128, 118, 91, 49, 0, -49, -91, -118};
const int32_t Tx[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 4095, 4095, 4095, 4095, 4095, 4095, 4095};
void Tx_Rx_Isr(void) {
ticks++;
ctr++;
TxPhase++;
digitalWrite(TxPin, Tx[TxPhase-1]);
int32_t i = dataPoints[0] - 2048;
input_average -= (input_average >> 10);
input_average += i;
input_average = input_average + i;
bins[ctr-1] = i - (input_average >> 10);
if (ctr == 16)
{
++numSamples;
if (numSamples == numSamplesToAverage)
{
numSamples = 0;
if (!sampleReady)
{
memcpy((void*)averages, bins, sizeof(averages));
sampleReady = true;
}
memset(bins, 0, sizeof(bins));
}
ctr = 0;
}
if (TxPhase == 16)
{
TxPhase = 0;
}
}
void setup()
{
SerialMode.begin(57600);
delay(10);
pinMode(TxPin, OUTPUT);
Timer3.setPrescaleFactor(prescaler);
freq = (72000000/2/prescaler)/frequency/8;
Timer3.setOverflow(freq);
Timer3.setMasterModeTrGo(TIMER_CR2_MMS_UPDATE);
myADC.calibrate();
myADC.setSampleRate(ADC_SMPR_1_5);
myADC.setPins(&RxPin, 1);
myADC.setDMA(dataPoints, maxSamples, (DMA_MINC_MODE | DMA_CIRC_MODE | DMA_HALF_TRNS | DMA_TRNS_CMPLT), Tx_Rx_Isr);
myADC.setTrigger(ADC_EXT_EV_TIM3_TRGO);
myADC.startConversion();
while (!sampleReady) {}
misses = 0;
sampleReady = false;
}
void loop(){
while (!sampleReady) {}
uint32_t oldTicks = ticks;
if(1 == Calibrate){
for (int i = 0; i < 16; ++i){
calib = averages;
}
sampleReady = false;
Calibrate = 0;
}
else
{
for (int i = 0; i < 16; ++i){
averages -= calib;
}
int32_t tmp1 = 0, tmp2 = 0;
int32_t rxX, rxY;
for (int i = 0; i < 16; ++i){
tmp1 += (averages * RXsin)/512;
tmp2 += (averages * RXcos)/512;
}
tmp1 -= (rxX >> 9);
tmp2 -= (rxY >> 9);
rxX += tmp1;
rxY += tmp2;
int VDI = atan2(rxY, rxX) * radiansToDegrees;
int Amp = sqrt((rxY * rxY) + (rxX * rxX));
SerialMode.print("Amp: ");
SerialMode.println(Amp);
SerialMode.println();
if (Amp >= 5){
SerialMode.print("VDI: ");
SerialMode.println(VDI);
}
sampleReady = false;
}
while (ticks - oldTicks < 16000)
{
}
}
Я начал писать свой собственный код для металлоискателя, основанный на STM32 Arduino коде работает правильно, отображение VDI на последовательном порту это нормально, но кто нибудь может посоветовать, как добавить в код функцию отладки GEB (Ground Balanc) ?
Вот мой код, спасибо заранее за все советы.
#include <STM32ADC.h>
STM32ADC myADC(ADC1);
uint8 RxPin = PA6;
const int TxPin = PA4;
const int maxSamples = 1;
uint16_t dataPoints[maxSamples];
#define SerialMode Serial
uint8_t TxPhase = 0; //TxPhase adjust 0-16
int32_t frequency = 10000; // Frequency(Hz)
int prescaler = 4;
double freq;
const uint16_t numSamplesToAverage = 128;
const double radiansToDegrees = 180.0/3.1415927;
int32_t bins[16];
int32_t calib[16];
volatile int32_t averages[16];
int VDI = 0;
int Calibrate = 1;
uint16_t numSamples = 0;
volatile uint32_t ticks = 0;
int interruptCounter = 0;
volatile uint8_t lastctr;
volatile uint16_t misses = 0;
uint8_t ctr = 0;
int32_t input_average;
volatile bool sampleReady = false;
const int32_t RXsin[] = {0, 49, 91, 118, 128, 118, 91, 49, 0, -49, -91, -118, -128, -118, -91, -49};
const int32_t RXcos[] = {-128, -118, -91, -49, 0, 49, 91, 118, 128, 118, 91, 49, 0, -49, -91, -118};
const int32_t Tx[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 4095, 4095, 4095, 4095, 4095, 4095, 4095};
void Tx_Rx_Isr(void) {
ticks++;
ctr++;
TxPhase++;
digitalWrite(TxPin, Tx[TxPhase-1]);
int32_t i = dataPoints[0] - 2048;
input_average -= (input_average >> 10);
input_average += i;
input_average = input_average + i;
bins[ctr-1] = i - (input_average >> 10);
if (ctr == 16)
{
++numSamples;
if (numSamples == numSamplesToAverage)
{
numSamples = 0;
if (!sampleReady)
{
memcpy((void*)averages, bins, sizeof(averages));
sampleReady = true;
}
memset(bins, 0, sizeof(bins));
}
ctr = 0;
}
if (TxPhase == 16)
{
TxPhase = 0;
}
}
void setup()
{
SerialMode.begin(57600);
delay(10);
pinMode(TxPin, OUTPUT);
Timer3.setPrescaleFactor(prescaler);
freq = (72000000/2/prescaler)/frequency/8;
Timer3.setOverflow(freq);
Timer3.setMasterModeTrGo(TIMER_CR2_MMS_UPDATE);
myADC.calibrate();
myADC.setSampleRate(ADC_SMPR_1_5);
myADC.setPins(&RxPin, 1);
myADC.setDMA(dataPoints, maxSamples, (DMA_MINC_MODE | DMA_CIRC_MODE | DMA_HALF_TRNS | DMA_TRNS_CMPLT), Tx_Rx_Isr);
myADC.setTrigger(ADC_EXT_EV_TIM3_TRGO);
myADC.startConversion();
while (!sampleReady) {}
misses = 0;
sampleReady = false;
}
void loop(){
while (!sampleReady) {}
uint32_t oldTicks = ticks;
if(1 == Calibrate){
for (int i = 0; i < 16; ++i){
calib = averages;
}
sampleReady = false;
Calibrate = 0;
}
else
{
for (int i = 0; i < 16; ++i){
averages -= calib;
}
int32_t tmp1 = 0, tmp2 = 0;
int32_t rxX, rxY;
for (int i = 0; i < 16; ++i){
tmp1 += (averages * RXsin)/512;
tmp2 += (averages * RXcos)/512;
}
tmp1 -= (rxX >> 9);
tmp2 -= (rxY >> 9);
rxX += tmp1;
rxY += tmp2;
int VDI = atan2(rxY, rxX) * radiansToDegrees;
int Amp = sqrt((rxY * rxY) + (rxX * rxX));
SerialMode.print("Amp: ");
SerialMode.println(Amp);
SerialMode.println();
if (Amp >= 5){
SerialMode.print("VDI: ");
SerialMode.println(VDI);
}
sampleReady = false;
}
while (ticks - oldTicks < 16000)
{
}
}