ماژول اپتوکوپلر چهار حالته

Four Optocoupler Module

[table id=6 /]

ایزولاتور چهار کاناله برای کاربردهای پیچیده صنعتی

⚡ اپتوکوپلر چهار حالته: راه‌حل جامع ایزولاسیون چندکاناله

ماژول اپتوکوپلر چهار حالته (Quad Channel Optocoupler) یک راه‌حل صنعتی کامل برای ایزوله کردن همزمان چهار سیگنال است. این ماژول ایده‌آل برای سیستم‌های PLC، رابط‌های صنعتی و کنترل‌کننده‌های چند کاناله است.

🎯 مزایای کلیدی چهار کاناله

🔌 طراحی فشرده و کارآمد:

  • چهار کانال مستقل: ایزولاسیون مجزای چهار سیگنال

  • یکپارچه‌سازی بالا: چهار کانال در یک پکیج DIP-16

  • تطابق کانال‌ها: مشخصات الکتریکی مشابه بین کانال‌ها

  • مدیریت توان بهینه: تلفات حرارتی یکنواخت

⚡ عملکرد صنعتی:

  • ایزولاسیون 5000Vrms: استاندارد صنعتی بالا

  • CTR یکنواخت: تطابق ±10% بین کانال‌ها

  • سرعت هماهنگ: پاسخ یکسان در تمام کانال‌ها

  • طول عمر طولانی: 100,000 ساعت عملیاتی

📊 مشخصات فنی پیشرفته

پارامترهای الکتریکی:

  • ولتاژ ایزولاسیون: 5000Vrms برای 1 دقیقه

  • ولتاژ ورودی LED: 1.15V – 1.5V (Vf @ If=10mA)

  • جریان ورودی: 5mA – 50mA در هر کانال

  • ولتاژ کلکتور-امیتر: 80V حداکثر

  • جریان کلکتور: 50mA در هر کانال (200mA مجموع)

  • CTR (نسبت انتقال): 50% – 600% با تطابق ±10%

پارامترهای عملکردی:

  • زمان پاسخ هر کانال:

    • Ton: 3µs – 15µs (مشخصات تیپیکال)

    • Toff: 4µs – 18µs

  • فرکانس کاری: تا 100kHz (تک کانال)

  • دمای کاری: -55°C تا +110°C

  • مقاومت عایقی: >10¹¹ Ω (ورودی-خروجی)

انواع رایج اپتوکوپلر چهار حالته:

  • TLP621-4: پرکاربردترین، CTR: 50%-600%

  • PS2501-4: سرعت متوسط، ایزولاسیون 5000V

  • LTV-847: با خروجی دارلینگتون

  • HCPL-2731: چهار کاناله با خروجی منطقی

  • SFH6346: سرعت بالا، CTR: 100%-400%

🔧 ساختار و پیکربندی

پیکربندی پایه‌های DIP-16:

پیکربندی استاندارد 16 پایه:
     ┌───┐
 1  │ ● │ 16   پایه 1: آند LED کانال 1
 2  │   │ 15   پایه 2: کاتد LED کانال 1
 3  │   │ 14   پایه 3: آند LED کانال 2
 4  │   │ 13   پایه 4: کاتد LED کانال 2
 5  │   │ 12   پایه 5: آند LED کانال 3
 6  │   │ 11   پایه 6: کاتد LED کانال 3
 7  │   │ 10   پایه 7: آند LED کانال 4
 8  │   │ 9    پایه 8: کاتد LED کانال 4
     └───┘     پایه 9: امیتر کانال 4
              پایه 10: کلکتور کانال 4
              پایه 11: امیتر کانال 3
              پایه 12: کلکتور کانال 3
              پایه 13: امیتر کانال 2
              پایه 14: کلکتور کانال 2
              پایه 15: امیتر کانال 1
              پایه 16: کلکتور کانال 1

ساختمان داخلی پیشرفته:

کانال 1: [LED1] → [فوتوترانزیستور1]
کانال 2: [LED2] → [فوتوترانزیستور2]
کانال 3: [LED3] → [فوتوترانزیستور3]
کانال 4: [LED4] → [فوتوترانزیستور4]
           ↓              ↓
     ورودی 1-4      خروجی 1-4
     (ایزوله)      (ایزوله)

💻 برنامه‌نویسی و کنترل چهار کاناله

اتصال پایه به آردوینو:

// تعریف پایه‌های اپتوکوپلر چهار حالته TLP621-4
#define CH1_INPUT_PIN   2    // کنترل LED کانال 1
#define CH1_OUTPUT_PIN  3    // خواندن خروجی کانال 1
#define CH2_INPUT_PIN   4    // کنترل LED کانال 2
#define CH2_OUTPUT_PIN  5    // خواندن خروجی کانال 2
#define CH3_INPUT_PIN   6    // کنترل LED کانال 3
#define CH3_OUTPUT_PIN  7    // خواندن خروجی کانال 3
#define CH4_INPUT_PIN   8    // کنترل LED کانال 4
#define CH4_OUTPUT_PIN  9    // خواندن خروجی کانال 4

// پین‌های فعال‌سازی گروهی
#define GROUP_ENABLE_PIN 10  // فعال‌سازی همه کانال‌ها

void setupQuadOptocoupler() {
    Serial.begin(115200);
    
    // تنظیم پین‌های کنترل کانال‌ها
    for (int i = 0; i < 4; i++) {
        pinMode(CH1_INPUT_PIN + (i * 2), OUTPUT);
        pinMode(CH1_OUTPUT_PIN + (i * 2), INPUT);
        digitalWrite(CH1_INPUT_PIN + (i * 2), LOW); // حالت اولیه
    }
    
    // تنظیم پین فعال‌سازی گروهی
    pinMode(GROUP_ENABLE_PIN, OUTPUT);
    digitalWrite(GROUP_ENABLE_PIN, HIGH); // فعال به طور پیش‌فرض
    
    Serial.println("ماژول اپتوکوپلر چهار حالته راه‌اندازی شد");
    Serial.println("=======================================");
    
    // تست اولیه همه کانال‌ها
    testAllChannels();
}

