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

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

За основу проекта взята известная схема генератора для катушки Мишина на основе генератора на микросхеме XR2206 (174ГФ2) и усилителя мощности на микросхеме TDA7056.
В схему генератора введены цепи авутоматической подстройки частоты на резонансную частоту катушки на основе следующих компонентов: датчик тока - INA219, управление arduino nano, цепь управления частотой - DAC MCP4725 в связке с полевым транзистором КП103.
Микропроцессорное управление позволяет устранить недостатки генератора по этой схеме описанные к примеру здесь.

Реализован режим синуса и режим меандра, ручной и автоматический режим работы генератора.
Обмен данными между управляющим модулем и датчиками осуществляется по шине I2C.
Ручной и автоматический режимы реализованы полностью независимыми, то-есть при переводе генератора в ручной режим коммутация соответствует базовой схеме. В автоматическом режиме элементы регулировки частоты переключаются на цифровой блок DAC, а в качестве регулирующего частоту элемента использован полевой транзистор КП103.
 

В настоящий момент программа управления несовершенна, имеет глюки и выкладывать её полностью не вижу смысла, но если проект станет кому-то интересен, можно доработать, а возможно разработать с нуля совместными усилиями.
 

Основа скетча:
 

#include <Wire.h>
#include "ina219.h"
#include <Adafruit_MCP4725.h>
Adafruit_MCP4725 dac;
INA219 monitor;

/************************** SETUP *************************/ 
void setup() {
  Serial.begin(9600);
  digitalWrite(8, LOW);
  monitor.begin(64); // i2c address 64=0x40
 // monitor.configure(0, 2, 10, 10, 7); // 4S -2.13ms
 // monitor.configure(0, 2, 11, 11, 7); // 8S -4.26ms
  monitor.configure(0, 2, 12, 12, 7); // 16S -8.51ms
 // monitor.configure(0, 2, 13, 13, 7); // 32S -17.02ms
 // monitor.configure(0, 2, 14, 14, 7); // 64S -34.05ms
 // monitor.configure(0, 2, 15, 15, 7);  // 128S - 68.10ms
 // monitor.configure(0, 2, 8, 8, 7);
                           // range, gain, bus_adc, shunt_adc, mode
                           // range = 1 (0-32V bus voltage range)
                           // gain = 3 (1/8 gain - 320mV range)
                           // bus adc = 3 (12-bit, single sample, 532uS conversion time)
                           // shunt adc = 3 (12-bit, single sample, 532uS conversion time)
                           // mode = 7 (continuous conversion)
   monitor.calibrate(0.100, 0.32, 16, 3.2); 
                           // R_шунта, напряж_шунта, макcнапряж, максток
                           
 dac.begin(0x62);
 dac.setVoltage(dfreq, true);
 delay(10);  
 initDAC();                // Регулировка через ЦАП 12 бит, находим резонансную частоту при включении прибора
 }                         // Конец процедуры инициализации прибора

 

Коды библиотеки:
INA219.H

/******************************************************************************
* TI INA219 hi-side i2c current/power monitor Library
*
* http://www.ti.com/product/ina219
*
* 6 May 2012 by John De Cristofaro
*
*
* Tested at standard i2c 100kbps signaling rate.
*
* This library does not handle triggered conversion modes. It uses the INA219
* in continuous conversion mode. All reads are from continous conversions.
*
* A note about the gain (PGA) setting:
*	The gain of the ADC pre-amplifier is programmable in the INA219, and can
*	be set between 1/8x (default) and unity. This allows a shunt voltage 
*	range of +/-320mV to +/-40mV respectively. Something to keep in mind,
*	however, is that this change in gain DOES NOT affect the resolution
*	of the ADC, which is fixed at 1uV. What it does do is increase noise
*	immunity by exploiting the integrative nature of the delta-sigma ADC.
*	For the best possible reading, you should set the gain to the range
*	of voltages that you expect to see in your particular circuit. See
*	page 15 in the datasheet for more info about the PGA.
*
* Known bugs:
*     * may return unreliable values if not connected to a bus or at
*	bus currents below 10uA.
*
* Arduino 1.0 compatible as of 6/6/2012
*
* Dependencies:
*    * Arduino Wire library
*
* MIT license
******************************************************************************/

#ifndef ina219_h
#define ina219_h


#if ARDUINO >= 100
 #include "Arduino.h"
#else
 #include "WProgram.h"
#endif

#include <Wire.h>

#define INA219_DEBUG 1

// INA219 memory registers
#define CONFIG_R		0x00	// configuration register
#define V_SHUNT_R		0x01	// differential shunt voltage
#define V_BUS_R			0x02	// bus voltage (wrt to system/chip GND)
#define P_BUS_R			0x03	// system power draw (= V_BUS * I_SHUNT)
#define I_SHUNT_R		0x04	// shunt current
#define CAL_R			0x05	// calibration register

#define INA_RESET		0xFFFF	// send to CONFIG_R to reset unit

#define CONFIG_DEFAULT		0x399F

// config. register bit labels
#define RST	15
#define BRNG	13
#define PG1	12
#define PG0	11
#define BADC4	10
#define BADC3	9
#define BADC2	8
#define BADC1	7
#define SADC4	6
#define SADC3	5
#define SADC2	4
#define SADC1	3
#define MODE3	2
#define MODE2	1
#define MODE1	0

// default values
#define D_I2C_ADDRESS	0x40 // (64)
#define D_RANGE			1
#define D_GAIN			3
#define D_SHUNT_ADC		3
#define D_BUS_ADC		3
#define D_MODE			7
#define D_SHUNT			0.25
#define D_V_BUS_MAX		6
#define D_V_SHUNT_MAX		0.3
#define D_I_MAX_EXPECTED	1


class INA219
{
  public:
	INA219();
	
	// by default uses addr = 0x40 (both a-pins tied low)
	void begin(uint8_t addr = D_I2C_ADDRESS);

	void calibrate(float r_shunt = D_SHUNT, float v_shunt_max = D_V_SHUNT_MAX, float v_bus_max = D_V_BUS_MAX, float i_max_expected = D_I_MAX_EXPECTED);

	void configure(uint8_t range = D_RANGE, uint8_t gain = D_GAIN, uint8_t bus_adc = D_BUS_ADC, uint8_t shunt_adc = D_SHUNT_ADC, uint8_t mode = D_MODE);

	void reset();

	int16_t shuntVoltageRaw();
	int16_t busVoltageRaw();
	float shuntVoltage();
	float busVoltage();
	float shuntCurrent();
	float busPower();


  private:
	uint8_t i2c_address;
	float r_shunt, current_lsb, power_lsb;
	uint16_t config, cal, gain;

	int16_t read16(uint8_t addr);
	void write16(uint8_t addr, uint16_t data);

};

#endif

 

INA219.CPP
 

/******************************************************************************
* TI INA219 hi-side i2c current/power monitor Library
*
* http://www.ti.com/product/ina219
*
* 6 May 2012 by John De Cristofaro
*
*
* Tested at standard i2c 100kbps signaling rate.
*
* This library does not handle triggered conversion modes. It uses the INA219
* in continuous conversion mode. All reads are from continous conversions.
*
* A note about the gain (PGA) setting:
*	The gain of the ADC pre-amplifier is programmable in the INA219, and can
*	be set between 1/8x (default) and unity. This allows a shunt voltage 
*	range of +/-320mV to +/-40mV respectively. Something to keep in mind,
*	however, is that this change in gain DOES NOT affect the resolution
*	of the ADC, which is fixed at 1uV. What it does do is increase noise
*	immunity by exploiting the integrative nature of the delta-sigma ADC.
*	For the best possible reading, you should set the gain to the range
*	of voltages that you expect to see in your particular circuit. See
*	page 15 in the datasheet for more info about the PGA.
*
* Known bugs:
*     * may return unreliable values if not connected to a bus or at
*	bus currents below 10uA.
*
* Arduino 1.0 compatible as of 6/6/2012
*
* Dependencies:
*    * Arduino Wire library
*
* MIT license
******************************************************************************/

