text:
Interrupts arduino interrupting serial comunication
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:

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 well

You misdiagnosed the problem. These cli() and sei() calls are harmless. Please, explain what your real problem is.

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.

the interrupt is executed every 509 clock ticks (no prescaler) and the handler is long. there is no time for anything else

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.

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?

@EdgarBonet.. I am working on VFD Inverter controlled by VB.Net. So, the output voltage and the frequency can be controlled with VB.Net. Now, the problem is i can't control the output, and i assume something is wrong with my interrupt. Nut the people here told me ISR is too long, i think that's also right. Now i don't know what todo with making the ISR shorter.

@chrisl.. When i ask someone else, he also mentioned the ISR is too long. Do you have any advice to make the ISR shorter? About the undesireable behavior, when i start VB.Net and scroll Voltage Trackbar, nothing happens to my project output. I expect the output Voltage can be vary through trackbar in VB.Net. But, when i use potensiometer, it works.

@Juraj.. Could you tell me what i supposed to do then, please?

@sa_leinad.. As you can see in my comments, i intend to control voltage and frequency through VB.Net. The problem is, i can't send any data from VB to arduino. I don't really know what's wrong. But i assume it's related with interrupt or ISR. Do you have any advice about the code?

How do yo know the value of OCR1A = 509 and you give i > 629? But based your link with OCR1A = 509 and   value of variable i < 313 instead. For the example where timer0 is for interrupt i have used the same formula OCR1A=(fclk/fOC1A*N)-1, where instead of OCR1A appear OCR0A.

To see if it is related to interrupts you could wrap the while (Serial.available()) loop in serialEvent() in a ATOMIC_BLOCK section. To shorten the ISR simply set a flag and then in the loop(): if(flag) // call the ISR as a function and clear the flag. Something else: variables used in an ISR and your program (like F) must be declared volatile'. You have to filter the analog output in hardware as analogWrite()` does not create an analog voltage but a pwm instead.

@abu-ahmedal-khatiri, 629 is the end variable of vector table, since the author said the table only generate 50Hz, i doubled it. In my logic, if 50Hz consist 314 variable, i thought for 100Hz needs 629 variable.. (why 629? Because i give extra 0 variable, just to make sure the mosfets is ok)

@SimSon.. Thanks for your advice. And, could you tell me simple code about how to set a flag? I can't find any example about it.

@SimSon.. i found something about flag in this link. But i am not sure how to put it in my code. Could you tell mw what to do first??

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.


text:
Controlling output frequency of 3 Phase SPWM Inverter
I am now on a 3 Phase SPWM inverter project, and i got this code from this article. It works perfectly on simulation. But the problem is, i can't make the output frequency variable. I intend to vary the frequency at range 0 to 100 Hz and use it to control the speed of 3 phase induction motor. Could anyone help me, please? Any advice or maybe you got a code that works perfectly in controlling spwm inverter frequency. Here is the code of 3 phase spwm inverter. Oh, i am using Arduino Mega by the way.
            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[]={1,2,5,7,10,12,15,17,19,22,24,27,30,32,34,37,39,42,
            44,47,49,52,54,57,59,61,64,66,69,71,73,76,78,80,83,85,88,90,92,94,97,99,
            101,103,106,108,110,113,115,117,119,121,124,126,128,130,132,134,136,138,140,142,144,146,
            148,150,152,154,156,158,160,162,164,166,168,169,171,173,175,177,178,180,182,184,185,187,188,190,192,193,
            195,196,198,199,201,202,204,205,207,208,209,211,212,213,215,216,217,219,220,221,222,223,224,225,226,227,
            228,229,230,231,232,233,234,235,236,237,237,238,239,240,240,241,242,242,243,243,244,244,245,245,246,246,
            247,247,247,248,248,248,248,249,249,249,249,249,255,255,255,255,249,249,249,249,249,248,
            248,248,248,247,247,247,246,246,245,245,244,244,243,243,242,242,241,240,240,239,238,237,237,236,235,234,
            233,232,231,230,229,228,227,226,225,224,223,222,221,220,219,217,216,215,213,212,211,209,208,207,205,204,
            202,201,199,198,196,195,193,192,190,188,187,185,184,182,180,178,177,175,173,171,169,168,166,164,162,160,
            158,156,154,152,150,148,146,144,142,140,138,136,134,132,130,128,126,124,121,119,117,115,113,110,108,106,
            103,101,99,97,94,92,90,88,85,83,80,78,76,73,71,69,66,64,61,59,57,54,52,49,47,44,42,39,37,34,32,30,
            27,24,22,19,17,15,12,10,7,5,2,1};

            int potinput = A1;
            int potfreq = A2;
            float potinputval;
            float potfreqval;
            float A;
            float F;

            void setup() {
            Serial.begin(9600);

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

            cli();// stop interrupts
            TCCR0A=0;//reset the value
            TCCR0B=0;//reset the value
            TCNT0=0;//reset the value
            //0b allow me to write bits in binary
            TCCR0A=0b10100001;//phase correct pwm mode
            TCCR0B=0b00000001; //no prescaler

            TCCR2A=0;//reset the value
            TCCR2B=0;//reset the value
            TCNT2=0;//reset the value
            //0b allow me to write bits in binary
            TCCR2A=0b10100001;//phase correct pwm mode
            TCCR2B=0b00000001; //no prescaler

            TCCR3A=0;//reset the value
            TCCR3B=0;//reset the value
            TCNT3=0;//reset the value
            //0b allow me to write bits in binary
            TCCR3A=0b10100001;//phase correct pwm mode
            TCCR3B=0b00000001; //no prescaler
            TCCR1A=0;//reset the value
            TCCR1B=0;//reset the value
            TCNT1=0;//reset the value
            OCR1A=509;// compare match value
            TCCR1B=0b00001001; //WGM12 bit is 1 for CTC mode and no prescaler

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

            sei();//stop interrupts
            }
            ISR(TIMER1_COMPA_vect){// interrupt when timer 1 match with OCR1A value
            if(i>313 && OK==0){// final value from vector for pin 13
            i=0;// go to first value of vector
            OK=1;//enable pin 4
            }
            if(i>313 && OK==1){// final value from vector for pin 4
            i=0;//go to firs value of vector
            OK=0;//enable pin 13
            }
            x = round(A*sinPWM[i]); // x take the value from vector corresponding to position i(i is zero indexed)
            i=i+1;// go to the next position
            if(OK==0){
            OCR0B=0;//make pin 4 0
            OCR0A=x;//enable pin 13 to corresponding duty cycle
            }
            if(OK==1){
            OCR0A=0;//make pin 13 0
            OCR0B=x;//enable pin 4 to corresponding duty cycle
            }

            if ((i==209) || OK1==1){//if i equal with 209 enable second signal
            OK1=1;//mantain if function
            if(j>313 && OK2==0){// final value from vector for pin 10
            j=0;// go to first value of vector
            OK2=1;//enable pin 9
            }
            if(j>313 && OK2==1){// final value from vector for pin 9
            j=0;//go to firs value of vector
            OK2=0;//enable pin 10
            }
            y = round(A*sinPWM[j]);// y take the value from vector corresponding to position j(j is zero indexed)
            j=j+1;// go to the next position
            if(OK2==0){
            OCR2B=0;//make pin 9 0
            OCR2A=y;//enable pin 10 to corresponding duty cycle
            }
            if(OK2==1){
            OCR2A=0;//make pin 10 0
            OCR2B=y;//enable pin 9 to corresponding duty cycle
            }
            }
            if ((j==209) || OK3==1){//if j equal with 209 enable third signal
            OK3=1;//mantain if function
            if(k>313 && OK4==0){// final value from vector for pin 5
            k=0;// go to first value of vector
            OK4=1;//enable pin 2
            }
            if(k>313 && OK4==1){// final value from vector for pin 2
            k=0;//go to firs value of vector
            OK4=0;//enable pin 5
            }
            z=round(A*sinPWM[k]);// z take the value from vector corresponding to position k(k is zero indexed)
            k=k+1;// go to the next position
            if(OK4==0){
            OCR3B=0;//make pin 2 0
            OCR3A=z;//enable pin 5 to corresponding duty cycle
            }
            if(OK4==1){
            OCR3A=0;//make pin 5 0
            OCR3B=z;//enable pin 2 to corresponding duty cycle
        }
        }
        }
        void loop() {

          potinputval = analogRead(potinput);
          A = potinputval/1023;

          potfreqval = analogRead(potfreq);
          F = map(potfreqval,1023,0,0,50);}

In this sketch the PWM values, matching a sampled sine curve, are stored in integer array sinPWM[]. The values from sinPWM (1 - 255) are used unmodified (via intermediate variables x, y and z) to set the various timing registers (OCR0A/B, OCR2A/B and OCR3A/B) which control the pulse width modulation. In this way the amplitude(s) of the generated sine wave(s) will be constant.
If you want to control the speed of the motor you have to multiply the values from sinPWM with a factor between 0 and 1. The most logical place is to do that when the values from sinPWM are transferred to the intermediate variables x, y and z. Example: x=round(0.8 * sinPWM[i]). The factor, 0.8 in this example, you can of course replace by a variable which value is derived from an analogRead() of a pin connected to a potmeter or some sensor. But make sure to convert it to a value in the range 0-1 before you use it in the calculation.

