Генератор для катушки Мишина

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

profinrus-1 пишет:
Ни кто не смотрит и не слушает первоисточник,от этого и рождаются не правильные выводы.

то, что наговорил он в 2016 и последующие годы сильно разнится

profinrus-1
Offline
Зарегистрирован: 10.07.2017

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

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

profinrus-1 пишет:
Правильно. В последних его видео,сказано что синус должен быть чистым!

при этом ТГА показал себя с лучшей стороны с бракованным блоком питания, когда уровень побочных был больше...так что только практика критерий истины...

profinrus-1
Offline
Зарегистрирован: 10.07.2017

Частный случай не истина в последней инстанции.
После прививки от кароны есть летальные случаи,но это не правило,а исключение.

AndreySS
Offline
Зарегистрирован: 15.10.2019

profinrus-1 пишет:
Частный случай не истина в последней инстанции. После прививки от кароны есть летальные случаи,но это не правило,а исключение.

Как сказать, из частного общее, из общего частное...

profinrus-1
Offline
Зарегистрирован: 10.07.2017

сделал ФАПЧ 

частоту держит,подстраивается в течении 1 сек,время на обновление частоты.

схема обросла CD4046 и LM393.

сдвоенный компаратор оказался нужен для согласования входных уровней CD4046

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

profinrus-1 пишет:

сделал ФАПЧ 

частоту держит,подстраивается в течении 1 сек,время на обновление частоты.

схема обросла CD4046 и LM393.

сдвоенный компаратор оказался нужен для согласования входных уровней CD4046

схема будет?
схема и скетч на основе nano, ina219, mcp4725, lcd0802, xr2206 и TDA будет как нарисуется, выложена тут же, теперь уже можно

profinrus-1
Offline
Зарегистрирован: 10.07.2017

XR2206 не будет.
Сделано на цифровом генераторе,как в исходнике.
Здесь уже всё реализовано.
Показывает частоту,ток,можно менять входное напряжение на TDA.
Есть таймер,что тоже не мало важно.
Сделано 15 мин,30,45 и 60.с обратным отсчетом
Схема и скетч конечно будет,но не скоро.
По крайней мере схему рисовать для меня проблематично,а скетч выложить,запросто.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

что-то не пойму как ты фапч наоборот работать заставил, хотелось бы схему, хотя бы структурно

profinrus-1
Offline
Зарегистрирован: 10.07.2017

ua6em пишет:

что-то не пойму как ты фапч наоборот работать заставил

я не понял,что значит наоборот работать заставил?

из скетча убрано сканирование частоты,а сделан генератор управляемый напряжением по внешнему аналоговому входу.всё остальное так же как и на ХР2206.

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Не пойму принцип, имеем: катушка - колебательный контур с резонансом (при t=20C)  на частоте 300кГц, при работе частота резонанса убегает вниз вследствии нагрева, как ФАПЧ отслеживает  и перестраивает частоту задающего генератора на этот выбег резонансной частоты контура?

profinrus-1
Offline
Зарегистрирован: 10.07.2017

любой уход частоты резонанса ведёт к рассогласованию по входам CD4046.

в свою очередь CD4046 на выходе понижает или повышает напряжение для управления ГУН.

ГУН меняет частоту до тех пор пока на входах CD4046 не станет одинаковая частота.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

profinrus-1 пишет:

любой уход частоты резонанса ведёт к рассогласованию по входам CD4046.

в свою очередь CD4046 на выходе понижает или повышает напряжение для управления ГУН.

ГУН меняет частоту до тех пор пока на входах CD4046 не станет одинаковая частота.

как работает фапч я представляю, выставляем к примеру контур настроеный на частоту 300кгц, фапч и будет удерживать эту частоту, а нам надо обратная задача подстраивать частоту под резонанс контура вот и не представляю как

profinrus-1
Offline
Зарегистрирован: 10.07.2017

ua6em пишет:

 

 выставляем к примеру контур настроеный на частоту 300кгц, фапч и будет удерживать эту частоту, 

так же и в резонансе

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

profinrus-1 пишет:

ua6em пишет:

 

 выставляем к примеру контур настроеный на частоту 300кгц, фапч и будет удерживать эту частоту, 

так же и в резонансе

так резонанс всё время плывёт, иногда даже скачет, не не пойму идеи

SAB
Offline
Зарегистрирован: 27.12.2016

Идея, как я понял, состоит в генераторе управляемом напряжением (ГУН). При резонансе будет максимальное напряжение, которое соответствует установленной частоте (300кГц). Схема будет всегда следить за тем, чтобы катушка всегда находилась в резонансе.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

по классике ФАПЧ применяется в системах, где от генератора требуется минимальное напряжение шумов и высокая стабильность...
то-есть от высокостабильного опорного подаём на один вход от регулируемого на второй с гуна напряжение на варикап регулируемого
да катушка это последовательный колебательный контур на резонансе напряжение будет минимальным

profinrus-1
Offline
Зарегистрирован: 10.07.2017

наверняка вы описываете радиоприёмник,здесь совсем не так.

здесь на один вход ФАПЧ подаётся напряжение с катушки,второй вход с ГУН,с него же на усилитель,цепь замкнулась.

https://x-faq.ru/index.php?topic=4030.940

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

profinrus-1 пишет:

наверняка вы описываете радиоприёмник,здесь совсем не так.

здесь на один вход ФАПЧ подаётся напряжение с катушки,второй вход с ГУН,с него же на усилитель,цепь замкнулась.

https://x-faq.ru/index.php?topic=4030.940

приёмо-передатчик, это генератор смесителя, работает на 300мегагерцах, потом умножитель до 10 гигагерц, с умножителя на смеситель куда приходит промежуточная 70 мегагерц, как-то так )))

profinrus-1
Offline
Зарегистрирован: 10.07.2017

ua6em пишет:

приёмо-передатчик, это генератор смесителя, работает на 300мегагерцах, потом умножитель до 10 гигагерц, с умножителя на смеситель куда приходит промежуточная 70 мегагерц, как-то так )))

я в радиоприёмниках не шарю!

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

profinrus-1 пишет:

ua6em пишет:

приёмо-передатчик, это генератор смесителя, работает на 300мегагерцах, потом умножитель до 10 гигагерц, с умножителя на смеситель куда приходит промежуточная 70 мегагерц, как-то так )))

я в радиоприёмниках не шарю!

я тоже )))

Опишите, как происходит поиск резонанса? ручками?

profinrus-1
Offline
Зарегистрирован: 10.07.2017

