Если кому-то надо срочно проверить эти устройства ниже приведён код, проверен на ESP32S3, собран из примеров, все претензии к авторам
// Использование пинов
// 18 - выходит сигнал для модулятора, 1 килогерц, амплитуда 3 вольта
// 1,3, 4 на модуль I2C NavKey
// 9, 10, 11, 13 на модуль AD9850
// кнопка влево переключает на регулирование энкодером частоты модуляции
// кнопка вправо переключает энкодер для регулирования несущей частоты кратно 1 килогерцу
#include <Wire.h>
#include <i2cNavKey.h>
#include <Ticker.h>
#include "AD985X.h"
#ifndef ESP32
#error ESP32 only example, please select appropriate board
#endif
uint8_t AD_RST = 9;
uint8_t AD_FQUDP = 10;
uint8_t AD_DATA = 11;
uint8_t AD_CLK = 13;
AD9850 freqGen(AD_RST, AD_FQUDP, AD_DATA, AD_CLK);
uint32_t rife_freq = 1100000;
uint32_t rife_prev = 0;
uint32_t rife_maxFreq;
Ticker tNavkey; // Таймер для обработки NavKey
// Генерируем ШИМ для модулятора
// Конфигурация ШИМ
const int pwmPin = 18; // GPIO для выхода ШИМ
volatile int freq = 1000; // Частота 1 кГц
const int ledChannel = 0; // Канал LEDC (0-7 для S3)
const int resolution = 10; // Разрешение 10 бит (значения 0-1023)
volatile int fcounter;
volatile int fcounter_old;
volatile bool fflag = true; // флаг, какую частоту меняем? true - модуляция, false - несущая
// Настройки пинов для ESP32-S3
const int SDA_PIN = 1;
const int SCL_PIN = 3;
const int INT_PIN = 4;
void help() {
Serial.println();
Serial.println("+ : f = f + 1");
Serial.println("- : f = f - 1");
Serial.println("* : f = f * 10");
Serial.println("/ : f = f / 10");
Serial.println("? : help");
Serial.println("R : AD9850 reset");
Serial.println("P : AD9850 power down");
Serial.println("U : AD9850 power up");
Serial.println();
}
// Инициализация объекта. Адрес 0x10 соответствует вашему 0b0010000
i2cNavKey navkey(0x10);
volatile bool eventFlag = false;
// Функция прерывания (обработчик) NavKey
void IRAM_ATTR navkeyISR() {
eventFlag = true;
}
// Функция опроса срабатывания энкодера
// Если сработало прерывание (нажат пин 4)
void tnav() {
if (eventFlag) {
eventFlag = false;
navkey.updateStatus(); // Эта функция вызовет нужный callback автоматически
}
}
// --- Функции обратного вызова (Callbacks) ---
void UP_Button_Pressed(i2cNavKey* p) {
Serial.println("ВВЕРХ нажата");
}
void DOWN_Button_Pressed(i2cNavKey* p) {
Serial.println("ВНИЗ нажата");
}
void LEFT_Button_Pressed(i2cNavKey* p) {
Serial.println("ВЛЕВО нажата");
fflag = true;
}
void RIGHT_Button_Pressed(i2cNavKey* p) {
Serial.println("ВПРАВО нажата");
fflag = false;
}
void CENTRAL_Button_Pressed(i2cNavKey* p) {
Serial.println("ЦЕНТР нажата");
}
void CENTRAL_Button_Double(i2cNavKey* p) {
Serial.println("Двойное нажатие ЦЕНТР!");
}
void Encoder_Rotate(i2cNavKey* p) {
Serial.printf("Значение энкодера: %d\n", p->readCounterInt());
// Меняем частоту если значение изменилось, кратно 10 герц
if (fflag) {
fcounter = p->readCounterInt();
if (fcounter > fcounter_old) {
freq += 10;
fcounter_old = fcounter;
ledcChangeFrequency(pwmPin, freq, resolution);
}
if (fcounter < fcounter_old) {
freq -= 10;
fcounter_old = fcounter;
ledcChangeFrequency(pwmPin, freq, resolution);
}
} else {
fcounter = p->readCounterInt();
if (fcounter > fcounter_old) {
rife_freq += 1000;
rife_prev = rife_freq;
fcounter_old = fcounter;
freqGen.setFrequency(rife_freq);
Serial.println(rife_freq);
}
if (fcounter < fcounter_old) {
rife_freq -= 1000;
rife_prev = rife_freq;
fcounter_old = fcounter;
freqGen.setFrequency(rife_freq);
Serial.println(rife_freq);
}
}
}
void setup(void) {
Serial.begin(115200);
// Инициализация I2C на пинах 1 и 3 для ESP32-S3
Wire.begin(SDA_PIN, SCL_PIN);
// Настройка прерывания на ESP32
pinMode(INT_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(INT_PIN), navkeyISR, FALLING);
Serial.println("**** I2C navkey V2 ESP32-S3 Ready ****");
navkey.reset();
// Конфигурация NavKey
navkey.begin(i2cNavKey::INT_DATA | i2cNavKey::WRAP_ENABLE | i2cNavKey::DIRE_RIGHT | i2cNavKey::IPUP_ENABLE);
navkey.writeCounter((int32_t)0);
navkey.writeMax((int32_t)256);
navkey.writeMin((int32_t)-256);
navkey.writeStep((int32_t)1);
navkey.writeDoublePushPeriod(50); // 300ms
// Привязка событий
navkey.onUpPush = UP_Button_Pressed;
navkey.onDownPush = DOWN_Button_Pressed;
navkey.onRightPush = RIGHT_Button_Pressed;
navkey.onLeftPush = LEFT_Button_Pressed;
navkey.onCentralPush = CENTRAL_Button_Pressed;
navkey.onCentralDoublePush = CENTRAL_Button_Double;
navkey.onChange = Encoder_Rotate;
// Активация прерываний в самом устройстве
navkey.autoconfigInterrupt();
Serial.print("ID CODE: 0x");
Serial.println(navkey.readIDCode(), HEX);
// Включим опрашивание энкодра каждые 5 миллисекунд
tNavkey.attach(0.005, tnav);
// Для ядра менее 3.0
// Настройка таймера LEDC
// ledcSetup(ledChannel, freq, resolution);
// Привязка канала к GPIO
// ledcAttachPin(pwmPin, ledChannel);
ledcAttach(pwmPin, freq, resolution);
// Вывод сигнала ШИМ
ledcWrite(pwmPin, 512); // PWM 50%
Serial.println("PWM on pin18 is ON");
Serial.println();
Serial.println(__FILE__);
Serial.print("AD985X_LIB_VERSION: \t");
Serial.println(AD985X_LIB_VERSION);
Serial.println();
freqGen.begin();
freqGen.powerUp();
rife_maxFreq = freqGen.getMaxFrequency();
Serial.println(rife_maxFreq);
help();
}
void loop() {
if (Serial.available() > 0) {
int c = Serial.read();
switch (c) {
case '?':
help();
break;
case 'R':
freqGen.reset();
rife_freq = freqGen.getFrequency();
break;
case 'P':
freqGen.powerDown();
break;
case 'U':
freqGen.powerUp();
break;
case '+':
rife_freq += 1;
break;
case '-':
rife_freq -= 1;
break;
case '*':
rife_freq *= 10;
break;
case '/':
rife_freq /= 10;
break;
}
if (rife_freq > rife_maxFreq) rife_freq = rife_maxFreq;
}
// UPDATE AD985X IF NEW VALUE
if (rife_prev != rife_freq) {
rife_prev = rife_freq;
freqGen.setFrequency(rife_freq);
Serial.println(rife_freq);
}
}


