title: How can I copy and compare a string?

text:
# Question
Title: How can I copy and compare a string?
I have the following code (I realise String isn't very efficient, but this sketch doesn't have to be)

debugOutput gets called every loop, but I only want to spam the serial bus (to debug) if the status changes.

However, it runs once, despite changes to the pins being made.

```
String prevState = "";
void debugOutput() {
  String s = "";
  //s = s + digitalRead(6) ? "1" : "0";
  //s = s + digitalRead(5) ? "1" : "0";
  s = s + digitalRead(4) ? "1" : "0";
  s = s + digitalRead(3) ? "1" : "0";
  s = s + digitalRead(2) ? "1" : "0";
  if(!prevState.equals(s)) {
    Serial.println("State Change: "+s);
    //strcpy(s, prevState);
    prevState = s;
  }
}

```

My suspicion is it was because of the pointers being the same, but I declare a new string every time this function runs. Just in case, I tried to swap this to strcpy, which isn't valid since I'm using String instead of character arrays.

What can I do, I'm really confused.

This is the Serial output, btw

`State Change: 1` So it's clear to me that my string appending isn't even working as expected.

# Answer
There is this thing called "operator precedence" that defines the hierarchy of operators.

The `?:` will be calculated after the `+`. That's why

```
s = s + digitalRead(2) ? "1" : "0";

```

actually means

```
s = (s + digitalRead(2)) ? "1" : "0";

```

But you want

```
s = s + (digitalRead(2) ? "1" : "0");

```
> 3 votes

# Answer
I'm not sure why string appending using + was failing, but changing it from

`s = s + digitalRead(2) ? "1" : "0";`

to

`s += digitalRead(2) ? "1" : "0";`

fixed my issue.
> 0 votes

---
Tags: serial, string
---


title: Connect one SD card to two devices

text:
# Question
Title: Connect one SD card to two devices
I have a system where an Arduino controls a DSLR camera for environmental monitoring. The Arduino can power on/off the camera and control the shutter (through the standard plug for a external shutter). The Arduino record and transmit the status of the system (battery voltaje, time of the last shot, etc.). **I want the Arduino to be able to access the camera's SD card while the camera is powered off**. In order to check if the pictures were actually taken and check available memory (I don't need to write to the card).

So my questions are:

1. If I create a contraption to connect a single card to the camera and the arduino. The fact that the card is connected to one device (although not been used) will interfere in the operation of the other?
2. Should I consider the use of a multiplexer or something alike to completely disconnect the data lines from one device while the other is using the card?

# Answer
An SD card has two interfaces: The SPI interface is what is used by the Arduino (it is rather slow). The second one is a parallel interface, which is capable of way bigger transmission speed. It is most likely, that the camera uses that interface, since it has to transmit rather big data packets in a short time. But as I remember some pins are used for both interfaces.

We cannot know, what happens inside the camera. But providing voltage to a digital pin of a microcontroller, while it is not powered, (as it would happen, when you drive the SD card while the camera is off) can be harmful. We must assume, that this would also happen with your camera, or you risk damaging it.