Я ссылку дал,там автор всё описывает.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

profinrus-1 пишет:
Я ссылку дал,там автор всё описывает.

а какой диапазон захвата по частоте получается, что-то не нашёл данных, кроме, что работает с любыми катушками

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

profinrus-1 пишет:
Я ссылку дал,там автор всё описывает.

а какой диапазон захвата по частоте получается, что-то не нашёл данных, кроме, что работает с любыми катушками

profinrus-1
Offline
Зарегистрирован: 10.07.2017

у автора от 100 кгц до 400 кгц

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

profinrus-1 пишет:

у автора от 100 кгц до 400 кгц

не анализировал, почему для регулирования частоты биполяр применяет, а не полевой кп-103 к примеру, у него ВАХ более точно вписывается в концепцию

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

profinrus-1 пишет:
XR2206 не будет. Сделано на цифровом генераторе,как в исходнике. Здесь уже всё реализовано. Показывает частоту,ток,можно менять входное напряжение на TDA. Есть таймер,что тоже не мало важно. Сделано 15 мин,30,45 и 60.с обратным отсчетом Схема и скетч конечно будет,но не скоро. По крайней мере схему рисовать для меня проблематично,а скетч выложить,запросто.

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

profinrus-1
Offline
Зарегистрирован: 10.07.2017

Это не радио. Здесь ничего этого нет, всё намного проще. В CD4046 гун не используется,в ней используется только компаратор. ГУНом  является AD9833 через ардуино,на вывод А7 подаётся напряжение управления с CD4046 .

profinrus-1
Offline
Зарегистрирован: 10.07.2017
// Генератор для катушки Мишина на основе DDS AD9833
// (c)UA6EM
/*
 * Версия от 12.06.2019 - Добавлено измерение напряжения, вывод на дисплей, установка
 * начальной частоты определённой в дефайне, если не найден резонанс катушки
 * - напряжение показывало отрицательное, ina219 был сконфигурирован на адрес 44, 
 * - поправил скетч пробовал в работе при запитке от USB, на Vin+ подавал +5V с ардуины
 * - вывод Vin- (ina219) нагрузил резистором 10 ком, напряжение показывает, ток - 0 )))
 *  
 *  - Версия от 22.06.2019 - Добавлен зуммер, работает через прерывание 1, 
 *                           формируется с частотой 490 герц
 * - добавлена библиотека модуля DAC для регулировки усиления, выставляет первичное
 *   значение на выходе модуля в 0.8 вольта (регулировка усиления TDA-7056) 
 * - Версия от 04.08.2019 - Добавлена процедура рассчета скользящего среднего (moving average)
 * - Версия от 17.11.2019 -Работа дисплея переведена на русифицированную библиотеку
 * - <a data-cke-saved-href="<a data-cke-saved-href="https://github.com/ssilver2007/LCD_1602_RUS" href="https://github.com/ssilver2007/LCD_1602_RUS" rel="nofollow">https://github.com/ssilver2007/LCD_1602_RUS</a>" href="<a data-cke-saved-href="https://github.com/ssilver2007/LCD_1602_RUS" href="https://github.com/ssilver2007/LCD_1602_RUS" rel="nofollow">https://github.com/ssilver2007/LCD_1602_RUS</a>" rel="nofollow"><a data-cke-saved-href="https://github.com/ssilver2007/LCD_1602_RUS" href="https://github.com/ssilver2007/LCD_1602_RUS" rel="nofollow">https://github.com/ssilver2007/LCD_1602_RUS</a></a> 
 * - добавлена функция обработки кнопок от QWONE
 * - <a data-cke-saved-href="<a data-cke-saved-href="http://arduino.ru/forum/programmirovanie/tsifrovye-avtomaty-v-klassakh-po-qwone#comment-385066" href="http://arduino.ru/forum/programmirovanie/tsifrovye-avtomaty-v-klassakh-po-qwone#comment-385066" rel="nofollow">http://arduino.ru/forum/programmirovanie/tsifrovye-avtomaty-v-klassakh-po-qwone#comment-385066</a>" href="<a data-cke-saved-href="http://arduino.ru/forum/programmirovanie/tsifrovye-avtomaty-v-klassakh-po-qwone#comment-385066" href="http://arduino.ru/forum/programmirovanie/tsifrovye-avtomaty-v-klassakh-po-qwone#comment-385066" rel="nofollow">http://arduino.ru/forum/programmirovanie/tsifrovye-avtomaty-v-klassakh-po-qwone#comment-385066</a>" rel="nofollow"><a data-cke-saved-href="http://arduino.ru/forum/programmirovanie/tsifrovye-avtomaty-v-klassakh-po-qwone#comment-385066" href="http://arduino.ru/forum/programmirovanie/tsifrovye-avtomaty-v-klassakh-po-qwone#comment-385066" rel="nofollow">http://arduino.ru/forum/programmirovanie/tsifrovye-avtomaty-v-klassakh-po-qwone#comment-385066</a></a>
 * 
 */
#define SECONDS(x) ((x) * 1000UL)
#define MINUTES(x)  (SECONDS(x) * 60UL)
#define HOURS(x)  (MINUTES(x) * 60UL)
#define DAYS(x)   (HOURS(x) * 24UL)
#define WEEKS(x)  (DAYS(x) * 7UL)
unsigned long interval = MINUTES(1);
unsigned long oneMinute = MINUTES(1);
unsigned long timers = MINUTES(5); // время таймера 15, 30, 45 или 60 минут 
unsigned long memTimers=0; //здесь будем хранить установленное время таймера
unsigned long oldmemTimers=0;
byte isTimers = 0; // флаг запуска таймера
byte selectedMenu = 1; // выбранное меню. 1 - напряжение, 2 - время

unsigned long timMillis = 0;
unsigned long oldMillis = 0;
unsigned long mill; // переменная под millis()
unsigned long prevCorrectTime = 0;

// переменные для измерения времени цикла
unsigned long t1;
unsigned long t2;
unsigned long ts1;
unsigned int ts2;
byte fts = 0;

#include <Wire.h>
#include <SPI.h>

#include <LCD_1602_RUS.h>               // <a data-cke-saved-href="<a data-cke-saved-href="https://github.com/ssilver2007/LCD_1602_RUS" href="https://github.com/ssilver2007/LCD_1602_RUS" rel="nofollow">https://github.com/ssilver2007/LCD_1602_RUS</a>" href="<a data-cke-saved-href="https://github.com/ssilver2007/LCD_1602_RUS" href="https://github.com/ssilver2007/LCD_1602_RUS" rel="nofollow">https://github.com/ssilver2007/LCD_1602_RUS</a>" rel="nofollow"><a data-cke-saved-href="https://github.com/ssilver2007/LCD_1602_RUS" href="https://github.com/ssilver2007/LCD_1602_RUS" rel="nofollow">https://github.com/ssilver2007/LCD_1602_RUS</a></a>
LCD_1602_RUS lcd(0x27, 20, 4);