Ok.. I will try it. But could you tell me why I should multiply the value with  a factor between 0 and 1, please?

You feed the motor with three sine waves with a mutual phase difference of 120 degrees. The amplitude of the sine wave (= half of the top-top value) determines the speed of the motor. I say this with some reservation because there are many different types of electro motor. I assume you use a three phase motor with a squirrel-cage rotor.

Thanks for your reply. So i've tried the formula you've mentioned above without potmeter first ( i multiplied the sinPWM with value between 0-1), and it takes effect on duty cycle values. But when i connect the potmeter and improve the code, it didn't work. I think something's wrong with my analog converting formula.  Would you mind to take a look to my code above, please?

I will try. But could you first tell me the details about the motor you are using (do you have a datasheet, or manufacturer plus part number)?

I only have these 2 pictures. Please take a look.
Image1
Image2

Thanks for the pictures. What circuit do you have between the Arduino and the motor?

I have 6 gate drivers with 13-14 volt output ( i made my own gate driver with hcpl-3120 IC). Then i have a MOSFET bridge with 6 x Irfp460 MOSFETs. I haven't had a filter yet, because i'm thinking to control the SPWM first. And, it's hard to find references about 3 phase low pass filter.

Thanks for the information. Indeed you made a mistake with the code for processing the potmeter value. First, you don't have to set the pinMode for this pin (this has no further influance). Second the variable A should be a float (not an int, because an int can't hold fractions). To be sure to avoid integer division and to avoid A having an invalid intermediary value (interruption can happen at any point in the calculation) also make a float of potinputval and do the calculation as follows: potinputval = analogRead(potinput); potinputval = potinputval / 1023; A = potinputval;

But my (original) answer is not correct. I was under the impression that you were using a small motor (e.g. a toy motor) in an analog way connected to the Arduino.

I am not a motor expert. But from the plate on the motor it looks like an 3 phase AC asynchronous motor with squirrel cage rotor. If this is correct the motor should have 6 electrical connection points, some of them connected to one of the others (with a metal 'bridge'). The motor can be electrically connected in star or delta configuration (Google on these terms if this is new for you).

The rotation speed of these motors depends on the frequency of the (electrical) phases. So, if you want to change the speed of the motor, you have to change the frequency of the generated sine waves. Most probably this involves other settings for the various timers. It would take me too much time to figure out how to do this. Maybe somebody else from Stack Overlow can help or maybe the guy running the site were you got your co

But when i search for 3 phase induction motor controlling method. I found that vary the supply voltage will effect the motor speed. I think that could be work. And do you know how to invert an array or how to invert pwm? The code above provide 6 spwm output. If i put 2 output together, one of them should be inverted. So i need 3 normal output and 3 inverted output. Do you know how to do that?

I am pretty sure that you can't control the speed of this motor by varying the supply voltage. But you can try that out in a simple way: the supply voltage for the motor is applied via your motor driver (H-bridge), so it is relatively easy to vary it. The article you refer to in the 1st line of your question describes how to generate the positive and the 'negative' halves of the three fases. As the Arduino can't generate negative signals also the 'negative' halves of the fases are positive. Inversion has to be done by a separate circuit (which might be integrated in the motor driver circuit).

Hi PimV, you were right, i have to vary the frequency output of the inverter. The thing is, i haven't find any method to control it. Could you help me once again? Or could you give me some advices or something, please? Thanks in advance.

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Unlocking Digispark ATTiny85 after flashing it to HID
I made a simple test sketch to make my ATTiny85 emulate a Keyboard and send a sequence of keystrokes.
#include "DigiKeyboard.h"
void setup() {
  // don't need to set anything up to use DigiKeyboard
}

void loop() {
  DigiKeyboard.delay(1000);
  DigiKeyboard.sendKeyStroke(0);
  DigiKeyboard.sendKeyStroke(106); // F15
  DigiKeyboard.delay(59 * 1000);
}

It worked fine, but now every time I plug it to the USB port on my computer, Windows detects it as a Keyboard and starts typing what I programmed it to type.
Arduino IDE can't reprogram it. When it says "Plug in device now", I do it, but it immediately acts like a Keyboard, not like a programmable ATTiny85.

Note: Image shows the console output. Code is just a simple blinker.
Is there any way to save this board? I just want to upload another sketch to it. Maybe some way to rewrite the bootloader or to erase the flash memory entirely.
Also, please give me some advice so I can avoid being locked out again in the future. I really want to use this board as a Keyboard emulator, but I want to be able to reprogram it if necessary.

Please don't post images of code.  Just copy and post your code into the editor, and then format it as a code sample.

@sempaiscuba the code is not the important part of the image... The console output is.

add the console output as text, not a picture

use a switch or a jumper to enable the keyboard code

You have nothing connected to the board at all except the computer?

This board is a tricky one, because the bootloader cannot be protected. -- As you describe it, you do everything correctly. After starting the upload, the board needs to be connected, so that its software starts. Commonly you disconnect the board before starting the upload. If the bootloader is present, it waits for 5 seconds for the uploader of the PC, before it launches the user application. -- Anyway, if the uploader does not connect to your board, the bootloader might be overwritten. -- Did you try to remove the device in the Hardware Manager? Windows might get into the way.

@timemage, yes, that's correct. Nothing is connected to the board, except the computer on the USB connection.

@thebusybee, Yes, I tried to remove the device in the Hardware Manager, but when I reconnect it, it shows up again. I also tried to replace the driver using Zadig (to libusb-win32) and now Windows doesn't detect it as a keyboard as before... but I still can't write a new sketch to it.

Well, then I'll assume that you lost the bootloader. There are multiple resources in the web that describe how to flash the bootloader. You should prefer the instructions of the manufacturer or similar serious site. Or buy a new device.

Yeah, I could just buy a new one, upload a new sketch and being locked outside again, the same way I am now... That's not sustainable, It should not be impossible to upload a new program multiple times. That's what this question is about: How to fix this specific board and how to prevent from being locked out again.

If you can't access the bootloader using USB your remaining option is ISP/ICSP (In-Circuit Serial Programming). I have that digispark board and I have never been able to program it using Arduino's IDE/USB. However, since then I always use both an USBasp programmer and the AVRDUDESS programming tool. With them you can eassily program the controller (they have never failed me). Connect the SPI, +5V, GND and RESET connectors from the ATTINY85 to the programmer, compile the code, program the binaries with AVRDUDESS and voila.

Hello. Could you please add more details to this answer? What is USBasp? AVRDUDESS? Which "programmer" are you talking about? Is it a separated device?

I added some details to my response. Yes, USBasp is a separate device, a programmer typically implemented with an Atmel AVR controller. You can easily buy them from Ebay or someplace else. AVRDUDESS is a GUI tool to help you flash the compiled binary into the target controller, i.e., the attiny85 in this case.

You can learn a lot from Have I bricked my Arduino Uno? Problems with uploading to board

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Using Pro Micro without soldering pin
I'm a total newbie. I bought a Pro Micro but I didn't know that it can't be used, if you don't solder things in his holes.
I found this picture on Google:
And it seems that exists those stuffs (green and white) to test the circuit before soldering.
Do you know where can I buy them? Or do you know their name?
Thanks.

As alternative I am looking for screws that would fit the pins but i've still haven't found any.

Perhaps you are looking for items like these from from a well established seller adafruit.com.  However, what you are proposing is not cheap when compared to soldering.  I would recommend you learn soldering as it will likely be the way you want to assemble your final Arduino project.

It's exactly what I looking for! Yes, sooner or later I'll learn how to solder. Thanks!

