message:
How do you connect parts once all GPIO ports are used?

I have a rather ambitious project in mind. Lots of buttons, sensors, feedback.

If I run out of GPIO ports to attach stuff to my Arduino, what's next? Do you have to buy a separate Arduino to run the extra parts, and then link the two arduinos somehow?

Thanks for any direction you can give.

body: Yes, it is one possible way, another are using some kind of multiplexing as input shift registers, Charlieplexing http://www.instructables.com/id/Charlieplexing-7-segment-displays/?ALLSTEPS, button matrix http://pcbheaven.com/wikipages/How_Key_Matrices_Works/ or i2C bus, which can connects up to 127 different i2c devices


sender: user

message:
Why can't I use just the digital pins and a ground to use a potentiometer?

First of all I am a newbie. So please excuse.

After doing the first basic project, in which I had hooked up the positive of a LED to a digital input of the Arduino and the negative to the ground of the board, I am assuming that the digital pins in Arduino are positive (are they 5v?).

So why can't the potentiometer be connected in the same way?

Thank you.

sender: assistant

body:
A potentiometer is an analog device, meaning it communicates its position by varying the voltage rather than sending discrete ones and zeros.

If a linear potentiometer is turned half way then the output of the pot will be at half the voltage of the input. If it is turned all the way then the output will equal the input voltage and if it is not turned at all then the output will be 0V.

