0
\$\begingroup\$

I found this project which is about controlling the firing angle of SCR using Arduino and it works well.

https://simple-circuit.com/arduino-scr-half-wave-controlled-rectifier/

Then I modified the code to add an I2C LCD Display to the project.

LCD Wiring

But after modification of the code even though the LCD works well, now the firing angle of SCR stops working.

So I'm wondering where is the mistake in my code?

When I remove the last 6 lines (LCD Commands) from the code it works just fine!

#define scr_trig   8
#define pot       A0

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

bool ZC = 0;
uint16_t alpha;
LiquidCrystal_I2C lcd(0x27,  16, 2);

void setup(void) {
    pinMode(scr_trig, OUTPUT);
    digitalWrite(scr_trig, LOW);
    attachInterrupt(0, ZC_detect, FALLING);       // Enable external interrupt (INT0)
    lcd.init();
    lcd.backlight();
}
 
void ZC_detect() {
    ZC = 1;
}

void loop() {
    if (ZC) {
        delayMicroseconds(alpha);
        digitalWrite(scr_trig, HIGH);
        delay(1);
        digitalWrite(scr_trig, LOW);
        ZC = 0;
        alpha = analogRead(pot) * 10;
        if (alpha > 10000)
            alpha = 10000;
    }

    lcd.setCursor(0, 0);
    lcd.print("Firing angle is=");
    lcd.setCursor(0, 1);
    lcd.print((1023 - analogRead(pot)) / 5.7);
    lcd.setCursor(8, 1);
    lcd.print("degree");
}
\$\endgroup\$

1 Answer 1

5
\$\begingroup\$

The modified code improves upon the original by addressing timing issues caused by LCD updates. In the original code, the LCD update (lcd.print()) happens in every iteration of the loop(), which causes delays and interferes with the precise timing required for triggering the SCR. The firing angle is adjusted by the potentiometer and relies on a precise timing loop (delayMicroseconds(alpha)), but the delay caused by updating the LCD at every cycle disrupts this.

In the revised code, I introduced a timer mechanism to update the LCD less frequently. Using millis() ensures that the LCD is only updated every 200 ms, preventing it from blocking critical operations like SCR firing. This allows the program to maintain precise timing for triggering the SCR, while still providing updates to the user about the firing angle via the LCD. Additionally, I reduced the delay(1) inside the SCR triggering section to delayMicroseconds(10), minimizing any unnecessary delays and ensuring more responsive behavior.

These changes prevent the timing interference caused by LCD updates and optimize the program for both the SCR control and LCD functionality.

Revised Code: -

#define scr_trig   8
#define pot       A0
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

bool ZC = 0;
uint16_t alpha;
LiquidCrystal_I2C lcd(0x27, 16, 2);
unsigned long lastLCDUpdate = 0;  // Timer for LCD updates

void setup(void) {
  pinMode(scr_trig, OUTPUT);
  digitalWrite(scr_trig, LOW);
  attachInterrupt(0, ZC_detect, FALLING); // Enable external interrupt (INT0)
  lcd.init();
  lcd.backlight();
}

void ZC_detect() {
  ZC = 1;
}

void loop() {
  if (ZC) {
    delayMicroseconds(alpha); // Timing critical for SCR firing
    digitalWrite(scr_trig, HIGH);
    delayMicroseconds(10);    // Shortened to minimize blocking
    digitalWrite(scr_trig, LOW);
    ZC = 0;
    alpha = analogRead(pot) * 10; 
    if (alpha > 10000)
      alpha = 10000;
  }

  // Update LCD every 200 ms
  if (millis() - lastLCDUpdate > 200) {
    lastLCDUpdate = millis();
    lcd.setCursor(0, 0);
    lcd.print("Firing angle is=");
    lcd.setCursor(0, 1);
    lcd.print((1023 - analogRead(pot)) / 5.7); // Display in degrees
    lcd.setCursor(8, 1);
    lcd.print("degree ");
  }
}
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Please be aware that 5 times per second the SCR might not be triggered correctly or at all. A better solution will make the SCR control completely independent of the loop, for example by multiple interrupts. You need to consider interrupt priorities, too, to avoid jitter because of other interrupts. Doing real-time is hard. \$\endgroup\$ Commented Nov 21 at 8:24
  • \$\begingroup\$ Thank you, i tried the new code and it is much better now, however it still not very stable, sometimes the output jump to maximum or minimum, i'm wondering if using an LCD display without I2C (parallel) can help the timer to work better or not? \$\endgroup\$
    – M.A.K
    Commented Nov 21 at 8:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.