#include "INA219.h"
INA219 ina219;

#define CORRECT_PIN A7 // пин для внешней корректировки частоты. 

//#define TWBR  //Зарезервировано для частоты обмена с DAC в 400Кгц
#include <Adafruit_MCP4725.h>
Adafruit_MCP4725 dac;
unsigned int dVolume = 837; // Напряжение на выходе DAC 
unsigned int dVolumeMax = 1850; // Максимальное напряжение, около 1.1В
unsigned int dVolumeMin = 400; // Минимальное напряжение, около 0.9В

#define PIN_ZUM 12  //  был 10 пин
#define pinINT1 3   // этот пин Шимим 490Гц 
#define zFreq 2     // делитель интервала - секунда/2

unsigned int imax = 0;
// unsigned int imin = 0;
unsigned int Data_ina219 = 0;
volatile float Voltage_ina219 = 0;

const int SINE = 0x2000;                    // определяем значение регистров AD9833 взависимости от формы сигнала
const int SQUARE = 0x2020;                  // После обновления частоты нужно определить форму сигнала
const int TRIANGLE = 0x2002;                // и произвести запись в регистр.
const float refFreq = 25000000.0;           // Частота кристалла на плате AD9833

#define Fdefine 300000
long Fmin = 50000;
long Fmax = 500000;
#define Ftune 10000
//int Ftune = 10000;
unsigned int di = (Fmax-Fmin)/Ftune -1;
long FFmax = 0;
long freq = Fmin;
long ifreq = Fdefine; // если не будет определена частота резонанса катушки, 
                      // то она установится в это значение
                      
//int Ffinetune = 200;
#define  Ffinetune 200
  
/*const int FSYNC = 10;                       // Standard SPI pins for the AD9833 waveform generator.
const int CLK = 13;                         // CLK and DATA pins are shared with the TFT display.
const int DATA = 11; 
*/
#define FSYNC 10
#define CLK 13
#define DATA 11
 byte myClock = 0;
 byte SetClock = 5;
 byte flagClock = 0;
 byte myBuzzer = 0;

const char toks[]PROGMEM  = "I = ";
const char freqs[]PROGMEM  = "Freq = ";
const char call[]PROGMEM  ="Generator AD9833";

const unsigned long availableTimers[] = {oneMinute * 15, oneMinute * 30, oneMinute * 45, oneMinute * 60};
const byte maxTimers = 4;
int timerPosition = 0;

 /********* используемые подпрограммы выносим сюда *********/

 /*** Обработчик кнопки энкодера ***/
//------Cl_Btn----------------------
enum {sbNONE = 0, sbClick, sbLong}; /*состояние не изменилось/клик/долгое нажатие*/
class Cl_Btn {
  protected:
    const byte pin;
    byte state;
    bool bounce = 0;
    bool btn = 1, oldBtn;
    unsigned long past;
    const uint32_t time = 500 ;
    bool flag = 0;
    uint32_t past_flag = 0 ;
  public:
    Cl_Btn(byte p): pin(p) {}
    /*инициализация-вставить в setup()*/
    void init() {
      pinMode(pin, INPUT_PULLUP);
    }
    /*работа-вставить в loop()*/
    void run() {
      state = sbNONE;
      bool newBtn = digitalRead(pin);
      if (!bounce && newBtn != btn) {
        bounce = 1;
        past = mill;
      }
      if (bounce && mill - past >= 10) {
        bounce = 0 ;
        oldBtn = btn;
        btn = newBtn;
        if (!btn && oldBtn) {
          flag = 1;
          past_flag = mill;
        }
        if (!oldBtn && btn && flag && mill - past_flag < time ) {
          flag = 0;
          state = sbClick;
        }
      }
      if (flag && mill - past_flag >= time ) {
        flag = 0;
        state = sbLong;
      }
    }
    byte read() {
      return state;
    }
};

Cl_Btn Btn1(/*пин*/8); //Экземпляр обработчика для кнопки энкодера

/******* Простой энкодер *******/
#include <util/atomic.h>        // для атомарности чтения данных в прерываниях
#include <RotaryEncoder.h>
RotaryEncoder encoder(6, 7);
volatile int newPos;
static int pos = 0;
/*** Обработчик прерывания для энкодера ***/
 ISR(PCINT2_vect) {encoder.tick();}

/*** Установка напряжения энкодером ***/
void setVoltage() {
  unsigned int newVoltage = dVolume + ((newPos-pos) * 10);
  if ((newVoltage < dVolumeMax) && (newVoltage > dVolumeMin)) {
    dVolume = newVoltage;
    dac.setVoltage(dVolume, true);
  }  
}
void setTimer() {
  if (newPos-pos > 0) {
    if (timerPosition == maxTimers - 1) {
      timerPosition = 0;
    } else {
      timerPosition += 1;
    }
  } else if (newPos - pos < 0) {
    if (timerPosition == 0) {
      timerPosition = maxTimers - 1;
    } else {
      timerPosition -= 1;
    }
  }
  memTimers = availableTimers[timerPosition];
}

/*** Обработчик энкодера через ШИМ ***/
void startEncoder(){
     attachInterrupt(1, Encoder2, RISING );
     analogWrite(3,0x80); //установим на пине частоту 
                                //490 гц скважность 2
 }
void Encoder2(void){ // процедура вызываемая прерыванием, пищим активным динамиком
     encoder.tick();    
} 

 /********* Таймер обратного отсчёта экспозиции **********/
unsigned long  setTimerLCD(unsigned long timlcd) {
  if(millis() - timMillis >=1000){
    timlcd = timlcd - 1000; 
    timMillis += 1000;
  }
  if(timlcd == 0){
    timlcd = oldmemTimers; 
    isTimers = 0;
     lcd.setCursor(0, 3); 
      lcd.print("     ЗАВЕРШЕНО!     ");
      start_Buzzer();
      delay(5000);
      stop_Buzzer();
      AD9833reset();
    }
  return timlcd;
 }
/*******************ПИЩАЛКА ********************/
void start_Buzzer(){
     pinMode(PIN_ZUM,OUTPUT);
     attachInterrupt(1, Buzzer, RISING );
 }