void testAllChannels() {
    Serial.println("=== تست اولیه چهار کانال ===");
    
    for (int i = 0; i < 4; i++) {
        Serial.print("تست کانال ");
        Serial.println(i + 1);
        testSingleChannel(i);
    }
    
    // تست همزمان
    Serial.println("تست همزمان چهار کانال:");
    testSimultaneousOperation();
}

void testSingleChannel(int channel) {
    int inputPin = CH1_INPUT_PIN + (channel * 2);
    int outputPin = CH1_OUTPUT_PIN + (channel * 2);
    
    // تست HIGH
    digitalWrite(inputPin, HIGH);
    delayMicroseconds(50);
    bool outputState = digitalRead(outputPin);
    Serial.print("  ورودی HIGH، خروجی: ");
    Serial.println(outputState ? "HIGH" : "LOW");
    
    // تست LOW
    digitalWrite(inputPin, LOW);
    delayMicroseconds(50);
    outputState = digitalRead(outputPin);
    Serial.print("  ورودی LOW، خروجی: ");
    Serial.println(outputState ? "HIGH" : "LOW");
}

کلاس مدیریت حرفه‌ای چهار کاناله:

class QuadChannelOptocoupler {
private:
    struct Channel {
        int inputPin;
        int outputPin;
        bool isEnabled;
        bool isInverting;
        unsigned long responseTime;
        float ctr;
        String name;
        bool lastState;
    };
    
    Channel channels[4];
    bool groupEnabled;
    int groupEnablePin;
    unsigned long channelMask; // ماسک 4 بیتی برای وضعیت کانال‌ها
    
public:
    QuadChannelOptocoupler(
        int ch1In, int ch1Out,
        int ch2In, int ch2Out,
        int ch3In, int ch3Out,
        int ch4In, int ch4Out,
        int groupEnPin = -1,
        bool defaultInversion = false
    ) {
        // تنظیم کانال 1
        channels[0].inputPin = ch1In;
        channels[0].outputPin = ch1Out;
        channels[0].name = "کانال 1";
        
        // تنظیم کانال 2
        channels[1].inputPin = ch2In;
        channels[1].outputPin = ch2Out;
        channels[1].name = "کانال 2";
        
        // تنظیم کانال 3
        channels[2].inputPin = ch3In;
        channels[2].outputPin = ch3Out;
        channels[2].name = "کانال 3";
        
        // تنظیم کانال 4
        channels[3].inputPin = ch4In;
        channels[3].outputPin = ch4Out;
        channels[3].name = "کانال 4";
        
        // تنظیمات مشترک
        for (int i = 0; i < 4; i++) {
            channels[i].isEnabled = true;
            channels[i].isInverting = defaultInversion;
            channels[i].responseTime = 10; // µs
            channels[i].ctr = 100.0; // %
            channels[i].lastState = false;
        }
        
        groupEnablePin = groupEnPin;
        groupEnabled = true;
        channelMask = 0x0F; // همه کانال‌ها فعال
        
        initializeAllPins();
    }
    
    void initializeAllPins() {
        for (int i = 0; i < 4; i++) {
            pinMode(channels[i].inputPin, OUTPUT);
            pinMode(channels[i].outputPin, INPUT);
            digitalWrite(channels[i].inputPin, LOW);
        }
        
        if (groupEnablePin != -1) {
            pinMode(groupEnablePin, OUTPUT);
            digitalWrite(groupEnablePin, HIGH);
        }
        
        Serial.println("اپتوکوپلر چهار کاناله آماده است");
        printConfiguration();
    }
    
    void setChannel(int channel, bool state) {
        if (channel >= 0 && channel < 4 && channels[channel].isEnabled) {
            digitalWrite(channels[channel].inputPin, state ? HIGH : LOW);
            channels[channel].lastState = state;
            
            if (channels[channel].responseTime > 0) {
                delayMicroseconds(channels[channel].responseTime);
            }
            
            updateChannelMask(channel, state);
        }
    }
    
    bool getChannelOutput(int channel) {
        if (channel >= 0 && channel < 4) {
            bool rawState = digitalRead(channels[channel].outputPin);
            return channels[channel].isInverting ? !rawState : rawState;
        }
        return false;
    }
    
    void setAllChannels(bool ch1, bool ch2, bool ch3, bool ch4) {
        bool states[4] = {ch1, ch2, ch3, ch4};
        unsigned long startTime = micros();
        
        for (int i = 0; i < 4; i++) {
            if (channels[i].isEnabled) {
                digitalWrite(channels[i].inputPin, states[i] ? HIGH : LOW);
                channels[i].lastState = states[i];
                updateChannelMask(i, states[i]);
            }
        }
        
        // انتظار برای آهسته‌ترین کانال
        unsigned long maxResponse = getMaxResponseTime();
        while (micros() - startTime < maxResponse) {
            // انتظار
        }
    }
    
    void setGroup(bool state) {
        // تنظیم همه کانال‌ها به یک حالت
        for (int i = 0; i < 4; i++) {
            if (channels[i].isEnabled) {
                setChannel(i, state);
            }
        }
    }
    
    void toggleChannel(int channel) {
        if (channel >= 0 && channel < 4) {
            setChannel(channel, !channels[channel].lastState);
        }
    }
    
    void toggleAll() {
        for (int i = 0; i < 4; i++) {
            if (channels[i].isEnabled) {
                toggleChannel(i);
            }
        }
    }
    
    void pulseChannel(int channel, unsigned long durationUs) {
        setChannel(channel, HIGH);
        delayMicroseconds(durationUs);
        setChannel(channel, LOW);
    }
    
    void pulseAll(unsigned long durationUs) {
        unsigned long startTime = micros();
        setGroup(true);
        
        while (micros() - startTime < durationUs) {
            // انتظار
        }
        
        setGroup(false);
    }
    
    void enableChannel(int channel, bool enable) {
        if (channel >= 0 && channel < 4) {
            channels[channel].isEnabled = enable;
            
            if (!enable) {
                setChannel(channel, LOW);
            }
            
            Serial.print(channels[channel].name);
            Serial.println(enable ? " فعال شد" : " غیرفعال شد");
        }
    }
    
