1

Тема: Измерение напряжения STM32 (Arduino IDE)

Здравствуйте 

Первая программа ( один вольтметр ) работает отлично.

//http://rcl-radio.ru/?p=68627

//#include <Wire.h>
#include <LiquidCrystal.h>
//LiquidCrystal lcd(PB15, PB5, PA2, PB6, PB8, PB9);
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);

int u, u_sum, i;
const float u3300 = 3280;// Замерьте напряжение 3.3 В и укажите его в мВ

void setup() {
  Serial.begin(115200);
  lcd.begin(16, 2);
  pinMode(PA6, INPUT_ANALOG);

}

void loop() {
  for (i = 0; i < 10; i++) {
    u = analogRead(PA6);
    //delay(100);
    u_sum = u_sum + u;
  }
  u = u_sum / 10; u_sum = 0;
  Serial.println(u);
  //lcd.clear();
   lcd.print("   ");
  lcd.setCursor(0, 0);
  lcd.print("U = ");
  float u_iz = u3300 / 4095 * u / 1000;
  lcd.print(u_iz, 3);
  lcd.print(" V");
  lcd.setCursor(10, 0);
  lcd.print(u);
}

http://forum.rcl-radio.ru/uploads/images/2021/01/1c478d2ef552bd7d8ea71c742734e5a7.png

Вторая не очень ( два вольтметра) , шумы увеличились в 7 раз.

//http://rcl-radio.ru/?p=68627

#include <LiquidCrystal.h>
//LiquidCrystal lcd(PB15, PB5, PA2, PB6, PB8, PB9);
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);

int u, u_sum, i;
const float u3300 = 3280;// Замерьте напряжение 3.3 В и укажите его в мВ
////////////
int u2, u2_sum2;
const float u23300 = 3280;
////////////
void setup() {
  Serial.begin(115200);
  lcd.begin(16, 2);
  pinMode(PA6, INPUT_ANALOG);
  pinMode(PA7, INPUT_ANALOG);

}

void loop() {
  for (i = 0; i < 10; i++) {
    u = analogRead(PA6);
    //delay(100);
    u_sum = u_sum + u;
    ///////////
    u2 = analogRead(PA7);
    //delay(100);
    u2_sum2 = u2_sum2 + u2;
    ////////////
  }
  u = u_sum / 10; u_sum = 0;
  u2 = u2_sum2 / 10; u2_sum2 = 0;

  Serial.print(u2);
  Serial.print(" ");
  Serial.println(u);
  //lcd.clear();
  lcd.print("   ");
  lcd.setCursor(0, 0);
  lcd.print("U = ");
  float u_iz = u3300 / 4095 * u / 1000;
  float u2_iz = u23300 / 4095 * u2 / 1000;
  lcd.print(u_iz, 3);
  lcd.print(" V");
  lcd.setCursor(10, 0);
  lcd.print(u);
  
  lcd.setCursor(0, 1);
   lcd.print("U2 ");
  lcd.print(u2_iz, 3);
 
  lcd.setCursor(10, 1);
  lcd.print(u2);
}

http://forum.rcl-radio.ru/uploads/images/2021/01/9dabc38048bad7a3dfea30ef3808381b.png


Программа взята от туда.
http://rcl-radio.ru/?p=68627

Помогите исправить

2

Re: Измерение напряжения STM32 (Arduino IDE)

Установите задержку между измерениями, хотя бы 10 мс

for (i = 0; i < 10; i++) {
    u = analogRead(PA6);
    delay(10);
    u_sum = u_sum + u;
    ///////////
    u2 = analogRead(PA7);
    delay(10);
    u2_sum2 = u2_sum2 + u2;
    ////////////
  }

3

Re: Измерение напряжения STM32 (Arduino IDE)

Шумы стали меньше, сейчас они 3 раза больше  по сравнению с одноканальным вольтметром.

4

Re: Измерение напряжения STM32 (Arduino IDE)

Используйте аналоговые входы не по порядку, разнесите их подальше друг от друга, возможно поможет.

5

Re: Измерение напряжения STM32 (Arduino IDE)

Думаю что проблема в программе, соединил  два входа короткой перемычкой, шумы не меняются, выключил один кана (PA7)во второй программе вот результат.

http://forum.rcl-radio.ru/uploads/images/2021/01/5bd128703eae797a221c20eab0e864e6.png

//http://rcl-radio.ru/?p=68627

#include <LiquidCrystal.h>
//LiquidCrystal lcd(PB15, PB5, PA2, PB6, PB8, PB9);
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);

int u, u_sum, i;
const float u3300 = 3280;// Замерьте напряжение 3.3 В и укажите его в мВ
////////////
int u2, u2_sum2, k;
const float u23300 = 3280;
////////////
void setup() {
  Serial.begin(115200);
  lcd.begin(16, 2);
  pinMode(PA6, INPUT_ANALOG);
  pinMode(PA7, INPUT_ANALOG);

}