Using multiplexers (or - if you find no fitting one - some simple transistors) to disconnect the camera, when you want to connect with the Arduino, seems a good idea to me. Disconnect all lines, including the supply voltage. The ground line has to stay together, though you should check with a multimeter, if the SD slot ground is the same as the shutter connector ground (if they are not, you don't want to connect these grounds). Is most likely is, but you should check it to be sure.
> 1 votes

---
Tags: spi, sd-card
---


title: Is WiFi traffic encrypted on ESP32?

text:
# Question
Title: Is WiFi traffic encrypted on ESP32?
I am using the ESP32 in soft access point mode. In other words I specify my wifi username and password on the ESP32 and I am able to connect to it from my phone.

So I am not using any router or internet connection. Only my phone and the esp32.

If my phone is the only device on the network created by the esp32 do I have to worry about HTTPS? People say HTTP is not secure and I also know how easy it is to see http traffic with Wireshark. **But if no one else has access to the network I guess http is secure correct?** If no one knows the wifi password will my http requests be encrypted? Moreover, if I connect from my computer instead than my phone via wifi to the ESP32 and send UDP packets will those be encrypted?

# Answer
> 3 votes
WiFi with WPA2 (which is what you get when you specify a password) is encrypted.

As long as your HTTP requests *only* go over that connection and nowhere else then yes, they are encrypted and as secure as WPA2 (which isn't unbreakable, but not easy to break).

HTTPS adds encryption for use over the internet which in general is *not* encrypted.

# Answer
> 3 votes
If you provide a password for you network, it will be encrypted. Thats the point of the password. When you look at the function description in the WifiAP.cpp file of the Wifi class for the ESP32, the description suggests, that it will be encrypted with WPA2, which is currently the standard in Wifi encryption. (Though that can depend on the actual library, that you are using)

> do I have to worry about HTTPS?

That depends on your needs. In IT security is a scale, not a binary. Using HTTP on a WPA2 protected network can be considered safe on the one side and unsafe on the other. You need to thing about, if your project needs that additional layer of encryption through HTTPS.

For example: If you control your Smart Home with that ESP32, which may be able to open your windows or even the door, I would consider that critical. Then I would take every bit of security, that I can get, as there are ways to break into a WPA2 protected wifi network.

An example in the other direction: I'm currently building a game, which gets configured on a smartphone via the Wifi network of an ESP32. The network is encrypted to prevent casual attackers from messing with my current game run, but the project has so low security needs, that I will not bother with HTTPS. It's just a game, that will not that often being used, and the possibility of an attack on it is very low.

So it's about risk assessment (as with all security in IT).

> if I connect from my computer instead than my phone via wifi to the ESP32 and send UDP packets will those be encrypted

The mentioned types of encryption (WPA2 and HTTPS) happen on two different layers of the network communication. With WPA2 your complete wifi data of that network is encrypted. So the UDP packet is also encrypted, but only in that wifi network, and it can be read by any authenticated user of the network. HTTPS works in a layer above that, so that your packet would be encrypted, even if it would move out of that Wifi network. For learning more about network layers, refer to the OSI model.

---

Apart from the security perspective: When you use HTTPS you also need to think about the certificate, that you are using. If you use a self-signed one, your browser will present you a warning about that, everytime you open that site. To prevent that, you either need to trust that certificate on all your devices, or you need to use an officially signed certificate (which might be a problem for a pure local project).

---
Tags: wifi, esp32
---


# Question
Title: Erasing 1 byte of external Flash memory (winbond)
i'm trying to use an external flash memory Winbond 25q64jvsiq for my Arduino Nano based project for audio recording purposes, to have extra memory for recording 1 byte audio samples, since Arduino nano SRAM memory is too small (8kb), to store at least 1 second of 8 kHz 8 bit samples audio. I'm trying to understand the basics of bytes storing in my external memory. I'm using SPIMemory library for that, and i can't find a function to erase 1 byte, there is only sectorErase() function. So i wonder is it even possible to erase a single byte of external memory?

Here is a part of code where i try to rewrite (erase one byte and write a new one) a next byte when the button pressed, but when it erase a sector it erases not the one byte but all bytes behind it, and i want to manipulate it more accurate, and erase only one byte:

```
if(!digitalRead(5)){      //button pressed
     if(e<3){
      e++;
      flash.eraseSector(count);    //erasing a byte
      flash.writeByte(count,e,NOERRCHK); // write a new value
      }  else {
        e=0;
        flash.eraseSector(count);
        flash.writeByte(count,e,NOERRCHK);
        }
     }

```

# Answer
For a flash chip, no it's not possible to erase a single byte.

The closest you can do is to read an entire sector into memory, erase that sector, modify your in-memory copy, then write the sector back.

You would be better using an SPI SRAM or PSRAM chip instead of a flash chip.
> 2 votes

---
Tags: arduino-nano, audio, memory-usage, flash
---


# Question
Title: How to Connect TFT LCD display with NodeMCU?
I am doing this project wherein I want to display some image on the LCD screen. I am having a problem with the connecting nodemcu with my TFT LCD screen. I cannot find any references. Does a TFT screen go well with a NodeMCU? if yes, please help

I tried taking refrence from this website but i ended up damaging my nodeMCU

http://nobrok.com/connecting-tft-lcd-touch-screen-with-nodemcu-esp8266/

Also attaching images of TFT display and my NodeMCU.

It would be great if you can help. Thanks :)

# Answer
> 1 votes
According to its web site, the TFT module does have SPI interface. https://www.jixin.pro/product/717.html
The site is in Chinese though.

# Answer
> 0 votes
That kind of TFT doesn't work well with the NodeMCU (or the ESP8266 in general).

Simply put: that TFT requires a lot of GPIO pins - 10 at an absolute bare minimum, but better if you have more available. The ESP8266 doesn't have many IO pins - and some of them are very sensitive about what they can be connected to without affecting the boot process.

It is better to choose a TFT screen with an SPI interface, which uses far fewer pins - although is slower to refresh the screen data.

If you are careful with your GPIO selection it *may* be possible to work with that screen. There are no specific requirements for what pins need to be connected to where (as far as hardware functionality goes), so it's up to you to find the right combination that doesn't cripple the boot process (stay away from GPIOs 0, 2 and 15 if you can).

---
Tags: arduino-uno, lcd, nodemcu
---


# Question
Title: help explain pulseIn function with arduino and Ultrasonic sensor
dears Engineers.. i got stuck with this issue couldn't understand.. please help with explanations.

first i was upset of my ultrasonic sensor reading deviations, that is i examine my sensor indoor and at quite environment,, so what makes this noisy output readings??!!!

so i tried to dig into the pulseIn function and tracking the timing of each instruction in the code.. after reading the library.., i decided to use pulseInLong function. following is a result of some iterations timing in microseconds:

```
Ultrasonic Sensor HC-SR04 Test
with Arduino UNO R3
Start ~ trig LOW  ~ 10us delay ~ trig High ~ 10us delay~ trig High ~   pulseIn    ~   Duration
0           8           12          8           12          4           7352            137976
4           4           12          8           12          8           7336            137960
4           8           12          8           12          8           7352            137976
4           8           12          8           12          8           7356            137980
4           8           12          8           12          8           7352            137976
4           8           12          8           12          8           7356            137980
4           8           12          8           12          8           7360            137984
4           8           12          8           12          8           7364            137996
0           8           12          8           12          8           7364            137992
4           8           12          8           12          8           7372            137996
4           8           12          4           12          8           7380            138004
0           4           12          8           12          8           7372            137996
0           4           12          8           12          8           7348            137968
4           8           12          4           12          8           7372            137996
4           8           12          8           12          4           7376            138004
4           8           12          8           12          8           7380            138008
0           8           12          8           8           8           7352            137980
4           8           12          4           12          8           7352            137976
4           8           12          4           12          8           7368            137992
4           8           12          8           12          8           7340            137964
4           8           12          4           12          8           7352            137980
4           8           12          4           12          8           7360            137984
12          8           12          8           12          8           7368            137996
4           8           12          8           12          8           7348            137972
4           8           12          8           12          12          7360            137984
0           8           12          8           12          8           7344            137968
4           8           12          8           12          8           7352            137976
4           8           12          8           12          8           7364            137988
4           8           12          4           12          8           7360            137984
4           8           12          8           12          4           7372            138000

```

first i wondered why there are different execution time for the same instruction??! for example digitalWrite(trig\_pin,LOW or High) varies in range 4 ~ 12 microseconds!!????

more strange when i found elapsed time after delay 10us, micros() function shows only 8 us??!!!

all these in range of 16 us,, so i expected maybe due to some instruction cycles or unprecise clock...etc.

but the BigBang i shocked when read this huuuuuge difference in pulseIn timing measurment; i reset the timer befor the function and just after it, so i got an elapsed time in range of 7350 us. in the same time the resultant measured time from the function in range of the 138000 us?????!!!!!!

put in mind that pulseInLong is a blocking function..as you will see below, it loops in a while loop until timeout (so return 0) or pulse generated and measured before timeout then return pulse elapsed time.

first i suspected in this number maybe not microseconds. inspected the function deeply, ??!!! i found it using the exact micros() function such i do in the code?

```
 * this function relies on micros() so cannot be used in noInterrupt() context
 */
unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout)
{
    // cache the port and bit of the pin in order to speed up the
    // pulse width measuring loop and achieve finer resolution.  calling
    // digitalRead() instead yields much coarser resolution.
    uint8_t bit = digitalPinToBitMask(pin);
    uint8_t port = digitalPinToPort(pin);
    uint8_t stateMask = (state ? bit : 0);

    unsigned long startMicros = micros();

    // wait for any previous pulse to end
    while ((*portInputRegister(port) & bit) == stateMask) {
        if (micros() - startMicros > timeout)
            return 0;
    }

    // wait for the pulse to start
    while ((*portInputRegister(port) & bit) != stateMask) {
        if (micros() - startMicros > timeout)
            return 0;
    }

    unsigned long start = micros();
    // wait for the pulse to stop
    while ((*portInputRegister(port) & bit) == stateMask) {
        if (micros() - startMicros > timeout)
            return 0;
    }
    return micros() - start;
}

```

anyway..i dont want to make this story long.. can someone explain what is going on to me please?!

thanx

here is arduino code i used

```
#define trigPin 3 //attach pin D3 Arduino to pin Trig of HC-SR04

// defines variables
long duration; // variable for the duration of sound wave travel
int distance; // variable for the distance measurement

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

  pinMode(trigPin, OUTPUT); // Sets the trigPin as an OUTPUT
  pinMode(echoPin, INPUT); // Sets the echoPin as an INPUT
  Serial.begin(9600); // // Serial Communication is starting with 9600 of baudrate speed

  Serial.println("Ultrasonic Sensor HC-SR04 Test"); // print some text in Serial Monitor
  Serial.println("with Arduino UNO R3");
  Serial.println("Start ~ trig LOW   ~   10us delay   ~   trig High   ~   10us delay   ~   trig High    ~    pulseIn    ~   Duration");

}

void loop() {
  // put your main code here, to run repeatedly:
  // Clears the trigPin condition
  int indx = 0;
  int arr[7] = {0};
  double last = micros();

  arr[indx] = micros() - last;
  indx++;
  last = micros();

  digitalWrite(trigPin, LOW);

  arr[indx] = micros() - last;
  indx++;
  last = micros();

  delayMicroseconds(10);

  arr[indx] = micros() - last;
  indx++;
  last = micros();
  // Sets the trigPin HIGH (ACTIVE) for 10 microseconds

  digitalWrite(trigPin, HIGH);
  arr[indx] = micros() - last;
  indx++;
  last = micros();

  delayMicroseconds(10);
  arr[indx] = micros() - last;
  indx++;
  last = micros();

  digitalWrite(trigPin, LOW);
  arr[indx] = micros() - last;
  indx++;
  last = micros();

  // Reads the echoPin, returns the sound wave travel time in microseconds
  duration = pulseInLong(echoPin, HIGH);
  arr[indx] = micros() - last;

  // Calculating the distance
  distance = duration * 0.034 / 2; // Speed of sound wave divided by 2 (go and back)
  // Displays the distance on the Serial Monitor

  for (int i = 0; i <= indx; i++)
  {
    Serial.print(arr[i]);
    Serial.print("     \t    ");
  }
  Serial.print(duration);
  Serial.println();

}

```

# Answer
I see at least three reasons for the behavior you notice:

1. `micros()` has a resolution of 4 µs. If you could call it at a period fixed to exactly 10 µs, you would see the time deltas alternate between 8 and 12 µs. But then `micros()` takes some time to execute, so if you use it to time a function that takes 10 µs to execute, you will read 12 µs more often than 8.
2. There is a timer interrupt firing every 1024 µs. Any process that gets interrupted will show an execution time longer than normal. This is the likely cause of `digitalWrite()` taking occasionally a lot longer than usual.
3. `pulseIn()` waits for the start of the pulse before it starts to measure its duration. Its execution time can then be significantly longer than the pulse duration it reports.

> i expected maybe due to some instruction cycles or unprecise clock.

The same clock is used for sequencing the CPU instructions and for timing them. So the clock precision has no effect on the timings you measure.

**Edit**: There is an extra issue here, which is the overflow of `arr[6]`. The execution time of `pulseInLong()` may be something like 138,424 µs. Since an `int` on the Uno is 16 bits, this value wraps modulo 216 to 7,352, which is the value shown in the first line of the output.
> 1 votes

# Answer
> Why do I receive the **big difference** in time measurement between elapsed time while execution the pulseInLong function and its return duration measurement?

The answer lies in the choice of the way it is implemented. The delay function itself is helpful but the accuracy is not great when precision is needed. Here is the official note from the site:

1. This function works very accurately in the range of **3 microseconds and up**. We cannot assure that delayMicroseconds will perform precisely for smaller delay-times.
2. As of Arduino 0018, delayMicroseconds() **no longer disables interrupts**

If you want to really be precise, I recommend to use hardware timers. I believe it will suffice. to know more about using hardware timers you can refer to

https://learn.adafruit.com/multi-tasking-the-arduino-part-2/timers

https://maker.pro/arduino/projects/timer-interrupts-improve-your-arduino-programming-skills
> 0 votes

---
Tags: arduino-uno, programming, c, timers, programming-sequence
---


title: Keypad as game input device?

text:
# Question
Title: Keypad as game input device?
I have been trying to get a button matrix to work but im not experienced enough in programming.

I Have tried to read up but i don't know how to execute so some help would be greatly appreciated.

I want the keypad to function as a game controller of sorts. when i pres the 1 key on the keypad i want the read light to light up and only go out when i release the button. code was copied from "mstanley" on arduino forum.

Q: How do i use the Keypad.h library to get my keypad press to run one line of code when i press a button and another line when i release the button.

I Was testing with leds now, the code is identical, digitalWrite(1, HIGH); then digitalWrite(1, LOW); this can easily get exchanged for joystic.PressButton 1 and Joystick.ReleaseButton 1

```
#include <Keypad.h>

const byte ROWS = 4; //four rows
const byte COLS = 4; //three columns
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {9,8,7,6}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {5,4,3,2}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

char holdKey;
unsigned long t_hold;

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

  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
}

void loop(){
  char key = keypad.getKey();

   if (key){
     holdKey = key;
     Serial.println(key);
   }

   if (keypad.getState() == HOLD) {
      if ((millis() - t_hold) > 100 ) {
          switch (holdKey) {
              case '1':
                  digitalWrite(11, HIGH);
                  delay(200);
                  digitalWrite(11, LOW);
                  break;
              case '2':
                  digitalWrite(12, HIGH);
                  delay(200);
                  digitalWrite(12, LOW);
                  break;
              case '3':
                  digitalWrite(13, HIGH);
                  delay(200);
                  digitalWrite(13, LOW);
          }
          t_hold = millis();
      }
   }
}

```

# Answer
I did a post about keypad handlers. I'm reluctant to mention it because we aren't supposed to post "link only" answers.

It refers to a library available on GitHub which handles keypads. In particular you can have a callback function for both the keydown and the keyup, for multiple keys.

> How do i use the Keypad.h library to get my keypad press to run one line of code when i press a button and another line when i release the button.

That seems to be what you want to do.

Example code:

```
/*
 *
 * Example of using Keypad_Matrix with a 4x4 keypad matrix.
 *
 */

#include <Keypad_Matrix.h>

const byte ROWS = 4;
const byte COLS = 4;

// how the keypad has its keys laid out
const char keys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'},
};

const byte rowPins[ROWS] = {6, 7, 8, 9}; //connect to the row pinouts of the keypad
const byte colPins[COLS] = {2, 3, 4, 5}; //connect to the column pinouts of the keypad

  // Create the Keypad
Keypad_Matrix kpd = Keypad_Matrix( makeKeymap (keys), rowPins, colPins, ROWS, COLS );

void keyDown (const char which)
  {
  Serial.print (F("Key down: "));
  Serial.println (which);
  }

void setup()
{
  Serial.begin (115200);
  Serial.println ("Starting.");
  kpd.begin ();
  kpd.setKeyDownHandler (keyDown);
}

void loop()
{
  kpd.scan ();
  // do other stuff here
}

```

You can also use `setKeyUpHandler` to do another function when a key is released. You can also call `isKeyDown` to see if a key is down (eg. when pressing key A is key B also down?).

Note that (as mentioned in the linked post) you need to use diodes to stop having false (ghost) key presses if more than two keys are pressed at once.
> 2 votes

# Answer
> How do i use the Keypad.h library to get my keypad press to run one line of code when i press a button and another line when i release the button

**Edit 1:**

```
void loop() {
  char key = keypad.getKey();

  if (key != NO_KEY) {
    Serial.println(key);
  }

  if (keypad.isPressed('*'))
  {
  randomr = random(10, 2000);
  Serial.println(randomr);
  }

```

}

---

From the link: https://playground.arduino.cc/Code/Keypad/ you can find all the functions supported by the Keypad library.

One relevant function is

```
KeyState getState()

```

It returns the current state of any of the keys. The four states supported are IDLE, **PRESSED**, **RELEASED**, and HOLD.

Hence you can use this function for the keys you are interested in.
Also, if helpful consider this function as well.

```
setHoldTime(unsigned int time)

```

