Sound simulation

can you add a command when the currentthrottle (potval) closes spontaneously from 1023-0 or -1023 -0 or reverse

case 2: // running ----
     
      if ((currentThrottle >= 0) && (currentThrottle <= 1000)) {
      if (curIdleSample >= idle_length) { // Loop the sample
        curIdleSample = 0;
      }
      OCR1A = currentIdleRate; // variable sample rate (RPM)!
      OCR2B = pgm_read_byte(&idle_data[curIdleSample]);
      curIdleSample++;
      break;
      }
      else if ((currentThrottle >= 1000) && (currentThrottle <= 1023)) {
       if (curOnlimiterSample >= onlimiter_length) { // Loop the sample
        curOnlimiterSample = 0;
      }
      OCR1A = currentONlimiterRate; // variable sample rate (RPM)!
      OCR2B = pgm_read_byte(&onlimiter_data[curOnlimiterSample]);
      curOnlimiterSample++;
      break;
      }
   }
}


Need to see the entire code

#include "settings.h"
#include "curves.h" // load nonlinear throttle curve arrays
#define SPEAKER1 3
#define SPEAKER2 11
                               // Amplifier PAM8403 connected to pin 3 (via 10kOhm potentiometer)
#define FREQ 32000000L                         // 16MHz clock frequency

// Define global variables
volatile uint32_t currentIdleRate = BASE_RATE;
volatile uint32_t currentONlimiterRate = ONLIMITER_RATE;
volatile uint32_t fixedSmpleRate = FREQ / BASE_RATE;
volatile uint16_t engineState = 1;
volatile uint32_t curIdleSample;
volatile uint32_t curOnlimiterSample;         
volatile uint32_t curStartSample;
bool SoundTransition = true;
uint16_t  currentThrottle = 0;                  // 0 - 500, a top value of 1023 is acceptable
const int analogInPin = A0;  // Analog input pin that the potentiometer is attached to
int sensorValue = 0;        // value read from the pot
void setup() {

  setupPcm();
}
void setupPcm() {

  pinMode(SPEAKER1, OUTPUT);
  pinMode(SPEAKER2, OUTPUT);
  pinMode(analogInPin,INPUT);
  // Set up Timer 2 to do pulse width modulation on the speaker pin.
  ASSR &= ~(_BV(EXCLK) | _BV(AS2));                         // Use internal clock (datasheet p.160)

  TCCR2A |= _BV(WGM21) | _BV(WGM20);                        // Set fast PWM mode  (p.157)
  TCCR2B &= ~_BV(WGM22);

  TCCR2A = (TCCR2A | _BV(COM2B1)) & ~_BV(COM2B0);           // Do non-inverting PWM on pin OC2B (p.155)
  TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
  TCCR2B = _BV(CS22);
  OCR2A = 180;
  OCR2B = 180;                   // On the Arduino this is pin 3.
  TCCR2B = (TCCR2B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10); // No prescaler (p.158)

  OCR2B = pgm_read_byte(&idle_data[curIdleSample]);                       // Set initial pulse width to the first sample.                       // Set initial pulse width to the first sample.
  OCR2B = pgm_read_byte(&onlimiter_data[curOnlimiterSample]);
  // Set up Timer 1 to send a sample every interrupt.
  cli();

  TCCR1B = (TCCR1B & ~_BV(WGM13)) | _BV(WGM12);             // Set CTC mode (Clear Timer on Compare Match) (p.133)
  TCCR1A = TCCR1A & ~(_BV(WGM11) | _BV(WGM10));             // Have to set OCR1A *after*, otherwise it gets reset to 0!

  TCCR1B = (TCCR1B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10); // No prescaler (p.134)

  OCR1A = FREQ / BASE_RATE;
                                  // Set the compare register (OCR1A).
  // OCR1A is a 16-bit register, so we have to do this with
  // interrupts disabled to be safe.

  TIMSK1 |= _BV(OCIE1A);                                   // Enable interrupt when TCNT1 == OCR1A (p.136)

  
  curIdleSample = 0;
  curOnlimiterSample = 0;
  curStartSample = 0;



  sei();
}

void engineMassSimulation() {

  static int32_t  mappedThrottle = 0;
  static int32_t currentRpm = 0;
  static unsigned long throtMillis;

  if (millis() - throtMillis > 5) { // Every 5ms
    throtMillis = millis();

    // compute unlinear throttle curve
    mappedThrottle = reMap(curveShifting, currentThrottle);

    // Accelerate engine
    if (mappedThrottle + acc > currentRpm && engineState == 2) {
      currentRpm += acc;
      if (currentRpm > maxRpm) currentRpm = maxRpm;
    }

    // Decelerate engine
    else if (mappedThrottle - dec < currentRpm) {
      currentRpm -= dec;
      if (currentRpm < minRpm) currentRpm = minRpm;
    }

    if ((currentThrottle >= 0) && (currentThrottle <= 1000)) {
    currentIdleRate = FREQ / (BASE_RATE + long(currentRpm * IDLE_MULTIPLIER) ); //1
    }   
    else if((currentThrottle >= 1000) && (currentThrottle <= 1023)) {
    currentONlimiterRate = FREQ / (ONLIMITER_RATE + long(currentRpm * LIMITER_MULTIPLIER) );//
    }
  }

}
void loop() {
  sensorValue = analogRead(analogInPin);
  // map it to the range of the analog out:
  currentThrottle = map(sensorValue, 200, 1023, 0, 1023);
  // Simulate engine mass, generate RPM signal
  engineMassSimulation();
}


// This is the main sound playback interrupt, keep this nice and tight!! ------------------------------
ISR(TIMER1_COMPA_vect) {

  static float attenuator;  // Float required for finer granularity!

  switch (engineState) {
  
      case 1:
      if (curStartSample >= start_length) { // Loop the sample
        curStartSample = 0;
        engineState = 2;
      }
      OCR1A = fixedSmpleRate; // fixed sample rate (speed)!
      OCR2B = pgm_read_byte(&start_data[curStartSample]);
      curStartSample++;
      break;      

     case 2: // running ----
     
      if ((currentThrottle >= 0) && (currentThrottle <= 1000)) {
      if (curIdleSample >= idle_length) { // Loop the sample
        curIdleSample = 0;
      }
      OCR1A = currentIdleRate; // variable sample rate (RPM)!
      OCR2B = pgm_read_byte(&idle_data[curIdleSample]);
      curIdleSample++;
      break;
      }
      else if ((currentThrottle >= 1000) && (currentThrottle <= 1023)) {
       if (curOnlimiterSample >= onlimiter_length) { // Loop the sample
        curOnlimiterSample = 0;
      }
      OCR1A = currentONlimiterRate; // variable sample rate (RPM)!
      OCR2B = pgm_read_byte(&onlimiter_data[curOnlimiterSample]);
      curOnlimiterSample++;
      break;
      }
   }
}


Thank you.
What do you want to do when it closes/opens spontaneously?

play other sounds, for example the sound of an engine braking

It's certainly possible to do what you want but off-hand, I'm not sure how to integrate that function into your existing code. For me me it would take some time to analyze the code.

@yuzeng_39 your topic was moved to its current location as it is more suitable.

Could you also take a few moments to Learn How To Use The Forum.

It will help you get the best out of the forum in the future.

Thank you

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.