#include "INA219.h"
#include <util/delay.h>

INA219::INA219() {
}


void INA219::begin(uint8_t addr)
{
  Wire.begin();
  i2c_address = addr;
  gain = D_GAIN;
}


// calibration of equations and device
// shunt_val 		= value of shunt in Ohms
// v_shunt_max 		= maximum value of voltage across shunt
// v_bus_max 		= maximum voltage of bus
// i_max_expected 	= maximum current draw of bus + shunt
// default values are for a 0.25 Ohm shunt on a 5V bus with max current of 1A
void INA219::calibrate(float shunt_val, float v_shunt_max, float v_bus_max, float i_max_expected)
{
  uint16_t cal;
  float i_max_possible, min_lsb, max_lsb, swap;

  r_shunt = shunt_val;

  i_max_possible = v_shunt_max / r_shunt;
  min_lsb = i_max_expected / 32767;
  max_lsb = i_max_expected / 4096;

  current_lsb = (uint16_t)(min_lsb * 100000000) + 1;
  current_lsb /= 100000000;
  swap = (0.04096)/(current_lsb*r_shunt);
  cal = (uint16_t)swap;
  power_lsb = current_lsb * 20;

#if (INA219_DEBUG == 1)
  Serial.print("v_bus_max:	"); Serial.println(v_bus_max, 8);
  Serial.print("v_shunt_max:	"); Serial.println(v_shunt_max, 8);
  Serial.print("i_max_possible:	"); Serial.println(i_max_possible, 8);
  Serial.print("i_max_expected: "); Serial.println(i_max_expected, 8);
  Serial.print("min_lsb:	"); Serial.println(min_lsb, 12);
  Serial.print("max_lsb:	"); Serial.println(max_lsb, 12);
  Serial.print("current_lsb:	"); Serial.println(current_lsb, 12);
  Serial.print("power_lsb:	"); Serial.println(power_lsb, 8);
  Serial.println("  ");
  Serial.print("cal:		"); Serial.println(cal);
  Serial.print("r_shunt:	"); Serial.println(r_shunt);
#endif

  write16(CAL_R, cal);

}


// config values (range, gain, bus adc, shunt adc, mode) can be derived from pp26-27 in the datasheet
// defaults are:
// range = 1 (0-32V bus voltage range)
// gain = 3 (1/8 gain - 320mV range)
// bus adc = 3 (12-bit, single sample, 532uS conversion time)
// shunt adc = 3 (12-bit, single sample, 532uS conversion time)
// mode = 7 (continuous conversion)
void INA219::configure(uint8_t range, uint8_t gain, uint8_t bus_adc, uint8_t shunt_adc, uint8_t mode)
{
  config = 0;

  config |= (range << BRNG | gain << PG0 | bus_adc << BADC1 | shunt_adc << SADC1 | mode);

  write16(CONFIG_R, config);		
}

// resets the INA219
void INA219::reset()
{
  write16(CONFIG_R, INA_RESET);
  _delay_ms(5);
}

// returns the raw binary value of the shunt voltage
int16_t INA219::shuntVoltageRaw()
{
  return read16(V_SHUNT_R);
}

// returns the shunt voltage in volts.
float INA219::shuntVoltage()
{
  float temp;
  temp = read16(V_SHUNT_R);
  return (temp / 100000);
}

// returns raw bus voltage binary value
int16_t INA219::busVoltageRaw()
{
  return read16(V_BUS_R);
}

// returns the bus voltage in volts
float INA219::busVoltage()
{
  int16_t temp;
  temp = read16(V_BUS_R);
  temp >>= 3;
  return (temp * 0.004);
}

// returns the shunt current in amps
float INA219::shuntCurrent()
{
  return (read16(I_SHUNT_R) * current_lsb);
}

// returns the bus power in watts
float INA219::busPower()
{
  return (read16(P_BUS_R) * power_lsb);
}


/**********************************************************************
* 			INTERNAL I2C FUNCTIONS			      *
**********************************************************************/

// writes a 16-bit word (d) to register pointer (a)
// when selecting a register pointer to read from, (d) = 0
void INA219::write16(uint8_t a, uint16_t d) {
  uint8_t temp;
  temp = (uint8_t)d;
  d >>= 8;
  Wire.beginTransmission(i2c_address); // start transmission to device

  #if ARDUINO >= 100
    Wire.write(a); // sends register address to read from
    Wire.write((uint8_t)d);  // write data hibyte 
    Wire.write(temp); // write data lobyte;
  #else
    Wire.send(a); // sends register address to read from
    Wire.send((uint8_t)d);  // write data hibyte 
    Wire.send(temp); // write data lobyte;
  #endif

  Wire.endTransmission(); // end transmission
  delay(1);
}


int16_t INA219::read16(uint8_t a) {
  uint16_t ret;

  // move the pointer to reg. of interest, null argument
  write16(a, 0);
  
  Wire.requestFrom((int)i2c_address, 2);	// request 2 data bytes

  #if ARDUINO >= 100
    ret = Wire.read(); // rx hi byte
    ret <<= 8;
    ret |= Wire.read(); // rx lo byte
  #else
    ret = Wire.receive(); // rx hi byte
    ret <<= 8;
    ret |= Wire.receive(); // rx lo byte
  #endif

  Wire.endTransmission(); // end transmission

  return ret;
}

Схема генератора:

Внешний и внутренний вид генератора:

 

Н_Андрей_Ю
Н_Андрей_Ю аватар
Offline
Зарегистрирован: 22.12.2016

Привет, по моему этот генерато никчемная вещь. Посмотрел отзовы на ютьюбе, это тоже самое что и генератор свободной энергии, не трать напрасно свое время  и нас всякой ерундой не грузи!

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Н_Андрей_Ю пишет:

Привет, по моему этот генерато никчемная вещь. Посмотрел отзовы на ютьюбе, это тоже самое что и генератор свободной энергии, не трать напрасно свое время  и нас всякой ерундой не грузи!

у меня на руках объективные данные СКТ (в динамике), они говорят совершенно о другом, дай Бог чтобы вам он никогда не понадобился!

Flikk
Offline
Зарегистрирован: 22.11.2017

А мне нравится идея, хочу повторить только на dds генераторе

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Flikk пишет:

А мне нравится идея, хочу повторить только на dds генераторе

Уже, только на макетной плате, до разработки новой платы руки еще не дошли, непонятно насколько высоко можно гнать по частоте от 300кГц, катушек пока не делалось, но датчик резонанса тот же )))

Flikk
Offline
Зарегистрирован: 22.11.2017

Заказал модуль на ad9833, усилитель останется на tda7056. Уже руки чешутся все собрать и проверить. А зачем высоко гнать по частоте, там же рабочий диапазон 300+-50 кГц

Flikk
Offline
Зарегистрирован: 22.11.2017

Хотел спросить, а в какую цепь вы включали датчик тока, он ведь измеряет падение постоянного напряжения, а на катушке переменка. Я ставил в цепь питания микросхемы усилителя, делал на тда7297. 

Pserg1977
Offline
Зарегистрирован: 03.02.2018

Есть продвижки?

Схема интересная!

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Pserg1977 пишет:

Есть продвижки?

Схема интересная!

Устройство реализовано!!!
В тех же габаритах сделана плата процессора и на PIC контроллере, программа на ассемблере.
То-есть, можно применить либо ардуино нано  либо самодельный контроллер не меня ничего в приборе.

Pserg1977
Offline
Зарегистрирован: 03.02.2018

Думаю пик в данном случае более уместен!!!

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Flikk пишет:

Хотел спросить, а в какую цепь вы включали датчик тока, он ведь измеряет падение постоянного напряжения, а на катушке переменка. Я ставил в цепь питания микросхемы усилителя, делал на тда7297. 

