message:
Using SD library in a ESP-IDF project on ESP32

I just started to move from the **Arduino** firmware to the **esp-idf** firmware.
I read [that link][1]. I learn that I have to include libraries creating a component files, with a `component.mk` file, `*.c`, `*.cpp` files and an `include/` folder for `*.h` files.
That was ok for most of libraries I had to include, except for the SD card library, more precisely the `Sd2PinMap.h` header.

It seems that **ESP32** is not recognized:

<!-- language: lang-none -->

    $(IDF-PATH)/Project/components/SD/include/Sd2PinMap.h:510:2: error:
    #error Architecture or board not supported.

but with the **Arduino** firmware, there were no problems.

I checked `make menuconfig` options, but I didn't find a way to make it work for an ESP32 board... Any ideas ?

  [1]: https://esp-idf.readthedocs.io/en/latest/api-guides/build-system.html

body:
Okay, the solution was simple, I just had to pull the [update][1] for the SD Card library, mine was outdated. Thank you all.

  [1]: https://github.com/espressif/arduino-esp32/tree/master/libraries/SD


sender: user

message:
Commucinate two arduino with each other

I have 2 arduino Unos where each one works properly on its own.

I try to make them communicate with each other using serial communication (TX-RX ports).

When I try to upload my code to them I get this error :

    avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00
    avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x00
    avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x00
    avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x00
    avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x00
    avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x00
    avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x00
    avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x00
    avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x00
    avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x00
    An error occurred while uploading the sketch

what should i do to fix it ? (MY os is windows 10) thanks

sender: assistant

body:
Pins 0 and 1 on the Arduino Uno are used for serial communication with the computer over USB, including uploading sketches. If you connect anything to those pins you can interfere with the upload process.

To communicate between the two boards using serial communication without using pins 0 and 1 you can do software serial on other pins:
https://www.arduino.cc/en/Reference/SoftwareSerial


message:
Arduino: Reading DS18B20 interferes with servo

I have an Arduino with a servo, INA219 (current and voltage sensor) and 2 DS18B20 connected to it.

DS18B20 are connected in full-power mode with 5k resistor connected between DATA line and +5V.

I use DallasTemperature library: https://github.com/milesburton/Arduino-Temperature-Control-Library

I get the temperature readings, but the problem is that my servo is jittering slightly almost every time temperature reading is done.
If I disconnect DATA line from pin 2 (where it's normally connected) then servo is not moving anymore and everything is fine.

Any ideas what might be causing it? I would expect servo interfering with OneWire readings, not the other way around :)

Here is the full code:
https://pastebin.com/xcES4PVT

Here is the minimal example with which I can reproduce the problem:

        #include <DallasTemperature.h>
    #include <Servo.h>

    #define ONE_WIRE_BUS 2
    OneWire oneWire(ONE_WIRE_BUS);

    // Pass our oneWire reference to Dallas Temperature.
    DallasTemperature sensors(&oneWire);

    Servo myservo;

    long previousMillis = 0;

    long tempRequestedMillis = 0;

    bool tempRequested = false;

    void setup(void)
    {
      // start serial port
      Serial.begin(115200);
      Serial.println("Dallas Temperature IC Control Library Demo");

      myservo.attach(9);

      // Start up the library
      sensors.begin();
      sensors.setWaitForConversion(false);
    }

    void loop(void)
    {

      unsigned long currentMillis = millis();
      if (!tempRequested && currentMillis - previousMillis > 2000) {
        previousMillis = currentMillis;

        sensors.requestTemperatures(); // Send the command to get temperatures

        tempRequestedMillis = currentMillis;
        tempRequested = true;
      } else if (tempRequested && currentMillis - tempRequestedMillis > 2000) {
        Serial.println(sensors.getTempCByIndex(0));
        tempRequested = false;
      }
    }

body:
Reading a DS18B20 the naive way takes up to 1500ms because you have to trigger a temperature conversion, then wait for it to complete.

If you have them full-powered, you better trigger the conversion, continue with your program and read the result 2 seconds later, when it's done. You can also trigger the conversion on all connected DS18B20 simultaneously by using the Skip ROM command before sending the Convert T command.

Please see the documentation of Maxim/Dallas' library how to do that.


body:
Arduino's Servo library on AVR uses interrupts; if interrupts are disabled for any amount of time, the servos will twitch.

1-Wire protocol (used by DS18B20) needs to disable interrupts for the protocol to work. Therefore, servos glitch.

There is a great explanation of the problem here: https://learn.adafruit.com/neopixels-and-servos/overview , just mentally replace "Neopixel library" with "OneWire library". Their TiCo_Servo library sounds just like what you want.


message:
SSD1306 / U8glib display fonts and commands

I cannot seem to find any reference for the SSD 1306 or U8glib display font library or any command reference, like all the options for display() etc. For my fonts I been going into the utility folder and scrolling through notepad for the U8glib library but its very croweded with numbers and code. is there any reference for both libraries online that is user friendly?

body:
First, [u8glib][1] is superceded by [u8g2][2]

Second, the [u8glib wiki][3] has a command reference and font reference.

As does the [u8g2 wiki][2].

Neither reference lists a `display()` command.

  [1]: https://github.com/olikraus/u8glib
  [2]: https://github.com/olikraus/u8g2/wiki
  [3]: https://github.com/olikraus/u8glib/wiki


message:
using special symbols from the U8glib library

I enter font symbols into the u8g.setFont() and I get a string of sympols. How do I grab just one of those symbols, for example an arrow?

body:
`setFont` just tell how display the next `drawStr` (or similar text output function).

To draw an arbitrary UTF8 char, just use

**drawUTF8**

C++/Arduino Prototype:

    u8g2_uint_t U8g2::drawUTF8(u8g2_uint_t x, u8g2_uint_t y, const char *s)
**C Prototype:**

    u8g2_uint_t u8g2_DrawUTF8(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *s);

**Description:**

Draw a string which is encoded as UTF-8. There are two preconditions for the use of this function:

 - The C/C++/Arduino compiler must support UTF-8 encoding (this is
   default for the gnu compiler, which is also used for most Arduino
   boards), and
 - The code editor/IDE must support and store the C/C++/Arduino code as UTF-8 (true for the Arduino IDE).

If these conditions are met, you can use the character with code value greater than 127 directly in the string (of course the character must exist in the font file, see also **setFont**).

Advantage: No escape codes are required and the source code is more readable. The glyph can be copied and paste into the editor from a "char set" tool.

Disadvantage: The code is less portable and the strlen function will not return the number of visible characters. Use getUTF8Len instead of strlen.

Arguments:
        u8g2: A pointer to the u8g2 structure.
        x, y: Position of the first character on the display.
        s: UTF-8 encoded text.

Returns: Width of the string.

Note 1: This drawing function depends on the current font mode and drawing color.
Note 2: Use the print function to print the value of a numeric variable.

See also: **setFont** drawStr print

Example:

    u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawUTF8(5, 20, "Snowman: ☃");
[![Snowman][1]][1]

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


message:
Reading setting from microSD

I modified the SD sketch for `ESP8266` to read `WIFI` setting from a file named `CONFIG.TXT`. The text file's content format is `SETTING=VALUE`. Ex.

    SSID=AP001
    KEY=AP001
I manage to separate the `SETTING` and `VALUE`
My code:

    #include <SPI.h>
    #include <SD.h>

    File myFile;

    void readWifiConfig() {
      Serial.println("Initializing SD card...");
      char temp;
      bool isSetting = true;
      if (!SD.begin(4)) {
        Serial.println("Initialization failed!");
        return;
      }
      Serial.println("Initialization done.");
      myFile = SD.open("CONFIG.TXT");
      if (myFile) {
        Serial.println("CONFIG.TXT");
        while (myFile.available()) {
          temp = myFile.read();
          if (isSetting == true) {
            if (temp == '=') {
              Serial.print("="); //Writes '=' to console
              isSetting  = false;
            }
            else {
              Serial.print(temp); //Writes SETTING part to console
            }
          }
          else {
            if (temp == '\n' || temp == '\r') {
              isSetting = true;
              }
            else {
              Serial.print(temp); //Writes VALUE part to console
              }
            }
        }
        myFile.close();
      } else {
        Serial.println("Can't open CONFIG.TXT");
      }
    }

    void setup() {
      // put your setup code here, to run once:
      Serial.begin(115200);
      delay(10);
      readWifiConfig();
    }

    void loop() {
      // put your main code here, to run repeatedly:

    }

Output:

    Initializing SD card...
    Initialization done.
    CONFIG.TXT
    SSID=AP001
    KEY=AP001

I want to write the values to their corresponding variables and I don't know how.

    char* ssid;
    char* key;

body:
Somehow I managed to do it but my code is un-optimized. Please let me now if I've done something that isn't good.

I changed the content format to this so it's much easier for me. (CONFIG.TXT)

    SSID%&WIFIAP001&%KEY%&PASS1234&
New Code.

    #include <SPI.h>
    #include <SD.h>

    File myFile;
    char wifiSsid[63];
    char wifiKey[63];
    char temp;
    char settingSsid[5] = "SSID";
    char settingKey[4] = "KEY";
    char settingTemp[10];
    char valueTemp[63];
    int settingTempLastPos = 0;
    int valueTempLastPos = 0;
    int percentCount = 0;
    int andCount = 0;
    bool isSetting = true;
    bool ssidValueFound = false;
    bool keyValueFound = false;

    void readWifiConfig() {
      Serial.println("Initializing SD card...");

      if (!SD.begin(4)) {
        Serial.println("Initialization failed!");
        return;
      }
      Serial.println("Initialization done.");
      myFile = SD.open("CONFIG.TXT");
      if (myFile) {
        Serial.println("CONFIG.TXT");
        while (myFile.available()) {
          temp = myFile.read();
          if (temp == '%') {
            percentCount++;
            isSetting = true;
            if (percentCount == 2) {
              //Serial.println(settingTemp);
              if (strcmp(settingSsid,settingTemp) == 0) {
                Serial.println("SSID SETTING FOUND");
                //IF FOUND RAISE FLAG FOR ADDING VALUE TO SSID CHAR ARRAY
                ssidValueFound = true;
                }
              else if (strcmp(settingKey,settingTemp) == 0) {
                Serial.println("KEY SETTING FOUND");
                //IF FOUND RAISE FLAG FOR ADDING VALUE TO SSID CHAR ARRAY
                keyValueFound = true;
                }
              memset(&settingTemp[0], 0, sizeof(settingTemp));
              settingTempLastPos = 0;
              percentCount = 0;
            }
          }
          else if (temp == '&') {
            andCount++;
            isSetting = false;
            if (andCount == 2) {
              //Serial.println(valueTemp);
              if (ssidValueFound) {
                //Serial.println(valueTemp);
                memcpy(wifiSsid,valueTemp,63);
                //Serial.println(wifiSsid);
                ssidValueFound = false;
                }
              else if (keyValueFound) {
                //Serial.println(valueTemp);
                memcpy(wifiKey,valueTemp,63);
                //Serial.println(wifiKey);
                keyValueFound = false;
                }
              memset(&valueTemp[0], 0, sizeof(valueTemp));
              valueTempLastPos = 0;
              andCount = 0;
            }
          }
          else {
            if (isSetting == true) { //setting
              settingTemp[settingTempLastPos] = temp;
              settingTempLastPos++;
            }
            else if (isSetting == false) { //value
              valueTemp[valueTempLastPos] = temp;
              valueTempLastPos++;
            }
          }
        }
        //Serial.println(settingTemp);
        myFile.close();
      } else {
        Serial.println("Can't open CONFIG.TXT");
      }
    }

    void setup() {
      // put your setup code here, to run once:
      Serial.begin(115200);
      delay(10);
      readWifiConfig();
      Serial.println(wifiSsid);
      Serial.println(wifiKey);
    }

    void loop() {
      // put your main code here, to run repeatedly:

    }