    void enableAll(bool enable) {
        groupEnabled = enable;
        
        if (groupEnablePin != -1) {
            digitalWrite(groupEnablePin, enable ? HIGH : LOW);
        }
        
        for (int i = 0; i < 4; i++) {
            channels[i].isEnabled = enable;
        }
        
        Serial.print("گروه کانال‌ها ");
        Serial.println(enable ? "فعال شد" : "غیرفعال شد");
    }
    
    void setResponseTime(int channel, unsigned long timeUs) {
        if (channel >= 0 && channel < 4) {
            channels[channel].responseTime = timeUs;
        }
    }
    
    void setAllResponseTimes(unsigned long timeUs) {
        for (int i = 0; i < 4; i++) {
            channels[i].responseTime = timeUs;
        }
    }
    
    unsigned long getMaxResponseTime() {
        unsigned long maxTime = 0;
        for (int i = 0; i < 4; i++) {
            if (channels[i].responseTime > maxTime) {
                maxTime = channels[i].responseTime;
            }
        }
        return maxTime;
    }
    
    void updateChannelMask(int channel, bool state) {
        if (state) {
            channelMask |= (1 << channel);
        } else {
            channelMask &= ~(1 << channel);
        }
    }
    
    unsigned long getChannelMask() {
        return channelMask & 0x0F; // فقط 4 بیت اول
    }
    
    void printConfiguration() {
        Serial.println("=== پیکربندی اپتوکوپلر چهار کاناله ===");
        Serial.println("کانال | فعال | معکوس | زمان پاسخ");
        Serial.println("------|-------|--------|----------");
        
        for (int i = 0; i < 4; i++) {
            Serial.print(channels[i].name);
            Serial.print(" | ");
            Serial.print(channels[i].isEnabled ? "✓" : "✗");
            Serial.print("     | ");
            Serial.print(channels[i].isInverting ? "✓" : "✗");
            Serial.print("      | ");
            Serial.print(channels[i].responseTime);
            Serial.println("µs");
        }
        
        Serial.print("ماسک کانال‌ها: 0x");
        Serial.println(getChannelMask(), HEX);
    }
    
    void measureChannelCharacteristics() {
        Serial.println("=== اندازه‌گیری مشخصات کانال‌ها ===");
        Serial.println("کانال | Ton (µs) | Toff (µs) | CTR (%)");
        Serial.println("------|----------|-----------|---------");
        
        for (int i = 0; i < 4; i++) {
            // اندازه‌گیری زمان روشن شدن
            unsigned long startTime = micros();
            setChannel(i, HIGH);
            unsigned long ton = micros() - startTime;
            
            // اندازه‌گیری زمان خاموش شدن
            startTime = micros();
            setChannel(i, LOW);
            unsigned long toff = micros() - startTime;
            
            // تخمین CTR (نسبت انتقال)
            float ctr = estimateCTR(i);
            
            Serial.print(channels[i].name);
            Serial.print(" | ");
            Serial.print(ton);
            Serial.print("     | ");
            Serial.print(toff);
            Serial.print("      | ");
            Serial.print(ctr, 1);
            Serial.println("%");
        }
        
        // تحلیل تطابق
        analyzeChannelMatching();
    }
    
    float estimateCTR(int channel) {
        // تخمین CTR بر اساس زمان پاسخ و رفتار خروجی
        // این یک تخمین ساده است، برای اندازه‌گیری دقیق نیاز به سخت‌افزار اضافی دارد
        return channels[channel].ctr;
    }
    
    void analyzeChannelMatching() {
        Serial.println("\n=== تحلیل تطابق کانال‌ها ===");
        
        float tonAvg = 0, toffAvg = 0;
        float tonValues[4], toffValues[4];
        
        // جمع‌آوری داده‌ها
        for (int i = 0; i < 4; i++) {
            // اندازه‌گیری‌ها را تکرار کنید
            tonValues[i] = measureExactTon(i);
            toffValues[i] = measureExactToff(i);
            
            tonAvg += tonValues[i];
            toffAvg += toffValues[i];
        }
        
        tonAvg /= 4.0;
        toffAvg /= 4.0;
        
        // محاسبه انحراف استاندارد
        float tonStdDev = 0, toffStdDev = 0;
        for (int i = 0; i < 4; i++) {
            tonStdDev += pow(tonValues[i] - tonAvg, 2);
            toffStdDev += pow(toffValues[i] - toffAvg, 2);
        }
        
        tonStdDev = sqrt(tonStdDev / 4.0);
        toffStdDev = sqrt(toffStdDev / 4.0);
        
        Serial.print("انحراف استاندارد Ton: ");
        Serial.print(tonStdDev, 2);
        Serial.print("µs (");
        Serial.print((tonStdDev / tonAvg) * 100, 1);
        Serial.println("%)");
        
        Serial.print("انحراف استاندارد Toff: ");
        Serial.print(toffStdDev, 2);
        Serial.print("µs (");
        Serial.print((toffStdDev / toffAvg) * 100, 1);
        Serial.println("%)");
        
        // تشخیص کانال‌های نامنطبق
        for (int i = 0; i < 4; i++) {
            float tonDeviation = abs(tonValues[i] - tonAvg) / tonAvg * 100;
            float toffDeviation = abs(toffValues[i] - toffAvg) / toffAvg * 100;
            
            if (tonDeviation > 20 || toffDeviation > 25) {
                Serial.print("⚠️ ");
                Serial.print(channels[i].name);
                Serial.println(" خارج از محدوده تطابق");
            }
        }
    }
    
    void runComprehensiveTestSuite() {
        Serial.println("=== تست جامع چهار کاناله ===");
        
        // 1. تست عملکرد پایه
        Serial.println("\n1. تست عملکرد پایه:");
        basicFunctionalTest();
        
        // 2. تست زمان پاسخ
        Serial.println("\n2. تست زمان‌های پاسخ:");
        responseTimeTest();
        
        // 3. تست ایزولاسیون
        Serial.println("\n3. تست ایزولاسیون:");
        isolationTest();
        
        // 4. تست تطابق کانال‌ها
        Serial.println("\n4. تست تطابق کانال‌ها:");
        channelMatchingTest();
        
        // 5. تست بارگذاری
        Serial.println("\n5. تست بارگذاری:");
        loadingTest();
        
        Serial.println("\n✅ تست کامل شد");
        generateTestReport();
    }
};