Set the number of milliseconds the user will have to hold a button until the HOLD state is triggered.

---

You can find the keypad.h library in action here. I motivate you to also try the code with this online Arduino emulator

you already have a builtin function defined to get the status of the key pressed

```
void loop() {
  char key = keypad.getKey();

  if (key != NO_KEY) {
    Serial.println(key);
  }
}

```

I have a poorly taken screenshot for the same for your quick reference.

Original Arduino emulator link: (you can play with the logic)

https://wokwi.com/playground/keypad

---

*Disclosure*: I use wokwi.com, to create interesting tools and libraries for the Arduino community https://github.com/wokwi

for a more free demonstration of the libraries:
https://github.com/wokwi/arduino-libraries
> 1 votes

---
Tags: arduino-leonardo, keypad
---


title: What NRF24L01 module is this?

text:
# Question
Title: What NRF24L01 module is this?
I received my NRF24L01 Module today but I'm having a hard time finding any resources about this particular combination of modules!

https://i.stack.imgur.com/Tiwyj.jpg

I tried searching up the v200 1812A but no results...You would think the seller would have some documentation on his page but nothing.

Does anyone know what I'm dealing with here?

Thank you!

# Answer
> 2 votes
They are transparent bridge modules that are designed specifically to work together. It's intended to be kind of like a wireless UART.

This AliExpress Seller details how to use them.

You need one UART and one USB module. You plug the UART module into the USB module and plug the USB module into your computer. After about 10 seconds the modules are paired together.

You then separate them, and you can connect the UART module to your Arduino or other board.

Now you have a wireless UART between your computer and your Arduino.

Alternatively, since they have an STM32F0 chip controlling them you could hack them to do other things using `stm32duino`.

---
Tags: nrf24l01+, uart, wireless, rf
---


# Question
Title: Is it possible to detach an interrupt for a certain ammount of time
Hardware: Arduino Uno Software Version: 1.8.13

My sketch has an interrupt service routine that triggers with the rising edge of digital pin 2. What I want to do now is detaching the interrupt as soon as it has been triggered once and reattaching it as soon as a certain amount of time (\>1s) has passed.

However despite of trying I haven't found a possibility to do this.

I have tried detaching it in the ISR itself and reattaching it in the main loop with a delay after manually clearing the interrupt flag. However with this approach the time the interrupt is detached for depends on the point of time the interrupt is triggered, which is undesirable.

Is there a better solution for this? Thank you in advance for every answer

# Answer
> 0 votes
The standard way to do this is just as you described (but with the non-blocking coding style like in the `BlinkWithoutDelay` example): Detach in the ISR and setting a flag and a timestamp. Then in the main code check the flag and the time since the timestamp was took. In code that looks somewhat like this (Note, that I left out some arguments of the attaching/detachting functions):

```
volatile byte flag = 0;
volatile unsigned long timestamp = 0;
#define REACTIVATE_INTERVAL  1000

void ISR_function(){
    detachInterrupt(...);
    flag = 1;
    timestamp = millis();
}

void setup(){
    attachInterrupt(..., ISR_function, ...);
}

void loop(){
    if(flag && millis() - timestamp > REACTIVATE_INTERVAL){
        flag = 0;
        attachInterrupt(..., ISR_function, ...);
    }
    // Rest of your main code from here on
}

```

For this to work correct, you must of course use a non-blocking coding style in your main code, meaning no `delay()`s (except for really small ones) and no blocking `while` loops. If you have those in your main code, you should rewrite it to be non-blocking. Not only for this feature, but for any further extension of your project. A non-blocking coding style is an important principle to embrace, especially microcontrollers.

---

Without a non-blocking coding style, you would need to use a timer interrupt, to reattach the pin interrupt. While that is totally possible, it does not make much sense to configure extra peripherals of the Arduino just for this.

---
Tags: arduino-uno, interrupt, atmega328, timers
---


# Question
Title: Why do my Hall sensor readings change when I write them to the serial port?
I have a small project where I connected a Hall sensor (see picture) to an Arduino Mega. The blue wire is connected to pin 45, the red wire to +5V, and the black wire to GND.

At the beginning I initialize the pin used to read the sensor as follows.

```
#define HALL_PIN 45

void setup()
{
  pinMode(HALL_PIN, INPUT);
}

```

I have written a function to read out the sensor. While there is no magnet nearby, the sensor returns HIGH. If a magnet approaches in the correct orientation, the sensor returns LOW. The function should return *true* if a magnet is nearby, i.e. if the read value is LOW.

I have noticed that my program logic sometimes does not work reliably after seemingly irrelevant changes to the code. After commenting out more and more code to narrow down the problem, I came across the following discovery.

**Implementation 1:**

In the first implementation, I initially read out the value of the Hall sensor. Next, I send the value to the serial port. The serial monitor in the Arduino IDE outputs the number 1 (HIGH). This is the expected behavior as during testing there is no magnet nearby. Based on the subsequent program behavior I can confirm that the function returns *false*. I can let the Arduino run for minutes and the behavior remains stable.

```
bool readHallSensor()
{
  int s = digitalRead(HALL_PIN);

  Serial.println(s); // The serial monitor outputs 1 (HIGH)

  return s == LOW; // Returns false
}

```

**Implementation 2:**

With the second implementation I do not write the read value to the serial port. As expected, the serial monitor in the Arduino IDE remains empty. The function, however, now returns *true*. Apart from commenting out the marked line and flashing the sketch to the Arduino, I did not make any changes (again no magnet nearby). Also in this case I can let the Arduino run for minutes and the behavior is stable.

```
bool readHallSensor()
{
  int s = digitalRead(HALL_PIN);

  // Serial.println(s); // No output to the serial monitor

  return s == LOW; // Returns true
}

```

My first suspicion was that the delay caused by writing to the serial port is what makes the difference. I asked an electrical engineer whether Hall sensors might need short breaks between successive readings. He denied my assumption, and indeed, if I simply insert a *delay(300);* after reading the value (without writing to the serial port) the behavior does not change and is identical to implementation 2.

I can switch back and forth between the two implementations and flash them to the Arduino as many times as I like. The behavior is always as described above for both cases. I cannot make any sense of this, as the behavior seems to lack any (programming) logic. Has anyone ever made similar observations and can give me a hint what might cause this? Thank you in advance.

---

I haven't found the problem yet, but I have come a step closer. The issue has reappeared in a similar project on the same Arduino. I use a new Hall sensor with pull-up, which is read out wrong again under certain circumstances (always read out as LOW, no matter if a magnet is nearby). The problem seems to occur only when I use a certain pin. The pin in question on my Arduino Mega this time is pin 37. If I connect the Hall sensor to another pin (I have tested 34 and 36), it works fine. If I connect a previously working Hall sensor to pin 37, it will not work anymore (always evaluated as LOW). The only explanations that make sense to me at the moment are that either the Arduino Mega is damaged or that there are side effects, maybe caused by external libraries using certain pins without my knowledge and incorrectly initializing them.

# Answer
> 3 votes
The 3144 requires a pull-up resistor. It only sinks when a magnet is present. It doesn't source, so the pin is floating if no magnet is present.

You can use the internal pull-up resistor by using `pinMode(HALL_PIN, INPUT_PULLUP);`

---
Tags: serial, hall-effect
---


title: ESP32 nodemcu serialbt sending data

text:
# Question
Title: ESP32 nodemcu serialbt sending data
I'm currently trying to send data from esp32 to my android app that I made. The sensor readings are showing in the serial monitor, however, what's showing on my app are either @ or &. Please help and thank you. I'm new to bluetooth coding.

Here's the code:

```
#include "BluetoothSerial.h"
int sensorPin = 35;
int sensorreading;

BluetoothSerial SerialBT;

void  setup ()
{
    Serial.begin(115200);
    SerialBT.begin("ESP32_ABO");
    pinMode (sensorPin, INPUT);
}
void  loop ()
{
   sensorreading = analogRead(sensorPin);
   String toSend = String (sensorreading);
   sendData(toSend);}

void sendData(String textToSend){

   Serial.print(sensorreading);
   SerialBT.write(textToSend[sensorreading]);
}
delay(1000);}

```

# Answer
> 1 votes
You see very different output via bluetooth and Serial Monitor, because you are sending completely different things. On the Serial Monitor you see the sensor reading, since that is exactly, what you send:

```
Serial.print(sensorreading);

```

The `print()` function will convert the integer variable `sensorreading` into human readable text (meaning ASCII encoded text) and send this over Serial.

But then you do this:

```
SerialBT.write(textToSend[sensorreading]);

```

`textToSend` is a `String` object here. So with the parentheses `[ ]` you are taking one character of that string. You try to use the `sensorreading`th character. Since `sensorreading` comes from an `analogRead()`, it is most likely, that is value is rather big, meaning bigger than the length of the string. So you are basically reading some random memory, that happens to lie behind your string variable. The `write()` function will then send that random data out over your bluetooth serial interface, without any conversion.

I guess you want to transmit the data over bluetooth also in human readable form. So just use the same code as with the `Serial` interface (for the Serial Monitor).

And remove all that manual conversion of the measured analog value to a `String`. That is not needed. If you want to also display some text, you can just use multiple `print()` commands, like this:

```
Serial.print("Value: ")
Serial.print(sensorreading);
Serial.print(" units");

```

---

Note, that it is rather bad to use the `String` object at all. The `String` class uses dynamic memory allocation, which leads to memory fragmentation, which can eat up your available memory. This is not as important on chips with rather big memory (as the ESP32) than on chips with smaller memory (like the Atmega328p, which is used in Arduino Uno and Nano), but you should still keep that in mind. Instead of the `String` class you would work with `char` arrays, aka C-strings.

---
Tags: bluetooth, esp32
---


# Question
Title: How to connect more than one arduino serial port together
The idea is to connect more than 1 arduino slave to master as shown in schamatic

simulate this circuit – Schematic created using CircuitLab The problem is TX slave can not just combine to master RX. It need to done some trick like tri-state buffer to make slave TX one at time. Anyway, avr port can config as tristate buffer. (Q1)Is there any software solution to done this? Second If I connnect TX to RX for half-duplex communication (using 1 data line). How to make Rx stop listenning to its self while transmiting data?

# Answer
You can do it with two diodes and a resistor:

simulate this circuit – Schematic created using CircuitLab

You'll still have to implement some system to prevent collisions, but electrically that will be sound.
> 2 votes

# Answer
You can use a single-pole dual throw switch. a simple switch that can switch lines between multiple slaves.

Limitation: The salve will not be able to create a request unless the master has selected its corresponding lines. Master has to actively ask for the data or send commands to the slaves. Slaves may not be able to initiate the communication (when not selected)
> 0 votes