Output:

    Initializing SD card...
    Initialization done.
    CONFIG.TXT
    SSID SETTING FOUND
    KEY SETTING FOUND
    WIFIAP001
    PASS1234


body:
New and improved code.

File format:

    $SETTINGNAME=SETTINGVALUE;

New code:

    #include <SPI.h>
    #include <SD.h>

    File configFile;
    uint8_t filePosition;
    uint8_t workingIndex = 0;
    uint8_t settingNameValuePositions[16][3];
    uint8_t temporaryBufferPosition = 0;
    char temporaryBuffer[32];

    void setPosition(uint8_t mrk) {
      settingNameValuePositions[workingIndex][mrk] = filePosition;
    }

    uint8_t getPosition(uint8_t idx, uint8_t mrk) {
      return settingNameValuePositions[idx][mrk];
    }

    void addToBuffer(char inp) {
      temporaryBuffer[temporaryBufferPosition] = inp;
      temporaryBufferPosition++;
    }

    void resetBuffer() {
      temporaryBufferPosition = 0;
      memset(temporaryBuffer, 0, sizeof(temporaryBuffer));
    }

    char* requestSetting(char *settingName) {
      for (int i = 0; i < workingIndex; i++) {
        uint8_t nS = getPosition(i,0); //$
        uint8_t eQ = getPosition(i,1); //=
        uint8_t vE = getPosition(i,2); //;
        bool isFound = false;
        resetBuffer();
        for (int g = nS; g < eQ - 1; g++) {
          configFile.seek(g);
          addToBuffer(configFile.read());
        }
        if (strcmp(temporaryBuffer,settingName) == 0) {
          isFound = true;
          resetBuffer();
        }
        for (int g = eQ; g < vE - 1; g++) {
          configFile.seek(g);
          addToBuffer(configFile.read());
        }
        if (isFound) {
          isFound = false;
          return temporaryBuffer;
        }
      }
      return "0";
    }

    bool readConfigFile(char* fileName) {
      //Serial.println("INITIALIZING SD CARD");
      if (!SD.begin()) {
        //Serial.println("INITIALIZING SD CARD FAILED");
        return false;
      }
      else {
        //Serial.println("INITIALIZING SD CARD COMPLETED");
        //Serial.println("OPENING FILE: " + String(fileName));
        configFile = SD.open(fileName);
        if (!configFile) {
          //Serial.println("ERROR OPENING FILE: " + String(fileName));
          return false;
        }
        else {
          //Serial.println("FILE " + fileName + " OPENED");
          //Serial.println("SEARCHING FOR MARKER POSITIONS");
          while (configFile.available()) {
            char fileChar = configFile.read();
            filePosition = configFile.position();
            switch (fileChar) {
              case '$':
                setPosition(0);
                break;
              case '=':
                setPosition(1);
                break;
              case ';':
                setPosition(2);
                workingIndex++;
            }
          }
        }
        return true;
      }
    }

    void setup() {
      Serial.begin(115200);
      readConfigFile("CONFIG.TXT"); //FILE NAME
      Serial.println(requestSetting("SETTINGNAME"));
    }
    void loop() {
    }


body:
    uint8_t settingNameValuePositions[16][3];

If you have more than 16 variables it's going to crash your webserver.

If your config file has more than 256 characters, then you should use short instead of uint8_t.


message:
What is the most Inputs on An analog Pin with a specified Accuracy on the Resistors Used?

I am asking about the technique were switches and resistors in series are used on the analog pin, so it creates a voltage divider when one of the switches is pressed, it a well known technique it is described here with 5 buttons on one analog pin

http://www.instructables.com/id/How-to-access-5-buttons-through-1-Arduino-input/

Obviously we assume the circuit is set up correctly e.g. the voltage reference is stable-but such things aren't the main point of this question.
My question is about an obvious generalisation of that circuit for more inputs - and where the resistors are all replaced by, a single type of resistor, a fixed resistance value (e.g. 4k ohm) with a known error on the resistance (e.g. 5%). We use the 4k resistors to make up larger values 4k,8k,12k,16k,20k Ohms and make the 100k Ohm resistor out of twenty five 4k ohm resistors.
My question using only 4k ohm resistors (connected in series in the voltage divider) within a 5% error of their value -what is the most switches  we can theoretically connect for reliable working on one analog pin?-I'll have a guess at 20 switches.

The second question is given X ohm resistors (connected in series in the voltage divider) within a E% error of their value -what is the most switches, M,  we can theoretically connect for reliable working on one analog pin? So there will be a formula for this-so what is it?

body:
The same the same technique is used routinely for 4x4 keypads. You don't really need very precise resistor as long as the final divider produce final voltage that are differente enough.

For each button/key you need to reserve some voltage range for it.
You can expected some random fluctuation every time you read the analog input, so you need some safety margin.

I think you can use up to 32 button/key using this technique. That's give you 150 mV of distance between each button (or +/- 32 for the corresponding analog value.


body:
You're just making a voltage resistor divider, with Vin at the top of the string of resistors, Vout at the selected resistor junction, and Gnd at the bottom.
Using 5V as Vin, then

Vout = Vin x (sum of resistance below the junction)/(sum of the entire string).

For example, 10 1K resistors, and the junction is between resistors 5 and 6 (resistor 1, R1, connected to Vin, resistor 10, R10, to Gnd).

Vout = 5V * 5,000/(10,000) = 2.5V

Arduino will return a reading of ~ 2.5V/5V * 1024 = 512 (~4.88mV per step)

Connect between R7 and R8

Vout = 5V * 3,000/(10,000) = 1.5V

analogRead = ~1.5/5 * 1024 = 307


body:
> My question using only 4k ohm resistors (connected in series in the
> voltage divider)

The circuit you are describing (a collection of identical resistors
connected in series) is quite different from the one discussed in the
link you provide. I assume you have in mind something analogous to a
digital pot, i.e. a chain of N resistors between GND and Vcc, with N
switches connecting the Arduino analog input to N taps along the chain:
N−1 taps in between consecutive resistors and one extra tap at GND¹.

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

The push buttons could actually be the multiple contacts of a rotary
switch. If using real push buttons, it would be tricky to know whether a
button is being pushed or if you are just reading noise, though it can
be known by toggling the pin between output and input and using its
stray capacitance.

In this case, the worst case error happens when all the resistors on one
side of the tap are 5% too high, while all those at the other side are
5% too low. It can be easily shown that the minimum possible voltage at
tap k is

V−(k) = k(1−e)/(k(1−e) + (N−k)(1+e))×Vcc

where e = 0.05 is the 5% tolerance of the resistors. The
maximum possible voltage, V+(k), is given by the same formula
after replacing e by −e.

The graph below shows the expected voltage at each tap for a chain of
20 resistors, with the error bars showing the possible voltage
ranges. The blue curves are the analytical expressions of
V−(k) and V+(k).

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

As can be seen on the graph, the largest error bars are the ones closer
to the central tap. Thus, the buttons can be discriminated accurately if
the two taps closest to the center have non overlapping error bars. This
criterion could be translated into an exact formula, but the formula
would be quite complex and depend on the parity of N. I propose to do
instead some approximations, starting with a first order Taylor
expansion on the error. This expansion gives the length of the error
bars as

V+(k) − V−(k) ≈ 4/N2 k (N−k) e × Vcc

This error is maximal when k = N/2 (we will forget the parity issue):

V+(N/2) − V−(N/2k) ≈ e × Vcc

Then we say that the taps can be discriminated if this error is smaller
than the expected voltage difference between consecutive taps, namely
Vcc/N. Then the criterion is now simply

N ≤ 1/e

which is exactly what your intuition told you.

------------------------------------------------------------------------
¹ The extra tap could be at Vcc rather than GND. It would be unwise,
however, to tap _both_ GND and Vcc, as a user pressing both buttons
simultaneously would then short the power supply.

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

------------------------------------------------------------------------

**Edit** to answer the questions in comments.

Yes, you could use the expressions of V+ and V− to
set the thresholds for discriminating the buttons. For example, you
could set the threshold between k and k+1 halfway between
V+(k) and V−(k+1), i.e.

threshold(k, k+1) = (V+(k) + V−(k+1)) / 2

However, if you try to compute that, you will see that it is extremely
close the average between the expected voltages. Then, you could use
that average as your threshold, which is given by a very simple formula:

threshold(k, k+1) = (k+½)/N×Vcc

Then, the pin number is just the integer closest to Vin/Vcc×N.
Assuming N = 20, this can be written as:

    const float VCC = 5.0
    float voltage = analogRead(PIN) * VCC / 1024;
    int button_number = round(voltage / VCC * 20);

This can be optimized to use only integer arithmetics:

    int button_number = (analogRead(PIN) * 5 + 128) >> 8;

Note that 20 buttons is kind of borderline. Your system could fail
if the errors due to resistor inaccuracies and those intrinsic to the
ADC (offset, gain error...) add up the wrong way. If you are building
only one device, then the safest fix would be to take note of the value
`analogRead()` returns for each button, and set the thresholds halfway
between consecutive values.

You could also measure the resistances of all your resistors, and
arrange them in a way that minimizes the errors. For example, if you
number the resistors from 0 to 19 in order of increasing resistance, I
would build the chain by arranging them in the following order:

0 19 2 17 4 15 6 13 8 11 9 10 7 12 5 14 3 16 1 18

Then you could most likely use the simple formula above to get the
button number at a minimal computing cost.


message:
functions not running

I have the following code as part of my efforts to clean this all up into more neatly organised functions.

I'm trying to run GetTemperatures and RunSerial as part of the main loop, however neither are being called.

If I uncomment the two code blocks I've tried to migrate into the functions in the main loop and comment out the calling of those two new functions, everything works ok.