In order to make sense of the potentiometer you must connect the output to the analog pins and it will give you a 10 bit number, the higher this number the closer the output voltage of the potentiometer is to 5v (or whatever you set the Analog Reference voltage to be, but don't worry about the AREF pin for now).

Digital pins are either on or off, there is no in between, so they do not work for this application

This page has an excellent potentiometer user guide: https://www.arduino.cc/en/Tutorial/Potentiometer


body:
> I had hooked up the positive of led to a digital input of the arduino and negative to the ground of the board.

You shouldn't have done that. It damages both the LED and the Arduino.

[The care and feeding of LEDs](http://www.thebox.myzen.co.uk/Tutorial/LEDs.html)

> So I am assuming that the digital pins in arduino are positive (are they 5v?).

Yes and yes (assuming a 5V Arduino).

> So why cant the pot be connected in the same way?

The pot has 3 terminals, so I'm not sure what you mean by that. You are going to connect them to ground, a digital pin, and **what else**?

---

Normally you connect one end of the pot to ground, the other end to +5V, and the middle terminal to one of the analog inputs. Then when you turn the pot, the voltage at the analog input changes to be somewhere between 0V and 5V.

---

A [potentiometer](https://en.wikipedia.org/wiki/Potentiometer) is a form of [voltage divider](https://en.wikipedia.org/wiki/Voltage_divider) - I suggest you read those links to understand more about them.


body:
For connect a LED you need use a little resistor to limit the current, so you can use the potenciometer with your LED and see the bright ajust.

> I had hooked up the positive of a LED to a digital input

A Arduino digital PIN as cofigurable how input or output, if you use it as input you need use this pin for read a digital value (0 or 1), example a button. When you configure the pin to output you can set the value high (~5v) or low (0v).


body:
> I am assuming that the digital pins in Arduino are positive (are they 5v?).

On a 5V Arduino, when a GPIO pin is set to OUTPUT and switched HIGH then yes, it is (almost) 5V. When switch LOW it is (almost) 0V or GND. When it is set to INPUT it is neither - it is "high impedance" and senses the voltage on the pin using a set of *thresholds*.

When the voltage being applied to the pin is above the *high* threshold (known as *VIH*) the pin sees it as a logic HIGH and `digitalRead()` reports it as such. When the voltage being applied is *below* the *low* threshold (known as *VIL*) the pin sees it as a logic LOW and `digitalRead()` reports it as such.

> So why can't the potentiometer be connected in the same way?

So yes, you can connect a potentiometer up to to a digital pin in the same way as you can to an analog pin (one pin to +5V, one pin to ground, and the middle "wiper" pin to the digital input):

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

When you turn it, instead of reading a value between 0 and 1023 as you would on an analog pin, you will either get a HIGH or a LOW depending on how far you have turned the knob and in which direction. In the region in the middle you will read "who knows?" - that is, maybe HIGH, maybe LOW, depending on the weather and the pin itself.

Note that connecting a potentiometer up like this on a pin set to OUTPUT is dangerous (not to you, to the Arduino) and has the potential to damage the GPIO pin's internal circuitry when the pot is turned all the way one way or the other, since it creates a dead short circuit to either ground or +5V, and the GPIO pin itself, when in OUTPUT mode, is also connected internally to either ground or +5V.

Some pins on microcontrollers (not sure about the Arduino off hand) have *[Schmitt Trigger](https://en.wikipedia.org/wiki/Schmitt_trigger)* inputs. These avoide the "who knows?" region by toggling the input HIGH or LOW depending on when the voltage passes a threshold. For the pin to change from reporting a LOW to a HIGH the voltage has to pass above the high threshold. To then switch to reporting a LOW again it has to drop all the way down to the low threshold. Any voltage in between the two thresholds is ignored completely and the previous state is retained.

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


body:
It depends on what you are trying to accomplish.  If you set the pin as output and turn it on, then can use it as 5v power source. This is done frequently when you want the software to be able to turn some part of your system on/off.  If this is what you want, you can put a pot or any other component downstream as long as it doesn't try to draw too much power. See [this post][1] for details on that

If you are trying to read the "value" of the pot, it would work as an on/off switch because this is a digital pin. Digital means 0 or 1. When there is enough voltage, it will register as 1, once the voltage gets low enough, it will register as a zero.  If you want to read a full range of values from the pot, you would have to use an analog pin.

  [1]: https://electronics.stackexchange.com/questions/67092/how-much-current-can-i-draw-from-the-arduinos-pins


body:
Analog pot on digital pin will give,
0:from min to half way and
1: from half way to end position
You can use it if this suits your program logic.


message:
Why is my code only reading the change of the encoder's pin A?

I am writing code for reading in a quadrature encoder. I used attachInterrupt on pin 2 and 3, but by using the same ISR.

        int encAPin= 2;
        int encBPin= 3;
        volatile int encAValue= 0;
        volatile int encBValue= 0;
        volatile int encCount= 0;

        void setup() {
          // put your setup code here, to run once:
          pinMode(encAPin, INPUT);
          pinMode(encBPin, INPUT);
          attachInterrupt(digitalPinToInterrupt(encAPin),encUpdate, CHANGE);
          attachInterrupt(digitalPinToInterrupt(encBPin),encUpdate, CHANGE);
          Serial.begin(9600);
        }

        void loop() {
          // put your main code here, to run repeatedly:
          Serial.println(encCount);
        }

        void encUpdate() {
          if(digitalRead(encAPin)==RISING){
            if(digitalRead(encBPin)==LOW){
              encCount++;
            }else if(digitalRead(encBPin)==HIGH){
              encCount--;
            }
          }
          if(digitalRead(encAPin)==HIGH){
            if(digitalRead(encBPin)==RISING){
              encCount++;
            }else if(digitalRead(encBPin)==FALLING){
              encCount--;
            }
          }
          if(digitalRead(encAPin)==FALLING){
            if(digitalRead(encBPin)==HIGH){
              encCount++;
            }else if(digitalRead(encBPin)==LOW){
              encCount--;
            }
          }
          if(digitalRead(encAPin)==LOW){
            if(digitalRead(encBPin)==FALLING){
              encCount++;
            }else if(digitalRead(encBPin)==RISING){
              encCount--;
            }
          }
        }

When I tried Serial.print to check whether or not the pin A's and B's inputs were changing, I noticed that only pin A's (pin 2) input was changing. I made sure that the circuit and the wiring were all correct. Is there something about my code that is not reading pin B's input properly?

body:
You're confusing interrupt *events* and pin *states* here.

A pin can be either HIGH or LOW. Never anything else.

An interrupt can trigger on one of four events:

1. The pin transitions from HIGH to LOW (`FALLING`)
2. The pin transitions from LOW to HIGH (`RISING`)
3. The pin transitions from one state to another (`CHANGE`)
4. The pin remains low (`LOW`)

Your code should be (as you have done) attaching the interrupt to the pins using `CHANGE` so you can see any change in the state of the pins.

Your interrupt code should then examine the two pins to see their current state.

But there is one bit missing from your code, and that is *what was the state **before** this interrupt triggered?* - i.e., from what did the pins change from to get to this state?

The simplest way of coding this kind of thing is to think of each pin as a bit in a 2-bit binary number. Join the two pins together to form a number between 0 and 3:

    uint8_t pinVal = (digitalRead(encBPin) << 1) | digitalRead(encAPin);

The truth table for that would be:

    B | A | B<<1 | pinVal
    0 | 0 |  00  |   00 (0)
    0 | 1 |  00  |   01 (1)
    1 | 0 |  10  |   10 (2)
    1 | 1 |  10  |   11 (3)

There you have 4 states. And if you remember that state from one interrupt call to the next, you can compare the current value to the previous value. And that is where you get your 8 states from.  Encoders use *[Gray Code](https://en.wikipedia.org/wiki/Gray_code)* so the sequence of numbers you would get as you rotate the encoder would be:

    0, 1, 3, 2, 0, 1, 3, 2 ...

Or the other way:

    2, 3, 1, 0, 2, 3, 1, 0 ...

And it's the transition between those values that tells you what the encoder is doing:

    0 <-> 1 <-> 3 <-> 2 <-> 0 ...

Each of those transitions can go two ways, and if you count the arrows (`<` and `>`) there are 8 of them there, which are the 8 states you were thinking of before.

So if the previous value is stored in `oldVal` from the last time the interrupt triggered, and the new value is in `newVal`, your 8 states are:

* oldVal == 0 && newVal == 1
* oldVal == 1 && newVal == 3
* oldVal == 3 && newVal == 2
* oldVal == 2 && newVal == 0
* oldVal == 0 && newVal == 2
* oldVal == 2 && newVal == 3
* oldVal == 3 && newVal == 1
* oldVal == 1 && newVal == 0

The first four are progressing in one direction, the last four in the other - one set is clockwise, one is anti-clockwise.

So you could have an (untested) interrupt handler that looks something like this:

    void encUpdate() {
        static uint8_t oldVal = 0; // Static variable to remember the last state
        uint8_t newVal = (digitalRead(encBPin)) << 1 | digitalRead(encAPin);

        if (
            (oldVal == 0 && newVal == 1) ||
            (oldVal == 1 && newVal == 3) ||
            (oldVal == 3 && newVal == 2) ||
            (oldVal == 2 && newVal == 0)) {
                encCount++;
        } else {
            encCount--;
        }
        oldVal = newVal;
    }

You notice I've only implemented the comparison for the first four states and not the last four. Since there are only 8 states, and those states cause one of only two things to happen, if it's not one of the first four states, which would increase your count, it must then be one of the last four states which decrease your count. No point in checking for them since it can't be anything else.  If you turned it clockwise then increase the value. Otherwise you must have turned it anti-clockwise since there is no other direction you can possibly turn it in, so decrease the count.

This is precisely why Gray Code is used - only one pin ever changes at a time, so there is no ambiguity in what has happened - either you turned it one code-point in one direction or you turned it one code-point in the other. Even if there is lots of bounce it will just bounce between two neighbouring code-points and settle on the final new code point (as long as the interrupt can react fast enough to catch all the bounces).


message:
Different functions using 2 buttons

I'm currently learning Arduino. So right now I'm trying to create an Arduino app that will use buttons, LEDs and RGB.

So I have 2 buttons, 8 LEDs and an RGB. The first button is the function switcher: when you press it the LED will light according to their function. The second button is the function activator so right now here's I want to do:

- Function 1: Turn on/off RED light
- Function 2: Increase RED light brightness by 5; if already at 255, reset at 0
- Function 3: Turn on/off GREEN light
- Function 4: Increase GREEN light brightness by 5; if already at 255, reset at 0
- Function 5: Turn on/off BLUE light
- Function 6: Increase BLUE light brightness by 5; if already at 255, reset at 0
- Function 7: Turn on ALL lights, all brightness to 255
- Function 8: Turn off ALL lights, all brightness to 0

I already started coding and I'm stuck at turning on and off the red light. Here's my code:

    const int red = 5;

    int b1, b2; //Buttons
    int dir = 0;
    int light = 11;
    int func = 0;
    boolean buttonValue = true;
    boolean buttonState = true;

    void setup() {
      pinMode(2, INPUT);
      pinMode(3, INPUT);
      pinMode(red, OUTPUT);
      for (int i = 11; i <= 18; i++) {
        pinMode(i, OUTPUT);
      }
    }

    void loop() {
      b1 = digitalRead(2);
      if (b1 == HIGH) {
        dir = 2;
        func++;
        if (func >= 8)
          func = 0;
        } else {
          dir = 0;
        }
        digitalWrite(light, LOW);
        if (dir == 2 && light < 18) {
          light++;
        }
        digitalWrite(light, HIGH);
        delay(200);
      }

    void function(int pin) {
      b2 = digitalRead(3);
      switch (func) {
        case 1:
          if (b2 = true) {
            digitalWrite(5, HIGH);
          } else {
            digitalWrite(5, LOW);
          }
      }
    }

body:
If you would like to call the function you defined at the end of your code you need to give it a name `function name()...`.

In your code you used `if (b2 = true)`. That will not work as expected, since it sets the `b2` variable to `true`. Note the `if` expressions use `==` to compare values, [see the Arduino Reference](https://www.arduino.cc/en/Reference/If). Further you should use the `HIGH` and `LOW` Pin level constants for comparing pin states as described [here](https://www.arduino.cc/en/Reference/Constants).

So your code will look like
`
    if (b2 == HIGH) {
        digitalWrite(5, HIGH);
    } else {
        digitalWrite(5, LOW);
    }
`

or shorter just:
`digitalWrite(5, b2);` without the if/else expressions.


body:
I have to be honest after reading you description and looking at you code I have no idea how you arrived at the code you have arrived at.

For now lets try a much simpler bit of code, once that is working you can build on it.

    #define PIN_BUTTON_1 2
    #define PIN_LED_RED  5

    void setup() {
     pinMode(PIN_BUTTON_1, INPUT);
     pinMode(PIN_LED_RED, OUTPUT);
    }

    void loop() {
     const int buttonState1 = digitalRead(PIN_BUTTON_1);
     digitalWrite(PIN_LED_RED, buttonState1);
     delay(200);
    }

If that code doesn't work then there is something wrong electrically.

I think is the next step you were trying for:

    #define PIN_BUTTON_1 2
    #define PIN_LED_RED  5

    int lastButtonState1 = LOW;
    int functionNumber = 0;
    int currentLedValue = 0;

    void setup() {
     pinMode(PIN_BUTTON_1, INPUT);
     pinMode(PIN_LED_RED, OUTPUT);

    }

    void loop() {
     const int currentButtonState1 = digitalRead(PIN_BUTTON_1);
     if (lastButtonState1 != currentButtonState1)
     { // If the button's state has changed
      if (currentButtonState1 == HIGH)
      {
       ++functionNumber;
      }
      lastButtonState1 = currentButtonState1;
     }
     DoFunction(functionNumber);
     delay(200);
    }

    void DoFunction(const int& function)
    {
     switch (function)
     {
     case 1:
      if (currentLedValue > 0)
      {
       currentLedValue = LOW;
      }
      else
      {
       currentLedValue = HIGH;
      }
      digitalWrite(PIN_LED_RED, currentLedValue);
      break;
     case 2:
      currentLedValue = 128;
      analogWrite(PIN_LED_RED, currentLedValue)
      break;
     default:
     }
    }


message:
Best way to send text to ESP8266 remote display

I need a remote display to show information sent via WiFi from another ESP8266. What needs to be sent is a string along with some variables, for example a string to be displayed along with two integers for the position on the display:

    0, 12, "message to display on screen"

As I am absolutely new to network stuff, what would be the best way to achieve this?

 - Sending a POST request through REST API?
 - Use UDP instead?
 - Or better use a framework like MQTT?

body:
Try the [esp8266 UDP messages][1]

With UDP you can send and receive messages quite easily and without consuming lots of resources.

  [1]: https://github.com/esp8266/Arduino/blob/master/doc/esp8266wifi/udp-examples.md


message:
Error while trying to drive relay through the state of a digital input pin in Arduino

I'm trying to change the state of a relay according to the state of a digital input in an Arduino with an ethernet shield. It works sometimes and some other times it doesn't work.

**My code:**

    const int led1 = 2;
    const int enable1 = 4;
    boolean led1_OnOff;

    void setup() {
      led1_OnOff = false;
      pinMode(enable1, INPUT);
      digitalWrite(enable1, LOW);
      pinMode(led1, OUTPUT);
    }

    void loop() {
      if(digitalRead(enable1) == HIGH) {
        if(led1_OnOff == true) {
          led1_OnOff = false;
        } else {
          led1_OnOff = true;
        }
      }

      if(led1_OnOff == true)
        digitalWrite(led1, HIGH);
      else
        digitalWrite(led1, LOW);
    }

**My schematics:**

Relay 5v -> arduino 5v
Relay gnd -> arduino gnd
Relay in -> digital pin 2
Relay com -> 220 AC
Relay NC -> 220 AC
Push button pin 1 -> Arduino 5v
Push button pin 2 -> digital pin 4

Pin 2 is connected to the relay enable pin and pin 4 is connected to a push button and the boolean is used for saving the state.

Can anyone tell me what the problem is, and why the relay doesn't work most of the time?

body:
Assuming your circuit is correct (and perhaps it is, since you imply that it works *some* of the time), the first obvious problem is that when you press the button, the code will repeatedly toggle the output, very very fast.  It may seem to you like you're only pressing the button for a moment, but the code will loop many many times.  When you release the button, it's a 50/50 chance whether it leaves the relay on or off.

To solve this, you can wait until the button is released before checking again.

In addition to this, you may have switch bounce.  There are nicer ways of fixing this, but for your stated purpose, waiting 0.1s after a releae before checking the button again is probably sufficient.

    ....
    void loop() {
      if(digitalRead(enable1) == HIGH)
      {
        if(led1_OnOff == true)
        {
          led1_OnOff = false;
          //+digitalWrite(led1, LOW);
        }
        else
        {
          led1_OnOff = true;
          //digitalWrite(led1, HIGH);
        }

        // Wait for the button to be released
        while(digitalRead(enable1) == HIGH)
        {
          // do nothing, just wait
        }
        // Poor-man's debounce
        delay(100);
      }

      if(led1_OnOff == true)
        digitalWrite(led1, HIGH);
      else
        digitalWrite(led1, LOW);
    }


body:
I modified my code and added some code for button debounce and added 10k ohm pull down resistor to my hardware and it works like a charm now.

**my new code :**

    const uint8_t led1 = 6;
    const uint8_t enable1 = 7;
    const uint16_t buttonConfidenceLevel = 500;
    boolean led1_OnOff;

    uint16_t pressedConfidenceLevel;
    uint16_t releasedConfidenceLevel;
    boolean pressed;

    void setup() {
        led1_OnOff = false;
        pinMode(enable1, INPUT);
        pinMode(led1, OUTPUT);

     pressedConfidenceLevel = 0;
     releasedConfidenceLevel = 0;
     pressed = false;
    }

    void loop() {
     if(isButtonPressed()) {
      // Button is pressed
      led1_OnOff = !led1_OnOff;

      if(led1_OnOff == true)
        digitalWrite(led1, LOW);
      else
        digitalWrite(led1, HIGH);
     }

    }

    boolean isButtonPressed() {
     if(digitalRead(enable1) == HIGH) // button is sensed pushed down
     {
      releasedConfidenceLevel = 0;

      if(pressed == false)
      {
       pressedConfidenceLevel++;

       if(pressedConfidenceLevel > buttonConfidenceLevel)
       {
        pressedConfidenceLevel = 0;
        pressed = true;

        // Button is pressed
        return true;
       }
      }
     }
     else // button is sensed released
     {
      pressedConfidenceLevel = 0;

      if(pressed == true)
      {
       releasedConfidenceLevel ++;

       if(releasedConfidenceLevel > buttonConfidenceLevel)
       {
        releasedConfidenceLevel = 0;
        pressed = false;
       }
      }
     }

     return false;
    }


body:
First, how you are set a pin as input and **write** in this pin?

>  pinMode(enable1, INPUT);
>
> digitalWrite(enable1, LOW);

You dont need compare a boolean with true

> if(digitalRead(enable1) == HIGH)

is the same as:

    if(digitalRead(enable1))

use a debbounce with a button state flag to change the button state

    if( digitalRead(enable1))
           ena_deb++;
           if(ena_deb > 5){
                change_en_state
           }
    }else{
        change_en_state = 0
    }

    if(change_en_state == X)
        change_output_value;


message:
Custom source directory

How do you specify a custom location for your sketch?

I want my code to be located in a `src` folder, but when I try to compile my `main.ino`, `arduino` complains `"The file main.ino needs to be inside a sketch folder named "main".` How do I disable this arbitrary restriction?

body: You can't. It's a feature of Processing, on which the Arduino IDE is based.


body:
I found I could accomplish this using the [arduino-builder][1] tool. I created this simple bash script to do the compilation:

    #!/bin/bash
    CURRENT_DIR=`pwd`
    mkdir -p $CURRENT_DIR/.build
    arduino-builder -compile -hardware /usr/share/arduino/hardware -tools /usr/share/arduino/hardware/tools -tools /usr/share/arduino/tools-builder -libraries $CURRENT_DIR/lib -fqbn arduino:avr:uno -build-path $CURRENT_DIR/.build $CURRENT_DIR/src/main.ino

  [1]: https://github.com/arduino/arduino-builder


message:
Is there any way I can light up a candle with an Arduino?

I want to make a candle flame light up triggered by a microcontroller. Is it possible? I only want to light it up. Not turn it down. Moreover, this is for a one-time use so the candle burning down and becoming shorter is not a problem.

body:
If you have a circuit, you can switch it on and off using a microcontroller.

So what you need is a circuit which can light a candle.  Have a look at these:

[DIY arc lighter][1]

[CCFL Inverter becomes an Arc Lighter?][2]

I predict your main problem will be dealing with the fact that candles get shorter as they burn.

  [1]: https://www.youtube.com/watch?v=lk_1lzMiUVc
  [2]: https://www.youtube.com/watch?v=SK0p1PFiXI4


body:
Use two rods at either side of the candle, and engineer two motors to slide op and down these rods. Meccano kung-fu.

Use limit switches to detect the highest and lowest positions for both motors. Mount a LED on one motor, and a laser (5 mW red is plenty). From the bottom, have both motors ascend, until the LED can receive data transmitted by the laser. Yes, you can most certainly use a laser diode for Serial.print.

When at the right height, engage gasburner. You can use an LDR (shielded against light from the sides with heatshrink) to check if the candle has been lit - shortly after disengaging gasburner. You will need a reading prior to each ignition.

Let me know how that works out.


body:
A simple solution is too use nichrome wire which when a current is passes through it will heat up. You could wrap some of this wire around the wick on the candle and then power it either straight from your arduino or you could include a capacitor.
This is much safer than some of the other methods which use potentially dangerous high voltages.

I tested the nichrome wire approach and it works! See following video clip. 2 Ohm resistance and 19V for 1 second.  https://1drv.ms/v/s!AvcBubMtAczvifYZwoESAhUodOoqRA


body:
Have you considered using a servo with a high torque, and a piezo-electric butane lighter?

The high torque would be required to push the lighter button as these tend to be rather stiff. Also, they do not always work on the first press and so a few attempts by the servo may be required. A [Dynamixel AX-12A](http://www.trossenrobotics.com/dynamixel-ax-12-robot-actuator.aspx) could do the job, but pricey, and could be overkill.

To save some money and time, measure the torque required to push the lighter button first and then get a servo/actuator to match.

Alternatively, use a gas oven lighter, again in conjunction with a linear actuator.


body:
Functioning proof of concept.

Ni-chrome wire from hair dryer, approximately 2 Ohms, powered by 19 V for about 1 second. [video of proof of concept][1]. Lots to work out still, but this obviously can work.

  [1]: https://1drv.ms/v/s!AvcBubMtAczvifYZwoESAhUodOoqRA


message:
Serial parsing strange data

I have a project where I use a software serial connection to read serial data from a barcode scanner.

All is good. However from time to time I have some problems with the data that I'm receiving.

> You said : 123456789��?�: @���?���?���?���?���?
>
> You said : 123456789
>
> You said : 123456789123456
>
> You said : 987654321789456123

My code is something similar to the one below
<!-- language-all: lang-cpp -->

    int count = 0;
    void parseSerial() {
      char ser[20];
      while (Serial.available() > 0) {
        char c = Serial.read();
        if ( c != '\r' && count <= sizeof(ser)) {
          ser[count] = c;
          count++;
        } else {
          Serial.print("You said : ");
          Serial.println(ser);
          for(int i=0; i < sizeof(ser); i++) {
            ser[i] = '\0';
          }
          count = 0;
        }
      }
    }

Any idea on how I can get rid of "��?�: @���?���?���?���?���?"?

Thanks.

body:
The problem is that the buffer is not initialized to start with. When
you call `parseSerial()`, it contains garbage, which is what you see on
the serial monitor. In order to avoid printing out that garbage, you
have to properly terminate the string, i.e. add a `\0` after the last
valid character.

You did that _after_ printing the string (you filled the whole buffer
with `\0`, which is overkill), but that's too late. The subsequent
printouts are OK though.

The recommended way to handle incoming serial data is to look for a
terminating character (`\r` seems to be what you expect), and buffer
all the incoming bytes until you see it. Don't forget to save 1 byte of
buffer space for the terminating `\0`:

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

    void parseSerial() {
        static char buffer[20];
        static int count = 0;

        while (Serial.available()) {
            int c = Serial.read();
            if (c == '\r') {           // received complete line
                buffer[count] = '\0';  // terminate the string
                Serial.print(F("You said: "));
                Serial.println(buffer);
                count = 0;
            }
            else if (count < sizeof buffer - 1) {
                buffer[count++] = c;
            }
        }
    }

Notice that the buffer here being static, you can accumulate partial
messages through successive calls to `parseSerial()`. Only when the
message is complete will it print it back.


body:
Why are you using char array when you can use String. And use Serial.readStringUntil('\r'); instead Serial.read.

Code:
```cpp

void parseSerial(){
String read = " ";
int count = 0;
if(Serial.available()>0){
while(Serial.available()>0){

if(count != 20){
read = Serial.readStringUntil('\r');
count++;
}
}

}
Serial.println("You said: ");
Serial.print(read);
}

```


message:
Multiple buttons on single interrupt, how to debounce?

Buttons on separate interrupt pins work fine (triggered on *FALLING*), bouncing is handling by forcing a 80ms lockout period during which further presses are ignored. I like that solution for being lightweight.

My goal is to have 1 interrupt handle all events (buttons and other digital inputs). I don't want to depend on *loop()*, I wish to be free to use *delay* often rather than timer interrupts.<br>
Most buttons execute an action when pressed, some, while pressed.

What I have now (just 2 buttons for now):
<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/lW4oK.png)

<!-- End schematic -->

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

    void setup() {
      pinMode(17, INPUT_PULLUP);
      pinMode(16, INPUT_PULLUP);
      pinMode(3, INPUT_PULLUP);
      attachInterrupt(digitalPinToInterrupt(3), wotHappnd, CHANGE);
    }

    boolean isDebouncing(){
      unsigned int now = millis();
      if(now - time_lastPressed > time_debounceLockout){
        time_lastPressed = now;
        return false;
      }
      return true;
    }

    void wotHappnd(){
      boolean interruptFalling = digitalRead(3) == LOW;
      if(interruptFalling && isDebouncing()) return;
      // digitalRead the pins; do stuff
    }

Internal pullups on all used pins.

My problem is that often (~4%), on interrupt, the interrupt pin is *LOW* all button pins are *HIGH* ("not pressed" - likely bouncing just as I read it). How to fix that?

Can't use *delay* during an interrupt; *delayMicroseconds* to wait for stable readout still feels inappropriate; a cap-based delay on the interrupt pin induces a period of floating.
Prefer solutions in software or with no more than 1 extra component per input.

**[edit]** [here](https://electronics.stackexchange.com/a/236692/65089)'s a claim that pin interrupts do some filtering already, which, if true, may make some solutions unreliable.

body:
In the Isr, read the two pins and maintain their current status (UN debounced), and reset a counter.

In the main loop, increment that counter. If it is more than a certain number, it means that the current state of the key has been stable for a while - bounce no more.

Or Google Kuhn debounced. I wrote a blog page about that. If you want, I can post it later. The basic idea is the same.


body:
As ever I am the voice of dissent: never write software to solve a hardware problem.

For a double-throw switch the classic solution is an SR latch.

Single throw is actually harder. On the face of it, debounce is a trivial matter done with a capacitor and a pull-down (or pull-up) resistor. This will certainly stop floating and false positives from induced current from spikes. However, microprocessors switch pretty fast and will recognise the edges of microsecond oscillations around the switching voltage as changes of switch state. To prevent this you need the hysteresis of a [Schmitt Trigger][1] such as an [LM7414][2] (TTL) or [LM7417][3] (suitable for 3V3).

Here is the debounce circuit suggested in [Understanding Schmitt Triggers][1]. Unfortunately, it doesn't behave correctly under all conditions, for reasons explained on the Ganssle page referenced later.

[![Almost, but misbehaves under out of spec conditions][4]][4]

You can fix the problem with a diode. For TTL, R1 = 82kΩ, R2 = 18kΩ, C = 1µF

[![robust][6]][6]

Larger values of C will absorb slower bounces. One of my projects has a relay that bounces for so long I needed 470µF.

[Here's what I regard as the last word on the subject — the Ganssle page.][7] There's even a solution for multiple buttons on a single input. This is not quite the same as multiple buttons on a single interrupt but I think the approach may be applicable.

Note that on the Ganssle page a software solution is touted as cheaper than hardware. That's irrelevant for a one-off, true for mid sized runs and potentially false for mass produced items. Debugging software has its own costs and so does product recall. Make your decision in context. Arduino projects are usually one-off.

One objection to a hardware solution is cost, in assembly time, component count and board size. For hobby work that's a personal choice, and for commercial work it's a trade-off between simplicity and reliability. Reliability of _software_ hinges on deterministic behaviour and the management of complexity. The Atmel chip doesn't have a _lot_ of DRAM or program space, and moving this problem out of the software will make it smaller, simpler and more predictable.

That's not to say there aren't _other_ ways to deal with the problem.

If you really want to do it in software you need to measure the pulse width and compare it to a threshold. Since you need both falling and rising edges for this, bind to CHANGE and test for state. The primary difference between this and the Kuhn method mentioned by others is it uses the clock instead of a counter allowing you to specify millisecond duration rather than iterations.

In the excerpt below, the `listen` flag is a simple alternative to noInterrupt() or unbinding the handler. My loop code evaluates a state machine transition function for current state and inputs, and not all states want input.

```
void isr_change()
{
 if (listen)
 {
  unsigned long now = millis();
  int d2 = digitalRead(2);
  if (d2 == LOW || fall_time == 0)
  { // FALLING
   fall_time = now;
  }
  if (d2 == HIGH)
  { // RISING
   command_pending = now - fall_time > MIN_PULSE_MS;
  }
 }
}

```

The state machine doesn't look at digital inputs, it looks at the `command_pending` flag, which is reset after the transition function finishes.

This is one of those things that looks simple, isn't, but does have a stock solution. It beats me why there isn't a mass produced debouncer component the way you can get op-amps.

Thank you to kaay in comments for referring me to the MC14490 which is a DIP16 or SOIC16 with six diode protected debouncers. Kaay thinks it's expensive but consider the cost of the time to code and debug debounce of six inputs. What about the cost when the program doesn't quite fit and you have to rewrite it to shrink it? And then regression test _everything_. Would you pay someone $5 for an instant guaranteed result that doesn't complicate or bloat your software? The economics change with production scale of course, but in very small runs I think it's well worthwhile.

I found the MC14490 DIP16 for 5USD and the SOIC for 9AUD online. Local shops didn't carry it.

  [1]: http://www.ti.com/lit/an/scea046/scea046.pdf
  [2]: https://www.onsemi.com/pub/Collateral/MC74HC14A-D.PDF
  [3]: http://www.ti.com/lit/ds/symlink/sn74aup1t17.pdf
  [4]: https://i.stack.imgur.com/pULTP.png
  [5]: https://i.stack.imgur.com/e1JQb.png
  [6]: https://i.stack.imgur.com/Mdiua.png
  [7]: http://www.ganssle.com/debouncing-pt2.htm


message:
Serial Connection

I was trying to communicate with my arduino uno over the serial connection from the USB. Connecting to it is usually not a problem, but what buggs me is the first transaction of the data... No matter with what I do it, java code or the serial monitor which comes with the IDE, I always have the problem that usually only one Byte is being transfered or received from the Arduino. What could be the problem? Is it just a bug and I have to live with it or can this somehow be fixed?

My Arduino Code:

    #include "RGBdriver.h"
    #define CLK 10
    #define DIN 11

    RGBdriver driver(CLK, DIN);
    byte red = 0;
    byte green = 0;
    byte blue = 0;

    byte newRed = 0;
    byte newGreen = 0;
    byte newBlue = 255;

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

    void loop() {
      if (Serial.available() >= 3) {
        newRed = Serial.read();
        newGreen = Serial.read();
        newBlue = Serial.read();
      }

      if ((red != newRed) || (green != newGreen) || (blue != newBlue)) {
        red = newRed;
        green = newGreen;
        blue = newBlue;

        driver.begin();
        driver.SetColor(red, green, blue);
        driver.end();
      }
    }

body: Consider giving sufficient delay to initiate the time to receive the data. The loop would otherwise terminate since the data received is less than 3


message:
Why does "!=LOW" != "HIGH"?

I'm learning about accessing ports directly on the ATMEGA 328 using an Arduino Uno. The program sets up pin 13 as an output and pin 2 as an input. I then enable the pull up resistor on pin 2.

I read Pin 2 and set the LED high or low depending on if pin 2 is high or low.

**Why is it that I cannot seem to use == HIGH in my if statement instead of != LOW?**

    void setup() {
      MCUCR &= ~(1 << 4); //disables pull-up disable (redundant as default is off)
      DDRB |= (1 << 5); //sets pin 13 (B5 on ATMEGA 328) as output
      DDRD &= ~(1 << 2); //sets pin 2 (D2 on ATMEGA 328) as input (redundant as default is input)
      PORTD |= (1 << 2); //since it's an input sets pull-up resistor ON
      PORTB &= ~(1 << 5); //sets pin 13 (B5 on ATMEGA 328) as LOW

    }

    void loop() {
      if ((PIND & (1 << 2)) != LOW) PORTB |= (1 << 5); //sets pin 13 (B5 on ATMEGA 328) as HIGH
      else PORTB &= ~(1 << 5); //sets pin 13 (B5 on ATMEGA 328) as LOW
       delay(100);

    }

body:
Because

    ((PIND & (1 << 2)) != LOW)

means exactly

    (PIND & 4) != 0

and that is true if PIND is 4, 5, 6, 7, 12, 13, ... (any number having 4 in it binary), so it yelds

    4 != 0

Which is definitively not equal

    4 == 1

---
BTW: in C any integer != 0 is true and 0 is false, so you can as well write:

    if (PIND & (1 << 2)) PORTB |= (1 << 5); //sets pin 13 (B5 on ATMEGA 328) as HIGH


body:
    if ((PIND & (1 << 2)) != LOW) PORTB |= (1 << 5); //sets pin 13 (B5 on ATMEGA 328) as HIGH
      else PORTB &= ~(1 << 5); //sets pin 13 (B5 on ATMEGA 328) as LOW

PIND & (1<<2) will return a value of either (1<<2) if PD.2 is high, or 0 if PD.2 is low.

So it basically says that if PD2 is high, set PB5; otherwise, clear PB5.`enter code here`


message:
Arduino digital output pin controling relay problem

I try my code to change the state of a relay on pushing a push button buy checking the state of a digital pin.

**My code :**

    const int led1 = 6;
    const int enable1 = 7;
    boolean led1_OnOff;
    long now;
    int minSecsBetweenUpdates = 1; // 1 seconds
    long lastSend = -minSecsBetweenUpdates * 1000l;

    void setup() {
      led1_OnOff = false;
      pinMode(enable1, INPUT);
      pinMode(led1, OUTPUT);
    }

    void loop() {
      now = millis();
      if (now > (lastSend + minSecsBetweenUpdates * 1000l))
      {
        if(digitalRead(enable1) == HIGH)
        {
          lastSend = now;
          if(led1_OnOff == true)
          {
            led1_OnOff = false;
            //+digitalWrite(led1, LOW);
          }
          else
          {
            led1_OnOff = true;
            //digitalWrite(led1, HIGH);
          }
        }
      }

      if(led1_OnOff == true)
        digitalWrite(led1, HIGH);
      else
        digitalWrite(led1, LOW);
    }

But the code keeps on looping and the relay keep changing it's state as if pin 7 is always high, I'm sure of my schematic but I don't know what's wrong with my code.

**for those who want my schematic:**

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

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

body:
Your problem is that you are basically saying "while the pin is HIGH toggle the relay" rather than "When, and only when, the pin *transitions from LOW to HIGH* do I toggle the relay".

To do that you must remember what state the pin was in during the last iteration:

    const uint8_t led1 = 6;
    const uint8_t enable1 = 7;

    void setup() {
        pinMode(enable1, INPUT);
        pinMode(led1, OUTPUT);
    }

    void loop() {
        static bool led1_OnOff = false;
        static bool lastValue = digitalRead(enable1);

        bool currentValue = digitalRead(enable1);

        if (currentValue != lastValue) {
            lastValue = currentValue;
            if (currentValue == HIGH) {
                led1_OnOff = !led1_OnOff;
                digitalWrite(led1, led1_OnOff);
            }
        }
    }


body:
You say your switch is between pin 7 and +5v.  Therefore you will need a pull-down resistor on pin 7.

You say that setting pin 7 to an output works.  However you are very likely to burn out the output like this.  A pull-down resistor is the way to go.


message:
Brushless motor + ESC with Arduino question

Sorry in advance as I'm still a rookie with Arduino projects. My goal is to use an Arduino Uno 3 to create an inexpensive drone/plane project.

Here are my materials and my set up:

 - [A2212 1000kv Brushless Motor][1]
 - [HW30A Brushless Motor Speed Controller (ESC)][2]
 - Arduino Uno R3
 - bunch of cables
 - 9 V battery

Upon compiling the code I found [here][3] and connecting the 9 V battery to the ESC, all I hear is constant beep sounds from the motor (about once every 1.5 seconds). Can anyone help me figure out what's going on? Is it the 9 V battery that's not giving the motor enough juice? Or am I just too silly hoping to create something that works under $10?

    #include <Servo.h>
    Servo ESC1;

    int pos = 0; //Sets position variable

    void arm() {
      setSpeed(0); //Sets speed variable delay(1000);
    }

    void setSpeed(int speed){
      int angle = map(speed, 0, 100, 0, 180);
      //Sets servo positions to different speeds ESC1.write(angle);
    }

    void setup() {
      ESC1.attach(9); //Adds ESC to certain pin. arm();
    }

    void loop() {
      int speed; //Implements speed variable
      for(speed = 0; speed <= 70; speed += 5) {
        //Cycles speed up to 70% power for 1 second
        setSpeed(speed);
        //Creates variable for speed to be used in in for loop
        delay(1000);
      }
      delay(4000); //Stays on for 4 seconds
      for(speed = 70; speed > 0; speed -= 5) {
        // Cycles speed down to 0% power for 1 second
        setSpeed(speed); delay(1000);
      }
      setSpeed(0);
      //Sets speed variable to zero no matter what
      delay(1000);
      //Turns off for 1 second
    }

[![Full build][4]][4]
[![Battery][5]][5]
[![Arduino][6]][6]

  [1]: http://www.ebay.com/itm/371792238120?_trksid=p2060353.m2749.l2649&ssPageName=STRK:MEBIDX:IT
  [2]: http://www.ebay.com/itm/131988260966?_trksid=p2060353.m2749.l2649&ssPageName=STRK:MEBIDX:IT
  [3]: http://www.instructables.com/id/How-to-run-an-ESC-with-Arduino/
  [4]: https://i.stack.imgur.com/eDCaN.jpg "Full build"
  [5]: https://i.stack.imgur.com/WYvCh.jpg "Battery"
  [6]: https://i.stack.imgur.com/i3Wm0.jpg "Arduino"

body:
The beeping is actually from the ESC. I believe that this model needs to be properly configured (which you can do using the Arduino - refer to the user manual or [here][1]) before it can be used. Some kits come with it preconfigured but since you seem to have possibly purchased it individually you need to configure it yourself. Also it doesn't appear to be that your code wouldn't actually send any PWM signals to the ESC. I've only ever used Servo.write() functions in my quads, so I can't be 100% sure on that.

  [1]: http://www.instructables.com/id/ESC-Programming-on-Arduino-Hobbyking-ESC/


body: You need high current for working with this motor, 8.4 LiPo battery for example.


body:
Like the previous answer stated, you should be using a 20-25c battery (can discharge up to 25A). I don't know exactly how much a 9V draws, but it definitely can't supply more than an AMP. Your motor pulls much more than 1 amp. Get yourself a nice LiPo from hobbyking.com, maybe an 8.4v or 11.1v

The ESC beeping could be telling you it can't draw enough Amps from the battery?


body:
Probably a bit late but your code has some important parts commented out such as (in order):

- delay(1000);
- ESC1.write(angle);
- arm();

Once you add those to the next lines the program should work and the esc shouldn't just beep and actually get the motor to spin


message:
Low Power Pin Change Detection (ATtiny)

I want to use an ATtiny as data logger for the opening and closing of a door/window. For that I am using a reed-switch. Since I want to run it from a 3V coin battery, long term power consumption is crucial. Therefore the ATtiny (currently 13A) is in system down mode most time and is only listening to Pin-Change-Interrupts. Depending on the state of the reed-switch the power consumption differs in an order of magnitude.

 - switch open:    0.1µA
 - switch closed: 74.5µA
 - my Multimeter has a tolerance of ±0.1µA

This is a difference of an order of magnitude. But it is plausible as the datasheet of the ATtiny13A states in chapter 10 that a GPIO pin can only be pulled up and is otherwise dangling. The pull-up resistor is somewhere between 20k and 50k as stated in chapter 18.2.

So in my setup the pin is pulled up and the reed-switch is grounded.

How can I reduce the power consumption in the case where the switch is closed?

Alternatively: Can I somehow revert the state of the switch, as windows and doors are closed most of the time?

The MCU is running with the 128kHz internal Clock with CKDIV8 so practically running @ 16kHz.

The minimum viable code:

    /*
      3V0               SW0
       |     |     |     |
     -----------------------
     |                     |
     |                     |
     |      ATtiny13A      |
     |                     |
     |                     |
     -----------------------
       |     |     |     |
                   TX   GND
     */

    #include <avr/interrupt.h>
    #include <avr/sleep.h>
    #include <iso646.h>
    #include <stdbool.h>
    #include <util/delay.h>

    #define BIT_SET( PORT, BIT_FIELD ) PORT |=  BIT_FIELD
    #define BIT_CLR( PORT, BIT_FIELD ) PORT &= ~BIT_FIELD

    #define TX_PIN          PB4
    #define SW0_PIN         PB0
    #define INT0_MASK       PCINT0

    // MARK: - POWER

    static void power_down(void) {
        BIT_SET(GIFR, _BV(PCIF));       // Clear interrupt signal
        BIT_SET(GIMSK, _BV(PCIE));      // Pin Change Interrupt Enabled
        sleep_enable();
        sleep_cpu();                    // Enter sleep mode
        sleep_disable();
        BIT_CLR(GIMSK, _BV(PCIE));      // Pin Change Interrupt Disabled
    }

    ISR(PCINT0_vect) {}

    // MARK: - Setup

    static void setup(void) {
        cli();

        // Set up output pins
        DDRB = _BV(TX_PIN);
        BIT_CLR(PORTB, _BV(TX_PIN));

        BIT_SET(PORTB, _BV(SW0_PIN));        // pull up interrupt pins
        BIT_SET(PCMSK, _BV(INT0_MASK));   // set PCINT0 to trigger interrupt
        BIT_SET(GIFR, _BV(PCIF));       // Clear interrupt signal
        BIT_SET(GIMSK, _BV(PCIE));      // Pin Change Interrupt Enabled
        set_sleep_mode(SLEEP_MODE_PWR_DOWN);

        sei();
    }

    static void loop() {
        BIT_SET(PORTB, _BV(TX_PIN));
        _delay_ms(1);
        BIT_CLR(PORTB, _BV(TX_PIN));

        power_down();
    }

    int main(void) {
        setup();

        while (true) {
            loop();
        }
    }

body:
The additional 80uA drain is almost certainly coming from the pull-up resistor being shunted to ground though the reed switch.

https://www.wolframalpha.com/input/?i=(3+volts)+/(50k+ohm)+in+uA

As suggested by @Edgar Bonet, one way to greatly reduce this drain is to disable the pull-up immediately when you wake from the pin going low. At this point it is possible for the pin to stay low even if the switch is no longer grounding the pin, so you need to periodically check it using a watchdog.

1. Wake from pin going low pin change interrupt
2. Disable pull-up (stops current flowing though resistor)
3. Do your logging operation.
4. Enable a watchdog wake up
5. Go back to sleep.

At this point you can wake either from (1) a watchdog or (2) pin change if the pin goes high again.

If you wake from a pin change...

1. re-enable the pull-up
2. disable the watchdog
3. go back to sleep

If you wake from the watchdog...

1. re-enable the pull-up.
2. if the pin is high now, disable the watchdog and go back to sleep.
3. if the pin is low, disable the pull-up and leave the watchdog running and go back to sleep.

The watchdog timer on this part should only use single digits of uA while running, and it should only need to be running while the switch is grounding the pin. You can set the watchdog timeout to be quite long- on the order of seconds even, to reduce the frequency you  wake to check with the pull-up (and therefore the net power used, at the cost of latency for detecting pin changes). The main downside to this strategy is that you can miss activations that happen inbetween your watchdog wake-ups, so for example if the pin goes low and then you set the watchdog for 8 seconds, and then the pin changes high and then low again during the next 8 seconds, it is possible (but not assured) that you could miss the second event, so set the watchdog timeout to be short enough that you will not miss consecutive events that you care about (you might not care if the door is opened twice in the same minute anyway).

Also, as noted by the famous @nick gammon, you might be able to get lower than 5uA when sleeping without the watchdog. Check to make sure you are disabling everything in the power register and that all unused pins are in input mode (these will be disabled when sleeping as long as there is not a pin change interrupt on them).  There are lots of googleable articles on minimizing ATTINY power during sleep.

You also mentioned that your dominant case is that the switch is closed rather than opened. Since this is the higher-power case with the current switch consider using a normally open switch rather than normally closed one if possible.

Finally, if you just want simplicity and you only care about events of a minimum duration (saym then door much be open for at least 1/2 second to be noticed), then you can skip the pin change interrupt completely and only use an always-running watchdog to wake periodically and very quickly enable the pull-up and check for the desired pin state, and then disable the pull-up and go back to sleep. You should be able to do this in less than a dozen cycles so the net power usage should be almost as low as the watchdog timer drain by itself.


body:
I'm tempted to suggest *two* reed switches (one NO and the other NC). Then depending on the window state you change to use the switch which gives you the lowest drain (you could use a spare couple of pins to activate one or the other).

Failing that, you can just sleep when the switch is open (the low-power condition) and if it is closed use the watchdog timer to check it from time to time (in other words, drop the power to the switch while asleep). The WDT only uses around 5 µA so that isn't too bad (the coin battery probably self-discharges at about that rate anyway). That would be a lot better than a constant drain of around 70 µA.

I've got an [ATtiny85 sitting in my hallway](http://www.gammon.com.au/forum/?id=12769) flashing an LED every couple of seconds. I can't recall when I replaced the battery, possibly once since I made it two years ago.


message:
WiFi.status() hangs / resets board

Using one of the RobotDyn boards with onboard WiFi and a Generic ESP8266 module.

I can load the sketch, but when `WiFi.status()` is called to see if WiFi enabled, the sketch hangs, rebooting the board after ten seconds are so.

<pre>
void setup() {
  Serial.begin( 115200 );
  Serial.println( "begin - wifi status: " );
  // program hangs here - - - - - - -
  int status = WiFi.status();
  Serial.println( status );
}
</pre>

body:
I think it might be a problem with the code you are using, prior to version 2.2.0 of the "ESP Core" the first block of code worked, since only the second version works.

It seems that you can get around it by rather than doing this:

     WiFi.begin(ssid, password); // connect to the network
     while (WiFi.status() != WL_CONNECTED)
     {
         delay(500);
     }

You should do this:

    if (WiFi.status() != WL_CONNECTED)
    {
         WiFi.begin(ssid, password); // connect to the network
         delay (500);
    }

Does that look it might be a likely cause?

Sources
 [1][1]  [2][2]

  [1]: https://github.com/esp8266/Arduino/issues/2594
  [2]: https://stackoverflow.com/questions/23280840/arduino-uno-wifi-shield-hangs-on-wifi-status


body:
Think I found the cause!

I previously had

#include <WiFi.h>

but now using

#include <ESP2866WiFi.h>

This seems to work

I was unaware of the two library sets. Since I use both `Arduino MiniPro` and versions of `NodeMCU`, am now going through the libraries and determining what breaks.

IMHO, in regard to libraries, `NodeMCU` Lua libraries are far, far better than `Arduino's` C++ libraries.


message:
TPS/MAP calculation problem - SOLVED

In my recent project, I have to create TPS/MAP table, which is provide value of LOAD.

Here, it is my table. You can see two value of LOAD which is separate by /. (TPS LOAD / MAP LOAD)

[![TPS/MAP Table][1]][1]

But now here as you can see, TPS provide different value of LOAD and MAP provide different value of LOAD. So, every cell has a two value of LOAD. So, I decide just add this both LOAD and divide it by 2.

I made program for this but it access only just LAST COLUMN and LAST ROW and it provide wrong value of LOAD. I don't understand why this happen.

Here, my code.

    float TPS[] = {0, 0.4, 0.8, 1.2, 1.6, 2, 2.4, 2.8, 3.2, 3.6, 4, 4.4, 4.8, 5};
    float MAP[] = {0.85, 0.95, 1.05, 1.15, 1.25, 1.35, 1.45, 1.55, 1.65, 1.75, 1.85, 1.9};

    float TPS_MIN = 0.00;
    float TPS_MAX = 5.00;

    float MAP_MIN = 0.85;
    float MAP_MAX = 1.90;

    float LOAD_MIN_TPS[] = {2, 3.23, 4.49, 5.73, 6.97, 8.22, 9.44, 10.63, 11.87, 13.11, 14.33, 15.00};
    float LOAD_MAX_TPS[] = {10.00, 17.08, 24.11, 31.67, 38.30, 45.73, 52.63, 60.19, 67.22, 74.52, 81.68, 85.00};

    float LOAD_MIN_MAP[] = {2, 2.64, 3.28, 3.92, 4.56, 5.21, 5.85, 6.47, 7.11, 7.76, 8.40, 9.05, 9.69, 10.00};
    float LOAD_MAX_MAP[] = {15.00, 20.62, 26.17, 31.79, 37.35, 42.97, 48.66, 54.14, 59.76, 65.38, 70.93, 76.63, 82.18, 85.00};

    float m1[12] = {};
    float m2[14] = {};

    float y1[14] = {};
    float y2[12] = {};

    float y[168] = {};

    int i, j, n;

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

    void loop()
    {
      for(j = 0; j < 12; j++)
      {
        m1[j] = (LOAD_MAX_TPS[j] - LOAD_MIN_TPS[j]) / (TPS_MAX - TPS_MIN);

        Serial.print("m1 : ");
        Serial.println(m1[j]);

        for(i = 0; i < 14; i++)
        {
          y1[i] = m1[j] * (TPS[i] - TPS_MIN) + LOAD_MIN_TPS[j];

          Serial.print("TPS : ");
          Serial.print(TPS[i]);
          Serial.print("\t");
          Serial.print("LOAD : ");
          Serial.println(y1[i]);
       }
      }

      for(i = 0; i < 14; i++)
      {
        m2[i] = (LOAD_MAX_MAP[i] - LOAD_MIN_MAP[i]) / (MAP_MAX - MAP_MIN);

        Serial.print("m2 : ");
        Serial.println(m2[i]);

        for(j = 0; j < 12; j++)
        {
          y2[j] = m2[i] * (MAP[j] - MAP_MIN) + LOAD_MIN_MAP[i];

          Serial.print("MAP : ");
          Serial.print(MAP[j]);
          Serial.print("\t");
          Serial.print("LOAD : ");
          Serial.println(y2[j]);
        }
       }

      for(i = 0; i < 14; i++)
      {
        for(j = 0; j < 12; j++)
        {
          y[n] = (y1[i] + y2[j]) / 2;
          Serial.print("LOAD TPS : ");
          Serial.print(y1[i]);
          Serial.print("\t");
          Serial.print("LOAD MAP : ");
          Serial.print(y2[j]);
          Serial.print("\t");
          Serial.print("TPS : ");
          Serial.print(TPS[i]);
          Serial.print("\t");
          Serial.print("MAP : ");
          Serial.print(MAP[j]);
          Serial.print("\t");
          Serial.print("Final LOAD : ");
          Serial.println(y[n]);
        }
      }
      delay(1000000);
    }

My serial monitor output :

    LOAD TPS : 15.00 LOAD MAP : 10.00 TPS : 0.00 MAP : 0.85 Final LOAD : 12.50
    LOAD TPS : 15.00 LOAD MAP : 17.14 TPS : 0.00 MAP : 0.95 Final LOAD : 16.07
    LOAD TPS : 15.00 LOAD MAP : 24.29 TPS : 0.00 MAP : 1.05 Final LOAD : 19.64
    LOAD TPS : 15.00 LOAD MAP : 31.43 TPS : 0.00 MAP : 1.15 Final LOAD : 23.21
    LOAD TPS : 15.00 LOAD MAP : 38.57 TPS : 0.00 MAP : 1.25 Final LOAD : 26.79
    LOAD TPS : 15.00 LOAD MAP : 45.71 TPS : 0.00 MAP : 1.35 Final LOAD : 30.36
    LOAD TPS : 15.00 LOAD MAP : 52.86 TPS : 0.00 MAP : 1.45 Final LOAD : 33.93
    LOAD TPS : 15.00 LOAD MAP : 60.00 TPS : 0.00 MAP : 1.55 Final LOAD : 37.50
    LOAD TPS : 15.00 LOAD MAP : 67.14 TPS : 0.00 MAP : 1.65 Final LOAD : 41.07
    LOAD TPS : 15.00 LOAD MAP : 74.29 TPS : 0.00 MAP : 1.75 Final LOAD : 44.64
    LOAD TPS : 15.00 LOAD MAP : 81.43 TPS : 0.00 MAP : 1.85 Final LOAD : 48.21
    LOAD TPS : 15.00 LOAD MAP : 85.00 TPS : 0.00 MAP : 1.90 Final LOAD : 50.00
    LOAD TPS : 20.60 LOAD MAP : 10.00 TPS : 0.40 MAP : 0.85 Final LOAD : 15.30
    LOAD TPS : 20.60 LOAD MAP : 17.14 TPS : 0.40 MAP : 0.95 Final LOAD : 18.87
    LOAD TPS : 20.60 LOAD MAP : 24.29 TPS : 0.40 MAP : 1.05 Final LOAD : 22.44
    LOAD TPS : 20.60 LOAD MAP : 31.43 TPS : 0.40 MAP : 1.15 Final LOAD : 26.01
    LOAD TPS : 20.60 LOAD MAP : 38.57 TPS : 0.40 MAP : 1.25 Final LOAD : 29.59
    LOAD TPS : 20.60 LOAD MAP : 45.71 TPS : 0.40 MAP : 1.35 Final LOAD : 33.16
    LOAD TPS : 20.60 LOAD MAP : 52.86 TPS : 0.40 MAP : 1.45 Final LOAD : 36.73
    LOAD TPS : 20.60 LOAD MAP : 60.00 TPS : 0.40 MAP : 1.55 Final LOAD : 40.30
    LOAD TPS : 20.60 LOAD MAP : 67.14 TPS : 0.40 MAP : 1.65 Final LOAD : 43.87
    LOAD TPS : 20.60 LOAD MAP : 74.29 TPS : 0.40 MAP : 1.75 Final LOAD : 47.44
    LOAD TPS : 20.60 LOAD MAP : 81.43 TPS : 0.40 MAP : 1.85 Final LOAD : 51.01
    LOAD TPS : 20.60 LOAD MAP : 85.00 TPS : 0.40 MAP : 1.90 Final LOAD : 52.80
    LOAD TPS : 26.20 LOAD MAP : 10.00 TPS : 0.80 MAP : 0.85 Final LOAD : 18.10
    LOAD TPS : 26.20 LOAD MAP : 17.14 TPS : 0.80 MAP : 0.95 Final LOAD : 21.67
    LOAD TPS : 26.20 LOAD MAP : 24.29 TPS : 0.80 MAP : 1.05 Final LOAD : 25.24
    LOAD TPS : 26.20 LOAD MAP : 31.43 TPS : 0.80 MAP : 1.15 Final LOAD : 28.81
    LOAD TPS : 26.20 LOAD MAP : 38.57 TPS : 0.80 MAP : 1.25 Final LOAD : 32.39
    LOAD TPS : 26.20 LOAD MAP : 45.71 TPS : 0.80 MAP : 1.35 Final LOAD : 35.96
    LOAD TPS : 26.20 LOAD MAP : 52.86 TPS : 0.80 MAP : 1.45 Final LOAD : 39.53
    LOAD TPS : 26.20 LOAD MAP : 60.00 TPS : 0.80 MAP : 1.55 Final LOAD : 43.10
    LOAD TPS : 26.20 LOAD MAP : 67.14 TPS : 0.80 MAP : 1.65 Final LOAD : 46.67
    LOAD TPS : 26.20 LOAD MAP : 74.29 TPS : 0.80 MAP : 1.75 Final LOAD : 50.24
    LOAD TPS : 26.20 LOAD MAP : 81.43 TPS : 0.80 MAP : 1.85 Final LOAD : 53.81
    LOAD TPS : 26.20 LOAD MAP : 85.00 TPS : 0.80 MAP : 1.90 Final LOAD : 55.60
    LOAD TPS : 31.80 LOAD MAP : 10.00 TPS : 1.20 MAP : 0.85 Final LOAD : 20.90
    LOAD TPS : 31.80 LOAD MAP : 17.14 TPS : 1.20 MAP : 0.95 Final LOAD : 24.47
    LOAD TPS : 31.80 LOAD MAP : 24.29 TPS : 1.20 MAP : 1.05 Final LOAD : 28.04
    LOAD TPS : 31.80 LOAD MAP : 31.43 TPS : 1.20 MAP : 1.15 Final LOAD : 31.61
    LOAD TPS : 31.80 LOAD MAP : 38.57 TPS : 1.20 MAP : 1.25 Final LOAD : 35.19
    LOAD TPS : 31.80 LOAD MAP : 45.71 TPS : 1.20 MAP : 1.35 Final LOAD : 38.76
    LOAD TPS : 31.80 LOAD MAP : 52.86 TPS : 1.20 MAP : 1.45 Final LOAD : 42.33
    LOAD TPS : 31.80 LOAD MAP : 60.00 TPS : 1.20 MAP : 1.55 Final LOAD : 45.90
    LOAD TPS : 31.80 LOAD MAP : 67.14 TPS : 1.20 MAP : 1.65 Final LOAD : 49.47
    LOAD TPS : 31.80 LOAD MAP : 74.29 TPS : 1.20 MAP : 1.75 Final LOAD : 53.04
    LOAD TPS : 31.80 LOAD MAP : 81.43 TPS : 1.20 MAP : 1.85 Final LOAD : 56.61
    LOAD TPS : 31.80 LOAD MAP : 85.00 TPS : 1.20 MAP : 1.90 Final LOAD : 58.40
    LOAD TPS : 37.40 LOAD MAP : 10.00 TPS : 1.60 MAP : 0.85 Final LOAD : 23.70
    LOAD TPS : 37.40 LOAD MAP : 17.14 TPS : 1.60 MAP : 0.95 Final LOAD : 27.27
    LOAD TPS : 37.40 LOAD MAP : 24.29 TPS : 1.60 MAP : 1.05 Final LOAD : 30.84
    LOAD TPS : 37.40 LOAD MAP : 31.43 TPS : 1.60 MAP : 1.15 Final LOAD : 34.41
    LOAD TPS : 37.40 LOAD MAP : 38.57 TPS : 1.60 MAP : 1.25 Final LOAD : 37.99
    LOAD TPS : 37.40 LOAD MAP : 45.71 TPS : 1.60 MAP : 1.35 Final LOAD : 41.56
    LOAD TPS : 37.40 LOAD MAP : 52.86 TPS : 1.60 MAP : 1.45 Final LOAD : 45.13
    LOAD TPS : 37.40 LOAD MAP : 60.00 TPS : 1.60 MAP : 1.55 Final LOAD : 48.70
    LOAD TPS : 37.40 LOAD MAP : 67.14 TPS : 1.60 MAP : 1.65 Final LOAD : 52.27
    LOAD TPS : 37.40 LOAD MAP : 74.29 TPS : 1.60 MAP : 1.75 Final LOAD : 55.84
    LOAD TPS : 37.40 LOAD MAP : 81.43 TPS : 1.60 MAP : 1.85 Final LOAD : 59.41
    LOAD TPS : 37.40 LOAD MAP : 85.00 TPS : 1.60 MAP : 1.90 Final LOAD : 61.20
    LOAD TPS : 43.00 LOAD MAP : 10.00 TPS : 2.00 MAP : 0.85 Final LOAD : 26.50
    LOAD TPS : 43.00 LOAD MAP : 17.14 TPS : 2.00 MAP : 0.95 Final LOAD : 30.07
    LOAD TPS : 43.00 LOAD MAP : 24.29 TPS : 2.00 MAP : 1.05 Final LOAD : 33.64
    LOAD TPS : 43.00 LOAD MAP : 31.43 TPS : 2.00 MAP : 1.15 Final LOAD : 37.21
    LOAD TPS : 43.00 LOAD MAP : 38.57 TPS : 2.00 MAP : 1.25 Final LOAD : 40.79
    LOAD TPS : 43.00 LOAD MAP : 45.71 TPS : 2.00 MAP : 1.35 Final LOAD : 44.36
    LOAD TPS : 43.00 LOAD MAP : 52.86 TPS : 2.00 MAP : 1.45 Final LOAD : 47.93
    LOAD TPS : 43.00 LOAD MAP : 60.00 TPS : 2.00 MAP : 1.55 Final LOAD : 51.50
    LOAD TPS : 43.00 LOAD MAP : 67.14 TPS : 2.00 MAP : 1.65 Final LOAD : 55.07
    LOAD TPS : 43.00 LOAD MAP : 74.29 TPS : 2.00 MAP : 1.75 Final LOAD : 58.64
    LOAD TPS : 43.00 LOAD MAP : 81.43 TPS : 2.00 MAP : 1.85 Final LOAD : 62.21
    LOAD TPS : 43.00 LOAD MAP : 85.00 TPS : 2.00 MAP : 1.90 Final LOAD : 64.00
    LOAD TPS : 48.60 LOAD MAP : 10.00 TPS : 2.40 MAP : 0.85 Final LOAD : 29.30
    LOAD TPS : 48.60 LOAD MAP : 17.14 TPS : 2.40 MAP : 0.95 Final LOAD : 32.87
    LOAD TPS : 48.60 LOAD MAP : 24.29 TPS : 2.40 MAP : 1.05 Final LOAD : 36.44
    LOAD TPS : 48.60 LOAD MAP : 31.43 TPS : 2.40 MAP : 1.15 Final LOAD : 40.01
    LOAD TPS : 48.60 LOAD MAP : 38.57 TPS : 2.40 MAP : 1.25 Final LOAD : 43.59
    LOAD TPS : 48.60 LOAD MAP : 45.71 TPS : 2.40 MAP : 1.35 Final LOAD : 47.16
    LOAD TPS : 48.60 LOAD MAP : 52.86 TPS : 2.40 MAP : 1.45 Final LOAD : 50.73
    LOAD TPS : 48.60 LOAD MAP : 60.00 TPS : 2.40 MAP : 1.55 Final LOAD : 54.30
    LOAD TPS : 48.60 LOAD MAP : 67.14 TPS : 2.40 MAP : 1.65 Final LOAD : 57.87
    LOAD TPS : 48.60 LOAD MAP : 74.29 TPS : 2.40 MAP : 1.75 Final LOAD : 61.44
    LOAD TPS : 48.60 LOAD MAP : 81.43 TPS : 2.40 MAP : 1.85 Final LOAD : 65.01
    LOAD TPS : 48.60 LOAD MAP : 85.00 TPS : 2.40 MAP : 1.90 Final LOAD : 66.80
    LOAD TPS : 54.20 LOAD MAP : 10.00 TPS : 2.80 MAP : 0.85 Final LOAD : 32.10
    LOAD TPS : 54.20 LOAD MAP : 17.14 TPS : 2.80 MAP : 0.95 Final LOAD : 35.67
    LOAD TPS : 54.20 LOAD MAP : 24.29 TPS : 2.80 MAP : 1.05 Final LOAD : 39.24
    LOAD TPS : 54.20 LOAD MAP : 31.43 TPS : 2.80 MAP : 1.15 Final LOAD : 42.81
    LOAD TPS : 54.20 LOAD MAP : 38.57 TPS : 2.80 MAP : 1.25 Final LOAD : 46.39
    LOAD TPS : 54.20 LOAD MAP : 45.71 TPS : 2.80 MAP : 1.35 Final LOAD : 49.96
    LOAD TPS : 54.20 LOAD MAP : 52.86 TPS : 2.80 MAP : 1.45 Final LOAD : 53.53
    LOAD TPS : 54.20 LOAD MAP : 60.00 TPS : 2.80 MAP : 1.55 Final LOAD : 57.10
    LOAD TPS : 54.20 LOAD MAP : 67.14 TPS : 2.80 MAP : 1.65 Final LOAD : 60.67
    LOAD TPS : 54.20 LOAD MAP : 74.29 TPS : 2.80 MAP : 1.75 Final LOAD : 64.24
    LOAD TPS : 54.20 LOAD MAP : 81.43 TPS : 2.80 MAP : 1.85 Final LOAD : 67.81
    LOAD TPS : 54.20 LOAD MAP : 85.00 TPS : 2.80 MAP : 1.90 Final LOAD : 69.60
    LOAD TPS : 59.80 LOAD MAP : 10.00 TPS : 3.20 MAP : 0.85 Final LOAD : 34.90
    LOAD TPS : 59.80 LOAD MAP : 17.14 TPS : 3.20 MAP : 0.95 Final LOAD : 38.47
    LOAD TPS : 59.80 LOAD MAP : 24.29 TPS : 3.20 MAP : 1.05 Final LOAD : 42.04
    LOAD TPS : 59.80 LOAD MAP : 31.43 TPS : 3.20 MAP : 1.15 Final LOAD : 45.61
    LOAD TPS : 59.80 LOAD MAP : 38.57 TPS : 3.20 MAP : 1.25 Final LOAD : 49.19
    LOAD TPS : 59.80 LOAD MAP : 45.71 TPS : 3.20 MAP : 1.35 Final LOAD : 52.76
    LOAD TPS : 59.80 LOAD MAP : 52.86 TPS : 3.20 MAP : 1.45 Final LOAD : 56.33
    LOAD TPS : 59.80 LOAD MAP : 60.00 TPS : 3.20 MAP : 1.55 Final LOAD : 59.90
    LOAD TPS : 59.80 LOAD MAP : 67.14 TPS : 3.20 MAP : 1.65 Final LOAD : 63.47
    LOAD TPS : 59.80 LOAD MAP : 74.29 TPS : 3.20 MAP : 1.75 Final LOAD : 67.04
    LOAD TPS : 59.80 LOAD MAP : 81.43 TPS : 3.20 MAP : 1.85 Final LOAD : 70.61
    LOAD TPS : 59.80 LOAD MAP : 85.00 TPS : 3.20 MAP : 1.90 Final LOAD : 72.40
    LOAD TPS : 65.40 LOAD MAP : 10.00 TPS : 3.60 MAP : 0.85 Final LOAD : 37.70
    LOAD TPS : 65.40 LOAD MAP : 17.14 TPS : 3.60 MAP : 0.95 Final LOAD : 41.27
    LOAD TPS : 65.40 LOAD MAP : 24.29 TPS : 3.60 MAP : 1.05 Final LOAD : 44.84
    LOAD TPS : 65.40 LOAD MAP : 31.43 TPS : 3.60 MAP : 1.15 Final LOAD : 48.41
    LOAD TPS : 65.40 LOAD MAP : 38.57 TPS : 3.60 MAP : 1.25 Final LOAD : 51.99
    LOAD TPS : 65.40 LOAD MAP : 45.71 TPS : 3.60 MAP : 1.35 Final LOAD : 55.56
    LOAD TPS : 65.40 LOAD MAP : 52.86 TPS : 3.60 MAP : 1.45 Final LOAD : 59.13
    LOAD TPS : 65.40 LOAD MAP : 60.00 TPS : 3.60 MAP : 1.55 Final LOAD : 62.70
    LOAD TPS : 65.40 LOAD MAP : 67.14 TPS : 3.60 MAP : 1.65 Final LOAD : 66.27
    LOAD TPS : 65.40 LOAD MAP : 74.29 TPS : 3.60 MAP : 1.75 Final LOAD : 69.84
    LOAD TPS : 65.40 LOAD MAP : 81.43 TPS : 3.60 MAP : 1.85 Final LOAD : 73.41
    LOAD TPS : 65.40 LOAD MAP : 85.00 TPS : 3.60 MAP : 1.90 Final LOAD : 75.20
    LOAD TPS : 71.00 LOAD MAP : 10.00 TPS : 4.00 MAP : 0.85 Final LOAD : 40.50
    LOAD TPS : 71.00 LOAD MAP : 17.14 TPS : 4.00 MAP : 0.95 Final LOAD : 44.07
    LOAD TPS : 71.00 LOAD MAP : 24.29 TPS : 4.00 MAP : 1.05 Final LOAD : 47.64
    LOAD TPS : 71.00 LOAD MAP : 31.43 TPS : 4.00 MAP : 1.15 Final LOAD : 51.21
    LOAD TPS : 71.00 LOAD MAP : 38.57 TPS : 4.00 MAP : 1.25 Final LOAD : 54.79
    LOAD TPS : 71.00 LOAD MAP : 45.71 TPS : 4.00 MAP : 1.35 Final LOAD : 58.36
    LOAD TPS : 71.00 LOAD MAP : 52.86 TPS : 4.00 MAP : 1.45 Final LOAD : 61.93
    LOAD TPS : 71.00 LOAD MAP : 60.00 TPS : 4.00 MAP : 1.55 Final LOAD : 65.50
    LOAD TPS : 71.00 LOAD MAP : 67.14 TPS : 4.00 MAP : 1.65 Final LOAD : 69.07
    LOAD TPS : 71.00 LOAD MAP : 74.29 TPS : 4.00 MAP : 1.75 Final LOAD : 72.64
    LOAD TPS : 71.00 LOAD MAP : 81.43 TPS : 4.00 MAP : 1.85 Final LOAD : 76.21
    LOAD TPS : 71.00 LOAD MAP : 85.00 TPS : 4.00 MAP : 1.90 Final LOAD : 78.00
    LOAD TPS : 76.60 LOAD MAP : 10.00 TPS : 4.40 MAP : 0.85 Final LOAD : 43.30
    LOAD TPS : 76.60 LOAD MAP : 17.14 TPS : 4.40 MAP : 0.95 Final LOAD : 46.87
    LOAD TPS : 76.60 LOAD MAP : 24.29 TPS : 4.40 MAP : 1.05 Final LOAD : 50.44
    LOAD TPS : 76.60 LOAD MAP : 31.43 TPS : 4.40 MAP : 1.15 Final LOAD : 54.01
    LOAD TPS : 76.60 LOAD MAP : 38.57 TPS : 4.40 MAP : 1.25 Final LOAD : 57.59
    LOAD TPS : 76.60 LOAD MAP : 45.71 TPS : 4.40 MAP : 1.35 Final LOAD : 61.16
    LOAD TPS : 76.60 LOAD MAP : 52.86 TPS : 4.40 MAP : 1.45 Final LOAD : 64.73
    LOAD TPS : 76.60 LOAD MAP : 60.00 TPS : 4.40 MAP : 1.55 Final LOAD : 68.30
    LOAD TPS : 76.60 LOAD MAP : 67.14 TPS : 4.40 MAP : 1.65 Final LOAD : 71.87
    LOAD TPS : 76.60 LOAD MAP : 74.29 TPS : 4.40 MAP : 1.75 Final LOAD : 75.44
    LOAD TPS : 76.60 LOAD MAP : 81.43 TPS : 4.40 MAP : 1.85 Final LOAD : 79.01
    LOAD TPS : 76.60 LOAD MAP : 85.00 TPS : 4.40 MAP : 1.90 Final LOAD : 80.80
    LOAD TPS : 82.20 LOAD MAP : 10.00 TPS : 4.80 MAP : 0.85 Final LOAD : 46.10
    LOAD TPS : 82.20 LOAD MAP : 17.14 TPS : 4.80 MAP : 0.95 Final LOAD : 49.67
    LOAD TPS : 82.20 LOAD MAP : 24.29 TPS : 4.80 MAP : 1.05 Final LOAD : 53.24
    LOAD TPS : 82.20 LOAD MAP : 31.43 TPS : 4.80 MAP : 1.15 Final LOAD : 56.81
    LOAD TPS : 82.20 LOAD MAP : 38.57 TPS : 4.80 MAP : 1.25 Final LOAD : 60.39
    LOAD TPS : 82.20 LOAD MAP : 45.71 TPS : 4.80 MAP : 1.35 Final LOAD : 63.96
    LOAD TPS : 82.20 LOAD MAP : 52.86 TPS : 4.80 MAP : 1.45 Final LOAD : 67.53
    LOAD TPS : 82.20 LOAD MAP : 60.00 TPS : 4.80 MAP : 1.55 Final LOAD : 71.10
    LOAD TPS : 82.20 LOAD MAP : 67.14 TPS : 4.80 MAP : 1.65 Final LOAD : 74.67
    LOAD TPS : 82.20 LOAD MAP : 74.29 TPS : 4.80 MAP : 1.75 Final LOAD : 78.24
    LOAD TPS : 82.20 LOAD MAP : 81.43 TPS : 4.80 MAP : 1.85 Final LOAD : 81.81
    LOAD TPS : 82.20 LOAD MAP : 85.00 TPS : 4.80 MAP : 1.90 Final LOAD : 83.60
    LOAD TPS : 85.00 LOAD MAP : 10.00 TPS : 5.00 MAP : 0.85 Final LOAD : 47.50
    LOAD TPS : 85.00 LOAD MAP : 17.14 TPS : 5.00 MAP : 0.95 Final LOAD : 51.07
    LOAD TPS : 85.00 LOAD MAP : 24.29 TPS : 5.00 MAP : 1.05 Final LOAD : 54.64
    LOAD TPS : 85.00 LOAD MAP : 31.43 TPS : 5.00 MAP : 1.15 Final LOAD : 58.21
    LOAD TPS : 85.00 LOAD MAP : 38.57 TPS : 5.00 MAP : 1.25 Final LOAD : 61.79
    LOAD TPS : 85.00 LOAD MAP : 45.71 TPS : 5.00 MAP : 1.35 Final LOAD : 65.36
    LOAD TPS : 85.00 LOAD MAP : 52.86 TPS : 5.00 MAP : 1.45 Final LOAD : 68.93
    LOAD TPS : 85.00 LOAD MAP : 60.00 TPS : 5.00 MAP : 1.55 Final LOAD : 72.50
    LOAD TPS : 85.00 LOAD MAP : 67.14 TPS : 5.00 MAP : 1.65 Final LOAD : 76.07
    LOAD TPS : 85.00 LOAD MAP : 74.29 TPS : 5.00 MAP : 1.75 Final LOAD : 79.64
    LOAD TPS : 85.00 LOAD MAP : 81.43 TPS : 5.00 MAP : 1.85 Final LOAD : 83.21
    LOAD TPS : 85.00 LOAD MAP : 85.00 TPS : 5.00 MAP : 1.90 Final LOAD : 85.00

NOTE : Here, I'm not providing all serial monitor output. Just needed part of OUTPUT here displayed.

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

body:
Here, this is modified code which provide result which I want.

    float TPS_MIN = 0.00;
    float TPS_MAX = 5.00;

    float MAP_MIN = 0.85;
    float MAP_MAX = 1.90;

    int LOAD_MIN = 2;
    int LOAD_MAX = 100;

    int RPM_MIN = 400;
    int RPM_MAX = 6000;

    float LOAD_MIN_TPS_MIN = 2.00;
    float LOAD_MAX_TPS_MIN = 10.00;

    float LOAD_MIN_TPS_MAX = 15.00;
    float LOAD_MAX_TPS_MAX = 85.00;

    float LOAD_MIN_MAP_MIN = 2.00;
    float LOAD_MAX_MAP_MIN = 15.00;

    float LOAD_MIN_MAP_MAX = 10.00;
    float LOAD_MAX_MAP_MAX = 85.00;

    float injTime_MIN_LOAD_MIN = 4.00;
    float injTime_MAX_LOAD_MIN = 4.60;

    float injTime_MIN_LOAD_MAX = 8.06;
    float injTime_MAX_LOAD_MAX = 14.86;

    float injTime_MIN_RPM_MIN = 4.00;
    float injTime_MAX_RPM_MIN = 8.06;

    float injTime_MIN_RPM_MAX = 4.60;
    float injTime_MAX_RPM_MAX = 14.86;

    float mTPSmin;
    float mTPSmax;
    float mMAPmin;
    float mMAPmax;

    float yTPSmin;
    float yTPSmax;
    float yMAPmin;
    float yMAPmax;

    float mTPS;
    float mMAP;

    float yTPS;
    float yMAP;

    float LOAD;

    float TPS, MAP;

    float mLOADmin;
    float mLOADmax;
    float mRPMmin;
    float mRPMmax;

    float yLOADmin;
    float yLOADmax;
    float yRPMmin;
    float yRPMmax;

    float mLOAD;
    float mRPM;

    float yLOAD;
    float yRPM;

    float yInjTime;

    int RPM;

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

    void loop()
    {
        TPS = analogRead(A0) * (5.0 / 1023.0);
        MAP = analogRead(A1) * (1.90 / 1023.0);
        RPM = analogRead(A2) * (6000 / 1023.0);

        mTPSmin = (LOAD_MAX_TPS_MIN - LOAD_MIN_TPS_MIN) / (TPS_MAX - TPS_MIN);

        Serial.print("mTPSmin : ");
        Serial.println(mTPSmin);

        yTPSmin = mTPSmin * (TPS - TPS_MIN) + LOAD_MIN_TPS_MIN;

        Serial.print("TPS : ");
        Serial.print(TPS);
        Serial.print("\t");
        Serial.print("LOAD : ");
        Serial.println(yTPSmin);

        mTPSmax = (LOAD_MAX_TPS_MAX - LOAD_MIN_TPS_MAX) / (TPS_MAX - TPS_MIN);

        Serial.print("mTPSmax : ");
        Serial.println(mTPSmax);

        yTPSmax = mTPSmax * (TPS - TPS_MIN) + LOAD_MIN_TPS_MAX;

        Serial.print("TPS : ");
        Serial.print(TPS);
        Serial.print("\t");
        Serial.print("LOAD : ");
        Serial.println(yTPSmax);

        mMAPmin = (LOAD_MAX_MAP_MIN - LOAD_MIN_MAP_MIN) / (MAP_MAX - MAP_MIN);

        Serial.print("mMAPmin : ");
        Serial.println(mMAPmin);

        yMAPmin = mMAPmin * (MAP - MAP_MIN) + LOAD_MIN_MAP_MIN;

        Serial.print("MAP : ");
        Serial.print(MAP);
        Serial.print("\t");
        Serial.print("LOAD : ");
        Serial.println(yMAPmin);

        mMAPmax = (LOAD_MAX_MAP_MAX - LOAD_MIN_MAP_MAX) / (MAP_MAX - MAP_MIN);

        Serial.print("mMAPmax : ");
        Serial.println(mMAPmax);

        yMAPmax = mMAPmax * (MAP - MAP_MIN) + LOAD_MIN_MAP_MAX;

        Serial.print("MAP : ");
        Serial.print(MAP);
        Serial.print("\t");
        Serial.print("LOAD : ");
        Serial.println(yMAPmax);

        mTPS = (yMAPmax - yMAPmin) / (TPS_MAX - TPS_MIN);

        Serial.print("mTPS : ");
        Serial.println(mTPS);

        yTPS = mTPS * (TPS - TPS_MIN) + yMAPmin;

        Serial.print("TPS : ");
        Serial.print(TPS);
        Serial.print("\t");
        Serial.print("LOAD : ");
        Serial.println(yTPS);

        mMAP = (yTPSmax - yTPSmin) / (MAP_MAX - MAP_MIN);

        Serial.print("mMAP : ");
        Serial.println(mMAP);

        yMAP = mMAP * (MAP - MAP_MIN) + yTPSmin;

        Serial.print("MAP : ");
        Serial.print(MAP);
        Serial.print("\t");
        Serial.print("LOAD : ");
        Serial.println(yMAP);

        LOAD = (yTPS + yMAP) / 2;
        Serial.print("Final LOAD : ");
        Serial.println(LOAD);

        mLOADmin = (injTime_MAX_LOAD_MIN - injTime_MIN_LOAD_MIN) / (LOAD_MAX - LOAD_MIN);

        Serial.print("mLOADmin : ");
        Serial.println(mLOADmin);

        yLOADmin = mLOADmin * (LOAD - LOAD_MIN) + injTime_MIN_LOAD_MIN;

        Serial.print("LOAD : ");
        Serial.print(LOAD);
        Serial.print("\t");
        Serial.print("injTime : ");
        Serial.println(yLOADmin);

        mLOADmax = (injTime_MAX_LOAD_MAX - injTime_MIN_LOAD_MAX) / (LOAD_MAX - LOAD_MIN);

        Serial.print("mLOADmax : ");
        Serial.println(mLOADmax);

        yLOADmax = mLOADmax * (LOAD - LOAD_MIN) + injTime_MIN_LOAD_MAX;

        Serial.print("LOAD : ");
        Serial.print(LOAD);
        Serial.print("\t");
        Serial.print("injTime : ");
        Serial.println(yLOADmax);

        mRPMmin = (injTime_MAX_RPM_MIN - injTime_MIN_RPM_MIN) / (RPM_MAX - RPM_MIN);

        Serial.print("mRPMmin : ");
        Serial.println(mRPMmin);

        yRPMmin = mRPMmin * (RPM - RPM_MIN) + injTime_MIN_RPM_MIN;

        Serial.print("RPM : ");
        Serial.print(RPM);
        Serial.print("\t");
        Serial.print("injTime : ");
        Serial.println(yRPMmin);

        mRPMmax = (injTime_MAX_RPM_MAX - injTime_MIN_RPM_MAX) / (RPM_MAX - RPM_MIN);

        Serial.print("mRPMmax : ");
        Serial.println(mRPMmax);

        yRPMmax = mRPMmax * (RPM - RPM_MIN) + injTime_MIN_RPM_MAX;

        Serial.print("RPM : ");
        Serial.print(RPM);
        Serial.print("\t");
        Serial.print("injTime : ");
        Serial.println(yRPMmax);

        mLOAD = (yRPMmax - yRPMmin) / (LOAD_MAX - LOAD_MIN);

        Serial.print("mLOAD : ");
        Serial.println(mLOAD);

        yLOAD = mLOAD * (LOAD - LOAD_MIN) + yRPMmin;

        Serial.print("LOAD : ");
        Serial.print(LOAD);
        Serial.print("\t");
        Serial.print("injTime : ");
        Serial.println(yLOAD);

        mRPM = (yLOADmax - yLOADmin) / (RPM_MAX - RPM_MIN);

        Serial.print("mRPM : ");
        Serial.println(mRPM);

        yRPM = mRPM * (RPM - RPM_MIN) + yLOADmin;

        Serial.print("RPM : ");
        Serial.print(RPM);
        Serial.print("\t");
        Serial.print("injTime : ");
        Serial.println(yRPM);

        yInjTime = (yLOAD + yRPM) / 2;
        Serial.print("Final injTime : ");
        Serial.println(yInjTime);

        delay(1000000);
    }


message:
Measure the duration a pin is in a HIGH state

I'm struggling with getting the button configuration. Simply, I have a LED controlling setup for a button to increase its brightness when pressed. However, I would like to have it setup like this:

1. When button is pressed.
2. change the value by 1,
3. wait for 500ms,
4. Then go fast (with the usual void loop time).

Is it something to do with interrupts? If I just write it like below, it actually (obviously) goes by +1 by itself, even when button is not pressed.

    void loop() {
      if(digitalRead(button_pressed) == HIGH) {
        current_state = current_state+1;
        delay(500);
        current_state = current_state+1;
      }
    }

body:
Non-blocking version.

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

    bool old_button_state = LOW;
    void loop()
    {
        if(digitalRead(button_pressed) == HIGH)
        {
            current_state = current_state+1

            if( old_button_state==LOW )
                delay(500); // long delay
            else
                delay(100); // short delay

            old_button_state = HIGH;
        }
        else
        {
            old_button_state = LOW;
        }
    }

<strike>
Simplistic version.

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

    void loop()
    {
        if(digitalRead(button_pressed) == HIGH)
        {
            current_state = current_state+1
            delay(500);// long delay

            // repeat while the button is being pressed
            while(digitalRead(button_pressed) == HIGH)
            {
                current_state = current_state+1
                delay(100); //short delay
            }
        }
    }

</strike>

Ideally you wouldn't just wait for 500ms, but 'break out' of this delay as soon as the button is released.


body:
> Fairly simple.

I thought I would lay out my code here so it is more clear.

 if (BTN_PRESSED()) {   //button is pressed now
  btn_cnt += 1;    //increment button counter
  if (btn_cnt >= BTN_LONGPRESS) {
   volume += VOLINC_FAST; //btn has been pressed for a long time, so increment volume fast
  } else {
   volume += VOLINC_SLOW;        //otherwise increment the button slowly
  }
 } else btn_cnt = 0;    //button is not pressed so reset the counter

It basically follows what I laid out earlier and is self explanatory, I hope.

Formatting needs more work, obviously.

edit: reformatted the code a little bit to make it more readable.

here is an example of this code at work:

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

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

here, the code is used to detect a button press (active low) on RA0. Once the button counter (btn_cnt) has been pressed sufficiently long (set by BTN_LONGPRESS), it increments volume by VOLINC_FAST (=4); otherwise, it increments volume by VOLINC_SLOW (=1).

the simulation shows just that. the value of volume is output on PB0..7, to a dac to show more graphically what happens to volume's value.

1) when the button is high (=not pressed), volume is not changed and you see a flat line on the DAC output;
2) when the button is just pressed (but not sufficient to trigger BTN_LONGPRESS), volume is incremented slowly and you see the DAC's output goes up slowly (1 at a time);
3) when the button is pressed long enough, volulme is incremented fast and you see the DAC's output goes up much steeper.

Obviously, you can modulize the code so it can process multiple buttons and return multiple states - not pressed, pressed, long pressed, double pressed. or if you wish, allow it to process bounces.

all sorts of possibilities but the basic idea is the same.


body:
    long timenow, timelong=500;
    int current_state = 0;
    void increase_state()
    {
     current_state++;
     Serial.println(current_state);
    }

    void loop()
     {
        if(digitalRead(button_pressed)) //button is pressed
        {
      timenow=millis(); //get current time
      increase_state(); // increase by 1
      while (digitalRead(button_pressed)) //check if the button is still pressed
       {
        //rapidly increase "current_state" by 1 if button is pressed more than 500ms with interval of 50ms.
        if ((millis()-timenow)>timelong)
        {
        increase_state();
        delay(50);
        }
       }
        }
     delay(500)
     }

The increment of `current_state` is always by 1. If button is pressed, it will always increase by 1, but if it's not a long press, you have to wait another 500ms to increase it values again.


message:
Arduino Mega read data from USB

I´m completely new to the arduino and not used to work with it. Due to an project I need to know the best way to transfer Data to my Arduino Mega. The transferred file will be an sliced 3D object. Is it possible to use the built in USB port to read from a stick? Or do I have to use a PC to transfer my data?
Please help me to answer this question since I have no clue how to manage to get the sliced file to my Arduino.

body:
The Arduino Mega doesn't support USB-host, so you can't connect a USB stick directly.

The easiest way is to connect it to a computer, and send the data over the serial connection.


message:
Arduino rc plane logger

Well, I want to make an rc plane with an arduino that logs to an sd card

A) Video

B) Accelerometer data

C) Tempature

D) Humitity