If you're just getting started and are not comfortable with soldering I would suggest getting one of the larger boards that has headers on it. (An Uno or a Mega, for example). You can use one of those and a breadboard to experiment without having to solder at all.
MicroCenter (A US retailer) sells 100% compatible Arduino Mega 2560 knockoffs for $10 US.
I suggest using a board like that when you are first starting out. (And learn how to solder. It's very useful for electronics repair and various other things.)

I need a Pro Micro because I need its ability to emulate an HID USB device.


text:
Arduino NANO hardware SPI not working
I have an Arduino NANO clone and a 2.4" ILI9341 TFT display.  The VCC and LCD pins of the display are connected to the 5V pin of the board.  The GND to the GND.  All the logic pins are connected to voltage dividers (2k2 and 4k3 resistors), their connections checked and delivering 3.3V when 5V is supplied to them.
If I understand the source correctly, if I specify all the pins to the constructor, then I use software SPI, but if I don't, then I use hardware SPI.
Now, if I use the software SPI, everything is working fine, I can get the info, I can draw, etc.  However if I use the hardware SPI then it is not giving me anything.
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>

// Adafruit_ILI9341 tft = Adafruit_ILI9341(10, 9);              // NOT WORKING!
Adafruit_ILI9341 tft = Adafruit_ILI9341(10, 9, 11, 13, 8, 12);  // WORKING!

void
setup()
{
    Serial.begin(9600);
    while (!Serial);

    Serial.println("ILI9341 Test!");

    tft.begin();

    // read diagnostics (optional but can help debug problems)
    uint8_t x = tft.readcommand8(ILI9341_RDMODE);
    Serial.print("Display Power Mode: 0x"); Serial.println(x, HEX);
    x = tft.readcommand8(ILI9341_RDMADCTL);
    Serial.print("MADCTL Mode: 0x"); Serial.println(x, HEX);
    x = tft.readcommand8(ILI9341_RDPIXFMT);
    Serial.print("Pixel Format: 0x"); Serial.println(x, HEX);
    x = tft.readcommand8(ILI9341_RDIMGFMT);
    Serial.print("Image Format: 0x"); Serial.println(x, HEX);
    x = tft.readcommand8(ILI9341_RDSELFDIAG);
    Serial.print("Self Diagnostic: 0x"); Serial.println(x, HEX);
}

void
loop()
{
    // pass
}

However, what really makes me totally confused is when I use the SD card reader with the SD Library alone (the SD card reader is on the ILI9341 board), then that is working fine as well (as if the hardware SPI would be working, unless the SD Library is switching to software SPI magically).  Anyway, the following is the working code:
#include <SD.h>
#include <SPI.h>

void
setup()
{
    Serial.begin(9600);
    while (!Serial);

    Serial.println("ILI9341 Test!");

    if (!SD.begin(7))
    {
        Serial.println("Cannot initialise SD card");
        while (true);
    }

    File file;

    if ((file = SD.open("file.txt", FILE_WRITE)))
    {
        Serial.print("Writing to file...");
        file.println("Hello, World!");
        file.close();
        Serial.println(" DONE");
    }
    else
        Serial.println("Cannot open file for writing");

    if ((file = SD.open("file.txt")))
    {
        Serial.println("Opening file...");
        while (file.available())
            Serial.write(file.read());
        file.close();
        Serial.println("DONE");
    }
    else
        Serial.println("Cannot open file for reading");
}

void
loop()
{
    // pass
}

So what exactly is going on here?  Am I doing something obviously wrong?  Or is the board's hardware SPI not working?  Or is there a problem with the Adafruit library?

Extra info:
I'm using the arduino-cli to upload sketches the following ways:
# To compile:
arduino-cli                                     \
    compile                                     \
    --fqbn arduino:avr:nano:cpu=atmega328old    \
    --warnings all                              \
    MyArduinoSketch;

# To upload
sudo arduino-cli                                \
     upload                                     \
     --verify                                   \
     --verbose                                  \
     --port /dev/ttyUSB0                        \
     --fqbn arduino:avr:nano:cpu=atmega328old   \
     MyArduinoSketch;

I installed the mentioned libraries via arduino-cli.

if you test the display on hardware SPI without SD library, is SD card inserted?

the adafruit display has internal logic level conversion and arduino will read 3.3 V as HIGH (even if it is out of limit specified in the datasheet). you don't need voltage dividers.

Hint: You might need to set the SD chip select pin to OUTPUT and HIGH when using the TFT only with HW SPI. Especially if a SD card is inserted.

@MikaelPatel, only if the card is inserted. without the card there is no device

@Juraj I tested with both inserted and ejected SD it is not working either way.  TBF it is not the official Adafruit display, it is like this: http://ceezblog.info/images/blog/9341breakout.jpg which is AFAIK handles 3.3V at the logic level and not 5V.  Either way, I don't think there's any harm on adding a voltage divider there and make sure the HIGH is actually the expected 3.3V.  If this would be a problem, the software SPI shouldn't work either, should it?

@MikaelPatel I have two identical setups, one with two SPI slaves (display, card), and one with only one (display).  Both of them are working with the software SPI (the first only works if the SD card is not inserted).  I tried to set the SD CS/SS pin to OUTPUT despite the fact the the SD.begin(<CS/SS pin>) will set it to output implicitly.  I haven't tested with setting it HIGH, however the version where I don't have the card reader connected should work yet it didn't.

try Adafruit_ILI9341(10, 9, 8); without SD card inserted

@Juraj that did the trick!  How?  Why? ;)

(Let me try and make it work with the SD card reader at the same time..  I'm sure it will work now, but let's just give it a test..)

I wouldn't use a resistive divider on SPI. The resistors coupled with the gate capacitance form a low-pass filter limiting the maximum frequency you can reliably communicate at. Using software SPI you are going a lot slower, so it works better. You should use a proper active level shifter.

Use constructor Adafruit_ILI9341(10, 9, 8); to make the reset that works with software SPI.
To SD card as second device on the bus:
Every SPI device on SPI bus must be controlled by slave select pin. If a device is connected to the bus and the SS pin is left floating the device disturbs the bus.
The empty SD card adapter is not a device on the bus, only the inserted card is a device. If it is on the bus the corresponding SS pin must be set HIGH. If you use the SD libray SD.begin(SD_SS_PIN), the library initializes the pin. If you don't use the library in the sketch (because it takes much memory), remove the SD card or set the SS pin to OUTPUT and HIGH.

Hi Peter First Adafruit spends a lot of time creating their libraries and i do appreciate that but my luck is that I never get anything working with their libraries it is just me
I use this library:
https://github.com/Bodmer/TFT_ILI9341
and it works wonders if I want to add other SPI devices like your SD card I edit the User_Setup File that is included in your sketch right at the bottom of the file you can find the following line:

// #define SUPPORT_TRANSACTIONS

uncomment that line and your Touch part as well as SD card will functional normally I have had a setup working with the screen, touch controller, RFID board and a SD card all working on SPI each with their own SS or Chip select pin
NB! if you are going to try the library it is best you remove the ADAfruit one first because there are some files with the same names and the IDE tends to include the first one it finds AKA Adafruit


text:
Johnny Five LCD: black boxes only
I posted this also at Stack Overflow. I have tested the Johnny Five LED example on my Arduino Uno, and it worked fine. Now I need to test Johnny Five LCD. I connected all wires correctly.

The code:
var five = require("johnny-five"), board, lcd;

board = new five.Board();
board.on("ready", function() {
  lcd = new five.LCD({
    // LCD pin name  RS  EN  DB4 DB5 DB6 DB7
    // Arduino pin # 7    8   9   10  11  12
    pins: [7, 8, 9, 10, 11, 12],
    backlight: 6,
    rows: 2,
    cols: 20
    // Options:
    // bitMode: 4 or 8, defaults to 4
    // lines: number of lines, defaults to 2
    // dots: matrix dimensions, defaults to "5x8"
  });

  // Tell the LCD you will use these characters:
  lcd.useChar("check");
  lcd.useChar("heart");
  lcd.useChar("duck");

  // Line 1: Hi rmurphey & hgstrp!
  lcd.clear().print("rmurphey, hgstrp");
  lcd.cursor(1, 0);

  // Line 2: I <3 johnny-five
  // lcd.print("I").write(7).print(" johnny-five");
  // can now be written as:
  lcd.print("I :heart: johnny-five");

  this.wait(3000, function() {
    lcd.clear().cursor(0, 0).print("I :check::heart: 2 :duck: :)");
  });

  this.repl.inject({
    lcd: lcd
  });
});

But it doesn't output as expected. It is showing one row of black boxes only. what have I missed?

Look at this answer here: http://arduino.stackexchange.com/a/17472/11174 . I'm still studying about it, otherwise I would've posted more.

Try changing the resistance in your 10k potentiometer. This might be a reason for the black boxes.
P.S: I.m a beginner too.

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
Controlling Servo Motors with push button. Problem though
I have this setup where I have and Arduino Uno, a mini servo motor, and a pushbutton. I use a single pushbutton to control the servo motor to go to one position, then push it again to go back. It first goes to 0 degrees, then if you push it it goes to 180 degrees then vice versa. The problem is that in its initial state (which is 0 degrees), the servo motor makes noise. Like it's running or something then it gets hot.
I've seen other servo motors that never do this. Here is my code by the way:
#include <Servo.h>

const int buttonPin = 8;
const int servoPin = 9;
int buttonState = 0;
int directionState = 0;
Servo servoOne;
int pos = 0;

void setup() {
  servoOne.attach(9);
  servoOne.write(directionState);
  pinMode(buttonPin, INPUT);
}

void loop() {
  buttonState = digitalRead(buttonPin);
  if (directionState == 0) {
    if (buttonState == HIGH) {
      directionState = 1;
      for (pos = 0; pos < 180; pos = pos + 1) {
        servoOne.write(pos);
        delay(5);
      }
    }
  } else if (directionState == 1) {
    if (buttonState == HIGH) {
      directionState = 0;
      for (pos = 180; pos > 1; pos = pos - 1) {
        servoOne.write(pos);
        delay(5);
      }
    }
  }
}

I really need all the help I can get.

Can you try setting the initial state to a middle value like 20 or 30? I have these really cheap servos I bought on ebay (no datasheet or anything). Empirically, I've found that my range is less than advertised. I see something similar to what you described when I try writing a degree beyond what my servo is capable of.

Looks like your delay is too short. If the delay gets over before the servo can reach the set postion, it will skip that command and execute the next one.
Also I agree with @julio about how are you powering your servo. By "mini" servo I assume that you are using a micro servo. I have a Tower Pro 9G micro servo (which I use as steering servo btw, small but pretty decent), and it works fine if I power it with the Arduino UNO, but torque is a bit less. Anyways, check your servo's datasheet, your servo might need more power. Just hook it up to a power supply and make sure the grounds are common. The jitter might just be the result of inappropriate power.

