0

I have problem with communicating VB.Net-Arduino.

It seems the interrupt pause my serial communication line in void loop() { ... }. I don't know what to do, and I can't erase interrupts line since I got this code from another site and he said that the interrupt play important role in this code.

So, is there another method to keep interrupts like make a new void in the code? Could you help me, please?

here is the code:

//For MEGA 2560

int i = 0;
int j = 0;
int k = 0;

int x = 0;
int y = 0;
int z = 0;

int OK = 0;
int OK1 = 0;
int OK2 = 0;
int OK3 = 0;
int OK4 = 0;

int sinPWM[] = {
    0, 1, 2, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14, 16, 17, 18, 19, 21, 22,
    23, 24, 26, 27, 28, 29, 31, 32, 33, 34, 36, 37, 38, 39, 40, 42, 43,
    44, 45, 47, 48, 49, 50, 52, 53, 54, 55, 56, 58, 59, 60, 61, 62, 64,
    65, 66, 67, 68, 70, 71, 72, 73, 74, 76, 77, 78, 79, 80, 82, 83, 84,
    85, 86, 87, 89, 90, 91, 92, 93, 94, 96, 97, 98, 99, 100, 101, 102,
    104, 105, 106, 107, 108, 109, 110, 111, 112, 114, 115, 116, 117,
    118, 119, 120, 121, 122, 123, 125, 126, 127, 128, 129, 130, 131,
    132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144,
    145, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157,
    158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170,
    171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 179, 180, 181,
    182, 183, 184, 185, 185, 186, 187, 188, 189, 189, 190, 191, 192,
    193, 193, 194, 195, 196, 197, 197, 198, 199, 200, 200, 201, 202,
    203, 203, 204, 205, 205, 206, 207, 208, 208, 209, 210, 210, 211,
    212, 212, 213, 214, 214, 215, 215, 216, 217, 217, 218, 219, 219,
    220, 220, 221, 221, 222, 223, 223, 224, 224, 225, 225, 226, 226,
    227, 227, 228, 228, 229, 229, 230, 230, 231, 231, 232, 232, 233,
    233, 234, 234, 234, 235, 235, 236, 236, 237, 237, 237, 238, 238,
    238, 239, 239, 240, 240, 240, 241, 241, 241, 241, 242, 242, 242,
    243, 243, 243, 244, 244, 244, 244, 245, 245, 245, 245, 246, 246,
    246, 246, 246, 247, 247, 247, 247, 247, 247, 248, 248, 248, 248,
    248, 248, 248, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
    249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
    249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
    248, 248, 248, 248, 248, 248, 248, 247, 247, 247, 247, 247, 247,
    246, 246, 246, 246, 246, 245, 245, 245, 245, 244, 244, 244, 244,
    243, 243, 243, 242, 242, 242, 241, 241, 241, 241, 240, 240, 240,
    239, 239, 238, 238, 238, 237, 237, 237, 236, 236, 235, 235, 234,
    234, 234, 233, 233, 232, 232, 231, 231, 230, 230, 229, 229, 228,
    228, 227, 227, 226, 226, 225, 225, 224, 224, 223, 223, 222, 221,
    221, 220, 220, 219, 219, 218, 217, 217, 216, 215, 215, 214, 214,
    213, 212, 212, 211, 210, 210, 209, 208, 208, 207, 206, 205, 205,
    204, 203, 203, 202, 201, 200, 200, 199, 198, 197, 197, 196, 195,
    194, 193, 193, 192, 191, 190, 189, 189, 188, 187, 186, 185, 185,
    184, 183, 182, 181, 180, 179, 179, 178, 177, 176, 175, 174, 173,
    172, 171, 171, 170, 169, 168, 167, 166, 165, 164, 163, 162, 161,
    160, 159, 158, 157, 156, 155, 154, 153, 152, 152, 151, 150, 149,
    148, 147, 145, 144, 143, 142, 141, 140, 139, 138, 137, 136, 135,
    134, 133, 132, 131, 130, 129, 128, 127, 126, 125, 123, 122, 121,
    120, 119, 118, 117, 116, 115, 114, 112, 111, 110, 109, 108, 107,
    106, 105, 104, 102, 101, 100, 99, 98, 97, 96, 94, 93, 92, 91, 90,
    89, 87, 86, 85, 84, 83, 82, 80, 79, 78, 77, 76, 74, 73, 72, 71, 70,
    68, 67, 66, 65, 64, 62, 61, 60, 59, 58, 56, 55, 54, 53, 52, 50, 49,
    48, 47, 45, 44, 43, 42, 40, 39, 38, 37, 36, 34, 33, 32, 31, 29, 28,
    27, 26, 24, 23, 22, 21, 19, 18, 17, 16, 14, 13, 12, 11, 9, 8, 7, 6,
    4, 3, 2, 1, 0
};

