Generator amplitude

ted
Wed Jun 06, 2018 6:04 pm
Hi
This is a program for sine generator and AC voltmeter, how to make amplitude of the generator the same as measured ?
By changing the number of – amp = 35 – I can change amplitude of thegenerator manualy.
I was tryimg to use amp = volt, but is not working, between forward slash lines is the part related to amplitude.
When measured amplitude is changing amplitude of the generator is not.
Any help ?
Thanks.

#define SAMPLES 100
#include <libmaple/dma.h>
#include <LiquidCrystal.h> // TM
#include "EmonLib.h"
#include <math.h>
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);
EnergyMonitor emon1, emon2, emon3; //TM

float volt, avolt[50], sumv, volt2, avolt2[50], sumv2, powerFactor, apowerFactor[50], sumPF, catchPF, cur, acur[50], sumc, volt3;
char symbPF = 223;
dma_tube_config dma_cfg, dma_cfg2;
int flag1 = 0;
int out1 = PB7;
int val1[SAMPLES];

int16 shift = 0;
///////////////////////////////////
int amp = 35;
//int amp = volt;

/////////////////////////////////////
int cnt = 0;
int time_track = 0;
float stp = 6.2831 / SAMPLES;
int ret = 17;
timer_dev *dev1 = PIN_MAP[out1].timer_device;
uint8 cc_channel1 = PIN_MAP[out1].timer_channel;

void timer_conf()
{
timer_dma_set_base_addr(dev1, TIMER_DMA_BASE_CCR2);
timer_dma_set_burst_len(dev1, 1);
timer_dma_enable_req(dev1, cc_channel1);
timer_set_reload(dev1, 102);
timer_set_prescaler(dev1, 0);
}

void dma_conf()
{
dma_init(DMA1);
/* T4C2 DMA C4 */
dma_cfg.tube_dst = &(dev1->regs.gen->DMAR);
dma_cfg.tube_dst_size = DMA_SIZE_32BITS;
dma_cfg.tube_src = val1;
dma_cfg.tube_src_size = DMA_SIZE_32BITS;
dma_cfg.tube_nr_xfers = SAMPLES;
dma_cfg.tube_flags = DMA_CFG_SRC_INC | DMA_CFG_CIRC | DMA_CFG_CMPLT_IE;
dma_cfg.tube_req_src = DMA_REQ_SRC_TIM4_CH2;
dma_cfg.target_data = 0;

ret = dma_tube_cfg(DMA1, DMA_CH4, &dma_cfg);
}

void dma_start()
{
dma_enable(DMA1, DMA_CH4);
timer_resume(dev1);
}
///////////////////////////////////////////////////
void init_wave()
{
int i;
for (i = 0; i < SAMPLES; i++)
{
val1[i] = 50 + amp * sin(stp * i);

}
}
//////////////////////////////////////////////////////////
void setup() {
int i;
pinMode(out1, PWM);
pinMode(PA7, INPUT); // U

lcd.begin(16, 2); // set up the LCD’s number of columns and rows:
emon1.voltage(PA6, 3000, 1.7); // Voltage: input pin, calibration, phase_shift U1
emon2.voltage(PA7, 3000, 1.7);
emon1.current(PA7, 111.1); // Current

Serial.begin(9600);
timer_conf();
dma_conf();
dma_start();
init_wave();
}

void loop() {
sumv = 0;

for (int i = 0; i < 50; i++)
{
emon1.calcVI(20, 200); // Calculate all. No.of half wavelengths (crossings), time-out TM
emon2.calcVI(20, 200);
avolt[i] = emon1.Vrms; // holds volt value
}
for (int i = 0; i < 50; i++)
{
sumv += avolt[i];
}
volt = sumv / 50;
lcd.setCursor(0, 1);
lcd.print("U=");
lcd.print(volt);
}


Pito
Wed Jun 06, 2018 6:55 pm
Provided you want to generate an “N”-point (i=0..N-1) sinus wave with amplitude “ampl” and frequency “freq” and DC offset “dcoff”, you have to do it like
val1[i] = dcoff + ampl * sin((2.0 * pi * freq * i)/N);

ted
Wed Jun 06, 2018 7:50 pm
I want generator to follow with the amplitude of applied signal to PA7 “0-3.3V” – LCD is displaying that
The output is PWM on pin PB7

Pito
Wed Jun 06, 2018 9:19 pm
float amp = analogRead(PA7); // you get 0 - 4095 for 0.0 - 3.3V on PA7
amp = amp * (3.3/4095); // amp in Volts, 3.3 is the 12bit ADC reference voltage

ted
Wed Jun 06, 2018 10:31 pm
This I understand.
I want.
When measured signal is 1V I want the program to change amplitude of the generator to 1V, when measurement is 3V the program will make amplitude of the generator also 3V

zmemw16
Thu Jun 07, 2018 7:31 am
float volt, avolt[50], sumv, volt2, avolt2[50], sumv2, powerFactor, apowerFactor[50], sumPF, catchPF, cur, acur[50], sumc, volt3;

///////////////////////////////////
int amp = 35;
//int amp = volt;