void loop() {
  for (i = 0; i < 100; i++) {
    u = analogRead(PA6);
    //delay(100);
    u_sum = u_sum + u;
    ///////////
   //delay(3);
   /*
    ///////////
    u2 = analogRead(PA7);
    //delay(100);
    u2_sum2 = u2_sum2 + u2;
    ////////////
    */
  }

  u = u_sum / 100; u_sum = 0;
  u2 = u2_sum2 / 100; u2_sum2 = 0;

 // Serial.print(u2);
  Serial.print(" ");
  Serial.println(u);
  //lcd.clear();
  lcd.print("   ");
  lcd.setCursor(0, 0);
  lcd.print("U = ");
  float u_iz = u3300 / 4095 * u / 1000;
  float u2_iz = u23300 / 4095 * u2 / 1000;
  
  lcd.print(u_iz, 3);
  lcd.print(" V");
  lcd.setCursor(10, 0);
  lcd.print(u);
  
  lcd.setCursor(0, 1);
   lcd.print("U2 ");
  lcd.print(u2_iz, 3);
 
  lcd.setCursor(10, 1);
  lcd.print(u2);
}

6

Re: Измерение напряжения STM32 (Arduino IDE)

Попробуйте этот код

#include <STM32ADC.h>
  STM32ADC myADC(ADC1);

uint8 pins[] = {PA6,PA7};

const int maxSamples = 2; 
uint16_t dataPoints[maxSamples];

void setup() {
  Serial.begin(9600);
  myADC.calibrate();
  pinMode(PA6,INPUT_ANALOG);
  pinMode(PA7,INPUT_ANALOG);
    
  myADC.setSampleRate(ADC_SMPR_239_5);//Время выборки канала
  // ADC_SMPR_7_5
  // ADC_SMPR_13_5
  // ADC_SMPR_28_5
  // ADC_SMPR_41_5
  // ADC_SMPR_55_5
  // ADC_SMPR_71_5
  // ADC_SMPR_239_5
  myADC.setScanMode();              
  myADC.setPins(pins, 2);          
  myADC.setContinuous();         
  myADC.setDMA(dataPoints, 2, (DMA_MINC_MODE | DMA_CIRC_MODE), NULL);  
  myADC.startConversion();   
}

void loop(){
      for(int i=0; i < maxSamples;i++) {
        Serial.print(i);
        Serial.print(" = ");
        Serial.println(dataPoints[i]);
        }
   // delay(1000); 
}; 

7

Re: Измерение напряжения STM32 (Arduino IDE)

Интересная программа.
Δ  = шумы
На сериал плоттер плохо видно , на сериал монитор это так .
http://forum.rcl-radio.ru/uploads/images/2021/01/a14b95917b47397a7ca5a7f16ff09b37.png

8

Re: Измерение напряжения STM32 (Arduino IDE)

Усреднение

#include <STM32ADC.h>
  STM32ADC myADC(ADC1);

uint8 pins[] = {PA6,PA7};

const int maxSamples = 2; 
uint16_t dataPoints[maxSamples];
long sum1, sum2;

void setup() {
  Serial.begin(9600);
  myADC.calibrate();
  pinMode(PA6,INPUT_ANALOG);
  pinMode(PA7,INPUT_ANALOG);
    
  myADC.setSampleRate(ADC_SMPR_239_5);//Время выборки канала
  // ADC_SMPR_7_5
  // ADC_SMPR_13_5
  // ADC_SMPR_28_5
  // ADC_SMPR_41_5
  // ADC_SMPR_55_5
  // ADC_SMPR_71_5
  // ADC_SMPR_239_5
  myADC.setScanMode();              
  myADC.setPins(pins, 2);          
  myADC.setContinuous();         
  myADC.setDMA(dataPoints, 2, (DMA_MINC_MODE | DMA_CIRC_MODE), NULL);  
  myADC.startConversion();   
}

void loop(){
  for (int j = 0; j < 10; j++) {
    sum1 = sum1 + dataPoints[0];
    sum2 = sum2 + dataPoints[1]; 
        }
  Serial.println(sum1/10);sum1=0;
  Serial.println(sum2/10);sum2=0;
};

9

Re: Измерение напряжения STM32 (Arduino IDE)

http://forum.rcl-radio.ru/uploads/images/2021/01/8946ccedd33af03bd69fa7160d30e86b.png

10

Re: Измерение напряжения STM32 (Arduino IDE)

#include <STM32ADC.h>
  STM32ADC myADC(ADC1);

uint8 pins[] = {PA6,PA7};

const int maxSamples = 2; 
uint16_t dataPoints[maxSamples];
long sum1, sum2;

