# Question
Title: Drum game controller - Problem with Piezo inputs
I currently try to build some Drums for the game Clone Hero. The problem that I have is that I can't use both of my Piezo inputs that I have hooked up at the same time. I have a Arduino Pro Micro and use this Library. This is my code that I have so far. I'm pretty new to this Arduino stuff, so I don't understand a ton yet.

Anyway, thanks in Advance. :)

```
#include <Joystick.h>

const int drum1 = A0;
const int drum2 = A1;
const int drum3 = A2;
const int drum4 = A3;

const int threshold = 100;

int sensorReading = 0;

Joystick_ Joystick;

void setup() {

  // Initialize Joystick Library
  Joystick.begin();
}

// Last state of the button
int lastButtonState = 0;

void loop() {

  sensorReading = analogRead(drum1);

  if (sensorReading >= threshold)
  {
    Joystick.pressButton(0);
    Joystick.releaseButton(0);
  }

  sensorReading = analogRead(drum2);

  if (sensorReading >= threshold)
  {
    Joystick.pressButton(1);
    Joystick.releaseButton(1);

  }
}

```

# Answer
From my interpretation of your problem it seems like you want to be able to press two (or more) joystick buttons at once by striking multiple drum pads. As it stands your code will never be able to do that since you press, then immediately release, each button sequentially.

The simplest way around this is to only press the button when you strike the drum, then release the button at a later time, which gives a chance for another button to be pressed in the meantime. What that "later time" is would be for you to decide.

The simplest thing to do is maintain a "this drum has been struck" flag along with a "this drum was struck at" timestamp (it's possible to combine the two), both of which are set at the moment of striking the drum. Then later in your code you check that timestamp and flag and release the button (and disable the flag) if the required time has expired.

To prevent duplicate code it can be good to encapsulate the logic and state variables for a single drum into a `class` and then instantiate multiple instances, one for each drum pad. For example, here's some untested code that may or may not work:

```
class Drum {
    private:
        uint32_t _timestamp;
        uint8_t _button;
        uint8_t _channel;
        int16_t _threshold;

    public:
        Drum(uint8_t channel, uint8_t button, int16_t threshold = 100) {
            _channel = channel;
            _button = button;
            _threshold = threshold;
            _timestamp = 0;
        }

        void process() {
            if (_timestamp > 0) { // Has been struck
                if (millis() - _timestamp >= 100) { // 100ms window - adjust as needed
                    Joystick.releaseButton(_button); // Release the button
                    _timestamp = 0; // Set it as not struck
                }
            }

            if (analogRead(_channel) > _threshold) {
                _timestamp = millis(); // Set it as struck now
                Joystick.pressButton(_button); // Press the button
            }
        }
};

```

Then you can instantiate multiple drums:

```
Drum drum1(A0, 0);
Drum drum2(A1, 1);

```

Then in your loop simply:

```
void loop() {
    drum1.process();
    drum2.process();
}

```

Again I reiterate: this code is untested, I don't even know if it compiles.
> 1 votes

---
Tags: input, atmega32u4, piezo
---


# Question
Title: Update the ESP to espduino via NodeMCU Flasher
I am using Cactus Micro Rev2 and I'm trying to communicate with ESP via Mega32U4. I guess I have to update to espduino to be able to program the ESP side.

And I don't know current ESP firmware version. I tried firmware update (https://github.com/AprilBrother/espduino/tree/master/esp8266/release) via esptool but it gave connection error. And I can't erase flash it still gives an error. This time I tried via nodeMcu flasher:

> Screenshot:

It succeeds. But when I uploaded the basic serial communicate sketch to ESP and Mega32U4 side, I still don't get a response.

ESP side sketch:

```
{
Serial1.begin(115200);
}

void loop()
{
Serial1.println(“Hello”);
delay(1000);
}

```

MEGA32U4 side sketch:

```
String character = Serial1.readString();
Serial.println(character);
}

```

Believe me, I don't know exactly where I went wrong. I wrote more descriptive, but I was asked to ask one question. In short, how exactly can I update to espduino via NodeMCU flasher?

# Answer
> 1 votes
The Cactus Micro Rev2 board has ATmega32u4 with LiliPad bootloader as main MCU and esp8266 as WiFi adapter.

The esp8266 UART is connected to 32u4 Serial1. The Serial on 32u4 is connected to computer over USB.

To bridge the esp8266 to computer you can use the SerialPassthrough sketch from Communication section of base Arduino IDE examples in File menu.

The manufacturer of the board made a sketch for the ATmega32u4 which sets the esp8266 to bootloader mode and bridges the esp8266 to USB.

The esp8266Programmer.ino sketch is basically a SerialPassthrough sketch with reset of the esp8266 to bootloader mode in setup().

Select "Arduino LiliPad USB" in Arduino IDE the upload the esp8266Programmer.ino sketch to the 32u4.

With the esp8266Programmer.ino in 32u4 you can upload to esp8266 with Arduino IDE or esptool.py.

If you want to communicate with the application (firmware or sketch) in esp8266, use the SerialPassthrough sketch from Arduino IDE examples (because the esp8266Programmer sketch always sets the esp8266 to bootloader mode).

For successful upload from IDE or esptool.py over the esp8266Programmer sketch, the reset before uploading must be suppressed. In IDE it is the "Reset method" option (select `no_dtr`), for esptool.py it is the `--before no_reset` option.

# Answer
> 2 votes
The board has an esp-03. First, we uploaded `esp8266programmer.ino` and then uploaded the esp sketch from IDE. Our esp settings must be like this:

> Flash Size: "1MB (none OTA)
> Flash Mode: "DIO"
> Reset method: "no dtr (aka ck)"

We uploaded our sketch. The Atmega sketch must have this two lines of code in the `setup()` function:

```
digitalWrite(program_pin, HIGH); //Set GPIO to boot into programming mode
digitalWrite(enable_pin, HIGH); //Enable ESP-03 module

```

The serial baud rate must be less than 74880. This way, the problem will be solved. Thanks to @Juraj for the support.

---
Tags: esp8266, arduino-mega
---


# Question
Title: Ethernet shield issues (defective shield?!)
I'm a newbie in using the **Arduino Ethernet Shield v2** (Arduino product code A000024) and I'm experiencing some strange behaviours on a critical work with strict deadline.

The project involve some Arduino (both UNOs and MEGA2560s) sending sensor data via OSC to a couple of destination PCs for later processing.

To do that I'm using what it seemed to me to be a quite simple to use Arduino OSC library, the CNMAT one.

I've noticed this fact, which I think is related to some hardware malfunction.

I've found my code getting stuck even with a correct setup of the LAN. The code stops working, stops sending OSC messages, Ethernet shield is no more reachable with the *ping*. This persists also after loading again the code, or manually resetting the Arduino board. Initially I thought it was my fault but I've found that, substituting the shield with another one, the problem magically disappeared. On one of the problematic shield I've also experienced many continuous shutdowns and startups of the Arduino every 5 seconds (firmware restart from the setup)!

Are these ethernet shields known to be defective or having some issues? The strange thing is that I've experienced this problem on 3 out of 8 of them: this is super critical! Have you experienced something similar? Do you know of similar problems occurred before?

---

For debug purposes, here's a code test I've written and tried on a single Arduino UNO, always the same, using the same LAN setup (ethernet cable, IP addresses, Ethernet switch) switching two different Ethernet shields:

```
/* NET stuff ********************************************/
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
EthernetUDP Udp;

IPAddress ip(10, 3, 3, 210); // the Arduino's IP
byte mac[] = { 0xA8, 0x61, 0x0A, 0xAE, 0x83, 0xCE };

#define DELAY 1000

// SETUP //////////////////////////////////////////////////////////////////
void setup() {

  Serial.begin( 115200 );
  Serial.println("setup");

  // Ethernet and OSC utilities **************************
  Ethernet.begin(mac, ip);

  // Hardware status check
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Ethernet shield was not found.");
  }
  else if (Ethernet.hardwareStatus() == EthernetW5100) {
    Serial.println("W5100 Ethernet controller detected.");
  }
  else if (Ethernet.hardwareStatus() == EthernetW5200) {
    Serial.println("W5200 Ethernet controller detected.");
  }
  else if (Ethernet.hardwareStatus() == EthernetW5500) {
    Serial.println("W5500 Ethernet controller detected.");
  }

  //Tells you whether the link is active.
  // LinkOFF could indicate the Ethernet cable is unplugged or defective.
  if (Ethernet.linkStatus() == Unknown) {
    Serial.println("Link status unknown. Link status detection is only available with W5200 and W5500.");
  }
  else if (Ethernet.linkStatus() == LinkON) {
    Serial.println("Link status: On");
  }
  else if (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Link status: Off");
  }

  while( Ethernet.linkStatus() == LinkOFF ) {
    delay( DELAY );
  }
}

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

  if (Ethernet.linkStatus() == LinkOFF) {
    Serial.print("Ethernet link broken!\t");
    Serial.println("please connect the Ethernet cable");
    delay( DELAY );
    return;
  }

  Serial.println("LOOP working as expected!");
  delay( DELAY );
}

```

When I try this code using the "defective" Arduino Ethernet shield the Serial monitor print something like this (note that I'm not doing anything, I'm leaving everything untouched):

```
[...]
14:25:17.906 -> setup
14:25:18.471 -> W5500 Ethernet controller detected.
14:25:18.471 -> Link status: On
[...]
14:26:41.545 -> LOOP working as expected!
14:26:42.542 -> LOOP working as expected!
14:26:43.538 -> LOOP working as expected!
14:26:44.535 -> Ethernet link broken!   please connect the Ethernet cable
14:26:45.531 -> LOOP working as expected!
14:26:46.561 -> LOOP working as expected!
14:26:47.558 -> LOOP working as expected!
14:26:48.555 -> LOOP working as expected!
14:26:49.552 -> Ethernet link broken!   please connect the Ethernet cable
14:26:50.549 -> LOOP working as expected!
14:26:51.546 -> LOOP working as expected!
14:26:52.543 -> LOOP working as expected!
14:26:53.540 -> LOOP working as expected!
14:26:54.570 -> LOOP working as expected!
14:26:55.567 -> Ethernet link broken!   please connect the Ethernet cable
14:26:56.564 -> LOOP working as expected!
14:26:57.561 -> LOOP working as expected!
14:26:58.557 -> LOOP working as expected!
14:26:59.553 -> Ethernet link broken!   please connect the Ethernet cable
14:27:00.550 -> Ethernet link broken!   please connect the Ethernet cable
14:27:01.546 -> LOOP working as expected!
14:27:02.576 -> Ethernet link broken!   please connect the Ethernet cable
14:27:03.572 -> LOOP working as expected!
14:27:04.569 -> LOOP working as expected!
14:27:05.566 -> LOOP working as expected!
14:27:06.563 -> LOOP working as expected!
14:27:07.560 -> LOOP working as expected!
14:27:08.557 -> LOOP working as expected!
14:27:09.587 -> LOOP working as expected!
14:27:10.583 -> Ethernet link broken!   please connect the Ethernet cable
14:27:11.580 -> LOOP working as expected!
14:27:12.577 -> LOOP working as expected!
[...]

```

In the meantime, the ping stops working and will not work again until I reboot the Arduino:

```
[...]
64 bytes from 10.3.3.210: icmp_seq=301 ttl=128 time=0.185 ms
64 bytes from 10.3.3.210: icmp_seq=302 ttl=128 time=0.171 ms
64 bytes from 10.3.3.210: icmp_seq=303 ttl=128 time=0.184 ms
64 bytes from 10.3.3.210: icmp_seq=304 ttl=128 time=0.229 ms
64 bytes from 10.3.3.210: icmp_seq=305 ttl=128 time=0.206 ms
64 bytes from 10.3.3.210: icmp_seq=306 ttl=128 time=0.278 ms
64 bytes from 10.3.3.210: icmp_seq=307 ttl=128 time=0.143 ms
64 bytes from 10.3.3.210: icmp_seq=308 ttl=128 time=0.229 ms
64 bytes from 10.3.3.210: icmp_seq=309 ttl=128 time=0.198 ms
From 10.3.3.165 icmp_seq=335 Destination Host Unreachable
From 10.3.3.165 icmp_seq=336 Destination Host Unreachable
From 10.3.3.165 icmp_seq=339 Destination Host Unreachable
From 10.3.3.165 icmp_seq=342 Destination Host Unreachable
From 10.3.3.165 icmp_seq=343 Destination Host Unreachable
From 10.3.3.165 icmp_seq=344 Destination Host Unreachable
[...]

```

As you see the "Link" seems to be on and than off repeatedly. I don't know why from the moment. I'm not modifying anything on my network setup (the LAN cable or anything like that).

I don't know why the ping stops working and will not work again even if the Serial monitor is telling the LINK is ON.

Let me know as soon as you can and thank you so much for your help and support.

bests

na

PS: I've posted a similar question on the Arduino forum but I had no way of understanding what kind of problem is this --\> link

**edit 11/02/2021**

I've written a new code sketch to always print the status of the link. Here it is.

```
    /* NET stuff ********************************************/
    #include <SPI.h>
    #include <Ethernet.h>
    #include <EthernetUdp.h>
    EthernetUDP Udp;

    IPAddress ip(10, 3, 3, 210); // the Arduino's IP
    byte mac[] = { 0xA8, 0x61, 0x0A, 0xAE, 0x83, 0xD5 };

    #define DELAY 1000

    // SETUP //////////////////////////////////////////////////////////////////
    void setup() {

      Serial.begin( 115200 );
      Serial.println("setup");

      // Ethernet and OSC utilities **************************
      Ethernet.begin(mac, ip);

      // Hardware status check
      if (Ethernet.hardwareStatus() == EthernetNoHardware) {
        Serial.println("Ethernet shield was not found.");
      }
      else if (Ethernet.hardwareStatus() == EthernetW5100) {
        Serial.println("W5100 Ethernet controller detected.");
      }
      else if (Ethernet.hardwareStatus() == EthernetW5200) {
        Serial.println("W5200 Ethernet controller detected.");
      }
      else if (Ethernet.hardwareStatus() == EthernetW5500) {
        Serial.println("W5500 Ethernet controller detected.");
      }

      //Tells you whether the link is active.
      // LinkOFF could indicate the Ethernet cable is unplugged or defective.
      if (Ethernet.linkStatus() == Unknown) {
        Serial.println("Link status unknown. Link status detection is only available with W5200 and W5500.");
      }
      else if (Ethernet.linkStatus() == LinkON) {
        Serial.println("Link status: On");
      }
      else if (Ethernet.linkStatus() == LinkOFF) {
        Serial.println("Link status: Off");
      }

      while( Ethernet.linkStatus() == LinkOFF ) {
        Serial.println("\tplease connect the Ethernet cable");
        delay( DELAY );
      }
    }

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

      int LINK_STATUS = Ethernet.linkStatus();

      if ( LINK_STATUS == LinkOFF) {
        Serial.print("Ethernet link broken!\t");
        Serial.println("please connect the Ethernet cable");
        delay( DELAY );
        return;
      } else if( LINK_STATUS == Unknown ) {
        Serial.println("LINK_STATUS: Unknown");
        delay( DELAY );
        return;
      } else if( LINK_STATUS == LinkON ) {
        Serial.println("LOOP working as expected! (LINK_STATUS: ON)");
      }

      delay( DELAY );
    }

```

After a while, it gave me this output on the serial monitor (at the same time ping said "Destination Host Unreachable"):

```
[...]
10:57:21.207 -> LOOP working as expected! (LINK_STATUS: ON)
10:57:22.203 -> LOOP working as expected! (LINK_STATUS: ON)
10:57:23.200 -> LOOP working as expected! (LINK_STATUS: ON)
10:57:24.197 -> LOOP working as expected! (LINK_STATUS: ON)
10:57:25.195 -> Ethernet link broken!   please connect the Ethernet cable
10:57:26.192 -> LOOP working as expected! (LINK_STATUS: ON)
10:57:27.188 -> LOOP working as expected! (LINK_STATUS: ON)
10:57:28.186 -> LOOP working as expected! (LINK_STATUS: ON)
10:57:29.216 -> Ethernet link broken!   please connect the Ethernet cable
10:57:30.213 -> Ethernet link broken!   please connect the Ethernet cable
10:57:31.210 -> Ethernet link broken!   please connect the Ethernet cable
10:57:32.207 -> Ethernet link broken!   please connect the Ethernet cable
10:57:33.204 -> LOOP working as expected! (LINK_STATUS: ON)
10:57:34.202 -> Ethernet link broken!   please connect the Ethernet cable
10:57:35.198 -> Ethernet link broken!   please connect the Ethernet cable
10:57:36.194 -> Ethernet link broken!   please connect the Ethernet cable
10:57:37.224 -> Ethernet link broken!   please connect the Ethernet cable
10:57:38.221 -> Ethernet link broken!   please connect the Ethernet cable
10:57:39.219 -> LOOP working as expected! (LINK_STATUS: ON)
10:57:40.216 -> LOOP working as expected! (LINK_STATUS: ON)
10:57:41.213 -> LOOP working as expected! (LINK_STATUS: ON)
10:57:42.210 -> LOOP working as expected! (LINK_STATUS: ON)
10:57:43.207 -> LOOP working as expected! (LINK_STATUS: ON)
10:57:44.236 -> LOOP working as expected! (LINK_STATUS: ON)
10:57:45.232 -> Ethernet link broken!   please connect the Ethernet cable
10:57:46.228 -> LOOP working as expected! (LINK_STATUS: ON)
10:57:47.225 -> LOOP working as expected! (LINK_STATUS: ON)
10:57:48.222 -> LOOP working as expected! (LINK_STATUS: ON)
10:57:49.218 -> Ethernet link broken!   please connect the Ethernet cable
10:57:50.216 -> Ethernet link broken!   please connect the Ethernet cable
10:57:51.212 -> Ethernet link broken!   please connect the Ethernet cable
10:57:52.242 -> Ethernet link broken!   please connect the Ethernet cable
10:57:53.239 -> Ethernet link broken!   please connect the Ethernet cable
10:57:54.235 -> Ethernet link broken!   please connect the Ethernet cable
10:57:55.231 -> Ethernet link broken!   please connect the Ethernet cable
10:57:56.227 -> Ethernet link broken!   please connect the Ethernet cable
[...]

```

Adding some new elements here. I've also noticed that, sometimes, even if the LINK status is ON, the ping is not working. It is almost clear to me that the two things are completely uncorrelated.

I've made some experiments in changing also the MAC address (setting a MAC address which is different from the one I see on the label on the shield). The "*wrong*" MAC address seems not to be cause of problems. Can it be that a MAC address misconfiguration on the Arduino firmware can make the things work the wrong way?

I've also made many attempts in disconnetting and re-connecting the ethernet cable to the shield without powering the Arduino off and I've experinced a series of different behaviours.

**1A)** disconnecting the ethernet cable:

* Serial monitor prints: "Ethernet link broken! please connect the Ethernet cable"
* ping stops;

**1B)** re-connecting the ethernet cable:

* on the Serial monitor LinkOn and LinkOff alternate between themselves, then, "LOOP working as expected! (LINK\_STATUS: ON)" becomes stable;
* ping still prints "Destination Host Unreachable";

**2)** reset of the Arduino Board (not the reset on the shield)

* Serial monitor: "LOOP working as expected! (LINK\_STATUS: ON)"
* ping works again;

**3A)** Trying to repeat the same procedure as before (1A). Disconnecting the Ethernet cable:

* Serial monitor prints "Ethernet link broken! please connect the Ethernet cable";
* ping stops;

**3B)** re-connecting the ethernet cable:

* on the Serial monitor LinkOn and LinkOff alternate between themselves, then, "LOOP working as expected! (LINK\_STATUS: ON)" becomes stable;
* ping works again (which is a different behaviour from before!!!);

This problem is really difficult for me to debug. It seems we have a lot of variables to take into consideration here, which are not under my control: if I repeat the same procedure again and again, behaviour changes.

I'm not sure if it depends on the board, on the *W5500* chip, maybe on other things happening on the net. Is it possible?

I don't know how to write a code to be capable of detecting these malfunctions.

Thank you so much for your help. na

# Answer
I've had similar issues with the Ethernet V2 shield, which were probably caused by the (unused) SD Card interface on the Ethernet V2 shield interfering with Ethernet functionality (both use the SPI bus).

From what I could see in the Ethernet Shield2 schematics, there is no pull-up on the signal controlling the SD card Chip Select (D4/SD\_CS), which means an unitialized I/O pin on the Arduino side could potentially cause random noise on the SD CS input.

My solution was to explicitly disable the SD Card interface CS, by setting pin 4 to high at the start of my `setup()` code.

I used the following code:

```
#define SDSelect  4

... Other initialization code

setup() {
    pinMode (SDSelect, OUTPUT);
    digitalWrite (SDSelect, HIGH);

    ... Code continues ...

```

This solved my issues with random crashing. I realize that I can't remember if there was an SD card present in the slot at the time.
> 3 votes

---
Tags: ethernet-shield
---


title: Interrupt takes longer than expected

text:
# Question
Title: Interrupt takes longer than expected
I am trying to write a delay function in C, which should take 0.5 seonds then carry on. I am aware that there are libraries for this purpouse, I want to make it myself.

```
#include <avr/interrupt.h>
#include <avr/io.h>
#define bitset(var,bitno) ((var) |= (1 << (bitno)))

int volatile time_unit;

ISR(TIMER0_COMPA_vect) {

  time_unit += 1;
}

void wait_func(){
  TCNT0 = 0;
  time_unit = 0;
  while (time_unit < 31);
}

int main(void){
  DDRD = 1;
   cli();
  bitset(TCCR0A, WGM01);
  bitset(TCCR0B, CS00);
  bitset(TCCR0B, CS02);
  OCR0A = 0xFF;
  bitset(TIMSK0, OCIE0A);
  sei();

  while(1){
    PIND = 0;
    wait_func();
    PIND = 1;
    wait_func();
  };
}

```

The timer is in CTC- Mode 1024 prescaler, counting 31\*255 (OCR0A = 0xFF) times should give about 0.5 seconds at a base clockrate of 16MHz of the Arduino Atmega328p. The code works, but it turns the LED on and of at a rate of 1 second, (1 sec on 1 sec off). I do not understand why.

# Answer
> 3 votes
* `PIND = 1;` toggles the state of bit 0 of `PORTD`.
* `PIND = 0;` does nothing at all; no toggling of any pins.

So you're simply just not toggling as often as you think. Your delay itself is otherwise fine. Change `PIND = 0;` to `PIND = 1;` and it will work as expected. Having done that you can get rid of one set of `PIND = 1;` and `wait_func();` call.

Alternately, if you want to follow the current form of the code, set and clear the bit on `PORTD` directly:

```
while(1){
  PORTD &= ~1; // or &= 0xFE
  wait_func();
  PORTD |=  1;
  wait_func();
}

```

