Проблема с функцией if

gena321
Offline
Зарегистрирован: 19.01.2019
Доброе утро.
Проблема с функцией if, кнопка PB9, строки # 186 - 204.
Программа - генератор синуса с с регулировкой  амплитуды, кнопки PB13 и PB15, выход генератора PB7 подключен к входу измерителя переменного напряжения PА7  .
После установки напряжения 2,5 В нажмаем  PB9, и напряжение должно регулироваться до  1 В.
 
проблема
1. После нажатия и отпускания кнопки PB9 напряжение снижается до нуля и увеличивается до 3,3 В. - после отпуска регулировка должна прекратиться.
2. После нажатия и не отпускания PB9, напряжение снижается до 0,4 В. - Должно остановиться на 1В.
 
#include <LiquidCrystal.h>
#include "EmonLib.h"
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);
EnergyMonitor emon1;
#define SAMPLES 57
#define DEBOUNCE_DELAY 10
#define DEBOUNCE_IDLE 0
#define DEBOUNCE_ACTIVE 1
#include <libmaple/dma.h>


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


dma_tube_config dma_cfg, dma_cfg2;


int flag1 = 0;
int flag2 = 0;
int out1 = PB7;
int out2 = PA8;
int val1[SAMPLES];
int val2[SAMPLES];
int ampp = PB13;
int ampn = PB15;


int16 shift = 0;


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


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


void fun()
{
  flag1++;
}