I've looked through the arduino documentation and other places online but I'm unable to see where I've gone wrong.

    #include <OneWire.h>
    #include <ESP8266WiFi.h>
    #include <WiFiClient.h>
    #include <ESP8266WebServer.h>
    #include <ESP8266mDNS.h>

    //#include <DallasTemperature.h>

    const char* ssid = "ssid";
    const char* password = "password";

    //This sketch is for Wemos R1 not Arduino
    //Pin Assignment
    OneWire  ds(D6);

    //Digital Pin 4 Fan PWM pins)
    int FanPin = D7; //Pin 4
    int FanPWM = 0; //Start fans at max speed
    int FanPercent = 100; // PWM power %

    //Temperature thresholds

    int Set0PCTemp = 26;   // Temp for 0% fan speed
    //int MidTemp = 30;   // Max Temp for Min & Min Temp for Max
    int Set100PCTemp = 36;   // Temp for 100% fan speed

    // Temperature measurements

    float MeasTemp;       //Measured temperature value
    float DStemp;         //Value extracted from DS18B20 Sensor

    // Serial port input values
    int In0PCTemp;
    int In100PCTemp;

    ESP8266WebServer server(80);

    void setup(void)
      {
      //analogWriteFreq(25000);
      pinMode(FanPin, OUTPUT);
      analogWrite(FanPin, 128);
      delay(1000);
      Serial.begin(9600);
      WiFi.mode(WIFI_STA);
      WiFi.begin(ssid, password);
      Serial.println("");
      // Wait for connection
      while (WiFi.status() != WL_CONNECTED)
        {
        delay(500);
        Serial.print(".");
        }
      Serial.println("");
      Serial.print("Connected to ");
      Serial.println(ssid);
      Serial.print("IP address: ");
      Serial.println(WiFi.localIP());
      if (MDNS.begin("esp8266"))
        {
        Serial.println("MDNS responder started");
        }
        server.on("/", handleRoot);
        server.on("/inline", []()
          {
          server.send(200, "text/plain", "this works as well");
          }
                  );
        server.onNotFound(handleNotFound);
        server.begin();
        Serial.println("HTTP server started");
        //wifi end
        }

    void handleRoot()
      {
      //declare CSV variables
      String CSVHeaders = "Set0PCTemp,Set100PCTemp,MeasTemp,FanPercent,FanPWM";
      String CSVMessage = "";
      String CSVPayload = "";
      //  Compile CSV variables
      //CSVMessage = Set0PCTemp + "," + Set100PCTemp + "," + MeasTemp + "," + FanPercent + "," + FanPWM;
      CSVMessage += Set0PCTemp;
      CSVMessage += ",";
      CSVMessage += Set100PCTemp;
      CSVMessage += ",";
      CSVMessage += MeasTemp;
      CSVMessage += ",";
      CSVMessage += FanPercent;
      CSVMessage += ",";
      CSVMessage += FanPWM;
      CSVPayload = CSVHeaders;
      CSVPayload += "\n";
      CSVPayload += CSVMessage;
      //  char CSV_Payload[] = CSVPayload;
      //notify serial port of HTTP request
      Serial.println( "Sending Readings");
      Serial.println(CSVPayload);
      server.send(200, "text/plain", CSVPayload);
      }

    void handleNotFound()
      {
      String message = "File Not Found\n\n";
      message += "URI: ";
      message += server.uri();
      message += "\nMethod: ";
      message += (server.method() == HTTP_GET)?"GET":"POST";
      message += "\nArguments: ";
      message += server.args();
      message += "\n";
      for (uint8_t i=0; i<server.args(); i++)
        {
        message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
        }
      server.send(404, "text/plain", message);
      }

    void GetTemperature ()
      {
        Serial.println("step1");
      //original
      byte i;
      byte present = 0;
      byte type_s;
      byte data[12];
      byte addr[8];
      float DStemp;
      //////
      if ( !ds.search(addr))
        {
        Serial.println("step2");
        ds.reset_search();
        delay(250);
        return;
        }
      if (OneWire::crc8(addr, 7) != addr[7])
        {
        Serial.println("CRC is not valid!");
        return;
        }
        // the first ROM byte indicates which chip
        switch (addr[0])
          {
          case 0x10:
          type_s = 1;
          break;
          case 0x28:
          type_s = 0;
          break;
          case 0x22:
          type_s = 0;
          break;
          default:
          Serial.println("Device is not a DS18x20 family device.");
          return;
          }
        Serial.println("step3");
        ds.reset();
        ds.select(addr);
        ds.write(0x44, 1);        // start conversion, with parasite power on at the end
        delay(1000);
        present = ds.reset();
        ds.select(addr);
        ds.write(0xBE);         // Read Scratchpad
        for ( i = 0; i < 9; i++)
          {
          data[i] = ds.read();
          }
        // Convert the data to actual temperature
        int16_t raw = (data[1] << 8) | data[0];
        if (type_s)
          {
          raw = raw << 3; // 9 bit resolution default
          if (data[7] == 0x10)
            {
            raw = (raw & 0xFFF0) + 12 - data[6];
            }
          }
        else
          {
          byte cfg = (data[4] & 0x60);
          if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
          else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
          else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
          }
      DStemp = (float)raw / 16.0;
      }

    void RunSerial()
      {
            Serial.print(Set0PCTemp);
        Serial.print(",");
        Serial.print(Set100PCTemp);
        Serial.print(",");
        Serial.print(DStemp);
        Serial.print(",");
        MeasTemp = DStemp;
        //control fan speed
        //if(MeasTemp < Set0PCTemp)
         //{
         // if temp is lower than minimum temp
           //FanPWM = map(DStemp, Set0PCTemp, Set100PCTemp, 255, 0); // the actual speed of fan
           FanPWM = map(DStemp, Set0PCTemp, Set100PCTemp, 1023, 0); // the actual speed of fan
           //FanPWM = constrain(FanPWM, 0, 255);
           FanPWM = constrain(FanPWM, 0, 1023);
           analogWrite(FanPin, FanPWM);  // spin the fan at the fanSpeed speed
           //FanPercent = map(FanPWM,0,255,100,0);
           FanPercent = map(FanPWM,0,1023,100,0);
           Serial.print(FanPercent);
           Serial.print(",");
           Serial.println(FanPWM);
           //Serial.println(CSVMessage);
           //}
           //take temperature threshold input
          while (Serial.available() > 0)
            {
            int In0PCTemp = Serial.parseInt();
            int In100PCTemp = Serial.parseInt();
            if (Serial.read() == '\n')
              {
              In0PCTemp = constrain(In0PCTemp, 20, 35);
              In100PCTemp = constrain(In100PCTemp, 35, 50);
              Serial.print("Min=");
              Serial.print(In0PCTemp);
              Serial.print(",");
              Serial.print("Max=");
              Serial.print(In100PCTemp);
              Serial.println();
              Set0PCTemp = In0PCTemp;
              Set100PCTemp = In100PCTemp;
              }
          }
      }

    void loop(void)
      {
        GetTemperature;
      //start of GetTemperature content
      /*
      Serial.println("step1");
      //original
      byte i;
      byte present = 0;
      byte type_s;
      byte data[12];
      byte addr[8];
      float DStemp;
      //////
      if ( !ds.search(addr))
        {
        Serial.println("step2");
        ds.reset_search();
        delay(250);
        return;
        }
      if (OneWire::crc8(addr, 7) != addr[7])
        {
        Serial.println("CRC is not valid!");
        return;
        }
        // the first ROM byte indicates which chip
        switch (addr[0])
          {
          case 0x10:
          type_s = 1;
          break;
          case 0x28:
          type_s = 0;
          break;
          case 0x22:
          type_s = 0;
          break;
          default:
          Serial.println("Device is not a DS18x20 family device.");
          return;
          }
        Serial.println("step3");
        ds.reset();
        ds.select(addr);
        ds.write(0x44, 1);        // start conversion, with parasite power on at the end
        delay(1000);
        present = ds.reset();
        ds.select(addr);
        ds.write(0xBE);         // Read Scratchpad
        for ( i = 0; i < 9; i++)
          {
          data[i] = ds.read();
          }
        // Convert the data to actual temperature
        int16_t raw = (data[1] << 8) | data[0];
        if (type_s)
          {
          raw = raw << 3; // 9 bit resolution default
          if (data[7] == 0x10)
            {
            raw = (raw & 0xFFF0) + 12 - data[6];
            }
          }
        else
          {
          byte cfg = (data[4] & 0x60);
          if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
          else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
          else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
          }

        //Display current values
        DStemp = (float)raw / 16.0;
        */
        //end of GetTemperature content
        RunSerial;
        //start of RunSerial content
        /*
        Serial.print(Set0PCTemp);
        Serial.print(",");
        Serial.print(Set100PCTemp);
        Serial.print(",");
        Serial.print(DStemp);
        Serial.print(",");
        MeasTemp = DStemp;
        //control fan speed
        //if(MeasTemp < Set0PCTemp)
         //{
         // if temp is lower than minimum temp
           //FanPWM = map(DStemp, Set0PCTemp, Set100PCTemp, 255, 0); // the actual speed of fan
           FanPWM = map(DStemp, Set0PCTemp, Set100PCTemp, 1023, 0); // the actual speed of fan
           //FanPWM = constrain(FanPWM, 0, 255);
           FanPWM = constrain(FanPWM, 0, 1023);
           analogWrite(FanPin, FanPWM);  // spin the fan at the fanSpeed speed
           //FanPercent = map(FanPWM,0,255,100,0);
           FanPercent = map(FanPWM,0,1023,100,0);
           Serial.print(FanPercent);
           Serial.print(",");
           Serial.println(FanPWM);
           //Serial.println(CSVMessage);
           //}
           //take temperature threshold input
          while (Serial.available() > 0)
            {
            int In0PCTemp = Serial.parseInt();
            int In100PCTemp = Serial.parseInt();
            if (Serial.read() == '\n')
              {
              In0PCTemp = constrain(In0PCTemp, 20, 35);
              In100PCTemp = constrain(In100PCTemp, 35, 50);
              Serial.print("Min=");
              Serial.print(In0PCTemp);
              Serial.print(",");
              Serial.print("Max=");
              Serial.print(In100PCTemp);
              Serial.println();
              Set0PCTemp = In0PCTemp;
              Set100PCTemp = In100PCTemp;
              }
          }
          */
          //end of RunSerial content
          //wifi
          server.handleClient();
      }

body:
    RunSerial;

that does not call the function. Instead you should do

    RunSerial();

same with `GetTemperature`


message:
3D printer firmware version

Is there a way to determine which version of a Marlin firmware I would have installed onto my printer? I am trying to modify the existing arduino sketch rather than starting all over with a wrong, earlier version. Thanks.

body:
First, check to see if the printer itself yields this information, either on LCD display if present, or by reporting it to a host computer upon connection (ie, try enabling verbose output in your printing software).

While it's not guaranteed to be supported, in practice many Arduino Mega based 3d printers have bootloaders capable of readback of the flashed contents, and the chips themselves are unlocked.  Even if the bootloader does not support this, an ISP connection might.

If you are able to read out the contents, you can have `avrdude` write them to a flat binary file, and examine it with the `strings` program or a hex editor.  If you end up with a hex file instead, there are tools for converting this to a flat binary.

Your goal would be to look through the file for version strings, and other messages which might indicate specifics, especially on which side of various points of change or configuration options it falls.

Making such a backup is a good idea before loading a new firmware anyway.  Ideally after verifying that you obtained meaningful contents, you would also readback a few distinct copies of the file and use something like `diff` to verify that they are all the same.  You can grab the EEPROM contents too, if your firmware may be storing things there.


message:
Is it possible to extract a hex file via UART from an Arduino?

Right now I am tinkering on my 3D printer that has an Arduino mega as a brain. I need to update the Marlin firmware but in case of an error I want to create an backup of the firmware. And because it is assembled using a shield on top have no access to the ICSP interface. And I was curious if you can extract all the flash and EEPROM via USB (UART). If yes than what software should I use to do that.

body:
AVRDUDE which is used by the IDE to send the content of HEX file from your computer, as a feature letting it to get back the data of the flash, in order to compare and see if data are correct.

For a UNO try:

    avrdude -patmega328p -carduino -P/dev/cu.usbmodemFD121 -b115200 -U flash:r:"flash.bin":r

I think it would not be very hard to change that for a Mega.

It works fine. I have use that a lot to debut my "Android Updater" which allow the user of my board to update the code themselves.

PS: Just for info, you'll not get back the HEX file as in the flash, you have only some "pieces" of the HEX file.