void stop_Buzzer(){
     detachInterrupt(1);
     digitalWrite(PIN_ZUM,LOW);
 }

void Buzzer(void){ // процедура вызываемая прерыванием, пищим активным динамиком
     static int i=490/zFreq;
     if(!i--)
     {
    digitalWrite(PIN_ZUM, ! digitalRead(PIN_ZUM));
    i=490/zFreq;
      }
} 

// ******************* Обработка AD9833 *********************** 
// AD9833 documentation advises a 'Reset' on first applying power.
void AD9833reset() {
  WriteRegister(0x100);   // Write '1' to AD9833 Control register bit D8.
   delay(10);
 }
  
// Set the frequency and waveform registers in the AD9833.
void AD9833setFrequency(long frequency, int Waveform) {
  long FreqWord = (frequency * pow(2, 28)) / refFreq;
  int MSB = (int)((FreqWord & 0xFFFC000) >> 14);    //Only lower 14 bits are used for data
  int LSB = (int)(FreqWord & 0x3FFF);
//Set control bits 15 ande 14 to 0 and 1, respectively, for frequency register 0
  LSB |= 0x4000;
  MSB |= 0x4000;
  WriteRegister(0x2100);
  WriteRegister(LSB);                  // Write lower 16 bits to AD9833 registers
  WriteRegister(MSB);                  // Write upper 16 bits to AD9833 registers.
  WriteRegister(0xC000);               // Phase register
  WriteRegister(Waveform);             // Exit & Reset to SINE, SQUARE or TRIANGLE
 }

// *************************
// Display and AD9833 use different SPI MODES so it has to be set for the AD9833 here.
 void WriteRegister(int dat) {
 SPI.setDataMode(SPI_MODE2);
 digitalWrite(FSYNC, LOW);           // Set FSYNC low before writing to AD9833 registers
 delayMicroseconds(10);              // Give AD9833 time to get ready to receive data.
 SPI.transfer(highByte(dat));        // Each AD9833 register is 32 bits wide and each 16
 SPI.transfer(lowByte(dat));         // bits has to be transferred as 2 x 8-bit bytes.
  digitalWrite(FSYNC, HIGH);          //Write done. Set FSYNC high
}

//**** Процедура грубой настройки частоты по максимальному току ***/
void setFreq(){
  for (unsigned int i=1; i <= di; i++) {
    Data_ina219=ina219.shuntCurrent() * 1000; 
    if (Data_ina219 > imax){ 
      imax=Data_ina219; 
      ifreq = freq; 
    } // Если значение больше, то запомнить
    if (freq >=Fmax) {
      freq = Fmax;
    }
    freq=freq+Ftune;
    AD9833setFrequency(freq, SINE);
    delay(20);
  } 
}

/*** Процедура тонкой настройки частоты по максимальному току ***/
void setFFreq(){
  for (int j=1; j <= 100; j++) {
    Data_ina219=ina219.shuntCurrent() * 1000; 
    if (Data_ina219 > imax) { 
      imax=Data_ina219; 
      ifreq = freq; 
    } // Если значение больше, то запомнить
    freq=freq+Ffinetune;
    if (freq >=FFmax) {
      freq = FFmax;
    } 
    AD9833setFrequency(freq, SINE);
    delay(20);
  } 
}

// читает значение аналогового входа и на основе него высчитывает новую частоту
void readVoltageAndCorrectFreq() {
  unsigned long curr = millis();

  // раз в секунду корректируем частоту
  if (curr - prevCorrectTime > 1000) {
    int value = analogRead(CORRECT_PIN);
    float minFreq = 200000; // 200kHz
    float maxFreq = 500000; // 400kHz
    float oneHzStep = (maxFreq - minFreq) / 1024; // ~195Hz. При смене значения на аналоговом входе на 1 единицу, частота будет меняться на 195Гц
    //float newFreq = (oneHzStep * value) + minFreq;//
    float newFreq = maxFreq - (oneHzStep * value);
    ifreq = newFreq;
    AD9833setFrequency(ifreq, SINE);
    prevCorrectTime = millis();
  }
}

//************************** SETUP *************************/
void setup() { 
  Btn1.init();
  SPI.begin();
  Serial.begin(115200);
  
  pinMode(PIN_ZUM, OUTPUT);
  pinMode(CORRECT_PIN, INPUT);
  
  dac.begin(0x60);               
  dac.setVoltage(dVolume, true);  
  lcd.begin();
  lcd.backlight();
  delay(10);   
  ina219.begin(0x40); // (44) i2c address 64=0x40 68=0х44 исправлять и в ina219.h одновременно
  ina219.configure(0, 2, 12, 12, 7); // 16S -8.51ms
  ina219.calibrate(0.100, 0.32, 16, 3.2); 
  AD9833reset();                   // Ресет после включения питания
  delay(10);
  AD9833setFrequency(freq, SINE);  // выставляем нижнюю частоту
  setFreq();
  Serial.print("freq=");
  Serial.println(freq);
  freq = ifreq-10000;
  FFmax =ifreq +10000;
  imax = 0;
  AD9833setFrequency(freq, SINE); 
  setFFreq();
  Serial.print("ffreq=");
  Serial.println(ifreq);
  AD9833setFrequency(ifreq, SINE); // выставляем частоту максимального тока
  Data_ina219=ina219.shuntCurrent() * 1000; 
  Voltage_ina219 = ina219.busVoltage();
  myDisplay();
  delay(1000);
  PCICR |= (1 << PCIE2); // инициализируем порты для энкодера
  PCMSK2 |= (1 << PCINT20) | (1 << PCINT21);
  startEncoder(); 
  
  memTimers = availableTimers[0]; // выставляем 15 минут по умолчанию
}    // Конец процедуры инициализации прибора
  

// *** ТЕЛО ПРОГРАММЫ ***
void loop() {
    mill = millis();
    Btn1.run();
    
    // если обычное нажатие на кнопку, то перелистываем пункты меню
    if (Btn1.read() == sbClick){
      if (selectedMenu == 2) {
        selectedMenu = 1;
      } else {
        selectedMenu += 1;
      }
    }

    if (Btn1.read() == sbLong){
      oldmemTimers=memTimers;
      timMillis = millis();
      isTimers=1;
    }

    Data_ina219=ina219.shuntCurrent() * 1000; 
    Voltage_ina219 = ina219.busVoltage();
    myDisplay();
       
    if(isTimers==1){
      memTimers = setTimerLCD(memTimers);
    }

    ATOMIC_BLOCK(ATOMIC_RESTORESTATE){
      newPos = encoder.getPosition();
    }
    
    if (pos != newPos) {
      if (selectedMenu == 1) {
        setVoltage();
      } else if (selectedMenu == 2 && !isTimers) {
        setTimer();
      }
      pos = newPos;
    } 
    myTESTloop();
    readVoltageAndCorrectFreq();
 } //END

 

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

