message:
Serial Monitor not properly interpreting data from my NodeMCU V3

I've just received several LoLin NodeMCUs from a 'cheap Chinese ebay vendor'.  They're working well except for the fact that I'm getting garbage in the Arduino IDE Serial monitor.

**I am able to:**

 1. Load and run sketches
 2. Use the NodeMCU as a webserver and
    connect to it from a computer/smartphone/etc
 3. Everything you else you would expect an ESP8266 to do EXCEPT

**I am not able to** get readable data to display in the Serial Monitor.

Some Details:
-My computer is running Linux Mint so I understand that drivers shouldn't be a problem

-The NodeMCU board has instructions printed on it to
           1) Install CH340G driver
           2) Use 9600 baud rate
           3) Connect to WiFi

-I **have not** tried issuing an AT command to slow the default baud rate down to 9600 (as suggested in answer to another question on this forum).  Since the NodeMCU standard rate is 115200 and it's only talking to my computer and not another Arduino, I didn't think that would be required.  {Could that be the answer to my problem?}

-I've tried all the standard baud rates between 9600 and 115200.  None produced readable outputs.

-I've connected stabilized external 5 and 3.3 V power sources to the board and added some caps for extra smoothing.

I'm running the simplest sketch I could think of to send data back the Arduino Serial Monitor:

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

    int LEDState = LOW;
    int pinNum = D7;  //LED on D7 will flash while loop is running

    void setup()
    {
      Serial.begin(15200);
      pinMode(pinNum, OUTPUT);
    }

    void loop()
    {
      digitalWrite(pinNum, HIGH);
      Serial.println("T");  // send the Letter T to the serial output
      for (int c = 0; c < 10; c++)
      {
        Serial.println(c); // send the count 0 to 9 to the serial output
        delay (200);
        LEDState = blinkLED(pinNum, LEDState); // blink the LED to demonstrate that the loop is running
      }
    }

    int blinkLED(int pinNum, int State)
    {
      if (State == LOW)
      {
        digitalWrite(pinNum, HIGH);
        State = HIGH;
      }
      else
      {
        digitalWrite(pinNum, LOW);
        State = LOW;
      }
      return State;
    }

---------
I've tried all the various line endings (CR/LF, CR, LF, nothing at all).  No success with any of them.

body:
That's not the simplest sketch to send serial data to Serial Monitor. Instead, try this:

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

    void loop(){
        delay(500);
        Serial.println("Hello World");
    }

Upload and open Serial Monitor at 9600 baudrate. Your AT firmware is already erased, never expect 'OK' response for 'AT' command. If Serial Monitor displays 'Hello World', then your board is okay. Then, you have to reflash AT firmware if needed.


sender: user

sender: assistant