For what it's worth:

* The semicolon after your while loop does nothing.
* The `time_unit` should probably be an `unsigned char` / `uint8_t`.
* Unless you're running really tight on code space, it's probably best not to rely on the prior state of the timer hardware registers.

---
Tags: interrupt, atmega328, timers
---


# Question
Title: I need to Get my changed SSID and Password in my Serial monitor
I have this(Wifi Manager - Autoconnect IP) program run in my arduino IDE. And I get the output in serial monitor as this

Can Anyone help me in displaying my SSID and PASS in this serial monitor output?

My code is this

```
#include <ESP8266WiFi.h>          //https://github.com/esp8266/Arduino

//needed for library
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>         //https://github.com/tzapu/WiFiManager

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

    //WiFiManager
    //Local intialization. Once its business is done, there is no need to keep it around
    WiFiManager wifiManager;
    //reset saved settings
    //wifiManager.resetSettings();

    //set custom ip for portal
    //wifiManager.setAPStaticIPConfig(IPAddress(10,0,1,1), IPAddress(10,0,1,1), IPAddress(255,255,255,0));

    //fetches ssid and pass from eeprom and tries to connect
    //if it does not connect it starts an access point with the specified name
    //here  "AutoConnectAP"
    //and goes into a blocking loop awaiting configuration
    wifiManager.autoConnect("AutoConnectAP");
    //or use this for auto generated name ESP + ChipID
    //wifiManager.autoConnect();

    //if you get here you have connected to the WiFi
    Serial.println("connected...yeey :)");
}

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

}

I am using WIFImanager library example - Autoconnect

```

# Answer
> 1 votes
You can use functions SSID() and psk() which are available on the WiFi object as documented here.

Put these lines in setup() after `wifiManager.autoConnect`:

```
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
Serial.print("psk: ");
Serial.println(WiFi.psk());

```

---
Tags: wifi, nodemcu
---


# Question
Title: How to flash pre-compiled bin files into NodeMCU using Ardunio IDE
How to flash pre-compiled binary into NodeMCU using Ardunio IDE. Since every time it require to compile and flash it. Is there way to flash binary alone to nodeMCU via Arduino IDE ?

One can export binary file from IDE -\> Sketch -\> Export Compiled Binary. Binary will be copied into working directory. U can check the path Sketchbook location in File -\> Preferences. But how to flash binary alone to nodeMCU.

I have fashed using esptool.py from linux. But is there a way to flash from IDE for handy ?

# Answer
> 1 votes
You can't flash precompiled binary with Arduino IDE, you have to use esptool.py from the command line.

---
Tags: arduino-ide, nodemcu
---


# Question
Title: How does while(analogRead(A0)) function in this code?
A sine wave is being fed to `A0` and I would like to calculate the frequency. If a certain threshold is crossed, start the timer.....count 5 such crossings.....then stop the timer. The code is attached. Even though I understand `while()` with logical operators such as `while(State<5)` (shown in code), I do not understand the use of `while(analogRead(A0))`. I would like to know how it functions in relation the code? The program runs fine as it is. Tested this in Tinkercad, and got erroneous readings when `while(analogRead(A0))` was commented. Thank you so much for reading my question ^\_^.

```
void loop()
{

  while(State<5)
  {
    val=analogRead(A0);
    if(val>200)
    {
      Serial.println("Threshold Crossed");
      if(State==0)
      {
        Start_Time=millis();
      }
      State++;
      while(analogRead(A0)); //I DON'T UNDERSTAND THIS
    }
  }

End_Time=millis();

Period=(Start_Time-End_Time)/5;
Frequency=1000/(Start_Time-End_Time)
Serial.println(Frequency);

State=0;
}

```

# Answer
As you correctly note, `while` typically takes a bool as argument. However, mainly for historical reasons, C/C++ don't really differentiate between int and bool, and therefore conditions can be of integer type. Any condition, be it in a `while` or an `if`, can be of int type. The condition evaluates to true if it is not zero. So the condition `while(analogRead(A0));` loops (doing nothing) until `analogRead` returns 0.
> 3 votes

# Answer
What you have implemented, perhaps unknowingly, is called hysteresis. Your program spends most of its time in either of these two states:

1. It is continually running the outer `while` loop, and the value read is ≤ 200. It gets out of this state as soon as it reads a value larger than 200.
2. It is continually running the inner `while` loop, and the value read is \> 0. It gets out of this state only when `analogRead()` returns zero.

Hysteresis is a good way to reject noise when you want to detect a signal crossing a threshold. I would, however, recommend you use it in a more controlled manner. Specifically, the second threshold should probably be greater than zero, otherwise it won't be crossed unless the signal goes all the way down to ground level. At a minimum, you can replace the inner `while` loop with something like:

```
while (analogRead(A0) >= 100)
    /* wait until the signal gets low enough */;

```

For the record, this logic can be implemented in a *non-blocking* fashion, which would let the program do other things, like responding to button presses, while waiting for the transitions. For this, you need a variable to record the current state of the signal (say, `LOW` or `HIGH`) and record the state changes when the corresponding thresholds are crossed.

The sketch below implements this non-blocking technique in `loop()`, whereas `setup()` does block while waiting for the first `LOW``HIGH` transition:

```
const int LOW_THRESHOLD  = 100;
const int HIGH_THRESHOLD = 200;

uint8_t state;      // either LOW or HIGH
uint8_t count = 0;  // count the LOW -> HIGH transitions
uint32_t start_time;

void setup() {
    // Wait for the first LOW -> HIGH transition.
    while (analogRead(A0) >= LOW_THRESHOLD)
        /* Wait for the LOW state. */;
    while (analogRead(A0) < HIGH_THRESHOLD)
        /* Wait for the HIGH state. */;
    state = HIGH;

    // Record transition time.
    start_time = millis();
}

void loop() {
    // Record transitions.
    uint8_t val = analogRead(A0);
    if (state == HIGH && val < LOW_THRESHOLD) {
        state = LOW;
    } else if (state == LOW && val >= HIGH_THRESHOLD) {
        state = HIGH;
        ++count;
    }

    if (count >= 5) {
        // Report measured frequency.
        uint32_t end_time = millis();
        int frequency = 1000 * count / (end_time - start_time);
        Serial.println(frequency);

        // Prepare for the next round.
        start_time = end_time;
        count = 0;
    }
}

```
> 4 votes

---
Tags: arduino-uno
---


# Question
Title: Multi turn potentiometer are a pain should I use a incremental encoder instead?
I built a robotic arm, the problem is I want to rotate the base more than once in order to complete a job, so I figured out I could use multi turn potentiometer. The problem I am facing is the potentiometer is burning without any reason. I have a ton of burnt ones with me. Sometimes it is caused by soldering and sometimes the shaft testing rotates the potentiometer beyond its limits. While I could get the values precisely. I am trying to avoid the pain of buying more.

My question is if I can use incremental encoder, the electricity in my country is not that stable and I don't want to lose the values accumulated by the arduino. So does the encoder remembers the values or rotation or it starts afresh?

# Answer
Yes, you can use a rotary encoder. However, there are two kinds of rotoary encoder: absolute, and relative. Relative encoders are the small common ones you find being used for things like volume controls. They only give you "It moved clockwise x steps" kind of information, which is not ideal for your usage. What you need is an *absolute* rotary encoder. This is a far more complex device and is often used on the shaft of motors to give the current angle the motor is at. These usually use a *Gray code* to represent an absolute angle at a specific resolution (choose the resolution to meet your requirements) and will tell you (within that level of resolution) the exact angle your robot arm is at. You can rotate it as many times as you like and it will always give you the current angle (note: it can't tell you how many revolutions it's made, that is down to you to count, should you actually need to).
> 2 votes

---
Tags: arduino-uno, potentiometer, rotary-encoder
---


title: Program nodeMCU Over the Air (OTA)

text:
# Question
Title: Program nodeMCU Over the Air (OTA)
I have a Lolin NodeMCU V3 with a broken USB port: no power, no data.

It does show up on WIFI as `AI-thinker_xxx`, I can connect, but what can I do next?

Is there a way to program the NodeMCU Over the Air (OTA), or through some pins?

Description found here under V3

# Answer
If powering over Vin pin is working, you can use the board without USB.

ESP8266 is bootloaded over UART pins. These are pins marked RX or D9 and TX or D10 on the NodeMcu board. You can use USB to TTL serial adapter to bootload (flash) the esp8266. To put the esp in flashing mode hold the FLASH button and click the RST button and then release the FLASH button.

You can then upload a sketch with ArduinoOTA library and do following uploads over OTA. After USB upload of a sketch, reset the board with RST button before doing the first OTA upload.
> 1 votes

---
Tags: serial, uploading, nodemcu
---


# Question
Title: How do I connect my ESP32 cam to my old modem without using Wi-Fi?
I have an Arduino ESP32 cam that I want to use as a bird cam. I want to use my old Orcon wireless modem to connect with this cam. I will connect with cable from my computer to this modem. As my existing Wi-Fi is running on 5Ghz, I cannot connect to it with this cam. So I need some pointers on how to do. Thanks.

# Answer
> 1 votes
Use an FTDI programmer and communicate with a serial protocol like UART. The connection schematic can be found here. https://randomnerdtutorials.com/program-upload-code-esp32-cam/ However you would have to do some extra research work on making the serial communication with the ESP32.

So a nice way would be to buy a wifi module for your old computer and use it to connect to the wifi and program the ESP32 accordingly.

---
Tags: arduino-uno, esp32, communication
---


# Question
Title: Bootloader only works once with usb to serial module
When programming the Pro Mini using this USB-to-serial adapter the boot loader only works once. After the first programming the programmer is out of sync or not responding.

To be able to program the Pro Mini again I have to burn the bootloader using my Uno as an ISP.

Programming the Pro Mini through an Uno does not present the same problem.

Are the lock bits not being set properly or somehow overridden?

# Answer
> 1 votes
The module I had does not have a DTR signal. I mistook the RTS for DTR. Ordering correct module.

# Answer
> -1 votes
It sounds likely that the OP (long since gone...) was resetting the board manually to get the bootloader to run even that once; and that the bootloader allowed itself to be overwritten, a critical fuse got changed, or that one successful upload otherwise left itself or the board in an un-bootable state.

---
Tags: serial, usb, bootloader
---


# Question
Title: How can I play sound on Arduino with an SD card?(I have a problem with the sound)
I am working on a "personal assistant" with Arduino and I am having trouble playing sound from an SD card... I am using a shield called "Easy Shield UNO" by Simkeim, and it has an SD card reader on it. It does work because I tested it through the Serial monitor, but when I try to play sound, nothing happens. (The speaker does work) Can someone please help me check my code or something to see what is wrong?

Here is the code I found online, I only changed it a bit...

```
#include "SD.h"
#define SD_ChipSelectPin 10
#include "TMRpcm.h"
#include "SPI.h"

TMRpcm tmrpcm;

void setup(){
 tmrpcm.speakerPin = 7;
 Serial.begin(9600);

 tmrpcm.setVolume(255);
}
void loop() {
  if(!SD.begin(SD_ChipSelectPin)) {
    Serial.println("SD card not found");
    return;
}
  else{
    Serial.println("SD card reading sucess");
    tmrpcm.play("test1.wav");
  }
}

```

# Answer
I see three problems with your code:

* It doesn't make much sense to begin the SD card again and again in `loop()`. Please move that part to `setup()` or somewhere, where it isn't called on every loop iteration.
* You shouldn't call `tmrpcm.play()` in every `loop()` iteration. It doesn't wait for the song to be finished. It just starts the playing (which is controlled by a timer interrupt) and exits. And every call of it will start the file again at its start. So by calling it again and again in fast succession you don't leave enough time for the file to actually be played, until you play again from start. To prevent that you can use an if statement to only start, if there isn't a file playing currently:

```
  if(!tmrpcm.isPlaying()){
      tmrpcm.play("test1.wav");
  }

```
* You are choosing pin 7 as output pin, but you cannot choose the pin freely, because it has to be connected to the used Timer and thus being PWM capable. Thats not the case for pin 7. In the wiki of the TMRpcm library you can find the following line under "Functions":

```
  audio.speakerPin = 11;     set to 5,6,11 or 46 for Mega, 9 for Uno, Nano, etc.

```

So please connect your speaker to pin 9 and use `tmrpcm.speakerPin = 9;`.
> 2 votes

---
Tags: arduino-uno, sd-card, shields
---


title: Read bytes from PROGMEM array

text:
# Question
Title: Read bytes from PROGMEM array
**Disclaimer:** I just started using C++ and I'm a bit of a beginner. Keep that in mind as your answering.

So I recently bought my first Arduino. It's a customized one and it has an 8x8 display attached to it. To display something on the display, the company I bought it from recommends storing the instructions for the display in a two-dimensional byte array.

I now have a longer animation I want it to play, so I researched and found PROGMEM which lets me store much more data. So I write something along the lines of:

```
const byte frames[2][8] PROGMEM {
  {
    B10000100,
    B10000100,
    B10000100,
    B10000100,
    B10000100,
    B10000100,
    B10000100,
    B10000100,
  },
  {
    B10010100,
    B10010100,
    B10010100,
    B10010100,
    B10010100,
    B10010100,
    B10010100,
    B10010100,
  }
};

void setup() {
  arduino.begin();
}

void loop() {
  arduino.printImage(frames[0]);
  delay(1000);
  arduino.printImage(frames[1]);
  delay(1000);
}

```

After compiling, it throws a few errors at me:

```
warning: invalid conversion from 'const byte* {aka const unsigned char*}' to 'byte* {aka unsigned char*}' [-fpermissive]
   arduino.printImage(frames[0]);
                      ~~~~~~~~^

```

This did not worry me as much and I just ignored those. After uploading, however, the display just showed arbitrary patterns instead of the lines I told it to draw.

After I removed the PROGMEM, it worked flawlessly, however, the memory wasn't big enough to store the array (not the one I provided as an example).

I could think of two reasons:

1. In the official documentation of PROGMEM, it states that you have to get the variables back into memory. However, none of the methods they provided worked for me.
2. In a similar question on ASE, both answer and comments state that nested arrays aren't supported, but my knowledge of C++ isn't good enough to understand the answer.

# Answer
> 2 votes
On the question you are referencing, the accepted answer suggests to modify the library. This could be the most efficient option. A less invasive solution, however, would be to copy the data from the flash memory to RAM, and use the `printImage()` function as is.

Obviously, copying everything to RAM defeats the purpose of PROGMEM. But you only need to copy one frame at a time, and only hold it in memory for little more than the duration of the call to `printImage()`:

```
void printProgmemFrame(const byte flashFrame[8]) {
  byte ramFrame[8];
  memcpy_P(ramFrame, flashFrame, 8);
  arduino.printImage(ramFrame);
}

void loop() {
  printProgmemFrame(frames[0]);
  delay(1000);
  printProgmemFrame(frames[1]);
  delay(1000);
}

```

---
Tags: arduino-uno, c++, memory-usage, memory, progmem
---


# Question
Title: How to attempt connection to WiFi only once?
I am working on a garden timer project, I connect to WiFi once and if its successful show time from NTPClient or else show time from RTC.

I have been done the above, and it works in the sense that if I turn off the WiFi **while the program is running**, it switches to the RTC and back to NTPClient when WiFi is available again.

**PROBLEM-** If the WiFi is not available **when the board boots**, the program just waits for WiFi where I want it to use RTC.

Hardware-ESP8266 based NodeMCU, I2C RTC, I2C 16x2 LCD.

Software-Blynk

My code:-

```
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <DS3231.h>
#include <Wire.h>
#include "DHT.h"
#include "LiquidCrystal_PCF8574.h"

#define BLYNK_PRINT Serial
#define DHT_PIN_DATA  12
// LCD definitions
#define LCD_ADDRESS 0x27
#define LCD_ROWS 2
#define LCD_COLUMNS 16
#define SCROLL_DELAY 150
#define BACKLIGHT 25
#define DHTTYPE DHT22

// Auth code and wifi credentials here
char auth[] = "ymri80lFL9_xjZppphf6WIRHtQ1kqEWOt9zBy";
char ssid[] = "Hotspot-82DB";
char pass[] = "qqnbkbbbk";
int autoSch;
int waterNow;
int morTime;
int afterTime;
int postNoon;
int eveTime;
int schTime;
int minStep;
int interval;
int count;
int flag = 0;
int soilHum = A0;
int waterItr;
int checkRun;
int waterItr1;
int oneTime;
bool h12Flag;
bool pmFlag;

unsigned long previousMillis = 0;
byte wifi[] = {
  B00001,
  B00001,
  B00101,
  B00101,
  B00101,
  B10101,
  B10101,
  B10101,

};

DHT dht(DHT_PIN_DATA, DHTTYPE);
LiquidCrystal_PCF8574 lcdI2C;
WiFiUDP ntpUDP;
DS3231 Clock;
NTPClient timeClient(ntpUDP, "in.pool.ntp.org", 19800, 600000);

BLYNK_CONNECTED() {
  Blynk.syncAll();
}

BLYNK_WRITE(V0)
{
  autoSch = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V1)
{
  morTime = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V2)
{
  afterTime = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V6)
{
  postNoon = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V3)
{
  eveTime = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V10)
{
  waterNow = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V4)
{
  schTime = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V7)
{
  minStep = param.asInt(); // assigning incoming value from pin V1 to a variable
}

void setup()
{
  Wire.begin();
  dht.begin();
  lcdI2C.begin(LCD_COLUMNS, LCD_ROWS, LCD_ADDRESS, BACKLIGHT);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);
  pinMode(14, OUTPUT);
  pinMode(15, OUTPUT);
  digitalWrite(14, LOW);
  digitalWrite(15, LOW);
  Blynk.virtualWrite(V5, 0);
  Blynk.virtualWrite(V8, 0);
  pinMode(0, INPUT_PULLUP);
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
      timeClient.begin();
  /*
    while ( WiFi.status() != WL_CONNECTED ) {
      delay ( 500 );
      Serial.print ( "." );
    }
  */

  Blynk.syncAll();
  lcdI2C.createChar(0, wifi);
}

void loop()
{
  Blynk.run();
  time_run();
  lcd();
  butPress();
  butCheck();
  /*if (waterNow != 1) {
    Blynk.virtualWrite(V10, 0);
    digitalWrite(14, LOW);
    Blynk.virtualWrite(V5, 0);
    Blynk.virtualWrite(V8, minStep * 60);
    }*/
  if (waterNow == 1) {
    if (waterItr < minStep * 60) {
      waterOn();
      waterItr++;
      delay(500);
    }
    else {
      waterOff();
    }

  } else if (autoSch == 0) {
    auto_run1();
    waterItr = 0;
  } else if (autoSch == 1) {
    sch_run2();
    waterItr = 0;
  } else {
    //Blynk.virtualWrite(V10, 0);
    waterItr = 0;
    digitalWrite(14, LOW);
    Blynk.virtualWrite(V5, 0);
  }
  Blynk.syncAll();

}

void butPress() {
  if (digitalRead(0) == LOW) {
    delay (100);
    if (flag == 0) {
      flag = 1;
    }
    else if (flag == 1) {
      flag = 0;
      waterItr1 = 0;
      digitalWrite(15, LOW);
      Blynk.virtualWrite(V5, 0);
    }
  }
}

void butCheck() {
  if (flag == 1) {
    digitalWrite(15, HIGH);
    Blynk.virtualWrite(V5, 255);
    lcdI2C.selectLine(2);
    lcdI2C.print("Wtr B Now :  ");
    lcdI2C.print(600 - waterItr1);
    if (waterItr1 < 600) {
      waterItr1++;
      delay(500);
    }
    else {
      waterItr1 = 0;
      flag = 0;
      digitalWrite(15, LOW);
      Blynk.virtualWrite(V5, 0);
    }
  }
}

void lcd() {
  if (oneTime == 0){

    oneTime=0;
    }
  //lcdI2C.clear();
  lcdI2C.setCursor(0, 0);

  if (WiFi.status() == WL_CONNECTED) {
    timeClient.update();
    lcdI2C.print("T:");
    lcdI2C.print(timeClient.getFormattedTime());
    Clock.setHour(timeClient.getHours());
    Clock.setMinute(timeClient.getMinutes());
    Clock.setSecond(timeClient.getSeconds());
  } else {
lcdI2C.print("R:");
lcdI2C.print(Clock.getHour(h12Flag, pmFlag)); lcdI2C.print(":"); lcdI2C.print(Clock.getMinute()); lcdI2C.print(":"); lcdI2C.print(Clock.getSecond());
  }
  if (autoSch == 0) {
    lcdI2C.setCursor(10, 0);
    lcdI2C.print(" Auto   ");
  } else {
    lcdI2C.print(" Sch   ");
  }

  if (WiFi.status() == WL_CONNECTED) {
    lcdI2C.setCursor(15, 0);
    lcdI2C.write(0);
  }

  if (digitalRead(14) == 1) {
    lcdI2C.selectLine(2);
    lcdI2C.print("Wtr Now           ");
  }
  else
  {
    if (int(timeClient.getHours()) < 6 && morTime == 1 && autoSch == 0) {
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 6a ");
    } else if (int(timeClient.getHours()) < 12 && afterTime == 1 && autoSch == 0) {
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 12n ");
    } else if (int(timeClient.getHours()) < 14 && postNoon == 1 && autoSch == 0) {
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at:14pn ");
    } else if (int(timeClient.getHours()) < 18 && eveTime == 1 && autoSch == 0) {
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 18e ");
    } else if (int(timeClient.getHours()) >= 18 && morTime == 1 && autoSch == 0) {
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 6a ");
    } else if (int(timeClient.getHours()) >= 6 && morTime == 1 && autoSch == 0) {
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 6a ");
    } else if (int(timeClient.getHours()) >= 12 && afterTime == 1 && autoSch == 0) {
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 12a ");
    }   else if (int(timeClient.getHours()) >= 14 && postNoon == 1 && autoSch == 0) {
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 14a ");
    }  else if (int(timeClient.getHours()) >= 18 && eveTime == 1 && autoSch == 0) {
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 18a ");
    } else {
      if (autoSch == 0) {
        lcdI2C.selectLine(2);
        lcdI2C.print("  Switch to Sch  ");
      } else {
        lcdI2C.selectLine(2);
        lcdI2C.print("  Schedule mode ");
      }
    }
  }
}

void waterOn() {
  lcdI2C.setCursor(0, 0);
  digitalWrite(14, HIGH);
  Blynk.virtualWrite(V5, 255);
  lcdI2C.selectLine(2);
  lcdI2C.print("Wtr Now :");
  lcdI2C.print((minStep * 60)  - waterItr);
  Blynk.virtualWrite(V8, (minStep * 60)  - waterItr);
  Blynk.syncAll();
}

void waterOff() {
  Blynk.virtualWrite(V10, 0);
  digitalWrite(14, LOW);
  Blynk.virtualWrite(V5, 0);
  Blynk.virtualWrite(V8, 0);
  waterItr = 0;
  Blynk.syncAll();
}

void sch_run2() {
  if (schTime == 1) {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    checkRun = 1;
    Blynk.syncAll();
  } else if (schTime == 0) {
    checkRun = 0;
    if (checkRun == 0) {
      digitalWrite(14, LOW);
      Blynk.virtualWrite(V5, 0);
      Blynk.syncAll();
    }
  }
}

void time_run() {
  Blynk.virtualWrite(V11, int(timeClient.getHours()));
  Blynk.virtualWrite(V12, int(timeClient.getMinutes()));
  Blynk.virtualWrite(V13, float(dht.readTempC()));
  Blynk.virtualWrite(V14, float(dht.readHumidity()));
}

void auto_run1() {
  if (morTime == 1 && String(timeClient.getFormattedTime()) > "06:00:00" && String(timeClient.getFormattedTime()) < "06:20:00") {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    checkRun = 1;
  }
  else if (afterTime == 1 && String(timeClient.getFormattedTime()) > "12:00:00" && String(timeClient.getFormattedTime()) < "12:20:00") {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    checkRun = 1;
  }
  else if (postNoon == 1 && String(timeClient.getFormattedTime()) > "14:00:00" && String(timeClient.getFormattedTime()) < "14:20:00") {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    checkRun = 1;
  }
  else if (eveTime == 1 && String(timeClient.getFormattedTime()) > "11:49:00" && String(timeClient.getFormattedTime()) < "11:50:00") {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    checkRun = 1;
  }
  else  {
    //(String(timeClient.getFormattedTime() == "06:20:00" || "12:20:00" || "14:20:00" || "13:48:00"))
    //waterNowrun();
    checkRun = 0;
    if (checkRun == 0) {
      //Blynk.virtualWrite(V10, 0);
      digitalWrite(14, LOW);
      Blynk.virtualWrite(V5, 0);
      Blynk.virtualWrite(V8, 0);
      Blynk.syncAll();
    }
  }
}

```