код желательно спрятать под спойлер

profinrus-1
Offline
Зарегистрирован: 10.07.2017

Незнаю как.
Не стоит пока заниматься с этим скетчем и ваще с апч.
Очень не устойчиво работает,нужно отработать процедуру настройки.
В этом скетче сделана проверка частоты каждую одну секунду,плохо работает.
Сделал постоянную работу генератора,лучше но нужно ещё заниматься.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Сейчас продумываю добавить программный фазовый компаратор, в Лайф-Синусе он точно есть )))

ingfa
Offline
Зарегистрирован: 15.09.2018

А как ad9833 прикрутить к stm32f103c8t6? Используя Ардуино. А еще Возможно ли вместо измерителя тока на ina219 сделать измерение через ацп? Шунт через резюк 1 ом, или вообще у меня лежит ad8307.  

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ingfa пишет:

А как ad9833 прикрутить к stm32f103c8t6? Используя Ардуино. А еще Возможно ли вместо измерителя тока на ina219 сделать измерение через ацп? Шунт через резюк 1 ом, или вообще у меня лежит ad8307.  

видимо придётся почитать тут и по образу и подобию делать

ingfa
Offline
Зарегистрирован: 15.09.2018
#include <SPI.h>
//#define SPI3_NSS_PIN PB12   //SPI_2 Chip Select pin is PB12. You can change it to the STM32 pin you want.
//             mosi, miso, sclk, ssel
//SPIClass SPI_3(PB15, PB14, PB13, SPI3_NSS_PIN);
const int slaveSelectPin = 10;
const float refFreq = 25000000.0;
const int SINE = 0x2000;
const int SQUARE = 0x2028;                  // When we update the frequency, we need to
const int TRIANGLE = 0x2002;
byte data;

void setup() {
    // Setup SPI 2
  pinMode(PA4, OUTPUT);
  SPI.begin(); //Initialize the SPI_2 port.
  //SPI.setBitOrder(MSBFIRST); // Set the SPI_2 bit order
  //SPI.setDataMode(SPI_MODE0); //Set the  SPI_2 data mode 0
  //SPI.setClockDivider(SPI_CLOCK_DIV16);  // Use a different speed to SPI 1
  AD9833reset();                                   
  delay(50);
  
}

void loop() {
  AD9833reset();                                   
  delay(50);
  AD9833setFrequency(1000, SINE);
  delayMicroseconds(1000);    //Delay 10 micro seconds.
}




void AD9833reset() {
  WriteRegister(0x100);   // Write '1' to AD9833 Control register bit D8.
  delay(10);
}



// Set the frequency and waveform registers in the AD9833.
void AD9833setFrequency(long frequency, int Waveform) {

  long FreqWord = (frequency * pow(2, 28)) / refFreq;

  int MSB = (int)((FreqWord & 0xFFFC000) >> 14);    //Only lower 14 bits are used for data
  int LSB = (int)(FreqWord & 0x3FFF);

  //Set control bits 15 ande 14 to 0 and 1, respectively, for frequency register 0
  LSB |= 0x4000;
  MSB |= 0x4000;

  WriteRegister(0x2100);
  WriteRegister(LSB);                  // Write lower 16 bits to AD9833 registers
  WriteRegister(MSB);                  // Write upper 16 bits to AD9833 registers.
  WriteRegister(0xC000);               // Phase register
  WriteRegister(Waveform);             // Exit & Reset to SINE, SQUARE or TRIANGLE

}
void WriteRegister(int dat) {

  // Display and AD9833 use different SPI MODES so it has to be set for the AD9833 here.
  //SPI.setDataMode(SPI_MODE2);
  digitalWrite(PA4, LOW);           // Set FSYNC low before writing to AD9833 registers
  delayMicroseconds(10);              // Give AD9833 time to get ready to receive data.
  SPI.transfer(highByte(dat));        // Each AD9833 register is 32 bits wide and each 16
  SPI.transfer(lowByte(dat));         // bits has to be transferred as 2 x 8-bit bytes.
  digitalWrite(PA4, HIGH);          //Write done. Set FSYNC high
}

 

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

 

profinrus-1
Offline
Зарегистрирован: 10.07.2017

В чём была цель переделки?

ingfa
Offline
Зарегистрирован: 15.09.2018

У меня сейчас свободный только stm32f103c8t6

а примеров я не нашел в интернете, как прикрутить ad9833 к этому контроллеру

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

в строке 27 установлена частота 1000, тысячу и выдаёт )))

profinrus-1
Offline
Зарегистрирован: 10.07.2017

На стм32 можно сделать абсолютно всё,если уметь с ним работать.
У меня на нём сделан проект исключительной возможности,заказывал за отдельную плату,сам не шарю.

ingfa
Offline
Зарегистрирован: 15.09.2018

стоит 10 секунд, а выдает пол секунды, подключено к первому spi но вообще начинает работать только тогда 

define SPI1_NSS_PIN PA12, стоит только установить PA4, как вообще ничего не работает. генерации нет.

Хотя в примере написано И припаяно туда же на PA4.

 Using the first SPI port (SPI_1)
    SS    <-->  PA4 <-->  BOARD_SPI1_NSS_PIN
    SCK   <-->  PA5 <-->  BOARD_SPI1_SCK_PIN
    MISO  <-->  PA6 <-->  BOARD_SPI1_MISO_PIN
    MOSI  <-->  PA7 <-->  BOARD_SPI1_MOSI_PIN

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Оставлю здесь схему Световита

ingfa
Offline
Зарегистрирован: 15.09.2018

TDA7056а имеет выход
16 Ом, от чего на моей катушке
сопротивление, которой равно 2 омам,
очень сильно греется, поэтому я
просто взял и сделал согласующий
трансформатор на колечке с проницаемостью 1000
Пойдет и 2000 и 3000, рассчитал
его по формуле:
L = (4*r)/(2*пи*f)
Где L мкГн
R Ом
Пи 3,14
F в Мегагерцах

Катушка к тдашке 16 ом, катушка к
Кукушке мишина 2 ом, в результате
Ток 1А при 12 вольтах, но
Микросхема без радиатора градусов
40. Синус почти без искажений.
Средняя частота транса 0,3 Мгц

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