You might need to add more time to the delay. Also, check how your powering the servo. If you're powering from the Arduino, it might be drawing to much current and causing issues. If it's a bigger servo, try to hook it up to an external power source and just connect the PWM line and it's ground.

also be sure to join the ground of the arduino with the ground of your external power supply (+5vdc)

The code was absolutely ok but position 180 was a problem sometimes. Those servos simply can't reach position 180 because the end is on 178 or nearby. But the servo was trying to go on that position. The solution is simple: try a different position (179 or less).

The most basic issue with servo motors is wrong cabling and then insufficient motor driver in terms of amperage. And then, PWM duty cycle must be set correctly. If you don't treat those things properly, you may hear noises such as humming, vibration instead of turning the motor.

I think you need to do some debouncing  on the button.
You can modify the code to suit your project:
/*
 Debounce

 Each time the input pin goes from LOW to HIGH (e.g. because of a push-button
 press), the output pin is toggled from LOW to HIGH or HIGH to LOW.  There's
 a minimum delay between toggles to debounce the circuit (i.e. to ignore
 noise).

 The circuit:
 * LED attached from pin 13 to ground
 * pushbutton attached from pin 2 to +5V
 * 10K resistor attached from pin 2 to ground

 * Note: On most Arduino boards, there is already an LED on the board
 connected to pin 13, so you don't need any extra components for this example.

 created 21 November 2006
 by David A. Mellis
 modified 30 Aug 2011
 by Limor Fried
 modified 28 Dec 2012
 by Mike Walters

 This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/Debounce
 */

// constants won't change. They're used here to
// set pin numbers:
const int buttonPin = 2;    // the number of the pushbutton pin
const int ledPin = 13;      // the number of the LED pin

// Variables will change:
int ledState = HIGH;         // the current state of the output pin
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin

// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 50;    // the debounce time; increase if the output flickers

void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);

  // set initial LED state
  digitalWrite(ledPin, ledState);
}

void loop() {
  // read the state of the switch into a local variable:
  int reading = digitalRead(buttonPin);

  // check to see if you just pressed the button
  // (i.e. the input went from LOW to HIGH),  and you've waited
  // long enough since the last press to ignore any noise:

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer
    // than the debounce delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;

      // only toggle the LED if the new button state is HIGH
      if (buttonState == HIGH) {
        ledState = !ledState;
      }
    }
  }

  // set the LED:
  digitalWrite(ledPin, ledState);

  // save the reading.  Next time through the loop,
  // it'll be the lastButtonState:
  lastButtonState = reading;
}

Your assessment is incorrect. The nearly second (180 * 5ms) of delay already present in the code already accomplises substantial debouncing.

The delay(5) is after servo.write() the debouncing is for the buttons!! I'm not sure what you are referring to. As an electronics and communication engineer, I believe I have a good idea of what I'm talking about!

You are fundamentally and grossly mistaken.  Because this is a serial execution language, once the button is detected high the entire blocking delay, 180 times 5 ms, must elapse before the state of the button will again be evaluated, which is an order of magnitude beyond typical debounce time. When it is seen as low, no action is taken so no debounce is required. Facts are facts, regardless of who you claim to be.

So you're saying the program is checking for the button state while it's executing the for loop?

No, rather obviously, once it decides to execute the for loop, it will ignore the button until the for loop is complete.  Ignoring an input after acting on it, until such time as any contact bounces must have died away, is the simplest and most basic form of debouncing.

And what happens when the button is set to low after the program has checked for the state?

Nothing happens when the button is set low.  But the key is that after the button is set high, the state of the button isn't even considered again for almost a second.  If you hold the button down, you can get it to slowly toggle modes, but that may not be undesired, and regardless it has nothing to do with the problem reported in the question.

NO, the button was left to high when the program checked for the state and was immediately set to low. Because there is no debouncing process in place the processor will miss the state change, as it's running on high frequencies. THIS means the program will run an extra loop and will cause problems in more important applications.

You are rather confused.   The program does not need to detect state changes, it is so slow that it can merely detect states.  If the user releases the button in less than 179*5 = 895 ms, the function will run only once.  If they hold the button down for longer than that, the motor will change position every 895 ms.  There is nothing in the question to indicate that such a result is undesired.  In fact, the question is quite clearly about a different problem entirely!!.

authors: 北京做假证_北京办文凭毕业证 - spam

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
Is it possible for Arduino firmware to recognise only one computer?
Is it possible to adjust the Arduino firmware to recognise only one PC computer? On other computers it would show driver not recognised or driver not found.
E.g.: My computer should see the Arduino normally, and it should not work if I connect the same arduino to other computers.

No.
However, it is possible to place unusual and/or secret requirements on the computer's drivers or application software - however those software components could be present on multiple computers unless you also take measures to node lock them.

You could customize the USB VID/PID and descriptors, causing the device not to be recognized by a usual driver
You could alter the behavior of the USB interface (or bootloader and sketch) to require unusual operations - either obscure, or even secret to the level of unique-per-unit cryptography
Or most simply, you could just use a board without a USB interface and bring your own.  Especially if you lock the flash, there's not a whole lot others can do except entirely erase your work and be left with an unusually expensive ATmega evaluation board.

Do note also that most operating systems make it possible to easily intercept the raw USB traffic going to/from devices, so someone who can see it in operation can learn a lot about how it is working.
If you want to play games with odd USB implementations, you'll probably do better with a direct USB board like a Leonardo - and you will certainly want to have an ISP setup to recover it, as your efforts will no doubt break it many times before you get something on there which works as intended.

Thanks for nice answer. I will try first solution, if not suceed, i will use simplest solution - third.


text:
How to set Alarms on the DS3231 easily so the Nano doesn't have to go to sleep with delay statements?
I want my solar array sun tracker to shut down at night then move full east in the morning to catch the first rays.
I know the DS3231 can set alarms but it is not clear from its documentation how to do it with the normal library.
Delay statements are the way I have it periodically check for when to take readings, but I really want it to be able to respond to radio-remote control commands, which don't work during delays.
Q:  Is there an easier way?

Which library are you using? As this one supports it just fine.

That is interesting.  Will bookmark it.  Thanks, @Gerben

https://arduino.stackexchange.com/questions/33972/how-to-have-some-code-executed-at-a-certain-time-of-day-with-a-ds3231-rtc/33973#33973

Here it is:
https://github.com/sleemanj/DS3231_Simple
Example:  https://github.com/sleemanj/DS3231_Simple/blob/master/examples/z2_Alarms/Alarm/Alarm.ino
This is what I was looking for.
My system needs to be able to respond to radio remote commands while asleep, and the long delay() statements were preventing that.
These alarms solve the problem.


text:
Arduino Nano periodic reset under program control?
Is there a way to cause a periodic reset of an Arduino Nano under program control, short of some kind of external relay that signals the RST pin?
I'd like to do a full reset triggered by a digital write.
When the power is applied to the Nano it automatically pulls all the digital output pins to LOW so it appears that simply connecting a wire from a digital output to the RST pin would cause the system to continually reset and never run the program.  This would apply equally to using the DS3231 RTC chip's alarm function.  It would require the program to run in order to use it.
I suppose a relay would do the trick.  Or maybe even just an inverter chip like the 7404 between a digital output and the RST pin.  I am trying to fit this all in a small box so more hardware gets to be a problem.
So the question:  Is there any way to do this without external hardware?

Use the watchdog.

You didn't elaborate enough for me to know what you mean, @Majenko.  Besides, I want to trigger it programatically, not just periodically, if possible.  But maybe you are on to something - yet you didn't explain how to do it.  If you have an answer, please post it as one.

You simply turn the watchdog on with a short period and don't bother kicking it. It'll reset. Be sure that the period is longer than the bootloader timeout so you can disable the watchdog at startup - otherwise only a poweroff will disable it.

http://playground.arduino.cc/Main/ArduinoReset

@Majenko, thank you for this info.  I upvoted all your comments.  (If you had made this an answer I would have accepted and upvoted it that way.)  If you read my comment on the other answer you will see why I needed this and why I thought program control was best.  But upon further reflection I see that the watchdog is by far the simplest answer.  This is why I like this forum.  Thanks again.

Why do you want to reset you board?  The reason affects the answer.
Do you want to reset the board because your program crashes after n hours?  If so its probably better to fix the memory leak that you have in the code.
Is it because some global variables need to resetting every now and again?  If so could you place them in a class and store a pointer to them as your only global.  When you want to 'reset' the board delete the instance of the class and recreate it.
What happens if the software crashes?  Have you got it configured to restart on a crash?  If so could you just crash the code deliberately?
Because you have size constraints then it may be worth a bit of lateral thinking to see what the code can do for you.

The reason is that the communications over the wire to the LCD sometimes suffers bit errors which scrambles the screen.  The only fix I have found is to power it off by unplugging the cable, then plugging it back in.  I still haven't looked into the watchdog timer, but I do know that I can detect bit errors by reading back what I just wrote, periodically.  If they don't match then I want to force a reset.