Основным потребителем тока в этой схеме является микросхема TDA-7056 поэтому меряю общий ток потребления, на резонансе он максимальный и равен при 9 вольтах питания порядка одного ампера, если микросхема исправна, на неисправной - вдвое меньше. На неисправной на осциллограмме питающего тока отсутствует тот эффект которому Мишин дал название эмплозия )))  (эффект перезаряда емкости контура)
Катушка - последовательный колебательный контур, эквивалентное сопротивление на частоте резонанса получилось порядка двух ом.

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Pserg1977 пишет:

Думаю пик в данном случае более уместен!!!


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

По распиновке и размерам PIC уложен в конструктив ардуино нано ))) то-есть лёгким движением руки...превращается )))

Pserg1977
Offline
Зарегистрирован: 03.02.2018

Ну хоть что-нибудь опубликуйте. Спасибо за труд!

Н_Андрей_Ю
Н_Андрей_Ю аватар
Offline
Зарегистрирован: 22.12.2016

Как я и говорил пустая трата времени. Это из тойже оперы что и поиск "свободной энергии"

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Pserg1977 пишет:
Ну хоть что-нибудь опубликуйте. Спасибо за труд!

Так основа опубликова выше, там указан режим измерения INA219 ну и библиотеки для работы с оной, далее измеряем, сравниваем, корректируем. На Пик контроллере нет аппаратного I2C, реализован программно.

Алгоритм обсуждался здесь

 

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Н_Андрей_Ю пишет:

Как я и говорил пустая трата времени. Это из тойже оперы что и поиск "свободной энергии"

а при чём здесь свободная энергия?
Аналогичный прибор сделан в Израиле как медицинский прибор, называется M1F, сертифицирован минздравом USA на лечение онкологии.
Исследования велись давно, не могу сказать, что Мишин не позаимствовал идеи этих исследований.
Только по частотам он значительно шире...

 

Pserg1977
Offline
Зарегистрирован: 03.02.2018

ua6em пишет:

Pserg1977 пишет:
Ну хоть что-нибудь опубликуйте. Спасибо за труд!

Так основа опубликова выше, там указан режим измерения INA219 ну и библиотеки для работы с оной, далее измеряем, сравниваем, корректируем. На Пик контроллере нет аппаратного I2C, реализован программно.

Алгоритм обсуждался здесь

 

Я ещё ардуинами не пользовался. Было бы не плохо увидеть схему целиком. Ну про платы....было бы сказочно просто. Может много хочу, ну как есть. Заранее благодарен.

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Pserg1977 пишет:

ua6em пишет:

Pserg1977 пишет:
Ну хоть что-нибудь опубликуйте. Спасибо за труд!

Так основа опубликова выше, там указан режим измерения INA219 ну и библиотеки для работы с оной, далее измеряем, сравниваем, корректируем. На Пик контроллере нет аппаратного I2C, реализован программно.

Алгоритм обсуждался здесь

 

Я ещё ардуинами не пользовался. Было бы не плохо увидеть схему целиком. Ну про платы....было бы сказочно просто. Может много хочу, ну как есть. Заранее благодарен.

Для этого надо сесть и специально этим заняться, к сожалению времени нет. Была надежда, что к проекту подключатся более компетентные программеры и реализуют свои познания на профессиональном уровне )))
Видимо никого не заинтересовал сей девайс.
Платы делались в Pcad так что доступен только формат pcb.
Да и повторять один к одному как-то не интересно.

PS можно купить готовое изделие, предложений масса, да и по цене будет дешевле, но из исследованных мной генераторов  ни один не работает в режиме стоячей волны, все в режиме бегущей волны, то-есть катушка работает не на своей резонансной частоте. Да и на осциллограмме "провальчика" нет.
Здесь реализована классика - именно тот режим, что публиковал Мишин в первых своих постах на Ютубе.

 

Pserg1977
Offline
Зарегистрирован: 03.02.2018

Ну хозяин барин. В любом случае, спасибо. А тех кого не заинтересовал, им сильно в голову вбили научную догму. Каждому своё.

Flikk
Offline
Зарегистрирован: 22.11.2017

Я делал на макетке схему, плюс датчик тока и усилитель TDA 7294 

Только еще подключал датчик тока по I2C и в ручном режиме смотрел показания тока потребления микросхемы усилителя.

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

Если кому нужет мой кривой скетч, могу выложить. И ручной генератор и с автоматической перестройкой с 270 кГц до 350кГц

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Flikk пишет:

Я делал на макетке схему, плюс датчик тока и усилитель TDA 7294 

Только еще подключал датчик тока по I2C и в ручном режиме смотрел показания тока потребления микросхемы усилителя.

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

Если кому нужет мой кривой скетч, могу выложить. И ручной генератор и с автоматической перестройкой с 270 кГц до 350кГц

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

Оригинальная схема и код видимо брались здесь?


 

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Pserg1977 пишет:
Ну хозяин барин. В любом случае, спасибо. А тех кого не заинтересовал, им сильно в голову вбили научную догму. Каждому своё.

просто предмет сей не входит в круг их понятий...
Обоснований то масса, но что истина ведает только абсолют...
Самое главное, что есть эффект!

Flikk
Offline
Зарегистрирован: 22.11.2017

Вот схема по которой собирал. А скетч взял с http://edycube.blog.fc2.com/blog-entry-933.html. Вечером выложу свой скетч. По току питания усилителя могу сказать, что максимум был 130 мА мне показалось как-то маловато. Возможно микросхема усилителя брак, так как цена была рублей 5 за штуку

Pserg1977
Offline
Зарегистрирован: 03.02.2018

Здорово, жду скетч.

Заранее благодарен!!!

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Если верить этому даташиту эта микросхема для этих целей не подходит,
Правильная TDA7056 наше всё.
Есть микросхемы для модемов    VDSL но я их еще не пытал, размах ножек мелковат для лута.
Код содран у англичанина

const int SINE = 0x2000;                    // Define AD9833's waveform register value.
const int SQUARE = 0x2028;                  // When we update the frequency, we need to
const int TRIANGLE = 0x2002;                // define the waveform when we end writing.    

Ну не может жеж пояснение совпадать до буковки )))

Flikk
Offline
Зарегистрирован: 22.11.2017

Я использовал не 7294, а TDA 7297. И хоть у нее и стоит предел в 300кГц, но видимо она не тянет их, как и некоторые TDA7056. Собрал макетку по схеме "Дена"для проверки микросхемы, работает отлично, ток  выставлял до 500мА. Делаю сейчас плату под выложенную мной схему с TDA7056 и енкодерами, посмотрим как пойдет, надеюсь жена не выгонет из дома.

Я скетч подсмотрел на китайском сайте, а уж откуда там передрали фиг знает

Вот мой  код. Автоподстройка частоты по току питания усилителя, енкодеры не задействованы.

 

#include <Rotary.h>            
#include <SPI.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Adafruit_INA219.h>

Adafruit_INA219 ina219;

// Set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 20, 4);

const int SINE = 0x2000;                    // Define AD9833's waveform register value.
const int SQUARE = 0x2020;                  // When we update the frequency, we need to
const int TRIANGLE = 0x2002;                // define the waveform when we end writing.

int wave = 0;
int waveType = SINE;
int wavePin = 7;
int freqUpPin = 2;                          // Define rotary encoder pins.
int freqDownPin = 3;
int stepUpPin = 5;
int stepDownPin = 6;
int current_mA_OLD = 0;
int maxFreq = 0;
const float refFreq = 25000000.0;           // On-board crystal reference frequency

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;

Rotary r = Rotary(freqUpPin, freqDownPin);    // Rotary encoder for frequency connects to interrupt pins
Rotary i = Rotary(stepUpPin, stepDownPin);    // Rotart encoder for setting increment.

long freq = 300000;               // Set initial frequency.
long freqOld = freq;

long incr = 1000;
long oldIncr = 1000;
char disp_buf[16];

char* formText[3] = {
  "      SINE",
  "    SQUARE",
  "  TRIANGLE",
  };