# Answer
For this scheme to work, you need to make sure that at most one slave drives its TX at any given time. You will have to devise some protocol by which the master addresses one slave, and then only that slave responds. The problem is:

* both slaves must have their serial ports turned on in order to notice when they are addressed by the master
* an active serial port keeps its TX pin in a low impedance state, actively driving it HIGH when not transmitting data.

The best way out of this dilemma is to modify the hardware, as per Majenko’s answer. If, for whatever reason, you cannot do that modification, there may be a software-only solution, but only if the underlying hardware allows you to turn off the serial transmitters of the slaves, while keeping the serial receivers active.

The Arduino API dos not allow you to keep the serial transmitter active while the receiver is disabled: the functions `Serial.begin()` and `Serial.end()` control the transmitter and the receiver as a whole. You may be able to do that by accessing the hardware at a lower-level. You didn't state what kind of Arduino you are using. Assuming you have something similar to an Uno, you can disable the transmitter with:

```
UCSR0B &= ~_BV(TXEN0);

```

and enable it again with:

```
UCSR0B |= _BV(TXEN0);

```

If you want to use the Arduino API for serial communication, you will have to disable the transmitter right after `Serial.begin()`:

```
const uint8_t TX_PIN = 1;

void setup() {
    pinMode(TX_PIN, INPUT_PULLUP);  // valid when transmitter is off
    Serial.begin(9600);             // enable serial port
    UCSR0B &= ~_BV(TXEN0);          // disable transmitter
}

```

But beware that then it will be enabled for a sort time (no more than a few microseconds), right before you disable it. This may cause a short if one slave boots while the other is transmitting data.

One problem with this kind of software-only solution is that bugs do happen, and with your circuit, a bug in the protocol handling can burn your hardware. If you can manage to at least add some protective resistors, as in Gabriel Staples’ answer, that should keep you safe.
> 0 votes

# Answer
Update Nov. 2020: my answer below, though a bit insightful and with many correct statements, is wrong. My schematic below will indeed prevent the Arduinos from damaging each other, but it will not allow proper communication. Majenko's answer here is right. Use his schematic, but read my answer below as well for additional insight and ideas.

---

ORIGINAL ANSWER:

You can do it with 2 resistors, as shown below. That's it! Super simple!

## Electrical explanation:

The goal is simply to protect the two Tx pins from killing each other. Without the resistors one Slave might be writing output LOW while the other Slave is writing output HIGH, which is a **dead short**--damaging both devices. Simply putting a 1k resistor in series with each Tx pin like this prevents that dead short. Now, if one Tx pin is HIGH while the other is LOW, you get current flow from one into the other through a total of 2kOhms, which means the current will be only `I = V/R = 5V/2000 Ohms = 2.5mA`, which isn't a problem, as each pin can handle 40mA max and 20mA~30mA continuous safely. Also, a 1k resistor isn't much load, so you should still get good serial throughput even at fairly high baudrates.

simulate this circuit – Schematic created using CircuitLab

# The code:

The communication code will be done as normal with `Serial.print()` or `Serial.write()`, `Serial.read()`, etc. Nothing special about the code, except you should make an effort to keep the slaves from talking at the same time to prevent data corruption from slave to master. So, you should have Master *request* data from a Slave, and a Slave should only talk when it knows the other Slave is not talking (ex: it should only talk when spoken to). The Master coordinates the communication. In this way, this is like SPI: the Master is in charge and tells each Slave when to talk. Since both Slaves are always listening, just use an "ID" to indicate which slave is being spoken to. If a Slave doesn't see it's ID, it should ignore the message.

Ex:

Request a new temperature reading from Slave 1:

```
Serial.println("1:T");

```

Now, wait until you get the full response from Slave 1, then send out a request for...let's say, some current reading, from Slave 2:

```
Serial.println("2:C");

```

The exact communication codes are up to you--your imagination is the limit.

Again, both slaves see both messages, but they look at the number at the beginning and only reply if it's their number. Doing this technique, you could connect nearly infinite Slaves all on the same line, just adding a 1k resistor to each Slave's Tx line before the junction where they all connect back to the Master's Rx line.

Pretty cool. I never thought of doing this before until you asked the question. Good question.
> -1 votes

---
Tags: serial
---


# Question
Title: Digital LED clock - matrix circuit question
i'm making a digital clock. Right now the plan is to matrix them on a atmega328 using transistors. I figured i need a transistor on both sides or the current would be sinked/sourced by the atmega, which is not what i want.

I'd rather use the MAX7219 but i'm not sure if it's possible to use transistors, because i don't think the MAX7219 can handle the current.

I found the circuits here, i smushed them together, is this correct? Idk.

This is the led segment i'm using, there's four of them. So four 337 transistors, one for each digit. And seven 327 transistors, one for each segment. I will scan through the four digits and turn on the apropriate segment.

So yea, please let me know if this is totally wacky or something else.

Edit : I guess this would be 1 digit. Sorry it's confusing to draw the whole matrix. I hope this clears it up. It's just a normal matrixing situation but with more leds.

So normally it goes something like this : **The cathodes of the leds are controlled directly by the atmega, but results in the atmega supplying the current. So my reasoning would be to put a row of transistors there instead, would that be correct?**

# Answer
> 0 votes
Since you're using a matrix of anodes and cathodes you need to connect/disconnect both ends of each LED.

You will probably multiplex these LEDs and only light one at a time. Are the LEDs high enough current that you can't either source or sink enough current for a single LED directly from Arduino pins? Most LEDs run on ≤ 20 mA, which an atmega328 can handle.

If you are trying to drive LEDs that need \> 20mA then your plan to switch both the +5 and the ground with transistors should work. As StarCat said, you should consider the "on resistance" of your transistors as part of your calculation for the value needed for the current limiting resistors of your LEDs.

# Answer
> 0 votes
Or just use the MAX7219, specifically designed for 7-segment displays. It has an operating current spec of 330 mA, good for all segments and the decimal point on at the same time. A four-digit 7-segment display with a total of 32 LEDs allows 10 mA per LED assuming you have everything on at once.

Am I missing something?

Frank

---
Tags: led
---


# Question
Title: Voltage issue on an esp32 wvroom 32D development board
I have an esp32 wroom 32 dev board. I'm running into power issues and I'm not sure what's going on.

When I try to upload sketches the uploads fail if I have any jumpers running to the 5v or 3.3v pins which is weird.

Also, when I have nothing plugged into the board other than the usb cable and try to measure voltage across the ground and power pins I get 1.5v from the 5v pin and 0 from the 3.3 pin

This is a brand new out-of-the-static-bag board and I'm having the same issue with another board of the same type.

I feel like there's something I'm missing. Any ideas?

# Answer
Try measuring the voltage against a different ground pin? I had a similar problem and discovered the pin next to the 5v input pin wasn't actually ground. Not sure why this would affect sketch uploading though..
> 1 votes

---
Tags: esp32
---


# Question
Title: Measuring car speed between two points: What sensor to use and how to cover the distance?
PROBLEM

Cars regularly exceed the speed limit in our street

SOLUTION

Measure each car's speed and clearly display the speed to the driver

EXECUTION

1. Measure the time the car takes to cover a set distance (e.g. 25 meters) to calculate the speed
2. For this I'd set up two sensors and calculate the difference between the timestamps recorded between the car passing the first and second sensors -\> then convert into km/h
3. Display the result on an LED screen

CHALLENGES & QUESTIONS

A. What sensors should I use here? Photoresistor with laser diode, digital or analog IR sensor, ...

B. How can I best cover the distance between the sensors and connect them to the Arduino? Long wire, wireless, connect two Arduinos, ...

Thanks!

# Answer
> 1 votes
Why 25meters? If you place the two sensors 1 meter apart, you only need 1ms accuracy to get km/h (assuming a 50km/h speed limit). The Arduino can handle 1ms resolution with ease.

I'd probably go with 3-5 meters, so you don't need your setup to be that precise (i.e. distance and alignment of the two sensors). Lowering the distance also makes it less likely for two cars, from both directions, to simultaneously be inside your sensor area.

For the sensors, the biggest problem is the legal one. Having objects on/near the road could cause some liability issues. The laser solution is probably the least likely to cause this issue. Though I'm unsure about having a display next to the road.

You could go with laser and photo-transistor on one side of the road. And a reflector/mirror on the other side. I'd probably go with an IR laser, so it's invisible. You'd have to shield the photo-transistor as much as possible from ambient light, so a sudden cloud won't trigger it. You probably still need to do some filtering in software.

There are radar modules available, but I think they are pretty expensive.

Another option is a Laser range sensor, like this one from sparkfun

---
Tags: arduino-uno, sensors, display, ir, photoresistor
---


# Question
Title: Reading a json file from SPIFFS and displaying the info it contains on an embedded web page
I am working on a smart IR receiver that reads an IR signal, decodes it and saves that decoded info in a json file stored on the NodeMCU's SPIFFS. This info is then displayed on the embedded web server in a table.

Now my problem is that even though I correctly save the signal's info in the json file (and when I try to print it in console it looks perfect), the son file is not correctly passed to my web server and the table remains empty. I am using jQuery to read the file and make the changes in the HTML. All the web server files (HTML, css & JavaScript) were tested first on my local machine with an example Json file of the same structure I am using on my SPIFFS so I know for sure the problem is not in there.

It is worth noting that I faced this problem when developing on my local machine, where the table would remain empty even though the json file is not, but it was fixed when I used the Live Server extension on VSCode. However, I don't understand if this is the problem how is it that there is no server to pass the json file on when all my web interface files are correctly passed and loaded from the SPIFFS.

I will include a portion of my code, and of course all help is appreciated.