# Answer
Instead of using `blynk.begin()` use `WiFi.begin()` and `blynk.config()` to achieve non-blocking code

```
void setup(){
//  Blynk.begin(auth, ssid, pass); don't use this
  WiFi.begin(ssid, pass);
  while ( WiFi.status() != WL_CONNECTED ) {
    delay ( 500 );
    Serial.print ( "." );
  }
  Blynk.config(auth);
}

```
> 2 votes

---
Tags: wifi, nodemcu, rtc, blynk, ntpclient
---


# Question
Title: What is the overhead of a saturated serial connection at 256k baud?
I have am putting together multiple arduinos on a RS485 network (connected to Rx/Tx on the arduino and using Serial - connection via one of these https://www.ebay.co.uk/itm/272929871278) - RS485 because it is spread over quite a distance - total linear wiring approx 200m.

My question is: If I have Master, Slave1 and Slave2 on the bus, and the link is running at full speed in comms between Master and Slave1 - then what is the expected interrupt handler overhead on Slave2 in putting the incoming traffic into the ring buffer? (since as it is RS485 all devices not sending see all the traffic)

My "finger in the air" estimate is around 5%-15% at 256k baud and would scale fairly linearly with baud rate.

Does anyone have a definitive answer on this or can point to any profiling done on this?

# Answer
> 1 votes
So I decided a little empirical testing was in order. This is using a nano (328P)

Using a simple for loop in loop() (calculating the squares of 0 to 255) over 10 seconds with and without there being serial traffic and at different speeds.

Note: this is without any inspection of the ring buffer on incoming data - just measuring the overhead of there being traffic on the wire. The traffic on the wire was the maximum an arduino mega was able to send at that baud rate.

```
No load: 2600462 iterations
256k: 2381219 iterations
2M: 1349142 iterations

256k takes 8.5% of the runtime
2M takes 48% of the runtime

```

Code block as requested for the unit doing the timing (it includes calls to the libraries I am using for my environment, but I am sure you can abstract those away to something else and should not be significant to the stats)

```
uint32_t start_time;
void setup() {
    init_serial();
    start_time = millis();
}

uint32_t count = 0;
uint16_t foo;
void loop() {
    byte buff[MESSAGE_BUFFER_SIZE];
    if (millis() - start_time < 10000){
        for(int i = 0; i<256; i++) {
            foo = i * i;
        }
        count++;
    }
    else {
        if (getMessage(buff)) {
            char msg[30];
            sprintf(msg, "Count: %lu ---", count);
            send_debug_message(msg);
        }
    }
}

```

---
Tags: serial, performance
---


# Question
Title: Cannot enable watchdog timer when using Arduino 8mhz bootloader
I am running my Arduino projects like this:

**My goal is to have this project run at 8mhz so that (1) battery last longer and (2) so that I am following the specs.** I was able to burn a 8mhz bootloader to my Atmega328 chip thanks to this video: https://www.youtube.com/watch?v=fzZ2TR\_mwgs

After following the video I am able to run sketches at 8mhz and they consume less current. But my original project crashes to the point where I have to burn a bootloader again. Even if I press the reset button it will not become responsive. I have discovered that this line of code is the one that makes my atmega328 chip unresponsive:

```
wdt_enable(WDTO_4S);  // #include <avr/wdt.h>

```

I find out about that because removing that line made my project work. That line enables waking up after 4 seconds. So I basically perform some work and go to sleep for 4 seconds. I then repeat the same steps forever in order to save battery. So before going to sleep I execute this:

```
// wake up from sleep after 4 seconds
wdt_enable(WDTO_4S);

// go to deep sleep
if (true)
{
    // BIG difference when in sleep
    // Diable ADC (analog to digital converter)
    ADCSRA &= ~(1 << 7);

    SMCR |= (1 << 2); // power down mode
    SMCR |= 1;        // enable sleep;

    // BOD DISABLE (big difference when in sleep only)
    MCUCR |= (3 << 5);                      // set both BODS and BODSE at the same time
    MCUCR = (MCUCR & ~(1 << 5)) | (1 << 6); // then set the BODS bit and clear the BOSE bit at the same time

    __asm__ __volatile__("sleep");
}

// this line will not execute....

```

**Anyways how could I solve this problem? Should I keep the original project and just replace the crystal to 8mhz?** I will then have to keep in mind that all delays will be half the speed correct?

# Answer
Try power cycling the UNO when the boards stops responding. That should reset the watchdog settings. Just pressing reset doesn't disable the watchdog, as far as I know.

The bootloader doesn't know you enabled the watchdog, and if it takes more that 4 seconds, you get stuck in an infinite loop. You could try using the optiboot bootloader instead. That one resets the watchdog when it runs.

Thirdly, you could enable the watchdog interrupt. If you do that the MCU will still wake up after 4 seconds of sleep, but it will resume you code, instead of doing a reset. Doing this will make it so the bootloader only runs once.
> 1 votes

# Answer
Your delays are probably what is killing you. If you have delays longer than the WDT time that will cause a WDT timeout. Remember the Delay function does nothing but burn time, nothing else is processed. Go to the Millis or something like that as recommended many times in the Arduino forums.
> 1 votes

---
Tags: arduino-uno
---


# Question
Title: Program ATTiny85 running at 16 KILOhertz
I set the fuses of my attiny85 so it uses the internal 128khz clock, prescaled so it is 16kHz. I set the CKOUT fuse too so I can check the clock using an oscilloscope on pin 3 and yes it is 16kHz.

Now my problem is I have no option in the Arduino IDE to compile my code for 16kHz clock speed. The slowest I have is 128khz, which causes the "blink" sketch to run for 8 seconds up, 8 seconds low on my attiny instead of 1 second.

I tried with "attiny" from David A. Mellis using https://raw.githubusercontent.com/damellis/attiny/ide-1.6.x-boards-manager/package\_damellis\_attiny\_index.json (Slowest : 1Mhz) and "ATTinyCore" from Spence Konde using http://drazzy.com/package\_drazzy.com\_index.json (Slowest : 128khz).

Does someone know how I can set my Arduino IDE to compile the code for an attiny85 using the 16khz internal clock ?

(Please, no question "why use a 16khz clock ?". The point is, this chip may be set to 16khz clock, so it should be possible to program it to use such clock speed)

Thank you.

# Answer
The Arduino core you've referenced (and pretty much all other AVR Arduino cores too) specify the clock frequency that a particular selected board is running at in the `boards.txt` file. The `platform.txt` file then retrieves that value and creates the `F_CPU` macro with the clock frequency in hertz as a value.

For the ATTinyCore by Spence Konde, the ATTiny85 board definition is the `attinyx5` section. There, you can either add a new clock selection menu item or modify the settings of an existing one, e.g.

https://github.com/SpenceKonde/ATTinyCore/blob/f5eabc8fb97e8fd72f1782a5e97345729e42ec47/avr/boards.txt#L409-L412

```
attinyx5.menu.clock.128internal=128 kHz (internal WDT)
attinyx5.menu.clock.128internal.bootloader.low_fuses=0xC4
attinyx5.menu.clock.128internal.build.f_cpu=128000L
attinyx5.menu.clock.128internal.build.clocksource=3

```

The file is locally under `C:\Users\<user>\AppData\Local\Arduino15\packages\ATTinyCore\hardware\avr\1.5.2`.

There, `f_cpu` should be modified to `16000L` for 16KHz, the `low_fuses` (lfuse) setting should be set to `0x24` and the text "128 kHz" should be adapted too. This is working per the comment on the question.

On a final note, you should create an issue at the core's repo to have a 16kHz added by default.

Also, you might find it easier to work with PlatformIO (+VSCode) instead of the Arduino IDE. A getting started page is here. In PlatformIO, instead of having to modify the internal `boards.txt` file, you can create a project configuration file (`platformio.ini`) in which you specify the same thing setting.

```
[env:attiny85]
platform = atmelavr
board = attiny85
framework = arduino
board_build.f_cpu = 16000L
; for upload settings, see
; https://docs.platformio.org/en/latest/platforms/atmelavr.html#upload-using-programmer

```
> 1 votes

---
Tags: arduino-ide, attiny85
---


# Question
Title: 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);
  }
}

```

# Answer
> 0 votes
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.

---
Tags: sd-card, code-review, audio
---


# Question
Title: Nikon IR remote trigger (ML-L3) emulator not working
I have tried to follow along/reproduce the results from several sources for emulating the Nikon infrared remote trigger:

I can read the signal from my remote trigger, but I cannot reproduce it with my Arduino setup. The signal I can receive (w/ TSOP38238 receiver diode) matches all of the signals given by the links above (there is some expected variance in pulse durations).

**I don't think my hardware is at fault:**

* TSOP38238 receives @ 950 nm
* my IR LED is 940-950 nm per datasheet
* my IR LED works (I can see it emitting when I point it at my phone camera)

simulate this circuit – Schematic created using CircuitLab

**My Code:**

I have tried the code given in the links above, most don't use Port Manipulation and instead trial-and-error the delay durations to account for the overhead in Arduino functions. I have experimented with different values of the `wait` variable (8-13 microseconds) but have not gotten it working so far. I prefer to have my code versatile like this (no hard coded durations) so I can use it with other remotes in the future.

```
uint16_t Signal[] = [2050, 27800, 430, 1650, 430, 3650, 430, 65000]; // ON & OFF pulse durations (microseconds)
uint8_t wait = 13; // duration (microseconds) between pin state changes