#define toggle 7

int sw;
int nilaiVB;
int potvolt = A1;                //Pengatur Tegangan
int potfreq = A2;                //Pengatur Frequency

float potvoltval;
float potfreqval;
float DataVolt;
float DataFreq;
float A;
float F;

String inputString = "";         // a String to hold incoming data
boolean stringComplete = false;  // whether the string is complete
String In_1;
String In_2;

int Val1 = 0;
int Val2 = 0;

void setup() {
    Serial.begin(9600);
    inputString.reserve(200);

    pinMode(4, OUTPUT);
    pinMode(13, OUTPUT);
    pinMode(9, OUTPUT);
    pinMode(10, OUTPUT);
    pinMode(2, OUTPUT);
    pinMode(5, OUTPUT);

    cli();                            // stop interrupts
    TCCR0A = 0;                       //reset nilai
    TCCR0B = 0;                       //reset nilai
    TCNT0 = 0;                        //reset nilai
    //0b : menulis bits dalam binary
    TCCR0A = 0b10100001;              //phase correct pwm mode
    TCCR0B = 0b00000001;              //tidak ada prescaler

    TCCR2A = 0;                       //reset nilai
    TCCR2B = 0;                       //reset nilai
    TCNT2 = 0;                        //reset nilai
    //0b : menulis bits dalam binary
    TCCR2A = 0b10100001;              //phase correct pwm mode
    TCCR2B = 0b00000001;              //tidak ada prescaler

    TCCR3A = 0;                       //reset nilai
    TCCR3B = 0;                       //reset nilai
    TCNT3 = 0;                        //reset nilai
    //0b  : menulis bits dalam binary
    TCCR3A = 0b10100001;              //phase correct pwm mode
    TCCR3B = 0b00000001;              //tidak ada prescaler

    TCCR1A = 0;                       //reset nilai
    TCCR1B = 0;                       //reset nilai
    TCNT1 = 0;                        //reset nilai
    OCR1A = 509;                      // compare match value
    TCCR1B = 0b00001001;  //WGM12 bit is 1 for CTC mode and no prescaler

    TIMSK1 |= (1 << OCIE1A);          // memulai interrupts

    sei();                            // enable interrupts
}