void fun2()
{
  flag2++;
}


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);


  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()
{


  /* 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_CH4, fun);


  dma_enable(DMA1, DMA_CH4);
  timer_resume(dev1);


  dma_attach_interrupt(DMA1, DMA_CH2, fun2);


  dma_enable(DMA1, DMA_CH2);
  timer_resume(dev2);
}


void init_wave()
{
  int i;
  for (i = 0; i < SAMPLES; i++)
  {
    val1[i] = 50 + amp * sin(stp * i);
    val2[i] = val1[i];
  }
}


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() {
  ////////////
  pinMode(PB9, INPUT_PULLDOWN);
  pinMode(PA7, INPUT);    // Irms
  ////////////
  int i;
  pinMode(out1, PWM);
  pinMode(out2, PWM);
  pinMode(ampp, INPUT_PULLDOWN);
  pinMode(ampn, INPUT_PULLDOWN);


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


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


  Serial.begin(9600);
  ///////////////
  lcd.begin(16, 2);
  emon1.current(PA7, 2.8);
  //////////////


  timer_conf();
  dma_conf();
  dma_start();
  init_wave();
  get_wave(shift);


}


void loop() {


  emon1.calcVI(20, 2);
  float Irms = emon1.Irms;


  /////////////
  if (digitalRead(PB9) == HIGH)
  {
    if (Irms > 1.0)
    {
      ampn--;
      //ampp--;
      // amp--;
      delay (100);
    }
    else
    {
      ampn++;
      //ampp++;
      // amp++;
      delay (100);
    }
  }
  //////////////////


  lcd.setCursor(0, 1);
  lcd.print("U=");
  lcd.print(Irms);


  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;
  }
}

 

 

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

gena321 пишет:

проблема
1. После нажатия и отпускания кнопки PB9 напряжение снижается до нуля и увеличивается до 3,3 В. - после отпуска регулировка должна прекратиться.
2. После нажатия и не отпускания PB9, напряжение снижается до 0,4 В. - Должно остановиться на 1В.

Спасибо за информацию, будем иметь ввиду. 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

if - это не функция, а оператор языка. Точнее - statement.

kalapanga
Offline
Зарегистрирован: 23.10.2016

gena321, Вы бы к автору скетча обратились, если что-то в нём доработать нужно. А то в указанных строчках Вы что-то совсем не дело написали. Переменная ampn вроде как номер пина содержит, и чего Вы хотите добиться усиленно её инкрементируя/декрементируя?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

gena321 пишет:

Проблема с функцией if

В скетче нет функции if и быть не может, т.к. if - зарезервированное слово и им нельзя называть функции. Трудно решать проблему с чем-то, чего в природе не существует.

gena321
Offline
Зарегистрирован: 19.01.2019
Проблема не в названии функция или statement а в том что программа не реагитет на строку -  if (Irms > 1.0)
Вот сдесь всё работает правельно.  
 
HardwareTimer pwmtimer4(4);
#include "EmonLib.h"
#include <LiquidCrystal.h>
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);
EnergyMonitor emon1;
int i ;
int ovfi;
//int Irms ;


void setup()
{
  pwmtimer4.pause();
  pwmtimer4.setPrescaleFactor(1);
  pwmtimer4.setOverflow(5900);
  //pwmtimer4.setCompare(TIMER_CH2, 2880);
  pwmtimer4.refresh();
  pwmtimer4.resume();


  pinMode(PB7, PWM); //duty regulated for balance
  pinMode(PB9, INPUT_PULLDOWN);
  pinMode(PA7, INPUT);    // Irms
  lcd.begin(16, 2);


  emon1.current(PA7, 2.8);
}


void loop()
{
  ovfi = 1000 - i;
  pwmtimer4.setCompare(TIMER_CH2, i);
  emon1.calcVI(20, 2);
  float Irms = emon1.Irms;


  if (digitalRead(PB9) == HIGH)
  {
    if (Irms > 0.1)  //0.09=i=95=V 0.1_ 0.05=i=62 V=0.06, _0.03=i= missing 0.03V
      //0.08ok,
    {
      i--;
       //digitalWrite(PA10, HIGH);
      delay (100);
    }
    else
    {
      i++;
      // digitalWrite(PC13, HIGH);
      delay (100);
    }
  }
  lcd.setCursor(0, 0);
  lcd.print("V=");
  lcd.print(Irms);
  lcd.setCursor(0, 1);
  lcd.print("I=");
  lcd.print( i);
  //delay (50);


}

 

 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

gena321 пишет:

 
Вот сдесь всё работает правельно.  
 

Спасибо, будем иметь в виду. Держите нас в курсе.

b707
Offline
Зарегистрирован: 26.05.2017

gena321 пишет:

Проблема не в названии функция или statement а в том что программа не реагитет на строку

if (Irms > 1.0)

ошибаетесь, проблема вовсе не в этом. Проблема в вашем отношении к ошибкам.

Компьютер (и контроллер) - это железки. Они работают строго по программе. Компьютер не может устать и пойти по более легкому пути. Поэтому жалобы новичков, что программа вдруг "не реагирует на оператор IF" или в ней "зависает цикл for" -  только выставляют их самих в глупом свете.

Запомните - в любых проблемах в программе всегда виноват программист!

В вашем случае то, что "программа не реагитет на строку -  if (Irms > 1.0)" - может быть только по двум причинам:

Первое - работа кода никогда не доходит до этой строки.

Второе - значение Irms никогда не превышвет 1.0

Вот в соответствии с этим и ищите, в чем причина. Самое простое - вставить непосредственно перед этой строчкой вывод значения Irms в монитор и посмотреть, будет ли он выводится вообще - а если да - с какими значениями

 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

b707 пишет:

Запомните - в любых проблемах в программе всегда виноват программист!

Да начнётся холивар! А я вот тебе скажу, как на духу - не всегда виноват программист. Кто виноват, если опорное напряжение 3.3В, расчёты относительно опорного, а датчик подключили - с 5В логикой, без согласования уровней? Программа при этом выдаёт неправильные значения, с точки зрения пользователя, который пырится на экран - проблема именно в программе.

З.Ы. Просто вот совсем недавно с этим столкнулся, аж пичот и пригорает до сих пор.

b707
Offline
Зарегистрирован: 26.05.2017

DIYMan пишет:

 А я вот тебе скажу, как на духу - не всегда виноват программист.

В любом случае виноват человек, но не всегда он зовется программистом :)

Цитата:
Кто виноват, если опорное напряжение 3.3В, расчёты относительно опорного, а датчик подключили - с 5В логикой, без согласования уровней?

ну а кто виноват? - датчик? или ардуина? :) - нет, кто датчик подключил. тот и виноват...

gena321
Offline
Зарегистрирован: 19.01.2019

b707 пишет:

gena321 пишет:

Проблема не в названии функция или statement а в том что программа не реагитет на строку

if (Irms > 1.0)

ошибаетесь, проблема вовсе не в этом. Проблема в вашем отношении к ошибкам.

Компьютер (и контроллер) - это железки. Они работают строго по программе. Компьютер не может устать и пойти по более легкому пути. Поэтому жалобы новичков, что программа вдруг "не реагирует на оператор IF" или в ней "зависает цикл for" -  только выставляют их самих в глупом свете.

Запомните - в любых проблемах в программе всегда виноват программист!

В вашем случае то, что "программа не реагитет на строку -  if (Irms > 1.0)" - может быть только по двум причинам:

Первое - работа кода никогда не доходит до этой строки.

Второе - значение Irms никогда не превышвет 1.0

Вот в соответствии с этим и ищите, в чем причина. Самое простое - вставить непосредственно перед этой строчкой вывод значения Irms в монитор и посмотреть, будет ли он выводится вообще - а если да - с какими значениями

 

Строка #209 в место сериал монитор,

b707
Offline
Зарегистрирован: 26.05.2017

gena321 пишет:

Строка #209 в место сериал монитор,

я не понимаю - вы разобраться хотите или поспорить? Строка 209 не там - и потому не показательна. Поместите вывод Irms на печать, причем лучше не на экран. а именно в монитор порта - непосредственно перед условием if, внутри предыдущего условия

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

gena321 пишет:

Проблема не в названии функция или statement

Конечно не в этом. Проблема в том, что Вы садитесь за руль не отличая газа от тормоза берётесь программировать не отличая оператора от функции.

Я же не предлагаю Вам уметь Гегеля от Бабеля отличать, но хотя бы между кабелем и кобелём разницу то понимать надо!

gena321
Offline
Зарегистрирован: 19.01.2019

b707 пишет:

gena321 пишет:

Строка #209 в место сериал монитор,

я не понимаю - вы разобраться хотите или поспорить? Строка 209 не там - и потому не показательна. Поместите вывод Irms на печать, причем лучше не на экран. а именно в монитор порта - непосредственно перед условием if, внутри предыдущего условия

Подключил  сериал монитор, он показывает тоже самое что ЛСД.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

gena321 пишет:

Подключил  сериал монитор, он показывает тоже самое что ЛСД.

ЛСД это серьёзно. И статья за него серьёзная. Если Вы такое употребляете, то лучше не говорите об этом вслух.

b707
Offline
Зарегистрирован: 26.05.2017

gena321 пишет:

Подключил  сериал монитор, он показывает тоже самое что ЛСД.

Гена, вы я вижу решать проблему не хотите - ну это ваше дело.

Удачи

gena321
Offline
Зарегистрирован: 19.01.2019

Проблему то  решил, не так как хотел но работает, видимо что в место 

 ampn++;

  //ampp++;

 // amp++;

 должен исполсовать что то другое, но пока не знаю что.

Сделал так 

double Irms = emon1.calcIrms(1480);  // Calculate Irms only
  Serial.println(Irms);
  if (digitalRead(PB9) == HIGH)
  {
    if (Irms > 0.5)
    {
      digitalWrite(PC13, HIGH);
      //ampn--;
      //ampp--;
      // amp--;
      delay (100);
    }
    else
    {
      digitalWrite(PC13, LOW);
      //ampn++;
      //ampp++;
      // amp++;
      delay (100);
    }
  }

И перемычка PC13 - PB13

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

gena321 пишет:

И перемычка PC13 - PB13

Ну, раз так, тогда понятно.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Женя и Б707, Дорогие! Вы не помните этот ник и этот код?? Этот код ходит по форуму, сколько себя помню. Комбинация этого кода и этого ника (в вариантах Тед и Вед) возникает с интервалами в несколько месяцев с одинаковыми вопросами. Периодика, как я понимаю, обусловлена медицинскими причинами.  Я как-то попался и долго что-то втолковывал одному из перечисленных ников.