char* stepText[18] = {
  "       1Hz",
  "       2Hz",
  "       5Hz",
  "      10Hz",
  "      20Hz",
  "      50Hz",
  "     100Hz",
  "     200Hz",
  "     500Hz",
  "   1,000Hz",
  "   2,000Hz",
  "   5,000Hz",
  "  10,000Hz",
  "  20,000Hz",
  "  50,000Hz",
  " 100,000Hz",
  " 200,000Hz",
  " 500,000Hz"
};

int stepPointer = 6;
//long  incr = 0;
String units = stepText[stepPointer];
String form = formText[wave];

void setup() {

  Serial.begin(9600);
  uint32_t currentFrequency;
    
  Serial.println("Hello!");
  
  // Initialize the INA219.
  // By default the initialization will use the largest range (32V, 2A).  However
  // you can call a setCalibration function to change this range (see comments).
  ina219.begin(0x40);
  // To use a slightly lower 32V, 1A range (higher precision on amps):
  ina219.setCalibration_32V_1A();
  // Or to use a lower 16V, 400mA range (higher precision on volts and amps):
  //ina219.setCalibration_16V_400mA();

  Serial.println("Measuring voltage and current with INA219 ..."); 
  
  pinMode(freqUpPin, INPUT_PULLUP);      // Set pins for rotary encoders as INPUTS and enable
  pinMode(freqDownPin, INPUT_PULLUP);    // internal pullup resistors.
  pinMode(stepUpPin, INPUT_PULLUP);
  pinMode(stepDownPin, INPUT_PULLUP);
  pinMode(wavePin, INPUT_PULLUP);

  // Configure interrupt and enable for rotary encoder.
  PCICR |= (1 << PCIE2);
  PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
  sei();
  SPI.begin();
  delay(50);

  lcd.init();
  lcd.backlight();
  lcd.clear();  // 
  lcd.setCursor( 0, 0 );
  lcd.print( "AD9833" );
  lcd.setCursor( 0, 1 );
  lcd.print( "Signal Generator" );
  delay(1000);
  lcd.clear();

  AD9833reset();                                   // Reset AD9833 module after power-up.
  delay(50);
  AD9833setFrequency(freq, SINE);                  // Set the frequency and Sine Wave output
  updateDisplay();

}

void getStep() {
  switch (stepPointer) {
    case 0:  incr = 1; break;
    case 1:  incr = 2; break;
    case 2:  incr = 5; break;
    case 3:  incr = 10; break;
    case 4:  incr = 20; break;
    case 5:  incr = 50; break;
    case 6:  incr = 100; break;
    case 7:  incr = 200; break;
    case 8:  incr = 500; break;
    case 9:  incr = 1000; break;
    case 10: incr = 2000; break;
    case 11: incr = 5000; break;
    case 12: incr = 10000; break;
    case 13: incr = 20000; break;
    case 14: incr = 50000; break;
    case 15: incr = 100000; break;
    case 16: incr = 200000; break;
    case 17: incr = 500000; break;
  }
}

void updateDisplay() {
  getStep();
  units = stepText[stepPointer];
  //lcd.clear();
  lcd.setCursor( 0, 0 );
  lcd.print( "STEP: " );
  lcd.print(units );

  lcd.setCursor( 0, 1 );
  lcd.print("FRQ:");
  if (freq < 1000) {
    sprintf(disp_buf, "%10ld", freq);
  }
  else if (freq < 1000000) {
    int freqL = freq % 1000;
    int freqM = freq / 1000;
    sprintf(disp_buf, "%6d,%03d", freqM, freqL);
  }
  else {
    int freqL = freq  % 1000;
    int freqM = (freq / 1000) % 1000;
    int freqH = freq / 1000000;
    sprintf(disp_buf, "%2d,%03d,%03d", freqH, freqM, freqL);
  }
  lcd.print(disp_buf);
  lcd.print("Hz");
  
  form = formText[wave];
  lcd.setCursor( 0, 2 );
  lcd.print( "FORM: " );
  lcd.print(form );

  
 
}

void loop() {

  float shuntvoltage = 0;
  float busvoltage = 0;
  float current_mA = 0;
  float loadvoltage = 0;

  shuntvoltage = ina219.getShuntVoltage_mV();
  busvoltage = ina219.getBusVoltage_V();
  current_mA = ina219.getCurrent_mA();
  loadvoltage = busvoltage + (shuntvoltage / 1000);
  
  Serial.print("Bus Voltage:   "); Serial.print(busvoltage); Serial.println(" V");
  Serial.print("Shunt Voltage: "); Serial.print(shuntvoltage); Serial.println(" mV");
  Serial.print("Load Voltage:  "); Serial.print(loadvoltage); Serial.println(" V");
  Serial.print("Current:    "); Serial.print(current_mA); Serial.println(" mA");
  Serial.println("");
  lcd.setCursor( 0, 3 );
  lcd.print( "Current: " );
  lcd.print(round(current_mA));
  lcd.print("mA");

  if (oldIncr != incr) {
    updateDisplay();
    oldIncr = incr;
  }
  // Check if push button on 'increment' rotary encoder is pushed and set Wave Type accordingly.
  if (digitalRead(wavePin) == LOW) {
    wave += 1;
    if (wave > 2) wave = 0;
    switch (wave) {
      case 0: waveType = SINE; break;
      case 1: waveType = SQUARE; break;
      case 2: waveType = TRIANGLE; break;
    }
   // AD9833setFrequency(freq, waveType);     // Set AD9833 to frequency and selected wave type.
   // updateDisplay();
    //delay(200);
  }
  if (current_mA <= current_mA_OLD-4){
    freq = 300000;
    current_mA_OLD =0;
  }
if  ((current_mA) >= current_mA_OLD) { 
     
if ((freq + incr) <= 350000) freq += incr;
    current_mA_OLD = current_mA;
     maxFreq = freq;
    if (freq <= 300000)  freq = 300000;
    if (freq >= 350000) freq = 350000;
    //delay(10);
  if (freq != freqOld) {                    // If frequency has changed, interrupt rotary encoder
    AD9833setFrequency(freq, waveType);     // must have been turned so update AD9833 and display.
    updateDisplay();
    freqOld = freq;                         // Remember new frequency to avoid unwanted display
  }                                         // and AD9833 updates.
}
}
// 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

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

 

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Flikk пишет:

Вот мой  код. Автоподстройка частоты по току питания усилителя, енкодеры не задействованы.

нет ребята, всё не так, всё не так ребята )))

1. Надо определиться с полосой пропускания самой катушки по уровню к примеру 0,5, если есть генератор померь
2. Шагать надо с шагом равным полосе пропускания от нижней частоты до верхней к примеру от 250Кгц до 350Кгц
3. Как только на следующем шаге ток начинает падать, останавливаем и запоминаем эту частоту и вносим новые значения Fmin и Fmax и запускаем второй проход определения резонансной частоты, к примеру с шагом 500 герц, находим экстремум, выставляем частоту
С режимом первичной настройки всё
А вот дальше процедура удержания.
Процедуру первичной установки частоты вынести в setup.
С этими библиотеками INA219 я не экспериментировал, с теми что работал библиотеки есть в посте, там же и процедура настройки датчика тока

Насчет супруги не переживай, катушка очень хорошо и быстро снимает любую депрессию )))

Прямо тут и начну делать скетч!
ПРОСЬБА НЕ ЦИТИРОВАТЬ!!!
 

/*
 * Генератор для катушки Мишина на AD9833 + TDA7056B + INA219
 * V1.00  - 08.02.2018 стартуем
 * V1.01  - 09.02.2018 добавлен дисплей LCD 2004A (1602A)
 */
 
#include <Wire.h>
#include <SPI.h>
#include <Wire.h>

#include "LiquidCrystal_I2C.h"
LiquidCrystal_I2C lcd(0x27, 20, 4);   // Для экрана 20х4 (четырехстрочный), I2C адрес дисплея уточнить
//LiquidCrystal_I2C lcd(0x27, 16, 2); // Для экрана 16х2 (двухстрочный)

