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

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

это был просто набросок, начало кода...
Ждём тогда alp... у меня пока что не на чем отлаживать
 

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

Наверное надо пройтись по шагам, буду собирать в чистой версии 1.8.9:
1. Для начала засветим дисплей, ниже будет код, не цитируйте пожалуйста.
    Библиотеку возьму отсюда, она русифицирована

    Не взлетело, заработало на библиотеке V112 но скетч немного поправил, вечером исправлю - выложу
   Так как девайса нету проверил только работу дисплея, всё остальное закомментировано
   надо  - расскомментировать строки с 104 по 112 и проверить установку максимума тока и отображение на дисплей

 

#include <Wire.h>
#include <SPI.h>
#include "LiquidCrystal_I2C.h"        // брал здесь - https://iarduino.ru/file/134.html
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
}

// Процедура грубой настройки частоты по максимальному току
 void setFreq(){
 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);
    } 
 }

// Процедура тонкой настройки частоты по максимальному току
 void setFFreq(){
    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(freq, SINE);
     if (freq >=FFmax) {freq = FFmax;} 
     Data_ina219=ina219.getCurrent_mA();
    } 
 }

//************************** SETUP *************************/
void setup() { 
  SPI.begin();
  Serial.begin(115200);
  lcd.init();
  lcd.backlight();
  delay(10);     
 // ina219.begin(0x40); //такая конфигурация конфликтует с дисплеем
  ina219.begin();
 // ina219.setCalibration_16V_400mA(); 
  ina219.setCalibration_32V_2A();  // Интересно, в библиотеку можно внести изменения
  delay(10);                       // сделав свои параметры калибровки? надо 16V 2A
  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.getCurrent_mA();
  
    lcd.setCursor(2, 0);                  // 1 строка, начало
    lcd.print("Freq = ");
    float freq_tic = ifreq/1000;
    lcd.print(freq_tic,2);
    lcd.print("kHz");
    lcd.setCursor(2, 1);                  // 2 строка, начало
    lcd.print("I = ");
  //  lcd.setCursor(5, 1);                  // 2 строка 7 позиция
    lcd.print(Data_ina219);
    lcd.print("ma");
    lcd.setCursor(2, 3); 
    lcd.print("Generator AD9833");
    delay(1);

  }    // Конец процедуры инициализации прибора
  
 
// ТЕЛО ПРОГРАММЫ
 
void loop() {

 // Data_ina219=ina219.getCurrent_mA();

 // lcd.setCursor(0, 0);                  // 1 строка
 // lcd.print("Freq = ");
 
   lcd.setCursor(9, 0);                   //1 строка 7 позиция
   float freq_tic = ifreq/1000;
   lcd.print(freq_tic,2);
   lcd.print("kHz");
   lcd.setCursor(2, 1);                  // 2 строка
   lcd.print("I = ");
  // lcd.setCursor(5, 1);                  // 2 строка 7 позиция
   lcd.print(Data_ina219);
   lcd.print("ma");
   lcd.setCursor(2, 3); 
   lcd.print("Generator AD9833");
   delay(200);
 } //END

 

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

Заработало?
SPI C I2C ПО ПИНАМ НЕ ПЕРЕСЕКАЮТСЯ

АндрейS
Offline
Зарегистрирован: 13.04.2018

При компиляции выдает ошибку:  error: 'Adafruit_INA219' does not name a type
 Adafruit_INA219 ina219;

exit status 1
'Adafruit_INA219' does not name a type
 

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

АндрейS пишет:

При компиляции выдает ошибку:  error: 'Adafruit_INA219' does not name a type
 Adafruit_INA219 ina219;

exit status 1
'Adafruit_INA219' does not name a type
 

компилировал в версии 1.8.9, библиотеки положил в неё в папку libraries

АндрейS
Offline
Зарегистрирован: 13.04.2018

Передела немного схему Ивана-исполина. Генератор заработал в ручном режиме на сктече Владимира из блога https://tsibrov.blogspot.com/2018/06/ad9833.html

#include <SPI.h>
// ***** I2C дисплей *****
#include <LiquidCrystal_I2C.h> // https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library
#define cols 20
#define rows 4
LiquidCrystal_I2C lcd(0x27, cols, rows);
char *Blank;

// ********** AD9833 **********
#define bMode 0x2
#define bDiv2 0x8
#define bOpbiten 0x20
#define bSleep12 0x40
#define bSleep1 0x80
#define bReset 0x100
#define bHLB 0x1000
#define bB28 0x2000
#define bCntrl_reg 0x0
#define bFreq_reg0 0x4000
#define bFreq_reg1 0x8000
#define bPhase_reg 0xC000

unsigned long Freq;
unsigned long FreqStep;
int Phase;
enum eWaveForm {wfSin, wfTri, wfSqr, wfSqr2};
eWaveForm WaveForm;