```
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266mDNS.h>
#include <ESP8266WebServer.h>
#include <Arduino.h>
#include <IRremoteESP8266.h>
#include <IRrecv.h>
#include <IRutils.h>
#include<FS.h>   // Include the SPIFFS library
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <ArduinoJson.h>

ESP8266WiFiMulti wifiMulti;     // Create an instance of the ESP8266WiFiMulti class, called 'wifiMulti'

ESP8266WebServer server(80);    // Create a webserver object that listens for HTTP request on port 80

String getContentType(String filename); // convert the file extension to the MIME type
bool handleFileRead(String path);       // send the right file to the client (if it exists)

// Declaring a variable to hold JSON object size
//const size_t capacity = JSON_OBJECT_SIZE(10);

// Creating a JSON document to hold signal entry
//DynamicJsonDocument doc(capacity);

// Declaring array size
const size_t array_capacity = JSON_ARRAY_SIZE(16) + JSON_OBJECT_SIZE(1) + 16*JSON_OBJECT_SIZE(9);

// Creating a JSON document to hold all signal entries in a nested array
DynamicJsonDocument array_doc(array_capacity);

// Creating a nested JSON array to hold all signal entries
JsonArray signals = array_doc.createNestedArray("signals");

// Declaring a JSON object to hold single signal entry
JsonObject signal_entry;

// Declaring method that save JSON object to JSON file stored on SPIFFS
void saveJSON();

// Declaring method that prints JSON file stored on SPIFFS
void printJSON();

void setup(void){
  Serial.begin(115200);         // Start the Serial communication to send messages to the computer
  delay(10);
  Serial.println('\n');

  Serial.println("Connecting ...");
  int i = 0;
  while (wifiMulti.run() != WL_CONNECTED) { // Wait for the Wi-Fi to connect: scan for Wi-Fi networks, and connect to the strongest of the networks above
    delay(250);
    Serial.print('.');
  }

SPIFFS.begin();                           // Start the SPI Flash Files System

  server.begin();                           // Actually start the server
  Serial.println("HTTP server started");

  server.onNotFound([]() {                              // If the client requests any URI
    if (!handleFileRead(server.uri()))                  // send it if it exists
      server.send(404, "text/plain", "404: Not Found"); // otherwise, respond with a 404 (Not Found) error
  });

void loop(void){
  server.handleClient();                    // Listen for HTTP requests from clients

//Creating a JSON object from the JSON document
    signal_entry = signals.createNestedObject();

    //Assigning correct values to keys in JSON object
    signal_entry["date"] = currentDate;
    signal_entry["protocol_type"] = protocol_type;
    signal_entry["bitNr_device"] = bitNr_device;
    signal_entry["bitNr_op"] = bitNr_op;
    signal_entry["codeDec_device"] = codeDec_device;
    signal_entry["codeDec_op"] = codeDec_op;
    signal_entry["codeHex_device"] = codeHex_device;
    signal_entry["codeHex_op"] = codeHex_op;
    signal_entry["codeBin_device"] = codeBin_device;
    signal_entry["codeBin_op"] = codeBin_op;

    serializeJsonPretty(signal_entry, Serial);
    Serial.println("");

    saveJSON();
   }
}

String getContentType(String filename) { // convert the file extension to the MIME type
  if (filename.endsWith(".html")) return "text/html";
  else if (filename.endsWith(".css")) return "text/css";
  else if (filename.endsWith(".js")) return "application/javascript";
  else if (filename.endsWith(".ico")) return "image/x-icon";
  return "text/plain";
}

bool handleFileRead(String path) { // send the right file to the client (if it exists)
  Serial.println("handleFileRead: " + path);
  if (path.endsWith("/")) path += "index.html";         // If a folder is requested, send the index file
  String contentType = getContentType(path);            // Get the MIME type
  if (SPIFFS.exists(path)) {                            // If the file exists
    File file = SPIFFS.open(path, "r");                 // Open it
    size_t sent = server.streamFile(file, contentType); // And send it to the client
    file.close();                                       // Then close the file again
    return true;
  }
  Serial.println("\tFile Not Found");
  return false;                                         // If the file doesn't exist, return false
}

void saveJSON(){
  File jsonFile = SPIFFS.open("signals.json", "w");
  if (serializeJsonPretty(array_doc, jsonFile) == 0) {
    Serial.println("Failed to write to file");
  }
  jsonFile.close();
}

void printJSON(){
  uint8_t* pBuffer;
  File testFile = SPIFFS.open("signals.json", "r");
  if(testFile){
    unsigned int fileSize = testFile.size();
    pBuffer = (uint8_t*)malloc(fileSize + 1);
    testFile.read(pBuffer, fileSize);
    pBuffer[fileSize] = '\0';
    Serial.println((char*)pBuffer);                // Print the file to the serial monitor.
    testFile.close();
  }
  else{
    Serial.println("Failed to read to file");
  }
  free(pBuffer);
}

```

# Answer
> 1 votes
Besides the somewhat strange problem of loop() being nested inside setup() (which I will put down to a copy-and-paste error) I think your main problem is that of a lack of content-type.

The function `getContentType()` is supposed to guess the content type by the filename extension. However there is nothing there to handle a .json file. So it will just default to `text/plain` \- which won't be interpreted as JSON data.

You need to add a bit in there to look for JSON files and set the content-type accordingly:

```
...
} else if (filename.endsWith(".json")) {
    return "application/json";
}

```

---
Tags: esp8266, json
---


title: ESP8266 not connecting to WiFi

text:
# Question
Title: ESP8266 not connecting to WiFi
I am trying to send the temperatures from an DS18B20 to ThingSpeak, using an ESP8266. You can see the code I am using for that.

When I run the code I do not get any errors. In serial monitor it just shows that it is not connected to WiFi. If I change the WiFi name in code to something not even existing I still do not get any errors. I do not think that the ESP even finds the WiFi.

I think that the only problem to get everything work is just to get the WiFi connection to work properly. I have also checked the ESP with another simple code just to check that it is not broken and it actually get the code from my computer.

Here is the code I am using. (I have removed my password etc... )

```
//nodeMCU v1.0 (black) with Arduino IDE
//stream temperature data DS18B20 with 1wire on ESP8266 ESP12-E (nodeMCU v1.0)
//shin-ajaran.blogspot.com
//nodemcu pinout https://github.com/esp8266/Arduino/issues/584
#include <ESP8266WiFi.h>
#include <DallasTemperature.h>
#include <OneWire.h>

//Def
#define myPeriodic 15 //in sec | Thingspeak pub is 15sec
#define ONE_WIRE_BUS D4  // DS18B20 on arduino pin2 corresponds to D4 on physical board
//#define mySSR 0  // Solid State Relay on pin 0

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature DS18B20(&oneWire);
float prevTemp = 0;
const char* server = "api.thingspeak.com";
String apiKey ="******";
const char* MY_SSID = "******";
const char* MY_PWD = "******";
int sent = 0;

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

void loop() {
    float temp;
    //char buffer[10];
    //DS18B20.requestTemperatures();
    //temp = DS18B20.getTempCByIndex(0);
    temp=1111;
    //String tempC = dtostrf(temp, 4, 1, buffer);//handled in sendTemp()
    Serial.print(String(sent)+" Temperature: ");
    Serial.println(temp);

    //if (temp != prevTemp)
    //{
    //  sendTeperatureTS(temp);
    //  prevTemp = temp;
    //}

    sendTeperatureTS(temp);
    int count = myPeriodic;
    while(count--)
    delay(1000);
}

void connectWifi()
{
    Serial.print("Connecting to "+*MY_SSID);
    WiFi.begin(MY_SSID, MY_PWD);
    while (WiFi.status() != WL_CONNECTED) {
        delay(1000);
        Serial.print(".");
    }

    Serial.println("");
    Serial.println("Connected");
    Serial.println("");
}//end connect

void sendTeperatureTS(float temp)
{
    WiFiClient client;

    if (client.connect(server, 80)) { // use ip 184.106.153.149 or api.thingspeak.com
        Serial.println("WiFi Client connected ");

        String postStr = apiKey;
        postStr += "&field1=";
        postStr += String(temp);
        postStr += "\r\n\r\n";

        client.print("POST /update HTTP/1.1\n");
        client.print("Host: api.thingspeak.com\n");
        client.print("Connection: close\n");
        client.print("X-THINGSPEAKAPIKEY: " + apiKey + "\n");
        client.print("Content-Type: application/x-www-form-urlencoded\n");
        client.print("Content-Length: ");
        client.print(postStr.length());
        client.print("\n\n");
        client.print(postStr);
        delay(1000);

    }//end if
    sent++;
    client.stop();
}//end send

```

# Answer
> 5 votes
Maybe you have a space in your WIFI SSID so you should check this in your router. Also maybe your WIFI is on 5Ghz and the ESP can't see it because it is only for 2.4 Ghz. Also if your WIFI AP is on a channel from 13 - 14 it also couldn't be seen by the ESP. And to test your ESP you can run the scan example and if it works you should try the web server example to connect to your network. If that all will work ok than the problem is in your code.

# Answer
> 4 votes
I had the same problem, when i tried to connect to my home wifi i got stuck with just printing dots and never could connected. First of all i though that my ssid or password had a typo, but it hadn't. Then i changed the nodemcu and the problem persisted. But when i tried to connect to other wifi it worked. So the problem was in my modem/router.So i changed my modem/router configuration to: Operation mode: 802.11g+n to Automatic Channel: 11 to Automatic Channel Bandwich: 20 to Automatic

then the problem was solved.

# Answer
> 2 votes
In order to connect to Wifi from ESP32 and other boards, the WiFi connection needs to be 2.4GHz, wireless mode must be legacy. It cannot be set to Auto or N only. Go to your router box web page, and change this setting under Advanced Settings \> Wireless.

The only code required to connect is.

```
void setup() {
  ...
  WiFi.begin(MY_SSID, MY_PWD);
}

void loop() {
  while (WiFi.status() != WL_CONNECTED) {
     delay(1000);
     Serial.print(".");
  }
  ...
}

```

# Answer
> 0 votes
Try to add `WiFi.hostname("ESP-host");` before `WiFi.begin(ssid, password);` \- it works in my case.

---
Tags: esp8266, wifi, nodemcu
---


# Question
Title: Is an Ultrasonic Sensor or Infrared Sensor better for measuring distance (to/from a human body)?
I'm trying to make a sensor to detect that a person is within 50cm to trigger a function. But when I use the HR-SR04 sensor, it works accurately on flat surfaces (e.g. walls, books) with a margin of error around 5cm, but not on uneven surfaces (e.g. humans) where the value randomly jumps between 0cm to 1000cm.

I was thinking whether using an IR distance sensor would be better.

# Answer
> 3 votes
That depends on your requirements. An IR distance sensor will work better with different materials, since IR light is mostly reflected in very broad angles (expect for very reflective materials, like mirrors), so that uneven surfaces are also detected. But you will get a significantly worse error margin in your 50cm range. Normal IR distance sensors are just an LED and an IR photo transistor, sometime with some extra components. So the LED is lighting up and the photo transistor is measuring, how much of the IR light is coming back. The IR sensor depends also on the reflectiveness of the materials and the level of surounding IR light.

But as you don't really need to measure the distance, but just want to know, if there is an object in the range, an IR sensor might be enough. You would need to change the threshold of your IR sensor according to your needs (by experimenting with it).

All in all I think, yes, an IR sensor can give you better results for your application, though not for really measuring the distance, but only for the presence in a range with rather big error margin.

# Answer
> 0 votes
I have found IR accuracy to be poor resolution (+/- a few centimeters), as it's highly dependent on the refectivity of the surface. It also frequently has very poor range (a few cm to tens of cm), depending on the emitting power of the illumination source.