E) Atmospheric pressure

F) Gyroscope Data

What arduino/parts should I use? I have a maximum of 170 grams or 6 OZ.
The arduino will not control the plane, just log data. I'm thinking an arduino 101... but I would like to know if there is a lighter/better way.
 THANKS! :)

body:
I've completed a similar project.

 - For the Arduino, I used a Pro Mini for its small size and weight.
 - For the accel/gyro, I used an MPU-6050. 2 bird, 1 stone!
 - For the Temp/Baro, I used an MPL3115A2. Again, 2 bird, 1 stone!
 - [For the camera feed, use one of these pre-built things.][1]

  [1]: http://www.ebay.com/itm/200W-HD-Camera-Shoot-Module-For-Hubsan-X4-H107C-A34-Mini-Aircraft-Quadcopter-/141434404852?hash=item20ee25bff4:g:q5IAAOSwajVUN5Ir


body: It is not an Arduino answer but a Raspberry Pi with a Sense hat will record most of what you need with little coding.  Add a Pi camera and you have all this for about $100.  The Sense Hat temperature sensor doesn't work because it is too close to the CPU but you could get a digital thermometer for a few bucks.


message:
Pulldown resistors and multiple switches

Maybe this is a question for Electronics SE but I’m not a member there yet so hopefully someone will have an answer here.