// interrupt mulai ketika timer 1 cocok dengan OCR1A
ISR(TIMER1_COMPA_vect) {

    //=========================Phase A================================//

    if (i > 629 && OK == 0) {   // nilai akhir dari sample untuk pin 13
        i = 0;                  // mulai dari nilai awal sample
        OK = 1;                 // mengaktifkan pin 4
    }

    if (i > 629 && OK == 1) {   // nilai akhir dari sample untuk pin 4
        i = 0;                  // mulai dari nilai awal sample
        OK = 0;                 // mengaktifkan pin 13
    }

    x = round(A*sinPWM[i]); // nilai x berasal dari sample dan i berindex 0
    i = i+F;                    // ke posisi selanjutnya dari sample
    if (OK == 0) {
        OCR0B = 0;                      //pin 4 0
        OCR0A = x; //pin 13 memulai pembacaan sample
    }

    if (OK == 1) {
        OCR0A = 0;                      //pin 13 0
        OCR0B = x; //pin 4 memulai pembacaan sample
    }

    // jika nilai i mencapai 209, maka phase kedua akan dimulai
    if ((i >= 418) || OK1 == 1) {
        OK1 = 1;                  //mempertahankan if function

        //=========================Phase B============================//

        if (j > 629 && OK2 == 0) {  // nilai akhir dari sample untuk pin 10
            j = 0;                  // mulai dari nilai awal sample
            OK2 = 1;                // mengaktifkan pin 9
        }

        if (j > 629 && OK2 == 1) {  // nilai akhir dari sample untuk pin 9
            j = 0;                  //mulai dari nilai awal sample
            OK2 = 0;                // mengaktifkan pin 10
        }

        y = round(A*sinPWM[j]); // nilai y berasal dari sample dan i berindex 0
        j = j+F;                    // ke posisi selanjutnya dari sample
        if (OK2 == 0) {
            OCR2B = 0;              // pin 9 0
            OCR2A = y;              // pin 10 memulai pembacaan sample
        }

        if (OK2 == 1) {
            OCR2A = 0;              // pin 10 0
            OCR2B = y;              // pin 9 memulai pembacaan sample
        }
    }

    // jika nilai j mencapai 209, maka phase ketiga akan dimulai
    if ((j>= 418) || OK3 == 1) {
        OK3 = 1;                    // mempertahankan if function

        //=========================Phase C============================//

        if (k > 629 && OK4 == 0) {  // nilai akhir dari sample untuk pin 5
            k = 0;                  // mulai dari nilai awal sample
            OK4 = 1;                // mengaktifkan pin 2
        }

        if (k > 629 && OK4 == 1) {  // nilai akhir dari sample untuk pin 2
            k = 0;                  // mulai dari nilai awal sample
            OK4 = 0;                // mengaktifkan pin 5
        }

        z = round(A*sinPWM[k]); // nilai z berasal dari sample dan i berindex 0
        k = k+F;                    // ke posisi selanjutnya dari sample
        if (OK4 == 0) {
            OCR3B = 0;              // pin 2 0
            OCR3A = z;              // pin 5 memulai pembacaan sample
        }

        if (OK4 == 1) {
            OCR3A = 0;              // pin 5 0
            OCR3B = z;              // pin 2 memulai pembacaan sample
        }
    }
}

void loop() {
    sw = digitalRead(toggle);

    if (sw == 0) { //    VB
        if (stringComplete) {
            if (inputString.substring(0, 4) == "VOLT") {
                In_1 = inputString.substring(4);
                Val1 = In_1.toInt();
                A = Val1/1023; // Formula Pengontrolan Tegangan
                Serial.println(Val1);
            }
            if (inputString.substring(0, 4) == "FREQ") {
                In_2 = inputString.substring(4);
                Val2 = In_2.toInt();
                F = map(Val2, 1023, 0, 0, 50);// Formula Pengontrolan Frequensi
            }

            inputString = "";
            stringComplete = false;
        }
    }
    else if (sw == 1) { // Potensiometer
        potvoltval = analogRead(potvolt);
        A = potvoltval/1023; // Formula Pengontrolan Tegangan

        potfreqval = analogRead(potfreq);
        F = map(potfreqval, 1023, 0, 0, 50);// Formula Pengontrolan Frequensi
    }
}

void serialEvent() {
    while (Serial.available()) {
        // get the new byte:
        char inChar = (char) Serial.read();
        // add it to the inputString:
        inputString += inChar;
        // if the incoming character is a newline, set a flag so the
        // main loop can do something about it:
        if (inChar == '\n') {
            stringComplete = true;
        }
    }
}

And here are the interrupts position: Interrupts

And i got the code from this site

And Here is my VB code

Public Class Form1

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Try
        Me.CenterToParent()
        SerialPort1.PortName = "COM4"
        SerialPort1.BaudRate = 9600
        SerialPort1.Open()
        Timer1.Start()
        SerialPort1.Write("VOLT" & TrackBar1.Value & Chr(10))
        SerialPort1.Write("FREQ" & TrackBar2.Value & Chr(10))
    Catch ex As Exception
        MsgBox(ex.Message, MessageBoxIcon.Error, "Error Message")
        Me.Close()
    End Try