#include "ina219.h"
INA219 monitor;
unsigned int imax = 0;
unsigned int Data_ina219 = 0;

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

/*
int wave = 0;
int waveType = SINE;
int wavePin = 7;
int freqUpPin = 2;                          // Define rotary encoder pins. (оставим на будущее)
int freqDownPin = 3;
int stepUpPin = 5;
int stepDownPin = 6;
int current_mA_OLD = 0;
int maxFreq = 0;
*/

const float refFreq = 25000000.0;           // On-board crystal reference frequency

long Fmin = 200000;
long Fmax = 350000;
long FFmax = 0;
long freq = Fmin;
long ifreq = 0;
int Ftune = 10000;
int Ffinetune = 500;

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;

/*** Процедура записи в регистры управления микросхемы AD9833 ***/
void WriteRegister(int dat) {

  // Обычно дисплеи и микросхема AD9833 испоьзуют различные режимы SPI поэтому требуемый
  // для AD9833 режим работы SPI должен быть установлен здесь.
  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
}

/*** Процедура RESET микросхемы AD9833 - должна выполняться после включения питания ***/
void AD9833reset() {
  WriteRegister(0x100);                // Write '1' to AD9833 Control register bit D8.
  delay(10);
}


/*** Процедура установки частоты и формы сигнала микросхемы 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

}



/************************** SETUP *************************/ 
void setup() {
  SPI.begin();
  AD9833reset();                                   // Reset AD9833 module after power-up.

  Serial.begin(9600);
  lcd.begin();
  digitalWrite(8, LOW);
  monitor.begin(64); // i2c address 64=0x40
 // monitor.configure(0, 2, 10, 10, 7);     // 4S     -2.13ms
 // monitor.configure(0, 2, 11, 11, 7);     // 8S     -4.26ms
 // monitor.configure(0, 2, 12, 12, 7);       // 16S    -8.51ms
 // monitor.configure(0, 2, 13, 13, 7);     // 32S   -17.02ms
 // monitor.configure(0, 2, 14, 14, 7);     // 64S -  34.05ms
    monitor.configure(0, 2, 15, 15, 7);     // 128S - 68.10ms
 // monitor.configure(0, 2, 8, 8, 7);
                           // range, gain, bus_adc, shunt_adc, mode
                           // range = 1 (0-32V bus voltage range)
                           // gain = 3 (1/8 gain - 320mV range)
                           // bus adc = 3 (12-bit, single sample, 532uS conversion time)
                           // shunt adc = 3 (12-bit, single sample, 532uS conversion time)
                           // mode = 7 (continuous conversion)
   monitor.calibrate(0.100, 0.32, 16, 3.2); 
                           // R_шунта, напряж_шунта, макcнапряж, максток
                           
 delay(10); 
// AD9833reset();                                   // Reset AD9833 module after power-up.
 delay(50);
 
 AD9833setFrequency(freq, SINE);  // выставляем нижнюю частоту
 
 for (int i=1; i <= 15; i++) {
    Data_ina219=monitor.shuntCurrent() * 1000;
    if (Data_ina219 > imax){ imax=Data_ina219; ifreq = freq; } // Если значение больше, то запомнить
    freq=freq+Ftune;
    if (freq >=Fmax) {freq = Fmax;}
    AD9833setFrequency(freq, SINE); 
    delay(70);
    }
    freq = ifreq-10000;
    FFmax =ifreq +10000;
    imax = 0;
    AD9833setFrequency(freq, SINE);                  // Set the frequency and Sine Wave output 
for (int j=1; j <= 40; j++) {
    Data_ina219=monitor.shuntCurrent() * 1000;
    if (Data_ina219 > imax){ imax=Data_ina219; ifreq = freq; } // Если значение больше, то запомнить
    freq=freq+Ffinetune;
    if (freq >=FFmax) {freq = FFmax;}
    AD9833setFrequency(freq, SINE); 
    delay(2);
    
    }
    Data_ina219=monitor.shuntCurrent() * 1000;
    lcd.setCursor(0, 0);                  // 1 строка
    lcd.print("GENERATOR MPGSP-V1.0");
    lcd.setCursor(0, 1);                  // 2 строка
    lcd.print("Freq = ");
    lcd.setCursor(0, 2);                  // 3 строка
    lcd.print(freq);
    lcd.setCursor(0, 3);                  // 4 строка
    lcd.print("TOK = ");
    lcd.setCursor(7, 3);                  // 4 строка 7 позиция
    lcd.print(Data_ina219);
 }                                                   // Конец процедуры инициализации прибора

void loop() {
  
}

Используемые библиотеки:

INA219.h

 

/******************************************************************************
* TI INA219 hi-side i2c current/power monitor Library
*
* <a href="http://www.ti.com/product/ina219" title="http://www.ti.com/product/ina219" rel="nofollow">http://www.ti.com/product/ina219</a>
*
* 6 May 2012 by John De Cristofaro
*
*
* Tested at standard i2c 100kbps signaling rate.
*
* This library does not handle triggered conversion modes. It uses the INA219
* in continuous conversion mode. All reads are from continous conversions.
*
* A note about the gain (PGA) setting:
*  The gain of the ADC pre-amplifier is programmable in the INA219, and can
* be set between 1/8x (default) and unity. This allows a shunt voltage 
* range of +/-320mV to +/-40mV respectively. Something to keep in mind,
* however, is that this change in gain DOES NOT affect the resolution
* of the ADC, which is fixed at 1uV. What it does do is increase noise
* immunity by exploiting the integrative nature of the delta-sigma ADC.
* For the best possible reading, you should set the gain to the range
* of voltages that you expect to see in your particular circuit. See
* page 15 in the datasheet for more info about the PGA.
*
* Known bugs:
*     * may return unreliable values if not connected to a bus or at
* bus currents below 10uA.
*
* Arduino 1.0 compatible as of 6/6/2012
*
* Dependencies:
*    * Arduino Wire library
*
* MIT license
******************************************************************************/

#ifndef ina219_h
#define ina219_h


#if ARDUINO >= 100
 #include "Arduino.h"
#else
 #include "WProgram.h"
#endif

#include <Wire.h>

#define INA219_DEBUG 1

// INA219 memory registers
#define CONFIG_R    0x00  // configuration register
#define V_SHUNT_R   0x01  // differential shunt voltage
#define V_BUS_R     0x02  // bus voltage (wrt to system/chip GND)
#define P_BUS_R     0x03  // system power draw (= V_BUS * I_SHUNT)
#define I_SHUNT_R   0x04  // shunt current
#define CAL_R     0x05  // calibration register

#define INA_RESET   0xFFFF  // send to CONFIG_R to reset unit

#define CONFIG_DEFAULT    0x399F

// config. register bit labels
#define RST 15
#define BRNG  13
#define PG1 12
#define PG0 11
#define BADC4 10
#define BADC3 9
#define BADC2 8
#define BADC1 7
#define SADC4 6
#define SADC3 5
#define SADC2 4
#define SADC1 3
#define MODE3 2
#define MODE2 1
#define MODE1 0

// default values
#define D_I2C_ADDRESS 0x40 // (64)
#define D_RANGE     1
#define D_GAIN      3
#define D_SHUNT_ADC   3
#define D_BUS_ADC   3
#define D_MODE      7
#define D_SHUNT     0.25
#define D_V_BUS_MAX   6
#define D_V_SHUNT_MAX   0.3
#define D_I_MAX_EXPECTED  1


class INA219
{
  public:
  INA219();
  
  // by default uses addr = 0x40 (both a-pins tied low)
  void begin(uint8_t addr = D_I2C_ADDRESS);

  void calibrate(float r_shunt = D_SHUNT, float v_shunt_max = D_V_SHUNT_MAX, float v_bus_max = D_V_BUS_MAX, float i_max_expected = D_I_MAX_EXPECTED);