I did an experiment with having some push-to-make buttons connected to my Uno. I copied the circuit from the aduino.cc website and all worked exactly as expected. Here is my schematic of the circuit as I have it now:
[![Circuit][1]][1]
The pins are both held LOW by the Pulldown resistor until the switch is closed, when they go HIGH.
All well and good. But I’ve just been looking at the circuit and something puzzles me. I can see a direct connection from Switch 1 to Pin 2 VIA the resistors and the Ground connection – and vice versa, S2 to P1. See my pathway in Red here:

[![Alt Path][2]][2]
Now, to be clear, this is NOT happening – but I just want to understand why not. Is it just that the 2 resistors in combination provide enough resistance to stop the opposite pin from going HIGH? In which case, this Pulldown resistor is actually serving 2 completely different functions in the circuit…?

  [1]: https://i.stack.imgur.com/0q8Qp.png
  [2]: https://i.stack.imgur.com/GAHyx.jpg

body: A simple rule of thumb is that electricity always follows the path of least resistance. The energy going over the switch has a lower resistance path to ground through the Arduino than it does through the pull-down resistor, so it will prefer to go that way than through one - or both resistors when it is available.


body:
Call the resistors R1 and R2, the negative terminal Ground, and the positive terminal V+.  The junction of R1 and R2 is connected to Ground.  This holds the resistor ends at the junction to zero volts relative to ground.  Ignoring P2 for the moment, the other end of R2 is open circuit to V+ when S2 is open.  Applying Ohm's law, we have a finite resistance in series with an infinite resistance, so zero volts across R2 when S2 is open.  Thus one sees that voltage across R2 is not affected by voltage changes across R1.