ted
Thu Jun 07, 2018 3:56 pm
Can you explain that ?

Actually only this part is used for meter
float volt, avolt[50], sumv;


ted
Thu Jun 07, 2018 3:59 pm
I also tried this – still not working
val1[i] = 50 + avolt* sin(stp * i);

zmemw16
Thu Jun 07, 2018 5:10 pm
it was written as a query / comment on the first attempt (commented it out as it didn’t work). i knew something was odd, forgotten this.
no idea if so, but if volt only ranges 0.0 to 0.99, all you’ll get is 0

google
Assigning a float to an int
A float value can be assigned to an integer variable but an implicit conversion occurs when compiler forces a float value to be assigned as an integer. The digits after the decimal notation in the float value get lost after assigning a float to an integer.23 Jul 2014

curiously that was my 60th :D
stephen


ted
Sat Jun 09, 2018 12:10 am
Here is updated program, amplitude can be controlled by buttons on pins PB6 and PB9.
Voltmeter is disabled, the goal is; disable the buttons and the function of them should be replaced by voltmeter. Whatever voltmeter amplitude is shows on LCD, U = xxx ,
thesame amplitude should have generator.

#define SAMPLES 92

#define DEBOUNCE_DELAY 10
#define DEBOUNCE_IDLE 0
#define DEBOUNCE_ACTIVE 1

#include <libmaple/dma.h>

#include <LiquidCrystal.h>
#include "EmonLib.h"
#include <math.h>
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);
EnergyMonitor emon1, emon2, emon3;
float volt, avolt[50], sumv;
char symbPF = 223;

struct debounce_info
{
int start, state;
int16 shift;
}
up, down;

dma_tube_config dma_cfg, dma_cfg2;

int flag2 = 0;
int out2 = PA8;

int val1[SAMPLES];
int val2[SAMPLES];
//////////////////////////////
int ampp = PB9;
int ampn = PB6;
//////////////////////////////
int16 shift = 0;

int amp = 35;
int cnt = 0;
int time_track = 0;
float stp = 6.2831 / SAMPLES;
int ret = 17;

timer_dev *dev2 = PIN_MAP[out2].timer_device;
uint8 cc_channel2 = PIN_MAP[out2].timer_channel;

void fun2()
{
flag2++;
}

void timer_conf()
{
timer_dma_set_base_addr(dev2, TIMER_DMA_BASE_CCR1);
timer_dma_set_burst_len(dev2, 1);
timer_dma_enable_req(dev2, cc_channel2);
timer_set_reload(dev2, 102);
timer_set_prescaler(dev2, 0);
}

void dma_conf()
{
dma_init(DMA1);

/* T1C1 DMA C2 */
dma_cfg.tube_dst = &(dev2->regs.gen->DMAR);
dma_cfg.tube_dst_size = DMA_SIZE_32BITS;
dma_cfg.tube_src = val2;
dma_cfg.tube_src_size = DMA_SIZE_32BITS;

dma_cfg.tube_nr_xfers = SAMPLES;
dma_cfg.tube_flags = DMA_CFG_SRC_INC | DMA_CFG_CIRC | DMA_CFG_CMPLT_IE;

dma_cfg.tube_req_src = DMA_REQ_SRC_TIM1_CH1;
dma_cfg.target_data = 0;

ret = dma_tube_cfg(DMA1, DMA_CH2, &dma_cfg);
}

void dma_start()
{
dma_attach_interrupt(DMA1, DMA_CH2, fun2);
dma_enable(DMA1, DMA_CH2);
timer_resume(dev2);
}

void get_wave(int16 shift)
{
int i;
for (i = 0; i < SAMPLES; i++)
{
val2[i] = 50 + amp * sin( stp * i + shift * 0.1 * 6.2831 / 360);
}
}

void setup() {

int i;
pinMode(PA7, INPUT); // U
pinMode(out2, PWM);
pinMode(ampp, INPUT_PULLDOWN);
pinMode(ampn, INPUT_PULLDOWN);

memset(&up, 0, sizeof(debounce_info));
memset(&down, 0, sizeof(debounce_info));

up.shift = 1;
down.shift = -1;

lcd.begin(16, 2); // set up the LCD’s number of columns and rows:
emon1.voltage(PA6, 3000, 1.7); // Voltage: input pin, calibration, phase_shift U1
emon2.voltage(PA7, 3000, 1.7);
emon1.current(PA7, 111.1);

Serial.begin(9600);

timer_conf();
dma_conf();
dma_start();

get_wave(shift);

}

void loop() {
/*
/////////////////////////////////////
sumv = 0;

for (int i = 0; i < 50; i++)
{
emon1.calcVI(20, 200); // Calculate all. No.of half wavelengths (crossings), time-out TM
emon2.calcVI(20, 200);
avolt[i] = emon1.Vrms; // holds volt value
}
for (int i = 0; i < 50; i++)
{
sumv += avolt[i];
}
volt = sumv / 50;
lcd.setCursor(0, 1);
lcd.print("U=");
lcd.print(volt);
/////////////////////////////////////
*/

process_key_amp(digitalRead(ampp), &up);
process_key_amp(digitalRead(ampn), &down);
delay(100);

}