// ********** Параметры меню **********
#define ShowScrollBar 1     // Показывать индикаторы прокрутки (0/1)
#define ScrollLongCaptions 1// Прокручивать длинные названия (0/1)
#define ScrollDelay 800     // Задержка при прокрутке текста
#define BacklightDelay 20000// Длительность подсветки
#define ReturnFromMenu 1    // Выходить из меню после выбора элемента(0/1)

enum eMenuKey {mkNull, mkBack, mkRoot, mkSetFreq, mkSetPhase, mkForm, mkSin, mkTri, mkSquare,
               mkSquareDiv2, mkInc, mkInc1, mkInc10, mkInc100, mkInc1000, mkAbout
              };

// ********** Переменные для энкодера ***************
#define pin_CLK 6 // Энкодер пин A
#define pin_DT  5 // Энкодер пин B
#define pin_Btn 4 // Кнопка

unsigned long CurrentTime, PrevEncoderTime;
enum eEncoderState {eNone, eLeft, eRight, eButton};
eEncoderState EncoderState;
int EncoderA, EncoderB, EncoderAPrev, counter;
bool ButtonPrev;

// ********** Прототипы функций ***************
eEncoderState GetEncoderState();
void LCDBacklight(byte v = 2);
eMenuKey DrawMenu(eMenuKey Key);

// ******************** Меню ********************
byte ScrollUp[8]  = {0x4, 0xa, 0x11, 0x1f};
byte ScrollDown[8]  = {0x0, 0x0, 0x0, 0x0, 0x1f, 0x11, 0xa, 0x4};

byte ItemsOnPage = rows;    // Максимальное количество элементов для отображения на экране
unsigned long BacklightOffTime = 0;
unsigned long ScrollTime = 0;
byte ScrollPos;
byte CaptionMaxLength;

struct sMenuItem {
  eMenuKey  Parent;       // Ключ родителя
  eMenuKey  Key;          // Ключ
  char      *Caption;     // Название пункта меню
  void      (*Handler)(); // Обработчик
};

sMenuItem Menu[] = {
  {mkNull, mkRoot, "Menu", NULL},
    {mkRoot, mkSetFreq, "Set frequency", NULL},
    {mkRoot, mkSetPhase, "Set phase", NULL},
    {mkRoot, mkForm, "Set wave form", NULL},
      {mkForm, mkSin, "Sinusoidal", NULL},
      {mkForm, mkTri, "Triangular", NULL},
      {mkForm, mkSquare, "Square", NULL},
      {mkForm, mkSquareDiv2, "Square F/2", NULL},
      {mkForm, mkBack, "Back", NULL},
    {mkRoot, mkInc, "Set frequency increment value", NULL},
      {mkInc, mkInc1, "1 HZ", NULL},
      {mkInc, mkInc10, "10 HZ", NULL},
      {mkInc, mkInc100, "100 HZ", NULL},
      {mkInc, mkInc1000, "1000 HZ", NULL},
      {mkInc, mkBack, "Back", NULL},
    {mkRoot, mkAbout, "About", NULL},
    {mkRoot, mkBack, "Back", NULL}
};

const int MenuLength = sizeof(Menu) / sizeof(Menu[0]);

void LCDBacklight(byte v) { // Управление подсветкой
  if (v == 0) { // Выключить подсветку
    BacklightOffTime = millis();
    lcd.noBacklight();
  }
  else if (v == 1) { //Включить подсветку
    BacklightOffTime = millis() + BacklightDelay;
    lcd.backlight();
  }
  else { // Выключить если время вышло
    if (BacklightOffTime < millis())
      lcd.noBacklight();
    else
      lcd.backlight();
  }
}

