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;
}
}
}
jim-p
December 3, 2024, 12:47pm
2
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;
}
}
}
jim-p
December 3, 2024, 12:58pm
4
Thank you.
What do you want to do when it closes/opens spontaneously?
play other sounds, for example the sound of an engine braking
jim-p
December 3, 2024, 1:10pm
6
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.
pert
December 3, 2024, 2:27pm
7
@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
system
Closed
June 1, 2025, 2:27pm
8
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.