⚙️ کاربردهای صنعتی پیشرفته

۱. رابط PLC چهار کاناله:

class PLC4ChannelInterface {
private:
    QuadChannelOptocoupler inputInterface;
    QuadChannelOptocoupler outputInterface;
    bool inputStates[4];
    bool outputStates[4];
    unsigned long debounceTimes[4];
    
public:
    PLC4ChannelInterface(
        // Inputs
        int in1In, int in1Out,
        int in2In, int in2Out,
        int in3In, int in3Out,
        int in4In, int in4Out,
        // Outputs
        int out1In, int out1Out,
        int out2In, int out2Out,
        int out3In, int out3Out,
        int out4In, int out4Out
    ) : inputInterface(in1In, in1Out, in2In, in2Out, in3In, in3Out, in4In, in4Out),
        outputInterface(out1In, out1Out, out2In, out2Out, out3In, out3Out, out4In, out4Out) {
        
        for (int i = 0; i < 4; i++) {
            inputStates[i] = false;
            outputStates[i] = false;
            debounceTimes[i] = 10; // ms
        }
        
        Serial.println("رابط PLC چهار کاناله راه‌اندازی شد");
    }
    
    void readAllInputs() {
        static bool lastStates[4] = {false, false, false, false};
        static unsigned long lastChangeTime[4] = {0, 0, 0, 0};
        
        for (int i = 0; i < 4; i++) {
            bool currentState = inputInterface.getChannelOutput(i);
            
            if (currentState != lastStates[i]) {
                unsigned long currentTime = millis();
                
                if (currentTime - lastChangeTime[i] > debounceTimes[i]) {
                    lastChangeTime[i] = currentTime;
                    lastStates[i] = currentState;
                    inputStates[i] = currentState;
                    
                    Serial.print("ورودی ");
                    Serial.print(i + 1);
                    Serial.print(" تغییر کرد: ");
                    Serial.println(currentState ? "ACTIVE" : "INACTIVE");
                    
                    processInputChange(i, currentState);
                }
            }
        }
    }
    
    void writeAllOutputs(bool out1, bool out2, bool out3, bool out4) {
        outputInterface.setAllChannels(out1, out2, out3, out4);
        
        outputStates[0] = out1;
        outputStates[1] = out2;
        outputStates[2] = out3;
        outputStates[3] = out4;
        
        // مانیتور جریان خروجی
        monitorOutputCurrents();
    }
    
    void writeOutput(int channel, bool state) {
        if (channel >= 0 && channel < 4) {
            outputInterface.setChannel(channel, state);
            outputStates[channel] = state;
            
            Serial.print("خروجی ");
            Serial.print(channel + 1);
            Serial.print(" تنظیم شد: ");
            Serial.println(state ? "ON" : "OFF");
        }
    }
    
    void processInputChange(int channel, bool state) {
        // منطق کنترل بر اساس تغییرات ورودی
        switch(channel) {
            case 0: // Emergency Stop
                if (state) {
                    emergencyStop();
                }
                break;
                
            case 1: // Start Button
                if (state) {
                    startProcess();
                }
                break;
                
            case 2: // Stop Button
                if (state) {
                    stopProcess();
                }
                break;
                
            case 3: // Reset Button
                if (state) {
                    resetSystem();
                }
                break;
        }
    }
    
    void emergencyStop() {
        Serial.println("🚨 توقف اضطراری فعال شد");
        outputInterface.setGroup(false); // خاموش کردن همه خروجی‌ها
        triggerAlarm();
    }
    
    void monitorOutputCurrents() {
        static unsigned long lastCheck = 0;
        if (millis() - lastCheck > 1000) {
            lastCheck = millis();
            
            // شبیه‌سازی مانیتورینگ جریان
            for (int i = 0; i < 4; i++) {
                if (outputStates[i]) {
                    // در حالت واقعی، جریان از سنسور خوانده می‌شود
                    float simulatedCurrent = 15.0 + random(-5, 5); // mA
                    
                    if (simulatedCurrent > 25.0) {
                        Serial.print("⚠️ جریان بالا در خروجی ");
                        Serial.println(i + 1);
                        reduceOutputCurrent(i);
                    }
                }
            }
        }
    }
    
    void setDebounceTime(int channel, unsigned long timeMs) {
        if (channel >= 0 && channel < 4) {
            debounceTimes[channel] = timeMs;
        }
    }
    
    void diagnosticCheck() {
        Serial.println("=== تست تشخیصی رابط PLC ===");
        
        // تست ورودی‌ها
        Serial.println("تست ورودی‌ها:");
        for (int i = 0; i < 4; i++) {
            bool state = inputInterface.getChannelOutput(i);
            Serial.print("  ورودی ");
            Serial.print(i + 1);
            Serial.print(": ");
            Serial.println(state ? "ACTIVE" : "INACTIVE");
        }
        
        // تست خروجی‌ها
        Serial.println("تست خروجی‌ها:");
        testAllOutputs();
        
        // تست ایزولاسیون
        Serial.println("تست ایزولاسیون:");
        checkIsolation();
        
        Serial.println("✅ تست تشخیصی کامل شد");
    }
};

۲. کنترلر موتور استپر چهار فاز:

class FourPhaseStepperController {
private:
    QuadChannelOptocoupler driver;
    int stepSequence[8][4] = {
        {HIGH, LOW, LOW, LOW},
        {HIGH, HIGH, LOW, LOW},
        {LOW, HIGH, LOW, LOW},
        {LOW, HIGH, HIGH, LOW},
        {LOW, LOW, HIGH, LOW},
        {LOW, LOW, HIGH, HIGH},
        {LOW, LOW, LOW, HIGH},
        {HIGH, LOW, LOW, HIGH}
    };
    int currentStep;
    int microstepLevel;
    int stepsPerRevolution;
    float currentPosition; // درجه
    
public:
    FourPhaseStepperController(
        int ch1In, int ch1Out,
        int ch2In, int ch2Out,
        int ch3In, int ch3Out,
        int ch4In, int ch4Out,
        int steps = 200,
        int microstep = 1
    ) : driver(ch1In, ch1Out, ch2In, ch2Out, ch3In, ch3Out, ch4In, ch4Out) {
        
        currentStep = 0;
        microstepLevel = microstep;
        stepsPerRevolution = steps * microstepLevel;
        currentPosition = 0.0;
        
        // غیرفعال کردن همه کانال‌ها در ابتدا
        driver.setGroup(false);
        
        Serial.println("کنترلر استپر چهار فاز آماده است");
        Serial.print("رزولوشن: ");
        Serial.print(stepsPerRevolution);
        Serial.println(" استپ بر دور");
    }
    
    void step(int direction, int steps = 1) {
        for (int i = 0; i < steps; i++) {
            currentStep = (currentStep + direction + 8) % 8;
            
            if (microstepLevel == 1) {
                // حالت تمام استپ
                driver.setAllChannels(
                    stepSequence[currentStep][0],
                    stepSequence[currentStep][1],
                    stepSequence[currentStep][2],
                    stepSequence[currentStep][3]
                );
            } else {
                // حالت میکرواستپ
                applyMicrostep(currentStep, direction);
            }
            
            // به‌روزرسانی موقعیت
            updatePosition(direction);
            
            // تأخیر بین استپ‌ها
            delayMicroseconds(1000); // 1ms
        }
    }
    
    void applyMicrostep(int baseStep, int direction) {
        // پیاده‌سازی میکرواستپینگ
        float angle = (2.0 * PI * baseStep) / 8.0;
        float microAngle = angle + (direction * PI / (4.0 * microstepLevel));
        
        float currents[4];
        for (int phase = 0; phase < 4; phase++) {
            float phaseAngle = (PI / 2.0) * phase;
            currents[phase] = sin(microAngle - phaseAngle);
            
            // تبدیل به PWM یا جریان آنالوگ
            applyPhaseCurrent(phase, currents[phase]);
        }
    }
    
    void applyPhaseCurrent(int phase, float current) {
        // کنترل جریان فاز (با PWM یا درایور جریان)
        float dutyCycle = (current + 1.0) / 2.0; // تبدیل به 0-1
        applyPWMTophase(phase, dutyCycle);
    }
    
    void applyPWMTophase(int phase, float duty) {
        // شبیه‌سازی PWM (در حالت واقعی از تایمر استفاده می‌شود)
        unsigned long onTime = 100 * duty; // µs
        driver.pulseChannel(phase, onTime);
    }
    
    void updatePosition(int direction) {
        float stepAngle = 360.0 / stepsPerRevolution;
        currentPosition += direction * stepAngle;
        
        // نرمال‌سازی به محدوده 0-360
        while (currentPosition >= 360.0) currentPosition -= 360.0;
        while (currentPosition < 0.0) currentPosition += 360.0;
    }
    
    void moveToAngle(float targetAngle, float speed = 1.0) {
        Serial.print("حرکت به زاویه: ");
        Serial.print(targetAngle, 1);
        Serial.println(" درجه");
        
        // محاسبه کوتاه‌ترین مسیر
        float angleDiff = targetAngle - currentPosition;
        if (angleDiff > 180.0) angleDiff -= 360.0;
        if (angleDiff < -180.0) angleDiff += 360.0;
        
        int stepsNeeded = (angleDiff / 360.0) * stepsPerRevolution;
        int direction = (stepsNeeded > 0) ? 1 : -1;
        stepsNeeded = abs(stepsNeeded);
        
        Serial.print("نیاز به ");
        Serial.print(stepsNeeded);
        Serial.println(" استپ");
        
        // اجرای حرکت
        for (int i = 0; i < stepsNeeded; i++) {
            step(direction);
            
            // کنترل سرعت
            delay(1000 / (speed * 100)); // ms
        }
        
        Serial.println("✅ حرکت کامل شد");
    }
    
    void enable(bool state) {
        driver.enableAll(state);
        Serial.print("درایور استپر ");
        Serial.println(state ? "فعال شد" : "غیرفعال شد");
    }
    
    float getPosition() {
        return currentPosition;
    }
    
    int getStep() {
        return currentStep;
    }
    
    void home() {
        // حرکت به موقعیت Home
        Serial.println("جستجوی موقعیت Home...");
        
        // الگوریتم جستجوی Home (با سنسور انتهایی)
        moveToAngle(0.0);
        currentPosition = 0.0;
        
        Serial.println("📍 موقعیت Home یافت شد");
    }
};

۳. سیستم ارتباطی Multiplexed:

class MultiplexedCommunicationSystem {
private:
    QuadChannelOptocoupler muxOpto;
    int selectPins[2]; // پین‌های انتخاب کانال
    int dataPins[4];   // پین‌های داده
    int currentChannel;
    
public:
    MultiplexedCommunicationSystem(
        int optoCh1In, int optoCh1Out,
        int optoCh2In, int optoCh2Out,
        int optoCh3In, int optoCh3Out,
        int optoCh4In, int optoCh4Out,
        int sel0, int sel1
    ) : muxOpto(optoCh1In, optoCh1Out, optoCh2In, optoCh2Out, 
                optoCh3In, optoCh3Out, optoCh4In, optoCh4Out) {
        
        selectPins[0] = sel0;
        selectPins[1] = sel1;
        currentChannel = 0;
        
        pinMode(selectPins[0], OUTPUT);
        pinMode(selectPins[1], OUTPUT);
        
        // تنظیم داده‌پین‌ها
        for (int i = 0; i < 4; i++) {
            dataPins[i] = -1; // می‌تواند بعداً تنظیم شود
        }
        
        Serial.println("سیستم ارتباطی مالتی‌پلکس شده آماده است");
    }
    