eMenuKey DrawMenu(eMenuKey Key) { // Отрисовка указанного уровня меню и навигация по нему
  eMenuKey Result;
  int k, l, Offset, CursorPos, y;
  sMenuItem **SubMenu = NULL;
  bool NeedRepaint;
  String S;
  l = 0;
  LCDBacklight(1);
  // Запишем в SubMenu элементы подменю
  for (byte i = 0; i < MenuLength; i++) {
    if (Menu[i].Key == Key) {
      k = i;
    }
    else if (Menu[i].Parent == Key) {
      l++;
      SubMenu = (sMenuItem**) realloc (SubMenu, l * sizeof(void*));
      SubMenu[l - 1] = &Menu[i];
    }
  }

  if (l == 0) { // l==0 - подменю нет
    if ((ReturnFromMenu == 0) and (Menu[k].Handler != NULL)) (*Menu[k].Handler)(); // Вызываем обработчик если он есть
    LCDBacklight(1);
    return Key; // и возвращаем индекс данного пункта меню
  }

  // Иначе рисуем подменю
  CursorPos = 0;
  Offset = 0;
  ScrollPos = 0;
  NeedRepaint = 1;
  do {
    if (NeedRepaint) {
      NeedRepaint = 0;
      lcd.clear();
      y = 0;
      for (int i = Offset; i < min(l, Offset + ItemsOnPage); i++) {
        lcd.setCursor(1, y++);
        lcd.print(String(SubMenu[i]->Caption).substring(0, CaptionMaxLength));
      }
      lcd.setCursor(0, CursorPos);
      lcd.print(">");
      if (ShowScrollBar) {
        if (Offset > 0) {
          lcd.setCursor(cols - 1, 0);
          lcd.write(0);
        }
        if (Offset + ItemsOnPage < l) {
          lcd.setCursor(cols - 1, ItemsOnPage - 1);
          lcd.write(1);
        }
      }
    }
    EncoderState = GetEncoderState();
    switch (EncoderState) {
      case eLeft: {
          // Прокрутка меню вверх
          LCDBacklight(1);
          ScrollTime = millis() + ScrollDelay * 5;
          if (CursorPos > 0) {  // Если есть возможность, поднимаем курсор
            if ((ScrollLongCaptions) and (ScrollPos)) {
              // Если предыдущий пункт меню прокручивался, то выводим его заново
              lcd.setCursor(1, CursorPos);
              lcd.print(Blank);
              lcd.setCursor(1, CursorPos);
              lcd.print(String(SubMenu[Offset + CursorPos]->Caption).substring(0, CaptionMaxLength));
              ScrollPos = 0;
            }
            // Стираем курсор на старом месте, рисуем в новом
            lcd.setCursor(0, CursorPos--);
            lcd.print(" ");
            lcd.setCursor(0, CursorPos);
            lcd.print(">");
          }
          else if (Offset > 0) {
            //Курсор уже в крайнем положении. Если есть пункты выше, то перерисовываем меню
            Offset--;
            NeedRepaint = 1;
          }
          break;
        }
      case eRight: {
          // Прокрутка меню вниз
          LCDBacklight(1);
          ScrollTime = millis() + ScrollDelay * 5;
          if (CursorPos < min(l, ItemsOnPage) - 1) {// Если есть возможность, то опускаем курсор
            if ((ScrollLongCaptions) and (ScrollPos)) {
              // Если предыдущий пункт меню прокручивался, то выводим его заново
              lcd.setCursor(1, CursorPos);
              lcd.print(Blank);
              lcd.setCursor(1, CursorPos);
              lcd.print(String(SubMenu[Offset + CursorPos]->Caption).substring(0, CaptionMaxLength));
              ScrollPos = 0;
            }
            // Стираем курсор на старом месте, рисуем в новом
            lcd.setCursor(0, CursorPos++);
            lcd.print(" ");
            lcd.setCursor(0, CursorPos);
            lcd.print(">");
          }
          else {
            // Курсор уже в крайнем положении. Если есть пункты ниже, то перерисовываем меню
            if (Offset + CursorPos + 1 < l) {
              Offset++;
              NeedRepaint = 1;
            }
          }
          break;
        }
      case eButton: {
          // Выбран элемент меню. Нажатие кнопки Назад обрабатываем отдельно
          LCDBacklight(1);
          ScrollTime = millis() + ScrollDelay * 5;
          if (SubMenu[CursorPos + Offset]->Key == mkBack) {
            free(SubMenu);
            return mkBack;
          }
          Result = DrawMenu(SubMenu[CursorPos + Offset]->Key);
          if ((Result != mkBack) and (ReturnFromMenu)) {
            free(SubMenu);
            return Result;
          }
          NeedRepaint = 1;
          break;
        }
      case eNone: {
          if (ScrollLongCaptions) {
            // При бездействии прокручиваем длинные названия
            S = SubMenu[CursorPos + Offset]->Caption;
            if (S.length() > CaptionMaxLength)
            {
              if (ScrollTime < millis())
              {
                ScrollPos++;
                if (ScrollPos == S.length() - CaptionMaxLength)
                  ScrollTime = millis() + ScrollDelay * 2; // Небольшая задержка когда вывели все название
                else if (ScrollPos > S.length() - CaptionMaxLength)
                {
                  ScrollPos = 0;
                  ScrollTime = millis() + ScrollDelay * 5; // Задержка перед началом прокрутки
                }
                else
                  ScrollTime = millis() + ScrollDelay;
                lcd.setCursor(1, CursorPos);
                lcd.print(Blank);
                lcd.setCursor(1, CursorPos);
                lcd.print(S.substring(ScrollPos, ScrollPos + CaptionMaxLength));
              }
            }
          }
          LCDBacklight();
        }
    }
  } while (1);
}
//****************************************