void setup() {
  Serial.begin(9600);
  myADC.calibrate();
  rcc_set_prescaler(RCC_PRESCALER_ADC, RCC_ADCPRE_PCLK_DIV_8); 
  pinMode(PA6,INPUT_ANALOG);
  pinMode(PA7,INPUT_ANALOG);
    
  myADC.setSampleRate(ADC_SMPR_239_5);
  myADC.setScanMode();              
  myADC.setPins(pins, 2);          
  myADC.setContinuous();         
  myADC.setDMA(dataPoints, 2, (DMA_MINC_MODE | DMA_CIRC_MODE), NULL);  
  myADC.startConversion();   
}

void loop(){
  for (int j = 0; j < 10; j++) {
    sum1 = sum1 + dataPoints[0];
    sum2 = sum2 + dataPoints[1]; 
    delay(1);
        }
  Serial.println(sum1/10);sum1=0;
  Serial.println(sum2/10);sum2=0;
};

Входы на GND
http://forum.rcl-radio.ru/uploads/images/2021/01/c9d373d7840821b03e79decf49f1f484.png
Входы на 3,3 V
http://forum.rcl-radio.ru/uploads/images/2021/01/be44f68ff15574a831cc3b3b8bc9b2f3.png

11

Re: Измерение напряжения STM32 (Arduino IDE)

http://forum.rcl-radio.ru/uploads/images/2021/01/1f92cf228a19fd5b2a4ea64c87de0f9e.png

заменил на

  ///////////////
Serial.print(sum1/10);sum1=0;
Serial.print("   ");
  Serial.println(sum2/10);sum2=0;
  ////////////////

http://forum.rcl-radio.ru/uploads/images/2021/01/e9fb1cd03093811318dae89514d10cc9.png

Все равно не получается как у Вас.

12

Re: Измерение напряжения STM32 (Arduino IDE)

Возможно проблема в источнике напряжения который измеряете? Подайте на вход 3,3 В с самой платы stm32.

13

Re: Измерение напряжения STM32 (Arduino IDE)

Так не работает
http://forum.rcl-radio.ru/uploads/images/2021/01/cfe867e7690e0aa1059f6f911490a162.png

А так работает
http://forum.rcl-radio.ru/uploads/images/2021/01/34a284388e43b3f5c22aae5b76ff6222.png

Сейчас можно измерять мВ

14

Re: Измерение напряжения STM32 (Arduino IDE)

СПОСИБО

15

Re: Измерение напряжения STM32 (Arduino IDE)

3,3 В с самой платы stm32.
http://forum.rcl-radio.ru/uploads/images/2021/01/0efe304c5ab70a4485718b0cb19739d9.png

4092 - 4094 = хорошо ,

Сейчас вижу что 3.3В на плате чистое и можно его использовать для питания других блоков, например усилителя, до сих пор использовал отдельный регулятор.

16

Re: Измерение напряжения STM32 (Arduino IDE)

Сейчас пытаюсь добавить вольтметр переменного напряжения.
Соединил две программы , вольтметр для переменного напряжения работает правельно но для нпостаянного нет, не реагирует на подачу сигнала на PA или PA7.

первый скетч,

#include <STM32ADC.h>
STM32ADC myADC(ADC1);

uint8 pins[] = {PA6, PA7};

const int maxSamples = 2;
uint16_t dataPoints[maxSamples];
long sum1, sum2;

void setup() {
  Serial.begin(115200);
  myADC.calibrate();
  rcc_set_prescaler(RCC_PRESCALER_ADC, RCC_ADCPRE_PCLK_DIV_8);
  pinMode(PA6, INPUT_ANALOG);
  pinMode(PA7, INPUT_ANALOG);

  myADC.setSampleRate(ADC_SMPR_239_5);
  myADC.setScanMode();
  myADC.setPins(pins, 2);
  myADC.setContinuous();
  myADC.setDMA(dataPoints, 2, (DMA_MINC_MODE | DMA_CIRC_MODE), NULL);
  myADC.startConversion();
}

void loop() {
  for (int j = 0; j < 10; j++) {
    sum1 = sum1 + dataPoints[0];
    sum2 = sum2 + dataPoints[1];
    delay(1);
  }
  //Serial.println(sum1/10);sum1=0;
  //Serial.println(sum2/10);sum2=0;
  ///////////////
  Serial.print(sum1 / 10); sum1 = 0;
  Serial.print("   ");
  Serial.println(sum2 / 10); sum2 = 0;
  ////////////////
};

второй,

#include "arduinoFFT.h"
#include <LiquidCrystal.h>
//LiquidCrystal lcd(PB15, PB5, PA2, PB6, PB8, PB9);
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);
#include <EEPROM.h>
#define SAMPLES1 128
#define SAMPLING_FREQUENCY 40000
///////////////
int led = PC13;
const int numReadings = 10;
const float THRESHOLD = 500;
int piezoPin = PB6;
int readings[numReadings];      // the readings from the analog input
int readIndex = 0;              // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average
////////////////
int Tup = PB13;
int Tdown = PB15;
int k;
//int k<100;
///////////////
//int inputPin = A0;
////////////////
arduinoFFT FFT = arduinoFFT();

