Sabtu, 09 Oktober 2021

Rangkaian PLC, satu saklar ON dan OFF + LED kedip pada ARDUINO UNO, Konversi Rangkaian PLC ke ARDUINO

Baca Disclaimer sebelum membaca / menonton video.

Halo Rek! Kali Ruang Teknik akan share konversi rangkaian PLC untuk diimplementasikan ke dalam Arduino, seperti diketahui penggunaan PLC sangat membantu mengurangi cost biaya Relay/Kontaktor dalam sistem otomasi, sehingga sangat bermanfaat jika kita ingin membuat rangkaian listrik yang membutuhkan banyak Relay/Kontaktor.

Untuk video demo rangkaian bisa dicek disini



Ok, tanpa panjang kali lebar :) silahkan dicek rangkaian On dan Off + LED kedip dengan satu saklar.


Setelah dikonversi ke dalam bahasa pemrograman hasil seperti dibawah ini:

Berikut kodingannya

#include <stdint.h>

#include <stdlib.h>

#include <string.h>

#include <avr/io.h>

#include <avr/interrupt.h>

 

volatile uint8_t timerOF=0;

#define OVERSAMPLES 10

static volatile uint16_t adcData;

static volatile uint16_t ADCtotal;

static volatile uint8_t adcDataL;

static volatile uint8_t adcDataH;

static volatile uint8_t sample_count;

ISR(TIMER0_OVF_vect){timerOF=1;}

ISR(ADC_vect)

{

    adcDataL = ADCL;

    adcDataH = ADCH;

    adcData = 0;

    adcData = adcData | adcDataH;

    adcData = adcData << 8;

    adcData = adcData | adcDataL;

    ADCtotal = ADCtotal+adcData;

    sample_count ++;

}

int16_t do_math(int16_t A,int16_t B,char Operator)

{

    int32_t result = 0;

    if (Operator == '+'){result = A+B;}

    if (Operator == '-'){result = A-B;}

    if (Operator == '*'){result = A*B;}

    if (Operator == '/'){result = A/B;}

//    if (Operator == '='){result = A = B;}

    int16_t i =  ((result >> 0) & 0xffff);

   return i;

}

uint16_t read_adc(uint8_t channel)

{

    ADMUX = channel;// set channel

    ADMUX |=  (1<<REFS0);// sets ref volts to Vcc

    ADCSRA |= (1<<ADEN); // enable the ADC

    sample_count = 0; ADCtotal = 0;//clear sample count

    ADCSRA |= (1<<ADSC);//start conversion

    //read adcData done in interrupt

    while (sample_count < OVERSAMPLES){asm volatile ("nop"::);}//wait for completion

    ADCSRA &=~ (1<<ADEN); // stop the ADC

    return (ADCtotal/OVERSAMPLES); //mx osamples = 63  othewise will overflow total register with 10 bit adc results

}

int main()