    void selectChannel(int channel) {
        if (channel >= 0 && channel < 4) {
            currentChannel = channel;
            
            // تنظیم پین‌های انتخاب
            digitalWrite(selectPins[0], channel & 0x01);
            digitalWrite(selectPins[1], (channel >> 1) & 0x01);
            
            Serial.print("کانال انتخاب شد: ");
            Serial.println(channel + 1);
        }
    }
    
    void sendToChannel(int channel, bool data) {
        selectChannel(channel);
        muxOpto.setChannel(channel, data);
        
        Serial.print("ارسال به کانال ");
        Serial.print(channel + 1);
        Serial.print(": ");
        Serial.println(data ? "HIGH" : "LOW");
    }
    
    bool receiveFromChannel(int channel) {
        selectChannel(channel);
        bool data = muxOpto.getChannelOutput(channel);
        
        Serial.print("دریافت از کانال ");
        Serial.print(channel + 1);
        Serial.print(": ");
        Serial.println(data ? "HIGH" : "LOW");
        
        return data;
    }
    
    void broadcast(bool data) {
        Serial.print("پخش به همه کانال‌ها: ");
        Serial.println(data ? "HIGH" : "LOW");
        
        muxOpto.setGroup(data);
    }
    
    void scanChannels() {
        Serial.println("=== اسکن همه کانال‌ها ===");
        
        for (int i = 0; i < 4; i++) {
            bool state = receiveFromChannel(i);
            
            Serial.print("کانال ");
            Serial.print(i + 1);
            Serial.print(": ");
            Serial.println(state ? "ACTIVE" : "INACTIVE");
            
            delay(100);
        }
    }
    
    void sendDataPacket(int channel, const String& data) {
        selectChannel(channel);
        
        Serial.print("ارسال بسته به کانال ");
        Serial.print(channel + 1);
        Serial.print(": ");
        Serial.println(data);
        
        // ارسال Start bit
        muxOpto.setChannel(channel, LOW);
        delay(2);
        
        // ارسال داده (8 بیت)
        for (int i = 0; i < data.length(); i++) {
            char c = data.charAt(i);
            sendChar(c, channel);
        }
        
        // ارسال Stop bit
        muxOpto.setChannel(channel, HIGH);
        delay(2);
    }
    
    void sendChar(char c, int channel) {
        for (int bit = 0; bit < 8; bit++) {
            bool bitValue = (c >> bit) & 0x01;
            muxOpto.setChannel(channel, bitValue);
            delay(1); // زمان بیت
        }
    }
    
    String receiveDataPacket(int channel, int length) {
        selectChannel(channel);
        String data = "";
        
        // منتظر Start bit
        waitForStartBit(channel);
        
        // خواندن داده
        for (int i = 0; i < length; i++) {
            char c = receiveChar(channel);
            if (c == '\0') break;
            data += c;
        }
        
        return data;
    }
    
    char receiveChar(int channel) {
        char received = 0;
        
        // خواندن 8 بیت
        for (int bit = 0; bit < 8; bit++) {
            delay(1); // زمان بیت
            bool bitValue = muxOpto.getChannelOutput(channel);
            
            if (bitValue) {
                received |= (1 << bit);
            }
        }
        
        return received;
    }
    
    void waitForStartBit(int channel) {
        // منتظر LOW شدن (Start bit)
        int timeout = 1000; // 1 ثانیه
        int startTime = millis();
        
        while (muxOpto.getChannelOutput(channel) == HIGH) {
            if (millis() - startTime > timeout) {
                Serial.println("⏰ تایم‌اوت در انتظار Start bit");
                return;
            }
            delay(1);
        }
    }
};

🔧 پیکربندی‌های پیشرفته

پیکربندی ماتریسی 2×2:

class MatrixOptocouplerConfiguration {
private:
    QuadChannelOptocoupler opto;
    bool matrixMode;
    
public:
    MatrixOptocouplerConfiguration(QuadChannelOptocoupler& o) : opto(o) {
        matrixMode = false;
    }
    
    void enableMatrixMode(bool enable) {
        matrixMode = enable;
        
        if (matrixMode) {
            Serial.println("حالت ماتریسی فعال شد");
            Serial.println("کانال‌ها به صورت 2×2 پیکربندی می‌شوند");
        } else {
            Serial.println("حالت عادی فعال شد");
        }
    }
    
    void setMatrixRow(int row, bool state) {
        if (matrixMode && row >= 0 && row < 2) {
            // روشن کردن یک ردیف
            if (row == 0) {
                opto.setChannel(0, state);
                opto.setChannel(1, state);
            } else {
                opto.setChannel(2, state);
                opto.setChannel(3, state);
            }
        }
    }
    
    void setMatrixColumn(int col, bool state) {
        if (matrixMode && col >= 0 && col < 2) {
            // روشن کردن یک ستون
            if (col == 0) {
                opto.setChannel(0, state);
                opto.setChannel(2, state);
            } else {
                opto.setChannel(1, state);
                opto.setChannel(3, state);
            }
        }
    }
    
    bool getMatrixCell(int row, int col) {
        if (matrixMode && row >= 0 && row < 2 && col >= 0 && col < 2) {
            int channel = row * 2 + col;
            return opto.getChannelOutput(channel);
        }
        return false;
    }
    
    void scanMatrix() {
        if (!matrixMode) return;
        
        Serial.println("=== اسکن ماتریس 2×2 ===");
        
        for (int row = 0; row < 2; row++) {
            for (int col = 0; col < 2; col++) {
                bool state = getMatrixCell(row, col);
                
                Serial.print("سلول [");
                Serial.print(row);
                Serial.print(",");
                Serial.print(col);
                Serial.print("]: ");
                Serial.println(state ? "ON" : "OFF");
            }
        }
    }
    
    void matrixDemo() {
        enableMatrixMode(true);
        
        Serial.println("دموی ماتریس: دنباله روشن/خاموش");
        
        // دنباله اسکن
        for (int i = 0; i < 4; i++) {
            int row = i / 2;
            int col = i % 2;
            
            setMatrixRow(row, HIGH);
            setMatrixColumn(col, HIGH);
            
            delay(500);
            
            setMatrixRow(row, LOW);
            setMatrixColumn(col, LOW);
        }
    }
};