void process_key_amp(int val, struct debounce_info *k)
{
switch (k->state)
{
case DEBOUNCE_IDLE:
if (val == HIGH)
{
k->state = DEBOUNCE_ACTIVE;
k->start = millis();
}
break;

case DEBOUNCE_ACTIVE:
if (val == HIGH)
{
if (millis() - k->start > DEBOUNCE_DELAY)
{
amp += (int)k->shift;
get_wave(shift);
}
}
else
k->state = DEBOUNCE_IDLE;

break;

}
}


ted
Sat Jun 09, 2018 8:30 am
Which function to use ?

Amplitude of generator depends to “int amp = 35;”
How to change that to make it depending to ” lcd.print(volt);”
“float amp = volt; ” is not working.
Which command is proper to use ?


Pito
Sat Jun 09, 2018 8:52 am
“float amp = volt; ” is not working.
What does it mean?
Do you handle the “volt” and “amp” variables at the right places in your source?
Try

// TED's issue with "int amp = float volt"

float volt = 0.0; // or any value like 10.0, 50.0, 1000.0 ..
int amp;

void setup()
{
delay(2000);
Serial.begin();
}

void loop()
{
volt = volt + 10.0;
amp = volt;
float valx = 50 + amp * sin(1.5);
Serial.println(valx);
delay(1000);
}


ted
Sat Jun 09, 2018 9:30 am
This is what I did, obviously wrong, no signal on output, empty LCD.
Disabled lines are causing the errors.

#define SAMPLES 100
#include <libmaple/dma.h>
#include <LiquidCrystal.h> // TM
#include "EmonLib.h"
#include <math.h>
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);
EnergyMonitor emon1, emon2, emon3; //TM

//float volt, avolt[50], sumv;
char symbPF = 223;
dma_tube_config dma_cfg, dma_cfg2;
int flag1 = 0;
int out1 = PB7;
int val1[SAMPLES];

int16 shift = 0;
///////////////////////////////////
//int amp = 35;
//int amp = volt;
//float amp = volt;
/////////////////////////////////////
int cnt = 0;
int time_track = 0;
float stp = 6.2831 / SAMPLES;
int ret = 17;
timer_dev *dev1 = PIN_MAP[out1].timer_device;
uint8 cc_channel1 = PIN_MAP[out1].timer_channel;

void timer_conf()
{
timer_dma_set_base_addr(dev1, TIMER_DMA_BASE_CCR2);
timer_dma_set_burst_len(dev1, 1);
timer_dma_enable_req(dev1, cc_channel1);
timer_set_reload(dev1, 102);
timer_set_prescaler(dev1, 0);
}

void dma_conf()
{
dma_init(DMA1);
/* T4C2 DMA C4 */
dma_cfg.tube_dst = &(dev1->regs.gen->DMAR);
dma_cfg.tube_dst_size = DMA_SIZE_32BITS;
dma_cfg.tube_src = val1;
dma_cfg.tube_src_size = DMA_SIZE_32BITS;
dma_cfg.tube_nr_xfers = SAMPLES;
dma_cfg.tube_flags = DMA_CFG_SRC_INC | DMA_CFG_CIRC | DMA_CFG_CMPLT_IE;
dma_cfg.tube_req_src = DMA_REQ_SRC_TIM4_CH2;
dma_cfg.target_data = 0;

ret = dma_tube_cfg(DMA1, DMA_CH4, &dma_cfg);
}

void dma_start()
{
dma_enable(DMA1, DMA_CH4);
timer_resume(dev1);
}
/*
///////////////////////////////////////////////////
void init_wave()
{
int i;
for (i = 0; i < SAMPLES; i++)
{
val1[i] = 50 + amp * sin(stp * i);

}
}
//////////////////////////////////////////////////////////
*/
float volt = 0.0; // or any value like 10.0, 50.0, 1000.0 ..
/////////////////////////////////////
void setup() {
{
delay(2000);
Serial.begin();
}

int i;
pinMode(out1, PWM);
pinMode(PA7, INPUT); // U

lcd.begin(16, 2); // set up the LCD’s number of columns and rows:
emon1.voltage(PA6, 3000, 1.7); // Voltage: input pin, calibration, phase_shift U1
emon2.voltage(PA7, 3000, 1.7);
emon1.current(PA7, 111.1); // Current

Serial.begin(9600);
timer_conf();
dma_conf();
dma_start();
// init_wave();
}

void loop() {

volt = volt + 10.0;
int amp = volt;
float valx = 50.0 + amp * sin(1.5);
Serial.println(valx);
delay(1000);
// sumv = 0;

for (int i = 0; i < 50; i++)
{
emon1.calcVI(20, 200); // Calculate all. No.of half wavelengths (crossings), time-out TM
emon2.calcVI(20, 200);
// avolt[i] = emon1.Vrms; // holds volt value
}
for (int i = 0; i < 50; i++)
{
// sumv += avolt[i];
}
// volt = sumv / 50;
lcd.setCursor(0, 1);
lcd.print("U=");
lcd.print(volt);
}


Leave a Reply

Your email address will not be published. Required fields are marked *