// the setup function runs once when you press reset or power the board
void setup() {
    DDRB = B00000001; // set digital pin 8 to output
    PORTB = B00000000; // set digital pin 8 LOW
    Serial.begin(9600); // start serial monitor
}

// the loop function runs over and over again forever
void loop() {
    delay(1500); // wait a bit between sending signal
    sendSignal();
    sendSignal();
    // send signal twice, this is what the actual remote does
    Serial.println("Signal sent"); // message saying signal was sent
}

// function that sends the signal
void sendSignal(void) {
    for (int i = 0; i < sizeof(Signal)/sizeof(Signal[0]); i++) { // for each element in Signal array
        if (i%2 > 0) { // odd numbered index, is an OFF pulse
            PORTB = B00000000; // set digital pin 8 LOW
            delayMicroseconds(Signal[i]); // delay for OFF pulse duration
        } else { // even numbered index (including i=0), is an ON pulse, 38 kHz (26.3 usec period), 50% duty cycle
            unsigned long currentTime = micros(); // get current time
            while (micros() - currentTime < (unsigned long)Signal[i]) { // while still in ON pulse duration
                PORTB = B00000001; // set digital pin 8 HIGH
                delayMicroseconds(wait); // leave ON for time
                PORTB = B00000000; // set digital pin 8 LOW
                delayMicroseconds(wait); // leave OFF for time
            }
        }
    }
}

```

I hold my camera in direct line of sight of the LED (not blocking the receiver on the camera) from distances of ~2in to ~3ft away without success.

Has anyone tried this before? Is there a mistake in my approach or code?

# Answer
> 1 votes
Got it working. The problems were the `delayMicroseconds` input being too large (see comments) and the frequency mismatches.

I set up a script to time the code segments of interest and that allowed me to select the best wait duration. It looks like this:

```
while (i < 256) {
    /* your code to time here */
    i++;
}
i = 0;
unsigned long time = 10000000 + micros();
Serial.println(time);

```

Make sure to time the empty loop and subtract that from your readings w/ code. Take the difference between `time` read outs, subtract the printing statement overhead (which is dependent on how many digits it is printing, hence the `10000000 + micros()` to keep # of digits constant) and divide by 256.

I measured 4 different combinations to find the closest frequency match:

| Command Type: | Wait duration (micro seconds): | Frequency (Hz): | % difference from 38 kHz |
| --- | --- | --- | --- |
| Port Manipulation | 14 | 36990 | -2.7 % |
| Port Manipulation | 13 | 39960 | 5.2 % |
| digitalWrite | 11 | 35980 | -5.3 % |
| **digitalWrite** | **10** | **38790** | **2.1 %** |

The final code ended up looking a lot like the one from this link; counting off cycles of the on-off 38 kHz pulse.

---
Tags: arduino-uno, ir, remote-control, camera
---


# Question
Title: Programming ATMega4809 via Atmel-ICE with Hex File from Arduino IDE - why doesn't the code loop / work?
**Background**

I am programming a 40-pin ATMega4809 (datasheet) using ATMEL-ICE programmer. I'm simply using the Atmel Studio to upload a HEX file to the chip. I generate the HEX file using the Arduino IDE.

I'm using the very simple blink sample sketch with a slight modification which uses a different output pin for the LED.

```
const byte LED = 6;

void setup() {
  // initialize digital pin LED as an output.
  pinMode(LED, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(LED, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

```

I have a LED (with resistor) connected to PA6 on the ATMega4809.

**Code Result**

I use the Export compiled binary choice in the Arduino IDE to generate the HEX file.

I then use Atmel Studio to upload the HEX file to the ATMega4809.

When I do, the program runs and the LED turns on.

However, I never see the LED turn off (blink).

Do you know why this might be true?

**Things I've Tried**

1. I've tried increasing the delay value to see if internal crystal is set different and the timing is different or something.
2. I've set the internal crystal to different values (ranging from 1Mhz to 20Mhz) and haven't seen any difference.
3. I've considered that it could just be not looping, so I've tried various things to see if that were true or not.
4. I've placed all of the code in the `setup()` function to see if it would working differently -- it didn't, it still just turned the LED on but never off.
5. I've tried turning LED **on** in `setup()` & **off** in `loop()` to insure both are at least running once and they are.

**NOTE**: I know the HEX file is being properly uploaded because when I alter the program and upload different ones (turn on/turn off led) then the code does seem to either turn the LED on or off. I've also verified the code using Atmel Studio -- reading the chip's memory out to a file and doing diff.

# Answer
Because of the great question asked by @Juraj I thought about how pins are mapped (and that I was probably thinking wrong about that mapping).

I searched for and found the following diagram:

Notice that D7 is mapped to PA1

I switched the code to use Digital Pin 7 (`const byte LED = 7;`) I then switched the LED in the circuit to be connected (with appropriate resistor) to PA1 which is actually PIN 34 (on my ATMega4809 40 pin).

Back in the Arduino IDE I switched the board to Nano Every (which also uses the ATMega4809).

I compiled the code. Then I exported the HEX file and uploaded it to the 40 pin ATMega4809 using Atmel Studio.

**With Bootloader Or Without**

**Didn't Work: With Bootloader**

The first time I tried it i selected the HEX file which contains the bootloader and it didn't work. The LED didn't flash.

**Did Work: Without Bootloader**

I then tried uploading the HEX file which does not contain the bootloader and the LED began flashing as expected.

Solved! All because of the great question which got me thinking better. Thanks, Here's a very fast video of it in action (youtube).
> 1 votes

---
Tags: arduino-mega, arduino-nano, atmel-studio
---


# Question
Title: Arduino Nano Every Vin 5V fixes I2c problems
I had problems with connecting my devices via I2C. The "requestfrom" constantly hanged and the endtransmission sometimes gave NACK responses.

After disconnecting the devices from 12V and powering one of them via USB (vin with which it was connected to the other arduino's became 3.8V) they stopped misbehaving and worked together in harmony.

How is this possible? Am I missing something? An Arduino Nano Every should be driven between 6-21V?

All devices are "Arduino Nano Every"'s. They used to get 12V directly on Vin and are connected together in a chain by Vin,GND,A5(SCK),A4(SDA)

The master is in the middle of the chain so that the distance is max 20cm.

I also tried powering them via vin with 9V and 5V. Had the same issue.

Already big thanks for the help.

# Answer
> 0 votes
SO... In the datasheet it says you should use 7-21V on VIN. This gave the problem. I powered the arduinos directly from 5V on the vin. This fixed all I2C problems. Haven't had any problems anymore after changing this.

cheers to all.

---
Tags: arduino-nano, i2c, usb, voltage
---


# Question
Title: Run esp32 without freeRTOS in order to execute something faster
I am currently running Arduino with this configuration (using atmega328p chip):

Basically, my program wakes up every 2 seconds for 10ms each time. If during those 10ms it finds and event of interest it will perform some actions. Because it only takes 10ms to check for those events the battery lasts for over a year even though it wakes up every 2 seconds.

Anyways now I want to migrate that same project to an esp32. I am not able to do so because the esp32 takes about 40ms to run the startup function plus the 10ms it takes to check for events it will be 50ms. **Waking up for 50ms every 2 seconds will drain my battery to fast!** Is there a way I can run some code before the setup function? I believe the reason it takes 40ms is because it uses freeRTOS. Is there a way I can run the esp32 without freeRTOS just like the atmega328P? I don't mind losing WiFi/bluetooth functionality. Moreover, the esp32 chip is able to run at lower voltages than the atmega328p and this makes it very convenient when using batteries. For example now I would be able to use 2 AA batteries instead of 3 that I need now.

# Answer
> 1 votes
What I am looking for is "Deep Sleep Wake Stubs"

Here is an example that works that I found from the internet:

```
#include <Arduino.h>

#include "driver/rtc_io.h"
#include "rom/ets_sys.h"
#include "rom/rtc.h"
#include "esp_attr.h"
#include "esp_sleep.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "soc/rtc.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/rtc_io_reg.h"
#include "soc/timer_group_reg.h"
#include "soc/uart_reg.h"
#include <stdio.h>
#include <string.h>

RTC_IRAM_ATTR void deepsleep_for_us(uint64_t duration_us);

#define S_TO_NS 1000000ULL
// Boot counter value, stored in RTC_SLOW_MEM
static size_t RTC_DATA_ATTR boots;
static size_t RTC_DATA_ATTR max_boots;

// Function which runs after exit from deep sleep
static void RTC_IRAM_ATTR wake_stub();
void setup(){

}
void loop(void) {
  if (rtc_get_reset_reason(0) == DEEPSLEEP_RESET) {
    printf("I'm back! Wake up from (extended) deep sleep. Should be 60s elapsed.\n");
    printf("Boot count=%d\n", boots);
    while (1) {
      ;
    }
  } else {
    printf("Not a deep sleep wake up\n");
  }

  printf("Going to deep sleep for 5x12=60s second\n");
  boots = 0;
  max_boots = 12;
  // hold high during deep sleep
  esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);

  // Set the wake stub function
  esp_set_deep_sleep_wake_stub(&wake_stub);

  esp_sleep_enable_timer_wakeup(5 * S_TO_NS);
  esp_deep_sleep_start();
}

static const char RTC_RODATA_ATTR wake_fmt_str[] = "count=%d\n";
static const char RTC_RODATA_ATTR sleep_fmt_str[] = "sleeping\n";

static void RTC_IRAM_ATTR wake_stub() {
  // Increment the Boot counter
  boots++;
  // and print the Boot counter value:
  ets_printf(wake_fmt_str, boots);

  if (boots >= max_boots) {
    // On revision 0 of ESP32, this function must be called:
    esp_default_wake_deep_sleep();
    // Return from the wake stub function to continue
    // booting the firmware.
    return;
  }

  // Print status
  ets_printf(sleep_fmt_str);
  // Wait for UART to end transmitting.
  // feed the watchdog
  REG_WRITE(TIMG_WDTFEED_REG(0), 1);
  while (REG_GET_FIELD(UART_STATUS_REG(0), UART_ST_UTX_OUT)) {

  }
  deepsleep_for_us(5 * S_TO_NS);

  // Set the pointer of the wake stub function.
  REG_WRITE(RTC_ENTRY_ADDR_REG, (uint32_t)&wake_stub);
  // Go to sleep.
  CLEAR_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_SLEEP_EN);
  SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_SLEEP_EN);
  // A few CPU cycles may be necessary for the sleep to start...
  while (true) {
    ;
  }
  // never reaches here.
}

// Comment out this line if you're using the internal RTC RC (150KHz) oscillator.
//#define USE_EXTERNAL_RTC_CRYSTAL
#ifdef USE_EXTERNAL_RTC_CRYSTAL
#define DEEP_SLEEP_TIME_OVERHEAD_US (650 + 100 * 240 / CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ)
#else
#define DEEP_SLEEP_TIME_OVERHEAD_US (250 + 100 * 240 / CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ)
#endif // USE_EXTERNAL_RTC_CRYSTAL