void setup() {
  pinMode(pin_CLK, INPUT);
  pinMode(pin_DT,  INPUT);
  pinMode(pin_Btn, INPUT_PULLUP);
  SPI.begin();
  lcd.begin();
  lcd.backlight();
  CaptionMaxLength = cols - 1;
  Blank = (char*) malloc(cols * sizeof(char));
  for (byte i = 0; i < CaptionMaxLength; i++)
    Blank[i] = ' ';
  if (ShowScrollBar) {
    CaptionMaxLength--;
    lcd.createChar(0, ScrollUp);
    lcd.createChar(1, ScrollDown);
  }
  Blank[CaptionMaxLength] = 0;
  FreqStep = 1000; // Установим шаг
  WaveForm = wfSin;
  WriteAD9833(bCntrl_reg | bReset | bB28);
  SetFrequency(300000); // Установим частоту 300000Гц
  SetPhase(0); // Сдвиг по фазе 0
  WriteAD9833(bCntrl_reg | bB28); // Снимаем Reset
  LCDRepaint(); // Выведем текущие параметры на дисплей
  LCDBacklight(1); // Включаем подвсветку
}

void loop() {
  unsigned long F;
  // В цикле опрашиваем энкодер
  switch (GetEncoderState()) {
    case eNone: { // При бездействии отключаем подсветку по таймауту
        LCDBacklight();
        return;
      }
    case eLeft: { // Уменьшить частоту
        LCDBacklight(1); // Включаем подсветку
        if (Freq == 1) return; // Меньше уже некуда
        if (Freq > FreqStep)
          SetFrequency(Freq - FreqStep);
        else
          SetFrequency(1);
        break;
      }
    case eRight: { // Увеличить частоту
        LCDBacklight(1); // Включаем подсветку
        if (Freq == 12500000) return; // Больше уже некуда
        if (Freq + FreqStep <= 12500000)
          SetFrequency(Freq + FreqStep);
        else
          SetFrequency(12500000);
        break;
      }
    case eButton: { // При нажатии на кнопку показываем меню
        LCDBacklight(1); // Включаем подсветку
        switch (DrawMenu(mkRoot)) { // Показываем меню и анализируем выбранный пункт
          case mkSetFreq: { // Установить новое значение частоты
              F = InputFreq(); // Запрашиваем новое значение
              while ((F > 12500000) or (F < 1)) {
                // Частота должна быть в диапазоне 1...12500000Гц
                lcd.clear();
                lcd.print("Frequency should be");
                lcd.setCursor(0, 1);
                lcd.print("between 1Hz and");
                lcd.setCursor(0, 2);
                lcd.print("12.5Mhz");
                while (GetEncoderState() == eNone);
                F = InputFreq(); // Предлагаем ввести частоту повторно
              }
              if (F != Freq)
                SetFrequency(F); // Устанавливаем новое значение частоты
              break;
            }
          case mkSetPhase:   { // Установить фазу
              SetPhase(InputPhase());
              break;
            }
          case mkSin:        { // Изменить форму сигнала на синусоидальную
              SetForm(wfSin);
              break;
            }
          case mkTri:        { // ... треугольную
              SetForm(wfTri);
              break;
            }
          case mkSquare:     { // ... прямоугольную
              SetForm(wfSqr);
              break;
            }
          case mkSquareDiv2: { // ... прямоугольную с делителем на 2
              SetForm(wfSqr2);
              break;
            }
          case mkInc1:    {    // Установить приращение частоты 1Гц
              FreqStep = 1;
              break;
            }
          case mkInc10:   {
              FreqStep = 10;  // 10Гц
              break;
            }
          case mkInc100:  {
              FreqStep = 100; // 100Гц
              break;
            }
          case mkInc1000: {
              FreqStep = 1000;// 1000Гц
              break;
            }
          case mkAbout: {
              lcd.clear();
              lcd.print("AD9833 generator");
              lcd.setCursor(0, 1);
              lcd.print("tsibrov.blogspot.com");
              while (GetEncoderState() == eNone){
                LCDBacklight();
              }
              LCDBacklight(1);
              break;
            }
        }
        // После выхода из меню перерисовываем главный экран
        LCDRepaint();
        return;
      }
  }
  // Обновить значение частоты
  lcd.setCursor(0, 0);
  lcd.print(Blank);
  lcd.setCursor(0, 0);
  lcd.print("Freq:  ");
  lcd.print(Freq);
  lcd.print("Hz");
}

// ******************** Вывод информации на дисплей ********************
void LCDRepaint() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Freq:  ");
  lcd.print(Freq);
  lcd.print("Hz");
  lcd.setCursor(0, 1);
  lcd.print("Phase: ");
  lcd.print(Phase);
  lcd.print("Deg");
  lcd.setCursor(0, 2);
  lcd.print("Form:  ");
  switch (WaveForm) {
    case wfSin: {
        lcd.print("Sinusoidal");
        break;
      }
    case wfTri: {
        lcd.print("Triangular");
        break;
      }
    case wfSqr: {
        lcd.print("Square");
        break;
      }
    case wfSqr2: {
        lcd.print("Square F/2");
        break;
      }
  }
}