End Sub

Private Sub Form1_Closed(sender As Object, e As EventArgs) Handles Me.Closed
    SerialPort1.Close()
End Sub

Private Sub TrackBar1_Scroll(sender As Object, e As EventArgs) Handles TrackBar1.Scroll
    Try
        SerialPort1.Write("VOLT" & TrackBar1.Value & Chr(10))
    Catch ex As Exception
        MsgBox(ex.Message, MessageBoxIcon.Error, "Error Message")
    End Try
End Sub

Private Sub TrackBar2_Scroll(sender As Object, e As EventArgs) Handles TrackBar2.Scroll
    Try
        SerialPort1.Write("FREQ" & TrackBar2.Value & Chr(10))
    Catch ex As Exception
        MsgBox(ex.Message, MessageBoxIcon.Error, "Error Message")
    End Try
End Sub
End Class

And the design as wellDesign

  • 3
    You misdiagnosed the problem. These cli() and sei() calls are harmless. Please, explain what your real problem is. – Edgar Bonet Jun 24 at 7:51
  • 2
    cli() and sei() are only used in setup, they are not the problem. Maybe your Timer ISR is taking too long. You can make it shorter, doing more things in loop. But please describe further, what undesireable behavior you see with this code. – chrisl Jun 24 at 10:13
  • 3
    the interrupt is executed every 509 clock ticks (no prescaler) and the handler is long. there is no time for anything else – Juraj Jun 24 at 11:07
  • The developers said To be sure there is no problem with interrupts we will use cli() ( stop interrupts) and sei()(enable interrupts). .please make sure how to timer interrupts works! How to PWM works! Try to interrupts simple LED or something to diagnosed your problem. – abu-ahmed al-khatiri Jun 24 at 12:06
  • What do you want your program to do in general. What are you trying to achieve? Then tell us what problems you are seeing? What is it doing wrong? – sa_leinad Jun 24 at 12:25
0

Since the ISR being too long seems to be your main problem, I will address the possibility to set a flag in the ISR. See this code example (which is not a complete compilable example, only code to show the principle):

volatile byte flag = 0;

ISR(TIMER1_COMPA_vect) {
    flag = 1;
}

void loop(){
    if(flag){
        flag = 0; // resetting the flag for the next execution
        //execute the code here, that was previously in the ISR
    }
}

First a flag variable is declared as volatile. This tells the compiler, that the value of this variable can change at any time and that the compiler cannot optimize it by using a cached value or other optimizations. This is always required, when you access a variable both in ISR's and the normal code.

In the actual ISR this flag is simply set to 1. This takes very short time, so that no other interrupt (for example for Serial) will be blocked by it.

Then in our void loop() we are checking if the flag has a value, that isn't zero (every value other than zero will evaluate as true, so we don't need a comparison operator here). If yes, we first reset the flag to zero, so that another interrupt can set it again to 1. Then we are executing the other code, that was previously in your ISR. Since it now runs in normal code, it will not block Serial interrupts from happening.


"The ISR is too long" can also mean, that it is happening too often. Juraj already stated in his comment, that the interrupt happens "every 509 clock ticks". That is not very much. You can increase the time between 2 consecutive timer interrupts by using a prescaler. As doing just this would reduce the frequency of your output sinus wave, you would need to do some calculations, maybe only using every forth or so array element of the sinus wave. With this you are loosing precision in time, but you gain more computation time to do other things.


In general you always have to do a trade-of. The longer the code runs, that should be executed on a timer interrupt, the less precision will be possible with it. The code should always run considerable shorter, that the time between two consecutive interrupts.

Your code is not really understandable, since you didn't use speaking variable names and your comments are not written in english. From the structure I would guess, that it can be strongly optimized by you to execute shorter, but without understanding what the code really should do, that is only wild guessing.

  • Thanks for your answer. I'll definitely try this. – Fitrah Hidayat Jul 2 at 2:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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