⚡ تست و کالیبراسیون صنعتی

روال کالیبراسیون چهار کاناله:

void quadChannelCalibration() {
    Serial.println("=== کالیبراسیون اپتوکوپلر چهار حالته ===");
    
    QuadChannelOptocoupler opto(2, 3, 4, 5, 6, 7, 8, 9);
    
    // 1. کالیبراسیون CTR تطبیقی
    Serial.println("1. کالیبراسیون CTR تطبیقی:");
    calibrateQuadCTR(opto);
    
    // 2. کالیبراسیون زمان پاسخ
    Serial.println("\n2. کالیبراسیون زمان پاسخ:");
    calibrateQuadResponseTimes(opto);
    
    // 3. کالیبراسیون تطابق کانال‌ها
    Serial.println("\n3. کالیبراسیون تطابق کانال‌ها:");
    calibrateQuadChannelMatching(opto);
    
    // 4. تست ایزولاسیون متقابل
    Serial.println("\n4. تست ایزولاسیون متقابل:");
    testQuadCrossIsolation(opto);
    
    // 5. تست بارگذاری کامل
    Serial.println("\n5. تست بارگذاری کامل:");
    testQuadLoading(opto);
    
    Serial.println("\n✅ کالیبراسیون کامل شد");
    generateCalibrationCertificate();
}

void calibrateQuadCTR(QuadChannelOptocoupler& opto) {
    Serial.println("اندازه‌گیری CTR در جریان‌های مختلف");
    
    float ctrMatrix[4][5]; // [کانال][جریان]
    float currents[5] = {5, 10, 15, 20, 25}; // mA
    
    for (int c = 0; c < 5; c++) {
        Serial.print("جریان: ");
        Serial.print(currents[c]);
        Serial.println("mA");
        
        for (int ch = 0; ch < 4; ch++) {
            // تنظیم جریان ورودی
            setInputCurrent(ch, currents[c]);
            delay(100);
            
            // اندازه‌گیری جریان خروجی
            float outputCurrent = measureOutputCurrent(ch);
            ctrMatrix[ch][c] = (outputCurrent / currents[c]) * 100.0;
            
            Serial.print("  کانال ");
            Serial.print(ch + 1);
            Serial.print(": CTR=");
            Serial.print(ctrMatrix[ch][c], 1);
            Serial.println("%");
        }
    }
    
    // تحلیل نتایج
    analyzeCTRResults(ctrMatrix, currents);
}

void testQuadCrossIsolation(QuadChannelOptocoupler& opto) {
    Serial.println("تست ایزولاسیون بین کانال‌ها");
    
    bool leakageDetected = false;
    
    // تست همه ترکیبات کانال‌ها
    for (int activeCh = 0; activeCh < 4; activeCh++) {
        opto.setChannel(activeCh, HIGH);
        delayMicroseconds(100);
        
        for (int testCh = 0; testCh < 4; testCh++) {
            if (testCh != activeCh) {
                bool state = opto.getChannelOutput(testCh);
                
                if (state) {
                    Serial.print("❌ نشتی از کانال ");
                    Serial.print(activeCh + 1);
                    Serial.print(" به کانال ");
                    Serial.println(testCh + 1);
                    leakageDetected = true;
                }
            }
        }
        
        opto.setChannel(activeCh, LOW);
        delayMicroseconds(100);
    }
    
    if (!leakageDetected) {
        Serial.println("✅ ایزولاسیون متقابل صحیح است");
    }
}

تست پایداری در شرایط محیطی:

class EnvironmentalStabilityTest {
private:
    QuadChannelOptocoupler& opto;
    float temperature;
    float humidity;
    
public:
    EnvironmentalStabilityTest(QuadChannelOptocoupler& o) : opto(o) {
        temperature = 25.0;
        humidity = 50.0;
    }
    
    void runTemperatureSweep(float start, float end, float step) {
        Serial.println("=== تست پایداری دمایی ===");
        
        for (float temp = start; temp <= end; temp += step) {
            setTestTemperature(temp);
            delay(5000); // تثبیت دما
            
            Serial.print("دما: ");
            Serial.print(temp, 1);
            Serial.println("°C");
            
            // تست عملکرد در این دما
            testAtTemperature(temp);
        }
    }
    
    void testAtTemperature(float temp) {
        float ctrValues[4];
        float responseTimes[4][2]; // Ton, Toff
        
        for (int ch = 0; ch < 4; ch++) {
            // اندازه‌گیری CTR
            ctrValues[ch] = measureCTRatTemperature(ch, temp);
            
            // اندازه‌گیری زمان پاسخ
            responseTimes[ch][0] = measureTon(ch);
            responseTimes[ch][1] = measureToff(ch);
            
            Serial.print("  کانال ");
            Serial.print(ch + 1);
            Serial.print(": CTR=");
            Serial.print(ctrValues[ch], 1);
            Serial.print("%, Ton=");
            Serial.print(responseTimes[ch][0]);
            Serial.print("µs, Toff=");
            Serial.print(responseTimes[ch][1]);
            Serial.println("µs");
        }
        
        // تحلیل تغییرات
        analyzeTemperatureEffects(ctrValues, responseTimes, temp);
    }
    
    void runHumidityTest(float startHumidity, float endHumidity, float step) {
        Serial.println("=== تست پایداری رطوبتی ===");
        
        for (float hum = startHumidity; hum <= endHumidity; hum += step) {
            setTestHumidity(hum);
            delay(10000); // تثبیت رطوبت
            
            Serial.print("رطوبت: ");
            Serial.print(hum, 0);
            Serial.println("%");
            
            // تست نشتی در رطوبت بالا
            testLeakageAtHumidity(hum);
        }
    }
    
    void testLeakageAtHumidity(float humidity) {
        // تست مقاومت عایقی در رطوبت مختلف
        float insulationResistance = measureInsulationResistance();
        
        Serial.print("  مقاومت عایقی: ");
        Serial.print(insulationResistance, 0);
        Serial.println(" Ω");
        
        if (insulationResistance < 1e9 && humidity > 80.0) {
            Serial.println("⚠️ کاهش مقاومت عایقی در رطوبت بالا");
        }
    }
};