// ******************** Энкодер с кнопкой ********************
eEncoderState GetEncoderState() {
  // Считываем состояние энкодера
  eEncoderState Result = eNone;
  CurrentTime = millis();
  if (CurrentTime >= (PrevEncoderTime + 5)) {
    PrevEncoderTime = CurrentTime;
    if (digitalRead(pin_Btn) == LOW ) {
      if (ButtonPrev) {
        Result = eButton; // Нажата кнопка
        ButtonPrev = 0;
      }
    }
    else {
      ButtonPrev = 1;
      EncoderA = digitalRead(pin_DT);
      EncoderB = digitalRead(pin_CLK);
      if ((!EncoderA) && (EncoderAPrev)) { // Сигнал A изменился с 1 на 0
        if (EncoderB) Result = eRight;     // B=1 => энкодер вращается по часовой
        else          Result = eLeft;      // B=0 => энкодер вращается против часовой
      }
      EncoderAPrev = EncoderA; // запомним текущее состояние
    }
  }
  return Result;
}

// ******************** Ввод нового значения частоты ********************
unsigned long InputFreq() {
  unsigned long F = Freq;
  int Positions[] = {4, 5, 7, 8, 9, 11, 12, 13};
  int Digits[8];
  int p = 0;
  lcd.clear();
  lcd.setCursor(2, 0);
  lcd.print("Input frequency:");
  lcd.setCursor(14, 1);
  lcd.print("Hz");
  // Разбиваем частоту на разряды и выводим на дисплей
  for (int i = 7; i >= 0; i--) {
    Digits[i] = F % 10;
    lcd.setCursor(Positions[i], 1);
    lcd.print(Digits[i]);
    F = F / 10;
  }
  lcd.setCursor(3, 3);
  lcd.print("OK      Cancel");
  lcd.setCursor(Positions[0], 1);
  lcd.cursor();

  //Основной цикл - выбор разряда для изменения либо OK/Cancel
  while (1)
  {
    EncoderState = GetEncoderState();
    switch (EncoderState) {
      case eNone: {
          LCDBacklight();
          continue;
        }
      case eLeft: { // Двигаем курсор влево
          LCDBacklight(1); // Включаем подсветку
          if (p == 0) continue; // Левее перемещаться некуда
          if (p == 9) { // Выбран Cancel, перемещаемся к OK
            lcd.setCursor(10, 3); lcd.print(' ');
            lcd.setCursor(2, 3);  lcd.print('>');
            p--;
            continue;
          }
          if (p == 8) { // Выбран OK, перемещаемся к частоте
            lcd.setCursor(2, 3); lcd.print(' ');
            p--;
            lcd.setCursor(Positions[p], 1);
            lcd.cursor();
            continue;
          }
          // Выбрана частота, перемещаемся к старшему разряду
          p--;
          lcd.setCursor(Positions[p], 1);
          continue;;
        }
      case eRight: { // Двигаем курсор вправо
          LCDBacklight(1); // Включаем подсветку
          if (p == 9) continue; // Правее перемещаться некуда
          if (p == 8) { // Выбран Ok, перемещаемся к Cancel
            lcd.setCursor(2, 3); lcd.print(' ');
            lcd.setCursor(10, 3); lcd.print('>');
            p++;
            continue;
          }
          if (p == 7) { // Выбран младший разряд частоты, перемещаемся к OK
            lcd.noCursor();
            lcd.setCursor(2, 3); lcd.print('>');
            p++;
            continue;
          }
          // Выбрана частота, перемещаемся к младшему разряду
          p++;
          lcd.setCursor(Positions[p], 1);
          continue;;
        }
      case eButton: { //Нажата кнопка
          LCDBacklight(1); // Включаем подсветку
          if (p == 9) {
            lcd.noCursor();
            return Freq; // Cancel.
          }
          if (p == 8) { // OK. Собираем и возвращаем новое значение частоты
            lcd.noCursor();
            F = 0;
            for (int i = 0; i < 8; i++)
              F = F * 10 + Digits[i];
            return F;
          }
          // Редактирование выбранного разряда частоты
          EncoderState = eNone;
          lcd.setCursor(Positions[p], 1);
          lcd.blink();
          while (EncoderState != eButton)
          {
            EncoderState = GetEncoderState();
            switch (EncoderState) {
              case eNone: {
                  LCDBacklight();
                  continue;
                }
              case eLeft: {
                  LCDBacklight(1); // Включаем подсветку
                  if (Digits[p] == 0) continue;
                  lcd.setCursor(Positions[p], 1);
                  lcd.print(--Digits[p]);
                  lcd.setCursor(Positions[p], 1);
                  continue;
                }
              case eRight: {
                  LCDBacklight(1); // Включаем подсветку
                  if (Digits[p] == 9) continue;
                  lcd.setCursor(Positions[p], 1);
                  lcd.print(++Digits[p]);
                  lcd.setCursor(Positions[p], 1);
                  continue;
                }
            }
          }
          LCDBacklight(1);
          lcd.noBlink();
          continue;
        }
    }
  }
}