Upvote because your answer made me have to think harder.....  I believe I will go with the watchdog instead of adding a bunch of new code.  Thanks!

@Archway - Do you need to reset the whole system, would power cycling just the LCD fix it?


text:
Interaction between Analog Pins when measuring a DC voltage- a common issue?
Just set up a replacement "Piduino" - a RPi3 connected by USB to an Arduino Uno.  The previous one was the victim of a Diet Big Gulp - spilled on the voltage divider breadboard.  Whoops.  The tiny breadboard with the voltage divider began to rust inside so it got really difficult to keep it working correctly.
This is for the plot named "Indoor 12V Lighting System" at https://www.SDsolarBlog.com/montage
I built a new Uno/breadboard from scratch and swapped it in with the breadboard stuck onto the plastic case.  All nice and tidy.
But the analog inputs were really strange.  It would read really close, but then minor changes to the software would produce wildly varying results.
Imagine my surprise when this morning I discovered that I had plugged the divider's analog input to A4 instead of to A1 where it belonged.
Now that it has been fixed all is well.  As long as the correct pin is being used in the digitalRead it seems not to matter, perhaps.
Here is the plot from before then after I moved the input to the correct location:

The actual voltage was falling from 12.7 down to 12.5, and after moving the pin it settled down to the correct reading.  Then I turned on the charger while the sun is up.  It is tracking the voltmeters perfectly now.
Clearly, the problem was that I was reading the wrong pin.  My fault, obviously. But it got me wondering just how much they affect each other.
So my question is about why I was getting any readings at all?  I would have hoped that the analog inputs were truly separate from each other.  Instead, it appears as if there is crosstalk of some kind.
Is this a common issue?

New information
I see that it has been pointed out that this was discussed in this Q&A:
Should all unused analog input ports be tied to ground for accurate A2D measurements?
But since that does not call it an imperative, just "one of the problems with using analog" I would have assumed that this is not common, so perhaps there is an implied answer there.
It would be a project all by itself to use half the small breadboard to distribute ground to all the other analog pins.  And I've never seen this referenced in any of the documentation.  Nor is there a tag for crosstalk.
So my question still stands:  Is this common when measuring a DC voltage?

You wrote: “Is this a common problem?” I fail to see any problem in what you describe. The behavior you experienced is perfectly normal and, usually, unproblematic.

TNX for the comment.  In response I posted this morning's plot that shows before and after moving it to the correct pin.  The actual voltage was slowly dropping from 12.7 to 12.5 the whole time.

The real problem is not crosstalk. The problem is you were reading the wrong pin. Is that a common problem? Yes, it happens, as people are often distracted. The fix is pretty simple, and you figured it out yourself: read the correct pin. Problem solved.

Mea Culpa.  All true.  I am surprised it showed any reading at all.  It makes me wonder if when I use multiple analog inputs I should use pins that are more widely-separated, kinda like how we use the urinal bank in bathrooms..?  ;-)

Majenko just explained how the internals work, and it makes perfect sense.    It is not crosstalk at all.  He gets the Accepted Answer on merit.

This is normal and expected behaviour.  There are a number of factors that influence it, and it will help to understand the basic internals of the ADC.
In simple terms the front-end of the ADC looks like this:

simulate this circuit – Schematic created using CircuitLab
The MUX selects which pin (A0-A5) is being sampled. Switch SW1 connects the Sample And Hold capacitor C1 to that selected input, which then charges (or discharges) to the same voltage as the input.
After the acquisition period switch SW1 switches position and the ADC circuit is connected to the capacitor.  Over a period of clock cycles the ADC works out what the voltage across the capacitor is and stores the result in the ADCH and ADCL registers.
Now - on a pin that has nothing connected to it, what voltage will be across that capacitor when SW1 is switched to charge it? Well, this is where your strange results come from:

Any charge already in the capacitor will still be there (which is why it can be good to connect the unused ADC pins to ground through a resistor, to remove that charge).
Signals, either in wires, IC pins, or the silicon circuitry in the chip itself, will be capacitively coupled with what is next to it.

That last one is the most critical for your results.  Capacitive coupling.
Place two wires next to each other and they will, through capacitance, try and get the same charge on them. Under most circumstances that attempt to influence the charge is completely swamped out by what is being send down the wire. But, when there is nothing being sent down the wire that charge becomes noticable. A1 will attempt to "float" to the same level as A0, because they're next to each other. A2 will try and float to the same level as A1, A3 to A2, etc.
If you put a signal in to A0 and plot all 6 inputs you will see each has a progressively lower amplitude copy of the signal. It's hopping, capacitively, between the pins. And all because there's nothing to stop it.
If you think "Ah, but it's DC. DC doesn't go through capacitors", then you're wrong.  Wrong in thinking it's DC.  There's a lot of mistaken assumptions about the labels "AC" and "DC".
DC is not what you have.  Yes, there is a "DC component" to what you have (which is manifest as the average of the voltage over time), but there is a large AC component as well.  That AC component is what you are graphing in the form of your changing battery voltage.
Voltage is far more complex than just DC or AC. What you think of as AC is actually a waveform with a fundamental frequency (e.g., 60Hz) and zero "DC offset". Add a DC offset to the signal and it's still AC, but compared to the "lower" end of whatever adds the DC offset, it's just the waveform is "shifted up".
Pure DC, and what doesn't pass through a capacitor, has no signal components. There is only 0Hz and nothing else. Pure DC is almost impossible to create without highly specialized equipment. All voltages in normal life vary, and that variance is the AC component of the signal.

Right on.  Excellent answer, Majenko.  Very thorough.  That explains a lot.  So it is not true crosstalk in the wiring at all.  Got it.  Thanks.

If you do read the 6 inputs, you will greatly enhance the coupling between them, as you will be connecting C1 to each of them in turn.


text:
Arduino button trigger coding
I am trying to write a simple coding to change the color of an RGB LED using a push button trigger.  I just need the the pin output to change when the button is pressed.  I would like to do this using just an ATTiny85 and uploading the code to it using an Arduino Nano.  I don't have much coding experience so I was hoping someone would take a quick look at my attempt and tell me if it will work.
// here are the pin number assignments

int blue = 2;

int green = 1;

int red = 0;

int button = 4; // the pin the button is on.

int choice = 0; // mode selection

void setup() {

  // initialize the pwm pins as outputs.

  pinMode(red, OUTPUT);

  pinMode(green, OUTPUT);

  pinMode(blue, OUTPUT);

  pinMode(button, INPUT);

  analogWrite(red, 255);

  analogWrite(green, 255);

  analogWrite(blue, 255);

}

void loop() {

  // read the pushbutton to see if it's been pushed
  int val;
  val = digitalRead(button);

  // val = HIGH means the button has been pushed
  // and the mode is to be changed.

// SELECT CHOICE //////////////////////////////////////////////////

  if (val == HIGH) {
    choice = choice + 1;

    analogWrite(blue, 255);
    analogWrite(green, 255);
    analogWrite(red, 255);
    delay(500);

    // indicate mode transition with blue flashes
    for (int i = 0; i < 5; i++) {
      analogWrite(blue, 125);
      delay(20);
      analogWrite(blue, 255);
      delay(40);
    }

    delay(500);

    // change this if you want more modes

    if (choice == 5) {
      choice = 0;
    }
  }

  while (val == HIGH) {
    delay(100);
    val = digitalRead(button);
  }

  //////////////////////////////

  // OFF

  if (choice == 0) {
    analogWrite(red, 0);
    analogWrite(green, 0);
    analogWrite(blue, 0);

  }

  // RED

  if (choice == 1) {
    analogWrite(red, 255);
    analogWrite(green, 0);
    analogWrite(blue, 0);

  }

  // GREEN
  if (choice == 2) {
    analogWrite(red, 0);
    analogWrite(green, 255);
    analogWrite(blue, 0);
  }

  // BLUE

  if (choice == 3) {
    analogWrite(red, 0);
    analogWrite(green, 0);
    analogWrite(blue, 255);
  }

  // AMBER
  if (choice == 4) {
    analogWrite(red, 255);
    analogWrite(green, 255);
    analogWrite(blue, 0);
  }

}

Any input?

You could look at the one shot button press example in the Arduino IDE and that change may be able to remove some of the delays in your code that prevent debounce.

The problem with the one shot button example (and apparently with my own code) is the action doesn't stick.  The LEDs only light up when the button is pressed.  When I let go of the button, the LEDs go out.  I need them to stay on when the button is release and change to the next color when the button is pressed again.  Any idea how to make that happen?


text:
setting output analog/digital pin to ground
So I need to automaically eject a CD from a Blu-Ray drive, I have a wire welded on the drive's card that if manually connected for a split second (pulse) to the ground of that same card on the drive, will eject the CD. Now in order to do that automatically I'm using an Arduino Nano and I connected that wire to an analog pin "d1" set its mode to Output and connected the grounds of both Arduino and drive together. Here's my code 1
int ds1 = A2; //pin that indicates the existence of the CD inside the drive if HIGH and its inexistance otherwise
int d1 = A3;  //pin connected to the wire that if connected to ground ejects the CD