RTC_IRAM_ATTR void deepsleep_for_us(uint64_t duration_us) {
  // Feed watchdog
  REG_WRITE(TIMG_WDTFEED_REG(0), 1);
  // Get RTC calibration
  uint32_t period = REG_READ(RTC_SLOW_CLK_CAL_REG);
  // Calculate sleep duration in microseconds
  int64_t sleep_duration = (int64_t)duration_us - (int64_t)DEEP_SLEEP_TIME_OVERHEAD_US;
  if (sleep_duration < 0) {
    sleep_duration = 0;
  }
  // Convert microseconds to RTC clock cycles
  int64_t rtc_count_delta = (sleep_duration << RTC_CLK_CAL_FRACT) / period;
  // Feed watchdog
  REG_WRITE(TIMG_WDTFEED_REG(0), 1);
  // Get current RTC time
  SET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_UPDATE);
  while (GET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_VALID) == 0) {
    ets_delay_us(1);
  }
  SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG, RTC_CNTL_TIME_VALID_INT_CLR);
  uint64_t now = READ_PERI_REG(RTC_CNTL_TIME0_REG);
  now |= ((uint64_t)READ_PERI_REG(RTC_CNTL_TIME1_REG)) << 32;
  // Set wakeup time
  uint64_t future = now + rtc_count_delta;
  WRITE_PERI_REG(RTC_CNTL_SLP_TIMER0_REG, future & UINT32_MAX);
  WRITE_PERI_REG(RTC_CNTL_SLP_TIMER1_REG, future >> 32);
  // Start RTC deepsleep timer
  REG_SET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, RTC_CNTL_WAKEUP_ENA, RTC_TIMER_TRIG_EN); // Wake up on timer
  WRITE_PERI_REG(RTC_CNTL_SLP_REJECT_CONF_REG, 0);                                  // Clear sleep rejection cause
  // Go to sleep
  CLEAR_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_SLEEP_EN);
  SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_SLEEP_EN);
}

```

I will try to see how hard is to run my code that checks for events on the `wake_stub` that runs before anything else.

---
Tags: esp32
---


title: False interrupt triggering Arduino Mega

text:
# Question
Title: False interrupt triggering Arduino Mega
I am using Arduino mega with 4 interrupts to find the rotation speed of 4 motors . For this I have used INT2, INT3, INT4, INT5 and the code for the same is given below

```
struct Pulse {
  uint32_t last_toggle;
  uint32_t width;
  bool stateHigh;
  uint32_t get_width() {
    noInterrupts();
    uint32_t width_copy = width;
    interrupts();
    return width_copy;
  }
};

Pulse ch1, ch2, ch3, ch4;

void pin_initialization() {
  // Four engine configuration
  pinMode(19, INPUT_PULLUP);
  pinMode(18, INPUT_PULLUP);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);

}

volatile uint32_t ovfCount = 0;
ISR(TIMER3_OVF_vect) {
  ovfCount++;
}

void timer3_initialization() {
  TCCR3A = 0x00;

  TCNT3 = 0x1FF; // from datasheet
  TIFR3 = _BV(TOV3);
  TIMSK3 = _BV(TOIE3); // overflow enable
  TCCR3B = B00000011; // 64 prescaling
}

void pulseWidthCalculator(Pulse *channel){
  unsigned char sreg;
  sreg = SREG;
  cli();
  uint16_t tcnt3 = TCNT3;
  SREG = sreg;
  uint32_t ovf_count = ovfCount;

  if (bit_is_set(TIFR3, TOV3) && tcnt3 < 32768) {
    ovf_count++;
  }

  uint32_t time = ovf_count << 16 | tcnt3;

  if (!channel->stateHigh) {  // first high
    channel->stateHigh = true;
  } else if ( channel->stateHigh) {  // second High
    channel->width = time - channel->last_toggle;
    channel->stateHigh = false;
  }
  channel->last_toggle = time;
}

ISR(INT2_vect) {
  pulseWidthCalculator(&ch1);
}

ISR(INT3_vect) {
  pulseWidthCalculator(&ch2);
}

ISR(INT4_vect) {
  pulseWidthCalculator(&ch3);
}

ISR(INT5_vect) {
  pulseWidthCalculator(&ch4);
}

void externalInterrputInitialization() {
  EIFR = _BV(INTF2) | _BV(INTF3) | _BV(INTF4) | _BV(INTF5);
  EICRA = 0; EICRB = 0;
  EICRA = B10100000;
  EICRB = B00001010;
  EIMSK = B00111100;
}

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

  pin_initialization();
  delayMicroseconds(10);

  externalInterrputInitialization();
  delayMicroseconds(10);

  timer3_initialization();
  delayMicroseconds(10);

}

void loop() {
  String a = String(15e6/ch1.get_width());
  a += " ";
  a += String(15e6/ch2.get_width());
  a += " ";
  a += String(15e6/ch3.get_width());
  a += " ";
  a += String(15e6/ch4.get_width());

  Serial.println(a);

}

```

The issue I am facing is , whenever I give a signal to INT2, INT3 is also getting triggered, same with INT4, INT5 also getting triggered without signal .

What I am I missing here, ?

Should I make my channels ch1, ch2 , ch3, ch4 to volatile or not.? like `volatile Pulse ch1, ch2, ch3, ch4`

* Any thing wrong with `OUTPUT_PULLUP`

# Answer
You have the right idea to atomically obtain a copy of the data that is updated by the interrupt:

```
  unsigned char sreg;
  sreg = SREG;
  cli();
  uint16_t tcnt3 = TCNT3;
  SREG = sreg;
  uint32_t ovf_count = ovfCount;

```

...but the last two lines should be swapped to keep the copying operation within the non-interrupt section:

```
  unsigned char sreg;
  sreg = SREG;                    // Save interrupt state.
  cli();                          // Disable interrupts.
  uint16_t tcnt3 = TCNT3;         // Atomic operations.
  uint32_t ovf_count = ovfCount;
  SREG = sreg;                    // Restore interrupt state.

```

Though I notice you are calling that code from within an interrupt service routine so interrupts should already be disabled unless you are intending to use nested interrupts.

The false interrupt could be caused by crosstalk between INT2 and INT3. You could confirm this by using an oscilloscope. Keep the signal wires separate to avoid crosstalk.

You could also try stronger external pull-ups such as 10K or 1K. The Arduino internal pull-ups are weaker at about 20-50K Ohms.
> 1 votes

---
Tags: arduino-mega, interrupt, atmega2560
---


title: MPU 6050 only reads 0 in output

text:
# Question
Title: MPU 6050 only reads 0 in output
I am new to using MPU 6050. I am stuck at a basic code of getting readings from the sensor. The code I used is attached below. Its the one with GY 521 breakout board. Concluding that my sensor is broken I have changed sensor and now using the third one. Still no luck. FYI I have run the i2c scanner code to check whether arduino(nano) can detect the sensor. The code responds to all the sensors I tried. I have no clue what I am doing wrong. If someone could provide some suggestions it would be helpful

```
    MPU6050 Triple Axis Gyroscope & Accelerometer. Simple Gyroscope Example.
    Read more: http://www.jarzebski.pl/arduino/czujniki-i-sensory/3-osiowy-zyroskop-i-akcelerometr-mpu6050.html
    GIT: https://github.com/jarzebski/Arduino-MPU6050
    Web: http://www.jarzebski.pl
    (c) 2014 by Korneliusz Jarzebski
*/

#include <Wire.h>
#include <MPU6050.h>

MPU6050 mpu;

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

  // Initialize MPU6050
  Serial.println("Initialize MPU6050");
  while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
  {
    Serial.println("Could not find a valid MPU6050 sensor, check wiring!");
    delay(500);
  }

  // If you want, you can set gyroscope offsets
  // mpu.setGyroOffsetX(155);
  // mpu.setGyroOffsetY(15);
  // mpu.setGyroOffsetZ(15);

  // Calibrate gyroscope. The calibration must be at rest.
  // If you don't want calibrate, comment this line.
  mpu.calibrateGyro();

  // Set threshold sensivty. Default 3.
  // If you don't want use threshold, comment this line or set 0.
  mpu.setThreshold(3);

  // Check settings
  checkSettings();
}

void checkSettings()
{
  Serial.println();

  Serial.print(" * Sleep Mode:        ");
  Serial.println(mpu.getSleepEnabled() ? "Enabled" : "Disabled");

  Serial.print(" * Clock Source:      ");
  switch(mpu.getClockSource())
  {
    case MPU6050_CLOCK_KEEP_RESET:     Serial.println("Stops the clock and keeps the timing generator in reset"); break;
    case MPU6050_CLOCK_EXTERNAL_19MHZ: Serial.println("PLL with external 19.2MHz reference"); break;
    case MPU6050_CLOCK_EXTERNAL_32KHZ: Serial.println("PLL with external 32.768kHz reference"); break;
    case MPU6050_CLOCK_PLL_ZGYRO:      Serial.println("PLL with Z axis gyroscope reference"); break;
    case MPU6050_CLOCK_PLL_YGYRO:      Serial.println("PLL with Y axis gyroscope reference"); break;
    case MPU6050_CLOCK_PLL_XGYRO:      Serial.println("PLL with X axis gyroscope reference"); break;
    case MPU6050_CLOCK_INTERNAL_8MHZ:  Serial.println("Internal 8MHz oscillator"); break;
  }

  Serial.print(" * Gyroscope:         ");
  switch(mpu.getScale())
  {
    case MPU6050_SCALE_2000DPS:        Serial.println("2000 dps"); break;
    case MPU6050_SCALE_1000DPS:        Serial.println("1000 dps"); break;
    case MPU6050_SCALE_500DPS:         Serial.println("500 dps"); break;
    case MPU6050_SCALE_250DPS:         Serial.println("250 dps"); break;
  }

  Serial.print(" * Gyroscope offsets: ");
  Serial.print(mpu.getGyroOffsetX());
  Serial.print(" / ");
  Serial.print(mpu.getGyroOffsetY());
  Serial.print(" / ");
  Serial.println(mpu.getGyroOffsetZ());

  Serial.println();
}

void loop()
{
  Vector rawGyro = mpu.readRawGyro();
  Vector normGyro = mpu.readNormalizeGyro();

  Serial.print(" Xraw = ");
  Serial.print(rawGyro.XAxis);
  Serial.print(" Yraw = ");
  Serial.print(rawGyro.YAxis);
  Serial.print(" Zraw = ");
  Serial.println(rawGyro.ZAxis);

  Serial.print(" Xnorm = ");
  Serial.print(normGyro.XAxis);
  Serial.print(" Ynorm = ");
  Serial.print(normGyro.YAxis);
  Serial.print(" Znorm = ");
  Serial.println(normGyro.ZAxis);

  delay(10);
}

```

# Answer
I hope it is useful for debugging ...

Only a sketch I found (here), not remembering if I have tested ...

```
// MPU-6050 Short Example Sketch
// By Arduino User JohnChi
// August 17, 2014
// Public Domain
#include<Wire.h>
const int MPU_addr=0x68;  // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;
void setup(){
  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
  Serial.begin(9600);
}
void loop(){
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true);  // request a total of 14 registers
  AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
  AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  Tmp=Wire.read()<<8|Wire.read();  // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
  GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
  Serial.print("AcX = "); Serial.print(AcX);
  Serial.print(" | AcY = "); Serial.print(AcY);
  Serial.print(" | AcZ = "); Serial.print(AcZ);
  Serial.print(" | Tmp = "); Serial.print(Tmp/340.00+36.53);  //equation for temperature in degrees C from datasheet
  Serial.print(" | GyX = "); Serial.print(GyX);
  Serial.print(" | GyY = "); Serial.print(GyY);
  Serial.print(" | GyZ = "); Serial.println(GyZ);
  delay(333);
}