  void configure(uint8_t range = D_RANGE, uint8_t gain = D_GAIN, uint8_t bus_adc = D_BUS_ADC, uint8_t shunt_adc = D_SHUNT_ADC, uint8_t mode = D_MODE);

  void reset();

  int16_t shuntVoltageRaw();
  int16_t busVoltageRaw();
  float shuntVoltage();
  float busVoltage();
  float shuntCurrent();
  float busPower();


  private:
  uint8_t i2c_address;
  float r_shunt, current_lsb, power_lsb;
  uint16_t config, cal, gain;

  int16_t read16(uint8_t addr);
  void write16(uint8_t addr, uint16_t data);

};

#endif

 

INA219.cpp
 

/******************************************************************************
* TI INA219 hi-side i2c current/power monitor Library
*
* <a href="http://www.ti.com/product/ina219" title="http://www.ti.com/product/ina219" rel="nofollow">http://www.ti.com/product/ina219</a>
*
* 6 May 2012 by John De Cristofaro
*
*
* Tested at standard i2c 100kbps signaling rate.
*
* This library does not handle triggered conversion modes. It uses the INA219
* in continuous conversion mode. All reads are from continous conversions.
*
* A note about the gain (PGA) setting:
*  The gain of the ADC pre-amplifier is programmable in the INA219, and can
* be set between 1/8x (default) and unity. This allows a shunt voltage 
* range of +/-320mV to +/-40mV respectively. Something to keep in mind,
* however, is that this change in gain DOES NOT affect the resolution
* of the ADC, which is fixed at 1uV. What it does do is increase noise
* immunity by exploiting the integrative nature of the delta-sigma ADC.
* For the best possible reading, you should set the gain to the range
* of voltages that you expect to see in your particular circuit. See
* page 15 in the datasheet for more info about the PGA.
*
* Known bugs:
*     * may return unreliable values if not connected to a bus or at
* bus currents below 10uA.
*
* Arduino 1.0 compatible as of 6/6/2012
*
* Dependencies:
*    * Arduino Wire library
*
* MIT license
******************************************************************************/

#include "INA219.h"
#include <util/delay.h>

INA219::INA219() {
}


void INA219::begin(uint8_t addr)
{
  Wire.begin();
  i2c_address = addr;
  gain = D_GAIN;
}


// calibration of equations and device
// shunt_val    = value of shunt in Ohms
// v_shunt_max    = maximum value of voltage across shunt
// v_bus_max    = maximum voltage of bus
// i_max_expected   = maximum current draw of bus + shunt
// default values are for a 0.25 Ohm shunt on a 5V bus with max current of 1A
void INA219::calibrate(float shunt_val, float v_shunt_max, float v_bus_max, float i_max_expected)
{
  uint16_t cal;
  float i_max_possible, min_lsb, max_lsb, swap;

  r_shunt = shunt_val;

  i_max_possible = v_shunt_max / r_shunt;
  min_lsb = i_max_expected / 32767;
  max_lsb = i_max_expected / 4096;

  current_lsb = (uint16_t)(min_lsb * 100000000) + 1;
  current_lsb /= 100000000;
  swap = (0.04096)/(current_lsb*r_shunt);
  cal = (uint16_t)swap;
  power_lsb = current_lsb * 20;

#if (INA219_DEBUG == 1)
  Serial.print("v_bus_max:  "); Serial.println(v_bus_max, 8);
  Serial.print("v_shunt_max:  "); Serial.println(v_shunt_max, 8);
  Serial.print("i_max_possible: "); Serial.println(i_max_possible, 8);
  Serial.print("i_max_expected: "); Serial.println(i_max_expected, 8);
  Serial.print("min_lsb:  "); Serial.println(min_lsb, 12);
  Serial.print("max_lsb:  "); Serial.println(max_lsb, 12);
  Serial.print("current_lsb:  "); Serial.println(current_lsb, 12);
  Serial.print("power_lsb:  "); Serial.println(power_lsb, 8);
  Serial.println("  ");
  Serial.print("cal:    "); Serial.println(cal);
  Serial.print("r_shunt:  "); Serial.println(r_shunt);
#endif

  write16(CAL_R, cal);

}


// config values (range, gain, bus adc, shunt adc, mode) can be derived from pp26-27 in the datasheet
// defaults are:
// range = 1 (0-32V bus voltage range)
// gain = 3 (1/8 gain - 320mV range)
// bus adc = 3 (12-bit, single sample, 532uS conversion time)
// shunt adc = 3 (12-bit, single sample, 532uS conversion time)
// mode = 7 (continuous conversion)
void INA219::configure(uint8_t range, uint8_t gain, uint8_t bus_adc, uint8_t shunt_adc, uint8_t mode)
{
  config = 0;

  config |= (range << BRNG | gain << PG0 | bus_adc << BADC1 | shunt_adc << SADC1 | mode);

  write16(CONFIG_R, config);    
}

// resets the INA219
void INA219::reset()
{
  write16(CONFIG_R, INA_RESET);
  _delay_ms(5);
}

// returns the raw binary value of the shunt voltage
int16_t INA219::shuntVoltageRaw()
{
  return read16(V_SHUNT_R);
}

// returns the shunt voltage in volts.
float INA219::shuntVoltage()
{
  float temp;
  temp = read16(V_SHUNT_R);
  return (temp / 100000);
}

// returns raw bus voltage binary value
int16_t INA219::busVoltageRaw()
{
  return read16(V_BUS_R);
}

// returns the bus voltage in volts
float INA219::busVoltage()
{
  int16_t temp;
  temp = read16(V_BUS_R);
  temp >>= 3;
  return (temp * 0.004);
}

// returns the shunt current in amps
float INA219::shuntCurrent()
{
  return (read16(I_SHUNT_R) * current_lsb);
}

// returns the bus power in watts
float INA219::busPower()
{
  return (read16(P_BUS_R) * power_lsb);
}


/**********************************************************************
*       INTERNAL I2C FUNCTIONS            *
**********************************************************************/

// writes a 16-bit word (d) to register pointer (a)
// when selecting a register pointer to read from, (d) = 0
void INA219::write16(uint8_t a, uint16_t d) {
  uint8_t temp;
  temp = (uint8_t)d;
  d >>= 8;
  Wire.beginTransmission(i2c_address); // start transmission to device

  #if ARDUINO >= 100
    Wire.write(a); // sends register address to read from
    Wire.write((uint8_t)d);  // write data hibyte 
    Wire.write(temp); // write data lobyte;
  #else
    Wire.send(a); // sends register address to read from
    Wire.send((uint8_t)d);  // write data hibyte 
    Wire.send(temp); // write data lobyte;
  #endif

  Wire.endTransmission(); // end transmission
  delay(1);
}


int16_t INA219::read16(uint8_t a) {
  uint16_t ret;

  // move the pointer to reg. of interest, null argument
  write16(a, 0);
  
  Wire.requestFrom((int)i2c_address, 2);  // request 2 data bytes

  #if ARDUINO >= 100
    ret = Wire.read(); // rx hi byte
    ret <<= 8;
    ret |= Wire.read(); // rx lo byte
  #else
    ret = Wire.receive(); // rx hi byte
    ret <<= 8;
    ret |= Wire.receive(); // rx lo byte
  #endif

  Wire.endTransmission(); // end transmission

  return ret;
}

Все сторонние библиотеки включаем в тело проекта, находиться будут файлами в папке проекта

Скетч сканера портов I2C:
 

// --------------------------------------
// i2c_scanner
//
// Version 1
//    This program (or code that looks like it)
//    can be found in many places.
//    For example on the Arduino.cc forum.
//    The original author is not know.
// Version 2, Juni 2012, Using Arduino 1.0.1
//     Adapted to be as simple as possible by Arduino.cc user Krodal
// Version 3, Feb 26  2013
//    V3 by louarnold
// Version 4, March 3, 2013, Using Arduino 1.0.3
//    by Arduino.cc user Krodal.
//    Changes by louarnold removed.
//    Scanning addresses changed from 0...127 to 1...119,
//    according to the i2c scanner by Nick Gammon
//    <a href="http://www.gammon.com.au/forum/?id=10896" title="http://www.gammon.com.au/forum/?id=10896" rel="nofollow">http://www.gammon.com.au/forum/?id=10896</a>
// Version 5, March 28, 2013
//    As version 4, but address scans now to 127.
//    A sensor seems to use address 120.
//
//
// This sketch tests the standard 7-bit addresses
// Devices with higher bit address might not be seen properly.
//