unsigned int sampling_period_us;
unsigned long microseconds;

double vReal[SAMPLES1];
double vImag[SAMPLES1];
// no noise
//--------------------------------------
int currentaverage = average;
int previousaverage = 0;
//---------------------------------------
void setup() {
  pinMode(led, OUTPUT);
  Serial.begin(115200);
  lcd.begin( 16, 2 );
   //EEPROM.read(500, (uint16*)&k);
    pinMode(Tup, INPUT_PULLDOWN);
  pinMode(Tdown, INPUT_PULLDOWN);
  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    readings[thisReading] = 0;
  }
  sampling_period_us = round(1000000 * (1.0 / SAMPLING_FREQUENCY));
}

void loop() {
  // no noise
  //----------------------------------------

  previousaverage = currentaverage;
  //**************************************************************************
  currentaverage = average;
  //if (abs(currentaverage -  previousaverage) <  previousaverage / 40 ) // 100 = 1%
  if (abs(currentaverage -  previousaverage) <  previousaverage / 25 ) // 100 = 1%

    //********************************************************************************
  {
    currentaverage = previousaverage;
  }
  //----------------------------------------

  /*SAMPLING*/
  for (int t = 0; t < SAMPLES1; t++)
  {
    microseconds = micros();    //Overflows after around 70 minutes!

    vReal[t] = analogRead(PB0);
   // vReal[t] = analogRead(PA6);
    vImag[t] = 0;

    while (micros() < (microseconds + sampling_period_us)) {
    }
  }

  /*FFT*/
  FFT.Windowing(vReal, SAMPLES1, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
  FFT.Compute(vReal, vImag, SAMPLES1, FFT_FORWARD);
  FFT.ComplexToMagnitude(vReal, vImag, SAMPLES1);
  double peak = FFT.MajorPeak(vReal, SAMPLES1, SAMPLING_FREQUENCY);
  ////////////////
  // subtract the last reading:
  total = total - readings[readIndex];
  // read from the sensor:
  //readings[readIndex] = analogRead(inputPin);
  readings[readIndex] = vReal[34];
  // add the reading to the total:
  total = total + readings[readIndex];
  // advance to the next position in the array:
  readIndex = readIndex + 1;

  // if we're at the end of the array...
  if (readIndex >= numReadings) {
    // ...wrap around to the beginning:
    readIndex = 0;
  }

  // calculate the average:
  average = total / numReadings;
  // send it to the computer as ASCII digits
  //Serial.println(average);
  delay(1);        // delay in between reads for stability
  ///////////////////
 // if (currentaverage > THRESHOLD)
   if (currentaverage > k)
  {
    digitalWrite(led, LOW);
    tone(piezoPin, 4000);
      Serial.print(1000.0);
    
  }
  else
  {
    digitalWrite(led, HIGH);
    noTone(piezoPin);
        Serial.print(5.0);
  }
/////////////////////
 if (digitalRead(Tup) == HIGH)

 {

 {
 k++;
 }
 }
  if (digitalRead(Tdown) == HIGH)
  {
    k--;
  }
  /////////////////
  /*PRINT RESULTS*/
   Serial.print(led);
  Serial.print(" ");
  Serial.print(average);
  Serial.print(" ");
  Serial.print(currentaverage);
  Serial.print(" ");
  //Serial.println(vReal[34], 1);//40=122.1kHz,  30=8.9, 35 = 10.6, 34 = 10.30kHz
  Serial.println(vReal[35], 1);
  lcd.print("   ");
  lcd.setCursor(0, 0);
  lcd.print("N ");
  //lcd.print(vReal[12], 1);// 10 - 3kHz, 12 =
  lcd.print(currentaverage);

  lcd.setCursor(0, 1);
  lcd.print("T ");
  //lcd.print(THRESHOLD);
    lcd.print(k);
  EEPROM.write(500, k);
}

и два вместе.

#include "arduinoFFT.h"
#include <LiquidCrystal.h>
//LiquidCrystal lcd(PB15, PB5, PA2, PB6, PB8, PB9);
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);
#include <EEPROM.h>
#define SAMPLES1 128
#define SAMPLING_FREQUENCY 40000
//////////////////
#include <STM32ADC.h>
STM32ADC myADC(ADC1);

uint8 pins[] = {PA6, PA7};

const int maxSamples = 2;
uint16_t dataPoints[maxSamples];
long sum1, sum2;
///////////////
int led = PC13;
const int numReadings = 10;
const float THRESHOLD = 500;
int piezoPin = PB6;
int readings[numReadings];      // the readings from the analog input
int readIndex = 0;              // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average
////////////////
int Tup = PB13;
int Tdown = PB15;
int k;
//int k<100;
///////////////
//int inputPin = A0;
////////////////
arduinoFFT FFT = arduinoFFT();