два ома что-то маловато, на проводе 0,5 ёмкость порядка 3000пф получается, катушка высокодобротная получилась, а так да использую TDA7056B она получше

AndreySS
Offline
Зарегистрирован: 15.10.2019

ua6em,вы ночью или утром были тут? А я не спал, пишу псевдо девятое видео про красоту момента, сплошной хаос и кругом система))rы

profinrus-1
Offline
Зарегистрирован: 10.07.2017

код тот что выкладывал выше

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Чтобы посмотреть почему резонанс не дотягивает до резонанса катушки нужен код, именно тот что сейчас используется, по идее не должно, максимальная частота для поиска резонанса выставлена в 500кгц судя по скетчу приведённому выше.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

profinrus-1 пишет:

код тот что выкладывал выше

тот код не компилируется даже

profinrus-1
Offline
Зарегистрирован: 10.07.2017
// Генератор для катушки Мишина на основе DDS AD9833
// (c)UA6EM
/*
 * Версия от 12.06.2019 - Добавлено измерение напряжения, вывод на дисплей, установка
 * начальной частоты определённой в дефайне, если не найден резонанс катушки
 * - напряжение показывало отрицательное, ina219 был сконфигурирован на адрес 44, 
 * - поправил скетч пробовал в работе при запитке от USB, на Vin+ подавал +5V с ардуины
 * - вывод Vin- (ina219) нагрузил резистором 10 ком, напряжение показывает, ток - 0 )))
 *  
 *  - Версия от 22.06.2019 - Добавлен зуммер, работает через прерывание 1, 
 *                           формируется с частотой 490 герц
 * - добавлена библиотека модуля DAC для регулировки усиления, выставляет первичное
 *   значение на выходе модуля в 0.8 вольта (регулировка усиления TDA-7056) 
 * - Версия от 04.08.2019 - Добавлена процедура рассчета скользящего среднего (moving average)
 * - Версия от 17.11.2019 -Работа дисплея переведена на русифицированную библиотеку
 * - <a data-cke-saved-href="<a data-cke-saved-href="https://github.com/ssilver2007/LCD_1602_RUS" href="https://github.com/ssilver2007/LCD_1602_RUS" rel="nofollow">https://github.com/ssilver2007/LCD_1602_RUS</a>" href="<a data-cke-saved-href="https://github.com/ssilver2007/LCD_1602_RUS" href="https://github.com/ssilver2007/LCD_1602_RUS" rel="nofollow">https://github.com/ssilver2007/LCD_1602_RUS</a>" rel="nofollow"><a data-cke-saved-href="https://github.com/ssilver2007/LCD_1602_RUS" href="https://github.com/ssilver2007/LCD_1602_RUS" rel="nofollow">https://github.com/ssilver2007/LCD_1602_RUS</a></a> 
 * - добавлена функция обработки кнопок от QWONE
 * - <a data-cke-saved-href="<a data-cke-saved-href="http://arduino.ru/forum/programmirovanie/tsifrovye-avtomaty-v-klassakh-po-qwone#comment-385066" href="http://arduino.ru/forum/programmirovanie/tsifrovye-avtomaty-v-klassakh-po-qwone#comment-385066" rel="nofollow">http://arduino.ru/forum/programmirovanie/tsifrovye-avtomaty-v-klassakh-po-qwone#comment-385066</a>" href="<a data-cke-saved-href="http://arduino.ru/forum/programmirovanie/tsifrovye-avtomaty-v-klassakh-po-qwone#comment-385066" href="http://arduino.ru/forum/programmirovanie/tsifrovye-avtomaty-v-klassakh-po-qwone#comment-385066" rel="nofollow">http://arduino.ru/forum/programmirovanie/tsifrovye-avtomaty-v-klassakh-po-qwone#comment-385066</a>" rel="nofollow"><a data-cke-saved-href="http://arduino.ru/forum/programmirovanie/tsifrovye-avtomaty-v-klassakh-po-qwone#comment-385066" href="http://arduino.ru/forum/programmirovanie/tsifrovye-avtomaty-v-klassakh-po-qwone#comment-385066" rel="nofollow">http://arduino.ru/forum/programmirovanie/tsifrovye-avtomaty-v-klassakh-po-qwone#comment-385066</a></a>
 * 
 */
#define SECONDS(x) ((x) * 1000UL)
#define MINUTES(x)  (SECONDS(x) * 60UL)
#define HOURS(x)  (MINUTES(x) * 60UL)
#define DAYS(x)   (HOURS(x) * 24UL)
#define WEEKS(x)  (DAYS(x) * 7UL)
unsigned long interval = MINUTES(1);
unsigned long oneMinute = MINUTES(1);
unsigned long timers = MINUTES(5); // время таймера 15, 30, 45 или 60 минут 
unsigned long memTimers=0; //здесь будем хранить установленное время таймера
unsigned long oldmemTimers=0;
byte isTimers = 0; // флаг запуска таймера
byte selectedMenu = 1; // выбранное меню. 1 - напряжение, 2 - время

unsigned long timMillis = 0;
unsigned long oldMillis = 0;
unsigned long mill; // переменная под millis()
unsigned long prevCorrectTime = 0;

// переменные для измерения времени цикла
unsigned long t1;
unsigned long t2;
unsigned long ts1;
unsigned int ts2;
byte fts = 0;

#include <Wire.h>
#include <SPI.h>

#include <LCD_1602_RUS.h>               // <a data-cke-saved-href="<a data-cke-saved-href="https://github.com/ssilver2007/LCD_1602_RUS" href="https://github.com/ssilver2007/LCD_1602_RUS" rel="nofollow">https://github.com/ssilver2007/LCD_1602_RUS</a>" href="<a data-cke-saved-href="https://github.com/ssilver2007/LCD_1602_RUS" href="https://github.com/ssilver2007/LCD_1602_RUS" rel="nofollow">https://github.com/ssilver2007/LCD_1602_RUS</a>" rel="nofollow"><a data-cke-saved-href="https://github.com/ssilver2007/LCD_1602_RUS" href="https://github.com/ssilver2007/LCD_1602_RUS" rel="nofollow">https://github.com/ssilver2007/LCD_1602_RUS</a></a>
LCD_1602_RUS lcd(0x27, 20, 4);

#include "INA219.h"
INA219 ina219;

#define CORRECT_PIN A7 // пин для внешней корректировки частоты. 

