I have a custom made PCB with 3 buzzers connected to an esp32-s3-wroom-1. I set up a routine on core 0 that takes the wanted frequencies and applies them to the buzzers but no sound comes out. When I use the tone function inside setup it works, but I want to be able to write to all 3 buzzers at the same time. I also tried using the LEDC library but the IDE keeps giving me the following error:
error: 'ledcSetup' was not declared in this scope
10 | ledcSetup(LEDC_CHANNEL, 50, LEDC_RESOLUTION);
| ^~~~~~~~~
and:
12 | ledcAttachPin(LEDC_PIN, LEDC_CHANNEL);
| ^~~~~~~~~~~~~
| ledcAttach
code with LEDc:
#include <Arduino.h>
// Define LEDC channel, GPIO pin, and resolution
#define LEDC_CHANNEL 0
#define LEDC_PIN 46
#define LEDC_RESOLUTION 10 // 10-bit resolution (0–1023)
void setup() {
// Initialize LEDC channel with 50Hz frequency and 10-bit resolution
ledcSetup(LEDC_CHANNEL, 50, LEDC_RESOLUTION);
// Attach the LEDC channel to the GPIO pin
ledcAttachPin(LEDC_PIN, LEDC_CHANNEL);
}
void loop() {
// Calculate duty values for 10-bit resolution
int maxDuty = (1 << LEDC_RESOLUTION) - 1;
ledcWrite(LEDC_CHANNEL, maxDuty * 0.075); // 7.5% duty cycle
delay(1000);
ledcWrite(LEDC_CHANNEL, maxDuty * 0.0875); // 8.75% duty cycle
delay(1000);
ledcWrite(LEDC_CHANNEL, maxDuty * 0.075); // 7.5%
delay(1000);
ledcWrite(LEDC_CHANNEL, maxDuty * 0.0625); // 6.25%
delay(1000);
}
code with custom function on core 0:
#include <SPI.h>
#include <SoftSPIB.h>
#define MAX_LEN 64
SoftSPIB spi(17, 18, 35);
#define PWM_PIN 46
int freq1 = 440;
int freq2 = 0;
int freq3 = 0;
bool buzzer1 = 0;
void buzzerHandle(void* parameter) {
long lastTime = 0; // Store the last time for frequency checking
uint8_t buzzer1 = 0; // State of buzzer1 (0 = off, 1 = on)
for (;;) {
long time = micros(); // Get current time in microseconds
// Check if frequency for buzzer1 is greater than 0
if (freq1 > 0) {
// Calculate period in microseconds for the given frequency
long period = 1000000L / freq1; // 1 second / frequency = period in microseconds
// Toggle buzzer state when the period is reached
if ((time - lastTime) >= (period / 2)) { // Toggle every half period
buzzer1 = !buzzer1; // Toggle buzzer state (0 -> 1 or 1 -> 0)
lastTime = time; // Update last time
}
}
Serial.println(buzzer1);
// Output the signal to pin 46
digitalWrite(PWM_PIN, buzzer1 == 0 ? LOW : HIGH);
// You can adjust the delay here if needed, but keeping it minimal to avoid time drift
delayMicroseconds(10); // Short delay to prevent excessive CPU usage
}
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
spi.begin();
pinMode(46, OUTPUT);
tone(46, 440, 3000);
TaskHandle_t buzzerTask;
xTaskCreatePinnedToCore(
buzzerHandle, /* Function to implement the task */
"handleBuzzer", /* Name of the task */
10000, /* Stack size in words */
NULL, /* Task input parameter */
0, /* Priority of the task */
&buzzerTask, /* Task handle. */
0); /* Core where the task should run */
}
void loop() {
char buffer[MAX_LEN + 1]; // +1 for null terminator
for (int i = 0; i < MAX_LEN; i++) {
buffer[i] = spi.transfer(0x00); // Read one byte by sending 0x00
}
if (buffer == "B1 440Hz") {
}
}
is there a problem where the 2nd core is not able to access the ports or is the code simply wrong? I have looked on multiple websites for help but I cannot find anything that can help me understand the LEDC library (it would be a better variant than using the other core). Does anyone have any experience with it?
