CCCPaste

Simultaneous Pulses rev_02

/********* Pleasedontcode.com **********

	Pleasedontcode thanks you for automatic code generation! Enjoy your code!

	- Terms and Conditions:
	You have a non-exclusive, revocable, worldwide, royalty-free license
	for personal and commercial use. Attribution is optional; modifications
	are allowed, but you're responsible for code maintenance. We're not
	liable for any loss or damage. For full terms,
	please visit pleasedontcode.com/termsandconditions.

	- Project: Simultaneous Pulses
	- Source Code compiled for: ESP32 DevKit V1
	- Source Code created on: 2025-10-19 08:07:02

********* Pleasedontcode.com **********/

/****** SYSTEM REQUIREMENTS *****/
/****** SYSTEM REQUIREMENT 1 *****/
	/* provide five pulse outputs simultaneously of one */
	/* millisecond  at individual frequencies . The */
	/* frequencies required are as follows : 10 Hz , 25 */
	/* Hz , 50 Hz , 75 Hz , 100 Hz . */
/****** END SYSTEM REQUIREMENTS *****/




/* START CODE */

/****** DEFINITION OF LIBRARIES *****/

/****** FUNCTION PROTOTYPES *****/
void setup(void);
void loop(void);

// ESP32 Five-Channel Pulse Generator
// Generates five simultaneous 1 ms pulses at frequencies:
// 10 Hz, 25 Hz, 50 Hz, 75 Hz, 100 Hz on five separate GPIO pins.

// Pin assignments for ESP32 DevKit V1 (adjust if needed):
const uint8_t PULSE_PINS[5] = {16, 17, 18, 19, 21};

// Target frequencies in Hz
const uint32_t PULSE_FREQS[5] = {10, 25, 50, 75, 100};

// Internal channel representation
typedef struct {
    uint8_t pin;          // GPIO pin for the channel
    uint64_t period_us;     // Pulse period in microseconds
    uint64_t next_time;     // Next scheduled pulse start time (microseconds)
    bool in_pulse;          // Is the 1 ms pulse currently high?
    uint64_t pulse_end;     // Time when current 1 ms pulse ends
} PulseChannel;

PulseChannel channels[5];

void setup(void)
{
    // Initialize serial for debugging (optional)
    // Serial.begin(115200);

    // Configure pins as outputs and reset state
    for (int i = 0; i < 5; i++) {
        pinMode(PULSE_PINS[i], OUTPUT);
        digitalWrite(PULSE_PINS[i], LOW);
    }

    // Initialize channel parameters
    uint64_t now = (uint64_t)micros();
    for (int i = 0; i < 5; i++) {
        channels[i].pin = PULSE_PINS[i];
        // Use integer division for period; fractional remainder ignored per cycle
        channels[i].period_us = (uint64_t)(1000000ull / PULSE_FREQS[i]);
        channels[i].next_time = now;  // start pulses immediately
        channels[i].in_pulse = false;
        channels[i].pulse_end = 0;
    }
}

void loop(void)
{
    uint64_t now = (uint64_t)micros();

    for (int i = 0; i < 5; i++) {
        // If not currently pulsing and it's time for the next pulse, start a 1 ms pulse
        if (!channels[i].in_pulse && now >= channels[i].next_time) {
            digitalWrite(channels[i].pin, HIGH);
            channels[i].in_pulse = true;
            channels[i].pulse_end = now + 1000ull; // 1 ms pulse width
        }
        // If currently pulsing and the 1 ms width has elapsed, end pulse and schedule next
        else if (channels[i].in_pulse && now >= channels[i].pulse_end) {
            digitalWrite(channels[i].pin, LOW);
            channels[i].in_pulse = false;
            // Schedule next pulse start time based on period
            channels[i].next_time += channels[i].period_us;
            // If we somehow fell behind, realign to now
            if (channels[i].next_time < now) {
                channels[i].next_time = now + channels[i].period_us;
            }
        }
    }

    // Small delay to prevent excessive CPU usage; keeps loop responsive
    delayMicroseconds(50);
}

/* END CODE */