body:
I seem to have found a solution to my own problem.  I poached a code snippet from another post on this forum (which I don't seem to be able to find now or I would happily give credit for) and inserted it into my sketch.  Works like a charm.

The code snippet resets the baud rate to 9600 within the program itself.  I upload the sketch at 115200 baud, but then switch to 9600 baud to talk to the Serial Monitor.

I've been running this code on the NodeMCU for 14 hours now and it's still going strong.

My next steps will be to insert this code into the rest of the Example Sketches that use the Serial Monitor and see if they all work on the NodeMCU V3 now.

    #include <SoftwareSerial.h>
    SoftwareSerial ESPserial(2, 3); // RX | TX

    int LEDState = LOW;
    int pinNum = D7;  //LED on D7 will flash while loop is running

    void setup() {
    //   ***  Additional Code that fixed my problem  ****
      Serial.begin(9600);
      ESPserial.begin(115200);
      ESPserial.println("AT+IPR=9600");
      delay(1000);

      // Start the software serial for communication with the ESP8266
      ESPserial.begin(9600);

      Serial.println("Ready");
      ESPserial.println("AT+GMR");

    // ***   End of additional code

      pinMode(pinNum,OUTPUT);

    }

    void loop() {
      digitalWrite(pinNum, HIGH);
      Serial.println("T");  // send the Letter T to the serial output
      for (int c = 0; c<10;c++)
      {
        Serial.println(c); // send the count 0 to 9 to the serial output
        delay (200);
        LEDState = blinkLED(pinNum, LEDState); // blink the LED to demonstrate that the loop is running

      }

    }

    int blinkLED(int pinNum, int State)
       {
          if (State == LOW)
            {
              digitalWrite(pinNum, HIGH);
              State = HIGH;
            }
            else
            {
              digitalWrite(pinNum,LOW);
              State = LOW;
            }
            return State;
       }


message:
Arduino Yun connection problems

I followed this [guide][1] and evertything works until I'm at chapter [Configuring the onboard WiFi][2].

I can see the arduino as an AP.

[![Arduino Yun Acces point][3]][3]

And I can connect with it. However when entering the IP adress *192.168.240.1* or *arduino.local* it does not give me the login page.
When using the IP adress I get: the site is not accessable screen. Using *arduino.local* gives me a page that loads forever for a long time before giving me the exact same result.

[![Page not loading][4]][4]

I have looked on different forums for a solution. [This one][5] said that I should download bonjour and bonjour browser because they use the same port (port 5353). After installing the bonjour browser I should be seeing a connection called .arduino._tcp but I don't see that. In fact I often can't see any connection what so ever.

[![Bonjour browser 1][6]][6]

and sometimes I can see a few connections but none of those are the arduino.

[![Bonjour browser 2][7]][7]

I have tried to ping with the arduino on the adress *192.168.240.1* but all I got was a time out.

    Pinging 192.168.240.1 with 32 bytes of data:
    Request timed out.

**Edit** : I managed to get the bonjour browser to work all the time, by installing itunes. It also shows the arduino.

[![enter image description here][8]][8]

  [1]: https://www.arduino.cc/en/Guide/ArduinoYun
  [2]: https://www.arduino.cc/en/Guide/ArduinoYun#toc16
  [3]: https://i.stack.imgur.com/ZLjKZ.png
  [4]: https://i.stack.imgur.com/L1RNK.png
  [5]: http://forum.arduino.cc/index.php?topic=188101.msg1554795#msg1554795
  [6]: https://i.stack.imgur.com/iPFMc.png
  [7]: https://i.stack.imgur.com/yUQKq.png
  [8]: https://i.stack.imgur.com/1qD6l.png

body:
 You have to find IP address of your Yùn on your local network.
What I do in this case:
- look on the Home router if you can see your Yùn and it's ip, or,
- there is a sketch in Arduino Ide / exemple / bridge / wifi status which can help you to get ip, or
-  open the Arduino Ide software, upload serialTerminal sketch and open serial monitor. It allows you to access the Linux part of the Yùn and type 'ifconfig' to get the IP from the Yùn.


message:
For loop not running

I've been trying to get a for loop to run 9 times using the below code but can't get the loop to run.

    void output() {
      int r;
      r = 1;
      Serial.println("Output");
      digitalWrite(Latch, LOW);
      for (int r=1; r >= 9;  r = r + 1) {
        Serial.println("Test");
        digitalWrite(DataOutput, Q[r]);
        digitalWrite(ClockPin, HIGH);
        digitalWrite(ClockPin, LOW);
      }
      Serial.println("Done For");
      digitalWrite(Latch, HIGH);
      digitalWrite(Latch, LOW);
    }

body:
Change

    for (int r=1; r >= 9;  r = r + 1) {

to

    for (int r=1; r <= 9;  r = r + 1) {

The for loop will only run while the second part is true.


body: The middle expression r => 9 in the for loop is wrong. This will only loop whilst r is greater than 9 and you are starting from r = 1. Change it to r <= 9.


message:
Are lambdas a good way to improve readability in this instance?

Disclaimer: The following code hasn't been compiled, and probably won't work in any way.  This is just for opinions relating to this [Arduino question](https://arduino.stackexchange.com/questions/47815/somevariable-somethingthatlookslikeafunction-possible/) as I'm still learning and experimenting with different coding techniques.

As I understand it (and please feel free to offer a (4.)), the following code could be written in numerous ways, including:

 1. No lambdas, and each following lambda as a separate function of its own.
 2. No lambdas, no external functions, and having it all flow within the same function.
 3. Using lambdas in a similar way to the code provided below.
 4. ?

As my programs are getting sizeable, I'm currently finding it difficult to keep track using (1.) and/or (2.) when writing programs, especially if bugs show up. This has led me to question if there was a way to reduce a great many `if` and `for` (etc) into a single, text-editor-foldable "_seed_" (i.e. a single variable).

In my original [question](https://arduino.stackexchange.com/questions/47815/somevariable-somethingthatlookslikeafunction-possible/) it was suggested that a possible way to do this could be option (3.) using lambdas.  However, it was also pointed out that it may be overkill/not practical, and without any examples of what I'm trying to achieve, it was difficult to make a more informed judgement. So with this in mind, I have thrown together an example showing how lambdas could help me achieve some readability to my code.

If this is an acceptable technique, or not, I would be extremely grateful for any advice.

Code, lambda example, unfolded:

    // Structs data, fans;
    void temperatures(int _temperaturePin) {

      data.cTemp = [](int _tPin) { // current temperature
        float _finalReading = 0.0f;
        for (int i = 0; i < temperatureResolution; i++) {
          float _currentReading = analogRead(_tPin);
          _finalReading += ( 10000 / ( ( 1023 / _currentReading ) - 1 ) );
        }
        _finalReading = (_finalReading / temperatureResolution);
        return (uint8_t)_finalReading;
      }(_temperaturePin);

      bool fanState = []( int rOne, int rTwo, int rThree ) { // fans on or off
        int _lowMin = data.tempTarget - ((data.tempTarget - data.tempMin) / 2);
        int _medMax = data.tempTarget + (( data.tempMax - data.tempTarget) / 2);
        bool _fanState = false;
        if (data.cTemp < data.minTemp) {
          digitalWrite(rOne, LOW);
          digitalWrite(rTwo, LOW);
          fans.off = !_fanState;
        } else {
          _fanState = true;
        }
        if ((data.cTemp > data.tempMin) && (data.cTemp > _lowMin)) {
          digitalWrite(rOne, LOW);
          digitalWrite(rTwo, HIGH);
          fans.low = _fanState;
        }
        if ((data.cTemp < data.tempTarget) && (data.cTemp < _medMax)) {
          digitalWrite(rOne, HIGH);
          digitalWrite(rThree, LOW);
          fans.medium = _fanState;
        }
        if (data.cTemp > data.tempMax) {
          digitalWrite(rOne, HIGH);
          digitalWrite(rThree, HIGH);
          fans.high = _fanState;
        }
        return _fanState;
      } (relayOne, relayTwo, relayThree);

      bool overloadProtection = [](bool _fState, int _lCount, int rCount) { // overload protection on or off
        bool _protect;
        int _pwmValue = 255;
        if (_fState) {
          _protect = ((_lCount > MAXLEDS) || ((_lCount > (MAXLEDS / 2) && (_rCount > MAXRELAYS) ))) ? true : false;
        }
        if (_protect) {
          for (int i = 0; i < _lCount; i++) {
            _pwmValue -= 10;
          }
        }
        for (int i = 0; i < _lCount; i++) {
          if (ledPins[i] == HIGH) {
            analogWrite(ledPins[i], _pwmValue);
          } else {
            digitalWrite(ledPins[i], LOW);
          }
        }
        return _protect;
      }(fanState, sizeof(ledPins), sizeof(relayPins);
    }

Code, lambda example, folded:

[![folded code][1]][1]

I can see that methods vs lambdas don't appear to make a huge difference to overall word count in this case, however, I can happily fold away `temperatures()` and know that's the root of everything I need for anything temperature related (without having to break off into another library; as far as I am aware), instead of having potentially 3 more functions sitting there and cluttering up screen space.

This also makes working within `temperatures()` a less daunting task than having potentially 100's of `for` and `if` (etc) statements permanently in view.

I'm only a hobbyist programmer at the moment, learning in my own time with no formal programming education, so I am 100% completely open to any suggestions or advice, especially due to ignorance regarding this subject on my part.

Much appreciated!

P.S. codereview.stackexchange requires working code to post there otherwise I would have.

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

body:
**Standard method using normal functions**

Quickly tell me, what does the `temperature()` function do?

    // Structs data, fans;
    void temperatures(int _temperaturePin)
    {
      data.cTemp = getTemperature(_temperaturePin);
      bool fanState = getFanState(relayOne, relayTwo, relayThree);
      bool overloadProtection = getOverloadProtecton(fanState, sizeof(ledPins), sizeof(relayPins);
    }

Well, it get the temperature, fan status and overload protection status. No need to know about lambdas, or even know C/C++: if you know *any* programming language (PHP, Javascript), you will able to understand what this code do.

Of course, `getTemperature` and others are implemented as traditional functions elsewhere. It's not important or relevant to know how they work, just what they do/return. I can write it in another source file and forget about them, never to be seen again.

**Lamba method**

Same question (with your original code), what does the `temperature()` function do?

       // Structs data, fans;

        void temperatures(int _temperaturePin) {

          data.cTemp = [](int _tPin) { // current temperature
            float _finalReading = 0.0f;
            for (int i = 0; i < temperatureResolution; i++) {
              float _currentReading = analogRead(_tPin);
              _finalReading += ( 10000 / ( ( 1023 / _currentReading ) - 1 ) );
            }
            _finalReading = (_finalReading / temperatureResolution);
            return (uint8_t)_finalReading;
          }(_temperaturePin);
    // More code ...

You have made one giant monolithic block of code, which is anatema by any standard. And code folding doesn't really solve that.

This not so easy to read. You have to scan searching for the each lambda end, taking mental notes about what is finally executing inside `temperatures()`. To much work, to much visual clutter, merging the *what to do* with the *how to do it*.

Think about testing. How do you test your lambdas? You can't do it easily. You need to extract the code from your application, to start with. And add all those external variables your are accessing from inside the lambda.

With traditional functions, no need to change your application to test your functions; just write a test program to exercise your code.

Think about code reuse. It's dificult with your code identify common code to refactor/reuse it.


body:
There is a reason, why the lambda concept was added to the C++ standard. This isn't it. This is called obfuscation.

    void temperatures(int pin)
    {
      // read the temperature with higher precision than single adc read:
      data.cTemp = 0.0f;
      for (int i = 0; i < temperatureResolution; i++) {
        data.cTemp += ( 10000 / ( ( 1023.0 / analogRead(pin) ) - 1 ) );
      }
      data.cTemp /= temperatureResolution;

Even this is a much better than misusing the lambda.

The main goal should be readability (= self docummented code), so anyone can quickly understand what is going on there.

That is also one of the reasons why the functions exists. The primary goal is you don't have to use the same snippets of code again and again (copy-paste). Try to fix the same bug on many places instead of one function.

In this code you should learn about concepts of finite state machines and ring buffers/floating averages, ...

Anyway, I've always hated parts of code in 10000 lines long file with only two methods or so. It's freaking hell to maintain that kind of code. Yes, having many tabs is also hard, but not harder than scrolling in mile long file. (I hate folding)


message:
SPI Temperature sensor interface with Arduino Uno

I want to interface with an [AD7314 Temperature Sensor][1]. I want to only read the temperature value from the sensor and output the value on to 8 LEDs connected to the Arduino. But so far I have not been able to read from the sensor. The datasheet says that the temperature readings are in 10 bit 2's complement, so I plan to convert to 8 bit before putting it out on the LEDs. Here is my code so far.

I am new to SPI and clearly don't understand the temperature sensor's datasheet. Please can anyone elaborate or explain where I am going wrong?

**Note: I have chosen pin A0 (PIN 23 of ATMEGA328P) as slave select and not pin 10**

    #include <SPI.h>

    byte val;

    void setup (void) {
      pinMode(0, OUTPUT); //LED 1
      pinMode(1, OUTPUT); //LED 2
      pinMode(5, OUTPUT); //LED 3
      pinMode(6, OUTPUT); //LED 4
      pinMode(7, OUTPUT); //LED 5
      pinMode(8, OUTPUT); //LED 6
      pinMode(9, OUTPUT); //LED 7
      pinMode(10, OUTPUT);//LED 8
      pinMode(11, OUTPUT); // MOSI
      pinMode(12, INPUT); //MISO
      pinMode(13, OUTPUT); //CLOCK PIN
      digitalWrite(A0, HIGH);  // ensure Slave select stays high
      SPI.begin ();
      Serial.begin(9600);
    } // end of setup

    void loop (void) {
      // enable Slave Select
      digitalWrite(A0, LOW); // enable communication with slave
      delay (0.425);// wait for conversion
      val = SPI.transfer(0x00);// read from sensor
      Serial.println(val); // display reading on serial monitor
      // disable Slave
      digitalWrite(A0, HIGH);
    }

  [1]: https://www.digikey.com/product-detail/en/analog-devices-inc/AD7314ARMZ-REEL7/AD7314ARMZ-REEL7CT-ND/3712422

body:
    delay (0.425);// wait for conversion

You can't delay a fraction of a millisecond. You can use delayMicroseconds though:

    delayMicroseconds(425);

However, you don't need to sleep at all.

> The conversion clock for the part is internally generated so no
external clock is required except when reading from and writing
to the serial port. In normal mode, an internal clock oscillator
runs the automatic conversion sequence. A conversion is initiated
every 400 ms. At this time, the part wakes up and performs
a temperature conversion. This temperature conversion typically
takes 25 ms, at which time the part automatically shuts down.
**The result of the most recent temperature conversion is available
in the serial output register at any time.**

You have your chip select pin backwards:

> To ensure that the serial port is reset properly
after power-up, the CE must be at a logic low before the
first serial port access. **The serial clock is active only when CE is
high.** For correct data synchronization, it is important that the
CE be low when the serial port is not being accessed

So it should start LOW, and be set HIGH before you read, and back to LOW afterwards.

You need to read 2 bytes, not one, then combine them in the right way to make a proper 8-bit value:

    digitalWrite(A0, HIGH);
    uint8_t b1 = SPI.transfer(0x00);
    uint8_t b2 = SPI.transfer(0x00);
    digitalWrite(A0, LOW);

    int8_t = (b1 << 1) | (b2 >> 7);

The reason for that is that the first bit of the first byte is a "leading zero" so you need to discard it, then add the first bit of the second byte as the last bit of your value, discarding the remainder of the second byte, since you specified only an 8-bit resolution in your question.


message:
Arduino LED flashes with one button press

I want the LED to flash when I press the switch once, but it keeps flashing. I tried the idea of just lighting the LED and keeping it lit with just one button press, so I wrote:

    int led=13,button=12;
    void setup() {
    pinMode(led,OUTPUT);
    pinMode(button,INPUT);
    }
    void loop() {
    if (digitalRead(button)==HIGH)
      digitalWrite(led,HIGH);
    }

and this worked; it stayed on after I pressed the button once, so for the flashing LED I wrote:

    int led=13,button=12;
    void setup() {
    pinMode(led,OUTPUT);
    pinMode(button,INPUT);
    }
    void loop() {
    if (digitalRead(button)==HIGH)
    {
      digitalWrite(led,HIGH);
    delay(1000);
     digitalWrite(led,LOW);
     delay(1000);

    } }

but this didn't work. It stops flashing after I remove my hand from the switch. Why is this happening?

body:
Because the digital writes only apply on `if (digitalRead(button)==HIGH)`. If you don't press the button, then the code goes:

    void loop() {
    }

Essentially doing nothing. Your code needs a bit more to keep track of the button press. Pseudo Code:

    if button == pressed {
        int tracker=1;
    }
    if tracker == 1 {
        led on;
        wait;
        led off;
        wait;
    }
    loop


body:
This is what you need. When you pressed the button then your LED turn ON. And it still ON until you pressed the button again.I hope it will help you.

    const int kPinBtn = 2;
    const int kPinLed = 13;

    boolean kPress = false;

    void setup()
    {
      pinMode(kPinBtn, INPUT_PULLUP);
      pinMode(kPinLed, OUTPUT);
    }

    void loop()
    {
      if(digitalRead(kPinBtn) == LOW && kPress == false)
      {
        digitalWrite(kPinLed, HIGH);
        kPress = true;
      }
      if(digitalRead(kPinBtn) == LOW && kPress == true)
      {
        digitalWrite(kPinLed, LOW);
        kPress = false;
      }
    }


message:
ATTiny85 Digispark clones failing USB handshake - how to program them?

I've recently bought a batch of ATTiny85 modules (Digispark clones) from China, and tried to write a first test program into them now. I noticed that they do seem to have some bootloader already installed since the P1 LED is flashing, but they do not seem to make any reasonable USB handshake.
(I have ordered other seemingly identical modules from a different seller on Ali before and was able to use them just fine.. so I generally know how to work with these.)

Linux dmesg shows me that a device was plugged in, but does not get any vendor or model ID. Windows tells me that 'the device last plugged in has failed enumeration'. This looks to me like the bootloader is incomplete or somehow broken.

So, as a next step, I tried to rewrite the AVR with an USBASP adapter over ISP, only to find out that the /reset pin apparently has been disabled via fuse bit.

I'm in some kind of a loop now... If the bootloader doesn't speak USB correctly, I can't use the Arduino IDE or avrdude or anything to write to it, and if the /reset is remapped I can't replace the bootloader via ISP to get USB working.

Can anyone provide a hint on how I can get these modules to work? Or should I just assume I bought a bad batch, throw them away and order fresh ones?

body:
I had problems too - SHORT: all about USB-hub or PC's root-hub and extension cables +Luck.

My ebay items were going under the name "Digispark Kickstarter ATTINY85 Arduino Micro USB Development Board" and naturally it came with no Digispark-(c)-right infringing markings from China. I kept my fingers crossed that my items would at least be AVRisp-programable..

So in high hopes I plugged in my China import into my trusty USB HUB2.0(which I always use at least as a current limiter) – after testing it first on a powerbank (>5secs blinky-blink)  .. checked for enumeration (which it did-but no driver yet) .. installed the DPinst[64].exe drivers.. and then kept getting messages like >>device failed to enumerate<<, etc. - the list of my failures:

* determined directly plugged into a PC's USB root-hub rigged/minimalistic usb devices do not enumerate at all (all 0s)

* with a certain USBAmale-to-USBAfemale extension cable with plastic-encasing(female side) the USBA device’s was not allowed to go "in" probably just for some millimeters to short.. the Data-lamella do not connect correct – just power's okay (blinky-blink) .. but no Windows device-recognition .. No-No!

* AND reminding the FTDI black-listing dilemma I used PCs without out the drivers still – using the good old “USBview.exe” program to check on the enumeration (on all my available device the same .. previously plugged into my driver-enable PC or just into an “out of the fab”-one

        idVendor:           0x16D0
        idProduct:          0x0753
        bcdDevice:          0x010B

so no mis-configuration of the bootloader through a >possibly mallign< Digispark clone dis-configurator (as I was thinking the FTDI schemes .. of course FTDI only did it to protect their name X-) – to stop getting accused for faulty devices coming from cheap chinese fake or clone-producers)
* EVEN tried to deinstall the Drivers with DPinst[64].exe /D .. which gave me .. Yes .. yet again “Drivers all installed properly!”..

.. and IN THE END .. I just went back to my old, initial “USB HUB-behind root-hub” configuration .. and *Abra-ca-Zang* .. the device just enumerated and registered as “Digispark Bootloader” (windows device manager under libusb-win32 Usb Devices)

and all went okay - reprogramming with the Arduino IDE - NO FUZZ!
.. The !very same! config I was using on my “first testings” (minus some fair time and headaches of debugging)

So my advice .. always do a Basic-Test on a USB Powerbank, USE an USB-Hub, check your cables - use ones you trusted before! – try as many options as you (may) have .. and use the tools at your hand .. down to PC-progs or an logic-analyzer or an Beagle USB / protocol analyer to check where the problem may be.. trace back your tracks and even retry..

There may be a suprise for you at the end of the rainbow!


body:
Using Arduino IDE 1.8, I had a *Windows did not recognize USB Device* message.

I successfully installed the DigiSpark drivers but still the PC was not recognizing the Tiny85 development board. In the Arduino IDE I had  *initially* selected the **DigiSpark (16.5 MHz default)** as instructed in a YouTube video. I did some more research,  someone suggested trying a different board. I selected the **DigiSpark (No USB 16 MHz)** uploaded the `Blink` example.

The LED started to flash and windows stopped complaining about the unrecognized device. I removed the flashed board and plugged in another, Windows started complaining, I uploaded the sketch successfully windows stopped complaining. I removed the second board and installed the first one and there were no further issues with Windows.


body:
Bootloader is poorly programmers it hand overs the overall hardware to user code,many people encounter error when uploading sketch second time.
Well i have solution though it may sound wears but it works for sure
"1.Disconnect board from USB ,
2.Hit upload button.,
3.Timout timer starts for 60 seconds.
4. Go ahead plug board to USB
5. CONGRATULATIONS"
thank me it will work...


message:
GUI interface with microcontroller to control a device through SPI

I am trying to develop a GUI to control a device hooked up on the Arduino. The Arduino communicates with the device through SPI. I have developed a GUI on MATLAB to visualize read by the Arduino. For this, I made Arduino write data from the MISO line to the serial port and MATLAB would read from the same port and do its magic. However, I am trying to come up with a method to write to the MOSI line using the GUI.

Right now I am thinking of making Arduino listen for a particular code (like a character) on the serial port and once it sees it, it will look for an x number of succeeding bytes. The bytes will be formatted in a particular way so that Arduino can then parse it and write to the appropriate registers.

Is there a better way to do this? As a generic question, what's a good way to write to a device hooked onto a microcontroller using I2C or SPI through a GUI?

body: SPI is a synchronized interface, it has master and slave. Either you need to switch between slave and master, or you need to provide a way to let Arduino start "reading" from the other end, since the one who initiates the communication in SPI or I2C is a master, in your case, Arduino, I suppose. The simplest way to do this is to provide another line via gpio. As for generic question, to do two-way communication properly, you probably want to choose asynchronous protocol like UART.


body:
I had a similar requirement and came up with [Wirekite](https://github.com/manuelbl/Wirekite/wiki). It is a complete solution based on a [Teensy](https://github.com/manuelbl/Wirekite/wiki) board, some code for it plus libraries for Mac or PC.

With Wirekite, you can hook up digital and analog inputs and outputs, I2C devices and SPI devices (very soon) to the Teensy board and connect the Teensy board via USB to your Mac or PC. You can then control the I/Os, I2C and SPI buses from you Mac or PC. You don't need to adapt the code on the Teensy.

Wirekite uses a custom protocol for the communication. But you don't need to care about that because you can simply use the far more convenient API provided by the Wirekite libraries (.NET for Windows, Objective-C/Swift for MacOS).


body: If you want to communicate from the computer to the arduino, use USART. Arduino already has this pre-programmed, as well it's own GUI.


body:
I grappled with the same question for a while. Here is how I solved the issue.

**1- Find a suitable exchange format and protocol**

Here you need to decide what is the most important thing on the communication. Is it speed? Is it error detection? Is it memory footprint? For my project, for instance, I decided that I need my communication to be as error free as possible, with minimal memory footprint (up to 64 bytes) and I don't really care about speed, so I gone for a JSON messaging protocol where the desktop application send a short (up to 64 characters) JSON message and receives a short answer. This solved **MY** problem, your requirements might be different. If you need speed and don't care for memory, for instance, you can use a binary protocol with a header specifing size, the message and a CRC footer to check vailidity. Or you can use BSON and take [this][1] library to avoid the hassle.

**2- Define the Serial Polling Cycle**
How will the arduino firmware knows it is time to send or receive messages? It is always talking? Always ready to receive? It looks at the serial port buffer once each few microsseconds to know if there is an incomming message? How that is handled by your device? If you just need to output data without bothering whether there is someone listening or not, like an GPS device, just throw a `Serial.print` now and then, but if you need to wait for data, you will have to compartimentalize the process inside an FSM or using some kind of scheduler. If you are not using a scheduler, I recommend [this one][2].

**3- Define the Communication Cycle**
Here you will take the data from serial port and storing it on a buffer for later usage.
The trick here is
1- Check the serial FIFO for incomming data. `Serial.available()` does it already.
2- If there is incomming data, copy the data to next available space in the buffer.
3- Check if there is more incomming data after a few millisseconds.
4- If there is no incomming data, mark the buffer as ready to use, and parse it.

The following code is unscheduled for simplicity,and I recommend you to replace the `sleep()` calls to proper scheduling least you want the arduino go unresponsive. It is also waiting text data, so you will need to make changes if you are waiting binary data.

      char buffer[64];
      memset(buffer, 0, 64);

      while (!Serial.available())
        delay(50);

      while (Serial.available()){
        Serial.readBytes(buffer + strlen(buffer), Serial.available());
        delay(50);
      }
      parseBuffer(buffer);

  [1]: https://github.com/argandas/ardubson
  [2]: https://github.com/Elidio/StateMachine


message:
Using a keypad to play an audio file on Arduino Mega and Adafruit VS1053?

I am trying to use a keypad to trigger an audio file using an Arduino Mega and Adafruit VS1053 Music Maker. I have gotten the music files to play independently, and when the correct number is entered into the keypad a red LED flashes to green, but I have no idea how to make the music file play as a result of my combination.

What works is that the music file plays, but the problem is that it plays automatically and not upon a combination input.

I have tried putting `musicPlayer.playfullfile("track002.mp3")` in the loop with an `if` statement, and when I press the keypad the serial reader tells me it is playing the music file, but nothing is actually playing :

    char key = keypad.getKey();
    if (key) {
        Serial.println(key);
        if (key =='9') {
            playMusic("track001.mp3");
        }
    }

I've done experiments with `playmusic` outside of the loop and it works fine and finds the file no problem. So the problem occurs when I try and put it into the loop as part of a keypad combination, it returns immediately without playing.

This is from the Serial reader
>Playing music file 9
>Playing music file 9
>Playing music file 9
>Playing music file

Any help would be tremendously appreciated.

My full code is below:

    #include <Keypad.h>
    #include <SD.h>
    #define SD_ChipSelectPin 53
    #include <SPI.h>
    #include <Adafruit_VS1053.h>

    String password = "123";
    String answer = "";
    int position = 0;
    const byte ROWS = 4;
    const byte COLS = 4;
    char keys[ROWS][COLS] = {
      {'1','2','3','A'},
      {'4','5','6','B'},
      {'7','8','9','C'},
      {'*','0','#','D'}
    };

    byte rowPins[ROWS] = { 51, 49, 47, 53 };
    byte colPins[COLS] = { 45, 43, 41, 39 };
    Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS,
    COLS );
    int R = 27; // 3rd yellow wire in GROUND
    int G = 29;

    // define the pins used
    //#define CLK 13       // SPI Clock, shared with SD card
    //#define MISO 12      // Input data, from VS1053/SD card
    //#define MOSI 11      // Output data, to VS1053/SD card
    // Connect CLK, MISO and MOSI to hardware SPI pins.
    // See http://arduino.cc/en/Reference/SPI "Connections"

    // These are the pins used for the breakout example
    #define BREAKOUT_RESET  9      // VS1053 reset pin (output)
    #define BREAKOUT_CS     10     // VS1053 chip select pin (output)
    #define BREAKOUT_DCS    8      // VS1053 Data/command select pin
    (output)
    // These are the pins used for the music maker shield
    #define SHIELD_RESET  -1      // VS1053 reset pin (unused!)
    #define SHIELD_CS     7      // VS1053 chip select pin (output)
    #define SHIELD_DCS    6      // VS1053 Data/command select pin
    (output)

    // These are common pins between breakout and shield
    #define CARDCS 4     // Card chip select pin
    // DREQ should be an Int pin, see
    http://arduino.cc/en/Reference/attachInterrupt
    #define DREQ 3       // VS1053 Data request, ideally an Interrupt pin

    Adafruit_VS1053_FilePlayer musicPlayer =
      // create breakout-example object!
      //Adafruit_VS1053_FilePlayer(BREAKOUT_RESET, BREAKOUT_CS,
    BREAKOUT_DCS,
    DREQ, CARDCS);
    // create shield-example object!
    Adafruit_VS1053_FilePlayer(SHIELD_RESET, SHIELD_CS, SHIELD_DCS, DREQ, CARDCS);

    void setup() {
      if (! musicPlayer.begin()) {
        // initialise the music player
        Serial.println(F("Couldn't find VS1053, do you have the right pins defined?"));
        while (1);
      }
      Serial.println(F("VS1053 found"));
      if (!SD.begin(CARDCS)) {
        Serial.println(F("SD failed, or not present"));
        while (1);  // don't do anything more
        // Set volume for left, right channels. lower numbers == louder volume!
        musicPlayer.setVolume(20,20);
        pinMode(R, OUTPUT);
        pinMode(G, OUTPUT);
      }
      musicPlayer.playFullFile("track003.mp3");
    }

    void loop() {
      char key = keypad.getKey(); // init. variable key keypad is non blocking
      while(key == NO_KEY) {
        // we got no key press? -> do again
        key = keypad.getKey();
        delay(100);
      }
      answer.concat(key); //add key to answer
      if(answer.equals(password)) {
        //password OK
        musicPlayer.playFullFile("track002.mp3");
        Serial.println(F("Playing track 001"));
        LockedPosition(false);
        answer="";
      } else {
        LockedPosition(true);
      }
      if (answer.length() > password.length()) {
        // answer is different and bigger than password
        // can't become the right answer
        answer = "";
      }
      if (key == '*' || key == '#') {
        LockedPosition(true);
        answer="";
      }
    }

    void LockedPosition(int locked) {
      if (locked) {
        digitalWrite(R, HIGH);
        digitalWrite(G, LOW);
      } else {
        digitalWrite(R, LOW);
        digitalWrite(G, HIGH);
        delay(10000);
        digitalWrite(G,LOW);
      }
    }

body:
The sketch has a pins conflict.

SD card is on SPI bus. SPI pins on Arduino Mega are pins 50, 51, 52 and 53. These pins are available on the ICSP/SPI header too. Mega compatible shields use the SPI pins on the ICSP header. Pin 53 must be set as output if the Mega is SPI master and is usual to use it as CS pin for a slave.

According to sketch the SD CS pin is 53.

According to sketch the keypad uses pins 51 and 53. 51 is SPI pin used by the shield and pin 53 is CS pin for SD card.


message:
Measuring frequency of 3-wire 12V fan on Arduino Uno

I am using a PC 12V fan (40x40mm), which I control speed with voltage (with adjustable power supply). I would like to measure the frequency of the fan with Arduino and read it on serial monitor.

I've googled over some results and I came across `pulseIn()`, which I don't quite understand. I've also used this code, which I found [here][1], but it doesn't work for me. I've added `serial.print` and delay line.

My output of this program is: "0000000" etc. and nothing else.

My goal is to set the frequency of the fan to around 50-500 Hz somewhere.

    int pin = 7;
    unsigned long duration;

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

    void loop()
    {
      duration = pulseIn(pin, HIGH);
      Serial.print(duration);
      delay(1);
    }

My schematics:

[![enter image description here][2]][2]

  [1]: https://www.arduino.cc/en/Serial/Print
  [2]: https://i.stack.imgur.com/3vesi.png

body:
The `pulseIn` measures the duration of a high pulse on the pin.  The [reference page][1] explains it as well as I ever could.  If there is a specific thing you don't understand from it, please ask.  However, I don't think it will achieve what you want.

The circuitry in the fan connects the third (yellow?) wire to ground twice per revolution of the fan.  To make this into a "pulse" you need to pull the pin high.  Twice per revolution, the fan will pull it low.

What you now have is a signal which, for every revolution of the fan, goes `HIGH`, `LOW`, `HIGH`, `LOW`.  We want to measure the time from one rising edge to the next.  This is the time for half a rotation of the fan.

Here's some untested code:

    // Wait for signal to go low
    while (HIGH==digitalRead(pin)) { /* Do nothing */ }

    // Start timing
    unsigned long start_time = micros();

    // Wait for signal to go high and low again
    while (LOW==digitalRead(pin)) { /* Do nothing */ }
    while (HIGH==digitalRead(pin)) { /* Do nothing */ }

    // Stop timing
    unsigned long end_time = micros();

    // How long did that take?
    unsigned long duration  = end_time - start_time;

That code can be improved in various ways but I hope it will let you understand what's going on.

That tells us how LONG half a cycle takes.  You can easily find how long a whole cycle would take -- double it.  If you want the frequency in revolutions-per-minute, you need to work out how many whole cycles you can get in a minute, which is the same as the number of half-cycles in half a minute:

    unsigned long rpm = 30000000L / duration;

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


message:
Reading input from digital pins 36, 37, 38 in Arduino Mega 2560 is giving a problem

I wrote a program to read digital input from pins 36, 37, 38 and print on LCD when they go HIGH.
I've connected those pins to a switch to test.

The program looks like this:

    #include "LiquidCrystal.h"

    // initialize the library by providing the nuber of pins to it
    LiquidCrystal lcd(8,9,4,5,6,7);
    int vswr,th,od,a;

    void setup() {
      pinMode(36,INPUT);//SENSING VSWR
      pinMode(37,INPUT);//SENSING THERMAL
      pinMode(38,INPUT);//SENSING OVER DRIVE
      pinMode(35,OUTPUT);//BYTE_CTRL SIGNAL TO SHUTDOWN
      digitalWrite(35,LOW);
    }

    void loop() {
      vswr = digitalRead(36);
      th= digitalRead(37);
      od = digitalRead(38);
      lcd.begin(16,2);
      // set cursor position to start of first line on the LCD
      lcd.setCursor(0,0);
      if (vswr==1) {
        lcd.write("vswr");
        digitalWrite(35,HIGH);
        delay(2000);
      }
      if (th==1) {
        lcd.write("thermal");
        digitalWrite(35,HIGH);
        delay(2000);
      }
      if (od==1) {
        lcd.write("over drive");
        digitalWrite(35,HIGH);
        delay(2000);
      }
    }

When I run this, the LCD continuously  displays:**

> vswrthermaloverdrive

Even though none of the pins are high.

When I use Pins 11, 12, 13 instead of 36, 37, 38 it works fine. I already used pins 11,12,13 for some other purpose. Why is this happening? And how do I solve this problem?

body:
I expect the problem is in the circuit. To be sure, put a serial print statement directly after reading the inputs, to be sure the input values are read correctly.

See the remark of using INPUT or INPUT_PULLUP from Jot below.

The following is just a more compact way of writing your loop (and does not fix your problem):

    void process(int pin, char* text)
    {
        if (digitalRead(pin) == HIGH) // Use HIGH instead of 1
        {
           lcd.write(text);
           digitalWrite(35, HIGH);
           delay(2000);
        }
    }

    void loop()
    {
        lcd.begin(16,2);
        // set cursor position to start of first line on the LCD
        lcd.setCursor(0,0);

        process(36, "vswr");
        process(37, "thermal");
        process(38, "overdrive");
    }

Also, I would add the delay at the end (after the three calls of process).
And instead of hard coded values 36, 37 and 38 use 3 constants/defines.


body:
Another thing, only pin == HIGH writes something to the LCD, the message does not magically go away when pin == LOW

Also, about the logic for pin 35, what should happen when alarm goes away?
Maybe pin 35 should be low again?

Code suggestion:

    void process(int pin, char* text)
    {
        if (digitalRead(pin) == HIGH) // Use HIGH instead of 1
        {
           lcd.write(text);
           digitalWrite(35, HIGH);
        }
        else
        {
           lcd.write("      ");
        }
    }


message:
Multiple I2C devices on Arduino

I'm design a custom PCB based around the Arduino Zero/Adafruit Feather M0. The plan is to use a few I2C devices. I just had a few questions about whether I've designed the board correctly.

You'll see that I've used 10k resistors on each devices's SDA and SCL lines, but is this necessary? I've seen it mentioned on a few online documents for certain breakout boards etc...

Also, are the devices just connected in parallel? Are there any considerations I need to make when using 3 I2C devices like this?

[![Circuit Schematic][1]][1]

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

body:
> You'll see that I've used 10k resistors on each devices's SDA and SCL lines, but is this necessary? I've seen it mentioned on a few online documents for certain breakout boards etc...

You should have just two 3.3K resistors - one on the SDA and one on the SCL lines.  However all your 10K resistors in parallel will equate to about the same thing - just taking up 3x the space.

> Also, are the devices just connected in parallel?

Yes, it's a simple multi-drop bus.

> Are there any considerations I need to make when using 3 I2C devices like this?

Not really, no.  The frequencies in use are generally too low to require any specific layout considerations. Just try to keep vias to a minimum and don't snake the traces around the board too far.


message:
How can I write an integer to a Mifare RFID card using the RFID library?

I'm a beginner to C++ and I'm clearly missing some fundamental knowledge of data types. As such, I'm struggling to adapt the examples in the [miguelbalboa/rfid][1] library to my use case. I'm simply trying to write an integer to a 13.56Mhz RFID tag. Ideally I'd like to optimize the data so as to be quick to read (it seems fully reading these cards can take a while and I'd like to read the integer, an ID, as quickly as possible).

So on to my actual questions... what is the data type shown in [this block of example code][2] (shown below) and how can I turn an integer into the same data type? Finally, how should I read this saved value back into the familiar integer data type?

    byte dataBlock[]    = {
        0x01, 0x02, 0x03, 0x04, //  1,  2,   3,  4,
        0x05, 0x06, 0x07, 0x08, //  5,  6,   7,  8,
        0x09, 0x0a, 0xff, 0x0b, //  9, 10, 255, 11,
        0x0c, 0x0d, 0x0e, 0x0f  // 12, 13, 14, 15
    };

  [1]: https://github.com/miguelbalboa/rfid
  [2]: https://github.com/miguelbalboa/rfid/blob/master/examples/ReadAndWrite/ReadAndWrite.ino#L91-L100

body:
The `dataBlock[]` variable is an array of bytes. One byte can represent an integer ranging from -128 to 127, or a positive integer ranging from 0 to 255. If your integer value will always be in one of those ranges, then you can just put your integer in the first element of the array and zero out the remaining.

    byte dataBlock[]    = {
        0x01, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00
    };

(That saves a value of 1 to the first element, and zeros to the rest. If you want to change the first element:

    dataBlock[0] = yourValue;

If your integer is a 2-byte integer, as is typically found in Arduino with type `int`, you need to split your value into the high byte and low byte:

    dataBlock[0] = (byte)(yourValue & 0xFF); // Low byte
    dataBlock[1] = (byte)(yourValue >> 8);   // High byte

Then you write the data block as per the example. To get your 2-byte integer value back:

    yourValue = ((int)dataBlock[1])<<8 | dataBlock[0];  // Shift high byte, OR with low byte.


body:
Well, the example is using the `MIFARE_Write` and `MIFARE_Read` functions. These functions, as explained in the library, accept at least 16 bytes, so the 16-bytes buffer is the smallest you can read/write. Consequently I suggest you, if you don't have any additional data, to use 16-bytes IDs (you get a much wider code space).

If you strictly want to use 2 or 4-bytes integers, the first solution which comes to my mind is jose's one, so manually split the int in two (or the long in four) bytes and store them in the array. For instance

    // Big endian format
    dataBlock[idx]   = (byte)(intValue >> 8); // Byte 1
    dataBlock[idx+1] = (byte)(intValue);      // Byte 0
    // or
    dataBlock[idx]   = (byte)(longValue >> 24); // Byte 3
    dataBlock[idx+1] = (byte)(longValue >> 16); // Byte 2
    dataBlock[idx+2] = (byte)(longValue >> 8);  // Byte 1
    dataBlock[idx+3] = (byte)(longValue);       // Byte 0

    // Little endian format
    dataBlock[idx]   = (byte)(intValue);      // Byte 0
    dataBlock[idx+1] = (byte)(intValue >> 8); // Byte 1
    // or
    dataBlock[idx]   = (byte)(longValue);       // Byte 0
    dataBlock[idx+1] = (byte)(longValue >> 8);  // Byte 1
    dataBlock[idx+2] = (byte)(longValue >> 16); // Byte 2
    dataBlock[idx+3] = (byte)(longValue >> 24); // Byte 3

NOTE: `idx` can be any value; the easiest approach is to put the int at the beginning (so substitute `idx` with 0)
This is the safest way to handle this, since the endianness is explicit. You can, however, trust the compiler and use its implicit handling of multi-byte variables in this way:

    *((int*)(&datablock[idx])) = intValue;
    // or
    *((long*)(&datablock[idx])) = longValue;

You take the cell where you want to put the beginning of the data, get its pointer, cast it to the pointer type you need, then write inside that pointer the value you want. Please note, however, that cells idx and idx+1 in the case of an int, or idx to idx+3 for long, will be written. If your array ends, you will pollute the memory in unpredictible ways (just like if you write `dataBlock[18] = something` when dataBlock has 16 cells).

Note you cannot control the endianness of the byte array, but if you always use the same device to read and write you should not worry. FYI, at present the compiler used by Arduino IDE is little endian.

Note also that, for `idx = 0`, `(&datablock[idx])` can be simplified in `(datablock)`.

To read back the data, you have the following ways

    // Big endian format
    intValue = (((int)dataBlock[idx]) << 8) | dataBlock[idx+1];
    // or
    longValue = (((long)dataBlock[idx]) << 24) | (((long)dataBlock[idx+1]) << 16) | (((long)dataBlock[idx+2]) << 8) | dataBlock[idx+3];

    // Little endian format
    intValue = (((int)dataBlock[idx+1]) << 8) | dataBlock[idx];
    // or
    longValue = (((long)dataBlock[idx+3]) << 24) | (((long)dataBlock[idx+2]) << 16) | (((long)dataBlock[idx+1]) << 8) | dataBlock[idx];

Or, in the last case,

    intValue = *((int*)(&datablock[idx]));
    // or
    longValue = *((long*)(&datablock[idx]));


message:
Can I code in Arduino depending up on LED status?

I have to count the blinkings of an LED. For that

    IF (LED = ON)
    {
        COUNT=COUNT++
    }
    Else
    {
    }

Can I code like this algorithm? In Arduino is it possible?

body:
Yes, you can make an arduino detect and count LED blinking. You will need some kind of light sensor, such as a [photodiode][1] or [photoresistor][2].

Also, you would need to code in C++, and the example pseudo-code you presented is not C or C++.

As you proceed with your project, you may ask more questions here, of a more specific nature. As it stands, your question is very broad.

  [1]: https://en.wikipedia.org/wiki/Photodiode
  [2]: https://en.wikipedia.org/wiki/Photoresistor


message:
16*2 1602A LCD not displaying any character or contrast, although correct wiring

I've used my LCD display with a lot of small projects. Now it doesn't work anymore. Most of the diagrams you find online use resistors and potentiometers. However I never done that, but still got it to work nonetheless.

I tried different schematics, but none of them seem to work. So I'm thinking I broke my LCD somehow.

I'm pretty sure the [schematic I'm currently using][1] works. The backlight works but nothing is being printed.

[Pictures][2] of the project (Warning!! wire hell)

The LCD component is a blue 16x2 1602A v2.0 display.
All the components come from the official Arduino starter kit, except for the wires. Though I tested every single wire for continuity, to make absolutely sure the problem was not within the wires themselves.
Also, turning the potentiometer doesn't show any blocks, or change anything on the LCD as expected.

Code:

    #include <LiquidCrystal.h>
    //LiquidCrystal lcd(RS, E, D4, D5, D6, D7);
    LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

    void setup() {
      pinMode(6,OUTPUT);
      analogWrite(6,90); //sweetspot for backlight without using a potentiometer.

      lcd.begin(16, 2);
      //lcd.setCursor(0,0);
      lcd.print("hello, world!");
    }

    void loop() {
    }

I'm not sure what's wrong, I tested everything I can think off.

*I can upload more (cleaner) pictures if requested, I just didn't want to tear down my other project.*

  [1]: https://i.stack.imgur.com/Hgpl8.png
  [2]: https://i.stack.imgur.com/hgy2Z.jpg

body:
I have an suggestion.  Try removing the comment from this line:  `//lcd.setCursor(0,0);`

You need to be sure your text is displaying on the first line, first position(0,0).


body:
The LCD is working perfectly fine (hardware side).

Only 2 changes require in your code.

    #include <LiquidCrystal.h>
    LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

    void setup() {
      pinMode(6,OUTPUT);
      analogWrite(6,90); //sweetspot for backlight without using a potentiometer.

      lcd.begin(16, 2);
      lcd.setCursor(0,0);
      lcd.print("hello, world!");
      delay(3000);
    }

    void loop() {
    }

Added delay (it must!) and set the cursor position.

Try above code and let inform.


body:
Ok so the problem were the wires.
Although I tested every single wire for continuity I went to the store and bought a brand new (expensive/not-from-aliexpress) pack of jumper wires. I rewired the entire project with the schematic and code that was posted in my question-post and it worked like a charm..

So I'm not sure what exactly caused the problem, but it was in the wire. I thought having continuity in a wire is like a 100% proof that the wire works properly. Maybe someone has an idea what could cause this?

So again, I only replaced the wires, not the schematic nor the code, with brand new ones and it worked perfectly.


body:
(This is a [duplicate][1]).

I solved it following this:

> The contrast can be adjusted by the potential-meter displayed in the following picture.

[![enter image description here][2]][2]

[credit][3]

  [1]: https://arduino.stackexchange.com/questions/6632/determining-contrast-on-lcd/58430#58430
  [2]: https://i.stack.imgur.com/BHoOm.png
  [3]: https://www.dfrobot.com/wiki/index.php/I2C/TWI_LCD1602_Module_(SKU:_DFR0063)


message:
Using a Micro SD card for data logging, bad idea? Reliable?

I'm planning a project that will read data from an I/O board.
The micro SD card would hold data for input bit identity, labeling ?, then logging after events end.

Nothing would be written to or read from the micro sd, unless an event takes place, usually 2-10 events/hour. System will run 24/7 for years, hopefully.
Is a micro sd card the best way?  Is it reliable enough?

body:
As far as durability concern, SD cards are quite durable.

8-10 years data storage and operations would be OKAY. In a practical scenario, average time is about to 5-6 years.

Just you have to keep some important and necessary instructions/cautions keep in mind while dealing with SD card and for its long life.

Importantly, use standard standard manufacture SD card (suggestion - Swissbit)

 - Don't store them below -40 °C or above +70 °C
 - Don't pressurized

Here are a few links, which may help you.

https://superuser.com/questions/17350/whats-the-life-expectancy-of-an-sd-card

SD cards generally have wear leveling (https://en.wikipedia.org/wiki/Wear_leveling)

Hope, this will helpful.


body:
We've been maintaining a network of loggers (60+ currently deployed) using SD card connected directly to the SPI pins (see: http://www.mdpi.com/1424-8220/18/2/530 for details) and our experience is that the SD cards are really reliable provided you don't have a brown-out when they are writing, even when we abuse them with hot surface deployments in the tropical sun. And we buy them used, (since the older, smaller Nokia & Sandisk cards have lower sleep currents) but test them well with H2testw.
 However there is one problem that develops over time: the actual SD adapters are not made that well, and tend to have solder flux residue left on the little pads used to hold the contact springs, and these will corrode over time if moisture gets in. I give everything a sonic bath in 90% isopropyl until the parts are squeaky clean, and then always put 2x10gram desiccant packs into the logger housings (with color indicator beads). If you are careful about the cleaning, the contacts last for years, but if you forget, and moisture gets into the housing, then the SD card contact spring solder points are often the first things to corrode.


message:
Lost AT+ commands on ESP8266 after flashing with "blink" sketch

I set my ESP8266 ESP-01 to flash mode and uploaded the example blink sketch on the arduino IDE esp example options. I know can no longer communicate with the ESP8266 using AT+ commands. I also cannot flash the device and can only receive the following message under baud 74880

"
 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1264, room 16
tail 0
chksum 0x0f
csum 0x0f
~ld
"

Anyone know how to fix this? Thanks.

body:
on Windows use [Espressif Flash Download Tool][1] to flash the [AT firmware][2]. Everything is on Espressif's site

  [1]: http://espressif.com/en/support/download/other-tools
  [2]: http://espressif.com/en/support/download/at?keys=&field_type_tid[]=14


body:
Thank you Juraj!

I had attempted to update the firmware multiple times and after 6hrs of trying was giving up. I really thought I had trashed my ESP-01. My post here was my last attempt to resolve the issue. I tend to have a problem of not asking for help until I'm frustrated. I saw your comment, and even though I had already attempted to reflash with new firmware I realized that you knew something I did not, and hopefully I could still salvage the ESP-01. So I downloaded documents about the esp8266 and decided to give it another try. What I found is my ignorance had let me believe that the esp-01 was broken when it was functioning as it should. Anytime you upload new firmware it will replace the old (including the at commands, but that's what it suppose to do). I then found this page that brought to my attention the mistake I was making. I was flashing the files to the wrong address, and there are multiple locations where the "blank" file needs to be flashed to.     So all is back to normal. At commands have returned. Now I have to remove them again to upload my program :).

https://www.allaboutcircuits.com/projects/flashing-the-ESP-01-firmware-to-SDK-v2.0.0-is-easier-now

I almost forgot to mention, I also had to hard wire my GPIO0 pin to ground before flashing. I was originally pulling GPIO0 to ground with a button. However, even though the serial console showed that I had booted in flash mode the flash tool failed. Only after hardwiring the GPIO0 to ground would the flash tool work.


message:
Receive data using ESP8266

I have connected ESP8266 to my Raspberry Pi's WiFi network and assigned a static IP.

My Arduino code

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

    #include "SoftwareSerial.h"

    String ssid = "Rpi";
    String password = "raspberry";

    SoftwareSerial esp(3, 2);// RX, TX

    String server = "192.168.50.1"; //my Host

    void setup() {
      esp.begin(115200);
      Serial.begin(115200);
      connectWifi();
      httpget();
      delay(1000);
    }

    void connectWifi() {
      String cmd = "AT+CWJAP=\"" + ssid + "\",\"" + password + "\"";
      esp.println(cmd);
      delay(4000);
      if (esp.find("OK")) {
        Serial.println("Connected!");
      }
      else {
        Serial.println("Cannot connect to wifi ! Connecting again...");
      }
      connectWifi();
    }

    /////////////////////////////GET METHOD///////////////////////////////
    void httpget() {
      esp.println("AT+CIPSTART=\"TCP\",\"" + server + "\",1234");//start a TCP connection.
      if ( esp.find("OK")) {
        Serial.println("TCP connection ready");
      }
      delay(1000);
      /*
        String getRequest =
        "GET " + uri + " HTTP/1.0\r\n" +
        "Host: " + server + "\r\n" +
        "Accept: *" + "/" + "*\r\n" +
        "Content-Type: application/json\r\n" +
        "\r\n";
      */
      String sendCmd = "AT+CIPSEND=";
      esp.print(sendCmd);
      //esp.println(getRequest.length() );
      delay(500);
      if (esp.find(">")) {
        Serial.println("Sending..");
        //  esp.print(getRequest);
        if ( esp.find("SEND OK")) {
          Serial.println("Packet sent");
          while (esp.available()) {
            String response = esp.readString();
          }
          esp.println("AT+CIPCLOSE");
        }
      }
    }

    void loop() {
      httpget();
    }

I get this message

>>Cannot connect to wifi ! Connecting again...

In my Raspberry Pi I am constantly sending a signal to this IP address.

    import socket

    TCP_IP = '192.168.50.1' #Local Host
    TCP_PORT = 1234            #Listening Port
    BUFFER_SIZE = 12

    SERVER_IP = '192.168.50.18'  #Arduino IP
    SERVER_PORT = 3007            #Server Port

    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.bind((TCP_IP,TCP_PORT))
    #s.listen(1)

    #(conn,addr) = s.accept()
    #print 'Connection address: ',addr
    while True:
        print 'Sending message'
        s.sendto('1',(SERVER_IP,SERVER_PORT))
        print 'Waiting for response'
        data,addr = s.recvfrom(BUFFER_SIZE)
        if not data: break
        print 'received data: ',data
        print 'data recieved from: ',addr
        conn.close()
    s.close()

But I can not see it in my Serial Monitor. Do I need to create a separate program for getting from WiFi?

body:
You are recursively calling `connectWifi()` and therefore your setup function results in an infinite loop.
You must not implement loops and for processes, which take some time, you should set and ask a flag.
Btw. why don't you use the official ESP WiFi library?


message:
ESP8266 returning 400 bad request

I am trying to get JSON data from my website using an HTTP GET request, but I'm getting a 400 bad request error. Can someone let me know why am I getting this error and how to fix that? I am tired of looking at online resources.

I am trying to fetch data from www.himalayavats.com/to_fetch/system_info.json

I am using this code:

    #include <SoftwareSerial.h>

    const byte rxPin = 2;
    const byte txPin = 3;

    SoftwareSerial ESP8266 (rxPin, txPin);

    unsigned long lastTimeMillis = 0;

    void setup() {
      sendData("AT+RST\r\n",1000, true);
      Serial.begin(9600);
      ESP8266.begin(9600);
      delay(2000);
      connectToWifi();
    }

    void connectToWifi() {
      String ssid = "moto g";
      String pass = "hvats555";
      sendData("AT+CWMODE=1\r\n", 3000, true); // Configure as client
      sendData("AT+CWJAP=\"moto g\",\"hvats555\"\r\n", 5000, true);  // Connects to wifi
    }

    String sendData(String command, const int timeout, boolean debug) {
      String response = "";
      ESP8266.print(command); // send the read character to ESP8266
      long int time = millis();
      while( (time+timeout) > millis() ) {
        while(ESP8266.available()) {
          // The ESP has data so display its output to serial window
          char c = ESP8266.read(); // read the next character
          response+=c;
        }
      }
      if(debug) {
        Serial.print(response);
      }
      return response;
    }

    void printResponse() {
      while (ESP8266.available()) {
        Serial.println(ESP8266.readStringUntil('\n'));
      }
    }

    void loop() {
      if (millis() - lastTimeMillis > 30000) {
        lastTimeMillis = millis();
        ESP8266.println("AT+CIPMUX=1");
        delay(1000);
        printResponse();
        ESP8266.println("AT+CIPSTART=4,\"TCP\",\"himalayavats.com\", 80");
        delay(1000);
        printResponse();
        String cmd = "GET /to_fetch/system_info.json HTTP/1.1";
        ESP8266.println("AT+CIPSEND=4," + String(cmd.length() + 4));
        delay(1000);
        ESP8266.println(cmd);
        delay(1000);
        ESP8266.println("");
      }

      if (ESP8266.available()) {
        Serial.write(ESP8266.read());
      }
    }

I get this response every time:

    AT+CWMODE=1

    OK
    AT+CWJAP="moto g","hvats555"

    WIFI DISCONNECT
    WIFI CONNECTED
    WIFI GOT IP

    OK
    AT+CIPMUX=1

    OK

    AT+CIPSTART=4,"TCP","himalayavats.com",80

    4,CONNECT

    OK

    AT+CIPSEND=4,43

    OK
    >
    Recv 43 bytes

    SEND OK

    +IPD,4,1370:HTTP/1.1 400 Bad Request
    Date: Tue, 19 Dec 2017 08:30:21 GMT
    Server: Apache
    Accept-Ranges: bytes
    Vary: Accept-Encoding,User-Agent
    Connection: close
    Content-Type: text/html

My JSON file on the website looks like this:

    {"power" : "high"}

body:
Take a look at the [HTTP specification][1]:

    Request       = Request-Line              ; Section 5.1
                    *(( general-header        ; Section 4.5
                     | request-header         ; Section 5.3
                     | entity-header ) CRLF)  ; Section 7.1
                    CRLF
                    [ message-body ]          ; Section 4.3

    Request-Line  = Method SP Request-URI SP HTTP-Version CRLF

You don't send the CRLF (carriage return, line feed) at the end of your request line and at the end of the header at the same time of the request. Why the delay?

You also miss the obligatory host header.

    Host = "Host" ":" host [ ":" port ] ; Section 3.2.2

  [1]: https://www.rfc-editor.org/rfc/rfc2616


message:
Arduino parsing JSON

I have created an API in Ruby on Rails and it send the following JSON response:

    {"sun_position":{"altitude":"32.46","azimuth":"223.93"}}

I'm able to successfully hit the API and store the response. But when I try to parse it and store data it gives me an error. I have used the Arduino JSON library.

The code for parsing the JSON is as follows:

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

    bool parseSunPosData(char* content, SunPosData* sunPos) {
      StaticJsonBuffer<JSONBUFFER_SIZE> jsonBuffer;
      JsonObject& root = jsonBuffer.parseObject(content);
      Serial.println("In parse fuc");
      Serial.println(content);
      Serial.println("==============");
      if (!root.success()) {
        Serial.println("JSON parsing failed!");
        return false;
      }

And the output on the serial monitor is as follows:

> In parse fuc 38
>
> {"sun_position":{"altitude":"32.46","azimuth":"223.93"}} 0
>
>
> ==============
>
>  JSON parsing failed! Disconnect

My guess is it can't parse the data due to the numbers 38 and zero printing... I don't know what that is and what it is.

PS: New to Arduino coding.

body:
you have the [HTTP chunked transfer encoding][1] numbers in the content. 38 is the length of the body and it is on the first line of the HTTP body and 0 marks the end.
maybe try using [ArduinoHttpClient][2] library for HTTP

  [1]: https://en.wikipedia.org/wiki/Chunked_transfer_encoding
  [2]: https://github.com/arduino-libraries/ArduinoHttpClient.


message:
How does Arduino UNO deal with bit shifting?

Explanatory comment: I'm a beginner. I'm examining the feasibly of bit shifting to the right 6 places to divide up the range of the Arduino ADC (has a range of 0 to 1023) to something much smaller. Such that any number in the ADC registers, between 0 and 63 produces a value of 0, a number between 64 and 127 a 1, between 128 and 191 a 2, between 192 and 255 a 3, etc. There is a change every 64 increase in the initial number.

I think this is possible to do. But some doubt has been expressed I think.

As far as I have determined, after right shifting 6 places to the right the following values of numbers are resident in the ADC registers: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15.

I wish you to consider, is there anything in the way Arduino's IDE works, or with the nature of the initial number in the register (signed/unsigned) that makes the results I have indicated false.  I think, that the initial number will be unsigned, just guessing.

body:
There are two types of right-shift in C - logical and arithmetic.

GCC (which is the compiler the Arduino IDE uses) selects which one to use depending on whether the type you are shifting is signed or not:

* If it's signed then use an arithmetic shift
* If it's unsigned then use a logical shift

In a logical shift, the value is literally shifted to the right padding the left side with zeros. An arithmetic shift, however, shifts and *extends the sign*. I.e., it performs an arithmetical "divide by 2".  That means if you right shift a negative value to still have a negative value (Note: this behaviour is implementation specific, so is only applicable to GCC. For other compilers in other situations you will have to check the documentation of that compiler).

So if you store the results of `analogRead()` in an unsigned integer variable `>> N` will right shift the value `N` times. If you store it in a signed integer it will divide the value by 2 `N` times.

For a positive value, which the results of `analogRead()` will be, the end result is the same - divide by 2 `N` times.

So if you right-shift 6 times you reduce a 10-bit value down to (10-6) 4 bits. 24 is 16, so you get 16 possible values.  24-1 is 15, so you get values 0-15 in your final value.


message:
digitalRead keeps giving 1

I am new to arduino programming and I have bought arduino UNO a few days ago.

I am trying to read the value of pin 4 using `digitalRead` with pinMode INPUT_PULLUP but it keeps giving me 1 even when the pin 4 is not connected to anything.

Here is the code:

    void setup() {
      pinMode(2,OUTPUT);
      pinMode(4,INPUT_PULLUP);
      Serial.begin(9600);
      digitalWrite(2,HIGH);
    }

    void loop() {
      Serial.print(digitalRead(4));
      Serial.print('\n');
      delay(150);
    }

Pin 2 is connected to one side of the button and Pin 4 is connected to other side of the button.
According to condition, when the button should be off , the value should be 0 and when the button  should be on , the value should be 1 , but the value is 1 even when I press the button is off or on.

On the other way , if I replace `INPUT_PULLUP` with `INPUT` then the value is floating.

Why the value with INPUT_PULLUP is 1?

body:
This looks as it is operating as wired and programmed.  When the button is open, the INPUT_PULLUP is pulling pin 4 to HIGH, and when the button is closed & shorted to pin 2, the `digitalWrite(2,HIGH)` would also pull the pin 4 to HIGH.

Maybe you want `digitalWrite(2,LOW)` so that connecting pin 4 to pin 2 through the button would pull pin 4 low.


body:
You have set Pin 2 to `HIGH`, which is 5V. You have set Pin 4 to `INPUT_PULLUP`, which means if no signal is driving it, it will be `HIGH`.

You have connected a button between Pins 2 and 4. So, if you don't press the button, the input is pulled `HIGH`. And if you do press the button, Pin 2 is driving it `HIGH`.


body:
There are to simple options how to connect a simple button. You mixed them.

Better option is connect the button between pin with INPUT_PULLUP and ground. The pin is HIGH when the button is open and LOW when the button grounds the pin. This option is better because if you disconnect the button, the pin is still pulled up to HIGH and not floating.

If you connect the [button with a pull-down circuit][1], then the pin is HIGH when the button is pressed and LOW when the button is open, but when you disconnect the circuit, the pin floats and the sketch reads chaos.

  [1]: https://www.arduino.cc/en/Tutorial/Button


message:
ESP8266 Missing data from Serial

I'm trying to read all the available access points nearby with an ESP8266 module.

Whenever I try to read all the available data from the ESP module and write it to the Monitor Serial it truncates text. Text often also a bit messed up.

I'm using an Arduino Uno with the following scheme (I'm using pins 2 & 3 NOT 1 & 0):

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

    #include <SoftwareSerial.h>

    SoftwareSerial esp8266(2, 3);

    void setup() {
      // Open serial communications and wait for port to open:
      Serial.begin(115200);

      esp8266.begin(115200);
    }

    void loop() {
      while(esp8266.available()) {
         Serial.write(esp8266.read());
      }

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

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

The code prints something like the following:

    AT+CWLAP

    +CWLAP:(3,#SBanaan",-73,"4c:09:d4:d5:d6:f2",1,,2,0)
    +CWLAP:(3,"UPC24923"CH7"0,L5-:d6Ai0:,
    ,,f5
    44"f"CZ7f1
    4-"6:0:4-95
    ,5-3d0

body: For `SoftwareSerial`, at 115200 bps data rate is not going to be reliable. Try 9600 bps.


body:
As @JoseCanUC has mentioned SoftwareSerial is not reliable at 115200 baud. This is because the bytes are sometimes too close together for the Arduino to start receiving a new one when the start bit arrives, and so the byte starts being received part way through, thus corrupting it.

You should investigate setting the baud rate of the ESP8266 to 9600, although this itself comes with its own set of pitfalls. You should be prepared to re-flash the AT firmware to reset the baud rate if it all goes wrong.  I would seriously suggest investing in one of the many cheap USB programming adaptors for the ESP-01 on eBay, since it makes working with these devices so much simpler.  It also opens up the possibility of creating and installing your own firmware for the ESP8266 instead of using the somewhat clunky AT firmware interface.


body:
I'm a bit confused by your diagram showing no ATmega chip on the Uno board, but you posted Uno code that should properly communicate with your ESP (except for the baud rate being too high for SoftwareSerial).

See my answer to another ESP question for [how to change the ESP's baud rate][1], especially the code fragment at the bottom of that answer.

Changing the ESPs parameters is not difficult as long as its AT firmware is intact (which it will be if you haven't attempted to re-flash the device). Changing baud rate is only slightly tricky, in that once the Uno has told the ESP to change its baud rate, the Uno must also change its baud rate to match before you can re-establish communication with it.

  [1]: https://arduino.stackexchange.com/questions/38289/at-command-is-not-responding-on-serial-monitor/38323#38323


message:
Does analogueRead() change the way a number is represented etc?

Explanatory Comment: The ADC conversion result is a 10 bit number and is placed in two 8 bit registers: ADCH & ADCL. AnalogueRead() reads the output of the ADC. This, I believe is an unsigned number. But, generally taken as only a positive number.

I'm interested in what changes, if any, take place to the number (in it's representation, interpretation, or construction or whatever) when analogueRead() reads the number and presumably makes something of it, or sends it or stores it somewhere.

body:
I assume you mean AnalogRead, see [AnalogRead][1].

What it effectively does is mapping 0 to 5V to values 0 to 1,023.
The unit is thus 5/1,024 V.
What this number means depend on the ADC used.

Probably the two bytes (ADCH as most significant bits and ADCL as least significant bits) contain this 0-1,023 value.

  [1]: https://www.arduino.cc/reference/en/language/functions/analog-io/analogread/


body:
It doesn't change anything, it just combines the two 8-bit register values to one 16-bit integer.

You can just look it up in the [source code for analogRead][1].

    int analogRead(uint8_t pin)
    {
     uint8_t low, high;

    [...]

     // we have to read ADCL first; doing so locks both ADCL
     // and ADCH until ADCH is read.  reading ADCL second would
     // cause the results of each conversion to be discarded,
     // as ADCL and ADCH would be locked when it completed.
     low  = ADCL;
     high = ADCH;

    [...]

     // combine the two bytes
     return (high << 8) | low;
    }

  [1]: https://github.com/arduino/Arduino/blob/2bfe164b9a5835e8cb6e194b928538a9093be333/hardware/arduino/avr/cores/arduino/wiring_analog.c#L84-L97


body:
There is no change in representation. `analogRead()` reads two I/O
registers, `ADCL` and `ADCH`, which on the Uno are memory-mapped to
addresses `0x0078` and `0x0079` respectively. It returns the result in a
register pair, `r24` and `r25`, which per the [AVR C calling
conventions](https://gcc.gnu.org/wiki/avr-gcc#Calling_Convention) is the
standard way of returning a 16-bit number. Thus, `r24` holds the value
read from `ADCL`, and `r25` the value read from `ADCH`. That's it. No
conversion whatsoever.

There is a change in interpretation... of sorts. The function is
declared as returning an `int`, which on the AVR is a 16-bit _signed_
integer, whereas it could be argued that the I/O registers contain an
unsigned number. However, since the sign bit will always be zero, the
signed/unsigned distinction is moot: either way the result will be
interpreted as a number between 0 and 1023.

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

**Edit**: As a clarification: the `ADC` register (which is another
name for the `ADCL`/`ADCH` register pair) is a 16-bit I/O register. At
the end of a conversion, it holds the 10-bit result right-adjusted into
this 16-bit space, zero-padded on the left, as follows:

    -------- ADCH --------- --------- ADCL --------
    0  0  0  0  0  0  r9 r8 r7 r6 r5 r4 r3 r2 r1 r0
    ----------------- ADC (16 bits) ---------------

where the bits r9..r0 represent the 10-bit conversion result. Since the
MSB is zero, it is irrelevant whether you interpret it as a sign bit or
as a regular unsigned bit.

Just for completeness, it could be noted that it is possible (though not
through the Arduino core library) to configure the ADC to left-adjust
the result, as follows:

    -------- ADCH --------- --------- ADCL --------
    r9 r8 r7 r6 r5 r4 r3 r2 r1 r0 0  0  0  0  0  0
    ----------------- ADC (16 bits) ---------------

In this case, the MSB could be one, at it would obviously be incorrect
to interpret it as a sign bit.

As a side note, the avr-libc defines `ADC` as
`(*(volatile uint16_t *)(0x78))`, which is unsigned. And it makes sense
considering that, unlike the users of Arduino core, the users of
avr-libc are supposed to know they have the choice to get a
left-adjusted result.


message:
NodeMCU v1 keeps dropping out

I've created a homebridge server on a Raspberry Pi Zero and have configured it to use my NodeMCU v1 (Esp - 12E Module) as an accessory to control RGB strip lights.

All works normally until you don't use the home kit to control the lights for certain amount of time (~30 seconds). My iPhone says that the accessory is non responsive until I force a command to happen, this after some time activates the accessory and goes back to normal.

Is there a way of keeping the NodeMCU active to HTTP responses all the time?

The code I have used is a mashup of a tutorial I used but I've modified it with some more features. (All coded in Arduino)

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

    //NodeMCU RGB-Controller for Homebridge & HomeKit (Siri)

    #include <ESP8266WiFi.h>
    #include <math.h>

    #define redPin 13 //D7 - Red channel
    #define grnPin 12 //D6 - Green channel
    #define bluPin 14 //D5 - Blue channel
    #define white 5 //D1 - Blue channel

    WiFiServer server(80); //Set server port

    String readString;           //String to hold incoming request
    String hexString = "000000"; //Define inititial color here (hex value), 080100 would be a calm warmtone i.e.

    int state;

    int r;
    int g;
    int b;

    float R;
    float G;
    float B;

    int x;
    int V;

    ///// WiFi SETTINGS - Replace with your values /////////////////
    const char* ssid = "xxxxxxx";
    const char* password = "xxxxxxx";
    IPAddress ip(192,168,1,234);      // set a fixed IP for the NodeMCU
    IPAddress gateway(192,168,1,1);  // Your router IP
    IPAddress subnet(255,255,255,0); // Subnet mask
    ////////////////////////////////////////////////////////////////////

    void WiFiStart() {
      Serial.print("Connecting to ");
      Serial.println(ssid);
      WiFi.begin(ssid, password);
      WiFi.config(ip, gateway, subnet); //Set a fixed IP. You can comment this out and set it in your router instead.
      while (WiFi.status() != WL_CONNECTED) {
        delay(100);
        Serial.print("_");
      }
      Serial.println();
      Serial.println("Done");
      Serial.print("IP address: ");
      Serial.println(WiFi.localIP());
      Serial.println("");

      server.begin();
    }

    void allOff() {
      state = 0;
      analogWrite(redPin, 0);
      analogWrite(grnPin, 0);
      analogWrite(bluPin, 0);
    }

    //Write requested hex-color to the pins (10bit pwm)
    void setHex() {
      state = 1;
      long number = (long) strtol( &hexString[0], NULL, 16);
      r = number >> 16;
      g = number >> 8 & 0xFF;
      b = number & 0xFF;
      r = map(r, 0, 255, 0, 1023);  //added for 10bit pwm
      g = map(g, 0, 255, 0, 1023);  //added for 10bit pwm
      b = map(b, 0, 255, 0, 1023);  //added for 10bit pwm
      analogWrite(redPin, (r));
      analogWrite(grnPin, (g));
      analogWrite(bluPin, (b));
    }

    //Compute current brightness value

    //For serial debugging only
    void showValues() {

      Serial.print("Status on/off: ");
      Serial.println(state);
      Serial.print("RGB color: ");
      Serial.print(r);
      Serial.print(".");
      Serial.print(g);
      Serial.print(".");
      Serial.println(b);
      Serial.print("Hex color: ");
      Serial.println(hexString);

      Serial.print("Brightness: ");
      Serial.println(V);
      Serial.println("");

    }

    void setup(){
      Serial.begin(9600);
      delay(1);
      pinMode(redPin, OUTPUT);  //declaration added
      pinMode(grnPin, OUTPUT);  //declaration added
      pinMode(bluPin, OUTPUT);  //declaration added
      setHex(); //Set initial color after booting. Value defined above
      WiFi.mode(WIFI_STA);
      WiFiStart();
      //showValues(); //Uncomment for serial output
    }

    void loop() {
      //Reconnect on lost WiFi connection (superfluous - will reconnect anyway)
      if (WiFi.status() != WL_CONNECTED) {
        WiFiStart();
      }

      WiFiClient client = server.available();

      if (!client) {
        return;
      }

      while(client.connected() && !client.available()) {
        delay(1);
      }

      //Respond on certain Homebridge HTTP requests
      if (client) {
        while (client.connected()) {
          if (client.available()) {
            char c = client.read();
            if (readString.length() < 100) {
              readString += c;
            }
            if (c == '\n') {
              Serial.print("Request: "); //Uncomment for serial output
              Serial.println(readString); //Uncomment for serial output

              //Send reponse
             client.println("HTTP/1.1 200 OK");
              client.println("Content-Type: text/html");
              client.println();

              //On
              if(readString.indexOf("on") >0) {
                setHex();
                Serial.println("on");
                showValues();
              }

              if(readString.indexOf("xw") >0) {

                Serial.println("won");
                analogWrite(white, 1024);
              }

              if(readString.indexOf("yw") >0) {

                Serial.println("woff");
                analogWrite(white, 0);
              }

              //Off
              if(readString.indexOf("off") >0) {
                allOff();
                showValues();
              }

              //Set color
              if(readString.indexOf("set") >0) {
                hexString = "";
                hexString = (readString.substring(9,15));
                setHex();
                //showValues();
              }

              //Status on/off
              if(readString.indexOf("status") >0) {
              client.println(state);
              }

              //Status color (hex)
              if(readString.indexOf("color") >0) {
              client.println(hexString);
              }

              //Status brightness (%)
              if(readString.indexOf("bright") >0) {

              client.println(V);
              }

              delay(1);
              client.stop();
              readString="";
            }
          }
        }
      }
    }

body:
You are probably running out of RAM because you are using the `String` object instead of a fixed-size char[] buffer. This code, in particular:

    if (readString.length() < 100) {
      readString += c;
    }

Concatenating `String` objects using the overloaded plus operator allocates a whole new block of RAM for the new, longer string. It frees the previous memory, but since you keep adding one character at a time, new strings won't be able to be put into the once-used RAM.

You should instead use C-style strings (character arrays) and the standard functions for managing them, such as `strnlen()` and `strncat()`, etc. Note, I am suggesting the versions of string functions with a `maxlen` parameter, which helps avoid bugs due to unterminated strings.


message:
Solution for two software serials

I've been working a while on a project using 3 Arduino Nanos, linked together using this tutorial [Nick Gammon][1].

  [1]: https://www.gammon.com.au/forum/?id=11428&reply=2#reply2

As I am not experienced with Arduino programming, I was making it step by step.

First I get all devices in one network, then managed to get the correct data sent from the correct device to one receiver. I added a Nextion display to visualize the received data. Then I have some physical buttons and some relays as well.

So far everything went fine until today. I wanted to send a command from the Nextion to the Arduino. Only then I realized that when using multiple software serial ports, only one can receive data at a time.

In my case I have an RS485 on SoftwareSerial and the Nextion.

I'm  feeling a bit upset now, as I soldered everything on a prototyping board as nice as I can. I tried to move the Nextion on to hardware serial, as that was quite easy to access, but the result was inconsistent.

Please, can someone suggest me how to change my project's hardware and what I need to program (Software Serial or Hardware Serial) to make it to work? Basically I am looking for the right direction now,  when I will get that I can figure out the rest by myself.

body:
Hardware serial, on the face of it, should be the more reliable because it uses hardware that can run simultaneously with other code. It uses interrupts to transfer a received byte from its internal register into program RAM.

Software serial, on the other hand, is somewhat more timing-dependent because it uses timing loops to detect each bit at the correct time. In order to do this, it turns off hardware interrupts in order to ensure that each timing loop runs at the expected speed.

If you use Software serial at the same time as hardware serial, the fact that Software serial turns off interrupts may mean that the processor doesn't get a chance to transfer the most recent byte from the serial hardware to RAM.

A work-around, if possible, is to use Software serial at the fastest possible baud rate. That means that interrupts are turned off for a shorter time. When they are turned back on the processor can recover the most recent hardware serial byte.

Thus, if you have two devices using serial, put the faster one onto Software serial, to reduce the time that interrupts are off.

RS485 does not, per se, specify a transfer rate. It is a balanced electrical protocol, which is designed to minimize the impact of noise over long cable runs.


message:
DHT11 Sensor Code Fatal Error

I recently tried using Hobbyist.co.nz's guide on the DHT11 sensor. I installed the Adafruit_Sensor and DHT11 Sensor libraries,  but it keeps returning with a fatal error.

Here is the code and the error:

    #include <dht.h>

    #define dht_dpin A0 //no ; here. Set equal to channel sensor is on

    dht DHT;

    void setup(){
      Serial.begin(9600);
      delay(300);//Let system settle
      Serial.println("Humidity and temperature\n\n");
      delay(700);//Wait rest of 1000ms recommended delay before
      //accessing sensor
    }//end "setup()"

    void loop(){
      //This is the "heart" of the program.
      DHT.read11(dht_dpin);

        Serial.print("Current humidity = ");
        Serial.print(DHT.humidity);
        Serial.print("%  ");
        Serial.print("temperature = ");
        Serial.print(DHT.temperature);
        Serial.println("C  ");
      delay(800);//Don't try to access too frequently... in theory
      //should be once per two seconds, fastest,
      //but seems to work after 0.8 second.
    }// end loop()

>     C:\Users\XXXXXX\Documents\Arduino\sketch_dec19c\sketch_dec19c.ino:2:17:
> fatal error: dht.h: No such file or directory
>
>     #include <dht.h>

body:
The examples I can see from Adafruit say

    #include "DHT.h"

or

    #include <DHT.h>

But you wrote

    #include <dht.h>

They aren't the same.

Further, the examples for the Adafruit library show usage like:

      // Reading temperature or humidity takes about 250 milliseconds!
      // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
      float h = dht.readHumidity();
      // Read temperature as Celsius (the default)
      float t = dht.readTemperature();
      // Read temperature as Fahrenheit (isFahrenheit = true)
      float f = dht.readTemperature(true);

But you call `DHT.temperature` and `DHT.humidity`.

If you are meaning to use the Adafruit library, you have to write your code according to their documentation.

Also of note, you have defined the type of the object as `dht` and the name as `DHT`, but for Adafruit, the type is `DHT`.

**EDIT:**

The example on the website you note has a downloadable zip file for the DHT library they use. You cannot assume that all libraries for interfacing a certain sensor will all have the same programming interface.


message:
RFID + LCD + Arduino Mega 2560 = RFID not printing correctly

My Arduino Mega isn't printing the RFID card's tag it simply prints the card's 2 digits at a time but deletes the previous prints. Can I get help with this?

    #include <SPI.h>
    #include <MFRC522.h>
    #include <Servo.h>
    #include <LiquidCrystal.h>

    Servo myservo;  //creates servo to control

    const int rs = 26, en = 27, d4 = 28, d5 = 29, d6 = 31, d7 = 30;
    LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

    #define SS_PIN 53
    #define RST_PIN 5
    MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.
    int R=3;
    int G=8;
    int B=6;

    void setup() {
      lcd.begin(16, 2);
      Serial.begin(9600);   // Initiate a serial communication
      SPI.begin();      // Initiate  SPI bus
      mfrc522.PCD_Init();   // Initiate MFRC522
      Serial.println("Approximate your card to the reader...");
      lcd.print("Place your card");
      lcd.setCursor(0, 1);
      lcd.print("Near reader");
      lcd.setCursor(0, 0);
      myservo.attach(7);//attatches servo to pin 7
      myservo.write(179);
    }

    void loop() {
      analogWrite(B, 255);
      // Look for new cards
      if (!mfrc522.PICC_IsNewCardPresent()) {
        return;
      }
      // Select one of the cards
      if (!mfrc522.PICC_ReadCardSerial()) {
        return;
      }
      //Show UID on serial monitor
      Serial.print("UID tag :");
      byte letter;
      String content= "";
      for (byte i = 0; i < mfrc522.uid.size; i++) {
         lcd.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
         lcd.print(mfrc522.uid.uidByte[i], HEX);
         content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
         content.concat(String(mfrc522.uid.uidByte[i], HEX));
         lcd.setCursor(0, 0);
      }
      delay(1000);
      lcd.clear();
      Serial.println();
      Serial.print("Message : ");
      content.toUpperCase();
      if (content.substring(1) == "4F 60 3C D9") {
        //change here the UID of the card/cards that you want to give access
        Serial.println("Authorized access");
        lcd.print("Authorized");
        analogWrite(B, 0);
        tone(4, 900, 100);
        lcd.clear();
        Serial.println("Unlocking...");
        lcd.print("Unlocking...");
        lcd.clear();
        analogWrite(R, 255);
        analogWrite(G, 127);
        delay(1000);
        myservo.write(100);
        delay(15);
        Serial.println("Unlocked");
        lcd.print("Unlocked");
        lcd.clear();
        analogWrite(R, 0);
        analogWrite(G, 255);
        delay(5000);
        Serial.println("Relocking...");
        lcd.print("Relocking...");
        lcd.clear();
        analogWrite(R, 255);
        analogWrite(G, 127);
        delay(1000);
        myservo.write(179);
        delay(15);
        Serial.println("Locked");
        lcd.print("Locked");
        lcd.clear();
        analogWrite(R, 0);
        analogWrite(G, 0);
        delay(100);
      } else {
        Serial.println("Checking Card");
        lcd.print("Checking Card");
        lcd.setCursor(0, 1);
        delay(100);
        lcd.clear();
        Serial.println("Access denied");
        lcd.print("Access denied");
        analogWrite(B, 0);
        tone(4, 900, 1000);
        analogWrite(R, 255);
        delay(500);
        analogWrite(R, 0);
        delay(500);
        tone(4, 1900, 1000);
        analogWrite(R, 255);
        delay(500);
        analogWrite(R, 0);
        delay(500);
        tone(4, 900, 1000);
        analogWrite(R, 255);
        delay(500);
        analogWrite(R, 0);
        delay(500);
        tone(4, 1900, 1000);
        analogWrite(R, 255);
        delay(500);
        analogWrite(R, 0);
        delay(500);
        tone(4, 900, 1000);
        analogWrite(R, 255);
        delay(500);
        analogWrite(R, 0);
        delay(500);
        tone(4, 1900, 1000);
        analogWrite(R, 255);
        delay(500);
        analogWrite(R, 0);
        delay(500);
        tone(4, 900, 1000);
        analogWrite(R, 255);
        delay(500);
        analogWrite(R, 0);
        delay(500);
        tone(4, 1900, 1000);
        analogWrite(R, 255);
        delay(500);
        analogWrite(R, 0);
        delay(500);
        tone(4, 900, 1000);
        analogWrite(R, 255);
        delay(500);
        analogWrite(R, 0);
        delay(500);
        tone(4, 1900, 1000);
        analogWrite(R, 255);
        delay(500);
        analogWrite(R, 0);
        delay(100);
      }
     lcd.clear();
     Serial.println("Ready");
     lcd.print("Ready");
    }

body:
OK i fixed it. It is now this :

    #include <SPI.h>
    #include <MFRC522.h>
    #include <Servo.h>
    #include <LiquidCrystal.h>

    Servo myservo;  //creates servo to control

    const int rs = 44, en = 45, d4 = 46, d5 = 47, d6 = 49, d7 = 48;
    LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

    #define SS_PIN 53
    #define RST_PIN 5
    MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.
    int R=3;
    int G=8;
    int B=6;

    void setup()
    {
      lcd.begin(16, 2);
      Serial.begin(9600);   // Initiate a serial communication
      SPI.begin();      // Initiate  SPI bus
      mfrc522.PCD_Init();   // Initiate MFRC522
      Serial.println("Place your card near reader");
      lcd.print("Place your card");
      lcd.setCursor(0, 1);
      lcd.print("Near reader");
      lcd.setCursor(0, 0);
      myservo.attach(7);//attatches servo to pin 7
      myservo.write(179);
    }
    void loop()
    {
      analogWrite(B, 255);
      // Look for new cards
      if ( ! mfrc522.PICC_IsNewCardPresent())
      {
        return;
      }
      // Select one of the cards
      if ( ! mfrc522.PICC_ReadCardSerial())
      {
        return;
      }
      //Show UID on serial monitor
      lcd.clear();
      Serial.print("UID tag :");
      lcd.print("ID:");
      byte letter;
      String content= "";
      for (byte i = 0; i < mfrc522.uid.size; i++)
      {
         Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
         Serial.print(mfrc522.uid.uidByte[i], HEX);
         lcd.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
         lcd.print(mfrc522.uid.uidByte[i], HEX);
         content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
         content.concat(String(mfrc522.uid.uidByte[i], HEX));
      }
      Serial.println();
      Serial.print("Message : ");
      content.toUpperCase();
      if (content.substring(1) == "4F 60 3C D9") //change here the UID of the card/cards that you want to give access
      {
        delay(5000);
        lcd.clear();
        Serial.println("Scanning Database");
        lcd.print("Scanning");
        lcd.setCursor(0, 1);
        lcd.print("Database");
        lcd.setCursor(0, 0);
        delay(5000);
        lcd.clear();
        Serial.println("Authorized access");
         lcd.print("Authorized");
        analogWrite(B, 0);
        tone(4, 900, 100);
        lcd.clear();
        Serial.println("Unlocking...");
        lcd.print("Unlocking...");
        lcd.clear();
        analogWrite(R, 255);
        analogWrite(G, 127);
        delay(1000);
        myservo.write(100);
        delay(15);
        Serial.println("Unlocked");
        lcd.print("Unlocked");
        delay(5000);
        lcd.clear();
        analogWrite(R, 0);
        analogWrite(G, 255);
        Serial.println("Relocking...");
        lcd.print("Relocking...");
        delay(1000);
        lcd.clear();
        analogWrite(R, 255);
        analogWrite(G, 127);
        myservo.write(179);
        delay(15);
        Serial.println("Locked");
        lcd.print("Locked");
        delay(100);
        lcd.clear();
        analogWrite(R, 0);
        analogWrite(G, 0);
      }else{
        delay(1000);
        lcd.clear();
        Serial.println("Scanning Database");
        lcd.print("Scanning Databas");
        delay(5000);
        lcd.clear();
        Serial.println("Access denied");
        lcd.print("Access denied");
        analogWrite(B, 0);
        tone(4, 900, 1000);
        analogWrite(R, 255);
        delay(500);
        analogWrite(R, 0);
        delay(500);
        tone(4, 1900, 1000);
        analogWrite(R, 255);
        delay(500);
        analogWrite(R, 0);
        delay(500);
        tone(4, 900, 1000);
        analogWrite(R, 255);
        delay(500);
        analogWrite(R, 0);
        delay(500);
        tone(4, 1900, 1000);
        analogWrite(R, 255);
        delay(500);
        analogWrite(R, 0);
        delay(500);
        tone(4, 900, 1000);
        analogWrite(R, 255);
        delay(500);
        analogWrite(R, 0);
        delay(500);
        tone(4, 1900, 1000);
        analogWrite(R, 255);
        delay(500);
        analogWrite(R, 0);
        delay(500);
        tone(4, 900, 1000);
        analogWrite(R, 255);
        delay(500);
        analogWrite(R, 0);
        delay(500);
        tone(4, 1900, 1000);
        analogWrite(R, 255);
        delay(500);
        analogWrite(R, 0);
        delay(500);
        tone(4, 900, 1000);
        analogWrite(R, 255);
        delay(500);
        analogWrite(R, 0);
        delay(500);
        tone(4, 1900, 1000);
        analogWrite(R, 255);
        delay(500);
        analogWrite(R, 0);
        delay(100);
      }
     lcd.clear();
     Serial.println("Ready");
     lcd.print("Ready");
    }

had to remove the `lcd.setCursor(0, 1);`
from line 57.