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

Сами делали прибор, или брали в аренду, или покупали (можете ссылочку на продавца)

прибор,начало этой темы от ua6em

немного модернизирован для точности измерения резонансной частоты.

можно купить в Юконд

если срочно, проще и дешевле купить, какой даже не посоветую, Лайв Синус по току слабоват был (5 версия) другие не смотрел
Лечить без диагностики тоже так себе идея

Да, фирма серьёзная)))

Как работать с KY-040?

#define ENCODER_CLK 2
#define ENCODER_DT A1
#define ENCODER_SW 4

Пин A1 назначен (#define ENCODER_DT A1) для DT что бы посмотреть, напряжение.

Serial.print(digitalRead(ENCODER_CLK));
Serial.print(":");
Serial.print(analogRead(ENCODER_DT));
Serial.print(":");
Serial.println(digitalRead(ENCODER_DT));

Кучу керамическим пинцетом, всё нормально:

В одну сторону:

1:1023:1
1:1023:1
1:1023:1
1:1023:1

В другую:

1:0:0
1:0:0
1:0:0
1:0:0
1:0:0

Кручу руками:

В одну сторону:

1:1023:1
1:1020:1
1:1022:1
1:1023:1
1:1023:1

В другую:

1:1023:1
1:1023:1
1:1023:1
1:1021:1
1:1023:1

Собрано по данной схеме: Ad_9833 - Platform for creating and sharing projects - OSHWLab

Пробовал на двух, оба ведут себя аналогично.

это нормально для энкодера , работать будет, а вот схема у тебя полная хрень, U4 отзеркаль по вертикали

По установке частоты на AD9833, а именно десятых долей герца, это в принципе возможно:

#ifndef AD9833_DRIVER_H
#define AD9833_DRIVER_H

#include <Arduino.h>
#include "s_spi.h"

// AD9833 регистры и команды
#define AD9833_REG_FREQ0    0x4000
#define AD9833_REG_FREQ1    0x8000
#define AD9833_REG_PHASE0   0xC000
#define AD9833_CMD_RESET    0x0100
#define AD9833_CMD_SINE     0x2000
#define AD9833_CMD_TRIANGLE 0x2002
#define AD9833_CMD_SQUARE   0x2028

#define AD9833_REF_FREQ     25000000.0f  // Используем float

class AD9833 {
private:
    spi_device_config_t spi_config;
    int cs_pin;
    float current_freq;        // Частота в Гц (float)
    float reference_clock;     // Опорная частота (float)
    
    void writeRegister(uint16_t value) {
        uint8_t data[2];
        data[0] = (value >> 8) & 0xFF;
        data[1] = value & 0xFF;
        spi_write_bytes(&spi_config, data, 2);
    }
    
    // Расчет 28-битного значения (float версия)
    uint32_t calculateFreqWord(float freq_hz) {
        const float TWO_POW_28 = 268435456.0f;
        float freq_word_float = (freq_hz * TWO_POW_28) / reference_clock;
        return (uint32_t)(freq_word_float + 0.5f);  // Округление
    }
    
    void setFreqWord(uint32_t freq_word) {
        uint16_t freq_lsb = freq_word & 0x3FFF;
        uint16_t freq_msb = (freq_word >> 14) & 0x3FFF;
        writeRegister(AD9833_REG_FREQ0 | freq_lsb);
        writeRegister(AD9833_REG_FREQ0 | (freq_msb << 2));
    }
    
public:
    // Конструктор с float параметром
    AD9833(int cs, float ref_clock = AD9833_REF_FREQ) {
        cs_pin = cs;
        current_freq = 1000.0f;
        reference_clock = ref_clock;
        spi_config = spi_create_device(cs_pin, 25000000, SPI_MODE_2, SPI_MSBFIRST);
    }
    
    void begin() {
        writeRegister(AD9833_CMD_RESET);
        delay(10);
        writeRegister(AD9833_CMD_SINE);
        delay(1);
    }
    
    // Основная функция установки частоты (принимает float)
    bool setFrequency(float freq_hz) {
        float max_freq = reference_clock / 2.0f;
        
        if (freq_hz < 0.1f || freq_hz > max_freq) {
            Serial.printf("[AD9833] Error: Frequency %.2f Hz out of range (0.1 - %.1f Hz)\n", 
                         freq_hz, max_freq);
            return false;
        }
        
        current_freq = freq_hz;
        uint32_t freq_word = calculateFreqWord(freq_hz);
        setFreqWord(freq_word);
        
        // Вычисляем реальную частоту для отладки
        float actual_freq = (freq_word * reference_clock) / 268435456.0f;
        
        Serial.printf("[AD9833] Set: %.4f Hz, Actual: %.4f Hz, Error: %.6f Hz\n", 
                     freq_hz, actual_freq, actual_freq - freq_hz);
        
        return true;
    }
    
    // Перегрузка для double (автоматически конвертирует в float)
    bool setFrequency(double freq_hz) {
        return setFrequency((float)freq_hz);
    }
    
    // Перегрузка для int
    bool setFrequency(uint32_t freq_hz) {
        return setFrequency((float)freq_hz);
    }
    
    float getFrequency() {
        return current_freq;
    }
    
    float getActualFrequency() {
        uint32_t freq_word = calculateFreqWord(current_freq);
        return (freq_word * reference_clock) / 268435456.0f;
    }
    
    void setWaveformSine() {
        writeRegister(AD9833_CMD_SINE);
    }
    
    void setWaveformTriangle() {
        writeRegister(AD9833_CMD_TRIANGLE);
    }
    
    void setWaveformSquare() {
        writeRegister(AD9833_CMD_SQUARE);
    }
    
    void reset() {
        writeRegister(AD9833_CMD_RESET);
        delay(10);
        setWaveformSine();
        setFrequency(current_freq);
    }
};

#endif // AD9833_DRIVER_H

И скетч примера

#include <Arduino.h>
#include "s_sdcard.h"
#include "ad9833_driver.h"

#define AD9833_CS_PIN   9

AD9833 ad9833(AD9833_CS_PIN);

// Функции для работы с float
float noteToFrequency(int note, int octave) {
    // Преобразует ноту в частоту (A4 = 440 Гц)
    // note: 0=C, 1=C#, 2=D, 3=D#, 4=E, 5=F, 6=F#, 7=G, 8=G#, 9=A, 10=A#, 11=B
    float frequencies[] = {
        16.35f, 17.32f, 18.35f, 19.45f, 20.60f, 21.83f, 23.12f, 24.50f, 25.96f, 27.50f, 29.14f, 30.87f
    };
    
    float freq = frequencies[note % 12];
    for (int i = 0; i < octave; i++) {
        freq *= 2.0f;
    }
    return freq;
}

float linearInterpolation(float t, float start_freq, float end_freq) {
    // Линейная интерполяция между частотами
    return start_freq + (end_freq - start_freq) * t;
}

void setup() {
    Serial.begin(115200);
    delay(1000);
    
    Serial.println("\n=================================");
    Serial.println("AD9833 Float Frequency Demo");
    Serial.println("=================================");
    
    // Инициализация
    if (!spi_init()) {
        Serial.println("✗ SPI init failed!");
        return;
    }
    
    ad9833.begin();
    ad9833.setWaveformSine();
    
    // Демонстрация разных способов установки частоты
    Serial.println("\n=== Float Frequency Examples ===");
    
    // 1. Прямая передача float
    float freq1 = 1234.567f;
    ad9833.setFrequency(freq1);
    delay(500);
    
    // 2. Результат вычисления
    float freq2 = 1000.0f + (millis() % 1000) / 1000.0f;
    ad9833.setFrequency(freq2);
    delay(500);
    
    // 3. Из переменной
    float userFreq = 440.0f;
    ad9833.setFrequency(userFreq);
    delay(500);
    
    // 4. Нота "A" 4-й октавы
    float noteFreq = noteToFrequency(9, 4);  // A4 = 440 Hz
    ad9833.setFrequency(noteFreq);
    Serial.printf("Note A4 frequency: %.2f Hz\n", noteFreq);
    delay(1000);
    
    if (sd_init()) {
        Serial.println("✓ SD Card initialized");
    }
    
    Serial.println("\nCommands:");
    Serial.println("  freq <float>  - Set frequency (e.g., 'freq 1234.567')");
    Serial.println("  sweep         - Start frequency sweep");
    Serial.println("  notes         - Play musical notes");
    Serial.println("  mod           - Frequency modulation demo");
    Serial.println("=================================\n");
}

void frequencySweep() {
    Serial.println("\n=== Frequency Sweep 100-2000 Hz ===");
    for (float f = 100.0f; f <= 2000.0f; f += 10.0f) {
        ad9833.setFrequency(f);
        Serial.printf("Sweep: %.1f Hz\r", f);
        delay(20);
    }
    Serial.println("\nSweep completed");
}

void playNotes() {
    Serial.println("\n=== Playing Musical Notes ===");
    
    // Мажорная гамма (A4 = 440 Hz)
    float notes[] = {
        440.00f,  // A4
        493.88f,  // B4
        523.25f,  // C5
        587.33f,  // D5
        659.25f,  // E5
        698.46f,  // F5
        783.99f,  // G5
        880.00f   // A5
    };
    
    const char* noteNames[] = {"A4", "B4", "C5", "D5", "E5", "F5", "G5", "A5"};
    
    for (int i = 0; i < 8; i++) {
        ad9833.setFrequency(notes[i]);
        Serial.printf("Playing: %s (%.2f Hz)\n", noteNames[i], notes[i]);
        delay(500);
    }
}

void frequencyModulation() {
    Serial.println("\n=== Frequency Modulation Demo ===");
    
    float base_freq = 1000.0f;
    float mod_depth = 500.0f;
    
    for (int i = 0; i < 100; i++) {
        float t = i / 100.0f;  // 0 to 1
        float mod = sin(t * 2 * PI) * mod_depth;
        float freq = base_freq + mod;
        
        ad9833.setFrequency(freq);
        Serial.printf("Modulation: %.1f Hz\r", freq);
        delay(20);
    }
    Serial.println("\nModulation completed");
}

void processCommands() {
    if (!Serial.available()) return;
    
    String cmd = Serial.readStringUntil('\n');
    cmd.trim();
    
    if (cmd.startsWith("freq ")) {
        // Парсим float из строки
        float frequency = cmd.substring(5).toFloat();
        if (frequency > 0.1f && frequency < 12500000.0f) {
            ad9833.setFrequency(frequency);
            Serial.printf("Frequency set to %.4f Hz\n", frequency);
        } else {
            Serial.println("Invalid frequency (0.1 - 12500000 Hz)");
        }
    }
    else if (cmd == "sweep") {
        frequencySweep();
    }
    else if (cmd == "notes") {
        playNotes();
    }
    else if (cmd == "mod") {
        frequencyModulation();
    }
    else if (cmd == "help") {
        Serial.println("Commands: freq, sweep, notes, mod, help");
    }
}

void loop() {
    static uint32_t last_log = 0;
    
    processCommands();
    
    // Логирование каждые 10 секунд
    if (sd_is_mounted() && millis() - last_log > 10000) {
        last_log = millis();
        
        float current = ad9833.getFrequency();
        float actual = ad9833.getActualFrequency();
        
        char log_data[128];
        sprintf(log_data, "[%lu] Set: %.4f Hz, Actual: %.4f Hz, Error: %.4f Hz\n",
                millis(), current, actual, actual - current);
        
        sd_append_file("/float_freq_log.txt", log_data);
    }
    
    delay(10);
}

Спасибо, попробую.

U4 я не поставил, оставил один U5, решил переключать режимы буду нажатиями, одно нажатие на энкодер, двойное нажатие и т. д.

ты всё таки его переверни, а то не в те пины питание подаёшь

Спасибо, я знаю, это из Вашего первого поста.

Господа, посоветуйте хороший энкодер с кнопкой (желательно с ссылкой на товар), что бы был выполнен из качественных материалов, что бы вал не гулял, как сосиска в коридоре, крутилка была приятной, с минимальным дребезгом, цена/качество? Раньше не имел с ними дела, купил четыре разных и беда просто, от гуляния вала, до невероятного дребезга при кручении.

Мышь от компа.

Не по мне потрошить работающие вещи.

Не получается заставить работать микросхему TDA7056, купил её в чип дипе.

Подключил её следующим образом (GND общий со схемой):

2 +5V
3 IN+
4 GND
6 OUT+
7 GND
8 OUT−

Отдельное питание от аккумулятора 7V, подавал на TDA7056 разную частоту от 100 Гц до 7кГц, ставил разные конденсаторы между AD9833 пином OUT и пином IN+ TDA7056, даже соединял эти пины напрямую, один фиг, на выходе нет сигнала.

Попробовал для вас проверить. Всё работает без проблем. Катушка проверочная со светодиодами на расстоянии 20 см светятся на частоте 300 кГц.

+5 вольт мало, надо хотя бы +9

В даташите от 4.5В должна работать, да и я 7 вольт подавал.

Думаю у меня сама TDA7056 неисправная

ищи с буквой B

в самом начале темы писал,покупал несколько штук,в разных местах,с разными буквами,так и не повезло что бы заработала хорошо.

хотя удовольствие это было не из дешёвых,щас не знаю сколько микра стоит.