// ******************** Ввод фазы ********************
int InputPhase() {
  int w = Phase;
  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print("Input phase shift:");
  lcd.setCursor(6, 1);
  lcd.print(w);
  lcd.print("Deg");
  while (1) {
    EncoderState = GetEncoderState();
    switch (EncoderState) {
      case eNone: {
          LCDBacklight();
          continue;
        }
      case eButton: {
          LCDBacklight(1);
          return w;
      }
      case eLeft: {
          LCDBacklight(1);
          if (w > 0) w--;
          break;
        }
      case eRight: {
          LCDBacklight(1);
          if (w < 360) w++;
          break;
        }
    }
    lcd.setCursor(6, 1);
    lcd.print(w);
    lcd.print("Deg  ");
  }
}

// ******************** Установить частоту ********************
void SetFrequency(unsigned long val) {
  Freq = val;
  unsigned long FreqData = round((float) val * 10.73741 + 0.5);
  WriteAD9833(FreqData & 0x3FFF | bFreq_reg0);
  WriteAD9833((FreqData >> 14) | bFreq_reg0);
}

// ******************** Установить фазу ********************
void SetPhase(int val) {
  Phase = val;
  unsigned long PhaseData = round (float(val) * 11.37777 + 0.5);
  WriteAD9833(PhaseData | bPhase_reg);
}

// ******************** Установить форму ********************
void SetForm(eWaveForm val) {
  WaveForm = val;
  int16_t CntrlData;
  switch (val) {
    case wfSin: {
        CntrlData = 0;
        break;
      }
    case wfTri: {
        CntrlData = bMode;
        break;
      }
    case wfSqr: {
        CntrlData = bOpbiten | bDiv2 | bSleep12;
        break;
      }
    case wfSqr2: {
        CntrlData = bOpbiten | bSleep12;
        break;
      }
  }
  WriteAD9833(CntrlData | bCntrl_reg | bB28);
}

// ******************** Передача 16-битного слова в AD9833 ********************
void WriteAD9833(uint16_t Data) {
  SPI.beginTransaction(SPISettings(SPI_CLOCK_DIV8, MSBFIRST, SPI_MODE2));
  digitalWrite(SS, LOW);
  delayMicroseconds(1);
  SPI.transfer16(Data);
  digitalWrite(SS, HIGH);
  SPI.endTransaction();
}

в 286 строке менятеся шаг по умолчанию FreqStep = 1000

в 289 строке меняется частота по умолчанию  SetFrequency (300000)

файлы KiCad https://yadi.sk/d/rj5g4pSRr1N7wg

АндрейS
Offline
Зарегистрирован: 13.04.2018

Библиотеки были в папке libraries, удалил от туда и закинул из папки со скетчем обратно в папку libraries . Экран заработал!

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

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

АндрейS
Offline
Зарегистрирован: 13.04.2018

ua6em пишет:

считаю, что ручной режим совершенно не нужен

Два скетча на одном железе не помешает)))

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

АндрейS пишет:

ua6em пишет:

считаю, что ручной режим совершенно не нужен

Два скетча на одном железе не помешает)))

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

АндрейS
Offline
Зарегистрирован: 13.04.2018

Ток не измеряется, сектч не рассчитан на работу с ina219

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

АндрейS пишет:

Ток не измеряется, сектч не рассчитан на работу с ina219

ты попробуй мой код, работает - нет?

АндрейS
Offline
Зарегистрирован: 13.04.2018

Работеат частично, на экран выводиться информация.  Стартовая частота 200000 кГц и  i=0ma. Как он должен начинать искать резонанс? У меня из-за колодок и массивного радиатора может контакт пропадать на ТДА.

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

АндрейS пишет:

Работеат частично, на экран выводиться информация.  Стартовая частота 200000 кГц и  i=0ma. Как он должен начинать искать резонанс? У меня из-за колодок и массивного радиатора может контакт пропадать на ТДА.

строки 103 до 111 размаркируй скомпилируй и залей, это поиск резонанса

АндрейS
Offline
Зарегистрирован: 13.04.2018

ua6em пишет:

да библиотека дисплея у него другая однако

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

АндрейS
Offline
Зарегистрирован: 13.04.2018

Строки изменил. Пишет частота 10,00Кгц  i=0ma. На дисплее больше ничего не меняется.

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

АндрейS пишет:

ua6em пишет:

да библиотека дисплея у него другая однако

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

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

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

АндрейS пишет:

Строки изменил. Пишет частота 10,00Кгц  i=0ma. На дисплее больше ничего не меняется.

перезалей крайнюю версию скетча из того поста, я его правил, были ошибки

АндрейS
Offline
Зарегистрирован: 13.04.2018

И у меня ina 219 подключена не через шунтирующий резистор а  вот так:

АндрейS
Offline
Зарегистрирован: 13.04.2018

Перезалил, ни чего не происходит. Только в начале, после подкючения индикатор поля моргает один раз и все. На том скетче тоже индикатор моргал. Осциллограф показывет частоту 93-35 Кгц и она скачет. И не известо, испавна ли ina219.

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