unsigned int sampling_period_us;
unsigned long microseconds;

double vReal[SAMPLES1];
double vImag[SAMPLES1];
// no noise
//--------------------------------------
int currentaverage = average;
int previousaverage = 0;
//---------------------------------------
void setup() {
  ////////////////
 myADC.calibrate();
  rcc_set_prescaler(RCC_PRESCALER_ADC, RCC_ADCPRE_PCLK_DIV_8);
  pinMode(PA6, INPUT_ANALOG);
  pinMode(PA7, INPUT_ANALOG);

  myADC.setSampleRate(ADC_SMPR_239_5);
  myADC.setScanMode();
  myADC.setPins(pins, 2);
  myADC.setContinuous();
  myADC.setDMA(dataPoints, 2, (DMA_MINC_MODE | DMA_CIRC_MODE), NULL);
  myADC.startConversion();

  ///////////////
  pinMode(led, OUTPUT);
  Serial.begin(115200);
  lcd.begin( 16, 2 );
   //EEPROM.read(500, (uint16*)&k);
    pinMode(Tup, INPUT_PULLDOWN);
  pinMode(Tdown, INPUT_PULLDOWN);
  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    readings[thisReading] = 0;
  }
  sampling_period_us = round(1000000 * (1.0 / SAMPLING_FREQUENCY));
}

void loop() {
  /////////////////
  for (int j = 0; j < 10; j++) {
    sum1 = sum1 + dataPoints[0];
    sum2 = sum2 + dataPoints[1];
    delay(1);
  }
  //Serial.println(sum1/10);sum1=0;
  //Serial.println(sum2/10);sum2=0;
  ///////////////
  //Serial.print(sum1 / 10); sum1 = 0;
 // Serial.print("   ");
 // Serial.println(sum2 / 10); sum2 = 0;
  ////////////////
  ////////////////
  // no noise
  //----------------------------------------

  previousaverage = currentaverage;
  //**************************************************************************
  currentaverage = average;
  //if (abs(currentaverage -  previousaverage) <  previousaverage / 40 ) // 100 = 1%
  if (abs(currentaverage -  previousaverage) <  previousaverage / 25 ) // 100 = 1%

    //********************************************************************************
  {
    currentaverage = previousaverage;
  }
  //----------------------------------------

  /*SAMPLING*/
  for (int t = 0; t< SAMPLES1; t++)
  {
    microseconds = micros();    //Overflows after around 70 minutes!

    vReal[t] = analogRead(PB0);
   // vReal[t] = analogRead(PA6);
    vImag[t] = 0;

    while (micros() < (microseconds + sampling_period_us)) {
    }
  }

  /*FFT*/
  FFT.Windowing(vReal, SAMPLES1, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
  FFT.Compute(vReal, vImag, SAMPLES1, FFT_FORWARD);
  FFT.ComplexToMagnitude(vReal, vImag, SAMPLES1);
  double peak = FFT.MajorPeak(vReal, SAMPLES1, SAMPLING_FREQUENCY);
  ////////////////
  // subtract the last reading:
  total = total - readings[readIndex];
  // read from the sensor:
  //readings[readIndex] = analogRead(inputPin);
  readings[readIndex] = vReal[34];
  // add the reading to the total:
  total = total + readings[readIndex];
  // advance to the next position in the array:
  readIndex = readIndex + 1;

  // if we're at the end of the array...
  if (readIndex >= numReadings) {
    // ...wrap around to the beginning:
    readIndex = 0;
  }

  // calculate the average:
  average = total / numReadings;
  // send it to the computer as ASCII digits
  //Serial.println(average);
  delay(1);        // delay in between reads for stability
  ///////////////////
 // if (currentaverage > THRESHOLD)
   if (currentaverage > k)
  {
    digitalWrite(led, LOW);
    tone(piezoPin, 4000);
      Serial.print(1000.0);
    
  }
  else
  {
    digitalWrite(led, HIGH);
    noTone(piezoPin);
        Serial.print(5.0);
  }
/////////////////////
 if (digitalRead(Tup) == HIGH)

 {

 {
 k++;
 }
 }
  if (digitalRead(Tdown) == HIGH)
  {
    k--;
  }
  /////////////////
  /*PRINT RESULTS*/
   Serial.print(led);
  Serial.print(" ");
  Serial.print(average);
  Serial.print(" ");
  Serial.print(currentaverage);
  Serial.print(" ");
  //Serial.println(vReal[34], 1);//40=122.1kHz,  30=8.9, 35 = 10.6, 34 = 10.30kHz
  Serial.print(vReal[35], 1);
  /////////////////
  Serial.print(sum1 / 10); sum1 = 0;
  Serial.print("   ");
  Serial.println(sum2 / 10); sum2 = 0;
  /////////////////
  lcd.print("   ");
  lcd.setCursor(0, 0);
  lcd.print("N ");
  //lcd.print(vReal[12], 1);// 10 - 3kHz, 12 =
  lcd.print(currentaverage);

  lcd.setCursor(0, 1);
  lcd.print("T ");
  //lcd.print(THRESHOLD);
    lcd.print(k);
  EEPROM.write(500, k);
}

17

Re: Измерение напряжения STM32 (Arduino IDE)

http://forum.rcl-radio.ru/uploads/images/2021/01/c2f4e0bcf0f5514b5480e5dc47bb45ac.png
поменял i на t

18

Re: Измерение напряжения STM32 (Arduino IDE)

нашел, забыл в одном месте  Serial.print(" ");

19 (2021-01-18 02:15:01 отредактировано galina)

Re: Измерение напряжения STM32 (Arduino IDE)

Поработало  несколько минут, хотел навести порядок и испортил. Сейчас как раньше, не реагирует на подачу сигнала на PA6 ,PA7.


#include "arduinoFFT.h"
#include <LiquidCrystal.h>
//LiquidCrystal lcd(PB15, PB5, PA2, PB6, PB8, PB9);
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);
#include <EEPROM.h>
#define SAMPLES1 128
#define SAMPLING_FREQUENCY 40000
//======================================
#include <STM32ADC.h>
STM32ADC myADC(ADC1);