P2 as an input is not completely an open circuit; typically its effect is similar to a multi-gigaohms resistor to some voltage between Ground and V+.

*Edit:*
More directly, observe that the voltage at the Ground ends of R1 and R2 is zero and remains at zero no matter what S1 and S2 do.  Thus, operation of S1 does not affect voltage at P2, and operation of S2 does not affect voltage at P1.


body:
It helped me to draw an equivalent schematic to yours when S1 is closed and S2 is open. P2 is neither high nor low by itself; it is a high-impedance (which is why you need a pulldown or pullup resistor). It is pulled to ground by R2 and the fact that the junction of the two resistors is grounded. If you disconnected that junction from ground, P2 would see a 20K pullup, but as it is, the (left) end of R2 stays at ground, regardless of what you apply to the P1-R1 junction.

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/BWuqg.png)

<!-- End schematic -->


body:
An input pin is in what is known as *high impedance* mode. That is, to all intents and purposes, to the external circuit it looks like a massive resistor to ground.

This resistance can be in the millions of ohms.

So let's redraw your circuit with those input pins as big resistors:

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/65fu6.png)

<!-- End schematic -->

Now you can see how the schematic really looks (see how it's set up so +5V is at the top and GND is at the bottom - the [conventional] current flows then from top to bottom).

So with SW2 pushed (as shown) the current wants to flow from 5V (top) to GND (bottom). That goes through SW2, through R2, and down to ground. Some tiny amount also flows through R4, which represents the input pin.  Since by then the current is already at ground and has reached its destination there is no reason at all for it to then flow back up through R1, and back down to ground again through R3. For current to flow through R1 the voltage at IN1 would have to be negative since current will only flow from a higher to a lower voltage. And since it isn't negative, no current can flow.


message:
How do I configure the Arduino IDE to look for source code in a subdirectory within the directory that holds my sketch?

I'm writing an Arduino program that contains various .h and .cpp files. Due to organizational needs, I have configured the directory that contains my Arduino sketch (.ino) to possess a subdirectory. This subdirectory contains related source code.

An example layout of my project directory is located below:

    mysketch
        mysketch.ino
        mycode.h
        mycode.cpp
        mylibs
            mylib1.h
            mylib1.cpp
            mylib2.h
            mylib2.cpp
            mylib3.h
            mylib3.cpp

With this, I'm able to successfully #include the header files. However, the compiler then complains that mylib1.cpp, mylib2.cpp, and mylib3.cpp are not defined (however they are). I'm guessing that the Arduino only looks for source files within the same directory that the sketch lives in. Thus subdirectories contains source code are ignored.

I can then modify my directory layout such that all of the 'mylib.h/.cpp's' are in the same directory and the project compiles fine.

So my question: how do I configure the Arduino IDE to reference source code within a subdirectory? Also, I would prefer that the mylibs exist within the same directory, and not within the Arduino 'library' directory. This will allow me to then easily distribute the code as a single zipped folder.

body:
In the Arduino IDE the answer is simple: you can't.

The Arduino IDE doesn't compile within the directory your sketch is in. Instead it writes out a fresh copy of all the files directly from the tabs in the IDE into a temporary build folder (munging them as it goes if they are .INO or .PDE) and then compiles them there. Anything else within your sketch folder is completely ignored.

If you want that kind of functionality you will have to use a different IDE.

For example, [UECIDE](http://uecide.org) lets you have a structure like:

    MySketch/
        MySketch.ino
        libraries/
            MyLib1/
                MyLib1.h
                MyLib1.cpp
            MyLib2/
                MyLib2.h
                MyLib2.cpp


body:
The behavior of the Arduino IDE with this sort of thing has changed over time so it depends on which version of the Arduino IDE you're using. With recent versions you can put the files in a `src` subfolder of your sketch folder and then do:

    #include "src/mylib1.h"
or:

    #include "src/mylib1/mylib1.h"
depending on how you want to organize the folder structure.

When doing this you may find that Arduino libraries often use incorrect include syntax in their source code. For example in mylib1.cpp:
<!-- language: lang-cpp -->

    #include <mylib1.h>
although wrong, would still work if the library was located in one of the Arduino libraries folders but with the library located in the sketch folder this no longer works and you need to change it to:

    #include "mylib1.h"


message:
DS18b20 Order of sensors on a cable

I have a string of 10x DS18b20 sensors on a single two wire line (parasitic power). Below is a table of the sensors, Where they are located on the wire, and in what order where they discovered.

    Serial             Order on wire*   Order discovered
    286305560100002c 1              7
    28a158610100006a 2              3
    28ad48610100006b 3              6
    2851ae60010000ad 4              4
    289b426101000089 5              8
    28cd1161010000ce 6              5
    2864026101000030  7              1
    280c766101000026 8              2

I read this document on how the OneWire discovers sensors on the bus. https://www.maximintegrated.com/en/app-notes/index.mvp/id/187

My question: Is there a way to detect the order of the sensors on a wire?

body:
I found this application note.

APPLICATION NOTE 4037
Regain Location Information by Leveraging the 1-Wire® Chain Function—A Simple Signaling and Protocol Method Determines Device Physical Location

https://www.maximintegrated.com/en/app-notes/index.mvp/id/4037


body:
There is no way to detect position on the bus because all devices are connected in parallel. This is why a serial or "chain" wire, added to the newer devices, is required.

(To complicate matters, what is the "order of devices" - or even the meaning of "order" in a center-fed bus, or a circular, star, or other branched network? Order is just something we perceive when looking at an end-fed linear network. Electrons don't care. Think of a capacitor (unfortunately, the bus behaves like one but that's another story) with two plates, several centimeters square, and a dozen 1-wire devices connected from plate to plate. Now what is their order? Ow, my brain hurts! Let's go back to linear buses.)

The discovery order is a function of the set of binary device IDs on the bus. There are two ways I know of to come to know the physical ordering, both empirical (i.e., by observation):

1. Connect the set of devices one at a time, to a temporary bus such as a breadboard. With an Arduino, read the their IDs and tag them (human readable). With knowledge of the discovery alogrithm, or by running actual discovery on an Arduino with all devices connected, write down the IDs in the order they are discovered which is invariant for a given set of device IDs. Assemble your wired bus with the devices in this order.

2. (The reverse of 1 and quicker to build, and is what you've already shown in your question: Wire the bus. With a simple Arduino program, repeatedly sample all devices on the bus and report print their indices and temperatures (the indices will be in discovery order). One at a time, warm each device with your hand and notice which device index is affected. Write down the physical position (first, second, ...) and the index. This is the mapping table between position and index. Include it in your control algorithm.


body: what you can apparently do is use the User Data space set aside for the alarm and add an ID in there. I have not done this yet but am looking at this option as my sensor array has over 40 sensors in a line and ideally I would like the top one to be 0 and the last one in the chain to be 40.