Announcement

Collapse
No announcement yet.

Announcement

Collapse
No announcement yet.

STM to ESP

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • #31
    Post #22 gives me the 4 channels as I need, now I need to regulate amplitude sine channel, whatever I do the amplitude is not changing.
    This part of code
    HTML Code:
    void generateWaveforms() {
      for (int i = 0; i < WAVEFORM_SAMPLES; i++) {
        // wave_data1[i] = (uint8_t)((255 * i) / WAVEFORM_SAMPLES);
        wave_data1[i] = (uint8_t)( (50 + cos(2 * 3.14159 * i / WAVEFORM_SAMPLES)));
        wave_data2[i] = (uint8_t)(127.5 * (1 + sin(2 * 3.14159 * i / WAVEFORM_SAMPLES)));
        // int dutyCycle = (int)(amp + amp * sin(stp * i)); // Calculate the duty cycle
    
      }
      for (int i = 0; i < WAVEFORM_SAMPLES; i++) {
        stereo_buffer[i * 2] = wave_data1[i];      // DAC1
        stereo_buffer[i * 2 + 1] = wave_data2[i];  // DAC2
      }
    }
    ​

    Comment


    • #32
      So far I have 2 squares for synchronous detectors (0 deg and 90 deg), 1 one sin for coil balance and one sin for ground balance.
      Sin waves need to be regulated in amplitude and phase = working on it.

      HTML Code:
      void generateWaveforms() {
        //for (int i = 0; i < WAVEFORM_SAMPLES; i++)
        for (int i = 0; i < WAVEFORM_SAMPLES; i++)
        {
          wave_data1[i] = (uint8_t)(128 * (1 + sin(stp * i)));  //127.5; // Half of the max value (255/2)  //\+++++++++++++++++++++++++
          //wave_data2[i] = (uint8_t)(100 * (1 + sin(stp * i)));
            wave_data2[i] = (uint8_t)(100 * (1 + cos(stp * i)));                                                                   //  +++++++++++++++++++++++  
          // int dutyCycle = (int)(amp + amp * sin(stp * i)); //
        }
      
        for (int i = 0; i < WAVEFORM_SAMPLES; i++) {
          stereo_buffer[i * 2] = wave_data1[i];      // DAC1
          stereo_buffer[i * 2 + 1] = wave_data2[i];  // DAC2
        }
      }
      ​

      Comment


      • #33
        Those two line should produce 2 sin waves shifted by 90 deg but they are giving no phase shifted sine.

        HTML Code:
           wave_data1[i] = (uint8_t)(128 * (1 + sin(stp * i)));  //127.5; // Half of the max value (255/2)  //\+++++++++++++++++++++++++
        
              wave_data2[i] = (uint8_t)(100 * (1 + cos(stp * i)));                                                                   //  +++++++++++++++++++++++  ​
        This line produces a sine wave on both DACs (DAC 1 and DAC 2).

        HTML Code:
         wave_data2[i] = (uint8_t)(127.5 * (1 + sin(2 * 3.14159 * i / WAVEFORM_SAMPLES)));
        This line does not produce a sine wave on both DACs (DAC 1 and DAC 2).
        HTML Code:
        wave_data1[i] = (uint8_t)(127.5 * (1 + sin(2 * 3.14159 * i / WAVEFORM_SAMPLES)));//

        Comment


        • #34
          Harder to follow because I'm not in a position to do the same thing as you.
          In that case it's fun to ask the AI.
          Too bad I can't copy the whole chat here.
          In short, you have a lot of problems there.
          ​Are you still basing your code on the code from post #22?
          If that is the case; than read this:


          PWM & I2S Conflicts
          Problem: The PWM (LEDC) and I2S DAC both use the internal DAC (GPIO 25 & 26).
          Fix: If using I2S DAC, avoid PWM on DAC pins (25, 26). Use external PWM drivers if needed.

          Sample Rate Mismatch
          Problem: The I2S sample rate (400 kHz) is much higher than the PWM frequency (16 kHz).
          Fix: Align the I2S rate with the PWM frequency to avoid aliasing.

          Waveform Efficiency
          Problem: The linear ramp (wave_data1) may not be optimal for metal detection.
          Fix: Use only sine waves (wave_data2) for better sensitivity.

          Floating Variables
          Problem: i is declared globally but unused.
          Fix: Remove unused variables to save memory.

          The issue you're facing is that changing the amplitude in software doesn't affect the actual output voltage when
          using the ESP32's built-in DAC.
          This happens because the I2S DAC has a fixed output range (0–3.3V) and does not allow direct amplitude modulation
          in the same way a PWM or external DAC would.

          Why Amplitude Doesn’t Change
          ESP32’s DAC is 8-bit (0–255) → Fixed 0–3.3V range.
          Even if you reduce values in software (e.g., amp = 60), the DAC still outputs 0–3.3V, just with fewer steps.
          The perceived amplitude (peak-to-peak voltage) remains the same.
          I2S DAC Mode Limitations
          The built-in DAC does not support variable reference voltage (unlike external DACs).

          Solutions to Control Amplitude
          1. Use PWM + Filtering (Best for Adjustable Amplitude)
          If you need true amplitude control, use PWM + an RC low-pass filter instead of the I2S DAC.

          Comment


          • #35
            Manually I can change amplitude
            HTML Code:
            int amp = 128;// 10 to 128 = 1/2 of 256 ,20 =0.52 Vpp, 40 = 1Vpp,128 = 3.28Vpp
            but using the buttons I have a problem, even serial monitor is blank, no reaction on button pressing.
            HTML Code:
            void ampchanges ()
            {
              int amp;
              if (digitalRead(32) == LOW)
              {
                amp++;
              }
              if (digitalRead(33) == LOW)
              {
                amp--;
              }
              Serial.print("amp  = ");
              Serial.println(amp);
            }​

            Comment


            • #36
              HTML Code:
              //https://esp32.com/viewtopic.php?p=144590&hilit=sin#p144590
              #include "driver/i2s.h"
              ////////////////////////
              #include <driver/ledc.h>
              ////////////////////////
              #define SAMPLE_RATE 4000000
              //#define WAVEFORM_SAMPLES 256            //3kHz
              //#define WAVEFORM_SAMPLES 100            // 8kHz
              //#define WAVEFORM_SAMPLES 50               //16 kHz
              ///////////////////////////
              #define WAVEFORM_SAMPLES 400           // 500 = 16kHz, 400 = 20kHz
              //#define SAMPLES 130
              int amp = 128;// 10 to 128 = 1/2 of 256 ,20 =0.52 Vpp, 40 = 1Vpp,128 = 3.28Vpp
              int cnt = 0;
              int time_track = 0;
              float stp = 6.2831 / WAVEFORM_SAMPLES;
              
              uint8_t stereo_buffer[WAVEFORM_SAMPLES * 2];
              uint8_t wave_data1[WAVEFORM_SAMPLES];
              uint8_t wave_data2[WAVEFORM_SAMPLES];
              
              void generateWaveforms() {
                //for (int i = 0; i < WAVEFORM_SAMPLES; i++)
                for (int i = 0; i < WAVEFORM_SAMPLES; i++)
                {
                  wave_data1[i] = (uint8_t)(amp * (1 + sin(stp * i)));  //127.5; // Half of the max value (255/2)
                  wave_data2[i] = (uint8_t)(amp * (1 + sin(stp * i)));
                   // wave_data2[i] = (uint8_t)(100 * (1 + cos(stp * i)));
                  // int dutyCycle = (int)(amp + amp * sin(stp * i)); //
                }
              
                for (int i = 0; i < WAVEFORM_SAMPLES; i++) {
                  stereo_buffer[i * 2] = wave_data1[i];      // DAC1
                  stereo_buffer[i * 2 + 1] = wave_data2[i];  // DAC2
                }
              }
              
              void setup() {
                Serial.begin(115200);
                //////////////////////
                ledc_timer_config_t timerConfig = {
                  .speed_mode = LEDC_LOW_SPEED_MODE,
                  .duty_resolution = LEDC_TIMER_10_BIT,
                  .timer_num = LEDC_TIMER_0,
                  .freq_hz = 8000,
                  .clk_cfg = LEDC_AUTO_CLK
                };
                ledc_timer_config(&timerConfig);
              
              
                ledc_channel_config_t channelConfig1 = {
                  .gpio_num = 12,
                  .speed_mode = LEDC_LOW_SPEED_MODE,
                  .channel = LEDC_CHANNEL_0,
                  .timer_sel = LEDC_TIMER_0,
                  .duty = 512,
                  .hpoint = 0
                };
                ledc_channel_config(&channelConfig1);
              
              
                ledc_channel_config_t channelConfig2 = {
                  .gpio_num = 14,
                  .speed_mode = LEDC_LOW_SPEED_MODE,
                  .channel = LEDC_CHANNEL_1,
                  .timer_sel = LEDC_TIMER_0,
                  .duty = 512,
                  .hpoint = 256 // 90 deg
                };
                ledc_channel_config(&channelConfig2);
                /////////////////////////
                generateWaveforms();
              
                i2s_config_t i2s_config = {
                  .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN),
                  .sample_rate = SAMPLE_RATE,
                  .bits_per_sample = I2S_BITS_PER_SAMPLE_8BIT,
                  .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
                  .communication_format = I2S_COMM_FORMAT_I2S_MSB,
                  .intr_alloc_flags = 0,
                  .dma_buf_count = 8,
                  .dma_buf_len = WAVEFORM_SAMPLES * 2,
                  .use_apll = false,
                };
              
                i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
                i2s_set_pin(I2S_NUM_0, NULL);
                i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN);
                i2s_set_sample_rates(I2S_NUM_0, i2s_config.sample_rate);
              }
              
              void loop() {
                size_t bytes_written;
                i2s_write(I2S_NUM_0, stereo_buffer, sizeof(stereo_buffer), &bytes_written, portMAX_DELAY);
              }
              //+++++++++++++++++++++++++++++++++++++++++++++++
              void ampchanges ()
              {
                int amp;
                if (digitalRead(32) == LOW)
                {
                  amp++;
                }
                if (digitalRead(33) == LOW)
                {
                  amp--;
                }
                Serial.print("amp  = ");
                Serial.println(amp);
              }
              ​

              Comment

              Working...
              X