uint8 pins[] = {PA6, PA7};
//uint8 pins[] = {PA0, PA7};
//uint8 pins[] = {PA0, PA3};
const int maxSamples = 2;
uint16_t dataPoints[maxSamples];
long sum1, sum2;
//==================================
///////////////
int led = PC13;
const int numReadings = 10;
const float THRESHOLD = 500;
int piezoPin = PB6;
int readings[numReadings];      // the readings from the analog input
int readIndex = 0;              // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average
////////////////
int Tup = PB13;
int Tdown = PB15;
int k;
//int k<100;
///////////////
//int inputPin = A0;
////////////////
arduinoFFT FFT = arduinoFFT();

unsigned int sampling_period_us;
unsigned long microseconds;

double vReal[SAMPLES1];
double vImag[SAMPLES1];
// no noise
//--------------------------------------
int currentaverage = average;
int previousaverage = 0;
//---------------------------------------
void setup() {
  pinMode(led, OUTPUT);
  Serial.begin(115200);
  //lcd.begin( 16, 2 );
  //====================================================

  myADC.calibrate();
  rcc_set_prescaler(RCC_PRESCALER_ADC, RCC_ADCPRE_PCLK_DIV_8);
   pinMode(PA6, INPUT_ANALOG);
  //pinMode(PA0, INPUT_ANALOG);
  pinMode(PA7, INPUT_ANALOG);
 // pinMode(PA3, INPUT_ANALOG);

  myADC.setSampleRate(ADC_SMPR_239_5);
  myADC.setScanMode();
  myADC.setPins(pins, 2);
  myADC.setContinuous();
  myADC.setDMA(dataPoints, 2, (DMA_MINC_MODE | DMA_CIRC_MODE), NULL);
  myADC.startConversion();

  //======================================================
  //EEPROM.read(500, (uint16*)&k);
  pinMode(Tup, INPUT_PULLDOWN);
  pinMode(Tdown, INPUT_PULLDOWN);
  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    readings[thisReading] = 0;
  }
  sampling_period_us = round(1000000 * (1.0 / SAMPLING_FREQUENCY));
}

