message:
Replacing large lookup table with switch statement

My arduino needs to take a 14-bit number and convert it to a 10-bit number. Can't use a formula for it since the data is quite random. So I created a lookup table with 2^14 elements, each containing a 10-bit value. But it's too big to fit on the arduino. So I thought of using a switch statement instead. Would this result in a significant speed decrease?

Say, for example, that the input value is 16383. How much longer would it take for the arduino to iterate through the 16384 cases compared to accessing index #16383 of an array?

EDIT: This code compiles fine and reports a program memory usage of 1000 bytes.
```
int xval;
int yval;

void setup() {
  // put your setup code here, to run once:
}

void loop() {
  xval = random(0,16383);
  switch (xval) {
  case 0:
  yval = 0;
  break;
  case 1:
  yval = 4;
  break;
  case 2:
  yval = 4;
  break;
  case 3:
  yval = -60;
  ...
  case 16383:
  yval = 1023;
  break;
}
}
```
However, I haven't tried if it really works so maybe the compiler is optimizing away too much.

EDIT 2: Added the line ```Serial.println(yval);``` so that I'm actually doing something with yval as Majenko commented. And now it doesn't compile :'( :'( :'(

So, I'll tackle my problem in some other way.

body:
214 is 16384 entries. Each entry takes 2 bytes. That's 32768 bytes. That's all the flash the ATMega328P has.

The most efficient storage will be an array in flash, and that will take 100% of it. Using a switch will take more space.

So in short: no. Just no. It won't work whatever you try. You need to come up with a radically different storage solution (external flash memory?) or use a larger chip.

----

As a side note, with "bit packing" you could reduce the storage to 20480 bytes, but doing a lookup of the data within that packed data (4 10-bit entries taking 5 bytes) will be slow to do since you have to work out exactly what combination of bits and bytes you need to reconstruct your 10-bit value.


sender: user

sender: assistant

body:
### Almost certainly not

Compilers often optimise switch statements using **[jump tables][1]**. However the entries in the jump table basically make up a lookup table with 214 entries! So you don't gain anything.

### Some ideas for compression

* You can use bit packing

If your numbers aren't 8 bits in size, you can pack them together. For example, if you have managed to code things in 6 byte chunks, you can squash 4 of these chunks into 3 bytes, to shrink a table by 25% (at the expense of some bit shifts when retrieving entries.)

* Take advantage of frequency of duplicates

You say you have duplicates. But how many "very common" duplicates are there?

If, say, 90% of your values come from a group of 15 possible values, then you can pack 2 entries per byte, each one represented by a value from 0-14. If one of the entries is 15, then that that value is an "exception" and is looked up by [binary search][2] in a second table.

This would result in a table of size 8KB plus the size of the other table (say 4KB when you pack the 14 bit index and 10 bit value into 3 bytes.)

If you instead have a set of 254 possible "common" values, then your main table would be more like 16KB. That *might* be doable.

* Is there *any* relation between input and output?

Maybe there is no formula, but there might be properties of the input that affect the properties of the output. (For example, maybe most input values 0-1024 have an output that is similar plus or minus 30.)

* Write a program to find patterns in your data

Don't just use your eyes. Write a script (Python?) to count the frequency of each output value, or compare inputs to outputs, or evaluate your suspicions about the data. Graph input vs output.

  [1]: https://en.wikipedia.org/wiki/Branch_table
  [2]: https://en.wikipedia.org/wiki/Binary_search_algorithm


message:
Arduino MySQL Connector Issues with Select only

first question i am doing so hope this is the right place.

I have an issue with an Arduino Uno and an Arduino ESP8266WiFi Shiald by WangTongze using this tutorial (https://www.instructables.com/id/ESP8266-ESP-12E-UART-Wireless-WIFI-Shield-TTL-Conv/) I have been able to connect to the my Wifi and host a small webserver.

Then with the Examples of the MySql Connector Library I have been able to do a simple Insert to a MySQL Database on a NAS Server. However, I want to be able to select a value from my DB and print it on the screen for some reason the Cursor always returns a null. I have been able to select from my PC using the same user. and created the user francis@% so that the host isn't an issue. Please note that this same code with a few tweaks worked to insert a record to the same table. Is there anything I am missing? Below is the code:
```
//#include <WiFi.h> // Use this for WiFi instead of Ethernet.h
#include <WiFiEsp.h> //use for ESP8266
#include <MySQL_Connection.h>
#include <MySQL_Cursor.h>

// Emulate Serial1 on pins 2/3 if not present
#ifndef HAVE_HWSERIAL1
#include "SoftwareSerial.h"
SoftwareSerial Serial1(2, 3); // RX, TX
#endif

byte mac_addr[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

IPAddress server_addr(192,168,x,x); // IP of the MySQL server here
char user[] = "francis";
char password[] = "xxxxxx";

// WiFi card example
char ssid[] = "PintoLoco"; // your network SSID (name)
char pass[] = "xxxxxxxx"; // your network password

//WiFiClient client; // Use this for WiFi instead of EthernetClient
WiFiEspClient client; //Use this for ESP8266
MySQL_Connection conn((Client *)&client);
MySQL_Cursor cur = MySQL_Cursor(&conn);

char query[] = "SELECT Value FROM Peceras.Parameters ";

void setup() {

  Serial.println("Starting....");
  Serial.begin(115200);
  // initialize ESP module
  WiFi.init(&Serial);
  Serial.println("Connecting to WiFi");

  // Begin WiFi section
  int status = WiFi.begin(ssid, pass);
  while(status != WL_CONNECTED){
      status = WiFi.begin(ssid, pass);
    }
  // print out info about the connection:

  Serial.println("Connected to network");
  IPAddress ip = WiFi.localIP();
  Serial.print("My IP address is: ");
  Serial.println(ip);

  // End WiFi section

  Serial.println("Connecting...");
  if (conn.connect(server_addr,3306,user,password)) {
  delay(1000);
  }
  else
  Serial.println("Connection failed.");
}
MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);
void loop() {
  row_values *row = NULL;
  long head_count = NULL;
column_names *cols = cur_mem->get_columns();
cur_mem->execute(query);
  // Execute the query
  do {
    row = cur_mem->get_next_row();
    if (row != NULL) {
      for (int f = 0; f < cols->num_fields; f++) {
        head_count = atoi(row->values[f]);
          Serial.print("Ingestelde Temperatuur:  ");
          Serial.println(head_count);
        if (f < cols->num_fields-1) {
          Serial.println(',');

        }
      }
      Serial.println();
    }
  } while (row != NULL);
  // Deleting the cursor also frees up memory used
  delete cur_mem;
  delay(2000);
}
```

body:
I have no access to a compiler, so there might be errors.

    #include <WiFiEsp.h>
    #include <MySQL_Connection.h>
    #include <MySQL_Cursor.h>

    #ifndef HAVE_HWSERIAL1
    #include "SoftwareSerial.h"
    SoftwareSerial Serial1(2, 3); // RX, TX
    #endif

    byte mac_addr[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

    IPAddress server_addr(192,168,x,x);
    char user[] = "francis";
    char password[] = "xxxxxx";

    char ssid[] = "PintoLoco";
    char pass[] = "xxxxxxxx";

    WiFiEspClient client;
    MySQL_Connection conn( (Client *) &client );
    MySQL_Cursor *cur_mem = null;

    // PPK: some database systems are case sensitive
    // so Peceras.Parameters is not the same as peceras.parameters
    // check if the tables and fields are named correctly.
    char query[] = "SELECT Value FROM Peceras.Parameters";

    void setup()
    {
      Serial.begin( 115200 );
      Serial1.begin( 115200 );

      Serial.println( "Connecting to WiFi" );
      WiFi.init( &Serial1 );
      int status = WiFi.begin( ssid, pass );
      while( status != WL_CONNECTED )
      {
        status = WiFi.begin(ssid, pass);
      }

      Serial.println( "Connected to network" );
      IPAddress ip = WiFi.localIP();
      Serial.print( "My IP address is: " );
      Serial.println( ip );

      Serial.println( "Connecting DB ..." );
      if ( conn.connect( server_addr, 3306, user, password ) )
      {
        Serial.println( "DB connected." );
        cur_mem = new MySQL_Cursor( &conn );
        row_values *row = NULL;
        long head_count = NULL;
        column_names *cols = cur_mem->get_columns();

        cur_mem->execute(query);

        do
        {
          row = cur_mem->get_next_row();
          if ( row != NULL )
          {
            for ( int f = 0; f < cols->num_fields; f++ )
            {
              head_count = atoi( row->values[f] );
              Serial.print( "Ingestelde Temperatuur:  ");
              Serial.println( head_count );
              if ( f < cols->num_fields - 1 )
              {
                Serial.println(',');
              }
            }
            Serial.println();
          }
        } while (row != NULL);

        // Deleting the cursor also frees up memory used
        // PPK: I'm not sure if this is a good idea, I don't know
        delete cur_mem;
      }
      else
      {
        Serial.println( "DB Connection failed." );
      }
    }

    void loop()
    {
      // PPK: I would recommend to do the select in the setup section
      // It looks like you want to run it just once
    }

**Edit**

Please note, that this code only works if you connect the software serial pins D2, D3 to the respective RX and TX pins on the Shield. You have to bend the pins (P0-P3) of the shield to disconnect them from the Arduino. Then you have to connect D2 and D3 to P0 and P1. This is described in step 1 of the instructables you linked to in the question. See the picture at the end of Step 1. https://www.instructables.com/id/ESP8266-ESP-12E-UART-Wireless-WIFI-Shield-TTL-Conv/


message:
How do I run a function every 10th time through a loop?

I currently have a function that poles all my sensors every time through it's loop, but I want to pole one of the sensors only every 10th time.  Currently there is a 10 millisecond delay at the beginning of my function.  I know I could increment a counter and use modulo, but is there a better practice for this?

body:
    for(int i=0; i < 9999; ++i)
    {
        if(i % 10 == 0)
        {
             //my actions on i = 0, 10, 20, 30 ...
        }
    }


body:
Normally it's suboptimal to reduce the speed of loop just to be able to count them.
Apply the BlinkWithoutDelay principle instead (which is not about Blink, but about **WithoutDelay**)


message:
Is there a way to make a function take an exact number of clock cycles?

Is it possible to use something like a compiler directive to pad a function with do nothing instructions so that as you add lines of code or take them away it always executes in the same amount of time?  I know there is the blink without delay style of writing a loop, but I want something a little more exact.

body:
To the best of my knowledge, there is not. What you speak of *is* possible, but it must be done manually by counting cycles, and I suspect it wouldn't actually help you. (And then you get into CISC issues where instructions can take different amounts of time to execute, potentially depending on arguments. Arduino (the actual one) is kinda safe from that, but branch instructions still take multiple cycles, for instance. This says nothing about all the boards that work with, but aren't, Arduinos.)

There are two potential routes for this.

 1. If this is for crypto, where you want to avoid side-channel attacks by detecting the length of an authentication or hashing function, it's not a good idea. Use a well-known library to do it instead, since in practicality it's not a good or safe idea to write your own (although if it's for a homemade door lock or safe lock, it's *probably* not a relevant issue since there are larger and more important security issues that will likely be found first despite your best efforts).
 2. If, as I suspect, you simply want a piece of code to run at very precise time intervals, I suggest you look up something like the FreeRTOS port for Arduino. That will let you schedule a task to run preemptively so that it will always run at intervals. The BWOD sketch is still quite accurate, mind you, and below is a self-correcting version that compensates for any times that it might run a bit late (meaning that it should ALWAYS execute with millisecond precision, repeatably):

```
  unsigned long currentMillis = millis();//and you could always use micros()

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis += interval;//adjustment for additional accuracy

    //The task you want to run would go below:
    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
```

The caveat to your stated goal is that any microprocessor WILL NOT execute code exactly when you want. Arduino too is incapable of this, since even a blank sketch runs several interrupts that will take over the processor for short periods of time, causing your hypothetical sketch to be delayed. You HAVE to use a reference method like BWOD or a scheduler like FreeRTOS. These use a reference or set up their own interrupt to make sure that they run on time, with the only interrupts that could be an issue being the ones that run during that instance of the task.

What this means is that they have a bit of overhead to add spacing between tasks so that if one is delayed, it won't cause the next to run late. So do mind that you'll lose a *quite* small percentage of CPU time to your scheduler, but if that's really an issue, find a better board (like TI TIVA/Energia IDE).


body:
You can use a timer with prescaler set to 1 in combination with a counter module. Attach interrupts to the compare and the overflow events. In the corresponding ISRs you handle the counting...
I have no example for you and it might be a bit tricky how to implement the ISRs, but it's possible for sure, as long as you count a reasonable amount of clock cycles (firing an interrupt each cycle e.g. will not work as the calculations in the ISR take some time).


message:
Can't use millis() instead of delay

I am making a home coming/leaving light for car. First I want that whenever I press the car key lock, a timer will start for 10 seconds. And if I press a button twice within 10 seconds, pin 13 will remain high for 10 seconds. If I don't press the button it returns to the void loop or condition may get false. I am working on it but I'm not getting the correct approach. I'm not able to use `millis` twice in this program.

```c++
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;
unsigned long previousMillis = 0;
const long interval = 5000;

void setup() {
  Serial.begin(9600);
  pinMode(8, INPUT_PULLUP);
  pinMode(13, OUTPUT);
}

void loop() {
  unsigned long currentMillis = millis();
  buttonState = digitalRead(8);
  if (buttonState != lastButtonState) {
    if (buttonPushCounter <= 2) {
      if (buttonState == LOW) {
        buttonPushCounter++;
        Serial.println("on");
        Serial.print("number of button pushes: ");
        Serial.println(buttonPushCounter);
        if (buttonPushCounter % 3 == 0) {
          if (currentMillis - previousMillis > 10000) {
            digitalWrite(13, HIGH);
            previousMillis = currentMillis;
          } else {
            digitalWrite(13, LOW);
          }
        } else {
          digitalWrite(13, LOW);
        }
      } else {
        digitalWrite(13, LOW);
      }
    } else {
      buttonPushCounter = 0;
    }
    lastButtonState = buttonState;
  }
}
```

body:
Here is what you have asked for:

> I am making home coming/leaving light for car. First i want that
> whenver i press car key lock a timer will start for 10 second.And if i
> press button twice within 10 second pin 13 will high remain for 10
> second and if i cant press the button it return to the void loop aor
> condition may get false. I am working on it but dont getting the
> correct approach . But i am not able to use millis twicely in this
> program.

So, I have refactored, and done my best to interpret your words, and the code that you wrote.

You will see that I broke down quite a bit the deep nesting of your code into separate methods.  I hope that you see that it makes it more readable and understandable.

I have replaced the "magic numbers" like `10000` with more readable code like `tenSeconds`.  And I hope the code does what you want now, but I'm not sure.  Hopefully the readability has improved enough that you can massage and reshape the code into what you want it to do, as well as shown you what direction to head when you don't understand your own code because it has grown (deeper, longer, more complicated, etc.) as most code does.

In the professional coding world, allowing code to remain like that is called "not paying down your design debt" and you (or your organization) will pay the consequences, with interest, just like a credit card.

Finally, note that my comments don't restate the code, but tries to add something (mine often tries to finish sentences involving readable code).  My comments also tend to be on the ends of lines to try to stay out of the way.

This code compiles, but has not been tested on an actual Arduino.  Please let me know if this meets your need, and please choose this as the answer if it does answer your question, and at least please vote up the answer if it doesn't quite answer you...   ...and give me a second chance, if possible.  Thanks.

    // pins defined and named
    int pin_button = 8;         // button Pin
    int pin_LED = 13;           // LED Pin

    int currentButtonState = 0;         // current state of the button
    int lastButtonState = 0;

    int buttonPushCounter = 0;   // counter for the number of button presses
    unsigned long currentMillis = 0;
    unsigned long previousMillis = 0;
    const unsigned int tenSeconds = 10000; // 10,000 milliseconds

    void setup()
    {
        pinMode(pin_button, INPUT_PULLUP);
        pinMode(pin_LED, OUTPUT);
    }

    void loop()
    {
        currentMillis = GetCurrentMillis();
        if (ButtonIsToggled() == 1)
        {
            CountButtonPushes();
        }
    }

    int ButtonIsToggled()
    {
        int isToggled = 0;
        currentButtonState = digitalRead(pin_button);
        if (currentButtonState != lastButtonState)
        {
            lastButtonState = currentButtonState;
            isToggled = 1;
        }
        return isToggled;
    }

    void CountButtonPushes()
    {
        int valueToWrite = LOW; // LED-OFF is default value unless overridden

        if (currentButtonState == LOW) // we just toggled from HIGH to LOW...
        {
            buttonPushCounter++; // We've successfully completed another button-press
            if (buttonPushCounter % 3 == 0) // if (buttonPushCounter==3) should be faster
            {                               // because compare is faster than division
                buttonPushCounter = 0;  // Reset
                valueToWrite = HIGH; // LED-ON
            }
        }

        if (valueToWrite == HIGH) // LED is ON
        {
            digitalWrite(pin_LED, HIGH); // valueToWrite
            while (currentMillis - previousMillis < tenSeconds)
            {
                // do nothing -- wait while LED is on
                // busy wait. Consider sleeping instead.
                currentMillis = GetCurrentMillis();
            }
            previousMillis = currentMillis;
            digitalWrite(pin_LED, LOW);
        }
    }

    unsigned long GetCurrentMillis()
    {
        return millis();
    }


message:
Can someone help me decipher the code for the arduino? I am totally lost

The code is as follows:

    void loop(){

        light = analogRead(5);
        Serial.println(light);
        analogWrite(3,light/4);

    }

body:
Not really a physics question, but I will answer anyway.

`loop()` is the standard Arduino function which contains code that the microprocessor runs repeatedly (as opposed to code in `setup()` which is only run once).

`light = analogRead(5);` takes an analogue voltage reading from pin 5, encodes it as an integer value (either 10 or 12 bits depending on the Arduino model) and stores the result in the variable `light`.

`Serial.println(light);` outputs the value of the variable `light` to the Arduino's serial port. This is a standard way of outputting data from the Arduino so that it can be displayed on a connected computer.

`analogWrite(3, light/4);` outputs the value of `light/4` as a phase-width modulated (PWM) signal to pin 3. Although Arduino output pins are either on (5 volts) or off (ground) at any point in time, PWM signals allow the Arduino to switch an output pin on and off rapidly so that the average voltage seen on that pin is an intermediate value. The duty cycle of the PWM signal which determines the average voltage on the pin is encoded as an 8 bit integer, so `light` is probably divided by 4 here to convert it from 10 bits to 8 bits.

So the Arduino will repeatedly read an input voltage from pin 5, output an integer representing this voltage to the serial port, and create a PWM signal on pin 3 that has an average voltage the same as that of the input voltage.

See the [Arduino language reference page][1] for more information.

  [1]: https://www.arduino.cc/reference/en/


message:
Difference in increment & decrement loop execution speed

I was experimenting with for loops when I noticed that a simple increment loop executes faster than a decrement loop. I can't think of any reason why it should be like that. Is there something in my code that is causing the different in execution speed?

The code is as follows:

    // Global Variables
    const int spk = 7;
    const int led = 6;
    int j = 0; // counter variable

    void setup() {

      pinMode(spk, OUTPUT);
      pinMode(led, OUTPUT);
      Serial.begin(9600);
    } // end of setup

    void loop() {

      tone(spk, 300, 500); // first note with duration

      // increment loop
      for (j=0; j <= 500; j = j + 1) {
        digitalWrite(led, HIGH);
        Serial.println(j);
      } // end 1st note loop

      tone(spk, 100, 500); // second note with duration

      // decrement loop

      for (j = 500; j >= 0; j=j-1) {
        digitalWrite(led, LOW);
        Serial.print("the value is=");
        Serial.print("\t");
        Serial.println(j);
      } // end 2nd Note loop

    } // end setup

body:
In the code you posted, the decrement loop has two more Serial.print() statements.

Serial.print() takes a lot of time and while it's useful for debugging, it sometimes can cause additional bugs because of the extra delay it introduces if you are running time-sensitive code.

Consider for using Serial.print("the value is=\t" + itoa(j,10));

"itoa" converts an integer to an array of characters (aka string). As Juraj said, it takes another two arguments which are the buffer to store the output string and the base to which it converts the incoming number to be represented by (eg: 10 is decimal, 16 is hexadecimal). It returns a pointer to the output string which is essentially the same as the second argument but AFAIR you can omit the second argument and use it's return value.


body:
Comment out these 2 lines

    Serial.print("the value is=");
    Serial.print("\t");

And report back on the speed difference.
Why not add a reading of micros() before and after each loop and see how much difference there really is?  All time variables are unsigned long.

    startTime = micros();
    // your loop
    endTime =  micros();
    duration = endTime - startTime;
    Serial.println (" "); // line break
    Serial.print ("duration in uS = ");
    Serial.println (duration);

I edited to add some missing )s and a 2nd line break.


message:
How to make an arduino button to forget his past purpose?

For my school project im making an arduino speedometer for a bicycle. I will be using a reed switch sensor to get the speed. There will also be an clock and a termometer, it will be on a 16x2 lcd screen. To get the speed I will need the user to type in his bike size, in zoll. I managed to let the user tap the button until his size and then double tap the button to confirm it. Alright, fine. Now I need the same button to FORGET his last purpose. Because I want to use the same button to change the screen between speed, clock and termometer. SPEED -> tap -> CLOCK -> tap -> TEMPERATURE -> tap -> SPEED ........

I hope you get the idea. After the user picks his size, if he keeps tapping the number it would just keep on growing. So, im trying to make the button forget, or make him go trough that loop only once.

Pick your size tap tap tap double tap, thank you. And stop! I want him to do that only once and never again. I will need the same principle when the user will adjust his clock, he will have to tap to set it, save the number but reset the buttons function.

    #include <LiquidCrystal_I2C.h>
    #include <LiquidCrystal.h>
    LiquidCrystal_I2C lcd(0x27, 16,2);
    #define buttonPin 7
    int a = 16;
    int b = 0;

    void setup() {
      lcd.init();
      lcd.backlight();
      lcd.print("RADGROESSE IN");
      lcd.setCursor(0, 1);
      lcd.print("ZOLL EINGEBEN");

       // Set button input pin
       pinMode(buttonPin, INPUT);
       digitalWrite(buttonPin, HIGH );
    }
    void loop() {
       int b = checkButton();
       if (b == 1) clickEvent();
       if (b == 2) doubleClickEvent();
    }
    void clickEvent() {

       lcd.setCursor(14, 1);
        lcd.print(a);
        delay(100);
        lcd.print(" ");
        delay(100);
        a++;
        delay(100);
        if(a >= 23){
          a = 16;
          }
    }
    void doubleClickEvent() {
          b = a - 1;
          Serial.println("Button was idle for one second or more");
          lcd.clear();
          lcd.print("ZOLL = ");
          lcd.setCursor(7, 0);
          lcd.print(b);

    }

    //=================================================
    //  MULTI-CLICK:  One Button, Multiple Events

    // Button timing variables
    int debounce = 20;          // ms debounce period to prevent flickering when pressing or releasing the button
    int DCgap = 420;            // max ms between clicks for a double click event
    // Button variables
    boolean buttonVal = HIGH;   // value read from button
    boolean buttonLast = HIGH;  // buffered value of the button's previous state
    boolean DCwaiting = false;  // whether we're waiting for a double click (down)
    boolean DConUp = false;     // whether to register a double click on next release, or whether to wait and click
    boolean singleOK = true;    // whether it's OK to do a single click
    long downTime = -1;         // time the button was pressed down
    long upTime = -1;           // time the button was released

    int checkButton() {
       int event = 0;
       buttonVal = digitalRead(buttonPin);
       // Button pressed down
       if (buttonVal == LOW && buttonLast == HIGH && (millis() - upTime) > debounce)
       {
           downTime = millis();
           singleOK = true;
           if ((millis()-upTime) < DCgap && DConUp == false && DCwaiting == true)  DConUp = true;
           else  DConUp = false;
           DCwaiting = false;
       }
       // Button released
       else if (buttonVal == HIGH && buttonLast == LOW && (millis() - downTime) > debounce)
       {
               upTime = millis();
               if (DConUp == false) DCwaiting = true;
               else
               {
                   event = 2;
                   DConUp = false;
                   DCwaiting = false;
                   singleOK = false;
               }
       }
       // Test for normal click event: DCgap expired
       if ( buttonVal == HIGH && (millis()-upTime) >= DCgap && DCwaiting == true && DConUp == false && singleOK == true && event != 2)
       {
           event = 1;
           DCwaiting = false;
       }

       buttonLast = buttonVal;
       return event;
    }

Thank you! I would really appreciate it!

body:
What you likely need is a state machine. The behavior of the actions depends on the state the program is currently in.

In your case, the state machine might look like this:

[![State machine][1]][1]

What does it mean?

* black circle: this is where the system powers on
* rectangle: a state
* arrow: a transition from one state to another
* green text: action

For the problematic double click action, you can see:

* it changes the state from "set size" to "speed"
* in all other cases, it does not change the state (actually it changes the state to the same state)

I always recommend drawing the state machine before implementing it. It makes mistakes much more obvious.

There are several ways to implement it. The easiest one being a `switch/case`. More advanced implementations may use object orientation. When using `switch/case`, I prefer to have one method per state, like so:

    void loop()
    {
        switch(state):
            case setsize:
                 setsize();
                 break;
            case speed:
                 speed();
                 break;
            ...
    }

If you know about function pointers, it gets even easier:

    enum State {
      setsize = 0,
      speed,
      clock,
      temperature
    };

    State state;

    void setup() {
      state = State::setsize;
    }

    typedef void (* functionPointer) ();
    functionPointer process[] = {do_setsize, do_speed, do_clock, do_temperature};
    void loop() {
      process[state]();
    }

    void do_setsize()
    {
      state = State::speed;
    }
    void do_speed()
    {
      state = State::clock;
    }
    void do_temperature()
    {
      state = State::speed;
    }
    void do_clock()
    {
      state = State::temperature;
    }

  [1]: https://i.stack.imgur.com/wHuRf.png


body:
jsotola wrote a very important term in the comments: state.

You should implement your project as a Finite State Machine (FSM), a very important and powerful, yet easy principle. You divide your program into different states. Each state contains code, that only gets executed, when the program is in this state. Depending on input events (like the user pressing the button), you do transitions between the states.

I already wrote a rather detailed answer about FSMs for [this question][1]. You can read it to get a better understanding of FSMs.

For your case I would suggest these states: `INPUT_SIZE`, `DISPLAY_SPEED`, `DISPLAY_CLOCK` and `DISPLAY_TEMPERATURE`. `INPUT_SIZE` is the initial state (which you might skip after the first power on, after you saved the size in persistent memory like EEPROM). There you execute your current button code. When you sense a double tap on the button, you change to the `DISPLAY_SPEED` state. From there on a button press to the `DISPLAY_CLOCK` state and so on.

In my linked answer I used a simple integer variable as state variable, which holds the current state. In fact it is better (easier to read), when you define an `enum` for the cases (`enum`s are actually only named integer constants):

    enum State {INPUT_SIZE, DISPLAY_SPEED, DISPLAY_CLOCK, DISPLAY_TEMPERATURE};

    State state = INPUT_SIZE;

    void loop(){
        switch(state){
            case INPUT_SIZE:
                // Button code here
                // on double tap use the following line
                state = DISPLAY_SPEED;
                break;
            case DISPLAY_SPEED:
                // code for displaying speed here
            ...
        }
    }

That is just a little template for the structure. You need to fill it with life yourself.

  [1]: https://arduino.stackexchange.com/questions/63488/wanted-to-control-2-servos-with-serial-read


message:
Binary to decimal using bitwise operators

I am trying to convert some binary data to decimal numbers. I succeeded to convert binary to hex, but now I want to do the same with binary to decimal. I want to use bitwise operators and NO array.

See my code from binairy to hex. The incoming data is 8 bits. This code first calculates the most significant number, and then, the least significant number. This works good, but I cannot figure it out for bin to dec

The function `console_print_char` is sort of the printf function of my program.

        void console_print_hex_char(unsigned char data){
     unsigned char temp;

     if(data){
      temp = (data >> 4);
      if(temp){
       if(temp> 9) console_print_char(temp + ('A'- 10));
       else console_print_char(temp + '0');
      }
      temp = data & 0x0F;
      if(temp> 9) console_print_char(temp + ('A'- 10));
      else console_print_char(temp + '0');
     }
     else{
      console_print_char('0');
     }
    }

body:
You cannot do what you are trying to do. There is no direct correspondence between some number of bits and a decimal digit.

With hexadecimal, every 4 bits corresponds to exactly 1 hex digit. That is why hex is used for computers.

One hex digit represents exactly 4 bits. Every time you add another hex digit, you add 4 bits.

Two hex digits corresponds to exactly a byte. 00h to FFh represents a value from 0 to 255.

There is no such direct correspondence between binary and decimal. If you have 4 bits, it takes 1 or 2 decimal digits to represent it (0-15) If you have 8 bits, it takes 1, 2, or 3 decimal digits to represent it, but there are 3 digit decimal values (values > 255) that you can't represent with 8 bits.

    Binary  Hex Decimal
    0000    0   0
    0001    1   1
    0010    2   2
    0011    3   3
    0100    4   4
    0101    5   5
    0110    6   6
    0111    7   7
    1000    8   8
    1001    9   9
    1010    A   10
    1011    B   11
    1100    C   12
    1101    D   13
    1110    E   14
    1111    F   15

You simply cannot convert a binary number to decimal using bit shifting and masking.

As @Kwasmich says in their answer, the closest you're likely to come would be to convert your binary value to BCD (Binary coded decimal) where each 4 bits holds a decimal digit. You could convert THAT to decimal character output using masking and shifting.


body:
here's the c++ code
```
    vector<int> b={1,0,1,0,1,0,1};
        int sum=0;
        for(int i=b.size()-1, j=0; i>=0; i--, j++){
            sum+=b[j]*(1<<i);
        }
        return sum;
```


message:
Sleep mode and watchdog at the same time

Suppose we want to save battery power, and we use sleep mode and also prevent the Arduino from hanging and use the watchdog timer.

The problem is here that when the Arduino goes to sleep the watchdog timer never (or can't be) reset again because of sleep and it will overflow over and over and reset the Arduino over and over.

So what do you suggest to solve this problem, I mean running sleep mode and watchdog timer at the same time in a code?

body:
When you sleep the Arduino *is* locked up. So yes, the watchdog timer will time out and reset the Arduino.

But, since you're in sleep mode, it's not so much a "reboot" as a "wakeup".

The watchdog timer is one of the normal ways of waking up periodically to do things.  If you want to use the watchdog for its other "anti-lockup" purpose then you will have to arrange some other way of waking up before the watchdog is due to expire so you can "kick" it.

Or you disable the watchdog entirely before going to sleep so that the only wakeup source is whatever source you have configured. Then you can turn the watchdog on again when you wake up.

However that probably means that the watchdog is useless, since chances are you won't be awake for long enough periods for the watchdog to have any effect.

Sleeping and using the internal watchdog as a watchdog are pretty much mutually exclusive.  If you sleep, then the watchdog is a periodic wake-up source.


body:
Either set the watchdog to 8s, and setup the WDT interrupt. And deal with the fact that the MCU wakes up every 8s. You could have it go back to sleep, unless a button is pressed, or something. The extra power usage for these short wakeups is negligible in most cases.

Or disable the watchdog right before sleeping, and enable right after waking up. And hope the MCU never hangs in between.


message:
I am facing a problem of firing multiple interrupts on nodemcu 1.0 on single rising edge pulse.what is problem and what are the solutions?

I am working on a project which involves counting the drops falling in a drip chamber of a IV fluid gravity based therapy bottle(saline bottle).I am using IR trans-receiver at the drip chamber to detect a drop falling. I am using a comparator to generate a pulse when ir voltage drops below a certain threshold. The output of comparator is connected to D1 of nodemcu. The ISR is called at rising pulse of comparator .But the nodemcu calls the ISR 3 to 5 times on a single drop.what should I do?plz help.

body:
The signal is probably "bouncing" between HIGH and LOW instead of performing a clean edge, just like it happens with [buttons][1].

Two simple solutions:

 1. Hardware solution: use a schmidt-trigger instead of a comparator
 2. Software solution: define a dead-time for the signal aquisition (disable the interrupt when the desired edge has been detected and enable it again after "dead-time")

  [1]: https://www.allaboutcircuits.com/technical-articles/switch-bounce-how-to-deal-with-it/


message:
Interrupts inside a class attaching to the function of the class

Hello i have a class and i would like to attach an interrupt inside the class and attach it to a function of the class.

    class counter{
      public:

      counter(int pin){
        Ipin=pin;
      }
      void startCounting(){
        attachInterrupt(digitalPinToInterrupt(Ipin),this.addCount,CHANGE);
      }
      void stopCounting(){
        detachInterrupt(digitalPinToInterrupt(Ipin));
      }

      void addCount(){
        count++;
      }

      private:
      int Ipin;
      unsigned long count= 0;
    };

Some what of the code above. There can be multiple intialization of this class. hopefully depending on the user uses a different pin.

There is a way arround this where the attaching of pin is done in the loop or setup and just calling a public function of the class. But to me that kinda doesn't fit the spirit of classes like a properly made library is done.

Im not very good at programming if you could teach me how it would be greatly appreciated.

body:
I have [a post about this problem](http://www.gammon.com.au/forum/?id=12983).

Basically you cannot attach a class function with attachInterrupt because of the hidden "this" pointer which needs to be supplied to a (non-static) class function, where "this" is the particular instance of the class. You can work around it like this:

<!-- language: lang-c++ -->

    class myClass
      {
      static volatile bool switchChanged;  // declare

      public:

      void begin ()
        {
        pinMode (2, INPUT_PULLUP);
        attachInterrupt (0, switchPressed, CHANGE);
        }  // end of myClass::begin

      static void switchPressed ()
        {
        switchChanged = true;
        }  // end of myClass::switchPressed

      };  // end of class myClass

    volatile bool myClass::switchChanged;  // define

    myClass foo;  // make an instance of myClass

    void setup ()
      {
      foo.begin ();
      }  // end of setup

    void loop ()
      {
      // whatever
      }  // end of loop

But that isn't great because, as you observed, you are really downgrading the class to use a static boolean.

---

Another way of doing it is to write "glue" routines, like this:

    class myClass
      {
      volatile bool switchChanged;

      static myClass * instances [2];

      static void switchPressedExt0 ()
        {
        if (myClass::instances [0] != NULL)
          myClass::instances [0]->switchPressed ();
        }  // end of myClass::switchPressedExt0

      static void switchPressedExt1 ()
        {
        if (myClass::instances [1] != NULL)
          myClass::instances [1]->switchPressed ();
        }  // end of myClass::switchPressedExt1

      public:

      void begin (const byte whichPin)
        {
        pinMode (whichPin, INPUT_PULLUP);
        switch (whichPin)
          {
          case 2:
            attachInterrupt (0, switchPressedExt0, CHANGE);
            instances [0] = this;
            break;

          case 3:
            attachInterrupt (1, switchPressedExt1, CHANGE);
            instances [1] = this;
            break;

          } // end of switch
        }  // end of myClass::begin

      void switchPressed ()
        {
        switchChanged = true;
        }

      };  // end of class myClass

    myClass * myClass::instances [2] = { NULL, NULL };

    // instances of our class
    myClass foo;
    myClass bar;

    void setup ()
      {
      foo.begin (2);   // pin D2
      bar.begin (3);   // pin D3
      }  // end of setup

    void loop ()
      {
      // whatever
      }  // end of loop

That's still not a great solution, but it might give you some ideas.

---

Your fundamental problem is that classes, by their nature, can be instantiated many times, however you only have a small, fixed, number of interrupts on the microprocessor.


message:
Reading PROGMEM results in an incorrect hex value

I'm sure I'm doing something stupid here, but the code below is supposed to write the test hex values to a I2C EEPROM, however when I attempt to read the EEPROM it has the wrong values.  Directly calling something like Wire.write(0xab) will write the 0xab as expected, so I know the EEPROM is being written to properly, just something seems to be getting lost in translation when writing test[counter++]
.
```
#include <Wire.h>

const byte test[] PROGMEM = {
  0x80, 0x7f, 0x7f, 0x80, 0x7f, 0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x80, 0x80,
  0x7f, 0x7f, 0x81, 0x7f, 0x7e, 0x81, 0x80, 0x7f, 0x7f, 0x7f, 0x80, 0x7e,
  0x7e, 0x81, 0x7e, 0x7c, 0x7f, 0x7f, 0x7d, 0x7c, 0x7f, 0x7f, 0x80, 0x7e
};

unsigned int test_len = 36;

#define EEPROM_ADR 0x50

void setup()
{
  Wire.begin();

  int counter = 0;

  Wire.beginTransmission(EEPROM_ADR);

  Wire.write((int)(0x0 >> 8)); //msb
  Wire.write((int)(0x0 & 0xFF)); //lsb

  while (counter < test_len)
  {
    Wire.write(test[counter++]); //using page buffering to write the entire array
  }

  Wire.endTransmission();
}
```

The results look something like: 0x00 0x00 0x08 0x00 0x00 0x00 0x01 etc..

body: I needed to either remove PROGMEM from the array or use pgm_read_byte to read the array.


message:
Part identification

This may be a dumb question but i would like to know what this part is. Anyone who knows?[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/xDWL8.jpg

body:
This looks like something out of an Arduino n-part “sensor kit”. It’s hard to tell because the quality of the image is not very good.

My guess is, this is an analog temperature sensor, like [in this link](https://www.instructables.com/id/Arduino-37-in-1-Sensors-Kit-Explained/), part number 18. You can also find an example sketch there.


message:
How to modify this code to use serial event to act after carriage return?

In part of a code used with UNO, I want to send number A and number B at once as A,B to the Arduino board if there is carriage return. So at the moment in HyperTerminal when I type: 100,0.5 the Arduino board immediately reacts x becomes 100 and n becomes 0.5. Following parts are related to reading with serial event:

    void loop() {

          if (stringComplete){

          delay(1000);
          Mwrite(level);
          sendFrequency(n);
          delay(100);

          stringComplete = false;

       }
    }

and in serial event:

    void serialEvent() {

         while (Serial.available()) {

         slevel  = Serial.readStringUntil(',');
         Serial.read(); //next character is comma, so skip it using this
         x = Serial.readStringUntil(',');

         level = slevel.toInt();
         n = x.toDouble();
         stringComplete = true;
      }
    }

But what I want to do is, I want the board only read the serial data only if I hit carriage return. So I should type 100,1 and then I should also hit carriage return for Arduino to react to the serial data.

How can this code be modified to achieve that?

body:
There are multiple ways you can solve it. The easiest way to do it is by just adding one more line in your code.

    static bool stringComplete = false;
    String x;
    String slevel;
    static int level;
    static int n;

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

    void loop()
    {
      if (stringComplete)
      {
        Serial.println(level);
        Serial.println(n);
        stringComplete = false;
      }
    }

    void serialEvent()
    {
      while(Serial.available())
      {
        slevel  = Serial.readStringUntil(',');

        //Serial.read(); // <-- You don't need this line. readStringUntil() will read ','

        x = Serial.readStringUntil(',');

        level = slevel.toInt();
        n = x.toDouble();
        Serial.readStringUntil('\r'); // <--------- Add this line
        stringComplete = true;
      }
    }

But this is not probably the right way to do it. First, ***serialEvent()*** executes in between ***loop()*** i.e. this is what it looks like:

    while(1)
    {
        loop();
        serialEvent();
    }

So, it is not like that the function will get called during a serial event. It just gets executed right after ***loop()***. Also ***readStringUntil()*** has a timeout (default: 1s). So if your 'until' character doesn't show up within one second of the function call, it will return with whatever it has. To test this, just type one character on your HyperTerminal and wait at least for a second, and see the output.<br>

Ideally, this is how you should handle the serial's incoming byte:

 - Check if there is serial byte available to read
 - If there is, read one byte and save it in a buffer/string. (I'm not really a fan of **String** variables, but in the example, I will use String because you were using a **String**)
 - If the byte you just read is delimiter (e.g. CR or '\r'), indicate the main loop that string is complete.
 - In the main loop parse the whole string.

So this is how the code looks like with above-mentioned points:

    static bool stringComplete = false;
    String x;
    String slevel;
    static int level;
    static int n;
    String rxString = "";

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

    void loop()
    {
      if (stringComplete)
      {
        // Parse the rxString
        int index1 = rxString.indexOf(',');             // finds location of first ,
        slevel = rxString.substring(0, index1);         // captures first data String
        int index2 = rxString.indexOf(',', index1 + 1); //finds location of second ,
        x = rxString.substring(index1 + 1, index2);     //captures second data String

        level = slevel.toInt();
        n = x.toDouble();

        Serial.println(level);
        Serial.println(n);

        // Reset the string
        rxString = "";
        stringComplete = false;
      }
    }

    void serialEvent()
    {
      while(Serial.available())
      {
        // get the new byte:
        char inChar = (char)Serial.read();
        // add it to the rxString:
        rxString += inChar;
        // if the incoming character is a carriage return, indicate main loop
        if (inChar == '\r')
        {
          stringComplete = true;
        }
      }
    }


message:
DHT11 analog or digital?

I saw some projects with DHT11, some connect it with analog pin, others connect with digital pin.

Is there any difference / advantage connecting to the analog?

body:
The DHT11 is a digital component with its own digital communication protocol.

Analog pins can be used for either analog input *or* digital input and output.

You can use a digital device like the DHT11 on *any* pin, whether it is labelled analog or digital (except on a couple of boards which have a few analog-only pins).


message:
Why does my ATtiny85 blink program only work with 4 out of the 16 registers?

The following blink program runs fine on my Attiny85 SparkFun Tiny AVR programmer board. It produces 5 short blinks and then stops.

It also works fine when I change r16 to any one of the registers r17, r21 or r29. But trying with any other register gives either no blink at all (r19, r20, r23, r25, r26, r27, r28, r31) or indefinite blinks (r18, r22, r24, r30).

Can anyone explain?

    int ledPin = 0;

    void setup() {

      pinMode(ledPin, OUTPUT);

      asm("ldi r16, 5");
      asm("blink:");
      digitalWrite(ledPin, HIGH);
      delay(500);
      digitalWrite(ledPin, LOW);
      delay(500);
      asm("dec r16");
      asm("brge blink");
    }

    void loop() {
    }

body: Solved it myself! The high-level command "delay(500)" destroys the register contents. Saving the register (using push/pop) while doing delay() solves this issue. (Btw, is should be "brpl" and not "brge".)


body:
As you discovered, calling a function may clobber some registers. To be precise, the [avr-gcc documentation][1] says:

> Call-Used Registers
>
> The call-used or call-clobbered general purpose registers (GPRs) are registers that might be destroyed (clobbered) by a function call.
>
> R18–R27, R30, R31
> These GPRs are call clobbered. An ordinary function may use them without restoring the contents. Interrupt service routines (ISRs) must save and restore each register they use.
>
> Call-Saved Registers
>
> R2–R17, R28, R29
> The remaining GPRs are call-saved, i.e. a function that uses such a registers must restore its original content. This applies even if the register is used to pass a function argument.

Now, an interesting detail here is that according to the documentation, one would expect R28 to work. Maybe that's not clobbered by the called procedure, but by your local procedure (mixing assembly and C in nontrivial amounts is a difficult
task for precisely this reason).

  [1]: https://gcc.gnu.org/wiki/avr-gcc#Call-Used_Registers


message:
not able to figure out what is wrong with my nodemcu code

```
#include <ESP8266WiFi.h>
#include <FirebaseArduino.h>

//Firebase settings
#define FIREBASE_HOST "..........firebaseio.com/"     //cant share
#define FIREBASE_AUTH "..............."               //cant share

//Wi-Fi settings
#define WIFI_SSID "kello"
#define WIFI_PASSWORD "8888"

//Define trigger and echo digital pins
const int trigPin = 4;
const int echoPin = 3;

// The amount of time the ultrassonic wave will be travelling for
long duration = 0;
// Define the distance variable
double distance = 0;

void setup()
{
     Serial.begin(9600);
    // Connect to Wi-Fi
    Serial.print("Wi-Fi...");
    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
    Serial.print("Connecting...");
    while (WiFi.status() != WL_CONNECTED)
    {
        Serial.print(".");
        delay(500);
    }
    Serial.println();
    Serial.print("Connected to: ");
    Serial.println(WiFi.localIP());

    Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);

    // Ultrasonic sensor, set echo as Input and trigger as Output
    pinMode(trigPin, OUTPUT);
    pinMode(echoPin, INPUT);

}

void loop()
{

    getDistance();
    // Prints the distance value to the serial monitor
    Serial.print("Distance: ");
    Serial.println(distance);

    delay(500);
}

void getDistance()
{
    // Clear trigPin
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);

    // trigPin HIGH por 10ms
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);

    //Reads echoPin, returns the travel time of the sound wave in ms
    duration = pulseIn(echoPin, HIGH);

    // Calculating the distance, in centimeters, using the formula described in the first section.
    distance = duration * 0.034 / 2;

    // Sends the distance value to Firebase
    Firebase.setFloat("distance", distance);

}
```
I am a computer graduate so i do not have much knowledge about nodemcu. I saw some documentations about nodemcu. I want to show the data obtained by the ultrasonic distance sensor in the realtime database of firebase. But i am not able to figure out why i am not able to get output of **serial.println(distance)** in the com5 window even though the code compiles successfully .
This is what i get when running the program
```
Executable segment sizes:

IROM   : 330560          - code in flash         (default or ICACHE_FLASH_ATTR)

IRAM   : 27760   / 32768 - code in IRAM          (ICACHE_RAM_ATTR, ISRs...)

DATA   : 1408  )         - initialized variables (global, static) in RAM/HEAP

RODATA : 2044  ) / 81920 - constants             (global, static) in RAM/HEAP

BSS    : 25160 )         - zeroed variables      (global, static) in RAM/HEAP

Sketch uses 361772 bytes (34%) of program storage space. Maximum is 1044464 bytes.
Global variables use 28612 bytes (34%) of dynamic memory, leaving 53308 bytes for local variables. Maximum is 81920 bytes.
esptool.py v2.8
Serial port COM5
Connecting....
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: ec:fa:bc:c1:44:d2
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 4MB
Compressed 365920 bytes to 264395...

Writing at 0x00000000... (5 %)
Writing at 0x00004000... (11 %)
Writing at 0x00008000... (17 %)
Writing at 0x0000c000... (23 %)
Writing at 0x00010000... (29 %)
Writing at 0x00014000... (35 %)
Writing at 0x00018000... (41 %)
Writing at 0x0001c000... (47 %)
Writing at 0x00020000... (52 %)
Writing at 0x00024000... (58 %)
Writing at 0x00028000... (64 %)
Writing at 0x0002c000... (70 %)
Writing at 0x00030000... (76 %)
Writing at 0x00034000... (82 %)
Writing at 0x00038000... (88 %)
Writing at 0x0003c000... (94 %)
Writing at 0x00040000... (100 %)
Wrote 365920 bytes (264395 compressed) at 0x00000000 in 23.4 seconds (effective 125.3 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...
```

[![Here is the serial window after executing][1]][1]

Is the ultrasonic sensor not getting enough power supply as nodemcu is connected to my laptop?
Please help me out and let me know if more information is required.

  [1]: https://i.stack.imgur.com/ocEzZ.png

body:
Your `echoPin` Is defined as `3`. GPIO3 of the NodeMCU is also the “RX” pin needed for serial communication to the host. This might explain why you don’t see any output. You should change it to a different pin (for example pin 5 / D1 is a safe choice).

Each pin on the NodeMCU has a “GPIO” number (which is just the pin number as defined by the ESP8266 architecture) and a corresponding “Dx” designation (which is usually marked on the NodeMCU board).

Which GPIO pin corresponds to which which “D” pin is shown in pinout diagrams, like the one [here](https://randomnerdtutorials.com/esp8266-pinout-reference-gpios/). Scroll to the NodeMCU 12-E pinout.

Some of the safest pins to use are:

 - Pin 5 (D1)
 - Pin 4 (D2)
 - Pin 12 (D6)
 - Pin 13 (D7)
 - Pin 14 (D5)

Some of the other pins could also be used, but have some restrictions, as you can see on the page I linked to.

Note that pins 12-14 are used for SPI and pins 4 and 5 are (normally) used for (software) I2C. If you want to control hardware that uses these protocols, these are the default pins it uses.


message:
Unable to find/connect I2C devices (SHT31 & SGP30)

I have recently purchased an Arduino Nano 33 IOT together with two sensors:

 - Adafruit SHT31-D (https://learn.adafruit.com/adafruit-sht31-d-temperature-and-humidity-sensor-breakout)
 - Adafruit SGP30 (https://learn.adafruit.com/adafruit-sgp30-gas-tvoc-eco2-mox-sensor/)

However, so far I have not succeeded in reaching any of these two sensors. For example I connect the SHT31 sensor like this:

 - +3.3V to Vin
 - GND to GND
 - A4 to SDA
 - A5 to SCL

I have tried the default Adafruit  SHT31-D example without success, the program appears to hang. I have tried a standard I2C scanner but it does not find any devices with the sensor connected. When the sensor is disconnected, it does find two devices (the IMU and something else I guess).

I believe there is something funky going on with the I2C connection of the internal sensors and the external ones but I have no idea how to troubleshoot this issue. I read some stuff about TwoWire (extern TwoWire Wire1; after the #include) but I am having a hard time figuring out if this is what I need and how to implement it.

I found these topics myself:

https://forum.arduino.cc/index.php?topic=639188.0

https://forum.arduino.cc/index.php?topic=658967.0

edit: I haven't had success dealing with these issues so far and I am still looking for some help with my problems!

body:
one can code an I2C sensor (I'm using a SHT31) using custom GPIO ports like so:

    //I2C Bus Pins
    #define SDA 8
    #define SCL 9

    #include "Adafruit_SHT31.h"
    TwoWire I2Cbus = TwoWire(0);
    Adafruit_SHT31 sht31 = Adafruit_SHT31(&I2Cbus);

    void setup(){
      Serial.begin(115200);            // USB communication with Serial Monitor
      Serial.print("Starting serial...");

      Serial.print("Starting SHT31...");
      startSHT();
    }

     // ********************************************************
     void startSHT(){
      I2Cbus.begin(SDA, SCL, 100000ul);
      if (! sht31.begin(0x44)) { // Set to 0x45 for alternate i2c addr
         Serial.println("Couldn't find SHT31");
    while (1)
    delay(1);
      }
    }


body:
I had a similar problem, but the fix turned out to be simple. All the tutorials for SHT3x sensors say to connect the VIN to the 3.3V GPIO. I checked using a test meter, the SHT3x was getting voltage but numerous SH3x libraries didn't seem to work, and a couple of I2C sketches also found nothing. So I tried moving the VIN lead to the 5V GPIO pin - it works perfectly. Perhaps my USB connection lacks enough power, or perhaps my SHT3x needs 5V. Either way it
works - happy now !


body: Without a schematic I will take a SWAG" For I2C to work it needs a pull up resistor for SCL another for SDA. Both are open drain/collector outputs neither of which can drive a + (logic 1) on the bus.


message:
Converting the 3.3V PWM signal to 5V PWM signal

I am using ESP32....the max Pwm signal of it is 3.3V...And I have to control two motors speed by TB6612FNG motor driver...when i was using Arduino.. The arduino can send max 5V Pwm signal to the motor drivers PWM pin.. And the motor runs at the exact speed...but now i have to use ESP32..which sends 3.3V and the motors slow down..

So what should I do to convert the ESP32's PWM signal to 5v and according If i change the PWM value at the program..the output will also change similarly as Arduino??
Please help me

body:
Looking at [TB6612FNG][1] datasheet i read

> Logic supply voltage (VCC) can be in the range of 2.7--5.5VDC

So, if you supply 3.3V to VCC all should be ok, if the motors themselves get enough power (via VM)

  [1]: https://www.sparkfun.com/products/14451


message:
How do I put timers by using millis on 3 PIR sensors?

I want to make the PIRs to stay on for about 1 minute. I've found the code that can do so for 1 PIR, but I dont know how to apply the code for 3 PIRs.

Here is the code for 1 PIR with timer using `millis`:

    int ledPin = 8;
    int pirPin = 3;

    unsigned long piron;
    //the time we give the sensor to calibrate (10-60 secs according to the datasheet)
    int calibrationTime = 10;

    int off;
    int on;
    const int LDR = A0;
    int ldrStatus;

    unsigned long currentMillis =( millis()/1000 ) / 60;

    /////////////////////////////
    //SETUP
    void setup(){
      Serial.begin(9600);
      pinMode(pirPin, INPUT);
      pinMode(ledPin, OUTPUT);
      digitalWrite(pirPin, LOW);

      //give the sensor some time to calibrate
      Serial.print("calibrating sensor ");
        for(int i = 0; i < calibrationTime; i++){
          Serial.print(".");
          delay(1000);
          }
        Serial.println(" done");
        Serial.println("SENSOR ACTIVE");
        delay(50);
      }

    ////////////////////////////
    //LOOP
    void loop()

    {
    ldrStatus = analogRead (LDR);
    if (ldrStatus <= 700)     // variable reading(ldrStatus) according to ldr
                              // the higher reading(ldrStatus), the dimmer light
                              // the lower the reading(ldrStatus), the brighter light

    {
    analogRead (pirPin) == off;

    Serial.println ("Its SUNNY DAY !!!");
    digitalWrite(ledPin, LOW);

    }

    if (ldrStatus >= 700)
    {
    Serial.println ("Its DARK already");

        if(digitalRead(pirPin) == HIGH){
           digitalWrite (ledPin, HIGH);
         piron = ( millis()/1000 ) / 60;
      }

      if ((currentMillis - piron) > 1) {
        digitalWrite(ledPin, LOW);

      }

        }
    }
    `

    and here is the code for 3 PIRs without the timer

        int calibrationTime = 10;

    int pirPin = 3;
    int ledPin = 8;

    int pirPin1 = 4;
    int ledPin1 = 9;

    int pirPin2 = 5;
    int ledPin2 = 10;

    int ledPin3 = 11;

    int off;
    int on;
    const int LDR = A0;
    int ldrStatus;

    /////////////////////////////
    //SETUP
    void setup(){
      Serial.begin(9600);
      pinMode(pirPin, INPUT);
      pinMode(ledPin, OUTPUT);
      digitalWrite(pirPin, LOW);

       pinMode(pirPin1, INPUT);
      pinMode(ledPin1, OUTPUT);
      digitalWrite(pirPin1, LOW);

       pinMode(pirPin2, INPUT);
      pinMode(ledPin2, OUTPUT);
      digitalWrite(pirPin2, LOW);

     pinMode (ledPin3, OUTPUT);

      //give the sensor some time to calibrate
      Serial.print("calibrating sensor ");
        for(int i = 0; i < calibrationTime; i++){
          Serial.print(".");
          delay(1000);
          }
        Serial.println(" done");
        Serial.println("SENSOR ACTIVE");
        delay(50);
      }

    ////////////////////////////
    //LOOP
    void loop()
    {
    ldrStatus = analogRead (LDR);
    if (ldrStatus <= 700)     // variable reading(ldrStatus) according to ldr
                              // the higher reading(ldrStatus), the dimmer light
                              // the lower the reading(ldrStatus), the brighter light

    {
    analogRead (pirPin) == off;
    analogRead (pirPin1) == off;
    analogRead (pirPin2) == off;
    Serial.println ("Its SUNNY DAY !!!");
    digitalWrite(ledPin, LOW);
    digitalWrite(ledPin1, LOW);
    digitalWrite(ledPin2, LOW);
    digitalWrite(ledPin3, LOW);
    }

    if (ldrStatus >= 700)
    {
    Serial.println ("Its DARK already");
    digitalWrite(ledPin3, HIGH);

        if(digitalRead(pirPin) == HIGH && digitalRead(pirPin1)== LOW && digitalRead(pirPin2) == LOW){
          digitalWrite (ledPin, HIGH);
          digitalWrite(ledPin1, LOW);
          digitalWrite(ledPin2,LOW);
        }

        if(digitalRead(pirPin) == LOW && digitalRead(pirPin1)== HIGH && digitalRead(pirPin2) == LOW){
          digitalWrite (ledPin1, HIGH);
          digitalWrite (ledPin, LOW);
          digitalWrite(ledPin2,LOW);

    }
       if(digitalRead(pirPin) == LOW && digitalRead(pirPin1)== LOW && digitalRead(pirPin2) == HIGH){
          digitalWrite (ledPin2, HIGH);
          digitalWrite (ledPin1, LOW);
          digitalWrite (ledPin, LOW);

       }

         if(digitalRead(pirPin) == HIGH && digitalRead(pirPin1)== HIGH && digitalRead(pirPin2) == LOW){
        digitalWrite (ledPin1, HIGH);
        digitalWrite (ledPin, HIGH);
        digitalWrite (ledPin2, LOW);

    }

         if(digitalRead(pirPin) == HIGH && digitalRead(pirPin1)== LOW && digitalRead(pirPin2) == HIGH){
          digitalWrite (ledPin, HIGH);
          digitalWrite (ledPin2, HIGH);
          digitalWrite (ledPin1, LOW);
         }

         if(digitalRead(pirPin) == LOW && digitalRead(pirPin1)== HIGH && digitalRead(pirPin2) == HIGH){
         digitalWrite (ledPin2, HIGH);
         digitalWrite (ledPin1, HIGH);
         digitalWrite (ledPin, LOW);
         }

        if(digitalRead(pirPin) == HIGH && digitalRead(pirPin1)== HIGH && digitalRead(pirPin2) == HIGH){
          digitalWrite (ledPin2, HIGH);
          digitalWrite (ledPin1, HIGH);
          digitalWrite (ledPin, HIGH);

        }

         if(digitalRead(pirPin) == LOW && digitalRead(pirPin1)== LOW && digitalRead(pirPin2) == LOW){
          digitalWrite (ledPin2, LOW);
          digitalWrite (ledPin1, LOW);
          digitalWrite (ledPin, LOW);
         }

    }

    }

body:
This is not a complete answer, but an idea of how to accomplish the task.

I just typed it in without testing the code.

Use arrays to hold variables. That way a loop can be used to service the three sensors and the three LEDs..

    for (i = 0; i<3; i++) {
       currentTime = millis();                             // save current millis() value

       if (digitalRead(pirPin[i]) == HIGH) {               // check if PIR is detecting motion
          trigTime[i] = millis();                          // save trigger time
          trig[i]     = true;                              // set a state variable that indicates
       }                                                   //   that a trigger happened

       if (trig[i]) {                                      // if trigger happened
          if (currentTime - trigTime[i] < 50000) {         // is it less than 50 sec since last motion?
             digitalWrite (ledPin[i], HIGH);
          }
          else {
             trig[i] = false;                              // 50 second timer ran out
             digitalWrite (ledPin[i], LOW);
          }
       }
    }


message:
Combined code and nothing works. Head scratcher for sure

I have spent a little over 2 hours trying to debug this code. All I did was combine a section of code to write to the SD card. Both of the codes work fine on their own. I can't figure this one out. I am hoping fresh eyes can spot the error. I am using a Arduino Nano with a Robot-Deek data logger board. Pin 10 is used for the data logger. I was using a DTH11 but switched to a LM35, both codes worked with LM35.
```
#include "RTClib.h"
#include <SD.h>
#include <SPI.h>
#define sample 500
#define current_ms millis()
RTC_DS1307 rtc;
File myFile;
int inPin = 0;   //analog in
float val;       //where to store info from inPin reading
int pinRed = A3;  //output of red led
float tempin = A5;  //input of temp sensor
float tempf;     // variable to hold temp in Fahrenheit
float vout;      // variable to hold voltage from sensor
int array1[sample];  //creates an array with number of elements equal to "sample"
unsigned long averaging;  //the program uses this variable to store the sum of each array it makes
int pinCS = 10;   // write to SD card
float last_dht11_reading_ms = 1;
DateTime now = rtc.now();
#define DHT11_SAMPLE_DELAY 500

void setup() {

  Serial.begin(9600);
  delay(500);//Delay to let system boot
  SD.begin();
  pinMode(pinCS, OUTPUT);
  pinMode(tempin, INPUT);
  Serial.println("Volt and Temperature\n\n");
Serial.println("middle the setup loop");
 // SD Card Initialization
  if (SD.begin())
  {
    Serial.println("SD card is ready to use.");
    File myFile = SD.open("Datalog.csv",FILE_WRITE);
    if (myFile) {
      myFile.println("Time, Temp, Volt");
      myFile.close();
    }
  } else
  {
    Serial.println("SD card initialization failed");
    return;
  }
  rtc.begin();
  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}//end "setup()"

void loop() {

  for (int i = 0; i < sample; i++) {         //this code tells the program to fill each element in the array we made with
    array1[i] = analogRead(inPin);           //information from the antenna wire coming out of the Arduino
    averaging += array1[i];                  //more information about for loops http://arduino.cc/en/Reference/For
  }                                          //the averaging line is simply saying: add averaging to whatever is in array position i
                                             //averaging += array[i] is the same as averaging = averaging + array[i]

  val = averaging / sample;                  //here the program takes the sum of all numbers in array1, and divides by the number of elements "sample"
  val = constrain(val, 0, 100);              //this constrains the variable value to between two numbers 0 and 100
  val = map(val, 0, 100, 0, 255);           //for more information about constrain http://arduino.cc/en/Reference/Constrain
  analogWrite(pinRed, val*20);                  //the map statement tells the program to map out 0-100 to 0-255
  averaging = 0;                                 //this line of code sets averaging back to zero so it can be used again
Serial.println("past the emf loop");

  if ( (current_ms - last_dht11_reading_ms) > DHT11_SAMPLE_DELAY ) {
    vout = analogRead(tempin);                //read LM35 output
    float mv = (vout/1024)*5000;              // conversion to mV
    float celc = mv/10;                       // convert to C
    float tempf = ((celc*9)/5 + 32)/10;       // convert to F
    myFile = SD.open("Datalog.csv", FILE_WRITE);      //open datalog file on SD card

  if (myFile) {                              //write to the SD card time, tempf and val
    myFile.print(now.hour());
    myFile.print(":");
    myFile.print(now.minute());
    myFile.print(":");
    myFile.print(now.second());
    myFile.print(",");
    myFile.print(tempf);
    myFile.print(",");
    myFile.println(val);
    myFile.close(); // close the file;    // close the file
    last_dht11_reading_ms = current_ms;
  }
Serial.println("past the logger loop");
  //delay(1000);//Wait 1 seconds before accessing sensor again.

}
}
// end loop()
```

body:
```DateTime now = rtc.now();```
Does not belong above void setup()
4hours to troubleshoot this little mistake.


message:
Programming pic microchip

I have a few pic chips, mainly pic16f72 and pic16f73 on old ups circuits, realized they are not that bad. Their adc capabilities are my point of focus.

I have an esp32 (my first mcu) and i am very disappointed mainly because its adc being crap, I did some research on programming pic chips, some could be programmed via an arduino but my chips were not mentioned anywhere. I wanna program them via my esp32..

Is there a way to program them via arduino (esp32 in my case)? I can build some basic circuits but diy pic programmers require a preprogrammed pic chip which I can't produce if I can't program one already.

body:
It seems, that you are talking about 2 different things:

- The programming/burning of the PIC can be done via an Arduino (so you don't need to build a complex PIC programmer circuit). It is irrelevant, what microcontroller type is on the programmer, as long as the programmer speaks ISP (the programming protocol). So even, when your specific PIC is not mentioned at your found sites, it should work nonetheless. The connections are every time the same, though of your specific PIC the used pin functions might be on other pins (consult the datasheet for this).

- An Arduino project - meaning the sketch/program, that was written for a normal Arduino, is normally not easily reusable. PICs are different microcontrollers with different hardware, so you need to port those projects to your specific microcontroller, which might involve extensive changes. When you have an Arduino Project, that was directly written for your PIC, then you can reuse it. (Be sure to install the correct core for your PIC in the Arduino IDE)


body:
For PIC32 you need [chipKIT](https://chipkit.net).  Not all chips are supported, but most of the PIC32MX and PIC32MZ chips are. Which exact PIC32 chip(s) do you have?

You will need to install a [bootloader](https://github.com/chipKIT32/PIC32-avrdude-bootloader), for which you will need a programmer. It is possible to build a programmer using an Arduino, though TBH I'd just pick up a cheap PICkit2 clone from China.

As for the 8-bit PICs, no, they can't be programmed like an Arduino, simply because there is no open source C++ compiler available.


message:
"Manually" generating a PWM signal

I've been trying, just out of curiosity, to write my own function that generates a PWM signal, just like `analogWrite()`, and to make it light up an LED. Here's my attempt so far:

    const int pin = 3;
    int cycle = 2; // analogWrite() outputs a 498 Hz signal, so each cycle has approximately 2ms

    int duty = 0.5; // for a 50% duty cycle

    void setup() {
      Serial.begin(9600);
      pinMode(pin,OUTPUT);
    }

    void loop() {
      digitalWrite(pin,HIGH);
      delay(cycle*duty);
      digitalWrite(pin,LOW);
      delay(cycle*(1-duty));
    }

The LED does light up, but very dimly, as shown below:

[![LED brightness with my code][1]][1]

However, when using `analogWrite()` with a 50% duty cycle to achieve the same result, the LED shines much brighter:

[![LED brightness with analogWrite(pin,128)][2]][2]

Is there something wrong with my code, or is there a special reason why more power is dissipated with `analogWrite()`?

  [1]: https://i.stack.imgur.com/ik8e8.jpg
  [2]: https://i.stack.imgur.com/uNb9x.jpg

body:
You need to review your code and also the capabilities of the Arduino UNO.

 - `int` declares an integer.  So `int duty = 0.5;` is going to get rounded to either 0 1.
 - `delay(0);` also will not work.  The instruction will simply get skipped. Likely the reason why you get a brighter LED. Try to use `delayMicroseconds();` if you need shorter time but the minimum delay you can have is 4 us for Arduino UNO.
 - If you are using times as short as 2 us, then from the above comment the `delayMicroseconds();` function is not going to be sufficient.  Also, you should consider the loop overhead, which will be a few microseconds.

All in all this is not a great method.  If you do want to create your own PWM signals, it is much better to use the hardware timers.  For example [this tutorial on the Arduino website.][1]  You should also be able to find posts about hardware timers on Arduino SE.

  [1]: https://playground.arduino.cc/Code/Timer1/


message:
Can not receive data from Python code

I want to send 4 float numbers from Python code to an Arduino; I was trying to send it via serial and I have some problems.

**here is my Python code:**

```python
import time
import serial
import struct

data = serial.Serial('COM6', 9600, timeout=1)
time.sleep(1)

while True:
   a = str(47.256*1000)
   data.write(a.encode())
```

**Here is my Arduino code :**

```c++
String msg;

void setup()
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);
}

void loop()
{
  if (Serial.available()) {
    msg = Serial.readString();
  }

  if (msg.toInt()>30){
    digitalWrite(13, 1);
  }
}
```
**end of code**

Thanks in advance.

My problem is that it does not work (LED does not turn on while I send data from the Python code in a while loop; when I remove the while and make it send data 1 time it works (LED turns on). Any ideas why this could be happening?

body:
It would be easier if you used Arduino <--> Python compatible libraries to ensure the communication between the two is robust and reliable. An example of such libraries would be [pySerialTransfer][1] and [SerialTransfer.h][2].

pySerialTransfer is pip-installable and cross-platform compatible. SerialTransfer.h runs on the Arduino platform and can be installed through the Arduino IDE's Libraries Manager.

Both of these libraries have highly efficient and robust packetizing/parsing algorithms with easy to use APIs.

**Example Python Script:**

    import time
    from pySerialTransfer import pySerialTransfer as txfer

    if __name__ == '__main__':
        try:
            link = txfer.SerialTransfer('COM17')

            link.open()
            time.sleep(2) # allow some time for the Arduino to completely reset

            while True:
                send_size = 0

                ###################################################################
                # Send a list
                ###################################################################
                list_ = [1, 3]
                list_size = link.tx_obj(list_)
                send_size += list_size

                ###################################################################
                # Send a string
                ###################################################################
                str_ = 'hello'
                str_size = link.tx_obj(str_, send_size) - send_size
                send_size += str_size

                ###################################################################
                # Send a float
                ###################################################################
                float_ = 5.234
                float_size = link.tx_obj(float_, send_size) - send_size
                send_size += float_size

                ###################################################################
                # Transmit all the data to send in a single packet
                ###################################################################
                link.send(send_size)

                ###################################################################
                # Wait for a response and report any errors while receiving packets
                ###################################################################
                while not link.available():
                    if link.status < 0:
                        if link.status == -1:
                            print('ERROR: CRC_ERROR')
                        elif link.status == -2:
                            print('ERROR: PAYLOAD_ERROR')
                        elif link.status == -3:
                            print('ERROR: STOP_BYTE_ERROR')

                ###################################################################
                # Parse response list
                ###################################################################
                rec_list_  = link.rx_obj(obj_type=type(list_),
                                         obj_byte_size=list_size,
                                         list_format='i')

                ###################################################################
                # Parse response string
                ###################################################################
                rec_str_   = link.rx_obj(obj_type=type(str_),
                                         obj_byte_size=str_size,
                                         start_pos=list_size)

                ###################################################################
                # Parse response float
                ###################################################################
                rec_float_ = link.rx_obj(obj_type=type(float_),
                                         obj_byte_size=float_size,
                                         start_pos=(list_size + str_size))

                ###################################################################
                # Display the received data
                ###################################################################
                print('SENT: {} {} {}'.format(list_, str_, float_))
                print('RCVD: {} {} {}'.format(rec_list_, rec_str_, rec_float_))
                print(' ')

        except KeyboardInterrupt:
            link.close()

        except:
            import traceback
            traceback.print_exc()

            link.close()

**Example Arduino Sketch:**

    #include "SerialTransfer.h"

    SerialTransfer myTransfer;

    void setup()
    {
      Serial.begin(115200);
      myTransfer.begin(Serial);
    }

    void loop()
    {
      if(myTransfer.available())
      {
        // send all received data back to Python
        for(uint16_t i=0; i < myTransfer.bytesRead; i++)
          myTransfer.txBuff[i] = myTransfer.rxBuff[i];

        myTransfer.sendData(myTransfer.bytesRead);
      }
    }

Note that you can send more than just individual chars with these libraries. It is possible to transfer floats, ints, bytes, arrays, and even structs (or any combination of the like) within your program using the libraries! See the examples in [SerialTransfer.h][3] for more info

**For theory behind robust serial communication,** check out the tutorials [Serial Input Basics][4] and [Serial Input Advanced][5].

  [1]: https://github.com/PowerBroker2/pySerialTransfer
  [2]: https://github.com/PowerBroker2/SerialTransfer
  [3]: https://github.com/PowerBroker2/SerialTransfer/tree/master/examples
  [4]: https://forum.arduino.cc/index.php?topic=396450.0
  [5]: https://forum.arduino.cc/index.php?topic=662346.0


message:
the boxservo works contrary to the code

i want to make a uselessbox .i connected the circuit correctly,i  checked every thing several times and every thing is in right place[ based on  descriptions and pattern],but when i turn  it on,the box servo closes the door and then handservo starts to turn off the switch ,the code says:[the boxservo opens the door then handservo starts to turn off the switch,when the switch  is off and handservo returned to its place then boxservo closes the door]but my box works like this(the boxservo closes the door then handservo starts to turn off the switch,when the switch  is off and handservo returned to its place,then boxservo opens the door).what should i do to solve this problem?https://arduino.stackexchange.com/q/70885

this is the code that i have uploaded:

    #include <Servo.h>

    Servo handServo;
    Servo boxServo;

    int switchStatus=0, action=1, vot, randNumber=0;
    const int ledPin = 13;
    const int frontSwitchPin = 2;
    const int handServoPin = 5;
    const int boxServoPin = 6;

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

      pinMode(ledPin, OUTPUT);
      digitalWrite(ledPin,HIGH);

      handServo.attach(handServoPin);
      boxServo.attach(boxServoPin);
      handServo.write(180);
      boxServo.write(70);

      //randomSeed(analogRead(0));
    }

    void loop()
    {
      switchStatus = digitalRead(frontSwitchPin);
      //action = random(1,16);

      if (switchStatus == LOW){

        if (action == 1)
        {
          Serial.println("Action 1");
          for (int i = 70; i <= 110; i++)
          {
            boxServo.write(i);
            delay(20);
          }
          for (int i = 180; i >= 35; i--)
          {
            handServo.write(i);
            delay(20);
          }
          delay(1000);
          handServo.write(26);
          delay(200);
          for (int i = 26; i <=180; i++)
          {
            handServo.write(i);
            delay(20);
          }
          for (int i = 110; i >= 70; i--)
          {
            boxServo.write(i);
            delay(20);
          }
          action++;
        }

        else if (action == 2)
        {
          Serial.println("Action 2");
          for (int i = 70; i <= 110; i++){
            boxServo.write(i);
            delay(6);
          }
          delay(550);
          handServo.write(26);
          delay(550);
          handServo.write(180);
          delay(550);
          boxServo.write(70);
          delay(1500);
          for (int i = 70; i <= 110; i++){
            boxServo.write(i);
            delay(6);
          }
          delay(3000);
          boxServo.write(70);
          action++;
        }

        else if (action == 3)
        {
          Serial.println("Action 3");
          for (int i = 70; i <= 110; i++){
            boxServo.write(i);
            delay(6);
          }
          delay(1000);
          boxServo.write(70);
          delay(2000);
          for (int i = 70; i <= 110; i++){
            boxServo.write(i);
            delay(6);
          }
          handServo.write(26);
          delay(550);
          handServo.write(180);
          delay(500);
          boxServo.write(70);
          action++;
        }

        else if (action == 4)
        {
          Serial.println("Action 4");
          for (int i = 70; i <= 110; i++)
          {
            boxServo.write(i);
            delay(20);
          }
          for (int i = 180; i >= 35; i--)
          {
            handServo.write(i);
            delay(20);
          }
          delay(2000);
          handServo.write(26);
          delay(200);
          handServo.write(180);
          delay(400);
          boxServo.write(70);
          action++;
        }

        else if (action == 5)
        {
          Serial.println("Action 5");
          for (int i = 70; i <= 110; i++){
            boxServo.write(i);
            delay(6);
          }
          delay(2000);
          handServo.write(65);
          delay(550);
          handServo.write(40);
          delay(200);
          handServo.write(65);
          delay(200);
          handServo.write(40);
          delay(200);
          handServo.write(65);
          delay(200);
          handServo.write(40);
          delay(200);
          handServo.write(65);
          delay(200);
          handServo.write(40);
          delay(200);
          handServo.write(65);
          delay(200);
          handServo.write(40);
          delay(200);
          handServo.write(65);
          delay(2000);
          handServo.write(26);
          delay(400);
          handServo.write(180);
          delay(400);
          boxServo.write(70);
          action++;
        }

        else if (action == 6)
        {
          Serial.println("Action 6");
          for (int i = 70; i <110; i++)
          {
            boxServo.write(i);
            delay(20);
          }
          delay(1000);
          for (int i = 0; i < 12; i++)
          {
            for (int j = 70; j <= 110; j++){
              boxServo.write(j);
              delay(6);
            }
            delay(200);
          }
          for (int i = 180; i >= 35; i--)
          {
            handServo.write(i);
            delay(30);
          }
          handServo.write(26);
          delay(400);
          handServo.write(180);
          delay(400);
          boxServo.write(70);
          delay(1500);
          for (int i = 70; i <= 110; i++){
            boxServo.write(i);
            delay(6);
          }
          delay(3000);
          boxServo.write(80);
          action++;
        }

        else if (action == 7)
        {
          Serial.println("Action 7");
          for (int i = 70; i <= 110; i++){
            boxServo.write(i);
            delay(6);
          }
          delay(400);
          handServo.write(26);
          delay(1000);
          for (int i = 0; i < 6; i++)
          {
            for (int j = 70; j <= 110; j++){
              boxServo.write(j);
              delay(6);
            }
            delay(200);
          }
          delay(500);
          handServo.write(180);
          delay(400);
          boxServo.write(70);
          action++;
        }

        else if (action == 8)
        {
          Serial.println("Action 8");
          for (int i = 70; i <= 110; i++){
            boxServo.write(i);
            delay(6);
          }
          handServo.write(26);
          delay(2000);
          for (int i = 0; i < 7; i++)
          {
            handServo.write(75);
            delay(100);
            handServo.write(40);
            delay(100);
          }
          delay(500);
          handServo.write(180);
          delay(1000);
          boxServo.write(70);
          action++;
        }

        else if (action == 9)
        {
          Serial.println("Action 9");
          for (int i = 70; i <= 105; i++){
            boxServo.write(i);
            delay(6);
          }
          delay(2000);
          boxServo.write(110);
          for (int i = 180; i >=35; i--)
          {
            handServo.write(i);
            delay(40);
          }
          delay(500);
          handServo.write(26);
          delay(200);
          for (int i = 26; i <=180; i++)
          {
            handServo.write(i);
            delay(40);
          }
          boxServo.write(70);
          delay(2000);
          boxServo.write(100);
          delay(3000);
          boxServo.write(70);
          action++;
        }

        else if (action == 10)
        {
          Serial.println("Action 10");
          for (int i = 70; i <= 105; i++)
          {
            boxServo.write(i);
            delay(100);
          }
          delay(1000);
          for (int i = 0; i < 10; i++)
          {
            for (int j = 70; j <= 100; j++){
              boxServo.write(j);
              delay(6);
          }
            delay(100);
          }
          boxServo.write(110);
          delay(100);
          handServo.write(26);
          delay(650);
          handServo.write(180);
          delay(400);
          boxServo.write(70);
          action++;
        }

        else if (action == 11)
        {
          Serial.println("Action 11");
          for (int i = 70; i <= 110; i++){
            boxServo.write(i);
            delay(6);
          }
          handServo.write(26);
          delay(2000);
          for (int i = 0; i < 3; i++)
          {
            handServo.write(65);
            delay(200);
            handServo.write(40);
            delay(200);
          }
          delay(1500);
          handServo.write(180);
          delay(400);
          boxServo.write(70);
          delay(1500);
          for (int i = 70; i <= 110; i++){
            boxServo.write(i);
            delay(6);
          }
          handServo.write(26);
          delay(3000);
          handServo.write(180);
          delay(400);
          boxServo.write(70);
          action++;
        }

        else if (action == 12)
        {
          Serial.println("Action 12");
          for (int i = 70; i <= 110; i++)
          {
            boxServo.write(i);
            delay(50);
          }
          delay(1000);
          for (int i = 180; i >= 26; i--)
          {
            handServo.write(i);
            delay(50);
          }
          delay(2000);
          handServo.write(26);
          delay(200);
          handServo.write(180);
          delay(400);
          boxServo.write(70);
          action++;
        }

        else if (action == 13)
        {
          Serial.println("Action 13");
          for (int i = 70; i <= 110; i++){
            boxServo.write(i);
            delay(6);
          }
          delay(2000);
          for (int i = 180; i >= 60; i--)
          {
            handServo.write(i);
            delay(40);
          }
          for (int i = 0; i < 3; i++)
          {
            handServo.write(60);
            delay(200);
            handServo.write(40);
            delay(800);
          }
          handServo.write(26);
          delay(2000);
          handServo.write(180);
          delay(500);
          boxServo.write(70);
          action++;
        }

        else if (action == 14)
        {
          Serial.println("Action 14");
          for (int i = 70; i <= 105; i++){
            boxServo.write(i);
            delay(6);
          }
          delay(4000);
          boxServo.write(110);
          handServo.write(26);
          delay(650);
          handServo.write(180);
          delay(500);
          boxServo.write(100);
          delay(4000);
          boxServo.write(70);
          action++;
        }

        else if (action == 15)
        {
          Serial.println("Action 15");
          for (int i = 70; i <= 105; i++){
            boxServo.write(i);
            delay(6);
          }
          delay(1000);
          for (int i = 0; i < 3; i++)
          {
            for (int j = 70; j <= 105; j++){
              boxServo.write(j);
              delay(50);
            }
            for (int j = 105; j >= 70; j--)
            {
              boxServo.write(j);
              delay(50);
            }
          }
          for (int j = 70; j <= 110; j++){
            boxServo.write(j);
            delay(50);
          }
          for (int i = 180; i >= 35; i--)
          {
            handServo.write(i);
            delay(40);
          }
          delay(1000);
          handServo.write(26);
          delay(400);
          handServo.write(180);
          delay(400);
          boxServo.write(70);
          action = 1;
        }

      }

    }

body: You have probably installed the box servo backwards so that when it tries to open it actually closes and vice versa.


message:
Arduino Mega LED doesn't light as expected

I wrote this for my Arduino Mega 2560:

    int LED[14] = { 28,29,30,31,32,33,34,35,36,37,38,39,40,41 } ;
    ...
    ... (some other code like setup(), etc. Note:pinmode output for this 14 leds wich pins is defined in
    ... array named LED[]
    ...
    void intro(){
      for(int j=1; j<100; j++ ){
        for(int r=1; r<15; r++ ){ digitalWrite(LED[r],HIGH); delay(100);  }
        delay(100);
        for(int r=1; r<15; r++ ){digitalWrite(LED[r],LOW); delay(100);}
        delay(100);
      }
      Serial.print("Pattern started");
      delay(1000);
    }

So when I run this script, I expect that each LED will light up in the sequence and remain lit until the second loop to turn it off, but I see that when lighting each LED, when lighting the 9th LED, the first 8 LEDs shut off inexplicably and LEDs 9 through 14 light one by one, remaining lit. That I expected but why do the first 8 LEDs shut off before the loop ends and the second loop starts?

body: your for statements with r=1 need to be changed to r=0;r<14  Arrays always start with the first item being 0, so yours is 0 to 13.


body:
While it is true that your loop is incorrect, the coding error is unlikely to cause the behaviour that you have described.

Please ensure that a current limiting resistor is placed in series with each LED. Since you have 14 LEDs, you will need 14 current limiting resistors. 470 Ohm resistors (or similar) should be adequate for this purpose.

As per the other comments, C++ Arrays start at 0, not 1. The last element is the size of the array minus 1. In your case 14 - 1 = 13. Thus the loop can continue as long as the index is < 14 (or <= 13)

Thus your loops should read:

```C
for(int r=0; r<14; r++ ) {
  digitalWrite(LED[r],HIGH);
  delay(100);
}
```


message:
Problem with if condition

So my project is including detecting the temperature in the room by using dth11 sensor.
my idea is to add 3 LED lights were each light represent the temperature if its cold or hot or perfect.

the wiring and coding is done and it's working .However, i'm having a problem were the perfect temperature is always on no matter if the temperature is hot or cold.
example: if the temperature is cold the cold LED will blink and the perfect temperature LED will be on.

    #include <Adafruit_Sensor.h>
    #include <DHT.h>
    #define DHTPIN A0
    #define DHTTYPE DHT11
    #define LED_TOO_COLD 6
    #define LED_PERFECT 8
    #define LED_TOO_HOT 7
    DHT dht(DHTPIN, DHTTYPE);
    void setup() {
      Serial.begin(9600);
      Serial.println("DHT11 test!");

      dht.begin();
    }

    void loop() {

      pinMode (6 , OUTPUT);
      pinMode (7 , OUTPUT);
      pinMode (8 , OUTPUT);
      delay(2000);

      float h = dht.readHumidity();
      float t = dht.readTemperature();
      float f = dht.readTemperature(true);

      if (isnan(h) || isnan(t) || isnan(f)) {
        Serial.println("Failed to read from DHT sensor!");
        return;
      }

      Serial.print("Humidity: ");
      Serial.print(h);
      Serial.print(" %\t");
      Serial.print("Temperature: ");
      Serial.print(t);
      Serial.println(" *C ");
      if (t < 22) {
        Serial.println("Too cold!");
        digitalWrite(6, HIGH);
        digitalWrite(7, LOW);
        digitalWrite(8, LOW);
        delay (2000);
      }
       if (t >26) {
        Serial.println("Too hot!");
        digitalWrite(7, HIGH);
        digitalWrite(6, LOW);
        digitalWrite(8, LOW);
        delay (2000);

      } else {
        Serial.println("Perfect temperature!");
        digitalWrite(8, HIGH);
        digitalWrite(6, LOW);
        digitalWrite(7, LOW);
        delay (2000);
      }

    }

 [![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/q147O.png

body:
firstly, move your `pinMode()` settings to `setup` section.

in your code, when the temperature is `21` active pin will be 6 and 8.
you should rewrite your code in next ways:

1:

    if (t < 22) {
      ... its cold temp ...
    } else if (t > 26) {
      ... its hot temp ...
    } else {
      ... it's nor temp ...
    }

2:

    if (t < 22) {
       ... its cold temp ...
    }
    if (t > 26) {
       ... it's hot temp ...
    }
    if (t >= 22 && t <= 26) {
       ... it's nor temp ...
    }

and my small advice for u, rewrite in this way, it is more readable

    digitalWrite(6, HIGH);
    digitalWrite(7, LOW);
    digitalWrite(8, LOW);

    digitalWrite(6, LOW);
    digitalWrite(7, HIGH);
    digitalWrite(8, LOW);

    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
    digitalWrite(8, HIGH);

visually changing ENUMS (like LOW or HIGH) more noticeable than changing numbers (6/7/8)