🛡️ سیستم‌های حفاظتی پیشرفته

حفاظت چندلایه برای کاربردهای صنعتی:

class IndustrialProtectionSystem {
private:
    QuadChannelOptocoupler& opto;
    float currentLimits[4];
    float temperatureLimits[4];
    unsigned long faultTimers[4];
    bool channelProtection[4];
    
public:
    IndustrialProtectionSystem(QuadChannelOptocoupler& o) : opto(o) {
        for (int i = 0; i < 4; i++) {
            currentLimits[i] = 50.0; // mA
            temperatureLimits[i] = 85.0; // °C
            faultTimers[i] = 0;
            channelProtection[i] = true;
        }
    }
    
    bool safeChannelOperation(int channel, bool state, float measuredCurrent, float measuredTemp) {
        if (!channelProtection[channel]) {
            opto.setChannel(channel, state);
            return true;
        }
        
        // بررسی جریان
        if (measuredCurrent > currentLimits[channel]) {
            Serial.print("⚠️ جریان کانال ");
            Serial.print(channel + 1);
            Serial.print(" بیش از حد: ");
            Serial.print(measuredCurrent, 1);
            Serial.println("mA");
            
            if (millis() - faultTimers[channel] > 5000) {
                emergencyChannelShutdown(channel);
                return false;
            }
        }
        
        // بررسی دما
        if (measuredTemp > temperatureLimits[channel]) {
            Serial.print("⚠️ دمای کانال ");
            Serial.print(channel + 1);
            Serial.print(" بیش از حد: ");
            Serial.print(measuredTemp, 1);
            Serial.println("°C");
            
            thermalShutdown(channel);
            return false;
        }
        
        // اگر همه چیز OK باشد
        opto.setChannel(channel, state);
        faultTimers[channel] = 0;
        return true;
    }
    
    void emergencyChannelShutdown(int channel) {
        Serial.print("🚨 خاموشی اضطراری کانال ");
        Serial.println(channel + 1);
        
        opto.setChannel(channel, LOW);
        faultTimers[channel] = millis();
        channelProtection[channel] = false; // غیرفعال کردن موقت
        
        // لاگ خطا
        logFault(channel, "OVERCURRENT");
    }
    
    void thermalShutdown(int channel) {
        Serial.print("🔥 خاموشی حرارتی کانال ");
        Serial.println(channel + 1);
        
        opto.setChannel(channel, LOW);
        
        // فعال کردن خنک‌کننده
        activateCooling(channel);
        
        // لاگ خطا
        logFault(channel, "OVERTEMPERATURE");
    }
    
    void setCurrentLimit(int channel, float limitmA) {
        if (channel >= 0 && channel < 4) {
            currentLimits[channel] = limitmA;
            Serial.print("محدودیت جریان کانال ");
            Serial.print(channel + 1);
            Serial.print(" تنظیم شد: ");
            Serial.print(limitmA);
            Serial.println("mA");
        }
    }
    
    void setTemperatureLimit(int channel, float limitC) {
        if (channel >= 0 && channel < 4) {
            temperatureLimits[channel] = limitC;
        }
    }
    
    void enableChannelProtection(int channel, bool enable) {
        if (channel >= 0 && channel < 4) {
            channelProtection[channel] = enable;
        }
    }
    
    void runProtectionDiagnostics() {
        Serial.println("=== تست سیستم حفاظتی ===");
        
        for (int i = 0; i < 4; i++) {
            Serial.print("کانال ");
            Serial.print(i + 1);
            Serial.print(": حفاظت ");
            Serial.println(channelProtection[i] ? "فعال" : "غیرفعال");
            
            Serial.print("  محدودیت جریان: ");
            Serial.print(currentLimits[i]);
            Serial.println("mA");
            
            Serial.print("  محدودیت دما: ");
            Serial.print(temperatureLimits[i]);
            Serial.println("°C");
        }
    }
};

📦 ویژگی‌های ماژول آماده چهار حالته

مشخصات ماژول اپتوکوپلر چهار حالته:

  • ابعاد: 40mm × 30mm × 15mm

  • پایه‌ها: هدر 16 پین 2.54mm

  • اپتوکوپلر: TLP621-4 یا معادل چهار کاناله

  • مقاومت‌ها:

    • مقاومت‌های LED: 220Ω × 4

    • مقاومت‌های پایه: 10KΩ × 4

  • خازن فیلتر: 100nF × 4

  • ولتاژ کاری: 3.3V – 5V

  • جریان خروجی کل: تا 200mA

  • ایزولاسیون بین کانال‌ها: 1500Vrms

  • ایزولاسیون به زمین: 5000Vrms

  • دمای کاری: -40°C تا +100°C

پکیج صنعتی:

  • 1 عدد ماژول اپتوکوپلر چهار حالته

  • 16 عدد پایه هدر طلایی

  • 8 عدد مقاومت اضافی

  • 4 عدد خازن اضافی

  • راهنمای نصب صنعتی

  • دیاگرام‌های نمونه مدار پیشرفته

  • کتابخانه نرم‌افزاری کامل

  • گواهی کالیبراسیون

  • مستندات ایمنی

کاربردهای ویژه:

  • سیستم‌های کنترل صنعتی (PLC)

  • درایورهای موتور چند فاز

  • رابط‌های ارتباطی صنعتی

  • سیستم‌های پزشکی ایزوله

  • تجهیزات آزمایشگاهی

  • سیستم‌های امنیتی

  • کنترل‌کننده‌های دمایی

  • منبع تغذیه سوئیچینگ

🌟 نتیجه‌گیری

ماژول اپتوکوپلر چهار حالته یک راه‌حل صنعتی کامل برای ایزوله کردن همزمان چهار سیگنال است. با طراحی فشرده، عملکرد یکنواخت و قابلیت‌های پیشرفته، این ماژول نیازهای پیچیده سیستم‌های کنترل صنعتی، درایورهای موتور و رابط‌های ارتباطی را به طور کامل برآورده می‌کند.

ایزولاسیون چهارگانه، کنترل صنعتی کامل