поменял скетч еще раз, напряжение на TDA должно подаваться через силовой резистор, на нём и измеряет, перезалей скетч, посмотрим

АндрейS
Offline
Зарегистрирован: 13.04.2018

Силовой резистор, это те выводы 7 и 8 что у меня перечеркнуты?

АндрейS
Offline
Зарегистрирован: 13.04.2018

Перезалил скетч, теперь пишет частота 0 ток 0. Надо подключить через выводы 7 и 8? Сейчас надо отлучиться, буду часа через 2.

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

АндрейS пишет:

Перезалил скетч, теперь пишет частота 0 ток 0. Надо подключить через выводы 7 и 8? Сейчас надо отлучиться, буду часа через 2.

библиотека INA не работает, буду разбираться, с этой библиотекой я не работал

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

скидал по быстрому другую версию с другими библиотеками датчика тока:
 

#include <Wire.h>
#include <SPI.h>
#include "LiquidCrystal_I2C.h"        // брал здесь - https://iarduino.ru/file/134.html
LiquidCrystal_I2C lcd(0x3F, 20, 4);   // Для экрана 20х4, I2C адрес дисплея уточнить  
//#include <Adafruit_INA219.h>
//Adafruit_INA219 ina219;

#include "ina219.h"
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
}

// Процедура грубой настройки частоты по максимальному току
 void setFreq(){
 for (int i=1; i <= 15; i++) {
   // Data_ina219=ina219.getCurrent_mA();
      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(2);
    } 
 }

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

//************************** SETUP *************************/
void setup() { 
  SPI.begin();
  Serial.begin(115200);
 // lcd.init(); //для библиотеки V112
  lcd.begin();
  lcd.backlight();
  delay(10);   
    
 // ina219.begin(0x40); //такая конфигурация конфликтует с дисплеем
 // ina219.begin();
 // ina219.setCalibration_16V_400mA(); 
 // ina219.setCalibration_32V_2A();  // Интересно, в библиотеку можно внести изменения
  delay(10);                       // сделав свои параметры калибровки? надо 16V 2A

  ina219.begin(0x44); // i2c address 64=0x40 68=0х44 исправлять и в ina219.h одновременно
  ina219.configure(0, 2, 12, 12, 7); // 16S -8.51ms
 // 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)

  ina219.calibrate(0.100, 0.32, 16, 3.2); 
                // R_шунта, напряж_шунта, макcнапряж, максток
 
  
  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.getCurrent_mA();
  Data_ina219=ina219.shuntCurrent() * 1000; 
    lcd.setCursor(2, 0);                  // 1 строка, начало
    lcd.print("Freq = ");
    float freq_tic = ifreq/1000;
    lcd.print(freq_tic,2);
    lcd.print("kHz");
    lcd.setCursor(2, 1);                  // 2 строка, начало
    lcd.print("I = ");
  //  lcd.setCursor(5, 1);                  // 2 строка 7 позиция
    lcd.print(Data_ina219);
    lcd.print("ma");
    lcd.setCursor(2, 3); 
    lcd.print("Generator AD9833");
    delay(1);

  }    // Конец процедуры инициализации прибора
  
 
// ТЕЛО ПРОГРАММЫ
 
void loop() {

 // Data_ina219=ina219.getCurrent_mA();
  Data_ina219=ina219.shuntCurrent() * 1000; 
 // lcd.setCursor(0, 0);                  // 1 строка
 // lcd.print("Freq = ");
 
   lcd.setCursor(9, 0);                   //1 строка 7 позиция
   float freq_tic = ifreq/1000;
   lcd.print(freq_tic,2);
   lcd.print("kHz");
   lcd.setCursor(2, 1);                  // 2 строка
   lcd.print("I = ");
  // lcd.setCursor(5, 1);                  // 2 строка 7 позиция
   lcd.print(Data_ina219);
   lcd.print("ma");
   lcd.setCursor(2, 3); 
   lcd.print("Generator AD9833");
   delay(200);
 } //END

И библиотеки, вложить в папку скетча, библиотека дисплея как в функциональном генераторе
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;
}

 

АндрейS
Offline
Зарегистрирован: 13.04.2018

Библиотеки в одной папке и скетч, все из последнего поста. Такие ошибки:

error: ina219.h: No such file or directory
compilation terminated.
exit status 1
ina219.h: No such file or directory