//#define TWBR  //Зарезервировано для частоты обмена с DAC в 400Кгц
#include <Adafruit_MCP4725.h>
Adafruit_MCP4725 dac;
unsigned int dVolume = 837; // Напряжение на выходе DAC 
unsigned int dVolumeMax = 1850; // Максимальное напряжение, около 1.1В
unsigned int dVolumeMin = 400; // Минимальное напряжение, около 0.9В

#define PIN_ZUM 12  //  был 10 пин
#define pinINT1 3   // этот пин Шимим 490Гц 
#define zFreq 2     // делитель интервала - секунда/2

unsigned int imax = 0;
// unsigned int imin = 0;
unsigned int Data_ina219 = 0;
volatile float Voltage_ina219 = 0;
 
const int SINE = 0x2000;                    // определяем значение регистров AD9833 взависимости от формы сигнала
const int SQUARE = 0x2020;                  // После обновления частоты нужно определить форму сигнала
const int TRIANGLE = 0x2002;                // и произвести запись в регистр.
const float refFreq = 25000000.0;           // Частота кристалла на плате AD9833

#define Fdefine 300000
long Fmin = 50000;
long Fmax = 500000;
#define Ftune 10000
//int Ftune = 10000;
unsigned int di = (Fmax-Fmin)/Ftune -1;
long FFmax = 0;
long freq = Fmin;
long ifreq = Fdefine; // если не будет определена частота резонанса катушки, 
                      // то она установится в это значение
                      
//int Ffinetune = 200;
#define  Ffinetune 200
  
/*const int FSYNC = 10;                       // Standard SPI pins for the AD9833 waveform generator.
const int CLK = 13;                         // CLK and DATA pins are shared with the TFT display.
const int DATA = 11; 
*/
#define FSYNC 10
#define CLK 13
#define DATA 11
 byte myClock = 0;
 byte SetClock = 5;
 byte flagClock = 0;
 byte myBuzzer = 0;

const char toks[]PROGMEM  = "I = ";
const char freqs[]PROGMEM  = "Freq = ";
const char call[]PROGMEM  ="Generator AD9833";

const unsigned long availableTimers[] = {oneMinute * 15, oneMinute * 30, oneMinute * 45, oneMinute * 60};
const byte maxTimers = 4;
int timerPosition = 0;

 /********* используемые подпрограммы выносим сюда *********/

 /*** Обработчик кнопки энкодера ***/
//------Cl_Btn----------------------
enum {sbNONE = 0, sbClick, sbLong}; /*состояние не изменилось/клик/долгое нажатие*/
class Cl_Btn {
  protected:
    const byte pin;
    byte state;
    bool bounce = 0;
    bool btn = 1, oldBtn;
    unsigned long past;
    const uint32_t time = 500 ;
    bool flag = 0;
    uint32_t past_flag = 0 ;
  public:
    Cl_Btn(byte p): pin(p) {}
    /*инициализация-вставить в setup()*/
    void init() {
      pinMode(pin, INPUT_PULLUP);
    }
    /*работа-вставить в loop()*/
    void run() {
      state = sbNONE;
      bool newBtn = digitalRead(pin);
      if (!bounce && newBtn != btn) {
        bounce = 1;
        past = mill;
      }
      if (bounce && mill - past >= 10) {
        bounce = 0 ;
        oldBtn = btn;
        btn = newBtn;
        if (!btn && oldBtn) {
          flag = 1;
          past_flag = mill;
        }
        if (!oldBtn && btn && flag && mill - past_flag < time ) {
          flag = 0;
          state = sbClick;
        }
      }
      if (flag && mill - past_flag >= time ) {
        flag = 0;
        state = sbLong;
      }
    }
    byte read() {
      return state;
    }
};

Cl_Btn Btn1(/*пин*/8); //Экземпляр обработчика для кнопки энкодера

/******* Простой энкодер *******/
#include <util/atomic.h>        // для атомарности чтения данных в прерываниях
#include <RotaryEncoder.h>
RotaryEncoder encoder(6, 7);
volatile int newPos;
static int pos = 0;
/*** Обработчик прерывания для энкодера ***/
 ISR(PCINT2_vect) {encoder.tick();}
 
/*** Установка напряжения энкодером ***/
void setVoltage() {
  unsigned int newVoltage = dVolume + ((newPos-pos) * 10);
  if ((newVoltage < dVolumeMax) && (newVoltage > dVolumeMin)) {
    dVolume = newVoltage;
    dac.setVoltage(dVolume, true);
  }  
}
void setTimer() {
  if (newPos-pos > 0) {
    if (timerPosition == maxTimers - 1) {
      timerPosition = 0;
    } else {
      timerPosition += 1;
    }
  } else if (newPos - pos < 0) {
    if (timerPosition == 0) {
      timerPosition = maxTimers - 1;
    } else {
      timerPosition -= 1;
    }
  }
  memTimers = availableTimers[timerPosition];
}

/*** Обработчик энкодера через ШИМ ***/
void startEncoder(){
     attachInterrupt(1, Encoder2, RISING );
     analogWrite(3,0x80); //установим на пине частоту 
                                //490 гц скважность 2
 }
void Encoder2(void){ // процедура вызываемая прерыванием, пищим активным динамиком
     encoder.tick();    
} 

 /********* Таймер обратного отсчёта экспозиции **********/
unsigned long  setTimerLCD(unsigned long timlcd) {
  if(millis() - timMillis >=1000){
    timlcd = timlcd - 1000; 
    timMillis += 1000;
  }
  if(timlcd == 0){
    timlcd = oldmemTimers; 
    isTimers = 0;
     lcd.setCursor(0, 3); 
      lcd.print("     ЗАВЕРШЕНО!     ");
      start_Buzzer();
      delay(5000);
      stop_Buzzer();
      AD9833reset();
    }
  return timlcd;
 }
/*******************ПИЩАЛКА ********************/
void start_Buzzer(){
     pinMode(PIN_ZUM,OUTPUT);
     attachInterrupt(1, Buzzer, RISING );
 }

void stop_Buzzer(){
     detachInterrupt(1);
     digitalWrite(PIN_ZUM,LOW);
 }

void Buzzer(void){ // процедура вызываемая прерыванием, пищим активным динамиком
     static int i=490/zFreq;
     if(!i--)
     {
    digitalWrite(PIN_ZUM, ! digitalRead(PIN_ZUM));
    i=490/zFreq;
      }
} 

// ******************* Обработка AD9833 *********************** 
// AD9833 documentation advises a 'Reset' on first applying power.
void AD9833reset() {
  WriteRegister(0x100);   // Write '1' to AD9833 Control register bit D8.
   delay(10);
 }
  