#include <Wire.h>


void setup()
{
  Wire.begin();

  Serial.begin(9600);
  Serial.println("\nI2C Scanner");
}


void loop()
{
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for(address = 1; address < 127; address++ )
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");

      nDevices++;
    }
    else if (error==4)
    {
      Serial.print("Unknow error at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");

  delay(5000);           // wait 5 seconds for next scan
}

 

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

откуда брал свою библиотеку для дисплея? включу в тело проекта ту, что подвернулась )))

Flikk
Offline
Зарегистрирован: 22.11.2017

Про скетч все верно, я и сам понимаю что не то у меня. Библиотека с GITHUB https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library

Буду переделывать

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Flikk пишет:

Про скетч все верно, я и сам понимаю что не то у меня. Библиотека с GITHUB https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library

Буду переделывать

Библиотеки заменил на твои, они более свежие, скомпилировалось.
1. Попробуй скетч, библиотеки надо поместить в папку скетча.
2. Если заработает, можешь показать осциллограмму?
 

PS компилирую на версии 1.8.2 под nano

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Flikk пишет:

Про скетч все верно, я и сам понимаю что не то у меня. Библиотека с GITHUB https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library

Буду переделывать

И что со скетчем, работает?

Flikk
Offline
Зарегистрирован: 22.11.2017

Пока руки не дошли. Все время уходит на зарабатывание денег.

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Flikk пишет:

Пока руки не дошли. Все время уходит на зарабатывание денег.

Так там делов на пять минут )))

Flikk
Offline
Зарегистрирован: 22.11.2017

Попробовал сетч. Компелируется, но после загрузки программа стопается на 118 строке

AD9833reset(); 

До этой строки все выполняется, как доходит, так и останавливается. Смотрел через SerialPrint();

Есть какие мысли?

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Есть! Процедура должна выполняться сразу после включения питания. Перетащил ее в первую строку процедуры setup(); #26

Flikk
Offline
Зарегистрирован: 22.11.2017

Разобрался. В void setup(); нужно было добавить SPI.begin(); 

Алгоритм мне понятен и все логично, Ишим экстремум грубо, затем отрезок +- 20кГц пробегаем по 500Гц и находим точно максимум. Но нужно усреднять показания тока, слишком быстро меняются значения. По предложенному алгоритму у меня генератор стопается на 230кГц и бывает ещё на 330кГц. А реальная резонансная частота катушки 304кГц. Видимо автонастройка стопается на гармониках. Курим алгоритм дальше

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Flikk пишет:

Разобрался. В void setup(); нужно было добавить SPI.begin(); 

Алгоритм мне понятен и все логично, Ишим экстремум грубо, затем отрезок +- 20кГц пробегаем по 500Гц и находим точно максимум. Но нужно усреднять показания тока, слишком быстро меняются значения. По предложенному алгоритму у меня генератор стопается на 230кГц и бывает ещё на 330кГц. А реальная резонансная частота катушки 304кГц. Видимо автонастройка стопается на гармониках. Курим алгоритм дальше

Поправил в скетче.
INA219 уже работает в режиме расчёта среднего значения, по всей видимости надо подобрать значение режима.
Ненужное закоментируем, нужное - открываем.

Строки 106 и 109 чуток поправил, константу задержки на накопление результата тока - тоже

 

Flikk
Offline
Зарегистрирован: 22.11.2017

Спасибо разобрался. Пока пытался заставить работать скетч переписал его на библиотеку Adafruit_INA219. 

Короче все заработало ток при резонансе держится на отметке 400 ма. Частота находится за 3 секунды примерно и держится уверенно. Подстройку сделал просто через условие, что если ток питания стал меньше максимального- то запускаем ещё раз цикл поиска ренанса. находится быстро и уверенно. 

Осциллографа пока нет и не могу снять форму и фазу тока и напряжения. 

От катушки чувствуется тепло если поднести ладонь, пока все

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Flikk пишет:

Спасибо разобрался. Пока пытался заставить работать скетч переписал его на библиотеку Adafruit_INA219. 

Короче все заработало ток при резонансе держится на отметке 400 ма. Частота находится за 3 секунды примерно и держится уверенно. Подстройку сделал просто через условие, что если ток питания стал меньше максимального- то запускаем ещё раз цикл поиска ренанса. находится быстро и уверенно. 

Осциллографа пока нет и не могу снять форму и фазу тока и напряжения. 

От катушки чувствуется тепло если поднести ладонь, пока все

скетч в студию

Flikk
Offline
Зарегистрирован: 22.11.2017
#include <Wire.h>
#include <SPI.h>
#include <Wire.h>
#include "LiquidCrystal_I2C.h"
LiquidCrystal_I2C lcd(0x27, 20, 4);   // Для экрана 20х4 (четырехстрочный), I2C адрес дисплея уточнить

#include <Adafruit_INA219.h>
Adafruit_INA219 ina219;

unsigned int imax = 0;
unsigned int Data_ina219 = 0;

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

const float refFreq = 25000000.0;           // Частота кристалла на плате AD9833

long Fmin = 200000;
long Fmax = 350000;
long FFmax = 0;
long freq = Fmin;
long ifreq = 0;
int Ftune = 10000;
int 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;



/************************** SETUP *************************/ 
void setup() {
 Serial.begin(9600);
 lcd.begin();
 ina219.begin(0x40);
 ina219.setCalibration_16V_400mA();  
 SPI.begin();
             
 delay(10); 
 AD9833reset(); // Ресет после включения питания
 delay(10);
 
 AD9833setFrequency(freq, SINE);  // выставляем нижнюю частоту 
    
for (int i=1; i <= 15; i++) {
    Data_ina219=ina219.getCurrent_mA();
    if (Data_ina219 > imax){ imax=Data_ina219; ifreq = freq; } // Если значение больше, то запомнить
    if (freq >=Fmax) {freq = Fmax;}
     freq=freq+Ftune;
     AD9833setFrequency(freq, SINE);
     delay(2);
    }
    freq = ifreq-10000;
    FFmax =ifreq +10000;
    imax = 0;
    AD9833setFrequency(freq, SINE);                  // 
for (int j=1; j <= 100; j++) {
    Data_ina219=ina219.getCurrent_mA();
    if (Data_ina219 > imax){ imax=Data_ina219; ifreq = freq; } // Если значение больше, то запомнить
    lcd.setCursor(0, 2);                  // 2 строка
    lcd.print(ifreq);
    freq=freq+Ffinetune;
    AD9833setFrequency(ifreq, SINE);
    if (freq >=FFmax) {freq = FFmax;}  
    Data_ina219=ina219.getCurrent_mA();
    lcd.setCursor(0, 0);                  // 1 строка
    lcd.print("GENERATOR MPGSP-V1.0");
    lcd.setCursor(0, 1);                  // 2 строка
    lcd.print("Freq = ");
    lcd.print(ifreq);
    lcd.setCursor(0, 3);                  // 4 строка
    lcd.print("TOK = ");
    lcd.setCursor(7, 3);                  // 4 строка 7 позиция
    lcd.print(Data_ina219);
    delay(1);
}

    
 }    // Конец процедуры инициализации прибора