{

//set up ADC

    ADCSRA |= ( (1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0) );//  sets adc clock prescaler to 128 //checked

    ADCSRA |= (1<<ADIE); // enable ADC conversion complete interrupt

    ADCSRA |= (1<<ADATE);// set to auto trigger (free running by default)

   DDRD |= (1<<5);

   DDRD |= (1<<6);

   DDRD |= (1<<7);

   DDRB |= (1<<0);

   DDRB |= (1<<3);

   DDRB |= (1<<4);

   DDRB |= (1<<5);

 

   PORTC |= (1<<4);

   PORTC |= (1<<5);

   PORTD |= (1<<2);

   PORTD |= (1<<3);

   PORTD |= (1<<4);

 

    //set up loop timer:

    TIMSK0 |= (1<<TOIE0);// overflow capture enable

    TCNT0 = 101;// start at this

    TCCR0B |= ((1<<CS10)|(1<<CS12));// timer started with /1024 prescaler

     sei();

    uint8_t cont_saklar_NO = 0;

    uint8_t output_R1 = 0;

    uint8_t branch_1_0 = 0;

    uint8_t cont_R1_NO = 0;

    uint8_t branch_2_0 = 0;

    uint8_t cont_R2_NO = 0;

    uint8_t branch_1_2 = 0;

    uint8_t cont_R1_NC = 1;

    uint8_t branch_2_2 = 0;

    uint8_t cont_R3_NC = 1;

    uint8_t output_R2 = 0;

    uint8_t branch_3_0 = 0;

    uint8_t cont_R3_NO = 0;

    uint8_t branch_4_0 = 0;

    uint8_t output_R3 = 0;

    uint8_t cont_R5_NC = 1;

    uint8_t cont_R4_NC = 1;

    uint8_t output_LED = 0;

 

    uint8_t Timer_T1 = 0;

    uint16_t setpoint_Timer_T1 = 50;

    uint16_t reg_Timer_T1 = 0;

 

    uint8_t prev_rungstate_Timer_T1 = 0;

    uint8_t rungstate_Timer_T1 = 0;

 

    uint8_t run_Timer_T1 = 0;

 

    uint8_t output_R4 = 0;

    uint8_t cont_R4_NO = 0;

 

    uint8_t Timer_T2 = 0;

    uint16_t setpoint_Timer_T2 = 50;

    uint16_t reg_Timer_T2 = 0;

 

    uint8_t prev_rungstate_Timer_T2 = 0;

    uint8_t rungstate_Timer_T2 = 0;

 

    uint8_t run_Timer_T2 = 0;

 

    uint8_t output_R5 = 0;

    uint8_t W = 1;

    while (1)

    {

        if (timerOF == 1)

        {

           timerOF=0;//reset timer flag

           TCNT0 = 101;// start at this

           //inputs:

           cont_saklar_NO =~ PINC &(1<<4);

             if(output_R1 == 1){

                cont_R1_NO=1;}

             else {

                cont_R1_NO=0;} //link name

             if(output_R2 == 1){

                cont_R2_NO=1;}

             else {

                cont_R2_NO=0;} //link name

             if(output_R1 == 0){

                cont_R1_NC=1;}

             else {

                cont_R1_NC=0;} //link name

             if(output_R3 == 0){

                cont_R3_NC=1;}

             else {

                cont_R3_NC=0;} //link name

             if(output_R1 == 1){

                cont_R1_NO=1;}

             else {

                cont_R1_NO=0;} //link name

             if(output_R3 == 1){

                cont_R3_NO=1;}

             else {

                cont_R3_NO=0;} //link name

             if(output_R1 == 0){

                cont_R1_NC=1;}

             else {

                cont_R1_NC=0;} //link name

             if(output_R2 == 1){

                cont_R2_NO=1;}

             else {

                cont_R2_NO=0;} //link name

             if(output_R2 == 1){

                cont_R2_NO=1;}

             else {

                cont_R2_NO=0;} //link name

             if(output_R5 == 0){

                cont_R5_NC=1;}

             else {

                cont_R5_NC=0;} //link name

             if(output_R2 == 1){

                cont_R2_NO=1;}

             else {

                cont_R2_NO=0;} //link name

             if(output_R5 == 0){

                cont_R5_NC=1;}

             else {

                cont_R5_NC=0;} //link name

             if(output_R4 == 0){

                cont_R4_NC=1;}

             else {

                cont_R4_NC=0;} //link name

             if(output_R2 == 1){

                cont_R2_NO=1;}

             else {

                cont_R2_NO=0;} //link name

             if(output_R5 == 0){

                cont_R5_NC=1;}

             else {

                cont_R5_NC=0;} //link name

             if(output_R4 == 1){

                cont_R4_NO=1;}

             else {

                cont_R4_NO=0;} //link name

             if(output_R4 == 1){

                cont_R4_NO=1;}

             else {

                cont_R4_NO=0;} //link name

 

            //Start of Ladder:

            //rung at 0

             W = 1;

             if(cont_saklar_NO == 0){W = 0;}

              output_R1 = W;

            //end rung

 

            //rung at 1

             W = 1;

             branch_1_0 = 1;

             if(cont_R1_NO == 0){branch_1_0 = 0;}

             branch_2_0 = 1;

             if(cont_R2_NO == 0){branch_2_0 = 0;}

             if( (branch_2_0 == 0) && (branch_1_0 == 0 )) {W = 0;} //node_[1, 0]

             if( (branch_2_0 == 2) || (branch_1_0 == 2 )) {W = 1;} //node_[1, 0] if is latching element

             branch_1_2 = 1;

             if(cont_R1_NC == 0){branch_1_2 = 0;}

             branch_2_2 = 1;

             if(cont_R3_NC == 0){branch_2_2 = 0;}

             if( (branch_2_2 == 0) && (branch_1_2 == 0 )) {W = 0;} //node_[1, 2]

             if( (branch_2_2 == 2) || (branch_1_2 == 2 )) {W = 1;} //node_[1, 2] if is latching element

              output_R2 = W;

            //end rung

 

            //rung at 3

             W = 1;

             branch_3_0 = 1;

             if(cont_R1_NO == 0){branch_3_0 = 0;}

             if(cont_R3_NO == 0){branch_3_0 = 0;}

             branch_4_0 = 1;

             if(cont_R1_NC == 0){branch_4_0 = 0;}

             if(cont_R2_NO == 0){branch_4_0 = 0;}

             if( (branch_4_0 == 0) && (branch_3_0 == 0 )) {W = 0;} //node_[3, 2]

             if( (branch_4_0 == 2) || (branch_3_0 == 2 )) {W = 1;} //node_[3, 2] if is latching element

              output_R3 = W;

            //end rung

 

            //StateUser

            //connected to rung at 5

             W = 1;

             if(cont_R2_NO == 0){W = 0;}

             if(cont_R5_NC == 0){W = 0;}

             rungstate_Timer_T1 = W;

             if((prev_rungstate_Timer_T1 == 0) && (rungstate_Timer_T1 == 1)){

                run_Timer_T1=1;}

             if(run_Timer_T1 == 1){

                reg_Timer_T1++;

                if (reg_Timer_T1 == 65535) {reg_Timer_T1--;}//avoid overrun

                if (setpoint_Timer_T1 <= reg_Timer_T1) {Timer_T1=1;}

             }

             if((prev_rungstate_Timer_T1 == 1) && (rungstate_Timer_T1 == 0)){

                reg_Timer_T1=0; Timer_T1=0; run_Timer_T1=0;} //reset

             prev_rungstate_Timer_T1 = rungstate_Timer_T1;

            //end rung

 

            //rung at 5

             W = 1;

             if(cont_R2_NO == 0){W = 0;}

             if(cont_R5_NC == 0){W = 0;}

             if(cont_R4_NC == 0){W = 0;}

              output_LED = W;

            //end rung

 

            //output brnch connected to rung at 5

             W = 1;

             if(cont_R2_NO == 0){W = 0;}

             if(cont_R5_NC == 0){W = 0;}

             if(Timer_T1 == 0){W = 0;}

              output_R4 = W;

            //end rung

 

            //StateUser

            //connected to rung at 7

             W = 1;

             if(cont_R4_NO == 0){W = 0;}

             rungstate_Timer_T2 = W;

             if((prev_rungstate_Timer_T2 == 0) && (rungstate_Timer_T2 == 1)){

                run_Timer_T2=1;}

             if(run_Timer_T2 == 1){

                reg_Timer_T2++;

                if (reg_Timer_T2 == 65535) {reg_Timer_T2--;}//avoid overrun

                if (setpoint_Timer_T2 <= reg_Timer_T2) {Timer_T2=1;}

             }

             if((prev_rungstate_Timer_T2 == 1) && (rungstate_Timer_T2 == 0)){

                reg_Timer_T2=0; Timer_T2=0; run_Timer_T2=0;} //reset

             prev_rungstate_Timer_T2 = rungstate_Timer_T2;

            //end rung

 

            //rung at 7

             W = 1;

             if(cont_R4_NO == 0){W = 0;}

             if(Timer_T2 == 0){W = 0;}

              output_R5 = W;

            //end rung

 

           //outputs:

         if(output_LED == 0){PORTD &=~ (1<<5);}

         else {PORTD |= (1<<5);}

 

       }

   }

}

copy paste seluruh coding dan paste ke dalam software Arduino IDE kosongan tanpa void setup dan void loop seperti dibawah ini:























Pastikan ikuti posisi Pin seperti pada gambar dibawah ini:







































Bagi yang tidak mau ribet silahkan download file codingnya dalam bentuk file .ino disini