body:
*It looks like my other answer was completely wrong, so I've deleted it.*

---

**Yes**, you can read back the flash using the USB interface, as Chris Stratton pointed out, and Peter mentioned in his answer.

The bootloader includes a "verify" action, which means it can be used to read the flash. If you connect up the USB cable to your Atmega2560 you can read the flash back by using a command similar to this:

<!-- language: lang-bash -->

    /usr/local/bin/arduino-1.6.9/hardware/tools/avr/bin/avrdude  `# where avrdude is`  \
    -patmega2560     `# chip type: atmega2560` \
    -cstk500v2       `# protocol: stk500 v2` \
    -P/dev/ttyACM2   `# what serial (hardware) port the board appears on` \
    -b115200         `# baud rate` \
    -U flash:r:"flash.hex":i   `# save flash as "flash.hex", in Intel format` \
    -C /usr/local/bin/arduino-1.6.9/hardware/tools/avr/etc/avrdude.conf  # config file for avrdude

This was done under Linux, with the command in "bash" format, which means the comments look a little strange, as I had to do that to put a comment on each line.

I've put comments on each line to show what each parameter means.

If you happen to have avrdude in your path, or are in the directory where it is installed, the brief form of the command would be:

    avrdude -patmega2560 -cstk500v2 -P/dev/ttyACM2 -b115200 -U flash:r:"flash.hex":i -C avrdude.conf

You will probably (almost certainly) have to change the path to where avrdude is, and where the configuration file for avrdude is. You will also need to find out the serial port that the board is on, which you can find out from the Arduino IDE (the Port menu will show you the possibilities).

---

As Chris Stratton suggests, do this a few times (change the file name of course) and compare the files (eg. using "diff"). If they are all the same then you can be reasonably confident that you have got good copies.


message:
Parse Bluetooth string

I'm developing on android with bluetooth LTE, I can send hex codes, but I send one code at time, so I need to send many informations in this way, how can I recognize a string and save the datas inside an array to parse it later?

Here is my sketch:

     char c=' ';
     String inString,one,check;
     char inData[11];
     char inChar;
     int counter=0;
     bool started = false;
     bool ended = false;
     byte index;

    boolean NL = true;
    const int LED1 = 6;
    const int LED2 = 7;
    const int LED3 = 2;
    const int LED4 = 3;
    const int LED5 = 4;
    const int LED6 = 5;

    void setup() {
       Serial.begin(9600);
        Serial.print("Sketch:   ");   Serial.println(__FILE__);
        Serial.print("Uploaded: ");   Serial.println(__DATE__);
        Serial.println(" ");

        BTserial.begin(9600);
        Serial.println("BTserial started at 9600");

        pinMode(LED1, OUTPUT);
        pinMode(LED2, OUTPUT);
        pinMode(LED3, OUTPUT);
        pinMode(LED4, OUTPUT);
        pinMode(LED5, OUTPUT);
        pinMode(LED6, OUTPUT);

    }

    void loop() {

      if (BTserial.available()>0)
        {
          Serial.print("bts: ");
          Serial.println(BTserial.available());
          c = BTserial.read();
          check =  String(c, HEX);

          if(check=="ffbc"){
            Serial.println("check");
            index=0;
            while (BTserial.available()>0){

                inChar = BTserial.read();
                check=String(inChar,HEX);
                if(check != "0xfff3")
                {
                    inData[index] = inChar;
                    index++;
                }
            }
            for (int i=0;i<=11;i++){
              one =  String(inData[i], HEX);
              Serial.print(i);Serial.print(": ");Serial.println(one);
            };

          }

                 if(check=="ffca"){
                 // Serial.write(c);
                  digitalWrite(LED1, !digitalRead(LED1));
                 }
                 if(check=="ffcb"){
                  //Serial.write(c);
                  digitalWrite(LED2, !digitalRead(LED2));
                  }
                  if(check=="ffcc"){
                  //Serial.write(c);
                  digitalWrite(LED3, !digitalRead(LED3));
                 }
                 if(check=="ffcd"){
                  //Serial.write(c);
                  digitalWrite(LED4, !digitalRead(LED4));
                  }
                  if(check=="ffce"){
                 // Serial.write(c);
                  digitalWrite(LED5, !digitalRead(LED5));
                 }
                 if(check=="ffcf"){
                 // Serial.write(c);
                  digitalWrite(LED6, !digitalRead(LED6));
                  }
        }
    }

Without the loop I can read all the single datas, but for my job it's not enough, to recognize the data applications I send a "sample string" to recognize the type of informations I want to send.

body:
i think i solved in some way, i send always the same codes at the start and at the end of the datas, so i can racognize the end and then i parse the first element of the destination array. tell  me what you think abou, if it could help someone else:

     if (BTserial.available()>0)
    {
      c = BTserial.read();
      check =  String(c, HEX);
      if(check!="fff3"){              // i always start wit an fff3
      inData[index] = c;
      index++;
     }
      else if(check=="fff3"){         //end of data
      index=0;                        //reset the index for the next set of data
      if(String(inData[1], HEX)=="ffbc"){
        Serial.println("read the next 10 data of the array");
        }else if(String(inData[1], HEX)=="11"){
        Serial.println("turn on led 1");
        }

        // for more operations use a switch/case over the if

      }


message:
powering Nodemcu using Vin

Forgive me for this really dumb question. I am an amateur in electronics, and im trying to wrap up my head around this question and im not able to do so. Need your help.

Im trying to power up a nodemcu using a 5v 1A power supply- I connected +ve to Vin and ground to ground. But i see that 5v is not enough to power up the nodemcu. So i removed the 5V and connected to a 9V battery, and again I find the same issue- the power is not enough. Knowing that i did something wrong - i measured the voltage across Vin and ground and find it to be around 2.5V when using the 5v source and around 2.5V when using the 9 V battery too.

Confused and thinking that my nodemcu is corrupted, i ordered a new one, and did the same. But i find that when i try to supply power using Vin, the voltage across the device- Vin and ground is around 2.5V for the newer device also. Obviously Im missing something.

Can anyone tell me what is it that Im doing wrong. Please tell me how to power a nodemcu without using a usb and only using a 5v source.

body: I have a NodeMCU Esp8266 v3 (Lolin) and it works fine conecting Vin and G to my cell phone power supply rated 5.1V, 1000mA. This develop board has a aprotective diode (the closest to Vin), if you have a Multimeter o multitester you can check it measurement continuity. If your diode is damaged the power applied to Vin never be enough to power up the nodemcu.


message:
Connect NodeMCU (ESP8266) with normal Switch (Regular 1 way Home button)

i am new to these circuit things, i am using Node MCU (ESP8266) board with relay board. To connect to a bulb, but i want to keep my old (one way) switch as it is. Also i want to add internet switching to this button.

How my circuit should look like? Two way switch will be compulsory to use here?  What my circuit should look like? with two way switch and one way switch.

Thank you! (in advance)

body:
First of all, a light bulb works on regular 110 or 230V AC depending on where you live, so directly connecting a wire to, for example, see if the hardware switch is turned on, would fry the NodeMCU. You'll need a relay break-out board that can handle these outputs on the COM/NO/NC (which most of them do) but they usually operate on 5V DC.

A NodeMCU can thus only supply the trigger signal to the relay, you'll need for example a AC to 5V DC power supply (like an iPhone adapter) to power your circuit. The circuit will contain of the relay board (connected with its DC in and out to the adapter and the com port to one of the GPIO's from the NodeMCU) and the NodeMCU itself as the 'brain' of the operation.

I don't exactly know what you mean by 'two-way switch' but the way I'd handle the situation is to wire the switch to the NodeMCU. This means the switch is connected to the 5V power adapter and when the switch is on, the nodeMCU will know because there will be a positive value at one of the GPIO's (whichever you choose). You can then also handle both commands from a server and the switch itself.

I'm doing kind off the same thing here with a NodeMCU working as a garageport opener with MQTT communication to a Homebridge server and MQTT broker running on a Raspberry Pi. If you want the code (still work in progress though) let me know ;)

**EDIT**
Here is the schematic you asked for. not the prettiest thing but it should make things clear. Let me know if you have any more questions!

<!-- 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/Z69uF.png)

<!-- End schematic -->

-BM


message:
Arduino MEGA 2560 - PWM in case statements not working

So I am using Arduino to control RGB Strip light, the `analogueWrite(Pin,Value);` Works with the prebuilt AnalogueWriteMega example - on pins 8, 9, and 10.

When I move this into my program, Pin 8 still works but pins 9 and 10 don't work.

Anywhere I write `analogueWrite()` it only works if the value is 255

- Green is pin 8
- Red is pin 9
- Blue is pin 10