void setup() {
  Serial.begin(9600);
  pinMode(ds1, INPUT);
  pinMode(d1, OUTPUT);
  while((!analogRead(ds1))) //if the CD isn't inside the drive wait
  {}
}

void loop() {
  analogWrite(d1,0); //eject CD
  delay(500);
  while(!analogRead(ds1)) //if the CD isn't inside the drive wait
  {}
  delay(1000);
}

I'm thinking that maybe setting the pin to 0 doesn't necessarily mean I connected it to the gnd, it's just a possibility if you see anything wrong with the code or have any suggestion please help me

https://majenko.co.uk/blog/what-exactly-gpio-pin

pinMode(d1, OUTPUT); sets the pin LOW (0 zero) connected to ground

while(!digitalRead(ds1)) would be better at first line in loop. then you can leave it out from setup()

what do you mean by Blu-Ray drive?  ..... is this a drive on a computer or is it a Blu-Ray player?

a blu-ray player not connected to a computer

Yes, setting a pin to OUTPUT and setting it LOW effectively connects the pin to ground (via a few ohms of resistance).
There's a couple of things wrong with your code, though, which you should address:

Use digitalWrite() not analogWrite().

analogWrite(pin, 0) is effectively the same as digitalWrite(pin, 0), but it's ambiguous to someone reading your code.

You never "release" the pin, so once it goes LOW it stays LOW.  You should emulate open drain by setting it to INPUT when not using it.
You should get into the habit of putting repeated code into functions to make it more understandable what's going on.

For example:
void setup() {
  Serial.begin(9600);
  pinMode(ds1, INPUT);
  pinMode(d1, INPUT);
  waitForCD();
}

void loop() {
  triggerEject();
  waitForCD();
  delay(1000);
}

void triggerEject() {
  pinMode(d1, OUTPUT);
  digitalWrite(d1, LOW); // Press the button
  delay(100); // This is how long the button is pressed for
  pinMode(d1, INPUT); // Release the button
}

void waitForCD() {
  while(!analogRead(ds1)) //if the CD isn't inside the drive wait
  {}
}

!analogRead(ds1) will only ever be true if the voltage at pin A2 is exactly zero volts. If you really want to read an analog voltage here you should find a threshold value that the value is compared to:
while (analogRead(ds1) < 100)) {}

Or it may be that you actually want to use digitalRead()...

Setting a digital PIN to LOW doesn't set it to GND. It set it to 0. Just try for example with a HC12: to set it, you must link its SET PIN to GND. If you link the SET pin to real GND, it works. If you link it to D8 (eg) and set D8 to LOW, it doesn't work.

@Peter I disagree entirely. When you set a pin to LOW it activates a low-side N-channel MOSFET with very low resistance to connect the pin to GND. Worst case would be 20Ω, but more likely <1Ω for the low-side. Which pales into insignificance compared to the 1kΩ resistor that the module slaps in there. Since it uses an STM8 MCU the input LOW threshold is 0.3VDD, which at 5V is 1.6V, which even with 20Ω plus 1kΩ against the 10kΩ pullup is a good 3-4x higher than the voltage the Arduino would give at that pin (0.46v). I suspect you just forgot to set the pin to OUTPUT mode.

Take a HC12 (eg) and read the DataSheet: if you put SET at GND, the HC12 will turn into setting mode. So try and you'll see it's true. Now, link to a PIN on the Arduino, set it to LOW. You'll see the HC 12 don't enter in setting mode (we've made also test with Ax PIN and result is the same. And "of course" we are in OUTPUt!) . Seems if you want to get a "real" GND you must trigger a NPN. Maybe using LOW it's "near to be GND" and so, in some case it will work.

NPN will be even worse as you impose a 0.7v junction voltage drop on to of the resistive divider. I don't have a HC12, but please do some voltage measurements on the stm8 io pin and show me that its above 1.6v when pulled low by an Arduino.

https://arduino.stackexchange.com/questions/69003/is-digitalwritepinnumber-low-different-from-ground-pin

I don't know what relevance you think that has.

Ah, It seems to depend on the HC12! With some, it works, with other no... I'll investigate to see if some are clones of clones

@Peter You are waiting the required amount of time after pulling SET low before trying to use it...?

yes. After testing I confirm: SET on D5 and D5 as LOW. It works one or two times and we can set the HC12. Then, we start to receive bad value from AT command. To get "again" good values, we need to connect SEt to "real GND". And in that case, we can send as many AT cmd we want, we never get bad return. It's very strange....


text:
Set parameters after compilation
I am extremely new to Arduino and have searched for this on the web but have not found it.
My project has 2 files, a .ino file with the sketch and another .h file with the secrets and configuration parameters, such as reading intervals, credentials to connect to WiFi, etc.
Now I need in runtime to be able to connect to the arduino, either by serial or by any other way to be able to set these parameters.
My question is: How can I change the parameters after compiling the sketch? For example, how can I specify the credentials for the Arduino to connect to the client's WiFi, since each client has different credentials?

You can set parameters, like SSID and password, at run time in several ways. The two most obvious are:

a small dialog using the serial monitor or an other serial console;
a web interface served by the Arduino that lets you enter parameters.

The idea of the latter is that, when the Arduino can't connect to an available network (because it is unknown, or because it doesn't have the right credentials stored), it sets itself up as an access point with a known SSID, password, and IP address.
You can then (first) connect to the Arduino's access point WiFi network, and then open a HTML page from the Arduino in a webbrowser that lets you enter your WiFi credentials for the "real" WiFi network. This is how the WiFiManager library works (for the ESP8266 and the ESP32).
Once the credentials have been entered, you can store them (permanently) in EEPROM using the EEPROM library or, if the MCU on your Arduino doesn't have EEPROM, using a library that stores in flash, like the FlashStorage library for SAMD21-based Arduinos.
The same mechanisms can be used for other parameters you may want to set at run time.

It is likely 2 features are desired for this project:

A way to enter WIFI credentials after the program is running.
A way to store the WIFI credentials between power cycles.

The solution for the 2nd requirement is to use non volatile memory. Both problems have been solved before for certain types of Arduinos.  Here is a project on GitHub which has solutions for boards using the ESP8266 or ESP32 processors.


text:
Ideal voltage level for attachInterrupt()
Well I am working on old textile machines, it is taking motor RPM with ISR. I want to read this RPM and publish on web. but the output voltage of this old system is 0 and 22 Volt. (0 Volt when the infrared light comes into the gap in the disk, 22 volt  when the infrared light see the photocell). if I try to read this data I see 17.000 - 18.000 RPM while actual RPM was 1600. I cant read true RPM. I suspect input signal voltages which is 0 and 22 Volts. I don't think Arduino UNO works in this voltage range but I cant see any info at docs. voltage divider with 0 - 2.2 volts I have dropped but still did not work. what is the ideal voltage level for attachInterrupt() command. I am using klon arduino uno (Arduino Uno R3 SMD CH340 Chip - Klon Arduino Uno )
Also are there ane filter  to prevent interference I am using long wire (100 meter)?
this is my code
int encoder_pin = 2; // pulse output from the module
unsigned int rpm; // rpm reading
volatile byte pulses; // number of pulses
unsigned long timeold;
// number of pulses per revolution
// based on your encoder disc
unsigned int pulsesperturn = 12;
void counter()
{
   //Update count
   pulses++;
}
void setup()
{
   Serial.begin(9600);
   pinMode(encoder_pin, INPUT);
   //Interrupt 0 is digital pin 2
   //Triggers on Falling Edge (change from HIGH to LOW)
   attachInterrupt(0, counter, FALLING);
   // Initialize
   pulses = 0;
   rpm = 0;
   timeold = 0;
}
void loop()
{
   if (millis() - timeold >= 1000) {
      //Don't process interrupts during calculations
      detachInterrupt(0);
      rpm = (60 * 1000 / pulsesperturn )/ (millis() - timeold)* pulses;
      timeold = millis();
      pulses = 0;
      Serial.print("RPM = ");
      Serial.println(rpm,DEC);
      //Restart the interrupt processing
      attachInterrupt(0, counter, FALLING);
   }
}

The interrupt signal is assumed to be a digital input signal of 0v or 5v (for an Arduino Uno, which is a 5v arduino board). You need a voltage divider which is two resistors to bring the 22v down to 5v. For example r1=33k and r2=10k (for 5.1v, close enough). Perhaps you need a capacitor of 1nF parallel to r2 to filter spikes and noise. Please check the links in your question, don't give links to something that requires to log in. The 100 meter cable is a serious problem. What kind of cable do you use? Can you put the arduino near the engine? The code in the loop is not okay.

You are awesome, I've checked links. 100 meter cablo there is no The voltage drop, is it still a problem? What happens if it happens. "Can you put the arduino near the engine?", no because there are 20 machines.Also where is the problem in "loop"

"100 meter cablo there is no The voltage drop, is it still a problem? "  You have a 100 meter antenna. What happens if you pick up disturbances from other sources, do you think that might matter?

Use an optocoupler, then the input voltage can be anything and the data is a bit more robust.

@ctrl-d If the signal can output enough current for a opto-coupler, that would be a good solution. With a shielded cable and a current as signal (instead of a voltage). Maybe it is possible, but it requires some electronics skills to make it work.