I have found ultrasonics, however, even the cheap $0.99 ones you mention, to have much better resolution (+/- mm), and much better range (about 2m), depending on the code driving them. I have yet to see good non-blocking code in any library for one of these, but when I write my own non-blocking code with interrupts and basic digital signal processing, such as a median filter, I get excellent results.

So, I recommend you use ultrasonics, but it requires advanced knowledge to do it well and do it right, such as using interrupts and taking the median of every 3 to 5 samples to remove spurious results.

On very flat surfaces, such as walls, at angles 45 deg or larger, ultrasonics also do poorly, since they end up measuring the distance *including* the extra reflections off the walls, but contrary to what you experienced, on odd shaped or softer objects, such as humans, I find them to do much better. I have used ultrasonics as the means of detecting humans several times before with good results. The real secret/challenge is your code. And again, I have yet to find a library worth using, and good code on these cheap things makes a HUGE difference in results and reliability and accuracy!

---
Tags: arduino-uno, sensors, ir, ultrasonics, distance
---


# Question
Title: Frequency of Retrieving Data from Website
I have wrote a code that communicate with my website to retrieve data to power on or off a 5V relay. I'm running the code every second to make sure it is real time. Is there more efficient way to tell Arduino to get the data whenever it is changed rather than continuous GET request.

```
// Send HTTP GET request
  int httpResponseCode = http.GET();

  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");        Serial.println(httpResponseCode);        String payload = http.getString();
        StaticJsonDocument<2000> doc;             DeserializationError error = deserializeJson(doc, payload);
        if (error) {              Serial.print(F("deserializeJson() failed: "));              Serial.println(error.c_str());              return;            }

        String status = doc["status"];
        Serial.println(status);
         if ( status == "ON" ) {
           digitalWrite(ledPin, LOW);
         } else {
           digitalWrite(ledPin, HIGH);
         }
  }

```

# Answer
Your two best options would be MQTT and WebSockets.

Both would open a long lived TCP connection that the ESP8266 and browser could use to transmit and receive data. Both would avoid constant polling to see if there's a new command.