void loop() {
   Data_ina219=ina219.getCurrent_mA();
    lcd.setCursor(0, 1);                  // 2 строка
    lcd.print("Freq = ");
    lcd.print(ifreq);
    lcd.setCursor(0, 3);                  // 4 строка
    lcd.print("TOK = ");
    lcd.setCursor(7, 3);                  // 4 строка 7 позиция
    lcd.print(Data_ina219);
    delay(200);
if(Data_ina219 < imax ){
  
  for (int i=1; i <= 15; i++) {
    Data_ina219=ina219.getCurrent_mA();
    if (Data_ina219 > imax){ imax=Data_ina219; ifreq = freq; } // Если значение больше, то запомнить
    if (freq >=Fmax) {freq = Fmax;}
     freq=freq+Ftune;
     AD9833setFrequency(freq, SINE);
    }
    freq = ifreq-10000;
    FFmax =ifreq +10000;
    imax = 0;
    AD9833setFrequency(freq, SINE);                  // Set the frequency and Sine Wave output 
for (int j=1; j <= 100; j++) {
    Data_ina219=ina219.getCurrent_mA();
    if (Data_ina219 > imax){ imax=Data_ina219; ifreq = freq; } // Если значение больше, то запомнить
    freq=freq+Ffinetune;
    AD9833setFrequency(ifreq, SINE);
    if (freq >=FFmax) {freq = FFmax;}
   }
  lcd.clear();//Очистка дисплея
  
  }
    
}

// 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

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

Работает, пробуйте хотя это тот же код что и у вас

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

я не попробую, у меня AD9833 пока еще нет )))
На фрутовской библиотеке скетч поменьше памяти забирает )))
Всё закинул в папку скетча, поправил кавычки и скомпилировал
Да, ток при 9 вольтах на исправной микросхеме будет и более 1 ампера, надо поправить в коде
учитывая этот параметр, как это будет выглядеть? (с библиотекой не разбирался)
 

sem_pai
Offline
Зарегистрирован: 02.03.2018

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

С нетерпением жду продолжения проекта. Я делал такие генераторы на 2206. Люди пользуются. Отзывы отличные.

Для улучшения параметров и юзабельности прибора давно смотрел в сторону Ардуино платформы. Но, к сожаления я не программист. Плату развести, дизайн сделать, спаять - это да. Да и времени не особо. На вас вся надежа.

С уважением

Flikk
Offline
Зарегистрирован: 22.11.2017

По току в коде ничего и нет, находит максимум и все. Думаю нужно поискать как регулировать уровень сигнала с AD9833, библиотеку пока не смотрел.

Можно конечно прикрутить еще модуль електронного сопротивления, но это увеличивает бюджет

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Так прототипируйте, код уже рабочий. Рабочее напряжение питания 9 вольт, при 12 вольтах  токи будут очень большие, это то минимальное напряжение при котором на осциллограмме видна имплозия )))
С выхода AD9833 на вход TDA резисторный делитель.
Схема надеюсь понятна.
Дисплей подключается по шине I2C

 

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Flikk пишет:

По току в коде ничего и нет

Как это нет, смотрим строка 38 -  ina219.setCalibration_16V_400mA(); 

 

Flikk
Offline
Зарегистрирован: 22.11.2017

Сори, исправлюсь

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Вот так будет выглядеть под мои деталюшки:
 

#include <Wire.h>
#include <SPI.h>
#include "LiquidCrystal_I2C.h"
LiquidCrystal_I2C lcd(0x3F, 20, 4);   // Для экрана 20х4 (четырехстрочный), I2C адрес дисплея уточнить

#include "Adafruit_INA219.h"
Adafruit_INA219 ina219;

unsigned int imax = 0;
unsigned int Data_ina219 = 0;

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

const float refFreq = 25000000.0;           // Частота кристалла на плате AD9833

long Fmin = 200000;
long Fmax = 350000;
long FFmax = 0;
long freq = Fmin;
long ifreq = 0;
int Ftune = 10000;
int 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;


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

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


/************************** SETUP *************************/ 
void setup() {
 SPI.begin();
 Serial.begin(9600);
 lcd.begin();
 ina219.begin(0x40);
// ina219.setCalibration_16V_400mA();  
 ina219.setCalibration_32V_2A();  // Интересно, в библиотеку можно внести изменения 
                                  // сделав свои параметры калибровки? надо 16V 2A
           
 delay(10); 
 AD9833reset(); // Ресет после включения питания
 delay(10);
 
 AD9833setFrequency(freq, SINE);  // выставляем нижнюю частоту 
    
for (int i=1; i <= 15; i++) {
    Data_ina219=ina219.getCurrent_mA();
    if (Data_ina219 > imax){ imax=Data_ina219; ifreq = freq; } // Если значение больше, то запомнить
    if (freq >=Fmax) {freq = Fmax;}
     freq=freq+Ftune;
     AD9833setFrequency(freq, SINE);
     delay(2);
    }
    freq = ifreq-10000;
    FFmax =ifreq +10000;
    imax = 0;
    AD9833setFrequency(freq, SINE);                  // 
for (int j=1; j <= 100; j++) {
    Data_ina219=ina219.getCurrent_mA();
    if (Data_ina219 > imax){ imax=Data_ina219; ifreq = freq; } // Если значение больше, то запомнить
    lcd.setCursor(0, 2);                  // 2 строка
    lcd.print(ifreq);
    freq=freq+Ffinetune;
    AD9833setFrequency(ifreq, SINE);
    if (freq >=FFmax) {freq = FFmax;}  
    Data_ina219=ina219.getCurrent_mA();
    lcd.setCursor(0, 0);                  // 1 строка
    lcd.print("GENERATOR MPGSP-V1.0");
    lcd.setCursor(0, 1);                  // 2 строка
    lcd.print("Freq = ");
    lcd.print(ifreq);
    lcd.setCursor(0, 3);                  // 4 строка
    lcd.print("TOK = ");
    lcd.setCursor(7, 3);                  // 4 строка 7 позиция
    lcd.print(Data_ina219);
    delay(1);
} 
 }    // Конец процедуры инициализации прибора


// ТЕЛО ПРОГРАММЫ

void loop() {
   Data_ina219=ina219.getCurrent_mA();
    lcd.setCursor(0, 1);                  // 2 строка
    lcd.print("Freq = ");
    lcd.print(ifreq);
    lcd.setCursor(0, 3);                  // 4 строка
    lcd.print("TOK = ");
    lcd.setCursor(7, 3);                  // 4 строка 7 позиция
    lcd.print(Data_ina219);
    delay(200);
if(Data_ina219 < imax ){
  
  for (int i=1; i <= 15; i++) {
    Data_ina219=ina219.getCurrent_mA();
    if (Data_ina219 > imax){ imax=Data_ina219; ifreq = freq; } // Если значение больше, то запомнить
    if (freq >=Fmax) {freq = Fmax;}
     freq=freq+Ftune;
     AD9833setFrequency(freq, SINE);
    }
    freq = ifreq-10000;
    FFmax =ifreq +10000;
    imax = 0;
    AD9833setFrequency(freq, SINE);                  // Set the frequency and Sine Wave output 
for (int j=1; j <= 100; j++) {
    Data_ina219=ina219.getCurrent_mA();
    if (Data_ina219 > imax){ imax=Data_ina219; ifreq = freq; } // Если значение больше, то запомнить
    freq=freq+Ffinetune;
    AD9833setFrequency(ifreq, SINE);
    if (freq >=FFmax) {freq = FFmax;}
   }
  lcd.clear();//Очистка дисплея
  
  }  
}



 

AleksandrM
Offline
Зарегистрирован: 20.07.2017

Заработало.Долго возился Пришлось подредактировать  строку

080 ina219.begin(0x40);

в такой вид

080 ina219.begin();

Причину не знаю ,может кто подскажет?

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Адрес видимо не совпал, надо перемычки запаивать под нужный адрес, по умолчанию они разомкнуты и не на всех модулях адрес поднимался правильно

AleksandrM
Offline
Зарегистрирован: 20.07.2017

Сканер показывает правильный адрес 0х40

И еще наблюдаеться болтанка тока и частоты в пределах 10-15 милиампер и частоты в пределах килогерц 10-15....

Может из за монтажа .... Пока все на проводочках.... Или из за питания все питаю от USB

 

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

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