void loop() {
  //================
  for (int j = 0; j < 10; j++) {
    sum1 = sum1 + dataPoints[0];
    sum2 = sum2 + dataPoints[1];
    delay(1);
  }
  //Serial.println(sum1/10);sum1=0;
  //Serial.println(sum2/10);sum2=0;
  ///////////////
  // Serial.print(sum1 / 10); sum1 = 0;
  // Serial.print("   ");
  // Serial.println(sum2 / 10); sum2 = 0;
  ////////////////
  //=================
  // no noise
  //----------------------------------------

  previousaverage = currentaverage;
  //**************************************************************************
  currentaverage = average;
  //if (abs(currentaverage -  previousaverage) <  previousaverage / 40 ) // 100 = 1%
  if (abs(currentaverage -  previousaverage) <  previousaverage / 25 ) // 100 = 1%

    //********************************************************************************
  {
    currentaverage = previousaverage;
  }
  //----------------------------------------

  /*SAMPLING*/
  for (int i = 0; i < SAMPLES1; i++)
  {
    microseconds = micros();    //Overflows after around 70 minutes!

    vReal[i] = analogRead(PB0);
    // vReal[i] = analogRead(PA6);
    vImag[i] = 0;

    while (micros() < (microseconds + sampling_period_us)) {
    }
  }

  /*FFT*/
  FFT.Windowing(vReal, SAMPLES1, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
  FFT.Compute(vReal, vImag, SAMPLES1, FFT_FORWARD);
  FFT.ComplexToMagnitude(vReal, vImag, SAMPLES1);
  double peak = FFT.MajorPeak(vReal, SAMPLES1, SAMPLING_FREQUENCY);
  ////////////////
  // subtract the last reading:
  total = total - readings[readIndex];
  // read from the sensor:
  //readings[readIndex] = analogRead(inputPin);
  readings[readIndex] = vReal[34];
  // add the reading to the total:
  total = total + readings[readIndex];
  // advance to the next position in the array:
  readIndex = readIndex + 1;

  // if we're at the end of the array...
  if (readIndex >= numReadings) {
    // ...wrap around to the beginning:
    readIndex = 0;
  }

  // calculate the average:
  average = total / numReadings;
  // send it to the computer as ASCII digits
  //Serial.println(average);
  delay(1);        // delay in between reads for stability
  ///////////////////
  // if (currentaverage > THRESHOLD)
  if (currentaverage > k)
  {
    digitalWrite(led, LOW);
    tone(piezoPin, 4000);
    //Serial.print(1000.0);
    Serial.print(300.0);

  }
  else
  {
    digitalWrite(led, HIGH);
    noTone(piezoPin);
    Serial.print(5.0);
  }
  /////////////////////
  if (digitalRead(Tup) == HIGH)

  {

    {
      k++;
    }
  }
  if (digitalRead(Tdown) == HIGH)
  {
    k--;
  }
  /////////////////
  /*PRINT RESULTS*/
  Serial.print(led);
  Serial.print(" ");
  Serial.print(average);
  Serial.print(" ");
  Serial.print(currentaverage);
  Serial.print(" ");
  //Serial.println(vReal[34], 1);//40=122.1kHz,  30=8.9, 35 = 10.6, 34 = 10.30kHz
  Serial.print(vReal[35], 1);
  //===================
  Serial.print(" ");
  Serial.print(sum1 / 10); sum1 = 0;
  Serial.print("   ");
  Serial.println(sum2 / 10); sum2 = 0;
  //===================
  /*
  lcd.print("   ");
  lcd.setCursor(0, 0);
  lcd.print("N ");
  //lcd.print(vReal[12], 1);// 10 - 3kHz, 12 =
  lcd.print(currentaverage);

  lcd.setCursor(0, 1);
  lcd.print("T ");
  //lcd.print(THRESHOLD);
  lcd.print(k);
  EEPROM.write(500, k);
  */
}

20

Re: Измерение напряжения STM32 (Arduino IDE)

Нашел проблему, вот она.

 
////////////////////////////////////////////////////////
 /*SAMPLING*/
  /*
    for (int t = 0; t < SAMPLES1; t++)
    {
    microseconds = micros();    

    vReal[t] = analogRead(PB0);
    vImag[t] = 0;

    while (micros() < (microseconds + sampling_period_us)) {
    }
    }

  */
//////////////////////////////////

Как исправить не знаю.

#include "arduinoFFT.h"
#include <LiquidCrystal.h>
//LiquidCrystal lcd(PB15, PB5, PA2, PB6, PB8, PB9);
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);
#include <EEPROM.h>
#define SAMPLES1 128
#define SAMPLING_FREQUENCY 40000
///////////////
int led = PC13;
const int numReadings = 10;
const float THRESHOLD = 500;
int piezoPin = PB6;
int readings[numReadings];      // the readings from the analog input
int readIndex = 0;              // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average
////////////////
int Tup = PB13;
int Tdown = PB15;
int k;
//int k<100;

arduinoFFT FFT = arduinoFFT();

unsigned int sampling_period_us;
unsigned long microseconds;

double vReal[SAMPLES1];
double vImag[SAMPLES1];
// no noise

int currentaverage = average;
int previousaverage = 0;


#include <STM32ADC.h>
STM32ADC myADC(ADC1);

uint8 pins[] = {PA6, PA7};
//uint8 pins[] = {PA0, PA7};
//uint8 pins[] = {PA0, PA3};

const int maxSamples = 2;
uint16_t dataPoints[maxSamples];
long sum1, sum2;

void setup() {


  Serial.begin(115200);
  lcd.begin( 16, 2 );
  //EEPROM.read(500, (uint16*)&k);
  pinMode(led, OUTPUT);
  pinMode(Tup, INPUT_PULLDOWN);
  pinMode(Tdown, INPUT_PULLDOWN);
  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    readings[thisReading] = 0;
  }
  sampling_period_us = round(1000000 * (1.0 / SAMPLING_FREQUENCY));

  myADC.calibrate();
  rcc_set_prescaler(RCC_PRESCALER_ADC, RCC_ADCPRE_PCLK_DIV_8);
  pinMode(PA6, INPUT_ANALOG);
  // pinMode(PA0, INPUT_ANALOG);
  pinMode(PA7, INPUT_ANALOG);
  // pinMode(PA3, INPUT_ANALOG);
  myADC.setSampleRate(ADC_SMPR_239_5);
  myADC.setScanMode();
  myADC.setPins(pins, 2);
  myADC.setContinuous();
  myADC.setDMA(dataPoints, 2, (DMA_MINC_MODE | DMA_CIRC_MODE), NULL);
  myADC.startConversion();
}