Что то нужно переименовать, не могу сообразить что и где(?  Метод научного тыка не помогает(

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

АндрейS пишет:

Библиотеки в одной папке и скетч, все из последнего поста. Такие ошибки:

error: ina219.h: No such file or directory
compilation terminated.
exit status 1
ina219.h: No such file or directory

Что то нужно переименовать, не могу сообразить что и где(?  Метод научного тыка не помогает(

перезагрузить IDE должны появиться закладки с этими файлами

АндрейS
Offline
Зарегистрирован: 13.04.2018

закладки есть, перезагружал и не один раз IDE 1.8.9. переименовывал, INA219.h  маленькими буквами, ошибка вылазиет на вкладке INA219.cpp та же, что нет ее

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

АндрейS пишет:

закладки есть, перезагружал и не один раз IDE 1.8.9. переименовывал, INA219.h  маленькими буквами, ошибка вылазиет на вкладке INA219.cpp та же, что нет ее

до точки большими буквами, переименуй

АндрейS
Offline
Зарегистрирован: 13.04.2018

Все большими. Ошибка появляется в 8 строке скетча:

8:20: error: ina219.h: No such file or directory
compilation terminated.
exit status 1
ina219.h: No such file or directory
 

если переименовать маленькими то таже ошибка  на вкладеке ina219.cpp в 37 строке

ina219.cpp:37:20: error: INA219.h: No such file or directory
compilation terminated.
exit status 1
INA219.h: No such file or directory
 

Надо что-то в теле библиотек переименовывать?

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

АндрейS пишет:

Все большими. Ошибка появляется в 8 строке скетча:

8:20: error: ina219.h: No such file or directory
compilation terminated.
exit status 1
ina219.h: No such file or directory
 

если переименовать маленькими то таже ошибка  на вкладеке ina219.cpp в 37 строке

ina219.cpp:37:20: error: INA219.h: No such file or directory
compilation terminated.
exit status 1
INA219.h: No such file or directory
 

Надо что-то в теле библиотек переименовывать?

Скрин экрана программы IDE покажи

АндрейS
Offline
Зарегистрирован: 13.04.2018

Разобрался, нужно было в ina219.сpp в 37 строке тоже переименовать #include "ina219.h"
теперь все маленькими и компилируется

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

АндрейS пишет:

Разобрался, нужно было в ina219.сpp в 37 строке тоже переименовать #include "ina219.h"
теперь все маленькими и компилируется

ну и что там с током?

PS лезть в библиотеки и переименовывать, чтобы привести имена библиотек в надлежащий вид не правильное решение. В посте 325 у меня прямо написано, как назвать файлы )))

PPS Модуль INA219 у меня был сконфигурирован на 0х44 адрес, на этом адресе конфликтов не было, у тебя на каком адресе он висит?

АндрейS
Offline
Зарегистрирован: 13.04.2018

новая проблема нарисовалась, IDE похоже не видит плату:

avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x66
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x72
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x65
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x71
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x3d
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x33
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x35
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x30
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x30
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x30
Произошла ошибка при загрузке скетча

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

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

АндрейS
Offline
Зарегистрирован: 13.04.2018

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

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

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

АндрейS пишет:

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

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

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

АндрейS пишет:

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

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

То-есть работать в линуксе ты можешь, а с написанием файлов (а линуксе в отличии от винды всё должно быть абсолютно точно) ты импровизируешь ))) Зачёт!!!

АндрейS
Offline
Зарегистрирован: 13.04.2018

Загрузчик програмный или апартный? Такие ошибки были раньше на ней, помогало переподключение.

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

АндрейS пишет:

Загрузчик програмный или апартный? Такие ошибки были раньше на ней, помогало переподключение.

ну так попробуй, сейчас Линукс с портами работает намного лучше, чем 20 лет назад )))

АндрейS
Offline
Зарегистрирован: 13.04.2018

ua6em пишет:

а линуксе в отличии от винды всё должно быть абсолютно точно) ты импровизируешь ))) Зачёт!!!

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

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

АндрейS пишет:

ua6em пишет:

а линуксе в отличии от винды всё должно быть абсолютно точно) ты импровизируешь ))) Зачёт!!!

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

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

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

АндрейS пишет:

ua6em пишет:

а линуксе в отличии от винды всё должно быть абсолютно точно) ты импровизируешь ))) Зачёт!!!

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

Модули надо на панели ставить, вполне надёжно, и паять потом ничего не понадобится, передёрнул и всех делов

АндрейS
Offline
Зарегистрирован: 13.04.2018

Загрузил, включил, не работает. Пишет частота 0 ток 0. У меня ина219 не через резистор подключена, она будет работать?
Есть  старенький ноут у меня с виндовс хр, на нем сейчас загрузил скетч в плату в которой на линуксе не грузилось.  Линукс шатлвротский))) Хочу на LMDE 3 дебиановский перейти.

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

адрес INA фактически какой?

АндрейS
Offline
Зарегистрирован: 13.04.2018

С адресом ИНА не разбирался, его также как и дисплея с I2C скетчем искать?

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

АндрейS пишет:

С адресом ИНА не разбирался, его также как и дисплея с I2C скетчем искать?

да

АндрейS
Offline
Зарегистрирован: 13.04.2018

0x40

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

АндрейS пишет:

0x40

ну так и поставь его в скетче

АндрейS
Offline
Зарегистрирован: 13.04.2018

Иземнил. Не работает.  Но вот если вытащить ТДА то ток 65488 -65514 ма паказывает частота 0