<!-- language-all: lang-cpp -->

    #include <boarddefs.h>
    #include <IRremote.h>
    #include <IRremoteInt.h>
    #include <ir_Lego_PF_BitStreamEncoder.h>

    #include <LiquidCrystal.h>
    // encoder
    int val;
    int encoder0PinS = 29;
    int encoder0PinA = 31;
    int encoder0PinB = 33;
    int encoder0Pos = 0;
    int encoder0PinALast = LOW;
    int n = LOW;
    int MenuPos;
    int SubPos;
    bool Selected = false;
    int Reader = LOW;

    // lcd
    const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
    LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

    //pot
    int ASensePin = A0;
    double ASenseValue = 0;
    double AFixedValue = 0;
    int AFixOut = 0;

    //randoms
    int ranPin;
    int ranVal;

    //IR

    int receiver = 45; // Signal Pin of IR receiver to Arduino Digital Pin 45

    /*-----( Declare objects )-----*/
    IRrecv irrecv(receiver);     // create instance of 'irrecv'
    decode_results results;      // create instance of 'decode_results'

    void translateIR() { // takes action based on IR code received

      // describing Remote IR codes
      switch (results.value)
      {

------------
        case 16195807:
          Serial.println("Red, 0, 255, 0");
          analogWrite(8, 0);
          analogWrite(9, 255);    < ------ works
          analogWrite(10, 0);
          break;

        case 16197847:
          Serial.println("Yellow, 255, 255, 0");
          analogWrite(8, 100);      < ----don't work
          delay(50);
          analogWrite(9, 100);       <----don't work
          delay(50);
          analogWrite(10, 0);
          break;

----------
        case 16228447:
          Serial.println("green, 255 , 0, 0");
          analogWrite(8, 255);
          analogWrite(9, 0);
          analogWrite(10, 0);
          break;

        case 16230487:
          Serial.println("turquois, 0, 255, 255");
          analogWrite(8, 0);
          delay(50);
          analogWrite(9, 100);
          delay(50);
          analogWrite(10, 100);
          delay(50);
          break;

        case 16212127:
          Serial.println("blue, 0, 0, 255");
          analogWrite(8, 0);
          analogWrite(9, 0);
          analogWrite(10, 255);
          break;

        case 16214167:
          Serial.println("Purple, 255, 0, 255");
          analogWrite(8, 100);
          delay(50);
          analogWrite(9, 0);
          delay(50);
          analogWrite(10, 100);
          delay(50);
          break;

        case 16244767:
          Serial.println("White, 255, 255, 255");
          analogWrite(8, 255);
          analogWrite(9, 255);
          analogWrite(10, 255);
          break;

        default:
          Serial.println(results.value);
      }// End Case

      delay(500); // Do not get immediate repeat
    } //END translateIR

    void setup() {
      pinMode (encoder0PinA, INPUT);
      pinMode (encoder0PinB, INPUT);
      pinMode (encoder0PinS, INPUT);
      pinMode (8, OUTPUT);
      pinMode (9, OUTPUT);
      pinMode (10, OUTPUT);

      lcd.begin(16, 2);
      lcd.print("      Start     ");

      Serial.begin (9600);
    }

    void loop() {
      n = digitalRead(encoder0PinA);
      if ((encoder0PinALast == LOW) && (n == HIGH)) {
        if (digitalRead(encoder0PinB) == LOW) {
          encoder0Pos--;
        } else {
          encoder0Pos++;
        }
      }
      encoder0PinALast = n;
      if (encoder0Pos == 4) {
        encoder0Pos = 0;
      }
      if (encoder0Pos == -1) {
        encoder0Pos = 3;
      }

      MenuPos = encoder0Pos;

      Reader = digitalRead(encoder0PinS);
      // Serial.println(Reader);

      if (digitalRead(encoder0PinS) == LOW) {
        while (digitalRead(encoder0PinS) == LOW) {}
        Selected = true;
      }

      Serial.println("MenuLoop");
      switch (MenuPos) {
        case 0:
          lcd.setCursor(0, 0);
          lcd.print("     Random    ");
          while (Selected == true) {
            ranPin = random(8, 10);
            ranVal = random(0, 255);
            analogWrite(ranPin, ranVal);

            if (digitalRead(encoder0PinS) == LOW) {
              while (digitalRead(encoder0PinS) == LOW) {}
              Selected = false;
            }
          }
          break;

        case 1:
          lcd.setCursor(0, 0);
          lcd.print("       IR      ");
          Serial.println("IR Receiver Button Decode");
          irrecv.enableIRIn(); // Start the receiver

          while (Selected == true) {
            if (irrecv.decode(&results)) // have we received an IR signal?
            {
              translateIR();
              irrecv.resume(); // receive the next value
              lcd.setCursor(0, 1);
              lcd.print("               ");
              lcd.setCursor(0, 1);
              lcd.print(results.value);
            }
            if (digitalRead(encoder0PinS) == LOW) {
              while (digitalRead(encoder0PinS) == LOW) {}
              Selected = false;
            }
          }

          break;

        case 2:
          lcd.setCursor(0, 0);
          lcd.print("      Temp     ");
          break;

        case 3:
          lcd.setCursor(0, 0);
          lcd.print("      Pot      ");

          while (Selected == true) {

---------
Not working

            for (int thisPin = 8; thisPin <= 10; thisPin++) {
              // fade the LED on thisPin from off to brightest:
              for (int brightness = 0; brightness < 255; brightness++) {
                analogWrite(thisPin, brightness);
                delay(2);
              }
              // fade the LED on thisPin from brightest to off:
              for (int brightness = 255; brightness >= 0; brightness--) {
                analogWrite(thisPin, brightness);
                delay(2);
              }
              // pause between LEDs:
              delay(100);
            }

--------

            if (digitalRead(encoder0PinS) == LOW) {
              while (digitalRead(encoder0PinS) == LOW) {}
              Selected = false;
            }
          }
          break;
      }
    }

body:
The problem has nothing to do with your switch code. It's all to do with what you are *trying* to do, and peripherals conflicting.

Simply put: both PWM on pins 9 & 10, and the infrared library, require exclusive use of Timer 2.

Only one can use it. Either the infrared library, or PWM on those two pins, but not both.

You can modify the IR library to use a different timer instead of Timer 2 - for instance, you can set it to use Timer 1 which will remove your ability to use pins 11 and 12 as PWM.