MQTT requires an external broker. There are MQTT services with free tiers you could use for this or you could run one locally - Eclipse Mosquitto is a popular MQTT broker that runs nicely on a Raspberry Pi. MQTT is particularly useful for networks with multiple publishers and subscribers (it's a "pubsub" protocol) and is probably overkill if you just have a single device and endpoint.

It's easy to use MQTT from a browser using Javascript. The Paho Javascript MQTT client works well. The ESP8266 would establish a connection to the MQTT broker, subscribe to a topic name and set a callback function that would be called when data was published to that topic. The browser would also establish a connection to the MQTT broker and would publish a message to the topic when responding to events from the user.

WebSockets would allow the ESP8266 and browser to establish a full duplex connection between them. The ESP8266 would create a websocket server which the browser would connect to. The ESP8266 would check for data on the websocket during while running code in `loop()` and would assemble messages from the browser.

Either works easily if both your devices are on the same network (for instance, at home). If your browser is outside the network, it won't be able to communicate directly with the ESP8266.

MQTT has the advantage that an MQTT server located outside of the network (not one running locally on a Raspberry Pi) would allow the browser and ESP8266 to communicate with one another through it. WebSockets would require the use of a proxy server (there are modules for popular web servers like NGINX and Apache, but this requires control of the web server to configure). If you only ever want to use the browser to control the ESP8266 while they're both on the same network you don't need to worry about this.
> 3 votes

---
Tags: esp8266, http
---


title: Detecting different objects closeness

text:
# Question
Title: Detecting different objects closeness
iam currently working on a new project, where i would like to detect the existence/closeness of several objects around the arduino up to like 1 meter. I was thinking about an rfid setup, but as the objects could have different sizes like 5 centimetre tall and only 3 centimetre wide, i think this won't work for the max distance. I was also thinking about a ble beacon, but as this one has to be activley powered all the time, it wouln't be the perfect solution. As the base could be fully customized, it may have some kind of sensors/wires overall the surface, but iam a bit lacking of a good idea for this.

I hope someone might had a similar setup, or a good idea to go.

PS: When i think about it twice, it would be better, if it can be differentiate between some areas within the one meter and the different objects, entering each area. I've added some image, hope this helps to understand, what i want to archive at the end.

Thank you and greetings, Sebastian

# Answer
> 1 votes
As you might have already seen, a position sensing system can be really complex. Here I will list some possibilities, that come to my mind and might be fitting for your case or not.

* **Matrix based solutions:** Here I mean sensors a some sort arranged in a matrix underneath the game table, which can sense the object placed on them. As you know from your wiring, where a specific sensor is located, you know from the triggered sensor, where the object was placed. The resolution directly corresponds to the numbers of sensors, that you place. You can use different sensors, which will give you different information, but are also very different in handling and costs:
* Reed switches and magnets on the bottom of the objects. The magnet on the object would close the reed switch. A read switches are rather cheap (have seen 40 pieces for about 10€ on amazon; on aliexpress or others you might get them even cheaper) and can be easily placed in an electrical matrix or (depending on the number and places of object at any time) checked via shift registers, which are also not very pricey.
* Hall sensors and magnets on the bottom of the objects. You would measure the magnetic field of the magnets with the hall sensors. You could use different magnet strengths to get different readings and thus directly distinguish between different object types. The hall sensors will be not that easy to read. Mostly they have an analog output, thus you would need extra ADCs and multiplexers to read them all.

+ RFID readers and RFID chips in each object. Very pricey and rather low resolution. Also very difficult to read from all of them with the Arduino. But you could go for the reed switch version and use a single RFID reader to first tell the Arduino, which object you are placing. In the game you would first hold the object to the reader, then place it on the board.
* Lidar system: A Lidar scanner could scan over your board (it measures the distance in a circle around it). Each object would be a negative peak in the measured distance distribution. From the angle and the distance, you could calculate the position on the board. Though you would need to carefully place the sensor, as one object might hide the other behind it. You can tackle that with an additional Lidar scanner, but the processing will also be rather complex. And Lidar scanners are rather expensive.
* Ultrasonic sensors out the board: If you place enough ultrasonic sensors around the board and measure with one after the other, you might also get fitting results. But I would guess, that you won't get good positioning results with them, especially for the rather small objects and distances used on a game table.
* Computer Vision: Away from Arduino you could use OpenCV on a Raspberry Pi together with a small camera above your board to detect objects. General object detecting is rather easy with OpenCV and python; getting it's position in the camera image is trivial then (from where you can calculate the position on the board easily). With more work it should also be possible to detect the object themselves (meaning distinguishing between different objects). We might need to train OpenCV with top-down images of the objects for that. If you don't get good results with the normal camera mode, you could try the IR camera mode (by removing the IR filter of the Pi's camera) and put some good IR reflective stuff on the top of the objects. Then OpenCV only has to find the bright spots in the image. All that is possible, though I cannot help you with that and also it is off-topic on this site.
* If you can have a board with fixed positions, you could make direct electrical connections between the objects and the board. Though that means, that you would have metal contacts all over the board. I recently used such electrical connections to distinguish between different objects, which can be put into a small number of bays. I have 7 pins on each object, one of them ground. On the object I connected some of the other pins to the ground pin to create a binary pattern. The pins of each bay get read by a shift-in register. All registers are chained together and connected to the Arduino with a total of 4 pins.

Depending on your needs you could combine some of these options. I would try the OpenCV solution, or alternatively the reed switch with one RFID reader solution.

# Answer
> -1 votes
You should use the HC-SR0 ultrasonic sensor. It has good accuracy and range. If you don't want to use that, you can use an infrared distance sensor. If these don't work, please tell me why.

---
Tags: arduino-uno, sensors, rfid, object-oriented
---


# Question
Title: Digispark Attiny85 draws more power for digital input than expected
I'm trying to figure out why my attiny85 (on a digistump developer board) draws around 3mA at 3V when setting up a pin as INPUT and connecting it straight to ground. The current is measured with a multimeter between said pin and ground (thus only the current sunk by that pin is measured). I would assume that without a pullup resistor it would consume a lot less but it seems, regardless if I configure the button as INPUT or INPUT\_PULLUP the current is the same.

Sketch:

```
void setup() {
  pinMode(3, INPUT);
  //According to datasheet pin needs to be low to disable internal pullup
  digitalWrite(3, LOW);
}

void loop() {
  digitalRead(3);
  delay(100);
}

```

I would like to design a circuit that can detect a normally closed switch being opened, but the idle power consumption is way to high at the moment. I was planing on using a very high external pullup but it seems I can't disable the internal one...

# Answer
> 2 votes
The schematics of the digistump developer board shows that PB3 is connected to +5V over two resistors (1.5 k + 66.5) Ohms. That's the reason for the high current (5V / 1560 Ohm = 0.0032051 A). See the schematics https://s3.amazonaws.com/digistump-resources/files/97a1bb28\_DigisparkSchematic.pdf

As you mentioned in a reply on my comment above, using PB2 shows the expected behavior of an AT85 IO pin.

# Answer
> 0 votes
Input pin only needs 1uA to pull it high or low.

What else is hooked up?

The internal pullup, 30K to 50K, would only draw 0.1mA.

Turn it on and try it, measure the Vcc current with the pin open and then Gnd'ed.

# Answer
> 0 votes
I removed the soic IC from board and used it on my own board. I mounted two identical SMT boards, one with a generic chinese pdip and the other with the soic removed, both chips soldered, and I used the same battery supply. The soic from digispark consumed 6 times more current than pdip, in sleep mode: 812uA vs 137uA. I suspect of fake chips. In this base, it is hard to speculate.

---
Tags: current, attiny85, pull-up
---


title: Arduino Object Oriented Programming

text:
# Question
Title: Arduino Object Oriented Programming
Can anyone send me a link tutorial about Arduino Object Oriented Programming? I want to learn Arduino, I am just a beginner.

# Answer
"Arduino" is just plain old C++ with (in some cases) bits removed and some helper functions and classes.

For the smaller (lower powered AVR for example) there is no full STL in the C++ library, and some functions are of a reduced complexity (such as no floating point support in the `printf` family of functions by default).

For OOP you don't need to know anything "Arduino" - it's just C++. Any C++ OOP tutorial will teach you what you need to know for Arduino OOP.
> 8 votes

# Answer
Have you programmed OOP before? For alot of projects you can get away with not knowing it.

I'll also point out that if you are just a beginner, I don't recommend starting off with OOP. Stick to simpler scripts (Trust me, OOP is a pain sometimes).

If you still INSIST on starting your arduino knowledge with OOP, look up "C++ classes" or "C++ OOP" as the default language that the arduino IDE uses is just a modified version of "C++"
> 3 votes

# Answer
http://paulmurraycbr.github.io/ArduinoTheOOWay.html really helped me understand what was happening. i had some previous oop expierence with java, but i still have a hard time using multiple files vs writing more methods in one file
> 2 votes

# Answer
I used OOP with C++ on an Arduino Due in an open source project.

Since I did not find any tutorila for the same the example might be helpful for You.

https://github.com/eschlot/Box-Joint-Jig-Control

W.r.t. the usability of OOP in embedded systems for scenarios like the above one there are plenty of good reasons to use OOP. A good example is the menu structure and the display control in the project. Nevertheless from my experience it is important to understand the effects of automatic object creation and tentative memory reorganization to the behavior of real time systems. This is much less predictable with C++ then with plain C and can be a reason to not use OOP in any real time system.
> 1 votes

---
Tags: arduino-uno, programming, loop
---


# Question
Title: Arduino nano 33 ble vs ble sense. Power consumption, etc
After working with an Arduino Uno at work, I am looking to buy myself a board for some projects/experiments at home. The nano size seems like a great option, especially the one without soldered headers, as it is very flexible and easy to fit in projects with limited space. More specifically, I am interested in nano 33 ble and nano 33 ble sense.

My question is, apart from price does anyone know of any other disadvantages the sense board might have on comparison to the 33 ble?

Does it consume more power if the sensors are not used in a projects (just from being integrated in the board’s circuit)?

Also, does the light intensity sensor work like an LDR (photoresistor)? E.g. will I be able to do things like turn on LEDs automatically when it is dark, based on the sensor’s readings?

# Answer
The official page for the Nano 33 BLE Sense mentions various things including the datasheet for the light sensor. That appears to be much more sophisticated than an LDR.

According to the sensor documentation (above):

> Upon power-up, POR, the device initializes and immedi-ately enters the low power SLEEP state. In this operational state the internal oscillator and other circuitry are not active, resulting in ultra-low power consumption.

You would have to read the documentation for the other devices to check these things. Personally I haven't used one, and Arduino claim it "is a completely new board". So, you may not find a lot of people that can answer those questions.

Keeping power consumption low is quite a complex field. You need to look at clock speeds, sleep states, peripheral power consumption and so on.
> 3 votes

---
Tags: sensors, arduino-nano, power
---


title: Confuse about PROGMEM and R"====()===="

text:
# Question
Title: Confuse about PROGMEM and R"====()===="
I saw the following code from https://circuits4you.com/2018/03/10/esp8266-jquery-and-ajax-web-server/ but I could not understand it thoroughly...

I looked at the documentation of PROGMEM from this https://www.arduino.cc/reference/en/language/variables/utilities/progmem/ but could not understand the importance in the code on why you should put your variables in flash memory instead of SRAM (the usual memory?)?

```
const char MAIN_page[] PROGMEM = R"=====(
  <!DOCTYPE html>
  <html>
  <head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <script>
  $(document).ready(function(){
      $("p").click(function(){
          $(this).hide();
      });
  });
  </script>
  </head>
  <body>

  <p>If you click on me, I will disappear.</p>
  <p>Click me away!</p>
  <p>Click me too!</p>
  <br><hr>
  <a href="https://circuits4you.com">circuits4you.com</a>
  </body>
  </html>
)=====";

```

Also, I could not understand the definition of R"====()====", what is meant by this in arduino?

# Answer
> why you should put your variables in flash memory instead of SRAM

Because the Arduino has only a very small amount of memory. If you have data that will never change it's better to store it in flash (of which there is much more) so as to leave the SRAM free for data that *does* change.

> Also, I could not understand the definition of R"====()====", what is meant by this in arduino?

The `R` means "Treat everything between these delimiters as a raw string". That is, everything between `"=====(` and `)====="`. It's not an Arduino thing, but a general C++ thing (see here). The `=====` can be anything you like (within certain bounds) as long as it's the same at both the start and end of the string. So you could use `R"-=(This is "text")=-"` which would assign the string `This is "text"`. It's a great way of working with long strings that may want to contain `"` as otherwise you would have to escape each and every `"` as `\"`. So the string I showed just now would otherwise have to be written as: `"This is \"text\""`, which can get very messy if there are lots of `"` in there. The important thing to remember is that `)=====` mustn't appear in your text anywhere, so make sure it's something really obscure.
> 11 votes

---
Tags: arduino-uno, arduino-ide
---


# Question
Title: error at compiling : 'class TwoWire' has no member named 'setClock'
I am a newbie C programmer and I just started with Arduino **web editor** (Win10-Firefox)to code for a **Raspberry Pi** (3B) board. RPi is on line via ethernet connection.

I tried to compile an example from Garmin Lidar\_lite v3HP for I2C, as available in the library collections for Arduino. When compiling the example I get after a while this error message:

*Using library Wire in folder: /home/builder/.arduino15/packages/arduino/hardware/mraa/1.0.8/libraries/Wire (legacy)*

*Using library lidar\_lite\_3\_0\_3 at version 3.0.3 in folder: /home/builder/opt/libraries/latest/lidar\_lite\_3\_0\_3*

*/tmp/967842743/v3HP\_I2C/v3HP\_I2C.ino: In function 'void setup()':*

*/tmp/967842743/v3HP\_I2C/v3HP\_I2C.ino:51:18: error: 'class TwoWire' has no member named 'setClock'*

*Wire.setClock(400000UL); // Set I2C frequency to 400kHz (for Arduino Due)*

^ *exit status 1*

Checking the arduino forum I find some similar question, but of many years ago and likely not applicable any longer.

I appreciate your expert inputs on how to resolve in simple terms. Thanks a lot! Greetz, Ivan

# Answer
> 1 votes
Thanks for the reply. I tried again with the arduino on PC with RasPiDuino librarie and had no further problem. The resulting executable does work on a RPi3 with Buster OS. Apparently the arduino webeditor lacks some libraries to succesfully compile for raspberry . I continue this road. Item can be closed.

---
Tags: i2c, raspberrypi, compilation-errors
---


# Question
Title: I am very new to Arduino and the kit tutorial just told me to wire this, I do not know how to wire it. Can Someone plz help!
I can't figure out how to do this the only wires I have are Jumper Wire and M-F 20 Pin DuPont Wire.

# Answer
If you don't have a breadboard, get one. It's a board with lots of holes in it that you can use for experimenting.

Something like this:

https://www.adafruit.com/product/64?gclid=EAIaIQobChMIz9XDj9bF6wIVcuW1Ch2\_kgD3EAQYAiABEgL4DvD\_BwE

As Delta\_G said in their comment, you could wire a circuit as simple as yours by just putting the wires from the components directly into the terminals on the Arduino, but that quickly becomes impractical. Get a breadboard and learn how to use it.
> 1 votes

---
Tags: arduino-uno, photoresistor
---


title: Possible noise from the motors

text:
# Question
Title: Possible noise from the motors
I'm trying to control a self-balancing car, but it seems that the MPU6050 get dirty once my motors operate a full velocity. I'm controlling my motors with the module L298N and with the PWM signal (pin 5, 6, 9 and 10 from the arduino). I have read about decoupling it, with capacitors, but I don't know exactly how should I do it.

This is my code. It's a little messy (sorry for that, it just I'm still figuring out what is going on) and also an image of my project:

```
#include <PID_v1.h>
#include <LMotorController.h>
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"

#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif

#define MIN_ABS_SPEED 20

MPU6050 mpu;

#define DEBUG
//#define OFFSET_1

//#define STOP

// MPU control/status vars
bool dmpReady = false; // set true if DMP init was successful
uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU
uint8_t devStatus; // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize; // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount; // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer

// orientation/motion vars
Quaternion q; // [w, x, y, z] quaternion container
VectorFloat gravity; // [x, y, z] gravity vector
float euler[3]; // [psi, theta, phi]    Euler angle container

//PID
//double originalSetpoint = 175.8;
#ifdef OFFSET_1
      double originalSetpoint = 225;
#else
      double originalSetpoint = 184;
#endif

double setpoint = originalSetpoint;
double movingAngleOffset = 0.1;
double input, output, output_left, output_right, error;
int moveState=0; //0 = balance; 1 = back; 2 = forth
double Kp = 40;
double Kd = 0.05;
double Ki = 5;
PID pid(&input, &output, &setpoint, Kp, Ki, Kd, DIRECT);

double motorSpeedFactorLeft = 1;
double motorSpeedFactorRight = 1;
double motorSpeedFactorForward = 1;
double motorSpeedFactorBackward = 1;

//MOTOR CONTROLLER
int ENA = 5;
int IN1 = 6;
int IN2 = 7;
int IN3 = 8;
int IN4 = 9;
int ENB = 10;
//LMotorController motorController(ENA, IN1, IN2, ENB, IN3, IN4, motorSpeedFactorLeft, motorSpeedFactorRight);

//timers
long time1Hz = 0;
long time5Hz = 0;

volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high
void dmpDataReady()
{
  mpuInterrupt = true;
}

void setup()
{

  // join I2C bus (I2Cdev library doesn't do this automatically)
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
  Wire.begin();
  Wire.setClock(400000);  // Set the SCL clock speed to 400kHz
  //Wire.setClock(200000);  // Set the SCL clock speed to 400kHz
  //TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
  Fastwire::setup(400, true);
  //Fastwire::setup(200, true);
#endif

  Serial.begin(115200);
  mpu.initialize();

  devStatus = mpu.dmpInitialize();

  // supply your own gyro offsets here, scaled for min sensitivity

  #ifdef OFFSET_1
      mpu.setXGyroOffset(0);
      mpu.setYGyroOffset(0);
      mpu.setZGyroOffset(0);
      mpu.setZAccelOffset(16372);
      mpu.setYAccelOffset(5);
      mpu.setXAccelOffset(2);
    #else
      mpu.setXGyroOffset(-52);
      mpu.setYGyroOffset(-12);
      mpu.setZGyroOffset(53);
      mpu.setZAccelOffset(2420);
      mpu.setYAccelOffset(2881);
      mpu.setXAccelOffset(-784);
    #endif

  // make sure it worked (returns 0 if so)
  if (devStatus == 0)
  {

    //mpu.CalibrateAccel(6);
    //mpu.CalibrateGyro(6);
    // turn on the DMP, now that it's ready
    mpu.setDMPEnabled(true);

    // enable Arduino interrupt detection
    attachInterrupt(0, dmpDataReady, RISING);
    mpuIntStatus = mpu.getIntStatus();

    // set our DMP Ready flag so the main loop() function knows it's okay to use it
    dmpReady = true;

    // get expected DMP packet size for later comparison
    packetSize = mpu.dmpGetFIFOPacketSize();

    pid.SetMode(AUTOMATIC);
    pid.SetSampleTime(10);
    pid.SetOutputLimits(-255, 255);
  }
  else
  {
    // ERROR!
    // 1 = initial memory load failed
    // 2 = DMP configuration updates failed
    // (if it's going to break, usually the code will be 1)
    Serial.print(F("DMP Initialization failed (code "));
    Serial.print(devStatus);
    Serial.println(F(")"));
  }

  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);

  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);

  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);

}
void loop()
{
  #ifdef STOP
      return;
  #endif

  // if programming failed, don't try to do anything
  if (!dmpReady) return;

  // wait for MPU interrupt or extra packet(s) available
  while (!mpuInterrupt && fifoCount < packetSize)
  {
    pid.Compute();

    output = 255;
    output_left = output * motorSpeedFactorLeft;
    output_right = output * motorSpeedFactorRight;
    if(input > (setpoint))
    {
      output_left = output_left*motorSpeedFactorForward ;
      output_right = output_right* motorSpeedFactorForward;

      Move_Forward();
    }
    else if(input < (setpoint))
    {
      output_left = output_left*motorSpeedFactorBackward ;
      output_right = output_right* motorSpeedFactorBackward;
      Move_Backward();
    }
    else
    {
      Stop();
    }
  }
  // reset interrupt flag and get INT_STATUS byte
  mpuInterrupt = false;
  mpuIntStatus = mpu.getIntStatus();

  // get current FIFO count
  fifoCount = mpu.getFIFOCount();

  // check for overflow (this should never happen unless our code is too inefficient)
  if ((mpuIntStatus & 0x10) || fifoCount == 1024)
  {
    // reset so we can continue cleanly
    mpu.resetFIFO();
    Serial.println(F("FIFO overflow!"));

    // otherwise, check for DMP data ready interrupt (this should happen frequently)
  }
  else if (mpuIntStatus & 0x02)
  {
    // wait for correct available data length, should be a VERY short wait
    while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();

    // read a packet from FIFO
    mpu.getFIFOBytes(fifoBuffer, packetSize);

    // track FIFO count here in case there is > 1 packet available
    // (this lets us immediately read more without waiting for an interrupt)
    fifoCount -= packetSize;

    mpu.dmpGetQuaternion(&q, fifoBuffer);
    mpu.dmpGetGravity(&gravity, &q);
    mpu.dmpGetYawPitchRoll(euler, &q, &gravity);
    input = (euler[1] * 180 / M_PI + 180);
    error = input - setpoint;
//    Serial.print("\tOutput: ");
//    Serial.print(output);
    Serial.print("\tError: ");
    Serial.println(error);

  }
}

void Move_Forward() //Code to rotate the wheel forward
{

  //******RIGHT******//
      analogWrite(5, -1*output_right);
      analogWrite(6, 0);

  //******LEFT******//
      analogWrite(9, -1*output_left);
      analogWrite(10, 0);

      digitalWrite(11, HIGH);
      digitalWrite(12, LOW);
}

void Move_Backward() //Code to rotate the wheel forward
{
  //******RIGHT******//
      analogWrite(5, LOW);
      analogWrite(6, 1*output_right);

  //******LEFT******//
      analogWrite(9, 0);
      analogWrite(10, 1*output_left);

      digitalWrite(11, LOW);
      digitalWrite(12, HIGH);
}

void Stop() //Code to rotate the wheel forward
{
      analogWrite(11, LOW);
      analogWrite(12, LOW);
      analogWrite(5, LOW);
      analogWrite(6, LOW);

      digitalWrite(9, LOW);
      digitalWrite(10, LOW);
}

```

# Answer
> 1 votes
Well, I have to said that at the beginning I didn't think that the arrangement that @Majenko mentioned will work. First I tried connecting the capacitor with cables, but it still give me noise. Once I soldered it directly to the motors the noise decrease a lot.

Thanks to all. This is the image of the arrangement that I made:

---
Tags: mpu6050, l298n
---


title: pin numbering for non-standard chips

text:
# Question
Title: pin numbering for non-standard chips
so i replaced the mainboard in (what was) an anet a8 3d printer with a proper RAMPS setup. there was nothing wrong with it, (or at least it wasnt damaged, there are a number of severe design flaws) so i thought it might be a good start point for a remote controlled crawler/bot thing. it already has four a4988 drivers on board, plus a few mosfets and other bits which will be great for accessories (planning headlights, horn, maybe light sensor). its built around the atmega1284p, which is something of an oddball inbetween the 328 on the uno and the 2560 on the mega, but is the same product line. ive already worked out the libraries/drivers for the ch340 or whatever it is that is needed to flash code to the board,**it already has already been added to the arduino ide**, i have successfully flashed sketches to it before, but not my own. what im wondering is how to declare pins when im writing my own code. the bottom right of this schematic lists connections to the main chip, is it reasonably safe to assume that the digital pin numbers listed there can be used like the normally labeled headers on a standard board? how exactly are those numbers determined?

# Answer
ok so what ive found is that pins are declared in a file, `pins_arduino.h`. for each board/chip/variant another file is added(or created, if writing your own) to the arduino hardware files. in my specific case the numbers in the graphic are consistent with those listed in the hardware file, so im good
> 1 votes

---
Tags: pins
---


# Question
Title: Most Efficient & Cost Effective Home Automation Setup
I managed to build a system using Wemos D1 R1 connected to my website to retrieve data to power on or off a 5V relay. Now I would like to expand the project to control all my house outlet. Assuming I have, 5 rooms each of which has 5 electricity wires to control. My question is what is the best setup to achieve my goal in terms of efficiency and cost optimization. If I clone my current setup, I would be needing Wemos Module for every room that connecting separately to my Wifi and then to my server which seems too much for me. So what would you recommend?

Thoughts:

* Can I use one single central Wemos and then communicate to each room through ESP2866 or 433MHZ RF modules.
* I would be using at least 4 channel 5V relay Module. Could it be powered using 5V in Wemos or Arduino or should be powered with adapter
* If I want to control a fridge or AC or water heater, should I need SS Relay or any relay would suffice
* if SS Relay to be used, I have read that heat sink or fan should be included, is that a must?

# Answer
I advice you to buy some Sonoff devices, either the basic or S20. (they are pretty cheap on AliExpress/ebay etc.) They are perfect for the job. Flash them with Tasmota, which you find on github Tasmota. Then use a RaspberryPi (or similar) as a server. Run Node-RED on this server to communicate via MQTT to all your (Sonoff) devices. Use Mosquitto as the MQTT broker. I know this sounds like a lot, but thank me later when your done.
> 1 votes

---
Tags: esp8266, relay, web-server, rf, home-automation
---


title: Error reading from PROGMEM

text:
# Question
Title: Error reading from PROGMEM
I was trying to run a code from this https://circuits4you.com/2018/03/10/esp8266-jquery-and-ajax-web-server/

I am pasting it here.

```
/*
 * ESP8266 NodeMCU jQuery CDN Demo
 *
 * https://circuits4you.com
 */
#include <ESP8266WiFi.h>
#include <WiFiClient.h>

//ESP Web Server Library to host a web page
#include <ESP8266WebServer.h>

//---------------------------------------------------------------
//Our HTML webpage contents in program memory
const char MAIN_page[] PROGMEM = R"=====(
  <!DOCTYPE html>
  <html>
  <head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <script>
  $(document).ready(function(){
      $("p").click(function(){
          $(this).hide();
      });
  });
  </script>
  </head>
  <body>

  <p>If you click on me, I will disappear.</p>
  <p>Click me away!</p>
  <p>Click me too!</p>
  <br><hr>
  <a href="https://circuits4you.com">circuits4you.com</a>
  </body>
  </html>
)=====";
//---------------------------------------------------------------

//On board LED Connected to GPIO2
#define LED 2

//SSID and Password of your WiFi router
const char* ssid = "circuits4you.com";
const char* password = "yourWiFipassword";

//Declare a global object variable from the ESP8266WebServer class.
ESP8266WebServer server(80); //Server on port 80

//===============================================================
// This routine is executed when you open its IP in browser
//===============================================================
void handleRoot() {
 Serial.println("You called root page");
 String s = MAIN_page; //Read HTML contents
 server.send(200, "text/html", s); //Send web page
}
//==============================================================
//                  SETUP
//==============================================================
void setup(void){
  Serial.begin(115200);

  WiFi.begin(ssid, password);     //Connect to your WiFi router
  Serial.println("");

  //Onboard LED port Direction output
  pinMode(LED,OUTPUT);

  //Power on LED state off
  digitalWrite(LED,HIGH);

  WiFi.mode(WIFI_STA); //WiFi mode station (connect to wifi router only

  WiFi.begin(ssid, password);

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  //If connection successful show IP address in serial monitor
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());  //IP address assigned to your ESP

  server.on("/", handleRoot);      //Which routine to handle at root location. This is display page

  server.begin();                  //Start server
  Serial.println("HTTP server started");
}
//==============================================================
//                     LOOP
//==============================================================
void loop(void){
  server.handleClient();          //Handle client requests
}

```

When I deploy this to my nodemcu esp-12e, I a m getting below error

I used the exception decoder

```
Exception 3: LoadStoreError: Processor internal physical address or data error during load or store
PC: 0x4000bf64
EXCVADDR: 0x4023d581

```

From the decoder it says the offending line is this one

```
void handleRoot() {
 Serial.println("You called root page");
 String s = MAIN_page; //<<<<<<<<<<<<<<<<<<<<<< Error on this line
 server.send(200, "text/html", s);
}

```

It looks like it cannot read from the variable in PROGMEM..

I replaced that line with this code and converting it into a string and the error was gone.

```
String MAIN_page = R"=====(
  <!DOCTYPE html>
  <html>
  <head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <script>
  $(document).ready(function(){
      $("p").click(function(){
          $(this).hide();
      });
  });
  </script>
  </head>
  <body>

  <p>If you click on me, I will disappear.</p>
  <p>Click me away!</p>
  <p>Click me too!</p>
  <br><hr>
  <a href="https://circuits4you.com">circuits4you.com</a>
  </body>
  </html>
)=====";

```

Is there something wrong in the code that I am following on how it reads the variable from the PROGMEM flash memory?

# Answer
> 0 votes
You cannot assign a PROGMEM string directly to a String object. Besides, the whole concept makes no sense, since String objects store their data in RAM regardless.

If you want to use PROGMEM you need to use `const char *` not `String`.

# Answer
> -1 votes
The whole point of using PROGMEM is to save the RAM for other uses. If you have a huge string that would overflow your RAM then PROGMEM is essential. However, if the string isn't too large and the program works fine, then just use String instead of PROGMEM.

---
Tags: esp8266, nodemcu
---