// Set the frequency and waveform registers in the AD9833.
void AD9833setFrequency(long frequency, int Waveform) {
  long FreqWord = (frequency * pow(2, 28)) / refFreq;
  int MSB = (int)((FreqWord & 0xFFFC000) >> 14);    //Only lower 14 bits are used for data
  int LSB = (int)(FreqWord & 0x3FFF);
//Set control bits 15 ande 14 to 0 and 1, respectively, for frequency register 0
  LSB |= 0x4000;
  MSB |= 0x4000;
  WriteRegister(0x2100);
  WriteRegister(LSB);                  // Write lower 16 bits to AD9833 registers
  WriteRegister(MSB);                  // Write upper 16 bits to AD9833 registers.
  WriteRegister(0xC000);               // Phase register
  WriteRegister(Waveform);             // Exit & Reset to SINE, SQUARE or TRIANGLE
 }
 
// *************************
// Display and AD9833 use different SPI MODES so it has to be set for the AD9833 here.
 void WriteRegister(int dat) {
 SPI.setDataMode(SPI_MODE2);
 digitalWrite(FSYNC, LOW);           // Set FSYNC low before writing to AD9833 registers
 delayMicroseconds(10);              // Give AD9833 time to get ready to receive data.
 SPI.transfer(highByte(dat));        // Each AD9833 register is 32 bits wide and each 16
 SPI.transfer(lowByte(dat));         // bits has to be transferred as 2 x 8-bit bytes.
  digitalWrite(FSYNC, HIGH);          //Write done. Set FSYNC high
}

//**** Процедура грубой настройки частоты по максимальному току ***/
void setFreq(){
  for (unsigned int i=1; i <= di; i++) {
    Data_ina219=ina219.shuntCurrent() * 1000; 
    if (Data_ina219 > imax){ 
      imax=Data_ina219; 
      ifreq = freq; 
    } // Если значение больше, то запомнить
    if (freq >=Fmax) {
      freq = Fmax;
    }
    freq=freq+Ftune;
    AD9833setFrequency(freq, SINE);
    delay(20);
  } 
}

/*** Процедура тонкой настройки частоты по максимальному току ***/
void setFFreq(){
  for (int j=1; j <= 100; j++) {
    Data_ina219=ina219.shuntCurrent() * 1000; 
    if (Data_ina219 > imax) { 
      imax=Data_ina219; 
      ifreq = freq; 
    } // Если значение больше, то запомнить
    freq=freq+Ffinetune;
    if (freq >=FFmax) {
      freq = FFmax;
    } 
    AD9833setFrequency(freq, SINE);
    delay(20);
  } 
}

// читает значение аналогового входа и на основе него высчитывает новую частоту
void readVoltageAndCorrectFreq() {
  //unsigned long curr = millis();

  // раз в секунду корректируем частоту
  //if (curr - prevCorrectTime > 1000) {
    int value = analogRead(CORRECT_PIN);
    float minFreq = 200000; // 200kHz
    float maxFreq = 400000; // 400kHz
    float oneHzStep = (maxFreq - minFreq) / 400; // -500Hz. При смене значения на аналоговом входе на 1 единицу, частота будет меняться на 500Гц
    //float newFreq = (oneHzStep * value) + minFreq;//
    float newFreq = maxFreq - (oneHzStep * value);//
    ifreq = newFreq;
    AD9833setFrequency(ifreq, SINE);
    //prevCorrectTime = millis();
  //}
}

//************************** SETUP *************************/
void setup() { 
  Btn1.init();
  SPI.begin();
  Serial.begin(115200);
  
  pinMode(PIN_ZUM, OUTPUT);
  pinMode(CORRECT_PIN, INPUT);
  
  analogReference(EXTERNAL); // использование AREF для опорного напряжения
  
  dac.begin(0x60);               
  dac.setVoltage(dVolume, true);  
  lcd.begin();
  lcd.backlight();
  delay(10);   
  ina219.begin(0x40); // (44) i2c address 64=0x40 68=0х44 исправлять и в ina219.h одновременно
  ina219.configure(0, 2, 12, 12, 7); // 16S -8.51ms
  ina219.calibrate(0.100, 0.32, 16, 3.2); 
  AD9833reset();                   // Ресет после включения питания
  delay(10);
  AD9833setFrequency(freq, SINE);  // выставляем нижнюю частоту
  setFreq();
  Serial.print("freq=");
  Serial.println(freq);
  freq = ifreq-10000;
  FFmax =ifreq +10000;
  imax = 0;
  AD9833setFrequency(freq, SINE); 
  setFFreq();
  Serial.print("ffreq=");
  Serial.println(ifreq);
  AD9833setFrequency(ifreq, SINE); // выставляем частоту максимального тока
  Data_ina219=ina219.shuntCurrent() * 1000; 
  Voltage_ina219 = ina219.busVoltage();
  myDisplay();
  delay(1000);
  PCICR |= (1 << PCIE2); // инициализируем порты для энкодера
  PCMSK2 |= (1 << PCINT20) | (1 << PCINT21);
  startEncoder(); 
  
  memTimers = availableTimers[0]; // выставляем 15 минут по умолчанию
}    // Конец процедуры инициализации прибора
  
 
// *** ТЕЛО ПРОГРАММЫ ***
void loop() {
    mill = millis();
    Btn1.run();
    
    // если обычное нажатие на кнопку, то перелистываем пункты меню
    if (Btn1.read() == sbClick){
      if (selectedMenu == 2) {
        selectedMenu = 1;
      } else {
        selectedMenu += 1;
      }
    }

    if (Btn1.read() == sbLong){
      oldmemTimers=memTimers;
      timMillis = millis();
      isTimers=1;
    }

    Data_ina219=ina219.shuntCurrent() * 1000; 
    Voltage_ina219 = ina219.busVoltage();
    myDisplay();
       
    if(isTimers==1){
      memTimers = setTimerLCD(memTimers);
    }

    ATOMIC_BLOCK(ATOMIC_RESTORESTATE){
      newPos = encoder.getPosition();
    }
    
    if (pos != newPos) {
      if (selectedMenu == 1) {
        setVoltage();
      } else if (selectedMenu == 2 && !isTimers) {
        setTimer();
      }
      pos = newPos;
    } 
    myTESTloop();
    readVoltageAndCorrectFreq();
 } //END

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

в папке наверное еще разные дополнения лежат?

profinrus-1
Offline
Зарегистрирован: 10.07.2017

в какой папке?