вот и я о том же,
40 лет назад упал с высоты спиной на перекладину,
всё время чем только не лечился ,а тут реально намного лучше.
комп новый,на нём нет ничего чем можно код открыть.
у кого есть возможность зайти на яндекс диск,скачать и сюда выложить.
program.ino
// Генератор для катушки Мишина на основе DDS AD9833
/* 06.05.2022
* - Переработал программу для 2-строчного экрана
*
* 11.06.2022
* - Во время работы отключил возможность крутить время
* - В меня при работе изменил Таймре на Т, добавил знак V
* - Добавил всем пинам имя
* - Определил пины для потенциометра ...
* - Добавил управление потенциометром с помощью энкодера
*
* 03.07.2022
* - перенес инициализацию потенциометра в начало setup
*/
#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 isWorkStarted = 0; // флаг запуска таймера
unsigned long timMillis = 0;
unsigned long oldMillis = 0;
unsigned long mill; // переменная под millis()
unsigned long prevCorrectTime = 0;
unsigned long prevReadAnalogTime = 0; // для отсчета 10 секунд между подстройкой частоты
unsigned long prevUpdateDataIna = 0; // для перерыва между обновлениями данных ina
#include <Wire.h>
#include <SPI.h>
#include <LCD_1602_RUS.h> // https://github.com/ssilver2007/LCD_1602_RUS
LCD_1602_RUS lcd(0x3F, 16, 2); // используемый дисплей (0x3F, 16, 2) адрес,символов в строке,строк.
#include "INA219.h"
INA219 ina219;
// PINS
#define CORRECT_PIN A7 // пин для внешней корректировки частоты.
#define ON_OFF_CASCADE_PIN 5 // для выключения выходного каскада
#define PIN_ENCODER1 6
#define PIN_ENCODER2 7
#define PIN_ENCODER3 3
#define PIN_ENCODER_BUTTON 8
#define PIN_ZUM 9
#define PIN_FSYNC 10
// пины потенциометра
#define PIN_CS 4
#define PIN_INC A1
#define PIN_UD A2
#define zFreq 2 // делитель интервала - секунда/2
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 FREQ_MIN = 200000; // 200kHz
long FREQ_MAX = 500000; // 500kHz
long ifreq = FREQ_MIN;
long freq = FREQ_MIN;
const unsigned long availableTimers[] = {oneMinute * 15, oneMinute * 30, oneMinute * 45, oneMinute * 60};
const byte maxTimers = 4;
int timerPosition = 0;
// по умолчанию 50% потенциометра
int currentPotenciometrPercent = 50;
/********* используемые подпрограммы выносим сюда *********/
/*** Обработчик кнопки энкодера ***/
//------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(PIN_ENCODER_BUTTON); //Экземпляр обработчика для кнопки энкодера
/******* Простой энкодер *******/
#include <util/atomic.h> // для атомарности чтения данных в прерываниях
#include <RotaryEncoder.h>
RotaryEncoder encoder(PIN_ENCODER1, PIN_ENCODER2);
volatile int newEncoderPos; // новая позиция энкодера
static int currentEncoderPos = 0; // текущая позиция энкодера
/*** Обработчик прерывания для энкодера ***/
ISR(PCINT2_vect) {encoder.tick();}
// функция выбора времени работы
void setTimer() {
// если энкодер крутим по часовой
if (newEncoderPos - currentEncoderPos > 0) {
if (timerPosition == maxTimers - 1) {
timerPosition = 0;
} else {
timerPosition += 1;
}
} else if (newEncoderPos - currentEncoderPos < 0) {
// если энкодер крутим против часовой
if (timerPosition == 0) {
timerPosition = maxTimers - 1;
} else {
timerPosition -= 1;
}
}
memTimers = availableTimers[timerPosition];
}
void resetPotenciometer() {
// Понижаем сопротивление до 0%:
analogWrite(PIN_UD, 0); // выбираем понижение
digitalWrite(PIN_CS, LOW); // выбираем потенциометр X9C
for (int i=0; i<100; i++) { // т.к. потенциометр имеет 100 доступных позиций
analogWrite(PIN_INC, 0);
delayMicroseconds(1);
analogWrite(PIN_INC, 255);
delayMicroseconds(1);
}
digitalWrite(PIN_CS, HIGH); /* запоминаем значение и выходим из режима настройки */
}
// Уровень percent - от 0 до 100% от максимума.
void setResistance(int percent) {
resetPotenciometer();
// Поднимаем сопротивление до нужного:
analogWrite(PIN_UD, 255); // выбираем повышение
digitalWrite(PIN_CS, LOW); // выбираем потенциометр X9C
for (int i=0; i < percent; i++) {
analogWrite(PIN_INC, 0);
delayMicroseconds(1);
analogWrite(PIN_INC, 255);
delayMicroseconds(1);
}
digitalWrite(PIN_CS, HIGH); /* запоминаем значение и выходим из режима настройки */
}
void processPotenciometr() {
// если энкодер крутим по часовой
if (newEncoderPos - currentEncoderPos > 0) {
if (currentPotenciometrPercent >= 100) {
currentPotenciometrPercent = 100;
} else {
currentPotenciometrPercent += 1;
}
} else if (newEncoderPos - currentEncoderPos < 0) {
// если энкодер крутим против часовой
if (currentPotenciometrPercent <= 1) {
currentPotenciometrPercent = 1;
} else {
currentPotenciometrPercent -= 1;
}
}
setResistance(currentPotenciometrPercent);
}
/*** Обработчик энкодера через ШИМ ***/
void startEncoder() {
attachInterrupt(1, Encoder2, RISING );
analogWrite(PIN_ENCODER3, 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;
isWorkStarted = 0;
lcd.setCursor(0, 3);
lcd.print(" ЗАВЕРШЕНО! ");
digitalWrite(ON_OFF_CASCADE_PIN, LOW);
start_Buzzer();
delay(3000);
stop_Buzzer();
AD9833reset();
}
return timlcd;
}
/*******************ПИЩАЛКА ********************/
void start_Buzzer() {
digitalWrite(PIN_ZUM, HIGH);
}
void stop_Buzzer() {
digitalWrite(PIN_ZUM, LOW);
}
// ******************* Обработка 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(PIN_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(PIN_FSYNC, HIGH); //Write done. Set FSYNC high
}
long readAnalogAndSetFreqInSetup() {
int maxValue = 0;
long freqWithMaxI = FREQ_MIN;
long freqIncrease = 1000; // 1kHz
int iterations = (FREQ_MAX-FREQ_MIN)/freqIncrease - 1; // (500000 - 200000) / 1000 - 1 = 199
for (int j = 1; j <= iterations; j++) {
// читаем значение аналогового входа
int tempValue = analogRead(CORRECT_PIN);
// если значение тока больше предыдущего, запоминаем это значение и текущую частоту
if (tempValue > maxValue) {
maxValue = tempValue;
freqWithMaxI = freq;
}
// увеличиваем частоту для дальнейшего измерения тока
freq = freq + freqIncrease;
if (freq > FREQ_MAX) {
freq = FREQ_MAX;
}
// подаём частоту на генератор
AD9833setFrequency(freq, SINE);
delay(20);
}
ifreq = freqWithMaxI;
AD9833setFrequency(ifreq, SINE);
prevReadAnalogTime = millis();
}
/**** Подстройка частоты каждые 1-10 секунд относительно аналогового сигнала ***/
void readAnalogAndSetFreqInLoop() {
unsigned long curr = millis();
// если прошло N секунд с момента последней проверки
if (curr - prevReadAnalogTime > 1000 * 5) { //выбор времени изменения частоты.1-10 сек.
long availableDiff = 5000; // 1kHz-10kHz разница частот
long freqIncrease = 500; // 100Hz-1kHz шаг увеличения частоты при сканировании
int iterations = (availableDiff * 2) / freqIncrease - 1; // (10000 * 2) / 1000 - 1 = 19
long minimalFreq = ifreq - availableDiff;
if (minimalFreq < FREQ_MIN) {
minimalFreq = FREQ_MIN;
}
// подаём на генератор минимальную частоту из диапазона +-10кГц
AD9833setFrequency(minimalFreq, SINE);
delay(20);
int maxValue = 0;
long freqWithMaxI = minimalFreq;
freq = minimalFreq;
for (int j = 1; j <= iterations; j++) {
// читаем значение аналогового входа
int tempValue = analogRead(CORRECT_PIN);
// если значение тока больше предыдущего, запоминаем это значение и текущую частоту
if (tempValue > maxValue) {
maxValue = tempValue;
freqWithMaxI = freq;
}
// увеличиваем частоту для дальнейшего измерения тока
freq = freq + freqIncrease;
if (freq > FREQ_MAX) {
freq = FREQ_MAX;
}
// подаём частоту на генератор
AD9833setFrequency(freq, SINE);
delay(10);
}
ifreq = freqWithMaxI;
AD9833setFrequency(ifreq, SINE);
prevReadAnalogTime = millis();
}
}
//************************** SETUP *************************/
void setup() {
// настройки потенциометра
// сначала настраиваем потенциометр
pinMode(PIN_CS, OUTPUT);
pinMode(PIN_INC, OUTPUT);
pinMode(PIN_UD, OUTPUT);
digitalWrite(PIN_CS, HIGH); // X9C в режиме низкого потребления
analogWrite(PIN_INC, 255);
analogWrite(PIN_UD, 255);
delay(30);
// сбрасываем потенциометр в 0%
resetPotenciometer();
// после сброса устанавливаем значение по умолчанию
setResistance(currentPotenciometrPercent);
// ждем секунду после настройки потенциометра
delay(1000);
Btn1.init();
SPI.begin();
Serial.begin(115200);
pinMode(ON_OFF_CASCADE_PIN, OUTPUT);
pinMode(PIN_ZUM, OUTPUT);
pinMode(CORRECT_PIN, INPUT);
digitalWrite(PIN_ZUM, LOW);
digitalWrite(ON_OFF_CASCADE_PIN, HIGH);
analogReference(INTERNAL);
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);
Serial.print("freq=");
Serial.println(freq);
// выставляем минимальную частоту для цикла определения максимального тока
AD9833setFrequency(FREQ_MIN, SINE);
delay(20);
readAnalogAndSetFreqInSetup();
Data_ina219=ina219.shuntCurrent() * 1000;
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() == sbLong){
oldmemTimers=memTimers;
timMillis = millis();
isWorkStarted = 1;
}
if (mill - prevUpdateDataIna > 1000 * 2) {
Data_ina219=ina219.shuntCurrent() * 1000;
prevUpdateDataIna = millis();
}
myDisplay();
if (isWorkStarted == 1) {
memTimers = setTimerLCD(memTimers);
}
ATOMIC_BLOCK(ATOMIC_RESTORESTATE){
newEncoderPos = encoder.getPosition();
}
// если значение экодера поменялось
if (currentEncoderPos != newEncoderPos) {
// если работа ещё не началась, то можем устанавливать время
if (isWorkStarted == 0) {
setTimer();
} else if (isWorkStarted == 1) {
// если работа ещё началась, то можем редактировать потенциометр
processPotenciometr();
}
currentEncoderPos = newEncoderPos;
}
readAnalogAndSetFreqInLoop();
}
display.ino
void myDisplay() {
// 1 строка
lcd.setCursor(0, 0);
if (!isWorkStarted) {
lcd.print("Время-");
lcd.print(memTimers/60000);
lcd.print(" мин. ");
} else {
lcd.print("Т-");
if (memTimers > 60000) {
// если больше минуты, то показываем минуты
lcd.print(memTimers / 1000 / 60);
lcd.print("мин.");
} else {
// если меньше минуты, то показываем секунды
lcd.print(memTimers / 1000);
lcd.print("сек.");
}
lcd.print(" U=");
lcd.print(currentPotenciometrPercent);
lcd.print("% ");
}
// 2 строка
lcd.setCursor(0, 1);
lcd.print("F=");
//lcd.setCursor(3, 1); //1 строка 7 позиция
float freq_tic = ifreq;
float kHz = freq_tic/1000;
lcd.print(kHz, 0);
lcd.print("kHz");
// 2 строка
lcd.setCursor(9, 1);
lcd.print("I=");
lcd.setCursor(11, 1);
lcd.print(Data_ina219*2);
lcd.print("ma");
}
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;
}
Да. Эта схема нарисована одним нашим коллегой с моей схемы нарисованной на листке.
А можно ли, с помощью этой катушки, увеличить член на пару самнтиметров. Жене в отместку, ибо ображается.(
тут лучше аппарат, тот что для космонавтов, подойдёт, он жеж двойного действия
на Кавказе это алмасты
тут другой вопрос, в инете много предложений по такому генератору выполненному на промышленном уровне, может проще купить?
Знаю, что ведутся разработки генератора с модуляцией низкими частотами (по Хильде Кларк и автору темнопольного микроскопа), та тема, что Мишин с Гаряевым обсуждали, но Гаряев свою матрицу в качестве модулирующего сигнала предложил
неправильно ТТ включен, он должен работать на низкоомную нагрузку.
т.е. после диодного моста резистор на землю 10-100 Ом.
какой конкретно это считать надо
Скажем макс ток катушки 1А, тогда ТТ 1/100 отдаст 10мА,
и при 100 Ом нагрузки на выходе будет 1В
Сильно увеличивать резистор нельзя иначе ТТ перестанет работать как трансформатор тока.
L/R >= 10*1/2f - условие неискаженной передачи тока.
L- это индуктивность обмотки ТТ
R- резистор нагрузки
f -частота генератора
Раз R небольшое желательно чтобы и сопротивление обмотки было минимальным, т.к. оно вносит погрешность.
тогда и AREF надо скорректировать, не 4-4.5 вольта, а где-то 1.5
на резонансе, на ковиде, ток увеличивался с одного ампера до 1.4 - 1.5, укладываемся
Можно пожалуйста небольшой рисунок схемы?
Удалить R11 и изменить сопротивление R12 на 100 Ом?
правильно
надо тогда конденсатор убирать, иначе мост будет нагружен на емкость.
или R12 =100 и перенести на другую сторону от R11.
тогда емкость и R11 образуют фнч на входе ацп, параметры которого нужно посчитать.
Считать параметры? Для этого? Ну, где ток примерно такой, частота - около этого, но резонанс что-бы был вроде близкий к этому и …
Главное, что-бы “Решение средствами электростатики заключается в создании притока среды внутрь кластера, чтобы добиться его размагничивания, ослабления и размыкания вихревых связей. Это достигается за счет образования зоны пониженной плотности с помощью электростатического резонанса. Мы получаем втягивание среды в эту зону, аналогичное по механизму гравитационному притяжению”(с)
теперь бы ещё перевести на понятный язык, что он сказать хотел )))