```

There is also a long example sketch ...
> 2 votes

# Answer
You do not tell us what is the problem so my guess is address or level. If you get "Could not find a valid MPU6050 sensor, check wiring!" this is an address problem. By default MP6050 uses x068 as I2C address. If you have something else connected to the bus, there might be a conflict. If so, connect AD0 to 3.3V (pull-up with a 2.2kOhms resistor) to set address to 0x69 (use I2C scanner in /example/wire to make sure). If you see zeros, this might be a logic level problem: To elaborate on the previous answer, the MP6050 is a 3.3V device. The GY 521 circuit has a voltage regulator (5V-\>3.3V) bUt on output it still uses 3.3V TTL logic level. With some noise, bad contacts or long wires, the Arduino may fail to read the I2C properly. Had similar problems, solved using a bidirectional logic level shifter between a Uno and the MPU6050. You can get pre-assembled 4-channels board (same size as GY521 board) for ~ 1US$. I hope this helps
> 1 votes

---
Tags: mpu6050
---


title: OTA over MQTT for ESP32

text:
# Question
Title: OTA over MQTT for ESP32
Before starting working, I am just researching around how can I achieve OTA over MQTT in ESP32 in using Arduino IDE. The process I understand the esp listen to MQTT messages and then received that file over MQTT(not fully at once may be in chunks). And then stored that in flash at specific address. And then change boot loader configuration for executing new firmware.

Here I am confused how can I change boot loader configuration settings to execute the new firmware memory address ?? Any help is appreciated.

is there any out of box library available for this work? Please share reference. I can take reference from there.

Thanks

# Answer
I am not familiar with OTA for ESP32 but with SAMD21 using ArduinoOTA library and there the download is not done over MQTT but HTTPS.

Link to download is sent over MQTT but that's where it ends, download over HTTPS, verification of received data using checksum and bytes count and once InternalStorage.apply() executed it swaps the program downloaded with the older version and reboot.

**EDIT:**

As per Juraj request, I am adding the code as a guide you can use to get ideas. You can't run it as is, you would need to add variable declaration and wrap it in a function.

As updating wrong file will most likely brick your board, I would just add that before running this code I check the filename to make sure it is the correct BIN for the board downloading it, I am using constants like WIFI, GSM, and board name and expect to see them in the filename.

I also send the file length from the server as part of the MQTT update request and check it against my own bytes count and I am not relying on TCP to provide an error on corrupted data and do a my own checksum test.

```
#include <ArduinoOTA.h>  // https://github.com/jandrassy/ArduinoOTA

// Access the file
HttpClient client(*transport, upgradeServer, upgradePort);
client.get(upgradePath);

int statusCode = client.responseStatusCode();
  /*
   0   HTTP_SUCCESS
  -1  HTTP_ERROR_CONNECTION_FAILED  The end of the headers has been reached.  This consumes the '\n' Could not connect to the server
  -2  HTTP_ERROR_API                This call was made when the HttpClient class wasn't expecting it to be called.
                                    Usually indicates your code is using the class incorrectly
  -3  HTTP_ERROR_TIMED_OUT          Spent too long waiting for a reply
  -4  HTTP_ERROR_INVALID_RESPONSE   The response from the server is invalid, is it definitely an HTTP server?
  */

if (statusCode != 200) {
  client.stop();
  // here you can do something with statusCode like notifying over MQTT
}

long length = client.contentLength();
if (length == HttpClient::kNoContentLengthHeader) {
  client.stop();
  //Server didn't provide Content-length header, abort.
  return;
}

if (!InternalStorage.open(length)) {
  client.stop();
  // Not enough space to store the file, abort.
  return;
}

// Start update, length holds the file size in bytes

client.setTimeout(5000);
byte b;
bool ok;
long fileLength = length;
unsigned long otaStartMillis = millis();
int localChecksum = 0;

while (length > 0) {

  ok = client.readBytes(&b, 1);
  if (!ok) {
   // Abort, stopped after ((millis() - otaStartMillis)/1000) Sec
    return;
  }

  InternalStorage.write(b);
  int bValue = (int)b;
  localChecksum = localChecksum + bValue;

  length--;
}

InternalStorage.close();
client.stop();

if (localChecksum != remoteCkecksum) {
 // Checksum mismatch, abort.
  return;
}

if (length > 0) {
  // Timeout at byte length, abort.
  return;
}

InternalStorage.apply(); // this doesn't return, board should restart

Serial.println("Update failed"); //shown only if update failed

```

Another opportunity to thank Jurak for this library!
> 2 votes

---
Tags: esp8266, mqtt, ota
---


# Question
Title: analogRead always returns 1023 - Arduino Mega 2560
I have connected an FSR (Force Sensitive Resistor) to  as per image(edited name for avoiding mismatch). When I measure the voltage b/w two pins of fsr, voltage changing as per pressure applied. But analogRead always returns **1023**. But my another Mega works good with same code and configurations. Can someone guide me to correct it. Thanks in advance.

```
void setup() {
  Serial.begin(19200);
}

void loop() {
  int num1 = analogRead(A15);
  Serial.println(num1);
  delay(1500);
}

```

# Answer
I had a similar problem when I ported my code from an Arduino Due to an Arduino Mega. I was able to solve this problem by adding the following call in the setup function.

```
analogReference(DEFAULT);

```

It seems that in some other Arduinos, the analog reference will be selected automatically, but at least the Arduino Mega needs it.
> 2 votes

# Answer
I had the same problem when simulating a similar circuit in proteus software. I was able to solve it by supplying power with an external dc input terminal to the arduino board 5v pin.
> 1 votes

# Answer
It sounds like your Arduino Mega 2560 is broken.

> If mega a works and mega b doesn't with the same circuit then mega b must be broken. – Majenko

You can confirm this theory by creating a voltage divider circuit (or use a potentiometer as a voltage divider) and get your Arduino Mega to read that in. It is good practice to measure the voltage using a multi-meter as well. This will help you verify that the voltage read in correspond with the voltage measured and will also help so you do not go over-voltage.

If you are constantly getting `1023` then change it to another analog input. If that still does not work, then try the other Arduino Mega.
> 0 votes

---
Tags: arduino-mega
---


title: ADXL345 accelerometer doesn't work

text:
# Question
Title: ADXL345 accelerometer doesn't work
I just got the ADXL345 accelerometer module. I tried everything I could find online but I can't get it work. Here's how I connect the pins to the arduino uno:

```
ADXL345    ->     ARDUINO
  VCC               3.3V
  CS                3.3V
  GND               GND
  SDA               SDA
  SCL               SCL

```

I also use 2 10kOhm resistors from SDA, SCL to 3.3V on arduino. I tried both Adafruit and SparkFun ADXL345 libraries but it doesn't work. Using Adafruit library it says that no adxl345 is connected. I tried to connect SDO to 3.3V pin and then it stopped saying no adxl345 is connected but still didn't work (no x,y,z values displayed). Then I tried SparkFun library without connecting SDO to 3.3V (because it failed) and all I got was 0, 0, 0. I literally tried everything I could find from videos, tutorials, etc. I don't know why it doesn't work. What am I doing wrong? I already ordered the MPU6050. Is it any better?

# Answer
> 1 votes
As far as my experience goes you donot have to connect it to pulldown resistors. If using a 5v Arduino, simply connect it like:

VCC --\> 5V (Arduino)
GND --\> GND (Arduino)
SDA --\> A4 or SDA (Arduino Uno has dedicated I2C pins beside AREF pin)
SCL --\> A5 or SCL

This is all you need. As although the ADXL345 is a 3.3v MEMS, its module comes with a 5v to 3.3v converter and also goes through its startup procedure (Refer datasheet) for you.
As for the library you can use this one here
Also you can refer this article for detailed usage here
And I hope next time you put in some more research and then buy a new part.

# Answer
> 0 votes
SDO should be tied to ground, not 3.3V. That puts it into I2C mode.

VDDIO, VS and CS all need to be on 3.3V.

To communicate with an Arduino at 5V you really need a 5V -\> 3.3V I2C level shifter. I use the PCA9306DCUR.

---
Tags: arduino-uno, accelerometer, gyroscope
---


# Question
Title: Can I pass data from an Arduino Nano to a Websocket Server via USB?
I have an Arduino Nano, and a local Java WebSocket server (ws://localhost:8888) run by a .jar file on my computer.

I'm wondering if it's possible to send data (text, numbers etc.) from the Arduino Nano to the WebSocket server via USB cable (USB-A to USB Mini, one that normally powers the Nano).

If so, what do I need to do it?

A quick Google for WebSocket Arduino libraries reveals:

Websockets and Arduino Websocket Fast, but looking at the examples, the former uses Ethernet.h and the latter uses Wifi.h, and I'm unsure if my board is compatible with that without other modules.

# Answer
> 1 votes
I ended up using Python to bridge Serial to WebSocket. I wanted flexibility in sending from WebSocket back to Serial too, so I didn't try a prepackaged solution like https://github.com/RandomStudio/serial-to-websocket

# Answer
> 3 votes
As @Majenko already said the ATmega328 uses a serial connection to communicate. Another chip on the board translates the serial data to USB-Format and the other way around. This enables your computer to interact with the main chip on the Nano (ATmega328). To solve your problem you might try using something like this simple serial-to-websocket node-server that listenes to data coming in from a serial port and sends it out over WebSocket.

# Answer
> 0 votes
No, you can't. The Arduino has a serial connection, not a network connection. If the Java program is of your own devising you would need to rewrite it to use serial instead of (or as well as) WebSockets. Either that or write a separate piece of software for your computer to go between the Arduino's serial connection and the WebSockets interface.

---
Tags: arduino-nano, c++, networking, java
---


title: Infamous white squares for LCD display

text:
# Question
Title: Infamous white squares for LCD display
I would like to know what I've done wrong. I configured my circuit using the "Hello world tutorial. I got the infamous white square pattern

* D7 to pin 2
* D6 to pin 3
* D5 to pin 4
* D4 to pin 5
* E to pin 11

My code:

```
// include the library code:
#include <LiquidCrystal.h>

//LiquidCrystal lcd(RS, E, D4, D5, D6, D7);
LiquidCrystal lcd(2, 3, 4, 5, 11, 12);      // put your pin numbers here

void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("hello, world!");
}

void loop() {
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 0);
  // print the number of seconds since reset:
  lcd.print("hello, world!");
}

```

# Answer
> 1 votes
Your picture does not give a clear view of the connections between the Arduino Uno and the LCD module. However, if we are to follow your description of your connections ...

> ```
> D7 to pin 2
> D6 to pin 3
> D5 to pin 4
> D4 to pin 5
> E to pin 11
>
> ```

... and we assume D7, D6, D5 & D4 are pins on the LCD, then we see that the code is incorrect ...

```
LiquidCrystal lcd(2, 3, 4, 5, 11, 12);      // put your pin numbers here

```

... given the LiquidCrystal description here of the syntax of the overloaded (means there are more than one pattern to the passed parameters to the identically named constructor) class ...

```
Syntax

LiquidCrystal(rs, enable, d4, d5, d6, d7)
LiquidCrystal(rs, rw, enable, d4, d5, d6, d7)
LiquidCrystal(rs, enable, d0, d1, d2, d3, d4, d5, d6, d7)
LiquidCrystal(rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7)

```

... instead, try:

```
LiquidCrystal lcd(?, 11, 5, 4, 3, 2);      // put your pin numbers here

```

... as you didn't tell us how you connected the RS line I have left that value above as a "?". So this will not compile until you fill in the missing information.

It should be added, based on what can be seen in the picture, that a connection has been made to the LCD's RS & RW pins and no connection has been made to the LCD's E (enable) pin. But in all the constructor's overloaded versions, there is always an E (enable) pin. Please take a closer look at your design to determine if this is a problem.

# Answer
> 0 votes
In my case the issue was trivial: the LCD pins were not making good contact with the breadboard.

By firmly inserting them and reuploading you should be able to see "hello world!"

---
Tags: lcd
---