[This is the bit of code](https://github.com/z3t0/Arduino-IRremote/blob/master/boarddefs.h#L82) that you would need to find and modify on your system to change timers.  [This page](https://playground.arduino.cc/Main/TimerPWMCheatsheet) shows you which timers are used for PWM on which pins.


message:
Powering Arduino Uno and Ardumoto Motor Driver Shield

I need to power an [Ardumoto Shield][1] to drive two 12V DC motors. I was planning to connect a 12V battery to the Max 18V input on the Ardumoto and a 9V battery to the barrel jack input of the Arduino Uno.  Can you tell me if this should be ok or if it would cause any damage to the Arduino?

It mentions in the [Ardumoto hookup guide:][2]

[![Ardumoto Supply Voltage][3]][3]

There's no mention of the Max 18V input on the Ardumoto.. Advice appreciated, thanks.

  [1]: https://www.antratek.com/ardumoto-motor-driver-shield
  [2]: https://learn.sparkfun.com/tutorials/ardumoto-kit-hookup-guide#ardumoto-overview
  [3]: https://i.stack.imgur.com/QivXR.png

body:
> **Do not supply power to both the Arduino barrel jack input and VIN on the shield!**

There goes the simple answer. Choose one.

If you power the system through arduino barrel jack input, you will have polarity protection, but the voltage output on VIN pin (which also used by Ardumoto shield) is slightly lower, about 0.6V lower than the input voltage because of the voltage drop on the protection diode.

If you have want to differentiate the supply for Ardumoto and Arduino (as described on your plan), you have to tamper the Ardumoto shield to isolate both supply. Although I never try it myself, it seems possible if you understands how L298 works.


body:
The L298 used in the Ardumoto shield has a maximum supply voltage of 46V. Hence 18V should be sufficient to power it as long as the motors have enough power too.

The Arduino voltage regulator, on the other hand, won't be able to handle such a high voltage. Hence you will have to remove the Vin pin that connects the Arduino & the shield in order to isolate the power supplies of the two.

Only then should you attempt plugging in the shield & then powering the Arduino through the 9V battery.


message:
Problem with SPI comms using NodeMCU v 3, Nano and SD

Recently I bought a NodeMCU 8266 v 3 (Lolin) and it works fine. I set up a Catalex SD card module (with a built-in 5-3.3V regulator) and all was good. Then I set the Lolin with an Arduino Uno and or a Nano working for SPI communications and all worked properly. So when I tried to put the Lolin as master, and two slaves (a Nano and an SD Card), all working with SPI, it did not work.

If I set up the SD card Vcc to 5 volts, the Lolin can "see" it and initializes it, but the communication between the Lolin and the Nano crashes (the Lolin can send the data but receives only trash; the Nano can receive and consequentely responds). When I disconnect the SD Vcc cable the communications works.

So I tried to remedy this situation using a bidirectional level shifter and the Lolin seems frozen.

Any help is welcome.

[![wired][1]][1]

Code of Lolin (as Master).

    /*Master - ESP12e create a variable string to be sent to slave - Nano_ChipSelect
        and receive a variable answer.

        Master ESP12e use:    COM5
              * SPI communications with a NANO as slave in GPIO 0 = D3
              * WiFi communication
              * a DS3231 for RTC
              * a catalex SD memory
    */

    /*---------------( Import needed libraries )-------------------------------------*/
    #include <ESP8266WiFi.h>                            // WiFi
    #include <WiFiClientSecure.h>                       // SSL Client
    #include <SPI.h>                                    // SPI comms
    #include <SD.h>                                     // SD mem card
    #include <Wire.h>                                   // RTC comms
    #include "RtcDS3231.h"                              // RTC by maluma

    /*---------------( Define Constants )--------------------------------------------*/
    #define Nano_ChipSelect             D3              // Slave select signal for NANO
    #define SD_ChipSelect               D8              // Slave select signal for SD

    /*---------------( Declare objects )---------------------------------------------*/
    RtcDS3231<TwoWire>    Rtc(Wire);
    File                  myFile;
    WiFiClientSecure      client;

    /*---------------( Declare Special settings--------------------------------------*/
    SPISettings           Set_SPI_NANO( 1000000, MSBFIRST, SPI_MODE0 );

    /*---------------( Declare Constants )--------------------*/
    String        defaultChatId         = "5";
    char          ssid[]                = "scouts";     // network SSID (name)
    char          password[]            = "R";   // network key

    /*---------------( Declare Variables )-------------------------------------------*/
    bool          switch_Red            = false;
    bool          switch_Yell           = false;
    bool          switch_Green          = false;
    unsigned int  temp_ESP12e            = 0;
    unsigned int  temp_nano             = 0;
    unsigned int  hum_nano              = 0;
    char          datestring[20];
    char          Nano_S_to_send[]      = "0000000000000000000000000|";
    //                                    "RRYYGcGYYYYcMMDDHcHMMSScc|"
    //                                     01234567890123456789012345
    //                                     0         1         2
    char          Nano_S_to_receive []  = "0000000000000000000000000|";
    //                                    "TTTTTcHHHHHcIIIIIcDDDDDcc|
    //                                     01234567890123456789012345
    //                                     0         1         2
    byte          Leds                  = 0;

    #define countof( a ) ( sizeof( a ) / sizeof( a[ 0 ] ) )

    void _printDateTime( const RtcDateTime& dt ) {  //---------------------------------
        snprintf_P(datestring,
                countof(datestring),
                PSTR("u/u/u u:u:u"),
                dt.Year(),
                dt.Month(),
                dt.Day(),
                dt.Hour(),
                dt.Minute(),
                dt.Second() );
    }

    void _create_data_for_nano() {  //-------------------------------------------------
      RtcDateTime now = Rtc.GetDateTime();
      _printDateTime( now );
      //;
      //             RRYYGcGYYYYcMMDDHcHMMSScc|
      //             0000000000000000000000000|
      Nano_S_to_send[ 0 ] = _getbit( Leds, 0 );  // red status
      Nano_S_to_send[ 1 ] = _getbit( Leds, 1 );  // red status
      Nano_S_to_send[ 2 ] = _getbit( Leds, 2 );  // yellow status
      Nano_S_to_send[ 3 ] = _getbit( Leds, 3 );  // yellow status
      Nano_S_to_send[ 4 ] = _getbit( Leds, 4 );  // green status
      Nano_S_to_send[ 5 ] = _Nano_CRC( 0, 5 );
      Nano_S_to_send[ 6 ] = _getbit( Leds, 5 );  //green status
      Nano_S_to_send[ 7 ] = datestring[ 0 ];  //y
      Nano_S_to_send[ 8 ] = datestring[ 1 ];  //y
      Nano_S_to_send[ 9 ] = datestring[ 2 ];  //y
      Nano_S_to_send[ 10 ] = datestring[ 3 ];  //y
      Nano_S_to_send[ 11 ] = _Nano_CRC( 6, 5 );
      Nano_S_to_send[ 12 ] = datestring[ 5 ];  //m
      Nano_S_to_send[ 13 ] = datestring[ 6 ];  //m
      Nano_S_to_send[ 14 ] = datestring[ 8 ];  //d
      Nano_S_to_send[ 15 ] = datestring[ 9 ];  //d
      Nano_S_to_send[ 16 ] = datestring[ 11 ];  //h
      Nano_S_to_send[ 17 ] = _Nano_CRC( 12, 5 );
      Nano_S_to_send[ 18 ] = datestring[ 12 ];  //h
      Nano_S_to_send[ 19 ] = datestring[ 14 ];  //m
      Nano_S_to_send[ 20 ] = datestring[ 15 ];  //m
      Nano_S_to_send[ 21 ] = datestring[ 17 ];  //s
      Nano_S_to_send[ 22 ] = datestring[ 18 ];  //s
      Nano_S_to_send[ 23 ] = _Nano_CRC( 18, 5 );
      Nano_S_to_send[ 24 ] = _Nano_CRC( 0, 24 );
    }

    char _getbit( byte data, byte pos ){
      byte b = data >> pos;
      b = b & 1;
      char b1[] = { '0' };
      if( b ) b1[ 0 ] = '1';
      return b1[ 0 ];
    }

    char _Nano_CRC( byte pos, byte lon ) {  //---------------------------------------------
      int  suma = 0;
      bool par  = false;
      for( int i = 0 ; i < lon ; i++ ) {
        suma += char( Nano_S_to_send[ i + pos ] );
        if( par )  {
          suma += 2 * char( Nano_S_to_send[ i + pos ] );
        }
        par = !par;
      }
      int  b = suma/10;
      if( suma != b*10 )  b++;
      b *= 10;
      char resultado[ 2 ];
      itoa( b - suma, resultado, 10 );
      return resultado[ 0 ];
    }

    void _transfer_data_to_NANO_by_spi() {  //----------------------------------------
      char c[2];
      digitalWrite( SD_ChipSelect, HIGH );
      cli();
      byte index2 = 0;
      SPI.beginTransaction( Set_SPI_NANO );
      digitalWrite( Nano_ChipSelect, LOW );
      byte num_char_to_transfer = sizeof( Nano_S_to_send ) ;
      for( byte index = 0 ; index <= num_char_to_transfer ; index++ ) {
        c[ 1 ] = ( Nano_S_to_send[ index ] );
        c[ 0 ] = SPI.transfer( c[ 1 ] );
        if( index != num_char_to_transfer ) Nano_S_to_receive [ index2 ] = 'E';
        if( c[ 0 ] != '\0' ) {
          Nano_S_to_receive [ index2 ] = c[ 0 ];
        }
        if( index != 0 ) index2++;
        delayMicroseconds( 2 );
      }
      digitalWrite(Nano_ChipSelect, HIGH);
      //Serial.print("-->");Serial.print(Nano_S_to_receive);Serial.println("<--");
      sei();
      SPI.endTransaction ();
    }

    String _txt2str( int valor ){  //-------------------------------------------------
      char v_txt[]= "000";
      itoa( valor, v_txt, 10 );
      String v_text = "";
      for( int i = 0 ; i < 4 ; i++ ){
        if( v_txt[ 3-i ] != '\0' ) {
          v_text = v_txt[ 3-i ]+ v_text;
        }
      }
      return v_text;
    }

    int _convierte( byte pos ){  //---------------------------------------------------
        char temporal [] = "     ";
        for( int i = 0 ; i < 4 ; i++ )  {
          temporal [ i ] = Nano_S_to_receive [ i + 1 + pos ];
        }
        int temp = atoi( temporal);
        return temp;
    }

    void setup() {   /*-----------( SETUP: RUNS ONCE )------------------------------*/
      pinMode( SD_ChipSelect,   OUTPUT );          // configure the line as output
      pinMode( Nano_ChipSelect, OUTPUT );          // configure the line as output

      Serial.begin( 115200 );              // start the serial monitor
      digitalWrite( SD_ChipSelect,   HIGH );       // turn to HIGH to disable
      digitalWrite( Nano_ChipSelect, HIGH );       // turn to HIGH to disable slave

      Serial.println();
      Serial.print( "compiled: " );Serial.print( __DATE__ );
      Serial.print( " at " );Serial.println( __TIME__ );
      Serial.print( "Connecting Wifi: " );
      Serial.println( ssid );

      Rtc.Begin();

      RtcDateTime compiled = RtcDateTime( __DATE__, __TIME__ );
      RtcDateTime now = Rtc.GetDateTime();
      _printDateTime( now );
      Serial.print(" --- Initialized WiFi at ");
      Serial.println( datestring );

      if ( !Rtc.IsDateTimeValid() )   {
            Serial.println( "RTC lost confidence in the DateTime!" );
            Rtc.SetDateTime( compiled );
            RtcDateTime now = Rtc.GetDateTime();
            _printDateTime( now );
      }

      if( !Rtc.GetIsRunning() )  {
        Serial.println( "RTC was not actively running, starting now" );
        Rtc.SetIsRunning( true );
      }

       if ( now < compiled )     {
        Serial.println( "RTC is older than compile time!  (Updating DateTime)");
        Rtc.SetDateTime( compiled );
      } else if( now > compiled )    {
          Serial.println( "RTC is newer than compile time. (this is expected)" );
        } else if ( now == compiled )     {
            Serial.println( "RTC is the same as compile time!");
          }
      Rtc.Enable32kHzPin( false );
      Rtc.SetSquareWavePin( DS3231SquareWavePin_ModeNone );

      Serial.print( "Initializing SD card..." );

      SPI.begin();
      /* begin SPI at 1 Mbit rate most significat bit first & mode 0 */
      SPI.beginTransaction( SPISettings( 1000000, MSBFIRST, SPI_MODE0 ) );
      digitalWrite( SD_ChipSelect, LOW );

      if ( !SD.begin( SD_ChipSelect ) ) {
        Serial.println( "initialization failed!" );
        return;
      }
      myFile = SD.open( "Log_1.txt", FILE_WRITE );
      if (myFile) {                           // if the file opened okay, write to it:
        myFile.println( "YYYY:MM:DD:HH:MM:SS:TNANO:HNANO:TESP12e" );
        // close the file:
        myFile.close();
      } else {                             // if the file didn't open, print an error:
        Serial.println( "error opening file Log_1.txt" );
      }

      digitalWrite( SD_ChipSelect, HIGH );
      SPI.endTransaction();

      Serial.println( "*****  initialization done. ******" );
    }

    void loop() {  //-----------------------------------------------------------------

      Serial.println("*********** E S P 1 2 ***********");
      RtcTemperature temp = Rtc.GetTemperature();
      temp_ESP12e = temp.AsFloat() * 100;                         // System Temperature

      _create_data_for_nano();
      _transfer_data_to_NANO_by_spi();       // transfer routine to send and receive data
      //_check_received_data();

      Serial.print( "->NANO:" );Serial.print(    Nano_S_to_send );Serial.println(":");
      Serial.print( "NANO<-:" );Serial.print( Nano_S_to_receive );Serial.println(":");

      Leds++;
      if( Leds > 64 ) Leds = 0;
      delay(5000);
    }

Code of nano ( as slave )

    /* Slave - Nano receive a variable string, byte by byte from
     *  master - ESP12e and create a variable answer

          Slave NANO use:    COM3
               * SPI communications
               * an AM2302 sensor for temperature and humidity
               * timers
    */

    /*---------------( Import needed libraries )-------------------------------------*/
    #include <SPI.h>
    #include <DHT.h>
    #include "DHT_U.h"
    #include "SimpleTimer.h"
    #include "Adafruit_Sensor.h"

    /*---------------( Define Constants )--------------------------------------------*/
    #define switch_Yell       2
    #define switch_Green      4
    #define switch_Red        6
    #define DHTPIN            9         // Pin connected to the DHT sensor.

    #define DHTTYPE           DHT22     // DHT 22 (AM2302)

    /*---------------( Declare objects )---------------------------------------------*/
    SimpleTimer timer;
    DHT_Unified dht(DHTPIN, DHTTYPE);

    /*---------------( Declare Special settings--------------------------------------*/

    /*---------------( Declare Constants )--------------------*/

    /*---------------( Declare Variables )-------------------------------------------*/
    uint32_t       waiting_for_AM2302;
    char           string_to_receive[] = "0000000000000000000000000|";
    //                                   "RRYYGcGYYYYcMMDDHcHMMSScc|"
    //                                    01234567890123456789012345
    //                                    0         1         2
    char           string_to_answer[]  = "0000000000000000000000000|";
    //                                   "TTTTTcHHHHHcIIIIIcDDDDDcc|
    //                                    01234567890123456789012345
    //                                    0         1         2
    volatile byte  index;
    volatile bool  receivedone;  /* used as reception complete flag */
    byte           Dummy               = 0;

    // function to be called repeatedly by timer function
    void Read_AM2302() {  //-----------------------------------------------------------

      int tempera    = -1;
      int humidit    = -1;
      int illumin    = -1;
      int dummy       = -1;
      sensors_event_t event;
      // Get temperature event and print its value.
      dht.temperature().getEvent(&event);
      if (isnan(event.temperature)) {
        Serial.println("Error reading temperature!");
      }
      else {
        tempera = event.temperature * 10;
      }
      // Get humidity event and print its value.
      dht.humidity().getEvent(&event);
      if (isnan(event.relative_humidity)) {
        Serial.println("Error reading humidity!");
      }
      else {
        humidit = event.relative_humidity * 10;
      }

    //  tempera = 9;
    //  humidit = 72;
      illumin = 143;

      _create_answer( tempera,   0 );
      string_to_answer[  5 ] = _CRC(  0,  5 );
      _create_answer( humidit,      6 );
      string_to_answer[ 11 ] = _CRC(  6,  5 );
      _create_answer( illumin, 12 );
      string_to_answer[ 17 ] = _CRC( 12,  5 );
      //_create_answer( Dummy,       18 );
      string_to_answer[ 18 ] = _getbit( Dummy, 4 );
      string_to_answer[ 19 ] = _getbit( Dummy, 3 );
      string_to_answer[ 20 ] = _getbit( Dummy, 2 );
      string_to_answer[ 21 ] = _getbit( Dummy, 1 );
      string_to_answer[ 22 ] = _getbit( Dummy, 0 );
      string_to_answer[ 23 ] = _CRC( 18,  5 );
      string_to_answer[ 24 ] = _CRC(  0, 24 );
      /*
      Serial.print(" Temperature =");Serial.println( tempera );
      Serial.print(" Humidity     =");Serial.println( humidit );
      Serial.print(" Illumination =");Serial.println( illumin );
      Serial.print(" Dummy       =");Serial.println( Dummy   );
      Serial.print("Answer-->"); Serial.println( string_to_answer );
      */
    }

    char _getbit( byte data, byte pos ){
      byte b = data >> pos;
      b = b & 1;
      char b1[] = { '0' };
      if( b ) b1[ 0 ] = '1';
      return b1[ 0 ];
    }

    char _CRC( byte pos, byte lon ) {  //----------------------------------------------
      int  suma = 0;
      bool par  = false;
      for( int i = 0 ; i < lon ; i++ ) {
        suma += char( string_to_answer[ i + pos ] );
        if( par )  {
          suma += 2 * char( string_to_answer[ i + pos ] );
        }
        /*
        Serial.print(" i=");Serial.print(i);
        Serial.print(" d=");Serial.print(string_to_answer[ i + pos ] );
        Serial.print(" s=");Serial.println( suma);
        */
        par = !par;
      }
      int  b = suma/10;
      if( suma != b*10 ) b++;
      b *= 10;
      char result[ 2 ];
      itoa( b - suma, result, 10 );
      /*
      Serial.print( "-S-" );Serial.print( sum );      Serial.println("---");
      Serial.print( "-B-" );Serial.print( b );        Serial.println("---");
      Serial.print( "-R-" );Serial.print( result[ 0 ] );Serial.println("---");
      */
      return result[ 0 ];
    }
                       //      9         0
    void _create_answer( int data, byte pos) {  //-------------------------------------
      char temporal[] = {'\0','\0','\0','\0','\0'};  // masc
      byte longitud = 5;          // posicion desde 0 hasta n
      byte puntero = pos + longitud; //5
      itoa( data, temporal, 10 );//9
      //Serial.print("-t-");Serial.println( temporal );
      //Serial.print("-s-");Serial.println( sizeof temporal );
      for( int i = longitud ; i >= 0 ; i-- ) {
        //Serial.print("-val-");Serial.println( (temporal[i]) );
        if( temporal[i] != '\0' ) {
        string_to_answer[ puntero-- ] = temporal [ i ];
        }
      }
    }

    // SPI interrupt routine
    ISR (SPI_STC_vect) {  //-----------------------------------------------------------
      uint8_t oldsrg = SREG;
      cli();
      string_to_receive[ index ] = SPDR;
      SPDR = string_to_answer[ index ];
      if( string_to_receive [index] == '\0' ) receivedone = true;
      if( index < sizeof( string_to_receive ) ) index++;
      sei();
      SREG = oldsrg;
    }

    void setup (){  //-----------------------------------------------------------------
      Serial.begin (115200);

      pinMode(MISO, OUTPUT);
      SPCR |= _BV(SPE);    // turn on SPI in slave mode
      SPCR |= _BV(SPIE);   // turn on interrupts

      index = 0;
      receivedone = false;
      SPI.attachInterrupt();    /* Attach SPI interrupt */
      dht.begin();
      sensor_t sensor;
      dht.temperature().getSensor(&sensor);
      dht.humidity().getSensor(&sensor);
      waiting_for_AM2302 = sensor.min_delay / 1000;
      Serial.println("------------------------------------");
      Serial.println("Temperature");
      Serial.print  ("Sensor:       "); Serial.println(sensor.name);
      Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
      Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
      Serial.print  ("Max Value:    "); Serial.print(sensor.max_value);
      Serial.println(" *C");
      Serial.print  ("Min Value:    "); Serial.print(sensor.min_value);
      Serial.println(" *C");
      Serial.print  ("Resolution:   "); Serial.print(sensor.resolution);
      Serial.println(" *C");
      Serial.println("------------------------------------");
      Serial.println("Humidity");
      Serial.print  ("Sensor:       "); Serial.println(sensor.name);
      Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
      Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
      Serial.print  ("Max Value:    "); Serial.print(sensor.max_value);
      Serial.println("%");
      Serial.print  ("Min Value:    "); Serial.print(sensor.min_value);
      Serial.println("%");
      Serial.print  ("Resolution:   "); Serial.print(sensor.resolution);
      Serial.println("%");
      Serial.println("------------------------------------");
      timer.setInterval( waiting_for_AM2302, Read_AM2302 );
      pinMode( switch_Red,   OUTPUT );
      pinMode( switch_Yell,  OUTPUT );
      pinMode( switch_Green, OUTPUT );
      digitalWrite( switch_Red,   LOW );
      digitalWrite( switch_Yell,  LOW );
      digitalWrite( switch_Green, LOW );

    }

    void loop () {  //-----------------------------------------------------------------
        timer.run();
      if (receivedone) {         /* Check and print received buffer if any */
        Serial.println( "************ N A N O ************" );
        Serial.print( "ESP12e<-:" );Serial.print( string_to_receive );Serial.println( ":" );
        Serial.print( "->ESP12e:" );Serial.print( string_to_answer );Serial.println( ":" );
        //_check_received_data();
        digitalWrite( switch_Red,   string_to_receive[ 1 ] - 48 );
        digitalWrite( switch_Yell,  string_to_receive[ 3 ] - 48 );
        digitalWrite( switch_Green, string_to_receive[ 6 ] - 48 );
        string_to_receive[index] = 0;
        index = 0;
        receivedone = false;

        Dummy++;
        if( Dummy > 32 ) Dummy = 0;
      }
    }

here is the Serial monitor view

    Master
        ******* L O L I N *******
        ->NANO:1111191201800204282452676|:
        NANO<-:000EEEEEEEE :                     --- connected at 5V
        ******* L O L I N *******
        ->NANO:0000080201810204282453192|:
        NANO<-:00<:
        ******* L O L I N *******
        ->NANO:0000080201810204282453642|:
        NANO<-:EEEEEEEEEEEEEEEEEEEEEE:          ---- connected at 3.3 V
        ******* L O L I N *******
        ->NANO:1000070201810204282454160|:
        NANO<-:0000990007250014320806510|:      ---- disconnected

    Slave
        ************ N A N O ************
        LOLIN<-:1111191201800204282452676|
        ->LOLIN:0000990007250014320806510|
        ************ N A N O ************
        LOLIN<-:0000080201810204282453192|
        ->LOLIN:0000990007250014320806510|
        ************ N A N O ************
        LOLIN<-:0000080201810204282453642|
        ->LOLIN:0000990007250014320806510|
        ************ N A N O ************
        LOLIN<-:1000070201810204282454160|
        ->LOLIN:0000990007250014320806510|

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

body: Use a tri-state buffer on the MISO pins of the SPI devices using the slave select as enable. It's the only way I could make it work.


message:
ESP8266 as wifi Card?

I am very new to arduino and electronics in general. Can i use the NodeMcu Esp8266 as one of those usb wifi dongles? I want to use it as a monitor mode capable wifi card, for my linux laptop.

body:
No, you can't. All you have is a UART interface through a USB to UART adaptor. It can only ever be a UART.

The best you could get would be to write a program to run on the NodeMCU that did the monitoring for you (assuming you can get it into a suitable promiscuous mode) and report information back to you through the UART.


message:
Why I'm getting this error: invalid conversion from 'const char*' to 'char' [-fpermissive]?

Why I'm getting this error?

`invalid conversion from 'const char*' to 'char' [-fpermissive]`

Here is my simple sketch:
<!-- language-all: lang-cpp -->

    const char data = "should";

    //I have also tried:
    //const char* data = "should";

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

    void loop() {
      Serial.print("this " + data + " work");
    }

body:
A char can only store one character.

and const char* data can store a pointer to a string.

You can copy it with strcpy:

    const char* data = malloc(7);
    if (data != 0)
    {
        strcpy(data, "should");
    }

This will create 7 bytes, which can store "should" (adding 1 byte extra for the \0 byte to denote the end of a string.

However, in your case you can create a const string like:

    const char data[7]="should";

or

    const char data[]="should";


body:
    const char data = "should";

In this case `data` is a single character, not a string. So it can store `'s'` but not `"should"`.

    Serial.print("this " + data + " work");

No, that will never work, even if you get your data types correct.  You do not concatenate strings like that. All you are doing is attempting to add the addresses of two string literals to the address of a string constant. If that were possible (the  compiler doesn't let  you) you'll get gibberish (or a crash) as it tries to print out whatever is at that address.

Instead break it down:

    Serial.print("this ");
    Serial.print(should);
    Serial.print(" work");


message:
Preventing relay switch-off crashing Ethernet controller

I have an Arduino Uno with Ethernet Shield controlling some relays. Initially everything works fine but then when switching the relay off, the Ethernet controller frequently 'crashes'. Ethernet stops responding to pings, although the Arduino Uno keeps running. Pressing the reset button brings the Ethernet controller back to life.

I am using three relays to control:

* The 'Call for Heat' contact on the boiler (normally connected to a thermostat)
* A Honeywell V4043 zone valve (6W / 0.42A)
* A Grundfos UPS2 underfloor heating pump (0.06A - 0.42A)

[![Block Diagram](https://raw.githubusercontent.com/njh/HeatingController/master/docs/block-diagram.png)](https://github.com/njh/HeatingController)

This is my setup:

* I am using 2N7002 MOSFETs to drive the relays
* I have 1N4004 diodes across the coils

There is a circuit diagram for the 'Relay Driver Shield' part of the circuit here:
https://github.com/njh/relay-driver-shield

This is what I have done to attempt to solve the problem:

 * I have moved the Arduino + Ethernet further away from the relays
 * I switched to higher quality Omron Relays (G2R-1-S-DC12)
 * I have tried both Wiznet W5100 and ENC28J60 Ethernet controllers

But so far nothing has solved the problem.

Of the three relays, it appears to be the Honeywell V4043 zone valve that is causing the problem. While testing with no loads connected to the relays, it was working fine. My assumption is that the problem is related to discharges across the contacts, partly due to the inductive loads. But I am not sure what to do to fix it.

Thanks,

nick.

body:
I would suggest two things:

1. Use opto-isolators instead of (or as well as) the MOSFETs to control the relays, and
2. Add RC snubber circuits across the contacts.

The latter is the most important, since the spark across the contacts when they open will cause massive amounts of EMI.

The simplest circuit is a simple series resistor and capacitor placed across the contacts:

<!-- 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/jdlAg.png)

<!-- End schematic -->

Of course, ensure that the resistor and capacitor are rated for *at least* the voltage you are switching, preferably double.

Selecting the right values for the components depends very much on the load being switched and how much energy needs to be absorbed. I have shown ball-park figures that are usually "ok" for many situations.


message:
Will adding Ethernet shield reduce the IO count of Arduino?

I have [searched this question][1] but could not find an answer on this site.

There was a [related question - `Latest Ethernet shield - used pins, how to bypass restrictions`][2] on arduino forums, but, I was unable to understand what the answer meant.

**The background of my project:**

My project requires
<pre>
| S.No. | IO Type | IO Qty |
|-------+---------+--------|
| 1     | AI      |     11 |
| 2     | DI      |      9 |
| 3     | DO      |     11 |
</pre>

I intend to connect this arduino board via ethernet shield to a network. I want to receive data over the network for display and storage purposes on a PC.

**Questions:**

 1. What Arduino board should I select?
 2. Will **ESP8266** be compatiable with the suggested model?
 3. Are there any pitfalls that should be considered when making the
    selection for this design.

*P.S: I have raised the same question on the [arduino forum][3]. If I get an answer- I will share my answer here as well*

  [1]: https://arduino.stackexchange.com/search?q=ethernet shield
  [2]: http://forum.arduino.cc/index.php?topic=178633.0
  [3]: https://forum.arduino.cc/index.php?topic=527048.msg3594605#msg3594605

body:
You should use a Mega if you really need so many gpio pins.

Arduino Ethernet and WiFi shields and their clones use 3 GPIO pins with SPI function with connection on ICSP header. Next they use the Slave Select signaling pin 10 and the SD card Slave Select signaling pin 4. The shields are compatible with Mega. So you should still have enough pins.

esp8266 can be connected to SPI. then it uses the same pins like the Ethernet shield except of the SD card slave select pin.

if you connect esp8266 to Serial port, then all the pins are free. Mega has 4 Serials.

esp8266 is cheaper but you need to connect it with level shifters and have a good power supply. there is no good esp8266 shield for now. The Mega + WiFi board from Robotdyn has the esp8266 on board with Serial connection.


message:
What causes Serial.available() to become false after Serial.read() gets data?

As serial data bytes are being read from the serial buffer by `Serial.read()`, are they removed from the Arduino's 64-byte serial buffer altogether?

In my current situation I'm using SoftwareSerial, but this question applies to both software and hardware serial connections.

**EDIT:** *Based on a comment from **@dandavis**, I'd like to further clarify my question*

How does `Serial.read()` interact with `Serial.available()`? Let's say that I have the usual setup:

    while( Serial.available() ) {
        Serial.read();
    }

What causes `Serial.available()` to become `false`?

**EDIT 2:** _Changed question title for even further clarification..._

body:
It is an internal buffer and only the pointer gets increased. It it visible in the source code off the project, located on [github][1]:

<!-- language: c -->

    // Read data from buffer
    int SoftwareSerial::read()
    {
      if (!isListening())
        return -1;

      // Empty buffer?
      if (_receive_buffer_head == _receive_buffer_tail)
        return -1;

      // Read from "head"
      uint8_t d = _receive_buffer[_receive_buffer_head]; // grab next byte
      _receive_buffer_head = (_receive_buffer_head + 1) % _SS_MAX_RX_BUFF;
      return d;
    }

This third line from the bottom is the important part, it wraps back to the beginning if the buffer space has run out. If you call `Serial.read()`, the pointer is moved to the next position. So with the next `Serial.read()`, you'll get the next byte, if available. The byte itself gets overwritten only after the wrap (circular buffer).

  [1]: https://github.com/arduino/Arduino/blob/2bfe164b9a5835e8cb6e194b928538a9093be333/hardware/arduino/avr/libraries/SoftwareSerial/src/SoftwareSerial.cpp


body:
Calculating how many bytes are available for reading:

    int HardwareSerial::available(void)
    {
      return ((unsigned int)(SERIAL_RX_BUFFER_SIZE + _rx_buffer_head - _rx_buffer_tail))
    }

It's so simple.

Have a look at the Arduino subdir (in your disk) `hardware/arduino/avr/cores/arduino`. The HardwareSerial.cpp is where you have to look at.


message:
SPI - Apparently Random pulses on CS/SS line

I'm trying to figure out why my SPI device isn't responding as expected. So I hooked up my logic analyzer and am a bit confused by the results.

I'm seeing what appears to be random pulses on the chip select/slave select line (CS in the images below). The pulses happen in random locations with random counts. Always matching either a falling edge or rising edge in the CLK line.

[![Logic Analyser Screen Capture 1][1]][1]
[![Logic Analyser Screen Capture 2][2]][2]

The code I'm running is part of a library, but I've pulled it all out for a minimum functional example:

    #include <SPI.h>

    #define DC_PIN          9
    #define CS_PIN          10
    #define BUSY_PIN        7

    int IfInit(void) {
        pinMode(CS_PIN, OUTPUT);
        SPI.begin();
        SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0));
        return 0;
    }

    void SpiTransfer(unsigned char data) {
        digitalWrite(CS_PIN, LOW);
        SPI.transfer(data);
        digitalWrite(CS_PIN, HIGH);
    }

    int Init() {

        if (IfInit() != 0) {
            return -1;
        }

        SendCommand(0x01); //POWER_SETTING
        SendData(0x03);                  // VDS_EN, VDG_EN
        SendData(0x00);                  // VCOM_HV, VGHL_LV[1], VGHL_LV[0]
        SendData(0x2b);                  // VDH
        SendData(0x2b);                  // VDL
        SendData(0xff);                  // VDHR
        SendCommand(0x06); //BOOSTER_SOFT_START
        SendData(0x17);
        SendData(0x17);
        SendData(0x17);                  //07 0f 17 1f 27 2F 37 2f
        SendCommand(0x04); //POWER_ON
        WaitUntilIdle();
        SendCommand(0x00); //PANEL_SETTING
        SendData(0xbf);    // KW-BF   KWR-AF  BWROTP 0f
        SendData(0x0b);
        SendCommand(0x30); //PLL_CONTROL
        SendData(0x3c);        // 3A 100HZ   29 150Hz 39 200HZ  31 171HZ

        return 0;
    }

    void SendCommand(unsigned char command) {
    //    digitalWrite(DC_PIN, LOW);
        SpiTransfer(command);
    }

    void SendData(unsigned char data) {
    //    digitalWrite(DC_PIN, HIGH);
        SpiTransfer(data);
    }

    void WaitUntilIdle(void) {
        while(digitalRead(BUSY_PIN) == 0) {      //0: busy, 1: idle
            delay(100);
        }
    }

    void setup() {

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

      Serial.begin(9600);
      Serial.println("Start");

      if (Init() != 0) {
        Serial.println("init failed");
        return;
      }

      Serial.print("init success");

    }

    void loop() {

    }

I've tried on two different ATMEGA chips (same Arduino Uno board), same results. I've also tried with the device disconnected. Again same results. I've also tried changing the pin used for the CS, still didn't change anything.

Anyone have some insight as to what might be causing this, and/or what can be done to stop it?

  [1]: https://i.stack.imgur.com/4YkdH.png
  [2]: https://i.stack.imgur.com/mLqyB.png

body:
See [my page about SPI](http://www.gammon.com.au/spi).

> Pin 10 of the Arduino is the SS line - so does this mean you have to use it for the peripheral SS line? Or should it be kept high? The answer (from the Atmega documentation) is that the SS line (pin 10) must be configured as an **output** (regardless of what value is on it). If configured as an output the Arduino ignores the value on that line, and thus the SPI hardware will not be put into slave mode.
>
>
Since the value on pin 10 is ignored, providing it is set as an output, then it can also be used as the SS line for your first, or only, slave. You could then use other pins (eg. 5, 6, 7, 8, 9) to control other slaves.

For you to successfully make an SPI master then pin 10 on your Uno must be configured as an output, regardless of whether or not you actually use pin 10 for SS. Under the circumstances, you may as well use pin 10 for SS if you are going to make it an output anyway.

---

> This issue persists when using pin 10 as the SS.

I tried your code with my Uno (no device connected) and had no such problems. Sounds like an electrical issue to me.

[![SPI timing][1]][1]

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


body:
I shortened the leads between my arduino board and the device from 15 inches down to ~5 inches and the issue disappeared.

I would have to guess that it was some RF interference.


message:
SD begin affecting OLED display

Okay, I'm using `u8g2` library for my OLED display. After calling SD.begin(4) function, I cannot display anything on my OLED.

I'm using `U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);` constructor from `u8g2` library since I'm using `I²C` for the display and SPI for microSD reader. I removed the `CS Pin 4` from `SD.begin()` and I can now display something on the OLED.

How did supplying CS Pin parameter to `SD.begin()` function affected the `I²C` OLED display?

body:
Pins 4 and 5 are the I2C pins that belong to the built in I2C peripheral on the Arduino. You have to put your CS line for the SPI SD card on a different pin.

**EDIT:**
The answer above is relevant to the Arduino ATMega328-based board, not ESP8266-based NodeMCU board. This answer is not relevant to ESP8266 or NodeMCU with regard to hardware I2C, as the ESP8266 does not have a dedicated hardware I2C peripheral.


message:
NodeMCU doesn’t send the sensor read while powering with Vin

I have connected a NodeMCU ESP 12 with the Vin (6 volts) shared with 2 other NodeMCU. The sensors are getting power from the NodeMCU but the NodeMCU isn’t sending to the ThingSpeak cloud unless I plugged it to the PC and unplug the Vin.

Help please.[![enter image description here][1]][1]

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

body: You must connect together all devices by their GND pin.


message:
How do I lower clock speed for MKR1000?

According to [data sheets](http://k12stem.us/assets/Arduino Board Lineup v2.pdf), the MKR1000 runs a SAMD21 Cortex-M0+ processor at 48 MHz. For a project I need to drop that down to 16MHz to get some accurate timing in us. How can I do this? Most of the suggestions on the internet involve the ATmega* boards.

Thanks in advance.

body: 48 MHz is a multiple of 16MHz. Why not just adjust the timing code to account?


message:
Nodemcu connecting to Wi-Fi Problem

I am trying to connect to Wi-Fi with Digital pin declaration in setup() function it's not connecting to wi-fi. But connecting to wi-fi without digital pin diclaration. `

    #include <ESP8266WiFi.h>
    #include <ESP8266HTTPClient.h>
    int m1 = 5;
    int m2 = 6;
    const char* ssid = "KS Infotech";
    const char* password = "kalamsalam";
    String readc = "";
    void setup () {
    pinMode(m1, OUTPUT);
    digitalWrite(m1, LOW);
    pinMode(m2, OUTPUT);
    digitalWrite(m2, LOW);
    Serial.begin(9600);
    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED) {

    delay(1000);
    Serial.print("Connecting..");

    }

    }

    void loop() {
    while (Serial.available()){  //Check if there is an available byte to read
    delay(10); //Delay added to make thing stable
    char c = Serial.read();
    String T = String(readc);
        Serial.println(T);
    if (WiFi.status() == WL_CONNECTED) { //Check WiFi connection status

    HTTPClient http;  //Declare an object of class HTTPClient

    http.begin("http://ksinfotech.co/kslab/write_to_database.php?incoming="+T+"&UID=surya");  //Specify request destination
    int httpCode = http.GET();

    if (httpCode > 0) { //Check the returning code

      String payload = http.getString();   //Get the request response payload
      Serial.println(payload);                     //Print the response payload
      if (payload == 'N');
      {
      digitalWrite(m1, HIGH);
      digitalWrite(m2, LOW);
      delay(2000);
      digitalWrite(m1, LOW);
      digitalWrite(m1, LOW);
    }
          if (payload == 'F');
      {
      digitalWrite(m1, LOW);
      digitalWrite(m2, HIGH);
      delay(2000);
      digitalWrite(m1, LOW);
      digitalWrite(m1, LOW);
    }

    http.end();   //Close connection

    }

    delay(30000);    //Send a request every 30 seconds

    }

The above code not working but the below code working.

    #include <ESP8266WiFi.h>
    #include <ESP8266HTTPClient.h>

    const char* ssid = "KS Infotech";
    const char* password = "kalamsalam";
    String readc = "";
    void setup () {

    Serial.begin(9600);
    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED) {

    delay(1000);
    Serial.print("Connecting..");

    }

    }

    void loop() {
    while (Serial.available()){  //Check if there is an available byte to read
    delay(10); //Delay added to make thing stable
    char c = Serial.read();
    if (c == '#'){
      break;                   //Stop the loop once # is detected after a word
    }//Conduct a serial read
    readc += c; //build the string- "forward", "reverse", "left" and "right"
    }
    String T = String(readc);
        Serial.println(T);
    if (WiFi.status() == WL_CONNECTED) { //Check WiFi connection status

    HTTPClient http;  //Declare an object of class HTTPClient

    http.begin("http://ksinfotech.co/kslab/write_to_database.php?incoming="+T+"&UID=surya");  //Specify request destination
    int httpCode = http.GET();
     //Send the request

    if (httpCode > 0) { //Check the returning code

      String payload = http.getString();   //Get the request response payload
      Serial.println(payload);                     //Print the response payload

    }

    http.end();   //Close connection

    }

    delay(30000);    //Send a request every 30 seconds

    }

body:
use D5 and D6, not 5 and 6. D5 is IO 14, D6 is IO 12. IO 5 is D1 and IO 6 is SDIO_CLK for the flash memory and that is your problem.

[the reference][1]

  [1]: https://nodemcu.readthedocs.io/en/master/en/modules/gpio/


message:
Ethernet connection - how to send data from interrupt

I have question similar to old topic here https://arduino.stackexchange.com/questions/17357/any-way-to-pass-ethernetclient-to-function-outside-of-loop-automatically

I have in the main loop opening of the TCP server which is just maintaining the connection, but I need to send data from the interrupt rutine.

Can anybody tel me how to declare the connection globaly to be able to reference from event rutine and not from main loop only?

Thank you

body:
You don't, instead you set a volatile flag in the interrupt routine and/or append to a circular buffer and handle the actual sending the next time through in your main loop.

The time delay from deferring action from the ISR to the main loop code will be on the order of milliseconds, if that.