text:
Can not print an element in an specific position in an arduino list
I have been tying to print an element of a list with the same position as the number that it matches, but it does not seem to work and I can not figure out if I made some mistake, could someone please check it? Would really appreciate it
Here are the list declarations:
int names[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
char *users[10] = {"Josh", "John", "Frederic", "Mikael", "Anthony", "Charles", "Tom", "Chris", "Steve", "Mike" };

And this is what I am using to print the name I need:
if (attempt != FINGERPRINT_OK) return -1;
Serial.println ("Belongs to: ");
if(data.fingerID == names[n]) {
    Serial.print(users[n]);
}

Complete Code:
#include <Adafruit_Fingerprint.h>
#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3);
pinMode (12, OUTPUT);
pinMode (13, OUTPUT);

Adafruit_Fingerprint data = Adafruit_Fingerprint(&mySerial);

int names[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
char *users[10] = {"Josh", "John", "Frederic", "Mikael", "Anthony",
"Charles", "Tom", "Chris", "Steve", "Mike" };

void setup() {
  Serial.begin(9600);
  while (!Serial);
  data.begin(57600);
  if (data.verifyPassword()) {
    Serial.println("Verified connection");
}

  else {
    Serial.println("Unnable to verify connection, try again");
 while (1) { delay(2500); }
}

data.getTemplateCount();
Serial.print("Waiting for one of the:"); Serial.print(data.templateCount);
Serial.println("valid fingerprint");

int getFingerprintIDez();
uint8_t getFingerprintID();

void loop() {
for ( int i = 0; i <= 10; i++) {
 uint8_t attempt = data.getImage();
  switch (attempt) {
   case FINGERPRINT_OK:
   break;
 delay (2500);
}

attempt = data.image2Tz();
  switch (attempt) {
    case FINGERPRINT_OK:
      Serial.println("Image converted");
    break;
    case FINGERPRINT_IMAGEMESS:
      Serial.println("Image too messy");
    return attempt;
  }

 attempt = data.fingerFastSearch();
   if (attempt == FINGERPRINT_OK) {
    Serial.println("Found a print match!");
    digitalWrite (13, HIGH);
    delay(1250 );
    digitalWrite (13, LOW);
  }
   else if (attempt == FINGERPRINT_NOTFOUND) {
   Serial.println("Did not find a match");
   digitalWrite (12, HIGH);
   delay(1250 );
   digitalWrite (12, LOW);
   return attempt;
  }
Serial.print("Found ID #"); Serial.print(data.fingerID);
Serial.print(" with confidence of "); Serial.println(data.confidence);
return data.fingerID;

uint8_t attempt2 = data.getImage();
if (attempt2 != FINGERPRINT_OK) return -1;
 attempt2 = data.image2Tz();
if (attempt2 != FINGERPRINT_OK) return -1;
 attempt2 = data.fingerFastSearch();
if (attempt2 != FINGERPRINT_OK) return -1;
 Serial.println ("Presents: ");
if(data.fingerID == names[n]) {
    Serial.print(users[n]);
}
}
}

I am attempting that when a fingerprint is verified, the position that matches it out of all the stored fingerprints gets stored as n so I can later print the name asigned to that same position. Thanks

What's 'n' ? Please provide complete and minimalistic example that we can debug.

What does your actual output look like? What do you want it to look like instead?

Right now I can not upload it because "'n' was not declared in this scope", last time I tried it was not able to recognize the name associated with each fingerprint value, so the names were not printed

How about you completely delete
int names[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

and instead do:
if (attempt != FINGERPRINT_OK)
    return -1;

Serial.println ("Belongs to: ");
Serial.print(users[data.fingerID - 1]);


text:
How to remove or only show part of the data received?
I'm using the ble_client.ino example and I can't figure out how to only show some of the notifyCallback data. I'm getting three different types of data from one service UUID.
static void notifyCallback(
  BLERemoteCharacteristic* pBLERemoteCharacteristic,
  uint8_t* pData,
  size_t length,
  bool isNotify) {

  static unsigned long lastPrinted;
  const unsigned long printInterval = 100;
  if(millis() - lastPrinted >= printInterval) {
    lastPrinted = millis();
    Serial.println();
    }
    Serial.printf(" Data:%X", pData[16]);

}

This is what get in the serial monitor

Data:A9 Data:B9 Data:F5
  Data:A9 Data:B9 Data:F5
  Data:A9 Data:B9 Data:F5
  Data:A9 Data:B9 Data:F5

I just want the

Data:B9
  Data:B9
  Data:B9
  Data:B9
  Data:B9

to be shown. How to?

use an if statement  ..... Serial.printf() executes only when data is B9

the value with change. can't use if

You only want each first and second value and not each third? Or you don't have found a clear condition which values you want? You need to find out a precise condition, and use it in an if statement as jsotola proposes.

You say the value can change, but then you also say that you only want "Data:B9" to be printed.  Do you see how that is ambiguous?  So do you want it printed only when it is B9?  Or what?  What determines that it should be printed?  Can you see how that is an important piece of information?


text:
Stuck Arduino Relay?
I am looking for a relay that stays on (NC=Normally Closed), and when I send a new signal switches to off (NO=Normally Open).
So the relay doesn't consume any power while being in a specific position.
Do you guys know any type?
Thanks :)

google latching relay ..... two different types available

Finally, I found it!
Google Image:
https://www.google.com/search?biw=1974&bih=1050&tbm=isch&sxsrf=ACYBGNSImNFTI2vRTPD5bbjE-eRkJUzdow%3A1571311366907&sa=1&ei=Bk-oXcSJN5K78gKG4brgCw&q=HFD2%2F005&oq=HFD2%2F005&gs_l=img.3..0j0i24l6.1135292.1138931..1139132...0.0..0.80.289.4......0....1..gws-wiz-img.......0i5i30j0i30.yfdL1Ivd0sU&ved=0ahUKEwjEpOz-lqPlAhWSnVwKHYawDrwQ4dUDCAc&uact=5
Aliexpress:
https://www.aliexpress.com/item/32988578668.html?spm=2114.13010708.0.0.57a64c4dkzjFcM

Digikey.com & Mouser.com also offers a wide range of latching relays with same day shipping available.


text:
Program only works with Serial.begin
My program only works when the following line is added:
Serial.begin(9600);

When this is disabled/removed the program no longer switches output state regular
I'm using an Arduino Mega 2560.
When the line is added:

The output is switched ON or OFF regular around every 1sec.

When the line is removed:

The output is switched after 1 sec (as expected) but then switched multiple times after around 3 sec.
I tried with another Arduino Mega 2560: This time, the output is switched after 1sec (as expected) but then switched multiple times right after (and not after around 3 sec).

What could be the problem?
My code:
byte inputPin2 = 2;
byte inputPin3 = 3;
byte outputPin = 13;
boolean outputPin_HIGH = false;
volatile short angle = -18;

void setup() {
  Serial.begin(9600);      //<----------------------
  pinMode(hallSensorPin, OUTPUT);

  pinMode(inputPin2, INPUT_PULLUP);
  pinMode(inputPin3, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(inputPin2), ISR_addAngle, CHANGE);
  attachInterrupt(digitalPinToInterrupt(inputPin3), ISR_addAngle, CHANGE);
}

void ISR_addAngle() {
  angle = angle + 18;
}

void loop() {
  if (angle == 900) {
    if (outputPin_HIGH) {
      digitalWrite(outputPin, LOW);
      outputPin_HIGH = false;
    } else {
      digitalWrite(outputPin, HIGH);
      outputPin_HIGH = true;
    }
    angle = angle - 900;
  }
}

"When this is disabled/removed the program no longer works..." is not very informative. What, exactly, doesn't work? What were you expecting to happen? What happened instead?

When the line is disabled/removed the program no longer receives the regular interrupts and the output therefore no longer switches state.
When the line is added:
The output is set (switched ON and OFF) regular around every 1sec.
When the line is removed:
The output is set after 1sec (as expected) but then set multiple times after around 3 sec.

... or I think that the interrupt works (I can see that a signal is sent to the interrupt pin), but as I can't serial.print a flag, I don't know if it really works...

The program works fine with it, but I want to remove it (it was only for debugging)

you can store the flag values in an array ... when you reach some desired number of values stored, then call a function to do serial.begin and print out the values

I'm guessing, but it sounds like the 'proper' operation depends on UART interrupts which go away without 'Serial.begin()'. Can you confirm your sensor is indeed signaling as you expect it to?

@JRobert The interrupt comes from a driver and not a sensor (A LED lights up when it sends a signal), and I'm sure that the signal is sent as usual. I ran the code with "Serial.begin(9600);" with no problem and right after again without, with errors. I therefore also don't think there should be a problem with the signal that triggers the interrupt.

@jsotola I will try that tomorrow. But I'm sure that I get the expected flags at the right time when "Serial.begin(9600);" is used. I rather want to debug this error without serial.

It looks like you're using a ATMega328P-based Arduino (UNO,  Nano, etc).  But, you should probably say what you're using and remove all doubt.

@timemage I'm using an Arduino Mega 2560. I tried with another Arduino Mega 2560: This time, the output is switched after 1sec (as expected) but then switched multiple times right after (and not after around 3 sec).

It works without "Serial.begin(9600)" when using an Arduino Micro Pro (ATmega32u4). Here, pin 0 and pin 1 are used as the inputs to the interrupts. Nothing else is changed in the code. Sadly is this not a solution to the problem...

"output is switched after 1 sec (as expected)" why is 1 second expected?

When adding "Serial.begin(9600)" the "1 sec" is around that time I normally expect the output to switch. Without, it is very different. Why should that line matter?!?


text:
Problems with Draw Loop using u8glib
I am using an Arduino Mega and a 12864ZW LCD with the u8glib library and the following code to draw to the LCD:
U8GLIB_ST7920_128X64 Display(LCD_E_PIN, LCD_RW_PIN, LCD_RS_PIN, U8G_PIN_NONE);

void loop(){
   Draw();
}

void Draw(){
   Display.firstPage();

   do{
      Display.setPrintPos(10, 10);
      Display.print("This is a test");
   }while(Display.nextPage());
}

The problem is that the display is constantly redrawing itself. When I used LCD displays in the past, they usually only required to write to the LCD once unless you wipe the display. When I adjusted the code to:
U8GLIB_ST7920_128X64 Display(LCD_E_PIN, LCD_RW_PIN, LCD_RS_PIN, U8G_PIN_NONE);
bool needsUpdate = true;

void loop(){
   Draw();
}

void Draw(){
   if (needsUpdate){
       Display.firstPage();
       do{
          Display.setPrintPos(10, 10);
          Display.print("This is a test");
       }while(Display.nextPage());
       needsUpdate = false;
   }
}

I do not get anything drawn on the LCD. Is there a parameter that needs to be set so I only have to redraw the LCD if something changes? Am I using an outdated library? Is there a better library I should be using?
EDIT
I think the main problem I have with using this library is does the Draw loop need to be executed continuously to display on the LCD or is there a way to only draw the screen once until it is needed to be drawn again?

You haven't shown us all the code – in particular, the call to Draw() from loop() is missing – so this answer is speculative, based on the assumption your loop() is as follows.
void loop(void) {
    Draw();
}

If so, your first bit of code will constantly redraw because loop() runs repeatedly without delay.  Try adding a delay(1000); after Draw() in that case.
Your second bit of code will begin by drawing your image once, and in that Draw() call it will set needsUpdate to false.  Then loop() runs again, and the firstPage() call erases the screen.  Since needsUpdate now is false and remains false, subsequent calls don't draw an image.
Rather than putting your picture loop into Draw(), perhaps use Draw() just to draw primitives, and keep your controls in loop():
void loop(void) {
  Display.firstPage();
  do {     // picture loop
    Draw();
  } while( Display.nextPage() );
  delay(1000); // delay before next picture
}

If you still get repeated fast redraws, for troubleshooting comment out the do and } while lines.

Thanks for the answer, I updated my question with the missing bits and also changed where the firstPage is located but still getting the same results. I tried commenting out the while loop when I do nothing gets drawn.

@AndyBraham, does thelloworld work ok (changed to use your own constructor) ?  If so you may need to add font selection, eg  Display.setFont(u8g_font_unifont);, in your own Draw, and/or drawStr vs print

Yes the Helloworld example you gave works fine. I guess my main hangup is that the LCD has to have a loop going all the time instead of only when things need updating and how long the Display takes to redraw each time. Seems to me that it is requiring allot of time to refresh the screen if it has much to draw. I will eventually have some highlight functionality that will be driven from Buttons and I am trying to figure out how the lcd code should work. As it is performing now the Draw is taking so much time that any inputs won't be caught.

@AndyBraham, you might be able to just call nextPage() after each Draw() call (to tell u8g drawing is done) and ignore its output [1 or 0 as another Draw is needed or not].  I haven't looked closely but imagine nextPage() is supposed to test whether new objects being drawn have made a write-from-scratch necessary.  If you already know that from how you update the image, just ignore output of  nextPage().  Re inputs, use PCI's, pin-change-interrupts, which can happen and probably can be handled during drawing.

Thanks a bunch! You got me on the right track, I posted an answer on here that shows the correct way (I feel) that this should be done.

Much thanks to jwpat7 for getting me on the right track with this. So I found out how this LCD should really be setup. I am not sure why the examples I was able to find online and even on the u8glib wiki showed the usage like my question but I was able to get this library functioning right.
First thing is the .firstPage() and .nextPage() functions. The .firstPage() function actually clears the screen and the .nextPage() function displays what is waiting in the queue (thanks jwpat7). When the .nextPage() finishes there is no need to write to the LCD again until you need a refresh. I put together a very simple code example that uses a input to change the text without having to continuously update the LCD.
U8GLIB_ST7920_128X64 Display(LCD_E_PIN, LCD_RW_PIN, LCD_RS_PIN, U8G_PIN_NONE);
bool redraw = true;
String strOut = "This is a test...";

void loop() {

    if (redraw){
        Display.firstPage();  //Clear the LCD

        //Main Difference while the LCD needs drawing will return 1
        while(Display.nextPage()){
            Display.setFont(u8g_font_04b_03b);
            Display.setPrintPos(20, 20);
            Display.print(strOut);
        }

        redraw = false;  //Clear flag to redraw
    }

    //check if any of the pins in PINA have been pressed
    if (~PINA & 0xff){
        strOut = "Of the emergency broadcast ...";

        redraw = true; //Set flag to redraw the screen
    }
}


text:
How to check if a pin is set from bank?
How would you go about checking if an input pin has been set using the entire bank? I am thinking that I need to use bit twiddling with a bit mask but I have not used this enough to figure out how to do what I want.
Basically I have the following code:
void setup() {
   DDRA = 0x00;
   PORTA = 0xff;
}

void loop(){
   //Check if any pin from Port A has been pressed
   if (PINA & 0xff){
      //do stuff
   }
}

But the code above is not working how I expected it to. Has anyone tried to use this approach before? Am I going about this the wrong way? I figured since I was using all 8 pins from one bank, it would be better to check if any of the pins on that bank have been set instead of checking each individual pin. My thinking on this was to prevent any user input from being skipped in case a button press was initiated while the program was running other code. This way I only check if anything in the bank has been set saving time (I think).

If you attached the buttont towards ground then the "pressed" state is the 0, so "any button pressed" is coded in the instruction if (PINA == 0xff) or if (~PINA & 0xff).

The problem is here:

//Check if any pin from Port A has been pressed
if (PINA & 0xff){

Since the pullups are enabled, the default state of the pins is high. To detect a "press", they have to be pulled to ground. This changes the test to:
//Check if any pin from Port A has been pressed
if (~PINA) {

And for individual pins:
//Check if PA3 has been pressed
if (!(PINA & _BV(PA3))) {

When I run the code if (~PINA) it always enters the loop no matter what. Did this work for you, did you test this?

I tried your code and it will always enter the loop but if you change the code to if(~PINA & 0xff){ ... } it works.

~PINA assumes that all 8 pins are being used for active-low input. If only part of the port is being used then you need to mask the pins in use.

I'm not really an expert in "plain avr code" but I've modified arduino blink and got (almost) a perfect example. Placed a jumper between 5v and pin 8 of arduino and uploaded the following code:
void setup() {
  // initialize digital pin 13 as an output.
  DDRB = 0b00100000;

}

// the loop function runs over and over again forever
void loop() {
  if (PINB & 0x1) {
    PORTB =  0b00100000;  // turn the LED on (HIGH is the voltage level)
    delay(500);              // wait for a second
    PORTB = 0;    // turn the LED off by making the voltage LOW
    delay(500);              // wait for a second
  }
}

according to following picture pin8 on arduino is PB0 and pin13 is PB5. So using DDRB I set PB5 as output and all others as input. Then in loop I check as you do PINB register and use bitmask to check first pin (the PB0). And it works... well not quite well. For some reason the loop goes a few times more before goes really low. I believe is because I just remove the jumper and do not actually ground pin 8 ( is left float) and maybe the extra loops are discharging some capacitance on that pin 8.

(source: arduinoexperts.com)
So, to your specific question, your bitmask is right. This instruction PORTA = 0xff; is useless because, as far as I know, this settings are ignored because you set Pin direction in pins of PORTA to input. However, according to that image, atmega328 doesn't have a PORTA. Is that your error or are you using another microcontroller?
EDIT Capacitance thing is confirmed, maked it swing between gnd and vcc   with a switch and all works fine.

"This instruction PORTA = 0xff; is useless" Incorrect. On modernish, largish AVRs this sets the state of the internal pullup resistor.

@IgnacioVazquez-Abrams Thanks for pointing that out. And reading your answear it all makes sense. Always learning :)

The simplest way is to use DigitalRead in a loop. It makes your code more portable, and easier to read.

The whole point was so I didn't have to read each Pin individually, I will have many more Inputs eventually and the time spent checking each Input might not catch everything.

There's a maximum of 20 inputs on the Uno; at 16 mhz, you would be checking them at hundreds of thousands of times per second (that gives you 8 instructions per pin). Sometimes you need that; often you don't.