void loop() {
  // no noise


  previousaverage = currentaverage;
  //**************************************************************************
  currentaverage = average;
  //if (abs(currentaverage -  previousaverage) <  previousaverage / 40 ) // 100 = 1%
  if (abs(currentaverage -  previousaverage) <  previousaverage / 25 ) // 100 = 1%

    //********************************************************************************
  {
    currentaverage = previousaverage;
  }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  /*SAMPLING*/
  /*
    for (int t = 0; t < SAMPLES1; t++)
    {
    microseconds = micros();    //Overflows after around 70 minutes!

    vReal[t] = analogRead(PB0);
    vImag[t] = 0;

    while (micros() < (microseconds + sampling_period_us)) {
    }
    }
  */
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  /*FFT*/
  FFT.Windowing(vReal, SAMPLES1, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
  FFT.Compute(vReal, vImag, SAMPLES1, FFT_FORWARD);
  FFT.ComplexToMagnitude(vReal, vImag, SAMPLES1);
  double peak = FFT.MajorPeak(vReal, SAMPLES1, SAMPLING_FREQUENCY);
  ////////////////
  // subtract the last reading:
  total = total - readings[readIndex];
  // read from the sensor:
  //readings[readIndex] = analogRead(inputPin);
  readings[readIndex] = vReal[34];
  // add the reading to the total:
  total = total + readings[readIndex];
  // advance to the next position in the array:
  readIndex = readIndex + 1;

  // if we're at the end of the array...
  if (readIndex >= numReadings) {
    // ...wrap around to the beginning:
    readIndex = 0;
  }

  // calculate the average:
  average = total / numReadings;
  // send it to the computer as ASCII digits
  //Serial.println(average);
  delay(1);        // delay in between reads for stability
 
  // if (currentaverage > THRESHOLD)
  if (currentaverage > k)
  {
    digitalWrite(led, LOW);
    tone(piezoPin, 4000);
    // Serial.print(100.0);

  }
  else
  {
    digitalWrite(led, HIGH);
    noTone(piezoPin);
      //Serial.print(5.0);
  }

  if (digitalRead(Tup) == HIGH)

  {

    {
      k++;
    }
  }
  if (digitalRead(Tdown) == HIGH)
  {
    k--;
  }
 
  for (int j = 0; j < 10; j++) {
    sum1 = sum1 + dataPoints[0];
    sum2 = sum2 + dataPoints[1];
    delay(1);
  }
  
  Serial.print(sum1 / 10); sum1 = 0;
  Serial.print("   ");
  Serial.print(sum2 / 10); sum2 = 0;
  Serial.print("   ");
  Serial.print(led);
  Serial.print(" ");
  Serial.print(average);
  Serial.print(" ");
  Serial.print(currentaverage);
  Serial.print(" ");
  //Serial.println(vReal[34], 1);//40=122.1kHz,  30=8.9, 35 = 10.6, 34 = 10.30kHz
  Serial.println(vReal[35], 1);
 
}

21 (2021-01-18 05:46:58 отредактировано galina)

Re: Измерение напряжения STM32 (Arduino IDE)

Без этой строки PA6 и PA7 работают , но вольтметр переменного напряжения без PB0 не может работать.

 //  vReal[t] = analogRead(PB0);

22

Re: Измерение напряжения STM32 (Arduino IDE)

Напишите что за вольтметр переменного напряжения Вы делаете, какой у него принцип измерения?

23

Re: Измерение напряжения STM32 (Arduino IDE)

Вот оригинал,
https://www.norwegiancreations.com/2017 … n-arduino/

переделал  на одну частоту 10 кгц, в место i поставил номер бина

  Serial.println(vReal[35], 1);

добавил smoothing, но он работает не очень хорошо.

24

Re: Измерение напряжения STM32 (Arduino IDE)

Это все же анализатор спектра или вольтметр, я не совсем понимаю суть Вашего уст-ва.

25 (2021-01-18 18:07:15 отредактировано galina)

Re: Измерение напряжения STM32 (Arduino IDE)

Bins

The term bins is related to the result of the FFT, where every element in the result array is a bin. One can say this is the “resolution” of the FFT. Every bin represent a frequency interval, just like a histogram. The number of bins you get is half the amount of samples spanning the frequency range from zero to half the sampling rate.

Аудио диапазон 0 - 20 кнц  делится на бинс , используем только один бин и получаем селективный измеритель на одну частоту. = Serial.println(vReal[35], 1); = бин #35

Весь диапазон  = Serial.println(vReal[t], 1); = анализатор спектра

Найден тег без соответствующего = поменял i на т